From f0083e3d4eb49e11fd7e37532dc64a6e6f5d4039 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 26 Apr 2005 20:59:47 -0700 Subject: [PATCH 0001/4284] added initial files. --- Makefile | 152 +++++++++++++++++++++++++++++++++++++++++++++++++ klibc/Makefile | 3 + logging.c | 52 +++++++++++++++++ udev.c | 83 +++++++++++++++++++++++++++ udev.h | 41 +++++++++++++ 5 files changed, 331 insertions(+) create mode 100644 Makefile create mode 100644 klibc/Makefile create mode 100644 logging.c create mode 100644 udev.c create mode 100644 udev.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..c73ee42a3e --- /dev/null +++ b/Makefile @@ -0,0 +1,152 @@ +# Makefile for diethotplug +# +# Copyright (C) 2000,2001 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. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# Set the following to `true' to make a debuggable build. +# Leave this set to `false' for production use. +DEBUG = false + + +ROOT = udev +#PREFIX = diet +VERSION = 0.01 +INSTALL_DIR = /usr/local/bin +RELEASE_NAME = $(PREFIX)$(ROOT)-$(VERSION) + + +# Comment out this line to build with something other +# than the local version of klibc +#KLIBC = true + +# If you are running a cross compiler, you may want to set this +# to something more interesting, like "arm-linux-". I you want +# to compile vs uClibc, that can be done here as well. +CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- +CC = $(CROSS)gcc +AR = $(CROSS)ar +STRIP = $(CROSS)strip + + +# code taken from uClibc to determine the current arch +ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ + -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/ppc/powerpc/g'} + +# code taken from uClibc to determine the gcc include dir +GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} + +# code taken from uClibc to determine the libgcc.a filename +GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) + +# use '-Os' optimization if available, else use -O2 +OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ + then echo "-Os"; else echo "-O2" ; fi} + +WARNINGS := -Wall -Wshadow -Wstrict-prototypes + +# Some nice architecture specific optimizations +ifeq ($(strip $(TARGET_ARCH)),arm) + OPTIMIZATION+=-fstrict-aliasing +endif +ifeq ($(strip $(TARGET_ARCH)),i386) + OPTIMIZATION+=-march=i386 + OPTIMIZATION += ${shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc \ + /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi} + OPTIMIZATION += ${shell if $(CC) -malign-functions=0 -malign-jumps=0 -S -o /dev/null -xc \ + /dev/null >/dev/null 2>&1; then echo "-malign-functions=0 -malign-jumps=0"; fi} + CFLAGS+=-pipe +else + CFLAGS+=-pipe +endif + +# if DEBUG is enabled, then we do not strip or optimize +ifeq ($(strip $(DEBUG)),true) + CFLAGS += $(WARNINGS) -O1 -g -DDEBUG -D_GNU_SOURCE + LDFLAGS += -Wl,-warn-common + STRIPCMD = /bin/true -Since_we_are_debugging +else + CFLAGS += $(WARNINGS) $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE + LDFLAGS += -s -Wl,-warn-common + STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment +endif + +# If we are using our version of klibc, then we need to build and link it. +# Otherwise, use glibc and link statically. +ifeq ($(strip $(KLIBC)),true) + KLIBC_DIR = klibc + INCLUDE_DIR := $(KLIBC_DIR)/include + # arch specific objects + ARCH_LIB_OBJS = \ + $(KLIBC_DIR)/bin-$(ARCH)/start.o \ + $(KLIBC_DIR)/bin-$(ARCH)/klibc.a + + LIB_OBJS = $(GCC_LIB) + + LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) + CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(GCCINCDIR) + LDFLAGS = --static --nostdlib -nostartfiles +else + LIBC = + CFLAGS += -I$(GCCINCDIR) + LIB_OBJS = -lc + LDFLAGS = --static +endif + +all: $(LIBC) $(ROOT) + +$(ARCH_LIB_OBJS) : + $(MAKE) -C klibc + +OBJS = udev.o \ + logging.o + + +# header files automatically generated +GEN_HEADERS = udev_version.h + +# Rules on how to create the generated header files +udev_version.h: + @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + + +$(ROOT): $(GEN_HEADERS) $(OBJS) + $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $(ROOT) + +clean: + -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ + | xargs rm -f + -rm -f core $(ROOT) $(GEN_HEADERS) + $(MAKE) -C klibc clean + +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS ) +DISTDIR := $(RELEASE_NAME) +srcdir = . +release: $(DISTFILES) clean +# @echo $(DISTFILES) + @-rm -rf $(DISTDIR) + @mkdir $(DISTDIR) + @-chmod 777 $(DISTDIR) + @for file in $(DISTFILES); do \ + if test -d $$file; then \ + mkdir $(DISTDIR)/$$file; \ + else \ + cp -p $$file $(DISTDIR)/$$file; \ + fi; \ + done + @tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz + @rm -rf $(DISTDIR) + @echo "Built $(RELEASE_NAME).tar.gz" diff --git a/klibc/Makefile b/klibc/Makefile new file mode 100644 index 0000000000..288a862707 --- /dev/null +++ b/klibc/Makefile @@ -0,0 +1,3 @@ + +clean: + @echo "all clean" diff --git a/logging.c b/logging.c new file mode 100644 index 0000000000..e074b1562c --- /dev/null +++ b/logging.c @@ -0,0 +1,52 @@ +/* + * logging.c + * + * Simple logging functions that can be compiled away into nothing. + * + * Copyright (C) 2001-2003 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. + * + * 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. + * + */ + +#include +#include +#include "udev.h" + +#ifdef DEBUG + +static int logging_init = 0; + +static void init_logging (void) +{ + openlog ("udev", 0, LOG_DAEMON); + logging_init = 1; +} + +/** + * log_message - sends a message to the logging facility + */ +int log_message (int level, const char *format, ...) +{ + va_list args; + + if (!logging_init) + init_logging(); + va_start (args, format); + vsyslog (level, format, args); + va_end (args); + return 1; +} + +#endif diff --git a/udev.c b/udev.c new file mode 100644 index 0000000000..1ac1c98507 --- /dev/null +++ b/udev.c @@ -0,0 +1,83 @@ +/* + * udev.c + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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. + * + */ + +#include +#include +#include "udev.h" +#include "udev_version.h" + + +static char *get_action(void) +{ + char *action; + + action = getenv("ACTION"); + return action; +} + + +/* yeah this should be dynamically allocated... */ +static char device[255]; + +static char *get_device(void) +{ + char *temp; + + temp = getenv("DEVPATH"); + if (temp == NULL) + return NULL; + strcpy(device, SYSFS_ROOT); + strcat(device, temp); + + return device; +} + + +int main(int argc, char *argv[]) +{ + char *subsystem; + char *action; + char *dev; + + if (argc != 2) { + dbg ("unknown number of arguments"); + return 1; + } + + subsystem = argv[1]; + + action = get_action(); + if (!action) { + dbg ("no action?"); + return 1; + } + + dev = get_device(); + if (!dev) { + dbg ("no device?"); + return 1; + } + + return 0; +} + diff --git a/udev.h b/udev.h new file mode 100644 index 0000000000..ef7175ea3a --- /dev/null +++ b/udev.h @@ -0,0 +1,41 @@ +/* + * udev.h + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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 UDEV_H +#define UDEV_H + + +#ifdef DEBUG +#include + #define dbg(format, arg...) do { log_message (LOG_DEBUG, __FUNCTION__ ": " format, ## arg); } while (0) +#else + #define dbg(format, arg...) do { } while (0) +#endif + + +/* Lots of constants that should be in a config file sometime */ +#define SYSFS_ROOT "/sys" +#define MKNOD "/bin/mknod" + + +#endif + From a507a0157240640b4fbf096577a3c2d9729511dd Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 20:04:38 -0700 Subject: [PATCH 0002/4284] [PATCH] enabled debugging. --- Makefile | 2 +- udev.h | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c73ee42a3e..c31f61d840 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ # Set the following to `true' to make a debuggable build. # Leave this set to `false' for production use. -DEBUG = false +DEBUG = true ROOT = udev diff --git a/udev.h b/udev.h index ef7175ea3a..83004bb791 100644 --- a/udev.h +++ b/udev.h @@ -26,7 +26,10 @@ #ifdef DEBUG #include - #define dbg(format, arg...) do { log_message (LOG_DEBUG, __FUNCTION__ ": " format, ## arg); } while (0) +#define dbg(format, arg...) \ + do { \ + log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + } while (0) #else #define dbg(format, arg...) do { } while (0) #endif @@ -37,5 +40,8 @@ #define MKNOD "/bin/mknod" +extern int log_message (int level, const char *format, ...); + + #endif From 0c63f1190f78bb47596c9a17df84b8dc091b0e0d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 20:09:14 -0700 Subject: [PATCH 0003/4284] [PATCH] added initial documentation and gpl license --- COPYING | 340 ++++++++++++++++++++++++++++++++++++++++++++++++++ ChangeLog | 1 + docs/overview | 123 ++++++++++++++++++ 3 files changed, 464 insertions(+) create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 docs/overview diff --git a/COPYING b/COPYING new file mode 100644 index 0000000000..5b6e7c66c2 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000000..6a7969d298 --- /dev/null +++ b/ChangeLog @@ -0,0 +1 @@ +0.1 - initial release diff --git a/docs/overview b/docs/overview new file mode 100644 index 0000000000..6528b058c2 --- /dev/null +++ b/docs/overview @@ -0,0 +1,123 @@ + +Instead of heading in on another "proposal" document, I thought I'd send out +this email describing ideas I've had about udev - thanks to the comments I've +received. The idea is starting to mushroom a bit and I'd like to get people's +comments before I go further down the path. + +As I see it, we've got a couple goals for udev: + +1) dynamic replacement for /dev +2) device naming +3) API to access info about current system devices + +I'd like to split 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. 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 Martin has made, I've decided to push out the device naming part +of udev 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, these were given to me by Greg. 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 +-------- + +Greg may object, but I believe there's 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., I've decided +to split out the sysfs calls into a separate library that will sit atop +sysfs. Sysfs callbacks aren't standard across devices, I beleive this is +another reason for creating a common and standard library interface for +querying device information. + +Another reason for libsysfs is it satisfies requirements the LTC RAS team has +for getting current system device information. Rather than keeping tons of +information in udev's in memory database, or even querying that database for +the sysfs directory that will require storing extra reference info in memory, +I've decided the RAS requirements can be fulfilled with a library atop sysfs. +Sysfs contains devices currently on the system. + +Applications like the Error Log Analysis piece, for example, can query the +sysfs library for device information. ELA gets specific information in an +error message thanks to the dev_* and soon to be proposed netdev_* macros. +One goal of the ELA is to gather as much information about an erroring device +so service engineers and administrators can diagnose the problem. The ELA +will get an error message with the bus id and driver name of the device. It +will then need to query sysfs for other VPD information. + +I've used syfs in the name of libsysfs for a reason, I believe sysfs will be +the device tree to use in the future. Until all VPD info is in sysfs, the +library could also make use of /proc, sginfo, and other sources for device +information under the covers so ELA and other applications don' t need to all +have that knowledge. + + +I'd like to know what everyone thinks about my proposal to split this all up +into three separate subsystems. All comments are welcome. + +Thanks, + +Dan + + From a2fd2ff38a20d70cdc4487ea43a74da9604c3b54 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 10:53:25 -0700 Subject: [PATCH 0004/4284] [PATCH] added stupid test script for debugging. --- test | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 test diff --git a/test b/test new file mode 100644 index 0000000000..9cab4a6db7 --- /dev/null +++ b/test @@ -0,0 +1,5 @@ +#!/bin/sh +export ACTION=add +export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.2/ttyUSB7 + +./udev tty From 85511f02466297b7dca07c3fe5491230f3f06d14 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 10:53:46 -0700 Subject: [PATCH 0005/4284] [PATCH] Creating nodes actually works. --- udev.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- udev.h | 11 +++ 2 files changed, 208 insertions(+), 10 deletions(-) diff --git a/udev.c b/udev.c index 1ac1c98507..971ac10809 100644 --- a/udev.c +++ b/udev.c @@ -23,6 +23,11 @@ #include #include +#include +#include +#include +#include + #include "udev.h" #include "udev_version.h" @@ -36,11 +41,9 @@ static char *get_action(void) } -/* yeah this should be dynamically allocated... */ -static char device[255]; - static char *get_device(void) { + static char device[255]; char *temp; temp = getenv("DEVPATH"); @@ -52,32 +55,216 @@ static char *get_device(void) return device; } +/* + * Right now the major/minor of a device is stored in a file called + * "dev" in sysfs. + * The number is stored as: + * MMmm + * MM is the major + * mm is the minor + * The value is in hex. + * Yes, this will probably change when we go to a bigger major/minor + * range, and will have to be changed at that time. + */ +static int get_major_minor (char *dev, int *major, int *minor) +{ + char filename[255]; + char line[20]; + char temp[3]; + int fd; + int retval = 0; + + /* add the dev file to the directory and see if it's present */ + strncpy(filename, dev, sizeof(filename)); + strncat(filename, DEV_FILE, sizeof(filename)); + fd = open(filename, O_RDONLY); + if (fd < 0) { + dbg("Can't open %s", filename); + return -ENODEV; + } + + /* get the major/minor */ + retval = read(fd, line, sizeof(line)); + if (retval < 0) { + dbg("read error on %s", dev); + goto exit; + } + + temp[0] = line[0]; + temp[1] = line[1]; + temp[2] = 0x00; + *major = (int)strtol(&temp[0], NULL, 16); + + temp[0] = line[2]; + temp[1] = line[3]; + temp[2] = 0x00; + *minor = (int)strtol(&temp[0], NULL, 16); + + dbg("found major = %d, minor = %d", *major, *minor); + + retval = 0; +exit: + close(fd); + return retval; +} + +/* + * Here would go a call to the naming deamon, to get the name we want to have + * for this device. But for now, let's just default to whatever the kernel is + * calling the device as that will keep the "old-style" naming policy + */ +static char *get_name(char *dev, int major, int minor) +{ + static char name[100]; + char *temp; + + temp = strrchr(dev, '/'); + if (temp == NULL) + return NULL; + strncpy(name, &temp[1], sizeof(name)); + + dbg("name is %s", name); + + return &name[0]; +} + +/* + * Again, this will live in the naming deamon + */ +static int get_mode(char *name, char *dev, int major, int minor) +{ + /* just default everyone to rw for the world! */ + return 0666; +} + +/* + * We also want to add some permissions here, and possibly some symlinks + */ +static int create_node(char *name, char type, int major, int minor, int mode) +{ + char *argv[7]; + char mode_string[100]; + char type_string[3]; + char major_string[20]; + char minor_string[20]; + char filename[255]; + int retval = 0; + + strncpy(filename, UDEV_ROOT, sizeof(filename)); + strncat(filename, name, sizeof(filename)); + + snprintf(mode_string, sizeof(mode_string), "--mode=%#o", mode); + snprintf(type_string, sizeof(type_string), "%c", type); + snprintf(major_string, sizeof(major_string), "%d", major); + snprintf(minor_string, sizeof(minor_string), "%d", minor); + + argv[0] = MKNOD; + argv[1] = mode_string; + argv[2] = filename; + argv[3] = type_string; + argv[4] = major_string; + argv[5] = minor_string; + argv[6] = NULL; + dbg ("executing %s %s %s %s %s %s", + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + switch (fork()) { + case 0: + /* we are the child, so lets run the program */ + execv (MKNOD, argv); + exit(0); + break; + case (-1): + dbg ("fork failed."); + retval = -EFAULT; + break; + default: + break; + } + return retval; +} + +static int remove_node(char *name) +{ + return 0; +} + +static int do_it(char *action, char *name, char type, int major, int minor, int mode) +{ + if (strcmp(action, "add") == 0) + return create_node(name, type, major, minor, mode); + + if (strcmp(action, "remove") == 0) + return remove_node(name); + + dbg("Unknown action: %s", action); + return -EINVAL; +} int main(int argc, char *argv[]) { char *subsystem; char *action; - char *dev; + char *device; + char *name; + char type; + int major; + int minor; + int mode; + int retval = -EINVAL; if (argc != 2) { dbg ("unknown number of arguments"); - return 1; + goto exit; } + /* for now, the block layer is the only place where block devices are */ subsystem = argv[1]; + if (strcmp(subsystem, "block") == 0) + type = 'b'; + else + type = 'c'; action = get_action(); if (!action) { dbg ("no action?"); - return 1; + goto exit; } - dev = get_device(); - if (!dev) { + device = get_device(); + if (!device) { dbg ("no device?"); - return 1; + goto exit; + } + dbg("looking at %s", device); + + retval = get_major_minor(device, &major, &minor); + if (retval) { + dbg ("get_major_minor failed"); + goto exit; } - return 0; + name = get_name(device, major, minor); + if (name == NULL) { + dbg ("get_name failed"); + retval = -ENODEV; + goto exit; + } + + mode = get_mode(name, device, major, minor); + if (mode < 0) { + dbg ("get_mode failed"); + retval = -EINVAL; + goto exit; + } + + retval = do_it(action, name, type, major, minor, mode); + if (retval) { + dbg ("do_it failed"); + goto exit; + } + + retval = 0; +exit: + return retval; } diff --git a/udev.h b/udev.h index 83004bb791..458d1d9c37 100644 --- a/udev.h +++ b/udev.h @@ -36,10 +36,21 @@ /* Lots of constants that should be in a config file sometime */ + +/* Location of sysfs mount */ #define SYSFS_ROOT "/sys" + +/* Where udev should create its device nodes, trailing / needed */ +#define UDEV_ROOT "/home/greg/linux/udev/" + +/* device file in sysfs that contains major/minor number, leading / needed */ +#define DEV_FILE "/dev" + +/* Binaries that udev calls to do stuff */ #define MKNOD "/bin/mknod" + extern int log_message (int level, const char *format, ...); From 3f4967a1fbb4270b0577cca7d6a6d43a880875a5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 11:02:32 -0700 Subject: [PATCH 0006/4284] [PATCH] restructure code to be able to actually get remove_node() to work. --- udev.c | 77 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 38 deletions(-) diff --git a/udev.c b/udev.c index 971ac10809..4bb41a8696 100644 --- a/udev.c +++ b/udev.c @@ -183,21 +183,43 @@ static int create_node(char *name, char type, int major, int minor, int mode) return retval; } -static int remove_node(char *name) +static int add_node(char *device, char type) { - return 0; + char *name; + int major; + int minor; + int mode; + int retval = -EINVAL; + + retval = get_major_minor(device, &major, &minor); + if (retval) { + dbg ("get_major_minor failed"); + goto exit; + } + + name = get_name(device, major, minor); + if (name == NULL) { + dbg ("get_name failed"); + retval = -ENODEV; + goto exit; + } + + mode = get_mode(name, device, major, minor); + if (mode < 0) { + dbg ("get_mode failed"); + retval = -EINVAL; + goto exit; + } + + return create_node(name, type, major, minor, mode); + +exit: + return retval; } -static int do_it(char *action, char *name, char type, int major, int minor, int mode) +static int remove_node(char *device) { - if (strcmp(action, "add") == 0) - return create_node(name, type, major, minor, mode); - - if (strcmp(action, "remove") == 0) - return remove_node(name); - - dbg("Unknown action: %s", action); - return -EINVAL; + return 0; } int main(int argc, char *argv[]) @@ -205,11 +227,7 @@ int main(int argc, char *argv[]) char *subsystem; char *action; char *device; - char *name; char type; - int major; - int minor; - int mode; int retval = -EINVAL; if (argc != 2) { @@ -237,31 +255,14 @@ int main(int argc, char *argv[]) } dbg("looking at %s", device); - retval = get_major_minor(device, &major, &minor); - if (retval) { - dbg ("get_major_minor failed"); - goto exit; - } + if (strcmp(action, "add") == 0) + return add_node(device, type); - name = get_name(device, major, minor); - if (name == NULL) { - dbg ("get_name failed"); - retval = -ENODEV; - goto exit; - } + if (strcmp(action, "remove") == 0) + return remove_node(device); - mode = get_mode(name, device, major, minor); - if (mode < 0) { - dbg ("get_mode failed"); - retval = -EINVAL; - goto exit; - } - - retval = do_it(action, name, type, major, minor, mode); - if (retval) { - dbg ("do_it failed"); - goto exit; - } + dbg("Unknown action: %s", action); + return -EINVAL; retval = 0; exit: From 8b16416dce3d5feab0827668e1184301a19074a8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 11:16:34 -0700 Subject: [PATCH 0007/4284] [PATCH] remove now works! --- test | 5 +++-- udev.c | 37 ++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/test b/test index 9cab4a6db7..730f0a446a 100644 --- a/test +++ b/test @@ -1,5 +1,6 @@ #!/bin/sh -export ACTION=add -export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.2/ttyUSB7 +#export ACTION=add +export ACTION=remove +export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.1/ttyUSB7 ./udev tty diff --git a/udev.c b/udev.c index 4bb41a8696..5aa9b43d43 100644 --- a/udev.c +++ b/udev.c @@ -183,7 +183,21 @@ static int create_node(char *name, char type, int major, int minor, int mode) return retval; } -static int add_node(char *device, char type) +/* + * We also want to clean up any symlinks that were created in create_node() + */ +static int delete_node(char *name) +{ + char filename[255]; + + strncpy(filename, UDEV_ROOT, sizeof(filename)); + strncat(filename, name, sizeof(filename)); + + dbg("unlinking %s", filename); + return unlink(filename); +} + +static int add_device(char *device, char type) { char *name; int major; @@ -217,9 +231,22 @@ exit: return retval; } -static int remove_node(char *device) +static int remove_device(char *device) { - return 0; + char *name; + int retval = 0; + + name = get_name(device, 0, 0); + if (name == NULL) { + dbg ("get_name failed"); + retval = -ENODEV; + goto exit; + } + + return delete_node(name); + +exit: + return retval; } int main(int argc, char *argv[]) @@ -256,10 +283,10 @@ int main(int argc, char *argv[]) dbg("looking at %s", device); if (strcmp(action, "add") == 0) - return add_node(device, type); + return add_device(device, type); if (strcmp(action, "remove") == 0) - return remove_node(device); + return remove_device(device); dbg("Unknown action: %s", action); return -EINVAL; From 1e7a3f9e1101c148bd52640715db14e4c76b4996 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 11:25:55 -0700 Subject: [PATCH 0008/4284] [PATCH] cleaned up the makefile a bit. --- Makefile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c31f61d840..803a2db569 100644 --- a/Makefile +++ b/Makefile @@ -22,10 +22,9 @@ DEBUG = true ROOT = udev -#PREFIX = diet VERSION = 0.01 INSTALL_DIR = /usr/local/bin -RELEASE_NAME = $(PREFIX)$(ROOT)-$(VERSION) +RELEASE_NAME = $(ROOT)-$(VERSION) # Comment out this line to build with something other From 1c8c0f62121ea0069f12af252384f66178fc7b07 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 11:38:33 -0700 Subject: [PATCH 0009/4284] [PATCH] updated the documentation. --- docs/overview | 153 +++++++++++++++++++++----------------------------- 1 file changed, 63 insertions(+), 90 deletions(-) diff --git a/docs/overview b/docs/overview index 6528b058c2..350d53ee70 100644 --- a/docs/overview +++ b/docs/overview @@ -1,123 +1,96 @@ -Instead of heading in on another "proposal" document, I thought I'd send out -this email describing ideas I've had about udev - thanks to the comments I've -received. The idea is starting to mushroom a bit and I'd like to get people's -comments before I go further down the path. - -As I see it, we've got a couple goals for udev: +We've got a couple goals for udev: 1) dynamic replacement for /dev 2) device naming 3) API to access info about current system devices -I'd like to split these goals into separate subsystems: +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. +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. On a remove call, udev will remove the -/dev entry, remove the device from the in memory table, and send -notification. +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. + -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 Martin has made, I've decided to push out the device naming part -of udev 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. +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. +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, these were given to me by Greg. 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: +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. +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. + -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 -------- -Greg may object, but I believe there's 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., I've decided -to split out the sysfs calls into a separate library that will sit atop -sysfs. Sysfs callbacks aren't standard across devices, I beleive this is -another reason for creating a common and standard library interface for +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. -Another reason for libsysfs is it satisfies requirements the LTC RAS team has -for getting current system device information. Rather than keeping tons of -information in udev's in memory database, or even querying that database for -the sysfs directory that will require storing extra reference info in memory, -I've decided the RAS requirements can be fulfilled with a library atop sysfs. -Sysfs contains devices currently on the system. - -Applications like the Error Log Analysis piece, for example, can query the -sysfs library for device information. ELA gets specific information in an -error message thanks to the dev_* and soon to be proposed netdev_* macros. -One goal of the ELA is to gather as much information about an erroring device -so service engineers and administrators can diagnose the problem. The ELA -will get an error message with the bus id and driver name of the device. It -will then need to query sysfs for other VPD information. - -I've used syfs in the name of libsysfs for a reason, I believe sysfs will be -the device tree to use in the future. Until all VPD info is in sysfs, the -library could also make use of /proc, sginfo, and other sources for device -information under the covers so ELA and other applications don' t need to all -have that knowledge. - - -I'd like to know what everyone thinks about my proposal to split this all up -into three separate subsystems. All comments are welcome. - -Thanks, - -Dan - - From d2ce1817117daa9523b1572523f1e7684bae779f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Apr 2003 15:56:20 -0700 Subject: [PATCH 0010/4284] [PATCH] added more documentation in README and TODO files. --- ChangeLog | 3 ++- Makefile | 2 +- README | 39 +++++++++++++++++++++++++++++++++++++++ TODO | 6 ++++++ 4 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 README create mode 100644 TODO diff --git a/ChangeLog b/ChangeLog index 6a7969d298..f8b5da0f1d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1 +1,2 @@ -0.1 - initial release +0.1 - Added a bit of documentation to the README and TODO files. +0.01 - initial release diff --git a/Makefile b/Makefile index 803a2db569..4e0ca6b3cf 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 0.01 +VERSION = 0.1 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/README b/README new file mode 100644 index 0000000000..1a46a3c1ee --- /dev/null +++ b/README @@ -0,0 +1,39 @@ + +udev - a userspace implementation of devfs + +For more information on the design, and structure of this project, see the +files in the docs/ directory. + +To use: + +- Edit the udev.h file and replace the following variables with values + that make sense for your system: + #define SYSFS_ROOT "/sys" + #define UDEV_ROOT "/home/greg/linux/udev/" + #define DEV_FILE "/dev" + #define MKNOD "/bin/mknod" + The only value most people will have to change is the UDEV_ROOT + variable, as I doubt you really want device nodes to be created in my + home directory :) + +- Run make to build the project. + +- Make sure sysfs is mounted. + +- Point /proc/sys/kernel/hotplug at the location of the udev binary that + is created. Then plug some block devices in, or other types of + devices that create dev files in sysfs. An easy way to do this, + without any hardware is to use the scsi_debug module to create virtual + scsi devices. + +- Watch as the nodes get created and removed. + + +Yes this is a really rough first cut, I know. It's mostly a proof of +concept that this can actually work. See the TODO file for a list of +things left to be done. + +Any comment/questions/concerns please let me know. + +greg k-h +greg@kroah.com diff --git a/TODO b/TODO new file mode 100644 index 0000000000..1f776b9142 --- /dev/null +++ b/TODO @@ -0,0 +1,6 @@ +- use mknod(2) and not execute mknod(1) +- add klibc to the build process (or make it easier to do) to get + smaller binary +- make program work like design says it should (three parts, not 1) +- add hooks to call D-BUS when new node is created or removed +- lots of other stuff... From 5776bbd73be13c4f595cf5fdc0c27770518de2af Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 16 Jul 2003 20:17:20 -0700 Subject: [PATCH 0011/4284] [PATCH] fix up the test to actually work... --- test | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test b/test index 730f0a446a..40613d48af 100644 --- a/test +++ b/test @@ -1,6 +1,8 @@ #!/bin/sh -#export ACTION=add -export ACTION=remove +export ACTION=add +#export ACTION=remove export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.1/ttyUSB7 +export DEVPATH=/class/tty/ttyUSB0 + ./udev tty From f0952f66e634c9da1639662079e74e60da4027ef Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 16 Jul 2003 20:17:41 -0700 Subject: [PATCH 0012/4284] [PATCH] pick a better default UDEV_ROOT --- udev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.h b/udev.h index 458d1d9c37..f4f4f11f2d 100644 --- a/udev.h +++ b/udev.h @@ -41,7 +41,7 @@ #define SYSFS_ROOT "/sys" /* Where udev should create its device nodes, trailing / needed */ -#define UDEV_ROOT "/home/greg/linux/udev/" +#define UDEV_ROOT "/udev/" /* device file in sysfs that contains major/minor number, leading / needed */ #define DEV_FILE "/dev" From af815f882dc196b1357f5be81cb00c8fe9c60670 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 16 Jul 2003 20:18:06 -0700 Subject: [PATCH 0013/4284] [PATCH] sleep for 2 seconds to give the kernel a chance to actually create the files we need. --- udev.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/udev.c b/udev.c index 5aa9b43d43..de6b6565f2 100644 --- a/udev.c +++ b/udev.c @@ -262,6 +262,11 @@ int main(int argc, char *argv[]) goto exit; } + /* sleep for a second or two to give the kernel a chance to + * create the dev file + */ + sleep(2); + /* for now, the block layer is the only place where block devices are */ subsystem = argv[1]; if (strcmp(subsystem, "block") == 0) From 2232cac825e4f8b53273d16154309278cf639e3c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 17 Jul 2003 01:24:51 -0700 Subject: [PATCH 0014/4284] [PATCH] Initial namedev parsing of config files .permission parsing works, .config needs more work. --- Makefile | 3 +- list.h | 444 ++++++++++++++++++++++++++++++++++++++++++++ namedev.c | 345 ++++++++++++++++++++++++++++++++++ namedev.config | 21 +++ namedev.h | 34 ++++ namedev.permissions | 4 + udev.c | 3 + udev.h | 2 - 8 files changed, 853 insertions(+), 3 deletions(-) create mode 100644 list.h create mode 100644 namedev.c create mode 100644 namedev.config create mode 100644 namedev.h create mode 100644 namedev.permissions diff --git a/Makefile b/Makefile index 4e0ca6b3cf..0013d06793 100644 --- a/Makefile +++ b/Makefile @@ -110,7 +110,8 @@ $(ARCH_LIB_OBJS) : $(MAKE) -C klibc OBJS = udev.o \ - logging.o + logging.o \ + namedev.o # header files automatically generated diff --git a/list.h b/list.h new file mode 100644 index 0000000000..07d474888e --- /dev/null +++ b/list.h @@ -0,0 +1,444 @@ +/* + * Copied from the Linux kernel source tree, version 2.6.0-test1. + * + * Licensed under the GPL v2 as per the whole kernel source tree. + * + * Ripped out the rcu stuff, as it's not needed. + */ + +#ifndef _LINUX_LIST_H +#define _LINUX_LIST_H + +//#include +/** + * 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) );}) + +//#include +static inline void prefetch(const void *x) {;} + +//#include + +/* + * 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, prefetch(pos->next); pos != (head); \ + pos = pos->next, prefetch(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, no prefetching is done. + * 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, prefetch(pos->prev); pos != (head); \ + pos = pos->prev, prefetch(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), \ + prefetch(pos->member.next); \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member), \ + prefetch(pos->member.next)) + +/** + * 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), \ + prefetch(pos->member.prev); \ + &pos->member != (head); \ + pos = list_entry(pos->member.prev, typeof(*pos), member), \ + prefetch(pos->member.prev)) + + +/** + * 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)) + +/* + * Double linked lists with a single pointer list head. + * Mostly useful for hash tables where the two pointer list head is + * too wasteful. + * You lose the ability to access the tail in O(1). + */ + +struct hlist_head { + struct hlist_node *first; +}; + +struct hlist_node { + struct hlist_node *next, **pprev; +}; + +#define HLIST_HEAD_INIT { .first = NULL } +#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } +#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) +#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL) + +static __inline__ int hlist_unhashed(struct hlist_node *h) +{ + return !h->pprev; +} + +static __inline__ int hlist_empty(struct hlist_head *h) +{ + return !h->first; +} + +static __inline__ void __hlist_del(struct hlist_node *n) +{ + struct hlist_node *next = n->next; + struct hlist_node **pprev = n->pprev; + *pprev = next; + if (next) + next->pprev = pprev; +} + +static __inline__ void hlist_del(struct hlist_node *n) +{ + __hlist_del(n); + n->next = LIST_POISON1; + n->pprev = LIST_POISON2; +} + +static __inline__ void hlist_del_init(struct hlist_node *n) +{ + if (n->pprev) { + __hlist_del(n); + INIT_HLIST_NODE(n); + } +} + +static __inline__ void hlist_add_head(struct hlist_node *n, struct hlist_head *h) +{ + struct hlist_node *first = h->first; + n->next = first; + if (first) + first->pprev = &n->next; + h->first = n; + n->pprev = &h->first; +} + +/* next must be != NULL */ +static __inline__ void hlist_add_before(struct hlist_node *n, struct hlist_node *next) +{ + n->pprev = next->pprev; + n->next = next; + next->pprev = &n->next; + *(n->pprev) = n; +} + +static __inline__ void hlist_add_after(struct hlist_node *n, + struct hlist_node *next) +{ + next->next = n->next; + *(next->pprev) = n; + n->next = next; +} + +#define hlist_entry(ptr, type, member) container_of(ptr,type,member) + +/* Cannot easily do prefetch unfortunately */ +#define hlist_for_each(pos, head) \ + for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ + pos = pos->next) + +#define hlist_for_each_safe(pos, n, head) \ + for (pos = (head)->first; n = pos ? pos->next : 0, pos; \ + pos = n) + +/** + * hlist_for_each_entry - iterate over list of given type + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry(tpos, pos, head, member) \ + for (pos = (head)->first; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_continue(tpos, pos, member) \ + for (pos = (pos)->next; \ + pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_from - iterate over a hlist continuing from existing point + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_from(tpos, pos, member) \ + for (; pos && ({ prefetch(pos->next); 1;}) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = pos->next) + +/** + * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @tpos: the type * to use as a loop counter. + * @pos: the &struct hlist_node to use as a loop counter. + * @n: another &struct hlist_node to use as temporary storage + * @head: the head for your list. + * @member: the name of the hlist_node within the struct. + */ +#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ + for (pos = (head)->first; \ + pos && ({ n = pos->next; 1; }) && \ + ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ + pos = n) + +#endif diff --git a/namedev.c b/namedev.c new file mode 100644 index 0000000000..ee122cf075 --- /dev/null +++ b/namedev.c @@ -0,0 +1,345 @@ +/* + * namedev.c + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "list.h" +#include "udev.h" +#include "udev_version.h" +#include "namedev.h" + +#define TYPE_LABEL "LABEL" +#define TYPE_NUMBER "NUMBER" +#define TYPE_TOPOLOGY "TOPOLOGY" +#define TYPE_REPLACE "REPLACE" + +enum config_type { + KERNEL_NAME = 0, /* must be 0 to let memset() default to this value */ + LABEL = 1, + NUMBER = 2, + TOPOLOGY = 3, + REPLACE = 4, +}; + +#define BUS_SIZE 30 +#define FILE_SIZE 50 +#define VALUE_SIZE 100 +#define ID_SIZE 50 +#define PLACE_SIZE 50 +#define NAME_SIZE 100 +#define OWNER_SIZE 30 +#define GROUP_SIZE 30 + + +struct config_device { + struct list_head node; + + enum config_type type; + + char bus[BUS_SIZE]; + char sysfs_file[FILE_SIZE]; + char sysfs_value[VALUE_SIZE]; + char id[ID_SIZE]; + char place[PLACE_SIZE]; + char kernel_name[NAME_SIZE]; + + /* what to set the device to */ + int mode; + char name[NAME_SIZE]; + char owner[OWNER_SIZE]; + char group[GROUP_SIZE]; +}; + + +static LIST_HEAD(config_device_list); + +#define copy_var(a, b, var) \ + if (b->var) \ + b->var = a->var; + +#define copy_string(a, b, var) \ + if (strlen(b->var)) \ + strcpy(b->var, a->var); + +static int add_dev(struct config_device *new_dev) +{ + struct list_head *tmp; + struct config_device *tmp_dev; + + /* loop through the whole list of devices to see if we already have + * this one... */ + list_for_each(tmp, &config_device_list) { + struct config_device *dev = list_entry(tmp, struct config_device, node); + if (strcmp(dev->name, new_dev->name) == 0) { + /* the same, copy the new info into this structure */ + copy_var(new_dev, dev, type); + copy_var(new_dev, dev, mode); + copy_string(new_dev, dev, bus); + copy_string(new_dev, dev, sysfs_file); + copy_string(new_dev, dev, sysfs_value); + copy_string(new_dev, dev, id); + copy_string(new_dev, dev, place); + copy_string(new_dev, dev, kernel_name); + copy_string(new_dev, dev, owner); + copy_string(new_dev, dev, group); + return 0; + } + } + + /* not found, lets create a new structure, and add it to the list */ + tmp_dev = malloc(sizeof(*tmp_dev)); + if (!tmp_dev) + return -ENOMEM; + memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); + list_add(&tmp_dev->node, &config_device_list); + return 0; +} + +static int get_value(const char *left, char **orig_string, char **ret_string) +{ + char *temp; + char *string = *orig_string; + + /* eat any whitespace */ + while (isspace(*string)) + ++string; + + /* split based on '=' */ + temp = strsep(&string, "="); + if (strcasecmp(temp, left) == 0) { + /* got it, now strip off the '"' */ + while (isspace(*string)) + ++string; + if (*string == '"') + ++string; + temp = strsep(&string, "\""); + *ret_string = temp; + *orig_string = string; + return 0; + } + return -ENODEV; +} + + +static int namedev_init_config(void) +{ + char filename[255]; + char line[255]; + char *temp; + char *temp2; + char *temp3; + FILE *fd; + int retval = 0; + struct config_device dev; + + strcpy(filename, NAMEDEV_CONFIG_ROOT NAMEDEV_CONFIG_FILE); + dbg("opening %s to read as permissions config", filename); + fd = fopen(filename, "r"); + if (fd == NULL) { + dbg("Can't open %s", filename); + return -ENODEV; + } + + /* loop through the whole file */ + while (1) { + /* get a line */ + temp = fgets(line, sizeof(line), fd); + if (temp == NULL) + break; + + dbg("read %s", temp); + + /* eat the whitespace at the beginning of the line */ + while (isspace(*temp)) + ++temp; + + /* no more line? */ + if (*temp == 0x00) + continue; + + /* see if this is a comment */ + if (*temp == COMMENT_CHARACTER) + continue; + + memset(&dev, 0x00, sizeof(dev)); + + /* parse the line */ + temp2 = strsep(&temp, ","); + if (strcasecmp(temp2, TYPE_LABEL) == 0) { + /* label type */ + dev.type = LABEL; + + /* BUS="bus" */ + retval = get_value("BUS", &temp, &temp3); + if (retval) + continue; + strcpy(dev.bus, temp3); + dbg("LABEL name = %s, bus = %s", dev.name, dev.bus); + } + + if (strcasecmp(temp2, TYPE_NUMBER) == 0) { + /* number type */ + dev.type = NUMBER; + + /* BUS="bus" */ + retval = get_value("BUS", &temp, &temp3); + if (retval) + continue; + strcpy(dev.bus, temp3); + dbg("NUMBER name = %s, bus = %s", dev.name, dev.bus); + } + + if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { + /* number type */ + dev.type = TOPOLOGY; + + /* BUS="bus" */ + retval = get_value("BUS", &temp, &temp3); + if (retval) + continue; + strcpy(dev.bus, temp3); + dbg("TOPOLOGY name = %s, bus = %s", dev.name, dev.bus); + } + + if (strcasecmp(temp2, TYPE_REPLACE) == 0) { + /* number type */ + dev.type = REPLACE; + + /* KERNEL="kernel_name" */ + retval = get_value("KERNEL", &temp, &temp3); + if (retval) + continue; + strcpy(dev.kernel_name, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + continue; + strcpy(dev.name, temp3); + dbg("REPLACE name = %s, kernel_name = %s", dev.name, dev.kernel_name); + } + + retval = add_dev(&dev); + if (retval) { + dbg("add_dev returned with error %d", retval); + goto exit; + } + } + +exit: + fclose(fd); + return retval; +} + + +static int namedev_init_permissions(void) +{ + char filename[255]; + char line[255]; + char *temp; + char *temp2; + FILE *fd; + int retval = 0; + struct config_device dev; + + strcpy(filename, NAMEDEV_CONFIG_ROOT NAMEDEV_CONFIG_PERMISSION_FILE); + dbg("opening %s to read as permissions config", filename); + fd = fopen(filename, "r"); + if (fd == NULL) { + dbg("Can't open %s", filename); + return -ENODEV; + } + + /* loop through the whole file */ + while (1) { + /* get a line */ + temp = fgets(line, sizeof(line), fd); + if (temp == NULL) + break; + + dbg("read %s", temp); + + /* eat the whitespace at the beginning of the line */ + while (isspace(*temp)) + ++temp; + + /* no more line? */ + if (*temp == 0x00) + continue; + + /* see if this is a comment */ + if (*temp == COMMENT_CHARACTER) + continue; + + memset(&dev, 0x00, sizeof(dev)); + + /* parse the line */ + temp2 = strsep(&temp, ":"); + strncpy(dev.name, temp2, sizeof(dev.name)); + + temp2 = strsep(&temp, ":"); + strncpy(dev.owner, temp2, sizeof(dev.owner)); + + temp2 = strsep(&temp, ":"); + strncpy(dev.group, temp2, sizeof(dev.owner)); + + dev.mode = strtol(temp, NULL, 8); + + dbg("name = %s, owner = %s, group = %s, mode = %x", dev.name, dev.owner, dev.group, dev.mode); + retval = add_dev(&dev); + if (retval) { + dbg("add_dev returned with error %d", retval); + goto exit; + } + } + +exit: + fclose(fd); + return retval; +} + + + +int namedev_init(void) +{ + int retval; + + retval = namedev_init_config(); + if (retval) + return retval; + + retval = namedev_init_permissions(); + if (retval) + return retval; + + return retval; +} + diff --git a/namedev.config b/namedev.config new file mode 100644 index 0000000000..a26562342c --- /dev/null +++ b/namedev.config @@ -0,0 +1,21 @@ +# USB Epson printer to be called lp_epson +LABEL, BUS="usb", serial="HXOLL0012202323480", NAME="lp_epson" + +# USB HP printer to be called lp_hp +LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_hp" + +# sound card with PCI bus id 00:0b.0 to be the first sound card +NUMBER, BUS="pci", id="00:0b.0", NAME="dsp" + +# sound card with PCI bus id 00:07.1 to be the second sound card +NUMBER, BUS="pci", id="00:07.1", NAME="dsp1" + +# USB mouse plugged into the third port of the first hub to be called mouse0 +TOPOLOGY, BUS="usb", place="1.3", NAME="mouse0" + +# USB tablet plugged into the second port of the second hub to be called mouse1 +TOPOLOGY, BUS="usb", place="2.2", NAME="mouse1" + +# ttyUSB1 should always be called visor +REPLACE, KERNEL="ttyUSB1", NAME="visor" + diff --git a/namedev.h b/namedev.h new file mode 100644 index 0000000000..0089b4d240 --- /dev/null +++ b/namedev.h @@ -0,0 +1,34 @@ +/* + * namedev.h + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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 NAMEDEV_H +#define NAMEDEV_H + +/* namedev config files */ +#define COMMENT_CHARACTER '#' +#define NAMEDEV_CONFIG_ROOT "/home/greg/src/udev/" +#define NAMEDEV_CONFIG_PERMISSION_FILE "namedev.permissions" +#define NAMEDEV_CONFIG_FILE "namedev.config" + +extern int namedev_init(void); + +#endif diff --git a/namedev.permissions b/namedev.permissions new file mode 100644 index 0000000000..6148a15e49 --- /dev/null +++ b/namedev.permissions @@ -0,0 +1,4 @@ +#name:user:group:mode +ttyUSB0:root:uucp:0666 +ttyUSB1:root:uucp:0666 + diff --git a/udev.c b/udev.c index de6b6565f2..bf170d1651 100644 --- a/udev.c +++ b/udev.c @@ -30,6 +30,7 @@ #include "udev.h" #include "udev_version.h" +#include "namedev.h" static char *get_action(void) @@ -262,6 +263,8 @@ int main(int argc, char *argv[]) goto exit; } + namedev_init(); + /* sleep for a second or two to give the kernel a chance to * create the dev file */ diff --git a/udev.h b/udev.h index f4f4f11f2d..fb35cad49a 100644 --- a/udev.h +++ b/udev.h @@ -49,8 +49,6 @@ /* Binaries that udev calls to do stuff */ #define MKNOD "/bin/mknod" - - extern int log_message (int level, const char *format, ...); From fe3004330107036de22c067f7ba49d6770596072 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 17 Jul 2003 01:49:00 -0700 Subject: [PATCH 0015/4284] [PATCH] added klibc makefile --- Makefile.klibc | 158 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 Makefile.klibc diff --git a/Makefile.klibc b/Makefile.klibc new file mode 100644 index 0000000000..d196d6f547 --- /dev/null +++ b/Makefile.klibc @@ -0,0 +1,158 @@ +# Makefile for diethotplug +# +# Copyright (C) 2000,2001 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. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +# Set the following to `true' to make a debuggable build. +# Leave this set to `false' for production use. +DEBUG = true + + +ROOT = udev +VERSION = 0.1 +INSTALL_DIR = /usr/local/bin +RELEASE_NAME = $(ROOT)-$(VERSION) + + +# Comment out this line to build with something other +# than the local version of klibc +KLIBC = true + +# If you are running a cross compiler, you may want to set this +# to something more interesting, like "arm-linux-". I you want +# to compile vs uClibc, that can be done here as well. +CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- +CC = $(CROSS)gcc +AR = $(CROSS)ar +STRIP = $(CROSS)strip + + +# code taken from uClibc to determine the current arch +ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ + -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/ppc/powerpc/g'} + +# code taken from uClibc to determine the gcc include dir +GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} + +# code taken from uClibc to determine the libgcc.a filename +GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) + +# use '-Os' optimization if available, else use -O2 +OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ + then echo "-Os"; else echo "-O2" ; fi} + +WARNINGS := -Wall -Wshadow -Wstrict-prototypes + +# Some nice architecture specific optimizations +ifeq ($(strip $(TARGET_ARCH)),arm) + OPTIMIZATION+=-fstrict-aliasing +endif +ifeq ($(strip $(TARGET_ARCH)),i386) + OPTIMIZATION+=-march=i386 + OPTIMIZATION += ${shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc \ + /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi} + OPTIMIZATION += ${shell if $(CC) -malign-functions=0 -malign-jumps=0 -S -o /dev/null -xc \ + /dev/null >/dev/null 2>&1; then echo "-malign-functions=0 -malign-jumps=0"; fi} + CFLAGS+=-pipe +else + CFLAGS+=-pipe +endif + +# if DEBUG is enabled, then we do not strip or optimize +ifeq ($(strip $(DEBUG)),true) + CFLAGS += $(WARNINGS) -O1 -g -DDEBUG -D_GNU_SOURCE + LDFLAGS += -Wl,-warn-common + STRIPCMD = /bin/true -Since_we_are_debugging +else + CFLAGS += $(WARNINGS) $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE + LDFLAGS += -s -Wl,-warn-common + STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment +endif + +# If we are using our version of klibc, then we need to build and link it. +# Otherwise, use glibc and link statically. +ifeq ($(strip $(KLIBC)),true) + KLIBC_DIR = /home/greg/src/klibc/klibc/klibc + INCLUDE_DIR := $(KLIBC_DIR)/include + # arch specific objects + LIBGCC = $(shell $(CC) --print-libgcc) + ARCH_LIB_OBJS = \ + $(KLIBC_DIR)/libc.a \ +# $(KLIBC_DIR)/crt0.o \ +# $(LIBGCC) +# $(KLIBC_DIR)/bin-$(ARCH)/start.o \ +# $(KLIBC_DIR)/bin-$(ARCH)/klibc.a + +# LIB_OBJS = $(GCC_LIB) + + LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) + CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I/home/greg/linux/linux-2.5/include -I$(GCCINCDIR) + LDFLAGS = +# LDFLAGS = --static --nostdlib -nostartfiles +else + LIBC = + CFLAGS += -I$(GCCINCDIR) + LIB_OBJS = -lc + LDFLAGS = --static +endif + +all: $(LIBC) $(ROOT) + +$(ARCH_LIB_OBJS) : + $(MAKE) -C klibc + +OBJS = udev.o \ + logging.o \ + namedev.o + + +# header files automatically generated +GEN_HEADERS = udev_version.h + +# Rules on how to create the generated header files +udev_version.h: + @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + + +$(ROOT): $(GEN_HEADERS) $(OBJS) +# $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $(ROOT) $(KLIBC_DIR)/crt0.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $(ROOT) + +clean: + -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ + | xargs rm -f + -rm -f core $(ROOT) $(GEN_HEADERS) + $(MAKE) -C klibc clean + +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS ) +DISTDIR := $(RELEASE_NAME) +srcdir = . +release: $(DISTFILES) clean +# @echo $(DISTFILES) + @-rm -rf $(DISTDIR) + @mkdir $(DISTDIR) + @-chmod 777 $(DISTDIR) + @for file in $(DISTFILES); do \ + if test -d $$file; then \ + mkdir $(DISTDIR)/$$file; \ + else \ + cp -p $$file $(DISTDIR)/$$file; \ + fi; \ + done + @tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz + @rm -rf $(DISTDIR) + @echo "Built $(RELEASE_NAME).tar.gz" From 032abea6fb9f0203dc22d46a1f48326b7da8182c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 18 Jul 2003 07:45:35 -0700 Subject: [PATCH 0016/4284] [PATCH] make log_message spit out warnings so I don't have --- udev.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udev.h b/udev.h index fb35cad49a..af1b6bbb8d 100644 --- a/udev.h +++ b/udev.h @@ -49,7 +49,8 @@ /* Binaries that udev calls to do stuff */ #define MKNOD "/bin/mknod" -extern int log_message (int level, const char *format, ...); +extern int log_message (int level, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); #endif From 3cc78d26379acfbfc68d178b9ee58e9f7e75a725 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 18 Jul 2003 07:45:48 -0700 Subject: [PATCH 0017/4284] [PATCH] more permission tests --- namedev.permissions | 2 ++ 1 file changed, 2 insertions(+) diff --git a/namedev.permissions b/namedev.permissions index 6148a15e49..7f87fc9b0e 100644 --- a/namedev.permissions +++ b/namedev.permissions @@ -1,4 +1,6 @@ #name:user:group:mode ttyUSB0:root:uucp:0666 ttyUSB1:root:uucp:0666 +visor:root:uucp:0666 +dsp1:::0666 From 469c7cff3b1432aa7a8786c08ee9a64caec2ba27 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 18 Jul 2003 07:46:17 -0700 Subject: [PATCH 0018/4284] [PATCH] namedev config files are fully parsed. now to do something with the data... --- namedev.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 136 insertions(+), 16 deletions(-) diff --git a/namedev.c b/namedev.c index ee122cf075..0271ba55a2 100644 --- a/namedev.c +++ b/namedev.c @@ -80,13 +80,51 @@ struct config_device { static LIST_HEAD(config_device_list); +static void dump_dev(struct config_device *dev) +{ + switch (dev->type) { + case KERNEL_NAME: + dbg("KERNEL name ='%s'" + " owner = '%s', group = '%s', mode = '%d'", + dev->name, + dev->owner, dev->group, dev->mode); + break; + case LABEL: + dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" + " owner = '%s', group = '%s', mode = '%d'", + dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, + dev->owner, dev->group, dev->mode); + break; + case NUMBER: + dbg("NUMBER name = '%s', bus = '%s', id = '%s'" + " owner = '%s', group = '%s', mode = '%d'", + dev->name, dev->bus, dev->id, + dev->owner, dev->group, dev->mode); + break; + case TOPOLOGY: + dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'" + " owner = '%s', group = '%s', mode = '%d'", + dev->name, dev->bus, dev->place, + dev->owner, dev->group, dev->mode); + break; + case REPLACE: + dbg("REPLACE name = %s, kernel_name = %s" + " owner = '%s', group = '%s', mode = '%d'", + dev->name, dev->kernel_name, + dev->owner, dev->group, dev->mode); + break; + default: + dbg("Unknown type of device!"); + } +} + #define copy_var(a, b, var) \ if (b->var) \ - b->var = a->var; + a->var = b->var; #define copy_string(a, b, var) \ if (strlen(b->var)) \ - strcpy(b->var, a->var); + strcpy(a->var, b->var); static int add_dev(struct config_device *new_dev) { @@ -99,16 +137,16 @@ static int add_dev(struct config_device *new_dev) struct config_device *dev = list_entry(tmp, struct config_device, node); if (strcmp(dev->name, new_dev->name) == 0) { /* the same, copy the new info into this structure */ - copy_var(new_dev, dev, type); - copy_var(new_dev, dev, mode); - copy_string(new_dev, dev, bus); - copy_string(new_dev, dev, sysfs_file); - copy_string(new_dev, dev, sysfs_value); - copy_string(new_dev, dev, id); - copy_string(new_dev, dev, place); - copy_string(new_dev, dev, kernel_name); - copy_string(new_dev, dev, owner); - copy_string(new_dev, dev, group); + copy_var(dev, new_dev, type); + copy_var(dev, new_dev, mode); + copy_string(dev, new_dev, bus); + copy_string(dev, new_dev, sysfs_file); + copy_string(dev, new_dev, sysfs_value); + copy_string(dev, new_dev, id); + copy_string(dev, new_dev, place); + copy_string(dev, new_dev, kernel_name); + copy_string(dev, new_dev, owner); + copy_string(dev, new_dev, group); return 0; } } @@ -119,9 +157,20 @@ static int add_dev(struct config_device *new_dev) return -ENOMEM; memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); list_add(&tmp_dev->node, &config_device_list); + //dump_dev(tmp_dev); return 0; } +static void dump_dev_list(void) +{ + struct list_head *tmp; + + list_for_each(tmp, &config_device_list) { + struct config_device *dev = list_entry(tmp, struct config_device, node); + dump_dev(dev); + } +} + static int get_value(const char *left, char **orig_string, char **ret_string) { char *temp; @@ -147,6 +196,30 @@ static int get_value(const char *left, char **orig_string, char **ret_string) return -ENODEV; } +static int get_pair(char **orig_string, char **left, char **right) +{ + char *temp; + char *string = *orig_string; + + /* eat any whitespace */ + while (isspace(*string)) + ++string; + + /* split based on '=' */ + temp = strsep(&string, "="); + *left = temp; + + /* take the right side and strip off the '"' */ + while (isspace(*string)) + ++string; + if (*string == '"') + ++string; + temp = strsep(&string, "\""); + *right = temp; + *orig_string = string; + + return 0; +} static int namedev_init_config(void) { @@ -188,7 +261,7 @@ static int namedev_init_config(void) if (*temp == COMMENT_CHARACTER) continue; - memset(&dev, 0x00, sizeof(dev)); + memset(&dev, 0x00, sizeof(struct config_device)); /* parse the line */ temp2 = strsep(&temp, ","); @@ -201,7 +274,23 @@ static int namedev_init_config(void) if (retval) continue; strcpy(dev.bus, temp3); - dbg("LABEL name = %s, bus = %s", dev.name, dev.bus); + + /* file="value" */ + temp2 = strsep(&temp, ","); + retval = get_pair(&temp, &temp2, &temp3); + if (retval) + continue; + strcpy(dev.sysfs_file, temp2); + strcpy(dev.sysfs_value, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + continue; + strcpy(dev.name, temp3); + + dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'", dev.name, dev.bus, dev.sysfs_file, dev.sysfs_value); } if (strcasecmp(temp2, TYPE_NUMBER) == 0) { @@ -213,7 +302,22 @@ static int namedev_init_config(void) if (retval) continue; strcpy(dev.bus, temp3); - dbg("NUMBER name = %s, bus = %s", dev.name, dev.bus); + + /* ID="id" */ + temp2 = strsep(&temp, ","); + retval = get_value("id", &temp, &temp3); + if (retval) + continue; + strcpy(dev.id, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + continue; + strcpy(dev.name, temp3); + + dbg("NUMBER name = '%s', bus = '%s', id = '%s'", dev.name, dev.bus, dev.id); } if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { @@ -225,7 +329,22 @@ static int namedev_init_config(void) if (retval) continue; strcpy(dev.bus, temp3); - dbg("TOPOLOGY name = %s, bus = %s", dev.name, dev.bus); + + /* PLACE="place" */ + temp2 = strsep(&temp, ","); + retval = get_value("place", &temp, &temp3); + if (retval) + continue; + strcpy(dev.place, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + continue; + strcpy(dev.name, temp3); + + dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'", dev.name, dev.bus, dev.place); } if (strcasecmp(temp2, TYPE_REPLACE) == 0) { @@ -340,6 +459,7 @@ int namedev_init(void) if (retval) return retval; + dump_dev_list(); return retval; } From 070f54223f66490e9d25719c495e074f77da8985 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 18 Jul 2003 20:08:00 -0700 Subject: [PATCH 0019/4284] [PATCH] added libsysfs code from sysutils-0.1.1-071803 release --- libsysfs/LGPL | 441 +++++++++++++++++++++++++++++++++++ libsysfs/Makefile | 44 ++++ libsysfs/libsysfs.h | 162 +++++++++++++ libsysfs/sysfs.h | 49 ++++ libsysfs/sysfs_bus.c | 301 ++++++++++++++++++++++++ libsysfs/sysfs_class.c | 273 ++++++++++++++++++++++ libsysfs/sysfs_device.c | 199 ++++++++++++++++ libsysfs/sysfs_dir.c | 496 ++++++++++++++++++++++++++++++++++++++++ libsysfs/sysfs_driver.c | 89 +++++++ libsysfs/sysfs_utils.c | 156 +++++++++++++ 10 files changed, 2210 insertions(+) create mode 100644 libsysfs/LGPL create mode 100644 libsysfs/Makefile create mode 100644 libsysfs/libsysfs.h create mode 100644 libsysfs/sysfs.h create mode 100644 libsysfs/sysfs_bus.c create mode 100644 libsysfs/sysfs_class.c create mode 100644 libsysfs/sysfs_device.c create mode 100644 libsysfs/sysfs_dir.c create mode 100644 libsysfs/sysfs_driver.c create mode 100644 libsysfs/sysfs_utils.c diff --git a/libsysfs/LGPL b/libsysfs/LGPL new file mode 100644 index 0000000000..e00a829bb6 --- /dev/null +++ b/libsysfs/LGPL @@ -0,0 +1,441 @@ + + GNU Lesser Public License + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + [This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your freedom to + share and change it. By contrast, the GNU General Public Licenses are + intended to guarantee your freedom to share and change free software--to + make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some specially + designated software packages--typically libraries--of the Free Software + Foundation and other authors who decide to use it. You can use it too, but + we suggest you first think carefully about whether this license or the + ordinary General Public License is the better strategy to use in any + particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free + programs; and that you are informed that you can do these things. + + To protect your rights, we need to make restrictions that forbid + distributors to deny you these rights or to ask you to surrender these + rights. These restrictions translate to certain responsibilities for you + if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis or + for a fee, you must give the recipients all the rights that we gave you. + You must make sure that they, too, receive or can get the source code. If + you link other code with the library, you must provide complete object + files to the recipients, so that they can relink them with the library + after making changes to the library and recompiling it. And you must show + them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the + library, and (2) we offer you this license, which gives you legal + permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that there is + no warranty for the free library. Also, if the library is modified by + someone else and passed on, the recipients should know that what they have + is not the original version, so that the original author's reputation will + not be affected by problems that might be introduced by others. + + Finally, software patents pose a constant threat to the existence of any + free program. We wish to make sure that a company cannot effectively + restrict the users of a free program by obtaining a restrictive license + from a patent holder. Therefore, we insist that any patent license + obtained for a version of the library must be consistent with the full + freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the ordinary + GNU General Public License. This license, the GNU Lesser General Public + License, applies to certain designated libraries, and is quite different + from the ordinary General Public License. We use this license for certain + libraries in order to permit linking those libraries into non-free + programs. + + When a program is linked with a library, whether statically or using a + shared library, the combination of the two is legally speaking a combined + work, a derivative of the original library. The ordinary General Public + License therefore permits such linking only if the entire combination fits + its criteria of freedom. The Lesser General Public License permits more + lax criteria for linking other code with the library. + + We call this license the "Lesser" General Public License because it does + Less to protect the user's freedom than the ordinary General Public + License. It also provides other free software developers Less of an + advantage over competing non-free programs. These disadvantages are the + reason we use the ordinary General Public License for many libraries. + However, the Lesser license provides advantages in certain special + circumstances. + + For example, on rare occasions, there may be a special need to encourage + the widest possible use of a certain library, so that it becomes a + de-facto standard. To achieve this, non-free programs must be allowed to + use the library. A more frequent case is that a free library does the same + job as widely used non-free libraries. In this case, there is little to + gain by limiting the free library to free software only, so we use the + Lesser General Public License. + + In other cases, permission to use a particular library in non-free + programs enables a greater number of people to use a large body of free + software. For example, permission to use the GNU C Library in non-free + programs enables many more people to use the whole GNU operating system, + as well as its variant, the GNU/Linux operating system. + + Although the Lesser General Public License is Less protective of the + users' freedom, it does ensure that the user of a program that is linked + with the Library has the freedom and the wherewithal to run that program + using a modified version of the Library. + + The precise terms and conditions for copying, distribution and + modification follow. Pay close attention to the difference between a "work + based on the library" and a "work that uses the library". The former + contains code derived from the library, whereas the latter must be + combined with the library in order to run. + + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other program + which contains a notice placed by the copyright holder or other authorized + party saying it may be distributed under the terms of this Lesser General + Public License (also called "this License"). Each licensee is addressed as + "you". + + A "library" means a collection of software functions and/or data prepared + so as to be conveniently linked with application programs (which use some + of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work which + has been distributed under these terms. A "work based on the Library" + means either the Library or any derivative work under copyright law: that + is to say, a work containing the Library or a portion of it, either + verbatim or with modifications and/or translated straightforwardly into + another language. (Hereinafter, translation is included without limitation + in the term "modification".) + + "Source code" for a work means the preferred form of the work for making + modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running a + program using the Library is not restricted, and output from such a + program is covered only if its contents constitute a work based on the + Library (independent of the use of the Library in a tool for writing it). + Whether that is true depends on what the Library does and what the program + that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's complete + 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 + distribute a copy of this License along with the Library. + + 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 Library or any portion of it, + thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices stating + that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no charge to + all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a table + of data to be supplied by an application program that uses the facility, + other than as an argument passed when the facility is invoked, then you + must make a good faith effort to ensure that, in the event an + application does not supply such function or table, the facility still + operates, and performs whatever part of its purpose remains meaningful. + + (For example, a function in a library to compute square roots has a + purpose that is entirely well-defined independent of the application. + Therefore, Subsection 2d requires that any application-supplied function + or table used by this function must be optional: if the application does + not supply it, the square root function must still compute square + roots.) + + These requirements apply to the modified work as a whole. If + identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. + + In addition, mere aggregation of another work not based on the Library + with the Library (or with a work based on the Library) on a volume of a + storage or distribution medium does not bring the other work under the + scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public + License instead of this License to a given copy of the Library. To do + this, you must alter all the notices that refer to this License, so that + they refer to the ordinary GNU General Public License, version 2, instead + of to this License. (If a newer version than version 2 of the ordinary GNU + General Public License has appeared, then you can specify that version + instead if you wish.) Do not make any other change in these notices. + + Once this change is made in a given copy, it is irreversible for that + copy, so the ordinary GNU General Public License applies to all subsequent + copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of the + Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or derivative of + it, under Section 2) in object code or executable form under the terms of + Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to distribute the source + code, even though third parties are not compelled to copy the source along + with the object code. + + 5. A program that contains no derivative of any portion of the Library, + but is designed to work with the Library by being compiled or linked with + it, is called a "work that uses the Library". Such a work, in isolation, + is not a derivative work of the Library, and therefore falls outside the + scope of this License. + + However, linking a "work that uses the Library" with the Library creates + an executable that is a derivative of the Library (because it contains + portions of the Library), rather than a "work that uses the library". The + executable is therefore covered by this License. Section 6 states terms + for distribution of such executables. + + When a "work that uses the Library" uses material from a header file that + is part of the Library, the object code for the work may be a derivative + work of the Library even though the source code is not. Whether this is + true is especially significant if the work can be linked without the + Library, or if the work is itself a library. The threshold for this to be + true is not precisely defined by law. + + If such an object file uses only numerical parameters, data structure + layouts and accessors, and small macros and small inline functions (ten + lines or less in length), then the use of the object file is unrestricted, + regardless of whether it is legally a derivative work. (Executables + containing this object code plus portions of the Library will still fall + under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may distribute + the object code for the work under the terms of Section 6. Any executables + containing that work also fall under Section 6, whether or not they are + linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or link a + "work that uses the Library" with the Library to produce a work containing + portions of the Library, and distribute that work under terms of your + choice, provided that the terms permit modification of the work for the + customer's own use and reverse engineering for debugging such + modifications. + + You must give prominent notice with each copy of the work that the Library + is used in it and that the Library and its use are covered by this + License. You must supply a copy of this License. If the work during + execution displays copyright notices, you must include the copyright + notice for the Library among them, as well as a reference directing the + user to the copy of this License. Also, you must do one of these things: + + a) Accompany the work with the complete corresponding machine-readable + source code for the Library including whatever changes were used in the + work (which must be distributed under Sections 1 and 2 above); and, if + the work is an executable linked with the Library, with the complete + machine-readable "work that uses the Library", as object code and/or + source code, so that the user can modify the Library and then relink to + produce a modified executable containing the modified Library. (It is + understood that the user who changes the contents of definitions files + in the Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the Library. + A suitable mechanism is one that (1) uses at run time a copy of the + library already present on the user's computer system, rather than + copying library functions into the executable, and (2) will operate + properly with a modified version of the library, if the user installs + one, as long as the modified version is interface-compatible with the + version that the work was made with. + + c) Accompany the work with a written offer, valid for at least three + years, to give the same user the materials specified in Subsection 6a, + above, for a charge no more than the cost of performing this + distribution. + + d) If distribution of the work is made by offering access to copy from a + designated place, offer equivalent access to copy the above specified + materials from the same place. + + e) Verify that the user has already received a copy of these materials + or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the Library" + must include any data and utility programs needed for reproducing the + executable from it. However, as a special exception, the materials to be + 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. + + It may happen that this requirement contradicts the license restrictions + of other proprietary libraries that do not normally accompany the + operating system. Such a contradiction means you cannot use both them and + the Library together in an executable that you distribute. + + 7. You may place library facilities that are a work based on the Library + side-by-side in a single library together with other library facilities + not covered by this License, and distribute such a combined library, + provided that the separate distribution of the work based on the Library + and of the other library facilities is otherwise permitted, and provided + that you do these two things: + + a) Accompany the combined library with a copy of the same work based on + the Library, uncombined with any other library facilities. This must be + distributed under the terms of the Sections above. + + b) Give prominent notice with the combined library of the fact that part + of it is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute the + Library except as expressly provided under this License. Any attempt + otherwise to copy, modify, sublicense, link with, or distribute the + Library 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. + + 9. 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 Library or its derivative works. These actions are prohibited by law + if you do not accept this License. Therefore, by modifying or distributing + the Library (or any work based on the Library), you indicate your + acceptance of this License to do so, and all its terms and conditions for + copying, distributing or modifying the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the + Library), the recipient automatically receives a license from the original + licensor to copy, distribute, link with or modify the Library 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 with this License. + + 11. 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 Library at all. For example, if a patent license would not + permit royalty-free redistribution of the Library 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 Library. + + 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. + + 12. If the distribution and/or use of the Library is restricted in certain + countries either by patents or by copyrighted interfaces, the original + copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new versions + of the Lesser 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 Library + 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 Library does not specify a license version + number, you may choose any version ever published by the Free Software + Foundation. + + 14. If you wish to incorporate parts of the Library into other free + programs whose distribution conditions are incompatible with these, 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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE + LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, + REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE + WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + diff --git a/libsysfs/Makefile b/libsysfs/Makefile new file mode 100644 index 0000000000..cf07a842b6 --- /dev/null +++ b/libsysfs/Makefile @@ -0,0 +1,44 @@ +# Makefile for libsysfs.a +# Copyright (c) International Business Machines Corp., 2003 + +CC=gcc + +H_INCLUDE=../include +LIB_INCLUDE=. +OBJS=sysfs_bus.o sysfs_class.o sysfs_device.o sysfs_dir.o sysfs_driver.o \ + sysfs_utils.o + +# Install directory + +# Options +CFLAGS=-O2 -Wall -ansi -g + +# sysfs library +LIBSYSFS=libsysfs.a + +RM=rm -f + +libsysfs.a: $(OBJS) + ar cru $(LIBSYSFS) $(OBJS) + ranlib $(LIBSYSFS) + +sysfs_bus.o: sysfs_bus.c + $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_bus.c + +sysfs_class.o: sysfs_class.c + $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_class.c + +sysfs_device.o: sysfs_device.c + $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_device.c + +sysfs_dir.o: sysfs_dir.c + $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_dir.c + +sysfs_driver.o: sysfs_driver.c + $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_driver.c + +sysfs_utils.o: sysfs_utils.c + $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_utils.c + +clean: + $(RM) *.o *~ core $(LIBSYSFS) diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h new file mode 100644 index 0000000000..01143954e7 --- /dev/null +++ b/libsysfs/libsysfs.h @@ -0,0 +1,162 @@ +/* + * libsysfs.h + * + * Header Definitions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _LIBSYSFS_H_ +#define _LIBSYSFS_H_ + +#include + +/* + * Generic #defines go here.. + */ +#define SYSFS_FSTYPE_NAME "sysfs" +#define SYSFS_PROC_MNTS "/proc/mounts" +#define SYSFS_BUS_DIR "/bus" +#define SYSFS_CLASS_DIR "/class" +#define SYSFS_DEVICES_DIR "/devices" +#define SYSFS_DEVICES_NAME "devices" +#define SYSFS_DRIVERS_DIR "/drivers" +#define SYSFS_DRIVERS_NAME "drivers" +#define SYSFS_NAME_ATTRIBUTE "name" + +#define SYSFS_PATH_MAX 255 +#define SYSFS_NAME_LEN 50 +#define SYSFS_BUS_ID_SIZE 20 + +#define SYSFS_METHOD_SHOW 0x01 /* attr can be read by user */ +#define SYSFS_METHOD_STORE 0x02 /* attr can be changed by user */ + +struct sysfs_attribute { + struct sysfs_attribute *next; + char path[SYSFS_PATH_MAX]; + char *value; + unsigned short len; /* value length */ + unsigned short method; /* show and store */ +}; + +struct sysfs_dlink { + struct sysfs_dlink *next; + char name[SYSFS_NAME_LEN]; + struct sysfs_directory *target; +}; + +struct sysfs_directory { + struct sysfs_directory *next; + char path[SYSFS_PATH_MAX]; + struct sysfs_directory *subdirs; + struct sysfs_dlink *links; + struct sysfs_attribute *attributes; +}; + +struct sysfs_driver { + struct sysfs_driver *next; + char name[SYSFS_NAME_LEN]; + struct sysfs_directory *directory; + struct sysfs_device *device; +}; + +struct sysfs_device { + struct sysfs_device *next; + char name[SYSFS_NAME_LEN]; + char bus_id[SYSFS_NAME_LEN]; + struct sysfs_driver *driver; + struct sysfs_directory *directory; + struct sysfs_device *parent; + struct sysfs_device *children; +}; + +struct sysfs_bus { + struct sysfs_bus *next; + char name[SYSFS_NAME_LEN]; + struct sysfs_directory *directory; + struct sysfs_driver *drivers; + struct sysfs_device *devices; +}; + +struct sysfs_class_device { + struct sysfs_class_device *next; + char name[SYSFS_NAME_LEN]; + struct sysfs_directory *directory; + struct sysfs_device *sysdevice; /* NULL if virtual */ + struct sysfs_driver *driver; /* NULL if not implemented */ +}; + +struct sysfs_class { + struct sysfs_class *next; + char name[SYSFS_NAME_LEN]; + struct sysfs_directory *directory; + struct sysfs_class_device *devices; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Function Prototypes + */ +extern int sysfs_get_mnt_path(char *mnt_path, size_t len); +extern int sysfs_get_name_from_path(const char *path, char *name, size_t len); +extern int sysfs_get_link(const char *path, char *target, size_t len); + +/* sysfs directory and file access */ +extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); +extern struct sysfs_attribute *sysfs_open_attribute(const char *path); +extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); +extern int sysfs_read_attribute_value(const char *attrpath, char *value, + size_t vsize); +extern char *sysfs_get_value_from_attributes(struct sysfs_attribute *attr, + const char * name); +extern void sysfs_close_directory(struct sysfs_directory *sysdir); +extern struct sysfs_directory *sysfs_open_directory(const char *path); +extern int sysfs_read_directory(struct sysfs_directory *sysdir); +extern void sysfs_close_dlink(struct sysfs_dlink *dlink); +extern struct sysfs_dlink *sysfs_open_dlink(const char *linkpath); +extern int sysfs_read_dlinks(struct sysfs_dlink *dlink); + +/* sysfs driver access */ +extern void sysfs_close_driver(struct sysfs_driver *driver); +extern struct sysfs_driver *sysfs_open_driver(const char *path); + +/* generic sysfs device access */ +extern void sysfs_close_device(struct sysfs_device *dev); +extern void sysfs_close_device_tree(struct sysfs_device *dev); +extern struct sysfs_device *sysfs_open_device(const char *path); +extern struct sysfs_device *sysfs_open_device_tree(const char *path); +extern struct sysfs_attribute *sysfs_get_device_attr + (struct sysfs_device *dev, const char *name); + +/* generic sysfs bus access */ +extern void sysfs_close_bus(struct sysfs_bus *bus); +extern struct sysfs_bus *sysfs_open_bus(const char *name); + +/* generic sysfs class access */ +extern void sysfs_close_class_device(struct sysfs_class_device *dev); +extern struct sysfs_class_device *sysfs_open_class_device(const char *path); +extern void sysfs_close_class(struct sysfs_class *cls); +extern struct sysfs_class *sysfs_open_class(const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* _LIBSYSFS_H_ */ diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h new file mode 100644 index 0000000000..eb2a002958 --- /dev/null +++ b/libsysfs/sysfs.h @@ -0,0 +1,49 @@ +/* + * sysfs.h + * + * Internal Header Definitions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _SYSFS_H_ +#define _SYSFS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* external library functions */ +extern int lstat(const char *file_name, struct stat *buf); +extern int readlink(const char *path, char *buf, size_t bufsize); +extern int getpagesize(void); +extern int isascii(int c); + +/* Debugging */ +#ifdef DEBUG +#define dprintf(format, arg...) fprintf(stderr, format, ## arg) +#else +#define dprintf(format, arg...) do { } while (0) +#endif + +#endif /* _SYSFS_H_ */ diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c new file mode 100644 index 0000000000..b2e2b2dd71 --- /dev/null +++ b/libsysfs/sysfs_bus.c @@ -0,0 +1,301 @@ +/* + * sysfs_bus.c + * + * Generic bus utility functions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_close_bus: close single bus + * @bus: bus structure + */ +void sysfs_close_bus(struct sysfs_bus *bus) +{ + struct sysfs_device *curdev = NULL, *nextdev = NULL; + struct sysfs_driver *curdrv = NULL, *nextdrv = NULL; + + if (bus != NULL) { + if (bus->directory != NULL) + sysfs_close_directory(bus->directory); + for (curdev = bus->devices; curdev != NULL; + curdev = nextdev) { + nextdev = curdev->next; + sysfs_close_device(curdev); + } + for (curdrv = bus->drivers; curdrv != NULL; + curdrv = nextdrv) { + nextdrv = curdrv->next; + sysfs_close_driver(curdrv); + } + free(bus); + } +} + +/** + * alloc_bus: mallocs new bus structure + * returns sysfs_bus_bus struct or NULL + */ +static struct sysfs_bus *alloc_bus(void) +{ + return (struct sysfs_bus *)calloc(1, sizeof(struct sysfs_bus)); +} + +/** + * open_bus_dir: opens up sysfs bus directory + * returns sysfs_directory struct with success and NULL with error + */ +static struct sysfs_directory *open_bus_dir(const char *name) +{ + struct sysfs_directory *busdir = NULL, *cur = NULL, *next = NULL; + char buspath[SYSFS_PATH_MAX]; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + memset(buspath, 0, SYSFS_PATH_MAX); + if ((sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) != 0) { + dprintf(stderr, "Sysfs not supported on this system\n"); + return NULL; + } + + strcat(buspath, SYSFS_BUS_DIR); + strcat(buspath, "/"); + strcat(buspath, name); + busdir = sysfs_open_directory(buspath); + if (busdir == NULL) { + errno = EINVAL; + dprintf(stderr,"Bus %s not supported on this system\n", + name); + return NULL; + } + if ((sysfs_read_directory(busdir)) != 0) { + dprintf(stderr, "Error reading %s bus dir %s\n", name, + buspath); + sysfs_close_directory(busdir); + return NULL; + } + /* read in devices and drivers subdirs */ + for (cur = busdir->subdirs; cur != NULL; cur = next) { + next = cur->next; + if ((sysfs_read_directory(cur)) != 0) + continue; + } + + return busdir; +} + +/** + * add_dev_to_bus: adds a bus device to bus device list + * @bus: bus to add the device + * @dev: device to add + */ +static void add_dev_to_bus(struct sysfs_bus *bus, struct sysfs_device *dev) +{ + if (bus != NULL && dev != NULL) { + dev->next = bus->devices; + bus->devices = dev; + } +} + +/** + * add_driver_to_bus: adds a bus driver to bus driver list + * @bus: bus to add driver to + * @driver: driver to add + */ +static void add_driver_to_bus(struct sysfs_bus *bus, + struct sysfs_driver *driver) +{ + if (bus != NULL && driver != NULL) { + driver->next = bus->drivers; + bus->drivers = driver; + } +} + +/** + * get_all_bus_devices: gets all devices for bus + * @bus: bus to get devices for + * returns 0 with success and -1 with failure + */ +static int get_all_bus_devices(struct sysfs_bus *bus) +{ + struct sysfs_device *bdev = NULL; + struct sysfs_directory *cur = NULL; + struct sysfs_dlink *curl = NULL, *nextl = NULL; + char dirname[SYSFS_NAME_LEN]; + + if (bus == NULL || bus->directory == NULL) { + errno = EINVAL; + return -1; + } + for (cur = bus->directory->subdirs; cur != NULL; cur = cur->next) { + memset(dirname, 0, SYSFS_NAME_LEN); + if ((sysfs_get_name_from_path(cur->path, dirname, + SYSFS_NAME_LEN)) != 0) + continue; + if (strcmp(dirname, SYSFS_DEVICES_NAME) != 0) + continue; + for (curl = cur->links; curl != NULL; curl = nextl) { + nextl = curl->next; + bdev = sysfs_open_device(curl->target->path); + if (bdev == NULL) { + dprintf(stderr, "Error opening device at %s\n", + curl->target->path); + continue; + } + add_dev_to_bus(bus, bdev); + } + } + + return 0; +} + +/** + * get_all_bus_drivers: get all pci drivers + * @bus: pci bus to add drivers to + * returns 0 with success and -1 with error + */ +static int get_all_bus_drivers(struct sysfs_bus *bus) +{ + struct sysfs_driver *driver = NULL; + struct sysfs_directory *cur = NULL, *next = NULL; + struct sysfs_directory *cursub = NULL, *nextsub = NULL; + char dirname[SYSFS_NAME_LEN]; + + if (bus == NULL || bus->directory == NULL) { + errno = EINVAL; + return -1; + } + for (cur = bus->directory->subdirs; cur != NULL; cur = next) { + next = cur->next; + memset(dirname, 0, SYSFS_NAME_LEN); + if ((sysfs_get_name_from_path(cur->path, dirname, + SYSFS_NAME_LEN)) != 0) + continue; + if (strcmp(dirname, SYSFS_DRIVERS_NAME) != 0) + continue; + for (cursub = cur->subdirs; cursub != NULL; cursub = nextsub) { + nextsub = cursub->next; + driver = sysfs_open_driver(cursub->path); + if (driver == NULL) { + dprintf(stderr, "Error opening driver at %s\n", + cursub->path); + continue; + } + add_driver_to_bus(bus, driver); + } + } + + return 0; +} + +/** + * match_bus_device_to_driver: returns 1 if device is bound to driver + * @driver: driver to match + * @busid: busid of device to match + * returns 1 if found and 0 if not found + */ +static int match_bus_device_to_driver(struct sysfs_driver *driver, char *busid) +{ + struct sysfs_dlink *cur = NULL, *next = NULL; + int found = 0; + + if (driver == NULL || driver->directory == NULL || busid == NULL) { + errno = EINVAL; + return found; + } + for (cur = driver->directory->links; cur != NULL && found == 0; + cur = next) { + next = cur->next; + if ((strcmp(cur->name, busid)) == 0) + found++; + } + return found; +} + +/** + * link_bus_devices_to_drivers: goes through and links devices to drivers + * @bus: bus to link + */ +static void link_bus_devices_to_drivers(struct sysfs_bus *bus) +{ + struct sysfs_device *dev = NULL, *nextdev = NULL; + struct sysfs_driver *drv = NULL, *nextdrv = NULL; + + if (bus != NULL && bus->devices != NULL && bus->drivers != NULL) { + for (dev = bus->devices; dev != NULL; dev = nextdev) { + nextdev = dev->next; + + for (drv = bus->drivers; drv != NULL; drv = nextdrv) { + nextdrv = drv->next; + if ((match_bus_device_to_driver(drv, + dev->bus_id)) != 0) { + dev->driver = drv; + drv->device = dev; + } + } + } + } +} + +/** + * sysfs_open_bus: opens specific bus and all its devices on system + * returns sysfs_bus structure with success or NULL with error. + */ +struct sysfs_bus *sysfs_open_bus(const char *name) +{ + struct sysfs_bus *bus = NULL; + struct sysfs_directory *busdir = NULL; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + bus = alloc_bus(); + if (bus == NULL) { + perror("malloc"); + return NULL; + } + strcpy(bus->name, name); + busdir = open_bus_dir(name); + if (busdir == NULL) { + dprintf(stderr,"Invalid bus, %s not supported on this system\n", + name); + sysfs_close_bus(bus); + return NULL; + } + bus->directory = busdir; + if ((get_all_bus_devices(bus)) != 0) { + dprintf(stderr, "Error reading %s bus devices\n", name); + sysfs_close_bus(bus); + return NULL; + } + if ((get_all_bus_drivers(bus)) != 0) { + dprintf(stderr, "Error reading %s bus drivers\n", name); + sysfs_close_bus(bus); + return NULL; + } + link_bus_devices_to_drivers(bus); + + return bus; +} diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c new file mode 100644 index 0000000000..9d7d8b2227 --- /dev/null +++ b/libsysfs/sysfs_class.c @@ -0,0 +1,273 @@ +/* + * sysfs_class.c + * + * Generic class utility functions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_close_class_device: closes a single class device. + * @dev: class device to close. + */ +void sysfs_close_class_device(struct sysfs_class_device *dev) +{ + if (dev != NULL) { + if (dev->directory != NULL) + sysfs_close_directory(dev->directory); + if (dev->sysdevice != NULL) + sysfs_close_device(dev->sysdevice); + if (dev->driver != NULL) + sysfs_close_driver(dev->driver); + free(dev); + } +} + +/** + * sysfs_close_class: close single class + * @class: class structure + */ +void sysfs_close_class(struct sysfs_class *cls) +{ + struct sysfs_class_device *cur = NULL, *next = NULL; + + if (cls != NULL) { + if (cls->directory != NULL) + sysfs_close_directory(cls->directory); + for (cur = cls->devices; cur != NULL; cur = next) { + next = cur->next; + sysfs_close_class_device(cur); + } + free(cls); + } +} + +/** + * alloc_class_device: mallocs and initializes new class device struct. + * returns sysfs_class_device or NULL. + */ +static struct sysfs_class_device *alloc_class_device(void) +{ + return (struct sysfs_class_device *) + calloc(1, sizeof(struct sysfs_class_device)); +} + +/** + * alloc_class: mallocs new class structure + * returns sysfs_class struct or NULL + */ +static struct sysfs_class *alloc_class(void) +{ + return (struct sysfs_class *)calloc(1, sizeof(struct sysfs_class)); +} + +/** + * open_class_dir: opens up sysfs class directory + * returns sysfs_directory struct with success and NULL with error + */ +static struct sysfs_directory *open_class_dir(const char *name) +{ + struct sysfs_directory *classdir = NULL; + char classpath[SYSFS_PATH_MAX]; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + memset(classpath, 0, SYSFS_PATH_MAX); + if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { + dprintf(stderr, "Sysfs not supported on this system\n"); + return NULL; + } + + strcat(classpath, SYSFS_CLASS_DIR); + strcat(classpath, "/"); + strcat(classpath, name); + classdir = sysfs_open_directory(classpath); + if (classdir == NULL) { + errno = EINVAL; + dprintf(stderr,"Class %s not supported on this system\n", + name); + return NULL; + } + if ((sysfs_read_directory(classdir)) != 0) { + dprintf(stderr, "Error reading %s class dir %s\n", name, + classpath); + sysfs_close_directory(classdir); + return NULL; + } + + return classdir; +} + +/** + * sysfs_open_class_device: Opens and populates class device + * @path: path to class device. + * returns struct sysfs_class_device with success and NULL with error. + */ +struct sysfs_class_device *sysfs_open_class_device(const char *path) +{ + struct sysfs_class_device *cdev = NULL; + struct sysfs_directory *dir = NULL, *cur = NULL; + struct sysfs_dlink *curl = NULL; + struct sysfs_device *sdev = NULL; + struct sysfs_driver *drv = NULL; + char temp[SYSFS_NAME_LEN]; + + if (path == NULL) { + errno = EINVAL; + return NULL; + } + cdev = alloc_class_device(); + if (cdev == NULL) { + perror("malloc"); + return NULL; + } + memset(temp, 0, SYSFS_NAME_LEN); + if ((sysfs_get_name_from_path(path, temp, SYSFS_NAME_LEN)) != 0) { + errno = EINVAL; + dprintf(stderr, "Invalid class device path %s\n", path); + sysfs_close_class_device(cdev); + return NULL; + } + strcpy(cdev->name, temp); + + dir = sysfs_open_directory(path); + if (dir == NULL) { + dprintf(stderr, "Error opening class device at %s\n", path); + sysfs_close_class_device(cdev); + return NULL; + } + if ((sysfs_read_directory(dir)) != 0) { + dprintf(stderr, "Error reading class device at %s\n", path); + sysfs_close_directory(dir); + sysfs_close_class_device(cdev); + return NULL; + } + cdev->directory = dir; + + cur = cdev->directory->subdirs; + while(cur != NULL) { + sysfs_read_directory(cur); + cur = cur->next; + } + /* get driver and device, if implemented */ + curl = cdev->directory->links; + while (curl != NULL) { + if (strncmp(curl->name, SYSFS_DEVICES_NAME, 6) == 0) { + sdev = sysfs_open_device(curl->target->path); + if (sdev != NULL) { + cdev->sysdevice = sdev; + if (cdev->driver != NULL) + sdev->driver = cdev->driver; + } + } else if (strncmp(curl->name, SYSFS_DRIVERS_NAME, 6) == 0) { + drv = sysfs_open_driver(curl->target->path); + if (drv != NULL) { + cdev->driver = drv; + if (cdev->sysdevice != NULL) + drv->device = cdev->sysdevice; + } + } + curl = curl->next; + } + return cdev; +} + +/** + * add_dev_to_class: adds a class device to class list + * @class: class to add the device + * @dev: device to add + */ +static void add_dev_to_class(struct sysfs_class *cls, + struct sysfs_class_device *dev) +{ + if (cls != NULL && dev != NULL) { + dev->next = cls->devices; + cls->devices = dev; + } +} + +/** + * get_all_class_devices: gets all devices for class + * @class: class to get devices for + * returns 0 with success and -1 with failure + */ +static int get_all_class_devices(struct sysfs_class *cls) +{ + struct sysfs_class_device *dev = NULL; + struct sysfs_directory *cur = NULL, *next = NULL; + + if (cls == NULL || cls->directory == NULL) { + errno = EINVAL; + return -1; + } + for (cur = cls->directory->subdirs; cur != NULL; cur = next) { + next = cur->next; + dev = sysfs_open_class_device(cur->path); + if (dev == NULL) { + dprintf(stderr, "Error opening device at %s\n", + cur->path); + continue; + } + add_dev_to_class(cls, dev); + } + + return 0; +} + +/** + * sysfs_open_class: opens specific class and all its devices on system + * returns sysfs_class structure with success or NULL with error. + */ +struct sysfs_class *sysfs_open_class(const char *name) +{ + struct sysfs_class *cls = NULL; + struct sysfs_directory *classdir = NULL; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + cls = alloc_class(); + if (cls == NULL) { + perror("malloc"); + return NULL; + } + strcpy(cls->name, name); + classdir = open_class_dir(name); + if (classdir == NULL) { + dprintf(stderr, + "Invalid class, %s not supported on this system\n", + name); + sysfs_close_class(cls); + return NULL; + } + cls->directory = classdir; + if ((get_all_class_devices(cls)) != 0) { + dprintf(stderr, "Error reading %s class devices\n", name); + sysfs_close_class(cls); + return NULL; + } + + return cls; +} diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c new file mode 100644 index 0000000000..185b5cf378 --- /dev/null +++ b/libsysfs/sysfs_device.c @@ -0,0 +1,199 @@ +/* + * sysfs_device.c + * + * Generic device utility functions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_close_device: closes and cleans up a device + * @dev = device to clean up + */ +void sysfs_close_device(struct sysfs_device *dev) +{ + if (dev != NULL) { + dev->next = NULL; + dev->driver = NULL; + if (dev->directory != NULL) + sysfs_close_directory(dev->directory); + dev->children = NULL; + free(dev); + } +} + +/** + * alloc_device: allocates and initializes device structure + * returns struct sysfs_device + */ +static struct sysfs_device *alloc_device(void) +{ + return (struct sysfs_device *)calloc(1, sizeof(struct sysfs_device)); +} + +/** + * sysfs_get_device_attr: searches dev's attributes by name + * @dev: device to look through + * @name: attribute name to get + * returns sysfs_attribute reference with success or NULL with error. + */ +struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, + const char *name) +{ + struct sysfs_attribute *cur = NULL; + char attrname[SYSFS_NAME_LEN]; + + if (dev == NULL || dev->directory == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + for (cur = dev->directory->attributes; cur != NULL; cur = cur->next) { + if ((sysfs_get_name_from_path(cur->path, attrname, + SYSFS_NAME_LEN)) != 0) + continue; + if (strcmp(name, attrname) != 0) + continue; + + return cur; + } + + return NULL; +} + +/** + * sysfs_open_device: opens and populates device structure + * @path: path to device, this is the /sys/devices/ path + * returns sysfs_device structure with success or NULL with error + */ +struct sysfs_device *sysfs_open_device(const char *path) +{ + struct sysfs_device *dev = NULL; + struct sysfs_directory *sdir = NULL; + char *p = NULL; + + if (path == NULL) { + errno = EINVAL; + return NULL; + } + dev = alloc_device(); + if (dev == NULL) { + dprintf(stderr, "Error allocating device at %s\n", path); + return NULL; + } + sdir = sysfs_open_directory(path); + if (sdir == NULL) { + dprintf(stderr, "Invalid device at %s\n", path); + errno = EINVAL; + sysfs_close_device(dev); + return NULL; + } + if ((sysfs_read_directory(sdir)) != 0) { + dprintf(stderr, "Error reading device directory at %s\n", path); + sysfs_close_directory(sdir); + sysfs_close_device(dev); + return NULL; + } + dev->directory = sdir; + sysfs_get_name_from_path(sdir->path, dev->bus_id, SYSFS_NAME_LEN); + /* get device name */ + p = sysfs_get_value_from_attributes(sdir->attributes, + SYSFS_NAME_ATTRIBUTE); + if (p != NULL) { + strncpy(dev->name, p, SYSFS_NAME_LEN); + p = dev->name + strlen(dev->name) - 1; + if ((strlen(dev->name) > 0) && *p == '\n') + *p = '\0'; + } + + return dev; +} + +/** + * sysfs_close_device_tree: closes every device in the supplied tree, + * closing children only. + * @devroot: device root of tree. + */ +void sysfs_close_device_tree(struct sysfs_device *devroot) +{ + if (devroot != NULL) { + if (devroot->children != NULL) { + struct sysfs_device *child = NULL, *next = NULL; + + for (child = devroot->children; child != NULL; + child = next) { + next = child->next; + sysfs_close_device_tree(child); + } + } + sysfs_close_device(devroot); + } +} + +/** + * add_device_child_to_parent: adds child device to parent + * @parent: parent device. + * @child: child device to add. + */ +static void add_device_child_to_parent(struct sysfs_device *parent, + struct sysfs_device *child) +{ + if (parent != NULL && child != NULL) { + child->next = parent->children; + parent->children = child; + child->parent = parent; + } +} + +/** + * sysfs_open_device_tree: opens root device and all of its children, + * creating a tree of devices. Only opens children. + * @path: sysfs path to devices + * returns struct sysfs_device and its children with success or NULL with + * error. + */ +struct sysfs_device *sysfs_open_device_tree(const char *path) +{ + struct sysfs_device *rootdev = NULL, *new = NULL; + struct sysfs_directory *cur = NULL; + + if (path == NULL) { + errno = EINVAL; + return NULL; + } + rootdev = sysfs_open_device(path); + if (rootdev == NULL) { + dprintf(stderr, "Error opening root device at %s\n", path); + return NULL; + } + cur = rootdev->directory->subdirs; + while (cur != NULL) { + new = sysfs_open_device_tree(cur->path); + if (new == NULL) { + dprintf(stderr, "Error opening device tree at %s\n", + cur->path); + sysfs_close_device_tree(rootdev); + return NULL; + } + add_device_child_to_parent(rootdev, new); + cur = cur->next; + } + + return rootdev; +} diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c new file mode 100644 index 0000000000..a83c81f493 --- /dev/null +++ b/libsysfs/sysfs_dir.c @@ -0,0 +1,496 @@ +/* + * syfs_dir.c + * + * Directory utility functions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_close_attribute: closes and cleans up attribute + * @sysattr: attribute to close. + */ +void sysfs_close_attribute(struct sysfs_attribute *sysattr) +{ + if (sysattr != NULL) { + if (sysattr->value != NULL) + free(sysattr->value); + free(sysattr); + } +} + +/** + * alloc_attribute: allocates and initializes attribute structure + * returns struct sysfs_attribute with success and NULL with error. + */ +static struct sysfs_attribute *alloc_attribute(void) +{ + return (struct sysfs_attribute *) + calloc(1, sizeof(struct sysfs_attribute)); +} + +/** + * sysfs_open_attribute: creates sysfs_attribute structure + * @path: path to attribute. + * returns sysfs_attribute struct with success and NULL with error. + */ +struct sysfs_attribute *sysfs_open_attribute(const char *path) +{ + struct sysfs_attribute *sysattr = NULL; + struct stat fileinfo; + + if (path == NULL) { + errno = EINVAL; + return NULL; + } + sysattr = alloc_attribute(); + if (sysattr == NULL) { + dprintf(stderr, "Error allocating attribute at %s\n", path); + return NULL; + } + strncpy(sysattr->path, path, sizeof(sysattr->path)); + if ((stat(sysattr->path, &fileinfo)) != 0) { + perror("stat"); + sysattr->method = 0; + } else { + if (fileinfo.st_mode & S_IRUSR) + sysattr->method |= SYSFS_METHOD_SHOW; + if (fileinfo.st_mode & S_IWUSR) + sysattr->method |= SYSFS_METHOD_STORE; + } + + return sysattr; +} + +/** + * sysfs_read_attribute: reads value from attribute + * @sysattr: attribute to read + * returns 0 with success and -1 with error. + */ +int sysfs_read_attribute(struct sysfs_attribute *sysattr) +{ + char *fbuf = NULL; + char *vbuf = NULL; + size_t length = 0; + int pgsize = 0; + int fd; + + if (sysattr == NULL) { + errno = EINVAL; + return -1; + } + if (!(sysattr->method & SYSFS_METHOD_SHOW)) { + dprintf (stderr, "Show method not supported for attribute %s\n", + sysattr->path); + return -1; + } + pgsize = getpagesize(); + fbuf = (char *)calloc(1, pgsize+1); + if (fbuf == NULL) { + perror("calloc"); + return -1; + } + if ((fd = open(sysattr->path, O_RDONLY)) < 0) { + dprintf (stderr, "Error reading attribute %s\n", sysattr->path); + free(fbuf); + return -1; + } + length = read(fd, fbuf, pgsize); + if (length < 0) { + dprintf (stderr, "Error reading from attribute %s\n", + sysattr->path); + close(fd); + free(fbuf); + return -1; + } + sysattr->len = length; + close(fd); + vbuf = (char *)realloc(fbuf, length+1); + if (vbuf == NULL) { + perror("realloc"); + free(fbuf); + return -1; + } + sysattr->value = vbuf; + + return 0; +} + +/** + * sysfs_read_attribute_value: given path to attribute, return its value. + * values can be up to a pagesize, if buffer is smaller the value will + * be truncated. + * @attrpath: sysfs path to attribute + * @value: buffer to put value + * @vsize: size of value buffer + * returns 0 with success and -1 with error. + */ +int sysfs_read_attribute_value(const char *attrpath, char *value, size_t vsize) +{ + struct sysfs_attribute *attr = NULL; + size_t length = 0; + + if (attrpath == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + attr = sysfs_open_attribute(attrpath); + if (attr == NULL) { + dprintf(stderr, "Invalid attribute path %s\n", attrpath); + errno = EINVAL; + return -1; + } + if((sysfs_read_attribute(attr)) != 0 || attr->value == NULL) { + dprintf(stderr, "Error reading from attribute %s\n", attrpath); + sysfs_close_attribute(attr); + return -1; + } + length = strlen(attr->value); + if (length > vsize) + dprintf(stderr, + "Value length %d is larger than supplied buffer %d\n", + length, vsize); + strncpy(value, attr->value, vsize); + sysfs_close_attribute(attr); + + return 0; +} + +/** + * sysfs_get_value_from_attrbutes: given a linked list of attributes and an + * attribute name, return its value + * @attr: attribute to search + * @name: name to look for + * returns char * value - could be NULL + */ +char *sysfs_get_value_from_attributes(struct sysfs_attribute *attr, + const char *name) +{ + struct sysfs_attribute *cur = NULL; + char tmpname[SYSFS_NAME_LEN]; + + if (attr == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + cur = attr; + while (cur != NULL) { + memset(tmpname, 0, SYSFS_NAME_LEN); + if ((sysfs_get_name_from_path(cur->path, tmpname, + SYSFS_NAME_LEN)) != 0) { + cur = cur->next; + continue; + } + if (strcmp(tmpname, name) == 0) + return cur->value; + cur = cur->next; + } + return NULL; +} + +/** + * add_subdir_to_dir: adds subdirectory to directory's subdirs + * @sysdir: directory to add subdir to + * @subdir: subdirectory to add. + */ +static void add_subdir_to_dir(struct sysfs_directory *sysdir, + struct sysfs_directory *subdir) +{ + if (sysdir != NULL && subdir != NULL) { + subdir->next = sysdir->subdirs; + sysdir->subdirs = subdir; + } +} + +/** + * add_attr_to_dir: adds attribute to directory's attributes + * @sysdir: directory to add attribute to + * @sysattr: attribute to add. + */ +static void add_attr_to_dir(struct sysfs_directory *sysdir, + struct sysfs_attribute *sysattr) +{ + if (sysdir != NULL && sysattr != NULL) { + sysattr->next = sysdir->attributes; + sysdir->attributes = sysattr; + } +} + +/** + * sysfs_close_dlink: closes and cleans up directory link. + * @dlink: directory link to close. + */ +void sysfs_close_dlink(struct sysfs_dlink *dlink) +{ + if (dlink != NULL) { + dlink->next = NULL; + if (dlink->target != NULL) + sysfs_close_directory(dlink->target); + free(dlink); + } +} + +/** + * add_dlink_to_dir: adds directory link to directory's links list. + * @sysdir: directory to add it to. + * @dlink: link to add. + */ +static void add_dlink_to_dir(struct sysfs_directory *sysdir, + struct sysfs_dlink *dlink) +{ + if (sysdir != NULL && dlink != NULL) { + dlink->next = sysdir->links; + sysdir->links = dlink; + } +} + +/** + * sysfs_close_directory: closes directory, cleans up attributes and links + * @sysdir: sysfs_directory to close + */ +void sysfs_close_directory(struct sysfs_directory *sysdir) +{ + struct sysfs_directory *sdir = NULL, *dnext = NULL; + struct sysfs_dlink *dlink = NULL, *nextl = NULL; + struct sysfs_attribute *attr = NULL, *anext = NULL; + + if (sysdir != NULL) { + if (sysdir->subdirs != NULL) { + for (sdir = sysdir->subdirs; sdir != NULL; + sdir = dnext) { + dnext = sdir->next; + sysfs_close_directory(sdir); + } + } + if (sysdir->links != NULL) { + for (dlink = sysdir->links; dlink != NULL; + dlink = nextl) { + nextl = dlink->next; + sysfs_close_dlink(dlink); + } + } + if (sysdir->attributes != NULL) { + for (attr = sysdir->attributes; attr != NULL; + attr = anext) { + anext = attr->next; + /* sysfs_close_attribute(attr); */ + if (attr->value != NULL) + free(attr->value); + free(attr); + } + } + free(sysdir); + } +} + +/** + * alloc_directory: allocates and initializes directory structure + * returns struct sysfs_directory with success or NULL with error. + */ +static struct sysfs_directory *alloc_directory(void) +{ + return (struct sysfs_directory *) + calloc(1, sizeof(struct sysfs_directory)); +} + +/** + * alloc_dlink: allocates and initializes directory link structure + * returns struct sysfs_dlink with success or NULL with error. + */ +static struct sysfs_dlink *alloc_dlink(void) +{ + return (struct sysfs_dlink *)calloc(1, sizeof(struct sysfs_dlink)); +} + +/** + * sysfs_open_directory: opens a sysfs directory, creates dir struct, and + * returns. + * @path: path of directory to open. + * returns: struct sysfs_directory * with success and NULL on error. + */ +struct sysfs_directory *sysfs_open_directory(const char *path) +{ + struct sysfs_directory *sdir = NULL; + + if (path == NULL) { + errno = EINVAL; + return NULL; + } + sdir = alloc_directory(); + if (sdir == NULL) { + dprintf(stderr, "Error allocating directory %s\n", path); + return NULL; + } + strncpy(sdir->path, path, sizeof(sdir->path)); + + return sdir; +} + +/** + * sysfs_open_dlink: opens a sysfs directory link, creates struct, and returns + * @path: path of link to open. + * returns: struct sysfs_dlink * with success and NULL on error. + */ +struct sysfs_dlink *sysfs_open_dlink(const char *linkpath) +{ + struct sysfs_dlink *dlink = NULL; + struct sysfs_directory *tdir = NULL; + char name[SYSFS_NAME_LEN]; + char target[SYSFS_PATH_MAX]; + + if (linkpath == NULL) { + errno = EINVAL; + return NULL; + } + + memset(name, 0, SYSFS_NAME_LEN); + memset(target, 0, SYSFS_PATH_MAX); + if ((sysfs_get_name_from_path(linkpath, name, SYSFS_NAME_LEN)) != 0 + || (sysfs_get_link(linkpath, target, SYSFS_PATH_MAX)) != 0) { + errno = EINVAL; + dprintf(stderr, "Invalid link path %s\n", linkpath); + return NULL; + } + dlink = alloc_dlink(); + if (dlink == NULL) { + dprintf(stderr, + "Error allocating directory link %s\n", linkpath); + return NULL; + } + strcpy(dlink->name, name); + tdir = sysfs_open_directory(target); + if (tdir == NULL) { + dprintf(stderr, "Invalid directory link target %s\n", target); + sysfs_close_dlink(dlink); + return NULL; + } + dlink->target = tdir; + + return dlink; +} + +/** + * sysfs_read_directory: grabs attributes, links, and subdirectories + * @sysdir: sysfs directory to open + * returns 0 with success and -1 with error. + */ +int sysfs_read_directory(struct sysfs_directory *sysdir) +{ + DIR *dir = NULL; + struct dirent *dirent = NULL; + struct stat astats; + struct sysfs_attribute *attr = NULL; + struct sysfs_directory *subdir = NULL; + struct sysfs_dlink *dlink = NULL; + char file_path[SYSFS_PATH_MAX]; + int retval = 0; + + if (sysdir == NULL) { + errno = EINVAL; + return -1; + } + dir = opendir(sysdir->path); + if (dir == NULL) { + perror("opendir"); + return -1; + } + while(((dirent = readdir(dir)) != NULL) && retval == 0) { + if (0 == strcmp(dirent->d_name, ".")) + continue; + if (0 == strcmp(dirent->d_name, "..")) + continue; + memset(file_path, 0, SYSFS_PATH_MAX); + strncpy(file_path, sysdir->path, sizeof(file_path)); + strncat(file_path, "/", sizeof(file_path)); + strncat(file_path, dirent->d_name, sizeof(file_path)); + if ((lstat(file_path, &astats)) != 0) { + perror("stat"); + continue; + } + if (S_ISREG(astats.st_mode)) { + attr = sysfs_open_attribute(file_path); + if (attr == NULL) { + dprintf (stderr, "Error opening attribute %s\n", + file_path); + retval = -1; + break; + } + if (attr->method & SYSFS_METHOD_SHOW) { + if ((sysfs_read_attribute(attr)) != 0) { + dprintf (stderr, + "Error reading attribute %s\n", + file_path); + sysfs_close_attribute(attr); + continue; + } + } + add_attr_to_dir(sysdir, attr); + } else if (S_ISDIR(astats.st_mode)) { + subdir = sysfs_open_directory(file_path); + if (subdir == NULL) { + dprintf (stderr, "Error opening directory %s\n", + file_path); + retval = -1; + break; + } + add_subdir_to_dir(sysdir, subdir); + } else if (S_ISLNK(astats.st_mode)) { + dlink = sysfs_open_dlink(file_path); + if (dlink == NULL) { + dprintf(stderr, "Error opening link %s\n", + file_path); + retval = -1; + break; + } + add_dlink_to_dir(sysdir, dlink); + } + } + closedir(dir); + return(retval); +} + +/** + * sysfs_read_dlinks: reads a directory link's target directory. Can + * supply a linked list of links. + * @dlink: directory link to read. + * returns 0 with success or -1 with error. + */ +int sysfs_read_dlinks(struct sysfs_dlink *dlink) +{ + struct sysfs_dlink *cur = NULL; + + if (dlink == NULL || dlink->target == NULL) { + errno = EINVAL; + return -1; + } + cur = dlink; + while (cur != NULL) { + if ((sysfs_read_directory(cur->target)) != 0) { + dprintf(stderr, + "Error reading directory link target %s\n", + dlink->name); + return -1; + } + cur = cur->next; + } + + return 0; +} diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c new file mode 100644 index 0000000000..6813c85f14 --- /dev/null +++ b/libsysfs/sysfs_driver.c @@ -0,0 +1,89 @@ +/* + * sysfs_driver.c + * + * Driver utility functions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_close_driver: closes and cleans up driver structure + * @driver: driver to close + */ +void sysfs_close_driver(struct sysfs_driver *driver) +{ + if (driver != NULL) { + if (driver->directory != NULL) + sysfs_close_directory(driver->directory); + free(driver); + } +} + +/** + * alloc_driver: allocates and initializes driver + * returns struct sysfs_driver with success and NULL with error. + */ +static struct sysfs_driver *alloc_driver(void) +{ + return (struct sysfs_driver *)calloc(1, sizeof(struct sysfs_driver)); +} + +/** + * sysfs_open_driver: opens and initializes driver structure + * @path: path to driver directory + * returns struct sysfs_driver with success and NULL with error + */ +struct sysfs_driver *sysfs_open_driver(const char *path) +{ + struct sysfs_driver *driver = NULL; + struct sysfs_directory *sdir = NULL; + char devname[SYSFS_NAME_LEN]; + + if (path == NULL) { + errno = EINVAL; + return NULL; + } + sdir = sysfs_open_directory(path); + if (sdir == NULL) { + dprintf (stderr, "Error opening directory %s\n", path); + return NULL; + } + if ((sysfs_read_directory(sdir)) != 0) { + dprintf (stderr, "Error reading directory %s\n", path); + sysfs_close_directory(sdir); + return NULL; + } + driver = alloc_driver(); + if (driver == NULL) { + dprintf(stderr, "Error allocating driver at %s\n", path); + sysfs_close_directory(sdir); + return NULL; + } + if ((sysfs_get_name_from_path(path, devname, SYSFS_NAME_LEN)) != 0) { + dprintf (stderr, "Error reading directory %s\n", path); + sysfs_close_directory(sdir); + free(driver); + return NULL; + } + strncpy(driver->name, devname, sizeof(driver->name)); + driver->directory = sdir; + + return driver; +} diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c new file mode 100644 index 0000000000..a2410abe69 --- /dev/null +++ b/libsysfs/sysfs_utils.c @@ -0,0 +1,156 @@ +/* + * syfs_utils.c + * + * System utility functions for libsysfs + * + * Copyright (C) 2003 International Business Machines, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +/** + * sysfs_get_mnt_path: Gets the mount point for specified filesystem. + * @fs_type: filesystem type to retrieve mount point + * @mnt_path: place to put the retrieved mount path + * @len: size of mnt_path + * returns 0 with success and -1 with error. + */ +static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, + size_t len) +{ + FILE *mnt; + struct mntent *mntent; + int ret = 0; + size_t dirlen = 0; + + /* check arg */ + if (fs_type == NULL || mnt_path == NULL) { + errno = EINVAL; + return -1; + } + + if ((mnt = setmntent(SYSFS_PROC_MNTS, "r")) == NULL) { + dprintf(stderr, "Error getting mount information\n"); + return -1; + } + while (ret == 0 && dirlen == 0 && (mntent = getmntent(mnt)) != NULL) { + if (strcmp(mntent->mnt_type, fs_type) == 0) { + dirlen = strlen(mntent->mnt_dir); + if (dirlen <= (len - 1)) { + strcpy(mnt_path, mntent->mnt_dir); + } else { + dprintf(stderr, + "Error - mount path too long\n"); + ret = -1; + } + } + } + endmntent(mnt); + if (dirlen == 0 && ret == 0) { + dprintf(stderr, "Filesystem %s not found!\n", fs_type); + errno = EINVAL; + ret = -1; + } + return ret; +} + +/* + * sysfs_get_mnt_path: Gets the sysfs mount point. + * @mnt_path: place to put "sysfs" mount point + * @len: size of mnt_path + * returns 0 with success and -1 with error. + */ +int sysfs_get_mnt_path(char *mnt_path, size_t len) +{ + int ret = -1; + + if (mnt_path != NULL) + ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, mnt_path, len); + else + errno = EINVAL; + + return ret; +} + +/** + * sysfs_get_name_from_path: returns last name from a "/" delimited path + * @path: path to get name from + * @name: where to put name + * @len: size of name + */ +int sysfs_get_name_from_path(const char *path, char *name, size_t len) +{ + char *n = NULL; + + if (path == NULL || name == NULL) { + errno = EINVAL; + return -1; + } + n = strrchr(path, '/'); + if (n == NULL) { + errno = EINVAL; + return -1; + } + n++; + strncpy(name, n, len); + + return 0; +} + +/** + * sysfs_get_link: returns link source + * @path: symbolic link's path + * @target: where to put name + * @len: size of name + */ +int sysfs_get_link(const char *path, char *target, size_t len) +{ + char devdir[SYSFS_PATH_MAX]; + char linkpath[SYSFS_PATH_MAX]; + char *d = NULL; + + if (path == NULL || target == NULL) { + errno = EINVAL; + return -1; + } + + memset(devdir, 0, SYSFS_PATH_MAX); + memset(linkpath, 0, SYSFS_PATH_MAX); + + if ((sysfs_get_mnt_path(devdir, SYSFS_PATH_MAX)) != 0) { + dprintf(stderr, "Sysfs not supported on this system\n"); + return -1; + } + + if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) { + return -1; + } + + d = linkpath; + + /* getting rid of leading "../.." */ + while (*d == '/' || *d == '.') + d++; + + d--; + + strcat(devdir, d); + strncpy(target, devdir, len); + + return 0; +} From 28972fe8a9a314761aacd16bf19f89dbaf5a9282 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 18 Jul 2003 22:43:45 -0700 Subject: [PATCH 0020/4284] [PATCH] added libsysfs to the build. --- Makefile | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0013d06793..7cca002c99 100644 --- a/Makefile +++ b/Makefile @@ -104,6 +104,8 @@ else LDFLAGS = --static endif +LIB=libsysfs + all: $(LIBC) $(ROOT) $(ARCH_LIB_OBJS) : @@ -113,6 +115,10 @@ OBJS = udev.o \ logging.o \ namedev.o +LIBSYSFS = libsysfs/libsysfs.a + +libsysfs/libsysfs.a: + $(MAKE) -C libsysfs # header files automatically generated GEN_HEADERS = udev_version.h @@ -122,8 +128,9 @@ udev_version.h: @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ -$(ROOT): $(GEN_HEADERS) $(OBJS) - $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(ROOT): $(GEN_HEADERS) $(OBJS) $(LIBSYSFS) + $(MAKE) -C libsysfs + $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) -lsysfs $(LIB_OBJS) -L$(LIB) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) clean: @@ -131,6 +138,7 @@ clean: | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(MAKE) -C klibc clean + $(MAKE) -C libsysfs clean DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS ) DISTDIR := $(RELEASE_NAME) From 185a35a403cc37b3943bc68aa61745ff2b6ed17b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 18 Jul 2003 22:48:28 -0700 Subject: [PATCH 0021/4284] [PATCH] add initial libsysfs support... needs lots more cleanup, but is much nicer than doing this by hand... --- namedev.c | 112 +++++++++++++++++++++++++++++++++++++++++++++++++----- namedev.h | 1 + udev.c | 18 ++++++--- udev.h | 13 +++++++ 4 files changed, 129 insertions(+), 15 deletions(-) diff --git a/namedev.c b/namedev.c index 0271ba55a2..b8a21a25ae 100644 --- a/namedev.c +++ b/namedev.c @@ -34,6 +34,7 @@ #include "udev.h" #include "udev_version.h" #include "namedev.h" +#include "libsysfs/libsysfs.h" #define TYPE_LABEL "LABEL" #define TYPE_NUMBER "NUMBER" @@ -53,9 +54,6 @@ enum config_type { #define VALUE_SIZE 100 #define ID_SIZE 50 #define PLACE_SIZE 50 -#define NAME_SIZE 100 -#define OWNER_SIZE 30 -#define GROUP_SIZE 30 struct config_device { @@ -80,36 +78,38 @@ struct config_device { static LIST_HEAD(config_device_list); +static char sysfs_path[SYSFS_PATH_MAX]; + static void dump_dev(struct config_device *dev) { switch (dev->type) { case KERNEL_NAME: dbg("KERNEL name ='%s'" - " owner = '%s', group = '%s', mode = '%d'", + " owner = '%s', group = '%s', mode = '%#o'", dev->name, dev->owner, dev->group, dev->mode); break; case LABEL: dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" - " owner = '%s', group = '%s', mode = '%d'", + " owner = '%s', group = '%s', mode = '%#o'", dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, dev->owner, dev->group, dev->mode); break; case NUMBER: dbg("NUMBER name = '%s', bus = '%s', id = '%s'" - " owner = '%s', group = '%s', mode = '%d'", + " owner = '%s', group = '%s', mode = '%#o'", dev->name, dev->bus, dev->id, dev->owner, dev->group, dev->mode); break; case TOPOLOGY: dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'" - " owner = '%s', group = '%s', mode = '%d'", + " owner = '%s', group = '%s', mode = '%#o'", dev->name, dev->bus, dev->place, dev->owner, dev->group, dev->mode); break; case REPLACE: dbg("REPLACE name = %s, kernel_name = %s" - " owner = '%s', group = '%s', mode = '%d'", + " owner = '%s', group = '%s', mode = '%#o'", dev->name, dev->kernel_name, dev->owner, dev->group, dev->mode); break; @@ -432,7 +432,7 @@ static int namedev_init_permissions(void) dev.mode = strtol(temp, NULL, 8); - dbg("name = %s, owner = %s, group = %s, mode = %x", dev.name, dev.owner, dev.group, dev.mode); + dbg("name = %s, owner = %s, group = %s, mode = %#o", dev.name, dev.owner, dev.group, dev.mode); retval = add_dev(&dev); if (retval) { dbg("add_dev returned with error %d", retval); @@ -446,10 +446,103 @@ exit: } +static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) +{ + char temp[3]; + int retval = 0; + + char *dev; + + dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); + if (dev == NULL) + return -ENODEV; + + dbg("dev = %s", dev); + + temp[0] = dev[0]; + temp[1] = dev[1]; + temp[2] = 0x00; + *major = (int)strtol(&temp[0], NULL, 16); + + temp[0] = dev[2]; + temp[1] = dev[3]; + temp[2] = 0x00; + *minor = (int)strtol(&temp[0], NULL, 16); + + dbg("found major = %d, minor = %d", *major, *minor); + + retval = 0; + return retval; +} + +static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *attr) +{ + struct list_head *tmp; + int retval = 0; + + retval = get_major_minor(class_dev, &attr->major, &attr->minor); + if (retval) { + dbg ("get_major_minor failed"); + goto exit; + } + + list_for_each(tmp, &config_device_list) { + struct config_device *dev = list_entry(tmp, struct config_device, node); + if (strcmp(dev->name, class_dev->name) == 0) { + attr->mode = dev->mode; + strcpy(attr->owner, dev->owner); + strcpy(attr->group, dev->group); + /* FIXME put the proper name here!!! */ + strcpy(attr->name, dev->name); + dbg("%s - owner = %s, group = %s, mode = %#o", dev->name, dev->owner, dev->group, dev->mode); + goto exit; + } + } + attr->mode = 0666; + attr->owner[0] = 0x00; + attr->group[0] = 0x00; + strcpy(attr->name, class_dev->name); +exit: + return retval; +} + +int namedev_name_device(char *device_name, struct device_attr *attr) +{ + char dev_path[SYSFS_PATH_MAX]; + struct sysfs_class_device *class_dev; + int retval; + + strcpy(dev_path, sysfs_path); + strcat(dev_path, device_name); + + dbg("looking at %s", dev_path); + + /* open up the sysfs class device for this thing... */ + class_dev = sysfs_open_class_device(dev_path); + if (class_dev == NULL) { + dbg ("sysfs_open_class_device failed"); + return -ENODEV; + } + dbg("class_dev->name = %s", class_dev->name); + + retval = get_attr(class_dev, attr); + if (retval) { + dbg ("get_attr failed"); + goto exit; + } +exit: + sysfs_close_class_device(class_dev); + return retval; +} int namedev_init(void) { int retval; + + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + if (retval) + return retval; + dbg("sysfs_path = %s", sysfs_path); retval = namedev_init_config(); if (retval) @@ -463,3 +556,4 @@ int namedev_init(void) return retval; } + diff --git a/namedev.h b/namedev.h index 0089b4d240..1fe5860015 100644 --- a/namedev.h +++ b/namedev.h @@ -30,5 +30,6 @@ #define NAMEDEV_CONFIG_FILE "namedev.config" extern int namedev_init(void); +extern int namedev_name_device(char *device_name, struct device_attr *attr); #endif diff --git a/udev.c b/udev.c index bf170d1651..dc5f5b8d89 100644 --- a/udev.c +++ b/udev.c @@ -50,7 +50,8 @@ static char *get_device(void) temp = getenv("DEVPATH"); if (temp == NULL) return NULL; - strcpy(device, SYSFS_ROOT); + strcpy(device, ""); +// strcpy(device, SYSFS_ROOT); strcat(device, temp); return device; @@ -198,14 +199,14 @@ static int delete_node(char *name) return unlink(filename); } -static int add_device(char *device, char type) +static int add_device(char *device, char type, struct device_attr *attr) { char *name; int major; int minor; int mode; int retval = -EINVAL; - +#if 0 retval = get_major_minor(device, &major, &minor); if (retval) { dbg ("get_major_minor failed"); @@ -225,8 +226,8 @@ static int add_device(char *device, char type) retval = -EINVAL; goto exit; } - - return create_node(name, type, major, minor, mode); +#endif + return create_node(attr->name, type, attr->major, attr->minor, attr->mode); exit: return retval; @@ -252,6 +253,7 @@ exit: int main(int argc, char *argv[]) { + struct device_attr attr; char *subsystem; char *action; char *device; @@ -290,8 +292,12 @@ int main(int argc, char *argv[]) } dbg("looking at %s", device); + retval = namedev_name_device(device, &attr); + if (retval) + return retval; + if (strcmp(action, "add") == 0) - return add_device(device, type); + return add_device(device, type, &attr); if (strcmp(action, "remove") == 0) return remove_device(device); diff --git a/udev.h b/udev.h index af1b6bbb8d..c82dbebded 100644 --- a/udev.h +++ b/udev.h @@ -52,6 +52,19 @@ extern int log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +#define NAME_SIZE 100 +#define OWNER_SIZE 30 +#define GROUP_SIZE 30 + +struct device_attr { + int major; + int minor; + int mode; + char name[NAME_SIZE]; + char owner[OWNER_SIZE]; + char group[GROUP_SIZE]; +}; + #endif From fa41b24051d9ac53cba45c0bb78623d4c0a5e5d6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 18 Jul 2003 22:48:49 -0700 Subject: [PATCH 0022/4284] [PATCH] update the tests to handle block devices too. --- namedev.permissions | 2 +- test | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/namedev.permissions b/namedev.permissions index 7f87fc9b0e..66d8af1f7a 100644 --- a/namedev.permissions +++ b/namedev.permissions @@ -1,5 +1,5 @@ #name:user:group:mode -ttyUSB0:root:uucp:0666 +ttyUSB0:root:uucp:0660 ttyUSB1:root:uucp:0666 visor:root:uucp:0666 dsp1:::0666 diff --git a/test b/test index 40613d48af..f5e808b557 100644 --- a/test +++ b/test @@ -3,6 +3,8 @@ export ACTION=add #export ACTION=remove export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.1/ttyUSB7 export DEVPATH=/class/tty/ttyUSB0 +export DEVPATH=/block/hda -./udev tty +./udev block +#./udev tty From 19dc5d4ce15ad387031ec4e78dc615a9eb07dc08 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 19 Jul 2003 05:06:55 -0700 Subject: [PATCH 0023/4284] [PATCH] Clean up the namedev interface a bit, making the code smaller... --- namedev.c | 72 +++------------------- namedev.h | 4 +- udev.c | 177 +++++++++++++++++++++++++++--------------------------- udev.h | 4 +- 4 files changed, 103 insertions(+), 154 deletions(-) diff --git a/namedev.c b/namedev.c index b8a21a25ae..b6d9a7f8e2 100644 --- a/namedev.c +++ b/namedev.c @@ -78,8 +78,6 @@ struct config_device { static LIST_HEAD(config_device_list); -static char sysfs_path[SYSFS_PATH_MAX]; - static void dump_dev(struct config_device *dev) { switch (dev->type) { @@ -445,47 +443,18 @@ exit: return retval; } - -static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) +static int get_default_mode(struct sysfs_class_device *class_dev) { - char temp[3]; - int retval = 0; - - char *dev; - - dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); - if (dev == NULL) - return -ENODEV; - - dbg("dev = %s", dev); - - temp[0] = dev[0]; - temp[1] = dev[1]; - temp[2] = 0x00; - *major = (int)strtol(&temp[0], NULL, 16); - - temp[0] = dev[2]; - temp[1] = dev[3]; - temp[2] = 0x00; - *minor = (int)strtol(&temp[0], NULL, 16); - - dbg("found major = %d, minor = %d", *major, *minor); - - retval = 0; - return retval; + /* just default everyone to rw for the world! */ + return 0666; } + static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *attr) { struct list_head *tmp; int retval = 0; - retval = get_major_minor(class_dev, &attr->major, &attr->minor); - if (retval) { - dbg ("get_major_minor failed"); - goto exit; - } - list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); if (strcmp(dev->name, class_dev->name) == 0) { @@ -498,7 +467,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at goto exit; } } - attr->mode = 0666; + attr->mode = get_default_mode(class_dev); attr->owner[0] = 0x00; attr->group[0] = 0x00; strcpy(attr->name, class_dev->name); @@ -506,32 +475,14 @@ exit: return retval; } -int namedev_name_device(char *device_name, struct device_attr *attr) +int namedev_name_device(struct sysfs_class_device *class_dev, struct device_attr *attr) { - char dev_path[SYSFS_PATH_MAX]; - struct sysfs_class_device *class_dev; int retval; - strcpy(dev_path, sysfs_path); - strcat(dev_path, device_name); - - dbg("looking at %s", dev_path); - - /* open up the sysfs class device for this thing... */ - class_dev = sysfs_open_class_device(dev_path); - if (class_dev == NULL) { - dbg ("sysfs_open_class_device failed"); - return -ENODEV; - } - dbg("class_dev->name = %s", class_dev->name); - retval = get_attr(class_dev, attr); - if (retval) { - dbg ("get_attr failed"); - goto exit; - } -exit: - sysfs_close_class_device(class_dev); + if (retval) + dbg("get_attr failed"); + return retval; } @@ -539,11 +490,6 @@ int namedev_init(void) { int retval; - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - if (retval) - return retval; - dbg("sysfs_path = %s", sysfs_path); - retval = namedev_init_config(); if (retval) return retval; diff --git a/namedev.h b/namedev.h index 1fe5860015..0e3a819952 100644 --- a/namedev.h +++ b/namedev.h @@ -23,6 +23,8 @@ #ifndef NAMEDEV_H #define NAMEDEV_H +struct sysfs_class_device; + /* namedev config files */ #define COMMENT_CHARACTER '#' #define NAMEDEV_CONFIG_ROOT "/home/greg/src/udev/" @@ -30,6 +32,6 @@ #define NAMEDEV_CONFIG_FILE "namedev.config" extern int namedev_init(void); -extern int namedev_name_device(char *device_name, struct device_attr *attr); +extern int namedev_name_device(struct sysfs_class_device *class_dev, struct device_attr *attr); #endif diff --git a/udev.c b/udev.c index dc5f5b8d89..b3e18ff9da 100644 --- a/udev.c +++ b/udev.c @@ -31,8 +31,11 @@ #include "udev.h" #include "udev_version.h" #include "namedev.h" +#include "libsysfs/libsysfs.h" +static char sysfs_path[SYSFS_PATH_MAX]; + static char *get_action(void) { char *action; @@ -44,16 +47,9 @@ static char *get_action(void) static char *get_device(void) { - static char device[255]; - char *temp; - - temp = getenv("DEVPATH"); - if (temp == NULL) - return NULL; - strcpy(device, ""); -// strcpy(device, SYSFS_ROOT); - strcat(device, temp); + char *device; + device = getenv("DEVPATH"); return device; } @@ -68,45 +64,32 @@ static char *get_device(void) * Yes, this will probably change when we go to a bigger major/minor * range, and will have to be changed at that time. */ -static int get_major_minor (char *dev, int *major, int *minor) +static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) { - char filename[255]; - char line[20]; char temp[3]; - int fd; int retval = 0; - /* add the dev file to the directory and see if it's present */ - strncpy(filename, dev, sizeof(filename)); - strncat(filename, DEV_FILE, sizeof(filename)); - fd = open(filename, O_RDONLY); - if (fd < 0) { - dbg("Can't open %s", filename); + char *dev; + + dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); + if (dev == NULL) return -ENODEV; - } - /* get the major/minor */ - retval = read(fd, line, sizeof(line)); - if (retval < 0) { - dbg("read error on %s", dev); - goto exit; - } + dbg("dev = %s", dev); - temp[0] = line[0]; - temp[1] = line[1]; + temp[0] = dev[0]; + temp[1] = dev[1]; temp[2] = 0x00; *major = (int)strtol(&temp[0], NULL, 16); - temp[0] = line[2]; - temp[1] = line[3]; + temp[0] = dev[2]; + temp[1] = dev[3]; temp[2] = 0x00; *minor = (int)strtol(&temp[0], NULL, 16); dbg("found major = %d, minor = %d", *major, *minor); retval = 0; -exit: - close(fd); return retval; } @@ -130,15 +113,6 @@ static char *get_name(char *dev, int major, int minor) return &name[0]; } -/* - * Again, this will live in the naming deamon - */ -static int get_mode(char *name, char *dev, int major, int minor) -{ - /* just default everyone to rw for the world! */ - return 0666; -} - /* * We also want to add some permissions here, and possibly some symlinks */ @@ -199,35 +173,61 @@ static int delete_node(char *name) return unlink(filename); } -static int add_device(char *device, char type, struct device_attr *attr) +struct sysfs_class_device *get_class_dev(char *device_name) { - char *name; + char dev_path[SYSFS_PATH_MAX]; + struct sysfs_class_device *class_dev; + + strcpy(dev_path, sysfs_path); + strcat(dev_path, device_name); + + dbg("looking at %s", dev_path); + + /* open up the sysfs class device for this thing... */ + class_dev = sysfs_open_class_device(dev_path); + if (class_dev == NULL) { + dbg ("sysfs_open_class_device failed"); + return NULL; + } + dbg("class_dev->name = %s", class_dev->name); + + return class_dev; +} + +static int add_device(char *device, char *subsystem) +{ + struct sysfs_class_device *class_dev; + struct device_attr attr; + //char *name; int major; int minor; - int mode; + char type; + //int mode; int retval = -EINVAL; -#if 0 - retval = get_major_minor(device, &major, &minor); + + /* for now, the block layer is the only place where block devices are */ + if (strcmp(subsystem, "block") == 0) + type = 'b'; + else + type = 'c'; + + class_dev = get_class_dev(device); + if (class_dev == NULL) + goto exit; + + retval = namedev_name_device(class_dev, &attr); + if (retval) + return retval; + + retval = get_major_minor(class_dev, &major, &minor); if (retval) { dbg ("get_major_minor failed"); goto exit; } - name = get_name(device, major, minor); - if (name == NULL) { - dbg ("get_name failed"); - retval = -ENODEV; - goto exit; - } + sysfs_close_class_device(class_dev); - mode = get_mode(name, device, major, minor); - if (mode < 0) { - dbg ("get_mode failed"); - retval = -EINVAL; - goto exit; - } -#endif - return create_node(attr->name, type, attr->major, attr->minor, attr->mode); + return create_node(attr.name, type, major, minor, attr.mode); exit: return retval; @@ -250,14 +250,20 @@ static int remove_device(char *device) exit: return retval; } + +static int udev_init(void) +{ + int retval; + + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + dbg("sysfs_path = %s", sysfs_path); + return retval; +} int main(int argc, char *argv[]) { - struct device_attr attr; - char *subsystem; char *action; char *device; - char type; int retval = -EINVAL; if (argc != 2) { @@ -265,26 +271,6 @@ int main(int argc, char *argv[]) goto exit; } - namedev_init(); - - /* sleep for a second or two to give the kernel a chance to - * create the dev file - */ - sleep(2); - - /* for now, the block layer is the only place where block devices are */ - subsystem = argv[1]; - if (strcmp(subsystem, "block") == 0) - type = 'b'; - else - type = 'c'; - - action = get_action(); - if (!action) { - dbg ("no action?"); - goto exit; - } - device = get_device(); if (!device) { dbg ("no device?"); @@ -292,12 +278,29 @@ int main(int argc, char *argv[]) } dbg("looking at %s", device); - retval = namedev_name_device(device, &attr); - if (retval) - return retval; + /* we only care about class devices and block stuff */ + if (!strstr(device, "class") && + !strstr(device, "block")) { + dbg("not block or class"); + goto exit; + } + + /* sleep for a second or two to give the kernel a chance to + * create the dev file + */ + sleep(1); + + udev_init(); + namedev_init(); + + action = get_action(); + if (!action) { + dbg ("no action?"); + goto exit; + } if (strcmp(action, "add") == 0) - return add_device(device, type, &attr); + return add_device(device, argv[1]); if (strcmp(action, "remove") == 0) return remove_device(device); diff --git a/udev.h b/udev.h index c82dbebded..56eb0d7edb 100644 --- a/udev.h +++ b/udev.h @@ -57,12 +57,10 @@ extern int log_message (int level, const char *format, ...) #define GROUP_SIZE 30 struct device_attr { - int major; - int minor; - int mode; char name[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; + int mode; }; From ea733a2f00174c3a39c8eb783e330b6a69abd67c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 20 Jul 2003 20:48:48 -0700 Subject: [PATCH 0024/4284] [PATCH] split udev main logic into udev-add and udev-remove. --- Makefile | 2 + udev-add.c | 200 ++++++++++++++++++++++++++++++++++++++++++ udev-remove.c | 88 +++++++++++++++++++ udev.c | 234 +++----------------------------------------------- udev.h | 2 + 5 files changed, 306 insertions(+), 220 deletions(-) create mode 100644 udev-add.c create mode 100644 udev-remove.c diff --git a/Makefile b/Makefile index 7cca002c99..989eb403bf 100644 --- a/Makefile +++ b/Makefile @@ -112,6 +112,8 @@ $(ARCH_LIB_OBJS) : $(MAKE) -C klibc OBJS = udev.o \ + udev-add.o \ + udev-remove.o \ logging.o \ namedev.o diff --git a/udev-add.c b/udev-add.c new file mode 100644 index 0000000000..45ffbf81b5 --- /dev/null +++ b/udev-add.c @@ -0,0 +1,200 @@ +/* + * udev-add.c + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "namedev.h" +#include "libsysfs/libsysfs.h" + + +static char sysfs_path[SYSFS_PATH_MAX]; + +/* + * Right now the major/minor of a device is stored in a file called + * "dev" in sysfs. + * The number is stored as: + * MMmm + * MM is the major + * mm is the minor + * The value is in hex. + * Yes, this will probably change when we go to a bigger major/minor + * range, and will have to be changed at that time. + */ +static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) +{ + char temp[3]; + int retval = 0; + + char *dev; + + dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); + if (dev == NULL) + return -ENODEV; + + dbg("dev = %s", dev); + + temp[0] = dev[0]; + temp[1] = dev[1]; + temp[2] = 0x00; + *major = (int)strtol(&temp[0], NULL, 16); + + temp[0] = dev[2]; + temp[1] = dev[3]; + temp[2] = 0x00; + *minor = (int)strtol(&temp[0], NULL, 16); + + dbg("found major = %d, minor = %d", *major, *minor); + + retval = 0; + return retval; +} + +/* + * We also want to add some permissions here, and possibly some symlinks + */ +static int create_node(char *name, char type, int major, int minor, int mode) +{ + char *argv[7]; + char mode_string[100]; + char type_string[3]; + char major_string[20]; + char minor_string[20]; + char filename[255]; + int retval = 0; + + strncpy(filename, UDEV_ROOT, sizeof(filename)); + strncat(filename, name, sizeof(filename)); + + snprintf(mode_string, sizeof(mode_string), "--mode=%#o", mode); + snprintf(type_string, sizeof(type_string), "%c", type); + snprintf(major_string, sizeof(major_string), "%d", major); + snprintf(minor_string, sizeof(minor_string), "%d", minor); + + argv[0] = MKNOD; + argv[1] = mode_string; + argv[2] = filename; + argv[3] = type_string; + argv[4] = major_string; + argv[5] = minor_string; + argv[6] = NULL; + dbg ("executing %s %s %s %s %s %s", + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); + switch (fork()) { + case 0: + /* we are the child, so lets run the program */ + execv (MKNOD, argv); + exit(0); + break; + case (-1): + dbg ("fork failed."); + retval = -EFAULT; + break; + default: + break; + } + return retval; +} + +struct sysfs_class_device *get_class_dev(char *device_name) +{ + char dev_path[SYSFS_PATH_MAX]; + struct sysfs_class_device *class_dev; + + strcpy(dev_path, sysfs_path); + strcat(dev_path, device_name); + + dbg("looking at %s", dev_path); + + /* open up the sysfs class device for this thing... */ + class_dev = sysfs_open_class_device(dev_path); + if (class_dev == NULL) { + dbg ("sysfs_open_class_device failed"); + return NULL; + } + dbg("class_dev->name = %s", class_dev->name); + + return class_dev; +} + +static int udev_init(void) +{ + int retval; + + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + dbg("sysfs_path = %s", sysfs_path); + return retval; +} + +int udev_add_device(char *device, char *subsystem) +{ + struct sysfs_class_device *class_dev; + struct device_attr attr; + //char *name; + int major; + int minor; + char type; + //int mode; + int retval = -EINVAL; + + /* sleep for a second or two to give the kernel a chance to + * create the dev file + */ + sleep(1); + + udev_init(); + + /* for now, the block layer is the only place where block devices are */ + if (strcmp(subsystem, "block") == 0) + type = 'b'; + else + type = 'c'; + + class_dev = get_class_dev(device); + if (class_dev == NULL) + goto exit; + + retval = namedev_name_device(class_dev, &attr); + if (retval) + return retval; + + retval = get_major_minor(class_dev, &major, &minor); + if (retval) { + dbg ("get_major_minor failed"); + goto exit; + } + + sysfs_close_class_device(class_dev); + + return create_node(attr.name, type, major, minor, attr.mode); + +exit: + return retval; +} + diff --git a/udev-remove.c b/udev-remove.c new file mode 100644 index 0000000000..cd917af193 --- /dev/null +++ b/udev-remove.c @@ -0,0 +1,88 @@ +/* + * udev-remove.c + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "namedev.h" +#include "libsysfs/libsysfs.h" + + +/* + * Here would go a call to the naming deamon, to get the name we want to have + * for this device. But for now, let's just default to whatever the kernel is + * calling the device as that will keep the "old-style" naming policy + */ +static char *get_name(char *dev, int major, int minor) +{ + static char name[100]; + char *temp; + + temp = strrchr(dev, '/'); + if (temp == NULL) + return NULL; + strncpy(name, &temp[1], sizeof(name)); + + dbg("name is %s", name); + + return &name[0]; +} + +/* + * We also want to clean up any symlinks that were created in create_node() + */ +static int delete_node(char *name) +{ + char filename[255]; + + strncpy(filename, UDEV_ROOT, sizeof(filename)); + strncat(filename, name, sizeof(filename)); + + dbg("unlinking %s", filename); + return unlink(filename); +} + +int udev_remove_device(char *device, char *subsystem) +{ + char *name; + int retval = 0; + + name = get_name(device, 0, 0); + if (name == NULL) { + dbg ("get_name failed"); + retval = -ENODEV; + goto exit; + } + + return delete_node(name); + +exit: + return retval; +} + diff --git a/udev.c b/udev.c index b3e18ff9da..74572625af 100644 --- a/udev.c +++ b/udev.c @@ -34,8 +34,6 @@ #include "libsysfs/libsysfs.h" -static char sysfs_path[SYSFS_PATH_MAX]; - static char *get_action(void) { char *action; @@ -53,217 +51,11 @@ static char *get_device(void) return device; } -/* - * Right now the major/minor of a device is stored in a file called - * "dev" in sysfs. - * The number is stored as: - * MMmm - * MM is the major - * mm is the minor - * The value is in hex. - * Yes, this will probably change when we go to a bigger major/minor - * range, and will have to be changed at that time. - */ -static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) -{ - char temp[3]; - int retval = 0; - - char *dev; - - dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); - if (dev == NULL) - return -ENODEV; - - dbg("dev = %s", dev); - - temp[0] = dev[0]; - temp[1] = dev[1]; - temp[2] = 0x00; - *major = (int)strtol(&temp[0], NULL, 16); - - temp[0] = dev[2]; - temp[1] = dev[3]; - temp[2] = 0x00; - *minor = (int)strtol(&temp[0], NULL, 16); - - dbg("found major = %d, minor = %d", *major, *minor); - - retval = 0; - return retval; -} - -/* - * Here would go a call to the naming deamon, to get the name we want to have - * for this device. But for now, let's just default to whatever the kernel is - * calling the device as that will keep the "old-style" naming policy - */ -static char *get_name(char *dev, int major, int minor) -{ - static char name[100]; - char *temp; - - temp = strrchr(dev, '/'); - if (temp == NULL) - return NULL; - strncpy(name, &temp[1], sizeof(name)); - - dbg("name is %s", name); - - return &name[0]; -} - -/* - * We also want to add some permissions here, and possibly some symlinks - */ -static int create_node(char *name, char type, int major, int minor, int mode) -{ - char *argv[7]; - char mode_string[100]; - char type_string[3]; - char major_string[20]; - char minor_string[20]; - char filename[255]; - int retval = 0; - - strncpy(filename, UDEV_ROOT, sizeof(filename)); - strncat(filename, name, sizeof(filename)); - - snprintf(mode_string, sizeof(mode_string), "--mode=%#o", mode); - snprintf(type_string, sizeof(type_string), "%c", type); - snprintf(major_string, sizeof(major_string), "%d", major); - snprintf(minor_string, sizeof(minor_string), "%d", minor); - - argv[0] = MKNOD; - argv[1] = mode_string; - argv[2] = filename; - argv[3] = type_string; - argv[4] = major_string; - argv[5] = minor_string; - argv[6] = NULL; - dbg ("executing %s %s %s %s %s %s", - argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); - switch (fork()) { - case 0: - /* we are the child, so lets run the program */ - execv (MKNOD, argv); - exit(0); - break; - case (-1): - dbg ("fork failed."); - retval = -EFAULT; - break; - default: - break; - } - return retval; -} - -/* - * We also want to clean up any symlinks that were created in create_node() - */ -static int delete_node(char *name) -{ - char filename[255]; - - strncpy(filename, UDEV_ROOT, sizeof(filename)); - strncat(filename, name, sizeof(filename)); - - dbg("unlinking %s", filename); - return unlink(filename); -} - -struct sysfs_class_device *get_class_dev(char *device_name) -{ - char dev_path[SYSFS_PATH_MAX]; - struct sysfs_class_device *class_dev; - - strcpy(dev_path, sysfs_path); - strcat(dev_path, device_name); - - dbg("looking at %s", dev_path); - - /* open up the sysfs class device for this thing... */ - class_dev = sysfs_open_class_device(dev_path); - if (class_dev == NULL) { - dbg ("sysfs_open_class_device failed"); - return NULL; - } - dbg("class_dev->name = %s", class_dev->name); - - return class_dev; -} - -static int add_device(char *device, char *subsystem) -{ - struct sysfs_class_device *class_dev; - struct device_attr attr; - //char *name; - int major; - int minor; - char type; - //int mode; - int retval = -EINVAL; - - /* for now, the block layer is the only place where block devices are */ - if (strcmp(subsystem, "block") == 0) - type = 'b'; - else - type = 'c'; - - class_dev = get_class_dev(device); - if (class_dev == NULL) - goto exit; - - retval = namedev_name_device(class_dev, &attr); - if (retval) - return retval; - - retval = get_major_minor(class_dev, &major, &minor); - if (retval) { - dbg ("get_major_minor failed"); - goto exit; - } - - sysfs_close_class_device(class_dev); - - return create_node(attr.name, type, major, minor, attr.mode); - -exit: - return retval; -} - -static int remove_device(char *device) -{ - char *name; - int retval = 0; - - name = get_name(device, 0, 0); - if (name == NULL) { - dbg ("get_name failed"); - retval = -ENODEV; - goto exit; - } - - return delete_node(name); - -exit: - return retval; -} - -static int udev_init(void) -{ - int retval; - - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - dbg("sysfs_path = %s", sysfs_path); - return retval; -} - int main(int argc, char *argv[]) { char *action; char *device; + char *subsystem; int retval = -EINVAL; if (argc != 2) { @@ -271,6 +63,8 @@ int main(int argc, char *argv[]) goto exit; } + subsystem = argv[1]; + device = get_device(); if (!device) { dbg ("no device?"); @@ -284,14 +78,12 @@ int main(int argc, char *argv[]) dbg("not block or class"); goto exit; } - - /* sleep for a second or two to give the kernel a chance to - * create the dev file - */ - sleep(1); - udev_init(); - namedev_init(); + /* but we don't care about net class devices */ + if (strcmp(subsystem, "net") == 0) { + dbg("don't care about net devices"); + goto exit; + } action = get_action(); if (!action) { @@ -299,16 +91,18 @@ int main(int argc, char *argv[]) goto exit; } + /* initialize the naming deamon */ + namedev_init(); + if (strcmp(action, "add") == 0) - return add_device(device, argv[1]); + return udev_add_device(device, argv[1]); if (strcmp(action, "remove") == 0) - return remove_device(device); + return udev_remove_device(device, argv[1]); dbg("Unknown action: %s", action); - return -EINVAL; + retval = -EINVAL; - retval = 0; exit: return retval; } diff --git a/udev.h b/udev.h index 56eb0d7edb..59c374365e 100644 --- a/udev.h +++ b/udev.h @@ -63,6 +63,8 @@ struct device_attr { int mode; }; +extern int udev_add_device(char *device, char *subsystem); +extern int udev_remove_device(char *device, char *subsystem); #endif From 405f634279bb31c4aa3bc70a2139ff638f2659b8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 23 Jul 2003 18:55:55 -0400 Subject: [PATCH 0025/4284] [PATCH] split the tests up into different files. --- test => test.block | 0 test.tty | 10 ++++++++++ 2 files changed, 10 insertions(+) rename test => test.block (100%) create mode 100644 test.tty diff --git a/test b/test.block similarity index 100% rename from test rename to test.block diff --git a/test.tty b/test.tty new file mode 100644 index 0000000000..2d64f07d3e --- /dev/null +++ b/test.tty @@ -0,0 +1,10 @@ +#!/bin/sh +export ACTION=add +#export ACTION=remove +export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.1/ttyUSB7 +export DEVPATH=/class/tty/ttyUSB0 +#export DEVPATH=/block/hda + + +#./udev block +./udev tty From b4c1dcf91277425371f7be4b9f8d28ef5d1e8910 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 23 Jul 2003 18:56:14 -0400 Subject: [PATCH 0026/4284] [PATCH] block test --- test.block | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test.block b/test.block index f5e808b557..675fbc057a 100644 --- a/test.block +++ b/test.block @@ -1,10 +1,8 @@ #!/bin/sh export ACTION=add #export ACTION=remove -export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.1/ttyUSB7 -export DEVPATH=/class/tty/ttyUSB0 + export DEVPATH=/block/hda ./udev block -#./udev tty From cb32ac946fe3606fa5bfeb0b26589a3b0f2e0c45 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 23 Jul 2003 18:56:56 -0400 Subject: [PATCH 0027/4284] [PATCH] make struct config_device contain a struct device_attr instead of duplicating the mess. --- namedev.c | 101 ++++++++++++++++++------------------------------------ namedev.h | 34 ++++++++++++++++++ 2 files changed, 67 insertions(+), 68 deletions(-) diff --git a/namedev.c b/namedev.c index b6d9a7f8e2..8b7edb7fb1 100644 --- a/namedev.c +++ b/namedev.c @@ -41,41 +41,6 @@ #define TYPE_TOPOLOGY "TOPOLOGY" #define TYPE_REPLACE "REPLACE" -enum config_type { - KERNEL_NAME = 0, /* must be 0 to let memset() default to this value */ - LABEL = 1, - NUMBER = 2, - TOPOLOGY = 3, - REPLACE = 4, -}; - -#define BUS_SIZE 30 -#define FILE_SIZE 50 -#define VALUE_SIZE 100 -#define ID_SIZE 50 -#define PLACE_SIZE 50 - - -struct config_device { - struct list_head node; - - enum config_type type; - - char bus[BUS_SIZE]; - char sysfs_file[FILE_SIZE]; - char sysfs_value[VALUE_SIZE]; - char id[ID_SIZE]; - char place[PLACE_SIZE]; - char kernel_name[NAME_SIZE]; - - /* what to set the device to */ - int mode; - char name[NAME_SIZE]; - char owner[OWNER_SIZE]; - char group[GROUP_SIZE]; -}; - - static LIST_HEAD(config_device_list); static void dump_dev(struct config_device *dev) @@ -84,32 +49,32 @@ static void dump_dev(struct config_device *dev) case KERNEL_NAME: dbg("KERNEL name ='%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->name, - dev->owner, dev->group, dev->mode); + dev->attr.name, + dev->attr.owner, dev->attr.group, dev->attr.mode); break; case LABEL: dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, - dev->owner, dev->group, dev->mode); + dev->attr.name, dev->bus, dev->sysfs_file, dev->sysfs_value, + dev->attr.owner, dev->attr.group, dev->attr.mode); break; case NUMBER: dbg("NUMBER name = '%s', bus = '%s', id = '%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->bus, dev->id, - dev->owner, dev->group, dev->mode); + dev->attr.name, dev->bus, dev->id, + dev->attr.owner, dev->attr.group, dev->attr.mode); break; case TOPOLOGY: dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->bus, dev->place, - dev->owner, dev->group, dev->mode); + dev->attr.name, dev->bus, dev->place, + dev->attr.owner, dev->attr.group, dev->attr.mode); break; case REPLACE: dbg("REPLACE name = %s, kernel_name = %s" " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->kernel_name, - dev->owner, dev->group, dev->mode); + dev->attr.name, dev->kernel_name, + dev->attr.owner, dev->attr.group, dev->attr.mode); break; default: dbg("Unknown type of device!"); @@ -133,18 +98,18 @@ static int add_dev(struct config_device *new_dev) * this one... */ list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); - if (strcmp(dev->name, new_dev->name) == 0) { + if (strcmp(dev->attr.name, new_dev->attr.name) == 0) { /* the same, copy the new info into this structure */ copy_var(dev, new_dev, type); - copy_var(dev, new_dev, mode); + copy_var(dev, new_dev, attr.mode); copy_string(dev, new_dev, bus); copy_string(dev, new_dev, sysfs_file); copy_string(dev, new_dev, sysfs_value); copy_string(dev, new_dev, id); copy_string(dev, new_dev, place); copy_string(dev, new_dev, kernel_name); - copy_string(dev, new_dev, owner); - copy_string(dev, new_dev, group); + copy_string(dev, new_dev, attr.owner); + copy_string(dev, new_dev, attr.group); return 0; } } @@ -286,9 +251,9 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.name, temp3); + strcpy(dev.attr.name, temp3); - dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'", dev.name, dev.bus, dev.sysfs_file, dev.sysfs_value); + dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'", dev.attr.name, dev.bus, dev.sysfs_file, dev.sysfs_value); } if (strcasecmp(temp2, TYPE_NUMBER) == 0) { @@ -313,9 +278,9 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.name, temp3); + strcpy(dev.attr.name, temp3); - dbg("NUMBER name = '%s', bus = '%s', id = '%s'", dev.name, dev.bus, dev.id); + dbg("NUMBER name = '%s', bus = '%s', id = '%s'", dev.attr.name, dev.bus, dev.id); } if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { @@ -340,9 +305,9 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.name, temp3); + strcpy(dev.attr.name, temp3); - dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'", dev.name, dev.bus, dev.place); + dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'", dev.attr.name, dev.bus, dev.place); } if (strcasecmp(temp2, TYPE_REPLACE) == 0) { @@ -360,8 +325,8 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.name, temp3); - dbg("REPLACE name = %s, kernel_name = %s", dev.name, dev.kernel_name); + strcpy(dev.attr.name, temp3); + dbg("REPLACE name = %s, kernel_name = %s", dev.attr.name, dev.kernel_name); } retval = add_dev(&dev); @@ -420,17 +385,17 @@ static int namedev_init_permissions(void) /* parse the line */ temp2 = strsep(&temp, ":"); - strncpy(dev.name, temp2, sizeof(dev.name)); + strncpy(dev.attr.name, temp2, sizeof(dev.attr.name)); temp2 = strsep(&temp, ":"); - strncpy(dev.owner, temp2, sizeof(dev.owner)); + strncpy(dev.attr.owner, temp2, sizeof(dev.attr.owner)); temp2 = strsep(&temp, ":"); - strncpy(dev.group, temp2, sizeof(dev.owner)); + strncpy(dev.attr.group, temp2, sizeof(dev.attr.owner)); - dev.mode = strtol(temp, NULL, 8); + dev.attr.mode = strtol(temp, NULL, 8); - dbg("name = %s, owner = %s, group = %s, mode = %#o", dev.name, dev.owner, dev.group, dev.mode); + dbg("name = %s, owner = %s, group = %s, mode = %#o", dev.attr.name, dev.attr.owner, dev.attr.group, dev.attr.mode); retval = add_dev(&dev); if (retval) { dbg("add_dev returned with error %d", retval); @@ -457,13 +422,13 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); - if (strcmp(dev->name, class_dev->name) == 0) { - attr->mode = dev->mode; - strcpy(attr->owner, dev->owner); - strcpy(attr->group, dev->group); + if (strcmp(dev->attr.name, class_dev->name) == 0) { + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); /* FIXME put the proper name here!!! */ - strcpy(attr->name, dev->name); - dbg("%s - owner = %s, group = %s, mode = %#o", dev->name, dev->owner, dev->group, dev->mode); + strcpy(attr->name, dev->attr.name); + dbg("%s - owner = %s, group = %s, mode = %#o", dev->attr.name, dev->attr.owner, dev->attr.group, dev->attr.mode); goto exit; } } diff --git a/namedev.h b/namedev.h index 0e3a819952..9d612dfe0c 100644 --- a/namedev.h +++ b/namedev.h @@ -23,6 +23,8 @@ #ifndef NAMEDEV_H #define NAMEDEV_H +#include "list.h" + struct sysfs_class_device; /* namedev config files */ @@ -31,6 +33,38 @@ struct sysfs_class_device; #define NAMEDEV_CONFIG_PERMISSION_FILE "namedev.permissions" #define NAMEDEV_CONFIG_FILE "namedev.config" +enum config_type { + KERNEL_NAME = 0, /* must be 0 to let memset() default to this value */ + LABEL = 1, + NUMBER = 2, + TOPOLOGY = 3, + REPLACE = 4, +}; + +#define BUS_SIZE 30 +#define FILE_SIZE 50 +#define VALUE_SIZE 100 +#define ID_SIZE 50 +#define PLACE_SIZE 50 + + +struct config_device { + struct list_head node; + + enum config_type type; + + char bus[BUS_SIZE]; + char sysfs_file[FILE_SIZE]; + char sysfs_value[VALUE_SIZE]; + char id[ID_SIZE]; + char place[PLACE_SIZE]; + char kernel_name[NAME_SIZE]; + + /* what to set the device to */ + struct device_attr attr; +}; + + extern int namedev_init(void); extern int namedev_name_device(struct sysfs_class_device *class_dev, struct device_attr *attr); From c18d70b4474ef226f06e97bd50dd1c10c494b540 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 23 Jul 2003 22:08:16 -0400 Subject: [PATCH 0028/4284] [PATCH] got REPLACE to work properly. --- namedev.c | 39 +++++++++++++++++++++++++++++++++------ namedev.config | 1 + 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/namedev.c b/namedev.c index 8b7edb7fb1..e1958b5d9f 100644 --- a/namedev.c +++ b/namedev.c @@ -419,18 +419,45 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at { struct list_head *tmp; int retval = 0; + int found; list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); - if (strcmp(dev->attr.name, class_dev->name) == 0) { + switch (dev->type) { + case LABEL: + dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" + " owner = '%s', group = '%s', mode = '%#o'", + dev->attr.name, dev->bus, dev->sysfs_file, dev->sysfs_value, + dev->attr.owner, dev->attr.group, dev->attr.mode); + break; + case NUMBER: + dbg("NUMBER name = '%s', bus = '%s', id = '%s'" + " owner = '%s', group = '%s', mode = '%#o'", + dev->attr.name, dev->bus, dev->id, + dev->attr.owner, dev->attr.group, dev->attr.mode); + break; + case TOPOLOGY: + dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'" + " owner = '%s', group = '%s', mode = '%#o'", + dev->attr.name, dev->bus, dev->place, + dev->attr.owner, dev->attr.group, dev->attr.mode); + break; + case REPLACE: + if (strcmp(dev->kernel_name, class_dev->name) != 0) + continue; + strcpy(attr->name, dev->attr.name); attr->mode = dev->attr.mode; strcpy(attr->owner, dev->attr.owner); strcpy(attr->group, dev->attr.group); - /* FIXME put the proper name here!!! */ - strcpy(attr->name, dev->attr.name); - dbg("%s - owner = %s, group = %s, mode = %#o", dev->attr.name, dev->attr.owner, dev->attr.group, dev->attr.mode); - goto exit; - } + dbg("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->kernel_name, attr->name, + dev->attr.owner, dev->attr.group, dev->attr.mode); + return retval; + break; + default: + dbg("Unknown type of device!"); + break; + } } attr->mode = get_default_mode(class_dev); attr->owner[0] = 0x00; diff --git a/namedev.config b/namedev.config index a26562342c..de7a56119e 100644 --- a/namedev.config +++ b/namedev.config @@ -18,4 +18,5 @@ TOPOLOGY, BUS="usb", place="2.2", NAME="mouse1" # ttyUSB1 should always be called visor REPLACE, KERNEL="ttyUSB1", NAME="visor" +REPLACE, KERNEL="ttyUSB0", NAME="pl2303" From 20051a5be96f731291705d6dce5bf3de7567d6a3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 23 Jul 2003 23:20:58 -0400 Subject: [PATCH 0029/4284] [PATCH] added topology support. --- namedev.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/namedev.c b/namedev.c index e1958b5d9f..b0f1f281b1 100644 --- a/namedev.c +++ b/namedev.c @@ -421,6 +421,8 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at int retval = 0; int found; + dbg("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); + dbg("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); switch (dev->type) { @@ -437,11 +439,37 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at dev->attr.owner, dev->attr.group, dev->attr.mode); break; case TOPOLOGY: - dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->bus, dev->place, + { + char path[SYSFS_PATH_MAX]; + char *temp; + + found = 0; + strcpy(path, class_dev->sysdevice->directory->path); + temp = strrchr(path, '/'); + dbg("TOPOLOGY path = '%s'", path); + dbg("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + if (strstr(temp, dev->place) != NULL) { + found = 1; + } else { + *temp = 0x00; + temp = strrchr(path, '/'); + dbg("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + if (strstr(temp, dev->place) != NULL) + found = 1; + } + if (!found) + continue; + + strcpy(attr->name, dev->attr.name); + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + dbg("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->place, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); + return retval; break; + } case REPLACE: if (strcmp(dev->kernel_name, class_dev->name) != 0) continue; @@ -463,7 +491,6 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at attr->owner[0] = 0x00; attr->group[0] = 0x00; strcpy(attr->name, class_dev->name); -exit: return retval; } From 8a6fbab6dd2ae52f4bf7edc25077948cc5f15a7d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 23 Jul 2003 23:37:27 -0400 Subject: [PATCH 0030/4284] [PATCH] add NUMBER support (basically same logic as TOPOLOGY, perhaps we should merge this...) --- namedev.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/namedev.c b/namedev.c index b0f1f281b1..d5f83c5bc2 100644 --- a/namedev.c +++ b/namedev.c @@ -433,11 +433,37 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at dev->attr.owner, dev->attr.group, dev->attr.mode); break; case NUMBER: - dbg("NUMBER name = '%s', bus = '%s', id = '%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->bus, dev->id, + { + char path[SYSFS_PATH_MAX]; + char *temp; + + found = 0; + strcpy(path, class_dev->sysdevice->directory->path); + temp = strrchr(path, '/'); + dbg("NUMBER path = '%s'", path); + dbg("NUMBER temp = '%s' id = '%s'", temp, dev->id); + if (strstr(temp, dev->id) != NULL) { + found = 1; + } else { + *temp = 0x00; + temp = strrchr(path, '/'); + dbg("TOPOLOGY temp = '%s' id = '%s'", temp, dev->id); + if (strstr(temp, dev->id) != NULL) + found = 1; + } + if (!found) + continue; + + strcpy(attr->name, dev->attr.name); + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + dbg("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->id, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); + return retval; break; + } case TOPOLOGY: { char path[SYSFS_PATH_MAX]; From fa39f0990a563c89cf65baaf400552de3ba49ac6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 23 Jul 2003 23:37:43 -0400 Subject: [PATCH 0031/4284] [PATCH] test config file changes... --- namedev.config | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/namedev.config b/namedev.config index de7a56119e..abff870103 100644 --- a/namedev.config +++ b/namedev.config @@ -13,10 +13,11 @@ NUMBER, BUS="pci", id="00:07.1", NAME="dsp1" # USB mouse plugged into the third port of the first hub to be called mouse0 TOPOLOGY, BUS="usb", place="1.3", NAME="mouse0" -# USB tablet plugged into the second port of the second hub to be called mouse1 -TOPOLOGY, BUS="usb", place="2.2", NAME="mouse1" +# USB tablet plugged into the third port of the second hub to be called mouse1 +TOPOLOGY, BUS="usb", place="2.3", NAME="mouse1" +TOPOLOGY, BUS="usb", place="2.4", NAME="mouse2" # ttyUSB1 should always be called visor REPLACE, KERNEL="ttyUSB1", NAME="visor" -REPLACE, KERNEL="ttyUSB0", NAME="pl2303" +#REPLACE, KERNEL="ttyUSB0", NAME="pl2303" From 03e64c8f8cc426d80db00291821cd6b645f20e05 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 24 Jul 2003 10:27:06 -0400 Subject: [PATCH 0032/4284] [PATCH] start working on label support, and fix some segfaults for block devices. --- namedev.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 5 deletions(-) diff --git a/namedev.c b/namedev.c index d5f83c5bc2..b8243682a7 100644 --- a/namedev.c +++ b/namedev.c @@ -421,23 +421,101 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at int retval = 0; int found; - dbg("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); - dbg("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); + if (class_dev->sysdevice) { + dbg("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); + dbg("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); + } else { + dbg("class_dev->name = '%s'", class_dev->name); + } list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); switch (dev->type) { case LABEL: - dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" + { + char *temp; + + dbg("LABEL: match file '%s' with value '%s'", dev->sysfs_file, dev->sysfs_value); + /* try to find the attribute in the class device directory */ + temp = sysfs_get_value_from_attributes(class_dev->directory->attributes, dev->sysfs_file); + if (temp) + goto label_found; + + /* look in the class device device directory if present */ + if (class_dev->sysdevice) { + temp = sysfs_get_value_from_attributes(class_dev->sysdevice->directory->attributes, dev->sysfs_file); + if (temp) + goto label_found; + } + + /* bah, let's go backwards up a level to see if the device is there, + * as block partitions don't point to the physical device. Need to fix that + * up in the kernel... + */ + if (strstr(class_dev->directory->path, "block")) { + dbg("looking at block device..."); + if (isdigit(class_dev->directory->path[strlen(class_dev->directory->path)-1])) { + char path[SYSFS_PATH_MAX]; + struct sysfs_class_device *class_dev_parent; + + dbg("really is a partition..."); + strcpy(path, class_dev->directory->path); + temp = strrchr(path, '/'); + *temp = 0x00; + dbg("looking for a class device at '%s'", path); + class_dev_parent = sysfs_open_class_device(path); + if (class_dev_parent == NULL) { + dbg ("sysfs_open_class_device failed"); + continue; + } + dbg("class_dev_parent->name = %s", class_dev_parent->name); + + /* try to find the attribute in the class device directory */ + temp = sysfs_get_value_from_attributes(class_dev_parent->directory->attributes, dev->sysfs_file); + if (temp) { + //sysfs_close_class_device(class_dev_parent); + goto label_found; + } + + /* look in the class device device directory if present */ + if (class_dev_parent->sysdevice) { + temp = sysfs_get_value_from_attributes(class_dev_parent->sysdevice->directory->attributes, dev->sysfs_file); + if (temp) { + // sysfs_close_class_device(class_dev_parent); + goto label_found; + } + } + + } + } + continue; + +label_found: + dbg("file '%s' found with value '%s'", dev->sysfs_file, temp); + if (strcmp(dev->sysfs_value, temp) != 0) + continue; + + strcpy(attr->name, dev->attr.name); + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + dbg("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->sysfs_file, dev->sysfs_value, attr->name, + dev->attr.owner, dev->attr.group, dev->attr.mode); + return retval; +dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" " owner = '%s', group = '%s', mode = '%#o'", dev->attr.name, dev->bus, dev->sysfs_file, dev->sysfs_value, dev->attr.owner, dev->attr.group, dev->attr.mode); break; + } case NUMBER: { char path[SYSFS_PATH_MAX]; char *temp; - found = 0; + found = 0; + if (!class_dev->sysdevice) + continue; strcpy(path, class_dev->sysdevice->directory->path); temp = strrchr(path, '/'); dbg("NUMBER path = '%s'", path); @@ -469,6 +547,8 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at char path[SYSFS_PATH_MAX]; char *temp; + if (!class_dev->sysdevice) + continue; found = 0; strcpy(path, class_dev->sysdevice->directory->path); temp = strrchr(path, '/'); @@ -508,8 +588,10 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at dev->attr.owner, dev->attr.group, dev->attr.mode); return retval; break; + case KERNEL_NAME: + break; default: - dbg("Unknown type of device!"); + dbg("Unknown type of device '%d'", dev->type); break; } } From cee360d32efd8392f7e342dcaeda1de50a2c1bcf Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 24 Jul 2003 19:59:52 -0400 Subject: [PATCH 0033/4284] [PATCH] added 0.2 change log info. --- ChangeLog | 11 +++++++++-- Makefile | 2 +- README | 4 +--- TODO | 2 ++ 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index f8b5da0f1d..a0bd85174b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,2 +1,9 @@ -0.1 - Added a bit of documentation to the README and TODO files. -0.01 - initial release +0.2 - added namedev + now used a snapshot of libsysfs. + Can now handle the 5 different naming schemes. + Was released based on my OLS 2003 presentation. + Lots still left to do, but it kinda works better... + +0.1 - Added a bit of documentation to the README and TODO files. + +0.01 - initial release diff --git a/Makefile b/Makefile index 989eb403bf..b1adf3456c 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 0.1 +VERSION = 0.2 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/README b/README index 1a46a3c1ee..07fa162bbd 100644 --- a/README +++ b/README @@ -8,9 +8,7 @@ To use: - Edit the udev.h file and replace the following variables with values that make sense for your system: - #define SYSFS_ROOT "/sys" - #define UDEV_ROOT "/home/greg/linux/udev/" - #define DEV_FILE "/dev" + #define UDEV_ROOT "/udev/" #define MKNOD "/bin/mknod" The only value most people will have to change is the UDEV_ROOT variable, as I doubt you really want device nodes to be created in my diff --git a/TODO b/TODO index 1f776b9142..0bcaf2cc24 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,8 @@ - use mknod(2) and not execute mknod(1) - add klibc to the build process (or make it easier to do) to get smaller binary +- document the config file format (it will change over time...) +- persistant naming database backend - make program work like design says it should (three parts, not 1) - add hooks to call D-BUS when new node is created or removed - lots of other stuff... From ea70388c3c21b6da592a859013b8e6aa071f6512 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 24 Jul 2003 20:00:17 -0400 Subject: [PATCH 0034/4284] [PATCH] removed unneeded stuff from udev.h --- udev.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/udev.h b/udev.h index 59c374365e..3c3c3d5de7 100644 --- a/udev.h +++ b/udev.h @@ -37,15 +37,9 @@ /* Lots of constants that should be in a config file sometime */ -/* Location of sysfs mount */ -#define SYSFS_ROOT "/sys" - /* Where udev should create its device nodes, trailing / needed */ #define UDEV_ROOT "/udev/" -/* device file in sysfs that contains major/minor number, leading / needed */ -#define DEV_FILE "/dev" - /* Binaries that udev calls to do stuff */ #define MKNOD "/bin/mknod" From 08daec117c109d53df85c07d250bdd9ce7a9f263 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 24 Jul 2003 20:00:32 -0400 Subject: [PATCH 0035/4284] [PATCH] more test stuff... --- namedev.config | 3 +++ test.block | 2 ++ 2 files changed, 5 insertions(+) diff --git a/namedev.config b/namedev.config index abff870103..a0c6f9d1e8 100644 --- a/namedev.config +++ b/namedev.config @@ -1,3 +1,6 @@ +# My usb camera... +LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera" + # USB Epson printer to be called lp_epson LABEL, BUS="usb", serial="HXOLL0012202323480", NAME="lp_epson" diff --git a/test.block b/test.block index 675fbc057a..3e198fe4b6 100644 --- a/test.block +++ b/test.block @@ -3,6 +3,8 @@ export ACTION=add #export ACTION=remove export DEVPATH=/block/hda +export DEVPATH=/block/sda/sda1 +export DEVPATH=/block/sda ./udev block From 615e05f84a36b948959a01c58738f00109f9de0a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 25 Jul 2003 07:01:48 -0400 Subject: [PATCH 0036/4284] [PATCH] oops, everything was getting created as 000 mode, try to fix this up, --- namedev.c | 65 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/namedev.c b/namedev.c index b8243682a7..d8dba345d1 100644 --- a/namedev.c +++ b/namedev.c @@ -421,6 +421,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at int retval = 0; int found; + attr->mode = -1; if (class_dev->sysdevice) { dbg("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); dbg("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); @@ -488,24 +489,28 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at } } continue; - + label_found: - dbg("file '%s' found with value '%s'", dev->sysfs_file, temp); + temp[strlen(temp)-1] = 0x00; + dbg("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, temp, dev->sysfs_value); if (strcmp(dev->sysfs_value, temp) != 0) continue; strcpy(attr->name, dev->attr.name); - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + if (isdigit(class_dev->directory->path[strlen(class_dev->directory->path)-1])) { + temp[0] = class_dev->directory->path[strlen(class_dev->directory->path)-1]; + temp[1] = 0x00; + strcat(attr->name, temp); + } + if (dev->attr.mode != 0) { + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + } dbg("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->sysfs_file, dev->sysfs_value, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); - return retval; -dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->bus, dev->sysfs_file, dev->sysfs_value, - dev->attr.owner, dev->attr.group, dev->attr.mode); + goto done; break; } case NUMBER: @@ -533,13 +538,15 @@ dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" continue; strcpy(attr->name, dev->attr.name); - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + if (dev->attr.mode != 0) { + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + } dbg("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->id, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); - return retval; + goto done; break; } case TOPOLOGY: @@ -567,26 +574,30 @@ dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" continue; strcpy(attr->name, dev->attr.name); - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + if (dev->attr.mode != 0) { + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + } dbg("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->place, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); - return retval; + goto done; break; } case REPLACE: if (strcmp(dev->kernel_name, class_dev->name) != 0) continue; strcpy(attr->name, dev->attr.name); - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + if (dev->attr.mode != 0) { + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + } dbg("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->kernel_name, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); - return retval; + goto done; break; case KERNEL_NAME: break; @@ -595,10 +606,14 @@ dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" break; } } - attr->mode = get_default_mode(class_dev); - attr->owner[0] = 0x00; - attr->group[0] = 0x00; strcpy(attr->name, class_dev->name); + +done: + if (attr->mode == -1) { + attr->mode = get_default_mode(class_dev); + attr->owner[0] = 0x00; + attr->group[0] = 0x00; + } return retval; } From ea256f901e30927591874ee3eb5b92e1ce5a5db1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 4 Aug 2003 21:20:19 -0700 Subject: [PATCH 0037/4284] [PATCH] handle new major:minor format of dev files that showed up in 2.6.0-test2-bk3 or so. --- udev-add.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/udev-add.c b/udev-add.c index 45ffbf81b5..54af7e4d77 100644 --- a/udev-add.c +++ b/udev-add.c @@ -49,30 +49,23 @@ static char sysfs_path[SYSFS_PATH_MAX]; */ static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) { - char temp[3]; - int retval = 0; + int retval = -ENODEV; char *dev; dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); if (dev == NULL) - return -ENODEV; + goto exit; dbg("dev = %s", dev); - temp[0] = dev[0]; - temp[1] = dev[1]; - temp[2] = 0x00; - *major = (int)strtol(&temp[0], NULL, 16); - - temp[0] = dev[2]; - temp[1] = dev[3]; - temp[2] = 0x00; - *minor = (int)strtol(&temp[0], NULL, 16); + if (sscanf(dev, "%u:%u", major, minor) != 2) + goto exit; dbg("found major = %d, minor = %d", *major, *minor); retval = 0; +exit: return retval; } From 0abf54fc09030f404f5c7d724a0f30d3e875e980 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 4 Aug 2003 21:39:33 -0700 Subject: [PATCH 0038/4284] [PATCH] remove mknod callout Patch from "Guo, Min" --- udev-add.c | 45 ++++++++++++--------------------------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/udev-add.c b/udev-add.c index 54af7e4d77..adbeb92425 100644 --- a/udev-add.c +++ b/udev-add.c @@ -74,45 +74,24 @@ exit: */ static int create_node(char *name, char type, int major, int minor, int mode) { - char *argv[7]; - char mode_string[100]; - char type_string[3]; - char major_string[20]; - char minor_string[20]; char filename[255]; int retval = 0; - strncpy(filename, UDEV_ROOT, sizeof(filename)); strncat(filename, name, sizeof(filename)); + if (type == 'b') { + mode |= S_IFBLK; + } else if ((type == 'c') || (type == 'u')){ + mode |= S_IFCHR; + } else if ( type == 'p') { + mode |= S_IFIFO; + } else { + dbg("unknown node type %c\n", type); + return -1; + } - snprintf(mode_string, sizeof(mode_string), "--mode=%#o", mode); - snprintf(type_string, sizeof(type_string), "%c", type); - snprintf(major_string, sizeof(major_string), "%d", major); - snprintf(minor_string, sizeof(minor_string), "%d", minor); - - argv[0] = MKNOD; - argv[1] = mode_string; - argv[2] = filename; - argv[3] = type_string; - argv[4] = major_string; - argv[5] = minor_string; - argv[6] = NULL; - dbg ("executing %s %s %s %s %s %s", - argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); - switch (fork()) { - case 0: - /* we are the child, so lets run the program */ - execv (MKNOD, argv); - exit(0); - break; - case (-1): - dbg ("fork failed."); - retval = -EFAULT; - break; - default: - break; - } + retval = mknod(filename,mode,makedev(major,minor)); return retval; + } struct sysfs_class_device *get_class_dev(char *device_name) From 1331c889c33a91f098fa7257488046e81241225c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 4 Aug 2003 21:59:50 -0700 Subject: [PATCH 0039/4284] [PATCH] cleanup the mknod code a bit. --- udev-add.c | 29 ++++++++++++++++++----------- udev.h | 3 --- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/udev-add.c b/udev-add.c index adbeb92425..10df31458d 100644 --- a/udev-add.c +++ b/udev-add.c @@ -78,20 +78,27 @@ static int create_node(char *name, char type, int major, int minor, int mode) int retval = 0; strncpy(filename, UDEV_ROOT, sizeof(filename)); strncat(filename, name, sizeof(filename)); - if (type == 'b') { - mode |= S_IFBLK; - } else if ((type == 'c') || (type == 'u')){ - mode |= S_IFCHR; - } else if ( type == 'p') { - mode |= S_IFIFO; - } else { - dbg("unknown node type %c\n", type); - return -1; - } + switch (type) { + case 'b': + mode |= S_IFBLK; + break; + case 'c': + case 'u': + mode |= S_IFCHR; + break; + case 'p': + mode |= S_IFIFO; + break; + default: + dbg("unknown node type %c\n", type); + return -EINVAL; + } retval = mknod(filename,mode,makedev(major,minor)); + if (retval) + dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", + filename, mode, major, minor, strerror(errno)); return retval; - } struct sysfs_class_device *get_class_dev(char *device_name) diff --git a/udev.h b/udev.h index 3c3c3d5de7..590a8ed039 100644 --- a/udev.h +++ b/udev.h @@ -40,9 +40,6 @@ /* Where udev should create its device nodes, trailing / needed */ #define UDEV_ROOT "/udev/" -/* Binaries that udev calls to do stuff */ -#define MKNOD "/bin/mknod" - extern int log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); From 63dde9f8eb9a204771be7cc3219d53ee7a0d5ffb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 4 Aug 2003 22:13:35 -0700 Subject: [PATCH 0040/4284] [PATCH] minor cleanups. --- udev-add.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/udev-add.c b/udev-add.c index 10df31458d..586815e2c7 100644 --- a/udev-add.c +++ b/udev-add.c @@ -34,8 +34,6 @@ #include "libsysfs/libsysfs.h" -static char sysfs_path[SYSFS_PATH_MAX]; - /* * Right now the major/minor of a device is stored in a file called * "dev" in sysfs. @@ -103,8 +101,18 @@ static int create_node(char *name, char type, int major, int minor, int mode) struct sysfs_class_device *get_class_dev(char *device_name) { + char sysfs_path[SYSFS_PATH_MAX]; char dev_path[SYSFS_PATH_MAX]; - struct sysfs_class_device *class_dev; + int retval; + struct sysfs_class_device *class_dev = NULL; + + + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + dbg("sysfs_path = %s", sysfs_path); + if (retval) { + dbg("sysfs_get_mnt_path failed"); + goto exit; + } strcpy(dev_path, sysfs_path); strcat(dev_path, device_name); @@ -115,46 +123,34 @@ struct sysfs_class_device *get_class_dev(char *device_name) class_dev = sysfs_open_class_device(dev_path); if (class_dev == NULL) { dbg ("sysfs_open_class_device failed"); - return NULL; + goto exit; } dbg("class_dev->name = %s", class_dev->name); +exit: return class_dev; } -static int udev_init(void) -{ - int retval; - - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - dbg("sysfs_path = %s", sysfs_path); - return retval; -} - int udev_add_device(char *device, char *subsystem) { struct sysfs_class_device *class_dev; struct device_attr attr; - //char *name; int major; int minor; char type; - //int mode; int retval = -EINVAL; - /* sleep for a second or two to give the kernel a chance to - * create the dev file - */ - sleep(1); - - udev_init(); - /* for now, the block layer is the only place where block devices are */ if (strcmp(subsystem, "block") == 0) type = 'b'; else type = 'c'; + /* sleep for a second or two to give the kernel a chance to + * create the dev file + */ + sleep(1); + class_dev = get_class_dev(device); if (class_dev == NULL) goto exit; From b137e367bb833ca82b396622997f512f5c856a41 Mon Sep 17 00:00:00 2001 From: "lethal@linux-sh.org" Date: Tue, 5 Aug 2003 01:10:01 -0700 Subject: [PATCH 0041/4284] [PATCH] udev/libsysfs cross compile fixes I noticed that libsysfs doesn't inherently grab cross compilation arguments that are set in the top-level Makefile, so I've come up with the following patch to fix this. With the patch, I can succesfully cross compile for other architectures (such as sh) by doing 'make ARCH=sh CROSS=sh-linux-' in the top-level directory. --- Makefile | 2 ++ libsysfs/Makefile | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index b1adf3456c..a7bb01d247 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,9 @@ CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- CC = $(CROSS)gcc AR = $(CROSS)ar STRIP = $(CROSS)strip +RANLIB = $(CROSS)ranlib +export CROSS CC AR STRIP RANLIB # code taken from uClibc to determine the current arch ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ diff --git a/libsysfs/Makefile b/libsysfs/Makefile index cf07a842b6..79cc533959 100644 --- a/libsysfs/Makefile +++ b/libsysfs/Makefile @@ -1,8 +1,6 @@ # Makefile for libsysfs.a # Copyright (c) International Business Machines Corp., 2003 -CC=gcc - H_INCLUDE=../include LIB_INCLUDE=. OBJS=sysfs_bus.o sysfs_class.o sysfs_device.o sysfs_dir.o sysfs_driver.o \ @@ -19,8 +17,8 @@ LIBSYSFS=libsysfs.a RM=rm -f libsysfs.a: $(OBJS) - ar cru $(LIBSYSFS) $(OBJS) - ranlib $(LIBSYSFS) + $(AR) cru $(LIBSYSFS) $(OBJS) + $(RANLIB) $(LIBSYSFS) sysfs_bus.o: sysfs_bus.c $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_bus.c From 3660f0b8ab54c79141a06b55ea617d7724042eae Mon Sep 17 00:00:00 2001 From: "lethal@linux-sh.org" Date: Tue, 5 Aug 2003 01:17:07 -0700 Subject: [PATCH 0042/4284] [PATCH] udev spec file Here's a relatively rudimentary patch that addes udev.spec. With this, you can rpm -ta the tarball and generate rpms. I've also attached the ones I build on my RH 7.3 host incase they are of interest to you. --- udev.spec | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 udev.spec diff --git a/udev.spec b/udev.spec new file mode 100644 index 0000000000..2a64fb31c2 --- /dev/null +++ b/udev.spec @@ -0,0 +1,36 @@ +Summary: A userspace implementation of devfs +Name: udev +Version: 0.2 +Release: 1 +License: GPL +Group: Utilities/System +Source: ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug/%{name}-%{version}.tar.gz +ExclusiveOS: Linux +BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root + +%description +udev is a implementation of devfs in userspace using sysfs and +/sbin/hotplug. It requires a 2.5/2.6 kernel to run properly. + +%prep +%setup + +%build +make + +%install +mkdir -p $RPM_BUILD_ROOT/sbin +install -m 755 %{name} $RPM_BUILD_ROOT/sbin + +%clean +rm -fr $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +%attr(755,root,root)/sbin/%{name} +%attr(-,root,root) %doc COPYING README TODO ChangeLog + +%changelog +* Mon Jul 28 2003 Paul Mundt +- Initial spec file for udev-0.2. + From e09292061689b59da68f05eb7a74e353c283078f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Aug 2003 01:18:46 -0700 Subject: [PATCH 0043/4284] [PATCH] added my name to the .spec file. --- udev.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.spec b/udev.spec index 2a64fb31c2..fe6ca84cc3 100644 --- a/udev.spec +++ b/udev.spec @@ -6,6 +6,7 @@ License: GPL Group: Utilities/System Source: ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug/%{name}-%{version}.tar.gz ExclusiveOS: Linux +Vendor: Greg Kroah-Hartman BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root %description From 5ac4a56b39fed9d95850161864befe612b1a538e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Aug 2003 01:26:59 -0700 Subject: [PATCH 0044/4284] [PATCH] Added tdb code from latest cvs version in the samba tree --- tdb/Makefile | 29 + tdb/README | 167 ++++ tdb/spinlock.c | 430 ++++++++++ tdb/spinlock.h | 55 ++ tdb/tdb.c | 2043 ++++++++++++++++++++++++++++++++++++++++++++++ tdb/tdb.h | 144 ++++ tdb/tdb.magic | 10 + tdb/tdbback.c | 201 +++++ tdb/tdbback.h | 23 + tdb/tdbbackup.c | 137 ++++ tdb/tdbdump.c | 89 ++ tdb/tdbtest.c | 263 ++++++ tdb/tdbtool.c | 547 +++++++++++++ tdb/tdbtorture.c | 226 +++++ tdb/tdbutil.c | 830 +++++++++++++++++++ tdb/tdbutil.h | 37 + 16 files changed, 5231 insertions(+) create mode 100644 tdb/Makefile create mode 100644 tdb/README create mode 100644 tdb/spinlock.c create mode 100644 tdb/spinlock.h create mode 100644 tdb/tdb.c create mode 100644 tdb/tdb.h create mode 100644 tdb/tdb.magic create mode 100644 tdb/tdbback.c create mode 100644 tdb/tdbback.h create mode 100644 tdb/tdbbackup.c create mode 100644 tdb/tdbdump.c create mode 100644 tdb/tdbtest.c create mode 100644 tdb/tdbtool.c create mode 100644 tdb/tdbtorture.c create mode 100644 tdb/tdbutil.c create mode 100644 tdb/tdbutil.h diff --git a/tdb/Makefile b/tdb/Makefile new file mode 100644 index 0000000000..59fbb079bd --- /dev/null +++ b/tdb/Makefile @@ -0,0 +1,29 @@ +# +# Makefile for tdb directory +# + +CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1 +CC = gcc + +PROGS = tdbtest tdbtool tdbtorture +TDB_OBJ = tdb.o spinlock.o + +default: $(PROGS) + +tdbtest: tdbtest.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbtest tdbtest.o $(TDB_OBJ) -lgdbm + +tdbtool: tdbtool.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbtool tdbtool.o $(TDB_OBJ) + +tdbtorture: tdbtorture.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o $(TDB_OBJ) + +tdbdump: tdbdump.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbdump tdbdump.o $(TDB_OBJ) + +tdbbackup: tdbbackup.o $(TDB_OBJ) + $(CC) $(CFLAGS) -o tdbbackup tdbbackup.o $(TDB_OBJ) + +clean: + rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm diff --git a/tdb/README b/tdb/README new file mode 100644 index 0000000000..fac3eacb4d --- /dev/null +++ b/tdb/README @@ -0,0 +1,167 @@ +tdb - a trivial database system +tridge@linuxcare.com December 1999 +================================== + +This is a simple database API. It was inspired by the realisation that +in Samba we have several ad-hoc bits of code that essentially +implement small databases for sharing structures between parts of +Samba. As I was about to add another I realised that a generic +database module was called for to replace all the ad-hoc bits. + +I based the interface on gdbm. I couldn't use gdbm as we need to be +able to have multiple writers to the databases at one time. + +Compilation +----------- + +add HAVE_MMAP=1 to use mmap instead of read/write +add TDB_DEBUG=1 for verbose debug info +add NOLOCK=1 to disable locking code + +Testing +------- + +Compile tdbtest.c and link with gdbm for testing. tdbtest will perform +identical operations via tdb and gdbm then make sure the result is the +same + +Also included is tdbtool, which allows simple database manipulation +on the commandline. + +tdbtest and tdbtool are not built as part of Samba, but are included +for completeness. + +Interface +--------- + +The interface is very similar to gdbm except for the following: + +- different open interface. The tdb_open call is more similar to a + traditional open() +- no tdbm_reorganise() function +- no tdbm_sync() function. No operations are cached in the library anyway +- added a tdb_traverse() function for traversing the whole database + +A general rule for using tdb is that the caller frees any returned +TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA +return value called p. This is the same as gdbm. + +here is a full list of tdb functions with brief descriptions. + + +---------------------------------------------------------------------- +TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) + + open the database, creating it if necessary + + The open_flags and mode are passed straight to the open call on the database + file. A flags value of O_WRONLY is invalid + + The hash size is advisory, use zero for a default value. + + return is NULL on error + + possible tdb_flags are: + TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open + TDB_INTERNAL - don't use a file, instaed store the data in + memory. The filename is ignored in this case. + TDB_NOLOCK - don't do any locking + TDB_NOMMAP - don't use mmap + +---------------------------------------------------------------------- +char *tdb_error(TDB_CONTEXT *tdb); + + return a error string for the last tdb error + +---------------------------------------------------------------------- +int tdb_close(TDB_CONTEXT *tdb); + + close a database + +---------------------------------------------------------------------- +int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf); + + update an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1 + +---------------------------------------------------------------------- +TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); + + fetch an entry in the database given a key + if the return value has a null dptr then a error occurred + + caller must free the resulting data + +---------------------------------------------------------------------- +int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); + + check if an entry in the database exists + + note that 1 is returned if the key is found and 0 is returned if not found + this doesn't match the conventions in the rest of this module, but is + compatible with gdbm + +---------------------------------------------------------------------- +int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, + TDB_DATA key, TDB_DATA dbuf, void *state), void *state); + + traverse the entire database - calling fn(tdb, key, data, state) on each + element. + + return -1 on error or the record count traversed + + if fn is NULL then it is not called + + a non-zero return value from fn() indicates that the traversal should stop + +---------------------------------------------------------------------- +TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); + + find the first entry in the database and return its key + + the caller must free the returned data + +---------------------------------------------------------------------- +TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); + + find the next entry in the database, returning its key + + the caller must free the returned data + +---------------------------------------------------------------------- +int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); + + delete an entry in the database given a key + +---------------------------------------------------------------------- +int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); + + store an element in the database, replacing any existing element + with the same key + + If flag==TDB_INSERT then don't overwrite an existing entry + If flag==TDB_MODIFY then don't create a new entry + + return 0 on success, -1 on failure + +---------------------------------------------------------------------- +int tdb_writelock(TDB_CONTEXT *tdb); + + lock the database. If we already have it locked then don't do anything + +---------------------------------------------------------------------- +int tdb_writeunlock(TDB_CONTEXT *tdb); + unlock the database + +---------------------------------------------------------------------- +int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key); + + lock one hash chain. This is meant to be used to reduce locking + contention - it cannot guarantee how many records will be locked + +---------------------------------------------------------------------- +int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key); + + unlock one hash chain diff --git a/tdb/spinlock.c b/tdb/spinlock.c new file mode 100644 index 0000000000..2370ce3bdd --- /dev/null +++ b/tdb/spinlock.c @@ -0,0 +1,430 @@ +/* + Unix SMB/CIFS implementation. + Samba database functions + Copyright (C) Anton Blanchard 2001 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +#if HAVE_CONFIG_H +#include +#endif + +#if STANDALONE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" +#include "spinlock.h" + +#define DEBUG +#else +#include "includes.h" +#endif + +#ifdef USE_SPINLOCKS + +/* + * ARCH SPECIFIC + */ + +#if defined(SPARC_SPINLOCKS) + +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int result; + + asm volatile("ldstub [%1], %0" + : "=r" (result) + : "r" (lock) + : "memory"); + + return (result == 0) ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("":::"memory"); + *lock = 0; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 0; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 0); +} + +#elif defined(POWERPC_SPINLOCKS) + +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int result; + + __asm__ __volatile__( +"1: lwarx %0,0,%1\n\ + cmpwi 0,%0,0\n\ + li %0,0\n\ + bne- 2f\n\ + li %0,1\n\ + stwcx. %0,0,%1\n\ + bne- 1b\n\ + isync\n\ +2:" : "=&r"(result) + : "r"(lock) + : "cr0", "memory"); + + return (result == 1) ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("eieio":::"memory"); + *lock = 0; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 0; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 0); +} + +#elif defined(INTEL_SPINLOCKS) + +static inline int __spin_trylock(spinlock_t *lock) +{ + int oldval; + + asm volatile("xchgl %0,%1" + : "=r" (oldval), "=m" (*lock) + : "0" (0) + : "memory"); + + return oldval > 0 ? 0 : EBUSY; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("":::"memory"); + *lock = 1; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 1; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 1); +} + +#elif defined(MIPS_SPINLOCKS) + +static inline unsigned int load_linked(unsigned long addr) +{ + unsigned int res; + + __asm__ __volatile__("ll\t%0,(%1)" + : "=r" (res) + : "r" (addr)); + + return res; +} + +static inline unsigned int store_conditional(unsigned long addr, unsigned int value) +{ + unsigned int res; + + __asm__ __volatile__("sc\t%0,(%2)" + : "=r" (res) + : "0" (value), "r" (addr)); + return res; +} + +static inline int __spin_trylock(spinlock_t *lock) +{ + unsigned int mw; + + do { + mw = load_linked(lock); + if (mw) + return EBUSY; + } while (!store_conditional(lock, 1)); + + asm volatile("":::"memory"); + + return 0; +} + +static inline void __spin_unlock(spinlock_t *lock) +{ + asm volatile("":::"memory"); + *lock = 0; +} + +static inline void __spin_lock_init(spinlock_t *lock) +{ + *lock = 0; +} + +static inline int __spin_is_locked(spinlock_t *lock) +{ + return (*lock != 0); +} + +#else +#error Need to implement spinlock code in spinlock.c +#endif + +/* + * OS SPECIFIC + */ + +static void yield_cpu(void) +{ + struct timespec tm; + +#ifdef USE_SCHED_YIELD + sched_yield(); +#else + /* Linux will busy loop for delays < 2ms on real time tasks */ + tm.tv_sec = 0; + tm.tv_nsec = 2000000L + 1; + nanosleep(&tm, NULL); +#endif +} + +static int this_is_smp(void) +{ + return 0; +} + +/* + * GENERIC + */ + +static int smp_machine = 0; + +static inline void __spin_lock(spinlock_t *lock) +{ + int ntries = 0; + + while(__spin_trylock(lock)) { + while(__spin_is_locked(lock)) { + if (smp_machine && ntries++ < MAX_BUSY_LOOPS) + continue; + yield_cpu(); + } + } +} + +static void __read_lock(tdb_rwlock_t *rwlock) +{ + int ntries = 0; + + while(1) { + __spin_lock(&rwlock->lock); + + if (!(rwlock->count & RWLOCK_BIAS)) { + rwlock->count++; + __spin_unlock(&rwlock->lock); + return; + } + + __spin_unlock(&rwlock->lock); + + while(rwlock->count & RWLOCK_BIAS) { + if (smp_machine && ntries++ < MAX_BUSY_LOOPS) + continue; + yield_cpu(); + } + } +} + +static void __write_lock(tdb_rwlock_t *rwlock) +{ + int ntries = 0; + + while(1) { + __spin_lock(&rwlock->lock); + + if (rwlock->count == 0) { + rwlock->count |= RWLOCK_BIAS; + __spin_unlock(&rwlock->lock); + return; + } + + __spin_unlock(&rwlock->lock); + + while(rwlock->count != 0) { + if (smp_machine && ntries++ < MAX_BUSY_LOOPS) + continue; + yield_cpu(); + } + } +} + +static void __write_unlock(tdb_rwlock_t *rwlock) +{ + __spin_lock(&rwlock->lock); + +#ifdef DEBUG + if (!(rwlock->count & RWLOCK_BIAS)) + fprintf(stderr, "bug: write_unlock\n"); +#endif + + rwlock->count &= ~RWLOCK_BIAS; + __spin_unlock(&rwlock->lock); +} + +static void __read_unlock(tdb_rwlock_t *rwlock) +{ + __spin_lock(&rwlock->lock); + +#ifdef DEBUG + if (!rwlock->count) + fprintf(stderr, "bug: read_unlock\n"); + + if (rwlock->count & RWLOCK_BIAS) + fprintf(stderr, "bug: read_unlock\n"); +#endif + + rwlock->count--; + __spin_unlock(&rwlock->lock); +} + +/* TDB SPECIFIC */ + +/* lock a list in the database. list -1 is the alloc list */ +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) +{ + tdb_rwlock_t *rwlocks; + + if (!tdb->map_ptr) return -1; + rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); + + switch(rw_type) { + case F_RDLCK: + __read_lock(&rwlocks[list+1]); + break; + + case F_WRLCK: + __write_lock(&rwlocks[list+1]); + break; + + default: + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + return 0; +} + +/* unlock the database. */ +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) +{ + tdb_rwlock_t *rwlocks; + + if (!tdb->map_ptr) return -1; + rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); + + switch(rw_type) { + case F_RDLCK: + __read_unlock(&rwlocks[list+1]); + break; + + case F_WRLCK: + __write_unlock(&rwlocks[list+1]); + break; + + default: + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + + return 0; +} + +int tdb_create_rwlocks(int fd, unsigned int hash_size) +{ + unsigned size, i; + tdb_rwlock_t *rwlocks; + + size = (hash_size + 1) * sizeof(tdb_rwlock_t); + rwlocks = malloc(size); + if (!rwlocks) + return -1; + + for(i = 0; i < hash_size+1; i++) { + __spin_lock_init(&rwlocks[i].lock); + rwlocks[i].count = 0; + } + + /* Write it out (appending to end) */ + if (write(fd, rwlocks, size) != size) { + free(rwlocks); + return -1; + } + smp_machine = this_is_smp(); + free(rwlocks); + return 0; +} + +int tdb_clear_spinlocks(TDB_CONTEXT *tdb) +{ + tdb_rwlock_t *rwlocks; + unsigned i; + + if (tdb->header.rwlocks == 0) return 0; + if (!tdb->map_ptr) return -1; + + /* We're mmapped here */ + rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); + for(i = 0; i < tdb->header.hash_size+1; i++) { + __spin_lock_init(&rwlocks[i].lock); + rwlocks[i].count = 0; + } + return 0; +} +#else +int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; } +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } + +/* Non-spinlock version: remove spinlock pointer */ +int tdb_clear_spinlocks(TDB_CONTEXT *tdb) +{ + tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks + - (char *)&tdb->header); + + tdb->header.rwlocks = 0; + if (lseek(tdb->fd, off, SEEK_SET) != off + || write(tdb->fd, (void *)&tdb->header.rwlocks, + sizeof(tdb->header.rwlocks)) + != sizeof(tdb->header.rwlocks)) + return -1; + return 0; +} +#endif diff --git a/tdb/spinlock.h b/tdb/spinlock.h new file mode 100644 index 0000000000..8b0e833ff5 --- /dev/null +++ b/tdb/spinlock.h @@ -0,0 +1,55 @@ +#ifndef __SPINLOCK_H__ +#define __SPINLOCK_H__ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "tdb.h" + +#ifdef USE_SPINLOCKS + +#define RWLOCK_BIAS 0x1000UL + +/* OS SPECIFIC */ +#define MAX_BUSY_LOOPS 1000 +#undef USE_SCHED_YIELD + +/* ARCH SPECIFIC */ +/* We should make sure these are padded to a cache line */ +#if defined(SPARC_SPINLOCKS) +typedef volatile char spinlock_t; +#elif defined(POWERPC_SPINLOCKS) +typedef volatile unsigned long spinlock_t; +#elif defined(INTEL_SPINLOCKS) +typedef volatile int spinlock_t; +#elif defined(MIPS_SPINLOCKS) +typedef volatile unsigned long spinlock_t; +#else +#error Need to implement spinlock code in spinlock.h +#endif + +typedef struct { + spinlock_t lock; + volatile int count; +} tdb_rwlock_t; + +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_create_rwlocks(int fd, unsigned int hash_size); +int tdb_clear_spinlocks(TDB_CONTEXT *tdb); + +#else /* !USE_SPINLOCKS */ +#if 0 +#define tdb_create_rwlocks(fd, hash_size) 0 +#define tdb_spinlock(tdb, list, rw_type) (-1) +#define tdb_spinunlock(tdb, list, rw_type) (-1) +#else +int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); +int tdb_create_rwlocks(int fd, unsigned int hash_size); +#endif +int tdb_clear_spinlocks(TDB_CONTEXT *tdb); +#endif + +#endif diff --git a/tdb/tdb.c b/tdb/tdb.c new file mode 100644 index 0000000000..34681ea78f --- /dev/null +++ b/tdb/tdb.c @@ -0,0 +1,2043 @@ + /* + Unix SMB/CIFS implementation. + Samba database functions + Copyright (C) Andrew Tridgell 1999-2000 + Copyright (C) Luke Kenneth Casson Leighton 2000 + Copyright (C) Paul `Rusty' Russell 2000 + Copyright (C) Jeremy Allison 2000-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; 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/* NOTE: If you use tdbs under valgrind, and in particular if you run + * tdbtorture, you may get spurious "uninitialized value" warnings. I + * think this is because valgrind doesn't understand that the mmap'd + * area may be written to by other processes. Memory can, from the + * point of view of the grinded process, spontaneously become + * initialized. + * + * I can think of a few solutions. [mbp 20030311] + * + * 1 - Write suppressions for Valgrind so that it doesn't complain + * about this. Probably the most reasonable but people need to + * remember to use them. + * + * 2 - Use IO not mmap when running under valgrind. Not so nice. + * + * 3 - Use the special valgrind macros to mark memory as valid at the + * right time. Probably too hard -- the process just doesn't know. + */ + +#ifdef STANDALONE +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" +#include "spinlock.h" +#else +#include "includes.h" +#endif + +#define TDB_MAGIC_FOOD "TDB file\n" +#define TDB_VERSION (0x26011967 + 6) +#define TDB_MAGIC (0x26011999U) +#define TDB_FREE_MAGIC (~TDB_MAGIC) +#define TDB_DEAD_MAGIC (0xFEE1DEAD) +#define TDB_ALIGNMENT 4 +#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT) +#define DEFAULT_HASH_SIZE 131 +#define TDB_PAGE_SIZE 0x2000 +#define FREELIST_TOP (sizeof(struct tdb_header)) +#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) +#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) +#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) +#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) +#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off)) + +/* NB assumes there is a local variable called "tdb" that is the + * current context, also takes doubly-parenthesized print-style + * argument. */ +#define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0) + +/* lock offsets */ +#define GLOBAL_LOCK 0 +#define ACTIVE_LOCK 4 + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +/* free memory if the pointer is valid and zero the pointer */ +#ifndef SAFE_FREE +#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0) +#endif + +#define BUCKET(hash) ((hash) % tdb->header.hash_size) +TDB_DATA tdb_null; + +/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ +static TDB_CONTEXT *tdbs = NULL; + +static int tdb_munmap(TDB_CONTEXT *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return 0; + +#ifdef HAVE_MMAP + if (tdb->map_ptr) { + int ret = munmap(tdb->map_ptr, tdb->map_size); + if (ret != 0) + return ret; + } +#endif + tdb->map_ptr = NULL; + return 0; +} + +static void tdb_mmap(TDB_CONTEXT *tdb) +{ + if (tdb->flags & TDB_INTERNAL) + return; + +#ifdef HAVE_MMAP + if (!(tdb->flags & TDB_NOMMAP)) { + tdb->map_ptr = mmap(NULL, tdb->map_size, + PROT_READ|(tdb->read_only? 0:PROT_WRITE), + MAP_SHARED|MAP_FILE, tdb->fd, 0); + + /* + * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! + */ + + if (tdb->map_ptr == MAP_FAILED) { + tdb->map_ptr = NULL; + TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n", + tdb->map_size, strerror(errno))); + } + } else { + tdb->map_ptr = NULL; + } +#else + tdb->map_ptr = NULL; +#endif +} + +/* Endian conversion: we only ever deal with 4 byte quantities */ +static void *convert(void *buf, u32 size) +{ + u32 i, *p = buf; + for (i = 0; i < size / 4; i++) + p[i] = TDB_BYTEREV(p[i]); + return buf; +} +#define DOCONV() (tdb->flags & TDB_CONVERT) +#define CONVERT(x) (DOCONV() ? convert(&x, sizeof(x)) : &x) + +/* the body of the database is made of one list_struct for the free space + plus a separate data list for each hash value */ +struct list_struct { + tdb_off next; /* offset of the next record in the list */ + tdb_len rec_len; /* total byte length of record */ + tdb_len key_len; /* byte length of key */ + tdb_len data_len; /* byte length of data */ + u32 full_hash; /* the full 32 bit hash of the key */ + u32 magic; /* try to catch errors */ + /* the following union is implied: + union { + char record[rec_len]; + struct { + char key[key_len]; + char data[data_len]; + } + u32 totalsize; (tailer) + } + */ +}; + +/*************************************************************** + Allow a caller to set a "alarm" flag that tdb can check to abort + a blocking lock on SIGALRM. +***************************************************************/ + +static sig_atomic_t *palarm_fired; + +void tdb_set_lock_alarm(sig_atomic_t *palarm) +{ + palarm_fired = palarm; +} + +/* a byte range locking function - return 0 on success + this functions locks/unlocks 1 byte at the specified offset. + + On error, errno is also set so that errors are passed back properly + through tdb_open(). */ +static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, + int rw_type, int lck_type, int probe) +{ + struct flock fl; + int ret; + + if (tdb->flags & TDB_NOLOCK) + return 0; + if ((rw_type == F_WRLCK) && (tdb->read_only)) { + errno = EACCES; + return -1; + } + + fl.l_type = rw_type; + fl.l_whence = SEEK_SET; + fl.l_start = offset; + fl.l_len = 1; + fl.l_pid = 0; + + do { + ret = fcntl(tdb->fd,lck_type,&fl); + if (ret == -1 && errno == EINTR && palarm_fired && *palarm_fired) + break; + } while (ret == -1 && errno == EINTR); + + if (ret == -1) { + if (!probe && lck_type != F_SETLK) { + /* Ensure error code is set for log fun to examine. */ + if (errno == EINTR && palarm_fired && *palarm_fired) + tdb->ecode = TDB_ERR_LOCK_TIMEOUT; + else + tdb->ecode = TDB_ERR_LOCK; + TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n", + tdb->fd, offset, rw_type, lck_type)); + } + /* Was it an alarm timeout ? */ + if (errno == EINTR && palarm_fired && *palarm_fired) + return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1); + /* Otherwise - generic lock error. */ + /* errno set by fcntl */ + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + } + return 0; +} + +/* lock a list in the database. list -1 is the alloc list */ +static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) +{ + if (list < -1 || list >= (int)tdb->header.hash_size) { + TDB_LOG((tdb, 0,"tdb_lock: invalid list %d for ltype=%d\n", + list, ltype)); + return -1; + } + if (tdb->flags & TDB_NOLOCK) + return 0; + + /* Since fcntl locks don't nest, we do a lock for the first one, + and simply bump the count for future ones */ + if (tdb->locked[list+1].count == 0) { + if (!tdb->read_only && tdb->header.rwlocks) { + if (tdb_spinlock(tdb, list, ltype)) { + TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list ltype=%d\n", + list, ltype)); + return -1; + } + } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 0)) { + TDB_LOG((tdb, 0,"tdb_lock failed on list %d ltype=%d (%s)\n", + list, ltype, strerror(errno))); + return -1; + } + tdb->locked[list+1].ltype = ltype; + } + tdb->locked[list+1].count++; + return 0; +} + +/* unlock the database: returns void because it's too late for errors. */ + /* changed to return int it may be interesting to know there + has been an error --simo */ +static int tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) +{ + int ret = -1; + + if (tdb->flags & TDB_NOLOCK) + return 0; + + /* Sanity checks */ + if (list < -1 || list >= (int)tdb->header.hash_size) { + TDB_LOG((tdb, 0, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); + return ret; + } + + if (tdb->locked[list+1].count==0) { + TDB_LOG((tdb, 0, "tdb_unlock: count is 0\n")); + return ret; + } + + if (tdb->locked[list+1].count == 1) { + /* Down to last nested lock: unlock underneath */ + if (!tdb->read_only && tdb->header.rwlocks) { + ret = tdb_spinunlock(tdb, list, ltype); + } else { + ret = tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0); + } + } else { + ret = 0; + } + tdb->locked[list+1].count--; + + if (ret) + TDB_LOG((tdb, 0,"tdb_unlock: An error occurred unlocking!\n")); + return ret; +} + +/* This is based on the hash algorithm from gdbm */ +static u32 tdb_hash(TDB_DATA *key) +{ + u32 value; /* Used to compute the hash value. */ + u32 i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) + value = (value + (key->dptr[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + +/* check for an out of bounds access - if it is out of bounds then + see if the database has been expanded by someone else and expand + if necessary + note that "len" is the minimum length needed for the db +*/ +static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe) +{ + struct stat st; + if (len <= tdb->map_size) + return 0; + if (tdb->flags & TDB_INTERNAL) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_oob len %d beyond internal malloc size %d\n", + (int)len, (int)tdb->map_size)); + } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + + if (fstat(tdb->fd, &st) == -1) + return TDB_ERRCODE(TDB_ERR_IO, -1); + + if (st.st_size < (size_t)len) { + if (!probe) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n", + (int)len, (int)st.st_size)); + } + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + + /* Unmap, update size, remap */ + if (tdb_munmap(tdb) == -1) + return TDB_ERRCODE(TDB_ERR_IO, -1); + tdb->map_size = st.st_size; + tdb_mmap(tdb); + return 0; +} + +/* write a lump of data at a specified offset */ +static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len) +{ + if (tdb_oob(tdb, off + len, 0) != 0) + return -1; + + if (tdb->map_ptr) + memcpy(off + (char *)tdb->map_ptr, buf, len); +#ifdef HAVE_PWRITE + else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) { +#else + else if (lseek(tdb->fd, off, SEEK_SET) != off + || write(tdb->fd, buf, len) != (ssize_t)len) { +#endif + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n", + off, len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + return 0; +} + +/* read a lump of data at a specified offset, maybe convert */ +static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv) +{ + if (tdb_oob(tdb, off + len, 0) != 0) + return -1; + + if (tdb->map_ptr) + memcpy(buf, off + (char *)tdb->map_ptr, len); +#ifdef HAVE_PREAD + else if (pread(tdb->fd, buf, len, off) != (ssize_t)len) { +#else + else if (lseek(tdb->fd, off, SEEK_SET) != off + || read(tdb->fd, buf, len) != (ssize_t)len) { +#endif + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_IO; + TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n", + off, len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_IO, -1); + } + if (cv) + convert(buf, len); + return 0; +} + +/* read a lump of data, allocating the space for it */ +static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len) +{ + char *buf; + + if (!(buf = malloc(len))) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_OOM; + TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n", + len, strerror(errno))); + return TDB_ERRCODE(TDB_ERR_OOM, buf); + } + if (tdb_read(tdb, offset, buf, len, 0) == -1) { + SAFE_FREE(buf); + return NULL; + } + return buf; +} + +/* read/write a tdb_off */ +static int ofs_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) +{ + return tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); +} +static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) +{ + tdb_off off = *d; + return tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); +} + +/* read/write a record */ +static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) +{ + if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + if (TDB_BAD_MAGIC(rec)) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + return tdb_oob(tdb, rec->next+sizeof(*rec), 0); +} +static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) +{ + struct list_struct r = *rec; + return tdb_write(tdb, offset, CONVERT(r), sizeof(r)); +} + +/* read a freelist record and check for simple errors */ +static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) +{ + if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) + return -1; + + if (rec->magic == TDB_MAGIC) { + /* this happens when a app is showdown while deleting a record - we should + not completely fail when this happens */ + TDB_LOG((tdb, 0,"rec_free_read non-free magic at offset=%d - fixing\n", + rec->magic, off)); + rec->magic = TDB_FREE_MAGIC; + if (tdb_write(tdb, off, rec, sizeof(*rec)) == -1) + return -1; + } + + if (rec->magic != TDB_FREE_MAGIC) { + /* Ensure ecode is set for log fn. */ + tdb->ecode = TDB_ERR_CORRUPT; + TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n", + rec->magic, off)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) + return -1; + return 0; +} + +/* update a record tailer (must hold allocation lock) */ +static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset, + const struct list_struct *rec) +{ + tdb_off totalsize; + + /* Offset of tailer from record header */ + totalsize = sizeof(*rec) + rec->rec_len; + return ofs_write(tdb, offset + totalsize - sizeof(tdb_off), + &totalsize); +} + +static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset) +{ + struct list_struct rec; + tdb_off tailer_ofs, tailer; + + if (tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { + printf("ERROR: failed to read record at %u\n", offset); + return 0; + } + + printf(" rec: offset=%u next=%d rec_len=%d key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", + offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); + + tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off); + if (ofs_read(tdb, tailer_ofs, &tailer) == -1) { + printf("ERROR: failed to read tailer at %u\n", tailer_ofs); + return rec.next; + } + + if (tailer != rec.rec_len + sizeof(rec)) { + printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", + (unsigned)tailer, (unsigned)(rec.rec_len + sizeof(rec))); + } + return rec.next; +} + +static int tdb_dump_chain(TDB_CONTEXT *tdb, int i) +{ + tdb_off rec_ptr, top; + + top = TDB_HASH_TOP(i); + + if (tdb_lock(tdb, i, F_WRLCK) != 0) + return -1; + + if (ofs_read(tdb, top, &rec_ptr) == -1) + return tdb_unlock(tdb, i, F_WRLCK); + + if (rec_ptr) + printf("hash=%d\n", i); + + while (rec_ptr) { + rec_ptr = tdb_dump_record(tdb, rec_ptr); + } + + return tdb_unlock(tdb, i, F_WRLCK); +} + +void tdb_dump_all(TDB_CONTEXT *tdb) +{ + int i; + for (i=0;iheader.hash_size;i++) { + tdb_dump_chain(tdb, i); + } + printf("freelist:\n"); + tdb_dump_chain(tdb, -1); +} + +int tdb_printfreelist(TDB_CONTEXT *tdb) +{ + int ret; + long total_free = 0; + tdb_off offset, rec_ptr; + struct list_struct rec; + + if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) + return ret; + + offset = FREELIST_TOP; + + /* read in the freelist top */ + if (ofs_read(tdb, offset, &rec_ptr) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + } + + printf("freelist top=[0x%08x]\n", rec_ptr ); + while (rec_ptr) { + if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + if (rec.magic != TDB_FREE_MAGIC) { + printf("bad magic 0x%08x in free list\n", rec.magic); + tdb_unlock(tdb, -1, F_WRLCK); + return -1; + } + + printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)]\n", rec.next, rec.rec_len, rec.rec_len ); + total_free += rec.rec_len; + + /* move to the next record */ + rec_ptr = rec.next; + } + printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, + (int)total_free); + + return tdb_unlock(tdb, -1, F_WRLCK); +} + +/* Remove an element from the freelist. Must have alloc lock. */ +static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) +{ + tdb_off last_ptr, i; + + /* read in the freelist top */ + last_ptr = FREELIST_TOP; + while (ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { + if (i == off) { + /* We've found it! */ + return ofs_write(tdb, last_ptr, &next); + } + /* Follow chain (next offset is at start of record) */ + last_ptr = i; + } + TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off)); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); +} + +/* Add an element into the freelist. Merge adjacent records if + neccessary. */ +static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) +{ + tdb_off right, left; + + /* Allocation and tailer lock */ + if (tdb_lock(tdb, -1, F_WRLCK) != 0) + return -1; + + /* set an initial tailer, so if we fail we don't leave a bogus record */ + if (update_tailer(tdb, offset, rec) != 0) { + TDB_LOG((tdb, 0, "tdb_free: upfate_tailer failed!\n")); + goto fail; + } + + /* Look right first (I'm an Australian, dammit) */ + right = offset + sizeof(*rec) + rec->rec_len; + if (right + sizeof(*rec) <= tdb->map_size) { + struct list_struct r; + + if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { + TDB_LOG((tdb, 0, "tdb_free: right read failed at %u\n", right)); + goto left; + } + + /* If it's free, expand to include it. */ + if (r.magic == TDB_FREE_MAGIC) { + if (remove_from_freelist(tdb, right, r.next) == -1) { + TDB_LOG((tdb, 0, "tdb_free: right free failed at %u\n", right)); + goto left; + } + rec->rec_len += sizeof(r) + r.rec_len; + } + } + +left: + /* Look left */ + left = offset - sizeof(tdb_off); + if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) { + struct list_struct l; + tdb_off leftsize; + + /* Read in tailer and jump back to header */ + if (ofs_read(tdb, left, &leftsize) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left)); + goto update; + } + left = offset - leftsize; + + /* Now read in record */ + if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); + goto update; + } + + /* If it's free, expand to include it. */ + if (l.magic == TDB_FREE_MAGIC) { + if (remove_from_freelist(tdb, left, l.next) == -1) { + TDB_LOG((tdb, 0, "tdb_free: left free failed at %u\n", left)); + goto update; + } else { + offset = left; + rec->rec_len += leftsize; + } + } + } + +update: + if (update_tailer(tdb, offset, rec) == -1) { + TDB_LOG((tdb, 0, "tdb_free: update_tailer failed at %u\n", offset)); + goto fail; + } + + /* Now, prepend to free list */ + rec->magic = TDB_FREE_MAGIC; + + if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || + rec_write(tdb, offset, rec) == -1 || + ofs_write(tdb, FREELIST_TOP, &offset) == -1) { + TDB_LOG((tdb, 0, "tdb_free record write failed at offset=%d\n", offset)); + goto fail; + } + + /* And we're done. */ + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + + +/* expand a file. we prefer to use ftruncate, as that is what posix + says to use for mmap expansion */ +static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition) +{ + char buf[1024]; +#if HAVE_FTRUNCATE_EXTEND + if (ftruncate(tdb->fd, size+addition) != 0) { + TDB_LOG((tdb, 0, "expand_file ftruncate to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } +#else + char b = 0; + +#ifdef HAVE_PWRITE + if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) { +#else + if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 || + write(tdb->fd, &b, 1) != 1) { +#endif + TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n", + size+addition, strerror(errno))); + return -1; + } +#endif + + /* now fill the file with something. This ensures that the file isn't sparse, which would be + very bad if we ran out of disk. This must be done with write, not via mmap */ + memset(buf, 0x42, sizeof(buf)); + while (addition) { + int n = addition>sizeof(buf)?sizeof(buf):addition; +#ifdef HAVE_PWRITE + int ret = pwrite(tdb->fd, buf, n, size); +#else + int ret; + if (lseek(tdb->fd, size, SEEK_SET) != size) + return -1; + ret = write(tdb->fd, buf, n); +#endif + if (ret != n) { + TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n", + n, strerror(errno))); + return -1; + } + addition -= n; + size += n; + } + return 0; +} + + +/* expand the database at least size bytes by expanding the underlying + file and doing the mmap again if necessary */ +static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) +{ + struct list_struct rec; + tdb_off offset; + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) { + TDB_LOG((tdb, 0, "lock failed in tdb_expand\n")); + return -1; + } + + /* must know about any previous expansions by another process */ + tdb_oob(tdb, tdb->map_size + 1, 1); + + /* always make room for at least 10 more records, and round + the database up to a multiple of TDB_PAGE_SIZE */ + size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size; + + if (!(tdb->flags & TDB_INTERNAL)) + tdb_munmap(tdb); + + /* + * We must ensure the file is unmapped before doing this + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ + + /* expand the file itself */ + if (!(tdb->flags & TDB_INTERNAL)) { + if (expand_file(tdb, tdb->map_size, size) != 0) + goto fail; + } + + tdb->map_size += size; + + if (tdb->flags & TDB_INTERNAL) + tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); + else { + /* + * We must ensure the file is remapped before adding the space + * to ensure consistency with systems like OpenBSD where + * writes and mmaps are not consistent. + */ + + /* We're ok if the mmap fails as we'll fallback to read/write */ + tdb_mmap(tdb); + } + + /* form a new freelist record */ + memset(&rec,'\0',sizeof(rec)); + rec.rec_len = size - sizeof(rec); + + /* link it into the free list */ + offset = tdb->map_size - size; + if (tdb_free(tdb, offset, &rec) == -1) + goto fail; + + tdb_unlock(tdb, -1, F_WRLCK); + return 0; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return -1; +} + +/* allocate some space from the free list. The offset returned points + to a unconnected list_struct within the database with room for at + least length bytes of total data + + 0 is returned if the space could not be allocated + */ +static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, + struct list_struct *rec) +{ + tdb_off rec_ptr, last_ptr, newrec_ptr; + struct list_struct newrec; + + if (tdb_lock(tdb, -1, F_WRLCK) == -1) + return 0; + + /* Extra bytes required for tailer */ + length += sizeof(tdb_off); + + again: + last_ptr = FREELIST_TOP; + + /* read in the freelist top */ + if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) + goto fail; + + /* keep looking until we find a freelist record big enough */ + while (rec_ptr) { + if (rec_free_read(tdb, rec_ptr, rec) == -1) + goto fail; + + if (rec->rec_len >= length) { + /* found it - now possibly split it up */ + if (rec->rec_len > length + MIN_REC_SIZE) { + /* Length of left piece */ + length = TDB_ALIGN(length, TDB_ALIGNMENT); + + /* Right piece to go on free list */ + newrec.rec_len = rec->rec_len + - (sizeof(*rec) + length); + newrec_ptr = rec_ptr + sizeof(*rec) + length; + + /* And left record is shortened */ + rec->rec_len = length; + } else + newrec_ptr = 0; + + /* Remove allocated record from the free list */ + if (ofs_write(tdb, last_ptr, &rec->next) == -1) + goto fail; + + /* Update header: do this before we drop alloc + lock, otherwise tdb_free() might try to + merge with us, thinking we're free. + (Thanks Jeremy Allison). */ + rec->magic = TDB_MAGIC; + if (rec_write(tdb, rec_ptr, rec) == -1) + goto fail; + + /* Did we create new block? */ + if (newrec_ptr) { + /* Update allocated record tailer (we + shortened it). */ + if (update_tailer(tdb, rec_ptr, rec) == -1) + goto fail; + + /* Free new record */ + if (tdb_free(tdb, newrec_ptr, &newrec) == -1) + goto fail; + } + + /* all done - return the new record offset */ + tdb_unlock(tdb, -1, F_WRLCK); + return rec_ptr; + } + /* move to the next record */ + last_ptr = rec_ptr; + rec_ptr = rec->next; + } + /* we didn't find enough space. See if we can expand the + database and if we can then try again */ + if (tdb_expand(tdb, length + sizeof(*rec)) == 0) + goto again; + fail: + tdb_unlock(tdb, -1, F_WRLCK); + return 0; +} + +/* initialise a new database with a specified hash size */ +static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) +{ + struct tdb_header *newdb; + int size, ret = -1; + + /* We make it up in memory, then write it out if not internal */ + size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off); + if (!(newdb = calloc(size, 1))) + return TDB_ERRCODE(TDB_ERR_OOM, -1); + + /* Fill in the header */ + newdb->version = TDB_VERSION; + newdb->hash_size = hash_size; +#ifdef USE_SPINLOCKS + newdb->rwlocks = size; +#endif + if (tdb->flags & TDB_INTERNAL) { + tdb->map_size = size; + tdb->map_ptr = (char *)newdb; + memcpy(&tdb->header, newdb, sizeof(tdb->header)); + /* Convert the `ondisk' version if asked. */ + CONVERT(*newdb); + return 0; + } + if (lseek(tdb->fd, 0, SEEK_SET) == -1) + goto fail; + + if (ftruncate(tdb->fd, 0) == -1) + goto fail; + + /* This creates an endian-converted header, as if read from disk */ + CONVERT(*newdb); + memcpy(&tdb->header, newdb, sizeof(tdb->header)); + /* Don't endian-convert the magic food! */ + memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); + if (write(tdb->fd, newdb, size) != size) + ret = -1; + else + ret = tdb_create_rwlocks(tdb->fd, hash_size); + + fail: + SAFE_FREE(newdb); + return ret; +} + +/* Returns 0 on fail. On success, return offset of record, and fills + in rec */ +static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, + struct list_struct *r) +{ + tdb_off rec_ptr; + + /* read in the hash top */ + if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) + return 0; + + /* keep looking until we find the right record */ + while (rec_ptr) { + if (rec_read(tdb, rec_ptr, r) == -1) + return 0; + + if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) { + char *k; + /* a very likely hit - read the key */ + k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r), + r->key_len); + if (!k) + return 0; + + if (memcmp(key.dptr, k, key.dsize) == 0) { + SAFE_FREE(k); + return rec_ptr; + } + SAFE_FREE(k); + } + rec_ptr = r->next; + } + return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); +} + +/* If they do lockkeys, check that this hash is one they locked */ +static int tdb_keylocked(TDB_CONTEXT *tdb, u32 hash) +{ + u32 i; + if (!tdb->lockedkeys) + return 1; + for (i = 0; i < tdb->lockedkeys[0]; i++) + if (tdb->lockedkeys[i+1] == hash) + return 1; + return TDB_ERRCODE(TDB_ERR_NOLOCK, 0); +} + +/* As tdb_find, but if you succeed, keep the lock */ +static tdb_off tdb_find_lock(TDB_CONTEXT *tdb, TDB_DATA key, int locktype, + struct list_struct *rec) +{ + u32 hash, rec_ptr; + + hash = tdb_hash(&key); + if (!tdb_keylocked(tdb, hash)) + return 0; + if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) + return 0; + if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) + tdb_unlock(tdb, BUCKET(hash), locktype); + return rec_ptr; +} + +enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb) +{ + return tdb->ecode; +} + +static struct tdb_errname { + enum TDB_ERROR ecode; const char *estring; +} emap[] = { {TDB_SUCCESS, "Success"}, + {TDB_ERR_CORRUPT, "Corrupt database"}, + {TDB_ERR_IO, "IO Error"}, + {TDB_ERR_LOCK, "Locking error"}, + {TDB_ERR_OOM, "Out of memory"}, + {TDB_ERR_EXISTS, "Record exists"}, + {TDB_ERR_NOLOCK, "Lock exists on other keys"}, + {TDB_ERR_NOEXIST, "Record does not exist"} }; + +/* Error string for the last tdb error */ +const char *tdb_errorstr(TDB_CONTEXT *tdb) +{ + u32 i; + for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) + if (tdb->ecode == emap[i].ecode) + return emap[i].estring; + return "Invalid error code"; +} + +/* update an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1. +*/ + +static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf) +{ + struct list_struct rec; + tdb_off rec_ptr; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec))) + return -1; + + /* must be long enough key, data and tailer */ + if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) { + tdb->ecode = TDB_SUCCESS; /* Not really an error */ + return -1; + } + + if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, + dbuf.dptr, dbuf.dsize) == -1) + return -1; + + if (dbuf.dsize != rec.data_len) { + /* update size */ + rec.data_len = dbuf.dsize; + return rec_write(tdb, rec_ptr, &rec); + } + + return 0; +} + +/* find an entry in the database given a key */ +/* If an entry doesn't exist tdb_err will be set to + * TDB_ERR_NOEXIST. If a key has no data attached + * tdb_err will not be set. Both will return a + * zero pptr and zero dsize. + */ + +TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) +{ + tdb_off rec_ptr; + struct list_struct rec; + TDB_DATA ret; + + /* find which hash bucket it is in */ + if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec))) + return tdb_null; + + if (rec.data_len) + ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, + rec.data_len); + else + ret.dptr = NULL; + ret.dsize = rec.data_len; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return ret; +} + +/* check if an entry in the database exists + + note that 1 is returned if the key is found and 0 is returned if not found + this doesn't match the conventions in the rest of this module, but is + compatible with gdbm +*/ +int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) +{ + struct list_struct rec; + + if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0) + return 0; + tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); + return 1; +} + +/* record lock stops delete underneath */ +static int lock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0; +} +/* + Write locks override our own fcntl readlocks, so check it here. + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ + +static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + struct tdb_traverse_lock *i; + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + return -1; + return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1); +} + +/* + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ + +static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0); +} +/* fcntl locks don't stack: avoid unlocking someone else's */ +static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) +{ + struct tdb_traverse_lock *i; + u32 count = 0; + + if (off == 0) + return 0; + for (i = &tdb->travlocks; i; i = i->next) + if (i->off == off) + count++; + return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0); +} + +/* actually delete an entry in the database given the offset */ +static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec) +{ + tdb_off last_ptr, i; + struct list_struct lastrec; + + if (tdb->read_only) return -1; + + if (write_lock_record(tdb, rec_ptr) == -1) { + /* Someone traversing here: mark it as dead */ + rec->magic = TDB_DEAD_MAGIC; + return rec_write(tdb, rec_ptr, rec); + } + if (write_unlock_record(tdb, rec_ptr) != 0) + return -1; + + /* find previous record in hash chain */ + if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) + return -1; + for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) + if (rec_read(tdb, i, &lastrec) == -1) + return -1; + + /* unlink it: next ptr is at start of record. */ + if (last_ptr == 0) + last_ptr = TDB_HASH_TOP(rec->full_hash); + if (ofs_write(tdb, last_ptr, &rec->next) == -1) + return -1; + + /* recover the space */ + if (tdb_free(tdb, rec_ptr, rec) == -1) + return -1; + return 0; +} + +/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ +static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, + struct list_struct *rec) +{ + int want_next = (tlock->off != 0); + + /* No traversal allows if you've called tdb_lockkeys() */ + if (tdb->lockedkeys) + return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); + + /* Lock each chain from the start one. */ + for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { + if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) + return -1; + + /* No previous record? Start at top of chain. */ + if (!tlock->off) { + if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), + &tlock->off) == -1) + goto fail; + } else { + /* Otherwise unlock the previous record. */ + if (unlock_record(tdb, tlock->off) != 0) + goto fail; + } + + if (want_next) { + /* We have offset of old record: grab next */ + if (rec_read(tdb, tlock->off, rec) == -1) + goto fail; + tlock->off = rec->next; + } + + /* Iterate through chain */ + while( tlock->off) { + tdb_off current; + if (rec_read(tdb, tlock->off, rec) == -1) + goto fail; + if (!TDB_DEAD(rec)) { + /* Woohoo: we found one! */ + if (lock_record(tdb, tlock->off) != 0) + goto fail; + return tlock->off; + } + /* Try to clean dead ones from old traverses */ + current = tlock->off; + tlock->off = rec->next; + if (!tdb->read_only && + do_delete(tdb, current, rec) != 0) + goto fail; + } + tdb_unlock(tdb, tlock->hash, F_WRLCK); + want_next = 0; + } + /* We finished iteration without finding anything */ + return TDB_ERRCODE(TDB_SUCCESS, 0); + + fail: + tlock->off = 0; + if (tdb_unlock(tdb, tlock->hash, F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_next_lock: On error unlock failed!\n")); + return -1; +} + +/* traverse the entire database - calling fn(tdb, key, data) on each element. + return -1 on error or the record count traversed + if fn is NULL then it is not called + a non-zero return value from fn() indicates that the traversal should stop + */ +int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state) +{ + TDB_DATA key, dbuf; + struct list_struct rec; + struct tdb_traverse_lock tl = { NULL, 0, 0 }; + int ret, count = 0; + + /* This was in the initializaton, above, but the IRIX compiler + * did not like it. crh + */ + tl.next = tdb->travlocks.next; + + /* fcntl locks don't stack: beware traverse inside traverse */ + tdb->travlocks.next = &tl; + + /* tdb_next_lock places locks on the record returned, and its chain */ + while ((ret = tdb_next_lock(tdb, &tl, &rec)) > 0) { + count++; + /* now read the full record */ + key.dptr = tdb_alloc_read(tdb, tl.off + sizeof(rec), + rec.key_len + rec.data_len); + if (!key.dptr) { + ret = -1; + if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) + goto out; + if (unlock_record(tdb, tl.off) != 0) + TDB_LOG((tdb, 0, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); + goto out; + } + key.dsize = rec.key_len; + dbuf.dptr = key.dptr + rec.key_len; + dbuf.dsize = rec.data_len; + + /* Drop chain lock, call out */ + if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) { + ret = -1; + goto out; + } + if (fn && fn(tdb, key, dbuf, state)) { + /* They want us to terminate traversal */ + ret = count; + if (unlock_record(tdb, tl.off) != 0) { + TDB_LOG((tdb, 0, "tdb_traverse: unlock_record failed!\n"));; + ret = -1; + } + tdb->travlocks.next = tl.next; + SAFE_FREE(key.dptr); + return count; + } + SAFE_FREE(key.dptr); + } +out: + tdb->travlocks.next = tl.next; + if (ret < 0) + return -1; + else + return count; +} + +/* find the first entry in the database and return its key */ +TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) +{ + TDB_DATA key; + struct list_struct rec; + + /* release any old lock */ + if (unlock_record(tdb, tdb->travlocks.off) != 0) + return tdb_null; + tdb->travlocks.off = tdb->travlocks.hash = 0; + + if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) + return tdb_null; + /* now read the key */ + key.dsize = rec.key_len; + key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); + if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_firstkey: error occurred while tdb_unlocking!\n")); + return key; +} + +/* find the next entry in the database, returning its key */ +TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) +{ + u32 oldhash; + TDB_DATA key = tdb_null; + struct list_struct rec; + char *k = NULL; + + /* Is locked key the old key? If so, traverse will be reliable. */ + if (tdb->travlocks.off) { + if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK)) + return tdb_null; + if (rec_read(tdb, tdb->travlocks.off, &rec) == -1 + || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), + rec.key_len)) + || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { + /* No, it wasn't: unlock it and start from scratch */ + if (unlock_record(tdb, tdb->travlocks.off) != 0) + return tdb_null; + if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) + return tdb_null; + tdb->travlocks.off = 0; + } + + SAFE_FREE(k); + } + + if (!tdb->travlocks.off) { + /* No previous element: do normal find, and lock record */ + tdb->travlocks.off = tdb_find_lock(tdb, oldkey, F_WRLCK, &rec); + if (!tdb->travlocks.off) + return tdb_null; + tdb->travlocks.hash = BUCKET(rec.full_hash); + if (lock_record(tdb, tdb->travlocks.off) != 0) { + TDB_LOG((tdb, 0, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); + return tdb_null; + } + } + oldhash = tdb->travlocks.hash; + + /* Grab next record: locks chain and returned record, + unlocks old record */ + if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { + key.dsize = rec.key_len; + key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), + key.dsize); + /* Unlock the chain of this new record */ + if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + } + /* Unlock the chain of old record */ + if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); + return key; +} + +/* delete an entry in the database given a key */ +int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) +{ + tdb_off rec_ptr; + struct list_struct rec; + int ret; + + if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec))) + return -1; + ret = do_delete(tdb, rec_ptr, &rec); + if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) + TDB_LOG((tdb, 0, "tdb_delete: WARNING tdb_unlock failed!\n")); + return ret; +} + +/* store an element in the database, replacing any existing element + with the same key + + return 0 on success, -1 on failure +*/ +int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) +{ + struct list_struct rec; + u32 hash; + tdb_off rec_ptr; + char *p = NULL; + int ret = 0; + + /* find which hash bucket it is in */ + hash = tdb_hash(&key); + if (!tdb_keylocked(tdb, hash)) + return -1; + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + /* check for it existing, on insert. */ + if (flag == TDB_INSERT) { + if (tdb_exists(tdb, key)) { + tdb->ecode = TDB_ERR_EXISTS; + goto fail; + } + } else { + /* first try in-place update, on modify or replace. */ + if (tdb_update(tdb, key, dbuf) == 0) + goto out; + if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST) + goto fail; + } + /* reset the error code potentially set by the tdb_update() */ + tdb->ecode = TDB_SUCCESS; + + /* delete any existing record - if it doesn't exist we don't + care. Doing this first reduces fragmentation, and avoids + coalescing with `allocated' block before it's updated. */ + if (flag != TDB_INSERT) + tdb_delete(tdb, key); + + /* Copy key+value *before* allocating free space in case malloc + fails and we are left with a dead spot in the tdb. */ + + if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + + memcpy(p, key.dptr, key.dsize); + if (dbuf.dsize) + memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); + + /* now we're into insert / modify / replace of a record which + * we know could not be optimised by an in-place store (for + * various reasons). */ + if (!(rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec))) + goto fail; + + /* Read hash top into next ptr */ + if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) + goto fail; + + rec.key_len = key.dsize; + rec.data_len = dbuf.dsize; + rec.full_hash = hash; + rec.magic = TDB_MAGIC; + + /* write out and point the top of the hash chain at it */ + if (rec_write(tdb, rec_ptr, &rec) == -1 + || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 + || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { + /* Need to tdb_unallocate() here */ + goto fail; + } + out: + SAFE_FREE(p); + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return ret; +fail: + ret = -1; + goto out; +} + +/* Attempt to append data to an entry in place - this only works if the new data size + is <= the old data size and the key exists. + on failure return -1. Record must be locked before calling. +*/ +static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) +{ + struct list_struct rec; + tdb_off rec_ptr; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec))) + return -1; + + /* Append of 0 is always ok. */ + if (new_dbuf.dsize == 0) + return 0; + + /* must be long enough for key, old data + new data and tailer */ + if (rec.rec_len < key.dsize + rec.data_len + new_dbuf.dsize + sizeof(tdb_off)) { + /* No room. */ + tdb->ecode = TDB_SUCCESS; /* Not really an error */ + return -1; + } + + if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len + rec.data_len, + new_dbuf.dptr, new_dbuf.dsize) == -1) + return -1; + + /* update size */ + rec.data_len += new_dbuf.dsize; + return rec_write(tdb, rec_ptr, &rec); +} + +/* Append to an entry. Create if not exist. */ + +int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) +{ + struct list_struct rec; + u32 hash; + tdb_off rec_ptr; + char *p = NULL; + int ret = 0; + size_t new_data_size = 0; + + /* find which hash bucket it is in */ + hash = tdb_hash(&key); + if (!tdb_keylocked(tdb, hash)) + return -1; + if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) + return -1; + + /* first try in-place. */ + if (tdb_append_inplace(tdb, key, new_dbuf) == 0) + goto out; + + /* reset the error code potentially set by the tdb_append_inplace() */ + tdb->ecode = TDB_SUCCESS; + + /* find entry */ + if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { + if (tdb->ecode != TDB_ERR_NOEXIST) + goto fail; + + /* Not found - create. */ + + ret = tdb_store(tdb, key, new_dbuf, TDB_INSERT); + goto out; + } + + new_data_size = rec.data_len + new_dbuf.dsize; + + /* Copy key+old_value+value *before* allocating free space in case malloc + fails and we are left with a dead spot in the tdb. */ + + if (!(p = (char *)malloc(key.dsize + new_data_size))) { + tdb->ecode = TDB_ERR_OOM; + goto fail; + } + + /* Copy the key in place. */ + memcpy(p, key.dptr, key.dsize); + + /* Now read the old data into place. */ + if (rec.data_len && + tdb_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, p + key.dsize, rec.data_len, 0) == -1) + goto fail; + + /* Finally append the new data. */ + if (new_dbuf.dsize) + memcpy(p+key.dsize+rec.data_len, new_dbuf.dptr, new_dbuf.dsize); + + /* delete any existing record - if it doesn't exist we don't + care. Doing this first reduces fragmentation, and avoids + coalescing with `allocated' block before it's updated. */ + + tdb_delete(tdb, key); + + if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec))) + goto fail; + + /* Read hash top into next ptr */ + if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) + goto fail; + + rec.key_len = key.dsize; + rec.data_len = new_data_size; + rec.full_hash = hash; + rec.magic = TDB_MAGIC; + + /* write out and point the top of the hash chain at it */ + if (rec_write(tdb, rec_ptr, &rec) == -1 + || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+new_data_size)==-1 + || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { + /* Need to tdb_unallocate() here */ + goto fail; + } + + out: + SAFE_FREE(p); + tdb_unlock(tdb, BUCKET(hash), F_WRLCK); + return ret; + +fail: + ret = -1; + goto out; +} + +static int tdb_already_open(dev_t device, + ino_t ino) +{ + TDB_CONTEXT *i; + + for (i = tdbs; i; i = i->next) { + if (i->device == device && i->inode == ino) { + return 1; + } + } + + return 0; +} + +/* open the database, creating it if necessary + + The open_flags and mode are passed straight to the open call on the + database file. A flags value of O_WRONLY is invalid. The hash size + is advisory, use zero for a default value. + + Return is NULL on error, in which case errno is also set. Don't + try to call tdb_error or tdb_errname, just do strerror(errno). + + @param name may be NULL for internal databases. */ +TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL); +} + + +TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + tdb_log_func log_fn) +{ + TDB_CONTEXT *tdb; + struct stat st; + int rev = 0, locked; + unsigned char *vp; + u32 vertest; + + if (!(tdb = calloc(1, sizeof *tdb))) { + /* Can't log this */ + errno = ENOMEM; + goto fail; + } + tdb->fd = -1; + tdb->name = NULL; + tdb->map_ptr = NULL; + tdb->lockedkeys = NULL; + tdb->flags = tdb_flags; + tdb->open_flags = open_flags; + tdb->log_fn = log_fn; + + if ((open_flags & O_ACCMODE) == O_WRONLY) { + TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n", + name)); + errno = EINVAL; + goto fail; + } + + if (hash_size == 0) + hash_size = DEFAULT_HASH_SIZE; + if ((open_flags & O_ACCMODE) == O_RDONLY) { + tdb->read_only = 1; + /* read only databases don't do locking or clear if first */ + tdb->flags |= TDB_NOLOCK; + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + } + + /* internal databases don't mmap or lock, and start off cleared */ + if (tdb->flags & TDB_INTERNAL) { + tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); + tdb->flags &= ~TDB_CLEAR_IF_FIRST; + if (tdb_new_database(tdb, hash_size) != 0) { + TDB_LOG((tdb, 0, "tdb_open_ex: tdb_new_database failed!")); + goto fail; + } + goto internal; + } + + if ((tdb->fd = open(name, open_flags, mode)) == -1) { + TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by open(2) */ + } + + /* ensure there is only one process initialising at once */ + if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) { + TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by tdb_brlock */ + } + + /* we need to zero database if we are the only one with it open */ + if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0)) + && (tdb_flags & TDB_CLEAR_IF_FIRST)) { + open_flags |= O_CREAT; + if (ftruncate(tdb->fd, 0) == -1) { + TDB_LOG((tdb, 0, "tdb_open_ex: " + "failed to truncate %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by ftruncate */ + } + } + + if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) + || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 + || (tdb->header.version != TDB_VERSION + && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { + /* its not a valid database - possibly initialise it */ + if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { + errno = EIO; /* ie bad format or something */ + goto fail; + } + rev = (tdb->flags & TDB_CONVERT); + } + vp = (unsigned char *)&tdb->header.version; + vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) | + (((u32)vp[2]) << 8) | (u32)vp[3]; + tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; + if (!rev) + tdb->flags &= ~TDB_CONVERT; + else { + tdb->flags |= TDB_CONVERT; + convert(&tdb->header, sizeof(tdb->header)); + } + if (fstat(tdb->fd, &st) == -1) + goto fail; + + /* Is it already in the open list? If so, fail. */ + if (tdb_already_open(st.st_dev, st.st_ino)) { + TDB_LOG((tdb, 2, "tdb_open_ex: " + "%s (%d,%d) is already open in this process\n", + name, st.st_dev, st.st_ino)); + errno = EBUSY; + goto fail; + } + + if (!(tdb->name = (char *)strdup(name))) { + errno = ENOMEM; + goto fail; + } + + tdb->map_size = st.st_size; + tdb->device = st.st_dev; + tdb->inode = st.st_ino; + tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0])); + if (!tdb->locked) { + TDB_LOG((tdb, 2, "tdb_open_ex: " + "failed to allocate lock structure for %s\n", + name)); + errno = ENOMEM; + goto fail; + } + tdb_mmap(tdb); + if (locked) { + if (!tdb->read_only) + if (tdb_clear_spinlocks(tdb) != 0) { + TDB_LOG((tdb, 0, "tdb_open_ex: " + "failed to clear spinlock\n")); + goto fail; + } + if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) { + TDB_LOG((tdb, 0, "tdb_open_ex: " + "failed to take ACTIVE_LOCK on %s: %s\n", + name, strerror(errno))); + goto fail; + } + } + /* leave this lock in place to indicate it's in use */ + if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) + goto fail; + + internal: + /* Internal (memory-only) databases skip all the code above to + * do with disk files, and resume here by releasing their + * global lock and hooking into the active list. */ + if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) + goto fail; + tdb->next = tdbs; + tdbs = tdb; + return tdb; + + fail: + { int save_errno = errno; + + if (!tdb) + return NULL; + + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + SAFE_FREE(tdb->name); + if (tdb->fd != -1) + if (close(tdb->fd) != 0) + TDB_LOG((tdb, 5, "tdb_open_ex: failed to close tdb->fd on error!\n")); + SAFE_FREE(tdb->locked); + SAFE_FREE(tdb); + errno = save_errno; + return NULL; + } +} + +/** + * Close a database. + * + * @returns -1 for error; 0 for success. + **/ +int tdb_close(TDB_CONTEXT *tdb) +{ + TDB_CONTEXT **i; + int ret = 0; + + if (tdb->map_ptr) { + if (tdb->flags & TDB_INTERNAL) + SAFE_FREE(tdb->map_ptr); + else + tdb_munmap(tdb); + } + SAFE_FREE(tdb->name); + if (tdb->fd != -1) + ret = close(tdb->fd); + SAFE_FREE(tdb->locked); + SAFE_FREE(tdb->lockedkeys); + + /* Remove from contexts list */ + for (i = &tdbs; *i; i = &(*i)->next) { + if (*i == tdb) { + *i = tdb->next; + break; + } + } + + memset(tdb, 0, sizeof(*tdb)); + SAFE_FREE(tdb); + + return ret; +} + +/* lock/unlock entire database */ +int tdb_lockall(TDB_CONTEXT *tdb) +{ + u32 i; + + /* There are no locks on read-only dbs */ + if (tdb->read_only) + return TDB_ERRCODE(TDB_ERR_LOCK, -1); + if (tdb->lockedkeys) + return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); + for (i = 0; i < tdb->header.hash_size; i++) + if (tdb_lock(tdb, i, F_WRLCK)) + break; + + /* If error, release locks we have... */ + if (i < tdb->header.hash_size) { + u32 j; + + for ( j = 0; j < i; j++) + tdb_unlock(tdb, j, F_WRLCK); + return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); + } + + return 0; +} +void tdb_unlockall(TDB_CONTEXT *tdb) +{ + u32 i; + for (i=0; i < tdb->header.hash_size; i++) + tdb_unlock(tdb, i, F_WRLCK); +} + +int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]) +{ + u32 i, j, hash; + + /* Can't lock more keys if already locked */ + if (tdb->lockedkeys) + return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); + if (!(tdb->lockedkeys = malloc(sizeof(u32) * (number+1)))) + return TDB_ERRCODE(TDB_ERR_OOM, -1); + /* First number in array is # keys */ + tdb->lockedkeys[0] = number; + + /* Insertion sort by bucket */ + for (i = 0; i < number; i++) { + hash = tdb_hash(&keys[i]); + for (j = 0; j < i && BUCKET(tdb->lockedkeys[j+1]) < BUCKET(hash); j++); + memmove(&tdb->lockedkeys[j+2], &tdb->lockedkeys[j+1], sizeof(u32) * (i-j)); + tdb->lockedkeys[j+1] = hash; + } + /* Finally, lock in order */ + for (i = 0; i < number; i++) + if (tdb_lock(tdb, i, F_WRLCK)) + break; + + /* If error, release locks we have... */ + if (i < number) { + for ( j = 0; j < i; j++) + tdb_unlock(tdb, j, F_WRLCK); + SAFE_FREE(tdb->lockedkeys); + return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); + } + return 0; +} + +/* Unlock the keys previously locked by tdb_lockkeys() */ +void tdb_unlockkeys(TDB_CONTEXT *tdb) +{ + u32 i; + if (!tdb->lockedkeys) + return; + for (i = 0; i < tdb->lockedkeys[0]; i++) + tdb_unlock(tdb, tdb->lockedkeys[i+1], F_WRLCK); + SAFE_FREE(tdb->lockedkeys); +} + +/* lock/unlock one hash chain. This is meant to be used to reduce + contention - it cannot guarantee how many records will be locked */ +int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK); +} + +int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK); +} + +int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK); +} + +int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key) +{ + return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK); +} + + +/* register a loging function */ +void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)) +{ + tdb->log_fn = fn; +} + + +/* reopen a tdb - this is used after a fork to ensure that we have an independent + seek pointer from our parent and to re-establish locks */ +int tdb_reopen(TDB_CONTEXT *tdb) +{ + struct stat st; + + if (tdb_munmap(tdb) != 0) { + TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); + goto fail; + } + if (close(tdb->fd) != 0) + TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n")); + tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); + if (tdb->fd == -1) { + TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno))); + goto fail; + } + if (fstat(tdb->fd, &st) != 0) { + TDB_LOG((tdb, 0, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); + goto fail; + } + if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { + TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n")); + goto fail; + } + tdb_mmap(tdb); + if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) { + TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); + goto fail; + } + + return 0; + +fail: + tdb_close(tdb); + return -1; +} + +/* reopen all tdb's */ +int tdb_reopen_all(void) +{ + TDB_CONTEXT *tdb; + + for (tdb=tdbs; tdb; tdb = tdb->next) { + if (tdb_reopen(tdb) != 0) return -1; + } + + return 0; +} diff --git a/tdb/tdb.h b/tdb/tdb.h new file mode 100644 index 0000000000..6f3b1ff756 --- /dev/null +++ b/tdb/tdb.h @@ -0,0 +1,144 @@ +#ifndef __TDB_H__ +#define __TDB_H__ + +/* + Unix SMB/CIFS implementation. + Samba database functions + Copyright (C) Andrew Tridgell 1999 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef __cplusplus +extern "C" { +#endif + + +/* flags to tdb_store() */ +#define TDB_REPLACE 1 +#define TDB_INSERT 2 +#define TDB_MODIFY 3 + +/* flags for tdb_open() */ +#define TDB_DEFAULT 0 /* just a readability place holder */ +#define TDB_CLEAR_IF_FIRST 1 +#define TDB_INTERNAL 2 /* don't store on disk */ +#define TDB_NOLOCK 4 /* don't do any locking */ +#define TDB_NOMMAP 8 /* don't use mmap */ +#define TDB_CONVERT 16 /* convert endian (internal use) */ +#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ + +#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) + +/* error codes */ +enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, + TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT }; + +#ifndef u32 +#define u32 unsigned +#endif + +typedef struct { + char *dptr; + size_t dsize; +} TDB_DATA; + +typedef u32 tdb_len; +typedef u32 tdb_off; + +/* this is stored at the front of every database */ +struct tdb_header { + char magic_food[32]; /* for /etc/magic */ + u32 version; /* version of the code */ + u32 hash_size; /* number of hash entries */ + tdb_off rwlocks; + tdb_off reserved[31]; +}; + +struct tdb_lock_type { + u32 count; + u32 ltype; +}; + +struct tdb_traverse_lock { + struct tdb_traverse_lock *next; + u32 off; + u32 hash; +}; + +/* this is the context structure that is returned from a db open */ +typedef struct tdb_context { + char *name; /* the name of the database */ + void *map_ptr; /* where it is currently mapped */ + int fd; /* open file descriptor for the database */ + tdb_len map_size; /* how much space has been mapped */ + int read_only; /* opened read-only */ + struct tdb_lock_type *locked; /* array of chain locks */ + enum TDB_ERROR ecode; /* error code for last tdb error */ + struct tdb_header header; /* a cached copy of the header */ + u32 flags; /* the flags passed to tdb_open */ + u32 *lockedkeys; /* array of locked keys: first is #keys */ + struct tdb_traverse_lock travlocks; /* current traversal locks */ + struct tdb_context *next; /* all tdbs to avoid multiple opens */ + dev_t device; /* uniquely identifies this tdb */ + ino_t inode; /* uniquely identifies this tdb */ + void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...); /* logging function */ + int open_flags; /* flags used in the open - needed by reopen */ +} TDB_CONTEXT; + +typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); +typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...); + +TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode); +TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode, + tdb_log_func log_fn); + +int tdb_reopen(TDB_CONTEXT *tdb); +int tdb_reopen_all(void); +void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func); +enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); +const char *tdb_errorstr(TDB_CONTEXT *tdb); +TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); +int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf); +int tdb_close(TDB_CONTEXT *tdb); +TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); +TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state); +int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]); +void tdb_unlockkeys(TDB_CONTEXT *tdb); +int tdb_lockall(TDB_CONTEXT *tdb); +void tdb_unlockall(TDB_CONTEXT *tdb); + +/* Low level locking functions: use with care */ +void tdb_set_lock_alarm(sig_atomic_t *palarm); +int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); + +/* Debug functions. Not used in production. */ +void tdb_dump_all(TDB_CONTEXT *tdb); +int tdb_printfreelist(TDB_CONTEXT *tdb); + +extern TDB_DATA tdb_null; + +#ifdef __cplusplus +} +#endif + +#endif /* tdb.h */ diff --git a/tdb/tdb.magic b/tdb/tdb.magic new file mode 100644 index 0000000000..f5619e7327 --- /dev/null +++ b/tdb/tdb.magic @@ -0,0 +1,10 @@ +# Magic file(1) information about tdb files. +# +# Install this into /etc/magic or the corresponding location for your +# system, or pass as a -m argument to file(1). + +# You may use and redistribute this file without restriction. + +0 string TDB\ file TDB database +>32 lelong =0x2601196D version 6, little-endian +>>36 lelong x hash size %d bytes diff --git a/tdb/tdbback.c b/tdb/tdbback.c new file mode 100644 index 0000000000..744cface55 --- /dev/null +++ b/tdb/tdbback.c @@ -0,0 +1,201 @@ +/* + Unix SMB/CIFS implementation. + low level tdb backup and restore utility + Copyright (C) Andrew Tridgell 2002 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" + +static int failed; + +char *add_suffix(const char *name, const char *suffix) +{ + char *ret; + int len = strlen(name) + strlen(suffix) + 1; + ret = malloc(len); + if (!ret) { + fprintf(stderr,"Out of memory!\n"); + exit(1); + } + strncpy(ret, name, len); + strncat(ret, suffix, len); + return ret; +} + +static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; + + if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { + fprintf(stderr,"Failed to insert into %s\n", tdb_new->name); + failed = 1; + return 1; + } + return 0; +} + + +static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + return 0; +} + +/* + carefully backup a tdb, validating the contents and + only doing the backup if its OK + this function is also used for restore +*/ +int backup_tdb(const char *old_name, const char *new_name) +{ + TDB_CONTEXT *tdb; + TDB_CONTEXT *tdb_new; + char *tmp_name; + struct stat st; + int count1, count2; + + tmp_name = add_suffix(new_name, ".tmp"); + + /* stat the old tdb to find its permissions */ + if (stat(old_name, &st) != 0) { + perror(old_name); + return 1; + } + + /* open the old tdb */ + tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); + if (!tdb) { + printf("Failed to open %s\n", old_name); + return 1; + } + + /* create the new tdb */ + unlink(tmp_name); + tdb_new = tdb_open(tmp_name, tdb->header.hash_size, + TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, + st.st_mode & 0777); + if (!tdb_new) { + perror(tmp_name); + free(tmp_name); + return 1; + } + + /* lock the old tdb */ + if (tdb_lockall(tdb) != 0) { + fprintf(stderr,"Failed to lock %s\n", old_name); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + failed = 0; + + /* traverse and copy */ + count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); + if (count1 < 0 || failed) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* close the old tdb */ + tdb_close(tdb); + + /* close the new tdb and re-open read-only */ + tdb_close(tdb_new); + tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); + if (!tdb_new) { + fprintf(stderr,"failed to reopen %s\n", tmp_name); + unlink(tmp_name); + perror(tmp_name); + free(tmp_name); + return 1; + } + + /* traverse the new tdb to confirm */ + count2 = tdb_traverse(tdb_new, test_fn, 0); + if (count2 != count1) { + fprintf(stderr,"failed to copy %s\n", old_name); + tdb_close(tdb_new); + unlink(tmp_name); + free(tmp_name); + return 1; + } + + /* make sure the new tdb has reached stable storage */ + fsync(tdb_new->fd); + + /* close the new tdb and rename it to .bak */ + tdb_close(tdb_new); + unlink(new_name); + if (rename(tmp_name, new_name) != 0) { + perror(new_name); + free(tmp_name); + return 1; + } + + free(tmp_name); + + return 0; +} + + + +/* + verify a tdb and if it is corrupt then restore from *.bak +*/ +int verify_tdb(const char *fname, const char *bak_name) +{ + TDB_CONTEXT *tdb; + int count = -1; + + /* open the tdb */ + tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); + + /* traverse the tdb, then close it */ + if (tdb) { + count = tdb_traverse(tdb, test_fn, NULL); + tdb_close(tdb); + } + + /* count is < 0 means an error */ + if (count < 0) { + printf("restoring %s\n", fname); + return backup_tdb(bak_name, fname); + } + + printf("%s : %d records\n", fname, count); + + return 0; +} diff --git a/tdb/tdbback.h b/tdb/tdbback.h new file mode 100644 index 0000000000..7ebeaa494d --- /dev/null +++ b/tdb/tdbback.h @@ -0,0 +1,23 @@ +/* + Unix SMB/CIFS implementation. + low level tdb backup and restore utility + Copyright (C) Andrew Tridgell 2002 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +char *add_suffix(const char *name, const char *suffix); +int backup_tdb(const char *old_name, const char *new_name); +int verify_tdb(const char *fname, const char *bak_name); diff --git a/tdb/tdbbackup.c b/tdb/tdbbackup.c new file mode 100644 index 0000000000..0eaf6b6c0b --- /dev/null +++ b/tdb/tdbbackup.c @@ -0,0 +1,137 @@ +/* + Unix SMB/CIFS implementation. + low level tdb backup and restore utility + Copyright (C) Andrew Tridgell 2002 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/* + + This program is meant for backup/restore of tdb databases. Typical usage would be: + tdbbackup *.tdb + when Samba shuts down cleanly, which will make a backup of all the local databases + to *.bak files. Then on Samba startup you would use: + tdbbackup -v *.tdb + and this will check the databases for corruption and if corruption is detected then + the backup will be restored. + + You may also like to do a backup on a regular basis while Samba is + running, perhaps using cron. + + The reason this program is needed is to cope with power failures + while Samba is running. A power failure could lead to database + corruption and Samba will then not start correctly. + + Note that many of the databases in Samba are transient and thus + don't need to be backed up, so you can optimise the above a little + by only running the backup on the critical databases. + + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" +#include "tdbback.h" + +/* + see if one file is newer than another +*/ +static int file_newer(const char *fname1, const char *fname2) +{ + struct stat st1, st2; + if (stat(fname1, &st1) != 0) { + return 0; + } + if (stat(fname2, &st2) != 0) { + return 1; + } + return (st1.st_mtime > st2.st_mtime); +} + +static void usage(void) +{ + printf("Usage: tdbbackup [options] \n\n"); + printf(" -h this help message\n"); + printf(" -s suffix set the backup suffix\n"); + printf(" -v verify mode (restore if corrupt)\n"); +} + + + int main(int argc, char *argv[]) +{ + int i; + int ret = 0; + int c; + int verify = 0; + const char *suffix = ".bak"; + extern int optind; + extern char *optarg; + + while ((c = getopt(argc, argv, "vhs:")) != -1) { + switch (c) { + case 'h': + usage(); + exit(0); + case 'v': + verify = 1; + break; + case 's': + suffix = optarg; + break; + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) { + usage(); + exit(1); + } + + for (i=0; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" + +static void print_data(TDB_DATA d) +{ + unsigned char *p = d.dptr; + int len = d.dsize; + while (len--) { + if (isprint(*p) && !strchr("\"\\", *p)) { + fputc(*p, stdout); + } else { + printf("\\%02X", *p); + } + p++; + } +} + +static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + printf("{\n"); + printf("key = \""); + print_data(key); + printf("\"\n"); + printf("data = \""); + print_data(dbuf); + printf("\"\n"); + printf("}\n"); + return 0; +} + +static int dump_tdb(const char *fname) +{ + TDB_CONTEXT *tdb; + + tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); + if (!tdb) { + printf("Failed to open %s\n", fname); + return 1; + } + + tdb_traverse(tdb, traverse_fn, NULL); + return 0; +} + + int main(int argc, char *argv[]) +{ + char *fname; + + if (argc < 2) { + printf("Usage: tdbdump \n"); + exit(1); + } + + fname = argv[1]; + + return dump_tdb(fname); +} diff --git a/tdb/tdbtest.c b/tdb/tdbtest.c new file mode 100644 index 0000000000..89295a3291 --- /dev/null +++ b/tdb/tdbtest.c @@ -0,0 +1,263 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" +#include + +/* a test program for tdb - the trivial database */ + + + +#define DELETE_PROB 7 +#define STORE_PROB 5 + +static TDB_CONTEXT *db; +static GDBM_FILE gdbm; + +struct timeval tp1,tp2; + +static void start_timer(void) +{ + gettimeofday(&tp1,NULL); +} + +static double end_timer(void) +{ + gettimeofday(&tp2,NULL); + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); +} + +static void fatal(char *why) +{ + perror(why); + exit(1); +} + +static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); + fflush(stdout); +} + +static void compare_db(void) +{ + TDB_DATA d, key, nextkey; + datum gd, gkey, gnextkey; + + key = tdb_firstkey(db); + while (key.dptr) { + d = tdb_fetch(db, key); + gkey.dptr = key.dptr; + gkey.dsize = key.dsize; + + gd = gdbm_fetch(gdbm, gkey); + + if (!gd.dptr) fatal("key not in gdbm"); + if (gd.dsize != d.dsize) fatal("data sizes differ"); + if (memcmp(gd.dptr, d.dptr, d.dsize)) { + fatal("data differs"); + } + + nextkey = tdb_nextkey(db, key); + free(key.dptr); + free(d.dptr); + free(gd.dptr); + key = nextkey; + } + + gkey = gdbm_firstkey(gdbm); + while (gkey.dptr) { + gd = gdbm_fetch(gdbm, gkey); + key.dptr = gkey.dptr; + key.dsize = gkey.dsize; + + d = tdb_fetch(db, key); + + if (!d.dptr) fatal("key not in db"); + if (d.dsize != gd.dsize) fatal("data sizes differ"); + if (memcmp(d.dptr, gd.dptr, gd.dsize)) { + fatal("data differs"); + } + + gnextkey = gdbm_nextkey(gdbm, gkey); + free(gkey.dptr); + free(gd.dptr); + free(d.dptr); + gkey = gnextkey; + } +} + +static char *randbuf(int len) +{ + char *buf; + int i; + buf = (char *)malloc(len+1); + + for (i=0;i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" + +/* a tdb tool for manipulating a tdb database */ + +#define FSTRING_LEN 256 +typedef char fstring[FSTRING_LEN]; + +typedef struct connections_key { + pid_t pid; + int cnum; + fstring name; +} connections_key; + +typedef struct connections_data { + int magic; + pid_t pid; + int cnum; + uid_t uid; + gid_t gid; + char name[24]; + char addr[24]; + char machine[128]; + time_t start; +} connections_data; + +static TDB_CONTEXT *tdb; + +static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); + +static void print_asc(unsigned char *buf,int len) +{ + int i; + + /* We're probably printing ASCII strings so don't try to display + the trailing NULL character. */ + + if (buf[len - 1] == 0) + len--; + + for (i=0;i8) printf(" "); + while (n--) printf(" "); + + n = i%16; + if (n > 8) n = 8; + print_asc(&buf[i-(i%16)],n); printf(" "); + n = (i%16) - n; + if (n>0) print_asc(&buf[i-n],n); + printf("\n"); + } +} + +static void help(void) +{ + printf("\n" +"tdbtool: \n" +" create dbname : create a database\n" +" open dbname : open an existing database\n" +" erase : erase the database\n" +" dump : dump the database as strings\n" +" insert key data : insert a record\n" +" move key file : move a record to a destination tdb\n" +" store key data : store a record (replace)\n" +" show key : show a record by key\n" +" delete key : delete a record by key\n" +" list : print the database hash table and freelist\n" +" free : print the database freelist\n" +" 1 | first : print the first record\n" +" n | next : print the next record\n" +" q | quit : terminate\n" +" \\n : repeat 'next' command\n" +"\n"); +} + +static void terror(char *why) +{ + printf("%s\n", why); +} + +static char *get_token(int startover) +{ + static char tmp[1024]; + static char *cont = NULL; + char *insert, *start; + char *k = strtok(NULL, " "); + + if (!k) + return NULL; + + if (startover) + start = tmp; + else + start = cont; + + strcpy(start, k); + insert = start + strlen(start) - 1; + while (*insert == '\\') { + *insert++ = ' '; + k = strtok(NULL, " "); + if (!k) + break; + strcpy(insert, k); + insert = start + strlen(start) - 1; + } + + /* Get ready for next call */ + cont = start + strlen(start) + 1; + return start; +} + +static void create_tdb(void) +{ + char *tok = get_token(1); + if (!tok) { + help(); + return; + } + if (tdb) tdb_close(tdb); + tdb = tdb_open(tok, 0, TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT | O_TRUNC, 0600); + if (!tdb) { + printf("Could not create %s: %s\n", tok, strerror(errno)); + } +} + +static void open_tdb(void) +{ + char *tok = get_token(1); + if (!tok) { + help(); + return; + } + if (tdb) tdb_close(tdb); + tdb = tdb_open(tok, 0, 0, O_RDWR, 0600); + if (!tdb) { + printf("Could not open %s: %s\n", tok, strerror(errno)); + } +} + +static void insert_tdb(void) +{ + char *k = get_token(1); + char *d = get_token(0); + TDB_DATA key, dbuf; + + if (!k || !d) { + help(); + return; + } + + key.dptr = k; + key.dsize = strlen(k)+1; + dbuf.dptr = d; + dbuf.dsize = strlen(d)+1; + + if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { + terror("insert failed"); + } +} + +static void store_tdb(void) +{ + char *k = get_token(1); + char *d = get_token(0); + TDB_DATA key, dbuf; + + if (!k || !d) { + help(); + return; + } + + key.dptr = k; + key.dsize = strlen(k)+1; + dbuf.dptr = d; + dbuf.dsize = strlen(d)+1; + + printf("Storing key:\n"); + print_rec(tdb, key, dbuf, NULL); + + if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { + terror("store failed"); + } +} + +static void show_tdb(void) +{ + char *k = get_token(1); + TDB_DATA key, dbuf; + + if (!k) { + help(); + return; + } + + key.dptr = k; + key.dsize = strlen(k)+1; + + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) { + /* maybe it is non-NULL terminated key? */ + key.dsize = strlen(k); + dbuf = tdb_fetch(tdb, key); + + if ( !dbuf.dptr ) { + terror("fetch failed"); + return; + } + } + + /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ + print_rec(tdb, key, dbuf, NULL); + + free( dbuf.dptr ); + + return; +} + +static void delete_tdb(void) +{ + char *k = get_token(1); + TDB_DATA key; + + if (!k) { + help(); + return; + } + + key.dptr = k; + key.dsize = strlen(k)+1; + + if (tdb_delete(tdb, key) != 0) { + terror("delete failed"); + } +} + +static void move_rec(void) +{ + char *k = get_token(1); + char *file = get_token(0); + TDB_DATA key, dbuf; + TDB_CONTEXT *dst_tdb; + + if (!k) { + help(); + return; + } + + if ( !file ) { + terror("need destination tdb name"); + return; + } + + key.dptr = k; + key.dsize = strlen(k)+1; + + dbuf = tdb_fetch(tdb, key); + if (!dbuf.dptr) { + /* maybe it is non-NULL terminated key? */ + key.dsize = strlen(k); + dbuf = tdb_fetch(tdb, key); + + if ( !dbuf.dptr ) { + terror("fetch failed"); + return; + } + } + + print_rec(tdb, key, dbuf, NULL); + + dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600); + if ( !dst_tdb ) { + terror("unable to open destination tdb"); + return; + } + + if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { + terror("failed to move record"); + } + else + printf("record moved\n"); + + tdb_close( dst_tdb ); + + return; +} + +#if 0 +static int print_conn_key(TDB_DATA key) +{ + printf( "pid =%5d ", ((connections_key*)key.dptr)->pid); + printf( "cnum =%10d ", ((connections_key*)key.dptr)->cnum); + printf( "name =[%s]\n", ((connections_key*)key.dptr)->name); + return 0; +} + +static int print_conn_data(TDB_DATA dbuf) +{ + printf( "pid =%5d ", ((connections_data*)dbuf.dptr)->pid); + printf( "cnum =%10d ", ((connections_data*)dbuf.dptr)->cnum); + printf( "name =[%s]\n", ((connections_data*)dbuf.dptr)->name); + + printf( "uid =%5d ", ((connections_data*)dbuf.dptr)->uid); + printf( "addr =[%s]\n", ((connections_data*)dbuf.dptr)->addr); + printf( "gid =%5d ", ((connections_data*)dbuf.dptr)->gid); + printf( "machine=[%s]\n", ((connections_data*)dbuf.dptr)->machine); + printf( "start = %s\n", ctime(&((connections_data*)dbuf.dptr)->start)); + return 0; +} +#endif + +static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ +#if 0 + print_conn_key(key); + print_conn_data(dbuf); + return 0; +#else + printf("\nkey %d bytes\n", key.dsize); + print_asc(key.dptr, key.dsize); + printf("\ndata %d bytes\n", dbuf.dsize); + print_data(dbuf.dptr, dbuf.dsize); + return 0; +#endif +} + +static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + print_asc(key.dptr, key.dsize); + printf("\n"); + return 0; +} + +static int total_bytes; + +static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + total_bytes += dbuf.dsize; + return 0; +} + +static void info_tdb(void) +{ + int count; + total_bytes = 0; + if ((count = tdb_traverse(tdb, traverse_fn, NULL) == -1)) + printf("Error = %s\n", tdb_errorstr(tdb)); + else + printf("%d records totalling %d bytes\n", count, total_bytes); +} + +static char *tdb_getline(char *prompt) +{ + static char line[1024]; + char *p; + fputs(prompt, stdout); + line[0] = 0; + p = fgets(line, sizeof(line)-1, stdin); + if (p) p = strchr(p, '\n'); + if (p) *p = 0; + return p?line:NULL; +} + +static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, + void *state) +{ + return tdb_delete(the_tdb, key); +} + +static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) +{ + TDB_DATA dbuf; + *pkey = tdb_firstkey(the_tdb); + + dbuf = tdb_fetch(the_tdb, *pkey); + if (!dbuf.dptr) terror("fetch failed"); + else { + /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ + print_rec(the_tdb, *pkey, dbuf, NULL); + } +} + +static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) +{ + TDB_DATA dbuf; + *pkey = tdb_nextkey(the_tdb, *pkey); + + dbuf = tdb_fetch(the_tdb, *pkey); + if (!dbuf.dptr) + terror("fetch failed"); + else + /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ + print_rec(the_tdb, *pkey, dbuf, NULL); +} + +int main(int argc, char *argv[]) +{ + int bIterate = 0; + char *line; + char *tok; + TDB_DATA iterate_kbuf; + + if (argv[1]) { + static char tmp[1024]; + sprintf(tmp, "open %s", argv[1]); + tok=strtok(tmp," "); + open_tdb(); + } + + while ((line = tdb_getline("tdb> "))) { + + /* Shell command */ + + if (line[0] == '!') { + system(line + 1); + continue; + } + + if ((tok = strtok(line," "))==NULL) { + if (bIterate) + next_record(tdb, &iterate_kbuf); + continue; + } + if (strcmp(tok,"create") == 0) { + bIterate = 0; + create_tdb(); + continue; + } else if (strcmp(tok,"open") == 0) { + open_tdb(); + continue; + } else if ((strcmp(tok, "q") == 0) || + (strcmp(tok, "quit") == 0)) { + break; + } + + /* all the rest require a open database */ + if (!tdb) { + bIterate = 0; + terror("database not open"); + help(); + continue; + } + + if (strcmp(tok,"insert") == 0) { + bIterate = 0; + insert_tdb(); + } else if (strcmp(tok,"store") == 0) { + bIterate = 0; + store_tdb(); + } else if (strcmp(tok,"show") == 0) { + bIterate = 0; + show_tdb(); + } else if (strcmp(tok,"erase") == 0) { + bIterate = 0; + tdb_traverse(tdb, do_delete_fn, NULL); + } else if (strcmp(tok,"delete") == 0) { + bIterate = 0; + delete_tdb(); + } else if (strcmp(tok,"dump") == 0) { + bIterate = 0; + tdb_traverse(tdb, print_rec, NULL); + } else if (strcmp(tok,"move") == 0) { + bIterate = 0; + move_rec(); + } else if (strcmp(tok,"list") == 0) { + tdb_dump_all(tdb); + } else if (strcmp(tok, "free") == 0) { + tdb_printfreelist(tdb); + } else if (strcmp(tok,"info") == 0) { + info_tdb(); + } else if ( (strcmp(tok, "1") == 0) || + (strcmp(tok, "first") == 0)) { + bIterate = 1; + first_record(tdb, &iterate_kbuf); + } else if ((strcmp(tok, "n") == 0) || + (strcmp(tok, "next") == 0)) { + next_record(tdb, &iterate_kbuf); + } else if ((strcmp(tok, "keys") == 0)) { + bIterate = 0; + tdb_traverse(tdb, print_key, NULL); + } else { + help(); + } + } + + if (tdb) tdb_close(tdb); + + return 0; +} diff --git a/tdb/tdbtorture.c b/tdb/tdbtorture.c new file mode 100644 index 0000000000..e27bbff990 --- /dev/null +++ b/tdb/tdbtorture.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tdb.h" + +/* this tests tdb by doing lots of ops from several simultaneous + writers - that stresses the locking code. Build with TDB_DEBUG=1 + for best effect */ + + + +#define REOPEN_PROB 30 +#define DELETE_PROB 8 +#define STORE_PROB 4 +#define APPEND_PROB 6 +#define LOCKSTORE_PROB 0 +#define TRAVERSE_PROB 20 +#define CULL_PROB 100 +#define KEYLEN 3 +#define DATALEN 100 +#define LOCKLEN 20 + +static TDB_CONTEXT *db; + +static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vfprintf(stdout, format, ap); + va_end(ap); + fflush(stdout); +#if 0 + { + char *ptr; + asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); + system(ptr); + free(ptr); + } +#endif +} + +static void fatal(char *why) +{ + perror(why); + exit(1); +} + +static char *randbuf(int len) +{ + char *buf; + int i; + buf = (char *)malloc(len+1); + + for (i=0;i + +/* these are little tdb utility functions that are meant to make + dealing with a tdb database a little less cumbersome in Samba */ + +static SIG_ATOMIC_T gotalarm; + +/*************************************************************** + Signal function to tell us we timed out. +****************************************************************/ + +static void gotalarm_sig(void) +{ + gotalarm = 1; +} + +/*************************************************************** + Make a TDB_DATA and keep the const warning in one place +****************************************************************/ + +static TDB_DATA make_tdb_data(const char *dptr, size_t dsize) +{ + TDB_DATA ret; + ret.dptr = dptr; + ret.dsize = dsize; + return ret; +} + +/**************************************************************************** + Lock a chain with timeout (in seconds). +****************************************************************************/ + +static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type) +{ + /* Allow tdb_chainlock to be interrupted by an alarm. */ + int ret; + gotalarm = 0; + tdb_set_lock_alarm(&gotalarm); + + if (timeout) { + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(timeout); + } + + if (rw_type == F_RDLCK) + ret = tdb_chainlock_read(tdb, key); + else + ret = tdb_chainlock(tdb, key); + + if (timeout) { + alarm(0); + CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); + if (gotalarm) { + DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n", + timeout, key.dptr, tdb->name )); + /* TODO: If we time out waiting for a lock, it might + * be nice to use F_GETLK to get the pid of the + * process currently holding the lock and print that + * as part of the debugging message. -- mbp */ + return -1; + } + } + + return ret; +} + +/**************************************************************************** + Write lock a chain. Return -1 if timeout or lock failed. +****************************************************************************/ + +int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout) +{ + return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK); +} + +/**************************************************************************** + Lock a chain by string. Return -1 if timeout or lock failed. +****************************************************************************/ + +int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK); +} + +/**************************************************************************** + Unlock a chain by string. +****************************************************************************/ + +void tdb_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + tdb_chainunlock(tdb, key); +} + +/**************************************************************************** + Read lock a chain by string. Return -1 if timeout or lock failed. +****************************************************************************/ + +int tdb_read_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_RDLCK); +} + +/**************************************************************************** + Read unlock a chain by string. +****************************************************************************/ + +void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) +{ + TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); + + tdb_chainunlock_read(tdb, key); +} + + +/**************************************************************************** + Fetch a int32 value by a arbitrary blob key, return -1 if not found. + Output is int32 in native byte order. +****************************************************************************/ + +int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len) +{ + TDB_DATA key = make_tdb_data(keyval, len); + TDB_DATA data; + int32 ret; + + data = tdb_fetch(tdb, key); + if (!data.dptr || data.dsize != sizeof(int32)) { + SAFE_FREE(data.dptr); + return -1; + } + + ret = IVAL(data.dptr,0); + SAFE_FREE(data.dptr); + return ret; +} + +/**************************************************************************** + Fetch a int32 value by string key, return -1 if not found. + Output is int32 in native byte order. +****************************************************************************/ + +int32 tdb_fetch_int32(TDB_CONTEXT *tdb, const char *keystr) +{ + return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1); +} + +/**************************************************************************** + Store a int32 value by an arbitary blob key, return 0 on success, -1 on failure. + Input is int32 in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +int tdb_store_int32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, int32 v) +{ + TDB_DATA key = make_tdb_data(keystr, len); + TDB_DATA data; + int32 v_store; + + SIVAL(&v_store,0,v); + data.dptr = (void *)&v_store; + data.dsize = sizeof(int32); + + return tdb_store(tdb, key, data, TDB_REPLACE); +} + +/**************************************************************************** + Store a int32 value by string key, return 0 on success, -1 on failure. + Input is int32 in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +int tdb_store_int32(TDB_CONTEXT *tdb, const char *keystr, int32 v) +{ + return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v); +} + +/**************************************************************************** + Fetch a uint32 value by a arbitrary blob key, return -1 if not found. + Output is uint32 in native byte order. +****************************************************************************/ + +BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len, uint32 *value) +{ + TDB_DATA key = make_tdb_data(keyval, len); + TDB_DATA data; + + data = tdb_fetch(tdb, key); + if (!data.dptr || data.dsize != sizeof(uint32)) { + SAFE_FREE(data.dptr); + return False; + } + + *value = IVAL(data.dptr,0); + SAFE_FREE(data.dptr); + return True; +} + +/**************************************************************************** + Fetch a uint32 value by string key, return -1 if not found. + Output is uint32 in native byte order. +****************************************************************************/ + +BOOL tdb_fetch_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 *value) +{ + return tdb_fetch_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); +} + +/**************************************************************************** + Store a uint32 value by an arbitary blob key, return 0 on success, -1 on failure. + Input is uint32 in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, uint32 value) +{ + TDB_DATA key = make_tdb_data(keystr, len); + TDB_DATA data; + uint32 v_store; + BOOL ret = True; + + SIVAL(&v_store, 0, value); + data.dptr = (void *)&v_store; + data.dsize = sizeof(uint32); + + if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) + ret = False; + + return ret; +} + +/**************************************************************************** + Store a uint32 value by string key, return 0 on success, -1 on failure. + Input is uint32 in native byte order. Output in tdb is in little-endian. +****************************************************************************/ + +BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value) +{ + return tdb_store_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); +} +/**************************************************************************** + Store a buffer by a null terminated string key. Return 0 on success, -1 + on failure. +****************************************************************************/ + +int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags) +{ + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); + + return tdb_store(tdb, key, data, flags); +} + +/**************************************************************************** + Fetch a buffer using a null terminated string key. Don't forget to call + free() on the result dptr. +****************************************************************************/ + +TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr) +{ + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); + + return tdb_fetch(tdb, key); +} + +/**************************************************************************** + Delete an entry using a null terminated string key. +****************************************************************************/ + +int tdb_delete_bystring(TDB_CONTEXT *tdb, const char *keystr) +{ + TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); + + return tdb_delete(tdb, key); +} + +/**************************************************************************** + Atomic integer change. Returns old value. To create, set initial value in *oldval. +****************************************************************************/ + +int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldval, int32 change_val) +{ + int32 val; + int32 ret = -1; + + if (tdb_lock_bystring(tdb, keystr,0) == -1) + return -1; + + if ((val = tdb_fetch_int32(tdb, keystr)) == -1) { + /* The lookup failed */ + if (tdb_error(tdb) != TDB_ERR_NOEXIST) { + /* but not because it didn't exist */ + goto err_out; + } + + /* Start with 'old' value */ + val = *oldval; + + } else { + /* It worked, set return value (oldval) to tdb data */ + *oldval = val; + } + + /* Increment value for storage and return next time */ + val += change_val; + + if (tdb_store_int32(tdb, keystr, val) == -1) + goto err_out; + + ret = 0; + + err_out: + + tdb_unlock_bystring(tdb, keystr); + return ret; +} + +/**************************************************************************** + Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval. +****************************************************************************/ + +BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldval, uint32 change_val) +{ + uint32 val; + BOOL ret = False; + + if (tdb_lock_bystring(tdb, keystr,0) == -1) + return False; + + if (!tdb_fetch_uint32(tdb, keystr, &val)) { + /* It failed */ + if (tdb_error(tdb) != TDB_ERR_NOEXIST) { + /* and not because it didn't exist */ + goto err_out; + } + + /* Start with 'old' value */ + val = *oldval; + + } else { + /* it worked, set return value (oldval) to tdb data */ + *oldval = val; + + } + + /* get a new value to store */ + val += change_val; + + if (!tdb_store_uint32(tdb, keystr, val)) + goto err_out; + + ret = True; + + err_out: + + tdb_unlock_bystring(tdb, keystr); + return ret; +} + +/**************************************************************************** + Useful pair of routines for packing/unpacking data consisting of + integers and strings. +****************************************************************************/ + +size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) +{ + va_list ap; + uint8 bt; + uint16 w; + uint32 d; + int i; + void *p; + int len; + char *s; + char c; + char *buf0 = buf; + const char *fmt0 = fmt; + int bufsize0 = bufsize; + + va_start(ap, fmt); + + while (*fmt) { + switch ((c = *fmt++)) { + case 'b': /* unsigned 8-bit integer */ + len = 1; + bt = (uint8)va_arg(ap, int); + if (bufsize && bufsize >= len) + SSVAL(buf, 0, bt); + break; + case 'w': /* unsigned 16-bit integer */ + len = 2; + w = (uint16)va_arg(ap, int); + if (bufsize && bufsize >= len) + SSVAL(buf, 0, w); + break; + case 'd': /* signed 32-bit integer (standard int in most systems) */ + len = 4; + d = va_arg(ap, uint32); + if (bufsize && bufsize >= len) + SIVAL(buf, 0, d); + break; + case 'p': /* pointer */ + len = 4; + p = va_arg(ap, void *); + d = p?1:0; + if (bufsize && bufsize >= len) + SIVAL(buf, 0, d); + break; + case 'P': /* null-terminated string */ + s = va_arg(ap,char *); + w = strlen(s); + len = w + 1; + if (bufsize && bufsize >= len) + memcpy(buf, s, len); + break; + case 'f': /* null-terminated string */ + s = va_arg(ap,char *); + w = strlen(s); + len = w + 1; + if (bufsize && bufsize >= len) + memcpy(buf, s, len); + break; + case 'B': /* fixed-length string */ + i = va_arg(ap, int); + s = va_arg(ap, char *); + len = 4+i; + if (bufsize && bufsize >= len) { + SIVAL(buf, 0, i); + memcpy(buf+4, s, i); + } + break; + default: + DEBUG(0,("Unknown tdb_pack format %c in %s\n", + c, fmt)); + len = 0; + break; + } + + buf += len; + if (bufsize) + bufsize -= len; + if (bufsize < 0) + bufsize = 0; + } + + va_end(ap); + + DEBUG(18,("tdb_pack(%s, %d) -> %d\n", + fmt0, bufsize0, (int)PTR_DIFF(buf, buf0))); + + return PTR_DIFF(buf, buf0); +} + +/**************************************************************************** + Useful pair of routines for packing/unpacking data consisting of + integers and strings. +****************************************************************************/ + +int tdb_unpack(char *buf, int bufsize, const char *fmt, ...) +{ + va_list ap; + uint8 *bt; + uint16 *w; + uint32 *d; + int len; + int *i; + void **p; + char *s, **b; + char c; + char *buf0 = buf; + const char *fmt0 = fmt; + int bufsize0 = bufsize; + + va_start(ap, fmt); + + while (*fmt) { + switch ((c=*fmt++)) { + case 'b': + len = 1; + bt = va_arg(ap, uint8 *); + if (bufsize < len) + goto no_space; + *bt = SVAL(buf, 0); + break; + case 'w': + len = 2; + w = va_arg(ap, uint16 *); + if (bufsize < len) + goto no_space; + *w = SVAL(buf, 0); + break; + case 'd': + len = 4; + d = va_arg(ap, uint32 *); + if (bufsize < len) + goto no_space; + *d = IVAL(buf, 0); + break; + case 'p': + len = 4; + p = va_arg(ap, void **); + if (bufsize < len) + goto no_space; + *p = (void *)IVAL(buf, 0); + break; + case 'P': + s = va_arg(ap,char *); + len = strlen(buf) + 1; + if (bufsize < len || len > sizeof(pstring)) + goto no_space; + memcpy(s, buf, len); + break; + case 'f': + s = va_arg(ap,char *); + len = strlen(buf) + 1; + if (bufsize < len || len > sizeof(fstring)) + goto no_space; + memcpy(s, buf, len); + break; + case 'B': + i = va_arg(ap, int *); + b = va_arg(ap, char **); + len = 4; + if (bufsize < len) + goto no_space; + *i = IVAL(buf, 0); + if (! *i) { + *b = NULL; + break; + } + len += *i; + if (bufsize < len) + goto no_space; + *b = (char *)malloc(*i); + if (! *b) + goto no_space; + memcpy(*b, buf+4, *i); + break; + default: + DEBUG(0,("Unknown tdb_unpack format %c in %s\n", + c, fmt)); + + len = 0; + break; + } + + buf += len; + bufsize -= len; + } + + va_end(ap); + + DEBUG(18,("tdb_unpack(%s, %d) -> %d\n", + fmt0, bufsize0, (int)PTR_DIFF(buf, buf0))); + + return PTR_DIFF(buf, buf0); + + no_space: + return -1; +} + + +/** + * Pack SID passed by pointer + * + * @param pack_buf pointer to buffer which is to be filled with packed data + * @param bufsize size of packing buffer + * @param sid pointer to sid to be packed + * + * @return length of the packed representation of the whole structure + **/ +size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid) +{ + int idx; + size_t len = 0; + + if (!sid || !pack_buf) return -1; + + len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num, + sid->num_auths); + + for (idx = 0; idx < 6; idx++) { + len += tdb_pack(pack_buf + len, bufsize - len, "b", sid->id_auth[idx]); + } + + for (idx = 0; idx < MAXSUBAUTHS; idx++) { + len += tdb_pack(pack_buf + len, bufsize - len, "d", sid->sub_auths[idx]); + } + + return len; +} + + +/** + * Unpack SID into a pointer + * + * @param pack_buf pointer to buffer with packed representation + * @param bufsize size of the buffer + * @param sid pointer to sid structure to be filled with unpacked data + * + * @return size of structure unpacked from buffer + **/ +size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid) +{ + int idx, len = 0; + + if (!sid || !pack_buf) return -1; + + len += tdb_unpack(pack_buf + len, bufsize - len, "bb", + &sid->sid_rev_num, &sid->num_auths); + + for (idx = 0; idx < 6; idx++) { + len += tdb_unpack(pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]); + } + + for (idx = 0; idx < MAXSUBAUTHS; idx++) { + len += tdb_unpack(pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]); + } + + return len; +} + + +/** + * Pack TRUSTED_DOM_PASS passed by pointer + * + * @param pack_buf pointer to buffer which is to be filled with packed data + * @param bufsize size of the buffer + * @param pass pointer to trusted domain password to be packed + * + * @return length of the packed representation of the whole structure + **/ +size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass) +{ + int idx, len = 0; + + if (!pack_buf || !pass) return -1; + + /* packing unicode domain name and password */ + len += tdb_pack(pack_buf + len, bufsize - len, "d", pass->uni_name_len); + + for (idx = 0; idx < 32; idx++) + len += tdb_pack(pack_buf + len, bufsize - len, "w", pass->uni_name[idx]); + + len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len, + pass->pass, pass->mod_time); + + /* packing SID structure */ + len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid); + + return len; +} + + +/** + * Unpack TRUSTED_DOM_PASS passed by pointer + * + * @param pack_buf pointer to buffer with packed representation + * @param bufsize size of the buffer + * @param pass pointer to trusted domain password to be filled with unpacked data + * + * @return size of structure unpacked from buffer + **/ +size_t tdb_trusted_dom_pass_unpack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass) +{ + int idx, len = 0; + + if (!pack_buf || !pass) return -1; + + /* unpack unicode domain name and plaintext password */ + len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len); + + for (idx = 0; idx < 32; idx++) + len += tdb_unpack(pack_buf + len, bufsize - len, "w", &pass->uni_name[idx]); + + len += tdb_unpack(pack_buf + len, bufsize - len, "dPd", &pass->pass_len, &pass->pass, + &pass->mod_time); + + /* unpack domain sid */ + len += tdb_sid_unpack(pack_buf + len, bufsize - len, &pass->domain_sid); + + return len; +} + + +/**************************************************************************** + Log tdb messages via DEBUG(). +****************************************************************************/ + +static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) +{ + va_list ap; + char *ptr = NULL; + + va_start(ap, format); + vasprintf(&ptr, format, ap); + va_end(ap); + + if (!ptr || !*ptr) + return; + + DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unnamed", ptr)); + SAFE_FREE(ptr); +} + +/**************************************************************************** + Like tdb_open() but also setup a logging function that redirects to + the samba DEBUG() system. +****************************************************************************/ + +TDB_CONTEXT *tdb_open_log(const char *name, int hash_size, int tdb_flags, + int open_flags, mode_t mode) +{ + TDB_CONTEXT *tdb; + + if (!lp_use_mmap()) + tdb_flags |= TDB_NOMMAP; + + tdb = tdb_open_ex(name, hash_size, tdb_flags, + open_flags, mode, tdb_log); + if (!tdb) + return NULL; + + return tdb; +} + + +/**************************************************************************** + Allow tdb_delete to be used as a tdb_traversal_fn. +****************************************************************************/ + +int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, + void *state) +{ + return tdb_delete(the_tdb, key); +} + + + +/** + * Search across the whole tdb for keys that match the given pattern + * return the result as a list of keys + * + * @param tdb pointer to opened tdb file context + * @param pattern searching pattern used by fnmatch(3) functions + * + * @return list of keys found by looking up with given pattern + **/ +TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT *tdb, const char* pattern) +{ + TDB_DATA key, next; + TDB_LIST_NODE *list = NULL; + TDB_LIST_NODE *rec = NULL; + TDB_LIST_NODE *tmp = NULL; + + for (key = tdb_firstkey(tdb); key.dptr; key = next) { + /* duplicate key string to ensure null-termination */ + char *key_str = (char*) strndup(key.dptr, key.dsize); + if (!key_str) { + DEBUG(0, ("tdb_search_keys: strndup() failed!\n")); + smb_panic("strndup failed!\n"); + } + + DEBUG(18, ("checking %s for match to pattern %s\n", key_str, pattern)); + + next = tdb_nextkey(tdb, key); + + /* do the pattern checking */ + if (fnmatch(pattern, key_str, 0) == 0) { + rec = (TDB_LIST_NODE*) malloc(sizeof(*rec)); + ZERO_STRUCTP(rec); + + rec->node_key = key; + + DLIST_ADD_END(list, rec, tmp); + + DEBUG(18, ("checking %s matched pattern %s\n", key_str, pattern)); + } else { + free(key.dptr); + } + + /* free duplicated key string */ + free(key_str); + } + + return list; + +}; + + +/** + * Free the list returned by tdb_search_keys + * + * @param node list of results found by tdb_search_keys + **/ +void tdb_search_list_free(TDB_LIST_NODE* node) +{ + TDB_LIST_NODE *next_node; + + while (node) { + next_node = node->next; + SAFE_FREE(node->node_key.dptr); + SAFE_FREE(node); + node = next_node; + }; +}; + + diff --git a/tdb/tdbutil.h b/tdb/tdbutil.h new file mode 100644 index 0000000000..01473446a1 --- /dev/null +++ b/tdb/tdbutil.h @@ -0,0 +1,37 @@ +/* + Unix SMB/CIFS implementation. + tdb utility functions + Copyright (C) Andrew Tridgell 1999 + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __TDBUTIL_H__ +#define __TDBUTIL_H__ + + +/* single node of a list returned by tdb_search_keys */ +typedef struct keys_node +{ + struct keys_node *prev, *next; + TDB_DATA node_key; +} TDB_LIST_NODE; + + +TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT*, const char*); +void tdb_search_list_free(TDB_LIST_NODE*); + + +#endif /* __TDBUTIL_H__ */ From 8e41d35d7675b7d47db3e27da4e1fd508d772c32 Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Tue, 5 Aug 2003 23:57:23 -0700 Subject: [PATCH 0045/4284] [PATCH] udevdb prototype Here's an "idea" of what I had in mind for udevdb. Let me preface the code with a few remarks: 1) I was expecting to write this udevdb for udev to keep track of devices. I was planning an external package that depends upon udev to provide an external API to the udevdb database. The calls for the interface would be read only access. Not sure how you want to do packaging, if having a separate package is ok or having it included in udev. 2) I created it as it is because udev isn't a daemon. So, the open database call doesn't take any parameters. My plan was to create a udevdb_init function that took arguments for initializing the db to start, where you could specify in memory only or a file location. This can all be filled in. 3) I hacked the Makefile to get it to work. Not sure how you'd want that in the future. 4) This assumes TDB has been installed elsewhere, you would need to edit your Makefile and point it to the header and library locations. How do you want to do TDB in udev? Do you want to just reference it and make udev dependent on that package being installed. Or should we do what samba does and include a limited tdb version in udev? 5) Again, I hacked udev into your existing code. In the future, I'd probably make a function around the filling out the udevice before calling the store command. Didn't know if you wanted to change your add device function to use struct udevice rather than having everything separate. 6) Not sure what we should include in the udevice structure that's stored by udev. I made a stab at a first shot - we can add and remove of course, this was a first pass. I've come to realize - with you including libsysfs in udev, the "external" interface that references udevdb could make use of getting information from through libsysfs from sysfs and doesn't need to be in udevdb. 7) I could write a namedevdb for namedev's device management if you wanted. --- namedev.h | 1 + udev-add.c | 23 ++ udev-remove.c | 4 +- udevdb.c | 591 ++++++++++++++++++++++++++++++++++++++++++++++++++ udevdb.h | 41 ++++ 5 files changed, 659 insertions(+), 1 deletion(-) create mode 100644 udevdb.c create mode 100644 udevdb.h diff --git a/namedev.h b/namedev.h index 9d612dfe0c..d986a2376d 100644 --- a/namedev.h +++ b/namedev.h @@ -23,6 +23,7 @@ #ifndef NAMEDEV_H #define NAMEDEV_H +#include "udev.h" #include "list.h" struct sysfs_class_device; diff --git a/udev-add.c b/udev-add.c index 586815e2c7..5bd934acd0 100644 --- a/udev-add.c +++ b/udev-add.c @@ -31,6 +31,7 @@ #include "udev.h" #include "udev_version.h" #include "namedev.h" +#include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -164,9 +165,31 @@ int udev_add_device(char *device, char *subsystem) dbg ("get_major_minor failed"); goto exit; } + memset(&dbdev, 0, sizeof(dbdev)); + strncpy(dbdev.name, attr.name, NAME_SIZE); + strncpy(dbdev.sysfs_path, class_dev->sysdevice->directory->path, + PATH_SIZE); + strncpy(dbdev.class_dev_name, class_dev->name, NAME_SIZE); + if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) + != 0) + strcpy(dbdev.class_name, "unkown"); + strncpy(dbdev.bus_id, class_dev->sysdevice->bus_id, ID_SIZE); + strcpy(dbdev.bus_name, "unknown"); + if (class_dev->driver != NULL) + strncpy(dbdev.driver, class_dev->driver->name, NAME_SIZE); + else + strcpy(dbdev.driver, "unkown"); + dbdev.type = type; + dbdev.major = major; + dbdev.minor = minor; + dbdev.mode = attr.mode; sysfs_close_class_device(class_dev); + retval = udevdb_add_udevice(&dbdev); + if (retval != 0) + goto exit; + return create_node(attr.name, type, major, minor, attr.mode); exit: diff --git a/udev-remove.c b/udev-remove.c index cd917af193..29063efb0d 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -31,6 +31,7 @@ #include "udev.h" #include "udev_version.h" #include "namedev.h" +#include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -80,9 +81,10 @@ int udev_remove_device(char *device, char *subsystem) goto exit; } + udevdb_delete_udevice(name); + return delete_node(name); exit: return retval; } - diff --git a/udevdb.c b/udevdb.c new file mode 100644 index 0000000000..b200f2f6ed --- /dev/null +++ b/udevdb.c @@ -0,0 +1,591 @@ +/* + * udev database library + */ +#include +#include +#include +#include +#include +#include + +#include "udevdb.h" +#include "tdb.h" + +static TDB_CONTEXT *busdb; +static TDB_CONTEXT *classdb; +static TDB_CONTEXT *namedb; + +/** + * busdb_record - bus and id are keys to look up name of device + */ +struct busdb_record { + char name[NAME_SIZE]; +}; + +/** + * classdb_record - class name and class device name used as keys to find + * device name. + */ +struct classdb_record { + char name[NAME_SIZE]; +}; + +/** + * namedb_record - device name is key, remaining udevice info stored here. + */ +struct namedb_record { + char sysfs_path[PATH_SIZE]; + char class_dev_name[NAME_SIZE]; + char class_name[NAME_SIZE]; + char bus[BUS_SIZE]; + char id[ID_SIZE]; + char driver[NAME_SIZE]; + char type; + int major; + int minor; + int mode; +}; + +/** + * busdb_close: close busdb database + */ +static void busdb_close(void) +{ + if (busdb != NULL) { + tdb_close(busdb); + busdb = NULL; + } +} + +/** + * classdb_close: close classdb database + */ +static void classdb_close(void) +{ + if (classdb != NULL) { + tdb_close(classdb); + classdb = NULL; + } +} + +/** + * namedb_close: close name database + */ +static void namedb_close(void) +{ + if (namedb != NULL) { + tdb_close(namedb); + namedb = NULL; + } +} + +/** + * busdb_open: open busdb's database + */ +static int busdb_open(void) +{ + busdb = tdb_open(BUS_DB, 0, 0, O_RDWR | O_CREAT, 0644); + if (busdb == NULL) + return -1; + return 0; +} + +/** + * classdb_open: open classdb's database + */ +static int classdb_open(void) +{ + classdb = tdb_open(CLASS_DB, 0, 0, O_RDWR | O_CREAT, 0644); + if (classdb == NULL) + return -1; + return 0; +} + +/** + * namedb_open: open name database + */ +static int namedb_open(void) +{ + namedb = tdb_open(NAME_DB, 0, 0, O_RDWR | O_CREAT, 0644); + if (namedb == NULL) + return -1; + return 0; +} + +/** + * busdb_fetch + */ +static struct busdb_record *busdb_fetch(const char *bus, const char *id) +{ + TDB_DATA key, data; + char keystr[BUS_SIZE+ID_SIZE+2]; + struct busdb_record *rec = NULL; + + if (bus == NULL || id == NULL) + return NULL; + if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE) + return NULL; + + if ((busdb_open()) != 0) + return NULL; + + memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); + strcpy(keystr, bus); + strcat(keystr, UDEVDB_DEL); + strcat(keystr, id); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + data = tdb_fetch(busdb, key); + busdb_close(); + if (data.dptr == NULL || data.dsize == 0) + return NULL; + + rec = (struct busdb_record *)malloc(sizeof(struct busdb_record)); + if (rec == NULL) { + free(data.dptr); + return NULL; + } + + memcpy(rec, data.dptr, sizeof(struct busdb_record)); + free(data.dptr); + + return rec; +} + +/** + * classdb_fetch + */ +static struct classdb_record *classdb_fetch(const char *cls, + const char *cls_dev) +{ + TDB_DATA key, data; + char keystr[NAME_SIZE+NAME_SIZE+2]; + struct classdb_record *rec = NULL; + + if (cls == NULL || cls_dev == NULL) + return NULL; + if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE) + return NULL; + + if ((classdb_open()) != 0) + return NULL; + + memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); + strcpy(keystr, cls); + strcat(keystr, UDEVDB_DEL); + strcat(keystr, cls_dev); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + data = tdb_fetch(classdb, key); + classdb_close(); + if (data.dptr == NULL || data.dsize == 0) + return NULL; + + rec = (struct classdb_record *)malloc(sizeof(struct classdb_record)); + if (rec == NULL) { + free(data.dptr); + return NULL; + } + + memcpy(rec, data.dptr, sizeof(struct classdb_record)); + free(data.dptr); + + return rec; +} + +/** + * namedb_fetch + */ +static struct namedb_record *namedb_fetch(const char *name) +{ + TDB_DATA key, data; + char nm_keystr[NAME_SIZE]; + struct namedb_record *nrec = NULL; + + if (name == NULL) + return NULL; + if (strlen(name) >= NAME_SIZE) + return NULL; + + if ((namedb_open()) != 0) + return NULL; + + memset(nm_keystr, 0, NAME_SIZE); + strcpy(nm_keystr, name); + + key.dptr = (void *)nm_keystr; + key.dsize = strlen(nm_keystr) + 1; + + data = tdb_fetch(namedb, key); + namedb_close(); + + if (data.dptr == NULL || data.dsize == 0) + return NULL; + + nrec = (struct namedb_record *)malloc(sizeof(struct namedb_record)); + if (nrec == NULL) { + free(data.dptr); + return NULL; + } + + memcpy(nrec, data.dptr, sizeof(struct namedb_record)); + free(data.dptr); + + return nrec; +} + +/** + * busdb_store + */ +static int busdb_store(const struct udevice *dev) +{ + TDB_DATA key, data; + char keystr[BUS_SIZE+ID_SIZE+2]; + struct busdb_record rec; + int retval = 0; + + if (dev == NULL) + return -1; + + if ((retval = busdb_open()) != 0) + return -1; + + memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); + strcpy(keystr, dev->bus_name); + strcat(keystr, UDEVDB_DEL); + strcat(keystr, dev->bus_id); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + strcpy(rec.name, dev->name); + + data.dptr = (void *) &rec; + data.dsize = sizeof(rec); + + retval = tdb_store(busdb, key, data, TDB_REPLACE); + + busdb_close(); + return retval; +} + +/** + * classdb_store + */ +static int classdb_store(const struct udevice *dev) +{ + TDB_DATA key, data; + char keystr[NAME_SIZE+NAME_SIZE+2]; + struct classdb_record rec; + int retval = 0; + + if (dev == NULL) + return -1; + + if ((retval = classdb_open()) != 0) + return -1; + + memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); + strcpy(keystr, dev->class_name); + strcat(keystr, UDEVDB_DEL); + strcat(keystr, dev->class_dev_name); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + strcpy(rec.name, dev->name); + + data.dptr = (void *) &rec; + data.dsize = sizeof(rec); + + retval = tdb_store(classdb, key, data, TDB_REPLACE); + + classdb_close(); + return retval; +} + +/** + * namedb_store + */ +static int namedb_store(const struct udevice *dev) +{ + TDB_DATA key, data; + char keystr[NAME_SIZE]; + struct namedb_record rec; + int retval = 0; + + if (dev == NULL) + return -1; + + if ((retval = namedb_open()) != 0) + return -1; + + memset(keystr, 0, NAME_SIZE); + strcpy(keystr, dev->name); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + strcpy(rec.sysfs_path, dev->sysfs_path); + strcpy(rec.bus, dev->bus_name); + strcpy(rec.id, dev->bus_id); + strcpy(rec.class_dev_name, dev->class_dev_name); + strcpy(rec.class_name, dev->class_name); + strcpy(rec.driver, dev->driver); + rec.type = dev->type; + rec.major = dev->major; + rec.minor = dev->minor; + rec.mode = dev->mode; + + data.dptr = (void *) &rec; + data.dsize = sizeof(rec); + + retval = tdb_store(namedb, key, data, TDB_REPLACE); + + namedb_close(); + return retval; +} + +/** + * busdb_delete + */ +static int busdb_delete(const char *bus, const char *id) +{ + TDB_DATA key; + char keystr[BUS_SIZE+ID_SIZE+2]; + int retval = 0; + + if (bus == NULL || id == NULL) + return -1; + if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE) + return -1; + + if ((busdb_open()) != 0) + return -1; + + memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); + strcpy(keystr, bus); + strcat(keystr, UDEVDB_DEL); + strcat(keystr, id); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + retval = tdb_delete(busdb, key); + busdb_close(); + + return retval; +} + +/** + * classdb_delete + */ +static int classdb_delete(const char *cls, const char *cls_dev) +{ + TDB_DATA key; + char keystr[NAME_SIZE+NAME_SIZE+2]; + int retval = 0; + + if (cls == NULL || cls_dev == NULL) + return -1; + if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE) + return -1; + + if ((classdb_open()) != 0) + return -1; + + memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); + strcpy(keystr, cls); + strcat(keystr, UDEVDB_DEL); + strcat(keystr, cls_dev); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + retval = tdb_delete(classdb, key); + classdb_close(); + + return retval; +} + +/** + * namedb_delete + */ +static int namedb_delete(const char *name) +{ + TDB_DATA key; + char keystr[NAME_SIZE]; + int retval = 0; + + if (name == NULL) + return -1; + if (strlen(name) >= NAME_SIZE) + return -1; + + if ((namedb_open()) != 0) + return -1; + + memset(keystr, 0, NAME_SIZE); + strcpy(keystr, name); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + retval = tdb_delete(namedb, key); + namedb_close(); + + return retval; +} + +/** + * namedb_exists + */ +static int namedb_exists(const char *name) +{ + TDB_DATA key; + char keystr[NAME_SIZE]; + int retval = 0; + + if (name == NULL) + return retval; + if (strlen(name) >= NAME_SIZE) + return retval; + + if ((namedb_open()) != 0) + return retval; + + memset(keystr, 0, NAME_SIZE); + strcpy(keystr, name); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + retval = tdb_exists(namedb, key); + namedb_close(); + + return retval; +} + +/** + * udevdb_delete_udevice + */ +int udevdb_delete_udevice(const char *name) +{ + struct namedb_record *nrec = NULL; + + if (name == NULL) + return -1; + + nrec = namedb_fetch(name); + if (nrec == NULL) + return -1; + + busdb_delete(nrec->bus, nrec->id); + classdb_delete(nrec->class_name, nrec->class_dev_name); + namedb_delete(name); + free(nrec); + + return 0; +} + +/** + * udevdb_add_udevice: adds udevice to database + */ +int udevdb_add_udevice(const struct udevice *dev) +{ + if (dev == NULL) + return -1; + + if ((busdb_store(dev)) != 0) + return -1; + if ((classdb_store(dev)) != 0) + return -1; + if ((namedb_store(dev)) != 0) + return -1; + + return 0; +} + +/** + * udevdb_get_device: grab's device by name + */ +struct udevice *udevdb_get_udevice(const char *name) +{ + struct namedb_record *nrec = NULL; + struct udevice *dev = NULL; + + if (name == NULL) + return NULL; + + nrec = namedb_fetch(name); + if (nrec == NULL) + return NULL; + + dev = (struct udevice *)malloc(sizeof(struct udevice)); + if (dev == NULL) { + free(nrec); + return NULL; + } + + strcpy(dev->name, name); + strcpy(dev->sysfs_path, nrec->sysfs_path); + strcpy(dev->class_dev_name, nrec->class_dev_name); + strcpy(dev->class_name, nrec->class_name); + strcpy(dev->bus_name, nrec->bus); + strcpy(dev->bus_id, nrec->id); + dev->type = nrec->type; + dev->major = nrec->major; + dev->minor = nrec->minor; + dev->mode = nrec->mode; + + free(nrec); + + return dev; +} + +/** + * udevdb_get_device_by_bus + */ +struct udevice *udevdb_get_udevice_by_bus(const char *bus, const char *id) +{ + struct busdb_record *brec = NULL; + struct udevice *dev = NULL; + + if (bus == NULL || id == NULL) + return NULL; + + brec = busdb_fetch(bus, id); + if (brec == NULL) + return NULL; + + dev = udevdb_get_udevice(brec->name); + free(brec); + + return dev; +} + +/** + * udevdb_get_udevice_by_class + */ +struct udevice *udevdb_get_udevice_by_class(const char *cls, + const char *cls_dev) +{ + struct classdb_record *crec = NULL; + struct udevice *dev = NULL; + + if (cls == NULL || cls_dev == NULL) + return NULL; + + crec = classdb_fetch(cls, cls_dev); + if (crec == NULL) + return NULL; + + dev = udevdb_get_udevice(crec->name); + free(crec); + + return dev; +} diff --git a/udevdb.h b/udevdb.h new file mode 100644 index 0000000000..d2c4a5320e --- /dev/null +++ b/udevdb.h @@ -0,0 +1,41 @@ +/* + * udevdb header file + */ +#ifndef _UDEVDB_H_ +#define _UDEVDB_H_ + +#include "namedev.h" +#include "udev.h" + +#define BUS_DB "/home/stekloff/src/udev-0.2/busdb.tdb" +#define CLASS_DB "/home/stekloff/src/udev-0.2/classdb.tdb" +#define NAME_DB "/home/stekloff/src/udev-0.2/namedb.tdb" + +#define PATH_SIZE 256 + +#define UDEVDB_DEL "#" + +struct udevice { + char name[NAME_SIZE]; + char sysfs_path[PATH_SIZE]; + char class_dev_name[NAME_SIZE]; + char class_name[NAME_SIZE]; + char bus_id[NAME_SIZE]; + char bus_name[NAME_SIZE]; + char driver[NAME_SIZE]; + char type; + int major; + int minor; + int mode; +}; + +/* Function Prototypes */ +extern int udevdb_delete_udevice(const char *name); +extern int udevdb_add_udevice(const struct udevice *dev); +extern struct udevice *udevdb_get_udevice(const char *name); +extern struct udevice *udevdb_get_udevice_by_bus(const char *bus, + const char *id); +extern struct udevice *udevdb_get_udevice_by_class(const char *cls, + const char *cls_dev); + +#endif /* _UDEVDB_H_ */ From a2822451e27dbc576343834e76d5382d5112ac24 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 6 Aug 2003 00:03:30 -0700 Subject: [PATCH 0046/4284] [PATCH] merge tdb into the build process. --- Makefile | 15 +++++++++++---- udev-add.c | 1 + udevdb.c | 3 ++- udevdb.h | 6 +++--- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index a7bb01d247..3f9fef49d5 100644 --- a/Makefile +++ b/Makefile @@ -113,17 +113,23 @@ all: $(LIBC) $(ROOT) $(ARCH_LIB_OBJS) : $(MAKE) -C klibc +LIBSYSFS = libsysfs/libsysfs.a +TDB = tdb/tdb.o tdb/spinlock.o + OBJS = udev.o \ udev-add.o \ udev-remove.o \ + udevdb.o \ logging.o \ - namedev.o - -LIBSYSFS = libsysfs/libsysfs.a + namedev.o \ + $(TDB) libsysfs/libsysfs.a: $(MAKE) -C libsysfs +tdb/tdb.o: + $(MAKE) -C tdb + # header files automatically generated GEN_HEADERS = udev_version.h @@ -132,7 +138,7 @@ udev_version.h: @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ -$(ROOT): $(GEN_HEADERS) $(OBJS) $(LIBSYSFS) +$(ROOT): $(GEN_HEADERS) $(OBJS) $(LIBSYSFS) $(TDB) $(MAKE) -C libsysfs $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) -lsysfs $(LIB_OBJS) -L$(LIB) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) @@ -143,6 +149,7 @@ clean: -rm -f core $(ROOT) $(GEN_HEADERS) $(MAKE) -C klibc clean $(MAKE) -C libsysfs clean + $(MAKE) -C tdb clean DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS ) DISTDIR := $(RELEASE_NAME) diff --git a/udev-add.c b/udev-add.c index 5bd934acd0..c8aa2f70c9 100644 --- a/udev-add.c +++ b/udev-add.c @@ -136,6 +136,7 @@ int udev_add_device(char *device, char *subsystem) { struct sysfs_class_device *class_dev; struct device_attr attr; + struct udevice dbdev; int major; int minor; char type; diff --git a/udevdb.c b/udevdb.c index b200f2f6ed..b976fd50ef 100644 --- a/udevdb.c +++ b/udevdb.c @@ -7,9 +7,10 @@ #include #include #include +#include #include "udevdb.h" -#include "tdb.h" +#include "tdb/tdb.h" static TDB_CONTEXT *busdb; static TDB_CONTEXT *classdb; diff --git a/udevdb.h b/udevdb.h index d2c4a5320e..fed52bc46a 100644 --- a/udevdb.h +++ b/udevdb.h @@ -7,9 +7,9 @@ #include "namedev.h" #include "udev.h" -#define BUS_DB "/home/stekloff/src/udev-0.2/busdb.tdb" -#define CLASS_DB "/home/stekloff/src/udev-0.2/classdb.tdb" -#define NAME_DB "/home/stekloff/src/udev-0.2/namedb.tdb" +#define BUS_DB "/home/greg/src/udev/busdb.tdb" +#define CLASS_DB "/home/greg/src/udev/classdb.tdb" +#define NAME_DB "/home/greg/src/udev/namedb.tdb" #define PATH_SIZE 256 From 99bec174973b08343a0daefe35bbcdc1f263f192 Mon Sep 17 00:00:00 2001 From: "lethal@linux-sh.org" Date: Mon, 11 Aug 2003 21:28:08 -0700 Subject: [PATCH 0047/4284] [PATCH] Fix TDB cross compilation The merge of tdb ended up breaking the ability to cross compile again, here's a bk patch that yanks CC out of the tdb Makefile, and in turn falls back on the exported CC value from the top-level Makefile which correctly sets it based off of the CROSS value. --- tdb/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/tdb/Makefile b/tdb/Makefile index 59fbb079bd..06e31fcc7f 100644 --- a/tdb/Makefile +++ b/tdb/Makefile @@ -3,7 +3,6 @@ # CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1 -CC = gcc PROGS = tdbtest tdbtool tdbtorture TDB_OBJ = tdb.o spinlock.o From e436917d9c7a157d62510fee9a4f80c1f3f77abf Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Wed, 24 Sep 2003 20:56:17 -0700 Subject: [PATCH 0048/4284] [PATCH] print udev pid makes debugging easier. --- logging.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/logging.c b/logging.c index e074b1562c..1ca3aed1a9 100644 --- a/logging.c +++ b/logging.c @@ -21,16 +21,22 @@ */ #include +#include +#include +#include #include #include "udev.h" #ifdef DEBUG static int logging_init = 0; +static unsigned char udev_logname[42]; static void init_logging (void) { - openlog ("udev", 0, LOG_DAEMON); + snprintf(udev_logname,42,"udev[%d]", getpid()); + + openlog (udev_logname, 0, LOG_DAEMON); logging_init = 1; } From dca0297941cd27117c23ea868caa82710a58948c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Oct 2003 06:09:57 -0700 Subject: [PATCH 0049/4284] [PATCH] do not build the tdb binary programs, only the objects. Now it's not necessary to have gdbm to build properly. --- tdb/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tdb/Makefile b/tdb/Makefile index 06e31fcc7f..021cb35c95 100644 --- a/tdb/Makefile +++ b/tdb/Makefile @@ -7,7 +7,9 @@ CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1 PROGS = tdbtest tdbtool tdbtorture TDB_OBJ = tdb.o spinlock.o -default: $(PROGS) +default: $(TDB_OBJ) + +progs: $(PROGS) tdbtest: tdbtest.o $(TDB_OBJ) $(CC) $(CFLAGS) -o tdbtest tdbtest.o $(TDB_OBJ) -lgdbm From 149f210617e812922831e329c347095115585783 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 14 Oct 2003 23:20:18 -0700 Subject: [PATCH 0050/4284] [PATCH] clean up some debugging stuff in namedev.c --- namedev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index d8dba345d1..782b73d0b9 100644 --- a/namedev.c +++ b/namedev.c @@ -21,6 +21,8 @@ * */ +#undef DEBUG + #include #include #include @@ -530,7 +532,7 @@ label_found: } else { *temp = 0x00; temp = strrchr(path, '/'); - dbg("TOPOLOGY temp = '%s' id = '%s'", temp, dev->id); + dbg("NUMBERY temp = '%s' id = '%s'", temp, dev->id); if (strstr(temp, dev->id) != NULL) found = 1; } From dbfc520c605dee3244dbbfd563e908901324689b Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Tue, 14 Oct 2003 23:20:53 -0700 Subject: [PATCH 0051/4284] [PATCH] udevdb patch This patch: 1) removes the three database files for just one udevdb.tdb file. 2) adds udevdb_init() and udevdb_exit() functions 3) initializes database now in main() in udev.c. Please look it over. --- udev.c | 21 +++++-- udevdb.c | 177 +++++++++++++------------------------------------------ udevdb.h | 10 +++- 3 files changed, 63 insertions(+), 145 deletions(-) diff --git a/udev.c b/udev.c index 74572625af..6e7ac25175 100644 --- a/udev.c +++ b/udev.c @@ -31,6 +31,7 @@ #include "udev.h" #include "udev_version.h" #include "namedev.h" +#include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -91,17 +92,27 @@ int main(int argc, char *argv[]) goto exit; } + /* initialize udev database */ + retval = udevdb_init(UDEVDB_DEFAULT); + if (retval != 0) { + dbg("Unable to initialize database."); + goto exit; + } + /* initialize the naming deamon */ namedev_init(); if (strcmp(action, "add") == 0) - return udev_add_device(device, argv[1]); + retval = udev_add_device(device, argv[1]); - if (strcmp(action, "remove") == 0) - return udev_remove_device(device, argv[1]); + else if (strcmp(action, "remove") == 0) + retval = udev_remove_device(device, argv[1]); - dbg("Unknown action: %s", action); - retval = -EINVAL; + else { + dbg("Unknown action: %s", action); + retval = -EINVAL; + } + udevdb_exit(); exit: return retval; diff --git a/udevdb.c b/udevdb.c index b976fd50ef..c2e90be32f 100644 --- a/udevdb.c +++ b/udevdb.c @@ -12,9 +12,7 @@ #include "udevdb.h" #include "tdb/tdb.h" -static TDB_CONTEXT *busdb; -static TDB_CONTEXT *classdb; -static TDB_CONTEXT *namedb; +static TDB_CONTEXT *udevdb; /** * busdb_record - bus and id are keys to look up name of device @@ -48,67 +46,25 @@ struct namedb_record { }; /** - * busdb_close: close busdb database + * udevdb_close: close udev database */ -static void busdb_close(void) +static void udevdb_close(void) { - if (busdb != NULL) { - tdb_close(busdb); - busdb = NULL; + if (udevdb != NULL) { + tdb_close(udevdb); + udevdb = NULL; } } /** - * classdb_close: close classdb database + * udevdb_open: opens udev's database + * @method: database can either be in memory - UDEVDB_INTERNAL - or + * written to a file with UDEVDB_DEFAULT. */ -static void classdb_close(void) +static int udevdb_open(int method) { - if (classdb != NULL) { - tdb_close(classdb); - classdb = NULL; - } -} - -/** - * namedb_close: close name database - */ -static void namedb_close(void) -{ - if (namedb != NULL) { - tdb_close(namedb); - namedb = NULL; - } -} - -/** - * busdb_open: open busdb's database - */ -static int busdb_open(void) -{ - busdb = tdb_open(BUS_DB, 0, 0, O_RDWR | O_CREAT, 0644); - if (busdb == NULL) - return -1; - return 0; -} - -/** - * classdb_open: open classdb's database - */ -static int classdb_open(void) -{ - classdb = tdb_open(CLASS_DB, 0, 0, O_RDWR | O_CREAT, 0644); - if (classdb == NULL) - return -1; - return 0; -} - -/** - * namedb_open: open name database - */ -static int namedb_open(void) -{ - namedb = tdb_open(NAME_DB, 0, 0, O_RDWR | O_CREAT, 0644); - if (namedb == NULL) + udevdb = tdb_open(UDEVDB, 0, method, O_RDWR | O_CREAT, 0644); + if (udevdb == NULL) return -1; return 0; } @@ -127,9 +83,6 @@ static struct busdb_record *busdb_fetch(const char *bus, const char *id) if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE) return NULL; - if ((busdb_open()) != 0) - return NULL; - memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); strcpy(keystr, bus); strcat(keystr, UDEVDB_DEL); @@ -138,8 +91,7 @@ static struct busdb_record *busdb_fetch(const char *bus, const char *id) key.dptr = (void *)keystr; key.dsize = strlen(keystr) + 1; - data = tdb_fetch(busdb, key); - busdb_close(); + data = tdb_fetch(udevdb, key); if (data.dptr == NULL || data.dsize == 0) return NULL; @@ -170,9 +122,6 @@ static struct classdb_record *classdb_fetch(const char *cls, if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE) return NULL; - if ((classdb_open()) != 0) - return NULL; - memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); strcpy(keystr, cls); strcat(keystr, UDEVDB_DEL); @@ -181,8 +130,7 @@ static struct classdb_record *classdb_fetch(const char *cls, key.dptr = (void *)keystr; key.dsize = strlen(keystr) + 1; - data = tdb_fetch(classdb, key); - classdb_close(); + data = tdb_fetch(udevdb, key); if (data.dptr == NULL || data.dsize == 0) return NULL; @@ -212,18 +160,13 @@ static struct namedb_record *namedb_fetch(const char *name) if (strlen(name) >= NAME_SIZE) return NULL; - if ((namedb_open()) != 0) - return NULL; - memset(nm_keystr, 0, NAME_SIZE); strcpy(nm_keystr, name); key.dptr = (void *)nm_keystr; key.dsize = strlen(nm_keystr) + 1; - data = tdb_fetch(namedb, key); - namedb_close(); - + data = tdb_fetch(udevdb, key); if (data.dptr == NULL || data.dsize == 0) return NULL; @@ -252,9 +195,6 @@ static int busdb_store(const struct udevice *dev) if (dev == NULL) return -1; - if ((retval = busdb_open()) != 0) - return -1; - memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); strcpy(keystr, dev->bus_name); strcat(keystr, UDEVDB_DEL); @@ -268,9 +208,7 @@ static int busdb_store(const struct udevice *dev) data.dptr = (void *) &rec; data.dsize = sizeof(rec); - retval = tdb_store(busdb, key, data, TDB_REPLACE); - - busdb_close(); + retval = tdb_store(udevdb, key, data, TDB_REPLACE); return retval; } @@ -287,9 +225,6 @@ static int classdb_store(const struct udevice *dev) if (dev == NULL) return -1; - if ((retval = classdb_open()) != 0) - return -1; - memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); strcpy(keystr, dev->class_name); strcat(keystr, UDEVDB_DEL); @@ -303,9 +238,7 @@ static int classdb_store(const struct udevice *dev) data.dptr = (void *) &rec; data.dsize = sizeof(rec); - retval = tdb_store(classdb, key, data, TDB_REPLACE); - - classdb_close(); + retval = tdb_store(udevdb, key, data, TDB_REPLACE); return retval; } @@ -322,9 +255,6 @@ static int namedb_store(const struct udevice *dev) if (dev == NULL) return -1; - if ((retval = namedb_open()) != 0) - return -1; - memset(keystr, 0, NAME_SIZE); strcpy(keystr, dev->name); @@ -345,9 +275,7 @@ static int namedb_store(const struct udevice *dev) data.dptr = (void *) &rec; data.dsize = sizeof(rec); - retval = tdb_store(namedb, key, data, TDB_REPLACE); - - namedb_close(); + retval = tdb_store(udevdb, key, data, TDB_REPLACE); return retval; } @@ -365,9 +293,6 @@ static int busdb_delete(const char *bus, const char *id) if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE) return -1; - if ((busdb_open()) != 0) - return -1; - memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); strcpy(keystr, bus); strcat(keystr, UDEVDB_DEL); @@ -376,9 +301,7 @@ static int busdb_delete(const char *bus, const char *id) key.dptr = (void *)keystr; key.dsize = strlen(keystr) + 1; - retval = tdb_delete(busdb, key); - busdb_close(); - + retval = tdb_delete(udevdb, key); return retval; } @@ -396,9 +319,6 @@ static int classdb_delete(const char *cls, const char *cls_dev) if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE) return -1; - if ((classdb_open()) != 0) - return -1; - memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); strcpy(keystr, cls); strcat(keystr, UDEVDB_DEL); @@ -407,9 +327,7 @@ static int classdb_delete(const char *cls, const char *cls_dev) key.dptr = (void *)keystr; key.dsize = strlen(keystr) + 1; - retval = tdb_delete(classdb, key); - classdb_close(); - + retval = tdb_delete(udevdb, key); return retval; } @@ -427,47 +345,13 @@ static int namedb_delete(const char *name) if (strlen(name) >= NAME_SIZE) return -1; - if ((namedb_open()) != 0) - return -1; - memset(keystr, 0, NAME_SIZE); strcpy(keystr, name); key.dptr = (void *)keystr; key.dsize = strlen(keystr) + 1; - retval = tdb_delete(namedb, key); - namedb_close(); - - return retval; -} - -/** - * namedb_exists - */ -static int namedb_exists(const char *name) -{ - TDB_DATA key; - char keystr[NAME_SIZE]; - int retval = 0; - - if (name == NULL) - return retval; - if (strlen(name) >= NAME_SIZE) - return retval; - - if ((namedb_open()) != 0) - return retval; - - memset(keystr, 0, NAME_SIZE); - strcpy(keystr, name); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - retval = tdb_exists(namedb, key); - namedb_close(); - + retval = tdb_delete(udevdb, key); return retval; } @@ -590,3 +474,22 @@ struct udevice *udevdb_get_udevice_by_class(const char *cls, return dev; } + +/** + * udevdb_exit: closes database + */ +void udevdb_exit(void) +{ + udevdb_close(); +} + +/** + * udevdb_init: initializes database + */ +int udevdb_init(int init_flag) +{ + if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) + return -1; + + return udevdb_open(init_flag); +} diff --git a/udevdb.h b/udevdb.h index fed52bc46a..a9ba2f93b4 100644 --- a/udevdb.h +++ b/udevdb.h @@ -7,14 +7,16 @@ #include "namedev.h" #include "udev.h" -#define BUS_DB "/home/greg/src/udev/busdb.tdb" -#define CLASS_DB "/home/greg/src/udev/classdb.tdb" -#define NAME_DB "/home/greg/src/udev/namedb.tdb" +#define UDEVDB "/home/greg/src/udev/udevdb.tdb" #define PATH_SIZE 256 #define UDEVDB_DEL "#" +/* Udevdb initialization flags */ +#define UDEVDB_DEFAULT 0 /* Defaults database to use file */ +#define UDEVDB_INTERNAL 1 /* Don't store db on disk, use in memory */ + struct udevice { char name[NAME_SIZE]; char sysfs_path[PATH_SIZE]; @@ -30,6 +32,8 @@ struct udevice { }; /* Function Prototypes */ +extern void udevdb_exit(void); +extern int udevdb_init(int init_flag); extern int udevdb_delete_udevice(const char *name); extern int udevdb_add_udevice(const struct udevice *dev); extern struct udevice *udevdb_get_udevice(const char *name); From c27e69116d3ef0ea069a3c5146009ced08a0238b Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Tue, 14 Oct 2003 23:32:17 -0700 Subject: [PATCH 0052/4284] [PATCH] add callout config type to udev This patch adds a callout config type to udev, so external programs can be called to get serial numbers or id's that are not available as a sysfs attribute. --- namedev.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ namedev.h | 2 + udev.c | 8 +++- udev.h | 2 + 4 files changed, 143 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 782b73d0b9..abed8685c8 100644 --- a/namedev.c +++ b/namedev.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "list.h" #include "udev.h" @@ -42,6 +43,7 @@ #define TYPE_NUMBER "NUMBER" #define TYPE_TOPOLOGY "TOPOLOGY" #define TYPE_REPLACE "REPLACE" +#define TYPE_CALLOUT "CALLOUT" static LIST_HEAD(config_device_list); @@ -78,6 +80,12 @@ static void dump_dev(struct config_device *dev) dev->attr.name, dev->kernel_name, dev->attr.owner, dev->attr.group, dev->attr.mode); break; + case CALLOUT: + dbg("CALLOUT name = '%s', program ='%s', bus = '%s', id = '%s'" + " owner = '%s', group = '%s', mode = '%#o'", + dev->attr.name, dev->exec_program, dev->bus, dev->id, + dev->attr.owner, dev->attr.group, dev->attr.mode); + break; default: dbg("Unknown type of device!"); } @@ -330,6 +338,38 @@ static int namedev_init_config(void) strcpy(dev.attr.name, temp3); dbg("REPLACE name = %s, kernel_name = %s", dev.attr.name, dev.kernel_name); } + if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { + /* number type */ + dev.type = CALLOUT; + + /* PROGRAM="executable" */ + retval = get_value("PROGRAM", &temp, &temp3); + if (retval) + continue; + strcpy(dev.exec_program, temp3); + + /* BUS="bus" */ + temp2 = strsep(&temp, ","); + retval = get_value("BUS", &temp, &temp3); + if (retval) + continue; + strcpy(dev.bus, temp3); + + /* ID="id" */ + temp2 = strsep(&temp, ","); + retval = get_value("ID", &temp, &temp3); + if (retval) + continue; + strcpy(dev.id, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + continue; + strcpy(dev.attr.name, temp3); + dbg("CALLOUT name = %s, program = %s", dev.attr.name, dev.exec_program); + } retval = add_dev(&dev); if (retval) { @@ -417,6 +457,78 @@ static int get_default_mode(struct sysfs_class_device *class_dev) } +static int exec_callout(struct config_device *dev, char *value, int len) +{ + int retval; + int res; + int status; + int fds[2]; + pid_t pid; + int value_set = 0; + char buffer[256]; + + dbg("callout to %s\n", dev->exec_program); + retval = pipe(fds); + if (retval != 0) { + dbg("pipe failed"); + return -1; + } + pid = fork(); + if (pid == -1) { + dbg("fork failed"); + return -1; + } + + if (pid == 0) { + /* + * child + */ + close(STDOUT_FILENO); + dup(fds[1]); /* dup write side of pipe to STDOUT */ + retval = execve(dev->exec_program, main_argv, main_envp); + if (retval != 0) { + dbg("child execve failed"); + exit(1); + } + return -1; /* avoid compiler warning */ + } else { + /* + * Parent reads from fds[0]. + */ + close(fds[1]); + retval = 0; + while (1) { + res = read(fds[0], buffer, sizeof(buffer) - 1); + if (res <= 0) + break; + buffer[res] = '\0'; + if (res > len) { + dbg("callout len %d too short\n", len); + retval = -1; + } + if (value_set) { + dbg("callout value already set"); + retval = -1; + } else { + value_set = 1; + strncpy(value, buffer, len); + } + } + close(fds[0]); + res = wait(&status); + if (res < 0) { + dbg("wait failed result %d", res); + retval = -1; + } + + if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { + dbg("callout program status 0x%x", status); + retval = -1; + } + } + return retval; +} + static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *attr) { struct list_head *tmp; @@ -587,6 +699,26 @@ label_found: goto done; break; } + case CALLOUT: + { + char value[ID_SIZE]; + + if (exec_callout(dev, value, sizeof(value))) + continue; + if (strncmp(value, dev->id, sizeof(value)) != 0) + continue; + strcpy(attr->name, dev->attr.name); + if (dev->attr.mode != 0) { + attr->mode = dev->attr.mode; + strcpy(attr->owner, dev->attr.owner); + strcpy(attr->group, dev->attr.group); + } + dbg("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->id, attr->name, + dev->attr.owner, dev->attr.group, dev->attr.mode); + goto done; + break; + } case REPLACE: if (strcmp(dev->kernel_name, class_dev->name) != 0) continue; diff --git a/namedev.h b/namedev.h index d986a2376d..1f535c4c8b 100644 --- a/namedev.h +++ b/namedev.h @@ -40,6 +40,7 @@ enum config_type { NUMBER = 2, TOPOLOGY = 3, REPLACE = 4, + CALLOUT = 5, }; #define BUS_SIZE 30 @@ -60,6 +61,7 @@ struct config_device { char id[ID_SIZE]; char place[PLACE_SIZE]; char kernel_name[NAME_SIZE]; + char exec_program[FILE_SIZE]; /* what to set the device to */ struct device_attr attr; diff --git a/udev.c b/udev.c index 6e7ac25175..0aba8c4bf9 100644 --- a/udev.c +++ b/udev.c @@ -52,13 +52,19 @@ static char *get_device(void) return device; } -int main(int argc, char *argv[]) +char **main_argv; +char **main_envp; + +int main(int argc, char **argv, char **envp) { char *action; char *device; char *subsystem; int retval = -EINVAL; + main_argv = argv; + main_envp = envp; + if (argc != 2) { dbg ("unknown number of arguments"); goto exit; diff --git a/udev.h b/udev.h index 590a8ed039..e9fc2e46eb 100644 --- a/udev.h +++ b/udev.h @@ -57,5 +57,7 @@ struct device_attr { extern int udev_add_device(char *device, char *subsystem); extern int udev_remove_device(char *device, char *subsystem); +extern char **main_argv; +extern char **main_envp; #endif From 6739707df53097ac378f8ff2f0aa694257e31da1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 15 Oct 2003 23:50:13 -0700 Subject: [PATCH 0053/4284] [PATCH] put config files and database in /etc/udev by default Can be overridden on the makefile line. --- Makefile | 14 +++++++++++--- namedev.h | 1 - udev.h | 16 ++++++++++++---- udevdb.c | 14 +++++++++++--- udevdb.h | 5 +---- 5 files changed, 35 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 3f9fef49d5..92b3dc7465 100644 --- a/Makefile +++ b/Makefile @@ -22,10 +22,16 @@ DEBUG = true ROOT = udev -VERSION = 0.2 +VERSION = 003 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) +# override this to make udev look in a different location for it's config files +PREFIX = +CONFIG_DIR = $(PREFIX)/etc/udev/ + +# place to put our device nodes +UDEV_DIR = /udev/ # Comment out this line to build with something other # than the local version of klibc @@ -135,7 +141,9 @@ GEN_HEADERS = udev_version.h # Rules on how to create the generated header files udev_version.h: - @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + @echo \#define UDEV_CONFIG_DIR \"$(CONFIG_DIR)\" >> $@ + @echo \#define UDEV_ROOT \"$(UDEV_DIR)\" >> $@ $(ROOT): $(GEN_HEADERS) $(OBJS) $(LIBSYSFS) $(TDB) @@ -151,7 +159,7 @@ clean: $(MAKE) -C libsysfs clean $(MAKE) -C tdb clean -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS ) +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v ".tdb" ) DISTDIR := $(RELEASE_NAME) srcdir = . release: $(DISTFILES) clean diff --git a/namedev.h b/namedev.h index 1f535c4c8b..567756c827 100644 --- a/namedev.h +++ b/namedev.h @@ -30,7 +30,6 @@ struct sysfs_class_device; /* namedev config files */ #define COMMENT_CHARACTER '#' -#define NAMEDEV_CONFIG_ROOT "/home/greg/src/udev/" #define NAMEDEV_CONFIG_PERMISSION_FILE "namedev.permissions" #define NAMEDEV_CONFIG_FILE "namedev.config" diff --git a/udev.h b/udev.h index e9fc2e46eb..33cb89af55 100644 --- a/udev.h +++ b/udev.h @@ -34,15 +34,23 @@ #define dbg(format, arg...) do { } while (0) #endif +/* Parser needs it's own debugging statement, we usually don't care about this at all */ +#ifdef DEBUG_PARSER +#define dbg_parse(format, arg...) \ + do { \ + log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + } while (0) +#else + #define dbg_parse(format, arg...) do { } while (0) +#endif -/* Lots of constants that should be in a config file sometime */ - -/* Where udev should create its device nodes, trailing / needed */ -#define UDEV_ROOT "/udev/" extern int log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); + +/* Lots of constants that should be in a config file sometime */ + #define NAME_SIZE 100 #define OWNER_SIZE 30 #define GROUP_SIZE 30 diff --git a/udevdb.c b/udevdb.c index c2e90be32f..db5bb73de9 100644 --- a/udevdb.c +++ b/udevdb.c @@ -9,6 +9,9 @@ #include #include +#include "udev_version.h" +#include "udev.h" +#include "namedev.h" #include "udevdb.h" #include "tdb/tdb.h" @@ -63,9 +66,14 @@ static void udevdb_close(void) */ static int udevdb_open(int method) { - udevdb = tdb_open(UDEVDB, 0, method, O_RDWR | O_CREAT, 0644); - if (udevdb == NULL) - return -1; + udevdb = tdb_open(UDEV_CONFIG_DIR UDEV_DB, 0, method, O_RDWR | O_CREAT, 0644); + if (udevdb == NULL) { + if (method == UDEVDB_INTERNAL) + dbg("Unable to initialize in-memory database"); + else + dbg("Unable to initialize database at %s", UDEV_CONFIG_DIR UDEV_DB); + return -EINVAL; + } return 0; } diff --git a/udevdb.h b/udevdb.h index a9ba2f93b4..089af2972b 100644 --- a/udevdb.h +++ b/udevdb.h @@ -4,10 +4,7 @@ #ifndef _UDEVDB_H_ #define _UDEVDB_H_ -#include "namedev.h" -#include "udev.h" - -#define UDEVDB "/home/greg/src/udev/udevdb.tdb" +#define UDEV_DB "udevdb.tdb" #define PATH_SIZE 256 From 5ef7b7992a5c8ea26c2a16a251bf93526b52559b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 15 Oct 2003 23:50:50 -0700 Subject: [PATCH 0054/4284] [PATCH] add dbg_parse() to cut down on parse file debugging statements Can be turned on by hand in the namedev.c file. --- namedev.c | 90 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 50 insertions(+), 40 deletions(-) diff --git a/namedev.c b/namedev.c index abed8685c8..6f69959346 100644 --- a/namedev.c +++ b/namedev.c @@ -21,7 +21,8 @@ * */ -#undef DEBUG +/* define this to enable parsing debugging */ +/* #define DEBUG_PARSER */ #include #include @@ -51,43 +52,43 @@ static void dump_dev(struct config_device *dev) { switch (dev->type) { case KERNEL_NAME: - dbg("KERNEL name ='%s'" + dbg_parse("KERNEL name ='%s'" " owner = '%s', group = '%s', mode = '%#o'", dev->attr.name, dev->attr.owner, dev->attr.group, dev->attr.mode); break; case LABEL: - dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" + dbg_parse("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" " owner = '%s', group = '%s', mode = '%#o'", dev->attr.name, dev->bus, dev->sysfs_file, dev->sysfs_value, dev->attr.owner, dev->attr.group, dev->attr.mode); break; case NUMBER: - dbg("NUMBER name = '%s', bus = '%s', id = '%s'" + dbg_parse("NUMBER name = '%s', bus = '%s', id = '%s'" " owner = '%s', group = '%s', mode = '%#o'", dev->attr.name, dev->bus, dev->id, dev->attr.owner, dev->attr.group, dev->attr.mode); break; case TOPOLOGY: - dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'" + dbg_parse("TOPOLOGY name = '%s', bus = '%s', place = '%s'" " owner = '%s', group = '%s', mode = '%#o'", dev->attr.name, dev->bus, dev->place, dev->attr.owner, dev->attr.group, dev->attr.mode); break; case REPLACE: - dbg("REPLACE name = %s, kernel_name = %s" + dbg_parse("REPLACE name = %s, kernel_name = %s" " owner = '%s', group = '%s', mode = '%#o'", dev->attr.name, dev->kernel_name, dev->attr.owner, dev->attr.group, dev->attr.mode); break; case CALLOUT: - dbg("CALLOUT name = '%s', program ='%s', bus = '%s', id = '%s'" + dbg_parse("CALLOUT name = '%s', program ='%s', bus = '%s', id = '%s'" " owner = '%s', group = '%s', mode = '%#o'", dev->attr.name, dev->exec_program, dev->bus, dev->id, dev->attr.owner, dev->attr.group, dev->attr.mode); break; default: - dbg("Unknown type of device!"); + dbg_parse("Unknown type of device!"); } } @@ -205,7 +206,7 @@ static int namedev_init_config(void) int retval = 0; struct config_device dev; - strcpy(filename, NAMEDEV_CONFIG_ROOT NAMEDEV_CONFIG_FILE); + strcpy(filename, UDEV_CONFIG_DIR NAMEDEV_CONFIG_FILE); dbg("opening %s to read as permissions config", filename); fd = fopen(filename, "r"); if (fd == NULL) { @@ -220,7 +221,7 @@ static int namedev_init_config(void) if (temp == NULL) break; - dbg("read %s", temp); + dbg_parse("read %s", temp); /* eat the whitespace at the beginning of the line */ while (isspace(*temp)) @@ -263,7 +264,10 @@ static int namedev_init_config(void) continue; strcpy(dev.attr.name, temp3); - dbg("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'", dev.attr.name, dev.bus, dev.sysfs_file, dev.sysfs_value); + dbg_parse("LABEL name = '%s', bus = '%s', " + "sysfs_file = '%s', sysfs_value = '%s'", + dev.attr.name, dev.bus, dev.sysfs_file, + dev.sysfs_value); } if (strcasecmp(temp2, TYPE_NUMBER) == 0) { @@ -290,7 +294,8 @@ static int namedev_init_config(void) continue; strcpy(dev.attr.name, temp3); - dbg("NUMBER name = '%s', bus = '%s', id = '%s'", dev.attr.name, dev.bus, dev.id); + dbg_parse("NUMBER name = '%s', bus = '%s', id = '%s'", + dev.attr.name, dev.bus, dev.id); } if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { @@ -317,7 +322,8 @@ static int namedev_init_config(void) continue; strcpy(dev.attr.name, temp3); - dbg("TOPOLOGY name = '%s', bus = '%s', place = '%s'", dev.attr.name, dev.bus, dev.place); + dbg_parse("TOPOLOGY name = '%s', bus = '%s', place = '%s'", + dev.attr.name, dev.bus, dev.place); } if (strcasecmp(temp2, TYPE_REPLACE) == 0) { @@ -336,7 +342,8 @@ static int namedev_init_config(void) if (retval) continue; strcpy(dev.attr.name, temp3); - dbg("REPLACE name = %s, kernel_name = %s", dev.attr.name, dev.kernel_name); + dbg_parse("REPLACE name = %s, kernel_name = %s", + dev.attr.name, dev.kernel_name); } if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { /* number type */ @@ -368,7 +375,8 @@ static int namedev_init_config(void) if (retval) continue; strcpy(dev.attr.name, temp3); - dbg("CALLOUT name = %s, program = %s", dev.attr.name, dev.exec_program); + dbg_parse("CALLOUT name = %s, program = %s", + dev.attr.name, dev.exec_program); } retval = add_dev(&dev); @@ -394,7 +402,7 @@ static int namedev_init_permissions(void) int retval = 0; struct config_device dev; - strcpy(filename, NAMEDEV_CONFIG_ROOT NAMEDEV_CONFIG_PERMISSION_FILE); + strcpy(filename, UDEV_CONFIG_DIR NAMEDEV_CONFIG_PERMISSION_FILE); dbg("opening %s to read as permissions config", filename); fd = fopen(filename, "r"); if (fd == NULL) { @@ -409,7 +417,7 @@ static int namedev_init_permissions(void) if (temp == NULL) break; - dbg("read %s", temp); + dbg_parse("read %s", temp); /* eat the whitespace at the beginning of the line */ while (isspace(*temp)) @@ -437,7 +445,8 @@ static int namedev_init_permissions(void) dev.attr.mode = strtol(temp, NULL, 8); - dbg("name = %s, owner = %s, group = %s, mode = %#o", dev.attr.name, dev.attr.owner, dev.attr.group, dev.attr.mode); + dbg_parse("name = %s, owner = %s, group = %s, mode = %#o", + dev.attr.name, dev.attr.owner, dev.attr.group, dev.attr.mode); retval = add_dev(&dev); if (retval) { dbg("add_dev returned with error %d", retval); @@ -537,10 +546,10 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at attr->mode = -1; if (class_dev->sysdevice) { - dbg("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); - dbg("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); + dbg_parse("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); + dbg_parse("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); } else { - dbg("class_dev->name = '%s'", class_dev->name); + dbg_parse("class_dev->name = '%s'", class_dev->name); } list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); @@ -549,7 +558,8 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at { char *temp; - dbg("LABEL: match file '%s' with value '%s'", dev->sysfs_file, dev->sysfs_value); + dbg_parse("LABEL: match file '%s' with value '%s'", + dev->sysfs_file, dev->sysfs_value); /* try to find the attribute in the class device directory */ temp = sysfs_get_value_from_attributes(class_dev->directory->attributes, dev->sysfs_file); if (temp) @@ -567,22 +577,22 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at * up in the kernel... */ if (strstr(class_dev->directory->path, "block")) { - dbg("looking at block device..."); + dbg_parse("looking at block device..."); if (isdigit(class_dev->directory->path[strlen(class_dev->directory->path)-1])) { char path[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev_parent; - dbg("really is a partition..."); + dbg_parse("really is a partition..."); strcpy(path, class_dev->directory->path); temp = strrchr(path, '/'); *temp = 0x00; - dbg("looking for a class device at '%s'", path); + dbg_parse("looking for a class device at '%s'", path); class_dev_parent = sysfs_open_class_device(path); if (class_dev_parent == NULL) { - dbg ("sysfs_open_class_device failed"); + dbg("sysfs_open_class_device at '%s' failed", path); continue; } - dbg("class_dev_parent->name = %s", class_dev_parent->name); + dbg_parse("class_dev_parent->name = %s", class_dev_parent->name); /* try to find the attribute in the class device directory */ temp = sysfs_get_value_from_attributes(class_dev_parent->directory->attributes, dev->sysfs_file); @@ -606,7 +616,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at label_found: temp[strlen(temp)-1] = 0x00; - dbg("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, temp, dev->sysfs_value); + dbg_parse("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, temp, dev->sysfs_value); if (strcmp(dev->sysfs_value, temp) != 0) continue; @@ -621,7 +631,7 @@ label_found: strcpy(attr->owner, dev->attr.owner); strcpy(attr->group, dev->attr.group); } - dbg("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->sysfs_file, dev->sysfs_value, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); goto done; @@ -637,14 +647,14 @@ label_found: continue; strcpy(path, class_dev->sysdevice->directory->path); temp = strrchr(path, '/'); - dbg("NUMBER path = '%s'", path); - dbg("NUMBER temp = '%s' id = '%s'", temp, dev->id); + dbg_parse("NUMBER path = '%s'", path); + dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); if (strstr(temp, dev->id) != NULL) { found = 1; } else { *temp = 0x00; temp = strrchr(path, '/'); - dbg("NUMBERY temp = '%s' id = '%s'", temp, dev->id); + dbg_parse("NUMBERY temp = '%s' id = '%s'", temp, dev->id); if (strstr(temp, dev->id) != NULL) found = 1; } @@ -657,7 +667,7 @@ label_found: strcpy(attr->owner, dev->attr.owner); strcpy(attr->group, dev->attr.group); } - dbg("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dbg_parse("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->id, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); goto done; @@ -673,14 +683,14 @@ label_found: found = 0; strcpy(path, class_dev->sysdevice->directory->path); temp = strrchr(path, '/'); - dbg("TOPOLOGY path = '%s'", path); - dbg("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + dbg_parse("TOPOLOGY path = '%s'", path); + dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); if (strstr(temp, dev->place) != NULL) { found = 1; } else { *temp = 0x00; temp = strrchr(path, '/'); - dbg("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); if (strstr(temp, dev->place) != NULL) found = 1; } @@ -693,7 +703,7 @@ label_found: strcpy(attr->owner, dev->attr.owner); strcpy(attr->group, dev->attr.group); } - dbg("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dbg_parse("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->place, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); goto done; @@ -713,7 +723,7 @@ label_found: strcpy(attr->owner, dev->attr.owner); strcpy(attr->group, dev->attr.group); } - dbg("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dbg_parse("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->id, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); goto done; @@ -728,7 +738,7 @@ label_found: strcpy(attr->owner, dev->attr.owner); strcpy(attr->group, dev->attr.group); } - dbg("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dbg_parse("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->kernel_name, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); goto done; @@ -736,7 +746,7 @@ label_found: case KERNEL_NAME: break; default: - dbg("Unknown type of device '%d'", dev->type); + dbg_parse("Unknown type of device '%d'", dev->type); break; } } From 8479066ec7dd5824a3fe5bf08bb5f9d2e14d8837 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 15 Oct 2003 23:51:11 -0700 Subject: [PATCH 0055/4284] [PATCH] tell the user what mknod() we are trying to do. --- udev-add.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev-add.c b/udev-add.c index c8aa2f70c9..48979393a5 100644 --- a/udev-add.c +++ b/udev-add.c @@ -93,6 +93,7 @@ static int create_node(char *name, char type, int major, int minor, int mode) return -EINVAL; } + dbg("mknod(%s, %#o, %u, %u)", filename, mode, major, minor); retval = mknod(filename,mode,makedev(major,minor)); if (retval) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", From 2e5a8b99f89f30ee06b39da7dee024a7361b9886 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 15 Oct 2003 23:51:27 -0700 Subject: [PATCH 0056/4284] [PATCH] add version to debug log on startup. --- udev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev.c b/udev.c index 0aba8c4bf9..a398477118 100644 --- a/udev.c +++ b/udev.c @@ -65,6 +65,8 @@ int main(int argc, char **argv, char **envp) main_argv = argv; main_envp = envp; + dbg("version %s", UDEV_VERSION); + if (argc != 2) { dbg ("unknown number of arguments"); goto exit; From 9f53b06a8da90b88c02f943502ea3cfdf8801087 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 16 Oct 2003 21:18:40 -0700 Subject: [PATCH 0057/4284] [PATCH] added install target for makefile so people don't have to do it by hand anymore. --- Makefile | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 92b3dc7465..fabb81b2c3 100644 --- a/Makefile +++ b/Makefile @@ -27,11 +27,23 @@ INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) # override this to make udev look in a different location for it's config files -PREFIX = -CONFIG_DIR = $(PREFIX)/etc/udev/ +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +mandir = ${prefix}/usr/share/man +hotplugdir = ${etcdir}/hotplug.d/default +configdir = ${etcdir}/udev/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + # place to put our device nodes -UDEV_DIR = /udev/ +udevdir = ${prefix}/udev/ # Comment out this line to build with something other # than the local version of klibc @@ -142,8 +154,8 @@ GEN_HEADERS = udev_version.h # Rules on how to create the generated header files udev_version.h: @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ - @echo \#define UDEV_CONFIG_DIR \"$(CONFIG_DIR)\" >> $@ - @echo \#define UDEV_ROOT \"$(UDEV_DIR)\" >> $@ + @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ + @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ $(ROOT): $(GEN_HEADERS) $(OBJS) $(LIBSYSFS) $(TDB) @@ -159,7 +171,7 @@ clean: $(MAKE) -C libsysfs clean $(MAKE) -C tdb clean -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v ".tdb" ) +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v ".tdb" | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . release: $(DISTFILES) clean @@ -177,3 +189,14 @@ release: $(DISTFILES) clean @tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz @rm -rf $(DISTDIR) @echo "Built $(RELEASE_NAME).tar.gz" + + +install: all + $(INSTALL) -d $(udevdir) + $(INSTALL) -d $(configdir) + $(INSTALL) -d $(hotplugdir) + $(INSTALL_PROGRAM) -D $(ROOT) $(sbindir)/$(ROOT) + $(INSTALL_DATA) -D udev.8 $(mandir)/man8/udev.8 + $(INSTALL_DATA) namedev.config $(configdir) + $(INSTALL_DATA) namedev.permissions $(configdir) + - ln -s $(sbindir)/$(ROOT) $(hotplugdir)/udev.hotplug From 6785820d3889863e4c34428d582726b0572a261a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 00:19:04 -0700 Subject: [PATCH 0058/4284] [PATCH] added uninstall support --- Makefile | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Makefile b/Makefile index fabb81b2c3..5523a48609 100644 --- a/Makefile +++ b/Makefile @@ -200,3 +200,15 @@ install: all $(INSTALL_DATA) namedev.config $(configdir) $(INSTALL_DATA) namedev.permissions $(configdir) - ln -s $(sbindir)/$(ROOT) $(hotplugdir)/udev.hotplug + +uninstall: + - rm $(hotplugdir)/udev.hotplug + - rm $(configdir)/namedev.permissions + - rm $(configdir)/namedev.config + - rm $(mandir)/man8/udev.8 + - rm $(sbindir)/$(ROOT) + - rmdir $(hotplugdir) + - rmdir $(configdir) + - rmdir $(udevdir) + + From 04db8c9e06986f0406f4f7cd9a2245e35dd5db9f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 00:29:17 -0700 Subject: [PATCH 0059/4284] [PATCH] add udev man page (basically just a place holder for now.) --- udev.8 | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 udev.8 diff --git a/udev.8 b/udev.8 new file mode 100644 index 0000000000..e44855ba16 --- /dev/null +++ b/udev.8 @@ -0,0 +1,26 @@ +.TH UDEV 8 "October 2003" "" "Linux Programmer's Manual" +.SH NAME +udev \- Linux dynamic device naming support +.SH SYNOPSIS +.B udev +.SH "DESCRIPTION" +.B udev +is a wonderful program whose man page has not been written yet. +.SH "FILES" +.nf +.ft B +.ft +/sbin/udev udev program +/etc/udev/* udev config and database files +/etc/hotplug.d/default/udev.hotplug hotplug symlink to udev program +.fi +.LP +.SH "SEE ALSO" +.BR hotplug "(8)" +.PP +The +.I http://linux-hotplug.sourceforge.net/ +web site. +.SH AUTHORS +udev was developed by Greg Kroah-Hartman with much help from +Dan Stekloff and many others. From fc1c2fd8b1815d7fa8f31cd858f553c557065c39 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 00:44:14 -0700 Subject: [PATCH 0060/4284] [PATCH] updated the TODO list. --- TODO | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/TODO b/TODO index 0bcaf2cc24..b05ad0c51b 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,29 @@ -- use mknod(2) and not execute mknod(1) +This is a short list of things that needs to be done. They are in no specific +order. I will gladly accept patches for any of these items, or any other stuff +people offer up. + + Greg Kroah-Hartman + + +- more documentation (can never have too much.) +- document the config file format (it will change over time...) +- add proper man page - add klibc to the build process (or make it easier to do) to get smaller binary -- document the config file format (it will change over time...) -- persistant naming database backend +- import latest libsysfs and convert udev to use it. +- On remove, look up the device in the database (now that we have one) and + delete what was created, not what the kernel is calling the device. +- add symlink generation and removal support +- better partition support (it's a hack right now, maybe new libsysfs changes + can help out a lot here.) +- allow database to be queried by other programs +- split program into two pieces (daemon and helper that sends events to it). + This will allow us to keep track of sequences, and lots of other needed + stuff. +- keep track of current permissions on devices when daemon shuts down. +- better permission handling +- create kernel name to devfs name config file so that all of the devfs users + will have an upgrade path. - make program work like design says it should (three parts, not 1) - add hooks to call D-BUS when new node is created or removed - lots of other stuff... From bf3ca56fd4685a52ae66ed6ee05ec4705130b9fe Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 01:39:19 -0700 Subject: [PATCH 0061/4284] [PATCH] Updatd the README --- README | 49 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/README b/README index 07fa162bbd..ed25a733ab 100644 --- a/README +++ b/README @@ -6,32 +6,47 @@ files in the docs/ directory. To use: -- Edit the udev.h file and replace the following variables with values - that make sense for your system: - #define UDEV_ROOT "/udev/" - #define MKNOD "/bin/mknod" - The only value most people will have to change is the UDEV_ROOT - variable, as I doubt you really want device nodes to be created in my - home directory :) +- You must be running a 2.6 version of the Linux kernel. -- Run make to build the project. +- Make sure sysfs is mounted. udev will figure out where sysfs is mounted, but + the traditional place for it is at /sys. You can mount it by hand by running: + mount -t sysfs none /sys -- Make sure sysfs is mounted. +- Make sure you have the latest version of the linux-hotplug scripts. They are + available at linux-hotplug.sf.net or from your local kernel.org mirror at: + kernel.org/pub/linux/utils/kernel/hotplug/ + They are required in order for udev to work properly. -- Point /proc/sys/kernel/hotplug at the location of the udev binary that - is created. Then plug some block devices in, or other types of - devices that create dev files in sysfs. An easy way to do this, - without any hardware is to use the scsi_debug module to create virtual - scsi devices. + If for some reason you do not install the hotplug scripts, you must tell the + kernel to point the hotplug binary at wherever you install udev at. This can + be done by: + echo "/sbin/udev" > /proc/sys/kernel/hotplug -- Watch as the nodes get created and removed. +- Build the project: + make + +- Install the project: + make install + + This will put the udev binary in /sbin, create the /udev and /etc/udev + directories, and place the udev configuration files in /etc/udev. You + will probably want to edit the namedev.* files to create custom naming + rules. More info on how the config files are set up are contained in + comments in the files, and is located in the documentation. + +- Add and remove devices from the system and marvel as nodes are created + and removed in /udev/ based on the device types. + +- If you later get sick of it, uninstall it: + make uninstall -Yes this is a really rough first cut, I know. It's mostly a proof of -concept that this can actually work. See the TODO file for a list of +Things are still quite rough, and it's a bit beyond proof of concept +code. Help is very much appreciated, see the TODO file for a list of things left to be done. Any comment/questions/concerns please let me know. greg k-h greg@kroah.com + From cd74c8e2022977ab560b40bedafa4e09abcb26aa Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 01:39:29 -0700 Subject: [PATCH 0062/4284] [PATCH] TODO updates --- TODO | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index b05ad0c51b..89fe6679d4 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,8 @@ This is a short list of things that needs to be done. They are in no specific order. I will gladly accept patches for any of these items, or any other stuff people offer up. - Greg Kroah-Hartman +greg k-h +greg@kroah.com - more documentation (can never have too much.) @@ -24,6 +25,7 @@ people offer up. - better permission handling - create kernel name to devfs name config file so that all of the devfs users will have an upgrade path. -- make program work like design says it should (three parts, not 1) +- do early boot logic (putting udev into initramfs, handle pivot-root, + etc.) - add hooks to call D-BUS when new node is created or removed - lots of other stuff... From c9e6dc553b218d06170863f17f4c82c77ca28f81 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 01:39:47 -0700 Subject: [PATCH 0063/4284] [PATCH] Add AUTHORS and INSTALL files. --- AUTHORS | 4 ++++ INSTALL | 1 + 2 files changed, 5 insertions(+) create mode 100644 AUTHORS create mode 100644 INSTALL diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000000..f15b702f34 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +Greg Kroah-Hartman +Dan Stekloff + +Your name should go here, just sent patches... diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000000..cc877be1a0 --- /dev/null +++ b/INSTALL @@ -0,0 +1 @@ +Read the README file for how to install udev. From 8dfc8dbe013124f06df74bad4e8e648348b1db39 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 01:40:02 -0700 Subject: [PATCH 0064/4284] [PATCH] copyright updates. --- Makefile | 4 ++-- udevdb.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5523a48609..c426a881e6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -# Makefile for diethotplug +# Makefile for udev # -# Copyright (C) 2000,2001 Greg Kroah-Hartman +# Copyright (C) 2003 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 diff --git a/udevdb.c b/udevdb.c index db5bb73de9..fb34ca61d3 100644 --- a/udevdb.c +++ b/udevdb.c @@ -1,3 +1,26 @@ +/* + * udevdb.c + * + * Userspace devfs + * + * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003 IBM Corp. + * + * 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. + * + */ + /* * udev database library */ From 4846106645b4df43791f918155b3bcec655e0e4f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 05:05:04 -0700 Subject: [PATCH 0065/4284] [PATCH] removed AUTHORS and INSTALL files as they were pretty pointless. --- AUTHORS | 4 ---- INSTALL | 1 - 2 files changed, 5 deletions(-) delete mode 100644 AUTHORS delete mode 100644 INSTALL diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index f15b702f34..0000000000 --- a/AUTHORS +++ /dev/null @@ -1,4 +0,0 @@ -Greg Kroah-Hartman -Dan Stekloff - -Your name should go here, just sent patches... diff --git a/INSTALL b/INSTALL deleted file mode 100644 index cc877be1a0..0000000000 --- a/INSTALL +++ /dev/null @@ -1 +0,0 @@ -Read the README file for how to install udev. From b1830e7984e86c5765a67a3aae4b63e1c48155b6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 05:55:24 -0700 Subject: [PATCH 0066/4284] [PATCH] Add FAQ for udev --- FAQ | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 FAQ diff --git a/FAQ b/FAQ new file mode 100644 index 0000000000..c082a5bec4 --- /dev/null +++ b/FAQ @@ -0,0 +1,75 @@ +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 /sbin/hotplug calls that the + kernel makes whenever a device is added or removed from the kernel. All + naming policy, and permission control is done in userspace. devfs + operated from within the kernel. + +Q: Why was devfs marked OBSOLETE if udev is not finished yet? +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 stoped 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: If you really require this functionality, then use devfs. It is still + present in the kernel. + +Q: But I really like the devfs naming scheme, will udev do that? +A: Yes, udev can create /dev nodes using the devfs naming policy. A + configuration file needs to be created to map the kernel default names + to the devfs names. Such a configuration file would be gladly added to + the udev package if it is provided by anyone who can create such a + mapping. + +Q: What kinds of devices does udev create nodes for? +A: All devices that are shown in sysfs will work with udev. If more + support is added for devices to the kernel, udev will automatically + start working for them. All block devices are currently supported, and + almost all major char devices are supported. Kernel developers are + working on adding support for all char devices at this time. See the + linux-kernel mailing list for patches and status of these patches. + +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: Will udev support symlinks? +A: Yes, patches are gladly accepted to add this functionality. + +Q: How will udev support changes to device permissions? +A: On shutdown, udev will save the state of existing device permissions to + its database, and then used the on the next boot time. + +Q: How will udev handle the /dev filesystem? +A: /dev can be a ramfs, or a backing filesystem. udev does not care what + kind of filesystem it runs on. + +Q: How will udev handle devices found before init runs? +A: udev will be placed in initramfs and run for every device that is found. + Work to get this implemented is still underway. + +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 + + Archives of the mailing list can be found at: + + From d3069ca3b71160cd7e89b3ff9d411ce2d7971610 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 06:12:52 -0700 Subject: [PATCH 0067/4284] [PATCH] fix makefile release rule to not drop tdb.h file. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c426a881e6..493cd08450 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,7 @@ clean: $(MAKE) -C libsysfs clean $(MAKE) -C tdb clean -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v ".tdb" | sort ) +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . release: $(DISTFILES) clean From 221204964609fec81f50a6c411f276c88f412755 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 06:14:02 -0700 Subject: [PATCH 0068/4284] [PATCH] update the spec file for the new version and install process. Spec file still does not install all of the proper files. --- udev.spec | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/udev.spec b/udev.spec index fe6ca84cc3..07b608ed6d 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 0.2 +Version: 003 Release: 1 License: GPL Group: Utilities/System @@ -11,7 +11,7 @@ BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root %description udev is a implementation of devfs in userspace using sysfs and -/sbin/hotplug. It requires a 2.5/2.6 kernel to run properly. +/sbin/hotplug. It requires a 2.6 kernel to run properly. %prep %setup @@ -20,8 +20,7 @@ udev is a implementation of devfs in userspace using sysfs and make %install -mkdir -p $RPM_BUILD_ROOT/sbin -install -m 755 %{name} $RPM_BUILD_ROOT/sbin +make prefix=$RPM_BUILD_ROOT install %clean rm -fr $RPM_BUILD_ROOT From 22b000237951ce98b2ab77540e4bf2e6b1e91582 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 06:32:01 -0700 Subject: [PATCH 0069/4284] [PATCH] update changelog for 003 release --- ChangeLog | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 104 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index a0bd85174b..fa72db5c20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,106 @@ -0.2 - added namedev - now used a snapshot of libsysfs. - Can now handle the 5 different naming schemes. - Was released based on my OLS 2003 presentation. - Lots still left to do, but it kinda works better... +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 -0.1 - Added a bit of documentation to the README and TODO files. -0.01 - initial release From 1c596cc0a5357105a80ab07f0ebbe2eb330b2c28 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 19:26:07 -0700 Subject: [PATCH 0070/4284] [PATCH] fix segfaults when dealing with partitions. --- udev-add.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/udev-add.c b/udev-add.c index 48979393a5..6060bcf5f7 100644 --- a/udev-add.c +++ b/udev-add.c @@ -169,13 +169,13 @@ int udev_add_device(char *device, char *subsystem) } memset(&dbdev, 0, sizeof(dbdev)); strncpy(dbdev.name, attr.name, NAME_SIZE); - strncpy(dbdev.sysfs_path, class_dev->sysdevice->directory->path, - PATH_SIZE); + if (class_dev->sysdevice) { + strncpy(dbdev.sysfs_path, class_dev->sysdevice->directory->path, PATH_SIZE); + strncpy(dbdev.bus_id, class_dev->sysdevice->bus_id, ID_SIZE); + } strncpy(dbdev.class_dev_name, class_dev->name, NAME_SIZE); - if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) - != 0) + if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) != 0) strcpy(dbdev.class_name, "unkown"); - strncpy(dbdev.bus_id, class_dev->sysdevice->bus_id, ID_SIZE); strcpy(dbdev.bus_name, "unknown"); if (class_dev->driver != NULL) strncpy(dbdev.driver, class_dev->driver->name, NAME_SIZE); From ca9998602336f67eb2590819eecf416977885e2a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 23:32:17 -0700 Subject: [PATCH 0071/4284] [PATCH] got "remove of named devices" working. database code still needs some major cleanup. --- udev-add.c | 31 +++--------- udev-remove.c | 5 ++ udevdb.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++---- udevdb.h | 5 +- 4 files changed, 135 insertions(+), 36 deletions(-) diff --git a/udev-add.c b/udev-add.c index 6060bcf5f7..116ab2b448 100644 --- a/udev-add.c +++ b/udev-add.c @@ -137,7 +137,6 @@ int udev_add_device(char *device, char *subsystem) { struct sysfs_class_device *class_dev; struct device_attr attr; - struct udevice dbdev; int major; int minor; char type; @@ -164,34 +163,18 @@ int udev_add_device(char *device, char *subsystem) retval = get_major_minor(class_dev, &major, &minor); if (retval) { - dbg ("get_major_minor failed"); + dbg("get_major_minor failed"); goto exit; } - memset(&dbdev, 0, sizeof(dbdev)); - strncpy(dbdev.name, attr.name, NAME_SIZE); - if (class_dev->sysdevice) { - strncpy(dbdev.sysfs_path, class_dev->sysdevice->directory->path, PATH_SIZE); - strncpy(dbdev.bus_id, class_dev->sysdevice->bus_id, ID_SIZE); - } - strncpy(dbdev.class_dev_name, class_dev->name, NAME_SIZE); - if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) != 0) - strcpy(dbdev.class_name, "unkown"); - strcpy(dbdev.bus_name, "unknown"); - if (class_dev->driver != NULL) - strncpy(dbdev.driver, class_dev->driver->name, NAME_SIZE); - else - strcpy(dbdev.driver, "unkown"); - dbdev.type = type; - dbdev.major = major; - dbdev.minor = minor; - dbdev.mode = attr.mode; + + retval = udevdb_add_device(device, class_dev, attr.name, type, major, minor, attr.mode); + + if (retval != 0) + dbg("udevdb_add_device failed, but we are going to try to create the node anyway. " + "But remove might not work properly for this device."); sysfs_close_class_device(class_dev); - retval = udevdb_add_udevice(&dbdev); - if (retval != 0) - goto exit; - return create_node(attr.name, type, major, minor, attr.mode); exit: diff --git a/udev-remove.c b/udev-remove.c index 29063efb0d..9862a6f201 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -45,6 +45,11 @@ static char *get_name(char *dev, int major, int minor) static char name[100]; char *temp; + temp = udevdb_get_udevice_by_sysfs(dev); + dbg("udevdb_get_udevice_by_sysfs returned %s", temp); + if (temp != NULL) + return temp; + temp = strrchr(dev, '/'); if (temp == NULL) return NULL; diff --git a/udevdb.c b/udevdb.c index fb34ca61d3..05bd72a5d9 100644 --- a/udevdb.c +++ b/udevdb.c @@ -37,6 +37,7 @@ #include "namedev.h" #include "udevdb.h" #include "tdb/tdb.h" +#include "libsysfs/libsysfs.h" static TDB_CONTEXT *udevdb; @@ -55,11 +56,15 @@ struct classdb_record { char name[NAME_SIZE]; }; +struct sysfsdb_record { + char name[PATH_SIZE]; +}; + /** * namedb_record - device name is key, remaining udevice info stored here. */ struct namedb_record { - char sysfs_path[PATH_SIZE]; + char sysfs_dev_path[PATH_SIZE]; char class_dev_name[NAME_SIZE]; char class_name[NAME_SIZE]; char bus[BUS_SIZE]; @@ -177,6 +182,41 @@ static struct classdb_record *classdb_fetch(const char *cls, return rec; } +static struct sysfsdb_record *sysfsdb_fetch(const char *path) +{ + TDB_DATA key, data; + char keystr[PATH_SIZE+2]; + struct sysfsdb_record *rec = NULL; + + if (strlen(path) >= PATH_SIZE) + return NULL; + + memset(keystr, 0, sizeof(keystr)); + strcpy(keystr, path); + + dbg("keystr = %s", keystr); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + data = tdb_fetch(udevdb, key); + if (data.dptr == NULL || data.dsize == 0) { + dbg("tdb_fetch did not work :("); + return NULL; + } + + rec = (struct sysfsdb_record *)malloc(sizeof(struct sysfsdb_record)); + if (rec == NULL) { + free(data.dptr); + return NULL; + } + + memcpy(rec, data.dptr, sizeof(struct sysfsdb_record)); + free(data.dptr); + + return rec; +} + /** * namedb_fetch */ @@ -273,6 +313,32 @@ static int classdb_store(const struct udevice *dev) return retval; } +static int sysfs_store(const char *path, const struct udevice *dev) +{ + TDB_DATA key, data; + char keystr[PATH_SIZE+2]; + struct sysfsdb_record rec; + int retval = 0; + + if (dev == NULL) + return -ENODEV; + + memset(keystr, 0, sizeof(keystr)); + strcpy(keystr, path); + dbg("keystr = %s", keystr); + + key.dptr = (void *)keystr; + key.dsize = strlen(keystr) + 1; + + strcpy(rec.name, dev->name); + + data.dptr = (void *) &rec; + data.dsize = sizeof(rec); + + retval = tdb_store(udevdb, key, data, TDB_REPLACE); + return retval; +} + /** * namedb_store */ @@ -292,7 +358,7 @@ static int namedb_store(const struct udevice *dev) key.dptr = (void *)keystr; key.dsize = strlen(keystr) + 1; - strcpy(rec.sysfs_path, dev->sysfs_path); + strcpy(rec.sysfs_dev_path, dev->sysfs_dev_path); strcpy(rec.bus, dev->bus_name); strcpy(rec.id, dev->bus_id); strcpy(rec.class_dev_name, dev->class_dev_name); @@ -409,18 +475,41 @@ int udevdb_delete_udevice(const char *name) } /** - * udevdb_add_udevice: adds udevice to database + * udevdb_add_device: adds class device to database */ -int udevdb_add_udevice(const struct udevice *dev) +int udevdb_add_device(const char *device, const struct sysfs_class_device *class_dev, const char *name, char type, int major, int minor, int mode) { - if (dev == NULL) - return -1; + struct udevice dbdev; - if ((busdb_store(dev)) != 0) + if (class_dev == NULL) + return -ENODEV; + + memset(&dbdev, 0, sizeof(dbdev)); + strncpy(dbdev.name, name, NAME_SIZE); + if (class_dev->sysdevice) { + strncpy(dbdev.sysfs_dev_path, class_dev->sysdevice->directory->path, PATH_SIZE); + strncpy(dbdev.bus_id, class_dev->sysdevice->bus_id, ID_SIZE); + } + strncpy(dbdev.class_dev_name, class_dev->name, NAME_SIZE); +// if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) != 0) +// strcpy(dbdev.class_name, "unknown"); + strcpy(dbdev.bus_name, "unknown"); + if (class_dev->driver != NULL) + strncpy(dbdev.driver, class_dev->driver->name, NAME_SIZE); + else + strcpy(dbdev.driver, "unknown"); + dbdev.type = type; + dbdev.major = major; + dbdev.minor = minor; + dbdev.mode = mode; + + if ((busdb_store(&dbdev)) != 0) return -1; - if ((classdb_store(dev)) != 0) + if ((classdb_store(&dbdev)) != 0) return -1; - if ((namedb_store(dev)) != 0) + if ((sysfs_store(device, &dbdev)) != 0) + return -1; + if ((namedb_store(&dbdev)) != 0) return -1; return 0; @@ -448,7 +537,7 @@ struct udevice *udevdb_get_udevice(const char *name) } strcpy(dev->name, name); - strcpy(dev->sysfs_path, nrec->sysfs_path); + strcpy(dev->sysfs_dev_path, nrec->sysfs_dev_path); strcpy(dev->class_dev_name, nrec->class_dev_name); strcpy(dev->class_name, nrec->class_name); strcpy(dev->bus_name, nrec->bus); @@ -506,6 +595,27 @@ struct udevice *udevdb_get_udevice_by_class(const char *cls, return dev; } + +char *udevdb_get_udevice_by_sysfs(const char *path) +{ + struct sysfsdb_record *crec = NULL; +// struct udevice *dev = NULL; + + if (path == NULL) + return NULL; + + crec = sysfsdb_fetch(path); + if (crec == NULL) + return NULL; + + // FIXME leak!!! + return crec->name; +// dev = udevdb_get_udevice(crec->name); +// free(crec); +// +// return dev; +} + /** * udevdb_exit: closes database */ diff --git a/udevdb.h b/udevdb.h index 089af2972b..8e72eded02 100644 --- a/udevdb.h +++ b/udevdb.h @@ -16,7 +16,7 @@ struct udevice { char name[NAME_SIZE]; - char sysfs_path[PATH_SIZE]; + char sysfs_dev_path[PATH_SIZE]; char class_dev_name[NAME_SIZE]; char class_name[NAME_SIZE]; char bus_id[NAME_SIZE]; @@ -32,11 +32,12 @@ struct udevice { extern void udevdb_exit(void); extern int udevdb_init(int init_flag); extern int udevdb_delete_udevice(const char *name); -extern int udevdb_add_udevice(const struct udevice *dev); +extern int udevdb_add_device(const char *device, const struct sysfs_class_device *class_dev, const char *name, char type, int major, int minor, int mode); extern struct udevice *udevdb_get_udevice(const char *name); extern struct udevice *udevdb_get_udevice_by_bus(const char *bus, const char *id); extern struct udevice *udevdb_get_udevice_by_class(const char *cls, const char *cls_dev); +extern char *udevdb_get_udevice_by_sysfs(const char *path); #endif /* _UDEVDB_H_ */ From 45dbc61ebe869c8f6da744e05353aa5316fe9b30 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 23:33:28 -0700 Subject: [PATCH 0072/4284] [PATCH] change the version to 003-bk to keep things sane with people using the bk tree. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 493cd08450..5cefb12ebf 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 003 +VERSION = 003-bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) From bbab56baedd3e2f75d8a606d97d54c7a4d01d454 Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Fri, 17 Oct 2003 23:34:19 -0700 Subject: [PATCH 0073/4284] [PATCH] udev spec file bits Some spec file changes. Primarily, this makes the thing build without a build root if so desired (i.e. build right out of /usr/src/redhat and the standard file system). It should still build from a build root, too. Also: - Add some Prereqs - Pass RPM_OPT_FLAGS to make so we build with the RPM build policy (i.e., optimizations, architecture, etc.) - Specify the exact files in %files to make sure we install everything properly and avoid a warning --- udev.spec | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/udev.spec b/udev.spec index 07b608ed6d..1bfaabaf86 100644 --- a/udev.spec +++ b/udev.spec @@ -8,29 +8,41 @@ Source: ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug/%{name}-%{version}.t ExclusiveOS: Linux Vendor: Greg Kroah-Hartman BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root +Prereq: /bin/sh, fileutils, hotplug %description udev is a implementation of devfs in userspace using sysfs and /sbin/hotplug. It requires a 2.6 kernel to run properly. %prep -%setup +%setup -q %build -make +make CC="gcc $RPM_OPT_FLAGS" %install make prefix=$RPM_BUILD_ROOT install %clean -rm -fr $RPM_BUILD_ROOT +rm -rf $RPM_BUILD_ROOT %files -%defattr(-,root,root) -%attr(755,root,root)/sbin/%{name} -%attr(-,root,root) %doc COPYING README TODO ChangeLog +%defattr(0644,root,root) +%doc COPYING README TODO ChangeLog +%attr(755,root,root) /sbin/udev +%attr(755,root,root) /udev/ +%attr(755,root,root) /etc/udev/ +%attr(0644,root,root) /etc/udev/namedev.config +%attr(0644,root,root) /etc/udev/namedev.permissions +%attr(0644,root,root) %{_mandir}/man8/udev.8* %changelog +* Fri Oct 17 2003 Robert Love +- Make work without a build root +- Correctly install the right files +- Pass the RPM_OPT_FLAGS to gcc so we can build per the build policy +- Put some prereqs in + * Mon Jul 28 2003 Paul Mundt - Initial spec file for udev-0.2. From 410e08dd08166c0745e30768fe1a1cdbe5180720 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 23:39:26 -0700 Subject: [PATCH 0074/4284] [PATCH] ok, rpm likes the "_" character instead of "-" better... --- Makefile | 2 +- udev.spec | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5cefb12ebf..535e5b9293 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 003-bk +VERSION = 003_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 1bfaabaf86..affa7ea867 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 003 +Version: 003_bk Release: 1 License: GPL Group: Utilities/System @@ -32,6 +32,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udev %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ +#%attr(755,root,root) /etc/hotplug.d/default/udev.hotplug %attr(0644,root,root) /etc/udev/namedev.config %attr(0644,root,root) /etc/udev/namedev.permissions %attr(0644,root,root) %{_mandir}/man8/udev.8* From 577aade748378e9b01d50d6ceb93c9c949d24228 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 17 Oct 2003 23:54:07 -0700 Subject: [PATCH 0075/4284] [PATCH] test.block changes. --- test.block | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.block b/test.block index 3e198fe4b6..f12c6f735c 100644 --- a/test.block +++ b/test.block @@ -4,7 +4,7 @@ export ACTION=add export DEVPATH=/block/hda export DEVPATH=/block/sda/sda1 -export DEVPATH=/block/sda +#export DEVPATH=/block/sda ./udev block From 5892ceb540405861e51db3832d4f5cbab123056f Mon Sep 17 00:00:00 2001 From: "rml@mvista.com" Date: Fri, 17 Oct 2003 23:54:14 -0700 Subject: [PATCH 0076/4284] [PATCH] udev: cool test scripts This patch changes test.tty and test.block to add/remove each tty and block device, respectively, on the system. Great way to populate/unpopulate udev rapidly. Its just a simple for loop over the sysfs entries. --- test.block | 18 ++++++++++-------- test.tty | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/test.block b/test.block index f12c6f735c..f6011a2221 100644 --- a/test.block +++ b/test.block @@ -1,10 +1,12 @@ -#!/bin/sh -export ACTION=add -#export ACTION=remove +#! /bin/sh +# +# test.block - run udev(8) on each block device in /sys/block -export DEVPATH=/block/hda -export DEVPATH=/block/sda/sda1 -#export DEVPATH=/block/sda +SYSFSDIR=/sys # change this for a nonstand sysfs mount point +BIN=./udev # location of your udev binary +export ACTION=add # 'add' or 'remove' - -./udev block +for i in ${SYSFSDIR}/block/*; do + export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` + $BIN block +done diff --git a/test.tty b/test.tty index 2d64f07d3e..ec8b1d0404 100644 --- a/test.tty +++ b/test.tty @@ -1,10 +1,12 @@ -#!/bin/sh -export ACTION=add -#export ACTION=remove -export DEVPATH=/devices/pci0/00:09.0/usb1/1-1/1-1.1/ttyUSB7 -export DEVPATH=/class/tty/ttyUSB0 -#export DEVPATH=/block/hda +#! /bin/sh +# +# test.tty - run udev(8) on each tty device in /sys/class/tty +SYSFSDIR=/sys # change this for a nonstand sysfs mount point +BIN=./udev # location of your udev binary +export ACTION=add # 'add' or 'remove' -#./udev block -./udev tty +for i in ${SYSFSDIR}/class/tty/*; do + export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` + $BIN tty +done From 88449f27e7870cfb713e4a7c2dde90b5032cb402 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 18 Oct 2003 00:11:13 -0700 Subject: [PATCH 0077/4284] [PATCH] spec file changes. --- udev.spec | 1 - 1 file changed, 1 deletion(-) diff --git a/udev.spec b/udev.spec index affa7ea867..ffb643c57a 100644 --- a/udev.spec +++ b/udev.spec @@ -32,7 +32,6 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udev %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ -#%attr(755,root,root) /etc/hotplug.d/default/udev.hotplug %attr(0644,root,root) /etc/udev/namedev.config %attr(0644,root,root) /etc/udev/namedev.permissions %attr(0644,root,root) %{_mandir}/man8/udev.8* From 8634e6d111730b6c95a8b846ddbadafb147b4a34 Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Sat, 18 Oct 2003 00:12:16 -0700 Subject: [PATCH 0078/4284] [PATCH] udev spec file symlink support > Hm, I would also like to add the /etc/hotplug.d/default/udev.hotplug > symlink, but rpm doesn't seem to like symlinks in the %files section. > Anyone know how to do this properly? The problem is that the symlink is left dangling to an absolute location in the build root, which won't exist on the installer's system. RPM 4.0 and on catches this. Attached patch fixes it up and makes it work. --- udev.spec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/udev.spec b/udev.spec index ffb643c57a..59b06a0d16 100644 --- a/udev.spec +++ b/udev.spec @@ -22,6 +22,8 @@ make CC="gcc $RPM_OPT_FLAGS" %install make prefix=$RPM_BUILD_ROOT install +rm -f ${RPM_BUILD_ROOT}/etc/hotplug.d/default/udev.hotplug +ln -s /sbin/udev ${RPM_BUILD_ROOT}/etc/hotplug.d/default/udev.hotplug %clean rm -rf $RPM_BUILD_ROOT @@ -34,6 +36,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /etc/udev/ %attr(0644,root,root) /etc/udev/namedev.config %attr(0644,root,root) /etc/udev/namedev.permissions +%attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(0644,root,root) %{_mandir}/man8/udev.8* %changelog @@ -42,6 +45,7 @@ rm -rf $RPM_BUILD_ROOT - Correctly install the right files - Pass the RPM_OPT_FLAGS to gcc so we can build per the build policy - Put some prereqs in +- Install the hotplug symlink to udev * Mon Jul 28 2003 Paul Mundt - Initial spec file for udev-0.2. From fd14ee04ef9834516cd3b6ae4d07a3e4156e232e Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Sat, 18 Oct 2003 01:18:04 -0700 Subject: [PATCH 0079/4284] [PATCH] udev: cool test scripts again > But the test.block script doesn't catch any partitions on the block > devices :) Never happy! [19:07:52]root@phantasy:~/src/udev/udev# ./test.block [19:13:37]root@phantasy:~/src/udev/udev# ls /udev/hd* ls: /udev/hd*: No such file or directory [19:13:42]root@phantasy:~/src/udev/udev# ./test.block [19:13:53]root@phantasy:~/src/udev/udev# ls /udev/hd* /udev/hda /udev/hda2 /udev/hda4 /udev/hda6 /udev/hdd /udev/hda1 /udev/hda3 /udev/hda5 /udev/hdc test.block now recurses /sys/block, looking for partitions. Should add all drives and all partitions. --- test.block | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test.block b/test.block index f6011a2221..781560dee1 100644 --- a/test.block +++ b/test.block @@ -7,6 +7,16 @@ BIN=./udev # location of your udev binary export ACTION=add # 'add' or 'remove' for i in ${SYSFSDIR}/block/*; do + # add each drive export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` $BIN block + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH="/"`echo $j | \ + cut --delimiter='/' --fields=3-` + $BIN block + fi + done done From d7e954a4ef664cd65fbb34cb23ca57dc1bb89ea0 Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Sun, 19 Oct 2003 21:55:43 -0700 Subject: [PATCH 0080/4284] [PATCH] udev: trivial trivialities Yah yah, really trivial stuff... - get_class_device() doesn't need to be exported; it should be static - white space cleanup --- udev-add.c | 2 +- udevdb.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/udev-add.c b/udev-add.c index 116ab2b448..05f2aa3e9d 100644 --- a/udev-add.c +++ b/udev-add.c @@ -101,7 +101,7 @@ static int create_node(char *name, char type, int major, int minor, int mode) return retval; } -struct sysfs_class_device *get_class_dev(char *device_name) +static struct sysfs_class_device *get_class_dev(char *device_name) { char sysfs_path[SYSFS_PATH_MAX]; char dev_path[SYSFS_PATH_MAX]; diff --git a/udevdb.c b/udevdb.c index 05bd72a5d9..fa26de46d5 100644 --- a/udevdb.c +++ b/udevdb.c @@ -130,13 +130,13 @@ static struct busdb_record *busdb_fetch(const char *bus, const char *id) data = tdb_fetch(udevdb, key); if (data.dptr == NULL || data.dsize == 0) return NULL; - + rec = (struct busdb_record *)malloc(sizeof(struct busdb_record)); if (rec == NULL) { free(data.dptr); return NULL; } - + memcpy(rec, data.dptr, sizeof(struct busdb_record)); free(data.dptr); From c2405f502cae4a634a25674306cffefb85df9ebb Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Sun, 19 Oct 2003 21:56:21 -0700 Subject: [PATCH 0081/4284] [PATCH] udev: mode should be mode_t Unix file modes should be stored in a mode_t, not a standard type. At the moment it is actually unsigned, in fact, not a signed integer. Attached patch does an s/int mode/mode_t mode/ and cleans up the results. --- namedev.c | 12 +++++++----- udev-add.c | 4 ++-- udev.h | 2 +- udevdb.c | 2 +- udevdb.h | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/namedev.c b/namedev.c index 6f69959346..ac05fd88e4 100644 --- a/namedev.c +++ b/namedev.c @@ -446,7 +446,8 @@ static int namedev_init_permissions(void) dev.attr.mode = strtol(temp, NULL, 8); dbg_parse("name = %s, owner = %s, group = %s, mode = %#o", - dev.attr.name, dev.attr.owner, dev.attr.group, dev.attr.mode); + dev.attr.name, dev.attr.owner, dev.attr.group, + dev.attr.mode); retval = add_dev(&dev); if (retval) { dbg("add_dev returned with error %d", retval); @@ -459,7 +460,7 @@ exit: return retval; } -static int get_default_mode(struct sysfs_class_device *class_dev) +static mode_t get_default_mode(struct sysfs_class_device *class_dev) { /* just default everyone to rw for the world! */ return 0666; @@ -544,7 +545,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at int retval = 0; int found; - attr->mode = -1; + attr->mode = 0; if (class_dev->sysdevice) { dbg_parse("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); dbg_parse("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); @@ -751,9 +752,10 @@ label_found: } } strcpy(attr->name, class_dev->name); - + done: - if (attr->mode == -1) { + /* mode was never set above */ + if (!attr->mode) { attr->mode = get_default_mode(class_dev); attr->owner[0] = 0x00; attr->group[0] = 0x00; diff --git a/udev-add.c b/udev-add.c index 05f2aa3e9d..d158c41b1d 100644 --- a/udev-add.c +++ b/udev-add.c @@ -71,7 +71,7 @@ exit: /* * We also want to add some permissions here, and possibly some symlinks */ -static int create_node(char *name, char type, int major, int minor, int mode) +static int create_node(char *name, char type, int major, int minor, mode_t mode) { char filename[255]; int retval = 0; @@ -94,7 +94,7 @@ static int create_node(char *name, char type, int major, int minor, int mode) } dbg("mknod(%s, %#o, %u, %u)", filename, mode, major, minor); - retval = mknod(filename,mode,makedev(major,minor)); + retval = mknod(filename, mode, makedev(major, minor)); if (retval) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, mode, major, minor, strerror(errno)); diff --git a/udev.h b/udev.h index 33cb89af55..af575c2b17 100644 --- a/udev.h +++ b/udev.h @@ -59,7 +59,7 @@ struct device_attr { char name[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; - int mode; + mode_t mode; }; extern int udev_add_device(char *device, char *subsystem); diff --git a/udevdb.c b/udevdb.c index fa26de46d5..678ddd9603 100644 --- a/udevdb.c +++ b/udevdb.c @@ -73,7 +73,7 @@ struct namedb_record { char type; int major; int minor; - int mode; + mode_t mode; }; /** diff --git a/udevdb.h b/udevdb.h index 8e72eded02..656613b593 100644 --- a/udevdb.h +++ b/udevdb.h @@ -25,7 +25,7 @@ struct udevice { char type; int major; int minor; - int mode; + mode_t mode; }; /* Function Prototypes */ From d3db5e5e405b81ae094a5b0fab53d37b2356514c Mon Sep 17 00:00:00 2001 From: "lkml001@vrfy.org" Date: Sun, 19 Oct 2003 21:59:45 -0700 Subject: [PATCH 0082/4284] [PATCH] man page update --- udev.8 | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 4 deletions(-) diff --git a/udev.8 b/udev.8 index e44855ba16..771ecfa454 100644 --- a/udev.8 +++ b/udev.8 @@ -1,11 +1,67 @@ -.TH UDEV 8 "October 2003" "" "Linux Programmer's Manual" +.TH UDEV 8 "October 2003" "" "Linux Administrator's Manual" .SH NAME -udev \- Linux dynamic device naming support +udev \- Linux configurable dynamic device naming support .SH SYNOPSIS .B udev .SH "DESCRIPTION" .B udev -is a wonderful program whose man page has not been written yet. +creates or removes device node files usually located in the /dev directory. +As part of the +.B hotplug +subsystem, +.B udev +is exectuted if a kernel device is added or removed from the system. +.P +On device creation, +.B udev +reads the sysfs directory of the given device, to collect device attributes +like label, serial number or bus device number. +These attributes are passed as a key to the namedev subsystem +to receive a unique name for device file creation. +namedev maintains a database for devices present on the system. +.P +On device removal, +.B udev +queries the namedev database for the name of the device file to delete. +.P +namedev expects its configuration at +.I /etc/udev/namedev.config. +The file consists of a set of lines. All empty lines and +lines beginning with a '#' will be ignored. +.br +Every line defines the mapping between device attributes and the name of +the device file. It starts with a keyword defining the method for +overriding the default kernel naming scheme, followed by a list +of keys and ends with the definition of the filename for the device. +.TP +.B LABEL +device label or serial number, like USB serial number, SCSI UUID or +file system label +.TP +.B NUMBER +device number on the bus, like PCI bus id +.TP +.B TOPOLOGY +device position on bus, like physical port of USB device +.TP +.B REPLACE +string replacement of the kernel device name +.P +If no matching configuration is found, the default kernel device name is used. +.SH "EXAMPLE" +.nf +# USB printer to be called lp_color +LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_color" + +# sound card with PCI bus id 00:0b.0 to be called dsp +NUMBER, BUS="pci", id="00:0b.0", NAME="dsp" + +# USB mouse at third port of the second hub to be called mouse1 +TOPOLOGY, BUS="usb", place="2.3", NAME="mouse1" + +# ttyUSB1 should always be called pda +REPLACE, KERNEL="ttyUSB1", NAME="pda" +.fi .SH "FILES" .nf .ft B @@ -16,7 +72,7 @@ is a wonderful program whose man page has not been written yet. .fi .LP .SH "SEE ALSO" -.BR hotplug "(8)" +.B hotplug (8) .PP The .I http://linux-hotplug.sourceforge.net/ From 05fdfe68e2a628ceabf41f32300bf9f7578a29c5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 20 Oct 2003 17:58:23 -0700 Subject: [PATCH 0083/4284] [PATCH] add BUS= bug to TODO list so it will not get forgotten. Thanks to reg@dwf.com for pointing this out to me. --- TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO b/TODO index 89fe6679d4..3c1581705b 100644 --- a/TODO +++ b/TODO @@ -29,3 +29,8 @@ greg@kroah.com etc.) - add hooks to call D-BUS when new node is created or removed - lots of other stuff... +- actually use the BUS= value to determine where the LABEL rule should look + (right now it's ignored, and we only look in the current sysfs directory.) + This is needed, for example, to look at the usb device's serial number of a + usb-storage device, instead of the scsi device's sysfs directory for the + serial number. From a9ce0a410e7ef573f2f1f48ea793829d3cec389f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 20 Oct 2003 20:28:42 -0700 Subject: [PATCH 0084/4284] [PATCH] more database work. Now we only store the info we really need right now. Also delete the record after the device is gone, and fix up a memory leak. --- udev-remove.c | 17 ++- udevdb.c | 305 +++++--------------------------------------------- udevdb.h | 7 +- 3 files changed, 40 insertions(+), 289 deletions(-) diff --git a/udev-remove.c b/udev-remove.c index 9862a6f201..430f1c901e 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -36,27 +36,25 @@ /* - * Here would go a call to the naming deamon, to get the name we want to have - * for this device. But for now, let's just default to whatever the kernel is - * calling the device as that will keep the "old-style" naming policy + * Look up the sysfs path in the database to see if we have named this device + * something different from the kernel name. If we have, us it. If not, use + * the default kernel name for lack of anything else to know to do. */ static char *get_name(char *dev, int major, int minor) { static char name[100]; char *temp; - temp = udevdb_get_udevice_by_sysfs(dev); - dbg("udevdb_get_udevice_by_sysfs returned %s", temp); - if (temp != NULL) - return temp; - + if (udevdb_get_dev(dev, &name[0], sizeof(name)) == 0) + goto exit; + temp = strrchr(dev, '/'); if (temp == NULL) return NULL; strncpy(name, &temp[1], sizeof(name)); +exit: dbg("name is %s", name); - return &name[0]; } @@ -87,6 +85,7 @@ int udev_remove_device(char *device, char *subsystem) } udevdb_delete_udevice(name); + udevdb_delete_dev(device); return delete_node(name); diff --git a/udevdb.c b/udevdb.c index 678ddd9603..e4330f5320 100644 --- a/udevdb.c +++ b/udevdb.c @@ -41,21 +41,6 @@ static TDB_CONTEXT *udevdb; -/** - * busdb_record - bus and id are keys to look up name of device - */ -struct busdb_record { - char name[NAME_SIZE]; -}; - -/** - * classdb_record - class name and class device name used as keys to find - * device name. - */ -struct classdb_record { - char name[NAME_SIZE]; -}; - struct sysfsdb_record { char name[PATH_SIZE]; }; @@ -67,9 +52,7 @@ struct namedb_record { char sysfs_dev_path[PATH_SIZE]; char class_dev_name[NAME_SIZE]; char class_name[NAME_SIZE]; - char bus[BUS_SIZE]; char id[ID_SIZE]; - char driver[NAME_SIZE]; char type; int major; int minor; @@ -105,83 +88,6 @@ static int udevdb_open(int method) return 0; } -/** - * busdb_fetch - */ -static struct busdb_record *busdb_fetch(const char *bus, const char *id) -{ - TDB_DATA key, data; - char keystr[BUS_SIZE+ID_SIZE+2]; - struct busdb_record *rec = NULL; - - if (bus == NULL || id == NULL) - return NULL; - if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE) - return NULL; - - memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); - strcpy(keystr, bus); - strcat(keystr, UDEVDB_DEL); - strcat(keystr, id); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(udevdb, key); - if (data.dptr == NULL || data.dsize == 0) - return NULL; - - rec = (struct busdb_record *)malloc(sizeof(struct busdb_record)); - if (rec == NULL) { - free(data.dptr); - return NULL; - } - - memcpy(rec, data.dptr, sizeof(struct busdb_record)); - free(data.dptr); - - return rec; -} - -/** - * classdb_fetch - */ -static struct classdb_record *classdb_fetch(const char *cls, - const char *cls_dev) -{ - TDB_DATA key, data; - char keystr[NAME_SIZE+NAME_SIZE+2]; - struct classdb_record *rec = NULL; - - if (cls == NULL || cls_dev == NULL) - return NULL; - if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE) - return NULL; - - memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); - strcpy(keystr, cls); - strcat(keystr, UDEVDB_DEL); - strcat(keystr, cls_dev); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(udevdb, key); - if (data.dptr == NULL || data.dsize == 0) - return NULL; - - rec = (struct classdb_record *)malloc(sizeof(struct classdb_record)); - if (rec == NULL) { - free(data.dptr); - return NULL; - } - - memcpy(rec, data.dptr, sizeof(struct classdb_record)); - free(data.dptr); - - return rec; -} - static struct sysfsdb_record *sysfsdb_fetch(const char *path) { TDB_DATA key, data; @@ -253,66 +159,6 @@ static struct namedb_record *namedb_fetch(const char *name) return nrec; } -/** - * busdb_store - */ -static int busdb_store(const struct udevice *dev) -{ - TDB_DATA key, data; - char keystr[BUS_SIZE+ID_SIZE+2]; - struct busdb_record rec; - int retval = 0; - - if (dev == NULL) - return -1; - - memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); - strcpy(keystr, dev->bus_name); - strcat(keystr, UDEVDB_DEL); - strcat(keystr, dev->bus_id); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - strcpy(rec.name, dev->name); - - data.dptr = (void *) &rec; - data.dsize = sizeof(rec); - - retval = tdb_store(udevdb, key, data, TDB_REPLACE); - return retval; -} - -/** - * classdb_store - */ -static int classdb_store(const struct udevice *dev) -{ - TDB_DATA key, data; - char keystr[NAME_SIZE+NAME_SIZE+2]; - struct classdb_record rec; - int retval = 0; - - if (dev == NULL) - return -1; - - memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); - strcpy(keystr, dev->class_name); - strcat(keystr, UDEVDB_DEL); - strcat(keystr, dev->class_dev_name); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - strcpy(rec.name, dev->name); - - data.dptr = (void *) &rec; - data.dsize = sizeof(rec); - - retval = tdb_store(udevdb, key, data, TDB_REPLACE); - return retval; -} - static int sysfs_store(const char *path, const struct udevice *dev) { TDB_DATA key, data; @@ -325,7 +171,6 @@ static int sysfs_store(const char *path, const struct udevice *dev) memset(keystr, 0, sizeof(keystr)); strcpy(keystr, path); - dbg("keystr = %s", keystr); key.dptr = (void *)keystr; key.dsize = strlen(keystr) + 1; @@ -359,11 +204,9 @@ static int namedb_store(const struct udevice *dev) key.dsize = strlen(keystr) + 1; strcpy(rec.sysfs_dev_path, dev->sysfs_dev_path); - strcpy(rec.bus, dev->bus_name); strcpy(rec.id, dev->bus_id); strcpy(rec.class_dev_name, dev->class_dev_name); strcpy(rec.class_name, dev->class_name); - strcpy(rec.driver, dev->driver); rec.type = dev->type; rec.major = dev->major; rec.minor = dev->minor; @@ -376,58 +219,6 @@ static int namedb_store(const struct udevice *dev) return retval; } -/** - * busdb_delete - */ -static int busdb_delete(const char *bus, const char *id) -{ - TDB_DATA key; - char keystr[BUS_SIZE+ID_SIZE+2]; - int retval = 0; - - if (bus == NULL || id == NULL) - return -1; - if (strlen(bus) >= BUS_SIZE || strlen(id) >= ID_SIZE) - return -1; - - memset(keystr, 0, (BUS_SIZE+ID_SIZE+2)); - strcpy(keystr, bus); - strcat(keystr, UDEVDB_DEL); - strcat(keystr, id); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - retval = tdb_delete(udevdb, key); - return retval; -} - -/** - * classdb_delete - */ -static int classdb_delete(const char *cls, const char *cls_dev) -{ - TDB_DATA key; - char keystr[NAME_SIZE+NAME_SIZE+2]; - int retval = 0; - - if (cls == NULL || cls_dev == NULL) - return -1; - if (strlen(cls) >= NAME_SIZE || strlen(cls_dev) >= NAME_SIZE) - return -1; - - memset(keystr, 0, (NAME_SIZE+NAME_SIZE+2)); - strcpy(keystr, cls); - strcat(keystr, UDEVDB_DEL); - strcat(keystr, cls_dev); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - retval = tdb_delete(udevdb, key); - return retval; -} - /** * namedb_delete */ @@ -452,6 +243,20 @@ static int namedb_delete(const char *name) return retval; } +static int sysfs_delete(const char *path) +{ + TDB_DATA key; + char keystr[PATH_SIZE]; + + memset(keystr, 0, sizeof(keystr)); + strcpy(keystr, path); + + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + return tdb_delete(udevdb, key); +} + /** * udevdb_delete_udevice */ @@ -466,8 +271,6 @@ int udevdb_delete_udevice(const char *name) if (nrec == NULL) return -1; - busdb_delete(nrec->bus, nrec->id); - classdb_delete(nrec->class_name, nrec->class_dev_name); namedb_delete(name); free(nrec); @@ -493,24 +296,15 @@ int udevdb_add_device(const char *device, const struct sysfs_class_device *class strncpy(dbdev.class_dev_name, class_dev->name, NAME_SIZE); // if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) != 0) // strcpy(dbdev.class_name, "unknown"); - strcpy(dbdev.bus_name, "unknown"); - if (class_dev->driver != NULL) - strncpy(dbdev.driver, class_dev->driver->name, NAME_SIZE); - else - strcpy(dbdev.driver, "unknown"); dbdev.type = type; dbdev.major = major; dbdev.minor = minor; dbdev.mode = mode; - if ((busdb_store(&dbdev)) != 0) - return -1; - if ((classdb_store(&dbdev)) != 0) - return -1; if ((sysfs_store(device, &dbdev)) != 0) return -1; - if ((namedb_store(&dbdev)) != 0) - return -1; +// if ((namedb_store(&dbdev)) != 0) +// return -1; return 0; } @@ -540,7 +334,6 @@ struct udevice *udevdb_get_udevice(const char *name) strcpy(dev->sysfs_dev_path, nrec->sysfs_dev_path); strcpy(dev->class_dev_name, nrec->class_dev_name); strcpy(dev->class_name, nrec->class_name); - strcpy(dev->bus_name, nrec->bus); strcpy(dev->bus_id, nrec->id); dev->type = nrec->type; dev->major = nrec->major; @@ -552,68 +345,30 @@ struct udevice *udevdb_get_udevice(const char *name) return dev; } -/** - * udevdb_get_device_by_bus - */ -struct udevice *udevdb_get_udevice_by_bus(const char *bus, const char *id) +int udevdb_get_dev(const char *path, char *name, size_t name_size) { - struct busdb_record *brec = NULL; - struct udevice *dev = NULL; + struct sysfsdb_record *rec = NULL; - if (bus == NULL || id == NULL) - return NULL; + if ((path == NULL) || (name == NULL) || (name_size < 1)) + return -EINVAL; - brec = busdb_fetch(bus, id); - if (brec == NULL) - return NULL; + rec = sysfsdb_fetch(path); + if (rec == NULL) + return -ENODEV; - dev = udevdb_get_udevice(brec->name); - free(brec); + if (strlen(rec->name) >= name_size) + return -EINVAL; - return dev; + strncpy(name, rec->name, name_size); + return 0; } -/** - * udevdb_get_udevice_by_class - */ -struct udevice *udevdb_get_udevice_by_class(const char *cls, - const char *cls_dev) +int udevdb_delete_dev(const char *path) { - struct classdb_record *crec = NULL; - struct udevice *dev = NULL; - - if (cls == NULL || cls_dev == NULL) - return NULL; - - crec = classdb_fetch(cls, cls_dev); - if (crec == NULL) - return NULL; - - dev = udevdb_get_udevice(crec->name); - free(crec); - - return dev; -} - - -char *udevdb_get_udevice_by_sysfs(const char *path) -{ - struct sysfsdb_record *crec = NULL; -// struct udevice *dev = NULL; - if (path == NULL) - return NULL; + return -EINVAL; - crec = sysfsdb_fetch(path); - if (crec == NULL) - return NULL; - - // FIXME leak!!! - return crec->name; -// dev = udevdb_get_udevice(crec->name); -// free(crec); -// -// return dev; + return sysfs_delete(path); } /** diff --git a/udevdb.h b/udevdb.h index 656613b593..57a27bc17f 100644 --- a/udevdb.h +++ b/udevdb.h @@ -21,7 +21,6 @@ struct udevice { char class_name[NAME_SIZE]; char bus_id[NAME_SIZE]; char bus_name[NAME_SIZE]; - char driver[NAME_SIZE]; char type; int major; int minor; @@ -34,10 +33,8 @@ extern int udevdb_init(int init_flag); extern int udevdb_delete_udevice(const char *name); extern int udevdb_add_device(const char *device, const struct sysfs_class_device *class_dev, const char *name, char type, int major, int minor, int mode); extern struct udevice *udevdb_get_udevice(const char *name); -extern struct udevice *udevdb_get_udevice_by_bus(const char *bus, - const char *id); -extern struct udevice *udevdb_get_udevice_by_class(const char *cls, - const char *cls_dev); extern char *udevdb_get_udevice_by_sysfs(const char *path); +extern int udevdb_get_dev(const char *path, char *name, size_t name_size); +extern int udevdb_delete_dev(const char *path); #endif /* _UDEVDB_H_ */ From 727d1ba5bee517fb8df940b31280a13035552386 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 20 Oct 2003 20:31:24 -0700 Subject: [PATCH 0085/4284] [PATCH] fix comment about how the "dev" file is made up. --- udev-add.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/udev-add.c b/udev-add.c index d158c41b1d..aa93a0c018 100644 --- a/udev-add.c +++ b/udev-add.c @@ -39,12 +39,10 @@ * Right now the major/minor of a device is stored in a file called * "dev" in sysfs. * The number is stored as: - * MMmm + * MM:mm * MM is the major * mm is the minor - * The value is in hex. - * Yes, this will probably change when we go to a bigger major/minor - * range, and will have to be changed at that time. + * The value is in decimal. */ static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) { From 29fd7e679beba83a9c79df82374b5e51453a3831 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 20 Oct 2003 21:03:15 -0700 Subject: [PATCH 0086/4284] [PATCH] don't sleep if 'dev' file is already present on device add. instead sleep for up to 10 seconds waiting for it to show up. --- udev-add.c | 57 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/udev-add.c b/udev-add.c index aa93a0c018..85bcbf6c18 100644 --- a/udev-add.c +++ b/udev-add.c @@ -34,6 +34,7 @@ #include "udevdb.h" #include "libsysfs/libsysfs.h" +static char sysfs_path[SYSFS_PATH_MAX]; /* * Right now the major/minor of a device is stored in a file called @@ -101,19 +102,9 @@ static int create_node(char *name, char type, int major, int minor, mode_t mode) static struct sysfs_class_device *get_class_dev(char *device_name) { - char sysfs_path[SYSFS_PATH_MAX]; char dev_path[SYSFS_PATH_MAX]; - int retval; struct sysfs_class_device *class_dev = NULL; - - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - dbg("sysfs_path = %s", sysfs_path); - if (retval) { - dbg("sysfs_get_mnt_path failed"); - goto exit; - } - strcpy(dev_path, sysfs_path); strcat(dev_path, device_name); @@ -131,6 +122,38 @@ exit: return class_dev; } +/* wait for the "dev" file to show up in the directory in sysfs. + * If it doesn't happen in about 10 seconds, give up. + */ +#define SECONDS_TO_WAIT_FOR_DEV 10 +int sleep_for_dev(char *device) +{ + char filename[SYSFS_PATH_MAX + 6]; + struct stat buf; + int loop = 0; + int retval = -ENODEV; + + strcpy(filename, sysfs_path); + strcat(filename, device); + strcat(filename, "/dev"); + + while (loop < SECONDS_TO_WAIT_FOR_DEV) { + dbg("looking for %s", filename); + retval = stat(filename, &buf); + if (retval == 0) { + retval = 0; + goto exit; + } + + /* sleep for a second or two to give the kernel a chance to + * create the dev file */ + sleep(1); + } + retval = -ENODEV; +exit: + return retval; +} + int udev_add_device(char *device, char *subsystem) { struct sysfs_class_device *class_dev; @@ -146,10 +169,16 @@ int udev_add_device(char *device, char *subsystem) else type = 'c'; - /* sleep for a second or two to give the kernel a chance to - * create the dev file - */ - sleep(1); + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + dbg("sysfs_path = %s", sysfs_path); + if (retval) { + dbg("sysfs_get_mnt_path failed"); + goto exit; + } + + retval = sleep_for_dev(device); + if (retval) + goto exit; class_dev = get_class_dev(device); if (class_dev == NULL) From c8c47999ff59b0235b217fbab4cba0c86b0fd075 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 20 Oct 2003 22:45:46 -0700 Subject: [PATCH 0087/4284] [PATCH] Changed test.block and test.tty to take ACTION from the command line. --- test.block | 10 +++++++++- test.tty | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/test.block b/test.block index 781560dee1..622a66037f 100644 --- a/test.block +++ b/test.block @@ -2,9 +2,17 @@ # # test.block - run udev(8) on each block device in /sys/block +if [ $# = "0" ] ; then + echo + echo "usage: $0 " + echo "where is \"add\" or \"remove\"" + echo + exit 1 +fi + SYSFSDIR=/sys # change this for a nonstand sysfs mount point BIN=./udev # location of your udev binary -export ACTION=add # 'add' or 'remove' +export ACTION=$1 # 'add' or 'remove' for i in ${SYSFSDIR}/block/*; do # add each drive diff --git a/test.tty b/test.tty index ec8b1d0404..d5e2d6715d 100644 --- a/test.tty +++ b/test.tty @@ -2,9 +2,17 @@ # # test.tty - run udev(8) on each tty device in /sys/class/tty +if [ $# = "0" ] ; then + echo + echo "usage: $0 " + echo "where is \"add\" or \"remove\"" + echo + exit 1 +fi + SYSFSDIR=/sys # change this for a nonstand sysfs mount point BIN=./udev # location of your udev binary -export ACTION=add # 'add' or 'remove' +export ACTION=$1 # 'add' or 'remove' for i in ${SYSFSDIR}/class/tty/*; do export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` From 5840bc63e2029d22682d8de77dc8fcc4da1b436c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 20 Oct 2003 22:48:44 -0700 Subject: [PATCH 0088/4284] [PATCH] major database cleanups Now we standardise on a struct udevice to pass around, and store in the database. This cleaned up the database code a lot. --- udev-add.c | 57 +++++---- udev-remove.c | 12 +- udev.h | 15 ++- udevdb.c | 335 ++++++-------------------------------------------- udevdb.h | 25 +--- 5 files changed, 96 insertions(+), 348 deletions(-) diff --git a/udev-add.c b/udev-add.c index 85bcbf6c18..7906638a7f 100644 --- a/udev-add.c +++ b/udev-add.c @@ -70,33 +70,37 @@ exit: /* * We also want to add some permissions here, and possibly some symlinks */ -static int create_node(char *name, char type, int major, int minor, mode_t mode) +static int create_node(struct udevice *dev) { char filename[255]; int retval = 0; + strncpy(filename, UDEV_ROOT, sizeof(filename)); - strncat(filename, name, sizeof(filename)); - switch (type) { + strncat(filename, dev->name, sizeof(filename)); + + switch (dev->type) { case 'b': - mode |= S_IFBLK; + dev->mode |= S_IFBLK; break; case 'c': case 'u': - mode |= S_IFCHR; + dev->mode |= S_IFCHR; break; case 'p': - mode |= S_IFIFO; + dev->mode |= S_IFIFO; break; default: - dbg("unknown node type %c\n", type); + dbg("unknown node type %c\n", dev->type); return -EINVAL; } - dbg("mknod(%s, %#o, %u, %u)", filename, mode, major, minor); - retval = mknod(filename, mode, makedev(major, minor)); + dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); + retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor)); if (retval) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", - filename, mode, major, minor, strerror(errno)); + filename, dev->mode, dev->major, dev->minor, strerror(errno)); + + // FIXME set the ownership of the node return retval; } @@ -126,7 +130,7 @@ exit: * If it doesn't happen in about 10 seconds, give up. */ #define SECONDS_TO_WAIT_FOR_DEV 10 -int sleep_for_dev(char *device) +int sleep_for_dev(char *path) { char filename[SYSFS_PATH_MAX + 6]; struct stat buf; @@ -134,7 +138,7 @@ int sleep_for_dev(char *device) int retval = -ENODEV; strcpy(filename, sysfs_path); - strcat(filename, device); + strcat(filename, path); strcat(filename, "/dev"); while (loop < SECONDS_TO_WAIT_FOR_DEV) { @@ -154,20 +158,18 @@ exit: return retval; } -int udev_add_device(char *device, char *subsystem) +int udev_add_device(char *path, char *subsystem) { struct sysfs_class_device *class_dev; + struct udevice dev; struct device_attr attr; - int major; - int minor; - char type; int retval = -EINVAL; /* for now, the block layer is the only place where block devices are */ if (strcmp(subsystem, "block") == 0) - type = 'b'; + dev.type = 'b'; else - type = 'c'; + dev.type = 'c'; retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); dbg("sysfs_path = %s", sysfs_path); @@ -176,11 +178,11 @@ int udev_add_device(char *device, char *subsystem) goto exit; } - retval = sleep_for_dev(device); + retval = sleep_for_dev(path); if (retval) goto exit; - class_dev = get_class_dev(device); + class_dev = get_class_dev(path); if (class_dev == NULL) goto exit; @@ -188,21 +190,26 @@ int udev_add_device(char *device, char *subsystem) if (retval) return retval; - retval = get_major_minor(class_dev, &major, &minor); + retval = get_major_minor(class_dev, &dev.major, &dev.minor); if (retval) { dbg("get_major_minor failed"); goto exit; } - retval = udevdb_add_device(device, class_dev, attr.name, type, major, minor, attr.mode); - + strcpy(dev.name, attr.name); + strcpy(dev.owner, attr.owner); + strcpy(dev.group, attr.group); + dev.mode = attr.mode; + + retval = udevdb_add_dev(path, &dev); if (retval != 0) - dbg("udevdb_add_device failed, but we are going to try to create the node anyway. " + dbg("udevdb_add_dev failed, but we are going to try to create the node anyway. " "But remove might not work properly for this device."); sysfs_close_class_device(class_dev); - return create_node(attr.name, type, major, minor, attr.mode); + dbg("name = %s", dev.name); + retval = create_node(&dev); exit: return retval; diff --git a/udev-remove.c b/udev-remove.c index 430f1c901e..c61a948fa0 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -40,15 +40,20 @@ * something different from the kernel name. If we have, us it. If not, use * the default kernel name for lack of anything else to know to do. */ -static char *get_name(char *dev, int major, int minor) +static char *get_name(char *path, int major, int minor) { static char name[100]; + struct udevice *dev; char *temp; - if (udevdb_get_dev(dev, &name[0], sizeof(name)) == 0) + dev = udevdb_get_dev(path); + if (dev != NULL) { + strcpy(name, dev->name); goto exit; + } - temp = strrchr(dev, '/'); + dbg("%s not found in database, falling back on default name", path); + temp = strrchr(path, '/'); if (temp == NULL) return NULL; strncpy(name, &temp[1], sizeof(name)); @@ -84,7 +89,6 @@ int udev_remove_device(char *device, char *subsystem) goto exit; } - udevdb_delete_udevice(name); udevdb_delete_dev(device); return delete_node(name); diff --git a/udev.h b/udev.h index af575c2b17..6d7017ff51 100644 --- a/udev.h +++ b/udev.h @@ -23,6 +23,7 @@ #ifndef UDEV_H #define UDEV_H +#include "libsysfs/libsysfs.h" #ifdef DEBUG #include @@ -62,8 +63,18 @@ struct device_attr { mode_t mode; }; -extern int udev_add_device(char *device, char *subsystem); -extern int udev_remove_device(char *device, char *subsystem); +struct udevice { + char name[NAME_SIZE]; + char owner[OWNER_SIZE]; + char group[GROUP_SIZE]; + char type; + int major; + int minor; + mode_t mode; +}; + +extern int udev_add_device(char *path, char *subsystem); +extern int udev_remove_device(char *path, char *subsystem); extern char **main_argv; extern char **main_envp; diff --git a/udevdb.c b/udevdb.c index e4330f5320..b75bf8048f 100644 --- a/udevdb.c +++ b/udevdb.c @@ -41,212 +41,58 @@ static TDB_CONTEXT *udevdb; -struct sysfsdb_record { - char name[PATH_SIZE]; -}; -/** - * namedb_record - device name is key, remaining udevice info stored here. - */ -struct namedb_record { - char sysfs_dev_path[PATH_SIZE]; - char class_dev_name[NAME_SIZE]; - char class_name[NAME_SIZE]; - char id[ID_SIZE]; - char type; - int major; - int minor; - mode_t mode; -}; - -/** - * udevdb_close: close udev database - */ -static void udevdb_close(void) -{ - if (udevdb != NULL) { - tdb_close(udevdb); - udevdb = NULL; - } -} - -/** - * udevdb_open: opens udev's database - * @method: database can either be in memory - UDEVDB_INTERNAL - or - * written to a file with UDEVDB_DEFAULT. - */ -static int udevdb_open(int method) -{ - udevdb = tdb_open(UDEV_CONFIG_DIR UDEV_DB, 0, method, O_RDWR | O_CREAT, 0644); - if (udevdb == NULL) { - if (method == UDEVDB_INTERNAL) - dbg("Unable to initialize in-memory database"); - else - dbg("Unable to initialize database at %s", UDEV_CONFIG_DIR UDEV_DB); - return -EINVAL; - } - return 0; -} - -static struct sysfsdb_record *sysfsdb_fetch(const char *path) +int udevdb_add_dev(const char *path, const struct udevice *dev) { TDB_DATA key, data; - char keystr[PATH_SIZE+2]; - struct sysfsdb_record *rec = NULL; + char keystr[SYSFS_PATH_MAX]; - if (strlen(path) >= PATH_SIZE) - return NULL; + if ((path == NULL) || (dev == NULL)) + return -ENODEV; - memset(keystr, 0, sizeof(keystr)); + memset(keystr, 0, NAME_SIZE); strcpy(keystr, path); - - dbg("keystr = %s", keystr); - - key.dptr = (void *)keystr; + key.dptr = keystr; key.dsize = strlen(keystr) + 1; - - data = tdb_fetch(udevdb, key); - if (data.dptr == NULL || data.dsize == 0) { - dbg("tdb_fetch did not work :("); - return NULL; - } - rec = (struct sysfsdb_record *)malloc(sizeof(struct sysfsdb_record)); - if (rec == NULL) { - free(data.dptr); - return NULL; - } + data.dptr = (void *)dev; + data.dsize = sizeof(*dev); - memcpy(rec, data.dptr, sizeof(struct sysfsdb_record)); - free(data.dptr); - - return rec; + return tdb_store(udevdb, key, data, TDB_REPLACE); } -/** - * namedb_fetch - */ -static struct namedb_record *namedb_fetch(const char *name) +struct udevice *udevdb_get_dev(const char *path) { TDB_DATA key, data; - char nm_keystr[NAME_SIZE]; - struct namedb_record *nrec = NULL; + struct udevice *dev; - if (name == NULL) - return NULL; - if (strlen(name) >= NAME_SIZE) + if (path == NULL) return NULL; - memset(nm_keystr, 0, NAME_SIZE); - strcpy(nm_keystr, name); - - key.dptr = (void *)nm_keystr; - key.dsize = strlen(nm_keystr) + 1; + key.dptr = (void *)path; + key.dsize = strlen(path) + 1; data = tdb_fetch(udevdb, key); if (data.dptr == NULL || data.dsize == 0) return NULL; - nrec = (struct namedb_record *)malloc(sizeof(struct namedb_record)); - if (nrec == NULL) { - free(data.dptr); - return NULL; - } + dev = malloc(sizeof(*dev)); + if (dev == NULL) + goto exit; - memcpy(nrec, data.dptr, sizeof(struct namedb_record)); + memcpy(dev, data.dptr, sizeof(*dev)); +exit: free(data.dptr); - - return nrec; + return dev; } -static int sysfs_store(const char *path, const struct udevice *dev) -{ - TDB_DATA key, data; - char keystr[PATH_SIZE+2]; - struct sysfsdb_record rec; - int retval = 0; - - if (dev == NULL) - return -ENODEV; - - memset(keystr, 0, sizeof(keystr)); - strcpy(keystr, path); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - strcpy(rec.name, dev->name); - - data.dptr = (void *) &rec; - data.dsize = sizeof(rec); - - retval = tdb_store(udevdb, key, data, TDB_REPLACE); - return retval; -} - -/** - * namedb_store - */ -static int namedb_store(const struct udevice *dev) -{ - TDB_DATA key, data; - char keystr[NAME_SIZE]; - struct namedb_record rec; - int retval = 0; - - if (dev == NULL) - return -1; - - memset(keystr, 0, NAME_SIZE); - strcpy(keystr, dev->name); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - strcpy(rec.sysfs_dev_path, dev->sysfs_dev_path); - strcpy(rec.id, dev->bus_id); - strcpy(rec.class_dev_name, dev->class_dev_name); - strcpy(rec.class_name, dev->class_name); - rec.type = dev->type; - rec.major = dev->major; - rec.minor = dev->minor; - rec.mode = dev->mode; - - data.dptr = (void *) &rec; - data.dsize = sizeof(rec); - - retval = tdb_store(udevdb, key, data, TDB_REPLACE); - return retval; -} - -/** - * namedb_delete - */ -static int namedb_delete(const char *name) +int udevdb_delete_dev(const char *path) { TDB_DATA key; - char keystr[NAME_SIZE]; - int retval = 0; + char keystr[SYSFS_PATH_MAX]; - if (name == NULL) - return -1; - if (strlen(name) >= NAME_SIZE) - return -1; - - memset(keystr, 0, NAME_SIZE); - strcpy(keystr, name); - - key.dptr = (void *)keystr; - key.dsize = strlen(keystr) + 1; - - retval = tdb_delete(udevdb, key); - return retval; -} - -static int sysfs_delete(const char *path) -{ - TDB_DATA key; - char keystr[PATH_SIZE]; + if (path == NULL) + return -EINVAL; memset(keystr, 0, sizeof(keystr)); strcpy(keystr, path); @@ -257,135 +103,34 @@ static int sysfs_delete(const char *path) return tdb_delete(udevdb, key); } -/** - * udevdb_delete_udevice - */ -int udevdb_delete_udevice(const char *name) -{ - struct namedb_record *nrec = NULL; - - if (name == NULL) - return -1; - - nrec = namedb_fetch(name); - if (nrec == NULL) - return -1; - - namedb_delete(name); - free(nrec); - - return 0; -} - -/** - * udevdb_add_device: adds class device to database - */ -int udevdb_add_device(const char *device, const struct sysfs_class_device *class_dev, const char *name, char type, int major, int minor, int mode) -{ - struct udevice dbdev; - - if (class_dev == NULL) - return -ENODEV; - - memset(&dbdev, 0, sizeof(dbdev)); - strncpy(dbdev.name, name, NAME_SIZE); - if (class_dev->sysdevice) { - strncpy(dbdev.sysfs_dev_path, class_dev->sysdevice->directory->path, PATH_SIZE); - strncpy(dbdev.bus_id, class_dev->sysdevice->bus_id, ID_SIZE); - } - strncpy(dbdev.class_dev_name, class_dev->name, NAME_SIZE); -// if ((sysfs_get_name_from_path(subsystem, dbdev.class_name, NAME_SIZE)) != 0) -// strcpy(dbdev.class_name, "unknown"); - dbdev.type = type; - dbdev.major = major; - dbdev.minor = minor; - dbdev.mode = mode; - - if ((sysfs_store(device, &dbdev)) != 0) - return -1; -// if ((namedb_store(&dbdev)) != 0) -// return -1; - - return 0; -} - -/** - * udevdb_get_device: grab's device by name - */ -struct udevice *udevdb_get_udevice(const char *name) -{ - struct namedb_record *nrec = NULL; - struct udevice *dev = NULL; - - if (name == NULL) - return NULL; - - nrec = namedb_fetch(name); - if (nrec == NULL) - return NULL; - - dev = (struct udevice *)malloc(sizeof(struct udevice)); - if (dev == NULL) { - free(nrec); - return NULL; - } - - strcpy(dev->name, name); - strcpy(dev->sysfs_dev_path, nrec->sysfs_dev_path); - strcpy(dev->class_dev_name, nrec->class_dev_name); - strcpy(dev->class_name, nrec->class_name); - strcpy(dev->bus_id, nrec->id); - dev->type = nrec->type; - dev->major = nrec->major; - dev->minor = nrec->minor; - dev->mode = nrec->mode; - - free(nrec); - - return dev; -} - -int udevdb_get_dev(const char *path, char *name, size_t name_size) -{ - struct sysfsdb_record *rec = NULL; - - if ((path == NULL) || (name == NULL) || (name_size < 1)) - return -EINVAL; - - rec = sysfsdb_fetch(path); - if (rec == NULL) - return -ENODEV; - - if (strlen(rec->name) >= name_size) - return -EINVAL; - - strncpy(name, rec->name, name_size); - return 0; -} - -int udevdb_delete_dev(const char *path) -{ - if (path == NULL) - return -EINVAL; - - return sysfs_delete(path); -} - /** * udevdb_exit: closes database */ void udevdb_exit(void) { - udevdb_close(); + if (udevdb != NULL) { + tdb_close(udevdb); + udevdb = NULL; + } } /** * udevdb_init: initializes database + * @init_flag: database can either be in memory - UDEVDB_INTERNAL - or + * written to a file with UDEVDB_DEFAULT. */ int udevdb_init(int init_flag) { if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) - return -1; + return -EINVAL; - return udevdb_open(init_flag); + udevdb = tdb_open(UDEV_CONFIG_DIR UDEV_DB, 0, init_flag, O_RDWR | O_CREAT, 0644); + if (udevdb == NULL) { + if (init_flag == UDEVDB_INTERNAL) + dbg("Unable to initialize in-memory database"); + else + dbg("Unable to initialize database at %s", UDEV_CONFIG_DIR UDEV_DB); + return -EINVAL; + } + return 0; } diff --git a/udevdb.h b/udevdb.h index 57a27bc17f..12f6648369 100644 --- a/udevdb.h +++ b/udevdb.h @@ -6,35 +6,16 @@ #define UDEV_DB "udevdb.tdb" -#define PATH_SIZE 256 - -#define UDEVDB_DEL "#" - /* Udevdb initialization flags */ #define UDEVDB_DEFAULT 0 /* Defaults database to use file */ #define UDEVDB_INTERNAL 1 /* Don't store db on disk, use in memory */ -struct udevice { - char name[NAME_SIZE]; - char sysfs_dev_path[PATH_SIZE]; - char class_dev_name[NAME_SIZE]; - char class_name[NAME_SIZE]; - char bus_id[NAME_SIZE]; - char bus_name[NAME_SIZE]; - char type; - int major; - int minor; - mode_t mode; -}; - /* Function Prototypes */ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); -extern int udevdb_delete_udevice(const char *name); -extern int udevdb_add_device(const char *device, const struct sysfs_class_device *class_dev, const char *name, char type, int major, int minor, int mode); -extern struct udevice *udevdb_get_udevice(const char *name); -extern char *udevdb_get_udevice_by_sysfs(const char *path); -extern int udevdb_get_dev(const char *path, char *name, size_t name_size); + +extern int udevdb_add_dev(const char *path, const struct udevice *dev); +extern struct udevice *udevdb_get_dev(const char *path); extern int udevdb_delete_dev(const char *path); #endif /* _UDEVDB_H_ */ From 3370fb2152d5c812ed4a48b9108a97b446713c9d Mon Sep 17 00:00:00 2001 From: "lkml001@vrfy.org" Date: Mon, 20 Oct 2003 23:33:54 -0700 Subject: [PATCH 0089/4284] [PATCH] man file update changes: o CALLOUT method included o required keys for every match method listed o keywords changed to uppercase in EXAMPLE --- udev.8 | 33 +++++++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/udev.8 b/udev.8 index 771ecfa454..efb02cc618 100644 --- a/udev.8 +++ b/udev.8 @@ -29,38 +29,55 @@ namedev expects its configuration at The file consists of a set of lines. All empty lines and lines beginning with a '#' will be ignored. .br -Every line defines the mapping between device attributes and the name of -the device file. It starts with a keyword defining the method for -overriding the default kernel naming scheme, followed by a list -of keys and ends with the definition of the filename for the device. +Every line defines the mapping between device attributes and the device file +name. It starts with a keyword defining the method used to match, followed by +one ore more keys to compare, optional ownwership and permission settings and +the filename for the device. If no matching configuration is found, +the default kernel device name is used. +.P +.I method, key,[key,...] [owner,] [group,] [mode,] name .TP .B LABEL device label or serial number, like USB serial number, SCSI UUID or file system label +.br +keys: \fBBUS\fP, \fIsysfs_attribute\fP .TP .B NUMBER device number on the bus, like PCI bus id +.br +keys: \fBBUS\fP, \fBID\fP .TP .B TOPOLOGY device position on bus, like physical port of USB device +.br +keys: \fBBUS\fP, \fBPLACE\fP .TP .B REPLACE string replacement of the kernel device name -.P -If no matching configuration is found, the default kernel device name is used. +.br +key: \fBKERNEL_NAME\fP +.TP +.B CALLOUT +calling external program, that returns a string to match +.br +keys: \fBBUS\fP, \fBPROGRAM\fP, \fBID\fP .SH "EXAMPLE" .nf # USB printer to be called lp_color LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_color" # sound card with PCI bus id 00:0b.0 to be called dsp -NUMBER, BUS="pci", id="00:0b.0", NAME="dsp" +NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" # USB mouse at third port of the second hub to be called mouse1 -TOPOLOGY, BUS="usb", place="2.3", NAME="mouse1" +TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" # ttyUSB1 should always be called pda REPLACE, KERNEL="ttyUSB1", NAME="pda" + +# if /sbin/dev_id returns "V0815" device will be called dev0815 +CALLOUT, PROGRAM="/sbin/dev_id", BUS="pci", ID="V0815", NAME="dev0815" .fi .SH "FILES" .nf From fe3fe3b29ffbc7d0ce7dca6a371da31d8b3ff7f8 Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Tue, 21 Oct 2003 01:19:14 -0700 Subject: [PATCH 0090/4284] [PATCH] new version of libsysfs patch Here's the patch applying the latest libsysfs. - adds the latest libsysfs code to udev * new code includes dlist implementation, a generic linked list implementation. Needed our own because LGPL * rearranged structures * provided more functions for accessing directory and attributes - gets rid of ->directory->path references in namedev.c - replaces sysfs_get_value_from_attributes with sysfs_get_classdev_attr --- libsysfs/Makefile | 9 +- libsysfs/dlist.c | 343 ++++++++++++++++++++++++ libsysfs/dlist.h | 195 ++++++++++++++ libsysfs/libsysfs.h | 198 ++++++++++---- libsysfs/sysfs.h | 2 +- libsysfs/sysfs_bus.c | 412 ++++++++++++++++++++++------- libsysfs/sysfs_class.c | 402 +++++++++++++++++++++++----- libsysfs/sysfs_device.c | 495 ++++++++++++++++++++++++++++------ libsysfs/sysfs_dir.c | 572 +++++++++++++++++++++++++++------------- libsysfs/sysfs_driver.c | 304 ++++++++++++++++++++- libsysfs/sysfs_utils.c | 163 ++++++++++-- namedev.c | 56 ++-- 12 files changed, 2606 insertions(+), 545 deletions(-) create mode 100644 libsysfs/dlist.c create mode 100644 libsysfs/dlist.h diff --git a/libsysfs/Makefile b/libsysfs/Makefile index 79cc533959..b82acbdbf2 100644 --- a/libsysfs/Makefile +++ b/libsysfs/Makefile @@ -1,15 +1,15 @@ # Makefile for libsysfs.a # Copyright (c) International Business Machines Corp., 2003 -H_INCLUDE=../include +H_INCLUDE=. LIB_INCLUDE=. OBJS=sysfs_bus.o sysfs_class.o sysfs_device.o sysfs_dir.o sysfs_driver.o \ - sysfs_utils.o + sysfs_utils.o dlist.o # Install directory # Options -CFLAGS=-O2 -Wall -ansi -g +CFLAGS=-O2 -Wall -g # sysfs library LIBSYSFS=libsysfs.a @@ -38,5 +38,8 @@ sysfs_driver.o: sysfs_driver.c sysfs_utils.o: sysfs_utils.c $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_utils.c +dlist.o: dlist.c + $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c dlist.c + clean: $(RM) *.o *~ core $(LIBSYSFS) diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c new file mode 100644 index 0000000000..6dfcf726ba --- /dev/null +++ b/libsysfs/dlist.c @@ -0,0 +1,343 @@ +/* + * dlist.c + * + * Copyright (C) 2003 Eric J Bohm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021110307 USA + * + */ + + +/* Double linked list implementation. + + * You allocate the data and give dlist the pointer. + * If your data is complex set the dlist->del_func to a an appropriate + * delete function. Otherwise dlist will just use free. + +*/ +#include "dlist.h" + +/* + * Return pointer to node at marker. + * else null if no nodes. + */ + +inline void *dlist_mark(Dlist *list) +{ + if(list->marker!=NULL) + return(list->marker->data); + else + return(NULL); +} + +/* + * Set marker to start. + */ + +inline void dlist_start(Dlist *list) +{ + list->marker=list->head; +} + +/* + * Set marker to end. + */ + +inline void dlist_end(Dlist *list) +{ + list->marker=list->head; +} + +/* internal use function + * quickie inline to consolidate the marker movement logic + * in one place + * + * when direction true it moves marker after + * when direction false it moves marker before. + * return pointer to data at new marker + * if nowhere to move the marker in desired direction return null + */ +inline void *_dlist_mark_move(Dlist *list,int direction) +{ + if(direction) + { + if( list->marker->next!=NULL) + list->marker=list->marker->next; + else + return(NULL); + } + else + { + if( list->marker->prev!=NULL) + list->marker=list->marker->prev; + else + return(NULL); + } + if(list->marker!=list->head) + return(list->marker->data); + else + return(NULL); +} + +/* + * Create new linked list to store nodes of datasize. + * return null if list cannot be created. + */ +Dlist *dlist_new(size_t datasize) +{ + Dlist *list=NULL; + if((list=malloc(sizeof(Dlist)))) + { + list->marker=NULL; + list->count=0L; + list->data_size=datasize; + list->del_func=free; + list->head=&(list->headnode); + list->head->prev=NULL; + list->head->next=NULL; + list->head->data=NULL; + } + return(list); +} + +/* + * Create new linked list to store nodes of datasize set list + * data node delete function to the passed in del_func + * return null if list cannot be created. + */ +Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)) +{ + Dlist *list=NULL; + list=dlist_new(datasize); + if(list!=NULL) + list->del_func=del_func; + return(list); +} + + +/* + * remove marker node from list + * call data_delete function on data if registered. + * otherwise call free. + * when direction true it moves marker after + * when direction false it moves marker before. + * free marker node + * return nothing. + */ +void dlist_delete(Dlist *list,int direction) +{ + if((list->marker != list->head)&&(list->marker!=NULL)) + { + DL_node *corpse; + corpse=list->marker; + _dlist_mark_move(list,direction); + if(list->head->next==corpse) + list->head->next=corpse->next; + if(list->head->prev==corpse) + list->head->prev=corpse->prev; + if(corpse->prev!=NULL) //should be impossible + corpse->prev->next=corpse->next; + if(corpse->next!=NULL) //should be impossible + corpse->next->prev=corpse->prev; + list->del_func(corpse->data); + list->count--; + free(corpse); + } +} + +/* + * Insert node containing data at marker. + * If direction true it inserts after. + * If direction false it inserts before. + * move marker to inserted node + * return pointer to inserted node + */ +void *dlist_insert(Dlist *list,void *data,int direction) +{ + DL_node *new_node=NULL; + if(list==NULL || data==NULL) + return(NULL); + if(list->marker==NULL) //in case the marker ends up unset + list->marker=list->head; + if((new_node=malloc(sizeof(DL_node)))) + { + new_node->data=data; + new_node->prev=NULL; + new_node->next=NULL; + list->count++; + if(list->head->next==NULL) //no l + { + list->head->next=list->head->prev=new_node; + new_node->prev=list->head; + new_node->next=list->head; + } + else if(direction) + { + new_node->next=list->marker->next; + new_node->prev=list->marker; + list->marker->next->prev=new_node; + list->marker->next=new_node; + } + else + { + new_node->prev=list->marker->prev; + new_node->next=list->marker; + list->marker->prev->next=new_node; + list->marker->prev=new_node; + } + list->marker=new_node; + } + else + { + return(NULL); + } + return(list->marker->data); +} + +/* + * Remove DL_node from list without deallocating data. + * if marker == killme . + * when direction true it moves marker after + * when direction false it moves marker before. + * to previous if there is no next. + */ +void *_dlist_remove(Dlist *list,DL_node *killme,int direction) +{ + if(killme!=NULL) + { + void *killer_data=killme->data; + // take care of head and marker pointers. + if(list->marker==killme) + _dlist_mark_move(list,direction); + if(killme ==list->head->next) + list->head->next=killme->next; + if(killme==list->head->prev) + list->head->prev=killme->prev; + // remove from list + if(killme->prev !=NULL) + killme->prev->next=killme->next; + if(killme->next !=NULL) + killme->next->prev=killme->prev; + list->count--; + free(killme); + return(killer_data); + } + else + return (NULL); +} + + +/* + * Insert node containing data after end. + */ +void dlist_push(Dlist *list,void *data) +{ + list->marker=list->head->prev; + dlist_insert(list,data,1); +} + +/* + * Insert node containing data at start. + */ + +void dlist_unshift(Dlist *list,void *data) + +{ + list->marker=list->head->next; + dlist_insert(list,data,0); +} + + +/* + * Remove end node from list. + * Return pointer to data in removed node. + * Null if no nodes. + */ + +void *dlist_pop(Dlist *list) +{ + return(_dlist_remove(list,list->head->prev,0)); +} + +/* + * Remove start node from list. + * Return pointer to data in removed node. + * Null if no nodes. + */ + +void *dlist_shift(Dlist *list) +{ + return(_dlist_remove(list,list->head->next,1)); +} + + +/* + * destroy the list freeing all memory + */ + + +void dlist_destroy(Dlist *list) +{ + if(list !=NULL) + { + dlist_start(list); + dlist_next(list); + while (dlist_mark(list)) { + dlist_delete(list,1); + } + free(list); + } +} + +/** + * Return void pointer to list_data element matching comp function criteria + * else null + * Does not move the marker. + */ + +void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)) +{ + /* test the comp function on each node */ + struct dl_node *nodepointer; + dlist_for_each_nomark(list,nodepointer) + if(comp(target,nodepointer->data)) + return(nodepointer->data); + return(NULL); +} + +/** + * Apply the node_operation function to each data node in the list + */ +void dlist_transform(struct dlist *list, void (*node_operation)(void *)) +{ + struct dl_node *nodepointer; + dlist_for_each_nomark(list,nodepointer) + node_operation(nodepointer->data); +} + +/** + * insert new into list in sorted order + * sorter function in form int sorter(new,ith) + * must return 1 for when new should go before ith + * else 0 + * return pointer to inserted node + * NOTE: assumes list is already sorted + */ +void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, void *)) +{ + for(dlist_start(list),dlist_next(list); \ + list->marker!=list->head && !sorter(new,list->marker->data);dlist_next(list)); + return(dlist_insert_before(list,new)); +} diff --git a/libsysfs/dlist.h b/libsysfs/dlist.h new file mode 100644 index 0000000000..5da79f9ba2 --- /dev/null +++ b/libsysfs/dlist.h @@ -0,0 +1,195 @@ +/* + * dlist.h + * + * Copyright (C) 2003 Eric J Bohm + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#ifndef _DLIST_H_ +#define _DLIST_H_ + +/* Double linked list header. + +* navigate your list with DLIST_PREV and DLIST_NEXT. These are macros +* so function call overhead is minimized. + +* Supports perl style push, pop, shift, unshift list semantics. + +* You allocate the data and give dlist the pointer. If your data is +* complex set the dlist->del_func to a an appropriate delete using +* dlist_new_with_delete. Your delete function must match +(void * )(del(void *) +*Otherwise dlist will just use free. + +* NOTE: The small amount of pain involved in doing that allows us to +* avoid copy in copy out semantics. + +* Dlist uses an internal mark pointer to keep track of where you are +* in the list. + +* insert and delete take a directional parameter. Where direction +* corresponds to the direction in which you want the list to go. +* true direction corresponded to progressing forward in the last +* false to regressing in the list. +* so a dlist_insert(yourlist,item,1) will insert it after the mark +* so a dlist_insert(yourlist,item,0) will insert it before the mark +* any insert will move the mark to the new node regardless of the direction. + +* Just use the dlist_(insert|delete)_(before|after) macros if you do not want +* to think about it. + +*/ +#include +typedef struct dl_node { + struct dl_node *prev; + struct dl_node *next; + void *data; +} DL_node; + +typedef struct dlist { + DL_node *marker; + unsigned long count; + size_t data_size; + void (*del_func)(void *); + DL_node headnode; + DL_node *head; +} Dlist; + +Dlist *dlist_new(size_t datasize); +Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)); +void *_dlist_mark_move(Dlist *list,int direction); +void *dlist_mark(Dlist *); +void dlist_start(Dlist *); +void dlist_end(Dlist *); + +void *dlist_insert(Dlist *,void *,int) ; + +void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, void *)); + +void dlist_delete(Dlist *,int); + +void dlist_push(Dlist *,void *); + +void dlist_unshift(Dlist *,void *); + +void *dlist_pop(Dlist *); + +void *dlist_shift(Dlist *); + +void dlist_destroy(Dlist *); + +void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)); +void dlist_transform(struct dlist *list, void (*node_operation)(void *)); + + +/* + * _dlist_remove is for internal use only + * _dlist_mark_move is for internal use only + */ +void *_dlist_remove(struct dlist *,struct dl_node *,int ); + +#define dlist_prev(A) _dlist_mark_move((A),0) +#define dlist_next(A) _dlist_mark_move((A),1) + +#define dlist_insert_before(A,B) dlist_insert((A),(B),0) +#define dlist_insert_after(A,B) dlist_insert((A),(B),1) + +#define dlist_delete_before(A) dlist_delete((A),0) +#define dlist_delete_after(A) dlist_delete((A),1) + +/** + * provide for loop header which iterates the mark from start to end + * list: the dlist pointer, use dlist_mark(list) to get iterator + */ +#define dlist_for_each(list) \ + for(dlist_start(list),dlist_next(list); \ + (list)->marker!=(list)->head;dlist_next(list)) + +/** + * provide for loop header which iterates the mark from end to start + * list: the dlist pointer, use dlist_mark(list) to get iterator + */ +#define dlist_for_each_rev(list) \ + for(dlist_end(list),dlist_prev(list); \ + (list)->marker!=(list)->head;dlist_prev(list)) + +/** + * provide for loop header which iterates through the list without moving mark + * list: the dlist_pointer + * iterator: dl_node pointer to iterate + */ +#define dlist_for_each_nomark(list,iterator) \ + for((iterator)=(list)->head->next; (iterator)!=(list)->head; \ + (iterator)=(iterator)->next) + +/** + * provide for loop header which iterates through the list without moving mark + * in reverse + * list: the dlist_pointer + * iterator: dl_node pointer to iterate + */ +#define dlist_for_each_nomark_rev(list,iterator) \ + for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \ + (iterator)=(iterator)->prev) +/** + * provide for loop header which iterates through the list providing a + * data iterator + * list: the dlist pointer + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ + +#define dlist_for_each_data(list,data_iterator,datatype) \ + for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \ + (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list)) + +/** + * provide for loop header which iterates through the list providing a + * data iterator in reverse + * list: the dlist pointer + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ +#define dlist_for_each_data_rev(list,data_iterator,datatype) \ + for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \ + (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list)) + +/** + * provide for loop header which iterates through the list providing a + * data iterator without moving the mark + * list: the dlist pointer + * iterator: the dl_node pointer to iterate + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ + +#define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \ + for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \ + (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator)) + +/** + * provide for loop header which iterates through the list providing a + * data iterator in reverse without moving the mark + * list: the dlist pointer + * iterator: the dl_node pointer to iterate + * data_iterator: the pointer of type datatype to iterate + * datatype: actual type of the contents in the dl_node->data + */ +#define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \ + for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \ + (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator)) + +#endif /* _DLIST_H_ */ diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index 01143954e7..ccb9898cb5 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -3,7 +3,7 @@ * * Header Definitions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,6 +24,7 @@ #define _LIBSYSFS_H_ #include +#include "dlist.h" /* * Generic #defines go here.. @@ -32,11 +33,17 @@ #define SYSFS_PROC_MNTS "/proc/mounts" #define SYSFS_BUS_DIR "/bus" #define SYSFS_CLASS_DIR "/class" +#define SYSFS_BLOCK_DIR "/block" #define SYSFS_DEVICES_DIR "/devices" #define SYSFS_DEVICES_NAME "devices" #define SYSFS_DRIVERS_DIR "/drivers" #define SYSFS_DRIVERS_NAME "drivers" #define SYSFS_NAME_ATTRIBUTE "name" +#define SYSFS_UNKNOWN "unknown" + +/* Some "block" subsystem specific #defines */ +#define SYSFS_QUEUE_NAME "queue" +#define SYSFS_IOSCHED_NAME "iosched" #define SYSFS_PATH_MAX 255 #define SYSFS_NAME_LEN 50 @@ -46,65 +53,84 @@ #define SYSFS_METHOD_STORE 0x02 /* attr can be changed by user */ struct sysfs_attribute { - struct sysfs_attribute *next; - char path[SYSFS_PATH_MAX]; - char *value; + unsigned char *value; unsigned short len; /* value length */ unsigned short method; /* show and store */ + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; }; -struct sysfs_dlink { - struct sysfs_dlink *next; - char name[SYSFS_NAME_LEN]; - struct sysfs_directory *target; +struct sysfs_link { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + unsigned char target[SYSFS_PATH_MAX]; }; struct sysfs_directory { - struct sysfs_directory *next; - char path[SYSFS_PATH_MAX]; - struct sysfs_directory *subdirs; - struct sysfs_dlink *links; - struct sysfs_attribute *attributes; + struct dlist *subdirs; + struct dlist *links; + struct dlist *attributes; + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; }; struct sysfs_driver { - struct sysfs_driver *next; - char name[SYSFS_NAME_LEN]; - struct sysfs_directory *directory; - struct sysfs_device *device; + struct dlist *devices; + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct sysfs_directory *directory; }; struct sysfs_device { - struct sysfs_device *next; - char name[SYSFS_NAME_LEN]; - char bus_id[SYSFS_NAME_LEN]; - struct sysfs_driver *driver; + struct sysfs_device *parent; + struct dlist *children; + unsigned char name[SYSFS_NAME_LEN]; + unsigned char bus_id[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + unsigned char driver_name[SYSFS_NAME_LEN]; + + /* for internal use only */ + struct sysfs_directory *directory; +}; + +struct sysfs_root_device { + struct dlist *devices; + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ struct sysfs_directory *directory; - struct sysfs_device *parent; - struct sysfs_device *children; }; struct sysfs_bus { - struct sysfs_bus *next; - char name[SYSFS_NAME_LEN]; - struct sysfs_directory *directory; - struct sysfs_driver *drivers; - struct sysfs_device *devices; + struct dlist *drivers; + struct dlist *devices; + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* internal use only */ + struct sysfs_directory *directory; }; struct sysfs_class_device { - struct sysfs_class_device *next; - char name[SYSFS_NAME_LEN]; - struct sysfs_directory *directory; struct sysfs_device *sysdevice; /* NULL if virtual */ struct sysfs_driver *driver; /* NULL if not implemented */ + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct sysfs_directory *directory; }; struct sysfs_class { - struct sysfs_class *next; - char name[SYSFS_NAME_LEN]; - struct sysfs_directory *directory; - struct sysfs_class_device *devices; + struct dlist *devices; + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct sysfs_directory *directory; }; #ifdef __cplusplus @@ -114,46 +140,108 @@ extern "C" { /* * Function Prototypes */ -extern int sysfs_get_mnt_path(char *mnt_path, size_t len); -extern int sysfs_get_name_from_path(const char *path, char *name, size_t len); -extern int sysfs_get_link(const char *path, char *target, size_t len); +extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); +extern int sysfs_get_name_from_path(const unsigned char *path, + unsigned char *name, size_t len); +extern int sysfs_get_link(const unsigned char *path, unsigned char *target, + size_t len); +extern struct dlist *sysfs_open_subsystem_list(unsigned char *name); +extern struct dlist *sysfs_open_bus_devices_list(unsigned char *name); +extern void sysfs_close_list(struct dlist *list); /* sysfs directory and file access */ extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); -extern struct sysfs_attribute *sysfs_open_attribute(const char *path); +extern struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path); extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); -extern int sysfs_read_attribute_value(const char *attrpath, char *value, - size_t vsize); -extern char *sysfs_get_value_from_attributes(struct sysfs_attribute *attr, - const char * name); +extern int sysfs_read_attribute_value(const unsigned char *attrpath, + unsigned char *value, size_t vsize); +extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, + const unsigned char *new_value, size_t len); +extern unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, + const unsigned char * name); extern void sysfs_close_directory(struct sysfs_directory *sysdir); -extern struct sysfs_directory *sysfs_open_directory(const char *path); +extern struct sysfs_directory *sysfs_open_directory(const unsigned char *path); extern int sysfs_read_directory(struct sysfs_directory *sysdir); -extern void sysfs_close_dlink(struct sysfs_dlink *dlink); -extern struct sysfs_dlink *sysfs_open_dlink(const char *linkpath); -extern int sysfs_read_dlinks(struct sysfs_dlink *dlink); +extern int sysfs_read_all_subdirs(struct sysfs_directory *sysdir); +extern struct sysfs_directory *sysfs_get_subdirectory + (struct sysfs_directory *dir, unsigned char *subname); +extern void sysfs_close_link(struct sysfs_link *ln); +extern struct sysfs_link *sysfs_open_link(const unsigned char *lnpath); +extern struct sysfs_link *sysfs_get_directory_link(struct sysfs_directory *dir, + unsigned char *linkname); +extern struct sysfs_link *sysfs_get_subdirectory_link + (struct sysfs_directory *dir, unsigned char *linkname); +extern struct sysfs_attribute *sysfs_get_directory_attribute + (struct sysfs_directory *dir, unsigned char *attrname); /* sysfs driver access */ extern void sysfs_close_driver(struct sysfs_driver *driver); -extern struct sysfs_driver *sysfs_open_driver(const char *path); +extern struct sysfs_driver *sysfs_open_driver(const unsigned char *path); +extern struct sysfs_attribute *sysfs_get_driver_attr + (struct sysfs_driver *drv, const unsigned char *name); +extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); +extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver); +extern void sysfs_close_driver_by_name(struct sysfs_driver *driver); +extern struct sysfs_driver *sysfs_open_driver_by_name + (const unsigned char *drv_name, const unsigned char *bus, size_t bsize); +extern int sysfs_write_driver_attr(unsigned char *drv, unsigned char *attrib, + unsigned char *value, size_t len); +extern int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib, + unsigned char *value, size_t len); /* generic sysfs device access */ +extern void sysfs_close_root_device(struct sysfs_root_device *root); +extern struct sysfs_root_device *sysfs_open_root_device + (const unsigned char *name); extern void sysfs_close_device(struct sysfs_device *dev); -extern void sysfs_close_device_tree(struct sysfs_device *dev); -extern struct sysfs_device *sysfs_open_device(const char *path); -extern struct sysfs_device *sysfs_open_device_tree(const char *path); +extern struct sysfs_device *sysfs_open_device(const unsigned char *path); extern struct sysfs_attribute *sysfs_get_device_attr - (struct sysfs_device *dev, const char *name); + (struct sysfs_device *dev, const unsigned char *name); +extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); +extern struct sysfs_device *sysfs_open_device_by_id + (const unsigned char *bus_id, const unsigned char *bus, size_t bsize); +extern int sysfs_write_device_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len); +extern int sysfs_read_device_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len); /* generic sysfs bus access */ extern void sysfs_close_bus(struct sysfs_bus *bus); -extern struct sysfs_bus *sysfs_open_bus(const char *name); +extern struct sysfs_bus *sysfs_open_bus(const unsigned char *name); +extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, + unsigned char *id); +extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, + unsigned char *drvname); +extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus); +extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, + unsigned char *attrname); +extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, + unsigned char *dev_id); +extern int sysfs_find_device_bus(const unsigned char *dev_id, + unsigned char *busname, size_t bsize); +extern int sysfs_find_driver_bus(const unsigned char *driver, + unsigned char *busname, size_t bsize); /* generic sysfs class access */ extern void sysfs_close_class_device(struct sysfs_class_device *dev); -extern struct sysfs_class_device *sysfs_open_class_device(const char *path); +extern struct sysfs_class_device *sysfs_open_class_device + (const unsigned char *path); extern void sysfs_close_class(struct sysfs_class *cls); -extern struct sysfs_class *sysfs_open_class(const char *name); +extern struct sysfs_class *sysfs_open_class(const unsigned char *name); +extern struct sysfs_class_device *sysfs_get_class_device + (struct sysfs_class *class, unsigned char *name); +extern struct sysfs_class_device *sysfs_open_class_device_by_name + (const unsigned char *class, unsigned char *name); +extern struct dlist *sysfs_get_classdev_attributes + (struct sysfs_class_device *cdev); +extern int sysfs_find_device_class(const unsigned char *bus_id, + unsigned char *classname, size_t bsize); +extern struct sysfs_attribute *sysfs_get_classdev_attr + (struct sysfs_class_device *clsdev, const unsigned char *name); +extern int sysfs_write_classdev_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len); +extern int sysfs_read_classdev_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len); #ifdef __cplusplus } diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index eb2a002958..00599954fd 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -3,7 +3,7 @@ * * Internal Header Definitions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index b2e2b2dd71..19fc275d84 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -3,7 +3,7 @@ * * Generic bus utility functions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,28 +23,62 @@ #include "libsysfs.h" #include "sysfs.h" +static void sysfs_close_dev(void *dev) +{ + sysfs_close_device((struct sysfs_device *)dev); +} + +static void sysfs_close_drv(void *drv) +{ + sysfs_close_driver((struct sysfs_driver *)drv); +} + +/* + * compares devices' bus ids. + * @a: device id looking for + * @b: sysfs_device comparing being compared + * returns 1 if a==b->bus_id or 0 not equal + */ +static int bus_device_id_equal(void *a, void *b) +{ + if (a == NULL || b == NULL) + return 0; + + if (strcmp(((unsigned char *)a), ((struct sysfs_device *)b)->bus_id) + == 0) + return 1; + return 0; +} + +/* + * compares drivers' names. + * @a: driver name looking for + * @b: sysfs_driver comparing being compared + * returns 1 if a==b->name or 0 not equal + */ +static int bus_driver_name_equal(void *a, void *b) +{ + if (a == NULL || b == NULL) + return 0; + + if (strcmp(((unsigned char *)a), ((struct sysfs_driver *)b)->name) == 0) + return 1; + return 0; +} + /** * sysfs_close_bus: close single bus * @bus: bus structure */ void sysfs_close_bus(struct sysfs_bus *bus) { - struct sysfs_device *curdev = NULL, *nextdev = NULL; - struct sysfs_driver *curdrv = NULL, *nextdrv = NULL; - if (bus != NULL) { if (bus->directory != NULL) sysfs_close_directory(bus->directory); - for (curdev = bus->devices; curdev != NULL; - curdev = nextdev) { - nextdev = curdev->next; - sysfs_close_device(curdev); - } - for (curdrv = bus->drivers; curdrv != NULL; - curdrv = nextdrv) { - nextdrv = curdrv->next; - sysfs_close_driver(curdrv); - } + if (bus->devices) + dlist_destroy(bus->devices); + if (bus->drivers) + dlist_destroy(bus->drivers); free(bus); } } @@ -62,10 +96,10 @@ static struct sysfs_bus *alloc_bus(void) * open_bus_dir: opens up sysfs bus directory * returns sysfs_directory struct with success and NULL with error */ -static struct sysfs_directory *open_bus_dir(const char *name) +static struct sysfs_directory *open_bus_dir(const unsigned char *name) { - struct sysfs_directory *busdir = NULL, *cur = NULL, *next = NULL; - char buspath[SYSFS_PATH_MAX]; + struct sysfs_directory *busdir = NULL; + unsigned char buspath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; @@ -74,7 +108,7 @@ static struct sysfs_directory *open_bus_dir(const char *name) memset(buspath, 0, SYSFS_PATH_MAX); if ((sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) != 0) { - dprintf(stderr, "Sysfs not supported on this system\n"); + dprintf("Sysfs not supported on this system\n"); return NULL; } @@ -84,53 +118,22 @@ static struct sysfs_directory *open_bus_dir(const char *name) busdir = sysfs_open_directory(buspath); if (busdir == NULL) { errno = EINVAL; - dprintf(stderr,"Bus %s not supported on this system\n", + dprintf("Bus %s not supported on this system\n", name); return NULL; } if ((sysfs_read_directory(busdir)) != 0) { - dprintf(stderr, "Error reading %s bus dir %s\n", name, + dprintf("Error reading %s bus dir %s\n", name, buspath); sysfs_close_directory(busdir); return NULL; } /* read in devices and drivers subdirs */ - for (cur = busdir->subdirs; cur != NULL; cur = next) { - next = cur->next; - if ((sysfs_read_directory(cur)) != 0) - continue; - } + sysfs_read_all_subdirs(busdir); return busdir; } -/** - * add_dev_to_bus: adds a bus device to bus device list - * @bus: bus to add the device - * @dev: device to add - */ -static void add_dev_to_bus(struct sysfs_bus *bus, struct sysfs_device *dev) -{ - if (bus != NULL && dev != NULL) { - dev->next = bus->devices; - bus->devices = dev; - } -} - -/** - * add_driver_to_bus: adds a bus driver to bus driver list - * @bus: bus to add driver to - * @driver: driver to add - */ -static void add_driver_to_bus(struct sysfs_bus *bus, - struct sysfs_driver *driver) -{ - if (bus != NULL && driver != NULL) { - driver->next = bus->drivers; - bus->drivers = driver; - } -} - /** * get_all_bus_devices: gets all devices for bus * @bus: bus to get devices for @@ -140,29 +143,33 @@ static int get_all_bus_devices(struct sysfs_bus *bus) { struct sysfs_device *bdev = NULL; struct sysfs_directory *cur = NULL; - struct sysfs_dlink *curl = NULL, *nextl = NULL; - char dirname[SYSFS_NAME_LEN]; + struct sysfs_link *curl = NULL; if (bus == NULL || bus->directory == NULL) { errno = EINVAL; return -1; } - for (cur = bus->directory->subdirs; cur != NULL; cur = cur->next) { - memset(dirname, 0, SYSFS_NAME_LEN); - if ((sysfs_get_name_from_path(cur->path, dirname, - SYSFS_NAME_LEN)) != 0) + if (bus->directory->subdirs == NULL) + return 0; + + dlist_for_each_data(bus->directory->subdirs, cur, + struct sysfs_directory) { + if (strcmp(cur->name, SYSFS_DEVICES_NAME) != 0) continue; - if (strcmp(dirname, SYSFS_DEVICES_NAME) != 0) + if (cur->links == NULL) continue; - for (curl = cur->links; curl != NULL; curl = nextl) { - nextl = curl->next; - bdev = sysfs_open_device(curl->target->path); + dlist_for_each_data(cur->links, curl, struct sysfs_link) { + bdev = sysfs_open_device(curl->target); if (bdev == NULL) { - dprintf(stderr, "Error opening device at %s\n", - curl->target->path); + dprintf("Error opening device at %s\n", + curl->target); continue; } - add_dev_to_bus(bus, bdev); + if (bus->devices == NULL) + bus->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_dev); + dlist_unshift(bus->devices, bdev); } } @@ -177,31 +184,35 @@ static int get_all_bus_devices(struct sysfs_bus *bus) static int get_all_bus_drivers(struct sysfs_bus *bus) { struct sysfs_driver *driver = NULL; - struct sysfs_directory *cur = NULL, *next = NULL; - struct sysfs_directory *cursub = NULL, *nextsub = NULL; - char dirname[SYSFS_NAME_LEN]; + struct sysfs_directory *cur = NULL; + struct sysfs_directory *cursub = NULL; if (bus == NULL || bus->directory == NULL) { errno = EINVAL; return -1; } - for (cur = bus->directory->subdirs; cur != NULL; cur = next) { - next = cur->next; - memset(dirname, 0, SYSFS_NAME_LEN); - if ((sysfs_get_name_from_path(cur->path, dirname, - SYSFS_NAME_LEN)) != 0) + if (bus->directory->subdirs == NULL) + return 0; + + dlist_for_each_data(bus->directory->subdirs, cur, + struct sysfs_directory) { + if (strcmp(cur->name, SYSFS_DRIVERS_NAME) != 0) continue; - if (strcmp(dirname, SYSFS_DRIVERS_NAME) != 0) + if (cur->subdirs == NULL) continue; - for (cursub = cur->subdirs; cursub != NULL; cursub = nextsub) { - nextsub = cursub->next; + dlist_for_each_data(cur->subdirs, cursub, + struct sysfs_directory) { driver = sysfs_open_driver(cursub->path); if (driver == NULL) { - dprintf(stderr, "Error opening driver at %s\n", + dprintf("Error opening driver at %s\n", cursub->path); continue; } - add_driver_to_bus(bus, driver); + if (bus->drivers == NULL) + bus->drivers = dlist_new_with_delete + (sizeof(struct sysfs_driver), + sysfs_close_drv); + dlist_unshift(bus->drivers, driver); } } @@ -214,20 +225,22 @@ static int get_all_bus_drivers(struct sysfs_bus *bus) * @busid: busid of device to match * returns 1 if found and 0 if not found */ -static int match_bus_device_to_driver(struct sysfs_driver *driver, char *busid) +static int match_bus_device_to_driver(struct sysfs_driver *driver, + unsigned char *busid) { - struct sysfs_dlink *cur = NULL, *next = NULL; + struct sysfs_link *cur = NULL; int found = 0; if (driver == NULL || driver->directory == NULL || busid == NULL) { errno = EINVAL; return found; } - for (cur = driver->directory->links; cur != NULL && found == 0; - cur = next) { - next = cur->next; - if ((strcmp(cur->name, busid)) == 0) - found++; + if (driver->directory->links != NULL) { + dlist_for_each_data(driver->directory->links, cur, + struct sysfs_link) { + if ((strcmp(cur->name, busid)) == 0) + found++; + } } return found; } @@ -238,19 +251,22 @@ static int match_bus_device_to_driver(struct sysfs_driver *driver, char *busid) */ static void link_bus_devices_to_drivers(struct sysfs_bus *bus) { - struct sysfs_device *dev = NULL, *nextdev = NULL; - struct sysfs_driver *drv = NULL, *nextdrv = NULL; + struct sysfs_device *dev = NULL; + struct sysfs_driver *drv = NULL; if (bus != NULL && bus->devices != NULL && bus->drivers != NULL) { - for (dev = bus->devices; dev != NULL; dev = nextdev) { - nextdev = dev->next; - - for (drv = bus->drivers; drv != NULL; drv = nextdrv) { - nextdrv = drv->next; + dlist_for_each_data(bus->devices, dev, struct sysfs_device) { + dlist_for_each_data(bus->drivers, drv, + struct sysfs_driver) { if ((match_bus_device_to_driver(drv, - dev->bus_id)) != 0) { - dev->driver = drv; - drv->device = dev; + dev->bus_id)) != 0) { + strncpy(dev->driver_name, drv->name, + SYSFS_NAME_LEN); + if (drv->devices == NULL) + drv->devices = dlist_new + (sizeof(struct + sysfs_device)); + dlist_unshift(drv->devices, dev); } } } @@ -261,7 +277,7 @@ static void link_bus_devices_to_drivers(struct sysfs_bus *bus) * sysfs_open_bus: opens specific bus and all its devices on system * returns sysfs_bus structure with success or NULL with error. */ -struct sysfs_bus *sysfs_open_bus(const char *name) +struct sysfs_bus *sysfs_open_bus(const unsigned char *name) { struct sysfs_bus *bus = NULL; struct sysfs_directory *busdir = NULL; @@ -273,25 +289,26 @@ struct sysfs_bus *sysfs_open_bus(const char *name) bus = alloc_bus(); if (bus == NULL) { - perror("malloc"); + dprintf("calloc failed\n"); return NULL; } strcpy(bus->name, name); busdir = open_bus_dir(name); if (busdir == NULL) { - dprintf(stderr,"Invalid bus, %s not supported on this system\n", + dprintf("Invalid bus, %s not supported on this system\n", name); sysfs_close_bus(bus); return NULL; } + strcpy(bus->path, busdir->path); bus->directory = busdir; if ((get_all_bus_devices(bus)) != 0) { - dprintf(stderr, "Error reading %s bus devices\n", name); + dprintf("Error reading %s bus devices\n", name); sysfs_close_bus(bus); return NULL; } if ((get_all_bus_drivers(bus)) != 0) { - dprintf(stderr, "Error reading %s bus drivers\n", name); + dprintf("Error reading %s bus drivers\n", name); sysfs_close_bus(bus); return NULL; } @@ -299,3 +316,198 @@ struct sysfs_bus *sysfs_open_bus(const char *name) return bus; } + +/** + * sysfs_get_bus_device: Get specific device on bus using device's id + * @bus: bus to find device on + * @id: bus_id for device + * returns struct sysfs_device reference or NULL if not found. + */ +struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, + unsigned char *id) +{ + if (bus == NULL || id == NULL) { + errno = EINVAL; + return NULL; + } + + return (struct sysfs_device *)dlist_find_custom(bus->devices, id, + bus_device_id_equal); +} + +/** + * sysfs_get_bus_driver: Get specific driver on bus using driver name + * @bus: bus to find driver on + * @drvname: name of driver + * returns struct sysfs_driver reference or NULL if not found. + */ +struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, + unsigned char *drvname) +{ + if (bus == NULL || drvname == NULL) { + errno = EINVAL; + return NULL; + } + + return (struct sysfs_driver *)dlist_find_custom(bus->drivers, drvname, + bus_driver_name_equal); +} + +/** + * sysfs_get_bus_attributes: returns bus' dlist of attributes + * @bus: bus to get attributes for. + * returns dlist of attributes or NULL if there aren't any. + */ +struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) +{ + if (bus == NULL || bus->directory == NULL) + return NULL; + return bus->directory->attributes; +} + +/** + * sysfs_get_bus_attribute: gets a specific bus attribute, if buses had + * attributes. + * @bus: bus to retrieve attribute from + * @attrname: attribute name to retrieve + * returns reference to sysfs_attribute if found or NULL if not found + */ +struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, + unsigned char *attrname) +{ + if (bus == NULL || bus->directory == NULL || attrname == NULL) { + errno = EINVAL; + return NULL; + } + return sysfs_get_directory_attribute(bus->directory, attrname); +} + +/** + * sysfs_open_bus_device: locates a device on a bus and returns it. Device + * must be closed using sysfs_close_device. + * @busname: Name of bus to search + * @dev_id: Id of device on bus. + * returns sysfs_device if found or NULL if not. + */ +struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, + unsigned char *dev_id) +{ + struct sysfs_device *rdev = NULL; + char path[SYSFS_PATH_MAX]; + + if (busname == NULL || dev_id == NULL) { + errno = EINVAL; + return NULL; + } + + memset(path, 0, SYSFS_PATH_MAX); + if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) { + dprintf("Error getting sysfs mount point\n"); + return NULL; + } + + strcat(path, SYSFS_BUS_DIR); + strcat(path, "/"); + strcat(path, busname); + strcat(path, SYSFS_DEVICES_DIR); + strcat(path, "/"); + strcat(path, dev_id); + + rdev = sysfs_open_device(path); + if (rdev == NULL) { + dprintf("Error getting device %s on bus %s\n", + dev_id, busname); + return NULL; + } + + return rdev; +} + +/** + * sysfs_find_device_bus: locates the bus a device is on. + * @dev_id: device id. + * @busname: buffer to copy name to + * @bsize: buffer size + * returns 0 with success or -1 with error + */ +int sysfs_find_device_bus(const unsigned char *dev_id, unsigned char *busname, + size_t bsize) +{ + unsigned char subsys[SYSFS_NAME_LEN], *bus = NULL, *curdev = NULL; + struct dlist *buslist = NULL, *device_list = NULL; + + if (dev_id == NULL || busname == NULL) { + errno = EINVAL; + return -1; + } + + strcpy(subsys, SYSFS_BUS_DIR); /* subsys = /bus */ + buslist = sysfs_open_subsystem_list(subsys); + if (buslist != NULL) { + dlist_for_each_data(buslist, bus, char) { + device_list = sysfs_open_bus_devices_list(bus); + if (device_list != NULL) { + dlist_for_each_data(device_list, + curdev, char) { + if (strcmp(dev_id, curdev) == 0) { + strncpy(busname, + bus, bsize); + sysfs_close_list(device_list); + sysfs_close_list(buslist); + return 0; + } + } + sysfs_close_list(device_list); + } + } + sysfs_close_list(buslist); + } + return -1; +} + +/** + * sysfs_find_driver_bus: locates the bus the driver is on. + * @driver: name of the driver to locate + * @busname: buffer to copy name to + * @bsize: buffer size + * returns 0 with success, -1 with error + */ +int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, + size_t bsize) +{ + unsigned char subsys[SYSFS_PATH_MAX], *bus = NULL, *curdrv = NULL; + struct dlist *buslist = NULL, *drivers = NULL; + + if (driver == NULL || busname == NULL) { + errno = EINVAL; + return -1; + } + + memset(subsys, 0, SYSFS_PATH_MAX); + strcpy(subsys, SYSFS_BUS_DIR); + buslist = sysfs_open_subsystem_list(subsys); + if (buslist != NULL) { + dlist_for_each_data(buslist, bus, char) { + memset(subsys, 0, SYSFS_PATH_MAX); + strcpy(subsys, SYSFS_BUS_DIR); + strcat(subsys, "/"); + strcat(subsys, bus); + strcat(subsys, SYSFS_DRIVERS_DIR); + drivers = sysfs_open_subsystem_list(subsys); + if (drivers != NULL) { + dlist_for_each_data(drivers, curdrv, char) { + if (strcmp(driver, curdrv) == 0) { + strncpy(busname, bus, bsize); + sysfs_close_list(drivers); + sysfs_close_list(buslist); + return 0; + } + } + sysfs_close_list(drivers); + } + } + sysfs_close_list(buslist); + } + return -1; +} + diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 9d7d8b2227..cb6ca9d00d 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -3,7 +3,7 @@ * * Generic class utility functions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,28 @@ #include "libsysfs.h" #include "sysfs.h" +void sysfs_close_cls_dev(void *dev) +{ + sysfs_close_class_device((struct sysfs_class_device *)dev); +} + +/** + * class_name_equal: compares class_devices' name + * @a: class_name looking for + * @b: sysfs_class_device being compared + */ +static int class_name_equal(void *a, void *b) +{ + if (a == NULL || b == NULL) + return 0; + + if (strcmp(((unsigned char *)a), ((struct sysfs_class_device *)b)->name) + == 0) + return 1; + + return 0; +} + /** * sysfs_close_class_device: closes a single class device. * @dev: class device to close. @@ -46,15 +68,11 @@ void sysfs_close_class_device(struct sysfs_class_device *dev) */ void sysfs_close_class(struct sysfs_class *cls) { - struct sysfs_class_device *cur = NULL, *next = NULL; - if (cls != NULL) { if (cls->directory != NULL) sysfs_close_directory(cls->directory); - for (cur = cls->devices; cur != NULL; cur = next) { - next = cur->next; - sysfs_close_class_device(cur); - } + if (cls->devices != NULL) + dlist_destroy(cls->devices); free(cls); } } @@ -82,10 +100,10 @@ static struct sysfs_class *alloc_class(void) * open_class_dir: opens up sysfs class directory * returns sysfs_directory struct with success and NULL with error */ -static struct sysfs_directory *open_class_dir(const char *name) +static struct sysfs_directory *open_class_dir(const unsigned char *name) { struct sysfs_directory *classdir = NULL; - char classpath[SYSFS_PATH_MAX]; + unsigned char classpath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; @@ -94,7 +112,7 @@ static struct sysfs_directory *open_class_dir(const char *name) memset(classpath, 0, SYSFS_PATH_MAX); if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { - dprintf(stderr, "Sysfs not supported on this system\n"); + dprintf("Sysfs not supported on this system\n"); return NULL; } @@ -104,13 +122,11 @@ static struct sysfs_directory *open_class_dir(const char *name) classdir = sysfs_open_directory(classpath); if (classdir == NULL) { errno = EINVAL; - dprintf(stderr,"Class %s not supported on this system\n", - name); + dprintf("Class %s not supported on this system\n", name); return NULL; } if ((sysfs_read_directory(classdir)) != 0) { - dprintf(stderr, "Error reading %s class dir %s\n", name, - classpath); + dprintf("Error reading %s class dir %s\n", name, classpath); sysfs_close_directory(classdir); return NULL; } @@ -123,14 +139,13 @@ static struct sysfs_directory *open_class_dir(const char *name) * @path: path to class device. * returns struct sysfs_class_device with success and NULL with error. */ -struct sysfs_class_device *sysfs_open_class_device(const char *path) +struct sysfs_class_device *sysfs_open_class_device(const unsigned char *path) { struct sysfs_class_device *cdev = NULL; - struct sysfs_directory *dir = NULL, *cur = NULL; - struct sysfs_dlink *curl = NULL; + struct sysfs_directory *dir = NULL; + struct sysfs_link *curl = NULL; struct sysfs_device *sdev = NULL; struct sysfs_driver *drv = NULL; - char temp[SYSFS_NAME_LEN]; if (path == NULL) { errno = EINVAL; @@ -138,74 +153,69 @@ struct sysfs_class_device *sysfs_open_class_device(const char *path) } cdev = alloc_class_device(); if (cdev == NULL) { - perror("malloc"); + dprintf("calloc failed\n"); return NULL; } - memset(temp, 0, SYSFS_NAME_LEN); - if ((sysfs_get_name_from_path(path, temp, SYSFS_NAME_LEN)) != 0) { + if ((sysfs_get_name_from_path(path, cdev->name, SYSFS_NAME_LEN)) != 0) { errno = EINVAL; - dprintf(stderr, "Invalid class device path %s\n", path); + dprintf("Invalid class device path %s\n", path); sysfs_close_class_device(cdev); return NULL; } - strcpy(cdev->name, temp); dir = sysfs_open_directory(path); if (dir == NULL) { - dprintf(stderr, "Error opening class device at %s\n", path); + dprintf("Error opening class device at %s\n", path); sysfs_close_class_device(cdev); return NULL; } if ((sysfs_read_directory(dir)) != 0) { - dprintf(stderr, "Error reading class device at %s\n", path); + dprintf("Error reading class device at %s\n", path); sysfs_close_directory(dir); sysfs_close_class_device(cdev); return NULL; } + sysfs_read_all_subdirs(dir); cdev->directory = dir; + strcpy(cdev->path, dir->path); - cur = cdev->directory->subdirs; - while(cur != NULL) { - sysfs_read_directory(cur); - cur = cur->next; - } /* get driver and device, if implemented */ - curl = cdev->directory->links; - while (curl != NULL) { - if (strncmp(curl->name, SYSFS_DEVICES_NAME, 6) == 0) { - sdev = sysfs_open_device(curl->target->path); - if (sdev != NULL) { - cdev->sysdevice = sdev; - if (cdev->driver != NULL) - sdev->driver = cdev->driver; - } - } else if (strncmp(curl->name, SYSFS_DRIVERS_NAME, 6) == 0) { - drv = sysfs_open_driver(curl->target->path); - if (drv != NULL) { - cdev->driver = drv; - if (cdev->sysdevice != NULL) - drv->device = cdev->sysdevice; + if (cdev->directory->links != NULL) { + dlist_for_each_data(cdev->directory->links, curl, + struct sysfs_link) { + if (strncmp(curl->name, SYSFS_DEVICES_NAME, 6) == 0) { + sdev = sysfs_open_device(curl->target); + if (sdev != NULL) { + cdev->sysdevice = sdev; + if (cdev->driver != NULL) + strncpy(sdev->driver_name, + cdev->driver->name, + SYSFS_NAME_LEN); + } + } else if (strncmp(curl->name, + SYSFS_DRIVERS_NAME, 6) == 0) { + drv = sysfs_open_driver(curl->target); + if (drv != NULL) { + cdev->driver = drv; + if (cdev->sysdevice != NULL) { + strncpy(cdev->sysdevice->name, + drv->name, + SYSFS_NAME_LEN); + if (drv->devices == NULL) + drv->devices = + dlist_new + (sizeof(struct + sysfs_device)); + dlist_unshift(drv->devices, + cdev->sysdevice); + } + } } } - curl = curl->next; } return cdev; } -/** - * add_dev_to_class: adds a class device to class list - * @class: class to add the device - * @dev: device to add - */ -static void add_dev_to_class(struct sysfs_class *cls, - struct sysfs_class_device *dev) -{ - if (cls != NULL && dev != NULL) { - dev->next = cls->devices; - cls->devices = dev; - } -} - /** * get_all_class_devices: gets all devices for class * @class: class to get devices for @@ -214,23 +224,27 @@ static void add_dev_to_class(struct sysfs_class *cls, static int get_all_class_devices(struct sysfs_class *cls) { struct sysfs_class_device *dev = NULL; - struct sysfs_directory *cur = NULL, *next = NULL; + struct sysfs_directory *cur = NULL; if (cls == NULL || cls->directory == NULL) { errno = EINVAL; return -1; } - for (cur = cls->directory->subdirs; cur != NULL; cur = next) { - next = cur->next; + if (cls->directory->subdirs == NULL) + return 0; + dlist_for_each_data(cls->directory->subdirs, cur, + struct sysfs_directory) { dev = sysfs_open_class_device(cur->path); if (dev == NULL) { - dprintf(stderr, "Error opening device at %s\n", - cur->path); + dprintf("Error opening device at %s\n", cur->path); continue; } - add_dev_to_class(cls, dev); + if (cls->devices == NULL) + cls->devices = dlist_new_with_delete + (sizeof(struct sysfs_class_device), + sysfs_close_cls_dev); + dlist_unshift(cls->devices, dev); } - return 0; } @@ -238,7 +252,7 @@ static int get_all_class_devices(struct sysfs_class *cls) * sysfs_open_class: opens specific class and all its devices on system * returns sysfs_class structure with success or NULL with error. */ -struct sysfs_class *sysfs_open_class(const char *name) +struct sysfs_class *sysfs_open_class(const unsigned char *name) { struct sysfs_class *cls = NULL; struct sysfs_directory *classdir = NULL; @@ -250,24 +264,268 @@ struct sysfs_class *sysfs_open_class(const char *name) cls = alloc_class(); if (cls == NULL) { - perror("malloc"); + dprintf("calloc failed\n"); return NULL; } strcpy(cls->name, name); classdir = open_class_dir(name); if (classdir == NULL) { - dprintf(stderr, - "Invalid class, %s not supported on this system\n", + dprintf("Invalid class, %s not supported on this system\n", name); sysfs_close_class(cls); return NULL; } cls->directory = classdir; + strcpy(cls->path, classdir->path); if ((get_all_class_devices(cls)) != 0) { - dprintf(stderr, "Error reading %s class devices\n", name); + dprintf("Error reading %s class devices\n", name); sysfs_close_class(cls); return NULL; } return cls; } + +/** + * sysfs_get_class_device: Get specific class device using the device's id + * @class: class to find device on + * @name: class name of the device + */ +struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class, + unsigned char *name) +{ + if (class == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + + return (struct sysfs_class_device *)dlist_find_custom(class->devices, + name, class_name_equal); +} + +/** + * sysfs_open_class_device_by_name: Locates a specific class_device and returns it. + * Class_device must be closed using sysfs_close_class_device + * @classname: Class to search + * @name: name of the class_device + */ +struct sysfs_class_device *sysfs_open_class_device_by_name + (const unsigned char *classname, unsigned char *name) +{ + struct sysfs_class *class = NULL; + struct sysfs_class_device *cdev = NULL, *rcdev = NULL; + + if (classname == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + + class = sysfs_open_class(classname); + if (class == NULL) { + dprintf("Error opening class %s\n", classname); + return NULL; + } + + cdev = sysfs_get_class_device(class, name); + if (cdev == NULL) { + dprintf("Error getting class device %s from class %s\n", + name, classname); + sysfs_close_class(class); + return NULL; + } + + rcdev = sysfs_open_class_device(cdev->directory->path); + if (rcdev == NULL) { + dprintf("Error getting class device %s from class %s\n", + name, classname); + sysfs_close_class(class); + return NULL; + } + sysfs_close_class(class); + + return rcdev; +} + +/** + * sysfs_get_classdev_attributes: returns a dlist of attributes for + * the requested class_device + * @cdev: sysfs_class_dev for which attributes are needed + * returns a dlist of attributes if exists, NULL otherwise + */ +struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev) +{ + if (cdev == NULL || cdev->directory == NULL) + return NULL; + + return (cdev->directory->attributes); +} + +/** + * sysfs_find_device_class: locates the device the device is on + * @bus_id: device to look for + * @classname: buffer to copy class name to + * @bsize: size of buffer + * returns 0 with success and -1 with error + */ +int sysfs_find_device_class(const unsigned char *bus_id, + unsigned char *classname, size_t bsize) +{ + unsigned char class[SYSFS_NAME_LEN], clspath[SYSFS_NAME_LEN]; + unsigned char *cls = NULL, *clsdev = NULL; + struct dlist *clslist = NULL, *clsdev_list = NULL; + + if (bus_id == NULL || classname == NULL) { + errno = EINVAL; + return -1; + } + + strcpy(class, SYSFS_CLASS_DIR); + clslist = sysfs_open_subsystem_list(class); + if (clslist != NULL) { + dlist_for_each_data(clslist, cls, char) { + memset(clspath, 0, SYSFS_NAME_LEN); + strcpy(clspath, SYSFS_CLASS_DIR); + strcat(clspath, "/"); + strcat(clspath, cls); + clsdev_list = sysfs_open_subsystem_list(clspath); + if (clsdev_list != NULL) { + dlist_for_each_data(clsdev_list, + clsdev, char) { + if (strcmp(bus_id, clsdev) == 0) { + strncpy(classname, + cls, bsize); + sysfs_close_list(clsdev_list); + sysfs_close_list(clslist); + return 0; + } + } + sysfs_close_list(clsdev_list); + } + } + sysfs_close_list(clslist); + } + return -1; +} + +/** + * sysfs_get_classdev_attr: searches class device's attributes by name + * @clsdev: class device to look through + * @name: attribute name to get + * returns sysfs_attribute reference with success or NULL with error + */ +struct sysfs_attribute *sysfs_get_classdev_attr + (struct sysfs_class_device *clsdev, const unsigned char *name) +{ + struct sysfs_attribute *cur = NULL; + + if (clsdev == NULL || clsdev->directory == NULL || + clsdev->directory->attributes == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + + cur = sysfs_get_directory_attribute(clsdev->directory, + (unsigned char *)name); + if (cur != NULL) + return cur; + + return NULL; +} + +/** + * sysfs_write_classdev_attr: modify writable attribute value for the given + * class device + * @dev: class device name for which the attribute has to be changed + * @attrib: attribute to change + * @value: value to change to + * @len: size of buffer at "value" + * Returns 0 on success and -1 on error + */ +int sysfs_write_classdev_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len) +{ + struct sysfs_class_device *clsdev = NULL; + struct sysfs_attribute *attribute = NULL; + unsigned char class_name[SYSFS_NAME_LEN]; + + if (dev == NULL || attrib == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + memset(class_name, 0, SYSFS_NAME_LEN); + if ((sysfs_find_device_class(dev, + class_name, SYSFS_NAME_LEN)) < 0) { + dprintf("Class device %s not found\n", dev); + return -1; + } + clsdev = sysfs_open_class_device_by_name(class_name, dev); + if (clsdev == NULL) { + dprintf("Error opening %s in class %s\n", dev, class_name); + return -1; + } + attribute = sysfs_get_directory_attribute(clsdev->directory, attrib); + if (attribute == NULL) { + dprintf("Attribute %s not defined for device %s on class %s\n", + attrib, dev, class_name); + sysfs_close_class_device(clsdev); + return -1; + } + if ((sysfs_write_attribute(attribute, value, len)) < 0) { + dprintf("Error setting %s to %s\n", attrib, value); + sysfs_close_class_device(clsdev); + return -1; + } + sysfs_close_class_device(clsdev); + return 0; +} + +/** + * sysfs_read_classdev_attr: read an attribute for a given class device + * @dev: class device name for which the attribute has to be read + * @attrib: attribute to read + * @value: buffer to return value to user + * @len: size of buffer at "value" + * Returns 0 on success and -1 on error + */ +int sysfs_read_classdev_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len) +{ + struct sysfs_class_device *clsdev = NULL; + struct sysfs_attribute *attribute = NULL; + unsigned char class_name[SYSFS_NAME_LEN]; + + if (dev == NULL || attrib == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + memset(class_name, 0, SYSFS_NAME_LEN); + if ((sysfs_find_device_class(dev, + class_name, SYSFS_NAME_LEN)) < 0) { + dprintf("Class device %s not found\n", dev); + return -1; + } + clsdev = sysfs_open_class_device_by_name(class_name, dev); + if (clsdev == NULL) { + dprintf("Error opening %s in class %s\n", dev, class_name); + return -1; + } + attribute = sysfs_get_directory_attribute(clsdev->directory, attrib); + if (attribute == NULL) { + dprintf("Attribute %s not defined for device %s on class %s\n", + attrib, dev, class_name); + sysfs_close_class_device(clsdev); + return -1; + } + if (attribute->len > len) { + dprintf("Value length %d is greater that suppled buffer %d\n", + attribute->len, len); + sysfs_close_class_device(clsdev); + return -1; + } + strncpy(value, attribute->value, attribute->len); + value[(attribute->len)+1] = 0; + sysfs_close_class_device(clsdev); + return 0; +} diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 185b5cf378..89704dcd80 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -3,7 +3,7 @@ * * Generic device utility functions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,42 @@ #include "libsysfs.h" #include "sysfs.h" +/** + * sysfs_close_device_tree: closes every device in the supplied tree, + * closing children only. + * @devroot: device root of tree. + */ +static void sysfs_close_device_tree(struct sysfs_device *devroot) +{ + if (devroot != NULL) { + if (devroot->children != NULL) { + struct sysfs_device *child = NULL; + + dlist_for_each_data(devroot->children, child, + struct sysfs_device) { + sysfs_close_device_tree(child); + } + } + sysfs_close_device(devroot); + } +} + +/** + * sysfs_del_device: routine for dlist integration + */ +static void sysfs_del_device(void *dev) +{ + sysfs_close_device((struct sysfs_device *)dev); +} + +/** + * sysfs_close_dev_tree: routine for dlist integration + */ +static void sysfs_close_dev_tree(void *dev) +{ + sysfs_close_device_tree((struct sysfs_device *)dev); +} + /** * sysfs_close_device: closes and cleans up a device * @dev = device to clean up @@ -30,11 +66,10 @@ void sysfs_close_device(struct sysfs_device *dev) { if (dev != NULL) { - dev->next = NULL; - dev->driver = NULL; if (dev->directory != NULL) sysfs_close_directory(dev->directory); - dev->children = NULL; + if (dev->children != NULL && dev->children->count == 0) + dlist_destroy(dev->children); free(dev); } } @@ -55,24 +90,20 @@ static struct sysfs_device *alloc_device(void) * returns sysfs_attribute reference with success or NULL with error. */ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, - const char *name) + const unsigned char *name) { struct sysfs_attribute *cur = NULL; - char attrname[SYSFS_NAME_LEN]; - if (dev == NULL || dev->directory == NULL || name == NULL) { + if (dev == NULL || dev->directory == NULL + || dev->directory->attributes == NULL || name == NULL) { errno = EINVAL; return NULL; } - for (cur = dev->directory->attributes; cur != NULL; cur = cur->next) { - if ((sysfs_get_name_from_path(cur->path, attrname, - SYSFS_NAME_LEN)) != 0) - continue; - if (strcmp(name, attrname) != 0) - continue; - + + cur = sysfs_get_directory_attribute(dev->directory, + (unsigned char *)name); + if (cur != NULL) return cur; - } return NULL; } @@ -82,11 +113,10 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, * @path: path to device, this is the /sys/devices/ path * returns sysfs_device structure with success or NULL with error */ -struct sysfs_device *sysfs_open_device(const char *path) +struct sysfs_device *sysfs_open_device(const unsigned char *path) { struct sysfs_device *dev = NULL; struct sysfs_directory *sdir = NULL; - char *p = NULL; if (path == NULL) { errno = EINVAL; @@ -94,73 +124,36 @@ struct sysfs_device *sysfs_open_device(const char *path) } dev = alloc_device(); if (dev == NULL) { - dprintf(stderr, "Error allocating device at %s\n", path); + dprintf("Error allocating device at %s\n", path); return NULL; } sdir = sysfs_open_directory(path); if (sdir == NULL) { - dprintf(stderr, "Invalid device at %s\n", path); + dprintf("Invalid device at %s\n", path); errno = EINVAL; sysfs_close_device(dev); return NULL; } if ((sysfs_read_directory(sdir)) != 0) { - dprintf(stderr, "Error reading device directory at %s\n", path); + dprintf("Error reading device directory at %s\n", path); sysfs_close_directory(sdir); sysfs_close_device(dev); return NULL; } dev->directory = sdir; - sysfs_get_name_from_path(sdir->path, dev->bus_id, SYSFS_NAME_LEN); - /* get device name */ - p = sysfs_get_value_from_attributes(sdir->attributes, - SYSFS_NAME_ATTRIBUTE); - if (p != NULL) { - strncpy(dev->name, p, SYSFS_NAME_LEN); - p = dev->name + strlen(dev->name) - 1; - if ((strlen(dev->name) > 0) && *p == '\n') - *p = '\0'; - } + strcpy(dev->bus_id, sdir->name); + strcpy(dev->path, sdir->path); + + /* + * The "name" attribute no longer exists... return the device's + * sysfs representation instead, in the "dev->name" field, which + * implies that the dev->name and dev->bus_id contain same data. + */ + strncpy(dev->name, sdir->name, SYSFS_NAME_LEN); return dev; } -/** - * sysfs_close_device_tree: closes every device in the supplied tree, - * closing children only. - * @devroot: device root of tree. - */ -void sysfs_close_device_tree(struct sysfs_device *devroot) -{ - if (devroot != NULL) { - if (devroot->children != NULL) { - struct sysfs_device *child = NULL, *next = NULL; - - for (child = devroot->children; child != NULL; - child = next) { - next = child->next; - sysfs_close_device_tree(child); - } - } - sysfs_close_device(devroot); - } -} - -/** - * add_device_child_to_parent: adds child device to parent - * @parent: parent device. - * @child: child device to add. - */ -static void add_device_child_to_parent(struct sysfs_device *parent, - struct sysfs_device *child) -{ - if (parent != NULL && child != NULL) { - child->next = parent->children; - parent->children = child; - child->parent = parent; - } -} - /** * sysfs_open_device_tree: opens root device and all of its children, * creating a tree of devices. Only opens children. @@ -168,7 +161,7 @@ static void add_device_child_to_parent(struct sysfs_device *parent, * returns struct sysfs_device and its children with success or NULL with * error. */ -struct sysfs_device *sysfs_open_device_tree(const char *path) +static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path) { struct sysfs_device *rootdev = NULL, *new = NULL; struct sysfs_directory *cur = NULL; @@ -179,21 +172,367 @@ struct sysfs_device *sysfs_open_device_tree(const char *path) } rootdev = sysfs_open_device(path); if (rootdev == NULL) { - dprintf(stderr, "Error opening root device at %s\n", path); + dprintf("Error opening root device at %s\n", path); return NULL; } - cur = rootdev->directory->subdirs; - while (cur != NULL) { - new = sysfs_open_device_tree(cur->path); - if (new == NULL) { - dprintf(stderr, "Error opening device tree at %s\n", - cur->path); - sysfs_close_device_tree(rootdev); - return NULL; + if (rootdev->directory->subdirs != NULL) { + dlist_for_each_data(rootdev->directory->subdirs, cur, + struct sysfs_directory) { + new = sysfs_open_device_tree(cur->path); + if (new == NULL) { + dprintf("Error opening device tree at %s\n", + cur->path); + sysfs_close_device_tree(rootdev); + return NULL; + } + if (rootdev->children == NULL) + rootdev->children = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_del_device); + dlist_unshift(rootdev->children, new); } - add_device_child_to_parent(rootdev, new); - cur = cur->next; } return rootdev; } + +/** + * sysfs_close_root_device: closes root and all devices + * @root: root device to close + */ +void sysfs_close_root_device(struct sysfs_root_device *root) +{ + if (root != NULL) { + if (root->devices != NULL) + dlist_destroy(root->devices); + if (root->directory != NULL) + sysfs_close_directory(root->directory); + free(root); + } +} + +/** + * open_root_device_dir: opens up sysfs_directory for specific root dev + * @name: name of root + * returns struct sysfs_directory with success and NULL with error + */ +static struct sysfs_directory *open_root_device_dir(const unsigned char *name) +{ + struct sysfs_directory *rdir = NULL; + unsigned char rootpath[SYSFS_PATH_MAX]; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + memset(rootpath, 0, SYSFS_PATH_MAX); + if (sysfs_get_mnt_path(rootpath, SYSFS_PATH_MAX) != 0) { + dprintf ("Sysfs not supported on this system\n"); + return NULL; + } + + strcat(rootpath, SYSFS_DEVICES_DIR); + strcat(rootpath, "/"); + strcat(rootpath, name); + rdir = sysfs_open_directory(rootpath); + if (rdir == NULL) { + errno = EINVAL; + dprintf ("Root device %s not supported on this system\n", + name); + return NULL; + } + if (sysfs_read_directory(rdir) != 0) { + dprintf ("Error reading %s root device at dir %s\n", name, + rootpath); + sysfs_close_directory(rdir); + return NULL; + } + + return rdir; +} + +/** + * get_all_root_devices: opens up all the devices under this root device + * @root: root device to open devices for + * returns 0 with success and -1 with error + */ +static int get_all_root_devices(struct sysfs_root_device *root) +{ + struct sysfs_device *dev = NULL; + struct sysfs_directory *cur = NULL; + + if (root == NULL || root->directory == NULL) { + errno = EINVAL; + return -1; + } + if (root->directory->subdirs == NULL) + return 0; + + dlist_for_each_data(root->directory->subdirs, cur, + struct sysfs_directory) { + dev = sysfs_open_device_tree(cur->path); + if (dev == NULL) { + dprintf ("Error opening device at %s\n", cur->path); + continue; + } + if (root->devices == NULL) + root->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_dev_tree); + dlist_unshift(root->devices, dev); + } + + return 0; +} + +/** + * sysfs_open_root_device: opens sysfs devices root and all of its + * devices. + * @name: name of /sys/devices/root to open + * returns struct sysfs_root_device if success and NULL with error + */ +struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) +{ + struct sysfs_root_device *root = NULL; + struct sysfs_directory *rootdir = NULL; + + if (name == NULL) { + errno = EINVAL; + return NULL; + } + + root = (struct sysfs_root_device *)calloc + (1, sizeof(struct sysfs_root_device)); + if (root == NULL) { + dprintf("calloc failure\n"); + return NULL; + } + rootdir = open_root_device_dir(name); + if (rootdir == NULL) { + dprintf ("Invalid root device, %s not supported\n", name); + sysfs_close_root_device(root); + return NULL; + } + strcpy(root->path, rootdir->path); + root->directory = rootdir; + if (get_all_root_devices(root) != 0) { + dprintf ("Error retrieving devices for root %s\n", name); + sysfs_close_root_device(root); + return NULL; + } + + return root; +} + +/** + * sysfs_get_device_attributes: returns a dlist of attributes corresponding to + * the specific device + * @device: struct sysfs_device * for which attributes are to be returned + */ +struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) +{ + if (device == NULL || device->directory == NULL) + return NULL; + + return (device->directory->attributes); +} + +/** + * sysfs_open_device_by_id: open a device by id (use the "bus" subsystem) + * @bus_id: bus_id of the device to open - has to be the "bus_id" in + * /sys/bus/xxx/devices + * @bus: bus the device belongs to + * @bsize: size of the bus buffer + * returns struct sysfs_device if found, NULL otherwise + * NOTE: + * 1. Use sysfs_close_device to close the device + * 2. Bus the device is on must be supplied + * Use sysfs_find_device_bus to get the bus name + */ +struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, + const unsigned char *bus, size_t bsize) +{ + char sysfs_path[SYSFS_PATH_MAX], device_path[SYSFS_PATH_MAX]; + struct sysfs_device *device = NULL; + + if (bus_id == NULL || bus == NULL) { + errno = EINVAL; + return NULL; + } + memset(sysfs_path, 0, SYSFS_PATH_MAX); + if ((sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting sysfs mount path\n"); + return NULL; + } + strcat(sysfs_path, SYSFS_BUS_DIR); + strcat(sysfs_path, "/"); + strncat(sysfs_path, bus, bsize); + strcat(sysfs_path, SYSFS_DEVICES_DIR); + strcat(sysfs_path, "/"); + strcat(sysfs_path, bus_id); + + /* devices under /sys/bus/xxx/devices are links to devices subsystem */ + if ((sysfs_get_link(sysfs_path, device_path, SYSFS_PATH_MAX)) < 0) { + dprintf("Error getting device path\n"); + return NULL; + } + + device = sysfs_open_device(device_path); + if (device == NULL) { + dprintf("Error opening device %s\n", bus_id); + return NULL; + } + + return device; +} + +/** + * get_device_absolute_path: looks up the bus the device is on, gets + * absolute path to the device + * @device: device for which path is needed + * @path: buffer to store absolute path + * @psize: size of "path" + * Returns 0 on success -1 on failure + */ +static int get_device_absolute_path(const unsigned char *device, + unsigned char *path, size_t psize) +{ + unsigned char bus_name[SYSFS_NAME_LEN], bus_path[SYSFS_PATH_MAX]; + + if (device == NULL || path == NULL) { + errno = EINVAL; + return -1; + } + + memset(bus_name, 0, SYSFS_NAME_LEN); + memset(bus_path, 0, SYSFS_NAME_LEN); + if ((sysfs_find_device_bus(device, bus_name, SYSFS_NAME_LEN)) != 0) { + dprintf("Device %s not found\n", device); + return -1; + } + if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX) != 0) { + dprintf ("Sysfs not supported on this system\n"); + return -1; + } + strcat(bus_path, SYSFS_BUS_DIR); + strcat(bus_path, "/"); + strcat(bus_path, bus_name); + strcat(bus_path, SYSFS_DEVICES_DIR); + strcat(bus_path, "/"); + strcat(bus_path, device); + /* + * We now are at /sys/bus/"bus_name"/devices/"device" which is a link. + * Now read this link to reach to the device. + */ + if ((sysfs_get_link(bus_path, path, SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to device %s\n", device); + return -1; + } + return 0; +} + +/** + * sysfs_write_device_attr: modify a "writable" attribute for the given device + * @dev: device bus_id for which attribute has to be changed + * @attrib: attribute to change + * @value: value to change to + * @len: "value" length to write + * Returns 0 on success -1 on error + */ +int sysfs_write_device_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len) +{ + struct sysfs_attribute *attribute = NULL; + unsigned char devpath[SYSFS_PATH_MAX]; + + if (dev == NULL || attrib == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + memset(devpath, 0, SYSFS_PATH_MAX); + if ((get_device_absolute_path(dev, devpath, SYSFS_PATH_MAX)) != 0) { + dprintf("Error finding absolute path to device %s\n", dev); + return -1; + } + strcat(devpath, "/"); + strcat(devpath, attrib); + attribute = sysfs_open_attribute(devpath); + if (attribute == NULL) { + dprintf("Attribute %s could not be retrieved for device %s\n", + attrib, dev); + return -1; + } + if (attribute->method & SYSFS_METHOD_SHOW) { + if ((sysfs_read_attribute(attribute)) != 0) { + dprintf("Error reading attribute %s for device %s\n", + attrib, dev); + sysfs_close_attribute(attribute); + return -1; + } + } + if ((sysfs_write_attribute(attribute, value, len)) < 0) { + dprintf("Error setting %s to %s\n", attrib, value); + sysfs_close_attribute(attribute); + return -1; + } + sysfs_close_attribute(attribute); + return 0; +} + +/** + * sysfs_read_device_attr: read an attribute of the given device + * @dev: device bus_id for which attribute has to be changed + * @attrib: attribute to read + * @value: buffer to return value in + * @len: size of buffer available + * Returns 0 on success -1 on error + */ +int sysfs_read_device_attr(unsigned char *dev, unsigned char *attrib, + unsigned char *value, size_t len) +{ + struct sysfs_attribute *attribute = NULL; + unsigned char devpath[SYSFS_PATH_MAX]; + + if (dev == NULL || attrib == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + memset(devpath, 0, SYSFS_PATH_MAX); + if ((get_device_absolute_path(dev, devpath, SYSFS_PATH_MAX)) != 0) { + dprintf("Error finding absolute path to device %s\n", dev); + return -1; + } + strcat(devpath, "/"); + strcat(devpath, attrib); + attribute = sysfs_open_attribute(devpath); + if (attribute == NULL) { + dprintf("Error opening attribute %s for device %s\n", + attrib, dev); + return -1; + } + if (!(attribute->method & SYSFS_METHOD_SHOW)) { + dprintf("Show method not supported for attribute %s\n", + attrib); + sysfs_close_attribute(attribute); + return -1; + } + if ((sysfs_read_attribute(attribute)) != 0) { + dprintf("Error reading attribute %s for device %s\n", + attrib, dev); + sysfs_close_attribute(attribute); + return -1; + } + if (attribute->len > len) { + dprintf("Value length %d is larger than supplied buffer %d\n", + attribute->len, len); + sysfs_close_attribute(attribute); + return -1; + } + strncpy(value, attribute->value, attribute->len); + value[(attribute->len)+1] = 0; + sysfs_close_attribute(attribute); + return 0; +} diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index a83c81f493..ff2edf4615 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -3,7 +3,7 @@ * * Directory utility functions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,6 +23,81 @@ #include "libsysfs.h" #include "sysfs.h" +/** + * sysfs_del_attribute: routine for dlist integration + */ +static void sysfs_del_attribute(void *attr) +{ + sysfs_close_attribute((struct sysfs_attribute *)attr); +} + +/** + * sysfs_del_link: routine for dlist integration + */ +static void sysfs_del_link(void *ln) +{ + sysfs_close_link((struct sysfs_link *)ln); +} + +/** + * sysfs_del_dir: routine for dlist integration + */ +static void sysfs_del_directory(void *dir) +{ + sysfs_close_directory((struct sysfs_directory *)dir); +} + +/** + * dir_attribute_name_equal: compares dir attributes by name + * @a: attribute name for comparison + * @b: sysfs_attribute to be compared. + * returns 1 if a==b->name or 0 if not equal + */ +static int dir_attribute_name_equal(void *a, void *b) +{ + if (a == NULL || b == NULL) + return 0; + + if (strcmp(((unsigned char *)a), ((struct sysfs_attribute *)b)->name) + == 0) + return 1; + return 0; +} + +/** + * dir_link_name_equal: compares dir links by name + * @a: link name for comparison + * @b: sysfs_link to be compared. + * returns 1 if a==b->name or 0 if not equal + */ +static int dir_link_name_equal(void *a, void *b) +{ + if (a == NULL || b == NULL) + return 0; + + if (strcmp(((unsigned char *)a), ((struct sysfs_link *)b)->name) + == 0) + return 1; + return 0; +} + +/** + * dir_subdir_name_equal: compares subdirs by name + * @a: name of subdirectory to compare + * @b: sysfs_directory subdirectory to be compared + * returns 1 if a==b->name or 0 if not equal + */ +static int dir_subdir_name_equal(void *a, void *b) +{ + if (a == NULL || b == NULL) + return 0; + + if (strcmp(((unsigned char *)a), ((struct sysfs_directory *)b)->name) + == 0) + return 1; + return 0; +} + /** * sysfs_close_attribute: closes and cleans up attribute * @sysattr: attribute to close. @@ -51,7 +126,7 @@ static struct sysfs_attribute *alloc_attribute(void) * @path: path to attribute. * returns sysfs_attribute struct with success and NULL with error. */ -struct sysfs_attribute *sysfs_open_attribute(const char *path) +struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path) { struct sysfs_attribute *sysattr = NULL; struct stat fileinfo; @@ -62,13 +137,22 @@ struct sysfs_attribute *sysfs_open_attribute(const char *path) } sysattr = alloc_attribute(); if (sysattr == NULL) { - dprintf(stderr, "Error allocating attribute at %s\n", path); + dprintf("Error allocating attribute at %s\n", path); + return NULL; + } + if (sysfs_get_name_from_path(path, sysattr->name, SYSFS_NAME_LEN) + != 0) { + dprintf("Error retrieving attribute name from path: %s\n", + path); + sysfs_close_attribute(sysattr); return NULL; } strncpy(sysattr->path, path, sizeof(sysattr->path)); if ((stat(sysattr->path, &fileinfo)) != 0) { - perror("stat"); + dprintf("Stat failed: No such attribute?\n"); sysattr->method = 0; + free(sysattr); + sysattr = NULL; } else { if (fileinfo.st_mode & S_IRUSR) sysattr->method |= SYSFS_METHOD_SHOW; @@ -79,6 +163,87 @@ struct sysfs_attribute *sysfs_open_attribute(const char *path) return sysattr; } +/** + * sysfs_write_attribute: write value to the attribute + * @sysattr: attribute to write + * @new_value: value to write + * @len: length of "new_value" + * returns 0 with success and -1 with error. + */ +int sysfs_write_attribute(struct sysfs_attribute *sysattr, + const unsigned char *new_value, size_t len) +{ + int fd; + int length; + + if (sysattr == NULL || new_value == NULL || len == 0) { + errno = EINVAL; + return -1; + } + + if (!(sysattr->method & SYSFS_METHOD_STORE)) { + dprintf ("Store method not supported for attribute %s\n", + sysattr->path); + return -1; + } + if (sysattr->method & SYSFS_METHOD_SHOW) { + if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0) { + dprintf("Attribute %s already has the requested value %s\n", + sysattr->name, new_value); + return 0; + } + } + /* + * open O_WRONLY since some attributes have no "read" but only + * "write" permission + */ + if ((fd = open(sysattr->path, O_WRONLY)) < 0) { + dprintf("Error reading attribute %s\n", sysattr->path); + return -1; + } + + length = write(fd, new_value, len); + if (length < 0) { + dprintf("Error writing to the attribute %s - invalid value?\n", + sysattr->name); + close(fd); + return -1; + } else if (length != len) { + dprintf("Could not write %d bytes to attribute %s\n", + len, sysattr->name); + /* + * since we could not write user supplied number of bytes, + * restore the old value if one available + */ + if (sysattr->method & SYSFS_METHOD_SHOW) { + length = write(fd, sysattr->value, sysattr->len); + close(fd); + return -1; + } + } + + /* + * Validate length that has been copied. Alloc appropriate area + * in sysfs_attribute. Verify first if the attribute supports reading + * (show method). If it does not, do not bother + */ + if (sysattr->method & SYSFS_METHOD_SHOW) { + if (length != sysattr->len) { + sysattr->value = (char *)realloc(sysattr->value, + length); + sysattr->len = length; + strncpy(sysattr->value, new_value, length); + } else { + /*"length" of the new value is same as old one */ + strncpy(sysattr->value, new_value, length); + } + } + + close(fd); + return 0; +} + + /** * sysfs_read_attribute: reads value from attribute * @sysattr: attribute to read @@ -86,8 +251,8 @@ struct sysfs_attribute *sysfs_open_attribute(const char *path) */ int sysfs_read_attribute(struct sysfs_attribute *sysattr) { - char *fbuf = NULL; - char *vbuf = NULL; + unsigned char *fbuf = NULL; + unsigned char *vbuf = NULL; size_t length = 0; int pgsize = 0; int fd; @@ -97,34 +262,33 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) return -1; } if (!(sysattr->method & SYSFS_METHOD_SHOW)) { - dprintf (stderr, "Show method not supported for attribute %s\n", + dprintf("Show method not supported for attribute %s\n", sysattr->path); return -1; } pgsize = getpagesize(); - fbuf = (char *)calloc(1, pgsize+1); + fbuf = (unsigned char *)calloc(1, pgsize+1); if (fbuf == NULL) { - perror("calloc"); + dprintf("calloc failed\n"); return -1; } if ((fd = open(sysattr->path, O_RDONLY)) < 0) { - dprintf (stderr, "Error reading attribute %s\n", sysattr->path); + dprintf("Error reading attribute %s\n", sysattr->path); free(fbuf); return -1; } length = read(fd, fbuf, pgsize); if (length < 0) { - dprintf (stderr, "Error reading from attribute %s\n", - sysattr->path); + dprintf("Error reading from attribute %s\n", sysattr->path); close(fd); free(fbuf); return -1; } sysattr->len = length; close(fd); - vbuf = (char *)realloc(fbuf, length+1); + vbuf = (unsigned char *)realloc(fbuf, length+1); if (vbuf == NULL) { - perror("realloc"); + dprintf("realloc failed\n"); free(fbuf); return -1; } @@ -142,7 +306,8 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) * @vsize: size of value buffer * returns 0 with success and -1 with error. */ -int sysfs_read_attribute_value(const char *attrpath, char *value, size_t vsize) +int sysfs_read_attribute_value(const unsigned char *attrpath, + unsigned char *value, size_t vsize) { struct sysfs_attribute *attr = NULL; size_t length = 0; @@ -154,19 +319,18 @@ int sysfs_read_attribute_value(const char *attrpath, char *value, size_t vsize) attr = sysfs_open_attribute(attrpath); if (attr == NULL) { - dprintf(stderr, "Invalid attribute path %s\n", attrpath); + dprintf("Invalid attribute path %s\n", attrpath); errno = EINVAL; return -1; } if((sysfs_read_attribute(attr)) != 0 || attr->value == NULL) { - dprintf(stderr, "Error reading from attribute %s\n", attrpath); + dprintf("Error reading from attribute %s\n", attrpath); sysfs_close_attribute(attr); return -1; } length = strlen(attr->value); if (length > vsize) - dprintf(stderr, - "Value length %d is larger than supplied buffer %d\n", + dprintf("Value length %d is larger than supplied buffer %d\n", length, vsize); strncpy(value, attr->value, vsize); sysfs_close_attribute(attr); @@ -179,87 +343,32 @@ int sysfs_read_attribute_value(const char *attrpath, char *value, size_t vsize) * attribute name, return its value * @attr: attribute to search * @name: name to look for - * returns char * value - could be NULL + * returns unsigned char * value - could be NULL */ -char *sysfs_get_value_from_attributes(struct sysfs_attribute *attr, - const char *name) +unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, + const unsigned char *name) { struct sysfs_attribute *cur = NULL; - char tmpname[SYSFS_NAME_LEN]; if (attr == NULL || name == NULL) { errno = EINVAL; return NULL; - } - cur = attr; - while (cur != NULL) { - memset(tmpname, 0, SYSFS_NAME_LEN); - if ((sysfs_get_name_from_path(cur->path, tmpname, - SYSFS_NAME_LEN)) != 0) { - cur = cur->next; - continue; - } - if (strcmp(tmpname, name) == 0) + } + dlist_for_each_data(attr, cur, struct sysfs_attribute) { + if (strcmp(cur->name, name) == 0) return cur->value; - cur = cur->next; } return NULL; } /** - * add_subdir_to_dir: adds subdirectory to directory's subdirs - * @sysdir: directory to add subdir to - * @subdir: subdirectory to add. + * sysfs_close_link: closes and cleans up link. + * @ln: link to close. */ -static void add_subdir_to_dir(struct sysfs_directory *sysdir, - struct sysfs_directory *subdir) +void sysfs_close_link(struct sysfs_link *ln) { - if (sysdir != NULL && subdir != NULL) { - subdir->next = sysdir->subdirs; - sysdir->subdirs = subdir; - } -} - -/** - * add_attr_to_dir: adds attribute to directory's attributes - * @sysdir: directory to add attribute to - * @sysattr: attribute to add. - */ -static void add_attr_to_dir(struct sysfs_directory *sysdir, - struct sysfs_attribute *sysattr) -{ - if (sysdir != NULL && sysattr != NULL) { - sysattr->next = sysdir->attributes; - sysdir->attributes = sysattr; - } -} - -/** - * sysfs_close_dlink: closes and cleans up directory link. - * @dlink: directory link to close. - */ -void sysfs_close_dlink(struct sysfs_dlink *dlink) -{ - if (dlink != NULL) { - dlink->next = NULL; - if (dlink->target != NULL) - sysfs_close_directory(dlink->target); - free(dlink); - } -} - -/** - * add_dlink_to_dir: adds directory link to directory's links list. - * @sysdir: directory to add it to. - * @dlink: link to add. - */ -static void add_dlink_to_dir(struct sysfs_directory *sysdir, - struct sysfs_dlink *dlink) -{ - if (sysdir != NULL && dlink != NULL) { - dlink->next = sysdir->links; - sysdir->links = dlink; - } + if (ln != NULL) + free(ln); } /** @@ -268,35 +377,13 @@ static void add_dlink_to_dir(struct sysfs_directory *sysdir, */ void sysfs_close_directory(struct sysfs_directory *sysdir) { - struct sysfs_directory *sdir = NULL, *dnext = NULL; - struct sysfs_dlink *dlink = NULL, *nextl = NULL; - struct sysfs_attribute *attr = NULL, *anext = NULL; - if (sysdir != NULL) { - if (sysdir->subdirs != NULL) { - for (sdir = sysdir->subdirs; sdir != NULL; - sdir = dnext) { - dnext = sdir->next; - sysfs_close_directory(sdir); - } - } - if (sysdir->links != NULL) { - for (dlink = sysdir->links; dlink != NULL; - dlink = nextl) { - nextl = dlink->next; - sysfs_close_dlink(dlink); - } - } - if (sysdir->attributes != NULL) { - for (attr = sysdir->attributes; attr != NULL; - attr = anext) { - anext = attr->next; - /* sysfs_close_attribute(attr); */ - if (attr->value != NULL) - free(attr->value); - free(attr); - } - } + if (sysdir->subdirs != NULL) + dlist_destroy(sysdir->subdirs); + if (sysdir->links != NULL) + dlist_destroy(sysdir->links); + if (sysdir->attributes != NULL) + dlist_destroy(sysdir->attributes); free(sysdir); } } @@ -312,12 +399,35 @@ static struct sysfs_directory *alloc_directory(void) } /** - * alloc_dlink: allocates and initializes directory link structure - * returns struct sysfs_dlink with success or NULL with error. + * alloc_link: allocates and initializes link structure + * returns struct sysfs_link with success or NULL with error. */ -static struct sysfs_dlink *alloc_dlink(void) +static struct sysfs_link *alloc_link(void) { - return (struct sysfs_dlink *)calloc(1, sizeof(struct sysfs_dlink)); + return (struct sysfs_link *)calloc(1, sizeof(struct sysfs_link)); +} + +/** + * sysfs_read_all_subdirs: calls sysfs_read_directory for all subdirs + * @sysdir: directory whose subdirs need reading. + * returns 0 with success and -1 with error. + */ +int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) +{ + struct sysfs_directory *cursub = NULL; + + if (sysdir == NULL) { + errno = EINVAL; + return -1; + } + if (sysdir->subdirs == NULL) + return 0; + dlist_for_each_data(sysdir->subdirs, cursub, struct sysfs_directory) { + if (sysfs_read_directory(cursub) != 0) + dprintf ("Error reading subdirectory %s\n", + cursub->name); + } + return 0; } /** @@ -326,7 +436,7 @@ static struct sysfs_dlink *alloc_dlink(void) * @path: path of directory to open. * returns: struct sysfs_directory * with success and NULL on error. */ -struct sysfs_directory *sysfs_open_directory(const char *path) +struct sysfs_directory *sysfs_open_directory(const unsigned char *path) { struct sysfs_directory *sdir = NULL; @@ -336,7 +446,12 @@ struct sysfs_directory *sysfs_open_directory(const char *path) } sdir = alloc_directory(); if (sdir == NULL) { - dprintf(stderr, "Error allocating directory %s\n", path); + dprintf("Error allocating directory %s\n", path); + return NULL; + } + if (sysfs_get_name_from_path(path, sdir->name, SYSFS_NAME_LEN) != 0) { + dprintf("Error getting directory name from path: %s\n", path); + sysfs_close_directory(sdir); return NULL; } strncpy(sdir->path, path, sizeof(sdir->path)); @@ -345,46 +460,33 @@ struct sysfs_directory *sysfs_open_directory(const char *path) } /** - * sysfs_open_dlink: opens a sysfs directory link, creates struct, and returns + * sysfs_open_link: opens a sysfs link, creates struct, and returns * @path: path of link to open. - * returns: struct sysfs_dlink * with success and NULL on error. + * returns: struct sysfs_link * with success and NULL on error. */ -struct sysfs_dlink *sysfs_open_dlink(const char *linkpath) +struct sysfs_link *sysfs_open_link(const unsigned char *linkpath) { - struct sysfs_dlink *dlink = NULL; - struct sysfs_directory *tdir = NULL; - char name[SYSFS_NAME_LEN]; - char target[SYSFS_PATH_MAX]; + struct sysfs_link *ln = NULL; - if (linkpath == NULL) { + if (linkpath == NULL || strlen(linkpath) > SYSFS_PATH_MAX) { errno = EINVAL; return NULL; } - memset(name, 0, SYSFS_NAME_LEN); - memset(target, 0, SYSFS_PATH_MAX); - if ((sysfs_get_name_from_path(linkpath, name, SYSFS_NAME_LEN)) != 0 - || (sysfs_get_link(linkpath, target, SYSFS_PATH_MAX)) != 0) { + ln = alloc_link(); + if (ln == NULL) { + dprintf("Error allocating link %s\n", linkpath); + return NULL; + } + strcpy(ln->path, linkpath); + if ((sysfs_get_name_from_path(linkpath, ln->name, SYSFS_NAME_LEN)) != 0 + || (sysfs_get_link(linkpath, ln->target, SYSFS_PATH_MAX)) != 0) { errno = EINVAL; - dprintf(stderr, "Invalid link path %s\n", linkpath); + dprintf("Invalid link path %s\n", linkpath); return NULL; } - dlink = alloc_dlink(); - if (dlink == NULL) { - dprintf(stderr, - "Error allocating directory link %s\n", linkpath); - return NULL; - } - strcpy(dlink->name, name); - tdir = sysfs_open_directory(target); - if (tdir == NULL) { - dprintf(stderr, "Invalid directory link target %s\n", target); - sysfs_close_dlink(dlink); - return NULL; - } - dlink->target = tdir; - return dlink; + return ln; } /** @@ -399,8 +501,8 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) struct stat astats; struct sysfs_attribute *attr = NULL; struct sysfs_directory *subdir = NULL; - struct sysfs_dlink *dlink = NULL; - char file_path[SYSFS_PATH_MAX]; + struct sysfs_link *ln = NULL; + unsigned char file_path[SYSFS_PATH_MAX]; int retval = 0; if (sysdir == NULL) { @@ -409,7 +511,7 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) } dir = opendir(sysdir->path); if (dir == NULL) { - perror("opendir"); + dprintf("Error opening directory %s\n", sysdir->path); return -1; } while(((dirent = readdir(dir)) != NULL) && retval == 0) { @@ -422,45 +524,57 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) strncat(file_path, "/", sizeof(file_path)); strncat(file_path, dirent->d_name, sizeof(file_path)); if ((lstat(file_path, &astats)) != 0) { - perror("stat"); + dprintf("stat failed\n"); continue; } if (S_ISREG(astats.st_mode)) { attr = sysfs_open_attribute(file_path); if (attr == NULL) { - dprintf (stderr, "Error opening attribute %s\n", + dprintf("Error opening attribute %s\n", file_path); retval = -1; break; } if (attr->method & SYSFS_METHOD_SHOW) { if ((sysfs_read_attribute(attr)) != 0) { - dprintf (stderr, - "Error reading attribute %s\n", + dprintf("Error reading attribute %s\n", file_path); sysfs_close_attribute(attr); continue; } } - add_attr_to_dir(sysdir, attr); + + if (sysdir->attributes == NULL) { + sysdir->attributes = dlist_new_with_delete + (sizeof(struct sysfs_attribute), + sysfs_del_attribute); + } + dlist_unshift(sysdir->attributes, attr); } else if (S_ISDIR(astats.st_mode)) { subdir = sysfs_open_directory(file_path); if (subdir == NULL) { - dprintf (stderr, "Error opening directory %s\n", + dprintf("Error opening directory %s\n", file_path); retval = -1; break; } - add_subdir_to_dir(sysdir, subdir); + if (sysdir->subdirs == NULL) + sysdir->subdirs = dlist_new_with_delete + (sizeof(struct sysfs_directory), + sysfs_del_directory); + dlist_unshift(sysdir->subdirs, subdir); } else if (S_ISLNK(astats.st_mode)) { - dlink = sysfs_open_dlink(file_path); - if (dlink == NULL) { - dprintf(stderr, "Error opening link %s\n", - file_path); + ln = sysfs_open_link(file_path); + if (ln == NULL) { + dprintf("Error opening link %s\n", file_path); retval = -1; break; } - add_dlink_to_dir(sysdir, dlink); + if (sysdir->links == NULL) + sysdir->links = dlist_new_with_delete + (sizeof(struct sysfs_link), + sysfs_del_link); + dlist_unshift(sysdir->links, ln); } } closedir(dir); @@ -468,29 +582,123 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) } /** - * sysfs_read_dlinks: reads a directory link's target directory. Can - * supply a linked list of links. - * @dlink: directory link to read. - * returns 0 with success or -1 with error. + * sysfs_get_directory_attribute: retrieves attribute attrname + * @dir: directory to retrieve attribute from + * @attrname: name of attribute to look for + * returns sysfs_attribute if found and NULL if not found */ -int sysfs_read_dlinks(struct sysfs_dlink *dlink) +struct sysfs_attribute *sysfs_get_directory_attribute + (struct sysfs_directory *dir, unsigned char *attrname) { - struct sysfs_dlink *cur = NULL; - - if (dlink == NULL || dlink->target == NULL) { + struct sysfs_directory *sdir = NULL; + struct sysfs_attribute *attr = NULL; + + if (dir == NULL || attrname == NULL) { errno = EINVAL; - return -1; - } - cur = dlink; - while (cur != NULL) { - if ((sysfs_read_directory(cur->target)) != 0) { - dprintf(stderr, - "Error reading directory link target %s\n", - dlink->name); - return -1; - } - cur = cur->next; + return NULL; } - return 0; + attr = (struct sysfs_attribute *)dlist_find_custom(dir->attributes, + attrname, dir_attribute_name_equal); + if (attr != NULL) + return attr; + + if (dir->subdirs != NULL) { + dlist_for_each_data(dir->subdirs, sdir, + struct sysfs_directory) { + if (sdir->attributes == NULL) + continue; + attr = sysfs_get_directory_attribute(sdir, attrname); + if (attr != NULL) + return attr; + } + } + return NULL; +} + +/** + * sysfs_get_directory_link: retrieves link from one directory list + * @dir: directory to retrieve link from + * @linkname: name of link to look for + * returns reference to sysfs_link if found and NULL if not found + */ +struct sysfs_link *sysfs_get_directory_link + (struct sysfs_directory *dir, unsigned char *linkname) +{ + if (dir == NULL || linkname == NULL) { + errno = EINVAL; + return NULL; + } + return (struct sysfs_link *)dlist_find_custom(dir->links, + linkname, dir_link_name_equal); +} + +/** + * sysfs_get_subdirectory: retrieves subdirectory by name. + * @dir: directory to search for subdirectory. + * @subname: subdirectory name to get. + * returns reference to subdirectory or NULL if not found + */ +struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir, + unsigned char *subname) +{ + struct sysfs_directory *sub = NULL, *cursub = NULL; + + if (dir == NULL || dir->subdirs == NULL || subname == NULL) { + errno = EINVAL; + return NULL; + } + sub = (struct sysfs_directory *)dlist_find_custom(dir->subdirs, + subname, dir_subdir_name_equal); + if (sub != NULL) + return sub; + + if (dir->subdirs != NULL) { + dlist_for_each_data(dir->subdirs, cursub, + struct sysfs_directory) { + if (cursub->subdirs == NULL) + continue; + sub = sysfs_get_subdirectory(cursub, subname); + if (sub != NULL) + return sub; + } + } + return NULL; +} + +/** + * sysfs_get_subdirectory_link: looks through all subdirs for specific link. + * @dir: directory and subdirectories to search for link. + * @linkname: link name to get. + * returns reference to link or NULL if not found + */ +struct sysfs_link *sysfs_get_subdirectory_link(struct sysfs_directory *dir, + unsigned char *linkname) +{ + struct sysfs_directory *cursub = NULL; + struct sysfs_link *ln = NULL; + + if (dir == NULL || dir->links == NULL || linkname == NULL) { + errno = EINVAL; + return NULL; + } + + ln = sysfs_get_directory_link(dir, linkname); + if (ln != NULL) + return ln; + + if (dir->subdirs == NULL) + return NULL; + + if (dir->subdirs != NULL) { + dlist_for_each_data(dir->subdirs, cursub, + struct sysfs_directory) { + if (cursub->subdirs == NULL) + continue; + ln = sysfs_get_subdirectory_link(cursub, linkname); + if (ln != NULL) + return ln; + } + } + return NULL; } diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 6813c85f14..f8e842c65c 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -3,7 +3,7 @@ * * Driver utility functions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,19 +23,46 @@ #include "libsysfs.h" #include "sysfs.h" +static void sysfs_close_driver_by_name_dev(void *device) +{ + sysfs_close_device((struct sysfs_device *)device); +} + /** * sysfs_close_driver: closes and cleans up driver structure + * NOTE: This routine does not deallocate devices list * @driver: driver to close */ void sysfs_close_driver(struct sysfs_driver *driver) { if (driver != NULL) { + if (driver->devices != NULL) { + dlist_for_each(driver->devices) + dlist_shift(driver->devices); + free(driver->devices); + driver->devices = NULL; + } if (driver->directory != NULL) sysfs_close_directory(driver->directory); free(driver); } } +/** + * sysfs_close_driver_by_name: closes driver and deletes device lists too + * @driver: driver to close + */ +void sysfs_close_driver_by_name(struct sysfs_driver *driver) +{ + if (driver != NULL) { + if (driver->devices != NULL) + dlist_destroy(driver->devices); + if (driver->directory != NULL) + sysfs_close_directory(driver->directory); + free(driver); + } +} + /** * alloc_driver: allocates and initializes driver * returns struct sysfs_driver with success and NULL with error. @@ -50,11 +77,10 @@ static struct sysfs_driver *alloc_driver(void) * @path: path to driver directory * returns struct sysfs_driver with success and NULL with error */ -struct sysfs_driver *sysfs_open_driver(const char *path) +struct sysfs_driver *sysfs_open_driver(const unsigned char *path) { struct sysfs_driver *driver = NULL; struct sysfs_directory *sdir = NULL; - char devname[SYSFS_NAME_LEN]; if (path == NULL) { errno = EINVAL; @@ -62,28 +88,280 @@ struct sysfs_driver *sysfs_open_driver(const char *path) } sdir = sysfs_open_directory(path); if (sdir == NULL) { - dprintf (stderr, "Error opening directory %s\n", path); + dprintf("Error opening directory %s\n", path); return NULL; } if ((sysfs_read_directory(sdir)) != 0) { - dprintf (stderr, "Error reading directory %s\n", path); + dprintf("Error reading directory %s\n", path); sysfs_close_directory(sdir); return NULL; } driver = alloc_driver(); if (driver == NULL) { - dprintf(stderr, "Error allocating driver at %s\n", path); + dprintf("Error allocating driver at %s\n", path); sysfs_close_directory(sdir); return NULL; } - if ((sysfs_get_name_from_path(path, devname, SYSFS_NAME_LEN)) != 0) { - dprintf (stderr, "Error reading directory %s\n", path); - sysfs_close_directory(sdir); - free(driver); - return NULL; - } - strncpy(driver->name, devname, sizeof(driver->name)); + strcpy(driver->name, sdir->name); driver->directory = sdir; + strcpy(driver->path, sdir->path); return driver; } + +/** + * sysfs_get_driver_attributes: gets list of attributes for the given driver + * @driver: sysfs_driver for which attributes are required + * returns a dlist of attributes corresponding to the driver if present + * NULL otherwise + */ +struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) +{ + if (driver == NULL || driver->directory == NULL) + return NULL; + + return(driver->directory->attributes); +} + +/** + * sysfs_get_driver_attr: searches driver's attributes by name + * @drv: driver to look through + * @name: attribute name to get + * returns sysfs_attribute reference on success or NULL with error + */ +struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, + const unsigned char *name) +{ + struct sysfs_attribute *cur = NULL; + + if (drv == NULL || drv->directory == NULL + || drv->directory->attributes == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + + cur = sysfs_get_directory_attribute(drv->directory, + (unsigned char *)name); + if (cur != NULL) + return cur; + + return NULL; +} + +/** + * sysfs_get_driver_links: gets list of links from the given driver + * @driver: sysfs_driver for which links list is required + * returns a dlist of links corresponding to the driver if present + * NULL otherwise + */ +struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) +{ + if (driver == NULL || driver->directory == NULL) + return NULL; + + return(driver->directory->links); +} + +/** + * sysfs_open_driver_by_name: open a driver by name and return the bus + * the driver is on. + * @drv_name: driver to open + * @bus: the driver bus + * @bsize: size of bus buffer + * returns struct sysfs_driver if found, NULL otherwise + * NOTE: + * 1. Need to call sysfs_close_driver_by_name to free up memory + * 2. Bus the driver is registered with must be supplied. + * Use sysfs_find_driver_bus() to obtain the bus name + */ +struct sysfs_driver *sysfs_open_driver_by_name(const unsigned char *drv_name, + const unsigned char *bus, size_t bsize) +{ + struct sysfs_driver *driver = NULL; + struct sysfs_device *device = NULL; + struct sysfs_link *curlink = NULL; + unsigned char path[SYSFS_PATH_MAX]; + + if (drv_name == NULL || bus == NULL) { + errno = EINVAL; + return NULL; + } + + memset(path, 0, SYSFS_PATH_MAX); + if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) { + dprintf("Error getting sysfs mount path\n"); + return NULL; + } + strcat(path, SYSFS_BUS_DIR); + strcat(path, "/"); + strcat(path, bus); + strcat(path, SYSFS_DRIVERS_DIR); + strcat(path, "/"); + strcat(path, drv_name); + driver = sysfs_open_driver(path); + if (driver == NULL) { + dprintf("Could not open driver %s\n", drv_name); + return NULL; + } + if (driver->directory->links != NULL) { + dlist_for_each_data(driver->directory->links, curlink, + struct sysfs_link) { + device = sysfs_open_device(curlink->target); + if (device == NULL) { + dprintf("Error opening device at %s\n", + curlink->target); + sysfs_close_driver_by_name(driver); + return NULL; + } + strcpy(device->driver_name, drv_name); + if (driver->devices == NULL) + driver->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_driver_by_name_dev); + dlist_unshift(driver->devices, device); + } + } + return driver; +} + +/** + * get_driver_path: looks up the bus the driver is on and builds path to + * the driver. + * @drv: driver to look for + * @path: buffer to return path to driver + * @psize: size of "path" + * Returns 0 on success and -1 on error + */ +static int get_driver_path(const unsigned char *drv, + unsigned char *path, size_t psize) +{ + unsigned char bus_name[SYSFS_NAME_LEN]; + + if (drv == NULL || path == NULL) { + errno = EINVAL; + return -1; + } + memset(bus_name, 0, SYSFS_NAME_LEN); + memset(path, 0, SYSFS_PATH_MAX); + if ((sysfs_find_driver_bus(drv, bus_name, SYSFS_NAME_LEN)) < 0) { + dprintf("Driver %s not found\n", drv); + return -1; + } + if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) { + dprintf("Error getting sysfs mount path\n"); + return -1; + } + strcat(path, SYSFS_BUS_DIR); + strcat(path, "/"); + strcat(path, bus_name); + strcat(path, SYSFS_DRIVERS_DIR); + strcat(path, "/"); + strcat(path, drv); + fprintf(stdout, "get_driver_path %s\n", path); + return 0; +} + +/** + * sysfs_write_driver_attr: modify "writable" driver attribute + * @drv: driver whose attribute has to be modified + * @attrib: Attribute to be modified + * @value: Value to change to + * Returns 0 on success -1 on failure + */ +int sysfs_write_driver_attr(unsigned char *drv, unsigned char *attrib, + unsigned char *value, size_t len) +{ + struct sysfs_attribute *attribute = NULL; + unsigned char path[SYSFS_PATH_MAX]; + + if (drv == NULL || attrib == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + memset(path, 0, SYSFS_PATH_MAX); + if ((get_driver_path(drv, path, SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to driver %s\n", drv); + return -1; + } + strcat(path, "/"); + strcat(path, attrib); + attribute = sysfs_open_attribute(path); + if (attribute == NULL) { + dprintf("Attribute %s could not be retrieved for driver %s\n", + attrib, drv); + return -1; + } + if (attribute->method & SYSFS_METHOD_SHOW) { + if ((sysfs_read_attribute(attribute)) != 0) { + dprintf("Error reading attribute %s for driver %s\n", + attrib, drv); + sysfs_close_attribute(attribute); + return -1; + } + } + if ((sysfs_write_attribute(attribute, value, len)) < 0) { + dprintf("Error setting %s to %s\n", attrib, value); + sysfs_close_attribute(attribute); + return -1; + } + sysfs_close_attribute(attribute); + return 0; +} + +/** + * sysfs_read_driver_attr: read the user supplied driver attribute + * @drv: driver whose attribute has to be read + * @attrib: Attribute to be read + * @value: Buffer to return the read value + * @len: Length of the buffer "value" + * Returns 0 on success -1 on failure + */ +int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib, + unsigned char *value, size_t len) +{ + struct sysfs_attribute *attribute = NULL; + unsigned char path[SYSFS_PATH_MAX]; + + if (drv == NULL || attrib == NULL || value == NULL) { + errno = EINVAL; + return -1; + } + + memset(path, 0, SYSFS_NAME_LEN); + if ((get_driver_path(drv, path, SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to driver %s\n", drv); + return -1; + } + strcat(path, "/"); + strcat(path, attrib); + attribute = sysfs_open_attribute(path); + if (attribute == NULL) { + dprintf("Error opening attribute %s for driver %s\n", + attrib, drv); + return -1; + } + if (!(attribute->method & SYSFS_METHOD_SHOW)) { + dprintf("Show method not supported for attribute %s\n", + attrib); + sysfs_close_attribute(attribute); + return -1; + } + if ((sysfs_read_attribute(attribute)) != 0) { + dprintf("Error reading attribute %s for driver %s\n", + attrib, drv); + sysfs_close_attribute(attribute); + return -1; + } + if (attribute->len > len) { + dprintf("Value length %d is larger than supplied buffer %d\n", + attribute->len, len); + sysfs_close_attribute(attribute); + return -1; + } + strncpy(value, attribute->value, attribute->len); + value[(attribute->len)+1] = 0; + sysfs_close_attribute(attribute); + return 0; +} + diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index a2410abe69..4475342433 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -3,7 +3,7 @@ * * System utility functions for libsysfs * - * Copyright (C) 2003 International Business Machines, Inc. + * Copyright (C) IBM Corp. 2003 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,8 +30,8 @@ * @len: size of mnt_path * returns 0 with success and -1 with error. */ -static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, - size_t len) +static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, + unsigned char *mnt_path, size_t len) { FILE *mnt; struct mntent *mntent; @@ -45,7 +45,7 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, } if ((mnt = setmntent(SYSFS_PROC_MNTS, "r")) == NULL) { - dprintf(stderr, "Error getting mount information\n"); + dprintf("Error getting mount information\n"); return -1; } while (ret == 0 && dirlen == 0 && (mntent = getmntent(mnt)) != NULL) { @@ -54,15 +54,14 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, if (dirlen <= (len - 1)) { strcpy(mnt_path, mntent->mnt_dir); } else { - dprintf(stderr, - "Error - mount path too long\n"); + dprintf("Error - mount path too long\n"); ret = -1; } } } endmntent(mnt); if (dirlen == 0 && ret == 0) { - dprintf(stderr, "Filesystem %s not found!\n", fs_type); + dprintf("Filesystem %s not found!\n", fs_type); errno = EINVAL; ret = -1; } @@ -75,7 +74,7 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, * @len: size of mnt_path * returns 0 with success and -1 with error. */ -int sysfs_get_mnt_path(char *mnt_path, size_t len) +int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) { int ret = -1; @@ -93,9 +92,10 @@ int sysfs_get_mnt_path(char *mnt_path, size_t len) * @name: where to put name * @len: size of name */ -int sysfs_get_name_from_path(const char *path, char *name, size_t len) +int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, + size_t len) { - char *n = NULL; + unsigned char *n = NULL; if (path == NULL || name == NULL) { errno = EINVAL; @@ -118,11 +118,11 @@ int sysfs_get_name_from_path(const char *path, char *name, size_t len) * @target: where to put name * @len: size of name */ -int sysfs_get_link(const char *path, char *target, size_t len) +int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) { - char devdir[SYSFS_PATH_MAX]; - char linkpath[SYSFS_PATH_MAX]; - char *d = NULL; + unsigned char devdir[SYSFS_PATH_MAX]; + unsigned char linkpath[SYSFS_PATH_MAX]; + unsigned char *d = NULL; if (path == NULL || target == NULL) { errno = EINVAL; @@ -133,7 +133,7 @@ int sysfs_get_link(const char *path, char *target, size_t len) memset(linkpath, 0, SYSFS_PATH_MAX); if ((sysfs_get_mnt_path(devdir, SYSFS_PATH_MAX)) != 0) { - dprintf(stderr, "Sysfs not supported on this system\n"); + dprintf("Sysfs not supported on this system\n"); return -1; } @@ -154,3 +154,136 @@ int sysfs_get_link(const char *path, char *target, size_t len) return 0; } + + +/** + * sysfs_del_name: free function for sysfs_open_subsystem_list + * @name: memory area to be freed + */ +void sysfs_del_name(void *name) +{ + free(name); +} + + +/** + * sysfs_close_list: generic list free routine + * @list: dlist to free + * Returns nothing + */ +void sysfs_close_list(struct dlist *list) +{ + if (list != NULL) + dlist_destroy(list); +} + +/** + * sysfs_open_subsystem_list: gets a list of all supported "name" subsystem + * details from the system + * @name: name of the subsystem, eg., "bus", "class", "devices" + * Returns a dlist of supported names or NULL if subsystem not supported + */ +struct dlist *sysfs_open_subsystem_list(unsigned char *name) +{ + unsigned char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL; + struct sysfs_directory *dir = NULL, *cur = NULL; + struct dlist *list = NULL; + + if (name == NULL) + return NULL; + + if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { + dprintf("Error getting sysfs mount point\n"); + return NULL; + } + + strcat(sysfs_path, name); + dir = sysfs_open_directory(sysfs_path); + if (dir == NULL) { + dprintf("Error opening sysfs_directory at %s\n", sysfs_path); + return NULL; + } + + if (sysfs_read_directory(dir) != 0) { + dprintf("Error reading sysfs_directory at %s\n", sysfs_path); + sysfs_close_directory(dir); + return NULL; + } + + if (dir->subdirs != NULL) { + list = dlist_new_with_delete(SYSFS_NAME_LEN, + sysfs_del_name); + if (list == NULL) { + dprintf("Error creating list\n"); + sysfs_close_directory(dir); + return NULL; + } + + dlist_for_each_data(dir->subdirs, cur, + struct sysfs_directory) { + subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); + strcpy(subsys_name, cur->name); + dlist_unshift(list, subsys_name); + } + } + sysfs_close_directory(dir); + return list; +} + + +/** + * sysfs_open_bus_devices_list: gets a list of all devices on "name" bus + * @name: name of the subsystem, eg., "pci", "scsi", "usb" + * Returns a dlist of supported names or NULL if subsystem not supported + */ +struct dlist *sysfs_open_bus_devices_list(unsigned char *name) +{ + unsigned char sysfs_path[SYSFS_PATH_MAX], *device_name = NULL; + struct sysfs_directory *dir = NULL; + struct sysfs_link *cur = NULL; + struct dlist *list = NULL; + + if (name == NULL) + return NULL; + + if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { + dprintf("Error getting sysfs mount point\n"); + return NULL; + } + + strcat(sysfs_path, SYSFS_BUS_DIR); + strcat(sysfs_path, "/"); + strcat(sysfs_path, name); + strcat(sysfs_path, SYSFS_DEVICES_DIR); + dir = sysfs_open_directory(sysfs_path); + if (dir == NULL) { + dprintf("Error opening sysfs_directory at %s\n", sysfs_path); + return NULL; + } + + if (sysfs_read_directory(dir) != 0) { + dprintf("Error reading sysfs_directory at %s\n", sysfs_path); + sysfs_close_directory(dir); + return NULL; + } + + if (dir->links != NULL) { + list = dlist_new_with_delete(SYSFS_NAME_LEN, + sysfs_del_name); + if (list == NULL) { + dprintf("Error creating list\n"); + sysfs_close_directory(dir); + return NULL; + } + + dlist_for_each_data(dir->links, cur, + struct sysfs_link) { + device_name = (char *)calloc(1, SYSFS_NAME_LEN); + strcpy(device_name, cur->name); + dlist_unshift(list, device_name); + } + } + sysfs_close_directory(dir); + return list; +} + diff --git a/namedev.c b/namedev.c index ac05fd88e4..c21a5be7ad 100644 --- a/namedev.c +++ b/namedev.c @@ -547,7 +547,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at attr->mode = 0; if (class_dev->sysdevice) { - dbg_parse("class_dev->sysdevice->directory->path = '%s'", class_dev->sysdevice->directory->path); + dbg_parse("class_dev->sysdevice->path = '%s'", class_dev->sysdevice->path); dbg_parse("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); } else { dbg_parse("class_dev->name = '%s'", class_dev->name); @@ -557,19 +557,21 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at switch (dev->type) { case LABEL: { - char *temp; + struct sysfs_attribute *tmpattr = NULL; + struct sysfs_class_device *class_dev_parent = NULL; + char *temp = NULL; dbg_parse("LABEL: match file '%s' with value '%s'", dev->sysfs_file, dev->sysfs_value); /* try to find the attribute in the class device directory */ - temp = sysfs_get_value_from_attributes(class_dev->directory->attributes, dev->sysfs_file); - if (temp) + tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); + if (tmpattr) goto label_found; /* look in the class device device directory if present */ if (class_dev->sysdevice) { - temp = sysfs_get_value_from_attributes(class_dev->sysdevice->directory->attributes, dev->sysfs_file); - if (temp) + tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); + if (tmpattr) goto label_found; } @@ -577,14 +579,13 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at * as block partitions don't point to the physical device. Need to fix that * up in the kernel... */ - if (strstr(class_dev->directory->path, "block")) { + if (strstr(class_dev->path, "block")) { dbg_parse("looking at block device..."); - if (isdigit(class_dev->directory->path[strlen(class_dev->directory->path)-1])) { + if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { char path[SYSFS_PATH_MAX]; - struct sysfs_class_device *class_dev_parent; dbg_parse("really is a partition..."); - strcpy(path, class_dev->directory->path); + strcpy(path, class_dev->path); temp = strrchr(path, '/'); *temp = 0x00; dbg_parse("looking for a class device at '%s'", path); @@ -596,35 +597,36 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at dbg_parse("class_dev_parent->name = %s", class_dev_parent->name); /* try to find the attribute in the class device directory */ - temp = sysfs_get_value_from_attributes(class_dev_parent->directory->attributes, dev->sysfs_file); - if (temp) { - //sysfs_close_class_device(class_dev_parent); + tmpattr = sysfs_get_classdev_attr(class_dev_parent, dev->sysfs_file); + if (tmpattr) goto label_found; - } /* look in the class device device directory if present */ if (class_dev_parent->sysdevice) { - temp = sysfs_get_value_from_attributes(class_dev_parent->sysdevice->directory->attributes, dev->sysfs_file); - if (temp) { - // sysfs_close_class_device(class_dev_parent); + tmpattr = sysfs_get_classdev_attr(class_dev_parent, dev->sysfs_file); + if (tmpattr) goto label_found; - } } } } + if (class_dev_parent) + sysfs_close_class_device(class_dev_parent); + continue; label_found: - temp[strlen(temp)-1] = 0x00; - dbg_parse("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, temp, dev->sysfs_value); - if (strcmp(dev->sysfs_value, temp) != 0) + tmpattr->value[strlen(tmpattr->value)-1] = 0x00; + dbg_parse("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); + if (strcmp(dev->sysfs_value, tmpattr->value) != 0) { + if (class_dev_parent) + sysfs_close_class_device(class_dev_parent); continue; + } strcpy(attr->name, dev->attr.name); - if (isdigit(class_dev->directory->path[strlen(class_dev->directory->path)-1])) { - temp[0] = class_dev->directory->path[strlen(class_dev->directory->path)-1]; - temp[1] = 0x00; + if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { + temp = &class_dev->path[strlen(class_dev->path)-1]; strcat(attr->name, temp); } if (dev->attr.mode != 0) { @@ -635,6 +637,8 @@ label_found: dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->sysfs_file, dev->sysfs_value, attr->name, dev->attr.owner, dev->attr.group, dev->attr.mode); + if (class_dev_parent) + sysfs_close_class_device(class_dev_parent); goto done; break; } @@ -646,7 +650,7 @@ label_found: found = 0; if (!class_dev->sysdevice) continue; - strcpy(path, class_dev->sysdevice->directory->path); + strcpy(path, class_dev->sysdevice->path); temp = strrchr(path, '/'); dbg_parse("NUMBER path = '%s'", path); dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); @@ -682,7 +686,7 @@ label_found: if (!class_dev->sysdevice) continue; found = 0; - strcpy(path, class_dev->sysdevice->directory->path); + strcpy(path, class_dev->sysdevice->path); temp = strrchr(path, '/'); dbg_parse("TOPOLOGY path = '%s'", path); dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); From 97d8c0156724590066be15076f58e0fe6638f77e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 17:08:45 -0700 Subject: [PATCH 0091/4284] [PATCH] 004 release --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 535e5b9293..7f8e689b93 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 003_bk +VERSION = 004 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 59b06a0d16..ada10a883e 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 003_bk +Version: 004 Release: 1 License: GPL Group: Utilities/System From d4e52dd0d95c21ccda50310404be4b5a540cc498 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 17:09:52 -0700 Subject: [PATCH 0092/4284] [PATCH] 004 changelog entrys --- ChangeLog | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa72db5c20..b57cd72eaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +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 + o update changelog for 003 release TAG: v003 + +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 ============================================ @@ -102,5 +137,3 @@ Greg Kroah-Hartman: o fixed up config o Initial repository create o BitKeeper file /home/greg/src/udev/udev/ChangeSet - - From c056c5141b16fe95485eeb233fe8b90954686a60 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 20:19:09 -0700 Subject: [PATCH 0093/4284] [PATCH] make config files, sysfs root, and udev root configurable from config variables This will make running tests a lot simpler. --- namedev.c | 16 ++++------ namedev.h | 3 -- udev-add.c | 11 +------ udev-remove.c | 2 +- udev.c | 84 ++++++++++++++++++++++++++++++++++++++++----------- udev.h | 13 +++++++- udevdb.c | 4 +-- udevdb.h | 2 -- 8 files changed, 89 insertions(+), 46 deletions(-) diff --git a/namedev.c b/namedev.c index c21a5be7ad..f2842ce436 100644 --- a/namedev.c +++ b/namedev.c @@ -197,7 +197,6 @@ static int get_pair(char **orig_string, char **left, char **right) static int namedev_init_config(void) { - char filename[255]; char line[255]; char *temp; char *temp2; @@ -206,11 +205,10 @@ static int namedev_init_config(void) int retval = 0; struct config_device dev; - strcpy(filename, UDEV_CONFIG_DIR NAMEDEV_CONFIG_FILE); - dbg("opening %s to read as permissions config", filename); - fd = fopen(filename, "r"); + dbg("opening %s to read as permissions config", udev_config_filename); + fd = fopen(udev_config_filename, "r"); if (fd == NULL) { - dbg("Can't open %s", filename); + dbg("Can't open %s", udev_config_filename); return -ENODEV; } @@ -394,7 +392,6 @@ exit: static int namedev_init_permissions(void) { - char filename[255]; char line[255]; char *temp; char *temp2; @@ -402,11 +399,10 @@ static int namedev_init_permissions(void) int retval = 0; struct config_device dev; - strcpy(filename, UDEV_CONFIG_DIR NAMEDEV_CONFIG_PERMISSION_FILE); - dbg("opening %s to read as permissions config", filename); - fd = fopen(filename, "r"); + dbg("opening %s to read as permissions config", udev_config_permission_filename); + fd = fopen(udev_config_permission_filename, "r"); if (fd == NULL) { - dbg("Can't open %s", filename); + dbg("Can't open %s", udev_config_permission_filename); return -ENODEV; } diff --git a/namedev.h b/namedev.h index 567756c827..d5aaae202c 100644 --- a/namedev.h +++ b/namedev.h @@ -28,10 +28,7 @@ struct sysfs_class_device; -/* namedev config files */ #define COMMENT_CHARACTER '#' -#define NAMEDEV_CONFIG_PERMISSION_FILE "namedev.permissions" -#define NAMEDEV_CONFIG_FILE "namedev.config" enum config_type { KERNEL_NAME = 0, /* must be 0 to let memset() default to this value */ diff --git a/udev-add.c b/udev-add.c index 7906638a7f..d9d7cab103 100644 --- a/udev-add.c +++ b/udev-add.c @@ -34,8 +34,6 @@ #include "udevdb.h" #include "libsysfs/libsysfs.h" -static char sysfs_path[SYSFS_PATH_MAX]; - /* * Right now the major/minor of a device is stored in a file called * "dev" in sysfs. @@ -75,7 +73,7 @@ static int create_node(struct udevice *dev) char filename[255]; int retval = 0; - strncpy(filename, UDEV_ROOT, sizeof(filename)); + strncpy(filename, udev_root, sizeof(filename)); strncat(filename, dev->name, sizeof(filename)); switch (dev->type) { @@ -171,13 +169,6 @@ int udev_add_device(char *path, char *subsystem) else dev.type = 'c'; - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - dbg("sysfs_path = %s", sysfs_path); - if (retval) { - dbg("sysfs_get_mnt_path failed"); - goto exit; - } - retval = sleep_for_dev(path); if (retval) goto exit; diff --git a/udev-remove.c b/udev-remove.c index c61a948fa0..666928f318 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -70,7 +70,7 @@ static int delete_node(char *name) { char filename[255]; - strncpy(filename, UDEV_ROOT, sizeof(filename)); + strncpy(filename, udev_root, sizeof(filename)); strncat(filename, name, sizeof(filename)); dbg("unlinking %s", filename); diff --git a/udev.c b/udev.c index a398477118..8d650c2561 100644 --- a/udev.c +++ b/udev.c @@ -34,8 +34,19 @@ #include "udevdb.h" #include "libsysfs/libsysfs.h" +/* global variables */ +char **main_argv; +char **main_envp; -static char *get_action(void) +char sysfs_path[SYSFS_PATH_MAX]; +char *udev_config_dir; +char *udev_root; +char udev_db_filename[PATH_MAX+NAME_MAX]; +char udev_config_permission_filename[PATH_MAX+NAME_MAX]; +char udev_config_filename[PATH_MAX+NAME_MAX]; + + +static inline char *get_action(void) { char *action; @@ -43,22 +54,60 @@ static char *get_action(void) return action; } - -static char *get_device(void) +static inline char *get_devpath(void) { - char *device; + char *devpath; - device = getenv("DEVPATH"); - return device; + devpath = getenv("DEVPATH"); + return devpath; } -char **main_argv; -char **main_envp; +static inline char *get_seqnum(void) +{ + char *seqnum; + + seqnum = getenv("SEQNUM"); + return seqnum; +} + +static void get_dirs(void) +{ + char *udev_test; + char *temp; + int retval; + + udev_test = getenv("UDEV_TEST"); + if (udev_test == NULL) { + /* normal operation, use the compiled in defaults */ + udev_config_dir = UDEV_CONFIG_DIR; + udev_root = UDEV_ROOT; + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + dbg("sysfs_path = %s", sysfs_path); + if (retval) + dbg("sysfs_get_mnt_path failed"); + + } else { + /* hm testing is happening, use the specified values */ + temp = getenv("UDEV_SYSFS_PATH"); + strncpy(sysfs_path, temp, sizeof(sysfs_path)); + udev_config_dir = getenv("UDEV_CONFIG_DIR"); + udev_root = getenv("UDEV_ROOT"); + } + + strncpy(udev_db_filename, udev_config_dir, sizeof(udev_db_filename)); + strncat(udev_db_filename, UDEV_DB, sizeof(udev_db_filename)); + + strncpy(udev_config_filename, udev_config_dir, sizeof(udev_config_filename)); + strncat(udev_config_filename, NAMEDEV_CONFIG_FILE, sizeof(udev_config_filename)); + + strncpy(udev_config_permission_filename, udev_config_dir, sizeof(udev_config_permission_filename)); + strncat(udev_config_permission_filename, NAMEDEV_CONFIG_PERMISSION_FILE, sizeof(udev_config_permission_filename)); +} int main(int argc, char **argv, char **envp) { char *action; - char *device; + char *devpath; char *subsystem; int retval = -EINVAL; @@ -74,16 +123,16 @@ int main(int argc, char **argv, char **envp) subsystem = argv[1]; - device = get_device(); - if (!device) { - dbg ("no device?"); + devpath = get_devpath(); + if (!devpath) { + dbg ("no devpath?"); goto exit; } - dbg("looking at %s", device); + dbg("looking at %s", devpath); /* we only care about class devices and block stuff */ - if (!strstr(device, "class") && - !strstr(device, "block")) { + if (!strstr(devpath, "class") && + !strstr(devpath, "block")) { dbg("not block or class"); goto exit; } @@ -101,6 +150,7 @@ int main(int argc, char **argv, char **envp) } /* initialize udev database */ + get_dirs(); retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { dbg("Unable to initialize database."); @@ -111,10 +161,10 @@ int main(int argc, char **argv, char **envp) namedev_init(); if (strcmp(action, "add") == 0) - retval = udev_add_device(device, argv[1]); + retval = udev_add_device(devpath, subsystem); else if (strcmp(action, "remove") == 0) - retval = udev_remove_device(device, argv[1]); + retval = udev_remove_device(devpath, subsystem); else { dbg("Unknown action: %s", action); diff --git a/udev.h b/udev.h index 6d7017ff51..4c8914f1e2 100644 --- a/udev.h +++ b/udev.h @@ -24,6 +24,7 @@ #define UDEV_H #include "libsysfs/libsysfs.h" +#include #ifdef DEBUG #include @@ -50,7 +51,10 @@ extern int log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); -/* Lots of constants that should be in a config file sometime */ +/* filenames for the config and database files */ +#define UDEV_DB "udevdb.tdb" +#define NAMEDEV_CONFIG_PERMISSION_FILE "namedev.permissions" +#define NAMEDEV_CONFIG_FILE "namedev.config" #define NAME_SIZE 100 #define OWNER_SIZE 30 @@ -78,5 +82,12 @@ extern int udev_remove_device(char *path, char *subsystem); extern char **main_argv; extern char **main_envp; +extern char sysfs_path[SYSFS_PATH_MAX]; +extern char *udev_config_dir; +extern char *udev_root; +extern char udev_db_filename[PATH_MAX+NAME_MAX]; +extern char udev_config_permission_filename[PATH_MAX+NAME_MAX]; +extern char udev_config_filename[PATH_MAX+NAME_MAX]; + #endif diff --git a/udevdb.c b/udevdb.c index b75bf8048f..ec67a07962 100644 --- a/udevdb.c +++ b/udevdb.c @@ -124,12 +124,12 @@ int udevdb_init(int init_flag) if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) return -EINVAL; - udevdb = tdb_open(UDEV_CONFIG_DIR UDEV_DB, 0, init_flag, O_RDWR | O_CREAT, 0644); + udevdb = tdb_open(udev_db_filename, 0, init_flag, O_RDWR | O_CREAT, 0644); if (udevdb == NULL) { if (init_flag == UDEVDB_INTERNAL) dbg("Unable to initialize in-memory database"); else - dbg("Unable to initialize database at %s", UDEV_CONFIG_DIR UDEV_DB); + dbg("Unable to initialize database at %s", udev_db_filename); return -EINVAL; } return 0; diff --git a/udevdb.h b/udevdb.h index 12f6648369..9935e80e9c 100644 --- a/udevdb.h +++ b/udevdb.h @@ -4,8 +4,6 @@ #ifndef _UDEVDB_H_ #define _UDEVDB_H_ -#define UDEV_DB "udevdb.tdb" - /* Udevdb initialization flags */ #define UDEVDB_DEFAULT 0 /* Defaults database to use file */ #define UDEVDB_INTERNAL 1 /* Don't store db on disk, use in memory */ From ada26cf593614bc26fe836e489bc8d7a31c53bc6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 20:20:03 -0700 Subject: [PATCH 0094/4284] [PATCH] change version to 004_bk --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7f8e689b93..2cc0c2a680 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 004 +VERSION = 004_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index ada10a883e..fd6b488aeb 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 004 +Version: 004_bk Release: 1 License: GPL Group: Utilities/System From 5b52fccb5950e26a30cd4bc44932fec45ce44227 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 21:40:53 -0700 Subject: [PATCH 0095/4284] [PATCH] Fix bug causing udev to sleep forever waiting for dev file to show up. Now we will timeout properly. --- udev-add.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev-add.c b/udev-add.c index d9d7cab103..2b27855553 100644 --- a/udev-add.c +++ b/udev-add.c @@ -150,6 +150,7 @@ int sleep_for_dev(char *path) /* sleep for a second or two to give the kernel a chance to * create the dev file */ sleep(1); + ++loop; } retval = -ENODEV; exit: From c2f17c9ea8a90d1c12158b947b3f8096404afe33 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 21:41:35 -0700 Subject: [PATCH 0096/4284] [PATCH] more overrides of config info with env variables if in test mode. --- udev.c | 53 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/udev.c b/udev.c index 8d650c2561..ed42862c00 100644 --- a/udev.c +++ b/udev.c @@ -39,8 +39,8 @@ char **main_argv; char **main_envp; char sysfs_path[SYSFS_PATH_MAX]; -char *udev_config_dir; -char *udev_root; +char *udev_config_dir = UDEV_CONFIG_DIR; +char *udev_root = UDEV_ROOT; char udev_db_filename[PATH_MAX+NAME_MAX]; char udev_config_permission_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; @@ -72,36 +72,49 @@ static inline char *get_seqnum(void) static void get_dirs(void) { - char *udev_test; char *temp; + char *udev_db = UDEV_DB; + char *udev_config = NAMEDEV_CONFIG_FILE; + char *udev_permission = NAMEDEV_CONFIG_PERMISSION_FILE; int retval; - udev_test = getenv("UDEV_TEST"); - if (udev_test == NULL) { - /* normal operation, use the compiled in defaults */ - udev_config_dir = UDEV_CONFIG_DIR; - udev_root = UDEV_ROOT; - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - dbg("sysfs_path = %s", sysfs_path); - if (retval) - dbg("sysfs_get_mnt_path failed"); + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + if (retval) + dbg("sysfs_get_mnt_path failed"); - } else { - /* hm testing is happening, use the specified values */ + /* see if we should try to override any of the default values */ + temp = getenv("UDEV_TEST"); + if (temp != NULL) { + /* hm testing is happening, use the specified values, if they are present */ temp = getenv("UDEV_SYSFS_PATH"); - strncpy(sysfs_path, temp, sizeof(sysfs_path)); - udev_config_dir = getenv("UDEV_CONFIG_DIR"); - udev_root = getenv("UDEV_ROOT"); + if (temp) + strncpy(sysfs_path, temp, sizeof(sysfs_path)); + temp = getenv("UDEV_CONFIG_DIR"); + if (temp) + udev_config_dir = temp; + temp = getenv("UDEV_ROOT"); + if (temp) + udev_root = temp; + temp = getenv("UDEV_DB"); + if (temp) + udev_db = temp; + temp = getenv("UDEV_CONFIG_FILE"); + if (temp) + udev_config = temp; + temp = getenv("UDEV_PERMISSION_FILE"); + if (temp) + udev_permission = temp; } + dbg("sysfs_path = %s", sysfs_path); strncpy(udev_db_filename, udev_config_dir, sizeof(udev_db_filename)); - strncat(udev_db_filename, UDEV_DB, sizeof(udev_db_filename)); + strncat(udev_db_filename, udev_db, sizeof(udev_db_filename)); strncpy(udev_config_filename, udev_config_dir, sizeof(udev_config_filename)); - strncat(udev_config_filename, NAMEDEV_CONFIG_FILE, sizeof(udev_config_filename)); + strncat(udev_config_filename, udev_config, sizeof(udev_config_filename)); strncpy(udev_config_permission_filename, udev_config_dir, sizeof(udev_config_permission_filename)); - strncat(udev_config_permission_filename, NAMEDEV_CONFIG_PERMISSION_FILE, sizeof(udev_config_permission_filename)); + strncat(udev_config_permission_filename, udev_permission, sizeof(udev_config_permission_filename)); } int main(int argc, char **argv, char **envp) From 6089318cd42a403b9816e7f5fc578f6888920b74 Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Tue, 21 Oct 2003 21:45:19 -0700 Subject: [PATCH 0097/4284] [PATCH] udev: another canidate for static Another one of those "trivial patches so everything must be good" sleep_for_dev() isn't exported or defined in a header, so it can be marked 'static' --- udev-add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev-add.c b/udev-add.c index 2b27855553..7d0bdadcb7 100644 --- a/udev-add.c +++ b/udev-add.c @@ -128,7 +128,7 @@ exit: * If it doesn't happen in about 10 seconds, give up. */ #define SECONDS_TO_WAIT_FOR_DEV 10 -int sleep_for_dev(char *path) +static int sleep_for_dev(char *path) { char filename[SYSFS_PATH_MAX + 6]; struct stat buf; From eb13ff87074f0a8dec135e4cb476585fe29bf49b Mon Sep 17 00:00:00 2001 From: "kay@vrfy.org" Date: Tue, 21 Oct 2003 21:46:00 -0700 Subject: [PATCH 0098/4284] [PATCH] man page update here a new patch for the man page: o namdev.permissions added o corrected a few typos o corrected text for config line format. owner, group mode are only in namedev.permissions (don't know what i was dreaming, while i wrote this :)) --- udev.8 | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/udev.8 b/udev.8 index efb02cc618..8865a7905a 100644 --- a/udev.8 +++ b/udev.8 @@ -2,28 +2,30 @@ .SH NAME udev \- Linux configurable dynamic device naming support .SH SYNOPSIS -.B udev +.BI udev " hotplug-subsystem" .SH "DESCRIPTION" .B udev creates or removes device node files usually located in the /dev directory. +Its goal is to provide a dynamic device directory that contains only the files +for devices that are actually present. +.P As part of the .B hotplug subsystem, .B udev -is exectuted if a kernel device is added or removed from the system. -.P +is executed if a kernel device is added or removed from the system. On device creation, .B udev -reads the sysfs directory of the given device, to collect device attributes +reads the sysfs directory of the given device to collect device attributes like label, serial number or bus device number. These attributes are passed as a key to the namedev subsystem to receive a unique name for device file creation. namedev maintains a database for devices present on the system. -.P +.br On device removal, .B udev -queries the namedev database for the name of the device file to delete. -.P +queries the namedev database for the name of the device file to be deleted. +.SH "CONFIGURATION" namedev expects its configuration at .I /etc/udev/namedev.config. The file consists of a set of lines. All empty lines and @@ -31,11 +33,16 @@ lines beginning with a '#' will be ignored. .br Every line defines the mapping between device attributes and the device file name. It starts with a keyword defining the method used to match, followed by -one ore more keys to compare, optional ownwership and permission settings and -the filename for the device. If no matching configuration is found, -the default kernel device name is used. +one ore more keys to compare and the filename for the device. If no matching +configuration is found, the default kernel device name is used. .P -.I method, key,[key,...] [owner,] [group,] [mode,] name +The line format is: +.RS +.sp +.I method, key,[key,...] name +.sp +.RE +where valid methods with corresponding keys are: .TP .B LABEL device label or serial number, like USB serial number, SCSI UUID or @@ -62,7 +69,9 @@ key: \fBKERNEL_NAME\fP calling external program, that returns a string to match .br keys: \fBBUS\fP, \fBPROGRAM\fP, \fBID\fP -.SH "EXAMPLE" +.P +A sample \fInamedev.conf\fP might look like this: +.sp .nf # USB printer to be called lp_color LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_color" @@ -79,6 +88,22 @@ REPLACE, KERNEL="ttyUSB1", NAME="pda" # if /sbin/dev_id returns "V0815" device will be called dev0815 CALLOUT, PROGRAM="/sbin/dev_id", BUS="pci", ID="V0815", NAME="dev0815" .fi +.P +Permissions and ownership for the created device files may specified at +.I /etc/udev/namedev.permissions. +The file consists of a set of lines. All empty lines and +lines beginning with a '#' will be ignored. +.br +Every line lists a device name followed by owner, group and permission mode. All values are separated by colons. +.sp +A sample \fInamedev.permissions\fP might look like this: +.sp +.nf +#name:user:group:mode +ttyUSB1:root:uucp:0666 +dsp1:::0666 +.fi + .SH "FILES" .nf .ft B @@ -89,7 +114,7 @@ CALLOUT, PROGRAM="/sbin/dev_id", BUS="pci", ID="V0815", NAME="dev0815" .fi .LP .SH "SEE ALSO" -.B hotplug (8) +.BR hotplug (8) .PP The .I http://linux-hotplug.sourceforge.net/ From 116176b0bde45832d212b60e8d7bcb5d87f5ce46 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 21:47:50 -0700 Subject: [PATCH 0099/4284] [PATCH] fix dbg line in namedev.c Thanks to Kay Sievers for pointing this out. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index f2842ce436..3b0a0caf48 100644 --- a/namedev.c +++ b/namedev.c @@ -205,7 +205,7 @@ static int namedev_init_config(void) int retval = 0; struct config_device dev; - dbg("opening %s to read as permissions config", udev_config_filename); + dbg("opening %s to read as config", udev_config_filename); fd = fopen(udev_config_filename, "r"); if (fd == NULL) { dbg("Can't open %s", udev_config_filename); From c2ec26b92809193a5126d34299abfe8df7877c0c Mon Sep 17 00:00:00 2001 From: "kay@vrfy.org" Date: Tue, 21 Oct 2003 21:48:11 -0700 Subject: [PATCH 0100/4284] [PATCH] namedev.c comments + debug patch and a patch for namdev.c comments + debug o correct 'device device' o correct permission file to config file --- namedev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 3b0a0caf48..d049349f22 100644 --- a/namedev.c +++ b/namedev.c @@ -564,7 +564,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at if (tmpattr) goto label_found; - /* look in the class device device directory if present */ + /* look in the class device directory if present */ if (class_dev->sysdevice) { tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); if (tmpattr) @@ -597,7 +597,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *at if (tmpattr) goto label_found; - /* look in the class device device directory if present */ + /* look in the class device directory if present */ if (class_dev_parent->sysdevice) { tmpattr = sysfs_get_classdev_attr(class_dev_parent, dev->sysfs_file); if (tmpattr) From 7bfd1a56436684ab1bc0d8e3661d6df81d3c82ef Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 00:18:49 -0700 Subject: [PATCH 0101/4284] [PATCH] more warning flags to the build. --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2cc0c2a680..6710ede1b9 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,8 @@ GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ then echo "-Os"; else echo "-O2" ; fi} -WARNINGS := -Wall -Wshadow -Wstrict-prototypes +# add -Wredundant-decls when libsysfs gets cleaned up +WARNINGS := -Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations # Some nice architecture specific optimizations ifeq ($(strip $(TARGET_ARCH)),arm) From d41120879358f783eb1a457f340c1a4b538a9410 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 22:08:03 -0700 Subject: [PATCH 0102/4284] [PATCH] rename namedev.permissions and namedev.config to udev.permissions and udev.config the namedev name didn't really make much sense anymore... --- Makefile | 8 ++++---- udev.8 | 18 +++++++++--------- udev.c | 4 ++-- namedev.config => udev.config | 0 udev.h | 6 +++--- namedev.permissions => udev.permissions | 0 udev.spec | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) rename namedev.config => udev.config (100%) rename namedev.permissions => udev.permissions (100%) diff --git a/Makefile b/Makefile index 6710ede1b9..a5c00b7191 100644 --- a/Makefile +++ b/Makefile @@ -198,14 +198,14 @@ install: all $(INSTALL) -d $(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(sbindir)/$(ROOT) $(INSTALL_DATA) -D udev.8 $(mandir)/man8/udev.8 - $(INSTALL_DATA) namedev.config $(configdir) - $(INSTALL_DATA) namedev.permissions $(configdir) + $(INSTALL_DATA) udev.config $(configdir) + $(INSTALL_DATA) udev.permissions $(configdir) - ln -s $(sbindir)/$(ROOT) $(hotplugdir)/udev.hotplug uninstall: - rm $(hotplugdir)/udev.hotplug - - rm $(configdir)/namedev.permissions - - rm $(configdir)/namedev.config + - rm $(configdir)/udev.permissions + - rm $(configdir)/udev.config - rm $(mandir)/man8/udev.8 - rm $(sbindir)/$(ROOT) - rmdir $(hotplugdir) diff --git a/udev.8 b/udev.8 index 8865a7905a..42239c824d 100644 --- a/udev.8 +++ b/udev.8 @@ -18,16 +18,16 @@ On device creation, .B udev reads the sysfs directory of the given device to collect device attributes like label, serial number or bus device number. -These attributes are passed as a key to the namedev subsystem -to receive a unique name for device file creation. -namedev maintains a database for devices present on the system. +These attributes are treated as a key +to determine a unique name for device file creation. +udev maintains a database for devices present on the system. .br On device removal, .B udev -queries the namedev database for the name of the device file to be deleted. +queries the internal database for the name of the device file to be deleted. .SH "CONFIGURATION" -namedev expects its configuration at -.I /etc/udev/namedev.config. +udev expects its configuration at +.I /etc/udev/udev.config. The file consists of a set of lines. All empty lines and lines beginning with a '#' will be ignored. .br @@ -70,7 +70,7 @@ calling external program, that returns a string to match .br keys: \fBBUS\fP, \fBPROGRAM\fP, \fBID\fP .P -A sample \fInamedev.conf\fP might look like this: +A sample \fIudev.conf\fP might look like this: .sp .nf # USB printer to be called lp_color @@ -90,13 +90,13 @@ CALLOUT, PROGRAM="/sbin/dev_id", BUS="pci", ID="V0815", NAME="dev0815" .fi .P Permissions and ownership for the created device files may specified at -.I /etc/udev/namedev.permissions. +.I /etc/udev/udev.permissions. The file consists of a set of lines. All empty lines and lines beginning with a '#' will be ignored. .br Every line lists a device name followed by owner, group and permission mode. All values are separated by colons. .sp -A sample \fInamedev.permissions\fP might look like this: +A sample \fIudev.permissions\fP might look like this: .sp .nf #name:user:group:mode diff --git a/udev.c b/udev.c index ed42862c00..8746b9a810 100644 --- a/udev.c +++ b/udev.c @@ -74,8 +74,8 @@ static void get_dirs(void) { char *temp; char *udev_db = UDEV_DB; - char *udev_config = NAMEDEV_CONFIG_FILE; - char *udev_permission = NAMEDEV_CONFIG_PERMISSION_FILE; + char *udev_config = UDEV_CONFIG_FILE; + char *udev_permission = UDEV_CONFIG_PERMISSION_FILE; int retval; retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); diff --git a/namedev.config b/udev.config similarity index 100% rename from namedev.config rename to udev.config diff --git a/udev.h b/udev.h index 4c8914f1e2..1f6e981cc2 100644 --- a/udev.h +++ b/udev.h @@ -52,9 +52,9 @@ extern int log_message (int level, const char *format, ...) /* filenames for the config and database files */ -#define UDEV_DB "udevdb.tdb" -#define NAMEDEV_CONFIG_PERMISSION_FILE "namedev.permissions" -#define NAMEDEV_CONFIG_FILE "namedev.config" +#define UDEV_DB "udev.tdb" +#define UDEV_CONFIG_PERMISSION_FILE "udev.permissions" +#define UDEV_CONFIG_FILE "udev.config" #define NAME_SIZE 100 #define OWNER_SIZE 30 diff --git a/namedev.permissions b/udev.permissions similarity index 100% rename from namedev.permissions rename to udev.permissions diff --git a/udev.spec b/udev.spec index fd6b488aeb..ffdfb2470d 100644 --- a/udev.spec +++ b/udev.spec @@ -34,8 +34,8 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udev %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ -%attr(0644,root,root) /etc/udev/namedev.config -%attr(0644,root,root) /etc/udev/namedev.permissions +%attr(0644,root,root) /etc/udev/udev.config +%attr(0644,root,root) /etc/udev/udev.permissions %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(0644,root,root) %{_mandir}/man8/udev.8* From 9d496c74f3a6b1963727b515126e87e64abe046c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 21 Oct 2003 22:28:32 -0700 Subject: [PATCH 0103/4284] [PATCH] got rid of struct device_attr namedev.c is still a mess, that's up next after testing... --- namedev.c | 156 ++++++++++++++++++++++++++--------------------------- namedev.h | 7 ++- udev-add.c | 11 ++-- udev.h | 7 --- 4 files changed, 88 insertions(+), 93 deletions(-) diff --git a/namedev.c b/namedev.c index d049349f22..6ed2415cdd 100644 --- a/namedev.c +++ b/namedev.c @@ -22,7 +22,7 @@ */ /* define this to enable parsing debugging */ -/* #define DEBUG_PARSER */ +#define DEBUG_PARSER #include #include @@ -54,38 +54,38 @@ static void dump_dev(struct config_device *dev) case KERNEL_NAME: dbg_parse("KERNEL name ='%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->name, + dev->owner, dev->group, dev->mode); break; case LABEL: dbg_parse("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->bus, dev->sysfs_file, dev->sysfs_value, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, + dev->owner, dev->group, dev->mode); break; case NUMBER: dbg_parse("NUMBER name = '%s', bus = '%s', id = '%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->bus, dev->id, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->name, dev->bus, dev->id, + dev->owner, dev->group, dev->mode); break; case TOPOLOGY: dbg_parse("TOPOLOGY name = '%s', bus = '%s', place = '%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->bus, dev->place, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->name, dev->bus, dev->place, + dev->owner, dev->group, dev->mode); break; case REPLACE: dbg_parse("REPLACE name = %s, kernel_name = %s" " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->kernel_name, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->name, dev->kernel_name, + dev->owner, dev->group, dev->mode); break; case CALLOUT: dbg_parse("CALLOUT name = '%s', program ='%s', bus = '%s', id = '%s'" " owner = '%s', group = '%s', mode = '%#o'", - dev->attr.name, dev->exec_program, dev->bus, dev->id, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->name, dev->exec_program, dev->bus, dev->id, + dev->owner, dev->group, dev->mode); break; default: dbg_parse("Unknown type of device!"); @@ -109,18 +109,18 @@ static int add_dev(struct config_device *new_dev) * this one... */ list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); - if (strcmp(dev->attr.name, new_dev->attr.name) == 0) { + if (strcmp(dev->name, new_dev->name) == 0) { /* the same, copy the new info into this structure */ copy_var(dev, new_dev, type); - copy_var(dev, new_dev, attr.mode); + copy_var(dev, new_dev, mode); copy_string(dev, new_dev, bus); copy_string(dev, new_dev, sysfs_file); copy_string(dev, new_dev, sysfs_value); copy_string(dev, new_dev, id); copy_string(dev, new_dev, place); copy_string(dev, new_dev, kernel_name); - copy_string(dev, new_dev, attr.owner); - copy_string(dev, new_dev, attr.group); + copy_string(dev, new_dev, owner); + copy_string(dev, new_dev, group); return 0; } } @@ -260,11 +260,11 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.attr.name, temp3); + strcpy(dev.name, temp3); dbg_parse("LABEL name = '%s', bus = '%s', " "sysfs_file = '%s', sysfs_value = '%s'", - dev.attr.name, dev.bus, dev.sysfs_file, + dev.name, dev.bus, dev.sysfs_file, dev.sysfs_value); } @@ -290,10 +290,10 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.attr.name, temp3); + strcpy(dev.name, temp3); dbg_parse("NUMBER name = '%s', bus = '%s', id = '%s'", - dev.attr.name, dev.bus, dev.id); + dev.name, dev.bus, dev.id); } if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { @@ -318,10 +318,10 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.attr.name, temp3); + strcpy(dev.name, temp3); dbg_parse("TOPOLOGY name = '%s', bus = '%s', place = '%s'", - dev.attr.name, dev.bus, dev.place); + dev.name, dev.bus, dev.place); } if (strcasecmp(temp2, TYPE_REPLACE) == 0) { @@ -339,9 +339,9 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.attr.name, temp3); + strcpy(dev.name, temp3); dbg_parse("REPLACE name = %s, kernel_name = %s", - dev.attr.name, dev.kernel_name); + dev.name, dev.kernel_name); } if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { /* number type */ @@ -372,9 +372,9 @@ static int namedev_init_config(void) retval = get_value("NAME", &temp, &temp3); if (retval) continue; - strcpy(dev.attr.name, temp3); + strcpy(dev.name, temp3); dbg_parse("CALLOUT name = %s, program = %s", - dev.attr.name, dev.exec_program); + dev.name, dev.exec_program); } retval = add_dev(&dev); @@ -431,19 +431,19 @@ static int namedev_init_permissions(void) /* parse the line */ temp2 = strsep(&temp, ":"); - strncpy(dev.attr.name, temp2, sizeof(dev.attr.name)); + strncpy(dev.name, temp2, sizeof(dev.name)); temp2 = strsep(&temp, ":"); - strncpy(dev.attr.owner, temp2, sizeof(dev.attr.owner)); + strncpy(dev.owner, temp2, sizeof(dev.owner)); temp2 = strsep(&temp, ":"); - strncpy(dev.attr.group, temp2, sizeof(dev.attr.owner)); + strncpy(dev.group, temp2, sizeof(dev.owner)); - dev.attr.mode = strtol(temp, NULL, 8); + dev.mode = strtol(temp, NULL, 8); dbg_parse("name = %s, owner = %s, group = %s, mode = %#o", - dev.attr.name, dev.attr.owner, dev.attr.group, - dev.attr.mode); + dev.name, dev.owner, dev.group, + dev.mode); retval = add_dev(&dev); if (retval) { dbg("add_dev returned with error %d", retval); @@ -535,13 +535,13 @@ static int exec_callout(struct config_device *dev, char *value, int len) return retval; } -static int get_attr(struct sysfs_class_device *class_dev, struct device_attr *attr) +static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) { struct list_head *tmp; int retval = 0; int found; - attr->mode = 0; + udev->mode = 0; if (class_dev->sysdevice) { dbg_parse("class_dev->sysdevice->path = '%s'", class_dev->sysdevice->path); dbg_parse("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); @@ -620,19 +620,19 @@ label_found: continue; } - strcpy(attr->name, dev->attr.name); + strcpy(udev->name, dev->name); if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { temp = &class_dev->path[strlen(class_dev->path)-1]; - strcat(attr->name, temp); + strcat(udev->name, temp); } - if (dev->attr.mode != 0) { - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); } dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->sysfs_file, dev->sysfs_value, attr->name, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->sysfs_file, dev->sysfs_value, udev->name, + dev->owner, dev->group, dev->mode); if (class_dev_parent) sysfs_close_class_device(class_dev_parent); goto done; @@ -662,15 +662,15 @@ label_found: if (!found) continue; - strcpy(attr->name, dev->attr.name); - if (dev->attr.mode != 0) { - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); } dbg_parse("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->id, attr->name, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->id, udev->name, + dev->owner, dev->group, dev->mode); goto done; break; } @@ -698,15 +698,15 @@ label_found: if (!found) continue; - strcpy(attr->name, dev->attr.name); - if (dev->attr.mode != 0) { - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); } dbg_parse("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->place, attr->name, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->place, udev->name, + dev->owner, dev->group, dev->mode); goto done; break; } @@ -718,30 +718,30 @@ label_found: continue; if (strncmp(value, dev->id, sizeof(value)) != 0) continue; - strcpy(attr->name, dev->attr.name); - if (dev->attr.mode != 0) { - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); } dbg_parse("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->id, attr->name, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->id, udev->name, + dev->owner, dev->group, dev->mode); goto done; break; } case REPLACE: if (strcmp(dev->kernel_name, class_dev->name) != 0) continue; - strcpy(attr->name, dev->attr.name); - if (dev->attr.mode != 0) { - attr->mode = dev->attr.mode; - strcpy(attr->owner, dev->attr.owner); - strcpy(attr->group, dev->attr.group); + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); } dbg_parse("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->kernel_name, attr->name, - dev->attr.owner, dev->attr.group, dev->attr.mode); + dev->kernel_name, udev->name, + dev->owner, dev->group, dev->mode); goto done; break; case KERNEL_NAME: @@ -751,23 +751,23 @@ label_found: break; } } - strcpy(attr->name, class_dev->name); + strcpy(udev->name, class_dev->name); done: /* mode was never set above */ - if (!attr->mode) { - attr->mode = get_default_mode(class_dev); - attr->owner[0] = 0x00; - attr->group[0] = 0x00; + if (!udev->mode) { + udev->mode = get_default_mode(class_dev); + udev->owner[0] = 0x00; + udev->group[0] = 0x00; } return retval; } -int namedev_name_device(struct sysfs_class_device *class_dev, struct device_attr *attr) +int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev) { int retval; - retval = get_attr(class_dev, attr); + retval = get_attr(class_dev, dev); if (retval) dbg("get_attr failed"); diff --git a/namedev.h b/namedev.h index d5aaae202c..56e6a96c03 100644 --- a/namedev.h +++ b/namedev.h @@ -60,11 +60,14 @@ struct config_device { char exec_program[FILE_SIZE]; /* what to set the device to */ - struct device_attr attr; + char name[NAME_SIZE]; + char owner[OWNER_SIZE]; + char group[GROUP_SIZE]; + mode_t mode; }; extern int namedev_init(void); -extern int namedev_name_device(struct sysfs_class_device *class_dev, struct device_attr *attr); +extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev); #endif diff --git a/udev-add.c b/udev-add.c index 7d0bdadcb7..3b0e4ddf0e 100644 --- a/udev-add.c +++ b/udev-add.c @@ -161,7 +161,6 @@ int udev_add_device(char *path, char *subsystem) { struct sysfs_class_device *class_dev; struct udevice dev; - struct device_attr attr; int retval = -EINVAL; /* for now, the block layer is the only place where block devices are */ @@ -178,7 +177,7 @@ int udev_add_device(char *path, char *subsystem) if (class_dev == NULL) goto exit; - retval = namedev_name_device(class_dev, &attr); + retval = namedev_name_device(class_dev, &dev); if (retval) return retval; @@ -188,10 +187,10 @@ int udev_add_device(char *path, char *subsystem) goto exit; } - strcpy(dev.name, attr.name); - strcpy(dev.owner, attr.owner); - strcpy(dev.group, attr.group); - dev.mode = attr.mode; +// strcpy(dev.name, attr.name); +// strcpy(dev.owner, attr.owner); +// strcpy(dev.group, attr.group); +// dev.mode = attr.mode; retval = udevdb_add_dev(path, &dev); if (retval != 0) diff --git a/udev.h b/udev.h index 1f6e981cc2..cdf1af4fc2 100644 --- a/udev.h +++ b/udev.h @@ -60,13 +60,6 @@ extern int log_message (int level, const char *format, ...) #define OWNER_SIZE 30 #define GROUP_SIZE 30 -struct device_attr { - char name[NAME_SIZE]; - char owner[OWNER_SIZE]; - char group[GROUP_SIZE]; - mode_t mode; -}; - struct udevice { char name[NAME_SIZE]; char owner[OWNER_SIZE]; From 64455bfc69aa4c9a79bdfa9face9c4ecbdb5a8ed Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 01:12:40 -0700 Subject: [PATCH 0104/4284] [PATCH] fix LABEL bug for device files (not class files.) --- namedev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 6ed2415cdd..22ec6ace24 100644 --- a/namedev.c +++ b/namedev.c @@ -566,7 +566,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) /* look in the class device directory if present */ if (class_dev->sysdevice) { - tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); + tmpattr = sysfs_get_device_attr(class_dev->sysdevice, dev->sysfs_file); if (tmpattr) goto label_found; } @@ -599,7 +599,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) /* look in the class device directory if present */ if (class_dev_parent->sysdevice) { - tmpattr = sysfs_get_classdev_attr(class_dev_parent, dev->sysfs_file); + tmpattr = sysfs_get_device_attr(class_dev_parent->sysdevice, dev->sysfs_file); if (tmpattr) goto label_found; } From 562e8810163ace28ec6683b494e26bd173a81f58 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 01:14:59 -0700 Subject: [PATCH 0105/4284] [PATCH] regression tests starting to be added. --- test/label_test | 14 ++++++++++++++ test/label_test.config | 3 +++ test/sys/block/sda/dev | 1 + test/sys/block/sda/queue/iosched/antic_expire | 1 + test/sys/block/sda/queue/iosched/read_batch_expire | 1 + test/sys/block/sda/queue/iosched/read_expire | 1 + .../sys/block/sda/queue/iosched/write_batch_expire | 1 + test/sys/block/sda/queue/iosched/write_expire | 1 + test/sys/block/sda/queue/nr_requests | 1 + test/sys/block/sda/range | 1 + test/sys/block/sda/sda1/dev | 1 + test/sys/block/sda/sda1/size | 1 + test/sys/block/sda/sda1/start | 1 + test/sys/block/sda/sda1/stat | 1 + test/sys/block/sda/sda2/dev | 1 + test/sys/block/sda/sda2/size | 1 + test/sys/block/sda/sda2/start | 1 + test/sys/block/sda/sda2/stat | 1 + test/sys/block/sda/sda3/dev | 1 + test/sys/block/sda/sda3/size | 1 + test/sys/block/sda/sda3/start | 1 + test/sys/block/sda/sda3/stat | 1 + test/sys/block/sda/sda4/dev | 1 + test/sys/block/sda/sda4/size | 1 + test/sys/block/sda/sda4/start | 1 + test/sys/block/sda/sda4/stat | 1 + test/sys/block/sda/size | 1 + test/sys/block/sda/stat | 1 + .../pci0000:00/0000:00:1e.0/0000:02:05.0/class | 1 + .../pci0000:00/0000:00:1e.0/0000:02:05.0/device | 1 + .../0000:02:05.0/host0/0:0:0:0/device_blocked | 1 + .../0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/model | 1 + .../0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/online | 1 + .../0000:02:05.0/host0/0:0:0:0/queue_depth | 1 + .../0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/rev | 1 + .../0000:02:05.0/host0/0:0:0:0/scsi_level | 1 + .../0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/type | 1 + .../0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/vendor | 1 + .../pci0000:00/0000:00:1e.0/0000:02:05.0/irq | 1 + .../pci0000:00/0000:00:1e.0/0000:02:05.0/resource | 7 +++++++ .../0000:00:1e.0/0000:02:05.0/subsystem_device | 1 + .../0000:00:1e.0/0000:02:05.0/subsystem_vendor | 1 + .../pci0000:00/0000:00:1e.0/0000:02:05.0/vendor | 1 + test/sys/devices/pci0000:00/0000:00:1e.0/class | 1 + test/sys/devices/pci0000:00/0000:00:1e.0/device | 1 + test/sys/devices/pci0000:00/0000:00:1e.0/irq | 1 + test/sys/devices/pci0000:00/0000:00:1e.0/resource | 12 ++++++++++++ .../pci0000:00/0000:00:1e.0/subsystem_device | 1 + .../pci0000:00/0000:00:1e.0/subsystem_vendor | 1 + test/sys/devices/pci0000:00/0000:00:1e.0/vendor | 1 + 50 files changed, 82 insertions(+) create mode 100644 test/label_test create mode 100644 test/label_test.config create mode 100644 test/sys/block/sda/dev create mode 100644 test/sys/block/sda/queue/iosched/antic_expire create mode 100644 test/sys/block/sda/queue/iosched/read_batch_expire create mode 100644 test/sys/block/sda/queue/iosched/read_expire create mode 100644 test/sys/block/sda/queue/iosched/write_batch_expire create mode 100644 test/sys/block/sda/queue/iosched/write_expire create mode 100644 test/sys/block/sda/queue/nr_requests create mode 100644 test/sys/block/sda/range create mode 100644 test/sys/block/sda/sda1/dev create mode 100644 test/sys/block/sda/sda1/size create mode 100644 test/sys/block/sda/sda1/start create mode 100644 test/sys/block/sda/sda1/stat create mode 100644 test/sys/block/sda/sda2/dev create mode 100644 test/sys/block/sda/sda2/size create mode 100644 test/sys/block/sda/sda2/start create mode 100644 test/sys/block/sda/sda2/stat create mode 100644 test/sys/block/sda/sda3/dev create mode 100644 test/sys/block/sda/sda3/size create mode 100644 test/sys/block/sda/sda3/start create mode 100644 test/sys/block/sda/sda3/stat create mode 100644 test/sys/block/sda/sda4/dev create mode 100644 test/sys/block/sda/sda4/size create mode 100644 test/sys/block/sda/sda4/start create mode 100644 test/sys/block/sda/sda4/stat create mode 100644 test/sys/block/sda/size create mode 100644 test/sys/block/sda/stat create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/class create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/device create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/device_blocked create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/model create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/online create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/queue_depth create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/rev create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/scsi_level create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/type create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/vendor create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/irq create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/resource create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_device create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_vendor create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/vendor create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/class create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/device create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/irq create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/resource create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_device create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/vendor diff --git a/test/label_test b/test/label_test new file mode 100644 index 0000000000..f2208cbbdd --- /dev/null +++ b/test/label_test @@ -0,0 +1,14 @@ +#!/bin/bash + +export UDEV_TEST=yes +export UDEV_SYSFS_PATH=$PWD/sys/ +export UDEV_CONFIG_DIR=$PWD/ +export UDEV_ROOT=$PWD/udev/ +export UDEV_DB=udev.tdb +export UDEV_CONFIG_FILE=label_test.config +export UDEV_PERMISSION_FILE=udev.permissions + +export DEVPATH=block/sda +export ACTION=add + +../udev block diff --git a/test/label_test.config b/test/label_test.config new file mode 100644 index 0000000000..b317537bb6 --- /dev/null +++ b/test/label_test.config @@ -0,0 +1,3 @@ +# LABEL test +LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk" + diff --git a/test/sys/block/sda/dev b/test/sys/block/sda/dev new file mode 100644 index 0000000000..fae0a50572 --- /dev/null +++ b/test/sys/block/sda/dev @@ -0,0 +1 @@ +8:0 diff --git a/test/sys/block/sda/queue/iosched/antic_expire b/test/sys/block/sda/queue/iosched/antic_expire new file mode 100644 index 0000000000..1e8b314962 --- /dev/null +++ b/test/sys/block/sda/queue/iosched/antic_expire @@ -0,0 +1 @@ +6 diff --git a/test/sys/block/sda/queue/iosched/read_batch_expire b/test/sys/block/sda/queue/iosched/read_batch_expire new file mode 100644 index 0000000000..08839f6bb2 --- /dev/null +++ b/test/sys/block/sda/queue/iosched/read_batch_expire @@ -0,0 +1 @@ +200 diff --git a/test/sys/block/sda/queue/iosched/read_expire b/test/sys/block/sda/queue/iosched/read_expire new file mode 100644 index 0000000000..e373ee695f --- /dev/null +++ b/test/sys/block/sda/queue/iosched/read_expire @@ -0,0 +1 @@ +50 diff --git a/test/sys/block/sda/queue/iosched/write_batch_expire b/test/sys/block/sda/queue/iosched/write_batch_expire new file mode 100644 index 0000000000..e373ee695f --- /dev/null +++ b/test/sys/block/sda/queue/iosched/write_batch_expire @@ -0,0 +1 @@ +50 diff --git a/test/sys/block/sda/queue/iosched/write_expire b/test/sys/block/sda/queue/iosched/write_expire new file mode 100644 index 0000000000..08839f6bb2 --- /dev/null +++ b/test/sys/block/sda/queue/iosched/write_expire @@ -0,0 +1 @@ +200 diff --git a/test/sys/block/sda/queue/nr_requests b/test/sys/block/sda/queue/nr_requests new file mode 100644 index 0000000000..a949a93dfc --- /dev/null +++ b/test/sys/block/sda/queue/nr_requests @@ -0,0 +1 @@ +128 diff --git a/test/sys/block/sda/range b/test/sys/block/sda/range new file mode 100644 index 0000000000..b6a7d89c68 --- /dev/null +++ b/test/sys/block/sda/range @@ -0,0 +1 @@ +16 diff --git a/test/sys/block/sda/sda1/dev b/test/sys/block/sda/sda1/dev new file mode 100644 index 0000000000..92c4b9b088 --- /dev/null +++ b/test/sys/block/sda/sda1/dev @@ -0,0 +1 @@ +8:1 diff --git a/test/sys/block/sda/sda1/size b/test/sys/block/sda/sda1/size new file mode 100644 index 0000000000..f00a59241e --- /dev/null +++ b/test/sys/block/sda/sda1/size @@ -0,0 +1 @@ +1060227 diff --git a/test/sys/block/sda/sda1/start b/test/sys/block/sda/sda1/start new file mode 100644 index 0000000000..4b9026d8e2 --- /dev/null +++ b/test/sys/block/sda/sda1/start @@ -0,0 +1 @@ +63 diff --git a/test/sys/block/sda/sda1/stat b/test/sys/block/sda/sda1/stat new file mode 100644 index 0000000000..199ce7330b --- /dev/null +++ b/test/sys/block/sda/sda1/stat @@ -0,0 +1 @@ + 50 400 103 824 diff --git a/test/sys/block/sda/sda2/dev b/test/sys/block/sda/sda2/dev new file mode 100644 index 0000000000..9799a2674a --- /dev/null +++ b/test/sys/block/sda/sda2/dev @@ -0,0 +1 @@ +8:2 diff --git a/test/sys/block/sda/sda2/size b/test/sys/block/sda/sda2/size new file mode 100644 index 0000000000..80483ab968 --- /dev/null +++ b/test/sys/block/sda/sda2/size @@ -0,0 +1 @@ +112455 diff --git a/test/sys/block/sda/sda2/start b/test/sys/block/sda/sda2/start new file mode 100644 index 0000000000..3a4bf076fc --- /dev/null +++ b/test/sys/block/sda/sda2/start @@ -0,0 +1 @@ +1060290 diff --git a/test/sys/block/sda/sda2/stat b/test/sys/block/sda/sda2/stat new file mode 100644 index 0000000000..c06b749cd1 --- /dev/null +++ b/test/sys/block/sda/sda2/stat @@ -0,0 +1 @@ + 342 500 15 30 diff --git a/test/sys/block/sda/sda3/dev b/test/sys/block/sda/sda3/dev new file mode 100644 index 0000000000..44ccff41b0 --- /dev/null +++ b/test/sys/block/sda/sda3/dev @@ -0,0 +1 @@ +8:3 diff --git a/test/sys/block/sda/sda3/size b/test/sys/block/sda/sda3/size new file mode 100644 index 0000000000..1373b38f8d --- /dev/null +++ b/test/sys/block/sda/sda3/size @@ -0,0 +1 @@ +20482875 diff --git a/test/sys/block/sda/sda3/start b/test/sys/block/sda/sda3/start new file mode 100644 index 0000000000..cab5c33336 --- /dev/null +++ b/test/sys/block/sda/sda3/start @@ -0,0 +1 @@ +1172745 diff --git a/test/sys/block/sda/sda3/stat b/test/sys/block/sda/sda3/stat new file mode 100644 index 0000000000..82fb1463a1 --- /dev/null +++ b/test/sys/block/sda/sda3/stat @@ -0,0 +1 @@ + 415052 6872874 669740 5357920 diff --git a/test/sys/block/sda/sda4/dev b/test/sys/block/sda/sda4/dev new file mode 100644 index 0000000000..aab3fc56e1 --- /dev/null +++ b/test/sys/block/sda/sda4/dev @@ -0,0 +1 @@ +8:4 diff --git a/test/sys/block/sda/sda4/size b/test/sys/block/sda/sda4/size new file mode 100644 index 0000000000..062619c44b --- /dev/null +++ b/test/sys/block/sda/sda4/size @@ -0,0 +1 @@ +49432005 diff --git a/test/sys/block/sda/sda4/start b/test/sys/block/sda/sda4/start new file mode 100644 index 0000000000..b65020c801 --- /dev/null +++ b/test/sys/block/sda/sda4/start @@ -0,0 +1 @@ +21655620 diff --git a/test/sys/block/sda/sda4/stat b/test/sys/block/sda/sda4/stat new file mode 100644 index 0000000000..3e7b7ad75c --- /dev/null +++ b/test/sys/block/sda/sda4/stat @@ -0,0 +1 @@ + 642730 9095506 275223 2201728 diff --git a/test/sys/block/sda/size b/test/sys/block/sda/size new file mode 100644 index 0000000000..88da032f61 --- /dev/null +++ b/test/sys/block/sda/size @@ -0,0 +1 @@ +71096640 diff --git a/test/sys/block/sda/stat b/test/sys/block/sda/stat new file mode 100644 index 0000000000..b93c7d4ac4 --- /dev/null +++ b/test/sys/block/sda/stat @@ -0,0 +1 @@ + 1043906 19157 16008400 4313104 317001 625161 7560502 48785829 0 3846686 53153390 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/class b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/class new file mode 100644 index 0000000000..145a550829 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/class @@ -0,0 +1 @@ +0x010000 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/device b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/device new file mode 100644 index 0000000000..c271a13ff6 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/device @@ -0,0 +1 @@ +0x008f diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/device_blocked b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/device_blocked new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/device_blocked @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/model b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/model new file mode 100644 index 0000000000..392039b199 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/model @@ -0,0 +1 @@ +ST336605LW !# diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/online b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/online new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/online @@ -0,0 +1 @@ +1 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/queue_depth b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/queue_depth new file mode 100644 index 0000000000..f5c89552bd --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/queue_depth @@ -0,0 +1 @@ +32 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/rev b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/rev new file mode 100644 index 0000000000..65dd514497 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/rev @@ -0,0 +1 @@ +B245 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/scsi_level b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/scsi_level new file mode 100644 index 0000000000..b8626c4cff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/scsi_level @@ -0,0 +1 @@ +4 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/type b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/type new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/type @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/vendor b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/vendor new file mode 100644 index 0000000000..d87b2a5c0b --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/vendor @@ -0,0 +1 @@ +IBM-ESXS diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/irq b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/irq new file mode 100644 index 0000000000..2bd5a0a98a --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/irq @@ -0,0 +1 @@ +22 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/resource b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/resource new file mode 100644 index 0000000000..2a3d654b9a --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_device b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_device new file mode 100644 index 0000000000..8419b39dd6 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_device @@ -0,0 +1 @@ +0x0205 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_vendor b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_vendor new file mode 100644 index 0000000000..7369ccd585 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/subsystem_vendor @@ -0,0 +1 @@ +0x1014 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/vendor b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/vendor new file mode 100644 index 0000000000..a5d57044c8 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/vendor @@ -0,0 +1 @@ +0x9005 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/class b/test/sys/devices/pci0000:00/0000:00:1e.0/class new file mode 100644 index 0000000000..8b40e6a7b7 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/class @@ -0,0 +1 @@ +0x060400 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/device b/test/sys/devices/pci0000:00/0000:00:1e.0/device new file mode 100644 index 0000000000..9fe3927fbb --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/device @@ -0,0 +1 @@ +0x244e diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/irq b/test/sys/devices/pci0000:00/0000:00:1e.0/irq new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/irq @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/resource b/test/sys/devices/pci0000:00/0000:00:1e.0/resource new file mode 100644 index 0000000000..f8f56abf32 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_device b/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_device new file mode 100644 index 0000000000..aa01954cc8 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_device @@ -0,0 +1 @@ +0x0000 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor b/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor new file mode 100644 index 0000000000..aa01954cc8 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/subsystem_vendor @@ -0,0 +1 @@ +0x0000 diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/vendor b/test/sys/devices/pci0000:00/0000:00:1e.0/vendor new file mode 100644 index 0000000000..ce6dc4da35 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/vendor @@ -0,0 +1 @@ +0x8086 From daf0bafa81db60954e20ff7199c8a24ae00d2b67 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 01:15:20 -0700 Subject: [PATCH 0106/4284] [PATCH] hm, makefile bug with so many files... will fix later... --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a5c00b7191..c7d0391473 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,7 @@ clean: $(MAKE) -C libsysfs clean $(MAKE) -C tdb clean -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | sort ) +#DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . release: $(DISTFILES) clean From 6c0eae77a1443c51a0c089f4d4053ffff13666f5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 01:32:07 -0700 Subject: [PATCH 0107/4284] [PATCH] makefile fix for now. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c7d0391473..ea0dc10c28 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,7 @@ clean: $(MAKE) -C libsysfs clean $(MAKE) -C tdb clean -#DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | sort ) +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . release: $(DISTFILES) clean From a41a0e28c2ba0abf99b5e7ea17645ae0e4f05758 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 18:37:40 -0700 Subject: [PATCH 0108/4284] [PATCH] added klibc version 0.82 (cvs tree) to the udev tree. Not hooked up to the build yet. --- klibc/MCONFIG | 41 + klibc/Makefile | 7 +- klibc/README | 16 + klibc/klibc/CAVEATS | 51 + klibc/klibc/LICENSE | 73 + klibc/klibc/MCONFIG | 49 + klibc/klibc/Makefile | 135 + klibc/klibc/README | 57 + klibc/klibc/SOCKETCALLS | 21 + klibc/klibc/SYSCALLS | 146 + klibc/klibc/__shared_init.c | 56 + klibc/klibc/__signal.c | 22 + klibc/klibc/__static_init.c | 40 + klibc/klibc/abort.c | 19 + klibc/klibc/alarm.c | 29 + klibc/klibc/arch/README | 67 + klibc/klibc/arch/alpha/MCONFIG | 17 + klibc/klibc/arch/alpha/Makefile.inc | 93 + klibc/klibc/arch/alpha/README-gcc | 23 + klibc/klibc/arch/alpha/crt0.S | 21 + klibc/klibc/arch/alpha/divide.c | 57 + .../arch/alpha/include/klibc/archsetjmp.h | 33 + .../klibc/arch/alpha/include/klibc/archsys.h | 53 + klibc/klibc/arch/alpha/include/machine/asm.h | 44 + klibc/klibc/arch/alpha/pipe.c | 28 + klibc/klibc/arch/alpha/setjmp.S | 77 + klibc/klibc/arch/arm/MCONFIG | 26 + klibc/klibc/arch/arm/Makefile.inc | 31 + klibc/klibc/arch/arm/crt0.S | 25 + .../klibc/arch/arm/include/klibc/archsetjmp.h | 14 + klibc/klibc/arch/arm/include/klibc/archsys.h | 12 + klibc/klibc/arch/arm/setjmp-arm.S | 40 + klibc/klibc/arch/arm/setjmp-thumb.S | 58 + klibc/klibc/arch/cris/MCONFIG | 11 + klibc/klibc/arch/cris/Makefile.inc | 10 + klibc/klibc/arch/cris/include/klibc/archsys.h | 12 + klibc/klibc/arch/i386/MCONFIG | 32 + klibc/klibc/arch/i386/Makefile.inc | 27 + klibc/klibc/arch/i386/crt0.S | 33 + klibc/klibc/arch/i386/exits.S | 45 + .../arch/i386/include/klibc/archsetjmp.h | 19 + klibc/klibc/arch/i386/include/klibc/archsys.h | 96 + klibc/klibc/arch/i386/include/klibc/diverr.h | 16 + klibc/klibc/arch/i386/libgcc/__ashldi3.S | 29 + klibc/klibc/arch/i386/libgcc/__ashrdi3.S | 29 + klibc/klibc/arch/i386/libgcc/__lshrdi3.S | 29 + klibc/klibc/arch/i386/libgcc/__muldi3.S | 34 + klibc/klibc/arch/i386/libgcc/__negdi2.S | 21 + klibc/klibc/arch/i386/setjmp.S | 58 + klibc/klibc/arch/i386/socketcall.S | 38 + klibc/klibc/arch/ia64/MCONFIG | 11 + klibc/klibc/arch/ia64/Makefile.inc | 10 + klibc/klibc/arch/ia64/include/klibc/archsys.h | 12 + klibc/klibc/arch/m68k/MCONFIG | 11 + klibc/klibc/arch/m68k/Makefile.inc | 10 + klibc/klibc/arch/m68k/include/klibc/archsys.h | 12 + klibc/klibc/arch/mips/MCONFIG | 18 + klibc/klibc/arch/mips/Makefile.inc | 24 + klibc/klibc/arch/mips/crt0.S | 25 + .../arch/mips/include/klibc/archsetjmp.h | 39 + klibc/klibc/arch/mips/include/klibc/archsys.h | 12 + klibc/klibc/arch/mips/include/machine/asm.h | 11 + klibc/klibc/arch/mips/include/sgidefs.h | 20 + klibc/klibc/arch/mips/pipe.S | 16 + klibc/klibc/arch/mips/setjmp.S | 82 + klibc/klibc/arch/mips/vfork.S | 19 + klibc/klibc/arch/mips64/MCONFIG | 11 + klibc/klibc/arch/mips64/Makefile.inc | 10 + .../klibc/arch/mips64/include/klibc/archsys.h | 12 + klibc/klibc/arch/parisc/MCONFIG | 11 + klibc/klibc/arch/parisc/Makefile.inc | 10 + .../klibc/arch/parisc/include/klibc/archsys.h | 12 + klibc/klibc/arch/ppc/MCONFIG | 11 + klibc/klibc/arch/ppc/Makefile.inc | 15 + klibc/klibc/arch/ppc/crt0.S | 29 + .../klibc/arch/ppc/include/klibc/archsetjmp.h | 36 + klibc/klibc/arch/ppc/include/klibc/archsys.h | 55 + klibc/klibc/arch/ppc/setjmp.S | 35 + klibc/klibc/arch/ppc64/MCONFIG | 11 + klibc/klibc/arch/ppc64/Makefile.inc | 10 + klibc/klibc/arch/ppc64/crt0.S | 38 + .../klibc/arch/ppc64/include/klibc/archsys.h | 52 + klibc/klibc/arch/s390/MCONFIG | 13 + klibc/klibc/arch/s390/Makefile.inc | 16 + klibc/klibc/arch/s390/crt0.S | 25 + .../arch/s390/include/klibc/archsetjmp.h | 15 + klibc/klibc/arch/s390/include/klibc/archsys.h | 41 + klibc/klibc/arch/s390/setjmp.S | 32 + klibc/klibc/arch/s390x/MCONFIG | 13 + klibc/klibc/arch/s390x/Makefile.inc | 16 + klibc/klibc/arch/s390x/crt0.S | 21 + .../arch/s390x/include/klibc/archsetjmp.h | 15 + .../klibc/arch/s390x/include/klibc/archsys.h | 41 + klibc/klibc/arch/s390x/setjmp.S | 36 + klibc/klibc/arch/sh/MCONFIG | 19 + klibc/klibc/arch/sh/Makefile.inc | 14 + klibc/klibc/arch/sh/crt0.S | 28 + .../klibc/arch/sh/include/klibc/archsetjmp.h | 22 + klibc/klibc/arch/sh/include/klibc/archsys.h | 12 + klibc/klibc/arch/sh/setjmp.S | 65 + klibc/klibc/arch/sparc/MCONFIG | 18 + klibc/klibc/arch/sparc/Makefile.inc | 44 + klibc/klibc/arch/sparc/crt0.S | 2 + klibc/klibc/arch/sparc/crt0i.S | 100 + klibc/klibc/arch/sparc/divrem.m4 | 276 ++ .../arch/sparc/include/klibc/archsetjmp.h | 16 + .../klibc/arch/sparc/include/klibc/archsys.h | 65 + klibc/klibc/arch/sparc/include/machine/asm.h | 192 + .../klibc/arch/sparc/include/machine/frame.h | 138 + klibc/klibc/arch/sparc/include/machine/trap.h | 141 + klibc/klibc/arch/sparc/setjmp.S | 38 + klibc/klibc/arch/sparc/smul.S | 160 + klibc/klibc/arch/sparc/umul.S | 193 + klibc/klibc/arch/sparc64/MCONFIG | 21 + klibc/klibc/arch/sparc64/Makefile.inc | 13 + klibc/klibc/arch/sparc64/crt0.S | 2 + .../arch/sparc64/include/klibc/archsetjmp.h | 16 + .../arch/sparc64/include/klibc/archsys.h | 157 + klibc/klibc/arch/sparc64/setjmp.S | 55 + klibc/klibc/arch/x86_64/MCONFIG | 16 + klibc/klibc/arch/x86_64/Makefile.inc | 16 + klibc/klibc/arch/x86_64/crt0.S | 22 + klibc/klibc/arch/x86_64/exits.S | 35 + .../arch/x86_64/include/klibc/archsetjmp.h | 21 + .../klibc/arch/x86_64/include/klibc/archsys.h | 32 + klibc/klibc/arch/x86_64/setjmp.S | 54 + klibc/klibc/assert.c | 13 + klibc/klibc/atexit.c | 10 + klibc/klibc/atexit.h | 19 + klibc/klibc/atoi.c | 3 + klibc/klibc/atol.c | 3 + klibc/klibc/atoll.c | 3 + klibc/klibc/atox.c | 14 + klibc/klibc/brk.c | 24 + klibc/klibc/bsd_signal.c | 11 + klibc/klibc/calloc.c | 21 + klibc/klibc/closelog.c | 18 + klibc/klibc/creat.c | 12 + klibc/klibc/ctypes.c | 281 ++ klibc/klibc/exec_l.c | 57 + klibc/klibc/execl.c | 8 + klibc/klibc/execle.c | 8 + klibc/klibc/execlp.c | 8 + klibc/klibc/execlpe.c | 8 + klibc/klibc/execv.c | 13 + klibc/klibc/execvp.c | 13 + klibc/klibc/execvpe.c | 73 + klibc/klibc/exitc.c | 36 + klibc/klibc/fdatasync.c | 15 + klibc/klibc/fgetc.c | 20 + klibc/klibc/fgets.c | 33 + klibc/klibc/fopen.c | 46 + klibc/klibc/fork.c | 29 + klibc/klibc/fprintf.c | 19 + klibc/klibc/fputc.c | 14 + klibc/klibc/fputs.c | 15 + klibc/klibc/fread.c | 35 + klibc/klibc/fread2.c | 13 + klibc/klibc/fwrite.c | 35 + klibc/klibc/fwrite2.c | 13 + klibc/klibc/getcwd.c | 15 + klibc/klibc/getdomainname.c | 25 + klibc/klibc/getenv.c | 22 + klibc/klibc/gethostname.c | 25 + klibc/klibc/getopt.c | 74 + klibc/klibc/getpriority.c | 25 + klibc/klibc/globals.c | 10 + klibc/klibc/include/alloca.h | 13 + klibc/klibc/include/arpa/inet.h | 24 + klibc/klibc/include/assert.h | 22 + klibc/klibc/include/bits32/bitsize/limits.h | 14 + klibc/klibc/include/bits32/bitsize/stddef.h | 18 + klibc/klibc/include/bits32/bitsize/stdint.h | 34 + .../include/bits32/bitsize/stdintconst.h | 18 + .../include/bits32/bitsize/stdintlimits.h | 22 + klibc/klibc/include/bits64/bitsize/limits.h | 14 + klibc/klibc/include/bits64/bitsize/stddef.h | 13 + klibc/klibc/include/bits64/bitsize/stdint.h | 36 + .../include/bits64/bitsize/stdintconst.h | 18 + .../include/bits64/bitsize/stdintlimits.h | 22 + klibc/klibc/include/ctype.h | 117 + klibc/klibc/include/dirent.h | 20 + klibc/klibc/include/elf.h | 12 + klibc/klibc/include/endian.h | 41 + klibc/klibc/include/errno.h | 8 + klibc/klibc/include/fcntl.h | 11 + klibc/klibc/include/grp.h | 13 + klibc/klibc/include/inttypes.h | 226 + klibc/klibc/include/klibc/compiler.h | 61 + klibc/klibc/include/klibc/diverr.h | 16 + klibc/klibc/include/klibc/extern.h | 14 + klibc/klibc/include/limits.h | 40 + klibc/klibc/include/net/if.h | 1 + klibc/klibc/include/net/if_arp.h | 1 + klibc/klibc/include/net/if_ether.h | 1 + klibc/klibc/include/net/if_packet.h | 1 + klibc/klibc/include/netinet/in.h | 33 + klibc/klibc/include/netinet/in6.h | 10 + klibc/klibc/include/netinet/ip.h | 13 + klibc/klibc/include/netinet/tcp.h | 11 + klibc/klibc/include/netinet/udp.h | 19 + klibc/klibc/include/poll.h | 16 + klibc/klibc/include/sched.h | 23 + klibc/klibc/include/setjmp.h | 43 + klibc/klibc/include/signal.h | 72 + klibc/klibc/include/stdarg.h | 14 + klibc/klibc/include/stddef.h | 24 + klibc/klibc/include/stdint.h | 113 + klibc/klibc/include/stdio.h | 109 + klibc/klibc/include/stdlib.h | 94 + klibc/klibc/include/string.h | 37 + klibc/klibc/include/sys/dirent.h | 13 + klibc/klibc/include/sys/fsuid.h | 14 + klibc/klibc/include/sys/ioctl.h | 14 + klibc/klibc/include/sys/klog.h | 24 + klibc/klibc/include/sys/mman.h | 21 + klibc/klibc/include/sys/module.h | 158 + klibc/klibc/include/sys/mount.h | 55 + klibc/klibc/include/sys/param.h | 11 + klibc/klibc/include/sys/reboot.h | 25 + klibc/klibc/include/sys/resource.h | 15 + klibc/klibc/include/sys/select.h | 13 + klibc/klibc/include/sys/socket.h | 50 + klibc/klibc/include/sys/socketcalls.h | 28 + klibc/klibc/include/sys/stat.h | 23 + klibc/klibc/include/sys/syscall.h | 15 + klibc/klibc/include/sys/time.h | 16 + klibc/klibc/include/sys/times.h | 14 + klibc/klibc/include/sys/types.h | 127 + klibc/klibc/include/sys/uio.h | 15 + klibc/klibc/include/sys/utime.h | 10 + klibc/klibc/include/sys/utsname.h | 23 + klibc/klibc/include/sys/vfs.h | 14 + klibc/klibc/include/sys/wait.h | 19 + klibc/klibc/include/syslog.h | 53 + klibc/klibc/include/termios.h | 86 + klibc/klibc/include/time.h | 14 + klibc/klibc/include/unistd.h | 111 + klibc/klibc/include/utime.h | 15 + klibc/klibc/inet/bindresvport.c | 48 + klibc/klibc/inet/inet_addr.c | 14 + klibc/klibc/inet/inet_aton.c | 23 + klibc/klibc/inet/inet_ntoa.c | 19 + klibc/klibc/inet/inet_ntop.c | 52 + klibc/klibc/inet/inet_pton.c | 74 + klibc/klibc/interp.S | 11 + klibc/klibc/isatty.c | 21 + klibc/klibc/libgcc/__divdi3.c | 29 + klibc/klibc/libgcc/__divsi3.c | 29 + klibc/klibc/libgcc/__moddi3.c | 29 + klibc/klibc/libgcc/__modsi3.c | 29 + klibc/klibc/libgcc/__udivdi3.c | 13 + klibc/klibc/libgcc/__udivmoddi4.c | 32 + klibc/klibc/libgcc/__udivmodsi4.c | 32 + klibc/klibc/libgcc/__udivsi3.c | 13 + klibc/klibc/libgcc/__umoddi3.c | 16 + klibc/klibc/libgcc/__umodsi3.c | 16 + klibc/klibc/llseek.c | 34 + klibc/klibc/lrand48.c | 42 + klibc/klibc/makeerrlist.pl | 80 + klibc/klibc/malloc.c | 192 + klibc/klibc/malloc.h | 51 + klibc/klibc/memccpy.c | 23 + klibc/klibc/memchr.c | 18 + klibc/klibc/memcmp.c | 19 + klibc/klibc/memcpy.c | 29 + klibc/klibc/memmem.c | 44 + klibc/klibc/memmove.c | 34 + klibc/klibc/memset.c | 30 + klibc/klibc/memswap.c | 23 + klibc/klibc/mmap.c | 51 + klibc/klibc/nice.c | 22 + klibc/klibc/onexit.c | 39 + klibc/klibc/pause.c | 21 + klibc/klibc/perror.c | 12 + klibc/klibc/printf.c | 19 + klibc/klibc/pty.c | 31 + klibc/klibc/puts.c | 13 + klibc/klibc/qsort.c | 42 + klibc/klibc/raise.c | 11 + klibc/klibc/readdir.c | 66 + klibc/klibc/realloc.c | 49 + klibc/klibc/reboot.c | 15 + klibc/klibc/recv.c | 11 + klibc/klibc/sbrk.c | 23 + klibc/klibc/seed48.c | 19 + klibc/klibc/select.c | 9 + klibc/klibc/send.c | 11 + klibc/klibc/setegid.c | 10 + klibc/klibc/setenv.c | 124 + klibc/klibc/seteuid.c | 10 + klibc/klibc/setpgrp.c | 10 + klibc/klibc/setresgid.c | 29 + klibc/klibc/setresuid.c | 30 + klibc/klibc/sha1hash.c | 317 ++ klibc/klibc/sigaction.c | 19 + klibc/klibc/siglist.c | 115 + klibc/klibc/siglongjmp.c | 16 + klibc/klibc/signal.c | 11 + klibc/klibc/sigpending.c | 19 + klibc/klibc/sigprocmask.c | 19 + klibc/klibc/sigsuspend.c | 19 + klibc/klibc/sleep.c | 20 + klibc/klibc/snprintf.c | 16 + klibc/klibc/socketcalls.pl | 71 + klibc/klibc/socketcommon.h | 25 + klibc/klibc/sprintf.c | 18 + klibc/klibc/srand48.c | 16 + klibc/klibc/sscanf.c | 17 + klibc/klibc/strcat.c | 11 + klibc/klibc/strchr.c | 16 + klibc/klibc/strcmp.c | 20 + klibc/klibc/strcpy.c | 20 + klibc/klibc/strdup.c | 17 + klibc/klibc/strerror.c | 25 + klibc/klibc/strlen.c | 14 + klibc/klibc/strncat.c | 11 + klibc/klibc/strncmp.c | 20 + klibc/klibc/strncpy.c | 22 + klibc/klibc/strntoimax.c | 13 + klibc/klibc/strntoumax.c | 75 + klibc/klibc/strrchr.c | 18 + klibc/klibc/strsep.c | 21 + klibc/klibc/strspn.c | 67 + klibc/klibc/strstr.c | 10 + klibc/klibc/strtoimax.c | 3 + klibc/klibc/strtok.c | 16 + klibc/klibc/strtol.c | 3 + klibc/klibc/strtoll.c | 3 + klibc/klibc/strtoul.c | 3 + klibc/klibc/strtoull.c | 3 + klibc/klibc/strtoumax.c | 3 + klibc/klibc/strtox.c | 13 + klibc/klibc/syscalls.pl | 81 + klibc/klibc/syscommon.h | 29 + klibc/klibc/syslog.c | 74 + klibc/klibc/system.c | 61 + klibc/klibc/tests/getenvtest.c | 26 + klibc/klibc/tests/getopttest.c | 31 + klibc/klibc/tests/hello.c | 7 + klibc/klibc/tests/idtest.c | 14 + klibc/klibc/tests/malloctest.c | 4145 +++++++++++++++++ klibc/klibc/tests/memstrtest.c | 29 + klibc/klibc/tests/microhello.c | 9 + klibc/klibc/tests/minihello.c | 7 + klibc/klibc/tests/minips.c | 452 ++ klibc/klibc/tests/nfs_no_rpc.c | 538 +++ klibc/klibc/tests/setjmptest.c | 36 + klibc/klibc/tests/testrand48.c | 19 + klibc/klibc/tests/testvsnp.c | 115 + klibc/klibc/time.c | 27 + klibc/klibc/umount.c | 12 + klibc/klibc/unsetenv.c | 40 + klibc/klibc/usleep.c | 15 + klibc/klibc/utime.c | 30 + klibc/klibc/vfprintf.c | 26 + klibc/klibc/vprintf.c | 11 + klibc/klibc/vsnprintf.c | 433 ++ klibc/klibc/vsprintf.c | 11 + klibc/klibc/vsscanf.c | 365 ++ klibc/klibc/wait.c | 12 + klibc/klibc/wait3.c | 12 + klibc/klibc/waitpid.c | 12 + klibc/version | 1 + 364 files changed, 18233 insertions(+), 2 deletions(-) create mode 100644 klibc/MCONFIG create mode 100644 klibc/README create mode 100644 klibc/klibc/CAVEATS create mode 100644 klibc/klibc/LICENSE create mode 100644 klibc/klibc/MCONFIG create mode 100644 klibc/klibc/Makefile create mode 100644 klibc/klibc/README create mode 100644 klibc/klibc/SOCKETCALLS create mode 100644 klibc/klibc/SYSCALLS create mode 100644 klibc/klibc/__shared_init.c create mode 100644 klibc/klibc/__signal.c create mode 100644 klibc/klibc/__static_init.c create mode 100644 klibc/klibc/abort.c create mode 100644 klibc/klibc/alarm.c create mode 100644 klibc/klibc/arch/README create mode 100644 klibc/klibc/arch/alpha/MCONFIG create mode 100644 klibc/klibc/arch/alpha/Makefile.inc create mode 100644 klibc/klibc/arch/alpha/README-gcc create mode 100644 klibc/klibc/arch/alpha/crt0.S create mode 100644 klibc/klibc/arch/alpha/divide.c create mode 100644 klibc/klibc/arch/alpha/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/alpha/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/alpha/include/machine/asm.h create mode 100644 klibc/klibc/arch/alpha/pipe.c create mode 100644 klibc/klibc/arch/alpha/setjmp.S create mode 100644 klibc/klibc/arch/arm/MCONFIG create mode 100644 klibc/klibc/arch/arm/Makefile.inc create mode 100644 klibc/klibc/arch/arm/crt0.S create mode 100644 klibc/klibc/arch/arm/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/arm/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/arm/setjmp-arm.S create mode 100644 klibc/klibc/arch/arm/setjmp-thumb.S create mode 100644 klibc/klibc/arch/cris/MCONFIG create mode 100644 klibc/klibc/arch/cris/Makefile.inc create mode 100644 klibc/klibc/arch/cris/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/i386/MCONFIG create mode 100644 klibc/klibc/arch/i386/Makefile.inc create mode 100644 klibc/klibc/arch/i386/crt0.S create mode 100644 klibc/klibc/arch/i386/exits.S create mode 100644 klibc/klibc/arch/i386/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/i386/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/i386/include/klibc/diverr.h create mode 100644 klibc/klibc/arch/i386/libgcc/__ashldi3.S create mode 100644 klibc/klibc/arch/i386/libgcc/__ashrdi3.S create mode 100644 klibc/klibc/arch/i386/libgcc/__lshrdi3.S create mode 100644 klibc/klibc/arch/i386/libgcc/__muldi3.S create mode 100644 klibc/klibc/arch/i386/libgcc/__negdi2.S create mode 100644 klibc/klibc/arch/i386/setjmp.S create mode 100644 klibc/klibc/arch/i386/socketcall.S create mode 100644 klibc/klibc/arch/ia64/MCONFIG create mode 100644 klibc/klibc/arch/ia64/Makefile.inc create mode 100644 klibc/klibc/arch/ia64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/m68k/MCONFIG create mode 100644 klibc/klibc/arch/m68k/Makefile.inc create mode 100644 klibc/klibc/arch/m68k/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/mips/MCONFIG create mode 100644 klibc/klibc/arch/mips/Makefile.inc create mode 100644 klibc/klibc/arch/mips/crt0.S create mode 100644 klibc/klibc/arch/mips/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/mips/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/mips/include/machine/asm.h create mode 100644 klibc/klibc/arch/mips/include/sgidefs.h create mode 100644 klibc/klibc/arch/mips/pipe.S create mode 100644 klibc/klibc/arch/mips/setjmp.S create mode 100644 klibc/klibc/arch/mips/vfork.S create mode 100644 klibc/klibc/arch/mips64/MCONFIG create mode 100644 klibc/klibc/arch/mips64/Makefile.inc create mode 100644 klibc/klibc/arch/mips64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/parisc/MCONFIG create mode 100644 klibc/klibc/arch/parisc/Makefile.inc create mode 100644 klibc/klibc/arch/parisc/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/ppc/MCONFIG create mode 100644 klibc/klibc/arch/ppc/Makefile.inc create mode 100644 klibc/klibc/arch/ppc/crt0.S create mode 100644 klibc/klibc/arch/ppc/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/ppc/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/ppc/setjmp.S create mode 100644 klibc/klibc/arch/ppc64/MCONFIG create mode 100644 klibc/klibc/arch/ppc64/Makefile.inc create mode 100644 klibc/klibc/arch/ppc64/crt0.S create mode 100644 klibc/klibc/arch/ppc64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/s390/MCONFIG create mode 100644 klibc/klibc/arch/s390/Makefile.inc create mode 100644 klibc/klibc/arch/s390/crt0.S create mode 100644 klibc/klibc/arch/s390/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/s390/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/s390/setjmp.S create mode 100644 klibc/klibc/arch/s390x/MCONFIG create mode 100644 klibc/klibc/arch/s390x/Makefile.inc create mode 100644 klibc/klibc/arch/s390x/crt0.S create mode 100644 klibc/klibc/arch/s390x/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/s390x/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/s390x/setjmp.S create mode 100644 klibc/klibc/arch/sh/MCONFIG create mode 100644 klibc/klibc/arch/sh/Makefile.inc create mode 100644 klibc/klibc/arch/sh/crt0.S create mode 100644 klibc/klibc/arch/sh/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/sh/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/sh/setjmp.S create mode 100644 klibc/klibc/arch/sparc/MCONFIG create mode 100644 klibc/klibc/arch/sparc/Makefile.inc create mode 100644 klibc/klibc/arch/sparc/crt0.S create mode 100644 klibc/klibc/arch/sparc/crt0i.S create mode 100644 klibc/klibc/arch/sparc/divrem.m4 create mode 100644 klibc/klibc/arch/sparc/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/sparc/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/sparc/include/machine/asm.h create mode 100644 klibc/klibc/arch/sparc/include/machine/frame.h create mode 100644 klibc/klibc/arch/sparc/include/machine/trap.h create mode 100644 klibc/klibc/arch/sparc/setjmp.S create mode 100644 klibc/klibc/arch/sparc/smul.S create mode 100644 klibc/klibc/arch/sparc/umul.S create mode 100644 klibc/klibc/arch/sparc64/MCONFIG create mode 100644 klibc/klibc/arch/sparc64/Makefile.inc create mode 100644 klibc/klibc/arch/sparc64/crt0.S create mode 100644 klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/sparc64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/sparc64/setjmp.S create mode 100644 klibc/klibc/arch/x86_64/MCONFIG create mode 100644 klibc/klibc/arch/x86_64/Makefile.inc create mode 100644 klibc/klibc/arch/x86_64/crt0.S create mode 100644 klibc/klibc/arch/x86_64/exits.S create mode 100644 klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/x86_64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/x86_64/setjmp.S create mode 100644 klibc/klibc/assert.c create mode 100644 klibc/klibc/atexit.c create mode 100644 klibc/klibc/atexit.h create mode 100644 klibc/klibc/atoi.c create mode 100644 klibc/klibc/atol.c create mode 100644 klibc/klibc/atoll.c create mode 100644 klibc/klibc/atox.c create mode 100644 klibc/klibc/brk.c create mode 100644 klibc/klibc/bsd_signal.c create mode 100644 klibc/klibc/calloc.c create mode 100644 klibc/klibc/closelog.c create mode 100644 klibc/klibc/creat.c create mode 100644 klibc/klibc/ctypes.c create mode 100644 klibc/klibc/exec_l.c create mode 100644 klibc/klibc/execl.c create mode 100644 klibc/klibc/execle.c create mode 100644 klibc/klibc/execlp.c create mode 100644 klibc/klibc/execlpe.c create mode 100644 klibc/klibc/execv.c create mode 100644 klibc/klibc/execvp.c create mode 100644 klibc/klibc/execvpe.c create mode 100644 klibc/klibc/exitc.c create mode 100644 klibc/klibc/fdatasync.c create mode 100644 klibc/klibc/fgetc.c create mode 100644 klibc/klibc/fgets.c create mode 100644 klibc/klibc/fopen.c create mode 100644 klibc/klibc/fork.c create mode 100644 klibc/klibc/fprintf.c create mode 100644 klibc/klibc/fputc.c create mode 100644 klibc/klibc/fputs.c create mode 100644 klibc/klibc/fread.c create mode 100644 klibc/klibc/fread2.c create mode 100644 klibc/klibc/fwrite.c create mode 100644 klibc/klibc/fwrite2.c create mode 100644 klibc/klibc/getcwd.c create mode 100644 klibc/klibc/getdomainname.c create mode 100644 klibc/klibc/getenv.c create mode 100644 klibc/klibc/gethostname.c create mode 100644 klibc/klibc/getopt.c create mode 100644 klibc/klibc/getpriority.c create mode 100644 klibc/klibc/globals.c create mode 100644 klibc/klibc/include/alloca.h create mode 100644 klibc/klibc/include/arpa/inet.h create mode 100644 klibc/klibc/include/assert.h create mode 100644 klibc/klibc/include/bits32/bitsize/limits.h create mode 100644 klibc/klibc/include/bits32/bitsize/stddef.h create mode 100644 klibc/klibc/include/bits32/bitsize/stdint.h create mode 100644 klibc/klibc/include/bits32/bitsize/stdintconst.h create mode 100644 klibc/klibc/include/bits32/bitsize/stdintlimits.h create mode 100644 klibc/klibc/include/bits64/bitsize/limits.h create mode 100644 klibc/klibc/include/bits64/bitsize/stddef.h create mode 100644 klibc/klibc/include/bits64/bitsize/stdint.h create mode 100644 klibc/klibc/include/bits64/bitsize/stdintconst.h create mode 100644 klibc/klibc/include/bits64/bitsize/stdintlimits.h create mode 100644 klibc/klibc/include/ctype.h create mode 100644 klibc/klibc/include/dirent.h create mode 100644 klibc/klibc/include/elf.h create mode 100644 klibc/klibc/include/endian.h create mode 100644 klibc/klibc/include/errno.h create mode 100644 klibc/klibc/include/fcntl.h create mode 100644 klibc/klibc/include/grp.h create mode 100644 klibc/klibc/include/inttypes.h create mode 100644 klibc/klibc/include/klibc/compiler.h create mode 100644 klibc/klibc/include/klibc/diverr.h create mode 100644 klibc/klibc/include/klibc/extern.h create mode 100644 klibc/klibc/include/limits.h create mode 100644 klibc/klibc/include/net/if.h create mode 100644 klibc/klibc/include/net/if_arp.h create mode 100644 klibc/klibc/include/net/if_ether.h create mode 100644 klibc/klibc/include/net/if_packet.h create mode 100644 klibc/klibc/include/netinet/in.h create mode 100644 klibc/klibc/include/netinet/in6.h create mode 100644 klibc/klibc/include/netinet/ip.h create mode 100644 klibc/klibc/include/netinet/tcp.h create mode 100644 klibc/klibc/include/netinet/udp.h create mode 100644 klibc/klibc/include/poll.h create mode 100644 klibc/klibc/include/sched.h create mode 100644 klibc/klibc/include/setjmp.h create mode 100644 klibc/klibc/include/signal.h create mode 100644 klibc/klibc/include/stdarg.h create mode 100644 klibc/klibc/include/stddef.h create mode 100644 klibc/klibc/include/stdint.h create mode 100644 klibc/klibc/include/stdio.h create mode 100644 klibc/klibc/include/stdlib.h create mode 100644 klibc/klibc/include/string.h create mode 100644 klibc/klibc/include/sys/dirent.h create mode 100644 klibc/klibc/include/sys/fsuid.h create mode 100644 klibc/klibc/include/sys/ioctl.h create mode 100644 klibc/klibc/include/sys/klog.h create mode 100644 klibc/klibc/include/sys/mman.h create mode 100644 klibc/klibc/include/sys/module.h create mode 100644 klibc/klibc/include/sys/mount.h create mode 100644 klibc/klibc/include/sys/param.h create mode 100644 klibc/klibc/include/sys/reboot.h create mode 100644 klibc/klibc/include/sys/resource.h create mode 100644 klibc/klibc/include/sys/select.h create mode 100644 klibc/klibc/include/sys/socket.h create mode 100644 klibc/klibc/include/sys/socketcalls.h create mode 100644 klibc/klibc/include/sys/stat.h create mode 100644 klibc/klibc/include/sys/syscall.h create mode 100644 klibc/klibc/include/sys/time.h create mode 100644 klibc/klibc/include/sys/times.h create mode 100644 klibc/klibc/include/sys/types.h create mode 100644 klibc/klibc/include/sys/uio.h create mode 100644 klibc/klibc/include/sys/utime.h create mode 100644 klibc/klibc/include/sys/utsname.h create mode 100644 klibc/klibc/include/sys/vfs.h create mode 100644 klibc/klibc/include/sys/wait.h create mode 100644 klibc/klibc/include/syslog.h create mode 100644 klibc/klibc/include/termios.h create mode 100644 klibc/klibc/include/time.h create mode 100644 klibc/klibc/include/unistd.h create mode 100644 klibc/klibc/include/utime.h create mode 100644 klibc/klibc/inet/bindresvport.c create mode 100644 klibc/klibc/inet/inet_addr.c create mode 100644 klibc/klibc/inet/inet_aton.c create mode 100644 klibc/klibc/inet/inet_ntoa.c create mode 100644 klibc/klibc/inet/inet_ntop.c create mode 100644 klibc/klibc/inet/inet_pton.c create mode 100644 klibc/klibc/interp.S create mode 100644 klibc/klibc/isatty.c create mode 100644 klibc/klibc/libgcc/__divdi3.c create mode 100644 klibc/klibc/libgcc/__divsi3.c create mode 100644 klibc/klibc/libgcc/__moddi3.c create mode 100644 klibc/klibc/libgcc/__modsi3.c create mode 100644 klibc/klibc/libgcc/__udivdi3.c create mode 100644 klibc/klibc/libgcc/__udivmoddi4.c create mode 100644 klibc/klibc/libgcc/__udivmodsi4.c create mode 100644 klibc/klibc/libgcc/__udivsi3.c create mode 100644 klibc/klibc/libgcc/__umoddi3.c create mode 100644 klibc/klibc/libgcc/__umodsi3.c create mode 100644 klibc/klibc/llseek.c create mode 100644 klibc/klibc/lrand48.c create mode 100644 klibc/klibc/makeerrlist.pl create mode 100644 klibc/klibc/malloc.c create mode 100644 klibc/klibc/malloc.h create mode 100644 klibc/klibc/memccpy.c create mode 100644 klibc/klibc/memchr.c create mode 100644 klibc/klibc/memcmp.c create mode 100644 klibc/klibc/memcpy.c create mode 100644 klibc/klibc/memmem.c create mode 100644 klibc/klibc/memmove.c create mode 100644 klibc/klibc/memset.c create mode 100644 klibc/klibc/memswap.c create mode 100644 klibc/klibc/mmap.c create mode 100644 klibc/klibc/nice.c create mode 100644 klibc/klibc/onexit.c create mode 100644 klibc/klibc/pause.c create mode 100644 klibc/klibc/perror.c create mode 100644 klibc/klibc/printf.c create mode 100644 klibc/klibc/pty.c create mode 100644 klibc/klibc/puts.c create mode 100644 klibc/klibc/qsort.c create mode 100644 klibc/klibc/raise.c create mode 100644 klibc/klibc/readdir.c create mode 100644 klibc/klibc/realloc.c create mode 100644 klibc/klibc/reboot.c create mode 100644 klibc/klibc/recv.c create mode 100644 klibc/klibc/sbrk.c create mode 100644 klibc/klibc/seed48.c create mode 100644 klibc/klibc/select.c create mode 100644 klibc/klibc/send.c create mode 100644 klibc/klibc/setegid.c create mode 100644 klibc/klibc/setenv.c create mode 100644 klibc/klibc/seteuid.c create mode 100644 klibc/klibc/setpgrp.c create mode 100644 klibc/klibc/setresgid.c create mode 100644 klibc/klibc/setresuid.c create mode 100644 klibc/klibc/sha1hash.c create mode 100644 klibc/klibc/sigaction.c create mode 100644 klibc/klibc/siglist.c create mode 100644 klibc/klibc/siglongjmp.c create mode 100644 klibc/klibc/signal.c create mode 100644 klibc/klibc/sigpending.c create mode 100644 klibc/klibc/sigprocmask.c create mode 100644 klibc/klibc/sigsuspend.c create mode 100644 klibc/klibc/sleep.c create mode 100644 klibc/klibc/snprintf.c create mode 100644 klibc/klibc/socketcalls.pl create mode 100644 klibc/klibc/socketcommon.h create mode 100644 klibc/klibc/sprintf.c create mode 100644 klibc/klibc/srand48.c create mode 100644 klibc/klibc/sscanf.c create mode 100644 klibc/klibc/strcat.c create mode 100644 klibc/klibc/strchr.c create mode 100644 klibc/klibc/strcmp.c create mode 100644 klibc/klibc/strcpy.c create mode 100644 klibc/klibc/strdup.c create mode 100644 klibc/klibc/strerror.c create mode 100644 klibc/klibc/strlen.c create mode 100644 klibc/klibc/strncat.c create mode 100644 klibc/klibc/strncmp.c create mode 100644 klibc/klibc/strncpy.c create mode 100644 klibc/klibc/strntoimax.c create mode 100644 klibc/klibc/strntoumax.c create mode 100644 klibc/klibc/strrchr.c create mode 100644 klibc/klibc/strsep.c create mode 100644 klibc/klibc/strspn.c create mode 100644 klibc/klibc/strstr.c create mode 100644 klibc/klibc/strtoimax.c create mode 100644 klibc/klibc/strtok.c create mode 100644 klibc/klibc/strtol.c create mode 100644 klibc/klibc/strtoll.c create mode 100644 klibc/klibc/strtoul.c create mode 100644 klibc/klibc/strtoull.c create mode 100644 klibc/klibc/strtoumax.c create mode 100644 klibc/klibc/strtox.c create mode 100644 klibc/klibc/syscalls.pl create mode 100644 klibc/klibc/syscommon.h create mode 100644 klibc/klibc/syslog.c create mode 100644 klibc/klibc/system.c create mode 100644 klibc/klibc/tests/getenvtest.c create mode 100644 klibc/klibc/tests/getopttest.c create mode 100644 klibc/klibc/tests/hello.c create mode 100644 klibc/klibc/tests/idtest.c create mode 100644 klibc/klibc/tests/malloctest.c create mode 100644 klibc/klibc/tests/memstrtest.c create mode 100644 klibc/klibc/tests/microhello.c create mode 100644 klibc/klibc/tests/minihello.c create mode 100644 klibc/klibc/tests/minips.c create mode 100644 klibc/klibc/tests/nfs_no_rpc.c create mode 100644 klibc/klibc/tests/setjmptest.c create mode 100644 klibc/klibc/tests/testrand48.c create mode 100644 klibc/klibc/tests/testvsnp.c create mode 100644 klibc/klibc/time.c create mode 100644 klibc/klibc/umount.c create mode 100644 klibc/klibc/unsetenv.c create mode 100644 klibc/klibc/usleep.c create mode 100644 klibc/klibc/utime.c create mode 100644 klibc/klibc/vfprintf.c create mode 100644 klibc/klibc/vprintf.c create mode 100644 klibc/klibc/vsnprintf.c create mode 100644 klibc/klibc/vsprintf.c create mode 100644 klibc/klibc/vsscanf.c create mode 100644 klibc/klibc/wait.c create mode 100644 klibc/klibc/wait3.c create mode 100644 klibc/klibc/waitpid.c create mode 100644 klibc/version diff --git a/klibc/MCONFIG b/klibc/MCONFIG new file mode 100644 index 0000000000..ed7755b382 --- /dev/null +++ b/klibc/MCONFIG @@ -0,0 +1,41 @@ +# -*- makefile -*- +# +# Makefile configuration, without explicit rules +# + +ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) +CROSS = +CC = $(CROSS)gcc +LD = $(CROSS)ld +KLIBSRC = $(SRCROOT)/klibc +REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include -I$(KLIBSRC) \ + -I$(KLIBSRC)/arch/$(ARCH)/include \ + -I$(KLIBSRC)/include/bits$(BITSIZE) \ + -D__KLIBC__ -DBITSIZE=$(BITSIZE) -I$(KLIBSRC)/include \ + -I$(SRCROOT)/linux/include +LDFLAGS = +AR = $(CROSS)ar +RANLIB = $(CROSS)ranlib +NM = $(CROSS)nm +PERL = perl +STRIP = $(CROSS)strip --strip-all -R .comment -R .note + +HOST_CC = gcc +HOST_LDFLAGS = -s +HOST_LIBS = + +CRT0 = $(KLIBSRC)/crt0.o +KLIBC = $(KLIBSRC)/libc.a +LIBGCC = $(shell $(CC) --print-libgcc) + +# +# This indicates the location of the final version of the shared library. +# THIS MUST BE AN ABSOLUTE PATH WITH NO FINAL SLASH. +# Leave this empty to make it the root. +# +SHLIBDIR = /lib + +# +# Include arch-specific rule fragments +# +include $(KLIBSRC)/arch/$(ARCH)/MCONFIG diff --git a/klibc/Makefile b/klibc/Makefile index 288a862707..5f9a7d6a6e 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -1,3 +1,6 @@ +SUBDIRS = klibc -clean: - @echo "all clean" +all: + +%: + @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done diff --git a/klibc/README b/klibc/README new file mode 100644 index 0000000000..577de2b704 --- /dev/null +++ b/klibc/README @@ -0,0 +1,16 @@ +Please see klibc/README for how to set up the tree before building. + +klibc is archived at: + + ftp://ftp.zytor.com/pub/linux/libs/klibc/ + +There is a mailing list for klibc and early-userspace issues at: + + http://www.zytor.com/mailman/listinfo/klibc/ + +There is also a cvsweb repository at: + + http://www.zytor.com/cvsweb.cgi/klibc/ + +There is no direct public CVS access yet, however. + diff --git a/klibc/klibc/CAVEATS b/klibc/klibc/CAVEATS new file mode 100644 index 0000000000..c7131ac367 --- /dev/null +++ b/klibc/klibc/CAVEATS @@ -0,0 +1,51 @@ + ------------------------------------------------- + Please note the following caveats to using klibc: + ------------------------------------------------- + +optimization: +------------- + +Compiling with -O0 is not supported. It may or may not work; please +use -O1 if you want to do maximize debuggability. + +Compiling with -O0 is more likely to work on gcc 3. + + +setjmp()/longjmp(): +------------------- + +setjmp() and longjmp() *do not* save signal state. sigsetjmp() and +siglongjmp() *do* save the signal mask -- regardless of the value of +the extra argument. + +The standards actually state that if you pass longjmp() a final value +of zero the library should change that to a 1! Presumably the reason +is so people who write broken code can get away with writing +longjmp(buf); or something equally bad. If you pass longjmp() a final +value of 0 you get what you deserve -- setjmp() will happily return 0. + + +stdio: +------ + +Only a small subset of the stdio functions are implemented. Those +that are implemented do not buffer, although they *do* trap EINTR or +short read/writes and iterate. + +_fread() and _fwrite(), which take only one size argument (like +read/write), but do handle EINTR/short return are also available. + + +namespaces: +----------- + +klibc frequently includes headers in other headers in a way that +exposes more symbols than POSIX says they should. "Live with it." + + +theading: +--------- + +klibc is not thread-safe. Consequently, clone() or any of the +pthreads functions are not included. + diff --git a/klibc/klibc/LICENSE b/klibc/klibc/LICENSE new file mode 100644 index 0000000000..b512ff96bc --- /dev/null +++ b/klibc/klibc/LICENSE @@ -0,0 +1,73 @@ +This license applies to all files in directory and its subdirectories, +unless otherwise noted in individual files. + + +Some files are derived from files derived from the include/ directory +of the Linux kernel, and are licensed under the terms of the GNU +General Public License, version 2, as released by the Free Software +Foundation, Inc.; incorporated herein by reference. + + ----- + +Some files are derived from files copyrighted by the Regents of The +University of California, and are available under the following +license: + +Note: The advertising clause in the license appearing on BSD Unix +files was officially rescinded by the Director of the Office of +Technology Licensing of the University of California on July 22 +1999. He states that clause 3 is "hereby deleted in its entirety." + + * Copyright (c) + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + + ----- + +For all remaining files, the following license applies: + + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * Any copyright notice(s) and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/klibc/klibc/MCONFIG b/klibc/klibc/MCONFIG new file mode 100644 index 0000000000..a46a98a9dd --- /dev/null +++ b/klibc/klibc/MCONFIG @@ -0,0 +1,49 @@ +# -*- makefile -*- +# +# Makefile configuration, without explicit rules +# + +SRCROOT = .. +include ../MCONFIG + +WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline +CFLAGS = -Wp,-MD,$(dir $*).$(notdir $*).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) + +SOFLAGS = -fPIC + +.SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss + +.c.o: + $(CC) $(CFLAGS) -c -o $@ $< + +.c.i: + $(CC) $(CFLAGS) -E -o $@ $< + +.c.s: + $(CC) $(CFLAGS) -S -o $@ $< + +.S.o: + $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< + +.S.s: + $(CC) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $< + +.S.lo: + $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -c -o $@ $< + +.S.ls: + $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -E -o $@ $< + +.s.o: + $(CC) $(CFLAGS) -x assembler -c -o $@ $< + +.ls.lo: + $(CC) $(CFLAGS) $(SOFLAGS) -x assembler -c -o $@ $< + +.c.lo: + $(CC) $(CFLAGS) $(SOFLAGS) -c -o $@ $< + +.c.ls: + $(CC) $(CFLAGS) $(SOFLAGS) -S -o $@ $< + + diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile new file mode 100644 index 0000000000..470a276ded --- /dev/null +++ b/klibc/klibc/Makefile @@ -0,0 +1,135 @@ +# +# Makefile +# +# Main makefile +# + +# Include configuration rules +include MCONFIG + +TESTS = $(patsubst %.c,%,$(wildcard tests/*.c)) \ + $(patsubst %.c,%.shared,$(wildcard tests/*.c)) +LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ + vsscanf.o sscanf.o ctypes.o \ + strntoumax.o strntoimax.o \ + atoi.o atol.o atoll.o \ + strtol.o strtoll.o strtoul.o strtoull.o \ + strtoimax.o strtoumax.o \ + globals.o exitc.o atexit.o onexit.o \ + execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \ + fork.o wait.o wait3.o waitpid.o system.o setpgrp.o \ + printf.o vprintf.o fprintf.o vfprintf.o perror.o \ + fopen.o fread.o fread2.o fgetc.o fgets.o \ + fwrite.o fwrite2.o fputc.o fputs.o puts.o \ + sleep.o usleep.o raise.o abort.o assert.o alarm.o pause.o \ + __signal.o signal.o bsd_signal.o siglist.o siglongjmp.o \ + sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ + brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ + memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ + memmove.o \ + strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o \ + strncat.o strstr.o strncmp.o strncpy.o strrchr.o strspn.o \ + strsep.o strtok.o \ + gethostname.o getdomainname.o getcwd.o \ + seteuid.o setegid.o setresuid.o setresgid.o \ + getenv.o setenv.o unsetenv.o getopt.o readdir.o \ + syslog.o closelog.o pty.o isatty.o reboot.o \ + time.o utime.o fdatasync.o llseek.o select.o nice.o getpriority.o \ + qsort.o lrand48.o srand48.o seed48.o \ + inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ + inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \ + send.o recv.o +SOLIB = libc.so +SOHASH = klibc.so + +CRT0 = crt0.o +LIB = libc.a + +#all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so +all: $(CRT0) $(LIB) $(SOLIB) klibc.so + +# Add any architecture-specific rules +include arch/$(ARCH)/Makefile.inc + +tests: $(TESTS) + +tests/%.o : tests/%.c + $(CC) $(CFLAGS) -c -o $@ $< + +tests/% : tests/%.o $(LIB) $(CRT0) + $(LD) $(LDFLAGS) -o $@ $(CRT0) $< $(LIB) $(LIBGCC) + cp $@ $@.stripped + $(STRIP) $@.stripped + +tests/%.shared : tests/%.o interp.o $(SOLIB) + $(LD) $(LDFLAGS) -o $@ -e main interp.o tests/$*.o -R $(SOLIB) $(LIBGCC) + cp $@ $@.stripped + $(STRIP) $@.stripped + +$(LIB): __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj + rm -f $(LIB) + $(AR) cq $(LIB) __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/*.o socketcalls/*.o + $(RANLIB) $(LIB) + +$(SOLIB): $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj + $(LD) $(LDFLAGS) $(SHAREDFLAGS) -o $@ \ + $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) \ + syscalls/*.o socketcalls/*.o \ + $(LIBGCC) + +sha1hash: sha1hash.c + $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ $< + +$(SOLIB).hash: $(SOLIB) sha1hash + $(NM) $(SOLIB) | \ + egrep '^[0-9a-fA-F]+ [ADRTW] ' | sort | ./sha1hash > $@ + +$(SOHASH): $(SOLIB) $(SOLIB).hash + cp -f $(SOLIB) $@ + $(STRIP) $@ + rm -f klibc-??????????????????????.so + ln -f $@ klibc-`cat $(SOLIB).hash`.so + +interp.o: interp.S $(SOLIB).hash + $(CC) $(CFLAGS) -D__ASSEMBLY__ -DLIBDIR=\"$(SHLIBDIR)\" \ + -DSOHASH=\"`cat $(SOLIB).hash`\" \ + -c -o $@ $< + +crt0.o: arch/$(ARCH)/crt0.o + cp arch/$(ARCH)/crt0.o . + +syscalls.dir: SYSCALLS syscalls.pl syscommon.h + rm -rf syscalls + mkdir syscalls + $(PERL) syscalls.pl $(ARCH) SYSCALLS + touch $@ + +socketcalls.dir: SOCKETCALLS socketcalls.pl socketcommon.h + rm -rf socketcalls + mkdir socketcalls + $(PERL) socketcalls.pl $(ARCH) SOCKETCALLS + touch $@ + +%/static.obj: %.dir + $(MAKE) objects-$(basename $(notdir $@)) DIR=$* + +STATIC = $(addsuffix .o,$(basename $(wildcard $(DIR)/*.[cS]))) + +objects-static: $(STATIC) + touch $(DIR)/static.obj + +clean: archclean + find . -type f -a \( -name \*.[isoa] -o -name \*.l[iso] \) -print0 | xargs -0rt rm -f + rm -f *.a *.so *.hash *.syms *.stripped + rm -f $(TESTS) tests/*.stripped + rm -rf syscalls syscalls.dir + rm -rf socketcalls socketcalls.dir + rm -f sha1hash + +spotless: clean + find . \( -name \*~ -o -name '.*.d' \) -not -type d -print0 | \ + xargs -0rt rm -f + +ifneq ($(wildcard $(DIR)/.*.d),) +include $(wildcard $(DIR)/.*.d) +endif diff --git a/klibc/klibc/README b/klibc/klibc/README new file mode 100644 index 0000000000..7d5751804f --- /dev/null +++ b/klibc/klibc/README @@ -0,0 +1,57 @@ +This is klibc, what is intended to be a minimalistic libc subset for +use with initramfs. It is deliberately written for small size, +minimal entaglement and portability, not speed. It is definitely a +work in progress, and a lot of things are still missing. + + +The build procedure is not very polished yet, but it should work like +this: + +a) In the source root directory (the directory above the one in which + this file is found) create a symlink called "linux" pointing to a + reasonably recent Linux kernel tree (2.4 or 2.5 should be OK.) + This tree must have the include/asm symlink set up for the + architecture you're compiling for, and include/linux/autoconf.h + must exist. The easiest way to make sure of all of these is to do + a "make config" or any of its variants on the kernel tree is + question, followed by a "make dep". + +b) If you're cross-compiling, change ARCH in the main MCONFIG file to + the appropriate architecture, and set CROSS to your toolchain + prefix. + + IMPORTANT: if you're on a 64-bit machine with a 32-bit userland + (ia64, mips64, ppc64 sparc64, s390x or x86_64), and you want to + build the 32-bit version: you need to set ARCH to the 32-bit + architecture as well as set up the linux/include/asm symlink to + point to the 32-bit architecture. Building the 32-bit architecture + usually (but not always) produces smaller binaries, and is likely + to be better tested. + + If you are on ARM, and want to build a thumb version of the library + (this is supported), change OPTFLAGS in arch/arm/MCONFIG to build + thumb code. + + The following is the last known status of various architectures: + + Known to work: alpha arm i386 s390 s390x sparc sparc64 x86_64* + Works static, not shared: mips* arm-thumb sh* + Need crt0.S updates: ppc + Missing setjmp: ppc64 + Need porting work: cris ia64 m68k mips64 parisc + + x86_64: requires a kernel header patch (to be created) + mips, sh: linker problem; might work with fixed linker + + Shared library support for sparc/sparc64 requires binutils 2.13.90.0.4. + + Note that even the "known to work" ones likely have bugs. Please + report them if you run into them. + +c) Type "make" and pray... + +d) Try the test programs in the tests/ directory. They should run... + +Contact me at for more info. + + -hpa diff --git a/klibc/klibc/SOCKETCALLS b/klibc/klibc/SOCKETCALLS new file mode 100644 index 0000000000..1ab4e367a2 --- /dev/null +++ b/klibc/klibc/SOCKETCALLS @@ -0,0 +1,21 @@ +# -*- fundamental -*- +# +# These are calls that are invoked via the socketcall mechanism +# +int socket(int, int, int) +int bind(int, struct sockaddr *, int) +int connect(int, struct sockaddr *, socklen_t) +int listen(int, int) +int accept(int, struct sockaddr *, socklen_t *) +int getsockname(int, struct sockaddr *, socklen_t *) +int getpeername(int, struct sockaddr *, socklen_t *) +int socketpair(int, int, int, int *) +# int send(int, const void *, size_t, unsigned int) +int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t) +# int recv(int, void *, size_t, unsigned int) +int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *) +int shutdown(int, int) +int setsockopt(int, int, int, const void *, socklen_t) +int getsockopt(int, int, int, void *, socklen_t *) +int sendmsg(int, const struct msghdr *, unsigned int) +int recvmsg(int, struct msghdr *, unsigned int) diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS new file mode 100644 index 0000000000..1ec94acec6 --- /dev/null +++ b/klibc/klibc/SYSCALLS @@ -0,0 +1,146 @@ +# -*- fundamental -*- +# +# This is a list of system calls we invoke "directly". These +# are generated into syscall stubs in their own C files, so the +# linker can do its job properly. +# +# The full description of a line is: +# [<[!]arch,...>] type sysname[@systype][::funcname](args) +# + +# +# Process-related syscalls +# + pid_t vfork() + pid_t vfork@forkish() + pid_t getpid() + pid_t getxpid@dual0::getpid() +int setpgid(pid_t, pid_t) +pid_t getpgid(pid_t) + pid_t getppid() + pid_t getxpid@dual1::getppid() + pid_t getpgrp() +pid_t setsid() +pid_t getsid(pid_t) +pid_t wait4(pid_t, int *, int, struct rusage *) +int execve(const char *, char * const *, char * const *) +int setpriority(int, int, int) +int sched_setscheduler(pid_t, int, const struct sched_param *) +int sched_yield() + +# +# User and group IDs +# +int setuid(uid_t) +int setgid(gid_t) + uid_t getuid() + uid_t getxuid@dual0::getuid() + gid_t getgid() + gid_t getxgid@dual0::getgid() + uid_t geteuid() + uid_t getxuid@dual1::geteuid() + gid_t getegid() + uid_t getxgid@dual1::getegid() +int getgroups(int, gid_t *) +int setgroups(size_t, const gid_t *) +int setreuid(uid_t, uid_t) +int setregid(gid_t, gid_t) +int setfsuid(uid_t) +int setfsgid(gid_t) + +# +# Filesystem-related system calls +# +int mount(const char *, const char *, const char *, unsigned long, const void *) + int umount2(const char *, int) + int umount::umount2(const char *, int) + int pivot_root(const char *, const char *) +int sync() +int statfs(const char *, struct statfs *) +int fstatfs(int, struct statfs *) +int swapon(const char *, int) +int swapoff(const char *) + +# +# Inode-related system calls +# +int access(const char *, int) +int link(const char *, const char *) +int unlink(const char *) +int chdir(const char *) +int rename(const char *, const char *) +int mknod(const char *, mode_t, dev_t) +int chmod(const char *, mode_t) +int mkdir(const char *, mode_t) +int rmdir(const char *) + int pipe(int *) +mode_t umask(mode_t) +int chroot(const char *) +int symlink(const char *, const char *) +int readlink(const char *, char *, size_t) +int stat(const char *, struct stat *) +int lstat(const char *, struct stat *) +int fstat(int, struct stat *) +int getdents(unsigned int, struct dirent *, unsigned int) +int chown(const char *, uid_t, gid_t) +int fchown(int, uid_t, gid_t) +int lchown(const char *, uid_t, gid_t) + +# +# I/O operations +# +ssize_t read(int, void *, size_t) +ssize_t write(int, const void *, size_t) +int open(const char *, int, mode_t) +int close(int) +off_t lseek(int, off_t, int) +int dup(int) +int dup2(int, int) +int fcntl(int, int, long) +int ioctl(int, int, void *) +int flock(int, int) +int poll(struct pollfd *, nfds_t, long) +int fsync(int) +int readv(int, const struct iovec *, int) +int writev(int, const struct iovec *, int) + +# +# Signal operations +# +int kill(pid_t, int) +int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) +int rt_sigsuspend(const sigset_t *, size_t) +int rt_sigpending(sigset_t *, size_t) +int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t) +int getitimer(int, struct itimerval *) +int setitimer(int, const struct itimerval *, struct itimerval *) + +# +# Time-related system calls +# +clock_t times(struct tms *) +int gettimeofday(struct timeval *, struct timezone *) +int settimeofday(const struct timeval *, const struct timezone *) +int nanosleep(const struct timespec *, struct timespec *) + +# +# Memory +# +void * brk::__brk(void *) +int munmap(void *, size_t) +void * mremap(void *, size_t, size_t, unsigned long) +int msync(const void *, size_t, int) +int mprotect(const void *, size_t, int) + +# +# System stuff +# +int uname(struct utsname *) +int setdomainname(const char *, size_t) +int sethostname(const char *, size_t) +int init_module(const char *, struct module *) +void * create_module(const char *, size_t) +int delete_module(const char *) +int query_module(const char *, int, void *, size_t, size_t) +int reboot::__reboot(int, int, int, void *) +int syslog::klogctl(int, char *, int) diff --git a/klibc/klibc/__shared_init.c b/klibc/klibc/__shared_init.c new file mode 100644 index 0000000000..63e3f4644e --- /dev/null +++ b/klibc/klibc/__shared_init.c @@ -0,0 +1,56 @@ +/* + * __shared_init.c + * + * This function takes the raw data block set up by the ELF loader + * in the kernel and parses it. It is invoked by crt0.S which makes + * any necessary adjustments and passes calls this function using + * the standard C calling convention. + * + * The arguments are: + * uintptr_t *elfdata -- The ELF loader data block; usually from the stack. + * Basically a pointer to argc. + * void (*onexit)(void) -- Function to install into onexit + */ + +#include +#include +#include +#include +#include + +char **environ; + +__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void)) +{ + int argc; + char **argv, **envp, **envend; + struct auxentry { + uintptr_t type; + uintptr_t v; + } *auxentry; + typedef int (*main_t)(int, char **, char **); + main_t main_ptr = NULL; + + (void)onexit; /* For now, we ignore this... */ + + argc = (int)*elfdata++; + argv = (char **)elfdata; + envp = argv+(argc+1); + + /* The auxillary entry vector is after all the environment vars */ + for ( envend = envp ; *envend ; envend++ ); + auxentry = (struct auxentry *)(envend+1); + + while ( auxentry->type ) { + if ( auxentry->type == AT_ENTRY ) { + main_ptr = (main_t)(auxentry->v); + break; + } + auxentry++; + } + + environ = envp; + exit(main_ptr(argc, argv, envp)); +} + + diff --git a/klibc/klibc/__signal.c b/klibc/klibc/__signal.c new file mode 100644 index 0000000000..b5081d386b --- /dev/null +++ b/klibc/klibc/__signal.c @@ -0,0 +1,22 @@ +/* + * __signal.c + */ + +#include + +__sighandler_t __signal(int signum, __sighandler_t handler, int flags) +{ + struct sigaction sa; + + sa.sa_handler = handler; + sa.sa_flags = flags; + sigemptyset(&sa.sa_mask); + + if ( sigaction(signum, &sa, &sa) ) { + return (__sighandler_t)SIG_ERR; + } else { + return (__sighandler_t)sa.sa_handler; + } +} + + diff --git a/klibc/klibc/__static_init.c b/klibc/klibc/__static_init.c new file mode 100644 index 0000000000..dcb8d01856 --- /dev/null +++ b/klibc/klibc/__static_init.c @@ -0,0 +1,40 @@ +/* + * __static_init.c + * + * This function takes the raw data block set up by the ELF loader + * in the kernel and parses it. It is invoked by crt0.S which makes + * any necessary adjustments and passes calls this function using + * the standard C calling convention. + * + * The arguments are: + * uintptr_t *elfdata -- The ELF loader data block; usually from the stack. + * Basically a pointer to argc. + * void (*onexit)(void) -- Function to install into onexit + */ + +#include +#include +#include +#include +#include + +char **environ; + +extern int main(int, char **, char **); + +__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void)) +{ + int argc; + char **argv, **envp; + + (void)onexit; /* For now, we ignore this... */ + + argc = (int)*elfdata++; + argv = (char **)elfdata; + envp = argv+(argc+1); + + environ = envp; + exit(main(argc, argv, envp)); +} + + diff --git a/klibc/klibc/abort.c b/klibc/klibc/abort.c new file mode 100644 index 0000000000..9280d9861b --- /dev/null +++ b/klibc/klibc/abort.c @@ -0,0 +1,19 @@ +/* + * abort.c + */ + +#include +#include +#include + +void abort(void) +{ + sigset_t set; + + sigemptyset(&set); + sigaddset(&set, SIGABRT); + sigprocmask(SIG_UNBLOCK, &set, NULL); + raise(SIGABRT); + _exit(255); /* raise() should have killed us */ +} + diff --git a/klibc/klibc/alarm.c b/klibc/klibc/alarm.c new file mode 100644 index 0000000000..ca7bb37f92 --- /dev/null +++ b/klibc/klibc/alarm.c @@ -0,0 +1,29 @@ +/* + * alarm.c + */ + +#include +#include + +#ifdef __NR_alarm + +_syscall1(unsigned int,alarm,unsigned int,seconds); + +#else + +/* Emulate alarm() via setitimer() */ + +unsigned int alarm(unsigned int seconds) +{ + struct itimerval iv; + + iv.it_interval.tv_sec = iv.it_interval.tv_usec = 0; + iv.it_value.tv_sec = seconds; + iv.it_value.tv_usec = 0; + + setitimer(ITIMER_REAL, &iv, &iv); + + return iv.it_value.tv_sec + (iv.it_value.tv_usec ? 1 : 0); +} + +#endif diff --git a/klibc/klibc/arch/README b/klibc/klibc/arch/README new file mode 100644 index 0000000000..eceb23de4b --- /dev/null +++ b/klibc/klibc/arch/README @@ -0,0 +1,67 @@ +To port klibc to a new architecture, you need: + +a) A directory structure + +Each archtecture has an arch/ directory, which should include an +MCONFIG and a Makefile.inc file. + +b) Startup code (arch/*/crt0.S) + +The crt0.S assembly routine typically corresponds to the following +pseudo-C code. In addition, each architecture needs any support +routines that gcc-generated code expects to find in the system library +-- Alpha, for example, needs divide subroutines. + +The "getenvtest" test program is a very good test for proper crt0.S +functionality. + + +extern __noreturn __libc_init(void *, void *); + +__noreturn _start(void) +{ + void *elf_data = get_elf_data_address(); /* Usually the stack address */ + void *atexit_ptr = get_atexit_ptr(); /* Usually in a register */ + + /* Some architectures need this for debugging to work */ + setup_null_stack_frame_if_necessary(); + + __libc_init(elf_data, atexit_ptr); +} + + +c) A setenv implementation (arch/*/setjmp.S, arch/*/include/klibc/archsetjmp.h) + +On most (but not all!) architectures, this entails creating a setjmp +buffer big enough to hold all callee-saved registers, plus the stack +pointer and the return address. In setjmp.S you have: + +* A "setjmp" function that writes out the callee-saved registers, the + stack pointer and the return address to the buffer pointed to by the + first argument, and then returns zero normally. + + On some architectures you need to take some kind of action to make + sure the contents of the stack is actually manifest in memory and + not cached in the CPU. In some cases (e.g. on SPARC) this will + automatically spill the registers onto the stack; then they don't + need to be spilled into the jmp_buf. + +* A "longjmp" function that read back these same registers from the + jmp_buf pointed to by the first argument, and returns the second + argument *to the address specified in the jmp_buf*. + + On some architectures you need to take some kind of action to flush + any cached stack data or return stack. + + +d) Any support functions needed by gcc, *unless* they are in libgcc + *and* libgcc is usable for klibc on your particular platform. If + libgcc isn't usable for klibc (on MIPS, for example, libgcc is + compiled in a way that is not compatible with klibc) there are + reasonably good clones of most of the libgcc functions in the libgcc + directory. To use them, add them to ARCHOBJS in + arch/*/Makefile.inc. + + +e) A link location for the shared klibc. This should be specified in + SHAREDFLAGS in arch/*/MCONFIG. diff --git a/klibc/klibc/arch/alpha/MCONFIG b/klibc/klibc/arch/alpha/MCONFIG new file mode 100644 index 0000000000..5987ed5841 --- /dev/null +++ b/klibc/klibc/arch/alpha/MCONFIG @@ -0,0 +1,17 @@ +# -*- makefile -*- +# +# arch/alpha/MCONFIG +# +# Build configuration for this architecture +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 64 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 7 GB - normal binaries start at 4.5 GB, and the stack is below +# the binary. +SHAREDFLAGS = -Ttext 0x1c0000200 + diff --git a/klibc/klibc/arch/alpha/Makefile.inc b/klibc/klibc/arch/alpha/Makefile.inc new file mode 100644 index 0000000000..2a1100f962 --- /dev/null +++ b/klibc/klibc/arch/alpha/Makefile.inc @@ -0,0 +1,93 @@ +# -*- makefile -*- +# +# arch/alpha/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +# Special CFLAGS for the divide code +DIVCFLAGS = $(REQFLAGS) \ + -O3 -fomit-frame-pointer -fcall-saved-1 -fcall-saved-2 \ + -fcall-saved-3 -fcall-saved-4 -fcall-saved-5 -fcall-saved-6 \ + -fcall-saved-7 -fcall-saved-8 -fcall-saved-15 -fcall-saved-16 \ + -fcall-saved-17 -fcall-saved-18 -fcall-saved-19 -fcall-saved-20 \ + -fcall-saved-21 -fcall-saved-22 -ffixed-23 -fcall-saved-24 \ + -ffixed-25 -ffixed-27 + +ARCHOBJS = \ + arch/$(ARCH)/__divqu.o \ + arch/$(ARCH)/__remqu.o \ + arch/$(ARCH)/__divq.o \ + arch/$(ARCH)/__remq.o \ + arch/$(ARCH)/__divlu.o \ + arch/$(ARCH)/__remlu.o \ + arch/$(ARCH)/__divl.o \ + arch/$(ARCH)/__reml.o \ + arch/$(ARCH)/pipe.o \ + arch/$(ARCH)/setjmp.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + +arch/$(ARCH)/%.s: arch/$(ARCH)/%.ss + sed -e 's/\$$0\b/$$27/g' -e 's/\$$24\b/$$99/g' \ + -e 's/\$$16\b/$$24/g' -e 's/\$$17\b/$$25/g' \ + -e 's/\$$26\b/$$23/g' -e 's/\$$99\b/$$16/g' < $< > $@ + +arch/$(ARCH)/%.ls: arch/$(ARCH)/%.lss + sed -e 's/\$$0\b/$$27/g' -e 's/\$$24\b/$$99/g' \ + -e 's/\$$16\b/$$24/g' -e 's/\$$17\b/$$25/g' \ + -e 's/\$$26\b/$$23/g' -e 's/\$$99\b/$$16/g' < $< > $@ + +arch/$(ARCH)/__divqu.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=0 -DBITS=64 -DNAME=__divqu -S -o $@ $< + +arch/$(ARCH)/__remqu.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=1 -DBITS=64 -DNAME=__remqu -S -o $@ $< + +arch/$(ARCH)/__divq.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=0 -DBITS=64 -DNAME=__divq -S -o $@ $< + +arch/$(ARCH)/__remq.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=1 -DBITS=64 -DNAME=__remq -S -o $@ $< + +arch/$(ARCH)/__divlu.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__divlu -S -o $@ $< + +arch/$(ARCH)/__remlu.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__remlu -S -o $@ $< + +arch/$(ARCH)/__divl.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__divl -S -o $@ $< + +arch/$(ARCH)/__reml.ss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__reml -S -o $@ $< + +arch/$(ARCH)/__divqu.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=0 -DBITS=64 -DNAME=__divqu -S -o $@ $< + +arch/$(ARCH)/__remqu.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=1 -DBITS=64 -DNAME=__remqu -S -o $@ $< + +arch/$(ARCH)/__divq.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=0 -DBITS=64 -DNAME=__divq -S -o $@ $< + +arch/$(ARCH)/__remq.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=1 -DBITS=64 -DNAME=__remq -S -o $@ $< + +arch/$(ARCH)/__divlu.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__divlu -S -o $@ $< + +arch/$(ARCH)/__remlu.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__remlu -S -o $@ $< + +arch/$(ARCH)/__divl.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__divl -S -o $@ $< + +arch/$(ARCH)/__reml.lss: arch/$(ARCH)/divide.c + $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__reml -S -o $@ $< + +archclean: + rm -f arch/$(ARCH)/*.ss arch/$(ARCH)/*.lss + diff --git a/klibc/klibc/arch/alpha/README-gcc b/klibc/klibc/arch/alpha/README-gcc new file mode 100644 index 0000000000..9aaba72837 --- /dev/null +++ b/klibc/klibc/arch/alpha/README-gcc @@ -0,0 +1,23 @@ + The current Alpha chips don't provide hardware for integer + division. The C compiler expects the functions + + __divqu: 64-bit unsigned long divide + __remqu: 64-bit unsigned long remainder + __divq/__remq: signed 64-bit + __divlu/__remlu: unsigned 32-bit + __divl/__reml: signed 32-bit + + These are not normal C functions: instead of the normal calling + sequence, these expect their arguments in registers t10 and t11, and + return the result in t12 (aka pv). Register AT may be clobbered + (assembly temporary), anything else must be saved. + + Furthermore, the return address is in t9 instead of ra. + + Normal function Divide functions + --------------- ---------------- + v0 ($0) t12/pv ($27) + a0 ($16) t10 ($24) + a1 ($17) t11 ($25) + ra ($26) t9 ($23) + diff --git a/klibc/klibc/arch/alpha/crt0.S b/klibc/klibc/arch/alpha/crt0.S new file mode 100644 index 0000000000..6c2958117d --- /dev/null +++ b/klibc/klibc/arch/alpha/crt0.S @@ -0,0 +1,21 @@ +# +# arch/alpha/crt0.S +# + + .text + .type __start,@function + .ent __start, 0 + .globl __start +__start: + .frame $30, 0, $26, 0 + mov $31, $15 + br $29, 1f +1: ldgp $29, 0($29) + .prologue 0 + + lda $16, 0($30) # ELF data structure + lda $17, 0($0) # atexit pointer + + jsr $26, __libc_init + + .size __start,.-__start diff --git a/klibc/klibc/arch/alpha/divide.c b/klibc/klibc/arch/alpha/divide.c new file mode 100644 index 0000000000..49d77cd5dc --- /dev/null +++ b/klibc/klibc/arch/alpha/divide.c @@ -0,0 +1,57 @@ +#include +#include +#include + +#if BITS == 64 +typedef uint64_t uint; +typedef int64_t sint; +#else +typedef uint32_t uint; +typedef int32_t sint; +#endif + +#ifdef SIGNED +typedef sint xint; +#else +typedef uint xint; +#endif + +xint NAME (uint num, uint den) +{ + uint quot = 0, qbit = 1; + int minus = 0; + xint v; + + if ( den == 0 ) { + /* This is really $16, but $16 and $24 are exchanged by a script */ + register unsigned long cause asm("$24") = GEN_INTDIV; + asm volatile("call_pal %0" :: "i" (PAL_gentrap), "r" (cause)); + return 0; /* If trap returns... */ + } + +#if SIGNED + if ( (sint)(num^den) < 0 ) + minus = 1; + if ( (sint)num < 0 ) num = -num; + if ( (sint)den < 0 ) den = -den; +#endif + + /* Left-justify denominator and count shift */ + while ( (sint)den >= 0 ) { + den <<= 1; + qbit <<= 1; + } + + while ( qbit ) { + if ( den <= num ) { + num -= den; + quot += qbit; + } + den >>= 1; + qbit >>= 1; + } + + v = (xint)(REM ? num : quot); + if ( minus ) v = -v; + return v; +} diff --git a/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h b/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..9dc570a6f5 --- /dev/null +++ b/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h @@ -0,0 +1,33 @@ +/* + * arch/alpha/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __s0; + unsigned long __s1; + unsigned long __s2; + unsigned long __s3; + unsigned long __s4; + unsigned long __s5; + unsigned long __fp; + unsigned long __ra; + unsigned long __gp; + unsigned long __sp; + + unsigned long __f2; + unsigned long __f3; + unsigned long __f4; + unsigned long __f5; + unsigned long __f6; + unsigned long __f7; + unsigned long __f8; + unsigned long __f9; +}; + +/* Must be an array so it will decay to a pointer when a function is called */ +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/klibc/arch/alpha/include/klibc/archsys.h b/klibc/klibc/arch/alpha/include/klibc/archsys.h new file mode 100644 index 0000000000..16ed658987 --- /dev/null +++ b/klibc/klibc/arch/alpha/include/klibc/archsys.h @@ -0,0 +1,53 @@ +/* + * arch/alpha/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* Alpha has some bizarre Tru64-derived system calls which return two + different values in $0 and $20(!), respectively. The standard + macros can't deal with these; even the ones that give the right + return value have the wrong clobbers. */ + +#define _syscall0_dual0(type, name) \ +type name(void) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_19 __asm__("$19"); \ + register long _sc_20 __asm__("$20"); \ + \ + _sc_0 = __NR_##name; \ + __asm__("callsys" \ + : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ + : "0"(_sc_0) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; (void)(_sc_20); \ + } \ + _syscall_return(type); \ +} + +#define _syscall0_dual1(type, name) \ +type name(void) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_19 __asm__("$19"); \ + register long _sc_20 __asm__("$20"); \ + \ + _sc_0 = __NR_##name; \ + __asm__("callsys" \ + : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ + : "0"(_sc_0) \ + : _syscall_clobbers); \ + _sc_ret = _sc_20, _sc_err = _sc_19; (void)(_sc_0); \ + } \ + _syscall_return(type); \ +} + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/alpha/include/machine/asm.h b/klibc/klibc/arch/alpha/include/machine/asm.h new file mode 100644 index 0000000000..e22db90412 --- /dev/null +++ b/klibc/klibc/arch/alpha/include/machine/asm.h @@ -0,0 +1,44 @@ +/* + * machine/asm.h + */ + +#ifndef _MACHINE_ASM_H +#define _MACHINE_ASM_H + +/* Standard aliases for Alpha register names */ + +#define v0 $0 +#define t0 $1 +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 +#define s0 $9 +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define fp $15 +#define a0 $16 +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 +#define t8 $22 +#define t9 $23 +#define t10 $24 +#define t11 $25 +#define ra $26 +#define t12 $27 /* t12 and pv are both used for $27 */ +#define pv $27 /* t12 and pv are both used for $27 */ +#define at $28 +#define gp $29 +#define sp $30 +#define zero $31 + +#endif /* _MACHINE_ASM_H */ diff --git a/klibc/klibc/arch/alpha/pipe.c b/klibc/klibc/arch/alpha/pipe.c new file mode 100644 index 0000000000..5aee9edbab --- /dev/null +++ b/klibc/klibc/arch/alpha/pipe.c @@ -0,0 +1,28 @@ +#include +#include + +/* pipe() on alpha returns both file descriptors in registers -- + $0 and $20 respectively. This is unlike any other system call, + as far as I can tell. */ + +int pipe(int *fds) +{ + register long sc_0 __asm__("$0"); + register long sc_19 __asm__("$19"); + register long sc_20 __asm__("$20"); + + sc_0 = __NR_pipe; + asm volatile("callsys" : "=r" (sc_0), "=r" (sc_19), "=r" (sc_20) + : "0" (sc_0) + : _syscall_clobbers); + + if ( sc_19 ) { + errno = sc_19; + return -1; + } + + fds[0] = sc_0; + fds[1] = sc_20; + + return 0; +} diff --git a/klibc/klibc/arch/alpha/setjmp.S b/klibc/klibc/arch/alpha/setjmp.S new file mode 100644 index 0000000000..e1ad642539 --- /dev/null +++ b/klibc/klibc/arch/alpha/setjmp.S @@ -0,0 +1,77 @@ +# +# setjmp.S +# + +# +# The jmp_buf looks like: +# +# s0..5 +# fp +# ra +# gp +# sp +# + +#include + + .text + .align 3 + .type setjmp,@function + .ent setjmp, 0 + .globl setjmp +setjmp: + lda v0, 0(zero) + stq s0, 0(a0) + stq s1, 8(a0) + stq s2, 16(a0) + stq s3, 24(a0) + stq s4, 32(a0) + stq s5, 40(a0) + stq fp, 48(a0) + stq ra, 56(a0) + stq gp, 64(a0) + stq sp, 72(a0) + stt f2, 80(a0) + stt f3, 88(a0) + stt f4, 96(a0) + stt f5, 104(a0) + stt f6, 112(a0) + stt f7, 120(a0) + stt f8, 128(a0) + stt f9, 136(a0) + ret zero,(ra),1 + + .size setjmp,.-setjmp + .end setjmp + + .type longjmp,@function + .ent longjmp, 0 + .globl longjmp +longjmp: + mov a1, v0 + ldq s0, 0(a0) + ldq s1, 8(a0) + ldq s2, 16(a0) + ldq s3, 24(a0) + ldq s4, 32(a0) + ldq s5, 40(a0) + ldq fp, 48(a0) + ldq ra, 56(a0) + ldq gp, 64(a0) + ldq sp, 72(a0) + ldt f2, 80(a0) + ldt f3, 88(a0) + ldt f4, 96(a0) + ldt f5, 104(a0) + ldt f6, 112(a0) + ldt f7, 120(a0) + ldt f8, 128(a0) + ldt f9, 136(a0) + /* We're bound to get a mispredict here, but at least give us + a chance to get the return stack back in sync... */ + ret zero,(ra),1 + + .size longjmp,.-longjmp + .end longjmp + + diff --git a/klibc/klibc/arch/arm/MCONFIG b/klibc/klibc/arch/arm/MCONFIG new file mode 100644 index 0000000000..6fbea32903 --- /dev/null +++ b/klibc/klibc/arch/arm/MCONFIG @@ -0,0 +1,26 @@ +# -*- makefile -*- +# +# arch/arm/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +THUMB = n +CPU_ARCH := armv4 +CPU_TUNE := strongarm + +OPTFLAGS = -Os -fomit-frame-pointer -march=$(CPU_ARCH) -mtune=$(CPU_TUNE) +BITSIZE = 32 + +ifeq ($(THUMB),y) +CPU_ARCH := $(CPU_ARCH)t +OPTFLAGS += -mthumb +LDFLAGS += --thumb-entry _start +endif + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +SHAREDFLAGS = -Ttext 0x01000200 diff --git a/klibc/klibc/arch/arm/Makefile.inc b/klibc/klibc/arch/arm/Makefile.inc new file mode 100644 index 0000000000..3ec8c051b2 --- /dev/null +++ b/klibc/klibc/arch/arm/Makefile.inc @@ -0,0 +1,31 @@ +# -*- makefile -*- +# +# arch/arm/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + libgcc/__divsi3.o \ + libgcc/__modsi3.o \ + libgcc/__udivsi3.o \ + libgcc/__umodsi3.o \ + libgcc/__udivmodsi4.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o + +ifeq ($(THUMB),y) +ARCHOBJS += arch/arm/setjmp-thumb.o +LIBGCC = +else +ARCHOBJS += arch/arm/setjmp-arm.o +endif + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + +archclean: diff --git a/klibc/klibc/arch/arm/crt0.S b/klibc/klibc/arch/arm/crt0.S new file mode 100644 index 0000000000..8cd3640c30 --- /dev/null +++ b/klibc/klibc/arch/arm/crt0.S @@ -0,0 +1,25 @@ +# +# arch/arm/crt0.S +# +# void _start(void) +# { +# /* Divine up argc, argv, and envp */ +# environ = envp; +# exit(main(argc, argv, envp)); +# } +# + + .text + .align 4 + .type _start,#function + .globl _start + +#ifdef __thumb__ + .thumb_func +#endif + +_start: mov r0, sp + mov r1, #0 + bl __libc_init + + .size _start,.-_start diff --git a/klibc/klibc/arch/arm/include/klibc/archsetjmp.h b/klibc/klibc/arch/arm/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..c956b50a90 --- /dev/null +++ b/klibc/klibc/arch/arm/include/klibc/archsetjmp.h @@ -0,0 +1,14 @@ +/* + * arch/i386/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned int regs[10]; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/arm/include/klibc/archsys.h b/klibc/klibc/arch/arm/include/klibc/archsys.h new file mode 100644 index 0000000000..1a77e53a65 --- /dev/null +++ b/klibc/klibc/arch/arm/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/arm/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/arm/setjmp-arm.S b/klibc/klibc/arch/arm/setjmp-arm.S new file mode 100644 index 0000000000..bcb30b4221 --- /dev/null +++ b/klibc/klibc/arch/arm/setjmp-arm.S @@ -0,0 +1,40 @@ +# +# arch/arm/setjmp.S +# +# setjmp/longjmp for the ARM architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# r4 +# r5 +# r6 +# r7 +# r8 +# r9 +# r10 +# fp +# sp +# lr +# + + .text + .align 4 + .globl setjmp + .type setjmp, #function +setjmp: + stmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr} + mov r0, #0 + mov pc, lr + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, #function +longjmp: + ldmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr} + movs r0, r1 + moveq r0, #1 + mov pc, lr + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/arm/setjmp-thumb.S b/klibc/klibc/arch/arm/setjmp-thumb.S new file mode 100644 index 0000000000..b581c5f7ad --- /dev/null +++ b/klibc/klibc/arch/arm/setjmp-thumb.S @@ -0,0 +1,58 @@ +# +# arch/arm/setjmp-thumb.S +# +# setjmp/longjmp for the ARM/thumb architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# lr +# r4 +# r5 +# r6 +# r7 +# r8 +# r9 +# r10 +# fp +# sp +# + + .text + .align 4 + .globl setjmp + .type setjmp, #function + .thumb_func +setjmp: + mov r3, lr + stmia r0!, {r3, r4, r5, r6, r7} + mov r3, r8 + mov r4, r9 + mov r5, r10 + mov r6, fp + mov r7, sp + stmia r0!, {r3, r4, r5, r6, r7} + mov r0, #0 + mov pc, lr + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, #function + .thumb_func +longjmp: + mov r2, r0 + add r0, #5*4 + ldmia r0!, {r3, r4, r5, r6, r7} + mov r8, r3 + mov r9, r4 + mov r10, r5 + mov fp, r6 + mov sp, r7 + ldmia r2!, {r3, r4, r5, r6, r7} + mov r0, r1 + bne 1f + mov r0, #1 +1: mov pc, r3 + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/cris/MCONFIG b/klibc/klibc/arch/cris/MCONFIG new file mode 100644 index 0000000000..27809ebbe7 --- /dev/null +++ b/klibc/klibc/arch/cris/MCONFIG @@ -0,0 +1,11 @@ +# -*- makefile -*- +# +# arch/cris/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 diff --git a/klibc/klibc/arch/cris/Makefile.inc b/klibc/klibc/arch/cris/Makefile.inc new file mode 100644 index 0000000000..41183fd64b --- /dev/null +++ b/klibc/klibc/arch/cris/Makefile.inc @@ -0,0 +1,10 @@ +# -*- makefile -*- +# +# arch/cris/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +archclean: diff --git a/klibc/klibc/arch/cris/include/klibc/archsys.h b/klibc/klibc/arch/cris/include/klibc/archsys.h new file mode 100644 index 0000000000..dfdc70a6de --- /dev/null +++ b/klibc/klibc/arch/cris/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/cris/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG new file mode 100644 index 0000000000..367ee89773 --- /dev/null +++ b/klibc/klibc/arch/i386/MCONFIG @@ -0,0 +1,32 @@ +# -*- makefile -*- +# +# arch/i386/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +# Comment this out to compile with register parameter passing +# This doesn't work right now because gcc 3.2 (at least) calls +# libgcc with the default calling convention instead of forcing +# them to be cdecl +# REGPARM = -mregparm=3 -DREGPARM + +gcc_major := $(shell $(CC) -v 2>&1 | awk '/gcc version/{print int($$3)}') + +OPTFLAGS = $(REGPARM) -march=i386 -Os + +ifeq ($(gcc_major),3) +OPTFLAGS += -falign-functions=0 -falign-jumps=0 -falign-loops=0 +else +OPTFLAGS += -malign-functions=0 -malign-jumps=0 -malign-loops=0 +endif + +BITSIZE = 32 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 96 MB - normal binaries start at 128 MB +SHAREDFLAGS = -Ttext 0x06000200 diff --git a/klibc/klibc/arch/i386/Makefile.inc b/klibc/klibc/arch/i386/Makefile.inc new file mode 100644 index 0000000000..171248a796 --- /dev/null +++ b/klibc/klibc/arch/i386/Makefile.inc @@ -0,0 +1,27 @@ +# -*- makefile -*- +# +# arch/i386/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/exits.o \ + arch/$(ARCH)/socketcall.o \ + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/libgcc/__ashldi3.o \ + arch/$(ARCH)/libgcc/__ashrdi3.o \ + arch/$(ARCH)/libgcc/__lshrdi3.o \ + arch/$(ARCH)/libgcc/__muldi3.o \ + arch/$(ARCH)/libgcc/__negdi2.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + +archclean: diff --git a/klibc/klibc/arch/i386/crt0.S b/klibc/klibc/arch/i386/crt0.S new file mode 100644 index 0000000000..1c82eda513 --- /dev/null +++ b/klibc/klibc/arch/i386/crt0.S @@ -0,0 +1,33 @@ +# +# arch/i386/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + + .text + .align 4 + .type _start,@function + .globl _start +_start: + # Save the address of the ELF argument array + movl %esp,%eax # Address of ELF arguments + # Set up a faux stack frame for the benefit of gdb + xorl %ebp,%ebp + push %ebp # Keep gdb from getting confused + push %ebp # Keep gdb from getting confused + # Push the arguments and called __libc_init() +#ifndef REGPARM + push %edx # atexit() function + push %eax # ELF array +#endif + call __libc_init + # If __libc_init returns, problem... + ud2 + hlt + + .size _start, .-_start + diff --git a/klibc/klibc/arch/i386/exits.S b/klibc/klibc/arch/i386/exits.S new file mode 100644 index 0000000000..59ff563ad8 --- /dev/null +++ b/klibc/klibc/arch/i386/exits.S @@ -0,0 +1,45 @@ +# +# exit and _exit get included in *every* program, and gcc generates +# horrible code for them. Yes, this only saves a few bytes, but +# it does it in every program. +# + +#include + + .data + .align 4 + .globl __exit_handler + .type __exit_handler,@object +__exit_handler: + .long _exit + .size __exit_handler,4 + + .text + .align 4 + .globl exit + .type exit,@function +exit: + jmp *(__exit_handler) + .size exit,.-exit + + /* No need to save any registers... we're exiting! */ + .text + .align 4 + .globl _exit + .type _exit,@function +_exit: +#ifdef REGPARM + movl %eax,%ebx +#else + popl %ebx + popl %ebx +#endif +#if __NR_exit == 1 + xorl %eax,%eax + incl %eax +#else + movl $__NR_exit,%eax +#endif + int $0x80 + hlt + .size _exit,.-exit diff --git a/klibc/klibc/arch/i386/include/klibc/archsetjmp.h b/klibc/klibc/arch/i386/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..db04314b8c --- /dev/null +++ b/klibc/klibc/arch/i386/include/klibc/archsetjmp.h @@ -0,0 +1,19 @@ +/* + * arch/i386/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned int __ebx; + unsigned int __esp; + unsigned int __ebp; + unsigned int __esi; + unsigned int __edi; + unsigned int __eip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/i386/include/klibc/archsys.h b/klibc/klibc/arch/i386/include/klibc/archsys.h new file mode 100644 index 0000000000..e21487b256 --- /dev/null +++ b/klibc/klibc/arch/i386/include/klibc/archsys.h @@ -0,0 +1,96 @@ +/* + * arch/i386/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* + * If we're compiling i386 in PIC mode, we need to treat %ebx + * specially. Most of these are copied from the equivalent file in + * newlib and were written by Werner Almesberger. + */ +#if defined(__PIC__) + +/* _syscall0() is the same as non-PIC */ + +#undef _syscall1 +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ +long __res; \ +__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall2 +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall3 +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall4 +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ +long __res; \ +__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall5 +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ + : "=a" (__res) \ + : "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ +__syscall_return(type,__res); \ +} + +#undef _syscall6 +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ +__asm__ __volatile__ ("push %%ebx; pushl %%ebp; movl %2,%%ebx; " \ + "movl %%eax,%%ebp; movl %1,%%eax; int $0x80; " \ + "pop %%ebp ; pop %%ebx" \ + : "=a" (__res) \ + : "i" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \ + "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \ + "a" ((long)(arg6))); \ +__syscall_return(type,__res); \ +} + +#endif /* __PIC__ */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/i386/include/klibc/diverr.h b/klibc/klibc/arch/i386/include/klibc/diverr.h new file mode 100644 index 0000000000..410aba06d3 --- /dev/null +++ b/klibc/klibc/arch/i386/include/klibc/diverr.h @@ -0,0 +1,16 @@ +/* + * arch/i386/include/klibc/diverr.h + */ + +#ifndef _KLIBC_DIVERR_H +#define _KLIBC_DIVERR_H + +#include + +static __inline__ void +__divide_error(void) +{ + asm volatile("divl %0" :: "rm" (0) : "eax", "edx"); +} + +#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/klibc/arch/i386/libgcc/__ashldi3.S b/klibc/klibc/arch/i386/libgcc/__ashldi3.S new file mode 100644 index 0000000000..80ed4be3cf --- /dev/null +++ b/klibc/klibc/arch/i386/libgcc/__ashldi3.S @@ -0,0 +1,29 @@ +/* + * arch/i386/libgcc/__ashldi3.S + * + * 64-bit shl + */ + .text + .align 4 + .globl __ashldi3 + .type __ashldi3,@function +__ashldi3: +#ifndef REGPARM + movl 4(%esp),%eax + movl 8(%esp),%edx + movb 12(%esp),%cl +#endif + cmpb $32,%cl + jae 1f + + shldl %cl,%eax,%edx + shl %cl,%eax + ret + +1: + xorl %edx,%edx + shl %cl,%eax + xchgl %edx,%eax + ret + + .size __ashldi3,.-__ashldi3 diff --git a/klibc/klibc/arch/i386/libgcc/__ashrdi3.S b/klibc/klibc/arch/i386/libgcc/__ashrdi3.S new file mode 100644 index 0000000000..ba43f9022a --- /dev/null +++ b/klibc/klibc/arch/i386/libgcc/__ashrdi3.S @@ -0,0 +1,29 @@ +/* + * arch/i386/libgcc/__ashrdi3.S + * + * 64-bit sar + */ + .text + .align 4 + .globl __ashrdi3 + .type __ashrdi3,@function +__ashrdi3: +#ifndef REGPARM + movl 4(%esp),%eax + movl 8(%esp),%edx + movb 12(%esp),%cl +#endif + cmpb $32,%cl + jae 1f + + shrdl %cl,%edx,%eax + sarl %cl,%edx + ret + +1: + sarl %cl,%edx + movl %edx,%eax + cdq + ret + + .size __ashrdi3,.-__ashrdi3 diff --git a/klibc/klibc/arch/i386/libgcc/__lshrdi3.S b/klibc/klibc/arch/i386/libgcc/__lshrdi3.S new file mode 100644 index 0000000000..6e521ace2c --- /dev/null +++ b/klibc/klibc/arch/i386/libgcc/__lshrdi3.S @@ -0,0 +1,29 @@ +/* + * arch/i386/libgcc/__lshrdi3.S + * + * 64-bit shr + */ + .text + .align 4 + .globl __lshrdi3 + .type __lshrdi3,@function +__lshrdi3: +#ifndef REGPARM + movl 4(%esp),%eax + movl 8(%esp),%edx + movb 12(%esp),%cl +#endif + cmpb $32,%cl + jae 1f + + shrdl %cl,%edx,%eax + shrl %cl,%edx + ret + +1: + shrl %cl,%edx + xorl %eax,%eax + xchgl %edx,%eax + ret + + .size __lshrdi3,.-__lshrdi3 diff --git a/klibc/klibc/arch/i386/libgcc/__muldi3.S b/klibc/klibc/arch/i386/libgcc/__muldi3.S new file mode 100644 index 0000000000..c164588b16 --- /dev/null +++ b/klibc/klibc/arch/i386/libgcc/__muldi3.S @@ -0,0 +1,34 @@ +/* + * arch/i386/libgcc/__muldi3.S + * + * 64*64 = 64 bit unsigned multiplication + */ + + .text + .align 4 + .globl __muldi3 + .type __muldi3,@function +__muldi3: + push %esi +#ifndef REGPARM + movl 8(%esp),%eax + movl %eax,%esi + movl 16(%esp),%ecx + mull %ecx + imull 12(%esp),%ecx + imull 20(%esp),%esi + addl %ecx,%edx + addl %esi,%edx +#else + movl %eax,%esi + push %edx + mull %ecx + imull 8(%esp),%esi + addl %esi,%edx + pop %esi + imull %esi,%ecx + addl %ecx,%edx +#endif + pop %esi + ret + .size __muldi3,.-__muldi3 diff --git a/klibc/klibc/arch/i386/libgcc/__negdi2.S b/klibc/klibc/arch/i386/libgcc/__negdi2.S new file mode 100644 index 0000000000..6c95cb235c --- /dev/null +++ b/klibc/klibc/arch/i386/libgcc/__negdi2.S @@ -0,0 +1,21 @@ +/* + * arch/i386/libgcc/__negdi2.S + * + * 64-bit negation + */ + + .text + .align 4 + .globl __negdi2 + .type __negdi2,@function +__negdi2: +#ifndef REGPARM + movl 4(%esp),%eax + movl 8(%esp),%edx +#endif + negl %edx + negl %eax + sbbl $0,%edx + ret + + .size __negdi2,.-__negdi2 diff --git a/klibc/klibc/arch/i386/setjmp.S b/klibc/klibc/arch/i386/setjmp.S new file mode 100644 index 0000000000..bea900c519 --- /dev/null +++ b/klibc/klibc/arch/i386/setjmp.S @@ -0,0 +1,58 @@ +# +# arch/i386/setjmp.S +# +# setjmp/longjmp for the i386 architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# %ebx +# %esp +# %ebp +# %esi +# %edi +# +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: +#ifdef REGPARM + movl %eax,%edx +#else + movl 4(%esp),%edx +#endif + popl %ecx # Return address, and adjust the stack + xorl %eax,%eax # Return value + movl %ebx,(%edx) + movl %esp,4(%edx) # Post-return %esp! + pushl %ecx # Make the call/return stack happy + movl %ebp,8(%edx) + movl %esi,12(%edx) + movl %edi,16(%edx) + movl %ecx,20(%edx) # Return address + ret + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: +#ifdef REGPARM + xchgl %eax,%edx +#else + movl 4(%esp),%edx # jmp_ptr address + movl 8(%esp),%eax # Return value +#endif + movl (%edx),%ebx + movl 4(%edx),%esp + movl 8(%edx),%ebp + movl 12(%edx),%esi + movl 16(%edx),%edi + jmp *20(%edx) + + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/i386/socketcall.S b/klibc/klibc/arch/i386/socketcall.S new file mode 100644 index 0000000000..6bac1e6913 --- /dev/null +++ b/klibc/klibc/arch/i386/socketcall.S @@ -0,0 +1,38 @@ +# +# socketcall.S +# +# On i386, the main (only?) user of socketcall(2), the memory array +# socketcall(2) needs is conveniently already assembled for us on +# the stack. Capitalize on that to make a common socketcall stub. +# + +#include + +#ifdef __i386__ + + .text + .align 4 + .globl __socketcall_common + .type __socketcall_common, @function + +__socketcall_common: + pushl %ebx + movzbl %al,%ebx # The socketcall number is passed in in %al + leal 8(%esp),%ecx # Argument pointer + movl $__NR_socketcall, %eax + int $0x80 + cmpl $-125,%eax # Error return? + popl %ebx + jb 1f + neg %eax + movl %eax,errno + xorl %eax,%eax + decl %eax # Return = -1 +1: + ret + + .size __socketcall_common,.-__socketcall_common + +#endif + + diff --git a/klibc/klibc/arch/ia64/MCONFIG b/klibc/klibc/arch/ia64/MCONFIG new file mode 100644 index 0000000000..631a478e4f --- /dev/null +++ b/klibc/klibc/arch/ia64/MCONFIG @@ -0,0 +1,11 @@ +# -*- makefile -*- +# +# arch/ia64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 64 diff --git a/klibc/klibc/arch/ia64/Makefile.inc b/klibc/klibc/arch/ia64/Makefile.inc new file mode 100644 index 0000000000..1fb364f92e --- /dev/null +++ b/klibc/klibc/arch/ia64/Makefile.inc @@ -0,0 +1,10 @@ +# -*- makefile -*- +# +# arch/ia64/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +archclean: diff --git a/klibc/klibc/arch/ia64/include/klibc/archsys.h b/klibc/klibc/arch/ia64/include/klibc/archsys.h new file mode 100644 index 0000000000..ef5940ac25 --- /dev/null +++ b/klibc/klibc/arch/ia64/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/ia64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/m68k/MCONFIG b/klibc/klibc/arch/m68k/MCONFIG new file mode 100644 index 0000000000..2ba69b3178 --- /dev/null +++ b/klibc/klibc/arch/m68k/MCONFIG @@ -0,0 +1,11 @@ +# -*- makefile -*- +# +# arch/m68k/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 diff --git a/klibc/klibc/arch/m68k/Makefile.inc b/klibc/klibc/arch/m68k/Makefile.inc new file mode 100644 index 0000000000..9abec14db1 --- /dev/null +++ b/klibc/klibc/arch/m68k/Makefile.inc @@ -0,0 +1,10 @@ +# -*- makefile -*- +# +# arch/m68k/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +archclean: diff --git a/klibc/klibc/arch/m68k/include/klibc/archsys.h b/klibc/klibc/arch/m68k/include/klibc/archsys.h new file mode 100644 index 0000000000..8f6bed8e94 --- /dev/null +++ b/klibc/klibc/arch/m68k/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/m68k/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/mips/MCONFIG b/klibc/klibc/arch/mips/MCONFIG new file mode 100644 index 0000000000..52b518461f --- /dev/null +++ b/klibc/klibc/arch/mips/MCONFIG @@ -0,0 +1,18 @@ +# -*- makefile -*- +# +# arch/mips/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHREQFLAGS = -fno-pic -mno-abicalls +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 2 MB -- the normal starting point for text is 4 MB. +SHAREDFLAGS = -Ttext 0x00200200 diff --git a/klibc/klibc/arch/mips/Makefile.inc b/klibc/klibc/arch/mips/Makefile.inc new file mode 100644 index 0000000000..09a2d2f736 --- /dev/null +++ b/klibc/klibc/arch/mips/Makefile.inc @@ -0,0 +1,24 @@ +# -*- makefile -*- +# +# arch/mips/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/pipe.o \ + arch/$(ARCH)/vfork.o \ + arch/$(ARCH)/setjmp.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o + + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + + +archclean: diff --git a/klibc/klibc/arch/mips/crt0.S b/klibc/klibc/arch/mips/crt0.S new file mode 100644 index 0000000000..42d9dd5e38 --- /dev/null +++ b/klibc/klibc/arch/mips/crt0.S @@ -0,0 +1,25 @@ +# +# arch/mips/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + +#include + +NESTED(__start, 32, sp) + subu sp, 32 + sw zero, 16(sp) + + lui gp, %hi(_gp) # Initialize gp + addiu gp, gp, _gp + + addiu a0, sp, 32 # Pointer to ELF entry structure + move a1, v0 # Kernel-provided atexit() pointer + + jal __libc_init + + END(__start) diff --git a/klibc/klibc/arch/mips/include/klibc/archsetjmp.h b/klibc/klibc/arch/mips/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..40e5be2736 --- /dev/null +++ b/klibc/klibc/arch/mips/include/klibc/archsetjmp.h @@ -0,0 +1,39 @@ +/* + * arch/mips/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __s0; + unsigned long __s1; + unsigned long __s2; + unsigned long __s3; + unsigned long __s4; + unsigned long __s5; + unsigned long __s6; + unsigned long __s7; + unsigned long __gp; + unsigned long __sp; + unsigned long __s8; + unsigned long __ra; + unsigned long __f20; + unsigned long __f21; + unsigned long __f22; + unsigned long __f23; + unsigned long __f24; + unsigned long __f25; + unsigned long __f26; + unsigned long __f27; + unsigned long __f28; + unsigned long __f29; + unsigned long __f30; + unsigned long __f31; + unsigned long __fcr31; + unsigned long __unused; +} __attribute__((aligned(8))); + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/klibc/arch/mips/include/klibc/archsys.h b/klibc/klibc/arch/mips/include/klibc/archsys.h new file mode 100644 index 0000000000..f696cdfaa7 --- /dev/null +++ b/klibc/klibc/arch/mips/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/mips/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/mips/include/machine/asm.h b/klibc/klibc/arch/mips/include/machine/asm.h new file mode 100644 index 0000000000..e5239a6cef --- /dev/null +++ b/klibc/klibc/arch/mips/include/machine/asm.h @@ -0,0 +1,11 @@ +/* + * arch/mips/include/machine/asm.h + */ + +#ifndef _MACHINE_ASM_H +#define _MACHINE_ASM_H + +#include +#include + +#endif /* _MACHINE_ASM_H */ diff --git a/klibc/klibc/arch/mips/include/sgidefs.h b/klibc/klibc/arch/mips/include/sgidefs.h new file mode 100644 index 0000000000..eb103ace2c --- /dev/null +++ b/klibc/klibc/arch/mips/include/sgidefs.h @@ -0,0 +1,20 @@ +/* + * arch/mips/include/sgidefs.h + */ + +/* Some ABI constants */ + +#ifndef _SGIDEFS_H +#define _SGIDEFS_H + +#define _MIPS_ISA_MIPS1 1 +#define _MIPS_ISA_MIPS2 2 +#define _MIPS_ISA_MIPS3 3 +#define _MIPS_ISA_MIPS4 4 +#define _MIPS_ISA_MIPS5 5 + +#define _MIPS_SIM_ABI32 1 +#define _MIPS_SIM_NABI32 2 +#define _MIPS_SIM_ABI64 3 + +#endif /* _SGIDEFS_H */ diff --git a/klibc/klibc/arch/mips/pipe.S b/klibc/klibc/arch/mips/pipe.S new file mode 100644 index 0000000000..d79f614025 --- /dev/null +++ b/klibc/klibc/arch/mips/pipe.S @@ -0,0 +1,16 @@ +#include +#include +#include + +LEAF(pipe) + li v0, __NR_pipe + syscall + bnez a3, 1f + sw v0, (a0) + sw v1, (a1) + li v0, 0 + b 2f +1: sw v0, errno + li v0, -1 +2: jr ra + END(pipe) diff --git a/klibc/klibc/arch/mips/setjmp.S b/klibc/klibc/arch/mips/setjmp.S new file mode 100644 index 0000000000..4d293757ec --- /dev/null +++ b/klibc/klibc/arch/mips/setjmp.S @@ -0,0 +1,82 @@ +# +# arch/mips/setjmp.S +# +# setjmp/longjmp for the MIPS architecture +# +# The jmp_buf is assumed to contain the following, in order: +# s0..s7 +# gp +# sp +# s8 +# ra +# f20..f31 +# fcr31 +# + +#include + +LEAF(setjmp) + sw s0, 0(a0) + sw s1, 4(a0) + sw s2, 8(a0) + sw s3, 12(a0) + sw s4, 16(a0) + sw s5, 20(a0) + sw s6, 24(a0) + sw s7, 28(a0) + sw gp, 32(a0) + sw sp, 36(a0) + sw s8, 40(a0) + sw ra, 44(a0) + cfc1 t0,$31 + swc1 $f20,48(a0) + swc1 $f21,52(a0) + swc1 $f22,56(a0) + swc1 $f23,60(a0) + swc1 $f24,64(a0) + swc1 $f25,68(a0) + swc1 $f26,72(a0) + swc1 $f27,76(a0) + swc1 $f28,80(a0) + swc1 $f29,84(a0) + swc1 $f30,88(a0) + swc1 $f31,92(a0) + sw t0,96(a0) + move v0,zero + jr ra + + END(setjmp) + +LEAF(longjmp) + lw s0, 0(a0) + lw s1, 4(a0) + lw s2, 8(a0) + lw s3, 12(a0) + lw s4, 16(a0) + lw s5, 20(a0) + lw s6, 24(a0) + lw s7, 28(a0) + lw gp, 32(a0) + lw sp, 36(a0) + lw s8, 40(a0) + lw ra, 44(a0) + lw t0, 96(a0) + lwc1 $f20,48(a0) + lwc1 $f21,52(a0) + lwc1 $f22,56(a0) + lwc1 $f23,60(a0) + lwc1 $f24,64(a0) + lwc1 $f25,68(a0) + lwc1 $f26,72(a0) + lwc1 $f27,76(a0) + lwc1 $f28,80(a0) + lwc1 $f29,84(a0) + lwc1 $f30,88(a0) + lwc1 $f31,92(a0) + ctc1 t0,$31 + move v0,a1 + jr ra + + END(longjmp) + + \ No newline at end of file diff --git a/klibc/klibc/arch/mips/vfork.S b/klibc/klibc/arch/mips/vfork.S new file mode 100644 index 0000000000..aca8083aa4 --- /dev/null +++ b/klibc/klibc/arch/mips/vfork.S @@ -0,0 +1,19 @@ +#include +#include +#include + +#define CLONE_VM 0x00000100 +#define CLONE_VFORK 0x00004000 +#define SIGCHLD 18 + +LEAF(vfork) + li a0, CLONE_VFORK | CLONE_VM | SIGCHLD + li a1, 0 + li v0, __NR_clone + syscall + bnez a3, 1f + b 2f +1: sw v0, errno + li v0, -1 +2: jr ra + END(vfork) diff --git a/klibc/klibc/arch/mips64/MCONFIG b/klibc/klibc/arch/mips64/MCONFIG new file mode 100644 index 0000000000..6a817e54b6 --- /dev/null +++ b/klibc/klibc/arch/mips64/MCONFIG @@ -0,0 +1,11 @@ +# -*- makefile -*- +# +# arch/mips64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 64 diff --git a/klibc/klibc/arch/mips64/Makefile.inc b/klibc/klibc/arch/mips64/Makefile.inc new file mode 100644 index 0000000000..4a9529adca --- /dev/null +++ b/klibc/klibc/arch/mips64/Makefile.inc @@ -0,0 +1,10 @@ +# -*- makefile -*- +# +# arch/mips64/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +archclean: diff --git a/klibc/klibc/arch/mips64/include/klibc/archsys.h b/klibc/klibc/arch/mips64/include/klibc/archsys.h new file mode 100644 index 0000000000..81e5106e16 --- /dev/null +++ b/klibc/klibc/arch/mips64/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/mips64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/parisc/MCONFIG b/klibc/klibc/arch/parisc/MCONFIG new file mode 100644 index 0000000000..93a31707c6 --- /dev/null +++ b/klibc/klibc/arch/parisc/MCONFIG @@ -0,0 +1,11 @@ +# -*- makefile -*- +# +# arch/parisc/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 diff --git a/klibc/klibc/arch/parisc/Makefile.inc b/klibc/klibc/arch/parisc/Makefile.inc new file mode 100644 index 0000000000..f7a983da7f --- /dev/null +++ b/klibc/klibc/arch/parisc/Makefile.inc @@ -0,0 +1,10 @@ +# -*- makefile -*- +# +# arch/parisc/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +archclean: diff --git a/klibc/klibc/arch/parisc/include/klibc/archsys.h b/klibc/klibc/arch/parisc/include/klibc/archsys.h new file mode 100644 index 0000000000..5013ba8794 --- /dev/null +++ b/klibc/klibc/arch/parisc/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/parisc/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/ppc/MCONFIG b/klibc/klibc/arch/ppc/MCONFIG new file mode 100644 index 0000000000..fcb0992150 --- /dev/null +++ b/klibc/klibc/arch/ppc/MCONFIG @@ -0,0 +1,11 @@ +# -*- makefile -*- +# +# arch/ppc/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 diff --git a/klibc/klibc/arch/ppc/Makefile.inc b/klibc/klibc/arch/ppc/Makefile.inc new file mode 100644 index 0000000000..6e87a48d6b --- /dev/null +++ b/klibc/klibc/arch/ppc/Makefile.inc @@ -0,0 +1,15 @@ +# -*- makefile -*- +# +# arch/ppc/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/setjmp.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + +archclean: diff --git a/klibc/klibc/arch/ppc/crt0.S b/klibc/klibc/arch/ppc/crt0.S new file mode 100644 index 0000000000..f7274b07dd --- /dev/null +++ b/klibc/klibc/arch/ppc/crt0.S @@ -0,0 +1,29 @@ +# +# arch/ppc/crt0.S +# +# void _start(void) +# { +# /* Divine up argc, argv, and envp */ +# environ = envp; +# exit(main(argc, argv, envp)); +# } +# + + .text + .align 4 + .type _start,@function + .globl _start +_start: + lwz 3,0(1) + addi 4,1,4 + addi 5,1,8 + slwi 0,3,2 + add 5,5,0 + li 0,0 + stwu 0,-16(1) + lis 9,environ@ha + stw 5,environ@l(9) + bl main + bl exit + + .size _start,.-_start diff --git a/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h b/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..53e2fccc3b --- /dev/null +++ b/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h @@ -0,0 +1,36 @@ +/* + * arch/ppc/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r2; + unsigned long __sp; + unsigned long __lr; + unsigned long __cr; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __r16; + unsigned long __r17; + unsigned long __r18; + unsigned long __r19; + unsigned long __r20; + unsigned long __r21; + unsigned long __r22; + unsigned long __r23; + unsigned long __r24; + unsigned long __r25; + unsigned long __r26; + unsigned long __r27; + unsigned long __r28; + unsigned long __r29; + unsigned long __r30; + unsigned long __r31; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/ppc/include/klibc/archsys.h b/klibc/klibc/arch/ppc/include/klibc/archsys.h new file mode 100644 index 0000000000..33a5ff3236 --- /dev/null +++ b/klibc/klibc/arch/ppc/include/klibc/archsys.h @@ -0,0 +1,55 @@ +/* + * arch/ppc/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* PowerPC seems to lack _syscall6() in its headers */ +/* This seems to work on both 32- and 64-bit ppc */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ + unsigned long __sc_ret, __sc_err; \ + { \ + register unsigned long __sc_0 __asm__ ("r0"); \ + register unsigned long __sc_3 __asm__ ("r3"); \ + register unsigned long __sc_4 __asm__ ("r4"); \ + register unsigned long __sc_5 __asm__ ("r5"); \ + register unsigned long __sc_6 __asm__ ("r6"); \ + register unsigned long __sc_7 __asm__ ("r7"); \ + register unsigned long __sc_8 __asm__ ("r8"); \ + \ + __sc_3 = (unsigned long) (arg1); \ + __sc_4 = (unsigned long) (arg2); \ + __sc_5 = (unsigned long) (arg3); \ + __sc_6 = (unsigned long) (arg4); \ + __sc_7 = (unsigned long) (arg5); \ + __sc_8 = (unsigned long) (arg6); \ + __sc_0 = __NR_##name; \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %1 " \ + : "=&r" (__sc_3), "=&r" (__sc_0) \ + : "0" (__sc_3), "1" (__sc_0), \ + "r" (__sc_4), \ + "r" (__sc_5), \ + "r" (__sc_6), \ + "r" (__sc_7), \ + "r" (__sc_8) \ + : __syscall_clobbers); \ + __sc_ret = __sc_3; \ + __sc_err = __sc_0; \ + } \ + __syscall_return (type); \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/ppc/setjmp.S b/klibc/klibc/arch/ppc/setjmp.S new file mode 100644 index 0000000000..1c50301707 --- /dev/null +++ b/klibc/klibc/arch/ppc/setjmp.S @@ -0,0 +1,35 @@ +# +# arch/ppc/setjmp.S +# +# Basic setjmp/longjmp implementation +# This file was derived from the equivalent file in NetBSD +# + + .text + .align 4 + .type setjmp,@function + .globl setjmp +setjmp: + mflr %r11 /* save return address */ + mfcr %r12 /* save condition register */ + mr %r10,%r1 /* save stack pointer */ + mr %r9,%r2 /* save GPR2 (not needed) */ + stmw %r9,0(%r3) /* save r9..r31 */ + li %r3,0 /* indicate success */ + blr /* return */ + + .size setjmp,.-setjmp + + .type longjmp,@function + .globl longjmp +longjmp: + lmw %r9,0(%r3) /* save r9..r31 */ + mtlr %r11 /* restore LR */ + mtcr %r12 /* restore CR */ + mr %r2,%r9 /* restore GPR2 (not needed) */ + mr %r1,%r10 /* restore stack */ + mr %r3,%r4 /* get return value */ + blr /* return */ + + .size longjmp,.-longjmp + \ No newline at end of file diff --git a/klibc/klibc/arch/ppc64/MCONFIG b/klibc/klibc/arch/ppc64/MCONFIG new file mode 100644 index 0000000000..6997693e99 --- /dev/null +++ b/klibc/klibc/arch/ppc64/MCONFIG @@ -0,0 +1,11 @@ +# -*- makefile -*- +# +# arch/ppc64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 64 diff --git a/klibc/klibc/arch/ppc64/Makefile.inc b/klibc/klibc/arch/ppc64/Makefile.inc new file mode 100644 index 0000000000..434d0aad96 --- /dev/null +++ b/klibc/klibc/arch/ppc64/Makefile.inc @@ -0,0 +1,10 @@ +# -*- makefile -*- +# +# arch/ppc64/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +archclean: diff --git a/klibc/klibc/arch/ppc64/crt0.S b/klibc/klibc/arch/ppc64/crt0.S new file mode 100644 index 0000000000..2f352e8045 --- /dev/null +++ b/klibc/klibc/arch/ppc64/crt0.S @@ -0,0 +1,38 @@ +# +# arch/ppc64/crt0.S +# +# void _start(void) +# { +# /* Divine up argc, argv, and envp */ +# environ = envp; +# exit(main(argc, argv, envp)); +# } +# + + .section ".toc","aw" +.LC0: .tc environ[TC],environ + + .section ".opd","aw" + .align 3 + .globl _start +_start: + .quad ._start + .quad .TOC.@tocbase, 0 + + .text + .globl ._start + .type ._start,@function +._start: + ld 3,0(1) + ld 4,8(1) + ld 5,16(1) + li 0,0 + stdu 0,-64(1) + ld 9,.LC0@toc(2) + std 5,0(9) + bl .main + nop + bl .exit + nop + + .size _start,.-_start diff --git a/klibc/klibc/arch/ppc64/include/klibc/archsys.h b/klibc/klibc/arch/ppc64/include/klibc/archsys.h new file mode 100644 index 0000000000..4f81fee00d --- /dev/null +++ b/klibc/klibc/arch/ppc64/include/klibc/archsys.h @@ -0,0 +1,52 @@ +/* + * arch/ppc64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ + unsigned long __sc_ret, __sc_err; \ + { \ + register unsigned long __sc_0 __asm__ ("r0"); \ + register unsigned long __sc_3 __asm__ ("r3"); \ + register unsigned long __sc_4 __asm__ ("r4"); \ + register unsigned long __sc_5 __asm__ ("r5"); \ + register unsigned long __sc_6 __asm__ ("r6"); \ + register unsigned long __sc_7 __asm__ ("r7"); \ + register unsigned long __sc_8 __asm__ ("r8"); \ + \ + __sc_3 = (unsigned long) (arg1); \ + __sc_4 = (unsigned long) (arg2); \ + __sc_5 = (unsigned long) (arg3); \ + __sc_6 = (unsigned long) (arg4); \ + __sc_7 = (unsigned long) (arg5); \ + __sc_8 = (unsigned long) (arg6); \ + __sc_0 = __NR_##name; \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %1 " \ + : "=&r" (__sc_3), "=&r" (__sc_0) \ + : "0" (__sc_3), "1" (__sc_0), \ + "r" (__sc_4), \ + "r" (__sc_5), \ + "r" (__sc_6), \ + "r" (__sc_7), \ + "r" (__sc_8) \ + : __syscall_clobbers); \ + __sc_ret = __sc_3; \ + __sc_err = __sc_0; \ + } \ + __syscall_return (type); \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/s390/MCONFIG b/klibc/klibc/arch/s390/MCONFIG new file mode 100644 index 0000000000..e32c33faa1 --- /dev/null +++ b/klibc/klibc/arch/s390/MCONFIG @@ -0,0 +1,13 @@ +# -*- makefile -*- +# +# arch/s390/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 + +SHAREDFLAGS = -Ttext 0x40000200 diff --git a/klibc/klibc/arch/s390/Makefile.inc b/klibc/klibc/arch/s390/Makefile.inc new file mode 100644 index 0000000000..45aa551695 --- /dev/null +++ b/klibc/klibc/arch/s390/Makefile.inc @@ -0,0 +1,16 @@ +# -*- makefile -*- +# +# arch/s390/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/setjmp.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + + +archclean: diff --git a/klibc/klibc/arch/s390/crt0.S b/klibc/klibc/arch/s390/crt0.S new file mode 100644 index 0000000000..49c3e7ebc7 --- /dev/null +++ b/klibc/klibc/arch/s390/crt0.S @@ -0,0 +1,25 @@ +# +# arch/s390/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + .text + .align 4 + .type _start,@function + .globl _start +_start: + lr %r2,%r15 + lhi %r3,0 + ahi %r15,-96 + bras %r1,.L0 +.L0: + l %r1,.L1-.L0(%r1) + br %r1 +.L1: + .long __libc_init + + .size _start,.-_start diff --git a/klibc/klibc/arch/s390/include/klibc/archsetjmp.h b/klibc/klibc/arch/s390/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..11a641ed5a --- /dev/null +++ b/klibc/klibc/arch/s390/include/klibc/archsetjmp.h @@ -0,0 +1,15 @@ +/* + * arch/s390/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + uint32_t __gregs[10]; /* general registers r6-r15 */ + uint64_t __fpregs[2]; /* fp registers f4 and f6 */ +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/s390/include/klibc/archsys.h b/klibc/klibc/arch/s390/include/klibc/archsys.h new file mode 100644 index 0000000000..1cd0948f3c --- /dev/null +++ b/klibc/klibc/arch/s390/include/klibc/archsys.h @@ -0,0 +1,41 @@ +/* + * arch/s390/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* S/390 only has five syscall parameters, and uses a structure for + 6-argument syscalls. */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ + type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5, type6 arg6) { \ + unsigned long __arg[6] = { \ + (unsigned long) arg1, \ + (unsigned long) arg2, \ + (unsigned long) arg3, \ + (unsigned long) arg4, \ + (unsigned long) arg5, \ + (unsigned long) arg6 \ + }; \ + register void *__argp asm("2") = &__arg; \ + long __res; \ + __asm__ __volatile__ ( \ + " svc %b1\n" \ + " lr %0,2" \ + : "=d" (__res) \ + : "i" (__NR_##name), \ + "d" (__argp) \ + : _svc_clobber); \ + __syscall_return(type, __res); \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/s390/setjmp.S b/klibc/klibc/arch/s390/setjmp.S new file mode 100644 index 0000000000..97132680ae --- /dev/null +++ b/klibc/klibc/arch/s390/setjmp.S @@ -0,0 +1,32 @@ +# +# arch/s390/setjmp.S +# +# setjmp/longjmp for the s390 architecture +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: + stm %r6,%r15,0(%r2) # save all general registers + std %f4,40(%r2) # save fp registers f4 and f6 + std %f6,48(%r2) + lhi %r2,0 # return 0 + br %r14 + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: + lr %r1,%r2 # jmp_buf + lr %r2,%r3 # return value + ld %f6,48(%r1) # restore all saved registers + ld %f4,40(%r1) + lm %r6,%r15,0(%r1) + br %r14 # return to restored address + + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/s390x/MCONFIG b/klibc/klibc/arch/s390x/MCONFIG new file mode 100644 index 0000000000..1c8232bed5 --- /dev/null +++ b/klibc/klibc/arch/s390x/MCONFIG @@ -0,0 +1,13 @@ +# -*- makefile -*- +# +# arch/s390x/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 64 + +SHAREDFLAGS = -Ttext 0x40000200 diff --git a/klibc/klibc/arch/s390x/Makefile.inc b/klibc/klibc/arch/s390x/Makefile.inc new file mode 100644 index 0000000000..eff8f951ac --- /dev/null +++ b/klibc/klibc/arch/s390x/Makefile.inc @@ -0,0 +1,16 @@ +# -*- makefile -*- +# +# arch/s390x/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/setjmp.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + + +archclean: diff --git a/klibc/klibc/arch/s390x/crt0.S b/klibc/klibc/arch/s390x/crt0.S new file mode 100644 index 0000000000..de35664904 --- /dev/null +++ b/klibc/klibc/arch/s390x/crt0.S @@ -0,0 +1,21 @@ +# +# arch/s390/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + + .text + .align 4 + .type _start,@function + .globl _start +_start: + lgr %r2,%r15 + lghi %r3,0 + aghi %r15,-160 + jg __libc_init + + .size _start,.-_start diff --git a/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h b/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..dd3ed0d47c --- /dev/null +++ b/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h @@ -0,0 +1,15 @@ +/* + * arch/s390x/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + uint64_t __gregs[10]; /* general registers r6-r15 */ + uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */ +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/s390x/include/klibc/archsys.h b/klibc/klibc/arch/s390x/include/klibc/archsys.h new file mode 100644 index 0000000000..15f7113bb4 --- /dev/null +++ b/klibc/klibc/arch/s390x/include/klibc/archsys.h @@ -0,0 +1,41 @@ +/* + * arch/s390x/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* S/390X only has five syscall parameters, and uses a structure for + 6-argument syscalls. */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ + type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5, type6 arg6) { \ + unsigned long __arg[6] = { \ + (unsigned long) arg1, \ + (unsigned long) arg2, \ + (unsigned long) arg3, \ + (unsigned long) arg4, \ + (unsigned long) arg5, \ + (unsigned long) arg6 \ + }; \ + register void *__argp asm("2") = &__arg; \ + long __res; \ + __asm__ __volatile__ ( \ + " svc %b1\n" \ + " lgr %0,2" \ + : "=d" (__res) \ + : "i" (__NR_##name), \ + "d" (__argp) \ + : _svc_clobber); \ + __syscall_return(type, __res); \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/s390x/setjmp.S b/klibc/klibc/arch/s390x/setjmp.S new file mode 100644 index 0000000000..251c57d43a --- /dev/null +++ b/klibc/klibc/arch/s390x/setjmp.S @@ -0,0 +1,36 @@ +# +# arch/s390x/setjmp.S +# +# setjmp/longjmp for the s390x architecture +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: + stmg %r6,%r15,0(%r2) # save all general registers + std %f1,80(%r2) # save fp registers f4 and f6 + std %f3,88(%r2) + std %f5,96(%r2) + std %f7,104(%r2) + lghi %r2,0 # return 0 + br %r14 + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: + lgr %r1,%r2 # jmp_buf + lgr %r2,%r3 # return value + ld %f7,104(%r1) # restore all saved registers + ld %f5,96(%r1) + ld %f3,88(%r1) + ld %f1,80(%r1) + lmg %r6,%r15,0(%r1) + br %r14 # return to restored address + + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/sh/MCONFIG b/klibc/klibc/arch/sh/MCONFIG new file mode 100644 index 0000000000..6cd4e5c839 --- /dev/null +++ b/klibc/klibc/arch/sh/MCONFIG @@ -0,0 +1,19 @@ +# -*- makefile -*- +# +# arch/sh/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHREGFLAGS = -m4 -mno-implicit-fp +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 2 MB -- the normal starting point for text is 4 MB. +SHAREDFLAGS = -Ttext 0x00200200 + diff --git a/klibc/klibc/arch/sh/Makefile.inc b/klibc/klibc/arch/sh/Makefile.inc new file mode 100644 index 0000000000..16d7ea1e18 --- /dev/null +++ b/klibc/klibc/arch/sh/Makefile.inc @@ -0,0 +1,14 @@ +# -*- makefile -*- +# +# arch/sh/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = arch/sh/setjmp.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + +archclean: diff --git a/klibc/klibc/arch/sh/crt0.S b/klibc/klibc/arch/sh/crt0.S new file mode 100644 index 0000000000..c9938a5612 --- /dev/null +++ b/klibc/klibc/arch/sh/crt0.S @@ -0,0 +1,28 @@ +# +# arch/sh/crt0.S +# +# void _start(void) +# { +# /* Divine up argc, argv, and envp */ +# environ = envp; +# exit(main(argc, argv, envp)); +# } +# + + .text + .align 2 + .type _start,#function + .globl _start + +_start: + mov r15, r4 + mov #0, r5 + mov.l 1f, r0 + + jsr @r0 + nop + + .align 2 +1: .long __libc_init + + .size _start,.-_start diff --git a/klibc/klibc/arch/sh/include/klibc/archsetjmp.h b/klibc/klibc/arch/sh/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..28dd932fbc --- /dev/null +++ b/klibc/klibc/arch/sh/include/klibc/archsetjmp.h @@ -0,0 +1,22 @@ +/* + * arch/sh/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; + unsigned long pr; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/klibc/arch/sh/include/klibc/archsys.h b/klibc/klibc/arch/sh/include/klibc/archsys.h new file mode 100644 index 0000000000..5f8050a536 --- /dev/null +++ b/klibc/klibc/arch/sh/include/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/sh/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/sh/setjmp.S b/klibc/klibc/arch/sh/setjmp.S new file mode 100644 index 0000000000..63f760283f --- /dev/null +++ b/klibc/klibc/arch/sh/setjmp.S @@ -0,0 +1,65 @@ +# +# arch/sh/setjmp.S +# +# setjmp/longjmp for the SuperH architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# +# r8 +# r9 +# r10 +# r11 +# r12 +# r13 +# r14 +# r15 +# pr +# + + .text + .align 2 + + .globl setjmp + .type setjmp, #function + +setjmp: + add #(9*4), r4 + sts.l pr, @-r4 + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + rts + mov #0, r0 + + .size setjmp,.-setjmp + + .align 2 + .globl longjmp + .type setjmp, #function + +longjmp: + mov.l @r4+, r8 + mov.l @r4+, r9 + mov.l @r4+, r10 + mov.l @r4+, r11 + mov.l @r4+, r12 + mov.l @r4+, r13 + mov.l @r4+, r14 + mov.l @r4+, r15 + lds.l @r4+, pr + mov r5, r0 + tst r0, r0 + bf 1f + mov #1, r0 ! in case val==0 +1: rts + nop + + .size longjmp,.-longjmp + diff --git a/klibc/klibc/arch/sparc/MCONFIG b/klibc/klibc/arch/sparc/MCONFIG new file mode 100644 index 0000000000..cb94f46c00 --- /dev/null +++ b/klibc/klibc/arch/sparc/MCONFIG @@ -0,0 +1,18 @@ +# -*- makefile -*- +# +# arch/sparc/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# Normal binaries start at 64K; the linker wants 64K alignment, +# and call instructions have a 30-bit signed offset, << 2. +SHAREDFLAGS = -Ttext 0x40000100 diff --git a/klibc/klibc/arch/sparc/Makefile.inc b/klibc/klibc/arch/sparc/Makefile.inc new file mode 100644 index 0000000000..0186810aca --- /dev/null +++ b/klibc/klibc/arch/sparc/Makefile.inc @@ -0,0 +1,44 @@ +# -*- makefile -*- +# +# arch/sparc/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/sdiv.o \ + arch/$(ARCH)/udiv.o \ + arch/$(ARCH)/srem.o \ + arch/$(ARCH)/urem.o \ + arch/$(ARCH)/smul.o \ + arch/$(ARCH)/umul.o \ + arch/$(ARCH)/setjmp.o + +arch/$(ARCH)/sdiv.S: arch/$(ARCH)/divrem.m4 + @echo 'building $@ from $^' + @(echo "define(NAME,\`.div')define(OP,\`div')define(S,\`true')"; \ + cat $^) | m4 > $@ + @chmod 444 $@ + +arch/$(ARCH)/udiv.S: arch/$(ARCH)/divrem.m4 + @echo 'building $@ from $^' + @(echo "define(NAME,\`.udiv')define(OP,\`div')define(S,\`false')"; \ + cat $^) | m4 > $@ + @chmod 444 $@ + +arch/$(ARCH)/srem.S: arch/$(ARCH)/divrem.m4 + @echo 'building $@ from $^' + @(echo "define(NAME,\`.rem')define(OP,\`rem')define(S,\`true')"; \ + cat $^) | m4 > $@ + @chmod 444 $@ + +arch/$(ARCH)/urem.S: arch/$(ARCH)/divrem.m4 + @echo 'building $@ from $^' + @(echo "define(NAME,\`.urem')define(OP,\`rem')define(S,\`false')"; \ + cat $^) | m4 > $@ + @chmod 444 $@ + +archclean: + rm -f arch/$(ARCH)/?div.S arch/$(ARCH)/?rem.S diff --git a/klibc/klibc/arch/sparc/crt0.S b/klibc/klibc/arch/sparc/crt0.S new file mode 100644 index 0000000000..148cb4b4e9 --- /dev/null +++ b/klibc/klibc/arch/sparc/crt0.S @@ -0,0 +1,2 @@ +#define TARGET_PTR_SIZE 32 +#include "arch/sparc/crt0i.S" diff --git a/klibc/klibc/arch/sparc/crt0i.S b/klibc/klibc/arch/sparc/crt0i.S new file mode 100644 index 0000000000..97652a3090 --- /dev/null +++ b/klibc/klibc/arch/sparc/crt0i.S @@ -0,0 +1,100 @@ +! This file derived from the equivalent in newlib +! +! C run time start off + +! This file supports: +! +! - both 32bit pointer and 64bit pointer environments (at compile time) +! - an imposed stack bias (of 2047) (at run time) +! - medium/low and medium/anywhere code models (at run time) + +! Initial stack setup: +! +! bottom of stack (higher memory address) +! ... +! text of environment strings +! text of argument strings +! envp[envc] = 0 (4/8 bytes) +! ... +! env[0] (4/8 bytes) +! argv[argc] = 0 (4/8 bytes) +! ... +! argv[0] (4/8 bytes) +! argc (4/8 bytes) +! register save area (64 bits by 16 registers = 128 bytes) +! top of stack (%sp) + +! Stack Bias: +! +! It is the responsibility of the o/s to set this up. +! We handle both a 0 and 2047 value for the stack bias. + +! Medium/Anywhere code model support: +! +! In this model %g4 points to the start of the data segment. +! The text segment can go anywhere, but %g4 points to the *data* segment. +! It is up to the compiler/linker to get this right. +! +! Since this model is statically linked the start of the data segment +! is known at link time. Eg: +! +! sethi %hh(data_start), %g1 +! sethi %lm(data_start), %g4 +! or %g1, %hm(data_start), %g1 +! or %g4, %lo(data_start), %g4 +! sllx %g1, 32, %g1 +! or %g4, %g1, %g4 +! +! FIXME: For now we just assume 0. + +! FIXME: if %g1 contains a non-zero value, atexit() should be invoked +! with this value. + + + .text + .align 4 + .globl _start + .type _start, @function +_start: + clr %fp + +! We use %g4 even if the code model is Medium/Low (simplifies the code). + + clr %g4 ! Medium/Anywhere base reg + +! If there is a stack bias in effect, account for it in %g5. Then always +! add %g5 to stack references below. This way the code can be used with +! or without an imposed bias. + + andcc %sp, 1, %g5 + bz,a .LNoBias + nop + mov 2047, %g5 +.LNoBias: + add %sp, %g5, %g5 + +! On entry, the kernel leaves room for one register frame, but +! the C API wants more free space. Thus, we need to drop the stack +! pointer additionally. + +#if TARGET_PTR_SIZE == 32 + sub %sp, 32, %sp ! make room for incoming arguments +#else /* TARGET_PTR_SIZE == 64 */ + sub %sp, 64, %sp ! make room for incoming arguments +#endif + +! Set up pointers to the ELF data structure (argc, argv, ...) +! Pass as the first argument to __libc_init +#if TARGET_PTR_SIZE == 32 + add %g5, 0x40, %o0 +#else /* TARGET_PTR_SIZE == 64 */ + add %g5, 0x80, %o0 +#endif + + call __libc_init + mov %g1, %o1 ! This is the "atexit" pointer; + ! pass as the second argument to __libc_init + +! If __libc_init returns, something is hosed. Try an illegal insn. +! If that does not work, the o/s is hosed more than we are. + .long 0 diff --git a/klibc/klibc/arch/sparc/divrem.m4 b/klibc/klibc/arch/sparc/divrem.m4 new file mode 100644 index 0000000000..aa4171dd88 --- /dev/null +++ b/klibc/klibc/arch/sparc/divrem.m4 @@ -0,0 +1,276 @@ +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: Header: divrem.m4,v 1.4 92/06/25 13:23:57 torek Exp + * $NetBSD: divrem.m4,v 1.4 1997/10/09 10:07:54 lukem Exp $ + */ + +/* + * Division and remainder, from Appendix E of the Sparc Version 8 + * Architecture Manual, with fixes from Gordon Irlam. + */ + +#if defined(LIBC_SCCS) && !defined(lint) + .asciz "@(#)divrem.m4 8.1 (Berkeley) 6/4/93" +#endif /* LIBC_SCCS and not lint */ + +/* + * Input: dividend and divisor in %o0 and %o1 respectively. + * + * m4 parameters: + * NAME name of function to generate + * OP OP=div => %o0 / %o1; OP=rem => %o0 % %o1 + * S S=true => signed; S=false => unsigned + * + * Algorithm parameters: + * N how many bits per iteration we try to get (4) + * WORDSIZE total number of bits (32) + * + * Derived constants: + * TWOSUPN 2^N, for label generation (m4 exponentiation currently broken) + * TOPBITS number of bits in the top `decade' of a number + * + * Important variables: + * Q the partial quotient under development (initially 0) + * R the remainder so far, initially the dividend + * ITER number of main division loop iterations required; + * equal to ceil(log2(quotient) / N). Note that this + * is the log base (2^N) of the quotient. + * V the current comparand, initially divisor*2^(ITER*N-1) + * + * Cost: + * Current estimate for non-large dividend is + * ceil(log2(quotient) / N) * (10 + 7N/2) + C + * A large dividend is one greater than 2^(31-TOPBITS) and takes a + * different path, as the upper bits of the quotient must be developed + * one bit at a time. + */ + +define(N, `4') +define(TWOSUPN, `16') +define(WORDSIZE, `32') +define(TOPBITS, eval(WORDSIZE - N*((WORDSIZE-1)/N))) + +define(dividend, `%o0') +define(divisor, `%o1') +define(Q, `%o2') +define(R, `%o3') +define(ITER, `%o4') +define(V, `%o5') + +/* m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d */ +define(T, `%g1') +define(SC, `%g7') +ifelse(S, `true', `define(SIGN, `%g6')') + +/* + * This is the recursive definition for developing quotient digits. + * + * Parameters: + * $1 the current depth, 1 <= $1 <= N + * $2 the current accumulation of quotient bits + * N max depth + * + * We add a new bit to $2 and either recurse or insert the bits in + * the quotient. R, Q, and V are inputs and outputs as defined above; + * the condition codes are expected to reflect the input R, and are + * modified to reflect the output R. + */ +define(DEVELOP_QUOTIENT_BITS, +` ! depth $1, accumulated bits $2 + bl L.$1.eval(TWOSUPN+$2) + srl V,1,V + ! remainder is positive + subcc R,V,R + ifelse($1, N, + ` b 9f + add Q, ($2*2+1), Q + ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')') +L.$1.eval(TWOSUPN+$2): + ! remainder is negative + addcc R,V,R + ifelse($1, N, + ` b 9f + add Q, ($2*2-1), Q + ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')') + ifelse($1, 1, `9:')') + +#include +#include + +FUNC(NAME) +ifelse(S, `true', +` ! compute sign of result; if neither is negative, no problem + orcc divisor, dividend, %g0 ! either negative? + bge 2f ! no, go do the divide + ifelse(OP, `div', + `xor divisor, dividend, SIGN', + `mov dividend, SIGN') ! compute sign in any case + tst divisor + bge 1f + tst dividend + ! divisor is definitely negative; dividend might also be negative + bge 2f ! if dividend not negative... + neg divisor ! in any case, make divisor nonneg +1: ! dividend is negative, divisor is nonnegative + neg dividend ! make dividend nonnegative +2: +') + ! Ready to divide. Compute size of quotient; scale comparand. + orcc divisor, %g0, V + bnz 1f + mov dividend, R + + ! Divide by zero trap. If it returns, return 0 (about as + ! wrong as possible, but that is what SunOS does...). + t ST_DIV0 + retl + clr %o0 + +1: + cmp R, V ! if divisor exceeds dividend, done + blu Lgot_result ! (and algorithm fails otherwise) + clr Q + sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T + cmp R, T + blu Lnot_really_big + clr ITER + + ! `Here the dividend is >= 2^(31-N) or so. We must be careful here, + ! as our usual N-at-a-shot divide step will cause overflow and havoc. + ! The number of bits in the result here is N*ITER+SC, where SC <= N. + ! Compute ITER in an unorthodox manner: know we need to shift V into + ! the top decade: so do not even bother to compare to R.' + 1: + cmp V, T + bgeu 3f + mov 1, SC + sll V, N, V + b 1b + inc ITER + + ! Now compute SC. + 2: addcc V, V, V + bcc Lnot_too_big + inc SC + + ! We get here if the divisor overflowed while shifting. + ! This means that R has the high-order bit set. + ! Restore V and subtract from R. + sll T, TOPBITS, T ! high order bit + srl V, 1, V ! rest of V + add V, T, V + b Ldo_single_div + dec SC + + Lnot_too_big: + 3: cmp V, R + blu 2b + nop + be Ldo_single_div + nop + /* NB: these are commented out in the V8-Sparc manual as well */ + /* (I do not understand this) */ + ! V > R: went too far: back up 1 step + ! srl V, 1, V + ! dec SC + ! do single-bit divide steps + ! + ! We have to be careful here. We know that R >= V, so we can do the + ! first divide step without thinking. BUT, the others are conditional, + ! and are only done if R >= 0. Because both R and V may have the high- + ! order bit set in the first step, just falling into the regular + ! division loop will mess up the first time around. + ! So we unroll slightly... + Ldo_single_div: + deccc SC + bl Lend_regular_divide + nop + sub R, V, R + mov 1, Q + b Lend_single_divloop + nop + Lsingle_divloop: + sll Q, 1, Q + bl 1f + srl V, 1, V + ! R >= 0 + sub R, V, R + b 2f + inc Q + 1: ! R < 0 + add R, V, R + dec Q + 2: + Lend_single_divloop: + deccc SC + bge Lsingle_divloop + tst R + b,a Lend_regular_divide + +Lnot_really_big: +1: + sll V, N, V + cmp V, R + bleu 1b + inccc ITER + be Lgot_result + dec ITER + + tst R ! set up for initial iteration +Ldivloop: + sll Q, N, Q + DEVELOP_QUOTIENT_BITS(1, 0) +Lend_regular_divide: + deccc ITER + bge Ldivloop + tst R + bl,a Lgot_result + ! non-restoring fixup here (one instruction only!) +ifelse(OP, `div', +` dec Q +', ` add R, divisor, R +') + +Lgot_result: +ifelse(S, `true', +` ! check to see if answer should be < 0 + tst SIGN + bl,a 1f + ifelse(OP, `div', `neg Q', `neg R') +1:') + retl + ifelse(OP, `div', `mov Q, %o0', `mov R, %o0') diff --git a/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h b/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..92c1c74c9d --- /dev/null +++ b/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h @@ -0,0 +1,16 @@ +/* + * arch/sparc/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __sp; + unsigned long __fp; + unsigned long __pc; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/sparc/include/klibc/archsys.h b/klibc/klibc/arch/sparc/include/klibc/archsys.h new file mode 100644 index 0000000000..fe6e68df8a --- /dev/null +++ b/klibc/klibc/arch/sparc/include/klibc/archsys.h @@ -0,0 +1,65 @@ +/* + * arch/sparc/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* fork and vfork return the "other process" pid in %o0 and an + "is child" flag in %o1... */ + +#define _syscall0_forkish(type,name) \ +type name(void) \ +{ \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register unsigned long __o0 __asm__ ("o0"); \ +register unsigned long __o1 __asm__ ("o1"); \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__o0), "=r" (__o1)\ + : "r" (__g1) \ + : "cc"); \ +if ((unsigned long)__o0 < (unsigned long)-255) \ + return (type)(__o0 & (__o1-1)); \ +errno = (int)-__o0; \ +return -1; \ +} + +/* SPARC seems to lack _syscall6() in its headers */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ +register long __g1 __asm__ ("g1") = __NR_##name; \ +register long __o0 __asm__ ("o0") = (long)(arg1); \ +register long __o1 __asm__ ("o1") = (long)(arg2); \ +register long __o2 __asm__ ("o2") = (long)(arg3); \ +register long __o3 __asm__ ("o3") = (long)(arg4); \ +register long __o4 __asm__ ("o4") = (long)(arg5); \ +register long __o5 __asm__ ("o5") = (long)(arg6); \ +__asm__ __volatile__ ("t 0x10\n\t" \ + "bcc 1f\n\t" \ + "mov %%o0, %0\n\t" \ + "sub %%g0, %%o0, %0\n\t" \ + "1:\n\t" \ + : "=r" (__res), "=&r" (__o0) \ + : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__o5), "r" (__g1) \ + : "cc"); \ +if (__res < -255 || __res>=0) \ +return (type) __res; \ +errno = -__res; \ +return (type)-1; \ +} + +#endif /* _syscall6 missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/sparc/include/machine/asm.h b/klibc/klibc/arch/sparc/include/machine/asm.h new file mode 100644 index 0000000000..b622bd8cf1 --- /dev/null +++ b/klibc/klibc/arch/sparc/include/machine/asm.h @@ -0,0 +1,192 @@ +/* $NetBSD: asm.h,v 1.14 2002/07/20 08:37:30 mrg Exp $ */ + +/* + * Copyright (c) 1994 Allen Briggs + * All rights reserved. + * + * Gleaned from locore.s and sun3 asm.h which had the following copyrights: + * locore.s: + * Copyright (c) 1988 University of Utah. + * Copyright (c) 1982, 1990 The Regents of the University of California. + * sun3/include/asm.h: + * Copyright (c) 1993 Adam Glass + * Copyright (c) 1990 The Regents of the University of California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ASM_H_ +#define _ASM_H_ + +/* Pull in CCFSZ, CC64FSZ, and BIAS from frame.h */ +#ifndef _LOCORE +#define _LOCORE +#endif +#include + +#ifdef __ELF__ +#define _C_LABEL(name) name +#else +#ifdef __STDC__ +#define _C_LABEL(name) _ ## name +#else +#define _C_LABEL(name) _/**/name +#endif +#endif +#define _ASM_LABEL(name) name + +#ifdef PIC +/* + * PIC_PROLOGUE() is akin to the compiler generated function prologue for + * PIC code. It leaves the address of the Global Offset Table in DEST, + * clobbering register TMP in the process. + * + * We can use two code sequences. We can read the %pc or use the call + * instruction that saves the pc in %o7. Call requires the branch unit and + * IEU1, and clobbers %o7 which needs to be restored. This instruction + * sequence takes about 4 cycles due to instruction interdependence. Reading + * the pc takes 4 cycles to dispatch and is always dispatched alone. That + * sequence takes 7 cycles. + */ +#ifdef __arch64__ +#define PIC_PROLOGUE(dest,tmp) \ + mov %o7, tmp; \ + sethi %hi(_GLOBAL_OFFSET_TABLE_-4),dest; \ + call 0f; \ + or dest,%lo(_GLOBAL_OFFSET_TABLE_+4),dest; \ +0: \ + add dest,%o7,dest; \ + mov tmp, %o7 +#else +#define PIC_PROLOGUE(dest,tmp) \ + mov %o7,tmp; 3: call 4f; nop; 4: \ + sethi %hi(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ + or dest,%lo(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ + add dest,%o7,dest; mov tmp,%o7 +#endif + +/* + * PICCY_SET() does the equivalent of a `set var, %dest' instruction in + * a PIC-like way, but without involving the Global Offset Table. This + * only works for VARs defined in the same file *and* in the text segment. + */ +#ifdef __arch64__ +#define PICCY_SET(var,dest,tmp) \ + 3: rd %pc, tmp; add tmp,(var-3b),dest +#else +#define PICCY_SET(var,dest,tmp) \ + mov %o7,tmp; 3: call 4f; nop; 4: \ + add %o7,(var-3b),dest; mov tmp,%o7 +#endif +#else +#define PIC_PROLOGUE(dest,tmp) +#define PICCY_OFFSET(var,dest,tmp) +#endif + +#define FTYPE(x) .type x,@function +#define OTYPE(x) .type x,@object + +#define _ENTRY(name) \ + .align 4; .globl name; .proc 1; FTYPE(name); name: + +#ifdef GPROF +/* see _MCOUNT_ENTRY in profile.h */ +#ifdef __ELF__ +#ifdef __arch64__ +#define _PROF_PROLOGUE \ + .data; .align 8; 1: .uaword 0; .uaword 0; \ + .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call _mcount; \ + or %o0,%lo(1b),%o0; restore +#else +#define _PROF_PROLOGUE \ + .data; .align 4; 1: .long 0; \ + .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call _mcount; \ + or %o0,%lo(1b),%o0; restore +#endif +#else +#ifdef __arch64__ +#define _PROF_PROLOGUE \ + .data; .align 8; 1: .uaword 0; .uaword 0; \ + .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call mcount; \ + or %o0,%lo(1b),%o0; restore +#else +#define _PROF_PROLOGUE \ + .data; .align 4; 1: .long 0; \ + .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call mcount; \ + or %o0,%lo(1b),%o0; restore +#endif +#endif +#else +#define _PROF_PROLOGUE +#endif + +#define ENTRY(name) _ENTRY(_C_LABEL(name)); _PROF_PROLOGUE +#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name)) +#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)); _PROF_PROLOGUE +#define FUNC(name) ASENTRY(name) +#define RODATA(name) .align 4; .text; .globl _C_LABEL(name); \ + OTYPE(_C_LABEL(name)); _C_LABEL(name): + + +#define ASMSTR .asciz + +#define RCSID(name) .asciz name + +#ifdef __ELF__ +#define WEAK_ALIAS(alias,sym) \ + .weak alias; \ + alias = sym +#endif + +/* + * WARN_REFERENCES: create a warning if the specified symbol is referenced. + */ +#ifdef __ELF__ +#ifdef __STDC__ +#define WARN_REFERENCES(_sym,_msg) \ + .section .gnu.warning. ## _sym ; .ascii _msg ; .text +#else +#define WARN_REFERENCES(_sym,_msg) \ + .section .gnu.warning./**/_sym ; .ascii _msg ; .text +#endif /* __STDC__ */ +#else +#ifdef __STDC__ +#define __STRING(x) #x +#define WARN_REFERENCES(sym,msg) \ + .stabs msg ## ,30,0,0,0 ; \ + .stabs __STRING(_ ## sym) ## ,1,0,0,0 +#else +#define __STRING(x) "x" +#define WARN_REFERENCES(sym,msg) \ + .stabs msg,30,0,0,0 ; \ + .stabs __STRING(_/**/sym),1,0,0,0 +#endif /* __STDC__ */ +#endif /* __ELF__ */ + +#endif /* _ASM_H_ */ diff --git a/klibc/klibc/arch/sparc/include/machine/frame.h b/klibc/klibc/arch/sparc/include/machine/frame.h new file mode 100644 index 0000000000..b09175c7f4 --- /dev/null +++ b/klibc/klibc/arch/sparc/include/machine/frame.h @@ -0,0 +1,138 @@ +/* $NetBSD: frame.h,v 1.4 2001/12/04 00:05:05 darrenr Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)frame.h 8.1 (Berkeley) 6/11/93 + */ + +#if defined(_KERNEL_OPT) +#include "opt_sparc_arch.h" +#endif + +/* + * Sparc stack frame format. + * + * Note that the contents of each stack frame may be held only in + * machine register windows. In order to get an accurate picture + * of the frame, you must first force the kernel to write any such + * windows to the stack. + */ +#ifndef _LOCORE +#ifndef SUN4U +struct frame { + int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ + int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ + struct frame *fr_fp; /* space to save frame pointer (%i6) */ + int32_t fr_pc; /* space to save return pc (%i7) */ + /* + * SunOS reserves another 8 words here; this is pointless + * but we do it for compatibility. + */ + int32_t fr_xxx; /* `structure return pointer' (unused) */ + int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ + int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ +}; +#else +struct frame32 { + int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ + int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ + u_int32_t fr_fp; /* space to save frame pointer (%i6) */ + u_int32_t fr_pc; /* space to save return pc (%i7) */ + /* + * SunOS reserves another 8 words here; this is pointless + * but we do it for compatibility. + */ + int32_t fr_xxx; /* `structure return pointer' (unused) */ + int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ + int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ +}; +#endif +#endif + +/* + * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if + * a function is to call C code. It should be just 64, but Sun defined + * their frame with space to hold arguments 0 through 5 (plus some junk), + * and varargs routines (such as kprintf) demand this, and gcc uses this + * area at times anyway. + */ +#define CCFSZ 96 + +/* + * Sparc v9 stack frame format. + * + * Note that the contents of each stack frame may be held only in + * machine register windows. In order to get an accurate picture + * of the frame, you must first force the kernel to write any such + * windows to the stack. + * + * V9 frames have an odd bias, so you can tall a v9 frame from + * a v8 frame by testing the stack pointer's lsb. + */ +#if !defined(_LOCORE) && !defined(_LIBC) +struct frame64 { + int64_t fr_local[8]; /* space to save locals (%l0..%l7) */ + int64_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ + u_int64_t fr_fp; /* space to save frame pointer (%i6) */ + u_int64_t fr_pc; /* space to save return pc (%i7) */ + /* + * SVR4 reserves a bunch of extra stuff. + */ + int64_t fr_argd[6]; /* `register save area' (lunacy) */ + int64_t fr_argx[0]; /* arg extension (args 7..n; variable size) */ +}; + +#define v9next_frame(f) ((struct frame64*)(f->fr_fp+BIAS)) +#endif + +/* + * CC64FSZ (C Compiler 64-bit Frame SiZe) is the size of a stack frame used + * by the compiler in 64-bit mode. It is (16)*8; space for 8 ins, 8 outs. + */ +#define CC64FSZ 176 + +/* + * v9 stacks all have a bias of 2047 added to the %sp and %fp, so you can easily + * detect it by testing the register for an odd value. Why 2K-1 I don't know. + */ +#define BIAS (2048-1) + diff --git a/klibc/klibc/arch/sparc/include/machine/trap.h b/klibc/klibc/arch/sparc/include/machine/trap.h new file mode 100644 index 0000000000..42c3ef6ae2 --- /dev/null +++ b/klibc/klibc/arch/sparc/include/machine/trap.h @@ -0,0 +1,141 @@ +/* $NetBSD: trap.h,v 1.11 1999/01/20 00:15:08 pk Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)trap.h 8.1 (Berkeley) 6/11/93 + */ +/* + * Sun4m support by Aaron Brown, Harvard University. + * Changes Copyright (c) 1995 The President and Fellows of Harvard College. + * All rights reserved. + */ + +#ifndef _MACHINE_TRAP_H +#define _MACHINE_TRAP_H + +/* trap vec (pri) description */ +#define T_RESET 0x00 /* (1) not actually vectored; jumps to 0 */ +#define T_TEXTFAULT 0x01 /* (2) address fault during instr fetch */ +#define T_ILLINST 0x02 /* (3) illegal instruction */ +#define T_PRIVINST 0x03 /* (4) privileged instruction */ +#define T_FPDISABLED 0x04 /* (5) fp instr while fp disabled */ +#define T_WINOF 0x05 /* (6) register window overflow */ +#define T_WINUF 0x06 /* (7) register window underflow */ +#define T_ALIGN 0x07 /* (8) address not properly aligned */ +#define T_FPE 0x08 /* (9) floating point exception */ +#define T_DATAFAULT 0x09 /* (10) address fault during data fetch */ +#define T_TAGOF 0x0a /* (11) tag overflow */ +/* 0x0b unused */ +/* 0x0c unused */ +/* 0x0d unused */ +/* 0x0e unused */ +/* 0x0f unused */ +/* 0x10 unused */ +#define T_L1INT 0x11 /* (27) level 1 interrupt */ +#define T_L2INT 0x12 /* (26) level 2 interrupt */ +#define T_L3INT 0x13 /* (25) level 3 interrupt */ +#define T_L4INT 0x14 /* (24) level 4 interrupt */ +#define T_L5INT 0x15 /* (23) level 5 interrupt */ +#define T_L6INT 0x16 /* (22) level 6 interrupt */ +#define T_L7INT 0x17 /* (21) level 7 interrupt */ +#define T_L8INT 0x18 /* (20) level 8 interrupt */ +#define T_L9INT 0x19 /* (19) level 9 interrupt */ +#define T_L10INT 0x1a /* (18) level 10 interrupt */ +#define T_L11INT 0x1b /* (17) level 11 interrupt */ +#define T_L12INT 0x1c /* (16) level 12 interrupt */ +#define T_L13INT 0x1d /* (15) level 13 interrupt */ +#define T_L14INT 0x1e /* (14) level 14 interrupt */ +#define T_L15INT 0x1f /* (13) level 15 interrupt */ +/* 0x20 unused */ +/* through 0x23 unused */ +#define T_CPDISABLED 0x24 /* (5) coprocessor instr while disabled */ +#define T_UNIMPLFLUSH 0x25 /* Unimplemented FLUSH */ +/* through 0x27 unused */ +#define T_CPEXCEPTION 0x28 /* (9) coprocessor exception */ +/* 0x29 unused */ +#define T_IDIV0 0x2a /* divide by zero (from hw [su]div instr) */ +#define T_STOREBUFFAULT 0x2b /* SuperSPARC: Store buffer copy-back fault */ +/* 0x2c unused */ +/* through 0x7f unused */ + +/* beginning of `user' vectors (from trap instructions) - all priority 12 */ +#define T_SUN_SYSCALL 0x80 /* system call */ +#define T_BREAKPOINT 0x81 /* breakpoint `instruction' */ +#define T_DIV0 0x82 /* division routine was handed 0 */ +#define T_FLUSHWIN 0x83 /* flush windows */ +#define T_CLEANWIN 0x84 /* provide clean windows */ +#define T_RANGECHECK 0x85 /* ? */ +#define T_FIXALIGN 0x86 /* fix up unaligned accesses */ +#define T_INTOF 0x87 /* integer overflow ? */ +#define T_SVR4_SYSCALL 0x88 /* SVR4 system call */ +#define T_BSD_SYSCALL 0x89 /* BSD system call */ +#define T_KGDB_EXEC 0x8a /* for kernel gdb */ + +/* 0x8b..0xff are currently unallocated, except the following */ +#define T_SVR4_GETCC 0xa0 +#define T_SVR4_SETCC 0xa1 +#define T_SVR4_GETPSR 0xa2 +#define T_SVR4_SETPSR 0xa3 +#define T_SVR4_GETHRTIME 0xa4 +#define T_SVR4_GETHRVTIME 0xa5 +#define T_SVR4_GETHRESTIME 0xa7 + + +#ifdef _KERNEL /* pseudo traps for locore.s */ +#define T_RWRET -1 /* need first user window for trap return */ +#define T_AST -2 /* no-op, just needed reschedule or profile */ +#endif + +/* flags to system call (flags in %g1 along with syscall number) */ +#define SYSCALL_G2RFLAG 0x400 /* on success, return to %g2 rather than npc */ +#define SYSCALL_G7RFLAG 0x800 /* use %g7 as above (deprecated) */ + +/* + * `software trap' macros to keep people happy (sparc v8 manual says not + * to set the upper bits). + */ +#define ST_BREAKPOINT (T_BREAKPOINT & 0x7f) +#define ST_DIV0 (T_DIV0 & 0x7f) +#define ST_FLUSHWIN (T_FLUSHWIN & 0x7f) +#define ST_SYSCALL (T_SUN_SYSCALL & 0x7f) + +#endif /* _MACHINE_TRAP_H_ */ diff --git a/klibc/klibc/arch/sparc/setjmp.S b/klibc/klibc/arch/sparc/setjmp.S new file mode 100644 index 0000000000..f41ee2bf12 --- /dev/null +++ b/klibc/klibc/arch/sparc/setjmp.S @@ -0,0 +1,38 @@ +! +! setjmp.S +! +! Basic setjmp/longjmp +! +! This code was based on the equivalent code in NetBSD +! + +#include +#include + +! +! The jmp_buf contains the following entries: +! sp +! fp +! pc +! +ENTRY(setjmp) + st %sp,[%o0+0] ! Callers stack pointer + st %o7,[%o0+4] ! Return pc + st %fp,[%o0+8] ! Frame pointer + retl ! Return + clr %o0 ! ...0 + +ENTRY(longjmp) + sub %sp, 64, %sp ! set up a local stack frame +0: + t ST_FLUSHWIN ! flush register windows out to memory + ! + ! We restore the saved stack pointer to %fp, then issue + ! a restore instruction which will reload the register + ! window from the stack. + ! + ld [%o0+4], %o7 /* restore return pc */ + ld [%o0+0], %fp /* and stack pointer */ + + retl ! success, return %g6 + restore %o1, 0, %o0 diff --git a/klibc/klibc/arch/sparc/smul.S b/klibc/klibc/arch/sparc/smul.S new file mode 100644 index 0000000000..0eb218bbe8 --- /dev/null +++ b/klibc/klibc/arch/sparc/smul.S @@ -0,0 +1,160 @@ +/* $NetBSD: mul.S,v 1.3 1997/07/16 14:37:42 christos Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: Header: mul.s,v 1.5 92/06/25 13:24:03 torek Exp + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + .asciz "@(#)mul.s 8.1 (Berkeley) 6/4/93" +#else + RCSID("$NetBSD: mul.S,v 1.3 1997/07/16 14:37:42 christos Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * Signed multiply, from Appendix E of the Sparc Version 8 + * Architecture Manual. + * + * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of + * the 64-bit product). + * + * This code optimizes short (less than 13-bit) multiplies. + */ + +FUNC(.mul) + mov %o0, %y ! multiplier -> Y + andncc %o0, 0xfff, %g0 ! test bits 12..31 + be Lmul_shortway ! if zero, can do it the short way + andcc %g0, %g0, %o4 ! zero the partial product and clear N and V + + /* + * Long multiply. 32 steps, followed by a final shift step. + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %o1, %o4 ! 13 + mulscc %o4, %o1, %o4 ! 14 + mulscc %o4, %o1, %o4 ! 15 + mulscc %o4, %o1, %o4 ! 16 + mulscc %o4, %o1, %o4 ! 17 + mulscc %o4, %o1, %o4 ! 18 + mulscc %o4, %o1, %o4 ! 19 + mulscc %o4, %o1, %o4 ! 20 + mulscc %o4, %o1, %o4 ! 21 + mulscc %o4, %o1, %o4 ! 22 + mulscc %o4, %o1, %o4 ! 23 + mulscc %o4, %o1, %o4 ! 24 + mulscc %o4, %o1, %o4 ! 25 + mulscc %o4, %o1, %o4 ! 26 + mulscc %o4, %o1, %o4 ! 27 + mulscc %o4, %o1, %o4 ! 28 + mulscc %o4, %o1, %o4 ! 29 + mulscc %o4, %o1, %o4 ! 30 + mulscc %o4, %o1, %o4 ! 31 + mulscc %o4, %o1, %o4 ! 32 + mulscc %o4, %g0, %o4 ! final shift + + ! If %o0 was negative, the result is + ! (%o0 * %o1) + (%o1 << 32)) + ! We fix that here. + + tst %o0 + bge 1f + rd %y, %o0 + + ! %o0 was indeed negative; fix upper 32 bits of result by subtracting + ! %o1 (i.e., return %o4 - %o1 in %o1). + retl + sub %o4, %o1, %o1 + +1: + retl + mov %o4, %o1 + +Lmul_shortway: + /* + * Short multiply. 12 steps, followed by a final shift step. + * The resulting bits are off by 12 and (32-12) = 20 bit positions, + * but there is no problem with %o0 being negative (unlike above). + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %g0, %o4 ! final shift + + /* + * %o4 has 20 of the bits that should be in the low part of the + * result; %y has the bottom 12 (as %y's top 12). That is: + * + * %o4 %y + * +----------------+----------------+ + * | -12- | -20- | -12- | -20- | + * +------(---------+------)---------+ + * --hi-- ----low-part---- + * + * The upper 12 bits of %o4 should be sign-extended to form the + * high part of the product (i.e., highpart = %o4 >> 20). + */ + + rd %y, %o5 + sll %o4, 12, %o0 ! shift middle bits left 12 + srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left + or %o5, %o0, %o0 ! construct low part of result + retl + sra %o4, 20, %o1 ! ... and extract high part of result diff --git a/klibc/klibc/arch/sparc/umul.S b/klibc/klibc/arch/sparc/umul.S new file mode 100644 index 0000000000..6a7193d217 --- /dev/null +++ b/klibc/klibc/arch/sparc/umul.S @@ -0,0 +1,193 @@ +/* $NetBSD: umul.S,v 1.3 1997/07/16 14:37:44 christos Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: Header: umul.s,v 1.4 92/06/25 13:24:05 torek Exp + */ + +#include +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 + .asciz "@(#)umul.s 8.1 (Berkeley) 6/4/93" +#else + RCSID("$NetBSD: umul.S,v 1.3 1997/07/16 14:37:44 christos Exp $") +#endif +#endif /* LIBC_SCCS and not lint */ + +/* + * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the + * upper 32 bits of the 64-bit product). + * + * This code optimizes short (less than 13-bit) multiplies. Short + * multiplies require 25 instruction cycles, and long ones require + * 45 instruction cycles. + * + * On return, overflow has occurred (%o1 is not zero) if and only if + * the Z condition code is clear, allowing, e.g., the following: + * + * call .umul + * nop + * bnz overflow (or tnz) + */ + +FUNC(.umul) + or %o0, %o1, %o4 + mov %o0, %y ! multiplier -> Y + andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args + be Lmul_shortway ! if zero, can do it the short way + andcc %g0, %g0, %o4 ! zero the partial product and clear N and V + + /* + * Long multiply. 32 steps, followed by a final shift step. + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %o1, %o4 ! 13 + mulscc %o4, %o1, %o4 ! 14 + mulscc %o4, %o1, %o4 ! 15 + mulscc %o4, %o1, %o4 ! 16 + mulscc %o4, %o1, %o4 ! 17 + mulscc %o4, %o1, %o4 ! 18 + mulscc %o4, %o1, %o4 ! 19 + mulscc %o4, %o1, %o4 ! 20 + mulscc %o4, %o1, %o4 ! 21 + mulscc %o4, %o1, %o4 ! 22 + mulscc %o4, %o1, %o4 ! 23 + mulscc %o4, %o1, %o4 ! 24 + mulscc %o4, %o1, %o4 ! 25 + mulscc %o4, %o1, %o4 ! 26 + mulscc %o4, %o1, %o4 ! 27 + mulscc %o4, %o1, %o4 ! 28 + mulscc %o4, %o1, %o4 ! 29 + mulscc %o4, %o1, %o4 ! 30 + mulscc %o4, %o1, %o4 ! 31 + mulscc %o4, %o1, %o4 ! 32 + mulscc %o4, %g0, %o4 ! final shift + + + /* + * Normally, with the shift-and-add approach, if both numbers are + * positive you get the correct result. WIth 32-bit two's-complement + * numbers, -x is represented as + * + * x 32 + * ( 2 - ------ ) mod 2 * 2 + * 32 + * 2 + * + * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s, + * we can treat this as if the radix point were just to the left + * of the sign bit (multiply by 2^32), and get + * + * -x = (2 - x) mod 2 + * + * Then, ignoring the `mod 2's for convenience: + * + * x * y = xy + * -x * y = 2y - xy + * x * -y = 2x - xy + * -x * -y = 4 - 2x - 2y + xy + * + * For signed multiplies, we subtract (x << 32) from the partial + * product to fix this problem for negative multipliers (see mul.s). + * Because of the way the shift into the partial product is calculated + * (N xor V), this term is automatically removed for the multiplicand, + * so we don't have to adjust. + * + * But for unsigned multiplies, the high order bit wasn't a sign bit, + * and the correction is wrong. So for unsigned multiplies where the + * high order bit is one, we end up with xy - (y << 32). To fix it + * we add y << 32. + */ + tst %o1 + bl,a 1f ! if %o1 < 0 (high order bit = 1), + add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half) +1: rd %y, %o0 ! get lower half of product + retl + addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0 + +Lmul_shortway: + /* + * Short multiply. 12 steps, followed by a final shift step. + * The resulting bits are off by 12 and (32-12) = 20 bit positions, + * but there is no problem with %o0 being negative (unlike above), + * and overflow is impossible (the answer is at most 24 bits long). + */ + mulscc %o4, %o1, %o4 ! 1 + mulscc %o4, %o1, %o4 ! 2 + mulscc %o4, %o1, %o4 ! 3 + mulscc %o4, %o1, %o4 ! 4 + mulscc %o4, %o1, %o4 ! 5 + mulscc %o4, %o1, %o4 ! 6 + mulscc %o4, %o1, %o4 ! 7 + mulscc %o4, %o1, %o4 ! 8 + mulscc %o4, %o1, %o4 ! 9 + mulscc %o4, %o1, %o4 ! 10 + mulscc %o4, %o1, %o4 ! 11 + mulscc %o4, %o1, %o4 ! 12 + mulscc %o4, %g0, %o4 ! final shift + + /* + * %o4 has 20 of the bits that should be in the result; %y has + * the bottom 12 (as %y's top 12). That is: + * + * %o4 %y + * +----------------+----------------+ + * | -12- | -20- | -12- | -20- | + * +------(---------+------)---------+ + * -----result----- + * + * The 12 bits of %o4 left of the `result' area are all zero; + * in fact, all top 20 bits of %o4 are zero. + */ + + rd %y, %o5 + sll %o4, 12, %o0 ! shift middle bits left 12 + srl %o5, 20, %o5 ! shift low bits right 20 + or %o5, %o0, %o0 + retl + addcc %g0, %g0, %o1 ! %o1 = zero, and set Z diff --git a/klibc/klibc/arch/sparc64/MCONFIG b/klibc/klibc/arch/sparc64/MCONFIG new file mode 100644 index 0000000000..d490c63643 --- /dev/null +++ b/klibc/klibc/arch/sparc64/MCONFIG @@ -0,0 +1,21 @@ +# -*- makefile -*- +# +# arch/sparc64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHREQFLAGS = -m64 -mptr64 +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 64 + +LDFLAGS = -m elf64_sparc + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# Normal binaries start at 1 MB; the linker wants 1 MB alignment, +# and call instructions have a 30-bit signed offset, << 2. +SHAREDFLAGS = -Ttext 0x80000200 diff --git a/klibc/klibc/arch/sparc64/Makefile.inc b/klibc/klibc/arch/sparc64/Makefile.inc new file mode 100644 index 0000000000..d59f9878e9 --- /dev/null +++ b/klibc/klibc/arch/sparc64/Makefile.inc @@ -0,0 +1,13 @@ +# -*- makefile -*- +# +# arch/sparc64/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/setjmp.o + +archclean: diff --git a/klibc/klibc/arch/sparc64/crt0.S b/klibc/klibc/arch/sparc64/crt0.S new file mode 100644 index 0000000000..23af82ecc4 --- /dev/null +++ b/klibc/klibc/arch/sparc64/crt0.S @@ -0,0 +1,2 @@ +#define TARGET_PTR_SIZE 64 +#include "arch/sparc/crt0i.S" diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h b/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..022a31e542 --- /dev/null +++ b/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h @@ -0,0 +1,16 @@ +/* + * arch/sparc64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __sp; + unsigned long __fp; + unsigned long __pc; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsys.h b/klibc/klibc/arch/sparc64/include/klibc/archsys.h new file mode 100644 index 0000000000..651e4f7f09 --- /dev/null +++ b/klibc/klibc/arch/sparc64/include/klibc/archsys.h @@ -0,0 +1,157 @@ +/* + * arch/sparc64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* The Linux 2.5.31 SPARC64 syscall macros are just plain broken */ + +#undef _syscall0 +#undef _syscall1 +#undef _syscall2 +#undef _syscall3 +#undef _syscall4 +#undef _syscall5 +#undef _syscall6 + +#define _syscall0(type,name) \ +type name (void) \ +{ \ + register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ + register unsigned long __ret __asm__("o0"); \ + __asm__ __volatile__ ("t 0x6d\n\t" \ + "bcs,a %%xcc, 1f\n\t" \ + " st %0,%1\n\t" \ + "1:" \ + "movcs %%xcc,-1,%0\n" \ + : "=&r" (__ret), "+m" (errno) \ + : "r" (__g1) \ + : "cc"); \ + return (type) __ret; \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name (type1 arg1) \ +{ \ + register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ + register unsigned long __ret __asm__("o0"); \ + type1 __o0 = (arg1); \ + __asm__ __volatile__ ("t 0x6d\n\t" \ + "bcs,a %%xcc, 1f\n\t" \ + " st %0,%1\n\t" \ + "1:" \ + "movcs %%xcc,-1,%0\n" \ + : "=&r" (__ret), "+m" (errno) \ + : "0" (__o0), "r" (__g1) \ + : "cc"); \ + return (type) __ret; \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name (type1 arg1,type2 arg2) \ +{ \ + register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ + register unsigned long __ret __asm__("o0"); \ + type1 __o0 = (arg1); \ + register type2 __o1 __asm__ ("o1") = (arg2); \ + __asm__ __volatile__ ("t 0x6d\n\t" \ + "bcs,a %%xcc, 1f\n\t" \ + " st %0,%1\n\t" \ + "1:" \ + "movcs %%xcc,-1,%0\n" \ + : "=&r" (__ret), "+m" (errno) \ + : "0" (__o0), "r" (__o1), "r" (__g1) \ + : "cc"); \ + return (type) __ret; \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name (type1 arg1,type2 arg2,type3 arg3) \ +{ \ + register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ + register unsigned long __ret __asm__("o0"); \ + type1 __o0 = (arg1); \ + register type2 __o1 __asm__ ("o1") = (arg2); \ + register type3 __o2 __asm__ ("o2") = (arg3); \ + __asm__ __volatile__ ("t 0x6d\n\t" \ + "bcs,a %%xcc, 1f\n\t" \ + " st %0,%1\n\t" \ + "1:" \ + "movcs %%xcc,-1,%0\n" \ + : "=&r" (__ret), "+m" (errno) \ + : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ + : "cc"); \ + return (type) __ret; \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ +{ \ + register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ + register unsigned long __ret __asm__("o0"); \ + type1 __o0 = (arg1); \ + register type2 __o1 __asm__ ("o1") = (arg2); \ + register type3 __o2 __asm__ ("o2") = (arg3); \ + register type4 __o3 __asm__ ("o3") = (arg4); \ + __asm__ __volatile__ ("t 0x6d\n\t" \ + "bcs,a %%xcc, 1f\n\t" \ + " st %0,%1\n\t" \ + "1:" \ + "movcs %%xcc,-1,%0\n" \ + : "=&r" (__ret), "+m" (errno) \ + : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ + : "cc"); \ + return (type) __ret; \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ + register unsigned long __ret __asm__("o0"); \ + type1 __o0 = (arg1); \ + register type2 __o1 __asm__ ("o1") = (arg2); \ + register type3 __o2 __asm__ ("o2") = (arg3); \ + register type4 __o3 __asm__ ("o3") = (arg4); \ + register type5 __o4 __asm__ ("o4") = (arg5); \ + __asm__ __volatile__ ("t 0x6d\n\t" \ + "bcs,a %%xcc, 1f\n\t" \ + " st %0,%1\n\t" \ + "1:" \ + "movcs %%xcc,-1,%0\n" \ + : "=&r" (__ret), "+m" (errno) \ + : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), \ + "r" (__g1) \ + : "cc"); \ + return (type) __ret; \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ + register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ + register unsigned long __ret __asm__("o0"); \ + type1 __o0 = (arg1); \ + register type2 __o1 __asm__ ("o1") = (arg2); \ + register type3 __o2 __asm__ ("o2") = (arg3); \ + register type4 __o3 __asm__ ("o3") = (arg4); \ + register type5 __o4 __asm__ ("o4") = (arg5); \ + register type6 __o5 __asm__ ("o5") = (arg6); \ + __asm__ __volatile__ ("t 0x6d\n\t" \ + "bcs,a %%xcc, 1f\n\t" \ + " st %0,%1\n\t" \ + "1:" \ + "movcs %%xcc,-1,%0\n" \ + : "=&r" (__ret), "+m" (errno) \ + : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), \ + "r" (__o5), "r" (__g1) \ + : "cc"); \ + return (type) __ret; \ +} + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/sparc64/setjmp.S b/klibc/klibc/arch/sparc64/setjmp.S new file mode 100644 index 0000000000..b04d47faab --- /dev/null +++ b/klibc/klibc/arch/sparc64/setjmp.S @@ -0,0 +1,55 @@ +! +! setjmp.S +! +! Basic setjmp/longjmp +! +! This code was based on the equivalent code in NetBSD +! + +! +! The jmp_buf contains the following entries: +! sp +! fp +! pc +! + .text + .align 4 + .global setjmp + .type setjmp, @function +setjmp: + stx %sp,[%o0+0] ! Callers stack pointer + stx %o7,[%o0+8] ! Return pc + stx %fp,[%o0+16] ! Frame pointer + retl ! Return + clr %o0 ! ...0 + + .size setjmp,.-setjmp + + + .globl longjmp + .type longjmp, @function +longjmp: + mov %o1, %g4 ! save return value + mov %o0, %g1 ! save target + ldx [%g1+16],%g5 ! get callers frame +1: + cmp %fp, %g5 ! compare against desired frame + bl,a 1b ! if below... + restore ! pop frame and loop + be,a 2f ! if there... + ldx [%g1+0],%o2 ! fetch return %sp + +.Lbotch: + unimp 0 ! ... error ... + +2: + cmp %o2, %sp ! %sp must not decrease + bl .Lbotch + nop + mov %o2, %sp ! it is OK, put it in place + + ldx [%g1+8],%o3 ! fetch %pc + jmp %o3 + 8 ! if sucess... + mov %g4,%o0 ! return %g4 + + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG new file mode 100644 index 0000000000..ecb14ccb70 --- /dev/null +++ b/klibc/klibc/arch/x86_64/MCONFIG @@ -0,0 +1,16 @@ +# -*- makefile -*- +# +# arch/x86-64/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# +# Blatantly copied and modified from i386 version by Mats Petersson, AMD. +# + +ARCHREQFLAGS = -m64 +OPTFLAGS = -Os -fomit-frame-pointer -falign-functions=0 -falign-jumps=0 -falign-loops=0 +BITSIZE = 64 +LDFLAGS = -m elf_x86_64 + diff --git a/klibc/klibc/arch/x86_64/Makefile.inc b/klibc/klibc/arch/x86_64/Makefile.inc new file mode 100644 index 0000000000..c84443f4e1 --- /dev/null +++ b/klibc/klibc/arch/x86_64/Makefile.inc @@ -0,0 +1,16 @@ +# -*- makefile -*- +# +# arch/x86_64/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/exits.o \ + arch/$(ARCH)/setjmp.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + +archclean: diff --git a/klibc/klibc/arch/x86_64/crt0.S b/klibc/klibc/arch/x86_64/crt0.S new file mode 100644 index 0000000000..c562708d0f --- /dev/null +++ b/klibc/klibc/arch/x86_64/crt0.S @@ -0,0 +1,22 @@ +# +# arch/x86_64/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + + .text + .align 4 + .type _start,@function + .globl _start +_start: + movq %rsp,%rdi # Offset of the ELF data structure + movq %rdx,%rsi # The atexit() pointer (if any) + call __libc_init + # We should never get here... + hlt + + .size _start,.-_start diff --git a/klibc/klibc/arch/x86_64/exits.S b/klibc/klibc/arch/x86_64/exits.S new file mode 100644 index 0000000000..618f4fb585 --- /dev/null +++ b/klibc/klibc/arch/x86_64/exits.S @@ -0,0 +1,35 @@ +# +# exit and _exit get included in *every* program, and gcc generates +# horrible code for them. Yes, this only saves a few bytes, but +# it does it in every program. +# + +#include + + .data + .align 8 + .globl __exit_handler + .type __exit_handler,@object +__exit_handler: + .quad _exit + .size __exit_handler,8 + + .text + .align 8 + .globl exit + .type exit,@function +exit: + jmp *(__exit_handler) + .size exit,.-exit + + /* No need to save any registers... we're exiting! */ + .text + .align 4 + .globl _exit + .type _exit,@function +_exit: + movl $__NR_exit,%eax + /* The argument is already in %rdi */ + syscall + .size _exit,.-exit + diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h b/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..90d0a0d263 --- /dev/null +++ b/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h @@ -0,0 +1,21 @@ +/* + * arch/x86_64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __rbx; + unsigned long __rsp; + unsigned long __rbp; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __rip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsys.h b/klibc/klibc/arch/x86_64/include/klibc/archsys.h new file mode 100644 index 0000000000..3bd8b0a5d9 --- /dev/null +++ b/klibc/klibc/arch/x86_64/include/klibc/archsys.h @@ -0,0 +1,32 @@ +/* + * arch/x86_64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* x86-64 seems to miss _syscall6() from its headers */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ +register type4 __r10 asm("%r10") = arg4; \ +register type5 __r8 asm("%r8") = arg5; \ +register type6 __r9 asm("%r9") = arg6; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3),"r" (__r10),"r" (__r8), "r" (__r9) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#endif /* _syscall6 missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/x86_64/setjmp.S b/klibc/klibc/arch/x86_64/setjmp.S new file mode 100644 index 0000000000..45f547b404 --- /dev/null +++ b/klibc/klibc/arch/x86_64/setjmp.S @@ -0,0 +1,54 @@ +# +# arch/x86_64/setjmp.S +# +# setjmp/longjmp for the x86-64 architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# %rbx +# %rsp (post-return) +# %rbp +# %r12 +# %r13 +# %r14 +# %r15 +# +# + + .text + .align 4 + .globl setjmp + .type setjmp, @function +setjmp: + pop %rsi # Return address, and adjust the stack + xorl %eax,%eax # Return value + movq %rbx,(%rdi) + movq %rsp,8(%rdi) # Post-return %rsp! + push %rsi # Make the call/return stack happy + movq %rbp,16(%rdi) + movq %r12,24(%rdi) + movq %r13,32(%rdi) + movq %r14,40(%rdi) + movq %r15,48(%rdi) + movq %rsi,56(%rdi) # Return address + ret + + .size setjmp,.-setjmp + + .text + .align 4 + .globl longjmp + .type longjmp, @function +longjmp: + movl %esi,%eax # Return value (int) + movq (%rdi),%rbx + movq 8(%rdi),%rsp + movq 16(%rdi),%rbp + movq 24(%rdi),%r12 + movq 32(%rdi),%r13 + movq 40(%rdi),%r14 + movq 48(%rdi),%r15 + jmp *56(%rdi) + + .size longjmp,.-longjmp diff --git a/klibc/klibc/assert.c b/klibc/klibc/assert.c new file mode 100644 index 0000000000..6d3ff238c9 --- /dev/null +++ b/klibc/klibc/assert.c @@ -0,0 +1,13 @@ +/* + * assert.c + */ + +#include +#include +#include + +void __assert_fail(const char *expr, const char *file, unsigned int line) +{ + printf("Assertion %s failed, file %s, line %u\n", expr, file, line); + abort(); +} diff --git a/klibc/klibc/atexit.c b/klibc/klibc/atexit.c new file mode 100644 index 0000000000..078dd8b211 --- /dev/null +++ b/klibc/klibc/atexit.c @@ -0,0 +1,10 @@ +/* + * atexit.c + */ + +#include + +int atexit(void (*fctn)(void)) +{ + return on_exit((void (*)(int, void *))fctn, NULL); +} diff --git a/klibc/klibc/atexit.h b/klibc/klibc/atexit.h new file mode 100644 index 0000000000..a60d641e23 --- /dev/null +++ b/klibc/klibc/atexit.h @@ -0,0 +1,19 @@ +/* + * atexit.h + * + * atexit()/on_exit() internal definitions + */ + +#ifndef ATEXIT_H +#define ATEXIT_H + +struct atexit { + void (*fctn)(int, void *); + void *arg; /* on_exit() parameter */ + struct atexit *next; +}; + +extern struct atexit *__atexit_list; + +#endif /* ATEXIT_H */ + diff --git a/klibc/klibc/atoi.c b/klibc/klibc/atoi.c new file mode 100644 index 0000000000..a6ec0bf778 --- /dev/null +++ b/klibc/klibc/atoi.c @@ -0,0 +1,3 @@ +#define TYPE int +#define NAME atoi +#include "atox.c" diff --git a/klibc/klibc/atol.c b/klibc/klibc/atol.c new file mode 100644 index 0000000000..e65484e7f1 --- /dev/null +++ b/klibc/klibc/atol.c @@ -0,0 +1,3 @@ +#define TYPE long +#define NAME atol +#include "atox.c" diff --git a/klibc/klibc/atoll.c b/klibc/klibc/atoll.c new file mode 100644 index 0000000000..25df79e1bf --- /dev/null +++ b/klibc/klibc/atoll.c @@ -0,0 +1,3 @@ +#define TYPE long long +#define NAME atoll +#include "atox.c" diff --git a/klibc/klibc/atox.c b/klibc/klibc/atox.c new file mode 100644 index 0000000000..56f8d93b40 --- /dev/null +++ b/klibc/klibc/atox.c @@ -0,0 +1,14 @@ +/* + * atox.c + * + * atoi(), atol(), atoll() + */ + +#include +#include +#include + +TYPE NAME (const char *nptr) +{ + return (TYPE) strntoumax(nptr, (char **)NULL, 10, ~(size_t)0); +} diff --git a/klibc/klibc/brk.c b/klibc/klibc/brk.c new file mode 100644 index 0000000000..0a08c4e1c5 --- /dev/null +++ b/klibc/klibc/brk.c @@ -0,0 +1,24 @@ +/* brk.c - Change data segment size */ + +/* Written 2000 by Werner Almesberger */ + + +#include +#include +#include + +char *__current_brk; /* Common with sbrk.c */ + +/* + * The Linux brk() isn't what most people expect, so we call the + * system call __brk() and provide a wrapper. + */ +int brk(void *end_data_segment) +{ + char *new_brk; + + new_brk = __brk(end_data_segment); + if (new_brk != end_data_segment) return -1; + __current_brk = new_brk; + return 0; +} diff --git a/klibc/klibc/bsd_signal.c b/klibc/klibc/bsd_signal.c new file mode 100644 index 0000000000..9acc867a36 --- /dev/null +++ b/klibc/klibc/bsd_signal.c @@ -0,0 +1,11 @@ +/* + * bsd_signal.c + */ + +#include + +__sighandler_t bsd_signal(int signum, __sighandler_t handler) +{ + /* BSD signal() semantics */ + return __signal(signum, handler, SA_RESTART); +} diff --git a/klibc/klibc/calloc.c b/klibc/klibc/calloc.c new file mode 100644 index 0000000000..228a1b70e4 --- /dev/null +++ b/klibc/klibc/calloc.c @@ -0,0 +1,21 @@ +/* + * calloc.c + */ + +#include +#include + +/* FIXME: This should look for multiplication overflow */ + +void *calloc(size_t nmemb, size_t size) +{ + void *ptr; + + size *= nmemb; + ptr = malloc(size); + if ( ptr ) + memset(ptr, 0, size); + + return ptr; +} + diff --git a/klibc/klibc/closelog.c b/klibc/klibc/closelog.c new file mode 100644 index 0000000000..2359d4f92b --- /dev/null +++ b/klibc/klibc/closelog.c @@ -0,0 +1,18 @@ +/* + * closelog.c + */ + +#include +#include + +extern int __syslog_fd; + +void closelog(void) +{ + int logfd = __syslog_fd; + + if ( logfd != -1 ) { + close(logfd); + __syslog_fd = -1; + } +} diff --git a/klibc/klibc/creat.c b/klibc/klibc/creat.c new file mode 100644 index 0000000000..9bd22172d4 --- /dev/null +++ b/klibc/klibc/creat.c @@ -0,0 +1,12 @@ +/* + * creat.c + */ + +#include +#include +#include + +int creat(const char *pathname, mode_t mode) +{ + return open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode); +} diff --git a/klibc/klibc/ctypes.c b/klibc/klibc/ctypes.c new file mode 100644 index 0000000000..a9398b8071 --- /dev/null +++ b/klibc/klibc/ctypes.c @@ -0,0 +1,281 @@ +/* + * ctypes.c + * + * This is the array that defines classes. + * This assumes ISO 8859-1. + */ + +#include + +const unsigned char __ctypes[257] = { + 0, /* EOF */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + __ctype_space, /* BS */ + __ctype_space, /* TAB */ + __ctype_space, /* LF */ + __ctype_space, /* VT */ + __ctype_space, /* FF */ + __ctype_space, /* CR */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + + __ctype_space|__ctype_print, /* space */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ + __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ + __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ + __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ + __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ + __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_upper|__ctype_print, /* G-Z */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ + __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ + __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ + __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ + __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ + __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_lower|__ctype_print, /* g-z */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + 0, /* control character */ + + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + 0, /* control character */ + + __ctype_space|__ctype_print, /* NBSP */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_print|__ctype_punct, /* punctuation */ + + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_upper|__ctype_print, /* upper accented */ + __ctype_lower|__ctype_print, /* lower accented */ + + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_print|__ctype_punct, /* punctuation */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ + __ctype_lower|__ctype_print, /* lower accented */ +}; diff --git a/klibc/klibc/exec_l.c b/klibc/klibc/exec_l.c new file mode 100644 index 0000000000..cdae11e981 --- /dev/null +++ b/klibc/klibc/exec_l.c @@ -0,0 +1,57 @@ +/* + * exec_l.c + * + * Common implementation of execl() execle() execlp() + */ + +#include +#include +#include + +int NAME (const char *path, const char *arg0, ...) +{ + va_list ap, cap; + int argc = 1, rv; + const char **argv, **argp; + const char *arg; +#if EXEC_E + char * const * envp; +#else +#define envp environ +#endif + + va_start(ap, arg0); + va_copy(cap, ap); + + /* Count the number of arguments */ + do { + arg = va_arg(cap, const char *); + argc++; + } while ( arg ); + + va_end(cap); + + /* Allocate memory for the pointer array */ + argp = argv = alloca(argc*sizeof(const char *)); + if ( !argv ) { + va_end(ap); + return -1; + } + + /* Copy the list into an array */ + *argp++ = arg0; + do { + *argp++ = arg = va_arg(ap, const char *); + } while ( arg ); + +#if EXEC_E + /* execle() takes one more argument for the environment pointer */ + envp = va_arg(ap, char * const *); +#endif + + rv = (EXEC_P ? execvpe : execve)(path, (char * const *)argv, envp); + + va_end(ap); + + return rv; +} diff --git a/klibc/klibc/execl.c b/klibc/klibc/execl.c new file mode 100644 index 0000000000..4581113ba5 --- /dev/null +++ b/klibc/klibc/execl.c @@ -0,0 +1,8 @@ +/* + * execl.c + */ + +#define NAME execl +#define EXEC_P 0 +#define EXEC_E 0 +#include "exec_l.c" diff --git a/klibc/klibc/execle.c b/klibc/klibc/execle.c new file mode 100644 index 0000000000..b073988835 --- /dev/null +++ b/klibc/klibc/execle.c @@ -0,0 +1,8 @@ +/* + * execle.c + */ + +#define NAME execle +#define EXEC_P 0 +#define EXEC_E 1 +#include "exec_l.c" diff --git a/klibc/klibc/execlp.c b/klibc/klibc/execlp.c new file mode 100644 index 0000000000..65c9aa4a7a --- /dev/null +++ b/klibc/klibc/execlp.c @@ -0,0 +1,8 @@ +/* + * execlp.c + */ + +#define NAME execlp +#define EXEC_P 1 +#define EXEC_E 0 +#include "exec_l.c" diff --git a/klibc/klibc/execlpe.c b/klibc/klibc/execlpe.c new file mode 100644 index 0000000000..fef972fcb3 --- /dev/null +++ b/klibc/klibc/execlpe.c @@ -0,0 +1,8 @@ +/* + * execlpe.c + */ + +#define NAME execlpe +#define EXEC_P 1 +#define EXEC_E 1 +#include "exec_l.c" diff --git a/klibc/klibc/execv.c b/klibc/klibc/execv.c new file mode 100644 index 0000000000..9856b76d87 --- /dev/null +++ b/klibc/klibc/execv.c @@ -0,0 +1,13 @@ +/* + * execv.c + */ + +#include +#include + +int execv(const char *path, char * const * argv) +{ + return execve(path, argv, environ); +} + + diff --git a/klibc/klibc/execvp.c b/klibc/klibc/execvp.c new file mode 100644 index 0000000000..b1065ee47e --- /dev/null +++ b/klibc/klibc/execvp.c @@ -0,0 +1,13 @@ +/* + * execvp.c + */ + +#include +#include + +int execvp(const char *path, char * const * argv) +{ + return execvpe(path, argv, environ); +} + + diff --git a/klibc/klibc/execvpe.c b/klibc/klibc/execvpe.c new file mode 100644 index 0000000000..afd791ab43 --- /dev/null +++ b/klibc/klibc/execvpe.c @@ -0,0 +1,73 @@ +/* + * execvpe.c + * + * execvpe() function (from which we build execlp, execlpe, execvp). + * + * This version of execvpe() will *not* spawn /bin/sh if the command + * return ENOEXEC. That's what #! is for, folks! + * + * Since execlpe() and execvpe() aren't in POSIX, nor in glibc, + * I have followed QNX precedent in the implementation of the PATH: + * the PATH that is used is the one in the current environment, not + * in the new environment. + */ + +#include +#include +#include +#include +#include + +#define DEFAULT_PATH "/bin:/usr/bin:." + +int execvpe(const char *file, char * const *argv, char * const *envp) +{ + char path[PATH_MAX]; + const char *searchpath, *esp; + size_t prefixlen, filelen, totallen; + + if ( strchr(file, '/') ) /* Specific path */ + return execve(file, argv, envp); + + filelen = strlen(file); + + searchpath = getenv("PATH"); + if ( !searchpath ) + searchpath = DEFAULT_PATH; + + errno = ENOENT; /* Default errno, if execve() doesn't change it */ + + do { + esp = strchr(searchpath, ':'); + if ( esp ) + prefixlen = esp-searchpath; + else + prefixlen = strlen(searchpath); + + if ( prefixlen == 0 || searchpath[prefixlen-1] == '/' ) { + totallen = prefixlen+filelen; + if ( totallen >= PATH_MAX ) + continue; + memcpy(path, searchpath, prefixlen); + memcpy(path+prefixlen, file, filelen); + } else { + totallen = prefixlen+filelen+1; + if ( totallen >= PATH_MAX ) + continue; + memcpy(path, searchpath, prefixlen); + path[prefixlen] = '/'; + memcpy(path+prefixlen+1, file, filelen); + } + path[totallen] = '\0'; + + execve(path, argv, envp); + if ( errno == E2BIG || errno == ENOEXEC || + errno == ENOMEM || errno == ETXTBSY ) + break; /* Report this as an error, no more search */ + + searchpath = esp+1; + } while ( esp ); + + return -1; +} + diff --git a/klibc/klibc/exitc.c b/klibc/klibc/exitc.c new file mode 100644 index 0000000000..6e5d78979d --- /dev/null +++ b/klibc/klibc/exitc.c @@ -0,0 +1,36 @@ +/* + * exit.c + * + * Note: all programs need exit(), since it's invoked from + * crt0.o. Therefore there is no point in breaking apart + * exit() and _exit(). + */ + +#include +#include +#include + +/* We have an assembly version for i386 and x86-64 */ + +#if !defined(__i386__) && !defined(__x86_64__) + +#define __NR___exit __NR_exit + +/* Syscalls can't return void... */ +static inline _syscall1(int,__exit,int,rv); + +/* This allows atexit/on_exit to install a hook */ +__noreturn (*__exit_handler)(int) = _exit; + +__noreturn exit(int rv) +{ + __exit_handler(rv); +} + +__noreturn _exit(int rv) +{ + __exit(rv); + for(;;); +} + +#endif diff --git a/klibc/klibc/fdatasync.c b/klibc/klibc/fdatasync.c new file mode 100644 index 0000000000..53079b09d6 --- /dev/null +++ b/klibc/klibc/fdatasync.c @@ -0,0 +1,15 @@ +/* + * fdatasync.c + * + * Some systems don't have this (alpha?) ... this is really a bug, + * but mimic using fsync() + */ + +#include +#include + +#ifndef __NR_fdatasync +#define __NR_fdatasync __NR_fsync +#endif + +_syscall1(int,fdatasync,int,fd); diff --git a/klibc/klibc/fgetc.c b/klibc/klibc/fgetc.c new file mode 100644 index 0000000000..83eee16f61 --- /dev/null +++ b/klibc/klibc/fgetc.c @@ -0,0 +1,20 @@ +/* + * fgetc.c + * + * Extremely slow fgetc implementation, using _fread(). If people + * actually need character-oriented input to be fast, we may actually + * have to implement buffering. Sigh. + */ + +#include +#include +#include +#include + +int fgetc(FILE *f) +{ + unsigned char ch; + + return (_fread(&ch, 1, f) == 1) ? (int)ch : EOF; +} + diff --git a/klibc/klibc/fgets.c b/klibc/klibc/fgets.c new file mode 100644 index 0000000000..88a145a63f --- /dev/null +++ b/klibc/klibc/fgets.c @@ -0,0 +1,33 @@ +/* + * fgets.c + * + * This will be very slow due to the implementation of getc(), + * but we can't afford to drain characters we don't need from + * the input. + */ + +#include + +char *fgets(char *s, int n, FILE *f) +{ + int ch; + char *p = s; + + while ( n > 1 ) { + ch = getc(f); + if ( ch == EOF ) { + *p = '\0'; + return NULL; + } + *p++ = ch; + if ( ch == '\n' ) + break; + } + if ( n ) + *p = '\0'; + + return s; +} + + + diff --git a/klibc/klibc/fopen.c b/klibc/klibc/fopen.c new file mode 100644 index 0000000000..5c84184809 --- /dev/null +++ b/klibc/klibc/fopen.c @@ -0,0 +1,46 @@ +/* + * fopen.c + */ + +#include +#include +#include + +/* This depends on O_RDONLY == 0, O_WRONLY == 1, O_RDWR == 2 */ + + +FILE *fopen(const char *file, const char *mode) +{ + int flags = O_RDONLY; + int plus = 0; + int fd; + + while ( *mode ) { + switch ( *mode ) { + case 'r': + flags = O_RDONLY; + break; + case 'w': + flags = O_WRONLY|O_CREAT|O_TRUNC; + break; + case 'a': + flags = O_WRONLY|O_CREAT|O_APPEND; + break; + case '+': + plus = 1; + break; + } + mode++; + } + + if ( plus ) { + flags = (flags & ~(O_RDONLY|O_WRONLY)) | O_RDWR; + } + + fd = open(file, flags, 0666); + + if ( fd < 0 ) + return NULL; + else + return fdopen(fd, mode); +} diff --git a/klibc/klibc/fork.c b/klibc/klibc/fork.c new file mode 100644 index 0000000000..d7e4db89a1 --- /dev/null +++ b/klibc/klibc/fork.c @@ -0,0 +1,29 @@ +/* + * fork.c + * + * This is normally just a syscall stub, but at least one system + * doesn't have sys_fork, only sys_clone... + */ + +#include +#include +#include + +#ifdef __NR_fork + +#ifdef _syscall0_forkish +_syscall0_forkish(pid_t,fork); +#else +_syscall0(pid_t,fork); +#endif + +#else /* __NR_fork */ + +static inline _syscall2(pid_t,clone,unsigned long,flags,void *,newsp); + +pid_t fork(void) +{ + return clone(SIGCHLD, 0); +} + +#endif /* __NR_fork */ diff --git a/klibc/klibc/fprintf.c b/klibc/klibc/fprintf.c new file mode 100644 index 0000000000..df3823eac3 --- /dev/null +++ b/klibc/klibc/fprintf.c @@ -0,0 +1,19 @@ +/* + * fprintf.c + */ + +#include +#include + +#define BUFFER_SIZE 16384 + +int fprintf(FILE *file, const char *format, ...) +{ + va_list ap; + int rv; + + va_start(ap, format); + rv = vfprintf(file, format, ap); + va_end(ap); + return rv; +} diff --git a/klibc/klibc/fputc.c b/klibc/klibc/fputc.c new file mode 100644 index 0000000000..61aff1644b --- /dev/null +++ b/klibc/klibc/fputc.c @@ -0,0 +1,14 @@ +/* + * fputc.c + * + * gcc "printf decompilation" expects this to exist... + */ + +#include + +int fputc(int c, FILE *f) +{ + unsigned char ch = c; + + return _fwrite(&ch, 1, f) == 1 ? ch : EOF; +} diff --git a/klibc/klibc/fputs.c b/klibc/klibc/fputs.c new file mode 100644 index 0000000000..4b68f96886 --- /dev/null +++ b/klibc/klibc/fputs.c @@ -0,0 +1,15 @@ +/* + * fputs.c + * + * This isn't quite fputs() in the stdio sense, since we don't + * have stdio, but it takes a file descriptor argument instead + * of the FILE *. + */ + +#include +#include + +int fputs(const char *s, FILE *file) +{ + return _fwrite(s, strlen(s), file); +} diff --git a/klibc/klibc/fread.c b/klibc/klibc/fread.c new file mode 100644 index 0000000000..8f7dba9c19 --- /dev/null +++ b/klibc/klibc/fread.c @@ -0,0 +1,35 @@ +/* + * fread.c + */ + +#include +#include +#include + +size_t _fread(void *buf, size_t count, FILE *f) +{ + size_t bytes = 0; + ssize_t rv; + char *p = buf; + + while ( count ) { + rv = read(fileno(f), p, count); + if ( rv == -1 ) { + if ( errno == EINTR ) + continue; + else + break; + } else if ( rv == 0 ) { + break; + } + + p += rv; + bytes += rv; + count -= rv; + } + + return bytes; +} + + + diff --git a/klibc/klibc/fread2.c b/klibc/klibc/fread2.c new file mode 100644 index 0000000000..9e5ac81fc2 --- /dev/null +++ b/klibc/klibc/fread2.c @@ -0,0 +1,13 @@ +/* + * fread2.c + * + * The actual fread() function as a non-inline + */ + +#define __NO_FREAD_FWRITE_INLINES +#include + +size_t fread(void *ptr, size_t size, size_t nmemb, FILE *f) +{ + return _fread(ptr, size*nmemb, f)/size; +} diff --git a/klibc/klibc/fwrite.c b/klibc/klibc/fwrite.c new file mode 100644 index 0000000000..0a73188c67 --- /dev/null +++ b/klibc/klibc/fwrite.c @@ -0,0 +1,35 @@ +/* + * fwrite.c + */ + +#include +#include +#include + +size_t _fwrite(const void *buf, size_t count, FILE *f) +{ + size_t bytes = 0; + ssize_t rv; + const char *p = buf; + + while ( count ) { + rv = write(fileno(f), p, count); + if ( rv == -1 ) { + if ( errno == EINTR ) + continue; + else + break; + } else if ( rv == 0 ) { + break; + } + + p += rv; + bytes += rv; + count -= rv; + } + + return bytes; +} + + + diff --git a/klibc/klibc/fwrite2.c b/klibc/klibc/fwrite2.c new file mode 100644 index 0000000000..82ec832be4 --- /dev/null +++ b/klibc/klibc/fwrite2.c @@ -0,0 +1,13 @@ +/* + * fwrite2.c + * + * The actual fwrite() function as a non-inline + */ + +#define __NO_FREAD_FWRITE_INLINES +#include + +size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *f) +{ + return _fwrite(ptr, size*nmemb, f)/size; +} diff --git a/klibc/klibc/getcwd.c b/klibc/klibc/getcwd.c new file mode 100644 index 0000000000..350ec69a63 --- /dev/null +++ b/klibc/klibc/getcwd.c @@ -0,0 +1,15 @@ +/* + * getcwd.c + */ + +#include +#include + +#define __NR___getcwd __NR_getcwd +static inline _syscall2(int,__getcwd,char *,buf,size_t,size); + +char *getcwd(char *buf, size_t size) +{ + return ( __getcwd(buf, size) < 0 ) ? NULL : buf; +} + diff --git a/klibc/klibc/getdomainname.c b/klibc/klibc/getdomainname.c new file mode 100644 index 0000000000..4cd68a3cb5 --- /dev/null +++ b/klibc/klibc/getdomainname.c @@ -0,0 +1,25 @@ +/* + * getdomainname.c + */ + +#include +#include +#include +#include + +int getdomainname(char *name, size_t len) +{ + struct utsname un; + + if ( !uname(&un) ) + return -1; + + if ( len < strlen(un.domainname)+1 ) { + errno = EINVAL; + return -1; + } + + strcpy(name, un.domainname); + + return 0; +} diff --git a/klibc/klibc/getenv.c b/klibc/klibc/getenv.c new file mode 100644 index 0000000000..84fc94c00e --- /dev/null +++ b/klibc/klibc/getenv.c @@ -0,0 +1,22 @@ +/* + * getenv.c + */ + +#include +#include +#include + +char *getenv(const char *name) +{ + char **p, *q; + int len = strlen(name); + + for ( p = environ ; (q = *p) ; p++ ) { + if ( !strncmp(name, q, len) && q[len] == '=' ) { + return q+(len+1); + } + } + + return NULL; +} + diff --git a/klibc/klibc/gethostname.c b/klibc/klibc/gethostname.c new file mode 100644 index 0000000000..6c5062e816 --- /dev/null +++ b/klibc/klibc/gethostname.c @@ -0,0 +1,25 @@ +/* + * gethostname.c + */ + +#include +#include +#include +#include + +int gethostname(char *name, size_t len) +{ + struct utsname un; + + if ( !uname(&un) ) + return -1; + + if ( len < strlen(un.nodename)+1 ) { + errno = EINVAL; + return -1; + } + + strcpy(name, un.nodename); + + return 0; +} diff --git a/klibc/klibc/getopt.c b/klibc/klibc/getopt.c new file mode 100644 index 0000000000..5a992dcdd7 --- /dev/null +++ b/klibc/klibc/getopt.c @@ -0,0 +1,74 @@ +/* + * getopt.c + * + * Simple POSIX getopt(), no GNU extensions... + */ + +#include +#include +#include + +char *optarg; +int optind = 1; +int opterr, optopt; +static const char *__optptr; + +int getopt(int argc, char * const *argv, const char *optstring) +{ + const char *carg = argv[optind]; + const char *osptr; + int opt; + + /* We don't actually need argc */ + (void)argc; + + /* First, eliminate all non-option cases */ + + if ( !carg || carg[0] != '-' || !carg[1] ) { + return -1; + } + + if ( carg[1] == '-' && !carg[2] ) { + optind++; + return -1; + } + + if ( (uintptr_t)(__optptr-carg) > (uintptr_t)strlen(carg) ) + __optptr = carg+1; /* Someone frobbed optind, change to new opt. */ + + opt = *__optptr++; + + if ( opt != ':' && (osptr = strchr(optstring, opt)) ) { + if ( osptr[1] == ':' ) { + if ( *__optptr ) { + /* Argument-taking option with attached argument */ + optarg = (char *)__optptr; + optind++; + } else { + /* Argument-taking option with non-attached argument */ + if ( argv[optind+1] ) { + optarg = (char *)argv[optind+1]; + optind += 2; + } else { + /* Missing argument */ + return (optstring[0] == ':') ? ':' : '?'; + } + } + return opt; + } else { + /* Non-argument-taking option */ + /* __optptr will remember the exact position to resume at */ + if ( ! *__optptr ) + optind++; + return opt; + } + } else { + /* Unknown option */ + optopt = opt; + if ( ! *__optptr ) + optind++; + return '?'; + } +} + + diff --git a/klibc/klibc/getpriority.c b/klibc/klibc/getpriority.c new file mode 100644 index 0000000000..d6db2cc6b9 --- /dev/null +++ b/klibc/klibc/getpriority.c @@ -0,0 +1,25 @@ +/* + * getpriority.c + * + * Needs to do some post-syscall mangling to distinguish error returns... + * but only on some platforms. Sigh. + */ + +#include +#include +#include +#include + +#define __NR__getpriority __NR_getpriority + +static inline _syscall2(int,_getpriority,int,which,int,who); + +int getpriority(int which, int who) +{ +#if defined(__alpha__) || defined(__ia64__) + return _getpriority(which, who); +#else + int rv = _getpriority(which, who); + return ( rv < 0 ) ? rv : 20-rv; +#endif +} diff --git a/klibc/klibc/globals.c b/klibc/klibc/globals.c new file mode 100644 index 0000000000..72ae91fbad --- /dev/null +++ b/klibc/klibc/globals.c @@ -0,0 +1,10 @@ +/* + * globals.c + * + * These have to be defined somewhere... + */ +#include +#include + +int errno; +char **environ; diff --git a/klibc/klibc/include/alloca.h b/klibc/klibc/include/alloca.h new file mode 100644 index 0000000000..41a4d94d44 --- /dev/null +++ b/klibc/klibc/include/alloca.h @@ -0,0 +1,13 @@ +/* + * alloca.h + * + * Just call the builtin alloca() function + */ + +#ifndef _ALLOCA_H +#define _ALLOCA_H + +#define alloca(size) __builtin_alloca(size) + +#endif /* _ALLOCA_H */ + diff --git a/klibc/klibc/include/arpa/inet.h b/klibc/klibc/include/arpa/inet.h new file mode 100644 index 0000000000..043b148e17 --- /dev/null +++ b/klibc/klibc/include/arpa/inet.h @@ -0,0 +1,24 @@ +/* + * arpa/inet.h + */ + +#ifndef _ARPA_INET_H +#define _ARPA_INET_H + +#include +#include +#include +#include +#include + +__extern uint32_t inet_addr(const char *); +__extern int inet_aton(const char *, struct in_addr *); +__extern char *inet_ntoa(struct in_addr); +__extern int inet_pton(int, const char *, void *); +__extern const char *inet_ntop(int, const void *, char *, size_t); +__extern unsigned int inet_nsap_addr(const char *, unsigned char *, int); +__extern char *inet_nsap_ntoa(int, const unsigned char *, char *); + +#endif /* _ARPA_INET_H */ + + diff --git a/klibc/klibc/include/assert.h b/klibc/klibc/include/assert.h new file mode 100644 index 0000000000..58cc37c487 --- /dev/null +++ b/klibc/klibc/include/assert.h @@ -0,0 +1,22 @@ +/* + * assert.h + */ + +#ifndef _ASSERT_H +#define _ASSERT_H + +#ifdef NDEBUG + +#define assert(x) ((void)(x)) + +#else + +extern void __assert_fail(const char *, const char *, + unsigned int); + +#define assert(x) ((x) ? (void)0 : __assert_fail(#x, __FILE__, __LINE__)) + +#endif + +#endif /* _ASSERT_H */ + diff --git a/klibc/klibc/include/bits32/bitsize/limits.h b/klibc/klibc/include/bits32/bitsize/limits.h new file mode 100644 index 0000000000..f90e524b2b --- /dev/null +++ b/klibc/klibc/include/bits32/bitsize/limits.h @@ -0,0 +1,14 @@ +/* + * bits32/limits.h + */ + +#ifndef _BITSIZE_LIMITS_H +#define _BITSIZE_LIMITS_H + +#define LONG_BIT 32 + +#define LONG_MIN (-2147483647L-1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stddef.h b/klibc/klibc/include/bits32/bitsize/stddef.h new file mode 100644 index 0000000000..bf6e695ed3 --- /dev/null +++ b/klibc/klibc/include/bits32/bitsize/stddef.h @@ -0,0 +1,18 @@ +/* + * bits32/stddef.h + */ + +#ifndef _BITSIZE_STDDEF_H +#define _BITSIZE_STDDEF_H + +#define _SIZE_T +#if (defined(__s390__) || defined(__hppa__) || defined(__cris__)) +typedef unsigned long size_t; +#else +typedef unsigned int size_t; +#endif + +#define _PTRDIFF_T +typedef signed int ptrdiff_t; + +#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stdint.h b/klibc/klibc/include/bits32/bitsize/stdint.h new file mode 100644 index 0000000000..40b464961c --- /dev/null +++ b/klibc/klibc/include/bits32/bitsize/stdint.h @@ -0,0 +1,34 @@ +/* + * bits32/stdint.h + */ + +#ifndef _BITSIZE_STDINT_H +#define _BITSIZE_STDINT_H + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef long long int int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long int uint64_t; + +typedef int int_fast16_t; +typedef int int_fast32_t; + +typedef unsigned int uint_fast16_t; +typedef unsigned int uint_fast32_t; + +typedef int intptr_t; +typedef unsigned int uintptr_t; + +#define __INT64_C(c) c ## LL +#define __UINT64_C(c) c ## ULL + +#define __PRI64_RANK "ll" +#define __PRIFAST_RANK "" +#define __PRIPTR_RANK "" + +#endif /* _BITSIZE_STDINT_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stdintconst.h b/klibc/klibc/include/bits32/bitsize/stdintconst.h new file mode 100644 index 0000000000..8157dd06e0 --- /dev/null +++ b/klibc/klibc/include/bits32/bitsize/stdintconst.h @@ -0,0 +1,18 @@ +/* + * bits32/stdintconst.h + */ + +#ifndef _BITSIZE_STDINTCONST_H +#define _BITSIZE_STDINTCONST_H + +#define INT_FAST16_C(c) INT32_C(c) +#define INT_FAST32_C(c) INT32_C(c) + +#define UINT_FAST16_C(c) UINT32_C(c) +#define UINT_FAST32_C(c) UINT32_C(c) + +#define INTPTR_C(c) INT32_C(c) +#define UINTPTR_C(c) UINT32_C(c) +#define PTRDIFF_C(c) INT32_C(c) + +#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stdintlimits.h b/klibc/klibc/include/bits32/bitsize/stdintlimits.h new file mode 100644 index 0000000000..b44fe01186 --- /dev/null +++ b/klibc/klibc/include/bits32/bitsize/stdintlimits.h @@ -0,0 +1,22 @@ +/* + * bits32/stdintlimits.h + */ + +#ifndef _BITSIZE_STDINTLIMITS_H +#define _BITSIZE_STDINTLIMITS_H + +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MAX INT32_MAX +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX + +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX + +#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/klibc/include/bits64/bitsize/limits.h b/klibc/klibc/include/bits64/bitsize/limits.h new file mode 100644 index 0000000000..7b20da085b --- /dev/null +++ b/klibc/klibc/include/bits64/bitsize/limits.h @@ -0,0 +1,14 @@ +/* + * bits64/limits.h + */ + +#ifndef _BITSIZE_LIMITS_H +#define _BITSIZE_LIMITS_H + +#define LONG_BIT 64 + +#define LONG_MIN (-9223372036854775807L-1) +#define LONG_MAX 9223372036854775807L +#define ULONG_MAX 18446744073709551615UL + +#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/klibc/include/bits64/bitsize/stddef.h b/klibc/klibc/include/bits64/bitsize/stddef.h new file mode 100644 index 0000000000..3e72621862 --- /dev/null +++ b/klibc/klibc/include/bits64/bitsize/stddef.h @@ -0,0 +1,13 @@ +/* + * bits64/stddef.h + */ + +#ifndef _BITSIZE_STDDEF_H +#define _BITSIZE_STDDEF_H + +#define _SIZE_T +typedef unsigned long size_t; +#define _PTRDIFF_T +typedef signed long ptrdiff_t; + +#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/klibc/include/bits64/bitsize/stdint.h b/klibc/klibc/include/bits64/bitsize/stdint.h new file mode 100644 index 0000000000..f569f526b6 --- /dev/null +++ b/klibc/klibc/include/bits64/bitsize/stdint.h @@ -0,0 +1,36 @@ +/* + * bits64/stdint.h + */ + +#ifndef _BITSIZE_STDINT_H +#define _BITSIZE_STDINT_H + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef long long int int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long int uint64_t; + +typedef long int int_fast16_t; +typedef long int int_fast32_t; + +typedef unsigned long int uint_fast16_t; +typedef unsigned long int uint_fast32_t; + +typedef long int intptr_t; +typedef unsigned long int uintptr_t; + +#define __INT64_C(c) c ## L +#define __UINT64_C(c) c ## UL + +#define __PRI64_RANK "l" +#define __PRIFAST_RANK "l" +#define __PRIPTR_RANK "l" + +#endif /* _BITSIZE_STDINT_H */ + + diff --git a/klibc/klibc/include/bits64/bitsize/stdintconst.h b/klibc/klibc/include/bits64/bitsize/stdintconst.h new file mode 100644 index 0000000000..65f2db0501 --- /dev/null +++ b/klibc/klibc/include/bits64/bitsize/stdintconst.h @@ -0,0 +1,18 @@ +/* + * bits64/stdintconst.h + */ + +#ifndef _BITSIZE_STDINTCONST_H +#define _BITSIZE_STDINTCONST_H + +#define INT_FAST16_C(c) INT64_C(c) +#define INT_FAST32_C(c) INT64_C(c) + +#define UINT_FAST16_C(c) UINT64_C(c) +#define UINT_FAST32_C(c) UINT64_C(c) + +#define INTPTR_C(c) INT64_C(c) +#define UINTPTR_C(c) UINT64_C(c) +#define PTRDIFF_C(c) INT64_C(c) + +#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/klibc/include/bits64/bitsize/stdintlimits.h b/klibc/klibc/include/bits64/bitsize/stdintlimits.h new file mode 100644 index 0000000000..d110d17d2d --- /dev/null +++ b/klibc/klibc/include/bits64/bitsize/stdintlimits.h @@ -0,0 +1,22 @@ +/* + * bits64/stdintlimits.h + */ + +#ifndef _BITSIZE_STDINTLIMITS_H +#define _BITSIZE_STDINTLIMITS_H + +#define INT_FAST16_MIN INT64_MIN +#define INT_FAST32_MIN INT64_MIN +#define INT_FAST16_MAX INT64_MAX +#define INT_FAST32_MAX INT64_MAX +#define UINT_FAST16_MAX UINT64_MAX +#define UINT_FAST32_MAX UINT64_MAX + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX + +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX + +#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/klibc/include/ctype.h b/klibc/klibc/include/ctype.h new file mode 100644 index 0000000000..2cb90a45d3 --- /dev/null +++ b/klibc/klibc/include/ctype.h @@ -0,0 +1,117 @@ +/* + * ctype.h + * + * This assumes ISO 8859-1, being a reasonable superset of ASCII. + */ + +#ifndef _CTYPE_H +#define _CTYPE_H + +#ifndef __CTYPE_NO_INLINE +# define __ctype_inline extern __inline__ +#else +# define __ctype_inline +#endif + +/* + * This relies on the following definitions: + * + * cntrl = !print + * alpha = upper|lower + * graph = punct|alpha|digit + * blank = '\t' || ' ' (per POSIX requirement) + */ +enum { + __ctype_upper = (1 << 0), + __ctype_lower = (1 << 1), + __ctype_digit = (1 << 2), + __ctype_xdigit = (1 << 3), + __ctype_space = (1 << 4), + __ctype_print = (1 << 5), + __ctype_punct = (1 << 6) +}; + +extern const unsigned char __ctypes[]; + +__ctype_inline int isalnum(int __c) +{ + return __ctypes[__c+1] & + (__ctype_upper|__ctype_lower|__ctype_digit); +} + +__ctype_inline int isalpha(int __c) +{ + return __ctypes[__c+1] & + (__ctype_upper|__ctype_lower); +} + +__ctype_inline int isascii(int __c) +{ + return !(__c & ~0x7f); +} + +__ctype_inline int isblank(int __c) +{ + return (__c == '\t') || (__c == ' '); +} + +__ctype_inline int iscntrl(int __c) +{ + return (__c >= 0) && !(__ctypes[__c+1] & __ctype_print); +} + +__ctype_inline int isdigit(int __c) +{ + return __ctypes[__c+1] & __ctype_digit; +} + +__ctype_inline int isgraph(int __c) +{ + return __ctypes[__c+1] & + (__ctype_upper|__ctype_lower|__ctype_digit|__ctype_punct); +} + +__ctype_inline int islower(int __c) +{ + return __ctypes[__c+1] & __ctype_lower; +} + +__ctype_inline int isprint(int __c) +{ + return __ctypes[__c+1] & __ctype_print; +} + +__ctype_inline int ispunct(int __c) +{ + return __ctypes[__c+1] & __ctype_punct; +} + +__ctype_inline int isspace(int __c) +{ + return __ctypes[__c+1] & __ctype_space; +} + +__ctype_inline int isupper(int __c) +{ + return __ctypes[__c+1] & __ctype_upper; +} + +__ctype_inline int isxdigit(int __c) +{ + return __ctypes[__c+1] & __ctype_xdigit; +} + +#define _toupper(__c) ((__c) & ~0x20) +#define _tolower(__c) ((__c) | 0x20) + +__ctype_inline int toupper(int __c) +{ + return islower(__c) ? _toupper(__c) : __c; +} + +__ctype_inline int tolower(int __c) +{ + return isupper(__c) ? _tolower(__c) : __c; +} + +#endif /* _CTYPE_H */ diff --git a/klibc/klibc/include/dirent.h b/klibc/klibc/include/dirent.h new file mode 100644 index 0000000000..10dd138ee5 --- /dev/null +++ b/klibc/klibc/include/dirent.h @@ -0,0 +1,20 @@ +/* + * dirent.h + */ + +#ifndef _DIRENT_H +#define _DIRENT_H + +#include +#include + +#ifndef __IO_DIR_DEFINED +struct _IO_dir; +#endif +typedef struct _IO_dir DIR; + +__extern DIR *opendir(const char *); +__extern struct dirent *readdir(DIR *); +__extern int closedir(DIR *); + +#endif /* _DIRENT_H */ diff --git a/klibc/klibc/include/elf.h b/klibc/klibc/include/elf.h new file mode 100644 index 0000000000..bd0f3e7f9b --- /dev/null +++ b/klibc/klibc/include/elf.h @@ -0,0 +1,12 @@ +/* + * elf.h + */ + +#ifndef _ELF_H +#define _ELF_H + +#include +#include + +#endif /* _ELF_H */ + diff --git a/klibc/klibc/include/endian.h b/klibc/klibc/include/endian.h new file mode 100644 index 0000000000..10dbbd8a89 --- /dev/null +++ b/klibc/klibc/include/endian.h @@ -0,0 +1,41 @@ +/* + * endian.h + */ + +#ifndef _ENDIAN_H +#define _ENDIAN_H + +#include + +/* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or + __BIG_ENDIAN, but the glibc/BSD-ish macros expect both to be + defined with __BYTE_ORDER defining which is actually used... */ + +#if defined(__LITTLE_ENDIAN) +# undef __LITTLE_ENDIAN +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# define __PDP_ENDIAN 3412 +# define __BYTE_ORDER __LITTLE_ENDIAN +#elif defined(__BIG_ENDIAN) +# undef __BIG_ENDIAN +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# define __PDP_ENDIAN 3412 +# define __BYTE_ORDER __BIG_ENDIAN +#elif defined(__PDP_ENDIAN) +# undef __PDP_ENDIAN +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# define __PDP_ENDIAN 3412 +# define __BYTE_ORDER __PDP_ENDIAN +#else +# error "Unknown byte order!" +#endif + +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#define BIG_ENDIAN __BIG_ENDIAN +#define PDP_ENDIAN __PDP_ENDIAN +#define BYTE_ORDER __BYTE_ORDER + +#endif /* _ENDIAN_H */ diff --git a/klibc/klibc/include/errno.h b/klibc/klibc/include/errno.h new file mode 100644 index 0000000000..b2e666504d --- /dev/null +++ b/klibc/klibc/include/errno.h @@ -0,0 +1,8 @@ +/* + * errno.h + */ + +#include +#include + +__extern int errno; diff --git a/klibc/klibc/include/fcntl.h b/klibc/klibc/include/fcntl.h new file mode 100644 index 0000000000..e90959c7e9 --- /dev/null +++ b/klibc/klibc/include/fcntl.h @@ -0,0 +1,11 @@ +/* + * fcntl.h + */ + +#ifndef _FCNTL_H +#define _FCNTL_H + +#include +#include + +#endif /* _FCNTL_H */ diff --git a/klibc/klibc/include/grp.h b/klibc/klibc/include/grp.h new file mode 100644 index 0000000000..03ceb31560 --- /dev/null +++ b/klibc/klibc/include/grp.h @@ -0,0 +1,13 @@ +/* + * grp.h + */ + +#ifndef _GRP_H +#define _GRP_H + +#include +#include + +__extern int setgroups(size_t, const gid_t *); + +#endif /* _GRP_H */ diff --git a/klibc/klibc/include/inttypes.h b/klibc/klibc/include/inttypes.h new file mode 100644 index 0000000000..e00fa63160 --- /dev/null +++ b/klibc/klibc/include/inttypes.h @@ -0,0 +1,226 @@ +/* + * inttypes.h + */ + +#ifndef _INTTYPES_H +#define _INTTYPES_H + +#include +#include +#include + +static __inline__ intmax_t imaxabs(intmax_t __n) +{ + return (__n < (intmax_t)0) ? -__n : __n; +} + +__extern intmax_t strtoimax(const char *, char **, int); +__extern uintmax_t strtoumax(const char *, char **, int); + +/* extensions */ +__extern intmax_t strntoimax(const char *, char **, int, size_t); +__extern uintmax_t strntoumax(const char *, char **, int, size_t); + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) + +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "d" +#define PRId64 __PRI64_RANK "d" + +#define PRIdLEAST8 "d" +#define PRIdLEAST16 "d" +#define PRIdLEAST32 "d" +#define PRIdLEAST64 __PRI64_RANK "d" + +#define PRIdFAST8 "d" +#define PRIdFAST16 __PRIFAST_RANK "d" +#define PRIdFAST32 __PRIFAST_RANK "d" +#define PRIdFAST64 __PRI64_RANK "d" + +#define PRIdMAX __PRI64_RANK "d" +#define PRIdPTR __PRIPTR_RANK "d" + +#define PRIi8 "i" +#define PRIi16 "i" +#define PRIi32 "i" +#define PRIi64 __PRI64_RANK "i" + +#define PRIiLEAST8 "i" +#define PRIiLEAST16 "i" +#define PRIiLEAST32 "i" +#define PRIiLEAST64 __PRI64_RANK "i" + +#define PRIiFAST8 "i" +#define PRIiFAST16 __PRIFAST_RANK "i" +#define PRIiFAST32 __PRIFAST_RANK "i" +#define PRIiFAST64 __PRI64_RANK "i" + +#define PRIiMAX __PRI64_RANK "i" +#define PRIiPTR __PRIPTR_RANK "i" + +#define PRIo8 "o" +#define PRIo16 "o" +#define PRIo32 "o" +#define PRIo64 __PRI64_RANK "o" + +#define PRIoLEAST8 "o" +#define PRIoLEAST16 "o" +#define PRIoLEAST32 "o" +#define PRIoLEAST64 __PRI64_RANK "o" + +#define PRIoFAST8 "o" +#define PRIoFAST16 __PRIFAST_RANK "o" +#define PRIoFAST32 __PRIFAST_RANK "o" +#define PRIoFAST64 __PRI64_RANK "o" + +#define PRIoMAX __PRI64_RANK "o" +#define PRIoPTR __PRIPTR_RANK "o" + +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "u" +#define PRIu64 __PRI64_RANK "u" + +#define PRIuLEAST8 "u" +#define PRIuLEAST16 "u" +#define PRIuLEAST32 "u" +#define PRIuLEAST64 __PRI64_RANK "u" + +#define PRIuFAST8 "u" +#define PRIuFAST16 __PRIFAST_RANK "u" +#define PRIuFAST32 __PRIFAST_RANK "u" +#define PRIuFAST64 __PRI64_RANK "u" + +#define PRIuMAX __PRI64_RANK "u" +#define PRIuPTR __PRIPTR_RANK "u" + +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "x" +#define PRIx64 __PRI64_RANK "x" + +#define PRIxLEAST8 "x" +#define PRIxLEAST16 "x" +#define PRIxLEAST32 "x" +#define PRIxLEAST64 __PRI64_RANK "x" + +#define PRIxFAST8 "x" +#define PRIxFAST16 __PRIFAST_RANK "x" +#define PRIxFAST32 __PRIFAST_RANK "x" +#define PRIxFAST64 __PRI64_RANK "x" + +#define PRIxMAX __PRI64_RANK "x" +#define PRIxPTR __PRIPTR_RANK "x" + +#define PRIX8 "X" +#define PRIX16 "X" +#define PRIX32 "X" +#define PRIX64 __PRI64_RANK "X" + +#define PRIXLEAST8 "X" +#define PRIXLEAST16 "X" +#define PRIXLEAST32 "X" +#define PRIXLEAST64 __PRI64_RANK "X" + +#define PRIXFAST8 "X" +#define PRIXFAST16 __PRIFAST_RANK "X" +#define PRIXFAST32 __PRIFAST_RANK "X" +#define PRIXFAST64 __PRI64_RANK "X" + +#define PRIXMAX __PRI64_RANK "X" +#define PRIXPTR __PRIPTR_RANK "X" + +#define SCNd8 "hhd" +#define SCNd16 "hd" +#define SCNd32 "d" +#define SCNd64 __PRI64_RANK "d" + +#define SCNdLEAST8 "hhd" +#define SCNdLEAST16 "hd" +#define SCNdLEAST32 "d" +#define SCNdLEAST64 __PRI64_RANK "d" + +#define SCNdFAST8 "hhd" +#define SCNdFAST16 __PRIFAST_RANK "d" +#define SCNdFAST32 __PRIFAST_RANK "d" +#define SCNdFAST64 __PRI64_RANK "d" + +#define SCNdMAX __PRI64_RANK "d" +#define SCNdPTR __PRIPTR_RANK "d" + +#define SCNi8 "hhi" +#define SCNi16 "hi" +#define SCNi32 "i" +#define SCNi64 __PRI64_RANK "i" + +#define SCNiLEAST8 "hhi" +#define SCNiLEAST16 "hi" +#define SCNiLEAST32 "i" +#define SCNiLEAST64 __PRI64_RANK "i" + +#define SCNiFAST8 "hhi" +#define SCNiFAST16 __PRIFAST_RANK "i" +#define SCNiFAST32 __PRIFAST_RANK "i" +#define SCNiFAST64 __PRI64_RANK "i" + +#define SCNiMAX __PRI64_RANK "i" +#define SCNiPTR __PRIPTR_RANK "i" + +#define SCNo8 "hho" +#define SCNo16 "ho" +#define SCNo32 "o" +#define SCNo64 __PRI64_RANK "o" + +#define SCNoLEAST8 "hho" +#define SCNoLEAST16 "ho" +#define SCNoLEAST32 "o" +#define SCNoLEAST64 __PRI64_RANK "o" + +#define SCNoFAST8 "hho" +#define SCNoFAST16 __PRIFAST_RANK "o" +#define SCNoFAST32 __PRIFAST_RANK "o" +#define SCNoFAST64 __PRI64_RANK "o" + +#define SCNoMAX __PRI64_RANK "o" +#define SCNoPTR __PRIPTR_RANK "o" + +#define SCNu8 "hhu" +#define SCNu16 "hu" +#define SCNu32 "u" +#define SCNu64 __PRI64_RANK "u" + +#define SCNuLEAST8 "hhu" +#define SCNuLEAST16 "hu" +#define SCNuLEAST32 "u" +#define SCNuLEAST64 __PRI64_RANK "u" + +#define SCNuFAST8 "hhu" +#define SCNuFAST16 __PRIFAST_RANK "u" +#define SCNuFAST32 __PRIFAST_RANK "u" +#define SCNuFAST64 __PRI64_RANK "u" + +#define SCNuMAX __PRI64_RANK "u" +#define SCNuPTR __PRIPTR_RANK "u" + +#define SCNx8 "hhx" +#define SCNx16 "hx" +#define SCNx32 "x" +#define SCNx64 __PRI64_RANK "x" + +#define SCNxLEAST8 "hhx" +#define SCNxLEAST16 "hx" +#define SCNxLEAST32 "x" +#define SCNxLEAST64 __PRI64_RANK "x" + +#define SCNxFAST8 "hhx" +#define SCNxFAST16 __PRIFAST_RANK "x" +#define SCNxFAST32 __PRIFAST_RANK "x" +#define SCNxFAST64 __PRI64_RANK "x" + +#define SCNxMAX __PRI64_RANK "x" +#define SCNxPTR __PRIPTR_RANK "x" + +#endif + +#endif /* _INTTYPES_H */ diff --git a/klibc/klibc/include/klibc/compiler.h b/klibc/klibc/include/klibc/compiler.h new file mode 100644 index 0000000000..5c284b206c --- /dev/null +++ b/klibc/klibc/include/klibc/compiler.h @@ -0,0 +1,61 @@ +/* + * klibc/compiler.h + * + * Various compiler features + */ + +#ifndef _KLIBC_COMPILER_H +#define _KLIBC_COMPILER_H + +/* Specific calling conventions */ +#ifdef __i386__ +# ifdef __GNUC__ +# define __cdecl __attribute__((cdecl,regparm(0))) +# else + /* Most other C compilers have __cdecl as a keyword */ +# endif +#endif + +/* How to declare a function that *must* be inlined */ +#ifdef __GNUC__ +# if __GNUC_MAJOR__ >= 3 +# define __must_inline static __inline__ __attribute__((always_inline)) +# else +# define __must_inline extern __inline__ +# endif +#else +# define __must_inline inline /* Just hope this works... */ +#endif + +/* How to declare a function that does not return */ +#ifdef __GNUC__ +# define __noreturn void __attribute__((noreturn)) +#else +# define __noreturn void +#endif + +/* How to declare a "constant" function (a function in the + mathematical sense) */ +#ifdef __GNUC__ +# define __constfunc __attribute__((const)) +#else +# define __constfunc +#endif + +/* Format attribute */ +#ifdef __GNUC__ +# define __formatfunc(t,f,a) __attribute__((format(t,f,a))) +#else +# define __formatfunc(t,f,a) +#endif + +/* likely/unlikely */ +#if defined(__GNUC__) && (__GNUC_MAJOR__ > 2 || (__GNUC_MAJOR__ == 2 && __GNUC_MINOR__ >= 95)) +# define __likely(x) __builtin_expect((x), 1) +# define __unlikely(x) __builtin_expect((x), 0) +#else +# define __likely(x) (x) +# define __unlikely(x) (x) +#endif + +#endif diff --git a/klibc/klibc/include/klibc/diverr.h b/klibc/klibc/include/klibc/diverr.h new file mode 100644 index 0000000000..4d8c8d36c2 --- /dev/null +++ b/klibc/klibc/include/klibc/diverr.h @@ -0,0 +1,16 @@ +/* + * klibc/diverr.h + */ + +#ifndef _KLIBC_DIVERR_H +#define _KLIBC_DIVERR_H + +#include + +static __inline__ void +__divide_error(void) +{ + raise(SIGFPE); +} + +#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/klibc/include/klibc/extern.h b/klibc/klibc/include/klibc/extern.h new file mode 100644 index 0000000000..f9c3467211 --- /dev/null +++ b/klibc/klibc/include/klibc/extern.h @@ -0,0 +1,14 @@ +/* + * klibc/extern.h + */ + +#ifndef _KLIBC_EXTERN_H +#define _KLIBC_EXTERN_H + +#ifdef __cplusplus +#define __extern extern "C" +#else +#define __extern extern +#endif + +#endif /* _KLIBC_EXTERN_H */ diff --git a/klibc/klibc/include/limits.h b/klibc/klibc/include/limits.h new file mode 100644 index 0000000000..f1532e5323 --- /dev/null +++ b/klibc/klibc/include/limits.h @@ -0,0 +1,40 @@ +/* + * limits.h + */ + +#ifndef _LIMITS_H +#define _LIMITS_H + +#define CHAR_BIT 8 +#define SHRT_BIT 16 +#define INT_BIT 32 +#define LONGLONG_BIT 64 + +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +#ifdef __CHAR_UNSIGNED__ +# define CHAR_MIN 0 +# define CHAR_MAX UCHAR_MAX +#else +# define CHAR_MIN SCHAR_MIN +# define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535 + +#define INT_MIN (-2147483647-1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +#define LONGLONG_MIN (-9223372036854775807LL-1) +#define LONGLONG_MAX 9223372036854775807LL +#define ULONGLONG_MAX 18446744073709551615ULL + +#include +#include + +#endif /* _LIMITS_H */ diff --git a/klibc/klibc/include/net/if.h b/klibc/klibc/include/net/if.h new file mode 100644 index 0000000000..1aa8e7b90c --- /dev/null +++ b/klibc/klibc/include/net/if.h @@ -0,0 +1 @@ +#include diff --git a/klibc/klibc/include/net/if_arp.h b/klibc/klibc/include/net/if_arp.h new file mode 100644 index 0000000000..a25f1b4759 --- /dev/null +++ b/klibc/klibc/include/net/if_arp.h @@ -0,0 +1 @@ +#include diff --git a/klibc/klibc/include/net/if_ether.h b/klibc/klibc/include/net/if_ether.h new file mode 100644 index 0000000000..060ef22070 --- /dev/null +++ b/klibc/klibc/include/net/if_ether.h @@ -0,0 +1 @@ +#include diff --git a/klibc/klibc/include/net/if_packet.h b/klibc/klibc/include/net/if_packet.h new file mode 100644 index 0000000000..b5e8e0e11f --- /dev/null +++ b/klibc/klibc/include/net/if_packet.h @@ -0,0 +1 @@ +#include diff --git a/klibc/klibc/include/netinet/in.h b/klibc/klibc/include/netinet/in.h new file mode 100644 index 0000000000..92dc843bb1 --- /dev/null +++ b/klibc/klibc/include/netinet/in.h @@ -0,0 +1,33 @@ +/* + * netinet/in.h + */ + +#ifndef _NETINET_IN_H +#define _NETINET_IN_H + +/* added this include by Mats Petersson */ +#include + +#include +#include +#include /* Must be included *before* */ +#include + +#ifndef htons +# define htons(x) __cpu_to_be16(x) +#endif +#ifndef ntohs +# define ntohs(x) __be16_to_cpu(x) +#endif +#ifndef htonl +# define htonl(x) __cpu_to_be32(x) +#endif +#ifndef ntohl +# define ntohl(x) __be32_to_cpu(x) +#endif + +#define IPPORT_RESERVED 1024 + +__extern int bindresvport (int sd, struct sockaddr_in *sin); + +#endif /* _NETINET_IN_H */ diff --git a/klibc/klibc/include/netinet/in6.h b/klibc/klibc/include/netinet/in6.h new file mode 100644 index 0000000000..46584ca627 --- /dev/null +++ b/klibc/klibc/include/netinet/in6.h @@ -0,0 +1,10 @@ +/* + * netinet/in6.h + */ + +#ifndef _NETINET_IN6_H +#define _NETINET_IN6_H + +#include + +#endif /* _NETINET_IN6_H */ diff --git a/klibc/klibc/include/netinet/ip.h b/klibc/klibc/include/netinet/ip.h new file mode 100644 index 0000000000..8aecbe66a3 --- /dev/null +++ b/klibc/klibc/include/netinet/ip.h @@ -0,0 +1,13 @@ +/* + * netinet/ip.h + */ + +#ifndef _NETINET_IP_H +#define _NETINET_IP_H + +#include +#include + +#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ + +#endif /* _NETINET_IP_H */ diff --git a/klibc/klibc/include/netinet/tcp.h b/klibc/klibc/include/netinet/tcp.h new file mode 100644 index 0000000000..bb5d307e98 --- /dev/null +++ b/klibc/klibc/include/netinet/tcp.h @@ -0,0 +1,11 @@ +/* + * netinet/tcp.h + */ + +#ifndef _NETINET_TCP_H +#define _NETINET_TCP_H + +#include /* Include *before* linux/tcp.h */ +#include + +#endif /* _NETINET_TCP_H */ diff --git a/klibc/klibc/include/netinet/udp.h b/klibc/klibc/include/netinet/udp.h new file mode 100644 index 0000000000..b809b4ee6e --- /dev/null +++ b/klibc/klibc/include/netinet/udp.h @@ -0,0 +1,19 @@ +/* + * netinet/udp.h + */ + +#ifndef _NETINET_UDP_H +#define _NETINET_UDP_H + +/* + * We would include linux/udp.h, but it brings in too much other stuff + */ + +struct udphdr { + __u16 source; + __u16 dest; + __u16 len; + __u16 check; +}; + +#endif /* _NETINET_UDP_H */ diff --git a/klibc/klibc/include/poll.h b/klibc/klibc/include/poll.h new file mode 100644 index 0000000000..8710d92ebd --- /dev/null +++ b/klibc/klibc/include/poll.h @@ -0,0 +1,16 @@ +/* + * poll.h + */ + +#ifndef _POLL_H +#define _POLL_H + +#include +#include + +/* POSIX specifies "int" for the timeout, Linux seems to use long... */ + +typedef unsigned int nfds_t; +__extern int poll(struct pollfd *, nfds_t, long); + +#endif /* _POLL_H */ diff --git a/klibc/klibc/include/sched.h b/klibc/klibc/include/sched.h new file mode 100644 index 0000000000..5e6103965f --- /dev/null +++ b/klibc/klibc/include/sched.h @@ -0,0 +1,23 @@ +/* + * sched.h + */ + +#ifndef _SCHED_H +#define _SCHED_H + +#include + +/* linux/sched.h is unusable; put the declarations we need here... */ + +#define SCHED_NORMAL 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 + +struct sched_param { + int sched_priority; +}; + +__extern int sched_setschedule(pid_t, int, const struct sched_param *); +__extern int sched_yield(void); + +#endif /* _SCHED_H */ diff --git a/klibc/klibc/include/setjmp.h b/klibc/klibc/include/setjmp.h new file mode 100644 index 0000000000..b504eb6d08 --- /dev/null +++ b/klibc/klibc/include/setjmp.h @@ -0,0 +1,43 @@ +/* + * setjmp.h + */ + +#ifndef _SETJMP_H +#define _SETJMP_H + +#include +#include +#include +#include + +#include + +__extern int setjmp(jmp_buf); +__extern __noreturn longjmp(jmp_buf, int); + +/* + Whose bright idea was it to add unrelated functionality to just about + the only function in the standard C library (setjmp) which cannot be + wrapped by an ordinary function wrapper? Anyway, the damage is done, + and therefore, this wrapper *must* be inline. However, gcc will + complain if this is an inline function for unknown reason, and + therefore sigsetjmp() needs to be a macro. +*/ + +struct __sigjmp_buf { + jmp_buf __jmpbuf; + sigset_t __sigs; +}; + +typedef struct __sigjmp_buf sigjmp_buf[1]; + +#define sigsetjmp(__env, __save) \ +({ \ + struct __sigjmp_buf *__e = (__env); \ + sigprocmask(0, NULL, &__e->__sigs); \ + setjmp(__e->__jmpbuf); \ +}) + +__extern __noreturn siglongjmp(sigjmp_buf, int); + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/include/signal.h b/klibc/klibc/include/signal.h new file mode 100644 index 0000000000..ffd2beba43 --- /dev/null +++ b/klibc/klibc/include/signal.h @@ -0,0 +1,72 @@ +/* + * signal.h + */ + +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include +#include /* For memset() */ +#include /* For LONG_BIT */ +#include +#include + +/* Some architectures don't define these */ +#ifndef SA_RESETHAND +# define SA_RESETHAND SA_ONESHOT +#endif +#ifndef SA_NODEFER +# define SA_NODEFER SA_NOMASK +#endif +#ifndef NSIG +# define NSIG _NSIG +#endif + +__extern const char * const sys_siglist[]; + +/* This assumes sigset_t is either an unsigned long or an array of such, + and that _NSIG_BPW in the kernel is always LONG_BIT */ + +static __inline__ int sigemptyset(sigset_t *__set) +{ + memset(__set, 0, sizeof *__set); + return 0; +} +static __inline__ int sigfillset(sigset_t *__set) +{ + memset(__set, ~0, sizeof *__set); + return 0; +} +static __inline__ int sigaddset(sigset_t *__set, int __signum) +{ + unsigned long *__lset = (unsigned long *)__set; + __lset[__signum/LONG_BIT] |= 1UL << (__signum%LONG_BIT); + return 0; +} +static __inline__ int sigdelset(sigset_t *__set, int __signum) +{ + unsigned long *__lset = (unsigned long *)__set; + __lset[__signum/LONG_BIT] &= ~(1UL << (__signum%LONG_BIT)); + return 0; +} +static __inline__ int sigismember(sigset_t *__set, int __signum) +{ + unsigned long *__lset = (unsigned long *)__set; + return (int)((__lset[__signum/LONG_BIT] >> (__signum%LONG_BIT)) & 1); +} + +__extern __sighandler_t __signal(int, __sighandler_t, int); +__extern __sighandler_t signal(int, __sighandler_t); +__extern __sighandler_t bsd_signal(int, __sighandler_t); +__extern int sigaction(int, const struct sigaction *, struct sigaction *); +__extern int sigprocmask(int, const sigset_t *, sigset_t *); +__extern int sigpending(sigset_t *); +__extern int sigsuspend(const sigset_t *); +__extern int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); +__extern int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); +__extern int rt_sigpending(sigset_t *, size_t); +__extern int rt_sigsuspend(const sigset_t *, size_t); +__extern int raise(int); +__extern int kill(pid_t, int); + +#endif /* _SIGNAL_H */ diff --git a/klibc/klibc/include/stdarg.h b/klibc/klibc/include/stdarg.h new file mode 100644 index 0000000000..cc324b825d --- /dev/null +++ b/klibc/klibc/include/stdarg.h @@ -0,0 +1,14 @@ +/* + * stdarg.h + * + * This is just a wrapper for the gcc one, but defines va_copy() + * even if gcc doesn't. + */ + +/* Note: the _STDARG_H macro belongs to the gcc header... */ +#include_next + +/* Older gcc considers this an extension, so it's double underbar only */ +#ifndef va_copy +#define va_copy(d,s) __va_copy(d,s) +#endif diff --git a/klibc/klibc/include/stddef.h b/klibc/klibc/include/stddef.h new file mode 100644 index 0000000000..900c147cd8 --- /dev/null +++ b/klibc/klibc/include/stddef.h @@ -0,0 +1,24 @@ +/* + * stddef.h + */ + +#ifndef _STDDEF_H +#define _STDDEF_H + +#ifndef __KLIBC__ +# define __KLIBC__ 1 +#endif + +#include + +#undef NULL +#ifdef __cplusplus +# define NULL 0 +#else +# define NULL ((void *)0) +#endif + +#undef offsetof +#define offsetof(t,m) ((size_t)&((t *)0->m)) + +#endif /* _STDDEF_H */ diff --git a/klibc/klibc/include/stdint.h b/klibc/klibc/include/stdint.h new file mode 100644 index 0000000000..2022a30fd7 --- /dev/null +++ b/klibc/klibc/include/stdint.h @@ -0,0 +1,113 @@ +/* + * stdint.h + */ + +#ifndef _STDINT_H +#define _STDINT_H + +#include + +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +typedef int8_t int_fast8_t; +typedef int64_t int_fast64_t; + +typedef uint8_t uint_fast8_t; +typedef uint64_t uint_fast64_t; + +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) + +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647-1) +#define INT64_MIN (__INT64_C(-9223372036854775807)-1) + +#define INT8_MAX (127) +#define INT16_MAX (32767) +#define INT32_MAX (2147483647) +#define INT64_MAX (__INT64_C(9223372036854775807)) + +#define UINT8_MAX (255U) +#define UINT16_MAX (65535U) +#define UINT32_MAX (4294967295U) +#define UINT64_MAX (__UINT64_C(18446744073709551615)) + +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST64_MAX UINT64_MAX + +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +#include + +#endif + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) + +#define INT8_C(c) c +#define INT16_C(c) c +#define INT32_C(c) c +#define INT64_C(c) __INT64_C(c) + +#define UINT8_C(c) c ## U +#define UINT16_C(c) c ## U +#define UINT32_C(c) c ## U +#define UINT64_C(c) __UINT64_C(c) + +#define INT_LEAST8_C(c) INT8_C(c) +#define INT_LEAST16_C(c) INT16_C(c) +#define INT_LEAST32_C(c) INT32_C(c) +#define INT_LEAST64_C(c) INT64_C(c) + +#define UINT_LEAST8_C(c) UINT8_C(c) +#define UINT_LEAST16_C(c) UINT16_C(c) +#define UINT_LEAST32_C(c) UINT32_C(c) +#define UINT_LEAST64_C(c) UINT64_C(c) + +#define INT_FAST8_C(c) INT8_C(c) +#define INT_FAST64_C(c) INT64_C(c) + +#define UINT_FAST8_C(c) UINT8_C(c) +#define UINT_FAST64_C(c) UINT64_C(c) + +#define INTMAX_C(c) INT64_C(c) +#define UINTMAX_C(c) UINT64_C(c) + +#include + +#endif + +#endif /* _STDINT_H */ diff --git a/klibc/klibc/include/stdio.h b/klibc/klibc/include/stdio.h new file mode 100644 index 0000000000..5e621af5f1 --- /dev/null +++ b/klibc/klibc/include/stdio.h @@ -0,0 +1,109 @@ +/* + * stdio.h + */ + +#ifndef _STDIO_H +#define _STDIO_H + +#include +#include +#include +#include + +/* This structure doesn't really exist, but it gives us something + to define FILE * with */ +struct _IO_file; +typedef struct _IO_file FILE; + +#define stdin ((FILE *)0) +#define stdout ((FILE *)1) +#define stderr ((FILE *)2) + +#ifndef EOF +# define EOF (-1) +#endif + +#ifndef BUFSIZ +# define BUFSIZ 4096 +#endif + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +static __inline__ int fileno(FILE *__f) +{ + /* This should really be intptr_t, but size_t should be the same size */ + return (int)(size_t)__f; +} + +static __inline__ FILE * __create_file(int __fd) +{ + return (FILE *)(size_t)__fd; +} + +__extern FILE *fopen(const char *, const char *); + +static __inline__ FILE *fdopen(int __fd, const char *__m) +{ + (void)__m; return __create_file(__fd); +} +static __inline__ int fclose(FILE *__f) +{ + extern int close(int); + return close(fileno(__f)); +} +static __inline__ int fseek(FILE *__f, off_t __o, int __w) +{ + extern off_t lseek(int, off_t, int); + return (lseek(fileno(__f), __o, __w) == (off_t)-1) ? -1 : 0; +} +static __inline__ off_t ftell(FILE *__f) +{ + extern off_t lseek(int, off_t, int); + return lseek(fileno(__f), 0, SEEK_CUR); +} + +__extern int fputs(const char *, FILE *); +__extern int puts(const char *); +__extern int fputc(int, FILE *); +#define putc(c,f) fputc((c),(f)) +#define putchar(c) fputc((c),stdout) + +__extern int fgetc(FILE *); +__extern char * fgets(char *, int, FILE *); +#define getc(f) fgetc(f) + +__extern size_t _fread(void *, size_t, FILE *); +__extern size_t _fwrite(const void *, size_t, FILE *); + +#ifndef __NO_FREAD_FWRITE_INLINES +static __inline__ size_t +fread(void *__p, size_t __s, size_t __n, FILE *__f) +{ + return _fread(__p, __s*__n, __f)/__s; +} +static __inline__ size_t +fwrite(void *__p, size_t __s, size_t __n, FILE *__f) +{ + return _fwrite(__p, __s*__n, __f)/__s; +} +#endif + +__extern int printf(const char *, ...); +__extern int vprintf(const char *, va_list); +__extern int fprintf(FILE *, const char *, ...); +__extern int vfprintf(FILE *, const char *, va_list); +__extern int sprintf(char *, const char *, ...); +__extern int vsprintf(char *, const char *, va_list); +__extern int snprintf(char *, size_t n, const char *, ...); +__extern int vsnprintf(char *, size_t n, const char *, va_list); + +__extern int sscanf(const char *, const char *, ...); +__extern int vsscanf(const char *, const char *, va_list); + +__extern void perror(const char *); + +__extern int rename(const char *, const char *); + +#endif /* _STDIO_H */ diff --git a/klibc/klibc/include/stdlib.h b/klibc/klibc/include/stdlib.h new file mode 100644 index 0000000000..38dd1624a5 --- /dev/null +++ b/klibc/klibc/include/stdlib.h @@ -0,0 +1,94 @@ +/* + * stdlib.h + */ + +#ifndef _STDLIB_H +#define _STDLIB_H + +#include +#include +#include + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +static __inline__ __noreturn _Exit(int __n) { + __extern __noreturn _exit(int); + _exit(__n); + for(;;); /* Some gcc versions are stupid */ +} +__extern __noreturn abort(void); +static __inline__ int abs(int __n) { + return (__n < 0) ? -__n : __n; +} +__extern int atexit(void (*)(void)); +__extern int on_exit(void (*)(int, void *), void *); +__extern int atoi(const char *); +__extern long atol(const char *); +__extern long long atoll(const char *); +__extern __noreturn exit(int); +__extern void free(void *); +static __inline__ long labs(long __n) { + return (__n < 0L) ? -__n : __n; +} + +static __inline__ long long llabs(long long __n) { + return (__n < 0LL) ? -__n : __n; +} + +#if defined(__GNUC__) && __GNUC_MAJOR__ >= 3 +# define __attribute_malloc __attribute__((malloc)) +#else +# define __attribute_malloc +#endif + +__extern __attribute_malloc void *malloc(size_t); +__extern __attribute_malloc void *calloc(size_t, size_t); +__extern void *realloc(void *, size_t); +__extern long strtol(const char *, char **, int); +__extern long long strtoll(const char *, char **, int); +__extern unsigned long strtoul(const char *, char **, int); +__extern unsigned long long strtoull(const char *, char **, int); + +__extern char *getenv(const char *); +__extern int putenv(const char *); +__extern int setenv(const char *, const char *, int); +__extern int unsetenv(const char *); + +__extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + + +__extern long jrand48(unsigned short *); +__extern long mrand48(void); +__extern long nrand48(unsigned short *); +__extern long lrand48(void); +__extern unsigned short *seed48(const unsigned short *); +__extern void srand48(long); + +#define RAND_MAX 0x7fffffff +static __inline__ int rand(void) { + return (int)lrand48(); +} +static __inline__ void srand(unsigned int __s) { + srand48(__s); +} +static __inline__ long random(void) +{ + return lrand48(); +} +static __inline__ void srandom(unsigned int __s) +{ + srand48(__s); +} + +/* Basic PTY functions. These only work if devpts is mounted! */ + +static __inline__ int grantpt(int __fd) +{ + (void)__fd; + return 0; /* devpts does this all for us! */ +} +__extern int unlockpt(int); +__extern char *ptsname(int); + +#endif /* _STDLIB_H */ diff --git a/klibc/klibc/include/string.h b/klibc/klibc/include/string.h new file mode 100644 index 0000000000..bce69284ec --- /dev/null +++ b/klibc/klibc/include/string.h @@ -0,0 +1,37 @@ +/* + * string.h + */ + +#ifndef _STRING_H +#define _STRING_H + +#include +#include + +__extern void *memccpy(void *, const void *, int, size_t); +__extern void *memchr(const void *, int, size_t); +__extern int memcmp(const void *, const void *, size_t); +__extern void *memcpy(void *, const void *, size_t); +__extern void *memmove(void *, const void *, size_t); +__extern void *memset(void *, int, size_t); +__extern void *memmem(const void *, size_t, const void *, size_t); +__extern void memswap(void *, void *, size_t); +__extern char *strcat(char *, const char *); +__extern char *strchr(const char *, int); +__extern int strcmp(const char *, const char *); +__extern char *strcpy(char *, const char *); +__extern size_t strcspn(const char *, const char *); +__extern char *strdup(const char *); +__extern char *strerror(int); +__extern size_t strlen(const char *); +__extern char *strncat(char *, const char *, size_t); +__extern int strncmp(const char *, const char *, size_t); +__extern char *strncpy(char *, const char *, size_t); +__extern char *strpbrk(const char *, const char *); +__extern char *strrchr(const char *, int); +__extern char *strsep(char **, const char *); +__extern size_t strspn(const char *, const char *); +__extern char *strstr(const char *, const char *); +__extern char *strtok(char *, const char *); + +#endif /* _STRING_H */ diff --git a/klibc/klibc/include/sys/dirent.h b/klibc/klibc/include/sys/dirent.h new file mode 100644 index 0000000000..0700f4b561 --- /dev/null +++ b/klibc/klibc/include/sys/dirent.h @@ -0,0 +1,13 @@ +/* + * sys/dirent.h + */ + +#ifndef _SYS_DIRENT_H +#define _SYS_DIRENT_H + +#include +#include + +__extern int getdents(unsigned int, struct dirent *, unsigned int); + +#endif /* _SYS_DIRENT_H */ diff --git a/klibc/klibc/include/sys/fsuid.h b/klibc/klibc/include/sys/fsuid.h new file mode 100644 index 0000000000..823486b776 --- /dev/null +++ b/klibc/klibc/include/sys/fsuid.h @@ -0,0 +1,14 @@ +/* + * sys/fsuid.h + */ + +#ifndef _SYS_FSUID_H +#define _SYS_FSUID_H + +#include +#include + +__extern int setfsuid(uid_t); +__extern int setfsgid(gid_t); + +#endif /* _SYS_FSUID_H */ diff --git a/klibc/klibc/include/sys/ioctl.h b/klibc/klibc/include/sys/ioctl.h new file mode 100644 index 0000000000..b0cee4c02c --- /dev/null +++ b/klibc/klibc/include/sys/ioctl.h @@ -0,0 +1,14 @@ +/* + * sys/ioctl.h + */ + +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H + +#include +#include +#include + +__extern int ioctl(int, int, void *); + +#endif /* _SYS_IOCTL_H */ diff --git a/klibc/klibc/include/sys/klog.h b/klibc/klibc/include/sys/klog.h new file mode 100644 index 0000000000..0fc5f5d945 --- /dev/null +++ b/klibc/klibc/include/sys/klog.h @@ -0,0 +1,24 @@ +/* + * sys/klog.h + */ + +#ifndef _SYS_KLOG_H +#define _SYS_KLOG_H + +#include + +#define KLOG_CLOSE 0 +#define KLOG_OPEN 1 +#define KLOG_READ 2 +#define KLOG_READ_ALL 3 +#define KLOG_READ_CLEAR 4 +#define KLOG_CLEAR 5 +#define KLOG_DISABLE 6 +#define KLOG_ENABLE 7 +#define KLOG_SETLEVEL 8 +#define KLOG_UNREADSIZE 9 +#define KLOG_WRITE 10 + +__extern int klogctl(int, char *, int); + +#endif /* _SYS_KLOG_H */ diff --git a/klibc/klibc/include/sys/mman.h b/klibc/klibc/include/sys/mman.h new file mode 100644 index 0000000000..3d8a2f63c2 --- /dev/null +++ b/klibc/klibc/include/sys/mman.h @@ -0,0 +1,21 @@ +/* + * sys/mman.h + */ + +#ifndef _SYS_MMAN_H +#define _SYS_MMAN_H + +#include +#include +#include +#include /* For PAGE_SIZE */ + +#define MAP_FAILED ((void *)-1) + +__extern void *mmap(void *, size_t, int, int, int, off_t); +__extern int munmap(void *, size_t); +__extern void *mremap(void *, size_t, size_t, unsigned long); +__extern int msync(const void *, size_t, int); +__extern int mprotect(const void *, size_t, int); + +#endif /* _SYS_MMAN_H */ diff --git a/klibc/klibc/include/sys/module.h b/klibc/klibc/include/sys/module.h new file mode 100644 index 0000000000..96b3b59945 --- /dev/null +++ b/klibc/klibc/include/sys/module.h @@ -0,0 +1,158 @@ +/* + * sys/module.h + * + * This is a bastardized version of linux/module.h, since the latter + * doesn't have __KERNEL__ guards where it needs them... + */ + +#ifndef _SYS_MODULE_H +#define _SYS_MODULE_H + +/* + * Dynamic loading of modules into the kernel. + * + * Rewritten by Richard Henderson Dec 1996 + */ + +#include + +/* Don't need to bring in all of uaccess.h just for this decl. */ +struct exception_table_entry; + +/* Used by get_kernel_syms, which is obsolete. */ +struct kernel_sym +{ + unsigned long value; + char name[60]; /* should have been 64-sizeof(long); oh well */ +}; + +struct module_symbol +{ + unsigned long value; + const char *name; +}; + +struct module_ref +{ + struct module *dep; /* "parent" pointer */ + struct module *ref; /* "child" pointer */ + struct module_ref *next_ref; +}; + +/* TBD */ +struct module_persist; + +struct module +{ + unsigned long size_of_struct; /* == sizeof(module) */ + struct module *next; + const char *name; + unsigned long size; + + union + { + atomic_t usecount; + long pad; + } uc; /* Needs to keep its size - so says rth */ + + unsigned long flags; /* AUTOCLEAN et al */ + + unsigned nsyms; + unsigned ndeps; + + struct module_symbol *syms; + struct module_ref *deps; + struct module_ref *refs; + int (*init)(void); + void (*cleanup)(void); + const struct exception_table_entry *ex_table_start; + const struct exception_table_entry *ex_table_end; +#ifdef __alpha__ + unsigned long gp; +#endif + /* Members past this point are extensions to the basic + module support and are optional. Use mod_member_present() + to examine them. */ + const struct module_persist *persist_start; + const struct module_persist *persist_end; + int (*can_unload)(void); + int runsize; /* In modutils, not currently used */ + const char *kallsyms_start; /* All symbols for kernel debugging */ + const char *kallsyms_end; + const char *archdata_start; /* arch specific data for module */ + const char *archdata_end; + const char *kernel_data; /* Reserved for kernel internal use */ +}; + +struct module_info +{ + unsigned long addr; + unsigned long size; + unsigned long flags; + long usecount; +}; + +/* Bits of module.flags. */ + +#define MOD_UNINITIALIZED 0 +#define MOD_RUNNING 1 +#define MOD_DELETED 2 +#define MOD_AUTOCLEAN 4 +#define MOD_VISITED 8 +#define MOD_USED_ONCE 16 +#define MOD_JUST_FREED 32 +#define MOD_INITIALIZING 64 + +/* Values for query_module's which. */ + +#define QM_MODULES 1 +#define QM_DEPS 2 +#define QM_REFS 3 +#define QM_SYMBOLS 4 +#define QM_INFO 5 + +/* Can the module be queried? */ +#define MOD_CAN_QUERY(mod) (((mod)->flags & (MOD_RUNNING | MOD_INITIALIZING)) && !((mod)->flags & MOD_DELETED)) + +/* When struct module is extended, we must test whether the new member + is present in the header received from insmod before we can use it. + This function returns true if the member is present. */ + +#define mod_member_present(mod,member) \ + ((unsigned long)(&((struct module *)0L)->member + 1) \ + <= (mod)->size_of_struct) + +/* + * Ditto for archdata. Assumes mod->archdata_start and mod->archdata_end + * are validated elsewhere. + */ +#define mod_archdata_member_present(mod, type, member) \ + (((unsigned long)(&((type *)0L)->member) + \ + sizeof(((type *)0L)->member)) <= \ + ((mod)->archdata_end - (mod)->archdata_start)) + + +/* Check if an address p with number of entries n is within the body of module m */ +#define mod_bound(p, n, m) ((unsigned long)(p) >= ((unsigned long)(m) + ((m)->size_of_struct)) && \ + (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size) + +/* Backwards compatibility definition. */ + +#define GET_USE_COUNT(module) (atomic_read(&(module)->uc.usecount)) + +/* Poke the use count of a module. */ + +#define __MOD_INC_USE_COUNT(mod) \ + (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE) +#define __MOD_DEC_USE_COUNT(mod) \ + (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED) +#define __MOD_IN_USE(mod) \ + (mod_member_present((mod), can_unload) && (mod)->can_unload \ + ? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount)) + +/* Indirect stringification. */ + +#define __MODULE_STRING_1(x) #x +#define __MODULE_STRING(x) __MODULE_STRING_1(x) + +#endif /* _SYS_MODULE_H */ diff --git a/klibc/klibc/include/sys/mount.h b/klibc/klibc/include/sys/mount.h new file mode 100644 index 0000000000..313c90ec0e --- /dev/null +++ b/klibc/klibc/include/sys/mount.h @@ -0,0 +1,55 @@ +/* + * sys/mount.h + */ + +#ifndef _SYS_MOUNT_H +#define _SYS_MOUNT_H + +#include + +/* + * These are the fs-independent mount-flags: up to 32 flags are supported + */ +#define MS_RDONLY 1 /* Mount read-only */ +#define MS_NOSUID 2 /* Ignore suid and sgid bits */ +#define MS_NODEV 4 /* Disallow access to device special files */ +#define MS_NOEXEC 8 /* Disallow program execution */ +#define MS_SYNCHRONOUS 16 /* Writes are synced at once */ +#define MS_REMOUNT 32 /* Alter flags of a mounted FS */ +#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ +#define MS_DIRSYNC 128 /* Directory modifications are synchronous */ +#define MS_NOATIME 1024 /* Do not update access times. */ +#define MS_NODIRATIME 2048 /* Do not update directory access times */ +#define MS_BIND 4096 +#define MS_MOVE 8192 +#define MS_REC 16384 +#define MS_VERBOSE 32768 +#define MS_NOUSER (1<<31) + +/* + * Superblock flags that can be altered by MS_REMOUNT + */ +#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|MS_NODIRATIME) + +/* + * Old magic mount flag and mask + */ +#define MS_MGC_VAL 0xC0ED0000 +#define MS_MGC_MSK 0xffff0000 + +/* + * umount2() flags + */ +#define MNT_FORCE 1 + +/* + * Prototypes + */ +__extern int mount(const char *, const char *, + const char *, unsigned long, + const void *); +__extern int umount(const char *); +__extern int umount2(const char *, int); +__extern int pivot_root(const char *, const char *); + +#endif /* _SYS_MOUNT_H */ diff --git a/klibc/klibc/include/sys/param.h b/klibc/klibc/include/sys/param.h new file mode 100644 index 0000000000..63a0661f43 --- /dev/null +++ b/klibc/klibc/include/sys/param.h @@ -0,0 +1,11 @@ +/* + * sys/param.h + */ + +#ifndef _SYS_PARAM_H +#define _SYS_PARAM_H + +#include +#include + +#endif /* _SYS_PARAM_H */ diff --git a/klibc/klibc/include/sys/reboot.h b/klibc/klibc/include/sys/reboot.h new file mode 100644 index 0000000000..eaf56610d7 --- /dev/null +++ b/klibc/klibc/include/sys/reboot.h @@ -0,0 +1,25 @@ +/* + * sys/reboot.h + */ + +#ifndef _SYS_REBOOT_H +#define _SYS_REBOOT_H + +#include +#include + +/* glibc names these constants differently; allow both versions */ + +#define RB_AUTOBOOT LINUX_REBOOT_CMD_RESTART +#define RB_HALT_SYSTEM LINUX_REBOOT_CMD_HALT +#define RB_ENABLE_CAD LINUX_REBOOT_CMD_CAD_ON +#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF +#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF + +/* glibc-ish one-argument version */ +__extern int reboot(int); + +/* Native four-argument system call */ +__extern int __reboot(int, int, int, void *); + +#endif /* _SYS_REBOOT_H */ diff --git a/klibc/klibc/include/sys/resource.h b/klibc/klibc/include/sys/resource.h new file mode 100644 index 0000000000..ef14bde9f6 --- /dev/null +++ b/klibc/klibc/include/sys/resource.h @@ -0,0 +1,15 @@ +/* + * sys/resource.h + */ + +#ifndef _SYS_RESOURCE_H +#define _SYS_RESOURCE_H + +#include +#include /* MUST be included before linux/resource.h */ +#include + +__extern int getpriority(int, int); +__extern int setpriority(int, int, int); + +#endif /* _SYS_RESOURCE_H */ diff --git a/klibc/klibc/include/sys/select.h b/klibc/klibc/include/sys/select.h new file mode 100644 index 0000000000..7caf8c931b --- /dev/null +++ b/klibc/klibc/include/sys/select.h @@ -0,0 +1,13 @@ +/* + * sys/select.h + */ + +#ifndef _SYS_SELECT_H +#define _SYS_SELECT_H + +#include +#include + +__extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); + +#endif /* _SYS_SELECT_H */ diff --git a/klibc/klibc/include/sys/socket.h b/klibc/klibc/include/sys/socket.h new file mode 100644 index 0000000000..cbc2b89591 --- /dev/null +++ b/klibc/klibc/include/sys/socket.h @@ -0,0 +1,50 @@ +/* + * sys/socket.h + */ + +#ifndef _SYS_SOCKET_H +#define _SYS_SOCKET_H + +#include +#include +#include + +/* For some reason these may be protected by __KERNEL__ in asm/socket.h */ +#ifndef SOCK_STREAM +# define SOCK_STREAM 1 +# define SOCK_DGRAM 2 +# define SOCK_RAW 3 +# define SOCK_RDM 4 +# define SOCK_SEQPACKET 5 +# define SOCK_PACKET 10 +#endif + +#ifdef __i386__ +# define __socketcall __extern __cdecl +#else +# define __socketcall __extern +#endif + +typedef int socklen_t; + +__socketcall int socket(int, int, int); +__socketcall int bind(int, struct sockaddr *, int); +__socketcall int connect(int, struct sockaddr *, socklen_t); +__socketcall int listen(int, int); +__socketcall int accept(int, struct sockaddr *, socklen_t *); +__socketcall int getsockname(int, struct sockaddr *, socklen_t *); +__socketcall int getpeername(int, struct sockaddr *, socklen_t *); +__socketcall int socketpair(int, int, int, int *); +__extern int send(int, const void *, size_t, unsigned int); +__socketcall int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); +__extern int recv(int, void *, size_t, unsigned int); +__socketcall int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *); +__socketcall int shutdown(int, int); +__socketcall int setsockopt(int, int, int, const void *, socklen_t); +__socketcall int getsockopt(int, int, int, void *, socklen_t *); +__socketcall int sendmsg(int, const struct msghdr *, unsigned int); +__socketcall int recvmsg(int, struct msghdr *, unsigned int); + +#undef __socketcall + +#endif /* _SYS_SOCKET_H */ diff --git a/klibc/klibc/include/sys/socketcalls.h b/klibc/klibc/include/sys/socketcalls.h new file mode 100644 index 0000000000..dac9f9aab6 --- /dev/null +++ b/klibc/klibc/include/sys/socketcalls.h @@ -0,0 +1,28 @@ +/* + * sys/socketcalls.h + */ + +#ifndef _SYS_SOCKETCALLS_H +#define _SYS_SOCKETCALLS_H + +/* socketcalls by number, since isn't usable for assembly */ + +#define SYS_SOCKET 1 /* sys_socket(2) */ +#define SYS_BIND 2 /* sys_bind(2) */ +#define SYS_CONNECT 3 /* sys_connect(2) */ +#define SYS_LISTEN 4 /* sys_listen(2) */ +#define SYS_ACCEPT 5 /* sys_accept(2) */ +#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ +#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ +#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ +#define SYS_SEND 9 /* sys_send(2) */ +#define SYS_RECV 10 /* sys_recv(2) */ +#define SYS_SENDTO 11 /* sys_sendto(2) */ +#define SYS_RECVFROM 12 /* sys_recvfrom(2) */ +#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ +#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ +#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ +#define SYS_SENDMSG 16 /* sys_sendmsg(2) */ +#define SYS_RECVMSG 17 /* sys_recvmsg(2) */ + +#endif /* _SYS_SOCKETCALLS_H */ diff --git a/klibc/klibc/include/sys/stat.h b/klibc/klibc/include/sys/stat.h new file mode 100644 index 0000000000..f7bb5aacc5 --- /dev/null +++ b/klibc/klibc/include/sys/stat.h @@ -0,0 +1,23 @@ +/* + * sys/stat.h + */ + +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include +#include +#include +#include + +__extern int stat(const char *, struct stat *); +__extern int fstat(int, struct stat *); +__extern int lstat(const char *, struct stat *); +__extern mode_t umask(mode_t); +__extern int mknod(const char *, mode_t, dev_t); +static __inline__ int mkfifo(const char *__p, mode_t __m) +{ + return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0); +} + +#endif /* _SYS_STAT_H */ diff --git a/klibc/klibc/include/sys/syscall.h b/klibc/klibc/include/sys/syscall.h new file mode 100644 index 0000000000..907c7f9b9a --- /dev/null +++ b/klibc/klibc/include/sys/syscall.h @@ -0,0 +1,15 @@ +/* + * sys/syscall.h + * + * Generic system call interface macros + */ +#ifndef _SYS_SYSCALL_H +#define _SYS_SYSCALL_H + +#include +#include + +/* Many architectures have incomplete or defective syscall macros */ +#include + +#endif /* _SYS_SYSCALL_H */ diff --git a/klibc/klibc/include/sys/time.h b/klibc/klibc/include/sys/time.h new file mode 100644 index 0000000000..4eccf824a4 --- /dev/null +++ b/klibc/klibc/include/sys/time.h @@ -0,0 +1,16 @@ +/* + * sys/time.h + */ + +#ifndef _SYS_TIME_H +#define _SYS_TIME_H + +#include +#include + +__extern int gettimeofday(struct timeval *, struct timezone *); +__extern int settimeofday(const struct timeval *, const struct timezone *); +__extern int getitimer(int, struct itimerval *); +__extern int setitimer(int, const struct itimerval *, struct itimerval *); + +#endif /* _SYS_TIME_H */ diff --git a/klibc/klibc/include/sys/times.h b/klibc/klibc/include/sys/times.h new file mode 100644 index 0000000000..657f9c4b1c --- /dev/null +++ b/klibc/klibc/include/sys/times.h @@ -0,0 +1,14 @@ +/* + * sys/times.h + */ + +#ifndef _SYS_TIMES_H +#define _SYS_TIMES_H + +#include + +__extern clock_t times(struct tms *); +__extern int gettimeofday(struct timeval *, struct timezone *); +__extern int settimeofday(const struct timeval *, const struct timezone *); + +#endif /* _SYS_TIMES_H */ diff --git a/klibc/klibc/include/sys/types.h b/klibc/klibc/include/sys/types.h new file mode 100644 index 0000000000..a25873cc4b --- /dev/null +++ b/klibc/klibc/include/sys/types.h @@ -0,0 +1,127 @@ +/* + * sys/types.h + * + * This is a bastardized version of linux/types.h, since that file + * is broken w.r.t. definitions. + */ + +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H + +#include +#include + +#define _SSIZE_T +typedef ptrdiff_t ssize_t; + +#include +#include + +/* Keeps linux/types.h from getting included elsewhere */ +#define _LINUX_TYPES_H + +typedef __kernel_fd_set fd_set; +typedef uint32_t dev_t; +typedef __kernel_ino_t ino_t; +typedef __kernel_mode_t mode_t; +typedef __kernel_nlink_t nlink_t; +typedef __kernel_off_t off_t; +typedef __kernel_pid_t pid_t; +typedef __kernel_daddr_t daddr_t; +typedef __kernel_key_t key_t; +typedef __kernel_suseconds_t suseconds_t; +typedef __kernel_timer_t timer_t; + +typedef __kernel_uid32_t uid_t; +typedef __kernel_gid32_t gid_t; + +typedef __kernel_loff_t loff_t; + +/* + * The following typedefs are also protected by individual ifdefs for + * historical reasons: + */ +#ifndef _SIZE_T +#define _SIZE_T +typedef __kernel_size_t size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __kernel_ssize_t ssize_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __kernel_ptrdiff_t ptrdiff_t; +#endif + +#ifndef _TIME_T +#define _TIME_T +typedef __kernel_time_t time_t; +#endif + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef __kernel_clock_t clock_t; +#endif + +#ifndef _CADDR_T +#define _CADDR_T +typedef __kernel_caddr_t caddr_t; +#endif + +/* bsd */ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +/* sysv */ +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ + +typedef __u8 u_int8_t; +typedef __u16 u_int16_t; +typedef __u32 u_int32_t; +typedef __u64 u_int64_t; + +#endif /* !(__BIT_TYPES_DEFINED__) */ + +/* + * transition to 64-bit sector_t, possibly making it an option... + */ +#undef BLK_64BIT_SECTOR + +#ifdef BLK_64BIT_SECTOR +typedef u64 sector_t; +#else +typedef unsigned long sector_t; +#endif + +/* + * The type of an index into the pagecache. Use a #define so asm/types.h + * can override it. + */ +#ifndef pgoff_t +#define pgoff_t unsigned long +#endif + +/* + * Below are truly Linux-specific types that should never collide with + * any application/library that wants linux/types.h. + */ + +struct ustat { + __kernel_daddr_t f_tfree; + __kernel_ino_t f_tinode; + char f_fname[6]; + char f_fpack[6]; +}; + +#endif diff --git a/klibc/klibc/include/sys/uio.h b/klibc/klibc/include/sys/uio.h new file mode 100644 index 0000000000..fc2525d11a --- /dev/null +++ b/klibc/klibc/include/sys/uio.h @@ -0,0 +1,15 @@ +/* + * sys/uio.h + */ + +#ifndef _SYS_UIO_H +#define _SYS_UIO_H + +#include +#include +#include + +__extern int readv(int, const struct iovec *, int); +__extern int writev(int, const struct iovec *, int); + +#endif /* _SYS_UIO_H */ diff --git a/klibc/klibc/include/sys/utime.h b/klibc/klibc/include/sys/utime.h new file mode 100644 index 0000000000..d1d635d242 --- /dev/null +++ b/klibc/klibc/include/sys/utime.h @@ -0,0 +1,10 @@ +/* + * sys/utime.h + */ + +#ifndef _SYS_UTIME_H +#define _SYS_UTIME_H + +#include + +#endif /* _SYS_UTIME_H */ diff --git a/klibc/klibc/include/sys/utsname.h b/klibc/klibc/include/sys/utsname.h new file mode 100644 index 0000000000..f2990f5711 --- /dev/null +++ b/klibc/klibc/include/sys/utsname.h @@ -0,0 +1,23 @@ +/* + * sys/utsname.h + */ + +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#include + +#define SYS_NMLN 65 + +struct utsname { + char sysname[SYS_NMLN]; + char nodename[SYS_NMLN]; + char release[SYS_NMLN]; + char version[SYS_NMLN]; + char machine[SYS_NMLN]; + char domainname[SYS_NMLN]; +}; + +__extern int uname(struct utsname *); + +#endif /* _SYS_UTSNAME_H */ diff --git a/klibc/klibc/include/sys/vfs.h b/klibc/klibc/include/sys/vfs.h new file mode 100644 index 0000000000..8c1577c4bf --- /dev/null +++ b/klibc/klibc/include/sys/vfs.h @@ -0,0 +1,14 @@ +/* + * sys/vfs.h + */ + +#ifndef _SYS_VFS_H +#define _SYS_VFS_H + +#include +#include + +__extern int statfs(const char *, struct statfs *); +__extern int fstatfs(int, struct statfs *); + +#endif /* _SYS_VFS_H */ diff --git a/klibc/klibc/include/sys/wait.h b/klibc/klibc/include/sys/wait.h new file mode 100644 index 0000000000..cad6989bf7 --- /dev/null +++ b/klibc/klibc/include/sys/wait.h @@ -0,0 +1,19 @@ +/* + * sys/wait.h + */ + +#ifndef _SYS_WAIT_H +#define _SYS_WAIT_H + +#include +#include +#include + +#include + +__extern pid_t wait(int *); +__extern pid_t waitpid(pid_t, int *, int); +__extern pid_t wait3(int *, int, struct rusage *); +__extern pid_t wait4(pid_t, int *, int, struct rusage *); + +#endif /* _SYS_WAIT_H */ diff --git a/klibc/klibc/include/syslog.h b/klibc/klibc/include/syslog.h new file mode 100644 index 0000000000..b6c0acfea1 --- /dev/null +++ b/klibc/klibc/include/syslog.h @@ -0,0 +1,53 @@ +/* + * syslog.h + */ + +#ifndef _SYSLOG_H +#define _SYSLOG_H + +#include + +/* Alert levels */ +#define LOG_EMERG 0 +#define LOG_ALERT 1 +#define LOG_CRIT 2 +#define LOG_ERR 3 +#define LOG_WARNING 4 +#define LOG_NOTICE 5 +#define LOG_INFO 6 +#define LOG_DEBUG 7 + +#define LOG_PRIMASK 7 +#define LOG_PRI(x) ((x) & LOG_PRIMASK) + + +/* Facilities; not actually used */ +#define LOG_KERN 0000 +#define LOG_USER 0010 +#define LOG_MAIL 0020 +#define LOG_DAEMON 0030 +#define LOG_AUTH 0040 +#define LOG_SYSLOG 0050 +#define LOG_LPR 0060 +#define LOG_NEWS 0070 +#define LOG_UUCP 0100 +#define LOG_CRON 0110 +#define LOG_AUTHPRIV 0120 +#define LOG_FTP 0130 +#define LOG_LOCAL0 0200 +#define LOG_LOCAL1 0210 +#define LOG_LOCAL2 0220 +#define LOG_LOCAL3 0230 +#define LOG_LOCAL4 0240 +#define LOG_LOCAL5 0250 +#define LOG_LOCAL6 0260 +#define LOG_LOCAL7 0270 + +#define LOG_FACMASK 01770 +#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3)) + +__extern void openlog(const char *, int, int); +__extern void syslog(int, const char *, ...); +__extern void closelog(void); + +#endif /* _SYSLOG_H */ diff --git a/klibc/klibc/include/termios.h b/klibc/klibc/include/termios.h new file mode 100644 index 0000000000..08a5e56855 --- /dev/null +++ b/klibc/klibc/include/termios.h @@ -0,0 +1,86 @@ +/* + * termios.h + */ + +#ifndef _TERMIOS_H +#define _TERMIOS_H + +#include +#include +#include +#include +#include + +/* Redefine these so the magic constants == the ioctl number to use. */ +#undef TCSANOW +#undef TCSADRAIN +#undef TCSAFLUSH +#define TCSANOW TCSETS +#define TCSADRAIN TCSETSW +#define TCSAFLUSH TCSETSF + +static __inline__ int tcgetattr(int __fd, struct termios *__s) +{ + return ioctl(__fd, TCGETS, __s); +} + +static __inline__ int tcsetattr(int __fd, int __opt, const struct termios *__s) +{ + return ioctl(__fd, __opt, (void *)__s); +} + +static __inline__ int tcflow(int __fd, int __action) +{ + return ioctl(__fd, TCXONC, (void *)(intptr_t)__action); +} + +static __inline__ int tcflush(int __fd, int __queue) +{ + return ioctl(__fd, TCFLSH, (void *)(intptr_t)__queue); +} + +static __inline__ pid_t tcgetpgrp(int __fd) +{ + pid_t __p; + return ioctl(__fd, TIOCGPGRP, &__p) ? (pid_t)-1 : __p; +} + +static __inline__ pid_t tcgetsid(int __fd) +{ + pid_t __p; + return ioctl(__fd, TIOCGSID, &__p) ? (pid_t)-1 : __p; +} + +static __inline__ int tcsendbreak(int __fd, int __duration) +{ + return ioctl(__fd, TCSBRKP, (void *)(uintptr_t)__duration); +} + +static __inline__ int tcsetpgrp(int __fd, pid_t __p) +{ + return ioctl(__fd, TIOCSPGRP, &__p); +} + +static __inline__ speed_t cfgetospeed(const struct termios *__s) +{ + return (speed_t)(__s->c_cflag & CBAUD); +} + +static __inline__ speed_t cfgetispeed(const struct termios *__s) +{ + return (speed_t)(__s->c_cflag & CBAUD); +} + +static __inline__ int cfsetospeed(struct termios *__s, speed_t __v) +{ + __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); + return 0; +} + +static __inline__ int cfsetispeed(struct termios *__s, speed_t __v) +{ + __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); + return 0; +} + +#endif /* _TERMIOS_H */ diff --git a/klibc/klibc/include/time.h b/klibc/klibc/include/time.h new file mode 100644 index 0000000000..c69c231ec8 --- /dev/null +++ b/klibc/klibc/include/time.h @@ -0,0 +1,14 @@ +/* + * time.h + */ + +#ifndef _TIME_H +#define _TIME_H + +#include +#include + +__extern time_t time(time_t *); +__extern int nanosleep(const struct timespec *, struct timespec *); + +#endif /* _TIME_H */ diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h new file mode 100644 index 0000000000..a9b434c16b --- /dev/null +++ b/klibc/klibc/include/unistd.h @@ -0,0 +1,111 @@ +/* + * unistd.h + */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#include +#include +#include +#include +#include + +__extern char **environ; +__extern __noreturn _exit(int); + +__extern pid_t fork(void); +__extern pid_t vfork(void); +__extern pid_t getpid(void); +__extern int setpgid(pid_t, pid_t); +__extern pid_t getppid(void); +__extern pid_t getpgrp(void); +__extern int setpgrp(void); +__extern pid_t setsid(void); +__extern pid_t getsid(pid_t); +__extern int execv(const char *, char * const *); +__extern int execvp(const char *, char * const *); +__extern int execve(const char *, char * const *, char * const *); +__extern int execvpe(const char *, char * const *, char * const *); +__extern int execl(const char *, const char *, ...); +__extern int execlp(const char *, const char *, ...); +__extern int execle(const char *, const char *, ...); +__extern int execlpe(const char *, const char *, ...); + +__extern int setuid(uid_t); +__extern uid_t getuid(void); +__extern int seteuid(uid_t); +__extern uid_t geteuid(void); +__extern int setgid(gid_t); +__extern gid_t getgid(void); +__extern int setegid(gid_t); +__extern gid_t getegid(void); +__extern int getgroups(int, gid_t *); +__extern int setgroups(size_t, const gid_t *); +__extern int setreuid(uid_t, uid_t); +__extern int setregid(gid_t, gid_t); +__extern int setresuid(uid_t, uid_t, uid_t); +__extern int setresgid(gid_t, gid_t, gid_t); +__extern int getfsuid(uid_t); +__extern int setfsuid(uid_t); + +__extern int access(const char *, int); +__extern int link(const char *, const char *); +__extern int unlink(const char *); +__extern int chdir(const char *); +__extern int chmod(const char *, mode_t); +__extern int mkdir(const char *, mode_t); +__extern int rmdir(const char *); +__extern int pipe(int *); +__extern int chroot(const char *); +__extern int symlink(const char *, const char *); +__extern int readlink(const char *, char *, size_t); +__extern int chown(const char *, uid_t, gid_t); +__extern int fchown(int, uid_t, gid_t); +__extern int lchown(const char *, uid_t, gid_t); +__extern char *getcwd(char *, size_t); + +__extern int sync(void); + +__extern ssize_t read(int, void *, size_t); +__extern ssize_t write(int, const void *, size_t); +#ifndef __IN_SYS_COMMON +__extern int open(const char *, int, ...); +#endif +__extern int close(int); +__extern off_t lseek(int, off_t, int); +__extern loff_t llseek(int, loff_t, int); +__extern int dup(int); +__extern int dup2(int, int); +__extern int fcntl(int, int, long); +__extern int ioctl(int, int, void *); +__extern int flock(int, int); +__extern int fsync(int); +__extern int fdatasync(int); + +__extern int pause(void); +__extern unsigned int alarm(unsigned int); +__extern unsigned int sleep(unsigned int); +__extern void usleep(unsigned long); + +__extern int gethostname(char *, size_t); +__extern int sethostname(const char *, size_t); +__extern int getdomainname(char *, size_t); +__extern int setdomainname(const char *, size_t); + +__extern void *__brk(void *); +__extern int brk(void *); +__extern void *sbrk(ptrdiff_t); + +__extern int getopt(int, char * const *, const char *); +__extern char *optarg; +__extern int optind, opterr, optopt; + +__extern int isatty(int); + +/* Standard file descriptor numbers. */ +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#endif /* _UNISTD_H */ diff --git a/klibc/klibc/include/utime.h b/klibc/klibc/include/utime.h new file mode 100644 index 0000000000..3dfa03a14a --- /dev/null +++ b/klibc/klibc/include/utime.h @@ -0,0 +1,15 @@ +/* + * utime.h + */ + +#ifndef _UTIME_H +#define _UTIME_H + +#include +#include +#include + +__extern int utime(const char *, const struct utimbuf *); + +#endif /* _UTIME_H */ + diff --git a/klibc/klibc/inet/bindresvport.c b/klibc/klibc/inet/bindresvport.c new file mode 100644 index 0000000000..b5f327bb33 --- /dev/null +++ b/klibc/klibc/inet/bindresvport.c @@ -0,0 +1,48 @@ +/* + * inet/bindresvport.c + */ + +#include +#include +#include +#include +#include +#include + +#define START_PORT 600 +#define END_PORT (IPPORT_RESERVED - 1) +#define NUM_PORTS (END_PORT - START_PORT) + +int bindresvport(int sd, struct sockaddr_in *sin) +{ + struct sockaddr_in me; + static short port; + int ret = 0; + int i; + + if (sin == NULL) { + sin = &me; + memset(sin, 0, sizeof(me)); + sin->sin_port = AF_INET; + } + else if (sin->sin_family != AF_INET) { + errno = EPFNOSUPPORT; + ret = -1; + goto bail; + } + + if (port == 0) { + port = START_PORT + (getpid() % NUM_PORTS); + } + + for (i = 0; i < NUM_PORTS; i++, port++) { + sin->sin_port = htons(port); + if ((ret = bind(sd, sin, sizeof(*sin))) != -1) + break; + if (port == END_PORT) + port = START_PORT; + } + + bail: + return ret; +} diff --git a/klibc/klibc/inet/inet_addr.c b/klibc/klibc/inet/inet_addr.c new file mode 100644 index 0000000000..e04a4d0214 --- /dev/null +++ b/klibc/klibc/inet/inet_addr.c @@ -0,0 +1,14 @@ +/* + * inet/inet_addr.c + */ + +#include +#include + +uint32_t inet_addr(const char *str) +{ + struct in_addr a; + int rv = inet_aton(str, &a); + + return rv ? INADDR_NONE : a.s_addr; +} diff --git a/klibc/klibc/inet/inet_aton.c b/klibc/klibc/inet/inet_aton.c new file mode 100644 index 0000000000..e581b492ad --- /dev/null +++ b/klibc/klibc/inet/inet_aton.c @@ -0,0 +1,23 @@ +/* + * inet/inet_aton.c + */ + +#include +#include + +int inet_aton(const char *str, struct in_addr *addr) +{ + union { + uint8_t b[4]; + uint32_t l; + } a; + + if ( sscanf(str, "%hhu.%hhu.%hhu.%hhu", &a.b[0], &a.b[1], &a.b[2], &a.b[3]) == 4 ) { + addr->s_addr = a.l; /* Always in network byte order */ + return 1; + } else { + return 0; + } +} + + diff --git a/klibc/klibc/inet/inet_ntoa.c b/klibc/klibc/inet/inet_ntoa.c new file mode 100644 index 0000000000..5340aa622a --- /dev/null +++ b/klibc/klibc/inet/inet_ntoa.c @@ -0,0 +1,19 @@ +/* + * inet/inet_ntoa.c + */ + +#include +#include + +char *inet_ntoa(struct in_addr addr) +{ + static char name[16]; + union { + uint8_t b[4]; + uint32_t l; + } a; + a.l = addr.s_addr; + + sprintf(name, "%u.%u.%u.%u", a.b[0], a.b[1], a.b[2], a.b[3]); + return name; +} diff --git a/klibc/klibc/inet/inet_ntop.c b/klibc/klibc/inet/inet_ntop.c new file mode 100644 index 0000000000..377bab7bf2 --- /dev/null +++ b/klibc/klibc/inet/inet_ntop.c @@ -0,0 +1,52 @@ +/* + * inet/inet_ntop.c + */ + +#include +#include +#include +#include +#include + +const char *inet_ntop(int af, const void *cp, char *buf, size_t len) +{ + size_t xlen; + + switch ( af ) { + case AF_INET: + { + union { + uint8_t b[4]; + uint32_t l; + } a; + a.l = ((const struct in_addr *)cp)->s_addr; + + xlen = snprintf(buf, len, "%u.%u.%u.%u", a.b[0], a.b[1], a.b[2], a.b[3]); + } + break; + + case AF_INET6: + { + const struct in6_addr *s = (const struct in6_addr *)cp; + + xlen = snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x", + ntohs(s->s6_addr16[0]), ntohs(s->s6_addr16[1]), + ntohs(s->s6_addr16[2]), ntohs(s->s6_addr16[3]), + ntohs(s->s6_addr16[4]), ntohs(s->s6_addr16[5]), + ntohs(s->s6_addr16[6]), ntohs(s->s6_addr16[7])); + } + break; + + default: + errno = EAFNOSUPPORT; + return NULL; + } + + if ( xlen > len ) { + errno = ENOSPC; + return NULL; + } + + return buf; +} + diff --git a/klibc/klibc/inet/inet_pton.c b/klibc/klibc/inet/inet_pton.c new file mode 100644 index 0000000000..6c14b3cfb6 --- /dev/null +++ b/klibc/klibc/inet/inet_pton.c @@ -0,0 +1,74 @@ +/* + * inet/inet_pton.c + */ + +#include +#include +#include +#include +#include +#include +#include + +static inline int hexval(int ch) +{ + if ( ch >= '0' && ch <= '9' ) { + return ch-'0'; + } else if ( ch >= 'A' && ch <= 'F' ) { + return ch-'A'+10; + } else if ( ch >= 'a' && ch <= 'f' ) { + return ch-'a'+10; + } else { + return -1; + } +} + +int inet_pton(int af, const char *src, void *dst) +{ + switch ( af ) { + case AF_INET: + return inet_aton(src, (struct in_addr *)dst); + + case AF_INET6: + { + struct in6_addr *d = (struct in6_addr *)dst; + int colons = 0, dcolons = 0; + int i; + const char *p; + + /* A double colon will increment colons by 2, dcolons by 1 */ + for ( p = dst ; *p ; p++ ) { + if ( p[0] == ':' ) { + colons++; + if ( p[1] == ':' ) + dcolons++; + } else if ( !isxdigit(*p) ) + return 0; /* Not a valid address */ + } + + if ( colons > 7 || dcolons > 1 || (!dcolons && colons != 7) ) + return 0; /* Not a valid address */ + + memset(d, 0, sizeof(struct in6_addr)); + + i = 0; + for ( p = dst ; *p ; p++ ) { + if ( *p == ':' ) { + if ( p[1] == ':' ) { + i += (8-colons); + } else { + i++; + } + } else { + d->s6_addr16[i] = htons((ntohs(d->s6_addr16[i]) << 4) + hexval(*p)); + } + } + + return 1; + } + + default: + errno = EAFNOSUPPORT; + return -1; + } +} diff --git a/klibc/klibc/interp.S b/klibc/klibc/interp.S new file mode 100644 index 0000000000..303943697b --- /dev/null +++ b/klibc/klibc/interp.S @@ -0,0 +1,11 @@ +# +# This is a hack to generate the .intrp section, which then +# ld turns into an PT_INTERP header. +# + + .section ".interp","a" + .ascii LIBDIR + .ascii "/klibc-" + .ascii SOHASH + .ascii ".so" + .byte 0 diff --git a/klibc/klibc/isatty.c b/klibc/klibc/isatty.c new file mode 100644 index 0000000000..ff5e1ff748 --- /dev/null +++ b/klibc/klibc/isatty.c @@ -0,0 +1,21 @@ +/* + * isatty.c + */ + +#include +#include +#include + +int isatty(int fd) +{ + int old_errno = errno; + int istty; + pid_t dummy; + + /* All ttys support TIOCGPGRP */ + istty = !ioctl(fd, TIOCGPGRP, &dummy); + errno = old_errno; + + return istty; +} + diff --git a/klibc/klibc/libgcc/__divdi3.c b/klibc/klibc/libgcc/__divdi3.c new file mode 100644 index 0000000000..be13caed7e --- /dev/null +++ b/klibc/klibc/libgcc/__divdi3.c @@ -0,0 +1,29 @@ +/* + * arch/i386/libgcc/__divdi3.c + */ + +#include +#include + +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); + +int64_t __divdi3(int64_t num, int64_t den) +{ + int minus = 0; + int64_t v; + + if ( num < 0 ) { + num = -num; + minus = 1; + } + if ( den < 0 ) { + den = -den; + minus ^= 1; + } + + v = __udivmoddi4(num, den, NULL); + if ( minus ) + v = -v; + + return v; +} diff --git a/klibc/klibc/libgcc/__divsi3.c b/klibc/klibc/libgcc/__divsi3.c new file mode 100644 index 0000000000..24a7e044c8 --- /dev/null +++ b/klibc/klibc/libgcc/__divsi3.c @@ -0,0 +1,29 @@ +/* + * libgcc/__divsi3.c + */ + +#include +#include + +extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); + +int32_t __divsi3(int32_t num, int32_t den) +{ + int minus = 0; + int32_t v; + + if ( num < 0 ) { + num = -num; + minus = 1; + } + if ( den < 0 ) { + den = -den; + minus ^= 1; + } + + v = __udivmodsi4(num, den, NULL); + if ( minus ) + v = -v; + + return v; +} diff --git a/klibc/klibc/libgcc/__moddi3.c b/klibc/klibc/libgcc/__moddi3.c new file mode 100644 index 0000000000..3e613654e4 --- /dev/null +++ b/klibc/klibc/libgcc/__moddi3.c @@ -0,0 +1,29 @@ +/* + * arch/i386/libgcc/__moddi3.c + */ + +#include +#include + +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); + +int64_t __moddi3(int64_t num, int64_t den) +{ + int minus = 0; + int64_t v; + + if ( num < 0 ) { + num = -num; + minus = 1; + } + if ( den < 0 ) { + den = -den; + minus ^= 1; + } + + (void) __udivmoddi4(num, den, &v); + if ( minus ) + v = -v; + + return v; +} diff --git a/klibc/klibc/libgcc/__modsi3.c b/klibc/klibc/libgcc/__modsi3.c new file mode 100644 index 0000000000..cf62b8b556 --- /dev/null +++ b/klibc/klibc/libgcc/__modsi3.c @@ -0,0 +1,29 @@ +/* + * libgcc/__modsi3.c + */ + +#include +#include + +extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); + +int32_t __modsi3(int32_t num, int32_t den) +{ + int minus = 0; + int32_t v; + + if ( num < 0 ) { + num = -num; + minus = 1; + } + if ( den < 0 ) { + den = -den; + minus ^= 1; + } + + (void) __udivmodsi4(num, den, &v); + if ( minus ) + v = -v; + + return v; +} diff --git a/klibc/klibc/libgcc/__udivdi3.c b/klibc/klibc/libgcc/__udivdi3.c new file mode 100644 index 0000000000..901ce2aea6 --- /dev/null +++ b/klibc/klibc/libgcc/__udivdi3.c @@ -0,0 +1,13 @@ +/* + * arch/i386/libgcc/__divdi3.c + */ + +#include +#include + +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); + +uint64_t __udivdi3(uint64_t num, uint64_t den) +{ + return __udivmoddi4(num, den, NULL); +} diff --git a/klibc/klibc/libgcc/__udivmoddi4.c b/klibc/klibc/libgcc/__udivmoddi4.c new file mode 100644 index 0000000000..1c456543be --- /dev/null +++ b/klibc/klibc/libgcc/__udivmoddi4.c @@ -0,0 +1,32 @@ +#include +#include + +uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p) +{ + uint64_t quot = 0, qbit = 1; + + if ( den == 0 ) { + __divide_error(); + return 0; /* If trap returns... */ + } + + /* Left-justify denominator and count shift */ + while ( (int64_t)den >= 0 ) { + den <<= 1; + qbit <<= 1; + } + + while ( qbit ) { + if ( den <= num ) { + num -= den; + quot += qbit; + } + den >>= 1; + qbit >>= 1; + } + + if ( rem_p ) + *rem_p = num; + + return quot; +} diff --git a/klibc/klibc/libgcc/__udivmodsi4.c b/klibc/klibc/libgcc/__udivmodsi4.c new file mode 100644 index 0000000000..61f6bef0a4 --- /dev/null +++ b/klibc/klibc/libgcc/__udivmodsi4.c @@ -0,0 +1,32 @@ +#include +#include + +uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem_p) +{ + uint32_t quot = 0, qbit = 1; + + if ( den == 0 ) { + __divide_error(); + return 0; /* If trap returns... */ + } + + /* Left-justify denominator and count shift */ + while ( (int32_t)den >= 0 ) { + den <<= 1; + qbit <<= 1; + } + + while ( qbit ) { + if ( den <= num ) { + num -= den; + quot += qbit; + } + den >>= 1; + qbit >>= 1; + } + + if ( rem_p ) + *rem_p = num; + + return quot; +} diff --git a/klibc/klibc/libgcc/__udivsi3.c b/klibc/klibc/libgcc/__udivsi3.c new file mode 100644 index 0000000000..cba6f8f03d --- /dev/null +++ b/klibc/klibc/libgcc/__udivsi3.c @@ -0,0 +1,13 @@ +/* + * libgcc/__divsi3.c + */ + +#include +#include + +extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); + +uint32_t __udivsi3(uint32_t num, uint32_t den) +{ + return __udivmodsi4(num, den, NULL); +} diff --git a/klibc/klibc/libgcc/__umoddi3.c b/klibc/klibc/libgcc/__umoddi3.c new file mode 100644 index 0000000000..c007d4859f --- /dev/null +++ b/klibc/klibc/libgcc/__umoddi3.c @@ -0,0 +1,16 @@ +/* + * arch/i386/libgcc/__umoddi3.c + */ + +#include +#include + +extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); + +uint64_t __umoddi3(uint64_t num, uint64_t den) +{ + uint64_t v; + + (void) __udivmoddi4(num, den, &v); + return v; +} diff --git a/klibc/klibc/libgcc/__umodsi3.c b/klibc/klibc/libgcc/__umodsi3.c new file mode 100644 index 0000000000..e3db972c4e --- /dev/null +++ b/klibc/klibc/libgcc/__umodsi3.c @@ -0,0 +1,16 @@ +/* + * libgcc/__umodsi3.c + */ + +#include +#include + +extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); + +uint32_t __umodsi3(uint32_t num, uint32_t den) +{ + uint32_t v; + + (void) __udivmodsi4(num, den, &v); + return v; +} diff --git a/klibc/klibc/llseek.c b/klibc/klibc/llseek.c new file mode 100644 index 0000000000..fdffc16e2c --- /dev/null +++ b/klibc/klibc/llseek.c @@ -0,0 +1,34 @@ +/* + * llseek.c + * + * On 32-bit platforms, we need llseek() as well as lseek() to be + * able to handle large disks + */ + +#include +#include + +#if BITSIZE == 32 + +static inline _syscall5(int, _llseek, int, fd, unsigned long, hi, unsigned long, lo, loff_t *,res, int, whence); + +loff_t llseek(int fd, loff_t offset, int whence) +{ + loff_t result; + int rv; + + rv = _llseek(fd, (unsigned long)(offset >> 32), + (unsigned long)offset, &result, whence); + + return rv ? (loff_t)-1 : result; +} + +#else + +loff_t llseek(int fd, loff_t offset, int whence) +{ + return lseek(fd, offset, whence); +} + +#endif + diff --git a/klibc/klibc/lrand48.c b/klibc/klibc/lrand48.c new file mode 100644 index 0000000000..4d05de2e89 --- /dev/null +++ b/klibc/klibc/lrand48.c @@ -0,0 +1,42 @@ +/* + * lrand48.c + */ + +#include +#include + +unsigned short __rand48_seed[3]; + +long jrand48(unsigned short xsubi[3]) +{ + uint64_t x; + + /* The xsubi[] array is littleendian by spec */ + x = (uint64_t)xsubi[0] + + ((uint64_t)xsubi[1] << 16) + + ((uint64_t)xsubi[2] << 32); + + x = (0x5deece66dULL * x) + 0xb; + + xsubi[0] = (unsigned short)x; + xsubi[1] = (unsigned short)(x >> 16); + xsubi[2] = (unsigned short)(x >> 32); + + return (long)(int32_t)(x >> 16); +} + +long mrand48(void) +{ + return jrand48(__rand48_seed); +} + +long nrand48(unsigned short xsubi[3]) +{ + return (long)((uint32_t)jrand48(xsubi) >> 1); +} + +long lrand48(void) +{ + return (long)((uint32_t)(mrand48() >> 1)); +} + diff --git a/klibc/klibc/makeerrlist.pl b/klibc/klibc/makeerrlist.pl new file mode 100644 index 0000000000..121ed1f46b --- /dev/null +++ b/klibc/klibc/makeerrlist.pl @@ -0,0 +1,80 @@ +#!/usr/bin/perl +# +# This creates sys_errlist from through somewhat +# heuristic matching. It presumes the relevant entries are of the form +# #define Exxxx /* comment */ +# + +use FileHandle; + +%errors = (); +%errmsg = (); +$maxerr = -1; +$rootdir = 'linux/include/'; # Must have trailing / + +sub parse_file($) { + my($file) = @_; + my($fh) = new FileHandle; + my($line, $error, $msg); + my($kernelonly) = 0; + + $file = $rootdir.$file; + + print STDERR "opening $file\n"; + + if ( !($fh->open("< ".$file)) ) { + die "$0: cannot open $file\n"; + } + + while ( defined($line = <$fh>) ) { + if ( $kernelonly ) { + if ( $line =~ /^\#\s*endif/ ) { + $kernelonly--; + } elsif ( $line =~ /^\#\sif/ ) { + $kernelonly++; + } + } else { + if ( $line =~ /^\#\s*define\s+([A-Z0-9_]+)\s+([0-9]+)\s*\/\*\s*(.*\S)\s*\*\// ) { + $error = $1; + $errno = $2+0; + $msg = $3; + print STDERR "$error ($errno) => \"$msg\"\n"; + $errors{$errno} = $error; + $errmsg{$errno} = $msg; + $maxerr = $errno if ( $errno > $maxerr ); + } elsif ( $line =~ /^\#\s*include\s+[\<\"](.*)[\>\"]/ ) { + parse_file($1); + } elsif ( $line =~ /^\#\s*ifdef\s+__KERNEL__/ ) { + $kernelonly++; + } + } + } + close($fh); + print STDERR "closing $file\n"; +} + +parse_file('linux/errno.h'); + +($type) = @ARGV; + +if ( $type eq '-errlist' ) { + print "#include \n"; + printf "const int sys_nerr = %d;\n", $maxerr+1; + printf "const char * const sys_errlist[%d] = {\n", $maxerr+1; + foreach $e ( sort(keys(%errors)) ) { + printf " [%s] = \"%s\",\n", $errors{$e}, $errmsg{$e}; + } + print "};\n"; +} elsif ( $type eq '-errnos' ) { + print "#include \n"; + printf "const int sys_nerr = %d;\n", $maxerr+1; + printf "const char * const sys_errlist[%d] = {\n", $maxerr+1; + foreach $e ( sort(keys(%errors)) ) { + printf " [%s] = \"%s\",\n", $errors{$e}, $errors{$e}; + } + print "};\n"; +} elsif ( $type eq '-maxerr' ) { + print $maxerr, "\n"; +} + + diff --git a/klibc/klibc/malloc.c b/klibc/klibc/malloc.c new file mode 100644 index 0000000000..20a2350d71 --- /dev/null +++ b/klibc/klibc/malloc.c @@ -0,0 +1,192 @@ +/* + * malloc.c + * + * Very simple linked-list based malloc()/free(). + */ + +#include +#include +#include "malloc.h" + +struct free_arena_header __malloc_head = +{ + { + ARENA_TYPE_HEAD, + 0, + &__malloc_head, + &__malloc_head, + }, + &__malloc_head, + &__malloc_head +}; + +static void *__malloc_from_block(struct free_arena_header *fp, size_t size) +{ + size_t fsize; + struct free_arena_header *nfp, *na; + + fsize = fp->a.size; + + /* We need the 2* to account for the larger requirements of a free block */ + if ( fsize >= size+2*sizeof(struct arena_header) ) { + /* Bigger block than required -- split block */ + nfp = (struct free_arena_header *)((char *)fp + size); + na = fp->a.next; + + nfp->a.type = ARENA_TYPE_FREE; + nfp->a.size = fsize-size; + fp->a.type = ARENA_TYPE_USED; + fp->a.size = size; + + /* Insert into all-block chain */ + nfp->a.prev = fp; + nfp->a.next = na; + na->a.prev = nfp; + fp->a.next = nfp; + + /* Replace current block on free chain */ + nfp->next_free = fp->next_free; + nfp->prev_free = fp->prev_free; + fp->next_free->prev_free = nfp; + fp->prev_free->next_free = nfp; + } else { + /* Allocate the whole block */ + fp->a.type = ARENA_TYPE_USED; + + /* Remove from free chain */ + fp->next_free->prev_free = fp->prev_free; + fp->prev_free->next_free = fp->next_free; + } + + return (void *)(&fp->a + 1); +} + +static struct free_arena_header * +__free_block(struct free_arena_header *ah) +{ + struct free_arena_header *pah, *nah; + + pah = ah->a.prev; + nah = ah->a.next; + if ( pah->a.type == ARENA_TYPE_FREE && + (char *)pah+pah->a.size == (char *)ah ) { + /* Coalesce into the previous block */ + pah->a.size += ah->a.size; + pah->a.next = nah; + nah->a.prev = pah; + +#ifdef DEBUG_MALLOC + ah->a.type = ARENA_TYPE_DEAD; +#endif + + ah = pah; + pah = ah->a.prev; + } else { + /* Need to add this block to the free chain */ + ah->a.type = ARENA_TYPE_FREE; + + ah->next_free = __malloc_head.next_free; + ah->prev_free = &__malloc_head; + __malloc_head.next_free = ah; + ah->next_free->prev_free = ah; + } + + /* In either of the previous cases, we might be able to merge + with the subsequent block... */ + if ( nah->a.type == ARENA_TYPE_FREE && + (char *)ah+ah->a.size == (char *)nah ) { + ah->a.size += nah->a.size; + + /* Remove the old block from the chains */ + nah->next_free->prev_free = nah->prev_free; + nah->prev_free->next_free = nah->next_free; + ah->a.next = nah->a.next; + nah->a.next->a.prev = ah; + +#ifdef DEBUG_MALLOC + nah->a.type = ARENA_TYPE_DEAD; +#endif + } + + /* Return the block that contains the called block */ + return ah; +} + +void *malloc(size_t size) +{ + struct free_arena_header *fp; + struct free_arena_header *pah; + size_t fsize; + + if ( size == 0 ) + return NULL; + + /* Add the obligatory arena header, and round up */ + size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK; + + for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ; + fp = fp->next_free ) { + if ( fp->a.size >= size ) { + /* Found fit -- allocate out of this block */ + return __malloc_from_block(fp, size); + } + } + + /* Nothing found... need to request a block from the kernel */ + fsize = (size+MALLOC_CHUNK_MASK) & ~MALLOC_CHUNK_MASK; + fp = (struct free_arena_header *) + mmap(NULL, fsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); + + if ( fp == (struct free_arena_header *)MAP_FAILED ) { + return NULL; /* Failed to get a block */ + } + + /* Insert the block into the management chains. We need to set + up the size and the main block list pointer, the rest of + the work is logically identical to free(). */ + fp->a.type = ARENA_TYPE_FREE; + fp->a.size = fsize; + + /* We need to insert this into the main block list in the proper + place -- this list is required to be sorted. Since we most likely + get memory assignments in ascending order, search backwards for + the proper place. */ + for ( pah = __malloc_head.a.prev ; pah->a.type != ARENA_TYPE_HEAD ; + pah = pah->a.prev ) { + if ( pah < fp ) + break; + } + + /* Now pah points to the node that should be the predecessor of + the new node */ + fp->a.next = pah->a.next; + fp->a.prev = pah; + pah->a.next = fp; + fp->a.next->a.prev = fp; + + + /* Insert into the free chain and coalesce with adjacent blocks */ + fp = __free_block(fp); + + /* Now we can allocate from this block */ + return __malloc_from_block(fp, size); +} + +void free(void *ptr) +{ + struct free_arena_header *ah; + + if ( !ptr ) + return; + + ah = (struct free_arena_header *) + ((struct arena_header *)ptr - 1); + +#ifdef DEBUG_MALLOC + assert( ah->a.type == ARENA_TYPE_USED ); +#endif + + __free_block(ah); + + /* Here we could insert code to return memory to the system. */ +} diff --git a/klibc/klibc/malloc.h b/klibc/klibc/malloc.h new file mode 100644 index 0000000000..e053f71401 --- /dev/null +++ b/klibc/klibc/malloc.h @@ -0,0 +1,51 @@ +/* + * malloc.h + * + * Internals for the memory allocator + */ + +#include +#include + +/* + * This is the minimum chunk size we will ask the kernel for; this should + * be a multiple of the page size on all architectures. + */ +#define MALLOC_CHUNK_SIZE 65536 +#define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) + +/* + * This structure should be a power of two. This becomes the + * alignment unit. + */ +struct free_arena_header; + +struct arena_header { + size_t type; + size_t size; /* Also gives the location of the next entry */ + struct free_arena_header *next, *prev; +}; + +#ifdef DEBUG_MALLOC +#define ARENA_TYPE_USED 0x64e69c70 +#define ARENA_TYPE_FREE 0x012d610a +#define ARENA_TYPE_HEAD 0x971676b5 +#define ARENA_TYPE_DEAD 0xeeeeeeee +#else +#define ARENA_TYPE_USED 0 +#define ARENA_TYPE_FREE 1 +#define ARENA_TYPE_HEAD 2 +#endif + +#define ARENA_SIZE_MASK (~(sizeof(struct arena_header)-1)) + +/* + * This structure should be no more than twice the size of the + * previous structure. + */ +struct free_arena_header { + struct arena_header a; + struct free_arena_header *next_free, *prev_free; +}; + +extern struct free_arena_header __malloc_head; diff --git a/klibc/klibc/memccpy.c b/klibc/klibc/memccpy.c new file mode 100644 index 0000000000..22f68deaad --- /dev/null +++ b/klibc/klibc/memccpy.c @@ -0,0 +1,23 @@ +/* + * memccpy.c + * + * memccpy() + */ + +#include +#include + +void *memccpy(void *dst, const void *src, int c, size_t n) +{ + char *q = dst; + const char *p = src; + char ch; + + while ( n-- ) { + *q++ = ch = *p++; + if ( ch == (char)c ) + return q; + } + + return NULL; /* No instance of "c" found */ +} diff --git a/klibc/klibc/memchr.c b/klibc/klibc/memchr.c new file mode 100644 index 0000000000..c5c5fa2963 --- /dev/null +++ b/klibc/klibc/memchr.c @@ -0,0 +1,18 @@ +/* + * memchr.c + */ + +#include +#include + +void *memchr(const void *s, int c, size_t n) +{ + const unsigned char *sp = s; + + while ( n-- ) { + if ( *sp == (unsigned char)c ) + return (void *)sp; + } + + return NULL; +} diff --git a/klibc/klibc/memcmp.c b/klibc/klibc/memcmp.c new file mode 100644 index 0000000000..f6bc17286f --- /dev/null +++ b/klibc/klibc/memcmp.c @@ -0,0 +1,19 @@ +/* + * memcmp.c + */ + +#include + +int memcmp(const void *s1, const void *s2, size_t n) +{ + const unsigned char *c1 = s1, *c2 = s2; + int d = 0; + + while ( n-- ) { + d = (int)*c1++ - (int)*c2++; + if ( d ) + break; + } + + return d; +} diff --git a/klibc/klibc/memcpy.c b/klibc/klibc/memcpy.c new file mode 100644 index 0000000000..b9171c300d --- /dev/null +++ b/klibc/klibc/memcpy.c @@ -0,0 +1,29 @@ +/* + * memcpy.c + */ + +#include +#include + +void *memcpy(void *dst, const void *src, size_t n) +{ + const char *p = src; + char *q = dst; +#if defined(__i386__) + size_t nl = n >> 2; + asm volatile("cld ; rep ; movsl ; movl %3,%0 ; rep ; movsb" + : "+c" (nl), "+S" (p), "+D" (q) + : "r" (n & 3)); +#elif defined(__x86_64__) + size_t nq = n >> 3; + asm volatile("cld ; rep ; movsq ; movl %3,%%ecx ; rep ; movsb" + : "+c" (nq), "+S" (p), "+D" (q) + : "r" ((uint32_t)(n & 7))); +#else + while ( n-- ) { + *q++ = *p++; + } +#endif + + return dst; +} diff --git a/klibc/klibc/memmem.c b/klibc/klibc/memmem.c new file mode 100644 index 0000000000..0f59938ffb --- /dev/null +++ b/klibc/klibc/memmem.c @@ -0,0 +1,44 @@ +/* + * memmem.c + * + * Find a byte string inside a longer byte string + * + * This uses the "Not So Naive" algorithm, a very simple but + * usually effective algorithm, see: + * + * http://www-igm.univ-mlv.fr/~lecroq/string/ + */ + +#include + +void *memmem(const void *haystack, size_t n, const void *needle, size_t m) +{ + const unsigned char *y = (const unsigned char *)haystack; + const unsigned char *x = (const unsigned char *)needle; + + size_t j, k, l; + + if ( m > n ) + return NULL; + + if ( x[0] == x[1] ) { + k = 2; + l = 1; + } else { + k = 1; + l = 2; + } + + j = 0; + while ( j <= n-m ) { + if (x[1] != y[j+1]) { + j += k; + } else { + if ( !memcmp(x+2, y+j+2, m-2) && x[0] == y[j] ) + return (void *)&y[j]; + j += l; + } + } + + return NULL; +} diff --git a/klibc/klibc/memmove.c b/klibc/klibc/memmove.c new file mode 100644 index 0000000000..c1f042af39 --- /dev/null +++ b/klibc/klibc/memmove.c @@ -0,0 +1,34 @@ +/* + * memmove.c + */ + +#include + +void *memmove(void *dst, const void *src, size_t n) +{ + const char *p = src; + char *q = dst; +#if defined(__i386__) || defined(__x86_64__) + if ( q < p ) { + asm volatile("cld ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q)); + } else { + p += (n-1); + q += (n-1); + asm volatile("std ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q)); + } +#else + if ( q < p ) { + while ( n-- ) { + *q++ = *p++; + } + } else { + p += n; + q += n; + while ( n-- ) { + *--q = *--p; + } + } +#endif + + return dst; +} diff --git a/klibc/klibc/memset.c b/klibc/klibc/memset.c new file mode 100644 index 0000000000..522cc59a1e --- /dev/null +++ b/klibc/klibc/memset.c @@ -0,0 +1,30 @@ +/* + * memset.c + */ + +#include +#include + +void *memset(void *dst, int c, size_t n) +{ + char *q = dst; + +#if defined(__i386__) + size_t nl = n >> 2; + asm volatile("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb" + : "+c" (nl), "+D" (q) + : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3)); +#elif defined(__x86_64__) + size_t nq = n >> 3; + asm volatile("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb" + : "+c" (nq), "+D" (q) + : "a" ((unsigned char)c * 0x0101010101010101U), + "r" ((uint32_t)n & 7)); +#else + while ( n-- ) { + *q++ = c; + } +#endif + + return dst; +} diff --git a/klibc/klibc/memswap.c b/klibc/klibc/memswap.c new file mode 100644 index 0000000000..10440e3499 --- /dev/null +++ b/klibc/klibc/memswap.c @@ -0,0 +1,23 @@ +/* + * memswap() + * + * Swaps the contents of two nonoverlapping memory areas. + * This really could be done faster... + */ + +#include + +void memswap(void *m1, void *m2, size_t n) +{ + char *p = m1; + char *q = m2; + char tmp; + + while ( n-- ) { + tmp = *p; + *p = *q; + *q = tmp; + + p++; q++; + } +} diff --git a/klibc/klibc/mmap.c b/klibc/klibc/mmap.c new file mode 100644 index 0000000000..3d28cba601 --- /dev/null +++ b/klibc/klibc/mmap.c @@ -0,0 +1,51 @@ +/* + * mmap.c + */ + +#include +#include +#include +#include +#include /* For PAGE_SHIFT */ + +#if defined(__sparc__) +# define MMAP2_SHIFT 12 /* Fixed by syscall definition */ +#else +# define MMAP2_SHIFT PAGE_SHIFT +#endif +#define MMAP2_MASK ((1UL << MMAP2_SHIFT)-1) + +/* + * Prefer mmap2() over mmap(), except on the architectures listed + */ + +#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__) + +/* This architecture uses mmap2() */ + +static inline _syscall6(void *,mmap2,void *,start,size_t,length,int,prot,int,flags,int,fd,off_t,offset); + +/* The Linux mmap2() system call takes a page offset as the offset argument. + We need to make sure we have the proper conversion in place. */ + +void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) +{ + if ( offset & MMAP2_MASK ) { + errno = EINVAL; + return MAP_FAILED; + } + + return mmap2(start, length, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT); +} + +#else + +/* This architecture uses a plain mmap() system call */ +/* Only use this for architectures where mmap() is a real 6-argument system call! */ + +_syscall6(void *,mmap,void *,start,size_t,length,int,prot,int,flags,int,fd,off_t,offset) + +#endif + + + diff --git a/klibc/klibc/nice.c b/klibc/klibc/nice.c new file mode 100644 index 0000000000..f0d97a3cd0 --- /dev/null +++ b/klibc/klibc/nice.c @@ -0,0 +1,22 @@ +/* + * nice.c + */ + +#include +#include +#include +#include + +#ifdef __NR_nice + +_syscall1(int,nice,int,inc); + +#else + +int nice(int inc) +{ + pid_t me = getpid(); + return setpriority(me, PRIO_PROCESS, getpriority(me, PRIO_PROCESS)+inc); +} + +#endif diff --git a/klibc/klibc/onexit.c b/klibc/klibc/onexit.c new file mode 100644 index 0000000000..70a9c01f61 --- /dev/null +++ b/klibc/klibc/onexit.c @@ -0,0 +1,39 @@ +/* + * onexit.c + */ + +#include +#include +#include "atexit.h" + +extern __noreturn (*__exit_handler)(int); +static struct atexit *__atexit_list; + +static __noreturn on_exit_exit(int rv) +{ + struct atexit *ap; + + for ( ap = __atexit_list ; ap ; ap = ap->next ) { + ap->fctn(rv, ap->arg); /* This assumes extra args are harmless */ + } + + _exit(rv); +} + +int on_exit(void (*fctn)(int, void *), void *arg) +{ + struct atexit *as = malloc(sizeof(struct atexit)); + + if ( !as ) + return -1; + + as->fctn = fctn; + as->arg = arg; + + as->next = __atexit_list; + __atexit_list = as; + + __exit_handler = on_exit_exit; + + return 0; +} diff --git a/klibc/klibc/pause.c b/klibc/klibc/pause.c new file mode 100644 index 0000000000..5748728472 --- /dev/null +++ b/klibc/klibc/pause.c @@ -0,0 +1,21 @@ +/* + * pause.c + */ + +#include +#include +#include +#include + +#ifdef __NR_pause + +_syscall0(int,pause); + +#else + +int pause(void) +{ + return select(0,NULL,NULL,NULL,NULL); +} + +#endif diff --git a/klibc/klibc/perror.c b/klibc/klibc/perror.c new file mode 100644 index 0000000000..45585cd577 --- /dev/null +++ b/klibc/klibc/perror.c @@ -0,0 +1,12 @@ +/* + * perror.c + */ + +#include +#include +#include + +void perror(const char *s) +{ + fprintf(stderr, "%s: error %d\n", s, errno); +} diff --git a/klibc/klibc/printf.c b/klibc/klibc/printf.c new file mode 100644 index 0000000000..34237592d6 --- /dev/null +++ b/klibc/klibc/printf.c @@ -0,0 +1,19 @@ +/* + * printf.c + */ + +#include +#include + +#define BUFFER_SIZE 16384 + +int printf(const char *format, ...) +{ + va_list ap; + int rv; + + va_start(ap, format); + rv = vfprintf(stdout, format, ap); + va_end(ap); + return rv; +} diff --git a/klibc/klibc/pty.c b/klibc/klibc/pty.c new file mode 100644 index 0000000000..5907ca2ff5 --- /dev/null +++ b/klibc/klibc/pty.c @@ -0,0 +1,31 @@ +/* + * pty.c + * + * Basic Unix98 PTY functionality; assumes devpts + */ + +#include +#include +#include +#include +#include + +char *ptsname(int fd) +{ + static char buffer[32]; /* Big enough to hold even a 64-bit pts no */ + unsigned int ptyno; + + if ( ioctl(fd, TIOCGPTN, &ptyno) ) + return NULL; + + snprintf(buffer, sizeof buffer, "/dev/pts/%u", ptyno); + + return buffer; +} + +int unlockpt(int fd) +{ + int unlock = 0; + + return ioctl(fd, TIOCSPTLCK, &unlock); +} diff --git a/klibc/klibc/puts.c b/klibc/klibc/puts.c new file mode 100644 index 0000000000..ecebf275da --- /dev/null +++ b/klibc/klibc/puts.c @@ -0,0 +1,13 @@ +/* + * puts.c + */ + +#include + +int puts(const char *s) +{ + if ( fputs(s, stdout) < 0 ) + return -1; + + return _fwrite("\n", 1, stdout); +} diff --git a/klibc/klibc/qsort.c b/klibc/klibc/qsort.c new file mode 100644 index 0000000000..e2197ea2ae --- /dev/null +++ b/klibc/klibc/qsort.c @@ -0,0 +1,42 @@ +/* + * qsort.c + * + * This is actually combsort. It's an O(n log n) algorithm with + * simplicity/small code size being its main virtue. + */ + +#include +#include + +static inline size_t newgap(size_t gap) +{ + gap = (gap*10)/13; + if ( gap == 9 || gap == 10 ) + gap = 11; + + if ( gap < 1 ) + gap = 1; + return gap; +} + +void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) +{ + size_t gap = nmemb; + size_t i, j; + void *p1, *p2; + int swapped; + + do { + gap = newgap(gap); + swapped = 0; + + for ( i = 0, p1 = base ; i < nmemb-gap ; i++, (char *)p1 += size ) { + j = i+gap; + if ( compar(p1, p2 = (char *)base+j*size) > 0 ) { + memswap(p1, p2, size); + swapped = 1; + } + } + } while ( gap > 1 || swapped ); +} + diff --git a/klibc/klibc/raise.c b/klibc/klibc/raise.c new file mode 100644 index 0000000000..dcbb9c9c6c --- /dev/null +++ b/klibc/klibc/raise.c @@ -0,0 +1,11 @@ +/* + * raise.c + */ + +#include +#include + +int raise(int signal) +{ + return kill(getpid(), signal); +} diff --git a/klibc/klibc/readdir.c b/klibc/klibc/readdir.c new file mode 100644 index 0000000000..bb216a1951 --- /dev/null +++ b/klibc/klibc/readdir.c @@ -0,0 +1,66 @@ +/* + * opendir/readdir/closedir + */ + +#include +#include +#include +#include +#include + +#define __IO_DIR_DEFINED +struct _IO_dir { + int fd; + size_t bytes_left; + struct dirent *next; + struct dirent buffer[15]; /* 15 times max dirent size =~ 4K */ +}; + +#include + +DIR *opendir(const char *name) +{ + DIR *dp = malloc(sizeof(DIR)); + + if ( !dp ) + return NULL; + + dp->fd = open(name, O_DIRECTORY|O_RDONLY); + + if ( dp->fd < 0 ) { + free(dp); + return NULL; + } + + dp->bytes_left = 0; + + return dp; +} + +struct dirent *readdir(DIR *dir) +{ + struct dirent *dent; + int rv; + + if ( !dir->bytes_left ) { + rv = getdents(dir->fd, dir->buffer, sizeof(dir->buffer)); + if ( rv <= 0 ) + return NULL; + dir->bytes_left = rv; + dir->next = dir->buffer; + } + + dent = dir->next; + ((char *)dir->next) += dent->d_reclen; + dir->bytes_left -= dent->d_reclen; + + return dent; +} + +int closedir(DIR *dir) +{ + int rv; + rv = close(dir->fd); + free(dir); + return rv; +} diff --git a/klibc/klibc/realloc.c b/klibc/klibc/realloc.c new file mode 100644 index 0000000000..577c2001a5 --- /dev/null +++ b/klibc/klibc/realloc.c @@ -0,0 +1,49 @@ +/* + * realloc.c + */ + +#include +#include + +#include "malloc.h" + +/* FIXME: This is cheesy, it should be fixed later */ + +void *realloc(void *ptr, size_t size) +{ + struct free_arena_header *ah; + void *newptr; + size_t oldsize; + + if ( !ptr ) + return malloc(size); + + if ( size == 0 ) { + free(ptr); + return NULL; + } + + /* Add the obligatory arena header, and round up */ + size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK; + + ah = (struct free_arena_header *) + ((struct arena_header *)ptr - 1); + + if ( ah->a.size >= size && size >= (ah->a.size >> 2) ) { + /* This field is a good size already. */ + return ptr; + } else { + /* Make me a new block. This is kind of bogus; we should + be checking the adjacent blocks to see if we can do an + in-place adjustment... fix that later. */ + + oldsize = ah->a.size - sizeof(struct arena_header); + + newptr = malloc(size); + memcpy(newptr, ptr, (size < oldsize) ? size : oldsize); + free(ptr); + + return newptr; + } +} + diff --git a/klibc/klibc/reboot.c b/klibc/klibc/reboot.c new file mode 100644 index 0000000000..772c85910e --- /dev/null +++ b/klibc/klibc/reboot.c @@ -0,0 +1,15 @@ +/* + * reboot.c + */ + +#include +#include +#include + +/* This provides the one-argument glibc-ish version of reboot. + The full four-argument system call is available as __reboot(). */ + +int reboot(int flag) +{ + return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, flag, NULL); +} diff --git a/klibc/klibc/recv.c b/klibc/klibc/recv.c new file mode 100644 index 0000000000..4d30610cee --- /dev/null +++ b/klibc/klibc/recv.c @@ -0,0 +1,11 @@ +/* + * recv.c + */ + +#include +#include + +int recv(int s, void *buf, size_t len, unsigned int flags) +{ + return recvfrom(s, buf, len, flags, NULL, 0); +} diff --git a/klibc/klibc/sbrk.c b/klibc/klibc/sbrk.c new file mode 100644 index 0000000000..03ab3c14bb --- /dev/null +++ b/klibc/klibc/sbrk.c @@ -0,0 +1,23 @@ +/* sbrk.c - Change data segment size */ + +/* Written 2000 by Werner Almesberger */ + +#include +#include +#include + +char *__current_brk; /* Common with brk.c */ + +void *sbrk(ptrdiff_t increment) +{ + char *old_brk, *new_brk; + + if (!__current_brk) + __current_brk = __brk(NULL); + new_brk = __brk(__current_brk+increment); + if (new_brk != __current_brk+increment) + return (void *) -1; + old_brk = __current_brk; + __current_brk = new_brk; + return old_brk; +} diff --git a/klibc/klibc/seed48.c b/klibc/klibc/seed48.c new file mode 100644 index 0000000000..f8353c8715 --- /dev/null +++ b/klibc/klibc/seed48.c @@ -0,0 +1,19 @@ +/* + * seed48.c + */ + +#include +#include +#include + +extern unsigned short __rand48_seed[3]; + +unsigned short *seed48(const unsigned short xsubi[3]) +{ + static unsigned short oldseed[3]; + memcpy(oldseed, __rand48_seed, sizeof __rand48_seed); + memcpy(__rand48_seed, xsubi, sizeof __rand48_seed); + + return oldseed; +} + diff --git a/klibc/klibc/select.c b/klibc/klibc/select.c new file mode 100644 index 0000000000..2404bb1e64 --- /dev/null +++ b/klibc/klibc/select.c @@ -0,0 +1,9 @@ +#include +#include + +#ifdef __NR__newselect +#undef __NR_select +#define __NR_select __NR__newselect +#endif + +_syscall5(int,select,int,a0,fd_set *,a1,fd_set *,a2,fd_set *,a3,struct timeval *,a4); diff --git a/klibc/klibc/send.c b/klibc/klibc/send.c new file mode 100644 index 0000000000..8c53d0f764 --- /dev/null +++ b/klibc/klibc/send.c @@ -0,0 +1,11 @@ +/* + * send.c + */ + +#include +#include + +int send(int s, const void *buf, size_t len, unsigned int flags) +{ + return sendto(s, buf, len, flags, NULL, 0); +} diff --git a/klibc/klibc/setegid.c b/klibc/klibc/setegid.c new file mode 100644 index 0000000000..09f2416e43 --- /dev/null +++ b/klibc/klibc/setegid.c @@ -0,0 +1,10 @@ +/* + * setegid.c + */ + +#include + +int setegid(gid_t egid) +{ + return setregid(-1, egid); +} diff --git a/klibc/klibc/setenv.c b/klibc/klibc/setenv.c new file mode 100644 index 0000000000..d1118ff3ed --- /dev/null +++ b/klibc/klibc/setenv.c @@ -0,0 +1,124 @@ +/* + * setenv.c + */ + +#include +#include +#include +#include + +/* Initialized to zero, meaning "not malloc'd" */ +static size_t __environ_size; + +/* str should be a duplicated version of the input string; + len is the length of the key including the = sign */ +static int _putenv(char *str, size_t len, int overwrite) +{ + char **p, *q; + char **newenv; + size_t n; + + n = 1; /* Include space for final NULL */ + for ( p = environ ; (q = *p) ; p++ ) { + n++; + if ( !strncmp(q,str,len) ) { + if ( overwrite ) + free(str); + else + *p = str; /* Memory leak... */ + return 0; + } + } + + /* Need to extend the environment */ + if ( n < __environ_size ) { + p[1] = NULL; + *p = str; + return 0; + } else { + if ( __environ_size ) { + newenv = realloc(environ, (__environ_size << 1)*sizeof(char *)); + if ( !newenv ) + return -1; + + __environ_size <<= 1; + } else { + /* Make a reasonable guess how much more space we need */ + size_t newsize = n+32; + newenv = malloc(newsize*sizeof(char *)); + if ( !newenv ) + return -1; + + memcpy(newenv, environ, n*sizeof(char *)); + __environ_size = newsize; + } + newenv[n+1] = NULL; + newenv[n] = str; + environ = newenv; + } + return 0; +} + +int putenv(const char *str) +{ + char *s; + const char *e, *z; + size_t len; + + if ( !str ) { + errno = EINVAL; + return -1; + } + + len = 0; e = NULL; + for ( z = str ; *z ; z++ ) { + len++; + if ( *z == '=' ) + e = z; + } + + if ( !e ) { + errno = EINVAL; + return -1; + } + + s = strdup(str); + if ( !s ) + return -1; + + return _putenv(s, len, 1); +} + +int setenv(const char *name, const char *val, int overwrite) +{ + const char *z; + char *s; + size_t l1, l2; + + if ( !name || !name[0] ) { + errno = EINVAL; + return -1; + } + + l1 = 0; + for ( z = name ; *z ; z++ ) { + l1++; + if ( *z == '=' ) { + errno = EINVAL; + return -1; + } + } + + l2 = strlen(val); + + s = malloc(l1+l2+2); + if ( !s ) + return -1; + + memcpy(s, name, l1); + s[l1] = '='; + memcpy(s+l1+1, val, l2); + s[l1+l2+1] = '\0'; + + return _putenv(s, l1+1, overwrite); +} diff --git a/klibc/klibc/seteuid.c b/klibc/klibc/seteuid.c new file mode 100644 index 0000000000..6d1ac3922a --- /dev/null +++ b/klibc/klibc/seteuid.c @@ -0,0 +1,10 @@ +/* + * seteuid.c + */ + +#include + +int seteuid(uid_t euid) +{ + return setreuid(-1, euid); +} diff --git a/klibc/klibc/setpgrp.c b/klibc/klibc/setpgrp.c new file mode 100644 index 0000000000..001dd0435d --- /dev/null +++ b/klibc/klibc/setpgrp.c @@ -0,0 +1,10 @@ +/* + * setpgrp.c + */ + +#include + +int setpgrp(void) +{ + return setpgid(0,0); +} diff --git a/klibc/klibc/setresgid.c b/klibc/klibc/setresgid.c new file mode 100644 index 0000000000..f1a8c6b45c --- /dev/null +++ b/klibc/klibc/setresgid.c @@ -0,0 +1,29 @@ +/* + * setresgid.c + */ + +#include +#include + +#ifdef __NR_setresgid + +_syscall3(int,setresgid,gid_t,a0,gid_t,a1,gid_t,a2); + +#elif defined(__NR_setresgid32) + +static inline _syscall3(int,setresgid32,gid_t,a0,gid_t,a1,gid_t,a2); + +int setresgid(gid_t a0, gid_t a1, gid_t a2) +{ + if ( sizeof(gid_t) == sizeof(uint32_t) ) { + return setresgid32(a0,a1,a2); + } else { + uint32_t x0 = (a0 == (gid_t)-1) ? (uint32_t)-1 : a0; + uint32_t x1 = (a1 == (gid_t)-1) ? (uint32_t)-1 : a1; + uint32_t x2 = (a2 == (gid_t)-1) ? (uint32_t)-1 : a2; + + return setresgid32(x0,x1,x2); + } +} + +#endif diff --git a/klibc/klibc/setresuid.c b/klibc/klibc/setresuid.c new file mode 100644 index 0000000000..a587acbae3 --- /dev/null +++ b/klibc/klibc/setresuid.c @@ -0,0 +1,30 @@ +/* + * setresuid.c + */ + +#include +#include + +#ifdef __NR_setresuid + +_syscall3(int,setresuid,uid_t,a0,uid_t,a1,uid_t,a2); + +#elif defined(__NR_setresuid32) + +static inline _syscall3(int,setresuid32,uid_t,a0,uid_t,a1,uid_t,a2); + +int setresuid(uid_t a0, uid_t a1, uid_t a2) +{ + if ( sizeof(uid_t) == sizeof(uint32_t) ) { + return setresuid32(a0,a1,a2); + } else { + uint32_t x0 = (a0 == (uid_t)-1) ? (uint32_t)-1 : a0; + uint32_t x1 = (a1 == (uid_t)-1) ? (uint32_t)-1 : a1; + uint32_t x2 = (a2 == (uid_t)-1) ? (uint32_t)-1 : a2; + + return setresuid32(x0,x1,x2); + } +} + +#endif + diff --git a/klibc/klibc/sha1hash.c b/klibc/klibc/sha1hash.c new file mode 100644 index 0000000000..600d51248c --- /dev/null +++ b/klibc/klibc/sha1hash.c @@ -0,0 +1,317 @@ +/* +SHA-1 in C +By Steve Reid +100% Public Domain + +----------------- +Modified 7/98 +By James H. Brown +Still 100% Public Domain + +Corrected a problem which generated improper hash values on 16 bit machines +Routine SHA1Update changed from + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int +len) +to + void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned +long len) + +The 'len' parameter was declared an int which works fine on 32 bit machines. +However, on 16 bit machines an int is too small for the shifts being done +against +it. This caused the hash function to generate incorrect values if len was +greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). + +Since the file IO in main() reads 16K at a time, any file 8K or larger would +be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million +"a"s). + +I also changed the declaration of variables i & j in SHA1Update to +unsigned long from unsigned int for the same reason. + +These changes should make no difference to any 32 bit implementations since +an +int and a long are the same size in those environments. + +-- +I also corrected a few compiler warnings generated by Borland C. +1. Added #include for exit() prototype +2. Removed unused variable 'j' in SHA1Final +3. Changed exit(0) to return(0) at end of main. + +ALL changes I made can be located by searching for comments containing 'JHB' +----------------- +Modified 8/98 +By Steve Reid +Still 100% public domain + +1- Removed #include and used return() instead of exit() +2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) +3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net + +----------------- +Modified 4/01 +By Saul Kravitz +Still 100% PD +Modified to run on Compaq Alpha hardware. + +----------------- +Modified 2/03 +By H. Peter Anvin +Still 100% PD +Modified to run on any hardware with and +Changed the driver program + +*/ + +/* +Test Vectors (from FIPS PUB 180-1) +"abc" + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D +"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 +A million repetitions of "a" + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +/* #define SHA1HANDSOFF */ + +#include +#include +#include +#include /* For htonl/ntohl/htons/ntohs */ + +/* #include */ /* prototype for exit() - JHB */ +/* Using return() instead of exit() - SWR */ + +typedef struct { + uint32_t state[5]; + uint32_t count[2]; + unsigned char buffer[64]; +} SHA1_CTX; + +void SHA1Transform(uint32_t state[5], unsigned char buffer[64]); +void SHA1Init(SHA1_CTX* context); +void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len); /* +JHB */ +void SHA1Final(unsigned char digest[20], SHA1_CTX* context); + +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) + +/* blk0() and blk() perform the initial expand. */ +/* I got the idea of expanding during the round function from SSLeay */ +#define blk0(i) (block->l[i] = ntohl(block->l[i])) +#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ + ^block->l[(i+2)&15]^block->l[i&15],1)) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); +#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); +#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); +#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); + + +#ifdef VERBOSE /* SAK */ +void SHAPrintContext(SHA1_CTX *context, char *msg){ + printf("%s (%d,%d) %x %x %x %x %x\n", + msg, + context->count[0], context->count[1], + context->state[0], + context->state[1], + context->state[2], + context->state[3], + context->state[4]); +} +#endif + +/* Hash a single 512-bit block. This is the core of the algorithm. */ + +void SHA1Transform(uint32_t state[5], unsigned char buffer[64]) +{ +uint32_t a, b, c, d, e; +typedef union { + unsigned char c[64]; + uint32_t l[16]; +} CHAR64LONG16; +CHAR64LONG16* block; +#ifdef SHA1HANDSOFF +static unsigned char workspace[64]; + block = (CHAR64LONG16*)workspace; + memcpy(block, buffer, 64); +#else + block = (CHAR64LONG16*)buffer; +#endif + /* Copy context->state[] to working vars */ + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + /* Wipe variables */ + a = b = c = d = e = 0; +} + + +/* SHA1Init - Initialize new context */ + +void SHA1Init(SHA1_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* Run your data through this. */ + +void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len) /* +JHB */ +{ +uint32_t i, j; /* JHB */ + +#ifdef VERBOSE + SHAPrintContext(context, "before"); +#endif + j = (context->count[0] >> 3) & 63; + if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + context->count[1] += (len >> 29); + if ((j + len) > 63) { + memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) { + SHA1Transform(context->state, &data[i]); + } + j = 0; + } + else i = 0; + memcpy(&context->buffer[j], &data[i], len - i); +#ifdef VERBOSE + SHAPrintContext(context, "after "); +#endif +} + + +/* Add padding and return the message digest. */ + +void SHA1Final(unsigned char digest[20], SHA1_CTX* context) +{ +uint32_t i; /* JHB */ +unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) { + SHA1Update(context, (unsigned char *)"\0", 1); + } + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() +*/ + for (i = 0; i < 20; i++) { + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } + /* Wipe variables */ + i = 0; /* JHB */ + memset(context->buffer, 0, 64); + memset(context->state, 0, 20); + memset(context->count, 0, 8); + memset(finalcount, 0, 8); /* SWR */ +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ + SHA1Transform(context->state, context->buffer); +#endif +} + +/*************************************************************/ + +/* This is not quite the MIME base64 algorithm: it uses _ instead of /, + and instead of padding the output with = characters we just make the + output shorter. */ +char *mybase64(uint8_t digest[20]) +{ + static const char charz[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_"; + uint8_t input[21]; + static char output[28]; + int i, j; + uint8_t *p; + char *q; + uint32_t bv; + + memcpy(input, digest, 20); + input[20] = 0; /* Pad to multiple of 3 bytes */ + + p = input; q = output; + for ( i = 0 ; i < 7 ; i++ ) { + bv = (p[0] << 16) | (p[1] << 8) | p[2]; + p += 3; + for ( j = 0 ; j < 4 ; j++ ) { + *q++ = charz[(bv >> 18) & 0x3f]; + bv <<= 6; + } + } + *--q = '\0'; /* The last character is not significant */ + return output; +} + +int main(int argc, char** argv) +{ + int i, j; + SHA1_CTX context; + uint8_t digest[20], buffer[16384]; + FILE* file; + + if (argc < 2) { + file = stdin; + } + else { + if (!(file = fopen(argv[1], "rb"))) { + fputs("Unable to open file.", stderr); + return(-1); + } + } + SHA1Init(&context); + while (!feof(file)) { /* note: what if ferror(file) */ + i = fread(buffer, 1, 16384, file); + SHA1Update(&context, buffer, i); + } + SHA1Final(digest, &context); + fclose(file); + + puts(mybase64(digest)); + + return 0; +} diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c new file mode 100644 index 0000000000..ebd34710f1 --- /dev/null +++ b/klibc/klibc/sigaction.c @@ -0,0 +1,19 @@ +/* + * sigaction.c + */ + +#include +#include + +#ifdef __NR_sigaction + +_syscall3(int,sigaction,int,sig,const struct sigaction *,act,struct sigaction *,oact); + +#else + +int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +{ + return rt_sigaction(sig, act, oact, sizeof(sigset_t)); +} + +#endif diff --git a/klibc/klibc/siglist.c b/klibc/klibc/siglist.c new file mode 100644 index 0000000000..dce7355079 --- /dev/null +++ b/klibc/klibc/siglist.c @@ -0,0 +1,115 @@ +/* + * siglist.h + * + * Construct the signal list + */ + +#include +#include + +const char * const sys_siglist[NSIG] = { +#ifdef SIGABRT + [SIGABRT] = "Aborted", +#endif +#ifdef SIGALRM + [SIGALRM] = "Alarm clock", +#endif +#ifdef SIGBUS + [SIGBUS] = "Bus error", +#endif +#ifdef SIGCHLD + [SIGCHLD] = "Child exited", +#endif +#if defined(SIGCLD) && (SIGCHLD != SIGCLD) + [SIGCLD] = "Child exited", +#endif +#ifdef SIGEMT + [SIGEMT] = "Emulation trap", +#endif +#ifdef SIGFPE + [SIGFPE] = "Floating point exception", +#endif +#ifdef SIGHUP + [SIGHUP] = "Hangup", +#endif +#ifdef SIGILL + [SIGILL] = "Illegal instruction", +#endif + /* SIGINFO == SIGPWR */ +#ifdef SIGINT + [SIGINT] = "Interrupt", +#endif +#ifdef SIGIO + [SIGIO] = "I/O possible", +#endif +#if defined(SIGIOT) && (SIGIOT != SIGABRT) + [SIGIOT] = "I/O trap", +#endif +#ifdef SIGKILL + [SIGKILL] = "Killed", +#endif +#if defined(SIGLOST) && (SIGLOST != SIGIO) && (SIGLOST != SIGPWR) + [SIGLOST] = "Lock lost", +#endif +#ifdef SIGPIPE + [SIGPIPE] = "Broken pipe", +#endif +#if defined(SIGPOLL) && (SIGPOLL != SIGIO) + [SIGPOLL] = "Pollable event", +#endif +#ifdef SIGPROF + [SIGPROF] = "Profiling timer expired", +#endif +#ifdef SIGPWR + [SIGPWR] = "Power failure", +#endif +#ifdef SIGQUIT + [SIGQUIT] = "Quit", +#endif + /* SIGRESERVE == SIGUNUSED */ +#ifdef SIGSEGV + [SIGSEGV] = "Segment violation", +#endif +#ifdef SIGSTKFLT + [SIGSTKFLT] = "Stack fault", +#endif +#ifdef SIGSTOP + [SIGSTOP] = "Stopped (signal)", +#endif +#ifdef SIGSYS + [SIGSYS] = "Bad system call", +#endif +#ifdef SIGTERM + [SIGTERM] = "Terminated", +#endif +#ifdef SIGTSTP + [SIGTSTP] = "Stopped", +#endif +#ifdef SIGTTIN + [SIGTTIN] = "Stopped (tty input)", +#endif +#ifdef SIGTTOU + [SIGTTOU] = "Stopped (tty output)", +#endif +#ifdef SIGURG + [SIGURG] = "Urgent I/O condition", +#endif +#ifdef SIGUSR1 + [SIGUSR1] = "User signal 1", +#endif +#ifdef SIGUSR2 + [SIGUSR2] = "User signal 2", +#endif +#ifdef SIGVTALRM + [SIGVTALRM] = "Virtual timer expired", +#endif +#ifdef SIGWINCH + [SIGWINCH] = "Window size changed", +#endif +#ifdef SIGXCPU + [SIGXCPU] = "CPU time limit exceeded", +#endif +#ifdef SIGXFSZ + [SIGXFSZ] = "File size limit exceeded", +#endif +}; diff --git a/klibc/klibc/siglongjmp.c b/klibc/klibc/siglongjmp.c new file mode 100644 index 0000000000..2ba1239b6b --- /dev/null +++ b/klibc/klibc/siglongjmp.c @@ -0,0 +1,16 @@ +/* + * siglongjmp.c + * + * sigsetjmp() is a macro, by necessity (it's either that or write + * it in assembly), but siglongjmp() is a normal function. + */ + +#include +#include + +__noreturn siglongjmp(sigjmp_buf buf, int retval) +{ + sigprocmask(SIG_SETMASK, &buf->__sigs, NULL); + longjmp(buf->__jmpbuf, retval); +} + diff --git a/klibc/klibc/signal.c b/klibc/klibc/signal.c new file mode 100644 index 0000000000..982d0c659d --- /dev/null +++ b/klibc/klibc/signal.c @@ -0,0 +1,11 @@ +/* + * signal.c + */ + +#include + +__sighandler_t signal(int signum, __sighandler_t handler) +{ + /* Linux/SysV signal() semantics */ + return __signal(signum, handler, SA_RESETHAND); +} diff --git a/klibc/klibc/sigpending.c b/klibc/klibc/sigpending.c new file mode 100644 index 0000000000..afbcf3cf34 --- /dev/null +++ b/klibc/klibc/sigpending.c @@ -0,0 +1,19 @@ +/* + * sigpending.c + */ + +#include +#include + +#ifdef __NR_sigpending + +_syscall1(int,sigpending,sigset_t *,set); + +#else + +int sigpending(sigset_t *set) +{ + return rt_sigpending(set, sizeof(sigset_t)); +} + +#endif diff --git a/klibc/klibc/sigprocmask.c b/klibc/klibc/sigprocmask.c new file mode 100644 index 0000000000..3a90f67732 --- /dev/null +++ b/klibc/klibc/sigprocmask.c @@ -0,0 +1,19 @@ +/* + * sigprocmask.c + */ + +#include +#include + +#ifdef __NR_sigprocmask + +_syscall3(int,sigprocmask,int,how,const sigset_t *,set,sigset_t *,oset); + +#else + +int sigprocmask(int how, const sigset_t *set, sigset_t *oset) +{ + return rt_sigprocmask(how, set, oset, sizeof(sigset_t)); +} + +#endif diff --git a/klibc/klibc/sigsuspend.c b/klibc/klibc/sigsuspend.c new file mode 100644 index 0000000000..85cdea20ca --- /dev/null +++ b/klibc/klibc/sigsuspend.c @@ -0,0 +1,19 @@ +/* + * sigsuspend.c + */ + +#include +#include + +#ifdef __NR_sigsuspend + +_syscall1(int,sigsuspend,const sigset_t *,mask); + +#else + +int sigsuspend(const sigset_t *mask) +{ + return rt_sigsuspend(mask, sizeof *mask); +} + +#endif diff --git a/klibc/klibc/sleep.c b/klibc/klibc/sleep.c new file mode 100644 index 0000000000..eb3777e8a6 --- /dev/null +++ b/klibc/klibc/sleep.c @@ -0,0 +1,20 @@ +/* + * sleep.c + */ + +#include +#include + +unsigned int sleep(unsigned int seconds) +{ + struct timespec ts; + + ts.tv_sec = seconds; + ts.tv_nsec = 0; + if ( !nanosleep(&ts,&ts) ) + return 0; + else if ( errno == EINTR ) + return ts.tv_sec; + else + return -1; +} diff --git a/klibc/klibc/snprintf.c b/klibc/klibc/snprintf.c new file mode 100644 index 0000000000..c642851b2f --- /dev/null +++ b/klibc/klibc/snprintf.c @@ -0,0 +1,16 @@ +/* + * snprintf.c + */ + +#include + +int snprintf(char *buffer, size_t n, const char *format, ...) +{ + va_list ap; + int rv; + + va_start(ap, format); + rv = vsnprintf(buffer, n, format, ap); + va_end(ap); + return rv; +} diff --git a/klibc/klibc/socketcalls.pl b/klibc/klibc/socketcalls.pl new file mode 100644 index 0000000000..cf4daf6036 --- /dev/null +++ b/klibc/klibc/socketcalls.pl @@ -0,0 +1,71 @@ +#!/usr/bin/perl +($arch, $file) = @ARGV; + +if (!open(FILE, "< $file")) { + print STDERR "$file: $!\n"; + exit(1); +} + +while ( defined($line = ) ) { + chomp $line; + $line =~ s/\s*\#.*$//; # Strip comments and trailing blanks + next unless $line; + + if ( $line =~ /^\s*(.*)\s+([_a-zA-Z][_a-zA-Z0-9]+)\s*\((.*)\)$/ ) { + $type = $1; + $name = $2; + $argv = $3; + + @args = split(/\s*\,\s*/, $argv); + @cargs = (); + + $i = 0; + for $arg ( @args ) { + push(@cargs, "$arg a".$i++); + } + $nargs = $i; + + if ( $arch eq 'i386' ) { + open(OUT, "> socketcalls/${name}.S") + or die "$0: Cannot open socketcalls/${name}.S\n"; + + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.text\n"; + print OUT "\t.align 4\n"; + print OUT "\t.globl ${name}\n"; + print OUT "\t.type ${name},\@function\n"; + print OUT "${name}:\n"; + print OUT "\tmovb \$SYS_\U${name}\E,%al\n"; + print OUT "\tjmp __socketcall_common\n"; + print OUT "\t.size ${name},.-${name}\n"; + } else { + open(OUT, "> socketcalls/${name}.c") + or die "$0: Cannot open socketcalls/${name}.c\n"; + print OUT "#include \"socketcommon.h\"\n\n"; + + print OUT "#ifdef __NR_$name\n\n"; + print OUT "_syscall", scalar(@args), "(", $type, ',', $name; + $i = 0; + foreach $arg ( @args ) { + print OUT ",", $arg, ",a",$i++; + } + print OUT ");\n"; + print OUT "\n#else\n\n"; + + print OUT "$type $name (", join(', ', @cargs), ")\n"; + print OUT "{\n"; + print OUT " unsigned long args[$nargs];\n"; + for ( $i = 0 ; $i < $nargs ; $i++ ) { + print OUT " args[$i] = (unsigned long)a$i;\n"; + } + print OUT " return ($type) socketcall(SYS_\U${name}\E, args);\n"; + print OUT "}\n"; + print OUT "\n#endif\n"; + } + close(OUT); + } else { + print STDERR "$file:$.: Could not parse input\n"; + exit(1); + } +} diff --git a/klibc/klibc/socketcommon.h b/klibc/klibc/socketcommon.h new file mode 100644 index 0000000000..7a5acaadaf --- /dev/null +++ b/klibc/klibc/socketcommon.h @@ -0,0 +1,25 @@ +/* + * socketcommon.h + * + * Common header file for socketcall stubs + */ + +#define __IN_SYS_COMMON +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Some architectures have socketcall(), some have real syscalls, + * and some have both, but the syscall version is always preferred. + * Look for __NR_ to probe for the existence of a syscall. + */ + +#ifdef __NR_socketcall +static inline _syscall2(int,socketcall,int,call,unsigned long *,args); +#endif diff --git a/klibc/klibc/sprintf.c b/klibc/klibc/sprintf.c new file mode 100644 index 0000000000..31f28af005 --- /dev/null +++ b/klibc/klibc/sprintf.c @@ -0,0 +1,18 @@ +/* + * sprintf.c + */ + +#include +#include + +int sprintf(char *buffer, const char *format, ...) +{ + va_list ap; + int rv; + + va_start(ap, format); + rv = vsnprintf(buffer, ~(size_t)0, format, ap); + va_end(ap); + + return rv; +} diff --git a/klibc/klibc/srand48.c b/klibc/klibc/srand48.c new file mode 100644 index 0000000000..a3df16d95c --- /dev/null +++ b/klibc/klibc/srand48.c @@ -0,0 +1,16 @@ +/* + * srand48.c + */ + +#include +#include + +extern unsigned short __rand48_seed[3]; + + +void srand48(long seedval) +{ + __rand48_seed[0] = 0x330e; + __rand48_seed[1] = (unsigned short)seedval; + __rand48_seed[2] = (unsigned short)((uint32_t)seedval >> 16); +} diff --git a/klibc/klibc/sscanf.c b/klibc/klibc/sscanf.c new file mode 100644 index 0000000000..81aab9e05b --- /dev/null +++ b/klibc/klibc/sscanf.c @@ -0,0 +1,17 @@ +/* + * sscanf() + */ + +#include + +int sscanf(const char *str, const char *format, ...) +{ + va_list ap; + int rv; + + va_start(ap, format); + rv = vsscanf(str, format, ap); + va_end(ap); + + return rv; +} diff --git a/klibc/klibc/strcat.c b/klibc/klibc/strcat.c new file mode 100644 index 0000000000..a5f9477866 --- /dev/null +++ b/klibc/klibc/strcat.c @@ -0,0 +1,11 @@ +/* + * strcat.c + */ + +#include + +char *strcat(char *dst, const char *src) +{ + strcpy(strchr(dst, '\0'), src); + return dst; +} diff --git a/klibc/klibc/strchr.c b/klibc/klibc/strchr.c new file mode 100644 index 0000000000..192f83600c --- /dev/null +++ b/klibc/klibc/strchr.c @@ -0,0 +1,16 @@ +/* + * strchr.c + */ + +#include + +char *strchr(const char *s, int c) +{ + while ( *s != (char)c ) { + if ( ! *s ) + return NULL; + s++; + } + + return (char *)s; +} diff --git a/klibc/klibc/strcmp.c b/klibc/klibc/strcmp.c new file mode 100644 index 0000000000..f44774f443 --- /dev/null +++ b/klibc/klibc/strcmp.c @@ -0,0 +1,20 @@ +/* + * strcmp.c + */ + +#include + +int strcmp(const char *s1, const char *s2) +{ + const unsigned char *c1 = s1, *c2 = s2; + unsigned char ch; + int d = 0; + + while ( 1 ) { + d = (int)(ch = *c1++) - (int)*c2++; + if ( d || !ch ) + break; + } + + return d; +} diff --git a/klibc/klibc/strcpy.c b/klibc/klibc/strcpy.c new file mode 100644 index 0000000000..8372eba50b --- /dev/null +++ b/klibc/klibc/strcpy.c @@ -0,0 +1,20 @@ +/* + * strcpy.c + * + * strcpy() + */ + +#include + +char *strcpy(char *dst, const char *src) +{ + char *q = dst; + const char *p = src; + char ch; + + do { + *q++ = ch = *p++; + } while ( ch ); + + return dst; +} diff --git a/klibc/klibc/strdup.c b/klibc/klibc/strdup.c new file mode 100644 index 0000000000..eb170c2645 --- /dev/null +++ b/klibc/klibc/strdup.c @@ -0,0 +1,17 @@ +/* + * strdup.c + */ + +#include +#include + +char *strdup(const char *s) +{ + int l = strlen(s)+1; + char *d = malloc(l); + + if ( d ) + memcpy(d, s, l); + + return d; +} diff --git a/klibc/klibc/strerror.c b/klibc/klibc/strerror.c new file mode 100644 index 0000000000..754a30693c --- /dev/null +++ b/klibc/klibc/strerror.c @@ -0,0 +1,25 @@ +/* + * strerror.c + */ + +#include + +char *strerror(int errnum) +{ + static char message[32] = "error "; /* enough for error 2^63-1 */ + + char numbuf[32]; + char *p; + int len; + + p = numbuf+sizeof numbuf; + *--p = '\0'; + + do { + *--p = (errnum % 10) + '0'; + errnum /= 10; + } while ( errnum ); + + return (char *)memcpy(message+6, p, (numbuf+sizeof numbuf)-p); +} + diff --git a/klibc/klibc/strlen.c b/klibc/klibc/strlen.c new file mode 100644 index 0000000000..4d773f9a05 --- /dev/null +++ b/klibc/klibc/strlen.c @@ -0,0 +1,14 @@ +/* + * strlen() + */ + +#include + +size_t strlen(const char *s) +{ + const char *ss = s; + while ( *ss ) + ss++; + return ss-s; +} + diff --git a/klibc/klibc/strncat.c b/klibc/klibc/strncat.c new file mode 100644 index 0000000000..99d957594c --- /dev/null +++ b/klibc/klibc/strncat.c @@ -0,0 +1,11 @@ +/* + * strncat.c + */ + +#include + +char *strncat(char *dst, const char *src, size_t n) +{ + strncpy(strchr(dst, '\0'), src, n); + return dst; +} diff --git a/klibc/klibc/strncmp.c b/klibc/klibc/strncmp.c new file mode 100644 index 0000000000..98a41c3773 --- /dev/null +++ b/klibc/klibc/strncmp.c @@ -0,0 +1,20 @@ +/* + * strncmp.c + */ + +#include + +int strncmp(const char *s1, const char *s2, size_t n) +{ + const unsigned char *c1 = s1, *c2 = s2; + unsigned char ch; + int d = 0; + + while ( n-- ) { + d = (int)*c2++ - (int)(ch = *c1++); + if ( d || !ch ) + break; + } + + return d; +} diff --git a/klibc/klibc/strncpy.c b/klibc/klibc/strncpy.c new file mode 100644 index 0000000000..a8fe45fcbb --- /dev/null +++ b/klibc/klibc/strncpy.c @@ -0,0 +1,22 @@ +/* + * strncpy.c + * + * strncpy() + */ + +#include + +char *strncpy(char *dst, const char *src, size_t n) +{ + char *q = dst; + const char *p = src; + char ch; + + while ( n-- ) { + *q++ = ch = *p++; + if ( !ch ) + break; + } + + return dst; +} diff --git a/klibc/klibc/strntoimax.c b/klibc/klibc/strntoimax.c new file mode 100644 index 0000000000..f53a266dba --- /dev/null +++ b/klibc/klibc/strntoimax.c @@ -0,0 +1,13 @@ +/* + * strntoimax.c + * + * strntoimax() + */ + +#include +#include + +intmax_t strntoimax(const char *nptr, char **endptr, int base, size_t n) +{ + return (intmax_t) strntoumax(nptr, endptr, base, n); +} diff --git a/klibc/klibc/strntoumax.c b/klibc/klibc/strntoumax.c new file mode 100644 index 0000000000..4e30637d2c --- /dev/null +++ b/klibc/klibc/strntoumax.c @@ -0,0 +1,75 @@ +/* + * strntoumax.c + * + * The strntoumax() function and associated + */ + +#include +#include +#include + +static inline int digitval(int ch) +{ + if ( ch >= '0' && ch <= '9' ) { + return ch-'0'; + } else if ( ch >= 'A' && ch <= 'Z' ) { + return ch-'A'+10; + } else if ( ch >= 'a' && ch <= 'z' ) { + return ch-'a'+10; + } else { + return -1; + } +} + +uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) +{ + int minus = 0; + uintmax_t v = 0; + int d; + + while ( n && isspace((unsigned char)*nptr) ) { + nptr++; + n--; + } + + /* Single optional + or - */ + if ( n && *nptr == '-' ) { + minus = 1; + nptr++; + n--; + } else if ( n && *nptr == '+' ) { + nptr++; + } + + if ( base == 0 ) { + if ( n >= 2 && nptr[0] == '0' && + (nptr[1] == 'x' || nptr[1] == 'X') ) { + n -= 2; + nptr += 2; + base = 16; + } else if ( n >= 1 && nptr[0] == '0' ) { + n--; + nptr++; + base = 8; + } else { + base = 10; + } + } else if ( base == 16 ) { + if ( n >= 2 && nptr[0] == '0' && + (nptr[1] == 'x' || nptr[1] == 'X') ) { + n -= 2; + nptr += 2; + } + } + + while ( n && (d = digitval(*nptr)) >= 0 && d < base ) { + v = v*base + d; + n--; + nptr++; + } + + if ( endptr ) + *endptr = (char *)nptr; + + return minus ? -v : v; +} diff --git a/klibc/klibc/strrchr.c b/klibc/klibc/strrchr.c new file mode 100644 index 0000000000..3b42464059 --- /dev/null +++ b/klibc/klibc/strrchr.c @@ -0,0 +1,18 @@ +/* + * strrchr.c + */ + +#include + +char *strrchr(const char *s, int c) +{ + const char *found = NULL; + + while ( *s ) { + if ( *s == (char) c ) + found = s; + s++; + } + + return (char *)found; +} diff --git a/klibc/klibc/strsep.c b/klibc/klibc/strsep.c new file mode 100644 index 0000000000..58a7a07773 --- /dev/null +++ b/klibc/klibc/strsep.c @@ -0,0 +1,21 @@ +/* + * strsep.c + */ + +#include + +char *strsep(char **stringp, const char *delim) +{ + char *s = *stringp; + char *e; + + if ( !s ) + return NULL; + + e = strpbrk(s, delim); + if (e) + *e++ = '\0'; + + *stringp = e; + return s; +} diff --git a/klibc/klibc/strspn.c b/klibc/klibc/strspn.c new file mode 100644 index 0000000000..856a964197 --- /dev/null +++ b/klibc/klibc/strspn.c @@ -0,0 +1,67 @@ +/* + * strspn, strcspn + */ + +#include +#include +#include +#include + +#ifndef LONG_BIT +#define LONG_BIT (CHAR_BIT*sizeof(long)) +#endif + +static inline void +set_bit(unsigned long *bitmap, unsigned int bit) +{ + bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT); +} + +static inline int +test_bit(unsigned long *bitmap, unsigned int bit) +{ + return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1; +} + +static size_t +strxspn(const char *s, const char *map, int parity) +{ + unsigned long matchmap[((1 << CHAR_BIT)+LONG_BIT-1)/LONG_BIT]; + size_t n = 0; + + /* Create bitmap */ + memset(matchmap, 0, sizeof matchmap); + while ( *map ) + set_bit(matchmap, (unsigned char) *map++); + + /* Make sure the null character never matches */ + if ( parity ) + set_bit(matchmap, 0); + + /* Calculate span length */ + while ( test_bit(matchmap, (unsigned char) *s++)^parity ) + n++; + + return n; +} + +size_t +strspn(const char *s, const char *accept) +{ + return strxspn(s, accept, 0); +} + +size_t +strcspn(const char *s, const char *reject) +{ + return strxspn(s, reject, 1); +} + +char * +strpbrk(const char *s, const char *accept) +{ + const char *ss = s+strxspn(s, accept, 1); + + return *ss ? (char *)ss : NULL; +} + diff --git a/klibc/klibc/strstr.c b/klibc/klibc/strstr.c new file mode 100644 index 0000000000..10222dfd30 --- /dev/null +++ b/klibc/klibc/strstr.c @@ -0,0 +1,10 @@ +/* + * strstr.c + */ + +#include + +char *strstr(const char *haystack, const char *needle) +{ + return (char *)memmem(haystack, strlen(haystack), needle, strlen(needle)); +} diff --git a/klibc/klibc/strtoimax.c b/klibc/klibc/strtoimax.c new file mode 100644 index 0000000000..0cdd088e51 --- /dev/null +++ b/klibc/klibc/strtoimax.c @@ -0,0 +1,3 @@ +#define TYPE intmax_t +#define NAME strtoimax +#include "strtox.c" diff --git a/klibc/klibc/strtok.c b/klibc/klibc/strtok.c new file mode 100644 index 0000000000..6e84f1dff3 --- /dev/null +++ b/klibc/klibc/strtok.c @@ -0,0 +1,16 @@ +/* + * strtok.c + */ + +#include + +char *strtok(char *s, const char *delim) +{ + static char *holder; + + if ( s ) + holder = s; + + return strsep(&holder, delim); +} + diff --git a/klibc/klibc/strtol.c b/klibc/klibc/strtol.c new file mode 100644 index 0000000000..9efc8b9e4a --- /dev/null +++ b/klibc/klibc/strtol.c @@ -0,0 +1,3 @@ +#define TYPE signed long +#define NAME strtol +#include "strtox.c" diff --git a/klibc/klibc/strtoll.c b/klibc/klibc/strtoll.c new file mode 100644 index 0000000000..a9428c7f14 --- /dev/null +++ b/klibc/klibc/strtoll.c @@ -0,0 +1,3 @@ +#define TYPE signed long long +#define NAME strtoll +#include "strtox.c" diff --git a/klibc/klibc/strtoul.c b/klibc/klibc/strtoul.c new file mode 100644 index 0000000000..3189aaa7ce --- /dev/null +++ b/klibc/klibc/strtoul.c @@ -0,0 +1,3 @@ +#define TYPE unsigned long +#define NAME strtoul +#include "strtox.c" diff --git a/klibc/klibc/strtoull.c b/klibc/klibc/strtoull.c new file mode 100644 index 0000000000..83c14e9128 --- /dev/null +++ b/klibc/klibc/strtoull.c @@ -0,0 +1,3 @@ +#define TYPE unsigned long long +#define NAME strtoull +#include "strtox.c" diff --git a/klibc/klibc/strtoumax.c b/klibc/klibc/strtoumax.c new file mode 100644 index 0000000000..a3797105e8 --- /dev/null +++ b/klibc/klibc/strtoumax.c @@ -0,0 +1,3 @@ +#define TYPE uintmax_t +#define NAME strtoumax +#include "strtox.c" diff --git a/klibc/klibc/strtox.c b/klibc/klibc/strtox.c new file mode 100644 index 0000000000..7c228b6fa4 --- /dev/null +++ b/klibc/klibc/strtox.c @@ -0,0 +1,13 @@ +/* + * strtox.c + * + * strto...() functions, by macro definition + */ + +#include +#include + +TYPE NAME (const char *nptr, char **endptr, int base) +{ + return (TYPE) strntoumax(nptr, endptr, base, ~(size_t)0); +} diff --git a/klibc/klibc/syscalls.pl b/klibc/klibc/syscalls.pl new file mode 100644 index 0000000000..b530a9b8c7 --- /dev/null +++ b/klibc/klibc/syscalls.pl @@ -0,0 +1,81 @@ +#!/usr/bin/perl +($arch, $file) = @ARGV; + +if (!open(FILE, "< $file")) { + print STDERR "$file: $!\n"; + exit(1); +} + +while ( defined($line = ) ) { + chomp $line; + $line =~ s/\s*\#.*$//; # Strip comments and trailing blanks + next unless $line; + + if ( $line =~ /^\s*(\<[^\>]+\>\s+|)([^\(\<\>]+[^\@\:A-Za-z0-9_])([A-Za-z0-9_]+)(|\@[A-Za-z0-9_]+)(|\:\:[A-Za-z0-9_]+)\s*\(([^\:\)]*)\)\s*$/ ) { + $archs = $1; + $type = $2; + $sname = $3; + $stype = $4; + $fname = $5; + $argv = $6; + + $doit = 1; + if ( $archs ne '' ) { + die "$0: Internal error" + unless ( $archs =~ /^\<(|\!)([^\>\!]+)\>/ ); + $not = $1; + $list = $2; + + $doit = ($not eq '') ? 0 : 1; + + @list = split(/,/, $list); + foreach $a ( @list ) { + if ( $a eq $arch ) { + $doit = ($not eq '') ? 1 : 0; + last; + } + } + } + next if ( ! $doit ); + + $type =~ s/\s*$//; + + $stype =~ s/^\@/_/; + + if ( $fname eq '' ) { + $fname = $sname; + } else { + $fname =~ s/^\:\://; + } + + @args = split(/\s*\,\s*/, $argv); + + open(OUT, "> syscalls/${fname}.c") + or die "$0: Cannot open syscalls/${fname}.c\n"; + + if ( $fname eq "rt_sigaction") { + print OUT "#ifdef __x86_64__\n\n"; + print OUT "struct sigaction;\n\n"; + print OUT "#endif\n\n" + } + + print OUT "#include \"syscommon.h\"\n\n"; + + if ( $fname ne $sname ) { + print OUT "#undef __NR_${fname}\n"; + print OUT "#define __NR_${fname} __NR_${sname}\n\n"; + } + + print OUT "_syscall", scalar(@args), $stype, "(", $type, ',', $fname; + + $i = 0; + foreach $arg ( @args ) { + print OUT ",", $arg, ",a",$i++; + } + print OUT ");\n"; + close(OUT); + } else { + print STDERR "$file:$.: Could not parse input\n"; + exit(1); + } +} diff --git a/klibc/klibc/syscommon.h b/klibc/klibc/syscommon.h new file mode 100644 index 0000000000..224e240e38 --- /dev/null +++ b/klibc/klibc/syscommon.h @@ -0,0 +1,29 @@ +/* + * syscommon.h + * + * Common header file for system call stubs + */ + +#define __IN_SYS_COMMON +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c new file mode 100644 index 0000000000..b031d4f0e7 --- /dev/null +++ b/klibc/klibc/syslog.c @@ -0,0 +1,74 @@ +/* + * syslog.c + * + * Issue syslog messages via the kernel printk queue. + */ + +#include +#include +#include +#include +#include +#include + +/* Maximum size for a kernel message */ +#define BUFLEN 1024 + +/* Logging node */ +#define LOGDEV "/dev/kmsg" + +/* Max length of ID string */ +#define MAXID 31 + +int __syslog_fd = -1; +static char id[MAXID+1]; + +void openlog(const char *ident, int option, int facility) +{ + int fd; + + (void)option; (void)facility; /* Unused */ + + if ( __syslog_fd == -1 ) { + __syslog_fd = fd = open(LOGDEV, O_WRONLY); + if ( fd == -1 ) + return; + fcntl(fd, F_SETFD, (long)FD_CLOEXEC); + } + + strncpy(id, ident?ident:"", MAXID); + id[MAXID] = '\0'; /* Make sure it's null-terminated */ +} + +void syslog(int prio, const char *format, ...) +{ + va_list ap; + char buf[BUFLEN]; + int rv, len; + int fd; + + if ( __syslog_fd == -1 ) + openlog(NULL, 0, 0); + + fd = __syslog_fd; + if ( fd == -1 ) + fd = 2; /* Failed to open log, write to stderr */ + + buf[0] = '<'; + buf[1] = LOG_PRI(prio)+'0'; + buf[2] = '>'; + len = 3; + + if ( *id ) + len += sprintf(buf+3, "%s: ", id); + + va_start(ap, format); + rv = vsnprintf(buf+len, BUFLEN-len, format, ap); + va_end(ap); + + len += rv; + if ( len > BUFLEN-1 ) len = BUFLEN-1; + buf[len] = '\n'; + + write(fd, buf, len+1); +} diff --git a/klibc/klibc/system.c b/klibc/klibc/system.c new file mode 100644 index 0000000000..643bf5e1cc --- /dev/null +++ b/klibc/klibc/system.c @@ -0,0 +1,61 @@ +/* + * system.c + * + * The system() function. If this turns out to actually be *used*, + * we may want to try to detect the very simple cases (no shell magic) + * and handle them internally, instead of requiring that /bin/sh be + * present. + */ + +#include +#include +#include +#include +#include + +int system(const char *string) +{ + pid_t pid; + struct sigaction ignore, old_int, old_quit; + sigset_t masked, oldmask; + static const char *argv[] = { "/bin/sh", "-c", NULL, NULL }; + int status; + + /* Block SIGCHLD and ignore SIGINT and SIGQUIT */ + /* Do this before the fork() to avoid races */ + + ignore.sa_handler = SIG_IGN; + sigemptyset(&ignore.sa_mask); + ignore.sa_flags = 0; + sigaction(SIGINT, &ignore, &old_int); + sigaction(SIGQUIT, &ignore, &old_quit); + + sigemptyset(&masked); + sigaddset(&masked, SIGCHLD); + sigprocmask(SIG_BLOCK, &masked, &oldmask); + + pid = fork(); + + if ( pid < 0 ) + return -1; + else if ( pid == 0 ) { + sigaction(SIGINT, &old_int, NULL); + sigaction(SIGQUIT, &old_quit, NULL); + sigprocmask(SIG_SETMASK, &oldmask, NULL); + + argv[2] = string; + + execve(argv[0], (char * const *)argv, (char * const *)environ); + _exit(127); + } + + /* else... */ + + waitpid(pid, &status, 0); + + sigaction(SIGINT, &old_int, NULL); + sigaction(SIGQUIT, &old_quit, NULL); + sigprocmask(SIG_SETMASK, &oldmask, NULL); + + return status; +} diff --git a/klibc/klibc/tests/getenvtest.c b/klibc/klibc/tests/getenvtest.c new file mode 100644 index 0000000000..07cac0cef7 --- /dev/null +++ b/klibc/klibc/tests/getenvtest.c @@ -0,0 +1,26 @@ +#include +#include +#include + +int main(int argc, char *argv[], char *envp[]) +{ + int i; + + /* Verify envp == environ */ + printf("Verifying envp == environ... %s\n", + (envp == environ) ? "ok" : "ERROR"); + + /* Test argc/argv */ + printf("argc = %d, argv = %p\n", argc, argv); + for ( i = 0 ; i < argc ; i++ ) { + printf("argv[%2d] = %s\n", i, argv[i]); + } + + /* Test environ */ + printf("PATH = %s\n", getenv("PATH")); + printf("HOME = %s\n", getenv("HOME")); + printf("TERM = %s\n", getenv("TERM")); + printf("USER = %s\n", getenv("USER")); + + return 0; +} diff --git a/klibc/klibc/tests/getopttest.c b/klibc/klibc/tests/getopttest.c new file mode 100644 index 0000000000..90ceaa2c58 --- /dev/null +++ b/klibc/klibc/tests/getopttest.c @@ -0,0 +1,31 @@ +/* + * getopttest.c + * + * Simple test for getopt, set the environment variable GETOPTTEST + * to give the argument string to getopt() + */ + +#include +#include +#include + +int main(int argc, char * const *argv) +{ + const char *parser; + char showchar[] = "\'?\'"; + int c; + + parser = getenv("GETOPTTEST"); + if ( !parser ) parser = "abzf:o:"; + + do { + c = getopt(argc, argv, parser); + showchar[1] = c; + printf("c = %s, optind = %d (%s), optarg = \"%s\", optopt = \'%c\'\n", + (c == EOF) ? "EOF" : showchar, + optind, argv[optind], optarg, optopt); + } while ( c != -1 ); + + return 0; +} + diff --git a/klibc/klibc/tests/hello.c b/klibc/klibc/tests/hello.c new file mode 100644 index 0000000000..20457af153 --- /dev/null +++ b/klibc/klibc/tests/hello.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + printf("Hello, World!\n"); + return 0; +} diff --git a/klibc/klibc/tests/idtest.c b/klibc/klibc/tests/idtest.c new file mode 100644 index 0000000000..c3c44479c5 --- /dev/null +++ b/klibc/klibc/tests/idtest.c @@ -0,0 +1,14 @@ +#include +#include + +int main(void) +{ + printf("pid = %u\n", getpid()); + printf("ppid = %u\n", getppid()); + printf("uid = %u\n", getuid()); + printf("euid = %u\n", geteuid()); + printf("gid = %u\n", getgid()); + printf("egid = %u\n", getegid()); + sleep(10); + return 0; +} diff --git a/klibc/klibc/tests/malloctest.c b/klibc/klibc/tests/malloctest.c new file mode 100644 index 0000000000..64e8e79851 --- /dev/null +++ b/klibc/klibc/tests/malloctest.c @@ -0,0 +1,4145 @@ +#include +#include +#include + +#define NCYCLES 4096 + +int sizes[NCYCLES] = { + 11986, + 277806, + 2659, + 46, + 0, + 775553, + 1991, + 21, + 7638, + 250197, + 155828, + 5777, + 9, + 315006, + 900788, + 0, + 24893, + 119996, + 72299, + 171266, + 357, + 560, + 368, + 22952, + 54058, + 12638, + 39155, + 2738, + 217563, + 26853, + 47, + 75, + 1167, + 16917, + 1899, + 2905, + 9337, + 62243, + 14214, + 270523, + 4024, + 21, + 32, + 14892, + 625144, + 13, + 21700, + 8804, + 254147, + 0, + 6, + 836004, + 1718, + 2289, + 15554, + 412857, + 185097, + 806709, + 64, + 18602, + 17064, + 1779, + 78153, + 170600, + 199100, + 546528, + 0, + 21, + 20609, + 16514, + 548196, + 311446, + 53484, + 0, + 551, + 22225, + 24, + 153989, + 457309, + 526833, + 227979, + 757167, + 429560, + 0, + 835, + 1702, + 475275, + 798416, + 753, + 0, + 11126, + 145779, + 2006, + 0, + 8182, + 0, + 569432, + 9671, + 36, + 5523, + 407325, + 0, + 65, + 9293, + 0, + 6793, + 468701, + 73, + 0, + 186236, + 0, + 328405, + 125616, + 508013, + 380519, + 599518, + 83, + 151973, + 466906, + 9029, + 159725, + 1316, + 1, + 911532, + 1508, + 19050, + 972850, + 126, + 439377, + 29, + 37928, + 149628, + 54, + 130248, + 2, + 143, + 0, + 716873, + 3327, + 5, + 116131, + 5124, + 559621, + 2886, + 534, + 186432, + 441, + 7348, + 10331, + 1, + 260935, + 7, + 4370, + 405415, + 2, + 84518, + 1970, + 1, + 281910, + 46, + 274, + 2273, + 370565, + 4190, + 820641, + 577970, + 32809, + 974893, + 398067, + 380698, + 4, + 25978, + 153, + 882668, + 312365, + 9523, + 156421, + 0, + 268143, + 6, + 2, + 42987, + 212, + 12303, + 6723, + 1179, + 0, + 120924, + 3877, + 330421, + 310445, + 39264, + 8, + 85380, + 464716, + 0, + 33657, + 6285, + 0, + 4491, + 229, + 50, + 373197, + 6029, + 19, + 86884, + 243745, + 335656, + 90945, + 38973, + 572950, + 164129, + 0, + 3, + 17, + 13579, + 4448, + 47, + 3, + 132966, + 726249, + 498503, + 256, + 0, + 25841, + 0, + 7, + 945380, + 11872, + 69, + 3799, + 77223, + 1914, + 73, + 810968, + 10223, + 257918, + 184252, + 350, + 8101, + 725, + 9, + 2, + 2089, + 175, + 247, + 185964, + 36517, + 3723, + 313465, + 209, + 1300, + 128071, + 7425, + 2436, + 62, + 13753, + 9514, + 41, + 409141, + 46643, + 20866, + 15664, + 388548, + 84692, + 9549, + 610, + 7213, + 14, + 14930, + 244719, + 4748, + 41682, + 401098, + 102506, + 176535, + 0, + 5133, + 548, + 5234, + 56, + 11101, + 87638, + 336579, + 291705, + 640250, + 768165, + 370, + 2809, + 3, + 0, + 445122, + 47190, + 24885, + 143556, + 84, + 504726, + 610020, + 40355, + 902230, + 4360, + 1747, + 3496, + 489501, + 19, + 801601, + 62189, + 48, + 2645, + 320601, + 27304, + 17740, + 344, + 10, + 991, + 925503, + 0, + 315, + 251, + 3611, + 1756, + 683, + 165, + 380132, + 181101, + 453041, + 892056, + 67191, + 252592, + 32407, + 56242, + 8, + 297173, + 542903, + 830334, + 585236, + 422555, + 44769, + 0, + 68, + 4143, + 38754, + 73539, + 44579, + 94001, + 428537, + 38554, + 106612, + 0, + 182987, + 831731, + 3605, + 752851, + 52, + 72, + 120872, + 963754, + 31, + 764, + 240592, + 99101, + 328538, + 440325, + 12211, + 151282, + 353436, + 2991, + 40710, + 5212, + 5106, + 139122, + 148915, + 498505, + 1366, + 516, + 29190, + 17, + 224208, + 40, + 89, + 19190, + 8, + 25377, + 10029, + 720, + 97963, + 0, + 614, + 244567, + 2113, + 903675, + 8388, + 6, + 390705, + 325006, + 284272, + 108086, + 17, + 2628, + 952530, + 20474, + 898276, + 138661, + 3883, + 903, + 569993, + 376918, + 5849, + 103404, + 794499, + 35388, + 5, + 0, + 961626, + 27415, + 1927, + 92036, + 46241, + 35978, + 7426, + 399884, + 29490, + 252655, + 675971, + 3509, + 54170, + 170790, + 831341, + 134579, + 0, + 790422, + 35, + 930830, + 97394, + 20265, + 670, + 38497, + 1759, + 71209, + 93, + 736, + 11, + 886, + 1961, + 7, + 210607, + 62226, + 186736, + 1518, + 5, + 5, + 13, + 66989, + 442321, + 0, + 607939, + 11253, + 210875, + 495530, + 2, + 221136, + 377663, + 372, + 200658, + 18591, + 129783, + 803411, + 867506, + 757446, + 48836, + 34, + 200, + 114983, + 7287, + 22849, + 226669, + 13, + 0, + 20164, + 7828, + 39, + 49448, + 26740, + 185566, + 9927, + 36192, + 91068, + 338368, + 926, + 27746, + 534794, + 936132, + 2922, + 5, + 183162, + 256846, + 242551, + 134318, + 212959, + 167162, + 470, + 477045, + 532116, + 483794, + 733, + 5335, + 83074, + 4686, + 9567, + 1, + 195100, + 40354, + 87338, + 369, + 800, + 0, + 194504, + 469051, + 363532, + 850574, + 5085, + 167027, + 794511, + 124320, + 303231, + 132195, + 13225, + 46333, + 4313, + 89, + 799, + 51482, + 0, + 26, + 12659, + 1045, + 23621, + 0, + 74926, + 490979, + 6, + 3188, + 9448, + 174730, + 38982, + 102317, + 189621, + 853, + 29227, + 43374, + 423, + 420951, + 686, + 128, + 31291, + 0, + 402819, + 663143, + 55903, + 142, + 2, + 331584, + 197164, + 7, + 671983, + 53, + 5020, + 9782, + 123, + 743407, + 1276, + 1115, + 1169, + 122752, + 824690, + 292030, + 2094, + 144626, + 0, + 297278, + 440, + 742, + 95879, + 17682, + 10654, + 31, + 22183, + 746, + 0, + 0, + 11185, + 28, + 394987, + 36, + 474, + 243749, + 1431, + 56702, + 76, + 15619, + 33071, + 12181, + 158647, + 261786, + 1, + 119783, + 48816, + 6278, + 4121, + 61122, + 69, + 48790, + 345335, + 275917, + 964393, + 424, + 586433, + 20519, + 18156, + 756400, + 27736, + 458706, + 1, + 3286, + 929624, + 1883, + 2, + 1086, + 439501, + 552, + 157132, + 5565, + 105061, + 8199, + 23, + 178797, + 0, + 130644, + 1, + 6952, + 754, + 500, + 647683, + 0, + 959079, + 622561, + 1131, + 559783, + 6862, + 175420, + 408671, + 463461, + 55908, + 606496, + 169, + 49060, + 247, + 953, + 333030, + 0, + 23399, + 29193, + 9303, + 15, + 515402, + 34961, + 365856, + 633043, + 173, + 556089, + 1809, + 12215, + 14, + 316, + 20642, + 9, + 15, + 190391, + 951463, + 25059, + 13654, + 385040, + 4272, + 929033, + 208813, + 35166, + 42849, + 662648, + 254811, + 4230, + 812459, + 681, + 390168, + 5381, + 4662, + 173257, + 478863, + 103, + 89332, + 0, + 0, + 589484, + 19369, + 94, + 9, + 639917, + 1110, + 393, + 101040, + 911, + 152899, + 0, + 2, + 0, + 0, + 335691, + 43694, + 62273, + 200121, + 2250, + 621004, + 149918, + 41063, + 218229, + 0, + 497924, + 16832, + 587071, + 0, + 0, + 729918, + 2, + 808513, + 9417, + 718, + 0, + 2769, + 28704, + 1335, + 734726, + 219157, + 786230, + 981004, + 350788, + 884529, + 0, + 87872, + 34647, + 85469, + 4524, + 339838, + 38228, + 0, + 4151, + 1145, + 0, + 351, + 167956, + 810075, + 689, + 251212, + 583068, + 2929, + 189456, + 2089, + 48749, + 278952, + 77134, + 0, + 0, + 45595, + 281829, + 969602, + 43999, + 69824, + 856982, + 61732, + 336, + 25488, + 213, + 46683, + 1909, + 174097, + 57930, + 91466, + 828418, + 95740, + 378828, + 128065, + 68068, + 0, + 13312, + 26006, + 6760, + 51, + 276081, + 640068, + 634985, + 7131, + 784882, + 790126, + 628585, + 205824, + 764965, + 17793, + 3159, + 649924, + 0, + 37383, + 9919, + 353, + 0, + 149003, + 620629, + 95928, + 2560, + 504343, + 1000, + 32, + 43836, + 407031, + 207, + 800894, + 3222, + 51028, + 7, + 6, + 22010, + 0, + 21174, + 12893, + 824932, + 7305, + 70, + 624258, + 372139, + 21504, + 387996, + 418931, + 914268, + 576, + 0, + 0, + 618224, + 787516, + 133014, + 422, + 383124, + 656318, + 4420, + 6082, + 244813, + 38585, + 3200, + 1, + 2, + 11882, + 113, + 45581, + 13121, + 95475, + 807219, + 8195, + 995116, + 13, + 2146, + 369925, + 60103, + 25, + 125165, + 51300, + 4894, + 173261, + 74186, + 1044, + 122992, + 1243, + 21703, + 26294, + 197, + 333825, + 426872, + 719580, + 3598, + 106, + 0, + 9932, + 61509, + 146, + 721428, + 964781, + 319850, + 573802, + 7458, + 317889, + 0, + 133086, + 87836, + 60496, + 304249, + 1565, + 27, + 42, + 899324, + 189637, + 8648, + 104570, + 901598, + 447765, + 24, + 108, + 120127, + 828626, + 8, + 899514, + 28, + 13, + 7576, + 163390, + 1625, + 3023, + 155175, + 2, + 391, + 1, + 493073, + 398, + 210771, + 26266, + 287999, + 38255, + 249666, + 598202, + 119601, + 216933, + 91205, + 0, + 7247, + 77077, + 565383, + 29102, + 253641, + 48855, + 19722, + 463536, + 40182, + 65393, + 829444, + 598402, + 1590, + 798, + 467, + 834847, + 3007, + 13711, + 0, + 195, + 101662, + 255749, + 129201, + 11965, + 1781, + 13349, + 3100, + 718066, + 99, + 712450, + 888215, + 42503, + 43171, + 494946, + 0, + 2175, + 12387, + 25662, + 78, + 739030, + 0, + 19, + 427526, + 4275, + 5583, + 0, + 2447, + 132398, + 26437, + 3873, + 440035, + 21, + 6, + 35432, + 41523, + 7179, + 712703, + 428868, + 2793, + 6, + 286277, + 1882, + 95116, + 2959, + 86, + 115425, + 81386, + 59836, + 37, + 247598, + 34732, + 249, + 500110, + 5589, + 40319, + 575, + 12145, + 385829, + 565600, + 582150, + 92, + 223209, + 0, + 910, + 1048, + 47329, + 90944, + 235, + 8739, + 686685, + 1753, + 126, + 434, + 609477, + 25021, + 6610, + 52675, + 4, + 717846, + 150864, + 418583, + 17751, + 513794, + 181362, + 329556, + 10426, + 717019, + 457, + 616, + 388984, + 17, + 8338, + 59531, + 32, + 99565, + 376146, + 134578, + 966, + 0, + 0, + 174, + 2105, + 555, + 8990, + 298, + 169932, + 247281, + 240918, + 298655, + 158743, + 15994, + 95708, + 51, + 2985, + 4294, + 731934, + 185640, + 1483, + 87, + 742033, + 9, + 1345, + 3680, + 133530, + 9355, + 800111, + 28508, + 0, + 369, + 31681, + 24, + 8237, + 313380, + 4732, + 275423, + 951592, + 0, + 41381, + 225515, + 393004, + 526, + 187, + 19515, + 6006, + 28923, + 310151, + 2390, + 374, + 0, + 19142, + 72, + 114, + 193305, + 24035, + 397067, + 18, + 14839, + 3473, + 164, + 104622, + 378958, + 2218, + 0, + 89053, + 105183, + 312265, + 82146, + 147210, + 3419, + 5178, + 34948, + 46836, + 41319, + 842825, + 595972, + 0, + 249625, + 325, + 608, + 372328, + 119634, + 7504, + 920214, + 7302, + 444532, + 359213, + 27265, + 1755, + 48, + 126799, + 651270, + 818220, + 799493, + 724024, + 64047, + 73699, + 206999, + 209, + 1581, + 0, + 42937, + 301144, + 73416, + 0, + 242058, + 29660, + 3, + 34709, + 162719, + 2863, + 3992, + 5212, + 151814, + 3092, + 198001, + 44331, + 36, + 407, + 364771, + 1349, + 502772, + 214726, + 607, + 388583, + 137660, + 337124, + 13279, + 10549, + 943075, + 164068, + 19157, + 38443, + 26351, + 0, + 67167, + 735, + 46486, + 130305, + 232330, + 744, + 882337, + 2, + 69275, + 126354, + 9370, + 2845, + 299, + 38988, + 37834, + 0, + 306433, + 9139, + 237132, + 0, + 500, + 13462, + 373684, + 107453, + 381924, + 347915, + 4329, + 1668, + 3960, + 370661, + 3614, + 636048, + 0, + 487449, + 64925, + 333894, + 11, + 52192, + 531200, + 155554, + 461, + 1547, + 994361, + 11955, + 321056, + 37425, + 14249, + 69151, + 621862, + 174, + 79607, + 34, + 77577, + 13723, + 267550, + 13801, + 698, + 12, + 171556, + 57354, + 676845, + 0, + 24965, + 908955, + 570483, + 0, + 296387, + 983966, + 85012, + 130298, + 151946, + 384474, + 731455, + 150699, + 772, + 216131, + 346, + 130935, + 3472, + 18, + 426045, + 677262, + 808, + 17030, + 5188, + 0, + 491153, + 67299, + 19, + 60342, + 69, + 0, + 76478, + 95763, + 0, + 28778, + 147869, + 335927, + 27846, + 2163, + 22750, + 162, + 23, + 11391, + 469099, + 5852, + 63, + 0, + 0, + 22193, + 165, + 489007, + 9249, + 12477, + 2841, + 223532, + 13877, + 173, + 3570, + 45477, + 233073, + 23296, + 64377, + 4910, + 8, + 76246, + 411147, + 287411, + 10450, + 3667, + 1, + 500933, + 31363, + 257, + 1705, + 6036, + 49934, + 13738, + 13485, + 61608, + 561978, + 76493, + 16377, + 1817, + 0, + 235600, + 0, + 16347, + 680478, + 5115, + 895607, + 138270, + 369912, + 53110, + 0, + 647083, + 85, + 458681, + 163227, + 52767, + 196, + 267719, + 14047, + 147293, + 814457, + 174896, + 0, + 34138, + 36, + 21575, + 3, + 0, + 0, + 38391, + 2597, + 2, + 1433, + 3807, + 36476, + 287, + 141530, + 29389, + 495655, + 30014, + 0, + 550766, + 11958, + 348, + 226760, + 15, + 251353, + 675788, + 518308, + 215, + 81987, + 409862, + 559596, + 114283, + 4925, + 0, + 17, + 14221, + 0, + 162, + 766370, + 4898, + 998, + 493, + 138418, + 265159, + 12152, + 5229, + 1204, + 1814, + 432530, + 2889, + 144, + 1149, + 35886, + 636931, + 6640, + 1508, + 414118, + 858, + 20039, + 17398, + 3, + 5094, + 6, + 13996, + 6754, + 362, + 451487, + 11471, + 7896, + 330009, + 244269, + 99928, + 0, + 14311, + 9949, + 15251, + 283923, + 123754, + 188360, + 93902, + 854384, + 548001, + 531788, + 26298, + 328479, + 941, + 246535, + 106320, + 28769, + 440, + 4, + 61262, + 55615, + 170, + 989327, + 692534, + 8063, + 445842, + 4434, + 255349, + 117781, + 6, + 9249, + 136216, + 38165, + 307012, + 12, + 2341, + 18062, + 371882, + 662154, + 12623, + 176847, + 332220, + 590935, + 33682, + 0, + 121374, + 67, + 46841, + 495890, + 640, + 19, + 14737, + 11032, + 17, + 5993, + 302562, + 827710, + 165346, + 49607, + 87863, + 308513, + 735300, + 1914, + 2900, + 207308, + 9068, + 83494, + 179, + 417, + 41605, + 74681, + 652171, + 4013, + 29811, + 13966, + 8136, + 78, + 61182, + 674187, + 0, + 331121, + 0, + 18559, + 386, + 77, + 348439, + 975358, + 18, + 33700, + 47396, + 204751, + 2350, + 26503, + 0, + 83653, + 446, + 10844, + 485, + 9241, + 88347, + 232419, + 936900, + 43250, + 2, + 26112, + 811955, + 20723, + 102069, + 42255, + 8431, + 119508, + 4080, + 13565, + 12, + 46110, + 62096, + 638777, + 44025, + 152985, + 13362, + 3, + 12331, + 193337, + 56419, + 14593, + 3837, + 282314, + 403454, + 48589, + 135, + 18350, + 2160, + 90, + 918216, + 7083, + 105534, + 742826, + 399028, + 1470, + 23770, + 480, + 677884, + 340472, + 107406, + 0, + 5002, + 445, + 748948, + 534012, + 592464, + 6539, + 819632, + 3138, + 4, + 39397, + 229683, + 12204, + 2439, + 65131, + 817226, + 22596, + 0, + 1046, + 94638, + 0, + 95403, + 1230, + 790056, + 19976, + 43085, + 14251, + 139187, + 20232, + 693, + 3058, + 27654, + 65690, + 40948, + 15001, + 21089, + 14425, + 322459, + 13571, + 228154, + 536814, + 761221, + 28030, + 2322, + 921, + 1, + 1137, + 187815, + 8, + 34911, + 4527, + 15, + 46, + 78801, + 0, + 73605, + 44, + 28233, + 1370, + 73409, + 198159, + 66586, + 3, + 2576, + 15, + 35460, + 263237, + 44997, + 2873, + 240, + 1781, + 269, + 46, + 272778, + 28404, + 8232, + 417073, + 234591, + 9, + 720349, + 1176, + 16195, + 0, + 9705, + 0, + 14, + 947048, + 163, + 76288, + 1115, + 267020, + 3416, + 414217, + 441004, + 95131, + 765002, + 6196, + 9069, + 27017, + 137039, + 65247, + 266489, + 484945, + 187008, + 45405, + 5700, + 9, + 7751, + 12, + 294, + 3093, + 6350, + 103303, + 6045, + 252345, + 140207, + 22390, + 234867, + 443326, + 1, + 0, + 89972, + 8637, + 427150, + 22146, + 0, + 310432, + 390333, + 10461, + 1632, + 31403, + 908653, + 0, + 6543, + 163479, + 67608, + 195543, + 315889, + 822964, + 383536, + 954954, + 1619, + 241, + 96053, + 104556, + 767302, + 2469, + 12, + 164330, + 78, + 141, + 170519, + 268214, + 53338, + 48342, + 721, + 58980, + 4345, + 1, + 856265, + 87289, + 57219, + 775679, + 123992, + 695804, + 113025, + 832, + 117420, + 16634, + 352, + 24729, + 14973, + 25622, + 131290, + 0, + 22, + 87740, + 5917, + 533, + 2934, + 34261, + 9174, + 0, + 1656, + 764587, + 54652, + 35597, + 36389, + 577889, + 63957, + 26808, + 34556, + 56, + 15641, + 137, + 1, + 3, + 11724, + 197397, + 39027, + 87902, + 320, + 791479, + 7, + 487864, + 0, + 433, + 25733, + 6956, + 15407, + 312557, + 526302, + 383019, + 340215, + 96, + 276158, + 6493, + 135613, + 2000, + 1218, + 930, + 276808, + 273249, + 8896, + 397, + 735095, + 20648, + 2079, + 5349, + 205, + 356313, + 841954, + 8255, + 266874, + 0, + 965, + 287993, + 1549, + 207833, + 75, + 178180, + 39072, + 0, + 43254, + 3847, + 227, + 2712, + 161043, + 463264, + 74720, + 795789, + 12, + 6812, + 202804, + 29379, + 64241, + 132121, + 790622, + 493588, + 0, + 48, + 147352, + 925197, + 38149, + 18380, + 0, + 270280, + 633, + 3373, + 31294, + 7830, + 0, + 0, + 11371, + 56143, + 5393, + 74724, + 495109, + 0, + 18993, + 21524, + 0, + 53889, + 400509, + 204563, + 0, + 11625, + 9635, + 0, + 1678, + 12096, + 59, + 817112, + 10002, + 128209, + 11593, + 17313, + 15200, + 106796, + 261401, + 707077, + 0, + 314030, + 798591, + 14175, + 5668, + 2766, + 0, + 566, + 5543, + 24112, + 154482, + 5642, + 0, + 38410, + 3, + 4, + 700724, + 25024, + 5, + 407, + 564150, + 672, + 143, + 2049, + 574708, + 65858, + 213412, + 3797, + 511, + 30907, + 1212, + 765, + 2127, + 481, + 130048, + 113816, + 39861, + 153169, + 503378, + 523944, + 111, + 55083, + 698, + 275, + 3, + 3195, + 1657, + 0, + 317881, + 6672, + 543, + 153011, + 77240, + 9338, + 889850, + 29518, + 872485, + 181927, + 376086, + 266, + 409, + 4, + 14856, + 31943, + 2448, + 8, + 75, + 383097, + 294366, + 0, + 173084, + 753160, + 66457, + 725783, + 51, + 127651, + 1073, + 12598, + 140080, + 0, + 296375, + 581720, + 217346, + 8272, + 2051, + 185390, + 520645, + 1260, + 13873, + 168040, + 19690, + 103347, + 295011, + 548404, + 48, + 4, + 916417, + 1948, + 621365, + 263245, + 2792, + 86803, + 181193, + 558081, + 50907, + 442770, + 51448, + 340276, + 1346, + 607, + 459627, + 0, + 30, + 73298, + 15389, + 12264, + 2719, + 2936, + 143043, + 209970, + 0, + 42, + 6657, + 317419, + 0, + 32622, + 524000, + 0, + 310331, + 303778, + 268710, + 9, + 10410, + 25343, + 949506, + 784353, + 3861, + 46823, + 251292, + 75008, + 269798, + 87731, + 112813, + 571679, + 385, + 3, + 2811, + 36025, + 9243, + 935128, + 906, + 10688, + 25, + 86757, + 307, + 55, + 22, + 2, + 61, + 620426, + 484530, + 633806, + 0, + 1342, + 9293, + 992181, + 503, + 195433, + 46150, + 893091, + 3207, + 2865, + 72894, + 830299, + 355, + 327479, + 0, + 35573, + 3068, + 15699, + 31187, + 55378, + 416067, + 91721, + 159, + 0, + 255139, + 2104, + 19, + 606757, + 323, + 902659, + 365655, + 400, + 903, + 408, + 385, + 21774, + 701290, + 234426, + 17020, + 950, + 0, + 0, + 429, + 1245, + 405871, + 1097, + 280634, + 74, + 158233, + 1583, + 180333, + 42114, + 575973, + 539327, + 59252, + 121928, + 165, + 148501, + 55757, + 7494, + 127728, + 7832, + 68504, + 619770, + 70995, + 312816, + 7307, + 38265, + 46248, + 363304, + 269442, + 77112, + 448331, + 910442, + 474418, + 152752, + 752, + 104912, + 408492, + 691709, + 632381, + 48519, + 20524, + 344294, + 14670, + 0, + 21607, + 81162, + 181458, + 0, + 908322, + 7261, + 10888, + 58054, + 1788, + 970933, + 5925, + 121553, + 36152, + 588267, + 23615, + 1850, + 30728, + 3599, + 1319, + 6027, + 0, + 32141, + 984156, + 436781, + 15003, + 621407, + 9412, + 562911, + 189740, + 377895, + 656800, + 197, + 14413, + 99382, + 384, + 11480, + 0, + 86118, + 881961, + 1905, + 82061, + 4140, + 741153, + 26, + 687, + 12251, + 10945, + 209267, + 220602, + 135881, + 6, + 237945, + 158, + 5, + 76303, + 81344, + 986042, + 956063, + 30282, + 186055, + 357802, + 12492, + 577476, + 838, + 0, + 11, + 117602, + 0, + 187928, + 96860, + 4268, + 3478, + 818264, + 1649, + 17175, + 272, + 158951, + 440987, + 677594, + 14935, + 37953, + 0, + 198, + 160404, + 12, + 287803, + 2386, + 10, + 271663, + 319152, + 361322, + 68370, + 428, + 182707, + 387429, + 1152, + 360065, + 25218, + 2790, + 42228, + 13, + 110942, + 452491, + 1, + 665638, + 2308, + 1196, + 87306, + 66, + 219, + 0, + 130736, + 334, + 605, + 5979, + 2681, + 0, + 123463, + 11219, + 283681, + 19269, + 553, + 6217, + 130965, + 714409, + 242, + 674833, + 237581, + 133284, + 683, + 1758, + 278193, + 518726, + 44, + 420361, + 325228, + 14955, + 10, + 11994, + 64157, + 1937, + 20214, + 848, + 27804, + 151341, + 79236, + 316393, + 158883, + 1196, + 334, + 22797, + 185955, + 13857, + 397357, + 7948, + 6038, + 0, + 2621, + 16, + 155267, + 44809, + 9171, + 21328, + 12212, + 40200, + 2600, + 439, + 804014, + 10938, + 96135, + 43696, + 158715, + 4, + 284558, + 191, + 270254, + 7923, + 880603, + 21032, + 107700, + 172, + 700823, + 5613, + 78816, + 258290, + 214398, + 821856, + 295325, + 0, + 1, + 23559, + 63895, + 21249, + 717490, + 956952, + 944819, + 793, + 356, + 757716, + 111773, + 394826, + 25665, + 4358, + 640216, + 1152, + 37175, + 150192, + 106071, + 28992, + 67, + 1685, + 134242, + 2, + 102045, + 1457, + 419589, + 6789, + 677, + 94675, + 11300, + 2595, + 8, + 926535, + 265194, + 0, + 886048, + 246242, + 1494, + 191, + 169985, + 649765, + 0, + 201, + 1069, + 679163, + 16627, + 274639, + 84438, + 3, + 1301, + 247496, + 5879, + 710904, + 403652, + 958241, + 361, + 139732, + 6042, + 15985, + 2378, + 267031, + 223767, + 9656, + 241717, + 33863, + 14314, + 205697, + 1274, + 168000, + 621777, + 837913, + 89654, + 659829, + 69, + 503884, + 432717, + 70443, + 110891, + 19655, + 132432, + 620401, + 428, + 0, + 425662, + 0, + 0, + 0, + 194489, + 7601, + 26870, + 0, + 63, + 594, + 12278, + 582479, + 213723, + 424489, + 96446, + 990664, + 46966, + 44137, + 829810, + 104, + 19707, + 16, + 0, + 2499, + 167075, + 140972, + 249283, + 6620, + 68368, + 856414, + 9255, + 14315, + 0, + 11432, + 24329, + 216463, + 299556, + 818401, + 246607, + 697733, + 229, + 144, + 389394, + 664634, + 0, + 19393, + 657903, + 52912, + 952177, + 536931, + 187271, + 17687, + 970155, + 232571, + 234016, + 159980, + 13510, + 32952, + 0, + 0, + 24132, + 18806, + 15624, + 28364, + 472126, + 626978, + 599, + 112843, + 502933, + 915660, + 63920, + 0, + 84, + 10899, + 904823, + 126, + 469132, + 590052, + 195831, + 443113, + 294149, + 15944, + 2271, + 282974, + 211, + 0, + 22934, + 82283, + 49973, + 41707, + 87530, + 0, + 910528, + 0, + 36029, + 423337, + 817512, + 223671, + 27800, + 398847, + 198528, + 1, + 560679, + 518270, + 23033, + 501059, + 0, + 3909, + 272062, + 261581, + 187, + 52043, + 334, + 24354, + 3947, + 8549, + 37863, + 328851, + 963771, + 1, + 3930, + 82416, + 6, + 2943, + 122101, + 82577, + 85, + 89540, + 5135, + 109236, + 18297, + 1, + 177371, + 4541, + 769577, + 178, + 417, + 960566, + 33803, + 911651, + 248160, + 153725, + 43981, + 809174, + 116, + 486900, + 4842, + 148490, + 131534, + 4347, + 239949, + 984096, + 749756, + 429499, + 2794, + 78209, + 18812, + 21111, + 490, + 328042, + 12, + 132119, + 505103, + 353148, + 0, + 373656, + 951244, + 491, + 355778, + 30620, + 317, + 60175, + 220, + 214496, + 41249, + 5169, + 78367, + 506804, + 0, + 1368, + 407, + 295126, + 1288, + 86, + 97614, + 61640, + 244723, + 3, + 0, + 869827, + 527246, + 52, + 107036, + 240739, + 780281, + 113084, + 62009, + 740343, + 483201, + 8649, + 16419, + 1, + 801574, + 95524, + 326126, + 26912, + 877040, + 10262, + 5895, + 0, + 132633, + 59171, + 306347, + 702701, + 196245, + 12642, + 32723, + 24608, + 30287, + 45775, + 18281, + 7587, + 144532, + 5, + 35, + 99862, + 215127, + 170875, + 61461, + 77790, + 5, + 0, + 129358, + 0, + 105084, + 21399, + 42233, + 85397, + 480654, + 555988, + 89575, + 42346, + 20004, + 11102, + 21321, + 185, + 379267, + 849147, + 121514, + 3388, + 33662, + 12, + 164898, + 226, + 274, + 385003, + 365052, + 693376, + 41245, + 9010, + 41594, + 89835, + 10490, + 272, + 128437, + 0, + 122648, + 277, + 116505, + 38372, + 4, + 1376, + 0, + 46317, + 139368, + 36398, + 193899, + 30632, + 26371, + 7548, + 367643, + 954849, + 25889, + 36567, + 176, + 140631, + 4690, + 975031, + 80965, + 500471, + 8442, + 43, + 27758, + 301501, + 3797, + 80, + 384440, + 928477, + 4960, + 24566, + 33245, + 14638, + 228354, + 54347, + 861285, + 12841, + 2, + 157402, + 646747, + 53763, + 1, + 214732, + 49471, + 49757, + 998, + 201135, + 566, + 73512, + 194240, + 391773, + 21510, + 13, + 829894, + 783200, + 565329, + 2101, + 12, + 191043, + 1621, + 18443, + 279, + 294135, + 526503, + 729735, + 4639, + 444138, + 5835, + 12372, + 46362, + 1543, + 870907, + 83262, + 0, + 38331, + 95, + 1194, + 909, + 8053, + 453066, + 845561, + 411, + 3229, + 1, + 158, + 1431, + 835137, + 21774, + 7298, + 148388, + 224649, + 379318, + 520138, + 39781, + 172130, + 362634, + 487495, + 51957, + 158, + 1770, + 7, + 18010, + 1063, + 171484, + 19924, + 279867, + 469956, + 189785, + 0, + 814, + 60580, + 944349, + 18743, + 553235, + 0, + 95475, + 99, + 0, + 5, + 42623, + 178418, + 398940, + 5700, + 69023, + 5786, + 0, + 10531, + 551, + 86308, + 63451, + 32704, + 176903, + 0, + 251689, + 11589, + 25711, + 43437, + 1431, + 304, + 52965, + 34816, + 268688, + 47756, + 825323, + 122608, + 81246, + 69974, + 360515, + 99973, + 143015, + 5063, + 4499, + 34459, + 171982, + 677943, + 489082, + 257515, + 3765, + 5, + 7416, + 602206, + 74122, + 3, + 686204, + 5493, + 28901, + 11349, + 549668, + 257082, + 82000, + 17031, + 1517, + 7442, + 937160, + 722, + 0, + 72952, + 377192, + 438266, + 555, + 31436, + 284, + 56390, + 0, + 585856, + 27635, + 519344, + 126131, + 360273, + 845073, + 0, + 191965, + 55652, + 23, + 112773, + 639025, + 84749, + 0, + 330822, + 7173, + 126217, + 871, + 112112, + 0, + 664, + 530474, + 1, + 379564, + 172617, + 647308, + 0, + 356, + 17, + 84345, + 457, + 0, + 8, + 6, + 136602, + 634424, + 0, + 177298, + 100726, + 91661, + 383792, + 1665, + 43583, + 15775, + 4083, + 4277, + 345749, + 969599, + 65804, + 19327, + 0, + 352514, + 4225, + 9, + 103767, + 0, + 0, + 148436, + 850, + 33, + 2146, + 20153, + 50, + 9063, + 50329, + 348379, + 2569, + 83697, + 37073, + 715486, + 629, + 4753, + 442, + 259203, + 287223, + 48625, + 9, + 70184, + 45946, + 144947, + 0, + 60285, + 28640, + 7626, + 134159, + 33, + 12452, + 150566, + 348293, + 124426, + 353952, + 11, + 22, + 776742, + 29072, + 132168, + 254533, + 319957, + 1602, + 1659, + 209341, + 32847, + 92392, + 753005, + 1392, + 10271, + 28557, + 6717, + 941745, + 0, + 0, + 0, + 78645, + 45320, + 11193, + 1448, + 130626, + 377907, + 795535, + 24285, + 26094, + 266691, + 64449, + 77400, + 191410, + 1, + 1346, + 25224, + 489637, + 47052, + 248592, + 76689, + 0, + 7722, + 47285, + 3152, + 285577, + 0, + 149366, + 264346, + 1, + 208602, + 320459, + 131771, + 1421, + 350, + 723283, + 714934, + 0, + 566439, + 11656, + 34189, + 125484, + 943273, + 15, + 7789, + 0, + 7427, + 464278, + 680924, + 651102, + 87794, + 39640, + 838644, + 964500, + 1, + 1765, + 272604, + 10, + 837347, + 44845, + 130, + 163357, + 4150, + 403331, + 839132, + 44876, + 272792, + 592527, + 57225, + 128826, + 2915, + 2, + 3570, + 2410, + 199, + 171358, + 5931, + 53620, + 55299, + 1868, + 24123, + 165, + 346513, + 16527, + 133, + 517412, + 195700, + 730365, + 896209, + 152760, + 24577, + 65, + 8218, + 349642, + 901345, + 5127, + 5102, + 238318, + 955, + 631921, + 12218, + 55101, + 930381, + 219503, + 469237, + 132, + 16701, + 494, + 199729, + 0, + 32139, + 314, + 172, + 2947, + 106997, + 4871, + 236, + 6146, + 1843, + 128, + 0, + 254240, + 2964, + 14825, + 60624, + 2108, + 286953, + 654931, + 0, + 0, + 396587, + 19852, + 70311, + 363561, + 282, + 17966, + 924254, + 104173, + 130816, + 179096, + 105466, + 136, + 618261, + 358433, + 25587, + 49357, + 102, + 133746, + 620776, + 17084, + 406881, + 802675, + 349, + 69, + 8761, + 278482, + 16336, + 128, + 160096, + 25857, + 280, + 39639, + 726299, + 293905, + 4621, + 41, + 649, + 3655, + 269286, + 578026, + 0, + 11156, + 1, + 744858, + 531, + 48155, + 28435, + 7991, + 447, + 10201, + 379341, + 0, + 5773, + 0, + 295, + 228592, + 331155, + 104089, + 628069, + 29693, + 22, + 13, + 0, + 0, + 554349, + 6082, + 238, + 23, + 151873, + 805937, + 0, + 194076, + 6450, + 3, + 128322, + 69149, + 95511, + 86, + 844368, + 415964, + 51985, + 308686, + 553403, + 624943, + 365800, + 4, + 120263, + 91239, + 195248, + 58010, + 19, + 415112, + 136806, + 42, + 571848, + 55306, + 29454, + 3, + 144926, + 189, + 0, + 161943, + 592155, + 10930, + 279297, + 56932, + 957430, + 10244, + 190296, + 807209, + 781, + 1466, + 235055, + 33, + 196, + 58280, + 436, + 408649, + 221, + 711143, + 10495, + 2441, + 275720, + 2, + 15391, + 132107, + 102610, + 688549, + 237142, + 3041, + 14, + 308623, + 0, + 0, + 287, + 295147, + 61443, + 229, + 207, + 2051, + 64, + 13479, + 55656, + 570134, + 50387, + 225869, + 20615, + 258465, + 64932, + 112461, + 164521, + 907269, + 758563, + 22901, + 0, + 7944, + 48, + 154921, + 2784, + 548608, + 0, + 12524, + 142556, + 0, + 13882, + 507227, + 316598, + 987551, + 0, + 894687, + 1964, + 364, + 10316, + 440269, + 9, + 776723, + 72288, + 54604, + 185101, + 142, + 362, + 11679, + 77, + 79, + 529321, + 364, + 42387, + 0, + 570879, + 417503, + 604871, + 578806, + 1102, + 66584, + 615440, + 146744, + 19441, + 170478, + 144069, + 36170, + 145376, + 842283, + 193612, + 3, + 359429, + 368596, + 0, + 11064, + 7726, + 229410, + 63569, + 67402, + 91, + 203201, + 213513, + 0, + 704479, + 1325, + 0, + 385154, + 13, + 806763, + 197132, + 6183, + 45760, + 99377, + 0, + 972077, + 4043, + 195700, + 34229, + 0, + 154027, + 633, + 6, + 32142, + 0, + 29, + 620842, + 14099, + 495465, + 26937, + 0, + 0, + 432, + 227704, + 0, + 63, + 0, + 19, + 863491, + 20, + 1, + 160713, + 24607, + 85800, + 3566, + 37854, + 81913, + 121573, + 816, + 20, + 133253, + 692231, + 4869, + 255175, + 15028, + 9383, + 542877, + 4608, + 369610, + 243635, + 385285, + 391565, + 286009, + 0, + 61685, + 416318, + 208, + 67019, + 788416, + 88, + 165056, + 0, + 439589, + 160, + 105528, + 152, + 160624, + 865, + 390229, + 714086, + 6007, + 30229, + 481306, + 173266, + 1135, + 2266, + 8, + 59, + 104722, + 647885, + 579471, + 21309, + 230834, + 140278, + 31858, + 3288, + 36011, + 151387, + 594217, + 22439, + 418638, + 76859, + 29363, + 154809, + 275533, + 39, + 472996, + 22076, + 7481, + 155705, + 10406, + 214779, + 223, + 1312, + 16391, + 17203, + 55605, + 44579, + 69332, + 303, + 19217, + 26288, + 126212, + 316, + 98, + 114, + 37382, + 137591, + 439749, + 12972, + 54, + 154879, + 0, + 102680, + 7639, + 309119, + 263550, + 766, + 1124, + 56, + 686608, + 123767, + 518054, + 18, + 672385, + 3161, + 53791, + 26769, + 451670, + 61, + 148245, + 2713, + 96725, + 4794, + 33247, + 297946, + 33380, + 0, + 20034, + 5647, + 17227, + 76444, + 0, + 21011, + 675, + 13226, + 1027, + 990842, + 124459, + 34406, + 53, + 69540, + 134, + 0, + 168521, + 6, + 4075, + 1137, + 63740, + 220, + 10434, + 1171, + 28950, + 0, + 79680, + 993269, + 355622, + 15, + 0, + 1452, + 21667, + 22208, + 494484, + 33984, + 691308, + 10, + 693686, + 196, + 9, + 70676, + 157660, + 775, + 165, + 468432, + 1083, + 515154, + 778344, + 70241, + 42, + 40931, + 277125, + 43837, + 301881, + 1332, + 56712, + 9013, + 1299, + 7564, + 31092, + 1975, + 113517, + 833295, + 245021, + 36503, + 23586, + 149327, + 89175, + 10512, + 484348, + 187793, + 954609, + 53199, + 792175, + 126, + 12369, + 405, + 0, + 6614, + 322857, + 166, + 571874, + 60839, + 180975, + 146722, + 411565, + 1536, + 1, + 11, + 116230, + 60514, + 9003, + 2325, + 43763, + 63, + 355553, + 0, + 389876, + 14672, + 11526, + 160209, + 65, + 10283, + 966, + 10, + 58333, + 129920, + 2850, + 83346, + 0, + 14, + 295819, + 679550, + 143928, + 29489, + 82324, + 36558, + 267118, + 143313, + 90107, + 12789, + 951, + 0, + 187619, + 295317, + 82, + 41326, + 309682, + 907327, + 809358, + 324, + 139157, + 12, + 78366, + 671811, + 354, + 131, + 70525, + 35830, + 281018, + 91456, + 92523, + 54874, + 48273, + 2423, + 0, + 81, + 361314, + 374811, + 394758, + 15350, + 795, + 3, + 16779, + 796684, + 477556, + 73927, + 26643, + 119281, + 62692, + 17039, + 454778, + 952, + 48973, + 19529, + 151, + 239121, + 93509, + 254702, + 1307, + 10029, + 7973, + 546706, + 806644, + 680517, + 223, + 0, + 2, + 0, + 402421, + 619193, + 15685, + 2, + 939715, + 519198, + 0, + 444312, + 23204, + 35669, + 32467, + 0, + 799725, + 5883, + 2217, + 32292, + 355557, + 22179, + 1066, + 15704, + 610, + 37819, + 403626, + 83101, + 10989, + 311607, + 43394, + 72576, + 335450, + 85964, + 73734, + 105142, + 38292, + 0, + 181516, + 33959, + 611797, + 221838, + 5931, + 7666, + 1044, + 477173, + 13591, + 405, + 521, + 190653, + 184191, + 0, + 215, + 847195, + 22782, + 11912, + 27345, + 2572, + 0, + 566350, + 7, + 52302, + 26641, + 587826, + 127, + 2, + 44449, + 153198, + 14, + 926, + 285, + 0, + 938196, + 52255, + 9153, + 807, + 12548, + 358324, + 18521, + 104956, + 42738, + 116, + 135772, + 189554, + 38, + 54, + 36, + 89768, + 17170, + 75, + 34502, + 45489, + 172796, + 971810, + 16153, + 499280, + 1, + 879663, + 53830, + 186, + 539, + 242059, + 268, + 402, + 2732, + 68057, + 18463, + 198560, + 10068, + 591753, + 6116, + 699280, + 1, + 0, + 114258, + 277, + 149, + 283821, + 352561, + 88172, + 684476, + 3450, + 87, + 99936, + 3155, + 72983, + 31619, + 8832, + 58666, + 0, + 59023, + 306091, + 352150, + 255063, + 992708, + 23, + 4896, + 18165, + 424401, + 227613, + 5175, + 347, + 139846, + 11962, + 714, + 3501, + 82367, + 11110, + 10, + 12874, + 0, + 0, + 222712, + 169, + 123281, + 0, + 268149, + 101, + 17446, + 4262, + 489, + 0, + 30, + 0, + 277235, + 28, + 71, + 23, + 61219, + 953631, + 477548, + 662491, + 273, + 44787, + 4130, + 14483, + 470571, + 735977, + 406648, + 815898, + 5985, + 462696, + 937510, + 9, + 0, + 111727, + 93, + 331435, + 336402, + 78690, + 49, + 0, + 87422, + 1242, + 0, + 8783, + 8540, + 314, + 33411, + 805718, + 247, + 6870, + 523743, + 8323, + 612593, + 430, + 354048, + 264913, + 83, + 114063, + 202825, + 35202, + 32823, + 185554, + 85760, + 45159, + 5971, + 267733, + 4545, + 116, + 6910, + 24833, + 218, + 922362, + 221735, + 740, + 7112, + 31, + 15739, + 523589, + 4, + 95996, + 936, + 823951, + 0, + 88, + 160, + 375419, + 663627, + 3741, + 22896, + 114326, + 415962, + 880100, + 6222, + 18650, + 35524, + 195076, + 506, + 451640, + 541336, + 70903, + 3946, + 1, + 61765, + 1, + 2696, + 753129, + 289, + 225234, + 378692, + 1703, + 6751, + 1, + 820, + 7677, + 589, + 12412, + 317, + 69, + 226031, + 134523, + 318253, + 66677, + 111025, + 96, + 0, + 96, + 523528, + 1017, + 0, + 258740, + 420947, + 4600, + 400684, + 12174, + 11770, + 52, + 5959, + 82658, + 531787, + 202, + 548430, + 964, + 1054, + 34, + 96897, + 25445, + 47609, + 386052, + 97004, + 1935, + 30074, + 13458, + 494105, + 54, + 65575, + 594698, + 2340, + 20259, + 84, + 2774, + 534, + 972534, + 115057, + 0, + 11379, + 0, + 271, + 266305, + 132595, + 2, + 773561, + 52365, + 3585, + 351, + 148206, + 778964, + 149379, + 596, + 284914, + 2900, + 35596, + 1547, + 212027, + 8100, + 12248, + 3013, + 1814, + 183415, + 273633, + 15812, + 0, + 966680, + 14830, + 134309, + 0, + 416450, + 206611, + 816, + 82258, + 9873, + 3155, + 53485, + 779805, + 107690, + 254475, + 102504, + 72495, + 17301, + 472130, + 6895, + 245420, + 7299, + 110508, + 27776, + 246134, + 0, + 330853, + 0, + 271767, + 61886, + 24123, + 309681, + 58325, + 608865, + 20666, + 87349, + 229228, + 246, + 457768, + 5374, + 69643, + 148, + 618375, + 45236, + 352565, + 133904, + 152, + 10688, + 18, + 0, + 276036, + 493281, + 11156, + 12566, + 5762, + 113, + 24179, + 98, + 327, + 893, + 209180, + 140805, + 0, + 2341, + 66309, + 30305, + 630559, + 3682, + 152767, + 265822, + 142868, + 1535, + 728603, + 69081, + 353151, + 237995, + 1075, + 925071, + 86, + 6748, + 0, + 684186, + 735, + 13793, + 4790, + 73175, + 69677, + 367627, + 238650, + 303543, + 1, + 26059, + 21392, + 10, + 288609, + 0, + 76345, + 158496, + 7000, + 1865, + 20385, + 0, + 54213, + 9948, + 102667, + 6963, + 71, + 555744, + 5626, + 2512, + 1124, + 7171, + 628, + 29225, + 321687, + 61519, + 4, + 8352, + 9156, +}; + +char *pointers[NCYCLES]; + +int main(void) +{ + int r, i, j, sp, sq; + char *p, *q, *ep, *eq; + int ok; + int err = 0; + + for ( r = 0 ; r < 4 ; r++ ) { + for ( i = 0 ; i < NCYCLES ; i++ ) { + pointers[i] = p = malloc(sp = sizes[i]); + ep = p+sp; + ok = 1; + for ( j = 0 ; j < i ; j++ ) { + q = pointers[j]; + sq = sizes[j]; + eq = q+sq; + + if ( (p < q && ep > q) || (p >= q && p < eq) ) { + ok = 0; + err = 1; + break; + } + } + printf("Allocated %6d bytes at %p, ok = %d\n", sp, p, ok); + + if ( p ) + memset(p, 0xee, sp); /* Poison this memory */ + } + + for ( i = 0 ; i < NCYCLES ; i++ ) { + free(pointers[i]); + printf("Freed %6d bytes at %p\n", sizes[i], pointers[i]); + } + } + + return err; +} + diff --git a/klibc/klibc/tests/memstrtest.c b/klibc/klibc/tests/memstrtest.c new file mode 100644 index 0000000000..14d5173cb2 --- /dev/null +++ b/klibc/klibc/tests/memstrtest.c @@ -0,0 +1,29 @@ +#include +#include +#include + +int main(void) +{ + unsigned char t1[256], t2[256]; + int i; + int r; + + for(i = 0; i < sizeof(t1); i++) + t1[i] = t2[i] = (unsigned char)i; + + r = memcmp(t1, t2, sizeof(t1)); + printf("memcmp r = %d\n", r); + r = memcmp(t1, t2, sizeof(t1)/2); + printf("memcmp r = %d\n", r); + t1[255] = 0; + r = memcmp(t1, t2, sizeof(t1)); + printf("memcmp r = %d\n", r); + + for (i = 0; i < sizeof(t1); i++) + t1[i] = 0xaa; + memset(t2, 0xaa, sizeof(t2)); + r = memcmp(t1, t2, sizeof(t1)); + printf("memcmp r = %d\n", r); + return 0; +} + diff --git a/klibc/klibc/tests/microhello.c b/klibc/klibc/tests/microhello.c new file mode 100644 index 0000000000..e57cd05a50 --- /dev/null +++ b/klibc/klibc/tests/microhello.c @@ -0,0 +1,9 @@ +#include +#include + +int main(void) +{ + const char hello[] = "Hello, World!\n"; + _fwrite(hello, sizeof hello-1, stdout); + return 0; +} diff --git a/klibc/klibc/tests/minihello.c b/klibc/klibc/tests/minihello.c new file mode 100644 index 0000000000..7698e0666b --- /dev/null +++ b/klibc/klibc/tests/minihello.c @@ -0,0 +1,7 @@ +#include + +int main(void) +{ + fputs("Hello, World!\n", stdout); + return 0; +} diff --git a/klibc/klibc/tests/minips.c b/klibc/klibc/tests/minips.c new file mode 100644 index 0000000000..c599150858 --- /dev/null +++ b/klibc/klibc/tests/minips.c @@ -0,0 +1,452 @@ +/* + * Copyright 1998 by Albert Cahalan; all rights reserved. + * This file may be used subject to the terms and conditions of the + * GNU Library General Public License Version 2, or any later version + * at your option, as published by the Free Software Foundation. + * 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 Library General Public License for more details. + */ + +/* This is a minimal /bin/ps, designed to be smaller than the old ps + * while still supporting some of the more important features of the + * new ps. (for total size, note that this ps does not need libproc) + * It is suitable for Linux-on-a-floppy systems only. + * + * Maintainers: do not compile or install for normal systems. + * Anyone needing this will want to tweak their compiler anyway. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /* HZ */ +#include /* PAGE_SIZE */ + +static int P_euid; +static int P_pid; +static char P_cmd[16]; +static char P_state; +static int P_ppid, P_pgrp, P_session, P_tty, P_tpgid; +static unsigned long P_flags, P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime; +static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_it_real_value; +static unsigned long P_start_time, P_vsize; +static long P_rss; +static unsigned long P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip; +static unsigned P_signal, P_blocked, P_sigignore, P_sigcatch; +static unsigned long P_wchan, P_nswap, P_cnswap; + + +#if 0 +static int screen_cols = 80; +static int w_count; +#endif + +static int want_one_pid; +static const char *want_one_command; +static int select_notty; +static int select_all; + +static int ps_format; +static int old_h_option; + +/* we only pretend to support this */ +static int show_args; /* implicit with -f and all BSD options */ +static int bsd_c_option; /* this option overrides the above */ + +static int ps_argc; /* global argc */ +static char **ps_argv; /* global argv */ +static int thisarg; /* index into ps_argv */ +static char *flagptr; /* current location in ps_argv[thisarg] */ + + +#ifndef PAGE_SIZE +#warning PAGE_SIZE not defined, assuming it is 4096 +#define PAGE_SIZE 4096 +#endif + +#ifndef HZ +#warning HZ not defined, assuming it is 100 +#define HZ 100 +#endif + + + +static void usage(void){ + fprintf(stderr, + "-C select by command name (minimal ps only accepts one)\n" + "-p select by process ID (minimal ps only accepts one)\n" + "-e all processes (same as ax)\n" + "a all processes w/ tty, including other users\n" + "x processes w/o controlling ttys\n" + "-f full format\n" + "-j,j job control format\n" + "v virtual memory format\n" + "-l,l long format\n" + "u user-oriented format\n" + "-o user-defined format (limited support, only \"ps -o pid=\")\n" + "h no header\n" +/* + "-A all processes (same as ax)\n" + "c true command name\n" + "-w,w wide output\n" +*/ + ); + exit(1); +} + +/* + * Return the next argument, or call the usage function. + * This handles both: -oFOO -o FOO + */ +static const char *get_opt_arg(void){ + const char *ret; + ret = flagptr+1; /* assume argument is part of ps_argv[thisarg] */ + if(*ret) return ret; + if(++thisarg >= ps_argc) usage(); /* there is nothing left */ + /* argument is the new ps_argv[thisarg] */ + ret = ps_argv[thisarg]; + if(!ret || !*ret) usage(); + return ret; +} + + +/* return the PID, or 0 if nothing good */ +static void parse_pid(const char *str){ + char *endp; + int num; + if(!str) goto bad; + num = strtol(str, &endp, 0); + if(*endp != '\0') goto bad; + if(num<1) goto bad; + if(want_one_pid) goto bad; + want_one_pid = num; + return; +bad: + usage(); +} + +/***************** parse SysV options, including Unix98 *****************/ +static void parse_sysv_option(void){ + do{ + switch(*flagptr){ + /**** selection ****/ + case 'C': /* end */ + if(want_one_command) usage(); + want_one_command = get_opt_arg(); + return; /* can't have any more options */ + case 'p': /* end */ + parse_pid(get_opt_arg()); + return; /* can't have any more options */ + case 'A': + case 'e': + select_all++; + select_notty++; +case 'w': /* here for now, since the real one is not used */ + break; + /**** output format ****/ + case 'f': + show_args = 1; + /* FALL THROUGH */ + case 'j': + case 'l': + if(ps_format) usage(); + ps_format = *flagptr; + break; + case 'o': /* end */ + /* We only support a limited form: "ps -o pid=" (yes, just "pid=") */ + if(strcmp(get_opt_arg(),"pid=")) usage(); + if(ps_format) usage(); + ps_format = 'o'; + old_h_option++; + return; /* can't have any more options */ + /**** other stuff ****/ +#if 0 + case 'w': + w_count++; + break; +#endif + default: + usage(); + } /* switch */ + }while(*++flagptr); +} + +/************************* parse BSD options **********************/ +static void parse_bsd_option(void){ + do{ + switch(*flagptr){ + /**** selection ****/ + case 'a': + select_all++; + break; + case 'x': + select_notty++; + break; + case 'p': /* end */ + parse_pid(get_opt_arg()); + return; /* can't have any more options */ + /**** output format ****/ + case 'j': + case 'l': + case 'u': + case 'v': + if(ps_format) usage(); + ps_format = 0x80 | *flagptr; /* use 0x80 to tell BSD from SysV */ + break; + /**** other stuff ****/ + case 'c': + bsd_c_option++; +#if 0 + break; +#endif + case 'w': +#if 0 + w_count++; +#endif + break; + case 'h': + old_h_option++; + break; + default: + usage(); + } /* switch */ + }while(*++flagptr); +} + +#if 0 +/* not used yet */ +static void choose_dimensions(void){ + struct winsize ws; + char *columns; + /* screen_cols is 80 by default */ + if(ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col>30) screen_cols = ws.ws_col; + columns = getenv("COLUMNS"); + if(columns && *columns){ + long t; + char *endptr; + t = strtol(columns, &endptr, 0); + if(!*endptr && (t>30) && (t<(long)999999999)) screen_cols = (int)t; + } + if(w_count && (screen_cols<132)) screen_cols=132; + if(w_count>1) screen_cols=999999999; +} +#endif + +static void arg_parse(int argc, char *argv[]){ + int sel = 0; /* to verify option sanity */ + ps_argc = argc; + ps_argv = argv; + thisarg = 0; + /**** iterate over the args ****/ + while(++thisarg < ps_argc){ + flagptr = ps_argv[thisarg]; + switch(*flagptr){ + case '0' ... '9': + show_args = 1; + parse_pid(flagptr); + break; + case '-': + flagptr++; + parse_sysv_option(); + break; + default: + show_args = 1; + parse_bsd_option(); + break; + } + } + /**** sanity check and clean-up ****/ + if(want_one_pid) sel++; + if(want_one_command) sel++; + if(select_notty || select_all) sel++; + if(sel>1 || select_notty>1 || select_all>1 || bsd_c_option>1 || old_h_option>1) usage(); + if(bsd_c_option) show_args = 0; +} + +/* return 1 if it works, or 0 for failure */ +static int stat2proc(int pid) { + char buf[800]; /* about 40 fields, 64-bit decimal is about 20 chars */ + int num; + int fd; + char* tmp; + struct stat sb; /* stat() used to get EUID */ + snprintf(buf, 32, "/proc/%d/stat", pid); + if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0; + num = read(fd, buf, sizeof buf - 1); + fstat(fd, &sb); + P_euid = sb.st_uid; + close(fd); + if(num<80) return 0; + buf[num] = '\0'; + tmp = strrchr(buf, ')'); /* split into "PID (cmd" and "" */ + *tmp = '\0'; /* replace trailing ')' with NUL */ + /* parse these two strings separately, skipping the leading "(". */ + memset(P_cmd, 0, sizeof P_cmd); /* clear */ + sscanf(buf, "%d (%15c", &P_pid, P_cmd); /* comm[16] in kernel */ + num = sscanf(tmp + 2, /* skip space after ')' too */ + "%c " + "%d %d %d %d %d " + "%lu %lu %lu %lu %lu %lu %lu " + "%ld %ld %ld %ld %ld %ld " + "%lu %lu " + "%ld " + "%lu %lu %lu %lu %lu %lu " + "%u %u %u %u " /* no use for RT signals */ + "%lu %lu %lu", + &P_state, + &P_ppid, &P_pgrp, &P_session, &P_tty, &P_tpgid, + &P_flags, &P_min_flt, &P_cmin_flt, &P_maj_flt, &P_cmaj_flt, &P_utime, &P_stime, + &P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_it_real_value, + &P_start_time, &P_vsize, + &P_rss, + &P_rss_rlim, &P_start_code, &P_end_code, &P_start_stack, &P_kstk_esp, &P_kstk_eip, + &P_signal, &P_blocked, &P_sigignore, &P_sigcatch, + &P_wchan, &P_nswap, &P_cnswap + ); +/* fprintf(stderr, "stat2proc converted %d fields.\n",num); */ + P_vsize /= 1024; + P_rss *= (PAGE_SIZE/1024); + if(num < 30) return 0; + if(P_pid != pid) return 0; + return 1; +} + +static const char *do_time(unsigned long t){ + int hh,mm,ss; + static char buf[32]; + int cnt = 0; + t /= HZ; + ss = t%60; + t /= 60; + mm = t%60; + t /= 60; + hh = t%24; + t /= 24; + if(t) cnt = snprintf(buf, sizeof buf, "%d-", (int)t); + snprintf(cnt + buf, sizeof(buf)-cnt, "%02d:%02d:%02d", hh, mm, ss); + return buf; +} + +static void print_proc(void){ + char tty[16]; + snprintf(tty, sizeof tty, "%3d,%-3d", (P_tty>>8)&0xff, P_tty&0xff); + switch(ps_format){ + case 0: + printf("%5d %s %s", P_pid, tty, do_time(P_utime+P_stime)); + break; + case 'o': + printf("%d\n", P_pid); + return; /* don't want the command */ + case 'l': + printf( + "%03x %c %5d %5d %5d - %3d %3d - " + "%5ld %06x %s %s", + (unsigned)P_flags&0x777, P_state, P_euid, P_pid, P_ppid, + (int)P_priority, (int)P_nice, P_vsize/(PAGE_SIZE/1024), + (unsigned)(P_wchan&0xffffff), tty, do_time(P_utime+P_stime) + ); + break; + case 'f': + printf( + "%5d %5d %5d - - %s %s", + P_euid, P_pid, P_ppid, tty, do_time(P_utime+P_stime) + ); + break; + case 'j': + printf( + "%5d %5d %5d %s %s", + P_pid, P_pgrp, P_session, tty, do_time(P_utime+P_stime) + ); + break; + case 'u'|0x80: + printf( + "%5d %5d - - %5ld %5ld %s %c - %s", + P_euid, P_pid, P_vsize, P_rss, tty, P_state, + do_time(P_utime+P_stime) + ); + break; + case 'v'|0x80: + printf( + "%5d %s %c %s %6d - - %5d -", + P_pid, tty, P_state, do_time(P_utime+P_stime), (int)P_maj_flt, + (int)P_rss + ); + break; + case 'j'|0x80: + printf( + "%5d %5d %5d %5d %s %5d %c %5d %s", + P_ppid, P_pid, P_pgrp, P_session, tty, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime) + ); + break; + case 'l'|0x80: + printf( + "%03x %5d %5d %5d %3d %3d " + "%5ld %4ld %06x %c %s %s", + (unsigned)P_flags&0x777, P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice, + P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, tty, do_time(P_utime+P_stime) + ); + break; + default: + } + if(show_args) printf(" [%s]\n", P_cmd); + else printf(" %s\n", P_cmd); +} + + +int main(int argc, char *argv[]){ + arg_parse(argc, argv); +#if 0 + choose_dimensions(); +#endif + if(!old_h_option){ + const char *head; + switch(ps_format){ + default: /* can't happen */ + case 0: head = " PID TTY TIME CMD"; break; + case 'l': head = " F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD"; break; + case 'f': head = " UID PID PPID C STIME TTY TIME CMD"; break; + case 'j': head = " PID PGID SID TTY TIME CMD"; break; + case 'u'|0x80: head = " UID PID %CPU %MEM VSZ RSS TTY S START TIME COMMAND"; break; + case 'v'|0x80: head = " PID TTY S TIME MAJFL TRS DRS RSS %MEM COMMAND"; break; + case 'j'|0x80: head = " PPID PID PGID SID TTY TPGID S UID TIME COMMAND"; break; + case 'l'|0x80: head = " F UID PID PPID PRI NI VSZ RSS WCHAN S TTY TIME COMMAND"; break; + } + printf("%s\n",head); + } + if(want_one_pid){ + if(stat2proc(want_one_pid)) print_proc(); + else exit(1); + }else{ + struct dirent *ent; /* dirent handle */ + DIR *dir; + int ouruid; + int found_a_proc; + found_a_proc = 0; + ouruid = getuid(); + dir = opendir("/proc"); + while(( ent = readdir(dir) )){ + if(*ent->d_name<'0' || *ent->d_name>'9') continue; + if(!stat2proc(atoi(ent->d_name))) continue; + if(want_one_command){ + if(strcmp(want_one_command,P_cmd)) continue; + }else{ + if(!select_notty && P_tty==-1) continue; + if(!select_all && P_euid!=ouruid) continue; + } + found_a_proc++; + print_proc(); + } + closedir(dir); + exit(!found_a_proc); + } + return 0; +} diff --git a/klibc/klibc/tests/nfs_no_rpc.c b/klibc/klibc/tests/nfs_no_rpc.c new file mode 100644 index 0000000000..11b9f61fea --- /dev/null +++ b/klibc/klibc/tests/nfs_no_rpc.c @@ -0,0 +1,538 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Default path we try to mount. "%s" gets replaced by our IP address */ +#define NFS_ROOT "/tftpboot/%s" +#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096 +#define NFS_MAXPATHLEN 1024 +#define NFS_MNT_PROGRAM 100005 +#define NFS_MNT_PORT 627 +#define NFS_PROGRAM 100003 +#define NFS_PORT 2049 +#define NFS2_VERSION 2 +#define NFS3_VERSION 3 +#define NFS_MNT_PROGRAM 100005 +#define NFS_MNT_VERSION 1 +#define NFS_MNT3_VERSION 3 +#define MNTPROC_MNT 1 +#define MOUNTPROC3_MNT 1 +#define RPC_PMAP_PROGRAM 100000 +#define RPC_PMAP_VERSION 2 +#define RPC_PMAP_PORT 111 + +#define NFS2_FHSIZE 32 +#define NFS3_FHSIZE 64 + +#define RPC_VERSION 2 + +enum rpc_msg_type { + RPC_CALL = 0, + RPC_REPLY = 1 +}; + +enum rpc_auth_flavor { + RPC_AUTH_NULL = 0, + RPC_AUTH_UNIX = 1, + RPC_AUTH_SHORT = 2, + RPC_AUTH_DES = 3, + RPC_AUTH_KRB = 4, +}; + +enum rpc_reply_stat { + RPC_MSG_ACCEPTED = 0, + RPC_MSG_DENIED = 1 +}; + +#define NFS_MAXFHSIZE 64 +struct nfs_fh { + unsigned short size; + unsigned char data[NFS_MAXFHSIZE]; +}; + +struct nfs2_fh { + char data[NFS2_FHSIZE]; +}; + +#define NFS_MOUNT_VERSION 4 + +struct nfs_mount_data { + int version; + int fd; + struct nfs2_fh old_root; + int flags; + int rsize; + int wsize; + int timeo; + int retrans; + int acregmin; + int acregmax; + int acdirmin; + int acdirmax; + struct sockaddr_in addr; + char hostname[256]; + int namlen; + unsigned int bsize; + struct nfs_fh root; +}; + +#define NFS_MOUNT_SOFT 0x0001 /* 1 */ +#define NFS_MOUNT_INTR 0x0002 /* 1 */ +#define NFS_MOUNT_SECURE 0x0004 /* 1 */ +#define NFS_MOUNT_POSIX 0x0008 /* 1 */ +#define NFS_MOUNT_NOCTO 0x0010 /* 1 */ +#define NFS_MOUNT_NOAC 0x0020 /* 1 */ +#define NFS_MOUNT_TCP 0x0040 /* 2 */ +#define NFS_MOUNT_VER3 0x0080 /* 3 */ +#define NFS_MOUNT_KERBEROS 0x0100 /* 3 */ +#define NFS_MOUNT_NONLM 0x0200 /* 3 */ +#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */ +#define NFS_MOUNT_FLAGMASK 0xFFFF + +static char nfs_root_name[256]; +static u_int32_t root_server_addr; +static char root_server_path[256]; + +/* Address of NFS server */ +static u_int32_t servaddr; + +/* Name of directory to mount */ +static char nfs_path[NFS_MAXPATHLEN]; + +/* NFS-related data */ +static struct nfs_mount_data nfs_data = { + .version = NFS_MOUNT_VERSION, + .flags = NFS_MOUNT_NONLM, /* No lockd in nfs root yet */ + .rsize = NFS_DEF_FILE_IO_BUFFER_SIZE, + .wsize = NFS_DEF_FILE_IO_BUFFER_SIZE, + .bsize = 0, + .timeo = 7, + .retrans = 3, + .acregmin = 3, + .acregmax = 60, + .acdirmin = 30, + .acdirmax = 60, +}; +static int nfs_port = -1; +static int mount_port; + +/*************************************************************************** + + Parsing of options + + ***************************************************************************/ + +/* + * The following integer options are recognized + */ +static struct nfs_int_opts { + const char *name; + int *val; +} root_int_opts[] = { + { "port", &nfs_port }, + { "rsize", &nfs_data.rsize }, + { "wsize", &nfs_data.wsize }, + { "timeo", &nfs_data.timeo }, + { "retrans", &nfs_data.retrans }, + { "acregmin", &nfs_data.acregmin }, + { "acregmax", &nfs_data.acregmax }, + { "acdirmin", &nfs_data.acdirmin }, + { "acdirmax", &nfs_data.acdirmax }, + { NULL, NULL } +}; + +/* + * And now the flag options + */ +static struct nfs_bool_opts { + const char *name; + int and_mask; + int or_mask; +} root_bool_opts[] = { + { "soft", ~NFS_MOUNT_SOFT, NFS_MOUNT_SOFT }, + { "hard", ~NFS_MOUNT_SOFT, 0 }, + { "intr", ~NFS_MOUNT_INTR, NFS_MOUNT_INTR }, + { "nointr", ~NFS_MOUNT_INTR, 0 }, + { "posix", ~NFS_MOUNT_POSIX, NFS_MOUNT_POSIX }, + { "noposix", ~NFS_MOUNT_POSIX, 0 }, + { "cto", ~NFS_MOUNT_NOCTO, 0 }, + { "nocto", ~NFS_MOUNT_NOCTO, NFS_MOUNT_NOCTO }, + { "ac", ~NFS_MOUNT_NOAC, 0 }, + { "noac", ~NFS_MOUNT_NOAC, NFS_MOUNT_NOAC }, + { "lock", ~NFS_MOUNT_NONLM, 0 }, + { "nolock", ~NFS_MOUNT_NONLM, NFS_MOUNT_NONLM }, +#ifdef CONFIG_NFS_V3 + { "v2", ~NFS_MOUNT_VER3, 0 }, + { "v3", ~NFS_MOUNT_VER3, NFS_MOUNT_VER3 }, +#endif + { "udp", ~NFS_MOUNT_TCP, 0 }, + { "tcp", ~NFS_MOUNT_TCP, NFS_MOUNT_TCP }, + { "broken_suid",~NFS_MOUNT_BROKEN_SUID, NFS_MOUNT_BROKEN_SUID }, + { NULL, 0, 0 } +}; +/* + * Parse option string. + */ +static void root_nfs_parse(char *name, char *buf) +{ + char *options, *val, *cp; + + if ((options = strchr(name, ','))) { + *options++ = 0; + cp = strtok(options, ","); + while (cp) { + if ((val = strchr(cp, '='))) { + struct nfs_int_opts *opts = root_int_opts; + *val++ = '\0'; + while (opts->name && strcmp(opts->name, cp)) + opts++; + if (opts->name) + *(opts->val) = (int) strtoul(val, NULL, 10); + } else { + struct nfs_bool_opts *opts = root_bool_opts; + while (opts->name && strcmp(opts->name, cp)) + opts++; + if (opts->name) { + nfs_data.flags &= opts->and_mask; + nfs_data.flags |= opts->or_mask; + } + } + cp = strtok(NULL, ","); + } + } + if (name[0] && strcmp(name, "default")) { + strncpy(buf, name, NFS_MAXPATHLEN-1); + buf[NFS_MAXPATHLEN-1] = 0; + } +} + +/* + * Prepare the NFS data structure and parse all options. + */ +static int root_nfs_name(char *name) +{ + char buf[NFS_MAXPATHLEN]; + struct utsname uname_buf; + + /* Set some default values */ + strcpy(buf, NFS_ROOT); + + /* Process options received from the remote server */ + root_nfs_parse(root_server_path, buf); + + /* Override them by options set on kernel command-line */ + root_nfs_parse(name, buf); + + uname(&uname_buf); + if (strlen(buf) + strlen(uname_buf.nodename) > NFS_MAXPATHLEN) { + printf("nfsroot: Pathname for remote directory too long.\n"); + return -1; + } + sprintf(nfs_path, buf, uname_buf.nodename); + + return 1; +} + +/*************************************************************************** + + Routines to actually mount the root directory + + ***************************************************************************/ + +/* + * Construct sockaddr_in from address and port number. + */ +static inline void +set_sockaddr(struct sockaddr_in *sin, u_int32_t addr, u_int16_t port) +{ + memset(sin, 0, sizeof(*sin)); + sin->sin_family = AF_INET; + sin->sin_addr.s_addr = addr; + sin->sin_port = port; +} + +/* + * Extremely crude RPC-over-UDP call. We get an already encoded request + * to pass, we do that and put the reply into buffer. That (and callers + * below - getport, getfh2 and getfh3) should be replaced with proper + * librpc use. Now, if we only had one that wasn't bloated as a dead + * gnu that had lied for a while under the sun... + */ + +static u_int32_t XID; +static int flag; +static void timeout(int n) +{ + (void)n; + flag = 1; +} +static int do_call(struct sockaddr_in *sin, u_int32_t msg[], u_int32_t rmsg[], + u_int32_t len, u_int32_t rlen) +{ + struct sockaddr_in from; + int slen = sizeof(struct sockaddr_in); + struct timeval tv = {1, 0}; + int n; + int fd; + + signal(SIGALRM, timeout); + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0) + goto Esocket; + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (void*)&tv, sizeof(tv)); + len *= 4; + if (sendto(fd, msg, len, 0, (struct sockaddr *)sin, slen)!=(int)len) + goto Esend; + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, sizeof(tv)); + alarm(0); + flag = 0; + alarm(5); + rlen *= 4; + do { + slen = sizeof(from); + n = recvfrom(fd, rmsg, rlen, 0, (struct sockaddr*)&from, &slen); + if (flag || n < 0) + goto Erecv; + } while (memcmp(&from, sin, sizeof(from)) || rmsg[0] != msg[0]); + + if (n < 6*4 || n % 4 || ntohl(rmsg[1]) != 1 || rmsg[2] || + rmsg[3] || rmsg[4] || rmsg[5]) + goto Einval; + alarm(0); + close(fd); + return n / 4 - 6; + +Esend: printf("rpc: write failed\n"); + goto out; +Erecv: printf("rpc: read failed\n"); + goto out; +Einval: printf("rpc: invalid response\n"); + goto out; +Esocket:printf("rpc: can't create socket\n"); + return -1; +out: + alarm(0); + close(fd); + return -1; +} + +enum { + PMAP_GETPORT = 3 +}; + +static void do_header(u_int32_t msg[], u_int32_t prog, u_int32_t vers, u_int32_t proc) +{ + msg[0] = XID++; + msg[1] = htonl(RPC_CALL); + msg[2] = htonl(RPC_VERSION); + msg[3] = htonl(prog); + msg[4] = htonl(vers); + msg[5] = htonl(proc); + msg[6] = htonl(RPC_AUTH_NULL); + msg[7] = htonl(0); + msg[8] = htonl(RPC_AUTH_NULL); + msg[9] = htonl(0); +} + +static int getport(u_int32_t prog, u_int32_t vers, u_int32_t prot) +{ + struct sockaddr_in sin; + unsigned msg[14]; + unsigned rmsg[7]; + int n; + set_sockaddr(&sin, servaddr, htons(RPC_PMAP_PORT)); + do_header(msg, RPC_PMAP_PROGRAM, RPC_PMAP_VERSION, PMAP_GETPORT); + msg[10] = htonl(prog); + msg[11] = htonl(vers); + msg[12] = htonl(prot); + msg[13] = htonl(0); + n = do_call(&sin, msg, rmsg, 14, 7); + if (n <= 0) + return -1; + else + return ntohl(rmsg[6]); +} + +static int getfh2(void) +{ + struct sockaddr_in sin; + unsigned msg[10+1+256/4]; + unsigned rmsg[6 + 1 + NFS2_FHSIZE/4]; + int n; + int len = strlen(nfs_path); + set_sockaddr(&sin, servaddr, mount_port); + + if (len > 255) { + printf("nfsroot: pathname is too long"); + return -1; + } + memset(msg, 0, sizeof(msg)); + do_header(msg, NFS_MNT_PROGRAM, NFS_MNT_VERSION, MNTPROC_MNT); + msg[10] = htonl(len); + strcpy((char*)&msg[11], nfs_path); + n = do_call(&sin, msg, rmsg, 11 + (len + 3)/4, 7 + NFS2_FHSIZE/4); + if (n < 0) + return -1; + if (n != NFS2_FHSIZE/4 + 1) + goto Esize; + if (rmsg[6]) { + printf("nfsroot: mountd returned an error (%d)",htonl(rmsg[6])); + return -1; + } + nfs_data.root.size = NFS2_FHSIZE; + memcpy(nfs_data.root.data, &rmsg[7], NFS2_FHSIZE); + return 0; +Esize: + printf("nfsroot: bad fhandle size"); + return -1; +} + +static int getfh3(void) +{ + struct sockaddr_in sin; + unsigned msg[10+1+256/4]; + unsigned rmsg[6 + 1 + 1 + NFS3_FHSIZE/4]; + int n; + int len = strlen(nfs_path); + int size; + set_sockaddr(&sin, servaddr, mount_port); + + if (len > 255) { + printf("nfsroot: pathname is too long"); + return -1; + } + memset(msg, 0, sizeof(msg)); + do_header(msg, NFS_MNT_PROGRAM, NFS_MNT3_VERSION, MOUNTPROC3_MNT); + msg[10] = htonl(len); + strcpy((char*)&msg[11], nfs_path); + n = do_call(&sin, msg, rmsg, 11 + (len + 3)/4, 8 + NFS3_FHSIZE/4); + if (n < 0) + return -1; + if (n <= 2) + goto Esize; + if (rmsg[6]) { + printf("nfsroot: mountd returned an error (%d)",htonl(rmsg[6])); + return -1; + } + size = ntohl(rmsg[7]); + if (size > NFS3_FHSIZE || n != 2 + size/4) + goto Esize; + nfs_data.root.size = size; + memcpy(nfs_data.root.data, &rmsg[8], size); + return 0; +Esize: + printf("nfsroot: bad fhandle size"); + return -1; +} + +/* + * Use portmapper to find mountd and nfsd port numbers if not overriden + * by the user. Use defaults if portmapper is not available. + * XXX: Is there any nfs server with no portmapper? + */ +static int root_nfs_ports(void) +{ + int port; + int nfsd_ver, mountd_ver; + int proto; + + if (nfs_data.flags & NFS_MOUNT_VER3) { + nfsd_ver = NFS3_VERSION; + mountd_ver = NFS_MNT3_VERSION; + } else { + nfsd_ver = NFS2_VERSION; + mountd_ver = NFS_MNT_VERSION; + } + + proto = (nfs_data.flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; + + if (nfs_port < 0) { + if ((port = getport(NFS_PROGRAM, nfsd_ver, proto)) < 0) { + printf("nfsroot: Unable to get nfsd port " + "number from server, using default\n"); + port = NFS_PORT; + } + nfs_port = htons(port); + printf("nfsroot: Portmapper on server returned %d " + "as nfsd port\n", port); + } + + if ((port = getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { + printf("nfsroot: Unable to get mountd port " + "number from server, using default\n"); + port = NFS_MNT_PORT; + } + mount_port = htons(port); + printf("nfsroot: mountd port is %d\n", port); + + return 0; +} + +int main(void) +{ + unsigned char *p; + struct timeval tv; + char *s; + + /* FIX: use getopt() instead of this */ + + s = getenv("root_server_addr"); + if (s) + root_server_addr = strtoul(s, NULL, 10); + s = getenv("root_server_path"); + if (s) + strncpy(root_server_path, s, 255); + s = getenv("nfs_root_name"); + if (s) + strncpy(nfs_root_name, s, 255); + + /* + * Decode the root directory path name and NFS options from + * the kernel command line. This has to go here in order to + * be able to use the client IP address for the remote root + * directory (necessary for pure RARP booting). + */ + if (root_nfs_name(nfs_root_name) < 0) + return 0; + if ((servaddr = root_server_addr) == INADDR_NONE) { + printf("nfsroot: No NFS server available, giving up.\n"); + return 0; + } + + p = (char *) &servaddr; + sprintf(nfs_data.hostname, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + +#ifdef NFSROOT_DEBUG + printf("nfsroot: Mounting %s on server %s as root\n", + nfs_path, nfs_data.hostname); + printf("nfsroot: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n", + nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans); + printf("nfsroot: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n", + nfs_data.acregmin, nfs_data.acregmax, + nfs_data.acdirmin, nfs_data.acdirmax); + printf("nfsroot: nfsd port = %d, mountd port = %d, flags = %08x\n", + nfs_port, mount_port, nfs_data.flags); +#endif + + gettimeofday(&tv, NULL); + XID = (tv.tv_sec << 15) ^ tv.tv_usec; + + if (root_nfs_ports() < 0) + return 0; + if (nfs_data.flags & NFS_MOUNT_VER3) { + if (getfh3()) + return 0; + } else { + if (getfh2()) + return 0; + } + set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port); + return mount("/dev/root", "/mnt", "nfs", 0, &nfs_data) == 0; +} diff --git a/klibc/klibc/tests/setjmptest.c b/klibc/klibc/tests/setjmptest.c new file mode 100644 index 0000000000..a199eedab8 --- /dev/null +++ b/klibc/klibc/tests/setjmptest.c @@ -0,0 +1,36 @@ +/* + * setjmptest.c + */ + +#include +#include + +static jmp_buf buf; + +void do_stuff(int v) +{ + printf("setjmp returned %d\n", v); + longjmp(buf, v+1); +} + +void recurse(int ctr, int v) +{ + if ( ctr-- ) { + recurse(ctr, v); + } else { + do_stuff(v); + } + _fwrite(".", 1, stdout); +} + +int main(void) +{ + int v; + + v = setjmp(buf); + + if ( v < 256 ) + recurse(v,v); + + return 0; +} diff --git a/klibc/klibc/tests/testrand48.c b/klibc/klibc/tests/testrand48.c new file mode 100644 index 0000000000..bf046b6bda --- /dev/null +++ b/klibc/klibc/tests/testrand48.c @@ -0,0 +1,19 @@ +#include +#include + +int main(void) +{ + unsigned short seed1[] = { 0x1234, 0x5678, 0x9abc }; + unsigned short *oldseed; + + oldseed = seed48(seed1); + printf("Initial seed: %#06x %#06x %#06x\n", + oldseed[0], oldseed[1], oldseed[2]); + + printf("lrand48() = %ld\n", lrand48()); + + seed48(seed1); + printf("mrand48() = %ld\n", mrand48()); + + return 1; +} diff --git a/klibc/klibc/tests/testvsnp.c b/klibc/klibc/tests/testvsnp.c new file mode 100644 index 0000000000..c86e8b30fb --- /dev/null +++ b/klibc/klibc/tests/testvsnp.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include +#include + +int main(void) +{ + int r, i; + char buffer[512]; + + r = snprintf(buffer, 512, "Hello, %d", 37); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'d", 37373737); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'x", 0xdeadbeef); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'#X", 0xdeadbeef); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'#llo", 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + /* Make sure overflow works correctly */ + memset(buffer, '\xff', 512); + r = snprintf(buffer, 16, "Hello, %'#llo", 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + for ( i = 16 ; i < 512 ; i++ ) + assert ( buffer[i] == '\xff' ); + + r = snprintf(buffer, 512, "Hello, %'#40.20llo", 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'#-40.20llo", 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'#*.*llo", 40, 20, 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'#*.*llo", -40, 20, 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'#*.*llo", -40, -20, 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %'#*.*llx", -40, -20, 0123456701234567ULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %p", &buffer); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %P", &buffer); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %20p", &buffer); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %-20p", &buffer); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 512, "Hello, %-20p", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 20, "Hello, %'-20p", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 15, "Hello, %'-20p", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 3, "Hello, %'-20p", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + /* This shouldn't change buffer in any way! */ + r = snprintf(buffer, 0, "Hello, %'-20p", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + for ( i = -30 ; i <= 30 ; i++ ) { + r = snprintf(buffer, 40, "Hello, %'*p", i, NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + } + + r = snprintf(buffer, 40, "Hello, %'-20s", "String"); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'20s", "String"); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'020s", "String"); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'-20s", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'20s", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'020s", NULL); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'-20c", '*'); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'20c", '*'); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + r = snprintf(buffer, 40, "Hello, %'020c", '*'); + printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); + + return 0; +} + diff --git a/klibc/klibc/time.c b/klibc/klibc/time.c new file mode 100644 index 0000000000..8f6e89738d --- /dev/null +++ b/klibc/klibc/time.c @@ -0,0 +1,27 @@ +/* + * time.c + */ + +#include +#include +#include + +#ifdef __NR_time + +_syscall1(time_t,time,time_t *,t); + +#else + +time_t time(time_t *t) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + + if ( t ) + *t = (time_t)tv.tv_sec; + + return (time_t)tv.tv_sec; +} + +#endif diff --git a/klibc/klibc/umount.c b/klibc/klibc/umount.c new file mode 100644 index 0000000000..9a8e62a779 --- /dev/null +++ b/klibc/klibc/umount.c @@ -0,0 +1,12 @@ +/* + * umount.c + * + * Single-argument form of umount + */ + +#include + +int umount(const char *dir) +{ + return umount2(dir, 0); +} diff --git a/klibc/klibc/unsetenv.c b/klibc/klibc/unsetenv.c new file mode 100644 index 0000000000..5f39f3d8f9 --- /dev/null +++ b/klibc/klibc/unsetenv.c @@ -0,0 +1,40 @@ +/* + * unsetenv.c + */ + +#include +#include +#include +#include + +int unsetenv(const char *name) +{ + size_t len; + char **p, *q; + const char *z; + + if ( !name || !name[0] ) { + errno = EINVAL; + return -1; + } + + len = 0; + for ( z = name ; *z ; z++ ) { + len++; + if ( *z == '=' ) { + errno = EINVAL; + return -1; + } + } + + for ( p = environ ; (q = *p) ; p++ ) { + if ( !strncmp(name,q,len) && q[len] == '=' ) + break; + } + + for ( ; (q = *p) ; p++ ) { + p[0] = p[1]; + } + + return 0; +} diff --git a/klibc/klibc/usleep.c b/klibc/klibc/usleep.c new file mode 100644 index 0000000000..b63352eebf --- /dev/null +++ b/klibc/klibc/usleep.c @@ -0,0 +1,15 @@ +/* + * usleep.c + */ + +#include +#include + +void usleep(unsigned long usec) +{ + struct timespec ts; + + ts.tv_sec = usec/1000000UL; + ts.tv_nsec = (usec%1000000UL) * 1000; + while ( nanosleep(&ts,&ts) == -1 && errno == EINTR ); +} diff --git a/klibc/klibc/utime.c b/klibc/klibc/utime.c new file mode 100644 index 0000000000..a00b589629 --- /dev/null +++ b/klibc/klibc/utime.c @@ -0,0 +1,30 @@ +/* + * utime.c + */ + +#include +#include +#include +#include + +#ifdef __NR_utime + +_syscall2(int,utime,const char *,filename,const struct utimbuf *,buf); + +#else + +static inline _syscall2(int,utimes,const char *,filename, const struct timeval *,tvp); + +int utime(const char *filename, const struct utimbuf *buf) +{ + struct timeval tvp[2]; + + tvp[0].tv_sec = buf->actime; + tvp[0].tv_usec = 0; + tvp[1].tv_sec = buf->modtime; + tvp[1].tv_usec = 0; + + return utimes(filename, tvp); +} + +#endif diff --git a/klibc/klibc/vfprintf.c b/klibc/klibc/vfprintf.c new file mode 100644 index 0000000000..39cf9838f6 --- /dev/null +++ b/klibc/klibc/vfprintf.c @@ -0,0 +1,26 @@ +/* + * vfprintf.c + */ + +#include +#include +#include +#include + +#define BUFFER_SIZE 32768 + +int vfprintf(FILE *file, const char *format, va_list ap) +{ + int rv; + char buffer[BUFFER_SIZE]; + + rv = vsnprintf(buffer, BUFFER_SIZE, format, ap); + + if ( rv < 0 ) + return rv; + + if ( rv > BUFFER_SIZE-1 ) + rv = BUFFER_SIZE-1; + + return _fwrite(buffer, rv, file); +} diff --git a/klibc/klibc/vprintf.c b/klibc/klibc/vprintf.c new file mode 100644 index 0000000000..7d6066586f --- /dev/null +++ b/klibc/klibc/vprintf.c @@ -0,0 +1,11 @@ +/* + * vprintf.c + */ + +#include +#include + +int vprintf(const char *format, va_list ap) +{ + return vfprintf(stdout, format, ap); +} diff --git a/klibc/klibc/vsnprintf.c b/klibc/klibc/vsnprintf.c new file mode 100644 index 0000000000..5cb9331954 --- /dev/null +++ b/klibc/klibc/vsnprintf.c @@ -0,0 +1,433 @@ +/* + * vsnprintf.c + * + * vsnprintf(), from which the rest of the printf() + * family is built + */ + +#include +#include +#include +#include +#include +#include + +enum flags { + FL_ZERO = 0x01, /* Zero modifier */ + FL_MINUS = 0x02, /* Minus modifier */ + FL_PLUS = 0x04, /* Plus modifier */ + FL_TICK = 0x08, /* ' modifier */ + FL_SPACE = 0x10, /* Space modifier */ + FL_HASH = 0x20, /* # modifier */ + FL_SIGNED = 0x40, /* Number is signed */ + FL_UPPER = 0x80 /* Upper case digits */ +}; + +/* These may have to be adjusted on certain implementations */ +enum ranks { + rank_char = -2, + rank_short = -1, + rank_int = 0, + rank_long = 1, + rank_longlong = 2 +}; + +#define MIN_RANK rank_char +#define MAX_RANK rank_longlong + +#define INTMAX_RANK rank_longlong +#define SIZE_T_RANK rank_long +#define PTRDIFF_T_RANK rank_long + +#define EMIT(x) ({ if (o nchars ) { + while ( width > nchars ) { + EMIT(' '); + width--; + } + } + + /* Emit nondigits */ + if ( minus ) + EMIT('-'); + else if ( flags & FL_PLUS ) + EMIT('+'); + else if ( flags & FL_SPACE ) + EMIT(' '); + + if ( (flags & FL_HASH) && base == 16 ) { + EMIT('0'); + EMIT((flags & FL_UPPER) ? 'X' : 'x'); + } + + /* Emit zero padding */ + if ( (flags & (FL_MINUS|FL_ZERO)) == FL_ZERO && width > ndigits ) { + while ( width > nchars ) { + EMIT('0'); + width--; + } + } + + /* Generate the number. This is done from right to left. */ + q += ndigits; /* Advance the pointer to end of number */ + o += ndigits; + qq = q; oo = o; /* Temporary values */ + + b4tick = tickskip; + while ( ndigits > 0 ) { + if ( !b4tick-- ) { + qq--; oo--; ndigits--; + if ( oo < n ) *qq = '_'; + b4tick = tickskip-1; + } + qq--; oo--; ndigits--; + if ( oo < n ) *qq = digits[val%base]; + val /= base; + } + + /* Emit late space padding */ + while ( (flags & FL_MINUS) && width > nchars ) { + EMIT(' '); + width--; + } + + return o; +} + + +int vsnprintf(char *buffer, size_t n, const char *format, va_list ap) +{ + const char *p = format; + char ch; + char *q = buffer; + size_t o = 0; /* Number of characters output */ + uintmax_t val = 0; + int rank = rank_int; /* Default rank */ + int width = 0; + int prec = -1; + int base; + size_t sz; + enum flags flags = 0; + enum { + st_normal, /* Ground state */ + st_flags, /* Special flags */ + st_width, /* Field width */ + st_prec, /* Field precision */ + st_modifiers /* Length or conversion modifiers */ + } state = st_normal; + const char *sarg; /* %s string argument */ + char carg; /* %c char argument */ + int slen; /* String length */ + + while ( (ch = *p++) ) { + switch ( state ) { + case st_normal: + if ( ch == '%' ) { + state = st_flags; + flags = 0; rank = rank_int; width = 0; prec = -1; + } else { + EMIT(ch); + } + break; + + case st_flags: + switch ( ch ) { + case '-': + flags |= FL_MINUS; + break; + case '+': + flags |= FL_PLUS; + break; + case '\'': + flags |= FL_TICK; + break; + case ' ': + flags |= FL_SPACE; + break; + case '#': + flags |= FL_HASH; + break; + case '0': + flags |= FL_ZERO; + break; + default: + state = st_width; + p--; /* Process this character again */ + break; + } + break; + + case st_width: + if ( ch >= '0' && ch <= '9' ) { + width = width*10+(ch-'0'); + } else if ( ch == '*' ) { + width = va_arg(ap, int); + if ( width < 0 ) { + width = -width; + flags |= FL_MINUS; + } + } else if ( ch == '.' ) { + prec = 0; /* Precision given */ + state = st_prec; + } else { + state = st_modifiers; + p--; /* Process this character again */ + } + break; + + case st_prec: + if ( ch >= '0' && ch <= '9' ) { + prec = prec*10+(ch-'0'); + } else if ( ch == '*' ) { + prec = va_arg(ap, int); + if ( prec < 0 ) + prec = -1; + } else { + state = st_modifiers; + p--; /* Process this character again */ + } + break; + + case st_modifiers: + switch ( ch ) { + /* Length modifiers - nonterminal sequences */ + case 'h': + rank--; /* Shorter rank */ + break; + case 'l': + rank++; /* Longer rank */ + break; + case 'j': + rank = INTMAX_RANK; + break; + case 'z': + rank = SIZE_T_RANK; + break; + case 't': + rank = PTRDIFF_T_RANK; + break; + case 'L': + case 'q': + rank += 2; + break; + default: + /* Output modifiers - terminal sequences */ + state = st_normal; /* Next state will be normal */ + if ( rank < MIN_RANK ) /* Canonicalize rank */ + rank = MIN_RANK; + else if ( rank > MAX_RANK ) + rank = MAX_RANK; + + switch ( ch ) { + case 'P': /* Upper case pointer */ + flags |= FL_UPPER; + /* fall through */ + case 'p': /* Pointer */ + base = 16; + prec = (CHAR_BIT*sizeof(void *)+3)/4; + flags |= FL_HASH; + val = (uintmax_t)(uintptr_t)va_arg(ap, void *); + goto is_integer; + + case 'd': /* Signed decimal output */ + case 'i': + base = 10; + flags |= FL_SIGNED; + switch (rank) { + case rank_char: + /* Yes, all these casts are needed... */ + val = (uintmax_t)(intmax_t)(signed char)va_arg(ap, signed int); + break; + case rank_short: + val = (uintmax_t)(intmax_t)(signed short)va_arg(ap, signed int); + break; + case rank_int: + val = (uintmax_t)(intmax_t)va_arg(ap, signed int); + break; + case rank_long: + val = (uintmax_t)(intmax_t)va_arg(ap, signed long); + break; + case rank_longlong: + val = (uintmax_t)(intmax_t)va_arg(ap, signed long long); + break; + } + goto is_integer; + case 'o': /* Octal */ + base = 8; + goto is_unsigned; + case 'u': /* Unsigned decimal */ + base = 10; + goto is_unsigned; + case 'X': /* Upper case hexadecimal */ + flags |= FL_UPPER; + /* fall through */ + case 'x': /* Hexadecimal */ + base = 16; + goto is_unsigned; + + is_unsigned: + switch (rank) { + case rank_char: + val = (uintmax_t)(unsigned char)va_arg(ap, unsigned int); + break; + case rank_short: + val = (uintmax_t)(unsigned short)va_arg(ap, unsigned int); + break; + case rank_int: + val = (uintmax_t)va_arg(ap, unsigned int); + break; + case rank_long: + val = (uintmax_t)va_arg(ap, unsigned long); + break; + case rank_longlong: + val = (uintmax_t)va_arg(ap, unsigned long long); + break; + } + /* fall through */ + + is_integer: + sz = format_int(q, (o prec ) + slen = prec; + + if ( width > slen && !(flags & FL_MINUS) ) { + char pad = (flags & FL_ZERO) ? '0' : ' '; + while ( width > slen ) { + EMIT(pad); + width--; + } + } + for ( i = slen ; i ; i-- ) { + sch = *sarg++; + EMIT(sch); + } + if ( width > slen && (flags & FL_MINUS) ) { + while ( width > slen ) { + EMIT(' '); + width--; + } + } + } + break; + + case 'n': /* Output the number of characters written */ + { + switch (rank) { + case rank_char: + *va_arg(ap, signed char *) = o; + break; + case rank_short: + *va_arg(ap, signed short *) = o; + break; + case rank_int: + *va_arg(ap, signed int *) = o; + break; + case rank_long: + *va_arg(ap, signed long *) = o; + break; + case rank_longlong: + *va_arg(ap, signed long long *) = o; + break; + } + } + break; + + default: /* Anything else, including % */ + EMIT(ch); + break; + } + } + } + } + + /* Null-terminate the string */ + if ( o0 ) + buffer[n-1] = '\0'; /* Overflow - terminate at end of buffer */ + + return o; +} diff --git a/klibc/klibc/vsprintf.c b/klibc/klibc/vsprintf.c new file mode 100644 index 0000000000..4a6100e70c --- /dev/null +++ b/klibc/klibc/vsprintf.c @@ -0,0 +1,11 @@ +/* + * vsprintf.c + */ + +#include +#include + +int vsprintf(char *buffer, const char *format, va_list ap) +{ + return vsnprintf(buffer, ~(size_t)0, format, ap); +} diff --git a/klibc/klibc/vsscanf.c b/klibc/klibc/vsscanf.c new file mode 100644 index 0000000000..12a82b2747 --- /dev/null +++ b/klibc/klibc/vsscanf.c @@ -0,0 +1,365 @@ +/* + * vsscanf.c + * + * vsscanf(), from which the rest of the scanf() + * family is built + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifndef LONG_BIT +#define LONG_BIT (CHAR_BIT*sizeof(long)) +#endif + +enum flags { + FL_SPLAT = 0x01, /* Drop the value, do not assign */ + FL_INV = 0x02, /* Character-set with inverse */ + FL_WIDTH = 0x04, /* Field width specified */ + FL_MINUS = 0x08, /* Negative number */ +}; + +enum ranks { + rank_char = -2, + rank_short = -1, + rank_int = 0, + rank_long = 1, + rank_longlong = 2, + rank_ptr = INT_MAX /* Special value used for pointers */ +}; + +#define MIN_RANK rank_char +#define MAX_RANK rank_longlong + +#define INTMAX_RANK rank_longlong +#define SIZE_T_RANK rank_long +#define PTRDIFF_T_RANK rank_long + +enum bail { + bail_none = 0, /* No error condition */ + bail_eof, /* Hit EOF */ + bail_err /* Conversion mismatch */ +}; + +static inline const char * +skipspace(const char *p) +{ + while ( isspace((unsigned char)*p) ) p++; + return p; +} + +#undef set_bit +static inline void +set_bit(unsigned long *bitmap, unsigned int bit) +{ + bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT); +} + +#undef test_bit +static inline int +test_bit(unsigned long *bitmap, unsigned int bit) +{ + return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1; +} + +int vsscanf(const char *buffer, const char *format, va_list ap) +{ + const char *p = format; + char ch; + const char *q = buffer; + const char *qq; + uintmax_t val = 0; + int rank = rank_int; /* Default rank */ + unsigned int width = UINT_MAX; + int base; + enum flags flags = 0; + enum { + st_normal, /* Ground state */ + st_flags, /* Special flags */ + st_width, /* Field width */ + st_modifiers, /* Length or conversion modifiers */ + st_match_init, /* Initial state of %[ sequence */ + st_match, /* Main state of %[ sequence */ + st_match_range, /* After - in a %[ sequence */ + } state = st_normal; + char *sarg = NULL; /* %s %c or %[ string argument */ + enum bail bail = bail_none; + int sign; + int converted = 0; /* Successful conversions */ + unsigned long matchmap[((1 << CHAR_BIT)+(LONG_BIT-1))/LONG_BIT]; + int matchinv = 0; /* Is match map inverted? */ + unsigned char range_start = 0; + + while ( (ch = *p++) && !bail ) { + switch ( state ) { + case st_normal: + if ( ch == '%' ) { + state = st_flags; + flags = 0; rank = rank_int; width = UINT_MAX; + } else if ( isspace((unsigned char)ch) ) { + q = skipspace(q); + } else { + if ( *q == ch ) + q++; + else + bail = bail_err; /* Match failure */ + } + break; + + case st_flags: + switch ( ch ) { + case '*': + flags |= FL_SPLAT; + break; + case '0' ... '9': + width = (ch-'0'); + state = st_width; + flags |= FL_WIDTH; + break; + default: + state = st_modifiers; + p--; /* Process this character again */ + break; + } + break; + + case st_width: + if ( ch >= '0' && ch <= '9' ) { + width = width*10+(ch-'0'); + } else { + state = st_modifiers; + p--; /* Process this character again */ + } + break; + + case st_modifiers: + switch ( ch ) { + /* Length modifiers - nonterminal sequences */ + case 'h': + rank--; /* Shorter rank */ + break; + case 'l': + rank++; /* Longer rank */ + break; + case 'j': + rank = INTMAX_RANK; + break; + case 'z': + rank = SIZE_T_RANK; + break; + case 't': + rank = PTRDIFF_T_RANK; + break; + case 'L': + case 'q': + rank = rank_longlong; /* long double/long long */ + break; + + default: + /* Output modifiers - terminal sequences */ + state = st_normal; /* Next state will be normal */ + if ( rank < MIN_RANK ) /* Canonicalize rank */ + rank = MIN_RANK; + else if ( rank > MAX_RANK ) + rank = MAX_RANK; + + switch ( ch ) { + case 'P': /* Upper case pointer */ + case 'p': /* Pointer */ +#if 0 /* Enable this to allow null pointers by name */ + q = skipspace(q); + if ( !isdigit((unsigned char)*q) ) { + static const char * const nullnames[] = + { "null", "nul", "nil", "(null)", "(nul)", "(nil)", 0 }; + const char * const *np; + + /* Check to see if it's a null pointer by name */ + for ( np = nullnames ; *np ; np++ ) { + if ( !strncasecmp(q, *np, strlen(*np)) ) { + val = (uintmax_t)((void *)NULL); + goto set_integer; + } + } + /* Failure */ + bail = bail_err; + break; + } + /* else */ +#endif + rank = rank_ptr; + base = 0; sign = 0; + goto scan_int; + + case 'i': /* Base-independent integer */ + base = 0; sign = 1; + goto scan_int; + + case 'd': /* Decimal integer */ + base = 10; sign = 1; + goto scan_int; + + case 'o': /* Octal integer */ + base = 8; sign = 0; + goto scan_int; + + case 'u': /* Unsigned decimal integer */ + base = 10; sign = 0; + goto scan_int; + + case 'x': /* Hexadecimal integer */ + case 'X': + base = 16; sign = 0; + goto scan_int; + + case 'n': /* Number of characters consumed */ + val = (q-buffer); + goto set_integer; + + scan_int: + q = skipspace(q); + if ( !*q ) { + bail = bail_eof; + break; + } + val = strntoumax(q, (char **)&qq, base, width); + if ( qq == q ) { + bail = bail_err; + break; + } + q = qq; + converted++; + /* fall through */ + + set_integer: + if ( !(flags & FL_SPLAT) ) { + switch(rank) { + case rank_char: + *va_arg(ap, unsigned char *) = (unsigned char)val; + break; + case rank_short: + *va_arg(ap, unsigned short *) = (unsigned short)val; + break; + case rank_int: + *va_arg(ap, unsigned int *) = (unsigned int)val; + break; + case rank_long: + *va_arg(ap, unsigned long *) = (unsigned long)val; + break; + case rank_longlong: + *va_arg(ap, unsigned long long *) = (unsigned long long)val; + break; + case rank_ptr: + *va_arg(ap, void **) = (void *)(uintptr_t)val; + break; + } + } + break; + + case 'c': /* Character */ + width = (flags & FL_WIDTH) ? width : 1; /* Default width == 1 */ + sarg = va_arg(ap, char *); + while ( width-- ) { + if ( !*q ) { + bail = bail_eof; + break; + } + *sarg++ = *q++; + } + if ( !bail ) + converted++; + break; + + case 's': /* String */ + { + char *sp; + sp = sarg = va_arg(ap, char *); + while ( width-- && *q && !isspace((unsigned char)*q) ) { + *sp++ = *q++; + } + if ( sarg != sp ) { + *sp = '\0'; /* Terminate output */ + converted++; + } else { + bail = bail_eof; + } + } + break; + + case '[': /* Character range */ + sarg = va_arg(ap, char *); + state = st_match_init; + matchinv = 0; + memset(matchmap, 0, sizeof matchmap); + break; + + case '%': /* %% sequence */ + if ( *q == '%' ) + q++; + else + bail = bail_err; + break; + + default: /* Anything else */ + bail = bail_err; /* Unknown sequence */ + break; + } + } + break; + + case st_match_init: /* Initial state for %[ match */ + if ( ch == '^' && !(flags & FL_INV) ) { + matchinv = 1; + } else { + set_bit(matchmap, (unsigned char)ch); + state = st_match; + } + break; + + case st_match: /* Main state for %[ match */ + if ( ch == ']' ) { + goto match_run; + } else if ( ch == '-' ) { + range_start = (unsigned char)ch; + state = st_match_range; + } else { + set_bit(matchmap, (unsigned char)ch); + } + break; + + case st_match_range: /* %[ match after - */ + if ( ch == ']' ) { + set_bit(matchmap, (unsigned char)'-'); /* - was last character */ + goto match_run; + } else { + int i; + for ( i = range_start ; i < (unsigned char)ch ; i++ ) + set_bit(matchmap, i); + state = st_match; + } + break; + + match_run: /* Match expression finished */ + qq = q; + while ( width && *q && test_bit(matchmap, (unsigned char)*q)^matchinv ) { + *sarg++ = *q++; + } + if ( q != qq ) { + *sarg = '\0'; + converted++; + } else { + bail = *q ? bail_err : bail_eof; + } + break; + } + } + + if ( bail == bail_eof && !converted ) + converted = -1; /* Return EOF (-1) */ + + return converted; +} diff --git a/klibc/klibc/wait.c b/klibc/klibc/wait.c new file mode 100644 index 0000000000..5e0bbe29c5 --- /dev/null +++ b/klibc/klibc/wait.c @@ -0,0 +1,12 @@ +/* + * wait.c + */ + +#include +#include +#include + +pid_t wait(int *status) +{ + return wait4((pid_t)-1, status, 0, NULL); +} diff --git a/klibc/klibc/wait3.c b/klibc/klibc/wait3.c new file mode 100644 index 0000000000..48840ad155 --- /dev/null +++ b/klibc/klibc/wait3.c @@ -0,0 +1,12 @@ +/* + * wait3.c + */ + +#include +#include +#include + +pid_t wait3(int *status, int options, struct rusage *rusage) +{ + return wait4((pid_t)-1, status, options, rusage); +} diff --git a/klibc/klibc/waitpid.c b/klibc/klibc/waitpid.c new file mode 100644 index 0000000000..f7c5cbfbc0 --- /dev/null +++ b/klibc/klibc/waitpid.c @@ -0,0 +1,12 @@ +/* + * waitpid.c + */ + +#include +#include +#include + +pid_t waitpid(pid_t pid, int *status, int options) +{ + return wait4(pid, status, options, NULL); +} diff --git a/klibc/version b/klibc/version new file mode 100644 index 0000000000..e6e9cf41cc --- /dev/null +++ b/klibc/version @@ -0,0 +1 @@ +0.82 From bf0314e326319354c857a7e9150460ec239fb07d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 19:38:10 -0700 Subject: [PATCH 0109/4284] [PATCH] make libsysfs build cleanly --- libsysfs/Makefile | 45 ---- libsysfs/dlist.c | 1 + libsysfs/dlist.h | 1 - tdb/tdbtest.c | 263 ---------------------- tdb/tdbtool.c | 547 ---------------------------------------------- tdb/tdbtorture.c | 226 ------------------- 6 files changed, 1 insertion(+), 1082 deletions(-) delete mode 100644 libsysfs/Makefile delete mode 100644 tdb/tdbtest.c delete mode 100644 tdb/tdbtool.c delete mode 100644 tdb/tdbtorture.c diff --git a/libsysfs/Makefile b/libsysfs/Makefile deleted file mode 100644 index b82acbdbf2..0000000000 --- a/libsysfs/Makefile +++ /dev/null @@ -1,45 +0,0 @@ -# Makefile for libsysfs.a -# Copyright (c) International Business Machines Corp., 2003 - -H_INCLUDE=. -LIB_INCLUDE=. -OBJS=sysfs_bus.o sysfs_class.o sysfs_device.o sysfs_dir.o sysfs_driver.o \ - sysfs_utils.o dlist.o - -# Install directory - -# Options -CFLAGS=-O2 -Wall -g - -# sysfs library -LIBSYSFS=libsysfs.a - -RM=rm -f - -libsysfs.a: $(OBJS) - $(AR) cru $(LIBSYSFS) $(OBJS) - $(RANLIB) $(LIBSYSFS) - -sysfs_bus.o: sysfs_bus.c - $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_bus.c - -sysfs_class.o: sysfs_class.c - $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_class.c - -sysfs_device.o: sysfs_device.c - $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_device.c - -sysfs_dir.o: sysfs_dir.c - $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_dir.c - -sysfs_driver.o: sysfs_driver.c - $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_driver.c - -sysfs_utils.o: sysfs_utils.c - $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c sysfs_utils.c - -dlist.o: dlist.c - $(CC) -I$(H_INCLUDE) -I$(LIB_INCLUDE) $(CFLAGS) -c dlist.c - -clean: - $(RM) *.o *~ core $(LIBSYSFS) diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index 6dfcf726ba..a94ab1f854 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -27,6 +27,7 @@ * delete function. Otherwise dlist will just use free. */ +#include #include "dlist.h" /* diff --git a/libsysfs/dlist.h b/libsysfs/dlist.h index 5da79f9ba2..83f67e8d44 100644 --- a/libsysfs/dlist.h +++ b/libsysfs/dlist.h @@ -52,7 +52,6 @@ * to think about it. */ -#include typedef struct dl_node { struct dl_node *prev; struct dl_node *next; diff --git a/tdb/tdbtest.c b/tdb/tdbtest.c deleted file mode 100644 index 89295a3291..0000000000 --- a/tdb/tdbtest.c +++ /dev/null @@ -1,263 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" -#include - -/* a test program for tdb - the trivial database */ - - - -#define DELETE_PROB 7 -#define STORE_PROB 5 - -static TDB_CONTEXT *db; -static GDBM_FILE gdbm; - -struct timeval tp1,tp2; - -static void start_timer(void) -{ - gettimeofday(&tp1,NULL); -} - -static double end_timer(void) -{ - gettimeofday(&tp2,NULL); - return((tp2.tv_sec - tp1.tv_sec) + - (tp2.tv_usec - tp1.tv_usec)*1.0e-6); -} - -static void fatal(char *why) -{ - perror(why); - exit(1); -} - -static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -} - -static void compare_db(void) -{ - TDB_DATA d, key, nextkey; - datum gd, gkey, gnextkey; - - key = tdb_firstkey(db); - while (key.dptr) { - d = tdb_fetch(db, key); - gkey.dptr = key.dptr; - gkey.dsize = key.dsize; - - gd = gdbm_fetch(gdbm, gkey); - - if (!gd.dptr) fatal("key not in gdbm"); - if (gd.dsize != d.dsize) fatal("data sizes differ"); - if (memcmp(gd.dptr, d.dptr, d.dsize)) { - fatal("data differs"); - } - - nextkey = tdb_nextkey(db, key); - free(key.dptr); - free(d.dptr); - free(gd.dptr); - key = nextkey; - } - - gkey = gdbm_firstkey(gdbm); - while (gkey.dptr) { - gd = gdbm_fetch(gdbm, gkey); - key.dptr = gkey.dptr; - key.dsize = gkey.dsize; - - d = tdb_fetch(db, key); - - if (!d.dptr) fatal("key not in db"); - if (d.dsize != gd.dsize) fatal("data sizes differ"); - if (memcmp(d.dptr, gd.dptr, gd.dsize)) { - fatal("data differs"); - } - - gnextkey = gdbm_nextkey(gdbm, gkey); - free(gkey.dptr); - free(gd.dptr); - free(d.dptr); - gkey = gnextkey; - } -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" - -/* a tdb tool for manipulating a tdb database */ - -#define FSTRING_LEN 256 -typedef char fstring[FSTRING_LEN]; - -typedef struct connections_key { - pid_t pid; - int cnum; - fstring name; -} connections_key; - -typedef struct connections_data { - int magic; - pid_t pid; - int cnum; - uid_t uid; - gid_t gid; - char name[24]; - char addr[24]; - char machine[128]; - time_t start; -} connections_data; - -static TDB_CONTEXT *tdb; - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); - -static void print_asc(unsigned char *buf,int len) -{ - int i; - - /* We're probably printing ASCII strings so don't try to display - the trailing NULL character. */ - - if (buf[len - 1] == 0) - len--; - - for (i=0;i8) printf(" "); - while (n--) printf(" "); - - n = i%16; - if (n > 8) n = 8; - print_asc(&buf[i-(i%16)],n); printf(" "); - n = (i%16) - n; - if (n>0) print_asc(&buf[i-n],n); - printf("\n"); - } -} - -static void help(void) -{ - printf("\n" -"tdbtool: \n" -" create dbname : create a database\n" -" open dbname : open an existing database\n" -" erase : erase the database\n" -" dump : dump the database as strings\n" -" insert key data : insert a record\n" -" move key file : move a record to a destination tdb\n" -" store key data : store a record (replace)\n" -" show key : show a record by key\n" -" delete key : delete a record by key\n" -" list : print the database hash table and freelist\n" -" free : print the database freelist\n" -" 1 | first : print the first record\n" -" n | next : print the next record\n" -" q | quit : terminate\n" -" \\n : repeat 'next' command\n" -"\n"); -} - -static void terror(char *why) -{ - printf("%s\n", why); -} - -static char *get_token(int startover) -{ - static char tmp[1024]; - static char *cont = NULL; - char *insert, *start; - char *k = strtok(NULL, " "); - - if (!k) - return NULL; - - if (startover) - start = tmp; - else - start = cont; - - strcpy(start, k); - insert = start + strlen(start) - 1; - while (*insert == '\\') { - *insert++ = ' '; - k = strtok(NULL, " "); - if (!k) - break; - strcpy(insert, k); - insert = start + strlen(start) - 1; - } - - /* Get ready for next call */ - cont = start + strlen(start) + 1; - return start; -} - -static void create_tdb(void) -{ - char *tok = get_token(1); - if (!tok) { - help(); - return; - } - if (tdb) tdb_close(tdb); - tdb = tdb_open(tok, 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT | O_TRUNC, 0600); - if (!tdb) { - printf("Could not create %s: %s\n", tok, strerror(errno)); - } -} - -static void open_tdb(void) -{ - char *tok = get_token(1); - if (!tok) { - help(); - return; - } - if (tdb) tdb_close(tdb); - tdb = tdb_open(tok, 0, 0, O_RDWR, 0600); - if (!tdb) { - printf("Could not open %s: %s\n", tok, strerror(errno)); - } -} - -static void insert_tdb(void) -{ - char *k = get_token(1); - char *d = get_token(0); - TDB_DATA key, dbuf; - - if (!k || !d) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - dbuf.dptr = d; - dbuf.dsize = strlen(d)+1; - - if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { - terror("insert failed"); - } -} - -static void store_tdb(void) -{ - char *k = get_token(1); - char *d = get_token(0); - TDB_DATA key, dbuf; - - if (!k || !d) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - dbuf.dptr = d; - dbuf.dsize = strlen(d)+1; - - printf("Storing key:\n"); - print_rec(tdb, key, dbuf, NULL); - - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { - terror("store failed"); - } -} - -static void show_tdb(void) -{ - char *k = get_token(1); - TDB_DATA key, dbuf; - - if (!k) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - /* maybe it is non-NULL terminated key? */ - key.dsize = strlen(k); - dbuf = tdb_fetch(tdb, key); - - if ( !dbuf.dptr ) { - terror("fetch failed"); - return; - } - } - - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ - print_rec(tdb, key, dbuf, NULL); - - free( dbuf.dptr ); - - return; -} - -static void delete_tdb(void) -{ - char *k = get_token(1); - TDB_DATA key; - - if (!k) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - - if (tdb_delete(tdb, key) != 0) { - terror("delete failed"); - } -} - -static void move_rec(void) -{ - char *k = get_token(1); - char *file = get_token(0); - TDB_DATA key, dbuf; - TDB_CONTEXT *dst_tdb; - - if (!k) { - help(); - return; - } - - if ( !file ) { - terror("need destination tdb name"); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - /* maybe it is non-NULL terminated key? */ - key.dsize = strlen(k); - dbuf = tdb_fetch(tdb, key); - - if ( !dbuf.dptr ) { - terror("fetch failed"); - return; - } - } - - print_rec(tdb, key, dbuf, NULL); - - dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600); - if ( !dst_tdb ) { - terror("unable to open destination tdb"); - return; - } - - if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { - terror("failed to move record"); - } - else - printf("record moved\n"); - - tdb_close( dst_tdb ); - - return; -} - -#if 0 -static int print_conn_key(TDB_DATA key) -{ - printf( "pid =%5d ", ((connections_key*)key.dptr)->pid); - printf( "cnum =%10d ", ((connections_key*)key.dptr)->cnum); - printf( "name =[%s]\n", ((connections_key*)key.dptr)->name); - return 0; -} - -static int print_conn_data(TDB_DATA dbuf) -{ - printf( "pid =%5d ", ((connections_data*)dbuf.dptr)->pid); - printf( "cnum =%10d ", ((connections_data*)dbuf.dptr)->cnum); - printf( "name =[%s]\n", ((connections_data*)dbuf.dptr)->name); - - printf( "uid =%5d ", ((connections_data*)dbuf.dptr)->uid); - printf( "addr =[%s]\n", ((connections_data*)dbuf.dptr)->addr); - printf( "gid =%5d ", ((connections_data*)dbuf.dptr)->gid); - printf( "machine=[%s]\n", ((connections_data*)dbuf.dptr)->machine); - printf( "start = %s\n", ctime(&((connections_data*)dbuf.dptr)->start)); - return 0; -} -#endif - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ -#if 0 - print_conn_key(key); - print_conn_data(dbuf); - return 0; -#else - printf("\nkey %d bytes\n", key.dsize); - print_asc(key.dptr, key.dsize); - printf("\ndata %d bytes\n", dbuf.dsize); - print_data(dbuf.dptr, dbuf.dsize); - return 0; -#endif -} - -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - print_asc(key.dptr, key.dsize); - printf("\n"); - return 0; -} - -static int total_bytes; - -static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - total_bytes += dbuf.dsize; - return 0; -} - -static void info_tdb(void) -{ - int count; - total_bytes = 0; - if ((count = tdb_traverse(tdb, traverse_fn, NULL) == -1)) - printf("Error = %s\n", tdb_errorstr(tdb)); - else - printf("%d records totalling %d bytes\n", count, total_bytes); -} - -static char *tdb_getline(char *prompt) -{ - static char line[1024]; - char *p; - fputs(prompt, stdout); - line[0] = 0; - p = fgets(line, sizeof(line)-1, stdin); - if (p) p = strchr(p, '\n'); - if (p) *p = 0; - return p?line:NULL; -} - -static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - return tdb_delete(the_tdb, key); -} - -static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_firstkey(the_tdb); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) terror("fetch failed"); - else { - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ - print_rec(the_tdb, *pkey, dbuf, NULL); - } -} - -static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_nextkey(the_tdb, *pkey); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) - terror("fetch failed"); - else - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ - print_rec(the_tdb, *pkey, dbuf, NULL); -} - -int main(int argc, char *argv[]) -{ - int bIterate = 0; - char *line; - char *tok; - TDB_DATA iterate_kbuf; - - if (argv[1]) { - static char tmp[1024]; - sprintf(tmp, "open %s", argv[1]); - tok=strtok(tmp," "); - open_tdb(); - } - - while ((line = tdb_getline("tdb> "))) { - - /* Shell command */ - - if (line[0] == '!') { - system(line + 1); - continue; - } - - if ((tok = strtok(line," "))==NULL) { - if (bIterate) - next_record(tdb, &iterate_kbuf); - continue; - } - if (strcmp(tok,"create") == 0) { - bIterate = 0; - create_tdb(); - continue; - } else if (strcmp(tok,"open") == 0) { - open_tdb(); - continue; - } else if ((strcmp(tok, "q") == 0) || - (strcmp(tok, "quit") == 0)) { - break; - } - - /* all the rest require a open database */ - if (!tdb) { - bIterate = 0; - terror("database not open"); - help(); - continue; - } - - if (strcmp(tok,"insert") == 0) { - bIterate = 0; - insert_tdb(); - } else if (strcmp(tok,"store") == 0) { - bIterate = 0; - store_tdb(); - } else if (strcmp(tok,"show") == 0) { - bIterate = 0; - show_tdb(); - } else if (strcmp(tok,"erase") == 0) { - bIterate = 0; - tdb_traverse(tdb, do_delete_fn, NULL); - } else if (strcmp(tok,"delete") == 0) { - bIterate = 0; - delete_tdb(); - } else if (strcmp(tok,"dump") == 0) { - bIterate = 0; - tdb_traverse(tdb, print_rec, NULL); - } else if (strcmp(tok,"move") == 0) { - bIterate = 0; - move_rec(); - } else if (strcmp(tok,"list") == 0) { - tdb_dump_all(tdb); - } else if (strcmp(tok, "free") == 0) { - tdb_printfreelist(tdb); - } else if (strcmp(tok,"info") == 0) { - info_tdb(); - } else if ( (strcmp(tok, "1") == 0) || - (strcmp(tok, "first") == 0)) { - bIterate = 1; - first_record(tdb, &iterate_kbuf); - } else if ((strcmp(tok, "n") == 0) || - (strcmp(tok, "next") == 0)) { - next_record(tdb, &iterate_kbuf); - } else if ((strcmp(tok, "keys") == 0)) { - bIterate = 0; - tdb_traverse(tdb, print_key, NULL); - } else { - help(); - } - } - - if (tdb) tdb_close(tdb); - - return 0; -} diff --git a/tdb/tdbtorture.c b/tdb/tdbtorture.c deleted file mode 100644 index e27bbff990..0000000000 --- a/tdb/tdbtorture.c +++ /dev/null @@ -1,226 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" - -/* this tests tdb by doing lots of ops from several simultaneous - writers - that stresses the locking code. Build with TDB_DEBUG=1 - for best effect */ - - - -#define REOPEN_PROB 30 -#define DELETE_PROB 8 -#define STORE_PROB 4 -#define APPEND_PROB 6 -#define LOCKSTORE_PROB 0 -#define TRAVERSE_PROB 20 -#define CULL_PROB 100 -#define KEYLEN 3 -#define DATALEN 100 -#define LOCKLEN 20 - -static TDB_CONTEXT *db; - -static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -#if 0 - { - char *ptr; - asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); - system(ptr); - free(ptr); - } -#endif -} - -static void fatal(char *why) -{ - perror(why); - exit(1); -} - -static char *randbuf(int len) -{ - char *buf; - int i; - buf = (char *)malloc(len+1); - - for (i=0;i Date: Wed, 22 Oct 2003 19:38:59 -0700 Subject: [PATCH 0110/4284] [PATCH] make libsysfs spit debug messages to the same place as the rest of udev. --- libsysfs/sysfs.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 00599954fd..e39b7413cb 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -41,9 +41,17 @@ extern int isascii(int c); /* Debugging */ #ifdef DEBUG -#define dprintf(format, arg...) fprintf(stderr, format, ## arg) +#include +#define dprintf(format, arg...) \ + do { \ + log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + } while (0) #else #define dprintf(format, arg...) do { } while (0) #endif +extern int log_message (int level, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); + + #endif /* _SYSFS_H_ */ From aa04c7f0cf40d07a25cc3186c8d786cf9014f531 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 19:39:28 -0700 Subject: [PATCH 0111/4284] [PATCH] tweak tdb to build within udev better. --- tdb/spinlock.c | 8 +++++++- tdb/tdb.c | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tdb/spinlock.c b/tdb/spinlock.c index 2370ce3bdd..4b17b1d943 100644 --- a/tdb/spinlock.c +++ b/tdb/spinlock.c @@ -17,11 +17,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* udev defines */ +#define STANDALONE +#define TDB_DEBUG +#define HAVE_MMAP 1 + + #if HAVE_CONFIG_H #include #endif -#if STANDALONE +#ifdef STANDALONE #include #include #include diff --git a/tdb/tdb.c b/tdb/tdb.c index 34681ea78f..772602ed5b 100644 --- a/tdb/tdb.c +++ b/tdb/tdb.c @@ -41,6 +41,12 @@ * right time. Probably too hard -- the process just doesn't know. */ +/* udev defines */ +#define STANDALONE +#define TDB_DEBUG +#define HAVE_MMAP 1 + + #ifdef STANDALONE #if HAVE_CONFIG_H #include From 32ff5bca1517932b1e14caddd8d19fb29ef693ba Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 19:39:54 -0700 Subject: [PATCH 0112/4284] [PATCH] udev-add build cleanups for other libc versions. --- udev-add.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev-add.c b/udev-add.c index 3b0e4ddf0e..8c63214a46 100644 --- a/udev-add.c +++ b/udev-add.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" From 1c386a909af69bc5b53eb03fedead725f5fc8331 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 22:39:59 -0700 Subject: [PATCH 0113/4284] [PATCH] udev build tweaks to tdb's spinlock code --- tdb/spinlock.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/tdb/spinlock.c b/tdb/spinlock.c index 4b17b1d943..9bf42adfcf 100644 --- a/tdb/spinlock.c +++ b/tdb/spinlock.c @@ -21,7 +21,7 @@ #define STANDALONE #define TDB_DEBUG #define HAVE_MMAP 1 - +#include "../udev.h" #if HAVE_CONFIG_H #include @@ -40,7 +40,6 @@ #include "tdb.h" #include "spinlock.h" -#define DEBUG #else #include "includes.h" #endif @@ -299,10 +298,8 @@ static void __write_unlock(tdb_rwlock_t *rwlock) { __spin_lock(&rwlock->lock); -#ifdef DEBUG if (!(rwlock->count & RWLOCK_BIAS)) - fprintf(stderr, "bug: write_unlock\n"); -#endif + dbg("bug: write_unlock"); rwlock->count &= ~RWLOCK_BIAS; __spin_unlock(&rwlock->lock); @@ -312,13 +309,11 @@ static void __read_unlock(tdb_rwlock_t *rwlock) { __spin_lock(&rwlock->lock); -#ifdef DEBUG if (!rwlock->count) - fprintf(stderr, "bug: read_unlock\n"); + dbg("bug: read_unlock"); if (rwlock->count & RWLOCK_BIAS) - fprintf(stderr, "bug: read_unlock\n"); -#endif + dbg("bug: read_unlock"); rwlock->count--; __spin_unlock(&rwlock->lock); From 5c75a3ecd1852abaf4d9ee67a37ee56b0cf0a6d3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 19:40:52 -0700 Subject: [PATCH 0114/4284] [PATCH] build tdb and libsysfs from the same makefile as udev. This fixes problem of libsysfs and tdb getting build with different gcc options as the rest of udev. --- Makefile | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index ea0dc10c28..6b2c39993c 100644 --- a/Makefile +++ b/Makefile @@ -125,15 +125,21 @@ else LDFLAGS = --static endif -LIB=libsysfs - all: $(LIBC) $(ROOT) $(ARCH_LIB_OBJS) : $(MAKE) -C klibc -LIBSYSFS = libsysfs/libsysfs.a -TDB = tdb/tdb.o tdb/spinlock.o +TDB = tdb/tdb.o \ + tdb/spinlock.o + +SYSFS = libsysfs/sysfs_bus.o \ + libsysfs/sysfs_class.o \ + libsysfs/sysfs_device.o \ + libsysfs/sysfs_dir.o \ + libsysfs/sysfs_driver.o \ + libsysfs/sysfs_utils.o \ + libsysfs/dlist.o OBJS = udev.o \ udev-add.o \ @@ -141,14 +147,9 @@ OBJS = udev.o \ udevdb.o \ logging.o \ namedev.o \ + $(SYSFS) \ $(TDB) -libsysfs/libsysfs.a: - $(MAKE) -C libsysfs - -tdb/tdb.o: - $(MAKE) -C tdb - # header files automatically generated GEN_HEADERS = udev_version.h @@ -159,9 +160,8 @@ udev_version.h: @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ -$(ROOT): $(GEN_HEADERS) $(OBJS) $(LIBSYSFS) $(TDB) - $(MAKE) -C libsysfs - $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) -lsysfs $(LIB_OBJS) -L$(LIB) $(ARCH_LIB_OBJS) +$(ROOT): $(GEN_HEADERS) $(OBJS) + $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) clean: @@ -169,8 +169,6 @@ clean: | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(MAKE) -C klibc clean - $(MAKE) -C libsysfs clean - $(MAKE) -C tdb clean DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) DISTDIR := $(RELEASE_NAME) From bb27dd9b6d6ace3594e0e2d94c7642c40db0003e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 22:30:50 -0700 Subject: [PATCH 0115/4284] [PATCH] klibc makefile changes. --- Makefile.klibc | 57 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/Makefile.klibc b/Makefile.klibc index d196d6f547..d679ba900b 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -1,6 +1,6 @@ -# Makefile for diethotplug +# Makefile for udev # -# Copyright (C) 2000,2001 Greg Kroah-Hartman +# Copyright (C) 2003 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 @@ -22,10 +22,28 @@ DEBUG = true ROOT = udev -VERSION = 0.1 +VERSION = 004_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) +# override this to make udev look in a different location for it's config files +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +mandir = ${prefix}/usr/share/man +hotplugdir = ${etcdir}/hotplug.d/default +configdir = ${etcdir}/udev/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + + +# place to put our device nodes +udevdir = ${prefix}/udev/ # Comment out this line to build with something other # than the local version of klibc @@ -38,7 +56,9 @@ CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- CC = $(CROSS)gcc AR = $(CROSS)ar STRIP = $(CROSS)strip +RANLIB = $(CROSS)ranlib +export CROSS CC AR STRIP RANLIB # code taken from uClibc to determine the current arch ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ @@ -54,7 +74,8 @@ GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ then echo "-Os"; else echo "-O2" ; fi} -WARNINGS := -Wall -Wshadow -Wstrict-prototypes +# add -Wredundant-decls when libsysfs gets cleaned up +WARNINGS := -Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations # Some nice architecture specific optimizations ifeq ($(strip $(TARGET_ARCH)),arm) @@ -109,22 +130,38 @@ else LDFLAGS = --static endif +LIB=libsysfs + all: $(LIBC) $(ROOT) $(ARCH_LIB_OBJS) : $(MAKE) -C klibc -OBJS = udev.o \ - logging.o \ - namedev.o +LIBSYSFS = libsysfs/libsysfs.a +TDB = tdb/tdb.o tdb/spinlock.o +OBJS = udev.o \ + udev-add.o \ + udev-remove.o \ + udevdb.o \ + logging.o \ + namedev.o \ + $(TDB) + +libsysfs/libsysfs.a: + $(MAKE) -C libsysfs + +tdb/tdb.o: + $(MAKE) -C tdb # header files automatically generated GEN_HEADERS = udev_version.h # Rules on how to create the generated header files udev_version.h: - @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ + @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ $(ROOT): $(GEN_HEADERS) $(OBJS) @@ -137,8 +174,10 @@ clean: | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(MAKE) -C klibc clean + $(MAKE) -C libsysfs clean + $(MAKE) -C tdb clean -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS ) +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . release: $(DISTFILES) clean From c8ba857171bd09a0019d3182fe989c6cf06d98d2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 23:46:19 -0700 Subject: [PATCH 0116/4284] [PATCH] libsysfs does not need mntent.h in it's header file. --- libsysfs/sysfs.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index e39b7413cb..3186c37a16 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include From 1e959a4b05f93bf31d0603a027b50cb148ef7e90 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 23:48:55 -0700 Subject: [PATCH 0117/4284] [PATCH] klibc specific tweaks --- Makefile.klibc | 48 +++++++++++------------------------- klibc.c | 33 +++++++++++++++++++++++++ klibc/klibc/include/signal.h | 2 ++ libsysfs/sysfs_dir.c | 4 +++ libsysfs/sysfs_utils.c | 8 ++++++ namedev.c | 2 ++ udev-add.c | 9 ++++++- 7 files changed, 72 insertions(+), 34 deletions(-) create mode 100644 klibc.c diff --git a/Makefile.klibc b/Makefile.klibc index d679ba900b..ccc862dd8b 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -106,7 +106,7 @@ endif # If we are using our version of klibc, then we need to build and link it. # Otherwise, use glibc and link statically. ifeq ($(strip $(KLIBC)),true) - KLIBC_DIR = /home/greg/src/klibc/klibc/klibc + KLIBC_DIR = klibc/klibc INCLUDE_DIR := $(KLIBC_DIR)/include # arch specific objects LIBGCC = $(shell $(CC) --print-libgcc) @@ -120,7 +120,7 @@ ifeq ($(strip $(KLIBC)),true) # LIB_OBJS = $(GCC_LIB) LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) - CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I/home/greg/linux/linux-2.5/include -I$(GCCINCDIR) + CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I/home/greg/linux/linux-2.5/include -I$(GCCINCDIR) -D__KLIBC__ LDFLAGS = # LDFLAGS = --static --nostdlib -nostartfiles else @@ -130,15 +130,21 @@ else LDFLAGS = --static endif -LIB=libsysfs - all: $(LIBC) $(ROOT) $(ARCH_LIB_OBJS) : $(MAKE) -C klibc -LIBSYSFS = libsysfs/libsysfs.a -TDB = tdb/tdb.o tdb/spinlock.o +TDB = tdb/tdb.o \ + tdb/spinlock.o + +SYSFS = libsysfs/sysfs_bus.o \ + libsysfs/sysfs_class.o \ + libsysfs/sysfs_device.o \ + libsysfs/sysfs_dir.o \ + libsysfs/sysfs_driver.o \ + libsysfs/sysfs_utils.o \ + libsysfs/dlist.o OBJS = udev.o \ udev-add.o \ @@ -146,14 +152,10 @@ OBJS = udev.o \ udevdb.o \ logging.o \ namedev.o \ + klibc.o \ + $(SYSFS) \ $(TDB) -libsysfs/libsysfs.a: - $(MAKE) -C libsysfs - -tdb/tdb.o: - $(MAKE) -C tdb - # header files automatically generated GEN_HEADERS = udev_version.h @@ -165,7 +167,7 @@ udev_version.h: $(ROOT): $(GEN_HEADERS) $(OBJS) -# $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(LD) $(LDFLAGS) -o $(ROOT) $(KLIBC_DIR)/crt0.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) @@ -174,24 +176,4 @@ clean: | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(MAKE) -C klibc clean - $(MAKE) -C libsysfs clean - $(MAKE) -C tdb clean -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) -DISTDIR := $(RELEASE_NAME) -srcdir = . -release: $(DISTFILES) clean -# @echo $(DISTFILES) - @-rm -rf $(DISTDIR) - @mkdir $(DISTDIR) - @-chmod 777 $(DISTDIR) - @for file in $(DISTFILES); do \ - if test -d $$file; then \ - mkdir $(DISTDIR)/$$file; \ - else \ - cp -p $$file $(DISTDIR)/$$file; \ - fi; \ - done - @tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz - @rm -rf $(DISTDIR) - @echo "Built $(RELEASE_NAME).tar.gz" diff --git a/klibc.c b/klibc.c new file mode 100644 index 0000000000..a5d5d5948a --- /dev/null +++ b/klibc.c @@ -0,0 +1,33 @@ + +#ifdef __KLIBC__ + +#include +#include +#include + +char *strerror(int errnum) +{ + return "some error"; +} + +int strcasecmp(const char *s1, const char *s2) +{ + char *n1; + char *n2; + int retval; + int i; + + n1 = strdup(s1); + n2 = strdup(s2); + + for (i = 0; i < strlen(n1); ++i) + n1[i] = toupper(n1[i]); + for (i = 0; i < strlen(n2); ++i) + n2[i] = toupper(n2[i]); + retval = strcmp(n1, n2); + free(n1); + free(n2); + return retval; +} + +#endif diff --git a/klibc/klibc/include/signal.h b/klibc/klibc/include/signal.h index ffd2beba43..e383755b20 100644 --- a/klibc/klibc/include/signal.h +++ b/klibc/klibc/include/signal.h @@ -22,6 +22,8 @@ # define NSIG _NSIG #endif +typedef int sig_atomic_t; + __extern const char * const sys_siglist[]; /* This assumes sigset_t is either an unsigned long or an array of such, diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index ff2edf4615..e983d0eff4 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -266,7 +266,11 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) sysattr->path); return -1; } +#ifdef __KLIBC__ + pgsize = 0x4000; +#else pgsize = getpagesize(); +#endif fbuf = (unsigned char *)calloc(1, pgsize+1); if (fbuf == NULL) { dprintf("calloc failed\n"); diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 4475342433..f1303cacb3 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -22,6 +22,9 @@ */ #include "libsysfs.h" #include "sysfs.h" +#ifndef __KLIBC__ +#include +#endif /** * sysfs_get_mnt_path: Gets the mount point for specified filesystem. @@ -33,6 +36,10 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, unsigned char *mnt_path, size_t len) { +#ifdef __KLIBC__ + strcpy(mnt_path, "/sys"); + return 0; +#else FILE *mnt; struct mntent *mntent; int ret = 0; @@ -66,6 +73,7 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, ret = -1; } return ret; +#endif } /* diff --git a/namedev.c b/namedev.c index 22ec6ace24..6d88b5d47a 100644 --- a/namedev.c +++ b/namedev.c @@ -527,10 +527,12 @@ static int exec_callout(struct config_device *dev, char *value, int len) retval = -1; } +#ifndef __KLIBC__ if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { dbg("callout program status 0x%x", status); retval = -1; } +#endif } return retval; } diff --git a/udev-add.c b/udev-add.c index 8c63214a46..7a89076add 100644 --- a/udev-add.c +++ b/udev-add.c @@ -73,10 +73,17 @@ static int create_node(struct udevice *dev) { char filename[255]; int retval = 0; + dev_t res; strncpy(filename, udev_root, sizeof(filename)); strncat(filename, dev->name, sizeof(filename)); +#ifdef __KLIBC__ + res = (dev->major << 8) | (dev->minor); +#else + res = makedev(dev->major, dev->minor); +#endif + switch (dev->type) { case 'b': dev->mode |= S_IFBLK; @@ -94,7 +101,7 @@ static int create_node(struct udevice *dev) } dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); - retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor)); + retval = mknod(filename, dev->mode, res); if (retval) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, dev->mode, dev->major, dev->minor, strerror(errno)); From 1861680616736c7be1b014173e0cc0d5054b710a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 22 Oct 2003 23:59:44 -0700 Subject: [PATCH 0118/4284] [PATCH] add ftruncate to klibc. probably got it wrong too... --- klibc/klibc/SYSCALLS | 1 + 1 file changed, 1 insertion(+) diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS index 1ec94acec6..802f8a1711 100644 --- a/klibc/klibc/SYSCALLS +++ b/klibc/klibc/SYSCALLS @@ -103,6 +103,7 @@ int poll(struct pollfd *, nfds_t, long) int fsync(int) int readv(int, const struct iovec *, int) int writev(int, const struct iovec *, int) +int ftruncate(int, off_t) # # Signal operations From 606bce83da8edaa63d249a15c2d7439856526249 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 23 Oct 2003 00:12:41 -0700 Subject: [PATCH 0119/4284] [PATCH] added vsyslog support to klibc. --- klibc/klibc/include/syslog.h | 2 ++ klibc/klibc/syslog.c | 14 ++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/klibc/klibc/include/syslog.h b/klibc/klibc/include/syslog.h index b6c0acfea1..a58ef05674 100644 --- a/klibc/klibc/include/syslog.h +++ b/klibc/klibc/include/syslog.h @@ -6,6 +6,7 @@ #define _SYSLOG_H #include +#include /* Alert levels */ #define LOG_EMERG 0 @@ -49,5 +50,6 @@ __extern void openlog(const char *, int, int); __extern void syslog(int, const char *, ...); __extern void closelog(void); +__extern void vsyslog(int, const char *format, va_list ap); #endif /* _SYSLOG_H */ diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c index b031d4f0e7..d40d8633d1 100644 --- a/klibc/klibc/syslog.c +++ b/klibc/klibc/syslog.c @@ -40,9 +40,8 @@ void openlog(const char *ident, int option, int facility) id[MAXID] = '\0'; /* Make sure it's null-terminated */ } -void syslog(int prio, const char *format, ...) +void vsyslog(int prio, const char *format, va_list ap) { - va_list ap; char buf[BUFLEN]; int rv, len; int fd; @@ -62,9 +61,7 @@ void syslog(int prio, const char *format, ...) if ( *id ) len += sprintf(buf+3, "%s: ", id); - va_start(ap, format); rv = vsnprintf(buf+len, BUFLEN-len, format, ap); - va_end(ap); len += rv; if ( len > BUFLEN-1 ) len = BUFLEN-1; @@ -72,3 +69,12 @@ void syslog(int prio, const char *format, ...) write(fd, buf, len+1); } + +void syslog(int prio, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + vsyslog(prio, format, ap); + va_end(ap); +} From 6c5c770ac62791fd514f3eee9e7a5a831eef8d32 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 23 Oct 2003 00:12:58 -0700 Subject: [PATCH 0120/4284] [PATCH] turn off debugging in namedev --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 6d88b5d47a..99542dc4d6 100644 --- a/namedev.c +++ b/namedev.c @@ -22,7 +22,7 @@ */ /* define this to enable parsing debugging */ -#define DEBUG_PARSER +/* #define DEBUG_PARSER */ #include #include From 9c516bec0df7aeb43bc78ce214b3ac515818de7a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 23 Oct 2003 00:13:16 -0700 Subject: [PATCH 0121/4284] [PATCH] turn off debugging if we are building with klibc --- Makefile.klibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.klibc b/Makefile.klibc index ccc862dd8b..b901170544 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -18,7 +18,7 @@ # Set the following to `true' to make a debuggable build. # Leave this set to `false' for production use. -DEBUG = true +DEBUG = false ROOT = udev From a34ea8f598af378dcd63528b6328d1bff7fab0f1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 23 Oct 2003 00:19:18 -0700 Subject: [PATCH 0122/4284] [PATCH] added README info for how to build using klibc. --- README | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README b/README index ed25a733ab..655a30051e 100644 --- a/README +++ b/README @@ -45,8 +45,14 @@ Things are still quite rough, and it's a bit beyond proof of concept code. Help is very much appreciated, see the TODO file for a list of things left to be done. +If you want to build using klibc, use the Makefile.klibc file: + make clean + make -f Makefile.klibc +and marvel at the tiny binary you just created :) + Any comment/questions/concerns please let me know. greg k-h greg@kroah.com + From c332cfc72da865f3c9f5e34867fc3ac1b0bf0154 Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Thu, 23 Oct 2003 00:50:27 -0700 Subject: [PATCH 0123/4284] [PATCH] udev: sleep_for_dev() bits OK, I fixed that bug you hinted at earlier in my previous sleep_for_dev() patch. I am sure you fixed it, but here we go nonetheless, just in case. I actually changed it up a bit. It is probably faster to count down from SECONDS_TO_WAIT_FOR_DEV than count up. I also made the lone 'path' argument const, since it can be. Some other misc. bits, too. --- udev-add.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/udev-add.c b/udev-add.c index 7a89076add..d237834c68 100644 --- a/udev-add.c +++ b/udev-add.c @@ -139,26 +139,24 @@ exit: static int sleep_for_dev(char *path) { char filename[SYSFS_PATH_MAX + 6]; - struct stat buf; - int loop = 0; - int retval = -ENODEV; + int loop = SECONDS_TO_WAIT_FOR_DEV; + int retval; strcpy(filename, sysfs_path); strcat(filename, path); strcat(filename, "/dev"); - while (loop < SECONDS_TO_WAIT_FOR_DEV) { + while (loop--) { + struct stat buf; + dbg("looking for %s", filename); retval = stat(filename, &buf); - if (retval == 0) { - retval = 0; + if (!retval) goto exit; - } /* sleep for a second or two to give the kernel a chance to * create the dev file */ sleep(1); - ++loop; } retval = -ENODEV; exit: From c94705b5648499c58b32099dc3a303b64e1de603 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 23 Oct 2003 01:04:09 -0700 Subject: [PATCH 0124/4284] [PATCH] get 'make release' to work properly again. --- Makefile | 1 + Makefile.klibc | 2 +- klibc.c => klibc_fixups.c | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename klibc.c => klibc_fixups.c (100%) diff --git a/Makefile b/Makefile index 6b2c39993c..96037e486d 100644 --- a/Makefile +++ b/Makefile @@ -147,6 +147,7 @@ OBJS = udev.o \ udevdb.o \ logging.o \ namedev.o \ + klibc_fixups.o \ $(SYSFS) \ $(TDB) diff --git a/Makefile.klibc b/Makefile.klibc index b901170544..aca73adb53 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -152,7 +152,7 @@ OBJS = udev.o \ udevdb.o \ logging.o \ namedev.o \ - klibc.o \ + klibc_fixups.o \ $(SYSFS) \ $(TDB) diff --git a/klibc.c b/klibc_fixups.c similarity index 100% rename from klibc.c rename to klibc_fixups.c From 0fba212217eba2fee944583a54ef66f532459fc0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 23 Oct 2003 01:04:30 -0700 Subject: [PATCH 0125/4284] [PATCH] add klibc linux symlink info to the README --- README | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README b/README index 655a30051e..6fa3a28b36 100644 --- a/README +++ b/README @@ -46,8 +46,10 @@ code. Help is very much appreciated, see the TODO file for a list of things left to be done. If you want to build using klibc, use the Makefile.klibc file: - make clean - make -f Makefile.klibc + - read the klibc/klibc/klibc/README file for how to set up the linux + symlink properly. + - make clean + - make -f Makefile.klibc and marvel at the tiny binary you just created :) Any comment/questions/concerns please let me know. @@ -56,3 +58,4 @@ greg k-h greg@kroah.com + From e1b579406db58dc4ced1bec6339f7647c4fd69ea Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 23 Oct 2003 01:08:58 -0700 Subject: [PATCH 0126/4284] [PATCH] 005 release --- ChangeLog | 47 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- Makefile.klibc | 2 +- README | 2 +- udev.spec | 2 +- 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index b57cd72eaf..b8fdf91c23 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +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 + o 004 changelog entrys TAG: v004 + +Robert Love: + o udev: sleep_for_dev() bits + o udev: another canidate for static + + Summary of changes from v003 to v004 ============================================ diff --git a/Makefile b/Makefile index 96037e486d..82ea0bc309 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 004_bk +VERSION = 005 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/Makefile.klibc b/Makefile.klibc index aca73adb53..f8f3955676 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -22,7 +22,7 @@ DEBUG = false ROOT = udev -VERSION = 004_bk +VERSION = 005 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/README b/README index 6fa3a28b36..fffa793987 100644 --- a/README +++ b/README @@ -46,7 +46,7 @@ code. Help is very much appreciated, see the TODO file for a list of things left to be done. If you want to build using klibc, use the Makefile.klibc file: - - read the klibc/klibc/klibc/README file for how to set up the linux + - read the klibc/klibc/README file for how to set up the linux symlink properly. - make clean - make -f Makefile.klibc diff --git a/udev.spec b/udev.spec index ffdfb2470d..4489065051 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 004_bk +Version: 005 Release: 1 License: GPL Group: Utilities/System From 6ea7aa72dd894e723aef8881bd55766914cb07ed Mon Sep 17 00:00:00 2001 From: "lethal@linux-sh.org" Date: Fri, 24 Oct 2003 23:37:17 -0700 Subject: [PATCH 0127/4284] [PATCH] Fixup path for kernel includes when building with klibc. Fixup path for kernel includes when building with klibc. klibc expects the symlink klibc/linux to point to a relatively up to date tree, use -Iklibc/linux/include to make linux/ and asm/ includes resolve properly, as these won't exist in the regular klibc/klibc/include location. --- Makefile.klibc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.klibc b/Makefile.klibc index f8f3955676..f7c3dbd844 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -120,7 +120,7 @@ ifeq ($(strip $(KLIBC)),true) # LIB_OBJS = $(GCC_LIB) LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) - CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I/home/greg/linux/linux-2.5/include -I$(GCCINCDIR) -D__KLIBC__ + CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I$(GCCINCDIR) -Iklibc/linux/include -D__KLIBC__ LDFLAGS = # LDFLAGS = --static --nostdlib -nostartfiles else From 38ebdcac033c88e01d75ca1f4a18893fb6d2de2e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 25 Oct 2003 00:20:51 -0700 Subject: [PATCH 0128/4284] [PATCH] klibc build fixes Still can't seem to build both klibc and glibc versions from same makefile :( --- Makefile.klibc | 60 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/Makefile.klibc b/Makefile.klibc index f7c3dbd844..808217e121 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -18,7 +18,7 @@ # Set the following to `true' to make a debuggable build. # Leave this set to `false' for production use. -DEBUG = false +DEBUG = true ROOT = udev @@ -112,18 +112,18 @@ ifeq ($(strip $(KLIBC)),true) LIBGCC = $(shell $(CC) --print-libgcc) ARCH_LIB_OBJS = \ $(KLIBC_DIR)/libc.a \ -# $(KLIBC_DIR)/crt0.o \ -# $(LIBGCC) -# $(KLIBC_DIR)/bin-$(ARCH)/start.o \ -# $(KLIBC_DIR)/bin-$(ARCH)/klibc.a + $(LIBGCC) -# LIB_OBJS = $(GCC_LIB) + CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I$(GCCINCDIR) -Iklibc/linux/include -D__KLIBC__ - LDFLAGS = -# LDFLAGS = --static --nostdlib -nostartfiles + LIB_OBJS = + LDFLAGS = --static --nostdlib -nostartfiles else +# ARCH_LIB_OBJS = /usr/lib/libc.a + LIBGCC = $(shell $(CC) --print-libgcc) + CRT0 = /usr/lib/crt1.o /usr/lib/crti.o LIBC = CFLAGS += -I$(GCCINCDIR) LIB_OBJS = -lc @@ -167,8 +167,7 @@ udev_version.h: $(ROOT): $(GEN_HEADERS) $(OBJS) - $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(LD) $(LDFLAGS) -o $(ROOT) $(KLIBC_DIR)/crt0.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(LIBGCC) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) clean: @@ -177,3 +176,44 @@ clean: -rm -f core $(ROOT) $(GEN_HEADERS) $(MAKE) -C klibc clean +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) +DISTDIR := $(RELEASE_NAME) +srcdir = . +release: $(DISTFILES) clean +# @echo $(DISTFILES) + @-rm -rf $(DISTDIR) + @mkdir $(DISTDIR) + @-chmod 777 $(DISTDIR) + @for file in $(DISTFILES); do \ + if test -d $$file; then \ + mkdir $(DISTDIR)/$$file; \ + else \ + cp -p $$file $(DISTDIR)/$$file; \ + fi; \ + done + @tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz + @rm -rf $(DISTDIR) + @echo "Built $(RELEASE_NAME).tar.gz" + + +install: all + $(INSTALL) -d $(udevdir) + $(INSTALL) -d $(configdir) + $(INSTALL) -d $(hotplugdir) + $(INSTALL_PROGRAM) -D $(ROOT) $(sbindir)/$(ROOT) + $(INSTALL_DATA) -D udev.8 $(mandir)/man8/udev.8 + $(INSTALL_DATA) udev.config $(configdir) + $(INSTALL_DATA) udev.permissions $(configdir) + - ln -s $(sbindir)/$(ROOT) $(hotplugdir)/udev.hotplug + +uninstall: + - rm $(hotplugdir)/udev.hotplug + - rm $(configdir)/udev.permissions + - rm $(configdir)/udev.config + - rm $(mandir)/man8/udev.8 + - rm $(sbindir)/$(ROOT) + - rmdir $(hotplugdir) + - rmdir $(configdir) + - rmdir $(udevdir) + + From 2d5b68864f8beeaa89b3d026c6de9a97d70eeb04 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 25 Oct 2003 00:21:18 -0700 Subject: [PATCH 0129/4284] [PATCH] pull some klibc stuff into the make Makefile to try to stay in sync. --- Makefile | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 82ea0bc309..8d7122858b 100644 --- a/Makefile +++ b/Makefile @@ -106,19 +106,22 @@ endif # If we are using our version of klibc, then we need to build and link it. # Otherwise, use glibc and link statically. ifeq ($(strip $(KLIBC)),true) - KLIBC_DIR = klibc + KLIBC_DIR = klibc/klibc INCLUDE_DIR := $(KLIBC_DIR)/include # arch specific objects + LIBGCC = $(shell $(CC) --print-libgcc) ARCH_LIB_OBJS = \ - $(KLIBC_DIR)/bin-$(ARCH)/start.o \ - $(KLIBC_DIR)/bin-$(ARCH)/klibc.a + $(KLIBC_DIR)/libc.a \ + $(LIBGCC) - LIB_OBJS = $(GCC_LIB) + CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) - CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(GCCINCDIR) + CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I$(GCCINCDIR) -Iklibc/linux/include -D__KLIBC__ + LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles else + CRT0 = LIBC = CFLAGS += -I$(GCCINCDIR) LIB_OBJS = -lc From 8b94dcd0671b038754af7683eccea5b32ccb955d Mon Sep 17 00:00:00 2001 From: "rml@tech9.net" Date: Wed, 29 Oct 2003 22:14:24 -0800 Subject: [PATCH 0130/4284] [PATCH] udev init script I integrated udev with Fedora Core. The main piece is simply building /udev on boot, since we don't have an initramfs yet. We should also clear out /udev on shutdown, for /udev directories mounted on persistent media. The attached script goes in /etc/init.d Then do "chkconfig --add udev" And the rest is handled automatically. I made it for Fedora but it will probably work, with little change, on any Linux system. Right now it only does sysfs-based discovery of block and tty devices, since those are the only types of devices I have on my system. There is a TODO in the script where we would add the other device types. --- etc/init.d/udev | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 etc/init.d/udev diff --git a/etc/init.d/udev b/etc/init.d/udev new file mode 100644 index 0000000000..99f06c2963 --- /dev/null +++ b/etc/init.d/udev @@ -0,0 +1,68 @@ +#! /bin/bash +# +# random init script to setup /udev +# +# chkconfig: 2345 20 80 +# description: manage user-space device nodes in /udev + +. /etc/rc.d/init.d/functions + +udev_dir=/udev +sysfs_dir=/sys +bin=/sbin/udev + +case "$1" in + start) + if [ ! -d $udev_dir ]; then + mkdir $udev_dir + fi + if [ ! -d $sysfs_dir ]; then + exit 1 + fi + # propogate /udev from /sys - we only need this while we do not + # have initramfs and an early user-space with which to do early + # device bring up + action "Creating initial udev device nodes: " /bin/true + export ACTION=add + # add tty devices + for i in ${sysfs_dir}/class/tty/*; do + export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` + $bin tty + done + # add block devices and their partitions + for i in ${sysfs_dir}/block/*; do + export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` + $bin block + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH="/"`echo $j | \ + cut --delimiter='/' --fields=3-` + $bin block + fi + done + done + # TODO: add other device classes + ;; + stop) + # be careful + if [ $udev_dir -a "$udev_dir" != "/" ]; then + # clear out /udev + rm -rf ${udev_dir}/* + fi + ;; + status) + if [ -d $udev_dir ]; then + echo "the udev device node directory exists" + else + echo "the udev device node directory does not exist" + fi + ;; + restart|reload) + # nothing to do here + ;; + *) + echo "Usage: $0 {start|stop|status}" + exit 1 +esac + +exit 0 From 8519ed1a5bfbbe084c941c4b443c7289adec313b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 29 Oct 2003 22:26:23 -0800 Subject: [PATCH 0131/4284] [PATCH] version number to 005_bk --- Makefile | 2 +- Makefile.klibc | 2 +- udev.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8d7122858b..586db488bc 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 005 +VERSION = 005_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/Makefile.klibc b/Makefile.klibc index 808217e121..df1e55b436 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 005 +VERSION = 005_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 4489065051..fcfb1cc75b 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 005 +Version: 005_bk Release: 1 License: GPL Group: Utilities/System From 4360a56d7f1d888fdef481018a168c0dade937b9 Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Wed, 29 Oct 2003 22:26:35 -0800 Subject: [PATCH 0132/4284] [PATCH] DESTDIR for udev --- Makefile | 17 +++++++++-------- udev.spec | 6 ++---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Makefile b/Makefile index 586db488bc..01536f6986 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ VERSION = 005_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) +DESTDIR = # override this to make udev look in a different location for it's config files prefix = exec_prefix = ${prefix} @@ -195,14 +196,14 @@ release: $(DISTFILES) clean install: all - $(INSTALL) -d $(udevdir) - $(INSTALL) -d $(configdir) - $(INSTALL) -d $(hotplugdir) - $(INSTALL_PROGRAM) -D $(ROOT) $(sbindir)/$(ROOT) - $(INSTALL_DATA) -D udev.8 $(mandir)/man8/udev.8 - $(INSTALL_DATA) udev.config $(configdir) - $(INSTALL_DATA) udev.permissions $(configdir) - - ln -s $(sbindir)/$(ROOT) $(hotplugdir)/udev.hotplug + $(INSTALL) -d $(DESTDIR)$(udevdir) + $(INSTALL) -d $(DESTDIR)$(configdir) + $(INSTALL) -d $(DESTDIR)$(hotplugdir) + $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) + $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 + $(INSTALL_DATA) udev.config $(DESTDIR)$(configdir) + $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) + - ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug uninstall: - rm $(hotplugdir)/udev.hotplug diff --git a/udev.spec b/udev.spec index fcfb1cc75b..c6ebefc998 100644 --- a/udev.spec +++ b/udev.spec @@ -7,7 +7,7 @@ Group: Utilities/System Source: ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug/%{name}-%{version}.tar.gz ExclusiveOS: Linux Vendor: Greg Kroah-Hartman -BuildRoot: /var/tmp/%{name}-%{version}-%{release}-root +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root Prereq: /bin/sh, fileutils, hotplug %description @@ -21,9 +21,7 @@ udev is a implementation of devfs in userspace using sysfs and make CC="gcc $RPM_OPT_FLAGS" %install -make prefix=$RPM_BUILD_ROOT install -rm -f ${RPM_BUILD_ROOT}/etc/hotplug.d/default/udev.hotplug -ln -s /sbin/udev ${RPM_BUILD_ROOT}/etc/hotplug.d/default/udev.hotplug +make DESTDIR=$RPM_BUILD_ROOT install %clean rm -rf $RPM_BUILD_ROOT From b80d82bced57930d6a79487a413418eb9d01344c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 30 Oct 2003 00:59:16 -0800 Subject: [PATCH 0133/4284] [PATCH] Remove a few items from the TODO list that are already done. --- TODO | 6 ------ 1 file changed, 6 deletions(-) diff --git a/TODO b/TODO index 3c1581705b..927f964a0b 100644 --- a/TODO +++ b/TODO @@ -8,12 +8,6 @@ greg@kroah.com - more documentation (can never have too much.) - document the config file format (it will change over time...) -- add proper man page -- add klibc to the build process (or make it easier to do) to get - smaller binary -- import latest libsysfs and convert udev to use it. -- On remove, look up the device in the database (now that we have one) and - delete what was created, not what the kernel is calling the device. - add symlink generation and removal support - better partition support (it's a hack right now, maybe new libsysfs changes can help out a lot here.) From ebc180a2b79913557f7872dbfe12f922f1fdf0e1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 03:33:44 -0800 Subject: [PATCH 0134/4284] [PATCH] add prototype for ftruncate to klibc --- klibc/klibc/include/unistd.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h index a9b434c16b..3c51c497a7 100644 --- a/klibc/klibc/include/unistd.h +++ b/klibc/klibc/include/unistd.h @@ -103,6 +103,8 @@ __extern int optind, opterr, optopt; __extern int isatty(int); +__extern int ftruncate(int, off_t); + /* Standard file descriptor numbers. */ #define STDIN_FILENO 0 #define STDOUT_FILENO 1 From c19a6b304cd7a727da9758853134b557f5f40705 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 12 Nov 2003 03:47:57 -0800 Subject: [PATCH 0135/4284] [PATCH] add uid/gid to nodes set uid/gid of node specified in udev.permissions only numeric id's are supported cause we can't resolve with klibc or libc before real /etc is mounted --- udev-add.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/udev-add.c b/udev-add.c index d237834c68..eb1c0fb676 100644 --- a/udev-add.c +++ b/udev-add.c @@ -67,7 +67,8 @@ exit: } /* - * We also want to add some permissions here, and possibly some symlinks + * we possibly want to add some symlinks here + * only numeric owner/group id's are supported */ static int create_node(struct udevice *dev) { @@ -106,7 +107,35 @@ static int create_node(struct udevice *dev) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, dev->mode, dev->major, dev->minor, strerror(errno)); - // FIXME set the ownership of the node + uid_t uid = 0; + gid_t gid = 0; + + if (*dev->owner) { + char *endptr; + unsigned long id = strtoul(dev->owner, &endptr, 10); + if (*endptr == 0x00) + uid = (uid_t) id; + else + dbg("only numeric owner id supported: %s", dev->owner); + } + + if (*dev->group) { + char *endptr; + unsigned long id = strtoul(dev->group, &endptr, 10); + if (*endptr == 0x00) + gid = (gid_t) id; + else + dbg("only numeric group id supported: %s", dev->group); + } + + if (uid || gid) { + dbg("chown(%s, %u, %u)", filename, uid, gid); + retval = chown(filename, uid, gid); + if (retval) + dbg("chown(%s, %u, %u) failed with error '%s'", filename, + uid, gid, strerror(errno)); + } + return retval; } From 218eae87273e6b1d401ac67f94d648c9f39a30fa Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 12 Nov 2003 03:48:01 -0800 Subject: [PATCH 0136/4284] [PATCH] add support for subdirs support subdirectory creation/removal for NAME="/devfs/is/crazy/video0" create parent subdirs for device node if needed remove subdirs when last node is removed --- udev-add.c | 26 ++++++++++++++++++++++++++ udev-remove.c | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/udev-add.c b/udev-add.c index eb1c0fb676..9c54602405 100644 --- a/udev-add.c +++ b/udev-add.c @@ -101,6 +101,32 @@ static int create_node(struct udevice *dev) return -EINVAL; } + /* create subdirectories if requested */ + if (strchr(dev->name, '/')) { + char path[255]; + char *pos; + struct stat stats; + + strncpy(path, filename, sizeof(path)); + pos = strchr(path+1, '/'); + while (1) { + pos = strchr(pos+1, '/'); + if (pos == NULL) + break; + *pos = 0x00; + if (stat(path, &stats)) { + retval = mkdir(path, 0755); + if (retval) { + dbg("mkdir(%s) failed with error '%s'", + path, strerror(errno)); + return retval; + } + dbg("created %s", path); + } + *pos = '/'; + } + } + dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); retval = mknod(filename, dev->mode, res); if (retval) diff --git a/udev-remove.c b/udev-remove.c index 666928f318..1cf5d5134d 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -69,12 +69,45 @@ exit: static int delete_node(char *name) { char filename[255]; + int retval; strncpy(filename, udev_root, sizeof(filename)); strncat(filename, name, sizeof(filename)); dbg("unlinking %s", filename); - return unlink(filename); + retval = unlink(filename); + if (retval) { + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + return retval; + } + + /* remove subdirectories */ + if (strchr(name, '/')) { + char *pos; + + pos = strrchr(filename, '/'); + while (1) { + *pos = 0x00; + pos = strrchr(filename, '/'); + + /* don't remove the last one */ + if ((pos == filename) || (pos == NULL)) + break; + + /* remove if empty */ + retval = rmdir(filename); + if (retval) { + if (errno == ENOTEMPTY) + return 0; + dbg("rmdir(%s) failed with error '%s'", + filename, strerror(errno)); + break; + } + dbg("removed %s", filename); + } + } + return retval; } int udev_remove_device(char *device, char *subsystem) From da86c7f02ffbe8c315598fb2c525dc4c3fb5dcae Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 12 Nov 2003 03:48:04 -0800 Subject: [PATCH 0137/4284] [PATCH] more manpage tweaks man page style fixes present the tiny udev in bold font :) --- udev.8 | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/udev.8 b/udev.8 index 42239c824d..79b74bf659 100644 --- a/udev.8 +++ b/udev.8 @@ -20,13 +20,15 @@ reads the sysfs directory of the given device to collect device attributes like label, serial number or bus device number. These attributes are treated as a key to determine a unique name for device file creation. -udev maintains a database for devices present on the system. +.B udev +maintains a database for devices present on the system. .br On device removal, .B udev queries the internal database for the name of the device file to be deleted. .SH "CONFIGURATION" -udev expects its configuration at +.B udev +expects its configuration at .I /etc/udev/udev.config. The file consists of a set of lines. All empty lines and lines beginning with a '#' will be ignored. @@ -85,8 +87,8 @@ TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" # ttyUSB1 should always be called pda REPLACE, KERNEL="ttyUSB1", NAME="pda" -# if /sbin/dev_id returns "V0815" device will be called dev0815 -CALLOUT, PROGRAM="/sbin/dev_id", BUS="pci", ID="V0815", NAME="dev0815" +# if /sbin/scsi_id returns "OEM 0815" device will be called disk1 +CALLOUT, PROGRAM="/sbin/scsi_id" BUS="scsi", ID="OEM 0815" NAME="disk1" .fi .P Permissions and ownership for the created device files may specified at @@ -120,5 +122,6 @@ The .I http://linux-hotplug.sourceforge.net/ web site. .SH AUTHORS -udev was developed by Greg Kroah-Hartman with much help from +.B udev +was developed by Greg Kroah-Hartman with much help from Dan Stekloff and many others. From e308ebb70f9d1e389577c2a8829cf2d210cd6a19 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 03:50:33 -0800 Subject: [PATCH 0138/4284] [PATCH] fix udev-add.c to build properly with older versions of gcc. --- udev-add.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/udev-add.c b/udev-add.c index 9c54602405..d20e96ee72 100644 --- a/udev-add.c +++ b/udev-add.c @@ -74,6 +74,8 @@ static int create_node(struct udevice *dev) { char filename[255]; int retval = 0; + uid_t uid = 0; + gid_t gid = 0; dev_t res; strncpy(filename, udev_root, sizeof(filename)); @@ -133,9 +135,6 @@ static int create_node(struct udevice *dev) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, dev->mode, dev->major, dev->minor, strerror(errno)); - uid_t uid = 0; - gid_t gid = 0; - if (*dev->owner) { char *endptr; unsigned long id = strtoul(dev->owner, &endptr, 10); From 8d8172514d8c29cd5b2c51a0825268b823eb8294 Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Wed, 12 Nov 2003 05:37:24 -0800 Subject: [PATCH 0139/4284] [PATCH] patch for libsysfs sysfs directory handling Here's a quick patch to: 1) Add an environment variable "SYSFS_PATH" that libsysfs will check for when getting mount point before searching system's sysfs mount point. 2) A quick fix to sysfs_get_link where the bug was. I have tested this out with libsysfs and with udev. I couldn't test with klibc because I haven't got the tree to build with klibc without my changes either. I made the link but get an error finding linux/linits.h. I will figure that out. Please have a look at the patch. If it's agreeable, please test it. I really want to add some generic path manipulation functions for the sysfs_get_link error, rather than my patch's hack. But, I haven't had time yet to do that. You really sounded like you needed this for testing, so I'm sending it out to you. I should probably add a function to set the env variable(?). --- libsysfs/libsysfs.h | 1 + libsysfs/sysfs_utils.c | 42 +++++++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index ccb9898cb5..b3ffc467d0 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -40,6 +40,7 @@ #define SYSFS_DRIVERS_NAME "drivers" #define SYSFS_NAME_ATTRIBUTE "name" #define SYSFS_UNKNOWN "unknown" +#define SYSFS_PATH_ENV "SYSFS_PATH" /* Some "block" subsystem specific #defines */ #define SYSFS_QUEUE_NAME "queue" diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index f1303cacb3..3e50bc6120 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -84,12 +84,18 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, */ int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) { - int ret = -1; + char *sysfs_path = NULL; + int ret = 0; - if (mnt_path != NULL) - ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, mnt_path, len); - else + if (mnt_path == NULL) { errno = EINVAL; + return -1; + } + sysfs_path = getenv(SYSFS_PATH_ENV); + if (sysfs_path != NULL) + strncpy(mnt_path, sysfs_path, len); + else + ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, mnt_path, len); return ret; } @@ -130,7 +136,8 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) { unsigned char devdir[SYSFS_PATH_MAX]; unsigned char linkpath[SYSFS_PATH_MAX]; - unsigned char *d = NULL; + unsigned char *d = NULL, *s = NULL; + int slashes = 0, count = 0; if (path == NULL || target == NULL) { errno = EINVAL; @@ -139,12 +146,8 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) memset(devdir, 0, SYSFS_PATH_MAX); memset(linkpath, 0, SYSFS_PATH_MAX); + strncpy(devdir, path, SYSFS_PATH_MAX); - if ((sysfs_get_mnt_path(devdir, SYSFS_PATH_MAX)) != 0) { - dprintf("Sysfs not supported on this system\n"); - return -1; - } - if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) { return -1; } @@ -152,12 +155,25 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) d = linkpath; /* getting rid of leading "../.." */ - while (*d == '/' || *d == '.') + while (*d == '/' || *d == '.') { + if (*d == '/') + slashes++; d++; + } d--; - - strcat(devdir, d); + + s = &devdir[strlen(devdir)-1]; + while (s != NULL && count != (slashes+1)) { + s--; + if (*s == '/') + count++; + } + + if (s == NULL) + return -1; + + strncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir))); strncpy(target, devdir, len); return 0; From dc5cecf659aac8686bb7db1d047456fdef281ab1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 07:17:33 -0800 Subject: [PATCH 0140/4284] [PATCH] fix bug in klibc's isspace function. --- klibc/klibc/include/ctype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/klibc/klibc/include/ctype.h b/klibc/klibc/include/ctype.h index 2cb90a45d3..e1a25f3693 100644 --- a/klibc/klibc/include/ctype.h +++ b/klibc/klibc/include/ctype.h @@ -88,7 +88,7 @@ __ctype_inline int ispunct(int __c) __ctype_inline int isspace(int __c) { - return __ctypes[__c+1] & __ctype_space; + return __ctypes[__c] & __ctype_space; } __ctype_inline int isupper(int __c) From e40fec176bcdd0b4e763cf85817a7e5c8e1c6c14 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 07:23:39 -0800 Subject: [PATCH 0141/4284] [PATCH] change UDEV_SYSFS_PATH environment variable due to libsysfs change. --- test/label_test | 2 +- udev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/label_test b/test/label_test index f2208cbbdd..f06c416130 100644 --- a/test/label_test +++ b/test/label_test @@ -1,7 +1,7 @@ #!/bin/bash export UDEV_TEST=yes -export UDEV_SYSFS_PATH=$PWD/sys/ +export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_DIR=$PWD/ export UDEV_ROOT=$PWD/udev/ export UDEV_DB=udev.tdb diff --git a/udev.c b/udev.c index 8746b9a810..56dab1f832 100644 --- a/udev.c +++ b/udev.c @@ -86,7 +86,7 @@ static void get_dirs(void) temp = getenv("UDEV_TEST"); if (temp != NULL) { /* hm testing is happening, use the specified values, if they are present */ - temp = getenv("UDEV_SYSFS_PATH"); + temp = getenv("SYSFS_PATH"); if (temp) strncpy(sysfs_path, temp, sizeof(sysfs_path)); temp = getenv("UDEV_CONFIG_DIR"); From 139d41e988bae66de1732be74adc09bc5791370d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 07:30:20 -0800 Subject: [PATCH 0142/4284] [PATCH] add more sysfs test tree files. --- test/sys/class/mem/full/dev | 1 + test/sys/class/mem/kmem/dev | 1 + test/sys/class/mem/kmsg/dev | 1 + test/sys/class/mem/mem/dev | 1 + test/sys/class/mem/null/dev | 1 + test/sys/class/mem/port/dev | 1 + test/sys/class/mem/random/dev | 1 + test/sys/class/mem/urandom/dev | 1 + test/sys/class/mem/zero/dev | 1 + test/sys/class/misc/psaux/dev | 1 + test/sys/class/misc/rtc/dev | 1 + test/sys/class/misc/uinput/dev | 1 + test/sys/class/tty/console/dev | 1 + test/sys/class/tty/ptmx/dev | 1 + test/sys/class/tty/tty/dev | 1 + test/sys/class/tty/tty0/dev | 1 + test/sys/class/tty/tty1/dev | 1 + test/sys/class/tty/tty10/dev | 1 + test/sys/class/tty/tty11/dev | 1 + test/sys/class/tty/tty12/dev | 1 + test/sys/class/tty/tty13/dev | 1 + test/sys/class/tty/tty14/dev | 1 + test/sys/class/tty/tty15/dev | 1 + test/sys/class/tty/tty16/dev | 1 + test/sys/class/tty/tty17/dev | 1 + test/sys/class/tty/tty18/dev | 1 + test/sys/class/tty/tty19/dev | 1 + test/sys/class/tty/tty2/dev | 1 + test/sys/class/tty/tty20/dev | 1 + test/sys/class/tty/tty21/dev | 1 + test/sys/class/tty/tty22/dev | 1 + test/sys/class/tty/tty23/dev | 1 + test/sys/class/tty/tty24/dev | 1 + test/sys/class/tty/tty25/dev | 1 + test/sys/class/tty/tty26/dev | 1 + test/sys/class/tty/tty27/dev | 1 + test/sys/class/tty/tty28/dev | 1 + test/sys/class/tty/tty29/dev | 1 + test/sys/class/tty/tty3/dev | 1 + test/sys/class/tty/tty30/dev | 1 + test/sys/class/tty/tty31/dev | 1 + test/sys/class/tty/tty32/dev | 1 + test/sys/class/tty/tty33/dev | 1 + test/sys/class/tty/tty34/dev | 1 + test/sys/class/tty/tty35/dev | 1 + test/sys/class/tty/tty36/dev | 1 + test/sys/class/tty/tty37/dev | 1 + test/sys/class/tty/tty38/dev | 1 + test/sys/class/tty/tty39/dev | 1 + test/sys/class/tty/tty4/dev | 1 + test/sys/class/tty/tty40/dev | 1 + test/sys/class/tty/tty41/dev | 1 + test/sys/class/tty/tty42/dev | 1 + test/sys/class/tty/tty43/dev | 1 + test/sys/class/tty/tty44/dev | 1 + test/sys/class/tty/tty45/dev | 1 + test/sys/class/tty/tty46/dev | 1 + test/sys/class/tty/tty47/dev | 1 + test/sys/class/tty/tty48/dev | 1 + test/sys/class/tty/tty49/dev | 1 + test/sys/class/tty/tty5/dev | 1 + test/sys/class/tty/tty50/dev | 1 + test/sys/class/tty/tty51/dev | 1 + test/sys/class/tty/tty52/dev | 1 + test/sys/class/tty/tty53/dev | 1 + test/sys/class/tty/tty54/dev | 1 + test/sys/class/tty/tty55/dev | 1 + test/sys/class/tty/tty56/dev | 1 + test/sys/class/tty/tty57/dev | 1 + test/sys/class/tty/tty58/dev | 1 + test/sys/class/tty/tty59/dev | 1 + test/sys/class/tty/tty6/dev | 1 + test/sys/class/tty/tty60/dev | 1 + test/sys/class/tty/tty61/dev | 1 + test/sys/class/tty/tty62/dev | 1 + test/sys/class/tty/tty63/dev | 1 + test/sys/class/tty/tty7/dev | 1 + test/sys/class/tty/tty8/dev | 1 + test/sys/class/tty/tty9/dev | 1 + test/sys/class/tty/ttyS0/dev | 1 + test/sys/class/tty/ttyS1/dev | 1 + test/sys/class/tty/ttyS2/dev | 1 + test/sys/class/tty/ttyS3/dev | 1 + test/sys/class/tty/ttyS4/dev | 1 + test/sys/class/tty/ttyS5/dev | 1 + test/sys/class/tty/ttyS6/dev | 1 + test/sys/class/tty/ttyS7/dev | 1 + test/sys/class/tty/ttyUSB0/dev | 1 + test/sys/devices/pci0000:00/0000:00:09.0/class | 1 + test/sys/devices/pci0000:00/0000:00:09.0/detach_state | 1 + test/sys/devices/pci0000:00/0000:00:09.0/device | 1 + test/sys/devices/pci0000:00/0000:00:09.0/irq | 1 + test/sys/devices/pci0000:00/0000:00:09.0/pools | 7 +++++++ test/sys/devices/pci0000:00/0000:00:09.0/power/state | 1 + test/sys/devices/pci0000:00/0000:00:09.0/resource | 7 +++++++ test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device | 1 + test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor | 1 + .../pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting | 1 + .../pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass | 1 + .../pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber | 1 + .../0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol | 1 + .../0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass | 1 + .../pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints | 1 + .../pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state | 1 + .../pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface | 1 + .../pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state | 1 + .../0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting | 1 + .../0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass | 1 + .../0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber | 1 + .../0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol | 1 + .../0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/power/state | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue | 1 + .../devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass | 1 + .../sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces | 1 + .../sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice | 1 + .../devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes | 1 + .../devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state | 1 + .../sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor | 1 + .../devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state | 1 + .../pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state | 1 + .../pci0000:00/0000:00:09.0/usb3/bConfigurationValue | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass | 1 + .../devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol | 1 + .../devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower | 1 + .../pci0000:00/0000:00:09.0/usb3/bNumConfigurations | 1 + .../devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/manufacturer | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/product | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed | 1 + test/sys/devices/pci0000:00/0000:00:09.0/vendor | 1 + 149 files changed, 161 insertions(+) create mode 100644 test/sys/class/mem/full/dev create mode 100644 test/sys/class/mem/kmem/dev create mode 100644 test/sys/class/mem/kmsg/dev create mode 100644 test/sys/class/mem/mem/dev create mode 100644 test/sys/class/mem/null/dev create mode 100644 test/sys/class/mem/port/dev create mode 100644 test/sys/class/mem/random/dev create mode 100644 test/sys/class/mem/urandom/dev create mode 100644 test/sys/class/mem/zero/dev create mode 100644 test/sys/class/misc/psaux/dev create mode 100644 test/sys/class/misc/rtc/dev create mode 100644 test/sys/class/misc/uinput/dev create mode 100644 test/sys/class/tty/console/dev create mode 100644 test/sys/class/tty/ptmx/dev create mode 100644 test/sys/class/tty/tty/dev create mode 100644 test/sys/class/tty/tty0/dev create mode 100644 test/sys/class/tty/tty1/dev create mode 100644 test/sys/class/tty/tty10/dev create mode 100644 test/sys/class/tty/tty11/dev create mode 100644 test/sys/class/tty/tty12/dev create mode 100644 test/sys/class/tty/tty13/dev create mode 100644 test/sys/class/tty/tty14/dev create mode 100644 test/sys/class/tty/tty15/dev create mode 100644 test/sys/class/tty/tty16/dev create mode 100644 test/sys/class/tty/tty17/dev create mode 100644 test/sys/class/tty/tty18/dev create mode 100644 test/sys/class/tty/tty19/dev create mode 100644 test/sys/class/tty/tty2/dev create mode 100644 test/sys/class/tty/tty20/dev create mode 100644 test/sys/class/tty/tty21/dev create mode 100644 test/sys/class/tty/tty22/dev create mode 100644 test/sys/class/tty/tty23/dev create mode 100644 test/sys/class/tty/tty24/dev create mode 100644 test/sys/class/tty/tty25/dev create mode 100644 test/sys/class/tty/tty26/dev create mode 100644 test/sys/class/tty/tty27/dev create mode 100644 test/sys/class/tty/tty28/dev create mode 100644 test/sys/class/tty/tty29/dev create mode 100644 test/sys/class/tty/tty3/dev create mode 100644 test/sys/class/tty/tty30/dev create mode 100644 test/sys/class/tty/tty31/dev create mode 100644 test/sys/class/tty/tty32/dev create mode 100644 test/sys/class/tty/tty33/dev create mode 100644 test/sys/class/tty/tty34/dev create mode 100644 test/sys/class/tty/tty35/dev create mode 100644 test/sys/class/tty/tty36/dev create mode 100644 test/sys/class/tty/tty37/dev create mode 100644 test/sys/class/tty/tty38/dev create mode 100644 test/sys/class/tty/tty39/dev create mode 100644 test/sys/class/tty/tty4/dev create mode 100644 test/sys/class/tty/tty40/dev create mode 100644 test/sys/class/tty/tty41/dev create mode 100644 test/sys/class/tty/tty42/dev create mode 100644 test/sys/class/tty/tty43/dev create mode 100644 test/sys/class/tty/tty44/dev create mode 100644 test/sys/class/tty/tty45/dev create mode 100644 test/sys/class/tty/tty46/dev create mode 100644 test/sys/class/tty/tty47/dev create mode 100644 test/sys/class/tty/tty48/dev create mode 100644 test/sys/class/tty/tty49/dev create mode 100644 test/sys/class/tty/tty5/dev create mode 100644 test/sys/class/tty/tty50/dev create mode 100644 test/sys/class/tty/tty51/dev create mode 100644 test/sys/class/tty/tty52/dev create mode 100644 test/sys/class/tty/tty53/dev create mode 100644 test/sys/class/tty/tty54/dev create mode 100644 test/sys/class/tty/tty55/dev create mode 100644 test/sys/class/tty/tty56/dev create mode 100644 test/sys/class/tty/tty57/dev create mode 100644 test/sys/class/tty/tty58/dev create mode 100644 test/sys/class/tty/tty59/dev create mode 100644 test/sys/class/tty/tty6/dev create mode 100644 test/sys/class/tty/tty60/dev create mode 100644 test/sys/class/tty/tty61/dev create mode 100644 test/sys/class/tty/tty62/dev create mode 100644 test/sys/class/tty/tty63/dev create mode 100644 test/sys/class/tty/tty7/dev create mode 100644 test/sys/class/tty/tty8/dev create mode 100644 test/sys/class/tty/tty9/dev create mode 100644 test/sys/class/tty/ttyS0/dev create mode 100644 test/sys/class/tty/ttyS1/dev create mode 100644 test/sys/class/tty/ttyS2/dev create mode 100644 test/sys/class/tty/ttyS3/dev create mode 100644 test/sys/class/tty/ttyS4/dev create mode 100644 test/sys/class/tty/ttyS5/dev create mode 100644 test/sys/class/tty/ttyS6/dev create mode 100644 test/sys/class/tty/ttyS7/dev create mode 100644 test/sys/class/tty/ttyUSB0/dev create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/class create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/detach_state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/device create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/irq create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/pools create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/power/state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/resource create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/power/state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bConfigurationValue create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumConfigurations create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/manufacturer create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/product create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed create mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/vendor diff --git a/test/sys/class/mem/full/dev b/test/sys/class/mem/full/dev new file mode 100644 index 0000000000..4dc588f930 --- /dev/null +++ b/test/sys/class/mem/full/dev @@ -0,0 +1 @@ +1:7 diff --git a/test/sys/class/mem/kmem/dev b/test/sys/class/mem/kmem/dev new file mode 100644 index 0000000000..c7bc405e0f --- /dev/null +++ b/test/sys/class/mem/kmem/dev @@ -0,0 +1 @@ +1:2 diff --git a/test/sys/class/mem/kmsg/dev b/test/sys/class/mem/kmsg/dev new file mode 100644 index 0000000000..59effa12a9 --- /dev/null +++ b/test/sys/class/mem/kmsg/dev @@ -0,0 +1 @@ +1:11 diff --git a/test/sys/class/mem/mem/dev b/test/sys/class/mem/mem/dev new file mode 100644 index 0000000000..a72b75e75e --- /dev/null +++ b/test/sys/class/mem/mem/dev @@ -0,0 +1 @@ +1:1 diff --git a/test/sys/class/mem/null/dev b/test/sys/class/mem/null/dev new file mode 100644 index 0000000000..d9812edfef --- /dev/null +++ b/test/sys/class/mem/null/dev @@ -0,0 +1 @@ +1:3 diff --git a/test/sys/class/mem/port/dev b/test/sys/class/mem/port/dev new file mode 100644 index 0000000000..ab11afd2ec --- /dev/null +++ b/test/sys/class/mem/port/dev @@ -0,0 +1 @@ +1:4 diff --git a/test/sys/class/mem/random/dev b/test/sys/class/mem/random/dev new file mode 100644 index 0000000000..2b7b905849 --- /dev/null +++ b/test/sys/class/mem/random/dev @@ -0,0 +1 @@ +1:8 diff --git a/test/sys/class/mem/urandom/dev b/test/sys/class/mem/urandom/dev new file mode 100644 index 0000000000..0695af03c5 --- /dev/null +++ b/test/sys/class/mem/urandom/dev @@ -0,0 +1 @@ +1:9 diff --git a/test/sys/class/mem/zero/dev b/test/sys/class/mem/zero/dev new file mode 100644 index 0000000000..0acbea55a4 --- /dev/null +++ b/test/sys/class/mem/zero/dev @@ -0,0 +1 @@ +1:5 diff --git a/test/sys/class/misc/psaux/dev b/test/sys/class/misc/psaux/dev new file mode 100644 index 0000000000..48ace1eca2 --- /dev/null +++ b/test/sys/class/misc/psaux/dev @@ -0,0 +1 @@ +10:1 diff --git a/test/sys/class/misc/rtc/dev b/test/sys/class/misc/rtc/dev new file mode 100644 index 0000000000..64e028a296 --- /dev/null +++ b/test/sys/class/misc/rtc/dev @@ -0,0 +1 @@ +10:135 diff --git a/test/sys/class/misc/uinput/dev b/test/sys/class/misc/uinput/dev new file mode 100644 index 0000000000..a47be0d551 --- /dev/null +++ b/test/sys/class/misc/uinput/dev @@ -0,0 +1 @@ +10:223 diff --git a/test/sys/class/tty/console/dev b/test/sys/class/tty/console/dev new file mode 100644 index 0000000000..99eb99cd27 --- /dev/null +++ b/test/sys/class/tty/console/dev @@ -0,0 +1 @@ +5:1 diff --git a/test/sys/class/tty/ptmx/dev b/test/sys/class/tty/ptmx/dev new file mode 100644 index 0000000000..b1df63ebd3 --- /dev/null +++ b/test/sys/class/tty/ptmx/dev @@ -0,0 +1 @@ +5:2 diff --git a/test/sys/class/tty/tty/dev b/test/sys/class/tty/tty/dev new file mode 100644 index 0000000000..97f5a222f0 --- /dev/null +++ b/test/sys/class/tty/tty/dev @@ -0,0 +1 @@ +5:0 diff --git a/test/sys/class/tty/tty0/dev b/test/sys/class/tty/tty0/dev new file mode 100644 index 0000000000..192d8b739c --- /dev/null +++ b/test/sys/class/tty/tty0/dev @@ -0,0 +1 @@ +4:0 diff --git a/test/sys/class/tty/tty1/dev b/test/sys/class/tty/tty1/dev new file mode 100644 index 0000000000..71275a262f --- /dev/null +++ b/test/sys/class/tty/tty1/dev @@ -0,0 +1 @@ +4:1 diff --git a/test/sys/class/tty/tty10/dev b/test/sys/class/tty/tty10/dev new file mode 100644 index 0000000000..eb477d040f --- /dev/null +++ b/test/sys/class/tty/tty10/dev @@ -0,0 +1 @@ +4:10 diff --git a/test/sys/class/tty/tty11/dev b/test/sys/class/tty/tty11/dev new file mode 100644 index 0000000000..685b194273 --- /dev/null +++ b/test/sys/class/tty/tty11/dev @@ -0,0 +1 @@ +4:11 diff --git a/test/sys/class/tty/tty12/dev b/test/sys/class/tty/tty12/dev new file mode 100644 index 0000000000..47b68a96a5 --- /dev/null +++ b/test/sys/class/tty/tty12/dev @@ -0,0 +1 @@ +4:12 diff --git a/test/sys/class/tty/tty13/dev b/test/sys/class/tty/tty13/dev new file mode 100644 index 0000000000..86e31456d2 --- /dev/null +++ b/test/sys/class/tty/tty13/dev @@ -0,0 +1 @@ +4:13 diff --git a/test/sys/class/tty/tty14/dev b/test/sys/class/tty/tty14/dev new file mode 100644 index 0000000000..9fa8103ff8 --- /dev/null +++ b/test/sys/class/tty/tty14/dev @@ -0,0 +1 @@ +4:14 diff --git a/test/sys/class/tty/tty15/dev b/test/sys/class/tty/tty15/dev new file mode 100644 index 0000000000..3f601b851f --- /dev/null +++ b/test/sys/class/tty/tty15/dev @@ -0,0 +1 @@ +4:15 diff --git a/test/sys/class/tty/tty16/dev b/test/sys/class/tty/tty16/dev new file mode 100644 index 0000000000..0310e8064a --- /dev/null +++ b/test/sys/class/tty/tty16/dev @@ -0,0 +1 @@ +4:16 diff --git a/test/sys/class/tty/tty17/dev b/test/sys/class/tty/tty17/dev new file mode 100644 index 0000000000..19360464d0 --- /dev/null +++ b/test/sys/class/tty/tty17/dev @@ -0,0 +1 @@ +4:17 diff --git a/test/sys/class/tty/tty18/dev b/test/sys/class/tty/tty18/dev new file mode 100644 index 0000000000..8710c48f12 --- /dev/null +++ b/test/sys/class/tty/tty18/dev @@ -0,0 +1 @@ +4:18 diff --git a/test/sys/class/tty/tty19/dev b/test/sys/class/tty/tty19/dev new file mode 100644 index 0000000000..5fac93ed2f --- /dev/null +++ b/test/sys/class/tty/tty19/dev @@ -0,0 +1 @@ +4:19 diff --git a/test/sys/class/tty/tty2/dev b/test/sys/class/tty/tty2/dev new file mode 100644 index 0000000000..ac0836d7ca --- /dev/null +++ b/test/sys/class/tty/tty2/dev @@ -0,0 +1 @@ +4:2 diff --git a/test/sys/class/tty/tty20/dev b/test/sys/class/tty/tty20/dev new file mode 100644 index 0000000000..3db4a84c87 --- /dev/null +++ b/test/sys/class/tty/tty20/dev @@ -0,0 +1 @@ +4:20 diff --git a/test/sys/class/tty/tty21/dev b/test/sys/class/tty/tty21/dev new file mode 100644 index 0000000000..f86a02508c --- /dev/null +++ b/test/sys/class/tty/tty21/dev @@ -0,0 +1 @@ +4:21 diff --git a/test/sys/class/tty/tty22/dev b/test/sys/class/tty/tty22/dev new file mode 100644 index 0000000000..b27a240d1a --- /dev/null +++ b/test/sys/class/tty/tty22/dev @@ -0,0 +1 @@ +4:22 diff --git a/test/sys/class/tty/tty23/dev b/test/sys/class/tty/tty23/dev new file mode 100644 index 0000000000..9359bfa71d --- /dev/null +++ b/test/sys/class/tty/tty23/dev @@ -0,0 +1 @@ +4:23 diff --git a/test/sys/class/tty/tty24/dev b/test/sys/class/tty/tty24/dev new file mode 100644 index 0000000000..9cd85c8a81 --- /dev/null +++ b/test/sys/class/tty/tty24/dev @@ -0,0 +1 @@ +4:24 diff --git a/test/sys/class/tty/tty25/dev b/test/sys/class/tty/tty25/dev new file mode 100644 index 0000000000..f9d8c9c059 --- /dev/null +++ b/test/sys/class/tty/tty25/dev @@ -0,0 +1 @@ +4:25 diff --git a/test/sys/class/tty/tty26/dev b/test/sys/class/tty/tty26/dev new file mode 100644 index 0000000000..210b637b97 --- /dev/null +++ b/test/sys/class/tty/tty26/dev @@ -0,0 +1 @@ +4:26 diff --git a/test/sys/class/tty/tty27/dev b/test/sys/class/tty/tty27/dev new file mode 100644 index 0000000000..de59b627a5 --- /dev/null +++ b/test/sys/class/tty/tty27/dev @@ -0,0 +1 @@ +4:27 diff --git a/test/sys/class/tty/tty28/dev b/test/sys/class/tty/tty28/dev new file mode 100644 index 0000000000..023871c676 --- /dev/null +++ b/test/sys/class/tty/tty28/dev @@ -0,0 +1 @@ +4:28 diff --git a/test/sys/class/tty/tty29/dev b/test/sys/class/tty/tty29/dev new file mode 100644 index 0000000000..2edd7c58af --- /dev/null +++ b/test/sys/class/tty/tty29/dev @@ -0,0 +1 @@ +4:29 diff --git a/test/sys/class/tty/tty3/dev b/test/sys/class/tty/tty3/dev new file mode 100644 index 0000000000..c8142884a4 --- /dev/null +++ b/test/sys/class/tty/tty3/dev @@ -0,0 +1 @@ +4:3 diff --git a/test/sys/class/tty/tty30/dev b/test/sys/class/tty/tty30/dev new file mode 100644 index 0000000000..63f0e669b8 --- /dev/null +++ b/test/sys/class/tty/tty30/dev @@ -0,0 +1 @@ +4:30 diff --git a/test/sys/class/tty/tty31/dev b/test/sys/class/tty/tty31/dev new file mode 100644 index 0000000000..77a50eeff5 --- /dev/null +++ b/test/sys/class/tty/tty31/dev @@ -0,0 +1 @@ +4:31 diff --git a/test/sys/class/tty/tty32/dev b/test/sys/class/tty/tty32/dev new file mode 100644 index 0000000000..ae38a8dcd7 --- /dev/null +++ b/test/sys/class/tty/tty32/dev @@ -0,0 +1 @@ +4:32 diff --git a/test/sys/class/tty/tty33/dev b/test/sys/class/tty/tty33/dev new file mode 100644 index 0000000000..9307b44cd0 --- /dev/null +++ b/test/sys/class/tty/tty33/dev @@ -0,0 +1 @@ +4:33 diff --git a/test/sys/class/tty/tty34/dev b/test/sys/class/tty/tty34/dev new file mode 100644 index 0000000000..be00cbe67c --- /dev/null +++ b/test/sys/class/tty/tty34/dev @@ -0,0 +1 @@ +4:34 diff --git a/test/sys/class/tty/tty35/dev b/test/sys/class/tty/tty35/dev new file mode 100644 index 0000000000..4e5e85cb70 --- /dev/null +++ b/test/sys/class/tty/tty35/dev @@ -0,0 +1 @@ +4:35 diff --git a/test/sys/class/tty/tty36/dev b/test/sys/class/tty/tty36/dev new file mode 100644 index 0000000000..4e5407ef59 --- /dev/null +++ b/test/sys/class/tty/tty36/dev @@ -0,0 +1 @@ +4:36 diff --git a/test/sys/class/tty/tty37/dev b/test/sys/class/tty/tty37/dev new file mode 100644 index 0000000000..765acf2d2c --- /dev/null +++ b/test/sys/class/tty/tty37/dev @@ -0,0 +1 @@ +4:37 diff --git a/test/sys/class/tty/tty38/dev b/test/sys/class/tty/tty38/dev new file mode 100644 index 0000000000..1532b15793 --- /dev/null +++ b/test/sys/class/tty/tty38/dev @@ -0,0 +1 @@ +4:38 diff --git a/test/sys/class/tty/tty39/dev b/test/sys/class/tty/tty39/dev new file mode 100644 index 0000000000..fac383d3df --- /dev/null +++ b/test/sys/class/tty/tty39/dev @@ -0,0 +1 @@ +4:39 diff --git a/test/sys/class/tty/tty4/dev b/test/sys/class/tty/tty4/dev new file mode 100644 index 0000000000..7f407b5d25 --- /dev/null +++ b/test/sys/class/tty/tty4/dev @@ -0,0 +1 @@ +4:4 diff --git a/test/sys/class/tty/tty40/dev b/test/sys/class/tty/tty40/dev new file mode 100644 index 0000000000..d7246138ac --- /dev/null +++ b/test/sys/class/tty/tty40/dev @@ -0,0 +1 @@ +4:40 diff --git a/test/sys/class/tty/tty41/dev b/test/sys/class/tty/tty41/dev new file mode 100644 index 0000000000..0d974303d5 --- /dev/null +++ b/test/sys/class/tty/tty41/dev @@ -0,0 +1 @@ +4:41 diff --git a/test/sys/class/tty/tty42/dev b/test/sys/class/tty/tty42/dev new file mode 100644 index 0000000000..4019d23bfa --- /dev/null +++ b/test/sys/class/tty/tty42/dev @@ -0,0 +1 @@ +4:42 diff --git a/test/sys/class/tty/tty43/dev b/test/sys/class/tty/tty43/dev new file mode 100644 index 0000000000..4b6c086540 --- /dev/null +++ b/test/sys/class/tty/tty43/dev @@ -0,0 +1 @@ +4:43 diff --git a/test/sys/class/tty/tty44/dev b/test/sys/class/tty/tty44/dev new file mode 100644 index 0000000000..9c2357463f --- /dev/null +++ b/test/sys/class/tty/tty44/dev @@ -0,0 +1 @@ +4:44 diff --git a/test/sys/class/tty/tty45/dev b/test/sys/class/tty/tty45/dev new file mode 100644 index 0000000000..23437be177 --- /dev/null +++ b/test/sys/class/tty/tty45/dev @@ -0,0 +1 @@ +4:45 diff --git a/test/sys/class/tty/tty46/dev b/test/sys/class/tty/tty46/dev new file mode 100644 index 0000000000..816feaf47d --- /dev/null +++ b/test/sys/class/tty/tty46/dev @@ -0,0 +1 @@ +4:46 diff --git a/test/sys/class/tty/tty47/dev b/test/sys/class/tty/tty47/dev new file mode 100644 index 0000000000..d2534e707d --- /dev/null +++ b/test/sys/class/tty/tty47/dev @@ -0,0 +1 @@ +4:47 diff --git a/test/sys/class/tty/tty48/dev b/test/sys/class/tty/tty48/dev new file mode 100644 index 0000000000..4003c709df --- /dev/null +++ b/test/sys/class/tty/tty48/dev @@ -0,0 +1 @@ +4:48 diff --git a/test/sys/class/tty/tty49/dev b/test/sys/class/tty/tty49/dev new file mode 100644 index 0000000000..64dc806057 --- /dev/null +++ b/test/sys/class/tty/tty49/dev @@ -0,0 +1 @@ +4:49 diff --git a/test/sys/class/tty/tty5/dev b/test/sys/class/tty/tty5/dev new file mode 100644 index 0000000000..1553222302 --- /dev/null +++ b/test/sys/class/tty/tty5/dev @@ -0,0 +1 @@ +4:5 diff --git a/test/sys/class/tty/tty50/dev b/test/sys/class/tty/tty50/dev new file mode 100644 index 0000000000..71e681bc39 --- /dev/null +++ b/test/sys/class/tty/tty50/dev @@ -0,0 +1 @@ +4:50 diff --git a/test/sys/class/tty/tty51/dev b/test/sys/class/tty/tty51/dev new file mode 100644 index 0000000000..1f8c4b6976 --- /dev/null +++ b/test/sys/class/tty/tty51/dev @@ -0,0 +1 @@ +4:51 diff --git a/test/sys/class/tty/tty52/dev b/test/sys/class/tty/tty52/dev new file mode 100644 index 0000000000..344e8c93f9 --- /dev/null +++ b/test/sys/class/tty/tty52/dev @@ -0,0 +1 @@ +4:52 diff --git a/test/sys/class/tty/tty53/dev b/test/sys/class/tty/tty53/dev new file mode 100644 index 0000000000..c4b80fb134 --- /dev/null +++ b/test/sys/class/tty/tty53/dev @@ -0,0 +1 @@ +4:53 diff --git a/test/sys/class/tty/tty54/dev b/test/sys/class/tty/tty54/dev new file mode 100644 index 0000000000..ba56c5e44c --- /dev/null +++ b/test/sys/class/tty/tty54/dev @@ -0,0 +1 @@ +4:54 diff --git a/test/sys/class/tty/tty55/dev b/test/sys/class/tty/tty55/dev new file mode 100644 index 0000000000..540bf11253 --- /dev/null +++ b/test/sys/class/tty/tty55/dev @@ -0,0 +1 @@ +4:55 diff --git a/test/sys/class/tty/tty56/dev b/test/sys/class/tty/tty56/dev new file mode 100644 index 0000000000..ee03fba97d --- /dev/null +++ b/test/sys/class/tty/tty56/dev @@ -0,0 +1 @@ +4:56 diff --git a/test/sys/class/tty/tty57/dev b/test/sys/class/tty/tty57/dev new file mode 100644 index 0000000000..664d8ec646 --- /dev/null +++ b/test/sys/class/tty/tty57/dev @@ -0,0 +1 @@ +4:57 diff --git a/test/sys/class/tty/tty58/dev b/test/sys/class/tty/tty58/dev new file mode 100644 index 0000000000..ffc6c0b62c --- /dev/null +++ b/test/sys/class/tty/tty58/dev @@ -0,0 +1 @@ +4:58 diff --git a/test/sys/class/tty/tty59/dev b/test/sys/class/tty/tty59/dev new file mode 100644 index 0000000000..c48309e7f0 --- /dev/null +++ b/test/sys/class/tty/tty59/dev @@ -0,0 +1 @@ +4:59 diff --git a/test/sys/class/tty/tty6/dev b/test/sys/class/tty/tty6/dev new file mode 100644 index 0000000000..cd94e0d09d --- /dev/null +++ b/test/sys/class/tty/tty6/dev @@ -0,0 +1 @@ +4:6 diff --git a/test/sys/class/tty/tty60/dev b/test/sys/class/tty/tty60/dev new file mode 100644 index 0000000000..37d25eab02 --- /dev/null +++ b/test/sys/class/tty/tty60/dev @@ -0,0 +1 @@ +4:60 diff --git a/test/sys/class/tty/tty61/dev b/test/sys/class/tty/tty61/dev new file mode 100644 index 0000000000..599df60bfd --- /dev/null +++ b/test/sys/class/tty/tty61/dev @@ -0,0 +1 @@ +4:61 diff --git a/test/sys/class/tty/tty62/dev b/test/sys/class/tty/tty62/dev new file mode 100644 index 0000000000..49fc9a0af5 --- /dev/null +++ b/test/sys/class/tty/tty62/dev @@ -0,0 +1 @@ +4:62 diff --git a/test/sys/class/tty/tty63/dev b/test/sys/class/tty/tty63/dev new file mode 100644 index 0000000000..d11e9d2a82 --- /dev/null +++ b/test/sys/class/tty/tty63/dev @@ -0,0 +1 @@ +4:63 diff --git a/test/sys/class/tty/tty7/dev b/test/sys/class/tty/tty7/dev new file mode 100644 index 0000000000..9410476660 --- /dev/null +++ b/test/sys/class/tty/tty7/dev @@ -0,0 +1 @@ +4:7 diff --git a/test/sys/class/tty/tty8/dev b/test/sys/class/tty/tty8/dev new file mode 100644 index 0000000000..a79f74ba39 --- /dev/null +++ b/test/sys/class/tty/tty8/dev @@ -0,0 +1 @@ +4:8 diff --git a/test/sys/class/tty/tty9/dev b/test/sys/class/tty/tty9/dev new file mode 100644 index 0000000000..62ada4bbe9 --- /dev/null +++ b/test/sys/class/tty/tty9/dev @@ -0,0 +1 @@ +4:9 diff --git a/test/sys/class/tty/ttyS0/dev b/test/sys/class/tty/ttyS0/dev new file mode 100644 index 0000000000..9f6b667886 --- /dev/null +++ b/test/sys/class/tty/ttyS0/dev @@ -0,0 +1 @@ +4:64 diff --git a/test/sys/class/tty/ttyS1/dev b/test/sys/class/tty/ttyS1/dev new file mode 100644 index 0000000000..db3f8ecdcd --- /dev/null +++ b/test/sys/class/tty/ttyS1/dev @@ -0,0 +1 @@ +4:65 diff --git a/test/sys/class/tty/ttyS2/dev b/test/sys/class/tty/ttyS2/dev new file mode 100644 index 0000000000..cef5d02fd9 --- /dev/null +++ b/test/sys/class/tty/ttyS2/dev @@ -0,0 +1 @@ +4:66 diff --git a/test/sys/class/tty/ttyS3/dev b/test/sys/class/tty/ttyS3/dev new file mode 100644 index 0000000000..3077006e7a --- /dev/null +++ b/test/sys/class/tty/ttyS3/dev @@ -0,0 +1 @@ +4:67 diff --git a/test/sys/class/tty/ttyS4/dev b/test/sys/class/tty/ttyS4/dev new file mode 100644 index 0000000000..26cd2d8c86 --- /dev/null +++ b/test/sys/class/tty/ttyS4/dev @@ -0,0 +1 @@ +4:68 diff --git a/test/sys/class/tty/ttyS5/dev b/test/sys/class/tty/ttyS5/dev new file mode 100644 index 0000000000..189b73bb6e --- /dev/null +++ b/test/sys/class/tty/ttyS5/dev @@ -0,0 +1 @@ +4:69 diff --git a/test/sys/class/tty/ttyS6/dev b/test/sys/class/tty/ttyS6/dev new file mode 100644 index 0000000000..f40a113a2a --- /dev/null +++ b/test/sys/class/tty/ttyS6/dev @@ -0,0 +1 @@ +4:70 diff --git a/test/sys/class/tty/ttyS7/dev b/test/sys/class/tty/ttyS7/dev new file mode 100644 index 0000000000..ec1b8ff559 --- /dev/null +++ b/test/sys/class/tty/ttyS7/dev @@ -0,0 +1 @@ +4:71 diff --git a/test/sys/class/tty/ttyUSB0/dev b/test/sys/class/tty/ttyUSB0/dev new file mode 100644 index 0000000000..5c0bba8170 --- /dev/null +++ b/test/sys/class/tty/ttyUSB0/dev @@ -0,0 +1 @@ +188:0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/class b/test/sys/devices/pci0000:00/0000:00:09.0/class new file mode 100644 index 0000000000..a9a8817576 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/class @@ -0,0 +1 @@ +0x0c0310 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/detach_state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/detach_state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/device b/test/sys/devices/pci0000:00/0000:00:09.0/device new file mode 100644 index 0000000000..90e151e254 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/device @@ -0,0 +1 @@ +0x0035 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/irq b/test/sys/devices/pci0000:00/0000:00:09.0/irq new file mode 100644 index 0000000000..ec635144f6 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/irq @@ -0,0 +1 @@ +9 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/pools b/test/sys/devices/pci0000:00/0000:00:09.0/pools new file mode 100644 index 0000000000..7da8ce818d --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/power/state b/test/sys/devices/pci0000:00/0000:00:09.0/power/state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/power/state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/resource b/test/sys/devices/pci0000:00/0000:00:09.0/resource new file mode 100644 index 0000000000..e7c459f811 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device b/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device new file mode 100644 index 0000000000..db5e9bccd0 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_device @@ -0,0 +1 @@ +0x11a3 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor b/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor new file mode 100644 index 0000000000..3dc3deeb2b --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/subsystem_vendor @@ -0,0 +1 @@ +0x10cf diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting new file mode 100644 index 0000000000..2142470504 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bAlternateSetting @@ -0,0 +1 @@ + 0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass new file mode 100644 index 0000000000..86397e5c10 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceClass @@ -0,0 +1 @@ +09 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceNumber @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceProtocol @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bInterfaceSubClass @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints new file mode 100644 index 0000000000..8a0f05e166 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bNumEndpoints @@ -0,0 +1 @@ +01 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/iInterface @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/power/state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting new file mode 100644 index 0000000000..2142470504 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bAlternateSetting @@ -0,0 +1 @@ + 0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass new file mode 100644 index 0000000000..fcd15acf93 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceClass @@ -0,0 +1 @@ +ff diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceNumber @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceProtocol @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bInterfaceSubClass @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints new file mode 100644 index 0000000000..75016ea362 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bNumEndpoints @@ -0,0 +1 @@ +03 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/iInterface @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/power/state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/power/state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bConfigurationValue @@ -0,0 +1 @@ +1 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceClass @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceProtocol @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bDeviceSubClass @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower new file mode 100644 index 0000000000..d579c4bb6d --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bMaxPower @@ -0,0 +1 @@ + 50mA diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumConfigurations @@ -0,0 +1 @@ +1 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces new file mode 100644 index 0000000000..c6cf38636b --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bNumInterfaces @@ -0,0 +1 @@ + 1 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice new file mode 100644 index 0000000000..635047563b --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bcdDevice @@ -0,0 +1 @@ +0001 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes new file mode 100644 index 0000000000..0042f6c56d --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bmAttributes @@ -0,0 +1 @@ +a0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct new file mode 100644 index 0000000000..9142bb40c2 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idProduct @@ -0,0 +1 @@ +2008 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor new file mode 100644 index 0000000000..6ffae177b7 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/idVendor @@ -0,0 +1 @@ +0557 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/power/state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed new file mode 100644 index 0000000000..48082f72f0 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/speed @@ -0,0 +1 @@ +12 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/power/state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bConfigurationValue b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bConfigurationValue new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bConfigurationValue @@ -0,0 +1 @@ +1 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass new file mode 100644 index 0000000000..86397e5c10 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceClass @@ -0,0 +1 @@ +09 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceProtocol @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass new file mode 100644 index 0000000000..4daddb72ff --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bDeviceSubClass @@ -0,0 +1 @@ +00 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower new file mode 100644 index 0000000000..ca2ea0dab5 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bMaxPower @@ -0,0 +1 @@ + 0mA diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumConfigurations b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumConfigurations new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumConfigurations @@ -0,0 +1 @@ +1 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces new file mode 100644 index 0000000000..c6cf38636b --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bNumInterfaces @@ -0,0 +1 @@ + 1 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice new file mode 100644 index 0000000000..ff5c1613f9 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bcdDevice @@ -0,0 +1 @@ +0206 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes new file mode 100644 index 0000000000..425151f3a4 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bmAttributes @@ -0,0 +1 @@ +40 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct new file mode 100644 index 0000000000..739d79706d --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idProduct @@ -0,0 +1 @@ +0000 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor new file mode 100644 index 0000000000..739d79706d --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/idVendor @@ -0,0 +1 @@ +0000 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/manufacturer b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/manufacturer new file mode 100644 index 0000000000..7ea94cede0 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/power/state @@ -0,0 +1 @@ +0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/product b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/product new file mode 100644 index 0000000000..a1c773affb --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/product @@ -0,0 +1 @@ +OHCI Host Controller diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial new file mode 100644 index 0000000000..1b7fda31c4 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/serial @@ -0,0 +1 @@ +0000:00:09.0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed new file mode 100644 index 0000000000..48082f72f0 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/speed @@ -0,0 +1 @@ +12 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/vendor b/test/sys/devices/pci0000:00/0000:00:09.0/vendor new file mode 100644 index 0000000000..fcfa779f23 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/vendor @@ -0,0 +1 @@ +0x1033 From 75ff8da8ab2e7362ec489fe5280fe5c84fe42741 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 07:32:29 -0800 Subject: [PATCH 0143/4284] [PATCH] add replace test --- test/replace_test | 14 ++++++++++++++ test/replace_test.config | 3 +++ 2 files changed, 17 insertions(+) create mode 100644 test/replace_test create mode 100644 test/replace_test.config diff --git a/test/replace_test b/test/replace_test new file mode 100644 index 0000000000..3aa8d5a8c9 --- /dev/null +++ b/test/replace_test @@ -0,0 +1,14 @@ +#!/bin/bash + +export UDEV_TEST=yes +export SYSFS_PATH=$PWD/sys/ +export UDEV_CONFIG_DIR=$PWD/ +export UDEV_ROOT=$PWD/udev/ +export UDEV_DB=udev.tdb +export UDEV_CONFIG_FILE=replace_test.config +export UDEV_PERMISSION_FILE=udev.permissions + +export DEVPATH=class/tty/ttyUSB0 +export ACTION=add + +../udev tty diff --git a/test/replace_test.config b/test/replace_test.config new file mode 100644 index 0000000000..8fbfd18100 --- /dev/null +++ b/test/replace_test.config @@ -0,0 +1,3 @@ +# REPLACE test +REPLACE, KERNEL="ttyUSB0", NAME="visor" + From 07b80e6d55ebeca61c7c4dba880517bb1a32ff81 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 07:44:56 -0800 Subject: [PATCH 0144/4284] [PATCH] add debug line for REPLACE call. --- namedev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/namedev.c b/namedev.c index 99542dc4d6..c277cec28f 100644 --- a/namedev.c +++ b/namedev.c @@ -733,6 +733,8 @@ label_found: break; } case REPLACE: + dbg_parse("REPLACE: replace name '%s' with '%s'", + dev->kernel_name, dev->name); if (strcmp(dev->kernel_name, class_dev->name) != 0) continue; strcpy(udev->name, dev->name); From 120d45d0a1565a1e4432616df3117ff474c0b249 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 08:26:08 -0800 Subject: [PATCH 0145/4284] [PATCH] split REPLACE and CALLOUT into separate functions Finally starting to process this in priority order, not config file order. --- namedev.c | 112 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 40 deletions(-) diff --git a/namedev.c b/namedev.c index c277cec28f..70236caca2 100644 --- a/namedev.c +++ b/namedev.c @@ -22,7 +22,7 @@ */ /* define this to enable parsing debugging */ -/* #define DEBUG_PARSER */ +#define DEBUG_PARSER #include #include @@ -537,6 +537,65 @@ static int exec_callout(struct config_device *dev, char *value, int len) return retval; } +static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev) +{ + struct config_device *dev; + struct list_head *tmp; + char value[ID_SIZE]; + + list_for_each(tmp, &config_device_list) { + dev = list_entry(tmp, struct config_device, node); + if (dev->type != CALLOUT) + continue; + + if (exec_callout(dev, value, sizeof(value))) + continue; + if (strncmp(value, dev->id, sizeof(value)) != 0) + continue; + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); + } + dbg_parse("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->id, udev->name, + dev->owner, dev->group, dev->mode); + return 0; + } + return -ENODEV; +} + +static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev) +{ + struct config_device *dev; + struct list_head *tmp; + + list_for_each(tmp, &config_device_list) { + dev = list_entry(tmp, struct config_device, node); + if (dev->type != REPLACE) + continue; + + dbg_parse("REPLACE: replace name '%s' with '%s'", + dev->kernel_name, dev->name); + if (strcmp(dev->kernel_name, class_dev->name) != 0) + continue; + + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); + } + dbg_parse("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->kernel_name, udev->name, + dev->owner, dev->group, dev->mode); + + return 0; + } + return -ENODEV; +} + static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) { struct list_head *tmp; @@ -712,49 +771,22 @@ label_found: goto done; break; } - case CALLOUT: - { - char value[ID_SIZE]; - - if (exec_callout(dev, value, sizeof(value))) - continue; - if (strncmp(value, dev->id, sizeof(value)) != 0) - continue; - strcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); - } - dbg_parse("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->id, udev->name, - dev->owner, dev->group, dev->mode); - goto done; - break; - } - case REPLACE: - dbg_parse("REPLACE: replace name '%s' with '%s'", - dev->kernel_name, dev->name); - if (strcmp(dev->kernel_name, class_dev->name) != 0) - continue; - strcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); - } - dbg_parse("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->kernel_name, udev->name, - dev->owner, dev->group, dev->mode); - goto done; - break; case KERNEL_NAME: - break; default: - dbg_parse("Unknown type of device '%d'", dev->type); break; } } + + /* rules are looked at in priority order */ + + retval = do_callout(class_dev, udev); + if (retval == 0) + goto done; + + retval = do_replace(class_dev, udev); + if (retval == 0) + goto done; + strcpy(udev->name, class_dev->name); done: @@ -764,7 +796,7 @@ done: udev->owner[0] = 0x00; udev->group[0] = 0x00; } - return retval; + return 0; } int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev) From 4c7f03c33f0bb38aac8d699c440b12e715ac7bc2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 08:35:40 -0800 Subject: [PATCH 0146/4284] [PATCH] updated label test script (tests for partitions now.) --- test/label_test | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/label_test b/test/label_test index f06c416130..faa516fdce 100644 --- a/test/label_test +++ b/test/label_test @@ -8,7 +8,13 @@ export UDEV_DB=udev.tdb export UDEV_CONFIG_FILE=label_test.config export UDEV_PERMISSION_FILE=udev.permissions -export DEVPATH=block/sda export ACTION=add +export DEVPATH=block/sda ../udev block + +export DEVPATH=block/sda/sda3 + +../udev block + + From 7bd22a78a1a75857330031db44c68d07b049e809 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 17:38:14 -0800 Subject: [PATCH 0147/4284] [PATCH] clean up the way we find the sysdevice for a block device for namedev. --- namedev.c | 93 +++++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/namedev.c b/namedev.c index 70236caca2..2176e8ba71 100644 --- a/namedev.c +++ b/namedev.c @@ -599,13 +599,47 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) { struct list_head *tmp; + struct sysfs_device *sysfs_device = NULL; + struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; int found; + char *temp = NULL; udev->mode = 0; + + /* find the sysfs_device for this class device */ if (class_dev->sysdevice) { - dbg_parse("class_dev->sysdevice->path = '%s'", class_dev->sysdevice->path); - dbg_parse("class_dev->sysdevice->bus_id = '%s'", class_dev->sysdevice->bus_id); + sysfs_device = class_dev->sysdevice; + } else { + /* bah, let's go backwards up a level to see if the device is there, + * as block partitions don't point to the physical device. Need to fix that + * up in the kernel... + */ + if (strstr(class_dev->path, "block")) { + dbg_parse("looking at block device..."); + if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { + char path[SYSFS_PATH_MAX]; + + dbg_parse("really is a partition..."); + strcpy(path, class_dev->path); + temp = strrchr(path, '/'); + *temp = 0x00; + dbg_parse("looking for a class device at '%s'", path); + class_dev_parent = sysfs_open_class_device(path); + if (class_dev_parent == NULL) { + dbg("sysfs_open_class_device at '%s' failed", path); + } else { + dbg_parse("class_dev_parent->name = %s", class_dev_parent->name); + if (class_dev_parent->sysdevice) + sysfs_device = class_dev_parent->sysdevice; + } + } + } + } + + if (sysfs_device) { + dbg_parse("sysfs_device->path = '%s'", sysfs_device->path); + dbg_parse("sysfs_device->bus_id = '%s'", sysfs_device->bus_id); } else { dbg_parse("class_dev->name = '%s'", class_dev->name); } @@ -615,8 +649,6 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) case LABEL: { struct sysfs_attribute *tmpattr = NULL; - struct sysfs_class_device *class_dev_parent = NULL; - char *temp = NULL; dbg_parse("LABEL: match file '%s' with value '%s'", dev->sysfs_file, dev->sysfs_value); @@ -626,60 +658,19 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) goto label_found; /* look in the class device directory if present */ - if (class_dev->sysdevice) { - tmpattr = sysfs_get_device_attr(class_dev->sysdevice, dev->sysfs_file); + if (sysfs_device) { + tmpattr = sysfs_get_device_attr(sysfs_device, dev->sysfs_file); if (tmpattr) goto label_found; } - /* bah, let's go backwards up a level to see if the device is there, - * as block partitions don't point to the physical device. Need to fix that - * up in the kernel... - */ - if (strstr(class_dev->path, "block")) { - dbg_parse("looking at block device..."); - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - char path[SYSFS_PATH_MAX]; - - dbg_parse("really is a partition..."); - strcpy(path, class_dev->path); - temp = strrchr(path, '/'); - *temp = 0x00; - dbg_parse("looking for a class device at '%s'", path); - class_dev_parent = sysfs_open_class_device(path); - if (class_dev_parent == NULL) { - dbg("sysfs_open_class_device at '%s' failed", path); - continue; - } - dbg_parse("class_dev_parent->name = %s", class_dev_parent->name); - - /* try to find the attribute in the class device directory */ - tmpattr = sysfs_get_classdev_attr(class_dev_parent, dev->sysfs_file); - if (tmpattr) - goto label_found; - - /* look in the class device directory if present */ - if (class_dev_parent->sysdevice) { - tmpattr = sysfs_get_device_attr(class_dev_parent->sysdevice, dev->sysfs_file); - if (tmpattr) - goto label_found; - } - - } - } - if (class_dev_parent) - sysfs_close_class_device(class_dev_parent); - continue; label_found: tmpattr->value[strlen(tmpattr->value)-1] = 0x00; dbg_parse("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); - if (strcmp(dev->sysfs_value, tmpattr->value) != 0) { - if (class_dev_parent) - sysfs_close_class_device(class_dev_parent); + if (strcmp(dev->sysfs_value, tmpattr->value) != 0) continue; - } strcpy(udev->name, dev->name); if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { @@ -694,8 +685,6 @@ label_found: dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->sysfs_file, dev->sysfs_value, udev->name, dev->owner, dev->group, dev->mode); - if (class_dev_parent) - sysfs_close_class_device(class_dev_parent); goto done; break; } @@ -796,6 +785,10 @@ done: udev->owner[0] = 0x00; udev->group[0] = 0x00; } + + if (class_dev_parent) + sysfs_close_class_device(class_dev_parent); + return 0; } From 8a0c11d360a5c07f200cb421c5a4291dd00d5a09 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 17:56:26 -0800 Subject: [PATCH 0148/4284] [PATCH] fix bug where NUMBER and TOPOLOGY would not work for partitions. --- namedev.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/namedev.c b/namedev.c index 2176e8ba71..140d50079f 100644 --- a/namedev.c +++ b/namedev.c @@ -608,6 +608,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) udev->mode = 0; /* find the sysfs_device for this class device */ + /* Wouldn't it really be nice if libsysfs could do this for us? */ if (class_dev->sysdevice) { sysfs_device = class_dev->sysdevice; } else { @@ -691,12 +692,11 @@ label_found: case NUMBER: { char path[SYSFS_PATH_MAX]; - char *temp; found = 0; - if (!class_dev->sysdevice) + if (!sysfs_device) continue; - strcpy(path, class_dev->sysdevice->path); + strcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg_parse("NUMBER path = '%s'", path); dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); @@ -727,12 +727,11 @@ label_found: case TOPOLOGY: { char path[SYSFS_PATH_MAX]; - char *temp; - if (!class_dev->sysdevice) + if (!sysfs_device) continue; found = 0; - strcpy(path, class_dev->sysdevice->path); + strcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg_parse("TOPOLOGY path = '%s'", path); dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); From 8c51bbfe5f159d79b365a50a20218f616d6b67b5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 18:08:19 -0800 Subject: [PATCH 0149/4284] [PATCH] move TOPOLOGY rule to it's own function. --- namedev.c | 91 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 36 deletions(-) diff --git a/namedev.c b/namedev.c index 140d50079f..7c2db150be 100644 --- a/namedev.c +++ b/namedev.c @@ -566,6 +566,55 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev return -ENODEV; } +static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +{ + struct config_device *dev; + struct list_head *tmp; + char path[SYSFS_PATH_MAX]; + int found; + char *temp = NULL; + + /* we have to have a sysfs device for TOPOLOGY to work */ + if (!sysfs_device) + return -ENODEV; + + list_for_each(tmp, &config_device_list) { + dev = list_entry(tmp, struct config_device, node); + if (dev->type != TOPOLOGY) + continue; + + found = 0; + strcpy(path, sysfs_device->path); + temp = strrchr(path, '/'); + dbg_parse("TOPOLOGY path = '%s'", path); + dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + if (strstr(temp, dev->place) != NULL) { + found = 1; + } else { + *temp = 0x00; + temp = strrchr(path, '/'); + dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + if (strstr(temp, dev->place) != NULL) + found = 1; + } + if (!found) + continue; + + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); + } + dbg_parse("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->place, udev->name, + dev->owner, dev->group, dev->mode); + + return 0; + } + return -ENODEV; +} + static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev) { struct config_device *dev; @@ -696,7 +745,8 @@ label_found: found = 0; if (!sysfs_device) continue; - strcpy(path, sysfs_device->path); + s + rcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg_parse("NUMBER path = '%s'", path); dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); @@ -724,41 +774,6 @@ label_found: goto done; break; } - case TOPOLOGY: - { - char path[SYSFS_PATH_MAX]; - - if (!sysfs_device) - continue; - found = 0; - strcpy(path, sysfs_device->path); - temp = strrchr(path, '/'); - dbg_parse("TOPOLOGY path = '%s'", path); - dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); - if (strstr(temp, dev->place) != NULL) { - found = 1; - } else { - *temp = 0x00; - temp = strrchr(path, '/'); - dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); - if (strstr(temp, dev->place) != NULL) - found = 1; - } - if (!found) - continue; - - strcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); - } - dbg_parse("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->place, udev->name, - dev->owner, dev->group, dev->mode); - goto done; - break; - } case KERNEL_NAME: default: break; @@ -771,6 +786,10 @@ label_found: if (retval == 0) goto done; + retval = do_topology(class_dev, udev, sysfs_device); + if (retval == 0) + goto done; + retval = do_replace(class_dev, udev); if (retval == 0) goto done; From a38c862f88b4794ba6bb2b6ef256100dd26b86bb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Nov 2003 18:08:40 -0800 Subject: [PATCH 0150/4284] [PATCH] add TOPO regression test. --- test/topo_test | 20 ++++++++++++++++++++ test/topo_test.config | 3 +++ 2 files changed, 23 insertions(+) create mode 100644 test/topo_test create mode 100644 test/topo_test.config diff --git a/test/topo_test b/test/topo_test new file mode 100644 index 0000000000..5a557e909d --- /dev/null +++ b/test/topo_test @@ -0,0 +1,20 @@ +#!/bin/bash + +export UDEV_TEST=yes +export SYSFS_PATH=$PWD/sys/ +export UDEV_CONFIG_DIR=$PWD/ +export UDEV_ROOT=$PWD/udev/ +export UDEV_DB=udev.tdb +export UDEV_CONFIG_FILE=topo_test.config +export UDEV_PERMISSION_FILE=udev.permissions + +export ACTION=add +export DEVPATH=block/sda + +../udev block + +export DEVPATH=block/sda/sda3 + +../udev block + + diff --git a/test/topo_test.config b/test/topo_test.config new file mode 100644 index 0000000000..d7ae92b080 --- /dev/null +++ b/test/topo_test.config @@ -0,0 +1,3 @@ +# TOPO test +TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="first_disk" + From ca1cc0fe7489c40a137ece43a65e65765678e89d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 13 Nov 2003 05:52:08 -0800 Subject: [PATCH 0151/4284] [PATCH] splig LABEL and NUMBER into separate functions. Now items are processed in priority order, fixing that bug. --- namedev.c | 198 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 109 insertions(+), 89 deletions(-) diff --git a/namedev.c b/namedev.c index 7c2db150be..d806d25edf 100644 --- a/namedev.c +++ b/namedev.c @@ -566,6 +566,107 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev return -ENODEV; } +static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +{ + struct sysfs_attribute *tmpattr = NULL; + struct config_device *dev; + struct list_head *tmp; + char *temp = NULL; + + list_for_each(tmp, &config_device_list) { + dev = list_entry(tmp, struct config_device, node); + if (dev->type != LABEL) + continue; + + dbg_parse("LABEL: match file '%s' with value '%s'", + dev->sysfs_file, dev->sysfs_value); + /* try to find the attribute in the class device directory */ + tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); + if (tmpattr) + goto label_found; + + /* look in the class device directory if present */ + if (sysfs_device) { + tmpattr = sysfs_get_device_attr(sysfs_device, dev->sysfs_file); + if (tmpattr) + goto label_found; + } + + continue; + +label_found: + tmpattr->value[strlen(tmpattr->value)-1] = 0x00; + dbg_parse("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); + if (strcmp(dev->sysfs_value, tmpattr->value) != 0) + continue; + + strcpy(udev->name, dev->name); + if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { + temp = &class_dev->path[strlen(class_dev->path)-1]; + strcat(udev->name, temp); + } + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); + } + dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->sysfs_file, dev->sysfs_value, udev->name, + dev->owner, dev->group, dev->mode); + + return 0; + } + return -ENODEV; +} + +static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +{ + struct config_device *dev; + struct list_head *tmp; + char path[SYSFS_PATH_MAX]; + int found; + char *temp = NULL; + + /* we have to have a sysfs device for NUMBER to work */ + if (!sysfs_device) + return -ENODEV; + + list_for_each(tmp, &config_device_list) { + dev = list_entry(tmp, struct config_device, node); + if (dev->type != NUMBER) + continue; + + found = 0; + strcpy(path, sysfs_device->path); + temp = strrchr(path, '/'); + dbg_parse("NUMBER path = '%s'", path); + dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); + if (strstr(temp, dev->id) != NULL) { + found = 1; + } else { + *temp = 0x00; + temp = strrchr(path, '/'); + dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); + if (strstr(temp, dev->id) != NULL) + found = 1; + } + if (!found) + continue; + strcpy(udev->name, dev->name); + if (dev->mode != 0) { + udev->mode = dev->mode; + strcpy(udev->owner, dev->owner); + strcpy(udev->group, dev->group); + } + dbg_parse("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", + dev->id, udev->name, + dev->owner, dev->group, dev->mode); + return 0; + } + return -ENODEV; +} + + static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; @@ -647,11 +748,9 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) { - struct list_head *tmp; struct sysfs_device *sysfs_device = NULL; struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; - int found; char *temp = NULL; udev->mode = 0; @@ -693,99 +792,20 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) } else { dbg_parse("class_dev->name = '%s'", class_dev->name); } - list_for_each(tmp, &config_device_list) { - struct config_device *dev = list_entry(tmp, struct config_device, node); - switch (dev->type) { - case LABEL: - { - struct sysfs_attribute *tmpattr = NULL; - - dbg_parse("LABEL: match file '%s' with value '%s'", - dev->sysfs_file, dev->sysfs_value); - /* try to find the attribute in the class device directory */ - tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); - if (tmpattr) - goto label_found; - - /* look in the class device directory if present */ - if (sysfs_device) { - tmpattr = sysfs_get_device_attr(sysfs_device, dev->sysfs_file); - if (tmpattr) - goto label_found; - } - - continue; - -label_found: - tmpattr->value[strlen(tmpattr->value)-1] = 0x00; - dbg_parse("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); - if (strcmp(dev->sysfs_value, tmpattr->value) != 0) - continue; - - strcpy(udev->name, dev->name); - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - temp = &class_dev->path[strlen(class_dev->path)-1]; - strcat(udev->name, temp); - } - if (dev->mode != 0) { - udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); - } - dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->sysfs_file, dev->sysfs_value, udev->name, - dev->owner, dev->group, dev->mode); - goto done; - break; - } - case NUMBER: - { - char path[SYSFS_PATH_MAX]; - - found = 0; - if (!sysfs_device) - continue; - s - rcpy(path, sysfs_device->path); - temp = strrchr(path, '/'); - dbg_parse("NUMBER path = '%s'", path); - dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); - if (strstr(temp, dev->id) != NULL) { - found = 1; - } else { - *temp = 0x00; - temp = strrchr(path, '/'); - dbg_parse("NUMBERY temp = '%s' id = '%s'", temp, dev->id); - if (strstr(temp, dev->id) != NULL) - found = 1; - } - if (!found) - continue; - - strcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); - } - dbg_parse("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->id, udev->name, - dev->owner, dev->group, dev->mode); - goto done; - break; - } - case KERNEL_NAME: - default: - break; - } - } /* rules are looked at in priority order */ - retval = do_callout(class_dev, udev); if (retval == 0) goto done; + retval = do_label(class_dev, udev, sysfs_device); + if (retval == 0) + goto done; + + retval = do_number(class_dev, udev, sysfs_device); + if (retval == 0) + goto done; + retval = do_topology(class_dev, udev, sysfs_device); if (retval == 0) goto done; From 20ff86bd7111221e8709c614c5e3969950293664 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 13 Nov 2003 06:24:09 -0800 Subject: [PATCH 0152/4284] [PATCH] trailing whitespace cleanups. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index d806d25edf..d76d03b490 100644 --- a/namedev.c +++ b/namedev.c @@ -684,7 +684,7 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude if (dev->type != TOPOLOGY) continue; - found = 0; + found = 0; strcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg_parse("TOPOLOGY path = '%s'", path); From 04a091d47e32d6480b99424e41db093b013dfaf5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 13 Nov 2003 06:30:57 -0800 Subject: [PATCH 0153/4284] [PATCH] Add multipath "extra" program from Christophe Varoqui, --- extras/multipath/AUTHOR | 1 + extras/multipath/COPYING | 483 +++++++++++++ extras/multipath/ChangeLog | 3 + extras/multipath/Makefile | 34 + extras/multipath/README | 82 +++ extras/multipath/VERSION | 1 + extras/multipath/main.c | 741 ++++++++++++++++++++ extras/multipath/main.h | 111 +++ extras/multipath/sg_err.c | 1197 +++++++++++++++++++++++++++++++++ extras/multipath/sg_err.h | 162 +++++ extras/multipath/sg_include.h | 44 ++ 11 files changed, 2859 insertions(+) create mode 100644 extras/multipath/AUTHOR create mode 100644 extras/multipath/COPYING create mode 100644 extras/multipath/ChangeLog create mode 100644 extras/multipath/Makefile create mode 100644 extras/multipath/README create mode 100644 extras/multipath/VERSION create mode 100644 extras/multipath/main.c create mode 100644 extras/multipath/main.h create mode 100644 extras/multipath/sg_err.c create mode 100644 extras/multipath/sg_err.h create mode 100644 extras/multipath/sg_include.h diff --git a/extras/multipath/AUTHOR b/extras/multipath/AUTHOR new file mode 100644 index 0000000000..4e8eeef5c8 --- /dev/null +++ b/extras/multipath/AUTHOR @@ -0,0 +1 @@ +Christophe Varoqui, diff --git a/extras/multipath/COPYING b/extras/multipath/COPYING new file mode 100644 index 0000000000..9e31bbf0b3 --- /dev/null +++ b/extras/multipath/COPYING @@ -0,0 +1,483 @@ + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, 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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, 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 companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog new file mode 100644 index 0000000000..f3014cf01e --- /dev/null +++ b/extras/multipath/ChangeLog @@ -0,0 +1,3 @@ +2003-09-18 Christophe Varoqui + * multipath 0.0.1 released. + * Initial release. diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile new file mode 100644 index 0000000000..0835d7a2c6 --- /dev/null +++ b/extras/multipath/Makefile @@ -0,0 +1,34 @@ +# Makefile +# +# Copyright (C) 2003 Christophe Varoqui, + +EXEC = multipath + +prefix = /usr/local +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin + +CC = gcc +CFLAGS = -g -O2 -Wall -Wunused -Wstrict-prototypes +LDFLAGS = -lsysfs -ldevmapper + +OBJS = main.o sg_err.o + +all: $(EXEC) + strip $(EXEC) + @echo "" + @echo "Make complete" + +$(EXEC): $(OBJS) + $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) + +clean: + rm -f core *.o $(EXEC) + +install: + install -d $(bindir) + install -m 755 $(EXEC) $(bindir)/ + +# Code dependencies +main.o: main.c main.h sg_err.h sg_include.h +sg_err.o: sg_err.c sg_err.h sg_include.h diff --git a/extras/multipath/README b/extras/multipath/README new file mode 100644 index 0000000000..6a5637de4b --- /dev/null +++ b/extras/multipath/README @@ -0,0 +1,82 @@ +Dependancies : +============== + +o libdevmapper : comes with device-mapper-XXXX.tar.gz + See www.sistina.com +o libsysfs : comes with sysutils + See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ + +How it works : +============== + +Fill the all_paths array. Each path store this info : + +struct path { + char dev[FILE_NAME_SIZE]; + char sg_dev[FILE_NAME_SIZE]; + struct scsi_idlun scsi_id; + struct sg_id sg_id; + int state; + char wwid[WWID_SIZE]; +}; + +scsi_id, sg_dev and sg_id are only really useful for 2.4 +kernels, for which SG cmnds must go through sg devs. +In 2.5+ we have the nice opportunity to send SG cmnds +through SCSI bdevs. + +For 2.4 compat, we pivot on idlun tupple to map sg devs +to SCSI bdevs. + +2.4 does not do device enumeration, so we must scan a +defined number of sg devs and scsi bdevs. Good enough. +In 2.5+, we rely on libsysfs (sysutils) to access to +sysfs device enums. + +the wwid is retrieved by a switch fonction. Only White +Listed HW can filled this field. For now only +StorageWorks HW is White Listed. (See notes) + +When all_paths is filled, we coalesce the paths and store +the result in mp array. Each mp is a struct like this : + +struct multipath { + char wwid[WWID_SIZE]; + int npaths; + int pindex[MAX_MP_PATHS]; +}; + +When mp is filled, the device maps are fed to the kernel +through libdevmapper. Stale paths (failed TUR) are +discarded. + +Notes : +======= + +o make sure you have enough /dev/sg* nodes + (/dev/MAKEDEV if necesary) + +o path coalescing relies on a path unique id being found. + This unique id, lacking a standard method, is vendor + specific. A switch function (get_unique_id) is present + and an example function is provided for storageworks + arrays (get_storageworks_wwid). Feel free to enrich + with hardware you have at hand :) + +o Something goes wrong with sd.o, qla2200 & dm-mod + refcounting : I can't unload these modules after exec. + +o The kernel does NOT manage properly ghosts paths + with StorageWorks HW. Seems nobody cares after a load + of posts to linux-scsi. + +o 2.4.21 version of DM does not like even segment size. + if you enconter pbs with this, upgrade DM. + +Credits : +========= + +o Heavy cut'n paste from sg_utils. Thanks goes to D. + Gilbert. +o Light cut'n paste from dmsetup. Thanks Joe Thornber. +o Greg KH for the nice sysfs API. diff --git a/extras/multipath/VERSION b/extras/multipath/VERSION new file mode 100644 index 0000000000..bbdeab6222 --- /dev/null +++ b/extras/multipath/VERSION @@ -0,0 +1 @@ +0.0.5 diff --git a/extras/multipath/main.c b/extras/multipath/main.c new file mode 100644 index 0000000000..0ed74c52a9 --- /dev/null +++ b/extras/multipath/main.c @@ -0,0 +1,741 @@ +/* + * Soft: Description here... + * + * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ + * + * Author: Copyright (C) 2003 Christophe Varoqui + * + * 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. + * + * 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 +#include "main.h" + +static int +do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, + void *resp, int mx_resp_len, int noisy) +{ + int res; + unsigned char inqCmdBlk[INQUIRY_CMDLEN] = + { INQUIRY_CMD, 0, 0, 0, 0, 0 }; + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_io_hdr io_hdr; + + if (cmddt) + inqCmdBlk[1] |= 2; + if (evpd) + inqCmdBlk[1] |= 1; + inqCmdBlk[2] = (unsigned char) pg_op; + inqCmdBlk[4] = (unsigned char) mx_resp_len; + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (inqCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_b); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = mx_resp_len; + io_hdr.dxferp = resp; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sense_b; + io_hdr.timeout = DEF_TIMEOUT; + + if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { + perror("SG_IO (inquiry) error"); + return -1; + } + res = sg_err_category3(&io_hdr); + switch (res) { + case SG_ERR_CAT_CLEAN: + case SG_ERR_CAT_RECOVERED: + return 0; + default: + return -1; + } +} + +static int +do_tur(int fd) +{ + unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; + struct sg_io_hdr io_hdr; + unsigned char sense_buffer[32]; + + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (turCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_buffer); + io_hdr.dxfer_direction = SG_DXFER_NONE; + io_hdr.cmdp = turCmdBlk; + io_hdr.sbp = sense_buffer; + io_hdr.timeout = 20000; + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + close(fd); + return 0; + } + if (io_hdr.info & SG_INFO_OK_MASK) { + return 0; + } + return 1; +} + +static void +sprint_wwid(char * buff, const char * str) +{ + int i; + const char *p; + char *cursor; + unsigned char c; + + p = str; + cursor = buff; + for (i = 0; i <= WWID_SIZE / 2 - 1; i++) { + c = *p++; + sprintf(cursor, "%.2x", (int) (unsigned char) c); + cursor += 2; + } + buff[WWID_SIZE - 1] = '\0'; +} + +static int +get_lun_strings(int fd, struct path * mypath) +{ + char buff[36]; + + if (0 == do_inq(fd, 0, 0, 0, buff, 36, 1)) { + memcpy(mypath->vendor_id, &buff[8], 8); + memcpy(mypath->product_id, &buff[16], 16); + memcpy(mypath->rev, &buff[32], 4); + return 1; + } + return 0; +} + +/* +static int +get_serial (int fd, char * str) +{ + char buff[MX_ALLOC_LEN + 1]; + int len; + + if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { + len = buff[3]; + if (len > 0) { + memcpy(str, buff + 4, len); + buff[len] = '\0'; + } + return 1; + } + return 0; +} +*/ + +/* hardware vendor specifics : add support for new models below */ +static int +get_storageworks_wwid(int fd, char *str) +{ + char buff[64]; + + if (0 == do_inq(fd, 0, 1, 0x83, buff, sizeof (buff), 1)) { + sprint_wwid(str, &buff[8]); + return 1; + } + return 0; +} + +/* White list switch */ +static int +get_unique_id(int fd, struct path * mypath) +{ + if (strncmp(mypath->product_id, "HSV110 (C)COMPAQ", 16) == 0 || + strncmp(mypath->product_id, "HSG80 ", 16) == 0) { + get_storageworks_wwid(fd, mypath->wwid); + return 0; + } + + return 1; +} + +static void +basename(char * str1, char * str2) +{ + char *p = str1 + (strlen(str1) - 1); + + while (*--p != '/') + continue; + strcpy(str2, ++p); +} + +static int +get_all_paths_sysfs(struct env * conf, struct path * all_paths) +{ + int k=0; + int sg_fd; + struct sysfs_directory * sdir; + struct sysfs_directory * devp; + struct sysfs_dlink * linkp; + char buff[FILE_NAME_SIZE]; + + char block_path[FILE_NAME_SIZE]; + + sprintf(block_path, "%s/block", conf->sysfs_path); + sdir = sysfs_open_directory(block_path); + sysfs_read_directory(sdir); + devp = sdir->subdirs; + while (devp != NULL) { + sysfs_read_directory(devp); + linkp = devp->links; + while (linkp != NULL) { + if (!strncmp(linkp->name, "device", 6)) + break; + linkp = linkp->next; + } + if (linkp == NULL) { + devp = devp->next; + continue; + } + + basename(devp->path, buff); + sprintf(all_paths[k].sg_dev, "/dev/%s", buff); + strcpy(all_paths[k].dev, all_paths[k].sg_dev); + if ((sg_fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) { + devp = devp->next; + continue; + } + get_lun_strings(sg_fd, &all_paths[k]); + get_unique_id(sg_fd, &all_paths[k]); + all_paths[k].state = do_tur(sg_fd); + close(sg_fd); + basename(linkp->target->path, buff); + sscanf(buff, "%i:%i:%i:%i", + &all_paths[k].sg_id.host_no, + &all_paths[k].sg_id.channel, + &all_paths[k].sg_id.scsi_id, + &all_paths[k].sg_id.lun); + k++; + devp = devp->next; + } + sysfs_close_directory(sdir); + + return 0; +} + +static int +get_all_paths_nosysfs(struct env * conf, struct path * all_paths, + struct scsi_dev * all_scsi_ids) +{ + int k, i, sg_fd; + char buff[FILE_NAME_SIZE]; + char file_name[FILE_NAME_SIZE]; + + for (k = 0; k < conf->max_devs; k++) { + strcpy(file_name, "/dev/sg"); + sprintf(buff, "%d", k); + strncat(file_name, buff, FILE_NAME_SIZE); + strcpy(all_paths[k].sg_dev, file_name); + if ((sg_fd = open(file_name, O_RDONLY)) < 0) + continue; + get_lun_strings(sg_fd, &all_paths[k]); + get_unique_id(sg_fd, &all_paths[k]); + all_paths[k].state = do_tur(sg_fd); + if (0 > ioctl(sg_fd, SG_GET_SCSI_ID, &(all_paths[k].sg_id))) + printf("device %s failed on sg ioctl, skip\n", + file_name); + + close(sg_fd); + + for (i = 0; i < conf->max_devs; i++) { + if ((all_paths[k].sg_id.host_no == + all_scsi_ids[i].host_no) + && (all_paths[k].sg_id.scsi_id == + (all_scsi_ids[i].scsi_id.dev_id & 0xff)) + && (all_paths[k].sg_id.lun == + ((all_scsi_ids[i].scsi_id.dev_id >> 8) & 0xff)) + && (all_paths[k].sg_id.channel == + ((all_scsi_ids[i].scsi_id. + dev_id >> 16) & 0xff))) { + strcpy(all_paths[k].dev, all_scsi_ids[i].dev); + break; + } + } + } + return 0; +} + +static int +get_all_scsi_ids(struct env * conf, struct scsi_dev * all_scsi_ids) +{ + int k, big, little, res, host_no, fd; + char buff[64]; + char fname[FILE_NAME_SIZE]; + struct scsi_idlun my_scsi_id; + + for (k = 0; k < conf->max_devs; k++) { + strcpy(fname, "/dev/sd"); + if (k < 26) { + buff[0] = 'a' + (char) k; + buff[1] = '\0'; + strcat(fname, buff); + } else if (k <= 255) { /* assumes sequence goes x,y,z,aa,ab,ac etc */ + big = k / 26; + little = k - (26 * big); + big = big - 1; + + buff[0] = 'a' + (char) big; + buff[1] = 'a' + (char) little; + buff[2] = '\0'; + strcat(fname, buff); + } else + strcat(fname, "xxxx"); + + if ((fd = open(fname, O_RDONLY)) < 0) + continue; + + res = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &my_scsi_id); + if (res < 0) { + close(fd); + printf("Could not get scsi idlun\n"); + continue; + } + + res = ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &host_no); + if (res < 0) { + close(fd); + printf("Could not get host_no\n"); + continue; + } + + close(fd); + + strcpy(all_scsi_ids[k].dev, fname); + all_scsi_ids[k].scsi_id = my_scsi_id; + all_scsi_ids[k].host_no = host_no; + } + return 0; +} + +/* print_path style */ +#define ALL 0 +#define NOWWID 1 + +static void +print_path(struct path * all_paths, int k, int style) +{ + if (style != NOWWID) + printf("%s ", all_paths[k].wwid); + else + printf(" \\_"); + printf("(%i %i %i %i) ", + all_paths[k].sg_id.host_no, + all_paths[k].sg_id.channel, + all_paths[k].sg_id.scsi_id, all_paths[k].sg_id.lun); + printf("%s ", all_paths[k].sg_dev); + printf("op:%i ", all_paths[k].state); + printf("%s ", all_paths[k].dev); + printf("[%.16s]\n", all_paths[k].product_id); +} + +static void +print_all_path(struct env * conf, struct path * all_paths) +{ + int k; + char empty_buff[WWID_SIZE]; + + memset(empty_buff, 0, WWID_SIZE); + for (k = 0; k < conf->max_devs; k++) { + if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) + continue; + print_path(all_paths, k, ALL); + } +} + +static void +print_all_mp(struct path * all_paths, struct multipath * mp, int nmp) +{ + int k, i; + + for (k = 0; k <= nmp; k++) { + printf("%s\n", mp[k].wwid); + for (i = 0; i <= mp[k].npaths; i++) + print_path(all_paths, PINDEX(k,i), NOWWID); + } +} + +static int +coalesce_paths(struct env * conf, struct multipath * mp, + struct path * all_paths) +{ + int k, i, nmp, np, already_done; + char empty_buff[WWID_SIZE]; + + nmp = -1; + already_done = 0; + memset(empty_buff, 0, WWID_SIZE); + + for (k = 0; k < conf->max_devs - 1; k++) { + /* skip this path if no unique id has been found */ + if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) + continue; + np = 0; + + for (i = 0; i <= nmp; i++) { + if (0 == strcmp(mp[i].wwid, all_paths[k].wwid)) + already_done = 1; + } + + if (already_done) { + already_done = 0; + continue; + } + + nmp++; + strcpy(mp[nmp].wwid, all_paths[k].wwid); + PINDEX(nmp,np) = k; + + for (i = k + 1; i < conf->max_devs; i++) { + if (0 == strcmp(all_paths[k].wwid, all_paths[i].wwid)) { + np++; + PINDEX(nmp,np) = i; + mp[nmp].npaths = np; + } + } + } + return nmp; +} + +static long +get_disk_size (struct env * conf, char * dev) { + long size; + int fd; + char attr_path[FILE_NAME_SIZE]; + char buff[FILE_NAME_SIZE]; + char basedev[FILE_NAME_SIZE]; + + if(conf->with_sysfs) { + basename(dev, basedev); + sprintf(attr_path, "%s/block/%s/size", + conf->sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, buff, + FILE_NAME_SIZE * sizeof(char))) + return -1; + size = atoi(buff); + return size; + } else { + if ((fd = open(dev, O_RDONLY)) < 0) + return -1; + if(!ioctl(fd, BLKGETSIZE, &size)) + return size; + } + return -1; +} + +static int +make_dm_node(char * str) +{ + int r = 0; + dev_t dev; + char buff[FILE_NAME_SIZE]; + int major, minor; + struct dm_names * names; + unsigned next = 0; + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) + return 0; + + if (!dm_task_run(dmt)) + goto out; + + if (!(names = dm_task_get_names(dmt))) + goto out; + + if (!names->dev) { + r = 1; + goto out; + } + + do { + if (0 == strcmp(names->name, str)) + break; + next = names->next; + names = (void *) names + next; + } while (next); + + major = (int) MAJOR(names->dev); + minor = (int) MINOR(names->dev); + + dev = major << sizeof(dev_t); + dev = dev | minor; + sprintf(buff, "/dev/mapper/%s", str); + unlink(buff); + mknod(buff, 0600 | S_IFBLK, dev); + + out: + dm_task_destroy(dmt); + return r; + +} + +/* future use ? +static int +del_map(char * str) { + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) + return 0; + if (!dm_task_set_name(dmt, str)) + goto delout; + if (!dm_task_run(dmt)) + goto delout; + + printf("Deleted device map : %s\n", str); + + delout: + dm_task_destroy(dmt); + return 1; +} +*/ + +static int +add_map(struct env * conf, struct path * all_paths, + struct multipath * mp, int index, int op) +{ + char params[255]; + char * params_p; + struct dm_task *dmt; + int i, np; + long size = -1; + + if (!(dmt = dm_task_create(op))) + return 0; + + if (!dm_task_set_name(dmt, mp[index].wwid)) + goto addout; + params_p = ¶ms[0]; + + np = 0; + for (i=0; i<=mp[index].npaths; i++) { + if ((1 == all_paths[PINDEX(index,i)].state) && + (0 == all_paths[PINDEX(index,i)].sg_id.scsi_type)) + np++; + } + if (np == 0) + goto addout; + params_p += sprintf(params_p, "%i 32", np); + + for (i=0; i<=mp[index].npaths; i++) { + if (( 0 == all_paths[PINDEX(index,i)].state) || + (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type)) + continue; + if (size < 0) + size = get_disk_size(conf, all_paths[PINDEX(index,0)].dev); + params_p += sprintf(params_p, " %s %i", + all_paths[PINDEX(index,i)].dev, 0); + } + + if (size < 0) + goto addout; + + if (!conf->quiet) { + if (op == DM_DEVICE_RELOAD) + printf("U|"); + if (op == DM_DEVICE_CREATE) + printf("N|"); + printf("%s : 0 %li %s %s\n", + mp[index].wwid, size, DM_TARGET, params); + } + + if (!dm_task_add_target(dmt, 0, size, DM_TARGET, params)) + goto addout; + + if (!dm_task_run(dmt)) + goto addout; + + + make_dm_node(mp[index].wwid); + + addout: + dm_task_destroy(dmt); + return 1; +} + +/* +static int +get_table(const char * str) +{ + int r = 0; + struct dm_task *dmt; + void *next = NULL; + uint64_t start, length; + char *target_type = NULL; + char *params; + + if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) + return 0; + + if (!dm_task_set_name(dmt, str)) + goto out; + + if (!dm_task_run(dmt)) + goto out; + + do { + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, ¶ms); + if (target_type) { + printf("%" PRIu64 " %" PRIu64 " %s %s\n", + start, length, target_type, params); + } + } while (next); + + r = 1; + + out: + dm_task_destroy(dmt); + return r; + +} +*/ + +static int +map_present(char * str) +{ + int r = 0; + struct dm_task *dmt; + struct dm_names *names; + unsigned next = 0; + + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) + return 0; + + if (!dm_task_run(dmt)) + goto out; + + if (!(names = dm_task_get_names(dmt))) + goto out; + + if (!names->dev) { + goto out; + } + + do { + if (0 == strcmp(names->name, str)) + r = 1; + next = names->next; + names = (void *) names + next; + } while (next); + + out: + dm_task_destroy(dmt); + return r; +} + +static void +usage(char * progname) +{ + fprintf(stderr, VERSION_STRING); + fprintf(stderr, "Usage: %s [-v|-q] [-d] [-m max_devs]\n", progname); + fprintf(stderr, "\t-v\t\tverbose, print all paths and multipaths\n"); + fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); + fprintf(stderr, "\t-d\t\tdry run, do not create or update devmaps\n"); + fprintf(stderr, "\t-m max_devs\tscan {max_devs} devices at most\n"); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct multipath * mp; + struct path * all_paths; + struct scsi_dev * all_scsi_ids; + struct env conf; + int i, k, nmp; + + /* Default behaviour */ + conf.max_devs = MAX_DEVS; + conf.dry_run = 0; /* 1 == Do not Create/Update devmaps */ + conf.verbose = 0; /* 1 == Print all_paths and mp */ + conf.quiet = 0; /* 1 == Do not even print devmaps */ + conf.with_sysfs = 0; /* Default to compat / suboptimal behaviour */ + + /* kindly provided by libsysfs */ + if (0 == sysfs_get_mnt_path(conf.sysfs_path, FILE_NAME_SIZE)) + conf.with_sysfs = 1; + + for (i = 1; i < argc; ++i) { + if (0 == strcmp("-v", argv[i])) { + if (conf.quiet == 1) + usage(argv[0]); + conf.verbose = 1; + } else if (0 == strcmp("-m", argv[i])) { + conf.max_devs = atoi(argv[++i]); + if (conf.max_devs < 2) + usage(argv[0]); + } else if (0 == strcmp("-q", argv[i])) { + if (conf.verbose == 1) + usage(argv[0]); + conf.quiet = 1; + } else if (0 == strcmp("-d", argv[i])) + conf.dry_run = 1; + else if (*argv[i] == '-') { + fprintf(stderr, "Unknown switch: %s\n", argv[i]); + usage(argv[0]); + } else if (*argv[i] != '-') { + fprintf(stderr, "Unknown argument\n"); + usage(argv[0]); + } + + } + + /* dynamic allocations */ + mp = malloc(conf.max_devs * sizeof(struct multipath)); + all_paths = malloc(conf.max_devs * sizeof(struct path)); + all_scsi_ids = malloc(conf.max_devs * sizeof(struct scsi_dev)); + if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) + exit(1); + + if (!conf.with_sysfs) { + get_all_scsi_ids(&conf, all_scsi_ids); + get_all_paths_nosysfs(&conf, all_paths, all_scsi_ids); + } else { + get_all_paths_sysfs(&conf, all_paths); + } + nmp = coalesce_paths(&conf, mp, all_paths); + + if (conf.verbose) { + print_all_path(&conf, all_paths); + printf("\n"); + print_all_mp(all_paths, mp, nmp); + printf("\n"); + } + + if (conf.dry_run) + exit(0); + + for (k=0; k<=nmp; k++) { + if (map_present(mp[k].wwid)) { + add_map(&conf, all_paths, mp, k, DM_DEVICE_RELOAD); + } else { + add_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); + } + } + exit(0); +} diff --git a/extras/multipath/main.h b/extras/multipath/main.h new file mode 100644 index 0000000000..43a24ac7bc --- /dev/null +++ b/extras/multipath/main.h @@ -0,0 +1,111 @@ +/* + * Soft: Description here... + * + * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ + * + * Author: Copyright (C) 2003 Christophe Varoqui + * + * 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. + * + * 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. + */ + +#ifndef _MAIN_H +#define _MAIN_H + +/* local includes */ +#include "sg_include.h" +#include "sg_err.h" + +/* global defs */ +#define WWID_SIZE 33 +#define MAX_DEVS 128 +#define MAX_MP MAX_DEVS / 2 +#define MAX_MP_PATHS MAX_DEVS / 4 +#define FILE_NAME_SIZE 256 +#define INQUIRY_CMDLEN 6 +#define INQUIRY_CMD 0x12 +#define SENSE_BUFF_LEN 32 +#define DEF_TIMEOUT 60000 +#define EBUFF_SZ 256 +#define TUR_CMD_LEN 6 +#define MX_ALLOC_LEN 255 +#define BLKGETSIZE _IO(0x12,96) +#define DM_TARGET "striped" + +#define PINDEX(x,y) mp[(x)].pindex[(y)] + +/* global types */ +struct scsi_idlun { + int dev_id; + int host_unique_id; + int host_no; +}; + +struct sg_id { + int host_no; + int channel; + int scsi_id; + int lun; + int scsi_type; + short h_cmd_per_lun; + short d_queue_depth; + int unused1; + int unused2; +}; + +struct scsi_dev { + char dev[FILE_NAME_SIZE]; + struct scsi_idlun scsi_id; + int host_no; +}; + +struct path { + char dev[FILE_NAME_SIZE]; + char sg_dev[FILE_NAME_SIZE]; + struct scsi_idlun scsi_id; + struct sg_id sg_id; + int state; + char wwid[WWID_SIZE]; + char vendor_id[8]; + char product_id[16]; + char rev[4]; +}; + +struct multipath { + char wwid[WWID_SIZE]; + int npaths; + int pindex[MAX_MP_PATHS]; +}; + +struct env { + int max_devs; + int verbose; + int quiet; + int dry_run; + int with_sysfs; + char sysfs_path[FILE_NAME_SIZE]; +}; + +/* Build version */ +#define PROG "multipath" + +#define VERSION_CODE 0x000005 +#define DATE_CODE 0x120903 + +#define MULTIPATH_VERSION(version) \ + (version >> 16) & 0xFF, \ + (version >> 8) & 0xFF, \ + version & 0xFF + +#define VERSION_STRING PROG" v%d.%d.%d (%.2d/%.2d, 20%.2d)\n", \ + MULTIPATH_VERSION(VERSION_CODE), \ + MULTIPATH_VERSION(DATE_CODE) + +#endif diff --git a/extras/multipath/sg_err.c b/extras/multipath/sg_err.c new file mode 100644 index 0000000000..8a332cd8c6 --- /dev/null +++ b/extras/multipath/sg_err.c @@ -0,0 +1,1197 @@ +#include +#include +#include +#include "sg_include.h" +#include "sg_err.h" + + +/* This file is a huge cut, paste and hack from linux/drivers/scsi/constant.c +* which I guess was written by: +* Copyright (C) 1993, 1994, 1995 Eric Youngdale + +* The rest of this is: +* Copyright (C) 1999 - 2003 D. Gilbert +* +* 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, or (at your option) +* any later version. +* +* ASCII values for a number of symbolic constants, printing functions, etc. +* +* Some of the tables have been updated for SCSI 2. +* Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 12 18 March 2003) +* +* Version 0.91 (20030529) +* sense key specific field (bytes 15-17) decoding [Trent Piepho] +*/ + +#define OUTP stderr + +static const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, + 16, 12, 10, 10 }; + +#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] + +static const char unknown[] = "UNKNOWN"; + +static const char * group_0_commands[] = { +/* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense", +/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks", +/* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown, +/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry", +/* 13-16 */ "Verify", "Recover Buffered Data", "Mode Select", "Reserve", +/* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit", +/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", +/* 1e-1f */ "Prevent/Allow Medium Removal", unknown, +}; + + +static const char *group_1_commands[] = { +/* 20-23 */ unknown, unknown, unknown, "Read Format capacities", +/* 24-28 */ "Set window", "Read Capacity", + unknown, unknown, "Read (10)", +/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase", + "Read updated block", +/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal", +/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", +/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data", +/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", + "Read Buffer", +/* 3d-3f */ "Update Block", "Read Long", "Write Long", +}; + +static const char *group_2_commands[] = { +/* 40-41 */ "Change Definition", "Write Same", +/* 42-48 */ "Read sub-channel", "Read TOC", "Read header", + "Play audio (10)", "Get configuration", "Play audio msf", + "Play audio track/index", +/* 49-4f */ "Play track relative (10)", "Get event status notification", + "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", + unknown, +/* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info", + "Reserve track", "Send OPC onfo", "Mode Select (10)", +/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue", + "Mode Sense (10)", "Close track/session", +/* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in", + "Persistent reserve out", +}; + +/* The following are 16 byte commands in group 4 */ +static const char *group_4_commands[] = { +/* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy", + "Receive copy results", +/* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out", + "Read (16)", "Memory Export Out (16)", +/* 8a-8f */ "Write (16)", unknown, "Read attributes", "Write attributes", + "Write and verify (16)", "Verify (16)", +/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)", + "Lock/unlock cache (16)", "Write same (16)", unknown, +/* 95-99 */ unknown, unknown, unknown, unknown, unknown, +/* 9a-9f */ unknown, unknown, unknown, unknown, "Service action in", + "Service action out", +}; + +/* The following are 12 byte commands in group 5 */ +static const char *group_5_commands[] = { +/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance (in)", + "Maintenance (out)", "Move medium/play audio(12)", +/* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)", + "Play track relative(12)", +/* aa-ae */ "Write(12)", unknown, "Erase(12), Get Performance", + "Read DVD structure", "Write and verify(12)", +/* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", +/* b2-b4 */ "Search data low(12)", "Set limits(12)", + "Read element status attached", +/* b5-b6 */ "Request volume element address", "Send volume tag, set streaming", +/* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf", +/* ba-bc */ "Redundancy group (in), Scan", + "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd", +/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd", + "Volume set (out), Send DVD structure", +}; + + +#define group(opcode) (((opcode) >> 5) & 7) + +#define RESERVED_GROUP 0 +#define VENDOR_GROUP 1 + +static const char **commands[] = { + group_0_commands, group_1_commands, group_2_commands, + (const char **) RESERVED_GROUP, group_4_commands, + group_5_commands, (const char **) VENDOR_GROUP, + (const char **) VENDOR_GROUP +}; + +static const char reserved[] = "RESERVED"; +static const char vendor[] = "VENDOR SPECIFIC"; + +static void print_opcode(int opcode) { + const char **table = commands[ group(opcode) ]; + + switch ((unsigned long) table) { + case RESERVED_GROUP: + fprintf(OUTP, "%s(0x%02x)", reserved, opcode); + break; + case VENDOR_GROUP: + fprintf(OUTP, "%s(0x%02x)", vendor, opcode); + break; + default: + fprintf(OUTP, "%s",table[opcode & 0x1f]); + break; + } +} + +void sg_print_command (const unsigned char * command) { + int k, s; + print_opcode(command[0]); + fprintf(OUTP, " ["); + for (k = 0, s = COMMAND_SIZE(command[0]); k < s; ++k) + fprintf(OUTP, "%02x ", command[k]); + fprintf(OUTP, "]\n"); +} + +void sg_print_status(int masked_status) +{ + int scsi_status = (masked_status << 1) & 0x7e; + + sg_print_scsi_status(scsi_status); +} + +void sg_print_scsi_status(int scsi_status) +{ + const char * ccp; + + scsi_status &= 0x7e; /* sanitize as much as possible */ + switch (scsi_status) { + case 0: ccp = "Good"; break; + case 0x2: ccp = "Check Condition"; break; + case 0x4: ccp = "Condition Met"; break; + case 0x8: ccp = "Busy"; break; + case 0x10: ccp = "Intermediate"; break; + case 0x14: ccp = "Intermediate-Condition Met"; break; + case 0x18: ccp = "Reservation Conflict"; break; + case 0x22: ccp = "Command Terminated (obsolete)"; break; + case 0x28: ccp = "Task set Full"; break; + case 0x30: ccp = "ACA Active"; break; + case 0x40: ccp = "Task Aborted"; break; + default: ccp = "Unknown status"; break; + } + fprintf(OUTP, "%s ", ccp); +} + +/* In brackets is the related SCSI document (see www.t10.org) with the */ +/* peripheral device type after the colon */ +/* No programmatic use is made of these flags currently */ +#define D 0x0001 /* DIRECT ACCESS DEVICE (disk) [SBC-2: 0] */ +#define T 0x0002 /* SEQUENTIAL ACCESS DEVICE (tape) [SSC: 1] */ +#define L 0x0004 /* PRINTER DEVICE [SSC: 2] */ +#define P 0x0008 /* PROCESSOR DEVICE [SPC-2: 3] */ +#define W 0x0010 /* WRITE ONCE READ MULTIPLE DEVICE [SBC-2: 4] */ +#define R 0x0020 /* CD/DVD DEVICE [MMC-2: 5] */ +#define S 0x0040 /* SCANNER DEVICE [SCSI-2 (obsolete): 6] */ +#define O 0x0080 /* OPTICAL MEMORY DEVICE [SBC-2: 7] */ +#define M 0x0100 /* MEDIA CHANGER DEVICE [SMC-2: 8] */ +#define C 0x0200 /* COMMUNICATION DEVICE [SCSI-2 (obsolete): 9] */ +#define A 0x0400 /* ARRAY STORAGE [SCC-2: 12] */ +#define E 0x0800 /* ENCLOSURE SERVICES DEVICE [SES: 13] */ +#define B 0x1000 /* SIMPLIFIED DIRECT ACCESS DEVICE [RBC: 14] */ +#define K 0x2000 /* OPTICAL CARD READER/WRITER DEVICE [OCRW: 15] */ + +#define SC_ALL_DEVS ( D|T|L|P|W|R|S|O|M|C|A|E|B|K ) + +/* oft used strings are encoded using ASCII codes 0x1 to 0x1f . */ +/* This is to save space. This encoding should be UTF-8 and */ +/* UTF-16 friendly. */ +#define SC_AUDIO_PLAY_OPERATION "\x1" +#define SC_LOGICAL_UNIT "\x2" +#define SC_NOT_READY "\x3" +#define SC_OPERATION "\x4" +#define SC_IN_PROGRESS "\x5" +#define SC_HARDWARE_IF "\x6" +#define SC_CONTROLLER_IF "\x7" +#define SC_DATA_CHANNEL_IF "\x8" +#define SC_SERVO_IF "\x9" +#define SC_SPINDLE_IF "\xa" +#define SC_FIRMWARE_IF "\xb" +#define SC_RECOVERED_DATA "\xc" +#define SC_ERROR_RATE_TOO_HIGH "\xd" +#define SC_TIMES_TOO_HIGH "\xe" + + +struct error_info{ + unsigned char code1, code2; + unsigned short int devices; + const char * text; +}; + +struct error_info2{ + unsigned char code1, code2_min, code2_max; + unsigned short int devices; + const char * text; +}; + +static struct error_info2 additional2[] = +{ + {0x40,0x00,0x7f,D,"Ram failure (%x)"}, + {0x40,0x80,0xff,D|T|L|P|W|R|S|O|M|C,"Diagnostic failure on component (%x)"}, + {0x41,0x00,0xff,D,"Data path failure (%x)"}, + {0x42,0x00,0xff,D,"Power-on or self-test failure (%x)"}, + {0, 0, 0, 0, NULL} +}; + +static struct error_info additional[] = +{ + {0x00,0x00,SC_ALL_DEVS,"No additional sense information"}, + {0x00,0x01,T,"Filemark detected"}, + {0x00,0x02,T|S,"End-of-partition/medium detected"}, + {0x00,0x03,T,"Setmark detected"}, + {0x00,0x04,T|S,"Beginning-of-partition/medium detected"}, + {0x00,0x05,T|L|S,"End-of-data detected"}, + {0x00,0x06,SC_ALL_DEVS,"I/O process terminated"}, + {0x00,0x11,R,SC_AUDIO_PLAY_OPERATION SC_IN_PROGRESS}, + {0x00,0x12,R,SC_AUDIO_PLAY_OPERATION "paused"}, + {0x00,0x13,R,SC_AUDIO_PLAY_OPERATION "successfully completed"}, + {0x00,0x14,R,SC_AUDIO_PLAY_OPERATION "stopped due to error"}, + {0x00,0x15,R,"No current audio status to return"}, + {0x00,0x16,SC_ALL_DEVS,SC_OPERATION SC_IN_PROGRESS}, + {0x00,0x17,D|T|L|W|R|S|O|M|A|E|B|K,"Cleaning requested"}, + {0x00,0x18,T,"Erase" SC_OPERATION SC_IN_PROGRESS}, + {0x00,0x19,T,"Locate" SC_OPERATION SC_IN_PROGRESS}, + {0x00,0x1a,T,"Rewind" SC_OPERATION SC_IN_PROGRESS}, + {0x00,0x1b,T,"Set capacity" SC_OPERATION SC_IN_PROGRESS}, + {0x00,0x1c,T,"Verify" SC_OPERATION SC_IN_PROGRESS}, + {0x01,0x00,D|W|O|B|K,"No index/sector signal"}, + {0x02,0x00,D|W|R|O|M|B|K,"No seek complete"}, + {0x03,0x00,D|T|L|W|S|O|B|K,"Peripheral device write fault"}, + {0x03,0x01,T,"No write current"}, + {0x03,0x02,T,"Excessive write errors"}, + {0x04,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY "cause not reportable"}, + {0x04,0x01,SC_ALL_DEVS,SC_LOGICAL_UNIT "is" SC_IN_PROGRESS + "of becoming ready"}, + {0x04,0x02,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY + "initializing cmd. required"}, + {0x04,0x03,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY + "manual intervention required"}, + {0x04,0x04,D|T|L|R|O|B,SC_LOGICAL_UNIT SC_NOT_READY "format" SC_IN_PROGRESS}, + {0x04,0x05,D|T|W|O|M|C|A|B|K,SC_LOGICAL_UNIT SC_NOT_READY + "rebuild" SC_IN_PROGRESS}, + {0x04,0x06,D|T|W|O|M|C|A|B|K,SC_LOGICAL_UNIT SC_NOT_READY + "recalculation" SC_IN_PROGRESS}, + {0x04,0x07,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY + SC_OPERATION SC_IN_PROGRESS}, + {0x04,0x08,R,SC_LOGICAL_UNIT SC_NOT_READY "long write" SC_IN_PROGRESS}, + {0x04,0x09,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY "self-test" + SC_IN_PROGRESS}, + {0x04,0x0a,SC_ALL_DEVS,SC_LOGICAL_UNIT + "not accessible, asymmetric access state transition"}, + {0x04,0x0b,SC_ALL_DEVS,SC_LOGICAL_UNIT + "not accessible, target port in standby state"}, + {0x04,0x0c,SC_ALL_DEVS,SC_LOGICAL_UNIT + "not accessible, target port in unavailable state"}, + {0x04,0x10,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY + "auxiliary memory not accessible"}, + {0x05,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT + "does not respond to selection"}, + {0x06,0x00,D|W|R|O|M|B|K,"No reference position found"}, + {0x07,0x00,D|T|L|W|R|S|O|M|B|K,"Multiple peripheral devices selected"}, + {0x08,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT "communication failure"}, + {0x08,0x01,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT + "communication time-out"}, + {0x08,0x02,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT + "communication parity error"}, + {0x08,0x03,D|T|R|O|M|B|K,SC_LOGICAL_UNIT + "communication CRC error (Ultra-DMA/32)"}, + {0x08,0x04,D|T|L|P|W|R|S|O|C|K,"Unreachable copy target"}, + {0x09,0x00,D|T|W|R|O|B,"Track following error"}, + {0x09,0x01,W|R|O|K,"Tracking servo failure"}, + {0x09,0x02,W|R|O|K,"Focus servo failure"}, + {0x09,0x03,W|R|O,"Spindle servo failure"}, + {0x09,0x04,D|T|W|R|O|B,"Head select fault"}, + {0x0A,0x00,SC_ALL_DEVS,"Error log overflow"}, + {0x0B,0x00,SC_ALL_DEVS,"Warning"}, + {0x0B,0x01,SC_ALL_DEVS,"Warning - specified temperature exceeded"}, + {0x0B,0x02,SC_ALL_DEVS,"Warning - enclosure degraded"}, + {0x0C,0x00,T|R|S,"Write error"}, + {0x0C,0x01,K,"Write error - recovered with auto reallocation"}, + {0x0C,0x02,D|W|O|B|K,"Write error - auto reallocation failed"}, + {0x0C,0x03,D|W|O|B|K,"Write error - recommend reassignment"}, + {0x0C,0x04,D|T|W|O|B,"Compression check miscompare error"}, + {0x0C,0x05,D|T|W|O|B,"Data expansion occurred during compression"}, + {0x0C,0x06,D|T|W|O|B,"Block not compressible"}, + {0x0C,0x07,R,"Write error - recovery needed"}, + {0x0C,0x08,R,"Write error - recovery failed"}, + {0x0C,0x09,R,"Write error - loss of streaming"}, + {0x0C,0x0A,R,"Write error - padding blocks added"}, + {0x0C,0x0B,D|T|W|R|O|M|B,"Auxiliary memory write error"}, + {0x0C,0x0C,SC_ALL_DEVS,"Write error - unexpected unsolicited data"}, + {0x0C,0x0D,SC_ALL_DEVS,"Write error - not enough unsolicited data"}, + {0x0D,0x00,D|T|L|P|W|R|S|O|C|A|K, + "Error detected by third party temporary initiator"}, + {0x0D,0x01,D|T|L|P|W|R|S|O|C|A|K, "Third party device failure"}, + {0x0D,0x02,D|T|L|P|W|R|S|O|C|A|K, "Copy target device not reachable"}, + {0x0D,0x03,D|T|L|P|W|R|S|O|C|A|K, "Incorrect copy target device"}, + {0x0D,0x04,D|T|L|P|W|R|S|O|C|A|K, "Copy target device underrun"}, + {0x0D,0x05,D|T|L|P|W|R|S|O|C|A|K, "Copy target device overrun"}, + {0x10,0x00,D|W|O|B|K,"Id CRC or ECC error"}, + {0x11,0x00,D|T|W|R|S|O|B|K,"Unrecovered read error"}, + {0x11,0x01,D|T|W|R|S|O|B|K,"Read retries exhausted"}, + {0x11,0x02,D|T|W|R|S|O|B|K,"Error too long to correct"}, + {0x11,0x03,D|T|W|S|O|B|K,"Multiple read errors"}, + {0x11,0x04,D|W|O|B|K,"Unrecovered read error - auto reallocate failed"}, + {0x11,0x05,W|R|O|B,"L-EC uncorrectable error"}, + {0x11,0x06,W|R|O|B,"CIRC unrecovered error"}, + {0x11,0x07,W|O|B,"Data re-synchronization error"}, + {0x11,0x08,T,"Incomplete block read"}, + {0x11,0x09,T,"No gap found"}, + {0x11,0x0A,D|T|O|B|K,"Miscorrected error"}, + {0x11,0x0B,D|W|O|B|K,"Unrecovered read error - recommend reassignment"}, + {0x11,0x0C,D|W|O|B|K,"Unrecovered read error - recommend rewrite the data"}, + {0x11,0x0D,D|T|W|R|O|B,"De-compression CRC error"}, + {0x11,0x0E,D|T|W|R|O|B,"Cannot decompress using declared algorithm"}, + {0x11,0x0F,R,"Error reading UPC/EAN number"}, + {0x11,0x10,R,"Error reading ISRC number"}, + {0x11,0x11,R,"Read error - loss of streaming"}, + {0x11,0x12,D|T|W|R|O|M|B,"Auxiliary memory read error"}, + {0x11,0x13,SC_ALL_DEVS,"Read error - failed retransmission request"}, + {0x12,0x00,D|W|O|B|K,"Address mark not found for id field"}, + {0x13,0x00,D|W|O|B|K,"Address mark not found for data field"}, + {0x14,0x00,D|T|L|W|R|S|O|B|K,"Recorded entity not found"}, + {0x14,0x01,D|T|W|R|O|B|K,"Record not found"}, + {0x14,0x02,T,"Filemark or setmark not found"}, + {0x14,0x03,T,"End-of-data not found"}, + {0x14,0x04,T,"Block sequence error"}, + {0x14,0x05,D|T|W|O|B|K,"Record not found - recommend reassignment"}, + {0x14,0x06,D|T|W|O|B|K,"Record not found - data auto-reallocated"}, + {0x14,0x07,T,"Locate" SC_OPERATION " failure"}, + {0x15,0x00,D|T|L|W|R|S|O|M|B|K,"Random positioning error"}, + {0x15,0x01,D|T|L|W|R|S|O|M|B|K,"Mechanical positioning error"}, + {0x15,0x02,D|T|W|R|O|B|K,"Positioning error detected by read of medium"}, + {0x16,0x00,D|W|O|B|K,"Data synchronization mark error"}, + {0x16,0x01,D|W|O|B|K,"Data sync error - data rewritten"}, + {0x16,0x02,D|W|O|B|K,"Data sync error - recommend rewrite"}, + {0x16,0x03,D|W|O|B|K,"Data sync error - data auto-reallocated"}, + {0x16,0x04,D|W|O|B|K,"Data sync error - recommend reassignment"}, + {0x17,0x00,D|T|W|R|S|O|B|K,SC_RECOVERED_DATA + "with no error correction applied"}, + {0x17,0x01,D|T|W|R|S|O|B|K,SC_RECOVERED_DATA "with retries"}, + {0x17,0x02,D|T|W|R|O|B|K,SC_RECOVERED_DATA "with positive head offset"}, + {0x17,0x03,D|T|W|R|O|B|K,SC_RECOVERED_DATA "with negative head offset"}, + {0x17,0x04,W|R|O|B,SC_RECOVERED_DATA "with retries and/or circ applied"}, + {0x17,0x05,D|W|R|O|B|K,SC_RECOVERED_DATA "using previous sector id"}, + {0x17,0x06,D|W|O|B|K,SC_RECOVERED_DATA "without ecc - data auto-reallocated"}, + {0x17,0x07,D|W|R|O|B|K,SC_RECOVERED_DATA + "without ecc - recommend reassignment"}, + {0x17,0x08,D|W|R|O|B|K,SC_RECOVERED_DATA "without ecc - recommend rewrite"}, + {0x17,0x09,D|W|R|O|B|K,SC_RECOVERED_DATA "without ecc - data rewritten"}, + {0x18,0x00,D|T|W|R|O|B|K,SC_RECOVERED_DATA "with error correction applied"}, + {0x18,0x01,D|W|R|O|B|K,SC_RECOVERED_DATA + "with error corr. & retries applied"}, + {0x18,0x02,D|W|R|O|B|K,SC_RECOVERED_DATA "- data auto-reallocated"}, + {0x18,0x03,R,SC_RECOVERED_DATA "with CIRC"}, + {0x18,0x04,R,SC_RECOVERED_DATA "with L-EC"}, + {0x18,0x05,D|W|R|O|B|K,SC_RECOVERED_DATA "- recommend reassignment"}, + {0x18,0x06,D|W|R|O|B|K,SC_RECOVERED_DATA "- recommend rewrite"}, + {0x18,0x07,D|W|O|B|K,SC_RECOVERED_DATA "with ecc - data rewritten"}, + {0x18,0x08,R,SC_RECOVERED_DATA "with linking"}, + {0x19,0x00,D|O|K,"Defect list error"}, + {0x19,0x01,D|O|K,"Defect list not available"}, + {0x19,0x02,D|O|K,"Defect list error in primary list"}, + {0x19,0x03,D|O|K,"Defect list error in grown list"}, + {0x1A,0x00,SC_ALL_DEVS,"Parameter list length error"}, + {0x1B,0x00,SC_ALL_DEVS,"Synchronous data transfer error"}, + {0x1C,0x00,D|O|B|K,"Defect list not found"}, + {0x1C,0x01,D|O|B|K,"Primary defect list not found"}, + {0x1C,0x02,D|O|B|K,"Grown defect list not found"}, + {0x1D,0x00,D|T|W|R|O|B|K,"Miscompare during verify" SC_OPERATION}, + {0x1E,0x00,D|W|O|B|K,"Recovered id with ecc correction"}, + {0x1F,0x00,D|O|K,"Partial defect list transfer"}, + {0x20,0x00,SC_ALL_DEVS,"Invalid command" SC_OPERATION " code"}, + {0x20,0x01,D|T|P|W|R|O|M|A|E|B|K, + "Access denied - initiator pending-enrolled"}, + {0x20,0x02,D|T|P|W|R|O|M|A|E|B|K,"Access denied - no access rights"}, + {0x20,0x03,D|T|P|W|R|O|M|A|E|B|K,"Access denied - no mgmt id key"}, + {0x20,0x04,T,"Illegal command while in write capable state"}, + {0x20,0x05,T,"Obsolete"}, + {0x20,0x06,T,"Illegal command while in explicit address mode"}, + {0x20,0x07,T,"Illegal command while in implicit address mode"}, + {0x20,0x08,D|T|P|W|R|O|M|A|E|B|K,"Access denied - enrollment conflict"}, + {0x20,0x09,D|T|P|W|R|O|M|A|E|B|K,"Access denied - invalid LU identifier"}, + {0x20,0x0A,D|T|P|W|R|O|M|A|E|B|K,"Access denied - invalid proxy token"}, + {0x20,0x0B,D|T|P|W|R|O|M|A|E|B|K,"Access denied - ACL LUN conflict"}, + {0x21,0x00,D|T|W|R|O|M|B|K,"Logical block address out of range"}, + {0x21,0x01,D|T|W|R|O|M|B|K,"Invalid element address"}, + {0x21,0x02,R,"Invalid address for write"}, + {0x22,0x00,D,"Illegal function (use 20 00,24 00,or 26 00)"}, + {0x24,0x00,SC_ALL_DEVS,"Invalid field in cdb"}, + {0x24,0x01,SC_ALL_DEVS,"CDB decryption error"}, + {0x25,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT "not supported"}, + {0x26,0x00,SC_ALL_DEVS,"Invalid field in parameter list"}, + {0x26,0x01,SC_ALL_DEVS,"Parameter not supported"}, + {0x26,0x02,SC_ALL_DEVS,"Parameter value invalid"}, + {0x26,0x03,D|T|L|P|W|R|S|O|M|C|A|E|K,"Threshold parameters not supported"}, + {0x26,0x04,SC_ALL_DEVS,"Invalid release of persistent reservation"}, + {0x26,0x05,D|T|L|P|W|R|S|O|M|C|A|B|K,"Data decryption error"}, + {0x26,0x06,D|T|L|P|W|R|S|O|C|K,"Too many target descriptors"}, + {0x26,0x07,D|T|L|P|W|R|S|O|C|K,"Unsupported target descriptor type code"}, + {0x26,0x08,D|T|L|P|W|R|S|O|C|K,"Too many segment descriptors"}, + {0x26,0x09,D|T|L|P|W|R|S|O|C|K,"Unsupported segment descriptor type code"}, + {0x26,0x0A,D|T|L|P|W|R|S|O|C|K,"Unexpected inexact segment"}, + {0x26,0x0B,D|T|L|P|W|R|S|O|C|K,"Inline data length exceeded"}, + {0x26,0x0C,D|T|L|P|W|R|S|O|C|K, + "Invalid" SC_OPERATION " for copy source or destination"}, + {0x26,0x0D,D|T|L|P|W|R|S|O|C|K,"Copy segment granularity violation"}, + {0x27,0x00,D|T|W|R|O|B|K,"Write protected"}, + {0x27,0x01,D|T|W|R|O|B|K,"Hardware write protected"}, + {0x27,0x02,D|T|W|R|O|B|K,SC_LOGICAL_UNIT "software write protected"}, + {0x27,0x03,T|R,"Associated write protect"}, + {0x27,0x04,T|R,"Persistent write protect"}, + {0x27,0x05,T|R,"Permanent write protect"}, + {0x27,0x06,R,"Conditional write protect"}, + {0x28,0x00,SC_ALL_DEVS,"Not ready to ready change, medium may have changed"}, + {0x28,0x01,D|T|W|R|O|M|B,"Import or export element accessed"}, + {0x29,0x00,SC_ALL_DEVS,"Power on, reset, or bus device reset occurred"}, + {0x29,0x01,SC_ALL_DEVS,"Power on occurred"}, + {0x29,0x02,SC_ALL_DEVS,"Scsi bus reset occurred"}, + {0x29,0x03,SC_ALL_DEVS,"Bus device reset function occurred"}, + {0x29,0x04,SC_ALL_DEVS,"Device internal reset"}, + {0x29,0x05,SC_ALL_DEVS,"Transceiver mode changed to single-ended"}, + {0x29,0x06,SC_ALL_DEVS,"Transceiver mode changed to lvd"}, + {0x29,0x07,SC_ALL_DEVS,"I_T nexus loss occurred"}, + {0x2A,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Parameters changed"}, + {0x2A,0x01,D|T|L|W|R|S|O|M|C|A|E|B|K,"Mode parameters changed"}, + {0x2A,0x02,D|T|L|W|R|S|O|M|C|A|E|K,"Log parameters changed"}, + {0x2A,0x03,D|T|L|P|W|R|S|O|M|C|A|E|K,"Reservations preempted"}, + {0x2A,0x04,D|T|L|P|W|R|S|O|M|C|A|E,"Reservations released"}, + {0x2A,0x05,D|T|L|P|W|R|S|O|M|C|A|E,"Registrations preempted"}, + {0x2A,0x06,SC_ALL_DEVS,"Asymmetric access state changed"}, + {0x2A,0x07,SC_ALL_DEVS,"Implicit asymmetric access state transition failed"}, + {0x2B,0x00,D|T|L|P|W|R|S|O|C|K, + "Copy cannot execute since host cannot disconnect"}, + {0x2C,0x00,SC_ALL_DEVS,"Command sequence error"}, + {0x2C,0x01,S,"Too many windows specified"}, + {0x2C,0x02,S,"Invalid combination of windows specified"}, + {0x2C,0x03,R,"Current program area is not empty"}, + {0x2C,0x04,R,"Current program area is empty"}, + {0x2C,0x05,B,"Illegal power condition request"}, + {0x2C,0x06,R,"Persistent prevent conflict"}, + {0x2C,0x07,SC_ALL_DEVS,"Previous busy status"}, + {0x2C,0x08,SC_ALL_DEVS,"Previous task set full status"}, + {0x2C,0x09,D|T|L|P|W|R|S|O|M|E|B|K,"Previous reservation conflict status"}, + {0x2D,0x00,T,"Overwrite error on update in place"}, + {0x2F,0x00,SC_ALL_DEVS,"Commands cleared by another initiator"}, + {0x30,0x00,D|T|W|R|O|M|B|K,"Incompatible medium installed"}, + {0x30,0x01,D|T|W|R|O|B|K,"Cannot read medium - unknown format"}, + {0x30,0x02,D|T|W|R|O|B|K,"Cannot read medium - incompatible format"}, + {0x30,0x03,D|T|R|K,"Cleaning cartridge installed"}, + {0x30,0x04,D|T|W|R|O|B|K,"Cannot write medium - unknown format"}, + {0x30,0x05,D|T|W|R|O|B|K,"Cannot write medium - incompatible format"}, + {0x30,0x06,D|T|W|R|O|B,"Cannot format medium - incompatible medium"}, + {0x30,0x07,D|T|L|W|R|S|O|M|A|E|B|K,"Cleaning failure"}, + {0x30,0x08,R,"Cannot write - application code mismatch"}, + {0x30,0x09,R,"Current session not fixated for append"}, + {0x30,0x10,R,"Medium not formatted"}, /* should ascq be 0xa ?? */ + {0x31,0x00,D|T|W|R|O|B|K,"Medium format corrupted"}, + {0x31,0x01,D|L|R|O|B,"Format command failed"}, + {0x31,0x02,R,"Zoned formatting failed due to spare linking"}, + {0x32,0x00,D|W|O|B|K,"No defect spare location available"}, + {0x32,0x01,D|W|O|B|K,"Defect list update failure"}, + {0x33,0x00,T,"Tape length error"}, + {0x34,0x00,SC_ALL_DEVS,"Enclosure failure"}, + {0x35,0x00,SC_ALL_DEVS,"Enclosure services failure"}, + {0x35,0x01,SC_ALL_DEVS,"Unsupported enclosure function"}, + {0x35,0x02,SC_ALL_DEVS,"Enclosure services unavailable"}, + {0x35,0x03,SC_ALL_DEVS,"Enclosure services transfer failure"}, + {0x35,0x04,SC_ALL_DEVS,"Enclosure services transfer refused"}, + {0x36,0x00,L,"Ribbon,ink,or toner failure"}, + {0x37,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Rounded parameter"}, + {0x38,0x00,B,"Event status notification"}, + {0x38,0x02,B,"Esn - power management class event"}, + {0x38,0x04,B,"Esn - media class event"}, + {0x38,0x06,B,"Esn - device busy class event"}, + {0x39,0x00,D|T|L|W|R|S|O|M|C|A|E|K,"Saving parameters not supported"}, + {0x3A,0x00,D|T|L|W|R|S|O|M|B|K,"Medium not present"}, + {0x3A,0x01,D|T|W|R|O|M|B|K,"Medium not present - tray closed"}, + {0x3A,0x02,D|T|W|R|O|M|B|K,"Medium not present - tray open"}, + {0x3A,0x03,D|T|W|R|O|M|B,"Medium not present - loadable"}, + {0x3A,0x04,D|T|W|R|O|M|B, + "Medium not present - medium auxiliary memory accessible"}, + {0x3B,0x00,T|L,"Sequential positioning error"}, + {0x3B,0x01,T,"Tape position error at beginning-of-medium"}, + {0x3B,0x02,T,"Tape position error at end-of-medium"}, + {0x3B,0x03,L,"Tape or electronic vertical forms unit " SC_NOT_READY}, + {0x3B,0x04,L,"Slew failure"}, + {0x3B,0x05,L,"Paper jam"}, + {0x3B,0x06,L,"Failed to sense top-of-form"}, + {0x3B,0x07,L,"Failed to sense bottom-of-form"}, + {0x3B,0x08,T,"Reposition error"}, + {0x3B,0x09,S,"Read past end of medium"}, + {0x3B,0x0A,S,"Read past beginning of medium"}, + {0x3B,0x0B,S,"Position past end of medium"}, + {0x3B,0x0C,T|S,"Position past beginning of medium"}, + {0x3B,0x0D,D|T|W|R|O|M|B|K,"Medium destination element full"}, + {0x3B,0x0E,D|T|W|R|O|M|B|K,"Medium source element empty"}, + {0x3B,0x0F,R,"End of medium reached"}, + {0x3B,0x11,D|T|W|R|O|M|B|K,"Medium magazine not accessible"}, + {0x3B,0x12,D|T|W|R|O|M|B|K,"Medium magazine removed"}, + {0x3B,0x13,D|T|W|R|O|M|B|K,"Medium magazine inserted"}, + {0x3B,0x14,D|T|W|R|O|M|B|K,"Medium magazine locked"}, + {0x3B,0x15,D|T|W|R|O|M|B|K,"Medium magazine unlocked"}, + {0x3B,0x16,R,"Mechanical positioning or changer error"}, + {0x3D,0x00,D|T|L|P|W|R|S|O|M|C|A|E|K,"Invalid bits in identify message"}, + {0x3E,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT "has not self-configured yet"}, + {0x3E,0x01,SC_ALL_DEVS,SC_LOGICAL_UNIT "failure"}, + {0x3E,0x02,SC_ALL_DEVS,"Timeout on logical unit"}, + {0x3E,0x03,SC_ALL_DEVS,SC_LOGICAL_UNIT "failed self-test"}, + {0x3E,0x04,SC_ALL_DEVS,SC_LOGICAL_UNIT "unable to update self-test log"}, + {0x3F,0x00,SC_ALL_DEVS,"Target operating conditions have changed"}, + {0x3F,0x01,SC_ALL_DEVS,"Microcode has been changed"}, + {0x3F,0x02,D|T|L|P|W|R|S|O|M|C|B|K,"Changed operating definition"}, + {0x3F,0x03,SC_ALL_DEVS,"Inquiry data has changed"}, + {0x3F,0x04,D|T|W|R|O|M|C|A|E|B|K,"Component device attached"}, + {0x3F,0x05,D|T|W|R|O|M|C|A|E|B|K,"Device identifier changed"}, + {0x3F,0x06,D|T|W|R|O|M|C|A|E|B,"Redundancy group created or modified"}, + {0x3F,0x07,D|T|W|R|O|M|C|A|E|B,"Redundancy group deleted"}, + {0x3F,0x08,D|T|W|R|O|M|C|A|E|B,"Spare created or modified"}, + {0x3F,0x09,D|T|W|R|O|M|C|A|E|B,"Spare deleted"}, + {0x3F,0x0A,D|T|W|R|O|M|C|A|E|B|K,"Volume set created or modified"}, + {0x3F,0x0B,D|T|W|R|O|M|C|A|E|B|K,"Volume set deleted"}, + {0x3F,0x0C,D|T|W|R|O|M|C|A|E|B|K,"Volume set deassigned"}, + {0x3F,0x0D,D|T|W|R|O|M|C|A|E|B|K,"Volume set reassigned"}, + {0x3F,0x0E,D|T|L|P|W|R|S|O|M|C|A|E,"Reported luns data has changed"}, + {0x3F,0x10,D|T|W|R|O|M|B,"Medium loadable"}, + {0x3F,0x11,D|T|W|R|O|M|B,"Medium auxiliary memory accessible"}, + {0x40,0x00,D,"Ram failure (should use 40 nn)"}, + /* + * FIXME(eric) - need a way to represent wildcards here. + */ + {0x40,0x00,SC_ALL_DEVS,"Diagnostic failure on component nn (80h-ffh)"}, + {0x41,0x00,D,"Data path failure (should use 40 nn)"}, + {0x42,0x00,D,"Power-on or self-test failure (should use 40 nn)"}, + {0x43,0x00,SC_ALL_DEVS,"Message error"}, + {0x44,0x00,SC_ALL_DEVS,"Internal target failure"}, + {0x45,0x00,SC_ALL_DEVS,"Select or reselect failure"}, + {0x46,0x00,D|T|L|P|W|R|S|O|M|C|B|K,"Unsuccessful soft reset"}, + {0x47,0x00,SC_ALL_DEVS,"Scsi parity error"}, + {0x47,0x01,SC_ALL_DEVS,"Data phase CRC error detected"}, + {0x47,0x02,SC_ALL_DEVS,"Scsi parity error detected during st data phase"}, + {0x47,0x03,SC_ALL_DEVS,"Information unit CRC error detected"}, + {0x47,0x04,SC_ALL_DEVS,"Asynchronous information protection error detected"}, + {0x47,0x05,SC_ALL_DEVS,"Protocol service CRC error"}, + {0x48,0x00,SC_ALL_DEVS,"Initiator detected error message received"}, + {0x49,0x00,SC_ALL_DEVS,"Invalid message error"}, + {0x4A,0x00,SC_ALL_DEVS,"Command phase error"}, + {0x4B,0x00,SC_ALL_DEVS,"Data phase error"}, + {0x4C,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT "failed self-configuration"}, + /* + * FIXME(eric) - need a way to represent wildcards here. + */ + {0x4D,0x00,SC_ALL_DEVS,"Tagged overlapped commands (nn = queue tag)"}, + {0x4E,0x00,SC_ALL_DEVS,"Overlapped commands attempted"}, + {0x50,0x00,T,"Write append error"}, + {0x50,0x01,T,"Write append position error"}, + {0x50,0x02,T,"Position error related to timing"}, + {0x51,0x00,T|R|O,"Erase failure"}, + {0x52,0x00,T,"Cartridge fault"}, + {0x53,0x00,D|T|L|W|R|S|O|M|B|K,"Media load or eject failed"}, + {0x53,0x01,T,"Unload tape failure"}, + {0x53,0x02,D|T|W|R|O|M|B|K,"Medium removal prevented"}, + {0x54,0x00,P,"Scsi to host system interface failure"}, + {0x55,0x00,P,"System resource failure"}, + {0x55,0x01,D|O|B|K,"System buffer full"}, + {0x55,0x02,D|T|L|P|W|R|S|O|M|A|E|K,"Insufficient reservation resources"}, + {0x55,0x03,D|T|L|P|W|R|S|O|M|C|A|E,"Insufficient resources"}, + {0x55,0x04,D|T|L|P|W|R|S|O|M|A|E,"Insufficient registration resources"}, + {0x55,0x05,D|T|P|W|R|O|M|A|E|B|K,"Insufficient access control resources"}, + {0x55,0x06,D|T|W|R|O|M|B,"Auxiliary memory out of space"}, + {0x57,0x00,R,"Unable to recover table-of-contents"}, + {0x58,0x00,O,"Generation does not exist"}, + {0x59,0x00,O,"Updated block read"}, + {0x5A,0x00,D|T|L|P|W|R|S|O|M|B|K,"Operator request or state change input"}, + {0x5A,0x01,D|T|W|R|O|M|B|K,"Operator medium removal request"}, + {0x5A,0x02,D|T|W|R|O|A|B|K,"Operator selected write protect"}, + {0x5A,0x03,D|T|W|R|O|A|B|K,"Operator selected write permit"}, + {0x5B,0x00,D|T|L|P|W|R|S|O|M|K,"Log exception"}, + {0x5B,0x01,D|T|L|P|W|R|S|O|M|K,"Threshold condition met"}, + {0x5B,0x02,D|T|L|P|W|R|S|O|M|K,"Log counter at maximum"}, + {0x5B,0x03,D|T|L|P|W|R|S|O|M|K,"Log list codes exhausted"}, + {0x5C,0x00,D|O,"Rpl status change"}, + {0x5C,0x01,D|O,"Spindles synchronized"}, + {0x5C,0x02,D|O,"Spindles not synchronized"}, + {0x5D,0x00,SC_ALL_DEVS,"Failure prediction threshold exceeded"}, + {0x5D,0x01,R|B,"Media failure prediction threshold exceeded"}, + {0x5D,0x02,R,SC_LOGICAL_UNIT "failure prediction threshold exceeded"}, + {0x5D,0x03,R,"spare area exhaustion prediction threshold exceeded"}, + /* large series of "impending failure" messages */ + {0x5D,0x10,D|B,SC_HARDWARE_IF "general hard drive failure"}, + {0x5D,0x11,D|B,SC_HARDWARE_IF "drive" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x12,D|B,SC_HARDWARE_IF "data" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x13,D|B,SC_HARDWARE_IF "seek" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x14,D|B,SC_HARDWARE_IF "too many block reassigns"}, + {0x5D,0x15,D|B,SC_HARDWARE_IF "access" SC_TIMES_TOO_HIGH }, + {0x5D,0x16,D|B,SC_HARDWARE_IF "start unit" SC_TIMES_TOO_HIGH }, + {0x5D,0x17,D|B,SC_HARDWARE_IF "channel parametrics"}, + {0x5D,0x18,D|B,SC_HARDWARE_IF "controller detected"}, + {0x5D,0x19,D|B,SC_HARDWARE_IF "throughput performance"}, + {0x5D,0x1A,D|B,SC_HARDWARE_IF "seek time performance"}, + {0x5D,0x1B,D|B,SC_HARDWARE_IF "spin-up retry count"}, + {0x5D,0x1C,D|B,SC_HARDWARE_IF "drive calibration retry count"}, + {0x5D,0x20,D|B,SC_CONTROLLER_IF "general hard drive failure"}, + {0x5D,0x21,D|B,SC_CONTROLLER_IF "drive" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x22,D|B,SC_CONTROLLER_IF "data" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x23,D|B,SC_CONTROLLER_IF "seek" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x24,D|B,SC_CONTROLLER_IF "too many block reassigns"}, + {0x5D,0x25,D|B,SC_CONTROLLER_IF "access" SC_TIMES_TOO_HIGH }, + {0x5D,0x26,D|B,SC_CONTROLLER_IF "start unit" SC_TIMES_TOO_HIGH }, + {0x5D,0x27,D|B,SC_CONTROLLER_IF "channel parametrics"}, + {0x5D,0x28,D|B,SC_CONTROLLER_IF "controller detected"}, + {0x5D,0x29,D|B,SC_CONTROLLER_IF "throughput performance"}, + {0x5D,0x2A,D|B,SC_CONTROLLER_IF "seek time performance"}, + {0x5D,0x2B,D|B,SC_CONTROLLER_IF "spin-up retry count"}, + {0x5D,0x2C,D|B,SC_CONTROLLER_IF "drive calibration retry count"}, + {0x5D,0x30,D|B,SC_DATA_CHANNEL_IF "general hard drive failure"}, + {0x5D,0x31,D|B,SC_DATA_CHANNEL_IF "drive" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x32,D|B,SC_DATA_CHANNEL_IF "data" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x33,D|B,SC_DATA_CHANNEL_IF "seek" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x34,D|B,SC_DATA_CHANNEL_IF "too many block reassigns"}, + {0x5D,0x35,D|B,SC_DATA_CHANNEL_IF "access" SC_TIMES_TOO_HIGH }, + {0x5D,0x36,D|B,SC_DATA_CHANNEL_IF "start unit" SC_TIMES_TOO_HIGH }, + {0x5D,0x37,D|B,SC_DATA_CHANNEL_IF "channel parametrics"}, + {0x5D,0x38,D|B,SC_DATA_CHANNEL_IF "controller detected"}, + {0x5D,0x39,D|B,SC_DATA_CHANNEL_IF "throughput performance"}, + {0x5D,0x3A,D|B,SC_DATA_CHANNEL_IF "seek time performance"}, + {0x5D,0x3B,D|B,SC_DATA_CHANNEL_IF "spin-up retry count"}, + {0x5D,0x3C,D|B,SC_DATA_CHANNEL_IF "drive calibration retry count"}, + {0x5D,0x40,D|B,SC_SERVO_IF "general hard drive failure"}, + {0x5D,0x41,D|B,SC_SERVO_IF "drive" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x42,D|B,SC_SERVO_IF "data" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x43,D|B,SC_SERVO_IF "seek" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x44,D|B,SC_SERVO_IF "too many block reassigns"}, + {0x5D,0x45,D|B,SC_SERVO_IF "access" SC_TIMES_TOO_HIGH }, + {0x5D,0x46,D|B,SC_SERVO_IF "start unit" SC_TIMES_TOO_HIGH }, + {0x5D,0x47,D|B,SC_SERVO_IF "channel parametrics"}, + {0x5D,0x48,D|B,SC_SERVO_IF "controller detected"}, + {0x5D,0x49,D|B,SC_SERVO_IF "throughput performance"}, + {0x5D,0x4A,D|B,SC_SERVO_IF "seek time performance"}, + {0x5D,0x4B,D|B,SC_SERVO_IF "spin-up retry count"}, + {0x5D,0x4C,D|B,SC_SERVO_IF "drive calibration retry count"}, + {0x5D,0x50,D|B,SC_SPINDLE_IF "general hard drive failure"}, + {0x5D,0x51,D|B,SC_SPINDLE_IF "drive" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x52,D|B,SC_SPINDLE_IF "data" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x53,D|B,SC_SPINDLE_IF "seek" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x54,D|B,SC_SPINDLE_IF "too many block reassigns"}, + {0x5D,0x55,D|B,SC_SPINDLE_IF "access" SC_TIMES_TOO_HIGH }, + {0x5D,0x56,D|B,SC_SPINDLE_IF "start unit" SC_TIMES_TOO_HIGH }, + {0x5D,0x57,D|B,SC_SPINDLE_IF "channel parametrics"}, + {0x5D,0x58,D|B,SC_SPINDLE_IF "controller detected"}, + {0x5D,0x59,D|B,SC_SPINDLE_IF "throughput performance"}, + {0x5D,0x5A,D|B,SC_SPINDLE_IF "seek time performance"}, + {0x5D,0x5B,D|B,SC_SPINDLE_IF "spin-up retry count"}, + {0x5D,0x5C,D|B,SC_SPINDLE_IF "drive calibration retry count"}, + {0x5D,0x60,D|B,SC_FIRMWARE_IF "general hard drive failure"}, + {0x5D,0x61,D|B,SC_FIRMWARE_IF "drive" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x62,D|B,SC_FIRMWARE_IF "data" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x63,D|B,SC_FIRMWARE_IF "seek" SC_ERROR_RATE_TOO_HIGH }, + {0x5D,0x64,D|B,SC_FIRMWARE_IF "too many block reassigns"}, + {0x5D,0x65,D|B,SC_FIRMWARE_IF "access" SC_TIMES_TOO_HIGH }, + {0x5D,0x66,D|B,SC_FIRMWARE_IF "start unit" SC_TIMES_TOO_HIGH }, + {0x5D,0x67,D|B,SC_FIRMWARE_IF "channel parametrics"}, + {0x5D,0x68,D|B,SC_FIRMWARE_IF "controller detected"}, + {0x5D,0x69,D|B,SC_FIRMWARE_IF "throughput performance"}, + {0x5D,0x6A,D|B,SC_FIRMWARE_IF "seek time performance"}, + {0x5D,0x6B,D|B,SC_FIRMWARE_IF "spin-up retry count"}, + {0x5D,0x6C,D|B,SC_FIRMWARE_IF "drive calibration retry count"}, + {0x5D,0xFF,SC_ALL_DEVS,"Failure prediction threshold exceeded (false)"}, + {0x5E,0x00,D|T|L|P|W|R|S|O|C|A|K,"Low power condition on"}, + {0x5E,0x01,D|T|L|P|W|R|S|O|C|A|K,"Idle condition activated by timer"}, + {0x5E,0x02,D|T|L|P|W|R|S|O|C|A|K,"Standby condition activated by timer"}, + {0x5E,0x03,D|T|L|P|W|R|S|O|C|A|K,"Idle condition activated by command"}, + {0x5E,0x04,D|T|L|P|W|R|S|O|C|A|K,"Standby condition activated by command"}, + {0x5E,0x41,B,"Power state change to active"}, + {0x5E,0x42,B,"Power state change to idle"}, + {0x5E,0x43,B,"Power state change to standby"}, + {0x5E,0x45,B,"Power state change to sleep"}, + {0x5E,0x47,B|K,"Power state change to device control"}, + {0x60,0x00,S,"Lamp failure"}, + {0x61,0x00,S,"Video acquisition error"}, + {0x61,0x01,S,"Unable to acquire video"}, + {0x61,0x02,S,"Out of focus"}, + {0x62,0x00,S,"Scan head positioning error"}, + {0x63,0x00,R,"End of user area encountered on this track"}, + {0x63,0x01,R,"Packet does not fit in available space"}, + {0x64,0x00,R,"Illegal mode for this track"}, + {0x64,0x01,R,"Invalid packet size"}, + {0x65,0x00,SC_ALL_DEVS,"Voltage fault"}, + {0x66,0x00,S,"Automatic document feeder cover up"}, + {0x66,0x01,S,"Automatic document feeder lift up"}, + {0x66,0x02,S,"Document jam in automatic document feeder"}, + {0x66,0x03,S,"Document miss feed automatic in document feeder"}, + {0x67,0x00,A,"Configuration failure"}, + {0x67,0x01,A,"Configuration of incapable logical units failed"}, + {0x67,0x02,A,"Add logical unit failed"}, + {0x67,0x03,A,"Modification of logical unit failed"}, + {0x67,0x04,A,"Exchange of logical unit failed"}, + {0x67,0x05,A,"Remove of logical unit failed"}, + {0x67,0x06,A,"Attachment of logical unit failed"}, + {0x67,0x07,A,"Creation of logical unit failed"}, + {0x67,0x08,A,"Assign failure occurred"}, + {0x67,0x09,A,"Multiply assigned logical unit"}, + {0x67,0x0A,SC_ALL_DEVS,"Set target port groups command failed"}, + {0x68,0x00,A,SC_LOGICAL_UNIT "not configured"}, + {0x69,0x00,A,"Data loss on logical unit"}, + {0x69,0x01,A,"Multiple logical unit failures"}, + {0x69,0x02,A,"Parity/data mismatch"}, + {0x6A,0x00,A,"Informational,refer to log"}, + {0x6B,0x00,A,"State change has occurred"}, + {0x6B,0x01,A,"Redundancy level got better"}, + {0x6B,0x02,A,"Redundancy level got worse"}, + {0x6C,0x00,A,"Rebuild failure occurred"}, + {0x6D,0x00,A,"Recalculate failure occurred"}, + {0x6E,0x00,A,"Command to logical unit failed"}, + {0x6F,0x00,R,"Copy protection key exchange failure - authentication failure"}, + {0x6F,0x01,R,"Copy protection key exchange failure - key not present"}, + {0x6F,0x02,R,"Copy protection key exchange failure - key not established"}, + {0x6F,0x03,R,"Read of scrambled sector without authentication"}, + {0x6F,0x04,R,"Media region code is mismatched to logical unit region"}, + {0x6F,0x05,R,"Drive region must be permanent/region reset count error"}, + /* + * FIXME(eric) - need a way to represent wildcards here. + */ + {0x70,0x00,T,"Decompression exception short algorithm id of nn"}, + {0x71,0x00,T,"Decompression exception long algorithm id"}, + {0x72,0x00,R,"Session fixation error"}, + {0x72,0x01,R,"Session fixation error writing lead-in"}, + {0x72,0x02,R,"Session fixation error writing lead-out"}, + {0x72,0x03,R,"Session fixation error - incomplete track in session"}, + {0x72,0x04,R,"Empty or partially written reserved track"}, + {0x72,0x05,R,"No more track reservations allowed"}, + {0x73,0x00,R,"Cd control error"}, + {0x73,0x01,R,"Power calibration area almost full"}, + {0x73,0x02,R,"Power calibration area is full"}, + {0x73,0x03,R,"Power calibration area error"}, + {0x73,0x04,R,"Program memory area update failure"}, + {0x73,0x05,R,"Program memory area is full"}, + {0x73,0x06,R,"RMA/PMA is full"}, + {0, 0, 0, NULL} +}; + +static const char * sc_oft_used[0x1f] = { + "umulig", /* index 0x0 should be impossible */ + "Audio play operation ", + "Logical unit ", + "not ready, ", + " operation", + " in progress ", + "Hardware impending failure ", + "Controller impending failure ", + "Data channel impending failure ", /* index 0x8 */ + "Servo impending failure ", + "Spindle impending failure ", + "Firmware impending failure ", + "Recovered data ", + " error rate too high", + " times too high", +}; + +static const char *snstext[] = { + "No Sense", /* There is no sense information */ + "Recovered Error", /* The last command completed successfully + but used error correction */ + "Not Ready", /* The addressed target is not ready */ + "Medium Error", /* Data error detected on the medium */ + "Hardware Error", /* Controller or device failure */ + "Illegal Request", + "Unit Attention", /* Removable medium was changed, or + the target has been reset */ + "Data Protect", /* Access to the data is blocked */ + "Blank Check", /* Reached unexpected written or unwritten + region of the medium */ + "Key=9", /* Vendor specific */ + "Copy Aborted", /* COPY or COMPARE was aborted */ + "Aborted Command", /* The target aborted the command */ + "Equal", /* SEARCH DATA found data equal (obsolete) */ + "Volume Overflow", /* Medium full with still data to be written */ + "Miscompare", /* Source data and data on the medium + do not agree */ + "Key=15" /* Reserved */ +}; + +static +void sg_print_asc_ascq(unsigned char asc, unsigned char ascq) +{ + int k, j; + char obuff[256]; + const char * ccp; + const char * oup; + char c; + int found = 0; + + for (k=0; additional[k].text; k++) { + if (additional[k].code1 == asc && + additional[k].code2 == ascq) { + found = 1; + ccp = additional[k].text; + for (j = 0; *ccp && (j < sizeof(obuff)); ++ccp) { + c = *ccp; + if ((c < 0x20) && (c > 0)) { + oup = sc_oft_used[(int)c]; + if (oup) { + strcpy(obuff + j, oup); + j += strlen(oup); + } + else { + strcpy(obuff + j, "???"); + j += 3; + } + } + else + obuff[j++] = c; + } + if (j < sizeof(obuff)) + obuff[j] = '\0'; + else + obuff[sizeof(obuff) - 1] = '\0'; + fprintf(OUTP, "Additional sense: %s\n", obuff); + } + } + if (found) + return; + + for(k=0; additional2[k].text; k++) { + if ((additional2[k].code1 == asc) && + (ascq >= additional2[k].code2_min) && + (ascq <= additional2[k].code2_max)) { + found = 1; + fprintf(OUTP, "Additional sense: "); + fprintf(OUTP, additional2[k].text, ascq); + fprintf(OUTP, "\n"); + } + } + if (! found) + fprintf(OUTP, "ASC=%2x ASCQ=%2x\n", asc, ascq); +} + +/* Print sense information */ +void sg_print_sense(const char * leadin, const unsigned char * sense_buffer, + int sb_len) +{ + int k, s; + int sense_key, sense_class, valid, code; + int descriptor_format = 0; + const char * error = NULL; + + if (sb_len < 1) { + fprintf(OUTP, "sense buffer empty\n"); + return; + } + sense_class = (sense_buffer[0] >> 4) & 0x07; + code = sense_buffer[0] & 0xf; + valid = sense_buffer[0] & 0x80; + if (leadin) + fprintf(OUTP, "%s: ", leadin); + + if (sense_class == 7) { /* extended sense data */ + s = sense_buffer[7] + 8; + if(s > sb_len) /* device has more available which we ignore */ + s = sb_len; + + switch (code) { + case 0x0: + error = "Current"; /* error concerns current command */ + break; + case 0x1: + error = "Deferred"; /* error concerns some earlier command */ + /* e.g., an earlier write to disk cache succeeded, but + now the disk discovers that it cannot write the data */ + break; + case 0x2: + descriptor_format = 1; + error = "Descriptor current"; + /* new descriptor sense format */ + break; + case 0x3: + descriptor_format = 1; + error = "Descriptor deferred"; + /* new descriptor sense format (deferred report) */ + break; + default: + error = "Invalid"; + } + sense_key = sense_buffer[ descriptor_format ? 1 : 2 ] & 0xf; + fprintf(OUTP, "%s, Sense key: %s\n", error, snstext[sense_key]); + + if (descriptor_format) + sg_print_asc_ascq(sense_buffer[2], sense_buffer[3]); + else { + if (!valid) + fprintf(OUTP, "[valid=0] "); + fprintf(OUTP, "Info fld=0x%x, ", (int)((sense_buffer[3] << 24) | + (sense_buffer[4] << 16) | (sense_buffer[5] << 8) | + sense_buffer[6])); + + if (sense_buffer[2] & 0x80) + fprintf(OUTP, "FMK "); /* current command has read a filemark */ + if (sense_buffer[2] & 0x40) + fprintf(OUTP, "EOM "); /* end-of-medium condition exists */ + if (sense_buffer[2] & 0x20) + fprintf(OUTP, "ILI "); /* incorrect block length requested */ + + if (s > 13) { + if (sense_buffer[12] || sense_buffer[13]) + sg_print_asc_ascq(sense_buffer[12], sense_buffer[13]); + } + if (sense_key == 5 && s >= 18 && (sense_buffer[15]&0x80)) { + fprintf(OUTP, "Sense Key Specific: Error in %s byte %d", + (sense_buffer[15]&0x40)?"Command":"Data", + (sense_buffer[16]<<8)|sense_buffer[17]); + if(sense_buffer[15]&0x08) { + fprintf(OUTP, " bit %d\n", sense_buffer[15]&0x07); + } else { + fprintf(OUTP, "\n"); + } + } + } + + } else { /* non-extended sense data */ + + /* + * Standard says: + * sense_buffer[0] & 0200 : address valid + * sense_buffer[0] & 0177 : vendor-specific error code + * sense_buffer[1] & 0340 : vendor-specific + * sense_buffer[1..3] : 21-bit logical block address + */ + + if (sb_len < 4) { + fprintf(OUTP, "sense buffer too short (4 byte minimum)\n"); + return; + } + if (leadin) + fprintf(OUTP, "%s: ", leadin); + if (sense_buffer[0] < 15) + fprintf(OUTP, + "old sense: key %s\n", snstext[sense_buffer[0] & 0x0f]); + else + fprintf(OUTP, "sns = %2x %2x\n", sense_buffer[0], sense_buffer[2]); + + fprintf(OUTP, "Non-extended sense class %d code 0x%0x ", + sense_class, code); + s = 4; + } + + fprintf(OUTP, "Raw sense data (in hex):\n "); + for (k = 0; k < s; ++k) { + if ((k > 0) && (0 == (k % 24))) + fprintf(OUTP, "\n "); + fprintf(OUTP, "%02x ", sense_buffer[k]); + } + fprintf(OUTP, "\n"); +} + +static const char * hostbyte_table[]={ +"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", +"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", +"DID_PASSTHROUGH", "DID_SOFT_ERROR", NULL}; + +void sg_print_host_status(int host_status) +{ static int maxcode=0; + int i; + + if(! maxcode) { + for(i = 0; hostbyte_table[i]; i++) ; + maxcode = i-1; + } + fprintf(OUTP, "Host_status=0x%02x", host_status); + if(host_status > maxcode) { + fprintf(OUTP, "is invalid "); + return; + } + fprintf(OUTP, "(%s) ",hostbyte_table[host_status]); +} + +static const char * driverbyte_table[]={ +"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", +"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE", NULL}; + +static const char * driversuggest_table[]={"SUGGEST_OK", +"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", +unknown,unknown,unknown, "SUGGEST_SENSE",NULL}; + + +void sg_print_driver_status(int driver_status) +{ + static int driver_max =0 , suggest_max=0; + int i; + int dr = driver_status & SG_ERR_DRIVER_MASK; + int su = (driver_status & SG_ERR_SUGGEST_MASK) >> 4; + + if(! driver_max) { + for(i = 0; driverbyte_table[i]; i++) ; + driver_max = i; + for(i = 0; driversuggest_table[i]; i++) ; + suggest_max = i; + } + fprintf(OUTP, "Driver_status=0x%02x",driver_status); + fprintf(OUTP, " (%s,%s) ", + dr < driver_max ? driverbyte_table[dr]:"invalid", + su < suggest_max ? driversuggest_table[su]:"invalid"); +} + +static int sg_sense_print(const char * leadin, int scsi_status, + int host_status, int driver_status, + const unsigned char * sense_buffer, int sb_len) +{ + int done_leadin = 0; + int done_sense = 0; + + scsi_status &= 0x7e; /*sanity */ + if ((0 == scsi_status) && (0 == host_status) && + (0 == driver_status)) + return 1; /* No problems */ + if (0 != scsi_status) { + if (leadin) + fprintf(OUTP, "%s: ", leadin); + done_leadin = 1; + fprintf(OUTP, "scsi status: "); + sg_print_scsi_status(scsi_status); + fprintf(OUTP, "\n"); + if (sense_buffer && ((scsi_status == SCSI_CHECK_CONDITION) || + (scsi_status == SCSI_COMMAND_TERMINATED))) { + sg_print_sense(0, sense_buffer, sb_len); + done_sense = 1; + } + } + if (0 != host_status) { + if (leadin && (! done_leadin)) + fprintf(OUTP, "%s: ", leadin); + if (done_leadin) + fprintf(OUTP, "plus...: "); + else + done_leadin = 1; + sg_print_host_status(host_status); + fprintf(OUTP, "\n"); + } + if (0 != driver_status) { + if (leadin && (! done_leadin)) + fprintf(OUTP, "%s: ", leadin); + if (done_leadin) + fprintf(OUTP, "plus...: "); + else + done_leadin = 1; + sg_print_driver_status(driver_status); + fprintf(OUTP, "\n"); + if (sense_buffer && (! done_sense) && + (SG_ERR_DRIVER_SENSE == (0xf & driver_status))) + sg_print_sense(0, sense_buffer, sb_len); + } + return 0; +} + +#ifdef SG_IO +int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp) +{ + return sg_sense_print(leadin, hp->status, hp->host_status, + hp->driver_status, hp->sbp, hp->sb_len_wr); +} +#endif + +int sg_chk_n_print(const char * leadin, int masked_status, + int host_status, int driver_status, + const unsigned char * sense_buffer, int sb_len) +{ + int scsi_status = (masked_status << 1) & 0x7e; + + return sg_sense_print(leadin, scsi_status, host_status, driver_status, + sense_buffer, sb_len); +} + +#ifdef SG_IO +int sg_err_category3(struct sg_io_hdr * hp) +{ + return sg_err_category_new(hp->status, hp->host_status, + hp->driver_status, hp->sbp, hp->sb_len_wr); +} +#endif + +int sg_err_category(int masked_status, int host_status, + int driver_status, const unsigned char * sense_buffer, + int sb_len) +{ + int scsi_status = (masked_status << 1) & 0x7e; + + return sg_err_category_new(scsi_status, host_status, driver_status, + sense_buffer, sb_len); +} + +int sg_err_category_new(int scsi_status, int host_status, int driver_status, + const unsigned char * sense_buffer, int sb_len) +{ + scsi_status &= 0x7e; + if ((0 == scsi_status) && (0 == host_status) && + (0 == driver_status)) + return SG_ERR_CAT_CLEAN; + if ((SCSI_CHECK_CONDITION == scsi_status) || + (SCSI_COMMAND_TERMINATED == scsi_status) || + (SG_ERR_DRIVER_SENSE == (0xf & driver_status))) { + 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(RECOVERED_ERROR == sense_key) + return SG_ERR_CAT_RECOVERED; + else if (UNIT_ATTENTION == sense_key) { + if (0x28 == asc) + return SG_ERR_CAT_MEDIA_CHANGED; + if (0x29 == asc) + return SG_ERR_CAT_RESET; + } + } + return SG_ERR_CAT_SENSE; + } + if (0 != host_status) { + if ((SG_ERR_DID_NO_CONNECT == host_status) || + (SG_ERR_DID_BUS_BUSY == host_status) || + (SG_ERR_DID_TIME_OUT == host_status)) + return SG_ERR_CAT_TIMEOUT; + } + if (0 != driver_status) { + if (SG_ERR_DRIVER_TIMEOUT == driver_status) + return SG_ERR_CAT_TIMEOUT; + } + return SG_ERR_CAT_OTHER; +} + +int sg_get_command_size(unsigned char opcode) +{ + return COMMAND_SIZE(opcode); +} + +void sg_get_command_name(unsigned char opcode, int buff_len, char * buff) +{ + const char **table = commands[ group(opcode) ]; + + if ((NULL == buff) || (buff_len < 1)) + return; + + switch ((unsigned long) table) { + case RESERVED_GROUP: + strncpy(buff, reserved, buff_len); + break; + case VENDOR_GROUP: + strncpy(buff, vendor, buff_len); + break; + default: + strncpy(buff, table[opcode & 0x1f], buff_len); + break; + } +} diff --git a/extras/multipath/sg_err.h b/extras/multipath/sg_err.h new file mode 100644 index 0000000000..ef57b5ce38 --- /dev/null +++ b/extras/multipath/sg_err.h @@ -0,0 +1,162 @@ +#ifndef SG_ERR_H +#define SG_ERR_H + +/* Feel free to copy and modify this GPL-ed code into your applications. */ + +/* Version 0.90 (20030519) +*/ + + +/* Some of the following error/status codes are exchanged between the + various layers of the SCSI sub-system in Linux and should never + reach the user. They are placed here for completeness. What appears + here is copied from drivers/scsi/scsi.h which is not visible in + the user space. */ + +#ifndef SCSI_CHECK_CONDITION +/* 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 +#endif + +/* The following are 'host_status' codes */ +#ifndef DID_OK +#define DID_OK 0x00 +#endif +#ifndef DID_NO_CONNECT +#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 DID_BAD_TARGET 0x04 /* Bad target (id?) */ +#define DID_ABORT 0x05 /* Told to abort for some other reason */ +#define DID_PARITY 0x06 /* Parity error (on SCSI bus) */ +#define DID_ERROR 0x07 /* Internal error */ +#define DID_RESET 0x08 /* Reset by somebody */ +#define DID_BAD_INTR 0x09 /* Received an unexpected interrupt */ +#define DID_PASSTHROUGH 0x0a /* Force command past mid-level */ +#define DID_SOFT_ERROR 0x0b /* The low-level driver wants a retry */ +#endif + +/* These defines are to isolate applictaions from kernel define changes */ +#define SG_ERR_DID_OK DID_OK +#define SG_ERR_DID_NO_CONNECT DID_NO_CONNECT +#define SG_ERR_DID_BUS_BUSY DID_BUS_BUSY +#define SG_ERR_DID_TIME_OUT DID_TIME_OUT +#define SG_ERR_DID_BAD_TARGET DID_BAD_TARGET +#define SG_ERR_DID_ABORT DID_ABORT +#define SG_ERR_DID_PARITY DID_PARITY +#define SG_ERR_DID_ERROR DID_ERROR +#define SG_ERR_DID_RESET DID_RESET +#define SG_ERR_DID_BAD_INTR DID_BAD_INTR +#define SG_ERR_DID_PASSTHROUGH DID_PASSTHROUGH +#define SG_ERR_DID_SOFT_ERROR DID_SOFT_ERROR + +/* The following are 'driver_status' codes */ +#ifndef DRIVER_OK +#define DRIVER_OK 0x00 +#endif +#ifndef DRIVER_BUSY +#define DRIVER_BUSY 0x01 +#define DRIVER_SOFT 0x02 +#define DRIVER_MEDIA 0x03 +#define DRIVER_ERROR 0x04 +#define DRIVER_INVALID 0x05 +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_HARD 0x07 +#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ + +/* Following "suggests" are "or-ed" with one of previous 8 entries */ +#define SUGGEST_RETRY 0x10 +#define SUGGEST_ABORT 0x20 +#define SUGGEST_REMAP 0x30 +#define SUGGEST_DIE 0x40 +#define SUGGEST_SENSE 0x80 +#define SUGGEST_IS_OK 0xff +#endif +#ifndef DRIVER_MASK +#define DRIVER_MASK 0x0f +#endif +#ifndef SUGGEST_MASK +#define SUGGEST_MASK 0xf0 +#endif + +/* These defines are to isolate applictaions from kernel define changes */ +#define SG_ERR_DRIVER_OK DRIVER_OK +#define SG_ERR_DRIVER_BUSY DRIVER_BUSY +#define SG_ERR_DRIVER_SOFT DRIVER_SOFT +#define SG_ERR_DRIVER_MEDIA DRIVER_MEDIA +#define SG_ERR_DRIVER_ERROR DRIVER_ERROR +#define SG_ERR_DRIVER_INVALID DRIVER_INVALID +#define SG_ERR_DRIVER_TIMEOUT DRIVER_TIMEOUT +#define SG_ERR_DRIVER_HARD DRIVER_HARD +#define SG_ERR_DRIVER_SENSE DRIVER_SENSE +#define SG_ERR_SUGGEST_RETRY SUGGEST_RETRY +#define SG_ERR_SUGGEST_ABORT SUGGEST_ABORT +#define SG_ERR_SUGGEST_REMAP SUGGEST_REMAP +#define SG_ERR_SUGGEST_DIE SUGGEST_DIE +#define SG_ERR_SUGGEST_SENSE SUGGEST_SENSE +#define SG_ERR_SUGGEST_IS_OK SUGGEST_IS_OK +#define SG_ERR_DRIVER_MASK DRIVER_MASK +#define SG_ERR_SUGGEST_MASK SUGGEST_MASK + + + +/* The following "print" functions send ACSII to stdout */ +extern void sg_print_command(const unsigned char * command); +extern void sg_print_sense(const char * leadin, + const unsigned char * sense_buffer, int sb_len); +extern void sg_print_status(int masked_status); +extern void sg_print_scsi_status(int scsi_status); +extern void sg_print_host_status(int host_status); +extern void sg_print_driver_status(int driver_status); + +/* sg_chk_n_print() returns 1 quietly if there are no errors/warnings + else it prints to standard output and returns 0. */ +extern int sg_chk_n_print(const char * leadin, int masked_status, + int host_status, int driver_status, + const unsigned char * sense_buffer, int sb_len); + +/* The following function declaration is for the sg version 3 driver. + Only version 3 sg_err.c defines it. */ +struct sg_io_hdr; +extern int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp); + + +/* 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_SENSE 98 /* Something else is in the sense buffer */ +#define SG_ERR_CAT_OTHER 99 /* Some other error/warning has occurred */ + +extern int sg_err_category(int masked_status, int host_status, + int driver_status, const unsigned char * sense_buffer, + int sb_len); + +extern int sg_err_category_new(int scsi_status, int host_status, + int driver_status, const unsigned char * sense_buffer, + int sb_len); + +/* The following function declaration is for the sg version 3 driver. + Only version 3 sg_err.c defines it. */ +extern int sg_err_category3(struct sg_io_hdr * hp); + +/* Returns length of SCSI command given the opcode (first byte) */ +extern int sg_get_command_size(unsigned char opcode); + +extern void sg_get_command_name(unsigned char opcode, int buff_len, + char * buff); + +#endif diff --git a/extras/multipath/sg_include.h b/extras/multipath/sg_include.h new file mode 100644 index 0000000000..6b6dd6f372 --- /dev/null +++ b/extras/multipath/sg_include.h @@ -0,0 +1,44 @@ +#ifdef SG_KERNEL_INCLUDES + #define __user + typedef unsigned char u8; + #include "/usr/src/linux/include/scsi/sg.h" + #include "/usr/src/linux/include/scsi/scsi.h" +#else + #ifdef SG_TRICK_GNU_INCLUDES + #include + #include + #else + #include + #include + #endif +#endif + +/* + Getting the correct include files for the sg interface can be an ordeal. + In a perfect world, one would just write: + #include + #include + This would include the files found in the /usr/include/scsi directory. + Those files are maintained with the GNU library which may or may not + agree with the kernel and version of sg driver that is running. Any + many cases this will not matter. However in some it might, for example + glibc 2.1's include files match the sg driver found in the lk 2.2 + series. Hence if glibc 2.1 is used with lk 2.4 then the additional + sg v3 interface will not be visible. + If this is a problem then defining SG_KERNEL_INCLUDES will access the + kernel supplied header files (assuming they are in the normal place). + The GNU library maintainers and various kernel people don't like + this approach (but it does work). + The technique selected by defining SG_TRICK_GNU_INCLUDES worked (and + was used) prior to glibc 2.2 . Prior to that version /usr/include/linux + was a symbolic link to /usr/src/linux/include/linux . + + There are other approaches if this include "mixup" causes pain. These + would involve include files being copied or symbolic links being + introduced. + + Sorry about the inconvenience. Typically neither SG_KERNEL_INCLUDES + nor SG_TRICK_GNU_INCLUDES is defined. + + dpg 20010415, 20030522 +*/ From c521693b54956c1f2dd0c0947c819b8570f6edaa Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 13 Nov 2003 06:34:36 -0800 Subject: [PATCH 0154/4284] [PATCH] add scsi_id "extra" program from Patrick Mansfield --- extras/scsi_id/COPYING | 340 ++++++++++++++ extras/scsi_id/Makefile | 51 +++ extras/scsi_id/README | 19 + extras/scsi_id/TODO | 16 + extras/scsi_id/VERSION | 1 + extras/scsi_id/scsi.h | 96 ++++ extras/scsi_id/scsi_id.c | 827 ++++++++++++++++++++++++++++++++++ extras/scsi_id/scsi_id.config | 40 ++ extras/scsi_id/scsi_id.h | 42 ++ extras/scsi_id/scsi_serial.c | 735 ++++++++++++++++++++++++++++++ 10 files changed, 2167 insertions(+) create mode 100644 extras/scsi_id/COPYING create mode 100644 extras/scsi_id/Makefile create mode 100644 extras/scsi_id/README create mode 100644 extras/scsi_id/TODO create mode 100644 extras/scsi_id/VERSION create mode 100644 extras/scsi_id/scsi.h create mode 100644 extras/scsi_id/scsi_id.c create mode 100644 extras/scsi_id/scsi_id.config create mode 100644 extras/scsi_id/scsi_id.h create mode 100644 extras/scsi_id/scsi_serial.c diff --git a/extras/scsi_id/COPYING b/extras/scsi_id/COPYING new file mode 100644 index 0000000000..60549be514 --- /dev/null +++ b/extras/scsi_id/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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) 19yy + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) 19yy 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 Library General +Public License instead of this License. diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile new file mode 100644 index 0000000000..5ad2bcf3e1 --- /dev/null +++ b/extras/scsi_id/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (C) 2003 IBM +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +VERSION=0.1 + +prefix = +sbindir = ${prefix}/sbin + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 + +CFLAGS=-DVERSION=\"$(VERSION)\" $(DEBUG) -Wall + +PROG=scsi_id + +LIBSYSFS=-lsysfs +STRIP=-s +LDFLAGS=$(STRIP) --static + +OBJS= scsi_id.o \ + scsi_serial.o \ + +all: $(PROG) + +install: all + $(INSTALL_PROGRAM) -D $(PROG) $(sbindir)/$(PROG) + +uninstall: + -rm $(sbindir)/$(PROG) + +$(OBJS): scsi_id.h scsi.h + +clean: + rm -f $(PROG) $(OBJS) + +$(PROG): $(OBJS) + $(CC) $(OBJS) $(LDFLAGS) $(LIBSYSFS) -o $(PROG) diff --git a/extras/scsi_id/README b/extras/scsi_id/README new file mode 100644 index 0000000000..b13cf1e50a --- /dev/null +++ b/extras/scsi_id/README @@ -0,0 +1,19 @@ +scsi_id - generate a SCSI unique identifier for a given SCSI device + +Primarily for use with udev callout config entries. This could also be +used by a multi-path configuration tool that requires SCSI id's. + +Requires: + +- Linux kernel 2.6 + +- libsysfs + +No man page yet. + +libsysfs 0_2_0 was not installing libsysfs.h or dlist.h, manually copy +those files to /usr/include/sys before compiling. + +Build via make and make install. + +Please send questions, comments or patches to patmans@us.ibm.com. diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO new file mode 100644 index 0000000000..ba52101431 --- /dev/null +++ b/extras/scsi_id/TODO @@ -0,0 +1,16 @@ +- Investigate shrinking build size: use klibc or uClibc, or copy whatever + udev does + +- write a man page + +- send in kernel patch for REQ_BLOCK_PC, to always set sd and sr set + retries (scmd->allowed) to <= 1 + +- Pull SG_IO code into one .c file. + +- implement callout to device specific serial id code. The "-c prog" is + not implemented. + + This needs an implementation of a device specific callout before it can + be completed. Someone with hardware requiring this needs to send in a + patch. diff --git a/extras/scsi_id/VERSION b/extras/scsi_id/VERSION new file mode 100644 index 0000000000..49d59571fb --- /dev/null +++ b/extras/scsi_id/VERSION @@ -0,0 +1 @@ +0.1 diff --git a/extras/scsi_id/scsi.h b/extras/scsi_id/scsi.h new file mode 100644 index 0000000000..780e001576 --- /dev/null +++ b/extras/scsi_id/scsi.h @@ -0,0 +1,96 @@ +/* + * scsi.h + * + * General scsi and linux scsi specific defines and structs. + * + * Copyright (C) IBM Corp. 2003 + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#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 + +/* + * 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/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c new file mode 100644 index 0000000000..d34d9284e5 --- /dev/null +++ b/extras/scsi_id/scsi_id.c @@ -0,0 +1,827 @@ +/* + * scsi_id.c + * + * Main section of the scsi_id program + * + * Copyright (C) IBM Corp. 2003 + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi_id.h" + +#ifndef VERSION +#warning No version +#define VERSION "unknown" +#endif + +/* + * temporary names for mknod. + */ +#define TMP_DIR "/tmp" +#define TMP_PREFIX "scsi" + +#define CONFIG_FILE "/etc/scsi_id.config" + +#define MAX_NAME_LEN 72 + +#define MAX_SERIAL_LEN 128 + +static const char short_options[] = "bc:d:ef:gip:s:vV"; +static const struct option long_options[] = { + {"broken", no_argument, NULL, 'b'}, /* also per dev */ + {"callout", required_argument, NULL, 'c'}, /* also per dev */ + {"device", required_argument, NULL, 'd'}, + {"stderr", no_argument, NULL, 'e'}, + {"file", required_argument, NULL, 'f'}, + {"good", no_argument, NULL, 'g'}, /* also per dev */ + {"busid", no_argument, NULL, 'i'}, /* also per dev */ + {"page", required_argument, NULL, 'p'}, /* also per dev */ + {"devpath", required_argument, NULL, 's'}, + {"verbose", no_argument, NULL, 'v'}, + {"version", no_argument, NULL, 'V'}, + {0, 0, 0, 0} +}; +/* + * Just duplicate per dev options. + */ +static const char dev_short_options[] = "bc:gp:"; +static const struct option dev_long_options[] = { + {"broken", no_argument, NULL, 'b'}, /* also per dev */ + {"callout", required_argument, NULL, 'c'}, /* also per dev */ + {"good", no_argument, NULL, 'g'}, /* also per dev */ + {"page", required_argument, NULL, 'p'}, /* also per dev */ + {0, 0, 0, 0} +}; + +char sysfs_mnt_path[SYSFS_PATH_MAX]; + +static int all_good; +static char *default_callout; +static int dev_specified; +static int sys_specified; +static char config_file[MAX_NAME_LEN] = CONFIG_FILE; +static int display_bus_id; +static int default_page_code; +static int use_stderr; +static int debug; +static int hotplug_mode; + +void log_message (int level, const char *format, ...) +{ + va_list args; + + if (!debug && level == LOG_DEBUG) + return; + + va_start (args, format); + if (!hotplug_mode || use_stderr) { + vfprintf(stderr, format, args); + } else { + static int logging_init = 0; + if (!logging_init) { + openlog ("scsi_id", LOG_PID, LOG_DAEMON); + logging_init = 1; + } + + vsyslog(level, format, args); + } + va_end (args); + return; +} + +static int sysfs_get_actual_dev(const char *sysfs_path, char *dev, int len) +{ + dprintf("%s\n", sysfs_path); + strncpy(dev, sysfs_path, len); + strncat(dev, "/device", len); + if (sysfs_get_link(dev, dev, len)) { + if (!hotplug_mode) + log_message(LOG_WARNING, "%s: %s\n", dev, + strerror(errno)); + return -1; + } + return 0; +} + +/* + * sysfs_is_bus: Given the sysfs_path to a device, return 1 if sysfs_path + * is on bus, 0 if not on bus, and < 0 on error + */ +static int sysfs_is_bus(const char *sysfs_path, const char *bus) +{ + char bus_dev_name[SYSFS_PATH_MAX]; + char bus_id[SYSFS_NAME_LEN]; + struct stat stat_buf; + ino_t dev_inode; + + dprintf("%s\n", sysfs_path); + + if (sysfs_get_name_from_path(sysfs_path, bus_id, SYSFS_NAME_LEN)) + return -1; + + snprintf(bus_dev_name, MAX_NAME_LEN, "%s/%s/%s/%s/%s", sysfs_mnt_path, + SYSFS_BUS_DIR, bus, SYSFS_DEVICES_NAME, bus_id); + + if (stat(sysfs_path, &stat_buf)) + return -1; + dev_inode = stat_buf.st_ino; + + if (stat(bus_dev_name, &stat_buf)) { + if (errno == ENOENT) + return 0; + else + return -1; + } + if (dev_inode == stat_buf.st_ino) + return 1; + else + return 0; +} + +static int get_major_minor(const char *devpath, int *major, int *minor) +{ + struct sysfs_class_device *class_dev; + char dev_value[SYSFS_NAME_LEN]; + char *dev; + + dprintf("%s\n", devpath); + class_dev = sysfs_open_class_device(devpath); + if (!class_dev) { + log_message(LOG_WARNING, "open class %s failed: %s\n", devpath, + strerror(errno)); + return -1; + } + + dev = sysfs_get_attr(class_dev, "dev"); + if (dev) + strncpy(dev_value, dev, SYSFS_NAME_LEN); + sysfs_close_class_device(class_dev); + if (!dev) { + /* + * XXX This happens a lot, since sg has no dev attr. + * Someday change this back to a LOG_WARNING. + */ + log_message(LOG_DEBUG, "%s could not get dev attribute: %s\n", + devpath, strerror(errno)); + return -1; + } + dev = NULL; + + dprintf("dev %s", dev_value); /* dev_value has a trailing \n */ + if (sscanf(dev_value, "%u:%u", major, minor) != 2) { + log_message(LOG_WARNING, "%s: invalid dev major/minor\n", + devpath); + return -1; + } + + return 0; +} + +static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) +{ + int major, minor; + + dprintf("(%s)\n", devpath); + + if (get_major_minor(devpath, &major, &minor)) + return -1; + snprintf(tmpdev, MAX_NAME_LEN, "%s/%s-maj%d-min%d-%u", + TMP_DIR, TMP_PREFIX, major, minor, getpid()); + + dprintf("tmpdev '%s'\n", tmpdev); + + if (mknod(tmpdev, 0600 | dev_type, makedev(major, minor))) { + log_message(LOG_WARNING, "mknod failed: %s\n", strerror(errno)); + return -1; + } + return 0; +} + +static int has_sysfs_prefix(const char *path, const char *prefix) +{ + char match[MAX_NAME_LEN]; + + strncpy(match, sysfs_mnt_path, MAX_NAME_LEN); + strncat(match, prefix, MAX_NAME_LEN); + if (strncmp(path, match, strlen(match)) == 0) + return 1; + else + 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(char *vendor, char *model, int *argc, + char ***newargv) +{ + char buffer[256]; + FILE *fd; + char *buf; + char *str1; + char *vendor_in, *model_in, *options_in; /* read in from file */ + int lineno; + int c; + int retval = 0; + static char *prog_string = "arg0"; + + dprintf("vendor='%s'; model='%s'\n", vendor, model); + fd = fopen(config_file, "r"); + if (fd == NULL) { + dprintf("can't open %s\n", config_file); + if (errno == ENOENT) { + return 1; + } else { + log_message(LOG_WARNING, "can't open %s: %s\n", + config_file, strerror(errno)); + return -1; + } + } + + *newargv = NULL; + lineno = 0; + + while (1) { + vendor_in = model_in = options_in = NULL; + + buf = fgets(buffer, sizeof(buffer), fd); + if (buf == NULL) + break; + lineno++; + + while (isspace(*buf)) + buf++; + + if (*buf == '\0') + /* + * blank or all whitespace line + */ + continue; + + if (*buf == '#') + /* + * comment line + */ + continue; + +#ifdef LOTS + dprintf("lineno %d: '%s'\n", lineno, buf); +#endif + 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; + } + dprintf("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)) { + log_message(LOG_WARNING, + "Error parsing config file line %d '%s'\n", + lineno, buffer); + retval = -1; + break; + } + if (vendor == NULL) { + if (vendor_in == NULL) { + dprintf("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). + */ + dprintf("matched vendor/model\n"); + break; + } else { + dprintf("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. + */ + c = argc_count(options_in) + 2; + *newargv = calloc(c, sizeof(**newargv)); + if (!*newargv) { + log_message(LOG_WARNING, + "Can't allocate memory\n"); + retval = -1; + } else { + *argc = c; + c = 0; + (*newargv)[c] = prog_string; /* nothing */ + for (c = 1; c < *argc; c++) + (*newargv)[c] = strsep(&options_in, " "); + } + } else { + /* + * No matches. + */ + retval = 1; + } + } + fclose(fd); + return retval; +} + +static int set_options(int argc, char **argv, const char *short_opts, + const struct option *long_opts, char *target, + char *maj_min_dev) +{ + int option; + int option_ind; + + /* + * optind is a global extern used by getopt_long. Since we can + * call set_options twice (once for command line, and once for + * config file) we have to reset this back to 0. + */ + optind = 0; + while (1) { + option = getopt_long(argc, argv, short_options, long_options, + &option_ind); + if (option == -1) + break; + + if (optarg) + dprintf("option '%c' arg '%s'\n", option, optarg); + else + dprintf("option '%c'\n", option); + + switch (option) { + case 'b': + all_good = 0; + break; + + case 'c': + default_callout = optarg; + break; + + case 'd': + dev_specified = 1; + strncpy(maj_min_dev, optarg, MAX_NAME_LEN); + break; + + case 'e': + use_stderr = 1; + break; + + case 'f': + strncpy(config_file, optarg, MAX_NAME_LEN); + break; + + case 'g': + all_good = 1; + break; + + case 'i': + display_bus_id = 1; + break; + + case 'p': + if (strcmp(optarg, "0x80") == 0) { + default_page_code = 0x80; + } else if (strcmp(optarg, "0x83") == 0) { + default_page_code = 0x83; + } else { + log_message(LOG_WARNING, + "Unknown page code '%s'\n", optarg); + return -1; + } + break; + + case 's': + sys_specified = 1; + strncpy(target, sysfs_mnt_path, MAX_NAME_LEN); + strncat(target, optarg, MAX_NAME_LEN); + break; + + case 'v': + debug++; + break; + + case 'V': + log_message(LOG_WARNING, "scsi_id version: %s\n", + VERSION); + exit(0); + break; + + default: + log_message(LOG_WARNING, + "Unknown or bad option '%c' (0x%x)\n", + option, option); + return -1; + } + } + return 0; +} + +static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, + int *page_code, char *callout) +{ + int retval; + int newargc; + char **newargv = NULL; + char *vendor; + char *model; + int option; + int option_ind; + + + *good_bad = all_good; + *page_code = default_page_code; + if (default_callout && (callout != default_callout)) + strncpy(callout, default_callout, MAX_NAME_LEN); + else + callout[0] = '\0'; + + vendor = sysfs_get_attr(scsi_dev, "vendor"); + if (!vendor) { + log_message(LOG_WARNING, "%s: no vendor attribute\n", + scsi_dev->name); + return -1; + } + + model = sysfs_get_attr(scsi_dev, "model"); + if (!vendor) { + log_message(LOG_WARNING, "%s: no model attribute\n", + scsi_dev->name); + return -1; + } + + retval = get_file_options(vendor, model, &newargc, &newargv); + + optind = 0; /* global extern, reset to 0 */ + while (retval == 0) { + option = getopt_long(newargc, newargv, dev_short_options, + dev_long_options, &option_ind); + if (option == -1) + break; + + if (optarg) + dprintf("option '%c' arg '%s'\n", option, optarg); + else + dprintf("option '%c'\n", option); + + switch (option) { + case 'b': + *good_bad = 0; + break; + + case 'c': + strncpy(callout, default_callout, MAX_NAME_LEN); + break; + + case 'g': + *good_bad = 1; + break; + + case 'p': + if (strcmp(optarg, "0x80") == 0) { + *page_code = 0x80; + } else if (strcmp(optarg, "0x83") == 0) { + *page_code = 0x83; + } else { + log_message(LOG_WARNING, + "Unknown page code '%s'\n", optarg); + retval = -1; + } + break; + + default: + log_message(LOG_WARNING, + "Unknown or bad option '%c' (0x%x)\n", + option, option); + retval = -1; + break; + } + } + + if (newargv) + free(newargv); + return retval; +} + +/* + * 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 *target_path, char *maj_min_dev) +{ + int retval; + int dev_type = 0; + char full_dev_path[MAX_NAME_LEN]; + char serial[MAX_SERIAL_LEN]; + struct sysfs_class_device *scsi_dev; /* of scsi_device full_dev_path */ + int good_dev; + int page_code; + char callout[MAX_NAME_LEN]; + + dprintf("target_path %s\n", target_path); + + /* + * Ugly: depend on the sysfs path to tell us whether this is a + * block or char device. This should probably be encoded in the + * "dev" along with the major/minor. + */ + if (has_sysfs_prefix(target_path, "/block")) { + dev_type = S_IFBLK; + } else if (has_sysfs_prefix(target_path, "/class")) { + dev_type = S_IFCHR; + } else { + if (!hotplug_mode) { + log_message(LOG_WARNING, + "Non block or class device '%s'\n", + target_path); + return 1; + } else { + /* + * Expected in some cases. + */ + dprintf("Non block or class device\n"); + return 0; + } + } + + if (sysfs_get_actual_dev(target_path, full_dev_path, MAX_NAME_LEN)) + return 1; + + dprintf("full_dev_path %s\n", full_dev_path); + + /* + * Allow only scsi devices (those that have a matching device + * under /bus/scsi/devices). + * + * Other block devices can support SG IO, but only ide-cd does, so + * for now, don't bother with anything else. + */ + retval = sysfs_is_bus(full_dev_path, "scsi"); + if (retval == 0) { + if (hotplug_mode) + /* + * Expected in some cases. + */ + dprintf("%s is not a scsi device\n", target_path); + else + log_message(LOG_WARNING, "%s is not a scsi device\n", + target_path); + return 1; + } else if (retval < 0) { + log_message(LOG_WARNING, "sysfs_is_bus failed: %s\n", + strerror(errno)); + return 1; + } + + /* + * mknod a temp dev to communicate with the device. + */ + if (!dev_specified && create_tmp_dev(target_path, maj_min_dev, + dev_type)) { + dprintf("create_tmp_dev failed\n"); + return 1; + } + + scsi_dev = sysfs_open_class_device(full_dev_path); + if (!scsi_dev) { + log_message(LOG_WARNING, "open class %s failed: %s\n", + full_dev_path, strerror(errno)); + return 1; + } + + /* + * Get any per device (vendor + model) options from the config + * file. + */ + retval = per_dev_options(scsi_dev, &good_dev, &page_code, callout); + dprintf("per dev options: good %d; page code 0x%x; callout '%s'\n", + good_dev, page_code, callout); + + if (!good_dev) { + retval = 1; + } else if (callout[0] != '\0') { + /* + * exec vendor callout, pass it only the "name" to be used + * for error messages, and the dev to open. + * + * This won't work if we need to pass on the original + * command line (when not hotplug mode) since the option + * parsing and per dev parsing modify the argv's. + * + * XXX Not implemented yet. And not fully tested ;-) + */ + retval = 1; + } else if (scsi_get_serial(scsi_dev, maj_min_dev, page_code, + serial, MAX_SERIAL_LEN)) { + retval = 1; + } else { + retval = 0; + } + if (!retval) { + if (display_bus_id) + printf("%s ", scsi_dev->name); + printf("%s", serial); + if (!hotplug_mode) + printf("\n"); + dprintf("%s\n", serial); + retval = 0; + } + fflush(stdout); + sysfs_close_class_device(scsi_dev); + + if (!dev_specified) + unlink(maj_min_dev); + + return retval; +} + +int main(int argc, char **argv) +{ + int retval; + char *devpath; + char target_path[MAX_NAME_LEN]; + char maj_min_dev[MAX_NAME_LEN]; + int newargc; + char **newargv; + + if (getenv("DEBUG")) + debug++; + + if ((argc == 2) && (argv[1][0] != '-')) { + hotplug_mode = 1; + dprintf("hotplug assumed\n"); + } + + dprintf("argc is %d\n", argc); + if (sysfs_get_mnt_path(sysfs_mnt_path, MAX_NAME_LEN)) { + log_message(LOG_WARNING, "sysfs_get_mnt_path failed: %s\n", + strerror(errno)); + exit(1); + } + + if (hotplug_mode) { + /* + * There is a kernel race creating attributes, if called + * directly, uncomment the sleep. + */ + /* sleep(1); */ + + devpath = getenv("DEVPATH"); + if (!devpath) { + log_message(LOG_WARNING, "DEVPATH is not set\n"); + exit(1); + } + sys_specified = 1; + + strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); + strncat(target_path, devpath, MAX_NAME_LEN); + } else { + if (set_options(argc, argv, short_options, long_options, + target_path, maj_min_dev) < 0) + exit(1); + } + + /* + * Override any command line options set via the config file. This + * is the only way to set options when in hotplug mode. + */ + newargv = NULL; + retval = get_file_options(NULL, NULL, &newargc, &newargv); + if (retval < 0) { + exit(1); + } else if (newargv && (retval == 0)) { + if (set_options(newargc, newargv, short_options, long_options, + target_path, maj_min_dev) < 0) + exit(1); + free(newargv); + } + + if (!sys_specified) { + log_message(LOG_WARNING, "-s must be specified\n"); + exit(1); + } + + retval = scsi_id(target_path, maj_min_dev); + exit(retval); +} diff --git a/extras/scsi_id/scsi_id.config b/extras/scsi_id/scsi_id.config new file mode 100644 index 0000000000..4fdb89e28a --- /dev/null +++ b/extras/scsi_id/scsi_id.config @@ -0,0 +1,40 @@ +# +# Informational and example scsi_id.config file for use with scsi_id. +# + +# General syntax is: +# +# lower or upper case has no affect on the left side. Quotes (") are +# required if you need 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 maching 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. +# +# The "option" line is searched when scsi_id first starts up (for use with +# hotplug during boot). +# +# options= +# +# vendor=string[,model=string],options= + +# +# If you normally don't need id's, black list everyone: +# +options=-b + +# +# Then white list devices on your system that have correct and useful id's: +# +vendor=someone, model=nicedrive, options=-g + +# If you have all good devices on your system use, mark all as good: + +## options=-g + +# Then black list any offenders. Missing entries here could be dangerous +# if you rely on the id for naming or multi-path configuration! + +## vendor=ELBONIA, model=borken, options=-b diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h new file mode 100644 index 0000000000..8be492b75a --- /dev/null +++ b/extras/scsi_id/scsi_id.h @@ -0,0 +1,42 @@ +/* + * scsi_id.h + * + * General defines and such for scsi_id + * + * Copyright (C) IBM Corp. 2003 + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#define dprintf(format, arg...) \ + log_message(LOG_DEBUG, "%s: " format, __FUNCTION__, ## arg) + +#define MAX_NAME_LEN 72 +#define OFFSET (2 * sizeof(unsigned int)) + +static inline char *sysfs_get_attr(struct sysfs_class_device *dev, + const char *attr) +{ + return sysfs_get_value_from_attributes(dev->directory->attributes, + attr); +} + +extern int scsi_get_serial (struct sysfs_class_device *scsi_dev, + const char *devname, int page_code, char *serial, + int len); +extern void log_message (int level, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); + diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c new file mode 100644 index 0000000000..302429c0d4 --- /dev/null +++ b/extras/scsi_id/scsi_serial.c @@ -0,0 +1,735 @@ +/* + * scsi_serial.c + * + * Code related to requesting and getting an id from a scsi device + * + * Copyright (C) IBM Corp. 2003 + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scsi_id.h" +#include "scsi.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"; + +/* + * XXX maybe move all these to an sg_io.c file. + * + * From here ... + */ + +/* + * 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_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; + } + } + 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_class_device *scsi_dev, + 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. + */ + + dprintf("got check condition\n"); + + sb_len = io->sb_len_wr; + if (sb_len < 1) { + log_message(LOG_WARNING, "%s: sense buffer empty\n", + scsi_dev->name); + 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) { + log_message(LOG_WARNING, + "%s: sense buffer too small %d bytes," + " %d bytes too short\n", scsi_dev->name, + 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? + */ + log_message(LOG_WARNING, "%s: sense result too" + " small %d bytes\n", + scsi_dev->name, 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 { + log_message(LOG_WARNING, + "%s: invalid sense code 0x%x\n", + scsi_dev->name, code); + return -1; + } + log_message(LOG_WARNING, + "%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n", + scsi_dev->name, sense_key, asc, ascq); + } else { + if (sb_len < 4) { + log_message(LOG_WARNING, + "%s: sense buffer too small %d bytes, %d bytes too short\n", + scsi_dev->name, sb_len, 4 - sb_len); + return -1; + } + + if (sense_buffer[0] < 15) + log_message(LOG_WARNING, "%s: old sense key: 0x%x\n", + scsi_dev->name, sense_buffer[0] & 0x0f); + else + log_message(LOG_WARNING, "%s: sense = %2x %2x\n", + scsi_dev->name, sense_buffer[0], + sense_buffer[2]); + log_message(LOG_WARNING, + "%s: non-extended sense class %d code 0x%0x ", + scsi_dev->name, sense_class, code); + + } + +#ifdef DUMP_SENSE + for (i = 0, j = 0; (i < s) && (j < 254); i++) { + dprintf("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'; + log_message(LOG_WARNING, "%s: sense dump:\n", scsi_dev->name); + log_message(LOG_WARNING, "%s: %s\n", scsi_dev->name, out_buffer); + +#endif + return -1; +} + +static int scsi_dump(struct sysfs_class_device *scsi_dev, struct sg_io_hdr *io) +{ + if (!io->status && !io->host_status && !io->msg_status && + !io->driver_status) { + /* + * Impossible, should not be called. + */ + log_message(LOG_WARNING, "%s: called with no error\n", + __FUNCTION__); + return -1; + } + + log_message(LOG_WARNING, "%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x\n", + scsi_dev->name, io->driver_status, io->host_status, + io->msg_status, io->status); + if (io->status == SCSI_CHECK_CONDITION) + return scsi_dump_sense(scsi_dev, io); + else + return -1; +} + +static int scsi_inquiry(struct sysfs_class_device *scsi_dev, 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; + unsigned char *inq; + unsigned char *buffer; + int retry = 3; /* rather random */ + + if (buflen > 255) { + log_message(LOG_WARNING, "buflen %d too long\n", buflen); + return -1; + } + inq = malloc(OFFSET + sizeof (inq_cmd) + 512); + memset(inq, 0, OFFSET + sizeof (inq_cmd) + 512); + buffer = inq + OFFSET; + +resend: + 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 = buffer; + io_hdr.cmdp = inq_cmd; + io_hdr.sbp = sense; + io_hdr.timeout = DEF_TIMEOUT; + + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + log_message(LOG_WARNING, "%s ioctl failed: %s\n", + scsi_dev->name, strerror(errno)); + return -1; + } + + retval = sg_err_category3(&io_hdr); + + switch (retval) { + case SG_ERR_CAT_CLEAN: + case SG_ERR_CAT_RECOVERED: + retval = 0; + break; + + default: + retval = scsi_dump(scsi_dev, &io_hdr); + } + + if (!retval) { + retval = buflen; + memcpy(buf, buffer, retval); + } else if (retval > 0) { + if (--retry > 0) { + dprintf("%s: Retrying ...\n", scsi_dev->name); + goto resend; + } + retval = -1; + } + + free(inq); + return retval; +} + +/* + * XXX maybe move all these to an sg_io.c file. + * + * Ending here. + */ + +int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, + char *buffer, int len) +{ + int retval; + char *vendor; + + memset(buffer, 0, len); + retval = scsi_inquiry(scsi_dev, fd, 1, 0x0, buffer, len); + if (retval < 0) + return 1; + + if (buffer[1] != 0) { + log_message(LOG_WARNING, "%s: page 0 not available.\n", + scsi_dev->name); + return 1; + } + if (buffer[3] > len) { + log_message(LOG_WARNING, "%s: page 0 buffer too long %d", + scsi_dev->name, 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_get_attr(scsi_dev, "vendor"); + if (!vendor) { + log_message(LOG_WARNING, "%s: no vendor attribute\n", + scsi_dev->name); + return 1; + } + if (!strncmp(&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) { + log_message(LOG_WARNING, "%s invalid page0 data\n", + scsi_dev->name); + return 1; + } + } + return 0; +} + +/* + * The caller checks that serial is long enough to include the vendor + + * model. + */ +static int prepend_vendor_model(struct sysfs_class_device *scsi_dev, + char *serial) +{ + char *attr; + int ind; + + attr = sysfs_get_attr(scsi_dev, "vendor"); + if (!attr) { + log_message(LOG_WARNING, "%s: no vendor attribute\n", + scsi_dev->name); + return 1; + } + strncpy(serial, attr, VENDOR_LENGTH); + ind = strlen(serial) - 1; + /* + * Remove sysfs added newlines. + */ + if (serial[ind] == '\n') + serial[ind] = '\0'; + + attr = sysfs_get_attr(scsi_dev, "model"); + if (!attr) { + log_message(LOG_WARNING, "%s: no model attribute\n", + scsi_dev->name); + return 1; + } + strncat(serial, attr, MODEL_LENGTH); + ind = strlen(serial) - 1; + if (serial[ind] == '\n') + serial[ind] = '\0'; + else + 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)) { + log_message(LOG_WARNING, "%s: expected length %d, got length %d\n", + scsi_dev->name, (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_class_device *scsi_dev, + char *page_83, + const struct scsi_id_search_values *id_search, + char *serial, int max_len) +{ + int i, j, 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) { + log_message(LOG_WARNING, "%s: length %d too short - need %d\n", + scsi_dev->name, max_len, len); + return 1; + } + + serial[0] = hex_str[id_search->id_type]; + + /* + * Prepend the vendor and model before the id since if it is not + * unique across all vendors and models. + */ + if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC) + if (prepend_vendor_model(scsi_dev, &serial[1]) < 0) { + dprintf("prepend failed\n"); + return 1; + } + + i = 4; /* offset to the start of the identifier */ + 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++; + } + } + return 0; +} + +static int do_scsi_page83_inquiry(struct sysfs_class_device *scsi_dev, int fd, + char *serial, int len) +{ + int retval; + int id_ind, j; + unsigned char page_83[256]; + + memset(page_83, 0, 256); + retval = scsi_inquiry(scsi_dev, fd, 1, 0x83, page_83, 255); + if (retval < 0) + return 1; + + if (page_83[1] != 0x83) { + log_message(LOG_WARNING, "%s: Invalid page 0x83\n", + scsi_dev->name); + return 1; + } + + /* + * 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 <= page_83[3] + 3; + j += page_83[j + 3] + 4) { + retval = check_fill_0x83_id(scsi_dev, &page_83[j], + &id_search_list[id_ind], + serial, len); + dprintf("%s id desc %d/%d/%d\n", scsi_dev->name, + id_search_list[id_ind].id_type, + id_search_list[id_ind].naa_type, + id_search_list[id_ind].code_set); + if (!retval) { + dprintf(" used\n"); + return retval; + } else if (retval < 0) { + dprintf(" failed\n"); + return retval; + } else { + dprintf(" not used\n"); + } + } + } + return 1; +} + +int do_scsi_page80_inquiry(struct sysfs_class_device *scsi_dev, int fd, + char *serial, int max_len) +{ + int retval; + int ser_ind; + int i; + int len; + unsigned char buf[256]; + + memset(buf, 0, 256); + retval = scsi_inquiry(scsi_dev, fd, 1, 0x80, buf, 255); + if (retval < 0) + return retval; + + if (buf[1] != 0x80) { + log_message(LOG_WARNING, "%s: Invalid page 0x80\n", + scsi_dev->name); + return 1; + } + + len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3]; + if (max_len < len) { + log_message(LOG_WARNING, "%s: length %d too short - need %d\n", + scsi_dev->name, 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(scsi_dev, &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]; + return 0; +} + +int scsi_get_serial (struct sysfs_class_device *scsi_dev, const char *devname, + int page_code, char *serial, int len) +{ + unsigned char page0[256]; + int fd; + int ind; + int retval; + + if (len > 255) { + } + memset(serial, 0, len); + dprintf("opening %s\n", devname); + fd = open(devname, O_RDONLY); + if (fd < 0) { + log_message(LOG_WARNING, "%s cannot open %s: %s\n", + scsi_dev->name, devname, strerror(errno)); + return 1; + } + + if (page_code == 0x80) { + if (do_scsi_page80_inquiry(scsi_dev, fd, serial, len)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } else if (page_code == 0x83) { + if (do_scsi_page83_inquiry(scsi_dev, fd, serial, len)) { + retval = 1; + goto completed; + } else { + retval = 0; + goto completed; + } + } else if (page_code != 0x00) { + log_message(LOG_WARNING, "%s unsupported page code 0x%d\n", + scsi_dev->name, 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(scsi_dev, fd, page0, 255)) { + /* + * 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; + } + + dprintf("%s: Checking page0\n", scsi_dev->name); + + for (ind = 4; ind <= page0[3] + 3; ind++) + if (page0[ind] == 0x83) + if (!do_scsi_page83_inquiry(scsi_dev, fd, serial, + len)) { + /* + * Success + */ + retval = 0; + goto completed; + } + + for (ind = 4; ind <= page0[3] + 3; ind++) + if (page0[ind] == 0x80) + if (!do_scsi_page80_inquiry(scsi_dev, fd, serial, + len)) { + /* + * Success + */ + retval = 0; + goto completed; + } + retval = 1; +completed: + if (close(fd) < 0) + log_message(LOG_WARNING, "close failed: %s", strerror(errno)); + return retval; +} From 30defadd3fbef99628a16dcd7c4a2964982deac2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 13 Nov 2003 20:08:10 -0800 Subject: [PATCH 0155/4284] [PATCH] get the major/minor number before we name the device. Will come in handy later... --- udev-add.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/udev-add.c b/udev-add.c index d20e96ee72..6f0e3bf105 100644 --- a/udev-add.c +++ b/udev-add.c @@ -44,7 +44,7 @@ * mm is the minor * The value is in decimal. */ -static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int *minor) +static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev) { int retval = -ENODEV; @@ -56,10 +56,10 @@ static int get_major_minor(struct sysfs_class_device *class_dev, int *major, int dbg("dev = %s", dev); - if (sscanf(dev, "%u:%u", major, minor) != 2) + if (sscanf(dev, "%u:%u", &udev->major, &udev->minor) != 2) goto exit; - dbg("found major = %d, minor = %d", *major, *minor); + dbg("found major = %d, minor = %d", udev->major, udev->minor); retval = 0; exit: @@ -219,7 +219,7 @@ exit: int udev_add_device(char *path, char *subsystem) { - struct sysfs_class_device *class_dev; + struct sysfs_class_device *class_dev = NULL; struct udevice dev; int retval = -EINVAL; @@ -237,32 +237,28 @@ int udev_add_device(char *path, char *subsystem) if (class_dev == NULL) goto exit; - retval = namedev_name_device(class_dev, &dev); - if (retval) - return retval; - - retval = get_major_minor(class_dev, &dev.major, &dev.minor); + retval = get_major_minor(class_dev, &dev); if (retval) { dbg("get_major_minor failed"); goto exit; } -// strcpy(dev.name, attr.name); -// strcpy(dev.owner, attr.owner); -// strcpy(dev.group, attr.group); -// dev.mode = attr.mode; - + retval = namedev_name_device(class_dev, &dev); + if (retval) + goto exit; + retval = udevdb_add_dev(path, &dev); if (retval != 0) dbg("udevdb_add_dev failed, but we are going to try to create the node anyway. " "But remove might not work properly for this device."); - sysfs_close_class_device(class_dev); - dbg("name = %s", dev.name); retval = create_node(&dev); exit: + if (class_dev) + sysfs_close_class_device(class_dev); + return retval; } From 98b88dbf704a1376ee4c79051086089adde5d626 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 18 Nov 2003 00:59:27 -0800 Subject: [PATCH 0156/4284] [PATCH] implement printf-like placeholder support for NAME > Problem is, if you use the LABEL rule to match a device, like a SCSI > vendor, then all of the partitions, as well as the main block device, > will end up with the same name. That's why I added the "add the number" > hack to the LABEL rule. > > So yes, your patch is correct in that we shouldn't always be adding the > number to any match for LABEL (like for char devices), but if we do > that, then we break partitions. Your '%' patch fixes this, but I'd just > like to extend it a bit. Let me see what I can come up with... Oh, I see. Do you mean something like this: LABEL, BUS="usb", model="Creative Labs WebCam 3", NAME="webcam%n-%M:%m-test" results in: "webcam0-81:0-test" Nov 15 16:51:53 pim udev[16193]: get_class_dev: looking at /sys/class/video4linux/video0 Nov 15 16:51:53 pim udev[16193]: get_class_dev: class_dev->name = video0 Nov 15 16:51:53 pim udev[16193]: get_major_minor: dev = 81:0 Nov 15 16:51:53 pim udev[16193]: get_major_minor: found major = 81, minor = 0 Nov 15 16:51:53 pim udev[16193]: udev_add_device: name = webcam0-81:0-test Nov 15 16:51:53 pim udev[16193]: create_node: mknod(/udev/webcam0-81:0-test, 020666, 81, 0) implement printf-like placeholder support for NAME %n-kernel number, %M-major number, %m-minor number --- namedev.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/namedev.c b/namedev.c index d76d03b490..f6be43ef51 100644 --- a/namedev.c +++ b/namedev.c @@ -817,6 +817,37 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) strcpy(udev->name, class_dev->name); done: + /* substitute placeholder in NAME */ + while (1) { + pos = strchr(udev->name, '%'); + if (pos) { + strcpy(name, pos+2); + *pos = 0x00; + switch (pos[1]) { + case 'n': + dig = class_dev->name + strlen(class_dev->name); + while (isdigit(*(dig-1))) + dig--; + strcat(udev->name, dig); + dbg_parse("kernel number appended: %s", dig); + break; + case 'm': + sprintf(pos, "%u", udev->minor); + dbg_parse("minor number appended: %u", udev->minor); + break; + case 'M': + sprintf(pos, "%u", udev->major); + dbg_parse("major number appended: %u", udev->major); + break; + default: + dbg_parse("unknown substitution type: %%%c", pos[1]); + break; + } + strcat(udev->name, name); + } else + break; + } + /* mode was never set above */ if (!udev->mode) { udev->mode = get_default_mode(class_dev); From 7408a7fbb5885033d266b4b31c3abeb695820da3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 01:07:21 -0800 Subject: [PATCH 0157/4284] [PATCH] fix up printf-like functionality due to previous changes. --- namedev.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/namedev.c b/namedev.c index f6be43ef51..6444dd0feb 100644 --- a/namedev.c +++ b/namedev.c @@ -601,10 +601,6 @@ label_found: continue; strcpy(udev->name, dev->name); - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - temp = &class_dev->path[strlen(class_dev->path)-1]; - strcat(udev->name, temp); - } if (dev->mode != 0) { udev->mode = dev->mode; strcpy(udev->owner, dev->owner); @@ -819,7 +815,9 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) done: /* substitute placeholder in NAME */ while (1) { - pos = strchr(udev->name, '%'); + char *pos = strchr(udev->name, '%'); + char *dig; + char name[NAME_SIZE]; if (pos) { strcpy(name, pos+2); *pos = 0x00; From f54b927e8b926e23d1c9b811a1f4d17552c43389 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 01:07:49 -0800 Subject: [PATCH 0158/4284] [PATCH] add printf option to label test to verify it works. --- test/label_test.config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/label_test.config b/test/label_test.config index b317537bb6..a6d1c1cb3e 100644 --- a/test/label_test.config +++ b/test/label_test.config @@ -1,3 +1,3 @@ # LABEL test -LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk" +LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n" From e366a459613ce9ff5c5155e93f3f09827dbb3815 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 01:09:58 -0800 Subject: [PATCH 0159/4284] [PATCH] add demo config file. --- udev.config.demo | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 udev.config.demo diff --git a/udev.config.demo b/udev.config.demo new file mode 100644 index 0000000000..5cbde13ef4 --- /dev/null +++ b/udev.config.demo @@ -0,0 +1,9 @@ +# USB camera from Fuji to be named "camera" +LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera" + +# USB device plugged into the fourth port of the second hub to be called gps_device +TOPOLOGY, BUS="usb", place="2.4", NAME="gps_device" + +# ttyUSB1 should always be called visor +REPLACE, KERNEL="ttyUSB1", NAME="visor" + From 85f3a7c3e0fbda61dde22d89a0dd74b49cc58d07 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 01:12:31 -0800 Subject: [PATCH 0160/4284] [PATCH] add some documentation of the modifiers to the default config file. --- udev.config | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/udev.config b/udev.config index a0c6f9d1e8..324c11e55f 100644 --- a/udev.config +++ b/udev.config @@ -1,5 +1,13 @@ +# There are a number of modifiers that are allowed to be used in the NAME field. +# They provide the following subsitutions: +# %n - the "kernel number" of the device. +# for example, 'sda3' has a "kernel number" of '3' +# %M - the kernel major number for the device +# %m - the kernel minor number for the device +# + # My usb camera... -LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera" +LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera%n" # USB Epson printer to be called lp_epson LABEL, BUS="usb", serial="HXOLL0012202323480", NAME="lp_epson" From fb2e1c4d6a03ee17978f4802572d1283885e3976 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 01:15:11 -0800 Subject: [PATCH 0161/4284] [PATCH] updated demo config file. --- udev.config.demo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.config.demo b/udev.config.demo index 5cbde13ef4..6426ce2090 100644 --- a/udev.config.demo +++ b/udev.config.demo @@ -1,5 +1,5 @@ # USB camera from Fuji to be named "camera" -LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera" +LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera%n" # USB device plugged into the fourth port of the second hub to be called gps_device TOPOLOGY, BUS="usb", place="2.4", NAME="gps_device" From 5e6e29fd355c037c73e00fa1be4043dcf441c537 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 01:22:02 -0800 Subject: [PATCH 0162/4284] [PATCH] change debug level on printf values for now. --- namedev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/namedev.c b/namedev.c index 6444dd0feb..dc56432e67 100644 --- a/namedev.c +++ b/namedev.c @@ -827,18 +827,18 @@ done: while (isdigit(*(dig-1))) dig--; strcat(udev->name, dig); - dbg_parse("kernel number appended: %s", dig); + dbg("kernel number appended: %s", dig); break; case 'm': sprintf(pos, "%u", udev->minor); - dbg_parse("minor number appended: %u", udev->minor); + dbg("minor number appended: %u", udev->minor); break; case 'M': sprintf(pos, "%u", udev->major); - dbg_parse("major number appended: %u", udev->major); + dbg("major number appended: %u", udev->major); break; default: - dbg_parse("unknown substitution type: %%%c", pos[1]); + dbg("unknown substitution type: %%%c", pos[1]); break; } strcat(udev->name, name); From 54e3a5d3ae475fadcac950d28bf69b8359212b9e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 21:35:44 -0800 Subject: [PATCH 0163/4284] [PATCH] change release target in makefile. --- Makefile | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 01536f6986..f39fe22461 100644 --- a/Makefile +++ b/Makefile @@ -178,7 +178,19 @@ clean: DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . -release: $(DISTFILES) clean +release: clean + @echo "--------------------------cut here------------------------" + @echo "cd .." + @echo "rm -rf $(DISTDIR)" + @echo "mkdir $(DISTDIR)" + @echo "chmod 777 $(DISTDIR)" + @echo "cp -avr udev/* $(DISTDIR)" + @echo "tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz" + @echo "rm -rf $(DISTDIR)" + @echo "--------------------------cut here------------------------" + + +small_release: $(DISTFILES) clean # @echo $(DISTFILES) @-rm -rf $(DISTDIR) @mkdir $(DISTDIR) From ae2859df40ef80d15dff39fadd470a8541bab857 Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Tue, 18 Nov 2003 21:36:10 -0800 Subject: [PATCH 0164/4284] [PATCH] add bus id modifier On Tuesday 18 November 2003 02:14, Greg KH wrote: > On Mon, Nov 17, 2003 at 06:33:32PM +0100, Arnd Bergmann wrote: > > That would at least be part of the solution I'm looking for. How about > > extra format characters for bus_id and for the result of a callout > > program? > > Sure, I can see the use for that. Want to send a patch? :) > Take a look at the current bk tree (which has moved to > bk://linuxusb.bkbits.net/udev/ ) I've made finding that device a lot > easier now, and it works for all rule types. Great, just what I was missing. I didn't see the any link to the bk repository. Here's the patch for the bus_id. I'll need to think about the handling of callout results a bit more. --- namedev.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/namedev.c b/namedev.c index dc56432e67..5970ef0590 100644 --- a/namedev.c +++ b/namedev.c @@ -822,6 +822,13 @@ done: strcpy(name, pos+2); *pos = 0x00; switch (pos[1]) { + case 'b': + if (!sysfs_device) + break; + strcat(udev->name, sysfs_device->bus_id); + dbg("bus_id appended: %s", + sysfs_device->bus_id); + break; case 'n': dig = class_dev->name + strlen(class_dev->name); while (isdigit(*(dig-1))) From 70033702cda3b13150426cd176a31713d48394d9 Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Tue, 18 Nov 2003 21:39:30 -0800 Subject: [PATCH 0165/4284] [PATCH] more robust config file parsing in namedev.c After getting a number of different crashes for udev reading broken udev.config files, I decided to try to make the parser a little more robust. The behaviour is changed to stop reading the configuration file and logging the broken entry instead of silently ignoring it (is that good? It's easy to just print and continue). All strcpy()'s to a fixed length string are now implicitly limited to the bounds of the target string. I kept the -ENODEV return code for now, not sure if there should be different ones. --- namedev.c | 159 +++++++++++++++++++++++++++--------------------------- udev.h | 6 +++ 2 files changed, 86 insertions(+), 79 deletions(-) diff --git a/namedev.c b/namedev.c index 5970ef0590..a9d66bcad7 100644 --- a/namedev.c +++ b/namedev.c @@ -144,37 +144,15 @@ static void dump_dev_list(void) dump_dev(dev); } } - -static int get_value(const char *left, char **orig_string, char **ret_string) -{ - char *temp; - char *string = *orig_string; - - /* eat any whitespace */ - while (isspace(*string)) - ++string; - - /* split based on '=' */ - temp = strsep(&string, "="); - if (strcasecmp(temp, left) == 0) { - /* got it, now strip off the '"' */ - while (isspace(*string)) - ++string; - if (*string == '"') - ++string; - temp = strsep(&string, "\""); - *ret_string = temp; - *orig_string = string; - return 0; - } - return -ENODEV; -} static int get_pair(char **orig_string, char **left, char **right) { char *temp; char *string = *orig_string; + if (!string) + return -ENODEV; + /* eat any whitespace */ while (isspace(*string)) ++string; @@ -182,22 +160,43 @@ static int get_pair(char **orig_string, char **left, char **right) /* split based on '=' */ temp = strsep(&string, "="); *left = temp; + if (!string) + return -ENODEV; /* take the right side and strip off the '"' */ while (isspace(*string)) ++string; if (*string == '"') ++string; + else + return -ENODEV; + temp = strsep(&string, "\""); + if (!string || *temp == '\0') + return -ENODEV; *right = temp; *orig_string = string; return 0; } +static int get_value(const char *left, char **orig_string, char **ret_string) +{ + int retval; + char *left_string; + + retval = get_pair(orig_string, &left_string, ret_string); + if (retval) + return retval; + if (strcasecmp(left_string, left) != 0) + return -ENODEV; + return 0; +} + static int namedev_init_config(void) { char line[255]; + int lineno; char *temp; char *temp2; char *temp3; @@ -213,11 +212,13 @@ static int namedev_init_config(void) } /* loop through the whole file */ + lineno = 0; while (1) { /* get a line */ temp = fgets(line, sizeof(line), fd); if (temp == NULL) - break; + goto exit; + lineno++; dbg_parse("read %s", temp); @@ -244,23 +245,23 @@ static int namedev_init_config(void) /* BUS="bus" */ retval = get_value("BUS", &temp, &temp3); if (retval) - continue; - strcpy(dev.bus, temp3); + break; + strfieldcpy(dev.bus, temp3); /* file="value" */ temp2 = strsep(&temp, ","); retval = get_pair(&temp, &temp2, &temp3); if (retval) - continue; - strcpy(dev.sysfs_file, temp2); - strcpy(dev.sysfs_value, temp3); + break; + strfieldcpy(dev.sysfs_file, temp2); + strfieldcpy(dev.sysfs_value, temp3); /* NAME="new_name" */ temp2 = strsep(&temp, ","); retval = get_value("NAME", &temp, &temp3); if (retval) - continue; - strcpy(dev.name, temp3); + break; + strfieldcpy(dev.name, temp3); dbg_parse("LABEL name = '%s', bus = '%s', " "sysfs_file = '%s', sysfs_value = '%s'", @@ -275,22 +276,22 @@ static int namedev_init_config(void) /* BUS="bus" */ retval = get_value("BUS", &temp, &temp3); if (retval) - continue; - strcpy(dev.bus, temp3); + break; + strfieldcpy(dev.bus, temp3); /* ID="id" */ temp2 = strsep(&temp, ","); retval = get_value("id", &temp, &temp3); if (retval) - continue; - strcpy(dev.id, temp3); + break; + strfieldcpy(dev.id, temp3); /* NAME="new_name" */ temp2 = strsep(&temp, ","); retval = get_value("NAME", &temp, &temp3); if (retval) - continue; - strcpy(dev.name, temp3); + break; + strfieldcpy(dev.name, temp3); dbg_parse("NUMBER name = '%s', bus = '%s', id = '%s'", dev.name, dev.bus, dev.id); @@ -303,22 +304,22 @@ static int namedev_init_config(void) /* BUS="bus" */ retval = get_value("BUS", &temp, &temp3); if (retval) - continue; - strcpy(dev.bus, temp3); + break; + strfieldcpy(dev.bus, temp3); /* PLACE="place" */ temp2 = strsep(&temp, ","); retval = get_value("place", &temp, &temp3); if (retval) - continue; - strcpy(dev.place, temp3); + break; + strfieldcpy(dev.place, temp3); /* NAME="new_name" */ temp2 = strsep(&temp, ","); retval = get_value("NAME", &temp, &temp3); if (retval) - continue; - strcpy(dev.name, temp3); + break; + strfieldcpy(dev.name, temp3); dbg_parse("TOPOLOGY name = '%s', bus = '%s', place = '%s'", dev.name, dev.bus, dev.place); @@ -331,15 +332,15 @@ static int namedev_init_config(void) /* KERNEL="kernel_name" */ retval = get_value("KERNEL", &temp, &temp3); if (retval) - continue; - strcpy(dev.kernel_name, temp3); + break; + strfieldcpy(dev.kernel_name, temp3); /* NAME="new_name" */ temp2 = strsep(&temp, ","); retval = get_value("NAME", &temp, &temp3); if (retval) - continue; - strcpy(dev.name, temp3); + break; + strfieldcpy(dev.name, temp3); dbg_parse("REPLACE name = %s, kernel_name = %s", dev.name, dev.kernel_name); } @@ -350,29 +351,29 @@ static int namedev_init_config(void) /* PROGRAM="executable" */ retval = get_value("PROGRAM", &temp, &temp3); if (retval) - continue; - strcpy(dev.exec_program, temp3); + break; + strfieldcpy(dev.exec_program, temp3); /* BUS="bus" */ temp2 = strsep(&temp, ","); retval = get_value("BUS", &temp, &temp3); if (retval) - continue; - strcpy(dev.bus, temp3); + break; + strfieldcpy(dev.bus, temp3); /* ID="id" */ temp2 = strsep(&temp, ","); retval = get_value("ID", &temp, &temp3); if (retval) - continue; - strcpy(dev.id, temp3); + break; + strfieldcpy(dev.id, temp3); /* NAME="new_name" */ temp2 = strsep(&temp, ","); retval = get_value("NAME", &temp, &temp3); if (retval) - continue; - strcpy(dev.name, temp3); + break; + strfieldcpy(dev.name, temp3); dbg_parse("CALLOUT name = %s, program = %s", dev.name, dev.exec_program); } @@ -383,7 +384,8 @@ static int namedev_init_config(void) goto exit; } } - + dbg_parse("%s:%d:%Zd: error parsing ``%s''", udev_config_filename, + lineno, temp - line, temp); exit: fclose(fd); return retval; @@ -552,11 +554,11 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev continue; if (strncmp(value, dev->id, sizeof(value)) != 0) continue; - strcpy(udev->name, dev->name); + strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); + strfieldcpy(udev->owner, dev->owner); + strfieldcpy(udev->group, dev->group); } dbg_parse("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->id, udev->name, @@ -571,7 +573,6 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_attribute *tmpattr = NULL; struct config_device *dev; struct list_head *tmp; - char *temp = NULL; list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); @@ -600,11 +601,11 @@ label_found: if (strcmp(dev->sysfs_value, tmpattr->value) != 0) continue; - strcpy(udev->name, dev->name); + strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); + strfieldcpy(udev->owner, dev->owner); + strfieldcpy(udev->group, dev->group); } dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->sysfs_file, dev->sysfs_value, udev->name, @@ -633,7 +634,7 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, continue; found = 0; - strcpy(path, sysfs_device->path); + strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg_parse("NUMBER path = '%s'", path); dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); @@ -648,11 +649,11 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, } if (!found) continue; - strcpy(udev->name, dev->name); + strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); + strfieldcpy(udev->owner, dev->owner); + strfieldcpy(udev->group, dev->group); } dbg_parse("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->id, udev->name, @@ -681,7 +682,7 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude continue; found = 0; - strcpy(path, sysfs_device->path); + strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg_parse("TOPOLOGY path = '%s'", path); dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); @@ -697,11 +698,11 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude if (!found) continue; - strcpy(udev->name, dev->name); + strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); + strfieldcpy(udev->owner, dev->owner); + strfieldcpy(udev->group, dev->group); } dbg_parse("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->place, udev->name, @@ -727,11 +728,11 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev if (strcmp(dev->kernel_name, class_dev->name) != 0) continue; - strcpy(udev->name, dev->name); + strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { udev->mode = dev->mode; - strcpy(udev->owner, dev->owner); - strcpy(udev->group, dev->group); + strfieldcpy(udev->owner, dev->owner); + strfieldcpy(udev->group, dev->group); } dbg_parse("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", dev->kernel_name, udev->name, @@ -766,7 +767,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) char path[SYSFS_PATH_MAX]; dbg_parse("really is a partition..."); - strcpy(path, class_dev->path); + strfieldcpy(path, class_dev->path); temp = strrchr(path, '/'); *temp = 0x00; dbg_parse("looking for a class device at '%s'", path); @@ -810,7 +811,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (retval == 0) goto done; - strcpy(udev->name, class_dev->name); + strfieldcpy(udev->name, class_dev->name); done: /* substitute placeholder in NAME */ @@ -819,7 +820,7 @@ done: char *dig; char name[NAME_SIZE]; if (pos) { - strcpy(name, pos+2); + strfieldcpy(name, pos+2); *pos = 0x00; switch (pos[1]) { case 'b': diff --git a/udev.h b/udev.h index cdf1af4fc2..904948d67a 100644 --- a/udev.h +++ b/udev.h @@ -70,6 +70,12 @@ struct udevice { mode_t mode; }; +#define strfieldcpy(to, from) \ +do { \ + to[sizeof(to)-1] = '\0'; \ + strncpy(to, from, sizeof(to)-1); \ +} while (0) + extern int udev_add_device(char *path, char *subsystem); extern int udev_remove_device(char *path, char *subsystem); From baa936855ece1b8ce0343c7c38b7d12b0a34455c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 21:45:46 -0800 Subject: [PATCH 0166/4284] [PATCH] fix make install rule for when the udev symlink is already there. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index f39fe22461..cd539eeb74 100644 --- a/Makefile +++ b/Makefile @@ -215,6 +215,7 @@ install: all $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) udev.config $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) + - rm $(DESTDIR)$(hotplugdir)/udev.hotplug - ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug uninstall: From c34c7c5018a4023d39f6ea4c778218e0d3e0f035 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 18 Nov 2003 22:48:46 -0800 Subject: [PATCH 0167/4284] [PATCH] add some documentation for the %b modifier to the default config file. --- udev.config | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udev.config b/udev.config index 324c11e55f..8d77099ca8 100644 --- a/udev.config +++ b/udev.config @@ -4,6 +4,7 @@ # for example, 'sda3' has a "kernel number" of '3' # %M - the kernel major number for the device # %m - the kernel minor number for the device +# %b - the bus id for the device # # My usb camera... @@ -30,5 +31,5 @@ TOPOLOGY, BUS="usb", place="2.4", NAME="mouse2" # ttyUSB1 should always be called visor REPLACE, KERNEL="ttyUSB1", NAME="visor" -#REPLACE, KERNEL="ttyUSB0", NAME="pl2303" +REPLACE, KERNEL="ttyUSB0", NAME="pl2303" From a43180955a49a6838f7ce564db3cc1d10f36b8fb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 00:27:38 -0800 Subject: [PATCH 0168/4284] [PATCH] turn DEBUG_PARSER off by default. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index a9d66bcad7..ccc675064d 100644 --- a/namedev.c +++ b/namedev.c @@ -22,7 +22,7 @@ */ /* define this to enable parsing debugging */ -#define DEBUG_PARSER +/* #define DEBUG_PARSER */ #include #include From 1ac5204774c4080d16f308ac3077db0dae8d221c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 00:39:43 -0800 Subject: [PATCH 0169/4284] [PATCH] add remove actions to the test scripts --- test/label_test | 13 +++++++++++++ test/replace_test | 7 +++++++ test/topo_test | 12 ++++++++++++ test/topo_test.config | 2 +- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/test/label_test b/test/label_test index faa516fdce..0bf89226cb 100644 --- a/test/label_test +++ b/test/label_test @@ -12,9 +12,22 @@ export ACTION=add export DEVPATH=block/sda ../udev block +ls udev export DEVPATH=block/sda/sda3 ../udev block +ls udev + +export ACTION=remove +export DEVPATH=block/sda + +../udev block +ls udev + +export DEVPATH=block/sda/sda3 + +../udev block +ls udev diff --git a/test/replace_test b/test/replace_test index 3aa8d5a8c9..0caa4dfb3d 100644 --- a/test/replace_test +++ b/test/replace_test @@ -12,3 +12,10 @@ export DEVPATH=class/tty/ttyUSB0 export ACTION=add ../udev tty +ls udev + +export ACTION=remove +../udev tty +ls udev + + diff --git a/test/topo_test b/test/topo_test index 5a557e909d..2a19c8b5f8 100644 --- a/test/topo_test +++ b/test/topo_test @@ -12,9 +12,21 @@ export ACTION=add export DEVPATH=block/sda ../udev block +ls udev export DEVPATH=block/sda/sda3 ../udev block +ls udev +export ACTION=remove +export DEVPATH=block/sda + +../udev block +ls udev + +export DEVPATH=block/sda/sda3 + +../udev block +ls udev diff --git a/test/topo_test.config b/test/topo_test.config index d7ae92b080..72f03ee0b2 100644 --- a/test/topo_test.config +++ b/test/topo_test.config @@ -1,3 +1,3 @@ # TOPO test -TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="first_disk" +TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="first_disk%n" From 17f73597fe88d60da3d105907dc45f753be42912 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 00:40:39 -0800 Subject: [PATCH 0170/4284] [PATCH] move the test.block and test.tty scripts to the test/ directory --- test.block => test/test.block | 0 test.tty => test/test.tty | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename test.block => test/test.block (100%) rename test.tty => test/test.tty (100%) diff --git a/test.block b/test/test.block similarity index 100% rename from test.block rename to test/test.block diff --git a/test.tty b/test/test.tty similarity index 100% rename from test.tty rename to test/test.tty From 8e5d5925254ea60ce487ba8660d99c7a50481ea6 Mon Sep 17 00:00:00 2001 From: "chris_friesen@sympatico.ca" Date: Wed, 19 Nov 2003 02:39:39 -0800 Subject: [PATCH 0171/4284] [PATCH] faster test scripts I've attached a patch against 005 for both the block and tty scripts. I didn't bother running udev backgrounded, since as you say, the new code runs a lot faster. --- test/test.block | 5 ++--- test/test.tty | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/test/test.block b/test/test.block index 622a66037f..b806a42aac 100644 --- a/test/test.block +++ b/test/test.block @@ -16,14 +16,13 @@ export ACTION=$1 # 'add' or 'remove' for i in ${SYSFSDIR}/block/*; do # add each drive - export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` + export DEVPATH=${i#${SYSFSDIR}} $BIN block # add each partition, on each device for j in $i/*; do if [ -f $j/dev ]; then - export DEVPATH="/"`echo $j | \ - cut --delimiter='/' --fields=3-` + export DEVPATH=${j#${SYSFSDIR}} $BIN block fi done diff --git a/test/test.tty b/test/test.tty index d5e2d6715d..42f46a2e7c 100644 --- a/test/test.tty +++ b/test/test.tty @@ -15,6 +15,6 @@ BIN=./udev # location of your udev binary export ACTION=$1 # 'add' or 'remove' for i in ${SYSFSDIR}/class/tty/*; do - export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` + export DEVPATH=${i#${SYSFSDIR}} $BIN tty done From cd55637f42c5be117b0495746625e095059f4b5a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 02:48:57 -0800 Subject: [PATCH 0172/4284] [PATCH] update the TODO list with more items that people can easily do. --- TODO | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/TODO b/TODO index 927f964a0b..4f5db9a982 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,12 @@ greg k-h greg@kroah.com +- add modifiers and more documentation about the config file to the man + page. +- add ability to capture CALLOUT result and use it in a device name. +- fix kernel name logic to handle devices like sdaj and such. +- make real test harness and have the tests be automated (instead of + relying on me knowing what the proper files should be created.) - more documentation (can never have too much.) - document the config file format (it will change over time...) - add symlink generation and removal support From db7a38df63130fedcb937961886eff1c93c98139 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 02:49:29 -0800 Subject: [PATCH 0173/4284] [PATCH] add dumb test for all of the different modifiers. --- test/modifier_test | 32 ++++++++++++++++++++++++++++++++ test/modifier_test.config | 3 +++ 2 files changed, 35 insertions(+) create mode 100644 test/modifier_test create mode 100644 test/modifier_test.config diff --git a/test/modifier_test b/test/modifier_test new file mode 100644 index 0000000000..3dcd4454fc --- /dev/null +++ b/test/modifier_test @@ -0,0 +1,32 @@ +#!/bin/bash + +export UDEV_TEST=yes +export SYSFS_PATH=$PWD/sys/ +export UDEV_CONFIG_DIR=$PWD/ +export UDEV_ROOT=$PWD/udev/ +export UDEV_DB=udev.tdb +export UDEV_CONFIG_FILE=modifier_test.config +export UDEV_PERMISSION_FILE=udev.permissions + +export ACTION=add +export DEVPATH=block/sda + +../udev block +ls udev + +export DEVPATH=block/sda/sda3 + +../udev block +ls udev + +export ACTION=remove +export DEVPATH=block/sda + +../udev block +ls udev + +export DEVPATH=block/sda/sda3 + +../udev block +ls udev + diff --git a/test/modifier_test.config b/test/modifier_test.config new file mode 100644 index 0000000000..f63e02c3ac --- /dev/null +++ b/test/modifier_test.config @@ -0,0 +1,3 @@ +# TOPO test +TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" + From 4b710f033e86c72dbcae345564257f3ecce9941b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 19 Nov 2003 06:18:54 -0800 Subject: [PATCH 0174/4284] [PATCH] man page with included placeholder list mention the printf-like support for string substitution in the NAME field --- udev.8 | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/udev.8 b/udev.8 index 79b74bf659..0dacde0f5c 100644 --- a/udev.8 +++ b/udev.8 @@ -72,6 +72,23 @@ calling external program, that returns a string to match .br keys: \fBBUS\fP, \fBPROGRAM\fP, \fBID\fP .P +The name field supports simple printf-like string subtitution: +.RS +.TP +.B %n +the "kernel number" of the device +for example, 'sda3' has a "kernel number" of '3' +.TP +.B %M +the kernel major number for the device +.TP +.B %m +the kernel minor number for the device +.TP +.B %b +the bus id for the device +.RE +.P A sample \fIudev.conf\fP might look like this: .sp .nf @@ -89,6 +106,9 @@ REPLACE, KERNEL="ttyUSB1", NAME="pda" # if /sbin/scsi_id returns "OEM 0815" device will be called disk1 CALLOUT, PROGRAM="/sbin/scsi_id" BUS="scsi", ID="OEM 0815" NAME="disk1" + +# USB webcams to be called webcam0, webcam1, ... +LABEL, BUS="usb", model="WebCam Version 3", NAME="webcam%n" .fi .P Permissions and ownership for the created device files may specified at From 09e52d51264080fab7062a1b4a405e526f299bc7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 19 Nov 2003 06:19:06 -0800 Subject: [PATCH 0175/4284] [PATCH] apply permissions.conf support for wildcard and default name Permissions given in udev.permissions are not applied if no METHOD from udev.config is found. I've added do_kernelname() to scan for known permissions if we only use the default method. Simple support for wildcards is also added: #name:user:group:mode hdb*:2702:2702:0660 results in: drwxr-xr-x 2 root root 240 Nov 19 03:45 . drwxr-xr-x 23 root root 528 Nov 17 03:36 .. brw-r--r-- 1 root root 3, 0 Nov 19 03:45 hda brw-r--r-- 1 root root 3, 1 Nov 19 03:45 hda1 brw-r--r-- 1 root root 3, 2 Nov 19 03:45 hda2 brw-r--r-- 1 root root 3, 4 Nov 19 03:45 hda4 brw-r----- 1 kay kay 3, 64 Nov 19 03:45 hdb brw-r----- 1 kay kay 3, 65 Nov 19 03:45 hdb1 brw-r--r-- 1 root root 22, 0 Nov 19 03:45 hdc crw-r--r-- 1 root root 81, 0 Nov 19 03:34 webcam0 --- namedev.c | 78 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/namedev.c b/namedev.c index ccc675064d..223fd6de1d 100644 --- a/namedev.c +++ b/namedev.c @@ -105,24 +105,30 @@ static int add_dev(struct config_device *new_dev) struct list_head *tmp; struct config_device *tmp_dev; - /* loop through the whole list of devices to see if we already have - * this one... */ + /* update the values if we already have the device */ list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); - if (strcmp(dev->name, new_dev->name) == 0) { - /* the same, copy the new info into this structure */ - copy_var(dev, new_dev, type); - copy_var(dev, new_dev, mode); - copy_string(dev, new_dev, bus); - copy_string(dev, new_dev, sysfs_file); - copy_string(dev, new_dev, sysfs_value); - copy_string(dev, new_dev, id); - copy_string(dev, new_dev, place); - copy_string(dev, new_dev, kernel_name); - copy_string(dev, new_dev, owner); - copy_string(dev, new_dev, group); - return 0; + int len = strlen(new_dev->name); + if (new_dev->name[len-1] == '*') { + len--; + if (strncmp(dev->name, new_dev->name, len)) + continue; + } else { + if (strcmp(dev->name, new_dev->name)) + continue; } + /* the same, copy the new info into this structure */ + copy_var(dev, new_dev, type); + copy_var(dev, new_dev, mode); + copy_string(dev, new_dev, bus); + copy_string(dev, new_dev, sysfs_file); + copy_string(dev, new_dev, sysfs_value); + copy_string(dev, new_dev, id); + copy_string(dev, new_dev, place); + copy_string(dev, new_dev, kernel_name); + copy_string(dev, new_dev, owner); + copy_string(dev, new_dev, group); + return 0; } /* not found, lets create a new structure, and add it to the list */ @@ -743,6 +749,32 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev return -ENODEV; } +static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice *udev) +{ + struct config_device *dev; + struct list_head *tmp; + + strfieldcpy(udev->name, class_dev->name); + list_for_each(tmp, &config_device_list) { + dev = list_entry(tmp, struct config_device, node); + int len = strlen(dev->name); + if (dev->name[len-1] == '*') { + len--; + if (strncmp(dev->name, class_dev->name, len)) + continue; + } else { + if (strcmp(dev->name, class_dev->name)) + continue; + } + if (dev->mode != 0) { + dbg_parse("found permissions from config for '%s'", class_dev->name); + udev->mode = dev->mode; + strfieldcpy(udev->owner, dev->owner); + strfieldcpy(udev->group, dev->group); + } + } +} + static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) { struct sysfs_device *sysfs_device = NULL; @@ -793,27 +825,28 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) /* rules are looked at in priority order */ retval = do_callout(class_dev, udev); if (retval == 0) - goto done; + goto found; retval = do_label(class_dev, udev, sysfs_device); if (retval == 0) - goto done; + goto found; retval = do_number(class_dev, udev, sysfs_device); if (retval == 0) - goto done; + goto found; retval = do_topology(class_dev, udev, sysfs_device); if (retval == 0) - goto done; + goto found; retval = do_replace(class_dev, udev); if (retval == 0) - goto done; + goto found; - strfieldcpy(udev->name, class_dev->name); + do_kernelname(class_dev, udev); + goto done; -done: +found: /* substitute placeholder in NAME */ while (1) { char *pos = strchr(udev->name, '%'); @@ -854,6 +887,7 @@ done: break; } +done: /* mode was never set above */ if (!udev->mode) { udev->mode = get_default_mode(class_dev); From a1b8786ae64c3bfeb92def5a7c11ed0aa1915358 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 06:38:18 -0800 Subject: [PATCH 0176/4284] [PATCH] fix namedev.c to build with older version of gcc. --- namedev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 223fd6de1d..9a556cb83d 100644 --- a/namedev.c +++ b/namedev.c @@ -753,11 +753,12 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice * { struct config_device *dev; struct list_head *tmp; + int len; strfieldcpy(udev->name, class_dev->name); list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); - int len = strlen(dev->name); + len = strlen(dev->name); if (dev->name[len-1] == '*') { len--; if (strncmp(dev->name, class_dev->name, len)) From 3258c8288784e94094dc491e8b280238d62b3e5c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 06:38:45 -0800 Subject: [PATCH 0177/4284] [PATCH] add real udev.permissions file to test directory. --- test/udev.permissions | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 test/udev.permissions diff --git a/test/udev.permissions b/test/udev.permissions new file mode 100644 index 0000000000..d14082ac05 --- /dev/null +++ b/test/udev.permissions @@ -0,0 +1,6 @@ +#name:user:group:mode +ttyUSB0:root:uucp:0660 +ttyUSB1:root:uucp:0666 +visor:500:500:0666 +dsp1:::0666 + From 5bd1061cd67dea7ebc5a061365335b394f37b122 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 09:23:24 -0800 Subject: [PATCH 0178/4284] [PATCH] fix permissions to work properly now. Forgot about umask in mknod... --- udev-add.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/udev-add.c b/udev-add.c index 6f0e3bf105..7ba873a8d4 100644 --- a/udev-add.c +++ b/udev-add.c @@ -135,6 +135,12 @@ static int create_node(struct udevice *dev) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, dev->mode, dev->major, dev->minor, strerror(errno)); + dbg("chmod(%s, %#o)", filename, dev->mode); + retval = chmod(filename, dev->mode); + if (retval) + dbg("chmod(%s, %#o) failed with error '%s'", + filename, dev->mode, strerror(errno)); + if (*dev->owner) { char *endptr; unsigned long id = strtoul(dev->owner, &endptr, 10); From d6d413dab79ed03e0531f90fb42a85baacd6e9b5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 09:24:56 -0800 Subject: [PATCH 0179/4284] [PATCH] tweak replace_test --- test/replace_test | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/replace_test b/test/replace_test index 0caa4dfb3d..c8e54f8f8d 100644 --- a/test/replace_test +++ b/test/replace_test @@ -12,10 +12,10 @@ export DEVPATH=class/tty/ttyUSB0 export ACTION=add ../udev tty -ls udev +ls -l udev export ACTION=remove ../udev tty -ls udev +ls -l udev From 4d595658c7fb5402e48c1fafc8926c600c330585 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 09:25:19 -0800 Subject: [PATCH 0180/4284] [PATCH] add another line to udev.permissions in the proper format. --- udev.permissions | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.permissions b/udev.permissions index 66d8af1f7a..7de9bc16e4 100644 --- a/udev.permissions +++ b/udev.permissions @@ -1,6 +1,7 @@ #name:user:group:mode ttyUSB0:root:uucp:0660 ttyUSB1:root:uucp:0666 +pl2303:500:500:0666 visor:root:uucp:0666 dsp1:::0666 From b981d07a19fdd9fc382a42bda98f19b857f8a36f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 09:34:53 -0800 Subject: [PATCH 0181/4284] [PATCH] v006 changelog --- ChangeLog | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/ChangeLog b/ChangeLog index b8fdf91c23..c1cf43bdc7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,78 @@ +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 ============================================ @@ -184,3 +259,4 @@ Greg Kroah-Hartman: o fixed up config o Initial repository create o BitKeeper file /home/greg/src/udev/udev/ChangeSet + From 378fe59875327bc4f51e38724ab7406edd36aa16 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Nov 2003 09:35:52 -0800 Subject: [PATCH 0182/4284] [PATCH] v006 --- Makefile | 2 +- Makefile.klibc | 2 +- udev.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index cd539eeb74..91ad58bc3b 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 005_bk +VERSION = 006 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/Makefile.klibc b/Makefile.klibc index df1e55b436..faf6521045 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 005_bk +VERSION = 006 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index c6ebefc998..f342fbb1a8 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 005_bk +Version: 006 Release: 1 License: GPL Group: Utilities/System From 95d3e90130681bd4a35f79bf0591b08390bea6bb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 20 Nov 2003 18:35:01 -0800 Subject: [PATCH 0183/4284] [PATCH] change to 006_bk version --- Makefile | 2 +- Makefile.klibc | 2 +- udev.spec | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 91ad58bc3b..fa29c8859b 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 006 +VERSION = 006_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/Makefile.klibc b/Makefile.klibc index faf6521045..e0961df718 100644 --- a/Makefile.klibc +++ b/Makefile.klibc @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 006 +VERSION = 006_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index f342fbb1a8..4da7e8808f 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 006 +Version: 006_bk Release: 1 License: GPL Group: Utilities/System From d0a4a110b719faafb07aa6e7a2bd5a131e8af38f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 20 Nov 2003 18:36:55 -0800 Subject: [PATCH 0184/4284] [PATCH] man page with udev.permissions wildcard here is the permissions wildcard text for the man page. --- udev.8 | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/udev.8 b/udev.8 index 0dacde0f5c..e46caaf322 100644 --- a/udev.8 +++ b/udev.8 @@ -116,13 +116,16 @@ Permissions and ownership for the created device files may specified at The file consists of a set of lines. All empty lines and lines beginning with a '#' will be ignored. .br -Every line lists a device name followed by owner, group and permission mode. All values are separated by colons. +Every line lists a device name followed by numeric owner, group and permission +mode. All values are separated by colons. The name field may end with a +wildcard to apply the values to a whole class of devices. .sp A sample \fIudev.permissions\fP might look like this: .sp .nf #name:user:group:mode -ttyUSB1:root:uucp:0666 +ttyUSB1:0:8:0660 +video*:500:500:0660 dsp1:::0666 .fi From 8f43a65e4f0b545d705cc4cf9f31fa336b0cf8f3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 20 Nov 2003 18:37:01 -0800 Subject: [PATCH 0185/4284] [PATCH] namedev.c whitespace + debug text cleanup here is mainly a whitespace cleanup for namedev.c. I changed the dbg_parse() output a bit for better readability: current: Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1.1' Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER temp='/2-1.1' id='00:07.1' Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER temp='/2-1' id='00:07.1' Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1.1' Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER temp='/2-1.1' id='00:0b.0' Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER temp='/2-1' id='00:0b.0' Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1.1' Nov 19 19:00:59 pim udev[25582]: do_number: NUMBER temp='/2-1.1' id='2-1.1' Nov 19 19:00:59 pim udev[25582]: do_number: device id '2-1.1' becomes 'webcam%n' - owner='', group ='', mode=0 becomes: Nov 19 19:23:40 pim udev[26091]: do_number: search '00:07.1' in '/2-1.1', path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1.1' Nov 19 19:23:40 pim udev[26091]: do_number: search '00:07.1' in '/2-1', path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1' Nov 19 19:23:40 pim udev[26091]: do_number: search '00:0b.0' in '/2-1.1', path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1.1' Nov 19 19:23:40 pim udev[26091]: do_number: search '00:0b.0' in '/2-1', path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1' Nov 19 19:23:40 pim udev[26091]: do_number: search '2-1.1' in '/2-1.1', path='/sys/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1.1' Nov 19 19:23:40 pim udev[26091]: do_number: found id '2-1.1', 'video0' becomes 'webcam%n' - owner='', group ='', mode=0 --- namedev.c | 172 ++++++++++++++++++++++++++---------------------------- 1 file changed, 84 insertions(+), 88 deletions(-) diff --git a/namedev.c b/namedev.c index 9a556cb83d..41480d50c0 100644 --- a/namedev.c +++ b/namedev.c @@ -52,43 +52,42 @@ static void dump_dev(struct config_device *dev) { switch (dev->type) { case KERNEL_NAME: - dbg_parse("KERNEL name ='%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->name, - dev->owner, dev->group, dev->mode); + dbg_parse("KERNEL name='%s' ," + "owner='%s', group='%s', mode=%#o", + dev->name, dev->owner, dev->group, dev->mode); break; case LABEL: - dbg_parse("LABEL name = '%s', bus = '%s', sysfs_file = '%s', sysfs_value = '%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, - dev->owner, dev->group, dev->mode); + dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, + dev->owner, dev->group, dev->mode); break; case NUMBER: - dbg_parse("NUMBER name = '%s', bus = '%s', id = '%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->bus, dev->id, - dev->owner, dev->group, dev->mode); + dbg_parse("NUMBER name='%s', bus='%s', id='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->bus, dev->id, + dev->owner, dev->group, dev->mode); break; case TOPOLOGY: - dbg_parse("TOPOLOGY name = '%s', bus = '%s', place = '%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->bus, dev->place, - dev->owner, dev->group, dev->mode); + dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->bus, dev->place, + dev->owner, dev->group, dev->mode); break; case REPLACE: - dbg_parse("REPLACE name = %s, kernel_name = %s" - " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->kernel_name, - dev->owner, dev->group, dev->mode); + dbg_parse("REPLACE name=%s, kernel_name=%s, " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->kernel_name, + dev->owner, dev->group, dev->mode); break; case CALLOUT: - dbg_parse("CALLOUT name = '%s', program ='%s', bus = '%s', id = '%s'" - " owner = '%s', group = '%s', mode = '%#o'", - dev->name, dev->exec_program, dev->bus, dev->id, - dev->owner, dev->group, dev->mode); + dbg_parse("CALLOUT name='%s', program='%s', bus='%s', id='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->exec_program, dev->bus, dev->id, + dev->owner, dev->group, dev->mode); break; default: - dbg_parse("Unknown type of device!"); + dbg_parse("unknown type of method"); } } @@ -131,7 +130,7 @@ static int add_dev(struct config_device *new_dev) return 0; } - /* not found, lets create a new structure, and add it to the list */ + /* not found, add new structure to the device list */ tmp_dev = malloc(sizeof(*tmp_dev)); if (!tmp_dev) return -ENOMEM; @@ -213,7 +212,7 @@ static int namedev_init_config(void) dbg("opening %s to read as config", udev_config_filename); fd = fopen(udev_config_filename, "r"); if (fd == NULL) { - dbg("Can't open %s", udev_config_filename); + dbg("can't open %s", udev_config_filename); return -ENODEV; } @@ -232,7 +231,7 @@ static int namedev_init_config(void) while (isspace(*temp)) ++temp; - /* no more line? */ + /* empty line? */ if (*temp == 0x00) continue; @@ -269,10 +268,10 @@ static int namedev_init_config(void) break; strfieldcpy(dev.name, temp3); - dbg_parse("LABEL name = '%s', bus = '%s', " - "sysfs_file = '%s', sysfs_value = '%s'", - dev.name, dev.bus, dev.sysfs_file, - dev.sysfs_value); + dbg_parse("LABEL name='%s', bus='%s', " + "sysfs_file='%s', sysfs_value='%s'", + dev.name, dev.bus, dev.sysfs_file, + dev.sysfs_value); } if (strcasecmp(temp2, TYPE_NUMBER) == 0) { @@ -299,8 +298,8 @@ static int namedev_init_config(void) break; strfieldcpy(dev.name, temp3); - dbg_parse("NUMBER name = '%s', bus = '%s', id = '%s'", - dev.name, dev.bus, dev.id); + dbg_parse("NUMBER name='%s', bus='%s', id='%s'", + dev.name, dev.bus, dev.id); } if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { @@ -327,8 +326,8 @@ static int namedev_init_config(void) break; strfieldcpy(dev.name, temp3); - dbg_parse("TOPOLOGY name = '%s', bus = '%s', place = '%s'", - dev.name, dev.bus, dev.place); + dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'", + dev.name, dev.bus, dev.place); } if (strcasecmp(temp2, TYPE_REPLACE) == 0) { @@ -347,8 +346,8 @@ static int namedev_init_config(void) if (retval) break; strfieldcpy(dev.name, temp3); - dbg_parse("REPLACE name = %s, kernel_name = %s", - dev.name, dev.kernel_name); + dbg_parse("REPLACE name='%s', kernel_name='%s'", + dev.name, dev.kernel_name); } if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { /* number type */ @@ -380,8 +379,8 @@ static int namedev_init_config(void) if (retval) break; strfieldcpy(dev.name, temp3); - dbg_parse("CALLOUT name = %s, program = %s", - dev.name, dev.exec_program); + dbg_parse("CALLOUT name='%s', program='%s'", + dev.name, dev.exec_program); } retval = add_dev(&dev); @@ -390,7 +389,7 @@ static int namedev_init_config(void) goto exit; } } - dbg_parse("%s:%d:%Zd: error parsing ``%s''", udev_config_filename, + dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, lineno, temp - line, temp); exit: fclose(fd); @@ -410,7 +409,7 @@ static int namedev_init_permissions(void) dbg("opening %s to read as permissions config", udev_config_permission_filename); fd = fopen(udev_config_permission_filename, "r"); if (fd == NULL) { - dbg("Can't open %s", udev_config_permission_filename); + dbg("can't open %s", udev_config_permission_filename); return -ENODEV; } @@ -427,7 +426,7 @@ static int namedev_init_permissions(void) while (isspace(*temp)) ++temp; - /* no more line? */ + /* empty line? */ if (*temp == 0x00) continue; @@ -449,9 +448,9 @@ static int namedev_init_permissions(void) dev.mode = strtol(temp, NULL, 8); - dbg_parse("name = %s, owner = %s, group = %s, mode = %#o", - dev.name, dev.owner, dev.group, - dev.mode); + dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", + dev.name, dev.owner, dev.group, + dev.mode); retval = add_dev(&dev); if (retval) { dbg("add_dev returned with error %d", retval); @@ -481,7 +480,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) int value_set = 0; char buffer[256]; - dbg("callout to %s\n", dev->exec_program); + dbg("callout to '%s'", dev->exec_program); retval = pipe(fds); if (retval != 0) { dbg("pipe failed"); @@ -494,9 +493,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) } if (pid == 0) { - /* - * child - */ + /* child */ close(STDOUT_FILENO); dup(fds[1]); /* dup write side of pipe to STDOUT */ retval = execve(dev->exec_program, main_argv, main_envp); @@ -506,9 +503,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) } return -1; /* avoid compiler warning */ } else { - /* - * Parent reads from fds[0]. - */ + /* parent reads from fds[0] */ close(fds[1]); retval = 0; while (1) { @@ -566,9 +561,10 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("device callout '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->id, udev->name, - dev->owner, dev->group, dev->mode); + dbg_parse("callout returned matching value '%s', '%s' becomes '%s'" + " - owner='%s', group='%s', mode =%#o", + dev->id, class_dev->name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } return -ENODEV; @@ -585,8 +581,7 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, if (dev->type != LABEL) continue; - dbg_parse("LABEL: match file '%s' with value '%s'", - dev->sysfs_file, dev->sysfs_value); + dbg_parse("look for device attribute '%s'", dev->sysfs_file); /* try to find the attribute in the class device directory */ tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); if (tmpattr) @@ -603,7 +598,8 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, label_found: tmpattr->value[strlen(tmpattr->value)-1] = 0x00; - dbg_parse("file '%s' found with value '%s' compare with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); + dbg_parse("compare attribute '%s' value '%s' with '%s'", + dev->sysfs_file, tmpattr->value, dev->sysfs_value); if (strcmp(dev->sysfs_value, tmpattr->value) != 0) continue; @@ -613,9 +609,10 @@ label_found: strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("file '%s' with value '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->sysfs_file, dev->sysfs_value, udev->name, - dev->owner, dev->group, dev->mode); + dbg_parse("found matching attribute '%s', '%s' becomes '%s' " + "- owner='%s', group='%s', mode=%#o", + dev->sysfs_file, class_dev->name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } @@ -642,14 +639,13 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); - dbg_parse("NUMBER path = '%s'", path); - dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); + dbg_parse("search '%s' in '%s', path='%s'", dev->id, temp, path); if (strstr(temp, dev->id) != NULL) { found = 1; } else { *temp = 0x00; temp = strrchr(path, '/'); - dbg_parse("NUMBER temp = '%s' id = '%s'", temp, dev->id); + dbg_parse("search '%s' in '%s', path='%s'", dev->id, temp, path); if (strstr(temp, dev->id) != NULL) found = 1; } @@ -661,9 +657,10 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("device id '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->id, udev->name, - dev->owner, dev->group, dev->mode); + dbg_parse("found matching id '%s', '%s' becomes '%s'" + " - owner='%s', group ='%s', mode=%#o", + dev->id, class_dev->name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } return -ENODEV; @@ -690,14 +687,13 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); - dbg_parse("TOPOLOGY path = '%s'", path); - dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + dbg_parse("search '%s' in '%s', path='%s'", dev->place, temp, path); if (strstr(temp, dev->place) != NULL) { found = 1; } else { *temp = 0x00; temp = strrchr(path, '/'); - dbg_parse("TOPOLOGY temp = '%s' place = '%s'", temp, dev->place); + dbg_parse("search '%s' in '%s', path='%s'", dev->place, temp, path); if (strstr(temp, dev->place) != NULL) found = 1; } @@ -710,10 +706,10 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("device at '%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->place, udev->name, - dev->owner, dev->group, dev->mode); - + dbg_parse("found matching place '%s', '%s' becomes '%s'" + " - owner='%s', group ='%s', mode=%#o", + dev->place, class_dev->name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } return -ENODEV; @@ -729,7 +725,7 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev if (dev->type != REPLACE) continue; - dbg_parse("REPLACE: replace name '%s' with '%s'", + dbg_parse("compare name '%s' with '%s'", dev->kernel_name, dev->name); if (strcmp(dev->kernel_name, class_dev->name) != 0) continue; @@ -740,9 +736,9 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("'%s' becomes '%s' - owner = %s, group = %s, mode = %#o", - dev->kernel_name, udev->name, - dev->owner, dev->group, dev->mode); + dbg_parse("found name, '%s' becomes '%s' - owner='%s', group='%s', mode = %#o", + dev->kernel_name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } @@ -768,7 +764,7 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice * continue; } if (dev->mode != 0) { - dbg_parse("found permissions from config for '%s'", class_dev->name); + dbg_parse("found permissions for '%s'", class_dev->name); udev->mode = dev->mode; strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); @@ -808,7 +804,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (class_dev_parent == NULL) { dbg("sysfs_open_class_device at '%s' failed", path); } else { - dbg_parse("class_dev_parent->name = %s", class_dev_parent->name); + dbg_parse("class_dev_parent->name=%s", class_dev_parent->name); if (class_dev_parent->sysdevice) sysfs_device = class_dev_parent->sysdevice; } @@ -817,8 +813,8 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) } if (sysfs_device) { - dbg_parse("sysfs_device->path = '%s'", sysfs_device->path); - dbg_parse("sysfs_device->bus_id = '%s'", sysfs_device->bus_id); + dbg_parse("sysfs_device->path='%s'", sysfs_device->path); + dbg_parse("sysfs_device->bus_id='%s'", sysfs_device->bus_id); } else { dbg_parse("class_dev->name = '%s'", class_dev->name); } @@ -861,7 +857,7 @@ found: if (!sysfs_device) break; strcat(udev->name, sysfs_device->bus_id); - dbg("bus_id appended: %s", + dbg("bus_id inserted: %s", sysfs_device->bus_id); break; case 'n': @@ -869,18 +865,18 @@ found: while (isdigit(*(dig-1))) dig--; strcat(udev->name, dig); - dbg("kernel number appended: %s", dig); + dbg("substitute kernel number '%s'", dig); break; case 'm': sprintf(pos, "%u", udev->minor); - dbg("minor number appended: %u", udev->minor); + dbg("substitute minor number '%u'", udev->minor); break; case 'M': sprintf(pos, "%u", udev->major); - dbg("major number appended: %u", udev->major); + dbg("substitute major number '%u'", udev->major); break; default: - dbg("unknown substitution type: %%%c", pos[1]); + dbg("unknown substitution type '%%%c'", pos[1]); break; } strcat(udev->name, name); From cb08e0f2531f910fcd46a24b2fa0eb8049165b02 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 21 Nov 2003 06:47:29 -0800 Subject: [PATCH 0186/4284] [PATCH] namedev.c - change order of fields in CALLOUT I want to bring the CALLOUT field ordering in line with the other methods, cause the current parsing relies on the ordering it's good to have it like the others. The BUS= is now the first expected field. Also made the last two remaining field names to uppercase and the man page callout example is updated. --- namedev.c | 18 +++++++++--------- udev.8 | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/namedev.c b/namedev.c index 41480d50c0..7c8761088f 100644 --- a/namedev.c +++ b/namedev.c @@ -286,7 +286,7 @@ static int namedev_init_config(void) /* ID="id" */ temp2 = strsep(&temp, ","); - retval = get_value("id", &temp, &temp3); + retval = get_value("ID", &temp, &temp3); if (retval) break; strfieldcpy(dev.id, temp3); @@ -314,7 +314,7 @@ static int namedev_init_config(void) /* PLACE="place" */ temp2 = strsep(&temp, ","); - retval = get_value("place", &temp, &temp3); + retval = get_value("PLACE", &temp, &temp3); if (retval) break; strfieldcpy(dev.place, temp3); @@ -353,19 +353,19 @@ static int namedev_init_config(void) /* number type */ dev.type = CALLOUT; - /* PROGRAM="executable" */ - retval = get_value("PROGRAM", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.exec_program, temp3); - /* BUS="bus" */ - temp2 = strsep(&temp, ","); retval = get_value("BUS", &temp, &temp3); if (retval) break; strfieldcpy(dev.bus, temp3); + /* PROGRAM="executable" */ + temp2 = strsep(&temp, ","); + retval = get_value("PROGRAM", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.exec_program, temp3); + /* ID="id" */ temp2 = strsep(&temp, ","); retval = get_value("ID", &temp, &temp3); diff --git a/udev.8 b/udev.8 index e46caaf322..079d15f4d1 100644 --- a/udev.8 +++ b/udev.8 @@ -105,7 +105,7 @@ TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" REPLACE, KERNEL="ttyUSB1", NAME="pda" # if /sbin/scsi_id returns "OEM 0815" device will be called disk1 -CALLOUT, PROGRAM="/sbin/scsi_id" BUS="scsi", ID="OEM 0815" NAME="disk1" +CALLOUT, BUS="scsi", PROGRAM="/sbin/scsi_id", ID="OEM 0815", NAME="disk1" # USB webcams to be called webcam0, webcam1, ... LABEL, BUS="usb", model="WebCam Version 3", NAME="webcam%n" From bc434511310a5bbbc5fe3783a9204b204ef05500 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 21 Nov 2003 06:48:01 -0800 Subject: [PATCH 0187/4284] [PATCH] support arguments in callout exec here is argument support for CALLOUT exec: CALLOUT, PROGRAM="/bin/echo -n xxx", BUS="usb", ID="xxx", NAME="webcam%n" results in: Nov 20 02:35:20 pim udev[30422]: get_major_minor: found major = 81, minor = 0 Nov 20 02:35:20 pim udev[30422]: exec_callout: callout to /bin/echo -n xxx Nov 20 02:35:20 pim udev[30422]: exec_callout: callout returned 'xxx' Nov 20 02:35:20 pim udev[30422]: get_attr: kernel number appended: 0 The feature is really nice, but the maximum argument count is hard coded to 8. --- namedev.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 7c8761088f..bed328f646 100644 --- a/namedev.c +++ b/namedev.c @@ -45,6 +45,7 @@ #define TYPE_TOPOLOGY "TOPOLOGY" #define TYPE_REPLACE "REPLACE" #define TYPE_CALLOUT "CALLOUT" +#define CALLOUT_MAXARG 8 static LIST_HEAD(config_device_list); @@ -479,6 +480,9 @@ static int exec_callout(struct config_device *dev, char *value, int len) pid_t pid; int value_set = 0; char buffer[256]; + char *arg; + char *args[CALLOUT_MAXARG]; + int i; dbg("callout to '%s'", dev->exec_program); retval = pipe(fds); @@ -496,7 +500,22 @@ static int exec_callout(struct config_device *dev, char *value, int len) /* child */ close(STDOUT_FILENO); dup(fds[1]); /* dup write side of pipe to STDOUT */ - retval = execve(dev->exec_program, main_argv, main_envp); + if (strchr(dev->exec_program, ' ')) { + /* callout with arguments */ + arg = dev->exec_program; + for (i=0; i < CALLOUT_MAXARG-1; i++) { + args[i] = strsep(&arg, " "); + if (args[i] == NULL) + break; + } + if (args[i]) { + dbg("to many args - %d", i); + args[i] = NULL; + } + retval = execve(args[0], args, main_envp); + } else { + retval = execve(dev->exec_program, main_argv, main_envp); + } if (retval != 0) { dbg("child execve failed"); exit(1); @@ -523,6 +542,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) strncpy(value, buffer, len); } } + dbg("callout returned '%s'", value); close(fds[0]); res = wait(&status); if (res < 0) { From 75d0730c84ffd6602fe903f66c31cf639890c0f6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 22 Nov 2003 18:18:53 -0800 Subject: [PATCH 0188/4284] [PATCH] added debian's version of udev.permissions. Hm, should probably move all of the config file stuff to a new directory soon... --- udev.permissions | 2 +- udev.permissions.debian | 89 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 udev.permissions.debian diff --git a/udev.permissions b/udev.permissions index 7de9bc16e4..e87b4ddc67 100644 --- a/udev.permissions +++ b/udev.permissions @@ -4,4 +4,4 @@ ttyUSB1:root:uucp:0666 pl2303:500:500:0666 visor:root:uucp:0666 dsp1:::0666 - +camera*:500:500:0666 diff --git a/udev.permissions.debian b/udev.permissions.debian new file mode 100644 index 0000000000..a5e40f89e2 --- /dev/null +++ b/udev.permissions.debian @@ -0,0 +1,89 @@ +# name:user:group:mode + +# character devices + +ttyACM*:root:dialout:0660 +ttyUSB*:root:dialout:0660 +ttyI*:root:dialout:0660 +ttyS*:root:dialout:0660 +ttySC*:root:dialout:0660 +ttyB*:root:dialout:0660 +ttyC*:root:dialout:0660 +ttyD*:root:dialout:0660 +ttyE*:root:dialout:0660 +ttyH*:root:dialout:0660 +ttyI*:root:dialout:0660 +ttyL*:root:dialout:0660 +ttyM*:root:dialout:0660 +ttyP*:root:dialout:0660 +ttyR*:root:dialout:0660 +ttyV*:root:dialout:0660 +ttyW*:root:dialout:0660 +ttyX*:root:dialout:0660 +tts/*:root:dialout:0660 +ippp*:root:dialout:0660 +isdn*:root:dialout:0660 +isdnctrl*:root:dialout:0660 +capi*:root:dialout:0660 +dcbri*:root:dialout:0660 +ircomm*:root:dialout:0660 + +admmidi*:root:audio:660 +adsp*:root:audio:660 +aload*:root:audio:660 +amidi*:root:audio:660 +amixer*:root:audio:660 +audio*:root:audio:660 +dmfm*:root:audio:660 +dsp*:root:audio:660 +audio*:root:audio:660 +mixer*:root:audio:660 +music:root:audio:660 +sequencer*:root:audio:660 +snd/*:root:audio:660 +sound/*:root:audio:660 + +lp*:root:lp:0660 +parport*:root:lp:0660 +irlpt*:root:lp:0660 +usblp*:root:lp:0660 +usb/lp*:root:lp:0660 + +js:root:root:644 +djs:root:root:644 +input/*:root:root:644 + +dri/card*:root:root:666 + +fb/*:root:video:0620 +agpgart:root:video:0660 +video*:root:video:0660 +radio*:root:video:0660 +vbi*:root:video:0660 +vtx*:root:video:0660 + +# block devices + +floppy*:root:floppy:660 +floppy/*:root:floppy:660 + +ram*:root:disk:660 +raw/*:root:disk:660 + +hd*:root:disk:660 +sd*:root:disk:660 +dasd*:root:disk:660 +ataraid*:root:disk:660 +loop*:root:disk:660 +md*:root:disk:660 + +sr*:root:cdrom:660 +scd*:root:cdrom:660 +sr*:root:cdrom:660 + +ht*:root:tape:0660 +nht*:root:tape:0660 +pt*:root:tape:0660 +npt*:root:tape:0660 +st*:root:tape:0660 +nst*:root:tape:0660 From a367f04ee0a45a9ad342e04532c73eb0cc179793 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 05:47:28 -0800 Subject: [PATCH 0189/4284] [PATCH] add udev-test perl script from Kay Sievers which blows away my puny shell scripts. --- test/udev-test.pl | 164 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 test/udev-test.pl diff --git a/test/udev-test.pl b/test/udev-test.pl new file mode 100644 index 0000000000..9a54b6192a --- /dev/null +++ b/test/udev-test.pl @@ -0,0 +1,164 @@ +#!/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 reads the config, 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. +# +# happy testing, +# Kay Sievers , 2003 + + +use warnings; +use strict; + +my $PWD = `pwd`; +chomp($PWD); + +my $sysfs = "sys/"; +my $udev_bin = "../udev"; +my $udev_root = "udev-root/"; # !!! directory will be removed !!! +my $udev_db = "udev.tdb"; +my $perm = "udev.permissions"; +my $conf_tmp = "udev-test.config"; + + +my @tests = ( + { + desc => "label test of scsi disc", + subsys => "block", + devpath => "block/sda", + expected => "boot_disk" , + conf => < "label test of scsi partition", + subsys => "block", + devpath => "block/sda/sda1", + expected => "boot_disk1" , + conf => < "replace kernel name", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor" , + conf => < "place on bus of scsi partition", + subsys => "block", + devpath => "block/sda/sda3", + expected => "first_disk3" , + conf => < "test NAME substitution chars", + subsys => "block", + devpath => "block/sda/sda3", + expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , + conf => < "callout result subtitution, only last should match", + subsys => "block", + devpath => "block/sda/sda3", + expected => "special-device-3" , + conf => <$conf_tmp" || die "unable to create config file: $conf_tmp"; + print CONF $$config; + close CONF; + + $ENV{ACTION} = $action; + system("$udev_bin $subsys"); +} + + +# prepare +system("rm -rf $udev_root"); +mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; + +# test +my $error; +print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; + +foreach my $config (@tests) { + $config->{conf} =~ m/^([A-Z]*).*/; + my $method = $1; + + print "TEST: $config->{desc}\n"; + print "method \'$method\' for \'$config->{devpath}\' expecting node \'$config->{expected}\'\n"; + + udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); + if (-e "$PWD/$udev_root$config->{expected}") { + print "add: ok "; + } else { + print "add: error\n"; + system("tree $udev_root"); + print "\n"; + $error++; +# next; + } + + udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf}); + if (-e "$PWD/$udev_root$config->{expected}") { + print "remove: error\n\n"; + system("tree $udev_root"); + $error++; + } else { + print "remove: ok\n\n"; + } +} + +print "$error errors occured\n\n"; + +# cleanup +system("rm -rf $udev_root"); +unlink($conf_tmp); +unlink($udev_db); + From ed839137305753796486b9d4570e68d04748d497 Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Sun, 23 Nov 2003 05:58:21 -0800 Subject: [PATCH 0190/4284] [PATCH] static klibc udev does not link against crt0.o On Wed, Nov 19, Greg KH wrote: > > I did 'make KLIBC=true' in the current bk tree. > > try 'make -f Makefile.klibc' in the current tree. For some reason I > couldn't figure out how to have Makefile work for both KLIBC=true and > KLIBC=false. But I didn't try too hard :) I dont understand that. please do rm -f Makefile.klibc; apply this patch and tell me what fails. works for me. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index fa29c8859b..fc5c9b1792 100644 --- a/Makefile +++ b/Makefile @@ -166,7 +166,7 @@ udev_version.h: $(ROOT): $(GEN_HEADERS) $(OBJS) - $(CC) $(LDFLAGS) -o $(ROOT) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(CC) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) clean: @@ -215,7 +215,7 @@ install: all $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) udev.config $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) - - rm $(DESTDIR)$(hotplugdir)/udev.hotplug + - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug uninstall: From 388e2a6a47296697a34f3482b9442df92169c4ac Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 05:59:07 -0800 Subject: [PATCH 0191/4284] [PATCH] remove Makefile.klibc --- Makefile.klibc | 219 ------------------------------------------------- 1 file changed, 219 deletions(-) delete mode 100644 Makefile.klibc diff --git a/Makefile.klibc b/Makefile.klibc deleted file mode 100644 index e0961df718..0000000000 --- a/Makefile.klibc +++ /dev/null @@ -1,219 +0,0 @@ -# Makefile for udev -# -# Copyright (C) 2003 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. -# -# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# - -# Set the following to `true' to make a debuggable build. -# Leave this set to `false' for production use. -DEBUG = true - - -ROOT = udev -VERSION = 006_bk -INSTALL_DIR = /usr/local/bin -RELEASE_NAME = $(ROOT)-$(VERSION) - -# override this to make udev look in a different location for it's config files -prefix = -exec_prefix = ${prefix} -etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -mandir = ${prefix}/usr/share/man -hotplugdir = ${etcdir}/hotplug.d/default -configdir = ${etcdir}/udev/ -srcdir = . - -INSTALL = /usr/bin/install -c -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_SCRIPT = ${INSTALL_PROGRAM} - - -# place to put our device nodes -udevdir = ${prefix}/udev/ - -# Comment out this line to build with something other -# than the local version of klibc -KLIBC = true - -# If you are running a cross compiler, you may want to set this -# to something more interesting, like "arm-linux-". I you want -# to compile vs uClibc, that can be done here as well. -CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- -CC = $(CROSS)gcc -AR = $(CROSS)ar -STRIP = $(CROSS)strip -RANLIB = $(CROSS)ranlib - -export CROSS CC AR STRIP RANLIB - -# code taken from uClibc to determine the current arch -ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ - -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/ppc/powerpc/g'} - -# code taken from uClibc to determine the gcc include dir -GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} - -# code taken from uClibc to determine the libgcc.a filename -GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) - -# use '-Os' optimization if available, else use -O2 -OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "-Os"; else echo "-O2" ; fi} - -# add -Wredundant-decls when libsysfs gets cleaned up -WARNINGS := -Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations - -# Some nice architecture specific optimizations -ifeq ($(strip $(TARGET_ARCH)),arm) - OPTIMIZATION+=-fstrict-aliasing -endif -ifeq ($(strip $(TARGET_ARCH)),i386) - OPTIMIZATION+=-march=i386 - OPTIMIZATION += ${shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc \ - /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi} - OPTIMIZATION += ${shell if $(CC) -malign-functions=0 -malign-jumps=0 -S -o /dev/null -xc \ - /dev/null >/dev/null 2>&1; then echo "-malign-functions=0 -malign-jumps=0"; fi} - CFLAGS+=-pipe -else - CFLAGS+=-pipe -endif - -# if DEBUG is enabled, then we do not strip or optimize -ifeq ($(strip $(DEBUG)),true) - CFLAGS += $(WARNINGS) -O1 -g -DDEBUG -D_GNU_SOURCE - LDFLAGS += -Wl,-warn-common - STRIPCMD = /bin/true -Since_we_are_debugging -else - CFLAGS += $(WARNINGS) $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE - LDFLAGS += -s -Wl,-warn-common - STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment -endif - -# If we are using our version of klibc, then we need to build and link it. -# Otherwise, use glibc and link statically. -ifeq ($(strip $(KLIBC)),true) - KLIBC_DIR = klibc/klibc - INCLUDE_DIR := $(KLIBC_DIR)/include - # arch specific objects - LIBGCC = $(shell $(CC) --print-libgcc) - ARCH_LIB_OBJS = \ - $(KLIBC_DIR)/libc.a \ - $(LIBGCC) - - - CRT0 = $(KLIBC_DIR)/crt0.o - LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) - CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I$(GCCINCDIR) -Iklibc/linux/include -D__KLIBC__ - LIB_OBJS = - LDFLAGS = --static --nostdlib -nostartfiles -else -# ARCH_LIB_OBJS = /usr/lib/libc.a - LIBGCC = $(shell $(CC) --print-libgcc) - CRT0 = /usr/lib/crt1.o /usr/lib/crti.o - LIBC = - CFLAGS += -I$(GCCINCDIR) - LIB_OBJS = -lc - LDFLAGS = --static -endif - -all: $(LIBC) $(ROOT) - -$(ARCH_LIB_OBJS) : - $(MAKE) -C klibc - -TDB = tdb/tdb.o \ - tdb/spinlock.o - -SYSFS = libsysfs/sysfs_bus.o \ - libsysfs/sysfs_class.o \ - libsysfs/sysfs_device.o \ - libsysfs/sysfs_dir.o \ - libsysfs/sysfs_driver.o \ - libsysfs/sysfs_utils.o \ - libsysfs/dlist.o - -OBJS = udev.o \ - udev-add.o \ - udev-remove.o \ - udevdb.o \ - logging.o \ - namedev.o \ - klibc_fixups.o \ - $(SYSFS) \ - $(TDB) - -# header files automatically generated -GEN_HEADERS = udev_version.h - -# Rules on how to create the generated header files -udev_version.h: - @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ - @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ - @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ - - -$(ROOT): $(GEN_HEADERS) $(OBJS) - $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(LIBGCC) $(ARCH_LIB_OBJS) - $(STRIPCMD) $(ROOT) - -clean: - -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ - | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) - $(MAKE) -C klibc clean - -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) -DISTDIR := $(RELEASE_NAME) -srcdir = . -release: $(DISTFILES) clean -# @echo $(DISTFILES) - @-rm -rf $(DISTDIR) - @mkdir $(DISTDIR) - @-chmod 777 $(DISTDIR) - @for file in $(DISTFILES); do \ - if test -d $$file; then \ - mkdir $(DISTDIR)/$$file; \ - else \ - cp -p $$file $(DISTDIR)/$$file; \ - fi; \ - done - @tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz - @rm -rf $(DISTDIR) - @echo "Built $(RELEASE_NAME).tar.gz" - - -install: all - $(INSTALL) -d $(udevdir) - $(INSTALL) -d $(configdir) - $(INSTALL) -d $(hotplugdir) - $(INSTALL_PROGRAM) -D $(ROOT) $(sbindir)/$(ROOT) - $(INSTALL_DATA) -D udev.8 $(mandir)/man8/udev.8 - $(INSTALL_DATA) udev.config $(configdir) - $(INSTALL_DATA) udev.permissions $(configdir) - - ln -s $(sbindir)/$(ROOT) $(hotplugdir)/udev.hotplug - -uninstall: - - rm $(hotplugdir)/udev.hotplug - - rm $(configdir)/udev.permissions - - rm $(configdir)/udev.config - - rm $(mandir)/man8/udev.8 - - rm $(sbindir)/$(ROOT) - - rmdir $(hotplugdir) - - rmdir $(configdir) - - rmdir $(udevdir) - - From 04a81cac0aab2ab6a54ddc661dd57be7d5b1595a Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Sun, 23 Nov 2003 18:35:03 -0800 Subject: [PATCH 0192/4284] [PATCH] fix segfault in parsing bad udev.permissions file --- namedev.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/namedev.c b/namedev.c index bed328f646..24b9bc01ac 100644 --- a/namedev.c +++ b/namedev.c @@ -439,12 +439,24 @@ static int namedev_init_permissions(void) /* parse the line */ temp2 = strsep(&temp, ":"); + if (!temp2) { + dbg("cannot parse line: %s", line); + continue; + } strncpy(dev.name, temp2, sizeof(dev.name)); temp2 = strsep(&temp, ":"); + if (!temp2) { + dbg("cannot parse line: %s", line); + continue; + } strncpy(dev.owner, temp2, sizeof(dev.owner)); temp2 = strsep(&temp, ":"); + if (!temp2) { + dbg("cannot parse line: %s", line); + continue; + } strncpy(dev.group, temp2, sizeof(dev.owner)); dev.mode = strtol(temp, NULL, 8); From 2023350eece60db60d30e387cfb644df09b9e8b6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 20:44:41 -0800 Subject: [PATCH 0193/4284] [PATCH] add getgrnam and getpwnam to klibc_fixups files. Hopefully the klibc_fixups code will not be needed eventually. --- klibc_fixups.c | 4 +++- klibc_fixups.h | 42 ++++++++++++++++++++++++++++++++++++++++++ namedev.c | 1 + 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 klibc_fixups.h diff --git a/klibc_fixups.c b/klibc_fixups.c index a5d5d5948a..c12c90fd1c 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -4,6 +4,8 @@ #include #include #include +#include +#include "klibc_fixups.h" char *strerror(int errnum) { @@ -29,5 +31,5 @@ int strcasecmp(const char *s1, const char *s2) free(n2); return retval; } - + #endif diff --git a/klibc_fixups.h b/klibc_fixups.h new file mode 100644 index 0000000000..21a23e7762 --- /dev/null +++ b/klibc_fixups.h @@ -0,0 +1,42 @@ +#ifdef __KLIBC__ + +#ifndef KLIBC_FIXUPS_H +#define KLIBC_FIXUPS_H + + +extern char *strerror(int errnum); + +extern int strcasecmp(const char *s1, const char *s2); + +struct group { + char *gr_name; /* group name */ + char *gr_passwd; /* group password */ + gid_t gr_gid; /* group id */ + char **gr_mem; /* group members */ +}; + +static inline struct group *getgrnam(const char *name) +{ + return NULL; +} + + +struct passwd { + char *pw_name; /* user name */ + char *pw_passwd; /* user password */ + uid_t pw_uid; /* user id */ + gid_t pw_gid; /* group id */ + char *pw_gecos; /* real name */ + char *pw_dir; /* home directory */ + char *pw_shell; /* shell program */ +}; + +static inline struct passwd *getpwnam(const char *name) +{ + return NULL; +} + + +#endif + +#endif diff --git a/namedev.c b/namedev.c index 24b9bc01ac..3b19aaf909 100644 --- a/namedev.c +++ b/namedev.c @@ -39,6 +39,7 @@ #include "udev_version.h" #include "namedev.h" #include "libsysfs/libsysfs.h" +#include "klibc_fixups.h" #define TYPE_LABEL "LABEL" #define TYPE_NUMBER "NUMBER" From 10950dfe84c064da2fde8d812c0c90cfba836d16 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 20:56:18 -0800 Subject: [PATCH 0194/4284] [PATCH] add support for string group and string user names in udev.permissions. This only works if you are using glibc. Patch based on patch from Marco d'Itri --- udev-add.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/udev-add.c b/udev-add.c index 7ba873a8d4..634a515c96 100644 --- a/udev-add.c +++ b/udev-add.c @@ -28,12 +28,18 @@ #include #include #include +#include +#include +#ifndef __KLIBC__ +#include +#endif #include "udev.h" #include "udev_version.h" #include "namedev.h" #include "udevdb.h" #include "libsysfs/libsysfs.h" +#include "klibc_fixups.h" /* * Right now the major/minor of a device is stored in a file called @@ -146,8 +152,13 @@ static int create_node(struct udevice *dev) unsigned long id = strtoul(dev->owner, &endptr, 10); if (*endptr == 0x00) uid = (uid_t) id; - else - dbg("only numeric owner id supported: %s", dev->owner); + else { + struct passwd *pw = getpwnam(dev->owner); + if (!pw) + dbg("user unknown: %s", dev->owner); + else + uid = pw->pw_uid; + } } if (*dev->group) { @@ -155,8 +166,13 @@ static int create_node(struct udevice *dev) unsigned long id = strtoul(dev->group, &endptr, 10); if (*endptr == 0x00) gid = (gid_t) id; - else - dbg("only numeric group id supported: %s", dev->group); + else { + struct group *gr = getgrnam(dev->group); + if (!gr) + dbg("group unknown: %s", dev->group); + else + gid = gr->gr_gid; + } } if (uid || gid) { From 6a670d61bce2f9cc6df23af0d594e764fb2e573b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 20:56:52 -0800 Subject: [PATCH 0195/4284] [PATCH] only build klibc_fixups.c if we are actually using klibc. --- Makefile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fc5c9b1792..a2f904a745 100644 --- a/Makefile +++ b/Makefile @@ -151,10 +151,13 @@ OBJS = udev.o \ udevdb.o \ logging.o \ namedev.o \ - klibc_fixups.o \ $(SYSFS) \ $(TDB) +ifeq ($(strip $(KLIBC)),true) + OBJS += klibc_fixups.o +endif + # header files automatically generated GEN_HEADERS = udev_version.h From 53dc383ee90b6699b85f2843247389f5adeb8d50 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 23 Nov 2003 21:14:10 -0800 Subject: [PATCH 0196/4284] [PATCH] more namedev whitespace cleanups attached is the last whitespace cleanup and debug text corrections. --- namedev.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/namedev.c b/namedev.c index 3b19aaf909..a010979052 100644 --- a/namedev.c +++ b/namedev.c @@ -83,9 +83,9 @@ static void dump_dev(struct config_device *dev) dev->owner, dev->group, dev->mode); break; case CALLOUT: - dbg_parse("CALLOUT name='%s', program='%s', bus='%s', id='%s', " + dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s', " "owner='%s', group='%s', mode=%#o", - dev->name, dev->exec_program, dev->bus, dev->id, + dev->name, dev->bus, dev->exec_program, dev->id, dev->owner, dev->group, dev->mode); break; default: @@ -271,8 +271,8 @@ static int namedev_init_config(void) strfieldcpy(dev.name, temp3); dbg_parse("LABEL name='%s', bus='%s', " - "sysfs_file='%s', sysfs_value='%s'", - dev.name, dev.bus, dev.sysfs_file, + "sysfs_file='%s', sysfs_value='%s'", + dev.name, dev.bus, dev.sysfs_file, dev.sysfs_value); } @@ -417,7 +417,6 @@ static int namedev_init_permissions(void) /* loop through the whole file */ while (1) { - /* get a line */ temp = fgets(line, sizeof(line), fd); if (temp == NULL) break; @@ -522,7 +521,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) break; } if (args[i]) { - dbg("to many args - %d", i); + dbg("too many args - %d", i); args[i] = NULL; } retval = execve(args[0], args, main_envp); @@ -882,6 +881,7 @@ found: char *pos = strchr(udev->name, '%'); char *dig; char name[NAME_SIZE]; + if (pos) { strfieldcpy(name, pos+2); *pos = 0x00; @@ -890,8 +890,7 @@ found: if (!sysfs_device) break; strcat(udev->name, sysfs_device->bus_id); - dbg("bus_id inserted: %s", - sysfs_device->bus_id); + dbg("substitute bus_id '%s'", sysfs_device->bus_id); break; case 'n': dig = class_dev->name + strlen(class_dev->name); @@ -957,5 +956,3 @@ int namedev_init(void) dump_dev_list(); return retval; } - - From c124eafa238b34a2e79100d3eb1fb143b7e8cb8b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 23 Nov 2003 21:14:33 -0800 Subject: [PATCH 0197/4284] [PATCH] - format char for CALLOUT output here is a patch for inserting the callout output into NAME=. ID= supports the usual wildcard to compare with the output. I've moved all wildcard matching to a function cause this was the third occurrence. Also attached is the last whitespace cleanup and debug text corrections. The callout patch depends on the whitespace patch. CALLOUT, BUS="usb", PROGRAM="/bin/echo -n return", ID="ret*", NAME="webcam-%c-" results in: Nov 21 17:33:51 pim udev[20399]: get_major_minor: found major = 81, minor = 0 Nov 21 17:33:51 pim udev[20399]: exec_callout: callout to '/bin/echo -n return' Nov 21 17:33:51 pim udev[20399]: exec_callout: callout returned 'return' Nov 21 17:33:51 pim udev[20399]: get_attr: substitute callout output 'return' Nov 21 17:33:51 pim udev[20399]: udev_add_device: name = webcam-return- Nov 21 17:33:51 pim udev[20399]: create_node: mknod(/udev/webcam-return-, 020660, 81, 0) --- namedev.c | 53 ++++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/namedev.c b/namedev.c index a010979052..cf9e92635e 100644 --- a/namedev.c +++ b/namedev.c @@ -50,6 +50,19 @@ static LIST_HEAD(config_device_list); +/* s2 may end with '*' to match everything */ +static int strncmp_wildcard(char *s1, char *s2, int max) +{ + int len = strlen(s2); + if (len > max) + len = max; + if (s2[len-1] == '*') + len--; + else + len = max; + return strncmp(s1, s2, len); +} + static void dump_dev(struct config_device *dev) { switch (dev->type) { @@ -109,16 +122,8 @@ static int add_dev(struct config_device *new_dev) /* update the values if we already have the device */ list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); - int len = strlen(new_dev->name); - if (new_dev->name[len-1] == '*') { - len--; - if (strncmp(dev->name, new_dev->name, len)) - continue; - } else { - if (strcmp(dev->name, new_dev->name)) - continue; - } - /* the same, copy the new info into this structure */ + if (strncmp_wildcard(dev->name, new_dev->name, sizeof(dev->name))) + continue; copy_var(dev, new_dev, type); copy_var(dev, new_dev, mode); copy_string(dev, new_dev, bus); @@ -572,20 +577,18 @@ static int exec_callout(struct config_device *dev, char *value, int len) return retval; } -static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev) +static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, char *value, int len) { struct config_device *dev; struct list_head *tmp; - char value[ID_SIZE]; list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); if (dev->type != CALLOUT) continue; - - if (exec_callout(dev, value, sizeof(value))) + if (exec_callout(dev, value, len)) continue; - if (strncmp(value, dev->id, sizeof(value)) != 0) + if (strncmp_wildcard(value, dev->id, len) != 0) continue; strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { @@ -784,17 +787,12 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice * int len; strfieldcpy(udev->name, class_dev->name); + /* look for permissions */ list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); len = strlen(dev->name); - if (dev->name[len-1] == '*') { - len--; - if (strncmp(dev->name, class_dev->name, len)) - continue; - } else { - if (strcmp(dev->name, class_dev->name)) - continue; - } + if (strncmp_wildcard(class_dev->name, dev->name, sizeof(dev->name))) + continue; if (dev->mode != 0) { dbg_parse("found permissions for '%s'", class_dev->name); udev->mode = dev->mode; @@ -810,6 +808,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; char *temp = NULL; + char value[ID_SIZE]; udev->mode = 0; @@ -852,7 +851,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) } /* rules are looked at in priority order */ - retval = do_callout(class_dev, udev); + retval = do_callout(class_dev, udev, value, sizeof(value)); if (retval == 0) goto found; @@ -896,7 +895,7 @@ found: dig = class_dev->name + strlen(class_dev->name); while (isdigit(*(dig-1))) dig--; - strcat(udev->name, dig); + strcat(pos, dig); dbg("substitute kernel number '%s'", dig); break; case 'm': @@ -907,6 +906,10 @@ found: sprintf(pos, "%u", udev->major); dbg("substitute major number '%u'", udev->major); break; + case 'c': + strcat(pos, value); + dbg("substitute callout output '%s'", value); + break; default: dbg("unknown substitution type '%%%c'", pos[1]); break; From e5fbfe0a13e11c08ed72b67fa4e72a93bcd5de37 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 21:17:34 -0800 Subject: [PATCH 0198/4284] [PATCH] tweak udev-test.pl to report '0' errors if that's what happened. --- test/udev-test.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 9a54b6192a..613aa792d4 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -124,7 +124,7 @@ system("rm -rf $udev_root"); mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; # test -my $error; +my $error = 0; print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; foreach my $config (@tests) { From f3b04a2e0a041aa5546284c5bfc2022ab3e8b15f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 22:25:13 -0800 Subject: [PATCH 0199/4284] [PATCH] added ability to put format specifiers in the CALLOUT program string. --- namedev.c | 118 ++++++++++++++++++++++++++++------------------ test/udev-test.pl | 9 ++++ udev-add.c | 2 + udev.h | 6 +++ 4 files changed, 88 insertions(+), 47 deletions(-) diff --git a/namedev.c b/namedev.c index cf9e92635e..e640b93c3d 100644 --- a/namedev.c +++ b/namedev.c @@ -487,6 +487,66 @@ static mode_t get_default_mode(struct sysfs_class_device *class_dev) return 0666; } +static void build_kernel_number(struct sysfs_class_device *class_dev, struct udevice *udev) +{ + char *dig; + + /* FIXME, figure out how to handle stuff like sdaj which will not work right now. */ + dig = class_dev->name + strlen(class_dev->name); + while (isdigit(*(dig-1))) + dig--; + strfieldcpy(udev->kernel_number, dig); + dbg("kernel_number = %s", udev->kernel_number); +} + +static void apply_format(struct udevice *udev, unsigned char *string) +{ + char name[NAME_SIZE]; + char *pos; + + while (1) { + pos = strchr(string, '%'); + + if (pos) { + strfieldcpy(name, pos+2); + *pos = 0x00; + switch (pos[1]) { + case 'b': + if (strlen(udev->bus_id) == 0) + break; + strcat(string, udev->bus_id); + dbg("substitute bus_id '%s'", udev->bus_id); + break; + case 'n': + if (strlen(udev->kernel_number) == 0) + break; + strcat(pos, udev->kernel_number); + dbg("substitute kernel number '%s'", udev->kernel_number); + break; + case 'm': + sprintf(pos, "%u", udev->minor); + dbg("substitute minor number '%u'", udev->minor); + break; + case 'M': + sprintf(pos, "%u", udev->major); + dbg("substitute major number '%u'", udev->major); + break; + case 'c': + if (strlen(udev->callout_value) == 0) + break; + strcat(pos, udev->callout_value); + dbg("substitute callout output '%s'", udev->callout_value); + break; + default: + dbg("unknown substitution type '%%%c'", pos[1]); + break; + } + strcat(string, name); + } else + break; + } +} + static int exec_callout(struct config_device *dev, char *value, int len) { @@ -577,7 +637,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) return retval; } -static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, char *value, int len) +static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev) { struct config_device *dev; struct list_head *tmp; @@ -586,9 +646,12 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev dev = list_entry(tmp, struct config_device, node); if (dev->type != CALLOUT) continue; - if (exec_callout(dev, value, len)) + + /* substitute anything that needs to be in the program name */ + apply_format(udev, dev->exec_program); + if (exec_callout(dev, udev->callout_value, NAME_SIZE)) continue; - if (strncmp_wildcard(value, dev->id, len) != 0) + if (strncmp_wildcard(udev->callout_value, dev->id, NAME_SIZE) != 0) continue; strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { @@ -808,7 +871,6 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; char *temp = NULL; - char value[ID_SIZE]; udev->mode = 0; @@ -846,12 +908,15 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (sysfs_device) { dbg_parse("sysfs_device->path='%s'", sysfs_device->path); dbg_parse("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + strfieldcpy(udev->bus_id, sysfs_device->bus_id); } else { dbg_parse("class_dev->name = '%s'", class_dev->name); } + build_kernel_number(class_dev, udev); + /* rules are looked at in priority order */ - retval = do_callout(class_dev, udev, value, sizeof(value)); + retval = do_callout(class_dev, udev); if (retval == 0) goto found; @@ -876,48 +941,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) found: /* substitute placeholder in NAME */ - while (1) { - char *pos = strchr(udev->name, '%'); - char *dig; - char name[NAME_SIZE]; - - if (pos) { - strfieldcpy(name, pos+2); - *pos = 0x00; - switch (pos[1]) { - case 'b': - if (!sysfs_device) - break; - strcat(udev->name, sysfs_device->bus_id); - dbg("substitute bus_id '%s'", sysfs_device->bus_id); - break; - case 'n': - dig = class_dev->name + strlen(class_dev->name); - while (isdigit(*(dig-1))) - dig--; - strcat(pos, dig); - dbg("substitute kernel number '%s'", dig); - break; - case 'm': - sprintf(pos, "%u", udev->minor); - dbg("substitute minor number '%u'", udev->minor); - break; - case 'M': - sprintf(pos, "%u", udev->major); - dbg("substitute major number '%u'", udev->major); - break; - case 'c': - strcat(pos, value); - dbg("substitute callout output '%s'", value); - break; - default: - dbg("unknown substitution type '%%%c'", pos[1]); - break; - } - strcat(udev->name, name); - } else - break; - } + apply_format(udev, udev->name); done: /* mode was never set above */ diff --git a/test/udev-test.pl b/test/udev-test.pl index 613aa792d4..02f8ff6319 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -90,6 +90,15 @@ CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special--*", NAM CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special-device-", NAME="%c-3-%n" CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special-devic", NAME="%c-4-%n" CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special-*", NAME="%c-%n" +EOF + }, + { + desc => "callout program subtitution", + subsys => "block", + devpath => "block/sda/sda3", + expected => "test-0:0:0:0" , + conf => < Date: Sun, 23 Nov 2003 23:39:39 -0800 Subject: [PATCH 0200/4284] [PATCH] updated the man page with the latest format specifier changes. --- udev.8 | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/udev.8 b/udev.8 index 079d15f4d1..e9470838b4 100644 --- a/udev.8 +++ b/udev.8 @@ -46,6 +46,11 @@ The line format is: .RE where valid methods with corresponding keys are: .TP +.B CALLOUT +calling external program, that returns a string to match +.br +keys: \fBBUS\fP, \fBPROGRAM\fP, \fBID\fP +.TP .B LABEL device label or serial number, like USB serial number, SCSI UUID or file system label @@ -66,13 +71,23 @@ keys: \fBBUS\fP, \fBPLACE\fP string replacement of the kernel device name .br key: \fBKERNEL_NAME\fP -.TP -.B CALLOUT -calling external program, that returns a string to match -.br -keys: \fBBUS\fP, \fBPROGRAM\fP, \fBID\fP .P -The name field supports simple printf-like string subtitution: +The methods are applied in the following order: +.B CALLOUT +, +.B LABEL +, +.B NUMBER +, +.B TOPOLOGY +, +.B REPLACE +.P +The +.B NAME +and +.B PROGRAM +fields support simple printf-like string subtitution: .RS .TP .B %n @@ -87,11 +102,17 @@ the kernel minor number for the device .TP .B %b the bus id for the device +.TP +.B %c +the CALLOUT program return value (this does not work within the PROGRAM field for the obvious reason.) .RE .P A sample \fIudev.conf\fP might look like this: .sp .nf +# if /sbin/scsi_id returns "OEM 0815" device will be called disk1 +CALLOUT, BUS="scsi", PROGRAM="/sbin/scsi_id", ID="OEM 0815", NAME="disk1" + # USB printer to be called lp_color LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_color" @@ -104,9 +125,6 @@ TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" # ttyUSB1 should always be called pda REPLACE, KERNEL="ttyUSB1", NAME="pda" -# if /sbin/scsi_id returns "OEM 0815" device will be called disk1 -CALLOUT, BUS="scsi", PROGRAM="/sbin/scsi_id", ID="OEM 0815", NAME="disk1" - # USB webcams to be called webcam0, webcam1, ... LABEL, BUS="usb", model="WebCam Version 3", NAME="webcam%n" .fi @@ -119,6 +137,8 @@ lines beginning with a '#' will be ignored. Every line lists a device name followed by numeric owner, group and permission mode. All values are separated by colons. The name field may end with a wildcard to apply the values to a whole class of devices. +.br +If udev was built using glibc, string owner and group names may be used. .sp A sample \fIudev.permissions\fP might look like this: .sp @@ -128,6 +148,11 @@ ttyUSB1:0:8:0660 video*:500:500:0660 dsp1:::0666 .fi +.P +If +.B +udev +was built using glibc, string owner and group names may be used. .SH "FILES" .nf From a86d6f567289ab546ebb06629f2d9b25555e0414 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 23 Nov 2003 23:39:59 -0800 Subject: [PATCH 0201/4284] [PATCH] update default config file with a CALLOUT rule, and more documentation. --- udev.config | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/udev.config b/udev.config index 8d77099ca8..3eb688a3a0 100644 --- a/udev.config +++ b/udev.config @@ -1,13 +1,18 @@ -# There are a number of modifiers that are allowed to be used in the NAME field. +# There are a number of modifiers that are allowed to be used in the NAME or PROGRAM fields. # They provide the following subsitutions: # %n - the "kernel number" of the device. # for example, 'sda3' has a "kernel number" of '3' # %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 return value for the CALLOUT program (note, this doesn't work within +# the PROGRAM field for the obvious reason.) # -# My usb camera... +# Looking for scsi bus id 42:0:0:1 +CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" + +# A usb camera. LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera%n" # USB Epson printer to be called lp_epson From f02763a95be342d169c8e194a78337cc7b74c9d8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 00:03:10 -0800 Subject: [PATCH 0202/4284] [PATCH] v007 Changelog --- ChangeLog | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ChangeLog b/ChangeLog index c1cf43bdc7..efaf86669a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +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 ============================================ From 44132eca4e36e9c9976b72eb9c14e3b8ce5c0e10 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 00:03:24 -0800 Subject: [PATCH 0203/4284] [PATCH] v007 release --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a2f904a745..376881f068 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 006_bk +VERSION = 007 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 4da7e8808f..399c34f8b3 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 006_bk +Version: 007 Release: 1 License: GPL Group: Utilities/System From 58a16d607ba79b03640e67679d0c54527b00111b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 05:38:01 -0800 Subject: [PATCH 0204/4284] [PATCH] 007_bk version change to Makefile. --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 376881f068..af181fe24a 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = true ROOT = udev -VERSION = 007 +VERSION = 007_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 399c34f8b3..0c30d613b7 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 007 +Version: 007_bk Release: 1 License: GPL Group: Utilities/System From f8f00338a15409f685fc51184862bca5988aee21 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 24 Nov 2003 05:44:01 -0800 Subject: [PATCH 0205/4284] [PATCH] udev-test.pl - tweaks I found two missing characters and optimized $PWD. --- test/udev-test.pl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 02f8ff6319..e4a4ddcda8 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -21,9 +21,7 @@ use warnings; use strict; -my $PWD = `pwd`; -chomp($PWD); - +my $PWD = $ENV{PWD}; my $sysfs = "sys/"; my $udev_bin = "../udev"; my $udev_root = "udev-root/"; # !!! directory will be removed !!! @@ -80,7 +78,7 @@ TOPOLOGY, BUS="scsi", PLACE="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:b EOF }, { - desc => "callout result subtitution, only last should match", + desc => "callout result substitution, only last should match", subsys => "block", devpath => "block/sda/sda3", expected => "special-device-3" , @@ -93,7 +91,7 @@ CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n special-device", ID="special-*", NAME EOF }, { - desc => "callout program subtitution", + desc => "callout program substitution", subsys => "block", devpath => "block/sda/sda3", expected => "test-0:0:0:0" , @@ -151,7 +149,6 @@ foreach my $config (@tests) { system("tree $udev_root"); print "\n"; $error++; -# next; } udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf}); From 89f38d18cef11f5fabd7ec73be1839491cf95cbc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 06:13:05 -0800 Subject: [PATCH 0206/4284] [PATCH] fix the test.block and test.tty scripts due to their moveing. Also add a test.all script. --- test/test.all | 41 +++++++++++++++++++++++++++++++++++++++++ test/test.block | 2 +- test/test.tty | 2 +- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/test.all diff --git a/test/test.all b/test/test.all new file mode 100644 index 0000000000..527569bd43 --- /dev/null +++ b/test/test.all @@ -0,0 +1,41 @@ +#! /bin/sh +# +# test.block - run udev(8) on each block device in /sys/block + +if [ $# = "0" ] ; then + echo + echo "usage: $0 " + echo "where is \"add\" or \"remove\"" + echo + exit 1 +fi + +SYSFSDIR=/sys # change this for a nonstand sysfs mount point +BIN=../udev # location of your udev binary +export ACTION=$1 # 'add' or 'remove' + +# do the block devices first +for i in ${SYSFSDIR}/block/*; do + # add each drive + export DEVPATH=${i#${SYSFSDIR}} + $BIN block + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${SYSFSDIR}} + $BIN block + fi + done +done + +# now all the devices in the class directories +for i in ${SYSFSDIR}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${SYSFSDIR}} + CLASS=`echo ${i#${SYSFSDIR}} | cut --delimiter='/' --fields=3-` + $BIN $CLASS + fi + done +done diff --git a/test/test.block b/test/test.block index b806a42aac..294c47c0be 100644 --- a/test/test.block +++ b/test/test.block @@ -11,7 +11,7 @@ if [ $# = "0" ] ; then fi SYSFSDIR=/sys # change this for a nonstand sysfs mount point -BIN=./udev # location of your udev binary +BIN=../udev # location of your udev binary export ACTION=$1 # 'add' or 'remove' for i in ${SYSFSDIR}/block/*; do diff --git a/test/test.tty b/test/test.tty index 42f46a2e7c..b89ad5a6d8 100644 --- a/test/test.tty +++ b/test/test.tty @@ -11,7 +11,7 @@ if [ $# = "0" ] ; then fi SYSFSDIR=/sys # change this for a nonstand sysfs mount point -BIN=./udev # location of your udev binary +BIN=../udev # location of your udev binary export ACTION=$1 # 'add' or 'remove' for i in ${SYSFSDIR}/class/tty/*; do From 7e1b28e8faad308523a22a78930c47e5cf9cb6cf Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 06:19:44 -0800 Subject: [PATCH 0207/4284] [PATCH] fix udev init.d script to handle all class devices in sysfs. --- etc/init.d/udev | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/etc/init.d/udev b/etc/init.d/udev index 99f06c2963..5c09afd205 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -24,24 +24,31 @@ case "$1" in # device bring up action "Creating initial udev device nodes: " /bin/true export ACTION=add - # add tty devices - for i in ${sysfs_dir}/class/tty/*; do - export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` - $bin tty - done # add block devices and their partitions for i in ${sysfs_dir}/block/*; do - export DEVPATH="/"`echo $i | cut --delimiter='/' --fields=3-` + # add each drive + export DEVPATH=${i#${sysfs_dir}} $bin block + + # add each partition, on each device for j in $i/*; do if [ -f $j/dev ]; then - export DEVPATH="/"`echo $j | \ - cut --delimiter='/' --fields=3-` + export DEVPATH=${j#${sysfs_dir}} $bin block fi done done - # TODO: add other device classes + # all other device classes + for i in ${sysfs_dir}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + CLASS=`echo ${i#${sysfs_dir}} | \ + cut --delimiter='/' --fields=3-` + $bin $CLASS + fi + done + done ;; stop) # be careful From 02cbdf5eb9af4af5c3f612990ac3250bdd2135c7 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 21:57:33 -0800 Subject: [PATCH 0208/4284] [PATCH] sync up with the 0.84 version of klibc --- klibc/klibc/Makefile | 1 + klibc/klibc/README | 8 +- klibc/klibc/SYSCALLS | 6 +- .../arch/alpha/include/klibc/archsignal.h | 13 + .../klibc/arch/arm/include/klibc/archsignal.h | 13 + .../arch/cris/include/klibc/archsignal.h | 13 + .../arch/i386/include/klibc/archsignal.h | 13 + klibc/klibc/arch/ia64/Makefile.inc | 6 + klibc/klibc/arch/ia64/crt0.S | 27 ++ .../arch/ia64/include/klibc/archsetjmp.h | 17 + .../arch/ia64/include/klibc/archsignal.h | 33 ++ klibc/klibc/arch/ia64/include/klibc/archsys.h | 208 ++++++++++- klibc/klibc/arch/ia64/setjmp.S | 341 ++++++++++++++++++ klibc/klibc/arch/ia64/vfork.S | 41 +++ .../arch/m68k/include/klibc/archsignal.h | 13 + .../arch/mips/include/klibc/archsignal.h | 13 + .../arch/mips64/include/klibc/archsignal.h | 13 + .../arch/parisc/include/klibc/archsignal.h | 13 + .../klibc/arch/ppc/include/klibc/archsignal.h | 13 + .../arch/ppc64/include/klibc/archsignal.h | 13 + .../arch/s390/include/klibc/archsignal.h | 13 + .../arch/s390x/include/klibc/archsignal.h | 13 + .../klibc/arch/sh/include/klibc/archsignal.h | 13 + .../arch/sparc/include/klibc/archsignal.h | 13 + .../arch/sparc64/include/klibc/archsignal.h | 13 + .../arch/x86_64/include/klibc/archsignal.h | 13 + klibc/klibc/ctypes.c | 3 + klibc/klibc/include/ctype.h | 7 +- klibc/klibc/include/signal.h | 4 +- klibc/klibc/include/string.h | 3 + klibc/klibc/include/syslog.h | 4 +- klibc/klibc/include/unistd.h | 3 +- klibc/klibc/strcasecmp.c | 25 ++ klibc/klibc/strncasecmp.c | 24 ++ klibc/klibc/strndup.c | 17 + klibc/klibc/syslog.c | 2 +- 36 files changed, 970 insertions(+), 18 deletions(-) create mode 100644 klibc/klibc/arch/alpha/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/arm/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/cris/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/i386/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/ia64/crt0.S create mode 100644 klibc/klibc/arch/ia64/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/ia64/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/ia64/setjmp.S create mode 100644 klibc/klibc/arch/ia64/vfork.S create mode 100644 klibc/klibc/arch/m68k/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/mips/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/mips64/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/parisc/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/ppc/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/ppc64/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/s390/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/s390x/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/sh/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/sparc/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/sparc64/include/klibc/archsignal.h create mode 100644 klibc/klibc/arch/x86_64/include/klibc/archsignal.h create mode 100644 klibc/klibc/strcasecmp.c create mode 100644 klibc/klibc/strncasecmp.c create mode 100644 klibc/klibc/strndup.c diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 470a276ded..e1d63381c1 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -27,6 +27,7 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ memmove.o \ + strcasecmp.o strncasecmp.o strndup.o strerror.o \ strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o \ strncat.o strstr.o strncmp.o strncpy.o strrchr.o strspn.o \ strsep.o strtok.o \ diff --git a/klibc/klibc/README b/klibc/klibc/README index 7d5751804f..ce0ad7ba6a 100644 --- a/klibc/klibc/README +++ b/klibc/klibc/README @@ -34,11 +34,11 @@ b) If you're cross-compiling, change ARCH in the main MCONFIG file to The following is the last known status of various architectures: - Known to work: alpha arm i386 s390 s390x sparc sparc64 x86_64* + Known to work: alpha arm ia64 i386 s390 s390x sparc + sparc64 x86_64* Works static, not shared: mips* arm-thumb sh* - Need crt0.S updates: ppc - Missing setjmp: ppc64 - Need porting work: cris ia64 m68k mips64 parisc + Might work: ppc ppc64 + Need porting work: cris m68k mips64 parisc x86_64: requires a kernel header patch (to be created) mips, sh: linker problem; might work with fixed linker diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS index 802f8a1711..92dff963b3 100644 --- a/klibc/klibc/SYSCALLS +++ b/klibc/klibc/SYSCALLS @@ -11,7 +11,7 @@ # # Process-related syscalls # - pid_t vfork() + pid_t vfork() pid_t vfork@forkish() pid_t getpid() pid_t getxpid@dual0::getpid() @@ -140,8 +140,8 @@ int uname(struct utsname *) int setdomainname(const char *, size_t) int sethostname(const char *, size_t) int init_module(const char *, struct module *) -void * create_module(const char *, size_t) + void * create_module(const char *, size_t) int delete_module(const char *) -int query_module(const char *, int, void *, size_t, size_t) + int query_module(const char *, int, void *, size_t, size_t) int reboot::__reboot(int, int, int, void *) int syslog::klogctl(int, char *, int) diff --git a/klibc/klibc/arch/alpha/include/klibc/archsignal.h b/klibc/klibc/arch/alpha/include/klibc/archsignal.h new file mode 100644 index 0000000000..b870a05131 --- /dev/null +++ b/klibc/klibc/arch/alpha/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/alpha/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/arm/include/klibc/archsignal.h b/klibc/klibc/arch/arm/include/klibc/archsignal.h new file mode 100644 index 0000000000..77685e62f0 --- /dev/null +++ b/klibc/klibc/arch/arm/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/arm/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/cris/include/klibc/archsignal.h b/klibc/klibc/arch/cris/include/klibc/archsignal.h new file mode 100644 index 0000000000..73b2e196c9 --- /dev/null +++ b/klibc/klibc/arch/cris/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/cris/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/i386/include/klibc/archsignal.h b/klibc/klibc/arch/i386/include/klibc/archsignal.h new file mode 100644 index 0000000000..caea8d8b3d --- /dev/null +++ b/klibc/klibc/arch/i386/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/i386/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +typedef int sig_atomic_t; + +#endif diff --git a/klibc/klibc/arch/ia64/Makefile.inc b/klibc/klibc/arch/ia64/Makefile.inc index 1fb364f92e..edf43459f8 100644 --- a/klibc/klibc/arch/ia64/Makefile.inc +++ b/klibc/klibc/arch/ia64/Makefile.inc @@ -7,4 +7,10 @@ # accordingly. # +ARCHOBJS = \ + arch/$(ARCH)/vfork.o \ + arch/$(ARCH)/setjmp.o + +ARCHSOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS)) + archclean: diff --git a/klibc/klibc/arch/ia64/crt0.S b/klibc/klibc/arch/ia64/crt0.S new file mode 100644 index 0000000000..4b128154e8 --- /dev/null +++ b/klibc/klibc/arch/ia64/crt0.S @@ -0,0 +1,27 @@ + +#include + + .align 32 + .global _start + + .proc _start + .type _start,@function +_start: + .prologue + .save rp, r0 + + alloc r2 = ar.pfs,0,0,2,0 + movl r3 = FPSR_DEFAULT + ;; + adds out0= 16,sp /* argc pointer */ + movl gp = @gprel(0f) +0: mov r9 = ip + ;; + sub gp = r9, gp /* back-compute gp value */ + + .body + br.call.sptk.few rp = __libc_init + ;; + break 0 /* break miserably if we ever return */ + + .endp _start diff --git a/klibc/klibc/arch/ia64/include/klibc/archsetjmp.h b/klibc/klibc/arch/ia64/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..bd639c0b00 --- /dev/null +++ b/klibc/klibc/arch/ia64/include/klibc/archsetjmp.h @@ -0,0 +1,17 @@ +/* + * arch/ia64/include/klibc/archsetjmp.h + * + * Code borrowed from the FreeBSD kernel. + * + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +/* User code must not depend on the internal representation of jmp_buf. */ +#define _JBLEN 0x200 + +/* guaranteed 128-bit alignment! */ +typedef char jmp_buf[_JBLEN] __attribute__ ((aligned (16))); + +#endif diff --git a/klibc/klibc/arch/ia64/include/klibc/archsignal.h b/klibc/klibc/arch/ia64/include/klibc/archsignal.h new file mode 100644 index 0000000000..9ab0ed744c --- /dev/null +++ b/klibc/klibc/arch/ia64/include/klibc/archsignal.h @@ -0,0 +1,33 @@ +/* + * arch/ia64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions. + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +#define _NSIG 64 +#define _NSIG_BPW 64 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + int sa_flags; +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +typedef int sig_atomic_t; + +#endif diff --git a/klibc/klibc/arch/ia64/include/klibc/archsys.h b/klibc/klibc/arch/ia64/include/klibc/archsys.h index ef5940ac25..fe331acf55 100644 --- a/klibc/klibc/arch/ia64/include/klibc/archsys.h +++ b/klibc/klibc/arch/ia64/include/klibc/archsys.h @@ -7,6 +7,212 @@ #ifndef _KLIBC_ARCHSYS_H #define _KLIBC_ARCHSYS_H -/* No special syscall definitions for this architecture */ +#define __IA64_BREAK "break 0x100000;;\n\t" + +#define _syscall0(type,name) \ +type \ +name (void) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15) \ + : "2" (_r15) ASM_ARGS_0 \ + : "memory" ASM_CLOBBERS_0); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return _retval; \ +} + +#define _syscall1(type,name,type1,arg1) \ +type \ +name (type1 arg1) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_1(arg1); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_1 \ + : "2" (_r15) ASM_ARGS_1 \ + : "memory" ASM_CLOBBERS_1); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return _retval; \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type \ +name (type1 arg1, type2 arg2) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_2(arg1, arg2); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_2 \ + : "2" (_r15) ASM_ARGS_2 \ + : "memory" ASM_CLOBBERS_2); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return _retval; \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_3(arg1, arg2, arg3); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_3 \ + : "2" (_r15) ASM_ARGS_3 \ + : "memory" ASM_CLOBBERS_3); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return _retval; \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_4(arg1, arg2, arg3, arg4); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_4 \ + : "2" (_r15) ASM_ARGS_4 \ + : "memory" ASM_CLOBBERS_4); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return _retval; \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_5(arg1, arg2, arg3, arg4, arg5); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_5 \ + : "2" (_r15) ASM_ARGS_5 \ + : "memory" ASM_CLOBBERS_5); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return _retval; \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_6 \ + : "2" (_r15) ASM_ARGS_6 \ + : "memory" ASM_CLOBBERS_6); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return _retval; \ +} + + +#define LOAD_ARGS_0() do { } while (0) +#define LOAD_ARGS_1(out0) \ + register long _out0 asm ("out0") = (long) (out0); \ + LOAD_ARGS_0 () +#define LOAD_ARGS_2(out0, out1) \ + register long _out1 asm ("out1") = (long) (out1); \ + LOAD_ARGS_1 (out0) +#define LOAD_ARGS_3(out0, out1, out2) \ + register long _out2 asm ("out2") = (long) (out2); \ + LOAD_ARGS_2 (out0, out1) +#define LOAD_ARGS_4(out0, out1, out2, out3) \ + register long _out3 asm ("out3") = (long) (out3); \ + LOAD_ARGS_3 (out0, out1, out2) +#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \ + register long _out4 asm ("out4") = (long) (out4); \ + LOAD_ARGS_4 (out0, out1, out2, out3) +#define LOAD_ARGS_6(out0, out1, out2, out3, out4, out5) \ + register long _out5 asm ("out5") = (long) (out5); \ + LOAD_ARGS_5 (out0, out1, out2, out3, out4) + +#define ASM_OUTARGS_1 "=r" (_out0) +#define ASM_OUTARGS_2 ASM_OUTARGS_1, "=r" (_out1) +#define ASM_OUTARGS_3 ASM_OUTARGS_2, "=r" (_out2) +#define ASM_OUTARGS_4 ASM_OUTARGS_3, "=r" (_out3) +#define ASM_OUTARGS_5 ASM_OUTARGS_4, "=r" (_out4) +#define ASM_OUTARGS_6 ASM_OUTARGS_5, "=r" (_out5) + +#define ASM_ARGS_0 +#define ASM_ARGS_1 ASM_ARGS_0, "3" (_out0) +#define ASM_ARGS_2 ASM_ARGS_1, "4" (_out1) +#define ASM_ARGS_3 ASM_ARGS_2, "5" (_out2) +#define ASM_ARGS_4 ASM_ARGS_3, "6" (_out3) +#define ASM_ARGS_5 ASM_ARGS_4, "7" (_out4) +#define ASM_ARGS_6 ASM_ARGS_5, "8" (_out5) + +#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0" +#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1" +#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2" +#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3" +#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4" +#define ASM_CLOBBERS_5 ASM_CLOBBERS_6, "out5" +#define ASM_CLOBBERS_6 , "out6", "out7", \ + /* Non-stacked integer registers, minus r8, r10, r15. */ \ + "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \ + "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \ + "r28", "r29", "r30", "r31", \ + /* Predicate registers. */ \ + "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \ + /* Non-rotating fp registers. */ \ + "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + /* Branch registers. */ \ + "b6", "b7" #endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/ia64/setjmp.S b/klibc/klibc/arch/ia64/setjmp.S new file mode 100644 index 0000000000..50f91dc1d6 --- /dev/null +++ b/klibc/klibc/arch/ia64/setjmp.S @@ -0,0 +1,341 @@ +/* + * IA-64 specific setjmp/longjmp routines + * + * Inspired by setjmp.s from the FreeBSD kernel. + */ + +#define J_UNAT 0 +#define J_NATS 0x8 +#define J_PFS 0x10 +#define J_BSP 0x18 +#define J_RNAT 0x20 +#define J_PREDS 0x28 +#define J_LC 0x30 +#define J_R4 0x38 +#define J_R5 0x40 +#define J_R6 0x48 +#define J_R7 0x50 +#define J_SP 0x58 +#define J_F2 0x60 +#define J_F3 0x70 +#define J_F4 0x80 +#define J_F5 0x90 +#define J_F16 0xa0 +#define J_F17 0xb0 +#define J_F18 0xc0 +#define J_F19 0xd0 +#define J_F20 0xe0 +#define J_F21 0xf0 +#define J_F22 0x100 +#define J_F23 0x110 +#define J_F24 0x120 +#define J_F25 0x130 +#define J_F26 0x140 +#define J_F27 0x150 +#define J_F28 0x160 +#define J_F29 0x170 +#define J_F30 0x180 +#define J_F31 0x190 +#define J_FPSR 0x1a0 +#define J_B0 0x1a8 +#define J_B1 0x1b0 +#define J_B2 0x1b8 +#define J_B3 0x1c0 +#define J_B4 0x1c8 +#define J_B5 0x1d0 +#define J_SIGMASK 0x1d8 +#define J_SIGSET 0x1e0 +#define J_GP 0x1f0 + +// int setjmp(struct jmp_buffer *) +// +// Setup a non-local goto. +// +// Description: +// +// SetJump stores the current register set in the area pointed to +// by "save". It returns zero. Subsequent calls to "LongJump" will +// restore the registers and return non-zero to the same location. +// +// On entry, r32 contains the pointer to the jmp_buffer +// + .align 32 + .global setjmp +setjmp: + // + // Make sure buffer is aligned at 16byte boundary + // + add r10 = -0x10,r0 ;; // mask the lower 4 bits + and r32 = r32, r10;; + add r32 = 0x10, r32;; // move to next 16 byte boundary + + add r10 = J_PREDS, r32 // skip Unats & pfs save area + add r11 = J_BSP, r32 + // + // save immediate context + // + mov r2 = ar.bsp // save backing store pointer + mov r3 = pr // save predicates + flushrs + ;; + // + // save user Unat register + // + mov r16 = ar.lc // save loop count register + mov r14 = ar.unat // save user Unat register + + st8 [r10] = r3, J_LC-J_PREDS + st8 [r11] = r2, J_R4-J_BSP + ;; + st8 [r10] = r16, J_R5-J_LC + st8 [r32] = r14, J_NATS // Note: Unat at the + // beginning of the save area + mov r15 = ar.pfs + ;; + // + // save preserved general registers & NaT's + // + st8.spill [r11] = r4, J_R6-J_R4 + ;; + st8.spill [r10] = r5, J_R7-J_R5 + ;; + st8.spill [r11] = r6, J_SP-J_R6 + ;; + st8.spill [r10] = r7, J_F3-J_R7 + ;; + st8.spill [r11] = sp, J_F2-J_SP + ;; + // + // save spilled Unat and pfs registers + // + mov r2 = ar.unat // save Unat register after spill + ;; + st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs + ;; + st8 [r32] = r15 // save pfs + // + // save floating registers + // + stf.spill [r11] = f2, J_F4-J_F2 + stf.spill [r10] = f3, J_F5-J_F3 + ;; + stf.spill [r11] = f4, J_F16-J_F4 + stf.spill [r10] = f5, J_F17-J_F5 + ;; + stf.spill [r11] = f16, J_F18-J_F16 + stf.spill [r10] = f17, J_F19-J_F17 + ;; + stf.spill [r11] = f18, J_F20-J_F18 + stf.spill [r10] = f19, J_F21-J_F19 + ;; + stf.spill [r11] = f20, J_F22-J_F20 + stf.spill [r10] = f21, J_F23-J_F21 + ;; + stf.spill [r11] = f22, J_F24-J_F22 + stf.spill [r10] = f23, J_F25-J_F23 + ;; + stf.spill [r11] = f24, J_F26-J_F24 + stf.spill [r10] = f25, J_F27-J_F25 + ;; + stf.spill [r11] = f26, J_F28-J_F26 + stf.spill [r10] = f27, J_F29-J_F27 + ;; + stf.spill [r11] = f28, J_F30-J_F28 + stf.spill [r10] = f29, J_F31-J_F29 + ;; + stf.spill [r11] = f30, J_FPSR-J_F30 + stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr + // + // save FPSR register & branch registers + // + mov r2 = ar.fpsr // save fpsr register + mov r3 = b0 + ;; + st8 [r11] = r2, J_B1-J_FPSR + st8 [r10] = r3, J_B2-J_B0 + mov r2 = b1 + mov r3 = b2 + ;; + st8 [r11] = r2, J_B3-J_B1 + st8 [r10] = r3, J_B4-J_B2 + mov r2 = b3 + mov r3 = b4 + ;; + st8 [r11] = r2, J_B5-J_B3 + st8 [r10] = r3 + mov r2 = b5 + ;; + st8 [r11] = r2 + ;; + // + // return + // + mov r8 = r0 // return 0 from setjmp + mov ar.unat = r14 // restore unat + br.ret.sptk b0 + .endp setjmp + +// +// void longjmp(struct jmp_buffer *, int val) +// +// Perform a non-local goto. +// +// Description: +// +// LongJump initializes the register set to the values saved by a +// previous 'SetJump' and jumps to the return location saved by that +// 'SetJump'. This has the effect of unwinding the stack and returning +// for a second time to the 'SetJump'. +// + + .align 32 + .global longjmp +longjmp: + // + // Make sure buffer is aligned at 16byte boundary + // + add r10 = -0x10,r0 ;; // mask the lower 4 bits + and r32 = r32, r10;; + add r32 = 0x10, r32;; // move to next 16 byte boundary + + // + // caching the return value as we do invala in the end + // + mov r8 = r33 // return value + + // + // get immediate context + // + mov r14 = ar.rsc // get user RSC conf + add r10 = J_PFS, r32 // get address of pfs + add r11 = J_NATS, r32 + ;; + ld8 r15 = [r10], J_BSP-J_PFS // get pfs + ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs + ;; + mov ar.unat = r2 + ;; + ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer + mov ar.rsc = r0 // put RSE in enforced lazy + mov ar.pfs = r15 + ;; + + // + // while returning from longjmp the BSPSTORE and BSP needs to be + // same and discard all the registers allocated after we did + // setjmp. Also, we need to generate the RNAT register since we + // did not flushed the RSE on setjmp. + // + mov r17 = ar.bspstore // get current BSPSTORE + ;; + cmp.ltu p6,p7 = r17, r16 // is it less than BSP of +(p6) br.spnt.few .flush_rse + mov r19 = ar.rnat // get current RNAT + ;; + loadrs // invalidate dirty regs + br.sptk.many .restore_rnat // restore RNAT + +.flush_rse: + flushrs + ;; + mov r19 = ar.rnat // get current RNAT + mov r17 = r16 // current BSPSTORE + ;; +.restore_rnat: + // + // check if RNAT is saved between saved BSP and curr BSPSTORE + // + mov r18 = 0x3f + ;; + dep r18 = r18,r16,3,6 // get RNAT address + ;; + cmp.ltu p8,p9 = r18, r17 // RNAT saved on RSE + ;; +(p8) ld8 r19 = [r18] // get RNAT from RSE + ;; + mov ar.bspstore = r16 // set new BSPSTORE + ;; + mov ar.rnat = r19 // restore RNAT + mov ar.rsc = r14 // restore RSC conf + + + ld8 r3 = [r11], J_R4-J_LC // get lc register + ld8 r2 = [r10], J_R5-J_PREDS // get predicates + ;; + mov pr = r2, -1 + mov ar.lc = r3 + // + // restore preserved general registers & NaT's + // + ld8.fill r4 = [r11], J_R6-J_R4 + ;; + ld8.fill r5 = [r10], J_R7-J_R5 + ld8.fill r6 = [r11], J_SP-J_R6 + ;; + ld8.fill r7 = [r10], J_F2-J_R7 + ld8.fill sp = [r11], J_F3-J_SP + ;; + // + // restore floating registers + // + ldf.fill f2 = [r10], J_F4-J_F2 + ldf.fill f3 = [r11], J_F5-J_F3 + ;; + ldf.fill f4 = [r10], J_F16-J_F4 + ldf.fill f5 = [r11], J_F17-J_F5 + ;; + ldf.fill f16 = [r10], J_F18-J_F16 + ldf.fill f17 = [r11], J_F19-J_F17 + ;; + ldf.fill f18 = [r10], J_F20-J_F18 + ldf.fill f19 = [r11], J_F21-J_F19 + ;; + ldf.fill f20 = [r10], J_F22-J_F20 + ldf.fill f21 = [r11], J_F23-J_F21 + ;; + ldf.fill f22 = [r10], J_F24-J_F22 + ldf.fill f23 = [r11], J_F25-J_F23 + ;; + ldf.fill f24 = [r10], J_F26-J_F24 + ldf.fill f25 = [r11], J_F27-J_F25 + ;; + ldf.fill f26 = [r10], J_F28-J_F26 + ldf.fill f27 = [r11], J_F29-J_F27 + ;; + ldf.fill f28 = [r10], J_F30-J_F28 + ldf.fill f29 = [r11], J_F31-J_F29 + ;; + ldf.fill f30 = [r10], J_FPSR-J_F30 + ldf.fill f31 = [r11], J_B0-J_F31 ;; + + // + // restore branch registers and fpsr + // + ld8 r16 = [r10], J_B1-J_FPSR // get fpsr + ld8 r17 = [r11], J_B2-J_B0 // get return pointer + ;; + mov ar.fpsr = r16 + mov b0 = r17 + ld8 r2 = [r10], J_B3-J_B1 + ld8 r3 = [r11], J_B4-J_B2 + ;; + mov b1 = r2 + mov b2 = r3 + ld8 r2 = [r10], J_B5-J_B3 + ld8 r3 = [r11] + ;; + mov b3 = r2 + mov b4 = r3 + ld8 r2 = [r10] + ld8 r21 = [r32] // get user unat + ;; + mov b5 = r2 + mov ar.unat = r21 + + // + // invalidate ALAT + // + invala ;; + + br.ret.sptk b0 + .endp longjmp diff --git a/klibc/klibc/arch/ia64/vfork.S b/klibc/klibc/arch/ia64/vfork.S new file mode 100644 index 0000000000..0354fa9ef7 --- /dev/null +++ b/klibc/klibc/arch/ia64/vfork.S @@ -0,0 +1,41 @@ +/* + * ia64 specific vfork syscall + * + * Written By: Martin Hicks + * + */ + +/* This syscall is a special case of the clone syscall */ +#include +#include +#include + +/* These are redefined here because linux/sched.h isn't safe for + * inclusion in asm. + */ +#define CLONE_VM 0x00000100 /* set if VM shared between processes */ +#define CLONE_VFORK 0x00004000 /* set if parent wants the child to wake it up on exit */ + +/* pid_t vfork(void) */ +/* Implemented as clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */ + + .proc vfork + .global vfork +vfork: + alloc r2=ar.pfs,0,0,2,0 + mov r15=__NR_clone + mov out0=CLONE_VM|CLONE_VFORK|SIGCHLD + mov out1=0 + ;; + __IA64_BREAK // Do the syscall + + addl r15=0,r1 + cmp.eq p7,p6 = -1,r10 + ;; + ld8 r14=[r15] + ;; +(p7) st4 [r14]=r8 + ;; +(p7) mov r8=-1 + br.ret.sptk.many b0 + .endp diff --git a/klibc/klibc/arch/m68k/include/klibc/archsignal.h b/klibc/klibc/arch/m68k/include/klibc/archsignal.h new file mode 100644 index 0000000000..714527f6b0 --- /dev/null +++ b/klibc/klibc/arch/m68k/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/m68k/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/mips/include/klibc/archsignal.h b/klibc/klibc/arch/mips/include/klibc/archsignal.h new file mode 100644 index 0000000000..3b72908636 --- /dev/null +++ b/klibc/klibc/arch/mips/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/mips/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/mips64/include/klibc/archsignal.h b/klibc/klibc/arch/mips64/include/klibc/archsignal.h new file mode 100644 index 0000000000..56b0fd323e --- /dev/null +++ b/klibc/klibc/arch/mips64/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/mips64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/parisc/include/klibc/archsignal.h b/klibc/klibc/arch/parisc/include/klibc/archsignal.h new file mode 100644 index 0000000000..511d774b2d --- /dev/null +++ b/klibc/klibc/arch/parisc/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/parisc/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/ppc/include/klibc/archsignal.h b/klibc/klibc/arch/ppc/include/klibc/archsignal.h new file mode 100644 index 0000000000..567a547ef9 --- /dev/null +++ b/klibc/klibc/arch/ppc/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/ppc/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/ppc64/include/klibc/archsignal.h b/klibc/klibc/arch/ppc64/include/klibc/archsignal.h new file mode 100644 index 0000000000..8452f6e4bc --- /dev/null +++ b/klibc/klibc/arch/ppc64/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/ppc64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/s390/include/klibc/archsignal.h b/klibc/klibc/arch/s390/include/klibc/archsignal.h new file mode 100644 index 0000000000..1f8de28b4b --- /dev/null +++ b/klibc/klibc/arch/s390/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/s390/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/s390x/include/klibc/archsignal.h b/klibc/klibc/arch/s390x/include/klibc/archsignal.h new file mode 100644 index 0000000000..08c9a0073a --- /dev/null +++ b/klibc/klibc/arch/s390x/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/s390x/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/sh/include/klibc/archsignal.h b/klibc/klibc/arch/sh/include/klibc/archsignal.h new file mode 100644 index 0000000000..6c4e5976ad --- /dev/null +++ b/klibc/klibc/arch/sh/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/sh/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/sparc/include/klibc/archsignal.h b/klibc/klibc/arch/sparc/include/klibc/archsignal.h new file mode 100644 index 0000000000..6af3709033 --- /dev/null +++ b/klibc/klibc/arch/sparc/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/sparc/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsignal.h b/klibc/klibc/arch/sparc64/include/klibc/archsignal.h new file mode 100644 index 0000000000..f81bd668bb --- /dev/null +++ b/klibc/klibc/arch/sparc64/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/sparc64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsignal.h b/klibc/klibc/arch/x86_64/include/klibc/archsignal.h new file mode 100644 index 0000000000..74e82e1dd0 --- /dev/null +++ b/klibc/klibc/arch/x86_64/include/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/x86_64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/klibc/ctypes.c b/klibc/klibc/ctypes.c index a9398b8071..c7adc9882c 100644 --- a/klibc/klibc/ctypes.c +++ b/klibc/klibc/ctypes.c @@ -9,6 +9,8 @@ const unsigned char __ctypes[257] = { 0, /* EOF */ + + 0, /* control character */ 0, /* control character */ 0, /* control character */ 0, /* control character */ @@ -23,6 +25,7 @@ const unsigned char __ctypes[257] = { __ctype_space, /* FF */ __ctype_space, /* CR */ 0, /* control character */ + 0, /* control character */ 0, /* control character */ 0, /* control character */ diff --git a/klibc/klibc/include/ctype.h b/klibc/klibc/include/ctype.h index e1a25f3693..3f5cfad558 100644 --- a/klibc/klibc/include/ctype.h +++ b/klibc/klibc/include/ctype.h @@ -88,7 +88,7 @@ __ctype_inline int ispunct(int __c) __ctype_inline int isspace(int __c) { - return __ctypes[__c] & __ctype_space; + return __ctypes[__c+1] & __ctype_space; } __ctype_inline int isupper(int __c) @@ -101,8 +101,9 @@ __ctype_inline int isxdigit(int __c) return __ctypes[__c+1] & __ctype_xdigit; } -#define _toupper(__c) ((__c) & ~0x20) -#define _tolower(__c) ((__c) | 0x20) +/* Note: this is decimal, not hex, to avoid accidental promotion to unsigned */ +#define _toupper(__c) ((__c) & ~32) +#define _tolower(__c) ((__c) | 32) __ctype_inline int toupper(int __c) { diff --git a/klibc/klibc/include/signal.h b/klibc/klibc/include/signal.h index e383755b20..62c5083dc0 100644 --- a/klibc/klibc/include/signal.h +++ b/klibc/klibc/include/signal.h @@ -11,6 +11,8 @@ #include #include +#include + /* Some architectures don't define these */ #ifndef SA_RESETHAND # define SA_RESETHAND SA_ONESHOT @@ -22,8 +24,6 @@ # define NSIG _NSIG #endif -typedef int sig_atomic_t; - __extern const char * const sys_siglist[]; /* This assumes sigset_t is either an unsigned long or an array of such, diff --git a/klibc/klibc/include/string.h b/klibc/klibc/include/string.h index bce69284ec..1debb55af0 100644 --- a/klibc/klibc/include/string.h +++ b/klibc/klibc/include/string.h @@ -16,12 +16,15 @@ __extern void *memmove(void *, const void *, size_t); __extern void *memset(void *, int, size_t); __extern void *memmem(const void *, size_t, const void *, size_t); __extern void memswap(void *, void *, size_t); +__extern int strcasecmp(const char *, const char *); +__extern int strncasecmp(const char *, const char *, size_t); __extern char *strcat(char *, const char *); __extern char *strchr(const char *, int); __extern int strcmp(const char *, const char *); __extern char *strcpy(char *, const char *); __extern size_t strcspn(const char *, const char *); __extern char *strdup(const char *); +__extern char *strndup(const char *, size_t); __extern char *strerror(int); __extern size_t strlen(const char *); __extern char *strncat(char *, const char *, size_t); diff --git a/klibc/klibc/include/syslog.h b/klibc/klibc/include/syslog.h index a58ef05674..551527a042 100644 --- a/klibc/klibc/include/syslog.h +++ b/klibc/klibc/include/syslog.h @@ -5,8 +5,8 @@ #ifndef _SYSLOG_H #define _SYSLOG_H +#include #include -#include /* Alert levels */ #define LOG_EMERG 0 @@ -49,7 +49,7 @@ __extern void openlog(const char *, int, int); __extern void syslog(int, const char *, ...); +__extern void vsyslog(int, const char *, va_list); __extern void closelog(void); -__extern void vsyslog(int, const char *format, va_list ap); #endif /* _SYSLOG_H */ diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h index 3c51c497a7..36c486f49d 100644 --- a/klibc/klibc/include/unistd.h +++ b/klibc/klibc/include/unistd.h @@ -82,6 +82,7 @@ __extern int ioctl(int, int, void *); __extern int flock(int, int); __extern int fsync(int); __extern int fdatasync(int); +__extern int ftruncate(int, off_t); __extern int pause(void); __extern unsigned int alarm(unsigned int); @@ -103,8 +104,6 @@ __extern int optind, opterr, optopt; __extern int isatty(int); -__extern int ftruncate(int, off_t); - /* Standard file descriptor numbers. */ #define STDIN_FILENO 0 #define STDOUT_FILENO 1 diff --git a/klibc/klibc/strcasecmp.c b/klibc/klibc/strcasecmp.c new file mode 100644 index 0000000000..e583491b35 --- /dev/null +++ b/klibc/klibc/strcasecmp.c @@ -0,0 +1,25 @@ +/* + * strcasecmp.c + * + */ + +#include +#include + +int strcasecmp(const char *s1, const char *s2) +{ + char *n1, *n2; + int i, retval; + + n1 = strdup(s1); + n2 = strdup(s2); + + for (i = 0; i < strlen(n1); i++) + n1[i] = toupper(n1[i]); + for (i = 0; i < strlen(n2); i++) + n2[i] = toupper(n2[i]); + retval = strcmp(n1, n2); + free(n1); + free(n2); + return retval; +} diff --git a/klibc/klibc/strncasecmp.c b/klibc/klibc/strncasecmp.c new file mode 100644 index 0000000000..542493de0f --- /dev/null +++ b/klibc/klibc/strncasecmp.c @@ -0,0 +1,24 @@ +/* + * strncasecmp.c + */ + +#include +#include + +int strncasecmp(const char *s1, const char *s2, size_t n) +{ + char *n1, *n2; + int i, retval; + + n1 = strndup(s1, n); + n2 = strndup(s2, n); + + for (i = 0; i < strlen(n1); i++) + n1[i] = toupper(n1[i]); + for (i = 0; i < strlen(n2); i++) + n2[i] = toupper(n2[i]); + retval = strcmp(n1, n2); + free(n1); + free(n2); + return retval; +} diff --git a/klibc/klibc/strndup.c b/klibc/klibc/strndup.c new file mode 100644 index 0000000000..1b44e6f99a --- /dev/null +++ b/klibc/klibc/strndup.c @@ -0,0 +1,17 @@ +/* + * strndup.c + */ + +#include +#include + +char *strndup(const char *s, size_t n) +{ + int l = n > strlen(s) ? strlen(s)+1 : n+1; + char *d = malloc(l); + + if (d) + memcpy(d, s, l); + d[n] = '\0'; + return d; +} diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c index d40d8633d1..10a2dce405 100644 --- a/klibc/klibc/syslog.c +++ b/klibc/klibc/syslog.c @@ -60,7 +60,7 @@ void vsyslog(int prio, const char *format, va_list ap) if ( *id ) len += sprintf(buf+3, "%s: ", id); - + rv = vsnprintf(buf+len, BUFLEN-len, format, ap); len += rv; From fee6f4150d0d5fbfc1ba74130bac1ae21ce69c81 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 21:59:03 -0800 Subject: [PATCH 0209/4284] [PATCH] get rid of functions in klibc_fixups that are now in klibc --- klibc_fixups.c | 25 ------------------------- klibc_fixups.h | 4 ---- 2 files changed, 29 deletions(-) diff --git a/klibc_fixups.c b/klibc_fixups.c index c12c90fd1c..a99166811c 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -7,29 +7,4 @@ #include #include "klibc_fixups.h" -char *strerror(int errnum) -{ - return "some error"; -} - -int strcasecmp(const char *s1, const char *s2) -{ - char *n1; - char *n2; - int retval; - int i; - - n1 = strdup(s1); - n2 = strdup(s2); - - for (i = 0; i < strlen(n1); ++i) - n1[i] = toupper(n1[i]); - for (i = 0; i < strlen(n2); ++i) - n2[i] = toupper(n2[i]); - retval = strcmp(n1, n2); - free(n1); - free(n2); - return retval; -} - #endif diff --git a/klibc_fixups.h b/klibc_fixups.h index 21a23e7762..a89638ead4 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -4,10 +4,6 @@ #define KLIBC_FIXUPS_H -extern char *strerror(int errnum); - -extern int strcasecmp(const char *s1, const char *s2); - struct group { char *gr_name; /* group name */ char *gr_passwd; /* group password */ From 74894b53f8f9f4de6f269a5c0c0f8ea03baa1587 Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Mon, 24 Nov 2003 22:10:23 -0800 Subject: [PATCH 0210/4284] [PATCH] klibc makefile fixes --- Makefile | 10 +++++++--- tdb/tdb.h | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index af181fe24a..d0c00aa88c 100644 --- a/Makefile +++ b/Makefile @@ -55,6 +55,7 @@ udevdir = ${prefix}/udev/ # to compile vs uClibc, that can be done here as well. CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- CC = $(CROSS)gcc +LD = $(CROSS)gcc AR = $(CROSS)ar STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib @@ -109,6 +110,7 @@ endif ifeq ($(strip $(KLIBC)),true) KLIBC_DIR = klibc/klibc INCLUDE_DIR := $(KLIBC_DIR)/include + include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG # arch specific objects LIBGCC = $(shell $(CC) --print-libgcc) ARCH_LIB_OBJS = \ @@ -117,8 +119,10 @@ ifeq ($(strip $(KLIBC)),true) CRT0 = $(KLIBC_DIR)/crt0.o - LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) - CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(INCLUDE_DIR)/bits32 -I$(GCCINCDIR) -Iklibc/linux/include -D__KLIBC__ + LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) + CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(KLIBC_DIR)/arch/$(ARCH)/include \ + -I$(INCLUDE_DIR)/bits$(BITSIZE) -I$(GCCINCDIR) -Iklibc/linux/include \ + -D__KLIBC__ LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles else @@ -169,7 +173,7 @@ udev_version.h: $(ROOT): $(GEN_HEADERS) $(OBJS) - $(CC) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) clean: diff --git a/tdb/tdb.h b/tdb/tdb.h index 6f3b1ff756..e236b31af5 100644 --- a/tdb/tdb.h +++ b/tdb/tdb.h @@ -25,6 +25,7 @@ extern "C" { #endif +#include /* flags to tdb_store() */ #define TDB_REPLACE 1 From f7b4eca455c7dbf850d984892756f22dbd9ddc3d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 24 Nov 2003 22:27:17 -0800 Subject: [PATCH 0211/4284] [PATCH] overall whitespace + debug text conditioning 01-overall-whitespace+debug-text-conditioning.diff o cleanup whitespace o clarify a few comments o enclose all printed debug string values in '' --- logging.c | 14 +++++++------- namedev.c | 30 +++++++++++++++--------------- namedev.h | 3 +-- udev-add.c | 22 ++++++++++------------ udev-remove.c | 8 ++++---- udev.c | 11 +++++------ udev.h | 1 - udevdb.c | 14 +++++++------- udevdb.h | 6 +++--- 9 files changed, 52 insertions(+), 57 deletions(-) diff --git a/logging.c b/logging.c index 1ca3aed1a9..4815f39fdc 100644 --- a/logging.c +++ b/logging.c @@ -32,26 +32,26 @@ static int logging_init = 0; static unsigned char udev_logname[42]; -static void init_logging (void) +static void init_logging(void) { - snprintf(udev_logname,42,"udev[%d]", getpid()); + snprintf(udev_logname, 42,"udev[%d]", getpid()); - openlog (udev_logname, 0, LOG_DAEMON); + openlog(udev_logname, 0, LOG_DAEMON); logging_init = 1; } /** * log_message - sends a message to the logging facility */ -int log_message (int level, const char *format, ...) +int log_message(int level, const char *format, ...) { va_list args; if (!logging_init) init_logging(); - va_start (args, format); - vsyslog (level, format, args); - va_end (args); + va_start(args, format); + vsyslog(level, format, args); + va_end(args); return 1; } diff --git a/namedev.c b/namedev.c index e640b93c3d..21815b694a 100644 --- a/namedev.c +++ b/namedev.c @@ -216,10 +216,10 @@ static int namedev_init_config(void) int retval = 0; struct config_device dev; - dbg("opening %s to read as config", udev_config_filename); + dbg("opening '%s' to read as config", udev_config_filename); fd = fopen(udev_config_filename, "r"); if (fd == NULL) { - dbg("can't open %s", udev_config_filename); + dbg("can't open '%s'", udev_config_filename); return -ENODEV; } @@ -232,7 +232,7 @@ static int namedev_init_config(void) goto exit; lineno++; - dbg_parse("read %s", temp); + dbg_parse("read '%s'", temp); /* eat the whitespace at the beginning of the line */ while (isspace(*temp)) @@ -413,10 +413,10 @@ static int namedev_init_permissions(void) int retval = 0; struct config_device dev; - dbg("opening %s to read as permissions config", udev_config_permission_filename); + dbg("opening '%s' to read as permissions config", udev_config_permission_filename); fd = fopen(udev_config_permission_filename, "r"); if (fd == NULL) { - dbg("can't open %s", udev_config_permission_filename); + dbg("can't open '%s'", udev_config_permission_filename); return -ENODEV; } @@ -426,7 +426,7 @@ static int namedev_init_permissions(void) if (temp == NULL) break; - dbg_parse("read %s", temp); + dbg_parse("read '%s'", temp); /* eat the whitespace at the beginning of the line */ while (isspace(*temp)) @@ -445,21 +445,21 @@ static int namedev_init_permissions(void) /* parse the line */ temp2 = strsep(&temp, ":"); if (!temp2) { - dbg("cannot parse line: %s", line); + dbg("cannot parse line '%s'", line); continue; } strncpy(dev.name, temp2, sizeof(dev.name)); temp2 = strsep(&temp, ":"); if (!temp2) { - dbg("cannot parse line: %s", line); + dbg("cannot parse line '%s'", line); continue; } strncpy(dev.owner, temp2, sizeof(dev.owner)); temp2 = strsep(&temp, ":"); if (!temp2) { - dbg("cannot parse line: %s", line); + dbg("cannot parse line '%s'", line); continue; } strncpy(dev.group, temp2, sizeof(dev.owner)); @@ -496,7 +496,7 @@ static void build_kernel_number(struct sysfs_class_device *class_dev, struct ude while (isdigit(*(dig-1))) dig--; strfieldcpy(udev->kernel_number, dig); - dbg("kernel_number = %s", udev->kernel_number); + dbg("kernel_number='%s'", udev->kernel_number); } static void apply_format(struct udevice *udev, unsigned char *string) @@ -608,7 +608,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) break; buffer[res] = '\0'; if (res > len) { - dbg("callout len %d too short\n", len); + dbg("callout len %d too short", len); retval = -1; } if (value_set) { @@ -660,7 +660,7 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev strfieldcpy(udev->group, dev->group); } dbg_parse("callout returned matching value '%s', '%s' becomes '%s'" - " - owner='%s', group='%s', mode =%#o", + " - owner='%s', group='%s', mode=%#o", dev->id, class_dev->name, udev->name, dev->owner, dev->group, dev->mode); return 0; @@ -884,11 +884,11 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) * up in the kernel... */ if (strstr(class_dev->path, "block")) { - dbg_parse("looking at block device..."); + dbg_parse("looking at block device"); if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { char path[SYSFS_PATH_MAX]; - dbg_parse("really is a partition..."); + dbg_parse("really is a partition"); strfieldcpy(path, class_dev->path); temp = strrchr(path, '/'); *temp = 0x00; @@ -897,7 +897,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (class_dev_parent == NULL) { dbg("sysfs_open_class_device at '%s' failed", path); } else { - dbg_parse("class_dev_parent->name=%s", class_dev_parent->name); + dbg_parse("class_dev_parent->name='%s'", class_dev_parent->name); if (class_dev_parent->sysdevice) sysfs_device = class_dev_parent->sysdevice; } diff --git a/namedev.h b/namedev.h index 56e6a96c03..5ea843e9b7 100644 --- a/namedev.h +++ b/namedev.h @@ -50,7 +50,6 @@ struct config_device { struct list_head node; enum config_type type; - char bus[BUS_SIZE]; char sysfs_file[FILE_SIZE]; char sysfs_value[VALUE_SIZE]; @@ -58,7 +57,7 @@ struct config_device { char place[PLACE_SIZE]; char kernel_name[NAME_SIZE]; char exec_program[FILE_SIZE]; - + /* what to set the device to */ char name[NAME_SIZE]; char owner[OWNER_SIZE]; diff --git a/udev-add.c b/udev-add.c index 068fd46f27..a71d435e32 100644 --- a/udev-add.c +++ b/udev-add.c @@ -60,12 +60,12 @@ static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice if (dev == NULL) goto exit; - dbg("dev = %s", dev); + dbg("dev='%s'", dev); if (sscanf(dev, "%u:%u", &udev->major, &udev->minor) != 2) goto exit; - dbg("found major = %d, minor = %d", udev->major, udev->minor); + dbg("found major=%d, minor=%d", udev->major, udev->minor); retval = 0; exit: @@ -129,7 +129,7 @@ static int create_node(struct udevice *dev) path, strerror(errno)); return retval; } - dbg("created %s", path); + dbg("created '%s'", path); } *pos = '/'; } @@ -155,7 +155,7 @@ static int create_node(struct udevice *dev) else { struct passwd *pw = getpwnam(dev->owner); if (!pw) - dbg("user unknown: %s", dev->owner); + dbg("user unknown '%s'", dev->owner); else uid = pw->pw_uid; } @@ -169,7 +169,7 @@ static int create_node(struct udevice *dev) else { struct group *gr = getgrnam(dev->group); if (!gr) - dbg("group unknown: %s", dev->group); + dbg("group unknown '%s'", dev->group); else gid = gr->gr_gid; } @@ -194,7 +194,7 @@ static struct sysfs_class_device *get_class_dev(char *device_name) strcpy(dev_path, sysfs_path); strcat(dev_path, device_name); - dbg("looking at %s", dev_path); + dbg("looking at '%s'", dev_path); /* open up the sysfs class device for this thing... */ class_dev = sysfs_open_class_device(dev_path); @@ -202,7 +202,7 @@ static struct sysfs_class_device *get_class_dev(char *device_name) dbg ("sysfs_open_class_device failed"); goto exit; } - dbg("class_dev->name = %s", class_dev->name); + dbg("class_dev->name='%s'", class_dev->name); exit: return class_dev; @@ -225,13 +225,12 @@ static int sleep_for_dev(char *path) while (loop--) { struct stat buf; - dbg("looking for %s", filename); + dbg("looking for '%s'", filename); retval = stat(filename, &buf); if (!retval) goto exit; - /* sleep for a second or two to give the kernel a chance to - * create the dev file */ + /* sleep to give the kernel a chance to create the dev file */ sleep(1); } retval = -ENODEV; @@ -276,7 +275,7 @@ int udev_add_device(char *path, char *subsystem) dbg("udevdb_add_dev failed, but we are going to try to create the node anyway. " "But remove might not work properly for this device."); - dbg("name = %s", dev.name); + dbg("name='%s'", dev.name); retval = create_node(&dev); exit: @@ -285,4 +284,3 @@ exit: return retval; } - diff --git a/udev-remove.c b/udev-remove.c index 1cf5d5134d..0f14a3d685 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -52,14 +52,14 @@ static char *get_name(char *path, int major, int minor) goto exit; } - dbg("%s not found in database, falling back on default name", path); + dbg("'%s' not found in database, falling back on default name", path); temp = strrchr(path, '/'); if (temp == NULL) return NULL; strncpy(name, &temp[1], sizeof(name)); exit: - dbg("name is %s", name); + dbg("name is '%s'", name); return &name[0]; } @@ -74,7 +74,7 @@ static int delete_node(char *name) strncpy(filename, udev_root, sizeof(filename)); strncat(filename, name, sizeof(filename)); - dbg("unlinking %s", filename); + dbg("unlinking '%s'", filename); retval = unlink(filename); if (retval) { dbg("unlink(%s) failed with error '%s'", @@ -104,7 +104,7 @@ static int delete_node(char *name) filename, strerror(errno)); break; } - dbg("removed %s", filename); + dbg("removed '%s'", filename); } } return retval; diff --git a/udev.c b/udev.c index 56dab1f832..a562bc27be 100644 --- a/udev.c +++ b/udev.c @@ -105,7 +105,7 @@ static void get_dirs(void) if (temp) udev_permission = temp; } - dbg("sysfs_path = %s", sysfs_path); + dbg("sysfs_path='%s'", sysfs_path); strncpy(udev_db_filename, udev_config_dir, sizeof(udev_db_filename)); strncat(udev_db_filename, udev_db, sizeof(udev_db_filename)); @@ -141,12 +141,12 @@ int main(int argc, char **argv, char **envp) dbg ("no devpath?"); goto exit; } - dbg("looking at %s", devpath); + dbg("looking at '%s'", devpath); /* we only care about class devices and block stuff */ if (!strstr(devpath, "class") && !strstr(devpath, "block")) { - dbg("not block or class"); + dbg("not a block or class device"); goto exit; } @@ -166,7 +166,7 @@ int main(int argc, char **argv, char **envp) get_dirs(); retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { - dbg("Unable to initialize database."); + dbg("unable to initialize database"); goto exit; } @@ -180,7 +180,7 @@ int main(int argc, char **argv, char **envp) retval = udev_remove_device(devpath, subsystem); else { - dbg("Unknown action: %s", action); + dbg("unknown action '%s'", action); retval = -EINVAL; } udevdb_exit(); @@ -188,4 +188,3 @@ int main(int argc, char **argv, char **envp) exit: return retval; } - diff --git a/udev.h b/udev.h index 6798f13666..8e35cb708f 100644 --- a/udev.h +++ b/udev.h @@ -95,4 +95,3 @@ extern char udev_config_permission_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; #endif - diff --git a/udevdb.c b/udevdb.c index ec67a07962..e0bd39e84b 100644 --- a/udevdb.c +++ b/udevdb.c @@ -54,7 +54,7 @@ int udevdb_add_dev(const char *path, const struct udevice *dev) strcpy(keystr, path); key.dptr = keystr; key.dsize = strlen(keystr) + 1; - + data.dptr = (void *)dev; data.dsize = sizeof(*dev); @@ -79,7 +79,7 @@ struct udevice *udevdb_get_dev(const char *path) dev = malloc(sizeof(*dev)); if (dev == NULL) goto exit; - + memcpy(dev, data.dptr, sizeof(*dev)); exit: free(data.dptr); @@ -99,7 +99,7 @@ int udevdb_delete_dev(const char *path) key.dptr = keystr; key.dsize = strlen(keystr) + 1; - + return tdb_delete(udevdb, key); } @@ -116,8 +116,8 @@ void udevdb_exit(void) /** * udevdb_init: initializes database - * @init_flag: database can either be in memory - UDEVDB_INTERNAL - or - * written to a file with UDEVDB_DEFAULT. + * @init_flag: UDEVDB_INTERNAL - database stays in memory + * UDEVDB_DEFAULT - database is written to a file */ int udevdb_init(int init_flag) { @@ -127,9 +127,9 @@ int udevdb_init(int init_flag) udevdb = tdb_open(udev_db_filename, 0, init_flag, O_RDWR | O_CREAT, 0644); if (udevdb == NULL) { if (init_flag == UDEVDB_INTERNAL) - dbg("Unable to initialize in-memory database"); + dbg("unable to initialize in-memory database"); else - dbg("Unable to initialize database at %s", udev_db_filename); + dbg("unable to initialize database at '%s'", udev_db_filename); return -EINVAL; } return 0; diff --git a/udevdb.h b/udevdb.h index 9935e80e9c..97e1f9bc40 100644 --- a/udevdb.h +++ b/udevdb.h @@ -5,10 +5,10 @@ #define _UDEVDB_H_ /* Udevdb initialization flags */ -#define UDEVDB_DEFAULT 0 /* Defaults database to use file */ -#define UDEVDB_INTERNAL 1 /* Don't store db on disk, use in memory */ +#define UDEVDB_DEFAULT 0 /* defaults database to use file */ +#define UDEVDB_INTERNAL 1 /* don't store db on disk, use in memory */ -/* Function Prototypes */ +/* function prototypes */ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); From 6968d494d76ea0e6e326e23948d2428b53faccf8 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 24 Nov 2003 22:27:20 -0800 Subject: [PATCH 0212/4284] [PATCH] namedev.c strcat tweak 02-namedev.c-strcat-tweak.diff o cat the substitution to the already known end of the string instead of searching it another time --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 21815b694a..83852f9df2 100644 --- a/namedev.c +++ b/namedev.c @@ -514,7 +514,7 @@ static void apply_format(struct udevice *udev, unsigned char *string) case 'b': if (strlen(udev->bus_id) == 0) break; - strcat(string, udev->bus_id); + strcat(pos, udev->bus_id); dbg("substitute bus_id '%s'", udev->bus_id); break; case 'n': From 5499d319057de0ca6407e07ef99069610633f56f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 24 Nov 2003 22:27:23 -0800 Subject: [PATCH 0213/4284] [PATCH] udev-test.pl add subdir test 03-udev-test.pl-add-subdir-test.diff o duplicate existing test and change it to explicitely test the subdir handling --- test/udev-test.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index e4a4ddcda8..2835489238 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -57,6 +57,15 @@ EOF expected => "visor" , conf => < "subdirectory handling", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "sub/direct/ory/visor" , + conf => < Date: Mon, 24 Nov 2003 22:27:25 -0800 Subject: [PATCH 0214/4284] [PATCH] udev.8 tweak numeric id text 04-udev.8-tweak-numeric-id-text.diff o change "return value" to "returned string" o add textual owner/group example for udev.permissions o mention klibc compile as special case for udev.permissions o remove duplicated numeric owner clause --- udev.8 | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/udev.8 b/udev.8 index e9470838b4..1500b3b424 100644 --- a/udev.8 +++ b/udev.8 @@ -104,7 +104,8 @@ the kernel minor number for the device the bus id for the device .TP .B %c -the CALLOUT program return value (this does not work within the PROGRAM field for the obvious reason.) +the CALLOUT program returned string +(this does not work within the PROGRAM field for the obvious reason.) .RE .P A sample \fIudev.conf\fP might look like this: @@ -134,26 +135,25 @@ Permissions and ownership for the created device files may specified at The file consists of a set of lines. All empty lines and lines beginning with a '#' will be ignored. .br -Every line lists a device name followed by numeric owner, group and permission +Every line lists a device name followed by owner, group and permission mode. All values are separated by colons. The name field may end with a wildcard to apply the values to a whole class of devices. .br -If udev was built using glibc, string owner and group names may be used. +If +.B udev +was built using klibc or is used before the user database is accessible (e.g. +.B initrd +), only numeric owner and group values may be used. .sp A sample \fIudev.permissions\fP might look like this: .sp .nf #name:user:group:mode +input/*:root:root:644 ttyUSB1:0:8:0660 -video*:500:500:0660 +video*:root:video:0660 dsp1:::0666 .fi -.P -If -.B -udev -was built using glibc, string owner and group names may be used. - .SH "FILES" .nf .ft B From 49d72e43487164194263d2c80dd27a4627f2169c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 23:14:44 -0800 Subject: [PATCH 0215/4284] [PATCH] changed the default location of the database to /udev/.udev.tdb to be LSB compliant Finally the Debian people can get off my back... --- udev.c | 2 +- udev.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/udev.c b/udev.c index a562bc27be..094905ecc2 100644 --- a/udev.c +++ b/udev.c @@ -107,7 +107,7 @@ static void get_dirs(void) } dbg("sysfs_path='%s'", sysfs_path); - strncpy(udev_db_filename, udev_config_dir, sizeof(udev_db_filename)); + strncpy(udev_db_filename, udev_root, sizeof(udev_db_filename)); strncat(udev_db_filename, udev_db, sizeof(udev_db_filename)); strncpy(udev_config_filename, udev_config_dir, sizeof(udev_config_filename)); diff --git a/udev.h b/udev.h index 8e35cb708f..8994307469 100644 --- a/udev.h +++ b/udev.h @@ -52,7 +52,7 @@ extern int log_message (int level, const char *format, ...) /* filenames for the config and database files */ -#define UDEV_DB "udev.tdb" +#define UDEV_DB ".udev.tdb" #define UDEV_CONFIG_PERMISSION_FILE "udev.permissions" #define UDEV_CONFIG_FILE "udev.config" From befd83cc4ee33f6a557b531d4a1be13472ec67cd Mon Sep 17 00:00:00 2001 From: "azarah@nosferatu.za.org" Date: Mon, 24 Nov 2003 23:25:06 -0800 Subject: [PATCH 0216/4284] [PATCH] more config file parsing robustness udev kept on segfaulting when it was in use, and not having the time (and building it with DEBUG=true showing nothing), I have not tracked it until tonight. Seems like I made a type-o, and forgotten the ':' between one line's group and permission parameters. Attached patch should stop the segfault, and warn at that at least. --- namedev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/namedev.c b/namedev.c index 83852f9df2..391da7efca 100644 --- a/namedev.c +++ b/namedev.c @@ -464,6 +464,10 @@ static int namedev_init_permissions(void) } strncpy(dev.group, temp2, sizeof(dev.owner)); + if (!temp) { + dbg("cannot parse line: %s", line); + continue; + } dev.mode = strtol(temp, NULL, 8); dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", From 5c6f0f141d43703fe84b8c0ddcebf9b79001daf9 Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Mon, 24 Nov 2003 23:41:40 -0800 Subject: [PATCH 0217/4284] [PATCH] Add format modifier for devfs like naming On Monday 24 November 2003 01:29, Greg KH wrote: > I think with the ability to capture the output of the CALLOUT rule, > combined with the ability to put format modifiers in the CALLOUT program > string, we now have everything in place to emulate the existing devfs > naming scheme. Anyone want to verify this or not? I would prefer to have the ability of creating partition nodes in devfs style built-in to udev. Devfs used to call the whole disk e.g. "/dev/dasd/0123/disk" and the partitions "/dev/dasd/0123/part[1-3]". This can obviously be done with a CALLOUT rule, but its common enough to make it a format modifier. AFAIK, this scheme has been used for ide, scsi and dasd disks, which is about 99% of all disks ever connected to Linux. --- namedev.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/namedev.c b/namedev.c index 391da7efca..d183a36329 100644 --- a/namedev.c +++ b/namedev.c @@ -527,6 +527,15 @@ static void apply_format(struct udevice *udev, unsigned char *string) strcat(pos, udev->kernel_number); dbg("substitute kernel number '%s'", udev->kernel_number); break; + case 'D': + if (strlen(udev->kernel_number) == 0) { + strcat(pos, "disk"); + break; + } + strcat(pos, "part"); + strcat(pos, udev->kernel_number); + dbg("substitute kernel number '%s'", udev->kernel_number); + break; case 'm': sprintf(pos, "%u", udev->minor); dbg("substitute minor number '%u'", udev->minor); From 36043f8418c8a0e8decb090c1ea22092fe9c976a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 24 Nov 2003 23:45:38 -0800 Subject: [PATCH 0218/4284] [PATCH] add test and documentation for new %D devfs format modifier --- test/udev-test.pl | 22 ++++++++++++++++++++-- udev.8 | 5 +++++ udev.config | 3 +++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 2835489238..ee2f4e691e 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -25,7 +25,7 @@ my $PWD = $ENV{PWD}; my $sysfs = "sys/"; my $udev_bin = "../udev"; my $udev_root = "udev-root/"; # !!! directory will be removed !!! -my $udev_db = "udev.tdb"; +my $udev_db = ".udev.tdb"; my $perm = "udev.permissions"; my $conf_tmp = "udev-test.config"; @@ -106,6 +106,24 @@ EOF expected => "test-0:0:0:0" , conf => < "devfs disk naming substitution", + subsys => "block", + devpath => "block/sda", + expected => "lun0/disk" , + conf => < "devfs disk naming substitution", + subsys => "block", + devpath => "block/sda/sda2", + expected => "lun0/part2" , + conf => < Date: Mon, 24 Nov 2003 23:47:43 -0800 Subject: [PATCH 0219/4284] [PATCH] libsysfs changes for sysfsutils 0.3.0 Here's the patch to up the library to the sysfsutils-0_3_0 level. The following changes: 1) adds class name to sysfs_class_device structure 2) adds bus to sysfs_device 3) gets rid of code that made assumptions as to bus addresses being unique across buses, which isn't the case. I still owe you: 1) change getpagesize->sysconf. This is in the CVS tree and part of other changes we're currently testing. Patch will follow. 2) you need a function to get a sysfs_class_device's parent. We hadn't considered class devices to have parents, the one example of a multilevel is the block class. We will add this function and send the patch to you. --- libsysfs/libsysfs.h | 36 ++---- libsysfs/sysfs_bus.c | 46 +------ libsysfs/sysfs_class.c | 275 ++++++++++++++++++---------------------- libsysfs/sysfs_device.c | 271 ++++++++++++++++++++------------------- libsysfs/sysfs_driver.c | 167 +++++++----------------- libsysfs/sysfs_utils.c | 40 +++++- 6 files changed, 352 insertions(+), 483 deletions(-) diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index b3ffc467d0..f7e989e242 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -32,8 +32,11 @@ #define SYSFS_FSTYPE_NAME "sysfs" #define SYSFS_PROC_MNTS "/proc/mounts" #define SYSFS_BUS_DIR "/bus" +#define SYSFS_BUS_NAME "bus" #define SYSFS_CLASS_DIR "/class" +#define SYSFS_CLASS_NAME "class" #define SYSFS_BLOCK_DIR "/block" +#define SYSFS_BLOCK_NAME "block" #define SYSFS_DEVICES_DIR "/devices" #define SYSFS_DEVICES_NAME "devices" #define SYSFS_DRIVERS_DIR "/drivers" @@ -42,10 +45,6 @@ #define SYSFS_UNKNOWN "unknown" #define SYSFS_PATH_ENV "SYSFS_PATH" -/* Some "block" subsystem specific #defines */ -#define SYSFS_QUEUE_NAME "queue" -#define SYSFS_IOSCHED_NAME "iosched" - #define SYSFS_PATH_MAX 255 #define SYSFS_NAME_LEN 50 #define SYSFS_BUS_ID_SIZE 20 @@ -89,8 +88,9 @@ struct sysfs_device { struct dlist *children; unsigned char name[SYSFS_NAME_LEN]; unsigned char bus_id[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + unsigned char bus[SYSFS_NAME_LEN]; unsigned char driver_name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; /* for internal use only */ struct sysfs_directory *directory; @@ -119,6 +119,7 @@ struct sysfs_class_device { struct sysfs_device *sysdevice; /* NULL if virtual */ struct sysfs_driver *driver; /* NULL if not implemented */ unsigned char name[SYSFS_NAME_LEN]; + unsigned char classname[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; /* for internal use only */ @@ -185,10 +186,8 @@ extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver); extern void sysfs_close_driver_by_name(struct sysfs_driver *driver); extern struct sysfs_driver *sysfs_open_driver_by_name (const unsigned char *drv_name, const unsigned char *bus, size_t bsize); -extern int sysfs_write_driver_attr(unsigned char *drv, unsigned char *attrib, - unsigned char *value, size_t len); -extern int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib, - unsigned char *value, size_t len); +extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, + const unsigned char *drv, const unsigned char *attrib); /* generic sysfs device access */ extern void sysfs_close_root_device(struct sysfs_root_device *root); @@ -201,10 +200,8 @@ extern struct sysfs_attribute *sysfs_get_device_attr extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); extern struct sysfs_device *sysfs_open_device_by_id (const unsigned char *bus_id, const unsigned char *bus, size_t bsize); -extern int sysfs_write_device_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len); -extern int sysfs_read_device_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len); +extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, + const unsigned char *bus_id, const unsigned char *attrib); /* generic sysfs bus access */ extern void sysfs_close_bus(struct sysfs_bus *bus); @@ -218,8 +215,6 @@ extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, unsigned char *attrname); extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, unsigned char *dev_id); -extern int sysfs_find_device_bus(const unsigned char *dev_id, - unsigned char *busname, size_t bsize); extern int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, size_t bsize); @@ -232,17 +227,14 @@ extern struct sysfs_class *sysfs_open_class(const unsigned char *name); extern struct sysfs_class_device *sysfs_get_class_device (struct sysfs_class *class, unsigned char *name); extern struct sysfs_class_device *sysfs_open_class_device_by_name - (const unsigned char *class, unsigned char *name); + (const unsigned char *class, const unsigned char *name); extern struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *cdev); -extern int sysfs_find_device_class(const unsigned char *bus_id, - unsigned char *classname, size_t bsize); extern struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const unsigned char *name); -extern int sysfs_write_classdev_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len); -extern int sysfs_read_classdev_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len); +extern struct sysfs_attribute *sysfs_open_classdev_attr + (const unsigned char *classname, const unsigned char *dev, + const unsigned char *attrib); #ifdef __cplusplus } diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 19fc275d84..3111154cbc 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -25,12 +25,12 @@ static void sysfs_close_dev(void *dev) { - sysfs_close_device((struct sysfs_device *)dev); + sysfs_close_device((struct sysfs_device *)dev); } static void sysfs_close_drv(void *drv) { - sysfs_close_driver((struct sysfs_driver *)drv); + sysfs_close_driver((struct sysfs_driver *)drv); } /* @@ -423,48 +423,6 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, return rdev; } -/** - * sysfs_find_device_bus: locates the bus a device is on. - * @dev_id: device id. - * @busname: buffer to copy name to - * @bsize: buffer size - * returns 0 with success or -1 with error - */ -int sysfs_find_device_bus(const unsigned char *dev_id, unsigned char *busname, - size_t bsize) -{ - unsigned char subsys[SYSFS_NAME_LEN], *bus = NULL, *curdev = NULL; - struct dlist *buslist = NULL, *device_list = NULL; - - if (dev_id == NULL || busname == NULL) { - errno = EINVAL; - return -1; - } - - strcpy(subsys, SYSFS_BUS_DIR); /* subsys = /bus */ - buslist = sysfs_open_subsystem_list(subsys); - if (buslist != NULL) { - dlist_for_each_data(buslist, bus, char) { - device_list = sysfs_open_bus_devices_list(bus); - if (device_list != NULL) { - dlist_for_each_data(device_list, - curdev, char) { - if (strcmp(dev_id, curdev) == 0) { - strncpy(busname, - bus, bsize); - sysfs_close_list(device_list); - sysfs_close_list(buslist); - return 0; - } - } - sysfs_close_list(device_list); - } - } - sysfs_close_list(buslist); - } - return -1; -} - /** * sysfs_find_driver_bus: locates the bus the driver is on. * @driver: name of the driver to locate diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index cb6ca9d00d..a0273565d5 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -23,7 +23,7 @@ #include "libsysfs.h" #include "sysfs.h" -void sysfs_close_cls_dev(void *dev) +static void sysfs_close_cls_dev(void *dev) { sysfs_close_class_device((struct sysfs_class_device *)dev); } @@ -116,9 +116,17 @@ static struct sysfs_directory *open_class_dir(const unsigned char *name) return NULL; } - strcat(classpath, SYSFS_CLASS_DIR); - strcat(classpath, "/"); - strcat(classpath, name); + /* + * We shall now treat "block" also as a class. Hence, check here + * if "name" is "block" and proceed accordingly + */ + if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { + strcat(classpath, SYSFS_BLOCK_DIR); + } else { + strcat(classpath, SYSFS_CLASS_DIR); + strcat(classpath, "/"); + strcat(classpath, name); + } classdir = sysfs_open_directory(classpath); if (classdir == NULL) { errno = EINVAL; @@ -134,6 +142,39 @@ static struct sysfs_directory *open_class_dir(const unsigned char *name) return classdir; } +/** + * set_classdev_classname: Grabs classname from path + * @cdev: class device to set + * Returns nothing + */ +static void set_classdev_classname(struct sysfs_class_device *cdev) +{ + unsigned char *c = NULL, *e = NULL; + int count = 0; + + c = strstr(cdev->path, SYSFS_CLASS_DIR); + if (c == NULL) + c = strstr(cdev->path, SYSFS_BLOCK_DIR); + else { + c++; + while (c != NULL && *c != '/') + c++; + } + + if (c == NULL) + strcpy(cdev->classname, SYSFS_UNKNOWN); + + else { + c++; + e = c; + while (e != NULL && *e != '/' && *e != '\0') { + e++; + count++; + } + strncpy(cdev->classname, c, count); + } +} + /** * sysfs_open_class_device: Opens and populates class device * @path: path to class device. @@ -178,6 +219,7 @@ struct sysfs_class_device *sysfs_open_class_device(const unsigned char *path) sysfs_read_all_subdirs(dir); cdev->directory = dir; strcpy(cdev->path, dir->path); + set_classdev_classname(cdev); /* get driver and device, if implemented */ if (cdev->directory->links != NULL) { @@ -303,47 +345,73 @@ struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class, name, class_name_equal); } +/** + * get_classdev_path: given the class and a device in the class, return the + * absolute path to the device + * @classname: name of the class + * @clsdev: the class device + * @path: buffer to return path + * @psize: size of "path" + * Returns 0 on SUCCESS or -1 on error + */ +static int get_classdev_path(const unsigned char *classname, + const unsigned char *clsdev, unsigned char *path, size_t len) +{ + if (classname == NULL || clsdev == NULL || path == NULL) { + errno = EINVAL; + return -1; + } + if (sysfs_get_mnt_path(path, len) != 0) { + dprintf("Error getting sysfs mount path\n"); + return -1; + } + if (strcmp(classname, SYSFS_BLOCK_NAME) == 0) { + strcat(path, SYSFS_BLOCK_DIR); + } else { + strcat(path, SYSFS_CLASS_DIR); + strcat(path, "/"); + strcat(path, classname); + } + strcat(path, "/"); + strcat(path, clsdev); + return 0; +} + /** * sysfs_open_class_device_by_name: Locates a specific class_device and returns it. * Class_device must be closed using sysfs_close_class_device * @classname: Class to search * @name: name of the class_device + * + * NOTE: + * Call sysfs_close_class_device() to close the class device */ struct sysfs_class_device *sysfs_open_class_device_by_name - (const unsigned char *classname, unsigned char *name) + (const unsigned char *classname, const unsigned char *name) { - struct sysfs_class *class = NULL; - struct sysfs_class_device *cdev = NULL, *rcdev = NULL; + unsigned char devpath[SYSFS_PATH_MAX]; + struct sysfs_class_device *cdev = NULL; if (classname == NULL || name == NULL) { errno = EINVAL; return NULL; } - class = sysfs_open_class(classname); - if (class == NULL) { - dprintf("Error opening class %s\n", classname); + memset(devpath, 0, SYSFS_PATH_MAX); + if ((get_classdev_path(classname, name, devpath, + SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to device %s on class %s\n", + name, classname); return NULL; } - - cdev = sysfs_get_class_device(class, name); + + cdev = sysfs_open_class_device(devpath); if (cdev == NULL) { dprintf("Error getting class device %s from class %s\n", name, classname); - sysfs_close_class(class); return NULL; } - - rcdev = sysfs_open_class_device(cdev->directory->path); - if (rcdev == NULL) { - dprintf("Error getting class device %s from class %s\n", - name, classname); - sysfs_close_class(class); - return NULL; - } - sysfs_close_class(class); - - return rcdev; + return cdev; } /** @@ -360,53 +428,6 @@ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev) return (cdev->directory->attributes); } -/** - * sysfs_find_device_class: locates the device the device is on - * @bus_id: device to look for - * @classname: buffer to copy class name to - * @bsize: size of buffer - * returns 0 with success and -1 with error - */ -int sysfs_find_device_class(const unsigned char *bus_id, - unsigned char *classname, size_t bsize) -{ - unsigned char class[SYSFS_NAME_LEN], clspath[SYSFS_NAME_LEN]; - unsigned char *cls = NULL, *clsdev = NULL; - struct dlist *clslist = NULL, *clsdev_list = NULL; - - if (bus_id == NULL || classname == NULL) { - errno = EINVAL; - return -1; - } - - strcpy(class, SYSFS_CLASS_DIR); - clslist = sysfs_open_subsystem_list(class); - if (clslist != NULL) { - dlist_for_each_data(clslist, cls, char) { - memset(clspath, 0, SYSFS_NAME_LEN); - strcpy(clspath, SYSFS_CLASS_DIR); - strcat(clspath, "/"); - strcat(clspath, cls); - clsdev_list = sysfs_open_subsystem_list(clspath); - if (clsdev_list != NULL) { - dlist_for_each_data(clsdev_list, - clsdev, char) { - if (strcmp(bus_id, clsdev) == 0) { - strncpy(classname, - cls, bsize); - sysfs_close_list(clsdev_list); - sysfs_close_list(clslist); - return 0; - } - } - sysfs_close_list(clsdev_list); - } - } - sysfs_close_list(clslist); - } - return -1; -} - /** * sysfs_get_classdev_attr: searches class device's attributes by name * @clsdev: class device to look through @@ -433,99 +454,45 @@ struct sysfs_attribute *sysfs_get_classdev_attr } /** - * sysfs_write_classdev_attr: modify writable attribute value for the given - * class device - * @dev: class device name for which the attribute has to be changed - * @attrib: attribute to change - * @value: value to change to - * @len: size of buffer at "value" - * Returns 0 on success and -1 on error - */ -int sysfs_write_classdev_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len) -{ - struct sysfs_class_device *clsdev = NULL; - struct sysfs_attribute *attribute = NULL; - unsigned char class_name[SYSFS_NAME_LEN]; - - if (dev == NULL || attrib == NULL || value == NULL) { - errno = EINVAL; - return -1; - } - - memset(class_name, 0, SYSFS_NAME_LEN); - if ((sysfs_find_device_class(dev, - class_name, SYSFS_NAME_LEN)) < 0) { - dprintf("Class device %s not found\n", dev); - return -1; - } - clsdev = sysfs_open_class_device_by_name(class_name, dev); - if (clsdev == NULL) { - dprintf("Error opening %s in class %s\n", dev, class_name); - return -1; - } - attribute = sysfs_get_directory_attribute(clsdev->directory, attrib); - if (attribute == NULL) { - dprintf("Attribute %s not defined for device %s on class %s\n", - attrib, dev, class_name); - sysfs_close_class_device(clsdev); - return -1; - } - if ((sysfs_write_attribute(attribute, value, len)) < 0) { - dprintf("Error setting %s to %s\n", attrib, value); - sysfs_close_class_device(clsdev); - return -1; - } - sysfs_close_class_device(clsdev); - return 0; -} - -/** - * sysfs_read_classdev_attr: read an attribute for a given class device + * sysfs_open_classdev_attr: read an attribute for a given class device + * @classname: name of the class on which to look * @dev: class device name for which the attribute has to be read * @attrib: attribute to read - * @value: buffer to return value to user - * @len: size of buffer at "value" - * Returns 0 on success and -1 on error + * Returns sysfs_attribute * on SUCCESS and NULL on error + * + * NOTE: + * A call to sysfs_close_attribute() is required to close the + * attribute returned and to free memory */ -int sysfs_read_classdev_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len) +struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname, + const unsigned char *dev, const unsigned char *attrib) { - struct sysfs_class_device *clsdev = NULL; struct sysfs_attribute *attribute = NULL; - unsigned char class_name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; - if (dev == NULL || attrib == NULL || value == NULL) { + if (classname == NULL || dev == NULL || attrib == NULL) { errno = EINVAL; - return -1; + return NULL; } - - memset(class_name, 0, SYSFS_NAME_LEN); - if ((sysfs_find_device_class(dev, - class_name, SYSFS_NAME_LEN)) < 0) { - dprintf("Class device %s not found\n", dev); - return -1; + memset(path, 0, SYSFS_PATH_MAX); + if ((get_classdev_path(classname, dev, path, SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to device %s on class %s\n", + dev, classname); + return NULL; } - clsdev = sysfs_open_class_device_by_name(class_name, dev); - if (clsdev == NULL) { - dprintf("Error opening %s in class %s\n", dev, class_name); - return -1; - } - attribute = sysfs_get_directory_attribute(clsdev->directory, attrib); + strcat(path, "/"); + strcat(path, attrib); + attribute = sysfs_open_attribute(path); if (attribute == NULL) { - dprintf("Attribute %s not defined for device %s on class %s\n", - attrib, dev, class_name); - sysfs_close_class_device(clsdev); - return -1; + dprintf("Error opening attribute %s on class device %s\n", + attrib, dev); + return NULL; } - if (attribute->len > len) { - dprintf("Value length %d is greater that suppled buffer %d\n", - attribute->len, len); - sysfs_close_class_device(clsdev); - return -1; + if ((sysfs_read_attribute(attribute)) != 0) { + dprintf("Error reading attribute %s for class device %s\n", + attrib, dev); + sysfs_close_attribute(attribute); + return NULL; } - strncpy(value, attribute->value, attribute->len); - value[(attribute->len)+1] = 0; - sysfs_close_class_device(clsdev); - return 0; + return attribute; } diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 89704dcd80..fbd046f229 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -23,6 +23,77 @@ #include "libsysfs.h" #include "sysfs.h" +static int confirm_device_bus(struct sysfs_device *dev, + unsigned char *busname, unsigned char *bus_id) +{ + struct sysfs_link *devlink = NULL; + unsigned char devpath[SYSFS_PATH_MAX]; + int result = 0; + + if (busname == NULL || bus_id == NULL) + return -1; + + if (sysfs_get_mnt_path(devpath, SYSFS_PATH_MAX) != 0) + return -1; + + strcat(devpath, SYSFS_BUS_DIR); + strcat(devpath, "/"); + strcat(devpath, busname); + strcat(devpath, SYSFS_DEVICES_DIR); + strcat(devpath, "/"); + strcat(devpath, bus_id); + + devlink = sysfs_open_link(devpath); + if (devlink == NULL) + return -1; + + if (strcmp(devlink->target, dev->path) == 0) + result++; + sysfs_close_link(devlink); + return result; +} + +/** + * get_device_bus: retrieves the bus name the device is on, checks path to + * bus' link to make sure it has correct device. + * @dev: device to get busname. + * returns 0 with success and -1 with error. + */ +static int get_device_bus(struct sysfs_device *dev) +{ + unsigned char subsys[SYSFS_NAME_LEN], *bus = NULL, *curdev = NULL; + struct dlist *buslist = NULL, *device_list = NULL; + + if (dev == NULL) { + errno = EINVAL; + return -1; + } + + strcpy(subsys, SYSFS_BUS_DIR); /* subsys = /bus */ + buslist = sysfs_open_subsystem_list(subsys); + if (buslist != NULL) { + dlist_for_each_data(buslist, bus, char) { + device_list = sysfs_open_bus_devices_list(bus); + if (device_list != NULL) { + dlist_for_each_data(device_list, + curdev, char) { + if (strcmp(dev->bus_id, curdev) == 0 + && confirm_device_bus(dev, bus, + curdev) > 0) { + strcpy(dev->bus, bus); + sysfs_close_list(device_list); + sysfs_close_list(buslist); + return 0; + } + } + sysfs_close_list(device_list); + } + } + sysfs_close_list(buslist); + } + return -1; +} + /** * sysfs_close_device_tree: closes every device in the supplied tree, * closing children only. @@ -150,6 +221,9 @@ struct sysfs_device *sysfs_open_device(const unsigned char *path) * implies that the dev->name and dev->bus_id contain same data. */ strncpy(dev->name, sdir->name, SYSFS_NAME_LEN); + + if (get_device_bus(dev) != 0) + strcpy(dev->bus, SYSFS_UNKNOWN); return dev; } @@ -338,55 +412,6 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) return (device->directory->attributes); } -/** - * sysfs_open_device_by_id: open a device by id (use the "bus" subsystem) - * @bus_id: bus_id of the device to open - has to be the "bus_id" in - * /sys/bus/xxx/devices - * @bus: bus the device belongs to - * @bsize: size of the bus buffer - * returns struct sysfs_device if found, NULL otherwise - * NOTE: - * 1. Use sysfs_close_device to close the device - * 2. Bus the device is on must be supplied - * Use sysfs_find_device_bus to get the bus name - */ -struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, - const unsigned char *bus, size_t bsize) -{ - char sysfs_path[SYSFS_PATH_MAX], device_path[SYSFS_PATH_MAX]; - struct sysfs_device *device = NULL; - - if (bus_id == NULL || bus == NULL) { - errno = EINVAL; - return NULL; - } - memset(sysfs_path, 0, SYSFS_PATH_MAX); - if ((sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX)) != 0) { - dprintf("Error getting sysfs mount path\n"); - return NULL; - } - strcat(sysfs_path, SYSFS_BUS_DIR); - strcat(sysfs_path, "/"); - strncat(sysfs_path, bus, bsize); - strcat(sysfs_path, SYSFS_DEVICES_DIR); - strcat(sysfs_path, "/"); - strcat(sysfs_path, bus_id); - - /* devices under /sys/bus/xxx/devices are links to devices subsystem */ - if ((sysfs_get_link(sysfs_path, device_path, SYSFS_PATH_MAX)) < 0) { - dprintf("Error getting device path\n"); - return NULL; - } - - device = sysfs_open_device(device_path); - if (device == NULL) { - dprintf("Error opening device %s\n", bus_id); - return NULL; - } - - return device; -} - /** * get_device_absolute_path: looks up the bus the device is on, gets * absolute path to the device @@ -395,29 +420,24 @@ struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, * @psize: size of "path" * Returns 0 on success -1 on failure */ -static int get_device_absolute_path(const unsigned char *device, - unsigned char *path, size_t psize) +static int get_device_absolute_path(const unsigned char *device, + const unsigned char *bus, unsigned char *path, size_t psize) { - unsigned char bus_name[SYSFS_NAME_LEN], bus_path[SYSFS_PATH_MAX]; + unsigned char bus_path[SYSFS_NAME_LEN]; if (device == NULL || path == NULL) { errno = EINVAL; return -1; } - memset(bus_name, 0, SYSFS_NAME_LEN); memset(bus_path, 0, SYSFS_NAME_LEN); - if ((sysfs_find_device_bus(device, bus_name, SYSFS_NAME_LEN)) != 0) { - dprintf("Device %s not found\n", device); - return -1; - } if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX) != 0) { dprintf ("Sysfs not supported on this system\n"); return -1; } strcat(bus_path, SYSFS_BUS_DIR); strcat(bus_path, "/"); - strcat(bus_path, bus_name); + strcat(bus_path, bus); strcat(bus_path, SYSFS_DEVICES_DIR); strcat(bus_path, "/"); strcat(bus_path, device); @@ -433,106 +453,85 @@ static int get_device_absolute_path(const unsigned char *device, } /** - * sysfs_write_device_attr: modify a "writable" attribute for the given device - * @dev: device bus_id for which attribute has to be changed - * @attrib: attribute to change - * @value: value to change to - * @len: "value" length to write - * Returns 0 on success -1 on error - */ -int sysfs_write_device_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len) + * sysfs_open_device_by_id: open a device by id (use the "bus" subsystem) + * @bus_id: bus_id of the device to open - has to be the "bus_id" in + * /sys/bus/xxx/devices + * @bus: bus the device belongs to + * @bsize: size of the bus buffer + * returns struct sysfs_device if found, NULL otherwise + * NOTE: + * 1. Use sysfs_close_device to close the device + * 2. Bus the device is on must be supplied + * Use sysfs_find_device_bus to get the bus name + */ +struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, + const unsigned char *bus, size_t bsize) { - struct sysfs_attribute *attribute = NULL; - unsigned char devpath[SYSFS_PATH_MAX]; + char sysfs_path[SYSFS_PATH_MAX]; + struct sysfs_device *device = NULL; - if (dev == NULL || attrib == NULL || value == NULL) { + if (bus_id == NULL || bus == NULL) { errno = EINVAL; - return -1; + return NULL; + } + memset(sysfs_path, 0, SYSFS_PATH_MAX); + if ((get_device_absolute_path(bus_id, bus, sysfs_path, + SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to device %s\n", bus_id); + return NULL; } - memset(devpath, 0, SYSFS_PATH_MAX); - if ((get_device_absolute_path(dev, devpath, SYSFS_PATH_MAX)) != 0) { - dprintf("Error finding absolute path to device %s\n", dev); - return -1; + device = sysfs_open_device(sysfs_path); + if (device == NULL) { + dprintf("Error opening device %s\n", bus_id); + return NULL; } - strcat(devpath, "/"); - strcat(devpath, attrib); - attribute = sysfs_open_attribute(devpath); - if (attribute == NULL) { - dprintf("Attribute %s could not be retrieved for device %s\n", - attrib, dev); - return -1; - } - if (attribute->method & SYSFS_METHOD_SHOW) { - if ((sysfs_read_attribute(attribute)) != 0) { - dprintf("Error reading attribute %s for device %s\n", - attrib, dev); - sysfs_close_attribute(attribute); - return -1; - } - } - if ((sysfs_write_attribute(attribute, value, len)) < 0) { - dprintf("Error setting %s to %s\n", attrib, value); - sysfs_close_attribute(attribute); - return -1; - } - sysfs_close_attribute(attribute); - return 0; + + return device; } -/** - * sysfs_read_device_attr: read an attribute of the given device - * @dev: device bus_id for which attribute has to be changed - * @attrib: attribute to read - * @value: buffer to return value in - * @len: size of buffer available - * Returns 0 on success -1 on error - */ -int sysfs_read_device_attr(unsigned char *dev, unsigned char *attrib, - unsigned char *value, size_t len) +/* + * sysfs_open_device_attr: open the given device's attribute + * @bus: Bus on which to look + * @dev_id: device for which attribute is required + * @attrname: name of the attribute to look for + * Returns struct sysfs_attribute on success and NULL on failure + * + * NOTE: + * A call to sysfs_close_attribute() is required to close + * the attribute returned and free memory. + */ +struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, + const unsigned char *bus_id, const unsigned char *attrib) { struct sysfs_attribute *attribute = NULL; unsigned char devpath[SYSFS_PATH_MAX]; - - if (dev == NULL || attrib == NULL || value == NULL) { - errno = EINVAL; - return -1; - } + if (bus == NULL || bus_id == NULL || attrib == NULL) { + errno = EINVAL; + return NULL; + } + memset(devpath, 0, SYSFS_PATH_MAX); - if ((get_device_absolute_path(dev, devpath, SYSFS_PATH_MAX)) != 0) { - dprintf("Error finding absolute path to device %s\n", dev); - return -1; + if ((get_device_absolute_path(bus_id, bus, devpath, + SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to device %s\n", bus_id); + return NULL; } strcat(devpath, "/"); strcat(devpath, attrib); attribute = sysfs_open_attribute(devpath); if (attribute == NULL) { dprintf("Error opening attribute %s for device %s\n", - attrib, dev); - return -1; - } - if (!(attribute->method & SYSFS_METHOD_SHOW)) { - dprintf("Show method not supported for attribute %s\n", - attrib); - sysfs_close_attribute(attribute); - return -1; + attrib, bus_id); + return NULL; } if ((sysfs_read_attribute(attribute)) != 0) { dprintf("Error reading attribute %s for device %s\n", - attrib, dev); + attrib, bus_id); sysfs_close_attribute(attribute); - return -1; + return NULL; } - if (attribute->len > len) { - dprintf("Value length %d is larger than supplied buffer %d\n", - attribute->len, len); - sysfs_close_attribute(attribute); - return -1; - } - strncpy(value, attribute->value, attribute->len); - value[(attribute->len)+1] = 0; - sysfs_close_attribute(attribute); - return 0; + return attribute; } + diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index f8e842c65c..0011177e99 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -162,6 +162,35 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) return(driver->directory->links); } +/** + * get_driver_path: looks up the bus the driver is on and builds path to + * the driver. + * @bus: bus on which to search + * @drv: driver to look for + * @path: buffer to return path to driver + * @psize: size of "path" + * Returns 0 on success and -1 on error + */ +static int get_driver_path(const unsigned char *bus, const unsigned char *drv, + unsigned char *path, size_t psize) +{ + if (bus == NULL || drv == NULL || path == NULL) { + errno = EINVAL; + return -1; + } + if (sysfs_get_mnt_path(path, psize) != 0) { + dprintf("Error getting sysfs mount path\n"); + return -1; + } + strcat(path, SYSFS_BUS_DIR); + strcat(path, "/"); + strcat(path, bus); + strcat(path, SYSFS_DRIVERS_DIR); + strcat(path, "/"); + strcat(path, drv); + return 0; +} + /** * sysfs_open_driver_by_name: open a driver by name and return the bus * the driver is on. @@ -188,16 +217,10 @@ struct sysfs_driver *sysfs_open_driver_by_name(const unsigned char *drv_name, } memset(path, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) { - dprintf("Error getting sysfs mount path\n"); + if (get_driver_path(bus, drv_name, path, SYSFS_PATH_MAX) != 0) { + dprintf("Error getting to driver %s\n", drv_name); return NULL; } - strcat(path, SYSFS_BUS_DIR); - strcat(path, "/"); - strcat(path, bus); - strcat(path, SYSFS_DRIVERS_DIR); - strcat(path, "/"); - strcat(path, drv_name); driver = sysfs_open_driver(path); if (driver == NULL) { dprintf("Could not open driver %s\n", drv_name); @@ -224,114 +247,33 @@ struct sysfs_driver *sysfs_open_driver_by_name(const unsigned char *drv_name, return driver; } -/** - * get_driver_path: looks up the bus the driver is on and builds path to - * the driver. - * @drv: driver to look for - * @path: buffer to return path to driver - * @psize: size of "path" - * Returns 0 on success and -1 on error - */ -static int get_driver_path(const unsigned char *drv, - unsigned char *path, size_t psize) -{ - unsigned char bus_name[SYSFS_NAME_LEN]; - - if (drv == NULL || path == NULL) { - errno = EINVAL; - return -1; - } - memset(bus_name, 0, SYSFS_NAME_LEN); - memset(path, 0, SYSFS_PATH_MAX); - if ((sysfs_find_driver_bus(drv, bus_name, SYSFS_NAME_LEN)) < 0) { - dprintf("Driver %s not found\n", drv); - return -1; - } - if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) { - dprintf("Error getting sysfs mount path\n"); - return -1; - } - strcat(path, SYSFS_BUS_DIR); - strcat(path, "/"); - strcat(path, bus_name); - strcat(path, SYSFS_DRIVERS_DIR); - strcat(path, "/"); - strcat(path, drv); - fprintf(stdout, "get_driver_path %s\n", path); - return 0; -} /** - * sysfs_write_driver_attr: modify "writable" driver attribute - * @drv: driver whose attribute has to be modified - * @attrib: Attribute to be modified - * @value: Value to change to - * Returns 0 on success -1 on failure - */ -int sysfs_write_driver_attr(unsigned char *drv, unsigned char *attrib, - unsigned char *value, size_t len) -{ - struct sysfs_attribute *attribute = NULL; - unsigned char path[SYSFS_PATH_MAX]; - - if (drv == NULL || attrib == NULL || value == NULL) { - errno = EINVAL; - return -1; - } - - memset(path, 0, SYSFS_PATH_MAX); - if ((get_driver_path(drv, path, SYSFS_PATH_MAX)) != 0) { - dprintf("Error getting to driver %s\n", drv); - return -1; - } - strcat(path, "/"); - strcat(path, attrib); - attribute = sysfs_open_attribute(path); - if (attribute == NULL) { - dprintf("Attribute %s could not be retrieved for driver %s\n", - attrib, drv); - return -1; - } - if (attribute->method & SYSFS_METHOD_SHOW) { - if ((sysfs_read_attribute(attribute)) != 0) { - dprintf("Error reading attribute %s for driver %s\n", - attrib, drv); - sysfs_close_attribute(attribute); - return -1; - } - } - if ((sysfs_write_attribute(attribute, value, len)) < 0) { - dprintf("Error setting %s to %s\n", attrib, value); - sysfs_close_attribute(attribute); - return -1; - } - sysfs_close_attribute(attribute); - return 0; -} - -/** - * sysfs_read_driver_attr: read the user supplied driver attribute + * sysfs_open_driver_attr: read the user supplied driver attribute + * @bus: bus on which to look * @drv: driver whose attribute has to be read * @attrib: Attribute to be read - * @value: Buffer to return the read value - * @len: Length of the buffer "value" - * Returns 0 on success -1 on failure + * Returns struct sysfs_attribute on success and NULL on failure + * + * NOTE: + * A call to sysfs_close_attribute() is required to close the + * attribute returned and to free memory */ -int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib, - unsigned char *value, size_t len) +struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, + const unsigned char *drv, const unsigned char *attrib) { struct sysfs_attribute *attribute = NULL; unsigned char path[SYSFS_PATH_MAX]; - if (drv == NULL || attrib == NULL || value == NULL) { + if (bus == NULL || drv == NULL || attrib == NULL) { errno = EINVAL; - return -1; + return NULL; } memset(path, 0, SYSFS_NAME_LEN); - if ((get_driver_path(drv, path, SYSFS_PATH_MAX)) != 0) { + if ((get_driver_path(bus, drv, path, SYSFS_PATH_MAX)) != 0) { dprintf("Error getting to driver %s\n", drv); - return -1; + return NULL; } strcat(path, "/"); strcat(path, attrib); @@ -339,29 +281,14 @@ int sysfs_read_driver_attr(unsigned char *drv, unsigned char *attrib, if (attribute == NULL) { dprintf("Error opening attribute %s for driver %s\n", attrib, drv); - return -1; - } - if (!(attribute->method & SYSFS_METHOD_SHOW)) { - dprintf("Show method not supported for attribute %s\n", - attrib); - sysfs_close_attribute(attribute); - return -1; + return NULL; } if ((sysfs_read_attribute(attribute)) != 0) { dprintf("Error reading attribute %s for driver %s\n", attrib, drv); sysfs_close_attribute(attribute); - return -1; + return NULL; } - if (attribute->len > len) { - dprintf("Value length %d is larger than supplied buffer %d\n", - attribute->len, len); - sysfs_close_attribute(attribute); - return -1; - } - strncpy(value, attribute->value, attribute->len); - value[(attribute->len)+1] = 0; - sysfs_close_attribute(attribute); - return 0; + return attribute; } diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 3e50bc6120..4e96051c78 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -92,7 +92,7 @@ int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) return -1; } sysfs_path = getenv(SYSFS_PATH_ENV); - if (sysfs_path != NULL) + if (sysfs_path != NULL) strncpy(mnt_path, sysfs_path, len); else ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, mnt_path, len); @@ -109,13 +109,19 @@ int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, size_t len) { + unsigned char tmp[SYSFS_PATH_MAX]; unsigned char *n = NULL; if (path == NULL || name == NULL) { errno = EINVAL; return -1; } - n = strrchr(path, '/'); + memset(tmp, 0, SYSFS_PATH_MAX); + strcpy(tmp, path); + n = &tmp[strlen(tmp)-1]; + if (strncmp(n, "/", 1) == 0) + *n = '\0'; + n = strrchr(tmp, '/'); if (n == NULL) { errno = EINVAL; return -1; @@ -169,10 +175,7 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) if (*s == '/') count++; } - - if (s == NULL) - return -1; - + strncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir))); strncpy(target, devdir, len); @@ -184,7 +187,7 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) * sysfs_del_name: free function for sysfs_open_subsystem_list * @name: memory area to be freed */ -void sysfs_del_name(void *name) +static void sysfs_del_name(void *name) { free(name); } @@ -210,8 +213,10 @@ void sysfs_close_list(struct dlist *list) struct dlist *sysfs_open_subsystem_list(unsigned char *name) { unsigned char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL; + unsigned char *c = NULL; struct sysfs_directory *dir = NULL, *cur = NULL; struct dlist *list = NULL; + struct stat astats; if (name == NULL) return NULL; @@ -251,6 +256,27 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) } } sysfs_close_directory(dir); + /* + * We are now considering "block" as a "class". Hence, if the subsys + * name requested here is "class", verify if "block" is supported on + * this system and return the same. + */ + if (strcmp(name, SYSFS_CLASS_DIR) == 0) { + c = strstr(sysfs_path, SYSFS_CLASS_NAME); + if (c == NULL) + goto out; + strcpy(c, SYSFS_BLOCK_NAME); + if ((lstat(sysfs_path, &astats)) != 0) { + dprintf("stat() failed\n"); + goto out; + } + if (S_ISDIR(astats.st_mode)) { + subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); + strcpy(subsys_name, SYSFS_BLOCK_NAME); + dlist_unshift(list, subsys_name); + } + } +out: return list; } From b376d32cb462455053061d2cf3da3ac640fd37ee Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Wed, 26 Nov 2003 17:31:59 -0800 Subject: [PATCH 0220/4284] [PATCH] quick fix for libsysfs bus There seems to be a mismatch in udev and in libsysfs as to what to expect if the mnt point has a slash on the end or not. If I use the included patch, it breaks something in udev. If I patch sysfs_get_mnt_path I break udev as well because what you're expecting. I need to sit down and go through the library and creaate a rule as to trailing slashes. Adding the env brought this to light. --- libsysfs/sysfs_device.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index fbd046f229..2a5353e6f7 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -28,6 +28,7 @@ static int confirm_device_bus(struct sysfs_device *dev, { struct sysfs_link *devlink = NULL; unsigned char devpath[SYSFS_PATH_MAX]; + unsigned char *s = NULL; int result = 0; if (busname == NULL || bus_id == NULL) @@ -36,6 +37,9 @@ static int confirm_device_bus(struct sysfs_device *dev, if (sysfs_get_mnt_path(devpath, SYSFS_PATH_MAX) != 0) return -1; + s = &devpath[strlen(devpath)-1]; + if (strncmp(s, "/", 1) == 0) + *s = '\0'; strcat(devpath, SYSFS_BUS_DIR); strcat(devpath, "/"); strcat(devpath, busname); From 137af0cc47a387b91f1216e7a888db54257d51e3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 26 Nov 2003 17:45:05 -0800 Subject: [PATCH 0221/4284] [PATCH] fix problem where we were not looking at the BUS value. --- namedev.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/namedev.c b/namedev.c index d183a36329..d45a827083 100644 --- a/namedev.c +++ b/namedev.c @@ -124,6 +124,8 @@ static int add_dev(struct config_device *new_dev) struct config_device *dev = list_entry(tmp, struct config_device, node); if (strncmp_wildcard(dev->name, new_dev->name, sizeof(dev->name))) continue; + if (strncmp(dev->bus, new_dev->bus, sizeof(dev->name))) + continue; copy_var(dev, new_dev, type); copy_var(dev, new_dev, mode); copy_string(dev, new_dev, bus); @@ -132,6 +134,7 @@ static int add_dev(struct config_device *new_dev) copy_string(dev, new_dev, id); copy_string(dev, new_dev, place); copy_string(dev, new_dev, kernel_name); + copy_string(dev, new_dev, exec_program); copy_string(dev, new_dev, owner); copy_string(dev, new_dev, group); return 0; @@ -650,7 +653,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) return retval; } -static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev) +static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; struct list_head *tmp; @@ -660,6 +663,12 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev if (dev->type != CALLOUT) continue; + if (sysfs_device) { + dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + if (strcasecmp(dev->bus, sysfs_device->bus) != 0) + continue; + } + /* substitute anything that needs to be in the program name */ apply_format(udev, dev->exec_program); if (exec_callout(dev, udev->callout_value, NAME_SIZE)) @@ -692,6 +701,12 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, if (dev->type != LABEL) continue; + if (sysfs_device) { + dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + if (strcasecmp(dev->bus, sysfs_device->bus) != 0) + continue; + } + dbg_parse("look for device attribute '%s'", dev->sysfs_file); /* try to find the attribute in the class device directory */ tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); @@ -747,6 +762,10 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, if (dev->type != NUMBER) continue; + dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + if (strcasecmp(dev->bus, sysfs_device->bus) != 0) + continue; + found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); @@ -795,6 +814,10 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude if (dev->type != TOPOLOGY) continue; + dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + if (strcasecmp(dev->bus, sysfs_device->bus) != 0) + continue; + found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); @@ -826,7 +849,7 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude return -ENODEV; } -static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev) +static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; struct list_head *tmp; @@ -921,6 +944,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (sysfs_device) { dbg_parse("sysfs_device->path='%s'", sysfs_device->path); dbg_parse("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + dbg_parse("sysfs_device->bus='%s'", sysfs_device->bus); strfieldcpy(udev->bus_id, sysfs_device->bus_id); } else { dbg_parse("class_dev->name = '%s'", class_dev->name); @@ -929,7 +953,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) build_kernel_number(class_dev, udev); /* rules are looked at in priority order */ - retval = do_callout(class_dev, udev); + retval = do_callout(class_dev, udev, sysfs_device); if (retval == 0) goto found; @@ -945,7 +969,7 @@ static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) if (retval == 0) goto found; - retval = do_replace(class_dev, udev); + retval = do_replace(class_dev, udev, sysfs_device); if (retval == 0) goto found; From 772558f4e9e981ca8f68026457589784028c730b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 26 Nov 2003 17:45:26 -0800 Subject: [PATCH 0222/4284] [PATCH] add test for checking the BUS value. --- test/udev-test.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index ee2f4e691e..3f48de8f3e 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -124,6 +124,17 @@ EOF expected => "lun0/part2" , conf => < "callout bus type", + subsys => "block", + devpath => "block/sda", + expected => "scsi-0:0:0:0" , + conf => < Date: Mon, 1 Dec 2003 23:50:09 -0800 Subject: [PATCH 0223/4284] [PATCH] fix udev parallel builds with klibc I can't build udev with make -j9. Here's a patch to fix it. --- Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index d0c00aa88c..6c8b311f4e 100644 --- a/Makefile +++ b/Makefile @@ -133,9 +133,13 @@ else LDFLAGS = --static endif -all: $(LIBC) $(ROOT) +all: $(ROOT) -$(ARCH_LIB_OBJS) : +$(ROOT): $(LIBC) + +$(ARCH_LIB_OBJS) : $(CRT0) + +$(CRT0): $(MAKE) -C klibc TDB = tdb/tdb.o \ @@ -171,8 +175,9 @@ udev_version.h: @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ +$(OBJS): $(GEN_HEADERS) -$(ROOT): $(GEN_HEADERS) $(OBJS) +$(ROOT): $(OBJS) $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) From 359618cd6ed05adcad97380f51790198ff653f87 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Tue, 2 Dec 2003 00:16:32 -0800 Subject: [PATCH 0224/4284] [PATCH] udev-007/extras/multipath update here is a clean-up patch : * removes sg_err.[ch] deps * makes sure the core code play nice with klibc * port the sysfs calls to dlist helpers * links against udev's sysfs (need libsysfs.a & dlist.a) * finally define DM_TARGET as "multipath" as Joe posted the code today (not tested yet) * push version forward (do you want it in sync with udev version?) libdevmapper doesn't play well with klibc, so I wasn't able to produce a static binary yet. Help needed here ... as I don't want to fall back to merge libdevmapper code in the core. It compiles here and doesn't segfault. --- extras/multipath/Makefile | 11 ++++----- extras/multipath/main.c | 43 ++++++++++++++++++++--------------- extras/multipath/main.h | 17 ++++++++++---- extras/multipath/sg_include.h | 1 - 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index 0835d7a2c6..9e0ce124c6 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -9,10 +9,10 @@ exec_prefix = ${prefix} bindir = ${exec_prefix}/bin CC = gcc -CFLAGS = -g -O2 -Wall -Wunused -Wstrict-prototypes -LDFLAGS = -lsysfs -ldevmapper +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc -I../../klibc/klibc/include -I../../klibc/klibc/include/bits32 -I/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/include -I../../klibc/linux/include -I../../libsysfs -I. +LDFLAGS = -lsysfs -ldevmapper -ldlist -OBJS = main.o sg_err.o +OBJS = main.o all: $(EXEC) strip $(EXEC) @@ -20,7 +20,7 @@ all: $(EXEC) @echo "Make complete" $(EXEC): $(OBJS) - $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) + $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) clean: rm -f core *.o $(EXEC) @@ -30,5 +30,4 @@ install: install -m 755 $(EXEC) $(bindir)/ # Code dependencies -main.o: main.c main.h sg_err.h sg_include.h -sg_err.o: sg_err.c sg_err.h sg_include.h +main.o: main.c main.h sg_include.h diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 0ed74c52a9..b5ab664433 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,6 @@ static int do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, void *resp, int mx_resp_len, int noisy) { - int res; unsigned char inqCmdBlk[INQUIRY_CMDLEN] = { INQUIRY_CMD, 0, 0, 0, 0, 0 }; unsigned char sense_b[SENSE_BUFF_LEN]; @@ -61,14 +59,27 @@ do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, perror("SG_IO (inquiry) error"); return -1; } - res = sg_err_category3(&io_hdr); - switch (res) { - case SG_ERR_CAT_CLEAN: - case SG_ERR_CAT_RECOVERED: + + /* treat SG_ERR here to get rid of sg_err.[ch] */ + io_hdr.status &= 0x7e; + if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && + (0 == io_hdr.driver_status)) return 0; - default: - return -1; + if ((SCSI_CHECK_CONDITION == io_hdr.status) || + (SCSI_COMMAND_TERMINATED == io_hdr.status) || + (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { + if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { + int sense_key; + unsigned char * sense_buffer = io_hdr.sbp; + if (sense_buffer[0] & 0x2) + sense_key = sense_buffer[1] & 0xf; + else + sense_key = sense_buffer[2] & 0xf; + if(RECOVERED_ERROR == sense_key) + return 0; + } } + return -1; } static int @@ -191,7 +202,7 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) int sg_fd; struct sysfs_directory * sdir; struct sysfs_directory * devp; - struct sysfs_dlink * linkp; + struct sysfs_link * linkp; char buff[FILE_NAME_SIZE]; char block_path[FILE_NAME_SIZE]; @@ -199,17 +210,15 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sprintf(block_path, "%s/block", conf->sysfs_path); sdir = sysfs_open_directory(block_path); sysfs_read_directory(sdir); - devp = sdir->subdirs; - while (devp != NULL) { + dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { sysfs_read_directory(devp); - linkp = devp->links; - while (linkp != NULL) { + if(devp->links == NULL) + continue; + dlist_for_each_data(devp->links, linkp, struct sysfs_link) { if (!strncmp(linkp->name, "device", 6)) break; - linkp = linkp->next; } if (linkp == NULL) { - devp = devp->next; continue; } @@ -217,21 +226,19 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sprintf(all_paths[k].sg_dev, "/dev/%s", buff); strcpy(all_paths[k].dev, all_paths[k].sg_dev); if ((sg_fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) { - devp = devp->next; continue; } get_lun_strings(sg_fd, &all_paths[k]); get_unique_id(sg_fd, &all_paths[k]); all_paths[k].state = do_tur(sg_fd); close(sg_fd); - basename(linkp->target->path, buff); + basename(linkp->target, buff); sscanf(buff, "%i:%i:%i:%i", &all_paths[k].sg_id.host_no, &all_paths[k].sg_id.channel, &all_paths[k].sg_id.scsi_id, &all_paths[k].sg_id.lun); k++; - devp = devp->next; } sysfs_close_directory(sdir); diff --git a/extras/multipath/main.h b/extras/multipath/main.h index 43a24ac7bc..019cb843a8 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -21,7 +21,16 @@ /* local includes */ #include "sg_include.h" -#include "sg_err.h" + +/* exerpt from "sg_err.h" */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SG_ERR_DRIVER_SENSE 0x08 + +/* exerpt from "scsi.h" */ +#define RECOVERED_ERROR 0x01 +#define SCSI_IOCTL_GET_IDLUN 0x5382 +#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 /* global defs */ #define WWID_SIZE 33 @@ -37,7 +46,7 @@ #define TUR_CMD_LEN 6 #define MX_ALLOC_LEN 255 #define BLKGETSIZE _IO(0x12,96) -#define DM_TARGET "striped" +#define DM_TARGET "multipath" #define PINDEX(x,y) mp[(x)].pindex[(y)] @@ -96,8 +105,8 @@ struct env { /* Build version */ #define PROG "multipath" -#define VERSION_CODE 0x000005 -#define DATE_CODE 0x120903 +#define VERSION_CODE 0x000006 +#define DATE_CODE 0x271103 #define MULTIPATH_VERSION(version) \ (version >> 16) & 0xFF, \ diff --git a/extras/multipath/sg_include.h b/extras/multipath/sg_include.h index 6b6dd6f372..460506826e 100644 --- a/extras/multipath/sg_include.h +++ b/extras/multipath/sg_include.h @@ -9,7 +9,6 @@ #include #else #include - #include #endif #endif From c076a2bde406e617ebfeda6b921d1db89eb1a9f6 Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Tue, 2 Dec 2003 00:26:46 -0800 Subject: [PATCH 0225/4284] [PATCH] Build failure - missing linux/limits.h include? MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Tuesday 25 November 2003 00:12, Chris Larson wrote: > udev fails to compile here unless I'm doing a KLIBC build.  The reason > appears to be that the normal limits.h in the gcc inc dir doesn't pull > in linux/limits.h, whereas the limits.h out in the klibc include dirs > does.  I'd think it'd be best to add a #include to > udev.h directly, since it uses PATH_MAX. No, don't include kernel headers directly if you can avoid it. The problem you are referring to seems to be with old tool chains, I have the same symptom with my s390 gcc-2.95/glibc-2.1.3. Including instead of seems to fix it. --- udev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.h b/udev.h index 8994307469..0c1951ad78 100644 --- a/udev.h +++ b/udev.h @@ -24,7 +24,7 @@ #define UDEV_H #include "libsysfs/libsysfs.h" -#include +#include #ifdef DEBUG #include From bfd8a5d0f7361b6cb396eee7cdd686138ecd2066 Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Tue, 2 Dec 2003 00:44:48 -0800 Subject: [PATCH 0226/4284] [PATCH] ARCH detection for ppc I'm not sure why ppc is converted to powerpc, it breaks at least $(ARCH) in klibc. gcc -dumpmachine powerpc-suse-linux --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6c8b311f4e..d8d2ec0d7b 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,7 @@ export CROSS CC AR STRIP RANLIB # code taken from uClibc to determine the current arch ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ - -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/ppc/powerpc/g'} + -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/powerpc/ppc/g'} # code taken from uClibc to determine the gcc include dir GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} From bc1530c65c282e27eb60de797291ca45c2d8cda2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Dec 2003 00:47:52 -0800 Subject: [PATCH 0227/4284] [PATCH] Cset exclude: dsteklof@us.ibm.com|ChangeSet|20031126173159|56255 --- libsysfs/sysfs_device.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 2a5353e6f7..fbd046f229 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -28,7 +28,6 @@ static int confirm_device_bus(struct sysfs_device *dev, { struct sysfs_link *devlink = NULL; unsigned char devpath[SYSFS_PATH_MAX]; - unsigned char *s = NULL; int result = 0; if (busname == NULL || bus_id == NULL) @@ -37,9 +36,6 @@ static int confirm_device_bus(struct sysfs_device *dev, if (sysfs_get_mnt_path(devpath, SYSFS_PATH_MAX) != 0) return -1; - s = &devpath[strlen(devpath)-1]; - if (strncmp(s, "/", 1) == 0) - *s = '\0'; strcat(devpath, SYSFS_BUS_DIR); strcat(devpath, "/"); strcat(devpath, busname); From edcd336477880368915245a4b7ddd1bca5940b30 Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Tue, 2 Dec 2003 00:48:01 -0800 Subject: [PATCH 0228/4284] [PATCH] another patch for path problem The quick patch I sent you yesterday fixes it in one location, but there are other points in the library that calls sysfs_get_mnt_path. We need to address all the areas in the library where paths are used. The following patch is a band-aid until we can get a proper path management in the library. --- libsysfs/libsysfs.h | 1 + libsysfs/sysfs_bus.c | 20 ++++++++++++++------ libsysfs/sysfs_class.c | 13 +++++++++---- libsysfs/sysfs_device.c | 13 ++++++++++--- libsysfs/sysfs_driver.c | 4 +++- libsysfs/sysfs_utils.c | 23 ++++++++++++++++++++++- 6 files changed, 59 insertions(+), 15 deletions(-) diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index f7e989e242..6d8e58de21 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -142,6 +142,7 @@ extern "C" { /* * Function Prototypes */ +extern int sysfs_trailing_slash(unsigned char *path); extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); extern int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, size_t len); diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 3111154cbc..639acef4ee 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -112,7 +112,10 @@ static struct sysfs_directory *open_bus_dir(const unsigned char *name) return NULL; } - strcat(buspath, SYSFS_BUS_DIR); + if (sysfs_trailing_slash(buspath) == 0) + strcat(buspath, "/"); + + strcat(buspath, SYSFS_BUS_NAME); strcat(buspath, "/"); strcat(buspath, name); busdir = sysfs_open_directory(buspath); @@ -406,10 +409,13 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, return NULL; } - strcat(path, SYSFS_BUS_DIR); + if (sysfs_trailing_slash(path) == 0) + strcat(path, "/"); + strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, busname); - strcat(path, SYSFS_DEVICES_DIR); + strcat(path, "/"); + strcat(path, SYSFS_DEVICES_NAME); strcat(path, "/"); strcat(path, dev_id); @@ -442,15 +448,17 @@ int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, } memset(subsys, 0, SYSFS_PATH_MAX); - strcpy(subsys, SYSFS_BUS_DIR); + strcpy(subsys, SYSFS_BUS_NAME); buslist = sysfs_open_subsystem_list(subsys); if (buslist != NULL) { dlist_for_each_data(buslist, bus, char) { memset(subsys, 0, SYSFS_PATH_MAX); - strcpy(subsys, SYSFS_BUS_DIR); + strcat(subsys, "/"); + strcpy(subsys, SYSFS_BUS_NAME); strcat(subsys, "/"); strcat(subsys, bus); - strcat(subsys, SYSFS_DRIVERS_DIR); + strcat(subsys, "/"); + strcat(subsys, SYSFS_DRIVERS_NAME); drivers = sysfs_open_subsystem_list(subsys); if (drivers != NULL) { dlist_for_each_data(drivers, curdrv, char) { diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index a0273565d5..54f22eee24 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -116,14 +116,16 @@ static struct sysfs_directory *open_class_dir(const unsigned char *name) return NULL; } + if (sysfs_trailing_slash(classpath) == 0) + strcat(classpath, "/"); /* * We shall now treat "block" also as a class. Hence, check here * if "name" is "block" and proceed accordingly */ if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { - strcat(classpath, SYSFS_BLOCK_DIR); + strcat(classpath, SYSFS_BLOCK_NAME); } else { - strcat(classpath, SYSFS_CLASS_DIR); + strcat(classpath, SYSFS_CLASS_NAME); strcat(classpath, "/"); strcat(classpath, name); } @@ -365,10 +367,13 @@ static int get_classdev_path(const unsigned char *classname, dprintf("Error getting sysfs mount path\n"); return -1; } + if (sysfs_trailing_slash(path) == 0) + strcat(path, "/"); + if (strcmp(classname, SYSFS_BLOCK_NAME) == 0) { - strcat(path, SYSFS_BLOCK_DIR); + strcat(path, SYSFS_BLOCK_NAME); } else { - strcat(path, SYSFS_CLASS_DIR); + strcat(path, SYSFS_CLASS_NAME); strcat(path, "/"); strcat(path, classname); } diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index fbd046f229..323a43dac1 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -36,7 +36,9 @@ static int confirm_device_bus(struct sysfs_device *dev, if (sysfs_get_mnt_path(devpath, SYSFS_PATH_MAX) != 0) return -1; - strcat(devpath, SYSFS_BUS_DIR); + if (sysfs_trailing_slash(devpath) == 0) + strcat(devpath, "/"); + strcat(devpath, SYSFS_BUS_NAME); strcat(devpath, "/"); strcat(devpath, busname); strcat(devpath, SYSFS_DEVICES_DIR); @@ -306,7 +308,10 @@ static struct sysfs_directory *open_root_device_dir(const unsigned char *name) return NULL; } - strcat(rootpath, SYSFS_DEVICES_DIR); + if (sysfs_trailing_slash(rootpath) == 0) + strcat(rootpath, "/"); + + strcat(rootpath, SYSFS_DEVICES_NAME); strcat(rootpath, "/"); strcat(rootpath, name); rdir = sysfs_open_directory(rootpath); @@ -435,7 +440,9 @@ static int get_device_absolute_path(const unsigned char *device, dprintf ("Sysfs not supported on this system\n"); return -1; } - strcat(bus_path, SYSFS_BUS_DIR); + if (sysfs_trailing_slash(bus_path) == 0) + strcat(bus_path, "/"); + strcat(bus_path, SYSFS_BUS_NAME); strcat(bus_path, "/"); strcat(bus_path, bus); strcat(bus_path, SYSFS_DEVICES_DIR); diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 0011177e99..1877dbce0b 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -182,7 +182,9 @@ static int get_driver_path(const unsigned char *bus, const unsigned char *drv, dprintf("Error getting sysfs mount path\n"); return -1; } - strcat(path, SYSFS_BUS_DIR); + if (sysfs_trailing_slash(path) == 0) + strcat(path, "/"); + strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, bus); strcat(path, SYSFS_DRIVERS_DIR); diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 4e96051c78..627e618dce 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -76,6 +76,23 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, #endif } +/* + * sysfs_trailing_slash: checks if there's a trailing slash to path + * @path: path to check + * returns 1 if true and 0 if not + */ +int sysfs_trailing_slash(unsigned char *path) +{ + unsigned char *s = NULL; + + if (path == NULL) + return 0; + s = &path[strlen(path)-1]; + if (strncmp(s, "/", 1) == 0) + return 1; + return 0; +} + /* * sysfs_get_mnt_path: Gets the sysfs mount point. * @mnt_path: place to put "sysfs" mount point @@ -226,6 +243,8 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) return NULL; } + if (sysfs_trailing_slash(sysfs_path) == 0) + strcat(sysfs_path, "/"); strcat(sysfs_path, name); dir = sysfs_open_directory(sysfs_path); if (dir == NULL) { @@ -301,7 +320,9 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) return NULL; } - strcat(sysfs_path, SYSFS_BUS_DIR); + if (sysfs_trailing_slash(sysfs_path) == 0) + strcat(sysfs_path, "/"); + strcat(sysfs_path, SYSFS_BUS_NAME); strcat(sysfs_path, "/"); strcat(sysfs_path, name); strcat(sysfs_path, SYSFS_DEVICES_DIR); From 7f2ea6a38223b02d38406baf1843f4ee1349abcf Mon Sep 17 00:00:00 2001 From: "mort@wildopensource.com" Date: Tue, 2 Dec 2003 00:59:36 -0800 Subject: [PATCH 0229/4284] [PATCH] Add -nodefaultlibs while compiling against klibc This patch adds -nodefaultlibs to LDFLAGS when compiling udev against klibc. This fixes the warning that I was getting when using $(LD)=gcc in the versions after Makefile.klibc disappeared. The problem was that it was still including a "-lc" in the call to the linker. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d8d2ec0d7b..67d38c0412 100644 --- a/Makefile +++ b/Makefile @@ -124,7 +124,7 @@ ifeq ($(strip $(KLIBC)),true) -I$(INCLUDE_DIR)/bits$(BITSIZE) -I$(GCCINCDIR) -Iklibc/linux/include \ -D__KLIBC__ LIB_OBJS = - LDFLAGS = --static --nostdlib -nostartfiles + LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs else CRT0 = LIBC = From 8cf7ebe8cdf9cb39ca9a60e23c735ab62cd15928 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Dec 2003 17:45:19 -0800 Subject: [PATCH 0230/4284] [PATCH] operate on the rules in the order they are in the config file (within the rule type) --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index d45a827083..0abd4b8041 100644 --- a/namedev.c +++ b/namedev.c @@ -145,7 +145,7 @@ static int add_dev(struct config_device *new_dev) if (!tmp_dev) return -ENOMEM; memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); - list_add(&tmp_dev->node, &config_device_list); + list_add_tail(&tmp_dev->node, &config_device_list); //dump_dev(tmp_dev); return 0; } From 0db6d4cc61523ee7f3f627f807c01f86ee2d36ab Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Dec 2003 17:52:26 -0800 Subject: [PATCH 0231/4284] [PATCH] catch replace device by wildcard catch device name by wildcard to support a whole class of devices by just one config line like: REPLACE, KERNEL="tty*", NAME="vc/%n" --- namedev.c | 4 ++-- test/udev-test.pl | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 0abd4b8041..ea64f3404f 100644 --- a/namedev.c +++ b/namedev.c @@ -860,8 +860,8 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev continue; dbg_parse("compare name '%s' with '%s'", - dev->kernel_name, dev->name); - if (strcmp(dev->kernel_name, class_dev->name) != 0) + dev->kernel_name, class_dev->name); + if (strncmp_wildcard(class_dev->name, dev->kernel_name, NAME_SIZE) != 0) continue; strfieldcpy(udev->name, dev->name); diff --git a/test/udev-test.pl b/test/udev-test.pl index 3f48de8f3e..8b967c353c 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -48,6 +48,15 @@ EOF expected => "boot_disk1" , conf => < "catch device by wildcard", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor/0" , + conf => < Date: Tue, 2 Dec 2003 17:55:00 -0800 Subject: [PATCH 0232/4284] [PATCH] add devfs like tty rules as an example in the default config file. --- udev.config | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/udev.config b/udev.config index 7e67d3a3b4..44fdb2561d 100644 --- a/udev.config +++ b/udev.config @@ -41,3 +41,9 @@ TOPOLOGY, BUS="usb", place="2.4", NAME="mouse2" REPLACE, KERNEL="ttyUSB1", NAME="visor" REPLACE, KERNEL="ttyUSB0", NAME="pl2303" +# a devfs like way to name some tty devices +#REPLACE, KERNEL="tty", NAME="tty" +#REPLACE, KERNEL="ttyS*", NAME="tts/%n" +#REPLACE, KERNEL="tty*", NAME="vc/%n" + + From 5c6f0fb0dcd999b96097b38311df439a85b6b799 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Dec 2003 18:18:21 -0800 Subject: [PATCH 0233/4284] [PATCH] rename namedev's get_attr() to be main namedev_name_device() as that's what it really is. --- namedev.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/namedev.c b/namedev.c index ea64f3404f..deb1d929e0 100644 --- a/namedev.c +++ b/namedev.c @@ -796,7 +796,6 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, return -ENODEV; } - static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; @@ -901,7 +900,7 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice * } } -static int get_attr(struct sysfs_class_device *class_dev, struct udevice *udev) +int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) { struct sysfs_device *sysfs_device = NULL; struct sysfs_class_device *class_dev_parent = NULL; @@ -994,17 +993,6 @@ done: return 0; } -int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev) -{ - int retval; - - retval = get_attr(class_dev, dev); - if (retval) - dbg("get_attr failed"); - - return retval; -} - int namedev_init(void) { int retval; From 19feb35100f602d2e9e4148d9e22548dae5a01d3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Dec 2003 18:38:30 -0800 Subject: [PATCH 0234/4284] [PATCH] split out the namedev config parsing logic to namedev_parse.c --- Makefile | 1 + namedev.c | 473 +++++------------------------------------------- namedev.h | 13 ++ namedev_parse.c | 420 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 475 insertions(+), 432 deletions(-) create mode 100644 namedev_parse.c diff --git a/Makefile b/Makefile index 67d38c0412..7aacb79de2 100644 --- a/Makefile +++ b/Makefile @@ -159,6 +159,7 @@ OBJS = udev.o \ udevdb.o \ logging.o \ namedev.o \ + namedev_parse.o \ $(SYSFS) \ $(TDB) diff --git a/namedev.c b/namedev.c index deb1d929e0..86685f8393 100644 --- a/namedev.c +++ b/namedev.c @@ -21,9 +21,6 @@ * */ -/* define this to enable parsing debugging */ -/* #define DEBUG_PARSER */ - #include #include #include @@ -41,14 +38,7 @@ #include "libsysfs/libsysfs.h" #include "klibc_fixups.h" -#define TYPE_LABEL "LABEL" -#define TYPE_NUMBER "NUMBER" -#define TYPE_TOPOLOGY "TOPOLOGY" -#define TYPE_REPLACE "REPLACE" -#define TYPE_CALLOUT "CALLOUT" -#define CALLOUT_MAXARG 8 - -static LIST_HEAD(config_device_list); +LIST_HEAD(config_device_list); /* s2 may end with '*' to match everything */ static int strncmp_wildcard(char *s1, char *s2, int max) @@ -63,49 +53,6 @@ static int strncmp_wildcard(char *s1, char *s2, int max) return strncmp(s1, s2, len); } -static void dump_dev(struct config_device *dev) -{ - switch (dev->type) { - case KERNEL_NAME: - dbg_parse("KERNEL name='%s' ," - "owner='%s', group='%s', mode=%#o", - dev->name, dev->owner, dev->group, dev->mode); - break; - case LABEL: - dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, - dev->owner, dev->group, dev->mode); - break; - case NUMBER: - dbg_parse("NUMBER name='%s', bus='%s', id='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->id, - dev->owner, dev->group, dev->mode); - break; - case TOPOLOGY: - dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->place, - dev->owner, dev->group, dev->mode); - break; - case REPLACE: - dbg_parse("REPLACE name=%s, kernel_name=%s, " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->kernel_name, - dev->owner, dev->group, dev->mode); - break; - case CALLOUT: - dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->exec_program, dev->id, - dev->owner, dev->group, dev->mode); - break; - default: - dbg_parse("unknown type of method"); - } -} - #define copy_var(a, b, var) \ if (b->var) \ a->var = b->var; @@ -114,7 +61,7 @@ static void dump_dev(struct config_device *dev) if (strlen(b->var)) \ strcpy(a->var, b->var); -static int add_dev(struct config_device *new_dev) +int add_config_dev(struct config_device *new_dev) { struct list_head *tmp; struct config_device *tmp_dev; @@ -146,348 +93,10 @@ static int add_dev(struct config_device *new_dev) return -ENOMEM; memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); list_add_tail(&tmp_dev->node, &config_device_list); - //dump_dev(tmp_dev); + //dump_config_dev(tmp_dev); return 0; } -static void dump_dev_list(void) -{ - struct list_head *tmp; - - list_for_each(tmp, &config_device_list) { - struct config_device *dev = list_entry(tmp, struct config_device, node); - dump_dev(dev); - } -} - -static int get_pair(char **orig_string, char **left, char **right) -{ - char *temp; - char *string = *orig_string; - - if (!string) - return -ENODEV; - - /* eat any whitespace */ - while (isspace(*string)) - ++string; - - /* split based on '=' */ - temp = strsep(&string, "="); - *left = temp; - if (!string) - return -ENODEV; - - /* take the right side and strip off the '"' */ - while (isspace(*string)) - ++string; - if (*string == '"') - ++string; - else - return -ENODEV; - - temp = strsep(&string, "\""); - if (!string || *temp == '\0') - return -ENODEV; - *right = temp; - *orig_string = string; - - return 0; -} - -static int get_value(const char *left, char **orig_string, char **ret_string) -{ - int retval; - char *left_string; - - retval = get_pair(orig_string, &left_string, ret_string); - if (retval) - return retval; - if (strcasecmp(left_string, left) != 0) - return -ENODEV; - return 0; -} - -static int namedev_init_config(void) -{ - char line[255]; - int lineno; - char *temp; - char *temp2; - char *temp3; - FILE *fd; - int retval = 0; - struct config_device dev; - - dbg("opening '%s' to read as config", udev_config_filename); - fd = fopen(udev_config_filename, "r"); - if (fd == NULL) { - dbg("can't open '%s'", udev_config_filename); - return -ENODEV; - } - - /* loop through the whole file */ - lineno = 0; - while (1) { - /* get a line */ - temp = fgets(line, sizeof(line), fd); - if (temp == NULL) - goto exit; - lineno++; - - dbg_parse("read '%s'", temp); - - /* eat the whitespace at the beginning of the line */ - while (isspace(*temp)) - ++temp; - - /* empty line? */ - if (*temp == 0x00) - continue; - - /* see if this is a comment */ - if (*temp == COMMENT_CHARACTER) - continue; - - memset(&dev, 0x00, sizeof(struct config_device)); - - /* parse the line */ - temp2 = strsep(&temp, ","); - if (strcasecmp(temp2, TYPE_LABEL) == 0) { - /* label type */ - dev.type = LABEL; - - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); - - /* file="value" */ - temp2 = strsep(&temp, ","); - retval = get_pair(&temp, &temp2, &temp3); - if (retval) - break; - strfieldcpy(dev.sysfs_file, temp2); - strfieldcpy(dev.sysfs_value, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - - dbg_parse("LABEL name='%s', bus='%s', " - "sysfs_file='%s', sysfs_value='%s'", - dev.name, dev.bus, dev.sysfs_file, - dev.sysfs_value); - } - - if (strcasecmp(temp2, TYPE_NUMBER) == 0) { - /* number type */ - dev.type = NUMBER; - - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); - - /* ID="id" */ - temp2 = strsep(&temp, ","); - retval = get_value("ID", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.id, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - - dbg_parse("NUMBER name='%s', bus='%s', id='%s'", - dev.name, dev.bus, dev.id); - } - - if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { - /* number type */ - dev.type = TOPOLOGY; - - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); - - /* PLACE="place" */ - temp2 = strsep(&temp, ","); - retval = get_value("PLACE", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.place, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - - dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'", - dev.name, dev.bus, dev.place); - } - - if (strcasecmp(temp2, TYPE_REPLACE) == 0) { - /* number type */ - dev.type = REPLACE; - - /* KERNEL="kernel_name" */ - retval = get_value("KERNEL", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.kernel_name, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - dbg_parse("REPLACE name='%s', kernel_name='%s'", - dev.name, dev.kernel_name); - } - if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { - /* number type */ - dev.type = CALLOUT; - - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); - - /* PROGRAM="executable" */ - temp2 = strsep(&temp, ","); - retval = get_value("PROGRAM", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.exec_program, temp3); - - /* ID="id" */ - temp2 = strsep(&temp, ","); - retval = get_value("ID", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.id, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - dbg_parse("CALLOUT name='%s', program='%s'", - dev.name, dev.exec_program); - } - - retval = add_dev(&dev); - if (retval) { - dbg("add_dev returned with error %d", retval); - goto exit; - } - } - dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, - lineno, temp - line, temp); -exit: - fclose(fd); - return retval; -} - - -static int namedev_init_permissions(void) -{ - char line[255]; - char *temp; - char *temp2; - FILE *fd; - int retval = 0; - struct config_device dev; - - dbg("opening '%s' to read as permissions config", udev_config_permission_filename); - fd = fopen(udev_config_permission_filename, "r"); - if (fd == NULL) { - dbg("can't open '%s'", udev_config_permission_filename); - return -ENODEV; - } - - /* loop through the whole file */ - while (1) { - temp = fgets(line, sizeof(line), fd); - if (temp == NULL) - break; - - dbg_parse("read '%s'", temp); - - /* eat the whitespace at the beginning of the line */ - while (isspace(*temp)) - ++temp; - - /* empty line? */ - if (*temp == 0x00) - continue; - - /* see if this is a comment */ - if (*temp == COMMENT_CHARACTER) - continue; - - memset(&dev, 0x00, sizeof(dev)); - - /* parse the line */ - temp2 = strsep(&temp, ":"); - if (!temp2) { - dbg("cannot parse line '%s'", line); - continue; - } - strncpy(dev.name, temp2, sizeof(dev.name)); - - temp2 = strsep(&temp, ":"); - if (!temp2) { - dbg("cannot parse line '%s'", line); - continue; - } - strncpy(dev.owner, temp2, sizeof(dev.owner)); - - temp2 = strsep(&temp, ":"); - if (!temp2) { - dbg("cannot parse line '%s'", line); - continue; - } - strncpy(dev.group, temp2, sizeof(dev.owner)); - - if (!temp) { - dbg("cannot parse line: %s", line); - continue; - } - dev.mode = strtol(temp, NULL, 8); - - dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", - dev.name, dev.owner, dev.group, - dev.mode); - retval = add_dev(&dev); - if (retval) { - dbg("add_dev returned with error %d", retval); - goto exit; - } - } - -exit: - fclose(fd); - return retval; -} - static mode_t get_default_mode(struct sysfs_class_device *class_dev) { /* just default everyone to rw for the world! */ @@ -664,7 +273,7 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev continue; if (sysfs_device) { - dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcasecmp(dev->bus, sysfs_device->bus) != 0) continue; } @@ -681,10 +290,10 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("callout returned matching value '%s', '%s' becomes '%s'" - " - owner='%s', group='%s', mode=%#o", - dev->id, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("callout returned matching value '%s', '%s' becomes '%s'" + " - owner='%s', group='%s', mode=%#o", + dev->id, class_dev->name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } return -ENODEV; @@ -702,12 +311,12 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, continue; if (sysfs_device) { - dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcasecmp(dev->bus, sysfs_device->bus) != 0) continue; } - dbg_parse("look for device attribute '%s'", dev->sysfs_file); + dbg("look for device attribute '%s'", dev->sysfs_file); /* try to find the attribute in the class device directory */ tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); if (tmpattr) @@ -724,7 +333,7 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, label_found: tmpattr->value[strlen(tmpattr->value)-1] = 0x00; - dbg_parse("compare attribute '%s' value '%s' with '%s'", + dbg("compare attribute '%s' value '%s' with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); if (strcmp(dev->sysfs_value, tmpattr->value) != 0) continue; @@ -735,7 +344,7 @@ label_found: strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("found matching attribute '%s', '%s' becomes '%s' " + dbg("found matching attribute '%s', '%s' becomes '%s' " "- owner='%s', group='%s', mode=%#o", dev->sysfs_file, class_dev->name, udev->name, dev->owner, dev->group, dev->mode); @@ -762,20 +371,20 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, if (dev->type != NUMBER) continue; - dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcasecmp(dev->bus, sysfs_device->bus) != 0) continue; found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); - dbg_parse("search '%s' in '%s', path='%s'", dev->id, temp, path); + dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); if (strstr(temp, dev->id) != NULL) { found = 1; } else { *temp = 0x00; temp = strrchr(path, '/'); - dbg_parse("search '%s' in '%s', path='%s'", dev->id, temp, path); + dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); if (strstr(temp, dev->id) != NULL) found = 1; } @@ -787,10 +396,10 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("found matching id '%s', '%s' becomes '%s'" - " - owner='%s', group ='%s', mode=%#o", - dev->id, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("found matching id '%s', '%s' becomes '%s'" + " - owner='%s', group ='%s', mode=%#o", + dev->id, class_dev->name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } return -ENODEV; @@ -813,20 +422,20 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude if (dev->type != TOPOLOGY) continue; - dbg_parse("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcasecmp(dev->bus, sysfs_device->bus) != 0) continue; found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); - dbg_parse("search '%s' in '%s', path='%s'", dev->place, temp, path); + dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); if (strstr(temp, dev->place) != NULL) { found = 1; } else { *temp = 0x00; temp = strrchr(path, '/'); - dbg_parse("search '%s' in '%s', path='%s'", dev->place, temp, path); + dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); if (strstr(temp, dev->place) != NULL) found = 1; } @@ -839,10 +448,10 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("found matching place '%s', '%s' becomes '%s'" - " - owner='%s', group ='%s', mode=%#o", - dev->place, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("found matching place '%s', '%s' becomes '%s'" + " - owner='%s', group ='%s', mode=%#o", + dev->place, class_dev->name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } return -ENODEV; @@ -858,8 +467,7 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev if (dev->type != REPLACE) continue; - dbg_parse("compare name '%s' with '%s'", - dev->kernel_name, class_dev->name); + dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name); if (strncmp_wildcard(class_dev->name, dev->kernel_name, NAME_SIZE) != 0) continue; @@ -869,9 +477,10 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); } - dbg_parse("found name, '%s' becomes '%s' - owner='%s', group='%s', mode = %#o", - dev->kernel_name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("found name, '%s' becomes '%s'" + " - owner='%s', group='%s', mode = %#o", + dev->kernel_name, udev->name, + dev->owner, dev->group, dev->mode); return 0; } @@ -892,7 +501,7 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice * if (strncmp_wildcard(class_dev->name, dev->name, sizeof(dev->name))) continue; if (dev->mode != 0) { - dbg_parse("found permissions for '%s'", class_dev->name); + dbg("found permissions for '%s'", class_dev->name); udev->mode = dev->mode; strfieldcpy(udev->owner, dev->owner); strfieldcpy(udev->group, dev->group); @@ -919,20 +528,20 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud * up in the kernel... */ if (strstr(class_dev->path, "block")) { - dbg_parse("looking at block device"); + dbg("looking at block device"); if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { char path[SYSFS_PATH_MAX]; - dbg_parse("really is a partition"); + dbg("really is a partition"); strfieldcpy(path, class_dev->path); temp = strrchr(path, '/'); *temp = 0x00; - dbg_parse("looking for a class device at '%s'", path); + dbg("looking for a class device at '%s'", path); class_dev_parent = sysfs_open_class_device(path); if (class_dev_parent == NULL) { dbg("sysfs_open_class_device at '%s' failed", path); } else { - dbg_parse("class_dev_parent->name='%s'", class_dev_parent->name); + dbg("class_dev_parent->name='%s'", class_dev_parent->name); if (class_dev_parent->sysdevice) sysfs_device = class_dev_parent->sysdevice; } @@ -941,12 +550,12 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } if (sysfs_device) { - dbg_parse("sysfs_device->path='%s'", sysfs_device->path); - dbg_parse("sysfs_device->bus_id='%s'", sysfs_device->bus_id); - dbg_parse("sysfs_device->bus='%s'", sysfs_device->bus); + dbg("sysfs_device->path='%s'", sysfs_device->path); + dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + dbg("sysfs_device->bus='%s'", sysfs_device->bus); strfieldcpy(udev->bus_id, sysfs_device->bus_id); } else { - dbg_parse("class_dev->name = '%s'", class_dev->name); + dbg("class_dev->name = '%s'", class_dev->name); } build_kernel_number(class_dev, udev); @@ -1005,6 +614,6 @@ int namedev_init(void) if (retval) return retval; - dump_dev_list(); + dump_config_dev_list(); return retval; } diff --git a/namedev.h b/namedev.h index 5ea843e9b7..1405d07e04 100644 --- a/namedev.h +++ b/namedev.h @@ -45,6 +45,12 @@ enum config_type { #define ID_SIZE 50 #define PLACE_SIZE 50 +#define TYPE_LABEL "LABEL" +#define TYPE_NUMBER "NUMBER" +#define TYPE_TOPOLOGY "TOPOLOGY" +#define TYPE_REPLACE "REPLACE" +#define TYPE_CALLOUT "CALLOUT" +#define CALLOUT_MAXARG 8 struct config_device { struct list_head node; @@ -65,8 +71,15 @@ struct config_device { mode_t mode; }; +extern struct list_head config_device_list; extern int namedev_init(void); extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev); +extern int namedev_init_permissions(void); +extern int namedev_init_config(void); + +extern int add_config_dev(struct config_device *new_dev); +extern void dump_config_dev(struct config_device *dev); +extern void dump_config_dev_list(void); #endif diff --git a/namedev_parse.c b/namedev_parse.c new file mode 100644 index 0000000000..a752b33050 --- /dev/null +++ b/namedev_parse.c @@ -0,0 +1,420 @@ +/* + * namedev_parse.c + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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. + * + */ + +/* define this to enable parsing debugging */ +/* #define DEBUG_PARSER */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "namedev.h" + +static int get_pair(char **orig_string, char **left, char **right) +{ + char *temp; + char *string = *orig_string; + + if (!string) + return -ENODEV; + + /* eat any whitespace */ + while (isspace(*string)) + ++string; + + /* split based on '=' */ + temp = strsep(&string, "="); + *left = temp; + if (!string) + return -ENODEV; + + /* take the right side and strip off the '"' */ + while (isspace(*string)) + ++string; + if (*string == '"') + ++string; + else + return -ENODEV; + + temp = strsep(&string, "\""); + if (!string || *temp == '\0') + return -ENODEV; + *right = temp; + *orig_string = string; + + return 0; +} + +static int get_value(const char *left, char **orig_string, char **ret_string) +{ + int retval; + char *left_string; + + retval = get_pair(orig_string, &left_string, ret_string); + if (retval) + return retval; + if (strcasecmp(left_string, left) != 0) + return -ENODEV; + return 0; +} + +void dump_config_dev(struct config_device *dev) +{ + switch (dev->type) { + case KERNEL_NAME: + dbg_parse("KERNEL name='%s' ," + "owner='%s', group='%s', mode=%#o", + dev->name, dev->owner, dev->group, dev->mode); + break; + case LABEL: + dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, + dev->owner, dev->group, dev->mode); + break; + case NUMBER: + dbg_parse("NUMBER name='%s', bus='%s', id='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->bus, dev->id, + dev->owner, dev->group, dev->mode); + break; + case TOPOLOGY: + dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->bus, dev->place, + dev->owner, dev->group, dev->mode); + break; + case REPLACE: + dbg_parse("REPLACE name=%s, kernel_name=%s, " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->kernel_name, + dev->owner, dev->group, dev->mode); + break; + case CALLOUT: + dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s', " + "owner='%s', group='%s', mode=%#o", + dev->name, dev->bus, dev->exec_program, dev->id, + dev->owner, dev->group, dev->mode); + break; + default: + dbg_parse("unknown type of method"); + } +} + +void dump_config_dev_list(void) +{ + struct list_head *tmp; + + list_for_each(tmp, &config_device_list) { + struct config_device *dev = list_entry(tmp, struct config_device, node); + dump_config_dev(dev); + } +} + +int namedev_init_config(void) +{ + char line[255]; + int lineno; + char *temp; + char *temp2; + char *temp3; + FILE *fd; + int retval = 0; + struct config_device dev; + + dbg("opening '%s' to read as config", udev_config_filename); + fd = fopen(udev_config_filename, "r"); + if (fd == NULL) { + dbg("can't open '%s'", udev_config_filename); + return -ENODEV; + } + + /* loop through the whole file */ + lineno = 0; + while (1) { + /* get a line */ + temp = fgets(line, sizeof(line), fd); + if (temp == NULL) + goto exit; + lineno++; + + dbg_parse("read '%s'", temp); + + /* eat the whitespace at the beginning of the line */ + while (isspace(*temp)) + ++temp; + + /* empty line? */ + if (*temp == 0x00) + continue; + + /* see if this is a comment */ + if (*temp == COMMENT_CHARACTER) + continue; + + memset(&dev, 0x00, sizeof(struct config_device)); + + /* parse the line */ + temp2 = strsep(&temp, ","); + if (strcasecmp(temp2, TYPE_LABEL) == 0) { + /* label type */ + dev.type = LABEL; + + /* BUS="bus" */ + retval = get_value("BUS", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.bus, temp3); + + /* file="value" */ + temp2 = strsep(&temp, ","); + retval = get_pair(&temp, &temp2, &temp3); + if (retval) + break; + strfieldcpy(dev.sysfs_file, temp2); + strfieldcpy(dev.sysfs_value, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.name, temp3); + + dbg_parse("LABEL name='%s', bus='%s', " + "sysfs_file='%s', sysfs_value='%s'", + dev.name, dev.bus, dev.sysfs_file, + dev.sysfs_value); + } + + if (strcasecmp(temp2, TYPE_NUMBER) == 0) { + /* number type */ + dev.type = NUMBER; + + /* BUS="bus" */ + retval = get_value("BUS", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.bus, temp3); + + /* ID="id" */ + temp2 = strsep(&temp, ","); + retval = get_value("ID", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.id, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.name, temp3); + + dbg_parse("NUMBER name='%s', bus='%s', id='%s'", + dev.name, dev.bus, dev.id); + } + + if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { + /* number type */ + dev.type = TOPOLOGY; + + /* BUS="bus" */ + retval = get_value("BUS", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.bus, temp3); + + /* PLACE="place" */ + temp2 = strsep(&temp, ","); + retval = get_value("PLACE", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.place, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.name, temp3); + + dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'", + dev.name, dev.bus, dev.place); + } + + if (strcasecmp(temp2, TYPE_REPLACE) == 0) { + /* number type */ + dev.type = REPLACE; + + /* KERNEL="kernel_name" */ + retval = get_value("KERNEL", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.kernel_name, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.name, temp3); + dbg_parse("REPLACE name='%s', kernel_name='%s'", + dev.name, dev.kernel_name); + } + if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { + /* number type */ + dev.type = CALLOUT; + + /* BUS="bus" */ + retval = get_value("BUS", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.bus, temp3); + + /* PROGRAM="executable" */ + temp2 = strsep(&temp, ","); + retval = get_value("PROGRAM", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.exec_program, temp3); + + /* ID="id" */ + temp2 = strsep(&temp, ","); + retval = get_value("ID", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.id, temp3); + + /* NAME="new_name" */ + temp2 = strsep(&temp, ","); + retval = get_value("NAME", &temp, &temp3); + if (retval) + break; + strfieldcpy(dev.name, temp3); + dbg_parse("CALLOUT name='%s', program='%s'", + dev.name, dev.exec_program); + } + + retval = add_config_dev(&dev); + if (retval) { + dbg("add_config_dev returned with error %d", retval); + goto exit; + } + } + dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, + lineno, temp - line, temp); +exit: + fclose(fd); + return retval; +} + + +int namedev_init_permissions(void) +{ + char line[255]; + char *temp; + char *temp2; + FILE *fd; + int retval = 0; + struct config_device dev; + + dbg("opening '%s' to read as permissions config", udev_config_permission_filename); + fd = fopen(udev_config_permission_filename, "r"); + if (fd == NULL) { + dbg("can't open '%s'", udev_config_permission_filename); + return -ENODEV; + } + + /* loop through the whole file */ + while (1) { + temp = fgets(line, sizeof(line), fd); + if (temp == NULL) + break; + + dbg_parse("read '%s'", temp); + + /* eat the whitespace at the beginning of the line */ + while (isspace(*temp)) + ++temp; + + /* empty line? */ + if (*temp == 0x00) + continue; + + /* see if this is a comment */ + if (*temp == COMMENT_CHARACTER) + continue; + + memset(&dev, 0x00, sizeof(dev)); + + /* parse the line */ + temp2 = strsep(&temp, ":"); + if (!temp2) { + dbg("cannot parse line '%s'", line); + continue; + } + strncpy(dev.name, temp2, sizeof(dev.name)); + + temp2 = strsep(&temp, ":"); + if (!temp2) { + dbg("cannot parse line '%s'", line); + continue; + } + strncpy(dev.owner, temp2, sizeof(dev.owner)); + + temp2 = strsep(&temp, ":"); + if (!temp2) { + dbg("cannot parse line '%s'", line); + continue; + } + strncpy(dev.group, temp2, sizeof(dev.owner)); + + if (!temp) { + dbg("cannot parse line: %s", line); + continue; + } + dev.mode = strtol(temp, NULL, 8); + + dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", + dev.name, dev.owner, dev.group, + dev.mode); + retval = add_config_dev(&dev); + if (retval) { + dbg("add_config_dev returned with error %d", retval); + goto exit; + } + } + +exit: + fclose(fd); + return retval; +} + + From 29b82deb7e8d7634792bd50be1377bae170a8acb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Dec 2003 18:41:29 -0800 Subject: [PATCH 0235/4284] [PATCH] turn debugging messages off by default. it's a bit noisy for the masses... --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7aacb79de2..340ca87f2a 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ # Set the following to `true' to make a debuggable build. # Leave this set to `false' for production use. -DEBUG = true +DEBUG = false ROOT = udev From e8bacccab296d6b75c4c9f43cb4e71007aff5b8a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 01:08:46 -0800 Subject: [PATCH 0236/4284] [PATCH] add support for a main udev config file, udev.conf. the older udev.config file is now called udev.rules. This allows us to better control configuration values, and move away from the environment variables. --- Makefile | 7 +- namedev.c | 2 +- namedev.h | 5 +- namedev_parse.c | 24 ++- test/{label_test.config => label_test.rules} | 0 ...difier_test.config => modifier_test.rules} | 0 ...replace_test.config => replace_test.rules} | 0 test/{topo_test.config => topo_test.rules} | 0 udev.c | 60 +----- udev.conf | 23 +++ udev.h | 17 +- udev.config => udev.rules | 0 udev.config.demo => udev.rules.demo | 0 udev.spec | 6 +- udev_config.c | 195 ++++++++++++++++++ 15 files changed, 265 insertions(+), 74 deletions(-) rename test/{label_test.config => label_test.rules} (100%) rename test/{modifier_test.config => modifier_test.rules} (100%) rename test/{replace_test.config => replace_test.rules} (100%) rename test/{topo_test.config => topo_test.rules} (100%) create mode 100644 udev.conf rename udev.config => udev.rules (100%) rename udev.config.demo => udev.rules.demo (100%) create mode 100644 udev_config.c diff --git a/Makefile b/Makefile index 340ca87f2a..d95aedc1a3 100644 --- a/Makefile +++ b/Makefile @@ -154,6 +154,7 @@ SYSFS = libsysfs/sysfs_bus.o \ libsysfs/dlist.o OBJS = udev.o \ + udev_config.o \ udev-add.o \ udev-remove.o \ udevdb.o \ @@ -226,7 +227,8 @@ install: all $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 - $(INSTALL_DATA) udev.config $(DESTDIR)$(configdir) + $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir) + $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug @@ -234,7 +236,8 @@ install: all uninstall: - rm $(hotplugdir)/udev.hotplug - rm $(configdir)/udev.permissions - - rm $(configdir)/udev.config + - rm $(configdir)/udev.rules + - rm $(configdir)/udev.conf - rm $(mandir)/man8/udev.8 - rm $(sbindir)/$(ROOT) - rmdir $(hotplugdir) diff --git a/namedev.c b/namedev.c index 86685f8393..a81721a9cf 100644 --- a/namedev.c +++ b/namedev.c @@ -606,7 +606,7 @@ int namedev_init(void) { int retval; - retval = namedev_init_config(); + retval = namedev_init_rules(); if (retval) return retval; diff --git a/namedev.h b/namedev.h index 1405d07e04..94fdf4ac91 100644 --- a/namedev.h +++ b/namedev.h @@ -28,7 +28,6 @@ struct sysfs_class_device; -#define COMMENT_CHARACTER '#' enum config_type { KERNEL_NAME = 0, /* must be 0 to let memset() default to this value */ @@ -76,10 +75,12 @@ extern struct list_head config_device_list; extern int namedev_init(void); extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev); extern int namedev_init_permissions(void); -extern int namedev_init_config(void); +extern int namedev_init_rules(void); extern int add_config_dev(struct config_device *new_dev); extern void dump_config_dev(struct config_device *dev); extern void dump_config_dev_list(void); +extern int get_pair(char **orig_string, char **left, char **right); + #endif diff --git a/namedev_parse.c b/namedev_parse.c index a752b33050..bd23867e18 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -36,7 +36,7 @@ #include "udev.h" #include "namedev.h" -static int get_pair(char **orig_string, char **left, char **right) +int get_pair(char **orig_string, char **left, char **right) { char *temp; char *string = *orig_string; @@ -137,7 +137,7 @@ void dump_config_dev_list(void) } } -int namedev_init_config(void) +int namedev_init_rules(void) { char line[255]; int lineno; @@ -148,10 +148,11 @@ int namedev_init_config(void) int retval = 0; struct config_device dev; - dbg("opening '%s' to read as config", udev_config_filename); - fd = fopen(udev_config_filename, "r"); - if (fd == NULL) { - dbg("can't open '%s'", udev_config_filename); + fd = fopen(udev_rules_filename, "r"); + if (fd != NULL) { + dbg("reading '%s' as rules file", udev_rules_filename); + } else { + dbg("can't open '%s' as a rules file", udev_rules_filename); return -ENODEV; } @@ -328,7 +329,7 @@ int namedev_init_config(void) goto exit; } } - dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, + dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_rules_filename, lineno, temp - line, temp); exit: fclose(fd); @@ -345,10 +346,11 @@ int namedev_init_permissions(void) int retval = 0; struct config_device dev; - dbg("opening '%s' to read as permissions config", udev_config_permission_filename); - fd = fopen(udev_config_permission_filename, "r"); - if (fd == NULL) { - dbg("can't open '%s'", udev_config_permission_filename); + fd = fopen(udev_permission_filename, "r"); + if (fd != NULL) { + dbg("reading '%s' as permissions file", udev_permission_filename); + } else { + dbg("can't open '%s' as permissions file", udev_permission_filename); return -ENODEV; } diff --git a/test/label_test.config b/test/label_test.rules similarity index 100% rename from test/label_test.config rename to test/label_test.rules diff --git a/test/modifier_test.config b/test/modifier_test.rules similarity index 100% rename from test/modifier_test.config rename to test/modifier_test.rules diff --git a/test/replace_test.config b/test/replace_test.rules similarity index 100% rename from test/replace_test.config rename to test/replace_test.rules diff --git a/test/topo_test.config b/test/topo_test.rules similarity index 100% rename from test/topo_test.config rename to test/topo_test.rules diff --git a/udev.c b/udev.c index 094905ecc2..272afbab6e 100644 --- a/udev.c +++ b/udev.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" @@ -39,11 +40,13 @@ char **main_argv; char **main_envp; char sysfs_path[SYSFS_PATH_MAX]; -char *udev_config_dir = UDEV_CONFIG_DIR; -char *udev_root = UDEV_ROOT; +char udev_config_dir[PATH_MAX]; +char udev_root[PATH_MAX]; char udev_db_filename[PATH_MAX+NAME_MAX]; -char udev_config_permission_filename[PATH_MAX+NAME_MAX]; +char udev_permission_filename[PATH_MAX+NAME_MAX]; +char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; +char default_mode_str[NAME_MAX]; static inline char *get_action(void) @@ -70,53 +73,6 @@ static inline char *get_seqnum(void) return seqnum; } -static void get_dirs(void) -{ - char *temp; - char *udev_db = UDEV_DB; - char *udev_config = UDEV_CONFIG_FILE; - char *udev_permission = UDEV_CONFIG_PERMISSION_FILE; - int retval; - - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); - if (retval) - dbg("sysfs_get_mnt_path failed"); - - /* see if we should try to override any of the default values */ - temp = getenv("UDEV_TEST"); - if (temp != NULL) { - /* hm testing is happening, use the specified values, if they are present */ - temp = getenv("SYSFS_PATH"); - if (temp) - strncpy(sysfs_path, temp, sizeof(sysfs_path)); - temp = getenv("UDEV_CONFIG_DIR"); - if (temp) - udev_config_dir = temp; - temp = getenv("UDEV_ROOT"); - if (temp) - udev_root = temp; - temp = getenv("UDEV_DB"); - if (temp) - udev_db = temp; - temp = getenv("UDEV_CONFIG_FILE"); - if (temp) - udev_config = temp; - temp = getenv("UDEV_PERMISSION_FILE"); - if (temp) - udev_permission = temp; - } - dbg("sysfs_path='%s'", sysfs_path); - - strncpy(udev_db_filename, udev_root, sizeof(udev_db_filename)); - strncat(udev_db_filename, udev_db, sizeof(udev_db_filename)); - - strncpy(udev_config_filename, udev_config_dir, sizeof(udev_config_filename)); - strncat(udev_config_filename, udev_config, sizeof(udev_config_filename)); - - strncpy(udev_config_permission_filename, udev_config_dir, sizeof(udev_config_permission_filename)); - strncat(udev_config_permission_filename, udev_permission, sizeof(udev_config_permission_filename)); -} - int main(int argc, char **argv, char **envp) { char *action; @@ -162,8 +118,10 @@ int main(int argc, char **argv, char **envp) goto exit; } + /* initialize our configuration */ + udev_init_config(); + /* initialize udev database */ - get_dirs(); retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { dbg("unable to initialize database"); diff --git a/udev.conf b/udev.conf new file mode 100644 index 0000000000..aadaea8a24 --- /dev/null +++ b/udev.conf @@ -0,0 +1,23 @@ +# udev.conf +# The main config file for udev +# +# This file can be used to override some of udev's default values +# for where it looks for files, and where it places device nodes. + + +# udev_root - where in the filesystem to place the device nodes +udev_root="/udev/" + +# udev_db - The name and location of the udev database. +udev_db="/udev/.udev.tdb" + +# udev_rules - The name and location of the udev rules file +udev_rules="/etc/udev/udev.rules" + +# udev_permissions - The name and location of the udev permission file +udev_permissions="/etc/udev/udev.permissions" + +# default_mode - set the default mode for all nodes that have no +# explicit match in the permissions file +default_mode="0666" + diff --git a/udev.h b/udev.h index 0c1951ad78..4acbb61391 100644 --- a/udev.h +++ b/udev.h @@ -51,10 +51,13 @@ extern int log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); -/* filenames for the config and database files */ +/* default filenames for the config and database files */ +#define UDEV_CONFIG_FILE "udev.conf" #define UDEV_DB ".udev.tdb" -#define UDEV_CONFIG_PERMISSION_FILE "udev.permissions" -#define UDEV_CONFIG_FILE "udev.config" +#define UDEV_RULES_FILE "udev.rules" +#define UDEV_PERMISSION_FILE "udev.permissions" + +#define COMMENT_CHARACTER '#' #define NAME_SIZE 100 #define OWNER_SIZE 30 @@ -84,14 +87,16 @@ do { \ extern int udev_add_device(char *path, char *subsystem); extern int udev_remove_device(char *path, char *subsystem); +extern void udev_init_config(void); extern char **main_argv; extern char **main_envp; extern char sysfs_path[SYSFS_PATH_MAX]; -extern char *udev_config_dir; -extern char *udev_root; +extern char udev_config_dir[PATH_MAX]; +extern char udev_root[PATH_MAX]; extern char udev_db_filename[PATH_MAX+NAME_MAX]; -extern char udev_config_permission_filename[PATH_MAX+NAME_MAX]; +extern char udev_permission_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; +extern char udev_rules_filename[PATH_MAX+NAME_MAX]; #endif diff --git a/udev.config b/udev.rules similarity index 100% rename from udev.config rename to udev.rules diff --git a/udev.config.demo b/udev.rules.demo similarity index 100% rename from udev.config.demo rename to udev.rules.demo diff --git a/udev.spec b/udev.spec index 0c30d613b7..8cc424cacb 100644 --- a/udev.spec +++ b/udev.spec @@ -32,12 +32,16 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udev %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ -%attr(0644,root,root) /etc/udev/udev.config +%attr(0644,root,root) /etc/udev/udev.conf +%attr(0644,root,root) /etc/udev/udev.rules %attr(0644,root,root) /etc/udev/udev.permissions %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(0644,root,root) %{_mandir}/man8/udev.8* %changelog +* Tue Nov 2 2003 Greg Kroah-Hartman +- changes due to config file name changes + * Fri Oct 17 2003 Robert Love - Make work without a build root - Correctly install the right files diff --git a/udev_config.c b/udev_config.c new file mode 100644 index 0000000000..262108dff7 --- /dev/null +++ b/udev_config.c @@ -0,0 +1,195 @@ +/* + * udev_config.c + * + * Userspace devfs + * + * Copyright (C) 2003 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. + * + * 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. + * + */ + +/* define this to enable parsing debugging */ +/* #define DEBUG_PARSER */ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "namedev.h" +#include "libsysfs/libsysfs.h" + +/* global variables */ +char sysfs_path[SYSFS_PATH_MAX]; +char udev_config_dir[PATH_MAX]; +char udev_root[PATH_MAX]; +char udev_db_filename[PATH_MAX+NAME_MAX]; +char udev_permission_filename[PATH_MAX+NAME_MAX]; +char udev_rules_filename[PATH_MAX+NAME_MAX]; +char udev_config_filename[PATH_MAX+NAME_MAX]; +char default_mode_str[NAME_MAX]; + + +static void init_variables(void) +{ + strfieldcpy(udev_root, UDEV_ROOT); + strfieldcpy(udev_config_dir, UDEV_CONFIG_DIR); +} + +#define set_var(_name, _var) \ + if (strcasecmp(variable, _name) == 0) { \ + dbg_parse("%s = '%s'", _name, value); \ + strncpy(_var, value, sizeof(_var)); \ + } + +static int parse_config_file(void) +{ + char line[255]; + char *temp; + char *variable; + char *value; + FILE *fd; + int lineno = 0; + int retval = 0; + + fd = fopen(udev_config_filename, "r"); + if (fd != NULL) { + dbg("reading '%s' as config file", udev_config_filename); + } else { + dbg("can't open '%s' as config file", udev_config_filename); + return -ENODEV; + } + + /* loop through the whole file */ + while (1) { + /* get a line */ + temp = fgets(line, sizeof(line), fd); + if (temp == NULL) + goto exit; + lineno++; + + dbg_parse("read '%s'", temp); + + /* eat the whitespace at the beginning of the line */ + while (isspace(*temp)) + ++temp; + + /* empty line? */ + if (*temp == 0x00) + continue; + + /* see if this is a comment */ + if (*temp == COMMENT_CHARACTER) + continue; + + retval = get_pair(&temp, &variable, &value); + if (retval) + break; + + dbg_parse("variable = '%s', value = '%s'", variable, value); + + set_var("udev_root", udev_root); + set_var("udev_db", udev_db_filename); + set_var("udev_rules", udev_rules_filename); + set_var("udev_permissions", udev_permission_filename); + set_var("default_mode", default_mode_str); + } + dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, + lineno, temp - line, temp); +exit: + fclose(fd); + return retval; +} + +static void get_dirs(void) +{ + char *temp; + char *udev_db = UDEV_DB; + char *udev_config = UDEV_CONFIG_FILE; + char *udev_rules = UDEV_RULES_FILE; + char *udev_permission = UDEV_PERMISSION_FILE; + int retval; + + retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + if (retval) + dbg("sysfs_get_mnt_path failed"); + + /* see if we should try to override any of the default values */ + temp = getenv("UDEV_TEST"); + if (temp != NULL) { + /* hm testing is happening, use the specified values, if they are present */ + temp = getenv("SYSFS_PATH"); + if (temp) + strfieldcpy(sysfs_path, temp); + temp = getenv("UDEV_CONFIG_DIR"); + if (temp) + strfieldcpy(udev_config_dir, temp); + temp = getenv("UDEV_ROOT"); + if (temp) + strfieldcpy(udev_root, temp); + temp = getenv("UDEV_DB"); + if (temp) + udev_db = temp; + temp = getenv("UDEV_CONFIG_FILE"); + if (temp) + udev_config = temp; + temp = getenv("UDEV_RULES_FILE"); + if (temp) + udev_rules = temp; + temp = getenv("UDEV_PERMISSION_FILE"); + if (temp) + udev_permission = temp; + } + dbg("sysfs_path='%s'", sysfs_path); + + strncpy(udev_db_filename, udev_root, sizeof(udev_db_filename)); + strncat(udev_db_filename, udev_db, sizeof(udev_db_filename)); + + strncpy(udev_config_filename, udev_config_dir, sizeof(udev_config_filename)); + strncat(udev_config_filename, udev_config, sizeof(udev_config_filename)); + + strncpy(udev_rules_filename, udev_config_dir, sizeof(udev_permission_filename)); + strncat(udev_rules_filename, udev_rules, sizeof(udev_permission_filename)); + + strncpy(udev_permission_filename, udev_config_dir, sizeof(udev_permission_filename)); + strncat(udev_permission_filename, udev_permission, sizeof(udev_permission_filename)); + + dbg_parse("udev_root = %s", udev_root); + dbg_parse("udev_config_filename = %s", udev_config_filename); + dbg_parse("udev_db_filename = %s", udev_db_filename); + dbg_parse("udev_rules_filename = %s", udev_rules_filename); + dbg_parse("udev_permission_filename = %s", udev_permission_filename); + parse_config_file(); + + dbg_parse("udev_root = %s", udev_root); + dbg_parse("udev_config_filename = %s", udev_config_filename); + dbg_parse("udev_db_filename = %s", udev_db_filename); + dbg_parse("udev_rules_filename = %s", udev_rules_filename); + dbg_parse("udev_permission_filename = %s", udev_permission_filename); +} + +void udev_init_config(void) +{ + init_variables(); + get_dirs(); +} + + From fd9594b61fb5ac4106731c087af614940b066df4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 01:09:05 -0800 Subject: [PATCH 0237/4284] [PATCH] fix up the tests to support the rules file name change --- test/label_test | 1 + test/modifier_test | 1 + test/replace_test | 1 + test/topo_test | 1 + test/udev-test.pl | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/test/label_test b/test/label_test index 0bf89226cb..b0a605cdac 100644 --- a/test/label_test +++ b/test/label_test @@ -6,6 +6,7 @@ export UDEV_CONFIG_DIR=$PWD/ export UDEV_ROOT=$PWD/udev/ export UDEV_DB=udev.tdb export UDEV_CONFIG_FILE=label_test.config +export UDEV_RULES_FILE=label_test.rules export UDEV_PERMISSION_FILE=udev.permissions export ACTION=add diff --git a/test/modifier_test b/test/modifier_test index 3dcd4454fc..a028d20e4d 100644 --- a/test/modifier_test +++ b/test/modifier_test @@ -6,6 +6,7 @@ export UDEV_CONFIG_DIR=$PWD/ export UDEV_ROOT=$PWD/udev/ export UDEV_DB=udev.tdb export UDEV_CONFIG_FILE=modifier_test.config +export UDEV_RULES_FILE=modifier_test.rules export UDEV_PERMISSION_FILE=udev.permissions export ACTION=add diff --git a/test/replace_test b/test/replace_test index c8e54f8f8d..aae07b48ac 100644 --- a/test/replace_test +++ b/test/replace_test @@ -6,6 +6,7 @@ export UDEV_CONFIG_DIR=$PWD/ export UDEV_ROOT=$PWD/udev/ export UDEV_DB=udev.tdb export UDEV_CONFIG_FILE=replace_test.config +export UDEV_RULES_FILE=replace_test.rules export UDEV_PERMISSION_FILE=udev.permissions export DEVPATH=class/tty/ttyUSB0 diff --git a/test/topo_test b/test/topo_test index 2a19c8b5f8..71121f478e 100644 --- a/test/topo_test +++ b/test/topo_test @@ -6,6 +6,7 @@ export UDEV_CONFIG_DIR=$PWD/ export UDEV_ROOT=$PWD/udev/ export UDEV_DB=udev.tdb export UDEV_CONFIG_FILE=topo_test.config +export UDEV_RULES_FILE=topo_test.rules export UDEV_PERMISSION_FILE=udev.permissions export ACTION=add diff --git a/test/udev-test.pl b/test/udev-test.pl index 8b967c353c..8af09a027b 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -161,7 +161,7 @@ sub udev { my ($action, $subsys, $devpath, $config) = @_; $ENV{DEVPATH} = $devpath; - $ENV{UDEV_CONFIG_FILE} = $conf_tmp; + $ENV{UDEV_RULES_FILE} = $conf_tmp; # create temporary config open CONF, ">$conf_tmp" || die "unable to create config file: $conf_tmp"; From 4865de442901cefebb7be889aa61233d8777b413 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 01:09:48 -0800 Subject: [PATCH 0238/4284] [PATCH] Update the man page to show the new config file, it's format, and how to use it. wow, update the docs to keep in line with reality, what a concept... --- udev.8 | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 73 insertions(+), 11 deletions(-) diff --git a/udev.8 b/udev.8 index 22c4586daa..fd1b6dd228 100644 --- a/udev.8 +++ b/udev.8 @@ -27,16 +27,73 @@ On device removal, .B udev queries the internal database for the name of the device file to be deleted. .SH "CONFIGURATION" +All udev configuration files consist of a set of lines of text. All empty +lines, and lines beginning with a '#' will be ignored. +.P + .B udev -expects its configuration at -.I /etc/udev/udev.config. -The file consists of a set of lines. All empty lines and -lines beginning with a '#' will be ignored. +expects its main configuration file at +.I /etc/udev/udev.conf. +The file consists of a set of variables and values that allow the user to +override default udev values. The current set of variables that can be +overridden in this file is: +.TP +.B udev_root +This is the where in the filesystem to place the device nodes. The default +value for this is +.I /udev/ +.TP +.B udev_db +The name and location of the udev database. The default value for this is +.I /udev/.udev.tdb +.TP +.B udev_rules +This is the location of the udev rules file. The default value for this is +.I /etc/udev/udev.rules +.TP +.B udev_permissions +This is the location of the udev permission file. The default value for this is +.I /etc/udev/udev.permissions +.TP +.B default_mode +This is the default mode for all nodes that have no explicit match in the +permissions file. The default value for this is +.I 0666 .br -Every line defines the mapping between device attributes and the device file -name. It starts with a keyword defining the method used to match, followed by -one ore more keys to compare and the filename for the device. If no matching -configuration is found, the default kernel device name is used. +.P +A sample \fIudev.conf\fP might look like this: +.sp +.nf +# udev_root - where in the filesystem to place the device nodes +udev_root="/udev/" + +# udev_db - The name and location of the udev database. +udev_db="/udev/.udev.tdb" + +# udev_rules - The name and location of the udev rules file +udev_rules="/etc/udev/udev.rules" + +# udev_permissions - The name and location of the udev permission file +udev_permissions="/etc/udev/udev.permissions" + +# default_mode - set the default mode for all nodes that have no +# explicit match in the permissions file +default_mode="0666" +.fi +.P +The rules for udev to use when naming devices may specified at +.I /etc/udev/udev.rules +or specified by the +.I udev_rules +value in the +.I /etc/udev/udev.conf +file. +.P +Every line in the rules file define the mapping between device attributes and +the device file name. It starts with a keyword defining the method used to +match, followed by one ore more keys to compare and the filename for the +device. If no matching configuration is found, the default kernel device name +is used. .P The line format is: .RS @@ -113,7 +170,7 @@ For partitions, this will result in 'part%n' If this is not a partition, it will result in 'disk' .RE .P -A sample \fIudev.conf\fP might look like this: +A sample \fIudev.rules\fP might look like this: .sp .nf # if /sbin/scsi_id returns "OEM 0815" device will be called disk1 @@ -136,7 +193,12 @@ LABEL, BUS="usb", model="WebCam Version 3", NAME="webcam%n" .fi .P Permissions and ownership for the created device files may specified at -.I /etc/udev/udev.permissions. +.I /etc/udev/udev.permissions +or specified by the +.I udev_permission +value in the +.I /etc/udev/udev.conf +file. The file consists of a set of lines. All empty lines and lines beginning with a '#' will be ignored. .br @@ -164,7 +226,7 @@ dsp1:::0666 .ft B .ft /sbin/udev udev program -/etc/udev/* udev config and database files +/etc/udev/* udev config files /etc/hotplug.d/default/udev.hotplug hotplug symlink to udev program .fi .LP From 9f1da3613897346b6a45e1f7a706d2315bc0f420 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 3 Dec 2003 06:22:53 -0800 Subject: [PATCH 0239/4284] [PATCH] pattern matching for namedev As promised yesterday, here is a patch to implement a more advanced pattern matching instead of the simple '*'. We can remove the "tty"="tty" line from udev.rules now and replace "tty*" by "tty[0-9]*" to catch only the vc's. implement pattern matching in namedev '*' - to match zero or more chars '?' - to match exactly one char '[]' - character classes with ranges '[0-9]'and negation [!A] --- namedev.c | 67 +++++++++++++++++++++++++++++++++++++---------- test/udev-test.pl | 26 ++++++++++++++++-- 2 files changed, 77 insertions(+), 16 deletions(-) diff --git a/namedev.c b/namedev.c index a81721a9cf..b9e099413b 100644 --- a/namedev.c +++ b/namedev.c @@ -40,17 +40,56 @@ LIST_HEAD(config_device_list); -/* s2 may end with '*' to match everything */ -static int strncmp_wildcard(char *s1, char *s2, int max) +/* compare string with pattern (supports * ? [0-9] [!A-Z]) */ +static int strcmp_pattern(const char *p, const char *s) { - int len = strlen(s2); - if (len > max) - len = max; - if (s2[len-1] == '*') - len--; - else - len = max; - return strncmp(s1, s2, len); + if (*s == '\0') { + while (*p == '*') + p++; + return (*p != '\0'); + } + switch (*p) { + case '[': + { + int not = 0; + p++; + if (*p == '!') { + not = 1; + p++; + } + while (*p && (*p != ']')) { + int match = 0; + if (p[1] == '-') { + if ((*s >= *p) && (*s <= p[2])) + match = 1; + p += 3; + } else { + match = (*p == *s); + p++; + } + if (match ^ not) { + while (*p && (*p != ']')) + p++; + return strcmp_pattern(p+1, s+1); + } + } + } + break; + case '*': + if (strcmp_pattern(p, s+1)) + return strcmp_pattern(p+1, s); + return 0; + case '\0': + if (*s == '\0') { + return 0; + } + break; + default: + if ((*p == *s) || (*p == '?')) + return strcmp_pattern(p+1, s+1); + break; + } + return 1; } #define copy_var(a, b, var) \ @@ -69,7 +108,7 @@ int add_config_dev(struct config_device *new_dev) /* update the values if we already have the device */ list_for_each(tmp, &config_device_list) { struct config_device *dev = list_entry(tmp, struct config_device, node); - if (strncmp_wildcard(dev->name, new_dev->name, sizeof(dev->name))) + if (strcmp_pattern(new_dev->name, dev->name)) continue; if (strncmp(dev->bus, new_dev->bus, sizeof(dev->name))) continue; @@ -282,7 +321,7 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev apply_format(udev, dev->exec_program); if (exec_callout(dev, udev->callout_value, NAME_SIZE)) continue; - if (strncmp_wildcard(udev->callout_value, dev->id, NAME_SIZE) != 0) + if (strcmp_pattern(dev->id, udev->callout_value) != 0) continue; strfieldcpy(udev->name, dev->name); if (dev->mode != 0) { @@ -468,7 +507,7 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev continue; dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name); - if (strncmp_wildcard(class_dev->name, dev->kernel_name, NAME_SIZE) != 0) + if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0) continue; strfieldcpy(udev->name, dev->name); @@ -498,7 +537,7 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice * list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); len = strlen(dev->name); - if (strncmp_wildcard(class_dev->name, dev->name, sizeof(dev->name))) + if (strcmp_pattern(dev->name, class_dev->name)) continue; if (dev->mode != 0) { dbg("found permissions for '%s'", class_dev->name); diff --git a/test/udev-test.pl b/test/udev-test.pl index 8af09a027b..47190f6e5d 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -51,12 +51,34 @@ LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n" EOF }, { - desc => "catch device by wildcard", + desc => "catch device by *", subsys => "tty", devpath => "class/tty/ttyUSB0", expected => "visor/0" , conf => < "catch device by ?", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor/0" , + conf => < "catch device by character class", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor/0" , + conf => < "callout result substitution", subsys => "block", devpath => "block/sda/sda3", expected => "special-device-3" , From 3836a3c49a72b9ee0b092725628f30839f100c4f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 08:13:11 -0800 Subject: [PATCH 0240/4284] [PATCH] get rid of the majority of the debug environment variables. Now there are only 3 valid environment test variables. The rest can be specified with the config file. --- Makefile | 6 ++++- namedev_parse.c | 6 ++--- test/label_test.rules | 3 --- test/modifier_test.rules | 3 --- test/replace_test.rules | 3 --- test/topo_test.rules | 3 --- udev.c | 10 -------- udev.h | 10 +------- udev_config.c | 50 ++++++++++------------------------------ 9 files changed, 21 insertions(+), 73 deletions(-) delete mode 100644 test/label_test.rules delete mode 100644 test/modifier_test.rules delete mode 100644 test/replace_test.rules delete mode 100644 test/topo_test.rules diff --git a/Makefile b/Makefile index d95aedc1a3..98f2a1f434 100644 --- a/Makefile +++ b/Makefile @@ -174,8 +174,12 @@ GEN_HEADERS = udev_version.h # Rules on how to create the generated header files udev_version.h: @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ - @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ + @echo \#define UDEV_DB \"$(udevdir)\.udev.tdb\" >> $@ + @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ + @echo \#define UDEV_CONFIG_FILE \"$(configdir)\udev.conf\" >> $@ + @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ + @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ $(OBJS): $(GEN_HEADERS) diff --git a/namedev_parse.c b/namedev_parse.c index bd23867e18..a6a7d4b62e 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -346,11 +346,11 @@ int namedev_init_permissions(void) int retval = 0; struct config_device dev; - fd = fopen(udev_permission_filename, "r"); + fd = fopen(udev_permissions_filename, "r"); if (fd != NULL) { - dbg("reading '%s' as permissions file", udev_permission_filename); + dbg("reading '%s' as permissions file", udev_permissions_filename); } else { - dbg("can't open '%s' as permissions file", udev_permission_filename); + dbg("can't open '%s' as permissions file", udev_permissions_filename); return -ENODEV; } diff --git a/test/label_test.rules b/test/label_test.rules deleted file mode 100644 index a6d1c1cb3e..0000000000 --- a/test/label_test.rules +++ /dev/null @@ -1,3 +0,0 @@ -# LABEL test -LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n" - diff --git a/test/modifier_test.rules b/test/modifier_test.rules deleted file mode 100644 index f63e02c3ac..0000000000 --- a/test/modifier_test.rules +++ /dev/null @@ -1,3 +0,0 @@ -# TOPO test -TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" - diff --git a/test/replace_test.rules b/test/replace_test.rules deleted file mode 100644 index 8fbfd18100..0000000000 --- a/test/replace_test.rules +++ /dev/null @@ -1,3 +0,0 @@ -# REPLACE test -REPLACE, KERNEL="ttyUSB0", NAME="visor" - diff --git a/test/topo_test.rules b/test/topo_test.rules deleted file mode 100644 index 72f03ee0b2..0000000000 --- a/test/topo_test.rules +++ /dev/null @@ -1,3 +0,0 @@ -# TOPO test -TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="first_disk%n" - diff --git a/udev.c b/udev.c index 272afbab6e..bf18a568ea 100644 --- a/udev.c +++ b/udev.c @@ -39,16 +39,6 @@ char **main_argv; char **main_envp; -char sysfs_path[SYSFS_PATH_MAX]; -char udev_config_dir[PATH_MAX]; -char udev_root[PATH_MAX]; -char udev_db_filename[PATH_MAX+NAME_MAX]; -char udev_permission_filename[PATH_MAX+NAME_MAX]; -char udev_rules_filename[PATH_MAX+NAME_MAX]; -char udev_config_filename[PATH_MAX+NAME_MAX]; -char default_mode_str[NAME_MAX]; - - static inline char *get_action(void) { char *action; diff --git a/udev.h b/udev.h index 4acbb61391..1a899bb40a 100644 --- a/udev.h +++ b/udev.h @@ -50,13 +50,6 @@ extern int log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); - -/* default filenames for the config and database files */ -#define UDEV_CONFIG_FILE "udev.conf" -#define UDEV_DB ".udev.tdb" -#define UDEV_RULES_FILE "udev.rules" -#define UDEV_PERMISSION_FILE "udev.permissions" - #define COMMENT_CHARACTER '#' #define NAME_SIZE 100 @@ -92,10 +85,9 @@ extern void udev_init_config(void); extern char **main_argv; extern char **main_envp; extern char sysfs_path[SYSFS_PATH_MAX]; -extern char udev_config_dir[PATH_MAX]; extern char udev_root[PATH_MAX]; extern char udev_db_filename[PATH_MAX+NAME_MAX]; -extern char udev_permission_filename[PATH_MAX+NAME_MAX]; +extern char udev_permissions_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; diff --git a/udev_config.c b/udev_config.c index 262108dff7..074bd7b35b 100644 --- a/udev_config.c +++ b/udev_config.c @@ -39,10 +39,9 @@ /* global variables */ char sysfs_path[SYSFS_PATH_MAX]; -char udev_config_dir[PATH_MAX]; char udev_root[PATH_MAX]; char udev_db_filename[PATH_MAX+NAME_MAX]; -char udev_permission_filename[PATH_MAX+NAME_MAX]; +char udev_permissions_filename[PATH_MAX+NAME_MAX]; char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; char default_mode_str[NAME_MAX]; @@ -50,8 +49,14 @@ char default_mode_str[NAME_MAX]; static void init_variables(void) { + /* fill up the defaults. + * If any config values are specified, they will + * override these values. */ strfieldcpy(udev_root, UDEV_ROOT); - strfieldcpy(udev_config_dir, UDEV_CONFIG_DIR); + strfieldcpy(udev_db_filename, UDEV_DB); + strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE); + strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); + strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); } #define set_var(_name, _var) \ @@ -109,7 +114,7 @@ static int parse_config_file(void) set_var("udev_root", udev_root); set_var("udev_db", udev_db_filename); set_var("udev_rules", udev_rules_filename); - set_var("udev_permissions", udev_permission_filename); + set_var("udev_permissions", udev_permissions_filename); set_var("default_mode", default_mode_str); } dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, @@ -122,10 +127,6 @@ exit: static void get_dirs(void) { char *temp; - char *udev_db = UDEV_DB; - char *udev_config = UDEV_CONFIG_FILE; - char *udev_rules = UDEV_RULES_FILE; - char *udev_permission = UDEV_PERMISSION_FILE; int retval; retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); @@ -139,51 +140,24 @@ static void get_dirs(void) temp = getenv("SYSFS_PATH"); if (temp) strfieldcpy(sysfs_path, temp); - temp = getenv("UDEV_CONFIG_DIR"); - if (temp) - strfieldcpy(udev_config_dir, temp); - temp = getenv("UDEV_ROOT"); - if (temp) - strfieldcpy(udev_root, temp); - temp = getenv("UDEV_DB"); - if (temp) - udev_db = temp; temp = getenv("UDEV_CONFIG_FILE"); if (temp) - udev_config = temp; - temp = getenv("UDEV_RULES_FILE"); - if (temp) - udev_rules = temp; - temp = getenv("UDEV_PERMISSION_FILE"); - if (temp) - udev_permission = temp; + strfieldcpy(udev_config_filename, temp); } dbg("sysfs_path='%s'", sysfs_path); - strncpy(udev_db_filename, udev_root, sizeof(udev_db_filename)); - strncat(udev_db_filename, udev_db, sizeof(udev_db_filename)); - - strncpy(udev_config_filename, udev_config_dir, sizeof(udev_config_filename)); - strncat(udev_config_filename, udev_config, sizeof(udev_config_filename)); - - strncpy(udev_rules_filename, udev_config_dir, sizeof(udev_permission_filename)); - strncat(udev_rules_filename, udev_rules, sizeof(udev_permission_filename)); - - strncpy(udev_permission_filename, udev_config_dir, sizeof(udev_permission_filename)); - strncat(udev_permission_filename, udev_permission, sizeof(udev_permission_filename)); - dbg_parse("udev_root = %s", udev_root); dbg_parse("udev_config_filename = %s", udev_config_filename); dbg_parse("udev_db_filename = %s", udev_db_filename); dbg_parse("udev_rules_filename = %s", udev_rules_filename); - dbg_parse("udev_permission_filename = %s", udev_permission_filename); + dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); parse_config_file(); dbg_parse("udev_root = %s", udev_root); dbg_parse("udev_config_filename = %s", udev_config_filename); dbg_parse("udev_db_filename = %s", udev_db_filename); dbg_parse("udev_rules_filename = %s", udev_rules_filename); - dbg_parse("udev_permission_filename = %s", udev_permission_filename); + dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); } void udev_init_config(void) From 72ffa78debb1f96488b5e13d3151486563b460e7 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 08:13:53 -0800 Subject: [PATCH 0241/4284] [PATCH] fix up the tests to work without all of the environ variables. --- test/label_test | 23 +++++++++++++++++------ test/modifier_test | 23 +++++++++++++++++------ test/replace_test | 24 +++++++++++++++++------- test/topo_test | 23 +++++++++++++++++------ test/udev-test.pl | 18 ++++++++++++------ 5 files changed, 80 insertions(+), 31 deletions(-) diff --git a/test/label_test b/test/label_test index b0a605cdac..c333937434 100644 --- a/test/label_test +++ b/test/label_test @@ -1,13 +1,22 @@ #!/bin/bash +RULES=label_test.rules +CONFIG=label_test.conf + export UDEV_TEST=yes export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_DIR=$PWD/ -export UDEV_ROOT=$PWD/udev/ -export UDEV_DB=udev.tdb -export UDEV_CONFIG_FILE=label_test.config -export UDEV_RULES_FILE=label_test.rules -export UDEV_PERMISSION_FILE=udev.permissions +export UDEV_CONFIG_FILE=$PWD/$CONFIG + +cat > $RULES << EOF +LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n" +EOF + +cat > $CONFIG << EOF +udev_root="$PWD/udev/" +udev_db="$PWD/udev/.udev.tdb" +udev_rules="$PWD/$RULES" +udev_permissions="$PWD/udev.permissions" +EOF export ACTION=add export DEVPATH=block/sda @@ -32,3 +41,5 @@ export DEVPATH=block/sda/sda3 ls udev +rm $RULES +rm $CONFIG diff --git a/test/modifier_test b/test/modifier_test index a028d20e4d..bbe072e58c 100644 --- a/test/modifier_test +++ b/test/modifier_test @@ -1,13 +1,22 @@ #!/bin/bash +RULES=modifier_test.rules +CONFIG=modifier_test.conf + export UDEV_TEST=yes export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_DIR=$PWD/ -export UDEV_ROOT=$PWD/udev/ -export UDEV_DB=udev.tdb -export UDEV_CONFIG_FILE=modifier_test.config -export UDEV_RULES_FILE=modifier_test.rules -export UDEV_PERMISSION_FILE=udev.permissions +export UDEV_CONFIG_FILE=$PWD/$CONFIG + +cat > $RULES << EOF +TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" +EOF + +cat > $CONFIG << EOF +udev_root="$PWD/udev/" +udev_db="$PWD/udev/.udev.tdb" +udev_rules="$PWD/$RULES" +udev_permissions="$PWD/udev.permissions" +EOF export ACTION=add export DEVPATH=block/sda @@ -31,3 +40,5 @@ export DEVPATH=block/sda/sda3 ../udev block ls udev +rm $RULES +rm $CONFIG diff --git a/test/replace_test b/test/replace_test index aae07b48ac..375c8dced3 100644 --- a/test/replace_test +++ b/test/replace_test @@ -1,13 +1,22 @@ #!/bin/bash +RULES=replace_test.rules +CONFIG=replace_test.conf + export UDEV_TEST=yes export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_DIR=$PWD/ -export UDEV_ROOT=$PWD/udev/ -export UDEV_DB=udev.tdb -export UDEV_CONFIG_FILE=replace_test.config -export UDEV_RULES_FILE=replace_test.rules -export UDEV_PERMISSION_FILE=udev.permissions +export UDEV_CONFIG_FILE=$PWD/$CONFIG + +cat > $RULES << EOF +REPLACE, KERNEL="ttyUSB0", NAME="visor" +EOF + +cat > $CONFIG << EOF +udev_root="$PWD/udev/" +udev_db="$PWD/udev/.udev.tdb" +udev_rules="$PWD/$RULES" +udev_permissions="$PWD/udev.permissions" +EOF export DEVPATH=class/tty/ttyUSB0 export ACTION=add @@ -19,4 +28,5 @@ export ACTION=remove ../udev tty ls -l udev - +rm $RULES +rm $CONFIG diff --git a/test/topo_test b/test/topo_test index 71121f478e..9225685c8c 100644 --- a/test/topo_test +++ b/test/topo_test @@ -1,13 +1,22 @@ #!/bin/bash +RULES=replace_test.rules +CONFIG=replace_test.conf + export UDEV_TEST=yes export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_DIR=$PWD/ -export UDEV_ROOT=$PWD/udev/ -export UDEV_DB=udev.tdb -export UDEV_CONFIG_FILE=topo_test.config -export UDEV_RULES_FILE=topo_test.rules -export UDEV_PERMISSION_FILE=udev.permissions +export UDEV_CONFIG_FILE=$PWD/$CONFIG + +cat > $RULES << EOF +TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="first_disk%n" +EOF + +cat > $CONFIG << EOF +udev_root="$PWD/udev/" +udev_db="$PWD/udev/.udev.tdb" +udev_rules="$PWD/$RULES" +udev_permissions="$PWD/udev.permissions" +EOF export ACTION=add export DEVPATH=block/sda @@ -31,3 +40,5 @@ export DEVPATH=block/sda/sda3 ../udev block ls udev +rm $RULES +rm $CONFIG diff --git a/test/udev-test.pl b/test/udev-test.pl index 47190f6e5d..97f75edc94 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -27,7 +27,8 @@ my $udev_bin = "../udev"; my $udev_root = "udev-root/"; # !!! directory will be removed !!! my $udev_db = ".udev.tdb"; my $perm = "udev.permissions"; -my $conf_tmp = "udev-test.config"; +my $main_conf = "udev-test.conf"; +my $conf_tmp = "udev-test.rules"; my @tests = ( @@ -173,17 +174,13 @@ EOF # set env $ENV{UDEV_TEST} = "yes"; $ENV{SYSFS_PATH} = $sysfs; -$ENV{UDEV_CONFIG_DIR} = "./"; -$ENV{UDEV_ROOT} = $udev_root; -$ENV{UDEV_DB} = $udev_db; -$ENV{UDEV_PERMISSION_FILE} = $perm; +$ENV{UDEV_CONFIG_FILE} = $main_conf; sub udev { my ($action, $subsys, $devpath, $config) = @_; $ENV{DEVPATH} = $devpath; - $ENV{UDEV_RULES_FILE} = $conf_tmp; # create temporary config open CONF, ">$conf_tmp" || die "unable to create config file: $conf_tmp"; @@ -203,6 +200,14 @@ mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; my $error = 0; print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; +# create initial config file +open CONF, ">$main_conf" || die "unable to create config file: $main_conf"; +print CONF "udev_root=\"$udev_root\"\n"; +print CONF "udev_db=\"$udev_db\"\n"; +print CONF "udev_rules=\"$conf_tmp\"\n"; +print CONF "udev_permissions=\"$perm\"\n"; +close CONF; + foreach my $config (@tests) { $config->{conf} =~ m/^([A-Z]*).*/; my $method = $1; @@ -236,4 +241,5 @@ print "$error errors occured\n\n"; unlink($udev_db); system("rm -rf $udev_root"); unlink($conf_tmp); +unlink($main_conf); From 5ec0b542163c3630b196ce676d717c8d1d8c0317 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 08:18:14 -0800 Subject: [PATCH 0242/4284] [PATCH] remove some items off of the TODO list, as they are now done. --- TODO | 6 ------ 1 file changed, 6 deletions(-) diff --git a/TODO b/TODO index 4f5db9a982..d5cc9194e6 100644 --- a/TODO +++ b/TODO @@ -6,14 +6,8 @@ greg k-h greg@kroah.com -- add modifiers and more documentation about the config file to the man - page. -- add ability to capture CALLOUT result and use it in a device name. - fix kernel name logic to handle devices like sdaj and such. -- make real test harness and have the tests be automated (instead of - relying on me knowing what the proper files should be created.) - more documentation (can never have too much.) -- document the config file format (it will change over time...) - add symlink generation and removal support - better partition support (it's a hack right now, maybe new libsysfs changes can help out a lot here.) From 356816abf60ca6a36d4e10e8ccd33fa9b1cd10a1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 17:37:29 -0800 Subject: [PATCH 0243/4284] [PATCH] show permissions and groups in the label_test --- test/label_test | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/label_test b/test/label_test index c333937434..fb3fa2359f 100644 --- a/test/label_test +++ b/test/label_test @@ -22,23 +22,23 @@ export ACTION=add export DEVPATH=block/sda ../udev block -ls udev +ls -l udev export DEVPATH=block/sda/sda3 ../udev block -ls udev +ls -l udev export ACTION=remove export DEVPATH=block/sda ../udev block -ls udev +ls -l udev export DEVPATH=block/sda/sda3 ../udev block -ls udev +ls -l udev rm $RULES From 8957102244524980f5008dcaf4cbf271a5254531 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 17:41:02 -0800 Subject: [PATCH 0244/4284] [PATCH] add support for the default_mode variable, as it is documented... --- namedev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index b9e099413b..f4c263f5bc 100644 --- a/namedev.c +++ b/namedev.c @@ -138,8 +138,12 @@ int add_config_dev(struct config_device *new_dev) static mode_t get_default_mode(struct sysfs_class_device *class_dev) { - /* just default everyone to rw for the world! */ - return 0666; + mode_t mode = 0600; /* default to owner rw only */ + + if (strlen(default_mode_str) != 0) { + mode = strtol(default_mode_str, NULL, 8); + } + return mode; } static void build_kernel_number(struct sysfs_class_device *class_dev, struct udevice *udev) From 206d3623c6454b6f34002d0d27e9aa2d00e4de06 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 18:30:49 -0800 Subject: [PATCH 0245/4284] [PATCH] enable default_mode ability to actually build --- udev.h | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.h b/udev.h index 1a899bb40a..01db449481 100644 --- a/udev.h +++ b/udev.h @@ -90,5 +90,6 @@ extern char udev_db_filename[PATH_MAX+NAME_MAX]; extern char udev_permissions_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; +extern char default_mode_str[NAME_MAX]; #endif From 61219c756ad0ad622decaf81b92a558ba2a1bc59 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 18:33:58 -0800 Subject: [PATCH 0246/4284] [PATCH] fix permission handling logic Now we can handle wildcards properly within the permission file. --- namedev.c | 129 ++++++++++++++++++++---------------------- namedev.h | 10 +++- namedev_parse.c | 57 ++++++++++--------- test/udev.permissions | 2 +- 4 files changed, 103 insertions(+), 95 deletions(-) diff --git a/namedev.c b/namedev.c index f4c263f5bc..4e0476c6e3 100644 --- a/namedev.c +++ b/namedev.c @@ -39,6 +39,7 @@ #include "klibc_fixups.h" LIST_HEAD(config_device_list); +LIST_HEAD(perm_device_list); /* compare string with pattern (supports * ? [0-9] [!A-Z]) */ static int strcmp_pattern(const char *p, const char *s) @@ -113,7 +114,6 @@ int add_config_dev(struct config_device *new_dev) if (strncmp(dev->bus, new_dev->bus, sizeof(dev->name))) continue; copy_var(dev, new_dev, type); - copy_var(dev, new_dev, mode); copy_string(dev, new_dev, bus); copy_string(dev, new_dev, sysfs_file); copy_string(dev, new_dev, sysfs_value); @@ -121,8 +121,6 @@ int add_config_dev(struct config_device *new_dev) copy_string(dev, new_dev, place); copy_string(dev, new_dev, kernel_name); copy_string(dev, new_dev, exec_program); - copy_string(dev, new_dev, owner); - copy_string(dev, new_dev, group); return 0; } @@ -136,6 +134,46 @@ int add_config_dev(struct config_device *new_dev) return 0; } +int add_perm_dev(struct perm_device *new_dev) +{ + struct list_head *tmp; + struct perm_device *tmp_dev; + + /* update the values if we already have the device */ + list_for_each(tmp, &perm_device_list) { + struct perm_device *dev = list_entry(tmp, struct perm_device, node); + if (strcmp_pattern(new_dev->name, dev->name)) + continue; + copy_var(dev, new_dev, mode); + copy_string(dev, new_dev, owner); + copy_string(dev, new_dev, group); + return 0; + } + + /* not found, add new structure to the perm list */ + tmp_dev = malloc(sizeof(*tmp_dev)); + if (!tmp_dev) + return -ENOMEM; + memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); + list_add_tail(&tmp_dev->node, &perm_device_list); + //dump_perm_dev(tmp_dev); + return 0; +} + +static struct perm_device *find_perm(char *name) +{ + struct list_head *tmp; + struct perm_device *perm = NULL; + + list_for_each(tmp, &perm_device_list) { + perm = list_entry(tmp, struct perm_device, node); + if (strcmp_pattern(perm->name, name)) + continue; + return perm; + } + return NULL; +} + static mode_t get_default_mode(struct sysfs_class_device *class_dev) { mode_t mode = 0600; /* default to owner rw only */ @@ -328,15 +366,8 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev if (strcmp_pattern(dev->id, udev->callout_value) != 0) continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("callout returned matching value '%s', '%s' becomes '%s'" - " - owner='%s', group='%s', mode=%#o", - dev->id, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("callout returned matching value '%s', '%s' becomes '%s'", + dev->id, class_dev->name, udev->name); return 0; } return -ENODEV; @@ -382,15 +413,8 @@ label_found: continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found matching attribute '%s', '%s' becomes '%s' " - "- owner='%s', group='%s', mode=%#o", - dev->sysfs_file, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("found matching attribute '%s', '%s' becomes '%s' ", + dev->sysfs_file, class_dev->name, udev->name); return 0; } @@ -434,15 +458,8 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, if (!found) continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found matching id '%s', '%s' becomes '%s'" - " - owner='%s', group ='%s', mode=%#o", - dev->id, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("found matching id '%s', '%s' becomes '%s'", + dev->id, class_dev->name, udev->name); return 0; } return -ENODEV; @@ -486,15 +503,8 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found matching place '%s', '%s' becomes '%s'" - " - owner='%s', group ='%s', mode=%#o", - dev->place, class_dev->name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("found matching place '%s', '%s' becomes '%s'", + dev->place, class_dev->name, udev->name); return 0; } return -ENODEV; @@ -515,15 +525,7 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev continue; strfieldcpy(udev->name, dev->name); - if (dev->mode != 0) { - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - dbg("found name, '%s' becomes '%s'" - " - owner='%s', group='%s', mode = %#o", - dev->kernel_name, udev->name, - dev->owner, dev->group, dev->mode); + dbg("found name, '%s' becomes '%s'", dev->kernel_name, udev->name); return 0; } @@ -532,24 +534,8 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice *udev) { - struct config_device *dev; - struct list_head *tmp; - int len; - + /* heh, this is pretty simple... */ strfieldcpy(udev->name, class_dev->name); - /* look for permissions */ - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); - len = strlen(dev->name); - if (strcmp_pattern(dev->name, class_dev->name)) - continue; - if (dev->mode != 0) { - dbg("found permissions for '%s'", class_dev->name); - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - strfieldcpy(udev->group, dev->group); - } - } } int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) @@ -558,6 +544,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; char *temp = NULL; + struct perm_device *perm; udev->mode = 0; @@ -632,12 +619,19 @@ found: apply_format(udev, udev->name); done: - /* mode was never set above */ - if (!udev->mode) { + perm = find_perm(udev->name); + if (perm) { + udev->mode = perm->mode; + strfieldcpy(udev->owner, perm->owner); + strfieldcpy(udev->group, perm->group); + } else { + /* no matching perms found :( */ udev->mode = get_default_mode(class_dev); udev->owner[0] = 0x00; udev->group[0] = 0x00; } + dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", + udev->name, udev->owner, udev->group, udev->mode); if (class_dev_parent) sysfs_close_class_device(class_dev_parent); @@ -658,5 +652,6 @@ int namedev_init(void) return retval; dump_config_dev_list(); + dump_perm_dev_list(); return retval; } diff --git a/namedev.h b/namedev.h index 94fdf4ac91..f7b8a67667 100644 --- a/namedev.h +++ b/namedev.h @@ -62,8 +62,12 @@ struct config_device { char place[PLACE_SIZE]; char kernel_name[NAME_SIZE]; char exec_program[FILE_SIZE]; + char name[NAME_SIZE]; +}; + +struct perm_device { + struct list_head node; - /* what to set the device to */ char name[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; @@ -71,6 +75,7 @@ struct config_device { }; extern struct list_head config_device_list; +extern struct list_head perm_device_list; extern int namedev_init(void); extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev); @@ -78,8 +83,11 @@ extern int namedev_init_permissions(void); extern int namedev_init_rules(void); extern int add_config_dev(struct config_device *new_dev); +extern int add_perm_dev(struct perm_device *new_dev); extern void dump_config_dev(struct config_device *dev); extern void dump_config_dev_list(void); +extern void dump_perm_dev(struct perm_device *dev); +extern void dump_perm_dev_list(void); extern int get_pair(char **orig_string, char **left, char **right); diff --git a/namedev_parse.c b/namedev_parse.c index a6a7d4b62e..5cb3a3eb1d 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -88,39 +88,27 @@ void dump_config_dev(struct config_device *dev) { switch (dev->type) { case KERNEL_NAME: - dbg_parse("KERNEL name='%s' ," - "owner='%s', group='%s', mode=%#o", - dev->name, dev->owner, dev->group, dev->mode); + dbg_parse("KERNEL name='%s'", dev->name); break; case LABEL: - dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value, - dev->owner, dev->group, dev->mode); + dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s'", + dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value); break; case NUMBER: - dbg_parse("NUMBER name='%s', bus='%s', id='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->id, - dev->owner, dev->group, dev->mode); + dbg_parse("NUMBER name='%s', bus='%s', id='%s'", + dev->name, dev->bus, dev->id); break; case TOPOLOGY: - dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->place, - dev->owner, dev->group, dev->mode); + dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'", + dev->name, dev->bus, dev->place); break; case REPLACE: - dbg_parse("REPLACE name=%s, kernel_name=%s, " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->kernel_name, - dev->owner, dev->group, dev->mode); + dbg_parse("REPLACE name=%s, kernel_name=%s", + dev->name, dev->kernel_name); break; case CALLOUT: - dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s', " - "owner='%s', group='%s', mode=%#o", - dev->name, dev->bus, dev->exec_program, dev->id, - dev->owner, dev->group, dev->mode); + dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s'", + dev->name, dev->bus, dev->exec_program, dev->id); break; default: dbg_parse("unknown type of method"); @@ -136,7 +124,24 @@ void dump_config_dev_list(void) dump_config_dev(dev); } } - + +void dump_perm_dev(struct perm_device *dev) +{ + dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", + dev->name, dev->owner, dev->group, dev->mode); +} + +void dump_perm_dev_list(void) +{ + struct list_head *tmp; + + list_for_each(tmp, &perm_device_list) { + struct perm_device *dev = list_entry(tmp, struct perm_device, node); + dump_perm_dev(dev); + } +} + + int namedev_init_rules(void) { char line[255]; @@ -344,7 +349,7 @@ int namedev_init_permissions(void) char *temp2; FILE *fd; int retval = 0; - struct config_device dev; + struct perm_device dev; fd = fopen(udev_permissions_filename, "r"); if (fd != NULL) { @@ -407,7 +412,7 @@ int namedev_init_permissions(void) dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", dev.name, dev.owner, dev.group, dev.mode); - retval = add_config_dev(&dev); + retval = add_perm_dev(&dev); if (retval) { dbg("add_config_dev returned with error %d", retval); goto exit; diff --git a/test/udev.permissions b/test/udev.permissions index d14082ac05..44ef3d43e5 100644 --- a/test/udev.permissions +++ b/test/udev.permissions @@ -3,4 +3,4 @@ ttyUSB0:root:uucp:0660 ttyUSB1:root:uucp:0666 visor:500:500:0666 dsp1:::0666 - +boot_disk?:::0666 From 07d7cfd1fa996ea7353410dc73c8a6ef98ff4e7e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 19:26:02 -0800 Subject: [PATCH 0247/4284] [PATCH] update the wildcard documentation in the man page to show the new styles supported. --- udev.8 | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/udev.8 b/udev.8 index fd1b6dd228..c6a9296255 100644 --- a/udev.8 +++ b/udev.8 @@ -199,11 +199,9 @@ or specified by the value in the .I /etc/udev/udev.conf file. -The file consists of a set of lines. All empty lines and -lines beginning with a '#' will be ignored. .br Every line lists a device name followed by owner, group and permission -mode. All values are separated by colons. The name field may end with a +mode. All values are separated by colons. The name field may contain a wildcard to apply the values to a whole class of devices. .br If @@ -221,6 +219,24 @@ ttyUSB1:0:8:0660 video*:root:video:0660 dsp1:::0666 .fi +.P +A number of different fields in the above configuration files support a simple +form of wildcard matching. This form is based on the fnmatch(3) style, and +supports the following fields: +.RS +.TP +.B * +Matches zero, one, or more characters. +.TP +.B ? +Matches any single character, but does not match zero characters. +.TP +.B [ ] +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. +.RE .SH "FILES" .nf .ft B From fc1f0d43267be8bfc1a4afd79532e081921589e1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 19:27:24 -0800 Subject: [PATCH 0248/4284] [PATCH] Added Kay's name to the man page. --- udev.8 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udev.8 b/udev.8 index c6a9296255..bac35b091d 100644 --- a/udev.8 +++ b/udev.8 @@ -255,4 +255,5 @@ web site. .SH AUTHORS .B udev was developed by Greg Kroah-Hartman with much help from -Dan Stekloff and many others. +Dan Stekloff , Kay Sievers , and +many others. From 9c9fb5f6eb47794dc5516e5b3d162bdc3b4ec7da Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 21:45:20 -0800 Subject: [PATCH 0249/4284] [PATCH] fix some compiler warnings in the tdb code. --- tdb/tdb.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tdb/tdb.h b/tdb/tdb.h index e236b31af5..839d5b1516 100644 --- a/tdb/tdb.h +++ b/tdb/tdb.h @@ -136,6 +136,10 @@ int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); void tdb_dump_all(TDB_CONTEXT *tdb); int tdb_printfreelist(TDB_CONTEXT *tdb); +/* used only in tdbutil.c */ +int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key); +int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key); + extern TDB_DATA tdb_null; #ifdef __cplusplus From a27170c49a777c132e0f0c81dda72c3c064ba4b7 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 21:51:37 -0800 Subject: [PATCH 0250/4284] [PATCH] fix up some duplicated function compiler warnings in libsysfs --- libsysfs/sysfs.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 3186c37a16..4ea4919351 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -32,12 +32,6 @@ #include #include -/* external library functions */ -extern int lstat(const char *file_name, struct stat *buf); -extern int readlink(const char *path, char *buf, size_t bufsize); -extern int getpagesize(void); -extern int isascii(int c); - /* Debugging */ #ifdef DEBUG #include From 6ad5f7b40ddcf9786eaae8673e0ca1c40de8c46a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Dec 2003 21:57:12 -0800 Subject: [PATCH 0251/4284] [PATCH] update ChangeLog for v008 --- ChangeLog | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/ChangeLog b/ChangeLog index efaf86669a..ac06290775 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,73 @@ +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 ============================================ From c9feb4d9f274614ef3600851fc5368cd01349960 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 4 Dec 2003 18:01:29 -0800 Subject: [PATCH 0252/4284] [PATCH] v008 release --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 98f2a1f434..5c66db4697 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = false ROOT = udev -VERSION = 007_bk +VERSION = 008 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 8cc424cacb..4833a20761 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 007_bk +Version: 008 Release: 1 License: GPL Group: Utilities/System From da146a3e36a2ee8ca25729983e6a8bf91ae3fc17 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 4 Dec 2003 19:21:10 -0800 Subject: [PATCH 0253/4284] [PATCH] 008_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5c66db4697..c6f322c880 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = false ROOT = udev -VERSION = 008 +VERSION = 008_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 4833a20761..a005b12dfa 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 008 +Version: 008_bk Release: 1 License: GPL Group: Utilities/System From 28d6536a0fff341bb3e307ad1abc30df57635f30 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 4 Dec 2003 19:21:27 -0800 Subject: [PATCH 0254/4284] [PATCH] a bug in linefeed removal While I was adding pattern match to the LABEL method i hit a bug. We modify a string returned from libsysfs, so with every iteration is is truncated by one char: Dec 4 02:27:16 pim udev[23307]: do_label: dev->bus='scsi' sysfs_device->bus='scsi' Dec 4 02:27:16 pim udev[23307]: do_label: look for device attribute 'vendor' Dec 4 02:27:16 pim udev[23307]: do_label: xxx 'IBM-ESXS ' Dec 4 02:27:16 pim udev[23307]: do_label: compare attribute 'vendor' value 'IBM-ESX' with '?IBM-ESXS' Dec 4 02:27:16 pim udev[23307]: do_label: dev->bus='scsi' sysfs_device->bus='scsi' Dec 4 02:27:16 pim udev[23307]: do_label: look for device attribute 'vendor' Dec 4 02:27:16 pim udev[23307]: do_label: xxx 'IBM-ESX' Dec 4 02:27:16 pim udev[23307]: do_label: compare attribute 'vendor' value 'IBM-ES' with 'IBM-ESXS?' Dec 4 02:27:16 pim udev[23307]: do_label: dev->bus='scsi' sysfs_device->bus='scsi' Dec 4 02:27:16 pim udev[23307]: do_label: look for device attribute 'vendor' Dec 4 02:27:16 pim udev[23307]: do_label: xxx 'IBM-ES' Dec 4 02:27:16 pim udev[23307]: do_label: compare attribute 'vendor' value 'IBM-E' with 'IBM-ES??' Dec 4 02:27:16 pim udev[23307]: do_label: dev->bus='scsi' sysfs_device->bus='scsi' Dec 4 02:27:16 pim udev[23307]: do_label: look for device attribute 'vendor' Dec 4 02:27:16 pim udev[23307]: do_label: xxx 'IBM-E' Dec 4 02:27:16 pim udev[23307]: do_label: compare attribute 'vendor' value 'IBM-' with 'IBM-ESXSS' I changed the behavior to remove only the line feed. 03-bug-in-linefeed-removal.diff remove only the line feed from string not every last char --- namedev.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/namedev.c b/namedev.c index 4e0476c6e3..ea75bc5d8f 100644 --- a/namedev.c +++ b/namedev.c @@ -378,6 +378,7 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_attribute *tmpattr = NULL; struct config_device *dev; struct list_head *tmp; + char *c; list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); @@ -406,7 +407,9 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, continue; label_found: - tmpattr->value[strlen(tmpattr->value)-1] = 0x00; + c = tmpattr->value + strlen(tmpattr->value)-1; + if (*c == '\n') + *c = 0x00; dbg("compare attribute '%s' value '%s' with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); if (strcmp(dev->sysfs_value, tmpattr->value) != 0) @@ -578,7 +581,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } } } - + if (sysfs_device) { dbg("sysfs_device->path='%s'", sysfs_device->path); dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); @@ -642,7 +645,7 @@ done: int namedev_init(void) { int retval; - + retval = namedev_init_rules(); if (retval) return retval; From 83be97ba211c4f69e7fd9f16f57ca7210a116a7d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 4 Dec 2003 19:21:31 -0800 Subject: [PATCH 0255/4284] [PATCH] pattern match for label method switch LABEL search to pattern match add a test for pattern match in LABEL remove useless rule from udev.rules --- namedev.c | 2 +- test/udev-test.pl | 12 ++++++++++++ udev.rules | 1 - 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index ea75bc5d8f..1faa253c1e 100644 --- a/namedev.c +++ b/namedev.c @@ -412,7 +412,7 @@ label_found: *c = 0x00; dbg("compare attribute '%s' value '%s' with '%s'", dev->sysfs_file, tmpattr->value, dev->sysfs_value); - if (strcmp(dev->sysfs_value, tmpattr->value) != 0) + if (strcmp_pattern(dev->sysfs_value, tmpattr->value) != 0) continue; strfieldcpy(udev->name, dev->name); diff --git a/test/udev-test.pl b/test/udev-test.pl index 97f75edc94..b1757ee1bb 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -49,6 +49,18 @@ EOF expected => "boot_disk1" , conf => < "label test of pattern match", + subsys => "block", + devpath => "block/sda/sda1", + expected => "boot_disk1" , + conf => < Date: Thu, 4 Dec 2003 19:22:53 -0800 Subject: [PATCH 0256/4284] [PATCH] man page beauty I've never seen any project where the documentation is in sync with the code at this early stage. Nice! So here is the patch to make it extra perfect :) remove random indent to be consistent style is "shell style" s/wildcard/pattern/ mention negation char in character class --- udev.8 | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/udev.8 b/udev.8 index bac35b091d..37b3b625e7 100644 --- a/udev.8 +++ b/udev.8 @@ -27,7 +27,9 @@ On device removal, .B udev queries the internal database for the name of the device file to be deleted. .SH "CONFIGURATION" -All udev configuration files consist of a set of lines of text. All empty +All +.B udev +configuration files consist of a set of lines of text. All empty lines, and lines beginning with a '#' will be ignored. .P @@ -96,11 +98,9 @@ device. If no matching configuration is found, the default kernel device name is used. .P The line format is: -.RS .sp .I method, key,[key,...] name .sp -.RE where valid methods with corresponding keys are: .TP .B CALLOUT @@ -130,22 +130,13 @@ string replacement of the kernel device name key: \fBKERNEL_NAME\fP .P The methods are applied in the following order: -.B CALLOUT -, -.B LABEL -, -.B NUMBER -, -.B TOPOLOGY -, -.B REPLACE +.BR CALLOUT ", " LABEL ", " NUMBER ", " TOPOLOGY ", " REPLACE "." .P The .B NAME and .B PROGRAM -fields support simple printf-like string subtitution: -.RS +fields support simple printf-like string substitution: .TP .B %n the "kernel number" of the device @@ -168,7 +159,6 @@ the CALLOUT program returned string Use the devfs style disk name for this device. For partitions, this will result in 'part%n' If this is not a partition, it will result in 'disk' -.RE .P A sample \fIudev.rules\fP might look like this: .sp @@ -202,7 +192,7 @@ file. .br Every line lists a device name followed by owner, group and permission mode. All values are separated by colons. The name field may contain a -wildcard to apply the values to a whole class of devices. +pattern to apply the values to a whole class of devices. .br If .B udev @@ -221,9 +211,7 @@ dsp1:::0666 .fi .P A number of different fields in the above configuration files support a simple -form of wildcard matching. This form is based on the fnmatch(3) style, and -supports the following fields: -.RS +form of shell style pattern matching. It supports the following pattern characters: .TP .B * Matches zero, one, or more characters. @@ -235,8 +223,8 @@ Matches any single character, but does not match zero characters. 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. -.RE +the range of all digits, the pattern [0-9] would be used. If the first character +following the '[' is a '!' then any character not enclosed is matched. .SH "FILES" .nf .ft B From 2bf80b67d1a64f1219bd366cee355e897596b2cf Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Sun, 7 Dec 2003 08:44:59 -0800 Subject: [PATCH 0257/4284] [PATCH] extras/multipath update here is the next update which brings this multipath to the state i'm not ashamed of it being in udev :) * drop a libdevmapper copy in extras/multipath; maybe discussions w/ Sistina folks will bring a better solution in the future. * drop a putchar usage in libdevmapper to compile cleanly with klibc * drop another such usage of my own in main.c * massage the Makefile to compile libdevmapper against klibc * use "ld" to produce the binary rather than "gcc -static" * stop being stupid w/ uneeded major, minor & dev in main.c:dm_mk_node() * reverse to creating striped target for now because the multipath target is more hairy than expected initialy * push the version code to 009 to be in synch w/ udev builds & run here. binary size is 43ko, which is fairly gratifying after all the efforts I've put to compiling it with klibc :) --- extras/multipath/Makefile | 24 +- extras/multipath/libdevmapper/Makefile | 15 + .../libdevmapper/ioctl/libdevmapper.c | 1092 +++++++++++++++++ .../libdevmapper/ioctl/libdm-compat.h | 111 ++ .../libdevmapper/ioctl/libdm-targets.h | 51 + extras/multipath/libdevmapper/libdevmapper.h | 147 +++ extras/multipath/libdevmapper/libdm-common.c | 382 ++++++ extras/multipath/libdevmapper/libdm-common.h | 38 + extras/multipath/libdevmapper/list.h | 99 ++ extras/multipath/main.c | 16 +- extras/multipath/main.h | 6 +- 11 files changed, 1964 insertions(+), 17 deletions(-) create mode 100644 extras/multipath/libdevmapper/Makefile create mode 100644 extras/multipath/libdevmapper/ioctl/libdevmapper.c create mode 100644 extras/multipath/libdevmapper/ioctl/libdm-compat.h create mode 100644 extras/multipath/libdevmapper/ioctl/libdm-targets.h create mode 100644 extras/multipath/libdevmapper/libdevmapper.h create mode 100644 extras/multipath/libdevmapper/libdm-common.c create mode 100644 extras/multipath/libdevmapper/libdm-common.h create mode 100644 extras/multipath/libdevmapper/list.h diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index 9e0ce124c6..bccf1264f0 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -13,17 +13,35 @@ CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc -I../../klibc LDFLAGS = -lsysfs -ldevmapper -ldlist OBJS = main.o +CRT0 = ../../klibc/klibc/crt0.o +LIB = ../../klibc/klibc/libc.a +LIBGCC = /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/libgcc.a +DMOBJS = libdevmapper/libdm-common.o libdevmapper/ioctl/libdevmapper.o +SYSFSOBJS = ../../libsysfs/dlist.o ../../libsysfs/sysfs_bus.o \ + ../../libsysfs/sysfs_class.o ../../libsysfs/sysfs_device.o \ + ../../libsysfs/sysfs_dir.o ../../libsysfs/sysfs_driver.o \ + ../../libsysfs/sysfs_utils.o -all: $(EXEC) - strip $(EXEC) +SUBDIRS = libdevmapper + +recurse: + @for dir in $(SUBDIRS); do\ + $(MAKE) -C $$dir ; \ + done + $(MAKE) $(EXEC) + +all: recurse @echo "" @echo "Make complete" + $(EXEC): $(OBJS) - $(CC) $(OBJS) -o $(EXEC) $(LDFLAGS) $(CFLAGS) + $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(SYSFSOBJS) $(DMOBJS) $(LIB) $(LIBGCC) + strip $(EXEC) clean: rm -f core *.o $(EXEC) + $(MAKE) -C libdevmapper clean install: install -d $(bindir) diff --git a/extras/multipath/libdevmapper/Makefile b/extras/multipath/libdevmapper/Makefile new file mode 100644 index 0000000000..72b39cedf5 --- /dev/null +++ b/extras/multipath/libdevmapper/Makefile @@ -0,0 +1,15 @@ +# Makefile +# +# Copyright (C) 2003 Christophe Varoqui, + +CC = gcc +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc -I../../../klibc/klibc/include -I../../../klibc/klibc/include/bits32 -I/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/include -I../../../klibc/linux/include -I. -Iioctl + +OBJS = ioctl/libdevmapper.o libdm-common.o + +all: $(OBJS) + @echo "" + @echo "Make complete" + +clean: + rm -f core *.o ioctl/*.o ioctl/*.so diff --git a/extras/multipath/libdevmapper/ioctl/libdevmapper.c b/extras/multipath/libdevmapper/ioctl/libdevmapper.c new file mode 100644 index 0000000000..ac7ba0c86a --- /dev/null +++ b/extras/multipath/libdevmapper/ioctl/libdevmapper.c @@ -0,0 +1,1092 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#include "libdm-targets.h" +#include "libdm-common.h" + +#ifdef DM_COMPAT +# include "libdm-compat.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef linux +# include +# include +# include +#else +# define MAJOR(x) major((x)) +# define MINOR(x) minor((x)) +# define MKDEV(x,y) makedev((x),(y)) +#endif + +/* + * Ensure build compatibility. + * The hard-coded versions here are the highest present + * in the _cmd_data arrays. + */ + +#if !((DM_VERSION_MAJOR == 1 && DM_VERSION_MINOR >= 0) || \ + (DM_VERSION_MAJOR == 4 && DM_VERSION_MINOR >= 0)) +#error The version of dm-ioctl.h included is incompatible. +#endif + +/* dm major version no for running kernel */ +static int _dm_version = DM_VERSION_MAJOR; +static int _log_suppress = 0; + +static int _control_fd = -1; +static int _version_checked = 0; +static int _version_ok = 1; + +/* + * Support both old and new major numbers to ease the transition. + * Clumsy, but only temporary. + */ +#if DM_VERSION_MAJOR == 4 && defined(DM_COMPAT) +const int _dm_compat = 1; +#else +const int _dm_compat = 0; +#endif + + +/* *INDENT-OFF* */ +static struct cmd_data _cmd_data_v4[] = { + {"create", DM_DEV_CREATE, {4, 0, 0}}, + {"reload", DM_TABLE_LOAD, {4, 0, 0}}, + {"remove", DM_DEV_REMOVE, {4, 0, 0}}, + {"remove_all", DM_REMOVE_ALL, {4, 0, 0}}, + {"suspend", DM_DEV_SUSPEND, {4, 0, 0}}, + {"resume", DM_DEV_SUSPEND, {4, 0, 0}}, + {"info", DM_DEV_STATUS, {4, 0, 0}}, + {"deps", DM_TABLE_DEPS, {4, 0, 0}}, + {"rename", DM_DEV_RENAME, {4, 0, 0}}, + {"version", DM_VERSION, {4, 0, 0}}, + {"status", DM_TABLE_STATUS, {4, 0, 0}}, + {"table", DM_TABLE_STATUS, {4, 0, 0}}, + {"waitevent", DM_DEV_WAIT, {4, 0, 0}}, + {"names", DM_LIST_DEVICES, {4, 0, 0}}, + {"clear", DM_TABLE_CLEAR, {4, 0, 0}}, + {"mknodes", DM_DEV_STATUS, {4, 0, 0}}, +}; +/* *INDENT-ON* */ + +#define ALIGNMENT_V1 sizeof(int) +#define ALIGNMENT 8 + +/* FIXME Rejig library to record & use errno instead */ +#ifndef DM_EXISTS_FLAG +# define DM_EXISTS_FLAG 0x00000004 +#endif + +static void *_align(void *ptr, unsigned int a) +{ + register unsigned long agn = --a; + + return (void *) (((unsigned long) ptr + agn) & ~agn); +} + +static int _open_control(void) +{ + char control[PATH_MAX]; + + if (_control_fd != -1) + return 1; + + snprintf(control, sizeof(control), "%s/control", dm_dir()); + + if ((_control_fd = open(control, O_RDWR)) < 0) { + log_error("%s: open failed: %s", control, strerror(errno)); + log_error("Is device-mapper driver missing from kernel?"); + return 0; + } + + return 1; +} + +void dm_task_destroy(struct dm_task *dmt) +{ + struct target *t, *n; + + for (t = dmt->head; t; t = n) { + n = t->next; + free(t->params); + free(t->type); + free(t); + } + + if (dmt->dev_name) + free(dmt->dev_name); + + if (dmt->newname) + free(dmt->newname); + + if (dmt->dmi.v4) + free(dmt->dmi.v4); + + if (dmt->uuid) + free(dmt->uuid); + + free(dmt); +} + +/* + * Protocol Version 1 compatibility functions. + */ + +#ifdef DM_COMPAT + +static int _dm_task_get_driver_version_v1(struct dm_task *dmt, char *version, + size_t size) +{ + unsigned int *v; + + if (!dmt->dmi.v1) { + version[0] = '\0'; + return 0; + } + + v = dmt->dmi.v1->version; + snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); + return 1; +} + +/* Unmarshall the target info returned from a status call */ +static int _unmarshal_status_v1(struct dm_task *dmt, struct dm_ioctl_v1 *dmi) +{ + char *outbuf = (char *) dmi + dmi->data_start; + char *outptr = outbuf; + int32_t i; + struct dm_target_spec_v1 *spec; + + for (i = 0; i < dmi->target_count; i++) { + spec = (struct dm_target_spec_v1 *) outptr; + + if (!dm_task_add_target(dmt, spec->sector_start, + (uint64_t) spec->length, + spec->target_type, + outptr + sizeof(*spec))) + return 0; + + outptr = outbuf + spec->next; + } + + return 1; +} + +static int _dm_format_dev_v1(char *buf, int bufsize, uint32_t dev_major, + uint32_t dev_minor) +{ + int r; + + if (bufsize < 8) + return 0; + + r = snprintf(buf, bufsize, "%03x:%03x", dev_major, dev_minor); + if (r < 0 || r > bufsize - 1) + return 0; + + return 1; +} + +static int _dm_task_get_info_v1(struct dm_task *dmt, struct dm_info *info) +{ + if (!dmt->dmi.v1) + return 0; + + memset(info, 0, sizeof(*info)); + + info->exists = dmt->dmi.v1->flags & DM_EXISTS_FLAG ? 1 : 0; + if (!info->exists) + return 1; + + info->suspended = dmt->dmi.v1->flags & DM_SUSPEND_FLAG ? 1 : 0; + info->read_only = dmt->dmi.v1->flags & DM_READONLY_FLAG ? 1 : 0; + info->target_count = dmt->dmi.v1->target_count; + info->open_count = dmt->dmi.v1->open_count; + info->event_nr = 0; + info->major = MAJOR(dmt->dmi.v1->dev); + info->minor = MINOR(dmt->dmi.v1->dev); + info->live_table = 1; + info->inactive_table = 0; + + return 1; +} + +static const char *_dm_task_get_name_v1(struct dm_task *dmt) +{ + return (dmt->dmi.v1->name); +} + +static const char *_dm_task_get_uuid_v1(struct dm_task *dmt) +{ + return (dmt->dmi.v1->uuid); +} + +static struct dm_deps *_dm_task_get_deps_v1(struct dm_task *dmt) +{ + log_error("deps version 1 no longer supported by libdevmapper"); + return NULL; +} + +static struct dm_names *_dm_task_get_names_v1(struct dm_task *dmt) +{ + return (struct dm_names *) (((void *) dmt->dmi.v1) + + dmt->dmi.v1->data_start); +} + +static void *_add_target_v1(struct target *t, void *out, void *end) +{ + void *out_sp = out; + struct dm_target_spec_v1 sp; + size_t sp_size = sizeof(struct dm_target_spec_v1); + int len; + const char no_space[] = "Ran out of memory building ioctl parameter"; + + out += sp_size; + if (out >= end) { + log_error(no_space); + return NULL; + } + + sp.status = 0; + sp.sector_start = t->start; + sp.length = t->length; + strncpy(sp.target_type, t->type, sizeof(sp.target_type)); + + len = strlen(t->params); + + if ((out + len + 1) >= end) { + log_error(no_space); + + log_error("t->params= '%s'", t->params); + return NULL; + } + strcpy((char *) out, t->params); + out += len + 1; + + /* align next block */ + out = _align(out, ALIGNMENT_V1); + + sp.next = out - out_sp; + + memcpy(out_sp, &sp, sp_size); + + return out; +} + +static struct dm_ioctl_v1 *_flatten_v1(struct dm_task *dmt) +{ + const size_t min_size = 16 * 1024; + const int (*version)[3]; + + struct dm_ioctl_v1 *dmi; + struct target *t; + size_t len = sizeof(struct dm_ioctl_v1); + void *b, *e; + int count = 0; + + for (t = dmt->head; t; t = t->next) { + len += sizeof(struct dm_target_spec_v1); + len += strlen(t->params) + 1 + ALIGNMENT_V1; + count++; + } + + if (count && dmt->newname) { + log_error("targets and newname are incompatible"); + return NULL; + } + + if (dmt->newname) + len += strlen(dmt->newname) + 1; + + /* + * Give len a minimum size so that we have space to store + * dependencies or status information. + */ + if (len < min_size) + len = min_size; + + if (!(dmi = malloc(len))) + return NULL; + + memset(dmi, 0, len); + + version = &_cmd_data_v1[dmt->type].version; + + dmi->version[0] = (*version)[0]; + dmi->version[1] = (*version)[1]; + dmi->version[2] = (*version)[2]; + + dmi->data_size = len; + dmi->data_start = sizeof(struct dm_ioctl_v1); + + if (dmt->dev_name) + strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); + + if (dmt->type == DM_DEVICE_SUSPEND) + dmi->flags |= DM_SUSPEND_FLAG; + if (dmt->read_only) + dmi->flags |= DM_READONLY_FLAG; + + if (dmt->minor >= 0) { + if (dmt->major <= 0) { + log_error("Missing major number for persistent device"); + return NULL; + } + dmi->flags |= DM_PERSISTENT_DEV_FLAG; + dmi->dev = MKDEV(dmt->major, dmt->minor); + } + + if (dmt->uuid) + strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); + + dmi->target_count = count; + + b = (void *) (dmi + 1); + e = (void *) ((char *) dmi + len); + + for (t = dmt->head; t; t = t->next) + if (!(b = _add_target_v1(t, b, e))) + goto bad; + + if (dmt->newname) + strcpy(b, dmt->newname); + + return dmi; + + bad: + free(dmi); + return NULL; +} + +static int _dm_names_v1(struct dm_ioctl_v1 *dmi) +{ + const char *dev_dir = dm_dir(); + int r = 1, len; + const char *name; + struct dirent *dirent; + DIR *d; + struct dm_names *names, *old_names = NULL; + void *end = (void *) dmi + dmi->data_size; + struct stat buf; + char path[PATH_MAX]; + + if (!(d = opendir(dev_dir))) { + log_error("%s: opendir failed: %s", dev_dir, strerror(errno)); + return 0; + } + + names = (struct dm_names *) ((void *) dmi + dmi->data_start); + + names->dev = 0; /* Flags no data */ + + while ((dirent = readdir(d))) { + name = dirent->d_name; + + if (name[0] == '.' || !strcmp(name, "control")) + continue; + + if (old_names) + old_names->next = (uint32_t) ((void *) names - + (void *) old_names); + snprintf(path, sizeof(path), "%s/%s", dev_dir, name); + if (stat(path, &buf)) { + log_error("%s: stat failed: %s", path, strerror(errno)); + continue; + } + if (!S_ISBLK(buf.st_mode)) + continue; + names->dev = (uint64_t) buf.st_rdev; + names->next = 0; + len = strlen(name); + if (((void *) (names + 1) + len + 1) >= end) { + log_error("Insufficient buffer space for device list"); + r = 0; + break; + } + + strcpy(names->name, name); + + old_names = names; + names = _align((void *) ++names + len + 1, ALIGNMENT); + } + + if (closedir(d)) + log_error("%s: closedir failed: %s", dev_dir, strerror(errno)); + + return r; +} + +static int _dm_task_run_v1(struct dm_task *dmt) +{ + struct dm_ioctl_v1 *dmi; + unsigned int command; + + dmi = _flatten_v1(dmt); + if (!dmi) { + log_error("Couldn't create ioctl argument"); + return 0; + } + + if (!_open_control()) + return 0; + + if ((unsigned) dmt->type >= + (sizeof(_cmd_data_v1) / sizeof(*_cmd_data_v1))) { + log_error("Internal error: unknown device-mapper task %d", + dmt->type); + goto bad; + } + + command = _cmd_data_v1[dmt->type].cmd; + + if (dmt->type == DM_DEVICE_TABLE) + dmi->flags |= DM_STATUS_TABLE_FLAG; + + log_debug("dm %s %s %s %s", _cmd_data_v1[dmt->type].name, dmi->name, + dmi->uuid, dmt->newname ? dmt->newname : ""); + if (dmt->type == DM_DEVICE_LIST) { + if (!_dm_names_v1(dmi)) + goto bad; + } else if (ioctl(_control_fd, command, dmi) < 0) { + if (_log_suppress) + log_verbose("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + else + log_error("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + goto bad; + } + + switch (dmt->type) { + case DM_DEVICE_CREATE: + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); + break; + + case DM_DEVICE_REMOVE: + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_RENAME: + rename_dev_node(dmt->dev_name, dmt->newname); + break; + + case DM_DEVICE_MKNODES: + if (dmi->flags & DM_EXISTS_FLAG) + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), + MINOR(dmi->dev)); + else + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_STATUS: + case DM_DEVICE_TABLE: + if (!_unmarshal_status_v1(dmt, dmi)) + goto bad; + break; + + case DM_DEVICE_SUSPEND: + case DM_DEVICE_RESUME: + dmt->type = DM_DEVICE_INFO; + if (!dm_task_run(dmt)) + goto bad; + free(dmi); /* We'll use what info returned */ + return 1; + } + + dmt->dmi.v1 = dmi; + return 1; + + bad: + free(dmi); + return 0; +} + +#endif + +/* + * Protocol Version 4 functions. + */ + +int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size) +{ + unsigned int *v; + +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_driver_version_v1(dmt, version, size); +#endif + + if (!dmt->dmi.v4) { + version[0] = '\0'; + return 0; + } + + v = dmt->dmi.v4->version; + snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); + return 1; +} + +static int _check_version(char *version, size_t size, int log_suppress) +{ + struct dm_task *task; + int r; + + if (!(task = dm_task_create(DM_DEVICE_VERSION))) { + log_error("Failed to get device-mapper version"); + version[0] = '\0'; + return 0; + } + + if (log_suppress) + _log_suppress = 1; + + r = dm_task_run(task); + dm_task_get_driver_version(task, version, size); + dm_task_destroy(task); + _log_suppress = 0; + + return r; +} + +/* + * Find out device-mapper's major version number the first time + * this is called and whether or not we support it. + */ +int dm_check_version(void) +{ + char libversion[64], dmversion[64]; + const char *compat = ""; + + if (_version_checked) + return _version_ok; + + _version_checked = 1; + + if (_check_version(dmversion, sizeof(dmversion), _dm_compat)) + return 1; + + if (!_dm_compat) + goto bad; + + log_verbose("device-mapper ioctl protocol version %d failed. " + "Trying protocol version 1.", _dm_version); + _dm_version = 1; + if (_check_version(dmversion, sizeof(dmversion), 0)) { + log_verbose("Using device-mapper ioctl protocol version 1"); + return 1; + } + + compat = "(compat)"; + + dm_get_library_version(libversion, sizeof(libversion)); + + log_error("Incompatible libdevmapper %s%s and kernel driver %s", + libversion, compat, dmversion); + + bad: + _version_ok = 0; + return 0; +} + +void *dm_get_next_target(struct dm_task *dmt, void *next, + uint64_t *start, uint64_t *length, + char **target_type, char **params) +{ + struct target *t = (struct target *) next; + + if (!t) + t = dmt->head; + + if (!t) + return NULL; + + *start = t->start; + *length = t->length; + *target_type = t->type; + *params = t->params; + + return t->next; +} + +/* Unmarshall the target info returned from a status call */ +static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi) +{ + char *outbuf = (char *) dmi + dmi->data_start; + char *outptr = outbuf; + uint32_t i; + struct dm_target_spec *spec; + + for (i = 0; i < dmi->target_count; i++) { + spec = (struct dm_target_spec *) outptr; + if (!dm_task_add_target(dmt, spec->sector_start, + spec->length, + spec->target_type, + outptr + sizeof(*spec))) + return 0; + + outptr = outbuf + spec->next; + } + + return 1; +} + +int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, + uint32_t dev_minor) +{ + int r; + +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_format_dev_v1(buf, bufsize, dev_major, dev_minor); +#endif + + if (bufsize < 8) + return 0; + + r = snprintf(buf, bufsize, "%03u:%03u", dev_major, dev_minor); + if (r < 0 || r > bufsize - 1) + return 0; + + return 1; +} + +int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_info_v1(dmt, info); +#endif + + if (!dmt->dmi.v4) + return 0; + + memset(info, 0, sizeof(*info)); + + info->exists = dmt->dmi.v4->flags & DM_EXISTS_FLAG ? 1 : 0; + if (!info->exists) + return 1; + + info->suspended = dmt->dmi.v4->flags & DM_SUSPEND_FLAG ? 1 : 0; + info->read_only = dmt->dmi.v4->flags & DM_READONLY_FLAG ? 1 : 0; + info->live_table = dmt->dmi.v4->flags & DM_ACTIVE_PRESENT_FLAG ? 1 : 0; + info->inactive_table = dmt->dmi.v4->flags & DM_INACTIVE_PRESENT_FLAG ? + 1 : 0; + info->target_count = dmt->dmi.v4->target_count; + info->open_count = dmt->dmi.v4->open_count; + info->event_nr = dmt->dmi.v4->event_nr; + info->major = MAJOR(dmt->dmi.v4->dev); + info->minor = MINOR(dmt->dmi.v4->dev); + + return 1; +} + +const char *dm_task_get_name(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_name_v1(dmt); +#endif + + return (dmt->dmi.v4->name); +} + +const char *dm_task_get_uuid(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_uuid_v1(dmt); +#endif + + return (dmt->dmi.v4->uuid); +} + +struct dm_deps *dm_task_get_deps(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_deps_v1(dmt); +#endif + + return (struct dm_deps *) (((void *) dmt->dmi.v4) + + dmt->dmi.v4->data_start); +} + +struct dm_names *dm_task_get_names(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_names_v1(dmt); +#endif + + return (struct dm_names *) (((void *) dmt->dmi.v4) + + dmt->dmi.v4->data_start); +} + +int dm_task_set_ro(struct dm_task *dmt) +{ + dmt->read_only = 1; + return 1; +} + +int dm_task_set_newname(struct dm_task *dmt, const char *newname) +{ + if (!(dmt->newname = strdup(newname))) { + log_error("dm_task_set_newname: strdup(%s) failed", newname); + return 0; + } + + return 1; +} + +int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr) +{ + dmt->event_nr = event_nr; + + return 1; +} + +struct target *create_target(uint64_t start, uint64_t len, const char *type, + const char *params) +{ + struct target *t = malloc(sizeof(*t)); + + if (!t) { + log_error("create_target: malloc(%d) failed", sizeof(*t)); + return NULL; + } + + memset(t, 0, sizeof(*t)); + + if (!(t->params = strdup(params))) { + log_error("create_target: strdup(params) failed"); + goto bad; + } + + if (!(t->type = strdup(type))) { + log_error("create_target: strdup(type) failed"); + goto bad; + } + + t->start = start; + t->length = len; + return t; + + bad: + free(t->params); + free(t->type); + free(t); + return NULL; +} + +static void *_add_target(struct target *t, void *out, void *end) +{ + void *out_sp = out; + struct dm_target_spec sp; + size_t sp_size = sizeof(struct dm_target_spec); + int len; + const char no_space[] = "Ran out of memory building ioctl parameter"; + + out += sp_size; + if (out >= end) { + log_error(no_space); + return NULL; + } + + sp.status = 0; + sp.sector_start = t->start; + sp.length = t->length; + strncpy(sp.target_type, t->type, sizeof(sp.target_type)); + + len = strlen(t->params); + + if ((out + len + 1) >= end) { + log_error(no_space); + + log_error("t->params= '%s'", t->params); + return NULL; + } + strcpy((char *) out, t->params); + out += len + 1; + + /* align next block */ + out = _align(out, ALIGNMENT); + + sp.next = out - out_sp; + memcpy(out_sp, &sp, sp_size); + + return out; +} + +static struct dm_ioctl *_flatten(struct dm_task *dmt) +{ + const size_t min_size = 16 * 1024; + const int (*version)[3]; + + struct dm_ioctl *dmi; + struct target *t; + size_t len = sizeof(struct dm_ioctl); + void *b, *e; + int count = 0; + + for (t = dmt->head; t; t = t->next) { + len += sizeof(struct dm_target_spec); + len += strlen(t->params) + 1 + ALIGNMENT; + count++; + } + + if (count && dmt->newname) { + log_error("targets and newname are incompatible"); + return NULL; + } + + if (dmt->newname) + len += strlen(dmt->newname) + 1; + + /* + * Give len a minimum size so that we have space to store + * dependencies or status information. + */ + if (len < min_size) + len = min_size; + + if (!(dmi = malloc(len))) + return NULL; + + memset(dmi, 0, len); + + version = &_cmd_data_v4[dmt->type].version; + + dmi->version[0] = (*version)[0]; + dmi->version[1] = (*version)[1]; + dmi->version[2] = (*version)[2]; + + dmi->data_size = len; + dmi->data_start = sizeof(struct dm_ioctl); + + if (dmt->dev_name) + strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); + + if (dmt->type == DM_DEVICE_SUSPEND) + dmi->flags |= DM_SUSPEND_FLAG; + if (dmt->read_only) + dmi->flags |= DM_READONLY_FLAG; + + if (dmt->minor >= 0) { + if (dmt->major <= 0) { + log_error("Missing major number for persistent device"); + return NULL; + } + dmi->flags |= DM_PERSISTENT_DEV_FLAG; + dmi->dev = MKDEV(dmt->major, dmt->minor); + } + + if (dmt->uuid) + strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); + + dmi->target_count = count; + dmi->event_nr = dmt->event_nr; + + b = (void *) (dmi + 1); + e = (void *) ((char *) dmi + len); + + for (t = dmt->head; t; t = t->next) + if (!(b = _add_target(t, b, e))) + goto bad; + + if (dmt->newname) + strcpy(b, dmt->newname); + + return dmi; + + bad: + free(dmi); + return NULL; +} + +static int _create_and_load_v4(struct dm_task *dmt) +{ + struct dm_task *task; + int r; + + /* Use new task struct to create the device */ + if (!(task = dm_task_create(DM_DEVICE_CREATE))) { + log_error("Failed to create device-mapper task struct"); + return 0; + } + + /* Copy across relevant fields */ + if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { + dm_task_destroy(task); + return 0; + } + + if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) { + dm_task_destroy(task); + return 0; + } + + task->major = dmt->major; + task->minor = dmt->minor; + + r = dm_task_run(task); + dm_task_destroy(task); + if (!r) + return r; + + /* Next load the table */ + if (!(task = dm_task_create(DM_DEVICE_RELOAD))) { + log_error("Failed to create device-mapper task struct"); + return 0; + } + + /* Copy across relevant fields */ + if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { + dm_task_destroy(task); + return 0; + } + + task->read_only = dmt->read_only; + task->head = dmt->head; + task->tail = dmt->tail; + + r = dm_task_run(task); + + task->head = NULL; + task->tail = NULL; + dm_task_destroy(task); + if (!r) + return r; + + /* Use the original structure last so the info will be correct */ + dmt->type = DM_DEVICE_RESUME; + dmt->uuid = NULL; + free(dmt->uuid); + + r = dm_task_run(dmt); + + return r; +} + +int dm_task_run(struct dm_task *dmt) +{ + struct dm_ioctl *dmi = NULL; + unsigned int command; + +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_run_v1(dmt); +#endif + + if ((unsigned) dmt->type >= + (sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) { + log_error("Internal error: unknown device-mapper task %d", + dmt->type); + goto bad; + } + + command = _cmd_data_v4[dmt->type].cmd; + + /* Old-style creation had a table supplied */ + if (dmt->type == DM_DEVICE_CREATE && dmt->head) + return _create_and_load_v4(dmt); + + if (!_open_control()) + return 0; + + dmi = _flatten(dmt); + if (!dmi) { + log_error("Couldn't create ioctl argument"); + return 0; + } + + if (dmt->type == DM_DEVICE_TABLE) + dmi->flags |= DM_STATUS_TABLE_FLAG; + + dmi->flags |= DM_EXISTS_FLAG; /* FIXME */ + log_debug("dm %s %s %s %s", _cmd_data_v4[dmt->type].name, dmi->name, + dmi->uuid, dmt->newname ? dmt->newname : ""); + if (ioctl(_control_fd, command, dmi) < 0) { + if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) || + (dmt->type == DM_DEVICE_MKNODES))) { + dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */ + goto ignore_error; + } + if (_log_suppress) + log_verbose("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + else + log_error("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + goto bad; + } + + ignore_error: + switch (dmt->type) { + case DM_DEVICE_CREATE: + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); + break; + + case DM_DEVICE_REMOVE: + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_RENAME: + rename_dev_node(dmt->dev_name, dmt->newname); + break; + + case DM_DEVICE_MKNODES: + if (dmi->flags & DM_EXISTS_FLAG) + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), + MINOR(dmi->dev)); + else + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_STATUS: + case DM_DEVICE_TABLE: + case DM_DEVICE_WAITEVENT: + if (!_unmarshal_status(dmt, dmi)) + goto bad; + break; + } + + dmt->dmi.v4 = dmi; + return 1; + + bad: + free(dmi); + return 0; +} + +void dm_lib_release(void) +{ + if (_control_fd != -1) { + close(_control_fd); + _control_fd = -1; + } + update_devs(); +} + +void dm_lib_exit(void) +{ + if (_control_fd != -1) { + close(_control_fd); + _control_fd = -1; + } + _version_ok = 1; + _version_checked = 0; +} diff --git a/extras/multipath/libdevmapper/ioctl/libdm-compat.h b/extras/multipath/libdevmapper/ioctl/libdm-compat.h new file mode 100644 index 0000000000..af7a9f1f71 --- /dev/null +++ b/extras/multipath/libdevmapper/ioctl/libdm-compat.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef _LINUX_LIBDM_COMPAT_H +#define _LINUX_LIBDM_COMPAT_H + +#include +#include +#include +#include + +struct dm_task; +struct dm_info; + +/* + * Old versions of structures for backwards compatibility. + */ + +struct dm_ioctl_v1 { + uint32_t version[3]; /* in/out */ + uint32_t data_size; /* total size of data passed in + * including this struct */ + + uint32_t data_start; /* offset to start of data + * relative to start of this struct */ + + int32_t target_count; /* in/out */ + int32_t open_count; /* out */ + uint32_t flags; /* in/out */ + + __kernel_dev_t dev; /* in/out */ + + char name[DM_NAME_LEN]; /* device name */ + char uuid[DM_UUID_LEN]; /* unique identifier for + * the block device */ +}; + +struct dm_target_spec_v1 { + int32_t status; /* used when reading from kernel only */ + uint64_t sector_start; + uint32_t length; + uint32_t next; + + char target_type[DM_MAX_TYPE_NAME]; + +}; + +struct dm_target_deps_v1 { + uint32_t count; + + __kernel_dev_t dev[0]; /* out */ +}; + +enum { + /* Top level cmds */ + DM_VERSION_CMD_V1 = 0, + DM_REMOVE_ALL_CMD_V1, + + /* device level cmds */ + DM_DEV_CREATE_CMD_V1, + DM_DEV_REMOVE_CMD_V1, + DM_DEV_RELOAD_CMD_V1, + DM_DEV_RENAME_CMD_V1, + DM_DEV_SUSPEND_CMD_V1, + DM_DEV_DEPS_CMD_V1, + DM_DEV_STATUS_CMD_V1, + + /* target level cmds */ + DM_TARGET_STATUS_CMD_V1, + DM_TARGET_WAIT_CMD_V1, +}; + +#define DM_VERSION_V1 _IOWR(DM_IOCTL, DM_VERSION_CMD_V1, struct dm_ioctl) +#define DM_REMOVE_ALL_V1 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD_V1, struct dm_ioctl) + +#define DM_DEV_CREATE_V1 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD_V1, struct dm_ioctl) +#define DM_DEV_REMOVE_V1 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD_V1, struct dm_ioctl) +#define DM_DEV_RELOAD_V1 _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD_V1, struct dm_ioctl) +#define DM_DEV_SUSPEND_V1 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD_V1, struct dm_ioctl) +#define DM_DEV_RENAME_V1 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD_V1, struct dm_ioctl) +#define DM_DEV_DEPS_V1 _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD_V1, struct dm_ioctl) +#define DM_DEV_STATUS_V1 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD_V1, struct dm_ioctl) + +#define DM_TARGET_STATUS_V1 _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD_V1, struct dm_ioctl) +#define DM_TARGET_WAIT_V1 _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD_V1, struct dm_ioctl) + +/* *INDENT-OFF* */ +static struct cmd_data _cmd_data_v1[] = { + { "create", DM_DEV_CREATE_V1, {1, 0, 0} }, + { "reload", DM_DEV_RELOAD_V1, {1, 0, 0} }, + { "remove", DM_DEV_REMOVE_V1, {1, 0, 0} }, + { "remove_all", DM_REMOVE_ALL_V1, {1, 0, 0} }, + { "suspend", DM_DEV_SUSPEND_V1, {1, 0, 0} }, + { "resume", DM_DEV_SUSPEND_V1, {1, 0, 0} }, + { "info", DM_DEV_STATUS_V1, {1, 0, 0} }, + { "deps", DM_DEV_DEPS_V1, {1, 0, 0} }, + { "rename", DM_DEV_RENAME_V1, {1, 0, 0} }, + { "version", DM_VERSION_V1, {1, 0, 0} }, + { "status", DM_TARGET_STATUS_V1, {1, 0, 0} }, + { "table", DM_TARGET_STATUS_V1, {1, 0, 0} }, + { "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} }, + { "names", 0, {4, 0, 0} }, + { "clear", 0, {4, 0, 0} }, + { "mknodes", 0, {4, 0, 0} }, +}; +/* *INDENT-ON* */ + +#endif diff --git a/extras/multipath/libdevmapper/ioctl/libdm-targets.h b/extras/multipath/libdevmapper/ioctl/libdm-targets.h new file mode 100644 index 0000000000..a8c0e20547 --- /dev/null +++ b/extras/multipath/libdevmapper/ioctl/libdm-targets.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef LIB_DMTARGETS_H +#define LIB_DMTARGETS_H + +#include + +struct dm_ioctl; +struct dm_ioctl_v1; + +struct target { + uint64_t start; + uint64_t length; + char *type; + char *params; + + struct target *next; +}; + +struct dm_task { + int type; + char *dev_name; + + struct target *head, *tail; + + int read_only; + uint32_t event_nr; + int major; + int minor; + union { + struct dm_ioctl *v4; + struct dm_ioctl_v1 *v1; + } dmi; + char *newname; + + char *uuid; +}; + +struct cmd_data { + const char *name; + const int cmd; + const int version[3]; +}; + +int dm_check_version(void); + +#endif diff --git a/extras/multipath/libdevmapper/libdevmapper.h b/extras/multipath/libdevmapper/libdevmapper.h new file mode 100644 index 0000000000..6549af3641 --- /dev/null +++ b/extras/multipath/libdevmapper/libdevmapper.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef LIB_DEVICE_MAPPER_H +#define LIB_DEVICE_MAPPER_H + +#include +#include + +#ifdef linux +# include +#endif + +/* + * Since it is quite laborious to build the ioctl + * arguments for the device-mapper people are + * encouraged to use this library. + * + * You will need to build a struct dm_task for + * each ioctl command you want to execute. + */ + +typedef void (*dm_log_fn) (int level, const char *file, int line, + const char *f, ...); + +/* + * The library user may wish to register their own + * logging function, by default errors go to + * stderr. + */ +void dm_log_init(dm_log_fn fn); +void dm_log_init_verbose(int level); + +enum { + DM_DEVICE_CREATE, + DM_DEVICE_RELOAD, + DM_DEVICE_REMOVE, + DM_DEVICE_REMOVE_ALL, + + DM_DEVICE_SUSPEND, + DM_DEVICE_RESUME, + + DM_DEVICE_INFO, + DM_DEVICE_DEPS, + DM_DEVICE_RENAME, + + DM_DEVICE_VERSION, + + DM_DEVICE_STATUS, + DM_DEVICE_TABLE, + DM_DEVICE_WAITEVENT, + + DM_DEVICE_LIST, + + DM_DEVICE_CLEAR, + + DM_DEVICE_MKNODES +}; + +struct dm_task; + +struct dm_task *dm_task_create(int type); +void dm_task_destroy(struct dm_task *dmt); + +int dm_task_set_name(struct dm_task *dmt, const char *name); +int dm_task_set_uuid(struct dm_task *dmt, const char *uuid); + +/* + * Retrieve attributes after an info. + */ +struct dm_info { + int exists; + int suspended; + int live_table; + int inactive_table; + int32_t open_count; + uint32_t event_nr; + uint32_t major; + uint32_t minor; /* minor device number */ + int read_only; /* 0:read-write; 1:read-only */ + + int32_t target_count; +}; + +struct dm_deps { + uint32_t count; + uint32_t filler; + uint64_t device[0]; +}; + +struct dm_names { + uint64_t dev; + uint32_t next; /* Offset to next struct from start of this struct */ + char name[0]; +}; + +int dm_get_library_version(char *version, size_t size); +int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size); +int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi); +const char *dm_task_get_name(struct dm_task *dmt); +const char *dm_task_get_uuid(struct dm_task *dmt); + +struct dm_deps *dm_task_get_deps(struct dm_task *dmt); +struct dm_names *dm_task_get_names(struct dm_task *dmt); + +int dm_task_set_ro(struct dm_task *dmt); +int dm_task_set_newname(struct dm_task *dmt, const char *newname); +int dm_task_set_minor(struct dm_task *dmt, int minor); +int dm_task_set_major(struct dm_task *dmt, int major); +int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr); + +/* + * Use these to prepare for a create or reload. + */ +int dm_task_add_target(struct dm_task *dmt, + uint64_t start, + uint64_t size, const char *ttype, const char *params); + +/* + * Format major/minor numbers correctly for input to driver + */ +int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor); + +/* Use this to retrive target information returned from a STATUS call */ +void *dm_get_next_target(struct dm_task *dmt, + void *next, uint64_t *start, uint64_t *length, + char **target_type, char **params); + +/* + * Call this to actually run the ioctl. + */ +int dm_task_run(struct dm_task *dmt); + +/* + * Configure the device-mapper directory + */ +int dm_set_dev_dir(const char *dir); +const char *dm_dir(void); + +/* Release library resources */ +void dm_lib_release(void); +void dm_lib_exit(void); + +#endif /* LIB_DEVICE_MAPPER_H */ diff --git a/extras/multipath/libdevmapper/libdm-common.c b/extras/multipath/libdevmapper/libdm-common.c new file mode 100644 index 0000000000..b0affd1eed --- /dev/null +++ b/extras/multipath/libdevmapper/libdm-common.c @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#include "libdm-targets.h" +#include "libdm-common.h" +#include "list.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEV_DIR "/dev/" + +static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; + +static int _verbose = 0; + +/* + * Library users can provide their own logging + * function. + */ +static void _default_log(int level, const char *file, int line, + const char *f, ...) +{ + va_list ap; + + if (level > _LOG_WARN && !_verbose) + return; + + va_start(ap, f); + + if (level < _LOG_WARN) + vfprintf(stderr, f, ap); + else + vprintf(f, ap); + + va_end(ap); + + if (level < _LOG_WARN) + fprintf(stderr, "\n"); + else + fprintf(stdout, "\n"); +} + +dm_log_fn _log = _default_log; + +void dm_log_init(dm_log_fn fn) +{ + _log = fn; +} + +void dm_log_init_verbose(int level) +{ + _verbose = level; +} + +static void _build_dev_path(char *buffer, size_t len, const char *dev_name) +{ + /* If there's a /, assume caller knows what they're doing */ + if (strchr(dev_name, '/')) + snprintf(buffer, len, "%s", dev_name); + else + snprintf(buffer, len, "%s/%s", _dm_dir, dev_name); +} + +int dm_get_library_version(char *version, size_t size) +{ + strncpy(version, DM_LIB_VERSION, size); + return 1; +} + +struct dm_task *dm_task_create(int type) +{ + struct dm_task *dmt = malloc(sizeof(*dmt)); + + if (!dm_check_version()) + return NULL; + + if (!dmt) { + log_error("dm_task_create: malloc(%d) failed", sizeof(*dmt)); + return NULL; + } + + memset(dmt, 0, sizeof(*dmt)); + + dmt->type = type; + dmt->minor = -1; + dmt->major = -1; + + return dmt; +} + +int dm_task_set_name(struct dm_task *dmt, const char *name) +{ + char *pos; + char path[PATH_MAX]; + struct stat st1, st2; + + if (dmt->dev_name) { + free(dmt->dev_name); + dmt->dev_name = NULL; + } + + /* If path was supplied, remove it if it points to the same device + * as its last component. + */ + if ((pos = strrchr(name, '/'))) { + snprintf(path, sizeof(path), "%s/%s", _dm_dir, pos + 1); + + if (stat(name, &st1) || stat(path, &st2) || + !(st1.st_dev == st2.st_dev)) { + log_error("dm_task_set_name: Device %s not found", + name); + return 0; + } + + name = pos + 1; + } + + if (!(dmt->dev_name = strdup(name))) { + log_error("dm_task_set_name: strdup(%s) failed", name); + return 0; + } + + return 1; +} + +int dm_task_set_uuid(struct dm_task *dmt, const char *uuid) +{ + if (dmt->uuid) { + free(dmt->uuid); + dmt->uuid = NULL; + } + + if (!(dmt->uuid = strdup(uuid))) { + log_error("dm_task_set_uuid: strdup(%s) failed", uuid); + return 0; + } + + return 1; +} + +int dm_task_set_major(struct dm_task *dmt, int major) +{ + dmt->major = major; + log_debug("Setting major: %d", dmt->major); + + return 1; +} + +int dm_task_set_minor(struct dm_task *dmt, int minor) +{ + dmt->minor = minor; + log_debug("Setting minor: %d", dmt->minor); + + return 1; +} + +int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size, + const char *ttype, const char *params) +{ + struct target *t = create_target(start, size, ttype, params); + + if (!t) + return 0; + + if (!dmt->head) + dmt->head = dmt->tail = t; + else { + dmt->tail->next = t; + dmt->tail = t; + } + + return 1; +} + +static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) +{ + char path[PATH_MAX]; + struct stat info; + dev_t dev = MKDEV(major, minor); + + _build_dev_path(path, sizeof(path), dev_name); + + if (stat(path, &info) >= 0) { + if (!S_ISBLK(info.st_mode)) { + log_error("A non-block device file at '%s' " + "is already present", path); + return 0; + } + + if (info.st_rdev == dev) + return 1; + + if (unlink(path) < 0) { + log_error("Unable to unlink device node for '%s'", + dev_name); + return 0; + } + } + + if (mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, dev) < 0) { + log_error("Unable to make device node for '%s'", dev_name); + return 0; + } + + return 1; +} + +static int _rename_dev_node(const char *old_name, const char *new_name) +{ + char oldpath[PATH_MAX]; + char newpath[PATH_MAX]; + struct stat info; + + _build_dev_path(oldpath, sizeof(oldpath), old_name); + _build_dev_path(newpath, sizeof(newpath), new_name); + + if (stat(newpath, &info) == 0) { + if (!S_ISBLK(info.st_mode)) { + log_error("A non-block device file at '%s' " + "is already present", newpath); + return 0; + } + + if (unlink(newpath) < 0) { + if (errno == EPERM) { + /* devfs, entry has already been renamed */ + return 1; + } + log_error("Unable to unlink device node for '%s'", + new_name); + return 0; + } + } + + if (rename(oldpath, newpath) < 0) { + log_error("Unable to rename device node from '%s' to '%s'", + old_name, new_name); + return 0; + } + + return 1; +} + +static int _rm_dev_node(const char *dev_name) +{ + char path[PATH_MAX]; + struct stat info; + + _build_dev_path(path, sizeof(path), dev_name); + + if (stat(path, &info) < 0) + return 1; + + if (unlink(path) < 0) { + log_error("Unable to unlink device node for '%s'", dev_name); + return 0; + } + + return 1; +} + +typedef enum { + NODE_ADD, + NODE_DEL, + NODE_RENAME +} node_op_t; + +static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major, + uint32_t minor, const char *old_name) +{ + switch (type) { + case NODE_ADD: + return _add_dev_node(dev_name, major, minor); + case NODE_DEL: + return _rm_dev_node(dev_name); + case NODE_RENAME: + return _rename_dev_node(old_name, dev_name); + } + + return 1; +} + +static LIST_INIT(_node_ops); + +struct node_op_parms { + struct list list; + node_op_t type; + char *dev_name; + uint32_t major; + uint32_t minor; + char *old_name; + char names[0]; +}; + +static void _store_str(char **pos, char **ptr, const char *str) +{ + strcpy(*pos, str); + *ptr = *pos; + *pos += strlen(*ptr) + 1; +} + +static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major, + uint32_t minor, const char *old_name) +{ + struct node_op_parms *nop; + size_t len = strlen(dev_name) + strlen(old_name) + 2; + char *pos; + + if (!(nop = malloc(sizeof(*nop) + len))) { + log_error("Insufficient memory to stack mknod operation"); + return 0; + } + + pos = nop->names; + nop->type = type; + nop->major = major; + nop->minor = minor; + + _store_str(&pos, &nop->dev_name, dev_name); + _store_str(&pos, &nop->old_name, old_name); + + list_add(&_node_ops, &nop->list); + + return 1; +} + +static void _pop_node_ops(void) +{ + struct list *noph, *nopht; + struct node_op_parms *nop; + + list_iterate_safe(noph, nopht, &_node_ops) { + nop = list_item(noph, struct node_op_parms); + _do_node_op(nop->type, nop->dev_name, nop->major, nop->minor, + nop->old_name); + list_del(&nop->list); + free(nop); + } +} + +int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) +{ + return _stack_node_op(NODE_ADD, dev_name, major, minor, ""); +} + +int rename_dev_node(const char *old_name, const char *new_name) +{ + return _stack_node_op(NODE_RENAME, new_name, 0, 0, old_name); +} + +int rm_dev_node(const char *dev_name) +{ + return _stack_node_op(NODE_DEL, dev_name, 0, 0, ""); +} + +void update_devs(void) +{ + _pop_node_ops(); +} + +int dm_set_dev_dir(const char *dir) +{ + snprintf(_dm_dir, sizeof(_dm_dir), "%s%s", dir, DM_DIR); + return 1; +} + +const char *dm_dir(void) +{ + return _dm_dir; +} diff --git a/extras/multipath/libdevmapper/libdm-common.h b/extras/multipath/libdevmapper/libdm-common.h new file mode 100644 index 0000000000..2b71242861 --- /dev/null +++ b/extras/multipath/libdevmapper/libdm-common.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef LIB_DMCOMMON_H +#define LIB_DMCOMMON_H + +#include "libdevmapper.h" + +#define _LOG_DEBUG 7 +#define _LOG_INFO 6 +#define _LOG_NOTICE 5 +#define _LOG_WARN 4 +#define _LOG_ERR 3 +#define _LOG_FATAL 2 + +extern dm_log_fn _log; + +#define log_error(msg, x...) _log(_LOG_ERR, __FILE__, __LINE__, msg, ## x) +#define log_print(msg, x...) _log(_LOG_WARN, __FILE__, __LINE__, msg, ## x) +#define log_verbose(msg, x...) _log(_LOG_NOTICE, __FILE__, __LINE__, msg, ## x) +#define log_very_verbose(msg, x...) _log(_LOG_INFO, __FILE__, __LINE__, msg, ## x) +#define log_debug(msg, x...) _log(_LOG_DEBUG, __FILE__, __LINE__, msg, ## x) + +struct target *create_target(uint64_t start, + uint64_t len, + const char *type, const char *params); + +int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major); +int rm_dev_node(const char *dev_name); +int rename_dev_node(const char *old_name, const char *new_name); +void update_devs(void); + +#define DM_LIB_VERSION "1.00.07-ioctl (2003-11-21)" + +#endif diff --git a/extras/multipath/libdevmapper/list.h b/extras/multipath/libdevmapper/list.h new file mode 100644 index 0000000000..df3d32aea8 --- /dev/null +++ b/extras/multipath/libdevmapper/list.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2001 Sistina Software + * + * This file is released under the LGPL. + */ + +#ifndef _LVM_LIST_H +#define _LVM_LIST_H + +#include + +struct list { + struct list *n, *p; +}; + +#define LIST_INIT(name) struct list name = { &(name), &(name) } + +static inline void list_init(struct list *head) +{ + head->n = head->p = head; +} + +static inline void list_add(struct list *head, struct list *elem) +{ + assert(head->n); + + elem->n = head; + elem->p = head->p; + + head->p->n = elem; + head->p = elem; +} + +static inline void list_add_h(struct list *head, struct list *elem) +{ + assert(head->n); + + elem->n = head->n; + elem->p = head; + + head->n->p = elem; + head->n = elem; +} + +static inline void list_del(struct list *elem) +{ + elem->n->p = elem->p; + elem->p->n = elem->n; +} + +static inline int list_empty(struct list *head) +{ + return head->n == head; +} + +static inline int list_end(struct list *head, struct list *elem) +{ + return elem->n == head; +} + +static inline struct list *list_next(struct list *head, struct list *elem) +{ + return (list_end(head, elem) ? NULL : elem->n); +} + +#define list_iterate(v, head) \ + for (v = (head)->n; v != head; v = v->n) + +#define list_uniterate(v, head, start) \ + for (v = (start)->p; v != head; v = v->p) + +#define list_iterate_safe(v, t, head) \ + for (v = (head)->n, t = v->n; v != head; v = t, t = v->n) + +static inline unsigned int list_size(const struct list *head) +{ + unsigned int s = 0; + const struct list *v; + + list_iterate(v, head) + s++; + + return s; +} + +#define list_item(v, t) \ + ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list)) + +#define list_struct_base(v, t, h) \ + ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h)) + +/* Given a known element in a known structure, locate another */ +#define struct_field(v, t, e, f) \ + (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f) + +/* Given a known element in a known structure, locate the list head */ +#define list_head(v, t, e) struct_field(v, t, e, list) + +#endif diff --git a/extras/multipath/main.c b/extras/multipath/main.c index b5ab664433..f3f92e7eba 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "libdevmapper/libdevmapper.h" #include "main.h" static int @@ -458,9 +458,7 @@ static int make_dm_node(char * str) { int r = 0; - dev_t dev; char buff[FILE_NAME_SIZE]; - int major, minor; struct dm_names * names; unsigned next = 0; struct dm_task *dmt; @@ -486,14 +484,9 @@ make_dm_node(char * str) names = (void *) names + next; } while (next); - major = (int) MAJOR(names->dev); - minor = (int) MINOR(names->dev); - - dev = major << sizeof(dev_t); - dev = dev | minor; sprintf(buff, "/dev/mapper/%s", str); unlink(buff); - mknod(buff, 0600 | S_IFBLK, dev); + mknod(buff, 0600 | S_IFBLK, names->dev); out: dm_task_destroy(dmt); @@ -729,9 +722,10 @@ main(int argc, char *argv[]) if (conf.verbose) { print_all_path(&conf, all_paths); - printf("\n"); + fprintf(stdout, "\n"); print_all_mp(all_paths, mp, nmp); - printf("\n"); + fprintf(stdout, "\n"); + //printf("\n"); } if (conf.dry_run) diff --git a/extras/multipath/main.h b/extras/multipath/main.h index 019cb843a8..692e5e4595 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -46,7 +46,7 @@ #define TUR_CMD_LEN 6 #define MX_ALLOC_LEN 255 #define BLKGETSIZE _IO(0x12,96) -#define DM_TARGET "multipath" +#define DM_TARGET "striped" #define PINDEX(x,y) mp[(x)].pindex[(y)] @@ -105,8 +105,8 @@ struct env { /* Build version */ #define PROG "multipath" -#define VERSION_CODE 0x000006 -#define DATE_CODE 0x271103 +#define VERSION_CODE 0x000009 +#define DATE_CODE 0x0C0503 #define MULTIPATH_VERSION(version) \ (version >> 16) & 0xFF, \ From d877515791ae4d625d396cdb3a35903cdbf6fde6 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Sun, 7 Dec 2003 08:48:23 -0800 Subject: [PATCH 0258/4284] [PATCH] more extras/multipath updates * Adds a /var/run/multipath.run handling to avoid simultaneous runs. * Remove a commented-out "printf" --- extras/multipath/main.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/extras/multipath/main.c b/extras/multipath/main.c index f3f92e7eba..9bceb265ba 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -660,9 +660,19 @@ usage(char * progname) exit(1); } +static int +running(char * run) { + struct stat buf; + + if(!stat(run, &buf)) + return 1; + return 0; +} + int main(int argc, char *argv[]) { + char * run = "/var/run/multipath.run"; struct multipath * mp; struct path * all_paths; struct scsi_dev * all_scsi_ids; @@ -705,12 +715,26 @@ main(int argc, char *argv[]) } + if (running(run)) { + if (conf.verbose) { + fprintf(stderr, "Already running.\n"); + fprintf(stderr, "If you know what you do, please "); + fprintf(stderr, "remove %s\n", run); + } + return 1; + } + + if(!open(run, O_CREAT)) + exit(1); + /* dynamic allocations */ mp = malloc(conf.max_devs * sizeof(struct multipath)); all_paths = malloc(conf.max_devs * sizeof(struct path)); all_scsi_ids = malloc(conf.max_devs * sizeof(struct scsi_dev)); - if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) + if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) { + unlink(run); exit(1); + } if (!conf.with_sysfs) { get_all_scsi_ids(&conf, all_scsi_ids); @@ -725,11 +749,12 @@ main(int argc, char *argv[]) fprintf(stdout, "\n"); print_all_mp(all_paths, mp, nmp); fprintf(stdout, "\n"); - //printf("\n"); } - if (conf.dry_run) + if (conf.dry_run) { + unlink(run); exit(0); + } for (k=0; k<=nmp; k++) { if (map_present(mp[k].wwid)) { @@ -738,5 +763,6 @@ main(int argc, char *argv[]) add_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); } } + unlink(run); exit(0); } From a652254ddba3f77abf63f732c42c3a0136dc03d2 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Sun, 7 Dec 2003 08:50:19 -0800 Subject: [PATCH 0259/4284] [PATCH] yet more extras/multipath * implement a reschedule flag in /var/run. Last thing the prog do before exit is check if a call to multipath was done (but canceled by /var/run/multipath.run check) during its execution. If so restart the main loop. * implement a blacklist of sysfs bdev to not bother with for now (hd, md, dm, sr, scd, ram, raw). This avoid sending SG_IO to unappropiate devices. Compiles & survive "while true;do (./multipath -v &);done" --- extras/multipath/main.c | 47 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 9bceb265ba..bc65899ce1 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -195,6 +195,31 @@ basename(char * str1, char * str2) strcpy(str2, ++p); } +static int +blacklist (char * dev) { + int i; + static struct { + char * headstr; + int lengh; + } blist[] = { + {"cciss", 5}, + {"hd", 2}, + {"md", 2}, + {"dm", 2}, + {"sr", 2}, + {"scd", 3}, + {"ram", 3}, + {"raw", 3}, + {NULL, 0}, + }; + + for (i = 0; blist[i].lengh; i++) { + if (strncmp(dev, blist[i].headstr, blist[i].lengh)) + return 1; + } + return 0; +} + static int get_all_paths_sysfs(struct env * conf, struct path * all_paths) { @@ -211,6 +236,8 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sdir = sysfs_open_directory(block_path); sysfs_read_directory(sdir); dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { + if (blacklist(devp->name)) + continue; sysfs_read_directory(devp); if(devp->links == NULL) continue; @@ -661,7 +688,7 @@ usage(char * progname) } static int -running(char * run) { +filepresent(char * run) { struct stat buf; if(!stat(run, &buf)) @@ -673,6 +700,7 @@ int main(int argc, char *argv[]) { char * run = "/var/run/multipath.run"; + char * resched = "/var/run/multipath.reschedule"; struct multipath * mp; struct path * all_paths; struct scsi_dev * all_scsi_ids; @@ -715,18 +743,17 @@ main(int argc, char *argv[]) } - if (running(run)) { + if (filepresent(run)) { if (conf.verbose) { fprintf(stderr, "Already running.\n"); fprintf(stderr, "If you know what you do, please "); fprintf(stderr, "remove %s\n", run); } + /* leave a trace that we were called while already running */ + open(resched, O_CREAT); return 1; } - if(!open(run, O_CREAT)) - exit(1); - /* dynamic allocations */ mp = malloc(conf.max_devs * sizeof(struct multipath)); all_paths = malloc(conf.max_devs * sizeof(struct path)); @@ -735,6 +762,9 @@ main(int argc, char *argv[]) unlink(run); exit(1); } +start: + if(!open(run, O_CREAT)) + exit(1); if (!conf.with_sysfs) { get_all_scsi_ids(&conf, all_scsi_ids); @@ -764,5 +794,12 @@ main(int argc, char *argv[]) } } unlink(run); + + /* start again if we were ask to during this process run */ + /* ie. do not loose an event-asked run */ + if (filepresent(resched)) { + unlink(resched); + goto start; + } exit(0); } From 1bed1db4994aae37f4a11e90dabcd8b4e3592686 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Sun, 7 Dec 2003 08:55:40 -0800 Subject: [PATCH 0260/4284] [PATCH] update udev extras/scsi_id to version 0.2 This patch updates scsi_id under udev from version 0.1 to version 0.2. --- extras/scsi_id/ChangeLog | 64 ++++++++++++++++++ extras/scsi_id/Makefile | 24 +++++-- extras/scsi_id/README | 4 +- extras/scsi_id/TODO | 21 +++--- extras/scsi_id/VERSION | 1 - extras/scsi_id/scsi_id.8 | 118 +++++++++++++++++++++++++++++++++ extras/scsi_id/scsi_id.c | 124 ++++++++++++++++++----------------- extras/scsi_id/scsi_id.h | 21 +++++- extras/scsi_id/scsi_serial.c | 34 ++++++++-- 9 files changed, 321 insertions(+), 90 deletions(-) create mode 100644 extras/scsi_id/ChangeLog delete mode 100644 extras/scsi_id/VERSION create mode 100644 extras/scsi_id/scsi_id.8 diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog new file mode 100644 index 0000000000..7f2317723d --- /dev/null +++ b/extras/scsi_id/ChangeLog @@ -0,0 +1,64 @@ +2003-dec-05: + * Makefile, scsi_id.8: Add a man page. + +2003-dec-04: + * Makefile: Set and use variables that might be passed down when + built under udev (with or without klibc), don't set LDFLAGS or + STRIP. + +2003-dec-04: + * scsi_id.c, scsi_id.h: Fix a bad bug - when parsing file options, + no space was allocated for the creation of the new argv[] + strings. + +2003-dec-04: + * scsi_id.c: Catch too long a line in the config file. + +2003-dec-02: + * scsi_id.h: Add u8 typedef to avoid ummm scsi.h kernel header + problem when built with klibc. + +2003-dec-02: + * scsi_id.h: Add define of makedev() if built with klibc. + +2003-dec-02: + * scsi_id.c: reset optind to 1 since klibc does not work if it is + reset to zero. + +2003-dec-02: + * scsi_id.c: remove fflush() as it is not needed, and is not + supported by klibc. + +2003-dec-02: + * scsi_serial.c: Make the functions do_scsi_page0_inquiry and + do_scsi_page80_inquiry static. + +2003-dec-01: + * scsi_id.c: Don't use syslog LOG_PID, as it is not supported by + klibc. + +2003-dec-01: + * scsi_id.c, scsi_serial.c: Hack - change include path to libsysfs + if built under klibc. + +2003-dec-01: + * Makefile: Use "override" for CFLAGS so we can pass CFLAGS values + down when built with udev + +2003-dec-01: + * scsi_id.c, Makefile: Use SCSI_ID_VERSION instead of VERSION. + +2003-nov-25: + * scsi_id.c: Remove getopt_long (long option names), as there + is no support for that in klibc. + +2003-nov-17: + * scsi_id.c: Patch from Brian King: check result of setting model, + not vendor in per_dev_options. + +2003-nov-03: + * scsi_id.c, scsi_serial.c: Use new and correct path to libsysfs.h. + +2003-nov-03: + * scsi_id.h: Fix scsi_id.h so var args in marcros works ok with + older gcc. diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 5ad2bcf3e1..ead205682a 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,33 +14,45 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -VERSION=0.1 +SCSI_ID_VERSION=0.2 prefix = sbindir = ${prefix}/sbin +mandir = ${prefix}/usr/share/man INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 -CFLAGS=-DVERSION=\"$(VERSION)\" $(DEBUG) -Wall +# Note some of the variables used here are set when built under udev, and +# otherwise might not be set. + +override CFLAGS+=-DSCSI_ID_VERSION=\"$(SCSI_ID_VERSION)\" $(DEBUG) -Wall PROG=scsi_id +SYSFS=-lsysfs -LIBSYSFS=-lsysfs -STRIP=-s -LDFLAGS=$(STRIP) --static +# +# Built static and stripped when built with udev. +# +# STRIP=-s +# LDFLAGS=$(STRIP) +LD=$(CC) OBJS= scsi_id.o \ scsi_serial.o \ all: $(PROG) +# XXX use a compressed man page? + install: all $(INSTALL_PROGRAM) -D $(PROG) $(sbindir)/$(PROG) + $(INSTALL_DATA) -D scsi_id.8 $(DESTDIR)$(mandir)/man8/scsi_id.8 uninstall: -rm $(sbindir)/$(PROG) + -rm $(mandir)/man8/scsi_id.8 $(OBJS): scsi_id.h scsi.h @@ -48,4 +60,4 @@ clean: rm -f $(PROG) $(OBJS) $(PROG): $(OBJS) - $(CC) $(OBJS) $(LDFLAGS) $(LIBSYSFS) -o $(PROG) + $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) diff --git a/extras/scsi_id/README b/extras/scsi_id/README index b13cf1e50a..4281c318a2 100644 --- a/extras/scsi_id/README +++ b/extras/scsi_id/README @@ -5,9 +5,9 @@ used by a multi-path configuration tool that requires SCSI id's. Requires: -- Linux kernel 2.6 + - Linux kernel 2.6 -- libsysfs + - libsysfs No man page yet. diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO index ba52101431..5d020c276a 100644 --- a/extras/scsi_id/TODO +++ b/extras/scsi_id/TODO @@ -1,16 +1,11 @@ -- Investigate shrinking build size: use klibc or uClibc, or copy whatever - udev does +- add information abou the config file to the man page -- write a man page +- change so non-KLIBC builds under udev don't use /usr/include/sysfs, + but instead use the sysfs included with udev (needs udev change and/or + sysfsutils changes). -- send in kernel patch for REQ_BLOCK_PC, to always set sd and sr set - retries (scmd->allowed) to <= 1 +- do something with callout code - remove or change to a tag? -- Pull SG_IO code into one .c file. - -- implement callout to device specific serial id code. The "-c prog" is - not implemented. - - This needs an implementation of a device specific callout before it can - be completed. Someone with hardware requiring this needs to send in a - patch. + This needs an implementation of a device specific callout or device + specific code (called via some special "tag" or such) before it can be + completed. Someone with such hardware to send in a patch. diff --git a/extras/scsi_id/VERSION b/extras/scsi_id/VERSION deleted file mode 100644 index 49d59571fb..0000000000 --- a/extras/scsi_id/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.1 diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 new file mode 100644 index 0000000000..a4fb881a05 --- /dev/null +++ b/extras/scsi_id/scsi_id.8 @@ -0,0 +1,118 @@ +.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-g\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 -p 0x80 -s /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 -p 0x83 -s /block/sdg +3600a0b80000b174b000000d63efc5c8c +.fi +.P + + +.SH OPTIONS +.TP +.BI \-b +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 \-d "\| 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. +.TP +.BI \-e +Send all output to standard error even if +.B scsi_id +is running in hotplug mode. +.TP +.BI \-f "\| 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 \-g +Treat the device as white listed. The \fB\-g\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 \-i +Prefix the identification string with the driver model (sysfs) bus id of +the SCSI device. +.TP +.BI \-p "\| 0x80 | 0x83" +Use SCSI INQUIRY VPD page code 0x80 or 0x83. The default behaviour is to +query the available VPD pages, and use page 0x83 if found, else page 0x80 +if found, else nothing. +.TP +.BI \-s "\|sysfs-device" +Generate an id for the +.B sysfs-device. +The sysfs mount point must not be included. For example, use /block/sd, +not /sys/block/sd. +.TP +.BI \-v +Generate verbose debugging output. +.TP +.BI \-V +Display version number and exit. +.RE +.SH "FILES" +.nf +.ft B +.ft +/etc/scsi_id.config configuration and black/white list entries +.fi +.LP +.SH "SEE ALSO" +.BR udev (8) +, especially the CALLOUT method. +.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/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index d34d9284e5..df18271b48 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include @@ -33,12 +32,19 @@ #include #include #include -#include +#ifdef __KLIBC__ +/* + * Assume built under udev with KLIBC + */ +#include +#else +#include +#endif #include "scsi_id.h" -#ifndef VERSION +#ifndef SCSI_ID_VERSION #warning No version -#define VERSION "unknown" +#define SCSI_ID_VERSION "unknown" #endif /* @@ -49,36 +55,11 @@ #define CONFIG_FILE "/etc/scsi_id.config" -#define MAX_NAME_LEN 72 - -#define MAX_SERIAL_LEN 128 - static const char short_options[] = "bc:d:ef:gip:s:vV"; -static const struct option long_options[] = { - {"broken", no_argument, NULL, 'b'}, /* also per dev */ - {"callout", required_argument, NULL, 'c'}, /* also per dev */ - {"device", required_argument, NULL, 'd'}, - {"stderr", no_argument, NULL, 'e'}, - {"file", required_argument, NULL, 'f'}, - {"good", no_argument, NULL, 'g'}, /* also per dev */ - {"busid", no_argument, NULL, 'i'}, /* also per dev */ - {"page", required_argument, NULL, 'p'}, /* also per dev */ - {"devpath", required_argument, NULL, 's'}, - {"verbose", no_argument, NULL, 'v'}, - {"version", no_argument, NULL, 'V'}, - {0, 0, 0, 0} -}; /* * Just duplicate per dev options. */ static const char dev_short_options[] = "bc:gp:"; -static const struct option dev_long_options[] = { - {"broken", no_argument, NULL, 'b'}, /* also per dev */ - {"callout", required_argument, NULL, 'c'}, /* also per dev */ - {"good", no_argument, NULL, 'g'}, /* also per dev */ - {"page", required_argument, NULL, 'p'}, /* also per dev */ - {0, 0, 0, 0} -}; char sysfs_mnt_path[SYSFS_PATH_MAX]; @@ -105,8 +86,13 @@ void log_message (int level, const char *format, ...) vfprintf(stderr, format, args); } else { static int logging_init = 0; + static unsigned char logname[32]; if (!logging_init) { - openlog ("scsi_id", LOG_PID, LOG_DAEMON); + /* + * klibc does not have LOG_PID. + */ + snprintf(logname, 32, "scsi_id[%d]", getpid()); + openlog (logname, 0, LOG_DAEMON); logging_init = 1; } @@ -295,7 +281,7 @@ static int argc_count(char *opts) static int get_file_options(char *vendor, char *model, int *argc, char ***newargv) { - char buffer[256]; + char *buffer; FILE *fd; char *buf; char *str1; @@ -303,7 +289,6 @@ static int get_file_options(char *vendor, char *model, int *argc, int lineno; int c; int retval = 0; - static char *prog_string = "arg0"; dprintf("vendor='%s'; model='%s'\n", vendor, model); fd = fopen(config_file, "r"); @@ -318,16 +303,31 @@ static int get_file_options(char *vendor, char *model, int *argc, } } + /* + * 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) { + log_message(LOG_WARNING, "Can't allocate memory.\n"); + return -1; + } + *newargv = NULL; lineno = 0; - while (1) { vendor_in = model_in = options_in = NULL; - buf = fgets(buffer, sizeof(buffer), fd); + buf = fgets(buffer, MAX_BUFFER_LEN, fd); if (buf == NULL) break; lineno++; + if (buf[strlen(buffer) - 1] != '\n') { + log_message(LOG_WARNING, + "Config file line %d too long.\n", lineno); + break; + } while (isspace(*buf)) buf++; @@ -419,18 +419,24 @@ static int get_file_options(char *vendor, char *model, int *argc, * Something matched. Allocate newargv, and store * values found in options_in. */ - c = argc_count(options_in) + 2; + strcpy(buffer, options_in); + c = argc_count(buffer) + 2; *newargv = calloc(c, sizeof(**newargv)); if (!*newargv) { log_message(LOG_WARNING, - "Can't allocate memory\n"); + "Can't allocate memory.\n"); retval = -1; } else { *argc = c; c = 0; - (*newargv)[c] = prog_string; /* nothing */ + /* + * argv[0] at 0 is skipped by getopt, but + * store the buffer address there for + * alter freeing. + */ + (*newargv)[c] = buffer; for (c = 1; c < *argc; c++) - (*newargv)[c] = strsep(&options_in, " "); + (*newargv)[c] = strsep(&buffer, " "); } } else { /* @@ -439,26 +445,26 @@ static int get_file_options(char *vendor, char *model, int *argc, retval = 1; } } + if (retval != 0) + free(buffer); fclose(fd); return retval; } static int set_options(int argc, char **argv, const char *short_opts, - const struct option *long_opts, char *target, - char *maj_min_dev) + char *target, char *maj_min_dev) { int option; - int option_ind; /* - * optind is a global extern used by getopt_long. Since we can - * call set_options twice (once for command line, and once for - * config file) we have to reset this back to 0. + * 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. [Note glibc handles + * setting this to 0, but klibc does not.] */ - optind = 0; + optind = 1; while (1) { - option = getopt_long(argc, argv, short_options, long_options, - &option_ind); + option = getopt(argc, argv, short_options); if (option == -1) break; @@ -521,7 +527,7 @@ static int set_options(int argc, char **argv, const char *short_opts, case 'V': log_message(LOG_WARNING, "scsi_id version: %s\n", - VERSION); + SCSI_ID_VERSION); exit(0); break; @@ -544,8 +550,6 @@ static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, char *vendor; char *model; int option; - int option_ind; - *good_bad = all_good; *page_code = default_page_code; @@ -562,7 +566,7 @@ static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, } model = sysfs_get_attr(scsi_dev, "model"); - if (!vendor) { + if (!model) { log_message(LOG_WARNING, "%s: no model attribute\n", scsi_dev->name); return -1; @@ -570,10 +574,9 @@ static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, retval = get_file_options(vendor, model, &newargc, &newargv); - optind = 0; /* global extern, reset to 0 */ + optind = 1; /* reset this global extern */ while (retval == 0) { - option = getopt_long(newargc, newargv, dev_short_options, - dev_long_options, &option_ind); + option = getopt(newargc, newargv, dev_short_options); if (option == -1) break; @@ -616,8 +619,10 @@ static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, } } - if (newargv) + if (newargv) { + free(newargv[0]); free(newargv); + } return retval; } @@ -747,7 +752,6 @@ static int scsi_id(const char *target_path, char *maj_min_dev) dprintf("%s\n", serial); retval = 0; } - fflush(stdout); sysfs_close_class_device(scsi_dev); if (!dev_specified) @@ -797,8 +801,8 @@ int main(int argc, char **argv) strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); strncat(target_path, devpath, MAX_NAME_LEN); } else { - if (set_options(argc, argv, short_options, long_options, - target_path, maj_min_dev) < 0) + if (set_options(argc, argv, short_options, target_path, + maj_min_dev) < 0) exit(1); } @@ -811,8 +815,8 @@ int main(int argc, char **argv) if (retval < 0) { exit(1); } else if (newargv && (retval == 0)) { - if (set_options(newargc, newargv, short_options, long_options, - target_path, maj_min_dev) < 0) + if (set_options(newargc, newargv, short_options, target_path, + maj_min_dev) < 0) exit(1); free(newargv); } diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 8be492b75a..eb9498ab71 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -22,11 +22,23 @@ */ #define dprintf(format, arg...) \ - log_message(LOG_DEBUG, "%s: " format, __FUNCTION__, ## arg) + log_message(LOG_DEBUG, "%s: " format, __FUNCTION__ , ## arg) #define MAX_NAME_LEN 72 #define OFFSET (2 * sizeof(unsigned int)) +/* + * MAX_SERIAL_LEN: the maximum length of the serial number, including + * added prefixes such as vendor and product (model) strings. + */ +#define MAX_SERIAL_LEN 128 + +/* + * MAX_BUFFER_LEN: maximum buffer size and line length used while reading + * the config file. + */ +#define MAX_BUFFER_LEN 256 + static inline char *sysfs_get_attr(struct sysfs_class_device *dev, const char *attr) { @@ -40,3 +52,10 @@ extern int scsi_get_serial (struct sysfs_class_device *scsi_dev, extern void log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +#ifdef __KLIBC__ +#define makedev(major, minor) ((major) << 8) | (minor) +#endif + +#ifndef u8 +typedef unsigned char u8; +#endif diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 302429c0d4..18cd290817 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -31,7 +31,14 @@ #include #include #include -#include +#ifdef __KLIBC__ +/* + * Assume built under udev with KLIBC + */ +#include +#else +#include +#endif #include "scsi_id.h" #include "scsi.h" @@ -348,6 +355,11 @@ resend: retval = scsi_dump(scsi_dev, &io_hdr); } + /* + * XXX where is the length checked? That is, was our request + * buffer long enough? + */ + if (!retval) { retval = buflen; memcpy(buf, buffer, retval); @@ -369,8 +381,8 @@ resend: * Ending here. */ -int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, - char *buffer, int len) +static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, + char *buffer, int len) { int retval; char *vendor; @@ -527,8 +539,10 @@ static int check_fill_0x83_id(struct sysfs_class_device *scsi_dev, serial[0] = hex_str[id_search->id_type]; /* - * Prepend the vendor and model before the id since if it is not - * unique across all vendors and models. + * 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(scsi_dev, &serial[1]) < 0) { @@ -575,6 +589,12 @@ static int do_scsi_page83_inquiry(struct sysfs_class_device *scsi_dev, int fd, scsi_dev->name); 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 ". + */ /* * Search for a match in the prioritized id_search_list. @@ -609,8 +629,8 @@ static int do_scsi_page83_inquiry(struct sysfs_class_device *scsi_dev, int fd, return 1; } -int do_scsi_page80_inquiry(struct sysfs_class_device *scsi_dev, int fd, - char *serial, int max_len) +static int do_scsi_page80_inquiry(struct sysfs_class_device *scsi_dev, int fd, + char *serial, int max_len) { int retval; int ser_ind; From eadb1bbc2eece84d9aff79bf17e252106c37f355 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Sun, 7 Dec 2003 09:04:49 -0800 Subject: [PATCH 0261/4284] [PATCH] better allow builds of extras programs under udev Here is an improved version of the patch that enables builds of the extras progams for the targets all, clean, install, and uninstall, and passes down the "prefix" for use by install and uninstall. This patch enables building of the "extras" programs using the same build environment as udev (i.e. build with udev's versions of klibc and sysfsutils). For example, build scsi_id and udev via: make EXTRAS=extras/scsi_id Build scsi_id and udev with klibc via: make KLIBC=true EXTRAS=extras/scsi_id --- Makefile | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index c6f322c880..aa1d45bdb7 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,9 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} +# To build any of the extras programs, run with: +# make EXTRAS="extras/a extras/b" +EXTRAS= # place to put our device nodes udevdir = ${prefix}/udev/ @@ -60,7 +63,7 @@ AR = $(CROSS)ar STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib -export CROSS CC AR STRIP RANLIB +export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH_LIB_OBJS CRT0 # code taken from uClibc to determine the current arch ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ @@ -108,20 +111,20 @@ endif # If we are using our version of klibc, then we need to build and link it. # Otherwise, use glibc and link statically. ifeq ($(strip $(KLIBC)),true) - KLIBC_DIR = klibc/klibc + KLIBC_BASE = $(PWD)/klibc + KLIBC_DIR = $(KLIBC_BASE)/klibc INCLUDE_DIR := $(KLIBC_DIR)/include + LINUX_INCLUDE_DIR := $(KLIBC_BASE)/linux/include include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG # arch specific objects - LIBGCC = $(shell $(CC) --print-libgcc) ARCH_LIB_OBJS = \ - $(KLIBC_DIR)/libc.a \ - $(LIBGCC) + $(KLIBC_DIR)/libc.a CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(KLIBC_DIR)/arch/$(ARCH)/include \ - -I$(INCLUDE_DIR)/bits$(BITSIZE) -I$(GCCINCDIR) -Iklibc/linux/include \ + -I$(INCLUDE_DIR)/bits$(BITSIZE) -I$(GCCINCDIR) -I$(LINUX_INCLUDE_DIR) \ -D__KLIBC__ LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs @@ -133,7 +136,14 @@ else LDFLAGS = --static endif +CFLAGS += -I$(PWD)/libsysfs + all: $(ROOT) + @for target in $(EXTRAS) ; do \ + echo $$target ; \ + $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + -C $$target $@ ; \ + done ; \ $(ROOT): $(LIBC) @@ -145,13 +155,13 @@ $(CRT0): TDB = tdb/tdb.o \ tdb/spinlock.o -SYSFS = libsysfs/sysfs_bus.o \ - libsysfs/sysfs_class.o \ - libsysfs/sysfs_device.o \ - libsysfs/sysfs_dir.o \ - libsysfs/sysfs_driver.o \ - libsysfs/sysfs_utils.o \ - libsysfs/dlist.o +SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ + $(PWD)/libsysfs/sysfs_class.o \ + $(PWD)/libsysfs/sysfs_device.o \ + $(PWD)/libsysfs/sysfs_dir.o \ + $(PWD)/libsysfs/sysfs_driver.o \ + $(PWD)/libsysfs/sysfs_utils.o \ + $(PWD)/libsysfs/dlist.o OBJS = udev.o \ udev_config.o \ @@ -192,6 +202,11 @@ clean: | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(MAKE) -C klibc clean + @for target in $(EXTRAS) ; do \ + echo $$target ; \ + $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + -C $$target $@ ; \ + done ; \ DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) DISTDIR := $(RELEASE_NAME) @@ -236,6 +251,11 @@ install: all $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug + @for target in $(EXTRAS) ; do \ + echo $$target ; \ + $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + -C $$target $@ ; \ + done ; \ uninstall: - rm $(hotplugdir)/udev.hotplug @@ -247,5 +267,10 @@ uninstall: - rmdir $(hotplugdir) - rmdir $(configdir) - rmdir $(udevdir) + @for target in $(EXTRAS) ; do \ + echo $$target ; \ + $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + -C $$target $@ ; \ + done ; \ From 3d150dfb28efbaf0b25f154fb8955c47d606c3d5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 7 Dec 2003 09:12:07 -0800 Subject: [PATCH 0262/4284] [PATCH] experimental (very simple) SYMLINK creation > > here is a experimental symlink creation patch - for discussion, > > in which direction we should go. > > It is possible now to define SYMLINK= after the NAME= in udev.rules. > > The link is relative to the node, but the path is not optimized now > > if the node and the link are in the same nested directory. > > Only one link is supported, cause i need to sleep now :) > > > > 06-simple-symlink-creation.diff > > simple symlink creation > > reorganized udev-remove to have access to the symlink field > > subdir creation/removal are functions now > > udev-test.pl tests for link creation/removal Here is a new version with relative link target path optimization an better tests in udev-test.pl: LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="1/2/a/b/node", SYMLINK="1/2/c/d/symlink" Dec 7 06:48:34 pim udev[13789]: create_node: symlink 'udev-root/1/2/c/d/symlink' to node '1/2/a/b/node' requested Dec 7 06:48:34 pim udev[13789]: create_path: created 'udev-root/1/2/c' Dec 7 06:48:34 pim udev[13789]: create_path: created 'udev-root/1/2/c/d' Dec 7 06:48:34 pim udev[13789]: create_node: symlink(../../a/b/node, udev-root/1/2/c/d/symlink) --- namedev.c | 9 +++- namedev.h | 1 + namedev_parse.c | 58 +++++++++++++++++---- test/udev-test.pl | 41 ++++++++++++++- udev-add.c | 99 ++++++++++++++++++++++++++---------- udev-remove.c | 125 ++++++++++++++++++++++------------------------ udev.h | 1 + 7 files changed, 228 insertions(+), 106 deletions(-) diff --git a/namedev.c b/namedev.c index 1faa253c1e..fbdb125e4c 100644 --- a/namedev.c +++ b/namedev.c @@ -121,6 +121,7 @@ int add_config_dev(struct config_device *new_dev) copy_string(dev, new_dev, place); copy_string(dev, new_dev, kernel_name); copy_string(dev, new_dev, exec_program); + copy_string(dev, new_dev, symlink); return 0; } @@ -366,6 +367,7 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev if (strcmp_pattern(dev->id, udev->callout_value) != 0) continue; strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); dbg("callout returned matching value '%s', '%s' becomes '%s'", dev->id, class_dev->name, udev->name); return 0; @@ -416,6 +418,7 @@ label_found: continue; strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); dbg("found matching attribute '%s', '%s' becomes '%s' ", dev->sysfs_file, class_dev->name, udev->name); @@ -461,6 +464,7 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, if (!found) continue; strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); dbg("found matching id '%s', '%s' becomes '%s'", dev->id, class_dev->name, udev->name); return 0; @@ -506,6 +510,7 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude continue; strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); dbg("found matching place '%s', '%s' becomes '%s'", dev->place, class_dev->name, udev->name); return 0; @@ -528,6 +533,7 @@ static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev continue; strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); dbg("found name, '%s' becomes '%s'", dev->kernel_name, udev->name); return 0; @@ -618,8 +624,9 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud goto done; found: - /* substitute placeholder in NAME */ + /* substitute placeholder */ apply_format(udev, udev->name); + apply_format(udev, udev->symlink); done: perm = find_perm(udev->name); diff --git a/namedev.h b/namedev.h index f7b8a67667..39cf3ae641 100644 --- a/namedev.h +++ b/namedev.h @@ -63,6 +63,7 @@ struct config_device { char kernel_name[NAME_SIZE]; char exec_program[FILE_SIZE]; char name[NAME_SIZE]; + char symlink[NAME_SIZE]; }; struct perm_device { diff --git a/namedev_parse.c b/namedev_parse.c index 5cb3a3eb1d..b5d0d64b9d 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -213,10 +213,16 @@ int namedev_init_rules(void) break; strfieldcpy(dev.name, temp3); + /* SYMLINK="name" */ + temp2 = strsep(&temp, ","); + retval = get_value("SYMLINK", &temp, &temp3); + if (retval == 0) + strfieldcpy(dev.symlink, temp3); + dbg_parse("LABEL name='%s', bus='%s', " - "sysfs_file='%s', sysfs_value='%s'", + "sysfs_file='%s', sysfs_value='%s', symlink='%s'", dev.name, dev.bus, dev.sysfs_file, - dev.sysfs_value); + dev.sysfs_value, dev.symlink); } if (strcasecmp(temp2, TYPE_NUMBER) == 0) { @@ -243,8 +249,14 @@ int namedev_init_rules(void) break; strfieldcpy(dev.name, temp3); - dbg_parse("NUMBER name='%s', bus='%s', id='%s'", - dev.name, dev.bus, dev.id); + /* SYMLINK="name" */ + temp2 = strsep(&temp, ","); + retval = get_value("SYMLINK", &temp, &temp3); + if (retval == 0) + strfieldcpy(dev.symlink, temp3); + + dbg_parse("NUMBER name='%s', bus='%s', id='%s', symlink='%s'", + dev.name, dev.bus, dev.id, dev.symlink); } if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { @@ -271,8 +283,15 @@ int namedev_init_rules(void) break; strfieldcpy(dev.name, temp3); - dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'", - dev.name, dev.bus, dev.place); + /* SYMLINK="name" */ + temp2 = strsep(&temp, ","); + retval = get_value("SYMLINK", &temp, &temp3); + if (retval == 0) + strfieldcpy(dev.symlink, temp3); + + dbg_parse("TOPOLOGY name='%s', bus='%s', " + "place='%s', symlink='%s'", + dev.name, dev.bus, dev.place, dev.symlink); } if (strcasecmp(temp2, TYPE_REPLACE) == 0) { @@ -291,9 +310,17 @@ int namedev_init_rules(void) if (retval) break; strfieldcpy(dev.name, temp3); - dbg_parse("REPLACE name='%s', kernel_name='%s'", - dev.name, dev.kernel_name); + + /* SYMLINK="name" */ + temp2 = strsep(&temp, ","); + retval = get_value("SYMLINK", &temp, &temp3); + if (retval == 0) + strfieldcpy(dev.symlink, temp3); + + dbg_parse("REPLACE name='%s', kernel_name='%s', symlink='%s'", + dev.name, dev.kernel_name, dev.symlink); } + if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { /* number type */ dev.type = CALLOUT; @@ -324,8 +351,17 @@ int namedev_init_rules(void) if (retval) break; strfieldcpy(dev.name, temp3); - dbg_parse("CALLOUT name='%s', program='%s'", - dev.name, dev.exec_program); + + /* SYMLINK="name" */ + temp2 = strsep(&temp, ","); + retval = get_value("SYMLINK", &temp, &temp3); + if (retval == 0) + strfieldcpy(dev.symlink, temp3); + + dbg_parse("CALLOUT name='%s', bus='%s', program='%s', " + "id='%s', symlink='%s'", + dev.name, dev.bus, dev.exec_program, + dev.id, dev.symlink); } retval = add_config_dev(&dev); @@ -414,7 +450,7 @@ int namedev_init_permissions(void) dev.mode); retval = add_perm_dev(&dev); if (retval) { - dbg("add_config_dev returned with error %d", retval); + dbg("add_perm_dev returned with error %d", retval); goto exit; } } diff --git a/test/udev-test.pl b/test/udev-test.pl index b1757ee1bb..190b7ce4d6 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -39,7 +39,7 @@ my @tests = ( expected => "boot_disk" , conf => < "symlink creation (same directory)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor0" , + conf => < "symlink creation (relative link back)", + subsys => "block", + devpath => "block/sda/sda2", + expected => "1/2/a/b/symlink" , + conf => < "symlink creation (relative link forward)", + subsys => "block", + devpath => "block/sda/sda2", + expected => "1/2/symlink" , + conf => < "symlink creation (relative link back and forward)", + subsys => "block", + devpath => "block/sda/sda2", + expected => "1/2/c/d/symlink" , + conf => <{subsys}, $config->{devpath}, \$config->{conf}); - if (-e "$PWD/$udev_root$config->{expected}") { + if ((-e "$PWD/$udev_root$config->{expected}") || + (-l "$PWD/$udev_root$config->{expected}")) { print "remove: error\n\n"; system("tree $udev_root"); $error++; diff --git a/udev-add.c b/udev-add.c index a71d435e32..ddf432bbc7 100644 --- a/udev-add.c +++ b/udev-add.c @@ -72,6 +72,34 @@ exit: return retval; } +static int create_path(char *file) +{ + char p[NAME_SIZE]; + char *pos; + int retval; + struct stat stats; + + strncpy(p, file, sizeof(p)); + pos = strchr(p+1, '/'); + while (1) { + pos = strchr(pos+1, '/'); + if (pos == NULL) + break; + *pos = 0x00; + if (stat(p, &stats)) { + retval = mkdir(p, 0755); + if (retval) { + dbg("mkdir(%s) failed with error '%s'", + p, strerror(errno)); + return retval; + } + dbg("created '%s'", p); + } + *pos = '/'; + } + return 0; +} + /* * we possibly want to add some symlinks here * only numeric owner/group id's are supported @@ -79,10 +107,14 @@ exit: static int create_node(struct udevice *dev) { char filename[255]; + char linktarget[255]; int retval = 0; uid_t uid = 0; gid_t gid = 0; dev_t res; + int i; + int tail; + strncpy(filename, udev_root, sizeof(filename)); strncat(filename, dev->name, sizeof(filename)); @@ -109,31 +141,9 @@ static int create_node(struct udevice *dev) return -EINVAL; } - /* create subdirectories if requested */ - if (strchr(dev->name, '/')) { - char path[255]; - char *pos; - struct stat stats; - - strncpy(path, filename, sizeof(path)); - pos = strchr(path+1, '/'); - while (1) { - pos = strchr(pos+1, '/'); - if (pos == NULL) - break; - *pos = 0x00; - if (stat(path, &stats)) { - retval = mkdir(path, 0755); - if (retval) { - dbg("mkdir(%s) failed with error '%s'", - path, strerror(errno)); - return retval; - } - dbg("created '%s'", path); - } - *pos = '/'; - } - } + /* create parent directories if needed */ + if (strrchr(dev->name, '/')) + create_path(filename); dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); retval = mknod(filename, dev->mode, res); @@ -179,8 +189,43 @@ static int create_node(struct udevice *dev) dbg("chown(%s, %u, %u)", filename, uid, gid); retval = chown(filename, uid, gid); if (retval) - dbg("chown(%s, %u, %u) failed with error '%s'", filename, - uid, gid, strerror(errno)); + dbg("chown(%s, %u, %u) failed with error '%s'", + filename, uid, gid, strerror(errno)); + } + + + /* create symlink if requested */ + if (*dev->symlink) { + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, dev->symlink, sizeof(filename)); + dbg("symlink '%s' to node '%s' requested", filename, dev->name); + if (strrchr(dev->symlink, '/')) + create_path(filename); + + /* optimize relative link */ + linktarget[0] = '\0'; + i = 0; + tail = 0; + while ((dev->name[i] == dev->symlink[i]) && dev->name[i]) { + if (dev->name[i] == '/') + tail = i+1; + i++; + } + while (dev->symlink[i]) { + if (dev->symlink[i] == '/') + strcat(linktarget, "../"); + i++; + } + + if (*linktarget == '\0') + strcpy(linktarget, "./"); + strcat(linktarget, &dev->name[tail]); + + dbg("symlink(%s, %s)", linktarget, filename); + retval = symlink(linktarget, filename); + if (retval) + dbg("symlink(%s, %s) failed with error '%s'", + linktarget, filename, strerror(errno)); } return retval; diff --git a/udev-remove.c b/udev-remove.c index 0f14a3d685..d42ed4be78 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -34,47 +34,43 @@ #include "udevdb.h" #include "libsysfs/libsysfs.h" - -/* - * Look up the sysfs path in the database to see if we have named this device - * something different from the kernel name. If we have, us it. If not, use - * the default kernel name for lack of anything else to know to do. - */ -static char *get_name(char *path, int major, int minor) +static int delete_path(char *path) { - static char name[100]; - struct udevice *dev; - char *temp; + char *pos; + int retval; - dev = udevdb_get_dev(path); - if (dev != NULL) { - strcpy(name, dev->name); - goto exit; + pos = strrchr(path, '/'); + while (1) { + *pos = '\0'; + pos = strrchr(path, '/'); + + /* don't remove the last one */ + if ((pos == path) || (pos == NULL)) + break; + + /* remove if empty */ + retval = rmdir(path); + if (retval) { + if (errno == ENOTEMPTY) + return 0; + dbg("rmdir(%s) failed with error '%s'", + path, strerror(errno)); + break; + } + dbg("removed '%s'", path); } - - dbg("'%s' not found in database, falling back on default name", path); - temp = strrchr(path, '/'); - if (temp == NULL) - return NULL; - strncpy(name, &temp[1], sizeof(name)); - -exit: - dbg("name is '%s'", name); - return &name[0]; + return 0; } -/* - * We also want to clean up any symlinks that were created in create_node() - */ -static int delete_node(char *name) +static int delete_node(struct udevice *dev) { char filename[255]; int retval; strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, name, sizeof(filename)); + strncat(filename, dev->name, sizeof(filename)); - dbg("unlinking '%s'", filename); + dbg("unlinking node '%s'", filename); retval = unlink(filename); if (retval) { dbg("unlink(%s) failed with error '%s'", @@ -83,49 +79,48 @@ static int delete_node(char *name) } /* remove subdirectories */ - if (strchr(name, '/')) { - char *pos; + if (strchr(dev->name, '/')) + delete_path(filename); - pos = strrchr(filename, '/'); - while (1) { - *pos = 0x00; - pos = strrchr(filename, '/'); - - /* don't remove the last one */ - if ((pos == filename) || (pos == NULL)) - break; - - /* remove if empty */ - retval = rmdir(filename); - if (retval) { - if (errno == ENOTEMPTY) - return 0; - dbg("rmdir(%s) failed with error '%s'", - filename, strerror(errno)); - break; - } - dbg("removed '%s'", filename); + if (*dev->symlink) { + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, dev->symlink, sizeof(filename)); + dbg("unlinking symlink '%s'", filename); + retval = unlink(filename); + if (retval) { + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + return retval; + } + if (strchr(dev->symlink, '/')) { + delete_path(filename); } } + return retval; } -int udev_remove_device(char *device, char *subsystem) +/* + * Look up the sysfs path in the database to see if we have named this device + * something different from the kernel name. If we have, us it. If not, use + * the default kernel name for lack of anything else to know to do. + */ +int udev_remove_device(char *path, char *subsystem) { - char *name; - int retval = 0; + char name[100]; + struct udevice *dev; + char *temp; - name = get_name(device, 0, 0); - if (name == NULL) { - dbg ("get_name failed"); - retval = -ENODEV; - goto exit; + dev = udevdb_get_dev(path); + if (dev == NULL) { + dbg("'%s' not found in database, falling back on default name", path); + temp = strrchr(path, '/'); + if (temp == NULL) + return -ENODEV; + strncpy(name, &temp[1], sizeof(name)); } - udevdb_delete_dev(device); - - return delete_node(name); - -exit: - return retval; + dbg("name is '%s'", dev->name); + udevdb_delete_dev(path); + return delete_node(dev); } diff --git a/udev.h b/udev.h index 01db449481..05f6b3c225 100644 --- a/udev.h +++ b/udev.h @@ -64,6 +64,7 @@ struct udevice { int major; int minor; mode_t mode; + char symlink[NAME_SIZE]; /* fields that help us in building strings */ unsigned char bus_id[SYSFS_NAME_LEN]; From 5aebfbcb62614fc2bf2b1579d62e3fe272c6751a Mon Sep 17 00:00:00 2001 From: "david@fubar.dk" Date: Mon, 8 Dec 2003 09:19:19 -0800 Subject: [PATCH 0263/4284] [PATCH] D-BUS patch for udev-008 Attached is a patch against udev-008 to send out a D-BUS message when a device node is added or removed. Using D-BUS lingo, udev acquires the org.kernel.udev service and sends out a NodeCreated or NodeDeleted signal on the org.kernel.udev.NodeMonitor interface. Each signal carries two parameters: the node in question and the corresponding sysfs path. [Note: the D-BUS concepts of service, interface, object can be a bit confusing at first glance] An example program listening for these messages looks like this #!/usr/bin/python import dbus import gtk def udev_signal_received(dbus_iface, member, service, object_path, message): [filename, sysfs_path] = message.get_args_list() if member=='NodeCreated': print 'Node %s created for %s'%(filename, sysfs_path) elif member=='NodeDeleted': print 'Node %s deleted for %s'%(filename, sysfs_path) def main(): bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) bus.add_signal_receiver(udev_signal_received, 'org.kernel.udev.NodeMonitor', # interface 'org.kernel.udev', # service '/org/kernel/udev/NodeMonitor') # object gtk.mainloop() if __name__ == '__main__': main() and this is the output when hot-plugging some usb-storage. [david@laptop udev-008]$ ~/node_monitor.py Node /udev/sda created for /block/sda Node /udev/sda1 created for /block/sda/sda1 Node /udev/sda1 deleted for /block/sda/sda1 Node /udev/sda deleted for /block/sda The patch requires D-BUS 0.20 or later while the python example program requires D-BUS from CVS as I only recently applied a patch against the python bindings. --- Makefile | 29 +++++++++++++++++-- TODO | 1 - udev-add.c | 42 +++++++++++++++++++++++++++ udev-remove.c | 41 ++++++++++++++++++++++++++ udev.c | 64 +++++++++++++++++++++++++++++++++++++++++ udev.h | 9 ++++++ udev_sysbus_policy.conf | 23 +++++++++++++++ 7 files changed, 206 insertions(+), 3 deletions(-) create mode 100644 udev_sysbus_policy.conf diff --git a/Makefile b/Makefile index aa1d45bdb7..c50bd04824 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,10 @@ # Leave this set to `false' for production use. DEBUG = false +# Set the following to `true' to make udev emit a D-BUS signal when a +# new node is created. +USE_DBUS = true + ROOT = udev VERSION = 008_bk @@ -34,6 +38,7 @@ etcdir = ${prefix}/etc sbindir = ${exec_prefix}/sbin mandir = ${prefix}/usr/share/man hotplugdir = ${etcdir}/hotplug.d/default +dbusdir = ${etcdir}/dbus-1/system.d configdir = ${etcdir}/udev/ srcdir = . @@ -138,6 +143,13 @@ endif CFLAGS += -I$(PWD)/libsysfs +ifeq ($(USE_DBUS), true) + CFLAGS += -DUSE_DBUS + CFLAGS += $(shell pkg-config --cflags dbus-1) + LIB_OBJS += $(shell pkg-config --libs-only-l dbus-1) +endif + + all: $(ROOT) @for target in $(EXTRAS) ; do \ echo $$target ; \ @@ -240,7 +252,20 @@ small_release: $(DISTFILES) clean @echo "Built $(RELEASE_NAME).tar.gz" -install: all +ifeq ($(USE_DBUS), true) +install-dbus-policy: + $(INSTALL) -d $(DESTDIR)$(dbusdir) + $(INSTALL_DATA) udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) +uninstall-dbus-policy: + - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf +else +install-dbus-policy: + - +uninstall-dbus-policy: + - +endif + +install: install-dbus-policy all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(configdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) @@ -257,7 +282,7 @@ install: all -C $$target $@ ; \ done ; \ -uninstall: +uninstall: uninstall-dbus-policy - rm $(hotplugdir)/udev.hotplug - rm $(configdir)/udev.permissions - rm $(configdir)/udev.rules diff --git a/TODO b/TODO index d5cc9194e6..e227834f36 100644 --- a/TODO +++ b/TODO @@ -21,7 +21,6 @@ greg@kroah.com will have an upgrade path. - do early boot logic (putting udev into initramfs, handle pivot-root, etc.) -- add hooks to call D-BUS when new node is created or removed - lots of other stuff... - actually use the BUS= value to determine where the LABEL rule should look (right now it's ignored, and we only look in the current sysfs directory.) diff --git a/udev-add.c b/udev-add.c index ddf432bbc7..174331fade 100644 --- a/udev-add.c +++ b/udev-add.c @@ -100,6 +100,42 @@ static int create_path(char *file) return 0; } +#ifdef USE_DBUS +/** Send out a signal that a device node is created + * + * @param dev udevice object + * @param path Sysfs path of device + */ +static void sysbus_send_create(struct udevice *dev, const char *path) +{ + char filename[255]; + DBusMessage* message; + DBusMessageIter iter; + + if (sysbus_connection == NULL) + return; + + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, dev->name, sizeof(filename)); + + /* object, interface, member */ + message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", + "org.kernel.udev.NodeMonitor", + "NodeCreated"); + + dbus_message_iter_init(message, &iter); + dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, path); + + if ( !dbus_connection_send(sysbus_connection, message, NULL) ) + dbg("error sending d-bus signal"); + + dbus_message_unref(message); + + dbus_connection_flush(sysbus_connection); +} +#endif /* USE_DBUS */ + /* * we possibly want to add some symlinks here * only numeric owner/group id's are supported @@ -323,6 +359,12 @@ int udev_add_device(char *path, char *subsystem) dbg("name='%s'", dev.name); retval = create_node(&dev); +#ifdef USE_DBUS + if (retval == 0) { + sysbus_send_create(&dev, path); + } +#endif /* USE_DBUS */ + exit: if (class_dev) sysfs_close_class_device(class_dev); diff --git a/udev-remove.c b/udev-remove.c index d42ed4be78..307b907c88 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -100,6 +100,42 @@ static int delete_node(struct udevice *dev) return retval; } +#ifdef USE_DBUS +/** Send out a signal that a device node is deleted + * + * @param name Name of the device node, e.g. /udev/sda1 + * @param path Sysfs path of device + */ +static void sysbus_send_remove(const char* name, const char *path) +{ + char filename[255]; + DBusMessage* message; + DBusMessageIter iter; + + if (sysbus_connection == NULL) + return; + + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, name, sizeof(filename)); + + /* object, interface, member */ + message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", + "org.kernel.udev.NodeMonitor", + "NodeDeleted"); + + dbus_message_iter_init(message, &iter); + dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, path); + + if ( !dbus_connection_send(sysbus_connection, message, NULL) ) + dbg("error sending d-bus signal"); + + dbus_message_unref(message); + + dbus_connection_flush(sysbus_connection); +} +#endif /* USE_DBUS */ + /* * Look up the sysfs path in the database to see if we have named this device * something different from the kernel name. If we have, us it. If not, use @@ -122,5 +158,10 @@ int udev_remove_device(char *path, char *subsystem) dbg("name is '%s'", dev->name); udevdb_delete_dev(path); + +#ifdef USE_DBUS + sysbus_send_remove(name, device); +#endif /* USE_DBUS */ + return delete_node(dev); } diff --git a/udev.c b/udev.c index bf18a568ea..67b86e5916 100644 --- a/udev.c +++ b/udev.c @@ -63,6 +63,60 @@ static inline char *get_seqnum(void) return seqnum; } +#ifdef USE_DBUS + +/** Global variable for the connection the to system message bus or #NULL + * if we cannot connect or acquire the org.kernel.udev service + */ +DBusConnection* sysbus_connection; + +/** Disconnect from the system message bus */ +static void sysbus_disconnect() +{ + if (sysbus_connection == NULL) + return; + + dbus_connection_disconnect(sysbus_connection); + sysbus_connection = NULL; +} + +/** Connect to the system message bus */ +static void sysbus_connect() +{ + DBusError error; + + /* Connect to a well-known bus instance, the system bus */ + dbus_error_init(&error); + sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (sysbus_connection == NULL) { + dbg("cannot connect to system message bus, error %s: %s", + error.name, error.message); + dbus_error_free(&error); + return; + } + + /* Acquire the org.kernel.udev service such that listeners + * know that the message is really from us and not from a + * random attacker. See the file udev_sysbus_policy.conf for + * details. + * + * Note that a service can have multiple owners (though there + * is a concept of a primary owner for reception of messages) + * so no race is introduced if two copies of udev is running + * at the same time. + */ + dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, + &error); + if (dbus_error_is_set(&error)) { + printf("cannot acquire org.kernel.udev service, error %s: %s'", + error.name, error.message); + sysbus_disconnect(); + return; + } +} + +#endif /* USE_DBUS */ + int main(int argc, char **argv, char **envp) { char *action; @@ -111,6 +165,11 @@ int main(int argc, char **argv, char **envp) /* initialize our configuration */ udev_init_config(); +#ifdef USE_DBUS + /* connect to the system message bus */ + sysbus_connect(); +#endif /* USE_DBUS */ + /* initialize udev database */ retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { @@ -133,6 +192,11 @@ int main(int argc, char **argv, char **envp) } udevdb_exit(); +#ifdef USE_DBUS + /* disconnect from the system message bus */ + sysbus_disconnect(); +#endif /* USE_DBUS */ + exit: return retval; } diff --git a/udev.h b/udev.h index 05f6b3c225..4ea04d5e71 100644 --- a/udev.h +++ b/udev.h @@ -93,4 +93,13 @@ extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; extern char default_mode_str[NAME_MAX]; +#ifdef USE_DBUS + +#define DBUS_API_SUBJECT_TO_CHANGE +#include + +extern DBusConnection* sysbus_connection; + +#endif /* USE_DBUS */ + #endif diff --git a/udev_sysbus_policy.conf b/udev_sysbus_policy.conf new file mode 100644 index 0000000000..b2660e65cf --- /dev/null +++ b/udev_sysbus_policy.conf @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + From 7ac0feeb6044470569d7ece5d34a76acdb03fc64 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 8 Dec 2003 09:40:40 -0800 Subject: [PATCH 0264/4284] [PATCH] move all of the DBUS logic into one file and remove all of the #ifdef crud from the main code. --- udev-add.c | 44 ++---------------- udev-remove.c | 43 ++--------------- udev.c | 69 +++------------------------ udev.h | 9 ---- udev_dbus.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++ udev_dbus.h | 23 +++++++++ 6 files changed, 161 insertions(+), 153 deletions(-) create mode 100644 udev_dbus.c create mode 100644 udev_dbus.h diff --git a/udev-add.c b/udev-add.c index 174331fade..8d45b26077 100644 --- a/udev-add.c +++ b/udev-add.c @@ -36,6 +36,7 @@ #include "udev.h" #include "udev_version.h" +#include "udev_dbus.h" #include "namedev.h" #include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -100,42 +101,6 @@ static int create_path(char *file) return 0; } -#ifdef USE_DBUS -/** Send out a signal that a device node is created - * - * @param dev udevice object - * @param path Sysfs path of device - */ -static void sysbus_send_create(struct udevice *dev, const char *path) -{ - char filename[255]; - DBusMessage* message; - DBusMessageIter iter; - - if (sysbus_connection == NULL) - return; - - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->name, sizeof(filename)); - - /* object, interface, member */ - message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", - "org.kernel.udev.NodeMonitor", - "NodeCreated"); - - dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, filename); - dbus_message_iter_append_string(&iter, path); - - if ( !dbus_connection_send(sysbus_connection, message, NULL) ) - dbg("error sending d-bus signal"); - - dbus_message_unref(message); - - dbus_connection_flush(sysbus_connection); -} -#endif /* USE_DBUS */ - /* * we possibly want to add some symlinks here * only numeric owner/group id's are supported @@ -359,11 +324,8 @@ int udev_add_device(char *path, char *subsystem) dbg("name='%s'", dev.name); retval = create_node(&dev); -#ifdef USE_DBUS - if (retval == 0) { - sysbus_send_create(&dev, path); - } -#endif /* USE_DBUS */ + if (retval == 0) + sysbus_send_create(&dev, path); exit: if (class_dev) diff --git a/udev-remove.c b/udev-remove.c index 307b907c88..02c84371a4 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -30,6 +30,7 @@ #include "udev.h" #include "udev_version.h" +#include "udev_dbus.h" #include "namedev.h" #include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -100,42 +101,6 @@ static int delete_node(struct udevice *dev) return retval; } -#ifdef USE_DBUS -/** Send out a signal that a device node is deleted - * - * @param name Name of the device node, e.g. /udev/sda1 - * @param path Sysfs path of device - */ -static void sysbus_send_remove(const char* name, const char *path) -{ - char filename[255]; - DBusMessage* message; - DBusMessageIter iter; - - if (sysbus_connection == NULL) - return; - - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, name, sizeof(filename)); - - /* object, interface, member */ - message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", - "org.kernel.udev.NodeMonitor", - "NodeDeleted"); - - dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, filename); - dbus_message_iter_append_string(&iter, path); - - if ( !dbus_connection_send(sysbus_connection, message, NULL) ) - dbg("error sending d-bus signal"); - - dbus_message_unref(message); - - dbus_connection_flush(sysbus_connection); -} -#endif /* USE_DBUS */ - /* * Look up the sysfs path in the database to see if we have named this device * something different from the kernel name. If we have, us it. If not, use @@ -159,9 +124,7 @@ int udev_remove_device(char *path, char *subsystem) dbg("name is '%s'", dev->name); udevdb_delete_dev(path); -#ifdef USE_DBUS - sysbus_send_remove(name, device); -#endif /* USE_DBUS */ - + sysbus_send_remove(name, path); + return delete_node(dev); } diff --git a/udev.c b/udev.c index 67b86e5916..ac29ec6f44 100644 --- a/udev.c +++ b/udev.c @@ -31,6 +31,7 @@ #include "udev.h" #include "udev_version.h" +#include "udev_dbus.h" #include "namedev.h" #include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -63,60 +64,6 @@ static inline char *get_seqnum(void) return seqnum; } -#ifdef USE_DBUS - -/** Global variable for the connection the to system message bus or #NULL - * if we cannot connect or acquire the org.kernel.udev service - */ -DBusConnection* sysbus_connection; - -/** Disconnect from the system message bus */ -static void sysbus_disconnect() -{ - if (sysbus_connection == NULL) - return; - - dbus_connection_disconnect(sysbus_connection); - sysbus_connection = NULL; -} - -/** Connect to the system message bus */ -static void sysbus_connect() -{ - DBusError error; - - /* Connect to a well-known bus instance, the system bus */ - dbus_error_init(&error); - sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - if (sysbus_connection == NULL) { - dbg("cannot connect to system message bus, error %s: %s", - error.name, error.message); - dbus_error_free(&error); - return; - } - - /* Acquire the org.kernel.udev service such that listeners - * know that the message is really from us and not from a - * random attacker. See the file udev_sysbus_policy.conf for - * details. - * - * Note that a service can have multiple owners (though there - * is a concept of a primary owner for reception of messages) - * so no race is introduced if two copies of udev is running - * at the same time. - */ - dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, - &error); - if (dbus_error_is_set(&error)) { - printf("cannot acquire org.kernel.udev service, error %s: %s'", - error.name, error.message); - sysbus_disconnect(); - return; - } -} - -#endif /* USE_DBUS */ - int main(int argc, char **argv, char **envp) { char *action; @@ -165,10 +112,8 @@ int main(int argc, char **argv, char **envp) /* initialize our configuration */ udev_init_config(); -#ifdef USE_DBUS - /* connect to the system message bus */ - sysbus_connect(); -#endif /* USE_DBUS */ + /* connect to the system message bus */ + sysbus_connect(); /* initialize udev database */ retval = udevdb_init(UDEVDB_DEFAULT); @@ -192,11 +137,9 @@ int main(int argc, char **argv, char **envp) } udevdb_exit(); -#ifdef USE_DBUS - /* disconnect from the system message bus */ - sysbus_disconnect(); -#endif /* USE_DBUS */ + /* disconnect from the system message bus */ + sysbus_disconnect(); -exit: +exit: return retval; } diff --git a/udev.h b/udev.h index 4ea04d5e71..05f6b3c225 100644 --- a/udev.h +++ b/udev.h @@ -93,13 +93,4 @@ extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; extern char default_mode_str[NAME_MAX]; -#ifdef USE_DBUS - -#define DBUS_API_SUBJECT_TO_CHANGE -#include - -extern DBusConnection* sysbus_connection; - -#endif /* USE_DBUS */ - #endif diff --git a/udev_dbus.c b/udev_dbus.c new file mode 100644 index 0000000000..57685163c5 --- /dev/null +++ b/udev_dbus.c @@ -0,0 +1,126 @@ +#define DBUS_API_SUBJECT_TO_CHANGE +#include + +#include "udev_dbus.h" + + +/** variable for the connection the to system message bus or #NULL + * if we cannot connect or acquire the org.kernel.udev service + */ +static DBusConnection* sysbus_connection; + +/** Disconnect from the system message bus */ +void sysbus_disconnect(void) +{ + if (sysbus_connection == NULL) + return; + + dbus_connection_disconnect(sysbus_connection); + sysbus_connection = NULL; +} + +/** Connect to the system message bus */ +void sysbus_connect(void) +{ + DBusError error; + + /* Connect to a well-known bus instance, the system bus */ + dbus_error_init(&error); + sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (sysbus_connection == NULL) { + dbg("cannot connect to system message bus, error %s: %s", + error.name, error.message); + dbus_error_free(&error); + return; + } + + /* Acquire the org.kernel.udev service such that listeners + * know that the message is really from us and not from a + * random attacker. See the file udev_sysbus_policy.conf for + * details. + * + * Note that a service can have multiple owners (though there + * is a concept of a primary owner for reception of messages) + * so no race is introduced if two copies of udev is running + * at the same time. + */ + dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, + &error); + if (dbus_error_is_set(&error)) { + printf("cannot acquire org.kernel.udev service, error %s: %s'", + error.name, error.message); + sysbus_disconnect(); + return; + } +} + + +/** Send out a signal that a device node is created + * + * @param dev udevice object + * @param path Sysfs path of device + */ +void sysbus_send_create(struct udevice *dev, const char *path) +{ + char filename[255]; + DBusMessage* message; + DBusMessageIter iter; + + if (sysbus_connection == NULL) + return; + + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, dev->name, sizeof(filename)); + + /* object, interface, member */ + message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", + "org.kernel.udev.NodeMonitor", + "NodeCreated"); + + dbus_message_iter_init(message, &iter); + dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, path); + + if ( !dbus_connection_send(sysbus_connection, message, NULL) ) + dbg("error sending d-bus signal"); + + dbus_message_unref(message); + + dbus_connection_flush(sysbus_connection); +} + +/** Send out a signal that a device node is deleted + * + * @param name Name of the device node, e.g. /udev/sda1 + * @param path Sysfs path of device + */ +void sysbus_send_remove(const char* name, const char *path) +{ + char filename[255]; + DBusMessage* message; + DBusMessageIter iter; + + if (sysbus_connection == NULL) + return; + + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, name, sizeof(filename)); + + /* object, interface, member */ + message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", + "org.kernel.udev.NodeMonitor", + "NodeDeleted"); + + dbus_message_iter_init(message, &iter); + dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, path); + + if ( !dbus_connection_send(sysbus_connection, message, NULL) ) + dbg("error sending d-bus signal"); + + dbus_message_unref(message); + + dbus_connection_flush(sysbus_connection); +} + + diff --git a/udev_dbus.h b/udev_dbus.h new file mode 100644 index 0000000000..afa2046548 --- /dev/null +++ b/udev_dbus.h @@ -0,0 +1,23 @@ +#ifndef UDEV_DBUS_H +#define UDEV_DBUS_H + + +#ifdef USE_DBUS + +extern void sysbus_connect(void); +extern void sysbus_disconnect(void); +extern void sysbus_send_create(struct udevice *dev, const char *path); +extern void sysbus_send_remove(const char* name, const char *path); + +#else + +static inline void sysbus_connect(void) { } +static inline void sysbus_disconnect(void) { } +static inline void sysbus_send_create(struct udevice *dev, const char *path) { } +static inline void sysbus_send_remove(const char* name, const char *path) { } + +#endif /* USE_DBUS */ + + + +#endif From 8e15f01dc8e25eca49b99e97059dccf793e6c4d4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 8 Dec 2003 18:01:28 -0800 Subject: [PATCH 0265/4284] [PATCH] fix formatting of udev_dbus.c to use tabs. Also get it to build properly now. --- udev_dbus.c | 158 +++++++++++++++++++++++++++------------------------- 1 file changed, 83 insertions(+), 75 deletions(-) diff --git a/udev_dbus.c b/udev_dbus.c index 57685163c5..947a5c1b5d 100644 --- a/udev_dbus.c +++ b/udev_dbus.c @@ -1,6 +1,16 @@ +#include +#include +#include +#include +#include +#include +#include + #define DBUS_API_SUBJECT_TO_CHANGE #include +#include "udev.h" +#include "udev_version.h" #include "udev_dbus.h" @@ -12,46 +22,46 @@ static DBusConnection* sysbus_connection; /** Disconnect from the system message bus */ void sysbus_disconnect(void) { - if (sysbus_connection == NULL) - return; + if (sysbus_connection == NULL) + return; - dbus_connection_disconnect(sysbus_connection); - sysbus_connection = NULL; + dbus_connection_disconnect(sysbus_connection); + sysbus_connection = NULL; } /** Connect to the system message bus */ void sysbus_connect(void) { - DBusError error; + DBusError error; - /* Connect to a well-known bus instance, the system bus */ - dbus_error_init(&error); - sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - if (sysbus_connection == NULL) { - dbg("cannot connect to system message bus, error %s: %s", - error.name, error.message); - dbus_error_free(&error); - return; - } + /* Connect to a well-known bus instance, the system bus */ + dbus_error_init(&error); + sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (sysbus_connection == NULL) { + dbg("cannot connect to system message bus, error %s: %s", + error.name, error.message); + dbus_error_free(&error); + return; + } - /* Acquire the org.kernel.udev service such that listeners - * know that the message is really from us and not from a - * random attacker. See the file udev_sysbus_policy.conf for - * details. - * - * Note that a service can have multiple owners (though there - * is a concept of a primary owner for reception of messages) - * so no race is introduced if two copies of udev is running - * at the same time. - */ - dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, - &error); - if (dbus_error_is_set(&error)) { - printf("cannot acquire org.kernel.udev service, error %s: %s'", - error.name, error.message); - sysbus_disconnect(); - return; - } + /* Acquire the org.kernel.udev service such that listeners + * know that the message is really from us and not from a + * random attacker. See the file udev_sysbus_policy.conf for + * details. + * + * Note that a service can have multiple owners (though there + * is a concept of a primary owner for reception of messages) + * so no race is introduced if two copies of udev is running + * at the same time. + */ + dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, + &error); + if (dbus_error_is_set(&error)) { + printf("cannot acquire org.kernel.udev service, error %s: %s'", + error.name, error.message); + sysbus_disconnect(); + return; + } } @@ -62,31 +72,31 @@ void sysbus_connect(void) */ void sysbus_send_create(struct udevice *dev, const char *path) { - char filename[255]; - DBusMessage* message; - DBusMessageIter iter; + char filename[255]; + DBusMessage* message; + DBusMessageIter iter; - if (sysbus_connection == NULL) - return; + if (sysbus_connection == NULL) + return; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->name, sizeof(filename)); + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, dev->name, sizeof(filename)); - /* object, interface, member */ - message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", - "org.kernel.udev.NodeMonitor", - "NodeCreated"); - - dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, filename); - dbus_message_iter_append_string(&iter, path); + /* object, interface, member */ + message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", + "org.kernel.udev.NodeMonitor", + "NodeCreated"); - if ( !dbus_connection_send(sysbus_connection, message, NULL) ) - dbg("error sending d-bus signal"); + dbus_message_iter_init(message, &iter); + dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, path); - dbus_message_unref(message); - - dbus_connection_flush(sysbus_connection); + if ( !dbus_connection_send(sysbus_connection, message, NULL) ) + dbg("error sending d-bus signal"); + + dbus_message_unref(message); + + dbus_connection_flush(sysbus_connection); } /** Send out a signal that a device node is deleted @@ -96,31 +106,29 @@ void sysbus_send_create(struct udevice *dev, const char *path) */ void sysbus_send_remove(const char* name, const char *path) { - char filename[255]; - DBusMessage* message; - DBusMessageIter iter; + char filename[255]; + DBusMessage* message; + DBusMessageIter iter; - if (sysbus_connection == NULL) - return; + if (sysbus_connection == NULL) + return; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, name, sizeof(filename)); + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, name, sizeof(filename)); - /* object, interface, member */ - message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", - "org.kernel.udev.NodeMonitor", - "NodeDeleted"); - - dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, filename); - dbus_message_iter_append_string(&iter, path); - - if ( !dbus_connection_send(sysbus_connection, message, NULL) ) - dbg("error sending d-bus signal"); - - dbus_message_unref(message); + /* object, interface, member */ + message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", + "org.kernel.udev.NodeMonitor", + "NodeDeleted"); - dbus_connection_flush(sysbus_connection); + dbus_message_iter_init(message, &iter); + dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, path); + + if ( !dbus_connection_send(sysbus_connection, message, NULL) ) + dbg("error sending d-bus signal"); + + dbus_message_unref(message); + + dbus_connection_flush(sysbus_connection); } - - From bbd063b5c2aa055a707b472d4e0b1ed297d00674 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 8 Dec 2003 18:01:56 -0800 Subject: [PATCH 0266/4284] [PATCH] change USE_DBUS to DBUS in Makefile, and disable it by default as it's still to hard to build on all systems. --- Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index c50bd04824..ae9d276721 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = false # Set the following to `true' to make udev emit a D-BUS signal when a # new node is created. -USE_DBUS = true +DBUS = false ROOT = udev @@ -143,13 +143,6 @@ endif CFLAGS += -I$(PWD)/libsysfs -ifeq ($(USE_DBUS), true) - CFLAGS += -DUSE_DBUS - CFLAGS += $(shell pkg-config --cflags dbus-1) - LIB_OBJS += $(shell pkg-config --libs-only-l dbus-1) -endif - - all: $(ROOT) @for target in $(EXTRAS) ; do \ echo $$target ; \ @@ -190,6 +183,13 @@ ifeq ($(strip $(KLIBC)),true) OBJS += klibc_fixups.o endif +ifeq ($(DBUS), true) + CFLAGS += -DUSE_DBUS + CFLAGS += $(shell pkg-config --cflags dbus-1) + LIB_OBJS += $(shell pkg-config --libs-only-l dbus-1) + OBJS += udev_dbus.o +endif + # header files automatically generated GEN_HEADERS = udev_version.h @@ -252,7 +252,7 @@ small_release: $(DISTFILES) clean @echo "Built $(RELEASE_NAME).tar.gz" -ifeq ($(USE_DBUS), true) +ifeq ($(DBUS), true) install-dbus-policy: $(INSTALL) -d $(DESTDIR)$(dbusdir) $(INSTALL_DATA) udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) From 7d27ce1dc005b3972ab7ed77a86f6333c2f8ee9f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 8 Dec 2003 18:08:52 -0800 Subject: [PATCH 0267/4284] [PATCH] document the different Makefile config options that we have. --- README | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README b/README index fffa793987..94a397936e 100644 --- a/README +++ b/README @@ -25,6 +25,27 @@ To use: - Build the project: make + Note: + There are a number of different flags that you can use when building + udev. They are as follows: + prefix - set this to the default root that you want udev to be + installed into. This works just like the 'configure --prefix' + script does. Default value is ''. Only override this if you + really know what you are doing. + KLIBC - if set to 'true', udev is built and linked against the included + version of klibc. Default value is 'false'. + DEBUG - if set to 'true', debugging messages will be sent to the syslog + as udev is run. Default value is 'false'. + DBUS - if set to 'true', DBUS messages will be sent everytime udev + creates or removes a device node. This requires that DBUS + development headers and libraries be present on your system to + build properly. Default value is 'false'. + + So, if you want to build udev using klibc with debugging messages, you + would do: + make KLIBC=true DEBUG=true + + - Install the project: make install From c6c13c31814e9fc7557ca303c331d0cf13664372 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Dec 2003 00:30:43 -0800 Subject: [PATCH 0268/4284] [PATCH] cleanup man & remove symlink comment remove "want symlinks" text from udev-add.c mention SYMLINK in man page man page format cleanup man page example for SYMLINK --- udev-add.c | 9 --------- udev.8 | 59 ++++++++++++++++++++++++++---------------------------- 2 files changed, 28 insertions(+), 40 deletions(-) diff --git a/udev-add.c b/udev-add.c index 8d45b26077..17b69eadab 100644 --- a/udev-add.c +++ b/udev-add.c @@ -54,18 +54,15 @@ static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev) { int retval = -ENODEV; - char *dev; dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); if (dev == NULL) goto exit; - dbg("dev='%s'", dev); if (sscanf(dev, "%u:%u", &udev->major, &udev->minor) != 2) goto exit; - dbg("found major=%d, minor=%d", udev->major, udev->minor); retval = 0; @@ -101,10 +98,6 @@ static int create_path(char *file) return 0; } -/* - * we possibly want to add some symlinks here - * only numeric owner/group id's are supported - */ static int create_node(struct udevice *dev) { char filename[255]; @@ -116,7 +109,6 @@ static int create_node(struct udevice *dev) int i; int tail; - strncpy(filename, udev_root, sizeof(filename)); strncat(filename, dev->name, sizeof(filename)); @@ -239,7 +231,6 @@ static struct sysfs_class_device *get_class_dev(char *device_name) strcpy(dev_path, sysfs_path); strcat(dev_path, device_name); - dbg("looking at '%s'", dev_path); /* open up the sysfs class device for this thing... */ diff --git a/udev.8 b/udev.8 index 37b3b625e7..0c461967d2 100644 --- a/udev.8 +++ b/udev.8 @@ -63,7 +63,7 @@ permissions file. The default value for this is .I 0666 .br .P -A sample \fIudev.conf\fP might look like this: +.RI "A sample " udev.conf " might look like this: .sp .nf # udev_root - where in the filesystem to place the device nodes @@ -85,7 +85,7 @@ default_mode="0666" .P The rules for udev to use when naming devices may specified at .I /etc/udev/udev.rules -or specified by the +or specified by the .I udev_rules value in the .I /etc/udev/udev.conf @@ -94,73 +94,73 @@ file. Every line in the rules file define the mapping between device attributes and the device file name. It starts with a keyword defining the method used to match, followed by one ore more keys to compare and the filename for the -device. If no matching configuration is found, the default kernel device name +device. Optional the name for a symlink targeting the node may specified. +.br +If no matching configuration is found, the default kernel device name is used. .P The line format is: .sp -.I method, key,[key,...] name +.I method, key,[key,...] name [, symlink] .sp where valid methods with corresponding keys are: .TP .B CALLOUT calling external program, that returns a string to match .br -keys: \fBBUS\fP, \fBPROGRAM\fP, \fBID\fP +.RB "keys: " BUS ", " PROGRAM ", " ID .TP .B LABEL device label or serial number, like USB serial number, SCSI UUID or file system label .br -keys: \fBBUS\fP, \fIsysfs_attribute\fP +.RB "keys: " BUS ", " +.I sysfs_attribute .TP .B NUMBER device number on the bus, like PCI bus id .br -keys: \fBBUS\fP, \fBID\fP +.RB "keys: " BUS ", " ID .TP .B TOPOLOGY device position on bus, like physical port of USB device .br -keys: \fBBUS\fP, \fBPLACE\fP +.RB "keys: " BUS ", " PLACE .TP .B REPLACE string replacement of the kernel device name .br -key: \fBKERNEL_NAME\fP +.RB "key: " KERNEL_NAME .P The methods are applied in the following order: -.BR CALLOUT ", " LABEL ", " NUMBER ", " TOPOLOGY ", " REPLACE "." +.BR CALLOUT ", " LABEL ", " NUMBER ", " TOPOLOGY ", " REPLACE "." .P -The -.B NAME -and -.B PROGRAM +.RB "The " NAME " ," SYMLINK " and " PROGRAM fields support simple printf-like string substitution: .TP .B %n -the "kernel number" of the device +The "kernel number" of the device. for example, 'sda3' has a "kernel number" of '3' .TP .B %M -the kernel major number for the device +The kernel major number for the device. .TP .B %m -the kernel minor number for the device +The kernel minor number for the device. .TP .B %b -the bus id for the device +The bus id for the device. .TP .B %c -the CALLOUT program returned string -(this does not work within the PROGRAM field for the obvious reason.) +The CALLOUT program returned string. +(This does not work within the PROGRAM field for the obvious reason.) .TP .B %D Use the devfs style disk name for this device. For partitions, this will result in 'part%n' -If this is not a partition, it will result in 'disk' +If this is not a partition, it will result in 'disk'. .P -A sample \fIudev.rules\fP might look like this: +.RI "A sample " udev.rules " might look like this:" .sp .nf # if /sbin/scsi_id returns "OEM 0815" device will be called disk1 @@ -178,15 +178,15 @@ TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" # ttyUSB1 should always be called pda REPLACE, KERNEL="ttyUSB1", NAME="pda" -# USB webcams to be called webcam0, webcam1, ... -LABEL, BUS="usb", model="WebCam Version 3", NAME="webcam%n" +# USB webcams with symlinks to be called webcam0, webcam1, ... +LABEL, BUS="usb", model="WebCam Version 3", NAME="video%n", SYMLINK="webcam%n" .fi .P Permissions and ownership for the created device files may specified at .I /etc/udev/udev.permissions -or specified by the +or specified by the .I udev_permission -value in the +value in the .I /etc/udev/udev.conf file. .br @@ -197,10 +197,9 @@ pattern to apply the values to a whole class of devices. If .B udev was built using klibc or is used before the user database is accessible (e.g. -.B initrd -), only numeric owner and group values may be used. +.BR initrd "(4)), only numeric owner and group values may be used." .sp -A sample \fIudev.permissions\fP might look like this: +.RI "A sample " udev.permissions " might look like this:" .sp .nf #name:user:group:mode @@ -227,8 +226,6 @@ the range of all digits, the pattern [0-9] would be used. If the first character following the '[' is a '!' then any character not enclosed is matched. .SH "FILES" .nf -.ft B -.ft /sbin/udev udev program /etc/udev/* udev config files /etc/hotplug.d/default/udev.hotplug hotplug symlink to udev program From 10a479f5e6df7010a47f1edfab8173de85a34d0d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Dec 2003 00:37:02 -0800 Subject: [PATCH 0269/4284] [PATCH] update the FAQ due to the latest devfs mess on lkml and also due to symlinks now working. --- FAQ | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/FAQ b/FAQ index c082a5bec4..d9aebde0da 100644 --- a/FAQ +++ b/FAQ @@ -31,12 +31,25 @@ Q: But udev will not automatically load a driver if a /dev node is opened A: If you really require this functionality, then use devfs. It is still present in the kernel. -Q: But I really like the devfs naming scheme, will udev do that? +Q: But wait, I really want udev to automatically load drivers when they + are not present but the device node is opened. It's the only reason I + like using devfs. Please make udev do this. +A: No. udev is for managing /dev, not loading kernel drivers. + +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: I really like the devfs naming scheme, will udev do that? A: Yes, udev can create /dev nodes using the devfs naming policy. A configuration file needs to be created to map the kernel default names - to the devfs names. Such a configuration file would be gladly added to - the udev package if it is provided by anyone who can create such a - mapping. + to the devfs names. See the initial udev.conf.devfs file in the udev + release. It is the start of such a configuration file. If there are + any things missing, please let the udev authors know. Q: What kinds of devices does udev create nodes for? A: All devices that are shown in sysfs will work with udev. If more @@ -51,7 +64,7 @@ A: udev is entirely in userspace. If the kernel supports a greater number of anonymous devices, udev will support it. Q: Will udev support symlinks? -A: Yes, patches are gladly accepted to add this functionality. +A: Yes, It now does. Multiple symlinks per device node too. Q: How will udev support changes to device permissions? A: On shutdown, udev will save the state of existing device permissions to From 4763256c65859b94ac7a309cbb8f772d5426a08d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Dec 2003 00:47:00 -0800 Subject: [PATCH 0270/4284] [PATCH] allow multiple symlinks Here is a patch to allow the creation of multiple symlinks. The names must be separated by a space character. REPLACE, KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n" results in: Dec 9 05:28:51 pim udev[12019]: create_node: mknod(udev-root/visor, 020666, 188, 0) Dec 9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/first-0' to node 'visor' requested Dec 9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/first-0) Dec 9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/second-0' to node 'visor' requested Dec 9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/second-0) Dec 9 05:28:51 pim udev[12019]: create_node: symlink 'udev-root/third-0' to node 'visor' requested Dec 9 05:28:51 pim udev[12019]: create_node: symlink(./visor, udev-root/third-0) --- test/udev-test.pl | 9 +++++++ udev-add.c | 66 ++++++++++++++++++++++++++--------------------- udev-remove.c | 32 +++++++++++++++-------- 3 files changed, 67 insertions(+), 40 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 190b7ce4d6..39d8450c34 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -215,6 +215,15 @@ EOF expected => "1/2/c/d/symlink" , conf => < "multiple symlinks", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "second-0" , + conf => <symlink) { - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->symlink, sizeof(filename)); - dbg("symlink '%s' to node '%s' requested", filename, dev->name); - if (strrchr(dev->symlink, '/')) - create_path(filename); + symlinks = dev->symlink; + while (1) { + linkname = strsep(&symlinks, " "); + if (linkname == NULL) + break; - /* optimize relative link */ - linktarget[0] = '\0'; - i = 0; - tail = 0; - while ((dev->name[i] == dev->symlink[i]) && dev->name[i]) { - if (dev->name[i] == '/') - tail = i+1; - i++; + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, linkname, sizeof(filename)); + dbg("symlink '%s' to node '%s' requested", filename, dev->name); + if (strrchr(linkname, '/')) + create_path(filename); + + /* optimize relative link */ + linktarget[0] = '\0'; + i = 0; + tail = 0; + while ((dev->name[i] == linkname[i]) && dev->name[i]) { + if (dev->name[i] == '/') + tail = i+1; + i++; + } + while (linkname[i]) { + if (linkname[i] == '/') + strcat(linktarget, "../"); + i++; + } + + if (*linktarget == '\0') + strcpy(linktarget, "./"); + strcat(linktarget, &dev->name[tail]); + + dbg("symlink(%s, %s)", linktarget, filename); + retval = symlink(linktarget, filename); + if (retval) + dbg("symlink(%s, %s) failed with error '%s'", + linktarget, filename, strerror(errno)); } - while (dev->symlink[i]) { - if (dev->symlink[i] == '/') - strcat(linktarget, "../"); - i++; - } - - if (*linktarget == '\0') - strcpy(linktarget, "./"); - strcat(linktarget, &dev->name[tail]); - - dbg("symlink(%s, %s)", linktarget, filename); - retval = symlink(linktarget, filename); - if (retval) - dbg("symlink(%s, %s) failed with error '%s'", - linktarget, filename, strerror(errno)); } return retval; diff --git a/udev-remove.c b/udev-remove.c index 02c84371a4..0886c23343 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -66,6 +66,8 @@ static int delete_path(char *path) static int delete_node(struct udevice *dev) { char filename[255]; + char *symlinks; + char *linkname; int retval; strncpy(filename, udev_root, sizeof(filename)); @@ -84,17 +86,25 @@ static int delete_node(struct udevice *dev) delete_path(filename); if (*dev->symlink) { - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->symlink, sizeof(filename)); - dbg("unlinking symlink '%s'", filename); - retval = unlink(filename); - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - return retval; - } - if (strchr(dev->symlink, '/')) { - delete_path(filename); + symlinks = dev->symlink; + while (1) { + linkname = strsep(&symlinks, " "); + if (linkname == NULL) + break; + + strncpy(filename, udev_root, sizeof(filename)); + strncat(filename, linkname, sizeof(filename)); + + dbg("unlinking symlink '%s'", filename); + retval = unlink(filename); + if (retval) { + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + return retval; + } + if (strchr(dev->symlink, '/')) { + delete_path(filename); + } } } From 61f76f5c9c12ec612458f515516b71a23b9410dd Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Wed, 10 Dec 2003 00:50:25 -0800 Subject: [PATCH 0271/4284] [PATCH] more extras/multipath updates * update the Makefiles to autodetect libgcc.a & gcc includes "ulibc-style". Factorisation of udevdirs & others niceties * drop a hint about absent /dev/sd? on failed open() for poor Debian users who don't imagine their favorite distro with only 16 preconfigured SCSI device nodes :) --- extras/multipath/Makefile | 14 ++++++++++---- extras/multipath/libdevmapper/Makefile | 9 ++++++++- extras/multipath/main.c | 15 +++++++++++++-- extras/multipath/main.h | 5 +++++ 4 files changed, 36 insertions(+), 7 deletions(-) diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index bccf1264f0..89e6f35185 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -6,16 +6,22 @@ EXEC = multipath prefix = /usr/local exec_prefix = ${prefix} -bindir = ${exec_prefix}/bin +bindir = ${exec_prefix}/bin +udevdir = ../.. +klibcdir = $(udevdir)/klibc +sysfsdir = $(udevdir)/libsysfs CC = gcc -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc -I../../klibc/klibc/include -I../../klibc/klibc/include/bits32 -I/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/include -I../../klibc/linux/include -I../../libsysfs -I. -LDFLAGS = -lsysfs -ldevmapper -ldlist +GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ + -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ + -I$(GCCINCDIR) -I$(klibcdir)/linux/include -I$(sysfsdir) -I. OBJS = main.o CRT0 = ../../klibc/klibc/crt0.o LIB = ../../klibc/klibc/libc.a -LIBGCC = /usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/libgcc.a +LIBGCC := $(shell $(CC) -print-libgcc-file-name ) + DMOBJS = libdevmapper/libdm-common.o libdevmapper/ioctl/libdevmapper.o SYSFSOBJS = ../../libsysfs/dlist.o ../../libsysfs/sysfs_bus.o \ ../../libsysfs/sysfs_class.o ../../libsysfs/sysfs_device.o \ diff --git a/extras/multipath/libdevmapper/Makefile b/extras/multipath/libdevmapper/Makefile index 72b39cedf5..b160075416 100644 --- a/extras/multipath/libdevmapper/Makefile +++ b/extras/multipath/libdevmapper/Makefile @@ -3,7 +3,14 @@ # Copyright (C) 2003 Christophe Varoqui, CC = gcc -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc -I../../../klibc/klibc/include -I../../../klibc/klibc/include/bits32 -I/usr/lib/gcc-lib/i586-mandrake-linux-gnu/3.3.1/include -I../../../klibc/linux/include -I. -Iioctl +udevdir = ../../.. +klibcdir = $(udevdir)/klibc + +CC = gcc +GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ + -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ + -I$(GCCINCDIR) -I$(klibcdir)/linux/include -I. -Iioctl OBJS = ioctl/libdevmapper.o libdm-common.o diff --git a/extras/multipath/main.c b/extras/multipath/main.c index bc65899ce1..e62d763252 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -253,6 +253,9 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sprintf(all_paths[k].sg_dev, "/dev/%s", buff); strcpy(all_paths[k].dev, all_paths[k].sg_dev); if ((sg_fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) { + if (conf->verbose) + fprintf(stderr, "can't open %s. mknod ?", + all_paths[k].sg_dev); continue; } get_lun_strings(sg_fd, &all_paths[k]); @@ -285,8 +288,12 @@ get_all_paths_nosysfs(struct env * conf, struct path * all_paths, sprintf(buff, "%d", k); strncat(file_name, buff, FILE_NAME_SIZE); strcpy(all_paths[k].sg_dev, file_name); - if ((sg_fd = open(file_name, O_RDONLY)) < 0) + if ((sg_fd = open(file_name, O_RDONLY)) < 0) { + if (conf->verbose) + fprintf(stderr, "can't open %s. mknod ?", + file_name); continue; + } get_lun_strings(sg_fd, &all_paths[k]); get_unique_id(sg_fd, &all_paths[k]); all_paths[k].state = do_tur(sg_fd); @@ -340,8 +347,12 @@ get_all_scsi_ids(struct env * conf, struct scsi_dev * all_scsi_ids) } else strcat(fname, "xxxx"); - if ((fd = open(fname, O_RDONLY)) < 0) + if ((fd = open(fname, O_RDONLY)) < 0) { + if (conf->verbose) + fprintf(stderr, "can't open %s. mknod ?", + fname); continue; + } res = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &my_scsi_id); if (res < 0) { diff --git a/extras/multipath/main.h b/extras/multipath/main.h index 692e5e4595..a1de1d8d2d 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -47,6 +47,11 @@ #define MX_ALLOC_LEN 255 #define BLKGETSIZE _IO(0x12,96) #define DM_TARGET "striped" +/* +#define DM_TARGET "multipath" +#define DM_POLL_INTERVAL 10 +#define DM_PATH_SELECTOR "latency" +*/ #define PINDEX(x,y) mp[(x)].pindex[(y)] From 197a978ea3e5d68d2ca8059cede2b60f62c497b7 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Wed, 10 Dec 2003 00:52:04 -0800 Subject: [PATCH 0272/4284] [PATCH] and more extras/multipath updates * configure the multipath target with round-robin path selector and conservative default for a start : yes it makes this release the first really useful one. * temporarily disable map creation for single path device due to current restrictive defaults in the kernel target. Sistina should work it out. * correct the strncmp logic in blacklist function. Tested on StorageWorks with 2.6.0-test10-udm1 : xa-s03:~# ./multipath -v 60001fe1000bdad0000903507109004b (1 0 1 1) /dev/sda op:1 /dev/sda [HSG80 ] 60001fe1000bdad000090371312100bf (1 0 1 2) /dev/sdb op:1 /dev/sdb [HSG80 ] 60001fe1000bdad000090371312100c2 (1 0 1 3) /dev/sdc op:1 /dev/sdc [HSG80 ] 60001fe1000bdad00009037131210067 (1 0 2 1) /dev/sdd op:1 /dev/sdd [HSG80 ] 60001fe1000bdad000090371312100b3 (1 0 2 2) /dev/sde op:1 /dev/sde [HSG80 ] 60001fe1000bdad00009035071090024 (1 0 2 3) /dev/sdf op:1 /dev/sdf [HSG80 ] 600508b4000156d700012000000b0000 (1 0 3 1) /dev/sdg op:1 /dev/sdg [HSV110 (C)COMPAQ] 600508b4000156c30001200000210000 (1 0 3 2) /dev/sdh op:1 /dev/sdh [HSV110 (C)COMPAQ] 600508b4000156d700012000000b0000 (1 0 6 1) /dev/sdi op:1 /dev/sdi [HSV110 (C)COMPAQ] 600508b4000156c30001200000210000 (1 0 6 2) /dev/sdj op:1 /dev/sdj [HSV110 (C)COMPAQ] 60001fe1000bdad0000903507109004b \_(1 0 1 1) /dev/sda op:1 /dev/sda [HSG80 ] 60001fe1000bdad000090371312100bf \_(1 0 1 2) /dev/sdb op:1 /dev/sdb [HSG80 ] 60001fe1000bdad000090371312100c2 \_(1 0 1 3) /dev/sdc op:1 /dev/sdc [HSG80 ] 60001fe1000bdad00009037131210067 \_(1 0 2 1) /dev/sdd op:1 /dev/sdd [HSG80 ] 60001fe1000bdad000090371312100b3 \_(1 0 2 2) /dev/sde op:1 /dev/sde [HSG80 ] 60001fe1000bdad00009035071090024 \_(1 0 2 3) /dev/sdf op:1 /dev/sdf [HSG80 ] 600508b4000156d700012000000b0000 \_(1 0 3 1) /dev/sdg op:1 /dev/sdg [HSV110 (C)COMPAQ] \_(1 0 6 1) /dev/sdi op:1 /dev/sdi [HSV110 (C)COMPAQ] 600508b4000156c30001200000210000 \_(1 0 3 2) /dev/sdh op:1 /dev/sdh [HSV110 (C)COMPAQ] \_(1 0 6 2) /dev/sdj op:1 /dev/sdj [HSV110 (C)COMPAQ] N|600508b4000156d700012000000b0000 : 0 4194304 multipath 2 2 10 round-robin 2 /dev/sdg 10 2 1 2 /dev/sdi 10 2 1 2 N|600508b4000156c30001200000210000 : 0 20971520 multipath 2 2 10 round-robin 2 /dev/sdh 10 2 1 2 /dev/sdj 10 2 1 2 xa-s03:~# dmsetup ls 600508b4000156c30001200000210000 (254, 1) 600508b4000156d700012000000b0000 (254, 0) xa-s03:~# ll /dev/mapper/ total 0 brw------- 1 root root 254, 1 Dec 9 22:57 600508b4000156c30001200000210000 brw------- 1 root root 254, 0 Dec 9 22:57 600508b4000156d700012000000b0000 crw------- 1 root root 10, 63 Jul 25 22:48 control xa-s03:~# dd if=/dev/mapper/600508b4000156c30001200000210000 of=/dev/null bs=1M count=500 500+0 records in 500+0 records out 524288000 bytes transferred in 5.662530 seconds (92589003 bytes/sec) gee, that pretty fast :) --- extras/multipath/main.c | 28 ++++++++++++++++++++++++---- extras/multipath/main.h | 5 ----- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/extras/multipath/main.c b/extras/multipath/main.c index e62d763252..6b1c37cd95 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -214,7 +214,7 @@ blacklist (char * dev) { }; for (i = 0; blist[i].lengh; i++) { - if (strncmp(dev, blist[i].headstr, blist[i].lengh)) + if (strncmp(dev, blist[i].headstr, blist[i].lengh) == 0) return 1; } return 0; @@ -562,6 +562,17 @@ add_map(struct env * conf, struct path * all_paths, int i, np; long size = -1; + /* defaults for multipath target */ + int dm_nr_path_args = 2; + int dm_path_test_int = 10; + char * dm_ps_name = "round-robin"; + int dm_ps_nr_args = 2; + int dm_path_failback_int = 10; + int dm_path_nr_fail = 2; + int dm_ps_prio = 1; + int dm_ps_min_io = 2; + + if (!(dmt = dm_task_create(op))) return 0; @@ -577,7 +588,14 @@ add_map(struct env * conf, struct path * all_paths, } if (np == 0) goto addout; - params_p += sprintf(params_p, "%i 32", np); + /* temporarily disable creation of single path maps */ + /* Sistina should modify the target limits */ + if (np < 2) + goto addout; + + params_p += sprintf(params_p, "%i %i %i %s %i", + np, dm_nr_path_args, dm_path_test_int, + dm_ps_name, dm_ps_nr_args); for (i=0; i<=mp[index].npaths; i++) { if (( 0 == all_paths[PINDEX(index,i)].state) || @@ -585,8 +603,10 @@ add_map(struct env * conf, struct path * all_paths, continue; if (size < 0) size = get_disk_size(conf, all_paths[PINDEX(index,0)].dev); - params_p += sprintf(params_p, " %s %i", - all_paths[PINDEX(index,i)].dev, 0); + params_p += sprintf(params_p, " %s %i %i %i %i", + all_paths[PINDEX(index,i)].dev, + dm_path_failback_int, dm_path_nr_fail, + dm_ps_prio, dm_ps_min_io); } if (size < 0) diff --git a/extras/multipath/main.h b/extras/multipath/main.h index a1de1d8d2d..d6dfb14296 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -46,12 +46,7 @@ #define TUR_CMD_LEN 6 #define MX_ALLOC_LEN 255 #define BLKGETSIZE _IO(0x12,96) -#define DM_TARGET "striped" -/* #define DM_TARGET "multipath" -#define DM_POLL_INTERVAL 10 -#define DM_PATH_SELECTOR "latency" -*/ #define PINDEX(x,y) mp[(x)].pindex[(y)] From 62adf3f7392ca923c3014c921b50f4f16029be42 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Dec 2003 01:02:03 -0800 Subject: [PATCH 0273/4284] [PATCH] Makefile tweaks for the DBUS build. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ae9d276721..51087bc8c6 100644 --- a/Makefile +++ b/Makefile @@ -186,7 +186,7 @@ endif ifeq ($(DBUS), true) CFLAGS += -DUSE_DBUS CFLAGS += $(shell pkg-config --cflags dbus-1) - LIB_OBJS += $(shell pkg-config --libs-only-l dbus-1) + LDFLAGS += $(shell pkg-config --libs dbus-1) OBJS += udev_dbus.o endif From 197eda9ab08a9d44b831bed19c214a5861e188a5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Dec 2003 01:05:30 -0800 Subject: [PATCH 0274/4284] [PATCH] set default mode to 0600 to be safer. --- udev.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.conf b/udev.conf index aadaea8a24..c3f31a6aa7 100644 --- a/udev.conf +++ b/udev.conf @@ -19,5 +19,5 @@ udev_permissions="/etc/udev/udev.permissions" # default_mode - set the default mode for all nodes that have no # explicit match in the permissions file -default_mode="0666" +default_mode="0600" From ef3c3df3a34df4ca7db7a490599ee2f8a3871a91 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Dec 2003 01:10:37 -0800 Subject: [PATCH 0275/4284] [PATCH] added a devfs udev config file from Marco d'Itri --- udev.rules.devfs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 udev.rules.devfs diff --git a/udev.rules.devfs b/udev.rules.devfs new file mode 100644 index 0000000000..c62559ba47 --- /dev/null +++ b/udev.rules.devfs @@ -0,0 +1,34 @@ +# These rules are to try to emulate a devfs naming scheme in udev +# if there are any missing rules, please let the udev developers +# know. +# +# There are a number of modifiers that are allowed to be used in the +# a number 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' +# %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 return value for the CALLOUT program (note, this doesn't work within +# the PROGRAM field for the obvious reason.) +# %D - use the devfs style disk name for this device. +# For partitions, this will result in 'part%n' +# If this is not a partition, it will result in 'disk' +# + +NUMBER, BUS="ide", id="0.0", NAME="ide/host0/bus0/target0/lun0/%D" +NUMBER, BUS="ide", id="0.1", NAME="ide/host0/bus0/target1/lun0/%D" +NUMBER, BUS="ide", id="1.0", NAME="ide/host0/bus1/target0/lun0/%D" +NUMBER, BUS="ide", id="1.1", NAME="ide/host0/bus1/target1/lun0/%D" + +REPLACE, KERNEL="md[0-9]*", NAME="md/%n" + +REPLACE, KERNEL="tty[0-9]*", NAME="vc/%n" +REPLACE, KERNEL="ttyS[0-9]*", NAME="tts/%n" +REPLACE, KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" + +REPLACE, KERNEL="video[0-9]*", NAME="v4l/video%n" +REPLACE, KERNEL="radio[0-9]*", NAME="v4l/radio%n" +REPLACE, KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +REPLACE, KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" + From babad3ff2ce7769b65474b29d97517e816f89bbd Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Dec 2003 01:14:24 -0800 Subject: [PATCH 0276/4284] [PATCH] add vc support to udev.rules.devfs --- udev.rules.devfs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/udev.rules.devfs b/udev.rules.devfs index c62559ba47..a92896078c 100644 --- a/udev.rules.devfs +++ b/udev.rules.devfs @@ -16,19 +16,28 @@ # If this is not a partition, it will result in 'disk' # +# ide block devices NUMBER, BUS="ide", id="0.0", NAME="ide/host0/bus0/target0/lun0/%D" NUMBER, BUS="ide", id="0.1", NAME="ide/host0/bus0/target1/lun0/%D" NUMBER, BUS="ide", id="1.0", NAME="ide/host0/bus1/target0/lun0/%D" NUMBER, BUS="ide", id="1.1", NAME="ide/host0/bus1/target1/lun0/%D" +# md block devices REPLACE, KERNEL="md[0-9]*", NAME="md/%n" +# tty devices REPLACE, KERNEL="tty[0-9]*", NAME="vc/%n" REPLACE, KERNEL="ttyS[0-9]*", NAME="tts/%n" REPLACE, KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" +# vc devices +REPLACE, KERNEL="vcs", NAME="vcc/0" +REPLACE, KERNEL="vcs[0-9]*", NAME="vcc/%n" +REPLACE, KERNEL="vcsa", NAME="vcc/a0" +REPLACE, KERNEL="vcsa[0-9]*", NAME="vcc/a%n" + +# v4l devices REPLACE, KERNEL="video[0-9]*", NAME="v4l/video%n" REPLACE, KERNEL="radio[0-9]*", NAME="v4l/radio%n" REPLACE, KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" REPLACE, KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" - From 26004fcc665d14220c5b15a15ee4b2dd5d4af314 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Dec 2003 15:40:08 -0800 Subject: [PATCH 0277/4284] [PATCH] man-page mention multiple symlinks As usual, when the stuff gets in the tree - here is a small man page update and a TODO line removal. mention multiple symlinks update example with silly symlink rule :) shorten example line to have less than 80 chars remove "want symlink support" from TODO --- TODO | 1 - udev.8 | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/TODO b/TODO index e227834f36..47275873c8 100644 --- a/TODO +++ b/TODO @@ -8,7 +8,6 @@ greg@kroah.com - fix kernel name logic to handle devices like sdaj and such. - more documentation (can never have too much.) -- add symlink generation and removal support - better partition support (it's a hack right now, maybe new libsysfs changes can help out a lot here.) - allow database to be queried by other programs diff --git a/udev.8 b/udev.8 index 0c461967d2..7b4e17b5c4 100644 --- a/udev.8 +++ b/udev.8 @@ -94,7 +94,7 @@ file. Every line in the rules file define the mapping between device attributes and the device file name. It starts with a keyword defining the method used to match, followed by one ore more keys to compare and the filename for the -device. Optional the name for a symlink targeting the node may specified. +device. One ore more optional symlinks targeting the node may be specified. .br If no matching configuration is found, the default kernel device name is used. @@ -175,11 +175,11 @@ NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" # USB mouse at third port of the second hub to be called mouse1 TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" -# ttyUSB1 should always be called pda -REPLACE, KERNEL="ttyUSB1", NAME="pda" +# ttyUSB1 should always be called pda with two additional symlinks +REPLACE, KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" -# USB webcams with symlinks to be called webcam0, webcam1, ... -LABEL, BUS="usb", model="WebCam Version 3", NAME="video%n", SYMLINK="webcam%n" +# multiple USB webcams with symlinks to be called webcam0, webcam1, ... +LABEL, BUS="usb", model="WebCam V3", NAME="video%n", SYMLINK="webcam%n" .fi .P Permissions and ownership for the created device files may specified at From 525d07e78e281f5034ee29d2cd5cc144fe320431 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Dec 2003 22:12:30 -0800 Subject: [PATCH 0278/4284] [PATCH] change devfs disk name rule from 'disk' to 'disc' --- namedev.c | 2 +- test/udev-test.pl | 2 +- udev.8 | 2 +- udev.rules | 2 +- udev.rules.devfs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/namedev.c b/namedev.c index fbdb125e4c..75e4d22370 100644 --- a/namedev.c +++ b/namedev.c @@ -223,7 +223,7 @@ static void apply_format(struct udevice *udev, unsigned char *string) break; case 'D': if (strlen(udev->kernel_number) == 0) { - strcat(pos, "disk"); + strcat(pos, "disc"); break; } strcat(pos, "part"); diff --git a/test/udev-test.pl b/test/udev-test.pl index 39d8450c34..3dfbaa2530 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -156,7 +156,7 @@ EOF desc => "devfs disk naming substitution", subsys => "block", devpath => "block/sda", - expected => "lun0/disk" , + expected => "lun0/disc" , conf => < Date: Thu, 11 Dec 2003 08:00:40 -0800 Subject: [PATCH 0279/4284] [PATCH] use udevdir in udev.conf udevdir is a define, but udev.conf has a hardcoded path. Maybe this config file should be generated on the fly, like shown below. --- Makefile | 9 +++++---- udev.conf => udev.conf.in | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) rename udev.conf => udev.conf.in (92%) diff --git a/Makefile b/Makefile index 51087bc8c6..cdee7ac812 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} EXTRAS= # place to put our device nodes -udevdir = ${prefix}/udev/ +udevdir = ${prefix}/udev # Comment out this line to build with something other # than the local version of klibc @@ -196,8 +196,8 @@ GEN_HEADERS = udev_version.h # Rules on how to create the generated header files udev_version.h: @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ - @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ - @echo \#define UDEV_DB \"$(udevdir)\.udev.tdb\" >> $@ + @echo \#define UDEV_ROOT \"$(udevdir)/\" >> $@ + @echo \#define UDEV_DB \"$(udevdir)/\.udev.tdb\" >> $@ @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)\udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ @@ -212,7 +212,7 @@ $(ROOT): $(OBJS) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) + -rm -f core $(ROOT) $(GEN_HEADERS) udev.conf $(MAKE) -C klibc clean @for target in $(EXTRAS) ; do \ echo $$target ; \ @@ -271,6 +271,7 @@ install: install-dbus-policy all $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 + sed -e "s-@udevdir@-$(udevdir)-" < udev.conf.in > udev.conf $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) diff --git a/udev.conf b/udev.conf.in similarity index 92% rename from udev.conf rename to udev.conf.in index c3f31a6aa7..d06b0b0698 100644 --- a/udev.conf +++ b/udev.conf.in @@ -6,10 +6,10 @@ # udev_root - where in the filesystem to place the device nodes -udev_root="/udev/" +udev_root="@udevdir@/" # udev_db - The name and location of the udev database. -udev_db="/udev/.udev.tdb" +udev_db="@udevdir@/.udev.tdb" # udev_rules - The name and location of the udev rules file udev_rules="/etc/udev/udev.rules" From 71896b56ee03a8f31c89263bbf5f4cb7201666be Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 11 Dec 2003 08:12:29 -0800 Subject: [PATCH 0280/4284] [PATCH] tweak the config file generation portion of the Makefile a bit. --- Makefile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index cdee7ac812..9415e1ec97 100644 --- a/Makefile +++ b/Makefile @@ -203,6 +203,14 @@ udev_version.h: @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ +# config files automatically generated +GEN_CONFIGS = udev.conf + +# Rules on how to create the generated config files +udev.conf: + sed -e "s-@udevdir@-$(udevdir)-" < udev.conf.in > $@ + + $(OBJS): $(GEN_HEADERS) $(ROOT): $(OBJS) @@ -212,7 +220,7 @@ $(ROOT): $(OBJS) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) udev.conf + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(MAKE) -C klibc clean @for target in $(EXTRAS) ; do \ echo $$target ; \ @@ -265,13 +273,12 @@ uninstall-dbus-policy: - endif -install: install-dbus-policy all +install: install-dbus-policy all $(GEN_CONFIGS) $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(configdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 - sed -e "s-@udevdir@-$(udevdir)-" < udev.conf.in > udev.conf $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) From 5d4754f19521568b775ba7a31465d3af192ce382 Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Mon, 15 Dec 2003 21:53:28 -0800 Subject: [PATCH 0281/4284] [PATCH] pre-libsysfs-0.4.0 patch I am sending you a pre-release patch. It's everything that's in our current CVS tree. It adds the functionality you've been looking for. Please play with this before checking it into your tree, I'd like to know if it's ok with you or if you find problems. I have tested this out with test.all and the perl regression test. Let me know what you think. Still need to do more testing for our work and add some more functions related to the changes. I've gone into namedev.c and udev-add.c to make the necessary changes in line with the library. I have not gone and edited any of the "extras". Changes: 1) Libsysfs object structures work more as handles now, their included directories or devices are labeled private. If you need attributes from a sysfs_class_device, call the available function and don't access the directory directly. Same holds true for a sysfs_class_device sysfs_device. Do not access the link directly but call the function sysfs_get_classdev_device() instead. We only populate entries upon request, makes things faster and uses less memory. 2) Added sysfs_get_classdev_parent() as requested. 3) Changed getpagesize to sysconf. 4) Added sysfs_refresh_attributes function for refreshing views of attribute lists. We still need to add refresh for links and subdirs. All udev needs to do is keep calling sysfs_get_classdev_attr() and that will internally call the refresh routine. --- libsysfs/libsysfs.h | 49 +++-- libsysfs/sysfs_bus.c | 338 +++++++++++++------------------- libsysfs/sysfs_class.c | 424 +++++++++++++++++++++++++++------------- libsysfs/sysfs_device.c | 309 +++++++++++++++-------------- libsysfs/sysfs_dir.c | 403 ++++++++++++++++++++++++++++++-------- libsysfs/sysfs_driver.c | 287 +++++++++++++++++---------- libsysfs/sysfs_utils.c | 73 ++++++- namedev.c | 25 +-- udev-add.c | 10 +- 9 files changed, 1197 insertions(+), 721 deletions(-) diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index 6d8e58de21..aca25772b5 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -31,15 +31,10 @@ */ #define SYSFS_FSTYPE_NAME "sysfs" #define SYSFS_PROC_MNTS "/proc/mounts" -#define SYSFS_BUS_DIR "/bus" #define SYSFS_BUS_NAME "bus" -#define SYSFS_CLASS_DIR "/class" #define SYSFS_CLASS_NAME "class" -#define SYSFS_BLOCK_DIR "/block" #define SYSFS_BLOCK_NAME "block" -#define SYSFS_DEVICES_DIR "/devices" #define SYSFS_DEVICES_NAME "devices" -#define SYSFS_DRIVERS_DIR "/drivers" #define SYSFS_DRIVERS_NAME "drivers" #define SYSFS_NAME_ATTRIBUTE "name" #define SYSFS_UNKNOWN "unknown" @@ -75,17 +70,15 @@ struct sysfs_directory { }; struct sysfs_driver { - struct dlist *devices; unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; /* for internal use only */ + struct dlist *devices; struct sysfs_directory *directory; }; struct sysfs_device { - struct sysfs_device *parent; - struct dlist *children; unsigned char name[SYSFS_NAME_LEN]; unsigned char bus_id[SYSFS_NAME_LEN]; unsigned char bus[SYSFS_NAME_LEN]; @@ -93,45 +86,48 @@ struct sysfs_device { unsigned char path[SYSFS_PATH_MAX]; /* for internal use only */ + struct sysfs_device *parent; + struct dlist *children; struct sysfs_directory *directory; }; struct sysfs_root_device { - struct dlist *devices; unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; /* for internal use only */ + struct dlist *devices; struct sysfs_directory *directory; }; struct sysfs_bus { - struct dlist *drivers; - struct dlist *devices; unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; /* internal use only */ + struct dlist *drivers; + struct dlist *devices; struct sysfs_directory *directory; }; struct sysfs_class_device { - struct sysfs_device *sysdevice; /* NULL if virtual */ - struct sysfs_driver *driver; /* NULL if not implemented */ unsigned char name[SYSFS_NAME_LEN]; unsigned char classname[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; /* for internal use only */ + struct sysfs_class_device *parent; + struct sysfs_device *sysdevice; /* NULL if virtual */ + struct sysfs_driver *driver; /* NULL if not implemented */ struct sysfs_directory *directory; }; struct sysfs_class { - struct dlist *devices; unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; /* for internal use only */ + struct dlist *devices; struct sysfs_directory *directory; }; @@ -146,6 +142,9 @@ extern int sysfs_trailing_slash(unsigned char *path); extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); extern int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, size_t len); +extern int sysfs_path_is_dir(const unsigned char *path); +extern int sysfs_path_is_link(const unsigned char *path); +extern int sysfs_path_is_file(const unsigned char *path); extern int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len); extern struct dlist *sysfs_open_subsystem_list(unsigned char *name); @@ -162,8 +161,12 @@ extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, const unsigned char *new_value, size_t len); extern unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, const unsigned char * name); +extern int sysfs_refresh_attributes(struct dlist *attrlist); extern void sysfs_close_directory(struct sysfs_directory *sysdir); extern struct sysfs_directory *sysfs_open_directory(const unsigned char *path); +extern int sysfs_read_dir_attributes(struct sysfs_directory *sysdir); +extern int sysfs_read_dir_links(struct sysfs_directory *sysdir); +extern int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir); extern int sysfs_read_directory(struct sysfs_directory *sysdir); extern int sysfs_read_all_subdirs(struct sysfs_directory *sysdir); extern struct sysfs_directory *sysfs_get_subdirectory @@ -183,10 +186,10 @@ extern struct sysfs_driver *sysfs_open_driver(const unsigned char *path); extern struct sysfs_attribute *sysfs_get_driver_attr (struct sysfs_driver *drv, const unsigned char *name); extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); +extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver); -extern void sysfs_close_driver_by_name(struct sysfs_driver *driver); -extern struct sysfs_driver *sysfs_open_driver_by_name - (const unsigned char *drv_name, const unsigned char *bus, size_t bsize); +extern struct sysfs_device *sysfs_get_driver_device + (struct sysfs_driver *driver, const unsigned char *name); extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, const unsigned char *drv, const unsigned char *attrib); @@ -194,13 +197,14 @@ extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, extern void sysfs_close_root_device(struct sysfs_root_device *root); extern struct sysfs_root_device *sysfs_open_root_device (const unsigned char *name); +extern struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root); extern void sysfs_close_device(struct sysfs_device *dev); extern struct sysfs_device *sysfs_open_device(const unsigned char *path); extern struct sysfs_attribute *sysfs_get_device_attr (struct sysfs_device *dev, const unsigned char *name); extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); extern struct sysfs_device *sysfs_open_device_by_id - (const unsigned char *bus_id, const unsigned char *bus, size_t bsize); + (const unsigned char *bus_id, const unsigned char *bus); extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, const unsigned char *bus_id, const unsigned char *attrib); @@ -211,6 +215,8 @@ extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, unsigned char *id); extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, unsigned char *drvname); +extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); +extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus); extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, unsigned char *attrname); @@ -223,8 +229,15 @@ extern int sysfs_find_driver_bus(const unsigned char *driver, extern void sysfs_close_class_device(struct sysfs_class_device *dev); extern struct sysfs_class_device *sysfs_open_class_device (const unsigned char *path); +extern struct sysfs_device *sysfs_get_classdev_device + (struct sysfs_class_device *clsdev); +extern struct sysfs_driver *sysfs_get_classdev_driver + (struct sysfs_class_device *clsdev); +extern struct sysfs_class_device *sysfs_get_classdev_parent + (struct sysfs_class_device *clsdev); extern void sysfs_close_class(struct sysfs_class *cls); extern struct sysfs_class *sysfs_open_class(const unsigned char *name); +extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); extern struct sysfs_class_device *sysfs_get_class_device (struct sysfs_class *class, unsigned char *name); extern struct sysfs_class_device *sysfs_open_class_device_by_name diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 639acef4ee..3e6c22bbb1 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -93,12 +93,100 @@ static struct sysfs_bus *alloc_bus(void) } /** - * open_bus_dir: opens up sysfs bus directory - * returns sysfs_directory struct with success and NULL with error + * sysfs_get_bus_devices: gets all devices for bus + * @bus: bus to get devices for + * returns dlist of devices with success and NULL with failure */ -static struct sysfs_directory *open_bus_dir(const unsigned char *name) +struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) { - struct sysfs_directory *busdir = NULL; + struct sysfs_device *bdev = NULL; + struct sysfs_directory *devdir = NULL; + struct sysfs_link *curl = NULL; + unsigned char path[SYSFS_PATH_MAX]; + + if (bus == NULL) { + errno = EINVAL; + return NULL; + } + memset(path, 0, SYSFS_PATH_MAX); + strcpy(path, bus->path); + strcat(path, "/"); + strcat(path, SYSFS_DEVICES_NAME); + devdir = sysfs_open_directory(path); + if (devdir == NULL) + return NULL; + + if (sysfs_read_dir_links(devdir) != 0) { + sysfs_close_directory(devdir); + return NULL; + } + + dlist_for_each_data(devdir->links, curl, struct sysfs_link) { + bdev = sysfs_open_device(curl->target); + if (bdev == NULL) { + dprintf("Error opening device at %s\n", curl->target); + continue; + } + if (bus->devices == NULL) + bus->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), sysfs_close_dev); + dlist_unshift(bus->devices, bdev); + } + sysfs_close_directory(devdir); + + return (bus->devices); +} + +/** + * sysfs_get_bus_drivers: get all pci drivers + * @bus: pci bus to add drivers to + * returns dlist of drivers with success and NULL with error + */ +struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) +{ + struct sysfs_driver *driver = NULL; + struct sysfs_directory *drvdir = NULL; + struct sysfs_directory *cursub = NULL; + unsigned char path[SYSFS_PATH_MAX]; + + if (bus == NULL) { + errno = EINVAL; + return NULL; + } + memset(path, 0, SYSFS_PATH_MAX); + strcpy(path, bus->path); + strcat(path, "/"); + strcat(path, SYSFS_DRIVERS_NAME); + drvdir = sysfs_open_directory(path); + if (drvdir == NULL) + return NULL; + + if (sysfs_read_dir_subdirs(drvdir) != 0) { + sysfs_close_directory(drvdir); + return NULL; + } + dlist_for_each_data(drvdir->subdirs, cursub, struct sysfs_directory) { + driver = sysfs_open_driver(cursub->path); + if (driver == NULL) { + dprintf("Error opening driver at %s\n", cursub->path); + continue; + } + if (bus->drivers == NULL) + bus->drivers = dlist_new_with_delete + (sizeof(struct sysfs_driver), sysfs_close_drv); + dlist_unshift(bus->drivers, driver); + } + sysfs_close_directory(drvdir); + return (bus->drivers); +} + +/** + * sysfs_open_bus: opens specific bus and all its devices on system + * returns sysfs_bus structure with success or NULL with error. + */ +struct sysfs_bus *sysfs_open_bus(const unsigned char *name) +{ + struct sysfs_bus *bus = NULL; unsigned char buspath[SYSFS_PATH_MAX]; if (name == NULL) { @@ -114,208 +202,21 @@ static struct sysfs_directory *open_bus_dir(const unsigned char *name) if (sysfs_trailing_slash(buspath) == 0) strcat(buspath, "/"); - + strcat(buspath, SYSFS_BUS_NAME); strcat(buspath, "/"); strcat(buspath, name); - busdir = sysfs_open_directory(buspath); - if (busdir == NULL) { - errno = EINVAL; - dprintf("Bus %s not supported on this system\n", - name); + if ((sysfs_path_is_dir(buspath)) != 0) { + dprintf("Invalid path to bus: %s\n", buspath); return NULL; } - if ((sysfs_read_directory(busdir)) != 0) { - dprintf("Error reading %s bus dir %s\n", name, - buspath); - sysfs_close_directory(busdir); - return NULL; - } - /* read in devices and drivers subdirs */ - sysfs_read_all_subdirs(busdir); - - return busdir; -} - -/** - * get_all_bus_devices: gets all devices for bus - * @bus: bus to get devices for - * returns 0 with success and -1 with failure - */ -static int get_all_bus_devices(struct sysfs_bus *bus) -{ - struct sysfs_device *bdev = NULL; - struct sysfs_directory *cur = NULL; - struct sysfs_link *curl = NULL; - - if (bus == NULL || bus->directory == NULL) { - errno = EINVAL; - return -1; - } - if (bus->directory->subdirs == NULL) - return 0; - - dlist_for_each_data(bus->directory->subdirs, cur, - struct sysfs_directory) { - if (strcmp(cur->name, SYSFS_DEVICES_NAME) != 0) - continue; - if (cur->links == NULL) - continue; - dlist_for_each_data(cur->links, curl, struct sysfs_link) { - bdev = sysfs_open_device(curl->target); - if (bdev == NULL) { - dprintf("Error opening device at %s\n", - curl->target); - continue; - } - if (bus->devices == NULL) - bus->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_dev); - dlist_unshift(bus->devices, bdev); - } - } - - return 0; -} - -/** - * get_all_bus_drivers: get all pci drivers - * @bus: pci bus to add drivers to - * returns 0 with success and -1 with error - */ -static int get_all_bus_drivers(struct sysfs_bus *bus) -{ - struct sysfs_driver *driver = NULL; - struct sysfs_directory *cur = NULL; - struct sysfs_directory *cursub = NULL; - - if (bus == NULL || bus->directory == NULL) { - errno = EINVAL; - return -1; - } - if (bus->directory->subdirs == NULL) - return 0; - - dlist_for_each_data(bus->directory->subdirs, cur, - struct sysfs_directory) { - if (strcmp(cur->name, SYSFS_DRIVERS_NAME) != 0) - continue; - if (cur->subdirs == NULL) - continue; - dlist_for_each_data(cur->subdirs, cursub, - struct sysfs_directory) { - driver = sysfs_open_driver(cursub->path); - if (driver == NULL) { - dprintf("Error opening driver at %s\n", - cursub->path); - continue; - } - if (bus->drivers == NULL) - bus->drivers = dlist_new_with_delete - (sizeof(struct sysfs_driver), - sysfs_close_drv); - dlist_unshift(bus->drivers, driver); - } - } - - return 0; -} - -/** - * match_bus_device_to_driver: returns 1 if device is bound to driver - * @driver: driver to match - * @busid: busid of device to match - * returns 1 if found and 0 if not found - */ -static int match_bus_device_to_driver(struct sysfs_driver *driver, - unsigned char *busid) -{ - struct sysfs_link *cur = NULL; - int found = 0; - - if (driver == NULL || driver->directory == NULL || busid == NULL) { - errno = EINVAL; - return found; - } - if (driver->directory->links != NULL) { - dlist_for_each_data(driver->directory->links, cur, - struct sysfs_link) { - if ((strcmp(cur->name, busid)) == 0) - found++; - } - } - return found; -} - -/** - * link_bus_devices_to_drivers: goes through and links devices to drivers - * @bus: bus to link - */ -static void link_bus_devices_to_drivers(struct sysfs_bus *bus) -{ - struct sysfs_device *dev = NULL; - struct sysfs_driver *drv = NULL; - - if (bus != NULL && bus->devices != NULL && bus->drivers != NULL) { - dlist_for_each_data(bus->devices, dev, struct sysfs_device) { - dlist_for_each_data(bus->drivers, drv, - struct sysfs_driver) { - if ((match_bus_device_to_driver(drv, - dev->bus_id)) != 0) { - strncpy(dev->driver_name, drv->name, - SYSFS_NAME_LEN); - if (drv->devices == NULL) - drv->devices = dlist_new - (sizeof(struct - sysfs_device)); - dlist_unshift(drv->devices, dev); - } - } - } - } -} - -/** - * sysfs_open_bus: opens specific bus and all its devices on system - * returns sysfs_bus structure with success or NULL with error. - */ -struct sysfs_bus *sysfs_open_bus(const unsigned char *name) -{ - struct sysfs_bus *bus = NULL; - struct sysfs_directory *busdir = NULL; - - if (name == NULL) { - errno = EINVAL; - return NULL; - } - bus = alloc_bus(); if (bus == NULL) { dprintf("calloc failed\n"); return NULL; } strcpy(bus->name, name); - busdir = open_bus_dir(name); - if (busdir == NULL) { - dprintf("Invalid bus, %s not supported on this system\n", - name); - sysfs_close_bus(bus); - return NULL; - } - strcpy(bus->path, busdir->path); - bus->directory = busdir; - if ((get_all_bus_devices(bus)) != 0) { - dprintf("Error reading %s bus devices\n", name); - sysfs_close_bus(bus); - return NULL; - } - if ((get_all_bus_drivers(bus)) != 0) { - dprintf("Error reading %s bus drivers\n", name); - sysfs_close_bus(bus); - return NULL; - } - link_bus_devices_to_drivers(bus); + strcpy(bus->path, buspath); return bus; } @@ -334,6 +235,12 @@ struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, return NULL; } + if (bus->devices == NULL) { + bus->devices = sysfs_get_bus_devices(bus); + if (bus->devices == NULL) + return NULL; + } + return (struct sysfs_device *)dlist_find_custom(bus->devices, id, bus_device_id_equal); } @@ -352,6 +259,12 @@ struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, return NULL; } + if (bus->drivers == NULL) { + bus->drivers = sysfs_get_bus_drivers(bus); + if (bus->drivers == NULL) + return NULL; + } + return (struct sysfs_driver *)dlist_find_custom(bus->drivers, drvname, bus_driver_name_equal); } @@ -363,8 +276,28 @@ struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, */ struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) { - if (bus == NULL || bus->directory == NULL) + if (bus == NULL) return NULL; + + if (bus->directory == NULL) { + bus->directory = sysfs_open_directory(bus->path); + if (bus->directory == NULL) + return NULL; + } + if (bus->directory->attributes == NULL) { + if ((sysfs_read_dir_attributes(bus->directory)) != 0) + return NULL; + } else { + if ((sysfs_path_is_dir(bus->path)) != 0) { + dprintf("Bus at %s no longer exists\n", bus->path); + return NULL; + } + if ((sysfs_refresh_attributes + (bus->directory->attributes)) != 0) { + dprintf("Error refreshing bus attributes\n"); + return NULL; + } + } return bus->directory->attributes; } @@ -378,10 +311,16 @@ struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, unsigned char *attrname) { - if (bus == NULL || bus->directory == NULL || attrname == NULL) { + struct dlist *attrlist = NULL; + + if (bus == NULL) { errno = EINVAL; return NULL; } + attrlist = sysfs_get_bus_attributes(bus); + if (attrlist == NULL) + return NULL; + return sysfs_get_directory_attribute(bus->directory, attrname); } @@ -408,9 +347,10 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, dprintf("Error getting sysfs mount point\n"); return NULL; } - + if (sysfs_trailing_slash(path) == 0) strcat(path, "/"); + strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, busname); @@ -448,6 +388,7 @@ int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, } memset(subsys, 0, SYSFS_PATH_MAX); + strcat(subsys, "/"); strcpy(subsys, SYSFS_BUS_NAME); buslist = sysfs_open_subsystem_list(subsys); if (buslist != NULL) { @@ -476,4 +417,3 @@ int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, } return -1; } - diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 54f22eee24..169600d5fd 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -58,6 +58,8 @@ void sysfs_close_class_device(struct sysfs_class_device *dev) sysfs_close_device(dev->sysdevice); if (dev->driver != NULL) sysfs_close_driver(dev->driver); + if (dev->parent != NULL) + sysfs_close_class_device(dev->parent); free(dev); } } @@ -96,54 +98,6 @@ static struct sysfs_class *alloc_class(void) return (struct sysfs_class *)calloc(1, sizeof(struct sysfs_class)); } -/** - * open_class_dir: opens up sysfs class directory - * returns sysfs_directory struct with success and NULL with error - */ -static struct sysfs_directory *open_class_dir(const unsigned char *name) -{ - struct sysfs_directory *classdir = NULL; - unsigned char classpath[SYSFS_PATH_MAX]; - - if (name == NULL) { - errno = EINVAL; - return NULL; - } - - memset(classpath, 0, SYSFS_PATH_MAX); - if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { - dprintf("Sysfs not supported on this system\n"); - return NULL; - } - - if (sysfs_trailing_slash(classpath) == 0) - strcat(classpath, "/"); - /* - * We shall now treat "block" also as a class. Hence, check here - * if "name" is "block" and proceed accordingly - */ - if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { - strcat(classpath, SYSFS_BLOCK_NAME); - } else { - strcat(classpath, SYSFS_CLASS_NAME); - strcat(classpath, "/"); - strcat(classpath, name); - } - classdir = sysfs_open_directory(classpath); - if (classdir == NULL) { - errno = EINVAL; - dprintf("Class %s not supported on this system\n", name); - return NULL; - } - if ((sysfs_read_directory(classdir)) != 0) { - dprintf("Error reading %s class dir %s\n", name, classpath); - sysfs_close_directory(classdir); - return NULL; - } - - return classdir; -} - /** * set_classdev_classname: Grabs classname from path * @cdev: class device to set @@ -154,20 +108,18 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) unsigned char *c = NULL, *e = NULL; int count = 0; - c = strstr(cdev->path, SYSFS_CLASS_DIR); - if (c == NULL) - c = strstr(cdev->path, SYSFS_BLOCK_DIR); - else { - c++; - while (c != NULL && *c != '/') - c++; + c = strstr(cdev->path, SYSFS_CLASS_NAME); + if (c == NULL) { + c = strstr(cdev->path, SYSFS_BLOCK_NAME); + } else { + c = strstr(c, "/"); } - if (c == NULL) + if (c == NULL) strcpy(cdev->classname, SYSFS_UNKNOWN); - else { - c++; + if (*c == '/') + c++; e = c; while (e != NULL && *e != '/' && *e != '\0') { e++; @@ -185,15 +137,15 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) struct sysfs_class_device *sysfs_open_class_device(const unsigned char *path) { struct sysfs_class_device *cdev = NULL; - struct sysfs_directory *dir = NULL; - struct sysfs_link *curl = NULL; - struct sysfs_device *sdev = NULL; - struct sysfs_driver *drv = NULL; if (path == NULL) { errno = EINVAL; return NULL; } + if ((sysfs_path_is_dir(path)) != 0) { + dprintf("%s is not a valid path to a class device\n", path); + return NULL; + } cdev = alloc_class_device(); if (cdev == NULL) { dprintf("calloc failed\n"); @@ -201,81 +153,41 @@ struct sysfs_class_device *sysfs_open_class_device(const unsigned char *path) } if ((sysfs_get_name_from_path(path, cdev->name, SYSFS_NAME_LEN)) != 0) { errno = EINVAL; - dprintf("Invalid class device path %s\n", path); + dprintf("Error getting class device name\n"); sysfs_close_class_device(cdev); return NULL; } - dir = sysfs_open_directory(path); - if (dir == NULL) { - dprintf("Error opening class device at %s\n", path); - sysfs_close_class_device(cdev); - return NULL; - } - if ((sysfs_read_directory(dir)) != 0) { - dprintf("Error reading class device at %s\n", path); - sysfs_close_directory(dir); - sysfs_close_class_device(cdev); - return NULL; - } - sysfs_read_all_subdirs(dir); - cdev->directory = dir; - strcpy(cdev->path, dir->path); + strcpy(cdev->path, path); set_classdev_classname(cdev); - /* get driver and device, if implemented */ - if (cdev->directory->links != NULL) { - dlist_for_each_data(cdev->directory->links, curl, - struct sysfs_link) { - if (strncmp(curl->name, SYSFS_DEVICES_NAME, 6) == 0) { - sdev = sysfs_open_device(curl->target); - if (sdev != NULL) { - cdev->sysdevice = sdev; - if (cdev->driver != NULL) - strncpy(sdev->driver_name, - cdev->driver->name, - SYSFS_NAME_LEN); - } - } else if (strncmp(curl->name, - SYSFS_DRIVERS_NAME, 6) == 0) { - drv = sysfs_open_driver(curl->target); - if (drv != NULL) { - cdev->driver = drv; - if (cdev->sysdevice != NULL) { - strncpy(cdev->sysdevice->name, - drv->name, - SYSFS_NAME_LEN); - if (drv->devices == NULL) - drv->devices = - dlist_new - (sizeof(struct - sysfs_device)); - dlist_unshift(drv->devices, - cdev->sysdevice); - } - } - } - } - } return cdev; } /** - * get_all_class_devices: gets all devices for class + * sysfs_get_class_devices: gets all devices for class * @class: class to get devices for - * returns 0 with success and -1 with failure + * returns dlist of class_devices with success and NULL with error */ -static int get_all_class_devices(struct sysfs_class *cls) +struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) { struct sysfs_class_device *dev = NULL; struct sysfs_directory *cur = NULL; - if (cls == NULL || cls->directory == NULL) { + if (cls == NULL) { errno = EINVAL; - return -1; + return NULL; } - if (cls->directory->subdirs == NULL) - return 0; + if (cls->directory == NULL) { + cls->directory = sysfs_open_directory(cls->path); + if (cls->directory == NULL) + return NULL; + } + + if ((sysfs_read_dir_subdirs(cls->directory) != 0) + || cls->directory->subdirs == NULL) + return NULL; + dlist_for_each_data(cls->directory->subdirs, cur, struct sysfs_directory) { dev = sysfs_open_class_device(cur->path); @@ -289,7 +201,7 @@ static int get_all_class_devices(struct sysfs_class *cls) sysfs_close_cls_dev); dlist_unshift(cls->devices, dev); } - return 0; + return cls->devices; } /** @@ -299,34 +211,46 @@ static int get_all_class_devices(struct sysfs_class *cls) struct sysfs_class *sysfs_open_class(const unsigned char *name) { struct sysfs_class *cls = NULL; - struct sysfs_directory *classdir = NULL; + unsigned char classpath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; return NULL; } + memset(classpath, 0, SYSFS_PATH_MAX); + if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { + dprintf("Sysfs not supported on this system\n"); + return NULL; + } + + if (sysfs_trailing_slash(classpath) == 0) + strcat(classpath, "/"); + + /* + * We shall now treat "block" also as a class. Hence, check here + * if "name" is "block" and proceed accordingly + */ + if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { + strcat(classpath, SYSFS_BLOCK_NAME); + } else { + strcat(classpath, SYSFS_CLASS_NAME); + strcat(classpath, "/"); + strcat(classpath, name); + } + if ((sysfs_path_is_dir(classpath)) != 0) { + dprintf("Class %s not found on the system\n", name); + return NULL; + } + cls = alloc_class(); if (cls == NULL) { dprintf("calloc failed\n"); return NULL; } strcpy(cls->name, name); - classdir = open_class_dir(name); - if (classdir == NULL) { - dprintf("Invalid class, %s not supported on this system\n", - name); - sysfs_close_class(cls); - return NULL; - } - cls->directory = classdir; - strcpy(cls->path, classdir->path); - if ((get_all_class_devices(cls)) != 0) { - dprintf("Error reading %s class devices\n", name); - sysfs_close_class(cls); - return NULL; - } - + strcpy(cls->path, classpath); + return cls; } @@ -338,15 +262,189 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class, unsigned char *name) { + struct dlist *devlist = NULL; + if (class == NULL || name == NULL) { errno = EINVAL; return NULL; } + if (class->devices == NULL) { + class->devices = sysfs_get_class_devices(class); + if (devlist == NULL) + return NULL; + } return (struct sysfs_class_device *)dlist_find_custom(class->devices, name, class_name_equal); } +/** + * sysfs_get_classdev_device: returns the sysfs_device corresponding to + * sysfs_class_device, if present + * @clsdev: class device whose sysfs_device is required + * Returns sysfs_device on success, NULL on error or if device is not + * implemented + */ +struct sysfs_device *sysfs_get_classdev_device + (struct sysfs_class_device *clsdev) +{ + struct sysfs_link *devlink = NULL; + + if (clsdev == NULL) { + errno = EINVAL; + return NULL; + } + + if (clsdev->sysdevice != NULL) + return (clsdev->sysdevice); + + if (clsdev->directory == NULL) { + clsdev->directory = sysfs_open_directory(clsdev->path); + if (clsdev->directory == NULL) + return NULL; + } + devlink = sysfs_get_directory_link(clsdev->directory, "device"); + if (devlink == NULL) + return NULL; + + clsdev->sysdevice = sysfs_open_device(devlink->target); + if (clsdev->sysdevice == NULL) + return NULL; + if (clsdev->driver != NULL) + strcpy(clsdev->sysdevice->driver_name, clsdev->driver->name); + + return (clsdev->sysdevice); +} + +/** + * sysfs_get_classdev_driver: returns the sysfs_driver corresponding to + * sysfs_class_device, if present + * @clsdev: class device whose sysfs_device is required + * Returns sysfs_driver on success, NULL on error or if driver is not + * implemented + */ +struct sysfs_driver *sysfs_get_classdev_driver + (struct sysfs_class_device *clsdev) +{ + struct sysfs_link *drvlink = NULL; + + if (clsdev == NULL) { + errno = EINVAL; + return NULL; + } + + if (clsdev->driver != NULL) + return (clsdev->driver); + + if (clsdev->directory == NULL) { + clsdev->directory = sysfs_open_directory(clsdev->path); + if (clsdev->directory == NULL) + return NULL; + } + drvlink = sysfs_get_directory_link(clsdev->directory, "driver"); + if (drvlink != NULL) { + clsdev->driver = sysfs_open_driver(drvlink->target); + if (clsdev->driver == NULL) + return NULL; + + } + return (clsdev->driver); +} + +/* + * get_blockdev_parent: Get the parent class device for a "block" subsystem + * device if present + * @clsdev: block subsystem class device whose parent needs to be found + * Returns 0 on success and 1 on error + */ +static int get_blockdev_parent(struct sysfs_class_device *clsdev) +{ + unsigned char parent_path[SYSFS_PATH_MAX], value[256], *c = NULL; + + memset(parent_path, 0, SYSFS_PATH_MAX); + strcpy(parent_path, clsdev->path); + + c = strstr(parent_path, SYSFS_BLOCK_NAME); + if (c == NULL) { + dprintf("Class device %s does not belong to BLOCK subsystem", + clsdev->name); + return 1; + } + + c += strlen(SYSFS_BLOCK_NAME); + if (*c == '/') + c++; + else + goto errout; + + /* validate whether the given class device is a partition or not */ + if ((strncmp(c, clsdev->name, strlen(clsdev->name))) == 0) { + dprintf("%s not a partition\n", clsdev->name); + return 1; + } + c = strchr(c, '/'); + if (c == NULL) + goto errout; + *c = '\0'; + + /* Now validate if the parent has the "dev" attribute */ + memset(value, 0, 256); + strcat(parent_path, "/dev"); + if ((sysfs_read_attribute_value(parent_path, value, 256)) != 0) { + dprintf("Block device %s does not have a parent\n", + clsdev->name); + return 1; + } + + c = strrchr(parent_path, '/'); + if (c == NULL) + goto errout; + + *c = '\0'; + clsdev->parent = sysfs_open_class_device(parent_path); + if (clsdev->parent == NULL) { + dprintf("Error opening the parent class device at %s\n", + parent_path); + return 1; + } + return 0; + +errout: + dprintf("Invalid path %s\n", clsdev->path); + return 1; +} + +/** + * sysfs_get_classdev_parent: Retrieves the parent of a class device. + * eg., when working with hda1, this function can be used to retrieve the + * sysfs_class_device for hda + * + * @clsdev: class device whose parent details are required. + * Returns sysfs_class_device of the parent on success, NULL on failure + */ +struct sysfs_class_device *sysfs_get_classdev_parent + (struct sysfs_class_device *clsdev) +{ + if (clsdev == NULL) { + errno = EINVAL; + return NULL; + } + if (clsdev->parent != NULL) + return (clsdev->parent); + + /* + * As of now, only block devices have a parent child heirarchy in sysfs + * We do not know, if, in the future, more classes will have a similar + * structure. Hence, we now call a specialized function for block and + * later we can add support functions for other subsystems as required. + */ + if (!(strcmp(clsdev->classname, SYSFS_BLOCK_NAME))) { + if ((get_blockdev_parent(clsdev)) == 0) + return (clsdev->parent); + } + return NULL; +} + /** * get_classdev_path: given the class and a device in the class, return the * absolute path to the device @@ -367,6 +465,7 @@ static int get_classdev_path(const unsigned char *classname, dprintf("Error getting sysfs mount path\n"); return -1; } + if (sysfs_trailing_slash(path) == 0) strcat(path, "/"); @@ -427,9 +526,32 @@ struct sysfs_class_device *sysfs_open_class_device_by_name */ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev) { - if (cdev == NULL || cdev->directory == NULL) + if (cdev == NULL) return NULL; + if (cdev->directory == NULL) { + cdev->directory = sysfs_open_directory(cdev->path); + if (cdev->directory == NULL) + return NULL; + } + if (cdev->directory->attributes == NULL) { + if ((sysfs_read_dir_attributes(cdev->directory)) != 0) { + dprintf("Error reading attributes for directory %s\n", + cdev->directory->path); + return NULL; + } + } else { + if ((sysfs_path_is_dir(cdev->path)) != 0) { + dprintf("Class device at %s no longer exists\n", + cdev->path); + return NULL; + } + if ((sysfs_refresh_attributes + (cdev->directory->attributes)) != 0) { + dprintf("Error refreshing classdev attributes\n"); + return NULL; + } + } return (cdev->directory->attributes); } @@ -443,18 +565,38 @@ struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const unsigned char *name) { struct sysfs_attribute *cur = NULL; - - if (clsdev == NULL || clsdev->directory == NULL || - clsdev->directory->attributes == NULL || name == NULL) { + struct sysfs_directory *sdir = NULL; + struct dlist *attrlist = NULL; + + if (clsdev == NULL || name == NULL) { errno = EINVAL; return NULL; } - + /* + * First, see if it's in the current directory. Then look at + * subdirs since class devices can have subdirs of attributes. + */ + attrlist = sysfs_get_classdev_attributes(clsdev); + if (attrlist == NULL) + return NULL; cur = sysfs_get_directory_attribute(clsdev->directory, (unsigned char *)name); if (cur != NULL) return cur; + if (clsdev->directory->subdirs == NULL) + if ((sysfs_read_dir_subdirs(clsdev->directory)) != 0 || + clsdev->directory->subdirs == NULL) + return NULL; + + dlist_for_each_data(clsdev->directory->subdirs, sdir, + struct sysfs_directory) { + cur = sysfs_get_directory_attribute(sdir, + (unsigned char *)name); + if (cur != NULL) + return cur; + } + return NULL; } diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 323a43dac1..82b54719ff 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -23,38 +23,6 @@ #include "libsysfs.h" #include "sysfs.h" -static int confirm_device_bus(struct sysfs_device *dev, - unsigned char *busname, unsigned char *bus_id) -{ - struct sysfs_link *devlink = NULL; - unsigned char devpath[SYSFS_PATH_MAX]; - int result = 0; - - if (busname == NULL || bus_id == NULL) - return -1; - - if (sysfs_get_mnt_path(devpath, SYSFS_PATH_MAX) != 0) - return -1; - - if (sysfs_trailing_slash(devpath) == 0) - strcat(devpath, "/"); - strcat(devpath, SYSFS_BUS_NAME); - strcat(devpath, "/"); - strcat(devpath, busname); - strcat(devpath, SYSFS_DEVICES_DIR); - strcat(devpath, "/"); - strcat(devpath, bus_id); - - devlink = sysfs_open_link(devpath); - if (devlink == NULL) - return -1; - - if (strcmp(devlink->target, dev->path) == 0) - result++; - sysfs_close_link(devlink); - return result; -} - /** * get_device_bus: retrieves the bus name the device is on, checks path to * bus' link to make sure it has correct device. @@ -63,33 +31,53 @@ static int confirm_device_bus(struct sysfs_device *dev, */ static int get_device_bus(struct sysfs_device *dev) { - unsigned char subsys[SYSFS_NAME_LEN], *bus = NULL, *curdev = NULL; - struct dlist *buslist = NULL, *device_list = NULL; + unsigned char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX]; + unsigned char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL; + struct dlist *buslist = NULL; if (dev == NULL) { errno = EINVAL; return -1; } - strcpy(subsys, SYSFS_BUS_DIR); /* subsys = /bus */ + memset(subsys, 0, SYSFS_NAME_LEN); + strcat(subsys, "/"); + strcpy(subsys, SYSFS_BUS_NAME); /* subsys = /bus */ buslist = sysfs_open_subsystem_list(subsys); if (buslist != NULL) { dlist_for_each_data(buslist, bus, char) { - device_list = sysfs_open_bus_devices_list(bus); - if (device_list != NULL) { - dlist_for_each_data(device_list, - curdev, char) { - if (strcmp(dev->bus_id, curdev) == 0 - && confirm_device_bus(dev, bus, - curdev) > 0) { - strcpy(dev->bus, bus); - sysfs_close_list(device_list); - sysfs_close_list(buslist); - return 0; - } - } - sysfs_close_list(device_list); - } + memset(path, 0, SYSFS_PATH_MAX); + strcpy(path, dev->path); + c = strstr(path, "/devices"); + if (c == NULL) { + dprintf("Invalid path to device %s\n", path); + sysfs_close_list(buslist); + return -1; + } + *c = '\0'; + strcat(path, "/"); + strcat(path, SYSFS_BUS_NAME); + strcat(path, "/"); + strcat(path, bus); + strcat(path, "/"); + strcat(path, SYSFS_DEVICES_NAME); + strcat(path, "/"); + strcat(path, dev->bus_id); + if ((sysfs_path_is_link(path)) == 0) { + memset(target, 0, SYSFS_PATH_MAX); + if ((sysfs_get_link(path, target, + SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting link target\n"); + sysfs_close_list(buslist); + return -1; + } + if (!(strncmp(target, dev->path, + SYSFS_PATH_MAX))) { + strcpy(dev->bus, bus); + sysfs_close_list(buslist); + return 0; + } + } } sysfs_close_list(buslist); } @@ -157,28 +145,32 @@ static struct sysfs_device *alloc_device(void) } /** - * sysfs_get_device_attr: searches dev's attributes by name - * @dev: device to look through - * @name: attribute name to get - * returns sysfs_attribute reference with success or NULL with error. + * open_device_dir: opens up sysfs_directory for specific root dev + * @name: name of root + * returns struct sysfs_directory with success and NULL with error */ -struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, - const unsigned char *name) +static struct sysfs_directory *open_device_dir(const unsigned char *path) { - struct sysfs_attribute *cur = NULL; + struct sysfs_directory *rdir = NULL; - if (dev == NULL || dev->directory == NULL - || dev->directory->attributes == NULL || name == NULL) { + if (path == NULL) { errno = EINVAL; return NULL; } - - cur = sysfs_get_directory_attribute(dev->directory, - (unsigned char *)name); - if (cur != NULL) - return cur; - return NULL; + rdir = sysfs_open_directory(path); + if (rdir == NULL) { + errno = EINVAL; + dprintf ("Device %s not supported on this system\n", path); + return NULL; + } + if ((sysfs_read_directory(rdir)) != 0) { + dprintf ("Error reading device at dir %s\n", path); + sysfs_close_directory(rdir); + return NULL; + } + + return rdir; } /** @@ -189,40 +181,34 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, struct sysfs_device *sysfs_open_device(const unsigned char *path) { struct sysfs_device *dev = NULL; - struct sysfs_directory *sdir = NULL; if (path == NULL) { errno = EINVAL; return NULL; } + if ((sysfs_path_is_dir(path)) != 0) { + dprintf("Incorrect path to device: %s\n", path); + return NULL; + } dev = alloc_device(); if (dev == NULL) { dprintf("Error allocating device at %s\n", path); return NULL; } - sdir = sysfs_open_directory(path); - if (sdir == NULL) { - dprintf("Invalid device at %s\n", path); + if ((sysfs_get_name_from_path(path, dev->bus_id, + SYSFS_NAME_LEN)) != 0) { errno = EINVAL; + dprintf("Error getting device bus_id\n"); sysfs_close_device(dev); return NULL; } - if ((sysfs_read_directory(sdir)) != 0) { - dprintf("Error reading device directory at %s\n", path); - sysfs_close_directory(sdir); - sysfs_close_device(dev); - return NULL; - } - dev->directory = sdir; - strcpy(dev->bus_id, sdir->name); - strcpy(dev->path, sdir->path); - + strcpy(dev->path, path); /* * The "name" attribute no longer exists... return the device's * sysfs representation instead, in the "dev->name" field, which * implies that the dev->name and dev->bus_id contain same data. */ - strncpy(dev->name, sdir->name, SYSFS_NAME_LEN); + strncpy(dev->name, dev->bus_id, SYSFS_NAME_LEN); if (get_device_bus(dev) != 0) strcpy(dev->bus, SYSFS_UNKNOWN); @@ -251,6 +237,11 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path) dprintf("Error opening root device at %s\n", path); return NULL; } + if (rootdev->directory == NULL) { + rootdev->directory = open_device_dir(rootdev->path); + if (rootdev->directory == NULL) + return NULL; + } if (rootdev->directory->subdirs != NULL) { dlist_for_each_data(rootdev->directory->subdirs, cur, struct sysfs_directory) { @@ -288,63 +279,25 @@ void sysfs_close_root_device(struct sysfs_root_device *root) } /** - * open_root_device_dir: opens up sysfs_directory for specific root dev - * @name: name of root - * returns struct sysfs_directory with success and NULL with error - */ -static struct sysfs_directory *open_root_device_dir(const unsigned char *name) -{ - struct sysfs_directory *rdir = NULL; - unsigned char rootpath[SYSFS_PATH_MAX]; - - if (name == NULL) { - errno = EINVAL; - return NULL; - } - - memset(rootpath, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(rootpath, SYSFS_PATH_MAX) != 0) { - dprintf ("Sysfs not supported on this system\n"); - return NULL; - } - - if (sysfs_trailing_slash(rootpath) == 0) - strcat(rootpath, "/"); - - strcat(rootpath, SYSFS_DEVICES_NAME); - strcat(rootpath, "/"); - strcat(rootpath, name); - rdir = sysfs_open_directory(rootpath); - if (rdir == NULL) { - errno = EINVAL; - dprintf ("Root device %s not supported on this system\n", - name); - return NULL; - } - if (sysfs_read_directory(rdir) != 0) { - dprintf ("Error reading %s root device at dir %s\n", name, - rootpath); - sysfs_close_directory(rdir); - return NULL; - } - - return rdir; -} - -/** - * get_all_root_devices: opens up all the devices under this root device + * sysfs_get_root_devices: opens up all the devices under this root device * @root: root device to open devices for - * returns 0 with success and -1 with error + * returns dlist of devices with success and NULL with error */ -static int get_all_root_devices(struct sysfs_root_device *root) +struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root) { struct sysfs_device *dev = NULL; struct sysfs_directory *cur = NULL; - if (root == NULL || root->directory == NULL) { + if (root == NULL) { errno = EINVAL; - return -1; + return NULL; } + if (root->directory == NULL) { + root->directory = open_device_dir(root->path); + if (root->directory == NULL) + return NULL; + } + if (root->directory->subdirs == NULL) return 0; @@ -362,7 +315,7 @@ static int get_all_root_devices(struct sysfs_root_device *root) dlist_unshift(root->devices, dev); } - return 0; + return root->devices; } /** @@ -374,33 +327,37 @@ static int get_all_root_devices(struct sysfs_root_device *root) struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) { struct sysfs_root_device *root = NULL; - struct sysfs_directory *rootdir = NULL; + unsigned char rootpath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; return NULL; } + memset(rootpath, 0, SYSFS_PATH_MAX); + if (sysfs_get_mnt_path(rootpath, SYSFS_PATH_MAX) != 0) { + dprintf ("Sysfs not supported on this system\n"); + return NULL; + } + + if (sysfs_trailing_slash(rootpath) == 0) + strcat(rootpath, "/"); + + strcat(rootpath, SYSFS_DEVICES_NAME); + strcat(rootpath, "/"); + strcat(rootpath, name); + if ((sysfs_path_is_dir(rootpath)) != 0) { + errno = EINVAL; + dprintf("Invalid root device: %s\n", name); + return NULL; + } root = (struct sysfs_root_device *)calloc (1, sizeof(struct sysfs_root_device)); if (root == NULL) { dprintf("calloc failure\n"); return NULL; } - rootdir = open_root_device_dir(name); - if (rootdir == NULL) { - dprintf ("Invalid root device, %s not supported\n", name); - sysfs_close_root_device(root); - return NULL; - } - strcpy(root->path, rootdir->path); - root->directory = rootdir; - if (get_all_root_devices(root) != 0) { - dprintf ("Error retrieving devices for root %s\n", name); - sysfs_close_root_device(root); - return NULL; - } - + strcpy(root->path, rootpath); return root; } @@ -411,12 +368,60 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) */ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) { - if (device == NULL || device->directory == NULL) + if (device == NULL) return NULL; + if (device->directory == NULL) { + device->directory = sysfs_open_directory(device->path); + if (device->directory == NULL) + return NULL; + } + if (device->directory->attributes == NULL) { + if ((sysfs_read_dir_attributes(device->directory)) != 0) + return NULL; + } else { + if ((sysfs_path_is_dir(device->path)) != 0) { + dprintf("Device at %s no longer exists", device->path); + return NULL; + } + if ((sysfs_refresh_attributes + (device->directory->attributes)) != 0) { + dprintf("Error refreshing device attributes\n"); + return NULL; + } + } return (device->directory->attributes); } +/** + * sysfs_get_device_attr: searches dev's attributes by name + * @dev: device to look through + * @name: attribute name to get + * returns sysfs_attribute reference with success or NULL with error. + */ +struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, + const unsigned char *name) +{ + struct sysfs_attribute *cur = NULL; + struct dlist *attrlist = NULL; + + if (dev == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + + attrlist = sysfs_get_device_attributes(dev); + if (attrlist == NULL) + return NULL; + + cur = sysfs_get_directory_attribute(dev->directory, + (unsigned char *)name); + if (cur != NULL) + return cur; + + return NULL; +} + /** * get_device_absolute_path: looks up the bus the device is on, gets * absolute path to the device @@ -428,24 +433,27 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) static int get_device_absolute_path(const unsigned char *device, const unsigned char *bus, unsigned char *path, size_t psize) { - unsigned char bus_path[SYSFS_NAME_LEN]; + unsigned char bus_path[SYSFS_PATH_MAX]; if (device == NULL || path == NULL) { errno = EINVAL; return -1; } - memset(bus_path, 0, SYSFS_NAME_LEN); + memset(bus_path, 0, SYSFS_PATH_MAX); if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX) != 0) { dprintf ("Sysfs not supported on this system\n"); return -1; } + if (sysfs_trailing_slash(bus_path) == 0) strcat(bus_path, "/"); + strcat(bus_path, SYSFS_BUS_NAME); strcat(bus_path, "/"); strcat(bus_path, bus); - strcat(bus_path, SYSFS_DEVICES_DIR); + strcat(bus_path, "/"); + strcat(bus_path, SYSFS_DEVICES_NAME); strcat(bus_path, "/"); strcat(bus_path, device); /* @@ -464,7 +472,6 @@ static int get_device_absolute_path(const unsigned char *device, * @bus_id: bus_id of the device to open - has to be the "bus_id" in * /sys/bus/xxx/devices * @bus: bus the device belongs to - * @bsize: size of the bus buffer * returns struct sysfs_device if found, NULL otherwise * NOTE: * 1. Use sysfs_close_device to close the device @@ -472,7 +479,7 @@ static int get_device_absolute_path(const unsigned char *device, * Use sysfs_find_device_bus to get the bus name */ struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, - const unsigned char *bus, size_t bsize) + const unsigned char *bus) { char sysfs_path[SYSFS_PATH_MAX]; struct sysfs_device *device = NULL; diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index e983d0eff4..ac2ecfcbe1 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -187,6 +187,13 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, return -1; } if (sysattr->method & SYSFS_METHOD_SHOW) { + /* + * read attribute again to see if we can get an updated value + */ + if ((sysfs_read_attribute(sysattr)) != 0) { + dprintf("Error reading attribute\n"); + return -1; + } if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0) { dprintf("Attribute %s already has the requested value %s\n", sysattr->name, new_value); @@ -254,7 +261,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) unsigned char *fbuf = NULL; unsigned char *vbuf = NULL; size_t length = 0; - int pgsize = 0; + long pgsize = 0; int fd; if (sysattr == NULL) { @@ -269,7 +276,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) #ifdef __KLIBC__ pgsize = 0x4000; #else - pgsize = getpagesize(); + pgsize = sysconf(_SC_PAGESIZE); #endif fbuf = (unsigned char *)calloc(1, pgsize+1); if (fbuf == NULL) { @@ -288,6 +295,14 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) free(fbuf); return -1; } + if (sysattr->len > 0) { + if ((sysattr->len == length) && + (!(strncmp(sysattr->value, fbuf, length)))) { + close(fd); + return 0; + } + free(sysattr->value); + } sysattr->len = length; close(fd); vbuf = (unsigned char *)realloc(fbuf, length+1); @@ -389,6 +404,7 @@ void sysfs_close_directory(struct sysfs_directory *sysdir) if (sysdir->attributes != NULL) dlist_destroy(sysdir->attributes); free(sysdir); + sysdir = NULL; } } @@ -424,10 +440,12 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) errno = EINVAL; return -1; } - if (sysdir->subdirs == NULL) - return 0; + if (sysdir->subdirs == NULL) + if ((sysfs_read_dir_subdirs(sysdir) != 0) + || sysdir->subdirs == NULL) + return 0; dlist_for_each_data(sysdir->subdirs, cursub, struct sysfs_directory) { - if (sysfs_read_directory(cursub) != 0) + if ((sysfs_read_directory(cursub)) != 0) dprintf ("Error reading subdirectory %s\n", cursub->name); } @@ -494,18 +512,131 @@ struct sysfs_link *sysfs_open_link(const unsigned char *linkpath) } /** - * sysfs_read_directory: grabs attributes, links, and subdirectories + * sysfs_refresh_attributes: Refresh attributes list + * @attrlist: list of attributes to refresh + * Returns 0 on success, 1 on failure + */ +int sysfs_refresh_attributes(struct dlist *attrlist) +{ + struct sysfs_attribute *attr = NULL; + + if (attrlist == NULL) { + errno = EINVAL; + return 1; + } + dlist_for_each_data(attrlist, attr, struct sysfs_attribute) { + if (attr->method & SYSFS_METHOD_SHOW) { + if ((sysfs_read_attribute(attr)) != 0) { + dprintf("Error reading attribute %s\n", attr->path); + if ((sysfs_path_is_file(attr->path)) != 0) { + dprintf("Attr %s no longer exists\n", + attr->name); + } + } + } else { + if ((sysfs_path_is_file(attr->path)) != 0) { + dprintf("Attr %s no longer exists\n", + attr->name); + } + } + } + if (attrlist->count == 0) { + dprintf("No attributes in the list, destroying list now\n"); + dlist_destroy(attrlist); + attrlist = NULL; + return 1; + } + return 0; +} + +/** + * add_attribute: open and add attribute at path to given directory + * @sysdir: directory to add attribute to + * @path: path to attribute + * returns 0 with success and -1 with error. + */ +static int add_attribute(struct sysfs_directory *sysdir, + const unsigned char *path) +{ + struct sysfs_attribute *attr = NULL; + + attr = sysfs_open_attribute(path); + if (attr == NULL) { + dprintf("Error opening attribute %s\n", path); + return -1; + } + if (attr->method & SYSFS_METHOD_SHOW) { + if ((sysfs_read_attribute(attr)) != 0) { + dprintf("Error reading attribute %s\n", path); + sysfs_close_attribute(attr); + return 0; + } + } + + if (sysdir->attributes == NULL) { + sysdir->attributes = dlist_new_with_delete + (sizeof(struct sysfs_attribute), sysfs_del_attribute); + } + dlist_unshift(sysdir->attributes, attr); + + return 0; +} + +/** + * add_subdirectory: open and add subdirectory at path to given directory + * @sysdir: directory to add subdir to + * @path: path to subdirectory + * returns 0 with success and -1 with error. + */ +static int add_subdirectory(struct sysfs_directory *sysdir, + const unsigned char *path) +{ + struct sysfs_directory *subdir = NULL; + + subdir = sysfs_open_directory(path); + if (subdir == NULL) { + dprintf("Error opening directory %s\n", path); + return -1; + } + if (sysdir->subdirs == NULL) + sysdir->subdirs = dlist_new_with_delete + (sizeof(struct sysfs_directory), sysfs_del_directory); + dlist_unshift(sysdir->subdirs, subdir); + return 0; +} + +/** + * add_link: open and add link at path to given directory + * @sysdir: directory to add link to + * @path: path to link + * returns 0 with success and -1 with error. + */ +static int add_link(struct sysfs_directory *sysdir, const unsigned char *path) +{ + struct sysfs_link *ln = NULL; + + ln = sysfs_open_link(path); + if (ln == NULL) { + dprintf("Error opening link %s\n", path); + return -1; + } + if (sysdir->links == NULL) + sysdir->links = dlist_new_with_delete + (sizeof(struct sysfs_link), sysfs_del_link); + dlist_unshift(sysdir->links, ln); + return 0; +} + +/** + * sysfs_read_dir_attributes: grabs attributes for the given directory * @sysdir: sysfs directory to open * returns 0 with success and -1 with error. */ -int sysfs_read_directory(struct sysfs_directory *sysdir) +int sysfs_read_dir_attributes(struct sysfs_directory *sysdir) { DIR *dir = NULL; struct dirent *dirent = NULL; struct stat astats; - struct sysfs_attribute *attr = NULL; - struct sysfs_directory *subdir = NULL; - struct sysfs_link *ln = NULL; unsigned char file_path[SYSFS_PATH_MAX]; int retval = 0; @@ -531,54 +662,52 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) dprintf("stat failed\n"); continue; } - if (S_ISREG(astats.st_mode)) { - attr = sysfs_open_attribute(file_path); - if (attr == NULL) { - dprintf("Error opening attribute %s\n", - file_path); - retval = -1; + if (S_ISREG(astats.st_mode)) + retval = add_attribute(sysdir, file_path); + } + closedir(dir); + return(retval); +} + +/** + * sysfs_read_dir_links: grabs links in a specific directory + * @sysdir: sysfs directory to read links + * returns 0 with success and -1 with error. + */ +int sysfs_read_dir_links(struct sysfs_directory *sysdir) +{ + DIR *dir = NULL; + struct dirent *dirent = NULL; + struct stat astats; + unsigned char file_path[SYSFS_PATH_MAX]; + int retval = 0; + + if (sysdir == NULL) { + errno = EINVAL; + return -1; + } + dir = opendir(sysdir->path); + if (dir == NULL) { + dprintf("Error opening directory %s\n", sysdir->path); + return -1; + } + while(((dirent = readdir(dir)) != NULL) && retval == 0) { + if (0 == strcmp(dirent->d_name, ".")) + continue; + if (0 == strcmp(dirent->d_name, "..")) + continue; + memset(file_path, 0, SYSFS_PATH_MAX); + strncpy(file_path, sysdir->path, sizeof(file_path)); + strncat(file_path, "/", sizeof(file_path)); + strncat(file_path, dirent->d_name, sizeof(file_path)); + if ((lstat(file_path, &astats)) != 0) { + dprintf("stat failed\n"); + continue; + } + if (S_ISLNK(astats.st_mode)) { + retval = add_link(sysdir, file_path); + if (retval != 0) break; - } - if (attr->method & SYSFS_METHOD_SHOW) { - if ((sysfs_read_attribute(attr)) != 0) { - dprintf("Error reading attribute %s\n", - file_path); - sysfs_close_attribute(attr); - continue; - } - } - - if (sysdir->attributes == NULL) { - sysdir->attributes = dlist_new_with_delete - (sizeof(struct sysfs_attribute), - sysfs_del_attribute); - } - dlist_unshift(sysdir->attributes, attr); - } else if (S_ISDIR(astats.st_mode)) { - subdir = sysfs_open_directory(file_path); - if (subdir == NULL) { - dprintf("Error opening directory %s\n", - file_path); - retval = -1; - break; - } - if (sysdir->subdirs == NULL) - sysdir->subdirs = dlist_new_with_delete - (sizeof(struct sysfs_directory), - sysfs_del_directory); - dlist_unshift(sysdir->subdirs, subdir); - } else if (S_ISLNK(astats.st_mode)) { - ln = sysfs_open_link(file_path); - if (ln == NULL) { - dprintf("Error opening link %s\n", file_path); - retval = -1; - break; - } - if (sysdir->links == NULL) - sysdir->links = dlist_new_with_delete - (sizeof(struct sysfs_link), - sysfs_del_link); - dlist_unshift(sysdir->links, ln); } } closedir(dir); @@ -586,7 +715,98 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) } /** - * sysfs_get_directory_attribute: retrieves attribute attrname + * sysfs_read_dir_subdirs: grabs subdirs in a specific directory + * @sysdir: sysfs directory to read links + * returns 0 with success and -1 with error. + */ +int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir) +{ + DIR *dir = NULL; + struct dirent *dirent = NULL; + struct stat astats; + unsigned char file_path[SYSFS_PATH_MAX]; + int retval = 0; + + if (sysdir == NULL) { + errno = EINVAL; + return -1; + } + dir = opendir(sysdir->path); + if (dir == NULL) { + dprintf("Error opening directory %s\n", sysdir->path); + return -1; + } + while(((dirent = readdir(dir)) != NULL) && retval == 0) { + if (0 == strcmp(dirent->d_name, ".")) + continue; + if (0 == strcmp(dirent->d_name, "..")) + continue; + memset(file_path, 0, SYSFS_PATH_MAX); + strncpy(file_path, sysdir->path, sizeof(file_path)); + strncat(file_path, "/", sizeof(file_path)); + strncat(file_path, dirent->d_name, sizeof(file_path)); + if ((lstat(file_path, &astats)) != 0) { + dprintf("stat failed\n"); + continue; + } + if (S_ISDIR(astats.st_mode)) + retval = add_subdirectory(sysdir, file_path); + } + closedir(dir); + return(retval); +} + +/** + * sysfs_read_directory: grabs attributes, links, and subdirectories + * @sysdir: sysfs directory to open + * returns 0 with success and -1 with error. + */ +int sysfs_read_directory(struct sysfs_directory *sysdir) +{ + DIR *dir = NULL; + struct dirent *dirent = NULL; + struct stat astats; + unsigned char file_path[SYSFS_PATH_MAX]; + int retval = 0; + + if (sysdir == NULL) { + errno = EINVAL; + return -1; + } + dir = opendir(sysdir->path); + if (dir == NULL) { + dprintf("Error opening directory %s\n", sysdir->path); + return -1; + } + while(((dirent = readdir(dir)) != NULL) && retval == 0) { + if (0 == strcmp(dirent->d_name, ".")) + continue; + if (0 == strcmp(dirent->d_name, "..")) + continue; + memset(file_path, 0, SYSFS_PATH_MAX); + strncpy(file_path, sysdir->path, sizeof(file_path)); + strncat(file_path, "/", sizeof(file_path)); + strncat(file_path, dirent->d_name, sizeof(file_path)); + if ((lstat(file_path, &astats)) != 0) { + dprintf("stat failed\n"); + continue; + } + if (S_ISDIR(astats.st_mode)) + retval = add_subdirectory(sysdir, file_path); + + else if (S_ISLNK(astats.st_mode)) + retval = add_link(sysdir, file_path); + + else if (S_ISREG(astats.st_mode)) + retval = add_attribute(sysdir, file_path); + } + closedir(dir); + return(retval); +} + +/** + * sysfs_get_directory_attribute: retrieves attribute attrname from current + * directory only * @dir: directory to retrieve attribute from * @attrname: name of attribute to look for * returns sysfs_attribute if found and NULL if not found @@ -594,27 +814,38 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) struct sysfs_attribute *sysfs_get_directory_attribute (struct sysfs_directory *dir, unsigned char *attrname) { - struct sysfs_directory *sdir = NULL; struct sysfs_attribute *attr = NULL; + unsigned char new_path[SYSFS_PATH_MAX]; if (dir == NULL || attrname == NULL) { errno = EINVAL; return NULL; } - - attr = (struct sysfs_attribute *)dlist_find_custom(dir->attributes, - attrname, dir_attribute_name_equal); - if (attr != NULL) + + if (dir->attributes == NULL) + if ((sysfs_read_dir_attributes(dir) != 0) + || (dir->attributes == NULL)) + return NULL; + + attr = (struct sysfs_attribute *)dlist_find_custom + (dir->attributes, attrname, dir_attribute_name_equal); + if (attr != NULL) { + /* + * don't read here since we would have read the attribute in + * in the routine that called this routine + */ return attr; - - if (dir->subdirs != NULL) { - dlist_for_each_data(dir->subdirs, sdir, - struct sysfs_directory) { - if (sdir->attributes == NULL) - continue; - attr = sysfs_get_directory_attribute(sdir, attrname); - if (attr != NULL) - return attr; + } else { + memset(new_path, 0, SYSFS_PATH_MAX); + strcpy(new_path, dir->path); + strcat(new_path, "/"); + strcat(new_path, attrname); + if ((sysfs_path_is_file(new_path)) == 0) { + if ((add_attribute(dir, new_path)) == 0) { + attr = (struct sysfs_attribute *)dlist_find_custom + (dir->attributes, attrname, dir_attribute_name_equal); + } + return attr; } } return NULL; @@ -633,6 +864,10 @@ struct sysfs_link *sysfs_get_directory_link errno = EINVAL; return NULL; } + if (dir->links == NULL) + if ((sysfs_read_dir_links(dir) != 0) || (dir->links == NULL)) + return NULL; + return (struct sysfs_link *)dlist_find_custom(dir->links, linkname, dir_link_name_equal); } @@ -648,10 +883,15 @@ struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir, { struct sysfs_directory *sub = NULL, *cursub = NULL; - if (dir == NULL || dir->subdirs == NULL || subname == NULL) { + if (dir == NULL || subname == NULL) { errno = EINVAL; return NULL; } + + if (dir->subdirs == NULL) + if (sysfs_read_dir_subdirs(dir) != 0) + return NULL; + sub = (struct sysfs_directory *)dlist_find_custom(dir->subdirs, subname, dir_subdir_name_equal); if (sub != NULL) @@ -660,8 +900,12 @@ struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir, if (dir->subdirs != NULL) { dlist_for_each_data(dir->subdirs, cursub, struct sysfs_directory) { - if (cursub->subdirs == NULL) - continue; + if (cursub->subdirs == NULL) { + if (sysfs_read_dir_subdirs(cursub) != 0) + continue; + if (cursub->subdirs == NULL) + continue; + } sub = sysfs_get_subdirectory(cursub, subname); if (sub != NULL) return sub; @@ -682,7 +926,7 @@ struct sysfs_link *sysfs_get_subdirectory_link(struct sysfs_directory *dir, struct sysfs_directory *cursub = NULL; struct sysfs_link *ln = NULL; - if (dir == NULL || dir->links == NULL || linkname == NULL) { + if (dir == NULL || linkname == NULL) { errno = EINVAL; return NULL; } @@ -691,14 +935,13 @@ struct sysfs_link *sysfs_get_subdirectory_link(struct sysfs_directory *dir, if (ln != NULL) return ln; - if (dir->subdirs == NULL) - return NULL; + if (dir->subdirs == NULL) + if (sysfs_read_dir_subdirs(dir) != 0) + return NULL; if (dir->subdirs != NULL) { dlist_for_each_data(dir->subdirs, cursub, struct sysfs_directory) { - if (cursub->subdirs == NULL) - continue; ln = sysfs_get_subdirectory_link(cursub, linkname); if (ln != NULL) return ln; diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 1877dbce0b..4372b19f10 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -23,36 +23,16 @@ #include "libsysfs.h" #include "sysfs.h" -static void sysfs_close_driver_by_name_dev(void *device) +static void sysfs_close_driver_device(void *device) { sysfs_close_device((struct sysfs_device *)device); } -/** - * sysfs_close_driver: closes and cleans up driver structure - * NOTE: This routine does not deallocate devices list - * @driver: driver to close - */ -void sysfs_close_driver(struct sysfs_driver *driver) -{ - if (driver != NULL) { - if (driver->devices != NULL) { - dlist_for_each(driver->devices) - dlist_shift(driver->devices); - free(driver->devices); - driver->devices = NULL; - } - if (driver->directory != NULL) - sysfs_close_directory(driver->directory); - free(driver); - } -} - /** - * sysfs_close_driver_by_name: closes driver and deletes device lists too + * sysfs_close_driver: closes driver and deletes device lists too * @driver: driver to close */ -void sysfs_close_driver_by_name(struct sysfs_driver *driver) +void sysfs_close_driver(struct sysfs_driver *driver) { if (driver != NULL) { if (driver->devices != NULL) @@ -63,6 +43,51 @@ void sysfs_close_driver_by_name(struct sysfs_driver *driver) } } +/** + * open_driver_dir: Open the sysfs_directory for this driver + * @driver: Driver whose directory to be opened + * Returns 0 on success and 1 on failure + */ +static int open_driver_dir(struct sysfs_driver *driver) +{ + if (driver == NULL) { + errno = EINVAL; + return 1; + } + if (driver->directory == NULL) { + driver->directory = sysfs_open_directory(driver->path); + if (driver->directory == NULL) { + dprintf("Error opening driver directory at %s\n", + driver->path); + return 1; + } + } + return 0; +} + +/** + * read_driver_dir: Read driver directory's subdirs and links + * @driver: Driver to read + * Returns 0 on success and 1 on failure + */ +static int read_driver_dir(struct sysfs_driver *driver) +{ + if (driver == NULL) { + errno = EINVAL; + return 1; + } + if (driver->directory == NULL) { + if ((open_driver_dir(driver)) == 1) + return 1; + } + if ((sysfs_read_directory(driver->directory)) != 0) { + dprintf("Error reading driver directory at %s\n", + driver->path); + return 1; + } + return 0; +} + /** * alloc_driver: allocates and initializes driver * returns struct sysfs_driver with success and NULL with error. @@ -80,31 +105,27 @@ static struct sysfs_driver *alloc_driver(void) struct sysfs_driver *sysfs_open_driver(const unsigned char *path) { struct sysfs_driver *driver = NULL; - struct sysfs_directory *sdir = NULL; if (path == NULL) { errno = EINVAL; return NULL; } - sdir = sysfs_open_directory(path); - if (sdir == NULL) { - dprintf("Error opening directory %s\n", path); - return NULL; - } - if ((sysfs_read_directory(sdir)) != 0) { - dprintf("Error reading directory %s\n", path); - sysfs_close_directory(sdir); + if ((sysfs_path_is_dir(path)) != 0) { + dprintf("Invalid path to driver: %s\n", path); return NULL; } driver = alloc_driver(); if (driver == NULL) { dprintf("Error allocating driver at %s\n", path); - sysfs_close_directory(sdir); return NULL; } - strcpy(driver->name, sdir->name); - driver->directory = sdir; - strcpy(driver->path, sdir->path); + if ((sysfs_get_name_from_path(path, driver->name, + SYSFS_NAME_LEN)) != 0) { + dprintf("Error getting driver name from path\n"); + free(driver); + return NULL; + } + strcpy(driver->path, path); return driver; } @@ -117,9 +138,32 @@ struct sysfs_driver *sysfs_open_driver(const unsigned char *path) */ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) { - if (driver == NULL || driver->directory == NULL) + if (driver == NULL) { + errno = EINVAL; return NULL; + } + if (driver->directory == NULL) { + if ((open_driver_dir(driver)) == 1) + return NULL; + } + if (driver->directory->attributes == NULL) { + if ((sysfs_read_dir_attributes(driver->directory)) != 0) { + dprintf("Error reading driver attributes\n"); + return NULL; + } + } else { + if ((sysfs_path_is_dir(driver->path)) != 0) { + dprintf("Driver at %s no longer exists\n", + driver->path); + return NULL; + } + if ((sysfs_refresh_attributes + (driver->directory->attributes)) != 0) { + dprintf("Error refreshing driver attributes\n"); + return NULL; + } + } return(driver->directory->attributes); } @@ -133,18 +177,20 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, const unsigned char *name) { struct sysfs_attribute *cur = NULL; + struct dlist *attrlist = NULL; - if (drv == NULL || drv->directory == NULL - || drv->directory->attributes == NULL || name == NULL) { + if (drv == NULL) { errno = EINVAL; return NULL; } - - cur = sysfs_get_directory_attribute(drv->directory, - (unsigned char *)name); - if (cur != NULL) - return cur; - + + attrlist = sysfs_get_driver_attributes(drv); + if (attrlist != NULL) { + cur = sysfs_get_directory_attribute(drv->directory, + (unsigned char *)name); + if (cur != NULL) + return cur; + } return NULL; } @@ -156,12 +202,95 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, */ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) { - if (driver == NULL || driver->directory == NULL) + if (driver == NULL) { + errno = EINVAL; return NULL; - + } + if (driver->directory == NULL) { + if ((open_driver_dir(driver)) == 1) + return NULL; + if ((read_driver_dir(driver)) != 0) + return NULL; + } return(driver->directory->links); } +/** + * sysfs_get_driver_devices: open up the list of devices this driver supports + * @driver: sysfs_driver for which devices are needed + * Returns dlist of devices on SUCCESS or NULL with ERROR + */ +struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) +{ + struct sysfs_link *curlink = NULL; + struct sysfs_device *device = NULL; + + if (driver == NULL) { + errno = EINVAL; + return NULL; + } + + if (driver->devices != NULL) + return (driver->devices); + + if (driver->directory == NULL) { + if ((open_driver_dir(driver)) == 1) + return NULL; + if ((read_driver_dir(driver)) != 0) + return NULL; + } + if (driver->directory->links != NULL) { + dlist_for_each_data(driver->directory->links, curlink, + struct sysfs_link) { + device = sysfs_open_device(curlink->target); + if (device == NULL) { + dprintf("Error opening device at %s\n", + curlink->target); + return NULL; + } + strcpy(device->driver_name, driver->name); + if (driver->devices == NULL) + driver->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_driver_device); + dlist_unshift(driver->devices, device); + } + } + return (driver->devices); +} + +/** + * sysfs_get_driver_device: looks up a device from a list of driver's devices + * and returns its sysfs_device corresponding to it + * @driver: sysfs_driver on which to search + * @name: name of the device to search + * Returns a sysfs_device if found, NULL otherwise + */ +struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver, + const unsigned char *name) +{ + struct sysfs_device *device = NULL; + struct dlist *devlist = NULL; + + if (driver == NULL || name == NULL) { + errno = EINVAL; + return NULL; + } + + if (driver->devices == NULL) { + devlist = sysfs_get_driver_devices(driver); + if (devlist == NULL) { + dprintf("Error getting driver devices\n"); + return NULL; + } + } + dlist_for_each_data(driver->devices, device, struct sysfs_device) { + if (!(strncmp(device->name, name, SYSFS_NAME_LEN))) + return device; + } + return NULL; +} + /** * get_driver_path: looks up the bus the driver is on and builds path to * the driver. @@ -171,8 +300,8 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) * @psize: size of "path" * Returns 0 on success and -1 on error */ -static int get_driver_path(const unsigned char *bus, const unsigned char *drv, - unsigned char *path, size_t psize) +static int get_driver_path(const unsigned char *bus, + const unsigned char *drv, unsigned char *path, size_t psize) { if (bus == NULL || drv == NULL || path == NULL) { errno = EINVAL; @@ -187,69 +316,13 @@ static int get_driver_path(const unsigned char *bus, const unsigned char *drv, strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, bus); - strcat(path, SYSFS_DRIVERS_DIR); + strcat(path, "/"); + strcat(path, SYSFS_DRIVERS_NAME); strcat(path, "/"); strcat(path, drv); return 0; } -/** - * sysfs_open_driver_by_name: open a driver by name and return the bus - * the driver is on. - * @drv_name: driver to open - * @bus: the driver bus - * @bsize: size of bus buffer - * returns struct sysfs_driver if found, NULL otherwise - * NOTE: - * 1. Need to call sysfs_close_driver_by_name to free up memory - * 2. Bus the driver is registered with must be supplied. - * Use sysfs_find_driver_bus() to obtain the bus name - */ -struct sysfs_driver *sysfs_open_driver_by_name(const unsigned char *drv_name, - const unsigned char *bus, size_t bsize) -{ - struct sysfs_driver *driver = NULL; - struct sysfs_device *device = NULL; - struct sysfs_link *curlink = NULL; - unsigned char path[SYSFS_PATH_MAX]; - - if (drv_name == NULL || bus == NULL) { - errno = EINVAL; - return NULL; - } - - memset(path, 0, SYSFS_PATH_MAX); - if (get_driver_path(bus, drv_name, path, SYSFS_PATH_MAX) != 0) { - dprintf("Error getting to driver %s\n", drv_name); - return NULL; - } - driver = sysfs_open_driver(path); - if (driver == NULL) { - dprintf("Could not open driver %s\n", drv_name); - return NULL; - } - if (driver->directory->links != NULL) { - dlist_for_each_data(driver->directory->links, curlink, - struct sysfs_link) { - device = sysfs_open_device(curlink->target); - if (device == NULL) { - dprintf("Error opening device at %s\n", - curlink->target); - sysfs_close_driver_by_name(driver); - return NULL; - } - strcpy(device->driver_name, drv_name); - if (driver->devices == NULL) - driver->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_driver_by_name_dev); - dlist_unshift(driver->devices, device); - } - } - return driver; -} - - /** * sysfs_open_driver_attr: read the user supplied driver attribute * @bus: bus on which to look diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 627e618dce..c2ce13433d 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -280,7 +280,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) * name requested here is "class", verify if "block" is supported on * this system and return the same. */ - if (strcmp(name, SYSFS_CLASS_DIR) == 0) { + if (strcmp(name, SYSFS_CLASS_NAME) == 0) { c = strstr(sysfs_path, SYSFS_CLASS_NAME); if (c == NULL) goto out; @@ -325,7 +325,8 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) strcat(sysfs_path, SYSFS_BUS_NAME); strcat(sysfs_path, "/"); strcat(sysfs_path, name); - strcat(sysfs_path, SYSFS_DEVICES_DIR); + strcat(sysfs_path, "/"); + strcat(sysfs_path, SYSFS_DEVICES_NAME); dir = sysfs_open_directory(sysfs_path); if (dir == NULL) { dprintf("Error opening sysfs_directory at %s\n", sysfs_path); @@ -358,3 +359,71 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) return list; } +/** + * sysfs_path_is_dir: Check if the path supplied points to a directory + * @path: path to validate + * Returns 0 if path points to dir, 1 otherwise + */ +int sysfs_path_is_dir(const unsigned char *path) +{ + struct stat astats; + + if (path == NULL) { + errno = EINVAL; + return 1; + } + if ((lstat(path, &astats)) != 0) { + dprintf("stat() failed\n"); + return 1; + } + if (S_ISDIR(astats.st_mode)) + return 0; + + return 1; +} + +/** + * sysfs_path_is_link: Check if the path supplied points to a link + * @path: path to validate + * Returns 0 if path points to link, 1 otherwise + */ +int sysfs_path_is_link(const unsigned char *path) +{ + struct stat astats; + + if (path == NULL) { + errno = EINVAL; + return 1; + } + if ((lstat(path, &astats)) != 0) { + dprintf("stat() failed\n"); + return 1; + } + if (S_ISLNK(astats.st_mode)) + return 0; + + return 1; +} + +/** + * sysfs_path_is_file: Check if the path supplied points to a file + * @path: path to validate + * Returns 0 if path points to file, 1 otherwise + */ +int sysfs_path_is_file(const unsigned char *path) +{ + struct stat astats; + + if (path == NULL) { + errno = EINVAL; + return 1; + } + if ((lstat(path, &astats)) != 0) { + dprintf("stat() failed\n"); + return 1; + } + if (S_ISREG(astats.st_mode)) + return 0; + + return 1; +} diff --git a/namedev.c b/namedev.c index 75e4d22370..633a7bf0da 100644 --- a/namedev.c +++ b/namedev.c @@ -552,37 +552,29 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud struct sysfs_device *sysfs_device = NULL; struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; - char *temp = NULL; struct perm_device *perm; udev->mode = 0; /* find the sysfs_device for this class device */ /* Wouldn't it really be nice if libsysfs could do this for us? */ - if (class_dev->sysdevice) { - sysfs_device = class_dev->sysdevice; - } else { + sysfs_device = sysfs_get_classdev_device(class_dev); + if (sysfs_device == NULL) { /* bah, let's go backwards up a level to see if the device is there, * as block partitions don't point to the physical device. Need to fix that * up in the kernel... */ - if (strstr(class_dev->path, "block")) { + if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { dbg("looking at block device"); if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - char path[SYSFS_PATH_MAX]; - dbg("really is a partition"); - strfieldcpy(path, class_dev->path); - temp = strrchr(path, '/'); - *temp = 0x00; - dbg("looking for a class device at '%s'", path); - class_dev_parent = sysfs_open_class_device(path); + class_dev_parent = sysfs_get_classdev_parent + (class_dev); if (class_dev_parent == NULL) { - dbg("sysfs_open_class_device at '%s' failed", path); + dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); } else { dbg("class_dev_parent->name='%s'", class_dev_parent->name); - if (class_dev_parent->sysdevice) - sysfs_device = class_dev_parent->sysdevice; + sysfs_device = sysfs_get_classdev_device(class_dev_parent); } } } @@ -643,9 +635,6 @@ done: dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); - if (class_dev_parent) - sysfs_close_class_device(class_dev_parent); - return 0; } diff --git a/udev-add.c b/udev-add.c index e64a845c7e..33ee633fd8 100644 --- a/udev-add.c +++ b/udev-add.c @@ -54,14 +54,14 @@ static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev) { int retval = -ENODEV; - char *dev; + struct sysfs_attribute *attr = NULL; - dev = sysfs_get_value_from_attributes(class_dev->directory->attributes, "dev"); - if (dev == NULL) + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) goto exit; - dbg("dev='%s'", dev); + dbg("dev='%s'", attr->value); - if (sscanf(dev, "%u:%u", &udev->major, &udev->minor) != 2) + if (sscanf(attr->value, "%u:%u", &udev->major, &udev->minor) != 2) goto exit; dbg("found major=%d, minor=%d", udev->major, udev->minor); From d870b833e9c1f7fb49f0ecf659f53e7f1cf5324e Mon Sep 17 00:00:00 2001 From: "eike-hotplug@sf-tec.de" Date: Mon, 15 Dec 2003 22:22:30 -0800 Subject: [PATCH 0282/4284] [PATCH] add init.d/udev to the spec file add /etc/init.d/udev to the SPEC-File and this way to the RPM --- udev.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.spec b/udev.spec index a005b12dfa..bd455ef2b1 100644 --- a/udev.spec +++ b/udev.spec @@ -36,6 +36,7 @@ rm -rf $RPM_BUILD_ROOT %attr(0644,root,root) /etc/udev/udev.rules %attr(0644,root,root) /etc/udev/udev.permissions %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug +%attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev.8* %changelog From dbc9b3f3a20520db6fcf791a3663ab943fc193d9 Mon Sep 17 00:00:00 2001 From: "eike-hotplug@sf-tec.de" Date: Mon, 15 Dec 2003 22:22:34 -0800 Subject: [PATCH 0283/4284] [PATCH] add init.d/udev to "make install" adds /etc/init.d/udev to "make install" --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 9415e1ec97..bd9a9035ee 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ mandir = ${prefix}/usr/share/man hotplugdir = ${etcdir}/hotplug.d/default dbusdir = ${etcdir}/dbus-1/system.d configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -278,6 +279,7 @@ install: install-dbus-policy all $(GEN_CONFIGS) $(INSTALL) -d $(DESTDIR)$(configdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) + $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir) $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir) From 5a3ee97760a8882e22435ca6424c54af8d8782be Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 15 Dec 2003 22:25:03 -0800 Subject: [PATCH 0284/4284] [PATCH] Add restart target to the etc/init.d/udev script Change made by Rolf Eike Beer --- etc/init.d/udev | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/etc/init.d/udev b/etc/init.d/udev index 5c09afd205..36ef2dafda 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -64,11 +64,15 @@ case "$1" in echo "the udev device node directory does not exist" fi ;; - restart|reload) + restart) + $0 stop + $0 start + ;; + reload) # nothing to do here ;; *) - echo "Usage: $0 {start|stop|status}" + echo "Usage: $0 {start|stop|status|restart}" exit 1 esac From 2052464275b50f27cc563aaee24aadd791a9d8ca Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 15 Dec 2003 22:38:18 -0800 Subject: [PATCH 0285/4284] [PATCH] remove '\n' from end of callout return remove possible newline at end of callout output, for easier matching with ID= --- namedev.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/namedev.c b/namedev.c index 633a7bf0da..74a411799b 100644 --- a/namedev.c +++ b/namedev.c @@ -264,7 +264,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) pid_t pid; int value_set = 0; char buffer[256]; - char *arg; + char *pos; char *args[CALLOUT_MAXARG]; int i; @@ -286,9 +286,9 @@ static int exec_callout(struct config_device *dev, char *value, int len) dup(fds[1]); /* dup write side of pipe to STDOUT */ if (strchr(dev->exec_program, ' ')) { /* callout with arguments */ - arg = dev->exec_program; + pos = dev->exec_program; for (i=0; i < CALLOUT_MAXARG-1; i++) { - args[i] = strsep(&arg, " "); + args[i] = strsep(&pos, " "); if (args[i] == NULL) break; } @@ -324,9 +324,12 @@ static int exec_callout(struct config_device *dev, char *value, int len) } else { value_set = 1; strncpy(value, buffer, len); + pos = value + strlen(value)-1; + if (pos[0] == '\n') + pos[0] = '\0'; + dbg("callout returned '%s'", value); } } - dbg("callout returned '%s'", value); close(fds[0]); res = wait(&status); if (res < 0) { From b1c5e3339deb97f4a30053111b444489a3bc9562 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 15 Dec 2003 22:54:38 -0800 Subject: [PATCH 0286/4284] [PATCH] get part of callout return string Try this patch if you like, to get special parts of the callout output. This beast works now: CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", ID="node *", NAME="%1c", SYMLINK="%2c %3c" The callout returned string is separated by spaces and is addressed by the "len" value of the 'c' format char. Since we support symlinks, this my be useful for other uses of callout too. introduce 'len number' for format chars the first use is 'c'-the callout return to select a part of the output string like: CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", ID="node *", NAME="%1c", SYMLINK="%2c %3c" (note: first part is requested by len=1, len=0 will return the whole string) add a test to udev-test.pl --- namedev.c | 41 ++++++++++++++++++++++++++++++++++++----- test/udev-test.pl | 9 +++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/namedev.c b/namedev.c index 74a411799b..212d6bb68d 100644 --- a/namedev.c +++ b/namedev.c @@ -200,15 +200,30 @@ static void build_kernel_number(struct sysfs_class_device *class_dev, struct ude static void apply_format(struct udevice *udev, unsigned char *string) { char name[NAME_SIZE]; + char temp[NAME_SIZE]; + char *tail; char *pos; + char *pos2; + char *pos3; + int num; while (1) { + num = 0; pos = strchr(string, '%'); if (pos) { - strfieldcpy(name, pos+2); - *pos = 0x00; - switch (pos[1]) { + *pos = '\0'; + tail = pos+1; + if (isdigit(tail[0])) { + num = (int) strtoul(&pos[1], &tail, 10); + if (tail == NULL) { + dbg("format parsing error '%s'", pos+1); + break; + } + } + strfieldcpy(name, tail+1); + + switch (tail[0]) { case 'b': if (strlen(udev->bus_id) == 0) break; @@ -241,8 +256,24 @@ static void apply_format(struct udevice *udev, unsigned char *string) case 'c': if (strlen(udev->callout_value) == 0) break; - strcat(pos, udev->callout_value); - dbg("substitute callout output '%s'", udev->callout_value); + if (num) { + /* get part of return string */ + strncpy(temp, udev->callout_value, sizeof(temp)); + pos2 = temp; + while (num) { + num--; + pos3 = strsep(&pos2, " "); + if (pos3 == NULL) { + dbg("requested part of callout string not found"); + break; + } + } + strcat(pos, pos3); + dbg("substitute partial callout output '%s'", pos3); + } else { + strcat(pos, udev->callout_value); + dbg("substitute callout output '%s'", udev->callout_value); + } break; default: dbg("unknown substitution type '%%%c'", pos[1]); diff --git a/test/udev-test.pl b/test/udev-test.pl index 3dfbaa2530..1a35e3da82 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -150,6 +150,15 @@ EOF expected => "test-0:0:0:0" , conf => < "callout program substitution (numbered part of)", + subsys => "block", + devpath => "block/sda/sda3", + expected => "link1" , + conf => < Date: Mon, 15 Dec 2003 23:25:51 -0800 Subject: [PATCH 0287/4284] [PATCH] more extras/multipath changes * Make the HW-specific get_unique_id switch pretty * Prepare to field-test by whitelisting all known fibre array, try to fetch WWID from the standard EVPD 0x83 off 8 for everyone ... we will learn from feedback :) Could you drop a note with the udev-009 release-notes asking for testing this WWID fetching thing ? --- extras/multipath/main.c | 42 +++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 6b1c37cd95..9402888c58 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -160,8 +160,11 @@ get_serial (int fd, char * str) */ /* hardware vendor specifics : add support for new models below */ + +/* this one get EVPD page 0x83 off 8 */ +/* tested ok with StorageWorks */ static int -get_storageworks_wwid(int fd, char *str) +get_evpd_wwid(int fd, char *str) { char buff[64]; @@ -176,12 +179,39 @@ get_storageworks_wwid(int fd, char *str) static int get_unique_id(int fd, struct path * mypath) { - if (strncmp(mypath->product_id, "HSV110 (C)COMPAQ", 16) == 0 || - strncmp(mypath->product_id, "HSG80 ", 16) == 0) { - get_storageworks_wwid(fd, mypath->wwid); - return 0; - } + int i; + static struct { + char * vendor; + char * product; + int (*getuid) (int fd, char * wwid); + } wlist[] = { + {"COMPAQ ", "HSV110 (C)COMPAQ", &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 ", &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 VOLUME ", &get_evpd_wwid}, + {"DEC ", "HSG80 ", &get_evpd_wwid}, + {"HP ", "HSV100 ", &get_evpd_wwid}, + {"HP ", "A6189A ", &get_evpd_wwid}, + {"HP ", "OPEN- ", &get_evpd_wwid}, + {"DDN ", "SAN DataDirector", &get_evpd_wwid}, + {"FSC ", "CentricStor ", &get_evpd_wwid}, + {"HITACHI ", "DF400 ", &get_evpd_wwid}, + {"HITACHI ", "DF500 ", &get_evpd_wwid}, + {"HITACHI ", "DF600 ", &get_evpd_wwid}, + {"IBM ", "ProFibre 4000R ", &get_evpd_wwid}, + {"SGI ", "TP9100 ", &get_evpd_wwid}, + {"SGI ", "TP9300 ", &get_evpd_wwid}, + {"SGI ", "TP9400 ", &get_evpd_wwid}, + {"SGI ", "TP9500 ", &get_evpd_wwid}, + {NULL, NULL, NULL}, + }; + for (i = 0; wlist[i].vendor; i++) { + if (strncmp(mypath->vendor_id, wlist[i].vendor, 8) == 0 && + strncmp(mypath->product_id, wlist[i].product, 16) == 0) { + wlist[i].getuid(fd, mypath->wwid); + return 0; + } + } return 1; } From 316c51507724406f2ded06d067f55e867df90b15 Mon Sep 17 00:00:00 2001 From: "rml@ximian.com" Date: Tue, 16 Dec 2003 23:30:15 -0800 Subject: [PATCH 0288/4284] [PATCH] install initscript in udev rpm Attached patch installs the initscript via 'make install' and adds it to the RPM package. The RPM script then runs chkconfig(8) to setup the initscript to run at the appropriate runlevels. --- Makefile | 1 + udev.spec | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/Makefile b/Makefile index bd9a9035ee..4a545db9c4 100644 --- a/Makefile +++ b/Makefile @@ -297,6 +297,7 @@ uninstall: uninstall-dbus-policy - rm $(configdir)/udev.permissions - rm $(configdir)/udev.rules - rm $(configdir)/udev.conf + - rm $(initdir)/udev - rm $(mandir)/man8/udev.8 - rm $(sbindir)/$(ROOT) - rmdir $(hotplugdir) diff --git a/udev.spec b/udev.spec index bd455ef2b1..516239bc6d 100644 --- a/udev.spec +++ b/udev.spec @@ -23,6 +23,9 @@ make CC="gcc $RPM_OPT_FLAGS" %install make DESTDIR=$RPM_BUILD_ROOT install +%post +/sbin/chkconfig --add udev + %clean rm -rf $RPM_BUILD_ROOT @@ -40,6 +43,9 @@ rm -rf $RPM_BUILD_ROOT %attr(0644,root,root) %{_mandir}/man8/udev.8* %changelog +* Tue Dec 16 2003 Robert Love +- install the initscript and run chkconfig on it + * Tue Nov 2 2003 Greg Kroah-Hartman - changes due to config file name changes From 600ee7f73e5381764803725e68a0f953bd2f46fd Mon Sep 17 00:00:00 2001 From: "rml@ximian.com" Date: Tue, 16 Dec 2003 23:31:16 -0800 Subject: [PATCH 0289/4284] [PATCH] remove udev from runlevels on uninstall I guess we should run 'chkconfig --del udev' on removal to clear out the now-stale udev entries, if any. --- udev.spec | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/udev.spec b/udev.spec index 516239bc6d..3f71e1452c 100644 --- a/udev.spec +++ b/udev.spec @@ -26,6 +26,11 @@ make DESTDIR=$RPM_BUILD_ROOT install %post /sbin/chkconfig --add udev +%postun +if [ $1 = 0 ]; then + /sbin/chkconfig --del udev +fi + %clean rm -rf $RPM_BUILD_ROOT From d94df232423870641132b307d74281f692219730 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 16 Dec 2003 23:36:19 -0800 Subject: [PATCH 0290/4284] [PATCH] don't rely on field order in namedev_parse o change the parsing to get a key from the rule and sort it into our list of known keys instead of expecting a special order o the key to match a sysfs file must be prependend by 'SYSFS_' now to match with the new parsing. (The config must be changed, but it's a bit more descriptive too.) o put names of fields in define's, like the name of the methods o update all tests and the man page --- namedev.h | 10 ++ namedev_parse.c | 289 +++++++++++++++++++--------------------------- test/label_test | 2 +- test/udev-test.pl | 22 ++-- udev.8 | 11 +- udev.rules.demo | 4 +- 6 files changed, 145 insertions(+), 193 deletions(-) diff --git a/namedev.h b/namedev.h index 39cf3ae641..69c488936d 100644 --- a/namedev.h +++ b/namedev.h @@ -49,6 +49,16 @@ enum config_type { #define TYPE_TOPOLOGY "TOPOLOGY" #define TYPE_REPLACE "REPLACE" #define TYPE_CALLOUT "CALLOUT" + +#define FIELD_BUS "BUS" +#define FIELD_ID "ID" +#define FIELD_SYSFS "SYSFS_" +#define FIELD_PLACE "PLACE" +#define FIELD_PROGRAM "PROGRAM" +#define FIELD_KERNEL "KERNEL" +#define FIELD_NAME "NAME" +#define FIELD_SYMLINK "SYMLINK" + #define CALLOUT_MAXARG 8 struct config_device { diff --git a/namedev_parse.c b/namedev_parse.c index b5d0d64b9d..3578058a76 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -45,7 +45,7 @@ int get_pair(char **orig_string, char **left, char **right) return -ENODEV; /* eat any whitespace */ - while (isspace(*string)) + while (isspace(*string) || *string == ',') ++string; /* split based on '=' */ @@ -71,19 +71,6 @@ int get_pair(char **orig_string, char **left, char **right) return 0; } -static int get_value(const char *left, char **orig_string, char **ret_string) -{ - int retval; - char *left_string; - - retval = get_pair(orig_string, &left_string, ret_string); - if (retval) - return retval; - if (strcasecmp(left_string, left) != 0) - return -ENODEV; - return 0; -} - void dump_config_dev(struct config_device *dev) { switch (dev->type) { @@ -169,13 +156,8 @@ int namedev_init_rules(void) if (temp == NULL) goto exit; lineno++; - dbg_parse("read '%s'", temp); - /* eat the whitespace at the beginning of the line */ - while (isspace(*temp)) - ++temp; - /* empty line? */ if (*temp == 0x00) continue; @@ -184,199 +166,160 @@ int namedev_init_rules(void) if (*temp == COMMENT_CHARACTER) continue; + /* eat the whitespace */ + while (isspace(*temp)) + ++temp; + memset(&dev, 0x00, sizeof(struct config_device)); - /* parse the line */ + /* get the method */ temp2 = strsep(&temp, ","); + if (strcasecmp(temp2, TYPE_LABEL) == 0) { - /* label type */ dev.type = LABEL; + goto keys; + } - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); + if (strcasecmp(temp2, TYPE_NUMBER) == 0) { + dev.type = NUMBER; + goto keys; + } - /* file="value" */ - temp2 = strsep(&temp, ","); + if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { + dev.type = TOPOLOGY; + goto keys; + } + + if (strcasecmp(temp2, TYPE_REPLACE) == 0) { + dev.type = REPLACE; + goto keys; + } + + if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { + dev.type = CALLOUT; + goto keys; + } + + dbg_parse("unknown type of method '%s'", temp2); + goto error; +keys: + /* get all known keys */ + while (1) { retval = get_pair(&temp, &temp2, &temp3); if (retval) break; - strfieldcpy(dev.sysfs_file, temp2); - strfieldcpy(dev.sysfs_value, temp3); - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); + if (strcasecmp(temp2, FIELD_BUS) == 0) { + strfieldcpy(dev.bus, temp3); + continue; + } - /* SYMLINK="name" */ - temp2 = strsep(&temp, ","); - retval = get_value("SYMLINK", &temp, &temp3); - if (retval == 0) + if (strcasecmp(temp2, FIELD_ID) == 0) { + strfieldcpy(dev.id, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_PLACE) == 0) { + strfieldcpy(dev.place, temp3); + continue; + } + + if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) { + /* remove prepended 'SYSFS_' */ + strfieldcpy(dev.sysfs_file, temp2 + sizeof(FIELD_SYSFS)-1); + strfieldcpy(dev.sysfs_value, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_KERNEL) == 0) { + strfieldcpy(dev.kernel_name, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { + strfieldcpy(dev.exec_program, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_NAME) == 0) { + strfieldcpy(dev.name, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_SYMLINK) == 0) { strfieldcpy(dev.symlink, temp3); + continue; + } + dbg_parse("unknown type of field '%s'", temp2); + } + + /* check presence of keys according to method type */ + switch (dev.type) { + case LABEL: dbg_parse("LABEL name='%s', bus='%s', " "sysfs_file='%s', sysfs_value='%s', symlink='%s'", dev.name, dev.bus, dev.sysfs_file, dev.sysfs_value, dev.symlink); - } - - if (strcasecmp(temp2, TYPE_NUMBER) == 0) { - /* number type */ - dev.type = NUMBER; - - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); - - /* ID="id" */ - temp2 = strsep(&temp, ","); - retval = get_value("ID", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.id, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - - /* SYMLINK="name" */ - temp2 = strsep(&temp, ","); - retval = get_value("SYMLINK", &temp, &temp3); - if (retval == 0) - strfieldcpy(dev.symlink, temp3); - + if ((*dev.name == '\0') || + (*dev.bus == '\0') || + (*dev.sysfs_file == '\0') || + (*dev.sysfs_value == '\0')) + goto error; + break; + case NUMBER: dbg_parse("NUMBER name='%s', bus='%s', id='%s', symlink='%s'", dev.name, dev.bus, dev.id, dev.symlink); - } - - if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { - /* number type */ - dev.type = TOPOLOGY; - - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); - - /* PLACE="place" */ - temp2 = strsep(&temp, ","); - retval = get_value("PLACE", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.place, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - - /* SYMLINK="name" */ - temp2 = strsep(&temp, ","); - retval = get_value("SYMLINK", &temp, &temp3); - if (retval == 0) - strfieldcpy(dev.symlink, temp3); - + if ((*dev.name == '\0') || + (*dev.bus == '\0') || + (*dev.id == '\0')) + goto error; + break; + case TOPOLOGY: dbg_parse("TOPOLOGY name='%s', bus='%s', " "place='%s', symlink='%s'", dev.name, dev.bus, dev.place, dev.symlink); - } - - if (strcasecmp(temp2, TYPE_REPLACE) == 0) { - /* number type */ - dev.type = REPLACE; - - /* KERNEL="kernel_name" */ - retval = get_value("KERNEL", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.kernel_name, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - - /* SYMLINK="name" */ - temp2 = strsep(&temp, ","); - retval = get_value("SYMLINK", &temp, &temp3); - if (retval == 0) - strfieldcpy(dev.symlink, temp3); - + if ((*dev.name == '\0') || + (*dev.bus == '\0') || + (*dev.place == '\0')) + goto error; + break; + case REPLACE: dbg_parse("REPLACE name='%s', kernel_name='%s', symlink='%s'", dev.name, dev.kernel_name, dev.symlink); - } - - if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { - /* number type */ - dev.type = CALLOUT; - - /* BUS="bus" */ - retval = get_value("BUS", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.bus, temp3); - - /* PROGRAM="executable" */ - temp2 = strsep(&temp, ","); - retval = get_value("PROGRAM", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.exec_program, temp3); - - /* ID="id" */ - temp2 = strsep(&temp, ","); - retval = get_value("ID", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.id, temp3); - - /* NAME="new_name" */ - temp2 = strsep(&temp, ","); - retval = get_value("NAME", &temp, &temp3); - if (retval) - break; - strfieldcpy(dev.name, temp3); - - /* SYMLINK="name" */ - temp2 = strsep(&temp, ","); - retval = get_value("SYMLINK", &temp, &temp3); - if (retval == 0) - strfieldcpy(dev.symlink, temp3); - + if ((*dev.name == '\0') || + (*dev.kernel_name == '\0')) + goto error; + break; + case CALLOUT: dbg_parse("CALLOUT name='%s', bus='%s', program='%s', " "id='%s', symlink='%s'", dev.name, dev.bus, dev.exec_program, dev.id, dev.symlink); + if ((*dev.name == '\0') || + (*dev.bus == '\0') || + (*dev.id == '\0') || + (*dev.exec_program == '\0')) + goto error; + break; + default: + dbg_parse("xxx default method"); + goto error; } retval = add_config_dev(&dev); if (retval) { dbg("add_config_dev returned with error %d", retval); - goto exit; + continue; } } - dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_rules_filename, - lineno, temp - line, temp); +error: + dbg_parse("%s:%d:%Zd: field missing or parse error", udev_rules_filename, + lineno, temp - line); exit: fclose(fd); return retval; -} - +} int namedev_init_permissions(void) { diff --git a/test/label_test b/test/label_test index fb3fa2359f..09ccab366e 100644 --- a/test/label_test +++ b/test/label_test @@ -8,7 +8,7 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -LABEL, BUS="scsi", vendor="IBM-ESXS", NAME="boot_disk%n" +LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n" EOF cat > $CONFIG << EOF diff --git a/test/udev-test.pl b/test/udev-test.pl index 1a35e3da82..08b99f041f 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -38,7 +38,7 @@ my @tests = ( devpath => "block/sda", expected => "boot_disk" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda", expected => "lun0/disc" , conf => < "block/sda/sda2", expected => "lun0/part2" , conf => < "block/sda/sda2", expected => "1/2/a/b/symlink" , conf => < "block/sda/sda2", expected => "1/2/symlink" , conf => < "block/sda/sda2", expected => "1/2/c/d/symlink" , conf => < Date: Tue, 16 Dec 2003 23:39:44 -0800 Subject: [PATCH 0291/4284] [PATCH] some cleanups due to the need for LABEL rules to use "SYSFS_" now. --- udev.8 | 2 +- udev.rules | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/udev.8 b/udev.8 index 08f12908b5..f26beb4b9d 100644 --- a/udev.8 +++ b/udev.8 @@ -178,7 +178,7 @@ TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" REPLACE, KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" # multiple USB webcams with symlinks to be called webcam0, webcam1, ... -LABEL, BUS="usb", model="WebCam V3", NAME="video%n", SYMLINK="webcam%n" +LABEL, BUS="usb", SYSFS_model="WebCam V3", NAME="video%n", SYMLINK="webcam%n" .fi .P Permissions and ownership for the created device files may specified at diff --git a/udev.rules b/udev.rules index e497aed05b..618737ffd8 100644 --- a/udev.rules +++ b/udev.rules @@ -16,26 +16,26 @@ CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" # A usb camera. -LABEL, BUS="usb", vendor="FUJIFILM", NAME="camera%n" +LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", NAME="camera%n" # USB Epson printer to be called lp_epson -LABEL, BUS="usb", serial="HXOLL0012202323480", NAME="lp_epson" +LABEL, BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -LABEL, BUS="usb", serial="W09090207101241330", NAME="lp_hp" +LABEL, BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card -NUMBER, BUS="pci", id="00:0b.0", NAME="dsp" +NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" # sound card with PCI bus id 00:07.1 to be the second sound card -NUMBER, BUS="pci", id="00:07.1", NAME="dsp1" +NUMBER, BUS="pci", ID="00:07.1", NAME="dsp1" # USB mouse plugged into the third port of the first hub to be called mouse0 -TOPOLOGY, BUS="usb", place="1.3", NAME="mouse0" +TOPOLOGY, BUS="usb", PLACE="1.3", NAME="mouse0" # USB tablet plugged into the third port of the second hub to be called mouse1 -TOPOLOGY, BUS="usb", place="2.3", NAME="mouse1" -TOPOLOGY, BUS="usb", place="2.4", NAME="mouse2" +TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" +TOPOLOGY, BUS="usb", PLACE="2.4", NAME="mouse2" # ttyUSB1 should always be called visor REPLACE, KERNEL="ttyUSB1", NAME="visor" From 666269480900dd8d099b9e188c16acc9f7f31ee5 Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Tue, 16 Dec 2003 23:41:59 -0800 Subject: [PATCH 0292/4284] [PATCH] dump latest klibc into the udev build tree KLIBC is used as an internal makefile variable, it expands to either true or false right now. udev should use something else than KLIBC to allow build against the latest and greatest klibc version. --- Makefile | 12 ++++++------ README | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 4a545db9c4..3653595b06 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DEBUG = false # Set the following to `true' to make udev emit a D-BUS signal when a # new node is created. -DBUS = false +USE_DBUS = false ROOT = udev @@ -57,7 +57,7 @@ udevdir = ${prefix}/udev # Comment out this line to build with something other # than the local version of klibc -#KLIBC = true +#USE_KLIBC = true # If you are running a cross compiler, you may want to set this # to something more interesting, like "arm-linux-". I you want @@ -116,7 +116,7 @@ endif # If we are using our version of klibc, then we need to build and link it. # Otherwise, use glibc and link statically. -ifeq ($(strip $(KLIBC)),true) +ifeq ($(strip $(USE_KLIBC)),true) KLIBC_BASE = $(PWD)/klibc KLIBC_DIR = $(KLIBC_BASE)/klibc INCLUDE_DIR := $(KLIBC_DIR)/include @@ -180,11 +180,11 @@ OBJS = udev.o \ $(SYSFS) \ $(TDB) -ifeq ($(strip $(KLIBC)),true) +ifeq ($(strip $(USE_KLIBC)),true) OBJS += klibc_fixups.o endif -ifeq ($(DBUS), true) +ifeq ($(USE_DBUS), true) CFLAGS += -DUSE_DBUS CFLAGS += $(shell pkg-config --cflags dbus-1) LDFLAGS += $(shell pkg-config --libs dbus-1) @@ -261,7 +261,7 @@ small_release: $(DISTFILES) clean @echo "Built $(RELEASE_NAME).tar.gz" -ifeq ($(DBUS), true) +ifeq ($(USE_DBUS), true) install-dbus-policy: $(INSTALL) -d $(DESTDIR)$(dbusdir) $(INSTALL_DATA) udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) diff --git a/README b/README index 94a397936e..dab0ab4197 100644 --- a/README +++ b/README @@ -32,18 +32,18 @@ To use: installed into. This works just like the 'configure --prefix' script does. Default value is ''. Only override this if you really know what you are doing. - KLIBC - if set to 'true', udev is built and linked against the included + USE_KLIBC - if set to 'true', udev is built and linked against the included version of klibc. Default value is 'false'. DEBUG - if set to 'true', debugging messages will be sent to the syslog as udev is run. Default value is 'false'. - DBUS - if set to 'true', DBUS messages will be sent everytime udev + USE_DBUS - if set to 'true', DBUS messages will be sent everytime udev creates or removes a device node. This requires that DBUS development headers and libraries be present on your system to build properly. Default value is 'false'. So, if you want to build udev using klibc with debugging messages, you would do: - make KLIBC=true DEBUG=true + make USE_KLIBC=true DEBUG=true - Install the project: From 470e365d5338fbdcc8019d790c97ed1229de0196 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 00:04:23 -0800 Subject: [PATCH 0293/4284] [PATCH] update the FAQ with info about bad modprobe events from the devfs scheme... --- FAQ | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/FAQ b/FAQ index d9aebde0da..1f7ceb0dd3 100644 --- a/FAQ +++ b/FAQ @@ -44,6 +44,12 @@ A: Such a functionality isn't needed on a properly configured system. All 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. A configuration file needs to be created to map the kernel default names From c63a27273bffd268dfedc492399f3be71bad5dd4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 00:04:50 -0800 Subject: [PATCH 0294/4284] [PATCH] add mol permissions to the debian permissions file. Info from Mathieu Segaud --- udev.permissions.debian | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.permissions.debian b/udev.permissions.debian index a5e40f89e2..b4ddacfcdd 100644 --- a/udev.permissions.debian +++ b/udev.permissions.debian @@ -61,6 +61,7 @@ video*:root:video:0660 radio*:root:video:0660 vbi*:root:video:0660 vtx*:root:video:0660 +mol:root:root:0600 # block devices From 3555a14bae9f372385e4bc01368027cdbc29384c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 00:22:55 -0800 Subject: [PATCH 0295/4284] [PATCH] sync klibc with release 0.95 --- klibc/Makefile | 17 ++ klibc/klibc/Makefile | 9 + klibc/klibc/SYSCALLS | 7 +- .../arch/i386/include/klibc/archsignal.h | 2 +- klibc/klibc/arch/ia64/Makefile.inc | 11 +- .../arch/ia64/include/klibc/archsignal.h | 2 - klibc/klibc/arch/ia64/pipe.c | 42 +++++ klibc/klibc/arch/ppc/Makefile.inc | 8 +- klibc/klibc/arch/ppc/crt0.S | 27 +-- klibc/klibc/arch/ppc64/Makefile.inc | 5 + klibc/klibc/arch/ppc64/crt0.S | 14 +- .../arch/ppc64/include/klibc/archsetjmp.h | 36 ++++ klibc/klibc/arch/ppc64/setjmp.S | 46 +++++ klibc/klibc/arch/s390/Makefile.inc | 7 +- klibc/klibc/include/klibc/compiler.h | 7 + klibc/klibc/include/signal.h | 6 + klibc/klibc/include/stdio.h | 5 +- klibc/klibc/include/sys/module.h | 158 ------------------ klibc/klibc/inet/bindresvport.c | 2 +- klibc/klibc/mmap.c | 2 +- klibc/klibc/strcasecmp.c | 24 ++- klibc/klibc/strerror.c | 1 - klibc/klibc/strncasecmp.c | 23 ++- klibc/klibc/strncmp.c | 2 +- klibc/klibc/syscommon.h | 1 - klibc/klibc/tests/memstrtest.c | 4 +- klibc/klibc/tests/minips.c | 1 + klibc/version | 2 +- 28 files changed, 240 insertions(+), 231 deletions(-) create mode 100644 klibc/klibc/arch/ia64/pipe.c create mode 100644 klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h create mode 100644 klibc/klibc/arch/ppc64/setjmp.S delete mode 100644 klibc/klibc/include/sys/module.h diff --git a/klibc/Makefile b/klibc/Makefile index 5f9a7d6a6e..ef5fbabff8 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -1,6 +1,23 @@ +VERSION := $(shell cat version) SUBDIRS = klibc all: +rpmbuild = $(shell which rpmbuild 2>/dev/null || which rpm) + +klibc.spec: klibc.spec.in version + sed -e 's/@@VERSION@@/$(VERSION)/g' < $< > $@ + +.PHONY: rpm +rpm: klibc.spec + +$(rpmbuild) -bb klibc.spec + %: @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done + +clean: + @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done + +spotless: + @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done + rm -f klibc.spec *~ tags diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index e1d63381c1..5fc481aa8a 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -57,6 +57,12 @@ tests: $(TESTS) tests/%.o : tests/%.c $(CC) $(CFLAGS) -c -o $@ $< +# This particular file uses a bunch of formats gcc don't know of, in order +# to test the full range of our vsnprintf() function. This outputs a bunch +# of useless warnings unless we tell it not to. +tests/testvsnp.o : tests/testvsnp.c + $(CC) $(CFLAGS) -Wno-format -c -o $@ $< + tests/% : tests/%.o $(LIB) $(CRT0) $(LD) $(LDFLAGS) -o $@ $(CRT0) $< $(LIB) $(LIBGCC) cp $@ $@.stripped @@ -131,6 +137,9 @@ spotless: clean find . \( -name \*~ -o -name '.*.d' \) -not -type d -print0 | \ xargs -0rt rm -f +bitsize: + @echo $(BITSIZE) + ifneq ($(wildcard $(DIR)/.*.d),) include $(wildcard $(DIR)/.*.d) endif diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS index 92dff963b3..0be1b4425a 100644 --- a/klibc/klibc/SYSCALLS +++ b/klibc/klibc/SYSCALLS @@ -73,7 +73,7 @@ int mknod(const char *, mode_t, dev_t) int chmod(const char *, mode_t) int mkdir(const char *, mode_t) int rmdir(const char *) - int pipe(int *) + int pipe(int *) mode_t umask(mode_t) int chroot(const char *) int symlink(const char *, const char *) @@ -139,9 +139,8 @@ int mprotect(const void *, size_t, int) int uname(struct utsname *) int setdomainname(const char *, size_t) int sethostname(const char *, size_t) -int init_module(const char *, struct module *) - void * create_module(const char *, size_t) -int delete_module(const char *) +long init_module(void *, unsigned long, const char *) +long delete_module(const char *, unsigned int) int query_module(const char *, int, void *, size_t, size_t) int reboot::__reboot(int, int, int, void *) int syslog::klogctl(int, char *, int) diff --git a/klibc/klibc/arch/i386/include/klibc/archsignal.h b/klibc/klibc/arch/i386/include/klibc/archsignal.h index caea8d8b3d..b092ba6d3a 100644 --- a/klibc/klibc/arch/i386/include/klibc/archsignal.h +++ b/klibc/klibc/arch/i386/include/klibc/archsignal.h @@ -8,6 +8,6 @@ #ifndef _KLIBC_ARCHSIGNAL_H #define _KLIBC_ARCHSIGNAL_H -typedef int sig_atomic_t; +/* No special stuff for this architecture */ #endif diff --git a/klibc/klibc/arch/ia64/Makefile.inc b/klibc/klibc/arch/ia64/Makefile.inc index edf43459f8..781448770e 100644 --- a/klibc/klibc/arch/ia64/Makefile.inc +++ b/klibc/klibc/arch/ia64/Makefile.inc @@ -9,7 +9,16 @@ ARCHOBJS = \ arch/$(ARCH)/vfork.o \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/pipe.o \ + libgcc/__divdi3.o \ + libgcc/__divsi3.o \ + libgcc/__udivdi3.o \ + libgcc/__udivsi3.o \ + libgcc/__umodsi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmodsi4.o \ + libgcc/__udivmoddi4.o ARCHSOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS)) diff --git a/klibc/klibc/arch/ia64/include/klibc/archsignal.h b/klibc/klibc/arch/ia64/include/klibc/archsignal.h index 9ab0ed744c..5b01f19bc2 100644 --- a/klibc/klibc/arch/ia64/include/klibc/archsignal.h +++ b/klibc/klibc/arch/ia64/include/klibc/archsignal.h @@ -28,6 +28,4 @@ struct sigaction { #define sa_handler _u._sa_handler #define sa_sigaction _u._sa_sigaction -typedef int sig_atomic_t; - #endif diff --git a/klibc/klibc/arch/ia64/pipe.c b/klibc/klibc/arch/ia64/pipe.c new file mode 100644 index 0000000000..5f5dd05727 --- /dev/null +++ b/klibc/klibc/arch/ia64/pipe.c @@ -0,0 +1,42 @@ +/* + * pipe.c + */ + +#include "syscommon.h" +#include + +#define ASM_CLOBBERS ,"out2", "out3", "out4", "out5", "out6", "out7", \ + /* Non-stacked integer registers, minus r8, r9, r10, r15. */ \ + "r2", "r3", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \ + "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \ + "r28", "r29", "r30", "r31", \ + /* Predicate registers. */ \ + "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \ + /* Non-rotating fp registers. */ \ + "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + /* Branch registers. */ \ + "b6", "b7" + +int pipe(int *filedes) +{ + register long _r8 asm("r8"); + register long _r9 asm("r9"); + register long _r10 asm("r10"); + register long _r15 asm("r15") = __NR_pipe; + register long _out0 asm ("out0") = (long)filedes; + long _retval; + __asm __volatile (__IA64_BREAK + : "=r" (_r8), "=r" (_r10), "=r" (_r15), + "=r" (_out0) + : "2" (_r15), "3" (_out0) + : "memory" ASM_CLOBBERS); + if (_r10 == -1) { + errno = _r8; + _retval = -1; + } else { + filedes[0] = _r8; + filedes[1] = _r9; + _retval = 0; + } + return _retval; +} diff --git a/klibc/klibc/arch/ppc/Makefile.inc b/klibc/klibc/arch/ppc/Makefile.inc index 6e87a48d6b..3bd2c0643c 100644 --- a/klibc/klibc/arch/ppc/Makefile.inc +++ b/klibc/klibc/arch/ppc/Makefile.inc @@ -8,7 +8,13 @@ # ARCHOBJS = \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o + ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) diff --git a/klibc/klibc/arch/ppc/crt0.S b/klibc/klibc/arch/ppc/crt0.S index f7274b07dd..282f8411e4 100644 --- a/klibc/klibc/arch/ppc/crt0.S +++ b/klibc/klibc/arch/ppc/crt0.S @@ -1,12 +1,5 @@ # # arch/ppc/crt0.S -# -# void _start(void) -# { -# /* Divine up argc, argv, and envp */ -# environ = envp; -# exit(main(argc, argv, envp)); -# } # .text @@ -14,16 +7,14 @@ .type _start,@function .globl _start _start: - lwz 3,0(1) - addi 4,1,4 - addi 5,1,8 - slwi 0,3,2 - add 5,5,0 - li 0,0 - stwu 0,-16(1) - lis 9,environ@ha - stw 5,environ@l(9) - bl main - bl exit + stwu 1,-16(1) + addi 3,1,16 + /* + * the SVR4abippc.pdf specifies r7 as a pointer to + * a termination function pointer. + * It is unused on Linux. + */ + mr 4,7 + bl __libc_init .size _start,.-_start diff --git a/klibc/klibc/arch/ppc64/Makefile.inc b/klibc/klibc/arch/ppc64/Makefile.inc index 434d0aad96..3ab3a8c8e6 100644 --- a/klibc/klibc/arch/ppc64/Makefile.inc +++ b/klibc/klibc/arch/ppc64/Makefile.inc @@ -7,4 +7,9 @@ # accordingly. # +ARCHOBJS = \ + arch/$(ARCH)/setjmp.o + +ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) + archclean: diff --git a/klibc/klibc/arch/ppc64/crt0.S b/klibc/klibc/arch/ppc64/crt0.S index 2f352e8045..872d2a0791 100644 --- a/klibc/klibc/arch/ppc64/crt0.S +++ b/klibc/klibc/arch/ppc64/crt0.S @@ -23,16 +23,10 @@ _start: .globl ._start .type ._start,@function ._start: - ld 3,0(1) - ld 4,8(1) - ld 5,16(1) - li 0,0 - stdu 0,-64(1) - ld 9,.LC0@toc(2) - std 5,0(9) - bl .main - nop - bl .exit + stdu %r1,-32(%r1) + addi %r3,%r1,32 + mr %r4,%r7 /* fini */ + b .__libc_init nop .size _start,.-_start diff --git a/klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h b/klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h new file mode 100644 index 0000000000..006a2e27be --- /dev/null +++ b/klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h @@ -0,0 +1,36 @@ +/* + * arch/ppc64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r2; + unsigned long __sp; + unsigned long __lr; + unsigned long __cr; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __r16; + unsigned long __r17; + unsigned long __r18; + unsigned long __r19; + unsigned long __r20; + unsigned long __r21; + unsigned long __r22; + unsigned long __r23; + unsigned long __r24; + unsigned long __r25; + unsigned long __r26; + unsigned long __r27; + unsigned long __r28; + unsigned long __r29; + unsigned long __r30; + unsigned long __r31; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/ppc64/setjmp.S b/klibc/klibc/arch/ppc64/setjmp.S new file mode 100644 index 0000000000..1dcc67035e --- /dev/null +++ b/klibc/klibc/arch/ppc64/setjmp.S @@ -0,0 +1,46 @@ +# +# arch/ppc64/setjmp.S +# +# Basic setjmp/longjmp implementation +# This file was derived from the equivalent file in NetBSD +# + + .text + .align 4 + + .section ".opd","aw" +setjmp: + .quad .setjmp,.TOC.@tocbase,0 + .previous + .size setjmp,24 + .type .setjmp,@function + .globl setjmp + .globl .setjmp +.setjmp: + mflr %r11 /* save return address */ + mfcr %r12 /* save condition register */ + mr %r10,%r1 /* save stack pointer */ + mr %r9,%r2 /* save GPR2 (not needed) */ + stmw %r9,0(%r3) /* save r9..r31 */ + li %r3,0 /* indicate success */ + blr /* return */ + + .size .setjmp,.-.setjmp + .section ".opd","aw" +longjmp: + .quad .longjmp,.TOC.@tocbase,0 + .previous + .size longjmp,24 + .type .longjmp,@function + .globl longjmp + .globl .longjmp +.longjmp: + lmw %r9,0(%r3) /* save r9..r31 */ + mtlr %r11 /* restore LR */ + mtcr %r12 /* restore CR */ + mr %r2,%r9 /* restore GPR2 (not needed) */ + mr %r1,%r10 /* restore stack */ + mr %r3,%r4 /* get return value */ + blr /* return */ + + .size .longjmp,.-.longjmp diff --git a/klibc/klibc/arch/s390/Makefile.inc b/klibc/klibc/arch/s390/Makefile.inc index 45aa551695..c50f4f2886 100644 --- a/klibc/klibc/arch/s390/Makefile.inc +++ b/klibc/klibc/arch/s390/Makefile.inc @@ -8,7 +8,12 @@ # ARCHOBJS = \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) diff --git a/klibc/klibc/include/klibc/compiler.h b/klibc/klibc/include/klibc/compiler.h index 5c284b206c..64b8c54158 100644 --- a/klibc/klibc/include/klibc/compiler.h +++ b/klibc/klibc/include/klibc/compiler.h @@ -58,4 +58,11 @@ # define __unlikely(x) (x) #endif +/* Possibly unused function */ +#ifdef __GNUC__ +# define __unusedfunc __attribute__((unused)) +#else +# define __unusedfunc +#endif + #endif diff --git a/klibc/klibc/include/signal.h b/klibc/klibc/include/signal.h index 62c5083dc0..f9eebb2a29 100644 --- a/klibc/klibc/include/signal.h +++ b/klibc/klibc/include/signal.h @@ -13,6 +13,12 @@ #include +/* glibc seems to use sig_atomic_t as "int" pretty much on all architectures. + Do the same, but allow the architecture to override. */ +#ifdef _KLIBC_HAS_ARCH_SIG_ATOMIC_T +typedef int sig_atomic_t; +#endif + /* Some architectures don't define these */ #ifndef SA_RESETHAND # define SA_RESETHAND SA_ONESHOT diff --git a/klibc/klibc/include/stdio.h b/klibc/klibc/include/stdio.h index 5e621af5f1..f57439f018 100644 --- a/klibc/klibc/include/stdio.h +++ b/klibc/klibc/include/stdio.h @@ -78,12 +78,13 @@ __extern size_t _fread(void *, size_t, FILE *); __extern size_t _fwrite(const void *, size_t, FILE *); #ifndef __NO_FREAD_FWRITE_INLINES -static __inline__ size_t +extern __inline__ size_t fread(void *__p, size_t __s, size_t __n, FILE *__f) { return _fread(__p, __s*__n, __f)/__s; } -static __inline__ size_t + +extern __inline__ size_t fwrite(void *__p, size_t __s, size_t __n, FILE *__f) { return _fwrite(__p, __s*__n, __f)/__s; diff --git a/klibc/klibc/include/sys/module.h b/klibc/klibc/include/sys/module.h deleted file mode 100644 index 96b3b59945..0000000000 --- a/klibc/klibc/include/sys/module.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * sys/module.h - * - * This is a bastardized version of linux/module.h, since the latter - * doesn't have __KERNEL__ guards where it needs them... - */ - -#ifndef _SYS_MODULE_H -#define _SYS_MODULE_H - -/* - * Dynamic loading of modules into the kernel. - * - * Rewritten by Richard Henderson Dec 1996 - */ - -#include - -/* Don't need to bring in all of uaccess.h just for this decl. */ -struct exception_table_entry; - -/* Used by get_kernel_syms, which is obsolete. */ -struct kernel_sym -{ - unsigned long value; - char name[60]; /* should have been 64-sizeof(long); oh well */ -}; - -struct module_symbol -{ - unsigned long value; - const char *name; -}; - -struct module_ref -{ - struct module *dep; /* "parent" pointer */ - struct module *ref; /* "child" pointer */ - struct module_ref *next_ref; -}; - -/* TBD */ -struct module_persist; - -struct module -{ - unsigned long size_of_struct; /* == sizeof(module) */ - struct module *next; - const char *name; - unsigned long size; - - union - { - atomic_t usecount; - long pad; - } uc; /* Needs to keep its size - so says rth */ - - unsigned long flags; /* AUTOCLEAN et al */ - - unsigned nsyms; - unsigned ndeps; - - struct module_symbol *syms; - struct module_ref *deps; - struct module_ref *refs; - int (*init)(void); - void (*cleanup)(void); - const struct exception_table_entry *ex_table_start; - const struct exception_table_entry *ex_table_end; -#ifdef __alpha__ - unsigned long gp; -#endif - /* Members past this point are extensions to the basic - module support and are optional. Use mod_member_present() - to examine them. */ - const struct module_persist *persist_start; - const struct module_persist *persist_end; - int (*can_unload)(void); - int runsize; /* In modutils, not currently used */ - const char *kallsyms_start; /* All symbols for kernel debugging */ - const char *kallsyms_end; - const char *archdata_start; /* arch specific data for module */ - const char *archdata_end; - const char *kernel_data; /* Reserved for kernel internal use */ -}; - -struct module_info -{ - unsigned long addr; - unsigned long size; - unsigned long flags; - long usecount; -}; - -/* Bits of module.flags. */ - -#define MOD_UNINITIALIZED 0 -#define MOD_RUNNING 1 -#define MOD_DELETED 2 -#define MOD_AUTOCLEAN 4 -#define MOD_VISITED 8 -#define MOD_USED_ONCE 16 -#define MOD_JUST_FREED 32 -#define MOD_INITIALIZING 64 - -/* Values for query_module's which. */ - -#define QM_MODULES 1 -#define QM_DEPS 2 -#define QM_REFS 3 -#define QM_SYMBOLS 4 -#define QM_INFO 5 - -/* Can the module be queried? */ -#define MOD_CAN_QUERY(mod) (((mod)->flags & (MOD_RUNNING | MOD_INITIALIZING)) && !((mod)->flags & MOD_DELETED)) - -/* When struct module is extended, we must test whether the new member - is present in the header received from insmod before we can use it. - This function returns true if the member is present. */ - -#define mod_member_present(mod,member) \ - ((unsigned long)(&((struct module *)0L)->member + 1) \ - <= (mod)->size_of_struct) - -/* - * Ditto for archdata. Assumes mod->archdata_start and mod->archdata_end - * are validated elsewhere. - */ -#define mod_archdata_member_present(mod, type, member) \ - (((unsigned long)(&((type *)0L)->member) + \ - sizeof(((type *)0L)->member)) <= \ - ((mod)->archdata_end - (mod)->archdata_start)) - - -/* Check if an address p with number of entries n is within the body of module m */ -#define mod_bound(p, n, m) ((unsigned long)(p) >= ((unsigned long)(m) + ((m)->size_of_struct)) && \ - (unsigned long)((p)+(n)) <= (unsigned long)(m) + (m)->size) - -/* Backwards compatibility definition. */ - -#define GET_USE_COUNT(module) (atomic_read(&(module)->uc.usecount)) - -/* Poke the use count of a module. */ - -#define __MOD_INC_USE_COUNT(mod) \ - (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE) -#define __MOD_DEC_USE_COUNT(mod) \ - (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED) -#define __MOD_IN_USE(mod) \ - (mod_member_present((mod), can_unload) && (mod)->can_unload \ - ? (mod)->can_unload() : atomic_read(&(mod)->uc.usecount)) - -/* Indirect stringification. */ - -#define __MODULE_STRING_1(x) #x -#define __MODULE_STRING(x) __MODULE_STRING_1(x) - -#endif /* _SYS_MODULE_H */ diff --git a/klibc/klibc/inet/bindresvport.c b/klibc/klibc/inet/bindresvport.c index b5f327bb33..c30054edfd 100644 --- a/klibc/klibc/inet/bindresvport.c +++ b/klibc/klibc/inet/bindresvport.c @@ -37,7 +37,7 @@ int bindresvport(int sd, struct sockaddr_in *sin) for (i = 0; i < NUM_PORTS; i++, port++) { sin->sin_port = htons(port); - if ((ret = bind(sd, sin, sizeof(*sin))) != -1) + if ((ret = bind(sd, (struct sockaddr *)&sin, sizeof(*sin))) != -1) break; if (port == END_PORT) port = START_PORT; diff --git a/klibc/klibc/mmap.c b/klibc/klibc/mmap.c index 3d28cba601..aedf4dceb5 100644 --- a/klibc/klibc/mmap.c +++ b/klibc/klibc/mmap.c @@ -19,7 +19,7 @@ * Prefer mmap2() over mmap(), except on the architectures listed */ -#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__) +#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__) && !defined(__powerpc64__) /* This architecture uses mmap2() */ diff --git a/klibc/klibc/strcasecmp.c b/klibc/klibc/strcasecmp.c index e583491b35..12aef40d93 100644 --- a/klibc/klibc/strcasecmp.c +++ b/klibc/klibc/strcasecmp.c @@ -1,6 +1,5 @@ /* * strcasecmp.c - * */ #include @@ -8,18 +7,17 @@ int strcasecmp(const char *s1, const char *s2) { - char *n1, *n2; - int i, retval; + const unsigned char *c1 = s1, *c2 = s2; + unsigned char ch; + int d = 0; - n1 = strdup(s1); - n2 = strdup(s2); + while ( 1 ) { + /* toupper() expects an unsigned char (implicitly cast to int) + as input, and returns an int, which is exactly what we want. */ + d = toupper(ch = *c1++) - toupper(*c2++); + if ( d || !ch ) + break; + } - for (i = 0; i < strlen(n1); i++) - n1[i] = toupper(n1[i]); - for (i = 0; i < strlen(n2); i++) - n2[i] = toupper(n2[i]); - retval = strcmp(n1, n2); - free(n1); - free(n2); - return retval; + return d; } diff --git a/klibc/klibc/strerror.c b/klibc/klibc/strerror.c index 754a30693c..62705553a6 100644 --- a/klibc/klibc/strerror.c +++ b/klibc/klibc/strerror.c @@ -10,7 +10,6 @@ char *strerror(int errnum) char numbuf[32]; char *p; - int len; p = numbuf+sizeof numbuf; *--p = '\0'; diff --git a/klibc/klibc/strncasecmp.c b/klibc/klibc/strncasecmp.c index 542493de0f..3309d1a7fe 100644 --- a/klibc/klibc/strncasecmp.c +++ b/klibc/klibc/strncasecmp.c @@ -7,18 +7,17 @@ int strncasecmp(const char *s1, const char *s2, size_t n) { - char *n1, *n2; - int i, retval; + const unsigned char *c1 = s1, *c2 = s2; + unsigned char ch; + int d = 0; - n1 = strndup(s1, n); - n2 = strndup(s2, n); + while ( n-- ) { + /* toupper() expects an unsigned char (implicitly cast to int) + as input, and returns an int, which is exactly what we want. */ + d = toupper(ch = *c1++) - toupper(*c2++); + if ( d || !ch ) + break; + } - for (i = 0; i < strlen(n1); i++) - n1[i] = toupper(n1[i]); - for (i = 0; i < strlen(n2); i++) - n2[i] = toupper(n2[i]); - retval = strcmp(n1, n2); - free(n1); - free(n2); - return retval; + return d; } diff --git a/klibc/klibc/strncmp.c b/klibc/klibc/strncmp.c index 98a41c3773..4dbde1389f 100644 --- a/klibc/klibc/strncmp.c +++ b/klibc/klibc/strncmp.c @@ -11,7 +11,7 @@ int strncmp(const char *s1, const char *s2, size_t n) int d = 0; while ( n-- ) { - d = (int)*c2++ - (int)(ch = *c1++); + d = (int)(ch = *c1++) - (int)*c2++; if ( d || !ch ) break; } diff --git a/klibc/klibc/syscommon.h b/klibc/klibc/syscommon.h index 224e240e38..916d4eb0c0 100644 --- a/klibc/klibc/syscommon.h +++ b/klibc/klibc/syscommon.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/klibc/klibc/tests/memstrtest.c b/klibc/klibc/tests/memstrtest.c index 14d5173cb2..70c642c067 100644 --- a/klibc/klibc/tests/memstrtest.c +++ b/klibc/klibc/tests/memstrtest.c @@ -8,7 +8,7 @@ int main(void) int i; int r; - for(i = 0; i < sizeof(t1); i++) + for(i = 0; i < (int)sizeof(t1); i++) t1[i] = t2[i] = (unsigned char)i; r = memcmp(t1, t2, sizeof(t1)); @@ -19,7 +19,7 @@ int main(void) r = memcmp(t1, t2, sizeof(t1)); printf("memcmp r = %d\n", r); - for (i = 0; i < sizeof(t1); i++) + for (i = 0; i < (int)sizeof(t1); i++) t1[i] = 0xaa; memset(t2, 0xaa, sizeof(t2)); r = memcmp(t1, t2, sizeof(t1)); diff --git a/klibc/klibc/tests/minips.c b/klibc/klibc/tests/minips.c index c599150858..20898270f4 100644 --- a/klibc/klibc/tests/minips.c +++ b/klibc/klibc/tests/minips.c @@ -396,6 +396,7 @@ static void print_proc(void){ ); break; default: + break; } if(show_args) printf(" [%s]\n", P_cmd); else printf(" %s\n", P_cmd); diff --git a/klibc/version b/klibc/version index e6e9cf41cc..fd6d73e4a0 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.82 +0.95 From d546791d3ab1cbf8cb08b27eab1fc09e1c5d04dc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 00:23:28 -0800 Subject: [PATCH 0296/4284] [PATCH] signal fixes due to klibc update. --- tdb/spinlock.c | 1 + tdb/tdb.c | 1 + tdb/tdb.h | 1 + udevdb.c | 1 + 4 files changed, 4 insertions(+) diff --git a/tdb/spinlock.c b/tdb/spinlock.c index 9bf42adfcf..50cd952c72 100644 --- a/tdb/spinlock.c +++ b/tdb/spinlock.c @@ -28,6 +28,7 @@ #endif #ifdef STANDALONE +#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include #include diff --git a/tdb/tdb.c b/tdb/tdb.c index 772602ed5b..9ae57a974e 100644 --- a/tdb/tdb.c +++ b/tdb/tdb.c @@ -52,6 +52,7 @@ #include #endif +#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include #include diff --git a/tdb/tdb.h b/tdb/tdb.h index 839d5b1516..cac172adce 100644 --- a/tdb/tdb.h +++ b/tdb/tdb.h @@ -25,6 +25,7 @@ extern "C" { #endif +#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include /* flags to tdb_store() */ diff --git a/udevdb.c b/udevdb.c index e0bd39e84b..5be3c25151 100644 --- a/udevdb.c +++ b/udevdb.c @@ -24,6 +24,7 @@ /* * udev database library */ +#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include #include From 54b72ce91eec6116f14f5fa5abefb2e6210df795 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 00:30:59 -0800 Subject: [PATCH 0297/4284] [PATCH] v009 release --- ChangeLog | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ac06290775..cb8fa7f15c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,68 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 3653595b06..e599df34ad 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 008_bk +VERSION = 009 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 3f71e1452c..da7743ef6c 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 008_bk +Version: 009 Release: 1 License: GPL Group: Utilities/System From 9c23ec09a04529b3875fb496ed34765a84199aee Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 00:57:52 -0800 Subject: [PATCH 0298/4284] [PATCH] 009_bk makefile changes. --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e599df34ad..c5c05d615d 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 009 +VERSION = 009_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index da7743ef6c..f8bde13171 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 009 +Version: 009_bk Release: 1 License: GPL Group: Utilities/System From 4868e8fba7fda5074fc7d64f4f22236127afc3c8 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 17 Dec 2003 00:58:01 -0800 Subject: [PATCH 0299/4284] [PATCH] trivial cleanup parser changes o use defines in debug strings o replace my 'xxx' debug :) o shorten line in man page example to not to exceed 80 chars when printed --- namedev_parse.c | 12 ++++++------ udev.8 | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 3578058a76..9cd96a6224 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -257,7 +257,7 @@ keys: /* check presence of keys according to method type */ switch (dev.type) { case LABEL: - dbg_parse("LABEL name='%s', bus='%s', " + dbg_parse(TYPE_LABEL " name='%s', bus='%s', " "sysfs_file='%s', sysfs_value='%s', symlink='%s'", dev.name, dev.bus, dev.sysfs_file, dev.sysfs_value, dev.symlink); @@ -268,7 +268,7 @@ keys: goto error; break; case NUMBER: - dbg_parse("NUMBER name='%s', bus='%s', id='%s', symlink='%s'", + dbg_parse(TYPE_NUMBER "name='%s', bus='%s', id='%s', symlink='%s'", dev.name, dev.bus, dev.id, dev.symlink); if ((*dev.name == '\0') || (*dev.bus == '\0') || @@ -276,7 +276,7 @@ keys: goto error; break; case TOPOLOGY: - dbg_parse("TOPOLOGY name='%s', bus='%s', " + dbg_parse(TYPE_TOPOLOGY "name='%s', bus='%s', " "place='%s', symlink='%s'", dev.name, dev.bus, dev.place, dev.symlink); if ((*dev.name == '\0') || @@ -285,14 +285,14 @@ keys: goto error; break; case REPLACE: - dbg_parse("REPLACE name='%s', kernel_name='%s', symlink='%s'", + dbg_parse(TYPE_REPLACE "name='%s', kernel_name='%s', symlink='%s'", dev.name, dev.kernel_name, dev.symlink); if ((*dev.name == '\0') || (*dev.kernel_name == '\0')) goto error; break; case CALLOUT: - dbg_parse("CALLOUT name='%s', bus='%s', program='%s', " + dbg_parse(TYPE_CALLOUT "name='%s', bus='%s', program='%s', " "id='%s', symlink='%s'", dev.name, dev.bus, dev.exec_program, dev.id, dev.symlink); @@ -303,7 +303,7 @@ keys: goto error; break; default: - dbg_parse("xxx default method"); + dbg_parse("unknown type of method"); goto error; } diff --git a/udev.8 b/udev.8 index f26beb4b9d..c4ee23dcc7 100644 --- a/udev.8 +++ b/udev.8 @@ -178,7 +178,7 @@ TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" REPLACE, KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" # multiple USB webcams with symlinks to be called webcam0, webcam1, ... -LABEL, BUS="usb", SYSFS_model="WebCam V3", NAME="video%n", SYMLINK="webcam%n" +LABEL, BUS="usb", SYSFS_model="XV3", NAME="video%n", SYMLINK="webcam%n" .fi .P Permissions and ownership for the created device files may specified at From 1b1dbc47a3b1b227273c7ed5074a6376efc7526e Mon Sep 17 00:00:00 2001 From: "dhollis@davehollis.com" Date: Wed, 17 Dec 2003 08:35:00 -0800 Subject: [PATCH 0300/4284] [PATCH] mark config files as such in the rpm spec file Got a nasty surprise after upgrading my RPM. The config files weren't marked as configs and were subsequently replaced! DOH! Fortunately, I didn't have much in there yet but that certainly isn't something others will like going forward. Attached is a simple patch to the spec file so they aren't replaced in the future. The config files included in the RPM should wind up as udev.conf.rpmnew, etc if they are different from what is installed. --- udev.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/udev.spec b/udev.spec index f8bde13171..2e5a472a52 100644 --- a/udev.spec +++ b/udev.spec @@ -40,9 +40,9 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udev %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ -%attr(0644,root,root) /etc/udev/udev.conf -%attr(0644,root,root) /etc/udev/udev.rules -%attr(0644,root,root) /etc/udev/udev.permissions +%config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf +%config(noreplace) %attr(0644,root,root) /etc/udev/udev.rules +%config(noreplace) %attr(0644,root,root) /etc/udev/udev.permissions %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev.8* From 093bf8f4d2c44fb1f581dfec0330f3f86473496c Mon Sep 17 00:00:00 2001 From: "Roman.Kagan@itep.ru" Date: Wed, 17 Dec 2003 18:24:05 -0800 Subject: [PATCH 0301/4284] [PATCH] fix comment and whitespace handling in config files. This chunk broke parsing of blank lines and comments with blanks before '#'. Please revert it with the patch below. Roman. --- namedev_parse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 9cd96a6224..33e0c89e22 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -158,6 +158,10 @@ int namedev_init_rules(void) lineno++; dbg_parse("read '%s'", temp); + /* eat the whitespace */ + while (isspace(*temp)) + ++temp; + /* empty line? */ if (*temp == 0x00) continue; @@ -166,10 +170,6 @@ int namedev_init_rules(void) if (*temp == COMMENT_CHARACTER) continue; - /* eat the whitespace */ - while (isspace(*temp)) - ++temp; - memset(&dev, 0x00, sizeof(struct config_device)); /* get the method */ From 281ff00a611aa0a71e43dd4355b0caa918d820d2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 18:28:05 -0800 Subject: [PATCH 0302/4284] [PATCH] add tests to catch whitespace and comment config file parsing errors. --- test/udev-test.pl | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 08b99f041f..7afbd0d6fc 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -101,6 +101,39 @@ EOF expected => "visor" , conf => < "Handle comment lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor" , + conf => < "Handle comment lines in config file with whitespace (and replace kernel name)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor" , + conf => < "Handle empty lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor" , + conf => < Date: Wed, 17 Dec 2003 18:32:53 -0800 Subject: [PATCH 0303/4284] [PATCH] Allow build with empty EXTRAS Need to let the shell expand $EXTRAS so it can properly detect an empty list. Without this patch, the build fails whenever $EXTRAS is empty. --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index c5c05d615d..c2ed659531 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,7 @@ endif CFLAGS += -I$(PWD)/libsysfs all: $(ROOT) - @for target in $(EXTRAS) ; do \ + @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ -C $$target $@ ; \ @@ -223,7 +223,7 @@ clean: | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(MAKE) -C klibc clean - @for target in $(EXTRAS) ; do \ + @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ -C $$target $@ ; \ @@ -286,7 +286,7 @@ install: install-dbus-policy all $(GEN_CONFIGS) $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug - @for target in $(EXTRAS) ; do \ + @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ -C $$target $@ ; \ @@ -303,7 +303,7 @@ uninstall: uninstall-dbus-policy - rmdir $(hotplugdir) - rmdir $(configdir) - rmdir $(udevdir) - @for target in $(EXTRAS) ; do \ + @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ -C $$target $@ ; \ From 77c46e9bd630806cf23741ead3d7551661973847 Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Wed, 17 Dec 2003 18:58:28 -0800 Subject: [PATCH 0304/4284] [PATCH] add libsysfs docs Here's the latest libsysfs doc, you may want to include it in your docs directory. --- docs/libsysfs.txt | 1687 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1687 insertions(+) create mode 100644 docs/libsysfs.txt diff --git a/docs/libsysfs.txt b/docs/libsysfs.txt new file mode 100644 index 0000000000..66156e5607 --- /dev/null +++ b/docs/libsysfs.txt @@ -0,0 +1,1687 @@ + + System Utilities sysfs Library - libsysfs + ========================================= + +Version: 0.4.0 +December 16, 2003 + +Contents +-------- +1. Introduction +2. Requirements +3. Definitions +4. Overview +5. Data Structures + 5.1 Directory and Attribute Data Structures + 5.1.1 Attribute Structure + 5.1.2 Link Structure + 5.1.3 Directory Structure + 5.2 Bus Data Structure + 5.3 Class Data Structures + 5.4 Root Device Data Structure + 5.5 Device Data Structure + 5.6 Driver Data Structure +6. Functions + 6.1 Utility Functions + 6.2 Filesystem Functions + 6.2.1 Attribute Functions + 6.2.2 Directory Link Functions + 6.2.3 Directory Functions + 6.3 Bus Functions + 6.4 Class Functions + 6.5 Device Functions + 6.6 Driver Functions +7. Navigating a dlist +8. Usage +9. Conclusion + + +1. Introduction +--------------- + +Libsysfs' purpose is to provide a consistent and stable interface for +querying system device information exposed through the sysfs filesystem. +The library implements functions for querying filesystem information, +such as reading directories and files. It also contains routines for +working with buses, classes, and the device tree. + + +2. Requirements +--------------- + +The library must satisfy the following requirements: + +- It must provide a stable programming interfaces that applications can + be built upon. + +- It must provide functions to retrieve device Vital Product Data (VPD) + information for Error Log Analysis (ELA) support. ELA will provide + device driver and device bus address information. + +- It must provide access to all system devices and information exposed + by sysfs. + +- It must provide a function to find sysfs' current mount point. + +- It must provide a function for udev to retrieve a device's major and + minor numbers. + + +3. Definitions +-------------- + +- sysfs: Sysfs is a virtual filesystem in 2.5+ Linux kernels that + presents a hierarchical representation of all system physical and + virtual devices. It presents system devices by bus, by class, and + by topology. Callbacks to device drivers are exposed as files in + device directories. Sysfs, for all purposes, is our tree of system + devices. For more information, please see: + + http://www.kernel.org/pub/linux/kernel/people/mochel/doc/ + +- udev: Udev is Greg Kroah-Hartman's User Space implementation of devfs. + Udev creates /dev nodes for devices upon Hotplug events. The Hotplug + event provides udev with a sysfs directory location of the device. Udev + must use that directory to grab device's major and minor number, which it + will use to create the /dev node. For more information, please see: + + http://www.kernel.org/pub/linux/utils/kernel/hotplug/ + + +4. Overview +----------- + +Libsysfs grew from a common need. There are several applications under +development that need access to sysfs and system devices. Udev, on a +hotplug event, must take a sysfs device path and create a /dev node. Our +diagnostic client needs to list all system devices. Finally, our Error +Log Analysis piece is required to retrieve VPD information for a +failing device. We divided to create a single library interface rather +than having these separate applications create their own accesses to +sysfs involving reading directories and files. + +Libsysfs will also provide stability for applications to be built upon. Sysfs +currently doesn't enforce any standards for callback or file names. File +names change depending on bus or class. Sysfs is also changing, it is +currently being developed. Libsysfs will provide a stable interface to +applications while allowing sysfs to change underneath it. + +Like sysfs, the library will provide devices to applications by bus, by +class, and by topology. The library will function similar to directories +and files that lie underneath it. To query a device on a PCI bus, one would +"open" the bus to scan or read devices and "close" the bus when +completed. Besides supplying functions to retrieve devices, the library +will also provide some utility functions like getting sysfs mount point. + + +5. Data Structures +------------------ + +Libsysfs will classify system devices following sysfs' example, dividing +them by bus, class, and devices. The library presents this information +generically. It doesn't, for example, differentiate between PCI and USB +buses. Device attributes are presented with values as they are exposed +by sysfs, the values are not formatted. + +The library will provide standard definitions for working with sysfs +and devices, here's some examples: + +#define SYSFS_FSTYPE_NAME "sysfs" +#define SYSFS_PROC_MNTS "/proc/mounts" +#define SYSFS_BUS_DIR "/bus" +#define SYSFS_BUS_NAME "bus" +#define SYSFS_CLASS_DIR "/class" +#define SYSFS_CLASS_DIR "/class" +#define SYSFS_BLOCK_DIR "/block" +#define SYSFS_BLOCK_NAME "block" +#define SYSFS_DEVICES_DIR "/devices" +#define SYSFS_DEVICES_NAME "devices" +#define SYSFS_DRIVERS_DIR "/drivers" +#define SYSFS_DRIVERS_NAME "drivers" +#define SYSFS_NAME_ATTRIBUTE "name" + +The library uses some definitions to mark maximum size of a sysfs name or +path length: + +#define SYSFS_PATH_MAX 255 +#define SYSFS_NAME_LEN 50 +#define SYSFS_BUS_ID_SIZE 20 + + +NOTE: + As of release 0.4.0 of libsysfs, a number of changes have been made + so that the dlists and "directory" references in all libsysfs's + structures are not populated until such time that it is absolutely + necessary. Hence, these elements may not contain valid data at all + times (as was the case before). + +5.1 Directory and Attribute Data Structures +------------------------------------------- + +The library implements structures to represent sysfs directories, links, +and files. + + +5.1.1 Attribute Structure +------------------------- + +A file in sysfs represents a device or driver attribute. Attributes can be +read only, write only, or read and write. File data can be ASCII and +binary. The library has the following structure to represent files: + +struct sysfs_attribute { + unsigned char *value; + unsigned short len; /* value length */ + unsigned short method; /* show and store */ + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; +}; + +Path represents the file/attribute's full path. Value is used when reading +from or writing to an attribute. "len" is the length of data in "value". +Method is a bitmask for defining if the attribute supports show(read) +and/or store(write). + + +5.1.2 Link Structure +-------------------- + +Symbolic links are used in sysfs to link bus or class views with +particular devices. + +struct sysfs_link { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + unsigned char target[SYSFS_PATH_MAX]; +}; + +Link's name is stored in "name' and it's target stored in "target". Absolute +path to the link is stored in "path". + + +5.1.3 Directory Structure +------------------------- + +The directory structure represents a sysfs directory: + +struct sysfs_directory { + struct dlist *subdirs; + struct dlist *links; + struct dlist *attributes; + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; +}; + +The sysfs_directory structure includes the list of subdirectories, links and +attributes. The "name" and absolute "path" are also stored in the structure. +The sysfs_directory structure is intended for use internal to the library. +Applications needing access to attributes and links from the directory +will need to make appropriate calls (described below) to get the same. + + +5.2 Bus Data Structure +---------------------- + +All buses look similar in sysfs including lists of devices and drivers, +therefore we use the following structure to represent all sysfs buses: + +struct sysfs_bus { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* internal use only */ + struct dlist *drivers; + struct dlist *devices; + struct sysfs_directory *directory; +}; + +The sysfs_bus structure contains the bus "name", while the "path" to bus +directory is also stored. It also contains lists of devices on the bus +and drivers that are registered on it. The bus' directory is represented +by the sysfs_directory structure and it contains references to all the +subdirectories, links, and attributes. The sysfs_directory structure +is for internal use only. The following functions may be used by +applications to retrieve data from the sysfs_directory structure: + +struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) +struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, + unsigned char *attrname) + + +5.3 Class Data Structures +------------------------- + +The library uses two data structures to represent classes in sysfs. Sysfs +classes contains a class directory like "net" or "scsi_host" and then +class devices like "eth0", "lo", or "eth1" for the "net" class. + +struct sysfs_class { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct dlist *devices; + struct sysfs_directory *directory; +}; + +The sysfs_class represents device classes in sysfs like "net". It contains +the class "name", "path" to the class, a list of class devices and the +directory representation (for internal use only). + +struct sysfs_class_device { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char classname[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct sysfs_class_device *parent; + struct sysfs_device *sysdevice; /* NULL if virtual */ + struct sysfs_driver *driver; /* NULL if not implemented */ + struct sysfs_directory *directory; +}; + +A class device isn't the same as a sysfs_device, it's specific to the class in +which it belongs. The class device structure contains the name of the class +the class device belongs to, its sysfs_device reference and that device's +driver reference (if any). It also contains the name of the class device +- like "eth0", its parent point (if present) and its sysfs directory +information including links and attributes (for internal use only). +The following function may be used by applications to retrieve data +from the sysfs_directory structure: + +struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev); + + +5.4 Root Device Data Structure +------------------------------ + +Device hierarchies in sysfs are represented under the /sys/devices directory +structure. Sysfs devices typically spawn off from base devices which are +represented by a sysfs_root_device. + +struct sysfs_root_device { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct dlist *devices; + struct sysfs_directory *directory; +}; + +The sysfs_root_device structure contains a list of "devices" that spawn off it. +The name of the root device as represented under /sys/devices is read into +"name" and the absolute path into "path" and its sysfs_directory information +intended to be used internal to the library. + + +5.5 Device Data Structure +------------------------- + +The sysfs_device structure represents a system device that's exposed +in sysfs under the /sys/devices directory structure. + +struct sysfs_device { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char bus_id[SYSFS_NAME_LEN]; + unsigned char bus[SYSFS_NAME_LEN]; + unsigned char driver_name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct sysfs_device *parent; + struct dlist *children; + struct sysfs_directory *directory; +}; + +The sysfs_device structure contains a "parent" pointer, a list of child +devices, if any, device's directory, its bus id - which is the name of +device's directory, the bus name on which this device is registered and +its driver name. The device structure also contains the absolute path +to the device and a directory structure, which contains a list of the +device's attributes (for internal use only). The following functions +may be used to obtain information from sysfs_directory structure: + +struct sysfs_attribute *sysfs_get_device_attribute(struct sysfs_device *dev, + const unsigned char *name) +struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) + + +5.6 Driver Data Structure +------------------------- + +The sysfs_driver structure represents a device driver. + +struct sysfs_driver { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* for internal use only */ + struct dlist *devices; + struct sysfs_directory *directory; +}; + +The sysfs_driver structure contains a list of devices that use this driver, +the name of the driver, its path, and its directory information, which +includes the driver's attributes (for internal use only). The following +function may be used to retrieve driver attribute information from the +sysfs_directory structure: + +struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) + + +6. Functions +------------ + +Libsysfs will provide functions to access system devices by bus, by class, +and by device. Functions will act like accessing directories and files, +using "open" and "close". Open returns a structure and close is used +to clean that structure up. + + +6.1 Utility Functions +--------------------- + +The library will provide a few utility functions for working with sysfs. + +------------------------------------------------------------------------------- +Name: sysfs_get_mnt_path + +Description: Function finds the mount path for filesystem type "sysfs". + +Arguments: unsigned char *mnt_path Mount path buffer + size_t len Size of mount path buffer + +Returns: Zero with success. + -1 with error. Errno will be set with error: + - EINVAL for invalid argument, if buffer is NULL. + +Prototype: sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_name_from_path + +Description: Function returns the last directory or file name from the + included path. + +Arguments: const unsigned char *path Path to parse name from + unsigned char *name Buffer to put parsed name into + size_t *len Size of name buffer + +Returns: 0 with success. + -1 on Error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_get_name_from_path(const unsigned char *path, + unsigned char *name, size_t *len) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_link + +Description: Sysfs readlink function, reads the link at supplied path + and returns its target path. + +Arguments: const unsigned char *path Link's path + unsigned char *target Buffer to place link's target path + size_t len Size of target buffer + +Returns: 0 with success + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_get_link(const unsigned char *path, + unsigned char *target, size_t len) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_subsystem_list + +Description: Function returns the list of entries for the given subsystem. If + the argument is "bus", this function will return a list of buses + ("pci", "scsi", etc) supported on the system. + + sysfs_close_list() has to be called to free the list obtained + from this call. + +Arguments: unsigned char *name Subsystem to open, like "bus".. + +Returns: dlist of entries for the subsystem on success + NULL with error indicating the "name" subsystem is invalid. + +Prototype: struct dlist *sysfs_open_subsystem_list(unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_bus_devices_list + +Description: Function returns the list of devices on the given bus. + + sysfs_close_list() has to be called to free the list obtained + from this call. + +Arguments: unsigned char *name Bus name to open "pci"/"scsi"/"usb".. + +Returns: dlist of device names for the given bus on success + NULL with error indicating the bus is not supported. + +Prototype: struct dlist *sysfs_open_bus_devices_list(unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_list + +Description: Closes a given dlist. This can be used as a generic list close + routine. + +Arguments: struct dlist *list List to be closed + +Prototype: void sysfs_close_list(struct dlist *list) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_path_is_dir + +Description: Utility function to verify if a given path is to a directory. + +Arguments: unsigned char *path Path to verify + +Returns: 0 on success, 1 on error + - EINVAL for invalid arguments + +Prototype: int sysfs_path_is_dir(unsigned char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_path_is_file + +Description: Utility function to verify if a given path is to a file. + +Arguments: unsigned char *path Path to verify + +Returns: 0 on success, 1 on error + - EINVAL for invalid arguments + +Prototype: int sysfs_path_is_file(unsigned char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_path_is_link + +Description: Utility function to verify if a given path is to a link. + +Arguments: unsigned char *path Path to verify + +Returns: 0 on success, 1 on error + - EINVAL for invalid arguments + +Prototype: int sysfs_path_is_link(unsigned char *path) +------------------------------------------------------------------------------- + +6.2 Filesystem Functions +------------------------ + +Libsysfs provides a set of functions to open, read, and close directories +and attributes/files in sysfs. These functions mirror their filesystem +function counterparts. + +6.2.1 Attribute Functions +------------------------- + +Along with the usual open, read, and close functions, libsysfs provides +a couple other functions for accessing attribute values. + +------------------------------------------------------------------------------- +Name: sysfs_open_attribute + +Description: Opens up a file in sysfs and creates a sysfs_attribute + structure. File isn't read with this function. + +Arguments: const unsigned char *path File/Attribute's path + +Returns: struct sysfs_attribute * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_open_attribute + (const unsigned char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_attribute + +Description: Cleans up and closes sysfs_attribute structure. + +Arguments: struct sysfs_attribute *sysattr Attribute to close + +Prototype: void sysfs_close_attribute(struct sysfs_attribute *sysattr) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_read_dir_attributes + +Description: Reads the given sysfs_directory to create a list of attributes. + +Arguments: struct sysfs_directory *sysdir sysfs_directory whose + attributes to read + +Returns: struct dlist * of attributes on success + NULL with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: struct dlist *sysfs_read_dir_attributes + (struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_refresh_attributes + +Description: Given a list of attributes, this function refreshes the values + of attributes in the list. + +Arguments: struct dlist *attrlist list of attributes to refresh + +Returns: 0 with success. + 1 with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: int sysfs_refresh_attributes(struct dlist *attrlist) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_read_attribute + +Description: Reads the supplied attribute. Since the maximum transfer + from a sysfs attribute is a pagesize, function reads in + up to a page from the file and stores it in the "value" + field in the attribute. + +Arguments: struct sysfs_attribute *sysattr Attribute to read + +Returns: 0 with success. + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_read_attribute(struct sysfs_attribute *sysattr) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_write_attribute + +Description: Writes to the supplied attribute. Function validates if attribute + is writable, and writes the new value to the attribute. Value to + write as well as its length is user supplied. In case the length + written is not equal to the length requested to be written, the + original value is restored and an error is returned. + +Arguments: struct sysfs_attribute *sysattr Attribute to write to + const unsigned char *new_value New value for the attribute + size_t len Length of "new_value" + +Returns: 0 with success. + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_write_attribute(struct sysfs_attribute *sysattr, + const unsigned char *new_value, size_t len) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_read_attribute_value + +Description: Given a path to a specific attribute, function reads and + returns its value to the supplied value buffer. + +Arguments: const unsigned char *attrpath Attribute path to read + unsigned char *value Buffer to place attribute's value + size_t vsize Size of buffer + +Returns: 0 with success. + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_read_attribute_value(const unsigned char *attrpath, + unsigned char *value, size_t vsize) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_value_from_attributes + +Description: Function takes a single or linked list of sysfs attribute + structures and returns the value of the specified attribute + name. + +Arguments: struct sysfs_attribute *attr + Attribute list to search through + const unsigned char *name Name of attribute to return value + +Returns: unsigned char * attribute value with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: unsigned char *sysfs_get_value_from_attributes + (struct sysfs_attribute *attr, const unsigned char * name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_directory_attribute + +Description: Function walks the list of attributes for the given sysfs + directory and returns the sysfs_attribute structure for + the specified attribute name. + +Arguments: struct sysfs_directory *dir Directory in which to search + unsigned char *attrname Attribute name to look for + +Returns: struct sysfs_attribute on success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_get_directory_attribute + (struct sysfs_directory *dir, unsigned char *attrname) +------------------------------------------------------------------------------- + + +6.2.2 Link Functions +-------------------- + +Sysfs contains many symbolic links, like bus links to bus devices. Libsysfs +treats links differently than directories due to processing differences. A +link in the /sys/bus/"busname"/devices/ directory indicates a device in the +/sys/devices directory. Through links we give the functionality to know +what is and what isn't a link and the ability to query the links target. + +------------------------------------------------------------------------------- +Name: sysfs_open_link + +Description: Opens a directory link. + +Arguments: const unsigned char *linkpath Path to link + +Returns: struct sysfs_link * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_link *sysfs_open_link + (const unsigned char *linkpath) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_link + +Description: Closes a directory link structure. + +Arguments: struct sysfs_link *ln Link to close + +Prototype: void sysfs_close_link(struct sysfs_link *ln) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_read_dir_links + +Description: Reads the given sysfs_directory to create a list of links. + +Arguments: struct sysfs_directory *sysdir sysfs_directory whose + links to read + +Returns: struct dlist * of links with success + NULL with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: struct dlist *sysfs_read_dir_links + (struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_directory_link + +Description: Function walks the list of links for the given sysfs directory + and returns the sysfs_link structure for the specified link + name. + +Arguments: struct sysfs_directory *dir Directory in which to search + unsigned char *linkname Link name to look for + +Returns: struct sysfs_link * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_link *sysfs_get_directory_link + (struct sysfs_directory *dir, unsigned char *linkname) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_subdirectory_link + +Description: Function walks the list of links for the given sysfs directory + and its subdirectories returns the sysfs_link structure for + the specified link name. + +Arguments: struct sysfs_directory *dir Directory in which to search + unsigned char *linkname Link name to look for + +Returns: struct sysfs_link * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_link *sysfs_get_subdirectory_link + (struct sysfs_directory *dir, unsigned char *linkname) +------------------------------------------------------------------------------- + + +6.2.3 Directory Functions +------------------------- + +Sysfs directories can represent every directory under sysfs. The structures +keep track of subdirectories, links, and files. Like opendir, readdir, and +closedir, libsysfs provides open, read, and close functions for working with +sysfs directories. Open creates the sysfs_directory structure. Read reads in +its contents - like subdirectories, links, and files. Close cleans it all +up. + +------------------------------------------------------------------------------- +Name: sysfs_open_directory + +Description: Opens a sysfs directory at a specific path + +Arguments: const unsigned char *path Directory path to open + +Returns: struct sysfs_directory * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_directory *sysfs_open_directory + (const unsigned char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_directory + +Description: Closes specific directory, its subdirectories, links, and + files. + +Arguments: struct sysfs_directory *sysdir Directory to close + +Prototype: void sysfs_close_directory(struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_read_dir_subdirs + +Description: Reads the given sysfs_directory to create a list of subdirs. + +Arguments: struct sysfs_directory *sysdir sysfs_directory whose + subdirs have to be read + +Returns: struct dlist * of links with success + NULL with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: struct dlist *sysfs_read_dir_subdirs + (struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_read_directory + +Description: Read the supplied directory. Reading fills in the directory's + contents like subdirectories, links, and attributes. + +Arguments: struct sysfs_directory *sysdir Directory to read + +Returns: 0 with success. + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_read_directory(struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_read_all_subdirs + +Description: Reads all subdirs under a given supplied directory. + +Arguments: struct sysfs_directory *sysdir Directory to read + +Returns: 0 with success. + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_subdirectory + +Description: Function walks the directory tree for the given directory and + returns a sysfs_directory structure for the specified directory + name. + +Arguments: struct sysfs_directory *dir Directory in which to search + unsigned char *subname Name of directory to look for + +Returns: struct sysfs_directory with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments +------------------------------------------------------------------------------- + + +6.3 Bus Functions +----------------- + +The library provides a functions for viewing buses represented in sysfs. +The sysfs_open_bus opens a bus in the /sys/bus directory, such as "pci", +"usb", or "scsi". The open command returns a sysfs_bus structure that +contains a list of the bus' devices. The sysfs_close_bus function is +used to clean up the bus structure. Given a device or a driver, +functions are provided to determine what bus they are on. + +------------------------------------------------------------------------------- +Name: sysfs_open_bus + +Description: Function opens up one of the buses represented in sysfs in + the /sys/bus directory. It returns a sysfs_bus structure + that includes a list of bus devices and drivers. + +Arguments: const unsigned char *name Bus name to open, like "pci"... + +Returns: struct sysfs_bus * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_bus *sysfs_open_bus(const unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_bus + +Description: Function closes up the sysfs_bus structure including its + devices, drivers, and directory. + +Arguments: sysfs_bus *bus Bus structure to close + +Prototype: void sysfs_close_bus(struct sysfs_bus *bus) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_bus_devices + +Description: Function returns a list of devices that are registered with + this bus. + +Arguments: struct sysfs_bus *bus Bus whose devices list to return + +Returns: struct dlist * of sysfs_devices on success + NULL with error. Errno will be sent with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_bus_drivers + +Description: Function returns a list of drivers that are registered with + this bus. + +Arguments: struct sysfs_bus *bus Bus whose drivers list to return + +Returns: struct dlist * of sysfs_drivers on success + NULL with error. Errno will be sent with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_bus_device + +Description: Function takes a sysfs_bus structure(obtained on a successful + return from a sysfs_open_bus() call) and looks for the given + device on this bus. On success, it returns a sysfs_device + structure corresponding to the device. + +Arguments: struct sysfs_bus *bus Bus structure on which to search + unsigned char *id Device to look for + +Returns: struct sysfs_device * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_get_bus_device + (struct sysfs_bus *bus, unsigned char *id) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_bus_driver + +Description: Function takes a sysfs_bus structure (obtained on a successful + return from a sysfs_open_bus() call) and looks for the given + driver on this bus. On success, it returns a sysfs_driver + structure corresponding to the driver. + +Arguments: struct sysfs_bus *bus Bus structure on which to search + unsigned char *drvname Driver to look for + +Returns: struct sysfs_driver * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_get_bus_driver + (struct sysfs_bus *bus, unsigned char *drvname) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_bus_attributes + +Description: Function takes a sysfs_bus structure and returns a list of + attributes for the bus. + +Arguments: struct sysfs_bus *bus Bus for which attributes are required + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_bus_attribute + +Description: Function takes a sysfs_bus structure and looks for the required + attribute on the bus. On success, it returns a sysfs_attribute + structure corresponding to the given attribute. + +Arguments: struct sysfs_bus *bus Bus structure on which to search + unsigned char *attrname Attribute to look for + +Returns: struct sysfs_attribute * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_get_bus_attribute + (struct sysfs_bus *bus, unsigned char *attrname) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_bus_device + +Description: Given the name of the bus on which to look for, this function + locates a given device on the bus and returns a sysfs_device + structure corresponding to the requested device. + + NOTE: + 1. The sysfs_device structure obtained upon successful return + from this function has to be closed by calling + sysfs_close_device(). + +Arguments: unsigned char *busname Bus on which to search + unsigned char *dev_id Name of the device to look for + +Returns: struct sysfs_device * on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_open_bus_device + (unsigned char *busname, unsigned char *dev_id) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_find_driver_bus + +Description: Given the name of a driver, this function finds the name of the + bus the driver is on + +Arguments: const unsigned char *driver Name of the driver to look for + unsigned char *busname Buffer to return the bus name + size_t bsize Size of the "busname" buffer + +Returns: 0 with success. + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_find_driver_bus(const unsigned char *driver, + unsigned char *busname, size_t bsize) +------------------------------------------------------------------------------- + + +6.4 Class Functions +------------------- + +Libsysfs provides functions to open sysfs classes and their class devices. +These functions too operate with open and close, close must be called to +clean up the class structures. Given a class device name, functions are +provided to determine what class they belong to. Once a class device +name and the class it belongs to is known, a function to open the +class device is provided. This method can be used when details of +a single class device is required. + +------------------------------------------------------------------------------- +Name: sysfs_open_class + +Description: Function opens up one of the classes represented in sysfs in + the /sys/class directory. It returns a sysfs_class structure + that includes a list of class devices. + +Arguments: const unsigned char *name Class name to open, like "net".. + +Returns: struct sysfs_class * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_class *sysfs_open_class(const unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_class + +Description: Function closes up the sysfs_class structure including its + class devices. + +Arguments: sysfs_class *class Class structure to close + +Prototype: void sysfs_close_class(struct sysfs_class *class); +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_class_device_path + +Description: Function opens up one of the class devices represented in + sysfs in sysfs/class/"class"/ directory. It returns a + sysfs_class_device structure. + +Arguments: const unsigned char *path Path to class device + +Returns: struct sysfs_class_device * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_class_device *sysfs_open_class_device_path + (const unsigned char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_class_device + +Description: Function closes up the sysfs_class_device structure. + +Arguments: sysfs_class_device *dev Class device structure to close + +Prototype: void sysfs_close_class_device(struct sysfs_class_device *dev) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_class_device + +Description: Function takes a sysfs_class structure(obtained on a successful + return from a sysfs_open_class() call) and looks for the given + device in this class. On success, it returns a sysfs_class_device + structure corresponding to the class device. + +Arguments: struct sysfs_class *class Class on which to search + unsigned_char *name Class device "name" to look for + +Returns: struct sysfs_class_device * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_class_device *sysfs_get_class_device + (struct sysfs_class *class, unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_class_devices + +Description: Function returns a list of class devices for the given class. + +Arguments: struct sysfs_class *cls Class whose class device list + is required + +Returns: struct dlist * of sysfs_class_devices on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_class_device + +Description: Given the name of the class on which to look for, this function + locates a given class device and returns a sysfs_class_device + structure corresponding to the requested class device. + + NOTE: + 1. The sysfs_class_device structure obtained upon successful + return from this function has to be closed by calling + sysfs_close_class_device(). + 2. Class this device belongs to must be known prior to calling + this function. + +Arguments: const unsigned char *classname Class on which to search + unsigned char *name Class device "name" to open + +Returns: struct sysfs_class_device * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_class_device *sysfs_open_class_device + (const unsigned char *classname, unsigned char *class) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_classdev_device + +Description: Function returns the sysfs_device reference (if present) for the + given class device. + +Arguments: struct sysfs_class_device *clsdev Class device whose + sysfs_device reference + is required + +Returns: struct sysfs_device * on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_get_classdev_device + (struct sysfs_class_device *clsdev) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_classdev_driver + +Description: Function returns the sysfs_driver reference (if present) for the + given class device. + +Arguments: struct sysfs_class_device *clsdev Class device whose + sysfs_driver reference + is required + +Returns: struct sysfs_driver * on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_driver *sysfs_get_classdev_driver + (struct sysfs_class_device *clsdev) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_classdev_parent + +Description: Function returns the sysfs_class_device reference for the parent + (if present) of the given class device. + +Arguments: struct sysfs_class_device *clsdev Class device whose + parent reference + is required + +Returns: struct sysfs_class_device * on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_class_device *sysfs_get_classdev_parent + (struct sysfs_class_device *clsdev) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_classdev_attributes + +Description: Function takes a sysfs_class_device structure and returns a list + of attributes for the class device. + +Arguments: struct sysfs_class_device *cdev Class device for which + attributes are required + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_classdev_attributes + (struct sysfs_class_device *cdev) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_classdev_attr + +Description: Searches supplied class device's attributes by name and returns + the attribute. + +Arguments: struct sysfs_class_device *clsdev Device to search + const unsigned char *name Attribute name to find + +Returns: struct sysfs_attribute * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_get_classdev_attr + (struct sysfs_class_device *clsdev, const unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_classdev_attr + +Description: Function takes as arguments, a the name of the class, the class + device name and the name of the required attribute. + + NOTE: + 1. The struct sysfs_attribute * obtained upon successful + return from this function has to be closed by making + a call to sysfs_close_attribute() + +Arguments: unsigned char *classname Class name on which to search + unsigned char *dev Name of the class device + unsigned char *attrib Attribute to open + +Returns: struct sysfs_attribute * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_write_classdev_attr + (const unsigned char *classname, const unsigned char *dev, + const unsigned char *attrib) +------------------------------------------------------------------------------- + + +6.5 Device Functions +-------------------- + +Devices represent everything in sysfs under /sys/devices, which is a +hierarchical view of system devices. Besides the expected open and +close functions, libsysfs provides open and close functions for +root devices. These functions recursively open or close a device +and all of its children. + +------------------------------------------------------------------------------- +Name: sysfs_open_device_path + +Description: Opens up a device at a specific path. It opens the device's + directory, reads the directory, and returns a sysfs_device + structure. + +Arguments: const unsigned char *path Path to device + +Returns: struct sysfs_device * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_open_device_path + (const unsigned char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_device + +Description: Function closes up the sysfs_device structure. + +Arguments: sysfs_device *dev Device structure to close + +Prototype: void sysfs_close_device(struct sysfs_device *dev) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_root_device + +Description: Function opens up one of the root devices represented in sysfs + in the /sys/devices directory. It returns a sysfs_root_device + structure that includes a list of devices in the tree. + +Arguments: const unsigned char *name Name of the root device to open + +Returns: struct sysfs_root_device * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_open_root_device + (const unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_root_device + +Description: Function closes up the sysfs_root_device structure including the + devices in the root device tree. + +Arguments: sysfs_device *root Root device structure to close + +Prototype: void sysfs_close_root_device(struct sysfs_root_device *root) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_device_parent + +Description: Function returns the sysfs_device reference for the parent + (if present) of the given sysfs_device. + +Arguments: struct sysfs_device *dev sysfs_device whose parent + reference is required + +Returns: struct sysfs_device * on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_get_device_parent + (struct sysfs_device *dev) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_root_devices + +Description: Function returns a list of devices under the given root device. + +Arguments: struct sysfs_root_device *root sysfs_root_device whose devices + list is required + +Returns: struct dlist * of sysfs_devices on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_root_devices + (struct sysfs_root_device *root) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_device_attr + +Description: Searches supplied device's attributes by name and returns + the attribute. + +Arguments: struct sysfs_device *dev Device to search + const unsigned char *name Attribute name to find + +Returns: struct sysfs_attribute * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_get_device_attr + (struct sysfs_device *dev, const unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_device_attributes + +Description: Function takes a sysfs_device structure and returns a list + of attributes for the device. + +Arguments: struct sysfs_device *device Device for which + attributes are required + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_device_attributes + (struct sysfs_device *device) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_device + +Description: Given the name of the bus on which to look for, this function + locates a given device and returns a sysfs_device structure + corresponding to the requested device. + +Arguments: const unsigned char *bus_id Device to look for + const unsigned char *bus Bus on which to search + +Returns: struct sysfs_device * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_open_device + (const unsigned char *bus_id, const unsigned char *bus) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_device_attr + +Description: Function takes as arguments, the bus on which to search for a + device, and an attribute of the device to open. + + NOTE: + 1. The struct sysfs_attribute * obtained upon successful + return from this function has to be closed by making + a call to sysfs_close_attribute() + +Arguments: unsigned char *bus Bus on which to search + unsigned char *bus_id Device to look for + unsigned char *attrib Name of the attribute to open + +Returns: struct sysfs_attribute * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_open_device_attr + (const unsigned char *bus, const unsigned char *bus_id, + const unsigned char *attrib) +------------------------------------------------------------------------------- + + +6.6 Driver Functions +-------------------- + +Drivers are represented in sysfs under the /sys/bus/xxx/drivers (xxx being +the bus type, such as "pci", "usb, and so on). Functions are provided to +open and close drivers. + +------------------------------------------------------------------------------- +Name: sysfs_open_driver_path + +Description: Opens driver at specific path. + +Arguments: const unsigned char *path Path to driver + +Returns: struct sysfs_driver * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_driver *sysfs_open_driver_path + (const unsigned char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_driver + +Description: Closes and cleans up sysfs_driver structure. + +Arguments: sysfs_driver *driver Driver structure to close + +Prototype: void sysfs_close_driver(struct sysfs_driver *driver) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_driver_devices + +Description: Function returns a list of devices that use this driver. + +Arguments: struct sysfs_driver *driver Driver whose devices list is + required + +Returns: struct dlist * of sysfs_devices on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_driver_devices + (struct sysfs_driver *driver) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_driver_device + +Description: Function returns a sysfs_device reference for the device with + "name" that uses this driver + +Arguments: struct sysfs_driver *driver Driver on which to search + const unsigned char *name Name of the device to look for + +Returns: struct sysfs_device * corresponding to "name" on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_driver_device + (struct sysfs_driver *driver, const unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_driver_attr + +Description: Searches supplied driver's attributes by name and returns + the attribute. + +Arguments: struct sysfs_driver *drv Driver to search + const unsigned char *name Attribute name to find + +Returns: struct sysfs_attribute * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_get_driver_attr + (struct sysfs_driver *drv, const unsigned char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_driver_attributes + +Description: Function takes a sysfs_driver structure and returns a list + of attributes for the driver. + +Arguments: struct sysfs_driver *driver Driver for which + attributes are required + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_driver_attributes + (struct sysfs_driver *driver) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_driver + +Description: Given the name of the bus on which to look for, this function + locates a given driver and returns a sysfs_driver structure + corresponding to the requested device. + + NOTE: + 1. The sysfs_driver structure obtained upon successful return + from this function has to be closed by calling + sysfs_close_driver_by_name(). + 2. Bus on which to look for this driver should be known prior + to calling this function. Use sysfs_find_driver_bus() + to determine this. + +Arguments: const unsigned char *drv_name Driver to look for + const unsigned char *bus Bus on which to search + size_t bsize Size of "bus" + +Returns: struct sysfs_driver * with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_driver *sysfs_open_driver + (const unsigned char *drv_name, + const unsigned char *bus, size_t bsize) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_driver_links + +Description: Function returns a list of links for a given driver + +Arguments: struct sysfs_driver *driver Driver to get links from + +Returns: struct dlist * of links on success + NULL with error + +Prototype: struct dlist *sysfs_get_driver_links + (struct sysfs_driver *driver) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_open_driver_attr + +Description: Function takes as arguments, the bus the driver is registered + on, the driver name and the name of the attribute to open. + + NOTE: + 1. The struct sysfs_attribute * obtained upon successful + return from this function has to be closed by making + a call to sysfs_close_attribute() + +Arguments: unsigned char *bus Bus on which driver is present + unsigned char *drv Driver to look for + unsigned char *attrib Name of the attribute to open + +Returns: struct sysfs_attribute * with success. + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_attribute *sysfs_open_driver_attr + (const unsigned char *bus, const unsigned char *drv, + const unsigned char *attrib) +------------------------------------------------------------------------------- + + +7. Navigating a dlist +--------------------- + +Libsysfs uses (yet another) list implementation thanks to Eric J Bohm. + +Some library functions return a dlist of devices/drivers/attributes, etc. +To navigate the list returned the macro "dlist_for_each_data" is to be used. + +------------------------------------------------------------------------------ +Function/Macro name: dlist_for_each_data + +Description: Walk the given list, returning a known data type/ + structure in each iteration. + +Arguments: struct dlist *list List pointer + data_iterator Data type/structure variable + contained in the list + datatype Data type/structure contained + in the list + +Returns: On each iteration, "data_iterator" will contain a list + element of "datatype" + +Usage example: The function sysfs_get_classdev_attributes() returns a + dlist of attributes. To navigate the list: + + struct sysfs_attribute *attr = NULL; + struct dlist *attrlist = NULL; + . + . + . + attrlist = sysfs_get_classdev_attributes + (struct sysfs_class_device *cdev) + if (attrlist != NULL) { + dlist_for_each_data(attrlist, attr, + struct sysfs_attribute) { + . + . + . + } + } +------------------------------------------------------------------------------- + + +8. Usage +-------- + +Accessing devices through libsysfs is supposed to mirror accessing devices +in the filesystem it represents. Here's a typical order of operation: + + - get sysfs mount point + - "open" sysfs category, ie. bus, class, or device + - work with category + - "close" sysfs category + + +9. Conclusion +------------- + +Libsysfs is meant to provide a stable application programming interface to +sysfs. Applications can depend upon the library to access system devices +and functions exposed through sysfs. From ff3633bf9d192c46c457cc3819dc27ff2807ed0d Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Wed, 17 Dec 2003 19:05:25 -0800 Subject: [PATCH 0305/4284] [PATCH] fix scsi_id segfault with udev-009 Scsi_id hasn't been changed to use the latest libsysfs changes. The "directory" in the sysfs_class_device is now considered "private" and only should be accessed using functions. Treating the structures as handles lets us only load information when it's needed, reducing caching or stale information and also helping performance. Here's the problem. static inline char *sysfs_get_attr(struct sysfs_class_device *dev, const char *attr) { return sysfs_get_value_from_attributes(dev->directory->attributes, attr); } Please try this quick fix: --- extras/scsi_id/scsi_id.c | 2 +- extras/scsi_id/scsi_id.h | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index df18271b48..3a34643c81 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -133,7 +133,7 @@ static int sysfs_is_bus(const char *sysfs_path, const char *bus) return -1; snprintf(bus_dev_name, MAX_NAME_LEN, "%s/%s/%s/%s/%s", sysfs_mnt_path, - SYSFS_BUS_DIR, bus, SYSFS_DEVICES_NAME, bus_id); + SYSFS_BUS_NAME, bus, SYSFS_DEVICES_NAME, bus_id); if (stat(sysfs_path, &stat_buf)) return -1; diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index eb9498ab71..cb27e88a5f 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -42,8 +42,14 @@ static inline char *sysfs_get_attr(struct sysfs_class_device *dev, const char *attr) { - return sysfs_get_value_from_attributes(dev->directory->attributes, - attr); + struct dlist *attributes = NULL; + + attributes = sysfs_get_classdev_attributes(dev); + + if (attributes == NULL) + return NULL; + + return sysfs_get_value_from_attributes(attributes, attr); } extern int scsi_get_serial (struct sysfs_class_device *scsi_dev, From a81805b9af899087f3d8367721ac0a51460f692e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 17 Dec 2003 22:33:29 -0800 Subject: [PATCH 0306/4284] [PATCH] bug in udev-remove.c Uups, we have a bug in udev-remove.c. udev segfaults with NULL-pointer, if the device is not in the database: ./test.block: line 29: 4844 Segmentation fault $BIN block Dec 17 22:47:42 pim udev[4882]: udev_remove_device: '/block/sdy' not found in database, falling back on default name Dec 17 22:47:42 pim udev[4882]: udev_remove_device: name is '(null)' --- udev-remove.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/udev-remove.c b/udev-remove.c index 0886c23343..dad4a98570 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -118,8 +118,8 @@ static int delete_node(struct udevice *dev) */ int udev_remove_device(char *path, char *subsystem) { - char name[100]; struct udevice *dev; + struct udevice device; char *temp; dev = udevdb_get_dev(path); @@ -128,13 +128,15 @@ int udev_remove_device(char *path, char *subsystem) temp = strrchr(path, '/'); if (temp == NULL) return -ENODEV; - strncpy(name, &temp[1], sizeof(name)); + memset(&device, 0, sizeof(device)); + dev = &device; + strncpy(device.name, &temp[1], sizeof(device.name)); } dbg("name is '%s'", dev->name); udevdb_delete_dev(path); - sysbus_send_remove(name, path); + sysbus_send_remove(dev->name, path); return delete_node(dev); } From d077e50c927209c4157f2696d15f0d1286ada411 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Dec 2003 22:41:04 -0800 Subject: [PATCH 0307/4284] [PATCH] clean up the stand-alone tests to work properly on other people's machines. --- test/label_test | 3 +++ test/modifier_test | 3 +++ test/replace_test | 3 +++ test/topo_test | 3 +++ 4 files changed, 12 insertions(+) diff --git a/test/label_test b/test/label_test index 09ccab366e..2e05692581 100644 --- a/test/label_test +++ b/test/label_test @@ -18,6 +18,8 @@ udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF +mkdir udev + export ACTION=add export DEVPATH=block/sda @@ -43,3 +45,4 @@ ls -l udev rm $RULES rm $CONFIG +rm -rf udev diff --git a/test/modifier_test b/test/modifier_test index bbe072e58c..9af946e598 100644 --- a/test/modifier_test +++ b/test/modifier_test @@ -18,6 +18,8 @@ udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF +mkdir udev + export ACTION=add export DEVPATH=block/sda @@ -42,3 +44,4 @@ ls udev rm $RULES rm $CONFIG +rm -rf udev diff --git a/test/replace_test b/test/replace_test index 375c8dced3..9ed366e358 100644 --- a/test/replace_test +++ b/test/replace_test @@ -18,6 +18,8 @@ udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF +mkdir udev + export DEVPATH=class/tty/ttyUSB0 export ACTION=add @@ -30,3 +32,4 @@ ls -l udev rm $RULES rm $CONFIG +rm -rf udev diff --git a/test/topo_test b/test/topo_test index 9225685c8c..385f415893 100644 --- a/test/topo_test +++ b/test/topo_test @@ -18,6 +18,8 @@ udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF +mkdir udev + export ACTION=add export DEVPATH=block/sda @@ -42,3 +44,4 @@ ls udev rm $RULES rm $CONFIG +rm -rf udev From 7ecb8d23f371a38cd918334ee7bf8383f1807ddb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 19 Dec 2003 18:08:39 -0800 Subject: [PATCH 0308/4284] [PATCH] remove unneeded TODO and FIXME entry Thanks to Kay for pointing it out to me. --- TODO | 1 - namedev.c | 1 - 2 files changed, 2 deletions(-) diff --git a/TODO b/TODO index 47275873c8..d0d0bec4d9 100644 --- a/TODO +++ b/TODO @@ -6,7 +6,6 @@ greg k-h greg@kroah.com -- fix kernel name logic to handle devices like sdaj and such. - more documentation (can never have too much.) - better partition support (it's a hack right now, maybe new libsysfs changes can help out a lot here.) diff --git a/namedev.c b/namedev.c index 212d6bb68d..58986e25c2 100644 --- a/namedev.c +++ b/namedev.c @@ -189,7 +189,6 @@ static void build_kernel_number(struct sysfs_class_device *class_dev, struct ude { char *dig; - /* FIXME, figure out how to handle stuff like sdaj which will not work right now. */ dig = class_dev->name + strlen(class_dev->name); while (isdigit(*(dig-1))) dig--; From a56ef382869bb76ade6d26cd7e8adc983ca3f89e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Dec 2003 18:29:01 -0800 Subject: [PATCH 0309/4284] [PATCH] udev-remove.c cleanups I've moved the malloc out of the udevdb into udev-remove to free the struct after use and not to allocate a different struct in the case the device is not in the data base. I seems a bit easier to read. --- udev-remove.c | 19 ++++++++++++------- udevdb.c | 15 ++++----------- udevdb.h | 2 +- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/udev-remove.c b/udev-remove.c index dad4a98570..6d7e2ad22a 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -119,18 +119,21 @@ static int delete_node(struct udevice *dev) int udev_remove_device(char *path, char *subsystem) { struct udevice *dev; - struct udevice device; char *temp; + int retval; - dev = udevdb_get_dev(path); - if (dev == NULL) { + dev = malloc(sizeof(*dev)); + if (dev == NULL) + return -ENOMEM; + memset(dev, 0, sizeof(*dev)); + + retval = udevdb_get_dev(path, dev); + if (retval) { dbg("'%s' not found in database, falling back on default name", path); temp = strrchr(path, '/'); if (temp == NULL) return -ENODEV; - memset(&device, 0, sizeof(device)); - dev = &device; - strncpy(device.name, &temp[1], sizeof(device.name)); + strncpy(dev->name, &temp[1], sizeof(dev->name)); } dbg("name is '%s'", dev->name); @@ -138,5 +141,7 @@ int udev_remove_device(char *path, char *subsystem) sysbus_send_remove(dev->name, path); - return delete_node(dev); + retval = delete_node(dev); + free(dev); + return retval; } diff --git a/udevdb.c b/udevdb.c index 5be3c25151..bbbeddad47 100644 --- a/udevdb.c +++ b/udevdb.c @@ -62,29 +62,22 @@ int udevdb_add_dev(const char *path, const struct udevice *dev) return tdb_store(udevdb, key, data, TDB_REPLACE); } -struct udevice *udevdb_get_dev(const char *path) +int udevdb_get_dev(const char *path, struct udevice *dev) { TDB_DATA key, data; - struct udevice *dev; if (path == NULL) - return NULL; + return -ENODEV; key.dptr = (void *)path; key.dsize = strlen(path) + 1; data = tdb_fetch(udevdb, key); if (data.dptr == NULL || data.dsize == 0) - return NULL; - - dev = malloc(sizeof(*dev)); - if (dev == NULL) - goto exit; + return -ENODEV; memcpy(dev, data.dptr, sizeof(*dev)); -exit: - free(data.dptr); - return dev; + return 0; } int udevdb_delete_dev(const char *path) diff --git a/udevdb.h b/udevdb.h index 97e1f9bc40..d6c58ae766 100644 --- a/udevdb.h +++ b/udevdb.h @@ -13,7 +13,7 @@ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); extern int udevdb_add_dev(const char *path, const struct udevice *dev); -extern struct udevice *udevdb_get_dev(const char *path); +extern int udevdb_get_dev(const char *path, struct udevice *dev); extern int udevdb_delete_dev(const char *path); #endif /* _UDEVDB_H_ */ From 7591c18a8f3460d3e7cab85d02915c4b51638b5c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Dec 2003 18:29:05 -0800 Subject: [PATCH 0310/4284] [PATCH] don't overwrite old config on install Here is a patch for the Makefile to look for a already installed config and not to overwrite it. --- Makefile | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index c2ed659531..3e220b47d0 100644 --- a/Makefile +++ b/Makefile @@ -274,18 +274,31 @@ uninstall-dbus-policy: - endif -install: install-dbus-policy all $(GEN_CONFIGS) - $(INSTALL) -d $(DESTDIR)$(udevdir) +install-config: $(GEN_CONFIGS) $(INSTALL) -d $(DESTDIR)$(configdir) + @if [ ! -r $(DESTDIR)$(configdir)udev.conf ]; then \ + echo $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir); \ + $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir); \ + fi + @if [ ! -r $(DESTDIR)$(configdir)udev.rules ]; then \ + echo $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir); \ + $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir); \ + fi + @if [ ! -r $(DESTDIR)$(configdir)udev.permissions ]; then \ + echo $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir); \ + $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir); \ + fi + + + +install: install-config install-dbus-policy all + $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 - $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir) - $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir) - $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir) - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - - ln -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug + - ln -f -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ From bcbe2d8e7d4ccd975e79d0c7defbe1d64d1b129c Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Fri, 19 Dec 2003 18:29:10 -0800 Subject: [PATCH 0311/4284] [PATCH] libsysfs 0.4.0 patch Ananth released sysfsutils 0.4.0 last night, I'm sure you saw the email. Here's a patch with the latest changes from the pre-patch I already gave you. It includes sysfs_get_device_parent(), which you said you needed. I've run your test scripts and I've built scsi_id. Please play around with this and check it out. There are quite a few changes. Please do not access structure pointers, like sysfs_device's parent, directly like dev->parent. Please use the "get" function to retrieve. The functions load things on demand and refresh views under the covers. --- extras/scsi_id/scsi_id.c | 4 +- libsysfs/libsysfs.h | 17 ++++---- libsysfs/sysfs_bus.c | 50 +++++++++++++---------- libsysfs/sysfs_class.c | 80 ++++++++++++++++++++---------------- libsysfs/sysfs_device.c | 88 ++++++++++++++++++++++++++++++---------- libsysfs/sysfs_dir.c | 71 ++++++++++++++------------------ libsysfs/sysfs_driver.c | 72 ++++++++++++++++---------------- libsysfs/sysfs_utils.c | 26 ++++++------ udev-add.c | 4 +- 9 files changed, 236 insertions(+), 176 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 3a34643c81..6bb41132de 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -158,7 +158,7 @@ static int get_major_minor(const char *devpath, int *major, int *minor) char *dev; dprintf("%s\n", devpath); - class_dev = sysfs_open_class_device(devpath); + class_dev = sysfs_open_class_device_path(devpath); if (!class_dev) { log_message(LOG_WARNING, "open class %s failed: %s\n", devpath, strerror(errno)); @@ -708,7 +708,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) return 1; } - scsi_dev = sysfs_open_class_device(full_dev_path); + scsi_dev = sysfs_open_class_device_path(full_dev_path); if (!scsi_dev) { log_message(LOG_WARNING, "open class %s failed: %s\n", full_dev_path, strerror(errno)); diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index aca25772b5..2ffe1005cc 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -182,7 +182,9 @@ extern struct sysfs_attribute *sysfs_get_directory_attribute /* sysfs driver access */ extern void sysfs_close_driver(struct sysfs_driver *driver); -extern struct sysfs_driver *sysfs_open_driver(const unsigned char *path); +extern struct sysfs_driver *sysfs_open_driver + (const unsigned char *drv_name, const unsigned char *bus_name); +extern struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path); extern struct sysfs_attribute *sysfs_get_driver_attr (struct sysfs_driver *drv, const unsigned char *name); extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); @@ -199,12 +201,13 @@ extern struct sysfs_root_device *sysfs_open_root_device (const unsigned char *name); extern struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root); extern void sysfs_close_device(struct sysfs_device *dev); -extern struct sysfs_device *sysfs_open_device(const unsigned char *path); +extern struct sysfs_device *sysfs_open_device + (const unsigned char *bus_id, const unsigned char *bus); +extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev); +extern struct sysfs_device *sysfs_open_device_path(const unsigned char *path); extern struct sysfs_attribute *sysfs_get_device_attr (struct sysfs_device *dev, const unsigned char *name); extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); -extern struct sysfs_device *sysfs_open_device_by_id - (const unsigned char *bus_id, const unsigned char *bus); extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, const unsigned char *bus_id, const unsigned char *attrib); @@ -227,8 +230,10 @@ extern int sysfs_find_driver_bus(const unsigned char *driver, /* generic sysfs class access */ extern void sysfs_close_class_device(struct sysfs_class_device *dev); -extern struct sysfs_class_device *sysfs_open_class_device +extern struct sysfs_class_device *sysfs_open_class_device_path (const unsigned char *path); +extern struct sysfs_class_device *sysfs_open_class_device + (const unsigned char *class, const unsigned char *name); extern struct sysfs_device *sysfs_get_classdev_device (struct sysfs_class_device *clsdev); extern struct sysfs_driver *sysfs_get_classdev_driver @@ -240,8 +245,6 @@ extern struct sysfs_class *sysfs_open_class(const unsigned char *name); extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); extern struct sysfs_class_device *sysfs_get_class_device (struct sysfs_class *class, unsigned char *name); -extern struct sysfs_class_device *sysfs_open_class_device_by_name - (const unsigned char *class, const unsigned char *name); extern struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *cdev); extern struct sysfs_attribute *sysfs_get_classdev_attr diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 3e6c22bbb1..d9da0f84cf 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -121,16 +121,20 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) return NULL; } - dlist_for_each_data(devdir->links, curl, struct sysfs_link) { - bdev = sysfs_open_device(curl->target); - if (bdev == NULL) { - dprintf("Error opening device at %s\n", curl->target); - continue; + if (devdir->links != 0) { + dlist_for_each_data(devdir->links, curl, struct sysfs_link) { + bdev = sysfs_open_device_path(curl->target); + if (bdev == NULL) { + dprintf("Error opening device at %s\n", + curl->target); + continue; + } + if (bus->devices == NULL) + bus->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_dev); + dlist_unshift(bus->devices, bdev); } - if (bus->devices == NULL) - bus->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), sysfs_close_dev); - dlist_unshift(bus->devices, bdev); } sysfs_close_directory(devdir); @@ -165,16 +169,21 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) sysfs_close_directory(drvdir); return NULL; } - dlist_for_each_data(drvdir->subdirs, cursub, struct sysfs_directory) { - driver = sysfs_open_driver(cursub->path); - if (driver == NULL) { - dprintf("Error opening driver at %s\n", cursub->path); - continue; + if (drvdir->subdirs != NULL) { + dlist_for_each_data(drvdir->subdirs, cursub, + struct sysfs_directory) { + driver = sysfs_open_driver_path(cursub->path); + if (driver == NULL) { + dprintf("Error opening driver at %s\n", + cursub->path); + continue; + } + if (bus->drivers == NULL) + bus->drivers = dlist_new_with_delete + (sizeof(struct sysfs_driver), + sysfs_close_drv); + dlist_unshift(bus->drivers, driver); } - if (bus->drivers == NULL) - bus->drivers = dlist_new_with_delete - (sizeof(struct sysfs_driver), sysfs_close_drv); - dlist_unshift(bus->drivers, driver); } sysfs_close_directory(drvdir); return (bus->drivers); @@ -347,10 +356,9 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, dprintf("Error getting sysfs mount point\n"); return NULL; } - + if (sysfs_trailing_slash(path) == 0) strcat(path, "/"); - strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, busname); @@ -359,7 +367,7 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, strcat(path, "/"); strcat(path, dev_id); - rdev = sysfs_open_device(path); + rdev = sysfs_open_device_path(path); if (rdev == NULL) { dprintf("Error getting device %s on bus %s\n", dev_id, busname); diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 169600d5fd..16eaf6e514 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -130,11 +130,12 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) } /** - * sysfs_open_class_device: Opens and populates class device + * sysfs_open_class_device_path: Opens and populates class device * @path: path to class device. * returns struct sysfs_class_device with success and NULL with error. */ -struct sysfs_class_device *sysfs_open_class_device(const unsigned char *path) +struct sysfs_class_device *sysfs_open_class_device_path + (const unsigned char *path) { struct sysfs_class_device *cdev = NULL; @@ -184,22 +185,24 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) return NULL; } - if ((sysfs_read_dir_subdirs(cls->directory) != 0) - || cls->directory->subdirs == NULL) + if ((sysfs_read_dir_subdirs(cls->directory)) != 0) return NULL; - dlist_for_each_data(cls->directory->subdirs, cur, - struct sysfs_directory) { - dev = sysfs_open_class_device(cur->path); - if (dev == NULL) { - dprintf("Error opening device at %s\n", cur->path); - continue; - } - if (cls->devices == NULL) - cls->devices = dlist_new_with_delete + if (cls->directory->subdirs != NULL) { + dlist_for_each_data(cls->directory->subdirs, cur, + struct sysfs_directory) { + dev = sysfs_open_class_device_path(cur->path); + if (dev == NULL) { + dprintf("Error opening device at %s\n", + cur->path); + continue; + } + if (cls->devices == NULL) + cls->devices = dlist_new_with_delete (sizeof(struct sysfs_class_device), sysfs_close_cls_dev); - dlist_unshift(cls->devices, dev); + dlist_unshift(cls->devices, dev); + } } return cls->devices; } @@ -223,7 +226,6 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) dprintf("Sysfs not supported on this system\n"); return NULL; } - if (sysfs_trailing_slash(classpath) == 0) strcat(classpath, "/"); @@ -307,7 +309,7 @@ struct sysfs_device *sysfs_get_classdev_device if (devlink == NULL) return NULL; - clsdev->sysdevice = sysfs_open_device(devlink->target); + clsdev->sysdevice = sysfs_open_device_path(devlink->target); if (clsdev->sysdevice == NULL) return NULL; if (clsdev->driver != NULL) @@ -343,7 +345,7 @@ struct sysfs_driver *sysfs_get_classdev_driver } drvlink = sysfs_get_directory_link(clsdev->directory, "driver"); if (drvlink != NULL) { - clsdev->driver = sysfs_open_driver(drvlink->target); + clsdev->driver = sysfs_open_driver_path(drvlink->target); if (clsdev->driver == NULL) return NULL; @@ -401,7 +403,7 @@ static int get_blockdev_parent(struct sysfs_class_device *clsdev) goto errout; *c = '\0'; - clsdev->parent = sysfs_open_class_device(parent_path); + clsdev->parent = sysfs_open_class_device_path(parent_path); if (clsdev->parent == NULL) { dprintf("Error opening the parent class device at %s\n", parent_path); @@ -482,7 +484,7 @@ static int get_classdev_path(const unsigned char *classname, } /** - * sysfs_open_class_device_by_name: Locates a specific class_device and returns it. + * sysfs_open_class_device: Locates a specific class_device and returns it. * Class_device must be closed using sysfs_close_class_device * @classname: Class to search * @name: name of the class_device @@ -490,7 +492,7 @@ static int get_classdev_path(const unsigned char *classname, * NOTE: * Call sysfs_close_class_device() to close the class device */ -struct sysfs_class_device *sysfs_open_class_device_by_name +struct sysfs_class_device *sysfs_open_class_device (const unsigned char *classname, const unsigned char *name) { unsigned char devpath[SYSFS_PATH_MAX]; @@ -509,7 +511,7 @@ struct sysfs_class_device *sysfs_open_class_device_by_name return NULL; } - cdev = sysfs_open_class_device(devpath); + cdev = sysfs_open_class_device_path(devpath); if (cdev == NULL) { dprintf("Error getting class device %s from class %s\n", name, classname); @@ -572,32 +574,41 @@ struct sysfs_attribute *sysfs_get_classdev_attr errno = EINVAL; return NULL; } + /* * First, see if it's in the current directory. Then look at * subdirs since class devices can have subdirs of attributes. */ attrlist = sysfs_get_classdev_attributes(clsdev); - if (attrlist == NULL) - return NULL; - cur = sysfs_get_directory_attribute(clsdev->directory, + if (attrlist != NULL) { + cur = sysfs_get_directory_attribute(clsdev->directory, (unsigned char *)name); - if (cur != NULL) - return cur; + if (cur != NULL) + return cur; + } if (clsdev->directory->subdirs == NULL) if ((sysfs_read_dir_subdirs(clsdev->directory)) != 0 || clsdev->directory->subdirs == NULL) return NULL; - dlist_for_each_data(clsdev->directory->subdirs, sdir, - struct sysfs_directory) { - cur = sysfs_get_directory_attribute(sdir, - (unsigned char *)name); - if (cur != NULL) - return cur; + if (clsdev->directory->subdirs != NULL) { + dlist_for_each_data(clsdev->directory->subdirs, sdir, + struct sysfs_directory) { + if ((sysfs_path_is_dir(sdir->path)) != 0) + continue; + if (sdir->attributes == NULL) { + cur = sysfs_get_directory_attribute(sdir, + (unsigned char *)name); + } else { + if ((sysfs_refresh_attributes + (sdir->attributes)) == 0) + cur = sysfs_get_directory_attribute(sdir, + (unsigned char *)name); + } + } } - - return NULL; + return cur; } /** @@ -643,3 +654,4 @@ struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname, } return attribute; } + diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 82b54719ff..66d5f9aef7 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -104,14 +104,6 @@ static void sysfs_close_device_tree(struct sysfs_device *devroot) } } -/** - * sysfs_del_device: routine for dlist integration - */ -static void sysfs_del_device(void *dev) -{ - sysfs_close_device((struct sysfs_device *)dev); -} - /** * sysfs_close_dev_tree: routine for dlist integration */ @@ -127,6 +119,8 @@ static void sysfs_close_dev_tree(void *dev) void sysfs_close_device(struct sysfs_device *dev) { if (dev != NULL) { + if (dev->parent != NULL) + sysfs_close_device(dev->parent); if (dev->directory != NULL) sysfs_close_directory(dev->directory); if (dev->children != NULL && dev->children->count == 0) @@ -164,7 +158,7 @@ static struct sysfs_directory *open_device_dir(const unsigned char *path) dprintf ("Device %s not supported on this system\n", path); return NULL; } - if ((sysfs_read_directory(rdir)) != 0) { + if ((sysfs_read_dir_subdirs(rdir)) != 0) { dprintf ("Error reading device at dir %s\n", path); sysfs_close_directory(rdir); return NULL; @@ -174,11 +168,11 @@ static struct sysfs_directory *open_device_dir(const unsigned char *path) } /** - * sysfs_open_device: opens and populates device structure + * sysfs_open_device_path: opens and populates device structure * @path: path to device, this is the /sys/devices/ path * returns sysfs_device structure with success or NULL with error */ -struct sysfs_device *sysfs_open_device(const unsigned char *path) +struct sysfs_device *sysfs_open_device_path(const unsigned char *path) { struct sysfs_device *dev = NULL; @@ -232,7 +226,7 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path) errno = EINVAL; return NULL; } - rootdev = sysfs_open_device(path); + rootdev = sysfs_open_device_path(path); if (rootdev == NULL) { dprintf("Error opening root device at %s\n", path); return NULL; @@ -255,7 +249,7 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path) if (rootdev->children == NULL) rootdev->children = dlist_new_with_delete (sizeof(struct sysfs_device), - sysfs_del_device); + sysfs_close_dev_tree); dlist_unshift(rootdev->children, new); } } @@ -342,7 +336,6 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) if (sysfs_trailing_slash(rootpath) == 0) strcat(rootpath, "/"); - strcat(rootpath, SYSFS_DEVICES_NAME); strcat(rootpath, "/"); strcat(rootpath, name); @@ -357,6 +350,7 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) dprintf("calloc failure\n"); return NULL; } + strcpy(root->name, name); strcpy(root->path, rootpath); return root; } @@ -416,10 +410,8 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, cur = sysfs_get_directory_attribute(dev->directory, (unsigned char *)name); - if (cur != NULL) - return cur; - return NULL; + return cur; } /** @@ -445,10 +437,8 @@ static int get_device_absolute_path(const unsigned char *device, dprintf ("Sysfs not supported on this system\n"); return -1; } - if (sysfs_trailing_slash(bus_path) == 0) strcat(bus_path, "/"); - strcat(bus_path, SYSFS_BUS_NAME); strcat(bus_path, "/"); strcat(bus_path, bus); @@ -468,7 +458,7 @@ static int get_device_absolute_path(const unsigned char *device, } /** - * sysfs_open_device_by_id: open a device by id (use the "bus" subsystem) + * sysfs_open_device: open a device by id (use the "bus" subsystem) * @bus_id: bus_id of the device to open - has to be the "bus_id" in * /sys/bus/xxx/devices * @bus: bus the device belongs to @@ -478,7 +468,7 @@ static int get_device_absolute_path(const unsigned char *device, * 2. Bus the device is on must be supplied * Use sysfs_find_device_bus to get the bus name */ -struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, +struct sysfs_device *sysfs_open_device(const unsigned char *bus_id, const unsigned char *bus) { char sysfs_path[SYSFS_PATH_MAX]; @@ -495,7 +485,7 @@ struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, return NULL; } - device = sysfs_open_device(sysfs_path); + device = sysfs_open_device_path(sysfs_path); if (device == NULL) { dprintf("Error opening device %s\n", bus_id); return NULL; @@ -504,6 +494,60 @@ struct sysfs_device *sysfs_open_device_by_id(const unsigned char *bus_id, return device; } +/** + * sysfs_get_device_parent: opens up given device's parent and returns a + * reference to its sysfs_device + * @dev: sysfs_device whose parent is requested + * Returns sysfs_device of the parent on success and NULL on failure + */ +struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) +{ + unsigned char ppath[SYSFS_PATH_MAX], *tmp = NULL; + + if (dev == NULL) { + errno = EINVAL; + return NULL; + } + + if (dev->parent != NULL) + return (dev->parent); + + memset(ppath, 0, SYSFS_PATH_MAX); + strcpy(ppath, dev->path); + tmp = strrchr(ppath, '/'); + if (tmp == NULL) { + dprintf("Invalid path to device %s\n", ppath); + return NULL; + } + if (*(tmp +1) == '\0') { + *tmp = '\0'; + tmp = strrchr(tmp, '/'); + if (tmp == NULL) { + dprintf("Invalid path to device %s\n", ppath); + return NULL; + } + } + *tmp = '\0'; + + /* + * All "devices" have the "detach_state" attribute - validate here + */ + strcat(ppath, "/detach_state"); + if ((sysfs_path_is_file(ppath)) != 0) { + dprintf("Device at %s does not have a parent\n", dev->path); + return NULL; + } + tmp = strrchr(ppath, '/'); + *tmp = '\0'; + dev->parent = sysfs_open_device_path(ppath); + if (dev->parent == NULL) { + dprintf("Error opening device %s's parent at %s\n", + dev->bus_id, ppath); + return NULL; + } + return (dev->parent); +} + /* * sysfs_open_device_attr: open the given device's attribute * @bus: Bus on which to look diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index ac2ecfcbe1..7dbee8aba8 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -1,5 +1,5 @@ /* - * syfs_dir.c + * sysfs_dir.c * * Directory utility functions for libsysfs * @@ -147,7 +147,7 @@ struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path) sysfs_close_attribute(sysattr); return NULL; } - strncpy(sysattr->path, path, sizeof(sysattr->path)); + strncpy(sysattr->path, path, SYSFS_PATH_MAX); if ((stat(sysattr->path, &fileinfo)) != 0) { dprintf("Stat failed: No such attribute?\n"); sysattr->method = 0; @@ -260,7 +260,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) { unsigned char *fbuf = NULL; unsigned char *vbuf = NULL; - size_t length = 0; + ssize_t length = 0; long pgsize = 0; int fd; @@ -441,13 +441,15 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) return -1; } if (sysdir->subdirs == NULL) - if ((sysfs_read_dir_subdirs(sysdir) != 0) - || sysdir->subdirs == NULL) + if ((sysfs_read_dir_subdirs(sysdir)) != 0) return 0; - dlist_for_each_data(sysdir->subdirs, cursub, struct sysfs_directory) { - if ((sysfs_read_directory(cursub)) != 0) - dprintf ("Error reading subdirectory %s\n", - cursub->name); + if (sysdir->subdirs != NULL) { + dlist_for_each_data(sysdir->subdirs, cursub, + struct sysfs_directory) { + if ((sysfs_read_dir_subdirs(cursub)) != 0) + dprintf ("Error reading subdirectory %s\n", + cursub->name); + } } return 0; } @@ -476,7 +478,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path) sysfs_close_directory(sdir); return NULL; } - strncpy(sdir->path, path, sizeof(sdir->path)); + strncpy(sdir->path, path, SYSFS_PATH_MAX); return sdir; } @@ -527,7 +529,8 @@ int sysfs_refresh_attributes(struct dlist *attrlist) dlist_for_each_data(attrlist, attr, struct sysfs_attribute) { if (attr->method & SYSFS_METHOD_SHOW) { if ((sysfs_read_attribute(attr)) != 0) { - dprintf("Error reading attribute %s\n", attr->path); + dprintf("Error reading attribute %s\n", + attr->path); if ((sysfs_path_is_file(attr->path)) != 0) { dprintf("Attr %s no longer exists\n", attr->name); @@ -540,12 +543,6 @@ int sysfs_refresh_attributes(struct dlist *attrlist) } } } - if (attrlist->count == 0) { - dprintf("No attributes in the list, destroying list now\n"); - dlist_destroy(attrlist); - attrlist = NULL; - return 1; - } return 0; } @@ -655,9 +652,9 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, sizeof(file_path)); - strncat(file_path, "/", sizeof(file_path)); - strncat(file_path, dirent->d_name, sizeof(file_path)); + strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); + strcat(file_path, "/"); + strcat(file_path, dirent->d_name); if ((lstat(file_path, &astats)) != 0) { dprintf("stat failed\n"); continue; @@ -697,9 +694,9 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, sizeof(file_path)); - strncat(file_path, "/", sizeof(file_path)); - strncat(file_path, dirent->d_name, sizeof(file_path)); + strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); + strcat(file_path, "/"); + strcat(file_path, dirent->d_name); if ((lstat(file_path, &astats)) != 0) { dprintf("stat failed\n"); continue; @@ -742,9 +739,9 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, sizeof(file_path)); - strncat(file_path, "/", sizeof(file_path)); - strncat(file_path, dirent->d_name, sizeof(file_path)); + strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); + strcat(file_path, "/"); + strcat(file_path, dirent->d_name); if ((lstat(file_path, &astats)) != 0) { dprintf("stat failed\n"); continue; @@ -784,9 +781,9 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, sizeof(file_path)); - strncat(file_path, "/", sizeof(file_path)); - strncat(file_path, dirent->d_name, sizeof(file_path)); + strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); + strcat(file_path, "/"); + strcat(file_path, dirent->d_name); if ((lstat(file_path, &astats)) != 0) { dprintf("stat failed\n"); continue; @@ -829,26 +826,20 @@ struct sysfs_attribute *sysfs_get_directory_attribute attr = (struct sysfs_attribute *)dlist_find_custom (dir->attributes, attrname, dir_attribute_name_equal); - if (attr != NULL) { - /* - * don't read here since we would have read the attribute in - * in the routine that called this routine - */ - return attr; - } else { + if (attr == NULL) { memset(new_path, 0, SYSFS_PATH_MAX); strcpy(new_path, dir->path); strcat(new_path, "/"); strcat(new_path, attrname); if ((sysfs_path_is_file(new_path)) == 0) { if ((add_attribute(dir, new_path)) == 0) { - attr = (struct sysfs_attribute *)dlist_find_custom - (dir->attributes, attrname, dir_attribute_name_equal); + attr = (struct sysfs_attribute *) + dlist_find_custom(dir->attributes, + attrname, dir_attribute_name_equal); } - return attr; } } - return NULL; + return attr; } /** diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 4372b19f10..695ca794f1 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -65,29 +65,6 @@ static int open_driver_dir(struct sysfs_driver *driver) return 0; } -/** - * read_driver_dir: Read driver directory's subdirs and links - * @driver: Driver to read - * Returns 0 on success and 1 on failure - */ -static int read_driver_dir(struct sysfs_driver *driver) -{ - if (driver == NULL) { - errno = EINVAL; - return 1; - } - if (driver->directory == NULL) { - if ((open_driver_dir(driver)) == 1) - return 1; - } - if ((sysfs_read_directory(driver->directory)) != 0) { - dprintf("Error reading driver directory at %s\n", - driver->path); - return 1; - } - return 0; -} - /** * alloc_driver: allocates and initializes driver * returns struct sysfs_driver with success and NULL with error. @@ -98,11 +75,11 @@ static struct sysfs_driver *alloc_driver(void) } /** - * sysfs_open_driver: opens and initializes driver structure + * sysfs_open_driver_path: opens and initializes driver structure * @path: path to driver directory * returns struct sysfs_driver with success and NULL with error */ -struct sysfs_driver *sysfs_open_driver(const unsigned char *path) +struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path) { struct sysfs_driver *driver = NULL; @@ -185,13 +162,10 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, } attrlist = sysfs_get_driver_attributes(drv); - if (attrlist != NULL) { + if (attrlist != NULL) cur = sysfs_get_directory_attribute(drv->directory, (unsigned char *)name); - if (cur != NULL) - return cur; - } - return NULL; + return cur; } /** @@ -209,7 +183,7 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) if (driver->directory == NULL) { if ((open_driver_dir(driver)) == 1) return NULL; - if ((read_driver_dir(driver)) != 0) + if ((sysfs_read_dir_links(driver->directory)) != 0) return NULL; } return(driver->directory->links); @@ -236,13 +210,13 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) if (driver->directory == NULL) { if ((open_driver_dir(driver)) == 1) return NULL; - if ((read_driver_dir(driver)) != 0) + if ((sysfs_read_dir_links(driver->directory)) != 0) return NULL; } if (driver->directory->links != NULL) { dlist_for_each_data(driver->directory->links, curlink, struct sysfs_link) { - device = sysfs_open_device(curlink->target); + device = sysfs_open_device_path(curlink->target); if (device == NULL) { dprintf("Error opening device at %s\n", curlink->target); @@ -345,7 +319,7 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, return NULL; } - memset(path, 0, SYSFS_NAME_LEN); + memset(path, 0, SYSFS_PATH_MAX); if ((get_driver_path(bus, drv, path, SYSFS_PATH_MAX)) != 0) { dprintf("Error getting to driver %s\n", drv); return NULL; @@ -367,3 +341,33 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, return attribute; } +/** + * sysfs_open_driver: open driver by name, given its bus + * @drv_name: Name of the driver + * @bus_name: Name of the bus + * Returns the sysfs_driver reference on success and NULL on failure + */ +struct sysfs_driver *sysfs_open_driver(const unsigned char *drv_name, + const unsigned char *bus_name) +{ + unsigned char path[SYSFS_PATH_MAX]; + struct sysfs_driver *driver = NULL; + + if (drv_name == NULL || bus_name == NULL) { + errno = EINVAL; + return NULL; + } + + memset(path, 0, SYSFS_PATH_MAX); + if ((get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) != 0) { + dprintf("Error getting to driver %s\n", drv_name); + return NULL; + } + driver = sysfs_open_driver_path(path); + if (driver == NULL) { + dprintf("Error opening driver at %s\n", path); + return NULL; + } + return driver; +} + diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index c2ce13433d..009ae94efa 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -1,5 +1,5 @@ /* - * syfs_utils.c + * sysfs_utils.c * * System utility functions for libsysfs * @@ -135,17 +135,21 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, } memset(tmp, 0, SYSFS_PATH_MAX); strcpy(tmp, path); - n = &tmp[strlen(tmp)-1]; - if (strncmp(n, "/", 1) == 0) - *n = '\0'; n = strrchr(tmp, '/'); if (n == NULL) { errno = EINVAL; return -1; } + if (*(n+1) == '\0') { + *n = '\0'; + n = strrchr(tmp, '/'); + if (n == NULL) { + errno = EINVAL; + return -1; + } + } n++; strncpy(name, n, len); - return 0; } @@ -233,7 +237,6 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) unsigned char *c = NULL; struct sysfs_directory *dir = NULL, *cur = NULL; struct dlist *list = NULL; - struct stat astats; if (name == NULL) return NULL; @@ -242,7 +245,6 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) dprintf("Error getting sysfs mount point\n"); return NULL; } - if (sysfs_trailing_slash(sysfs_path) == 0) strcat(sysfs_path, "/"); strcat(sysfs_path, name); @@ -252,7 +254,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) return NULL; } - if (sysfs_read_directory(dir) != 0) { + if ((sysfs_read_dir_subdirs(dir)) != 0) { dprintf("Error reading sysfs_directory at %s\n", sysfs_path); sysfs_close_directory(dir); return NULL; @@ -285,11 +287,7 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) if (c == NULL) goto out; strcpy(c, SYSFS_BLOCK_NAME); - if ((lstat(sysfs_path, &astats)) != 0) { - dprintf("stat() failed\n"); - goto out; - } - if (S_ISDIR(astats.st_mode)) { + if ((sysfs_path_is_dir(sysfs_path)) == 0) { subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); strcpy(subsys_name, SYSFS_BLOCK_NAME); dlist_unshift(list, subsys_name); @@ -333,7 +331,7 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) return NULL; } - if (sysfs_read_directory(dir) != 0) { + if ((sysfs_read_dir_links(dir)) != 0) { dprintf("Error reading sysfs_directory at %s\n", sysfs_path); sysfs_close_directory(dir); return NULL; diff --git a/udev-add.c b/udev-add.c index 33ee633fd8..ba5c864165 100644 --- a/udev-add.c +++ b/udev-add.c @@ -242,9 +242,9 @@ static struct sysfs_class_device *get_class_dev(char *device_name) dbg("looking at '%s'", dev_path); /* open up the sysfs class device for this thing... */ - class_dev = sysfs_open_class_device(dev_path); + class_dev = sysfs_open_class_device_path(dev_path); if (class_dev == NULL) { - dbg ("sysfs_open_class_device failed"); + dbg ("sysfs_open_class_device_path failed"); goto exit; } dbg("class_dev->name='%s'", class_dev->name); From dac056aa301def4d45ae63636b4b9c286bac8fa1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 20 Dec 2003 01:05:13 -0800 Subject: [PATCH 0312/4284] [PATCH] try to wait until the proper device file shows up in sysfs. this still isn't working correctly for partitions, so don't think this is the final version... --- namedev.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 159 insertions(+), 24 deletions(-) diff --git a/namedev.c b/namedev.c index 58986e25c2..30c276ae1c 100644 --- a/namedev.c +++ b/namedev.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "list.h" #include "udev.h" @@ -284,6 +285,55 @@ static void apply_format(struct udevice *udev, unsigned char *string) } } +static struct bus_file { + char *bus; + char *file; +} bus_files[] = { + { .bus = "scsi", .file = "vendor" }, + { .bus = "usb", .file = "idVendor" }, + {} +}; + +#define SECONDS_TO_WAIT_FOR_FILE 10 +static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) +{ + /* sleep until we see the file for this specific bus type show up this + * is needed because we can easily out-run the kernel in looking for + * these files before the paticular subsystem has created them in the + * sysfs tree properly. + * + * And people thought that the /sbin/hotplug event system was going to + * be slow, poo on you for arguing that before even testing it... + */ + struct bus_file *b = &bus_files[0]; + struct sysfs_attribute *tmpattr; + int loop; + + while (1) { + if (b->bus == NULL) + break; + if (strcmp(sysfs_device->bus, b->bus) == 0) { + tmpattr = NULL; + loop = SECONDS_TO_WAIT_FOR_FILE; + while (loop--) { + dbg("looking for file '%s' on bus '%s'", b->file, b->bus); + tmpattr = sysfs_get_device_attr(sysfs_device, b->file); + if (tmpattr) { + /* found it! */ + goto exit; + } + /* sleep to give the kernel a chance to create the file */ + sleep(1); + } + dbg("Timed out waiting for '%s' file, continuing on anyway...", b->file); + goto exit; + } + b++; + } + dbg("Did not find bus type '%s' on list of bus_id_files, contact greg@kroah.com", sysfs_device->bus); +exit: + return; /* here to prevent compiler warning... */ +} static int exec_callout(struct config_device *dev, char *value, int len) { @@ -580,6 +630,112 @@ static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice * strfieldcpy(udev->name, class_dev->name); } +static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev) +{ + struct sysfs_device *sysfs_device; + struct sysfs_class_device *class_dev_parent; + int loop; + int retval; + char filename[SYSFS_PATH_MAX + 6]; + + /* FIXME!!! */ + /* This is needed here as we can easily out-race the placement of the + * device symlink by the kernel. The call to sleep(1); will be removed + * once libsysfs can be queried for sysfs_get_classdev_device() + * multiple times and have it return the proper information when the + * class device really shows up. For now, we live with the time + * delay... + */ +// sleep(1); + loop = 10; + while (loop--) { + struct stat buf; + + strcpy(filename, class_dev->path); + strcat(filename, "/device"); + dbg("looking for '%s'", filename); + retval = stat(filename, &buf); + if (!retval) + break; +#if 0 + /* bah, let's go backwards up a level to see if the device is there, + * as block partitions don't point to the physical device. Need to fix that + * up in the kernel... + */ + if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { + if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { + char *temp = strrchr(filename, '/'); + if (temp) { + *temp = 0x00; + temp = strrchr(filename, '/'); + if (temp) { + *temp = 0x00; + strcat(filename, "/device"); + dbg("looking for '%s'", filename); + retval = stat(filename, &buf); + if (!retval) + break; + } + } + } + } +#endif +// class_dev_parent = sysfs_get_classdev_parent(class_dev); +// if (class_dev_parent == NULL) { +// dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); +// } else { +// strcpy(filename, class_dev_parent->path); +// strcat(filename, "/device"); +// dbg("looking for '%s'", filename); +// retval = stat(filename, &buf); +// if (!retval) +// break; +// } +// } +// } + /* sleep to give the kernel a chance to create the device file */ + sleep(1); + } +// retval = -ENODEV; + +// sleep(1); + + loop = 1; /* FIXME put a real value in here for when everything is fixed... */ + while (loop--) { + /* find the sysfs_device for this class device */ + /* Wouldn't it really be nice if libsysfs could do this for us? */ + sysfs_device = sysfs_get_classdev_device(class_dev); + if (sysfs_device != NULL) + goto exit; + + /* bah, let's go backwards up a level to see if the device is there, + * as block partitions don't point to the physical device. Need to fix that + * up in the kernel... + */ + if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { + dbg("looking at block device"); + if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { + dbg("really is a partition"); + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent == NULL) { + dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); + } else { + dbg("class_dev_parent->name='%s'", class_dev_parent->name); + sysfs_device = sysfs_get_classdev_device(class_dev_parent); + if (sysfs_device != NULL) + goto exit; + } + } + } + /* sleep to give the kernel a chance to create the link */ + /* sleep(1); */ + + } +// dbg("Timed out waiting for device symlink, continuing on anyway..."); +exit: + return sysfs_device; +} + int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) { struct sysfs_device *sysfs_device = NULL; @@ -589,35 +745,14 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud udev->mode = 0; - /* find the sysfs_device for this class device */ - /* Wouldn't it really be nice if libsysfs could do this for us? */ - sysfs_device = sysfs_get_classdev_device(class_dev); - if (sysfs_device == NULL) { - /* bah, let's go backwards up a level to see if the device is there, - * as block partitions don't point to the physical device. Need to fix that - * up in the kernel... - */ - if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { - dbg("looking at block device"); - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - dbg("really is a partition"); - class_dev_parent = sysfs_get_classdev_parent - (class_dev); - if (class_dev_parent == NULL) { - dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); - } else { - dbg("class_dev_parent->name='%s'", class_dev_parent->name); - sysfs_device = sysfs_get_classdev_device(class_dev_parent); - } - } - } - } - + /* find the sysfs_device associated with this class device */ + sysfs_device = get_sysfs_device(class_dev); if (sysfs_device) { dbg("sysfs_device->path='%s'", sysfs_device->path); dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); dbg("sysfs_device->bus='%s'", sysfs_device->bus); strfieldcpy(udev->bus_id, sysfs_device->bus_id); + wait_for_device_to_initialize(sysfs_device); } else { dbg("class_dev->name = '%s'", class_dev->name); } From 1edbb8d350c3e751d7b9b146eb3873895157791f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Dec 2003 19:07:08 -0800 Subject: [PATCH 0313/4284] [PATCH] Just live with a sleep(1) in namedev for now until libsysfs is fixed up. --- namedev.c | 58 +++++++++++++++++++++---------------------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/namedev.c b/namedev.c index 30c276ae1c..05553e69a4 100644 --- a/namedev.c +++ b/namedev.c @@ -635,8 +635,6 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de struct sysfs_device *sysfs_device; struct sysfs_class_device *class_dev_parent; int loop; - int retval; - char filename[SYSFS_PATH_MAX + 6]; /* FIXME!!! */ /* This is needed here as we can easily out-race the placement of the @@ -646,10 +644,17 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de * class device really shows up. For now, we live with the time * delay... */ -// sleep(1); + sleep(1); + +#if 0 /* FIXME + Something like this could also work, but for some reason doesn't, + I also tried just stat() on the device symlink, but that still + has nasty races, I'm probably doing something stupid... :( */ loop = 10; while (loop--) { struct stat buf; + int retval; + char filename[SYSFS_PATH_MAX + 6]; strcpy(filename, class_dev->path); strcat(filename, "/device"); @@ -657,49 +662,30 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de retval = stat(filename, &buf); if (!retval) break; -#if 0 + /* bah, let's go backwards up a level to see if the device is there, * as block partitions don't point to the physical device. Need to fix that * up in the kernel... */ if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - char *temp = strrchr(filename, '/'); - if (temp) { - *temp = 0x00; - temp = strrchr(filename, '/'); - if (temp) { - *temp = 0x00; - strcat(filename, "/device"); - dbg("looking for '%s'", filename); - retval = stat(filename, &buf); - if (!retval) - break; - } + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent == NULL) { + dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); + } else { + strcpy(filename, class_dev_parent->path); + strcat(filename, "/device"); + dbg("looking for '%s'", filename); + retval = stat(filename, &buf); + if (!retval) + break; } } } -#endif -// class_dev_parent = sysfs_get_classdev_parent(class_dev); -// if (class_dev_parent == NULL) { -// dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); -// } else { -// strcpy(filename, class_dev_parent->path); -// strcat(filename, "/device"); -// dbg("looking for '%s'", filename); -// retval = stat(filename, &buf); -// if (!retval) -// break; -// } -// } -// } /* sleep to give the kernel a chance to create the device file */ sleep(1); } -// retval = -ENODEV; - -// sleep(1); - +#endif loop = 1; /* FIXME put a real value in here for when everything is fixed... */ while (loop--) { /* find the sysfs_device for this class device */ @@ -728,10 +714,10 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de } } /* sleep to give the kernel a chance to create the link */ - /* sleep(1); */ + sleep(1); } -// dbg("Timed out waiting for device symlink, continuing on anyway..."); + dbg("Timed out waiting for device symlink, continuing on anyway..."); exit: return sysfs_device; } From 8c5d34e50856b9bed938cbd4f5648b62df64a04c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Dec 2003 19:10:27 -0800 Subject: [PATCH 0314/4284] [PATCH] trivial make fixes One patch to let bk ignore the created udev.conf. The second to depend on the .h files. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3e220b47d0..5833d4cb94 100644 --- a/Makefile +++ b/Makefile @@ -214,7 +214,7 @@ udev.conf: $(OBJS): $(GEN_HEADERS) -$(ROOT): $(OBJS) +$(ROOT): $(OBJS) udev.h namedev.h $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) From 3e54036862061d8b81fca6cdd3d24bc9ceb53bc0 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Dec 2003 19:13:19 -0800 Subject: [PATCH 0315/4284] [PATCH] introduce format char 'k' for kernel-name Attached is a patch that introduces the format char 'k' to be replaced with the kernel name. I like to have it in a callout script. I've moved the build_kernel_name() back to namedev_name_device() since we don't expect it growing cause of 'sdaj' :) --- namedev.c | 27 +++++++++++++++------------ udev.h | 1 + 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/namedev.c b/namedev.c index 05553e69a4..5044870d32 100644 --- a/namedev.c +++ b/namedev.c @@ -186,17 +186,6 @@ static mode_t get_default_mode(struct sysfs_class_device *class_dev) return mode; } -static void build_kernel_number(struct sysfs_class_device *class_dev, struct udevice *udev) -{ - char *dig; - - dig = class_dev->name + strlen(class_dev->name); - while (isdigit(*(dig-1))) - dig--; - strfieldcpy(udev->kernel_number, dig); - dbg("kernel_number='%s'", udev->kernel_number); -} - static void apply_format(struct udevice *udev, unsigned char *string) { char name[NAME_SIZE]; @@ -230,6 +219,12 @@ static void apply_format(struct udevice *udev, unsigned char *string) strcat(pos, udev->bus_id); dbg("substitute bus_id '%s'", udev->bus_id); break; + case 'k': + if (strlen(udev->kernel_name) == 0) + break; + strcat(pos, udev->kernel_name); + dbg("substitute kernel name '%s'", udev->kernel_name); + break; case 'n': if (strlen(udev->kernel_number) == 0) break; @@ -728,6 +723,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; struct perm_device *perm; + char *pos; udev->mode = 0; @@ -743,7 +739,14 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dbg("class_dev->name = '%s'", class_dev->name); } - build_kernel_number(class_dev, udev); + strfieldcpy(udev->kernel_name, class_dev->name); + + /* get kernel number */ + pos = class_dev->name + strlen(class_dev->name); + while (isdigit(*(pos-1))) + pos--; + strfieldcpy(udev->kernel_number, pos); + dbg("kernel_number='%s'", udev->kernel_number); /* rules are looked at in priority order */ retval = do_callout(class_dev, udev, sysfs_device); diff --git a/udev.h b/udev.h index 05f6b3c225..656c1b7d8c 100644 --- a/udev.h +++ b/udev.h @@ -70,6 +70,7 @@ struct udevice { unsigned char bus_id[SYSFS_NAME_LEN]; unsigned char callout_value[NAME_SIZE]; unsigned char kernel_number[NAME_SIZE]; + unsigned char kernel_name[NAME_SIZE]; }; From 958479a0dead606c6e44490a30a7040773654281 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Dec 2003 19:16:19 -0800 Subject: [PATCH 0316/4284] [PATCH] add any valid device --- namedev.c | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/namedev.c b/namedev.c index 5044870d32..7c422f7877 100644 --- a/namedev.c +++ b/namedev.c @@ -104,31 +104,10 @@ static int strcmp_pattern(const char *p, const char *s) int add_config_dev(struct config_device *new_dev) { - struct list_head *tmp; struct config_device *tmp_dev; - /* update the values if we already have the device */ - list_for_each(tmp, &config_device_list) { - struct config_device *dev = list_entry(tmp, struct config_device, node); - if (strcmp_pattern(new_dev->name, dev->name)) - continue; - if (strncmp(dev->bus, new_dev->bus, sizeof(dev->name))) - continue; - copy_var(dev, new_dev, type); - copy_string(dev, new_dev, bus); - copy_string(dev, new_dev, sysfs_file); - copy_string(dev, new_dev, sysfs_value); - copy_string(dev, new_dev, id); - copy_string(dev, new_dev, place); - copy_string(dev, new_dev, kernel_name); - copy_string(dev, new_dev, exec_program); - copy_string(dev, new_dev, symlink); - return 0; - } - - /* not found, add new structure to the device list */ tmp_dev = malloc(sizeof(*tmp_dev)); - if (!tmp_dev) + if (tmp_dev == NULL) return -ENOMEM; memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); list_add_tail(&tmp_dev->node, &config_device_list); From 4af58c70571c5c63edaff20d2032c8eeb59678b6 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Dec 2003 20:34:53 -0800 Subject: [PATCH 0317/4284] [PATCH] experimental CALLOUT script for devfs ide node creation with cd, disc, part Here is a experimental CALLOUT script for udev to create devfs nodes for IDE-devices. Not that I need these, I just wanted to see if it works :) The script is really stupid, no error handling, nothing more than absolutely needed. The rule uses the 'k' format char of the previous patch. The %D is not used, so the user can have disc or disk :) this single line: CALLOUT, BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c" creates the following on my machine with two hard disks, one DVD and a PCMCIA-compact-flash inserted: /udev |-- hda |-- hda1 |-- hda2 |-- hda4 |-- hdb |-- hdb1 |-- hdc |-- hde |-- hde1 `-- ide |-- host0 | |-- bus0 | | |-- target0 | | | `-- lun0 | | | |-- disc -> ../../../../../hda | | | |-- part1 -> ../../../../../hda1 | | | |-- part2 -> ../../../../../hda2 | | | `-- part4 -> ../../../../../hda4 | | `-- target1 | | `-- lun0 | | |-- disc -> ../../../../../hdb | | `-- part1 -> ../../../../../hdb1 | `-- bus1 | `-- target0 | `-- lun0 | `-- cd -> ../../../../../hdc `-- host2 `-- bus0 `-- target0 `-- lun0 |-- disc -> ../../../../../hde `-- part1 -> ../../../../../hde1 --- extras/ide-devfs.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 extras/ide-devfs.sh diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh new file mode 100644 index 0000000000..3409c407eb --- /dev/null +++ b/extras/ide-devfs.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +# udev CALLOUT script +# return devfs-names for ide-devices +# CALLOUT, BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c" + +HOST=${2%\.[0-9]} +TARGET=${2#[0-9]\.} + +if [ -z ${HOST#[13579]} ]; then + HOST=`expr $HOST - 1` + BUS="1" +else + BUS="0" +fi + +if [ -z "$3" ]; then + MEDIA=`cat /proc/ide/$1/media` + if [ "$MEDIA" = "cdrom" ]; then + echo $1 ide/host$HOST/bus$BUS/target$TARGET/lun0/cd + elif [ "$MEDIA" = "disk" ]; then + echo $1 ide/host$HOST/bus$BUS/target$TARGET/lun0/disc + fi +else + echo $1 ide/host$HOST/bus$BUS/target$TARGET/lun0/part$3 +fi + From 176857119a77aad650412d9fedb568da4b543e07 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Mon, 22 Dec 2003 20:49:22 -0800 Subject: [PATCH 0318/4284] [PATCH] extras multipath update An important one, against stock udev-009 : 2003-12-20 multipath-010 * big ChangeLog update * start to give a little control over target params : introduce cmdline arg -i to control polling interval * cope with hotplug-style calling convention : ie "multipath scsi $DEVPATH" ... to avoid messing with online maps not concerned by an event * example hotplug agent to drop in /etc/hotplug.d/scsi * revert the run & resched patch : unless someone proves me wrong, this was overdesigned * move commented out functions in unused.c * update multipath target params to "udm[23] style" * mp target now supports nr_path == 1, so do we * add gratuitous free() * push version forward --- extras/multipath/ChangeLog | 57 ++++++++ extras/multipath/main.c | 207 +++++++++++------------------ extras/multipath/main.h | 6 +- extras/multipath/multipath.hotplug | 3 + extras/multipath/unsused.c | 52 ++++++++ 5 files changed, 194 insertions(+), 131 deletions(-) create mode 100644 extras/multipath/multipath.hotplug create mode 100644 extras/multipath/unsused.c diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index f3014cf01e..f31fbf41dc 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,3 +1,60 @@ +2003-12-20 multipath-010 + * big ChangeLog update + * start to give a little control over target params : + introduce cmdline arg -i to control polling interval + * cope with hotplug-style calling convention : + ie "multipath scsi $DEVPATH" ... to avoid messing with + online maps not concerned by an event + * example hotplug agent to drop in /etc/hotplug.d/scsi + * revert the run & resched patch : unless someone proves me + wrong, this was overdesigned + * move commented out functions in unused.c + * update multipath target params to "udm[23] style" + * mp target now supports nr_path == 1, so do we + * add gratuitous free() + * push version forward +2003-12-15 multipath-009 + * Make the HW-specific get_unique_id switch pretty + * Prepare to field-test by whitelisting all known fibre array, + try to fetch WWID from the standard EVPD 0x83 off 8 for everyone + * configure the multipath target with round-robin path selector and + conservative default for a start (udm1 style) : + yes it makes this release the firstreally useful one. + * temporarily disable map creation for single path device + due to current restrictive defaults in the kernel target. + Sistina should work it out. + * correct the strncmp logic in blacklist function. + * update the Makefiles to autodetect libgcc.a & gcc includes + "ulibc-style". Factorisation of udevdirs & others niceties + * drop a hint about absent /dev/sd? on failed open() + * implement a reschedule flag in /var/run. + Last thing the prog do before exit is check if a call to multipath + was done (but canceled by /var/run/multipath.run check) during its + execution. If so restart themain loop. + * implement a blacklist of sysfs bdev to not bother with for now + (hd,md, dm, sr, scd, ram, raw). + This avoid sending SG_IO to unappropiate devices. + * Adds a /var/run/multipath.run handling to avoid simultaneous runs. + * Remove a commented-out "printf" + * drop a libdevmapper copy in extras/multipath; + maybe discussions w/Sistina folks will bring a better solution in the future. + * drop a putchar usage in libdevmapper to compile cleanly with klibc + * drop another such usage of my own in main.c + * massage the Makefile to compile libdevmapper against klibc + * use "ld" to produce the binary rather than "gcc -static" + * stop being stupid w/ uneeded major, minor & dev in main.c:dm_mk_node() + * reverse to creating striped target for now because the multipath target + is more hairy than expected initialy + * push the version code to 009 to be in synch w/ udev +2003-11-27 multipath-007 + * removes sg_err.[ch] deps + * makes sure the core code play nice with klibc + * port the sysfs calls to dlist helpers + * links against udev's sysfs (need libsysfs.a & dlist.a) + * finally define DM_TARGET as "multipath" as Joe posted the code today (not tested yet) + * push version forward (do you want it in sync with udev version?) +2003-11-19 + * merged in udev-006 tree 2003-09-18 Christophe Varoqui * multipath 0.0.1 released. * Initial release. diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 9402888c58..39b4a9fa93 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -1,5 +1,5 @@ /* - * Soft: Description here... + * Soft: multipath device mapper target autoconfig * * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ * @@ -258,38 +258,80 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) struct sysfs_directory * sdir; struct sysfs_directory * devp; struct sysfs_link * linkp; + char refwwid[WWID_SIZE]; + char empty_buff[WWID_SIZE]; char buff[FILE_NAME_SIZE]; + char path[FILE_NAME_SIZE]; + struct path curpath; - char block_path[FILE_NAME_SIZE]; + /* if called from udev, only consider the paths that relate to */ + /* to the device pointed by conf.hotplugdev */ + memset(empty_buff, 0, WWID_SIZE); + memset(refwwid, 0, WWID_SIZE); + if (strncmp("/devices", conf->hotplugdev, 8) == 0) { + sprintf(buff, "%s%s/block", + conf->sysfs_path, conf->hotplugdev); + memset(conf->hotplugdev, 0, FILE_NAME_SIZE); + readlink(buff, conf->hotplugdev, FILE_NAME_SIZE); + basename(conf->hotplugdev, buff); + sprintf(curpath.sg_dev, "/dev/%s", buff); - sprintf(block_path, "%s/block", conf->sysfs_path); - sdir = sysfs_open_directory(block_path); + if ((sg_fd = open(curpath.sg_dev, O_RDONLY)) < 0) + exit(1); + + get_lun_strings(sg_fd, &curpath); + get_unique_id(sg_fd, &curpath); + strcpy(refwwid, curpath.wwid); + memset(&curpath, 0, sizeof(path)); + } + + sprintf(path, "%s/block", conf->sysfs_path); + sdir = sysfs_open_directory(path); sysfs_read_directory(sdir); + dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { if (blacklist(devp->name)) continue; + sysfs_read_directory(devp); + if(devp->links == NULL) continue; + dlist_for_each_data(devp->links, linkp, struct sysfs_link) { if (!strncmp(linkp->name, "device", 6)) break; } + if (linkp == NULL) { continue; } basename(devp->path, buff); - sprintf(all_paths[k].sg_dev, "/dev/%s", buff); - strcpy(all_paths[k].dev, all_paths[k].sg_dev); - if ((sg_fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) { + sprintf(curpath.sg_dev, "/dev/%s", buff); + + if ((sg_fd = open(curpath.sg_dev, O_RDONLY)) < 0) { if (conf->verbose) - fprintf(stderr, "can't open %s. mknod ?", - all_paths[k].sg_dev); + fprintf(stderr, "can't open %s\n", + curpath.sg_dev); continue; } - get_lun_strings(sg_fd, &all_paths[k]); - get_unique_id(sg_fd, &all_paths[k]); + + get_lun_strings(sg_fd, &curpath); + get_unique_id(sg_fd, &curpath); + + if (memcmp(empty_buff, refwwid, WWID_SIZE) != 0 && + strncmp(curpath.wwid, refwwid, WWID_SIZE) != 0) { + memset(&curpath, 0, sizeof(path)); + continue; + } + + strcpy(all_paths[k].sg_dev, curpath.sg_dev); + strcpy(all_paths[k].dev, curpath.sg_dev); + strcpy(all_paths[k].wwid, curpath.wwid); + strcpy(all_paths[k].vendor_id, curpath.vendor_id); + strcpy(all_paths[k].product_id, curpath.product_id); + memset(&curpath, 0, sizeof(path)); all_paths[k].state = do_tur(sg_fd); close(sg_fd); basename(linkp->target, buff); @@ -301,7 +343,6 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) k++; } sysfs_close_directory(sdir); - return 0; } @@ -562,26 +603,6 @@ make_dm_node(char * str) } -/* future use ? -static int -del_map(char * str) { - struct dm_task *dmt; - - if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) - return 0; - if (!dm_task_set_name(dmt, str)) - goto delout; - if (!dm_task_run(dmt)) - goto delout; - - printf("Deleted device map : %s\n", str); - - delout: - dm_task_destroy(dmt); - return 1; -} -*/ - static int add_map(struct env * conf, struct path * all_paths, struct multipath * mp, int index, int op) @@ -593,15 +614,9 @@ add_map(struct env * conf, struct path * all_paths, long size = -1; /* defaults for multipath target */ - int dm_nr_path_args = 2; - int dm_path_test_int = 10; + int dm_pg_prio = 1; char * dm_ps_name = "round-robin"; - int dm_ps_nr_args = 2; - int dm_path_failback_int = 10; - int dm_path_nr_fail = 2; - int dm_ps_prio = 1; - int dm_ps_min_io = 2; - + int dm_ps_nr_args = 0; if (!(dmt = dm_task_create(op))) return 0; @@ -618,14 +633,13 @@ add_map(struct env * conf, struct path * all_paths, } if (np == 0) goto addout; - /* temporarily disable creation of single path maps */ - /* Sistina should modify the target limits */ - if (np < 2) + + if (np < 1) goto addout; - params_p += sprintf(params_p, "%i %i %i %s %i", - np, dm_nr_path_args, dm_path_test_int, - dm_ps_name, dm_ps_nr_args); + params_p += sprintf(params_p, "%i %i %s %i %i", + conf->dm_path_test_int, dm_pg_prio, + dm_ps_name, np, dm_ps_nr_args); for (i=0; i<=mp[index].npaths; i++) { if (( 0 == all_paths[PINDEX(index,i)].state) || @@ -633,10 +647,8 @@ add_map(struct env * conf, struct path * all_paths, continue; if (size < 0) size = get_disk_size(conf, all_paths[PINDEX(index,0)].dev); - params_p += sprintf(params_p, " %s %i %i %i %i", - all_paths[PINDEX(index,i)].dev, - dm_path_failback_int, dm_path_nr_fail, - dm_ps_prio, dm_ps_min_io); + params_p += sprintf(params_p, " %s", + all_paths[PINDEX(index,i)].dev); } if (size < 0) @@ -665,44 +677,6 @@ add_map(struct env * conf, struct path * all_paths, return 1; } -/* -static int -get_table(const char * str) -{ - int r = 0; - struct dm_task *dmt; - void *next = NULL; - uint64_t start, length; - char *target_type = NULL; - char *params; - - if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) - return 0; - - if (!dm_task_set_name(dmt, str)) - goto out; - - if (!dm_task_run(dmt)) - goto out; - - do { - next = dm_get_next_target(dmt, next, &start, &length, - &target_type, ¶ms); - if (target_type) { - printf("%" PRIu64 " %" PRIu64 " %s %s\n", - start, length, target_type, params); - } - } while (next); - - r = 1; - - out: - dm_task_destroy(dmt); - return r; - -} -*/ - static int map_present(char * str) { @@ -740,28 +714,18 @@ static void usage(char * progname) { fprintf(stderr, VERSION_STRING); - fprintf(stderr, "Usage: %s [-v|-q] [-d] [-m max_devs]\n", progname); - fprintf(stderr, "\t-v\t\tverbose, print all paths and multipaths\n"); - fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); + fprintf(stderr, "Usage: %s [-v|-q] [-d] [-i int] [-m max_devs]\n", progname); fprintf(stderr, "\t-d\t\tdry run, do not create or update devmaps\n"); + fprintf(stderr, "\t-i\t\tmultipath target param : polling interval\n"); fprintf(stderr, "\t-m max_devs\tscan {max_devs} devices at most\n"); + fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); + fprintf(stderr, "\t-v\t\tverbose, print all paths and multipaths\n"); exit(1); } -static int -filepresent(char * run) { - struct stat buf; - - if(!stat(run, &buf)) - return 1; - return 0; -} - int main(int argc, char *argv[]) { - char * run = "/var/run/multipath.run"; - char * resched = "/var/run/multipath.reschedule"; struct multipath * mp; struct path * all_paths; struct scsi_dev * all_scsi_ids; @@ -774,6 +738,7 @@ main(int argc, char *argv[]) conf.verbose = 0; /* 1 == Print all_paths and mp */ conf.quiet = 0; /* 1 == Do not even print devmaps */ conf.with_sysfs = 0; /* Default to compat / suboptimal behaviour */ + conf.dm_path_test_int = 10; /* kindly provided by libsysfs */ if (0 == sysfs_get_mnt_path(conf.sysfs_path, FILE_NAME_SIZE)) @@ -794,6 +759,10 @@ main(int argc, char *argv[]) conf.quiet = 1; } else if (0 == strcmp("-d", argv[i])) conf.dry_run = 1; + else if (0 == strcmp("-i", argv[i])) + conf.dm_path_test_int = atoi(argv[++i]); + else if (0 == strcmp("scsi", argv[i])) + strcpy(conf.hotplugdev, argv[++i]); else if (*argv[i] == '-') { fprintf(stderr, "Unknown switch: %s\n", argv[i]); usage(argv[0]); @@ -804,27 +773,11 @@ main(int argc, char *argv[]) } - if (filepresent(run)) { - if (conf.verbose) { - fprintf(stderr, "Already running.\n"); - fprintf(stderr, "If you know what you do, please "); - fprintf(stderr, "remove %s\n", run); - } - /* leave a trace that we were called while already running */ - open(resched, O_CREAT); - return 1; - } - /* dynamic allocations */ mp = malloc(conf.max_devs * sizeof(struct multipath)); all_paths = malloc(conf.max_devs * sizeof(struct path)); all_scsi_ids = malloc(conf.max_devs * sizeof(struct scsi_dev)); - if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) { - unlink(run); - exit(1); - } -start: - if(!open(run, O_CREAT)) + if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) exit(1); if (!conf.with_sysfs) { @@ -842,10 +795,8 @@ start: fprintf(stdout, "\n"); } - if (conf.dry_run) { - unlink(run); + if (conf.dry_run) exit(0); - } for (k=0; k<=nmp; k++) { if (map_present(mp[k].wwid)) { @@ -854,13 +805,11 @@ start: add_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); } } - unlink(run); - /* start again if we were ask to during this process run */ - /* ie. do not loose an event-asked run */ - if (filepresent(resched)) { - unlink(resched); - goto start; - } + /* free allocs */ + free(mp); + free(all_paths); + free(all_scsi_ids); + exit(0); } diff --git a/extras/multipath/main.h b/extras/multipath/main.h index d6dfb14296..0c5620ff74 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -99,14 +99,16 @@ struct env { int quiet; int dry_run; int with_sysfs; + int dm_path_test_int; char sysfs_path[FILE_NAME_SIZE]; + char hotplugdev[FILE_NAME_SIZE]; }; /* Build version */ #define PROG "multipath" -#define VERSION_CODE 0x000009 -#define DATE_CODE 0x0C0503 +#define VERSION_CODE 0x000010 +#define DATE_CODE 0x0C1503 #define MULTIPATH_VERSION(version) \ (version >> 16) & 0xFF, \ diff --git a/extras/multipath/multipath.hotplug b/extras/multipath/multipath.hotplug new file mode 100644 index 0000000000..db7894cb99 --- /dev/null +++ b/extras/multipath/multipath.hotplug @@ -0,0 +1,3 @@ +. /etc/hotplug/hotplug.functions +sleep 1 +mesg `/root/multipath scsi $DEVPATH` diff --git a/extras/multipath/unsused.c b/extras/multipath/unsused.c new file mode 100644 index 0000000000..ecdd695ac8 --- /dev/null +++ b/extras/multipath/unsused.c @@ -0,0 +1,52 @@ +static int +del_map(char * str) { + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) + return 0; + if (!dm_task_set_name(dmt, str)) + goto delout; + if (!dm_task_run(dmt)) + goto delout; + + printf("Deleted device map : %s\n", str); + + delout: + dm_task_destroy(dmt); + return 1; +} + +get_table(const char * str) +{ + int r = 0; + struct dm_task *dmt; + void *next = NULL; + uint64_t start, length; + char *target_type = NULL; + char *params; + + if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) + return 0; + + if (!dm_task_set_name(dmt, str)) + goto out; + + if (!dm_task_run(dmt)) + goto out; + + do { + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, ¶ms); + if (target_type) { + printf("%" PRIu64 " %" PRIu64 " %s %s\n", + start, length, target_type, params); + } + } while (next); + + r = 1; + + out: + dm_task_destroy(dmt); + return r; + +} From 4081da7fe560f0ad173a9836589d6839d9dff9df Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Mon, 22 Dec 2003 20:49:48 -0800 Subject: [PATCH 0319/4284] [PATCH] extras multipath update incremental to 20031220, 2003-12-22 multipath-010 * don't print .sg_dev if equal to .dev (2.6) in print_path() * since the kernel code handles defective paths, remove all code to cope with them : * move do_tur() to unused.c * remove .state from path struct * remove .state settings & conditionals * add a cmdline switch to force maps to failover mode, ie 1 path per priority group * add default policies to the whitelist array (spread io == MULTIBUS / io forced to 1 path == FAILOVER) * move get_disk_size() call out of add_map() to coalesce() * comment tricky coalesce() fn * bogus unsused.c file renamed to unused.c --- extras/multipath/ChangeLog | 14 ++ extras/multipath/main.c | 230 ++++++++++++----------- extras/multipath/main.h | 8 +- extras/multipath/{unsused.c => unused.c} | 26 +++ 4 files changed, 163 insertions(+), 115 deletions(-) rename extras/multipath/{unsused.c => unused.c} (62%) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index f31fbf41dc..dc29400e0e 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,3 +1,17 @@ +2003-12-22 multipath-010 + * don't print .sg_dev if equal to .dev (2.6) in print_path() + * since the kernel code handles defective paths, remove all + code to cope with them : + * move do_tur() to unused.c + * remove .state from path struct + * remove .state settings & conditionals + * add a cmdline switch to force maps to failover mode, + ie 1 path per priority group + * add default policies to the whitelist array (spread io == + MULTIBUS / io forced to 1 path == FAILOVER) + * move get_disk_size() call out of add_map() to coalesce() + * comment tricky coalesce() fn + * bogus unsused.c file renamed to unused.c 2003-12-20 multipath-010 * big ChangeLog update * start to give a little control over target params : diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 39b4a9fa93..c57cd4fe7e 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -82,32 +82,6 @@ do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, return -1; } -static int -do_tur(int fd) -{ - unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; - struct sg_io_hdr io_hdr; - unsigned char sense_buffer[32]; - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (turCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_buffer); - io_hdr.dxfer_direction = SG_DXFER_NONE; - io_hdr.cmdp = turCmdBlk; - io_hdr.sbp = sense_buffer; - io_hdr.timeout = 20000; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - close(fd); - return 0; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - return 0; - } - return 1; -} - static void sprint_wwid(char * buff, const char * str) { @@ -183,32 +157,34 @@ get_unique_id(int fd, struct path * mypath) static struct { char * vendor; char * product; + int iopolicy; int (*getuid) (int fd, char * wwid); } wlist[] = { - {"COMPAQ ", "HSV110 (C)COMPAQ", &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 ", &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 VOLUME ", &get_evpd_wwid}, - {"DEC ", "HSG80 ", &get_evpd_wwid}, - {"HP ", "HSV100 ", &get_evpd_wwid}, - {"HP ", "A6189A ", &get_evpd_wwid}, - {"HP ", "OPEN- ", &get_evpd_wwid}, - {"DDN ", "SAN DataDirector", &get_evpd_wwid}, - {"FSC ", "CentricStor ", &get_evpd_wwid}, - {"HITACHI ", "DF400 ", &get_evpd_wwid}, - {"HITACHI ", "DF500 ", &get_evpd_wwid}, - {"HITACHI ", "DF600 ", &get_evpd_wwid}, - {"IBM ", "ProFibre 4000R ", &get_evpd_wwid}, - {"SGI ", "TP9100 ", &get_evpd_wwid}, - {"SGI ", "TP9300 ", &get_evpd_wwid}, - {"SGI ", "TP9400 ", &get_evpd_wwid}, - {"SGI ", "TP9500 ", &get_evpd_wwid}, - {NULL, NULL, NULL}, + {"COMPAQ ", "HSV110 (C)COMPAQ", MULTIBUS, &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 ", MULTIBUS, &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 VOLUME ", MULTIBUS, &get_evpd_wwid}, + {"DEC ", "HSG80 ", MULTIBUS, &get_evpd_wwid}, + {"HP ", "HSV100 ", MULTIBUS, &get_evpd_wwid}, + {"HP ", "A6189A ", MULTIBUS, &get_evpd_wwid}, + {"HP ", "OPEN- ", MULTIBUS, &get_evpd_wwid}, + {"DDN ", "SAN DataDirector", MULTIBUS, &get_evpd_wwid}, + {"FSC ", "CentricStor ", MULTIBUS, &get_evpd_wwid}, + {"HITACHI ", "DF400 ", MULTIBUS, &get_evpd_wwid}, + {"HITACHI ", "DF500 ", MULTIBUS, &get_evpd_wwid}, + {"HITACHI ", "DF600 ", MULTIBUS, &get_evpd_wwid}, + {"IBM ", "ProFibre 4000R ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9100 ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9300 ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9400 ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9500 ", MULTIBUS, &get_evpd_wwid}, + {NULL, NULL, 0, NULL}, }; for (i = 0; wlist[i].vendor; i++) { if (strncmp(mypath->vendor_id, wlist[i].vendor, 8) == 0 && strncmp(mypath->product_id, wlist[i].product, 16) == 0) { wlist[i].getuid(fd, mypath->wwid); + mypath->iopolicy = wlist[i].iopolicy; return 0; } } @@ -264,7 +240,7 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) char path[FILE_NAME_SIZE]; struct path curpath; - /* if called from udev, only consider the paths that relate to */ + /* if called from hotplug, only consider the paths that relate to */ /* to the device pointed by conf.hotplugdev */ memset(empty_buff, 0, WWID_SIZE); memset(refwwid, 0, WWID_SIZE); @@ -331,8 +307,11 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) strcpy(all_paths[k].wwid, curpath.wwid); strcpy(all_paths[k].vendor_id, curpath.vendor_id); strcpy(all_paths[k].product_id, curpath.product_id); + all_paths[k].iopolicy = curpath.iopolicy; + + /* done with curpath, zero for reuse */ memset(&curpath, 0, sizeof(path)); - all_paths[k].state = do_tur(sg_fd); + close(sg_fd); basename(linkp->target, buff); sscanf(buff, "%i:%i:%i:%i", @@ -367,7 +346,6 @@ get_all_paths_nosysfs(struct env * conf, struct path * all_paths, } get_lun_strings(sg_fd, &all_paths[k]); get_unique_id(sg_fd, &all_paths[k]); - all_paths[k].state = do_tur(sg_fd); if (0 > ioctl(sg_fd, SG_GET_SCSI_ID, &(all_paths[k].sg_id))) printf("device %s failed on sg ioctl, skip\n", file_name); @@ -406,7 +384,8 @@ get_all_scsi_ids(struct env * conf, struct scsi_dev * all_scsi_ids) buff[0] = 'a' + (char) k; buff[1] = '\0'; strcat(fname, buff); - } else if (k <= 255) { /* assumes sequence goes x,y,z,aa,ab,ac etc */ + } else if (k <= 255) { + /* assumes sequence goes x,y,z,aa,ab,ac etc */ big = k / 26; little = k - (26 * big); big = big - 1; @@ -463,8 +442,8 @@ print_path(struct path * all_paths, int k, int style) all_paths[k].sg_id.host_no, all_paths[k].sg_id.channel, all_paths[k].sg_id.scsi_id, all_paths[k].sg_id.lun); - printf("%s ", all_paths[k].sg_dev); - printf("op:%i ", all_paths[k].state); + if(0 != strcmp(all_paths[k].sg_dev, all_paths[k].dev)) + printf("%s ", all_paths[k].sg_dev); printf("%s ", all_paths[k].dev); printf("[%.16s]\n", all_paths[k].product_id); } @@ -495,48 +474,6 @@ print_all_mp(struct path * all_paths, struct multipath * mp, int nmp) } } -static int -coalesce_paths(struct env * conf, struct multipath * mp, - struct path * all_paths) -{ - int k, i, nmp, np, already_done; - char empty_buff[WWID_SIZE]; - - nmp = -1; - already_done = 0; - memset(empty_buff, 0, WWID_SIZE); - - for (k = 0; k < conf->max_devs - 1; k++) { - /* skip this path if no unique id has been found */ - if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) - continue; - np = 0; - - for (i = 0; i <= nmp; i++) { - if (0 == strcmp(mp[i].wwid, all_paths[k].wwid)) - already_done = 1; - } - - if (already_done) { - already_done = 0; - continue; - } - - nmp++; - strcpy(mp[nmp].wwid, all_paths[k].wwid); - PINDEX(nmp,np) = k; - - for (i = k + 1; i < conf->max_devs; i++) { - if (0 == strcmp(all_paths[k].wwid, all_paths[i].wwid)) { - np++; - PINDEX(nmp,np) = i; - mp[nmp].npaths = np; - } - } - } - return nmp; -} - static long get_disk_size (struct env * conf, char * dev) { long size; @@ -563,6 +500,54 @@ get_disk_size (struct env * conf, char * dev) { return -1; } +static int +coalesce_paths(struct env * conf, struct multipath * mp, + struct path * all_paths) +{ + int k, i, nmp, np, already_done; + char empty_buff[WWID_SIZE]; + + nmp = -1; + already_done = 0; + memset(empty_buff, 0, WWID_SIZE); + + for (k = 0; k < conf->max_devs - 1; k++) { + /* skip this path for some reason */ + + /* 1. if path has no unique id */ + if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) + continue; + + /* 2. mp with this uid already instanciated */ + for (i = 0; i <= nmp; i++) { + if (0 == strcmp(mp[i].wwid, all_paths[k].wwid)) + already_done = 1; + } + if (already_done) { + already_done = 0; + continue; + } + + /* at this point, we know we really got a new mp */ + np = 0; + nmp++; + strcpy(mp[nmp].wwid, all_paths[k].wwid); + PINDEX(nmp,np) = k; + + if (mp[nmp].size == 0) + mp[nmp].size = get_disk_size(conf, all_paths[k].dev); + + for (i = k + 1; i < conf->max_devs; i++) { + if (0 == strcmp(all_paths[k].wwid, all_paths[i].wwid)) { + np++; + PINDEX(nmp,np) = i; + mp[nmp].npaths = np; + } + } + } + return nmp; +} + static int make_dm_node(char * str) { @@ -611,7 +596,6 @@ add_map(struct env * conf, struct path * all_paths, char * params_p; struct dm_task *dmt; int i, np; - long size = -1; /* defaults for multipath target */ int dm_pg_prio = 1; @@ -627,8 +611,7 @@ add_map(struct env * conf, struct path * all_paths, np = 0; for (i=0; i<=mp[index].npaths; i++) { - if ((1 == all_paths[PINDEX(index,i)].state) && - (0 == all_paths[PINDEX(index,i)].sg_id.scsi_type)) + if (0 == all_paths[PINDEX(index,i)].sg_id.scsi_type) np++; } if (np == 0) @@ -637,33 +620,48 @@ add_map(struct env * conf, struct path * all_paths, if (np < 1) goto addout; - params_p += sprintf(params_p, "%i %i %s %i %i", - conf->dm_path_test_int, dm_pg_prio, - dm_ps_name, np, dm_ps_nr_args); - - for (i=0; i<=mp[index].npaths; i++) { - if (( 0 == all_paths[PINDEX(index,i)].state) || - (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type)) - continue; - if (size < 0) - size = get_disk_size(conf, all_paths[PINDEX(index,0)].dev); - params_p += sprintf(params_p, " %s", - all_paths[PINDEX(index,i)].dev); + params_p += sprintf(params_p, "%i", conf->dm_path_test_int); + + if (all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && + !conf->forcedfailover ) { + params_p += sprintf(params_p, " %i %s %i %i", + dm_pg_prio, dm_ps_name, np, dm_ps_nr_args); + + for (i=0; i<=mp[index].npaths; i++) { + if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) + continue; + params_p += sprintf(params_p, " %s", + all_paths[PINDEX(index,i)].dev); + } } - if (size < 0) + if (all_paths[PINDEX(index,0)].iopolicy == FAILOVER || + conf->forcedfailover) { + for (i=0; i<=mp[index].npaths; i++) { + if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) + continue; + params_p += sprintf(params_p, " %i %s ", + dm_pg_prio, dm_ps_name); + params_p += sprintf(params_p, "1 %i", + dm_ps_nr_args); + params_p += sprintf(params_p, " %s", + all_paths[PINDEX(index,i)].dev); + } + } + + if (mp[index].size < 0) goto addout; if (!conf->quiet) { if (op == DM_DEVICE_RELOAD) - printf("U|"); + printf("U:"); if (op == DM_DEVICE_CREATE) - printf("N|"); - printf("%s : 0 %li %s %s\n", - mp[index].wwid, size, DM_TARGET, params); + printf("N:"); + printf("%s:0 %li %s %s\n", + mp[index].wwid, mp[index].size, DM_TARGET, params); } - if (!dm_task_add_target(dmt, 0, size, DM_TARGET, params)) + if (!dm_task_add_target(dmt, 0, mp[index].size, DM_TARGET, params)) goto addout; if (!dm_task_run(dmt)) @@ -714,8 +712,10 @@ static void usage(char * progname) { fprintf(stderr, VERSION_STRING); - fprintf(stderr, "Usage: %s [-v|-q] [-d] [-i int] [-m max_devs]\n", progname); + fprintf(stderr, "Usage: %s [-v|-q] [-d] [-i int] [-m max_devs]\n", + progname); fprintf(stderr, "\t-d\t\tdry run, do not create or update devmaps\n"); + fprintf(stderr, "\t-f\t\tforce maps to failover mode (1 path/pg)\n"); fprintf(stderr, "\t-i\t\tmultipath target param : polling interval\n"); fprintf(stderr, "\t-m max_devs\tscan {max_devs} devices at most\n"); fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); @@ -759,6 +759,8 @@ main(int argc, char *argv[]) conf.quiet = 1; } else if (0 == strcmp("-d", argv[i])) conf.dry_run = 1; + else if (0 == strcmp("-f", argv[i])) + conf.forcedfailover = 1; else if (0 == strcmp("-i", argv[i])) conf.dm_path_test_int = atoi(argv[++i]); else if (0 == strcmp("scsi", argv[i])) diff --git a/extras/multipath/main.h b/extras/multipath/main.h index 0c5620ff74..3941c32e7c 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -48,6 +48,10 @@ #define BLKGETSIZE _IO(0x12,96) #define DM_TARGET "multipath" +/* Storage controlers cpabilities */ +#define FAILOVER 0 +#define MULTIBUS 1 + #define PINDEX(x,y) mp[(x)].pindex[(y)] /* global types */ @@ -80,16 +84,17 @@ struct path { char sg_dev[FILE_NAME_SIZE]; struct scsi_idlun scsi_id; struct sg_id sg_id; - int state; char wwid[WWID_SIZE]; char vendor_id[8]; char product_id[16]; char rev[4]; + int iopolicy; }; struct multipath { char wwid[WWID_SIZE]; int npaths; + long size; int pindex[MAX_MP_PATHS]; }; @@ -98,6 +103,7 @@ struct env { int verbose; int quiet; int dry_run; + int forcedfailover; int with_sysfs; int dm_path_test_int; char sysfs_path[FILE_NAME_SIZE]; diff --git a/extras/multipath/unsused.c b/extras/multipath/unused.c similarity index 62% rename from extras/multipath/unsused.c rename to extras/multipath/unused.c index ecdd695ac8..33b3e859d1 100644 --- a/extras/multipath/unsused.c +++ b/extras/multipath/unused.c @@ -1,3 +1,29 @@ +static int +do_tur(int fd) +{ + unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; + struct sg_io_hdr io_hdr; + unsigned char sense_buffer[32]; + + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (turCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_buffer); + io_hdr.dxfer_direction = SG_DXFER_NONE; + io_hdr.cmdp = turCmdBlk; + io_hdr.sbp = sense_buffer; + io_hdr.timeout = 20000; + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + close(fd); + return 0; + } + if (io_hdr.info & SG_INFO_OK_MASK) { + return 0; + } + return 1; +} + static int del_map(char * str) { struct dm_task *dmt; From 88bca8484d88ce543f40d631ec9048795a725c13 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Mon, 22 Dec 2003 20:52:01 -0800 Subject: [PATCH 0320/4284] [PATCH] extras multipath update incremental to 20031222, 2003-12-22 multipath-010 * introduce dm-simplecmd for RESUME & SUSPEND requests * split add_map() in setup_map() & dm-addmap() * setup_map() correctly submits "SUSPEND-RELOAD-RESUME or CREATE" sequences instead of the bogus "RELOAD or CREATE" --- extras/multipath/ChangeLog | 4 +++ extras/multipath/main.c | 70 ++++++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 21 deletions(-) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index dc29400e0e..ee26e06ac0 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,4 +1,8 @@ 2003-12-22 multipath-010 + * introduce dm-simplecmd for RESUME & SUSPEND requests + * split add_map() in setup_map() & dm-addmap() + * setup_map() correctly submits "SUSPEND-RELOAD-RESUME or CREATE" + sequences instead of the bogus "RELOAD or CREATE" * don't print .sg_dev if equal to .dev (2.6) in print_path() * since the kernel code handles defective paths, remove all code to cope with them : diff --git a/extras/multipath/main.c b/extras/multipath/main.c index c57cd4fe7e..293ee06fbc 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -589,12 +589,50 @@ make_dm_node(char * str) } static int -add_map(struct env * conf, struct path * all_paths, +dm_simplecmd(int task, const char *name) { + int r = 0; + struct dm_task *dmt; + + if (!(dmt = dm_task_create(task))) + return 0; + + if (!dm_task_set_name(dmt, name)) + goto out; + + r = dm_task_run(dmt); + + out: + dm_task_destroy(dmt); + return r; +} + +static int +dm_addmap(int task, const char *name, const char *params, long size) { + struct dm_task *dmt; + + if (!(dmt = dm_task_create(task))) + return 0; + + if (!dm_task_set_name(dmt, name)) + goto addout; + + if (!dm_task_add_target(dmt, 0, size, DM_TARGET, params)) + goto addout; + + if (!dm_task_run(dmt)) + goto addout; + + addout: + dm_task_destroy(dmt); + return 1; +} + +static int +setup_map(struct env * conf, struct path * all_paths, struct multipath * mp, int index, int op) { char params[255]; char * params_p; - struct dm_task *dmt; int i, np; /* defaults for multipath target */ @@ -602,11 +640,6 @@ add_map(struct env * conf, struct path * all_paths, char * dm_ps_name = "round-robin"; int dm_ps_nr_args = 0; - if (!(dmt = dm_task_create(op))) - return 0; - - if (!dm_task_set_name(dmt, mp[index].wwid)) - goto addout; params_p = ¶ms[0]; np = 0; @@ -614,11 +647,9 @@ add_map(struct env * conf, struct path * all_paths, if (0 == all_paths[PINDEX(index,i)].sg_id.scsi_type) np++; } - if (np == 0) - goto addout; if (np < 1) - goto addout; + return 0; params_p += sprintf(params_p, "%i", conf->dm_path_test_int); @@ -650,7 +681,7 @@ add_map(struct env * conf, struct path * all_paths, } if (mp[index].size < 0) - goto addout; + return 0; if (!conf->quiet) { if (op == DM_DEVICE_RELOAD) @@ -661,18 +692,15 @@ add_map(struct env * conf, struct path * all_paths, mp[index].wwid, mp[index].size, DM_TARGET, params); } - if (!dm_task_add_target(dmt, 0, mp[index].size, DM_TARGET, params)) - goto addout; + if (op == DM_DEVICE_RELOAD) + dm_simplecmd(DM_DEVICE_SUSPEND, mp[index].wwid); - if (!dm_task_run(dmt)) - goto addout; + dm_addmap(op, mp[index].wwid, params, mp[index].size); + if (op == DM_DEVICE_RELOAD) + dm_simplecmd(DM_DEVICE_RESUME, mp[index].wwid); make_dm_node(mp[index].wwid); - - addout: - dm_task_destroy(dmt); - return 1; } static int @@ -802,9 +830,9 @@ main(int argc, char *argv[]) for (k=0; k<=nmp; k++) { if (map_present(mp[k].wwid)) { - add_map(&conf, all_paths, mp, k, DM_DEVICE_RELOAD); + setup_map(&conf, all_paths, mp, k, DM_DEVICE_RELOAD); } else { - add_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); + setup_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); } } From 01ff79f58925dd26a717ae78f201d739053b5477 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Mon, 22 Dec 2003 20:53:55 -0800 Subject: [PATCH 0321/4284] [PATCH] extras multipath update incremental to 20031222-2, 2003-12-22 multipath-010 * tweak the install target in Makefile * stop passing fds as argument : this change enable a strict segregation of ugly 2.4 code * sysfs version of get_lun_strings() * be careful about the return of get_unique_id() since errors formerly caught up by if(open()) in the caller fn are now returned by get_unique_id() * send get_serial() in unused.c --- extras/multipath/ChangeLog | 8 +++ extras/multipath/Makefile | 6 +- extras/multipath/main.c | 137 +++++++++++++++++++------------------ extras/multipath/unused.c | 17 +++++ 4 files changed, 101 insertions(+), 67 deletions(-) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index ee26e06ac0..730d6e34a6 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,4 +1,12 @@ 2003-12-22 multipath-010 + * tweak the install target in Makefile + * stop passing fds as argument : this change enable a strict + segregation of ugly 2.4 code + * sysfs version of get_lun_strings() + * be careful about the return of get_unique_id() since errors + formerly caught up by if(open()) in the caller fn are now returned + by get_unique_id() + * send get_serial() in unused.c * introduce dm-simplecmd for RESUME & SUSPEND requests * split add_map() in setup_map() & dm-addmap() * setup_map() correctly submits "SUSPEND-RELOAD-RESUME or CREATE" diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index 89e6f35185..99036a6a00 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -4,9 +4,9 @@ EXEC = multipath -prefix = /usr/local +prefix = exec_prefix = ${prefix} -bindir = ${exec_prefix}/bin +bindir = ${exec_prefix}/sbin udevdir = ../.. klibcdir = $(udevdir)/klibc sysfsdir = $(udevdir)/libsysfs @@ -52,6 +52,8 @@ clean: install: install -d $(bindir) install -m 755 $(EXEC) $(bindir)/ + install -d /etc/hotplug.d/scsi/ + install -m 755 multipath.hotplug /etc/hotplug.d/scsi/ # Code dependencies main.o: main.c main.h sg_include.h diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 293ee06fbc..f62e0f9954 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -100,65 +100,89 @@ sprint_wwid(char * buff, const char * str) buff[WWID_SIZE - 1] = '\0'; } -static int -get_lun_strings(int fd, struct path * mypath) +static void +basename(char * str1, char * str2) { - char buff[36]; + char *p = str1 + (strlen(str1) - 1); - if (0 == do_inq(fd, 0, 0, 0, buff, 36, 1)) { + while (*--p != '/') + continue; + strcpy(str2, ++p); +} + +static int +get_lun_strings(struct env * conf, struct path * mypath) +{ + int fd; + char buff[36]; + char attr_path[FILE_NAME_SIZE]; + char basedev[FILE_NAME_SIZE]; + + if(conf->with_sysfs) { + /* sysfs style */ + basename(mypath->sg_dev, basedev); + + sprintf(attr_path, "%s/block/%s/device/vendor", + conf->sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + mypath->vendor_id, 8)) return 0; + + sprintf(attr_path, "%s/block/%s/device/model", + conf->sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + mypath->product_id, 16)) return 0; + + sprintf(attr_path, "%s/block/%s/device/rev", + conf->sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + mypath->rev, 4)) return 0; + } else { + /* ioctl style */ + if ((fd = open(mypath->sg_dev, O_RDONLY)) < 0) + return 0; + if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) + return 0; memcpy(mypath->vendor_id, &buff[8], 8); memcpy(mypath->product_id, &buff[16], 16); memcpy(mypath->rev, &buff[32], 4); + close(fd); return 1; } return 0; } -/* -static int -get_serial (int fd, char * str) -{ - char buff[MX_ALLOC_LEN + 1]; - int len; - - if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { - len = buff[3]; - if (len > 0) { - memcpy(str, buff + 4, len); - buff[len] = '\0'; - } - return 1; - } - return 0; -} -*/ - /* hardware vendor specifics : add support for new models below */ /* this one get EVPD page 0x83 off 8 */ /* tested ok with StorageWorks */ static int -get_evpd_wwid(int fd, char *str) +get_evpd_wwid(struct path * mypath) { + int fd; char buff[64]; + if ((fd = open(mypath->sg_dev, O_RDONLY)) < 0) + return 0; + if (0 == do_inq(fd, 0, 1, 0x83, buff, sizeof (buff), 1)) { - sprint_wwid(str, &buff[8]); - return 1; + sprint_wwid(mypath->wwid, &buff[8]); + close(fd); + return 1; /* success */ } - return 0; + close(fd); + return 0; /* not good */ } /* White list switch */ static int -get_unique_id(int fd, struct path * mypath) +get_unique_id(struct path * mypath) { int i; static struct { char * vendor; char * product; int iopolicy; - int (*getuid) (int fd, char * wwid); + int (*getuid) (struct path *); } wlist[] = { {"COMPAQ ", "HSV110 (C)COMPAQ", MULTIBUS, &get_evpd_wwid}, {"COMPAQ ", "MSA1000 ", MULTIBUS, &get_evpd_wwid}, @@ -183,24 +207,14 @@ get_unique_id(int fd, struct path * mypath) for (i = 0; wlist[i].vendor; i++) { if (strncmp(mypath->vendor_id, wlist[i].vendor, 8) == 0 && strncmp(mypath->product_id, wlist[i].product, 16) == 0) { - wlist[i].getuid(fd, mypath->wwid); mypath->iopolicy = wlist[i].iopolicy; - return 0; + if (!wlist[i].getuid(mypath)) + return 0; } } return 1; } -static void -basename(char * str1, char * str2) -{ - char *p = str1 + (strlen(str1) - 1); - - while (*--p != '/') - continue; - strcpy(str2, ++p); -} - static int blacklist (char * dev) { int i; @@ -230,7 +244,6 @@ static int get_all_paths_sysfs(struct env * conf, struct path * all_paths) { int k=0; - int sg_fd; struct sysfs_directory * sdir; struct sysfs_directory * devp; struct sysfs_link * linkp; @@ -252,11 +265,9 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) basename(conf->hotplugdev, buff); sprintf(curpath.sg_dev, "/dev/%s", buff); - if ((sg_fd = open(curpath.sg_dev, O_RDONLY)) < 0) - exit(1); - - get_lun_strings(sg_fd, &curpath); - get_unique_id(sg_fd, &curpath); + get_lun_strings(conf, &curpath); + if (!get_unique_id(&curpath)) + return 0; strcpy(refwwid, curpath.wwid); memset(&curpath, 0, sizeof(path)); } @@ -286,16 +297,12 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) basename(devp->path, buff); sprintf(curpath.sg_dev, "/dev/%s", buff); - if ((sg_fd = open(curpath.sg_dev, O_RDONLY)) < 0) { - if (conf->verbose) - fprintf(stderr, "can't open %s\n", - curpath.sg_dev); + get_lun_strings(conf, &curpath); + if(!get_unique_id(&curpath)) { + memset(&curpath, 0, sizeof(path)); continue; } - get_lun_strings(sg_fd, &curpath); - get_unique_id(sg_fd, &curpath); - if (memcmp(empty_buff, refwwid, WWID_SIZE) != 0 && strncmp(curpath.wwid, refwwid, WWID_SIZE) != 0) { memset(&curpath, 0, sizeof(path)); @@ -312,7 +319,6 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) /* done with curpath, zero for reuse */ memset(&curpath, 0, sizeof(path)); - close(sg_fd); basename(linkp->target, buff); sscanf(buff, "%i:%i:%i:%i", &all_paths[k].sg_id.host_no, @@ -329,7 +335,7 @@ static int get_all_paths_nosysfs(struct env * conf, struct path * all_paths, struct scsi_dev * all_scsi_ids) { - int k, i, sg_fd; + int k, i, fd; char buff[FILE_NAME_SIZE]; char file_name[FILE_NAME_SIZE]; @@ -338,19 +344,19 @@ get_all_paths_nosysfs(struct env * conf, struct path * all_paths, sprintf(buff, "%d", k); strncat(file_name, buff, FILE_NAME_SIZE); strcpy(all_paths[k].sg_dev, file_name); - if ((sg_fd = open(file_name, O_RDONLY)) < 0) { - if (conf->verbose) - fprintf(stderr, "can't open %s. mknod ?", - file_name); + + get_lun_strings(conf, &all_paths[k]); + if (!get_unique_id(&all_paths[k])) continue; - } - get_lun_strings(sg_fd, &all_paths[k]); - get_unique_id(sg_fd, &all_paths[k]); - if (0 > ioctl(sg_fd, SG_GET_SCSI_ID, &(all_paths[k].sg_id))) + + if ((fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) + return 0; + + if (0 > ioctl(fd, SG_GET_SCSI_ID, &(all_paths[k].sg_id))) printf("device %s failed on sg ioctl, skip\n", file_name); - close(sg_fd); + close(fd); for (i = 0; i < conf->max_devs; i++) { if ((all_paths[k].sg_id.host_no == @@ -701,6 +707,7 @@ setup_map(struct env * conf, struct path * all_paths, dm_simplecmd(DM_DEVICE_RESUME, mp[index].wwid); make_dm_node(mp[index].wwid); + return 1; } static int diff --git a/extras/multipath/unused.c b/extras/multipath/unused.c index 33b3e859d1..08144cf717 100644 --- a/extras/multipath/unused.c +++ b/extras/multipath/unused.c @@ -1,3 +1,20 @@ +static int +get_serial (int fd, char * str) +{ + char buff[MX_ALLOC_LEN + 1]; + int len; + + if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { + len = buff[3]; + if (len > 0) { + memcpy(str, buff + 4, len); + buff[len] = '\0'; + } + return 1; + } + return 0; +} + static int do_tur(int fd) { From f4f3939a6cfc4fa1fb6a1621fdfb0ef174f11e41 Mon Sep 17 00:00:00 2001 From: "ananth@in.ibm.com" Date: Mon, 22 Dec 2003 20:54:51 -0800 Subject: [PATCH 0322/4284] [PATCH] change pgsize In udev-009 and previous releases, for klibc compatibility, the pgsize var in sysfs_read_attribute() (file sysfs_dir.c under libsysfs) is handcoded to 0x4000. Should it not be 4096 bytes (0x1000 in hex) instead of 0x4000 (16k bytes)? --- libsysfs/sysfs_dir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index 7dbee8aba8..c159db7af8 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -274,7 +274,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) return -1; } #ifdef __KLIBC__ - pgsize = 0x4000; + pgsize = 0x1000; #else pgsize = sysconf(_SC_PAGESIZE); #endif From a8b01705c6204c660062cb6abc8fe7dbb8a42197 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Dec 2003 22:31:35 -0800 Subject: [PATCH 0323/4284] [PATCH] add ability to have up to 5 SYSFS_ file/value pairs for the LABEL rule. --- namedev.c | 91 ++++++++++++++++++++++++++++--------------------- namedev.h | 10 ++++-- namedev_parse.c | 47 +++++++++++++++++++------ 3 files changed, 97 insertions(+), 51 deletions(-) diff --git a/namedev.c b/namedev.c index 7c422f7877..d879fd5590 100644 --- a/namedev.c +++ b/namedev.c @@ -102,19 +102,6 @@ static int strcmp_pattern(const char *p, const char *s) if (strlen(b->var)) \ strcpy(a->var, b->var); -int add_config_dev(struct config_device *new_dev) -{ - struct config_device *tmp_dev; - - tmp_dev = malloc(sizeof(*tmp_dev)); - if (tmp_dev == NULL) - return -ENOMEM; - memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); - list_add_tail(&tmp_dev->node, &config_device_list); - //dump_config_dev(tmp_dev); - return 0; -} - int add_perm_dev(struct perm_device *new_dev) { struct list_head *tmp; @@ -432,12 +419,50 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev return -ENODEV; } -static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +static int match_pair(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair) { struct sysfs_attribute *tmpattr = NULL; + char *c; + + if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0')) + return -ENODEV; + + dbg("look for device attribute '%s'", pair->file); + /* try to find the attribute in the class device directory */ + tmpattr = sysfs_get_classdev_attr(class_dev, pair->file); + if (tmpattr) + goto label_found; + + /* look in the class device directory if present */ + if (sysfs_device) { + tmpattr = sysfs_get_device_attr(sysfs_device, pair->file); + if (tmpattr) + goto label_found; + } + + return -ENODEV; + +label_found: + c = tmpattr->value + strlen(tmpattr->value)-1; + if (*c == '\n') + *c = 0x00; + dbg("compare attribute '%s' value '%s' with '%s'", + pair->file, tmpattr->value, pair->value); + if (strcmp_pattern(pair->value, tmpattr->value) != 0) + return -ENODEV; + + dbg("found matching attribute '%s' with value '%s'", + pair->file, pair->value); + return 0; +} + +static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +{ + struct sysfs_pair *pair; struct config_device *dev; struct list_head *tmp; - char *c; + int i; + int match; list_for_each(tmp, &config_device_list) { dev = list_entry(tmp, struct config_device, node); @@ -450,34 +475,24 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, continue; } - dbg("look for device attribute '%s'", dev->sysfs_file); - /* try to find the attribute in the class device directory */ - tmpattr = sysfs_get_classdev_attr(class_dev, dev->sysfs_file); - if (tmpattr) - goto label_found; - - /* look in the class device directory if present */ - if (sysfs_device) { - tmpattr = sysfs_get_device_attr(sysfs_device, dev->sysfs_file); - if (tmpattr) - goto label_found; + match = 1; + for (i = 0; i < MAX_SYSFS_PAIRS; ++i) { + pair = &dev->sysfs_pair[i]; + if ((pair->file[0] == '\0') || (pair->value[0] == '\0')) + break; + if (match_pair(class_dev, sysfs_device, pair) != 0) { + match = 0; + break; + } } - - continue; - -label_found: - c = tmpattr->value + strlen(tmpattr->value)-1; - if (*c == '\n') - *c = 0x00; - dbg("compare attribute '%s' value '%s' with '%s'", - dev->sysfs_file, tmpattr->value, dev->sysfs_value); - if (strcmp_pattern(dev->sysfs_value, tmpattr->value) != 0) + if (match == 0) continue; + /* found match */ strfieldcpy(udev->name, dev->name); strfieldcpy(udev->symlink, dev->symlink); - dbg("found matching attribute '%s', '%s' becomes '%s' ", - dev->sysfs_file, class_dev->name, udev->name); + dbg("found matching attribute, '%s' becomes '%s' ", + class_dev->name, udev->name); return 0; } diff --git a/namedev.h b/namedev.h index 69c488936d..1eaf4fee4d 100644 --- a/namedev.h +++ b/namedev.h @@ -60,20 +60,25 @@ enum config_type { #define FIELD_SYMLINK "SYMLINK" #define CALLOUT_MAXARG 8 +#define MAX_SYSFS_PAIRS 5 + +struct sysfs_pair { + char file[FILE_SIZE]; + char value[VALUE_SIZE]; +}; struct config_device { struct list_head node; enum config_type type; char bus[BUS_SIZE]; - char sysfs_file[FILE_SIZE]; - char sysfs_value[VALUE_SIZE]; char id[ID_SIZE]; char place[PLACE_SIZE]; char kernel_name[NAME_SIZE]; char exec_program[FILE_SIZE]; char name[NAME_SIZE]; char symlink[NAME_SIZE]; + struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; }; struct perm_device { @@ -93,7 +98,6 @@ extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udev extern int namedev_init_permissions(void); extern int namedev_init_rules(void); -extern int add_config_dev(struct config_device *new_dev); extern int add_perm_dev(struct perm_device *new_dev); extern void dump_config_dev(struct config_device *dev); extern void dump_config_dev_list(void); diff --git a/namedev_parse.c b/namedev_parse.c index 33e0c89e22..266fa35a19 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -36,6 +36,19 @@ #include "udev.h" #include "namedev.h" +static int add_config_dev(struct config_device *new_dev) +{ + struct config_device *tmp_dev; + + tmp_dev = malloc(sizeof(*tmp_dev)); + if (tmp_dev == NULL) + return -ENOMEM; + memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); + list_add_tail(&tmp_dev->node, &config_device_list); + //dump_config_dev(tmp_dev); + return 0; +} + int get_pair(char **orig_string, char **left, char **right) { char *temp; @@ -78,8 +91,8 @@ void dump_config_dev(struct config_device *dev) dbg_parse("KERNEL name='%s'", dev->name); break; case LABEL: - dbg_parse("LABEL name='%s', bus='%s', sysfs_file='%s', sysfs_value='%s'", - dev->name, dev->bus, dev->sysfs_file, dev->sysfs_value); + dbg_parse("LABEL name='%s', bus='%s', sysfs_file[0]='%s', sysfs_value[0]='%s'", + dev->name, dev->bus, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value); break; case NUMBER: dbg_parse("NUMBER name='%s', bus='%s', id='%s'", @@ -225,9 +238,23 @@ keys: } if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) { - /* remove prepended 'SYSFS_' */ - strfieldcpy(dev.sysfs_file, temp2 + sizeof(FIELD_SYSFS)-1); - strfieldcpy(dev.sysfs_value, temp3); + struct sysfs_pair *pair = &dev.sysfs_pair[0]; + int sysfs_pair_num = 0; + + /* find first unused pair */ + while (pair->file[0] != '\0') { + ++sysfs_pair_num; + if (sysfs_pair_num >= MAX_SYSFS_PAIRS) { + pair = NULL; + break; + } + ++pair; + } + if (pair) { + /* remove prepended 'SYSFS_' */ + strfieldcpy(pair->file, temp2 + sizeof(FIELD_SYSFS)-1); + strfieldcpy(pair->value, temp3); + } continue; } @@ -258,13 +285,13 @@ keys: switch (dev.type) { case LABEL: dbg_parse(TYPE_LABEL " name='%s', bus='%s', " - "sysfs_file='%s', sysfs_value='%s', symlink='%s'", - dev.name, dev.bus, dev.sysfs_file, - dev.sysfs_value, dev.symlink); + "sysfs_file[0]='%s', sysfs_value[0]='%s', symlink='%s'", + dev.name, dev.bus, dev.sysfs_pair[0].file, + dev.sysfs_pair[0].value, dev.symlink); if ((*dev.name == '\0') || (*dev.bus == '\0') || - (*dev.sysfs_file == '\0') || - (*dev.sysfs_value == '\0')) + (*dev.sysfs_pair[0].file == '\0') || + (*dev.sysfs_pair[0].value == '\0')) goto error; break; case NUMBER: From 358c8c20239a314b4684c54485c526deaf36dd3b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Dec 2003 22:32:06 -0800 Subject: [PATCH 0324/4284] [PATCH] add tests for multi-file LABEL rules. --- test/label_test | 3 ++- test/udev-test.pl | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/test/label_test b/test/label_test index 2e05692581..cf0d2eb09c 100644 --- a/test/label_test +++ b/test/label_test @@ -8,7 +8,8 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", NAME="boot_disk%n" +LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_diskX%n" +LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_disk%n" EOF cat > $CONFIG << EOF diff --git a/test/udev-test.pl b/test/udev-test.pl index 7afbd0d6fc..4773954b9c 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -61,6 +61,26 @@ LABEL, BUS="scsi", SYSFS_vendor="?IBM-ESXS", NAME="boot_disk%n-1" LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS?", NAME="boot_disk%n-2" LABEL, BUS="scsi", SYSFS_vendor="IBM-ES??", NAME="boot_disk%n" LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXSS", NAME="boot_disk%n-3" +EOF + }, + { + desc => "label test of multiple sysfs files", + subsys => "block", + devpath => "block/sda/sda1", + expected => "boot_disk1" , + conf => < "label test of max sysfs files", + subsys => "block", + devpath => "block/sda/sda1", + expected => "boot_disk1" , + conf => < Date: Mon, 22 Dec 2003 22:36:10 -0800 Subject: [PATCH 0325/4284] [PATCH] add documentation about the multiple sysfs values that are now allowed for the LABEL rule. --- udev.8 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/udev.8 b/udev.8 index c4ee23dcc7..5e411282ff 100644 --- a/udev.8 +++ b/udev.8 @@ -112,7 +112,8 @@ calling external program, that returns a string to match .TP .B LABEL device label or serial number, like USB serial number, SCSI UUID or -file system label +file system label. Up to 5 different sysfs files can be checked, with +all of the values being required in order to match the rule. .br .RB "keys: " BUS ", " SYSFS_ .TP @@ -168,6 +169,9 @@ CALLOUT, BUS="scsi", PROGRAM="/sbin/scsi_id", ID="OEM 0815", NAME="disk1" # USB printer to be called lp_color LABEL, BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_color" +# SCSI disk with a specific vendor and model number is to be called boot +LABEL, BUS="scsi", SYSFS_vendor="IBM", SYSFS_model="ST336", NAME="boot%n" + # sound card with PCI bus id 00:0b.0 to be called dsp NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" From 170ae44e7d45e5907668cd1eab740a84eb79c70a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Dec 2003 22:40:19 -0800 Subject: [PATCH 0326/4284] [PATCH] add documentation for the new '%k' modifier (kernel name replacement) --- udev.8 | 3 +++ udev.rules | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/udev.8 b/udev.8 index 5e411282ff..f2006c42dc 100644 --- a/udev.8 +++ b/udev.8 @@ -142,6 +142,9 @@ fields support simple printf-like string substitution: The "kernel number" of the device. for example, 'sda3' has a "kernel number" of '3' .TP +.B %k +The "kernel name" for the device. +.TP .B %M The kernel major number for the device. .TP diff --git a/udev.rules b/udev.rules index 618737ffd8..06d5842c2a 100644 --- a/udev.rules +++ b/udev.rules @@ -2,6 +2,7 @@ # 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 @@ -16,7 +17,7 @@ CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" # A usb camera. -LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", NAME="camera%n" +LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" # USB Epson printer to be called lp_epson LABEL, BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" From ca593541e63b6accd1f8c5f5592ada4b85930576 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Dec 2003 22:45:43 -0800 Subject: [PATCH 0327/4284] [PATCH] fix complier warning in namedev.c --- namedev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/namedev.c b/namedev.c index d879fd5590..c77b0f8ef4 100644 --- a/namedev.c +++ b/namedev.c @@ -714,7 +714,6 @@ exit: int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) { struct sysfs_device *sysfs_device = NULL; - struct sysfs_class_device *class_dev_parent = NULL; int retval = 0; struct perm_device *perm; char *pos; From 808423c90c113294c09faafafebdf4556a093e80 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Dec 2003 22:47:58 -0800 Subject: [PATCH 0328/4284] [PATCH] small cleanup udev-remove.c Here is a small cleanup. It replaces the malloc in udev-remove.c with a struct, like we do in udev-add.c --- udev-remove.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/udev-remove.c b/udev-remove.c index 6d7e2ad22a..c5de6c823f 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -118,30 +118,26 @@ static int delete_node(struct udevice *dev) */ int udev_remove_device(char *path, char *subsystem) { - struct udevice *dev; + struct udevice dev; char *temp; int retval; - dev = malloc(sizeof(*dev)); - if (dev == NULL) - return -ENOMEM; - memset(dev, 0, sizeof(*dev)); + memset(&dev, 0, sizeof(dev)); - retval = udevdb_get_dev(path, dev); + retval = udevdb_get_dev(path, &dev); if (retval) { dbg("'%s' not found in database, falling back on default name", path); temp = strrchr(path, '/'); if (temp == NULL) return -ENODEV; - strncpy(dev->name, &temp[1], sizeof(dev->name)); + strncpy(dev.name, &temp[1], sizeof(dev.name)); } - dbg("name is '%s'", dev->name); + dbg("name is '%s'", dev.name); udevdb_delete_dev(path); - sysbus_send_remove(dev->name, path); + sysbus_send_remove(dev.name, path); - retval = delete_node(dev); - free(dev); + retval = delete_node(&dev); return retval; } From 5cac7def788fc6dec19dc8185f9c2c7c7c8d49a2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Dec 2003 23:30:51 -0800 Subject: [PATCH 0329/4284] [PATCH] fix udev-test.pl Here is a small fix for udev-test.pl, to print the METHOD also for the "whitespace config" tests. TEST: Handle comment lines in config file (and replace kernel name) method '' for 'class/tty/ttyUSB0' expecting node 'visor' add: ok remove: ok --- test/udev-test.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 4773954b9c..3e7068faa6 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -328,7 +328,7 @@ print CONF "udev_permissions=\"$perm\"\n"; close CONF; foreach my $config (@tests) { - $config->{conf} =~ m/^([A-Z]*).*/; + $config->{conf} =~ m/([A-Z]+)\s*,/; my $method = $1; print "TEST: $config->{desc}\n"; From 1e5b0d2fc975e6202239b1b97065baab2ce8196e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 23 Dec 2003 00:33:29 -0800 Subject: [PATCH 0330/4284] [PATCH] v010 release --- ChangeLog | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cb8fa7f15c..d50e3a5cce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,54 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 5833d4cb94..785ad96349 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 009_bk +VERSION = 010 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 2e5a472a52..cdfc23e198 100644 --- a/udev.spec +++ b/udev.spec @@ -1,6 +1,6 @@ Summary: A userspace implementation of devfs Name: udev -Version: 009_bk +Version: 010 Release: 1 License: GPL Group: Utilities/System From 07562d6ecf64f708a3a20388200ec8bd9c5a3774 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 19:44:19 -0800 Subject: [PATCH 0331/4284] [PATCH] fix long delay for all devices in namedev Now we only sleep if we can't find the device file, and we have a hack to sleep for 1 second if we are on a partition. This will be removed when the libsysfs change gets made... --- namedev.c | 110 ++++++++++++++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 58 deletions(-) diff --git a/namedev.c b/namedev.c index c77b0f8ef4..1e600bbe6d 100644 --- a/namedev.c +++ b/namedev.c @@ -624,57 +624,51 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de struct sysfs_device *sysfs_device; struct sysfs_class_device *class_dev_parent; int loop; + char filename[SYSFS_PATH_MAX + 6]; + int retval; + char *temp; + int partition = 0; - /* FIXME!!! */ - /* This is needed here as we can easily out-race the placement of the - * device symlink by the kernel. The call to sleep(1); will be removed - * once libsysfs can be queried for sysfs_get_classdev_device() - * multiple times and have it return the proper information when the - * class device really shows up. For now, we live with the time - * delay... + /* Figure out where the device symlink is at. For char devices this will + * always be in the class_dev->path. But for block devices, it's different. + * The main block device will have the device symlink in it's path, but + * all partitions have the symlink in its parent directory. + * But we need to watch out for block devices that do not have parents, yet + * look like a partition (fd0, loop0, etc.) They all do not have a device + * symlink yet. We do sit and spin on waiting for them right now, we should + * possibly have a whitelist for these devices here... */ - sleep(1); + strcpy(filename, class_dev->path); + dbg("filename = %s", filename); + if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { + if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { + temp = strrchr(filename, '/'); + if (temp) { + partition = 1; + *temp = 0x00; + char *temp2 = strrchr(filename, '/'); + dbg("temp2 = %s", temp2); + if (temp2 && (strcmp(temp2, "/block") == 0)) { + /* oops, we have no parent block device, so go back to original directory */ + strcpy(filename, class_dev->path); + partition = 0; + } + } + } + } + strcat(filename, "/device"); -#if 0 /* FIXME - Something like this could also work, but for some reason doesn't, - I also tried just stat() on the device symlink, but that still - has nasty races, I'm probably doing something stupid... :( */ - loop = 10; + loop = 2; while (loop--) { struct stat buf; - int retval; - char filename[SYSFS_PATH_MAX + 6]; - - strcpy(filename, class_dev->path); - strcat(filename, "/device"); dbg("looking for '%s'", filename); retval = stat(filename, &buf); if (!retval) break; - - /* bah, let's go backwards up a level to see if the device is there, - * as block partitions don't point to the physical device. Need to fix that - * up in the kernel... - */ - if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent == NULL) { - dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); - } else { - strcpy(filename, class_dev_parent->path); - strcat(filename, "/device"); - dbg("looking for '%s'", filename); - retval = stat(filename, &buf); - if (!retval) - break; - } - } - } /* sleep to give the kernel a chance to create the device file */ sleep(1); } -#endif + loop = 1; /* FIXME put a real value in here for when everything is fixed... */ while (loop--) { /* find the sysfs_device for this class device */ @@ -683,28 +677,28 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de if (sysfs_device != NULL) goto exit; - /* bah, let's go backwards up a level to see if the device is there, - * as block partitions don't point to the physical device. Need to fix that - * up in the kernel... - */ - if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { - dbg("looking at block device"); - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - dbg("really is a partition"); - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent == NULL) { - dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); - } else { - dbg("class_dev_parent->name='%s'", class_dev_parent->name); - sysfs_device = sysfs_get_classdev_device(class_dev_parent); - if (sysfs_device != NULL) - goto exit; - } + /* if it's a partition, we need to get the parent device */ + if (partition) { + /* FIXME HACK HACK HACK HACK + * for some reason partitions need this extra sleep here, in order + * to wait for the device properly. Once the libsysfs code is + * fixed properly, this sleep should go away, and we can just loop above. + */ + sleep(1); + dbg("really is a partition"); + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent == NULL) { + dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); + } else { + dbg("class_dev_parent->name='%s'", class_dev_parent->name); + sysfs_device = sysfs_get_classdev_device(class_dev_parent); + if (sysfs_device != NULL) + goto exit; } } /* sleep to give the kernel a chance to create the link */ - sleep(1); - + /* FIXME remove comment... + sleep(1); */ } dbg("Timed out waiting for device symlink, continuing on anyway..."); exit: From 5779dd31f49b41d52d1f08c2eb4239926fa58864 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 21:25:40 -0800 Subject: [PATCH 0332/4284] [PATCH] make udev init script run udev in the background to let startup go much faster --- etc/init.d/udev | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/etc/init.d/udev b/etc/init.d/udev index 36ef2dafda..c540057d21 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -28,13 +28,13 @@ case "$1" in for i in ${sysfs_dir}/block/*; do # add each drive export DEVPATH=${i#${sysfs_dir}} - $bin block + $bin block & # add each partition, on each device for j in $i/*; do if [ -f $j/dev ]; then export DEVPATH=${j#${sysfs_dir}} - $bin block + $bin block & fi done done @@ -45,13 +45,14 @@ case "$1" in export DEVPATH=${j#${sysfs_dir}} CLASS=`echo ${i#${sysfs_dir}} | \ cut --delimiter='/' --fields=3-` - $bin $CLASS + $bin $CLASS & fi done done ;; stop) # be careful + action "Removing udev device nodes: " /bin/true if [ $udev_dir -a "$udev_dir" != "/" ]; then # clear out /udev rm -rf ${udev_dir}/* From 18c783a7e6acab9590980a54978a129f7b3dca81 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 21:47:14 -0800 Subject: [PATCH 0333/4284] [PATCH] more init script cleanups, the stop target now calls udev to cleanup instead of just removing the whole /udev directory. --- etc/init.d/udev | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/etc/init.d/udev b/etc/init.d/udev index c540057d21..0d26d07083 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -11,20 +11,8 @@ udev_dir=/udev sysfs_dir=/sys bin=/sbin/udev -case "$1" in - start) - if [ ! -d $udev_dir ]; then - mkdir $udev_dir - fi - if [ ! -d $sysfs_dir ]; then - exit 1 - fi - # propogate /udev from /sys - we only need this while we do not - # have initramfs and an early user-space with which to do early - # device bring up - action "Creating initial udev device nodes: " /bin/true - export ACTION=add - # add block devices and their partitions +run_udev () { + # handle block devices and their partitions for i in ${sysfs_dir}/block/*; do # add each drive export DEVPATH=${i#${sysfs_dir}} @@ -49,14 +37,29 @@ case "$1" in fi done done +} + + +case "$1" in + start) + if [ ! -d $udev_dir ]; then + mkdir $udev_dir + fi + if [ ! -d $sysfs_dir ]; then + exit 1 + fi + # propogate /udev from /sys - we only need this while we do not + # have initramfs and an early user-space with which to do early + # device bring up + action "Creating initial udev device nodes: " /bin/true + export ACTION=add + run_udev ;; stop) # be careful action "Removing udev device nodes: " /bin/true - if [ $udev_dir -a "$udev_dir" != "/" ]; then - # clear out /udev - rm -rf ${udev_dir}/* - fi + export ACTION=remove + run_udev ;; status) if [ -d $udev_dir ]; then From bc64a25fd223d8e0cbc0a4aa2ef8cc03e1d60562 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 21:48:18 -0800 Subject: [PATCH 0334/4284] [PATCH] check for empty line a bit better in the parser. Thanks to Mitch for pointing this out. --- namedev_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 266fa35a19..4526203253 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -176,7 +176,7 @@ int namedev_init_rules(void) ++temp; /* empty line? */ - if (*temp == 0x00) + if ((*temp == 0x00) || (*temp == 0x0a)) continue; /* see if this is a comment */ @@ -378,7 +378,7 @@ int namedev_init_permissions(void) ++temp; /* empty line? */ - if (*temp == 0x00) + if ((*temp == 0x00) || (*temp == 0x0a)) continue; /* see if this is a comment */ From 480763324d812d3d5eb11cbe898a9b358b6fedbf Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 22:51:16 -0800 Subject: [PATCH 0335/4284] [PATCH] add pci to the bus_files list. --- namedev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/namedev.c b/namedev.c index 1e600bbe6d..e474b48e57 100644 --- a/namedev.c +++ b/namedev.c @@ -252,6 +252,7 @@ static struct bus_file { } bus_files[] = { { .bus = "scsi", .file = "vendor" }, { .bus = "usb", .file = "idVendor" }, + { .bus = "pci", .file = "vendor" }, {} }; From ee15698133ecd754c0d847b6ebb3a533536a42dc Mon Sep 17 00:00:00 2001 From: "mh@nadir.org" Date: Wed, 24 Dec 2003 22:54:39 -0800 Subject: [PATCH 0336/4284] [PATCH] patch udev 009-010 rpm spec file the following problem was introduced with udev 009: [root@claw packages]# rpm -Uvh ~mh/rpm/RPMS/ppc/udev-010-1.ppc.rpm Preparing...########################################### [100%] 1:udev ########################################### [100%] error: unpacking of archive failed on file /usr/share/doc/udev-010/COPYING;3fe8a8e3: cpio: open failed - Permission denied it's because the mode of the directory /usr/share/doc/udev-010/ is 0644. This is with yellodog-3.0. the following patch fixes it: --- udev.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index cdfc23e198..6530c557c7 100644 --- a/udev.spec +++ b/udev.spec @@ -35,7 +35,7 @@ fi rm -rf $RPM_BUILD_ROOT %files -%defattr(0644,root,root) +%defattr(-,root,root) %doc COPYING README TODO ChangeLog %attr(755,root,root) /sbin/udev %attr(755,root,root) /udev/ From df496acbee49c5974f9ed42a92cca4a119315643 Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Wed, 24 Dec 2003 22:58:16 -0800 Subject: [PATCH 0337/4284] [PATCH] proper cleanup on udevdb_init() failure Seems like we need the following patch to do proper sysbus cleanup, if udevdb_init() fails. --- udev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udev.c b/udev.c index ac29ec6f44..71c5f1fba5 100644 --- a/udev.c +++ b/udev.c @@ -119,7 +119,7 @@ int main(int argc, char **argv, char **envp) retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { dbg("unable to initialize database"); - goto exit; + goto exit_sysbus; } /* initialize the naming deamon */ @@ -137,6 +137,7 @@ int main(int argc, char **argv, char **envp) } udevdb_exit(); +exit_sysbus: /* disconnect from the system message bus */ sysbus_disconnect(); From 335e433720e8cdb5ca0f9caeb76ab9d525e96260 Mon Sep 17 00:00:00 2001 From: "svetljo@gmx.de" Date: Wed, 24 Dec 2003 23:01:40 -0800 Subject: [PATCH 0338/4284] [PATCH] fix udev sed Makefile usage --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 785ad96349..61abc1f60e 100644 --- a/Makefile +++ b/Makefile @@ -209,7 +209,7 @@ GEN_CONFIGS = udev.conf # Rules on how to create the generated config files udev.conf: - sed -e "s-@udevdir@-$(udevdir)-" < udev.conf.in > $@ + sed -e "s:@udevdir@:$(udevdir):" < udev.conf.in > $@ $(OBJS): $(GEN_HEADERS) From 0c6758962ba9f1d238962611faca7c2cb2290bfb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 23:38:58 -0800 Subject: [PATCH 0339/4284] [PATCH] added different build options to the rpm udev.spec file. --- udev.spec | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index 6530c557c7..9f923ef9ab 100644 --- a/udev.spec +++ b/udev.spec @@ -1,3 +1,21 @@ +# if we want to build against the included version of klibc or not. +# 0 - do not use klibc +# 1 - use klibc +# Watch out for where the linux symlink is in the klibc part of the tarball, +# it probably is not where you want it to be. +%define klibc 1 + +# if we want to build DBUS support in or not. +# 0 - no DBUS support +# 1 - DBUS support +%define dbus 0 + +# if we want to enable debugging support in udev. If it is enabled, lots of +# stuff will get sent to the debug syslog. +# 0 - debugging disabled +# 1 - debugging enabled +%define debug 0 + Summary: A userspace implementation of devfs Name: udev Version: 010 @@ -18,7 +36,16 @@ udev is a implementation of devfs in userspace using sysfs and %setup -q %build -make CC="gcc $RPM_OPT_FLAGS" +make CC="gcc $RPM_OPT_FLAGS" \ +%if %{klibc} + USE_KLIBC=true \ +%endif +%if %{dbus} + USE_DBUS=true \ +%endif +%if %{debug} + DEBUG=true \ +%endif %install make DESTDIR=$RPM_BUILD_ROOT install From fe0a916c31fd597d29adbfb701656c08b462bcbe Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 23:56:29 -0800 Subject: [PATCH 0340/4284] [PATCH] 010_bk stamp --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 61abc1f60e..d2e6fd559d 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 010 +VERSION = 010_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 9f923ef9ab..431dfd8be5 100644 --- a/udev.spec +++ b/udev.spec @@ -18,7 +18,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 010 +Version: 010_bk Release: 1 License: GPL Group: Utilities/System From 8ff8bbbaddaa30a7ec60d066652bca2628eaeb69 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Dec 2003 23:56:54 -0800 Subject: [PATCH 0341/4284] [PATCH] add test for callout rule with a device that has no bus. --- test/udev-test.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 3e7068faa6..ea1d8611ef 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -212,6 +212,16 @@ EOF expected => "link1" , conf => < "callout for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + expected => "TTY" , + conf => < Date: Thu, 25 Dec 2003 00:03:56 -0800 Subject: [PATCH 0342/4284] [PATCH] Don't require the BUS value for the CALLOUT rule. --- namedev_parse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/namedev_parse.c b/namedev_parse.c index 4526203253..449aa44eaa 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -324,7 +324,6 @@ keys: dev.name, dev.bus, dev.exec_program, dev.id, dev.symlink); if ((*dev.name == '\0') || - (*dev.bus == '\0') || (*dev.id == '\0') || (*dev.exec_program == '\0')) goto error; From 1d936fbca0b93dd9cc7a71983ca1a8ea890f181d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Dec 2003 00:05:28 -0800 Subject: [PATCH 0343/4284] [PATCH] If a CALLOUT rule has a BUS id, then we must check to see if the device is on a bus. Thanks to Martin Schlemmer for pointing this out. --- namedev.c | 5 ++++- test/udev-test.pl | 11 ++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index e474b48e57..de1b206180 100644 --- a/namedev.c +++ b/namedev.c @@ -399,7 +399,10 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev if (dev->type != CALLOUT) continue; - if (sysfs_device) { + if (dev->bus[0] != '\0') { + /* as the user specified a bus, we must match it up */ + if (!sysfs_device) + continue; dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcasecmp(dev->bus, sysfs_device->bus) != 0) continue; diff --git a/test/udev-test.pl b/test/udev-test.pl index ea1d8611ef..9538cba2d1 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -215,13 +215,22 @@ CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n node link1 link2", ID="node *", NAME= EOF }, { - desc => "callout for device with no bus", + desc => "invalid callout for device with no bus", subsys => "tty", devpath => "class/tty/console", expected => "TTY" , conf => < "valid callout for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + expected => "foo" , + conf => < Date: Thu, 25 Dec 2003 00:08:55 -0800 Subject: [PATCH 0344/4284] [PATCH] add documentation about the BUS key being optional for the CALLOUT rule. --- udev.8 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/udev.8 b/udev.8 index f2006c42dc..0a0640ad8c 100644 --- a/udev.8 +++ b/udev.8 @@ -106,7 +106,10 @@ The line format is: where valid methods with corresponding keys are: .TP .B CALLOUT -calling external program, that returns a string to match +calling external program, that returns a string to match. The +.BR BUS +key is optional, but if specified, the sysfs device bus must be able to be +detemined by a "device" symlink. .br .RB "keys: " BUS ", " PROGRAM ", " ID .TP From a7402175da70f53d308450b50dd0c00cb733276e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Dec 2003 00:33:00 -0800 Subject: [PATCH 0345/4284] [PATCH] If a LABEL rule has a BUS id, then we must check to see if the device is on a bus. --- namedev.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index de1b206180..813f26b035 100644 --- a/namedev.c +++ b/namedev.c @@ -473,7 +473,10 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, if (dev->type != LABEL) continue; - if (sysfs_device) { + if (dev->bus[0] != '\0') { + /* as the user specified a bus, we must match it up */ + if (!sysfs_device) + continue; dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcasecmp(dev->bus, sysfs_device->bus) != 0) continue; From 2ae1a0c6f33a2050346269588416e715ed8d4cfa Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Dec 2003 00:33:27 -0800 Subject: [PATCH 0346/4284] [PATCH] Don't require the BUS value for the LABEL rule. --- namedev_parse.c | 1 - 1 file changed, 1 deletion(-) diff --git a/namedev_parse.c b/namedev_parse.c index 449aa44eaa..aec87d2771 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -289,7 +289,6 @@ keys: dev.name, dev.bus, dev.sysfs_pair[0].file, dev.sysfs_pair[0].value, dev.symlink); if ((*dev.name == '\0') || - (*dev.bus == '\0') || (*dev.sysfs_pair[0].file == '\0') || (*dev.sysfs_pair[0].value == '\0')) goto error; From 64682333bb02d946c179bc729da687f6c85bf9e8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Dec 2003 00:33:56 -0800 Subject: [PATCH 0347/4284] [PATCH] add tests for LABEL rule with a device that has no bus. --- test/udev-test.pl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 9538cba2d1..97c0094921 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -231,6 +231,27 @@ EOF expected => "foo" , conf => < "invalid label for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + expected => "TTY" , + conf => < "valid label for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + expected => "foo" , + conf => < Date: Thu, 25 Dec 2003 00:35:09 -0800 Subject: [PATCH 0348/4284] [PATCH] add documentation about the BUS key being optional for the LABEL rule. --- udev.8 | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/udev.8 b/udev.8 index 0a0640ad8c..65af6d00a8 100644 --- a/udev.8 +++ b/udev.8 @@ -116,7 +116,10 @@ detemined by a "device" symlink. .B LABEL device label or serial number, like USB serial number, SCSI UUID or file system label. Up to 5 different sysfs files can be checked, with -all of the values being required in order to match the rule. +all of the values being required in order to match the rule. The +.BR BUS +key is optional, but if specified, the sysfs device bus must be able to be +detemined by a "device" symlink. .br .RB "keys: " BUS ", " SYSFS_ .TP From d7577c8b90b112f414837a708e5440b91794737b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Dec 2003 00:38:45 -0800 Subject: [PATCH 0349/4284] [PATCH] v011 release --- ChangeLog | 30 ++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d50e3a5cce..fa12f67046 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +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 ============================================ diff --git a/Makefile b/Makefile index d2e6fd559d..4c8c8d7dad 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 010_bk +VERSION = 011 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 431dfd8be5..4283521326 100644 --- a/udev.spec +++ b/udev.spec @@ -18,7 +18,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 010_bk +Version: 011 Release: 1 License: GPL Group: Utilities/System From 1f99bc3254d8d996408ad712b149d115505c8422 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 30 Dec 2003 00:52:16 -0800 Subject: [PATCH 0350/4284] [PATCH] 011_bk tag --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4c8c8d7dad..06c564ec57 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 011 +VERSION = 011_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) diff --git a/udev.spec b/udev.spec index 4283521326..a81720e7c4 100644 --- a/udev.spec +++ b/udev.spec @@ -18,7 +18,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 011 +Version: 011_bk Release: 1 License: GPL Group: Utilities/System From e15b5ed5ded18af1329b304fc650a1cbc8123ccc Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 00:54:29 -0800 Subject: [PATCH 0351/4284] [PATCH] small trivial cleanup of latest changes here is a patch for a typo in the man page, a whitespace cleanup and a replace for the magic hex ASCII in char operations. --- namedev_parse.c | 4 ++-- udev.8 | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index aec87d2771..2858a28091 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -176,7 +176,7 @@ int namedev_init_rules(void) ++temp; /* empty line? */ - if ((*temp == 0x00) || (*temp == 0x0a)) + if ((*temp == '\0') || (*temp == '\n')) continue; /* see if this is a comment */ @@ -376,7 +376,7 @@ int namedev_init_permissions(void) ++temp; /* empty line? */ - if ((*temp == 0x00) || (*temp == 0x0a)) + if ((*temp == '\0') || (*temp == '\n')) continue; /* see if this is a comment */ diff --git a/udev.8 b/udev.8 index 65af6d00a8..eb772c9dbe 100644 --- a/udev.8 +++ b/udev.8 @@ -78,7 +78,7 @@ udev_rules="/etc/udev/udev.rules" # udev_permissions - The name and location of the udev permission file udev_permissions="/etc/udev/udev.permissions" -# default_mode - set the default mode for all nodes that have no +# default_mode - set the default mode for all nodes that have no # explicit match in the permissions file default_mode="0666" .fi @@ -106,18 +106,18 @@ The line format is: where valid methods with corresponding keys are: .TP .B CALLOUT -calling external program, that returns a string to match. The -.BR BUS +calling external program, that returns a string to match. The +.B BUS key is optional, but if specified, the sysfs device bus must be able to be -detemined by a "device" symlink. +determined by a "device" symlink. .br .RB "keys: " BUS ", " PROGRAM ", " ID .TP .B LABEL device label or serial number, like USB serial number, SCSI UUID or file system label. Up to 5 different sysfs files can be checked, with -all of the values being required in order to match the rule. The -.BR BUS +all of the values being required in order to match the rule. The +.B BUS key is optional, but if specified, the sysfs device bus must be able to be detemined by a "device" symlink. .br From 5e22c4df53cf8c8c3868cc9789027a929c4f9a60 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 30 Dec 2003 00:58:31 -0800 Subject: [PATCH 0352/4284] [PATCH] added udev.init script for the Linux From Scratch project. Thanks to Michael Buesch for providing it. --- etc/init.d/udev.init.lfs | 103 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) create mode 100644 etc/init.d/udev.init.lfs diff --git a/etc/init.d/udev.init.lfs b/etc/init.d/udev.init.lfs new file mode 100644 index 0000000000..08c81733e1 --- /dev/null +++ b/etc/init.d/udev.init.lfs @@ -0,0 +1,103 @@ +#!/bin/sh +# +# LinuxFromScratch udev init script +# derived from original RedHat udev init script +# 2003 by Michael Buesch +# + +source /etc/sysconfig/rc +source $rc_functions + +udev_dir="/udev" +sysfs_dir="/sys" +bin="/sbin/udev" + +case "$1" in + start) + echo "Creating initial udev device nodes ..." + if [ ! -d $udev_dir ]; then + mkdir $udev_dir + if [ $? -ne 0 ]; then + print_status failure + exit 1 + fi + fi + if [ ! -d $sysfs_dir ]; then + echo "sysfs_dir $sysfs_dir does not exist!" + print_status failure + exit 1 + fi + # propogate /udev from /sys - we only need this while we do not + # have initramfs and an early user-space with which to do early + # device bring up + clean_exit="yes" + export ACTION=add + # add block devices and their partitions + for i in ${sysfs_dir}/block/*; do + # add each drive + export DEVPATH=${i#${sysfs_dir}} + $bin block + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + $bin block + if [ $? -ne 0 ]; then + echo "Warning: $DEVPATH failed." + clean_exit="no" + fi + fi + done + done + # all other device classes + for i in ${sysfs_dir}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + CLASS=`echo ${i#${sysfs_dir}} | \ + cut --delimiter='/' --fields=3-` + $bin $CLASS + if [ $? -ne 0 ]; then + echo "Warning: $DEVPATH failed." + clean_exit="no" + fi + fi + done + done + if [ $clean_exit = "yes" ]; then + print_status success + else + print_status warning + fi + ;; + stop) + echo "Removing udev device nodes ..." + # be careful + if [ $udev_dir -a "$udev_dir" != "/" ]; then + # clear out /udev + rm -rf ${udev_dir}/* + evaluate_retval + fi + ;; + reload) + # nothing to do here + ;; + restart) + $0 stop + sleep 1 + $0 start + ;; + status) + if [ -d $udev_dir ]; then + echo "the udev device node directory exists" + else + echo "the udev device node directory does not exist" + fi + ;; + *) + echo "Usage: $0 {start|stop|restart|status}" + exit 1 + ;; +esac +exit 0 From 41e559861b1c018b17f0ad2819fa73f0d98c066a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 30 Dec 2003 01:01:05 -0800 Subject: [PATCH 0353/4284] [PATCH] update the udev.permissions.debian file with new entries. Thanks to Mathieu Segaud for the information --- udev.permissions.debian | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/udev.permissions.debian b/udev.permissions.debian index b4ddacfcdd..294982a824 100644 --- a/udev.permissions.debian +++ b/udev.permissions.debian @@ -1,7 +1,11 @@ # name:user:group:mode -# character devices +# CHARACTER DEVICES +# tty devices +tty:root:tty:0660 +console:root:tty:0600 +ptmx:root:tty:0666 ttyACM*:root:dialout:0660 ttyUSB*:root:dialout:0660 ttyI*:root:dialout:0660 @@ -28,6 +32,20 @@ capi*:root:dialout:0660 dcbri*:root:dialout:0660 ircomm*:root:dialout:0660 +# Memory devices +random:root:root:0666 +urandom:root:root:0444 +mem:root:kmem:0640 +kmem:root:kmem:0640 +port:root:kmem:0640 +full:root:root:0666 +null:root:root:0666 +zero:root:root:0666 + +# Misc devices +nvram:root:root:0660 +rtc:root:root:0660 + admmidi*:root:audio:660 adsp*:root:audio:660 aload*:root:audio:660 @@ -55,7 +73,7 @@ input/*:root:root:644 dri/card*:root:root:666 -fb/*:root:video:0620 +fb*:root:video:0620 agpgart:root:video:0660 video*:root:video:0660 radio*:root:video:0660 @@ -63,7 +81,8 @@ vbi*:root:video:0660 vtx*:root:video:0660 mol:root:root:0600 -# block devices + +# BLOCK DEVICES floppy*:root:floppy:660 floppy/*:root:floppy:660 From 3c90f15174e30a39e4dc05b5c99c647ef0623973 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 30 Dec 2003 01:02:59 -0800 Subject: [PATCH 0354/4284] [PATCH] udev.permissions.debian - forgot the dm nodes. --- udev.permissions.debian | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev.permissions.debian b/udev.permissions.debian index 294982a824..5df3d0feac 100644 --- a/udev.permissions.debian +++ b/udev.permissions.debian @@ -107,3 +107,5 @@ pt*:root:tape:0660 npt*:root:tape:0660 st*:root:tape:0660 nst*:root:tape:0660 + +dm-*:root:root:0640 From 2441c20743e62f135d1b52cb3fa47b29d59fbef6 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 01:07:55 -0800 Subject: [PATCH 0355/4284] [PATCH] 'ide' missing in bus_files[] my syslog want's to contact you :) Dec 25 20:37:48 pim udev[2274]: wait_for_device_to_initialize: Did not find bus type 'ide' on list of bus_id_files, contact greg@kroah.com We need to put 'ide' to the bus_files array, don't know which file to use... --- namedev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/namedev.c b/namedev.c index 813f26b035..949c2eedf6 100644 --- a/namedev.c +++ b/namedev.c @@ -252,6 +252,7 @@ static struct bus_file { } bus_files[] = { { .bus = "scsi", .file = "vendor" }, { .bus = "usb", .file = "idVendor" }, + { .bus = "ide", .file = "detach_state" }, { .bus = "pci", .file = "vendor" }, {} }; From 0529e2ed2eb1ccfd28d2cd33ce759f9c7b9bc0ff Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 01:07:57 -0800 Subject: [PATCH 0356/4284] [PATCH] check for empty symlink string Attached is a patch for udev-add.c to ignore empty symlink string parts. Issue was brought up by ide-devfs.sh with only one symlink returned, while two are expected. --- udev-add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev-add.c b/udev-add.c index ba5c864165..2f72613ea9 100644 --- a/udev-add.c +++ b/udev-add.c @@ -193,7 +193,7 @@ static int create_node(struct udevice *dev) symlinks = dev->symlink; while (1) { linkname = strsep(&symlinks, " "); - if (linkname == NULL) + if (linkname == NULL || linkname[0] == '\0') break; strncpy(filename, udev_root, sizeof(filename)); From 647c8fc43eb8f3d92ed7142f7c235f3db02f4cfa Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 01:07:59 -0800 Subject: [PATCH 0357/4284] [PATCH] fix for apply_format() fix possible NULL pointer in '%c' callout substitution and cleanup '%D' debug text --- namedev.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/namedev.c b/namedev.c index 949c2eedf6..e69eba657a 100644 --- a/namedev.c +++ b/namedev.c @@ -200,11 +200,12 @@ static void apply_format(struct udevice *udev, unsigned char *string) case 'D': if (strlen(udev->kernel_number) == 0) { strcat(pos, "disc"); + dbg("substitute devfs disc"); break; } strcat(pos, "part"); strcat(pos, udev->kernel_number); - dbg("substitute kernel number '%s'", udev->kernel_number); + dbg("substitute devfs part '%s'", udev->kernel_number); break; case 'm': sprintf(pos, "%u", udev->minor); @@ -229,8 +230,10 @@ static void apply_format(struct udevice *udev, unsigned char *string) break; } } - strcat(pos, pos3); - dbg("substitute partial callout output '%s'", pos3); + if (pos3) { + strcat(pos, pos3); + dbg("substitute partial callout output '%s'", pos3); + } } else { strcat(pos, udev->callout_value); dbg("substitute callout output '%s'", udev->callout_value); From bbc1c767b21e17a51dbe1b5edb2c379c5fce7e95 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 01:08:00 -0800 Subject: [PATCH 0358/4284] [PATCH] ide-devfs.sh update Attached is a patch for ide-devfs.sh, The script is merged with the one from Martin Schlemmer, and cleaned up by him, to create both types of symlinks with one single rule: CALLOUT, BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c %3c" /udev/ |-- cdroms | `-- cdrom0 -> ../hdc |-- discs | |-- disc0 | | |-- disc -> ../../hda | | |-- part1 -> ../../hda1 | | |-- part2 -> ../../hda2 | | `-- part4 -> ../../hda4 | |-- disc1 | | |-- disc -> ../../hdb | | `-- part1 -> ../../hdb1 | `-- disc2 | |-- disc -> ../../hde | `-- part1 -> ../../hde1 |-- hda |-- hda1 |-- hda2 |-- hda4 |-- hdb |-- hdb1 |-- hdc |-- hde |-- hde1 `-- ide |-- host0 | |-- bus0 | | |-- target0 | | | `-- lun0 | | | |-- disc -> ../../../../../hda | | | |-- part1 -> ../../../../../hda1 | | | |-- part2 -> ../../../../../hda2 | | | `-- part4 -> ../../../../../hda4 | | `-- target1 | | `-- lun0 | | |-- disc -> ../../../../../hdb | | `-- part1 -> ../../../../../hdb1 | `-- bus1 | `-- target0 | `-- lun0 | `-- cd -> ../../../../../hdc `-- host2 `-- bus0 `-- target0 `-- lun0 |-- disc -> ../../../../../hde `-- part1 -> ../../../../../hde1 --- extras/ide-devfs.sh | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 3409c407eb..db96b5d299 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -2,26 +2,46 @@ # udev CALLOUT script # return devfs-names for ide-devices -# CALLOUT, BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c" +# CALLOUT, BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c %3c" -HOST=${2%\.[0-9]} -TARGET=${2#[0-9]\.} +HOST="${2%\.[0-9]}" +TARGET="${2#[0-9]\.}" -if [ -z ${HOST#[13579]} ]; then - HOST=`expr $HOST - 1` +if [ -z "${HOST#[13579]}" ]; then + HOST=`expr ${HOST} - 1` BUS="1" else BUS="0" fi +get_dev_number() { + local x= + local num=0 + local MEDIA= + local DRIVE="${1%[0-9]*}" + + for x in /proc/ide/*/media; do + if [ -e "${x}" ]; then + MEDIA=`cat ${x}` + if [ "${MEDIA}" = "$2" ]; then + num=`expr ${num} + 1` + fi + if [ "${x}" = "/proc/ide/${DRIVE}/media" ]; then + break + fi + fi + done + + echo `expr ${num} - 1` +} + if [ -z "$3" ]; then - MEDIA=`cat /proc/ide/$1/media` - if [ "$MEDIA" = "cdrom" ]; then - echo $1 ide/host$HOST/bus$BUS/target$TARGET/lun0/cd - elif [ "$MEDIA" = "disk" ]; then - echo $1 ide/host$HOST/bus$BUS/target$TARGET/lun0/disc + MEDIA=`cat /proc/ide/${1}/media` + if [ "${MEDIA}" = "cdrom" ]; then + echo ${1} ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` + elif [ "${MEDIA}" = "disk" ]; then + echo $1 ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc fi else - echo $1 ide/host$HOST/bus$BUS/target$TARGET/lun0/part$3 + echo $1 ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/part$3 discs/disc`get_dev_number $1 disk`/part$3 fi - From f732a97ebe079413524fb992a119b9579bd04136 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 01:08:02 -0800 Subject: [PATCH 0359/4284] [PATCH] extend exec_program[] extend exec_program size to 100 chars cause: PROGRAM="/home/kay/src/udev.kay/extras/ide-devfs.sh %k %b %n" is too long :) --- namedev.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/namedev.h b/namedev.h index 1eaf4fee4d..1ac71069ad 100644 --- a/namedev.h +++ b/namedev.h @@ -43,6 +43,7 @@ enum config_type { #define VALUE_SIZE 100 #define ID_SIZE 50 #define PLACE_SIZE 50 +#define PROGRAM_SIZE 100 #define TYPE_LABEL "LABEL" #define TYPE_NUMBER "NUMBER" @@ -75,7 +76,7 @@ struct config_device { char id[ID_SIZE]; char place[PLACE_SIZE]; char kernel_name[NAME_SIZE]; - char exec_program[FILE_SIZE]; + char exec_program[PROGRAM_SIZE]; char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; From 8ed89229bc8afed84ad6d587a6df29329bbbf440 Mon Sep 17 00:00:00 2001 From: "azarah@nosferatu.za.org" Date: Tue, 30 Dec 2003 01:18:28 -0800 Subject: [PATCH 0360/4284] [PATCH] Fix udev gcc-2.95.4 compat Two liner to get gcc-2.95.4 to compile udev. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index e69eba657a..cff338f1a7 100644 --- a/namedev.c +++ b/namedev.c @@ -655,9 +655,9 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { temp = strrchr(filename, '/'); if (temp) { + char *temp2 = strrchr(filename, '/'); partition = 1; *temp = 0x00; - char *temp2 = strrchr(filename, '/'); dbg("temp2 = %s", temp2); if (temp2 && (strcmp(temp2, "/block") == 0)) { /* oops, we have no parent block device, so go back to original directory */ From d12ecb53cf8c5955135b94e4b671ad28dfb3a7b4 Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Tue, 30 Dec 2003 01:21:06 -0800 Subject: [PATCH 0361/4284] [PATCH] introduce signal handler Here's a patch that adds a signal handler to udev to clean up the environment (close the sysbus and close the database) on kill-signals. --- udev.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/udev.c b/udev.c index 71c5f1fba5..1d66410b6c 100644 --- a/udev.c +++ b/udev.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" @@ -40,6 +41,22 @@ char **main_argv; char **main_envp; +static void sig_handler(int signum) +{ + dbg("caught signal %d", signum); + switch (signum) { + case SIGINT: + case SIGTERM: + case SIGKILL: + sysbus_disconnect(); + udevdb_exit(); + exit(20 + signum); + break; + default: + dbg("unhandled signal"); + } +} + static inline char *get_action(void) { char *action; @@ -70,7 +87,11 @@ int main(int argc, char **argv, char **envp) char *devpath; char *subsystem; int retval = -EINVAL; - + + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGKILL, sig_handler); + main_argv = argv; main_envp = envp; From 3fd52a7694d94b57fc5a0dc380673a78683118fe Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 30 Dec 2003 01:29:16 -0800 Subject: [PATCH 0362/4284] [PATCH] move the signal handling registration to after we have initialized enough stuff. --- udev.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/udev.c b/udev.c index 1d66410b6c..17eade221e 100644 --- a/udev.c +++ b/udev.c @@ -88,10 +88,6 @@ int main(int argc, char **argv, char **envp) char *subsystem; int retval = -EINVAL; - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - signal(SIGKILL, sig_handler); - main_argv = argv; main_envp = envp; @@ -143,6 +139,11 @@ int main(int argc, char **argv, char **envp) goto exit_sysbus; } + /* set up a default signal handler for now */ + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGKILL, sig_handler); + /* initialize the naming deamon */ namedev_init(); From 13148857cb880c421711db60ad1785ed8e373906 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 01:29:25 -0800 Subject: [PATCH 0363/4284] [PATCH] cleanup namedev_parse debug text I missed a few spaces with my recent change. --- namedev_parse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 2858a28091..02ffb0a3e7 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -294,7 +294,7 @@ keys: goto error; break; case NUMBER: - dbg_parse(TYPE_NUMBER "name='%s', bus='%s', id='%s', symlink='%s'", + dbg_parse(TYPE_NUMBER " name='%s', bus='%s', id='%s', symlink='%s'", dev.name, dev.bus, dev.id, dev.symlink); if ((*dev.name == '\0') || (*dev.bus == '\0') || @@ -302,7 +302,7 @@ keys: goto error; break; case TOPOLOGY: - dbg_parse(TYPE_TOPOLOGY "name='%s', bus='%s', " + dbg_parse(TYPE_TOPOLOGY " name='%s', bus='%s', " "place='%s', symlink='%s'", dev.name, dev.bus, dev.place, dev.symlink); if ((*dev.name == '\0') || @@ -311,14 +311,14 @@ keys: goto error; break; case REPLACE: - dbg_parse(TYPE_REPLACE "name='%s', kernel_name='%s', symlink='%s'", + dbg_parse(TYPE_REPLACE " name='%s', kernel_name='%s', symlink='%s'", dev.name, dev.kernel_name, dev.symlink); if ((*dev.name == '\0') || (*dev.kernel_name == '\0')) goto error; break; case CALLOUT: - dbg_parse(TYPE_CALLOUT "name='%s', bus='%s', program='%s', " + dbg_parse(TYPE_CALLOUT " name='%s', bus='%s', program='%s', " "id='%s', symlink='%s'", dev.name, dev.bus, dev.exec_program, dev.id, dev.symlink); From 3f09184b43dfd8b27fb05786a789f392de18bfca Mon Sep 17 00:00:00 2001 From: "azarah@nosferatu.za.org" Date: Tue, 30 Dec 2003 01:33:35 -0800 Subject: [PATCH 0364/4284] [PATCH] make symlink work properly if there is already a file in its place If a file that is not a symlink (node, socket, fifo, etc) already exist where udev need to create a symlink, symlink() fails. This patch basically test for an existing file, and unlink it. --- udev-add.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/udev-add.c b/udev-add.c index 2f72613ea9..802d85b5b0 100644 --- a/udev-add.c +++ b/udev-add.c @@ -100,6 +100,7 @@ static int create_path(char *file) static int create_node(struct udevice *dev) { + struct stat stats; char filename[255]; char linktarget[255]; char *linkname; @@ -221,6 +222,16 @@ static int create_node(struct udevice *dev) strcpy(linktarget, "./"); strcat(linktarget, &dev->name[tail]); + /* unlink existing non-directories to ensure that our symlink + * is created */ + if (lstat(filename, &stats) == 0) { + if ((stats.st_mode & S_IFMT) != S_IFDIR) { + if (unlink(filename)) + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + } + } + dbg("symlink(%s, %s)", linktarget, filename); retval = symlink(linktarget, filename); if (retval) From c78cb204bc64bce32e705dead071bd4149b731ac Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 22:25:12 -0800 Subject: [PATCH 0365/4284] [PATCH] depend on all .h files Let the build depend on all header files. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 06c564ec57..9d0ece9c3f 100644 --- a/Makefile +++ b/Makefile @@ -214,7 +214,7 @@ udev.conf: $(OBJS): $(GEN_HEADERS) -$(ROOT): $(OBJS) udev.h namedev.h +$(ROOT): $(OBJS) udev.h namedev.h udev_version.h udev_dbus.h udevdb.h klibc_fixups.h list.h $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) From f4dc8d11c22ef72567a2e5c56ac9bae82867189b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Dec 2003 22:31:37 -0800 Subject: [PATCH 0366/4284] [PATCH] make udev user callable to query the database Here is a slightly better version that prints the usage if a unknown option is given: kay@pim:~/src/udev.kay$ ./udev -x ./udev: invalid option -- x Usage: [-qrVh] -q arg query database -r print udev root -V print udev version -h print this help text > Here is a patch that makes it possible to call udev with options on the command line. > Valid options are for now: > > -V for the udev version: > kay@pim:~/src/udev.kay$ ./udev -V > udev, version 011_bk > > -r for the udev root: > kay@pim:~/src/udev.kay$ ./udev -r > /udev/ > > -q to query the database with the sysfs path for the name of the node: > kay@pim:~/src/udev.kay$ ./udev -q /class/video4linux/video0 > test/video/webcam0 --- udev.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++-------- udevdb.c | 13 ++++++++ udevdb.h | 1 + 3 files changed, 97 insertions(+), 14 deletions(-) diff --git a/udev.c b/udev.c index 17eade221e..1797e08273 100644 --- a/udev.c +++ b/udev.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" @@ -81,23 +82,70 @@ static inline char *get_seqnum(void) return seqnum; } -int main(int argc, char **argv, char **envp) +static inline int udev_user(int argc, char **argv) +{ + static const char short_options[] = "q:rVh"; + int option; + int retval = -EINVAL; + struct udevice dev; + + while (1) { + option = getopt(argc, argv, short_options); + if (option == -1) + break; + + dbg("option '%c'", option); + switch (option) { + case 'q': + dbg("udev query: %s\n", optarg); + retval = udevdb_open_ro(); + if (retval != 0) { + printf("unable to open udev database\n"); + return -1; + } + retval = udevdb_get_dev(optarg, &dev); + if (retval == 0) { + printf("%s\n", dev.name); + } else { + printf("device not found in udev database\n"); + } + udevdb_exit(); + return retval; + + case 'r': + printf("%s\n", udev_root); + return 0; + + case 'V': + printf("udev, version %s\n", UDEV_VERSION); + return 0; + + case 'h': + retval = 0; + case '?': + default: + goto help; + } + } + +help: + printf("Usage: [-qrVh]\n" + " -q arg query database \n" + " -r print udev root\n" + " -V print udev version\n" + " -h print this help text\n" + "\n"); + + return retval; +} + +static inline int udev_hotplug(int argc, char **argv) { char *action; char *devpath; char *subsystem; int retval = -EINVAL; - main_argv = argv; - main_envp = envp; - - dbg("version %s", UDEV_VERSION); - - if (argc != 2) { - dbg ("unknown number of arguments"); - goto exit; - } - subsystem = argv[1]; devpath = get_devpath(); @@ -126,9 +174,6 @@ int main(int argc, char **argv, char **envp) goto exit; } - /* initialize our configuration */ - udev_init_config(); - /* connect to the system message bus */ sysbus_connect(); @@ -166,3 +211,27 @@ exit_sysbus: exit: return retval; } + +int main(int argc, char **argv, char **envp) +{ + main_argv = argv; + main_envp = envp; + int retval; + + dbg("version %s", UDEV_VERSION); + + /* initialize our configuration */ + udev_init_config(); + + if (argc == 2 && argv[1][0] != '-') { + dbg("called by hotplug"); + retval = udev_hotplug(argc, argv); + } else { + dbg("called by user"); + retval = udev_user(argc, argv); + } + + return retval; +} + + diff --git a/udevdb.c b/udevdb.c index bbbeddad47..0f9de661a4 100644 --- a/udevdb.c +++ b/udevdb.c @@ -128,3 +128,16 @@ int udevdb_init(int init_flag) } return 0; } + +/** + * udevdb_init: open database for reading + */ +int udevdb_open_ro(void) +{ + udevdb = tdb_open(udev_db_filename, 0, 0, O_RDONLY, 0); + if (udevdb == NULL) { + dbg("unable to open database at '%s'", udev_db_filename); + return -EINVAL; + } + return 0; +} diff --git a/udevdb.h b/udevdb.h index d6c58ae766..f36a9ca799 100644 --- a/udevdb.h +++ b/udevdb.h @@ -11,6 +11,7 @@ /* function prototypes */ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); +extern int udevdb_open_ro(void); extern int udevdb_add_dev(const char *path, const struct udevice *dev); extern int udevdb_get_dev(const char *path, struct udevice *dev); From 9107fb88ba7a7b2eb09f01e311cdc2b29d04a123 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Tue, 30 Dec 2003 22:36:17 -0800 Subject: [PATCH 0367/4284] [PATCH] extras multipath update 2003-12-29 multipath-012 * refresh doc * add the uninstall target in Makefile * /sbin/multipath, not /root/multipath in hotplug agent --- extras/multipath/ChangeLog | 3 +++ extras/multipath/Makefile | 4 ++++ extras/multipath/README | 18 ++++++++---------- extras/multipath/multipath.hotplug | 2 +- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index 730d6e34a6..9296b4db68 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,3 +1,6 @@ +2003-12-29 multipath-012 + * refresh doc + * add the uninstall target in Makefile 2003-12-22 multipath-010 * tweak the install target in Makefile * stop passing fds as argument : this change enable a strict diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index 99036a6a00..3f13532e16 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -55,5 +55,9 @@ install: install -d /etc/hotplug.d/scsi/ install -m 755 multipath.hotplug /etc/hotplug.d/scsi/ +uninstall: + rm /etc/hotplug.d/scsi/multipath.hotplug + rm $(bindir)/$(EXEC) + # Code dependencies main.o: main.c main.h sg_include.h diff --git a/extras/multipath/README b/extras/multipath/README index 6a5637de4b..951c2788bc 100644 --- a/extras/multipath/README +++ b/extras/multipath/README @@ -3,6 +3,7 @@ Dependancies : o libdevmapper : comes with device-mapper-XXXX.tar.gz See www.sistina.com + This lib has been dropped in the multipath tree o libsysfs : comes with sysutils See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ @@ -34,8 +35,9 @@ In 2.5+, we rely on libsysfs (sysutils) to access to sysfs device enums. the wwid is retrieved by a switch fonction. Only White -Listed HW can filled this field. For now only -StorageWorks HW is White Listed. (See notes) +Listed HW can filled this field. For now every FC array +HW listed in kernel's devinfo.c is White Listed, assuming +the WWID is stored is the SCSI-3 standard 0x83 EVPD page. When all_paths is filled, we coalesce the paths and store the result in mp array. Each mp is a struct like this : @@ -47,25 +49,21 @@ struct multipath { }; When mp is filled, the device maps are fed to the kernel -through libdevmapper. Stale paths (failed TUR) are -discarded. +through libdevmapper. Notes : ======= -o make sure you have enough /dev/sg* nodes - (/dev/MAKEDEV if necesary) +o On 2.4, make sure you have enough /dev/sg* nodes + (/dev/MAKEDEV if necesary). Same goes for /dev/sd* o path coalescing relies on a path unique id being found. This unique id, lacking a standard method, is vendor specific. A switch function (get_unique_id) is present and an example function is provided for storageworks - arrays (get_storageworks_wwid). Feel free to enrich + arrays (get_evpd_wwid). Feel free to enrich with hardware you have at hand :) -o Something goes wrong with sd.o, qla2200 & dm-mod - refcounting : I can't unload these modules after exec. - o The kernel does NOT manage properly ghosts paths with StorageWorks HW. Seems nobody cares after a load of posts to linux-scsi. diff --git a/extras/multipath/multipath.hotplug b/extras/multipath/multipath.hotplug index db7894cb99..8d60f4d2c6 100644 --- a/extras/multipath/multipath.hotplug +++ b/extras/multipath/multipath.hotplug @@ -1,3 +1,3 @@ . /etc/hotplug/hotplug.functions sleep 1 -mesg `/root/multipath scsi $DEVPATH` +mesg `/sbin/multipath scsi $DEVPATH` From b02d14d0a6210ceb76e097a56109abeecdd2b112 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Tue, 30 Dec 2003 22:39:37 -0800 Subject: [PATCH 0368/4284] [PATCH] extras multipath update incremental to 0.0.12-1, * check hotplug event refers to a block device; if not exit early --- extras/multipath/ChangeLog | 1 + extras/multipath/main.c | 6 +++++- extras/multipath/multipath.hotplug | 3 +++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index 9296b4db68..a780865d3e 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,4 +1,5 @@ 2003-12-29 multipath-012 + * check hotplug event refers to a block device; if not exit early * refresh doc * add the uninstall target in Makefile 2003-12-22 multipath-010 diff --git a/extras/multipath/main.c b/extras/multipath/main.c index f62e0f9954..a8e29e8ba6 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -261,7 +261,11 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) sprintf(buff, "%s%s/block", conf->sysfs_path, conf->hotplugdev); memset(conf->hotplugdev, 0, FILE_NAME_SIZE); - readlink(buff, conf->hotplugdev, FILE_NAME_SIZE); + + /* if called from hotplug but with no block, leave */ + if (0 > readlink(buff, conf->hotplugdev, FILE_NAME_SIZE)) + return 0; + basename(conf->hotplugdev, buff); sprintf(curpath.sg_dev, "/dev/%s", buff); diff --git a/extras/multipath/multipath.hotplug b/extras/multipath/multipath.hotplug index 8d60f4d2c6..9bab619826 100644 --- a/extras/multipath/multipath.hotplug +++ b/extras/multipath/multipath.hotplug @@ -1,3 +1,6 @@ . /etc/hotplug/hotplug.functions + +# wait for sysfs sleep 1 + mesg `/sbin/multipath scsi $DEVPATH` From 3310f9d0e8a585c4b96d558a34b06b47699586b1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 00:25:01 -0800 Subject: [PATCH 0369/4284] [PATCH] added udev vs devfs supid document to the tree. --- docs/udev_vs_devfs | 190 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 190 insertions(+) create mode 100644 docs/udev_vs_devfs diff --git a/docs/udev_vs_devfs b/docs/udev_vs_devfs new file mode 100644 index 0000000000..5a46231c1f --- /dev/null +++ b/docs/udev_vs_devfs @@ -0,0 +1,190 @@ + 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 it's +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 it's 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 (49Kb binary) 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. + +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 affect +of it's 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 it's 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 From 1237229594bf02f63922e481462efe0dae4294e4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 00:28:05 -0800 Subject: [PATCH 0370/4284] [PATCH] minor change to udev_vs_devfs document. --- docs/udev_vs_devfs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/udev_vs_devfs b/docs/udev_vs_devfs index 5a46231c1f..17853f881f 100644 --- a/docs/udev_vs_devfs +++ b/docs/udev_vs_devfs @@ -108,7 +108,9 @@ 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. +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 From 5bfabc59c06f28405af3735603f3ce986e9b8b3e Mon Sep 17 00:00:00 2001 From: "rml@ximian.com" Date: Wed, 31 Dec 2003 00:34:49 -0800 Subject: [PATCH 0371/4284] [PATCH] udev spec file update More udev spec file updates. This one from David Zeuthen. Attached patch, against udev-011, makes sure we pass USE_DBUS and also makes sure we install the D-BUS policy file, if the %{dbus} option is set. --- udev.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index a81720e7c4..9b5ef54cef 100644 --- a/udev.spec +++ b/udev.spec @@ -48,7 +48,10 @@ make CC="gcc $RPM_OPT_FLAGS" \ %endif %install -make DESTDIR=$RPM_BUILD_ROOT install +make DESTDIR=$RPM_BUILD_ROOT install \ +%if %{dbus} + USE_DBUS=true +%endif %post /sbin/chkconfig --add udev @@ -70,6 +73,9 @@ rm -rf $RPM_BUILD_ROOT %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf %config(noreplace) %attr(0644,root,root) /etc/udev/udev.rules %config(noreplace) %attr(0644,root,root) /etc/udev/udev.permissions +%if %{dbus} + %config(noreplace) %attr(0644,root,root) /etc/dbus-1/system.d/udev_sysbus_policy.conf +%endif %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev.8* From 4070d2fea01f3c9ee9b9761b5ec795e2c13b126b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 31 Dec 2003 00:34:51 -0800 Subject: [PATCH 0372/4284] [PATCH] mention user callable udev + options in man page As usual, here is the corresponding man page update and a small text correction. --- udev.8 | 24 ++++++++++++++++++++++++ udev.c | 2 +- udevdb.c | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/udev.8 b/udev.8 index eb772c9dbe..5f497af92a 100644 --- a/udev.8 +++ b/udev.8 @@ -3,6 +3,9 @@ udev \- Linux configurable dynamic device naming support .SH SYNOPSIS .BI udev " hotplug-subsystem" +.br +.B udev +.RI "[-q " sysfs_path "] [-rVh]" .SH "DESCRIPTION" .B udev creates or removes device node files usually located in the /dev directory. @@ -26,6 +29,27 @@ maintains a database for devices present on the system. On device removal, .B udev queries the internal database for the name of the device file to be deleted. +.SH "OPTIONS" +.B udev +normally is called by +.B hotplug +with the subsystem as argument and various environment variables set. +.br +It may also called with the following options: +.TP +.B -V +Print the version information. +.TP +.B -r +Print the the +.B udev +root directory. +.TP +.BI -q " sysfs_path" +Query with the sysfs path as argument for the name of the created device node. +.TP +.B -h +Print help text. .SH "CONFIGURATION" All .B udev diff --git a/udev.c b/udev.c index 1797e08273..0d0a5da207 100644 --- a/udev.c +++ b/udev.c @@ -130,7 +130,7 @@ static inline int udev_user(int argc, char **argv) help: printf("Usage: [-qrVh]\n" - " -q arg query database \n" + " -q query database for the name of the created node\n" " -r print udev root\n" " -V print udev version\n" " -h print this help text\n" diff --git a/udevdb.c b/udevdb.c index 0f9de661a4..ca9e63c97e 100644 --- a/udevdb.c +++ b/udevdb.c @@ -130,7 +130,7 @@ int udevdb_init(int init_flag) } /** - * udevdb_init: open database for reading + * udevdb_open_ro: open database for reading */ int udevdb_open_ro(void) { From fb43c2b2e8aee09662226cb8ee8cb9ac93f32890 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 19:11:04 -0800 Subject: [PATCH 0373/4284] [PATCH] if using glibc, link dynamically, as no one like 500Kb udev binaries... --- Makefile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9d0ece9c3f..8b20612de0 100644 --- a/Makefile +++ b/Makefile @@ -114,8 +114,9 @@ else STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif -# If we are using our version of klibc, then we need to build and link it. -# Otherwise, use glibc and link statically. +# If we are using our version of klibc, then we need to build, link it, and then +# link udev against it statically. +# Otherwise, use glibc and link dynamically. ifeq ($(strip $(USE_KLIBC)),true) KLIBC_BASE = $(PWD)/klibc KLIBC_DIR = $(KLIBC_BASE)/klibc @@ -139,7 +140,7 @@ else LIBC = CFLAGS += -I$(GCCINCDIR) LIB_OBJS = -lc - LDFLAGS = --static + LDFLAGS = endif CFLAGS += -I$(PWD)/libsysfs From 9f7fff04ee0b58f22936693649edb7bd1f5ea8bf Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 20:28:15 -0800 Subject: [PATCH 0374/4284] [PATCH] add Gentoo versions of the rules and permissions files. --- etc/udev/udev.permissions.gentoo | 176 +++++++++++++++++++++++++++++++ etc/udev/udev.rules.gentoo | 97 +++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 etc/udev/udev.permissions.gentoo create mode 100644 etc/udev/udev.rules.gentoo diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo new file mode 100644 index 0000000000..c2016bc280 --- /dev/null +++ b/etc/udev/udev.permissions.gentoo @@ -0,0 +1,176 @@ +# /etc/udev/udev.permissions: permission/ownership map for udev +# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.permissions,v 1.2 2003/12/26 23:32:44 azarah Exp $ + +# console devices +console:root:tty:0600 +tty[0-9][0-9]*:root:tty:0660 +vc/[0-9]*:root:tty:0660 + +# pty devices +# Set this to 0660 if you only want users belonging to tty group +# to be able to allocate PTYs +ptmx:root:tty:0666 +pty[p-za-e][0-9a-f]*:root:tty:0660 +tty[p-za-e][0-9a-f]*:root:tty:0660 +pty/m*:root:tty:0660 +vc/s*:root:tty:0660 + +# serial+dialup devices +ttyS*:root:tty:0660 +ippp*:root:tty:0660 +isdn*:root:tty:0660 +isdnctrl*:root:tty:0660 +capi*:root:tty:0660 +dcbri*:root:tty:0660 +ircomm*:root:tty:0660 +ttyUSB*:root:usb:0660 +tts/[0-9]*:root:tty:0660 +tts/USB[0-9]*:root:usb:0660 + +# vc devices +vcs:root:root:0600 +vcs[0-9]*:root:root:0600 +vcsa:root:root:0600 +vcsa[0-9]*:root:root:0600 +vcc/*:root:root:0600 + +# floppy devices +fd[01]*:root:floppy:0660 + +# audio devices +dsp*:root:audio:0660 +audio*:root:audio:0660 +midi*:root:audio:0660 +mixer*:root:audio:0660 +sequencer*:root:audio:0660 +sound/*:root:audio:0660 +snd/*:root:audio:0660 +beep:root:audio:0660 +admm*:root:audio:0660 +adsp*:root:audio:0660 +aload*:root:audio:0660 +amidi*:root:audio:0660 +dmfm*:root:audio:0660 +dmmidi*:root:audio:0660 +sndstat:root:audio:0660 + +# optical devices +sr*:root:cdrom:660 +scd*:root:cdrom:660 +pcd*:root:cdrom:0660 +cdrom*:root:cdrom:0660 +dvd:root:cdrom:0660 +rdvd:root:cdrom:0660 +cdroms/*:root:cdrom:0660 + +# pilot/palm devices +pilot:root:uucp:0660 + +# jaz devices +jaz*:root:disk:0660 + +# zip devices +pocketzip*:root:disk:0660 +zip*:root:disk:0660 + +# ls120 devices +ls120:root:disk:0660 +ls120*:root:disk:0660 + +# lp devices +lp*:root:lp:0660 +parport*:root:lp:0660 +irlpt*:root:lp:0660 +usblp*:root:lp:0660 +usb/lp*:root:lp:0660 + +# scanner devices +scanner:root:root:0600 +usb/scanner*:root:root:0600 + +# camera devices +camera*:root:root:0600 +usb/dc2xx*:root:root:0600 +usb/mdc800*:root:root:0600 + +# raw devices +ram*:root:disk:660 +raw/*:root:disk:660 + +# disk devices +hd*:root:disk:660 +sd*:root:disk:660 +dasd*:root:disk:660 +ataraid*:root:disk:660 +loop*:root:disk:660 +md*:root:disk:660 +ide/*/*/*/*/*:root:disk:660 +discs/*/*:root:disk:660 +loop/*:root:disk:660 +md/*:root:disk:660 + +# tape devices +ht*:root:tape:0660 +nht*:root:tape:0660 +pt[0-9]*:root:tape:0660 +npt*:root:tape:0660 +st*:root:tape:0660 +nst*:root:tape:0660 + +# memstick devices +memstick*:root:root:0600 + +# flash devices +flash*:root:root:0600 + +# diskonkey devices +diskonkey*:root:disk:0660 + +# rem_ide devices +microdrive*:root:disk:0660 + +# fb devices +fb:root:root:0600 +fb[0-9]*:root:root:0600 +fb/*:root:root:0600 + +# kbd devices +kbd:root:root:0600 + +# joystick devices +js[0-9]*:root:root:0600 + +# v4l devices +video*:root:video:0660 +radio*:root:video:0660 +winradio*:root:video:0660 +vtx*:root:video:0660 +vbi*:root:video:0660 +video/*:root:video:0660 +vttuner:root:video:0660 +v4l/*:root:video:0660 + +# input devices +input/*:root:root:644 + +# gpm devices +gpmctl:root:root:0700 + +# dri devices +nvidia*:root:video:0660 +3dfx*:root:video:0660 +dri/*:root:video:0660 + +# mainboard devices +apm_bios:root:root:0600 + +# scsi devices +sg*:root:disk:0660 +pg*:root:disk:0660 +cdwriter:root:disk:0660 + +# usb devices +usb/dabusb*:root:usb:0660 +usb/mdc800*:root:usb:0660 +usb/rio500:root:usb:0660 + diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo new file mode 100644 index 0000000000..e752fd0216 --- /dev/null +++ b/etc/udev/udev.rules.gentoo @@ -0,0 +1,97 @@ +# /etc/udev/udev.rules: device naming rules for udev +# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.rules,v 1.1 2003/12/26 23:32:44 azarah Exp $ +# +# There are a number of modifiers that are allowed to be used in the NAME or PROGRAM 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 return value for the CALLOUT program (note, this doesn't work within +# the PROGRAM field for the obvious reason.) +# %D - use the devfs style disk name for this device. +# For partitions, this will result in 'part%n' +# If this is not a partition, it will result in 'disc' +# + +########################################################### +# +# Add your own rules here +# +########################################################### + +# Looking for scsi bus id 42:0:0:1 +CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" + +# A usb camera. +LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" + +# USB Epson printer to be called lp_epson +LABEL, BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" + +# USB HP printer to be called lp_hp +LABEL, BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" + +# sound card with PCI bus id 00:0b.0 to be the first sound card +NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" + +# sound card with PCI bus id 00:07.1 to be the second sound card +NUMBER, BUS="pci", ID="00:07.1", NAME="dsp1" + +# USB mouse plugged into the third port of the first hub to be called mouse0 +TOPOLOGY, BUS="usb", PLACE="1.3", NAME="mouse0" + +# USB tablet plugged into the third port of the second hub to be called mouse1 +TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" +TOPOLOGY, BUS="usb", PLACE="2.4", NAME="mouse2" + +# ttyUSB1 should always be called visor +REPLACE, KERNEL="ttyUSB1", NAME="visor" +REPLACE, KERNEL="ttyUSB0", NAME="pl2303" + + +########################################################### +# +# For devfs similar /dev layout (neater) +# +########################################################### + +# devfs-names for ide-devices (uncomment only one) +# /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names +CALLOUT, BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c %3c" + +# fb devices +REPLACE, KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" + +# loop devices +REPLACE, KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" + +# md block devices +REPLACE, KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" + +# pty devices +REPLACE, KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" +REPLACE, KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" + +# ram devices +REPLACE, KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" + +# tty devices +REPLACE, KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" +REPLACE, KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" +REPLACE, KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" + +# vc devices +REPLACE, KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" +REPLACE, KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" +REPLACE, KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" +REPLACE, KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" + +# v4l devices +REPLACE, KERNEL="video[0-9]*", NAME="v4l/video%n" +REPLACE, KERNEL="radio[0-9]*", NAME="v4l/radio%n" +REPLACE, KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +REPLACE, KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" + From 6d88260a8be069a65ab52fa924e6d4dc13c4e83c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 20:35:02 -0800 Subject: [PATCH 0375/4284] [PATCH] move the config files to etc/udev to clean up main directory a bit. --- Makefile | 19 ++++++++++--------- udev.conf.in => etc/udev/udev.conf.in | 0 udev.permissions => etc/udev/udev.permissions | 0 .../udev/udev.permissions.debian | 0 udev.rules => etc/udev/udev.rules | 0 udev.rules.devfs => etc/udev/udev.rules.devfs | 0 udev.rules.demo | 9 --------- 7 files changed, 10 insertions(+), 18 deletions(-) rename udev.conf.in => etc/udev/udev.conf.in (100%) rename udev.permissions => etc/udev/udev.permissions (100%) rename udev.permissions.debian => etc/udev/udev.permissions.debian (100%) rename udev.rules => etc/udev/udev.rules (100%) rename udev.rules.devfs => etc/udev/udev.rules.devfs (100%) delete mode 100644 udev.rules.demo diff --git a/Makefile b/Makefile index 8b20612de0..b27f1b92d9 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ ROOT = udev VERSION = 011_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) +LOCAL_CFG_DIR = etc/udev DESTDIR = # override this to make udev look in a different location for it's config files @@ -206,11 +207,11 @@ udev_version.h: @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ # config files automatically generated -GEN_CONFIGS = udev.conf +GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf # Rules on how to create the generated config files -udev.conf: - sed -e "s:@udevdir@:$(udevdir):" < udev.conf.in > $@ +$(LOCAL_CFG_DIR)/udev.conf: + sed -e "s:@udevdir@:$(udevdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ $(OBJS): $(GEN_HEADERS) @@ -278,16 +279,16 @@ endif install-config: $(GEN_CONFIGS) $(INSTALL) -d $(DESTDIR)$(configdir) @if [ ! -r $(DESTDIR)$(configdir)udev.conf ]; then \ - echo $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir); \ - $(INSTALL_DATA) udev.conf $(DESTDIR)$(configdir); \ + echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ + $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ fi @if [ ! -r $(DESTDIR)$(configdir)udev.rules ]; then \ - echo $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir); \ - $(INSTALL_DATA) udev.rules $(DESTDIR)$(configdir); \ + echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir); \ + $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir); \ fi @if [ ! -r $(DESTDIR)$(configdir)udev.permissions ]; then \ - echo $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir); \ - $(INSTALL_DATA) udev.permissions $(DESTDIR)$(configdir); \ + echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ + $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ fi diff --git a/udev.conf.in b/etc/udev/udev.conf.in similarity index 100% rename from udev.conf.in rename to etc/udev/udev.conf.in diff --git a/udev.permissions b/etc/udev/udev.permissions similarity index 100% rename from udev.permissions rename to etc/udev/udev.permissions diff --git a/udev.permissions.debian b/etc/udev/udev.permissions.debian similarity index 100% rename from udev.permissions.debian rename to etc/udev/udev.permissions.debian diff --git a/udev.rules b/etc/udev/udev.rules similarity index 100% rename from udev.rules rename to etc/udev/udev.rules diff --git a/udev.rules.devfs b/etc/udev/udev.rules.devfs similarity index 100% rename from udev.rules.devfs rename to etc/udev/udev.rules.devfs diff --git a/udev.rules.demo b/udev.rules.demo deleted file mode 100644 index 9ea7895791..0000000000 --- a/udev.rules.demo +++ /dev/null @@ -1,9 +0,0 @@ -# USB camera from Fuji to be named "camera" -LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", NAME="camera%n" - -# USB device plugged into the fourth port of the second hub to be called gps_device -TOPOLOGY, BUS="usb", PLACE="2.4", NAME="gps_device" - -# ttyUSB1 should always be called visor -REPLACE, KERNEL="ttyUSB1", NAME="visor" - From 8ccd82e04c28ca49b70a619e3d6e81d67e68ab95 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 20:38:14 -0800 Subject: [PATCH 0376/4284] [PATCH] move the dbus config file to etc/dbus-1/system.d/ --- Makefile | 3 ++- .../dbus-1/system.d/udev_sysbus_policy.conf | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename udev_sysbus_policy.conf => etc/dbus-1/system.d/udev_sysbus_policy.conf (100%) diff --git a/Makefile b/Makefile index b27f1b92d9..dae0d9a1f9 100644 --- a/Makefile +++ b/Makefile @@ -266,7 +266,8 @@ small_release: $(DISTFILES) clean ifeq ($(USE_DBUS), true) install-dbus-policy: $(INSTALL) -d $(DESTDIR)$(dbusdir) - $(INSTALL_DATA) udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) + $(INSTALL_DATA) etc/dbus-1/system.d/udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) + uninstall-dbus-policy: - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf else diff --git a/udev_sysbus_policy.conf b/etc/dbus-1/system.d/udev_sysbus_policy.conf similarity index 100% rename from udev_sysbus_policy.conf rename to etc/dbus-1/system.d/udev_sysbus_policy.conf From 5f7c4c1bb07c4398331b548de366c76c05eed1ff Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 21:22:35 -0800 Subject: [PATCH 0377/4284] [PATCH] minor grammer fixes for the udev_vs_devfs document Thanks to Seemant Kulleen for pointing them out. --- docs/udev_vs_devfs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/udev_vs_devfs b/docs/udev_vs_devfs index 17853f881f..fbf757d437 100644 --- a/docs/udev_vs_devfs +++ b/docs/udev_vs_devfs @@ -13,7 +13,7 @@ Executive summary for those too lazy to read this whole thing: will be gladly ignored. -First off, some background. For a description of udev, and what it's +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: @@ -26,7 +26,7 @@ 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 +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 @@ -90,7 +90,7 @@ And now for udev: 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 it's database to see + 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.) @@ -123,8 +123,8 @@ everything that devfs currently does, in about 6Kb of userspace code: 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 affect -of it's primary goal, the ability to never worry about major/minor +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. @@ -132,7 +132,7 @@ 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 it's goals: +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 From 8c55357fa7314aee14fe1e8677ba030de97b0998 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Dec 2003 21:46:59 -0800 Subject: [PATCH 0378/4284] [PATCH] v012 release --- ChangeLog | 45 +++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index fa12f67046..f626070268 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +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 ============================================ diff --git a/Makefile b/Makefile index dae0d9a1f9..13fc19296c 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 011_bk +VERSION = 012 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 9b5ef54cef..c34b1454f8 100644 --- a/udev.spec +++ b/udev.spec @@ -18,7 +18,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 011_bk +Version: 012 Release: 1 License: GPL Group: Utilities/System From e9a8c2e432bc2b419a2bac590d3021f2b736b305 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 3 Jan 2004 05:37:27 -0800 Subject: [PATCH 0379/4284] [PATCH] 012_bk change. --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 13fc19296c..ffd61c0400 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 012 +VERSION = 012_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index c34b1454f8..9e301deb7c 100644 --- a/udev.spec +++ b/udev.spec @@ -18,7 +18,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 012 +Version: 012_bk Release: 1 License: GPL Group: Utilities/System From 8eb38ef882192445bd0e012351a6192a2968a76c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 4 Jan 2004 08:08:26 -0800 Subject: [PATCH 0380/4284] [PATCH] add a blacklist of class devices we do not want to look at. Thanks to Kay for the original patch, and the idea. --- udev.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/udev.c b/udev.c index 0d0a5da207..1222b239ef 100644 --- a/udev.c +++ b/udev.c @@ -139,12 +139,20 @@ help: return retval; } +static char *subsystem_blacklist[] = { + "net", + "scsi_host", + "scsi_device", + "", +}; + static inline int udev_hotplug(int argc, char **argv) { char *action; char *devpath; char *subsystem; int retval = -EINVAL; + int i; subsystem = argv[1]; @@ -162,10 +170,14 @@ static inline int udev_hotplug(int argc, char **argv) goto exit; } - /* but we don't care about net class devices */ - if (strcmp(subsystem, "net") == 0) { - dbg("don't care about net devices"); - goto exit; + /* skip blacklisted subsystems */ + i = 0; + while (subsystem_blacklist[i][0] != '\0') { + if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { + dbg("don't care about '%s' devices", subsystem); + goto exit; + } + i++; } action = get_action(); From 843d1a84b9be2b3e11f26186fee24676f5dc3f53 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 4 Jan 2004 08:18:16 -0800 Subject: [PATCH 0381/4284] [PATCH] replace list_for_each with list_for_each_entry, saving a few lines of code. --- namedev.c | 31 +++++++++---------------------- namedev_parse.c | 12 ++++-------- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/namedev.c b/namedev.c index cff338f1a7..e1b57ec350 100644 --- a/namedev.c +++ b/namedev.c @@ -104,12 +104,11 @@ static int strcmp_pattern(const char *p, const char *s) int add_perm_dev(struct perm_device *new_dev) { - struct list_head *tmp; + struct perm_device *dev; struct perm_device *tmp_dev; /* update the values if we already have the device */ - list_for_each(tmp, &perm_device_list) { - struct perm_device *dev = list_entry(tmp, struct perm_device, node); + list_for_each_entry(dev, &perm_device_list, node) { if (strcmp_pattern(new_dev->name, dev->name)) continue; copy_var(dev, new_dev, mode); @@ -130,11 +129,9 @@ int add_perm_dev(struct perm_device *new_dev) static struct perm_device *find_perm(char *name) { - struct list_head *tmp; - struct perm_device *perm = NULL; + struct perm_device *perm; - list_for_each(tmp, &perm_device_list) { - perm = list_entry(tmp, struct perm_device, node); + list_for_each_entry(perm, &perm_device_list, node) { if (strcmp_pattern(perm->name, name)) continue; return perm; @@ -396,10 +393,8 @@ static int exec_callout(struct config_device *dev, char *value, int len) static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; - struct list_head *tmp; - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); + list_for_each_entry(dev, &config_device_list, node) { if (dev->type != CALLOUT) continue; @@ -468,12 +463,10 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, { struct sysfs_pair *pair; struct config_device *dev; - struct list_head *tmp; int i; int match; - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); + list_for_each_entry(dev, &config_device_list, node) { if (dev->type != LABEL) continue; @@ -513,7 +506,6 @@ static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; - struct list_head *tmp; char path[SYSFS_PATH_MAX]; int found; char *temp = NULL; @@ -522,8 +514,7 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, if (!sysfs_device) return -ENODEV; - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); + list_for_each_entry(dev, &config_device_list, node) { if (dev->type != NUMBER) continue; @@ -558,7 +549,6 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; - struct list_head *tmp; char path[SYSFS_PATH_MAX]; int found; char *temp = NULL; @@ -567,8 +557,7 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude if (!sysfs_device) return -ENODEV; - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); + list_for_each_entry(dev, &config_device_list, node) { if (dev->type != TOPOLOGY) continue; @@ -604,10 +593,8 @@ static int do_topology(struct sysfs_class_device *class_dev, struct udevice *ude static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { struct config_device *dev; - struct list_head *tmp; - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); + list_for_each_entry(dev, &config_device_list, node) { if (dev->type != REPLACE) continue; diff --git a/namedev_parse.c b/namedev_parse.c index 02ffb0a3e7..de29057a95 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -117,12 +117,10 @@ void dump_config_dev(struct config_device *dev) void dump_config_dev_list(void) { - struct list_head *tmp; + struct config_device *dev; - list_for_each(tmp, &config_device_list) { - struct config_device *dev = list_entry(tmp, struct config_device, node); + list_for_each_entry(dev, &config_device_list, node) dump_config_dev(dev); - } } void dump_perm_dev(struct perm_device *dev) @@ -133,12 +131,10 @@ void dump_perm_dev(struct perm_device *dev) void dump_perm_dev_list(void) { - struct list_head *tmp; + struct perm_device *dev; - list_for_each(tmp, &perm_device_list) { - struct perm_device *dev = list_entry(tmp, struct perm_device, node); + list_for_each_entry(dev, &perm_device_list, node) dump_perm_dev(dev); - } } From 6a827072275a28798ac4c26ee166b03a145f4174 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 6 Jan 2004 01:11:15 -0800 Subject: [PATCH 0382/4284] [PATCH] add cdrom rule for ide cdrom. Rule came from Kay --- etc/udev/udev.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 06d5842c2a..b206503e15 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -46,4 +46,7 @@ REPLACE, KERNEL="ttyUSB0", NAME="pl2303" #REPLACE, KERNEL="ttyS*", NAME="tts/%n" #REPLACE, KERNEL="tty*", NAME="vc/%n" +# if this is a ide cdrom, name it the default name, and create a symlink to cdrom +CALLOUT, BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", ID="cdrom", NAME="%k", SYMLINK="cdrom" + From a05b77509e6e3723f3e969eefd1c2a34bad79675 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 6 Jan 2004 01:11:53 -0800 Subject: [PATCH 0383/4284] [PATCH] add silly script that names cdrom drives based on the cd in them. --- extras/name_cdrom.pl | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 extras/name_cdrom.pl diff --git a/extras/name_cdrom.pl b/extras/name_cdrom.pl new file mode 100644 index 0000000000..569b119be7 --- /dev/null +++ b/extras/name_cdrom.pl @@ -0,0 +1,45 @@ +#!/usr/bin/perl + +# a horribly funny script that shows how flexible udev can really be +# This is to be executed by udev with the following rules: +# CALLOUT, BUS="ide", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%1c", SYMLINK="cdrom" +# CALLOUT, BUS="scsi", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%1c", SYMLINK="cdrom" +# +# The scsi rule catches USB cdroms and ide-scsi devices. +# + +use CDDB_get qw( get_cddb ); + +my %config; + +$dev_node = "/tmp/cd_foo"; + +# following variables just need to be declared if different from defaults +$config{CDDB_HOST}="freedb.freedb.org"; # set cddb host +$config{CDDB_PORT}=8880; # set cddb port +$config{CDDB_MODE}="cddb"; # set cddb mode: cddb or http +$config{CD_DEVICE}="$dev_node"; # set cd device + +# No user interaction, this is a automated script! +$config{input}=0; + +$major = $ARGV[0]; +$minor = $ARGV[1]; + +# create our temp device node to read the cd info from +if (system("mknod $dev_node b $major $minor")) { + die "bad mknod failed"; + } + +# get it on +my %cd=get_cddb(\%config); + +# remove the dev node we just created +unlink($dev_node); + +# print out our cd name if we have found it +unless(defined $cd{title}) { + print"bad unknown cdrom\n"; +} else { + print "good $cd{artist}_$cd{title}\n"; +} From c53735efc9720b28676c1b51fbed04dc592236e8 Mon Sep 17 00:00:00 2001 From: "christophe@saout.de" Date: Sat, 10 Jan 2004 00:54:33 -0800 Subject: [PATCH 0384/4284] [PATCH] small cleanup This one is nothing important, just add some quotes to be more consistent with the rest and make sure that the return value is positive (since the error return values are negative). Hmm? --- namedev_parse.c | 2 +- udev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index de29057a95..4b1377dc32 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -103,7 +103,7 @@ void dump_config_dev(struct config_device *dev) dev->name, dev->bus, dev->place); break; case REPLACE: - dbg_parse("REPLACE name=%s, kernel_name=%s", + dbg_parse("REPLACE name='%s', kernel_name='%s'", dev->name, dev->kernel_name); break; case CALLOUT: diff --git a/udev.c b/udev.c index 1222b239ef..bbff89bad5 100644 --- a/udev.c +++ b/udev.c @@ -221,7 +221,7 @@ exit_sysbus: sysbus_disconnect(); exit: - return retval; + return -retval; } int main(int argc, char **argv, char **envp) From f1db055ab2e349ce22254562faaece66d6a4a873 Mon Sep 17 00:00:00 2001 From: "christophe@saout.de" Date: Sat, 10 Jan 2004 00:55:28 -0800 Subject: [PATCH 0385/4284] [PATCH] add IGNORE rule type On Wed, Dec 31, 2003 at 11:24:53AM -0800, Greg KH wrote: > > There should be a possibility to tell udev not to create a device node. > > > > device-mapper: Usually set up by libdevmapper (or EVMS tools) which > > creates the device node on its own under /dev/mapper/. > > > > With udev a second device is created named /dev/dm- which is not > > really needed. > > Good point. Ok, I'll agree with you. Care to make up a patch for this > kind of feature? Yes, I can try. There was no way to tell not to do anything so I created one. Errors are signalled via negative return values, so I thought that a positive, non-zero one could mean to ignore the device. I don't like it but perhaps you have a better solution. --- etc/udev/udev.rules | 3 ++- etc/udev/udev.rules.devfs | 3 +++ namedev.c | 27 +++++++++++++++++++++++++++ namedev.h | 2 ++ namedev_parse.c | 15 +++++++++++++++ udev.8 | 8 +++++++- udev.c | 3 +++ 7 files changed, 59 insertions(+), 2 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index b206503e15..c2b50eb90d 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -49,4 +49,5 @@ REPLACE, KERNEL="ttyUSB0", NAME="pl2303" # if this is a ide cdrom, name it the default name, and create a symlink to cdrom CALLOUT, BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", ID="cdrom", NAME="%k", SYMLINK="cdrom" - +# device mapper creates its own device nodes +IGNORE, KERNEL="dm-[0-9]*" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 0d579a4dd4..537d655a0e 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -41,3 +41,6 @@ REPLACE, KERNEL="video[0-9]*", NAME="v4l/video%n" REPLACE, KERNEL="radio[0-9]*", NAME="v4l/radio%n" REPLACE, KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" REPLACE, KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" + +# dm devices +IGNORE, KERNEL="dm-[0-9]*" diff --git a/namedev.c b/namedev.c index e1b57ec350..226c1d313f 100644 --- a/namedev.c +++ b/namedev.c @@ -298,6 +298,27 @@ exit: return; /* here to prevent compiler warning... */ } +static int do_ignore(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +{ + struct config_device *dev; + struct list_head *tmp; + + list_for_each(tmp, &config_device_list) { + dev = list_entry(tmp, struct config_device, node); + if (dev->type != IGNORE) + continue; + + dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name); + if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0) + continue; + + dbg("found name, '%s' will be ignored", dev->kernel_name); + + return 0; + } + return -ENODEV; +} + static int exec_callout(struct config_device *dev, char *value, int len) { int retval; @@ -734,6 +755,12 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dbg("kernel_number='%s'", udev->kernel_number); /* rules are looked at in priority order */ + retval = do_ignore(class_dev, udev, sysfs_device); + if (retval == 0) { + dbg("name, '%s' is being ignored", class_dev->name); + return 1; + } + retval = do_callout(class_dev, udev, sysfs_device); if (retval == 0) goto found; diff --git a/namedev.h b/namedev.h index 1ac71069ad..f1e770277b 100644 --- a/namedev.h +++ b/namedev.h @@ -36,6 +36,7 @@ enum config_type { TOPOLOGY = 3, REPLACE = 4, CALLOUT = 5, + IGNORE = 6, }; #define BUS_SIZE 30 @@ -50,6 +51,7 @@ enum config_type { #define TYPE_TOPOLOGY "TOPOLOGY" #define TYPE_REPLACE "REPLACE" #define TYPE_CALLOUT "CALLOUT" +#define TYPE_IGNORE "IGNORE" #define FIELD_BUS "BUS" #define FIELD_ID "ID" diff --git a/namedev_parse.c b/namedev_parse.c index 4b1377dc32..5b5a5b3bc1 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -110,6 +110,10 @@ void dump_config_dev(struct config_device *dev) dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s'", dev->name, dev->bus, dev->exec_program, dev->id); break; + case IGNORE: + dbg_parse("IGNORE name='%s', kernel_name='%s'", + dev->name, dev->kernel_name); + break; default: dbg_parse("unknown type of method"); } @@ -209,6 +213,11 @@ int namedev_init_rules(void) goto keys; } + if (strcasecmp(temp2, TYPE_IGNORE) == 0) { + dev.type = IGNORE; + goto keys; + } + dbg_parse("unknown type of method '%s'", temp2); goto error; keys: @@ -323,6 +332,12 @@ keys: (*dev.exec_program == '\0')) goto error; break; + case IGNORE: + dbg_parse(TYPE_IGNORE "name='%s', kernel_name='%s'", + dev.name, dev.kernel_name); + if ((*dev.kernel_name == '\0')) + goto error; + break; default: dbg_parse("unknown type of method"); goto error; diff --git a/udev.8 b/udev.8 index 5f497af92a..3eb4aecad2 100644 --- a/udev.8 +++ b/udev.8 @@ -161,9 +161,15 @@ device position on bus, like physical port of USB device string replacement of the kernel device name .br .RB "key: " KERNEL +.TP +.B IGNORE +tell udev to not care about creation of this device, e.g. because the +device is already handled by another program +.br +.RB "key: " KERNEL .P The methods are applied in the following order: -.BR CALLOUT ", " LABEL ", " NUMBER ", " TOPOLOGY ", " REPLACE "." +.BR IGNORE ", " CALLOUT ", " LABEL ", " NUMBER ", " TOPOLOGY ", " REPLACE "." .P .RB "The " NAME " ," SYMLINK " and " PROGRAM fields support simple printf-like string substitution: diff --git a/udev.c b/udev.c index bbff89bad5..116acf5389 100644 --- a/udev.c +++ b/udev.c @@ -221,6 +221,9 @@ exit_sysbus: sysbus_disconnect(); exit: + if (retval > 0) + retval = 0; + return -retval; } From bc20530f5017cf56fb55a4d9c04612bfb2664dd1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 10 Jan 2004 00:58:35 -0800 Subject: [PATCH 0386/4284] [PATCH] add a script that tests the IGNORE rule Can't figure out how to test for "nothing" in the udev-test.pl script framework. --- test/ignore_test | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 test/ignore_test diff --git a/test/ignore_test b/test/ignore_test new file mode 100644 index 0000000000..888fd16ff3 --- /dev/null +++ b/test/ignore_test @@ -0,0 +1,35 @@ +#!/bin/bash + +RULES=ignore_test.rules +CONFIG=ignore_test.conf + +export UDEV_TEST=yes +export SYSFS_PATH=$PWD/sys/ +export UDEV_CONFIG_FILE=$PWD/$CONFIG + +cat > $RULES << EOF +IGNORE, KERNEL="ttyUSB0" +EOF + +cat > $CONFIG << EOF +udev_root="$PWD/udev/" +udev_db="$PWD/udev/.udev.tdb" +udev_rules="$PWD/$RULES" +udev_permissions="$PWD/udev.permissions" +EOF + +mkdir udev + +export DEVPATH=class/tty/ttyUSB0 +export ACTION=add + +../udev tty +ls -l udev + +export ACTION=remove +../udev tty +ls -l udev + +rm $RULES +rm $CONFIG +rm -rf udev From 512d781263b4f7791ba1e7adde89b813e6c8fdc1 Mon Sep 17 00:00:00 2001 From: "tiggi@infa.abo.fi" Date: Sat, 10 Jan 2004 00:59:55 -0800 Subject: [PATCH 0387/4284] [PATCH] udev 012 old gcc fixup Hello, without this patch: wolf@duel:/tmp/ud/udev-012>gcc -v Reading specs from /usr/lib/gcc-lib/i386-slackware-linux/2.95.3/specs gcc version 2.95.3 20010315 (release) cannot compile udev. --- udev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.c b/udev.c index 116acf5389..30921420a0 100644 --- a/udev.c +++ b/udev.c @@ -229,9 +229,9 @@ exit: int main(int argc, char **argv, char **envp) { + int retval; main_argv = argv; main_envp = envp; - int retval; dbg("version %s", UDEV_VERSION); From 8240b4751473bbfed72e496e9fd36c3ccbf8d41d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 10 Jan 2004 01:02:44 -0800 Subject: [PATCH 0388/4284] [PATCH] added init.d udev script for debian Thanks to Mathieu Segaud for the file. --- etc/init.d/udev.debian | 113 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 etc/init.d/udev.debian diff --git a/etc/init.d/udev.debian b/etc/init.d/udev.debian new file mode 100644 index 0000000000..cf7b0070ad --- /dev/null +++ b/etc/init.d/udev.debian @@ -0,0 +1,113 @@ +#! /bin/bash +# +# random init script to setup /udev +# +# chkconfig: 2345 20 80 +# description: manage user-space device nodes in /udev +# +# 2003-12-23: - some tweaks to run silently on a debian system +# 2003-12-30: - manage creation (and deletion) of /proc/self/fd->fd and +# fd/[0,1,2]->std[in,out,err] links +# - creation and deletion of /proc/kcore->core link +# - creation and deletion of /proc/asound/oss/sndstat->sndstat link + + + +udev_dir=/udev +sysfs_dir=/sys +bin=/sbin/udev + +action () { + if test $2 ; then + echo $1 + else + echo "Assertion $2 failed" + echo "Aborting" + exit 1 + fi +} + +run_udev () { + # handle block devices and their partitions + for i in ${sysfs_dir}/block/*; do + # add each drive + export DEVPATH=${i#${sysfs_dir}} + $bin block & + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + $bin block & + fi + done + done + # all other device classes + for i in ${sysfs_dir}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + CLASS=`echo ${i#${sysfs_dir}} | \ + cut --delimiter='/' --fields=3-` + $bin $CLASS & + fi + done + done +} + + +case "$1" in + start) + if [ ! -d $udev_dir ]; then + mkdir $udev_dir + fi + if [ ! -d $sysfs_dir ]; then + exit 1 + fi + # propogate /udev from /sys - we only need this while we do not + # have initramfs and an early user-space with which to do early + # device bring up + action "Creating initial udev device nodes: " /bin/true + export ACTION=add + run_udev + + # hack to create stdin node + cd /udev && ln -s /proc/self/fd fd + cd /udev && ln -s fd/0 stdin + cd /udev && ln -s fd/1 stdout + cd /udev && ln -s fd/2 stderr + cd /udev && ln -s /proc/kcore core + cd /udev && ln -s /proc/asound/oss/sndstat sndstat + ;; + stop) + # be careful + action "Removing udev device nodes: " /bin/true + export ACTION=remove + run_udev + rm -f /udev/sndstat + rm -f /udev/core + rm -f /udev/stderr + rm -f /udev/stdout + rm -f /udev/stdin + rm -f /udev/fd + ;; + status) + if [ -d $udev_dir ]; then + echo "the udev device node directory exists" + else + echo "the udev device node directory does not exist" + fi + ;; + restart) + $0 stop + $0 start + ;; + reload) + # nothing to do here + ;; + *) + echo "Usage: $0 {start|stop|status|restart}" + exit 1 +esac + +exit 0 From d6e86b3752dc2603c5811b153a1db0143cac5721 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 10 Jan 2004 01:04:13 -0800 Subject: [PATCH 0389/4284] [PATCH] fix Silly udev script Hey, this is funny. I couldn't resist to give it a try and we need a few changes: - it's %2c otherwise nearly all my CD's are "good", but sure I also have bad ones :) - remove the node first, cause get_cddb() dies and leaves the old one there - remove spaces in name, cause this is our separator /udev/ |-- The_Cure-The_Peel_Sessions |-- cdrom -> ./The_Cure-The_Peel_Sessions |-- hda |-- hda1 |-- hda2 |-- hda4 --- extras/name_cdrom.pl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/extras/name_cdrom.pl b/extras/name_cdrom.pl index 569b119be7..7a14e866a6 100644 --- a/extras/name_cdrom.pl +++ b/extras/name_cdrom.pl @@ -2,8 +2,8 @@ # a horribly funny script that shows how flexible udev can really be # This is to be executed by udev with the following rules: -# CALLOUT, BUS="ide", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%1c", SYMLINK="cdrom" -# CALLOUT, BUS="scsi", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%1c", SYMLINK="cdrom" +# CALLOUT, BUS="ide", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%2c", SYMLINK="cdrom" +# CALLOUT, BUS="scsi", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%2c", SYMLINK="cdrom" # # The scsi rule catches USB cdroms and ide-scsi devices. # @@ -27,9 +27,10 @@ $major = $ARGV[0]; $minor = $ARGV[1]; # create our temp device node to read the cd info from +unlink($dev_node); if (system("mknod $dev_node b $major $minor")) { die "bad mknod failed"; - } +} # get it on my %cd=get_cddb(\%config); @@ -41,5 +42,7 @@ unlink($dev_node); unless(defined $cd{title}) { print"bad unknown cdrom\n"; } else { - print "good $cd{artist}_$cd{title}\n"; + $cd{artist} =~ s/ /_/g; + $cd{title} =~ s/ /_/g; + print "good $cd{artist}-$cd{title}\n"; } From 2794d2491714bc546bc209d6996f6ad97aa8a994 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 10 Jan 2004 01:05:38 -0800 Subject: [PATCH 0390/4284] [PATCH] udev - exec status fix for klibc Here is a patch to remove the ifdef's and fix klibc instead. --- klibc_fixups.h | 5 +++++ namedev.c | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/klibc_fixups.h b/klibc_fixups.h index a89638ead4..37622c86d6 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -4,6 +4,11 @@ #define KLIBC_FIXUPS_H +#define WTERMSIG(status) ((status) & 0x7f) +#define WEXITSTATUS(status) (((status) & 0xff00) >> 8) +#define WIFEXITED(status) (WTERMSIG(status) == 0) + + struct group { char *gr_name; /* group name */ char *gr_passwd; /* group password */ diff --git a/namedev.c b/namedev.c index 226c1d313f..08cceacda0 100644 --- a/namedev.c +++ b/namedev.c @@ -401,12 +401,10 @@ static int exec_callout(struct config_device *dev, char *value, int len) retval = -1; } -#ifndef __KLIBC__ if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { dbg("callout program status 0x%x", status); retval = -1; } -#endif } return retval; } From 41397661c625ece84c54d98d875d5afef4f829ff Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 10 Jan 2004 01:10:50 -0800 Subject: [PATCH 0391/4284] [PATCH] udev - make exec_callout() reusable Here is a patch that switches exec_callout() to be reusable. I want it to be callable in a different context. --- namedev.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/namedev.c b/namedev.c index 08cceacda0..e502ba1a39 100644 --- a/namedev.c +++ b/namedev.c @@ -319,7 +319,7 @@ static int do_ignore(struct sysfs_class_device *class_dev, struct udevice *udev, return -ENODEV; } -static int exec_callout(struct config_device *dev, char *value, int len) +static int exec_program(char *path, char *value, int len) { int retval; int res; @@ -332,7 +332,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) char *args[CALLOUT_MAXARG]; int i; - dbg("callout to '%s'", dev->exec_program); + dbg("callout to '%s'", path); retval = pipe(fds); if (retval != 0) { dbg("pipe failed"); @@ -348,9 +348,9 @@ static int exec_callout(struct config_device *dev, char *value, int len) /* child */ close(STDOUT_FILENO); dup(fds[1]); /* dup write side of pipe to STDOUT */ - if (strchr(dev->exec_program, ' ')) { + if (strchr(path, ' ')) { /* callout with arguments */ - pos = dev->exec_program; + pos = path; for (i=0; i < CALLOUT_MAXARG-1; i++) { args[i] = strsep(&pos, " "); if (args[i] == NULL) @@ -362,7 +362,7 @@ static int exec_callout(struct config_device *dev, char *value, int len) } retval = execve(args[0], args, main_envp); } else { - retval = execve(dev->exec_program, main_argv, main_envp); + retval = execve(path, main_argv, main_envp); } if (retval != 0) { dbg("child execve failed"); @@ -428,7 +428,7 @@ static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev /* substitute anything that needs to be in the program name */ apply_format(udev, dev->exec_program); - if (exec_callout(dev, udev->callout_value, NAME_SIZE)) + if (exec_program(dev->exec_program, udev->callout_value, NAME_SIZE)) continue; if (strcmp_pattern(dev->id, udev->callout_value) != 0) continue; From 40041ff4f1153360409ae88f0c0168ad2ee4d224 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 10 Jan 2004 01:14:34 -0800 Subject: [PATCH 0392/4284] [PATCH] added dri rule to the default config file. --- etc/udev/udev.rules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index c2b50eb90d..68c0c63c89 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -51,3 +51,7 @@ CALLOUT, BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", ID="cdrom", NAME="%k" # device mapper creates its own device nodes IGNORE, KERNEL="dm-[0-9]*" + +# DRI devices always go into a subdirectory (as per the LSB spec) +REPLACE, KERNEL="card*", NAME="dri/card%n" + From e64280b8b30569ad6029e48f23d290e06a28d7ed Mon Sep 17 00:00:00 2001 From: "eike-hotplug@sf-tec.de" Date: Sat, 10 Jan 2004 01:19:57 -0800 Subject: [PATCH 0393/4284] [PATCH] LSB init script and other stuff I had too much time during the holidays, so I played a bit with udev. The changes are like last time mostly on the init stuff. I'm sending you this as a great diff which is just for comments. What it does: -fix a typo in Makefile -use only one "grep -v" instead of many -don't include BK-Files into release (shrinks the stuff to 30%!) -add a new init script which is LSB compliant -add some flags to choose which one to use -use /etc/udev/udev.conf in Redhat init script as the source for the udev directory. If this is not done then the init script may create a directory which udev itself isn't using (I changed /udev to /Udev to avoid collisions with /usr and ran into this) -first check for sysfs_dir before creating udev_root (maybe someone else has already fixed this, I saw this discussion on lkml) --- Makefile | 15 ++--- etc/init.d/udev | 11 ++-- etc/init.d/udev.init.LSB | 133 +++++++++++++++++++++++++++++++++++++++ extras/ide-devfs.sh | 2 +- udev.spec | 12 +++- 5 files changed, 159 insertions(+), 14 deletions(-) create mode 100644 etc/init.d/udev.init.LSB diff --git a/Makefile b/Makefile index ffd61c0400..36f0272d02 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,7 @@ udevdir = ${prefix}/udev #USE_KLIBC = true # If you are running a cross compiler, you may want to set this -# to something more interesting, like "arm-linux-". I you want +# to something more interesting, like "arm-linux-". If you want # to compile vs uClibc, that can be done here as well. CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- CC = $(CROSS)gcc @@ -231,7 +231,7 @@ clean: -C $$target $@ ; \ done ; \ -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v CVS | grep -v "\.tar\.gz" | grep -v "\/\." | grep -v releases | grep -v BitKeeper | grep -v SCCS | grep -v "\.tdb" | grep -v "test\/sys" | sort ) +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz$" -e "\/\." -e releases -e BitKeeper -e SCCS -e "\.tdb$" -e test/sys | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . release: clean @@ -292,13 +292,16 @@ install-config: $(GEN_CONFIGS) $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ fi - - install: install-config install-dbus-policy all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) - $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev + @if [ "x$(USE_LSB)" = "xtrue" ]; then \ + $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev + ln -s $(DESTDIR)$(initdir)/udev $(sbin_dir)/rcudev + else + $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev + fi $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - ln -f -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug @@ -324,5 +327,3 @@ uninstall: uninstall-dbus-policy $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ -C $$target $@ ; \ done ; \ - - diff --git a/etc/init.d/udev b/etc/init.d/udev index 0d26d07083..364a9aa5f7 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -7,7 +7,8 @@ . /etc/rc.d/init.d/functions -udev_dir=/udev +. /etc/udev/udev.conf + sysfs_dir=/sys bin=/sbin/udev @@ -42,12 +43,12 @@ run_udev () { case "$1" in start) - if [ ! -d $udev_dir ]; then - mkdir $udev_dir - fi if [ ! -d $sysfs_dir ]; then exit 1 fi + if [ ! -d $udev_root ]; then + mkdir $udev_root + fi # propogate /udev from /sys - we only need this while we do not # have initramfs and an early user-space with which to do early # device bring up @@ -62,7 +63,7 @@ case "$1" in run_udev ;; status) - if [ -d $udev_dir ]; then + if [ -d $udev_root ]; then echo "the udev device node directory exists" else echo "the udev device node directory does not exist" diff --git a/etc/init.d/udev.init.LSB b/etc/init.d/udev.init.LSB new file mode 100644 index 0000000000..0f5881c416 --- /dev/null +++ b/etc/init.d/udev.init.LSB @@ -0,0 +1,133 @@ +#! /bin/sh +# +# Author: Rolf Eike Beer +# derived from original RedHat udev init script +# based on the SuSE 9.0 template (c) 1995-2002 SuSE Linux AG +# +# /etc/init.d/udev +# and its symbolic link +# /(usr/)sbin/rcudev +# +# System startup script for udev +# +# LSB compatible service control script; see http://www.linuxbase.org/spec/ +# +### BEGIN INIT INFO +# Provides: udev +# Required-Start: +# Required-Stop: +# Default-Start: 1 2 3 5 +# Default-Stop: 0 6 +# Short-Description: manage user-space device nodes in /udev +# Description: Start udev to create the device files for all +# devices already present in system when script is +# called. All other devices files will be automatically +# created when udev is called via /sbin/hotplug. +# Requires at least a kernel 2.6 to work properly. +### END INIT INFO +# +# Note on script names: +# http://www.linuxbase.org/spec/refspecs/LSB_1.2.0/gLSB/scrptnames.html +# A registry has been set up to manage the init script namespace. +# http://www.lanana.org/ +# Please use the names already registered or register one or use a +# vendor prefix. + + +# Check for missing binaries (stale symlinks should not happen) +UDEV_BIN=/sbin/udev +test -x $UDEV_BIN || exit 5 + +# Check for existence of needed config file and read it +UDEV_CONFIG=/etc/udev/udev.conf +test -r $UDEV_CONFIG || exit 6 +. $UDEV_CONFIG + +# Directory where sysfs is mounted +SYSFS_DIR=/sys + +# Source LSB init functions +. /lib/lsb/init-functions + +run_udev () { + # handle block devices and their partitions + for i in ${SYSFS_DIR}/block/*; do + # add each drive + export DEVPATH=${i#${SYSFS_DIR}} + $UDEV_BIN block & + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${SYSFS_DIR}} + $UDEV_BIN block & + fi + done + done + # all other device classes + for i in ${SYSFS_DIR}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${SYSFS_DIR}} + CLASS=`echo ${i#${SYSFS_DIR}} | \ + cut --delimiter='/' --fields=3-` + $UDEV_BIN $CLASS & + fi + done + done +} + +case "$1" in + start) + if [ ! -d $SYSFS_DIR ]; then + log_failure_msg "${0}: SYSFS_DIR \"$SYSFS_DIR\" not found" + exit 1 + fi + if [ ! -d $udev_root ]; then + mkdir $udev_root || exit 4 + fi + # propogate /udev from /sys - we only need this while we do not + # have initramfs and an early user-space with which to do early + # device bring up + echo -n "Creating initial udev device nodes: " + export ACTION=add + run_udev + log_success_msg + ;; + stop) + # be careful + echo -n "Removing udev device nodes: " + export ACTION=remove + run_udev + rm -f $udev_db || exit 1 + rmdir $udev_root || exit 1 + log_success_msg + ;; + restart) + $0 stop + $0 start + + exit $? + ;; + force-reload) + echo -n "Reload udev " + $0 stop && $0 start + exit $? + ;; + reload) + exit 3 + ;; + status) + echo -n "Checking for udev root directory: " + if [ -d $udev_root ]; then + log_success_msg found + else + log_warning_msg "not found" + exit 3 + fi + ;; + *) + echo "Usage: $0 {start|stop|status|restart|force-reload|reload}" + exit 1 + ;; +esac diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index db96b5d299..57fb00b676 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -38,7 +38,7 @@ get_dev_number() { if [ -z "$3" ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then - echo ${1} ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` + echo $1 ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` elif [ "${MEDIA}" = "disk" ]; then echo $1 ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc fi diff --git a/udev.spec b/udev.spec index 9e301deb7c..4056025df8 100644 --- a/udev.spec +++ b/udev.spec @@ -16,6 +16,11 @@ # 1 - debugging enabled %define debug 0 +# if we want to use the LSB version of the init script or the Redhat one +# 0 - use Redhat version: etc/init.d/udev +# 1 - use LSB version: etc/init.d/udev.init.LSB +%define lsb 0 + Summary: A userspace implementation of devfs Name: udev Version: 012_bk @@ -52,6 +57,9 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %if %{dbus} USE_DBUS=true %endif +%if %{lsb} + USE_LSB=true +%endif %post /sbin/chkconfig --add udev @@ -81,6 +89,9 @@ rm -rf $RPM_BUILD_ROOT %attr(0644,root,root) %{_mandir}/man8/udev.8* %changelog +* Mon Jan 05 2004 Rolf Eike Beer +- add defines to choose the init script (Redhat or LSB) + * Tue Dec 16 2003 Robert Love - install the initscript and run chkconfig on it @@ -96,4 +107,3 @@ rm -rf $RPM_BUILD_ROOT * Mon Jul 28 2003 Paul Mundt - Initial spec file for udev-0.2. - From 606143c8d214f7bb7271d40d514eb23a86547b3c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 12 Jan 2004 21:17:22 -0800 Subject: [PATCH 0394/4284] [PATCH] udev - Makefile error I get the following error on install: pim:/home/kay/src/udev.test# make install sed -e "s:@udevdir@:/udev:" < etc/udev/udev.conf.in > etc/udev/udev.conf /usr/bin/install -c -d /etc/udev/ /usr/bin/install -c -d /udev /usr/bin/install -c -d /etc/hotplug.d/default /usr/bin/install -c -D udev /sbin/udev /bin/sh: -c: line 2: syntax error: unexpected end of file make: *** [install] Error 2 --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 36f0272d02..5e64129266 100644 --- a/Makefile +++ b/Makefile @@ -297,10 +297,10 @@ install: install-config install-dbus-policy all $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) @if [ "x$(USE_LSB)" = "xtrue" ]; then \ - $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev - ln -s $(DESTDIR)$(initdir)/udev $(sbin_dir)/rcudev - else - $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev + $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ + ln -s $(DESTDIR)$(initdir)/udev $(sbin_dir)/rcudev; \ + else \ + $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ fi $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug From 5472beeea5884dfc8bc5afb0f963de3ea3232e66 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 12 Jan 2004 21:18:57 -0800 Subject: [PATCH 0395/4284] [PATCH] udev - advanced user query options This patch improves the user options for udev. It is possible now to query for the name, the symlinks or owner/group. If asked for the name of the node we are able to prepend the udev_root with the -r option. SAMPLE: kay@pim:~/src/udev.test$ ./udev -V udev, version 012_bk kay@pim:~/src/udev.test$ ./udev -h Usage: [-qrVh] -q query database for the specified value -p device path used for query -r print udev root -V print udev version -h print this help text kay@pim:~/src/udev.test$ ./udev -r /udev/ kay@pim:~/src/udev.test$ ./udev -q name -p /class/video4linux/video0 video/webcam0 kay@pim:~/src/udev.test$ ./udev -q symlink -p /class/video4linux/video0 camera0 kamera0 kay@pim:~/src/udev.test$ ./udev -q owner -p /class/video4linux/video0 501 kay@pim:~/src/udev.test$ ./udev -r -q name -p /class/video4linux/video0 /udev/video/webcam0 --- udev.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 93 insertions(+), 16 deletions(-) diff --git a/udev.c b/udev.c index 30921420a0..7078f089e2 100644 --- a/udev.c +++ b/udev.c @@ -82,13 +82,26 @@ static inline char *get_seqnum(void) return seqnum; } +enum query_type { + NONE, + NAME, + SYMLINK, + OWNER, + GROUP +}; + static inline int udev_user(int argc, char **argv) { - static const char short_options[] = "q:rVh"; + static const char short_options[] = "p:q:rVh"; int option; int retval = -EINVAL; struct udevice dev; + int root = 0; + enum query_type query = NONE; + char result[NAME_SIZE] = ""; + char path[NAME_SIZE] = ""; + /* get command line options */ while (1) { option = getopt(argc, argv, short_options); if (option == -1) @@ -96,25 +109,40 @@ static inline int udev_user(int argc, char **argv) dbg("option '%c'", option); switch (option) { + case 'p': + dbg("udev path: %s\n", optarg); + strfieldcpy(path, optarg); + break; + case 'q': dbg("udev query: %s\n", optarg); - retval = udevdb_open_ro(); - if (retval != 0) { - printf("unable to open udev database\n"); - return -1; + + if (strcmp(optarg, "name") == 0) { + query = NAME; + break; } - retval = udevdb_get_dev(optarg, &dev); - if (retval == 0) { - printf("%s\n", dev.name); - } else { - printf("device not found in udev database\n"); + + if (strcmp(optarg, "symlink") == 0) { + query = SYMLINK; + break; } - udevdb_exit(); - return retval; + + if (strcmp(optarg, "owner") == 0) { + query = OWNER; + break; + } + + if (strcmp(optarg, "group") == 0) { + query = GROUP; + break; + } + + printf("unknown query type\n"); + return -EINVAL; case 'r': - printf("%s\n", udev_root); - return 0; + root = 1; + break; case 'V': printf("udev, version %s\n", UDEV_VERSION); @@ -128,14 +156,63 @@ static inline int udev_user(int argc, char **argv) } } + /* process options */ + if (query != NONE) { + if (path[0] == '\0') { + printf("query needs device path specified\n"); + return -EINVAL; + } + + retval = udevdb_open_ro(); + if (retval != 0) { + printf("unable to open udev database\n"); + return -EACCES; + } + retval = udevdb_get_dev(path, &dev); + if (retval == 0) { + switch(query) { + case NAME: + if (root) + strfieldcpy(result, udev_root); + strncat(result, dev.name, sizeof(result)); + break; + + case SYMLINK: + strfieldcpy(result, dev.symlink); + break; + + case GROUP: + strfieldcpy(result, dev.group); + break; + + case OWNER: + strfieldcpy(result, dev.owner); + break; + + default: + break; + } + printf("%s\n", result); + } else { + printf("device not found in udev database\n"); + } + udevdb_exit(); + return retval; + } + + if (root) { + printf("%s\n", udev_root); + return 0; + } + help: printf("Usage: [-qrVh]\n" - " -q query database for the name of the created node\n" + " -q query database for the specified value\n" + " -p device path used for query\n" " -r print udev root\n" " -V print udev version\n" " -h print this help text\n" "\n"); - return retval; } From ac28b86d631f23b5df74dbeb33e76a2b3f5d88bb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 12 Jan 2004 21:39:05 -0800 Subject: [PATCH 0396/4284] [PATCH] udev - drop all methods :) > Hi, > as promised yesterday, here is a patch that drops the explicit methods > given in the udev config and implement only one type of rule. > > A rule now consists only of a number of keys to match. All known keys > are valid in any combination. The former configs should work with a few > changes: > > o the ", " at the beginning of the line should be removed > > o the result of the externel program is matched with RESULT= instead if ID= > the PROGRAM= key is only valid if the program exits with zero > (just exit with nozero in a script if the rule should not match) > > o rules are processed in order they appear in the file, no priority > > o if NAME="" is given, udev is instructed to ignore this device, > no node will be created > > > EXAMPLE: > > # combined BUS, SYSFS and KERNEL > BUS="usb", KERNEL="video*", SYSFS_model="Creative Labs WebCam*", NAME="test/webcam%n" > > # exec script only for the first ide drive (hda), all other will be skipped > BUS="ide", KERNEL="hda*", PROGRAM="/home/kay/src/udev.kay/extras/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c" > > > The udev-test.pl and test.block works fine here. > Please adapt your config and give it a try. > Here is a slightly better version of the patch. After a conversation with Patrick, we are now able to execute the PROGRAM and also match in all following rules with the RESULT value from this exec. EXAMPLE: We have 7 rules with RESULT and 2 with PROGRAM. Only the 5th rule matches with the callout result from the exec in the 4th rule. RULES: PROGRAM="/bin/echo abc", RESULT="no_match", NAME="web-no-2" KERNEL="video*", RESULT="123", NAME="web-no-3" KERNEL="video*", RESULT="123", NAME="web-no-4" PROGRAM="/bin/echo 123", RESULT="no_match", NAME="web-no-5" KERNEL="video*", RESULT="123", NAME="web-yes" RESULT: Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo abc' Jan 11 23:36:52 pim udev[26050]: execute_program: result is 'abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='abc' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check PROGRAM Jan 11 23:36:52 pim udev[26050]: execute_program: executing '/bin/echo 123' Jan 11 23:36:52 pim udev[26050]: execute_program: result is '123' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: PROGRAM returned successful Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='no_match', udev->program_result='123' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT is not matching Jan 11 23:36:52 pim udev[26050]: namedev_name_device: process rule Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for KERNEL dev->kernel='video*' class_dev->name='video0' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: KERNEL matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: check for RESULT dev->result='123', udev->program_result='123' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: RESULT matches Jan 11 23:36:52 pim udev[26050]: namedev_name_device: found matching rule, 'video*' becomes '' Jan 11 23:36:52 pim udev[26050]: namedev_name_device: name, 'web-yes' is going to have owner='', group='', mode = 0600 --- namedev.c | 371 ++++++++++++++++++++-------------------------- namedev.h | 29 +--- namedev_parse.c | 154 ++++--------------- test/udev-test.pl | 117 +++++++-------- udev.h | 2 +- 5 files changed, 249 insertions(+), 424 deletions(-) diff --git a/namedev.c b/namedev.c index e502ba1a39..41fefc4bc8 100644 --- a/namedev.c +++ b/namedev.c @@ -213,27 +213,27 @@ static void apply_format(struct udevice *udev, unsigned char *string) dbg("substitute major number '%u'", udev->major); break; case 'c': - if (strlen(udev->callout_value) == 0) + if (strlen(udev->program_result) == 0) break; if (num) { /* get part of return string */ - strncpy(temp, udev->callout_value, sizeof(temp)); + strncpy(temp, udev->program_result, sizeof(temp)); pos2 = temp; while (num) { num--; pos3 = strsep(&pos2, " "); if (pos3 == NULL) { - dbg("requested part of callout string not found"); + dbg("requested part of result string not found"); break; } } if (pos3) { strcat(pos, pos3); - dbg("substitute partial callout output '%s'", pos3); + dbg("substitute part of result string '%s'", pos3); } } else { - strcat(pos, udev->callout_value); - dbg("substitute callout output '%s'", udev->callout_value); + strcat(pos, udev->program_result); + dbg("substitute result string '%s'", udev->program_result); } break; default: @@ -298,28 +298,7 @@ exit: return; /* here to prevent compiler warning... */ } -static int do_ignore(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) -{ - struct config_device *dev; - struct list_head *tmp; - - list_for_each(tmp, &config_device_list) { - dev = list_entry(tmp, struct config_device, node); - if (dev->type != IGNORE) - continue; - - dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name); - if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0) - continue; - - dbg("found name, '%s' will be ignored", dev->kernel_name); - - return 0; - } - return -ENODEV; -} - -static int exec_program(char *path, char *value, int len) +static int execute_program(char *path, char *value, int len) { int retval; int res; @@ -332,7 +311,7 @@ static int exec_program(char *path, char *value, int len) char *args[CALLOUT_MAXARG]; int i; - dbg("callout to '%s'", path); + dbg("executing '%s'", path); retval = pipe(fds); if (retval != 0) { dbg("pipe failed"); @@ -349,7 +328,7 @@ static int exec_program(char *path, char *value, int len) close(STDOUT_FILENO); dup(fds[1]); /* dup write side of pipe to STDOUT */ if (strchr(path, ' ')) { - /* callout with arguments */ + /* exec with arguments */ pos = path; for (i=0; i < CALLOUT_MAXARG-1; i++) { args[i] = strsep(&pos, " "); @@ -379,11 +358,11 @@ static int exec_program(char *path, char *value, int len) break; buffer[res] = '\0'; if (res > len) { - dbg("callout len %d too short", len); + dbg("result len %d too short", len); retval = -1; } if (value_set) { - dbg("callout value already set"); + dbg("result value already set"); retval = -1; } else { value_set = 1; @@ -391,7 +370,7 @@ static int exec_program(char *path, char *value, int len) pos = value + strlen(value)-1; if (pos[0] == '\n') pos[0] = '\0'; - dbg("callout returned '%s'", value); + dbg("result is '%s'", value); } } close(fds[0]); @@ -402,46 +381,14 @@ static int exec_program(char *path, char *value, int len) } if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { - dbg("callout program status 0x%x", status); + dbg("exec program status 0x%x", status); retval = -1; } } return retval; } -static int do_callout(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) -{ - struct config_device *dev; - - list_for_each_entry(dev, &config_device_list, node) { - if (dev->type != CALLOUT) - continue; - - if (dev->bus[0] != '\0') { - /* as the user specified a bus, we must match it up */ - if (!sysfs_device) - continue; - dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); - if (strcasecmp(dev->bus, sysfs_device->bus) != 0) - continue; - } - - /* substitute anything that needs to be in the program name */ - apply_format(udev, dev->exec_program); - if (exec_program(dev->exec_program, udev->callout_value, NAME_SIZE)) - continue; - if (strcmp_pattern(dev->id, udev->callout_value) != 0) - continue; - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - dbg("callout returned matching value '%s', '%s' becomes '%s'", - dev->id, class_dev->name, udev->name); - return 0; - } - return -ENODEV; -} - -static int match_pair(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair) +static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair) { struct sysfs_attribute *tmpattr = NULL; char *c; @@ -461,7 +408,6 @@ static int match_pair(struct sysfs_class_device *class_dev, struct sysfs_device if (tmpattr) goto label_found; } - return -ENODEV; label_found: @@ -478,53 +424,26 @@ label_found: return 0; } -static int do_label(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { struct sysfs_pair *pair; - struct config_device *dev; int i; - int match; - list_for_each_entry(dev, &config_device_list, node) { - if (dev->type != LABEL) - continue; - - if (dev->bus[0] != '\0') { - /* as the user specified a bus, we must match it up */ - if (!sysfs_device) - continue; - dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); - if (strcasecmp(dev->bus, sysfs_device->bus) != 0) - continue; + for (i = 0; i < MAX_SYSFS_PAIRS; ++i) { + pair = &dev->sysfs_pair[i]; + if ((pair->file[0] == '\0') || (pair->value[0] == '\0')) + break; + if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) { + dbg("sysfs attribute doesn't match"); + return -ENODEV; } - - match = 1; - for (i = 0; i < MAX_SYSFS_PAIRS; ++i) { - pair = &dev->sysfs_pair[i]; - if ((pair->file[0] == '\0') || (pair->value[0] == '\0')) - break; - if (match_pair(class_dev, sysfs_device, pair) != 0) { - match = 0; - break; - } - } - if (match == 0) - continue; - - /* found match */ - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - dbg("found matching attribute, '%s' becomes '%s' ", - class_dev->name, udev->name); - - return 0; } - return -ENODEV; + + return 0; } -static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - struct config_device *dev; char path[SYSFS_PATH_MAX]; int found; char *temp = NULL; @@ -533,107 +452,56 @@ static int do_number(struct sysfs_class_device *class_dev, struct udevice *udev, if (!sysfs_device) return -ENODEV; - list_for_each_entry(dev, &config_device_list, node) { - if (dev->type != NUMBER) - continue; - - dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); - if (strcasecmp(dev->bus, sysfs_device->bus) != 0) - continue; - - found = 0; - strfieldcpy(path, sysfs_device->path); + found = 0; + strfieldcpy(path, sysfs_device->path); + temp = strrchr(path, '/'); + dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); + if (strstr(temp, dev->id) != NULL) { + found = 1; + } else { + *temp = 0x00; temp = strrchr(path, '/'); dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); - if (strstr(temp, dev->id) != NULL) { + if (strstr(temp, dev->id) != NULL) found = 1; - } else { - *temp = 0x00; - temp = strrchr(path, '/'); - dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); - if (strstr(temp, dev->id) != NULL) - found = 1; - } - if (!found) - continue; - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - dbg("found matching id '%s', '%s' becomes '%s'", - dev->id, class_dev->name, udev->name); - return 0; } - return -ENODEV; + if (!found) { + dbg("id doesn't match"); + return -ENODEV; + } + + return 0; } -static int do_topology(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - struct config_device *dev; char path[SYSFS_PATH_MAX]; int found; char *temp = NULL; - /* we have to have a sysfs device for TOPOLOGY to work */ + /* we have to have a sysfs device for NUMBER to work */ if (!sysfs_device) return -ENODEV; - list_for_each_entry(dev, &config_device_list, node) { - if (dev->type != TOPOLOGY) - continue; - - dbg("dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); - if (strcasecmp(dev->bus, sysfs_device->bus) != 0) - continue; - - found = 0; - strfieldcpy(path, sysfs_device->path); + found = 0; + strfieldcpy(path, sysfs_device->path); + temp = strrchr(path, '/'); + dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); + if (strstr(temp, dev->place) != NULL) { + found = 1; + } else { + *temp = 0x00; temp = strrchr(path, '/'); dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); - if (strstr(temp, dev->place) != NULL) { + if (strstr(temp, dev->place) != NULL) found = 1; - } else { - *temp = 0x00; - temp = strrchr(path, '/'); - dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); - if (strstr(temp, dev->place) != NULL) - found = 1; - } - if (!found) - continue; - - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - dbg("found matching place '%s', '%s' becomes '%s'", - dev->place, class_dev->name, udev->name); - return 0; } - return -ENODEV; -} - -static int do_replace(struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) -{ - struct config_device *dev; - - list_for_each_entry(dev, &config_device_list, node) { - if (dev->type != REPLACE) - continue; - - dbg("compare name '%s' with '%s'", dev->kernel_name, class_dev->name); - if (strcmp_pattern(dev->kernel_name, class_dev->name) != 0) - continue; - - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - dbg("found name, '%s' becomes '%s'", dev->kernel_name, udev->name); - - return 0; + if (!found) { + dbg("place doesn't match"); + return -ENODEV; } - return -ENODEV; -} -static void do_kernelname(struct sysfs_class_device *class_dev, struct udevice *udev) -{ - /* heh, this is pretty simple... */ - strfieldcpy(udev->name, class_dev->name); + return 0; } static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev) @@ -725,7 +593,7 @@ exit: int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) { struct sysfs_device *sysfs_device = NULL; - int retval = 0; + struct config_device *dev; struct perm_device *perm; char *pos; @@ -752,34 +620,109 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud strfieldcpy(udev->kernel_number, pos); dbg("kernel_number='%s'", udev->kernel_number); - /* rules are looked at in priority order */ - retval = do_ignore(class_dev, udev, sysfs_device); - if (retval == 0) { - dbg("name, '%s' is being ignored", class_dev->name); - return 1; + /* look for a matching rule to apply */ + list_for_each_entry(dev, &config_device_list, node) { + dbg("process rule"); + + /* check for matching bus value */ + if (dev->bus[0] != '\0') { + if (sysfs_device == NULL) { + dbg("device has no bus"); + continue; + } + dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { + dbg(FIELD_BUS " is not matching"); + continue; + } else { + dbg(FIELD_BUS " matches"); + } + } + + /* check for matching kernel name*/ + if (dev->kernel[0] != '\0') { + dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); + if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { + dbg(FIELD_KERNEL " is not matching"); + continue; + } else { + dbg(FIELD_KERNEL " matches"); + } + } + + /* check for matching bus id */ + if (dev->id[0] != '\0') { + dbg("check " FIELD_ID); + if (match_id(dev, class_dev, sysfs_device) != 0) { + dbg(FIELD_ID " is not matching"); + continue; + } else { + dbg(FIELD_ID " matches"); + } + } + + /* check for matching place of device */ + if (dev->place[0] != '\0') { + dbg("check " FIELD_PLACE); + if (match_place(dev, class_dev, sysfs_device) != 0) { + dbg(FIELD_PLACE " is not matching"); + continue; + } else { + dbg(FIELD_PLACE " matches"); + } + } + + /* check for matching sysfs pairs */ + if (dev->sysfs_pair[0].file[0] != '\0') { + dbg("check " FIELD_SYSFS " pairs"); + if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) { + dbg(FIELD_SYSFS " is not matching"); + continue; + } else { + dbg(FIELD_SYSFS " matches"); + } + } + + /* execute external program */ + if (dev->program[0] != '\0') { + dbg("check " FIELD_PROGRAM); + apply_format(udev, dev->program); + if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { + dbg(FIELD_PROGRAM " returned nozero"); + continue; + } else { + dbg(FIELD_PROGRAM " returned successful"); + } + } + + /* check for matching result of external program */ + if (dev->result[0] != '\0') { + dbg("check for " FIELD_RESULT + " dev->result='%s', udev->program_result='%s'", + dev->result, udev->program_result); + if (strcmp_pattern(dev->result, udev->program_result) != 0) { + dbg(FIELD_RESULT " is not matching"); + continue; + } else { + dbg(FIELD_RESULT " matches"); + } + } + + /* check if we are instructed to ignore this device */ + if (dev->name[0] == '\0') { + dbg("instructed to ignore this device"); + return -1; + } + + /* Yup, this rule belongs to us! */ + dbg("found matching rule, '%s' becomes '%s'", dev->kernel, udev->name); + strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); + goto found; } - retval = do_callout(class_dev, udev, sysfs_device); - if (retval == 0) - goto found; - - retval = do_label(class_dev, udev, sysfs_device); - if (retval == 0) - goto found; - - retval = do_number(class_dev, udev, sysfs_device); - if (retval == 0) - goto found; - - retval = do_topology(class_dev, udev, sysfs_device); - if (retval == 0) - goto found; - - retval = do_replace(class_dev, udev, sysfs_device); - if (retval == 0) - goto found; - - do_kernelname(class_dev, udev); + /* no rule was found so we use the kernel name */ + strfieldcpy(udev->name, class_dev->name); goto done; found: diff --git a/namedev.h b/namedev.h index f1e770277b..4e75db6410 100644 --- a/namedev.h +++ b/namedev.h @@ -28,17 +28,6 @@ struct sysfs_class_device; - -enum config_type { - KERNEL_NAME = 0, /* must be 0 to let memset() default to this value */ - LABEL = 1, - NUMBER = 2, - TOPOLOGY = 3, - REPLACE = 4, - CALLOUT = 5, - IGNORE = 6, -}; - #define BUS_SIZE 30 #define FILE_SIZE 50 #define VALUE_SIZE 100 @@ -46,23 +35,17 @@ enum config_type { #define PLACE_SIZE 50 #define PROGRAM_SIZE 100 -#define TYPE_LABEL "LABEL" -#define TYPE_NUMBER "NUMBER" -#define TYPE_TOPOLOGY "TOPOLOGY" -#define TYPE_REPLACE "REPLACE" -#define TYPE_CALLOUT "CALLOUT" -#define TYPE_IGNORE "IGNORE" - #define FIELD_BUS "BUS" -#define FIELD_ID "ID" #define FIELD_SYSFS "SYSFS_" +#define FIELD_ID "ID" #define FIELD_PLACE "PLACE" #define FIELD_PROGRAM "PROGRAM" +#define FIELD_RESULT "RESULT" #define FIELD_KERNEL "KERNEL" #define FIELD_NAME "NAME" #define FIELD_SYMLINK "SYMLINK" -#define CALLOUT_MAXARG 8 +#define CALLOUT_MAXARG 10 #define MAX_SYSFS_PAIRS 5 struct sysfs_pair { @@ -73,12 +56,12 @@ struct sysfs_pair { struct config_device { struct list_head node; - enum config_type type; char bus[BUS_SIZE]; char id[ID_SIZE]; char place[PLACE_SIZE]; - char kernel_name[NAME_SIZE]; - char exec_program[PROGRAM_SIZE]; + char kernel[NAME_SIZE]; + char program[PROGRAM_SIZE]; + char result[PROGRAM_SIZE]; char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; diff --git a/namedev_parse.c b/namedev_parse.c index 5b5a5b3bc1..98e822dfef 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -86,37 +86,13 @@ int get_pair(char **orig_string, char **left, char **right) void dump_config_dev(struct config_device *dev) { - switch (dev->type) { - case KERNEL_NAME: - dbg_parse("KERNEL name='%s'", dev->name); - break; - case LABEL: - dbg_parse("LABEL name='%s', bus='%s', sysfs_file[0]='%s', sysfs_value[0]='%s'", - dev->name, dev->bus, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value); - break; - case NUMBER: - dbg_parse("NUMBER name='%s', bus='%s', id='%s'", - dev->name, dev->bus, dev->id); - break; - case TOPOLOGY: - dbg_parse("TOPOLOGY name='%s', bus='%s', place='%s'", - dev->name, dev->bus, dev->place); - break; - case REPLACE: - dbg_parse("REPLACE name='%s', kernel_name='%s'", - dev->name, dev->kernel_name); - break; - case CALLOUT: - dbg_parse("CALLOUT name='%s', bus='%s', program='%s', id='%s'", - dev->name, dev->bus, dev->exec_program, dev->id); - break; - case IGNORE: - dbg_parse("IGNORE name='%s', kernel_name='%s'", - dev->name, dev->kernel_name); - break; - default: - dbg_parse("unknown type of method"); - } + /*FIXME dump all sysfs's */ + dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', " + "sysfs_file[0]='%s', sysfs_value[0]='%s', " + "kernel='%s', program='%s', result='%s'", + dev->name, dev->symlink, dev->bus, dev->place, dev->id, + dev->sysfs_pair[0].file, dev->sysfs_pair[0].value, + dev->kernel, dev->program, dev->result); } void dump_config_dev_list(void) @@ -150,6 +126,7 @@ int namedev_init_rules(void) char *temp2; char *temp3; FILE *fd; + int program_given = 0; int retval = 0; struct config_device dev; @@ -185,42 +162,6 @@ int namedev_init_rules(void) memset(&dev, 0x00, sizeof(struct config_device)); - /* get the method */ - temp2 = strsep(&temp, ","); - - if (strcasecmp(temp2, TYPE_LABEL) == 0) { - dev.type = LABEL; - goto keys; - } - - if (strcasecmp(temp2, TYPE_NUMBER) == 0) { - dev.type = NUMBER; - goto keys; - } - - if (strcasecmp(temp2, TYPE_TOPOLOGY) == 0) { - dev.type = TOPOLOGY; - goto keys; - } - - if (strcasecmp(temp2, TYPE_REPLACE) == 0) { - dev.type = REPLACE; - goto keys; - } - - if (strcasecmp(temp2, TYPE_CALLOUT) == 0) { - dev.type = CALLOUT; - goto keys; - } - - if (strcasecmp(temp2, TYPE_IGNORE) == 0) { - dev.type = IGNORE; - goto keys; - } - - dbg_parse("unknown type of method '%s'", temp2); - goto error; -keys: /* get all known keys */ while (1) { retval = get_pair(&temp, &temp2, &temp3); @@ -264,12 +205,18 @@ keys: } if (strcasecmp(temp2, FIELD_KERNEL) == 0) { - strfieldcpy(dev.kernel_name, temp3); + strfieldcpy(dev.kernel, temp3); continue; } if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { - strfieldcpy(dev.exec_program, temp3); + program_given = 1; + strfieldcpy(dev.program, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_RESULT) == 0) { + strfieldcpy(dev.result, temp3); continue; } @@ -286,60 +233,15 @@ keys: dbg_parse("unknown type of field '%s'", temp2); } - /* check presence of keys according to method type */ - switch (dev.type) { - case LABEL: - dbg_parse(TYPE_LABEL " name='%s', bus='%s', " - "sysfs_file[0]='%s', sysfs_value[0]='%s', symlink='%s'", - dev.name, dev.bus, dev.sysfs_pair[0].file, - dev.sysfs_pair[0].value, dev.symlink); - if ((*dev.name == '\0') || - (*dev.sysfs_pair[0].file == '\0') || - (*dev.sysfs_pair[0].value == '\0')) - goto error; - break; - case NUMBER: - dbg_parse(TYPE_NUMBER " name='%s', bus='%s', id='%s', symlink='%s'", - dev.name, dev.bus, dev.id, dev.symlink); - if ((*dev.name == '\0') || - (*dev.bus == '\0') || - (*dev.id == '\0')) - goto error; - break; - case TOPOLOGY: - dbg_parse(TYPE_TOPOLOGY " name='%s', bus='%s', " - "place='%s', symlink='%s'", - dev.name, dev.bus, dev.place, dev.symlink); - if ((*dev.name == '\0') || - (*dev.bus == '\0') || - (*dev.place == '\0')) - goto error; - break; - case REPLACE: - dbg_parse(TYPE_REPLACE " name='%s', kernel_name='%s', symlink='%s'", - dev.name, dev.kernel_name, dev.symlink); - if ((*dev.name == '\0') || - (*dev.kernel_name == '\0')) - goto error; - break; - case CALLOUT: - dbg_parse(TYPE_CALLOUT " name='%s', bus='%s', program='%s', " - "id='%s', symlink='%s'", - dev.name, dev.bus, dev.exec_program, - dev.id, dev.symlink); - if ((*dev.name == '\0') || - (*dev.id == '\0') || - (*dev.exec_program == '\0')) - goto error; - break; - case IGNORE: - dbg_parse(TYPE_IGNORE "name='%s', kernel_name='%s'", - dev.name, dev.kernel_name); - if ((*dev.kernel_name == '\0')) - goto error; - break; - default: - dbg_parse("unknown type of method"); + /* simple plausibility check for given keys */ + if ((dev.sysfs_pair[0].file[0] == '\0') ^ + (dev.sysfs_pair[0].value[0] == '\0')) { + dbg("inconsistency in SYSFS_ key"); + goto error; + } + + if ((dev.result[0] != '\0') && (program_given == 0)) { + dbg("RESULT is only useful when PROGRAM called in any rule before"); goto error; } @@ -347,11 +249,11 @@ keys: if (retval) { dbg("add_config_dev returned with error %d", retval); continue; +error: + dbg("%s:%d:%Zd: parse error, rule skipped", + udev_rules_filename, lineno, temp - line); } } -error: - dbg_parse("%s:%d:%Zd: field missing or parse error", udev_rules_filename, - lineno, temp - line); exit: fclose(fd); return retval; diff --git a/test/udev-test.pl b/test/udev-test.pl index 97c0094921..ab27c74c6a 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -38,8 +38,8 @@ my @tests = ( devpath => "block/sda", expected => "boot_disk" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "class/tty/ttyUSB0", expected => "visor/0" , conf => < "class/tty/ttyUSB0", expected => "visor/0" , conf => < "class/tty/ttyUSB0", expected => "visor/0" , conf => < "class/tty/ttyUSB0", expected => "visor" , conf => < "visor" , conf => < "visor" , conf => < "visor" , conf => < "class/tty/ttyUSB0", expected => "sub/direct/ory/visor" , conf => < "block/sda/sda3", expected => "first_disk3" , conf => < "block/sda/sda3", expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "callout result substitution", + desc => "program result substitution", subsys => "block", devpath => "block/sda/sda3", expected => "special-device-3" , conf => < "callout program substitution", + desc => "program result substitution", subsys => "block", devpath => "block/sda/sda3", expected => "test-0:0:0:0" , conf => < "callout program substitution (numbered part of)", + desc => "program result substitution (numbered part of)", subsys => "block", devpath => "block/sda/sda3", expected => "link1" , conf => < "invalid callout for device with no bus", + desc => "invalid program for device with no bus", subsys => "tty", devpath => "class/tty/console", expected => "TTY" , conf => < "valid callout for device with no bus", + desc => "valid program for device with no bus", subsys => "tty", devpath => "class/tty/console", expected => "foo" , conf => < "class/tty/console", expected => "TTY" , conf => < "class/tty/console", expected => "foo" , conf => < "block/sda", expected => "lun0/disc" , conf => < "block/sda/sda2", expected => "lun0/part2" , conf => < "callout bus type", + desc => "program and bus type match", subsys => "block", devpath => "block/sda", expected => "scsi-0:0:0:0" , conf => < "class/tty/ttyUSB0", expected => "visor0" , conf => < "block/sda/sda2", expected => "1/2/a/b/symlink" , conf => < "block/sda/sda2", expected => "1/2/symlink" , conf => < "block/sda/sda2", expected => "1/2/c/d/symlink" , conf => < "class/tty/ttyUSB0", expected => "second-0" , conf => <{conf} =~ m/([A-Z]+)\s*,/; - my $method = $1; - print "TEST: $config->{desc}\n"; - print "method \'$method\' for \'$config->{devpath}\' expecting node \'$config->{expected}\'\n"; + print "device \'$config->{devpath}\' expecting node \'$config->{expected}\'\n"; udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); if (-e "$PWD/$udev_root$config->{expected}") { diff --git a/udev.h b/udev.h index 656c1b7d8c..678731c7d1 100644 --- a/udev.h +++ b/udev.h @@ -68,7 +68,7 @@ struct udevice { /* fields that help us in building strings */ unsigned char bus_id[SYSFS_NAME_LEN]; - unsigned char callout_value[NAME_SIZE]; + unsigned char program_result[NAME_SIZE]; unsigned char kernel_number[NAME_SIZE]; unsigned char kernel_name[NAME_SIZE]; From 851cd18d81f7bce79947a014f19a6cb97141311d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 12 Jan 2004 23:08:43 -0800 Subject: [PATCH 0397/4284] [PATCH] Add some helpful messages if the user uses the older config file format Also fail a rule that we can not parse, as we can easily create incorrect rules if we do not do this. --- namedev_parse.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 98e822dfef..0712c3b447 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -21,8 +21,10 @@ * */ -/* define this to enable parsing debugging */ +#ifdef DEBUG +/* define this to enable parsing debugging also */ /* #define DEBUG_PARSER */ +#endif #include #include @@ -230,7 +232,9 @@ int namedev_init_rules(void) continue; } - dbg_parse("unknown type of field '%s'", temp2); + dbg("unknown type of field '%s'", temp2); + dbg("You might be using a rules file in the old format, please fix."); + goto error; } /* simple plausibility check for given keys */ @@ -250,7 +254,7 @@ int namedev_init_rules(void) dbg("add_config_dev returned with error %d", retval); continue; error: - dbg("%s:%d:%Zd: parse error, rule skipped", + dbg("%s:%d:%d: parse error, rule skipped", udev_rules_filename, lineno, temp - line); } } From b7824727a07a3d23674cfffbb0a819ed4184ecb2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 12 Jan 2004 23:09:02 -0800 Subject: [PATCH 0398/4284] [PATCH] add bus test for usb-serial bus. --- namedev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/namedev.c b/namedev.c index 41fefc4bc8..80ab96afe5 100644 --- a/namedev.c +++ b/namedev.c @@ -252,6 +252,7 @@ static struct bus_file { } bus_files[] = { { .bus = "scsi", .file = "vendor" }, { .bus = "usb", .file = "idVendor" }, + { .bus = "usb-serial", .file = "detach_state" }, { .bus = "ide", .file = "detach_state" }, { .bus = "pci", .file = "vendor" }, {} From c38b796be9ff453903db7b4813f69323b6422695 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 12 Jan 2004 23:09:20 -0800 Subject: [PATCH 0399/4284] [PATCH] convert the test shell scripts to the config file format. --- test/ignore_test | 2 +- test/label_test | 4 ++-- test/modifier_test | 2 +- test/replace_test | 2 +- test/topo_test | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/ignore_test b/test/ignore_test index 888fd16ff3..602624c1e0 100644 --- a/test/ignore_test +++ b/test/ignore_test @@ -8,7 +8,7 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -IGNORE, KERNEL="ttyUSB0" +KERNEL="ttyUSB0", NAME="" EOF cat > $CONFIG << EOF diff --git a/test/label_test b/test/label_test index cf0d2eb09c..93d02c18f2 100644 --- a/test/label_test +++ b/test/label_test @@ -8,8 +8,8 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_diskX%n" -LABEL, BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_disk%n" +BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_diskX%n" +BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_disk%n" EOF cat > $CONFIG << EOF diff --git a/test/modifier_test b/test/modifier_test index 9af946e598..7ffc7b16a1 100644 --- a/test/modifier_test +++ b/test/modifier_test @@ -8,7 +8,7 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" +BUS="scsi", place="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" EOF cat > $CONFIG << EOF diff --git a/test/replace_test b/test/replace_test index 9ed366e358..10215b0f24 100644 --- a/test/replace_test +++ b/test/replace_test @@ -8,7 +8,7 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -REPLACE, KERNEL="ttyUSB0", NAME="visor" +KERNEL="ttyUSB0", NAME="visor" EOF cat > $CONFIG << EOF diff --git a/test/topo_test b/test/topo_test index 385f415893..18b2549b97 100644 --- a/test/topo_test +++ b/test/topo_test @@ -8,7 +8,7 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -TOPOLOGY, BUS="scsi", place="0:0:0:0", NAME="first_disk%n" +BUS="scsi", place="0:0:0:0", NAME="first_disk%n" EOF cat > $CONFIG << EOF From 71cf391508a0f458971b327260d3d90af629131f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 12 Jan 2004 23:13:10 -0800 Subject: [PATCH 0400/4284] [PATCH] convert the default rules files to the new format. --- etc/udev/udev.rules | 34 +++++++++++----------- etc/udev/udev.rules.devfs | 34 +++++++++++----------- etc/udev/udev.rules.gentoo | 58 +++++++++++++++++++------------------- 3 files changed, 63 insertions(+), 63 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 68c0c63c89..e72751656e 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -14,44 +14,44 @@ # # Looking for scsi bus id 42:0:0:1 -CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" +BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" # A usb camera. -LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" +BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" # USB Epson printer to be called lp_epson -LABEL, BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" +BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -LABEL, BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" +BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card -NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" +BUS="pci", ID="00:0b.0", NAME="dsp" # sound card with PCI bus id 00:07.1 to be the second sound card -NUMBER, BUS="pci", ID="00:07.1", NAME="dsp1" +BUS="pci", ID="00:07.1", NAME="dsp1" # USB mouse plugged into the third port of the first hub to be called mouse0 -TOPOLOGY, BUS="usb", PLACE="1.3", NAME="mouse0" +BUS="usb", PLACE="1.3", NAME="mouse0" # USB tablet plugged into the third port of the second hub to be called mouse1 -TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" -TOPOLOGY, BUS="usb", PLACE="2.4", NAME="mouse2" +BUS="usb", PLACE="2.3", NAME="mouse1" +BUS="usb", PLACE="2.4", NAME="mouse2" # ttyUSB1 should always be called visor -REPLACE, KERNEL="ttyUSB1", NAME="visor" -REPLACE, KERNEL="ttyUSB0", NAME="pl2303" +KERNEL="ttyUSB1", NAME="visor" +KERNEL="ttyUSB0", NAME="pl2303" # a devfs like way to name some tty devices -#REPLACE, KERNEL="ttyS*", NAME="tts/%n" -#REPLACE, KERNEL="tty*", NAME="vc/%n" +#KERNEL="ttyS*", NAME="tts/%n" +#KERNEL="tty*", NAME="vc/%n" # if this is a ide cdrom, name it the default name, and create a symlink to cdrom -CALLOUT, BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", ID="cdrom", NAME="%k", SYMLINK="cdrom" +BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", ID="cdrom", NAME="%k", SYMLINK="cdrom" -# device mapper creates its own device nodes -IGNORE, KERNEL="dm-[0-9]*" +# device mapper creates its own device nodes so ignore these +KERNEL="dm-[0-9]*", NAME="" # DRI devices always go into a subdirectory (as per the LSB spec) -REPLACE, KERNEL="card*", NAME="dri/card%n" +KERNEL="card*", NAME="dri/card%n" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 537d655a0e..b165e0dc8b 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -17,30 +17,30 @@ # # ide block devices -NUMBER, BUS="ide", id="0.0", NAME="ide/host0/bus0/target0/lun0/%D" -NUMBER, BUS="ide", id="0.1", NAME="ide/host0/bus0/target1/lun0/%D" -NUMBER, BUS="ide", id="1.0", NAME="ide/host0/bus1/target0/lun0/%D" -NUMBER, BUS="ide", id="1.1", NAME="ide/host0/bus1/target1/lun0/%D" +BUS="ide", id="0.0", NAME="ide/host0/bus0/target0/lun0/%D" +BUS="ide", id="0.1", NAME="ide/host0/bus0/target1/lun0/%D" +BUS="ide", id="1.0", NAME="ide/host0/bus1/target0/lun0/%D" +BUS="ide", id="1.1", NAME="ide/host0/bus1/target1/lun0/%D" # md block devices -REPLACE, KERNEL="md[0-9]*", NAME="md/%n" +KERNEL="md[0-9]*", NAME="md/%n" # tty devices -REPLACE, KERNEL="tty[0-9]*", NAME="vc/%n" -REPLACE, KERNEL="ttyS[0-9]*", NAME="tts/%n" -REPLACE, KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" +KERNEL="tty[0-9]*", NAME="vc/%n" +KERNEL="ttyS[0-9]*", NAME="tts/%n" +KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" # vc devices -REPLACE, KERNEL="vcs", NAME="vcc/0" -REPLACE, KERNEL="vcs[0-9]*", NAME="vcc/%n" -REPLACE, KERNEL="vcsa", NAME="vcc/a0" -REPLACE, KERNEL="vcsa[0-9]*", NAME="vcc/a%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" # v4l devices -REPLACE, KERNEL="video[0-9]*", NAME="v4l/video%n" -REPLACE, KERNEL="radio[0-9]*", NAME="v4l/radio%n" -REPLACE, KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" -REPLACE, KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +KERNEL="video[0-9]*", NAME="v4l/video%n" +KERNEL="radio[0-9]*", NAME="v4l/radio%n" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" # dm devices -IGNORE, KERNEL="dm-[0-9]*" +KERNEL="dm-[0-9]*", NAME="" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index e752fd0216..51c8bdd99d 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -23,33 +23,33 @@ ########################################################### # Looking for scsi bus id 42:0:0:1 -CALLOUT, BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" +BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" # A usb camera. -LABEL, BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" +BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" # USB Epson printer to be called lp_epson -LABEL, BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" +BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -LABEL, BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" +BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card -NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" +BUS="pci", ID="00:0b.0", NAME="dsp" # sound card with PCI bus id 00:07.1 to be the second sound card -NUMBER, BUS="pci", ID="00:07.1", NAME="dsp1" +BUS="pci", ID="00:07.1", NAME="dsp1" # USB mouse plugged into the third port of the first hub to be called mouse0 -TOPOLOGY, BUS="usb", PLACE="1.3", NAME="mouse0" +BUS="usb", PLACE="1.3", NAME="mouse0" # USB tablet plugged into the third port of the second hub to be called mouse1 -TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" -TOPOLOGY, BUS="usb", PLACE="2.4", NAME="mouse2" +BUS="usb", PLACE="2.3", NAME="mouse1" +BUS="usb", PLACE="2.4", NAME="mouse2" # ttyUSB1 should always be called visor -REPLACE, KERNEL="ttyUSB1", NAME="visor" -REPLACE, KERNEL="ttyUSB0", NAME="pl2303" +KERNEL="ttyUSB1", NAME="visor" +KERNEL="ttyUSB0", NAME="pl2303" ########################################################### @@ -60,38 +60,38 @@ REPLACE, KERNEL="ttyUSB0", NAME="pl2303" # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -CALLOUT, BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c %3c" +BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c %3c" # fb devices -REPLACE, KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" # loop devices -REPLACE, KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" +KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" # md block devices -REPLACE, KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" +KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" # pty devices -REPLACE, KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" -REPLACE, KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" +KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" # ram devices -REPLACE, KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" +KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" # tty devices -REPLACE, KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" -REPLACE, KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" -REPLACE, KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" +KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" +KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" +KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" # vc devices -REPLACE, KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" -REPLACE, KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" -REPLACE, KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" -REPLACE, KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" +KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" +KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" +KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" +KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" # v4l devices -REPLACE, KERNEL="video[0-9]*", NAME="v4l/video%n" -REPLACE, KERNEL="radio[0-9]*", NAME="v4l/radio%n" -REPLACE, KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" -REPLACE, KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +KERNEL="video[0-9]*", NAME="v4l/video%n" +KERNEL="radio[0-9]*", NAME="v4l/radio%n" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" From 1f7148c7df35aea00f96ad52db221c0d561dbc4c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 12 Jan 2004 23:22:13 -0800 Subject: [PATCH 0401/4284] [PATCH] fix a few stale comments in namedev.c --- namedev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 80ab96afe5..4247b26693 100644 --- a/namedev.c +++ b/namedev.c @@ -449,7 +449,7 @@ static int match_id(struct config_device *dev, struct sysfs_class_device *class_ int found; char *temp = NULL; - /* we have to have a sysfs device for NUMBER to work */ + /* we have to have a sysfs device for ID to work */ if (!sysfs_device) return -ENODEV; @@ -480,7 +480,7 @@ static int match_place(struct config_device *dev, struct sysfs_class_device *cla int found; char *temp = NULL; - /* we have to have a sysfs device for NUMBER to work */ + /* we have to have a sysfs device for PLACE to work */ if (!sysfs_device) return -ENODEV; From 86673eb3edb0f23bb83f2d04ed76f0302ea39fa5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 12 Jan 2004 23:22:52 -0800 Subject: [PATCH 0402/4284] [PATCH] Add alsa device rules and a few other devfs rules. Thanks to Libor Klepac for the information --- etc/udev/udev.rules | 8 ++++++++ etc/udev/udev.rules.devfs | 27 ++++++++++++++++++++++++++- etc/udev/udev.rules.gentoo | 24 ++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index e72751656e..12c7c581ec 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -55,3 +55,11 @@ KERNEL="dm-[0-9]*", NAME="" # DRI devices always go into a subdirectory (as per the LSB spec) KERNEL="card*", NAME="dri/card%n" +# 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" + diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index b165e0dc8b..3c45db79cf 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -42,5 +42,30 @@ KERNEL="radio[0-9]*", NAME="v4l/radio%n" KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" -# dm devices +# dm devices (ignore them) KERNEL="dm-[0-9]*", NAME="" + +# i2c devices +KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" + +# loop devices +KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" + +# ramdisks +KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" + +# framebuffer devices +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" + +# misc +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" + +# 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" + diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 51c8bdd99d..a9c5f57bb4 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -95,3 +95,27 @@ KERNEL="radio[0-9]*", NAME="v4l/radio%n" KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +# dm devices (ignore them) +KERNEL="dm-[0-9]*", NAME="" + +# i2c devices +KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" + +# loop devices +KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" + +# framebuffer devices +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" + +# misc devices +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" + +# 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" + From 655f414dde99fefacdd43948f3ca95ab05373e83 Mon Sep 17 00:00:00 2001 From: "elkropac@students.zcu.cz" Date: Mon, 12 Jan 2004 23:29:57 -0800 Subject: [PATCH 0403/4284] [PATCH] fix udev directory for Debian init script there is also patch on debian init.d file, it uses variable $udev_dir also when creating and removing symlinks --- etc/init.d/udev.debian | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/etc/init.d/udev.debian b/etc/init.d/udev.debian index cf7b0070ad..d67941cc13 100644 --- a/etc/init.d/udev.debian +++ b/etc/init.d/udev.debian @@ -72,24 +72,24 @@ case "$1" in run_udev # hack to create stdin node - cd /udev && ln -s /proc/self/fd fd - cd /udev && ln -s fd/0 stdin - cd /udev && ln -s fd/1 stdout - cd /udev && ln -s fd/2 stderr - cd /udev && ln -s /proc/kcore core - cd /udev && ln -s /proc/asound/oss/sndstat sndstat + cd $udev_dir && ln -s /proc/self/fd fd + cd $udev_dir && ln -s fd/0 stdin + cd $udev_dir && ln -s fd/1 stdout + cd $udev_dir && ln -s fd/2 stderr + cd $udev_dir && ln -s /proc/kcore core + cd $udev_dir && ln -s /proc/asound/oss/sndstat sndstat ;; stop) # be careful action "Removing udev device nodes: " /bin/true export ACTION=remove run_udev - rm -f /udev/sndstat - rm -f /udev/core - rm -f /udev/stderr - rm -f /udev/stdout - rm -f /udev/stdin - rm -f /udev/fd + rm -f $udev_dir/sndstat + rm -f $udev_dir/core + rm -f $udev_dir/stderr + rm -f $udev_dir/stdout + rm -f $udev_dir/stdin + rm -f $udev_dir/fd ;; status) if [ -d $udev_dir ]; then From 1eefb969ab96e3a897d0d1344db38ae2956eec31 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 12 Jan 2004 23:45:30 -0800 Subject: [PATCH 0404/4284] [PATCH] oops, forgot to fix up the PROGRAM result from ID to RESULT in the config files. --- etc/udev/udev.rules | 4 ++-- etc/udev/udev.rules.gentoo | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 12c7c581ec..6cb4896743 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -14,7 +14,7 @@ # # Looking for scsi bus id 42:0:0:1 -BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" +BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" # A usb camera. BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" @@ -47,7 +47,7 @@ KERNEL="ttyUSB0", NAME="pl2303" #KERNEL="tty*", NAME="vc/%n" # if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", ID="cdrom", NAME="%k", SYMLINK="cdrom" +BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" # device mapper creates its own device nodes so ignore these KERNEL="dm-[0-9]*", NAME="" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index a9c5f57bb4..4a3292853f 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -23,7 +23,7 @@ ########################################################### # Looking for scsi bus id 42:0:0:1 -BUS="scsi", PROGRAM="/bin/echo -n test-%b", ID="test-42:0:0:1", NAME="%c" +BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" # A usb camera. BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" @@ -60,7 +60,7 @@ KERNEL="ttyUSB0", NAME="pl2303" # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c %3c" +BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c" # fb devices KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" From a2505f4d1da4793991a4d2b2dc8f93b9b89d9672 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Jan 2004 00:51:44 -0800 Subject: [PATCH 0405/4284] [PATCH] udev - simple debug tweak change the empty debug string: Jan 13 00:55:42 pim udev[2849]: namedev_name_device: found matching rule, 'video*' becomes '' to something useful: Jan 13 01:00:23 pim udev[3234]: namedev_name_device: found matching rule, 'video*' becomes 'video/webcam%n' --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 4247b26693..fdc6252bf6 100644 --- a/namedev.c +++ b/namedev.c @@ -716,7 +716,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } /* Yup, this rule belongs to us! */ - dbg("found matching rule, '%s' becomes '%s'", dev->kernel, udev->name); + dbg("found matching rule, '%s' becomes '%s'", dev->kernel, dev->name); strfieldcpy(udev->name, dev->name); strfieldcpy(udev->symlink, dev->symlink); goto found; From ee1db00d07ed1db55061ba5e2cb54800cc3e2495 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Jan 2004 01:01:19 -0800 Subject: [PATCH 0406/4284] [PATCH] more advanced user query options Here is the '-h' and a '-d' to dump the whole database: kay@pim:~/src/udev.kay$ ./udev -d P: /block/hdb/hdb1 N: hdb1 S: O: G: P: /class/video4linux/video0 N: video/webcam0 S: camera0 kamera0 O: 500 G: 500 P: /block/hdc N: hdc S: O: G: --- udev.c | 39 ++++++++++++++++++++++++++++++++------- udevdb.c | 27 +++++++++++++++++++++++++-- udevdb.h | 1 + 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/udev.c b/udev.c index 7078f089e2..84950c82a3 100644 --- a/udev.c +++ b/udev.c @@ -82,6 +82,16 @@ static inline char *get_seqnum(void) return seqnum; } +static void print_record(char *path, struct udevice *dev) +{ + printf("P: %s\n", path); + printf("N: %s\n", dev->name); + printf("S: %s\n", dev->symlink); + printf("O: %s\n", dev->owner); + printf("G: %s\n", dev->group); + printf("\n"); +} + enum query_type { NONE, NAME, @@ -92,7 +102,7 @@ enum query_type { static inline int udev_user(int argc, char **argv) { - static const char short_options[] = "p:q:rVh"; + static const char short_options[] = "dp:q:rVh"; int option; int retval = -EINVAL; struct udevice dev; @@ -144,6 +154,16 @@ static inline int udev_user(int argc, char **argv) root = 1; break; + case 'd': + retval = udevdb_open_ro(); + if (retval != 0) { + printf("unable to open udev database\n"); + return -EACCES; + } + retval = udevdb_dump(print_record); + udevdb_exit(); + return retval; + case 'V': printf("udev, version %s\n", UDEV_VERSION); return 0; @@ -206,12 +226,17 @@ static inline int udev_user(int argc, char **argv) } help: - printf("Usage: [-qrVh]\n" - " -q query database for the specified value\n" - " -p device path used for query\n" - " -r print udev root\n" - " -V print udev version\n" - " -h print this help text\n" + printf("Usage: [-pqrdVh]\n" + " -q TYPE query database for the specified value:\n" + " 'name' name of device node\n" + " 'symlink' pointing to node\n" + " 'owner' of node\n" + " 'group' of node\n" + " -p PATH sysfs device path used for query\n" + " -r print udev root\n" + " -d dump whole database\n" + " -V print udev version\n" + " -h print this help text\n" "\n"); return retval; } diff --git a/udevdb.c b/udevdb.c index ca9e63c97e..8d077ea94f 100644 --- a/udevdb.c +++ b/udevdb.c @@ -124,7 +124,7 @@ int udevdb_init(int init_flag) dbg("unable to initialize in-memory database"); else dbg("unable to initialize database at '%s'", udev_db_filename); - return -EINVAL; + return -EACCES; } return 0; } @@ -137,7 +137,30 @@ int udevdb_open_ro(void) udevdb = tdb_open(udev_db_filename, 0, 0, O_RDONLY, 0); if (udevdb == NULL) { dbg("unable to open database at '%s'", udev_db_filename); - return -EINVAL; + return -EACCES; } return 0; } + +void (*user_record_callback) (char *path, struct udevice *dev); + +static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +{ + user_record_callback((char*) key.dptr, (struct udevice*) dbuf.dptr); + return 0; +} + +/** + * udevdb_dump: dumps whole database by passing record data to user function + * @user_record_handler: user function called for every record in the database + */ +int udevdb_dump(void (*user_record_handler) (char *path, struct udevice *dev)) +{ + if (user_record_handler == NULL) { + dbg("invalid user record handling function"); + return -EINVAL; + } + user_record_callback = user_record_handler; + tdb_traverse(udevdb, traverse_callback, NULL); + return 0; +} diff --git a/udevdb.h b/udevdb.h index f36a9ca799..a0e5338265 100644 --- a/udevdb.h +++ b/udevdb.h @@ -12,6 +12,7 @@ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); extern int udevdb_open_ro(void); +extern int udevdb_dump(void (*user_record_handler) (char *path, struct udevice *dev)); extern int udevdb_add_dev(const char *path, const struct udevice *dev); extern int udevdb_get_dev(const char *path, struct udevice *dev); From 79c3cb65f8a2c17502258aaed36704780470f257 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Jan 2004 01:02:56 -0800 Subject: [PATCH 0407/4284] [PATCH] Fix stupid gcc "optimization" of 1 character printk() calls.... Ick... --- udev.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/udev.c b/udev.c index 84950c82a3..a51c04399e 100644 --- a/udev.c +++ b/udev.c @@ -88,8 +88,7 @@ static void print_record(char *path, struct udevice *dev) printf("N: %s\n", dev->name); printf("S: %s\n", dev->symlink); printf("O: %s\n", dev->owner); - printf("G: %s\n", dev->group); - printf("\n"); + printf("G: %s\n\n", dev->group); } enum query_type { From 4bd46ac7e5ea893989c3bb83b07c26e852380cac Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Jan 2004 01:35:55 -0800 Subject: [PATCH 0408/4284] [PATCH] update documentation for new config file format Here is the man page update after my udev-weekend :) --- udev.8 | 115 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 57 insertions(+), 58 deletions(-) diff --git a/udev.8 b/udev.8 index 3eb4aecad2..fdf5eae73d 100644 --- a/udev.8 +++ b/udev.8 @@ -5,7 +5,7 @@ udev \- Linux configurable dynamic device naming support .BI udev " hotplug-subsystem" .br .B udev -.RI "[-q " sysfs_path "] [-rVh]" +.RI "[-q " query_type " -p " sysfs_path "] [-drVh]" .SH "DESCRIPTION" .B udev creates or removes device node files usually located in the /dev directory. @@ -21,14 +21,14 @@ On device creation, .B udev reads the sysfs directory of the given device to collect device attributes like label, serial number or bus device number. -These attributes are treated as a key -to determine a unique name for device file creation. +These attributes may used as keys to determine a +unique name for device file creation. .B udev maintains a database for devices present on the system. .br On device removal, .B udev -queries the internal database for the name of the device file to be deleted. +queries its database for the name of the device file to be deleted. .SH "OPTIONS" .B udev normally is called by @@ -42,11 +42,21 @@ Print the version information. .TP .B -r Print the the -.B udev -root directory. +.B udev_root +directory. When used in conjunction with a query for the node name, the +.B udev_root +will be prepended. .TP -.BI -q " sysfs_path" -Query with the sysfs path as argument for the name of the created device node. +.BI -q " query_type" +Query the database for specified value of a created device node. +Valid types are: +.BR name ", " symlink ", " owner " or " group . +.TP +.BI -p " sysfs_path" +Specify the sysfs path needed for the query. +.TP +.B -q +Dump the whole database. .TP .B -h Print help text. @@ -115,61 +125,50 @@ value in the .I /etc/udev/udev.conf file. .P -Every line in the rules file define the mapping between device attributes and -the device file name. It starts with a keyword defining the method used to -match, followed by one ore more keys to compare and the filename for the -device. One ore more optional symlinks targeting the node may be specified. +Every line in the rules file defines the mapping between device attributes +and the device file name. One ore more keys are specified to match a rule +with the current device. If all keys are matching, the rule will be applied +and the name is used for the device node. One or more optional symlinks +targeting the node may be specified. .br -If no matching configuration is found, the default kernel device name -is used. +If no matching rule is found, the default kernel device name is used. .P The line format is: .sp -.I method, key,[key,...] name [, symlink] +.I key,[key,...] name [, symlink] .sp -where valid methods with corresponding keys are: +where keys are: .TP -.B CALLOUT -calling external program, that returns a string to match. The .B BUS -key is optional, but if specified, the sysfs device bus must be able to be -determined by a "device" symlink. -.br -.RB "keys: " BUS ", " PROGRAM ", " ID +Match the bus type of the device. +(The sysfs device bus must be able to be determined by a "device" symlink.) .TP -.B LABEL -device label or serial number, like USB serial number, SCSI UUID or -file system label. Up to 5 different sysfs files can be checked, with -all of the values being required in order to match the rule. The -.B BUS -key is optional, but if specified, the sysfs device bus must be able to be -detemined by a "device" symlink. -.br -.RB "keys: " BUS ", " SYSFS_ +.B KERNEL +Match the kernel device name. .TP -.B NUMBER -device number on the bus, like PCI bus id -.br -.RB "keys: " BUS ", " ID +.B ID +Match the device number on the bus, like PCI bus id. .TP -.B TOPOLOGY -device position on bus, like physical port of USB device -.br -.RB "keys: " BUS ", " PLACE +.B PLACE +Match the topological position on bus, like physical port of USB device .TP -.B REPLACE -string replacement of the kernel device name -.br -.RB "key: " KERNEL +.BI SYSFS_ filename +Match sysfs device attribute like label, vendor, USB serial number, SCSI UUID +or file system label. Up to 5 different sysfs files can be checked, with +all of the values being required in order to match the rule. .TP -.B IGNORE -tell udev to not care about creation of this device, e.g. because the -device is already handled by another program -.br -.RB "key: " KERNEL -.P -The methods are applied in the following order: -.BR IGNORE ", " CALLOUT ", " LABEL ", " NUMBER ", " TOPOLOGY ", " REPLACE "." +.B PROGRAM +Call external program. This key is valid if the program returns successful. +The string returned by the program may additionally matched with the +.B RESULT +key. +.TP +.B RESULT +Match the returned string of the last +.B PROGRAM +call. This key may used in any following rule after a +.B PROGRAM +call. .P .RB "The " NAME " ," SYMLINK " and " PROGRAM fields support simple printf-like string substitution: @@ -203,25 +202,25 @@ If this is not a partition, it will result in 'disc'. .sp .nf # if /sbin/scsi_id returns "OEM 0815" device will be called disk1 -CALLOUT, BUS="scsi", PROGRAM="/sbin/scsi_id", ID="OEM 0815", NAME="disk1" +BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="OEM 0815", NAME="disk1" # USB printer to be called lp_color -LABEL, BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_color" +BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_color" # SCSI disk with a specific vendor and model number is to be called boot -LABEL, BUS="scsi", SYSFS_vendor="IBM", SYSFS_model="ST336", NAME="boot%n" +BUS="scsi", SYSFS_vendor="IBM", SYSFS_model="ST336", NAME="boot%n" # sound card with PCI bus id 00:0b.0 to be called dsp -NUMBER, BUS="pci", ID="00:0b.0", NAME="dsp" +BUS="pci", ID="00:0b.0", NAME="dsp" # USB mouse at third port of the second hub to be called mouse1 -TOPOLOGY, BUS="usb", PLACE="2.3", NAME="mouse1" +BUS="usb", PLACE="2.3", NAME="mouse1" # ttyUSB1 should always be called pda with two additional symlinks -REPLACE, KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" +KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" # multiple USB webcams with symlinks to be called webcam0, webcam1, ... -LABEL, BUS="usb", SYSFS_model="XV3", NAME="video%n", SYMLINK="webcam%n" +BUS="usb", SYSFS_model="XV3", NAME="video%n", SYMLINK="webcam%n" .fi .P Permissions and ownership for the created device files may specified at From 2ebcaa235fe2b82a844ae19daecb0c996375fc1b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Jan 2004 01:36:56 -0800 Subject: [PATCH 0409/4284] [PATCH] fix -d typo in the manpage update --- udev.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.8 b/udev.8 index fdf5eae73d..6ee68d795e 100644 --- a/udev.8 +++ b/udev.8 @@ -55,7 +55,7 @@ Valid types are: .BI -p " sysfs_path" Specify the sysfs path needed for the query. .TP -.B -q +.B -d Dump the whole database. .TP .B -h From 9ab314222d66d53a46ecefdeb37bec15b7dff66a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Jan 2004 01:49:45 -0800 Subject: [PATCH 0410/4284] [PATCH] update the README in a few places. --- README | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/README b/README index dab0ab4197..123fce6a1b 100644 --- a/README +++ b/README @@ -8,6 +8,8 @@ To use: - You must be running a 2.6 version of the Linux kernel. +- Your 2.6 kernel must have had CONFIG_HOTPLUG enabled when it was built. + - Make sure sysfs is mounted. udev will figure out where sysfs is mounted, but the traditional place for it is at /sys. You can mount it by hand by running: mount -t sysfs none /sys @@ -45,6 +47,9 @@ To use: would do: make USE_KLIBC=true DEBUG=true + Note: If you want to use klibc, you will have to set up the "linux" + symlink properly. See the file klibc/klibc/README and pay + attention to step "a)" there. - Install the project: make install @@ -62,18 +67,18 @@ To use: make uninstall -Things are still quite rough, and it's a bit beyond proof of concept -code. Help is very much appreciated, see the TODO file for a list of -things left to be done. +Things are still quite rough, but it should work properly. If nothing +seems to happen, make sure your build worked properly by running the +udev-test.pl script as root in the test/ subdirectory of the udev source +tree. -If you want to build using klibc, use the Makefile.klibc file: - - read the klibc/klibc/README file for how to set up the linux - symlink properly. - - make clean - - make -f Makefile.klibc -and marvel at the tiny binary you just created :) +Development and documentation help is very much appreciated, see the TODO +file for a list of things left to be done. -Any comment/questions/concerns please let me know. + +Any comment/questions/concerns please let me and the other udev developers +know by sending a message to the linux-hotplug-devel mailing list at: + linux-hotplug-devel@lists.sourceforge.net greg k-h greg@kroah.com From 7e5f7397f9dbbf2be421d639494576a5c8167241 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Jan 2004 18:31:18 -0800 Subject: [PATCH 0411/4284] [PATCH] udev - CALLOUT is PROGRAM now replace CALLOUT by PROGRAM and fix old rule format --- etc/udev/udev.rules | 2 +- etc/udev/udev.rules.devfs | 2 +- etc/udev/udev.rules.gentoo | 2 +- extras/ide-devfs.sh | 4 ++-- extras/name_cdrom.pl | 4 ++-- namedev.c | 4 ++-- namedev.h | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 6cb4896743..a2279976fe 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -6,7 +6,7 @@ # %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 return value for the CALLOUT program (note, this doesn't work within +# %c - the return value of the external PROGRAM (note, this doesn't work within # the PROGRAM field for the obvious reason.) # %D - use the devfs style disk name for this device. # For partitions, this will result in 'part%n' diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 3c45db79cf..bc3f26c1cc 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -9,7 +9,7 @@ # %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 return value for the CALLOUT program (note, this doesn't work within +# %c - the return value of the external PROGRAM (note, this doesn't work within # the PROGRAM field for the obvious reason.) # %D - use the devfs style disk name for this device. # For partitions, this will result in 'part%n' diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 4a3292853f..a449a4dac9 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -9,7 +9,7 @@ # %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 return value for the CALLOUT program (note, this doesn't work within +# %c - the return value of the external PROGRAM (note, this doesn't work within # the PROGRAM field for the obvious reason.) # %D - use the devfs style disk name for this device. # For partitions, this will result in 'part%n' diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 57fb00b676..ab194b01e6 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -1,8 +1,8 @@ #!/bin/sh -# udev CALLOUT script +# udev external PROGRAM script # return devfs-names for ide-devices -# CALLOUT, BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", ID="hd*", NAME="%1c", SYMLINK="%2c %3c" +# BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c" HOST="${2%\.[0-9]}" TARGET="${2#[0-9]\.}" diff --git a/extras/name_cdrom.pl b/extras/name_cdrom.pl index 7a14e866a6..e522c9fda8 100644 --- a/extras/name_cdrom.pl +++ b/extras/name_cdrom.pl @@ -2,8 +2,8 @@ # a horribly funny script that shows how flexible udev can really be # This is to be executed by udev with the following rules: -# CALLOUT, BUS="ide", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%2c", SYMLINK="cdrom" -# CALLOUT, BUS="scsi", PROGRAM="name_cdrom.pl %M %m", ID="good*", NAME="%2c", SYMLINK="cdrom" +# BUS="ide", PROGRAM="name_cdrom.pl %M %m", PROGRAM="good*", NAME="%2c", SYMLINK="cdrom" +# BUS="scsi", PROGRAM="name_cdrom.pl %M %m", PROGRAM="good*", NAME="%2c", SYMLINK="cdrom" # # The scsi rule catches USB cdroms and ide-scsi devices. # diff --git a/namedev.c b/namedev.c index fdc6252bf6..6f7bfb6805 100644 --- a/namedev.c +++ b/namedev.c @@ -309,7 +309,7 @@ static int execute_program(char *path, char *value, int len) int value_set = 0; char buffer[256]; char *pos; - char *args[CALLOUT_MAXARG]; + char *args[PROGRAM_MAXARG]; int i; dbg("executing '%s'", path); @@ -331,7 +331,7 @@ static int execute_program(char *path, char *value, int len) if (strchr(path, ' ')) { /* exec with arguments */ pos = path; - for (i=0; i < CALLOUT_MAXARG-1; i++) { + for (i=0; i < PROGRAM_MAXARG-1; i++) { args[i] = strsep(&pos, " "); if (args[i] == NULL) break; diff --git a/namedev.h b/namedev.h index 4e75db6410..f5b63a8805 100644 --- a/namedev.h +++ b/namedev.h @@ -45,7 +45,7 @@ struct sysfs_class_device; #define FIELD_NAME "NAME" #define FIELD_SYMLINK "SYMLINK" -#define CALLOUT_MAXARG 10 +#define PROGRAM_MAXARG 10 #define MAX_SYSFS_PAIRS 5 struct sysfs_pair { From e68faf511dd9be15a27042d1828460d3655707d8 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Jan 2004 18:31:20 -0800 Subject: [PATCH 0412/4284] [PATCH] udev - more CALLOUT is PROGRAM now On Tue, Jan 13, 2004 at 02:45:17AM +0100, Kay Sievers wrote: > replace CALLOUT by PROGRAM and fix old rule format One is missing. --- udev.8 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/udev.8 b/udev.8 index 6ee68d795e..c78fd4a32b 100644 --- a/udev.8 +++ b/udev.8 @@ -190,8 +190,12 @@ The kernel minor number for the device. The bus id for the device. .TP .B %c -The CALLOUT program returned string. -(This does not work within the PROGRAM field for the obvious reason.) +The +.B PROGRAM +returned string. +(This does not work within the +.B PROGRAM +field for the obvious reason.) .TP .B %D Use the devfs style disk name for this device. From 8ffb636f013a193688b132b8512e77b0747c41a1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Jan 2004 18:34:33 -0800 Subject: [PATCH 0413/4284] [PATCH] udev - introduce format escape char This patch adds a '%' to the format char list, so that a external program may called with a non expanded '%' like: PROGRAM="/bin/date +%%s" Olaf Hering asked for the feature. A tricky test is also added :) --- namedev.c | 19 ++++++++++++------- test/udev-test.pl | 9 +++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/namedev.c b/namedev.c index 6f7bfb6805..0e1af9385f 100644 --- a/namedev.c +++ b/namedev.c @@ -151,20 +151,21 @@ static mode_t get_default_mode(struct sysfs_class_device *class_dev) static void apply_format(struct udevice *udev, unsigned char *string) { - char name[NAME_SIZE]; char temp[NAME_SIZE]; + char temp1[NAME_SIZE]; char *tail; char *pos; char *pos2; char *pos3; int num; + pos = string; while (1) { num = 0; - pos = strchr(string, '%'); + pos = strchr(pos, '%'); if (pos) { - *pos = '\0'; + pos[0] = '\0'; tail = pos+1; if (isdigit(tail[0])) { num = (int) strtoul(&pos[1], &tail, 10); @@ -173,7 +174,7 @@ static void apply_format(struct udevice *udev, unsigned char *string) break; } } - strfieldcpy(name, tail+1); + strfieldcpy(temp, tail+1); switch (tail[0]) { case 'b': @@ -217,8 +218,8 @@ static void apply_format(struct udevice *udev, unsigned char *string) break; if (num) { /* get part of return string */ - strncpy(temp, udev->program_result, sizeof(temp)); - pos2 = temp; + strncpy(temp1, udev->program_result, sizeof(temp1)); + pos2 = temp1; while (num) { num--; pos3 = strsep(&pos2, " "); @@ -236,11 +237,15 @@ static void apply_format(struct udevice *udev, unsigned char *string) dbg("substitute result string '%s'", udev->program_result); } break; + case '%': + strcat(pos, "%"); + pos++; + break; default: dbg("unknown substitution type '%%%c'", pos[1]); break; } - strcat(string, name); + strcat(string, temp); } else break; } diff --git a/test/udev-test.pl b/test/udev-test.pl index ab27c74c6a..5e5756b660 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -203,6 +203,15 @@ EOF expected => "test-0:0:0:0" , conf => < "program with escaped format char (tricky: callout returns format char!)", + subsys => "block", + devpath => "block/sda/sda3", + expected => "escape-3" , + conf => < Date: Tue, 13 Jan 2004 18:34:38 -0800 Subject: [PATCH 0414/4284] [PATCH] udev - small script optimization Optimize the scripts reflecting the now more powerful rule logic, cause we can combine all known fields now in any order: The ide-devfs.sh is only executed if the kernel name matches with 'hd*': BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%1c %2c" The name_cdrom.pl is only executed for ide and scsi devices, but not for a partition. It exits with nonzero to skip the rule if the CD is not found: KERNEL="[hs]d[a-z]", PROGRAM="name_cdrom.pl %M %m", NAME="%1c", SYMLINK="cdrom" --- extras/ide-devfs.sh | 8 ++++---- extras/name_cdrom.pl | 28 +++++++++++++--------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index ab194b01e6..8648f6c0c0 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -2,7 +2,7 @@ # udev external PROGRAM script # return devfs-names for ide-devices -# BUS="ide", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c" +# BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%1c %2c" HOST="${2%\.[0-9]}" TARGET="${2#[0-9]\.}" @@ -38,10 +38,10 @@ get_dev_number() { if [ -z "$3" ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then - echo $1 ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` elif [ "${MEDIA}" = "disk" ]; then - echo $1 ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc fi else - echo $1 ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/part$3 discs/disc`get_dev_number $1 disk`/part$3 + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/part$3 discs/disc`get_dev_number $1 disk`/part$3 fi diff --git a/extras/name_cdrom.pl b/extras/name_cdrom.pl index e522c9fda8..3a4772e6d9 100644 --- a/extras/name_cdrom.pl +++ b/extras/name_cdrom.pl @@ -2,19 +2,17 @@ # a horribly funny script that shows how flexible udev can really be # This is to be executed by udev with the following rules: -# BUS="ide", PROGRAM="name_cdrom.pl %M %m", PROGRAM="good*", NAME="%2c", SYMLINK="cdrom" -# BUS="scsi", PROGRAM="name_cdrom.pl %M %m", PROGRAM="good*", NAME="%2c", SYMLINK="cdrom" -# -# The scsi rule catches USB cdroms and ide-scsi devices. -# +# KERNEL="[hs]d[a-z]", PROGRAM="name_cdrom.pl %M %m", NAME="%1c", SYMLINK="cdrom" + +use strict; +use warnings; use CDDB_get qw( get_cddb ); -my %config; - -$dev_node = "/tmp/cd_foo"; +my $dev_node = "/tmp/cd_foo"; # following variables just need to be declared if different from defaults +my %config; $config{CDDB_HOST}="freedb.freedb.org"; # set cddb host $config{CDDB_PORT}=8880; # set cddb port $config{CDDB_MODE}="cddb"; # set cddb mode: cddb or http @@ -23,8 +21,8 @@ $config{CD_DEVICE}="$dev_node"; # set cd device # No user interaction, this is a automated script! $config{input}=0; -$major = $ARGV[0]; -$minor = $ARGV[1]; +my $major = $ARGV[0]; +my $minor = $ARGV[1]; # create our temp device node to read the cd info from unlink($dev_node); @@ -38,11 +36,11 @@ my %cd=get_cddb(\%config); # remove the dev node we just created unlink($dev_node); -# print out our cd name if we have found it -unless(defined $cd{title}) { - print"bad unknown cdrom\n"; -} else { +# print out our cd name if we have found it or skip rule by nonzero exit +if (defined $cd{title}) { $cd{artist} =~ s/ /_/g; $cd{title} =~ s/ /_/g; - print "good $cd{artist}-$cd{title}\n"; + print "$cd{artist}-$cd{title}\n"; +} else { + exit -1; } From c03e2c6f5f385c6782416cfade63661374a22c5f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Jan 2004 18:47:17 -0800 Subject: [PATCH 0415/4284] [PATCH] Cset exclude: greg@kroah.com|ChangeSet|20040113010256|48515 --- udev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udev.c b/udev.c index a51c04399e..84950c82a3 100644 --- a/udev.c +++ b/udev.c @@ -88,7 +88,8 @@ static void print_record(char *path, struct udevice *dev) printf("N: %s\n", dev->name); printf("S: %s\n", dev->symlink); printf("O: %s\n", dev->owner); - printf("G: %s\n\n", dev->group); + printf("G: %s\n", dev->group); + printf("\n"); } enum query_type { From 68e07a2b0798bd22554c82496455100f29cf6140 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Jan 2004 18:48:33 -0800 Subject: [PATCH 0416/4284] [PATCH] fix klibc with printf() and gcc On Mon, Jan 12, 2004 at 05:04:45PM -0800, Greg KH wrote: > Very nice, applied. But I did have to make one small change to get the > code to build properly with klibc: > > > +static void print_record(char *path, struct udevice *dev) > > +{ > > + printf("P: %s\n", path); > > + printf("N: %s\n", dev->name); > > + printf("S: %s\n", dev->symlink); > > + printf("O: %s\n", dev->owner); > > + printf("G: %s\n", dev->group); > > + printf("\n"); > > +} > > Turns out that gcc likes to convert single character printf() calls to > putchar() which is only defined in klibc as a macro :( Just for information. This seems to fix the gcc with klibc :) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5e64129266..a921a22bb9 100644 --- a/Makefile +++ b/Makefile @@ -133,7 +133,7 @@ ifeq ($(strip $(USE_KLIBC)),true) LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(KLIBC_DIR)/arch/$(ARCH)/include \ -I$(INCLUDE_DIR)/bits$(BITSIZE) -I$(GCCINCDIR) -I$(LINUX_INCLUDE_DIR) \ - -D__KLIBC__ + -D__KLIBC__ -fno-builtin-printf LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs else From 542bd1c0150453c94f3cc179e3aa891581a5004a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Jan 2004 22:55:21 -0800 Subject: [PATCH 0417/4284] [PATCH] update TODO with some new, small items. --- TODO | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/TODO b/TODO index d0d0bec4d9..702d0d6b27 100644 --- a/TODO +++ b/TODO @@ -9,6 +9,11 @@ greg@kroah.com - more documentation (can never have too much.) - better partition support (it's a hack right now, maybe new libsysfs changes can help out a lot here.) +- option to always add all partitions. This is needed to properly handle + devices with removable media. +- install the proper init.d script based on the distro we are running on. +- persuade the distro packagers to submit their changes (or just steal them + if we can find them...) - allow database to be queried by other programs - split program into two pieces (daemon and helper that sends events to it). This will allow us to keep track of sequences, and lots of other needed From c58ffe501caa2757437aa13ab1d84db1033eb065 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Jan 2004 22:59:11 -0800 Subject: [PATCH 0418/4284] [PATCH] v013 release --- ChangeLog | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f626070268..4affadaf53 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +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 ============================================ diff --git a/Makefile b/Makefile index a921a22bb9..eba9766938 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 012_bk +VERSION = 013 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 4056025df8..f76ccaa134 100644 --- a/udev.spec +++ b/udev.spec @@ -23,7 +23,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 012_bk +Version: 013 Release: 1 License: GPL Group: Utilities/System From 78812b99d371f362bb0e0eb1c111a8a7adffe48f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 14 Jan 2004 18:16:32 -0800 Subject: [PATCH 0419/4284] [PATCH] 013_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index eba9766938..80c4908ccb 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ USE_DBUS = false ROOT = udev -VERSION = 013 +VERSION = 013_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index f76ccaa134..07331807ef 100644 --- a/udev.spec +++ b/udev.spec @@ -23,7 +23,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 013 +Version: 013_bk Release: 1 License: GPL Group: Utilities/System From b6864b4bf1945d6b950a77e96fd68e9952bbeb02 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 14 Jan 2004 18:18:12 -0800 Subject: [PATCH 0420/4284] [PATCH] udev - mention format string escape char in man page If we want to pass any '%' down to a program, you need to ecape it by '%%', otherwise we try to expand it with our own format char list. --- udev.8 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/udev.8 b/udev.8 index c78fd4a32b..1ca42982ea 100644 --- a/udev.8 +++ b/udev.8 @@ -201,6 +201,9 @@ field for the obvious reason.) Use the devfs style disk name for this device. For partitions, this will result in 'part%n' If this is not a partition, it will result in 'disc'. +.TP +.B %% +The '%' char itself. .P .RI "A sample " udev.rules " might look like this:" .sp From 1782087e4f80fd1d8c4d8bd9a6edeed27414426e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 14 Jan 2004 21:38:36 -0800 Subject: [PATCH 0421/4284] [PATCH] added input device rules to udev.rules and udev.rules.devfs --- etc/udev/udev.rules | 8 ++++++++ etc/udev/udev.rules.devfs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index a2279976fe..1f3ef07242 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -63,3 +63,11 @@ 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="keyboard", NAME="input/%k" +KERNEL="mouse*", NAME="input/%k" +KERNEL="event*", NAME="input/%k" +KERNEL="js*", NAME="input/%k" +KERNEL="ts*", NAME="input/%k" + diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index bc3f26c1cc..026e9465b1 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -69,3 +69,11 @@ 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="keyboard", NAME="input/%k" +KERNEL="mouse*", NAME="input/%k" +KERNEL="event*", NAME="input/%k" +KERNEL="js*", NAME="input/%k" +KERNEL="ts*", NAME="input/%k" + From 616a7078071362b32a4db73fe3314feb46438258 Mon Sep 17 00:00:00 2001 From: "ananthmg@rediffmail.com" Date: Wed, 14 Jan 2004 22:21:38 -0800 Subject: [PATCH 0422/4284] [PATCH] libsysfs update for refresh + namedev.c changes Please find inlined a patch which contains updates to libsysfs (pre-release) for refresh and also changes to namedev.c to take advantage of it. --- libsysfs/libsysfs.h | 36 +++++-- libsysfs/sysfs_bus.c | 49 ++++++--- libsysfs/sysfs_class.c | 201 ++++++++++++++++++++++------------- libsysfs/sysfs_device.c | 72 ++++++++----- libsysfs/sysfs_dir.c | 227 ++++++++++++++++++++++++++++++---------- libsysfs/sysfs_driver.c | 86 +++++++++++---- libsysfs/sysfs_utils.c | 144 ++++++++++++++++--------- namedev.c | 105 ++++++++----------- 8 files changed, 611 insertions(+), 309 deletions(-) diff --git a/libsysfs/libsysfs.h b/libsysfs/libsysfs.h index 2ffe1005cc..10faab92aa 100644 --- a/libsysfs/libsysfs.h +++ b/libsysfs/libsysfs.h @@ -62,18 +62,20 @@ struct sysfs_link { }; struct sysfs_directory { + unsigned char name[SYSFS_NAME_LEN]; + unsigned char path[SYSFS_PATH_MAX]; + + /* Private: for internal use only */ struct dlist *subdirs; struct dlist *links; struct dlist *attributes; - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; }; struct sysfs_driver { unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct dlist *devices; struct sysfs_directory *directory; }; @@ -85,7 +87,7 @@ struct sysfs_device { unsigned char driver_name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct sysfs_device *parent; struct dlist *children; struct sysfs_directory *directory; @@ -95,7 +97,7 @@ struct sysfs_root_device { unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct dlist *devices; struct sysfs_directory *directory; }; @@ -104,7 +106,7 @@ struct sysfs_bus { unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; - /* internal use only */ + /* Private: for internal use only */ struct dlist *drivers; struct dlist *devices; struct sysfs_directory *directory; @@ -115,7 +117,7 @@ struct sysfs_class_device { unsigned char classname[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct sysfs_class_device *parent; struct sysfs_device *sysdevice; /* NULL if virtual */ struct sysfs_driver *driver; /* NULL if not implemented */ @@ -126,7 +128,7 @@ struct sysfs_class { unsigned char name[SYSFS_NAME_LEN]; unsigned char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct dlist *devices; struct sysfs_directory *directory; }; @@ -138,8 +140,8 @@ extern "C" { /* * Function Prototypes */ -extern int sysfs_trailing_slash(unsigned char *path); extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); +extern int sysfs_remove_trailing_slash(unsigned char *path); extern int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, size_t len); extern int sysfs_path_is_dir(const unsigned char *path); @@ -161,7 +163,9 @@ extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, const unsigned char *new_value, size_t len); extern unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, const unsigned char * name); -extern int sysfs_refresh_attributes(struct dlist *attrlist); +extern int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir); +extern int sysfs_refresh_dir_links(struct sysfs_directory *sysdir); +extern int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir); extern void sysfs_close_directory(struct sysfs_directory *sysdir); extern struct sysfs_directory *sysfs_open_directory(const unsigned char *path); extern int sysfs_read_dir_attributes(struct sysfs_directory *sysdir); @@ -179,6 +183,9 @@ extern struct sysfs_link *sysfs_get_subdirectory_link (struct sysfs_directory *dir, unsigned char *linkname); extern struct sysfs_attribute *sysfs_get_directory_attribute (struct sysfs_directory *dir, unsigned char *attrname); +extern struct dlist *sysfs_get_dir_attributes(struct sysfs_directory *dir); +extern struct dlist *sysfs_get_dir_links(struct sysfs_directory *dir); +extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir); /* sysfs driver access */ extern void sysfs_close_driver(struct sysfs_driver *driver); @@ -189,9 +196,12 @@ extern struct sysfs_attribute *sysfs_get_driver_attr (struct sysfs_driver *drv, const unsigned char *name); extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); +extern struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver); extern struct sysfs_device *sysfs_get_driver_device (struct sysfs_driver *driver, const unsigned char *name); +extern struct dlist *sysfs_refresh_driver_attributes + (struct sysfs_driver *driver); extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, const unsigned char *drv, const unsigned char *attrib); @@ -205,9 +215,12 @@ extern struct sysfs_device *sysfs_open_device (const unsigned char *bus_id, const unsigned char *bus); extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev); extern struct sysfs_device *sysfs_open_device_path(const unsigned char *path); +extern int sysfs_get_device_bus(struct sysfs_device *dev); extern struct sysfs_attribute *sysfs_get_device_attr (struct sysfs_device *dev, const unsigned char *name); extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); +extern struct dlist *sysfs_refresh_device_attributes + (struct sysfs_device *device); extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, const unsigned char *bus_id, const unsigned char *attrib); @@ -221,6 +234,7 @@ extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus); +extern struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus); extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, unsigned char *attrname); extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, @@ -247,6 +261,8 @@ extern struct sysfs_class_device *sysfs_get_class_device (struct sysfs_class *class, unsigned char *name); extern struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *cdev); +extern struct dlist *sysfs_refresh_classdev_attributes + (struct sysfs_class_device *cdev); extern struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const unsigned char *name); extern struct sysfs_attribute *sysfs_open_classdev_attr diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index d9da0f84cf..aca392875e 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -209,9 +209,7 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name) return NULL; } - if (sysfs_trailing_slash(buspath) == 0) - strcat(buspath, "/"); - + strcat(buspath, "/"); strcat(buspath, SYSFS_BUS_NAME); strcat(buspath, "/"); strcat(buspath, name); @@ -226,6 +224,11 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name) } strcpy(bus->name, name); strcpy(bus->path, buspath); + if ((sysfs_remove_trailing_slash(bus->path)) != 0) { + dprintf("Incorrect path to bus %s\n", bus->path); + sysfs_close_bus(bus); + return NULL; + } return bus; } @@ -296,20 +299,37 @@ struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) if (bus->directory->attributes == NULL) { if ((sysfs_read_dir_attributes(bus->directory)) != 0) return NULL; - } else { - if ((sysfs_path_is_dir(bus->path)) != 0) { - dprintf("Bus at %s no longer exists\n", bus->path); - return NULL; - } - if ((sysfs_refresh_attributes - (bus->directory->attributes)) != 0) { - dprintf("Error refreshing bus attributes\n"); - return NULL; - } } return bus->directory->attributes; } +/** + * sysfs_refresh_bus_attributes: refreshes the bus's list of attributes + * @bus: sysfs_bus whose attributes to refresh + * + * NOTE: Upon return, prior references to sysfs_attributes for this bus + * _may_ not be valid + * + * Returns list of attributes on success and NULL on failure + */ +struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus) +{ + if (bus == NULL) { + errno = EINVAL; + return NULL; + } + + if (bus->directory == NULL) + return (sysfs_get_bus_attributes(bus)); + + if ((sysfs_refresh_dir_attributes(bus->directory)) != 0) { + dprintf("Error refreshing bus attributes\n"); + return NULL; + } + + return (bus->directory->attributes); +} + /** * sysfs_get_bus_attribute: gets a specific bus attribute, if buses had * attributes. @@ -357,8 +377,7 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, return NULL; } - if (sysfs_trailing_slash(path) == 0) - strcat(path, "/"); + strcat(path, "/"); strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, busname); diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 16eaf6e514..cd86912142 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -160,6 +160,11 @@ struct sysfs_class_device *sysfs_open_class_device_path } strcpy(cdev->path, path); + if ((sysfs_remove_trailing_slash(cdev->path)) != 0) { + dprintf("Invalid path to class device %s\n", cdev->path); + sysfs_close_class_device(cdev); + return NULL; + } set_classdev_classname(cdev); return cdev; @@ -179,6 +184,10 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) errno = EINVAL; return NULL; } + + if (cls->devices != NULL) + return cls->devices; + if (cls->directory == NULL) { cls->directory = sysfs_open_directory(cls->path); if (cls->directory == NULL) @@ -226,16 +235,16 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) dprintf("Sysfs not supported on this system\n"); return NULL; } - if (sysfs_trailing_slash(classpath) == 0) - strcat(classpath, "/"); /* * We shall now treat "block" also as a class. Hence, check here * if "name" is "block" and proceed accordingly */ if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { + strcat(classpath, "/"); strcat(classpath, SYSFS_BLOCK_NAME); } else { + strcat(classpath, "/"); strcat(classpath, SYSFS_CLASS_NAME); strcat(classpath, "/"); strcat(classpath, name); @@ -252,6 +261,11 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) } strcpy(cls->name, name); strcpy(cls->path, classpath); + if ((sysfs_remove_trailing_slash(cls->path)) != 0) { + dprintf("Invalid path to class device %s\n", cls->path); + sysfs_close_class(cls); + return NULL; + } return cls; } @@ -264,8 +278,6 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class, unsigned char *name) { - struct dlist *devlist = NULL; - if (class == NULL || name == NULL) { errno = EINVAL; return NULL; @@ -273,7 +285,7 @@ struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class, if (class->devices == NULL) { class->devices = sysfs_get_class_devices(class); - if (devlist == NULL) + if (class->devices == NULL) return NULL; } return (struct sysfs_class_device *)dlist_find_custom(class->devices, @@ -291,14 +303,21 @@ struct sysfs_device *sysfs_get_classdev_device (struct sysfs_class_device *clsdev) { struct sysfs_link *devlink = NULL; + unsigned char devpath[SYSFS_PATH_MAX]; if (clsdev == NULL) { errno = EINVAL; return NULL; } - - if (clsdev->sysdevice != NULL) - return (clsdev->sysdevice); + strcpy(devpath, clsdev->path); + strcat(devpath, "/device"); + if ((sysfs_path_is_link(devpath)) != 0) { + if (clsdev->sysdevice != NULL) { + sysfs_close_device(clsdev->sysdevice); + clsdev->sysdevice = NULL; + } + return NULL; + } if (clsdev->directory == NULL) { clsdev->directory = sysfs_open_directory(clsdev->path); @@ -306,8 +325,24 @@ struct sysfs_device *sysfs_get_classdev_device return NULL; } devlink = sysfs_get_directory_link(clsdev->directory, "device"); - if (devlink == NULL) + if (devlink == NULL) { + if (clsdev->sysdevice != NULL) { + dprintf("Device link no longer exists\n"); + sysfs_close_device(clsdev->sysdevice); + clsdev->sysdevice = NULL; + } return NULL; + } + + if (clsdev->sysdevice != NULL) { + if (!strncmp(devlink->target, clsdev->sysdevice->path, + SYSFS_PATH_MAX)) + /* sysdevice hasn't changed */ + return (clsdev->sysdevice); + else + /* come here only if the device link for has changed */ + sysfs_close_device(clsdev->sysdevice); + } clsdev->sysdevice = sysfs_open_device_path(devlink->target); if (clsdev->sysdevice == NULL) @@ -329,31 +364,56 @@ struct sysfs_driver *sysfs_get_classdev_driver (struct sysfs_class_device *clsdev) { struct sysfs_link *drvlink = NULL; + unsigned char drvpath[SYSFS_PATH_MAX]; if (clsdev == NULL) { errno = EINVAL; return NULL; } - - if (clsdev->driver != NULL) - return (clsdev->driver); - + strcpy(drvpath, clsdev->path); + strcat(drvpath, "/driver"); + if ((sysfs_path_is_link(drvpath)) != 0) { + if (clsdev->driver != NULL) { + sysfs_close_driver(clsdev->driver); + clsdev->driver = NULL; + } + return NULL; + } + if (clsdev->directory == NULL) { clsdev->directory = sysfs_open_directory(clsdev->path); if (clsdev->directory == NULL) return NULL; } drvlink = sysfs_get_directory_link(clsdev->directory, "driver"); - if (drvlink != NULL) { - clsdev->driver = sysfs_open_driver_path(drvlink->target); - if (clsdev->driver == NULL) - return NULL; - + if (drvlink == NULL) { + if (clsdev->driver != NULL) { + dprintf("Driver link no longer exists\n"); + sysfs_close_driver(clsdev->driver); + clsdev->driver = NULL; + } + return NULL; } + if (clsdev->driver != NULL) { + if (!strncmp(drvlink->target, clsdev->driver->path, + SYSFS_PATH_MAX)) + /* driver hasn't changed */ + return (clsdev->driver); + else + /* come here only if the device link for has changed */ + sysfs_close_driver(clsdev->driver); + } + + clsdev->driver = sysfs_open_driver_path(drvlink->target); + if (clsdev->driver == NULL) + return NULL; + if (clsdev->sysdevice != NULL) + strcpy(clsdev->sysdevice->driver_name, clsdev->driver->name); + return (clsdev->driver); } - -/* + +/** * get_blockdev_parent: Get the parent class device for a "block" subsystem * device if present * @clsdev: block subsystem class device whose parent needs to be found @@ -361,48 +421,34 @@ struct sysfs_driver *sysfs_get_classdev_driver */ static int get_blockdev_parent(struct sysfs_class_device *clsdev) { - unsigned char parent_path[SYSFS_PATH_MAX], value[256], *c = NULL; - - memset(parent_path, 0, SYSFS_PATH_MAX); - strcpy(parent_path, clsdev->path); + unsigned char parent_path[SYSFS_PATH_MAX], *c = NULL; + strcpy(parent_path, clsdev->path); c = strstr(parent_path, SYSFS_BLOCK_NAME); if (c == NULL) { - dprintf("Class device %s does not belong to BLOCK subsystem", + dprintf("Class device %s does not belong to BLOCK subsystem\n", clsdev->name); return 1; } - + c += strlen(SYSFS_BLOCK_NAME); if (*c == '/') c++; else goto errout; - - /* validate whether the given class device is a partition or not */ - if ((strncmp(c, clsdev->name, strlen(clsdev->name))) == 0) { - dprintf("%s not a partition\n", clsdev->name); - return 1; - } - c = strchr(c, '/'); - if (c == NULL) - goto errout; - *c = '\0'; - - /* Now validate if the parent has the "dev" attribute */ - memset(value, 0, 256); - strcat(parent_path, "/dev"); - if ((sysfs_read_attribute_value(parent_path, value, 256)) != 0) { - dprintf("Block device %s does not have a parent\n", - clsdev->name); - return 1; - } - - c = strrchr(parent_path, '/'); + + /* validate whether the given class device is a partition or not */ + if ((strncmp(c, clsdev->name, strlen(clsdev->name))) == 0) { + dprintf("%s not a partition\n", clsdev->name); + return 1; + } + + c = strchr(c, '/'); if (c == NULL) goto errout; *c = '\0'; + clsdev->parent = sysfs_open_class_device_path(parent_path); if (clsdev->parent == NULL) { dprintf("Error opening the parent class device at %s\n", @@ -467,13 +513,11 @@ static int get_classdev_path(const unsigned char *classname, dprintf("Error getting sysfs mount path\n"); return -1; } - - if (sysfs_trailing_slash(path) == 0) - strcat(path, "/"); - if (strcmp(classname, SYSFS_BLOCK_NAME) == 0) { + strcat(path, "/"); strcat(path, SYSFS_BLOCK_NAME); } else { + strcat(path, "/"); strcat(path, SYSFS_CLASS_NAME); strcat(path, "/"); strcat(path, classname); @@ -537,26 +581,40 @@ struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev) return NULL; } if (cdev->directory->attributes == NULL) { - if ((sysfs_read_dir_attributes(cdev->directory)) != 0) { - dprintf("Error reading attributes for directory %s\n", - cdev->directory->path); + if ((sysfs_read_dir_attributes(cdev->directory)) != 0) return NULL; - } - } else { - if ((sysfs_path_is_dir(cdev->path)) != 0) { - dprintf("Class device at %s no longer exists\n", - cdev->path); - return NULL; - } - if ((sysfs_refresh_attributes - (cdev->directory->attributes)) != 0) { - dprintf("Error refreshing classdev attributes\n"); - return NULL; - } } return (cdev->directory->attributes); } +/** + * sysfs_refresh_clsassdev_attributes: refreshes the driver's list of attributes + * @clsdev: sysfs_class_device whose attributes to refresh + * + * NOTE: Upon return, prior references to sysfs_attributes for this classdev + * _may_ not be valid + * + * Returns list of attributes on success and NULL on failure + */ +struct dlist *sysfs_refresh_classdev_attributes + (struct sysfs_class_device *clsdev) +{ + if (clsdev == NULL) { + errno = EINVAL; + return NULL; + } + + if (clsdev->directory == NULL) + return (sysfs_get_classdev_attributes(clsdev)); + + if ((sysfs_refresh_dir_attributes(clsdev->directory)) != 0) { + dprintf("Error refreshing class_device attributes\n"); + return NULL; + } + + return (clsdev->directory->attributes); +} + /** * sysfs_get_classdev_attr: searches class device's attributes by name * @clsdev: class device to look through @@ -597,15 +655,10 @@ struct sysfs_attribute *sysfs_get_classdev_attr struct sysfs_directory) { if ((sysfs_path_is_dir(sdir->path)) != 0) continue; - if (sdir->attributes == NULL) { - cur = sysfs_get_directory_attribute(sdir, + cur = sysfs_get_directory_attribute(sdir, (unsigned char *)name); - } else { - if ((sysfs_refresh_attributes - (sdir->attributes)) == 0) - cur = sysfs_get_directory_attribute(sdir, - (unsigned char *)name); - } + if (cur == NULL) + continue; } } return cur; diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 66d5f9aef7..bfd761b885 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -24,12 +24,12 @@ #include "sysfs.h" /** - * get_device_bus: retrieves the bus name the device is on, checks path to - * bus' link to make sure it has correct device. + * sysfs_get_device_bus: retrieves the bus name the device is on, checks path + * to bus' link to make sure it has correct device. * @dev: device to get busname. * returns 0 with success and -1 with error. */ -static int get_device_bus(struct sysfs_device *dev) +int sysfs_get_device_bus(struct sysfs_device *dev) { unsigned char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX]; unsigned char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL; @@ -197,6 +197,11 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path) return NULL; } strcpy(dev->path, path); + if ((sysfs_remove_trailing_slash(dev->path)) != 0) { + dprintf("Invalid path to device %s\n", dev->path); + sysfs_close_device(dev); + return NULL; + } /* * The "name" attribute no longer exists... return the device's * sysfs representation instead, in the "dev->name" field, which @@ -204,8 +209,8 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path) */ strncpy(dev->name, dev->bus_id, SYSFS_NAME_LEN); - if (get_device_bus(dev) != 0) - strcpy(dev->bus, SYSFS_UNKNOWN); + if (sysfs_get_device_bus(dev) != 0) + dprintf("Could not get device bus\n"); return dev; } @@ -334,8 +339,7 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) return NULL; } - if (sysfs_trailing_slash(rootpath) == 0) - strcat(rootpath, "/"); + strcat(rootpath, "/"); strcat(rootpath, SYSFS_DEVICES_NAME); strcat(rootpath, "/"); strcat(rootpath, name); @@ -352,6 +356,11 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) } strcpy(root->name, name); strcpy(root->path, rootpath); + if ((sysfs_remove_trailing_slash(root->path)) != 0) { + dprintf("Invalid path to root device %s\n", root->path); + sysfs_close_root_device(root); + return NULL; + } return root; } @@ -373,20 +382,37 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) if (device->directory->attributes == NULL) { if ((sysfs_read_dir_attributes(device->directory)) != 0) return NULL; - } else { - if ((sysfs_path_is_dir(device->path)) != 0) { - dprintf("Device at %s no longer exists", device->path); - return NULL; - } - if ((sysfs_refresh_attributes - (device->directory->attributes)) != 0) { - dprintf("Error refreshing device attributes\n"); - return NULL; - } } return (device->directory->attributes); } +/** + * sysfs_refresh_device_attributes: refreshes the device's list of attributes + * @device: sysfs_device whose attributes to refresh + * + * NOTE: Upon return, prior references to sysfs_attributes for this device + * _may_ not be valid + * + * Returns list of attributes on success and NULL on failure + */ +struct dlist *sysfs_refresh_device_attributes(struct sysfs_device *device) +{ + if (device == NULL) { + errno = EINVAL; + return NULL; + } + + if (device->directory == NULL) + return (sysfs_get_device_attributes(device)); + + if ((sysfs_refresh_dir_attributes(device->directory)) != 0) { + dprintf("Error refreshing device attributes\n"); + return NULL; + } + + return (device->directory->attributes); +} + /** * sysfs_get_device_attr: searches dev's attributes by name * @dev: device to look through @@ -396,22 +422,19 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, const unsigned char *name) { - struct sysfs_attribute *cur = NULL; struct dlist *attrlist = NULL; if (dev == NULL || name == NULL) { errno = EINVAL; return NULL; } - + attrlist = sysfs_get_device_attributes(dev); if (attrlist == NULL) return NULL; - cur = sysfs_get_directory_attribute(dev->directory, - (unsigned char *)name); - - return cur; + return sysfs_get_directory_attribute(dev->directory, + (unsigned char *)name); } /** @@ -437,8 +460,7 @@ static int get_device_absolute_path(const unsigned char *device, dprintf ("Sysfs not supported on this system\n"); return -1; } - if (sysfs_trailing_slash(bus_path) == 0) - strcat(bus_path, "/"); + strcat(bus_path, "/"); strcat(bus_path, SYSFS_BUS_NAME); strcat(bus_path, "/"); strcat(bus_path, bus); diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index c159db7af8..a60410ed28 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -195,7 +195,7 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, return -1; } if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0) { - dprintf("Attribute %s already has the requested value %s\n", + dprintf("Attr %s already has the requested value %s\n", sysattr->name, new_value); return 0; } @@ -274,7 +274,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) return -1; } #ifdef __KLIBC__ - pgsize = 0x1000; + pgsize = 0x1000; #else pgsize = sysconf(_SC_PAGESIZE); #endif @@ -468,6 +468,13 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path) errno = EINVAL; return NULL; } + + if (sysfs_path_is_dir(path) != 0) { + dprintf("Invalid path directory %s\n", path); + errno = EINVAL; + return NULL; + } + sdir = alloc_directory(); if (sdir == NULL) { dprintf("Error allocating directory %s\n", path); @@ -513,39 +520,6 @@ struct sysfs_link *sysfs_open_link(const unsigned char *linkpath) return ln; } -/** - * sysfs_refresh_attributes: Refresh attributes list - * @attrlist: list of attributes to refresh - * Returns 0 on success, 1 on failure - */ -int sysfs_refresh_attributes(struct dlist *attrlist) -{ - struct sysfs_attribute *attr = NULL; - - if (attrlist == NULL) { - errno = EINVAL; - return 1; - } - dlist_for_each_data(attrlist, attr, struct sysfs_attribute) { - if (attr->method & SYSFS_METHOD_SHOW) { - if ((sysfs_read_attribute(attr)) != 0) { - dprintf("Error reading attribute %s\n", - attr->path); - if ((sysfs_path_is_file(attr->path)) != 0) { - dprintf("Attr %s no longer exists\n", - attr->name); - } - } - } else { - if ((sysfs_path_is_file(attr->path)) != 0) { - dprintf("Attr %s no longer exists\n", - attr->name); - } - } - } - return 0; -} - /** * add_attribute: open and add attribute at path to given directory * @sysdir: directory to add attribute to @@ -633,7 +607,6 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir) { DIR *dir = NULL; struct dirent *dirent = NULL; - struct stat astats; unsigned char file_path[SYSFS_PATH_MAX]; int retval = 0; @@ -655,11 +628,7 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir) strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); strcat(file_path, "/"); strcat(file_path, dirent->d_name); - if ((lstat(file_path, &astats)) != 0) { - dprintf("stat failed\n"); - continue; - } - if (S_ISREG(astats.st_mode)) + if ((sysfs_path_is_file(file_path)) == 0) retval = add_attribute(sysdir, file_path); } closedir(dir); @@ -675,7 +644,6 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir) { DIR *dir = NULL; struct dirent *dirent = NULL; - struct stat astats; unsigned char file_path[SYSFS_PATH_MAX]; int retval = 0; @@ -697,11 +665,7 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir) strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); strcat(file_path, "/"); strcat(file_path, dirent->d_name); - if ((lstat(file_path, &astats)) != 0) { - dprintf("stat failed\n"); - continue; - } - if (S_ISLNK(astats.st_mode)) { + if ((sysfs_path_is_link(file_path)) == 0) { retval = add_link(sysdir, file_path); if (retval != 0) break; @@ -720,7 +684,6 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir) { DIR *dir = NULL; struct dirent *dirent = NULL; - struct stat astats; unsigned char file_path[SYSFS_PATH_MAX]; int retval = 0; @@ -742,11 +705,7 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir) strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); strcat(file_path, "/"); strcat(file_path, dirent->d_name); - if ((lstat(file_path, &astats)) != 0) { - dprintf("stat failed\n"); - continue; - } - if (S_ISDIR(astats.st_mode)) + if ((sysfs_path_is_dir(file_path)) == 0) retval = add_subdirectory(sysdir, file_path); } closedir(dir); @@ -801,6 +760,90 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) return(retval); } +/** + * sysfs_refresh_dir_attributes: Refresh attributes list + * @sysdir: directory whose list of attributes to refresh + * Returns 0 on success, 1 on failure + */ +int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir) +{ + if (sysdir == NULL) { + errno = EINVAL; + return 1; + } + if ((sysfs_path_is_dir(sysdir->path)) != 0) { + dprintf("Invalid path to directory %s\n", sysdir->path); + errno = EINVAL; + return 1; + } + if (sysdir->attributes != NULL) { + dlist_destroy(sysdir->attributes); + sysdir->attributes = NULL; + } + if ((sysfs_read_dir_attributes(sysdir)) != 0) { + dprintf("Error refreshing attributes for directory %s\n", + sysdir->path); + return 1; + } + return 0; +} + +/** + * sysfs_refresh_dir_links: Refresh links list + * @sysdir: directory whose list of links to refresh + * Returns 0 on success, 1 on failure + */ +int sysfs_refresh_dir_links(struct sysfs_directory *sysdir) +{ + if (sysdir == NULL) { + errno = EINVAL; + return 1; + } + if ((sysfs_path_is_dir(sysdir->path)) != 0) { + dprintf("Invalid path to directory %s\n", sysdir->path); + errno = EINVAL; + return 1; + } + if (sysdir->links != NULL) { + dlist_destroy(sysdir->links); + sysdir->links = NULL; + } + if ((sysfs_read_dir_links(sysdir)) != 0) { + dprintf("Error refreshing links for directory %s\n", + sysdir->path); + return 1; + } + return 0; +} + +/** + * sysfs_refresh_dir_subdirs: Refresh subdirs list + * @sysdir: directory whose list of subdirs to refresh + * Returns 0 on success, 1 on failure + */ +int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir) +{ + if (sysdir == NULL) { + errno = EINVAL; + return 1; + } + if ((sysfs_path_is_dir(sysdir->path)) != 0) { + dprintf("Invalid path to directory %s\n", sysdir->path); + errno = EINVAL; + return 1; + } + if (sysdir->subdirs != NULL) { + dlist_destroy(sysdir->subdirs); + sysdir->subdirs = NULL; + } + if ((sysfs_read_dir_subdirs(sysdir)) != 0) { + dprintf("Error refreshing subdirs for directory %s\n", + sysdir->path); + return 1; + } + return 0; +} + /** * sysfs_get_directory_attribute: retrieves attribute attrname from current * directory only @@ -826,19 +869,25 @@ struct sysfs_attribute *sysfs_get_directory_attribute attr = (struct sysfs_attribute *)dlist_find_custom (dir->attributes, attrname, dir_attribute_name_equal); - if (attr == NULL) { + if (attr != NULL) { + if ((sysfs_read_attribute(attr)) != 0) { + dprintf("Error reading attribute %s\n", attr->name); + return NULL; + } + } else { memset(new_path, 0, SYSFS_PATH_MAX); strcpy(new_path, dir->path); strcat(new_path, "/"); strcat(new_path, attrname); if ((sysfs_path_is_file(new_path)) == 0) { - if ((add_attribute(dir, new_path)) == 0) { + if ((add_attribute(dir, new_path)) == 0) { attr = (struct sysfs_attribute *) - dlist_find_custom(dir->attributes, + dlist_find_custom(dir->attributes, attrname, dir_attribute_name_equal); } } } + return attr; } @@ -855,9 +904,13 @@ struct sysfs_link *sysfs_get_directory_link errno = EINVAL; return NULL; } - if (dir->links == NULL) + if (dir->links == NULL) { if ((sysfs_read_dir_links(dir) != 0) || (dir->links == NULL)) return NULL; + } else { + if ((sysfs_refresh_dir_links(dir)) != 0) + return NULL; + } return (struct sysfs_link *)dlist_find_custom(dir->links, linkname, dir_link_name_equal); @@ -940,3 +993,63 @@ struct sysfs_link *sysfs_get_subdirectory_link(struct sysfs_directory *dir, } return NULL; } + +/** + * sysfs_get_dir_attributes: returns dlist of directory attributes + * @dir: directory to retrieve attributes from + * returns dlist of attributes or NULL + */ +struct dlist *sysfs_get_dir_attributes(struct sysfs_directory *dir) +{ + if (dir == NULL) { + errno = EINVAL; + return NULL; + } + + if (dir->attributes == NULL) { + if (sysfs_read_dir_attributes(dir) != 0) + return NULL; + } + + return (dir->attributes); +} + +/** + * sysfs_get_dir_links: returns dlist of directory links + * @dir: directory to return links for + * returns dlist of links or NULL + */ +struct dlist *sysfs_get_dir_links(struct sysfs_directory *dir) +{ + if (dir == NULL) { + errno = EINVAL; + return NULL; + } + + if (dir->links == NULL) { + if (sysfs_read_dir_links(dir) != 0) + return NULL; + } + + return (dir->links); +} + +/** + * sysfs_get_dir_subdirs: returns dlist of directory subdirectories + * @dir: directory to return subdirs for + * returns dlist of subdirs or NULL + */ +struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir) +{ + if (dir == NULL) { + errno = EINVAL; + return NULL; + } + + if (dir->subdirs == NULL) { + if (sysfs_read_dir_subdirs(dir) != 0) + return NULL; + } + + return (dir->subdirs); +} diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 695ca794f1..a4440cfdf9 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -103,6 +103,11 @@ struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path) return NULL; } strcpy(driver->path, path); + if ((sysfs_remove_trailing_slash(driver->path)) != 0) { + dprintf("Invalid path to driver %s\n", driver->path); + sysfs_close_driver(driver); + return NULL; + } return driver; } @@ -125,25 +130,37 @@ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) return NULL; } if (driver->directory->attributes == NULL) { - if ((sysfs_read_dir_attributes(driver->directory)) != 0) { - dprintf("Error reading driver attributes\n"); + if ((sysfs_read_dir_attributes(driver->directory)) != 0) return NULL; - } - } else { - if ((sysfs_path_is_dir(driver->path)) != 0) { - dprintf("Driver at %s no longer exists\n", - driver->path); - return NULL; - } - if ((sysfs_refresh_attributes - (driver->directory->attributes)) != 0) { - dprintf("Error refreshing driver attributes\n"); - return NULL; - } } return(driver->directory->attributes); } +/** + * sysfs_refresh_driver_attributes: refreshes the driver's list of attributes + * @driver: sysfs_driver whose attributes to refresh + * + * NOTE: Upon return, prior references to sysfs_attributes for this driver + * _may_ not be valid + * + * Returns list of attributes on success and NULL on failure + */ +struct dlist *sysfs_refresh_driver_attributes(struct sysfs_driver *driver) +{ + if (driver == NULL) { + errno = EINVAL; + return NULL; + } + if (driver->directory == NULL) + return (sysfs_get_driver_attributes(driver)); + + if ((sysfs_refresh_dir_attributes(driver->directory)) != 0) { + dprintf("Error refreshing driver attributes\n"); + return NULL; + } + return (driver->directory->attributes); +} + /** * sysfs_get_driver_attr: searches driver's attributes by name * @drv: driver to look through @@ -153,7 +170,6 @@ struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, const unsigned char *name) { - struct sysfs_attribute *cur = NULL; struct dlist *attrlist = NULL; if (drv == NULL) { @@ -163,9 +179,10 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, attrlist = sysfs_get_driver_attributes(drv); if (attrlist != NULL) - cur = sysfs_get_directory_attribute(drv->directory, + return NULL; + + return sysfs_get_directory_attribute(drv->directory, (unsigned char *)name); - return cur; } /** @@ -233,6 +250,38 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) return (driver->devices); } +/** + * sysfs_refresh_driver_devices: Refreshes drivers list of devices + * @driver: sysfs_driver whose devices list needs to be refreshed + * + * NOTE: Upon return from this function, prior sysfs_device references from + * this driver's list of devices _may_ not be valid + * + * Returns dlist of devices on success and NULL on failure + */ +struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver) +{ + if (driver == NULL) { + errno = EINVAL; + return NULL; + } + + if (driver->devices != NULL) { + dlist_destroy(driver->devices); + driver->devices = NULL; + } + + if (driver->directory == NULL) + return (sysfs_get_driver_devices(driver)); + + if ((sysfs_refresh_dir_links(driver->directory)) != 0) { + dprintf("Error refreshing driver links\n"); + return NULL; + } + + return (sysfs_get_driver_devices(driver)); +} + /** * sysfs_get_driver_device: looks up a device from a list of driver's devices * and returns its sysfs_device corresponding to it @@ -285,8 +334,7 @@ static int get_driver_path(const unsigned char *bus, dprintf("Error getting sysfs mount path\n"); return -1; } - if (sysfs_trailing_slash(path) == 0) - strcat(path, "/"); + strcat(path, "/"); strcat(path, SYSFS_BUS_NAME); strcat(path, "/"); strcat(path, bus); diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 009ae94efa..f1f82361d0 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -26,6 +26,30 @@ #include #endif +/** + * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path + * @path: Path to look for the trailing '/' + * Returns 0 on success 1 on error + */ +int sysfs_remove_trailing_slash(unsigned char *path) +{ + unsigned char *c = NULL; + + if (path == NULL) { + errno = EINVAL; + return 1; + } + c = strrchr(path, '/'); + if (c == NULL) { + dprintf("Invalid path %s\n", path); + errno = EINVAL; + return 1; + } + if (*(c+1) == '\0') + *c = '\0'; + return 0; +} + /** * sysfs_get_mnt_path: Gets the mount point for specified filesystem. * @fs_type: filesystem type to retrieve mount point @@ -72,27 +96,13 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, errno = EINVAL; ret = -1; } + if ((sysfs_remove_trailing_slash(mnt_path)) != 0) + ret = -1; + return ret; #endif } -/* - * sysfs_trailing_slash: checks if there's a trailing slash to path - * @path: path to check - * returns 1 if true and 0 if not - */ -int sysfs_trailing_slash(unsigned char *path) -{ - unsigned char *s = NULL; - - if (path == NULL) - return 0; - s = &path[strlen(path)-1]; - if (strncmp(s, "/", 1) == 0) - return 1; - return 0; -} - /* * sysfs_get_mnt_path: Gets the sysfs mount point. * @mnt_path: place to put "sysfs" mount point @@ -109,9 +119,11 @@ int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) return -1; } sysfs_path = getenv(SYSFS_PATH_ENV); - if (sysfs_path != NULL) + if (sysfs_path != NULL) { strncpy(mnt_path, sysfs_path, len); - else + if ((sysfs_remove_trailing_slash(mnt_path)) != 0) + return 1; + } else ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, mnt_path, len); return ret; @@ -152,7 +164,7 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, strncpy(name, n, len); return 0; } - + /** * sysfs_get_link: returns link source * @path: symbolic link's path @@ -178,32 +190,69 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) { return -1; } - d = linkpath; - - /* getting rid of leading "../.." */ - while (*d == '/' || *d == '.') { - if (*d == '/') - slashes++; - d++; + /* + * Three cases here: + * 1. relative path => format ../.. + * 2. absolute path => format /abcd/efgh + * 3. relative path _from_ this dir => format abcd/efgh + */ + switch (*d) { + case '.': + /* + * handle the case where link is of type ./abcd/xxx + */ + strncpy(target, devdir, len); + if (*(d+1) == '/') + d += 2; + else if (*(d+1) == '.') + goto parse_path; + s = strrchr(target, '/'); + if (s != NULL) { + *(s+1) = '\0'; + strcat(target, d); + } else { + strcpy(target, d); + } + break; + /* + * relative path + * getting rid of leading "../.." + */ +parse_path: + while (*d == '/' || *d == '.') { + if (*d == '/') + slashes++; + d++; + } + d--; + s = &devdir[strlen(devdir)-1]; + while (s != NULL && count != (slashes+1)) { + s--; + if (*s == '/') + count++; + } + strncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir))); + strncpy(target, devdir, len); + break; + case '/': + /* absolute path - copy as is */ + strncpy(target, linkpath, len); + break; + default: + /* relative path from this directory */ + strncpy(target, devdir, len); + s = strrchr(target, '/'); + if (s != NULL) { + *(s+1) = '\0'; + strcat(target, linkpath); + } else { + strcpy(target, linkpath); + } } - - d--; - - s = &devdir[strlen(devdir)-1]; - while (s != NULL && count != (slashes+1)) { - s--; - if (*s == '/') - count++; - } - - strncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir))); - strncpy(target, devdir, len); - return 0; } - /** * sysfs_del_name: free function for sysfs_open_subsystem_list * @name: memory area to be freed @@ -245,8 +294,8 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) dprintf("Error getting sysfs mount point\n"); return NULL; } - if (sysfs_trailing_slash(sysfs_path) == 0) - strcat(sysfs_path, "/"); + + strcat(sysfs_path, "/"); strcat(sysfs_path, name); dir = sysfs_open_directory(sysfs_path); if (dir == NULL) { @@ -318,8 +367,7 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) return NULL; } - if (sysfs_trailing_slash(sysfs_path) == 0) - strcat(sysfs_path, "/"); + strcat(sysfs_path, "/"); strcat(sysfs_path, SYSFS_BUS_NAME); strcat(sysfs_path, "/"); strcat(sysfs_path, name); @@ -376,7 +424,7 @@ int sysfs_path_is_dir(const unsigned char *path) } if (S_ISDIR(astats.st_mode)) return 0; - + return 1; } @@ -399,7 +447,7 @@ int sysfs_path_is_link(const unsigned char *path) } if (S_ISLNK(astats.st_mode)) return 0; - + return 1; } @@ -422,6 +470,6 @@ int sysfs_path_is_file(const unsigned char *path) } if (S_ISREG(astats.st_mode)) return 0; - + return 1; } diff --git a/namedev.c b/namedev.c index 0e1af9385f..fdda039f59 100644 --- a/namedev.c +++ b/namedev.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -514,11 +515,8 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de { struct sysfs_device *sysfs_device; struct sysfs_class_device *class_dev_parent; + struct timespec tspec; int loop; - char filename[SYSFS_PATH_MAX + 6]; - int retval; - char *temp; - int partition = 0; /* Figure out where the device symlink is at. For char devices this will * always be in the class_dev->path. But for block devices, it's different. @@ -529,69 +527,54 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de * symlink yet. We do sit and spin on waiting for them right now, we should * possibly have a whitelist for these devices here... */ - strcpy(filename, class_dev->path); - dbg("filename = %s", filename); - if (strcmp(class_dev->classname, SYSFS_BLOCK_NAME) == 0) { - if (isdigit(class_dev->path[strlen(class_dev->path)-1])) { - temp = strrchr(filename, '/'); - if (temp) { - char *temp2 = strrchr(filename, '/'); - partition = 1; - *temp = 0x00; - dbg("temp2 = %s", temp2); - if (temp2 && (strcmp(temp2, "/block") == 0)) { - /* oops, we have no parent block device, so go back to original directory */ - strcpy(filename, class_dev->path); - partition = 0; - } - } - } - } - strcat(filename, "/device"); + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent) + dbg("Really a partition"); - loop = 2; + tspec.tv_sec = 0; + tspec.tv_nsec = 10000000; /* sleep 10 millisec */ + loop = 10; while (loop--) { - struct stat buf; - dbg("looking for '%s'", filename); - retval = stat(filename, &buf); - if (!retval) - break; - /* sleep to give the kernel a chance to create the device file */ - sleep(1); - } + nanosleep(&tspec, NULL); + if (class_dev_parent) + sysfs_device = sysfs_get_classdev_device(class_dev_parent); + else + sysfs_device = sysfs_get_classdev_device(class_dev); - loop = 1; /* FIXME put a real value in here for when everything is fixed... */ - while (loop--) { - /* find the sysfs_device for this class device */ - /* Wouldn't it really be nice if libsysfs could do this for us? */ - sysfs_device = sysfs_get_classdev_device(class_dev); if (sysfs_device != NULL) - goto exit; - - /* if it's a partition, we need to get the parent device */ - if (partition) { - /* FIXME HACK HACK HACK HACK - * for some reason partitions need this extra sleep here, in order - * to wait for the device properly. Once the libsysfs code is - * fixed properly, this sleep should go away, and we can just loop above. - */ - sleep(1); - dbg("really is a partition"); - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent == NULL) { - dbg("sysfs_get_classdev_parent for class device '%s' failed", class_dev->name); - } else { - dbg("class_dev_parent->name='%s'", class_dev_parent->name); - sysfs_device = sysfs_get_classdev_device(class_dev_parent); - if (sysfs_device != NULL) - goto exit; - } - } - /* sleep to give the kernel a chance to create the link */ - /* FIXME remove comment... - sleep(1); */ + goto device_found; } dbg("Timed out waiting for device symlink, continuing on anyway..."); + +device_found: + /* We have another issue with just the wait above - the sysfs part of + * the kernel may not be quick enough to have created the link to the + * device under the "bus" subsystem. Due to this, the sysfs_device->bus + * will not contain the actual bus name :( + * + * Libsysfs now provides a new API sysfs_get_device_bus(), so use it + * if needed + */ + if (sysfs_device) { + + if (sysfs_device->bus[0] != '\0') + goto bus_found; + + loop = 10; + tspec.tv_nsec = 10000000; + while (loop--) { + nanosleep(&tspec, NULL); + sysfs_get_device_bus(sysfs_device); + + if (sysfs_device->bus[0] != '\0') + goto bus_found; + } + dbg("Timed out waiting to find the device bus, continuing on anyway\n"); + goto exit; +bus_found: + dbg("Device %s is registered with bus %s\n", + sysfs_device->name, sysfs_device->bus); + } exit: return sysfs_device; } From f130b15645fb41d9dd902b6c96948d344bfe96fa Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 14 Jan 2004 22:55:24 -0800 Subject: [PATCH 0423/4284] [PATCH] add usb_host and pci_bus to the class blacklist. --- udev.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev.c b/udev.c index 84950c82a3..b395be2abb 100644 --- a/udev.c +++ b/udev.c @@ -245,6 +245,8 @@ static char *subsystem_blacklist[] = { "net", "scsi_host", "scsi_device", + "usb_host", + "pci_bus", "", }; From 45d57088f915897fc54ff8a98934b1b34c4cc18f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 15 Jan 2004 21:18:21 -0800 Subject: [PATCH 0424/4284] [PATCH] remove unneeded keyboard rule. --- etc/udev/udev.rules | 1 - etc/udev/udev.rules.devfs | 1 - 2 files changed, 2 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 1f3ef07242..406a1891bd 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -65,7 +65,6 @@ KERNEL="seq", NAME="snd/%k" # input devices KERNEL="mice", NAME="input/%k" -KERNEL="keyboard", NAME="input/%k" KERNEL="mouse*", NAME="input/%k" KERNEL="event*", NAME="input/%k" KERNEL="js*", NAME="input/%k" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 026e9465b1..c04fc7e8ef 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -71,7 +71,6 @@ KERNEL="seq", NAME="snd/%k" # input devices KERNEL="mice", NAME="input/%k" -KERNEL="keyboard", NAME="input/%k" KERNEL="mouse*", NAME="input/%k" KERNEL="event*", NAME="input/%k" KERNEL="js*", NAME="input/%k" From 18f0045bc86f6b8b50a91fc4e8af4cfdd2379751 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 15 Jan 2004 21:42:59 -0800 Subject: [PATCH 0425/4284] [PATCH] remove the %D modifier as it is not longer needed. --- etc/udev/udev.rules | 16 ++-------------- etc/udev/udev.rules.devfs | 19 ++----------------- namedev.c | 10 ---------- udev.8 | 5 ----- 4 files changed, 4 insertions(+), 46 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 406a1891bd..98d2ceccc7 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -1,17 +1,5 @@ -# There are a number of modifiers that are allowed to be used in the NAME or PROGRAM 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 return value of the external PROGRAM (note, this doesn't work within -# the PROGRAM field for the obvious reason.) -# %D - use the devfs style disk name for this device. -# For partitions, this will result in 'part%n' -# If this is not a partition, it will result in 'disc' -# +# 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. # Looking for scsi bus id 42:0:0:1 BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index c04fc7e8ef..6182f502bf 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -1,20 +1,5 @@ -# These rules are to try to emulate a devfs naming scheme in udev -# if there are any missing rules, please let the udev developers -# know. -# -# There are a number of modifiers that are allowed to be used in the -# a number 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' -# %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 return value of the external PROGRAM (note, this doesn't work within -# the PROGRAM field for the obvious reason.) -# %D - use the devfs style disk name for this device. -# For partitions, this will result in 'part%n' -# If this is not a partition, it will result in 'disc' -# +# 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. # ide block devices BUS="ide", id="0.0", NAME="ide/host0/bus0/target0/lun0/%D" diff --git a/namedev.c b/namedev.c index fdda039f59..b3b23521d6 100644 --- a/namedev.c +++ b/namedev.c @@ -196,16 +196,6 @@ static void apply_format(struct udevice *udev, unsigned char *string) strcat(pos, udev->kernel_number); dbg("substitute kernel number '%s'", udev->kernel_number); break; - case 'D': - if (strlen(udev->kernel_number) == 0) { - strcat(pos, "disc"); - dbg("substitute devfs disc"); - break; - } - strcat(pos, "part"); - strcat(pos, udev->kernel_number); - dbg("substitute devfs part '%s'", udev->kernel_number); - break; case 'm': sprintf(pos, "%u", udev->minor); dbg("substitute minor number '%u'", udev->minor); diff --git a/udev.8 b/udev.8 index 1ca42982ea..0421fee4e6 100644 --- a/udev.8 +++ b/udev.8 @@ -197,11 +197,6 @@ returned string. .B PROGRAM field for the obvious reason.) .TP -.B %D -Use the devfs style disk name for this device. -For partitions, this will result in 'part%n' -If this is not a partition, it will result in 'disc'. -.TP .B %% The '%' char itself. .P From 5e4f123888a30bcc2a9fc256ec00315387b2d240 Mon Sep 17 00:00:00 2001 From: "flamingice@sourmilk.net" Date: Thu, 15 Jan 2004 21:49:53 -0800 Subject: [PATCH 0426/4284] [PATCH] minor patch for devfs rules I've attached a patch that adds a few rules to udev.rules.devfs, making it look a little more like devfs on my system. (I have the sysfs patches from 2.6.1-rc1-mm2) I added rules for oss, misc, floppy, and input devices. The oss rules look like trouble with a wildcard at the end of each name, but I'm not sure how I can make it any better. Devfs has a bunch of other devices in the floppy directory for floppies formatted in unusual ways, but I don't see them in udev. Not that I ever used them, since they're usually automatically detected. --- etc/udev/udev.rules.devfs | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 6182f502bf..1a52425633 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -10,9 +10,12 @@ BUS="ide", id="1.1", NAME="ide/host0/bus1/target1/lun0/%D" # md block devices KERNEL="md[0-9]*", NAME="md/%n" +# floppy devices +KERNEL="fd[0-9]*", NAME="floppy/%n" + # tty devices -KERNEL="tty[0-9]*", NAME="vc/%n" -KERNEL="ttyS[0-9]*", NAME="tts/%n" +KERNEL="tty[0-9]*", NAME="vc/%n" +KERNEL="ttyS[0-9]*", NAME="tts/%n" KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" # vc devices @@ -43,8 +46,12 @@ KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" # misc -KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" -KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" @@ -54,10 +61,18 @@ KERNEL="midi[CD0-9]*", NAME="snd/%k" KERNEL="timer", NAME="snd/%k" KERNEL="seq", NAME="snd/%k" +# oss devices +KERNEL="audio*", NAME="sound/%k", SYMLINK="%k" +KERNEL="dmmidi", NAME="sound/%k", SYMLINK="%k" +KERNEL="dsp*", NAME="sound/%k", SYMLINK="%k" +KERNEL="midi*", NAME="sound/%k", SYMLINK="%k" +KERNEL="mixer*", NAME="sound/%k", SYMLINK="%k" +KERNEL="sequencer*", NAME="sound/%k", SYMLINK="%k" + # input devices -KERNEL="mice", NAME="input/%k" -KERNEL="mouse*", NAME="input/%k" -KERNEL="event*", NAME="input/%k" -KERNEL="js*", NAME="input/%k" -KERNEL="ts*", NAME="input/%k" +KERNEL="mice", NAME="input/%k" +KERNEL="mouse*", NAME="input/%k" +KERNEL="event*", NAME="input/%k" +KERNEL="js*", NAME="input/%k" +KERNEL="ts*", NAME="input/%k" From 54988802b795328ceba29480611102902e88f572 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 15 Jan 2004 21:53:20 -0800 Subject: [PATCH 0427/4284] [PATCH] add udev logging to info log On Thu, Jan 15, 2004 at 05:14:16AM +0100, Kay Sievers wrote: > On Wed, Jan 14, 2004 at 01:10:43PM -0800, Greg KH wrote: > > On Wed, Jan 14, 2004 at 02:34:26PM -0600, Clay Haapala wrote: > > > On Wed, 14 Jan 2004, Chris Friesen spake thusly: > > > > > > > > Maybe for ones with a matching rule, you could print something like: > > > > > > > > > > > Is the act of printing/syslogging a rule in an of itself? > > > > No, as currently the only way stuff ends up in the syslog is if > > DEBUG=true is used on the build line. > > > > But it's sounding like we might want to change that... :) > > How about this in the syslog after connect/disconnect? > > Jan 15 05:07:45 pim udev[28007]: configured rule in '/etc/udev/udev.rules' at line 17 applied, 'video*' becomes 'video/webcam%n' > Jan 15 05:07:45 pim udev[28007]: creating device node '/udev/video/webcam0' > Jan 15 05:07:47 pim udev[28015]: removing device node '/udev/video/webcam0' Here is a slightly better version. I've created a logging.h file and moved the debug macros from udev.h in there. If you type: 'make' - you will get a binary that prints one or two lines to syslog if a device node is created or deleted 'make LOG=false' - you get a binary that prints asolutely nothing 'make DEBUG=true' - the same as today, it will print all debug lines --- Makefile | 13 +++++++++-- logging.c | 6 ++--- logging.h | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ namedev.c | 14 +++++++----- namedev.h | 1 + namedev_parse.c | 2 ++ udev-add.c | 2 ++ udev-remove.c | 3 ++- udev.c | 1 + udev.h | 25 --------------------- udev_config.c | 1 + udevdb.c | 1 + 12 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 logging.h diff --git a/Makefile b/Makefile index 80c4908ccb..88c7cf0bc7 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,12 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# Set the following to `true' to make a debuggable build. +# Set the following to control the use of syslog +# Set it to `false' to remove all logging +LOG = true + +# Set the following to `true' to log the debug +# and make a unstripped, unoptimized binary. # Leave this set to `false' for production use. DEBUG = false @@ -104,6 +109,10 @@ else CFLAGS+=-pipe endif +ifeq ($(strip $(LOG)),true) + CFLAGS += -DLOG +endif + # if DEBUG is enabled, then we do not strip or optimize ifeq ($(strip $(DEBUG)),true) CFLAGS += $(WARNINGS) -O1 -g -DDEBUG -D_GNU_SOURCE @@ -216,7 +225,7 @@ $(LOCAL_CFG_DIR)/udev.conf: $(OBJS): $(GEN_HEADERS) -$(ROOT): $(OBJS) udev.h namedev.h udev_version.h udev_dbus.h udevdb.h klibc_fixups.h list.h +$(ROOT): $(OBJS) udev.h namedev.h udev_version.h udev_dbus.h udevdb.h klibc_fixups.h logging.h list.h $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) diff --git a/logging.c b/logging.c index 4815f39fdc..cf1da5e040 100644 --- a/logging.c +++ b/logging.c @@ -25,9 +25,9 @@ #include #include #include -#include "udev.h" -#ifdef DEBUG +#include "logging.h" + static int logging_init = 0; static unsigned char udev_logname[42]; @@ -54,5 +54,3 @@ int log_message(int level, const char *format, ...) va_end(args); return 1; } - -#endif diff --git a/logging.h b/logging.h new file mode 100644 index 0000000000..85016ad328 --- /dev/null +++ b/logging.h @@ -0,0 +1,60 @@ +/* + * udev.h + * + * Userspace devfs + * + * Copyright (C) 2003 Greg Kroah-Hartman + * 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. + * + * 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 LOGGING_H +#define LOGGING_H + +#ifdef LOG +#include +#define info(format, arg...) \ + do { \ + log_message (LOG_INFO , format , ## arg); \ + } while (0) +#else + #define info(format, arg...) do { } while (0) +#endif + +#ifdef DEBUG +#define dbg(format, arg...) \ + do { \ + log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + } while (0) +#else + #define dbg(format, arg...) do { } while (0) +#endif + +/* Parser needs it's own debugging statement, we usually don't care about this at all */ +#ifdef DEBUG_PARSER +#define dbg_parse(format, arg...) \ + do { \ + log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + } while (0) +#else + #define dbg_parse(format, arg...) do { } while (0) +#endif + + +extern int log_message (int level, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); + +#endif diff --git a/namedev.c b/namedev.c index b3b23521d6..137446e255 100644 --- a/namedev.c +++ b/namedev.c @@ -36,6 +36,7 @@ #include "list.h" #include "udev.h" #include "udev_version.h" +#include "logging.h" #include "namedev.h" #include "libsysfs/libsysfs.h" #include "klibc_fixups.h" @@ -285,12 +286,12 @@ static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) /* sleep to give the kernel a chance to create the file */ sleep(1); } - dbg("Timed out waiting for '%s' file, continuing on anyway...", b->file); + dbg("timed out waiting for '%s' file, continuing on anyway...", b->file); goto exit; } b++; } - dbg("Did not find bus type '%s' on list of bus_id_files, contact greg@kroah.com", sysfs_device->bus); + dbg("did not find bus type '%s' on list of bus_id_files, contact greg@kroah.com", sysfs_device->bus); exit: return; /* here to prevent compiler warning... */ } @@ -534,7 +535,7 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de if (sysfs_device != NULL) goto device_found; } - dbg("Timed out waiting for device symlink, continuing on anyway..."); + dbg("timed out waiting for device symlink, continuing on anyway..."); device_found: /* We have another issue with just the wait above - the sysfs part of @@ -559,10 +560,10 @@ device_found: if (sysfs_device->bus[0] != '\0') goto bus_found; } - dbg("Timed out waiting to find the device bus, continuing on anyway\n"); + dbg("timed out waiting to find the device bus, continuing on anyway"); goto exit; bus_found: - dbg("Device %s is registered with bus %s\n", + dbg("device %s is registered with bus '%s'", sysfs_device->name, sysfs_device->bus); } exit: @@ -694,7 +695,8 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } /* Yup, this rule belongs to us! */ - dbg("found matching rule, '%s' becomes '%s'", dev->kernel, dev->name); + info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", + udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); strfieldcpy(udev->name, dev->name); strfieldcpy(udev->symlink, dev->symlink); goto found; diff --git a/namedev.h b/namedev.h index f5b63a8805..42b1e6c1a0 100644 --- a/namedev.h +++ b/namedev.h @@ -65,6 +65,7 @@ struct config_device { char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; + int config_line; }; struct perm_device { diff --git a/namedev_parse.c b/namedev_parse.c index 0712c3b447..a17c02e395 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -36,6 +36,7 @@ #include #include "udev.h" +#include "logging.h" #include "namedev.h" static int add_config_dev(struct config_device *new_dev) @@ -249,6 +250,7 @@ int namedev_init_rules(void) goto error; } + dev.config_line = lineno; retval = add_config_dev(&dev); if (retval) { dbg("add_config_dev returned with error %d", retval); diff --git a/udev-add.c b/udev-add.c index 802d85b5b0..9aa8bdb3e9 100644 --- a/udev-add.c +++ b/udev-add.c @@ -37,6 +37,7 @@ #include "udev.h" #include "udev_version.h" #include "udev_dbus.h" +#include "logging.h" #include "namedev.h" #include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -141,6 +142,7 @@ static int create_node(struct udevice *dev) if (strrchr(dev->name, '/')) create_path(filename); + info("creating device node '%s'", filename); dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); retval = mknod(filename, dev->mode, res); if (retval) diff --git a/udev-remove.c b/udev-remove.c index c5de6c823f..9db63ed93e 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -31,6 +31,7 @@ #include "udev.h" #include "udev_version.h" #include "udev_dbus.h" +#include "logging.h" #include "namedev.h" #include "udevdb.h" #include "libsysfs/libsysfs.h" @@ -73,7 +74,7 @@ static int delete_node(struct udevice *dev) strncpy(filename, udev_root, sizeof(filename)); strncat(filename, dev->name, sizeof(filename)); - dbg("unlinking node '%s'", filename); + info("removing device node '%s'", filename); retval = unlink(filename); if (retval) { dbg("unlink(%s) failed with error '%s'", diff --git a/udev.c b/udev.c index b395be2abb..b872f42494 100644 --- a/udev.c +++ b/udev.c @@ -34,6 +34,7 @@ #include "udev.h" #include "udev_version.h" #include "udev_dbus.h" +#include "logging.h" #include "namedev.h" #include "udevdb.h" #include "libsysfs/libsysfs.h" diff --git a/udev.h b/udev.h index 678731c7d1..90aa823939 100644 --- a/udev.h +++ b/udev.h @@ -26,30 +26,6 @@ #include "libsysfs/libsysfs.h" #include -#ifdef DEBUG -#include -#define dbg(format, arg...) \ - do { \ - log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ - } while (0) -#else - #define dbg(format, arg...) do { } while (0) -#endif - -/* Parser needs it's own debugging statement, we usually don't care about this at all */ -#ifdef DEBUG_PARSER -#define dbg_parse(format, arg...) \ - do { \ - log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ - } while (0) -#else - #define dbg_parse(format, arg...) do { } while (0) -#endif - - -extern int log_message (int level, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - #define COMMENT_CHARACTER '#' #define NAME_SIZE 100 @@ -71,7 +47,6 @@ struct udevice { unsigned char program_result[NAME_SIZE]; unsigned char kernel_number[NAME_SIZE]; unsigned char kernel_name[NAME_SIZE]; - }; #define strfieldcpy(to, from) \ diff --git a/udev_config.c b/udev_config.c index 074bd7b35b..44b5767b85 100644 --- a/udev_config.c +++ b/udev_config.c @@ -34,6 +34,7 @@ #include "udev.h" #include "udev_version.h" +#include "logging.h" #include "namedev.h" #include "libsysfs/libsysfs.h" diff --git a/udevdb.c b/udevdb.c index 8d077ea94f..2d99f51d0e 100644 --- a/udevdb.c +++ b/udevdb.c @@ -35,6 +35,7 @@ #include "udev_version.h" #include "udev.h" +#include "logging.h" #include "namedev.h" #include "udevdb.h" #include "tdb/tdb.h" From 0523018487a60ad817556af30632a212ad3351e0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 15 Jan 2004 22:00:58 -0800 Subject: [PATCH 0428/4284] [PATCH] clean up the logging patch a bit to make the option more like the other options. Also documented it and added it to the .spec file. --- Makefile | 4 ++-- README | 22 ++++++++++++++++------ logging.h | 2 +- udev.spec | 9 +++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 88c7cf0bc7..f19354fb05 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ # Set the following to control the use of syslog # Set it to `false' to remove all logging -LOG = true +USE_LOG = true # Set the following to `true' to log the debug # and make a unstripped, unoptimized binary. @@ -109,7 +109,7 @@ else CFLAGS+=-pipe endif -ifeq ($(strip $(LOG)),true) +ifeq ($(strip $(USE_LOG)),true) CFLAGS += -DLOG endif diff --git a/README b/README index 123fce6a1b..26032c35dc 100644 --- a/README +++ b/README @@ -30,18 +30,28 @@ To use: Note: There are a number of different flags that you can use when building udev. They are as follows: - prefix - set this to the default root that you want udev to be + prefix + set this to the default root that you want udev to be installed into. This works just like the 'configure --prefix' script does. Default value is ''. Only override this if you really know what you are doing. - USE_KLIBC - if set to 'true', udev is built and linked against the included - version of klibc. Default value is 'false'. - DEBUG - if set to 'true', debugging messages will be sent to the syslog - as udev is run. Default value is 'false'. - USE_DBUS - if set to 'true', DBUS messages will be sent everytime udev + USE_KLIBC + if set to 'true', udev is built and linked against the + included version of klibc. Default value is 'false'. + USE_LOG + if set to 'true', udev will emit messages to the syslog when + it creates or removes device nodes. This is helpful to see + what udev is doing. This is enabled by default. Note, if you + are building udev against klibc it is recommended that you + disable this option (due to klibc's syslog implementation.) + USE_DBUS + if set to 'true', DBUS messages will be sent everytime udev creates or removes a device node. This requires that DBUS development headers and libraries be present on your system to build properly. Default value is 'false'. + DEBUG + if set to 'true', debugging messages will be sent to the syslog + as udev is run. Default value is 'false'. So, if you want to build udev using klibc with debugging messages, you would do: diff --git a/logging.h b/logging.h index 85016ad328..1f2126839b 100644 --- a/logging.h +++ b/logging.h @@ -1,5 +1,5 @@ /* - * udev.h + * logging.h * * Userspace devfs * diff --git a/udev.spec b/udev.spec index 07331807ef..575e3cdf60 100644 --- a/udev.spec +++ b/udev.spec @@ -5,6 +5,12 @@ # it probably is not where you want it to be. %define klibc 1 +# if we want to have logging support in or not. +# 0 - no logging support +# 1 - logging support +# Note, it is not recommend if you use klibc to enable logging. +%define log 0 + # if we want to build DBUS support in or not. # 0 - no DBUS support # 1 - DBUS support @@ -45,6 +51,9 @@ make CC="gcc $RPM_OPT_FLAGS" \ %if %{klibc} USE_KLIBC=true \ %endif +%if %{log} + USE_LOG=true \ +%endif %if %{dbus} USE_DBUS=true \ %endif From eb7a964a7c66e5aff8147026a60c99258454b612 Mon Sep 17 00:00:00 2001 From: "hannal@us.ibm.com" Date: Fri, 16 Jan 2004 00:22:56 -0800 Subject: [PATCH 0429/4284] [PATCH] small cut n paste error fix --- namedev_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev_parse.c b/namedev_parse.c index a17c02e395..546d767aed 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -324,7 +324,7 @@ int namedev_init_permissions(void) dbg("cannot parse line '%s'", line); continue; } - strncpy(dev.group, temp2, sizeof(dev.owner)); + strncpy(dev.group, temp2, sizeof(dev.group)); if (!temp) { dbg("cannot parse line: %s", line); From e996d97835c8d0728a9d4880e9e1f8f285cadf4b Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Fri, 16 Jan 2004 22:03:50 -0800 Subject: [PATCH 0430/4284] [PATCH] update udev scsi_id to scsi_id 0.3 --- extras/scsi_id/ChangeLog | 39 ++++++++++++++++++++++-- extras/scsi_id/Makefile | 29 ++++++++++++------ extras/scsi_id/README | 7 +---- extras/scsi_id/TODO | 2 +- extras/scsi_id/release-notes | 39 ++++++++++++++++++++++++ extras/scsi_id/scsi_id.c | 57 +++++++++++++++++------------------ extras/scsi_id/scsi_id.config | 7 +++-- extras/scsi_id/scsi_id.h | 21 +++++-------- extras/scsi_id/scsi_serial.c | 21 ++++++------- 9 files changed, 147 insertions(+), 75 deletions(-) create mode 100644 extras/scsi_id/release-notes diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog index 7f2317723d..7032dfd07f 100644 --- a/extras/scsi_id/ChangeLog +++ b/extras/scsi_id/ChangeLog @@ -1,3 +1,36 @@ +2004-jan-15: + * Makefile: Version 0.3 + +2004-jan-13: + * scsi_id.c, Makefile: Fix prefix usage with scsi_id.config. + +2004-jan-13: + * scsi_id.config: Clean up some comment entries. + +2004-jan-13: + * Makefile: Install the sample scsi_id.config file. + +2004-jan-13: + * Makefile: Use DESTDIR in all install/uninstall rules, per + problem reported by Svetoslav Slavtchev. + +2004-jan-12: + * scsi_id.h, scsi_id.c, scsi_serial.c: Fix to work with current + sysfs 0.4, based on patch from Dan Stekloff, but uses + sysfs_read_attribute_value instead of + sysfs_get_value_from_attributes. + +2004-jan-08: + * scsi_id.c: SYSFS_BUS_DIR was replaced with SYSFS_BUS_NAME. + +2004-jan-08: + * scsi_id.c: Must now use sysfs_open_class_device_path instead of the + previous sysfs_open_class_device. + +2003-dec-07: + * Makefile: patch from Olaf Hering remove DEBUG and + add --fno-builtin + 2003-dec-05: * Makefile, scsi_id.8: Add a man page. @@ -53,12 +86,12 @@ is no support for that in klibc. 2003-nov-17: - * scsi_id.c: Patch from Brian King: check result of setting model, - not vendor in per_dev_options. + * scsi_id.c: Patch from Brian King : check + result of setting model, not vendor in per_dev_options. 2003-nov-03: * scsi_id.c, scsi_serial.c: Use new and correct path to libsysfs.h. 2003-nov-03: - * scsi_id.h: Fix scsi_id.h so var args in marcros works ok with + * scsi_id.h: Fix scsi_id.h so var args in macros works ok with older gcc. diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index ead205682a..abf48895ad 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,9 +14,10 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.2 +SCSI_ID_VERSION=0.3 prefix = +etcdir = ${prefix}/etc sbindir = ${prefix}/sbin mandir = ${prefix}/usr/share/man @@ -27,7 +28,7 @@ INSTALL_DATA = ${INSTALL} -m 644 # Note some of the variables used here are set when built under udev, and # otherwise might not be set. -override CFLAGS+=-DSCSI_ID_VERSION=\"$(SCSI_ID_VERSION)\" $(DEBUG) -Wall +override CFLAGS+=-Wall -fno-builtin PROG=scsi_id SYSFS=-lsysfs @@ -39,25 +40,35 @@ SYSFS=-lsysfs # LDFLAGS=$(STRIP) LD=$(CC) -OBJS= scsi_id.o \ - scsi_serial.o \ +OBJS= scsi_id.o scsi_serial.o all: $(PROG) # XXX use a compressed man page? install: all - $(INSTALL_PROGRAM) -D $(PROG) $(sbindir)/$(PROG) + $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(sbindir)/$(PROG) $(INSTALL_DATA) -D scsi_id.8 $(DESTDIR)$(mandir)/man8/scsi_id.8 + @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 uninstall: - -rm $(sbindir)/$(PROG) - -rm $(mandir)/man8/scsi_id.8 + -rm $(DESTDIR)$(sbindir)/$(PROG) + -rm $(DESTDIR)$(mandir)/man8/scsi_id.8 + -rm $(DESTDIR)$(etcdir)/scsi_id.config -$(OBJS): scsi_id.h scsi.h +GEN_HEADER=scsi_id_version.h + +scsi_id_version.h: + @echo "/* This file is auto-generated by the Makefile */" > $@ + @echo \#define SCSI_ID_VERSION \"$(SCSI_ID_VERSION)\" >> $@ + @echo \#define SCSI_ID_CONFIG_FILE \"$(etcdir)/scsi_id.config\" >> $@ +$(OBJS): scsi_id.h scsi.h scsi_id_version.h clean: - rm -f $(PROG) $(OBJS) + rm -f $(PROG) $(OBJS) $(GEN_HEADER) $(PROG): $(OBJS) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) diff --git a/extras/scsi_id/README b/extras/scsi_id/README index 4281c318a2..97af517304 100644 --- a/extras/scsi_id/README +++ b/extras/scsi_id/README @@ -7,12 +7,7 @@ Requires: - Linux kernel 2.6 - - libsysfs - -No man page yet. - -libsysfs 0_2_0 was not installing libsysfs.h or dlist.h, manually copy -those files to /usr/include/sys before compiling. + - sysfsutils 0.4 Build via make and make install. diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO index 5d020c276a..dde5c84a67 100644 --- a/extras/scsi_id/TODO +++ b/extras/scsi_id/TODO @@ -1,4 +1,4 @@ -- add information abou the config file to the man page +- add information about the config file to the man page - change so non-KLIBC builds under udev don't use /usr/include/sysfs, but instead use the sysfs included with udev (needs udev change and/or diff --git a/extras/scsi_id/release-notes b/extras/scsi_id/release-notes new file mode 100644 index 0000000000..7ef12a25db --- /dev/null +++ b/extras/scsi_id/release-notes @@ -0,0 +1,39 @@ +Version 0.3 of scsi_id is available at: + +http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.3.tar.gz + +scsi_id is a program to generate a SCSI unique identifier for a given SCSI +device. + +It is primarily for use with udev callout config entries. It can also be +used for automatic multi-path configuration or device mapper configuration. + +Version 0.3 requires: + +- Linux kernel 2.6 +- libsysfs 0.4.0 + +Major changes since the last release: + + - Changes to work with libsysfs 0.4.0 + +All changes: + + - fix "prefix" usage for path to scsi_id.config + + - install the sample scsi_id.config file. + + - Use DESTDIR in all install/uninstall rules, per problem reported + by Svetoslav Slavtchev. + + - Fix to work with current sysfs 0.4, based on patch from Dan + Stekloff, but uses sysfs_read_attribute_value instead of + sysfs_get_value_from_attributes. + + - SYSFS_BUS_DIR was replaced with SYSFS_BUS_NAME. + + - Must now use sysfs_open_class_device_path instead of the + previous sysfs_open_class_device. + + - patch from Olaf Hering remove DEBUG and + add --fno-builtin diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 6bb41132de..75a342bb12 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -40,6 +40,7 @@ #else #include #endif +#include "scsi_id_version.h" #include "scsi_id.h" #ifndef SCSI_ID_VERSION @@ -53,8 +54,6 @@ #define TMP_DIR "/tmp" #define TMP_PREFIX "scsi" -#define CONFIG_FILE "/etc/scsi_id.config" - static const char short_options[] = "bc:d:ef:gip:s:vV"; /* * Just duplicate per dev options. @@ -67,7 +66,7 @@ static int all_good; static char *default_callout; static int dev_specified; static int sys_specified; -static char config_file[MAX_NAME_LEN] = CONFIG_FILE; +static char config_file[MAX_NAME_LEN] = SCSI_ID_CONFIG_FILE; static int display_bus_id; static int default_page_code; static int use_stderr; @@ -102,6 +101,18 @@ void log_message (int level, const char *format, ...) return; } +int sysfs_get_attr(const char *devpath, const char *attr, char *value, + size_t bufsize) +{ + char attr_path[SYSFS_PATH_MAX]; + + strncpy(attr_path, devpath, SYSFS_PATH_MAX); + strncat(attr_path, "/", SYSFS_PATH_MAX); + strncat(attr_path, attr, SYSFS_PATH_MAX); + dprintf("%s\n", attr_path); + return sysfs_read_attribute_value(attr_path, value, SYSFS_NAME_LEN); +} + static int sysfs_get_actual_dev(const char *sysfs_path, char *dev, int len) { dprintf("%s\n", sysfs_path); @@ -153,34 +164,22 @@ static int sysfs_is_bus(const char *sysfs_path, const char *bus) static int get_major_minor(const char *devpath, int *major, int *minor) { - struct sysfs_class_device *class_dev; - char dev_value[SYSFS_NAME_LEN]; - char *dev; + char dev_value[MAX_ATTR_LEN]; - dprintf("%s\n", devpath); - class_dev = sysfs_open_class_device_path(devpath); - if (!class_dev) { - log_message(LOG_WARNING, "open class %s failed: %s\n", devpath, - strerror(errno)); - return -1; - } - - dev = sysfs_get_attr(class_dev, "dev"); - if (dev) - strncpy(dev_value, dev, SYSFS_NAME_LEN); - sysfs_close_class_device(class_dev); - if (!dev) { + if (sysfs_get_attr(devpath, "dev", dev_value, MAX_ATTR_LEN)) { /* * XXX This happens a lot, since sg has no dev attr. - * Someday change this back to a LOG_WARNING. + * And now sysfsutils does not set a meaningful errno + * value. Someday change this back to a LOG_WARNING. + * And if sysfsutils changes, check for ENOENT and handle + * it separately. */ log_message(LOG_DEBUG, "%s could not get dev attribute: %s\n", devpath, strerror(errno)); return -1; } - dev = NULL; - dprintf("dev %s", dev_value); /* dev_value has a trailing \n */ + dprintf("dev value %s", dev_value); /* dev_value has a trailing \n */ if (sscanf(dev_value, "%u:%u", major, minor) != 2) { log_message(LOG_WARNING, "%s: invalid dev major/minor\n", devpath); @@ -547,8 +546,8 @@ static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, int retval; int newargc; char **newargv = NULL; - char *vendor; - char *model; + char vendor[MAX_ATTR_LEN]; + char model[MAX_ATTR_LEN]; int option; *good_bad = all_good; @@ -558,16 +557,14 @@ static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, else callout[0] = '\0'; - vendor = sysfs_get_attr(scsi_dev, "vendor"); - if (!vendor) { - log_message(LOG_WARNING, "%s: no vendor attribute\n", + if (sysfs_get_attr(scsi_dev->path, "vendor", vendor, MAX_ATTR_LEN)) { + log_message(LOG_WARNING, "%s: cannot get vendor attribute\n", scsi_dev->name); return -1; } - model = sysfs_get_attr(scsi_dev, "model"); - if (!model) { - log_message(LOG_WARNING, "%s: no model attribute\n", + if (sysfs_get_attr(scsi_dev->path, "model", model, MAX_ATTR_LEN)) { + log_message(LOG_WARNING, "%s: cannot get model attribute\n", scsi_dev->name); return -1; } diff --git a/extras/scsi_id/scsi_id.config b/extras/scsi_id/scsi_id.config index 4fdb89e28a..f3fc4b3fda 100644 --- a/extras/scsi_id/scsi_id.config +++ b/extras/scsi_id/scsi_id.config @@ -21,7 +21,9 @@ # vendor=string[,model=string],options= # -# If you normally don't need id's, black list everyone: +# If you normally don't need scsi id's, or might be attaching devices of +# an unknown functionality, black list everyone. This is the default +# behaviour (if no -b or -g is specified). # options=-b @@ -30,7 +32,8 @@ options=-b # vendor=someone, model=nicedrive, options=-g -# If you have all good devices on your system use, mark all as good: +# If you all the scsi devices are your system support valid id's, remove +# the -b line above, and mark all devices as good: ## options=-g diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index cb27e88a5f..573a2b60d7 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -27,6 +27,12 @@ #define MAX_NAME_LEN 72 #define OFFSET (2 * sizeof(unsigned int)) +/* + * 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. @@ -39,19 +45,8 @@ */ #define MAX_BUFFER_LEN 256 -static inline char *sysfs_get_attr(struct sysfs_class_device *dev, - const char *attr) -{ - struct dlist *attributes = NULL; - - attributes = sysfs_get_classdev_attributes(dev); - - if (attributes == NULL) - return NULL; - - return sysfs_get_value_from_attributes(attributes, attr); -} - +extern int sysfs_get_attr(const char *devpath, const char *attr, char *value, + size_t bufsize); extern int scsi_get_serial (struct sysfs_class_device *scsi_dev, const char *devname, int page_code, char *serial, int len); diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 18cd290817..80a1d51635 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -385,7 +385,7 @@ static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, char *buffer, int len) { int retval; - char *vendor; + char vendor[MAX_ATTR_LEN]; memset(buffer, 0, len); retval = scsi_inquiry(scsi_dev, fd, 1, 0x0, buffer, len); @@ -415,9 +415,10 @@ static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, * If the vendor id appears in the page assume the page is * invalid. */ - vendor = sysfs_get_attr(scsi_dev, "vendor"); - if (!vendor) { - log_message(LOG_WARNING, "%s: no vendor attribute\n", + if (sysfs_get_attr(scsi_dev->path, "vendor", vendor, + MAX_ATTR_LEN)) { + log_message(LOG_WARNING, + "%s: cannot get model attribute\n", scsi_dev->name); return 1; } @@ -437,12 +438,11 @@ static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, static int prepend_vendor_model(struct sysfs_class_device *scsi_dev, char *serial) { - char *attr; + char attr[MAX_ATTR_LEN]; int ind; - attr = sysfs_get_attr(scsi_dev, "vendor"); - if (!attr) { - log_message(LOG_WARNING, "%s: no vendor attribute\n", + if (sysfs_get_attr(scsi_dev->path, "vendor", attr, MAX_ATTR_LEN)) { + log_message(LOG_WARNING, "%s: cannot get vendor attribute\n", scsi_dev->name); return 1; } @@ -454,9 +454,8 @@ static int prepend_vendor_model(struct sysfs_class_device *scsi_dev, if (serial[ind] == '\n') serial[ind] = '\0'; - attr = sysfs_get_attr(scsi_dev, "model"); - if (!attr) { - log_message(LOG_WARNING, "%s: no model attribute\n", + if (sysfs_get_attr(scsi_dev->path, "model", attr, MAX_ATTR_LEN)) { + log_message(LOG_WARNING, "%s: cannot get model attribute\n", scsi_dev->name); return 1; } From 778050914360dfb469817e12a1080bbf98422ef2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 19 Jan 2004 19:39:28 -0800 Subject: [PATCH 0431/4284] [PATCH] udev - kill %D from udev-test.pl Kill the two tests with %D. --- test/udev-test.pl | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 5e5756b660..b7013e4bde 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -261,24 +261,6 @@ EOF conf => < "devfs disk naming substitution", - subsys => "block", - devpath => "block/sda", - expected => "lun0/disc" , - conf => < "devfs disk naming substitution", - subsys => "block", - devpath => "block/sda/sda2", - expected => "lun0/part2" , - conf => < Date: Mon, 19 Jan 2004 19:40:32 -0800 Subject: [PATCH 0432/4284] [PATCH] udev - reverse user query options Here we get the ability to query with the name of the node instead of the device path. It uses a linear search over the whole database. kay@pim:~/src/udev.kay$ ./udev -q path -n video/webcam0 /class/video4linux/video0 New version, with better function return codes for error handling. --- udev.8 | 7 ++-- udev.c | 104 +++++++++++++++++++++++++++++++++++++------------------ udevdb.c | 49 ++++++++++++++++++++++---- udevdb.h | 3 +- 4 files changed, 120 insertions(+), 43 deletions(-) diff --git a/udev.8 b/udev.8 index 0421fee4e6..ff89e435ff 100644 --- a/udev.8 +++ b/udev.8 @@ -50,10 +50,13 @@ will be prepended. .BI -q " query_type" Query the database for specified value of a created device node. Valid types are: -.BR name ", " symlink ", " owner " or " group . +.BR name ", " symlink ", " owner " , " group " or " path. .TP .BI -p " sysfs_path" -Specify the sysfs path needed for the query. +Specify the sysfs path of the device to query. +.TP +.BI -n " name" +Specify the name of the node for the device to query. .TP .B -d Dump the whole database. diff --git a/udev.c b/udev.c index b872f42494..3b701ac26f 100644 --- a/udev.c +++ b/udev.c @@ -83,7 +83,8 @@ static inline char *get_seqnum(void) return seqnum; } -static void print_record(char *path, struct udevice *dev) +/* callback for database dump */ +static int print_record(char *path, struct udevice *dev) { printf("P: %s\n", path); printf("N: %s\n", dev->name); @@ -91,11 +92,13 @@ static void print_record(char *path, struct udevice *dev) printf("O: %s\n", dev->owner); printf("G: %s\n", dev->group); printf("\n"); + return 0; } enum query_type { NONE, NAME, + PATH, SYMLINK, OWNER, GROUP @@ -103,7 +106,7 @@ enum query_type { static inline int udev_user(int argc, char **argv) { - static const char short_options[] = "dp:q:rVh"; + static const char short_options[] = "dn:p:q:rVh"; int option; int retval = -EINVAL; struct udevice dev; @@ -111,6 +114,7 @@ static inline int udev_user(int argc, char **argv) enum query_type query = NONE; char result[NAME_SIZE] = ""; char path[NAME_SIZE] = ""; + char name[NAME_SIZE] = ""; /* get command line options */ while (1) { @@ -120,6 +124,11 @@ static inline int udev_user(int argc, char **argv) dbg("option '%c'", option); switch (option) { + case 'n': + dbg("udev name: %s\n", optarg); + strfieldcpy(name, optarg); + break; + case 'p': dbg("udev path: %s\n", optarg); strfieldcpy(path, optarg); @@ -148,6 +157,11 @@ static inline int udev_user(int argc, char **argv) break; } + if (strcmp(optarg, "path") == 0) { + query = PATH; + break; + } + printf("unknown query type\n"); return -EINVAL; @@ -161,7 +175,7 @@ static inline int udev_user(int argc, char **argv) printf("unable to open udev database\n"); return -EACCES; } - retval = udevdb_dump(print_record); + retval = udevdb_call_foreach(print_record); udevdb_exit(); return retval; @@ -179,44 +193,63 @@ static inline int udev_user(int argc, char **argv) /* process options */ if (query != NONE) { - if (path[0] == '\0') { - printf("query needs device path specified\n"); - return -EINVAL; - } - retval = udevdb_open_ro(); if (retval != 0) { printf("unable to open udev database\n"); return -EACCES; } - retval = udevdb_get_dev(path, &dev); - if (retval == 0) { - switch(query) { - case NAME: - if (root) - strfieldcpy(result, udev_root); - strncat(result, dev.name, sizeof(result)); - break; - case SYMLINK: - strfieldcpy(result, dev.symlink); - break; - - case GROUP: - strfieldcpy(result, dev.group); - break; - - case OWNER: - strfieldcpy(result, dev.owner); - break; - - default: - break; + if (path[0] != '\0') { + retval = udevdb_get_dev(path, &dev); + if (retval != 0) { + printf("device not found in database\n"); + goto exit; } - printf("%s\n", result); - } else { - printf("device not found in udev database\n"); + goto print; } + + if (name[0] != '\0') { + retval = udevdb_get_dev_byname(name, path, &dev); + if (retval != 0) { + printf("device not found in database\n"); + goto exit; + } + goto print; + } + + printf("query needs device path(-p) or node name(-n) specified\n"); + goto exit; + +print: + switch(query) { + case NAME: + if (root) + strfieldcpy(result, udev_root); + strncat(result, dev.name, sizeof(result)); + break; + + case SYMLINK: + strfieldcpy(result, dev.symlink); + break; + + case GROUP: + strfieldcpy(result, dev.group); + break; + + case OWNER: + strfieldcpy(result, dev.owner); + break; + + case PATH: + strfieldcpy(result, path); + break; + + default: + goto exit; + } + printf("%s\n", result); + +exit: udevdb_exit(); return retval; } @@ -227,13 +260,16 @@ static inline int udev_user(int argc, char **argv) } help: - printf("Usage: [-pqrdVh]\n" + printf("Usage: [-npqrdVh]\n" " -q TYPE query database for the specified value:\n" " 'name' name of device node\n" " 'symlink' pointing to node\n" " 'owner' of node\n" " 'group' of node\n" + " 'path' sysfs device path\n" " -p PATH sysfs device path used for query\n" + " -n NAME node name used for query\n" + "\n" " -r print udev root\n" " -d dump whole database\n" " -V print udev version\n" diff --git a/udevdb.c b/udevdb.c index 2d99f51d0e..c4e064fc11 100644 --- a/udevdb.c +++ b/udevdb.c @@ -143,25 +143,62 @@ int udevdb_open_ro(void) return 0; } -void (*user_record_callback) (char *path, struct udevice *dev); +static int (*user_record_callback) (char *path, struct udevice *dev); static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { - user_record_callback((char*) key.dptr, (struct udevice*) dbuf.dptr); - return 0; + return user_record_callback((char*) key.dptr, (struct udevice*) dbuf.dptr); } /** - * udevdb_dump: dumps whole database by passing record data to user function + * udevdb_call_foreach: dumps whole database by passing record data to user function * @user_record_handler: user function called for every record in the database */ -int udevdb_dump(void (*user_record_handler) (char *path, struct udevice *dev)) +int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev)) { + int retval = 0; + if (user_record_handler == NULL) { dbg("invalid user record handling function"); return -EINVAL; } user_record_callback = user_record_handler; - tdb_traverse(udevdb, traverse_callback, NULL); + retval = tdb_traverse(udevdb, traverse_callback, NULL); + if (retval < 0) + return -ENODEV; + else + return 0; +} + +static struct udevice *find_dev; +static char *find_path; +static const char *find_name; +static int find_found; + +static int find_device_by_name(char *path, struct udevice *dev) +{ + if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { + memcpy(find_dev, dev, sizeof(*find_dev)); + strncpy(find_path, path, NAME_SIZE); + find_found = 1; + /* stop search */ + return 1; + } return 0; } + +/** + * udevdb_get_dev_byname: search device with given name by traversing the whole database + */ +int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev) +{ + find_found = 0; + find_path = path; + find_dev = dev; + find_name = name; + udevdb_call_foreach(find_device_by_name); + if (find_found == 1) + return 0; + else + return -1; +} diff --git a/udevdb.h b/udevdb.h index a0e5338265..6eaeb25668 100644 --- a/udevdb.h +++ b/udevdb.h @@ -12,10 +12,11 @@ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); extern int udevdb_open_ro(void); -extern int udevdb_dump(void (*user_record_handler) (char *path, struct udevice *dev)); +extern int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev)); extern int udevdb_add_dev(const char *path, const struct udevice *dev); extern int udevdb_get_dev(const char *path, struct udevice *dev); extern int udevdb_delete_dev(const char *path); +extern int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev); #endif /* _UDEVDB_H_ */ From 74c73ef994f3ea8d013c33fe7be73e0c0c86977b Mon Sep 17 00:00:00 2001 From: "hannal@us.ibm.com" Date: Mon, 19 Jan 2004 19:42:42 -0800 Subject: [PATCH 0433/4284] [PATCH] set default owner/group in db. This patch fixes a bug where the udev database stored empty strings for Owner and Group if they were default. This patch stores the default value into the database if not set otherwise. See example output: crw------- 1 root root 4, 65 Jan 16 11:13 ttyS1 P: /class/tty/ttyS1 N: ttyS1 S: O: root G: root This is a bit of a hack. However, until udev supports setting the o/g values they will be root/root anyway so the database might as well reflect the truth instead of empty strings. --- namedev.c | 20 ++++++++++++++++++-- udev.h | 2 ++ udev_config.c | 4 ++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 137446e255..e39207e6a7 100644 --- a/namedev.c +++ b/namedev.c @@ -151,6 +151,22 @@ static mode_t get_default_mode(struct sysfs_class_device *class_dev) return mode; } +static char * get_default_owner(void) +{ + if (strlen(default_owner_str) == 0) { + strncpy(default_owner_str, "root", OWNER_SIZE); + } + return default_owner_str; +} + +static char * get_default_group(void) +{ + if (strlen(default_group_str) == 0) { + strncpy(default_group_str, "root", GROUP_SIZE); + } + return default_group_str; +} + static void apply_format(struct udevice *udev, unsigned char *string) { char temp[NAME_SIZE]; @@ -720,8 +736,8 @@ done: } else { /* no matching perms found :( */ udev->mode = get_default_mode(class_dev); - udev->owner[0] = 0x00; - udev->group[0] = 0x00; + strncpy(udev->owner, get_default_owner(), OWNER_SIZE); + strncpy(udev->group, get_default_group(), GROUP_SIZE); } dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); diff --git a/udev.h b/udev.h index 90aa823939..963f8d2516 100644 --- a/udev.h +++ b/udev.h @@ -68,5 +68,7 @@ extern char udev_permissions_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; extern char default_mode_str[NAME_MAX]; +extern char default_owner_str[OWNER_SIZE]; +extern char default_group_str[GROUP_SIZE]; #endif diff --git a/udev_config.c b/udev_config.c index 44b5767b85..d262f2af07 100644 --- a/udev_config.c +++ b/udev_config.c @@ -46,6 +46,8 @@ char udev_permissions_filename[PATH_MAX+NAME_MAX]; char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; char default_mode_str[NAME_MAX]; +char default_owner_str[OWNER_SIZE]; +char default_group_str[GROUP_SIZE]; static void init_variables(void) @@ -117,6 +119,8 @@ static int parse_config_file(void) set_var("udev_rules", udev_rules_filename); set_var("udev_permissions", udev_permissions_filename); set_var("default_mode", default_mode_str); + set_var("default_owner", default_owner_str); + set_var("default_group", default_group_str); } dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, lineno, temp - line, temp); From 765cbd97599d943adc73d03f4c91bd7cf7ef7fab Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 19 Jan 2004 19:44:24 -0800 Subject: [PATCH 0434/4284] [PATCH] set default owner/group in db - update I've edited the man page today, so this is alreay included :) Also a few more trivials: o added the defaults to udev.conf.in o removed class_dev from get_default_mode(), to match with Hanna's o changed size of mode_str to MODE_SIZE o changed a few char compares from from 0x00 to '\0' --- etc/udev/udev.conf.in | 10 +++++++++- namedev.c | 4 ++-- udev-add.c | 18 +++++++++--------- udev.8 | 18 ++++++++++++++++++ udev.h | 3 ++- udev_config.c | 2 +- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index d06b0b0698..f9a60ab3c8 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -17,7 +17,15 @@ udev_rules="/etc/udev/udev.rules" # udev_permissions - The name and location of the udev permission file udev_permissions="/etc/udev/udev.permissions" -# default_mode - set the default mode for all nodes that have no +# default_mode - set the default mode for all nodes that have no # explicit match in the permissions file default_mode="0600" +# default_owner - set the default owner for all nodes that have no +# explicit match in the permissions file +default_owner="root" + +# default_group - set the default group for all nodes that have no +# explicit match in the permissions file +default_group="root" + diff --git a/namedev.c b/namedev.c index e39207e6a7..7fd69f7778 100644 --- a/namedev.c +++ b/namedev.c @@ -141,7 +141,7 @@ static struct perm_device *find_perm(char *name) return NULL; } -static mode_t get_default_mode(struct sysfs_class_device *class_dev) +static mode_t get_default_mode(void) { mode_t mode = 0600; /* default to owner rw only */ @@ -735,7 +735,7 @@ done: strfieldcpy(udev->group, perm->group); } else { /* no matching perms found :( */ - udev->mode = get_default_mode(class_dev); + udev->mode = get_default_mode(); strncpy(udev->owner, get_default_owner(), OWNER_SIZE); strncpy(udev->group, get_default_group(), GROUP_SIZE); } diff --git a/udev-add.c b/udev-add.c index 9aa8bdb3e9..586911acc2 100644 --- a/udev-add.c +++ b/udev-add.c @@ -155,29 +155,29 @@ static int create_node(struct udevice *dev) dbg("chmod(%s, %#o) failed with error '%s'", filename, dev->mode, strerror(errno)); - if (*dev->owner) { + if (dev->owner[0]) { char *endptr; unsigned long id = strtoul(dev->owner, &endptr, 10); - if (*endptr == 0x00) + if (endptr[0] == '\0') uid = (uid_t) id; else { struct passwd *pw = getpwnam(dev->owner); - if (!pw) - dbg("user unknown '%s'", dev->owner); + if (pw == NULL) + dbg("specified user unknown '%s'", dev->owner); else uid = pw->pw_uid; } } - if (*dev->group) { + if (dev->group[0]) { char *endptr; unsigned long id = strtoul(dev->group, &endptr, 10); - if (*endptr == 0x00) + if (endptr[0] == '\0') gid = (gid_t) id; else { struct group *gr = getgrnam(dev->group); - if (!gr) - dbg("group unknown '%s'", dev->group); + if (gr == NULL) + dbg("specified group unknown '%s'", dev->group); else gid = gr->gr_gid; } @@ -192,7 +192,7 @@ static int create_node(struct udevice *dev) } /* create symlink if requested */ - if (*dev->symlink) { + if (dev->symlink[0]) { symlinks = dev->symlink; while (1) { linkname = strsep(&symlinks, " "); diff --git a/udev.8 b/udev.8 index ff89e435ff..9a597276c6 100644 --- a/udev.8 +++ b/udev.8 @@ -98,6 +98,16 @@ This is the location of the udev permission file. The default value for this is This is the default mode for all nodes that have no explicit match in the permissions file. The default value for this is .I 0666 +.TP +.B default_owner +This is the default owner for all nodes that have no explicit match in the +permissions file. The default value for this is +.I root +.TP +.B default_group +This is the default group for all nodes that have no explicit match in the +permissions file. The default value for this is +.I root .br .P .RI "A sample " udev.conf " might look like this: @@ -118,6 +128,14 @@ udev_permissions="/etc/udev/udev.permissions" # default_mode - set the default mode for all nodes that have no # explicit match in the permissions file default_mode="0666" + +# default_owner - set the default owner for all nodes that have no +# explicit match in the permissions file +default_owner="root" + +# default_group - set the default group for all nodes that have no +# explicit match in the permissions file +default_group="root" .fi .P The rules for udev to use when naming devices may specified at diff --git a/udev.h b/udev.h index 963f8d2516..e5c983a212 100644 --- a/udev.h +++ b/udev.h @@ -31,6 +31,7 @@ #define NAME_SIZE 100 #define OWNER_SIZE 30 #define GROUP_SIZE 30 +#define MODE_SIZE 8 struct udevice { char name[NAME_SIZE]; @@ -67,7 +68,7 @@ extern char udev_db_filename[PATH_MAX+NAME_MAX]; extern char udev_permissions_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; -extern char default_mode_str[NAME_MAX]; +extern char default_mode_str[MODE_SIZE]; extern char default_owner_str[OWNER_SIZE]; extern char default_group_str[GROUP_SIZE]; diff --git a/udev_config.c b/udev_config.c index d262f2af07..e75ee3a346 100644 --- a/udev_config.c +++ b/udev_config.c @@ -45,7 +45,7 @@ char udev_db_filename[PATH_MAX+NAME_MAX]; char udev_permissions_filename[PATH_MAX+NAME_MAX]; char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; -char default_mode_str[NAME_MAX]; +char default_mode_str[MODE_SIZE]; char default_owner_str[OWNER_SIZE]; char default_group_str[GROUP_SIZE]; From be9b51f6638d66025ebde1ca154ae9180383409c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 19 Jan 2004 19:46:26 -0800 Subject: [PATCH 0435/4284] [PATCH] udev - program to query all device attributes to build a rule On Sun, Jan 18, 2004 at 07:30:50AM +0100, Kay Sievers wrote: > Hi, > here is a small program to query all attributes of a device and > print these in the udev key format. It may help to get the keys to > define a rule. Fixed a typo - the sysfs_device is right now. USB FLash Reader: kay@pim:~/src/udev.kay$ extras/udevinfo/udevinfo /sys/block/sda/sda1 device '/sys/block/sda/sda1' has major:minor 8:1 looking at class device '/sys/block/sda/sda1': SYSFS_dev="8:1" SYSFS_start="32" SYSFS_size="160" SYSFS_stat=" 0 0 0 0" follow class device's "device" link '/sys/block/sda': BUS="scsi" ID="57:0:0:0" SYSFS_detach_state="0" SYSFS_type="0" SYSFS_device_blocked="0" SYSFS_queue_depth="1" SYSFS_scsi_level="3" SYSFS_vendor="SMSC " SYSFS_model="USB 2 HS-CF" SYSFS_rev="1.25" SYSFS_online="1" --- extras/udevinfo/Makefile | 14 ++++ extras/udevinfo/udevinfo.c | 132 +++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 extras/udevinfo/Makefile create mode 100644 extras/udevinfo/udevinfo.c diff --git a/extras/udevinfo/Makefile b/extras/udevinfo/Makefile new file mode 100644 index 0000000000..f31c8c11e9 --- /dev/null +++ b/extras/udevinfo/Makefile @@ -0,0 +1,14 @@ +PROG=udevinfo +LD=$(CC) +OBJS=udevinfo.o + +all: $(PROG) + +clean: + rm -f $(PROG) $(OBJS) + +$(PROG): $(OBJS) + $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) + +me: + cd ../..; make EXTRAS=extras/udevinfo diff --git a/extras/udevinfo/udevinfo.c b/extras/udevinfo/udevinfo.c new file mode 100644 index 0000000000..4f229cd376 --- /dev/null +++ b/extras/udevinfo/udevinfo.c @@ -0,0 +1,132 @@ +/* + * udevinfo - fetches attributes for a device + * + * 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. + * + * 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. + * + */ + +#include +#include +#include + +#include "libsysfs.h" + + +# define VALUE_SIZE 200 + +char **main_argv; +char **main_envp; + +static int print_all_attributes(char *path) +{ + struct dlist *attributes; + struct sysfs_attribute *attr; + struct sysfs_directory *sysfs_dir; + char value[VALUE_SIZE]; + int len; + int retval = 0; + + sysfs_dir = sysfs_open_directory(path); + if (sysfs_dir == NULL) + return -1; + + attributes = sysfs_get_dir_attributes(sysfs_dir); + if (attributes == NULL) { + retval = -1; + goto exit; + } + + dlist_for_each_data(attributes, attr, struct sysfs_attribute) { + if (attr->value != NULL) { + strncpy(value, attr->value, VALUE_SIZE); + len = strlen(value); + if (value[len-1] == '\n') + value[len-1] = '\0'; + printf(" SYSFS_%s=\"%s\"\n", attr->name, value); + } + } + printf("\n"); + +exit: + sysfs_close_directory(sysfs_dir); + + return retval; +} + +int main(int argc, char **argv, char **envp) +{ + main_argv = argv; + main_envp = envp; + struct sysfs_class_device *class_dev; + struct sysfs_class_device *class_dev_parent; + struct sysfs_attribute *attr; + struct sysfs_device *sysfs_device; + char *path; + int retval = 0; + + if (argc != 2) { + printf("Usage: udevinfo \n"); + return -1; + } + path = argv[1]; + + /* get the class dev */ + class_dev = sysfs_open_class_device_path(path); + if (class_dev == NULL) { + printf("couldn't get the class device\n"); + return -1; + } + + /* read the 'dev' file for major/minor*/ + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) { + printf("couldn't get the \"dev\" file\n"); + retval = -1; + goto exit; + } + printf("\ndevice '%s' has major:minor %s\n", class_dev->path, attr->value); + sysfs_close_attribute(attr); + + /* open sysfs class device directory and print all attributes */ + printf("looking at class device '%s':\n", class_dev->path); + if (print_all_attributes(class_dev->path) != 0) { + printf("couldn't open class device directory\n"); + retval = -1; + goto exit; + } + + /* get the device (if parent exists use it instead) */ + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent != NULL) { + //sysfs_close_class_device(class_dev); + class_dev = class_dev_parent; + } + sysfs_device = sysfs_get_classdev_device(class_dev); + if (sysfs_device != NULL) { + printf("follow class device's \"device\" link '%s':\n", class_dev->path); + printf(" BUS=\"%s\"\n", sysfs_device->bus); + printf(" ID=\"%s\"\n", sysfs_device->bus_id); + + /* open sysfs device directory and print all attributes */ + print_all_attributes(sysfs_device->path); + sysfs_close_device(sysfs_device); + } + +exit: + //sysfs_close_class_device(class_dev); + return retval; +} From f10fec8197d9cc794f7f87cf9b14daaf414974d4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 19 Jan 2004 20:41:14 -0800 Subject: [PATCH 0436/4284] [PATCH] fixup logging.h to handle different logging options properly. Thanks to Olaf Hering for the error message. --- logging.h | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/logging.h b/logging.h index 1f2126839b..2d09b9a088 100644 --- a/logging.h +++ b/logging.h @@ -24,35 +24,37 @@ #ifndef LOGGING_H #define LOGGING_H +#define info(format, arg...) do { } while (0) +#define dbg(format, arg...) do { } while (0) +#define dbg_parse(format, arg...) do { } while (0) + #ifdef LOG #include + +#undef info #define info(format, arg...) \ do { \ log_message (LOG_INFO , format , ## arg); \ } while (0) -#else - #define info(format, arg...) do { } while (0) -#endif #ifdef DEBUG +#undef dbg #define dbg(format, arg...) \ do { \ log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ } while (0) -#else - #define dbg(format, arg...) do { } while (0) #endif /* Parser needs it's own debugging statement, we usually don't care about this at all */ #ifdef DEBUG_PARSER +#undef dbg_parse #define dbg_parse(format, arg...) \ do { \ log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ } while (0) -#else - #define dbg_parse(format, arg...) do { } while (0) #endif +#endif /* LOG */ extern int log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); From 069bd530124afe40453a5530b8bfa17b1b39989a Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Thu, 22 Jan 2004 00:16:28 -0800 Subject: [PATCH 0437/4284] [PATCH] udev-013/extras/multipath update incremental to 0.0.13, * update the DM target synthax to the 2.6.0-udm5 style * update the changelog and the doc to reflect minimal requirements --- extras/multipath/ChangeLog | 2 ++ extras/multipath/README | 4 +++- extras/multipath/main.c | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index a780865d3e..bb2f6baf89 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,3 +1,5 @@ +2004-01-19 multipath-013 + * update the DM target synthax to the 2.6.0-udm5 style 2003-12-29 multipath-012 * check hotplug event refers to a block device; if not exit early * refresh doc diff --git a/extras/multipath/README b/extras/multipath/README index 951c2788bc..417a0d38e4 100644 --- a/extras/multipath/README +++ b/extras/multipath/README @@ -4,8 +4,10 @@ Dependancies : o libdevmapper : comes with device-mapper-XXXX.tar.gz See www.sistina.com This lib has been dropped in the multipath tree -o libsysfs : comes with sysutils +o libsysfs : comes with sysutils or udev See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ +o Linux kernel 2.6.0 with udm5 patchset + http://people.sistina.com/~thornber/dm/ How it works : ============== diff --git a/extras/multipath/main.c b/extras/multipath/main.c index a8e29e8ba6..e18e049128 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -665,7 +665,7 @@ setup_map(struct env * conf, struct path * all_paths, if (all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && !conf->forcedfailover ) { - params_p += sprintf(params_p, " %i %s %i %i", + params_p += sprintf(params_p, " 1 %i %s %i %i", dm_pg_prio, dm_ps_name, np, dm_ps_nr_args); for (i=0; i<=mp[index].npaths; i++) { @@ -678,6 +678,7 @@ setup_map(struct env * conf, struct path * all_paths, if (all_paths[PINDEX(index,0)].iopolicy == FAILOVER || conf->forcedfailover) { + params_p += sprintf(params_p, " %i", mp[index].npaths + 1); for (i=0; i<=mp[index].npaths; i++) { if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) continue; From 267f534d1c809c31e0dcc9613953ecac45529038 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 22 Jan 2004 00:54:52 -0800 Subject: [PATCH 0438/4284] [PATCH] misc code cleanups. --- logging.h | 2 +- namedev.c | 19 +++++++++---------- namedev_parse.c | 4 +--- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/logging.h b/logging.h index 2d09b9a088..df5922b3e6 100644 --- a/logging.h +++ b/logging.h @@ -34,7 +34,7 @@ #undef info #define info(format, arg...) \ do { \ - log_message (LOG_INFO , format , ## arg); \ + log_message (LOG_INFO , format , ## arg); \ } while (0) #ifdef DEBUG diff --git a/namedev.c b/namedev.c index 7fd69f7778..e0d396e6ff 100644 --- a/namedev.c +++ b/namedev.c @@ -145,25 +145,25 @@ static mode_t get_default_mode(void) { mode_t mode = 0600; /* default to owner rw only */ - if (strlen(default_mode_str) != 0) { + if (strlen(default_mode_str) != 0) mode = strtol(default_mode_str, NULL, 8); - } + return mode; } -static char * get_default_owner(void) +static char *get_default_owner(void) { - if (strlen(default_owner_str) == 0) { + if (strlen(default_owner_str) == 0) strncpy(default_owner_str, "root", OWNER_SIZE); - } + return default_owner_str; } -static char * get_default_group(void) +static char *get_default_group(void) { - if (strlen(default_group_str) == 0) { + if (strlen(default_group_str) == 0) strncpy(default_group_str, "root", GROUP_SIZE); - } + return default_group_str; } @@ -563,10 +563,9 @@ device_found: * if needed */ if (sysfs_device) { - if (sysfs_device->bus[0] != '\0') goto bus_found; - + loop = 10; tspec.tv_nsec = 10000000; while (loop--) { diff --git a/namedev_parse.c b/namedev_parse.c index 546d767aed..b15be0e6fa 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -120,7 +120,6 @@ void dump_perm_dev_list(void) dump_perm_dev(dev); } - int namedev_init_rules(void) { char line[255]; @@ -345,6 +344,5 @@ int namedev_init_permissions(void) exit: fclose(fd); return retval; -} - +} From f2ec8f1a7f1af707579d3cd85d440176e5180212 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 22 Jan 2004 01:06:18 -0800 Subject: [PATCH 0439/4284] [PATCH] 014 release --- ChangeLog | 39 +++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4affadaf53..534fff49e9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +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 + o v013 release TAG: v013 + +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 ============================================ diff --git a/Makefile b/Makefile index f19354fb05..1bb9d878b3 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ USE_DBUS = false ROOT = udev -VERSION = 013_bk +VERSION = 014 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 575e3cdf60..89a9ee6c6a 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 013_bk +Version: 014 Release: 1 License: GPL Group: Utilities/System From bb513a064ce00e8efca1c697955d4a34b6782c29 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 22 Jan 2004 21:04:54 -0800 Subject: [PATCH 0440/4284] [PATCH] 014_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1bb9d878b3..8ff4dd1384 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ USE_DBUS = false ROOT = udev -VERSION = 014 +VERSION = 014_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 89a9ee6c6a..8494143ec0 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 014 +Version: 014_bk Release: 1 License: GPL Group: Utilities/System From 724257d97b452dd563ea1a3a5cdc53b18e8dcb34 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 23 Jan 2004 00:21:13 -0800 Subject: [PATCH 0441/4284] [PATCH] add support for figuring out which device on the sysfs "chain" the rule applies to. This should fix one of the more annoying things to me about udev, and gets rid of a TODO item. --- namedev.c | 209 +++++++++++++++++++++++++--------------------- test/udev-test.pl | 9 ++ 2 files changed, 123 insertions(+), 95 deletions(-) diff --git a/namedev.c b/namedev.c index e0d396e6ff..6b1aa297ea 100644 --- a/namedev.c +++ b/namedev.c @@ -585,6 +585,113 @@ exit: return sysfs_device; } +static int match_rule(struct config_device *dev, struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +{ + while (1) { + /* check for matching bus value */ + if (dev->bus[0] != '\0') { + if (sysfs_device == NULL) { + dbg("device has no bus"); + goto no_good; + } + dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { + dbg(FIELD_BUS " is not matching"); + goto no_good; + } else { + dbg(FIELD_BUS " matches"); + } + } + + /* check for matching kernel name*/ + if (dev->kernel[0] != '\0') { + dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); + if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { + dbg(FIELD_KERNEL " is not matching"); + goto no_good; + } else { + dbg(FIELD_KERNEL " matches"); + } + } + + /* check for matching bus id */ + if (dev->id[0] != '\0') { + dbg("check " FIELD_ID); + if (match_id(dev, class_dev, sysfs_device) != 0) { + dbg(FIELD_ID " is not matching"); + goto no_good; + } else { + dbg(FIELD_ID " matches"); + } + } + + /* check for matching place of device */ + if (dev->place[0] != '\0') { + dbg("check " FIELD_PLACE); + if (match_place(dev, class_dev, sysfs_device) != 0) { + dbg(FIELD_PLACE " is not matching"); + goto no_good; + } else { + dbg(FIELD_PLACE " matches"); + } + } + + /* check for matching sysfs pairs */ + if (dev->sysfs_pair[0].file[0] != '\0') { + dbg("check " FIELD_SYSFS " pairs"); + if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) { + dbg(FIELD_SYSFS " is not matching"); + goto no_good; + } else { + dbg(FIELD_SYSFS " matches"); + } + } + + /* execute external program */ + if (dev->program[0] != '\0') { + dbg("check " FIELD_PROGRAM); + apply_format(udev, dev->program); + if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { + dbg(FIELD_PROGRAM " returned nozero"); + goto no_good; + } else { + dbg(FIELD_PROGRAM " returned successful"); + } + } + + /* check for matching result of external program */ + if (dev->result[0] != '\0') { + dbg("check for " FIELD_RESULT + " dev->result='%s', udev->program_result='%s'", + dev->result, udev->program_result); + if (strcmp_pattern(dev->result, udev->program_result) != 0) { + dbg(FIELD_RESULT " is not matching"); + goto no_good; + } else { + dbg(FIELD_RESULT " matches"); + } + } + + /* check if we are instructed to ignore this device */ + if (dev->name[0] == '\0') { + dbg("instructed to ignore this device"); + return -1; + } + + /* Yeah, we matched! */ + return 0; + +no_good: + sysfs_device = sysfs_get_device_parent(sysfs_device); + if (sysfs_device == NULL) + return -ENODEV; + dbg("sysfs_device->path='%s'", sysfs_device->path); + dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + dbg("sysfs_device->bus='%s'", sysfs_device->bus); + } + +} + int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) { struct sysfs_device *sysfs_device = NULL; @@ -619,102 +726,14 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud list_for_each_entry(dev, &config_device_list, node) { dbg("process rule"); - /* check for matching bus value */ - if (dev->bus[0] != '\0') { - if (sysfs_device == NULL) { - dbg("device has no bus"); - continue; - } - dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); - if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { - dbg(FIELD_BUS " is not matching"); - continue; - } else { - dbg(FIELD_BUS " matches"); - } + if (match_rule(dev, class_dev, udev, sysfs_device) == 0) { + /* Yup, this rule belongs to us! */ + info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", + udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); + strfieldcpy(udev->name, dev->name); + strfieldcpy(udev->symlink, dev->symlink); + goto found; } - - /* check for matching kernel name*/ - if (dev->kernel[0] != '\0') { - dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); - if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { - dbg(FIELD_KERNEL " is not matching"); - continue; - } else { - dbg(FIELD_KERNEL " matches"); - } - } - - /* check for matching bus id */ - if (dev->id[0] != '\0') { - dbg("check " FIELD_ID); - if (match_id(dev, class_dev, sysfs_device) != 0) { - dbg(FIELD_ID " is not matching"); - continue; - } else { - dbg(FIELD_ID " matches"); - } - } - - /* check for matching place of device */ - if (dev->place[0] != '\0') { - dbg("check " FIELD_PLACE); - if (match_place(dev, class_dev, sysfs_device) != 0) { - dbg(FIELD_PLACE " is not matching"); - continue; - } else { - dbg(FIELD_PLACE " matches"); - } - } - - /* check for matching sysfs pairs */ - if (dev->sysfs_pair[0].file[0] != '\0') { - dbg("check " FIELD_SYSFS " pairs"); - if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) { - dbg(FIELD_SYSFS " is not matching"); - continue; - } else { - dbg(FIELD_SYSFS " matches"); - } - } - - /* execute external program */ - if (dev->program[0] != '\0') { - dbg("check " FIELD_PROGRAM); - apply_format(udev, dev->program); - if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { - dbg(FIELD_PROGRAM " returned nozero"); - continue; - } else { - dbg(FIELD_PROGRAM " returned successful"); - } - } - - /* check for matching result of external program */ - if (dev->result[0] != '\0') { - dbg("check for " FIELD_RESULT - " dev->result='%s', udev->program_result='%s'", - dev->result, udev->program_result); - if (strcmp_pattern(dev->result, udev->program_result) != 0) { - dbg(FIELD_RESULT " is not matching"); - continue; - } else { - dbg(FIELD_RESULT " matches"); - } - } - - /* check if we are instructed to ignore this device */ - if (dev->name[0] == '\0') { - dbg("instructed to ignore this device"); - return -1; - } - - /* Yup, this rule belongs to us! */ - info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", - udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - goto found; } /* no rule was found so we use the kernel name */ diff --git a/test/udev-test.pl b/test/udev-test.pl index b7013e4bde..0700e53576 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -317,6 +317,15 @@ EOF expected => "second-0" , conf => < "sysfs parent heirachy", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor" , + conf => < Date: Fri, 23 Jan 2004 00:22:17 -0800 Subject: [PATCH 0442/4284] [PATCH] remove TODO item about BUS value, as it is now done. --- TODO | 5 ----- 1 file changed, 5 deletions(-) diff --git a/TODO b/TODO index 702d0d6b27..dffa809df9 100644 --- a/TODO +++ b/TODO @@ -25,8 +25,3 @@ greg@kroah.com - do early boot logic (putting udev into initramfs, handle pivot-root, etc.) - lots of other stuff... -- actually use the BUS= value to determine where the LABEL rule should look - (right now it's ignored, and we only look in the current sysfs directory.) - This is needed, for example, to look at the usb device's serial number of a - usb-storage device, instead of the scsi device's sysfs directory for the - serial number. From 7fafc0324272731c5666047715b9f58f56761534 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 23 Jan 2004 00:28:57 -0800 Subject: [PATCH 0443/4284] [PATCH] spilt udev into pieces On Thu, Jan 22, 2004 at 01:27:45AM +0100, Kay Sievers wrote: > On Wed, Jan 21, 2004 at 02:38:25PM +0100, Kay Sievers wrote: > > On Thu, Jan 15, 2004 at 01:45:10PM -0800, Greg KH wrote: > > > On Thu, Jan 15, 2004 at 10:36:25PM +0800, Ling, Xiaofeng wrote: > > > > Hi, Greg > > > > I wrote a simple implementation for the two pieces > > > > of send and receive hotplug event, > > > > use a message queue and a list for the out of order > > > > hotplug event. It also has a timeout timer of 3 seconds. > > > > They are now separate program. the file nseq is the test script. > > > > Could you have a look to see wether it is feasible? > > > > If so, I'll continue to merge with udev. > > > > > > Yes, very nice start. Please continue on. > > > > > > One minor comment, please stick with the kernel coding style when you > > > are writing new code for udev. > > > > I took the code from Xiaofeng, cleaned the whitespace, renamed some bits, > > tweaked the debugging, added the udev exec and created a patch for the current tree. > > > > It seems functional now, by simply executing our current udev (dirty hack). > > It reorders the incoming events and if one is missing it delays the > > execution of the following ones up to a maximum of 10 seconds. > > > > Test script is included, but you can't mix hotplug sequence numbers and > > test script numbers, it will result in waiting for the missing numbers :) > > Hey, nobody want's to play with me? > So here I'm chatting with myself :) > > This is the next version with signal handling for resetting the expected > signal number. I changed the behaviour of the timeout to skip all > missing events at once and to proceed with the next event in the queue. > > So it's now possible to use the test script at any time, cause it resets > the daemon, if real hotplug event coming in later all missing nimbers will > be skipped after a timeout of 10 seconds and the queued events are applied. Here is the next updated updated version to apply to the lastet udev. I've added infrastructure for getting the state of the IPC queue in the sender and set the program to exec by the daemon. Also the magic key id is replaced by the usual key generation by path/nr. It looks promising, I use it on my machine and my 4in1 USB-flash-reader connect/disconnect emits the events "randomly" but udevd is able to reorder it and calls our normal udev in the right order. --- Makefile | 14 ++- test/udevd_test.sh | 47 +++++++++ udevd.c | 255 +++++++++++++++++++++++++++++++++++++++++++++ udevd.h | 36 +++++++ udevsend.c | 152 +++++++++++++++++++++++++++ 5 files changed, 502 insertions(+), 2 deletions(-) create mode 100644 test/udevd_test.sh create mode 100644 udevd.c create mode 100644 udevd.h create mode 100644 udevsend.c diff --git a/Makefile b/Makefile index 8ff4dd1384..0fd158a2c7 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,8 @@ USE_DBUS = false ROOT = udev +DAEMON = udevd +SENDER = udevsend VERSION = 014_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -155,7 +157,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) +all: $(ROOT) $(DAEMON) $(SENDER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ @@ -229,10 +231,18 @@ $(ROOT): $(OBJS) udev.h namedev.h udev_version.h udev_dbus.h udevdb.h klibc_fixu $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) +$(DAEMON): $(ROOT) udevd.h udevd.o + $(LD) $(LDFLAGS) -o $(DAEMON) $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $(ROOT) + +$(SENDER): $(ROOT) udevd.h udevsend.o + $(LD) $(LDFLAGS) -o $(SENDER) $(CRT0) udevsend.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $(ROOT) + clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(DAEMON) $(SENDER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff --git a/test/udevd_test.sh b/test/udevd_test.sh new file mode 100644 index 0000000000..013cdb9d6c --- /dev/null +++ b/test/udevd_test.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# reset udevd, expected sequence number and empty queue +killall -HUP udevd + +export ACTION=add +export DEVPATH=/block/sda + +export SEQNUM=1 +./udevsend block + +export SEQNUM=2 +./udevsend block + +export SEQNUM=3 +./udevsend block + +export SEQNUM=5 +./udevsend block + +export SEQNUM=4 +./udevsend block + +export SEQNUM=6 +./udevsend block + +export SEQNUM=7 +./udevsend block + +export SEQNUM=10 +./udevsend block + +export SEQNUM=9 +#./udevsend block + +export SEQNUM=8 +#./udevsend block + +export SEQNUM=13 +./udevsend block + +export SEQNUM=12 +./udevsend block + +export SEQNUM=11 +./udevsend block + diff --git a/udevd.c b/udevd.c new file mode 100644 index 0000000000..08dede36ee --- /dev/null +++ b/udevd.c @@ -0,0 +1,255 @@ +/* + * udevd.c + * + * Userspace devfs + * + * Copyright (C) 2004 Ling, Xiaofeng + * 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" +#include "logging.h" + +#define BUFFER_SIZE 1024 +#define TIMEOUT_SECONDS 10 + +static void reset_timer(void); +static void reset_queue(void); + + +static int expect_seqnum = 0; +static int timeout_value = TIMEOUT_SECONDS; +static int timeout = 0; +static struct hotplug_msg *head = NULL; +static char exec_program[100]; + +static void sig_handler(int signum) +{ + dbg("caught signal %d", signum); + switch (signum) { + case SIGHUP: + dbg("reset requested, all waiting events killed"); + reset_timer(); + reset_queue(); + timeout = 0; + expect_seqnum = 0; + break; + + case SIGINT: + case SIGTERM: + case SIGKILL: + exit(20 + signum); + break; + + default: + dbg("unhandled signal"); + } +} + +static void sig_alarmhandler(int signum) +{ + dbg("caught signal %d", signum); + switch (signum) { + case SIGALRM: + timeout = 1; + dbg("event timeout reached"); + break; + + default: + dbg("unhandled signal"); + } +} + +static void dump_queue(void) +{ + struct hotplug_msg *p; + p = head; + + dbg("next expected sequence is %d", expect_seqnum); + while(p) { + dbg("sequence %d in queue", p->seqnum); + p=p->next; + } +} + +static void dump_msg(struct hotplug_msg *pmsg) +{ + dbg("sequence %d, '%s', '%s', '%s'", + pmsg->seqnum, pmsg->action, pmsg->devpath, pmsg->subsystem); +} + +static void dispatch_msg(struct hotplug_msg *pmsg) +{ + dump_msg(pmsg); + dbg("exec '%s'", exec_program); + setenv("ACTION", pmsg->action, 1); + setenv("DEVPATH", pmsg->devpath, 1); + execl(exec_program, pmsg->subsystem); +} + +static void reset_timer(void) +{ + alarm(0); +} + +static void set_timer(void) +{ + signal(SIGALRM, sig_alarmhandler); + alarm(timeout_value); +} + +static void reset_queue(void) +{ + struct hotplug_msg *p; + p = head; + + while(head) { + p = head; + head = head->next; + free(p); + } +} + +static void check_queue(void) +{ + struct hotplug_msg *p; + p = head; + + dump_queue(); + while(head && head->seqnum == expect_seqnum) { + dispatch_msg(head); + expect_seqnum++; + p = head; + head = head->next; + free(p); + } + if (head != NULL) + set_timer(); + else + reset_timer(); +} + +static void add_queue(struct hotplug_msg *pmsg) +{ + struct hotplug_msg *pnewmsg; + struct hotplug_msg *p; + struct hotplug_msg *p1; + + p = head; + p1 = NULL; + pnewmsg = malloc(sizeof(struct hotplug_msg)); + *pnewmsg = *pmsg; + pnewmsg->next = NULL; + while(p && pmsg->seqnum > p->seqnum) { + p1 = p; + p = p->next; + } + pnewmsg->next = p; + if (p1 == NULL) { + head = pnewmsg; + } else { + p1->next = pnewmsg; + } + dump_queue(); +} + +static int process_queue(void) +{ + int msgid; + key_t key; + struct hotplug_msg *pmsg; + char buf[BUFFER_SIZE]; + int ret; + + key = ftok(DEFAULT_EXEC_PROGRAM, IPC_KEY_ID); + pmsg = (struct hotplug_msg *) buf; + msgid = msgget(key, IPC_CREAT); + if (msgid == -1) { + dbg("open message queue error"); + goto exit; + } + while (1) { + ret = msgrcv(msgid, (struct msgbuf *) buf, BUFFER_SIZE-4, HOTPLUGMSGTYPE, 0); + if (ret != -1) { + dbg("current sequence %d, expected sequence %d", pmsg->seqnum, expect_seqnum); + + /* init expected sequence with value from first call */ + if (expect_seqnum == 0) { + expect_seqnum = pmsg->seqnum; + dbg("init next expected sequence number to %d", expect_seqnum); + } + + if (pmsg->seqnum > expect_seqnum) { + add_queue(pmsg); + set_timer(); + } else { + if (pmsg->seqnum == expect_seqnum) { + dispatch_msg(pmsg); + expect_seqnum++; + check_queue(); + } else { + dbg("timeout event for unexpected sequence number %d", pmsg->seqnum); + } + } + } else + if (errno == EINTR) { + if (head != NULL) { + /* timeout, skip all missing, proceed with next queued event */ + dbg("timeout reached, skip events %d - %d", expect_seqnum, head->seqnum-1); + expect_seqnum = head->seqnum; + } + check_queue(); + timeout = 0; + } else { + dbg("ipc message receive error '%s'", strerror(errno)); + } + } + return 0; +exit: + return -1; +} + +int main(int argc, char *argv[]) +{ + /* get program to exec on events */ + if (argc == 2) + strncpy(exec_program, argv[1], sizeof(exec_program)); + else + strcpy(exec_program, DEFAULT_EXEC_PROGRAM); + + /* set up signal handler */ + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); + signal(SIGKILL, sig_handler); + signal(SIGHUP, sig_handler); + + /* main loop */ + process_queue(); + return 0; +} diff --git a/udevd.h b/udevd.h new file mode 100644 index 0000000000..eb516ab65d --- /dev/null +++ b/udevd.h @@ -0,0 +1,36 @@ +/* + * udevd.h + * + * Userspace devfs + * + * Copyright (C) 2004 Ling, Xiaofeng + * + * + * 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. + * + */ + +#define HOTPLUGMSGTYPE 44 +#define DEFAULT_EXEC_PROGRAM "/sbin/udev" +#define IPC_KEY_ID 0 + + +struct hotplug_msg { + long mtype; + struct hotplug_msg *next; + int seqnum; + char action[8]; + char devpath[128]; + char subsystem[16]; +}; diff --git a/udevsend.c b/udevsend.c new file mode 100644 index 0000000000..37afaf55fa --- /dev/null +++ b/udevsend.c @@ -0,0 +1,152 @@ +/* + * udevsend.c + * + * Userspace devfs + * + * Copyright (C) 2004 Ling, Xiaofeng + * 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" +#include "logging.h" + +static inline char *get_action(void) +{ + char *action; + + action = getenv("ACTION"); + return action; +} + +static inline char *get_devpath(void) +{ + char *devpath; + + devpath = getenv("DEVPATH"); + return devpath; +} + +static inline char *get_seqnum(void) +{ + char *seqnum; + + seqnum = getenv("SEQNUM"); + return seqnum; +} + +static int build_hotplugmsg(struct hotplug_msg **ppmsg, char *action, + char *devpath, char *subsystem, int seqnum) +{ + struct hotplug_msg *pmsg; + + pmsg = malloc(sizeof(struct hotplug_msg)); + pmsg->mtype = HOTPLUGMSGTYPE; + pmsg->seqnum = seqnum; + strncpy(pmsg->action, action, 8); + strncpy(pmsg->devpath, devpath, 128); + strncpy(pmsg->subsystem, subsystem, 16); + *ppmsg = pmsg; + return sizeof(struct hotplug_msg); +} + +static void free_hotplugmsg(struct hotplug_msg *pmsg) +{ + free(pmsg); +} + +int main(int argc, char* argv[]) +{ + int msgid; + key_t key; + struct msqid_ds msg_queue; + struct msgbuf *pmsg; + char *action; + char *devpath; + char *subsystem; + char *seqnum; + int seq; + int retval = -EINVAL; + int size; + + subsystem = argv[1]; + if (subsystem == NULL) { + dbg("no subsystem"); + goto exit; + } + + devpath = get_devpath(); + if (devpath == NULL) { + dbg("no devpath"); + goto exit; + } + + action = get_action(); + if (action == NULL) { + dbg("no action"); + goto exit; + } + + seqnum = get_seqnum(); + if (seqnum == NULL) { + dbg("no seqnum"); + goto exit; + } + + seq = atoi(seqnum); + key = ftok(DEFAULT_EXEC_PROGRAM, IPC_KEY_ID); + size = build_hotplugmsg( (struct hotplug_msg**) &pmsg, action, devpath, subsystem, seq); + msgid = msgget(key, IPC_CREAT); + if (msgid == -1) + { + dbg("open ipc queue error"); + goto exit; + } + + /* get state of queue */ + retval = msgctl(msgid, IPC_STAT, &msg_queue); + if (retval == -1) { + dbg("error getting info on ipc queue"); + goto exit; + } + if (msg_queue.msg_qnum > 0) + dbg("%li messages already in the ipc queue", msg_queue.msg_qnum); + + retval = msgsnd(msgid, pmsg, size, 0); + free_hotplugmsg( (struct hotplug_msg*) pmsg); + if (retval == -1) + { + dbg("send ipc message error"); + goto exit; + } + return 0; + +exit: + if (retval > 0) + retval = 0; + + return retval; +} From 7b15897b464e246c7342b9bf2098fd5d91b64cca Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 23 Jan 2004 01:51:06 -0800 Subject: [PATCH 0444/4284] [PATCH] whitespace cleanups --- udevsend.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/udevsend.c b/udevsend.c index 37afaf55fa..1a897451c0 100644 --- a/udevsend.c +++ b/udevsend.c @@ -115,13 +115,12 @@ int main(int argc, char* argv[]) dbg("no seqnum"); goto exit; } - seq = atoi(seqnum); + key = ftok(DEFAULT_EXEC_PROGRAM, IPC_KEY_ID); size = build_hotplugmsg( (struct hotplug_msg**) &pmsg, action, devpath, subsystem, seq); msgid = msgget(key, IPC_CREAT); - if (msgid == -1) - { + if (msgid == -1) { dbg("open ipc queue error"); goto exit; } @@ -137,8 +136,7 @@ int main(int argc, char* argv[]) retval = msgsnd(msgid, pmsg, size, 0); free_hotplugmsg( (struct hotplug_msg*) pmsg); - if (retval == -1) - { + if (retval == -1) { dbg("send ipc message error"); goto exit; } From 034f35d7e634d3900c32e58e791bf631f30a1e57 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 23 Jan 2004 03:01:02 -0800 Subject: [PATCH 0445/4284] [PATCH] udev - udevinfo with device chain walk udevinfo is now capable to print "all" attributes along the device chain of a sysfs device. Just like udev itself it walks the chain upwards and prints all usable attributes in the udev key format. So it should be easy to find unique attributes to compose a rule. All multiline attribute values and values containing non printable characters are skipped now. I hope nothing useful gets lost with this :) NOTE: The BUS value corresponding with the attributes is printed for every device. Don't specify BUS= in a rule and mix SYSFS_attributes from different busses, the rule can't match. ./udevinfo /sys/block/sda/sda1 device '/sys/block/sda/sda1' has major:minor 8:1 looking at class device '/sys/block/sda/sda1': SYSFS_dev="8:1" SYSFS_start="32" SYSFS_size="160" SYSFS_stat=" 0 0 0 0" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.3/1-1.3:1.0/host32/32:0:0:0': BUS="scsi" ID="32:0:0:0" SYSFS_detach_state="0" SYSFS_type="0" SYSFS_model="USB 2 HS-CF" SYSFS_vendor="SMSC " SYSFS_max_sectors="240" SYSFS_device_blocked="0" SYSFS_queue_depth="1" SYSFS_scsi_level="3" SYSFS_rev="1.25" SYSFS_online="1" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.3/1-1.3:1.0/host32': BUS="" ID="host32" SYSFS_detach_state="0" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.3/1-1.3:1.0': BUS="usb" ID="1-1.3:1.0" SYSFS_detach_state="0" SYSFS_bInterfaceNumber="00" SYSFS_bAlternateSetting=" 0" SYSFS_bNumEndpoints="02" SYSFS_bInterfaceClass="08" SYSFS_bInterfaceSubClass="06" SYSFS_bInterfaceProtocol="50" SYSFS_iInterface="00" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.3': BUS="usb" ID="1-1.3" SYSFS_detach_state="0" SYSFS_bNumConfigurations="1" SYSFS_bNumInterfaces=" 1" SYSFS_bConfigurationValue="1" SYSFS_bmAttributes="80" SYSFS_bMaxPower=" 96mA" SYSFS_idVendor="0424" SYSFS_idProduct="20fc" SYSFS_bcdDevice="0125" SYSFS_bDeviceClass="00" SYSFS_bDeviceSubClass="00" SYSFS_bDeviceProtocol="00" SYSFS_speed="12" SYSFS_manufacturer="SMSC" SYSFS_product="USB 2 Flash Media Device" SYSFS_serial="0305037000C2" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.0/usb1/1-1': BUS="usb" ID="1-1" SYSFS_detach_state="0" SYSFS_bNumConfigurations="1" SYSFS_bNumInterfaces=" 1" SYSFS_bConfigurationValue="1" SYSFS_bmAttributes="e0" SYSFS_bMaxPower=" 64mA" SYSFS_idVendor="03eb" SYSFS_idProduct="3301" SYSFS_bcdDevice="0300" SYSFS_bDeviceClass="09" SYSFS_bDeviceSubClass="00" SYSFS_bDeviceProtocol="00" SYSFS_speed="12" SYSFS_product="Standard USB Hub" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.0/usb1': BUS="usb" ID="usb1" SYSFS_detach_state="0" SYSFS_bNumConfigurations="1" SYSFS_bNumInterfaces=" 1" SYSFS_bConfigurationValue="1" SYSFS_bmAttributes="40" SYSFS_bMaxPower=" 0mA" SYSFS_idVendor="0000" SYSFS_idProduct="0000" SYSFS_bcdDevice="0206" SYSFS_bDeviceClass="09" SYSFS_bDeviceSubClass="00" SYSFS_bDeviceProtocol="00" SYSFS_speed="12" SYSFS_manufacturer="Linux 2.6.2-rc1-p4 uhci_hcd" SYSFS_product="UHCI Host Controller" SYSFS_serial="0000:00:1d.0" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1d.0': BUS="pci" ID="0000:00:1d.0" SYSFS_detach_state="0" SYSFS_vendor="0x8086" SYSFS_device="0x2482" SYSFS_subsystem_vendor="0x1014" SYSFS_subsystem_device="0x0220" SYSFS_class="0x0c0300" SYSFS_irq="9" looking at the device chain at '/sys/devices/pci0000:00': BUS="" ID="pci0000:00" SYSFS_detach_state="0" --- extras/udevinfo/udevinfo.c | 53 ++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 13 deletions(-) diff --git a/extras/udevinfo/udevinfo.c b/extras/udevinfo/udevinfo.c index 4f229cd376..c5934be2d4 100644 --- a/extras/udevinfo/udevinfo.c +++ b/extras/udevinfo/udevinfo.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "libsysfs.h" @@ -54,9 +55,23 @@ static int print_all_attributes(char *path) if (attr->value != NULL) { strncpy(value, attr->value, VALUE_SIZE); len = strlen(value); - if (value[len-1] == '\n') + if (len == 0) + continue; + + /* remove trailing newline */ + if (value[len-1] == '\n') { value[len-1] = '\0'; - printf(" SYSFS_%s=\"%s\"\n", attr->name, value); + len--; + } + + /* skip nonprintable values */ + while (len) { + if (isprint(value[len-1]) == 0) + break; + len--; + } + if (len == 0) + printf(" SYSFS_%s=\"%s\"\n", attr->name, value); } } printf("\n"); @@ -74,7 +89,8 @@ int main(int argc, char **argv, char **envp) struct sysfs_class_device *class_dev; struct sysfs_class_device *class_dev_parent; struct sysfs_attribute *attr; - struct sysfs_device *sysfs_device; + struct sysfs_device *sysfs_dev; + struct sysfs_device *sysfs_dev_parent; char *path; int retval = 0; @@ -98,33 +114,44 @@ int main(int argc, char **argv, char **envp) retval = -1; goto exit; } - printf("\ndevice '%s' has major:minor %s\n", class_dev->path, attr->value); + printf("\ndevice '%s' has major:minor %s", class_dev->path, attr->value); sysfs_close_attribute(attr); /* open sysfs class device directory and print all attributes */ - printf("looking at class device '%s':\n", class_dev->path); + printf(" looking at class device '%s':\n", class_dev->path); if (print_all_attributes(class_dev->path) != 0) { printf("couldn't open class device directory\n"); retval = -1; goto exit; } - /* get the device (if parent exists use it instead) */ + /* get the device link (if parent exists look here) */ class_dev_parent = sysfs_get_classdev_parent(class_dev); if (class_dev_parent != NULL) { //sysfs_close_class_device(class_dev); class_dev = class_dev_parent; } - sysfs_device = sysfs_get_classdev_device(class_dev); - if (sysfs_device != NULL) { - printf("follow class device's \"device\" link '%s':\n", class_dev->path); - printf(" BUS=\"%s\"\n", sysfs_device->bus); - printf(" ID=\"%s\"\n", sysfs_device->bus_id); + sysfs_dev = sysfs_get_classdev_device(class_dev); + if (sysfs_dev != NULL) + printf("follow the class device's \"device\"\n"); + + /* look the device chain upwards */ + while (sysfs_dev != NULL) { + printf(" looking at the device chain at '%s':\n", sysfs_dev->path); + printf(" BUS=\"%s\"\n", sysfs_dev->bus); + printf(" ID=\"%s\"\n", sysfs_dev->bus_id); /* open sysfs device directory and print all attributes */ - print_all_attributes(sysfs_device->path); - sysfs_close_device(sysfs_device); + print_all_attributes(sysfs_dev->path); + + sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev); + if (sysfs_dev_parent == NULL) + break; + + //sysfs_close_device(sysfs_dev); + sysfs_dev = sysfs_dev_parent; } + sysfs_close_device(sysfs_dev); exit: //sysfs_close_class_device(class_dev); From 90c210eb6bfc2ae294202fffb080315f3c47a57b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 23 Jan 2004 04:01:09 -0800 Subject: [PATCH 0446/4284] [PATCH] fix udevd exec Sorry, some code is missing. Here is a fix to make the exec functional. --- udevd.c | 33 +++++++++++++++++++++++++++++++-- udevsend.c | 8 +++++--- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/udevd.c b/udevd.c index 08dede36ee..6af265a389 100644 --- a/udevd.c +++ b/udevd.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -49,6 +50,7 @@ static int timeout = 0; static struct hotplug_msg *head = NULL; static char exec_program[100]; + static void sig_handler(int signum) { dbg("caught signal %d", signum); @@ -104,13 +106,40 @@ static void dump_msg(struct hotplug_msg *pmsg) pmsg->seqnum, pmsg->action, pmsg->devpath, pmsg->subsystem); } -static void dispatch_msg(struct hotplug_msg *pmsg) +static int dispatch_msg(struct hotplug_msg *pmsg) { + pid_t pid; + char *argv[3]; + int retval; + extern char **environ; + dump_msg(pmsg); dbg("exec '%s'", exec_program); + setenv("ACTION", pmsg->action, 1); setenv("DEVPATH", pmsg->devpath, 1); - execl(exec_program, pmsg->subsystem); + + argv[0] = exec_program; + argv[1] = pmsg->subsystem; + argv[2] = NULL; + + pid = fork(); + switch (pid) { + case 0: + retval = execve(argv[0], argv, environ); + if (retval != 0) { + dbg("child execve failed"); + exit(1); + } + break; + case -1: + dbg("fork failed"); + return -1; + default: + wait(0); + break; + } + return 0; } static void reset_timer(void) diff --git a/udevsend.c b/udevsend.c index 1a897451c0..748c8f2217 100644 --- a/udevsend.c +++ b/udevsend.c @@ -117,15 +117,16 @@ int main(int argc, char* argv[]) } seq = atoi(seqnum); + /* create ipc message queue or get id of our existing one */ key = ftok(DEFAULT_EXEC_PROGRAM, IPC_KEY_ID); size = build_hotplugmsg( (struct hotplug_msg**) &pmsg, action, devpath, subsystem, seq); msgid = msgget(key, IPC_CREAT); if (msgid == -1) { - dbg("open ipc queue error"); + dbg("error open ipc queue"); goto exit; } - /* get state of queue */ + /* get state of ipc queue */ retval = msgctl(msgid, IPC_STAT, &msg_queue); if (retval == -1) { dbg("error getting info on ipc queue"); @@ -134,10 +135,11 @@ int main(int argc, char* argv[]) if (msg_queue.msg_qnum > 0) dbg("%li messages already in the ipc queue", msg_queue.msg_qnum); + /* send ipc message to the daemon */ retval = msgsnd(msgid, pmsg, size, 0); free_hotplugmsg( (struct hotplug_msg*) pmsg); if (retval == -1) { - dbg("send ipc message error"); + dbg("error sending ipc message"); goto exit; } return 0; From 33db4b8da001242b8b3b0ce8a746ef46d4416d6d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 23 Jan 2004 21:25:17 -0800 Subject: [PATCH 0447/4284] [PATCH] udev - next round of udev event order daemon Here is the next round of udevd/udevsend: udevsend - If the IPC message we send is not catched by a receiver we fork the udevd daemon to process this and the following events udevd - We reorder the events we receive and execute our current udev for every event. If one or more events are missing, we wait 10 seconds and then go ahead in the queue. If the queue is empty and we don't receive any event for the next 30 seconds, the daemon exits. The next incoming event will fork the daemon again. config - The path's to the executable are specified in udevd.h Now they are pointing to the current directory only. I don't like daemons hiding secrets (and mem leaks :)) inside, so I want to try this model. It should be enough logic to get all possible hotplug events executed in the right order. If no event, then no daemon! So everybody should be happy :) Here we see: 1. the daemon fork, 2. the udev work, 3. the 10 sec timeout and the skipped events, 4. the udev work, ..., 5. and the 30 sec timeout and exit. EVENTS: pim:/home/kay/src/udev.kay# test/udevd_test.sh pim:/home/kay/src/udev.kay# SEQNUM=15 ./udevsend block pim:/home/kay/src/udev.kay# SEQNUM=16 ./udevsend block pim:/home/kay/src/udev.kay# SEQNUM=17 ./udevsend block pim:/home/kay/src/udev.kay# SEQNUM=18 ./udevsend block pim:/home/kay/src/udev.kay# SEQNUM=20 ./udevsend block pim:/home/kay/src/udev.kay# SEQNUM=21 ./udevsend block LOG: Jan 23 15:35:35 pim udev[11795]: message is still in the ipc queue, starting daemon... Jan 23 15:35:35 pim udev[11799]: configured rule in '/etc/udev/udev.rules' at line 19 applied, 'sda' becomes '%k-flash' Jan 23 15:35:35 pim udev[11799]: creating device node '/udev/sda-flash' Jan 23 15:35:35 pim udev[11800]: creating device node '/udev/sdb' Jan 23 15:35:35 pim udev[11804]: creating device node '/udev/sdc' Jan 23 15:35:35 pim udev[11805]: removing device node '/udev/sda-flash' Jan 23 15:35:35 pim udev[11808]: removing device node '/udev/sdb' Jan 23 15:35:35 pim udev[11809]: removing device node '/udev/sdc' Jan 23 15:35:45 pim udev[11797]: timeout reached, skip events 7 - 7 Jan 23 15:35:45 pim udev[11811]: creating device node '/udev/sdb' Jan 23 15:35:45 pim udev[11812]: creating device node '/udev/sdc' Jan 23 15:36:01 pim udev[11797]: timeout reached, skip events 10 - 14 Jan 23 15:36:01 pim udev[11814]: creating device node '/udev/sdc' Jan 23 15:36:04 pim udev[11816]: creating device node '/udev/sdc' Jan 23 15:36:12 pim udev[11818]: creating device node '/udev/sdc' Jan 23 15:36:16 pim udev[11820]: creating device node '/udev/sdc' Jan 23 15:36:38 pim udev[11797]: timeout reached, skip events 19 - 19 Jan 23 15:36:38 pim udev[11823]: creating device node '/udev/sdc' Jan 23 15:36:38 pim udev[11824]: creating device node '/udev/sdc' Jan 23 15:37:08 pim udev[11797]: we have nothing to do, so daemon exits... --- test/udevd_test.sh | 53 ++++++++++--------- udevd.c | 129 ++++++++++++++++----------------------------- udevd.h | 6 ++- udevsend.c | 71 ++++++++++++++++++++----- 4 files changed, 135 insertions(+), 124 deletions(-) diff --git a/test/udevd_test.sh b/test/udevd_test.sh index 013cdb9d6c..0c7bd431be 100644 --- a/test/udevd_test.sh +++ b/test/udevd_test.sh @@ -1,47 +1,52 @@ #!/bin/bash -# reset udevd, expected sequence number and empty queue -killall -HUP udevd +# kill daemon, first event will start it again +killall udevd -export ACTION=add -export DEVPATH=/block/sda +# connect(123) - disconnect(456) - connect(789) sequence of sda/sdb/sdc export SEQNUM=1 +export ACTION=add +export DEVPATH=/block/sda ./udevsend block export SEQNUM=2 -./udevsend block - -export SEQNUM=3 -./udevsend block - -export SEQNUM=5 +export ACTION=add +export DEVPATH=/block/sdb ./udevsend block export SEQNUM=4 +export ACTION=remove +export DEVPATH=/block/sda +./udevsend block + +export SEQNUM=3 +export ACTION=add +export DEVPATH=/block/sdc ./udevsend block export SEQNUM=6 +export ACTION=remove +export DEVPATH=/block/sdc +./udevsend block + +export SEQNUM=5 +export ACTION=remove +export DEVPATH=/block/sdb ./udevsend block export SEQNUM=7 -./udevsend block - -export SEQNUM=10 -./udevsend block +export ACTION=add +export DEVPATH=/block/sda +#./udevsend block export SEQNUM=9 -#./udevsend block +export ACTION=add +export DEVPATH=/block/sdc +./udevsend block export SEQNUM=8 -#./udevsend block - -export SEQNUM=13 -./udevsend block - -export SEQNUM=12 -./udevsend block - -export SEQNUM=11 +export ACTION=add +export DEVPATH=/block/sdb ./udevsend block diff --git a/udevd.c b/udevd.c index 6af265a389..da887ec29b 100644 --- a/udevd.c +++ b/udevd.c @@ -37,49 +37,20 @@ #include "udevd.h" #include "logging.h" -#define BUFFER_SIZE 1024 -#define TIMEOUT_SECONDS 10 - -static void reset_timer(void); -static void reset_queue(void); +#define BUFFER_SIZE 1024 +#define EVENT_TIMEOUT_SECONDS 10 +#define DAEMON_TIMEOUT_SECONDS 30 static int expect_seqnum = 0; -static int timeout_value = TIMEOUT_SECONDS; -static int timeout = 0; static struct hotplug_msg *head = NULL; -static char exec_program[100]; -static void sig_handler(int signum) -{ - dbg("caught signal %d", signum); - switch (signum) { - case SIGHUP: - dbg("reset requested, all waiting events killed"); - reset_timer(); - reset_queue(); - timeout = 0; - expect_seqnum = 0; - break; - - case SIGINT: - case SIGTERM: - case SIGKILL: - exit(20 + signum); - break; - - default: - dbg("unhandled signal"); - } -} - static void sig_alarmhandler(int signum) { dbg("caught signal %d", signum); switch (signum) { case SIGALRM: - timeout = 1; dbg("event timeout reached"); break; @@ -94,9 +65,9 @@ static void dump_queue(void) p = head; dbg("next expected sequence is %d", expect_seqnum); - while(p) { + while(p != NULL) { dbg("sequence %d in queue", p->seqnum); - p=p->next; + p = p->next; } } @@ -110,59 +81,37 @@ static int dispatch_msg(struct hotplug_msg *pmsg) { pid_t pid; char *argv[3]; - int retval; extern char **environ; dump_msg(pmsg); - dbg("exec '%s'", exec_program); setenv("ACTION", pmsg->action, 1); setenv("DEVPATH", pmsg->devpath, 1); - - argv[0] = exec_program; + argv[0] = DEFAULT_UDEV_EXEC; argv[1] = pmsg->subsystem; argv[2] = NULL; pid = fork(); switch (pid) { case 0: - retval = execve(argv[0], argv, environ); - if (retval != 0) { - dbg("child execve failed"); - exit(1); - } + /* child */ + execve(argv[0], argv, environ); + dbg("exec of child failed"); + exit(1); break; case -1: - dbg("fork failed"); + dbg("fork of child failed"); return -1; default: wait(0); - break; } return 0; } -static void reset_timer(void) -{ - alarm(0); -} - -static void set_timer(void) +static void set_timer(int seconds) { signal(SIGALRM, sig_alarmhandler); - alarm(timeout_value); -} - -static void reset_queue(void) -{ - struct hotplug_msg *p; - p = head; - - while(head) { - p = head; - head = head->next; - free(p); - } + alarm(seconds); } static void check_queue(void) @@ -171,7 +120,7 @@ static void check_queue(void) p = head; dump_queue(); - while(head && head->seqnum == expect_seqnum) { + while(head != NULL && head->seqnum == expect_seqnum) { dispatch_msg(head); expect_seqnum++; p = head; @@ -179,9 +128,9 @@ static void check_queue(void) free(p); } if (head != NULL) - set_timer(); + set_timer(EVENT_TIMEOUT_SECONDS); else - reset_timer(); + set_timer(DAEMON_TIMEOUT_SECONDS); } static void add_queue(struct hotplug_msg *pmsg) @@ -195,7 +144,7 @@ static void add_queue(struct hotplug_msg *pmsg) pnewmsg = malloc(sizeof(struct hotplug_msg)); *pnewmsg = *pmsg; pnewmsg->next = NULL; - while(p && pmsg->seqnum > p->seqnum) { + while(p != NULL && pmsg->seqnum > p->seqnum) { p1 = p; p = p->next; } @@ -216,12 +165,12 @@ static int process_queue(void) char buf[BUFFER_SIZE]; int ret; - key = ftok(DEFAULT_EXEC_PROGRAM, IPC_KEY_ID); + key = ftok(DEFAULT_UDEVD_EXEC, IPC_KEY_ID); pmsg = (struct hotplug_msg *) buf; msgid = msgget(key, IPC_CREAT); if (msgid == -1) { dbg("open message queue error"); - goto exit; + return -1; } while (1) { ret = msgrcv(msgid, (struct msgbuf *) buf, BUFFER_SIZE-4, HOTPLUGMSGTYPE, 0); @@ -236,7 +185,7 @@ static int process_queue(void) if (pmsg->seqnum > expect_seqnum) { add_queue(pmsg); - set_timer(); + set_timer(EVENT_TIMEOUT_SECONDS); } else { if (pmsg->seqnum == expect_seqnum) { dispatch_msg(pmsg); @@ -246,37 +195,49 @@ static int process_queue(void) dbg("timeout event for unexpected sequence number %d", pmsg->seqnum); } } - } else + } else { if (errno == EINTR) { if (head != NULL) { - /* timeout, skip all missing, proceed with next queued event */ - dbg("timeout reached, skip events %d - %d", expect_seqnum, head->seqnum-1); + /* event timeout, skip all missing, proceed with next queued event */ + info("timeout reached, skip events %d - %d", expect_seqnum, head->seqnum-1); expect_seqnum = head->seqnum; + } else { + info("we have nothing to do, so daemon exits..."); + exit(0); } check_queue(); - timeout = 0; } else { dbg("ipc message receive error '%s'", strerror(errno)); } + } } return 0; -exit: - return -1; +} + +static void sig_handler(int signum) +{ + dbg("caught signal %d", signum); + switch (signum) { + case SIGINT: + case SIGTERM: + case SIGKILL: + exit(20 + signum); + break; + + default: + dbg("unhandled signal"); + } } int main(int argc, char *argv[]) { - /* get program to exec on events */ - if (argc == 2) - strncpy(exec_program, argv[1], sizeof(exec_program)); - else - strcpy(exec_program, DEFAULT_EXEC_PROGRAM); - /* set up signal handler */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); signal(SIGKILL, sig_handler); - signal(SIGHUP, sig_handler); + + /* we exit if we have nothing to do, next event will start us again */ + set_timer(DAEMON_TIMEOUT_SECONDS); /* main loop */ process_queue(); diff --git a/udevd.h b/udevd.h index eb516ab65d..43fe6b421a 100644 --- a/udevd.h +++ b/udevd.h @@ -21,9 +21,11 @@ * */ -#define HOTPLUGMSGTYPE 44 -#define DEFAULT_EXEC_PROGRAM "/sbin/udev" +#define DEFAULT_UDEV_EXEC "./udev" +#define DEFAULT_UDEVD_EXEC "./udevd" + #define IPC_KEY_ID 0 +#define HOTPLUGMSGTYPE 44 struct hotplug_msg { diff --git a/udevsend.c b/udevsend.c index 748c8f2217..d3e5378285 100644 --- a/udevsend.c +++ b/udevsend.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #include "udev.h" #include "udevd.h" @@ -78,6 +81,39 @@ static void free_hotplugmsg(struct hotplug_msg *pmsg) free(pmsg); } +static int start_daemon(void) +{ + pid_t pid; + pid_t child_pid; + + pid = fork(); + switch (pid) { + case 0: + /* helper child */ + child_pid = fork(); + switch (child_pid) { + case 0: + /* daemon */ + execl(DEFAULT_UDEVD_EXEC, NULL); + dbg("exec of daemon failed"); + exit(1); + case -1: + dbg("fork of daemon failed"); + return -1; + default: + exit(0); + } + break; + case -1: + dbg("fork of helper failed"); + return -1; + default: + wait(0); + } + return 0; +} + + int main(int argc, char* argv[]) { int msgid; @@ -91,6 +127,8 @@ int main(int argc, char* argv[]) int seq; int retval = -EINVAL; int size; + int loop; + struct timespec tspec; subsystem = argv[1]; if (subsystem == NULL) { @@ -118,7 +156,7 @@ int main(int argc, char* argv[]) seq = atoi(seqnum); /* create ipc message queue or get id of our existing one */ - key = ftok(DEFAULT_EXEC_PROGRAM, IPC_KEY_ID); + key = ftok(DEFAULT_UDEVD_EXEC, IPC_KEY_ID); size = build_hotplugmsg( (struct hotplug_msg**) &pmsg, action, devpath, subsystem, seq); msgid = msgget(key, IPC_CREAT); if (msgid == -1) { @@ -126,15 +164,6 @@ int main(int argc, char* argv[]) goto exit; } - /* get state of ipc queue */ - retval = msgctl(msgid, IPC_STAT, &msg_queue); - if (retval == -1) { - dbg("error getting info on ipc queue"); - goto exit; - } - if (msg_queue.msg_qnum > 0) - dbg("%li messages already in the ipc queue", msg_queue.msg_qnum); - /* send ipc message to the daemon */ retval = msgsnd(msgid, pmsg, size, 0); free_hotplugmsg( (struct hotplug_msg*) pmsg); @@ -142,11 +171,25 @@ int main(int argc, char* argv[]) dbg("error sending ipc message"); goto exit; } - return 0; + + /* get state of ipc queue */ + tspec.tv_sec = 0; + tspec.tv_nsec = 10000000; /* 10 millisec */ + loop = 20; + while (loop--) { + retval = msgctl(msgid, IPC_STAT, &msg_queue); + if (retval == -1) { + dbg("error getting info on ipc queue"); + goto exit; + } + if (msg_queue.msg_qnum == 0) + goto exit; + nanosleep(&tspec, NULL); + } + + info("message is still in the ipc queue, starting daemon..."); + retval = start_daemon(); exit: - if (retval > 0) - retval = 0; - return retval; } From 71c077fb0a9f7222f5363ebc1c67d48d7a2f5ff8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 23 Jan 2004 21:43:37 -0800 Subject: [PATCH 0448/4284] [PATCH] udevsnd : clean up message creation logic a bit. --- udevsend.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/udevsend.c b/udevsend.c index d3e5378285..bdc8293df7 100644 --- a/udevsend.c +++ b/udevsend.c @@ -61,26 +61,17 @@ static inline char *get_seqnum(void) return seqnum; } -static int build_hotplugmsg(struct hotplug_msg **ppmsg, char *action, +static int build_hotplugmsg(struct hotplug_msg *msg, char *action, char *devpath, char *subsystem, int seqnum) { - struct hotplug_msg *pmsg; - - pmsg = malloc(sizeof(struct hotplug_msg)); - pmsg->mtype = HOTPLUGMSGTYPE; - pmsg->seqnum = seqnum; - strncpy(pmsg->action, action, 8); - strncpy(pmsg->devpath, devpath, 128); - strncpy(pmsg->subsystem, subsystem, 16); - *ppmsg = pmsg; + msg->mtype = HOTPLUGMSGTYPE; + msg->seqnum = seqnum; + strncpy(msg->action, action, 8); + strncpy(msg->devpath, devpath, 128); + strncpy(msg->subsystem, subsystem, 16); return sizeof(struct hotplug_msg); } -static void free_hotplugmsg(struct hotplug_msg *pmsg) -{ - free(pmsg); -} - static int start_daemon(void) { pid_t pid; @@ -118,8 +109,8 @@ int main(int argc, char* argv[]) { int msgid; key_t key; - struct msqid_ds msg_queue; - struct msgbuf *pmsg; + struct msqid_ds msg_queue; + struct hotplug_msg message; char *action; char *devpath; char *subsystem; @@ -157,7 +148,7 @@ int main(int argc, char* argv[]) /* create ipc message queue or get id of our existing one */ key = ftok(DEFAULT_UDEVD_EXEC, IPC_KEY_ID); - size = build_hotplugmsg( (struct hotplug_msg**) &pmsg, action, devpath, subsystem, seq); + size = build_hotplugmsg(&message, action, devpath, subsystem, seq); msgid = msgget(key, IPC_CREAT); if (msgid == -1) { dbg("error open ipc queue"); @@ -165,8 +156,7 @@ int main(int argc, char* argv[]) } /* send ipc message to the daemon */ - retval = msgsnd(msgid, pmsg, size, 0); - free_hotplugmsg( (struct hotplug_msg*) pmsg); + retval = msgsnd(msgid, &message, size, 0); if (retval == -1) { dbg("error sending ipc message"); goto exit; From 305dd8b494d62168897313031293485ef4d085c2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 23 Jan 2004 22:25:24 -0800 Subject: [PATCH 0449/4284] [PATCH] new testd.block script for debugging. --- test/testd.block | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 test/testd.block diff --git a/test/testd.block b/test/testd.block new file mode 100644 index 0000000000..ca9ac8c1ac --- /dev/null +++ b/test/testd.block @@ -0,0 +1,36 @@ +#!/bin/bash +# +# test.block - run udev(8) on each block device in /sys/block + +if [ $# = "0" ] ; then + echo + echo "usage: $0 " + echo "where is \"add\" or \"remove\"" + echo + exit 1 +fi + +killall udevd + +SYSFSDIR=/sys # change this for a nonstand sysfs mount point +BIN=./udevsend # location of your udev binary +export ACTION=$1 # 'add' or 'remove' +seq=1 + +for i in ${SYSFSDIR}/block/*; do + # add each drive + export DEVPATH=${i#${SYSFSDIR}} + export SEQNUM=$seq + $BIN block + x=$((seq++)) + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${SYSFSDIR}} + export SEQNUM=$seq + $BIN block + x=$((seq++)) + fi + done +done From 1c5c245e6f053da7ac147a1733ea49dd84f260a5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 23 Jan 2004 22:26:19 -0800 Subject: [PATCH 0450/4284] [PATCH] make udevd only have one instance running at a time it used a file lock right now. need to put that lock in the udev directory, it's in the current directory, which isn't a good thing... --- udevd.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/udevd.c b/udevd.c index da887ec29b..2e63d8030e 100644 --- a/udevd.c +++ b/udevd.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "udev.h" #include "udevd.h" @@ -157,6 +158,9 @@ static void add_queue(struct hotplug_msg *pmsg) dump_queue(); } +static int lock_file = -1; +static char *lock_filename = ".udevd_lock"; + static int process_queue(void) { int msgid; @@ -203,6 +207,10 @@ static int process_queue(void) expect_seqnum = head->seqnum; } else { info("we have nothing to do, so daemon exits..."); + if (lock_file >= 0) { + close(lock_file); + unlink(lock_filename); + } exit(0); } check_queue(); @@ -221,6 +229,10 @@ static void sig_handler(int signum) case SIGINT: case SIGTERM: case SIGKILL: + if (lock_file >= 0) { + close(lock_file); + unlink(lock_filename); + } exit(20 + signum); break; @@ -229,8 +241,35 @@ static void sig_handler(int signum) } } +static int one_and_only(void) +{ + char string[100]; + + lock_file = open(lock_filename, O_RDWR | O_CREAT, 0x640); + + /* see if we can open */ + if (lock_file < 0) + return -EINVAL; + + /* see if we can lock */ + if (lockf(lock_file, F_TLOCK, 0) < 0) { + close(lock_file); + unlink(lock_filename); + return -EINVAL; + } + + snprintf(string, sizeof(string), "%d\n", getpid()); + write(lock_file, string, strlen(string)); + + return 0; +} + int main(int argc, char *argv[]) { + /* only let one version of the daemon run at any one time */ + if (one_and_only() != 0) + exit(0); + /* set up signal handler */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); From 25f8a5ad642e4338dacaf892e4ad47577c1cbf11 Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Fri, 23 Jan 2004 22:54:55 -0800 Subject: [PATCH 0451/4284] [PATCH] LFS init script update --- etc/init.d/udev.init.lfs | 100 ++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/etc/init.d/udev.init.lfs b/etc/init.d/udev.init.lfs index 08c81733e1..c738369081 100644 --- a/etc/init.d/udev.init.lfs +++ b/etc/init.d/udev.init.lfs @@ -2,83 +2,75 @@ # # LinuxFromScratch udev init script # derived from original RedHat udev init script -# 2003 by Michael Buesch +# 2003, 2004 by Michael Buesch # source /etc/sysconfig/rc source $rc_functions +source /etc/udev/udev.conf -udev_dir="/udev" sysfs_dir="/sys" bin="/sbin/udev" + +run_udev () +{ + # handle block devices and their partitions + for i in ${sysfs_dir}/block/*; do + # add each drive + export DEVPATH=${i#${sysfs_dir}} + $bin block & + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + $bin block & + fi + done + done + # all other device classes + for i in ${sysfs_dir}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + CLASS=`echo ${i#${sysfs_dir}} | \ + cut --delimiter='/' --fields=3-` + $bin $CLASS & + fi + done + done + return 0 +} + case "$1" in start) echo "Creating initial udev device nodes ..." - if [ ! -d $udev_dir ]; then - mkdir $udev_dir - if [ $? -ne 0 ]; then - print_status failure - exit 1 - fi - fi if [ ! -d $sysfs_dir ]; then echo "sysfs_dir $sysfs_dir does not exist!" print_status failure exit 1 fi + if [ ! -d $udev_root ]; then + mkdir $udev_root + if [ $? -ne 0 ]; then + print_status failure + exit 1 + fi + fi + # propogate /udev from /sys - we only need this while we do not # have initramfs and an early user-space with which to do early # device bring up - clean_exit="yes" export ACTION=add - # add block devices and their partitions - for i in ${sysfs_dir}/block/*; do - # add each drive - export DEVPATH=${i#${sysfs_dir}} - $bin block - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - $bin block - if [ $? -ne 0 ]; then - echo "Warning: $DEVPATH failed." - clean_exit="no" - fi - fi - done - done - # all other device classes - for i in ${sysfs_dir}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - CLASS=`echo ${i#${sysfs_dir}} | \ - cut --delimiter='/' --fields=3-` - $bin $CLASS - if [ $? -ne 0 ]; then - echo "Warning: $DEVPATH failed." - clean_exit="no" - fi - fi - done - done - if [ $clean_exit = "yes" ]; then - print_status success - else - print_status warning - fi + run_udev + evaluate_retval ;; stop) echo "Removing udev device nodes ..." - # be careful - if [ $udev_dir -a "$udev_dir" != "/" ]; then - # clear out /udev - rm -rf ${udev_dir}/* - evaluate_retval - fi + export ACTION=remove + run_udev + evaluate_retval ;; reload) # nothing to do here From eea34a0e9909405467185bb1e5291e6cc88fd0bc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 18:10:53 -0800 Subject: [PATCH 0452/4284] [PATCH] clean up compiler warnings if building using klibc. --- Makefile | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 0fd158a2c7..30ebd45eed 100644 --- a/Makefile +++ b/Makefile @@ -94,7 +94,7 @@ OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2> then echo "-Os"; else echo "-O2" ; fi} # add -Wredundant-decls when libsysfs gets cleaned up -WARNINGS := -Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations +WARNINGS := -Wall # Some nice architecture specific optimizations ifeq ($(strip $(TARGET_ARCH)),arm) @@ -117,11 +117,11 @@ endif # if DEBUG is enabled, then we do not strip or optimize ifeq ($(strip $(DEBUG)),true) - CFLAGS += $(WARNINGS) -O1 -g -DDEBUG -D_GNU_SOURCE + CFLAGS += -O1 -g -DDEBUG -D_GNU_SOURCE LDFLAGS += -Wl,-warn-common STRIPCMD = /bin/true -Since_we_are_debugging else - CFLAGS += $(WARNINGS) $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE + CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE LDFLAGS += -s -Wl,-warn-common STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif @@ -142,15 +142,20 @@ ifeq ($(strip $(USE_KLIBC)),true) CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) - CFLAGS += -nostdinc -I$(INCLUDE_DIR) -I$(KLIBC_DIR)/arch/$(ARCH)/include \ - -I$(INCLUDE_DIR)/bits$(BITSIZE) -I$(GCCINCDIR) -I$(LINUX_INCLUDE_DIR) \ - -D__KLIBC__ -fno-builtin-printf + CFLAGS += $(WARNINGS) -nostdinc \ + -D__KLIBC__ -fno-builtin-printf \ + -I$(INCLUDE_DIR) \ + -I$(KLIBC_DIR)/arch/$(ARCH)/include \ + -I$(INCLUDE_DIR)/bits$(BITSIZE) \ + -I$(GCCINCDIR) \ + -I$(LINUX_INCLUDE_DIR) LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs else + WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations CRT0 = LIBC = - CFLAGS += -I$(GCCINCDIR) + CFLAGS += $(WARNINGS) -I$(GCCINCDIR) LIB_OBJS = -lc LDFLAGS = endif From a695feaeff0551745e1a397be2daa61b8cd0cc42 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 26 Jan 2004 18:19:33 -0800 Subject: [PATCH 0453/4284] [PATCH] udevd - cleanup and better timeout handling Here is the next revision for udevd: o Small cleanups all over the place. o Swich to the usual linked list format "list.h". o Better timeout handling. We store a timestamp in in every queued event, so we don't wait longer than the timeout specified, if the hole in the list is not shrinking. o ignore udevd target if klibc is used --- Makefile | 8 +- udevd.c | 227 ++++++++++++++++++++++++++--------------------------- udevd.h | 15 ++-- udevsend.c | 10 ++- 4 files changed, 131 insertions(+), 129 deletions(-) diff --git a/Makefile b/Makefile index 30ebd45eed..5c265492b4 100644 --- a/Makefile +++ b/Makefile @@ -151,6 +151,7 @@ ifeq ($(strip $(USE_KLIBC)),true) -I$(LINUX_INCLUDE_DIR) LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs + UDEVD = else WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations CRT0 = @@ -158,11 +159,12 @@ else CFLAGS += $(WARNINGS) -I$(GCCINCDIR) LIB_OBJS = -lc LDFLAGS = + UDEVD = $(DAEMON) $(SENDER) endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(DAEMON) $(SENDER) +all: $(ROOT) $(UDEVD) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ @@ -236,11 +238,11 @@ $(ROOT): $(OBJS) udev.h namedev.h udev_version.h udev_dbus.h udevdb.h klibc_fixu $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) -$(DAEMON): $(ROOT) udevd.h udevd.o +$(DAEMON): udevd.h udevd.o udevd.o logging.o $(LD) $(LDFLAGS) -o $(DAEMON) $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) -$(SENDER): $(ROOT) udevd.h udevsend.o +$(SENDER): udevd.h udevsend.o udevd.o logging.o $(LD) $(LDFLAGS) -o $(SENDER) $(CRT0) udevsend.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $(ROOT) diff --git a/udevd.c b/udevd.c index 2e63d8030e..26e6b23486 100644 --- a/udevd.c +++ b/udevd.c @@ -22,6 +22,7 @@ * */ +#include #include #include #include @@ -32,29 +33,38 @@ #include #include #include +#include #include +#include "list.h" #include "udev.h" #include "udevd.h" #include "logging.h" #define BUFFER_SIZE 1024 -#define EVENT_TIMEOUT_SECONDS 10 -#define DAEMON_TIMEOUT_SECONDS 30 - static int expect_seqnum = 0; -static struct hotplug_msg *head = NULL; +static int lock_file = -1; +static char *lock_filename = ".udevd_lock"; +LIST_HEAD(msg_list); -static void sig_alarmhandler(int signum) +static void sig_handler(int signum) { dbg("caught signal %d", signum); switch (signum) { case SIGALRM: dbg("event timeout reached"); break; - + case SIGINT: + case SIGTERM: + case SIGKILL: + if (lock_file >= 0) { + close(lock_file); + unlink(lock_filename); + } + exit(20 + signum); + break; default: dbg("unhandled signal"); } @@ -62,41 +72,32 @@ static void sig_alarmhandler(int signum) static void dump_queue(void) { - struct hotplug_msg *p; - p = head; + struct hotplug_msg *msg; - dbg("next expected sequence is %d", expect_seqnum); - while(p != NULL) { - dbg("sequence %d in queue", p->seqnum); - p = p->next; - } + list_for_each_entry(msg, &msg_list, list) + dbg("sequence %d in queue", msg->seqnum); } -static void dump_msg(struct hotplug_msg *pmsg) +static void dump_msg(struct hotplug_msg *msg) { dbg("sequence %d, '%s', '%s', '%s'", - pmsg->seqnum, pmsg->action, pmsg->devpath, pmsg->subsystem); + msg->seqnum, msg->action, msg->devpath, msg->subsystem); } -static int dispatch_msg(struct hotplug_msg *pmsg) +static int dispatch_msg(struct hotplug_msg *msg) { pid_t pid; - char *argv[3]; - extern char **environ; - dump_msg(pmsg); + dump_msg(msg); - setenv("ACTION", pmsg->action, 1); - setenv("DEVPATH", pmsg->devpath, 1); - argv[0] = DEFAULT_UDEV_EXEC; - argv[1] = pmsg->subsystem; - argv[2] = NULL; + setenv("ACTION", msg->action, 1); + setenv("DEVPATH", msg->devpath, 1); pid = fork(); switch (pid) { case 0: /* child */ - execve(argv[0], argv, environ); + execl(UDEV_EXEC, "udev", msg->subsystem, NULL); dbg("exec of child failed"); exit(1); break; @@ -104,108 +105,119 @@ static int dispatch_msg(struct hotplug_msg *pmsg) dbg("fork of child failed"); return -1; default: - wait(0); + wait(NULL); } return 0; } -static void set_timer(int seconds) +static void set_timeout(int seconds) { - signal(SIGALRM, sig_alarmhandler); alarm(seconds); + dbg("set timeout in %d seconds", seconds); } static void check_queue(void) { - struct hotplug_msg *p; - p = head; + struct hotplug_msg *msg; + struct hotplug_msg *tmp_msg; + time_t msg_age; - dump_queue(); - while(head != NULL && head->seqnum == expect_seqnum) { - dispatch_msg(head); +recheck: + /* dispatch events until one is missing */ + list_for_each_entry_safe(msg, tmp_msg, &msg_list, list) { + if (msg->seqnum != expect_seqnum) + break; + dispatch_msg(msg); expect_seqnum++; - p = head; - head = head->next; - free(p); + list_del_init(&msg->list); + free(msg); } - if (head != NULL) - set_timer(EVENT_TIMEOUT_SECONDS); - else - set_timer(DAEMON_TIMEOUT_SECONDS); + + /* recalculate timeout */ + if (list_empty(&msg_list) == 0) { + msg_age = time(NULL) - msg->queue_time; + if (msg_age > EVENT_TIMEOUT_SECONDS-1) { + info("event %d, age %li seconds, skip event %d-%d", + msg->seqnum, msg_age, expect_seqnum, msg->seqnum-1); + expect_seqnum = msg->seqnum; + goto recheck; + } + set_timeout(EVENT_TIMEOUT_SECONDS - msg_age); + return; + } + + /* queue is empty */ + set_timeout(UDEVD_TIMEOUT_SECONDS); } -static void add_queue(struct hotplug_msg *pmsg) +static int queue_msg(struct hotplug_msg *msg) { - struct hotplug_msg *pnewmsg; - struct hotplug_msg *p; - struct hotplug_msg *p1; + struct hotplug_msg *new_msg; + struct hotplug_msg *tmp_msg; - p = head; - p1 = NULL; - pnewmsg = malloc(sizeof(struct hotplug_msg)); - *pnewmsg = *pmsg; - pnewmsg->next = NULL; - while(p != NULL && pmsg->seqnum > p->seqnum) { - p1 = p; - p = p->next; + new_msg = malloc(sizeof(*new_msg)); + if (new_msg == NULL) { + dbg("error malloc"); + return -ENOMEM; } - pnewmsg->next = p; - if (p1 == NULL) { - head = pnewmsg; - } else { - p1->next = pnewmsg; - } - dump_queue(); + memcpy(new_msg, msg, sizeof(*new_msg)); + + /* store timestamp of queuing */ + new_msg->queue_time = time(NULL); + + /* sort message by sequence number into list*/ + list_for_each_entry(tmp_msg, &msg_list, list) + if (tmp_msg->seqnum > new_msg->seqnum) + break; + list_add_tail(&new_msg->list, &tmp_msg->list); + + return 0; } -static int lock_file = -1; -static char *lock_filename = ".udevd_lock"; - -static int process_queue(void) +static void work(void) { + struct hotplug_msg *msg; int msgid; key_t key; - struct hotplug_msg *pmsg; char buf[BUFFER_SIZE]; int ret; - key = ftok(DEFAULT_UDEVD_EXEC, IPC_KEY_ID); - pmsg = (struct hotplug_msg *) buf; + key = ftok(UDEVD_EXEC, IPC_KEY_ID); + msg = (struct hotplug_msg *) buf; msgid = msgget(key, IPC_CREAT); if (msgid == -1) { dbg("open message queue error"); - return -1; + exit(1); } while (1) { ret = msgrcv(msgid, (struct msgbuf *) buf, BUFFER_SIZE-4, HOTPLUGMSGTYPE, 0); if (ret != -1) { - dbg("current sequence %d, expected sequence %d", pmsg->seqnum, expect_seqnum); - - /* init expected sequence with value from first call */ + /* init the expected sequence with value from first call */ if (expect_seqnum == 0) { - expect_seqnum = pmsg->seqnum; + expect_seqnum = msg->seqnum; dbg("init next expected sequence number to %d", expect_seqnum); } - - if (pmsg->seqnum > expect_seqnum) { - add_queue(pmsg); - set_timer(EVENT_TIMEOUT_SECONDS); - } else { - if (pmsg->seqnum == expect_seqnum) { - dispatch_msg(pmsg); - expect_seqnum++; - check_queue(); - } else { - dbg("timeout event for unexpected sequence number %d", pmsg->seqnum); - } + dbg("current sequence %d, expected sequence %d", msg->seqnum, expect_seqnum); + if (msg->seqnum == expect_seqnum) { + /* execute expected event */ + dispatch_msg(msg); + expect_seqnum++; + check_queue(); + dump_queue(); + continue; } + if (msg->seqnum > expect_seqnum) { + /* something missing, queue event*/ + queue_msg(msg); + check_queue(); + dump_queue(); + continue; + } + dbg("too late for event with sequence %d, even skipped ", msg->seqnum); } else { if (errno == EINTR) { - if (head != NULL) { - /* event timeout, skip all missing, proceed with next queued event */ - info("timeout reached, skip events %d - %d", expect_seqnum, head->seqnum-1); - expect_seqnum = head->seqnum; - } else { + /* timeout */ + if (list_empty(&msg_list)) { info("we have nothing to do, so daemon exits..."); if (lock_file >= 0) { close(lock_file); @@ -214,31 +226,12 @@ static int process_queue(void) exit(0); } check_queue(); - } else { - dbg("ipc message receive error '%s'", strerror(errno)); + dump_queue(); + continue; } + dbg("ipc message receive error '%s'", strerror(errno)); } } - return 0; -} - -static void sig_handler(int signum) -{ - dbg("caught signal %d", signum); - switch (signum) { - case SIGINT: - case SIGTERM: - case SIGKILL: - if (lock_file >= 0) { - close(lock_file); - unlink(lock_filename); - } - exit(20 + signum); - break; - - default: - dbg("unhandled signal"); - } } static int one_and_only(void) @@ -249,18 +242,18 @@ static int one_and_only(void) /* see if we can open */ if (lock_file < 0) - return -EINVAL; + return -1; /* see if we can lock */ if (lockf(lock_file, F_TLOCK, 0) < 0) { close(lock_file); unlink(lock_filename); - return -EINVAL; + return -1; } snprintf(string, sizeof(string), "%d\n", getpid()); write(lock_file, string, strlen(string)); - + return 0; } @@ -274,11 +267,11 @@ int main(int argc, char *argv[]) signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); signal(SIGKILL, sig_handler); + signal(SIGALRM, sig_handler); /* we exit if we have nothing to do, next event will start us again */ - set_timer(DAEMON_TIMEOUT_SECONDS); + set_timeout(UDEVD_TIMEOUT_SECONDS); - /* main loop */ - process_queue(); - return 0; + work(); + exit(0); } diff --git a/udevd.h b/udevd.h index 43fe6b421a..c9b69bbc3c 100644 --- a/udevd.h +++ b/udevd.h @@ -21,17 +21,22 @@ * */ -#define DEFAULT_UDEV_EXEC "./udev" -#define DEFAULT_UDEVD_EXEC "./udevd" +#include "list.h" -#define IPC_KEY_ID 0 -#define HOTPLUGMSGTYPE 44 +#define UDEV_EXEC "./udev" +#define UDEVD_EXEC "./udevd" +#define UDEVD_TIMEOUT_SECONDS 60 +#define EVENT_TIMEOUT_SECONDS 5 + +#define IPC_KEY_ID 0 +#define HOTPLUGMSGTYPE 44 struct hotplug_msg { long mtype; - struct hotplug_msg *next; + struct list_head list; int seqnum; + time_t queue_time; char action[8]; char devpath[128]; char subsystem[16]; diff --git a/udevsend.c b/udevsend.c index bdc8293df7..3f3bbacbc2 100644 --- a/udevsend.c +++ b/udevsend.c @@ -64,6 +64,7 @@ static inline char *get_seqnum(void) static int build_hotplugmsg(struct hotplug_msg *msg, char *action, char *devpath, char *subsystem, int seqnum) { + memset(msg, 0x00, sizeof(msg)); msg->mtype = HOTPLUGMSGTYPE; msg->seqnum = seqnum; strncpy(msg->action, action, 8); @@ -85,7 +86,8 @@ static int start_daemon(void) switch (child_pid) { case 0: /* daemon */ - execl(DEFAULT_UDEVD_EXEC, NULL); + setsid(); + execl(UDEVD_EXEC, "udevd", NULL); dbg("exec of daemon failed"); exit(1); case -1: @@ -99,7 +101,7 @@ static int start_daemon(void) dbg("fork of helper failed"); return -1; default: - wait(0); + wait(NULL); } return 0; } @@ -147,7 +149,7 @@ int main(int argc, char* argv[]) seq = atoi(seqnum); /* create ipc message queue or get id of our existing one */ - key = ftok(DEFAULT_UDEVD_EXEC, IPC_KEY_ID); + key = ftok(UDEVD_EXEC, IPC_KEY_ID); size = build_hotplugmsg(&message, action, devpath, subsystem, seq); msgid = msgget(key, IPC_CREAT); if (msgid == -1) { @@ -165,7 +167,7 @@ int main(int argc, char* argv[]) /* get state of ipc queue */ tspec.tv_sec = 0; tspec.tv_nsec = 10000000; /* 10 millisec */ - loop = 20; + loop = 30; while (loop--) { retval = msgctl(msgid, IPC_STAT, &msg_queue); if (retval == -1) { From 87171e46cd9d179e0bb5549c4d74769a1be86e64 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 26 Jan 2004 18:20:12 -0800 Subject: [PATCH 0454/4284] [PATCH] udevinfo - now a real program :) I want to make udevinfo the standard query interface, so all the user features of the main udev are copied in here. It is now capable to: o query the database for a given value o dump the whole database o extract all possible device attributes for a sysfs_device In addition to the known options of udev it supports the query for the mode of the device node, and it includes the mode in the database dump: udevinfo -d P: /class/video4linux/video0 N: video/webcam0 M: 0666 S: camera0 kamera0 O: 500 G: 500 It is also a bit more friendly with the pathnames specified for devices or nodes. We remove the absolute path or add it if neccessary: udevinfo -q mode -n video/webcam0 udevinfo -q mode -n /udev/video/webcam0 0666 udevinfo -q mode -p /sys/class/video4linux/video0 udevinfo -q mode -p /class/video4linux/video0 udevinfo -q mode -p class/video4linux/video0 0666 --- extras/udevinfo/Makefile | 28 +++- extras/udevinfo/udevinfo.c | 295 +++++++++++++++++++++++++++++++++++-- 2 files changed, 301 insertions(+), 22 deletions(-) diff --git a/extras/udevinfo/Makefile b/extras/udevinfo/Makefile index f31c8c11e9..b740b25331 100644 --- a/extras/udevinfo/Makefile +++ b/extras/udevinfo/Makefile @@ -1,14 +1,28 @@ PROG=udevinfo -LD=$(CC) -OBJS=udevinfo.o +OBJS= ../../udev_config.o \ + ../../udev-add.o \ + ../../udev-remove.o \ + ../../udevdb.o \ + ../../logging.o \ + ../../namedev.o \ + ../../namedev_parse.o \ + ../../libsysfs/sysfs_bus.o \ + ../../libsysfs/sysfs_class.o \ + ../../libsysfs/sysfs_device.o \ + ../../libsysfs/sysfs_dir.o \ + ../../libsysfs/sysfs_driver.o \ + ../../libsysfs/sysfs_utils.o \ + ../../libsysfs/dlist.o \ + ../../tdb/tdb.o \ + ../../tdb/spinlock.o \ -all: $(PROG) +all: $(PROG) + +$(PROG): $(PROG).o + $(LD) $(LDFLAGS) -o $(PROG) $(PROG).o $(OBJS) -lc clean: - rm -f $(PROG) $(OBJS) - -$(PROG): $(OBJS) - $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) + rm -f $(PROG) $(OBJS) $(PROG).o me: cd ../..; make EXTRAS=extras/udevinfo diff --git a/extras/udevinfo/udevinfo.c b/extras/udevinfo/udevinfo.c index c5934be2d4..3f03901f49 100644 --- a/extras/udevinfo/udevinfo.c +++ b/extras/udevinfo/udevinfo.c @@ -23,21 +23,29 @@ #include #include #include +#include +#include +#include -#include "libsysfs.h" +#include "../../udev.h" +#include "../../udev_version.h" +#include "../../logging.h" +#include "../../udevdb.h" +#include "../../libsysfs/libsysfs.h" -# define VALUE_SIZE 200 +# define SYSFS_VALUE_MAX 200 char **main_argv; +int main_argc; char **main_envp; -static int print_all_attributes(char *path) +static int print_all_attributes(const char *path) { struct dlist *attributes; struct sysfs_attribute *attr; struct sysfs_directory *sysfs_dir; - char value[VALUE_SIZE]; + char value[SYSFS_VALUE_MAX]; int len; int retval = 0; @@ -53,7 +61,7 @@ static int print_all_attributes(char *path) dlist_for_each_data(attributes, attr, struct sysfs_attribute) { if (attr->value != NULL) { - strncpy(value, attr->value, VALUE_SIZE); + strncpy(value, attr->value, SYSFS_VALUE_MAX); len = strlen(value); if (len == 0) continue; @@ -82,24 +90,38 @@ exit: return retval; } -int main(int argc, char **argv, char **envp) +/* callback for database dump */ +static int print_record(char *path, struct udevice *dev) +{ + printf("P: %s\n", path); + printf("N: %s\n", dev->name); + printf("M: %#o\n", dev->mode); + printf("S: %s\n", dev->symlink); + printf("O: %s\n", dev->owner); + printf("G: %s\n", dev->group); + printf("\n"); + return 0; +} + +enum query_type { + NONE, + NAME, + PATH, + SYMLINK, + MODE, + OWNER, + GROUP +}; + +static int print_device_chain(const char *path) { - main_argv = argv; - main_envp = envp; struct sysfs_class_device *class_dev; struct sysfs_class_device *class_dev_parent; struct sysfs_attribute *attr; struct sysfs_device *sysfs_dev; struct sysfs_device *sysfs_dev_parent; - char *path; int retval = 0; - if (argc != 2) { - printf("Usage: udevinfo \n"); - return -1; - } - path = argv[1]; - /* get the class dev */ class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { @@ -157,3 +179,246 @@ exit: //sysfs_close_class_device(class_dev); return retval; } + +static int process_options(void) +{ + static const char short_options[] = "adn:p:q:rVh"; + int option; + int retval = 1; + struct udevice dev; + int root = 0; + int attributes = 0; + enum query_type query = NONE; + char result[NAME_SIZE] = ""; + char path[NAME_SIZE] = ""; + char name[NAME_SIZE] = ""; + char temp[NAME_SIZE]; + char *pos; + + /* get command line options */ + while (1) { + option = getopt(main_argc, main_argv, short_options); + if (option == -1) + break; + + dbg("option '%c'", option); + switch (option) { + case 'n': + dbg("udev name: %s\n", optarg); + strfieldcpy(name, optarg); + break; + + case 'p': + dbg("udev path: %s\n", optarg); + strfieldcpy(path, optarg); + break; + + case 'q': + dbg("udev query: %s\n", optarg); + + if (strcmp(optarg, "name") == 0) { + query = NAME; + break; + } + + if (strcmp(optarg, "symlink") == 0) { + query = SYMLINK; + break; + } + + if (strcmp(optarg, "mode") == 0) { + query = MODE; + break; + } + + if (strcmp(optarg, "owner") == 0) { + query = OWNER; + break; + } + + if (strcmp(optarg, "group") == 0) { + query = GROUP; + break; + } + + if (strcmp(optarg, "path") == 0) { + query = PATH; + break; + } + + printf("unknown query type\n"); + exit(1); + + case 'r': + root = 1; + break; + + case 'a': + attributes = 1; + break; + + case 'd': + retval = udevdb_open_ro(); + if (retval != 0) { + printf("unable to open udev database\n"); + exit(2); + } + udevdb_call_foreach(print_record); + udevdb_exit(); + exit(0); + + case 'V': + printf("udev, version %s\n", UDEV_VERSION); + exit(0); + + case 'h': + retval = 0; + case '?': + default: + goto help; + } + } + + /* process options */ + if (query != NONE) { + retval = udevdb_open_ro(); + if (retval != 0) { + printf("unable to open udev database\n"); + return -EACCES; + } + + if (path[0] != '\0') { + /* remove sysfs_path if given */ + if (strncmp(path, sysfs_path, strlen(sysfs_path)) == 0) { + pos = path + strlen(sysfs_path); + } else { + if (path[0] != '/') { + /* prepend '/' if missing */ + strcat(temp, "/"); + strncat(temp, path, sizeof(path)); + pos = temp; + } else { + pos = path; + } + } + retval = udevdb_get_dev(pos, &dev); + if (retval != 0) { + printf("device not found in database\n"); + goto exit; + } + goto print; + } + + if (name[0] != '\0') { + /* remove udev_root if given */ + if (strncmp(name, udev_root, strlen(udev_root)) == 0) { + pos = name + strlen(udev_root); + } else + pos = name; + retval = udevdb_get_dev_byname(pos, path, &dev); + if (retval != 0) { + printf("device not found in database\n"); + goto exit; + } + goto print; + } + + printf("query needs device path(-p) or node name(-n) specified\n"); + goto exit; + +print: + switch(query) { + case NAME: + if (root) + strfieldcpy(result, udev_root); + strncat(result, dev.name, sizeof(result)); + break; + + case SYMLINK: + strfieldcpy(result, dev.symlink); + break; + + case MODE: + sprintf(result, "%#o", dev.mode); + break; + + case GROUP: + strfieldcpy(result, dev.group); + break; + + case OWNER: + strfieldcpy(result, dev.owner); + break; + + case PATH: + strfieldcpy(result, path); + break; + + default: + goto exit; + } + printf("%s\n", result); + +exit: + udevdb_exit(); + return retval; + } + + if (attributes) { + if (path[0] == '\0') { + printf("attribute walk on device chain needs path(-p) specified\n"); + return -EINVAL; + } else { + if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) { + /* prepend sysfs mountpoint if not given */ + strfieldcpy(temp, path); + strfieldcpy(path, sysfs_path); + strncat(path, temp, sizeof(path)); + } + print_device_chain(path); + return 0; + } + } + + if (root) { + printf("%s\n", udev_root); + return 0; + } + +help: + printf("Usage: [-anpqrdVh]\n" + " -q TYPE query database for the specified value:\n" + " 'name' name of device node\n" + " 'symlink' pointing to node\n" + " 'mode' permissions of node\n" + " 'owner' of node\n" + " 'group' of node\n" + " 'path' sysfs device path\n" + " -p PATH sysfs device path used for query or chain\n" + " -n NAME node name used for query\n" + "\n" + " -r print udev root\n" + " -a print all attributes along the chain of the device\n" + " -d dump whole database\n" + " -V print udev version\n" + " -h print this help text\n" + "\n"); + return retval; +} + +int main(int argc, char *argv[], char *envp[]) +{ + int retval; + + main_argv = argv; + main_argc = argc; + main_envp = envp; + + /* initialize our configuration */ + udev_init_config(); + + retval = process_options(); + if (retval != 0) + exit(1); + exit(0); +} From 869fc2f1ff73209b9aa5dc7d582eba39feaf6f86 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 18:55:37 -0800 Subject: [PATCH 0455/4284] [PATCH] move udevinfo into the main build and clean up the main Makefile a bit. --- Makefile | 34 +++++++++++++++++------- extras/udevinfo/Makefile | 28 ------------------- extras/udevinfo/udevinfo.c => udevinfo.c | 12 ++++----- 3 files changed, 30 insertions(+), 44 deletions(-) delete mode 100644 extras/udevinfo/Makefile rename extras/udevinfo/udevinfo.c => udevinfo.c (97%) diff --git a/Makefile b/Makefile index 5c265492b4..20c739e404 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ USE_DBUS = false ROOT = udev DAEMON = udevd SENDER = udevsend +HELPERS = udevinfo VERSION = 014_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -164,7 +165,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(UDEVD) +all: $(ROOT) $(UDEVD) $(HELPERS) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ @@ -189,8 +190,7 @@ SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ $(PWD)/libsysfs/sysfs_utils.o \ $(PWD)/libsysfs/dlist.o -OBJS = udev.o \ - udev_config.o \ +OBJS = udev_config.o \ udev-add.o \ udev-remove.o \ udevdb.o \ @@ -200,6 +200,16 @@ OBJS = udev.o \ $(SYSFS) \ $(TDB) +HEADERS = $(GEN_HEADERS) \ + udev.h \ + namedev.h \ + udev_version.h \ + udev_dbus.h \ + udevdb.h \ + klibc_fixups.h \ + logging.h \ + list.h + ifeq ($(strip $(USE_KLIBC)),true) OBJS += klibc_fixups.o endif @@ -234,17 +244,21 @@ $(LOCAL_CFG_DIR)/udev.conf: $(OBJS): $(GEN_HEADERS) -$(ROOT): $(OBJS) udev.h namedev.h udev_version.h udev_dbus.h udevdb.h klibc_fixups.h logging.h list.h - $(LD) $(LDFLAGS) -o $(ROOT) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $(ROOT) +$(ROOT): udev.o $(OBJS) $(HEADERS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $@ + +$(HELPERS): udevinfo.o $(OBJS) $(HEADERS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $@ $(DAEMON): udevd.h udevd.o udevd.o logging.o - $(LD) $(LDFLAGS) -o $(DAEMON) $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $(ROOT) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $@ $(SENDER): udevd.h udevsend.o udevd.o logging.o - $(LD) $(LDFLAGS) -o $(SENDER) $(CRT0) udevsend.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $(ROOT) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $@ clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ diff --git a/extras/udevinfo/Makefile b/extras/udevinfo/Makefile deleted file mode 100644 index b740b25331..0000000000 --- a/extras/udevinfo/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -PROG=udevinfo -OBJS= ../../udev_config.o \ - ../../udev-add.o \ - ../../udev-remove.o \ - ../../udevdb.o \ - ../../logging.o \ - ../../namedev.o \ - ../../namedev_parse.o \ - ../../libsysfs/sysfs_bus.o \ - ../../libsysfs/sysfs_class.o \ - ../../libsysfs/sysfs_device.o \ - ../../libsysfs/sysfs_dir.o \ - ../../libsysfs/sysfs_driver.o \ - ../../libsysfs/sysfs_utils.o \ - ../../libsysfs/dlist.o \ - ../../tdb/tdb.o \ - ../../tdb/spinlock.o \ - -all: $(PROG) - -$(PROG): $(PROG).o - $(LD) $(LDFLAGS) -o $(PROG) $(PROG).o $(OBJS) -lc - -clean: - rm -f $(PROG) $(OBJS) $(PROG).o - -me: - cd ../..; make EXTRAS=extras/udevinfo diff --git a/extras/udevinfo/udevinfo.c b/udevinfo.c similarity index 97% rename from extras/udevinfo/udevinfo.c rename to udevinfo.c index 3f03901f49..a2f5601b7c 100644 --- a/extras/udevinfo/udevinfo.c +++ b/udevinfo.c @@ -27,11 +27,11 @@ #include #include -#include "../../udev.h" -#include "../../udev_version.h" -#include "../../logging.h" -#include "../../udevdb.h" -#include "../../libsysfs/libsysfs.h" +#include "udev.h" +#include "udev_version.h" +#include "logging.h" +#include "udevdb.h" +#include "libsysfs/libsysfs.h" # define SYSFS_VALUE_MAX 200 @@ -268,7 +268,7 @@ static int process_options(void) exit(0); case 'V': - printf("udev, version %s\n", UDEV_VERSION); + printf("udevinfo, version %s\n", UDEV_VERSION); exit(0); case 'h': From 1f6d07b9a5d97183a20f3d07619e2f9aa31510f0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:21:12 -0800 Subject: [PATCH 0456/4284] [PATCH] more makefile cleanups --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 20c739e404..23b6ff87d8 100644 --- a/Makefile +++ b/Makefile @@ -200,8 +200,7 @@ OBJS = udev_config.o \ $(SYSFS) \ $(TDB) -HEADERS = $(GEN_HEADERS) \ - udev.h \ +HEADERS = udev.h \ namedev.h \ udev_version.h \ udev_dbus.h \ @@ -243,13 +242,14 @@ $(LOCAL_CFG_DIR)/udev.conf: $(OBJS): $(GEN_HEADERS) +udev.o: $(GEN_HEADERS) -$(ROOT): udev.o $(OBJS) $(HEADERS) +$(ROOT): udev.o $(OBJS) $(HEADERS) $(GEN_HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(HELPERS): udevinfo.o $(OBJS) $(HEADERS) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o logging.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(DAEMON): udevd.h udevd.o udevd.o logging.o From 274812b502089c55acb1bc7bfe99bebf9ce669b2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:21:58 -0800 Subject: [PATCH 0457/4284] [PATCH] move get_pair to udev_config.c because udevinfo doesn't need all of namedev.o --- namedev.h | 4 +--- namedev_parse.c | 39 ++------------------------------------- udev.h | 1 + udev_config.c | 39 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 42 deletions(-) diff --git a/namedev.h b/namedev.h index 42b1e6c1a0..9cff3710d4 100644 --- a/namedev.h +++ b/namedev.h @@ -3,7 +3,7 @@ * * Userspace devfs * - * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003,2004 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 @@ -91,6 +91,4 @@ extern void dump_config_dev_list(void); extern void dump_perm_dev(struct perm_device *dev); extern void dump_perm_dev_list(void); -extern int get_pair(char **orig_string, char **left, char **right); - #endif diff --git a/namedev_parse.c b/namedev_parse.c index b15be0e6fa..e6575fa108 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -3,7 +3,7 @@ * * Userspace devfs * - * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003,2004 Greg Kroah-Hartman * * * This program is free software; you can redistribute it and/or modify it @@ -52,41 +52,6 @@ static int add_config_dev(struct config_device *new_dev) return 0; } -int get_pair(char **orig_string, char **left, char **right) -{ - char *temp; - char *string = *orig_string; - - if (!string) - return -ENODEV; - - /* eat any whitespace */ - while (isspace(*string) || *string == ',') - ++string; - - /* split based on '=' */ - temp = strsep(&string, "="); - *left = temp; - if (!string) - return -ENODEV; - - /* take the right side and strip off the '"' */ - while (isspace(*string)) - ++string; - if (*string == '"') - ++string; - else - return -ENODEV; - - temp = strsep(&string, "\""); - if (!string || *temp == '\0') - return -ENODEV; - *right = temp; - *orig_string = string; - - return 0; -} - void dump_config_dev(struct config_device *dev) { /*FIXME dump all sysfs's */ @@ -166,7 +131,7 @@ int namedev_init_rules(void) /* get all known keys */ while (1) { - retval = get_pair(&temp, &temp2, &temp3); + retval = parse_get_pair(&temp, &temp2, &temp3); if (retval) break; diff --git a/udev.h b/udev.h index e5c983a212..f854a183d3 100644 --- a/udev.h +++ b/udev.h @@ -59,6 +59,7 @@ do { \ extern int udev_add_device(char *path, char *subsystem); extern int udev_remove_device(char *path, char *subsystem); extern void udev_init_config(void); +extern int parse_get_pair(char **orig_string, char **left, char **right); extern char **main_argv; extern char **main_envp; diff --git a/udev_config.c b/udev_config.c index e75ee3a346..6d39d294e1 100644 --- a/udev_config.c +++ b/udev_config.c @@ -3,7 +3,7 @@ * * Userspace devfs * - * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003,2004 Greg Kroah-Hartman * * * This program is free software; you can redistribute it and/or modify it @@ -68,6 +68,41 @@ static void init_variables(void) strncpy(_var, value, sizeof(_var)); \ } +int parse_get_pair(char **orig_string, char **left, char **right) +{ + char *temp; + char *string = *orig_string; + + if (!string) + return -ENODEV; + + /* eat any whitespace */ + while (isspace(*string) || *string == ',') + ++string; + + /* split based on '=' */ + temp = strsep(&string, "="); + *left = temp; + if (!string) + return -ENODEV; + + /* take the right side and strip off the '"' */ + while (isspace(*string)) + ++string; + if (*string == '"') + ++string; + else + return -ENODEV; + + temp = strsep(&string, "\""); + if (!string || *temp == '\0') + return -ENODEV; + *right = temp; + *orig_string = string; + + return 0; +} + static int parse_config_file(void) { char line[255]; @@ -108,7 +143,7 @@ static int parse_config_file(void) if (*temp == COMMENT_CHARACTER) continue; - retval = get_pair(&temp, &variable, &value); + retval = parse_get_pair(&temp, &variable, &value); if (retval) break; From ac4dc8746501ae3b9c859e5714f508d90cbe41a7 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:22:31 -0800 Subject: [PATCH 0458/4284] [PATCH] udevinfo doesn't need to declare main_envp --- udevinfo.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index a2f5601b7c..aa9d20a773 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -38,7 +38,6 @@ char **main_argv; int main_argc; -char **main_envp; static int print_all_attributes(const char *path) { @@ -412,7 +411,6 @@ int main(int argc, char *argv[], char *envp[]) main_argv = argv; main_argc = argc; - main_envp = envp; /* initialize our configuration */ udev_init_config(); From 8202eb32b97a236dac725bfe24e390840ded7098 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:23:11 -0800 Subject: [PATCH 0459/4284] [PATCH] rip out command line code from udev, now that we have udevinfo. --- udev.c | 233 +++------------------------------------------------------ 1 file changed, 12 insertions(+), 221 deletions(-) diff --git a/udev.c b/udev.c index 3b701ac26f..4c67477c20 100644 --- a/udev.c +++ b/udev.c @@ -3,8 +3,7 @@ * * Userspace devfs * - * Copyright (C) 2003 Greg Kroah-Hartman - * + * Copyright (C) 2003,2004 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 @@ -24,12 +23,9 @@ #include #include #include -#include -#include #include #include #include -#include #include "udev.h" #include "udev_version.h" @@ -83,201 +79,6 @@ static inline char *get_seqnum(void) return seqnum; } -/* callback for database dump */ -static int print_record(char *path, struct udevice *dev) -{ - printf("P: %s\n", path); - printf("N: %s\n", dev->name); - printf("S: %s\n", dev->symlink); - printf("O: %s\n", dev->owner); - printf("G: %s\n", dev->group); - printf("\n"); - return 0; -} - -enum query_type { - NONE, - NAME, - PATH, - SYMLINK, - OWNER, - GROUP -}; - -static inline int udev_user(int argc, char **argv) -{ - static const char short_options[] = "dn:p:q:rVh"; - int option; - int retval = -EINVAL; - struct udevice dev; - int root = 0; - enum query_type query = NONE; - char result[NAME_SIZE] = ""; - char path[NAME_SIZE] = ""; - char name[NAME_SIZE] = ""; - - /* get command line options */ - while (1) { - option = getopt(argc, argv, short_options); - if (option == -1) - break; - - dbg("option '%c'", option); - switch (option) { - case 'n': - dbg("udev name: %s\n", optarg); - strfieldcpy(name, optarg); - break; - - case 'p': - dbg("udev path: %s\n", optarg); - strfieldcpy(path, optarg); - break; - - case 'q': - dbg("udev query: %s\n", optarg); - - if (strcmp(optarg, "name") == 0) { - query = NAME; - break; - } - - if (strcmp(optarg, "symlink") == 0) { - query = SYMLINK; - break; - } - - if (strcmp(optarg, "owner") == 0) { - query = OWNER; - break; - } - - if (strcmp(optarg, "group") == 0) { - query = GROUP; - break; - } - - if (strcmp(optarg, "path") == 0) { - query = PATH; - break; - } - - printf("unknown query type\n"); - return -EINVAL; - - case 'r': - root = 1; - break; - - case 'd': - retval = udevdb_open_ro(); - if (retval != 0) { - printf("unable to open udev database\n"); - return -EACCES; - } - retval = udevdb_call_foreach(print_record); - udevdb_exit(); - return retval; - - case 'V': - printf("udev, version %s\n", UDEV_VERSION); - return 0; - - case 'h': - retval = 0; - case '?': - default: - goto help; - } - } - - /* process options */ - if (query != NONE) { - retval = udevdb_open_ro(); - if (retval != 0) { - printf("unable to open udev database\n"); - return -EACCES; - } - - if (path[0] != '\0') { - retval = udevdb_get_dev(path, &dev); - if (retval != 0) { - printf("device not found in database\n"); - goto exit; - } - goto print; - } - - if (name[0] != '\0') { - retval = udevdb_get_dev_byname(name, path, &dev); - if (retval != 0) { - printf("device not found in database\n"); - goto exit; - } - goto print; - } - - printf("query needs device path(-p) or node name(-n) specified\n"); - goto exit; - -print: - switch(query) { - case NAME: - if (root) - strfieldcpy(result, udev_root); - strncat(result, dev.name, sizeof(result)); - break; - - case SYMLINK: - strfieldcpy(result, dev.symlink); - break; - - case GROUP: - strfieldcpy(result, dev.group); - break; - - case OWNER: - strfieldcpy(result, dev.owner); - break; - - case PATH: - strfieldcpy(result, path); - break; - - default: - goto exit; - } - printf("%s\n", result); - -exit: - udevdb_exit(); - return retval; - } - - if (root) { - printf("%s\n", udev_root); - return 0; - } - -help: - printf("Usage: [-npqrdVh]\n" - " -q TYPE query database for the specified value:\n" - " 'name' name of device node\n" - " 'symlink' pointing to node\n" - " 'owner' of node\n" - " 'group' of node\n" - " 'path' sysfs device path\n" - " -p PATH sysfs device path used for query\n" - " -n NAME node name used for query\n" - "\n" - " -r print udev root\n" - " -d dump whole database\n" - " -V print udev version\n" - " -h print this help text\n" - "\n"); - return retval; -} - static char *subsystem_blacklist[] = { "net", "scsi_host", @@ -287,7 +88,7 @@ static char *subsystem_blacklist[] = { "", }; -static inline int udev_hotplug(int argc, char **argv) +static int udev_hotplug(int argc, char **argv) { char *action; char *devpath; @@ -295,7 +96,11 @@ static inline int udev_hotplug(int argc, char **argv) int retval = -EINVAL; int i; - subsystem = argv[1]; + action = get_action(); + if (!action) { + dbg ("no action?"); + goto exit; + } devpath = get_devpath(); if (!devpath) { @@ -312,6 +117,7 @@ static inline int udev_hotplug(int argc, char **argv) } /* skip blacklisted subsystems */ + subsystem = argv[1]; i = 0; while (subsystem_blacklist[i][0] != '\0') { if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { @@ -321,15 +127,12 @@ static inline int udev_hotplug(int argc, char **argv) i++; } - action = get_action(); - if (!action) { - dbg ("no action?"); - goto exit; - } - /* connect to the system message bus */ sysbus_connect(); + /* initialize our configuration */ + udev_init_config(); + /* initialize udev database */ retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { @@ -370,24 +173,12 @@ exit: int main(int argc, char **argv, char **envp) { - int retval; main_argv = argv; main_envp = envp; dbg("version %s", UDEV_VERSION); - /* initialize our configuration */ - udev_init_config(); - - if (argc == 2 && argv[1][0] != '-') { - dbg("called by hotplug"); - retval = udev_hotplug(argc, argv); - } else { - dbg("called by user"); - retval = udev_user(argc, argv); - } - - return retval; + return udev_hotplug(argc, argv); } From 245f9f52cec28b0377376beec222c8d5c0d07276 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:32:01 -0800 Subject: [PATCH 0460/4284] [PATCH] add udevinfo to install target of Makefile --- Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 23b6ff87d8..7846086294 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ USE_DBUS = false ROOT = udev DAEMON = udevd SENDER = udevsend -HELPERS = udevinfo +HELPER = udevinfo VERSION = 014_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -165,7 +165,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(UDEVD) $(HELPERS) +all: $(ROOT) $(UDEVD) $(HELPER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ @@ -248,7 +248,7 @@ $(ROOT): udev.o $(OBJS) $(HEADERS) $(GEN_HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(HELPERS): udevinfo.o $(OBJS) $(HEADERS) +$(HELPER): udevinfo.o $(OBJS) $(HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o logging.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ @@ -336,6 +336,7 @@ install: install-config install-dbus-policy all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) + $(INSTALL_PROGRAM) -D $(HELPER) $(DESTDIR)$(sbindir)/$(HELPER) @if [ "x$(USE_LSB)" = "xtrue" ]; then \ $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ ln -s $(DESTDIR)$(initdir)/udev $(sbin_dir)/rcudev; \ @@ -359,6 +360,7 @@ uninstall: uninstall-dbus-policy - rm $(initdir)/udev - rm $(mandir)/man8/udev.8 - rm $(sbindir)/$(ROOT) + - rm $(sbindir)/$(HELPER) - rmdir $(hotplugdir) - rmdir $(configdir) - rmdir $(udevdir) From da1cc7cc5fc671312436cd6122fcb6022cbcfd83 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:32:57 -0800 Subject: [PATCH 0461/4284] [PATCH] add udevinfo to udev.spec file. --- udev.spec | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/udev.spec b/udev.spec index 8494143ec0..2be4496f40 100644 --- a/udev.spec +++ b/udev.spec @@ -85,6 +85,7 @@ rm -rf $RPM_BUILD_ROOT %defattr(-,root,root) %doc COPYING README TODO ChangeLog %attr(755,root,root) /sbin/udev +%attr(755,root,root) /sbin/udevinfo %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf @@ -98,6 +99,9 @@ rm -rf $RPM_BUILD_ROOT %attr(0644,root,root) %{_mandir}/man8/udev.8* %changelog +* Mon Jan 26 2004 Greg Kroah-Hartman +- add udevinfo to rpm + * Mon Jan 05 2004 Rolf Eike Beer - add defines to choose the init script (Redhat or LSB) From 8fc34188503e0dd131eb215b7b1832e21434c7c8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:41:00 -0800 Subject: [PATCH 0462/4284] [PATCH] added URL to spec file. --- udev.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev.spec b/udev.spec index 2be4496f40..b9a20ac5fd 100644 --- a/udev.spec +++ b/udev.spec @@ -36,6 +36,7 @@ Group: Utilities/System Source: ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug/%{name}-%{version}.tar.gz ExclusiveOS: Linux Vendor: Greg Kroah-Hartman +URL : kernel.org/pub/linux/utils/kernel/hotplug/ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root Prereq: /bin/sh, fileutils, hotplug @@ -101,6 +102,7 @@ rm -rf $RPM_BUILD_ROOT %changelog * Mon Jan 26 2004 Greg Kroah-Hartman - add udevinfo to rpm +- added URL to spec file * Mon Jan 05 2004 Rolf Eike Beer - add defines to choose the init script (Redhat or LSB) From e31474a1e1ede5692f6dd7c710e4f2682588659e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:56:19 -0800 Subject: [PATCH 0463/4284] [PATCH] create initial version of udevinfo man page. --- Makefile | 2 ++ udevinfo.8 | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+) create mode 100644 udevinfo.8 diff --git a/Makefile b/Makefile index 7846086294..0fa39d7a41 100644 --- a/Makefile +++ b/Makefile @@ -344,6 +344,7 @@ install: install-config install-dbus-policy all $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ fi $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 + $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - ln -f -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug @extras="$(EXTRAS)" ; for target in $$extras ; do \ @@ -359,6 +360,7 @@ uninstall: uninstall-dbus-policy - rm $(configdir)/udev.conf - rm $(initdir)/udev - rm $(mandir)/man8/udev.8 + - rm $(mandir)/man8/udevinfo.8 - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(HELPER) - rmdir $(hotplugdir) diff --git a/udevinfo.8 b/udevinfo.8 new file mode 100644 index 0000000000..852e2ae93f --- /dev/null +++ b/udevinfo.8 @@ -0,0 +1,52 @@ +.TH UDEVINFO 8 "October 2003" "" "Linux Administrator's Manual" +.SH NAME +udevinfo \- retrieve information from udev +.SH SYNOPSIS +.B udevinfo +.RI "[-q " query_type " -p " sysfs_path "] [-drVh]" +.SH "DESCRIPTION" +.B udevinfo +allows users to query the udev database for information on any of the devices +currently present in the system. It also provides a way to query any device +in the sysfs tree to help in creating +.B udev +rule files. +.SH "OPTIONS" +.TP +.B -V +Print the version information. +.TP +.B -r +Print the the +.B udev_root +directory. When used in conjunction with a query for the node name, the +.B udev_root +will be prepended. +.TP +.BI -q " query_type" +Query the database for specified value of a created device node. +Valid types are: +.BR name ", " symlink ", " owner " , " group " or " path. +.TP +.BI -p " sysfs_path" +Specify the sysfs path of the device to query. +.TP +.BI -n " name" +Specify the name of the node for the device to query. +.TP +.B -d +Dump the whole database. +.TP +.B -h +Print help text. +.SH "FILES" +.nf +/etc/udev/* udev config files +.fi +.LP +.SH "SEE ALSO" +.BR udev (8) +.SH AUTHORS +.B udevinfo +was developed primarily by Kay Sievers , with help +from others. From 05c0c9da0b49d53ce5cf8e3f20a17e3b7b1566e1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:56:43 -0800 Subject: [PATCH 0464/4284] [PATCH] remove command line documentation from udev man page --- udev.8 | 38 +------------------------------------- 1 file changed, 1 insertion(+), 37 deletions(-) diff --git a/udev.8 b/udev.8 index 9a597276c6..0c8f2b1e60 100644 --- a/udev.8 +++ b/udev.8 @@ -3,9 +3,6 @@ udev \- Linux configurable dynamic device naming support .SH SYNOPSIS .BI udev " hotplug-subsystem" -.br -.B udev -.RI "[-q " query_type " -p " sysfs_path "] [-drVh]" .SH "DESCRIPTION" .B udev creates or removes device node files usually located in the /dev directory. @@ -29,40 +26,6 @@ maintains a database for devices present on the system. On device removal, .B udev queries its database for the name of the device file to be deleted. -.SH "OPTIONS" -.B udev -normally is called by -.B hotplug -with the subsystem as argument and various environment variables set. -.br -It may also called with the following options: -.TP -.B -V -Print the version information. -.TP -.B -r -Print the the -.B udev_root -directory. When used in conjunction with a query for the node name, the -.B udev_root -will be prepended. -.TP -.BI -q " query_type" -Query the database for specified value of a created device node. -Valid types are: -.BR name ", " symlink ", " owner " , " group " or " path. -.TP -.BI -p " sysfs_path" -Specify the sysfs path of the device to query. -.TP -.BI -n " name" -Specify the name of the node for the device to query. -.TP -.B -d -Dump the whole database. -.TP -.B -h -Print help text. .SH "CONFIGURATION" All .B udev @@ -296,6 +259,7 @@ following the '[' is a '!' then any character not enclosed is matched. .fi .LP .SH "SEE ALSO" +.BR udevinfo (8), .BR hotplug (8) .PP The From 567f6d14e8dec7d252601b90808c320b136d6e60 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 19:56:59 -0800 Subject: [PATCH 0465/4284] [PATCH] add udevinfo man page to spec file. --- udev.spec | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/udev.spec b/udev.spec index b9a20ac5fd..b622237e67 100644 --- a/udev.spec +++ b/udev.spec @@ -97,12 +97,13 @@ rm -rf $RPM_BUILD_ROOT %endif %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev -%attr(0644,root,root) %{_mandir}/man8/udev.8* +%attr(0644,root,root) %{_mandir}/man8/udev*.8* %changelog * Mon Jan 26 2004 Greg Kroah-Hartman -- add udevinfo to rpm +- added udevinfo to rpm - added URL to spec file +- added udevinfo's man page * Mon Jan 05 2004 Rolf Eike Beer - add defines to choose the init script (Redhat or LSB) From 28706bd9a1110f00f40888251425eea6e4bc22e1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 20:04:26 -0800 Subject: [PATCH 0466/4284] [PATCH] clean up udevinfo on 'make clean' --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0fa39d7a41..2712f265f5 100644 --- a/Makefile +++ b/Makefile @@ -263,7 +263,7 @@ $(SENDER): udevd.h udevsend.o udevd.o logging.o clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(DAEMON) $(SENDER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(HELPER) $(DAEMON) $(SENDER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ From 125611d9d47bd3a99ed6ce90ed327860de022e8a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 20:17:10 -0800 Subject: [PATCH 0467/4284] [PATCH] update klibc to version 0.98 --- klibc/klibc/SYSCALLS | 8 ++ klibc/klibc/arch/i386/include/sys/io.h | 126 +++++++++++++++++++++++ klibc/klibc/arch/i386/include/sys/vm86.h | 41 ++++++++ klibc/klibc/arch/x86_64/include/sys/io.h | 126 +++++++++++++++++++++++ klibc/klibc/fopen.c | 12 +-- klibc/klibc/include/stdio.h | 11 +- klibc/klibc/include/unistd.h | 1 + klibc/klibc/makeerrlist.pl | 2 +- klibc/klibc/syscommon.h | 4 + klibc/version | 2 +- 10 files changed, 320 insertions(+), 13 deletions(-) create mode 100644 klibc/klibc/arch/i386/include/sys/io.h create mode 100644 klibc/klibc/arch/i386/include/sys/vm86.h create mode 100644 klibc/klibc/arch/x86_64/include/sys/io.h diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS index 0be1b4425a..00883cc098 100644 --- a/klibc/klibc/SYSCALLS +++ b/klibc/klibc/SYSCALLS @@ -71,6 +71,7 @@ int chdir(const char *) int rename(const char *, const char *) int mknod(const char *, mode_t, dev_t) int chmod(const char *, mode_t) +int fchmod(int, mode_t) int mkdir(const char *, mode_t) int rmdir(const char *) int pipe(int *) @@ -144,3 +145,10 @@ long delete_module(const char *, unsigned int) int query_module(const char *, int, void *, size_t, size_t) int reboot::__reboot(int, int, int, void *) int syslog::klogctl(int, char *, int) + +# +# Low-level I/O (generally architecture-specific) +# + int iopl(int) + int ioperm(unsigned long, unsigned long, int) + int vm86(struct vm86_struct *) diff --git a/klibc/klibc/arch/i386/include/sys/io.h b/klibc/klibc/arch/i386/include/sys/io.h new file mode 100644 index 0000000000..b051464dfc --- /dev/null +++ b/klibc/klibc/arch/i386/include/sys/io.h @@ -0,0 +1,126 @@ +#ident "$Id: io.h,v 1.2 2004/01/25 07:49:39 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * sys/io.h for the i386 architecture + * + * Basic I/O macros + */ + +#ifndef _SYS_IO_H +#define _SYS_IO_H 1 + +/* I/O-related system calls */ + +int iopl(int); +int ioperm(unsigned long, unsigned long, int); + +/* Basic I/O macros */ + +static __inline__ void +outb(unsigned char __v, unsigned short __p) +{ + asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outw(unsigned short __v, unsigned short __p) +{ + asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outl(unsigned int __v, unsigned short __p) +{ + asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ unsigned char +inb(unsigned short __p) +{ + unsigned char __v; + asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); + return __v; +} + +static __inline__ unsigned short +inw(unsigned short __p) +{ + unsigned short __v; + asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); + return __v; +} + +static __inline__ unsigned int +inl(unsigned short __p) +{ + unsigned int __v; + asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); + return __v; +} + +/* String I/O macros */ + +static __inline__ void +outsb (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsw (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsl (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + + +static __inline__ void +insb (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insw (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insl (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +#endif /* _SYS_IO_H */ diff --git a/klibc/klibc/arch/i386/include/sys/vm86.h b/klibc/klibc/arch/i386/include/sys/vm86.h new file mode 100644 index 0000000000..d3272393dc --- /dev/null +++ b/klibc/klibc/arch/i386/include/sys/vm86.h @@ -0,0 +1,41 @@ +#ident "$Id: vm86.h,v 1.1 2004/01/25 01:34:28 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * sys/vm86.h for i386 + */ + +#ifndef _SYS_VM86_H +#define _SYS_VM86_H 1 + +#include + +/* Actual system call */ +int vm86(struct vm86_struct *); + +#endif diff --git a/klibc/klibc/arch/x86_64/include/sys/io.h b/klibc/klibc/arch/x86_64/include/sys/io.h new file mode 100644 index 0000000000..4a0ae44985 --- /dev/null +++ b/klibc/klibc/arch/x86_64/include/sys/io.h @@ -0,0 +1,126 @@ +#ident "$Id: io.h,v 1.1 2004/01/25 01:34:29 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * sys/io.h for the i386 architecture + * + * Basic I/O macros + */ + +#ifndef _SYS_IO_H +#define _SYS_IO_H 1 + +/* I/O-related system calls */ + +int iopl(int); +int ioperm(unsigned long, unsigned long, int); + +/* Basic I/O macros */ + +static __inline__ void +outb(unsigned char __v, unsigned short __p) +{ + asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outw(unsigned short __v, unsigned short __p) +{ + asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outl(unsigned int __v, unsigned short __p) +{ + asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ unsigned char +inb(unsigned short __p) +{ + unsigned char __v; + asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); + return v; +} + +static __inline__ unsigned short +inw(unsigned short __p) +{ + unsigned short __v; + asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); + return v; +} + +static __inline__ unsigned int +inl(unsigned short __p) +{ + unsigned int __v; + asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); + return v; +} + +/* String I/O macros */ + +static __inline__ void +outsb (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsw (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsl (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + + +static __inline__ void +insb (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insw (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insl (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +#endif /* _SYS_IO_H */ diff --git a/klibc/klibc/fopen.c b/klibc/klibc/fopen.c index 5c84184809..ee62c68bd7 100644 --- a/klibc/klibc/fopen.c +++ b/klibc/klibc/fopen.c @@ -13,10 +13,9 @@ FILE *fopen(const char *file, const char *mode) { int flags = O_RDONLY; int plus = 0; - int fd; while ( *mode ) { - switch ( *mode ) { + switch ( *mode++ ) { case 'r': flags = O_RDONLY; break; @@ -30,17 +29,12 @@ FILE *fopen(const char *file, const char *mode) plus = 1; break; } - mode++; } if ( plus ) { flags = (flags & ~(O_RDONLY|O_WRONLY)) | O_RDWR; } - fd = open(file, flags, 0666); - - if ( fd < 0 ) - return NULL; - else - return fdopen(fd, mode); + /* Note: __create_file(-1) == NULL, so this is safe */ + return __create_file(open(file, flags, 0666)); } diff --git a/klibc/klibc/include/stdio.h b/klibc/klibc/include/stdio.h index f57439f018..31a1fe40af 100644 --- a/klibc/klibc/include/stdio.h +++ b/klibc/klibc/include/stdio.h @@ -31,15 +31,22 @@ typedef struct _IO_file FILE; #define SEEK_CUR 1 #define SEEK_END 2 +/* + * Convert between a FILE * and a file descriptor. We don't actually + * have any in-memory data, so we just abuse the pointer itself to + * hold the data. Note, however, that for file descriptors, -1 is + * error and 0 is a valid value; for FILE *, NULL (0) is error and + * non-NULL are valid. + */ static __inline__ int fileno(FILE *__f) { /* This should really be intptr_t, but size_t should be the same size */ - return (int)(size_t)__f; + return (int)(size_t)__f - 1; } static __inline__ FILE * __create_file(int __fd) { - return (FILE *)(size_t)__fd; + return (FILE *)(size_t)(__fd + 1); } __extern FILE *fopen(const char *, const char *); diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h index 36c486f49d..ad12913834 100644 --- a/klibc/klibc/include/unistd.h +++ b/klibc/klibc/include/unistd.h @@ -54,6 +54,7 @@ __extern int link(const char *, const char *); __extern int unlink(const char *); __extern int chdir(const char *); __extern int chmod(const char *, mode_t); +__extern int fchmod(int, mode_t); __extern int mkdir(const char *, mode_t); __extern int rmdir(const char *); __extern int pipe(int *); diff --git a/klibc/klibc/makeerrlist.pl b/klibc/klibc/makeerrlist.pl index 121ed1f46b..00acb8a3d5 100644 --- a/klibc/klibc/makeerrlist.pl +++ b/klibc/klibc/makeerrlist.pl @@ -10,7 +10,7 @@ use FileHandle; %errors = (); %errmsg = (); $maxerr = -1; -$rootdir = 'linux/include/'; # Must have trailing / +$rootdir = '../linux/include/'; # Must have trailing / sub parse_file($) { my($file) = @_; diff --git a/klibc/klibc/syscommon.h b/klibc/klibc/syscommon.h index 916d4eb0c0..3093920739 100644 --- a/klibc/klibc/syscommon.h +++ b/klibc/klibc/syscommon.h @@ -26,3 +26,7 @@ #include #include #include + +#ifdef __i386__ +#include +#endif diff --git a/klibc/version b/klibc/version index fd6d73e4a0..0f6db3dda2 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.95 +0.98 From 46a7fa4bdbce640c76b0a582e3afadc53b8cffd2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 20:23:55 -0800 Subject: [PATCH 0468/4284] [PATCH] v015 release --- ChangeLog | 38 ++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 534fff49e9..3a4b2c0099 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,41 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 2712f265f5..88b61d6be6 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ROOT = udev DAEMON = udevd SENDER = udevsend HELPER = udevinfo -VERSION = 014_bk +VERSION = 015 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index b622237e67..fba731fc36 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 014_bk +Version: 015 Release: 1 License: GPL Group: Utilities/System From ff2c16f0d1ee459b7bd002f4f9d5e41390c9a21d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 26 Jan 2004 23:54:46 -0800 Subject: [PATCH 0469/4284] [PATCH] allow dbus code to actually build again. --- udev_dbus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_dbus.c b/udev_dbus.c index 947a5c1b5d..da633a31a1 100644 --- a/udev_dbus.c +++ b/udev_dbus.c @@ -12,6 +12,7 @@ #include "udev.h" #include "udev_version.h" #include "udev_dbus.h" +#include "logging.h" /** variable for the connection the to system message bus or #NULL From 8af67a67c2542a9d4eb2371dfba661c65d48d4b6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 27 Jan 2004 00:40:06 -0800 Subject: [PATCH 0470/4284] [PATCH] 015_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 88b61d6be6..d43899b9ed 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ROOT = udev DAEMON = udevd SENDER = udevsend HELPER = udevinfo -VERSION = 015 +VERSION = 015_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index fba731fc36..ccc0ca7f6a 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 015 +Version: 015_bk Release: 1 License: GPL Group: Utilities/System From 2a25816ff0079247d7f868621951739e6d58c885 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 27 Jan 2004 00:40:12 -0800 Subject: [PATCH 0471/4284] [PATCH] udev - trivial style cleanup Trivial style cleanup, to be consistent. And add chdir("/") to the daemon so one can umout its filesystem, while we are running :) --- namedev.c | 24 ++++++++++-------------- udevinfo.c | 2 +- udevsend.c | 1 + 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/namedev.c b/namedev.c index 6b1aa297ea..de7f7c1b88 100644 --- a/namedev.c +++ b/namedev.c @@ -332,12 +332,8 @@ static int execute_program(char *path, char *value, int len) return -1; } pid = fork(); - if (pid == -1) { - dbg("fork failed"); - return -1; - } - - if (pid == 0) { + switch(pid) { + case 0: /* child */ close(STDOUT_FILENO); dup(fds[1]); /* dup write side of pipe to STDOUT */ @@ -353,16 +349,16 @@ static int execute_program(char *path, char *value, int len) dbg("too many args - %d", i); args[i] = NULL; } - retval = execve(args[0], args, main_envp); + retval = execv(args[0], args); } else { - retval = execve(path, main_argv, main_envp); + retval = execv(path, main_argv); } - if (retval != 0) { - dbg("child execve failed"); - exit(1); - } - return -1; /* avoid compiler warning */ - } else { + dbg("child execve failed"); + exit(1); + case -1: + dbg("fork failed"); + return -1; + default: /* parent reads from fds[0] */ close(fds[1]); retval = 0; diff --git a/udevinfo.c b/udevinfo.c index aa9d20a773..4d28755b2f 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -397,7 +397,7 @@ help: " -n NAME node name used for query\n" "\n" " -r print udev root\n" - " -a print all attributes along the chain of the device\n" + " -a print all SYSFS_attributes along the device chain\n" " -d dump whole database\n" " -V print udev version\n" " -h print this help text\n" diff --git a/udevsend.c b/udevsend.c index 3f3bbacbc2..0a305e50c4 100644 --- a/udevsend.c +++ b/udevsend.c @@ -87,6 +87,7 @@ static int start_daemon(void) case 0: /* daemon */ setsid(); + chdir("/"); execl(UDEVD_EXEC, "udevd", NULL); dbg("exec of daemon failed"); exit(1); From 01fc67683a88d4175a9437fb24e3b99e83eeb3ef Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 27 Jan 2004 00:40:14 -0800 Subject: [PATCH 0472/4284] [PATCH] udevinfo - missing options for man page Here are the missing udevinfo options for the new man page. --- udevinfo.8 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/udevinfo.8 b/udevinfo.8 index 852e2ae93f..fdb0e6f62b 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -25,8 +25,10 @@ will be prepended. .TP .BI -q " query_type" Query the database for specified value of a created device node. +.RB Needs " -p " or " -n " specified. +.br Valid types are: -.BR name ", " symlink ", " owner " , " group " or " path. +.BR name ", " symlink ", " mode " ," owner " , " group " or " path. .TP .BI -p " sysfs_path" Specify the sysfs path of the device to query. @@ -34,6 +36,13 @@ Specify the sysfs path of the device to query. .BI -n " name" Specify the name of the node for the device to query. .TP +.B -a +Print all +.BI SYSFS_ filename +attributes along the device chain. Useful for for finding +unique attributes to compose a rule. +.RB Needs " -p " specified. +.TP .B -d Dump the whole database. .TP From 34ee4dd4553160b082b6bc44a6e5be74787cd085 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 27 Jan 2004 18:54:24 -0800 Subject: [PATCH 0473/4284] [PATCH] fix Makefile typo for USE_LSB install. Thanks to Martin Schwenke for pointing this out. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d43899b9ed..c68fd37312 100644 --- a/Makefile +++ b/Makefile @@ -339,7 +339,7 @@ install: install-config install-dbus-policy all $(INSTALL_PROGRAM) -D $(HELPER) $(DESTDIR)$(sbindir)/$(HELPER) @if [ "x$(USE_LSB)" = "xtrue" ]; then \ $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ - ln -s $(DESTDIR)$(initdir)/udev $(sbin_dir)/rcudev; \ + ln -s $(DESTDIR)$(initdir)/udev $(sbindir)/rcudev; \ else \ $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ fi From 35b7d88c0dab4c1104c127ddd644db22307949c9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 27 Jan 2004 18:57:36 -0800 Subject: [PATCH 0474/4284] [PATCH] udevd - next round of fixes Here is the next round. We have three queues now. All incoming messages are queued in msg_list and if nothing is missing we move it to the running_list and exec in the background. If the exec comes back, it removes the message from the running_list and frees the message. Before we exec, we check the running_list if there is a udev running on the same device path. If yes, we move the message to the delay_list. If the former exec comes back, we move the message to the running_list and exec it. The very first event is delayed now to catch possible earlier sequences, every following event is executed without delay if no sequence is missing. The daemon doesn't exit by itself any longer, cause we don't want to delay every first exec. I've put a $(PWD) for now in the Makefile for testing this beast. Only the local binaries are executed, not the /sbin/udev. We can change it if we are ready for real testing. And SIGKILL can't be cought, so I removed it from the handler :) 06:58:36 sig_handler: caught signal 15 06:58:36 main: using ipc queue 0x2d548 06:58:37 message is still in the ipc queue, starting daemon... 06:58:37 work: received sequence 3, expected sequence 0 06:58:37 msg_dump_queue: sequence 3 in queue 06:58:37 set_timeout: set timeout in 1 seconds 06:58:37 main: using ipc queue 0x2d548 06:58:37 main: using ipc queue 0x2d548 06:58:37 work: received sequence 1, expected sequence 1 06:58:37 msg_dump_queue: sequence 1 in queue 06:58:37 msg_dump_queue: sequence 3 in queue 06:58:37 msg_dump: sequence 1, 'add', '/block/sda', 'block' 06:58:37 msg_exec: child [8038] created 06:58:37 running_moveto_queue: move sequence 1 [8038] to running queue '/block/sda' 06:58:37 set_timeout: set timeout in 5 seconds 06:58:37 work: received sequence 2, expected sequence 2 06:58:37 msg_dump_queue: sequence 2 in queue 06:58:37 msg_dump_queue: sequence 3 in queue 06:58:37 msg_dump: sequence 2, 'add', '/block/sdb', 'block' 06:58:37 msg_exec: child [8039] created 06:58:37 running_moveto_queue: move sequence 2 [8039] to running queue '/block/sdb' 06:58:37 msg_dump: sequence 3, 'add', '/block/sdc', 'block' 06:58:37 msg_exec: child [8040] created 06:58:37 running_moveto_queue: move sequence 3 [8040] to running queue '/block/sdc' 06:58:37 main: using ipc queue 0x2d548 06:58:37 main: using ipc queue 0x2d548 06:58:37 work: received sequence 4, expected sequence 4 06:58:37 msg_dump_queue: sequence 4 in queue 06:58:37 msg_dump: sequence 4, 'remove', '/block/sdc', 'block' 06:58:37 msg_exec: delay exec of sequence 4, [8040] already working on '/block/sdc' 06:58:37 delayed_moveto_queue: move event to delayed queue '/block/sdc' 06:58:37 msg_exec: child [8043] created 06:58:37 running_moveto_queue: move sequence 4 [8043] to running queue '/block/sdc' 06:58:37 work: received sequence 5, expected sequence 5 06:58:37 msg_dump_queue: sequence 5 in queue 06:58:37 msg_dump: sequence 5, 'remove', '/block/sdb', 'block' 06:58:37 msg_exec: delay exec of sequence 5, [8039] already working on '/block/sdb' 06:58:37 delayed_moveto_queue: move event to delayed queue '/block/sdb' 06:58:37 msg_exec: child [8044] created 06:58:37 running_moveto_queue: move sequence 5 [8044] to running queue '/block/sdb' 06:58:37 main: using ipc queue 0x2d548 06:58:37 main: using ipc queue 0x2d548 06:58:37 work: received sequence 8, expected sequence 6 06:58:37 msg_dump_queue: sequence 8 in queue 06:58:37 set_timeout: set timeout in 5 seconds 06:58:37 work: received sequence 6, expected sequence 6 06:58:37 msg_dump_queue: sequence 6 in queue 06:58:37 msg_dump_queue: sequence 8 in queue 06:58:37 msg_dump: sequence 6, 'remove', '/block/sda', 'block' 06:58:37 msg_exec: delay exec of sequence 6, [8038] already working on '/block/sda' 06:58:37 delayed_moveto_queue: move event to delayed queue '/block/sda' 06:58:37 msg_exec: child [8047] created 06:58:37 running_moveto_queue: move sequence 6 [8047] to running queue '/block/sda' 06:58:37 set_timeout: set timeout in 5 seconds 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8038 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8039 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8040 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8043 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8044 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:38 sig_handler: caught signal 17 06:58:38 sig_handler: exec finished, pid 8047 06:58:38 set_timeout: set timeout in 4 seconds 06:58:38 msg_dump_queue: sequence 8 in queue 06:58:39 main: using ipc queue 0x2d548 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 9, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 work: received sequence 11, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 10, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 13, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 msg_dump_queue: sequence 13 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 14, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 msg_dump_queue: sequence 13 in queue 06:58:39 msg_dump_queue: sequence 14 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:39 main: using ipc queue 0x2d548 06:58:39 work: received sequence 15, expected sequence 7 06:58:39 msg_dump_queue: sequence 8 in queue 06:58:39 msg_dump_queue: sequence 9 in queue 06:58:39 msg_dump_queue: sequence 10 in queue 06:58:39 msg_dump_queue: sequence 11 in queue 06:58:39 msg_dump_queue: sequence 13 in queue 06:58:39 msg_dump_queue: sequence 14 in queue 06:58:39 msg_dump_queue: sequence 15 in queue 06:58:39 set_timeout: set timeout in 3 seconds 06:58:41 main: using ipc queue 0x2d548 06:58:41 work: received sequence 12, expected sequence 7 06:58:41 msg_dump_queue: sequence 8 in queue 06:58:41 msg_dump_queue: sequence 9 in queue 06:58:41 msg_dump_queue: sequence 10 in queue 06:58:41 msg_dump_queue: sequence 11 in queue 06:58:41 msg_dump_queue: sequence 12 in queue 06:58:41 msg_dump_queue: sequence 13 in queue 06:58:41 msg_dump_queue: sequence 14 in queue 06:58:41 msg_dump_queue: sequence 15 in queue 06:58:41 set_timeout: set timeout in 1 seconds 06:58:42 sig_handler: caught signal 14 06:58:42 sig_handler: event timeout reached 06:58:42 event 8, age 5 seconds, skip event 7-7 06:58:42 msg_dump: sequence 8, 'add', '/block/sdb', 'block' 06:58:42 msg_exec: child [8057] created 06:58:42 running_moveto_queue: move sequence 8 [8057] to running queue '/block/sdb' 06:58:42 msg_dump: sequence 9, 'add', '/block/sdc', 'block' 06:58:42 msg_exec: child [8058] created 06:58:42 running_moveto_queue: move sequence 9 [8058] to running queue '/block/sdc' 06:58:42 msg_dump: sequence 10, 'remove', '/block/sdc', 'block' 06:58:42 msg_exec: delay exec of sequence 10, [8058] already working on '/block/sdc' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdc' 06:58:42 msg_exec: child [8059] created 06:58:42 running_moveto_queue: move sequence 10 [8059] to running queue '/block/sdc' 06:58:42 msg_dump: sequence 11, 'remove', '/block/sdb', 'block' 06:58:42 msg_exec: delay exec of sequence 11, [8057] already working on '/block/sdb' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdb' 06:58:42 msg_exec: child [8060] created 06:58:42 running_moveto_queue: move sequence 11 [8060] to running queue '/block/sdb' 06:58:42 msg_dump: sequence 12, 'remove', '/block/sda', 'block' 06:58:42 msg_exec: child [8061] created 06:58:42 running_moveto_queue: move sequence 12 [8061] to running queue '/block/sda' 06:58:42 msg_dump: sequence 13, 'add', '/block/sda', 'block' 06:58:42 msg_exec: delay exec of sequence 13, [8061] already working on '/block/sda' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sda' 06:58:42 msg_exec: child [8062] created 06:58:42 running_moveto_queue: move sequence 13 [8062] to running queue '/block/sda' 06:58:42 msg_dump: sequence 14, 'add', '/block/sdb', 'block' 06:58:42 msg_exec: delay exec of sequence 14, [8057] already working on '/block/sdb' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdb' 06:58:42 msg_exec: child [8063] created 06:58:42 running_moveto_queue: move sequence 14 [8063] to running queue '/block/sdb' 06:58:42 msg_dump: sequence 15, 'add', '/block/sdc', 'block' 06:58:42 msg_exec: delay exec of sequence 15, [8058] already working on '/block/sdc' 06:58:42 delayed_moveto_queue: move event to delayed queue '/block/sdc' 06:58:42 msg_exec: child [8064] created 06:58:42 running_moveto_queue: move sequence 15 [8064] to running queue '/block/sdc' 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8057 06:58:43 sig_handler: exec finished, pid 8058 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8059 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8060 06:58:43 sig_handler: exec finished, pid 8061 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8062 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8063 06:58:43 sig_handler: caught signal 17 06:58:43 sig_handler: exec finished, pid 8064 --- Makefile | 2 + test/udevd_test.sh | 57 +++++++++++--- udev.c | 2 - udevd.c | 190 ++++++++++++++++++++++++++++++--------------- udevd.h | 10 +-- udevsend.c | 10 ++- 6 files changed, 187 insertions(+), 84 deletions(-) diff --git a/Makefile b/Makefile index c68fd37312..8af6ecf638 100644 --- a/Makefile +++ b/Makefile @@ -232,6 +232,8 @@ udev_version.h: @echo \#define UDEV_CONFIG_FILE \"$(configdir)\udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ + @echo \#define UDEV_BIN \"$(PWD)/udev\" >> $@ + @echo \#define UDEVD_BIN \"$(PWD)/udevd\" >> $@ # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf diff --git a/test/udevd_test.sh b/test/udevd_test.sh index 0c7bd431be..94698085ca 100644 --- a/test/udevd_test.sh +++ b/test/udevd_test.sh @@ -3,7 +3,12 @@ # kill daemon, first event will start it again killall udevd -# connect(123) - disconnect(456) - connect(789) sequence of sda/sdb/sdc +# 3 x connect/disconnect sequence of sda/sdb/sdc + +export SEQNUM=3 +export ACTION=add +export DEVPATH=/block/sdc +./udevsend block export SEQNUM=1 export ACTION=add @@ -17,16 +22,6 @@ export DEVPATH=/block/sdb export SEQNUM=4 export ACTION=remove -export DEVPATH=/block/sda -./udevsend block - -export SEQNUM=3 -export ACTION=add -export DEVPATH=/block/sdc -./udevsend block - -export SEQNUM=6 -export ACTION=remove export DEVPATH=/block/sdc ./udevsend block @@ -35,18 +30,56 @@ export ACTION=remove export DEVPATH=/block/sdb ./udevsend block +export SEQNUM=8 +export ACTION=add +export DEVPATH=/block/sdb +./udevsend block + +export SEQNUM=6 +export ACTION=remove +export DEVPATH=/block/sda +./udevsend block + export SEQNUM=7 export ACTION=add export DEVPATH=/block/sda #./udevsend block +sleep 2 + export SEQNUM=9 export ACTION=add export DEVPATH=/block/sdc ./udevsend block -export SEQNUM=8 +export SEQNUM=11 +export ACTION=remove +export DEVPATH=/block/sdb +./udevsend block + +export SEQNUM=10 +export ACTION=remove +export DEVPATH=/block/sdc +./udevsend block + +export SEQNUM=13 +export ACTION=add +export DEVPATH=/block/sda +./udevsend block + +export SEQNUM=14 export ACTION=add export DEVPATH=/block/sdb ./udevsend block +export SEQNUM=15 +export ACTION=add +export DEVPATH=/block/sdc +./udevsend block + +sleep 2 + +export SEQNUM=12 +export ACTION=remove +export DEVPATH=/block/sda +./udevsend block diff --git a/udev.c b/udev.c index 4c67477c20..38b26916c9 100644 --- a/udev.c +++ b/udev.c @@ -45,7 +45,6 @@ static void sig_handler(int signum) switch (signum) { case SIGINT: case SIGTERM: - case SIGKILL: sysbus_disconnect(); udevdb_exit(); exit(20 + signum); @@ -143,7 +142,6 @@ static int udev_hotplug(int argc, char **argv) /* set up a default signal handler for now */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - signal(SIGKILL, sig_handler); /* initialize the naming deamon */ namedev_init(); diff --git a/udevd.c b/udevd.c index 26e6b23486..a80da5b0d4 100644 --- a/udevd.c +++ b/udevd.c @@ -38,27 +38,42 @@ #include "list.h" #include "udev.h" +#include "udev_version.h" #include "udevd.h" #include "logging.h" + #define BUFFER_SIZE 1024 +static int running_remove_queue(pid_t pid); +static int msg_exec(struct hotplug_msg *msg); + static int expect_seqnum = 0; static int lock_file = -1; static char *lock_filename = ".udevd_lock"; LIST_HEAD(msg_list); +LIST_HEAD(running_list); +LIST_HEAD(delayed_list); static void sig_handler(int signum) { + pid_t pid; + dbg("caught signal %d", signum); switch (signum) { case SIGALRM: dbg("event timeout reached"); break; + case SIGCHLD: + /* catch signals from exiting childs */ + while ( (pid = waitpid(-1, NULL, WNOHANG)) > 0) { + dbg("exec finished, pid %d", pid); + running_remove_queue(pid); + } + break; case SIGINT: case SIGTERM: - case SIGKILL: if (lock_file >= 0) { close(lock_file); unlink(lock_filename); @@ -70,34 +85,104 @@ static void sig_handler(int signum) } } -static void dump_queue(void) +static void set_timeout(int seconds) { - struct hotplug_msg *msg; - - list_for_each_entry(msg, &msg_list, list) - dbg("sequence %d in queue", msg->seqnum); + alarm(seconds); + dbg("set timeout in %d seconds", seconds); } -static void dump_msg(struct hotplug_msg *msg) +static int running_moveto_queue(struct hotplug_msg *msg) +{ + dbg("move sequence %d [%d] to running queue '%s'", + msg->seqnum, msg->pid, msg->devpath); + list_move_tail(&msg->list, &running_list); + return 0; +} + +static int running_remove_queue(pid_t pid) +{ + struct hotplug_msg *child; + struct hotplug_msg *tmp_child; + + list_for_each_entry_safe(child, tmp_child, &running_list, list) + if (child->pid == pid) { + list_del_init(&child->list); + free(child); + return 0; + } + return -EINVAL; +} + +static pid_t running_getpid_by_devpath(struct hotplug_msg *msg) +{ + struct hotplug_msg *child; + struct hotplug_msg *tmp_child; + + list_for_each_entry_safe(child, tmp_child, &running_list, list) + if (strncmp(child->devpath, msg->devpath, sizeof(child->devpath)) == 0) + return child->pid; + return 0; +} + +static void delayed_dump_queue(void) +{ + struct hotplug_msg *child; + + list_for_each_entry(child, &delayed_list, list) + dbg("event for '%s' in queue", child->devpath); +} + +static int delayed_moveto_queue(struct hotplug_msg *msg) +{ + dbg("move event to delayed queue '%s'", msg->devpath); + list_move_tail(&msg->list, &delayed_list); + return 0; +} + +static void delayed_check_queue(void) +{ + struct hotplug_msg *delayed_child; + struct hotplug_msg *running_child; + struct hotplug_msg *tmp_child; + + /* see if we have delayed exec's that can run now */ + list_for_each_entry_safe(delayed_child, tmp_child, &delayed_list, list) + list_for_each_entry_safe(running_child, tmp_child, &running_list, list) + if (strncmp(delayed_child->devpath, running_child->devpath, + sizeof(running_child->devpath)) == 0) { + dbg("delayed exec for '%s' can run now", delayed_child->devpath); + msg_exec(delayed_child); + } +} + +static void msg_dump(struct hotplug_msg *msg) { dbg("sequence %d, '%s', '%s', '%s'", msg->seqnum, msg->action, msg->devpath, msg->subsystem); } -static int dispatch_msg(struct hotplug_msg *msg) +static int msg_exec(struct hotplug_msg *msg) { pid_t pid; - dump_msg(msg); + msg_dump(msg); setenv("ACTION", msg->action, 1); setenv("DEVPATH", msg->devpath, 1); + /* delay exec, if we already have a udev working on the same devpath */ + pid = running_getpid_by_devpath(msg); + if (pid != 0) { + dbg("delay exec of sequence %d, [%d] already working on '%s'", + msg->seqnum, pid, msg->devpath); + delayed_moveto_queue(msg); + } + pid = fork(); switch (pid) { case 0: /* child */ - execl(UDEV_EXEC, "udev", msg->subsystem, NULL); + execl(UDEV_BIN, "udev", msg->subsystem, NULL); dbg("exec of child failed"); exit(1); break; @@ -105,18 +190,23 @@ static int dispatch_msg(struct hotplug_msg *msg) dbg("fork of child failed"); return -1; default: - wait(NULL); + /* exec in background, get the SIGCHLD with the sig handler */ + msg->pid = pid; + running_moveto_queue(msg); + break; } return 0; } -static void set_timeout(int seconds) +static void msg_dump_queue(void) { - alarm(seconds); - dbg("set timeout in %d seconds", seconds); + struct hotplug_msg *msg; + + list_for_each_entry(msg, &msg_list, list) + dbg("sequence %d in queue", msg->seqnum); } -static void check_queue(void) +static void msg_check_queue(void) { struct hotplug_msg *msg; struct hotplug_msg *tmp_msg; @@ -127,30 +217,32 @@ recheck: list_for_each_entry_safe(msg, tmp_msg, &msg_list, list) { if (msg->seqnum != expect_seqnum) break; - dispatch_msg(msg); + msg_exec(msg); expect_seqnum++; - list_del_init(&msg->list); - free(msg); } - /* recalculate timeout */ + /* recalculate next timeout */ if (list_empty(&msg_list) == 0) { msg_age = time(NULL) - msg->queue_time; - if (msg_age > EVENT_TIMEOUT_SECONDS-1) { + if (msg_age > EVENT_TIMEOUT_SEC-1) { info("event %d, age %li seconds, skip event %d-%d", msg->seqnum, msg_age, expect_seqnum, msg->seqnum-1); expect_seqnum = msg->seqnum; goto recheck; } - set_timeout(EVENT_TIMEOUT_SECONDS - msg_age); + + /* the first sequence gets its own timeout */ + if (expect_seqnum == 0) { + msg_age = EVENT_TIMEOUT_SEC - FIRST_EVENT_TIMEOUT_SEC; + expect_seqnum = 1; + } + + set_timeout(EVENT_TIMEOUT_SEC - msg_age); return; } - - /* queue is empty */ - set_timeout(UDEVD_TIMEOUT_SECONDS); } -static int queue_msg(struct hotplug_msg *msg) +static int msg_add_queue(struct hotplug_msg *msg) { struct hotplug_msg *new_msg; struct hotplug_msg *tmp_msg; @@ -182,7 +274,7 @@ static void work(void) char buf[BUFFER_SIZE]; int ret; - key = ftok(UDEVD_EXEC, IPC_KEY_ID); + key = ftok(UDEVD_BIN, IPC_KEY_ID); msg = (struct hotplug_msg *) buf; msgid = msgget(key, IPC_CREAT); if (msgid == -1) { @@ -192,41 +284,20 @@ static void work(void) while (1) { ret = msgrcv(msgid, (struct msgbuf *) buf, BUFFER_SIZE-4, HOTPLUGMSGTYPE, 0); if (ret != -1) { - /* init the expected sequence with value from first call */ - if (expect_seqnum == 0) { - expect_seqnum = msg->seqnum; - dbg("init next expected sequence number to %d", expect_seqnum); - } - dbg("current sequence %d, expected sequence %d", msg->seqnum, expect_seqnum); - if (msg->seqnum == expect_seqnum) { - /* execute expected event */ - dispatch_msg(msg); - expect_seqnum++; - check_queue(); - dump_queue(); + dbg("received sequence %d, expected sequence %d", msg->seqnum, expect_seqnum); + if (msg->seqnum >= expect_seqnum) { + msg_add_queue(msg); + msg_dump_queue(); + msg_check_queue(); continue; } - if (msg->seqnum > expect_seqnum) { - /* something missing, queue event*/ - queue_msg(msg); - check_queue(); - dump_queue(); - continue; - } - dbg("too late for event with sequence %d, even skipped ", msg->seqnum); + dbg("too late for event with sequence %d, event skipped ", msg->seqnum); } else { if (errno == EINTR) { - /* timeout */ - if (list_empty(&msg_list)) { - info("we have nothing to do, so daemon exits..."); - if (lock_file >= 0) { - close(lock_file); - unlink(lock_filename); - } - exit(0); - } - check_queue(); - dump_queue(); + msg_check_queue(); + msg_dump_queue(); + delayed_check_queue(); + delayed_dump_queue(); continue; } dbg("ipc message receive error '%s'", strerror(errno)); @@ -266,11 +337,8 @@ int main(int argc, char *argv[]) /* set up signal handler */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - signal(SIGKILL, sig_handler); signal(SIGALRM, sig_handler); - - /* we exit if we have nothing to do, next event will start us again */ - set_timeout(UDEVD_TIMEOUT_SECONDS); + signal(SIGCHLD, sig_handler); work(); exit(0); diff --git a/udevd.h b/udevd.h index c9b69bbc3c..4bccd4b81a 100644 --- a/udevd.h +++ b/udevd.h @@ -23,18 +23,18 @@ #include "list.h" -#define UDEV_EXEC "./udev" -#define UDEVD_EXEC "./udevd" -#define UDEVD_TIMEOUT_SECONDS 60 -#define EVENT_TIMEOUT_SECONDS 5 +#define FIRST_EVENT_TIMEOUT_SEC 1 +#define EVENT_TIMEOUT_SEC 5 +#define UDEVSEND_RETRY_COUNT 50 /* x 10 millisec */ -#define IPC_KEY_ID 0 +#define IPC_KEY_ID 1 #define HOTPLUGMSGTYPE 44 struct hotplug_msg { long mtype; struct list_head list; + pid_t pid; int seqnum; time_t queue_time; char action[8]; diff --git a/udevsend.c b/udevsend.c index 0a305e50c4..f92ee2b5d8 100644 --- a/udevsend.c +++ b/udevsend.c @@ -34,6 +34,7 @@ #include #include "udev.h" +#include "udev_version.h" #include "udevd.h" #include "logging.h" @@ -64,7 +65,7 @@ static inline char *get_seqnum(void) static int build_hotplugmsg(struct hotplug_msg *msg, char *action, char *devpath, char *subsystem, int seqnum) { - memset(msg, 0x00, sizeof(msg)); + memset(msg, 0x00, sizeof(*msg)); msg->mtype = HOTPLUGMSGTYPE; msg->seqnum = seqnum; strncpy(msg->action, action, 8); @@ -88,7 +89,7 @@ static int start_daemon(void) /* daemon */ setsid(); chdir("/"); - execl(UDEVD_EXEC, "udevd", NULL); + execl(UDEVD_BIN, "udevd", NULL); dbg("exec of daemon failed"); exit(1); case -1: @@ -150,7 +151,8 @@ int main(int argc, char* argv[]) seq = atoi(seqnum); /* create ipc message queue or get id of our existing one */ - key = ftok(UDEVD_EXEC, IPC_KEY_ID); + key = ftok(UDEVD_BIN, IPC_KEY_ID); + dbg("using ipc queue 0x%0x", key); size = build_hotplugmsg(&message, action, devpath, subsystem, seq); msgid = msgget(key, IPC_CREAT); if (msgid == -1) { @@ -168,7 +170,7 @@ int main(int argc, char* argv[]) /* get state of ipc queue */ tspec.tv_sec = 0; tspec.tv_nsec = 10000000; /* 10 millisec */ - loop = 30; + loop = UDEVSEND_RETRY_COUNT; while (loop--) { retval = msgctl(msgid, IPC_STAT, &msg_queue); if (retval == -1) { From 273636ca8b745ec62d432a4cbf30269f52aedaf4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 28 Jan 2004 18:35:47 -0800 Subject: [PATCH 0475/4284] [PATCH] update to klibc version 0.101, fixing the stdin bug. --- klibc/klibc/Makefile | 12 ++++----- klibc/klibc/arch/ppc/include/klibc/archsys.h | 24 +++++++++++------- klibc/klibc/getpagesize.c | 26 ++++++++++++++++++++ klibc/klibc/include/stdio.h | 14 +++++------ klibc/klibc/include/unistd.h | 2 ++ klibc/klibc/mmap.c | 2 +- klibc/klibc/syscommon.h | 2 +- klibc/version | 2 +- 8 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 klibc/klibc/getpagesize.c diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 5fc481aa8a..def201524a 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -24,7 +24,7 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ sleep.o usleep.o raise.o abort.o assert.o alarm.o pause.o \ __signal.o signal.o bsd_signal.o siglist.o siglongjmp.o \ sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ - brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ + brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o getpagesize.o \ memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ memmove.o \ strcasecmp.o strncasecmp.o strndup.o strerror.o \ @@ -118,12 +118,12 @@ socketcalls.dir: SOCKETCALLS socketcalls.pl socketcommon.h touch $@ %/static.obj: %.dir - $(MAKE) objects-$(basename $(notdir $@)) DIR=$* + $(MAKE) objects-$(basename $(notdir $@)) DIR=$*/ -STATIC = $(addsuffix .o,$(basename $(wildcard $(DIR)/*.[cS]))) +STATIC = $(addsuffix .o,$(basename $(wildcard $(DIR)*.[cS]))) objects-static: $(STATIC) - touch $(DIR)/static.obj + touch $(DIR)static.obj clean: archclean find . -type f -a \( -name \*.[isoa] -o -name \*.l[iso] \) -print0 | xargs -0rt rm -f @@ -140,6 +140,6 @@ spotless: clean bitsize: @echo $(BITSIZE) -ifneq ($(wildcard $(DIR)/.*.d),) -include $(wildcard $(DIR)/.*.d) +ifneq ($(wildcard $(DIR).*.d),) +include $(wildcard $(DIR).*.d) endif diff --git a/klibc/klibc/arch/ppc/include/klibc/archsys.h b/klibc/klibc/arch/ppc/include/klibc/archsys.h index 33a5ff3236..17a28859e5 100644 --- a/klibc/klibc/arch/ppc/include/klibc/archsys.h +++ b/klibc/klibc/arch/ppc/include/klibc/archsys.h @@ -36,18 +36,24 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ __asm__ __volatile__ \ ("sc \n\t" \ "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6), \ - "r" (__sc_7), \ - "r" (__sc_8) \ - : __syscall_clobbers); \ + : "+r" (__sc_3), \ + "+r" (__sc_0), \ + "+r" (__sc_4), \ + "+r" (__sc_5), \ + "+r" (__sc_6), \ + "+r" (__sc_7), \ + "+r" (__sc_8) \ + : : "cr0", "ctr", "memory", \ + "r9", "r10", "r11", "r12"); \ __sc_ret = __sc_3; \ __sc_err = __sc_0; \ } \ - __syscall_return (type); \ + if (__sc_err & 0x10000000) \ + { \ + errno = (int)__sc_ret; \ + __sc_ret = -1; \ + } \ + return (type)__sc_ret; \ } #endif /* _syscall6() missing */ diff --git a/klibc/klibc/getpagesize.c b/klibc/klibc/getpagesize.c new file mode 100644 index 0000000000..2d975b1586 --- /dev/null +++ b/klibc/klibc/getpagesize.c @@ -0,0 +1,26 @@ +/* + * getpagesize.c + */ + +#include +#include + +/* Presumably there is a better way to do this... */ +#ifdef __ia64__ +# define __NR_getpagesize 1171 +#endif + +#ifdef __NR_getpagesize + +_syscall0(int,getpagesize); + +#else + +int getpagesize(void) +{ + return PAGE_SIZE; +} + +#endif + + diff --git a/klibc/klibc/include/stdio.h b/klibc/klibc/include/stdio.h index 31a1fe40af..fba1e30746 100644 --- a/klibc/klibc/include/stdio.h +++ b/klibc/klibc/include/stdio.h @@ -15,10 +15,6 @@ struct _IO_file; typedef struct _IO_file FILE; -#define stdin ((FILE *)0) -#define stdout ((FILE *)1) -#define stderr ((FILE *)2) - #ifndef EOF # define EOF (-1) #endif @@ -44,10 +40,12 @@ static __inline__ int fileno(FILE *__f) return (int)(size_t)__f - 1; } -static __inline__ FILE * __create_file(int __fd) -{ - return (FILE *)(size_t)(__fd + 1); -} +/* This is a macro so it can be used as initializer */ +#define __create_file(__fd) ((FILE *)(size_t)((__fd) + 1)) + +#define stdin __create_file(0) +#define stdout __create_file(1) +#define stderr __create_file(2) __extern FILE *fopen(const char *, const char *); diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h index ad12913834..3d5c6881d3 100644 --- a/klibc/klibc/include/unistd.h +++ b/klibc/klibc/include/unistd.h @@ -105,6 +105,8 @@ __extern int optind, opterr, optopt; __extern int isatty(int); +__extern int getpagesize(void); + /* Standard file descriptor numbers. */ #define STDIN_FILENO 0 #define STDOUT_FILENO 1 diff --git a/klibc/klibc/mmap.c b/klibc/klibc/mmap.c index aedf4dceb5..89cf3a6a8f 100644 --- a/klibc/klibc/mmap.c +++ b/klibc/klibc/mmap.c @@ -19,7 +19,7 @@ * Prefer mmap2() over mmap(), except on the architectures listed */ -#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__) && !defined(__powerpc64__) +#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__) && !defined(__powerpc__) && !defined(__powerpc64__) /* This architecture uses mmap2() */ diff --git a/klibc/klibc/syscommon.h b/klibc/klibc/syscommon.h index 3093920739..429025279e 100644 --- a/klibc/klibc/syscommon.h +++ b/klibc/klibc/syscommon.h @@ -28,5 +28,5 @@ #include #ifdef __i386__ -#include +# include #endif diff --git a/klibc/version b/klibc/version index 0f6db3dda2..2f3d7fa995 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.98 +0.101 From 0115874355e618a4b7684be814610d3612283c6a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 28 Jan 2004 18:52:45 -0800 Subject: [PATCH 0476/4284] [PATCH] udevd - remove stupid locking error I wrote. --- udevd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/udevd.c b/udevd.c index a80da5b0d4..22c38653e7 100644 --- a/udevd.c +++ b/udevd.c @@ -318,7 +318,6 @@ static int one_and_only(void) /* see if we can lock */ if (lockf(lock_file, F_TLOCK, 0) < 0) { close(lock_file); - unlink(lock_filename); return -1; } From bc59f0167a03be2d2e4cf8a680dda8444243c64f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 28 Jan 2004 18:53:12 -0800 Subject: [PATCH 0477/4284] [PATCH] remove a __KLIBC__ tests in libsysfs, as klibc now supports getpagesize() --- libsysfs/sysfs_dir.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index a60410ed28..ce01669754 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -273,11 +273,8 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) sysattr->path); return -1; } -#ifdef __KLIBC__ - pgsize = 0x1000; -#else - pgsize = sysconf(_SC_PAGESIZE); -#endif + + pgsize = getpagesize(); fbuf = (unsigned char *)calloc(1, pgsize+1); if (fbuf == NULL) { dprintf("calloc failed\n"); From 8a08e4b1906eef5d5cb585b125612cce8d565e5c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 28 Jan 2004 19:00:51 -0800 Subject: [PATCH 0478/4284] [PATCH] fix possible buffer overflow On Tue, Jan 27, 2004 at 11:02:25AM -0800, Greg KH wrote: > On Mon, Jan 26, 2004 at 07:28:03PM -0500, Adrian Drzewiecki wrote: > > Looking over the code, I noticed something odd in > > namedev.c:strcmp_pattern() -- > > > > while (*p && (*p != ']')) > > p ++; > > return strcmp_pattern(p+1, s+1); > > > > If the pattern string is invalid, and is not terminated by a ']', then 'p' > > will point at \0 and p+1 will be beyond the string. > > Yes, I think you are correct. > > Hm, Kay, any idea of the proper way to fix this? I've attached a patch > below, but I don't think it is correct. > > while (*p && (*p != ']')) > p++; > - return strcmp_pattern(p+1, s+1); > + if (*p) > + return strcmp_pattern(p+1, s+1); > + else > + return 1; > } > } Sure, it's perfectly correct. I'm wondering how Adrian found this. We can use the return 1 at the end of the whole function, and asking for the closing ']' is more descriptive, but it does the same. - return strcmp_pattern(p+1, s+1); + if (*p == ']') + return strcmp_pattern(p+1, s+1); Patch is attached, that also replaces all the *s with s[0]. --- namedev.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/namedev.c b/namedev.c index de7f7c1b88..6685596479 100644 --- a/namedev.c +++ b/namedev.c @@ -47,34 +47,35 @@ LIST_HEAD(perm_device_list); /* compare string with pattern (supports * ? [0-9] [!A-Z]) */ static int strcmp_pattern(const char *p, const char *s) { - if (*s == '\0') { - while (*p == '*') + if (s[0] == '\0') { + while (p[0] == '*') p++; - return (*p != '\0'); + return (p[0] != '\0'); } - switch (*p) { + switch (p[0]) { case '[': { int not = 0; p++; - if (*p == '!') { + if (p[0] == '!') { not = 1; p++; } - while (*p && (*p != ']')) { + while ((p[0] != '\0') && (p[0] != ']')) { int match = 0; if (p[1] == '-') { - if ((*s >= *p) && (*s <= p[2])) + if ((s[0] >= p[0]) && (s[0] <= p[2])) match = 1; p += 3; } else { - match = (*p == *s); + match = (p[0] == s[0]); p++; } if (match ^ not) { - while (*p && (*p != ']')) + while ((p[0] != '\0') && (p[0] != ']')) p++; - return strcmp_pattern(p+1, s+1); + if (p[0] == ']') + return strcmp_pattern(p+1, s+1); } } } @@ -84,12 +85,12 @@ static int strcmp_pattern(const char *p, const char *s) return strcmp_pattern(p+1, s); return 0; case '\0': - if (*s == '\0') { + if (s[0] == '\0') { return 0; } break; default: - if ((*p == *s) || (*p == '?')) + if ((p[0] == s[0]) || (p[0] == '?')) return strcmp_pattern(p+1, s+1); break; } From 79080c2664117e745eee3fcb812ec17208263672 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 29 Jan 2004 21:54:38 -0800 Subject: [PATCH 0479/4284] [PATCH] kill the last examples that contained the %D option. --- etc/udev/udev.rules.devfs | 5 +---- etc/udev/udev.rules.gentoo | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 1a52425633..f9333e91c4 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -2,10 +2,7 @@ # fields. See the udev man page for a full description of them. # ide block devices -BUS="ide", id="0.0", NAME="ide/host0/bus0/target0/lun0/%D" -BUS="ide", id="0.1", NAME="ide/host0/bus0/target1/lun0/%D" -BUS="ide", id="1.0", NAME="ide/host0/bus1/target0/lun0/%D" -BUS="ide", id="1.1", NAME="ide/host0/bus1/target1/lun0/%D" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%1c %2c" # md block devices KERNEL="md[0-9]*", NAME="md/%n" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index a449a4dac9..0c53df535c 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -11,9 +11,6 @@ # %b - the bus id for the device # %c - the return value of the external PROGRAM (note, this doesn't work within # the PROGRAM field for the obvious reason.) -# %D - use the devfs style disk name for this device. -# For partitions, this will result in 'part%n' -# If this is not a partition, it will result in 'disc' # ########################################################### From 53921bfa44129a19661a4aaa4c1647282921fc18 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 1 Feb 2004 09:12:36 -0800 Subject: [PATCH 0480/4284] [PATCH] udevd - cleanup and better timeout handling On Thu, Jan 29, 2004 at 04:55:11PM +0100, Kay Sievers wrote: > On Thu, Jan 29, 2004 at 02:56:25AM +0100, Kay Sievers wrote: > > On Wed, Jan 28, 2004 at 10:47:36PM +0100, Kay Sievers wrote: > > > Oh, couldn't resist to try threads. > > > It's a multithreaded udevd that communicates through a localhost socket. > > > The message includes a magic with the udev version, so we don't accept > > > older udevsend's. > > > > > > No need for locking, cause we can't bind two sockets on the same address. > > > The daemon tries to connect and if it fails it starts the daemon. > > > > > > We create a thread for every incoming connection, handle over the socket, > > > sort the messages in the global message queue and exit the thread. > > > Huh, that was easy with threads :) > > > > > > With the addition of a message we wakeup the queue manager thread and > > > handle timeouts or move the message to the global exec list. This wakes > > > up the exec list manager who looks if a process is already running for this > > > device path. > > > If yes, the exec is delayed otherwise we create a thread that execs udev. > > > n the background. With the return of udev we free the message and wakeup > > > the exec list manager to look if something is pending. > > > > > > It is just a quick shot, cause I couldn't solve the problems with fork an > > > scheduling and I wanted to see if I'm to stupid :) > > > But if anybody with a better idea or more experience with I/O scheduling > > > we may go another way. The remaining problem is that klibc doesn't support > > > threads. > > > > > > By now, we don't exec anything, it's just a sleep 3 for every exec, > > > but you can see the queue management by watching syslog and do: > > > > > > DEVPATH=/abc ACTION=add SEQNUM=0 ./udevsend /abc > > Next version, switched to unix domain sockets. Next cleaned up version. Hey, nobody wants to try it :) Works for me, It's funny if I connect/disconnect my 4in1-usb-flash-reader every two seconds. The 2.6 usb rocks! I can connect/diconnect a hub with 3 devices plugged in every second and don't run into any problem but a _very_ big udevd queue. --- Makefile | 2 +- test/udevd_test.sh | 8 +- udevd.c | 520 +++++++++++++++++++++++++-------------------- udevd.h | 20 +- udevsend.c | 82 ++++--- 5 files changed, 361 insertions(+), 271 deletions(-) diff --git a/Makefile b/Makefile index 8af6ecf638..d953218f7b 100644 --- a/Makefile +++ b/Makefile @@ -255,7 +255,7 @@ $(HELPER): udevinfo.o $(OBJS) $(HEADERS) $(STRIPCMD) $@ $(DAEMON): udevd.h udevd.o udevd.o logging.o - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -lpthread -o $@ $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(SENDER): udevd.h udevsend.o udevd.o logging.o diff --git a/test/udevd_test.sh b/test/udevd_test.sh index 94698085ca..506e886948 100644 --- a/test/udevd_test.sh +++ b/test/udevd_test.sh @@ -1,9 +1,7 @@ -#!/bin/bash +#!/bin/sh -# kill daemon, first event will start it again -killall udevd - -# 3 x connect/disconnect sequence of sda/sdb/sdc +# add/rem/add/rem/add sequence of sda/sdb/sdc +# a few days longer and the socket of my usb-flash-reader is gone :) export SEQNUM=3 export ACTION=add diff --git a/udevd.c b/udevd.c index 22c38653e7..22fb4d33db 100644 --- a/udevd.c +++ b/udevd.c @@ -1,9 +1,6 @@ /* - * udevd.c + * udevd.c - hotplug event serializer * - * Userspace devfs - * - * Copyright (C) 2004 Ling, Xiaofeng * Copyright (C) 2004 Kay Sievers * * @@ -24,9 +21,7 @@ #include #include -#include #include -#include #include #include #include @@ -35,6 +30,10 @@ #include #include #include +#include +#include +#include +#include #include "list.h" #include "udev.h" @@ -43,116 +42,27 @@ #include "logging.h" -#define BUFFER_SIZE 1024 - -static int running_remove_queue(pid_t pid); -static int msg_exec(struct hotplug_msg *msg); - -static int expect_seqnum = 0; -static int lock_file = -1; -static char *lock_filename = ".udevd_lock"; +static pthread_mutex_t msg_lock; +static pthread_mutex_t msg_active_lock; +static pthread_cond_t msg_active; +static pthread_mutex_t exec_lock; +static pthread_mutex_t exec_active_lock; +static pthread_cond_t exec_active; +static pthread_mutex_t running_lock; +static pthread_attr_t thr_attr; +static int expected_seqnum = 0; LIST_HEAD(msg_list); +LIST_HEAD(exec_list); LIST_HEAD(running_list); -LIST_HEAD(delayed_list); -static void sig_handler(int signum) + +static void msg_dump_queue(void) { - pid_t pid; + struct hotplug_msg *msg; - dbg("caught signal %d", signum); - switch (signum) { - case SIGALRM: - dbg("event timeout reached"); - break; - case SIGCHLD: - /* catch signals from exiting childs */ - while ( (pid = waitpid(-1, NULL, WNOHANG)) > 0) { - dbg("exec finished, pid %d", pid); - running_remove_queue(pid); - } - break; - case SIGINT: - case SIGTERM: - if (lock_file >= 0) { - close(lock_file); - unlink(lock_filename); - } - exit(20 + signum); - break; - default: - dbg("unhandled signal"); - } -} - -static void set_timeout(int seconds) -{ - alarm(seconds); - dbg("set timeout in %d seconds", seconds); -} - -static int running_moveto_queue(struct hotplug_msg *msg) -{ - dbg("move sequence %d [%d] to running queue '%s'", - msg->seqnum, msg->pid, msg->devpath); - list_move_tail(&msg->list, &running_list); - return 0; -} - -static int running_remove_queue(pid_t pid) -{ - struct hotplug_msg *child; - struct hotplug_msg *tmp_child; - - list_for_each_entry_safe(child, tmp_child, &running_list, list) - if (child->pid == pid) { - list_del_init(&child->list); - free(child); - return 0; - } - return -EINVAL; -} - -static pid_t running_getpid_by_devpath(struct hotplug_msg *msg) -{ - struct hotplug_msg *child; - struct hotplug_msg *tmp_child; - - list_for_each_entry_safe(child, tmp_child, &running_list, list) - if (strncmp(child->devpath, msg->devpath, sizeof(child->devpath)) == 0) - return child->pid; - return 0; -} - -static void delayed_dump_queue(void) -{ - struct hotplug_msg *child; - - list_for_each_entry(child, &delayed_list, list) - dbg("event for '%s' in queue", child->devpath); -} - -static int delayed_moveto_queue(struct hotplug_msg *msg) -{ - dbg("move event to delayed queue '%s'", msg->devpath); - list_move_tail(&msg->list, &delayed_list); - return 0; -} - -static void delayed_check_queue(void) -{ - struct hotplug_msg *delayed_child; - struct hotplug_msg *running_child; - struct hotplug_msg *tmp_child; - - /* see if we have delayed exec's that can run now */ - list_for_each_entry_safe(delayed_child, tmp_child, &delayed_list, list) - list_for_each_entry_safe(running_child, tmp_child, &running_list, list) - if (strncmp(delayed_child->devpath, running_child->devpath, - sizeof(running_child->devpath)) == 0) { - dbg("delayed exec for '%s' can run now", delayed_child->devpath); - msg_exec(delayed_child); - } + list_for_each_entry(msg, &msg_list, list) + dbg("sequence %d in queue", msg->seqnum); } static void msg_dump(struct hotplug_msg *msg) @@ -161,23 +71,53 @@ static void msg_dump(struct hotplug_msg *msg) msg->seqnum, msg->action, msg->devpath, msg->subsystem); } -static int msg_exec(struct hotplug_msg *msg) +/* allocates a new message */ +static struct hotplug_msg *msg_create(void) +{ + struct hotplug_msg *new_msg; + + new_msg = malloc(sizeof(struct hotplug_msg)); + if (new_msg == NULL) { + dbg("error malloc"); + return NULL; + } + memset(new_msg, 0x00, sizeof(struct hotplug_msg)); + return new_msg; +} + +/* orders the message in the queue by sequence number */ +static void msg_queue_insert(struct hotplug_msg *msg) +{ + struct hotplug_msg *loop_msg; + + /* sort message by sequence number into list*/ + list_for_each_entry(loop_msg, &msg_list, list) + if (loop_msg->seqnum > msg->seqnum) + break; + list_add_tail(&msg->list, &loop_msg->list); + dbg("queued message seq %d", msg->seqnum); + + /* store timestamp of queuing */ + msg->queue_time = time(NULL); + + /* signal queue activity to manager */ + pthread_mutex_lock(&msg_active_lock); + pthread_cond_signal(&msg_active); + pthread_mutex_unlock(&msg_active_lock); + + return ; +} + +/* forks event and removes event from run queue when finished */ +static void *run_threads(void * parm) { pid_t pid; + struct hotplug_msg *msg; - msg_dump(msg); - + msg = parm; setenv("ACTION", msg->action, 1); setenv("DEVPATH", msg->devpath, 1); - /* delay exec, if we already have a udev working on the same devpath */ - pid = running_getpid_by_devpath(msg); - if (pid != 0) { - dbg("delay exec of sequence %d, [%d] already working on '%s'", - msg->seqnum, pid, msg->devpath); - delayed_moveto_queue(msg); - } - pid = fork(); switch (pid) { case 0: @@ -188,135 +128,206 @@ static int msg_exec(struct hotplug_msg *msg) break; case -1: dbg("fork of child failed"); - return -1; + goto exit; default: - /* exec in background, get the SIGCHLD with the sig handler */ - msg->pid = pid; - running_moveto_queue(msg); - break; - } - return 0; -} - -static void msg_dump_queue(void) -{ - struct hotplug_msg *msg; - - list_for_each_entry(msg, &msg_list, list) - dbg("sequence %d in queue", msg->seqnum); -} - -static void msg_check_queue(void) -{ - struct hotplug_msg *msg; - struct hotplug_msg *tmp_msg; - time_t msg_age; - -recheck: - /* dispatch events until one is missing */ - list_for_each_entry_safe(msg, tmp_msg, &msg_list, list) { - if (msg->seqnum != expect_seqnum) - break; - msg_exec(msg); - expect_seqnum++; + /* wait for exit of child */ + dbg("==> exec seq %d [%d] working at '%s'", + msg->seqnum, pid, msg->devpath); + wait(NULL); + dbg("<== exec seq %d came back", msg->seqnum); } - /* recalculate next timeout */ - if (list_empty(&msg_list) == 0) { - msg_age = time(NULL) - msg->queue_time; - if (msg_age > EVENT_TIMEOUT_SEC-1) { - info("event %d, age %li seconds, skip event %d-%d", - msg->seqnum, msg_age, expect_seqnum, msg->seqnum-1); - expect_seqnum = msg->seqnum; - goto recheck; - } +exit: + /* remove event from run list */ + pthread_mutex_lock(&running_lock); + list_del_init(&msg->list); + pthread_mutex_unlock(&running_lock); - /* the first sequence gets its own timeout */ - if (expect_seqnum == 0) { - msg_age = EVENT_TIMEOUT_SEC - FIRST_EVENT_TIMEOUT_SEC; - expect_seqnum = 1; - } + free(msg); - set_timeout(EVENT_TIMEOUT_SEC - msg_age); - return; - } + /* signal queue activity to exec manager */ + pthread_mutex_lock(&exec_active_lock); + pthread_cond_signal(&exec_active); + pthread_mutex_unlock(&exec_active_lock); + + pthread_exit(0); } -static int msg_add_queue(struct hotplug_msg *msg) +/* returns already running task with devpath */ +static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) { - struct hotplug_msg *new_msg; + struct hotplug_msg *loop_msg; struct hotplug_msg *tmp_msg; - new_msg = malloc(sizeof(*new_msg)); - if (new_msg == NULL) { - dbg("error malloc"); - return -ENOMEM; - } - memcpy(new_msg, msg, sizeof(*new_msg)); - - /* store timestamp of queuing */ - new_msg->queue_time = time(NULL); - - /* sort message by sequence number into list*/ - list_for_each_entry(tmp_msg, &msg_list, list) - if (tmp_msg->seqnum > new_msg->seqnum) - break; - list_add_tail(&new_msg->list, &tmp_msg->list); - - return 0; + list_for_each_entry_safe(loop_msg, tmp_msg, &running_list, list) + if (strncmp(loop_msg->devpath, msg->devpath, sizeof(loop_msg->devpath)) == 0) + return loop_msg; + return NULL; } -static void work(void) +/* queue management executes the events and delays events for the same devpath */ +static void *exec_queue_manager(void * parm) { + struct hotplug_msg *loop_msg; + struct hotplug_msg *tmp_msg; struct hotplug_msg *msg; - int msgid; - key_t key; - char buf[BUFFER_SIZE]; - int ret; + pthread_t run_tid; - key = ftok(UDEVD_BIN, IPC_KEY_ID); - msg = (struct hotplug_msg *) buf; - msgid = msgget(key, IPC_CREAT); - if (msgid == -1) { - dbg("open message queue error"); - exit(1); - } while (1) { - ret = msgrcv(msgid, (struct msgbuf *) buf, BUFFER_SIZE-4, HOTPLUGMSGTYPE, 0); - if (ret != -1) { - dbg("received sequence %d, expected sequence %d", msg->seqnum, expect_seqnum); - if (msg->seqnum >= expect_seqnum) { - msg_add_queue(msg); - msg_dump_queue(); - msg_check_queue(); - continue; + pthread_mutex_lock(&exec_lock); + list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, list) { + msg = running_with_devpath(loop_msg); + if (msg == NULL) { + /* move event to run list */ + pthread_mutex_lock(&running_lock); + list_move_tail(&loop_msg->list, &running_list); + pthread_mutex_unlock(&running_lock); + + pthread_create(&run_tid, &thr_attr, run_threads, (void *) loop_msg); + + dbg("moved seq %d to running list", loop_msg->seqnum); + } else { + dbg("delay seq %d, cause seq %d already working on '%s'", + loop_msg->seqnum, msg->seqnum, msg->devpath); } - dbg("too late for event with sequence %d, event skipped ", msg->seqnum); - } else { - if (errno == EINTR) { - msg_check_queue(); - msg_dump_queue(); - delayed_check_queue(); - delayed_dump_queue(); - continue; - } - dbg("ipc message receive error '%s'", strerror(errno)); } + pthread_mutex_unlock(&exec_lock); + + /* wait for activation, new events or childs coming back */ + pthread_mutex_lock(&exec_active_lock); + pthread_cond_wait(&exec_active, &exec_active_lock); + pthread_mutex_unlock(&exec_active_lock); + } +} + +/* move message from incoming to exec queue */ +static void msg_move_exec(struct list_head *head) +{ + list_move_tail(head, &exec_list); + /* signal queue activity to manager */ + pthread_mutex_lock(&exec_active_lock); + pthread_cond_signal(&exec_active); + pthread_mutex_unlock(&exec_active_lock); +} + +/* queue management thread handles the timeouts and dispatches the events */ +static void *msg_queue_manager(void * parm) +{ + struct hotplug_msg *loop_msg; + struct hotplug_msg *tmp_msg; + time_t msg_age = 0; + struct timespec tv; + + while (1) { + dbg("msg queue manager, next expected is %d", expected_seqnum); + pthread_mutex_lock(&msg_lock); + pthread_mutex_lock(&exec_lock); +recheck: + list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, list) { + /* move event with expected sequence to the exec list */ + if (loop_msg->seqnum == expected_seqnum) { + msg_move_exec(&loop_msg->list); + expected_seqnum++; + dbg("moved seq %d to exec, next expected is %d", + loop_msg->seqnum, expected_seqnum); + continue; + } + + /* move event with expired timeout to the exec list */ + msg_age = time(NULL) - loop_msg->queue_time; + if (msg_age > EVENT_TIMEOUT_SEC-1) { + msg_move_exec(&loop_msg->list); + expected_seqnum = loop_msg->seqnum+1; + dbg("moved seq %d to exec, reset next expected to %d", + loop_msg->seqnum, expected_seqnum); + goto recheck; + } else { + break; + } + } + + msg_dump_queue(); + pthread_mutex_unlock(&exec_lock); + pthread_mutex_unlock(&msg_lock); + + /* wait until queue gets active or next message timeout expires */ + pthread_mutex_lock(&msg_active_lock); + + if (list_empty(&msg_list) == 0) { + tv.tv_sec = time(NULL) + EVENT_TIMEOUT_SEC - msg_age; + tv.tv_nsec = 0; + dbg("next event expires in %li seconds", + EVENT_TIMEOUT_SEC - msg_age); + pthread_cond_timedwait(&msg_active, &msg_active_lock, &tv); + } else { + pthread_cond_wait(&msg_active, &msg_active_lock); + } + pthread_mutex_unlock(&msg_active_lock); + } +} + +/* every connect creates a thread which gets the msg, queues it and exits */ +static void *client_threads(void * parm) +{ + int sock; + struct hotplug_msg *msg; + int retval; + + sock = (int) parm; + + msg = msg_create(); + if (msg == NULL) { + dbg("unable to store message"); + goto exit; + } + + retval = recv(sock, msg, sizeof(struct hotplug_msg), 0); + if (retval < 0) { + dbg("unable to receive message"); + goto exit; + } + + if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { + dbg("message magic '%s' doesn't match, ignore it", msg->magic); + goto exit; + } + + pthread_mutex_lock(&msg_lock); + msg_queue_insert(msg); + pthread_mutex_unlock(&msg_lock); + +exit: + close(sock); + pthread_exit(0); +} + +static void sig_handler(int signum) +{ + switch (signum) { + case SIGINT: + case SIGTERM: + unlink(UDEVD_LOCK); + unlink(UDEVD_SOCKET); + exit(20 + signum); + break; + default: + dbg("unhandled signal"); } } static int one_and_only(void) { - char string[100]; - - lock_file = open(lock_filename, O_RDWR | O_CREAT, 0x640); + char string[50]; + int lock_file; /* see if we can open */ + lock_file = open(UDEVD_LOCK, O_RDWR | O_CREAT, 0x640); if (lock_file < 0) return -1; - + /* see if we can lock */ if (lockf(lock_file, F_TLOCK, 0) < 0) { + dbg("file is already locked, exit"); close(lock_file); return -1; } @@ -329,16 +340,73 @@ static int one_and_only(void) int main(int argc, char *argv[]) { + int ssock; + int csock; + struct sockaddr_un saddr; + struct sockaddr_un caddr; + socklen_t clen; + pthread_t cli_tid; + pthread_t mgr_msg_tid; + pthread_t mgr_exec_tid; + int retval; + /* only let one version of the daemon run at any one time */ if (one_and_only() != 0) exit(0); - /* set up signal handler */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); - signal(SIGALRM, sig_handler); - signal(SIGCHLD, sig_handler); - work(); - exit(0); + memset(&saddr, 0x00, sizeof(saddr)); + saddr.sun_family = AF_LOCAL; + strcpy(saddr.sun_path, UDEVD_SOCKET); + + unlink(UDEVD_SOCKET); + ssock = socket(AF_LOCAL, SOCK_STREAM, 0); + if (ssock == -1) { + dbg("error getting socket"); + exit(1); + } + + retval = bind(ssock, &saddr, sizeof(saddr)); + if (retval < 0) { + dbg("bind failed\n"); + goto exit; + } + + retval = listen(ssock, SOMAXCONN); + if (retval < 0) { + dbg("listen failed\n"); + goto exit; + } + + pthread_mutex_init(&msg_lock, NULL); + pthread_mutex_init(&msg_active_lock, NULL); + pthread_mutex_init(&exec_lock, NULL); + pthread_mutex_init(&exec_active_lock, NULL); + pthread_mutex_init(&running_lock, NULL); + + /* set default attributes for created threads */ + pthread_attr_init(&thr_attr); + pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED); + + /* init queue management */ + pthread_create(&mgr_msg_tid, &thr_attr, msg_queue_manager, NULL); + pthread_create(&mgr_exec_tid, &thr_attr, exec_queue_manager, NULL); + + clen = sizeof(caddr); + /* main loop */ + while (1) { + csock = accept(ssock, &caddr, &clen); + if (csock < 0) { + if (errno == EINTR) + continue; + dbg("client accept failed\n"); + } + pthread_create(&cli_tid, &thr_attr, client_threads, (void *) csock); + } +exit: + close(ssock); + unlink(UDEVD_SOCKET); + exit(1); } diff --git a/udevd.h b/udevd.h index 4bccd4b81a..e24bc28a78 100644 --- a/udevd.h +++ b/udevd.h @@ -4,6 +4,7 @@ * Userspace devfs * * Copyright (C) 2004 Ling, Xiaofeng + * Copyright (C) 2004 Kay Sievers * * * This program is free software; you can redistribute it and/or modify it @@ -23,16 +24,21 @@ #include "list.h" -#define FIRST_EVENT_TIMEOUT_SEC 1 +/* + * FIXME: udev_root is post compile configurable and may also be + * mounted over at any time and /var/run/ and /tmp/ is unusable, + * cause it's cleaned at system startup, long _after_ udevd is + * already running. Should we use udev_init_config()? + */ + +#define UDEV_MAGIC "udev_" UDEV_VERSION #define EVENT_TIMEOUT_SEC 5 -#define UDEVSEND_RETRY_COUNT 50 /* x 10 millisec */ - -#define IPC_KEY_ID 1 -#define HOTPLUGMSGTYPE 44 - +#define UDEVSEND_CONNECT_RETRY 20 /* x 100 millisec */ +#define UDEVD_SOCKET UDEV_ROOT ".udevd.socket" +#define UDEVD_LOCK UDEV_ROOT ".udevd.pid" struct hotplug_msg { - long mtype; + char magic[20]; struct list_head list; pid_t pid; int seqnum; diff --git a/udevsend.c b/udevsend.c index f92ee2b5d8..6ffd68c1b7 100644 --- a/udevsend.c +++ b/udevsend.c @@ -32,12 +32,15 @@ #include #include #include +#include +#include #include "udev.h" #include "udev_version.h" #include "udevd.h" #include "logging.h" + static inline char *get_action(void) { char *action; @@ -66,7 +69,7 @@ static int build_hotplugmsg(struct hotplug_msg *msg, char *action, char *devpath, char *subsystem, int seqnum) { memset(msg, 0x00, sizeof(*msg)); - msg->mtype = HOTPLUGMSGTYPE; + strfieldcpy(msg->magic, UDEV_MAGIC); msg->seqnum = seqnum; strncpy(msg->action, action, 8); strncpy(msg->devpath, devpath, 128); @@ -108,12 +111,8 @@ static int start_daemon(void) return 0; } - int main(int argc, char* argv[]) { - int msgid; - key_t key; - struct msqid_ds msg_queue; struct hotplug_msg message; char *action; char *devpath; @@ -124,6 +123,8 @@ int main(int argc, char* argv[]) int size; int loop; struct timespec tspec; + int sock; + struct sockaddr_un saddr; subsystem = argv[1]; if (subsystem == NULL) { @@ -150,41 +151,58 @@ int main(int argc, char* argv[]) } seq = atoi(seqnum); - /* create ipc message queue or get id of our existing one */ - key = ftok(UDEVD_BIN, IPC_KEY_ID); - dbg("using ipc queue 0x%0x", key); - size = build_hotplugmsg(&message, action, devpath, subsystem, seq); - msgid = msgget(key, IPC_CREAT); - if (msgid == -1) { - dbg("error open ipc queue"); + sock = socket(AF_LOCAL, SOCK_STREAM, 0); + if (sock == -1) { + dbg("error getting socket"); goto exit; } - /* send ipc message to the daemon */ - retval = msgsnd(msgid, &message, size, 0); - if (retval == -1) { - dbg("error sending ipc message"); - goto exit; - } + memset(&saddr, 0x00, sizeof(saddr)); + saddr.sun_family = AF_LOCAL; + strcpy(saddr.sun_path, UDEVD_SOCKET); - /* get state of ipc queue */ - tspec.tv_sec = 0; - tspec.tv_nsec = 10000000; /* 10 millisec */ - loop = UDEVSEND_RETRY_COUNT; - while (loop--) { - retval = msgctl(msgid, IPC_STAT, &msg_queue); - if (retval == -1) { - dbg("error getting info on ipc queue"); + /* try to connect, if it fails start daemon */ + retval = connect(sock, &saddr, sizeof(saddr)); + if (retval != -1) { + goto send; + } else { + dbg("connect failed, try starting daemon..."); + retval = start_daemon(); + if (retval == 0) { + dbg("daemon started"); + } else { + dbg("error starting daemon"); goto exit; } - if (msg_queue.msg_qnum == 0) - goto exit; - nanosleep(&tspec, NULL); } - info("message is still in the ipc queue, starting daemon..."); - retval = start_daemon(); + /* try to connect while daemon to starts */ + tspec.tv_sec = 0; + tspec.tv_nsec = 100000000; /* 100 millisec */ + loop = UDEVSEND_CONNECT_RETRY; + while (loop--) { + retval = connect(sock, &saddr, sizeof(saddr)); + if (retval != -1) + goto send; + else + dbg("retry to connect %d", + UDEVSEND_CONNECT_RETRY - loop); + nanosleep(&tspec, NULL); + } + dbg("error connecting to daemon, start daemon failed"); + goto exit; + +send: + size = build_hotplugmsg(&message, action, devpath, subsystem, seq); + retval = send(sock, &message, size, 0); + if (retval == -1) { + dbg("error sending message"); + close (sock); + goto exit; + } + close (sock); + return 0; exit: - return retval; + return 1; } From 8e2229c439f4d0bcf5660457d5a2d6f9d4723e88 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 2 Feb 2004 08:00:07 -0800 Subject: [PATCH 0481/4284] [PATCH] udevd - config cleanup > Here is a small cleanup and better Makefile integration. > udevd and udevsender are now installed. Just switch HOTPLUG_EXEC from ROOT > to SENDER before install and udevsend will be called. > > We may add the location of the socket and lock file to the config, > if this is needed. Same patch with a fix for the stack size setting. --- Makefile | 15 +++++++++++---- udevd.c | 26 +++++++++++++++----------- udevd.h | 11 +---------- udevsend.c | 2 +- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index d953218f7b..05d5da5a33 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,7 @@ VERSION = 015_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev +HOTPLUG_EXEC = $(ROOT) DESTDIR = # override this to make udev look in a different location for it's config files @@ -232,8 +233,10 @@ udev_version.h: @echo \#define UDEV_CONFIG_FILE \"$(configdir)\udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ - @echo \#define UDEV_BIN \"$(PWD)/udev\" >> $@ - @echo \#define UDEVD_BIN \"$(PWD)/udevd\" >> $@ + @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ + @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ + @echo \#define UDEVD_SOCK \"$(udevdir)/\.udevd.sock\" >> $@ + @echo \#define UDEVD_LOCK \"$(udevdir)/\.udevd.lock\" >> $@ # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf @@ -338,6 +341,8 @@ install: install-config install-dbus-policy all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) + $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) + $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(HELPER) $(DESTDIR)$(sbindir)/$(HELPER) @if [ "x$(USE_LSB)" = "xtrue" ]; then \ $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ @@ -347,8 +352,8 @@ install: install-config install-dbus-policy all fi $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 - - rm -f $(DESTDIR)$(hotplugdir)/udev.hotplug - - ln -f -s $(sbindir)/$(ROOT) $(DESTDIR)$(hotplugdir)/udev.hotplug + - rm -f $(DESTDIR)$(hotplugdir)/$(HOTPLUG_EXEC).hotplug + - ln -f -s $(sbindir)/$(HOTPLUG_EXEC) $(DESTDIR)$(hotplugdir)/udev.hotplug @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ @@ -364,6 +369,8 @@ uninstall: uninstall-dbus-policy - rm $(mandir)/man8/udev.8 - rm $(mandir)/man8/udevinfo.8 - rm $(sbindir)/$(ROOT) + - rm $(sbindir)/$(DAEMON) + - rm $(sbindir)/$(SENDER) - rm $(sbindir)/$(HELPER) - rmdir $(hotplugdir) - rmdir $(configdir) diff --git a/udevd.c b/udevd.c index 22fb4d33db..dc7d581c24 100644 --- a/udevd.c +++ b/udevd.c @@ -19,6 +19,7 @@ * */ +#include #include #include #include @@ -33,7 +34,6 @@ #include #include #include -#include #include "list.h" #include "udev.h" @@ -71,7 +71,6 @@ static void msg_dump(struct hotplug_msg *msg) msg->seqnum, msg->action, msg->devpath, msg->subsystem); } -/* allocates a new message */ static struct hotplug_msg *msg_create(void) { struct hotplug_msg *new_msg; @@ -81,10 +80,15 @@ static struct hotplug_msg *msg_create(void) dbg("error malloc"); return NULL; } - memset(new_msg, 0x00, sizeof(struct hotplug_msg)); return new_msg; } +static void msg_delete(struct hotplug_msg *msg) +{ + if (msg != NULL) + free(msg); +} + /* orders the message in the queue by sequence number */ static void msg_queue_insert(struct hotplug_msg *msg) { @@ -143,7 +147,7 @@ exit: list_del_init(&msg->list); pthread_mutex_unlock(&running_lock); - free(msg); + msg_delete(msg); /* signal queue activity to exec manager */ pthread_mutex_lock(&exec_active_lock); @@ -289,6 +293,7 @@ static void *client_threads(void * parm) if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { dbg("message magic '%s' doesn't match, ignore it", msg->magic); + msg_delete(msg); goto exit; } @@ -307,7 +312,7 @@ static void sig_handler(int signum) case SIGINT: case SIGTERM: unlink(UDEVD_LOCK); - unlink(UDEVD_SOCKET); + unlink(UDEVD_SOCK); exit(20 + signum); break; default: @@ -320,7 +325,6 @@ static int one_and_only(void) char string[50]; int lock_file; - /* see if we can open */ lock_file = open(UDEVD_LOCK, O_RDWR | O_CREAT, 0x640); if (lock_file < 0) return -1; @@ -359,9 +363,9 @@ int main(int argc, char *argv[]) memset(&saddr, 0x00, sizeof(saddr)); saddr.sun_family = AF_LOCAL; - strcpy(saddr.sun_path, UDEVD_SOCKET); + strcpy(saddr.sun_path, UDEVD_SOCK); - unlink(UDEVD_SOCKET); + unlink(UDEVD_SOCK); ssock = socket(AF_LOCAL, SOCK_STREAM, 0); if (ssock == -1) { dbg("error getting socket"); @@ -389,6 +393,7 @@ int main(int argc, char *argv[]) /* set default attributes for created threads */ pthread_attr_init(&thr_attr); pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&thr_attr, 16 * 1024); /* init queue management */ pthread_create(&mgr_msg_tid, &thr_attr, msg_queue_manager, NULL); @@ -399,14 +404,13 @@ int main(int argc, char *argv[]) while (1) { csock = accept(ssock, &caddr, &clen); if (csock < 0) { - if (errno == EINTR) - continue; dbg("client accept failed\n"); + continue; } pthread_create(&cli_tid, &thr_attr, client_threads, (void *) csock); } exit: close(ssock); - unlink(UDEVD_SOCKET); + unlink(UDEVD_SOCK); exit(1); } diff --git a/udevd.h b/udevd.h index e24bc28a78..6dbee3a295 100644 --- a/udevd.h +++ b/udevd.h @@ -24,18 +24,9 @@ #include "list.h" -/* - * FIXME: udev_root is post compile configurable and may also be - * mounted over at any time and /var/run/ and /tmp/ is unusable, - * cause it's cleaned at system startup, long _after_ udevd is - * already running. Should we use udev_init_config()? - */ - -#define UDEV_MAGIC "udev_" UDEV_VERSION +#define UDEV_MAGIC "udevd_" UDEV_VERSION #define EVENT_TIMEOUT_SEC 5 #define UDEVSEND_CONNECT_RETRY 20 /* x 100 millisec */ -#define UDEVD_SOCKET UDEV_ROOT ".udevd.socket" -#define UDEVD_LOCK UDEV_ROOT ".udevd.pid" struct hotplug_msg { char magic[20]; diff --git a/udevsend.c b/udevsend.c index 6ffd68c1b7..0ddc6839de 100644 --- a/udevsend.c +++ b/udevsend.c @@ -159,7 +159,7 @@ int main(int argc, char* argv[]) memset(&saddr, 0x00, sizeof(saddr)); saddr.sun_family = AF_LOCAL; - strcpy(saddr.sun_path, UDEVD_SOCKET); + strcpy(saddr.sun_path, UDEVD_SOCK); /* try to connect, if it fails start daemon */ retval = connect(sock, &saddr, sizeof(saddr)); From 3a7798f4714c88021b6ac0cda3e1d818a3fa7a07 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 2 Feb 2004 08:19:13 -0800 Subject: [PATCH 0482/4284] [PATCH] remove logging.c as it's no longer needed. --- logging.c | 56 ------------------------------------------------------- 1 file changed, 56 deletions(-) delete mode 100644 logging.c diff --git a/logging.c b/logging.c deleted file mode 100644 index cf1da5e040..0000000000 --- a/logging.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * logging.c - * - * Simple logging functions that can be compiled away into nothing. - * - * Copyright (C) 2001-2003 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. - * - * 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. - * - */ - -#include -#include -#include -#include -#include - -#include "logging.h" - - -static int logging_init = 0; -static unsigned char udev_logname[42]; - -static void init_logging(void) -{ - snprintf(udev_logname, 42,"udev[%d]", getpid()); - - openlog(udev_logname, 0, LOG_DAEMON); - logging_init = 1; -} - -/** - * log_message - sends a message to the logging facility - */ -int log_message(int level, const char *format, ...) -{ - va_list args; - - if (!logging_init) - init_logging(); - va_start(args, format); - vsyslog(level, format, args); - va_end(args); - return 1; -} From 95a6f4c8acafe7031087667aa556a50a6a091c93 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 2 Feb 2004 08:19:41 -0800 Subject: [PATCH 0483/4284] [PATCH] rework the logging code so that each program logs with the proper name in the syslog. --- Makefile | 11 +++++------ libsysfs/sysfs.h | 6 +----- logging.h | 28 +++++++++++++++++++++++----- udev.c | 2 ++ udevd.c | 3 +++ udevinfo.c | 3 +++ udevsend.c | 3 +++ 7 files changed, 40 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 05d5da5a33..386583b7eb 100644 --- a/Makefile +++ b/Makefile @@ -195,7 +195,6 @@ OBJS = udev_config.o \ udev-add.o \ udev-remove.o \ udevdb.o \ - logging.o \ namedev.o \ namedev_parse.o \ $(SYSFS) \ @@ -254,15 +253,15 @@ $(ROOT): udev.o $(OBJS) $(HEADERS) $(GEN_HEADERS) $(STRIPCMD) $@ $(HELPER): udevinfo.o $(OBJS) $(HEADERS) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o logging.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(DAEMON): udevd.h udevd.o udevd.o logging.o - $(LD) $(LDFLAGS) -lpthread -o $@ $(CRT0) udevd.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(DAEMON): udevd.h udevd.o + $(LD) $(LDFLAGS) -lpthread -o $@ $(CRT0) udevd.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(SENDER): udevd.h udevsend.o udevd.o logging.o - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o logging.o $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(SENDER): udevd.h udevsend.o + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ clean: diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 4ea4919351..49c9285bc3 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -34,7 +34,7 @@ /* Debugging */ #ifdef DEBUG -#include +#include "../logging.h" #define dprintf(format, arg...) \ do { \ log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ @@ -43,8 +43,4 @@ #define dprintf(format, arg...) do { } while (0) #endif -extern int log_message (int level, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - - #endif /* _SYSFS_H_ */ diff --git a/logging.h b/logging.h index df5922b3e6..e233ddc889 100644 --- a/logging.h +++ b/logging.h @@ -1,9 +1,9 @@ /* * logging.h * - * Userspace devfs + * Simple logging functions that can be compiled away into nothing. * - * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003,2004 Greg Kroah-Hartman * Copyright (C) 2004 Kay Sievers * * This program is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ #define dbg_parse(format, arg...) do { } while (0) #ifdef LOG +#include #include #undef info @@ -54,9 +55,26 @@ } while (0) #endif +static void log_message (int level, const char *format, ...) + __attribute__ ((format (printf, 2, 3))); +static inline void log_message (int level, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} + +/* each program must declare this variable somewhere */ +extern unsigned char logname[42]; + +static inline void init_logging(char *program_name) +{ + snprintf(logname, 42,"%s[%d]", program_name, getpid()); + openlog(logname, 0, LOG_DAEMON); +} + #endif /* LOG */ -extern int log_message (int level, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - #endif diff --git a/udev.c b/udev.c index 38b26916c9..b45fb336be 100644 --- a/udev.c +++ b/udev.c @@ -38,6 +38,7 @@ /* global variables */ char **main_argv; char **main_envp; +unsigned char logname[42]; static void sig_handler(int signum) { @@ -174,6 +175,7 @@ int main(int argc, char **argv, char **envp) main_argv = argv; main_envp = envp; + init_logging("udev"); dbg("version %s", UDEV_VERSION); return udev_hotplug(argc, argv); diff --git a/udevd.c b/udevd.c index dc7d581c24..331b7e4b84 100644 --- a/udevd.c +++ b/udevd.c @@ -42,6 +42,7 @@ #include "logging.h" +unsigned char logname[42]; static pthread_mutex_t msg_lock; static pthread_mutex_t msg_active_lock; static pthread_cond_t msg_active; @@ -354,6 +355,8 @@ int main(int argc, char *argv[]) pthread_t mgr_exec_tid; int retval; + init_logging("udevd"); + /* only let one version of the daemon run at any one time */ if (one_and_only() != 0) exit(0); diff --git a/udevinfo.c b/udevinfo.c index 4d28755b2f..71a9a6d93e 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -38,6 +38,7 @@ char **main_argv; int main_argc; +unsigned char logname[42]; static int print_all_attributes(const char *path) { @@ -412,6 +413,8 @@ int main(int argc, char *argv[], char *envp[]) main_argv = argv; main_argc = argc; + init_logging("udevinfo"); + /* initialize our configuration */ udev_init_config(); diff --git a/udevsend.c b/udevsend.c index 0ddc6839de..6af9df7704 100644 --- a/udevsend.c +++ b/udevsend.c @@ -40,6 +40,7 @@ #include "udevd.h" #include "logging.h" +unsigned char logname[42]; static inline char *get_action(void) { @@ -126,6 +127,8 @@ int main(int argc, char* argv[]) int sock; struct sockaddr_un saddr; + init_logging("udevsend"); + subsystem = argv[1]; if (subsystem == NULL) { dbg("no subsystem"); From 62e156af9438bfd6404de3e359a890286cb49479 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 2 Feb 2004 08:22:01 -0800 Subject: [PATCH 0484/4284] [PATCH] fix up logging code so that it can be built without it being enabled --- logging.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/logging.h b/logging.h index e233ddc889..3ee3e1acf0 100644 --- a/logging.h +++ b/logging.h @@ -27,6 +27,7 @@ #define info(format, arg...) do { } while (0) #define dbg(format, arg...) do { } while (0) #define dbg_parse(format, arg...) do { } while (0) +#define init_logging(foo) do { } while (0) #ifdef LOG #include @@ -69,6 +70,7 @@ static inline void log_message (int level, const char *format, ...) /* each program must declare this variable somewhere */ extern unsigned char logname[42]; +#undef init_logging static inline void init_logging(char *program_name) { snprintf(logname, 42,"%s[%d]", program_name, getpid()); From 0be0c18de37b463f40c649f1b66b7683f2bf836b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 2 Feb 2004 08:29:04 -0800 Subject: [PATCH 0485/4284] [PATCH] udevsend now almost compiles with klibc, struct sockaddr_un is only problem now. --- udevsend.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/udevsend.c b/udevsend.c index 6af9df7704..415207d8ca 100644 --- a/udevsend.c +++ b/udevsend.c @@ -23,17 +23,15 @@ */ #include -#include -#include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include #include "udev.h" #include "udev_version.h" From d5c6d80ff1b617419dfcadb2fea4710d14f34b98 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 2 Feb 2004 18:10:29 -0800 Subject: [PATCH 0486/4284] [PATCH] let udevsend build with klibc > I don't mind udevd using glibc, I just want the programs that get run a > lot of different times (udev and udevsend) to be as small as possible to > get the best cache results. As udevd sticks around all the time, it's > not as important. Sound sane to you? Oh, nice. Good idea. --- Makefile | 4 ++-- klibc/klibc/include/sys/un.h | 10 ++++++++++ udevsend.c | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 klibc/klibc/include/sys/un.h diff --git a/Makefile b/Makefile index 386583b7eb..dd2f697591 100644 --- a/Makefile +++ b/Makefile @@ -161,12 +161,12 @@ else CFLAGS += $(WARNINGS) -I$(GCCINCDIR) LIB_OBJS = -lc LDFLAGS = - UDEVD = $(DAEMON) $(SENDER) + UDEVD = $(DAEMON) endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(UDEVD) $(HELPER) +all: $(ROOT) $(SENDER) $(UDEVD) $(HELPER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ diff --git a/klibc/klibc/include/sys/un.h b/klibc/klibc/include/sys/un.h new file mode 100644 index 0000000000..85822ba6a4 --- /dev/null +++ b/klibc/klibc/include/sys/un.h @@ -0,0 +1,10 @@ +/* + * sys/un.h + */ + +#ifndef _UN_H +#define _UN_H + +#include + +#endif /* _UN_H */ diff --git a/udevsend.c b/udevsend.c index 415207d8ca..fd61cb2a2f 100644 --- a/udevsend.c +++ b/udevsend.c @@ -163,7 +163,7 @@ int main(int argc, char* argv[]) strcpy(saddr.sun_path, UDEVD_SOCK); /* try to connect, if it fails start daemon */ - retval = connect(sock, &saddr, sizeof(saddr)); + retval = connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)); if (retval != -1) { goto send; } else { @@ -182,7 +182,7 @@ int main(int argc, char* argv[]) tspec.tv_nsec = 100000000; /* 100 millisec */ loop = UDEVSEND_CONNECT_RETRY; while (loop--) { - retval = connect(sock, &saddr, sizeof(saddr)); + retval = connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)); if (retval != -1) goto send; else From e047ca9bdfc3d95cccbbcf6d4f2358648c7d0758 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 2 Feb 2004 18:42:42 -0800 Subject: [PATCH 0487/4284] [PATCH] make udevsend binary even smaller --- udevsend.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udevsend.c b/udevsend.c index fd61cb2a2f..d3c74dd46a 100644 --- a/udevsend.c +++ b/udevsend.c @@ -125,7 +125,9 @@ int main(int argc, char* argv[]) int sock; struct sockaddr_un saddr; +#ifdef DEBUG init_logging("udevsend"); +#endif subsystem = argv[1]; if (subsystem == NULL) { From 786f9231961cc12e59cce3e3ad117ad976adf6f5 Mon Sep 17 00:00:00 2001 From: "rrm3@rrm3.org" Date: Tue, 3 Feb 2004 00:20:27 -0800 Subject: [PATCH 0488/4284] [PATCH] FAQ udev.rules.devfs I have a very small patch for the udev FAQ. :-) --- FAQ | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FAQ b/FAQ index 1f7ceb0dd3..a3bec17408 100644 --- a/FAQ +++ b/FAQ @@ -53,7 +53,7 @@ A: The devfs approach caused a lot of spurious modprobe attempts as Q: I really like the devfs naming scheme, will udev do that? A: Yes, udev can create /dev nodes using the devfs naming policy. A configuration file needs to be created to map the kernel default names - to the devfs names. See the initial udev.conf.devfs file in the udev + to the devfs names. See the initial udev.rules.devfs file in the udev release. It is the start of such a configuration file. If there are any things missing, please let the udev authors know. From c7e2a0bc082321bceea7ac86fa6e1a42bcc91072 Mon Sep 17 00:00:00 2001 From: "elkropac@students.zcu.cz" Date: Tue, 3 Feb 2004 00:20:31 -0800 Subject: [PATCH 0489/4284] [PATCH] get_dev_number() in extras/ide-devfs.sh this patch corrects ide devices with number greater than 9 being linked into wrong discs/discX directories (my hda10 device was in discs/disc1 directory) it adds % into pattern for $DRIVE, so for example, hda10 is not eaten to hda1, but to hda, and break in for cycle works for it --- extras/ide-devfs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 8648f6c0c0..1cf6f9c9e4 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -18,7 +18,7 @@ get_dev_number() { local x= local num=0 local MEDIA= - local DRIVE="${1%[0-9]*}" + local DRIVE="${1%%[0-9]*}" for x in /proc/ide/*/media; do if [ -e "${x}" ]; then From 977083c253a6c7ec282f1cf36c496ee280dbf069 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 3 Feb 2004 00:51:51 -0800 Subject: [PATCH 0490/4284] [PATCH] add KERNEL_DIR option so that the distros will be happy Based on a patch from Svetoslav Slavtchev --- Makefile | 13 ++++++++++--- README | 10 ++++++---- extras/multipath/Makefile | 4 ++-- extras/multipath/libdevmapper/Makefile | 2 +- klibc/MCONFIG | 2 +- 5 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index dd2f697591..e1846dd4c0 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,9 @@ LOCAL_CFG_DIR = etc/udev HOTPLUG_EXEC = $(ROOT) DESTDIR = + +KERNEL_DIR = /lib/modules/${shell uname -r}/build + # override this to make udev look in a different location for it's config files prefix = exec_prefix = ${prefix} @@ -135,7 +138,8 @@ ifeq ($(strip $(USE_KLIBC)),true) KLIBC_BASE = $(PWD)/klibc KLIBC_DIR = $(KLIBC_BASE)/klibc INCLUDE_DIR := $(KLIBC_DIR)/include - LINUX_INCLUDE_DIR := $(KLIBC_BASE)/linux/include + LINUX_INCLUDE_DIR := $(KERNEL_DIR)/include +# LINUX_INCLUDE_DIR := $(KLIBC_BASE)/linux/include include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG # arch specific objects ARCH_LIB_OBJS = \ @@ -169,7 +173,10 @@ CFLAGS += -I$(PWD)/libsysfs all: $(ROOT) $(SENDER) $(UDEVD) $(HELPER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ - $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ + $(MAKE) prefix=$(prefix) \ + LD="$(LD)" \ + SYSFS="$(SYSFS)" \ + KERNEL_DIR="$(KERNEL_DIR)" \ -C $$target $@ ; \ done ; \ @@ -178,7 +185,7 @@ $(ROOT): $(LIBC) $(ARCH_LIB_OBJS) : $(CRT0) $(CRT0): - $(MAKE) -C klibc + $(MAKE) -C klibc KERNEL_DIR=$(KERNEL_DIR) TDB = tdb/tdb.o \ tdb/spinlock.o diff --git a/README b/README index 26032c35dc..c63912101a 100644 --- a/README +++ b/README @@ -52,15 +52,16 @@ To use: DEBUG if set to 'true', debugging messages will be sent to the syslog as udev is run. Default value is 'false'. + KERNEL_DIR + If this is not set it will default to /lib/modules/`uname -r`/build + This is used if USE_KLIBC=true to find the kernel include + directory that klibc needs to build against. This must be set + if you are not building udev while running a 2.6 kernel. So, if you want to build udev using klibc with debugging messages, you would do: make USE_KLIBC=true DEBUG=true - Note: If you want to use klibc, you will have to set up the "linux" - symlink properly. See the file klibc/klibc/README and pay - attention to step "a)" there. - - Install the project: make install @@ -95,3 +96,4 @@ greg@kroah.com + diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index 3f13532e16..0aac146a87 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -15,7 +15,7 @@ CC = gcc GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ - -I$(GCCINCDIR) -I$(klibcdir)/linux/include -I$(sysfsdir) -I. + -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. OBJS = main.o CRT0 = ../../klibc/klibc/crt0.o @@ -32,7 +32,7 @@ SUBDIRS = libdevmapper recurse: @for dir in $(SUBDIRS); do\ - $(MAKE) -C $$dir ; \ + $(MAKE) KERNEL_DIR=$(KERNEL_DIR) -C $$dir ; \ done $(MAKE) $(EXEC) diff --git a/extras/multipath/libdevmapper/Makefile b/extras/multipath/libdevmapper/Makefile index b160075416..a05a31e85a 100644 --- a/extras/multipath/libdevmapper/Makefile +++ b/extras/multipath/libdevmapper/Makefile @@ -10,7 +10,7 @@ CC = gcc GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ - -I$(GCCINCDIR) -I$(klibcdir)/linux/include -I. -Iioctl + -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I. -Iioctl OBJS = ioctl/libdevmapper.o libdm-common.o diff --git a/klibc/MCONFIG b/klibc/MCONFIG index ed7755b382..8b5da4154b 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -12,7 +12,7 @@ REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include -I$(KLIBSRC) \ -I$(KLIBSRC)/arch/$(ARCH)/include \ -I$(KLIBSRC)/include/bits$(BITSIZE) \ -D__KLIBC__ -DBITSIZE=$(BITSIZE) -I$(KLIBSRC)/include \ - -I$(SRCROOT)/linux/include + -I$(KERNEL_DIR)/include LDFLAGS = AR = $(CROSS)ar RANLIB = $(CROSS)ranlib From db8f5cf28c13fd7d81d1aa32fe8df6864a0a019f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 3 Feb 2004 01:29:20 -0800 Subject: [PATCH 0491/4284] [PATCH] make /etc/hotplug.d/default/udev.hotplug symlink point to udevsend now. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e1846dd4c0..58e0bd51af 100644 --- a/Makefile +++ b/Makefile @@ -358,8 +358,8 @@ install: install-config install-dbus-policy all fi $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 - - rm -f $(DESTDIR)$(hotplugdir)/$(HOTPLUG_EXEC).hotplug - - ln -f -s $(sbindir)/$(HOTPLUG_EXEC) $(DESTDIR)$(hotplugdir)/udev.hotplug + - rm -f $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug + - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ From d83a9b89e75aeb79856ddc4d95dc32a6bbd17f0e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 3 Feb 2004 01:29:45 -0800 Subject: [PATCH 0492/4284] [PATCH] add udevd and udevsend to the spec file. --- udev.spec | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index ccc0ca7f6a..7a42dbc1fd 100644 --- a/udev.spec +++ b/udev.spec @@ -62,6 +62,10 @@ make CC="gcc $RPM_OPT_FLAGS" \ DEBUG=true \ %endif +# now build udevd on it's own, as it can't handle being built with klibc +make CC="gcc $RPM_OPT_FLAGS" udevd + + %install make DESTDIR=$RPM_BUILD_ROOT install \ %if %{dbus} @@ -70,7 +74,6 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %if %{lsb} USE_LSB=true %endif - %post /sbin/chkconfig --add udev @@ -87,6 +90,8 @@ rm -rf $RPM_BUILD_ROOT %doc COPYING README TODO ChangeLog %attr(755,root,root) /sbin/udev %attr(755,root,root) /sbin/udevinfo +%attr(755,root,root) /sbin/udevsend +%attr(755,root,root) /sbin/udevd %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf @@ -100,6 +105,10 @@ rm -rf $RPM_BUILD_ROOT %attr(0644,root,root) %{_mandir}/man8/udev*.8* %changelog +* Mon Feb 2 2004 Greg Kroah-Hartman +- add udevsend, and udevd to the files +- add ability to build udevd with glibc after the rest is build with klibc + * Mon Jan 26 2004 Greg Kroah-Hartman - added udevinfo to rpm - added URL to spec file From 33689812366dfc74825956b4a2a1f86081b51b9d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 3 Feb 2004 18:23:13 -0800 Subject: [PATCH 0493/4284] [PATCH] v016 release --- ChangeLog | 35 +++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3a4b2c0099..ca1f765aef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,38 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 58e0bd51af..631439a316 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ROOT = udev DAEMON = udevd SENDER = udevsend HELPER = udevinfo -VERSION = 015_bk +VERSION = 016 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 7a42dbc1fd..238494c45b 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 015_bk +Version: 016 Release: 1 License: GPL Group: Utilities/System From 1dc10a94d8334b49ddf6fb4ceed33e5038105c83 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 3 Feb 2004 22:45:49 -0800 Subject: [PATCH 0494/4284] [PATCH] fix up Makefile dependancies for udev_version.h --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 631439a316..426ee577e3 100644 --- a/Makefile +++ b/Makefile @@ -259,15 +259,15 @@ $(ROOT): udev.o $(OBJS) $(HEADERS) $(GEN_HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(HELPER): udevinfo.o $(OBJS) $(HEADERS) +$(HELPER): $(HEADERS) udevinfo.o $(OBJS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(DAEMON): udevd.h udevd.o +$(DAEMON): udevd.h $(GEN_HEADERS) udevd.o $(LD) $(LDFLAGS) -lpthread -o $@ $(CRT0) udevd.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(SENDER): udevd.h udevsend.o +$(SENDER): udevd.h $(GEN_HEADERS) udevsend.o $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ From e5369f0a3adf14cebaf9537cba2d2092d392583d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 4 Feb 2004 00:55:24 -0800 Subject: [PATCH 0495/4284] [PATCH] include used function This includes the missing header for the use of getpid in logging.h. --- logging.h | 1 + 1 file changed, 1 insertion(+) diff --git a/logging.h b/logging.h index 3ee3e1acf0..485209adf3 100644 --- a/logging.h +++ b/logging.h @@ -31,6 +31,7 @@ #ifdef LOG #include +#include #include #undef info From 16be1328898ed54d6b9cbc56ea113bf911450376 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 4 Feb 2004 00:56:10 -0800 Subject: [PATCH 0496/4284] [PATCH] 016_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 426ee577e3..618adad71e 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ ROOT = udev DAEMON = udevd SENDER = udevsend HELPER = udevinfo -VERSION = 016 +VERSION = 016_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 238494c45b..20f4154998 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 016 +Version: 016_bk Release: 1 License: GPL Group: Utilities/System From 86590cd590a9f2fcc5917e8f5c85e024af1e58e0 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 5 Feb 2004 01:35:08 -0800 Subject: [PATCH 0497/4284] [PATCH] udevd - allow to bypass sequence number This patch allows udevsend to be called by the user and not only by the kernel with its SEQNUM. If no SEQNUM is given, we move the event straight to the exec queue and don't look if something is missing. I don't know if this is really needed, but some people seem trying to send events trough udevd instead of calling udev directly with their scripts and confuse the reorder logic with that. So at least, we may remove this source of confusion and udevsend is much much faster back than udev itself and it will also block concurrent events for the same devpath. --- udevd.c | 26 +++++++++++++++++++------- udevsend.c | 9 ++++----- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/udevd.c b/udevd.c index 331b7e4b84..f8b8c27ee4 100644 --- a/udevd.c +++ b/udevd.c @@ -205,14 +205,18 @@ static void *exec_queue_manager(void * parm) } } +static void exec_queue_activate(void) +{ + pthread_mutex_lock(&exec_active_lock); + pthread_cond_signal(&exec_active); + pthread_mutex_unlock(&exec_active_lock); +} + /* move message from incoming to exec queue */ static void msg_move_exec(struct list_head *head) { list_move_tail(head, &exec_list); - /* signal queue activity to manager */ - pthread_mutex_lock(&exec_active_lock); - pthread_cond_signal(&exec_active); - pthread_mutex_unlock(&exec_active_lock); + exec_queue_activate(); } /* queue management thread handles the timeouts and dispatches the events */ @@ -298,9 +302,17 @@ static void *client_threads(void * parm) goto exit; } - pthread_mutex_lock(&msg_lock); - msg_queue_insert(msg); - pthread_mutex_unlock(&msg_lock); + /* if no seqnum is given, we move straight to exec queue */ + if (msg->seqnum == 0) { + pthread_mutex_lock(&exec_lock); + list_add(&msg->list, &exec_list); + exec_queue_activate(); + pthread_mutex_unlock(&exec_lock); + } else { + pthread_mutex_lock(&msg_lock); + msg_queue_insert(msg); + pthread_mutex_unlock(&msg_lock); + } exit: close(sock); diff --git a/udevsend.c b/udevsend.c index d3c74dd46a..9dc2b2e841 100644 --- a/udevsend.c +++ b/udevsend.c @@ -148,11 +148,10 @@ int main(int argc, char* argv[]) } seqnum = get_seqnum(); - if (seqnum == NULL) { - dbg("no seqnum"); - goto exit; - } - seq = atoi(seqnum); + if (seqnum == NULL) + seq = 0; + else + seq = atoi(seqnum); sock = socket(AF_LOCAL, SOCK_STREAM, 0); if (sock == -1) { From 872344c41094f636fd667b9e619f8f219d814605 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 5 Feb 2004 01:35:15 -0800 Subject: [PATCH 0498/4284] [PATCH] udevd - switch socket path to abstract namespace As Chris Friesen suggested, here we switch the unix domains socket path to abstract namespace and get rid of the socket file in the filesystem. Hey, this was new to me today. So here a few words: Linux supports a abstract namespace for sockets. We don't need a physical file on the filesystem but only a unique string magically starting with the '\0' character. strace with real file: connect(3, {sa_family=AF_UNIX, path="/udev/.udevd.sock"}, 110) strace with abstract namespace: connect(3, {sa_family=AF_UNIX, path=@udevd}, 110) --- Makefile | 1 - udevd.c | 6 ++---- udevd.h | 1 + udevsend.c | 3 ++- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 618adad71e..35575806db 100644 --- a/Makefile +++ b/Makefile @@ -241,7 +241,6 @@ udev_version.h: @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ - @echo \#define UDEVD_SOCK \"$(udevdir)/\.udevd.sock\" >> $@ @echo \#define UDEVD_LOCK \"$(udevdir)/\.udevd.lock\" >> $@ # config files automatically generated diff --git a/udevd.c b/udevd.c index f8b8c27ee4..24cf9c9a7c 100644 --- a/udevd.c +++ b/udevd.c @@ -325,7 +325,6 @@ static void sig_handler(int signum) case SIGINT: case SIGTERM: unlink(UDEVD_LOCK); - unlink(UDEVD_SOCK); exit(20 + signum); break; default: @@ -378,9 +377,9 @@ int main(int argc, char *argv[]) memset(&saddr, 0x00, sizeof(saddr)); saddr.sun_family = AF_LOCAL; - strcpy(saddr.sun_path, UDEVD_SOCK); + /* use abstract namespace for socket path */ + strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); - unlink(UDEVD_SOCK); ssock = socket(AF_LOCAL, SOCK_STREAM, 0); if (ssock == -1) { dbg("error getting socket"); @@ -426,6 +425,5 @@ int main(int argc, char *argv[]) } exit: close(ssock); - unlink(UDEVD_SOCK); exit(1); } diff --git a/udevd.h b/udevd.h index 6dbee3a295..8efe1d569c 100644 --- a/udevd.h +++ b/udevd.h @@ -27,6 +27,7 @@ #define UDEV_MAGIC "udevd_" UDEV_VERSION #define EVENT_TIMEOUT_SEC 5 #define UDEVSEND_CONNECT_RETRY 20 /* x 100 millisec */ +#define UDEVD_SOCK_PATH "udevd" struct hotplug_msg { char magic[20]; diff --git a/udevsend.c b/udevsend.c index 9dc2b2e841..223647785d 100644 --- a/udevsend.c +++ b/udevsend.c @@ -161,7 +161,8 @@ int main(int argc, char* argv[]) memset(&saddr, 0x00, sizeof(saddr)); saddr.sun_family = AF_LOCAL; - strcpy(saddr.sun_path, UDEVD_SOCK); + /* use abstract namespace for socket path */ + strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); /* try to connect, if it fails start daemon */ retval = connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)); From 1dadabd79b28a4cd72382abf746e9cf4c0589617 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 6 Feb 2004 00:11:24 -0800 Subject: [PATCH 0499/4284] [PATCH] udevd - fix socket path length It seems that the guys are no longer differ about the right size of the socket address :) The kernel simply takes all bytes until the specified length as the name, so the real length should be enough. --- udevd.c | 4 +++- udevsend.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/udevd.c b/udevd.c index 24cf9c9a7c..10d67f2c35 100644 --- a/udevd.c +++ b/udevd.c @@ -360,6 +360,7 @@ int main(int argc, char *argv[]) int csock; struct sockaddr_un saddr; struct sockaddr_un caddr; + socklen_t addrlen; socklen_t clen; pthread_t cli_tid; pthread_t mgr_msg_tid; @@ -379,6 +380,7 @@ int main(int argc, char *argv[]) saddr.sun_family = AF_LOCAL; /* use abstract namespace for socket path */ strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; ssock = socket(AF_LOCAL, SOCK_STREAM, 0); if (ssock == -1) { @@ -386,7 +388,7 @@ int main(int argc, char *argv[]) exit(1); } - retval = bind(ssock, &saddr, sizeof(saddr)); + retval = bind(ssock, &saddr, addrlen); if (retval < 0) { dbg("bind failed\n"); goto exit; diff --git a/udevsend.c b/udevsend.c index 223647785d..246a097f26 100644 --- a/udevsend.c +++ b/udevsend.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -124,6 +125,7 @@ int main(int argc, char* argv[]) struct timespec tspec; int sock; struct sockaddr_un saddr; + socklen_t addrlen; #ifdef DEBUG init_logging("udevsend"); @@ -163,9 +165,10 @@ int main(int argc, char* argv[]) saddr.sun_family = AF_LOCAL; /* use abstract namespace for socket path */ strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; /* try to connect, if it fails start daemon */ - retval = connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)); + retval = connect(sock, (struct sockaddr *) &saddr, addrlen); if (retval != -1) { goto send; } else { From aca29aa51f0c8dfb1e6b8d60471d4034b65effb5 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Fri, 6 Feb 2004 00:14:51 -0800 Subject: [PATCH 0500/4284] [PATCH] update extras/multipath incremental to udev-016/extras/multipath, * don't rely on the linux symlink in the udev/klibc dir since udev build doesn't use it anymore. This corrects build breakage * remove make_dm_node fn & call. Rely on udev for this. The first patch is to be applied. The second is conditioned by udev dealing correctly with devmap names. For this I can suggest a CALLOUT rule like this : KERNEL=3D"dm-[0-9]*", PROGRAM=3D"/tmp/name_devmap %M %m", NAME=3D"%k", SY= MLINK=3D"%c" With name_devmap like : #!/bin/sh /usr/sbin/dmsetup ls|/bin/grep "$1, $2"|/usr/bin/awk '{print $1}' --- extras/multipath/ChangeLog | 4 ++++ extras/multipath/Makefile | 1 + extras/multipath/main.c | 41 -------------------------------------- 3 files changed, 5 insertions(+), 41 deletions(-) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index bb2f6baf89..c3361ff8e8 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,3 +1,7 @@ +2004-02-04 multipath-016 + * remove make_dm_node fn & call. Rely on udev for this. + * don't rely on the linux symlink in the udev/klibc dir since + udev build doesn't use it anymore. This corrects build breakage 2004-01-19 multipath-013 * update the DM target synthax to the 2.6.0-udm5 style 2003-12-29 multipath-012 diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index 0aac146a87..caf24bbd90 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -13,6 +13,7 @@ sysfsdir = $(udevdir)/libsysfs CC = gcc GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} +KERNEL_DIR = /lib/modules/${shell uname -r}/build CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. diff --git a/extras/multipath/main.c b/extras/multipath/main.c index e18e049128..d4dd89a305 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -558,46 +558,6 @@ coalesce_paths(struct env * conf, struct multipath * mp, return nmp; } -static int -make_dm_node(char * str) -{ - int r = 0; - char buff[FILE_NAME_SIZE]; - struct dm_names * names; - unsigned next = 0; - struct dm_task *dmt; - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) - return 0; - - if (!dm_task_run(dmt)) - goto out; - - if (!(names = dm_task_get_names(dmt))) - goto out; - - if (!names->dev) { - r = 1; - goto out; - } - - do { - if (0 == strcmp(names->name, str)) - break; - next = names->next; - names = (void *) names + next; - } while (next); - - sprintf(buff, "/dev/mapper/%s", str); - unlink(buff); - mknod(buff, 0600 | S_IFBLK, names->dev); - - out: - dm_task_destroy(dmt); - return r; - -} - static int dm_simplecmd(int task, const char *name) { int r = 0; @@ -711,7 +671,6 @@ setup_map(struct env * conf, struct path * all_paths, if (op == DM_DEVICE_RELOAD) dm_simplecmd(DM_DEVICE_RESUME, mp[index].wwid); - make_dm_node(mp[index].wwid); return 1; } From d2cf99df7df132d8d90c4f7b438374618793c15a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 6 Feb 2004 01:04:28 -0800 Subject: [PATCH 0501/4284] [PATCH] udevd - kill the lockfile --- Makefile | 1 - udev-remove.c | 1 - udevd.c | 29 ----------------------------- 3 files changed, 31 deletions(-) diff --git a/Makefile b/Makefile index 35575806db..d3493f6940 100644 --- a/Makefile +++ b/Makefile @@ -241,7 +241,6 @@ udev_version.h: @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ - @echo \#define UDEVD_LOCK \"$(udevdir)/\.udevd.lock\" >> $@ # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf diff --git a/udev-remove.c b/udev-remove.c index 9db63ed93e..c21938fae7 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -34,7 +34,6 @@ #include "logging.h" #include "namedev.h" #include "udevdb.h" -#include "libsysfs/libsysfs.h" static int delete_path(char *path) { diff --git a/udevd.c b/udevd.c index 10d67f2c35..3ce8c8b07d 100644 --- a/udevd.c +++ b/udevd.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -30,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -324,7 +322,6 @@ static void sig_handler(int signum) switch (signum) { case SIGINT: case SIGTERM: - unlink(UDEVD_LOCK); exit(20 + signum); break; default: @@ -332,28 +329,6 @@ static void sig_handler(int signum) } } -static int one_and_only(void) -{ - char string[50]; - int lock_file; - - lock_file = open(UDEVD_LOCK, O_RDWR | O_CREAT, 0x640); - if (lock_file < 0) - return -1; - - /* see if we can lock */ - if (lockf(lock_file, F_TLOCK, 0) < 0) { - dbg("file is already locked, exit"); - close(lock_file); - return -1; - } - - snprintf(string, sizeof(string), "%d\n", getpid()); - write(lock_file, string, strlen(string)); - - return 0; -} - int main(int argc, char *argv[]) { int ssock; @@ -369,10 +344,6 @@ int main(int argc, char *argv[]) init_logging("udevd"); - /* only let one version of the daemon run at any one time */ - if (one_and_only() != 0) - exit(0); - signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); From 2f6cbd19113167746dc4fb6b4f3f5fd64a1c211f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 6 Feb 2004 22:21:15 -0800 Subject: [PATCH 0502/4284] [PATCH] convert udevsend/udevd to DGRAM and single-threaded On Fri, Feb 06, 2004 at 01:08:24AM -0500, Chris Friesen wrote: > > Kay, you said "unless we can get rid of _all_ the threads or at least > getting faster, I don't want to change it." > > Well how about we get rid of all the threads, *and* we get faster? Yes, we are twice as fast now on my box :) > This patch applies to current bk trees, and does the following: > > 1) Switch to DGRAM sockets rather than STREAM. This simplifies things > as mentioned in the previous message. > > 2) Invalid sequence numbers are mapped to -1 rather than zero, since > zero is a valid sequence number (I think). Also, this allows for real > speed tests using scripts starting at a zero sequence number, since that > is what the initial expected sequence number is. > > 3) Get rid of all threading. This is the biggie. Some highlights: > a) timeout using setitimer() and SIGALRM > b) async child death notification via SIGCHLD > c) these two signal handlers do nothing but raise volatile flags, > all the > work is done in the main loop > d) locking no longer required I cleaned up the rest of the comments, the whitespace and a few names to match the whole thing. Please recheck it. Test script is switched to work on subsystem 'test' to let udev ignore it. --- Makefile | 2 +- test/udevd_test.sh | 65 +++++----- udevd.c | 301 ++++++++++++++++++--------------------------- udevsend.c | 82 ++++++------ 4 files changed, 192 insertions(+), 258 deletions(-) diff --git a/Makefile b/Makefile index d3493f6940..97c6ca63bd 100644 --- a/Makefile +++ b/Makefile @@ -262,7 +262,7 @@ $(HELPER): $(HEADERS) udevinfo.o $(OBJS) $(STRIPCMD) $@ $(DAEMON): udevd.h $(GEN_HEADERS) udevd.o - $(LD) $(LDFLAGS) -lpthread -o $@ $(CRT0) udevd.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(SENDER): udevd.h $(GEN_HEADERS) udevsend.o diff --git a/test/udevd_test.sh b/test/udevd_test.sh index 506e886948..981a39d01d 100644 --- a/test/udevd_test.sh +++ b/test/udevd_test.sh @@ -3,81 +3,86 @@ # add/rem/add/rem/add sequence of sda/sdb/sdc # a few days longer and the socket of my usb-flash-reader is gone :) +export SEQNUM=0 +export ACTION=add +export DEVPATH=/test/init +./udevsend test + export SEQNUM=3 export ACTION=add -export DEVPATH=/block/sdc -./udevsend block +export DEVPATH=/test/sdc +./udevsend test export SEQNUM=1 export ACTION=add -export DEVPATH=/block/sda -./udevsend block +export DEVPATH=/test/sda +./udevsend test export SEQNUM=2 export ACTION=add -export DEVPATH=/block/sdb -./udevsend block +export DEVPATH=/test/sdb +./udevsend test export SEQNUM=4 export ACTION=remove -export DEVPATH=/block/sdc -./udevsend block +export DEVPATH=/test/sdc +./udevsend test export SEQNUM=5 export ACTION=remove -export DEVPATH=/block/sdb -./udevsend block +export DEVPATH=/test/sdb +./udevsend test export SEQNUM=8 export ACTION=add -export DEVPATH=/block/sdb -./udevsend block +export DEVPATH=/test/sdb +./udevsend test export SEQNUM=6 export ACTION=remove -export DEVPATH=/block/sda -./udevsend block +export DEVPATH=/test/sda +./udevsend test export SEQNUM=7 export ACTION=add -export DEVPATH=/block/sda -#./udevsend block +export DEVPATH=/test/sda +#./udevsend test sleep 2 export SEQNUM=9 export ACTION=add -export DEVPATH=/block/sdc -./udevsend block +export DEVPATH=/test/sdc +./udevsend test export SEQNUM=11 export ACTION=remove -export DEVPATH=/block/sdb -./udevsend block +export DEVPATH=/test/sdb +./udevsend test export SEQNUM=10 export ACTION=remove -export DEVPATH=/block/sdc -./udevsend block +export DEVPATH=/test/sdc +./udevsend test export SEQNUM=13 export ACTION=add -export DEVPATH=/block/sda -./udevsend block +export DEVPATH=/test/sda +./udevsend test export SEQNUM=14 export ACTION=add -export DEVPATH=/block/sdb -./udevsend block +export DEVPATH=/test/sdb +./udevsend test export SEQNUM=15 export ACTION=add -export DEVPATH=/block/sdc -./udevsend block +export DEVPATH=/test/sdc +./udevsend test sleep 2 export SEQNUM=12 export ACTION=remove -export DEVPATH=/block/sda -./udevsend block +export DEVPATH=/test/sda +./udevsend test diff --git a/udevd.c b/udevd.c index 3ce8c8b07d..8ba833186e 100644 --- a/udevd.c +++ b/udevd.c @@ -2,6 +2,7 @@ * udevd.c - hotplug event serializer * * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2004 Chris Friesen * * * This program is free software; you can redistribute it and/or modify it @@ -19,7 +20,6 @@ * */ -#include #include #include #include @@ -32,6 +32,7 @@ #include #include #include +#include #include "list.h" #include "udev.h" @@ -39,22 +40,17 @@ #include "udevd.h" #include "logging.h" - unsigned char logname[42]; -static pthread_mutex_t msg_lock; -static pthread_mutex_t msg_active_lock; -static pthread_cond_t msg_active; -static pthread_mutex_t exec_lock; -static pthread_mutex_t exec_active_lock; -static pthread_cond_t exec_active; -static pthread_mutex_t running_lock; -static pthread_attr_t thr_attr; static int expected_seqnum = 0; +volatile static int children_waiting; +volatile static int msg_q_timeout; LIST_HEAD(msg_list); LIST_HEAD(exec_list); LIST_HEAD(running_list); +static void exec_queue_manager(void); +static void msg_queue_manager(void); static void msg_dump_queue(void) { @@ -75,17 +71,16 @@ static struct hotplug_msg *msg_create(void) struct hotplug_msg *new_msg; new_msg = malloc(sizeof(struct hotplug_msg)); - if (new_msg == NULL) { + if (new_msg == NULL) dbg("error malloc"); - return NULL; - } return new_msg; } -static void msg_delete(struct hotplug_msg *msg) +static void run_queue_delete(struct hotplug_msg *msg) { - if (msg != NULL) - free(msg); + list_del(&msg->list); + free(msg); + exec_queue_manager(); } /* orders the message in the queue by sequence number */ @@ -103,21 +98,16 @@ static void msg_queue_insert(struct hotplug_msg *msg) /* store timestamp of queuing */ msg->queue_time = time(NULL); - /* signal queue activity to manager */ - pthread_mutex_lock(&msg_active_lock); - pthread_cond_signal(&msg_active); - pthread_mutex_unlock(&msg_active_lock); + /* run msg queue manager */ + msg_queue_manager(); return ; } /* forks event and removes event from run queue when finished */ -static void *run_threads(void * parm) +static void udev_run(struct hotplug_msg *msg) { pid_t pid; - struct hotplug_msg *msg; - - msg = parm; setenv("ACTION", msg->action, 1); setenv("DEVPATH", msg->devpath, 1); @@ -131,190 +121,124 @@ static void *run_threads(void * parm) break; case -1: dbg("fork of child failed"); - goto exit; + run_queue_delete(msg); + break; default: - /* wait for exit of child */ - dbg("==> exec seq %d [%d] working at '%s'", - msg->seqnum, pid, msg->devpath); - wait(NULL); - dbg("<== exec seq %d came back", msg->seqnum); + /* get SIGCHLD in main loop */ + dbg("==> exec seq %d [%d] working at '%s'", msg->seqnum, pid, msg->devpath); + msg->pid = pid; } - -exit: - /* remove event from run list */ - pthread_mutex_lock(&running_lock); - list_del_init(&msg->list); - pthread_mutex_unlock(&running_lock); - - msg_delete(msg); - - /* signal queue activity to exec manager */ - pthread_mutex_lock(&exec_active_lock); - pthread_cond_signal(&exec_active); - pthread_mutex_unlock(&exec_active_lock); - - pthread_exit(0); } /* returns already running task with devpath */ static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) { struct hotplug_msg *loop_msg; - struct hotplug_msg *tmp_msg; - - list_for_each_entry_safe(loop_msg, tmp_msg, &running_list, list) + list_for_each_entry(loop_msg, &running_list, list) if (strncmp(loop_msg->devpath, msg->devpath, sizeof(loop_msg->devpath)) == 0) return loop_msg; return NULL; } -/* queue management executes the events and delays events for the same devpath */ -static void *exec_queue_manager(void * parm) +/* exec queue management routine executes the events and delays events for the same devpath */ +static void exec_queue_manager() { struct hotplug_msg *loop_msg; struct hotplug_msg *tmp_msg; struct hotplug_msg *msg; - pthread_t run_tid; - while (1) { - pthread_mutex_lock(&exec_lock); - list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, list) { - msg = running_with_devpath(loop_msg); - if (msg == NULL) { - /* move event to run list */ - pthread_mutex_lock(&running_lock); - list_move_tail(&loop_msg->list, &running_list); - pthread_mutex_unlock(&running_lock); - - pthread_create(&run_tid, &thr_attr, run_threads, (void *) loop_msg); - - dbg("moved seq %d to running list", loop_msg->seqnum); - } else { - dbg("delay seq %d, cause seq %d already working on '%s'", - loop_msg->seqnum, msg->seqnum, msg->devpath); - } + list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, list) { + msg = running_with_devpath(loop_msg); + if (!msg) { + /* move event to run list */ + list_move_tail(&loop_msg->list, &running_list); + udev_run(loop_msg); + dbg("moved seq %d to running list", loop_msg->seqnum); + } else { + dbg("delay seq %d, cause seq %d already working on '%s'", + loop_msg->seqnum, msg->seqnum, msg->devpath); } - pthread_mutex_unlock(&exec_lock); - - /* wait for activation, new events or childs coming back */ - pthread_mutex_lock(&exec_active_lock); - pthread_cond_wait(&exec_active, &exec_active_lock); - pthread_mutex_unlock(&exec_active_lock); } } -static void exec_queue_activate(void) +static void msg_move_exec(struct hotplug_msg *msg) { - pthread_mutex_lock(&exec_active_lock); - pthread_cond_signal(&exec_active); - pthread_mutex_unlock(&exec_active_lock); + list_move_tail(&msg->list, &exec_list); + exec_queue_manager(); + expected_seqnum = msg->seqnum+1; + dbg("moved seq %d to exec, next expected is %d", + msg->seqnum, expected_seqnum); } -/* move message from incoming to exec queue */ -static void msg_move_exec(struct list_head *head) -{ - list_move_tail(head, &exec_list); - exec_queue_activate(); -} - -/* queue management thread handles the timeouts and dispatches the events */ -static void *msg_queue_manager(void * parm) +/* msg queue management routine handles the timeouts and dispatches the events */ +static void msg_queue_manager() { struct hotplug_msg *loop_msg; struct hotplug_msg *tmp_msg; time_t msg_age = 0; - struct timespec tv; - while (1) { - dbg("msg queue manager, next expected is %d", expected_seqnum); - pthread_mutex_lock(&msg_lock); - pthread_mutex_lock(&exec_lock); + dbg("msg queue manager, next expected is %d", expected_seqnum); recheck: - list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, list) { - /* move event with expected sequence to the exec list */ - if (loop_msg->seqnum == expected_seqnum) { - msg_move_exec(&loop_msg->list); - expected_seqnum++; - dbg("moved seq %d to exec, next expected is %d", - loop_msg->seqnum, expected_seqnum); - continue; - } - - /* move event with expired timeout to the exec list */ - msg_age = time(NULL) - loop_msg->queue_time; - if (msg_age > EVENT_TIMEOUT_SEC-1) { - msg_move_exec(&loop_msg->list); - expected_seqnum = loop_msg->seqnum+1; - dbg("moved seq %d to exec, reset next expected to %d", - loop_msg->seqnum, expected_seqnum); - goto recheck; - } else { - break; - } + list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, list) { + /* move event with expected sequence to the exec list */ + if (loop_msg->seqnum == expected_seqnum) { + msg_move_exec(loop_msg); + continue; } - msg_dump_queue(); - pthread_mutex_unlock(&exec_lock); - pthread_mutex_unlock(&msg_lock); - - /* wait until queue gets active or next message timeout expires */ - pthread_mutex_lock(&msg_active_lock); - - if (list_empty(&msg_list) == 0) { - tv.tv_sec = time(NULL) + EVENT_TIMEOUT_SEC - msg_age; - tv.tv_nsec = 0; - dbg("next event expires in %li seconds", - EVENT_TIMEOUT_SEC - msg_age); - pthread_cond_timedwait(&msg_active, &msg_active_lock, &tv); + /* move event with expired timeout to the exec list */ + msg_age = time(NULL) - loop_msg->queue_time; + if (msg_age > EVENT_TIMEOUT_SEC-1) { + msg_move_exec(loop_msg); + goto recheck; } else { - pthread_cond_wait(&msg_active, &msg_active_lock); + break; } - pthread_mutex_unlock(&msg_active_lock); + } + + msg_dump_queue(); + + if (list_empty(&msg_list) == 0) { + /* set timeout for remaining queued events */ + struct itimerval itv = {{0, 0}, {EVENT_TIMEOUT_SEC - msg_age, 0}}; + dbg("next event expires in %li seconds", + EVENT_TIMEOUT_SEC - msg_age); + setitimer(ITIMER_REAL, &itv, 0); } } -/* every connect creates a thread which gets the msg, queues it and exits */ -static void *client_threads(void * parm) +/* receive the msg, do some basic sanity checks, and queue it */ +static void handle_msg(int sock) { - int sock; struct hotplug_msg *msg; int retval; - sock = (int) parm; - msg = msg_create(); if (msg == NULL) { dbg("unable to store message"); - goto exit; + return; } retval = recv(sock, msg, sizeof(struct hotplug_msg), 0); if (retval < 0) { - dbg("unable to receive message"); - goto exit; + if (errno != EINTR) + dbg("unable to receive message"); + return; } - + if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { dbg("message magic '%s' doesn't match, ignore it", msg->magic); - msg_delete(msg); - goto exit; + free(msg); + return; } /* if no seqnum is given, we move straight to exec queue */ - if (msg->seqnum == 0) { - pthread_mutex_lock(&exec_lock); + if (msg->seqnum == -1) { list_add(&msg->list, &exec_list); - exec_queue_activate(); - pthread_mutex_unlock(&exec_lock); + exec_queue_manager(); } else { - pthread_mutex_lock(&msg_lock); msg_queue_insert(msg); - pthread_mutex_unlock(&msg_lock); } - -exit: - close(sock); - pthread_exit(0); } static void sig_handler(int signum) @@ -324,28 +248,48 @@ static void sig_handler(int signum) case SIGTERM: exit(20 + signum); break; + case SIGALRM: + msg_q_timeout = 1; + break; + case SIGCHLD: + children_waiting = 1; + break; default: dbg("unhandled signal"); } } +static void udev_done(int pid) +{ + /* find msg associated with pid and delete it */ + struct hotplug_msg *msg; + + list_for_each_entry(msg, &running_list, list) { + if (msg->pid == pid) { + dbg("<== exec seq %d came back", msg->seqnum); + run_queue_delete(msg); + return; + } + } +} + int main(int argc, char *argv[]) { int ssock; - int csock; struct sockaddr_un saddr; - struct sockaddr_un caddr; socklen_t addrlen; - socklen_t clen; - pthread_t cli_tid; - pthread_t mgr_msg_tid; - pthread_t mgr_exec_tid; int retval; init_logging("udevd"); signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); + signal(SIGALRM, sig_handler); + signal(SIGCHLD, sig_handler); + + /* we want these two to interrupt system calls */ + siginterrupt(SIGALRM, 1); + siginterrupt(SIGCHLD, 1); memset(&saddr, 0x00, sizeof(saddr)); saddr.sun_family = AF_LOCAL; @@ -353,48 +297,37 @@ int main(int argc, char *argv[]) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - ssock = socket(AF_LOCAL, SOCK_STREAM, 0); + ssock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (ssock == -1) { dbg("error getting socket"); exit(1); } + /* the bind takes care of ensuring only one copy running */ retval = bind(ssock, &saddr, addrlen); if (retval < 0) { dbg("bind failed\n"); goto exit; } - retval = listen(ssock, SOMAXCONN); - if (retval < 0) { - dbg("listen failed\n"); - goto exit; - } - - pthread_mutex_init(&msg_lock, NULL); - pthread_mutex_init(&msg_active_lock, NULL); - pthread_mutex_init(&exec_lock, NULL); - pthread_mutex_init(&exec_active_lock, NULL); - pthread_mutex_init(&running_lock, NULL); - - /* set default attributes for created threads */ - pthread_attr_init(&thr_attr); - pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&thr_attr, 16 * 1024); - - /* init queue management */ - pthread_create(&mgr_msg_tid, &thr_attr, msg_queue_manager, NULL); - pthread_create(&mgr_exec_tid, &thr_attr, exec_queue_manager, NULL); - - clen = sizeof(caddr); - /* main loop */ while (1) { - csock = accept(ssock, &caddr, &clen); - if (csock < 0) { - dbg("client accept failed\n"); - continue; + handle_msg(ssock); + + while(msg_q_timeout) { + msg_q_timeout = 0; + msg_queue_manager(); + } + + while(children_waiting) { + children_waiting = 0; + /* reap all dead children */ + while(1) { + int pid = waitpid(-1, 0, WNOHANG); + if ((pid == -1) || (pid == 0)) + break; + udev_done(pid); + } } - pthread_create(&cli_tid, &thr_attr, client_threads, (void *) csock); } exit: close(ssock); diff --git a/udevsend.c b/udevsend.c index 246a097f26..f6de88565f 100644 --- a/udevsend.c +++ b/udevsend.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" @@ -119,13 +120,14 @@ int main(int argc, char* argv[]) char *subsystem; char *seqnum; int seq; - int retval = -EINVAL; + int retval = 1; int size; int loop; struct timespec tspec; int sock; struct sockaddr_un saddr; socklen_t addrlen; + int started_daemon = 0; #ifdef DEBUG init_logging("udevsend"); @@ -151,11 +153,11 @@ int main(int argc, char* argv[]) seqnum = get_seqnum(); if (seqnum == NULL) - seq = 0; + seq = -1; else seq = atoi(seqnum); - sock = socket(AF_LOCAL, SOCK_STREAM, 0); + sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { dbg("error getting socket"); goto exit; @@ -167,48 +169,42 @@ int main(int argc, char* argv[]) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - /* try to connect, if it fails start daemon */ - retval = connect(sock, (struct sockaddr *) &saddr, addrlen); - if (retval != -1) { - goto send; - } else { - dbg("connect failed, try starting daemon..."); - retval = start_daemon(); - if (retval == 0) { - dbg("daemon started"); - } else { - dbg("error starting daemon"); - goto exit; - } - } - - /* try to connect while daemon to starts */ - tspec.tv_sec = 0; - tspec.tv_nsec = 100000000; /* 100 millisec */ + size = build_hotplugmsg(&message, action, devpath, subsystem, seq); + + /* If we can't send, try to start daemon and resend message */ loop = UDEVSEND_CONNECT_RETRY; while (loop--) { - retval = connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)); - if (retval != -1) - goto send; - else - dbg("retry to connect %d", - UDEVSEND_CONNECT_RETRY - loop); - nanosleep(&tspec, NULL); + retval = sendto(sock, &message, size, 0, (struct sockaddr*)&saddr, addrlen); + if (retval != -1) { + retval = 0; + goto close_and_exit; + } + + if (errno != ECONNREFUSED) { + dbg("error sending message"); + goto close_and_exit; + } + + if (!started_daemon) { + dbg("connect failed, try starting daemon..."); + retval = start_daemon(); + if (retval) { + dbg("error starting daemon"); + goto exit; + } + + dbg("daemon started"); + started_daemon = 1; + } else { + dbg("retry to connect %d", UDEVSEND_CONNECT_RETRY - loop); + tspec.tv_sec = 0; + tspec.tv_nsec = 100000000; /* 100 millisec */ + nanosleep(&tspec, NULL); + } } - dbg("error connecting to daemon, start daemon failed"); - goto exit; - -send: - size = build_hotplugmsg(&message, action, devpath, subsystem, seq); - retval = send(sock, &message, size, 0); - if (retval == -1) { - dbg("error sending message"); - close (sock); - goto exit; - } - close (sock); - return 0; - + +close_and_exit: + close(sock); exit: - return 1; + return retval; } From 01504bd96b6e7cb6ad1350d6d0a0c6a1300409b8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 11 Feb 2004 18:27:55 -0800 Subject: [PATCH 0503/4284] [PATCH] sync with latest version of klibc (0.107) --- klibc/klibc/CAVEATS | 10 + klibc/klibc/MCONFIG | 38 +--- klibc/klibc/Makefile | 5 +- klibc/klibc/README | 17 +- klibc/klibc/__put_env.c | 60 ++++++ .../klibc/arch/x86_64/include/klibc/archsys.h | 85 +++++++- klibc/klibc/include/elf.h | 4 +- klibc/klibc/include/signal.h | 2 +- klibc/klibc/include/stdint.h | 3 + klibc/klibc/include/sys/elf32.h | 115 +++++++++++ klibc/klibc/include/sys/elf64.h | 115 +++++++++++ klibc/klibc/include/sys/elfcommon.h | 186 ++++++++++++++++++ klibc/klibc/include/sys/sysmacros.h | 31 +++ klibc/klibc/include/sys/time.h | 1 + klibc/klibc/include/sys/types.h | 24 ++- klibc/klibc/include/sys/wait.h | 9 + klibc/klibc/include/unistd.h | 6 + klibc/klibc/putenv.c | 40 ++++ klibc/klibc/setenv.c | 85 +------- klibc/klibc/{signal.c => sysv_signal.c} | 4 +- klibc/klibc/tests/{getenvtest.c => environ.c} | 6 +- klibc/klibc/tests/nfs_no_rpc.c | 2 +- klibc/klibc/tests/setenvtest.c | 38 ++++ 23 files changed, 732 insertions(+), 154 deletions(-) create mode 100644 klibc/klibc/__put_env.c create mode 100644 klibc/klibc/include/sys/elf32.h create mode 100644 klibc/klibc/include/sys/elf64.h create mode 100644 klibc/klibc/include/sys/elfcommon.h create mode 100644 klibc/klibc/include/sys/sysmacros.h create mode 100644 klibc/klibc/putenv.c rename klibc/klibc/{signal.c => sysv_signal.c} (60%) rename klibc/klibc/tests/{getenvtest.c => environ.c} (72%) create mode 100644 klibc/klibc/tests/setenvtest.c diff --git a/klibc/klibc/CAVEATS b/klibc/klibc/CAVEATS index c7131ac367..5bc11e4179 100644 --- a/klibc/klibc/CAVEATS +++ b/klibc/klibc/CAVEATS @@ -49,3 +49,13 @@ theading: klibc is not thread-safe. Consequently, clone() or any of the pthreads functions are not included. + +bsd_signal vs sysv_signal: +-------------------------- + +There is no signal() call, because you never know if you want +Linux/SysV semantics (SA_RESETHAND) or GNU/BSD semantics (SA_RESTART). +The best, in *any* circumstances, is to never use signal() and instead +use sigaction(), but in order to simplify porting you can use either +sysv_signal() or bsd_signal(), depending on what you actually want. + diff --git a/klibc/klibc/MCONFIG b/klibc/klibc/MCONFIG index a46a98a9dd..253a9461b7 100644 --- a/klibc/klibc/MCONFIG +++ b/klibc/klibc/MCONFIG @@ -5,45 +5,9 @@ SRCROOT = .. include ../MCONFIG +include ../MRULES WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline CFLAGS = -Wp,-MD,$(dir $*).$(notdir $*).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) SOFLAGS = -fPIC - -.SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss - -.c.o: - $(CC) $(CFLAGS) -c -o $@ $< - -.c.i: - $(CC) $(CFLAGS) -E -o $@ $< - -.c.s: - $(CC) $(CFLAGS) -S -o $@ $< - -.S.o: - $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< - -.S.s: - $(CC) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $< - -.S.lo: - $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -c -o $@ $< - -.S.ls: - $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -E -o $@ $< - -.s.o: - $(CC) $(CFLAGS) -x assembler -c -o $@ $< - -.ls.lo: - $(CC) $(CFLAGS) $(SOFLAGS) -x assembler -c -o $@ $< - -.c.lo: - $(CC) $(CFLAGS) $(SOFLAGS) -c -o $@ $< - -.c.ls: - $(CC) $(CFLAGS) $(SOFLAGS) -S -o $@ $< - - diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index def201524a..0d5b197f0d 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -22,7 +22,7 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ fopen.o fread.o fread2.o fgetc.o fgets.o \ fwrite.o fwrite2.o fputc.o fputs.o puts.o \ sleep.o usleep.o raise.o abort.o assert.o alarm.o pause.o \ - __signal.o signal.o bsd_signal.o siglist.o siglongjmp.o \ + __signal.o sysv_signal.o bsd_signal.o siglist.o siglongjmp.o \ sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o getpagesize.o \ memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ @@ -33,7 +33,8 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ strsep.o strtok.o \ gethostname.o getdomainname.o getcwd.o \ seteuid.o setegid.o setresuid.o setresgid.o \ - getenv.o setenv.o unsetenv.o getopt.o readdir.o \ + getenv.o setenv.o putenv.o __put_env.o unsetenv.o \ + getopt.o readdir.o \ syslog.o closelog.o pty.o isatty.o reboot.o \ time.o utime.o fdatasync.o llseek.o select.o nice.o getpriority.o \ qsort.o lrand48.o srand48.o seed48.o \ diff --git a/klibc/klibc/README b/klibc/klibc/README index ce0ad7ba6a..4495908a22 100644 --- a/klibc/klibc/README +++ b/klibc/klibc/README @@ -9,12 +9,12 @@ this: a) In the source root directory (the directory above the one in which this file is found) create a symlink called "linux" pointing to a - reasonably recent Linux kernel tree (2.4 or 2.5 should be OK.) + reasonably recent Linux kernel tree (2.4 or 2.6 should be OK.) This tree must have the include/asm symlink set up for the architecture you're compiling for, and include/linux/autoconf.h must exist. The easiest way to make sure of all of these is to do a "make config" or any of its variants on the kernel tree is - question, followed by a "make dep". + question, followed by a "make dep" (2.4) or "make prepare" (2.6). b) If you're cross-compiling, change ARCH in the main MCONFIG file to the appropriate architecture, and set CROSS to your toolchain @@ -34,16 +34,17 @@ b) If you're cross-compiling, change ARCH in the main MCONFIG file to The following is the last known status of various architectures: - Known to work: alpha arm ia64 i386 s390 s390x sparc + Known to work: alpha arm ia64 i386 ppc s390 s390x sparc sparc64 x86_64* Works static, not shared: mips* arm-thumb sh* - Might work: ppc ppc64 + Might work: ppc64 Need porting work: cris m68k mips64 parisc x86_64: requires a kernel header patch (to be created) mips, sh: linker problem; might work with fixed linker - Shared library support for sparc/sparc64 requires binutils 2.13.90.0.4. + Shared library support requires binutils 2.13.90.0.4 or later on + many architectures. Note that even the "known to work" ones likely have bugs. Please report them if you run into them. @@ -52,6 +53,10 @@ c) Type "make" and pray... d) Try the test programs in the tests/ directory. They should run... -Contact me at for more info. +Contact the klibc mailing list: + + http://www.zytor.com/mailman/listinfo/klibc + +... for more info. -hpa diff --git a/klibc/klibc/__put_env.c b/klibc/klibc/__put_env.c new file mode 100644 index 0000000000..7e55f2c43b --- /dev/null +++ b/klibc/klibc/__put_env.c @@ -0,0 +1,60 @@ +/* + * __put_env.c - common code for putenv() and setenv() + */ + +#include +#include +#include +#include + +/* Initialized to zero, meaning "not malloc'd" */ +static size_t __environ_size; + +/* str should be a duplicated version of the input string; + len is the length of the key including the = sign */ +int __put_env(char *str, size_t len, int overwrite) +{ + char **p, *q; + char **newenv; + size_t n; + + n = 1; /* Include space for final NULL */ + for ( p = environ ; (q = *p) ; p++ ) { + n++; + if ( !strncmp(q,str,len) ) { + if ( !overwrite ) + free(str); + else + *p = str; /* Possible memory leak... */ + return 0; + } + } + + /* Need to extend the environment */ + if ( n < __environ_size ) { + p[1] = NULL; + *p = str; + return 0; + } else { + if ( __environ_size ) { + newenv = realloc(environ, (__environ_size << 1)*sizeof(char *)); + if ( !newenv ) + return -1; + + __environ_size <<= 1; + } else { + /* Make a reasonable guess how much more space we need */ + size_t newsize = n+32; + newenv = malloc(newsize*sizeof(char *)); + if ( !newenv ) + return -1; + + memcpy(newenv, environ, n*sizeof(char *)); + __environ_size = newsize; + } + newenv[n-1] = str; /* Old NULL position */ + newenv[n] = NULL; + environ = newenv; + } + return 0; +} diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsys.h b/klibc/klibc/arch/x86_64/include/klibc/archsys.h index 3bd8b0a5d9..2ec72cd397 100644 --- a/klibc/klibc/arch/x86_64/include/klibc/archsys.h +++ b/klibc/klibc/arch/x86_64/include/klibc/archsys.h @@ -7,9 +7,88 @@ #ifndef _KLIBC_ARCHSYS_H #define _KLIBC_ARCHSYS_H -/* x86-64 seems to miss _syscall6() from its headers */ +/* The x86-64 syscall headers are needlessly inefficient */ -#ifndef _syscall6 +#undef _syscall0 +#undef _syscall1 +#undef _syscall2 +#undef _syscall3 +#undef _syscall4 +#undef _syscall5 +#undef _syscall6 + +#define _syscall0(type,name) \ +type name (void) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name (type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name (type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name (type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ +{ \ +long __res; \ +register type4 __r10 asm("%r10") = arg4; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3),"r" (__r10) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +register type4 __r10 asm("%r10") = arg4; \ +register type5 __r8 asm("%r8") = arg5; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3),"r" (__r10),"r" (__r8) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} #define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ type5,arg5,type6,arg6) \ @@ -27,6 +106,4 @@ __asm__ volatile (__syscall \ __syscall_return(type,__res); \ } -#endif /* _syscall6 missing */ - #endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/include/elf.h b/klibc/klibc/include/elf.h index bd0f3e7f9b..52f47d042e 100644 --- a/klibc/klibc/include/elf.h +++ b/klibc/klibc/include/elf.h @@ -5,8 +5,8 @@ #ifndef _ELF_H #define _ELF_H -#include -#include +#include +#include #endif /* _ELF_H */ diff --git a/klibc/klibc/include/signal.h b/klibc/klibc/include/signal.h index f9eebb2a29..513b4e5a04 100644 --- a/klibc/klibc/include/signal.h +++ b/klibc/klibc/include/signal.h @@ -64,7 +64,7 @@ static __inline__ int sigismember(sigset_t *__set, int __signum) } __extern __sighandler_t __signal(int, __sighandler_t, int); -__extern __sighandler_t signal(int, __sighandler_t); +__extern __sighandler_t sysv_signal(int, __sighandler_t); __extern __sighandler_t bsd_signal(int, __sighandler_t); __extern int sigaction(int, const struct sigaction *, struct sigaction *); __extern int sigprocmask(int, const sigset_t *, sigset_t *); diff --git a/klibc/klibc/include/stdint.h b/klibc/klibc/include/stdint.h index 2022a30fd7..47fec18594 100644 --- a/klibc/klibc/include/stdint.h +++ b/klibc/klibc/include/stdint.h @@ -110,4 +110,7 @@ typedef uint64_t uintmax_t; #endif +/* Keep the kernel from trying to define these types... */ +#define __BIT_TYPES_DEFINED__ + #endif /* _STDINT_H */ diff --git a/klibc/klibc/include/sys/elf32.h b/klibc/klibc/include/sys/elf32.h new file mode 100644 index 0000000000..652de5bc5f --- /dev/null +++ b/klibc/klibc/include/sys/elf32.h @@ -0,0 +1,115 @@ +/* + * sys/elf32.h + */ + +#ifndef _SYS_ELF32_H +#define _SYS_ELF32_H + +#include + +/* ELF standard typedefs (yet more proof that was way overdue) */ +typedef uint16_t Elf32_Half; +typedef int16_t Elf32_SHalf; +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; + +typedef uint32_t Elf32_Off; +typedef uint32_t Elf32_Addr; +typedef uint16_t Elf32_Section; + +/* Dynamic header */ + +typedef struct elf32_dyn { + Elf32_Sword d_tag; + union{ + Elf32_Sword d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +/* Relocations */ + +#define ELF32_R_SYM(x) ((x) >> 8) +#define ELF32_R_TYPE(x) ((x) & 0xff) + +typedef struct elf32_rel { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct elf32_rela { + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +/* Symbol */ + +typedef struct elf32_sym { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +/* Main file header */ + +typedef struct elf32_hdr { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +/* Program header */ + +typedef struct elf32_phdr { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + + +/* Section header */ + +typedef struct elf32_shdr { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +/* Note header */ +typedef struct elf32_note { + Elf32_Word n_namesz; /* Name size */ + Elf32_Word n_descsz; /* Content size */ + Elf32_Word n_type; /* Content type */ +} Elf32_Nhdr; + +#endif /* _SYS_ELF32_H */ + diff --git a/klibc/klibc/include/sys/elf64.h b/klibc/klibc/include/sys/elf64.h new file mode 100644 index 0000000000..750ddac4d9 --- /dev/null +++ b/klibc/klibc/include/sys/elf64.h @@ -0,0 +1,115 @@ +/* + * sys/elf64.h + */ + +#ifndef _SYS_ELF64_H +#define _SYS_ELF64_H + +#include + +/* ELF standard typedefs (yet more proof that was way overdue) */ +typedef uint16_t Elf64_Half; +typedef int16_t Elf64_SHalf; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +typedef uint64_t Elf64_Off; +typedef uint64_t Elf64_Addr; +typedef uint16_t Elf64_Section; + +/* Dynamic header */ + +typedef struct elf64_dyn { + Elf64_Sxword d_tag; + union{ + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +} Elf64_Dyn; + +/* Relocations */ + +#define ELF64_R_SYM(x) ((x) >> 32) +#define ELF64_R_TYPE(x) ((x) & 0xffffffff) + +typedef struct elf64_rel { + Elf64_Addr r_offset; + Elf64_Xword r_info; +} Elf64_Rel; + +typedef struct elf64_rela { + Elf64_Addr r_offset; + Elf64_Xword r_info; + Elf64_Sxword r_addend; +} Elf64_Rela; + +/* Symbol */ + +typedef struct elf64_sym { + Elf64_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf64_Half st_shndx; + Elf64_Addr st_value; + Elf64_Xword st_size; +} Elf64_Sym; + +/* Main file header */ + +typedef struct elf64_hdr { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; + +/* Program header */ + +typedef struct elf64_phdr { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +} Elf64_Phdr; + + +/* Section header */ + +typedef struct elf64_shdr { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +} Elf64_Shdr; + +/* Note header */ +typedef struct elf64_note { + Elf64_Word n_namesz; /* Name size */ + Elf64_Word n_descsz; /* Content size */ + Elf64_Word n_type; /* Content type */ +} Elf64_Nhdr; + +#endif /* _SYS_ELF64_H */ + diff --git a/klibc/klibc/include/sys/elfcommon.h b/klibc/klibc/include/sys/elfcommon.h new file mode 100644 index 0000000000..f984f6a56b --- /dev/null +++ b/klibc/klibc/include/sys/elfcommon.h @@ -0,0 +1,186 @@ +/* + * sys/elfcommon.h + */ + +#ifndef _SYS_ELFCOMMON_H +#define _SYS_ELFCOMMON_H + +/* Segment types */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff +#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */ + +/* ELF file types */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff + +/* ELF machine types */ +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +#define EM_486 6 /* Not used in Linux at least */ +#define EM_860 7 +#define EM_MIPS 8 /* R3k, bigendian(?) */ +#define EM_MIPS_RS4_BE 10 /* R4k BE */ +#define EM_PARISC 15 +#define EM_SPARC32PLUS 18 +#define EM_PPC 20 +#define EM_PPC64 21 +#define EM_S390 22 +#define EM_SH 42 +#define EM_SPARCV9 43 /* v9 = SPARC64 */ +#define EM_H8_300H 47 +#define EM_H8S 48 +#define EM_IA_64 50 /* Itanic */ +#define EM_X86_64 62 +#define EM_CRIS 76 +#define EM_V850 87 +#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */ +#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */ +#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ + +/* Dynamic type values */ +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + +/* Auxilliary table entries */ +#define AT_NULL 0 /* end of vector */ +#define AT_IGNORE 1 /* entry should be ignored */ +#define AT_EXECFD 2 /* file descriptor of program */ +#define AT_PHDR 3 /* program headers for program */ +#define AT_PHENT 4 /* size of program header entry */ +#define AT_PHNUM 5 /* number of program headers */ +#define AT_PAGESZ 6 /* system page size */ +#define AT_BASE 7 /* base address of interpreter */ +#define AT_FLAGS 8 /* flags */ +#define AT_ENTRY 9 /* entry point of program */ +#define AT_NOTELF 10 /* program is not ELF */ +#define AT_UID 11 /* real uid */ +#define AT_EUID 12 /* effective uid */ +#define AT_GID 13 /* real gid */ +#define AT_EGID 14 /* effective gid */ +#define AT_PLATFORM 15 /* string identifying CPU for optimizations */ +#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ +#define AT_CLKTCK 17 /* frequency at which times() increments */ +/* 18..22 = ? */ +#define AT_SECURE 23 /* secure mode boolean */ + +/* Program header permission flags */ +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 + +/* Section header types */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_NUM 12 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* Section header flags */ +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MASKPROC 0xf0000000 + +/* Special section numbers */ +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +/* Lenght of magic at the start of a file */ +#define EI_NIDENT 16 + +/* Magic number constants... */ +#define EI_MAG0 0 /* e_ident[] indexes */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_PAD 8 + +#define ELFMAG0 0x7f /* EI_MAG */ +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define ELFCLASSNONE 0 /* EI_CLASS */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 /* e_version, EI_VERSION */ +#define EV_CURRENT 1 +#define EV_NUM 2 + +#define ELFOSABI_NONE 0 +#define ELFOSABI_LINUX 3 + +#endif /* _SYS_ELFCOMMON_H */ + diff --git a/klibc/klibc/include/sys/sysmacros.h b/klibc/klibc/include/sys/sysmacros.h new file mode 100644 index 0000000000..7f1e0822b3 --- /dev/null +++ b/klibc/klibc/include/sys/sysmacros.h @@ -0,0 +1,31 @@ +/* + * sys/sysmacros.h + * + * Constructs to create and pick apart dev_t. This applies to the Linux 2.6 + * 32-bit dev_t format. + */ + +#ifndef _SYS_SYSMACROS_H +#define _SYS_SYSMACROS_H + +#ifndef _SYS_TYPES_H +# include +#endif + +static __inline__ int major(dev_t __d) +{ + return (__d >> 8) & 0xfff; +} + +static __inline__ int minor(dev_t __d) +{ + return (__d & 0xff) | ((__d >> 12) & 0xfff00); +} + +static __inline__ dev_t makedev(int __ma, int __mi) +{ + return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12); +} + +#endif /* _SYS_SYSMACROS_H */ + diff --git a/klibc/klibc/include/sys/time.h b/klibc/klibc/include/sys/time.h index 4eccf824a4..b503d21076 100644 --- a/klibc/klibc/include/sys/time.h +++ b/klibc/klibc/include/sys/time.h @@ -6,6 +6,7 @@ #define _SYS_TIME_H #include +#include #include __extern int gettimeofday(struct timeval *, struct timezone *); diff --git a/klibc/klibc/include/sys/types.h b/klibc/klibc/include/sys/types.h index a25873cc4b..0aaeeb1612 100644 --- a/klibc/klibc/include/sys/types.h +++ b/klibc/klibc/include/sys/types.h @@ -1,8 +1,5 @@ /* * sys/types.h - * - * This is a bastardized version of linux/types.h, since that file - * is broken w.r.t. definitions. */ #ifndef _SYS_TYPES_H @@ -25,7 +22,7 @@ typedef uint32_t dev_t; typedef __kernel_ino_t ino_t; typedef __kernel_mode_t mode_t; typedef __kernel_nlink_t nlink_t; -typedef __kernel_off_t off_t; +typedef __kernel_off_t off_t; /* Should become __kernel_loff_t... */ typedef __kernel_pid_t pid_t; typedef __kernel_daddr_t daddr_t; typedef __kernel_key_t key_t; @@ -83,15 +80,11 @@ typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; -#ifndef __BIT_TYPES_DEFINED__ -#define __BIT_TYPES_DEFINED__ - -typedef __u8 u_int8_t; -typedef __u16 u_int16_t; -typedef __u32 u_int32_t; -typedef __u64 u_int64_t; - -#endif /* !(__BIT_TYPES_DEFINED__) */ +/* Linux-specific? */ +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; /* * transition to 64-bit sector_t, possibly making it an option... @@ -124,4 +117,9 @@ struct ustat { char f_fpack[6]; }; +/* + * Some apps want this in + */ +#include + #endif diff --git a/klibc/klibc/include/sys/wait.h b/klibc/klibc/include/sys/wait.h index cad6989bf7..4cfafc9408 100644 --- a/klibc/klibc/include/sys/wait.h +++ b/klibc/klibc/include/sys/wait.h @@ -11,6 +11,15 @@ #include +#define WEXITSTATUS(s) (((s) & 0xff00) >> 8) +#define WTERMSIG(s) ((s) & 0x7f) +#define WIFEXITED(s) (WTERMSIG(s) == 0) +#define WIFSTOPPED(s) (WTERMSIG(s) == 0x7f) +/* Ugly hack to avoid multiple evaluation of "s" */ +#define WIFSIGNALED(s) (WTERMSIG((s)+1) >= 2) +#define WCOREDUMP(s) ((s) & 0x80) +#define WSTOPSIG(s) WEXITSTATUS(s) + __extern pid_t wait(int *); __extern pid_t waitpid(pid_t, int *, int); __extern pid_t wait3(int *, int, struct rusage *); diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h index 3d5c6881d3..f1cde2376e 100644 --- a/klibc/klibc/include/unistd.h +++ b/klibc/klibc/include/unistd.h @@ -49,6 +49,12 @@ __extern int setresgid(gid_t, gid_t, gid_t); __extern int getfsuid(uid_t); __extern int setfsuid(uid_t); +/* Macros for access() */ +#define R_OK 4 /* Read */ +#define W_OK 2 /* Write */ +#define X_OK 1 /* Execute */ +#define F_OK 0 /* Existence */ + __extern int access(const char *, int); __extern int link(const char *, const char *); __extern int unlink(const char *); diff --git a/klibc/klibc/putenv.c b/klibc/klibc/putenv.c new file mode 100644 index 0000000000..8138c653b4 --- /dev/null +++ b/klibc/klibc/putenv.c @@ -0,0 +1,40 @@ +/* + * putenv.c + */ + +#include +#include +#include +#include + +/* str should be a duplicated version of the input string; + len is the length of the key including the = sign */ +int __put_env(char *str, size_t len, int overwrite); + +int putenv(const char *str) +{ + char *s; + const char *e, *z; + + if ( !str ) { + errno = EINVAL; + return -1; + } + + e = NULL; + for ( z = str ; *z ; z++ ) { + if ( *z == '=' ) + e = z; + } + + if ( !e ) { + errno = EINVAL; + return -1; + } + + s = strdup(str); + if ( !s ) + return -1; + + return __put_env(s, e-str, 1); +} diff --git a/klibc/klibc/setenv.c b/klibc/klibc/setenv.c index d1118ff3ed..d4ada53d74 100644 --- a/klibc/klibc/setenv.c +++ b/klibc/klibc/setenv.c @@ -7,87 +7,9 @@ #include #include -/* Initialized to zero, meaning "not malloc'd" */ -static size_t __environ_size; - /* str should be a duplicated version of the input string; len is the length of the key including the = sign */ -static int _putenv(char *str, size_t len, int overwrite) -{ - char **p, *q; - char **newenv; - size_t n; - - n = 1; /* Include space for final NULL */ - for ( p = environ ; (q = *p) ; p++ ) { - n++; - if ( !strncmp(q,str,len) ) { - if ( overwrite ) - free(str); - else - *p = str; /* Memory leak... */ - return 0; - } - } - - /* Need to extend the environment */ - if ( n < __environ_size ) { - p[1] = NULL; - *p = str; - return 0; - } else { - if ( __environ_size ) { - newenv = realloc(environ, (__environ_size << 1)*sizeof(char *)); - if ( !newenv ) - return -1; - - __environ_size <<= 1; - } else { - /* Make a reasonable guess how much more space we need */ - size_t newsize = n+32; - newenv = malloc(newsize*sizeof(char *)); - if ( !newenv ) - return -1; - - memcpy(newenv, environ, n*sizeof(char *)); - __environ_size = newsize; - } - newenv[n+1] = NULL; - newenv[n] = str; - environ = newenv; - } - return 0; -} - -int putenv(const char *str) -{ - char *s; - const char *e, *z; - size_t len; - - if ( !str ) { - errno = EINVAL; - return -1; - } - - len = 0; e = NULL; - for ( z = str ; *z ; z++ ) { - len++; - if ( *z == '=' ) - e = z; - } - - if ( !e ) { - errno = EINVAL; - return -1; - } - - s = strdup(str); - if ( !s ) - return -1; - - return _putenv(s, len, 1); -} +int __put_env(char *str, size_t len, int overwrite); int setenv(const char *name, const char *val, int overwrite) { @@ -117,8 +39,7 @@ int setenv(const char *name, const char *val, int overwrite) memcpy(s, name, l1); s[l1] = '='; - memcpy(s+l1+1, val, l2); - s[l1+l2+1] = '\0'; + memcpy(s+l1+1, val, l2+1); - return _putenv(s, l1+1, overwrite); + return __put_env(s, l1+1, overwrite); } diff --git a/klibc/klibc/signal.c b/klibc/klibc/sysv_signal.c similarity index 60% rename from klibc/klibc/signal.c rename to klibc/klibc/sysv_signal.c index 982d0c659d..3e55a02bb5 100644 --- a/klibc/klibc/signal.c +++ b/klibc/klibc/sysv_signal.c @@ -1,10 +1,10 @@ /* - * signal.c + * sysv_signal.c */ #include -__sighandler_t signal(int signum, __sighandler_t handler) +__sighandler_t sysv_signal(int signum, __sighandler_t handler) { /* Linux/SysV signal() semantics */ return __signal(signum, handler, SA_RESETHAND); diff --git a/klibc/klibc/tests/getenvtest.c b/klibc/klibc/tests/environ.c similarity index 72% rename from klibc/klibc/tests/getenvtest.c rename to klibc/klibc/tests/environ.c index 07cac0cef7..6eeeb9197e 100644 --- a/klibc/klibc/tests/getenvtest.c +++ b/klibc/klibc/tests/environ.c @@ -17,10 +17,8 @@ int main(int argc, char *argv[], char *envp[]) } /* Test environ */ - printf("PATH = %s\n", getenv("PATH")); - printf("HOME = %s\n", getenv("HOME")); - printf("TERM = %s\n", getenv("TERM")); - printf("USER = %s\n", getenv("USER")); + for ( i = 0 ; envp[i] ; i++ ) + printf("%s\n", envp[i]); return 0; } diff --git a/klibc/klibc/tests/nfs_no_rpc.c b/klibc/klibc/tests/nfs_no_rpc.c index 11b9f61fea..5c17706b63 100644 --- a/klibc/klibc/tests/nfs_no_rpc.c +++ b/klibc/klibc/tests/nfs_no_rpc.c @@ -282,7 +282,7 @@ static int do_call(struct sockaddr_in *sin, u_int32_t msg[], u_int32_t rmsg[], int n; int fd; - signal(SIGALRM, timeout); + sysv_signal(SIGALRM, timeout); fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (fd < 0) goto Esocket; diff --git a/klibc/klibc/tests/setenvtest.c b/klibc/klibc/tests/setenvtest.c new file mode 100644 index 0000000000..111bef9dfe --- /dev/null +++ b/klibc/klibc/tests/setenvtest.c @@ -0,0 +1,38 @@ +#include +#include +#include + +int main(int argc, char *argv[]) +{ + (void)argc; (void)argv; + + /* Set SETENV */ + setenv("SETENV", "setenv", 1); + + /* Set PUTENV */ + putenv("PUTENV=putenv"); + + /* Print the results... */ + printf("SETENV = %s\n", getenv("SETENV")); + printf("PUTENV = %s\n", getenv("PUTENV")); + + /* Override tests */ + setenv("SETENV", "setenv_good", 1); + putenv("PUTENV=putenv_good"); + printf("SETENV = %s\n", getenv("SETENV")); + printf("PUTENV = %s\n", getenv("PUTENV")); + + /* Non-override test */ + setenv("SETENV", "setenv_bad", 0); + setenv("NEWENV", "newenv_good", 0); + printf("SETENV = %s\n", getenv("SETENV")); + printf("NEWENV = %s\n", getenv("NEWENV")); + + /* Undef test */ + unsetenv("SETENV"); + unsetenv("NEWENV"); + printf("SETENV = %s\n", getenv("SETENV")); + printf("NEWENV = %s\n", getenv("NEWENV")); + + return 0; +} From da92f46b9e86643e70861bb705453f81aef5618d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 11 Feb 2004 18:34:28 -0800 Subject: [PATCH 0504/4284] [PATCH] finish syncing up with klibc --- klibc/MCONFIG | 3 +- klibc/MRULES | 41 ++++++++++++ klibc/README | 10 ++- klibc/klibc.spec.in | 151 ++++++++++++++++++++++++++++++++++++++++++++ klibc/version | 2 +- 5 files changed, 202 insertions(+), 5 deletions(-) create mode 100644 klibc/MRULES create mode 100644 klibc/klibc.spec.in diff --git a/klibc/MCONFIG b/klibc/MCONFIG index 8b5da4154b..de8b332d98 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -21,7 +21,8 @@ PERL = perl STRIP = $(CROSS)strip --strip-all -R .comment -R .note HOST_CC = gcc -HOST_LDFLAGS = -s +HOST_CFLAGS = -g -O +HOST_LDFLAGS = HOST_LIBS = CRT0 = $(KLIBSRC)/crt0.o diff --git a/klibc/MRULES b/klibc/MRULES new file mode 100644 index 0000000000..8a8831c348 --- /dev/null +++ b/klibc/MRULES @@ -0,0 +1,41 @@ +# -*- makefile -*- +# +# Standard pattern rules +# + +.SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss + +.c.o: + $(CC) $(CFLAGS) -c -o $@ $< + +.c.i: + $(CC) $(CFLAGS) -E -o $@ $< + +.c.s: + $(CC) $(CFLAGS) -S -o $@ $< + +.S.o: + $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< + +.S.s: + $(CC) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $< + +.S.lo: + $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -c -o $@ $< + +.S.ls: + $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -E -o $@ $< + +.s.o: + $(CC) $(CFLAGS) -x assembler -c -o $@ $< + +.ls.lo: + $(CC) $(CFLAGS) $(SOFLAGS) -x assembler -c -o $@ $< + +.c.lo: + $(CC) $(CFLAGS) $(SOFLAGS) -c -o $@ $< + +.c.ls: + $(CC) $(CFLAGS) $(SOFLAGS) -S -o $@ $< + + diff --git a/klibc/README b/klibc/README index 577de2b704..4381364874 100644 --- a/klibc/README +++ b/klibc/README @@ -1,8 +1,10 @@ -Please see klibc/README for how to set up the tree before building. +Please see klibc/README for build instructions. + + klibc is archived at: - ftp://ftp.zytor.com/pub/linux/libs/klibc/ + ftp://ftp.kernel.org/pub/linux/libs/klibc/ There is a mailing list for klibc and early-userspace issues at: @@ -12,5 +14,7 @@ There is also a cvsweb repository at: http://www.zytor.com/cvsweb.cgi/klibc/ -There is no direct public CVS access yet, however. +There is no direct public CVS access yet, however, the CVS repository +is available for rsync from: + rsync://rsync.kernel.org/pub/linux/libs/klibc/cvsroot/ diff --git a/klibc/klibc.spec.in b/klibc/klibc.spec.in new file mode 100644 index 0000000000..f8bccc390e --- /dev/null +++ b/klibc/klibc.spec.in @@ -0,0 +1,151 @@ +%define _rpmdir rpms +%define _builddir . + +Summary: A minimal libc subset for use with initramfs. +Name: klibc +Version: 0.89 +Release: 1 +License: BSD/GPL +Group: Development/Libraries +URL: http://www.zytor.com/klibc +Source: /dev/null +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +Packager: Bryan O'Sullivan +Prefix: /usr +Vendor: Starving Linux Artists + +%description +%{name} is intended to be a minimalistic libc subset for use with +initramfs. It is deliberately written for small size, minimal +entanglement, and portability, not speed. It is definitely a work in +progress, and a lot of things are still missing. + +%package kernheaders +Summary: Kernel headers used during the build of klibc. +Group: Development/Libraries + +%description kernheaders +This package contains the set of kernel headers that were required to +build %{name} and the utilities that ship with it. This may or may +not be a complete enough set to build other programs that link against +%{name}. If in doubt, use real kernel headers instead. + +%package utils +Summary: Small statically-linked utilities built with klibc. +Group: Utilities/System + +%description utils + +This package contains a collection of programs that are statically +linked against klibc. These duplicate some of the functionality of a +regular Linux toolset, but are typically much smaller than their +full-function counterparts. They are intended for inclusion in +initramfs images and embedded systems. + +%prep +if [ ! -L linux ]; then + echo "*** You must have a symlink named linux to build klibc" 1>&2 + exit 1 +fi +if [ ! -f linux/include/asm/page.h ]; then + echo "*** You need to 'make prepare' in the linux tree before building klibc" 1>&2 + exit 1 +fi +mkdir -p %{buildroot} %{_rpmdir} + +%build +make + +%install +rm -rf %{buildroot} + +dest=%{buildroot}/%{prefix} +lib=$dest/%{_lib}/klibc +inc=$dest/include/klibc +exe=$dest/libexec/klibc +doc=$dest/share/doc/%{name}-%{version} +udoc=$dest/share/doc/%{name}-utils-%{version} + +# First, the library. + +install -dD -m 755 $lib $inc/kernel $exe $doc $udoc +install -m 755 klibc/klibc.so $lib +install -m 644 klibc/libc.a $lib +install -m 644 klibc/crt0.o $lib +install -m 644 klibc/libc.so.hash $lib +ln $lib/klibc.so $lib/libc.so +ln $lib/klibc.so $lib/klibc-$(cat $lib/libc.so.hash).so + +# Next, the generated binaries. + +install -m 755 ash/sh $exe +install -m 755 gzip/gzip $exe +ln $exe/gzip $exe/gunzip +ln $exe/gzip $exe/zcat +install -m 755 ipconfig/ipconfig $exe +install -m 755 kinit/kinit $exe +install -m 755 nfsmount/nfsmount $exe +for i in chroot dd fstype mkdir mkfifo mount umount; do + install -m 755 utils/$i $exe +done + +# The docs. + +install -m 444 README $doc +install -m 444 klibc/README $doc/README.klibc +install -m 444 klibc/arch/README $doc/README.klibc.arch + +install -m 444 gzip/COPYING $udoc/COPYING.gzip +install -m 444 gzip/README $udoc/README.gzip +install -m 444 ipconfig/README $udoc/README.ipconfig +install -m 444 kinit/README $udoc/README.kinit + +# Finally, the include files. + +bitsize=$(make --no-print-directory -C klibc bitsize) +cp --parents $(find klibc/include \( -name CVS -o -name SCCS \) -prune \ + -o -name '*.h' -print) $inc +mv $inc/klibc $inc/klibc.$$ +mv $inc/klibc.$$/include/* $inc +mv $inc/bits$bitsize/bitsize $inc +rm -rf $inc/klibc.$$ $inc/bits[0-9]* +pushd klibc/arch/%{_arch}/include +cp --parents -f $(find . \( -name CVS -o -name SCCS \) -prune \ + -o -name '*.h' -print) $inc +popd + +# Yeugh. Find the transitive closure over all kernel headers included +# by klibc, and copy them into place. + +find . -name '.*.d' | xargs -r sed -e 's,[ \t][ \t]*,\n,g' | sed -n -e 's,^\.\./linux/include/,,p' | sort | uniq | (cd linux/include && xargs -ri cp --parents '{}' $inc/kernel) + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%docdir %{prefix}/share/doc/%{name}-%{version} +%{prefix}/%{_lib}/klibc +%dir %{prefix}/include/klibc +%{prefix}/include/klibc/*.h +%{prefix}/include/klibc/arpa +%{prefix}/include/klibc/bitsize +%{prefix}/include/klibc/klibc +%{prefix}/include/klibc/net +%{prefix}/include/klibc/netinet +%{prefix}/include/klibc/sys +%{prefix}/share/doc/%{name}-%{version} + +%files kernheaders +%defattr(-,root,root,-) +%{prefix}/include/klibc/kernel + +%files utils +%defattr(-,root,root,-) +%{prefix}/libexec/klibc +%docdir %{prefix}/share/doc/%{name}-utils-%{version} +%{prefix}/share/doc/%{name}-utils-%{version} + +%changelog +* Sat Nov 29 2003 Bryan O'Sullivan - +- Initial build. diff --git a/klibc/version b/klibc/version index 2f3d7fa995..f14cf6a1e0 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.101 +0.107 From 4d803d8d04a8493f8efc039c7789c65be33048a0 Mon Sep 17 00:00:00 2001 From: "azarah@nosferatu.za.org" Date: Wed, 11 Feb 2004 19:42:51 -0800 Subject: [PATCH 0505/4284] [PATCH] make logging a config option Once again, patch to make logging a config option. Reason for this (since you asked for it): - In our setup it is easy (although still annoying) .. just edit the ebuild, add logging support (or remove it) and rebuild. For say a binary distro, having the logging is useful for debugging some times, but its more a once of, or rare thing, as you do not add or change config files every day. Sure, we can have logging by default, but many do not want ~300 lines of extra debugging in their logs is not pleasant, and they will complain. Rebuilding the package for that binary package (given the users it is targeted to) is usually not within most users grasp. --- Makefile | 1 + etc/udev/udev.conf.in | 3 +++ logging.h | 6 ++++++ udev.h | 3 +++ udev_config.c | 5 +++++ 5 files changed, 18 insertions(+) diff --git a/Makefile b/Makefile index 97c6ca63bd..ebcb2815c8 100644 --- a/Makefile +++ b/Makefile @@ -239,6 +239,7 @@ udev_version.h: @echo \#define UDEV_CONFIG_FILE \"$(configdir)\udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ + @echo \#define UDEV_LOG_DEFAULT \"yes\" >> $@ @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index f9a60ab3c8..3e73bedbf5 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -29,3 +29,6 @@ default_owner="root" # explicit match in the permissions file default_group="root" +# udev_log - set to "yes" if you want logging, else "no" +udev_log="yes" + diff --git a/logging.h b/logging.h index 485209adf3..5ae228b139 100644 --- a/logging.h +++ b/logging.h @@ -34,6 +34,9 @@ #include #include +#include "udev.h" +#include "udev_version.h" + #undef info #define info(format, arg...) \ do { \ @@ -63,6 +66,9 @@ static inline void log_message (int level, const char *format, ...) { va_list args; + if (0 != strncmp(udev_log_str, UDEV_LOG_DEFAULT, BOOL_SIZE)) + return; + va_start(args, format); vsyslog(level, format, args); va_end(args); diff --git a/udev.h b/udev.h index f854a183d3..8b3f305d34 100644 --- a/udev.h +++ b/udev.h @@ -32,6 +32,8 @@ #define OWNER_SIZE 30 #define GROUP_SIZE 30 #define MODE_SIZE 8 +#define BOOL_SIZE 5 /* 'yes', 'no' and possibly 'true' or 'false' + in future */ struct udevice { char name[NAME_SIZE]; @@ -72,5 +74,6 @@ extern char udev_rules_filename[PATH_MAX+NAME_MAX]; extern char default_mode_str[MODE_SIZE]; extern char default_owner_str[OWNER_SIZE]; extern char default_group_str[GROUP_SIZE]; +extern char udev_log_str[BOOL_SIZE]; #endif diff --git a/udev_config.c b/udev_config.c index 6d39d294e1..ec38272bc5 100644 --- a/udev_config.c +++ b/udev_config.c @@ -48,6 +48,7 @@ char udev_config_filename[PATH_MAX+NAME_MAX]; char default_mode_str[MODE_SIZE]; char default_owner_str[OWNER_SIZE]; char default_group_str[GROUP_SIZE]; +char udev_log_str[BOOL_SIZE]; static void init_variables(void) @@ -60,6 +61,7 @@ static void init_variables(void) strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE); strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); + strfieldcpy(udev_log_str, UDEV_LOG_DEFAULT); } #define set_var(_name, _var) \ @@ -156,6 +158,7 @@ static int parse_config_file(void) set_var("default_mode", default_mode_str); set_var("default_owner", default_owner_str); set_var("default_group", default_group_str); + set_var("udev_log", udev_log_str); } dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, lineno, temp - line, temp); @@ -191,6 +194,7 @@ static void get_dirs(void) dbg_parse("udev_db_filename = %s", udev_db_filename); dbg_parse("udev_rules_filename = %s", udev_rules_filename); dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); + dbg_parse("udev_log_str = %s", udev_log_str); parse_config_file(); dbg_parse("udev_root = %s", udev_root); @@ -198,6 +202,7 @@ static void get_dirs(void) dbg_parse("udev_db_filename = %s", udev_db_filename); dbg_parse("udev_rules_filename = %s", udev_rules_filename); dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); + dbg_parse("udev_log_str = %s", udev_log_str); } void udev_init_config(void) From 51a8bb2f361d86013e7579570faba446eed9c66d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 11 Feb 2004 22:10:26 -0800 Subject: [PATCH 0506/4284] [PATCH] fix log option code so that it actually works for all udev programs. Also introduce boolean type for config file to use. --- logging.h | 12 +++++------- test/ignore_test | 1 + udev.c | 5 +++++ udev.h | 4 +--- udev_config.c | 25 ++++++++++++++++++++----- udevd.c | 8 +++++++- udevinfo.c | 5 +++++ udevsend.c | 5 +++++ 8 files changed, 49 insertions(+), 16 deletions(-) diff --git a/logging.h b/logging.h index 5ae228b139..df0d7dedce 100644 --- a/logging.h +++ b/logging.h @@ -34,9 +34,6 @@ #include #include -#include "udev.h" -#include "udev_version.h" - #undef info #define info(format, arg...) \ do { \ @@ -60,13 +57,17 @@ } while (0) #endif +/* each program must declare this variable and function somewhere */ +extern unsigned char logname[42]; +extern int log_ok(void); + static void log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); static inline void log_message (int level, const char *format, ...) { va_list args; - if (0 != strncmp(udev_log_str, UDEV_LOG_DEFAULT, BOOL_SIZE)) + if (!log_ok()) return; va_start(args, format); @@ -74,9 +75,6 @@ static inline void log_message (int level, const char *format, ...) va_end(args); } -/* each program must declare this variable somewhere */ -extern unsigned char logname[42]; - #undef init_logging static inline void init_logging(char *program_name) { diff --git a/test/ignore_test b/test/ignore_test index 602624c1e0..ca51e9a1ab 100644 --- a/test/ignore_test +++ b/test/ignore_test @@ -16,6 +16,7 @@ udev_root="$PWD/udev/" udev_db="$PWD/udev/.udev.tdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" +udev_log="true" EOF mkdir udev diff --git a/udev.c b/udev.c index b45fb336be..55a324efbc 100644 --- a/udev.c +++ b/udev.c @@ -40,6 +40,11 @@ char **main_argv; char **main_envp; unsigned char logname[42]; +int log_ok(void) +{ + return udev_log; +} + static void sig_handler(int signum) { dbg("caught signal %d", signum); diff --git a/udev.h b/udev.h index 8b3f305d34..108623e059 100644 --- a/udev.h +++ b/udev.h @@ -32,8 +32,6 @@ #define OWNER_SIZE 30 #define GROUP_SIZE 30 #define MODE_SIZE 8 -#define BOOL_SIZE 5 /* 'yes', 'no' and possibly 'true' or 'false' - in future */ struct udevice { char name[NAME_SIZE]; @@ -74,6 +72,6 @@ extern char udev_rules_filename[PATH_MAX+NAME_MAX]; extern char default_mode_str[MODE_SIZE]; extern char default_owner_str[OWNER_SIZE]; extern char default_group_str[GROUP_SIZE]; -extern char udev_log_str[BOOL_SIZE]; +extern int udev_log; #endif diff --git a/udev_config.c b/udev_config.c index ec38272bc5..34ef82b881 100644 --- a/udev_config.c +++ b/udev_config.c @@ -48,9 +48,18 @@ char udev_config_filename[PATH_MAX+NAME_MAX]; char default_mode_str[MODE_SIZE]; char default_owner_str[OWNER_SIZE]; char default_group_str[GROUP_SIZE]; -char udev_log_str[BOOL_SIZE]; +int udev_log; +static int string_is_true(char *str) +{ + if (strcasecmp(str, "true") == 0) + return 1; + if (strcasecmp(str, "yes") == 0) + return 1; + return 0; +} + static void init_variables(void) { /* fill up the defaults. @@ -61,7 +70,7 @@ static void init_variables(void) strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE); strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); - strfieldcpy(udev_log_str, UDEV_LOG_DEFAULT); + udev_log = string_is_true(UDEV_LOG_DEFAULT); } #define set_var(_name, _var) \ @@ -70,6 +79,12 @@ static void init_variables(void) strncpy(_var, value, sizeof(_var)); \ } +#define set_bool(_name, _var) \ + if (strcasecmp(variable, _name) == 0) { \ + dbg_parse("%s = '%s'", _name, value); \ + _var = string_is_true(value); \ + } + int parse_get_pair(char **orig_string, char **left, char **right) { char *temp; @@ -158,7 +173,7 @@ static int parse_config_file(void) set_var("default_mode", default_mode_str); set_var("default_owner", default_owner_str); set_var("default_group", default_group_str); - set_var("udev_log", udev_log_str); + set_bool("udev_log", udev_log); } dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, lineno, temp - line, temp); @@ -194,7 +209,7 @@ static void get_dirs(void) dbg_parse("udev_db_filename = %s", udev_db_filename); dbg_parse("udev_rules_filename = %s", udev_rules_filename); dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); - dbg_parse("udev_log_str = %s", udev_log_str); + dbg_parse("udev_log = %d", udev_log); parse_config_file(); dbg_parse("udev_root = %s", udev_root); @@ -202,7 +217,7 @@ static void get_dirs(void) dbg_parse("udev_db_filename = %s", udev_db_filename); dbg_parse("udev_rules_filename = %s", udev_rules_filename); dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); - dbg_parse("udev_log_str = %s", udev_log_str); + dbg_parse("udev_log_str = %d", udev_log); } void udev_init_config(void) diff --git a/udevd.c b/udevd.c index 8ba833186e..476cb64309 100644 --- a/udevd.c +++ b/udevd.c @@ -40,7 +40,6 @@ #include "udevd.h" #include "logging.h" -unsigned char logname[42]; static int expected_seqnum = 0; volatile static int children_waiting; volatile static int msg_q_timeout; @@ -52,6 +51,13 @@ LIST_HEAD(running_list); static void exec_queue_manager(void); static void msg_queue_manager(void); +unsigned char logname[42]; + +int log_ok(void) +{ + return 1; +} + static void msg_dump_queue(void) { struct hotplug_msg *msg; diff --git a/udevinfo.c b/udevinfo.c index 71a9a6d93e..103ebce08c 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -40,6 +40,11 @@ char **main_argv; int main_argc; unsigned char logname[42]; +int log_ok(void) +{ + return 1; +} + static int print_all_attributes(const char *path) { struct dlist *attributes; diff --git a/udevsend.c b/udevsend.c index f6de88565f..17372d8d9a 100644 --- a/udevsend.c +++ b/udevsend.c @@ -42,6 +42,11 @@ unsigned char logname[42]; +int log_ok(void) +{ + return 1; +} + static inline char *get_action(void) { char *action; From 0c25b2066d06ae1f75d3e9f3f8e1e31d952906c5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 11 Feb 2004 22:28:47 -0800 Subject: [PATCH 0507/4284] [PATCH] udev - fix cdrom symlink rule We only need to look at the device, not at the partitions. --- etc/udev/udev.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 98d2ceccc7..344304dd95 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -35,7 +35,7 @@ KERNEL="ttyUSB0", NAME="pl2303" #KERNEL="tty*", NAME="vc/%n" # if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS="ide", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" +BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" # device mapper creates its own device nodes so ignore these KERNEL="dm-[0-9]*", NAME="" From c5118442a16940fc6ba40fd94ab28061e0f0d43b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 11 Feb 2004 22:28:51 -0800 Subject: [PATCH 0508/4284] [PATCH] udev - fix "ignore method" On Sun, Feb 08, 2004 at 04:36:01PM +0100, Kay Sievers wrote: > We don't handle NAME="" the right way. Thanks to Emil None > for pointing this out. Here is a fix for it and a trivial style cleanup. Changed the ignore dbg() to info(). --- namedev.c | 35 +++++++++++++++++------------------ udev-add.c | 30 +++++++++++++++--------------- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/namedev.c b/namedev.c index 6685596479..7984adfb31 100644 --- a/namedev.c +++ b/namedev.c @@ -589,12 +589,12 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas if (dev->bus[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no bus"); - goto no_good; + goto try_parent; } dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { dbg(FIELD_BUS " is not matching"); - goto no_good; + goto try_parent; } else { dbg(FIELD_BUS " matches"); } @@ -605,7 +605,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { dbg(FIELD_KERNEL " is not matching"); - goto no_good; + goto try_parent; } else { dbg(FIELD_KERNEL " matches"); } @@ -616,7 +616,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas dbg("check " FIELD_ID); if (match_id(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_ID " is not matching"); - goto no_good; + goto try_parent; } else { dbg(FIELD_ID " matches"); } @@ -627,7 +627,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas dbg("check " FIELD_PLACE); if (match_place(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_PLACE " is not matching"); - goto no_good; + goto try_parent; } else { dbg(FIELD_PLACE " matches"); } @@ -638,7 +638,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas dbg("check " FIELD_SYSFS " pairs"); if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_SYSFS " is not matching"); - goto no_good; + goto try_parent; } else { dbg(FIELD_SYSFS " matches"); } @@ -650,7 +650,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas apply_format(udev, dev->program); if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { dbg(FIELD_PROGRAM " returned nozero"); - goto no_good; + goto try_parent; } else { dbg(FIELD_PROGRAM " returned successful"); } @@ -663,22 +663,17 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas dev->result, udev->program_result); if (strcmp_pattern(dev->result, udev->program_result) != 0) { dbg(FIELD_RESULT " is not matching"); - goto no_good; + goto try_parent; } else { dbg(FIELD_RESULT " matches"); } } - /* check if we are instructed to ignore this device */ - if (dev->name[0] == '\0') { - dbg("instructed to ignore this device"); - return -1; - } - /* Yeah, we matched! */ return 0; -no_good: +try_parent: + dbg("try parent sysfs device"); sysfs_device = sysfs_get_device_parent(sysfs_device); if (sysfs_device == NULL) return -ENODEV; @@ -722,11 +717,15 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud /* look for a matching rule to apply */ list_for_each_entry(dev, &config_device_list, node) { dbg("process rule"); - if (match_rule(dev, class_dev, udev, sysfs_device) == 0) { - /* Yup, this rule belongs to us! */ + if (dev->name[0] == '\0') { + info("configured rule in '%s' at line %i applied, '%s' is ignored", + udev_rules_filename, dev->config_line, udev->kernel_name); + return -1; + } + info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", - udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); + udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); strfieldcpy(udev->name, dev->name); strfieldcpy(udev->symlink, dev->symlink); goto found; diff --git a/udev-add.c b/udev-add.c index 586911acc2..9f07d22ec6 100644 --- a/udev-add.c +++ b/udev-add.c @@ -87,7 +87,7 @@ static int create_path(char *file) *pos = 0x00; if (stat(p, &stats)) { retval = mkdir(p, 0755); - if (retval) { + if (retval != 0) { dbg("mkdir(%s) failed with error '%s'", p, strerror(errno)); return retval; @@ -145,17 +145,17 @@ static int create_node(struct udevice *dev) info("creating device node '%s'", filename); dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); retval = mknod(filename, dev->mode, res); - if (retval) + if (retval != 0) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, dev->mode, dev->major, dev->minor, strerror(errno)); dbg("chmod(%s, %#o)", filename, dev->mode); retval = chmod(filename, dev->mode); - if (retval) + if (retval != 0) dbg("chmod(%s, %#o) failed with error '%s'", filename, dev->mode, strerror(errno)); - if (dev->owner[0]) { + if (dev->owner[0] != '\0') { char *endptr; unsigned long id = strtoul(dev->owner, &endptr, 10); if (endptr[0] == '\0') @@ -169,7 +169,7 @@ static int create_node(struct udevice *dev) } } - if (dev->group[0]) { + if (dev->group[0] != '\0') { char *endptr; unsigned long id = strtoul(dev->group, &endptr, 10); if (endptr[0] == '\0') @@ -183,16 +183,16 @@ static int create_node(struct udevice *dev) } } - if (uid || gid) { + if (uid != 0 || gid != 0) { dbg("chown(%s, %u, %u)", filename, uid, gid); retval = chown(filename, uid, gid); - if (retval) + if (retval != 0) dbg("chown(%s, %u, %u) failed with error '%s'", filename, uid, gid, strerror(errno)); } /* create symlink if requested */ - if (dev->symlink[0]) { + if (dev->symlink[0] != '\0') { symlinks = dev->symlink; while (1) { linkname = strsep(&symlinks, " "); @@ -214,13 +214,13 @@ static int create_node(struct udevice *dev) tail = i+1; i++; } - while (linkname[i]) { + while (linkname[i] != '\0') { if (linkname[i] == '/') strcat(linktarget, "../"); i++; } - if (*linktarget == '\0') + if (linktarget[0] == '\0') strcpy(linktarget, "./"); strcat(linktarget, &dev->name[tail]); @@ -236,7 +236,7 @@ static int create_node(struct udevice *dev) dbg("symlink(%s, %s)", linktarget, filename); retval = symlink(linktarget, filename); - if (retval) + if (retval != 0) dbg("symlink(%s, %s) failed with error '%s'", linktarget, filename, strerror(errno)); } @@ -285,7 +285,7 @@ static int sleep_for_dev(char *path) dbg("looking for '%s'", filename); retval = stat(filename, &buf); - if (!retval) + if (retval == 0) goto exit; /* sleep to give the kernel a chance to create the dev file */ @@ -311,7 +311,7 @@ int udev_add_device(char *path, char *subsystem) dev.type = 'c'; retval = sleep_for_dev(path); - if (retval) + if (retval != 0) goto exit; class_dev = get_class_dev(path); @@ -319,13 +319,13 @@ int udev_add_device(char *path, char *subsystem) goto exit; retval = get_major_minor(class_dev, &dev); - if (retval) { + if (retval != 0) { dbg("get_major_minor failed"); goto exit; } retval = namedev_name_device(class_dev, &dev); - if (retval) + if (retval != 0) goto exit; retval = udevdb_add_dev(path, &dev); From f8911dbb0404902502085c7bb204f2f9c5bc1b9c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 11 Feb 2004 22:29:15 -0800 Subject: [PATCH 0509/4284] [PATCH] compile udevd with klibc On Mon, Feb 09, 2004 at 05:41:15AM +0100, Kay Sievers wrote: > It seems that today was just another udev-sunday for me :) > > Here is a working patch to compile udevd with klibc. > > It's sweet the static binary takes 6 kbytes and it runs > with only 80 kbytes virtual memory. > > I changed a few peaces and added a siginterrupt.c file to klibc. > We may check with hpa to get the changes upstream? So here is the next try :) hpa, for good reason, didn't like my changes to klibc. He will dump signal() completely from klibc instead, so here we switch to sigaction() and keep udevd working with klibc. --- Makefile | 4 +--- udev.c | 10 ++++++---- udevd.c | 28 ++++++++++++++++++---------- udevsend.c | 2 +- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index ebcb2815c8..d2cec3ac8a 100644 --- a/Makefile +++ b/Makefile @@ -157,7 +157,6 @@ ifeq ($(strip $(USE_KLIBC)),true) -I$(LINUX_INCLUDE_DIR) LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs - UDEVD = else WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations CRT0 = @@ -165,12 +164,11 @@ else CFLAGS += $(WARNINGS) -I$(GCCINCDIR) LIB_OBJS = -lc LDFLAGS = - UDEVD = $(DAEMON) endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(SENDER) $(UDEVD) $(HELPER) +all: $(ROOT) $(SENDER) $(DAEMON) $(HELPER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ diff --git a/udev.c b/udev.c index 55a324efbc..0f01fa41d2 100644 --- a/udev.c +++ b/udev.c @@ -47,14 +47,12 @@ int log_ok(void) static void sig_handler(int signum) { - dbg("caught signal %d", signum); switch (signum) { case SIGINT: case SIGTERM: sysbus_disconnect(); udevdb_exit(); exit(20 + signum); - break; default: dbg("unhandled signal"); } @@ -100,6 +98,7 @@ static int udev_hotplug(int argc, char **argv) char *subsystem; int retval = -EINVAL; int i; + struct sigaction act; action = get_action(); if (!action) { @@ -146,8 +145,11 @@ static int udev_hotplug(int argc, char **argv) } /* set up a default signal handler for now */ - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); + act.sa_handler = sig_handler; + sigemptyset (&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); /* initialize the naming deamon */ namedev_init(); diff --git a/udevd.c b/udevd.c index 476cb64309..104cb2b987 100644 --- a/udevd.c +++ b/udevd.c @@ -114,14 +114,18 @@ static void msg_queue_insert(struct hotplug_msg *msg) static void udev_run(struct hotplug_msg *msg) { pid_t pid; - setenv("ACTION", msg->action, 1); - setenv("DEVPATH", msg->devpath, 1); + char action[32]; + char devpath[256]; + char *env[] = { action, devpath, NULL }; + + snprintf(action, sizeof(action), "ACTION=%s", msg->action); + snprintf(devpath, sizeof(devpath), "DEVPATH=%s", msg->devpath); pid = fork(); switch (pid) { case 0: /* child */ - execl(UDEV_BIN, "udev", msg->subsystem, NULL); + execle(UDEV_BIN, "udev", msg->subsystem, NULL, env); dbg("exec of child failed"); exit(1); break; @@ -285,17 +289,21 @@ int main(int argc, char *argv[]) struct sockaddr_un saddr; socklen_t addrlen; int retval; + struct sigaction act; init_logging("udevd"); - signal(SIGINT, sig_handler); - signal(SIGTERM, sig_handler); - signal(SIGALRM, sig_handler); - signal(SIGCHLD, sig_handler); + /* set signal handler */ + act.sa_handler = sig_handler; + sigemptyset (&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); /* we want these two to interrupt system calls */ - siginterrupt(SIGALRM, 1); - siginterrupt(SIGCHLD, 1); + act.sa_flags = 0; + sigaction(SIGALRM, &act, NULL); + sigaction(SIGCHLD, &act, NULL); memset(&saddr, 0x00, sizeof(saddr)); saddr.sun_family = AF_LOCAL; @@ -310,7 +318,7 @@ int main(int argc, char *argv[]) } /* the bind takes care of ensuring only one copy running */ - retval = bind(ssock, &saddr, addrlen); + retval = bind(ssock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { dbg("bind failed\n"); goto exit; diff --git a/udevsend.c b/udevsend.c index 17372d8d9a..a24e7d75ed 100644 --- a/udevsend.c +++ b/udevsend.c @@ -179,7 +179,7 @@ int main(int argc, char* argv[]) /* If we can't send, try to start daemon and resend message */ loop = UDEVSEND_CONNECT_RETRY; while (loop--) { - retval = sendto(sock, &message, size, 0, (struct sockaddr*)&saddr, addrlen); + retval = sendto(sock, &message, size, 0, (struct sockaddr *)&saddr, addrlen); if (retval != -1) { retval = 0; goto close_and_exit; From 0028653cdff8e3a7f3577509ce89f8bb15efa01e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 11 Feb 2004 22:32:11 -0800 Subject: [PATCH 0510/4284] [PATCH] udevd - client access authorization Here is the badly needed client authorization for udevd. Since we switched to abstract namespace sockets, we are unable to control the access of the socket by file permissions. So here we send a ancillary credential message with every datagram, to be able to verify the uid of the sender. The sender can't fake the credentials, cause the kernel doesn't allow it for non root users. udevd is still working with klibc here :) --- udevd.c | 30 ++++++++++++++++++++++++++++-- udevsend.c | 37 +++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 6 deletions(-) diff --git a/udevd.c b/udevd.c index 104cb2b987..366c227a3b 100644 --- a/udevd.c +++ b/udevd.c @@ -222,6 +222,11 @@ static void handle_msg(int sock) { struct hotplug_msg *msg; int retval; + struct msghdr smsg; + struct cmsghdr *cmsg; + struct iovec iov; + struct ucred *cred; + char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; msg = msg_create(); if (msg == NULL) { @@ -229,13 +234,30 @@ static void handle_msg(int sock) return; } - retval = recv(sock, msg, sizeof(struct hotplug_msg), 0); + iov.iov_base = msg; + iov.iov_len = sizeof(struct hotplug_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); + + retval = recvmsg(sock, &smsg, 0); if (retval < 0) { if (errno != EINTR) dbg("unable to receive message"); return; } - + cmsg = CMSG_FIRSTHDR(&smsg); + cred = (struct ucred *) CMSG_DATA(cmsg); + + if (cred->uid != 0) { + dbg("sender uid=%i, message ignored", cred->uid); + free(msg); + return; + } + if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { dbg("message magic '%s' doesn't match, ignore it", msg->magic); free(msg); @@ -289,6 +311,7 @@ int main(int argc, char *argv[]) struct sockaddr_un saddr; socklen_t addrlen; int retval; + const int on = 1; struct sigaction act; init_logging("udevd"); @@ -324,6 +347,9 @@ int main(int argc, char *argv[]) goto exit; } + /* enable receiving of the sender credentials */ + setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + while (1) { handle_msg(ssock); diff --git a/udevsend.c b/udevsend.c index a24e7d75ed..b26c744422 100644 --- a/udevsend.c +++ b/udevsend.c @@ -119,7 +119,7 @@ static int start_daemon(void) int main(int argc, char* argv[]) { - struct hotplug_msg message; + struct hotplug_msg msg; char *action; char *devpath; char *subsystem; @@ -133,6 +133,13 @@ int main(int argc, char* argv[]) struct sockaddr_un saddr; socklen_t addrlen; int started_daemon = 0; + struct iovec iov; + struct msghdr smsg; + char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; + struct cmsghdr *cmsg; + struct ucred *cred; + + #ifdef DEBUG init_logging("udevsend"); @@ -174,12 +181,34 @@ int main(int argc, char* argv[]) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - size = build_hotplugmsg(&message, action, devpath, subsystem, seq); - + size = build_hotplugmsg(&msg, action, devpath, subsystem, seq); + + /* prepare message with credentials to authenticate ourself */ + iov.iov_base = &msg; + iov.iov_len = size; + + smsg.msg_name = &saddr; + smsg.msg_namelen = addrlen; + smsg.msg_iov = &iov; + smsg.msg_iovlen = 1; + smsg.msg_control = cred_msg; + smsg.msg_controllen = CMSG_LEN(sizeof(struct ucred));; + smsg.msg_flags = 0; + + cmsg = CMSG_FIRSTHDR(&smsg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_CREDENTIALS; + cmsg->cmsg_len = sizeof(cred_msg); + cred = (struct ucred *) CMSG_DATA(cmsg); + cred->uid = getuid(); + cred->gid = getgid(); + cred->pid = getpid(); + cred->pid = getpid(); + /* If we can't send, try to start daemon and resend message */ loop = UDEVSEND_CONNECT_RETRY; while (loop--) { - retval = sendto(sock, &message, size, 0, (struct sockaddr *)&saddr, addrlen); + retval = sendmsg(sock, &smsg, 0); if (retval != -1) { retval = 0; goto close_and_exit; From e9b2679f420b77f1ea49fc3cd8a746072fe66854 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 11 Feb 2004 23:23:17 -0800 Subject: [PATCH 0511/4284] [PATCH] fix up 'make release' to use bk to build the export tree. --- Makefile | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index d2cec3ac8a..f53e7ca2fd 100644 --- a/Makefile +++ b/Makefile @@ -283,15 +283,13 @@ DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.ta DISTDIR := $(RELEASE_NAME) srcdir = . release: clean - @echo "--------------------------cut here------------------------" - @echo "cd .." - @echo "rm -rf $(DISTDIR)" - @echo "mkdir $(DISTDIR)" - @echo "chmod 777 $(DISTDIR)" - @echo "cp -avr udev/* $(DISTDIR)" - @echo "tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz" - @echo "rm -rf $(DISTDIR)" - @echo "--------------------------cut here------------------------" + -rm -rf $(DISTDIR) + mkdir $(DISTDIR) + chmod 777 $(DISTDIR) + bk export $(DISTDIR) + tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz + rm -rf $(DISTDIR) + @echo "$(RELEASE_NAME).tar.gz created" small_release: $(DISTFILES) clean From f0142622b8b68d58694d0c97396bb24d0830c5df Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 11 Feb 2004 23:34:21 -0800 Subject: [PATCH 0512/4284] [PATCH] add a block device with a ! in the name, and a test for this. --- test/sys/block/rd!c0d0/dev | 1 + test/udev-test.pl | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 test/sys/block/rd!c0d0/dev diff --git a/test/sys/block/rd!c0d0/dev b/test/sys/block/rd!c0d0/dev new file mode 100644 index 0000000000..fae0a50572 --- /dev/null +++ b/test/sys/block/rd!c0d0/dev @@ -0,0 +1 @@ +8:0 diff --git a/test/udev-test.pl b/test/udev-test.pl index 0700e53576..1bce65885e 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -326,6 +326,16 @@ EOF expected => "visor" , conf => < "name test with ! in the name", + subsys => "block", + devpath => "block/rd!c0d0", + expected => "rd/c0d0" , + conf => < Date: Wed, 11 Feb 2004 23:49:04 -0800 Subject: [PATCH 0513/4284] [PATCH] Handle the '!' character that some block devices have. --- namedev.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 7984adfb31..3e2182ae7b 100644 --- a/namedev.c +++ b/namedev.c @@ -313,6 +313,19 @@ exit: return; /* here to prevent compiler warning... */ } +static void fix_kernel_name(struct udevice *udev) +{ + char *temp = udev->kernel_name; + + while (*temp != 0x00) { + /* Some block devices have a ! in their name, + * we need to change that to / */ + if (*temp == '!') + *temp = '/'; + ++temp; + } +} + static int execute_program(char *path, char *value, int len) { int retval; @@ -701,11 +714,12 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud dbg("sysfs_device->bus='%s'", sysfs_device->bus); strfieldcpy(udev->bus_id, sysfs_device->bus_id); wait_for_device_to_initialize(sysfs_device); - } else { - dbg("class_dev->name = '%s'", class_dev->name); } + dbg("class_dev->name = '%s'", class_dev->name); strfieldcpy(udev->kernel_name, class_dev->name); + fix_kernel_name(udev); + dbg("udev->kernel_name = '%s'", udev->kernel_name); /* get kernel number */ pos = class_dev->name + strlen(class_dev->name); From 2e31718495a89e6b582240ed527950f78e7d1849 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 00:49:52 -0800 Subject: [PATCH 0514/4284] [PATCH] let udev-test.pl run an individual test if you ask it to. just put the test number on the command line: udev-test.pl 3 will run test number 3 If no test number is specified, all of the tests will be run, just like before. --- test/udev-test.pl | 62 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 1bce65885e..c433b84a97 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -90,6 +90,16 @@ EOF expected => "visor/0" , conf => < "catch device by * - take 2", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + expected => "visor/0" , + conf => <$main_conf" || die "unable to create config file: $main_conf"; -print CONF "udev_root=\"$udev_root\"\n"; -print CONF "udev_db=\"$udev_db\"\n"; -print CONF "udev_rules=\"$conf_tmp\"\n"; -print CONF "udev_permissions=\"$perm\"\n"; -close CONF; - -foreach my $config (@tests) { - print "TEST: $config->{desc}\n"; +sub run_test { + my ($config, $number) = @_; + + print "TEST $number: $config->{desc}\n"; print "device \'$config->{devpath}\' expecting node \'$config->{expected}\'\n"; udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); @@ -402,6 +399,37 @@ foreach my $config (@tests) { } } +# prepare +system("rm -rf $udev_root"); +mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; + +# create initial config file +open CONF, ">$main_conf" || die "unable to create config file: $main_conf"; +print CONF "udev_root=\"$udev_root\"\n"; +print CONF "udev_db=\"$udev_db\"\n"; +print CONF "udev_rules=\"$conf_tmp\"\n"; +print CONF "udev_permissions=\"$perm\"\n"; +close CONF; + +my $test_num = 1; + +if ($ARGV[0]) { + # only run one test + $test_num = $ARGV[0]; + print "udev-test will run test number $test_num only\n"; + + run_test($tests[$test_num], $test_num); +} else { + # test all + print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; + + foreach my $config (@tests) { + run_test($config, $test_num); + $test_num++; + + } +} + print "$error errors occured\n\n"; # cleanup From ede4308a803131f473efed3dc3246ffac7163dfa Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 01:14:48 -0800 Subject: [PATCH 0515/4284] [PATCH] remove some more KLIBC fixups that are no longer needed. --- klibc_fixups.h | 6 ------ udev-add.c | 9 +-------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/klibc_fixups.h b/klibc_fixups.h index 37622c86d6..1ac112b087 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -3,12 +3,6 @@ #ifndef KLIBC_FIXUPS_H #define KLIBC_FIXUPS_H - -#define WTERMSIG(status) ((status) & 0x7f) -#define WEXITSTATUS(status) (((status) & 0xff00) >> 8) -#define WIFEXITED(status) (WTERMSIG(status) == 0) - - struct group { char *gr_name; /* group name */ char *gr_passwd; /* group password */ diff --git a/udev-add.c b/udev-add.c index 9f07d22ec6..fedc8f0fc8 100644 --- a/udev-add.c +++ b/udev-add.c @@ -109,19 +109,12 @@ static int create_node(struct udevice *dev) int retval = 0; uid_t uid = 0; gid_t gid = 0; - dev_t res; int i; int tail; strncpy(filename, udev_root, sizeof(filename)); strncat(filename, dev->name, sizeof(filename)); -#ifdef __KLIBC__ - res = (dev->major << 8) | (dev->minor); -#else - res = makedev(dev->major, dev->minor); -#endif - switch (dev->type) { case 'b': dev->mode |= S_IFBLK; @@ -144,7 +137,7 @@ static int create_node(struct udevice *dev) info("creating device node '%s'", filename); dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); - retval = mknod(filename, dev->mode, res); + retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor)); if (retval != 0) dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, dev->mode, dev->major, dev->minor, strerror(errno)); From 7b1cbec91a51a8d8f1546935d942744b0f5a274e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 12 Feb 2004 01:23:59 -0800 Subject: [PATCH 0516/4284] [PATCH] better credential patch Here is a small improvement. We check for the type of message we receive and udevsend seems not to need all the credential setup stuff, the kernel will fill it for us. udevd now refuses to start as non root, cause it doesn't make any sense. --- udevd.c | 25 +++++++++++++++++++------ udevsend.c | 31 +------------------------------ 2 files changed, 20 insertions(+), 36 deletions(-) diff --git a/udevd.c b/udevd.c index 366c227a3b..14616b9824 100644 --- a/udevd.c +++ b/udevd.c @@ -252,16 +252,19 @@ static void handle_msg(int sock) cmsg = CMSG_FIRSTHDR(&smsg); cred = (struct ucred *) CMSG_DATA(cmsg); + if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { + dbg("no sender credentials received, message ignored"); + goto skip; + } + if (cred->uid != 0) { dbg("sender uid=%i, message ignored", cred->uid); - free(msg); - return; + goto skip; } if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { dbg("message magic '%s' doesn't match, ignore it", msg->magic); - free(msg); - return; + goto skip; } /* if no seqnum is given, we move straight to exec queue */ @@ -271,6 +274,11 @@ static void handle_msg(int sock) } else { msg_queue_insert(msg); } + return; + +skip: + free(msg); + return; } static void sig_handler(int signum) @@ -316,6 +324,11 @@ int main(int argc, char *argv[]) init_logging("udevd"); + if (getuid() != 0) { + dbg("need to be root, exit"); + exit(1); + } + /* set signal handler */ act.sa_handler = sig_handler; sigemptyset (&act.sa_mask); @@ -336,14 +349,14 @@ int main(int argc, char *argv[]) ssock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (ssock == -1) { - dbg("error getting socket"); + dbg("error getting socket, exit"); exit(1); } /* the bind takes care of ensuring only one copy running */ retval = bind(ssock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { - dbg("bind failed\n"); + dbg("bind failed, exit"); goto exit; } diff --git a/udevsend.c b/udevsend.c index b26c744422..b2fbcbbca6 100644 --- a/udevsend.c +++ b/udevsend.c @@ -133,13 +133,6 @@ int main(int argc, char* argv[]) struct sockaddr_un saddr; socklen_t addrlen; int started_daemon = 0; - struct iovec iov; - struct msghdr smsg; - char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; - struct cmsghdr *cmsg; - struct ucred *cred; - - #ifdef DEBUG init_logging("udevsend"); @@ -183,32 +176,10 @@ int main(int argc, char* argv[]) size = build_hotplugmsg(&msg, action, devpath, subsystem, seq); - /* prepare message with credentials to authenticate ourself */ - iov.iov_base = &msg; - iov.iov_len = size; - - smsg.msg_name = &saddr; - smsg.msg_namelen = addrlen; - smsg.msg_iov = &iov; - smsg.msg_iovlen = 1; - smsg.msg_control = cred_msg; - smsg.msg_controllen = CMSG_LEN(sizeof(struct ucred));; - smsg.msg_flags = 0; - - cmsg = CMSG_FIRSTHDR(&smsg); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_CREDENTIALS; - cmsg->cmsg_len = sizeof(cred_msg); - cred = (struct ucred *) CMSG_DATA(cmsg); - cred->uid = getuid(); - cred->gid = getgid(); - cred->pid = getpid(); - cred->pid = getpid(); - /* If we can't send, try to start daemon and resend message */ loop = UDEVSEND_CONNECT_RETRY; while (loop--) { - retval = sendmsg(sock, &smsg, 0); + retval = sendto(sock, &msg, size, 0, (struct sockaddr *)&saddr, addrlen); if (retval != -1) { retval = 0; goto close_and_exit; From 5a42932b9a783670ae3406fb2c3462036bb16d32 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Thu, 12 Feb 2004 01:24:54 -0800 Subject: [PATCH 0517/4284] [PATCH] udev kill extra bus_id compares in match_id Kill the extra bus_id check in match_id. This is wrong, especially since we check for rule matches with the parent devices on a given devices path. For example, given a device path of: /sys/devices/pci0000:01/0000:01:0c.0/host5/5:0:2:0 With this patch, the following rule will no longer match: BUS="scsi", ID="host5", NAME="sd-bus_id-host5" --- namedev.c | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/namedev.c b/namedev.c index 3e2182ae7b..59ec08c715 100644 --- a/namedev.c +++ b/namedev.c @@ -469,32 +469,19 @@ static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_devic static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { char path[SYSFS_PATH_MAX]; - int found; char *temp = NULL; /* we have to have a sysfs device for ID to work */ if (!sysfs_device) return -ENODEV; - found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); - if (strstr(temp, dev->id) != NULL) { - found = 1; - } else { - *temp = 0x00; - temp = strrchr(path, '/'); - dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); - if (strstr(temp, dev->id) != NULL) - found = 1; - } - if (!found) { - dbg("id doesn't match"); + if (strstr(temp, dev->id) == NULL) return -ENODEV; - } - - return 0; + else + return 0; } static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) From 3a8c51a771b5c67d5cf0002980254ef175668630 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Thu, 12 Feb 2004 01:25:28 -0800 Subject: [PATCH 0518/4284] [PATCH] udev add wild card compare for ID Allow wild card comparison of the ID. Using strcmp_pattern here also means we on longer match partial values, for example, a scsi rule like this won't match anymore: BUS="scsi", ID=":0", NAME="sdfoo-short-bus_id-1" But this now works: BUS="scsi", ID="*:0", NAME="sdfoo-bus_id-wild-card-1" --- namedev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 59ec08c715..e4e585b5cd 100644 --- a/namedev.c +++ b/namedev.c @@ -477,8 +477,9 @@ static int match_id(struct config_device *dev, struct sysfs_class_device *class_ strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); + temp++; dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); - if (strstr(temp, dev->id) == NULL) + if (strcmp_pattern(dev->id, temp) != 0) return -ENODEV; else return 0; From d45ea2b70c0cba69b02dae81d696a8b4c05c1771 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 01:29:40 -0800 Subject: [PATCH 0519/4284] [PATCH] stop using mode_t as different libcs define it in different ways :( --- namedev.h | 2 +- udev.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev.h b/namedev.h index 9cff3710d4..a0cdba6b16 100644 --- a/namedev.h +++ b/namedev.h @@ -74,7 +74,7 @@ struct perm_device { char name[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; - mode_t mode; + unsigned int mode; }; extern struct list_head config_device_list; diff --git a/udev.h b/udev.h index 108623e059..9e01e40492 100644 --- a/udev.h +++ b/udev.h @@ -40,7 +40,7 @@ struct udevice { char type; int major; int minor; - mode_t mode; + unsigned int mode; /* not mode_t due to conflicting definitions in different libcs */ char symlink[NAME_SIZE]; /* fields that help us in building strings */ From d026a35d747c0a993281408a9644ab843cf89fdd Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 18:57:06 -0800 Subject: [PATCH 0520/4284] [PATCH] more logging.h cleanups to be a bit more flexible. --- logging.h | 18 +++--------------- udev.c | 15 ++++++++++++--- udevd.c | 11 ++++++++--- udevinfo.c | 12 +++++++++--- udevsend.c | 11 ++++++++--- 5 files changed, 40 insertions(+), 27 deletions(-) diff --git a/logging.h b/logging.h index df0d7dedce..2ba2ac4965 100644 --- a/logging.h +++ b/logging.h @@ -57,23 +57,11 @@ } while (0) #endif -/* each program must declare this variable and function somewhere */ -extern unsigned char logname[42]; -extern int log_ok(void); - -static void log_message (int level, const char *format, ...) +extern void log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); -static inline void log_message (int level, const char *format, ...) -{ - va_list args; - if (!log_ok()) - return; - - va_start(args, format); - vsyslog(level, format, args); - va_end(args); -} +/* each program that uses syslog must declare this variable somewhere */ +extern unsigned char logname[42]; #undef init_logging static inline void init_logging(char *program_name) diff --git a/udev.c b/udev.c index 0f01fa41d2..9f10cc2125 100644 --- a/udev.c +++ b/udev.c @@ -38,12 +38,21 @@ /* global variables */ char **main_argv; char **main_envp; -unsigned char logname[42]; -int log_ok(void) +#ifdef LOG +unsigned char logname[42]; +void log_message (int level, const char *format, ...) { - return udev_log; + va_list args; + + if (!udev_log) + return; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); } +#endif static void sig_handler(int signum) { diff --git a/udevd.c b/udevd.c index 14616b9824..9fbb4e964b 100644 --- a/udevd.c +++ b/udevd.c @@ -51,12 +51,17 @@ LIST_HEAD(running_list); static void exec_queue_manager(void); static void msg_queue_manager(void); +#ifdef LOG unsigned char logname[42]; - -int log_ok(void) +void log_message (int level, const char *format, ...) { - return 1; + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); } +#endif static void msg_dump_queue(void) { diff --git a/udevinfo.c b/udevinfo.c index 103ebce08c..44eb142709 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -38,12 +38,18 @@ char **main_argv; int main_argc; -unsigned char logname[42]; -int log_ok(void) +#ifdef LOG +unsigned char logname[42]; +void log_message (int level, const char *format, ...) { - return 1; + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); } +#endif static int print_all_attributes(const char *path) { diff --git a/udevsend.c b/udevsend.c index b2fbcbbca6..c738fe2245 100644 --- a/udevsend.c +++ b/udevsend.c @@ -40,12 +40,17 @@ #include "udevd.h" #include "logging.h" +#ifdef LOG unsigned char logname[42]; - -int log_ok(void) +void log_message (int level, const char *format, ...) { - return 1; + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); } +#endif static inline char *get_action(void) { From bb051f66571121e2c9c97422b65aa89a37ec8feb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 19:48:07 -0800 Subject: [PATCH 0521/4284] [PATCH] fix problem where usb devices can be either the main device or the interface This fixes the bug of a long delay for mouse devices --- namedev.c | 50 ++++++++------ udevtest.c | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 230 insertions(+), 20 deletions(-) create mode 100644 udevtest.c diff --git a/namedev.c b/namedev.c index e4e585b5cd..68ca5dd306 100644 --- a/namedev.c +++ b/namedev.c @@ -260,12 +260,17 @@ static void apply_format(struct udevice *udev, unsigned char *string) } } +/* + * Note, we can have multiple files for different busses in here due + * to the mess that USB has for its device tree... + */ static struct bus_file { char *bus; char *file; } bus_files[] = { { .bus = "scsi", .file = "vendor" }, { .bus = "usb", .file = "idVendor" }, + { .bus = "usb", .file = "iInterface" }, { .bus = "usb-serial", .file = "detach_state" }, { .bus = "ide", .file = "detach_state" }, { .bus = "pci", .file = "vendor" }, @@ -285,30 +290,35 @@ static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) */ struct bus_file *b = &bus_files[0]; struct sysfs_attribute *tmpattr; - int loop; + int found = 0; + int loop = SECONDS_TO_WAIT_FOR_FILE; while (1) { - if (b->bus == NULL) - break; - if (strcmp(sysfs_device->bus, b->bus) == 0) { - tmpattr = NULL; - loop = SECONDS_TO_WAIT_FOR_FILE; - while (loop--) { - dbg("looking for file '%s' on bus '%s'", b->file, b->bus); - tmpattr = sysfs_get_device_attr(sysfs_device, b->file); - if (tmpattr) { - /* found it! */ - goto exit; - } - /* sleep to give the kernel a chance to create the file */ - sleep(1); - } - dbg("timed out waiting for '%s' file, continuing on anyway...", b->file); - goto exit; + if (b->bus == NULL) { + if (!found) + break; + /* sleep to give the kernel a chance to create the file */ + sleep(1); + --loop; + if (loop == 0) + break; + b = &bus_files[0]; } - b++; + if (strcmp(sysfs_device->bus, b->bus) == 0) { + found = 1; + dbg("looking for file '%s' on bus '%s'", b->file, b->bus); + tmpattr = sysfs_get_device_attr(sysfs_device, b->file); + if (tmpattr) { + /* found it! */ + goto exit; + } + dbg("can't find '%s' file", b->file); + } + ++b; } - dbg("did not find bus type '%s' on list of bus_id_files, contact greg@kroah.com", sysfs_device->bus); + if (!found) + dbg("did not find bus type '%s' on list of bus_id_files, " + "contact greg@kroah.com", sysfs_device->bus); exit: return; /* here to prevent compiler warning... */ } diff --git a/udevtest.c b/udevtest.c new file mode 100644 index 0000000000..9f10cc2125 --- /dev/null +++ b/udevtest.c @@ -0,0 +1,200 @@ +/* + * udev.c + * + * Userspace devfs + * + * Copyright (C) 2003,2004 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "udev_dbus.h" +#include "logging.h" +#include "namedev.h" +#include "udevdb.h" +#include "libsysfs/libsysfs.h" + +/* global variables */ +char **main_argv; +char **main_envp; + +#ifdef LOG +unsigned char logname[42]; +void log_message (int level, const char *format, ...) +{ + va_list args; + + if (!udev_log) + return; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif + +static void sig_handler(int signum) +{ + switch (signum) { + case SIGINT: + case SIGTERM: + sysbus_disconnect(); + udevdb_exit(); + exit(20 + signum); + default: + dbg("unhandled signal"); + } +} + +static inline char *get_action(void) +{ + char *action; + + action = getenv("ACTION"); + return action; +} + +static inline char *get_devpath(void) +{ + char *devpath; + + devpath = getenv("DEVPATH"); + return devpath; +} + +static inline char *get_seqnum(void) +{ + char *seqnum; + + seqnum = getenv("SEQNUM"); + return seqnum; +} + +static char *subsystem_blacklist[] = { + "net", + "scsi_host", + "scsi_device", + "usb_host", + "pci_bus", + "", +}; + +static int udev_hotplug(int argc, char **argv) +{ + char *action; + char *devpath; + char *subsystem; + int retval = -EINVAL; + int i; + struct sigaction act; + + action = get_action(); + if (!action) { + dbg ("no action?"); + goto exit; + } + + devpath = get_devpath(); + if (!devpath) { + dbg ("no devpath?"); + goto exit; + } + dbg("looking at '%s'", devpath); + + /* we only care about class devices and block stuff */ + if (!strstr(devpath, "class") && + !strstr(devpath, "block")) { + dbg("not a block or class device"); + goto exit; + } + + /* skip blacklisted subsystems */ + subsystem = argv[1]; + i = 0; + while (subsystem_blacklist[i][0] != '\0') { + if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { + dbg("don't care about '%s' devices", subsystem); + goto exit; + } + i++; + } + + /* connect to the system message bus */ + sysbus_connect(); + + /* initialize our configuration */ + udev_init_config(); + + /* initialize udev database */ + retval = udevdb_init(UDEVDB_DEFAULT); + if (retval != 0) { + dbg("unable to initialize database"); + goto exit_sysbus; + } + + /* set up a default signal handler for now */ + act.sa_handler = sig_handler; + sigemptyset (&act.sa_mask); + act.sa_flags = SA_RESTART; + sigaction(SIGINT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + + /* initialize the naming deamon */ + namedev_init(); + + if (strcmp(action, "add") == 0) + retval = udev_add_device(devpath, subsystem); + + else if (strcmp(action, "remove") == 0) + retval = udev_remove_device(devpath, subsystem); + + else { + dbg("unknown action '%s'", action); + retval = -EINVAL; + } + udevdb_exit(); + +exit_sysbus: + /* disconnect from the system message bus */ + sysbus_disconnect(); + +exit: + if (retval > 0) + retval = 0; + + return -retval; +} + +int main(int argc, char **argv, char **envp) +{ + main_argv = argv; + main_envp = envp; + + init_logging("udev"); + dbg("version %s", UDEV_VERSION); + + return udev_hotplug(argc, argv); +} + + From eb10f97f2816ae09f949060a2bb8c46b8c1788ed Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 20:19:21 -0800 Subject: [PATCH 0522/4284] [PATCH] add udevtest program to build Also fix up some other dependancy issues in the Makefile. Thanks to Olaf Hering for pointing them out. --- Makefile | 23 ++++++++++++++-------- udev-add.c | 56 ++++++++++++++++++++++++++++++++---------------------- udev.c | 2 +- udev.h | 2 +- udevtest.c | 51 +++++++++---------------------------------------- 5 files changed, 59 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index f53e7ca2fd..cb9dfdd3d8 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ ROOT = udev DAEMON = udevd SENDER = udevsend HELPER = udevinfo +TESTER = udevtest VERSION = 016_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -168,7 +169,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(SENDER) $(DAEMON) $(HELPER) +all: $(ROOT) $(SENDER) $(DAEMON) $(HELPER) $(TESTER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -178,8 +179,6 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(HELPER) -C $$target $@ ; \ done ; \ -$(ROOT): $(LIBC) - $(ARCH_LIB_OBJS) : $(CRT0) $(CRT0): @@ -250,21 +249,29 @@ $(LOCAL_CFG_DIR)/udev.conf: $(OBJS): $(GEN_HEADERS) -udev.o: $(GEN_HEADERS) +$(ROOT).o: $(GEN_HEADERS) +$(TESTER).o: $(GEN_HEADERS) +$(HELPER).o: $(GEN_HEADERS) +$(DAEMON).o: $(GEN_HEADERS) +$(SENDER).o: $(GEN_HEADERS) -$(ROOT): udev.o $(OBJS) $(HEADERS) $(GEN_HEADERS) +$(ROOT): $(ROOT).o $(OBJS) $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(HELPER): $(HEADERS) udevinfo.o $(OBJS) +$(TESTER): $(TESTER).o $(OBJS) $(HEADERS) $(LIBC) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevtest.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $@ + +$(HELPER): $(HELPER).o $(OBJS) $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(DAEMON): udevd.h $(GEN_HEADERS) udevd.o +$(DAEMON): $(DAEMON).o udevd.h $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(SENDER): udevd.h $(GEN_HEADERS) udevsend.o +$(SENDER): $(SENDER).o udevd.h $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ diff --git a/udev-add.c b/udev-add.c index fedc8f0fc8..8867c8f5af 100644 --- a/udev-add.c +++ b/udev-add.c @@ -99,7 +99,7 @@ static int create_path(char *file) return 0; } -static int create_node(struct udevice *dev) +static int create_node(struct udevice *dev, int fake) { struct stat stats; char filename[255]; @@ -137,16 +137,20 @@ static int create_node(struct udevice *dev) info("creating device node '%s'", filename); dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); - retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor)); - if (retval != 0) - dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", - filename, dev->mode, dev->major, dev->minor, strerror(errno)); + if (!fake) { + retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor)); + if (retval != 0) + dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", + filename, dev->mode, dev->major, dev->minor, strerror(errno)); + } dbg("chmod(%s, %#o)", filename, dev->mode); - retval = chmod(filename, dev->mode); - if (retval != 0) - dbg("chmod(%s, %#o) failed with error '%s'", - filename, dev->mode, strerror(errno)); + if (!fake) { + retval = chmod(filename, dev->mode); + if (retval != 0) + dbg("chmod(%s, %#o) failed with error '%s'", + filename, dev->mode, strerror(errno)); + } if (dev->owner[0] != '\0') { char *endptr; @@ -195,8 +199,9 @@ static int create_node(struct udevice *dev) strncpy(filename, udev_root, sizeof(filename)); strncat(filename, linkname, sizeof(filename)); dbg("symlink '%s' to node '%s' requested", filename, dev->name); - if (strrchr(linkname, '/')) - create_path(filename); + if (!fake) + if (strrchr(linkname, '/')) + create_path(filename); /* optimize relative link */ linktarget[0] = '\0'; @@ -219,7 +224,7 @@ static int create_node(struct udevice *dev) /* unlink existing non-directories to ensure that our symlink * is created */ - if (lstat(filename, &stats) == 0) { + if (!fake && (lstat(filename, &stats) == 0)) { if ((stats.st_mode & S_IFMT) != S_IFDIR) { if (unlink(filename)) dbg("unlink(%s) failed with error '%s'", @@ -228,10 +233,12 @@ static int create_node(struct udevice *dev) } dbg("symlink(%s, %s)", linktarget, filename); - retval = symlink(linktarget, filename); - if (retval != 0) - dbg("symlink(%s, %s) failed with error '%s'", - linktarget, filename, strerror(errno)); + if (!fake) { + retval = symlink(linktarget, filename); + if (retval != 0) + dbg("symlink(%s, %s) failed with error '%s'", + linktarget, filename, strerror(errno)); + } } } @@ -289,7 +296,7 @@ exit: return retval; } -int udev_add_device(char *path, char *subsystem) +int udev_add_device(char *path, char *subsystem, int fake) { struct sysfs_class_device *class_dev = NULL; struct udevice dev; @@ -321,15 +328,18 @@ int udev_add_device(char *path, char *subsystem) if (retval != 0) goto exit; - retval = udevdb_add_dev(path, &dev); - if (retval != 0) - dbg("udevdb_add_dev failed, but we are going to try to create the node anyway. " - "But remove might not work properly for this device."); + if (!fake) { + retval = udevdb_add_dev(path, &dev); + if (retval != 0) + dbg("udevdb_add_dev failed, but we are going to try " + "to create the node anyway. But remove might not " + "work properly for this device."); + } dbg("name='%s'", dev.name); - retval = create_node(&dev); + retval = create_node(&dev, fake); - if (retval == 0) + if ((retval == 0) && (!fake)) sysbus_send_create(&dev, path); exit: diff --git a/udev.c b/udev.c index 9f10cc2125..ce6d6ce9df 100644 --- a/udev.c +++ b/udev.c @@ -164,7 +164,7 @@ static int udev_hotplug(int argc, char **argv) namedev_init(); if (strcmp(action, "add") == 0) - retval = udev_add_device(devpath, subsystem); + retval = udev_add_device(devpath, subsystem, 0); else if (strcmp(action, "remove") == 0) retval = udev_remove_device(devpath, subsystem); diff --git a/udev.h b/udev.h index 9e01e40492..00f1361016 100644 --- a/udev.h +++ b/udev.h @@ -56,7 +56,7 @@ do { \ strncpy(to, from, sizeof(to)-1); \ } while (0) -extern int udev_add_device(char *path, char *subsystem); +extern int udev_add_device(char *path, char *subsystem, int fake); extern int udev_remove_device(char *path, char *subsystem); extern void udev_init_config(void); extern int parse_get_pair(char **orig_string, char **left, char **right); diff --git a/udevtest.c b/udevtest.c index 9f10cc2125..dd8375aa5c 100644 --- a/udevtest.c +++ b/udevtest.c @@ -29,10 +29,8 @@ #include "udev.h" #include "udev_version.h" -#include "udev_dbus.h" #include "logging.h" #include "namedev.h" -#include "udevdb.h" #include "libsysfs/libsysfs.h" /* global variables */ @@ -45,12 +43,15 @@ void log_message (int level, const char *format, ...) { va_list args; - if (!udev_log) - return; +// if (!udev_log) +// return; + /* FIXME use level... */ va_start(args, format); - vsyslog(level, format, args); + vprintf(format, args); va_end(args); + if (format[strlen(format)-1] != '\n') + printf("\n"); } #endif @@ -59,8 +60,6 @@ static void sig_handler(int signum) switch (signum) { case SIGINT: case SIGTERM: - sysbus_disconnect(); - udevdb_exit(); exit(20 + signum); default: dbg("unhandled signal"); @@ -102,22 +101,15 @@ static char *subsystem_blacklist[] = { static int udev_hotplug(int argc, char **argv) { - char *action; char *devpath; char *subsystem; int retval = -EINVAL; int i; struct sigaction act; - action = get_action(); - if (!action) { - dbg ("no action?"); - goto exit; - } - - devpath = get_devpath(); + devpath = argv[1]; if (!devpath) { - dbg ("no devpath?"); + dbg("no devpath?"); goto exit; } dbg("looking at '%s'", devpath); @@ -140,19 +132,9 @@ static int udev_hotplug(int argc, char **argv) i++; } - /* connect to the system message bus */ - sysbus_connect(); - /* initialize our configuration */ udev_init_config(); - /* initialize udev database */ - retval = udevdb_init(UDEVDB_DEFAULT); - if (retval != 0) { - dbg("unable to initialize database"); - goto exit_sysbus; - } - /* set up a default signal handler for now */ act.sa_handler = sig_handler; sigemptyset (&act.sa_mask); @@ -163,21 +145,7 @@ static int udev_hotplug(int argc, char **argv) /* initialize the naming deamon */ namedev_init(); - if (strcmp(action, "add") == 0) - retval = udev_add_device(devpath, subsystem); - - else if (strcmp(action, "remove") == 0) - retval = udev_remove_device(devpath, subsystem); - - else { - dbg("unknown action '%s'", action); - retval = -EINVAL; - } - udevdb_exit(); - -exit_sysbus: - /* disconnect from the system message bus */ - sysbus_disconnect(); + retval = udev_add_device(devpath, subsystem, 1); exit: if (retval > 0) @@ -191,7 +159,6 @@ int main(int argc, char **argv, char **envp) main_argv = argv; main_envp = envp; - init_logging("udev"); dbg("version %s", UDEV_VERSION); return udev_hotplug(argc, argv); From 5a98bc58e429bd6f4b1da10ef965d8b3f130fbe9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 22:41:55 -0800 Subject: [PATCH 0523/4284] [PATCH] update klibc to version .107 --- klibc/klibc/include/endian.h | 1 + klibc/klibc/include/klibc/compiler.h | 34 ++++++++++++++++++++++++++++ klibc/version | 2 +- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/klibc/klibc/include/endian.h b/klibc/klibc/include/endian.h index 10dbbd8a89..44f89ccbbc 100644 --- a/klibc/klibc/include/endian.h +++ b/klibc/klibc/include/endian.h @@ -5,6 +5,7 @@ #ifndef _ENDIAN_H #define _ENDIAN_H +#include #include /* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or diff --git a/klibc/klibc/include/klibc/compiler.h b/klibc/klibc/include/klibc/compiler.h index 64b8c54158..49872b89d4 100644 --- a/klibc/klibc/include/klibc/compiler.h +++ b/klibc/klibc/include/klibc/compiler.h @@ -65,4 +65,38 @@ # define __unusedfunc #endif +/* "pure" function: + + Many functions have no effects except the return value and their + return value depends only on the parameters and/or global + variables. Such a function can be subject to common subexpression + elimination and loop optimization just as an arithmetic operator + would be. These functions should be declared with the attribute + `pure'. +*/ +#ifdef __GNUC__ +# define __attribute_pure__ __attribute__((pure)) +#else +# define __attribute_pure__ +#endif + +/* "const" function: + + Many functions do not examine any values except their arguments, + and have no effects except the return value. Basically this is + just slightly more strict class than the `pure' attribute above, + since function is not allowed to read global memory. + + Note that a function that has pointer arguments and examines the + data pointed to must _not_ be declared `const'. Likewise, a + function that calls a non-`const' function usually must not be + `const'. It does not make sense for a `const' function to return + `void'. +*/ +#ifdef __GNUC__ +# define __attribute_const__ __attribute__((const)) +#else +# define __attribute_const__ +#endif + #endif diff --git a/klibc/version b/klibc/version index f14cf6a1e0..4b0a18ac52 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.107 +0.108 From ba053b91e145d7bb88bbd34856f6a6a86e3e718b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 22:42:14 -0800 Subject: [PATCH 0524/4284] [PATCH] fix bug in permission handling. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 68ca5dd306..018fd452e9 100644 --- a/namedev.c +++ b/namedev.c @@ -112,7 +112,7 @@ int add_perm_dev(struct perm_device *new_dev) /* update the values if we already have the device */ list_for_each_entry(dev, &perm_device_list, node) { - if (strcmp_pattern(new_dev->name, dev->name)) + if (strcmp(new_dev->name, dev->name)) continue; copy_var(dev, new_dev, mode); copy_string(dev, new_dev, owner); From 00866ed2a1f755eb027c84827fed1ed77364d436 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 12 Feb 2004 22:51:44 -0800 Subject: [PATCH 0525/4284] [PATCH] udev - keep private data out of the database? Shouldn't we keep the temporary strings out of the database, or is this information useful for something? It cuts the length of the data from 628 to 275 bytes. --- udev.h | 14 +++++++++----- udevdb.c | 7 ++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/udev.h b/udev.h index 00f1361016..e615b4c8bb 100644 --- a/udev.h +++ b/udev.h @@ -24,6 +24,7 @@ #define UDEV_H #include "libsysfs/libsysfs.h" +#include #include #define COMMENT_CHARACTER '#' @@ -33,6 +34,9 @@ #define GROUP_SIZE 30 #define MODE_SIZE 8 +/* length of public data */ +#define UDEVICE_LEN (offsetof(struct udevice, bus_id)) + struct udevice { char name[NAME_SIZE]; char owner[OWNER_SIZE]; @@ -43,11 +47,11 @@ struct udevice { unsigned int mode; /* not mode_t due to conflicting definitions in different libcs */ char symlink[NAME_SIZE]; - /* fields that help us in building strings */ - unsigned char bus_id[SYSFS_NAME_LEN]; - unsigned char program_result[NAME_SIZE]; - unsigned char kernel_number[NAME_SIZE]; - unsigned char kernel_name[NAME_SIZE]; + /* private data that help us in building strings */ + char bus_id[SYSFS_NAME_LEN]; + char program_result[NAME_SIZE]; + char kernel_number[NAME_SIZE]; + char kernel_name[NAME_SIZE]; }; #define strfieldcpy(to, from) \ diff --git a/udevdb.c b/udevdb.c index c4e064fc11..e657fedcb2 100644 --- a/udevdb.c +++ b/udevdb.c @@ -58,8 +58,8 @@ int udevdb_add_dev(const char *path, const struct udevice *dev) key.dsize = strlen(keystr) + 1; data.dptr = (void *)dev; - data.dsize = sizeof(*dev); - + data.dsize = UDEVICE_LEN; + return tdb_store(udevdb, key, data, TDB_REPLACE); } @@ -77,7 +77,8 @@ int udevdb_get_dev(const char *path, struct udevice *dev) if (data.dptr == NULL || data.dsize == 0) return -ENODEV; - memcpy(dev, data.dptr, sizeof(*dev)); + memset(dev, 0, sizeof(struct udevice)); + memcpy(dev, data.dptr, UDEVICE_LEN); return 0; } From 66a90217605c149fe06f3edf0f3c491f28e640b6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 23:08:22 -0800 Subject: [PATCH 0526/4284] [PATCH] remove the database at startup. --- etc/init.d/udev | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/etc/init.d/udev b/etc/init.d/udev index 364a9aa5f7..437556c3fb 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -49,6 +49,12 @@ case "$1" in if [ ! -d $udev_root ]; then mkdir $udev_root fi + + # remove the database if it is there as we always want to start fresh + if [ -f $udev_root/.udevdb ]; then + rm -f $udev_root/.udevdb + fi + # propogate /udev from /sys - we only need this while we do not # have initramfs and an early user-space with which to do early # device bring up From 552a4d426f24364a13d92a31bafdb37649fcb0f1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 23:20:50 -0800 Subject: [PATCH 0527/4284] [PATCH] remove the .udev.tdb when installing or uninstalling to be safe. --- Makefile | 2 ++ etc/init.d/udev | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index cb9dfdd3d8..2ecfd3a968 100644 --- a/Makefile +++ b/Makefile @@ -361,6 +361,7 @@ install: install-config install-dbus-policy all $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 - rm -f $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug + - rm -f $(udevdir)/.udev.tdb - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ @@ -382,6 +383,7 @@ uninstall: uninstall-dbus-policy - rm $(sbindir)/$(HELPER) - rmdir $(hotplugdir) - rmdir $(configdir) + - rm $(udevdir)/.udev.tdb - rmdir $(udevdir) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff --git a/etc/init.d/udev b/etc/init.d/udev index 437556c3fb..8a29f11975 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -51,8 +51,8 @@ case "$1" in fi # remove the database if it is there as we always want to start fresh - if [ -f $udev_root/.udevdb ]; then - rm -f $udev_root/.udevdb + if [ -f $udev_root/.udev.tdb ]; then + rm -f $udev_root/.udev.tdb fi # propogate /udev from /sys - we only need this while we do not From 1a3b802ff219a82b4a39cd3d7cb7bb037b396216 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 23:30:11 -0800 Subject: [PATCH 0528/4284] [PATCH] update the init.d udev script based on a patch from Red Hat. --- etc/init.d/udev | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/etc/init.d/udev b/etc/init.d/udev index 8a29f11975..69c1bab74e 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -9,6 +9,7 @@ . /etc/udev/udev.conf +prog=udev sysfs_dir=/sys bin=/sbin/udev @@ -38,9 +39,9 @@ run_udev () { fi done done + return 0 } - case "$1" in start) if [ ! -d $sysfs_dir ]; then @@ -58,22 +59,29 @@ case "$1" in # propogate /udev from /sys - we only need this while we do not # have initramfs and an early user-space with which to do early # device bring up - action "Creating initial udev device nodes: " /bin/true export ACTION=add + echo -n $"Creating initial udev device nodes:" run_udev + success /bin/true + echo + touch /var/lock/subsys/udev ;; stop) # be careful - action "Removing udev device nodes: " /bin/true + echo -n $"Removing udev device nodes: " export ACTION=remove run_udev + success /bin/true + echo + rm -f /var/lock/subsys/udev ;; status) - if [ -d $udev_root ]; then - echo "the udev device node directory exists" - else - echo "the udev device node directory does not exist" + if [ -f /var/lock/subsys/udev ]; then + echo $"$prog has run" + exit 0 fi + echo $"$prog is stopped" + exit 3 ;; restart) $0 stop From 1659326d724e5f94d94d43243e087c54f8508e2b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 23:40:56 -0800 Subject: [PATCH 0529/4284] [PATCH] add some .spec file changes from Red Hat. --- udev.spec | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/udev.spec b/udev.spec index 20f4154998..0b142f0942 100644 --- a/udev.spec +++ b/udev.spec @@ -54,12 +54,18 @@ make CC="gcc $RPM_OPT_FLAGS" \ %endif %if %{log} USE_LOG=true \ +%else + USE_LOG=false \ %endif %if %{dbus} USE_DBUS=true \ +%else + USE_DBUS=false \ %endif %if %{debug} DEBUG=true \ +%else + DEBUG=false \ %endif # now build udevd on it's own, as it can't handle being built with klibc @@ -94,6 +100,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udevd %attr(755,root,root) /udev/ %attr(755,root,root) /etc/udev/ +%attr(755,root,root) %dir %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf %config(noreplace) %attr(0644,root,root) /etc/udev/udev.rules %config(noreplace) %attr(0644,root,root) /etc/udev/udev.permissions @@ -105,6 +112,9 @@ rm -rf $RPM_BUILD_ROOT %attr(0644,root,root) %{_mandir}/man8/udev*.8* %changelog +* Thu Feb 12 2004 Greg Kroah-Hartman +- add some changes from the latest Fedora udev release. + * Mon Feb 2 2004 Greg Kroah-Hartman - add udevsend, and udevd to the files - add ability to build udevd with glibc after the rest is build with klibc From 89c941084f175904fed110fc254eac0c1897f036 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 12 Feb 2004 23:43:31 -0800 Subject: [PATCH 0530/4284] [PATCH] fix offsetof() define in klibc. --- klibc/klibc/include/stddef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/klibc/klibc/include/stddef.h b/klibc/klibc/include/stddef.h index 900c147cd8..125d2352ec 100644 --- a/klibc/klibc/include/stddef.h +++ b/klibc/klibc/include/stddef.h @@ -19,6 +19,6 @@ #endif #undef offsetof -#define offsetof(t,m) ((size_t)&((t *)0->m)) +#define offsetof(t,m) ((size_t)&((t *)0)->m) #endif /* _STDDEF_H */ From 0c040e8d7cc0d027a240769dd7455679beca521d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 13 Feb 2004 00:35:30 -0800 Subject: [PATCH 0531/4284] [PATCH] add udev_log to the documentation. --- udev.8 | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/udev.8 b/udev.8 index 0c8f2b1e60..aea922675a 100644 --- a/udev.8 +++ b/udev.8 @@ -57,6 +57,11 @@ This is the location of the udev rules file. The default value for this is This is the location of the udev permission file. The default value for this is .I /etc/udev/udev.permissions .TP +.B udev_log +If you want udev to log some information to the syslog for every node created or +removed. The default value for this is +.I yes +.TP .B default_mode This is the default mode for all nodes that have no explicit match in the permissions file. The default value for this is @@ -88,6 +93,9 @@ udev_rules="/etc/udev/udev.rules" # udev_permissions - The name and location of the udev permission file udev_permissions="/etc/udev/udev.permissions" +# udev_log - set to "yes" if you want logging, else "no" +udev_log="yes" + # default_mode - set the default mode for all nodes that have no # explicit match in the permissions file default_mode="0666" From cbb576b91dea8bd84a9fdd147b6b4cbe757dd198 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Fri, 13 Feb 2004 00:48:36 -0800 Subject: [PATCH 0532/4284] [PATCH] more udev-016/extras/multipath > Hello, > > incremental to udev-016/extras/multipath, > > * don't rely on the linux symlink in the udev/klibc dir since > udev build doesn't use it anymore. This corrects build breakage > * remove make_dm_node fn & call. Rely on udev for this. > > The first patch is to be applied. > The second is conditioned by udev dealing correctly with devmap names. > > For this I can suggest a CALLOUT rule like this : > KERNEL="dm-[0-9]*", PROGRAM="/tmp/name_devmap %M %m", NAME="%k", > SYMLINK="%c" > > With name_devmap like : > #!/bin/sh > /usr/sbin/dmsetup ls|/bin/grep "$1, $2"|/usr/bin/awk '{print $1}' > ok I coded the suggested tool. it works with the following rule : KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" I don't know if it's right to keep this tools packaged with multipath because it's widely more general. Maybe Joe should merge it in the device-mapper package or provide the functionnality through dmsetup ? --- extras/multipath/ChangeLog | 4 +++ extras/multipath/Makefile | 10 ++++-- extras/multipath/README | 8 +++++ extras/multipath/devmap_name.c | 60 ++++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 extras/multipath/devmap_name.c diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index c3361ff8e8..2cc492a192 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,4 +1,8 @@ 2004-02-04 multipath-016 + * add devmap_name proggy for udev to name devmaps as per their + internal DM name and not only by their sysfs enum name (dm-*) + The corresponding udev.rules line is : + KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" * remove make_dm_node fn & call. Rely on udev for this. * don't rely on the linux symlink in the udev/klibc dir since udev build doesn't use it anymore. This corrects build breakage diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index caf24bbd90..c039e2a19f 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -36,29 +36,35 @@ recurse: $(MAKE) KERNEL_DIR=$(KERNEL_DIR) -C $$dir ; \ done $(MAKE) $(EXEC) + $(MAKE) devmap_name all: recurse @echo "" @echo "Make complete" - $(EXEC): $(OBJS) $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(SYSFSOBJS) $(DMOBJS) $(LIB) $(LIBGCC) strip $(EXEC) +devmap_name: devmap_name.o + $(LD) -o devmap_name $(CRT0) devmap_name.o $(DMOBJS) $(LIB) $(LIBGCC) + strip devmap_name + clean: - rm -f core *.o $(EXEC) + rm -f core *.o $(EXEC) devmap_name $(MAKE) -C libdevmapper clean install: install -d $(bindir) install -m 755 $(EXEC) $(bindir)/ + install -m 755 devmap_name $(bindir)/ install -d /etc/hotplug.d/scsi/ install -m 755 multipath.hotplug /etc/hotplug.d/scsi/ uninstall: rm /etc/hotplug.d/scsi/multipath.hotplug rm $(bindir)/$(EXEC) + rm $(bindir)/devmap_name # Code dependencies main.o: main.c main.h sg_include.h diff --git a/extras/multipath/README b/extras/multipath/README index 417a0d38e4..80945db438 100644 --- a/extras/multipath/README +++ b/extras/multipath/README @@ -8,6 +8,8 @@ o libsysfs : comes with sysutils or udev See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ o Linux kernel 2.6.0 with udm5 patchset http://people.sistina.com/~thornber/dm/ +o udev + See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ How it works : ============== @@ -53,6 +55,12 @@ struct multipath { When mp is filled, the device maps are fed to the kernel through libdevmapper. +The naming of the corresponding block device is handeld +by udev with the help of the devmap_name proggy. It is +called by the following rule in /etc/udev/udev.rules : +KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \ +NAME="%k", SYMLINK="%c" + Notes : ======= diff --git a/extras/multipath/devmap_name.c b/extras/multipath/devmap_name.c new file mode 100644 index 0000000000..08e526e072 --- /dev/null +++ b/extras/multipath/devmap_name.c @@ -0,0 +1,60 @@ +#include "libdevmapper/libdevmapper.h" + +#include +#include +#include +#include + +static void usage(char * progname) { + fprintf(stderr, "usage : %s major minor\n", progname); + exit(1); +} + +int main(int argc, char **argv) +{ + int r = 0; + struct dm_names *names; + unsigned next = 0; + int major, minor; + + /* sanity check */ + if (argc != 3) + usage(argv[0]); + + major = atoi(argv[1]); + minor = atoi(argv[2]); + + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) + return 0; + + if (!dm_task_run(dmt)) + goto out; + + if (!(names = dm_task_get_names(dmt))) + goto out; + + if (!names->dev) { + printf("No devices found\n"); + goto out; + } + + do { + names = (void *) names + next; + if ((int) MAJOR(names->dev) == major && + (int) MINOR(names->dev) == minor) { + printf("%s\n", names->name); + goto out; + } + next = names->next; + } while (next); + + /* No correspondance found */ + r = 1; + + out: + dm_task_destroy(dmt); + return r; +} + From 09b7985cf611df26fc756e0b8025a260fc4a4948 Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Fri, 13 Feb 2004 00:53:10 -0800 Subject: [PATCH 0533/4284] [PATCH] more udev-016/extras/multipath incremental to udev-016/extras/multipath-0.0.16.3, * add a GROUP_BY_SERIAL flag. This should be useful for controlers that activate their spare paths on simple IO submition with a penalty. The StorageWorks HW defaults to this mode, even if the MULTIBUS mode is OK. * remove unused sg_err.c * big restructuring : split devinfo.c from main.c. Export : * void basename (char *, char *); * int get_serial (int, char *); * int get_lun_strings (char *, char *, char *, char *); * int get_evpd_wwid(char *, char *); * long get_disk_size (char *); Now we see clearly what is expected from an external package like scsi_id. * stop passing struct env as param --- extras/multipath/ChangeLog | 12 + extras/multipath/Makefile | 4 +- extras/multipath/devinfo.c | 204 ++++++ extras/multipath/devinfo.h | 19 + extras/multipath/main.c | 255 +++----- extras/multipath/main.h | 9 +- extras/multipath/sg_err.c | 1197 ------------------------------------ 7 files changed, 313 insertions(+), 1387 deletions(-) create mode 100644 extras/multipath/devinfo.c create mode 100644 extras/multipath/devinfo.h delete mode 100644 extras/multipath/sg_err.c diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index 2cc492a192..31f6c48f69 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,4 +1,16 @@ 2004-02-04 multipath-016 + * add a GROUP_BY_SERIAL flag. This should be useful for + controlers that activate they spare paths on simple IO + submition with a penalty. The StorageWorks HW defaults to + this mode, even if the MULTIBUS mode is OK. + * remove unused sg_err.c + * big restructuring : split devinfo.c from main.c. Export : + * void basename (char *, char *); + * int get_serial (int, char *); + * int get_lun_strings (char *, char *, char *, char *); + * int get_evpd_wwid(char *, char *); + * long get_disk_size (char *); + * stop passing struct env as param * add devmap_name proggy for udev to name devmaps as per their internal DM name and not only by their sysfs enum name (dm-*) The corresponding udev.rules line is : diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index c039e2a19f..eeec25b893 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -18,7 +18,7 @@ CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. -OBJS = main.o +OBJS = devinfo.o main.o CRT0 = ../../klibc/klibc/crt0.o LIB = ../../klibc/klibc/libc.a LIBGCC := $(shell $(CC) -print-libgcc-file-name ) @@ -67,4 +67,4 @@ uninstall: rm $(bindir)/devmap_name # Code dependencies -main.o: main.c main.h sg_include.h +main.o: main.c main.h sg_include.h devinfo.h diff --git a/extras/multipath/devinfo.c b/extras/multipath/devinfo.c new file mode 100644 index 0000000000..a6b089f517 --- /dev/null +++ b/extras/multipath/devinfo.c @@ -0,0 +1,204 @@ +#include +#include +#include +#include +#include +#include +#include "devinfo.h" +#include "sg_include.h" + +#define FILE_NAME_SIZE 255 + +void +basename(char * str1, char * str2) +{ + char *p = str1 + (strlen(str1) - 1); + + while (*--p != '/') + continue; + strcpy(str2, ++p); +} + +static int +do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, + void *resp, int mx_resp_len, int noisy) +{ + unsigned char inqCmdBlk[INQUIRY_CMDLEN] = + { INQUIRY_CMD, 0, 0, 0, 0, 0 }; + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_io_hdr io_hdr; + + if (cmddt) + inqCmdBlk[1] |= 2; + if (evpd) + inqCmdBlk[1] |= 1; + inqCmdBlk[2] = (unsigned char) pg_op; + inqCmdBlk[4] = (unsigned char) mx_resp_len; + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (inqCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_b); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = mx_resp_len; + io_hdr.dxferp = resp; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sense_b; + io_hdr.timeout = DEF_TIMEOUT; + + if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { + perror("SG_IO (inquiry) error"); + return -1; + } + + /* treat SG_ERR here to get rid of sg_err.[ch] */ + io_hdr.status &= 0x7e; + if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && + (0 == io_hdr.driver_status)) + return 0; + if ((SCSI_CHECK_CONDITION == io_hdr.status) || + (SCSI_COMMAND_TERMINATED == io_hdr.status) || + (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { + if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { + int sense_key; + unsigned char * sense_buffer = io_hdr.sbp; + if (sense_buffer[0] & 0x2) + sense_key = sense_buffer[1] & 0xf; + else + sense_key = sense_buffer[2] & 0xf; + if(RECOVERED_ERROR == sense_key) + return 0; + } + } + return -1; +} + +int +get_serial (char * str, char * devname) +{ + int fd; + int len; + char buff[MX_ALLOC_LEN + 1]; + + if ((fd = open(devname, O_RDONLY)) < 0) + return 0; + + if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { + len = buff[3]; + if (len > 0) { + memcpy(str, buff + 4, len); + buff[len] = '\0'; + } + close(fd); + return 1; + } + close(fd); + return 0; +} + +int +get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname) +{ + int fd; + char buff[36]; + char attr_path[FILE_NAME_SIZE]; + char sysfs_path[FILE_NAME_SIZE]; + char basedev[FILE_NAME_SIZE]; + + if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { + /* sysfs style */ + basename(devname, basedev); + + sprintf(attr_path, "%s/block/%s/device/vendor", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + vendor_id, 8)) return 0; + + sprintf(attr_path, "%s/block/%s/device/model", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + product_id, 16)) return 0; + + sprintf(attr_path, "%s/block/%s/device/rev", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + rev, 4)) return 0; + } else { + /* ioctl style */ + if ((fd = open(devname, O_RDONLY)) < 0) + return 0; + if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) + return 0; + memcpy(vendor_id, &buff[8], 8); + memcpy(product_id, &buff[16], 16); + memcpy(rev, &buff[32], 4); + close(fd); + return 1; + } + return 0; +} + +static void +sprint_wwid(char * buff, const char * str) +{ + int i; + const char *p; + char *cursor; + unsigned char c; + + p = str; + cursor = buff; + for (i = 0; i <= WWID_SIZE / 2 - 1; i++) { + c = *p++; + sprintf(cursor, "%.2x", (int) (unsigned char) c); + cursor += 2; + } + buff[WWID_SIZE - 1] = '\0'; +} + +/* get EVPD page 0x83 off 8 */ +/* tested ok with StorageWorks */ +int +get_evpd_wwid(char * devname, char * wwid) +{ + int fd; + char buff[64]; + + if ((fd = open(devname, O_RDONLY)) < 0) + return 0; + + if (0 == do_inq(fd, 0, 1, 0x83, buff, sizeof (buff), 1)) { + sprint_wwid(wwid, &buff[8]); + close(fd); + return 1; /* success */ + } + close(fd); + return 0; /* not good */ +} + +long +get_disk_size (char * devname) { + long size; + int fd; + char attr_path[FILE_NAME_SIZE]; + char sysfs_path[FILE_NAME_SIZE]; + char buff[FILE_NAME_SIZE]; + char basedev[FILE_NAME_SIZE]; + + if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { + basename(devname, basedev); + sprintf(attr_path, "%s/block/%s/size", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, buff, + FILE_NAME_SIZE * sizeof(char))) + return -1; + size = atoi(buff); + return size; + } else { + if ((fd = open(devname, O_RDONLY)) < 0) + return -1; + if(!ioctl(fd, BLKGETSIZE, &size)) + return size; + } + return -1; +} + diff --git a/extras/multipath/devinfo.h b/extras/multipath/devinfo.h new file mode 100644 index 0000000000..53f2473027 --- /dev/null +++ b/extras/multipath/devinfo.h @@ -0,0 +1,19 @@ +#define INQUIRY_CMDLEN 6 +#define INQUIRY_CMD 0x12 +#define SENSE_BUFF_LEN 32 +#define DEF_TIMEOUT 60000 +#define RECOVERED_ERROR 0x01 +#define MX_ALLOC_LEN 255 +#define WWID_SIZE 33 +#define BLKGETSIZE _IO(0x12,96) + +/* exerpt from "sg_err.h" */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SG_ERR_DRIVER_SENSE 0x08 + +void basename (char *, char *); +int get_serial (char *, char *); +int get_lun_strings (char *, char *, char *, char *); +int get_evpd_wwid(char *, char *); +long get_disk_size (char *); diff --git a/extras/multipath/main.c b/extras/multipath/main.c index d4dd89a305..6ea9a064e1 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -28,150 +28,7 @@ #include #include "libdevmapper/libdevmapper.h" #include "main.h" - -static int -do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, - void *resp, int mx_resp_len, int noisy) -{ - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = - { INQUIRY_CMD, 0, 0, 0, 0, 0 }; - unsigned char sense_b[SENSE_BUFF_LEN]; - struct sg_io_hdr io_hdr; - - if (cmddt) - inqCmdBlk[1] |= 2; - if (evpd) - inqCmdBlk[1] |= 1; - inqCmdBlk[2] = (unsigned char) pg_op; - inqCmdBlk[4] = (unsigned char) mx_resp_len; - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_b); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = mx_resp_len; - io_hdr.dxferp = resp; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sense_b; - io_hdr.timeout = DEF_TIMEOUT; - - if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { - perror("SG_IO (inquiry) error"); - return -1; - } - - /* treat SG_ERR here to get rid of sg_err.[ch] */ - io_hdr.status &= 0x7e; - if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && - (0 == io_hdr.driver_status)) - return 0; - if ((SCSI_CHECK_CONDITION == io_hdr.status) || - (SCSI_COMMAND_TERMINATED == io_hdr.status) || - (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { - if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { - int sense_key; - unsigned char * sense_buffer = io_hdr.sbp; - if (sense_buffer[0] & 0x2) - sense_key = sense_buffer[1] & 0xf; - else - sense_key = sense_buffer[2] & 0xf; - if(RECOVERED_ERROR == sense_key) - return 0; - } - } - return -1; -} - -static void -sprint_wwid(char * buff, const char * str) -{ - int i; - const char *p; - char *cursor; - unsigned char c; - - p = str; - cursor = buff; - for (i = 0; i <= WWID_SIZE / 2 - 1; i++) { - c = *p++; - sprintf(cursor, "%.2x", (int) (unsigned char) c); - cursor += 2; - } - buff[WWID_SIZE - 1] = '\0'; -} - -static void -basename(char * str1, char * str2) -{ - char *p = str1 + (strlen(str1) - 1); - - while (*--p != '/') - continue; - strcpy(str2, ++p); -} - -static int -get_lun_strings(struct env * conf, struct path * mypath) -{ - int fd; - char buff[36]; - char attr_path[FILE_NAME_SIZE]; - char basedev[FILE_NAME_SIZE]; - - if(conf->with_sysfs) { - /* sysfs style */ - basename(mypath->sg_dev, basedev); - - sprintf(attr_path, "%s/block/%s/device/vendor", - conf->sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - mypath->vendor_id, 8)) return 0; - - sprintf(attr_path, "%s/block/%s/device/model", - conf->sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - mypath->product_id, 16)) return 0; - - sprintf(attr_path, "%s/block/%s/device/rev", - conf->sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - mypath->rev, 4)) return 0; - } else { - /* ioctl style */ - if ((fd = open(mypath->sg_dev, O_RDONLY)) < 0) - return 0; - if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) - return 0; - memcpy(mypath->vendor_id, &buff[8], 8); - memcpy(mypath->product_id, &buff[16], 16); - memcpy(mypath->rev, &buff[32], 4); - close(fd); - return 1; - } - return 0; -} - -/* hardware vendor specifics : add support for new models below */ - -/* this one get EVPD page 0x83 off 8 */ -/* tested ok with StorageWorks */ -static int -get_evpd_wwid(struct path * mypath) -{ - int fd; - char buff[64]; - - if ((fd = open(mypath->sg_dev, O_RDONLY)) < 0) - return 0; - - if (0 == do_inq(fd, 0, 1, 0x83, buff, sizeof (buff), 1)) { - sprint_wwid(mypath->wwid, &buff[8]); - close(fd); - return 1; /* success */ - } - close(fd); - return 0; /* not good */ -} +#include "devinfo.h" /* White list switch */ static int @@ -182,13 +39,13 @@ get_unique_id(struct path * mypath) char * vendor; char * product; int iopolicy; - int (*getuid) (struct path *); + int (*getuid) (char *, char *); } wlist[] = { - {"COMPAQ ", "HSV110 (C)COMPAQ", MULTIBUS, &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 ", MULTIBUS, &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 VOLUME ", MULTIBUS, &get_evpd_wwid}, - {"DEC ", "HSG80 ", MULTIBUS, &get_evpd_wwid}, - {"HP ", "HSV100 ", MULTIBUS, &get_evpd_wwid}, + {"COMPAQ ", "HSV110 (C)COMPAQ", GROUP_BY_SERIAL, &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 ", GROUP_BY_SERIAL, &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 VOLUME ", GROUP_BY_SERIAL, &get_evpd_wwid}, + {"DEC ", "HSG80 ", GROUP_BY_SERIAL, &get_evpd_wwid}, + {"HP ", "HSV100 ", GROUP_BY_SERIAL, &get_evpd_wwid}, {"HP ", "A6189A ", MULTIBUS, &get_evpd_wwid}, {"HP ", "OPEN- ", MULTIBUS, &get_evpd_wwid}, {"DDN ", "SAN DataDirector", MULTIBUS, &get_evpd_wwid}, @@ -208,7 +65,7 @@ get_unique_id(struct path * mypath) if (strncmp(mypath->vendor_id, wlist[i].vendor, 8) == 0 && strncmp(mypath->product_id, wlist[i].product, 16) == 0) { mypath->iopolicy = wlist[i].iopolicy; - if (!wlist[i].getuid(mypath)) + if (!wlist[i].getuid(mypath->sg_dev, mypath->wwid)) return 0; } } @@ -269,7 +126,11 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) basename(conf->hotplugdev, buff); sprintf(curpath.sg_dev, "/dev/%s", buff); - get_lun_strings(conf, &curpath); + get_lun_strings(curpath.vendor_id, + curpath.product_id, + curpath.rev, + curpath.sg_dev); + get_serial(curpath.serial, curpath.sg_dev); if (!get_unique_id(&curpath)) return 0; strcpy(refwwid, curpath.wwid); @@ -301,7 +162,11 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) basename(devp->path, buff); sprintf(curpath.sg_dev, "/dev/%s", buff); - get_lun_strings(conf, &curpath); + get_lun_strings(curpath.vendor_id, + curpath.product_id, + curpath.rev, + curpath.sg_dev); + get_serial(curpath.serial, curpath.sg_dev); if(!get_unique_id(&curpath)) { memset(&curpath, 0, sizeof(path)); continue; @@ -349,7 +214,11 @@ get_all_paths_nosysfs(struct env * conf, struct path * all_paths, strncat(file_name, buff, FILE_NAME_SIZE); strcpy(all_paths[k].sg_dev, file_name); - get_lun_strings(conf, &all_paths[k]); + get_lun_strings(all_paths[k].vendor_id, + all_paths[k].product_id, + all_paths[k].rev, + all_paths[k].sg_dev); + get_serial(all_paths[k].serial, all_paths[k].sg_dev); if (!get_unique_id(&all_paths[k])) continue; @@ -484,32 +353,6 @@ print_all_mp(struct path * all_paths, struct multipath * mp, int nmp) } } -static long -get_disk_size (struct env * conf, char * dev) { - long size; - int fd; - char attr_path[FILE_NAME_SIZE]; - char buff[FILE_NAME_SIZE]; - char basedev[FILE_NAME_SIZE]; - - if(conf->with_sysfs) { - basename(dev, basedev); - sprintf(attr_path, "%s/block/%s/size", - conf->sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, buff, - FILE_NAME_SIZE * sizeof(char))) - return -1; - size = atoi(buff); - return size; - } else { - if ((fd = open(dev, O_RDONLY)) < 0) - return -1; - if(!ioctl(fd, BLKGETSIZE, &size)) - return size; - } - return -1; -} - static int coalesce_paths(struct env * conf, struct multipath * mp, struct path * all_paths) @@ -528,7 +371,7 @@ coalesce_paths(struct env * conf, struct multipath * mp, if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) continue; - /* 2. mp with this uid already instanciated */ + /* 2. if mp with this uid already instanciated */ for (i = 0; i <= nmp; i++) { if (0 == strcmp(mp[i].wwid, all_paths[k].wwid)) already_done = 1; @@ -545,7 +388,7 @@ coalesce_paths(struct env * conf, struct multipath * mp, PINDEX(nmp,np) = k; if (mp[nmp].size == 0) - mp[nmp].size = get_disk_size(conf, all_paths[k].dev); + mp[nmp].size = get_disk_size(all_paths[k].dev); for (i = k + 1; i < conf->max_devs; i++) { if (0 == strcmp(all_paths[k].wwid, all_paths[i].wwid)) { @@ -558,6 +401,49 @@ coalesce_paths(struct env * conf, struct multipath * mp, return nmp; } +static void +group_by_serial(struct multipath * mp, struct path * all_paths, char * str) { + int path_count, pg_count = 0; + int i, k; + int * bitmap; + char path_buff[FILE_NAME_SIZE]; + char pg_buff[FILE_NAME_SIZE]; + char * path_buff_p = &path_buff[0]; + char * pg_buff_p = &pg_buff[0]; + + /* init the bitmap */ + bitmap = malloc((mp->npaths + 1) * sizeof(int)); + memset(bitmap, 0, (mp->npaths + 1) * sizeof(int)); + + for (i = 0; i <= mp->npaths; i++) { + if (bitmap[i]) + continue; + + /* here, we really got a new pg */ + pg_count++; + path_count = 1; + memset(&path_buff, 0, FILE_NAME_SIZE * sizeof(char)); + path_buff_p = &path_buff[0]; + + path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[i]].dev); + bitmap[i] = 1; + + for (k = i + 1; k <= mp->npaths; k++) { + if (bitmap[k]) + continue; + if (0 == strcmp(all_paths[mp->pindex[i]].serial, + all_paths[mp->pindex[k]].serial)) { + path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[k]].dev); + bitmap[k] = 1; + path_count++; + } + } + pg_buff_p += sprintf(pg_buff_p, " 1 round-robin %i 0%s", + path_count, path_buff); + } + sprintf(str, " %i%s", pg_count, pg_buff); +} + static int dm_simplecmd(int task, const char *name) { int r = 0; @@ -651,6 +537,11 @@ setup_map(struct env * conf, struct path * all_paths, } } + if (all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_SERIAL && + !conf->forcedfailover ) { + group_by_serial(&mp[index], all_paths, params_p); + } + if (mp[index].size < 0) return 0; diff --git a/extras/multipath/main.h b/extras/multipath/main.h index 3941c32e7c..731c55e41f 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -28,29 +28,25 @@ #define SG_ERR_DRIVER_SENSE 0x08 /* exerpt from "scsi.h" */ -#define RECOVERED_ERROR 0x01 #define SCSI_IOCTL_GET_IDLUN 0x5382 #define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 /* global defs */ #define WWID_SIZE 33 +#define SERIAL_SIZE 14 #define MAX_DEVS 128 #define MAX_MP MAX_DEVS / 2 #define MAX_MP_PATHS MAX_DEVS / 4 #define FILE_NAME_SIZE 256 -#define INQUIRY_CMDLEN 6 -#define INQUIRY_CMD 0x12 -#define SENSE_BUFF_LEN 32 #define DEF_TIMEOUT 60000 #define EBUFF_SZ 256 #define TUR_CMD_LEN 6 -#define MX_ALLOC_LEN 255 -#define BLKGETSIZE _IO(0x12,96) #define DM_TARGET "multipath" /* Storage controlers cpabilities */ #define FAILOVER 0 #define MULTIBUS 1 +#define GROUP_BY_SERIAL 2 #define PINDEX(x,y) mp[(x)].pindex[(y)] @@ -88,6 +84,7 @@ struct path { char vendor_id[8]; char product_id[16]; char rev[4]; + char serial[SERIAL_SIZE]; int iopolicy; }; diff --git a/extras/multipath/sg_err.c b/extras/multipath/sg_err.c deleted file mode 100644 index 8a332cd8c6..0000000000 --- a/extras/multipath/sg_err.c +++ /dev/null @@ -1,1197 +0,0 @@ -#include -#include -#include -#include "sg_include.h" -#include "sg_err.h" - - -/* This file is a huge cut, paste and hack from linux/drivers/scsi/constant.c -* which I guess was written by: -* Copyright (C) 1993, 1994, 1995 Eric Youngdale - -* The rest of this is: -* Copyright (C) 1999 - 2003 D. Gilbert -* -* 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, or (at your option) -* any later version. -* -* ASCII values for a number of symbolic constants, printing functions, etc. -* -* Some of the tables have been updated for SCSI 2. -* Additions for SCSI 3+ (SPC-3 T10/1416-D Rev 12 18 March 2003) -* -* Version 0.91 (20030529) -* sense key specific field (bytes 15-17) decoding [Trent Piepho] -*/ - -#define OUTP stderr - -static const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, - 16, 12, 10, 10 }; - -#define COMMAND_SIZE(opcode) scsi_command_size[((opcode) >> 5) & 7] - -static const char unknown[] = "UNKNOWN"; - -static const char * group_0_commands[] = { -/* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense", -/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks", -/* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown, -/* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry", -/* 13-16 */ "Verify", "Recover Buffered Data", "Mode Select", "Reserve", -/* 17-1b */ "Release", "Copy", "Erase", "Mode Sense", "Start/Stop Unit", -/* 1c-1d */ "Receive Diagnostic", "Send Diagnostic", -/* 1e-1f */ "Prevent/Allow Medium Removal", unknown, -}; - - -static const char *group_1_commands[] = { -/* 20-23 */ unknown, unknown, unknown, "Read Format capacities", -/* 24-28 */ "Set window", "Read Capacity", - unknown, unknown, "Read (10)", -/* 29-2d */ "Read Generation", "Write (10)", "Seek (10)", "Erase", - "Read updated block", -/* 2e-31 */ "Write Verify","Verify", "Search High", "Search Equal", -/* 32-34 */ "Search Low", "Set Limits", "Prefetch or Read Position", -/* 35-37 */ "Synchronize Cache","Lock/Unlock Cache", "Read Defect Data", -/* 38-3c */ "Medium Scan", "Compare", "Copy Verify", "Write Buffer", - "Read Buffer", -/* 3d-3f */ "Update Block", "Read Long", "Write Long", -}; - -static const char *group_2_commands[] = { -/* 40-41 */ "Change Definition", "Write Same", -/* 42-48 */ "Read sub-channel", "Read TOC", "Read header", - "Play audio (10)", "Get configuration", "Play audio msf", - "Play audio track/index", -/* 49-4f */ "Play track relative (10)", "Get event status notification", - "Pause/resume", "Log Select", "Log Sense", "Stop play/scan", - unknown, -/* 50-55 */ "Xdwrite", "Xpwrite, Read disk info", "Xdread, Read track info", - "Reserve track", "Send OPC onfo", "Mode Select (10)", -/* 56-5b */ "Reserve (10)", "Release (10)", "Repair track", "Read master cue", - "Mode Sense (10)", "Close track/session", -/* 5c-5f */ "Read buffer capacity", "Send cue sheet", "Persistent reserve in", - "Persistent reserve out", -}; - -/* The following are 16 byte commands in group 4 */ -static const char *group_4_commands[] = { -/* 80-84 */ "Xdwrite (16)", "Rebuild (16)", "Regenerate (16)", "Extended copy", - "Receive copy results", -/* 85-89 */ "Memory Export In (16)", "Access control in", "Access control out", - "Read (16)", "Memory Export Out (16)", -/* 8a-8f */ "Write (16)", unknown, "Read attributes", "Write attributes", - "Write and verify (16)", "Verify (16)", -/* 90-94 */ "Pre-fetch (16)", "Synchronize cache (16)", - "Lock/unlock cache (16)", "Write same (16)", unknown, -/* 95-99 */ unknown, unknown, unknown, unknown, unknown, -/* 9a-9f */ unknown, unknown, unknown, unknown, "Service action in", - "Service action out", -}; - -/* The following are 12 byte commands in group 5 */ -static const char *group_5_commands[] = { -/* a0-a5 */ "Report luns", "Blank", "Send event", "Maintenance (in)", - "Maintenance (out)", "Move medium/play audio(12)", -/* a6-a9 */ "Exchange medium", "Move medium attached", "Read(12)", - "Play track relative(12)", -/* aa-ae */ "Write(12)", unknown, "Erase(12), Get Performance", - "Read DVD structure", "Write and verify(12)", -/* af-b1 */ "Verify(12)", "Search data high(12)", "Search data equal(12)", -/* b2-b4 */ "Search data low(12)", "Set limits(12)", - "Read element status attached", -/* b5-b6 */ "Request volume element address", "Send volume tag, set streaming", -/* b7-b9 */ "Read defect data(12)", "Read element status", "Read CD msf", -/* ba-bc */ "Redundancy group (in), Scan", - "Redundancy group (out), Set cd-rom speed", "Spare (in), Play cd", -/* bd-bf */ "Spare (out), Mechanism status", "Volume set (in), Read cd", - "Volume set (out), Send DVD structure", -}; - - -#define group(opcode) (((opcode) >> 5) & 7) - -#define RESERVED_GROUP 0 -#define VENDOR_GROUP 1 - -static const char **commands[] = { - group_0_commands, group_1_commands, group_2_commands, - (const char **) RESERVED_GROUP, group_4_commands, - group_5_commands, (const char **) VENDOR_GROUP, - (const char **) VENDOR_GROUP -}; - -static const char reserved[] = "RESERVED"; -static const char vendor[] = "VENDOR SPECIFIC"; - -static void print_opcode(int opcode) { - const char **table = commands[ group(opcode) ]; - - switch ((unsigned long) table) { - case RESERVED_GROUP: - fprintf(OUTP, "%s(0x%02x)", reserved, opcode); - break; - case VENDOR_GROUP: - fprintf(OUTP, "%s(0x%02x)", vendor, opcode); - break; - default: - fprintf(OUTP, "%s",table[opcode & 0x1f]); - break; - } -} - -void sg_print_command (const unsigned char * command) { - int k, s; - print_opcode(command[0]); - fprintf(OUTP, " ["); - for (k = 0, s = COMMAND_SIZE(command[0]); k < s; ++k) - fprintf(OUTP, "%02x ", command[k]); - fprintf(OUTP, "]\n"); -} - -void sg_print_status(int masked_status) -{ - int scsi_status = (masked_status << 1) & 0x7e; - - sg_print_scsi_status(scsi_status); -} - -void sg_print_scsi_status(int scsi_status) -{ - const char * ccp; - - scsi_status &= 0x7e; /* sanitize as much as possible */ - switch (scsi_status) { - case 0: ccp = "Good"; break; - case 0x2: ccp = "Check Condition"; break; - case 0x4: ccp = "Condition Met"; break; - case 0x8: ccp = "Busy"; break; - case 0x10: ccp = "Intermediate"; break; - case 0x14: ccp = "Intermediate-Condition Met"; break; - case 0x18: ccp = "Reservation Conflict"; break; - case 0x22: ccp = "Command Terminated (obsolete)"; break; - case 0x28: ccp = "Task set Full"; break; - case 0x30: ccp = "ACA Active"; break; - case 0x40: ccp = "Task Aborted"; break; - default: ccp = "Unknown status"; break; - } - fprintf(OUTP, "%s ", ccp); -} - -/* In brackets is the related SCSI document (see www.t10.org) with the */ -/* peripheral device type after the colon */ -/* No programmatic use is made of these flags currently */ -#define D 0x0001 /* DIRECT ACCESS DEVICE (disk) [SBC-2: 0] */ -#define T 0x0002 /* SEQUENTIAL ACCESS DEVICE (tape) [SSC: 1] */ -#define L 0x0004 /* PRINTER DEVICE [SSC: 2] */ -#define P 0x0008 /* PROCESSOR DEVICE [SPC-2: 3] */ -#define W 0x0010 /* WRITE ONCE READ MULTIPLE DEVICE [SBC-2: 4] */ -#define R 0x0020 /* CD/DVD DEVICE [MMC-2: 5] */ -#define S 0x0040 /* SCANNER DEVICE [SCSI-2 (obsolete): 6] */ -#define O 0x0080 /* OPTICAL MEMORY DEVICE [SBC-2: 7] */ -#define M 0x0100 /* MEDIA CHANGER DEVICE [SMC-2: 8] */ -#define C 0x0200 /* COMMUNICATION DEVICE [SCSI-2 (obsolete): 9] */ -#define A 0x0400 /* ARRAY STORAGE [SCC-2: 12] */ -#define E 0x0800 /* ENCLOSURE SERVICES DEVICE [SES: 13] */ -#define B 0x1000 /* SIMPLIFIED DIRECT ACCESS DEVICE [RBC: 14] */ -#define K 0x2000 /* OPTICAL CARD READER/WRITER DEVICE [OCRW: 15] */ - -#define SC_ALL_DEVS ( D|T|L|P|W|R|S|O|M|C|A|E|B|K ) - -/* oft used strings are encoded using ASCII codes 0x1 to 0x1f . */ -/* This is to save space. This encoding should be UTF-8 and */ -/* UTF-16 friendly. */ -#define SC_AUDIO_PLAY_OPERATION "\x1" -#define SC_LOGICAL_UNIT "\x2" -#define SC_NOT_READY "\x3" -#define SC_OPERATION "\x4" -#define SC_IN_PROGRESS "\x5" -#define SC_HARDWARE_IF "\x6" -#define SC_CONTROLLER_IF "\x7" -#define SC_DATA_CHANNEL_IF "\x8" -#define SC_SERVO_IF "\x9" -#define SC_SPINDLE_IF "\xa" -#define SC_FIRMWARE_IF "\xb" -#define SC_RECOVERED_DATA "\xc" -#define SC_ERROR_RATE_TOO_HIGH "\xd" -#define SC_TIMES_TOO_HIGH "\xe" - - -struct error_info{ - unsigned char code1, code2; - unsigned short int devices; - const char * text; -}; - -struct error_info2{ - unsigned char code1, code2_min, code2_max; - unsigned short int devices; - const char * text; -}; - -static struct error_info2 additional2[] = -{ - {0x40,0x00,0x7f,D,"Ram failure (%x)"}, - {0x40,0x80,0xff,D|T|L|P|W|R|S|O|M|C,"Diagnostic failure on component (%x)"}, - {0x41,0x00,0xff,D,"Data path failure (%x)"}, - {0x42,0x00,0xff,D,"Power-on or self-test failure (%x)"}, - {0, 0, 0, 0, NULL} -}; - -static struct error_info additional[] = -{ - {0x00,0x00,SC_ALL_DEVS,"No additional sense information"}, - {0x00,0x01,T,"Filemark detected"}, - {0x00,0x02,T|S,"End-of-partition/medium detected"}, - {0x00,0x03,T,"Setmark detected"}, - {0x00,0x04,T|S,"Beginning-of-partition/medium detected"}, - {0x00,0x05,T|L|S,"End-of-data detected"}, - {0x00,0x06,SC_ALL_DEVS,"I/O process terminated"}, - {0x00,0x11,R,SC_AUDIO_PLAY_OPERATION SC_IN_PROGRESS}, - {0x00,0x12,R,SC_AUDIO_PLAY_OPERATION "paused"}, - {0x00,0x13,R,SC_AUDIO_PLAY_OPERATION "successfully completed"}, - {0x00,0x14,R,SC_AUDIO_PLAY_OPERATION "stopped due to error"}, - {0x00,0x15,R,"No current audio status to return"}, - {0x00,0x16,SC_ALL_DEVS,SC_OPERATION SC_IN_PROGRESS}, - {0x00,0x17,D|T|L|W|R|S|O|M|A|E|B|K,"Cleaning requested"}, - {0x00,0x18,T,"Erase" SC_OPERATION SC_IN_PROGRESS}, - {0x00,0x19,T,"Locate" SC_OPERATION SC_IN_PROGRESS}, - {0x00,0x1a,T,"Rewind" SC_OPERATION SC_IN_PROGRESS}, - {0x00,0x1b,T,"Set capacity" SC_OPERATION SC_IN_PROGRESS}, - {0x00,0x1c,T,"Verify" SC_OPERATION SC_IN_PROGRESS}, - {0x01,0x00,D|W|O|B|K,"No index/sector signal"}, - {0x02,0x00,D|W|R|O|M|B|K,"No seek complete"}, - {0x03,0x00,D|T|L|W|S|O|B|K,"Peripheral device write fault"}, - {0x03,0x01,T,"No write current"}, - {0x03,0x02,T,"Excessive write errors"}, - {0x04,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY "cause not reportable"}, - {0x04,0x01,SC_ALL_DEVS,SC_LOGICAL_UNIT "is" SC_IN_PROGRESS - "of becoming ready"}, - {0x04,0x02,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY - "initializing cmd. required"}, - {0x04,0x03,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY - "manual intervention required"}, - {0x04,0x04,D|T|L|R|O|B,SC_LOGICAL_UNIT SC_NOT_READY "format" SC_IN_PROGRESS}, - {0x04,0x05,D|T|W|O|M|C|A|B|K,SC_LOGICAL_UNIT SC_NOT_READY - "rebuild" SC_IN_PROGRESS}, - {0x04,0x06,D|T|W|O|M|C|A|B|K,SC_LOGICAL_UNIT SC_NOT_READY - "recalculation" SC_IN_PROGRESS}, - {0x04,0x07,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY - SC_OPERATION SC_IN_PROGRESS}, - {0x04,0x08,R,SC_LOGICAL_UNIT SC_NOT_READY "long write" SC_IN_PROGRESS}, - {0x04,0x09,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY "self-test" - SC_IN_PROGRESS}, - {0x04,0x0a,SC_ALL_DEVS,SC_LOGICAL_UNIT - "not accessible, asymmetric access state transition"}, - {0x04,0x0b,SC_ALL_DEVS,SC_LOGICAL_UNIT - "not accessible, target port in standby state"}, - {0x04,0x0c,SC_ALL_DEVS,SC_LOGICAL_UNIT - "not accessible, target port in unavailable state"}, - {0x04,0x10,SC_ALL_DEVS,SC_LOGICAL_UNIT SC_NOT_READY - "auxiliary memory not accessible"}, - {0x05,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT - "does not respond to selection"}, - {0x06,0x00,D|W|R|O|M|B|K,"No reference position found"}, - {0x07,0x00,D|T|L|W|R|S|O|M|B|K,"Multiple peripheral devices selected"}, - {0x08,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT "communication failure"}, - {0x08,0x01,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT - "communication time-out"}, - {0x08,0x02,D|T|L|W|R|S|O|M|C|A|E|B|K,SC_LOGICAL_UNIT - "communication parity error"}, - {0x08,0x03,D|T|R|O|M|B|K,SC_LOGICAL_UNIT - "communication CRC error (Ultra-DMA/32)"}, - {0x08,0x04,D|T|L|P|W|R|S|O|C|K,"Unreachable copy target"}, - {0x09,0x00,D|T|W|R|O|B,"Track following error"}, - {0x09,0x01,W|R|O|K,"Tracking servo failure"}, - {0x09,0x02,W|R|O|K,"Focus servo failure"}, - {0x09,0x03,W|R|O,"Spindle servo failure"}, - {0x09,0x04,D|T|W|R|O|B,"Head select fault"}, - {0x0A,0x00,SC_ALL_DEVS,"Error log overflow"}, - {0x0B,0x00,SC_ALL_DEVS,"Warning"}, - {0x0B,0x01,SC_ALL_DEVS,"Warning - specified temperature exceeded"}, - {0x0B,0x02,SC_ALL_DEVS,"Warning - enclosure degraded"}, - {0x0C,0x00,T|R|S,"Write error"}, - {0x0C,0x01,K,"Write error - recovered with auto reallocation"}, - {0x0C,0x02,D|W|O|B|K,"Write error - auto reallocation failed"}, - {0x0C,0x03,D|W|O|B|K,"Write error - recommend reassignment"}, - {0x0C,0x04,D|T|W|O|B,"Compression check miscompare error"}, - {0x0C,0x05,D|T|W|O|B,"Data expansion occurred during compression"}, - {0x0C,0x06,D|T|W|O|B,"Block not compressible"}, - {0x0C,0x07,R,"Write error - recovery needed"}, - {0x0C,0x08,R,"Write error - recovery failed"}, - {0x0C,0x09,R,"Write error - loss of streaming"}, - {0x0C,0x0A,R,"Write error - padding blocks added"}, - {0x0C,0x0B,D|T|W|R|O|M|B,"Auxiliary memory write error"}, - {0x0C,0x0C,SC_ALL_DEVS,"Write error - unexpected unsolicited data"}, - {0x0C,0x0D,SC_ALL_DEVS,"Write error - not enough unsolicited data"}, - {0x0D,0x00,D|T|L|P|W|R|S|O|C|A|K, - "Error detected by third party temporary initiator"}, - {0x0D,0x01,D|T|L|P|W|R|S|O|C|A|K, "Third party device failure"}, - {0x0D,0x02,D|T|L|P|W|R|S|O|C|A|K, "Copy target device not reachable"}, - {0x0D,0x03,D|T|L|P|W|R|S|O|C|A|K, "Incorrect copy target device"}, - {0x0D,0x04,D|T|L|P|W|R|S|O|C|A|K, "Copy target device underrun"}, - {0x0D,0x05,D|T|L|P|W|R|S|O|C|A|K, "Copy target device overrun"}, - {0x10,0x00,D|W|O|B|K,"Id CRC or ECC error"}, - {0x11,0x00,D|T|W|R|S|O|B|K,"Unrecovered read error"}, - {0x11,0x01,D|T|W|R|S|O|B|K,"Read retries exhausted"}, - {0x11,0x02,D|T|W|R|S|O|B|K,"Error too long to correct"}, - {0x11,0x03,D|T|W|S|O|B|K,"Multiple read errors"}, - {0x11,0x04,D|W|O|B|K,"Unrecovered read error - auto reallocate failed"}, - {0x11,0x05,W|R|O|B,"L-EC uncorrectable error"}, - {0x11,0x06,W|R|O|B,"CIRC unrecovered error"}, - {0x11,0x07,W|O|B,"Data re-synchronization error"}, - {0x11,0x08,T,"Incomplete block read"}, - {0x11,0x09,T,"No gap found"}, - {0x11,0x0A,D|T|O|B|K,"Miscorrected error"}, - {0x11,0x0B,D|W|O|B|K,"Unrecovered read error - recommend reassignment"}, - {0x11,0x0C,D|W|O|B|K,"Unrecovered read error - recommend rewrite the data"}, - {0x11,0x0D,D|T|W|R|O|B,"De-compression CRC error"}, - {0x11,0x0E,D|T|W|R|O|B,"Cannot decompress using declared algorithm"}, - {0x11,0x0F,R,"Error reading UPC/EAN number"}, - {0x11,0x10,R,"Error reading ISRC number"}, - {0x11,0x11,R,"Read error - loss of streaming"}, - {0x11,0x12,D|T|W|R|O|M|B,"Auxiliary memory read error"}, - {0x11,0x13,SC_ALL_DEVS,"Read error - failed retransmission request"}, - {0x12,0x00,D|W|O|B|K,"Address mark not found for id field"}, - {0x13,0x00,D|W|O|B|K,"Address mark not found for data field"}, - {0x14,0x00,D|T|L|W|R|S|O|B|K,"Recorded entity not found"}, - {0x14,0x01,D|T|W|R|O|B|K,"Record not found"}, - {0x14,0x02,T,"Filemark or setmark not found"}, - {0x14,0x03,T,"End-of-data not found"}, - {0x14,0x04,T,"Block sequence error"}, - {0x14,0x05,D|T|W|O|B|K,"Record not found - recommend reassignment"}, - {0x14,0x06,D|T|W|O|B|K,"Record not found - data auto-reallocated"}, - {0x14,0x07,T,"Locate" SC_OPERATION " failure"}, - {0x15,0x00,D|T|L|W|R|S|O|M|B|K,"Random positioning error"}, - {0x15,0x01,D|T|L|W|R|S|O|M|B|K,"Mechanical positioning error"}, - {0x15,0x02,D|T|W|R|O|B|K,"Positioning error detected by read of medium"}, - {0x16,0x00,D|W|O|B|K,"Data synchronization mark error"}, - {0x16,0x01,D|W|O|B|K,"Data sync error - data rewritten"}, - {0x16,0x02,D|W|O|B|K,"Data sync error - recommend rewrite"}, - {0x16,0x03,D|W|O|B|K,"Data sync error - data auto-reallocated"}, - {0x16,0x04,D|W|O|B|K,"Data sync error - recommend reassignment"}, - {0x17,0x00,D|T|W|R|S|O|B|K,SC_RECOVERED_DATA - "with no error correction applied"}, - {0x17,0x01,D|T|W|R|S|O|B|K,SC_RECOVERED_DATA "with retries"}, - {0x17,0x02,D|T|W|R|O|B|K,SC_RECOVERED_DATA "with positive head offset"}, - {0x17,0x03,D|T|W|R|O|B|K,SC_RECOVERED_DATA "with negative head offset"}, - {0x17,0x04,W|R|O|B,SC_RECOVERED_DATA "with retries and/or circ applied"}, - {0x17,0x05,D|W|R|O|B|K,SC_RECOVERED_DATA "using previous sector id"}, - {0x17,0x06,D|W|O|B|K,SC_RECOVERED_DATA "without ecc - data auto-reallocated"}, - {0x17,0x07,D|W|R|O|B|K,SC_RECOVERED_DATA - "without ecc - recommend reassignment"}, - {0x17,0x08,D|W|R|O|B|K,SC_RECOVERED_DATA "without ecc - recommend rewrite"}, - {0x17,0x09,D|W|R|O|B|K,SC_RECOVERED_DATA "without ecc - data rewritten"}, - {0x18,0x00,D|T|W|R|O|B|K,SC_RECOVERED_DATA "with error correction applied"}, - {0x18,0x01,D|W|R|O|B|K,SC_RECOVERED_DATA - "with error corr. & retries applied"}, - {0x18,0x02,D|W|R|O|B|K,SC_RECOVERED_DATA "- data auto-reallocated"}, - {0x18,0x03,R,SC_RECOVERED_DATA "with CIRC"}, - {0x18,0x04,R,SC_RECOVERED_DATA "with L-EC"}, - {0x18,0x05,D|W|R|O|B|K,SC_RECOVERED_DATA "- recommend reassignment"}, - {0x18,0x06,D|W|R|O|B|K,SC_RECOVERED_DATA "- recommend rewrite"}, - {0x18,0x07,D|W|O|B|K,SC_RECOVERED_DATA "with ecc - data rewritten"}, - {0x18,0x08,R,SC_RECOVERED_DATA "with linking"}, - {0x19,0x00,D|O|K,"Defect list error"}, - {0x19,0x01,D|O|K,"Defect list not available"}, - {0x19,0x02,D|O|K,"Defect list error in primary list"}, - {0x19,0x03,D|O|K,"Defect list error in grown list"}, - {0x1A,0x00,SC_ALL_DEVS,"Parameter list length error"}, - {0x1B,0x00,SC_ALL_DEVS,"Synchronous data transfer error"}, - {0x1C,0x00,D|O|B|K,"Defect list not found"}, - {0x1C,0x01,D|O|B|K,"Primary defect list not found"}, - {0x1C,0x02,D|O|B|K,"Grown defect list not found"}, - {0x1D,0x00,D|T|W|R|O|B|K,"Miscompare during verify" SC_OPERATION}, - {0x1E,0x00,D|W|O|B|K,"Recovered id with ecc correction"}, - {0x1F,0x00,D|O|K,"Partial defect list transfer"}, - {0x20,0x00,SC_ALL_DEVS,"Invalid command" SC_OPERATION " code"}, - {0x20,0x01,D|T|P|W|R|O|M|A|E|B|K, - "Access denied - initiator pending-enrolled"}, - {0x20,0x02,D|T|P|W|R|O|M|A|E|B|K,"Access denied - no access rights"}, - {0x20,0x03,D|T|P|W|R|O|M|A|E|B|K,"Access denied - no mgmt id key"}, - {0x20,0x04,T,"Illegal command while in write capable state"}, - {0x20,0x05,T,"Obsolete"}, - {0x20,0x06,T,"Illegal command while in explicit address mode"}, - {0x20,0x07,T,"Illegal command while in implicit address mode"}, - {0x20,0x08,D|T|P|W|R|O|M|A|E|B|K,"Access denied - enrollment conflict"}, - {0x20,0x09,D|T|P|W|R|O|M|A|E|B|K,"Access denied - invalid LU identifier"}, - {0x20,0x0A,D|T|P|W|R|O|M|A|E|B|K,"Access denied - invalid proxy token"}, - {0x20,0x0B,D|T|P|W|R|O|M|A|E|B|K,"Access denied - ACL LUN conflict"}, - {0x21,0x00,D|T|W|R|O|M|B|K,"Logical block address out of range"}, - {0x21,0x01,D|T|W|R|O|M|B|K,"Invalid element address"}, - {0x21,0x02,R,"Invalid address for write"}, - {0x22,0x00,D,"Illegal function (use 20 00,24 00,or 26 00)"}, - {0x24,0x00,SC_ALL_DEVS,"Invalid field in cdb"}, - {0x24,0x01,SC_ALL_DEVS,"CDB decryption error"}, - {0x25,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT "not supported"}, - {0x26,0x00,SC_ALL_DEVS,"Invalid field in parameter list"}, - {0x26,0x01,SC_ALL_DEVS,"Parameter not supported"}, - {0x26,0x02,SC_ALL_DEVS,"Parameter value invalid"}, - {0x26,0x03,D|T|L|P|W|R|S|O|M|C|A|E|K,"Threshold parameters not supported"}, - {0x26,0x04,SC_ALL_DEVS,"Invalid release of persistent reservation"}, - {0x26,0x05,D|T|L|P|W|R|S|O|M|C|A|B|K,"Data decryption error"}, - {0x26,0x06,D|T|L|P|W|R|S|O|C|K,"Too many target descriptors"}, - {0x26,0x07,D|T|L|P|W|R|S|O|C|K,"Unsupported target descriptor type code"}, - {0x26,0x08,D|T|L|P|W|R|S|O|C|K,"Too many segment descriptors"}, - {0x26,0x09,D|T|L|P|W|R|S|O|C|K,"Unsupported segment descriptor type code"}, - {0x26,0x0A,D|T|L|P|W|R|S|O|C|K,"Unexpected inexact segment"}, - {0x26,0x0B,D|T|L|P|W|R|S|O|C|K,"Inline data length exceeded"}, - {0x26,0x0C,D|T|L|P|W|R|S|O|C|K, - "Invalid" SC_OPERATION " for copy source or destination"}, - {0x26,0x0D,D|T|L|P|W|R|S|O|C|K,"Copy segment granularity violation"}, - {0x27,0x00,D|T|W|R|O|B|K,"Write protected"}, - {0x27,0x01,D|T|W|R|O|B|K,"Hardware write protected"}, - {0x27,0x02,D|T|W|R|O|B|K,SC_LOGICAL_UNIT "software write protected"}, - {0x27,0x03,T|R,"Associated write protect"}, - {0x27,0x04,T|R,"Persistent write protect"}, - {0x27,0x05,T|R,"Permanent write protect"}, - {0x27,0x06,R,"Conditional write protect"}, - {0x28,0x00,SC_ALL_DEVS,"Not ready to ready change, medium may have changed"}, - {0x28,0x01,D|T|W|R|O|M|B,"Import or export element accessed"}, - {0x29,0x00,SC_ALL_DEVS,"Power on, reset, or bus device reset occurred"}, - {0x29,0x01,SC_ALL_DEVS,"Power on occurred"}, - {0x29,0x02,SC_ALL_DEVS,"Scsi bus reset occurred"}, - {0x29,0x03,SC_ALL_DEVS,"Bus device reset function occurred"}, - {0x29,0x04,SC_ALL_DEVS,"Device internal reset"}, - {0x29,0x05,SC_ALL_DEVS,"Transceiver mode changed to single-ended"}, - {0x29,0x06,SC_ALL_DEVS,"Transceiver mode changed to lvd"}, - {0x29,0x07,SC_ALL_DEVS,"I_T nexus loss occurred"}, - {0x2A,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Parameters changed"}, - {0x2A,0x01,D|T|L|W|R|S|O|M|C|A|E|B|K,"Mode parameters changed"}, - {0x2A,0x02,D|T|L|W|R|S|O|M|C|A|E|K,"Log parameters changed"}, - {0x2A,0x03,D|T|L|P|W|R|S|O|M|C|A|E|K,"Reservations preempted"}, - {0x2A,0x04,D|T|L|P|W|R|S|O|M|C|A|E,"Reservations released"}, - {0x2A,0x05,D|T|L|P|W|R|S|O|M|C|A|E,"Registrations preempted"}, - {0x2A,0x06,SC_ALL_DEVS,"Asymmetric access state changed"}, - {0x2A,0x07,SC_ALL_DEVS,"Implicit asymmetric access state transition failed"}, - {0x2B,0x00,D|T|L|P|W|R|S|O|C|K, - "Copy cannot execute since host cannot disconnect"}, - {0x2C,0x00,SC_ALL_DEVS,"Command sequence error"}, - {0x2C,0x01,S,"Too many windows specified"}, - {0x2C,0x02,S,"Invalid combination of windows specified"}, - {0x2C,0x03,R,"Current program area is not empty"}, - {0x2C,0x04,R,"Current program area is empty"}, - {0x2C,0x05,B,"Illegal power condition request"}, - {0x2C,0x06,R,"Persistent prevent conflict"}, - {0x2C,0x07,SC_ALL_DEVS,"Previous busy status"}, - {0x2C,0x08,SC_ALL_DEVS,"Previous task set full status"}, - {0x2C,0x09,D|T|L|P|W|R|S|O|M|E|B|K,"Previous reservation conflict status"}, - {0x2D,0x00,T,"Overwrite error on update in place"}, - {0x2F,0x00,SC_ALL_DEVS,"Commands cleared by another initiator"}, - {0x30,0x00,D|T|W|R|O|M|B|K,"Incompatible medium installed"}, - {0x30,0x01,D|T|W|R|O|B|K,"Cannot read medium - unknown format"}, - {0x30,0x02,D|T|W|R|O|B|K,"Cannot read medium - incompatible format"}, - {0x30,0x03,D|T|R|K,"Cleaning cartridge installed"}, - {0x30,0x04,D|T|W|R|O|B|K,"Cannot write medium - unknown format"}, - {0x30,0x05,D|T|W|R|O|B|K,"Cannot write medium - incompatible format"}, - {0x30,0x06,D|T|W|R|O|B,"Cannot format medium - incompatible medium"}, - {0x30,0x07,D|T|L|W|R|S|O|M|A|E|B|K,"Cleaning failure"}, - {0x30,0x08,R,"Cannot write - application code mismatch"}, - {0x30,0x09,R,"Current session not fixated for append"}, - {0x30,0x10,R,"Medium not formatted"}, /* should ascq be 0xa ?? */ - {0x31,0x00,D|T|W|R|O|B|K,"Medium format corrupted"}, - {0x31,0x01,D|L|R|O|B,"Format command failed"}, - {0x31,0x02,R,"Zoned formatting failed due to spare linking"}, - {0x32,0x00,D|W|O|B|K,"No defect spare location available"}, - {0x32,0x01,D|W|O|B|K,"Defect list update failure"}, - {0x33,0x00,T,"Tape length error"}, - {0x34,0x00,SC_ALL_DEVS,"Enclosure failure"}, - {0x35,0x00,SC_ALL_DEVS,"Enclosure services failure"}, - {0x35,0x01,SC_ALL_DEVS,"Unsupported enclosure function"}, - {0x35,0x02,SC_ALL_DEVS,"Enclosure services unavailable"}, - {0x35,0x03,SC_ALL_DEVS,"Enclosure services transfer failure"}, - {0x35,0x04,SC_ALL_DEVS,"Enclosure services transfer refused"}, - {0x36,0x00,L,"Ribbon,ink,or toner failure"}, - {0x37,0x00,D|T|L|W|R|S|O|M|C|A|E|B|K,"Rounded parameter"}, - {0x38,0x00,B,"Event status notification"}, - {0x38,0x02,B,"Esn - power management class event"}, - {0x38,0x04,B,"Esn - media class event"}, - {0x38,0x06,B,"Esn - device busy class event"}, - {0x39,0x00,D|T|L|W|R|S|O|M|C|A|E|K,"Saving parameters not supported"}, - {0x3A,0x00,D|T|L|W|R|S|O|M|B|K,"Medium not present"}, - {0x3A,0x01,D|T|W|R|O|M|B|K,"Medium not present - tray closed"}, - {0x3A,0x02,D|T|W|R|O|M|B|K,"Medium not present - tray open"}, - {0x3A,0x03,D|T|W|R|O|M|B,"Medium not present - loadable"}, - {0x3A,0x04,D|T|W|R|O|M|B, - "Medium not present - medium auxiliary memory accessible"}, - {0x3B,0x00,T|L,"Sequential positioning error"}, - {0x3B,0x01,T,"Tape position error at beginning-of-medium"}, - {0x3B,0x02,T,"Tape position error at end-of-medium"}, - {0x3B,0x03,L,"Tape or electronic vertical forms unit " SC_NOT_READY}, - {0x3B,0x04,L,"Slew failure"}, - {0x3B,0x05,L,"Paper jam"}, - {0x3B,0x06,L,"Failed to sense top-of-form"}, - {0x3B,0x07,L,"Failed to sense bottom-of-form"}, - {0x3B,0x08,T,"Reposition error"}, - {0x3B,0x09,S,"Read past end of medium"}, - {0x3B,0x0A,S,"Read past beginning of medium"}, - {0x3B,0x0B,S,"Position past end of medium"}, - {0x3B,0x0C,T|S,"Position past beginning of medium"}, - {0x3B,0x0D,D|T|W|R|O|M|B|K,"Medium destination element full"}, - {0x3B,0x0E,D|T|W|R|O|M|B|K,"Medium source element empty"}, - {0x3B,0x0F,R,"End of medium reached"}, - {0x3B,0x11,D|T|W|R|O|M|B|K,"Medium magazine not accessible"}, - {0x3B,0x12,D|T|W|R|O|M|B|K,"Medium magazine removed"}, - {0x3B,0x13,D|T|W|R|O|M|B|K,"Medium magazine inserted"}, - {0x3B,0x14,D|T|W|R|O|M|B|K,"Medium magazine locked"}, - {0x3B,0x15,D|T|W|R|O|M|B|K,"Medium magazine unlocked"}, - {0x3B,0x16,R,"Mechanical positioning or changer error"}, - {0x3D,0x00,D|T|L|P|W|R|S|O|M|C|A|E|K,"Invalid bits in identify message"}, - {0x3E,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT "has not self-configured yet"}, - {0x3E,0x01,SC_ALL_DEVS,SC_LOGICAL_UNIT "failure"}, - {0x3E,0x02,SC_ALL_DEVS,"Timeout on logical unit"}, - {0x3E,0x03,SC_ALL_DEVS,SC_LOGICAL_UNIT "failed self-test"}, - {0x3E,0x04,SC_ALL_DEVS,SC_LOGICAL_UNIT "unable to update self-test log"}, - {0x3F,0x00,SC_ALL_DEVS,"Target operating conditions have changed"}, - {0x3F,0x01,SC_ALL_DEVS,"Microcode has been changed"}, - {0x3F,0x02,D|T|L|P|W|R|S|O|M|C|B|K,"Changed operating definition"}, - {0x3F,0x03,SC_ALL_DEVS,"Inquiry data has changed"}, - {0x3F,0x04,D|T|W|R|O|M|C|A|E|B|K,"Component device attached"}, - {0x3F,0x05,D|T|W|R|O|M|C|A|E|B|K,"Device identifier changed"}, - {0x3F,0x06,D|T|W|R|O|M|C|A|E|B,"Redundancy group created or modified"}, - {0x3F,0x07,D|T|W|R|O|M|C|A|E|B,"Redundancy group deleted"}, - {0x3F,0x08,D|T|W|R|O|M|C|A|E|B,"Spare created or modified"}, - {0x3F,0x09,D|T|W|R|O|M|C|A|E|B,"Spare deleted"}, - {0x3F,0x0A,D|T|W|R|O|M|C|A|E|B|K,"Volume set created or modified"}, - {0x3F,0x0B,D|T|W|R|O|M|C|A|E|B|K,"Volume set deleted"}, - {0x3F,0x0C,D|T|W|R|O|M|C|A|E|B|K,"Volume set deassigned"}, - {0x3F,0x0D,D|T|W|R|O|M|C|A|E|B|K,"Volume set reassigned"}, - {0x3F,0x0E,D|T|L|P|W|R|S|O|M|C|A|E,"Reported luns data has changed"}, - {0x3F,0x10,D|T|W|R|O|M|B,"Medium loadable"}, - {0x3F,0x11,D|T|W|R|O|M|B,"Medium auxiliary memory accessible"}, - {0x40,0x00,D,"Ram failure (should use 40 nn)"}, - /* - * FIXME(eric) - need a way to represent wildcards here. - */ - {0x40,0x00,SC_ALL_DEVS,"Diagnostic failure on component nn (80h-ffh)"}, - {0x41,0x00,D,"Data path failure (should use 40 nn)"}, - {0x42,0x00,D,"Power-on or self-test failure (should use 40 nn)"}, - {0x43,0x00,SC_ALL_DEVS,"Message error"}, - {0x44,0x00,SC_ALL_DEVS,"Internal target failure"}, - {0x45,0x00,SC_ALL_DEVS,"Select or reselect failure"}, - {0x46,0x00,D|T|L|P|W|R|S|O|M|C|B|K,"Unsuccessful soft reset"}, - {0x47,0x00,SC_ALL_DEVS,"Scsi parity error"}, - {0x47,0x01,SC_ALL_DEVS,"Data phase CRC error detected"}, - {0x47,0x02,SC_ALL_DEVS,"Scsi parity error detected during st data phase"}, - {0x47,0x03,SC_ALL_DEVS,"Information unit CRC error detected"}, - {0x47,0x04,SC_ALL_DEVS,"Asynchronous information protection error detected"}, - {0x47,0x05,SC_ALL_DEVS,"Protocol service CRC error"}, - {0x48,0x00,SC_ALL_DEVS,"Initiator detected error message received"}, - {0x49,0x00,SC_ALL_DEVS,"Invalid message error"}, - {0x4A,0x00,SC_ALL_DEVS,"Command phase error"}, - {0x4B,0x00,SC_ALL_DEVS,"Data phase error"}, - {0x4C,0x00,SC_ALL_DEVS,SC_LOGICAL_UNIT "failed self-configuration"}, - /* - * FIXME(eric) - need a way to represent wildcards here. - */ - {0x4D,0x00,SC_ALL_DEVS,"Tagged overlapped commands (nn = queue tag)"}, - {0x4E,0x00,SC_ALL_DEVS,"Overlapped commands attempted"}, - {0x50,0x00,T,"Write append error"}, - {0x50,0x01,T,"Write append position error"}, - {0x50,0x02,T,"Position error related to timing"}, - {0x51,0x00,T|R|O,"Erase failure"}, - {0x52,0x00,T,"Cartridge fault"}, - {0x53,0x00,D|T|L|W|R|S|O|M|B|K,"Media load or eject failed"}, - {0x53,0x01,T,"Unload tape failure"}, - {0x53,0x02,D|T|W|R|O|M|B|K,"Medium removal prevented"}, - {0x54,0x00,P,"Scsi to host system interface failure"}, - {0x55,0x00,P,"System resource failure"}, - {0x55,0x01,D|O|B|K,"System buffer full"}, - {0x55,0x02,D|T|L|P|W|R|S|O|M|A|E|K,"Insufficient reservation resources"}, - {0x55,0x03,D|T|L|P|W|R|S|O|M|C|A|E,"Insufficient resources"}, - {0x55,0x04,D|T|L|P|W|R|S|O|M|A|E,"Insufficient registration resources"}, - {0x55,0x05,D|T|P|W|R|O|M|A|E|B|K,"Insufficient access control resources"}, - {0x55,0x06,D|T|W|R|O|M|B,"Auxiliary memory out of space"}, - {0x57,0x00,R,"Unable to recover table-of-contents"}, - {0x58,0x00,O,"Generation does not exist"}, - {0x59,0x00,O,"Updated block read"}, - {0x5A,0x00,D|T|L|P|W|R|S|O|M|B|K,"Operator request or state change input"}, - {0x5A,0x01,D|T|W|R|O|M|B|K,"Operator medium removal request"}, - {0x5A,0x02,D|T|W|R|O|A|B|K,"Operator selected write protect"}, - {0x5A,0x03,D|T|W|R|O|A|B|K,"Operator selected write permit"}, - {0x5B,0x00,D|T|L|P|W|R|S|O|M|K,"Log exception"}, - {0x5B,0x01,D|T|L|P|W|R|S|O|M|K,"Threshold condition met"}, - {0x5B,0x02,D|T|L|P|W|R|S|O|M|K,"Log counter at maximum"}, - {0x5B,0x03,D|T|L|P|W|R|S|O|M|K,"Log list codes exhausted"}, - {0x5C,0x00,D|O,"Rpl status change"}, - {0x5C,0x01,D|O,"Spindles synchronized"}, - {0x5C,0x02,D|O,"Spindles not synchronized"}, - {0x5D,0x00,SC_ALL_DEVS,"Failure prediction threshold exceeded"}, - {0x5D,0x01,R|B,"Media failure prediction threshold exceeded"}, - {0x5D,0x02,R,SC_LOGICAL_UNIT "failure prediction threshold exceeded"}, - {0x5D,0x03,R,"spare area exhaustion prediction threshold exceeded"}, - /* large series of "impending failure" messages */ - {0x5D,0x10,D|B,SC_HARDWARE_IF "general hard drive failure"}, - {0x5D,0x11,D|B,SC_HARDWARE_IF "drive" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x12,D|B,SC_HARDWARE_IF "data" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x13,D|B,SC_HARDWARE_IF "seek" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x14,D|B,SC_HARDWARE_IF "too many block reassigns"}, - {0x5D,0x15,D|B,SC_HARDWARE_IF "access" SC_TIMES_TOO_HIGH }, - {0x5D,0x16,D|B,SC_HARDWARE_IF "start unit" SC_TIMES_TOO_HIGH }, - {0x5D,0x17,D|B,SC_HARDWARE_IF "channel parametrics"}, - {0x5D,0x18,D|B,SC_HARDWARE_IF "controller detected"}, - {0x5D,0x19,D|B,SC_HARDWARE_IF "throughput performance"}, - {0x5D,0x1A,D|B,SC_HARDWARE_IF "seek time performance"}, - {0x5D,0x1B,D|B,SC_HARDWARE_IF "spin-up retry count"}, - {0x5D,0x1C,D|B,SC_HARDWARE_IF "drive calibration retry count"}, - {0x5D,0x20,D|B,SC_CONTROLLER_IF "general hard drive failure"}, - {0x5D,0x21,D|B,SC_CONTROLLER_IF "drive" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x22,D|B,SC_CONTROLLER_IF "data" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x23,D|B,SC_CONTROLLER_IF "seek" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x24,D|B,SC_CONTROLLER_IF "too many block reassigns"}, - {0x5D,0x25,D|B,SC_CONTROLLER_IF "access" SC_TIMES_TOO_HIGH }, - {0x5D,0x26,D|B,SC_CONTROLLER_IF "start unit" SC_TIMES_TOO_HIGH }, - {0x5D,0x27,D|B,SC_CONTROLLER_IF "channel parametrics"}, - {0x5D,0x28,D|B,SC_CONTROLLER_IF "controller detected"}, - {0x5D,0x29,D|B,SC_CONTROLLER_IF "throughput performance"}, - {0x5D,0x2A,D|B,SC_CONTROLLER_IF "seek time performance"}, - {0x5D,0x2B,D|B,SC_CONTROLLER_IF "spin-up retry count"}, - {0x5D,0x2C,D|B,SC_CONTROLLER_IF "drive calibration retry count"}, - {0x5D,0x30,D|B,SC_DATA_CHANNEL_IF "general hard drive failure"}, - {0x5D,0x31,D|B,SC_DATA_CHANNEL_IF "drive" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x32,D|B,SC_DATA_CHANNEL_IF "data" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x33,D|B,SC_DATA_CHANNEL_IF "seek" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x34,D|B,SC_DATA_CHANNEL_IF "too many block reassigns"}, - {0x5D,0x35,D|B,SC_DATA_CHANNEL_IF "access" SC_TIMES_TOO_HIGH }, - {0x5D,0x36,D|B,SC_DATA_CHANNEL_IF "start unit" SC_TIMES_TOO_HIGH }, - {0x5D,0x37,D|B,SC_DATA_CHANNEL_IF "channel parametrics"}, - {0x5D,0x38,D|B,SC_DATA_CHANNEL_IF "controller detected"}, - {0x5D,0x39,D|B,SC_DATA_CHANNEL_IF "throughput performance"}, - {0x5D,0x3A,D|B,SC_DATA_CHANNEL_IF "seek time performance"}, - {0x5D,0x3B,D|B,SC_DATA_CHANNEL_IF "spin-up retry count"}, - {0x5D,0x3C,D|B,SC_DATA_CHANNEL_IF "drive calibration retry count"}, - {0x5D,0x40,D|B,SC_SERVO_IF "general hard drive failure"}, - {0x5D,0x41,D|B,SC_SERVO_IF "drive" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x42,D|B,SC_SERVO_IF "data" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x43,D|B,SC_SERVO_IF "seek" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x44,D|B,SC_SERVO_IF "too many block reassigns"}, - {0x5D,0x45,D|B,SC_SERVO_IF "access" SC_TIMES_TOO_HIGH }, - {0x5D,0x46,D|B,SC_SERVO_IF "start unit" SC_TIMES_TOO_HIGH }, - {0x5D,0x47,D|B,SC_SERVO_IF "channel parametrics"}, - {0x5D,0x48,D|B,SC_SERVO_IF "controller detected"}, - {0x5D,0x49,D|B,SC_SERVO_IF "throughput performance"}, - {0x5D,0x4A,D|B,SC_SERVO_IF "seek time performance"}, - {0x5D,0x4B,D|B,SC_SERVO_IF "spin-up retry count"}, - {0x5D,0x4C,D|B,SC_SERVO_IF "drive calibration retry count"}, - {0x5D,0x50,D|B,SC_SPINDLE_IF "general hard drive failure"}, - {0x5D,0x51,D|B,SC_SPINDLE_IF "drive" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x52,D|B,SC_SPINDLE_IF "data" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x53,D|B,SC_SPINDLE_IF "seek" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x54,D|B,SC_SPINDLE_IF "too many block reassigns"}, - {0x5D,0x55,D|B,SC_SPINDLE_IF "access" SC_TIMES_TOO_HIGH }, - {0x5D,0x56,D|B,SC_SPINDLE_IF "start unit" SC_TIMES_TOO_HIGH }, - {0x5D,0x57,D|B,SC_SPINDLE_IF "channel parametrics"}, - {0x5D,0x58,D|B,SC_SPINDLE_IF "controller detected"}, - {0x5D,0x59,D|B,SC_SPINDLE_IF "throughput performance"}, - {0x5D,0x5A,D|B,SC_SPINDLE_IF "seek time performance"}, - {0x5D,0x5B,D|B,SC_SPINDLE_IF "spin-up retry count"}, - {0x5D,0x5C,D|B,SC_SPINDLE_IF "drive calibration retry count"}, - {0x5D,0x60,D|B,SC_FIRMWARE_IF "general hard drive failure"}, - {0x5D,0x61,D|B,SC_FIRMWARE_IF "drive" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x62,D|B,SC_FIRMWARE_IF "data" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x63,D|B,SC_FIRMWARE_IF "seek" SC_ERROR_RATE_TOO_HIGH }, - {0x5D,0x64,D|B,SC_FIRMWARE_IF "too many block reassigns"}, - {0x5D,0x65,D|B,SC_FIRMWARE_IF "access" SC_TIMES_TOO_HIGH }, - {0x5D,0x66,D|B,SC_FIRMWARE_IF "start unit" SC_TIMES_TOO_HIGH }, - {0x5D,0x67,D|B,SC_FIRMWARE_IF "channel parametrics"}, - {0x5D,0x68,D|B,SC_FIRMWARE_IF "controller detected"}, - {0x5D,0x69,D|B,SC_FIRMWARE_IF "throughput performance"}, - {0x5D,0x6A,D|B,SC_FIRMWARE_IF "seek time performance"}, - {0x5D,0x6B,D|B,SC_FIRMWARE_IF "spin-up retry count"}, - {0x5D,0x6C,D|B,SC_FIRMWARE_IF "drive calibration retry count"}, - {0x5D,0xFF,SC_ALL_DEVS,"Failure prediction threshold exceeded (false)"}, - {0x5E,0x00,D|T|L|P|W|R|S|O|C|A|K,"Low power condition on"}, - {0x5E,0x01,D|T|L|P|W|R|S|O|C|A|K,"Idle condition activated by timer"}, - {0x5E,0x02,D|T|L|P|W|R|S|O|C|A|K,"Standby condition activated by timer"}, - {0x5E,0x03,D|T|L|P|W|R|S|O|C|A|K,"Idle condition activated by command"}, - {0x5E,0x04,D|T|L|P|W|R|S|O|C|A|K,"Standby condition activated by command"}, - {0x5E,0x41,B,"Power state change to active"}, - {0x5E,0x42,B,"Power state change to idle"}, - {0x5E,0x43,B,"Power state change to standby"}, - {0x5E,0x45,B,"Power state change to sleep"}, - {0x5E,0x47,B|K,"Power state change to device control"}, - {0x60,0x00,S,"Lamp failure"}, - {0x61,0x00,S,"Video acquisition error"}, - {0x61,0x01,S,"Unable to acquire video"}, - {0x61,0x02,S,"Out of focus"}, - {0x62,0x00,S,"Scan head positioning error"}, - {0x63,0x00,R,"End of user area encountered on this track"}, - {0x63,0x01,R,"Packet does not fit in available space"}, - {0x64,0x00,R,"Illegal mode for this track"}, - {0x64,0x01,R,"Invalid packet size"}, - {0x65,0x00,SC_ALL_DEVS,"Voltage fault"}, - {0x66,0x00,S,"Automatic document feeder cover up"}, - {0x66,0x01,S,"Automatic document feeder lift up"}, - {0x66,0x02,S,"Document jam in automatic document feeder"}, - {0x66,0x03,S,"Document miss feed automatic in document feeder"}, - {0x67,0x00,A,"Configuration failure"}, - {0x67,0x01,A,"Configuration of incapable logical units failed"}, - {0x67,0x02,A,"Add logical unit failed"}, - {0x67,0x03,A,"Modification of logical unit failed"}, - {0x67,0x04,A,"Exchange of logical unit failed"}, - {0x67,0x05,A,"Remove of logical unit failed"}, - {0x67,0x06,A,"Attachment of logical unit failed"}, - {0x67,0x07,A,"Creation of logical unit failed"}, - {0x67,0x08,A,"Assign failure occurred"}, - {0x67,0x09,A,"Multiply assigned logical unit"}, - {0x67,0x0A,SC_ALL_DEVS,"Set target port groups command failed"}, - {0x68,0x00,A,SC_LOGICAL_UNIT "not configured"}, - {0x69,0x00,A,"Data loss on logical unit"}, - {0x69,0x01,A,"Multiple logical unit failures"}, - {0x69,0x02,A,"Parity/data mismatch"}, - {0x6A,0x00,A,"Informational,refer to log"}, - {0x6B,0x00,A,"State change has occurred"}, - {0x6B,0x01,A,"Redundancy level got better"}, - {0x6B,0x02,A,"Redundancy level got worse"}, - {0x6C,0x00,A,"Rebuild failure occurred"}, - {0x6D,0x00,A,"Recalculate failure occurred"}, - {0x6E,0x00,A,"Command to logical unit failed"}, - {0x6F,0x00,R,"Copy protection key exchange failure - authentication failure"}, - {0x6F,0x01,R,"Copy protection key exchange failure - key not present"}, - {0x6F,0x02,R,"Copy protection key exchange failure - key not established"}, - {0x6F,0x03,R,"Read of scrambled sector without authentication"}, - {0x6F,0x04,R,"Media region code is mismatched to logical unit region"}, - {0x6F,0x05,R,"Drive region must be permanent/region reset count error"}, - /* - * FIXME(eric) - need a way to represent wildcards here. - */ - {0x70,0x00,T,"Decompression exception short algorithm id of nn"}, - {0x71,0x00,T,"Decompression exception long algorithm id"}, - {0x72,0x00,R,"Session fixation error"}, - {0x72,0x01,R,"Session fixation error writing lead-in"}, - {0x72,0x02,R,"Session fixation error writing lead-out"}, - {0x72,0x03,R,"Session fixation error - incomplete track in session"}, - {0x72,0x04,R,"Empty or partially written reserved track"}, - {0x72,0x05,R,"No more track reservations allowed"}, - {0x73,0x00,R,"Cd control error"}, - {0x73,0x01,R,"Power calibration area almost full"}, - {0x73,0x02,R,"Power calibration area is full"}, - {0x73,0x03,R,"Power calibration area error"}, - {0x73,0x04,R,"Program memory area update failure"}, - {0x73,0x05,R,"Program memory area is full"}, - {0x73,0x06,R,"RMA/PMA is full"}, - {0, 0, 0, NULL} -}; - -static const char * sc_oft_used[0x1f] = { - "umulig", /* index 0x0 should be impossible */ - "Audio play operation ", - "Logical unit ", - "not ready, ", - " operation", - " in progress ", - "Hardware impending failure ", - "Controller impending failure ", - "Data channel impending failure ", /* index 0x8 */ - "Servo impending failure ", - "Spindle impending failure ", - "Firmware impending failure ", - "Recovered data ", - " error rate too high", - " times too high", -}; - -static const char *snstext[] = { - "No Sense", /* There is no sense information */ - "Recovered Error", /* The last command completed successfully - but used error correction */ - "Not Ready", /* The addressed target is not ready */ - "Medium Error", /* Data error detected on the medium */ - "Hardware Error", /* Controller or device failure */ - "Illegal Request", - "Unit Attention", /* Removable medium was changed, or - the target has been reset */ - "Data Protect", /* Access to the data is blocked */ - "Blank Check", /* Reached unexpected written or unwritten - region of the medium */ - "Key=9", /* Vendor specific */ - "Copy Aborted", /* COPY or COMPARE was aborted */ - "Aborted Command", /* The target aborted the command */ - "Equal", /* SEARCH DATA found data equal (obsolete) */ - "Volume Overflow", /* Medium full with still data to be written */ - "Miscompare", /* Source data and data on the medium - do not agree */ - "Key=15" /* Reserved */ -}; - -static -void sg_print_asc_ascq(unsigned char asc, unsigned char ascq) -{ - int k, j; - char obuff[256]; - const char * ccp; - const char * oup; - char c; - int found = 0; - - for (k=0; additional[k].text; k++) { - if (additional[k].code1 == asc && - additional[k].code2 == ascq) { - found = 1; - ccp = additional[k].text; - for (j = 0; *ccp && (j < sizeof(obuff)); ++ccp) { - c = *ccp; - if ((c < 0x20) && (c > 0)) { - oup = sc_oft_used[(int)c]; - if (oup) { - strcpy(obuff + j, oup); - j += strlen(oup); - } - else { - strcpy(obuff + j, "???"); - j += 3; - } - } - else - obuff[j++] = c; - } - if (j < sizeof(obuff)) - obuff[j] = '\0'; - else - obuff[sizeof(obuff) - 1] = '\0'; - fprintf(OUTP, "Additional sense: %s\n", obuff); - } - } - if (found) - return; - - for(k=0; additional2[k].text; k++) { - if ((additional2[k].code1 == asc) && - (ascq >= additional2[k].code2_min) && - (ascq <= additional2[k].code2_max)) { - found = 1; - fprintf(OUTP, "Additional sense: "); - fprintf(OUTP, additional2[k].text, ascq); - fprintf(OUTP, "\n"); - } - } - if (! found) - fprintf(OUTP, "ASC=%2x ASCQ=%2x\n", asc, ascq); -} - -/* Print sense information */ -void sg_print_sense(const char * leadin, const unsigned char * sense_buffer, - int sb_len) -{ - int k, s; - int sense_key, sense_class, valid, code; - int descriptor_format = 0; - const char * error = NULL; - - if (sb_len < 1) { - fprintf(OUTP, "sense buffer empty\n"); - return; - } - sense_class = (sense_buffer[0] >> 4) & 0x07; - code = sense_buffer[0] & 0xf; - valid = sense_buffer[0] & 0x80; - if (leadin) - fprintf(OUTP, "%s: ", leadin); - - if (sense_class == 7) { /* extended sense data */ - s = sense_buffer[7] + 8; - if(s > sb_len) /* device has more available which we ignore */ - s = sb_len; - - switch (code) { - case 0x0: - error = "Current"; /* error concerns current command */ - break; - case 0x1: - error = "Deferred"; /* error concerns some earlier command */ - /* e.g., an earlier write to disk cache succeeded, but - now the disk discovers that it cannot write the data */ - break; - case 0x2: - descriptor_format = 1; - error = "Descriptor current"; - /* new descriptor sense format */ - break; - case 0x3: - descriptor_format = 1; - error = "Descriptor deferred"; - /* new descriptor sense format (deferred report) */ - break; - default: - error = "Invalid"; - } - sense_key = sense_buffer[ descriptor_format ? 1 : 2 ] & 0xf; - fprintf(OUTP, "%s, Sense key: %s\n", error, snstext[sense_key]); - - if (descriptor_format) - sg_print_asc_ascq(sense_buffer[2], sense_buffer[3]); - else { - if (!valid) - fprintf(OUTP, "[valid=0] "); - fprintf(OUTP, "Info fld=0x%x, ", (int)((sense_buffer[3] << 24) | - (sense_buffer[4] << 16) | (sense_buffer[5] << 8) | - sense_buffer[6])); - - if (sense_buffer[2] & 0x80) - fprintf(OUTP, "FMK "); /* current command has read a filemark */ - if (sense_buffer[2] & 0x40) - fprintf(OUTP, "EOM "); /* end-of-medium condition exists */ - if (sense_buffer[2] & 0x20) - fprintf(OUTP, "ILI "); /* incorrect block length requested */ - - if (s > 13) { - if (sense_buffer[12] || sense_buffer[13]) - sg_print_asc_ascq(sense_buffer[12], sense_buffer[13]); - } - if (sense_key == 5 && s >= 18 && (sense_buffer[15]&0x80)) { - fprintf(OUTP, "Sense Key Specific: Error in %s byte %d", - (sense_buffer[15]&0x40)?"Command":"Data", - (sense_buffer[16]<<8)|sense_buffer[17]); - if(sense_buffer[15]&0x08) { - fprintf(OUTP, " bit %d\n", sense_buffer[15]&0x07); - } else { - fprintf(OUTP, "\n"); - } - } - } - - } else { /* non-extended sense data */ - - /* - * Standard says: - * sense_buffer[0] & 0200 : address valid - * sense_buffer[0] & 0177 : vendor-specific error code - * sense_buffer[1] & 0340 : vendor-specific - * sense_buffer[1..3] : 21-bit logical block address - */ - - if (sb_len < 4) { - fprintf(OUTP, "sense buffer too short (4 byte minimum)\n"); - return; - } - if (leadin) - fprintf(OUTP, "%s: ", leadin); - if (sense_buffer[0] < 15) - fprintf(OUTP, - "old sense: key %s\n", snstext[sense_buffer[0] & 0x0f]); - else - fprintf(OUTP, "sns = %2x %2x\n", sense_buffer[0], sense_buffer[2]); - - fprintf(OUTP, "Non-extended sense class %d code 0x%0x ", - sense_class, code); - s = 4; - } - - fprintf(OUTP, "Raw sense data (in hex):\n "); - for (k = 0; k < s; ++k) { - if ((k > 0) && (0 == (k % 24))) - fprintf(OUTP, "\n "); - fprintf(OUTP, "%02x ", sense_buffer[k]); - } - fprintf(OUTP, "\n"); -} - -static const char * hostbyte_table[]={ -"DID_OK", "DID_NO_CONNECT", "DID_BUS_BUSY", "DID_TIME_OUT", "DID_BAD_TARGET", -"DID_ABORT", "DID_PARITY", "DID_ERROR", "DID_RESET", "DID_BAD_INTR", -"DID_PASSTHROUGH", "DID_SOFT_ERROR", NULL}; - -void sg_print_host_status(int host_status) -{ static int maxcode=0; - int i; - - if(! maxcode) { - for(i = 0; hostbyte_table[i]; i++) ; - maxcode = i-1; - } - fprintf(OUTP, "Host_status=0x%02x", host_status); - if(host_status > maxcode) { - fprintf(OUTP, "is invalid "); - return; - } - fprintf(OUTP, "(%s) ",hostbyte_table[host_status]); -} - -static const char * driverbyte_table[]={ -"DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", -"DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", "DRIVER_SENSE", NULL}; - -static const char * driversuggest_table[]={"SUGGEST_OK", -"SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", -unknown,unknown,unknown, "SUGGEST_SENSE",NULL}; - - -void sg_print_driver_status(int driver_status) -{ - static int driver_max =0 , suggest_max=0; - int i; - int dr = driver_status & SG_ERR_DRIVER_MASK; - int su = (driver_status & SG_ERR_SUGGEST_MASK) >> 4; - - if(! driver_max) { - for(i = 0; driverbyte_table[i]; i++) ; - driver_max = i; - for(i = 0; driversuggest_table[i]; i++) ; - suggest_max = i; - } - fprintf(OUTP, "Driver_status=0x%02x",driver_status); - fprintf(OUTP, " (%s,%s) ", - dr < driver_max ? driverbyte_table[dr]:"invalid", - su < suggest_max ? driversuggest_table[su]:"invalid"); -} - -static int sg_sense_print(const char * leadin, int scsi_status, - int host_status, int driver_status, - const unsigned char * sense_buffer, int sb_len) -{ - int done_leadin = 0; - int done_sense = 0; - - scsi_status &= 0x7e; /*sanity */ - if ((0 == scsi_status) && (0 == host_status) && - (0 == driver_status)) - return 1; /* No problems */ - if (0 != scsi_status) { - if (leadin) - fprintf(OUTP, "%s: ", leadin); - done_leadin = 1; - fprintf(OUTP, "scsi status: "); - sg_print_scsi_status(scsi_status); - fprintf(OUTP, "\n"); - if (sense_buffer && ((scsi_status == SCSI_CHECK_CONDITION) || - (scsi_status == SCSI_COMMAND_TERMINATED))) { - sg_print_sense(0, sense_buffer, sb_len); - done_sense = 1; - } - } - if (0 != host_status) { - if (leadin && (! done_leadin)) - fprintf(OUTP, "%s: ", leadin); - if (done_leadin) - fprintf(OUTP, "plus...: "); - else - done_leadin = 1; - sg_print_host_status(host_status); - fprintf(OUTP, "\n"); - } - if (0 != driver_status) { - if (leadin && (! done_leadin)) - fprintf(OUTP, "%s: ", leadin); - if (done_leadin) - fprintf(OUTP, "plus...: "); - else - done_leadin = 1; - sg_print_driver_status(driver_status); - fprintf(OUTP, "\n"); - if (sense_buffer && (! done_sense) && - (SG_ERR_DRIVER_SENSE == (0xf & driver_status))) - sg_print_sense(0, sense_buffer, sb_len); - } - return 0; -} - -#ifdef SG_IO -int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp) -{ - return sg_sense_print(leadin, hp->status, hp->host_status, - hp->driver_status, hp->sbp, hp->sb_len_wr); -} -#endif - -int sg_chk_n_print(const char * leadin, int masked_status, - int host_status, int driver_status, - const unsigned char * sense_buffer, int sb_len) -{ - int scsi_status = (masked_status << 1) & 0x7e; - - return sg_sense_print(leadin, scsi_status, host_status, driver_status, - sense_buffer, sb_len); -} - -#ifdef SG_IO -int sg_err_category3(struct sg_io_hdr * hp) -{ - return sg_err_category_new(hp->status, hp->host_status, - hp->driver_status, hp->sbp, hp->sb_len_wr); -} -#endif - -int sg_err_category(int masked_status, int host_status, - int driver_status, const unsigned char * sense_buffer, - int sb_len) -{ - int scsi_status = (masked_status << 1) & 0x7e; - - return sg_err_category_new(scsi_status, host_status, driver_status, - sense_buffer, sb_len); -} - -int sg_err_category_new(int scsi_status, int host_status, int driver_status, - const unsigned char * sense_buffer, int sb_len) -{ - scsi_status &= 0x7e; - if ((0 == scsi_status) && (0 == host_status) && - (0 == driver_status)) - return SG_ERR_CAT_CLEAN; - if ((SCSI_CHECK_CONDITION == scsi_status) || - (SCSI_COMMAND_TERMINATED == scsi_status) || - (SG_ERR_DRIVER_SENSE == (0xf & driver_status))) { - 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(RECOVERED_ERROR == sense_key) - return SG_ERR_CAT_RECOVERED; - else if (UNIT_ATTENTION == sense_key) { - if (0x28 == asc) - return SG_ERR_CAT_MEDIA_CHANGED; - if (0x29 == asc) - return SG_ERR_CAT_RESET; - } - } - return SG_ERR_CAT_SENSE; - } - if (0 != host_status) { - if ((SG_ERR_DID_NO_CONNECT == host_status) || - (SG_ERR_DID_BUS_BUSY == host_status) || - (SG_ERR_DID_TIME_OUT == host_status)) - return SG_ERR_CAT_TIMEOUT; - } - if (0 != driver_status) { - if (SG_ERR_DRIVER_TIMEOUT == driver_status) - return SG_ERR_CAT_TIMEOUT; - } - return SG_ERR_CAT_OTHER; -} - -int sg_get_command_size(unsigned char opcode) -{ - return COMMAND_SIZE(opcode); -} - -void sg_get_command_name(unsigned char opcode, int buff_len, char * buff) -{ - const char **table = commands[ group(opcode) ]; - - if ((NULL == buff) || (buff_len < 1)) - return; - - switch ((unsigned long) table) { - case RESERVED_GROUP: - strncpy(buff, reserved, buff_len); - break; - case VENDOR_GROUP: - strncpy(buff, vendor, buff_len); - break; - default: - strncpy(buff, table[opcode & 0x1f], buff_len); - break; - } -} From 44a523e30d79efc5aca9a05073b32f5924191244 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 13 Feb 2004 01:01:07 -0800 Subject: [PATCH 0534/4284] [PATCH] v017 release --- ChangeLog | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 56 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca1f765aef..4ad5f63ace 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,57 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 2ecfd3a968..0f347c7342 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ DAEMON = udevd SENDER = udevsend HELPER = udevinfo TESTER = udevtest -VERSION = 016_bk +VERSION = 017 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 0b142f0942..a53a1ad63b 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 016_bk +Version: 017 Release: 1 License: GPL Group: Utilities/System From 7a4877bf6fea5f1d1d8390b7efd6b8a53003631a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 16 Feb 2004 18:19:48 -0800 Subject: [PATCH 0535/4284] [PATCH] Fix bug where we did not use the "converted" kernel name if we had no rule. This fixes the bug with names that have a ! in them and no rule to match. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 018fd452e9..f138fe9769 100644 --- a/namedev.c +++ b/namedev.c @@ -745,7 +745,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } /* no rule was found so we use the kernel name */ - strfieldcpy(udev->name, class_dev->name); + strfieldcpy(udev->name, udev->kernel_name); goto done; found: From b9fc973b9a9e9622e3b7f4c4031ffe0835df5f65 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 16 Feb 2004 18:25:01 -0800 Subject: [PATCH 0536/4284] [PATCH] Add another test to udev-test.pl and fix a bug when only running 1 test. --- test/udev-test.pl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index c433b84a97..62a2bb327b 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -346,6 +346,15 @@ EOF conf => < "name test with ! in the name, but no matching rule", + subsys => "block", + devpath => "block/rd!c0d0", + expected => "rd/c0d0" , + conf => < Date: Mon, 16 Feb 2004 18:27:46 -0800 Subject: [PATCH 0537/4284] [PATCH] 017_bk mark --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 0f347c7342..c9455e460c 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ DAEMON = udevd SENDER = udevsend HELPER = udevinfo TESTER = udevtest -VERSION = 017 +VERSION = 017_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev From aa3400ae6d621db5d257340c1b07cb8ca6190913 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 16 Feb 2004 18:32:20 -0800 Subject: [PATCH 0538/4284] [PATCH] add ability to install udevtest to Makefile --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index c9455e460c..936a6613f0 100644 --- a/Makefile +++ b/Makefile @@ -352,6 +352,7 @@ install: install-config install-dbus-policy all $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(HELPER) $(DESTDIR)$(sbindir)/$(HELPER) + $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(sbindir)/$(TESTER) @if [ "x$(USE_LSB)" = "xtrue" ]; then \ $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ ln -s $(DESTDIR)$(initdir)/udev $(sbindir)/rcudev; \ From e68582be4a9522bb936a7c8adcd20991793d7d14 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 16 Feb 2004 18:37:59 -0800 Subject: [PATCH 0539/4284] [PATCH] update the udev.spec to add udevtest and make some more Red Hat suggested changes. --- udev.spec | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/udev.spec b/udev.spec index a53a1ad63b..aa595962f7 100644 --- a/udev.spec +++ b/udev.spec @@ -23,13 +23,13 @@ %define debug 0 # if we want to use the LSB version of the init script or the Redhat one -# 0 - use Redhat version: etc/init.d/udev -# 1 - use LSB version: etc/init.d/udev.init.LSB +# 0 - use Redhat: etc/init.d/udev +# 1 - use LSB: etc/init.d/udev.init.LSB %define lsb 0 Summary: A userspace implementation of devfs Name: udev -Version: 017 +Version: 017_bk Release: 1 License: GPL Group: Utilities/System @@ -68,18 +68,20 @@ make CC="gcc $RPM_OPT_FLAGS" \ DEBUG=false \ %endif -# now build udevd on it's own, as it can't handle being built with klibc -make CC="gcc $RPM_OPT_FLAGS" udevd - %install make DESTDIR=$RPM_BUILD_ROOT install \ %if %{dbus} - USE_DBUS=true + USE_DBUS=true \ +%else + USE_DBUS=false \ %endif %if %{lsb} - USE_LSB=true + USE_LSB=true \ +%else + USE_LSB=false \ %endif + %post /sbin/chkconfig --add udev @@ -98,9 +100,9 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udevinfo %attr(755,root,root) /sbin/udevsend %attr(755,root,root) /sbin/udevd -%attr(755,root,root) /udev/ -%attr(755,root,root) /etc/udev/ -%attr(755,root,root) %dir +%attr(755,root,root) /sbin/udevtest +%attr(755,root,root) %dir /udev/ +%attr(755,root,root) %dir /etc/udev/ %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf %config(noreplace) %attr(0644,root,root) /etc/udev/udev.rules %config(noreplace) %attr(0644,root,root) /etc/udev/udev.permissions @@ -112,6 +114,11 @@ rm -rf $RPM_BUILD_ROOT %attr(0644,root,root) %{_mandir}/man8/udev*.8* %changelog +* Mon Feb 16 2004 Greg Kroah-Hartman +- fix up udevd build, as it's no longer needed to be build seperatly +- add udevtest to list of files +- more Red Hat sync ups. + * Thu Feb 12 2004 Greg Kroah-Hartman - add some changes from the latest Fedora udev release. From a27cd06c6d3c83d9906f5e1aaf8d3c4b32055830 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 16 Feb 2004 21:36:34 -0800 Subject: [PATCH 0540/4284] [PATCH] Adding '%s' format specifier to NAME and SYMLINK On Thu, Feb 12, 2004 at 05:34:57PM -0800, Greg KH wrote: > On Tue, Feb 10, 2004 at 09:14:20AM +0100, Hannes Reinecke wrote: > > Hi all, > > > > this patch makes the format for NAME and SYMLINK a bit more flexible: > > I've added a new format specifier '%s{}', which allows for > > the value of any sysfs entry found for this device to be inserted. > > Example (for our S/390 fcp adapter): > > > > BUS="ccw", SYSFS_devtype="1732/03", NAME="%k" \ > > SYMLINK="zfcp-%s{hba_id}-%s{wwpn}:%s{fcp_lun}" > > > > I know this could also be done with an external program, but having this > > incorporated into udev makes life easier, especially if run from > > initramfs. Plus it makes the rules easier to follow, as the result is > > directly visible and need not to be looked up in some external program. > > > > Comments etc. welcome. > > Oops, sorry I missed this for the 017 release. I'll look at it tomorrow > and get back to you. At first glance it looks like a good thing. > > Oh, you forgot to update the documentation, that's important to do if > you want this change to make it in :) I took a part of the code and made a version that uses already implemented attribute finding logic. The parsing of the format length '%3x' and the '%x{attribute}' is a fuction now, maybe there are more possible users in the future. I've also added the test to udev-test.pl. --- namedev.c | 250 +++++++++++++++++++++++++++++----------------- test/udev-test.pl | 10 ++ 2 files changed, 169 insertions(+), 91 deletions(-) diff --git a/namedev.c b/namedev.c index f138fe9769..cd38f25cb0 100644 --- a/namedev.c +++ b/namedev.c @@ -41,6 +41,8 @@ #include "libsysfs/libsysfs.h" #include "klibc_fixups.h" +static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr); + LIST_HEAD(config_device_list); LIST_HEAD(perm_device_list); @@ -168,7 +170,46 @@ static char *get_default_group(void) return default_group_str; } -static void apply_format(struct udevice *udev, unsigned char *string) +/* 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) { + dbg("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 (tail != NULL) { + *str = tail; + dbg("format length=%i", num); + return num; + } else { + dbg("format parsing error '%s'", *str); + } + } + return -1; +} + +static void apply_format(struct udevice *udev, unsigned char *string, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { char temp[NAME_SIZE]; char temp1[NAME_SIZE]; @@ -176,87 +217,100 @@ static void apply_format(struct udevice *udev, unsigned char *string) char *pos; char *pos2; char *pos3; + char *attr; int num; + char c; + struct sysfs_attribute *tmpattr; pos = string; - while (1) { - num = 0; - pos = strchr(pos, '%'); - if (pos) { + while (1) { + pos = strchr(pos, '%'); + if (pos != NULL) { pos[0] = '\0'; tail = pos+1; - if (isdigit(tail[0])) { - num = (int) strtoul(&pos[1], &tail, 10); - if (tail == NULL) { - dbg("format parsing error '%s'", pos+1); - break; - } - } + num = get_format_len(&tail); + c = tail[0]; strfieldcpy(temp, tail+1); - - switch (tail[0]) { - case 'b': - if (strlen(udev->bus_id) == 0) - break; - strcat(pos, udev->bus_id); - dbg("substitute bus_id '%s'", udev->bus_id); - break; - case 'k': - if (strlen(udev->kernel_name) == 0) - break; - strcat(pos, udev->kernel_name); - dbg("substitute kernel name '%s'", udev->kernel_name); - break; - case 'n': - if (strlen(udev->kernel_number) == 0) - break; - strcat(pos, udev->kernel_number); - dbg("substitute kernel number '%s'", udev->kernel_number); - break; - case 'm': - sprintf(pos, "%u", udev->minor); - dbg("substitute minor number '%u'", udev->minor); - break; - case 'M': - sprintf(pos, "%u", udev->major); - dbg("substitute major number '%u'", udev->major); - break; - case 'c': - if (strlen(udev->program_result) == 0) - break; - if (num) { - /* get part of return string */ - strncpy(temp1, udev->program_result, sizeof(temp1)); - pos2 = temp1; - while (num) { - num--; - pos3 = strsep(&pos2, " "); - if (pos3 == NULL) { - dbg("requested part of result string not found"); - break; - } - } - if (pos3) { - strcat(pos, pos3); - dbg("substitute part of result string '%s'", pos3); - } - } else { - strcat(pos, udev->program_result); - dbg("substitute result string '%s'", udev->program_result); - } - break; - case '%': - strcat(pos, "%"); - pos++; - break; - default: - dbg("unknown substitution type '%%%c'", pos[1]); - break; - } - strcat(string, temp); - } else + tail = temp; + } else { break; + } + dbg("format=%c, string='%s', tail='%s'",c , string, tail); + + attr = get_format_attribute(&tail); + + switch (c) { + case 'b': + if (strlen(udev->bus_id) == 0) + break; + strcat(pos, udev->bus_id); + dbg("substitute bus_id '%s'", udev->bus_id); + break; + case 'k': + if (strlen(udev->kernel_name) == 0) + break; + strcat(pos, udev->kernel_name); + dbg("substitute kernel name '%s'", udev->kernel_name); + break; + case 'n': + if (strlen(udev->kernel_number) == 0) + break; + strcat(pos, udev->kernel_number); + dbg("substitute kernel number '%s'", udev->kernel_number); + break; + case 'm': + sprintf(pos, "%u", udev->minor); + dbg("substitute minor number '%u'", udev->minor); + break; + case 'M': + sprintf(pos, "%u", udev->major); + dbg("substitute major number '%u'", udev->major); + break; + case 'c': + if (strlen(udev->program_result) == 0) + break; + if (num > 0) { + strncpy(temp1, udev->program_result, sizeof(temp1)); + pos2 = temp1; + while (num) { + num--; + pos3 = strsep(&pos2, " "); + if (pos3 == NULL) { + dbg("requested part of result string not found"); + break; + } + } + if (pos3) { + strcat(pos, pos3); + dbg("substitute part of result string '%s'", pos3); + } + } else { + strcat(pos, udev->program_result); + dbg("substitute result string '%s'", udev->program_result); + } + break; + case 's': + if (attr != NULL) { + tmpattr = find_sysfs_attribute(class_dev, sysfs_device, attr); + if (tmpattr == NULL) { + dbg("sysfa attribute '%s' not found", attr); + break; + } + strcpy(pos, tmpattr->value); + dbg("substitute sysfs value '%s'", tmpattr->value); + } else { + dbg("missing attribute"); + } + break; + case '%': + strcat(pos, "%"); + break; + default: + dbg("unknown substitution type '%%%c'", c); + break; + } + strcat(pos, tail); } } @@ -422,32 +476,46 @@ static int execute_program(char *path, char *value, int len) return retval; } -static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair) +static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr) { struct sysfs_attribute *tmpattr = NULL; char *c; - if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0')) - return -ENODEV; - - dbg("look for device attribute '%s'", pair->file); + dbg("look for device attribute '%s'", attr); /* try to find the attribute in the class device directory */ - tmpattr = sysfs_get_classdev_attr(class_dev, pair->file); + tmpattr = sysfs_get_classdev_attr(class_dev, attr); if (tmpattr) - goto label_found; + goto attr_found; /* look in the class device directory if present */ if (sysfs_device) { - tmpattr = sysfs_get_device_attr(sysfs_device, pair->file); + tmpattr = sysfs_get_device_attr(sysfs_device, attr); if (tmpattr) - goto label_found; + goto attr_found; } - return -ENODEV; -label_found: - c = tmpattr->value + strlen(tmpattr->value)-1; - if (*c == '\n') - *c = 0x00; + return NULL; + +attr_found: + c = strchr(tmpattr->value, '\n'); + if (c != NULL) + c[0] = '\0'; + + dbg("found attribute '%s'", tmpattr->path); + return tmpattr; +} + +static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair) +{ + struct sysfs_attribute *tmpattr; + + if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0')) + return -ENODEV; + + tmpattr = find_sysfs_attribute(class_dev, sysfs_device, pair->file); + if (tmpattr == NULL) + return -ENODEV; + dbg("compare attribute '%s' value '%s' with '%s'", pair->file, tmpattr->value, pair->value); if (strcmp_pattern(pair->value, tmpattr->value) != 0) @@ -658,7 +726,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas /* execute external program */ if (dev->program[0] != '\0') { dbg("check " FIELD_PROGRAM); - apply_format(udev, dev->program); + apply_format(udev, dev->program, class_dev, sysfs_device); if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { dbg(FIELD_PROGRAM " returned nozero"); goto try_parent; @@ -750,8 +818,8 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud found: /* substitute placeholder */ - apply_format(udev, udev->name); - apply_format(udev, udev->symlink); + apply_format(udev, udev->name, class_dev, sysfs_device); + apply_format(udev, udev->symlink, class_dev, sysfs_device); done: perm = find_perm(udev->name); diff --git a/test/udev-test.pl b/test/udev-test.pl index 62a2bb327b..cbe110f797 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -191,6 +191,16 @@ EOF expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "sustitution of sysfs value (%s{file})", + subsys => "block", + devpath => "block/sda", + expected => "disk-IBM-ESXS-sda" , + conf => < Date: Mon, 16 Feb 2004 21:39:40 -0800 Subject: [PATCH 0541/4284] [PATCH] allow SYSFS{file} On Sun, Feb 15, 2004 at 03:36:00AM +0100, Kay Sievers wrote: > > Since we have %s{file} it may be nice to allow SYSFS{file}. > This patch allows: > > BUS="usb", SYSFS{idProduct}="a511", NAME="video%n" > > compared to the current: > > BUS="usb", SYSFS_idProduct="a511", NAME="video%n" > > The curent syntax is still supported. > Looks a bit nicer and less hackish, I think. Better patch with infrastructure to easily implement KEY{attribute} for every other key. The first user is the SYSFS{file} key. Both versions, brackets or underscore is supported for the attribute. --- namedev.h | 2 +- namedev_parse.c | 43 +++++++++++++++++++++++++++++++++++++++---- test/udev-test.pl | 10 ++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/namedev.h b/namedev.h index a0cdba6b16..e38c4f5257 100644 --- a/namedev.h +++ b/namedev.h @@ -36,7 +36,7 @@ struct sysfs_class_device; #define PROGRAM_SIZE 100 #define FIELD_BUS "BUS" -#define FIELD_SYSFS "SYSFS_" +#define FIELD_SYSFS "SYSFS" #define FIELD_ID "ID" #define FIELD_PLACE "PLACE" #define FIELD_PROGRAM "PROGRAM" diff --git a/namedev_parse.c b/namedev_parse.c index e6575fa108..20ff60d640 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -85,6 +85,35 @@ void dump_perm_dev_list(void) dump_perm_dev(dev); } +/* extract possible KEY{attr} or KEY_attr */ +static char *get_key_attribute(char *str) +{ + char *pos; + char *attr; + + attr = strchr(str, '_'); + if (attr != NULL) { + attr++; + dbg("attribute='%s'", attr); + return attr; + } + + attr = strchr(str, '{'); + if (attr != NULL) { + attr++; + pos = strchr(attr, '}'); + if (pos == NULL) { + dbg("missing closing brace for format"); + return NULL; + } + pos[0] = '\0'; + dbg("attribute='%s'", attr); + return attr; + } + + return NULL; +} + int namedev_init_rules(void) { char line[255]; @@ -92,6 +121,7 @@ int namedev_init_rules(void) char *temp; char *temp2; char *temp3; + char *attr; FILE *fd; int program_given = 0; int retval = 0; @@ -164,8 +194,12 @@ int namedev_init_rules(void) ++pair; } if (pair) { - /* remove prepended 'SYSFS_' */ - strfieldcpy(pair->file, temp2 + sizeof(FIELD_SYSFS)-1); + attr = get_key_attribute(temp2 + sizeof(FIELD_SYSFS)-1); + if (attr == NULL) { + dbg("error parsing " FIELD_SYSFS " attribute"); + continue; + } + strfieldcpy(pair->file, attr); strfieldcpy(pair->value, temp3); } continue; @@ -205,12 +239,13 @@ int namedev_init_rules(void) /* simple plausibility check for given keys */ if ((dev.sysfs_pair[0].file[0] == '\0') ^ (dev.sysfs_pair[0].value[0] == '\0')) { - dbg("inconsistency in SYSFS_ key"); + dbg("inconsistency in " FIELD_SYSFS " key"); goto error; } if ((dev.result[0] != '\0') && (program_given == 0)) { - dbg("RESULT is only useful when PROGRAM called in any rule before"); + dbg(FIELD_RESULT " is only useful when " + FIELD_PROGRAM " is called in any rule before"); goto error; } diff --git a/test/udev-test.pl b/test/udev-test.pl index cbe110f797..abe622cf8a 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -191,6 +191,16 @@ EOF expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "select sysfs attribute by SYSFS{vendor}", + subsys => "block", + devpath => "block/sda", + expected => "disk-IBM-ESXS-sda" , + conf => < Date: Mon, 16 Feb 2004 21:44:28 -0800 Subject: [PATCH 0542/4284] [PATCH] udev - create all partitions of blockdevice Here is the first try to create all partitons of a blockdevice, since removable media devices may need to acces the expected partition to revalidate the media. It uses the attribute syntax introduced with the last %s{file} patch. I'm using this with my multi-slot-flash-card-reader: SYSFS{model}="USB Storage-SMC ", NAME{all_partitions}="smartmedia" SYSFS{model}="USB Storage-CFC ", NAME{all_partitions}="compactflash" SYSFS{model}="USB Storage-MSC ", NAME{all_partitions}="memorystick" SYSFS{model}="USB Storage-MMC ", NAME{all_partitions}="multimedia" and I get: tree /udev/ /udev/ |-- memorystick |-- memorystick1 |-- memorystick10 |-- memorystick11 |-- memorystick12 |-- memorystick13 |-- memorystick14 |-- memorystick15 |-- memorystick2 |-- memorystick3 |-- memorystick4 |-- memorystick5 |-- memorystick6 |-- memorystick7 |-- memorystick8 |-- memorystick9 |-- multimedia |-- multimedia1 |-- multimedia10 |-- multimedia11 |-- multimedia12 |-- multimedia13 |-- multimedia14 |-- multimedia15 |-- multimedia2 |-- multimedia3 |-- multimedia4 |-- multimedia5 |-- multimedia6 |-- multimedia7 |-- multimedia8 |-- multimedia9 ... If needed, we can make the number of partions to create adjustable with the attribute? --- namedev.c | 2 +- namedev.h | 39 ++++++++++++++------------ namedev_parse.c | 22 +++++++++------ test/udev-test.pl | 11 +++++++- udev-add.c | 71 ++++++++++++++++++++++++++++++----------------- udev-remove.c | 13 ++++++++- udev.h | 1 + 7 files changed, 106 insertions(+), 53 deletions(-) diff --git a/namedev.c b/namedev.c index cd38f25cb0..942788b2a2 100644 --- a/namedev.c +++ b/namedev.c @@ -820,7 +820,7 @@ found: /* substitute placeholder */ apply_format(udev, udev->name, class_dev, sysfs_device); apply_format(udev, udev->symlink, class_dev, sysfs_device); - + udev->partitions = dev->partitions; done: perm = find_perm(udev->name); if (perm) { diff --git a/namedev.h b/namedev.h index e38c4f5257..10a5dcaf0c 100644 --- a/namedev.h +++ b/namedev.h @@ -28,25 +28,29 @@ struct sysfs_class_device; -#define BUS_SIZE 30 -#define FILE_SIZE 50 -#define VALUE_SIZE 100 -#define ID_SIZE 50 -#define PLACE_SIZE 50 -#define PROGRAM_SIZE 100 +#define BUS_SIZE 30 +#define FILE_SIZE 50 +#define VALUE_SIZE 100 +#define ID_SIZE 50 +#define PLACE_SIZE 50 +#define PROGRAM_SIZE 100 -#define FIELD_BUS "BUS" -#define FIELD_SYSFS "SYSFS" -#define FIELD_ID "ID" -#define FIELD_PLACE "PLACE" -#define FIELD_PROGRAM "PROGRAM" -#define FIELD_RESULT "RESULT" -#define FIELD_KERNEL "KERNEL" -#define FIELD_NAME "NAME" -#define FIELD_SYMLINK "SYMLINK" +#define FIELD_BUS "BUS" +#define FIELD_SYSFS "SYSFS" +#define FIELD_ID "ID" +#define FIELD_PLACE "PLACE" +#define FIELD_PROGRAM "PROGRAM" +#define FIELD_RESULT "RESULT" +#define FIELD_KERNEL "KERNEL" +#define FIELD_NAME "NAME" +#define FIELD_SYMLINK "SYMLINK" -#define PROGRAM_MAXARG 10 -#define MAX_SYSFS_PAIRS 5 +#define ATTR_PARTITIONS "all_partitions" +#define PARTITIONS_COUNT 15 + + +#define PROGRAM_MAXARG 10 +#define MAX_SYSFS_PAIRS 5 struct sysfs_pair { char file[FILE_SIZE]; @@ -65,6 +69,7 @@ struct config_device { char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; + int partitions; int config_line; }; diff --git a/namedev_parse.c b/namedev_parse.c index 20ff60d640..d5d2181cb6 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -91,13 +91,6 @@ static char *get_key_attribute(char *str) char *pos; char *attr; - attr = strchr(str, '_'); - if (attr != NULL) { - attr++; - dbg("attribute='%s'", attr); - return attr; - } - attr = strchr(str, '{'); if (attr != NULL) { attr++; @@ -111,6 +104,13 @@ static char *get_key_attribute(char *str) return attr; } + attr = strchr(str, '_'); + if (attr != NULL) { + attr++; + dbg("attribute='%s'", attr); + return attr; + } + return NULL; } @@ -221,7 +221,13 @@ int namedev_init_rules(void) continue; } - if (strcasecmp(temp2, FIELD_NAME) == 0) { + if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) { + attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1); + if (attr != NULL) + if (strcasecmp(attr, ATTR_PARTITIONS) == 0) { + dbg_parse("creation of partition nodes requested"); + dev.partitions = PARTITIONS_COUNT; + } strfieldcpy(dev.name, temp3); continue; } diff --git a/test/udev-test.pl b/test/udev-test.pl index abe622cf8a..258d5c9596 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -350,7 +350,16 @@ KERNEL="ttyUSB0", NAME="visor", SYMLINK="first-%n second-%n third-%n" EOF }, { - desc => "sysfs parent heirachy", + desc => "create all possible partitions", + subsys => "block", + devpath => "block/sda", + expected => "boot_disk15" , + conf => < "sysfs parent hierarchy", subsys => "tty", devpath => "class/tty/ttyUSB0", expected => "visor" , diff --git a/udev-add.c b/udev-add.c index 8867c8f5af..3b3ebd5bbb 100644 --- a/udev-add.c +++ b/udev-add.c @@ -99,11 +99,44 @@ static int create_path(char *file) return 0; } +static int make_node(char *filename, int major, int minor, unsigned int mode, uid_t uid, gid_t gid) +{ + int retval; + + retval = mknod(filename, mode, makedev(major, minor)); + if (retval != 0) { + dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", + filename, mode, major, minor, strerror(errno)); + return retval; + } + + dbg("chmod(%s, %#o)", filename, mode); + retval = chmod(filename, mode); + if (retval != 0) { + dbg("chmod(%s, %#o) failed with error '%s'", + filename, mode, strerror(errno)); + return retval; + } + + if (uid != 0 || gid != 0) { + dbg("chown(%s, %u, %u)", filename, uid, gid); + retval = chown(filename, uid, gid); + if (retval != 0) { + dbg("chown(%s, %u, %u) failed with error '%s'", + filename, uid, gid, strerror(errno)); + return retval; + } + } + + return 0; +} + static int create_node(struct udevice *dev, int fake) { struct stat stats; char filename[255]; char linktarget[255]; + char partitionname[255]; char *linkname; char *symlinks; int retval = 0; @@ -135,23 +168,6 @@ static int create_node(struct udevice *dev, int fake) if (strrchr(dev->name, '/')) create_path(filename); - info("creating device node '%s'", filename); - dbg("mknod(%s, %#o, %u, %u)", filename, dev->mode, dev->major, dev->minor); - if (!fake) { - retval = mknod(filename, dev->mode, makedev(dev->major, dev->minor)); - if (retval != 0) - dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", - filename, dev->mode, dev->major, dev->minor, strerror(errno)); - } - - dbg("chmod(%s, %#o)", filename, dev->mode); - if (!fake) { - retval = chmod(filename, dev->mode); - if (retval != 0) - dbg("chmod(%s, %#o) failed with error '%s'", - filename, dev->mode, strerror(errno)); - } - if (dev->owner[0] != '\0') { char *endptr; unsigned long id = strtoul(dev->owner, &endptr, 10); @@ -180,12 +196,18 @@ static int create_node(struct udevice *dev, int fake) } } - if (uid != 0 || gid != 0) { - dbg("chown(%s, %u, %u)", filename, uid, gid); - retval = chown(filename, uid, gid); - if (retval != 0) - dbg("chown(%s, %u, %u) failed with error '%s'", - filename, uid, gid, strerror(errno)); + if (!fake) + info("creating device node '%s'", filename); + make_node(filename, dev->major, dev->minor, dev->mode, uid, gid); + + /* create partitions if requested */ + if (dev->partitions > 0) { + info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions); + for (i = 1; i <= dev->partitions; i++) { + sprintf(partitionname, "%s%i", filename, i); + make_node(partitionname, dev->major, dev->minor + i, + dev->mode, uid, gid); + } } /* create symlink if requested */ @@ -222,8 +244,7 @@ static int create_node(struct udevice *dev, int fake) strcpy(linktarget, "./"); strcat(linktarget, &dev->name[tail]); - /* unlink existing non-directories to ensure that our symlink - * is created */ + /* unlink existing files to ensure that our symlink is created */ if (!fake && (lstat(filename, &stats) == 0)) { if ((stats.st_mode & S_IFMT) != S_IFDIR) { if (unlink(filename)) diff --git a/udev-remove.c b/udev-remove.c index c21938fae7..c20c651dc5 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -66,9 +66,11 @@ static int delete_path(char *path) static int delete_node(struct udevice *dev) { char filename[255]; + char partitionname[255]; char *symlinks; char *linkname; int retval; + int i; strncpy(filename, udev_root, sizeof(filename)); strncat(filename, dev->name, sizeof(filename)); @@ -81,11 +83,20 @@ static int delete_node(struct udevice *dev) return retval; } + /* remove partition nodes */ + if (dev->partitions > 0) { + info("removing partitions '%s[1-%i]'", filename, dev->partitions); + for (i = 1; i <= dev->partitions; i++) { + sprintf(partitionname, "%s%i", filename, i); + unlink(partitionname); + } + } + /* remove subdirectories */ if (strchr(dev->name, '/')) delete_path(filename); - if (*dev->symlink) { + if (dev->symlink[0] != '\0') { symlinks = dev->symlink; while (1) { linkname = strsep(&symlinks, " "); diff --git a/udev.h b/udev.h index e615b4c8bb..e8f93ad5ad 100644 --- a/udev.h +++ b/udev.h @@ -46,6 +46,7 @@ struct udevice { int minor; unsigned int mode; /* not mode_t due to conflicting definitions in different libcs */ char symlink[NAME_SIZE]; + int partitions; /* private data that help us in building strings */ char bus_id[SYSFS_NAME_LEN]; From ab2e5bd94631eb3fcc66ec0aaa031d83a2de1604 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 16 Feb 2004 21:58:25 -0800 Subject: [PATCH 0543/4284] [PATCH] fix up bug created for udevtest in previous partition creation patch. --- udev-add.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/udev-add.c b/udev-add.c index 3b3ebd5bbb..a3bc0df579 100644 --- a/udev-add.c +++ b/udev-add.c @@ -196,17 +196,24 @@ static int create_node(struct udevice *dev, int fake) } } - if (!fake) + if (!fake) { info("creating device node '%s'", filename); make_node(filename, dev->major, dev->minor, dev->mode, uid, gid); + } else { + info("creating device node '%s', major = '%d', minor = '%d', " + "mode = '%#o', uid = '%d', gid = '%d'", filename, + dev->major, dev->minor, (mode_t)dev->mode, uid, gid); + } /* create partitions if requested */ if (dev->partitions > 0) { info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions); - for (i = 1; i <= dev->partitions; i++) { - sprintf(partitionname, "%s%i", filename, i); - make_node(partitionname, dev->major, dev->minor + i, - dev->mode, uid, gid); + if (!fake) { + for (i = 1; i <= dev->partitions; i++) { + sprintf(partitionname, "%s%i", filename, i); + make_node(partitionname, dev->major, + dev->minor + i, dev->mode, uid, gid); + } } } From 93656247f3b398959a0b40ac352b9f6ac195e86b Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Mon, 16 Feb 2004 22:00:38 -0800 Subject: [PATCH 0544/4284] [PATCH] udev add some ID tests Patch against current udev bk to add a few ID rule tests. --- test/udev-test.pl | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 258d5c9596..7459f8ff5c 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -384,6 +384,52 @@ EOF expected => "rd/c0d0" , conf => < "ID rule", + subsys => "block", + devpath => "block/sda", + expected => "scsi-0:0:0:0", + conf => < "ID wildcard all", + subsys => "block", + devpath => "block/sda", + expected => "scsi-0:0:0:0", + conf => < "ID wildcard partial", + subsys => "block", + devpath => "block/sda", + expected => "scsi-0:0:0:0", + conf => < "ID wildcard partial 2", + subsys => "block", + devpath => "block/sda", + expected => "scsi-0:0:0:0", + conf => < Date: Mon, 16 Feb 2004 22:31:15 -0800 Subject: [PATCH 0545/4284] [PATCH] Have udevd report it's version in debug mode. --- udevd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udevd.c b/udevd.c index 9fbb4e964b..f7901cb752 100644 --- a/udevd.c +++ b/udevd.c @@ -328,6 +328,7 @@ int main(int argc, char *argv[]) struct sigaction act; init_logging("udevd"); + dbg("version %s", UDEV_VERSION); if (getuid() != 0) { dbg("need to be root, exit"); From 8bbf27514c5e59f4982d0164af6b5df00ca2bac9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 16 Feb 2004 22:31:32 -0800 Subject: [PATCH 0546/4284] [PATCH] Have udevsend report more info in debug mode. --- udevsend.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/udevsend.c b/udevsend.c index c738fe2245..b5850294ae 100644 --- a/udevsend.c +++ b/udevsend.c @@ -142,30 +142,35 @@ int main(int argc, char* argv[]) #ifdef DEBUG init_logging("udevsend"); #endif + dbg("version %s", UDEV_VERSION); subsystem = argv[1]; if (subsystem == NULL) { dbg("no subsystem"); goto exit; } + dbg("subsystem = '%s'", subsystem); devpath = get_devpath(); if (devpath == NULL) { dbg("no devpath"); goto exit; } + dbg("DEVPATH = '%s'", devpath); action = get_action(); if (action == NULL) { dbg("no action"); goto exit; } + dbg("ACTION = '%s'", action); seqnum = get_seqnum(); if (seqnum == NULL) seq = -1; else seq = atoi(seqnum); + dbg("SEQNUM = '%d'", seq); sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { From 16378373cb9d96e5d424921806ff71f218e92694 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 17 Feb 2004 01:27:01 -0800 Subject: [PATCH 0547/4284] [PATCH] udev - switch SYSFS_file to SYSFS{file} Here we switch the configs and man pages to the new attribute syntax. Also the 'partition trick' is mentioned in udev.8 I think it's more clear visible now, that inside the brackets are user supplied values used and not some magic keys handled: 'SYSFS_dev' is now 'SYSFS{dev}' The old syntax is still supported. --- etc/udev/udev.rules | 4 ++-- etc/udev/udev.rules.gentoo | 6 +++--- test/label_test | 4 ++-- test/udev-test.pl | 36 ++++++++++++++++++------------------ udev.8 | 15 +++++++++++---- udevinfo.8 | 2 +- udevinfo.c | 2 +- 7 files changed, 38 insertions(+), 31 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 344304dd95..e1c2cbe91e 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -5,13 +5,13 @@ BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" # A usb camera. -BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" +BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n" # USB Epson printer to be called lp_epson BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" +BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card BUS="pci", ID="00:0b.0", NAME="dsp" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 0c53df535c..b3ca042224 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -23,13 +23,13 @@ BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" # A usb camera. -BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" +BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n" # USB Epson printer to be called lp_epson -BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" +BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" +BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card BUS="pci", ID="00:0b.0", NAME="dsp" diff --git a/test/label_test b/test/label_test index 93d02c18f2..b99a4acd54 100644 --- a/test/label_test +++ b/test/label_test @@ -8,8 +8,8 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_diskX%n" -BUS="scsi", SYSFS_vendor="IBM-ESXS", SYSFS_model="ST336605LW !#", NAME="boot_disk%n" +BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_diskX%n" +BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_disk%n" EOF cat > $CONFIG << EOF diff --git a/test/udev-test.pl b/test/udev-test.pl index 7459f8ff5c..e238c909fa 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -38,7 +38,7 @@ my @tests = ( devpath => "block/sda", expected => "boot_disk" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda/sda1", expected => "boot_disk1" , conf => < "block/sda", expected => "disk-IBM-ESXS-sda" , conf => < "class/tty/console", expected => "TTY" , conf => < "class/tty/console", expected => "foo" , conf => < "block/sda/sda2", expected => "1/2/a/b/symlink" , conf => < "block/sda/sda2", expected => "1/2/symlink" , conf => < "block/sda/sda2", expected => "1/2/c/d/symlink" , conf => < "block/sda", expected => "boot_disk15" , conf => < "class/tty/ttyUSB0", expected => "visor" , conf => <name, value); + printf(" SYSFS{%s}=\"%s\"\n", attr->name, value); } } printf("\n"); From 88f09368b3dc2d17cf2ce1a4841e42a120a4dbb9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 17 Feb 2004 01:29:03 -0800 Subject: [PATCH 0548/4284] [PATCH] udev - switch callout part selector to {attribute} Here we change the magic callout part number selector to the new atribute syntax. The syntax to select the second part of the callout string: '%2c' is now '%c{2}' I think it's more clear and we no longer misuse the length argument. The old syntax is still supported, but we should remove it some time in the future. --- etc/udev/udev.rules.devfs | 2 +- etc/udev/udev.rules.gentoo | 2 +- extras/ide-devfs.sh | 2 +- extras/name_cdrom.pl | 2 +- namedev.c | 11 ++++++++--- test/udev-test.pl | 12 +----------- 6 files changed, 13 insertions(+), 18 deletions(-) diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index f9333e91c4..77d3cf5414 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -2,7 +2,7 @@ # fields. See the udev man page for a full description of them. # ide block devices -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%1c %2c" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" # md block devices KERNEL="md[0-9]*", NAME="md/%n" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index b3ca042224..7e8966961d 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -57,7 +57,7 @@ KERNEL="ttyUSB0", NAME="pl2303" # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%1c", SYMLINK="%2c %3c" +BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%c{1}", SYMLINK="%c{2} %c{3}" # fb devices KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 1cf6f9c9e4..0a9369dff4 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -2,7 +2,7 @@ # udev external PROGRAM script # return devfs-names for ide-devices -# BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%1c %2c" +# BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" HOST="${2%\.[0-9]}" TARGET="${2#[0-9]\.}" diff --git a/extras/name_cdrom.pl b/extras/name_cdrom.pl index 3a4772e6d9..766f6f366a 100644 --- a/extras/name_cdrom.pl +++ b/extras/name_cdrom.pl @@ -2,7 +2,7 @@ # a horribly funny script that shows how flexible udev can really be # This is to be executed by udev with the following rules: -# KERNEL="[hs]d[a-z]", PROGRAM="name_cdrom.pl %M %m", NAME="%1c", SYMLINK="cdrom" +# KERNEL="[hs]d[a-z]", PROGRAM="name_cdrom.pl %M %m", NAME="%c{1}", SYMLINK="cdrom" use strict; use warnings; diff --git a/namedev.c b/namedev.c index 942788b2a2..186a9f5cc2 100644 --- a/namedev.c +++ b/namedev.c @@ -219,6 +219,7 @@ static void apply_format(struct udevice *udev, unsigned char *string, struct sys char *pos3; char *attr; int num; + int i; char c; struct sysfs_attribute *tmpattr; @@ -270,11 +271,15 @@ static void apply_format(struct udevice *udev, unsigned char *string, struct sys case 'c': if (strlen(udev->program_result) == 0) break; - if (num > 0) { + /* get part part of the result string */ + i = num; /* num syntax is deprecated and will be removed */ + if (attr != NULL) + i = atoi(attr); + if (i > 0) { strncpy(temp1, udev->program_result, sizeof(temp1)); pos2 = temp1; - while (num) { - num--; + while (i) { + i--; pos3 = strsep(&pos2, " "); if (pos3 == NULL) { dbg("requested part of result string not found"); diff --git a/test/udev-test.pl b/test/udev-test.pl index e238c909fa..6e031c4c2c 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -191,16 +191,6 @@ EOF expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "select sysfs attribute by SYSFS{vendor}", - subsys => "block", - devpath => "block/sda", - expected => "disk-IBM-ESXS-sda" , - conf => < "block/sda/sda3", expected => "link1" , conf => < Date: Tue, 17 Feb 2004 01:31:42 -0800 Subject: [PATCH 0549/4284] [PATCH] add a "old style" SYSFS_attribute test to udev-test.pl --- test/udev-test.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 6e031c4c2c..f2f77dd0e4 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -191,6 +191,15 @@ EOF expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "old style SYSFS_ attribute", + subsys => "block", + devpath => "block/sda", + expected => "good" , + conf => < Date: Tue, 17 Feb 2004 18:17:50 -0800 Subject: [PATCH 0550/4284] [PATCH] udev - udevd/udevsend man page Here is the missing man page for udevd/udevsend. --- Makefile | 2 ++ udevd.8 | 36 ++++++++++++++++++++++++++++++++++++ udevinfo.8 | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 udevd.8 diff --git a/Makefile b/Makefile index 936a6613f0..25881e1dd3 100644 --- a/Makefile +++ b/Makefile @@ -361,6 +361,8 @@ install: install-config install-dbus-policy all fi $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 + $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 + - ln -f -s ./udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - rm -f $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug - rm -f $(udevdir)/.udev.tdb - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug diff --git a/udevd.8 b/udevd.8 new file mode 100644 index 0000000000..401e9b2ade --- /dev/null +++ b/udevd.8 @@ -0,0 +1,36 @@ +.TH UDEVD 8 "February 2004" "" "Linux Administrator's Manual" +.SH NAME +udevd \- udev event serializer daemon +.br +udevsend \- sends the event to udevd +.SH "DESCRIPTION" +.B udevd +allows the serialization of +.BR hotplug (8) +events. The events generated by the kernel may arrive in random order +in userspace, that makes it neccessary to reorder it. +.br +.B udevd +takes care of the kernel supplied sequence number and arranges the events for +execution in the correct order. Missing sequences are delaying the +execution of the following events until a timeout of a maximum of 5 seconds +is reached. +.br +For each event a +.BR udev (8) +instance is executed in the background. All further events for the same device +are delayed until the execution is finished. This way it will never run more +than one instance for a single device. +.br +.B udevd +receives the events from +.B udevsend +which is called by +.BR hotplug (8) + +.SH "SEE ALSO" +.BR udev (8) +.SH AUTHORS +.B udevd +was developed primarily by Kay Sievers , with much help +from others. diff --git a/udevinfo.8 b/udevinfo.8 index 67d034aea6..1716d17434 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -1,4 +1,4 @@ -.TH UDEVINFO 8 "October 2003" "" "Linux Administrator's Manual" +.TH UDEVINFO 8 "January 2004" "" "Linux Administrator's Manual" .SH NAME udevinfo \- retrieve information from udev .SH SYNOPSIS From 20f86361f48da48b08e1b73b04e22ea098f64e72 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 17 Feb 2004 18:34:23 -0800 Subject: [PATCH 0551/4284] [PATCH] update the red hat init script to handle nodes that are not present Thanks to Gentoo for the list of these files. --- etc/init.d/udev | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/etc/init.d/udev b/etc/init.d/udev index 69c1bab74e..3f1430271b 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -1,6 +1,6 @@ #! /bin/bash # -# random init script to setup /udev +# udev init script to setup /udev # # chkconfig: 2345 20 80 # description: manage user-space device nodes in /udev @@ -12,6 +12,7 @@ prog=udev sysfs_dir=/sys bin=/sbin/udev +udev_root=/udev run_udev () { # handle block devices and their partitions @@ -42,9 +43,34 @@ run_udev () { return 0 } +make_extra_nodes () { + # there are a few things that sysfs does not export for us. + # these things go here (and remember to remove them in + # remove_extra_nodes() + # + # Thanks to Gentoo for the initial list of these. + ln -snf /proc/self/fd $udev_root/fd + ln -snf /proc/self/fd/0 $udev_root/stdin + ln -snf /proc/self/fd/1 $udev_root/stdout + ln -snf /proc/self/fd/2 $udev_root/stderr + ln -snf /proc/kcore $udev_root/core + #ln -snf /proc/asound/oss/sndstat $udev_root/sndstat +} + +remove_extra_nodes () { + # get rid of the extra nodes created in make_extra_nodes() + rm $udev_root/fd + rm $udev_root/stdin + rm $udev_root/stdout + rm $udev_root/stderr + rm $udev_root/core + #rm $udev_root/sndstat +} + case "$1" in start) - if [ ! -d $sysfs_dir ]; then + # don't use udev if sysfs is not mounted. + if [ ! -d $sysfs_dir/block ]; then exit 1 fi if [ ! -d $udev_root ]; then @@ -61,7 +87,8 @@ case "$1" in # device bring up export ACTION=add echo -n $"Creating initial udev device nodes:" - run_udev + run_udev + make_extra_nodes success /bin/true echo touch /var/lock/subsys/udev @@ -71,6 +98,7 @@ case "$1" in echo -n $"Removing udev device nodes: " export ACTION=remove run_udev + remove_extra_nodes success /bin/true echo rm -f /var/lock/subsys/udev From ad63031e49abc18a961c4b4302312744a487f417 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 17 Feb 2004 19:02:39 -0800 Subject: [PATCH 0552/4284] [PATCH] udev - add %s{filename} to man page Add the new %s{filename} to the udev man page. And add the automatic start of udevd to the udevd man page. --- udev.8 | 7 +++++++ udevd.8 | 12 ++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/udev.8 b/udev.8 index 9291f33242..603ca45cba 100644 --- a/udev.8 +++ b/udev.8 @@ -195,6 +195,13 @@ returned string. (This does not work within the .B PROGRAM field for the obvious reason.) +.br +A single part of the string, separated by the space character +my be selected by specifying the part number as a attribute: +.BI %c{ part } +.TP +.BI %s{ filename } +The content of a sysfs attribute. .TP .B %% The '%' char itself. diff --git a/udevd.8 b/udevd.8 index 401e9b2ade..59dc0206c2 100644 --- a/udevd.8 +++ b/udevd.8 @@ -20,16 +20,20 @@ For each event a .BR udev (8) instance is executed in the background. All further events for the same device are delayed until the execution is finished. This way it will never run more -than one instance for a single device. +than one instance for a single device at the same time. .br .B udevd receives the events from .B udevsend which is called by -.BR hotplug (8) - +.BR hotplug (8). +If +.B udevd +isn't already running, +.B udevsend +will start it. .SH "SEE ALSO" -.BR udev (8) +.BR udev (8), hotplug (8) .SH AUTHORS .B udevd was developed primarily by Kay Sievers , with much help From 24f8f09876e426ab1b5a4b7c76f25eededbeaa11 Mon Sep 17 00:00:00 2001 From: "john-hotplug@fjellstad.org" Date: Tue, 17 Feb 2004 19:02:44 -0800 Subject: [PATCH 0553/4284] [PATCH] init.d debian patch I dualboot between 2.4.x and 2.6.x right now, and although I want udev to start up when 2.6 is booting, I don't want it to try when 2.4.x is booting. This is a small patch to not start up udev if sysfs is not mounted. --- etc/init.d/udev.debian | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/etc/init.d/udev.debian b/etc/init.d/udev.debian index d67941cc13..776a73644c 100644 --- a/etc/init.d/udev.debian +++ b/etc/init.d/udev.debian @@ -61,7 +61,8 @@ case "$1" in if [ ! -d $udev_dir ]; then mkdir $udev_dir fi - if [ ! -d $sysfs_dir ]; then + # don't use udev if sysfs is not mounted + if [ ! -d $sysfs_dir/block ]; then exit 1 fi # propogate /udev from /sys - we only need this while we do not From f01f8c667793ef10baac489cf845ba273fd023db Mon Sep 17 00:00:00 2001 From: "ext.devoteam.varoqui@sncf.fr" Date: Tue, 17 Feb 2004 19:07:56 -0800 Subject: [PATCH 0554/4284] [PATCH] update extras/multipath patch follows : * remove the restrictive -f flag. Introduce a more generic "-m iopolicy" one. * remove useless "int with_sysfs" in env struct --- extras/multipath/ChangeLog | 4 ++++ extras/multipath/main.c | 43 +++++++++++++++++++++----------------- extras/multipath/main.h | 2 +- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index 31f6c48f69..43aa497e51 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,3 +1,7 @@ +2004-02-17 multipath-017 + * remove the restrictive -f flag. + Introduce a more generic "-m iopolicy" one. + * remove useless "int with_sysfs" in env struct 2004-02-04 multipath-016 * add a GROUP_BY_SERIAL flag. This should be useful for controlers that activate they spare paths on simple IO diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 6ea9a064e1..706b2d1317 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -509,8 +509,8 @@ setup_map(struct env * conf, struct path * all_paths, params_p += sprintf(params_p, "%i", conf->dm_path_test_int); - if (all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && - !conf->forcedfailover ) { + if ((all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && + conf->iopolicy == -1) || conf->iopolicy == MULTIBUS) { params_p += sprintf(params_p, " 1 %i %s %i %i", dm_pg_prio, dm_ps_name, np, dm_ps_nr_args); @@ -522,8 +522,8 @@ setup_map(struct env * conf, struct path * all_paths, } } - if (all_paths[PINDEX(index,0)].iopolicy == FAILOVER || - conf->forcedfailover) { + if ((all_paths[PINDEX(index,0)].iopolicy == FAILOVER && + conf->iopolicy == -1) || conf->iopolicy == FAILOVER) { params_p += sprintf(params_p, " %i", mp[index].npaths + 1); for (i=0; i<=mp[index].npaths; i++) { if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) @@ -537,8 +537,8 @@ setup_map(struct env * conf, struct path * all_paths, } } - if (all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_SERIAL && - !conf->forcedfailover ) { + if ((all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_SERIAL && + conf->iopolicy == -1) || conf->iopolicy == GROUP_BY_SERIAL) { group_by_serial(&mp[index], all_paths, params_p); } @@ -602,14 +602,18 @@ static void usage(char * progname) { fprintf(stderr, VERSION_STRING); - fprintf(stderr, "Usage: %s [-v|-q] [-d] [-i int] [-m max_devs]\n", + fprintf(stderr, "Usage: %s [-v|-q] [-d] [-i int] [-m max_devs] ", progname); + fprintf(stderr, "[-p failover|multibus|group_by_serial]\n"); + fprintf(stderr, "\t-v\t\tverbose, print all paths and multipaths\n"); + fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); fprintf(stderr, "\t-d\t\tdry run, do not create or update devmaps\n"); - fprintf(stderr, "\t-f\t\tforce maps to failover mode (1 path/pg)\n"); fprintf(stderr, "\t-i\t\tmultipath target param : polling interval\n"); fprintf(stderr, "\t-m max_devs\tscan {max_devs} devices at most\n"); - fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); - fprintf(stderr, "\t-v\t\tverbose, print all paths and multipaths\n"); + fprintf(stderr, "\t-p policy\tforce maps to specified policy :\n"); + fprintf(stderr, "\t\t\tfailover\t1 path per priority group\n"); + fprintf(stderr, "\t\t\tmultibus\tall paths in 1 priority group\n"); + fprintf(stderr, "\t\t\tgroup_by_serial\t1 priority group per serial\n"); exit(1); } @@ -627,13 +631,9 @@ main(int argc, char *argv[]) conf.dry_run = 0; /* 1 == Do not Create/Update devmaps */ conf.verbose = 0; /* 1 == Print all_paths and mp */ conf.quiet = 0; /* 1 == Do not even print devmaps */ - conf.with_sysfs = 0; /* Default to compat / suboptimal behaviour */ + conf.iopolicy = -1; /* Apply the defaults in get_unique_id() */ conf.dm_path_test_int = 10; - /* kindly provided by libsysfs */ - if (0 == sysfs_get_mnt_path(conf.sysfs_path, FILE_NAME_SIZE)) - conf.with_sysfs = 1; - for (i = 1; i < argc; ++i) { if (0 == strcmp("-v", argv[i])) { if (conf.quiet == 1) @@ -649,11 +649,16 @@ main(int argc, char *argv[]) conf.quiet = 1; } else if (0 == strcmp("-d", argv[i])) conf.dry_run = 1; - else if (0 == strcmp("-f", argv[i])) - conf.forcedfailover = 1; else if (0 == strcmp("-i", argv[i])) conf.dm_path_test_int = atoi(argv[++i]); - else if (0 == strcmp("scsi", argv[i])) + else if (0 == strcmp("-p", argv[i++])) { + if (!strcmp(argv[i], "failover")) + conf.iopolicy = FAILOVER; + if (!strcmp(argv[i], "multibus")) + conf.iopolicy = MULTIBUS; + if (!strcmp(argv[i], "group_by_serial")) + conf.iopolicy = GROUP_BY_SERIAL; + } else if (0 == strcmp("scsi", argv[i])) strcpy(conf.hotplugdev, argv[++i]); else if (*argv[i] == '-') { fprintf(stderr, "Unknown switch: %s\n", argv[i]); @@ -672,7 +677,7 @@ main(int argc, char *argv[]) if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) exit(1); - if (!conf.with_sysfs) { + if (sysfs_get_mnt_path(conf.sysfs_path, FILE_NAME_SIZE)) { get_all_scsi_ids(&conf, all_scsi_ids); get_all_paths_nosysfs(&conf, all_paths, all_scsi_ids); } else { diff --git a/extras/multipath/main.h b/extras/multipath/main.h index 731c55e41f..e05555599f 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -100,7 +100,7 @@ struct env { int verbose; int quiet; int dry_run; - int forcedfailover; + int iopolicy; int with_sysfs; int dm_path_test_int; char sysfs_path[FILE_NAME_SIZE]; From 8fff7b42b45ef13946f7bc25308016d3dfdc63df Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 17 Feb 2004 19:31:33 -0800 Subject: [PATCH 0555/4284] [PATCH] start up udevd ourselves in the init script to give it some good priorities. --- etc/init.d/udev | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/etc/init.d/udev b/etc/init.d/udev index 3f1430271b..cd9074de09 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -12,6 +12,7 @@ prog=udev sysfs_dir=/sys bin=/sbin/udev +udevd=/sbin/udevd udev_root=/udev run_udev () { @@ -89,6 +90,11 @@ case "$1" in echo -n $"Creating initial udev device nodes:" run_udev make_extra_nodes + + # We want to start udevd ourselves if it isn't already running. This + # lets udevd run at a sane nice level... + $udevd & + success /bin/true echo touch /var/lock/subsys/udev From 961e47847cdb33b1fabe4084cef7cd37f73a19d1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 17 Feb 2004 20:59:26 -0800 Subject: [PATCH 0556/4284] [PATCH] add support for UDEV_NO_SLEEP env variable so Gentoo people will be happy. Actually, I'm happy to, startup time is much smaller... --- namedev.c | 6 ++++-- udev.h | 1 + udev_config.c | 5 +++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 186a9f5cc2..90c85d41e4 100644 --- a/namedev.c +++ b/namedev.c @@ -623,7 +623,8 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de tspec.tv_nsec = 10000000; /* sleep 10 millisec */ loop = 10; while (loop--) { - nanosleep(&tspec, NULL); + if (udev_sleep) + nanosleep(&tspec, NULL); if (class_dev_parent) sysfs_device = sysfs_get_classdev_device(class_dev_parent); else @@ -650,7 +651,8 @@ device_found: loop = 10; tspec.tv_nsec = 10000000; while (loop--) { - nanosleep(&tspec, NULL); + if (udev_sleep) + nanosleep(&tspec, NULL); sysfs_get_device_bus(sysfs_device); if (sysfs_device->bus[0] != '\0') diff --git a/udev.h b/udev.h index e8f93ad5ad..1cd07852b4 100644 --- a/udev.h +++ b/udev.h @@ -78,5 +78,6 @@ extern char default_mode_str[MODE_SIZE]; extern char default_owner_str[OWNER_SIZE]; extern char default_group_str[GROUP_SIZE]; extern int udev_log; +extern int udev_sleep; #endif diff --git a/udev_config.c b/udev_config.c index 34ef82b881..6714c1b73d 100644 --- a/udev_config.c +++ b/udev_config.c @@ -49,6 +49,7 @@ char default_mode_str[MODE_SIZE]; char default_owner_str[OWNER_SIZE]; char default_group_str[GROUP_SIZE]; int udev_log; +int udev_sleep; static int string_is_true(char *str) @@ -71,6 +72,10 @@ static void init_variables(void) strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); udev_log = string_is_true(UDEV_LOG_DEFAULT); + + udev_sleep = 1; + if (getenv("UDEV_NO_SLEEP") != NULL) + udev_sleep = 0; } #define set_var(_name, _var) \ From 2152332ea77b4dfdf04693b2861a58264259ece9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 17 Feb 2004 21:35:56 -0800 Subject: [PATCH 0557/4284] [PATCH] add start_udev init script. --- extras/start_udev | 91 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 extras/start_udev diff --git a/extras/start_udev b/extras/start_udev new file mode 100644 index 0000000000..caba5270c2 --- /dev/null +++ b/extras/start_udev @@ -0,0 +1,91 @@ +#! /bin/bash +# +# start_udev +# +# script to initialize /dev by using udev. +# +# This needs to be run at the earliest possible point in the boot +# process. +# +# Based on the udev init.d script +# + +. /etc/udev/udev.conf + +prog=udev +sysfs_dir=/sys +bin=/sbin/udev +udevd=/sbin/udevd + +run_udev () { + # handle block devices and their partitions + for i in ${sysfs_dir}/block/*; do + # add each drive + export DEVPATH=${i#${sysfs_dir}} + echo "$DEVPATH" + $bin block + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + echo "$DEVPATH" + $bin block + fi + done + done + # all other device classes + for i in ${sysfs_dir}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${sysfs_dir}} + CLASS=`echo ${i#${sysfs_dir}} | \ + cut --delimiter='/' --fields=3-` + echo "$DEVPATH" + $bin $CLASS + fi + done + done + return 0 +} + +make_extra_nodes () { + # there are a few things that sysfs does not export for us. + # these things go here (and remember to remove them in + # remove_extra_nodes() + # + # Thanks to Gentoo for the initial list of these. + ln -snf /proc/self/fd $udev_root/fd + ln -snf /proc/self/fd/0 $udev_root/stdin + ln -snf /proc/self/fd/1 $udev_root/stdout + ln -snf /proc/self/fd/2 $udev_root/stderr + ln -snf /proc/kcore $udev_root/core + + mkdir $udev_root/pts + mkdir $udev_root/shm +} + +# don't use udev if sysfs is not mounted. +if [ ! -d $sysfs_dir/block ]; then + exit 1 +fi + +echo "mounting... ramfs at $udev_root" +mount -n -t ramfs none $udev_root + +# We want to start udevd ourselves if it isn't already running. This +# lets udevd run at a sane nice level... +echo "starting udevd" +$udevd & + +# propogate /udev from /sys +export ACTION=add +export UDEV_NO_SLEEP=1 +echo "Creating initial udev device nodes:" +run_udev + +echo "making extra nodes" +make_extra_nodes + +echo "udev startup is finished!" +exit 0 From a638109dfa2e99c31c74ce107940c8171027ba2e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 17 Feb 2004 23:56:59 -0800 Subject: [PATCH 0558/4284] [PATCH] mv libsysfs/libsysfs.h to libsysfs/sysfs/libsysfs.h to make it easier to use. --- libsysfs/{ => sysfs}/libsysfs.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libsysfs/{ => sysfs}/libsysfs.h (100%) diff --git a/libsysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h similarity index 100% rename from libsysfs/libsysfs.h rename to libsysfs/sysfs/libsysfs.h From 0bad3406c1e8eba6d5af2cbfd44d8a61231fa2bb Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Tue, 17 Feb 2004 23:59:06 -0800 Subject: [PATCH 0559/4284] [PATCH] udev use new libsysfs header file location Use the new location of libsysfs header files. --- extras/scsi_id/scsi_id.c | 8 +------- extras/scsi_id/scsi_serial.c | 8 +------- libsysfs/sysfs_bus.c | 2 +- libsysfs/sysfs_class.c | 2 +- libsysfs/sysfs_device.c | 2 +- libsysfs/sysfs_dir.c | 2 +- libsysfs/sysfs_driver.c | 2 +- libsysfs/sysfs_utils.c | 2 +- namedev.c | 2 +- udev-add.c | 2 +- udev.c | 2 +- udev.h | 2 +- udev_config.c | 2 +- udevdb.c | 2 +- udevinfo.c | 2 +- udevtest.c | 2 +- 16 files changed, 16 insertions(+), 28 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 75a342bb12..2754381976 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -32,14 +32,8 @@ #include #include #include -#ifdef __KLIBC__ -/* - * Assume built under udev with KLIBC - */ -#include -#else #include -#endif + #include "scsi_id_version.h" #include "scsi_id.h" diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 80a1d51635..9fb0f05e61 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -31,14 +31,8 @@ #include #include #include -#ifdef __KLIBC__ -/* - * Assume built under udev with KLIBC - */ -#include -#else #include -#endif + #include "scsi_id.h" #include "scsi.h" diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index aca392875e..87318c0029 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" static void sysfs_close_dev(void *dev) diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index cd86912142..05305056dd 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" static void sysfs_close_cls_dev(void *dev) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index bfd761b885..06b8d2d99a 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" /** diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index ce01669754..050e674038 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" /** diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index a4440cfdf9..cd202d9f23 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" static void sysfs_close_driver_device(void *device) diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index f1f82361d0..2509c73c98 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "libsysfs.h" +#include "sysfs/libsysfs.h" #include "sysfs.h" #ifndef __KLIBC__ #include diff --git a/namedev.c b/namedev.c index 90c85d41e4..89513934ff 100644 --- a/namedev.c +++ b/namedev.c @@ -32,13 +32,13 @@ #include #include #include +#include #include "list.h" #include "udev.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" -#include "libsysfs/libsysfs.h" #include "klibc_fixups.h" static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr); diff --git a/udev-add.c b/udev-add.c index a3bc0df579..87cf57c3b6 100644 --- a/udev-add.c +++ b/udev-add.c @@ -33,6 +33,7 @@ #ifndef __KLIBC__ #include #endif +#include #include "udev.h" #include "udev_version.h" @@ -40,7 +41,6 @@ #include "logging.h" #include "namedev.h" #include "udevdb.h" -#include "libsysfs/libsysfs.h" #include "klibc_fixups.h" /* diff --git a/udev.c b/udev.c index ce6d6ce9df..f3fab18b29 100644 --- a/udev.c +++ b/udev.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" @@ -33,7 +34,6 @@ #include "logging.h" #include "namedev.h" #include "udevdb.h" -#include "libsysfs/libsysfs.h" /* global variables */ char **main_argv; diff --git a/udev.h b/udev.h index 1cd07852b4..b5088b90c6 100644 --- a/udev.h +++ b/udev.h @@ -23,7 +23,7 @@ #ifndef UDEV_H #define UDEV_H -#include "libsysfs/libsysfs.h" +#include #include #include diff --git a/udev_config.c b/udev_config.c index 6714c1b73d..1d05a3fb13 100644 --- a/udev_config.c +++ b/udev_config.c @@ -31,12 +31,12 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" -#include "libsysfs/libsysfs.h" /* global variables */ char sysfs_path[SYSFS_PATH_MAX]; diff --git a/udevdb.c b/udevdb.c index e657fedcb2..bfd5b4bd69 100644 --- a/udevdb.c +++ b/udevdb.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "udev_version.h" #include "udev.h" @@ -39,7 +40,6 @@ #include "namedev.h" #include "udevdb.h" #include "tdb/tdb.h" -#include "libsysfs/libsysfs.h" static TDB_CONTEXT *udevdb; diff --git a/udevinfo.c b/udevinfo.c index e4ea698111..7991855b28 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -26,12 +26,12 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" #include "logging.h" #include "udevdb.h" -#include "libsysfs/libsysfs.h" # define SYSFS_VALUE_MAX 200 diff --git a/udevtest.c b/udevtest.c index dd8375aa5c..175f143269 100644 --- a/udevtest.c +++ b/udevtest.c @@ -26,12 +26,12 @@ #include #include #include +#include #include "udev.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" -#include "libsysfs/libsysfs.h" /* global variables */ char **main_argv; From b07ed5a7dcfc6d8b5eb98f97592267a6f35de820 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 18 Feb 2004 00:04:58 -0800 Subject: [PATCH 0560/4284] [PATCH] udev - TODO update Make TODO really small :) --- TODO | 8 -------- 1 file changed, 8 deletions(-) diff --git a/TODO b/TODO index dffa809df9..1a29adba0e 100644 --- a/TODO +++ b/TODO @@ -7,17 +7,9 @@ greg@kroah.com - more documentation (can never have too much.) -- better partition support (it's a hack right now, maybe new libsysfs changes - can help out a lot here.) -- option to always add all partitions. This is needed to properly handle - devices with removable media. - install the proper init.d script based on the distro we are running on. - persuade the distro packagers to submit their changes (or just steal them if we can find them...) -- allow database to be queried by other programs -- split program into two pieces (daemon and helper that sends events to it). - This will allow us to keep track of sequences, and lots of other needed - stuff. - keep track of current permissions on devices when daemon shuts down. - better permission handling - create kernel name to devfs name config file so that all of the devfs users From de46ad1952a40911eeea9fd941f578b6dacc1cec Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 18 Feb 2004 23:54:01 -0800 Subject: [PATCH 0561/4284] [PATCH] add HOWTO detailing how to use udev to manage /dev --- HOWTO-udev_for_dev | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 HOWTO-udev_for_dev diff --git a/HOWTO-udev_for_dev b/HOWTO-udev_for_dev new file mode 100644 index 0000000000..75a858f22a --- /dev/null +++ b/HOWTO-udev_for_dev @@ -0,0 +1,73 @@ +HOWTO use udev to manage /dev + + This document describes one way to get udev working on a Fedora-development + machine to manage /dev. This procedure may be used to get udev to manage + /dev on other distros, if you modify some of the steps. + + This will only work if you use a 2.6 based kernel, preferably the most + recent one. This does not prevent your machine from using a 2.4 + kernel, if you boot into one, udev will not run and your old /dev will + be present with no changes needed. + + +NOTE NOTE NOTE NOTE NOTE NOTE NOTE + This is completely unsupported. Attempting to do this may cause your + machine to be unable to boot properly. USE AT YOUR OWN RISK. Always + have a rescue disk or CD handy to allow you to fix up any errors that + may occur. +NOTE NOTE NOTE NOTE NOTE NOTE NOTE + + + - Build and install udev as specified in the README that comes with + udev. I recommend using the following build options to get the + smallest possible binaries: + make USE_KLIBC=true USE_LOG=false DEBUG=false + + - disable udev from the boot process by running: + chkconfig udev off + or + chkconfig --del udev + as root. + + - place the start_udev script somewhere that is accessible by your + initscripts. I placed it into /etc/rc.d with the following command: + copy extras/start_udev /etc/rc.d/ + + - modify the rc.sysinit script to call the start_udev script as one of + the first things that it does, but after /proc and /sys are mounted. + I did this with the latest Fedora startup scripts with the patch at + the end of this file. + + - reboot into a 2.6 kernel and watch udev create all of the initial + device nodes in /dev + + +If anyone has any problems with this, please let me, and the +linux-hotplug-devel@lists.sourceforge.net mailing list know. + +A big thanks go out to the Gentoo developers for showing me that this is +possible to do. + +Greg Kroah-Hartman + + + +---------------------------------- +Patch to modify rc.sysinit to call udev at the beginning of the boot +process: + + +--- /etc/rc.sysinit.orig 2004-02-17 11:45:17.000000000 -0800 ++++ /etc/rc.sysinit 2004-02-17 13:28:33.000000000 -0800 +@@ -32,6 +32,9 @@ + + . /etc/init.d/functions + ++# start udev to populate /dev ++/etc/rc.d/start_udev ++ + if [ "$HOSTTYPE" != "s390" -a "$HOSTTYPE" != "s390x" ]; then + last=0 + for i in `LC_ALL=C grep '^[0-9].*respawn:/sbin/mingetty' /etc/inittab | sed 's/^.* tty\([0-9][0-9]*\).*/\1/g'`; do + + From 7fdc5cb4454d21b3451d3492f45e3891e5780f75 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 18 Feb 2004 23:59:54 -0800 Subject: [PATCH 0562/4284] [PATCH] more HOWTO cleanups. --- HOWTO-udev_for_dev | 4 ++++ extras/start_udev | 11 +++++++++++ 2 files changed, 15 insertions(+) diff --git a/HOWTO-udev_for_dev b/HOWTO-udev_for_dev index 75a858f22a..a6d0892e37 100644 --- a/HOWTO-udev_for_dev +++ b/HOWTO-udev_for_dev @@ -38,6 +38,10 @@ NOTE NOTE NOTE NOTE NOTE NOTE NOTE I did this with the latest Fedora startup scripts with the patch at the end of this file. + - make sure the /etc/udev/udev.conf file lists the udev_root as /dev. + It should contain the following line in order to work properly. + udev_root="/dev/" + - reboot into a 2.6 kernel and watch udev create all of the initial device nodes in /dev diff --git a/extras/start_udev b/extras/start_udev index caba5270c2..3c39fc9260 100644 --- a/extras/start_udev +++ b/extras/start_udev @@ -4,11 +4,22 @@ # # script to initialize /dev by using udev. # +# Copyright (C) 2004 Greg Kroah-Hartman +# +# Released under the GPL v2 only. +# # This needs to be run at the earliest possible point in the boot # process. # # Based on the udev init.d script # +# Thanks go out to the Gentoo developers for proving +# that this is possible to do. +# +# Yes, it's very verbose, feel free to turn off all of the echo calls, +# they were there to make me feel better that everything was working +# properly during development... +# . /etc/udev/udev.conf From 67632351ec672ea7891a43fbceec696690dd940b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 19 Feb 2004 17:43:43 -0800 Subject: [PATCH 0563/4284] [PATCH] add udevd priority issue to the TODO list. --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 1a29adba0e..a87f398a03 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,9 @@ greg@kroah.com - more documentation (can never have too much.) +- have udevd move up to the "default" priority level if it is started by + keventd (otherwise it runs at a _very_ low priority level.) Don't + know if this is necessary, but it would be nice to do. - install the proper init.d script based on the distro we are running on. - persuade the distro packagers to submit their changes (or just steal them if we can find them...) From 3217d739fb0fb17656dfdfc5d2a2aec389dcc811 Mon Sep 17 00:00:00 2001 From: "ext.devoteam.varoqui@sncf.fr" Date: Thu, 19 Feb 2004 17:45:37 -0800 Subject: [PATCH 0564/4284] [PATCH] symlink dm-[0-9]* rule --- etc/udev/udev.rules | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index e1c2cbe91e..6e6bf4786b 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -37,8 +37,9 @@ KERNEL="ttyUSB0", NAME="pl2303" # if this is a ide cdrom, name it the default name, and create a symlink to cdrom BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" -# device mapper creates its own device nodes so ignore these -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" # DRI devices always go into a subdirectory (as per the LSB spec) KERNEL="card*", NAME="dri/card%n" From 1d24d9977d46e20779e7d9d05f4b6aa6dcad28cc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 19 Feb 2004 17:54:48 -0800 Subject: [PATCH 0565/4284] [PATCH] Create a udev.rules.examples file to hold odd udev.rules These are for examples only, not for everyone to use as they cause too many problems for different people when they are in the main udev.rules file. --- etc/udev/udev.rules | 36 ++----------------- etc/udev/udev.rules.examples | 68 ++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 33 deletions(-) create mode 100644 etc/udev/udev.rules.examples diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 6e6bf4786b..370a961de1 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -1,38 +1,8 @@ # 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. - -# Looking for scsi bus id 42:0:0:1 -BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" - -# A usb camera. -BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n" - -# USB Epson printer to be called lp_epson -BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" - -# USB HP printer to be called lp_hp -BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_hp" - -# sound card with PCI bus id 00:0b.0 to be the first sound card -BUS="pci", ID="00:0b.0", NAME="dsp" - -# sound card with PCI bus id 00:07.1 to be the second sound card -BUS="pci", ID="00:07.1", NAME="dsp1" - -# USB mouse plugged into the third port of the first hub to be called mouse0 -BUS="usb", PLACE="1.3", NAME="mouse0" - -# USB tablet plugged into the third port of the second hub to be called mouse1 -BUS="usb", PLACE="2.3", NAME="mouse1" -BUS="usb", PLACE="2.4", NAME="mouse2" - -# ttyUSB1 should always be called visor -KERNEL="ttyUSB1", NAME="visor" -KERNEL="ttyUSB0", NAME="pl2303" - -# a devfs like way to name some tty devices -#KERNEL="ttyS*", NAME="tts/%n" -#KERNEL="tty*", NAME="vc/%n" +# +# See the udev.rules.examples file for more examples of how to create rules +# # if this is a ide cdrom, name it the default name, and create a symlink to cdrom BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" diff --git a/etc/udev/udev.rules.examples b/etc/udev/udev.rules.examples new file mode 100644 index 0000000000..0d619e37e6 --- /dev/null +++ b/etc/udev/udev.rules.examples @@ -0,0 +1,68 @@ +# 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. +# +# +# These are some example rules that you could use to name your devices. +# +# If anyone has any other examples that they think should be in here for others +# to use, please send them to greg@kroah.com +# + +# Looking for scsi bus id 42:0:0:1 +BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" + +# A usb camera. +BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n" + +# USB Epson printer to be called lp_epson +BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" + +# USB HP printer to be called lp_hp +BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_hp" + +# sound card with PCI bus id 00:0b.0 to be the first sound card +BUS="pci", ID="00:0b.0", NAME="dsp" + +# sound card with PCI bus id 00:07.1 to be the second sound card +BUS="pci", ID="00:07.1", NAME="dsp1" + +# USB mouse plugged into the third port of the first hub to be called mouse0 +BUS="usb", PLACE="1.3", NAME="mouse0" + +# USB tablet plugged into the third port of the second hub to be called mouse1 +BUS="usb", PLACE="2.3", NAME="mouse1" +BUS="usb", PLACE="2.4", NAME="mouse2" + +# ttyUSB1 should always be called visor +KERNEL="ttyUSB1", NAME="visor" +KERNEL="ttyUSB0", NAME="pl2303" + +# a devfs like way to name some tty devices +KERNEL="ttyS*", NAME="tts/%n" +KERNEL="tty*", NAME="vc/%n" + +# if this is a ide cdrom, name it the default name, and create a symlink to cdrom +BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" + +# 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" + +# DRI devices always go into a subdirectory (as per the LSB spec) +KERNEL="card*", NAME="dri/card%n" + +# 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" +KERNEL="ts*", NAME="input/%k" + From e59d338c9685985fa9aed890cbb8bf3bb17160ee Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 19 Feb 2004 17:55:17 -0800 Subject: [PATCH 0566/4284] [PATCH] Update the Gentoo udev.rules and udev.permissions files These are very good devfs-like rules for others to use if they want to. --- etc/udev/udev.permissions.gentoo | 24 ++++- etc/udev/udev.rules.gentoo | 156 ++++++++++++++++--------------- 2 files changed, 103 insertions(+), 77 deletions(-) diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index c2016bc280..d5ef9eaa37 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -1,5 +1,5 @@ # /etc/udev/udev.permissions: permission/ownership map for udev -# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.permissions,v 1.2 2003/12/26 23:32:44 azarah Exp $ +# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.permissions,v 1.3 2004/01/01 03:41:24 azarah Exp $ # console devices console:root:tty:0600 @@ -34,6 +34,20 @@ vcsa:root:root:0600 vcsa[0-9]*:root:root:0600 vcc/*:root:root:0600 +# memory devices +random:root:root:0666 +urandom:root:root:0444 +mem:root:kmem:0640 +kmem:root:kmem:0640 +port:root:kmem:0640 +full:root:root:0666 +null:root:root:0666 +zero:root:root:0666 + +# misc devices +nvram:root:root:0660 +rtc:root:root:0660 + # floppy devices fd[01]*:root:floppy:0660 @@ -117,6 +131,9 @@ npt*:root:tape:0660 st*:root:tape:0660 nst*:root:tape:0660 +# dm devices +dm-*:root:root:0640 + # memstick devices memstick*:root:root:0600 @@ -135,10 +152,11 @@ fb[0-9]*:root:root:0600 fb/*:root:root:0600 # kbd devices -kbd:root:root:0600 +kbd:root:root:0644 # joystick devices -js[0-9]*:root:root:0600 +js[0-9]*:root:root:0644 +djs[0-9]*:root:root:0644 # v4l devices video*:root:video:0660 diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 7e8966961d..81c370e03e 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -1,52 +1,43 @@ # /etc/udev/udev.rules: device naming rules for udev -# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.rules,v 1.1 2003/12/26 23:32:44 azarah Exp $ -# -# There are a number of modifiers that are allowed to be used in the NAME or PROGRAM 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 return value of the external PROGRAM (note, this doesn't work within -# the PROGRAM field for the obvious reason.) +# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.rules.post_012,v 1.5 2004/02/08 16:59:29 azarah Exp $ # +# 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. ########################################################### # -# Add your own rules here +# Add your own rules here (examples are commented) # ########################################################### # Looking for scsi bus id 42:0:0:1 -BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" +#BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" # A usb camera. -BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n" +#BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" # USB Epson printer to be called lp_epson -BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson" +#BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_hp" +#BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card -BUS="pci", ID="00:0b.0", NAME="dsp" +#BUS="pci", ID="00:0b.0", NAME="dsp" # sound card with PCI bus id 00:07.1 to be the second sound card -BUS="pci", ID="00:07.1", NAME="dsp1" +#BUS="pci", ID="00:07.1", NAME="dsp1" # USB mouse plugged into the third port of the first hub to be called mouse0 -BUS="usb", PLACE="1.3", NAME="mouse0" +#BUS="usb", PLACE="1.3", NAME="mouse0" # USB tablet plugged into the third port of the second hub to be called mouse1 -BUS="usb", PLACE="2.3", NAME="mouse1" -BUS="usb", PLACE="2.4", NAME="mouse2" +#BUS="usb", PLACE="2.3", NAME="mouse1" +#BUS="usb", PLACE="2.4", NAME="mouse2" # ttyUSB1 should always be called visor -KERNEL="ttyUSB1", NAME="visor" -KERNEL="ttyUSB0", NAME="pl2303" +#KERNEL="ttyUSB1", NAME="visor" +#KERNEL="ttyUSB0", NAME="pl2303" ########################################################### @@ -57,56 +48,7 @@ KERNEL="ttyUSB0", NAME="pl2303" # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", RESULT="hd*", NAME="%c{1}", SYMLINK="%c{2} %c{3}" - -# fb devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" - -# loop devices -KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" - -# md block devices -KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" - -# pty devices -KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" - -# ram devices -KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" - -# tty devices -KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" -KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" -KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" - -# vc devices -KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" -KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" -KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" -KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" - -# v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n" -KERNEL="radio[0-9]*", NAME="v4l/radio%n" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" -KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" - -# dm devices (ignore them) -KERNEL="dm-[0-9]*", NAME="" - -# i2c devices -KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" - -# loop devices -KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" - -# framebuffer devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" - -# misc devices -KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" -KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%1c %2c" # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" @@ -116,3 +58,69 @@ KERNEL="midi[CD0-9]*", NAME="snd/%k" KERNEL="timer", NAME="snd/%k" KERNEL="seq", NAME="snd/%k" +# dm devices (ignore them) +KERNEL="dm-[0-9]*", NAME="" +KERNEL="device-mapper", NAME="mapper/control" + +# fb devices +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" + +# floppy devices +KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k" + +# i2c devices +KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" + +# input devices +KERNEL="mice", NAME="input/mice" +KERNEL="mouse[0-9]*", NAME="input/mouse%n" +KERNEL="event[0-9]*", NAME="input/event%n" +KERNEL="js*", NAME="input/%k" +KERNEL="ts*", NAME="input/%k" + +# loop devices +KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" + +# md block devices +KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" + +# misc devices +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" + +# pty devices +KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" + +# ramdisk devices +KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" + +# sound devices +KERNEL="adsp", NAME="sound/adsp" SYMLINK="%k" +KERNEL="audio", NAME="sound/audio", SYMLINK="%k" +KERNEL="dsp", NAME="sound/dsp", SYMLINK="%k" +KERNEL="mixer", NAME="sound/mixer", SYMLINK="%k" +KERNEL="sequencer", NAME="sound/sequencer", SYMLINK="%k" +KERNEL="sequencer2", NAME="sound/sequencer2", SYMLINK="%k" + +# tty devices +KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" +KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" +KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" + +# vc devices +KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" +KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" +KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" +KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" + +# v4l devices +KERNEL="video[0-9]*", NAME="v4l/video%n" +KERNEL="radio[0-9]*", NAME="v4l/radio%n" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" + From 2b7289ae887af8ed6bbdf060f618a1cc560caffb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 19 Feb 2004 18:00:38 -0800 Subject: [PATCH 0567/4284] [PATCH] update udev.rules.gentoo with new config file format. --- etc/udev/udev.rules.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 81c370e03e..0f871ca7ff 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -48,7 +48,7 @@ # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%1c %2c" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" From ca8e992c9b9e1a4f476573756d16cf0ebabebf28 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 19 Feb 2004 18:20:33 -0800 Subject: [PATCH 0568/4284] [PATCH] added scsi_id and some more documentation to the udev.spec file. --- udev.spec | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/udev.spec b/udev.spec index aa595962f7..553e58a783 100644 --- a/udev.spec +++ b/udev.spec @@ -27,6 +27,11 @@ # 1 - use LSB: etc/init.d/udev.init.LSB %define lsb 0 +# if we want to build the scsi_id "extra" package or not +# 0 - do not build the package +# 1 - build it +%define scsi_id 1 + Summary: A userspace implementation of devfs Name: udev Version: 017_bk @@ -67,7 +72,11 @@ make CC="gcc $RPM_OPT_FLAGS" \ %else DEBUG=false \ %endif - + EXTRAS=" \ +%if %{scsi_id} + extras/scsi_id \ +%endif +" %install make DESTDIR=$RPM_BUILD_ROOT install \ @@ -81,6 +90,11 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %else USE_LSB=false \ %endif + EXTRAS=" \ +%if %{scsi_id} + extras/scsi_id \ +%endif +" %post /sbin/chkconfig --add udev @@ -95,7 +109,7 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) -%doc COPYING README TODO ChangeLog +%doc COPYING README TODO ChangeLog HOWTO* etc/udev/udev.rules.examples docs/* %attr(755,root,root) /sbin/udev %attr(755,root,root) /sbin/udevinfo %attr(755,root,root) /sbin/udevsend @@ -106,14 +120,25 @@ rm -rf $RPM_BUILD_ROOT %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf %config(noreplace) %attr(0644,root,root) /etc/udev/udev.rules %config(noreplace) %attr(0644,root,root) /etc/udev/udev.permissions -%if %{dbus} - %config(noreplace) %attr(0644,root,root) /etc/dbus-1/system.d/udev_sysbus_policy.conf -%endif %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev*.8* +%if %{dbus} + %config(noreplace) %attr(0644,root,root) /etc/dbus-1/system.d/udev_sysbus_policy.conf +%endif + +%if %{scsi_id} + %attr(755,root,root) /sbin/scsi_id + %config(noreplace) %attr(0644,root,root) /etc/scsi_id.config + %attr(0644,root,root) %{_mandir}/man8/scsi_id*.8* +%endif + %changelog +* Thu Feb 19 2004 Greg Kroah-Hartman +- add some more files to the documentation directory +- add ability to build scsi_id and make it the default + * Mon Feb 16 2004 Greg Kroah-Hartman - fix up udevd build, as it's no longer needed to be build seperatly - add udevtest to list of files From 9e5a55213067422a6355b538d15b72de320d93bc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 19 Feb 2004 18:35:19 -0800 Subject: [PATCH 0569/4284] [PATCH] v018 release --- ChangeLog | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ad5f63ace..bcc22c2328 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,53 @@ +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 + o v017 release TAG: v017 + +Patrick Mansfield: + o udev use new libsysfs header file location + o udev add some ID tests + + Summary of changes from v016 to v017 ============================================ diff --git a/Makefile b/Makefile index 25881e1dd3..8ee84d09b9 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ DAEMON = udevd SENDER = udevsend HELPER = udevinfo TESTER = udevtest -VERSION = 017_bk +VERSION = 018 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 553e58a783..bfa633ba66 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 017_bk +Version: 018 Release: 1 License: GPL Group: Utilities/System From 286903679a6cd4cfa9f5e7eed49f0bb8f059109e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 20 Feb 2004 01:06:41 -0800 Subject: [PATCH 0570/4284] [PATCH] remove udevd priority TODO item, as it's not needed at all. We want to be started by keventd, as that runs at a very fast priority. --- TODO | 3 --- extras/start_udev | 5 ----- 2 files changed, 8 deletions(-) diff --git a/TODO b/TODO index a87f398a03..1a29adba0e 100644 --- a/TODO +++ b/TODO @@ -7,9 +7,6 @@ greg@kroah.com - more documentation (can never have too much.) -- have udevd move up to the "default" priority level if it is started by - keventd (otherwise it runs at a _very_ low priority level.) Don't - know if this is necessary, but it would be nice to do. - install the proper init.d script based on the distro we are running on. - persuade the distro packagers to submit their changes (or just steal them if we can find them...) diff --git a/extras/start_udev b/extras/start_udev index 3c39fc9260..5a7bc63515 100644 --- a/extras/start_udev +++ b/extras/start_udev @@ -84,11 +84,6 @@ fi echo "mounting... ramfs at $udev_root" mount -n -t ramfs none $udev_root -# We want to start udevd ourselves if it isn't already running. This -# lets udevd run at a sane nice level... -echo "starting udevd" -$udevd & - # propogate /udev from /sys export ACTION=add export UDEV_NO_SLEEP=1 From d54fe24caa38ffc6e5dee7ef5cdcb3c24a882bf8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 20 Feb 2004 01:10:29 -0800 Subject: [PATCH 0571/4284] [PATCH] 018_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 8ee84d09b9..a4bba06d55 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ DAEMON = udevd SENDER = udevsend HELPER = udevinfo TESTER = udevtest -VERSION = 018 +VERSION = 018_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index bfa633ba66..63d1835a4a 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 018 +Version: 018_bk Release: 1 License: GPL Group: Utilities/System From 75a7b641ab766b14f4e5f3689b47486c7fdba694 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 20 Feb 2004 01:33:49 -0800 Subject: [PATCH 0572/4284] [PATCH] remove udevtest on 'make clean' --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a4bba06d55..3b44b23359 100644 --- a/Makefile +++ b/Makefile @@ -278,7 +278,7 @@ $(SENDER): $(SENDER).o udevd.h $(LIBC) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(HELPER) $(DAEMON) $(SENDER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(HELPER) $(DAEMON) $(SENDER) $(TESTER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ From df41554d990fd9e69495253b4dc1979c6cd8621f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 23 Feb 2004 19:06:49 -0800 Subject: [PATCH 0573/4284] [PATCH] fix up libsysfs header file usage to fix bug reports from users that have sysfsutils installed already. --- libsysfs/sysfs.h | 1 + libsysfs/sysfs/libsysfs.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 49c9285bc3..1b800ddcd2 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -31,6 +31,7 @@ #include #include #include +#include "dlist.h" /* Debugging */ #ifdef DEBUG diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index 10faab92aa..f3d2dd4d16 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -24,7 +24,6 @@ #define _LIBSYSFS_H_ #include -#include "dlist.h" /* * Generic #defines go here.. @@ -47,6 +46,8 @@ #define SYSFS_METHOD_SHOW 0x01 /* attr can be read by user */ #define SYSFS_METHOD_STORE 0x02 /* attr can be changed by user */ +struct dlist; + struct sysfs_attribute { unsigned char *value; unsigned short len; /* value length */ From c80da5085f915bf6305e7ed6b786b63f6e9b14ea Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 23 Feb 2004 19:07:25 -0800 Subject: [PATCH 0574/4284] [PATCH] force udev to include the internal version of libsysfs and never the external one. Should fix some more build bugs... --- namedev.c | 2 +- udev-add.c | 2 +- udev.c | 2 +- udev_config.c | 2 +- udevdb.c | 2 +- udevinfo.c | 3 ++- udevtest.c | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/namedev.c b/namedev.c index 89513934ff..2f9d8f5f67 100644 --- a/namedev.c +++ b/namedev.c @@ -32,8 +32,8 @@ #include #include #include -#include +#include "libsysfs/sysfs/libsysfs.h" #include "list.h" #include "udev.h" #include "udev_version.h" diff --git a/udev-add.c b/udev-add.c index 87cf57c3b6..736316629f 100644 --- a/udev-add.c +++ b/udev-add.c @@ -33,8 +33,8 @@ #ifndef __KLIBC__ #include #endif -#include +#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "udev_version.h" #include "udev_dbus.h" diff --git a/udev.c b/udev.c index f3fab18b29..8c91ac62d4 100644 --- a/udev.c +++ b/udev.c @@ -26,8 +26,8 @@ #include #include #include -#include +#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "udev_version.h" #include "udev_dbus.h" diff --git a/udev_config.c b/udev_config.c index 1d05a3fb13..cade81cf20 100644 --- a/udev_config.c +++ b/udev_config.c @@ -31,8 +31,8 @@ #include #include #include -#include +#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "udev_version.h" #include "logging.h" diff --git a/udevdb.c b/udevdb.c index bfd5b4bd69..f9fca4ab70 100644 --- a/udevdb.c +++ b/udevdb.c @@ -32,8 +32,8 @@ #include #include #include -#include +#include "libsysfs/sysfs/libsysfs.h" #include "udev_version.h" #include "udev.h" #include "logging.h" diff --git a/udevinfo.c b/udevinfo.c index 7991855b28..b94376c9ce 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -26,8 +26,9 @@ #include #include #include -#include +#include "libsysfs/sysfs/libsysfs.h" +#include "libsysfs/dlist.h" #include "udev.h" #include "udev_version.h" #include "logging.h" diff --git a/udevtest.c b/udevtest.c index 175f143269..4956758636 100644 --- a/udevtest.c +++ b/udevtest.c @@ -26,8 +26,8 @@ #include #include #include -#include +#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "udev_version.h" #include "logging.h" From 82962619c626edfc68d39f0b179a909dd3dd0a6b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 23 Feb 2004 19:29:32 -0800 Subject: [PATCH 0575/4284] [PATCH] udev - simple klibc textual uid/gid handling Here we get a very dumb getpwnam() and getgrnam() for klibc to stop the confusion of not handling textual id's if klibc is used. If used with initrd we just need to copy the /etc/passwd and /etc/group file and all should work well. --- klibc_fixups.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++ klibc_fixups.h | 25 ++++--------- 2 files changed, 108 insertions(+), 17 deletions(-) diff --git a/klibc_fixups.c b/klibc_fixups.c index a99166811c..927f2f649a 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -1,10 +1,110 @@ +/* + * klibc_fixups.c - very simple implementation of stuff missing in klibc + * + * Copyright (C) 2003 Greg Kroah-Hartman + * 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. + * + * 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. + * + */ #ifdef __KLIBC__ #include +#include #include #include #include + #include "klibc_fixups.h" +#include "logging.h" + +#define PW_FILE "/etc/passwd" +#define GR_FILE "/etc/group" + +/* return the id of a passwd style line, selected by the users name */ +static unsigned long get_id_by_name(const char *uname, const char *dbfile) +{ + unsigned long id = -1; + FILE *file; + char buf[255]; + char *pos; + char *name; + char *idstr; + char *tail; + + file = fopen(dbfile, "r"); + if (file == NULL) { + dbg("unable to open file '%s'", dbfile); + return -1; + } + + while (1) { + pos = fgets(buf, sizeof(buf), file); + if (pos == NULL) + break; + + /* get name */ + name = strsep(&pos, ":"); + if (name == NULL) + continue; + + /* skip pass */ + if (strsep(&pos, ":") == NULL) + continue; + + /* get id */ + idstr = strsep(&pos, ":"); + if (idstr == NULL) + continue; + + if (strcmp(uname, name) == 0) { + id = strtoul(idstr, &tail, 10); + if (tail == NULL) + id = -1; + else + dbg("id for '%s' is '%li'", name, id); + break; + } + } + + fclose(file); + return id; +} + +struct passwd *getpwnam(const char *name) +{ + static struct passwd pw; + + memset(&pw, 0x00, sizeof(struct passwd)); + pw.pw_uid = (uid_t) get_id_by_name(name, PW_FILE); + if (pw.pw_uid < 0) + return NULL; + else + return &pw; +} + +struct group *getgrnam(const char *name) +{ + static struct group gr; + + memset(&gr, 0x00, sizeof(struct group)); + gr.gr_gid = (gid_t) get_id_by_name(name, GR_FILE); + if (gr.gr_gid < 0) + return NULL; + else + return &gr; +} #endif diff --git a/klibc_fixups.h b/klibc_fixups.h index 1ac112b087..19bfd51caa 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -3,19 +3,6 @@ #ifndef KLIBC_FIXUPS_H #define KLIBC_FIXUPS_H -struct group { - char *gr_name; /* group name */ - char *gr_passwd; /* group password */ - gid_t gr_gid; /* group id */ - char **gr_mem; /* group members */ -}; - -static inline struct group *getgrnam(const char *name) -{ - return NULL; -} - - struct passwd { char *pw_name; /* user name */ char *pw_passwd; /* user password */ @@ -26,11 +13,15 @@ struct passwd { char *pw_shell; /* shell program */ }; -static inline struct passwd *getpwnam(const char *name) -{ - return NULL; -} +struct group { + char *gr_name; /* group name */ + char *gr_passwd; /* group password */ + gid_t gr_gid; /* group id */ + char **gr_mem; /* group members */ +}; +struct passwd *getpwnam(const char *name); +struct group *getgrnam(const char *name); #endif From e41245cb256231ef6954b3cbf45f0635d01501ed Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 23 Feb 2004 19:31:14 -0800 Subject: [PATCH 0576/4284] [PATCH] udev - allow all files in a directory as the config I was on the train for 5 hours today and the TODO is almost empty :) So, at least four people wanted this feature, then here is a actual working patch. We may specify now in udev.conf: udev_rules="/etc/udev/" and udev will scan the whole directory for files ending with *.rules, sort it in lexical order and create our rule list from all of the files. A plain given file will still work and the same applies to the *.permissions. I sort the files in our usual linked list, cause klibc has no scandir(). --- namedev.h | 4 +- namedev_parse.c | 107 ++++++++++++++++++++++++++++++++++++++++++++---- udev.c | 8 +++- 3 files changed, 107 insertions(+), 12 deletions(-) diff --git a/namedev.h b/namedev.h index 10a5dcaf0c..ffdde83ca4 100644 --- a/namedev.h +++ b/namedev.h @@ -48,10 +48,12 @@ struct sysfs_class_device; #define ATTR_PARTITIONS "all_partitions" #define PARTITIONS_COUNT 15 - #define PROGRAM_MAXARG 10 #define MAX_SYSFS_PAIRS 5 +#define RULEFILE_EXT ".rules" +#define PERMFILE_EXT ".permissions" + struct sysfs_pair { char file[FILE_SIZE]; char value[VALUE_SIZE]; diff --git a/namedev_parse.c b/namedev_parse.c index d5d2181cb6..013878c679 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -33,12 +33,16 @@ #include #include #include +#include +#include #include #include "udev.h" #include "logging.h" #include "namedev.h" +LIST_HEAD(file_list); + static int add_config_dev(struct config_device *new_dev) { struct config_device *tmp_dev; @@ -114,7 +118,7 @@ static char *get_key_attribute(char *str) return NULL; } -int namedev_init_rules(void) +static int namedev_parse_rules(char *filename) { char line[255]; int lineno; @@ -127,11 +131,11 @@ int namedev_init_rules(void) int retval = 0; struct config_device dev; - fd = fopen(udev_rules_filename, "r"); + fd = fopen(filename, "r"); if (fd != NULL) { - dbg("reading '%s' as rules file", udev_rules_filename); + dbg("reading '%s' as rules file", filename); } else { - dbg("can't open '%s' as a rules file", udev_rules_filename); + dbg("can't open '%s' as a rules file", filename); return -ENODEV; } @@ -262,7 +266,7 @@ int namedev_init_rules(void) continue; error: dbg("%s:%d:%d: parse error, rule skipped", - udev_rules_filename, lineno, temp - line); + filename, lineno, temp - line); } } exit: @@ -270,7 +274,7 @@ exit: return retval; } -int namedev_init_permissions(void) +static int namedev_parse_permissions(char *filename) { char line[255]; char *temp; @@ -279,11 +283,11 @@ int namedev_init_permissions(void) int retval = 0; struct perm_device dev; - fd = fopen(udev_permissions_filename, "r"); + fd = fopen(filename, "r"); if (fd != NULL) { - dbg("reading '%s' as permissions file", udev_permissions_filename); + dbg("reading '%s' as permissions file", filename); } else { - dbg("can't open '%s' as permissions file", udev_permissions_filename); + dbg("can't open '%s' as permissions file", filename); return -ENODEV; } @@ -352,3 +356,88 @@ exit: return retval; } +struct files { + struct list_head list; + char name[NAME_SIZE]; +}; + +/* sort files in lexical order */ +static int file_list_insert(char *filename) +{ + struct files *loop_file; + struct files *new_file; + + list_for_each_entry(loop_file, &file_list, list) { + if (strcmp(loop_file->name, filename) > 0) { + break; + } + } + + new_file = malloc(sizeof(struct files)); + if (new_file == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + strfieldcpy(new_file->name, filename); + list_add_tail(&new_file->list, &loop_file->list); + return 0; +} + +/* calls function for file or every file found in directory */ +static int call_foreach_file(int parser (char *f) , char *filename, char *extension) +{ + struct dirent *ent; + DIR *dir; + char *ext; + char file[NAME_SIZE]; + struct stat stats; + struct files *loop_file; + struct files *tmp_file; + + /* look if we have a plain file or a directory to scan */ + stat(filename, &stats); + if ((stats.st_mode & S_IFMT) != S_IFDIR) + return parser(filename); + + /* sort matching filename into list */ + dbg("open config as directory '%s'", filename); + dir = opendir(filename); + while (1) { + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + + dbg("found file '%s'", ent->d_name); + ext = strrchr(ent->d_name, '.'); + if (ext == NULL) + continue; + + if (strcmp(ext, extension) == 0) { + dbg("put file in list '%s'", ent->d_name); + file_list_insert(ent->d_name); + } + } + + /* parse every file in the list */ + list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { + strfieldcpy(file, filename); + strcat(file, loop_file->name); + parser(file); + list_del(&loop_file->list); + free(loop_file); + } + + closedir(dir); + return 0; +} + +int namedev_init_rules() +{ + return call_foreach_file(namedev_parse_rules, udev_rules_filename, RULEFILE_EXT); +} + +int namedev_init_permissions() +{ + return call_foreach_file(namedev_parse_permissions, udev_permissions_filename, PERMFILE_EXT); +} diff --git a/udev.c b/udev.c index 8c91ac62d4..1c65f2e59c 100644 --- a/udev.c +++ b/udev.c @@ -111,13 +111,13 @@ static int udev_hotplug(int argc, char **argv) action = get_action(); if (!action) { - dbg ("no action?"); + dbg("no action?"); goto exit; } devpath = get_devpath(); if (!devpath) { - dbg ("no devpath?"); + dbg("no devpath?"); goto exit; } dbg("looking at '%s'", devpath); @@ -131,6 +131,10 @@ static int udev_hotplug(int argc, char **argv) /* skip blacklisted subsystems */ subsystem = argv[1]; + if (!subsystem) { + dbg("no subsystem?"); + goto exit; + } i = 0; while (subsystem_blacklist[i][0] != '\0') { if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { From 7b7e4df57ba0109d8c90db84b1663f5f25427ce1 Mon Sep 17 00:00:00 2001 From: "arvidjaar@mail.ru" Date: Mon, 23 Feb 2004 19:31:19 -0800 Subject: [PATCH 0577/4284] [PATCH] do not remove real .udev.tdb during RPM build --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3b44b23359..8ab9099f4f 100644 --- a/Makefile +++ b/Makefile @@ -364,7 +364,7 @@ install: install-config install-dbus-policy all $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 - ln -f -s ./udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - rm -f $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug - - rm -f $(udevdir)/.udev.tdb + - rm -f $(DESTDIR)$(udevdir)/.udev.tdb - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ From 167a27e70f4010fdce561cff2ea1a07730aae28a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 26 Feb 2004 19:35:38 -0800 Subject: [PATCH 0578/4284] [PATCH] manpage update Nice, here is the corresponding man update which also removes the mention of the limitation of getgrname() and friends with klibc. --- udev.8 | 37 ++++++++++++++++++++----------------- udevd.8 | 2 +- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/udev.8 b/udev.8 index 603ca45cba..d7999aadfd 100644 --- a/udev.8 +++ b/udev.8 @@ -35,7 +35,7 @@ lines, and lines beginning with a '#' will be ignored. .B udev expects its main configuration file at -.I /etc/udev/udev.conf. +.IR /etc/udev/udev.conf . The file consists of a set of variables and values that allow the user to override default udev values. The current set of variables that can be overridden in this file is: @@ -43,39 +43,46 @@ overridden in this file is: .B udev_root This is the where in the filesystem to place the device nodes. The default value for this is -.I /udev/ +.IR /udev/ . .TP .B udev_db The name and location of the udev database. The default value for this is -.I /udev/.udev.tdb +.IR /udev/.udev.tdb . .TP .B udev_rules This is the location of the udev rules file. The default value for this is -.I /etc/udev/udev.rules +.IR /etc/udev/udev.rules . +If a directory is specified, the whole directory is +scanned for files ending with +.I .rules +and all rule files are read in lexical order. .TP .B udev_permissions -This is the location of the udev permission file. The default value for this is -.I /etc/udev/udev.permissions +This is the location of the udev permission file. The default value for this is +.IR /etc/udev/udev.permissions . +If a directory is specified, the whole directory is scanned for files ending with +.I .permissions +and all permission files are read in lexical order. .TP .B udev_log If you want udev to log some information to the syslog for every node created or removed. The default value for this is -.I yes +.IR yes . .TP .B default_mode This is the default mode for all nodes that have no explicit match in the permissions file. The default value for this is -.I 0666 +.IR 0666 . .TP .B default_owner This is the default owner for all nodes that have no explicit match in the permissions file. The default value for this is -.I root +.IR root . .TP .B default_group This is the default group for all nodes that have no explicit match in the permissions file. The default value for this is -.I root +.IR root . .br .P .RI "A sample " udev.conf " might look like this: @@ -87,8 +94,9 @@ udev_root="/udev/" # udev_db - The name and location of the udev database. udev_db="/udev/.udev.tdb" -# udev_rules - The name and location of the udev rules file -udev_rules="/etc/udev/udev.rules" +# udev_rules - The location of the directory where to look for files + which names ending with .rules +udev_rules="/etc/udev/" # udev_permissions - The name and location of the udev permission file udev_permissions="/etc/udev/udev.permissions" @@ -242,11 +250,6 @@ file. Every line lists a device name followed by owner, group and permission mode. All values are separated by colons. The name field may contain a pattern to apply the values to a whole class of devices. -.br -If -.B udev -was built using klibc or is used before the user database is accessible (e.g. -.BR initrd "(4)), only numeric owner and group values may be used." .sp .RI "A sample " udev.permissions " might look like this:" .sp diff --git a/udevd.8 b/udevd.8 index 59dc0206c2..ab13a31107 100644 --- a/udevd.8 +++ b/udevd.8 @@ -33,7 +33,7 @@ isn't already running, .B udevsend will start it. .SH "SEE ALSO" -.BR udev (8), hotplug (8) +.BR udev (8), " hotplug" (8) .SH AUTHORS .B udevd was developed primarily by Kay Sievers , with much help From c472e3c89b9aaad90ad6398c0d2ff5dcf5a9d238 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 26 Feb 2004 19:37:47 -0800 Subject: [PATCH 0579/4284] [PATCH] udev - safer string handling all over the place On Tue, Feb 24, 2004 at 11:50:52PM +0100, Kay Sievers wrote: > Here is the first step towards a safer string handling. > More will follow, but for now only the easy ones :) > > Thanks to all who pointed this out. strncat() isn't a nice function. We > all should remember that the destination string is not terminated if the > given lenght is shorter than the strlen of the source string. > > And shame on the various implementers of strfieldcat() I found in the > unapplied patches on this list, it's not really better than strncpy() > and hides the real problem. Hmm, bk didn't checked in one file, maybe I edited it again as root. Nevermind, here is the more complete version. --- namedev.c | 10 +++++----- namedev_parse.c | 8 ++++---- udev-add.c | 26 +++++++++++++------------- udev-remove.c | 10 +++++----- udev.h | 6 ++++++ udev_dbus.c | 8 ++++---- udevdb.c | 6 +++--- udevinfo.c | 10 +++++----- udevsend.c | 6 +++--- 9 files changed, 48 insertions(+), 42 deletions(-) diff --git a/namedev.c b/namedev.c index 2f9d8f5f67..219cb8a4b8 100644 --- a/namedev.c +++ b/namedev.c @@ -157,7 +157,7 @@ static mode_t get_default_mode(void) static char *get_default_owner(void) { if (strlen(default_owner_str) == 0) - strncpy(default_owner_str, "root", OWNER_SIZE); + strfieldcpy(default_owner_str, "root"); return default_owner_str; } @@ -165,7 +165,7 @@ static char *get_default_owner(void) static char *get_default_group(void) { if (strlen(default_group_str) == 0) - strncpy(default_group_str, "root", GROUP_SIZE); + strfieldcpy(default_group_str, "root"); return default_group_str; } @@ -276,7 +276,7 @@ static void apply_format(struct udevice *udev, unsigned char *string, struct sys if (attr != NULL) i = atoi(attr); if (i > 0) { - strncpy(temp1, udev->program_result, sizeof(temp1)); + strfieldcpy(temp1, udev->program_result); pos2 = temp1; while (i) { i--; @@ -837,8 +837,8 @@ done: } else { /* no matching perms found :( */ udev->mode = get_default_mode(); - strncpy(udev->owner, get_default_owner(), OWNER_SIZE); - strncpy(udev->group, get_default_group(), GROUP_SIZE); + strfieldcpy(udev->owner, get_default_owner()); + strfieldcpy(udev->group, get_default_group()); } dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); diff --git a/namedev_parse.c b/namedev_parse.c index 013878c679..d300b0907d 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -319,21 +319,21 @@ static int namedev_parse_permissions(char *filename) dbg("cannot parse line '%s'", line); continue; } - strncpy(dev.name, temp2, sizeof(dev.name)); + strfieldcpy(dev.name, temp2); temp2 = strsep(&temp, ":"); if (!temp2) { dbg("cannot parse line '%s'", line); continue; } - strncpy(dev.owner, temp2, sizeof(dev.owner)); + strfieldcpy(dev.owner, temp2); temp2 = strsep(&temp, ":"); if (!temp2) { dbg("cannot parse line '%s'", line); continue; } - strncpy(dev.group, temp2, sizeof(dev.group)); + strfieldcpy(dev.group, temp2); if (!temp) { dbg("cannot parse line: %s", line); @@ -422,7 +422,7 @@ static int call_foreach_file(int parser (char *f) , char *filename, char *extens /* parse every file in the list */ list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { strfieldcpy(file, filename); - strcat(file, loop_file->name); + strfieldcat(file, loop_file->name); parser(file); list_del(&loop_file->list); free(loop_file); diff --git a/udev-add.c b/udev-add.c index 736316629f..0d3131300f 100644 --- a/udev-add.c +++ b/udev-add.c @@ -78,7 +78,7 @@ static int create_path(char *file) int retval; struct stat stats; - strncpy(p, file, sizeof(p)); + strfieldcpy(p, file); pos = strchr(p+1, '/'); while (1) { pos = strchr(pos+1, '/'); @@ -145,8 +145,8 @@ static int create_node(struct udevice *dev, int fake) int i; int tail; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->name, sizeof(filename)); + strfieldcpy(filename, udev_root); + strfieldcat(filename, dev->name); switch (dev->type) { case 'b': @@ -225,8 +225,8 @@ static int create_node(struct udevice *dev, int fake) if (linkname == NULL || linkname[0] == '\0') break; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, linkname, sizeof(filename)); + strfieldcpy(filename, udev_root); + strfieldcat(filename, linkname); dbg("symlink '%s' to node '%s' requested", filename, dev->name); if (!fake) if (strrchr(linkname, '/')) @@ -243,13 +243,13 @@ static int create_node(struct udevice *dev, int fake) } while (linkname[i] != '\0') { if (linkname[i] == '/') - strcat(linktarget, "../"); + strfieldcat(linktarget, "../"); i++; } if (linktarget[0] == '\0') - strcpy(linktarget, "./"); - strcat(linktarget, &dev->name[tail]); + strfieldcpy(linktarget, "./"); + strfieldcat(linktarget, &dev->name[tail]); /* unlink existing files to ensure that our symlink is created */ if (!fake && (lstat(filename, &stats) == 0)) { @@ -278,8 +278,8 @@ static struct sysfs_class_device *get_class_dev(char *device_name) char dev_path[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev = NULL; - strcpy(dev_path, sysfs_path); - strcat(dev_path, device_name); + strfieldcpy(dev_path, sysfs_path); + strfieldcat(dev_path, device_name); dbg("looking at '%s'", dev_path); /* open up the sysfs class device for this thing... */ @@ -304,9 +304,9 @@ static int sleep_for_dev(char *path) int loop = SECONDS_TO_WAIT_FOR_DEV; int retval; - strcpy(filename, sysfs_path); - strcat(filename, path); - strcat(filename, "/dev"); + strfieldcpy(filename, sysfs_path); + strfieldcat(filename, path); + strfieldcat(filename, "/dev"); while (loop--) { struct stat buf; diff --git a/udev-remove.c b/udev-remove.c index c20c651dc5..8794429635 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -72,8 +72,8 @@ static int delete_node(struct udevice *dev) int retval; int i; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->name, sizeof(filename)); + strfieldcpy(filename, udev_root); + strfieldcat(filename, dev->name); info("removing device node '%s'", filename); retval = unlink(filename); @@ -103,8 +103,8 @@ static int delete_node(struct udevice *dev) if (linkname == NULL) break; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, linkname, sizeof(filename)); + strfieldcpy(filename, udev_root); + strfieldcat(filename, linkname); dbg("unlinking symlink '%s'", filename); retval = unlink(filename); @@ -141,7 +141,7 @@ int udev_remove_device(char *path, char *subsystem) temp = strrchr(path, '/'); if (temp == NULL) return -ENODEV; - strncpy(dev.name, &temp[1], sizeof(dev.name)); + strfieldcpy(dev.name, &temp[1]); } dbg("name is '%s'", dev.name); diff --git a/udev.h b/udev.h index b5088b90c6..fc44a9847c 100644 --- a/udev.h +++ b/udev.h @@ -61,6 +61,12 @@ do { \ strncpy(to, from, sizeof(to)-1); \ } while (0) +#define strfieldcat(to, from) \ +do { \ + to[sizeof(to)-1] = '\0'; \ + strncat(to, from, sizeof(to) - strlen(to) -1); \ +} while (0) + extern int udev_add_device(char *path, char *subsystem, int fake); extern int udev_remove_device(char *path, char *subsystem); extern void udev_init_config(void); diff --git a/udev_dbus.c b/udev_dbus.c index da633a31a1..7b672ef363 100644 --- a/udev_dbus.c +++ b/udev_dbus.c @@ -80,8 +80,8 @@ void sysbus_send_create(struct udevice *dev, const char *path) if (sysbus_connection == NULL) return; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, dev->name, sizeof(filename)); + strfieldcpy(filename, udev_root); + strfieldcat(filename, dev->name); /* object, interface, member */ message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", @@ -114,8 +114,8 @@ void sysbus_send_remove(const char* name, const char *path) if (sysbus_connection == NULL) return; - strncpy(filename, udev_root, sizeof(filename)); - strncat(filename, name, sizeof(filename)); + strfieldcpy(filename, udev_root); + strfieldcat(filename, name); /* object, interface, member */ message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", diff --git a/udevdb.c b/udevdb.c index f9fca4ab70..a1f79a7c65 100644 --- a/udevdb.c +++ b/udevdb.c @@ -53,7 +53,7 @@ int udevdb_add_dev(const char *path, const struct udevice *dev) return -ENODEV; memset(keystr, 0, NAME_SIZE); - strcpy(keystr, path); + strfieldcpy(keystr, path); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -91,7 +91,7 @@ int udevdb_delete_dev(const char *path) return -EINVAL; memset(keystr, 0, sizeof(keystr)); - strcpy(keystr, path); + strfieldcpy(keystr, path); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -180,7 +180,7 @@ static int find_device_by_name(char *path, struct udevice *dev) { if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { memcpy(find_dev, dev, sizeof(*find_dev)); - strncpy(find_path, path, NAME_SIZE); + strfieldcpy(find_path, path); find_found = 1; /* stop search */ return 1; diff --git a/udevinfo.c b/udevinfo.c index b94376c9ce..defed2ee31 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -73,7 +73,7 @@ static int print_all_attributes(const char *path) dlist_for_each_data(attributes, attr, struct sysfs_attribute) { if (attr->value != NULL) { - strncpy(value, attr->value, SYSFS_VALUE_MAX); + strfieldcpy(value, attr->value); len = strlen(value); if (len == 0) continue; @@ -306,8 +306,8 @@ static int process_options(void) } else { if (path[0] != '/') { /* prepend '/' if missing */ - strcat(temp, "/"); - strncat(temp, path, sizeof(path)); + strfieldcat(temp, "/"); + strfieldcat(temp, path); pos = temp; } else { pos = path; @@ -343,7 +343,7 @@ print: case NAME: if (root) strfieldcpy(result, udev_root); - strncat(result, dev.name, sizeof(result)); + strfieldcat(result, dev.name); break; case SYMLINK: @@ -385,7 +385,7 @@ exit: /* prepend sysfs mountpoint if not given */ strfieldcpy(temp, path); strfieldcpy(path, sysfs_path); - strncat(path, temp, sizeof(path)); + strfieldcat(path, temp); } print_device_chain(path); return 0; diff --git a/udevsend.c b/udevsend.c index b5850294ae..08212dfee6 100644 --- a/udevsend.c +++ b/udevsend.c @@ -82,9 +82,9 @@ static int build_hotplugmsg(struct hotplug_msg *msg, char *action, memset(msg, 0x00, sizeof(*msg)); strfieldcpy(msg->magic, UDEV_MAGIC); msg->seqnum = seqnum; - strncpy(msg->action, action, 8); - strncpy(msg->devpath, devpath, 128); - strncpy(msg->subsystem, subsystem, 16); + strfieldcpy(msg->action, action); + strfieldcpy(msg->devpath, devpath); + strfieldcpy(msg->subsystem, subsystem); return sizeof(struct hotplug_msg); } From bef370d6ebd6707cc2ef183c2dc83f4a62d8111b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 26 Feb 2004 19:39:33 -0800 Subject: [PATCH 0580/4284] [PATCH] udev - man page update Hey it's not longer the "goal" to provide a dynamic dev directory, we have just arrived. So I change it to more self-confident words :) I've also added the completly missing environment variables to the man pages. To stop the misuse of the PROGRAM= call paramenters, we better mention its limitations. --- udev.8 | 33 +++++++++++++++++++++++++++++++-- udevd.8 | 19 ++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/udev.8 b/udev.8 index d7999aadfd..84b08488fe 100644 --- a/udev.8 +++ b/udev.8 @@ -3,11 +3,34 @@ udev \- Linux configurable dynamic device naming support .SH SYNOPSIS .BI udev " hotplug-subsystem" +.P +The environment must provide the following variables: +.TP +.B ACTION +.IR add " or " remove +signifies the connection or disconnection of a device. +.TP +.B DEVPATH +The sysfs devpath of the device without the mountpoint but a leading slash. +.P +Additional optional environment variables are: +.TP +.B UDEV_CONFIG_FILE +Overrides the default location of the +.B udev +config file. +.TP +.B UDEV_NO_SLEEP +The default behavior of +.B udev +is to wait until all the sysfs files of the device chain are populated. If set +.B udev +will will continue, regardless of the state of the device representation. .SH "DESCRIPTION" .B udev creates or removes device node files usually located in the /dev directory. -Its goal is to provide a dynamic device directory that contains only the files -for devices that are actually present. +It provides a dynamic device directory that contains only the files for +devices that are actually present. .P As part of the .B hotplug @@ -159,6 +182,11 @@ all of the values being required in order to match the rule. .TP .B PROGRAM Call external program. This key is valid if the program returns successful. +A few command line options may specified, but shell characters like pipe, +diversion or similiar options are not available. The environment variables of +.B udev +are also available for the program. +.br The string returned by the program may additionally matched with the .B RESULT key. @@ -285,6 +313,7 @@ following the '[' is a '!' then any character not enclosed is matched. .LP .SH "SEE ALSO" .BR udevinfo (8), +.BR udevd (8), .BR hotplug (8) .PP The diff --git a/udevd.8 b/udevd.8 index ab13a31107..30adb94f2b 100644 --- a/udevd.8 +++ b/udevd.8 @@ -3,6 +3,21 @@ udevd \- udev event serializer daemon .br udevsend \- sends the event to udevd +.SH SYNOPSIS +.BI udevsend " hotplug-subsystem" +.sp +The environment must provide the following variables: +.TP +.B ACTION +.IR add " or " remove +signifies the connection or disconnection of a device. +.TP +.B DEVPATH +The sysfs devpath of the device without the mountpoint but a leading slash. +.TP +.B SEQNUM +The sequence number of the event provided by the kernel. +If unset, the event bypasses the queue and will be executed immediately. .SH "DESCRIPTION" .B udevd allows the serialization of @@ -33,7 +48,9 @@ isn't already running, .B udevsend will start it. .SH "SEE ALSO" -.BR udev (8), " hotplug" (8) +.BR udev (8), +.BR udevinfo (8), +.BR hotplug (8) .SH AUTHORS .B udevd was developed primarily by Kay Sievers , with much help From 831f800da34ddb449aecae925cd1f154f20b1eed Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 26 Feb 2004 19:40:22 -0800 Subject: [PATCH 0581/4284] [PATCH] udev - safer string handling - part two As promised, here is the next round. We provide in addition to the already used macros: strfieldcpy(to, from) strfieldcat(to, from) the corresponding friends, if the size of the target is not known and must be provided by the caller: strnfieldcpy(to, from, maxsize) strnfieldcat(to, from, maxsize) and switch nearly all possibly unsafe users of strcat(), strncat(), strcpy() and strncpy() to these safer macros. The last known remaining issue seems the use of sprintf() and snprintf(). I will take on it later today or tomorrow. --- namedev.c | 31 ++++++++++++++++++------------- udev.h | 14 +++++++++++++- udev_config.c | 2 +- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/namedev.c b/namedev.c index 219cb8a4b8..f688507dc3 100644 --- a/namedev.c +++ b/namedev.c @@ -209,7 +209,9 @@ static int get_format_len(char **str) return -1; } -static void apply_format(struct udevice *udev, unsigned char *string, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) +static void apply_format(struct udevice *udev, char *string, size_t maxsize, + struct sysfs_class_device *class_dev, + struct sysfs_device *sysfs_device) { char temp[NAME_SIZE]; char temp1[NAME_SIZE]; @@ -245,19 +247,19 @@ static void apply_format(struct udevice *udev, unsigned char *string, struct sys case 'b': if (strlen(udev->bus_id) == 0) break; - strcat(pos, udev->bus_id); + strnfieldcat(pos, udev->bus_id, maxsize); dbg("substitute bus_id '%s'", udev->bus_id); break; case 'k': if (strlen(udev->kernel_name) == 0) break; - strcat(pos, udev->kernel_name); + strnfieldcat(pos, udev->kernel_name, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'n': if (strlen(udev->kernel_number) == 0) break; - strcat(pos, udev->kernel_number); + strnfieldcat(pos, udev->kernel_number, maxsize); dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': @@ -287,11 +289,11 @@ static void apply_format(struct udevice *udev, unsigned char *string, struct sys } } if (pos3) { - strcat(pos, pos3); + strnfieldcat(pos, pos3, maxsize); dbg("substitute part of result string '%s'", pos3); } } else { - strcat(pos, udev->program_result); + strnfieldcat(pos, udev->program_result, maxsize); dbg("substitute result string '%s'", udev->program_result); } break; @@ -302,20 +304,20 @@ static void apply_format(struct udevice *udev, unsigned char *string, struct sys dbg("sysfa attribute '%s' not found", attr); break; } - strcpy(pos, tmpattr->value); + strnfieldcpy(pos, tmpattr->value, maxsize); dbg("substitute sysfs value '%s'", tmpattr->value); } else { dbg("missing attribute"); } break; case '%': - strcat(pos, "%"); + strnfieldcat(pos, "%", maxsize); break; default: dbg("unknown substitution type '%%%c'", c); break; } - strcat(pos, tail); + strnfieldcat(pos, tail, maxsize); } } @@ -462,7 +464,7 @@ static int execute_program(char *path, char *value, int len) strncpy(value, buffer, len); pos = value + strlen(value)-1; if (pos[0] == '\n') - pos[0] = '\0'; + pos[0] = '\0'; dbg("result is '%s'", value); } } @@ -733,7 +735,8 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas /* execute external program */ if (dev->program[0] != '\0') { dbg("check " FIELD_PROGRAM); - apply_format(udev, dev->program, class_dev, sysfs_device); + apply_format(udev, dev->program, sizeof(dev->program), + class_dev, sysfs_device); if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { dbg(FIELD_PROGRAM " returned nozero"); goto try_parent; @@ -825,8 +828,10 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud found: /* substitute placeholder */ - apply_format(udev, udev->name, class_dev, sysfs_device); - apply_format(udev, udev->symlink, class_dev, sysfs_device); + apply_format(udev, udev->name, sizeof(udev->name), + class_dev, sysfs_device); + apply_format(udev, udev->symlink, sizeof(udev->symlink), + class_dev, sysfs_device); udev->partitions = dev->partitions; done: perm = find_perm(udev->name); diff --git a/udev.h b/udev.h index fc44a9847c..0ce010f3c4 100644 --- a/udev.h +++ b/udev.h @@ -64,7 +64,19 @@ do { \ #define strfieldcat(to, from) \ do { \ to[sizeof(to)-1] = '\0'; \ - strncat(to, from, sizeof(to) - strlen(to) -1); \ + strncat(to, from, sizeof(to) - strlen(to)-1); \ +} while (0) + +#define strnfieldcpy(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncpy(to, from, maxsize-1); \ +} while (0) + +#define strnfieldcat(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncat(to, from, maxsize - strlen(to)-1); \ } while (0) extern int udev_add_device(char *path, char *subsystem, int fake); diff --git a/udev_config.c b/udev_config.c index cade81cf20..de83ef9c4c 100644 --- a/udev_config.c +++ b/udev_config.c @@ -81,7 +81,7 @@ static void init_variables(void) #define set_var(_name, _var) \ if (strcasecmp(variable, _name) == 0) { \ dbg_parse("%s = '%s'", _name, value); \ - strncpy(_var, value, sizeof(_var)); \ + strnfieldcpy(_var, value, sizeof(_var));\ } #define set_bool(_name, _var) \ From e964c2c05d3d6e2bdb21b3461ed7a4e85315cbc1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 26 Feb 2004 19:40:32 -0800 Subject: [PATCH 0582/4284] [PATCH] udev - safer string handling - part three Here we truncate our input strings from the environment to our defined limit. It's a bit theroretical but better check for it. It cleans up some magic length definitions and removes the code duplication in udev, udevtest and udevsend. udevd needs to be killed after installation, cause the message size is changed with this patch. Should we do this with the 'make install', like we do with the '.udevdb'? --- namedev.c | 2 +- udev.c | 30 ++---------------------------- udev.h | 45 +++++++++++++++++++++++++++++++++++++++++++++ udevd.c | 4 ++-- udevd.h | 6 +++--- udevsend.c | 26 +------------------------- udevtest.c | 24 ------------------------ 7 files changed, 54 insertions(+), 83 deletions(-) diff --git a/namedev.c b/namedev.c index f688507dc3..bc407dd103 100644 --- a/namedev.c +++ b/namedev.c @@ -405,7 +405,7 @@ static int execute_program(char *path, char *value, int len) int fds[2]; pid_t pid; int value_set = 0; - char buffer[256]; + char buffer[255]; char *pos; char *args[PROGRAM_MAXARG]; int i; diff --git a/udev.c b/udev.c index 1c65f2e59c..4486707f42 100644 --- a/udev.c +++ b/udev.c @@ -43,7 +43,7 @@ char **main_envp; unsigned char logname[42]; void log_message (int level, const char *format, ...) { - va_list args; + va_list args; if (!udev_log) return; @@ -67,30 +67,6 @@ static void sig_handler(int signum) } } -static inline char *get_action(void) -{ - char *action; - - action = getenv("ACTION"); - return action; -} - -static inline char *get_devpath(void) -{ - char *devpath; - - devpath = getenv("DEVPATH"); - return devpath; -} - -static inline char *get_seqnum(void) -{ - char *seqnum; - - seqnum = getenv("SEQNUM"); - return seqnum; -} - static char *subsystem_blacklist[] = { "net", "scsi_host", @@ -130,7 +106,7 @@ static int udev_hotplug(int argc, char **argv) } /* skip blacklisted subsystems */ - subsystem = argv[1]; + subsystem = get_subsystem(argv[1]); if (!subsystem) { dbg("no subsystem?"); goto exit; @@ -200,5 +176,3 @@ int main(int argc, char **argv, char **envp) return udev_hotplug(argc, argv); } - - diff --git a/udev.h b/udev.h index 0ce010f3c4..fa56c36691 100644 --- a/udev.h +++ b/udev.h @@ -23,6 +23,8 @@ #ifndef UDEV_H #define UDEV_H +#include +#include #include #include #include @@ -34,6 +36,10 @@ #define GROUP_SIZE 30 #define MODE_SIZE 8 +#define ACTION_SIZE 30 +#define DEVPATH_SIZE 255 +#define SUBSYSTEM_SIZE 30 + /* length of public data */ #define UDEVICE_LEN (offsetof(struct udevice, bus_id)) @@ -79,6 +85,45 @@ do { \ strncat(to, from, maxsize - strlen(to)-1); \ } while (0) +static inline char *get_action(void) +{ + char *action; + + action = getenv("ACTION"); + if (strlen(action) > ACTION_SIZE) + action[ACTION_SIZE-1] = '\0'; + + return action; +} + +static inline char *get_devpath(void) +{ + char *devpath; + + devpath = getenv("DEVPATH"); + if (strlen(devpath) > DEVPATH_SIZE) + devpath[DEVPATH_SIZE-1] = '\0'; + + return devpath; +} + +static inline char *get_seqnum(void) +{ + char *seqnum; + + seqnum = getenv("SEQNUM"); + + return seqnum; +} + +static inline char *get_subsystem(char *subsystem) +{ + if (strlen(subsystem) > SUBSYSTEM_SIZE) + subsystem[SUBSYSTEM_SIZE-1] = '\0'; + + return subsystem; +} + extern int udev_add_device(char *path, char *subsystem, int fake); extern int udev_remove_device(char *path, char *subsystem); extern void udev_init_config(void); diff --git a/udevd.c b/udevd.c index f7901cb752..2b3dc55788 100644 --- a/udevd.c +++ b/udevd.c @@ -119,8 +119,8 @@ static void msg_queue_insert(struct hotplug_msg *msg) static void udev_run(struct hotplug_msg *msg) { pid_t pid; - char action[32]; - char devpath[256]; + char action[ACTION_SIZE]; + char devpath[DEVPATH_SIZE]; char *env[] = { action, devpath, NULL }; snprintf(action, sizeof(action), "ACTION=%s", msg->action); diff --git a/udevd.h b/udevd.h index 8efe1d569c..8b82ff9a70 100644 --- a/udevd.h +++ b/udevd.h @@ -35,7 +35,7 @@ struct hotplug_msg { pid_t pid; int seqnum; time_t queue_time; - char action[8]; - char devpath[128]; - char subsystem[16]; + char action[ACTION_SIZE]; + char devpath[DEVPATH_SIZE]; + char subsystem[SUBSYSTEM_SIZE]; }; diff --git a/udevsend.c b/udevsend.c index 08212dfee6..4b6ef5c2f3 100644 --- a/udevsend.c +++ b/udevsend.c @@ -52,30 +52,6 @@ void log_message (int level, const char *format, ...) } #endif -static inline char *get_action(void) -{ - char *action; - - action = getenv("ACTION"); - return action; -} - -static inline char *get_devpath(void) -{ - char *devpath; - - devpath = getenv("DEVPATH"); - return devpath; -} - -static inline char *get_seqnum(void) -{ - char *seqnum; - - seqnum = getenv("SEQNUM"); - return seqnum; -} - static int build_hotplugmsg(struct hotplug_msg *msg, char *action, char *devpath, char *subsystem, int seqnum) { @@ -144,7 +120,7 @@ int main(int argc, char* argv[]) #endif dbg("version %s", UDEV_VERSION); - subsystem = argv[1]; + subsystem = get_subsystem(argv[1]); if (subsystem == NULL) { dbg("no subsystem"); goto exit; diff --git a/udevtest.c b/udevtest.c index 4956758636..4bc094fd90 100644 --- a/udevtest.c +++ b/udevtest.c @@ -66,30 +66,6 @@ static void sig_handler(int signum) } } -static inline char *get_action(void) -{ - char *action; - - action = getenv("ACTION"); - return action; -} - -static inline char *get_devpath(void) -{ - char *devpath; - - devpath = getenv("DEVPATH"); - return devpath; -} - -static inline char *get_seqnum(void) -{ - char *seqnum; - - seqnum = getenv("SEQNUM"); - return seqnum; -} - static char *subsystem_blacklist[] = { "net", "scsi_host", From 3fe0734266becd2ebcb111b07c3e17b2a9780477 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 26 Feb 2004 19:40:40 -0800 Subject: [PATCH 0583/4284] [PATCH] udev - safer string handling - part four Mainly a cleanup of the earlier patches with a few missing pieces and some cosmetical changes. I've moved the udev_init_config() to very early init, otherwise we don't get any logging for the processing of the input. What would I do without gdb :) Greg, it's the 7th patch in your box to apply. I will stop now and wait for you :) --- logging.h | 8 ++++---- namedev.c | 18 +++++++++--------- udev.c | 15 ++++++++------- udev.h | 6 +++--- 4 files changed, 24 insertions(+), 23 deletions(-) diff --git a/logging.h b/logging.h index 2ba2ac4965..1c27917f61 100644 --- a/logging.h +++ b/logging.h @@ -37,14 +37,14 @@ #undef info #define info(format, arg...) \ do { \ - log_message (LOG_INFO , format , ## arg); \ + log_message(LOG_INFO , format , ## arg); \ } while (0) #ifdef DEBUG #undef dbg #define dbg(format, arg...) \ do { \ - log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + log_message(LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ } while (0) #endif @@ -53,11 +53,11 @@ #undef dbg_parse #define dbg_parse(format, arg...) \ do { \ - log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + log_message(LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ } while (0) #endif -extern void log_message (int level, const char *format, ...) +extern void log_message(int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); /* each program that uses syslog must declare this variable somewhere */ diff --git a/namedev.c b/namedev.c index bc407dd103..21f52d1f3c 100644 --- a/namedev.c +++ b/namedev.c @@ -228,7 +228,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, pos = string; while (1) { - pos = strchr(pos, '%'); + pos = strchr(string, '%'); if (pos != NULL) { pos[0] = '\0'; tail = pos+1; @@ -247,19 +247,19 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, case 'b': if (strlen(udev->bus_id) == 0) break; - strnfieldcat(pos, udev->bus_id, maxsize); + strnfieldcat(string, udev->bus_id, maxsize); dbg("substitute bus_id '%s'", udev->bus_id); break; case 'k': if (strlen(udev->kernel_name) == 0) break; - strnfieldcat(pos, udev->kernel_name, maxsize); + strnfieldcat(string, udev->kernel_name, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'n': if (strlen(udev->kernel_number) == 0) break; - strnfieldcat(pos, udev->kernel_number, maxsize); + strnfieldcat(string, udev->kernel_number, maxsize); dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': @@ -289,11 +289,11 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } } if (pos3) { - strnfieldcat(pos, pos3, maxsize); + strnfieldcat(string, pos3, maxsize); dbg("substitute part of result string '%s'", pos3); } } else { - strnfieldcat(pos, udev->program_result, maxsize); + strnfieldcat(string, udev->program_result, maxsize); dbg("substitute result string '%s'", udev->program_result); } break; @@ -304,20 +304,20 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("sysfa attribute '%s' not found", attr); break; } - strnfieldcpy(pos, tmpattr->value, maxsize); + strnfieldcat(string, tmpattr->value, maxsize); dbg("substitute sysfs value '%s'", tmpattr->value); } else { dbg("missing attribute"); } break; case '%': - strnfieldcat(pos, "%", maxsize); + strnfieldcat(string, "%", maxsize); break; default: dbg("unknown substitution type '%%%c'", c); break; } - strnfieldcat(pos, tail, maxsize); + strnfieldcat(string, tail, maxsize); } } diff --git a/udev.c b/udev.c index 4486707f42..4ae4684536 100644 --- a/udev.c +++ b/udev.c @@ -41,7 +41,7 @@ char **main_envp; #ifdef LOG unsigned char logname[42]; -void log_message (int level, const char *format, ...) +void log_message(int level, const char *format, ...) { va_list args; @@ -76,7 +76,7 @@ static char *subsystem_blacklist[] = { "", }; -static int udev_hotplug(int argc, char **argv) +static int udev_hotplug(void) { char *action; char *devpath; @@ -106,7 +106,7 @@ static int udev_hotplug(int argc, char **argv) } /* skip blacklisted subsystems */ - subsystem = get_subsystem(argv[1]); + subsystem = get_subsystem(main_argv[1]); if (!subsystem) { dbg("no subsystem?"); goto exit; @@ -123,9 +123,6 @@ static int udev_hotplug(int argc, char **argv) /* connect to the system message bus */ sysbus_connect(); - /* initialize our configuration */ - udev_init_config(); - /* initialize udev database */ retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { @@ -172,7 +169,11 @@ int main(int argc, char **argv, char **envp) main_envp = envp; init_logging("udev"); + + /* initialize our configuration */ + udev_init_config(); + dbg("version %s", UDEV_VERSION); - return udev_hotplug(argc, argv); + return udev_hotplug(); } diff --git a/udev.h b/udev.h index fa56c36691..3b676acf40 100644 --- a/udev.h +++ b/udev.h @@ -90,7 +90,7 @@ static inline char *get_action(void) char *action; action = getenv("ACTION"); - if (strlen(action) > ACTION_SIZE) + if (action != NULL && strlen(action) > ACTION_SIZE) action[ACTION_SIZE-1] = '\0'; return action; @@ -101,7 +101,7 @@ static inline char *get_devpath(void) char *devpath; devpath = getenv("DEVPATH"); - if (strlen(devpath) > DEVPATH_SIZE) + if (devpath != NULL && strlen(devpath) > DEVPATH_SIZE) devpath[DEVPATH_SIZE-1] = '\0'; return devpath; @@ -118,7 +118,7 @@ static inline char *get_seqnum(void) static inline char *get_subsystem(char *subsystem) { - if (strlen(subsystem) > SUBSYSTEM_SIZE) + if (subsystem != NULL && strlen(subsystem) > SUBSYSTEM_SIZE) subsystem[SUBSYSTEM_SIZE-1] = '\0'; return subsystem; From dde05ccb8d423fbc5c29f54b0c1b545938c8f151 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 26 Feb 2004 21:29:49 -0800 Subject: [PATCH 0584/4284] [PATCH] remove limit of the number of args passed to PROGRAM If we go over our internal limit of 7, then we call out to /bin/sh otherwise we handle it ourself without relying on a shell. --- namedev.c | 18 +++++++++++++----- test/udev-test.pl | 9 +++++++++ udev.8 | 3 +-- 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/namedev.c b/namedev.c index 21f52d1f3c..7c07e3b104 100644 --- a/namedev.c +++ b/namedev.c @@ -421,7 +421,13 @@ static int execute_program(char *path, char *value, int len) case 0: /* child */ close(STDOUT_FILENO); - dup(fds[1]); /* dup write side of pipe to STDOUT */ + + /* dup write side of pipe to STDOUT */ + dup(fds[1]); + + /* copy off our path to use incase we have too many args */ + strnfieldcpy(buffer, path, sizeof(buffer)); + if (strchr(path, ' ')) { /* exec with arguments */ pos = path; @@ -431,14 +437,16 @@ static int execute_program(char *path, char *value, int len) break; } if (args[i]) { - dbg("too many args - %d", i); - args[i] = NULL; + dbg("too many args - %d, using subshell instead '%s'", i, buffer); + retval = execl("/bin/sh", "sh", "-c", buffer, NULL); + } else { + dbg("execute program '%s'", path); + retval = execv(args[0], args); } - retval = execv(args[0], args); } else { retval = execv(path, main_argv); } - dbg("child execve failed"); + info(FIELD_PROGRAM " execution of '%s' failed", path); exit(1); case -1: dbg("fork failed"); diff --git a/test/udev-test.pl b/test/udev-test.pl index f2f77dd0e4..a3bf768fe3 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -241,6 +241,15 @@ EOF expected => "escape-3" , conf => < "program with lots of arguments", + subsys => "block", + devpath => "block/sda/sda3", + expected => "foo9" , + conf => < Date: Sat, 28 Feb 2004 00:30:24 -0800 Subject: [PATCH 0585/4284] [PATCH] fix build for very old versions of make. Should get rid of some more error reports of libsysfs header issues. --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 8ab9099f4f..d58569f581 100644 --- a/Makefile +++ b/Makefile @@ -73,6 +73,9 @@ udevdir = ${prefix}/udev # than the local version of klibc #USE_KLIBC = true +# set up PWD so that older versions of make will work with our build. +PWD = $(shell pwd) + # If you are running a cross compiler, you may want to set this # to something more interesting, like "arm-linux-". If you want # to compile vs uClibc, that can be done here as well. From 8481f8ce2bd2b19ebcf3cb96ac6825093f626b0f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 28 Feb 2004 00:52:20 -0800 Subject: [PATCH 0586/4284] [PATCH] Add initial SELinux support for udev Based on a patch from Daniel J Walsh --- Makefile | 8 ++++++++ README | 6 ++++++ udev-add.c | 4 ++++ udev.spec | 15 +++++++++++++++ udev_selinux.c | 34 ++++++++++++++++++++++++++++++++++ udev_selinux.h | 10 ++++++++++ 6 files changed, 77 insertions(+) create mode 100644 udev_selinux.c create mode 100644 udev_selinux.h diff --git a/Makefile b/Makefile index d58569f581..b24e147838 100644 --- a/Makefile +++ b/Makefile @@ -227,6 +227,14 @@ ifeq ($(USE_DBUS), true) OBJS += udev_dbus.o endif +# if USE_SELINUX is enabled, then we do not strip or optimize +ifeq ($(strip $(USE_SELINUX)),true) + CFLAGS += -DUSE_SELINUX + OBJS += udev_selinux.o + LIB_OBJS += -lselinux +endif + + # header files automatically generated GEN_HEADERS = udev_version.h diff --git a/README b/README index c63912101a..75d642c942 100644 --- a/README +++ b/README @@ -49,6 +49,11 @@ To use: creates or removes a device node. This requires that DBUS development headers and libraries be present on your system to build properly. Default value is 'false'. + USE_SELINUX + if set to 'true', SELinux support for udev will be built in. + This requires that SELinux development headers and libraries be + present on your system to build properly. Default value is + 'false'. DEBUG if set to 'true', debugging messages will be sent to the syslog as udev is run. Default value is 'false'. @@ -97,3 +102,4 @@ greg@kroah.com + diff --git a/udev-add.c b/udev-add.c index 0d3131300f..2f64b4375a 100644 --- a/udev-add.c +++ b/udev-add.c @@ -38,6 +38,7 @@ #include "udev.h" #include "udev_version.h" #include "udev_dbus.h" +#include "udev_selinux.h" #include "logging.h" #include "namedev.h" #include "udevdb.h" @@ -217,6 +218,9 @@ static int create_node(struct udevice *dev, int fake) } } + if (!fake) + selinux_add_node(filename); + /* create symlink if requested */ if (dev->symlink[0] != '\0') { symlinks = dev->symlink; diff --git a/udev.spec b/udev.spec index 63d1835a4a..4cd1f8a94b 100644 --- a/udev.spec +++ b/udev.spec @@ -16,6 +16,11 @@ # 1 - DBUS support %define dbus 0 +# if we want to build SELinux support in or not. +# 0 - no SELinux support +# 1 - SELinux support +%define selinux 1 + # if we want to enable debugging support in udev. If it is enabled, lots of # stuff will get sent to the debug syslog. # 0 - debugging disabled @@ -67,6 +72,11 @@ make CC="gcc $RPM_OPT_FLAGS" \ %else USE_DBUS=false \ %endif +%if %{selinux} + USE_SELINUX=true \ +%else + USE_SELINUX=false \ +%endif %if %{debug} DEBUG=true \ %else @@ -85,6 +95,11 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %else USE_DBUS=false \ %endif +%if %{selinux} + USE_SELINUX=true \ +%else + USE_SELINUX=false \ +%endif %if %{lsb} USE_LSB=true \ %else diff --git a/udev_selinux.c b/udev_selinux.c new file mode 100644 index 0000000000..3728fd0b50 --- /dev/null +++ b/udev_selinux.c @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "udev_selinux.h" +#include "logging.h" + + +void selinux_add_node(char *filename) +{ + int retval; + + if (is_selinux_enabled() > 0) { + security_context_t scontext; + retval = matchpathcon(filename, 0, &scontext); + if (retval < 0) { + dbg("matchpathcon(%s) failed\n", filename); + } else { + retval=setfilecon(filename,scontext); + if (retval < 0) + dbg("setfiles %s failed with error '%s'", + filename, strerror(errno)); + free(scontext); + } + } +} + diff --git a/udev_selinux.h b/udev_selinux.h new file mode 100644 index 0000000000..77a1f36bd9 --- /dev/null +++ b/udev_selinux.h @@ -0,0 +1,10 @@ +#ifndef UDEV_SELINUX_H +#define UDEV_SELINUX_H + +#ifdef USE_SELINUX +extern void selinux_add_node(char *filename); +#else +static void selinux_add_node(char *filename) { } +#endif + +#endif From 49f9bede7c06d7c1c55ea795f3fcf36c95f26668 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 28 Feb 2004 00:54:49 -0800 Subject: [PATCH 0587/4284] [PATCH] udev - correct relative symlink Here we remove the useless leading "./" of the linktargets. Thanks to Olaf Hering , who asked why we do this :) We have now: /udev |-- camera0 -> video0 |-- kamera0 -> video0 `-- video0 --- udev-add.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/udev-add.c b/udev-add.c index 2f64b4375a..8fdd66fad5 100644 --- a/udev-add.c +++ b/udev-add.c @@ -251,8 +251,6 @@ static int create_node(struct udevice *dev, int fake) i++; } - if (linktarget[0] == '\0') - strfieldcpy(linktarget, "./"); strfieldcat(linktarget, &dev->name[tail]); /* unlink existing files to ensure that our symlink is created */ From 84d282a9d29f9c1191fca8e58246e9fc912ab2e9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 28 Feb 2004 00:54:52 -0800 Subject: [PATCH 0588/4284] [PATCH] TODO update On Thu, Feb 12, 2004 at 05:26:37PM -0800, Greg KH wrote: > On Fri, Feb 13, 2004 at 12:45:38AM +0100, Kay Sievers wrote: > > > > Here a few questions about my favorite file in the tree :) > > - better permission handling > > > > What is missing here? > > I don't know for sure. Just a vague feeling that the way we currently > handle permissions is pretty lousy. Anyone else feel this way too? Seems that nobody cares and perhaps the recent klibc permission changes and the multiple file config directory are enough to kill these lines? :) --- TODO | 2 -- 1 file changed, 2 deletions(-) diff --git a/TODO b/TODO index 1a29adba0e..2239d7b024 100644 --- a/TODO +++ b/TODO @@ -10,8 +10,6 @@ greg@kroah.com - install the proper init.d script based on the distro we are running on. - persuade the distro packagers to submit their changes (or just steal them if we can find them...) -- keep track of current permissions on devices when daemon shuts down. -- better permission handling - create kernel name to devfs name config file so that all of the devfs users will have an upgrade path. - do early boot logic (putting udev into initramfs, handle pivot-root, From 1373b381d0881dba99b2f2654856d28ac0a70fda Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 28 Feb 2004 00:55:25 -0800 Subject: [PATCH 0589/4284] [PATCH] add new TODO item about local user permissions. --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 2239d7b024..fb94135426 100644 --- a/TODO +++ b/TODO @@ -7,6 +7,7 @@ greg@kroah.com - more documentation (can never have too much.) +- create way to set permission to the local user. - install the proper init.d script based on the distro we are running on. - persuade the distro packagers to submit their changes (or just steal them if we can find them...) From b484e43622c04aaf4a2ca851bc7436b873530b1d Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Sat, 28 Feb 2004 01:00:36 -0800 Subject: [PATCH 0590/4284] [PATCH] update udev scsi_id to scsi_id 0.4 This patch syncs the scsi_id in the udev tree to version 0.4. --- extras/scsi_id/ChangeLog | 43 +++++++ extras/scsi_id/Makefile | 2 +- extras/scsi_id/TODO | 15 +-- extras/scsi_id/gen_scsi_id_udev_rules.sh | 85 ++++++++++++++ extras/scsi_id/release-notes | 50 +++++---- extras/scsi_id/scsi_id.8 | 47 ++++++-- extras/scsi_id/scsi_id.c | 136 +++++++++-------------- extras/scsi_id/scsi_id.h | 6 +- extras/scsi_id/scsi_serial.c | 64 ++++------- 9 files changed, 280 insertions(+), 168 deletions(-) create mode 100644 extras/scsi_id/gen_scsi_id_udev_rules.sh diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog index 7032dfd07f..095d84f2d0 100644 --- a/extras/scsi_id/ChangeLog +++ b/extras/scsi_id/ChangeLog @@ -1,3 +1,46 @@ +2004-feb-25: + * scsi_id.8: Add verbage about usage with udev, and running via + hotplug. + +2004-feb-25: + * scsi_id.c, scsi_id.8: Disable support for -e (all output to + stderr) as it cannot be used in any useful way, and the -c + (device specific callout) as the code is incomplete and has no + users. + +2004-feb-25: + * scsi_id.c: Don't print errno for NULL return from + sysfs_get_classdev_device. + +2004-feb-23: + * scsi_id.c: Get rid of dead/leftover code that checked + if we are on a scsi bus. + +2004-feb-23: + * scsi_serial.c, scsi_id.c: Use ":" consistently in output messages. + +2004-feb-23: + * scsi_serial.c: Add missing new lines for some error messages. + +2004-feb-23: + * scsi_serial.c: open O_NONBLOCK so we handle tape drives without + tapes loaded. + +2004-feb-20: + * scsi_id.h, scsi_id.c: Remove hacks based on KLIBC define to get + around problems when building with udev (udev libsysfs files + were rearranged). + +2004-feb-19: + * scsi_id.h, scsi_id.c, scsi_serial.c: As done in udev code, support + partitions via looking for a parent of the target path. Uses + libsysfs functions to do most of the work, and includes changing + a lot of variables to be struct sysfs_device instead of + sysfs_class_device. + +2004-feb-19: + * Makefile: Version 0.4 + 2004-jan-15: * Makefile: Version 0.3 diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index abf48895ad..bfc2923b34 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.3 +SCSI_ID_VERSION=0.4 prefix = etcdir = ${prefix}/etc diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO index dde5c84a67..4f302ea0a4 100644 --- a/extras/scsi_id/TODO +++ b/extras/scsi_id/TODO @@ -1,11 +1,8 @@ -- add information about the config file to the man page +- Document that config file options override command line options, or fix + the code. This means a '-b' in the config file disables any -g on the + command line. -- change so non-KLIBC builds under udev don't use /usr/include/sysfs, - but instead use the sysfs included with udev (needs udev change and/or - sysfsutils changes). +- Add code to check that SCSI commands get back enough data for their + intended usage, mainly callers of scsi_inquiry(). -- do something with callout code - remove or change to a tag? - - This needs an implementation of a device specific callout or device - specific code (called via some special "tag" or such) before it can be - completed. Someone with such hardware to send in a patch. +- Document the config file in the man page diff --git a/extras/scsi_id/gen_scsi_id_udev_rules.sh b/extras/scsi_id/gen_scsi_id_udev_rules.sh new file mode 100644 index 0000000000..07e21ebd50 --- /dev/null +++ b/extras/scsi_id/gen_scsi_id_udev_rules.sh @@ -0,0 +1,85 @@ +#! /bin/sh + +# This script generates and sends to stdout a set of udev.rules for use +# with all scsi block devices on your system. It creates a udev key NAME +# with prefix defaulting to "disk-", and appends the current kernel name +# and the udev kernel number (the partition number, empty for the entire +# disk). +# +# Managing these is probably better done via a gui interface. +# +# You can edit and append the output to your /etc/udev/udev.rules file. +# You probably want to to change names to be non-kernel defaults, so as to +# avoid confusion if a configuration change modifies /sys/block/sd* +# naming. +# +# /etc/scsi_id.config must be properly configured. If you are using this +# script, you probably want a single line enabling scsi_id for all +# devices as follows: +# +# options=-g +# +# The above assumes you will not attach block devices that do not +# properly support the page codes used by scsi_id, this is especially true +# of many USB mass storage devices (mainly flash card readers). +# + +prefix=disk- +scsi_id=/sbin/scsi_id + +dump_ids() +{ + cd ${sysfs_dir}/block + for b in sd* + do + echo -n "$b " + $scsi_id -s /block/$b + if [ $? != 0 ] + then + echo $0 failed for device $b >&2 + exit 1 + fi + done +} + +sysfs_dir=$(mount | awk '$5 == "sysfs" {print $3}') + +c=$(ls /${sysfs_dir}/block/sd* 2>/dev/null | wc -l) +if [ $c = 0 ] +then + echo $0 no block devices present >&2 + exit 1 +fi + +echo "#" +echo "# Start of autogenerated scsi_id rules. Edit the NAME portions of these" +echo "# rules to your liking." +echo "#" +first_line=yes +dump_ids | while read in +do + set $in + name=$1 + shift + id="$*" + if [ $first_line = "yes" ] + then + first_line=no + echo "BUS=\"scsi\", PROGRAM=\"${scsi_id}\", RESULT=\"${id}\", NAME=\"${prefix}${name}%n\"" + echo + echo "# Further RESULT keys use the result of the last PROGRAM rule." + echo "# Be careful not to add any rules containing PROGRAM key between here" + echo "# and the end of this section" + echo + else + # No PROGRAM, so just use the last result of PROGRAM. The + # following is the same as the above without the PROGRAM + # key. + echo "BUS=\"scsi\", RESULT=\"${id}\", NAME=\"${prefix}${name}%n\"" + fi + +done + +echo "#" +echo "# End of autogenerated scsi_id rules" +echo "#" diff --git a/extras/scsi_id/release-notes b/extras/scsi_id/release-notes index 7ef12a25db..a10b569c2d 100644 --- a/extras/scsi_id/release-notes +++ b/extras/scsi_id/release-notes @@ -1,39 +1,49 @@ -Version 0.3 of scsi_id is available at: +Version 0.4 of scsi_id is available at: -http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.3.tar.gz +http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.4.tar.gz -scsi_id is a program to generate a SCSI unique identifier for a given SCSI +scsi_id is a program to generate a unique identifier for a given SCSI device. -It is primarily for use with udev callout config entries. It can also be -used for automatic multi-path configuration or device mapper configuration. +It is primarily for use with the udev callout key. It could also be used +for automatic multi-path configuration or device mapper configuration. -Version 0.3 requires: +Version 0.4 requires: - Linux kernel 2.6 - libsysfs 0.4.0 Major changes since the last release: - - Changes to work with libsysfs 0.4.0 + - Support block device partitions -All changes: + - Added a script to auto-generate udev rules. The script is not + installed but is part of the tarball. - - fix "prefix" usage for path to scsi_id.config +Detailed changes: - - install the sample scsi_id.config file. + - Add man page verbage about usage with udev, and running via + hotplug - - Use DESTDIR in all install/uninstall rules, per problem reported - by Svetoslav Slavtchev. + - Disable support for -e (all output to stderr) as it cannot be + used in any useful way, and the -c (device specific callout) as + the code is incomplete and has no users. - - Fix to work with current sysfs 0.4, based on patch from Dan - Stekloff, but uses sysfs_read_attribute_value instead of - sysfs_get_value_from_attributes. + - Don't print errno for NULL return from sysfs_get_classdev_device. - - SYSFS_BUS_DIR was replaced with SYSFS_BUS_NAME. + - Get rid of dead/leftover code that checked if we are on a scsi + bus. - - Must now use sysfs_open_class_device_path instead of the - previous sysfs_open_class_device. + - ":" consistently in output messages. - - patch from Olaf Hering remove DEBUG and - add --fno-builtin + - Add missing new lines for some error messages. + + - open O_NONBLOCK so we handle tape drives without tapes loaded. + + - Remove hacks based on KLIBC define to get around problems when + building with udev (udev libsysfs files were rearranged). + + - As done in udev code, support partitions via looking for a + parent of the target path. Uses libsysfs functions to do most of + the work, and includes changing a lot of variables to be struct + sysfs_device instead of sysfs_class_device. diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index a4fb881a05..db3effbc45 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -50,9 +50,13 @@ identifier starts with the NAA value of 6): .fi .P - .SH OPTIONS .TP +.BI subsystem +When called with only a single argument without a leading \-, runs in a hotplug +mode, and expects the environment variable DEVPATH to specify the +corresponding sysfs device. See section below on usage with \fBudev\fP. +.TP .BI \-b 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. @@ -63,11 +67,6 @@ 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. .TP -.BI \-e -Send all output to standard error even if -.B scsi_id -is running in hotplug mode. -.TP .BI \-f "\| config-file" Read configuration and black/white list entries from .B config-file @@ -90,7 +89,7 @@ Use SCSI INQUIRY VPD page code 0x80 or 0x83. The default behaviour is to query the available VPD pages, and use page 0x83 if found, else page 0x80 if found, else nothing. .TP -.BI \-s "\|sysfs-device" +.BI \-s "\| sysfs-device" Generate an id for the .B sysfs-device. The sysfs mount point must not be included. For example, use /block/sd, @@ -102,6 +101,37 @@ Generate verbose debugging output. .BI \-V Display version number and exit. .RE + +.SH USAGE WITH UDEV +If \fBscsi_id\fP is invoked with one argument without a leading \-, it +assumes it is called for a hotplug event, and looks for the sysfs device +in the DEVPATH environment variable. + +This mode is used when run via the \fBudev\fP PROGRAM key. Passing any +arguments or options as part of the PROGRAM rule breaks this assumption, +and the results will likely not be as expected. + +When in this mode, all errors and warnings are sent via syslog. + +To determine the specific value needed in a RESULT key, use the -s option, +for example: + +.sp +.nf +/sbin/scsi_id -s /block/sda +.fi +.P + +An example \fBudev\fP rule using \fBscsi_id\fP, that will name a block +device and any partitions for the device matching the \fBscsi_id\fP output +of 312345: + +.sp +.nf +BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="312345", NAME="disk%n" +.fi +.P + .SH "FILES" .nf .ft B @@ -110,8 +140,7 @@ Display version number and exit. .fi .LP .SH "SEE ALSO" -.BR udev (8) -, especially the CALLOUT method. +.BR udev (8), hotplug (8) .SH AUTHORS Developed by Patrick Mansfield based on SCSI ID source included in earlier linux 2.5 kernels, sg_utils source, and SCSI diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 2754381976..1cd6981e5e 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -33,7 +33,6 @@ #include #include #include - #include "scsi_id_version.h" #include "scsi_id.h" @@ -48,11 +47,16 @@ #define TMP_DIR "/tmp" #define TMP_PREFIX "scsi" -static const char short_options[] = "bc:d:ef:gip:s:vV"; +/* + * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout) + * options are not supported, but other code is still left in place for + * now. + */ +static const char short_options[] = "bd:f:gip:s:vV"; /* * Just duplicate per dev options. */ -static const char dev_short_options[] = "bc:gp:"; +static const char dev_short_options[] = "bgp:"; char sysfs_mnt_path[SYSFS_PATH_MAX]; @@ -107,55 +111,6 @@ int sysfs_get_attr(const char *devpath, const char *attr, char *value, return sysfs_read_attribute_value(attr_path, value, SYSFS_NAME_LEN); } -static int sysfs_get_actual_dev(const char *sysfs_path, char *dev, int len) -{ - dprintf("%s\n", sysfs_path); - strncpy(dev, sysfs_path, len); - strncat(dev, "/device", len); - if (sysfs_get_link(dev, dev, len)) { - if (!hotplug_mode) - log_message(LOG_WARNING, "%s: %s\n", dev, - strerror(errno)); - return -1; - } - return 0; -} - -/* - * sysfs_is_bus: Given the sysfs_path to a device, return 1 if sysfs_path - * is on bus, 0 if not on bus, and < 0 on error - */ -static int sysfs_is_bus(const char *sysfs_path, const char *bus) -{ - char bus_dev_name[SYSFS_PATH_MAX]; - char bus_id[SYSFS_NAME_LEN]; - struct stat stat_buf; - ino_t dev_inode; - - dprintf("%s\n", sysfs_path); - - if (sysfs_get_name_from_path(sysfs_path, bus_id, SYSFS_NAME_LEN)) - return -1; - - snprintf(bus_dev_name, MAX_NAME_LEN, "%s/%s/%s/%s/%s", sysfs_mnt_path, - SYSFS_BUS_NAME, bus, SYSFS_DEVICES_NAME, bus_id); - - if (stat(sysfs_path, &stat_buf)) - return -1; - dev_inode = stat_buf.st_ino; - - if (stat(bus_dev_name, &stat_buf)) { - if (errno == ENOENT) - return 0; - else - return -1; - } - if (dev_inode == stat_buf.st_ino) - return 1; - else - return 0; -} - static int get_major_minor(const char *devpath, int *major, int *minor) { char dev_value[MAX_ATTR_LEN]; @@ -168,7 +123,7 @@ static int get_major_minor(const char *devpath, int *major, int *minor) * And if sysfsutils changes, check for ENOENT and handle * it separately. */ - log_message(LOG_DEBUG, "%s could not get dev attribute: %s\n", + log_message(LOG_DEBUG, "%s: could not get dev attribute: %s\n", devpath, strerror(errno)); return -1; } @@ -534,7 +489,7 @@ static int set_options(int argc, char **argv, const char *short_opts, return 0; } -static int per_dev_options(struct sysfs_class_device *scsi_dev, int *good_bad, +static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, int *page_code, char *callout) { int retval; @@ -628,9 +583,10 @@ static int scsi_id(const char *target_path, char *maj_min_dev) { int retval; int dev_type = 0; - char full_dev_path[MAX_NAME_LEN]; char serial[MAX_SERIAL_LEN]; - struct sysfs_class_device *scsi_dev; /* of scsi_device full_dev_path */ + struct sysfs_class_device *class_dev; /* of target_path */ + struct sysfs_class_device *class_dev_parent; /* for partitions */ + struct sysfs_device *scsi_dev; /* the scsi_device */ int good_dev; int page_code; char callout[MAX_NAME_LEN]; @@ -661,20 +617,48 @@ static int scsi_id(const char *target_path, char *maj_min_dev) } } - if (sysfs_get_actual_dev(target_path, full_dev_path, MAX_NAME_LEN)) + class_dev = sysfs_open_class_device_path(target_path); + if (!class_dev) { + log_message(LOG_WARNING, "open class %s failed: %s\n", + target_path, strerror(errno)); return 1; - - dprintf("full_dev_path %s\n", full_dev_path); + } + class_dev_parent = sysfs_get_classdev_parent(class_dev); + dprintf("class_dev 0x%p; class_dev_parent 0x%p\n", class_dev, + class_dev_parent); + if (class_dev_parent) { + scsi_dev = sysfs_get_classdev_device(class_dev_parent); + } else { + scsi_dev = sysfs_get_classdev_device(class_dev); + } /* - * Allow only scsi devices (those that have a matching device - * under /bus/scsi/devices). + * The close of scsi_dev will close class_dev or class_dev_parent. + */ + + /* + * We assume we are called after the device is completely ready, + * so we don't have to loop here like udev. (And we are usually + * called via udev.) + */ + if (!scsi_dev) { + /* + * errno is not set if we can't find the device link, so + * don't print it out here. + */ + log_message(LOG_WARNING, "Cannot find sysfs device associated with %s\n", + target_path); + return 1; + } + + + /* + * Allow only scsi devices. * * Other block devices can support SG IO, but only ide-cd does, so * for now, don't bother with anything else. */ - retval = sysfs_is_bus(full_dev_path, "scsi"); - if (retval == 0) { + if (strcmp(scsi_dev->bus, "scsi") != 0) { if (hotplug_mode) /* * Expected in some cases. @@ -684,14 +668,12 @@ static int scsi_id(const char *target_path, char *maj_min_dev) log_message(LOG_WARNING, "%s is not a scsi device\n", target_path); return 1; - } else if (retval < 0) { - log_message(LOG_WARNING, "sysfs_is_bus failed: %s\n", - strerror(errno)); - return 1; } /* * mknod a temp dev to communicate with the device. + * + * XXX pass down class_dev or class_dev_parent. */ if (!dev_specified && create_tmp_dev(target_path, maj_min_dev, dev_type)) { @@ -699,13 +681,6 @@ static int scsi_id(const char *target_path, char *maj_min_dev) return 1; } - scsi_dev = sysfs_open_class_device_path(full_dev_path); - if (!scsi_dev) { - log_message(LOG_WARNING, "open class %s failed: %s\n", - full_dev_path, strerror(errno)); - return 1; - } - /* * Get any per device (vendor + model) options from the config * file. @@ -718,14 +693,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) retval = 1; } else if (callout[0] != '\0') { /* - * exec vendor callout, pass it only the "name" to be used - * for error messages, and the dev to open. - * - * This won't work if we need to pass on the original - * command line (when not hotplug mode) since the option - * parsing and per dev parsing modify the argv's. - * - * XXX Not implemented yet. And not fully tested ;-) + * XXX Disabled for now ('c' is not in any options[]). */ retval = 1; } else if (scsi_get_serial(scsi_dev, maj_min_dev, page_code, @@ -736,14 +704,14 @@ static int scsi_id(const char *target_path, char *maj_min_dev) } if (!retval) { if (display_bus_id) - printf("%s ", scsi_dev->name); + printf("%s: ", scsi_dev->name); printf("%s", serial); if (!hotplug_mode) printf("\n"); dprintf("%s\n", serial); retval = 0; } - sysfs_close_class_device(scsi_dev); + sysfs_close_device(scsi_dev); if (!dev_specified) unlink(maj_min_dev); diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 573a2b60d7..9edb39ec49 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -47,9 +47,9 @@ extern int sysfs_get_attr(const char *devpath, const char *attr, char *value, size_t bufsize); -extern int scsi_get_serial (struct sysfs_class_device *scsi_dev, - const char *devname, int page_code, char *serial, - int len); +extern int scsi_get_serial (struct sysfs_device *scsi_dev, const char + *devname, int page_code, char *serial, int + len); extern void log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 9fb0f05e61..ae83330c30 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -32,7 +32,6 @@ #include #include #include - #include "scsi_id.h" #include "scsi.h" @@ -70,12 +69,6 @@ static const struct scsi_id_search_values id_search_list[] = { static const char hex_str[]="0123456789abcdef"; -/* - * XXX maybe move all these to an sg_io.c file. - * - * From here ... - */ - /* * Values returned in the result/status, only the ones used by the code * are used here. @@ -160,8 +153,7 @@ static int sg_err_category3(struct sg_io_hdr *hp) hp->sbp, hp->sb_len_wr); } -static int scsi_dump_sense(struct sysfs_class_device *scsi_dev, - struct sg_io_hdr *io) +static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) { unsigned char *sense_buffer; int s; @@ -257,7 +249,7 @@ static int scsi_dump_sense(struct sysfs_class_device *scsi_dev, scsi_dev->name, sense_buffer[0], sense_buffer[2]); log_message(LOG_WARNING, - "%s: non-extended sense class %d code 0x%0x ", + "%s: non-extended sense class %d code 0x%0x\n", scsi_dev->name, sense_class, code); } @@ -277,7 +269,7 @@ static int scsi_dump_sense(struct sysfs_class_device *scsi_dev, return -1; } -static int scsi_dump(struct sysfs_class_device *scsi_dev, struct sg_io_hdr *io) +static int scsi_dump(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) { if (!io->status && !io->host_status && !io->msg_status && !io->driver_status) { @@ -298,9 +290,9 @@ static int scsi_dump(struct sysfs_class_device *scsi_dev, struct sg_io_hdr *io) return -1; } -static int scsi_inquiry(struct sysfs_class_device *scsi_dev, int fd, - unsigned char evpd, unsigned char page, unsigned - char *buf, unsigned int buflen) +static int scsi_inquiry(struct sysfs_device *scsi_dev, 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 }; @@ -332,7 +324,7 @@ resend: io_hdr.timeout = DEF_TIMEOUT; if (ioctl(fd, SG_IO, &io_hdr) < 0) { - log_message(LOG_WARNING, "%s ioctl failed: %s\n", + log_message(LOG_WARNING, "%s: ioctl failed: %s\n", scsi_dev->name, strerror(errno)); return -1; } @@ -349,11 +341,6 @@ resend: retval = scsi_dump(scsi_dev, &io_hdr); } - /* - * XXX where is the length checked? That is, was our request - * buffer long enough? - */ - if (!retval) { retval = buflen; memcpy(buf, buffer, retval); @@ -369,13 +356,7 @@ resend: return retval; } -/* - * XXX maybe move all these to an sg_io.c file. - * - * Ending here. - */ - -static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, +static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, char *buffer, int len) { int retval; @@ -392,7 +373,7 @@ static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, return 1; } if (buffer[3] > len) { - log_message(LOG_WARNING, "%s: page 0 buffer too long %d", + log_message(LOG_WARNING, "%s: page 0 buffer too long %d\n", scsi_dev->name, buffer[3]); return 1; } @@ -417,7 +398,7 @@ static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, return 1; } if (!strncmp(&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) { - log_message(LOG_WARNING, "%s invalid page0 data\n", + log_message(LOG_WARNING, "%s: invalid page0 data\n", scsi_dev->name); return 1; } @@ -429,8 +410,7 @@ static int do_scsi_page0_inquiry(struct sysfs_class_device *scsi_dev, int fd, * The caller checks that serial is long enough to include the vendor + * model. */ -static int prepend_vendor_model(struct sysfs_class_device *scsi_dev, - char *serial) +static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial) { char attr[MAX_ATTR_LEN]; int ind; @@ -477,10 +457,9 @@ static int prepend_vendor_model(struct sysfs_class_device *scsi_dev, * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill * serial number. **/ -static int check_fill_0x83_id(struct sysfs_class_device *scsi_dev, - char *page_83, - const struct scsi_id_search_values *id_search, - char *serial, int max_len) +static int check_fill_0x83_id(struct sysfs_device *scsi_dev, char + *page_83, const struct scsi_id_search_values + *id_search, char *serial, int max_len) { int i, j, len; @@ -565,7 +544,7 @@ static int check_fill_0x83_id(struct sysfs_class_device *scsi_dev, return 0; } -static int do_scsi_page83_inquiry(struct sysfs_class_device *scsi_dev, int fd, +static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int len) { int retval; @@ -622,7 +601,7 @@ static int do_scsi_page83_inquiry(struct sysfs_class_device *scsi_dev, int fd, return 1; } -static int do_scsi_page80_inquiry(struct sysfs_class_device *scsi_dev, int fd, +static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int max_len) { int retval; @@ -662,7 +641,7 @@ static int do_scsi_page80_inquiry(struct sysfs_class_device *scsi_dev, int fd, return 0; } -int scsi_get_serial (struct sysfs_class_device *scsi_dev, const char *devname, +int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, int page_code, char *serial, int len) { unsigned char page0[256]; @@ -674,9 +653,9 @@ int scsi_get_serial (struct sysfs_class_device *scsi_dev, const char *devname, } memset(serial, 0, len); dprintf("opening %s\n", devname); - fd = open(devname, O_RDONLY); + fd = open(devname, O_RDONLY | O_NONBLOCK); if (fd < 0) { - log_message(LOG_WARNING, "%s cannot open %s: %s\n", + log_message(LOG_WARNING, "%s: cannot open %s: %s\n", scsi_dev->name, devname, strerror(errno)); return 1; } @@ -698,7 +677,7 @@ int scsi_get_serial (struct sysfs_class_device *scsi_dev, const char *devname, goto completed; } } else if (page_code != 0x00) { - log_message(LOG_WARNING, "%s unsupported page code 0x%d\n", + log_message(LOG_WARNING, "%s: unsupported page code 0x%d\n", scsi_dev->name, page_code); return 1; } @@ -743,6 +722,7 @@ int scsi_get_serial (struct sysfs_class_device *scsi_dev, const char *devname, retval = 1; completed: if (close(fd) < 0) - log_message(LOG_WARNING, "close failed: %s", strerror(errno)); + log_message(LOG_WARNING, "%s: close failed: %s\n", + scsi_dev->name, strerror(errno)); return retval; } From 7eb136adb8fe265050b2a3e44b216e747163743f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 28 Feb 2004 01:11:20 -0800 Subject: [PATCH 0591/4284] [PATCH] 018 release --- ChangeLog | 32 ++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 5 ++++- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bcc22c2328..a3cc00c17a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +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 ============================================ diff --git a/Makefile b/Makefile index b24e147838..9f7c439974 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ DAEMON = udevd SENDER = udevsend HELPER = udevinfo TESTER = udevtest -VERSION = 018_bk +VERSION = 019 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 4cd1f8a94b..92a2911711 100644 --- a/udev.spec +++ b/udev.spec @@ -39,7 +39,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 018_bk +Version: 019 Release: 1 License: GPL Group: Utilities/System @@ -150,6 +150,9 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Fri Feb 27 2004 Greg Kroah-Hartman +- added ability to build with SELinux support + * Thu Feb 19 2004 Greg Kroah-Hartman - add some more files to the documentation directory - add ability to build scsi_id and make it the default From c58e36c092ad5acc84d35e455ecc74096b25ae66 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 28 Feb 2004 01:59:02 -0800 Subject: [PATCH 0592/4284] [PATCH] udev - safer sprintf() use Here is for now my last patch to the string handling for a rather theorethical case, where the node is very very very long. :) We have accordant to strfieldcat(to, from) now a strintcat(to, i) macro, which appends the ascii representation of a integer to a string in a safe way. --- namedev.c | 6 +++--- udev-add.c | 3 ++- udev-remove.c | 3 ++- udev.h | 12 ++++++++++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/namedev.c b/namedev.c index 7c07e3b104..581a7f2218 100644 --- a/namedev.c +++ b/namedev.c @@ -263,11 +263,11 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': - sprintf(pos, "%u", udev->minor); + strnintcat(string, udev->minor, maxsize); dbg("substitute minor number '%u'", udev->minor); break; - case 'M': - sprintf(pos, "%u", udev->major); + case 'M': + strnintcat(string, udev->major, maxsize); dbg("substitute major number '%u'", udev->major); break; case 'c': diff --git a/udev-add.c b/udev-add.c index 8fdd66fad5..3a72c544b8 100644 --- a/udev-add.c +++ b/udev-add.c @@ -211,7 +211,8 @@ static int create_node(struct udevice *dev, int fake) info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions); if (!fake) { for (i = 1; i <= dev->partitions; i++) { - sprintf(partitionname, "%s%i", filename, i); + strfieldcpy(partitionname, filename); + strintcat(partitionname, i); make_node(partitionname, dev->major, dev->minor + i, dev->mode, uid, gid); } diff --git a/udev-remove.c b/udev-remove.c index 8794429635..e62d1fb122 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -87,7 +87,8 @@ static int delete_node(struct udevice *dev) if (dev->partitions > 0) { info("removing partitions '%s[1-%i]'", filename, dev->partitions); for (i = 1; i <= dev->partitions; i++) { - sprintf(partitionname, "%s%i", filename, i); + strfieldcpy(partitionname, filename); + strintcat(partitionname, i); unlink(partitionname); } } diff --git a/udev.h b/udev.h index 3b676acf40..5737c84c9d 100644 --- a/udev.h +++ b/udev.h @@ -85,6 +85,18 @@ do { \ strncat(to, from, maxsize - strlen(to)-1); \ } while (0) +#define strintcat(to, i) \ +do { \ + to[sizeof(to)-1] = '\0'; \ + snprintf((to) + strlen(to), sizeof(to) - strlen(to)-1, "%u", i); \ +} while (0) + +#define strnintcat(to, i, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ +} while (0) + static inline char *get_action(void) { char *action; From f070df164c95f825ba0217a71b2d475fd4a8a29e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 1 Mar 2004 22:23:35 -0800 Subject: [PATCH 0593/4284] [PATCH] udev - kill udevd on install We want to kill udevd after installing a new version, cause the event contains a magic with the version number of udev. --- Makefile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 9f7c439974..739b9c1351 100644 --- a/Makefile +++ b/Makefile @@ -373,10 +373,12 @@ install: install-config install-dbus-policy all $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 - - ln -f -s ./udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - - rm -f $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug - - rm -f $(DESTDIR)$(udevdir)/.udev.tdb + - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug +ifndef DESTDIR + - killall udevd + - rm -f $(udevdir)/.udev.tdb +endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ From 97ed02eebe5c0676848d0707d13f4a21b6f4232f Mon Sep 17 00:00:00 2001 From: "arvidjaar@mail.ru" Date: Mon, 1 Mar 2004 22:23:39 -0800 Subject: [PATCH 0594/4284] [PATCH] Add symlink only rules support --- namedev.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/namedev.c b/namedev.c index 581a7f2218..c9232fa2aa 100644 --- a/namedev.c +++ b/namedev.c @@ -816,17 +816,31 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud list_for_each_entry(dev, &config_device_list, node) { dbg("process rule"); if (match_rule(dev, class_dev, udev, sysfs_device) == 0) { - if (dev->name[0] == '\0') { + if (dev->name[0] == '\0' && dev->symlink[0] == '\0') { info("configured rule in '%s' at line %i applied, '%s' is ignored", udev_rules_filename, dev->config_line, udev->kernel_name); return -1; } - info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", - udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); - strfieldcpy(udev->name, dev->name); - strfieldcpy(udev->symlink, dev->symlink); - goto found; + if (dev->symlink[0] != '\0') { + char temp[NAME_MAX]; + + info("configured rule in '%s' at line %i applied, added symlink '%s'", + udev_rules_filename, dev->config_line, dev->symlink); + /* do not clobber dev */ + strfieldcpy(temp, dev->symlink); + apply_format(udev, temp, sizeof(temp), + class_dev, sysfs_device); + strfieldcat(udev->symlink, temp); + strfieldcat(udev->symlink, " "); + } + + if (dev->name[0] != '\0') { + info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", + udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); + strfieldcpy(udev->name, dev->name); + goto found; + } } } @@ -838,8 +852,6 @@ found: /* substitute placeholder */ apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - apply_format(udev, udev->symlink, sizeof(udev->symlink), - class_dev, sysfs_device); udev->partitions = dev->partitions; done: perm = find_perm(udev->name); From e408796e91e89a3fa50d1b8dc964f07fd439d865 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 28 Feb 2004 01:59:44 -0800 Subject: [PATCH 0595/4284] [PATCH] 019_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 739b9c1351..c315d099ef 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ DAEMON = udevd SENDER = udevsend HELPER = udevinfo TESTER = udevtest -VERSION = 019 +VERSION = 019_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 92a2911711..ae802ca8e5 100644 --- a/udev.spec +++ b/udev.spec @@ -39,7 +39,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 019 +Version: 019_bk Release: 1 License: GPL Group: Utilities/System From 63ead27c228f9306f175b14a49df2415d09ece10 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 28 Feb 2004 06:53:25 -0800 Subject: [PATCH 0596/4284] [PATCH] udev - activate formt length attribute We carried the the old callout part selector syntax for two releases now after it was replaced by the new %c{1} syntax. So here we remove the old syntax and use the code to possibly specify the maximum count of chars to insert into the string. It will work with all of our format chars. I don't know if somebody will use it, but the code is already there :) 's%3s{vendor}' returns "IBM" now, instead of "IBM-ESXS". Also added is a test for it and a few words in the man page. --- namedev.c | 10 +++++++--- test/udev-test.pl | 9 +++++++++ udev.8 | 8 ++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/namedev.c b/namedev.c index c9232fa2aa..505264554d 100644 --- a/namedev.c +++ b/namedev.c @@ -220,7 +220,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, char *pos2; char *pos3; char *attr; - int num; + int len; int i; char c; struct sysfs_attribute *tmpattr; @@ -232,7 +232,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, if (pos != NULL) { pos[0] = '\0'; tail = pos+1; - num = get_format_len(&tail); + len = get_format_len(&tail); c = tail[0]; strfieldcpy(temp, tail+1); tail = temp; @@ -274,7 +274,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, if (strlen(udev->program_result) == 0) break; /* get part part of the result string */ - i = num; /* num syntax is deprecated and will be removed */ + i = 0; if (attr != NULL) i = atoi(attr); if (i > 0) { @@ -317,6 +317,10 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("unknown substitution type '%%%c'", c); break; } + /* truncate to specified length */ + if (len > 0) + pos[len] = '\0'; + strnfieldcat(string, tail, maxsize); } } diff --git a/test/udev-test.pl b/test/udev-test.pl index a3bf768fe3..6b7f515442 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -191,6 +191,15 @@ EOF expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "test NAME substitution chars (with length limit)", + subsys => "block", + devpath => "block/sda/sda3", + expected => "M8-m3-n3-b0:0-sIBM" , + conf => < Date: Mon, 1 Mar 2004 22:28:51 -0800 Subject: [PATCH 0597/4284] [PATCH] udev - fix debug info for multiple rule file config On Sat, Feb 28, 2004 at 09:56:32PM +0100, Kay Sievers wrote: > Andrey pointed out that we don't print the right filename in the debug > output. Here is a fix for that. It applies on top of Andrey's symlink > patch, cause we are touching the same part of the code. The copy/paste devil catched me :) Here is a fixed one. --- namedev.c | 6 +++--- namedev.h | 1 + namedev_parse.c | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/namedev.c b/namedev.c index 505264554d..2ebf276f6b 100644 --- a/namedev.c +++ b/namedev.c @@ -822,7 +822,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud if (match_rule(dev, class_dev, udev, sysfs_device) == 0) { if (dev->name[0] == '\0' && dev->symlink[0] == '\0') { info("configured rule in '%s' at line %i applied, '%s' is ignored", - udev_rules_filename, dev->config_line, udev->kernel_name); + dev->config_file, dev->config_line, udev->kernel_name); return -1; } @@ -830,7 +830,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud char temp[NAME_MAX]; info("configured rule in '%s' at line %i applied, added symlink '%s'", - udev_rules_filename, dev->config_line, dev->symlink); + dev->config_file, dev->config_line, dev->symlink); /* do not clobber dev */ strfieldcpy(temp, dev->symlink); apply_format(udev, temp, sizeof(temp), @@ -841,7 +841,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud if (dev->name[0] != '\0') { info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", - udev_rules_filename, dev->config_line, udev->kernel_name, dev->name); + dev->config_file, dev->config_line, udev->kernel_name, dev->name); strfieldcpy(udev->name, dev->name); goto found; } diff --git a/namedev.h b/namedev.h index ffdde83ca4..7f875ed603 100644 --- a/namedev.h +++ b/namedev.h @@ -72,6 +72,7 @@ struct config_device { char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; int partitions; + char config_file[NAME_SIZE]; int config_line; }; diff --git a/namedev_parse.c b/namedev_parse.c index d300b0907d..19acd96ef0 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -260,6 +260,7 @@ static int namedev_parse_rules(char *filename) } dev.config_line = lineno; + strfieldcpy(dev.config_file, filename); retval = add_config_dev(&dev); if (retval) { dbg("add_config_dev returned with error %d", retval); From b7b6562729a661f6ebf4576e9ce90e9228315e93 Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Mon, 1 Mar 2004 22:34:08 -0800 Subject: [PATCH 0598/4284] [PATCH] remove usage of expr in ide-devfs.sh fix_expr: remove usage of expr in ide-devfs.sh, because it may be in /usr/bin and not available at early boot time. --- extras/ide-devfs.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 0a9369dff4..e5bf177f8b 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -8,7 +8,7 @@ HOST="${2%\.[0-9]}" TARGET="${2#[0-9]\.}" if [ -z "${HOST#[13579]}" ]; then - HOST=`expr ${HOST} - 1` + HOST=$((${HOST} - 1)) BUS="1" else BUS="0" @@ -24,7 +24,7 @@ get_dev_number() { if [ -e "${x}" ]; then MEDIA=`cat ${x}` if [ "${MEDIA}" = "$2" ]; then - num=`expr ${num} + 1` + num=$((${num} + 1)) fi if [ "${x}" = "/proc/ide/${DRIVE}/media" ]; then break @@ -32,7 +32,7 @@ get_dev_number() { fi done - echo `expr ${num} - 1` + echo $((${num} - 1)) } if [ -z "$3" ]; then From 758f236fd1385fc7d95c719ec03e4e22ef205bf8 Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Mon, 1 Mar 2004 22:34:10 -0800 Subject: [PATCH 0599/4284] [PATCH] escape dashes in man pages man-dashes.diff: escape dashes in man pages, helps with UTF-8 locales (by Philipp Matthias Hahn). --- udev.8 | 6 +++--- udevinfo.8 | 22 +++++++++++----------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/udev.8 b/udev.8 index e449ef8dbb..21ec908b82 100644 --- a/udev.8 +++ b/udev.8 @@ -304,8 +304,8 @@ Matches any single character, but does not match zero characters. .B [ ] 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 +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 '!' then any character not enclosed is matched. .SH "FILES" .nf @@ -320,7 +320,7 @@ following the '[' is a '!' then any character not enclosed is matched. .BR hotplug (8) .PP The -.I http://linux-hotplug.sourceforge.net/ +.I http://linux\-hotplug.sourceforge.net/ web site. .SH AUTHORS .B udev diff --git a/udevinfo.8 b/udevinfo.8 index 1716d17434..ad16ce6aed 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -3,7 +3,7 @@ udevinfo \- retrieve information from udev .SH SYNOPSIS .B udevinfo -.RI "[-q " query_type " -p " sysfs_path "] [-drVh]" +.RI "[\-q " query_type " \-p " sysfs_path "] [\-drVh]" .SH "DESCRIPTION" .B udevinfo allows users to query the udev database for information on any of the devices @@ -13,40 +13,40 @@ in the sysfs tree to help in creating rule files. .SH "OPTIONS" .TP -.B -V +.B \-V Print the version information. .TP -.B -r +.B \-r Print the the .B udev_root directory. When used in conjunction with a query for the node name, the .B udev_root will be prepended. .TP -.BI -q " query_type" +.BI \-q " query_type" Query the database for specified value of a created device node. -.RB Needs " -p " or " -n " specified. +.RB Needs " \-p " or " \-n " specified. .br Valid types are: .BR name ", " symlink ", " mode " ," owner " , " group " or " path. .TP -.BI -p " sysfs_path" +.BI \-p " sysfs_path" Specify the sysfs path of the device to query. .TP -.BI -n " name" +.BI \-n " name" Specify the name of the node for the device to query. .TP -.B -a +.B \-a Print all .BI SYSFS{ filename } attributes along the device chain. Useful for for finding unique attributes to compose a rule. -.RB Needs " -p " specified. +.RB Needs " \-p " specified. .TP -.B -d +.B \-d Dump the whole database. .TP -.B -h +.B \-h Print help text. .SH "FILES" .nf From 92c5ddee382d06de63c10aa81a18255d0b789812 Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Mon, 1 Mar 2004 22:34:12 -0800 Subject: [PATCH 0600/4284] [PATCH] no error on enoent no_error_on_enoent: do not exit with an error and delete all files when a device or directory does not exist. --- udev-remove.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/udev-remove.c b/udev-remove.c index e62d1fb122..dcd460bedc 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -51,6 +51,8 @@ static int delete_path(char *path) /* remove if empty */ retval = rmdir(path); + if (errno == ENOENT) + retval = 0; if (retval) { if (errno == ENOTEMPTY) return 0; @@ -77,6 +79,8 @@ static int delete_node(struct udevice *dev) info("removing device node '%s'", filename); retval = unlink(filename); + if (errno == ENOENT) + retval = 0; if (retval) { dbg("unlink(%s) failed with error '%s'", filename, strerror(errno)); @@ -109,6 +113,8 @@ static int delete_node(struct udevice *dev) dbg("unlinking symlink '%s'", filename); retval = unlink(filename); + if (errno == ENOENT) + retval = 0; if (retval) { dbg("unlink(%s) failed with error '%s'", filename, strerror(errno)); From 311e9ae68139083c801284a52f498c105d7c09f9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 1 Mar 2004 22:38:44 -0800 Subject: [PATCH 0601/4284] [PATCH] udev - man page update Here is a small change to the udev man page: - clarify the use of the NAME{all_partitions} syntax and add a example to udev.rules.example - mention the empty NAME field to ignore the device - prepare a SYMLINK field for the addition of Andrey's "multiple symlinks" documentation :) --- etc/udev/udev.rules.examples | 4 ++++ udev.8 | 23 ++++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/etc/udev/udev.rules.examples b/etc/udev/udev.rules.examples index 0d619e37e6..a464b6ba57 100644 --- a/etc/udev/udev.rules.examples +++ b/etc/udev/udev.rules.examples @@ -51,6 +51,10 @@ KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" # DRI devices always go into a subdirectory (as per the LSB spec) KERNEL="card*", NAME="dri/card%n" +# create all 15 partitions of a USB flash card reader +# note the trailing spaces in the attribute, use udevinfo(8) to examine your device +BUS="scsi", SYSFS{model}="CF/MD ", NAME{all_partitions}="compactflash" + # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" KERNEL="hw[CD0-9]*", NAME="snd/%k" diff --git a/udev.8 b/udev.8 index 21ec908b82..9eeff96d48 100644 --- a/udev.8 +++ b/udev.8 @@ -151,16 +151,15 @@ file. Every line in the rules file defines the mapping between device attributes and the device file name. One ore more keys are specified to match a rule with the current device. If all keys are matching, the rule will be applied -and the name is used for the device node. One or more optional symlinks -targeting the node may be specified. +and the name is used for the device node. .br If no matching rule is found, the default kernel device name is used. .P -The line format is: +Every rule consists of a list a comma separated fields: .sp -.I key,[key,...] name [, symlink] +.IR "key " ,[ "key " ,...] " name " [, " symlink" ] .sp -where keys are: +where possible fields are: .TP .B BUS Match the bus type of the device. @@ -196,13 +195,19 @@ Match the returned string of the last call. This key may used in any following rule after a .B PROGRAM call. -.P -The +.TP .B NAME -field given with the attribute +The name of the node to be created. If the name field is omitted or its +value is empty, the device will be ignored and no node will be created. +.br +If given with the attribute .BR NAME{ all_partitions } -will create all 15 partitions of a blockdevice. +it will create all 15 partitions of a blockdevice. This may be useful for removable media devices. +.TP +.B SYMLINK +The name of a symlink targeting the node. Multiple symlinks may be +specified by separating the names by the space character. .P .RB "The " NAME " ," SYMLINK " and " PROGRAM fields support simple printf-like string substitution: From 534c853df52810b63b126e7e43d051a682829464 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 1 Mar 2004 22:42:30 -0800 Subject: [PATCH 0602/4284] [PATCH] add $local user spport for permissions --- klibc_fixups.c | 37 +++++++++++++++++++++++++++++++++++++ klibc_fixups.h | 47 +++++++++++++++++++++++++++++++++++++++++++++-- udev-add.c | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/klibc_fixups.c b/klibc_fixups.c index 927f2f649a..1241eb7d10 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "klibc_fixups.h" @@ -32,6 +33,8 @@ #define PW_FILE "/etc/passwd" #define GR_FILE "/etc/group" +#define UTMP_FILE "/var/run/utmp" + /* return the id of a passwd style line, selected by the users name */ static unsigned long get_id_by_name(const char *uname, const char *dbfile) @@ -107,4 +110,38 @@ struct group *getgrnam(const char *name) return &gr; } + +int ufd = -1; + +void setutent() +{ + if (ufd < 0) + ufd = open(UTMP_FILE, O_RDONLY); + fcntl(ufd, F_SETFD, FD_CLOEXEC); + lseek(ufd, 0, SEEK_SET); +} + +void endutent() { + if (ufd < 0) + return; + close(ufd); + ufd = -1; +} + +struct utmp *getutent(void) +{ + static struct utmp utmp; + int retval; + + if (ufd < 0) { + setutent(); + if (ufd < 0) + return NULL; + } + retval = read(ufd, &utmp, sizeof(struct utmp)); + if (retval < 1) + return NULL; + return &utmp; +} + #endif diff --git a/klibc_fixups.h b/klibc_fixups.h index 19bfd51caa..f6c91cdd94 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -1,7 +1,7 @@ #ifdef __KLIBC__ #ifndef KLIBC_FIXUPS_H -#define KLIBC_FIXUPS_H +#define KLIBC_FIXUPS_H struct passwd { char *pw_name; /* user name */ @@ -23,6 +23,49 @@ struct group { struct passwd *getpwnam(const char *name); struct group *getgrnam(const char *name); -#endif +#define UT_LINESIZE 32 +#define UT_NAMESIZE 32 +#define UT_HOSTSIZE 256 +#define USER_PROCESS 7 /* normal process */ +#define ut_time ut_tv.tv_sec + + +extern int ufd; + +struct exit_status { + short int e_termination; /* process termination status */ + short int e_exit; /* process exit status */ +}; + +struct utmp +{ + short int ut_type; /* type of login */ + pid_t ut_pid; /* pid of login process */ + char ut_line[UT_LINESIZE]; /* devicename */ + char ut_id[4]; /* Inittab id */ + char ut_user[UT_NAMESIZE]; /* username */ + char ut_host[UT_HOSTSIZE]; /* hostname for remote login */ + struct exit_status ut_exit; /* exit status of a process marked as DEAD_PROCESS */ + /* The ut_session and ut_tv fields must be the same size for 32 and 64-bit */ +#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 + int32_t ut_session; /* sid used for windowing */ + struct { + int32_t tv_sec; /* seconds */ + int32_t tv_usec; /* microseconds */ + } ut_tv; +#else + long int ut_session; + struct timeval ut_tv; #endif + int32_t ut_addr_v6[4]; /* internet address of remote host */ + char __unused[20]; /* reserved for future use */ +}; + +struct utmp *getutent(void); +void setutent(void); +void endutent(void); + + +#endif /* KLIBC_FIXUPS_H */ +#endif /* __KLIBC__ */ diff --git a/udev-add.c b/udev-add.c index 3a72c544b8..19196bec54 100644 --- a/udev-add.c +++ b/udev-add.c @@ -32,6 +32,7 @@ #include #ifndef __KLIBC__ #include +#include #endif #include "libsysfs/sysfs/libsysfs.h" @@ -44,6 +45,8 @@ #include "udevdb.h" #include "klibc_fixups.h" +#define LOCAL_USER "$local" + /* * Right now the major/minor of a device is stored in a file called * "dev" in sysfs. @@ -132,6 +135,37 @@ static int make_node(char *filename, int major, int minor, unsigned int mode, ui return 0; } +/* get the local logged in user */ +static void set_to_local_user(char *user) +{ + struct utmp *u; + time_t recent = 0; + + strnfieldcpy(user, default_owner_str, OWNER_SIZE); + setutent(); + while (1) { + u = getutent(); + if (u == NULL) + break; + + /* is this a user login ? */ + if (u->ut_type != USER_PROCESS) + continue; + + /* is this a local login ? */ + if (strcmp(u->ut_host, "")) + continue; + + if (u->ut_time > recent) { + recent = u->ut_time; + strfieldcpy(user, u->ut_user); + dbg("local user is '%s'", user); + break; + } + } + endutent(); +} + static int create_node(struct udevice *dev, int fake) { struct stat stats; @@ -175,6 +209,9 @@ static int create_node(struct udevice *dev, int fake) if (endptr[0] == '\0') uid = (uid_t) id; else { + if (strncmp(dev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0) + set_to_local_user(dev->owner); + struct passwd *pw = getpwnam(dev->owner); if (pw == NULL) dbg("specified user unknown '%s'", dev->owner); From cbd2ea21e4eac53bb95465c7808c723b787a709c Mon Sep 17 00:00:00 2001 From: "christophe.varoqui@free.fr" Date: Mon, 1 Mar 2004 23:08:47 -0800 Subject: [PATCH 0603/4284] [PATCH] multipath update --- extras/multipath/ChangeLog | 10 ++++++ extras/multipath/Makefile | 28 +++++++++++----- extras/multipath/devinfo.c | 2 +- extras/multipath/devmap_name.8 | 30 +++++++++++++++++ extras/multipath/main.c | 37 +++++++++------------ extras/multipath/main.h | 5 ++- extras/multipath/multipath.8 | 53 ++++++++++++++++++++++++++++++ extras/multipath/multipath.hotplug | 3 +- 8 files changed, 132 insertions(+), 36 deletions(-) create mode 100644 extras/multipath/devmap_name.8 create mode 100644 extras/multipath/multipath.8 diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog index 43aa497e51..a2863ec23e 100644 --- a/extras/multipath/ChangeLog +++ b/extras/multipath/ChangeLog @@ -1,3 +1,13 @@ +2004-02-21 multipath-018 + * From the Debian SID inclusion review (Philipp Matthias Hahn) + * use DESTDIR install prefix in the Makefile + * add man pages for devmap_name & multipath + * correct libsysfs.h includes + * fork the hotplug script in its own shell + * Sync with the kernel device mapper code as of 2.6.3-udm3 + ie. Remove the test interval parameter and its uses + * Remove superfluous scsi parameter passed from hotplug + * Add the man pages to the [un]install targets 2004-02-17 multipath-017 * remove the restrictive -f flag. Introduce a more generic "-m iopolicy" one. diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile index eeec25b893..ee7f60e472 100644 --- a/extras/multipath/Makefile +++ b/extras/multipath/Makefile @@ -10,8 +10,11 @@ bindir = ${exec_prefix}/sbin udevdir = ../.. klibcdir = $(udevdir)/klibc sysfsdir = $(udevdir)/libsysfs +mandir = /usr/share/man/man8 CC = gcc +GZIP = /bin/gzip -c + GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} KERNEL_DIR = /lib/modules/${shell uname -r}/build CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ @@ -45,26 +48,33 @@ all: recurse $(EXEC): $(OBJS) $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(SYSFSOBJS) $(DMOBJS) $(LIB) $(LIBGCC) strip $(EXEC) + $(GZIP) $(EXEC).8 > $(EXEC).8.gz devmap_name: devmap_name.o $(LD) -o devmap_name $(CRT0) devmap_name.o $(DMOBJS) $(LIB) $(LIBGCC) strip devmap_name + $(GZIP) devmap_name.8 > devmap_name.8.gz clean: - rm -f core *.o $(EXEC) devmap_name + rm -f core *.o $(EXEC) devmap_name *.gz $(MAKE) -C libdevmapper clean install: - install -d $(bindir) - install -m 755 $(EXEC) $(bindir)/ - install -m 755 devmap_name $(bindir)/ - install -d /etc/hotplug.d/scsi/ - install -m 755 multipath.hotplug /etc/hotplug.d/scsi/ + install -d $(DESTDIR)$(bindir) + install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + install -m 755 devmap_name $(DESTDIR)$(bindir)/ + install -d $(DESTDIR)/etc/hotplug.d/scsi/ + install -m 755 multipath.hotplug $(DESTDIR)/etc/hotplug.d/scsi/ + install -d $(DESTDIR)$(mandir) + install -m 644 devmap_name.8.gz $(DESTDIR)$(mandir) + install -m 644 multipath.8.gz $(DESTDIR)$(mandir) uninstall: - rm /etc/hotplug.d/scsi/multipath.hotplug - rm $(bindir)/$(EXEC) - rm $(bindir)/devmap_name + rm $(DESTDIR)/etc/hotplug.d/scsi/multipath.hotplug + rm $(DESTDIR)$(bindir)/$(EXEC) + rm $(DESTDIR)$(bindir)/devmap_name + rm $(DESTDIR)$(mandir)/devmap_name.8.gz + rm $(DESTDIR)$(mandir)/multipath.8.gz # Code dependencies main.o: main.c main.h sg_include.h devinfo.h diff --git a/extras/multipath/devinfo.c b/extras/multipath/devinfo.c index a6b089f517..323da2f2f0 100644 --- a/extras/multipath/devinfo.c +++ b/extras/multipath/devinfo.c @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "devinfo.h" #include "sg_include.h" diff --git a/extras/multipath/devmap_name.8 b/extras/multipath/devmap_name.8 new file mode 100644 index 0000000000..f4f03c3ec6 --- /dev/null +++ b/extras/multipath/devmap_name.8 @@ -0,0 +1,30 @@ +.TH DEVMAP_NAME 8 "February 2004" "" "Linux Administrator's Manual" +.SH NAME +devmap_name \- Query device-mapper name +.SH SYNOPSIS +.BI devmap_name " major minor" +.SH DESCRIPTION +.B devmap_name +queries the device-mapper for the name for the device +specified by +.I major +and +.I minor +number. +.br +.B devmap_name +can be called from +.B udev +by the following rule in +.IR /etc/udev/udev.rules : +.sp +.nf +KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \\ + NAME="%k", SYMLINK="%c" +.fi +.SH "SEE ALSO" +.BR udev (8), +.BR dmsetup (8) +.SH AUTHORS +.B devmap_name +was developed by Christophe Varoqui, and others. diff --git a/extras/multipath/main.c b/extras/multipath/main.c index 706b2d1317..dfaa6867dd 100644 --- a/extras/multipath/main.c +++ b/extras/multipath/main.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "libdevmapper/libdevmapper.h" #include "main.h" #include "devinfo.h" @@ -110,7 +110,7 @@ get_all_paths_sysfs(struct env * conf, struct path * all_paths) char path[FILE_NAME_SIZE]; struct path curpath; - /* if called from hotplug, only consider the paths that relate to */ + /* if called from hotplug, only consider the paths that relate */ /* to the device pointed by conf.hotplugdev */ memset(empty_buff, 0, WWID_SIZE); memset(refwwid, 0, WWID_SIZE); @@ -442,6 +442,7 @@ group_by_serial(struct multipath * mp, struct path * all_paths, char * str) { path_count, path_buff); } sprintf(str, " %i%s", pg_count, pg_buff); + free(bitmap); } static int @@ -507,8 +508,6 @@ setup_map(struct env * conf, struct path * all_paths, if (np < 1) return 0; - params_p += sprintf(params_p, "%i", conf->dm_path_test_int); - if ((all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && conf->iopolicy == -1) || conf->iopolicy == MULTIBUS) { params_p += sprintf(params_p, " 1 %i %s %i %i", @@ -602,18 +601,19 @@ static void usage(char * progname) { fprintf(stderr, VERSION_STRING); - fprintf(stderr, "Usage: %s [-v|-q] [-d] [-i int] [-m max_devs] ", + fprintf(stderr, "Usage: %s [-v|-q] [-d] [-m max_devs]", progname); - fprintf(stderr, "[-p failover|multibus|group_by_serial]\n"); + fprintf(stderr, "[-p failover|multibus|group_by_serial] [device]\n"); fprintf(stderr, "\t-v\t\tverbose, print all paths and multipaths\n"); fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); fprintf(stderr, "\t-d\t\tdry run, do not create or update devmaps\n"); - fprintf(stderr, "\t-i\t\tmultipath target param : polling interval\n"); fprintf(stderr, "\t-m max_devs\tscan {max_devs} devices at most\n"); fprintf(stderr, "\t-p policy\tforce maps to specified policy :\n"); - fprintf(stderr, "\t\t\tfailover\t1 path per priority group\n"); - fprintf(stderr, "\t\t\tmultibus\tall paths in 1 priority group\n"); - fprintf(stderr, "\t\t\tgroup_by_serial\t1 priority group per serial\n"); + fprintf(stderr, "\t failover\t\t- 1 path per priority group\n"); + fprintf(stderr, "\t multibus\t\t- all paths in 1 priority group\n"); + fprintf(stderr, "\t group_by_serial\t- 1 priority group per serial\n"); + fprintf(stderr, "\tdevice\t\tlimit scope to the device's multipath\n"); + fprintf(stderr, "\t\t\t(hotplug-style $DEVPATH reference)\n"); exit(1); } @@ -632,7 +632,6 @@ main(int argc, char *argv[]) conf.verbose = 0; /* 1 == Print all_paths and mp */ conf.quiet = 0; /* 1 == Do not even print devmaps */ conf.iopolicy = -1; /* Apply the defaults in get_unique_id() */ - conf.dm_path_test_int = 10; for (i = 1; i < argc; ++i) { if (0 == strcmp("-v", argv[i])) { @@ -649,25 +648,19 @@ main(int argc, char *argv[]) conf.quiet = 1; } else if (0 == strcmp("-d", argv[i])) conf.dry_run = 1; - else if (0 == strcmp("-i", argv[i])) - conf.dm_path_test_int = atoi(argv[++i]); - else if (0 == strcmp("-p", argv[i++])) { + else if (0 == strcmp("-p", argv[i])) { + i++; if (!strcmp(argv[i], "failover")) conf.iopolicy = FAILOVER; if (!strcmp(argv[i], "multibus")) conf.iopolicy = MULTIBUS; if (!strcmp(argv[i], "group_by_serial")) conf.iopolicy = GROUP_BY_SERIAL; - } else if (0 == strcmp("scsi", argv[i])) - strcpy(conf.hotplugdev, argv[++i]); - else if (*argv[i] == '-') { + } else if (*argv[i] == '-') { fprintf(stderr, "Unknown switch: %s\n", argv[i]); usage(argv[0]); - } else if (*argv[i] != '-') { - fprintf(stderr, "Unknown argument\n"); - usage(argv[0]); - } - + } else + strncpy(conf.hotplugdev, argv[i], FILE_NAME_SIZE); } /* dynamic allocations */ diff --git a/extras/multipath/main.h b/extras/multipath/main.h index e05555599f..cee99d2b88 100644 --- a/extras/multipath/main.h +++ b/extras/multipath/main.h @@ -102,7 +102,6 @@ struct env { int dry_run; int iopolicy; int with_sysfs; - int dm_path_test_int; char sysfs_path[FILE_NAME_SIZE]; char hotplugdev[FILE_NAME_SIZE]; }; @@ -110,8 +109,8 @@ struct env { /* Build version */ #define PROG "multipath" -#define VERSION_CODE 0x000010 -#define DATE_CODE 0x0C1503 +#define VERSION_CODE 0x000012 +#define DATE_CODE 0x021504 #define MULTIPATH_VERSION(version) \ (version >> 16) & 0xFF, \ diff --git a/extras/multipath/multipath.8 b/extras/multipath/multipath.8 new file mode 100644 index 0000000000..98746424b4 --- /dev/null +++ b/extras/multipath/multipath.8 @@ -0,0 +1,53 @@ +.TH MULTIPATH 8 "February 2004" "" "Linux Administrator's Manual" +.SH NAME +multipath \- Device mapper target autoconfig +.SH SYNOPSIS +.B multipath +.RB [\| \-v | \-q \|] +.RB [\| \-d \|] +.RB [\| \-m\ \c +.IR max_devs \|] +.RB [\| \-p\ \c +.BR failover | multibus | group_by_serial \|] +.RB [\| device \|] +.SH DESCRIPTION +.B multipath +is used to detect multiple paths to devices for fail-over or performance reasons and coalesces them. +.SH OPTIONS +.TP +.B \-v +verbose, print all paths and multipaths +.TP +.B \-q +quiet, no output at all +.TP +.B \-d +dry run, do not create or update devmaps +.TP +.BI \-m " max_devs" +scan +.I max_devs +devices at most +.TP +.BI \-p " policy" +force maps to specified policy: +.RS 1.2i +.TP 1.2i +.B failover +1 path per priority group +.TP +.B multibus +all paths in 1 priority group +.TP +.B group_by_serial +1 priority group per serial +.RE +.TP +.B device +limit the [re]configuration to the specified device's multipath scope. device is given in its hotplug $DEVPATH form like /devices/pci0000:03/0000:03:01.0/host0/0:0:5:1 +.SH "SEE ALSO" +.BR udev (8), +.BR dmsetup (8) +.SH AUTHORS +.B multipath +was developed by Christophe Varoqui, and others. diff --git a/extras/multipath/multipath.hotplug b/extras/multipath/multipath.hotplug index 9bab619826..9f44f86c9b 100644 --- a/extras/multipath/multipath.hotplug +++ b/extras/multipath/multipath.hotplug @@ -1,6 +1,7 @@ +#!bin/sh . /etc/hotplug/hotplug.functions # wait for sysfs sleep 1 -mesg `/sbin/multipath scsi $DEVPATH` +mesg `/sbin/multipath $DEVPATH` From a6f01502bd2a76d1f9d90abb7bbeebd8f6893ed9 Mon Sep 17 00:00:00 2001 From: "rml@ximian.com" Date: Mon, 1 Mar 2004 23:16:39 -0800 Subject: [PATCH 0604/4284] [PATCH] update documetation for $local On Mon, 2004-03-01 at 17:44, Greg KH wrote: > Hm, that should be Robert's job actually, he should do something for > real... :) Hey, I wrote the nifty local user detection snippet - but, I owe Kay, so here is an updated man page. --- udev.8 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/udev.8 b/udev.8 index 9eeff96d48..c0dc68b803 100644 --- a/udev.8 +++ b/udev.8 @@ -297,6 +297,17 @@ video*:root:video:0660 dsp1:::0666 .fi .P +The value +.I $local +can be substituted for a specific username. In that case, udev will determine +the current local user at the time of device node creation and substitute +that username as the owner of the new device node. This is useful, for +example, to let hot-plugged devices, such as cameras, be owned by the user at +the current console. Note that if no user is currently logged in, or if udev +otherwise fails to determine a current user, the +.I default_owner +value is used in lieu. +.P A number of different fields in the above configuration files support a simple form of shell style pattern matching. It supports the following pattern characters: .TP From aebef544cb4417bcf1dbc6d9d0ad795e5525e41c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 1 Mar 2004 23:17:59 -0800 Subject: [PATCH 0605/4284] [PATCH] fix stroul endptr use The endptr is never NULL, so here we hopefully do the right thing. --- klibc_fixups.c | 2 +- namedev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/klibc_fixups.c b/klibc_fixups.c index 1241eb7d10..99460c32f7 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -74,7 +74,7 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) if (strcmp(uname, name) == 0) { id = strtoul(idstr, &tail, 10); - if (tail == NULL) + if (tail[0] != '\0') id = -1; else dbg("id for '%s' is '%li'", name, id); diff --git a/namedev.c b/namedev.c index 2ebf276f6b..ed8d6c1808 100644 --- a/namedev.c +++ b/namedev.c @@ -198,7 +198,7 @@ static int get_format_len(char **str) if (isdigit(*str[0])) { num = (int) strtoul(*str, &tail, 10); - if (tail != NULL) { + if (num > 0) { *str = tail; dbg("format length=%i", num); return num; From 97853b4f40708d2fdcde3da7e78138c683d9d66b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 1 Mar 2004 23:31:06 -0800 Subject: [PATCH 0606/4284] [PATCH] unlink the file before we try to create it. Based on the patch in the Gentoo repo. --- udev-add.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/udev-add.c b/udev-add.c index 19196bec54..776b542f08 100644 --- a/udev-add.c +++ b/udev-add.c @@ -166,9 +166,26 @@ static void set_to_local_user(char *user) endutent(); } -static int create_node(struct udevice *dev, int fake) +/* Used to unlink existing files to ensure that our new file/symlink is created */ +static int unlink_entry(char *filename) { struct stat stats; + int retval = 0; + + if (lstat(filename, &stats) == 0) { + if ((stats.st_mode & S_IFMT) != S_IFDIR) { + retval = unlink(filename); + if (retval) { + dbg("unlink(%s) failed with error '%s', " + filename, strerror(errno)); + } + } + } + return retval; +} + +static int create_node(struct udevice *dev, int fake) +{ char filename[255]; char linktarget[255]; char partitionname[255]; @@ -235,6 +252,7 @@ static int create_node(struct udevice *dev, int fake) } if (!fake) { + unlink_entry(filename); info("creating device node '%s'", filename); make_node(filename, dev->major, dev->minor, dev->mode, uid, gid); } else { @@ -250,6 +268,7 @@ static int create_node(struct udevice *dev, int fake) for (i = 1; i <= dev->partitions; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); + unlink_entry(partitionname); make_node(partitionname, dev->major, dev->minor + i, dev->mode, uid, gid); } @@ -291,14 +310,8 @@ static int create_node(struct udevice *dev, int fake) strfieldcat(linktarget, &dev->name[tail]); - /* unlink existing files to ensure that our symlink is created */ - if (!fake && (lstat(filename, &stats) == 0)) { - if ((stats.st_mode & S_IFMT) != S_IFDIR) { - if (unlink(filename)) - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - } - } + if (!fake) + unlink_entry(filename); dbg("symlink(%s, %s)", linktarget, filename); if (!fake) { From 8ea84a8a781c22f67def088eb9df581590393cda Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 1 Mar 2004 23:47:59 -0800 Subject: [PATCH 0607/4284] [PATCH] udevinfo symlink reverse query Thanks to Olaf Hering for this patch. It's possible now to feed the -n option of udevinfo with a symlink. I've also added a 'all' attribute, but no more text, it's all in the included man page :) --- udevdb.c | 21 +++++++++++++++++++-- udevinfo.8 | 4 ++-- udevinfo.c | 16 ++++++++++++++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/udevdb.c b/udevdb.c index a1f79a7c65..95bc06ce67 100644 --- a/udevdb.c +++ b/udevdb.c @@ -27,6 +27,7 @@ #define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include +#include #include #include #include @@ -178,13 +179,29 @@ static int find_found; static int find_device_by_name(char *path, struct udevice *dev) { + int l, i, j; if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { - memcpy(find_dev, dev, sizeof(*find_dev)); - strfieldcpy(find_path, path); + memcpy(find_dev, dev, sizeof(struct udevice)); + strnfieldcpy(find_path, path, NAME_SIZE); find_found = 1; /* stop search */ return 1; } + /* look for matching symlink*/ + l = strlen(dev->symlink); + if (!l) + return 0; + i = j = 0; + do { + j = strcspn(&dev->symlink[i], " "); + if (j && strncmp(&dev->symlink[i], find_name, j) == 0) { + memcpy(find_dev, dev, sizeof(struct udevice)); + strnfieldcpy(find_path, path, NAME_SIZE); + find_found = 1; + return 1; + } + i = i + j + 1; + } while (i < l); return 0; } diff --git a/udevinfo.8 b/udevinfo.8 index ad16ce6aed..528fa4ad95 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -28,13 +28,13 @@ Query the database for specified value of a created device node. .RB Needs " \-p " or " \-n " specified. .br Valid types are: -.BR name ", " symlink ", " mode " ," owner " , " group " or " path. +.BR name ", " symlink ", " mode " ," owner " , " group " , " path " or " all. .TP .BI \-p " sysfs_path" Specify the sysfs path of the device to query. .TP .BI \-n " name" -Specify the name of the node for the device to query. +Specify the name of the node or the symlink for the device to query. .TP .B \-a Print all diff --git a/udevinfo.c b/udevinfo.c index defed2ee31..01c2a2a8ae 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -122,7 +122,8 @@ enum query_type { SYMLINK, MODE, OWNER, - GROUP + GROUP, + ALL }; static int print_device_chain(const char *path) @@ -258,6 +259,11 @@ static int process_options(void) break; } + if (strcmp(optarg, "all") == 0) { + query = ALL; + break; + } + printf("unknown query type\n"); exit(1); @@ -366,6 +372,10 @@ print: strfieldcpy(result, path); break; + case ALL: + print_record(path, &dev); + goto exit; + default: goto exit; } @@ -406,8 +416,10 @@ help: " 'owner' of node\n" " 'group' of node\n" " 'path' sysfs device path\n" + " 'all' all values\n" + "\n" " -p PATH sysfs device path used for query or chain\n" - " -n NAME node name used for query\n" + " -n NAME node/symlink name used for query\n" "\n" " -r print udev root\n" " -a print all SYSFS_attributes along the device chain\n" From dba8c18b8b7b5f4c6d79593df8179c02a78d020f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 00:08:28 -0800 Subject: [PATCH 0608/4284] [PATCH] clarify udevinfo device walk It seems that the long attribute list can confuse the user. Se here we print a few words on top the attributes. --- udevinfo.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/udevinfo.c b/udevinfo.c index 01c2a2a8ae..b15f174e40 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -149,7 +149,14 @@ static int print_device_chain(const char *path) retval = -1; goto exit; } - printf("\ndevice '%s' has major:minor %s", class_dev->path, attr->value); + + printf("\nudevinfo starts with the device the node belongs to and then walks up the\n" + "device chain to print for every device found all possibly useful attributes\n" + "in the udev key format.\n" + "Only attributes within one device section may be used in a rule to match the\n" + "device for which the node will be created.\n" + "\n"); + printf("device '%s' has major:minor %s", class_dev->path, attr->value); sysfs_close_attribute(attr); /* open sysfs class device directory and print all attributes */ From 5202dc99915de8fd858a75ccd0a51edc182f39ee Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 00:09:27 -0800 Subject: [PATCH 0609/4284] [PATCH] TODO update I promise, that I will not take every item you put in the TODO list :) --- TODO | 1 - 1 file changed, 1 deletion(-) diff --git a/TODO b/TODO index fb94135426..2239d7b024 100644 --- a/TODO +++ b/TODO @@ -7,7 +7,6 @@ greg@kroah.com - more documentation (can never have too much.) -- create way to set permission to the local user. - install the proper init.d script based on the distro we are running on. - persuade the distro packagers to submit their changes (or just steal them if we can find them...) From dc820c1bc191db59f587660342285b2418e5ee74 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 00:21:27 -0800 Subject: [PATCH 0610/4284] [PATCH] - unlink bugfix Fix for recent unlink patch. --- udev-add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev-add.c b/udev-add.c index 776b542f08..c13cce53d4 100644 --- a/udev-add.c +++ b/udev-add.c @@ -176,7 +176,7 @@ static int unlink_entry(char *filename) if ((stats.st_mode & S_IFMT) != S_IFDIR) { retval = unlink(filename); if (retval) { - dbg("unlink(%s) failed with error '%s', " + dbg("unlink(%s) failed with error '%s'", filename, strerror(errno)); } } From 82b9a637827398a1deada3d91fee72cc700818ec Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 01:30:38 -0800 Subject: [PATCH 0611/4284] [PATCH] add udevstart program based on a old patch from Harald Hoyer This can be used instead of the start_udev script for systems that do not have a shell, or some other problem... --- Makefile | 10 ++- udevstart.c | 247 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 udevstart.c diff --git a/Makefile b/Makefile index c315d099ef..e2c7e42988 100644 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ DAEMON = udevd SENDER = udevsend HELPER = udevinfo TESTER = udevtest +STARTER = udevstart VERSION = 019_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -172,7 +173,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(SENDER) $(DAEMON) $(HELPER) $(TESTER) +all: $(ROOT) $(SENDER) $(DAEMON) $(HELPER) $(TESTER) $(STARTER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -265,6 +266,7 @@ $(TESTER).o: $(GEN_HEADERS) $(HELPER).o: $(GEN_HEADERS) $(DAEMON).o: $(GEN_HEADERS) $(SENDER).o: $(GEN_HEADERS) +$(STARTER).o: $(GEN_HEADERS) $(ROOT): $(ROOT).o $(OBJS) $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) @@ -286,10 +288,14 @@ $(SENDER): $(SENDER).o udevd.h $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ +$(STARTER): $(STARTER).o $(HEADERS) $(LIBC) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevstart.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $@ + clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(HELPER) $(DAEMON) $(SENDER) $(TESTER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(HELPER) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff --git a/udevstart.c b/udevstart.c new file mode 100644 index 0000000000..867919972a --- /dev/null +++ b/udevstart.c @@ -0,0 +1,247 @@ +/* + * udevstart.c + * + * Copyright (C) 2004 Greg Kroah-Hartman + * + * Quick and dirty way to populate a /dev with udev if your system + * does not have access to a shell. Based originally on a patch to udev + * from Harald Hoyer + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "logging.h" + + +#ifdef LOG +unsigned char logname[42]; +void log_message(int level, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif + + +#define MAX_PATHLEN 1024 +#define SYSBLOCK "/sys/block" +#define SYSCLASS "/sys/class" + +static int execute_udev(char *path, char *value, int len) +{ + int retval; + int res; + int status; + int fds[2]; + pid_t pid; + int value_set = 0; + char buffer[255]; + char *pos; + + retval = pipe(fds); + if (retval != 0) { + dbg("pipe failed"); + return -1; + } + pid = fork(); + switch(pid) { + case 0: + /* child */ + close(STDOUT_FILENO); + + /* dup write side of pipe to STDOUT */ + dup(fds[1]); + + dbg("executing /sbin/udev '%s'", path); + retval = execl("/sbin/udev", "/sbin/udev", path, NULL); + + info("execution of '%s' failed", path); + exit(1); + case -1: + dbg("fork failed"); + return -1; + default: + /* parent reads from fds[0] */ + close(fds[1]); + retval = 0; + while (1) { + res = read(fds[0], buffer, sizeof(buffer) - 1); + if (res <= 0) + break; + buffer[res] = '\0'; + if (res > len) { + dbg("result len %d too short", len); + retval = -1; + } + if (value_set) { + dbg("result value already set"); + retval = -1; + } else { + value_set = 1; + strncpy(value, buffer, len); + pos = value + strlen(value)-1; + if (pos[0] == '\n') + pos[0] = '\0'; + dbg("result is '%s'", value); + } + } + close(fds[0]); + res = wait(&status); + if (res < 0) { + dbg("wait failed result %d", res); + retval = -1; + } + + if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { + dbg("exec program status 0x%x", status); + retval = -1; + } + } + return retval; +} + +static int udev_scan(void) +{ + char *devpath; + DIR *dir; + struct dirent *dent; + int retval = -EINVAL; + char scratch[200]; + + devpath = "block"; + dir = opendir(SYSBLOCK); + if (dir) { + for (dent = readdir(dir); dent; dent = readdir(dir)) { + char dirname[MAX_PATHLEN]; + DIR *dir2; + struct dirent *dent2; + if ((strcmp(dent->d_name, ".") == 0) + || (strcmp(dent->d_name, "..") == 0)) + continue; + + snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name); + + setenv("DEVPATH", dirname, 1); + dbg("udev block, 'DEVPATH' = '%s'", dirname); + execute_udev("block", scratch, sizeof(scratch)); + + snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name); + + dir2 = opendir(dirname); + if (dir2) { + for (dent2 = readdir(dir2); dent2; dent2 = readdir(dir2)) { + char dirname2[MAX_PATHLEN]; + DIR *dir3; + struct dirent *dent3; + + if ((strcmp(dent2->d_name, ".") == 0) || + (strcmp(dent2->d_name, "..") == 0)) + continue; + + snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); + + dir3 = opendir(dirname2); + if (dir3) { + for (dent3 = readdir(dir3); dent3; dent3 = readdir(dir3)) { + char filename[MAX_PATHLEN]; + + if (strcmp(dent3->d_name, "dev") == 0) { + snprintf(filename, MAX_PATHLEN, "/block/%s/%s", dent->d_name, dent2->d_name); + setenv("DEVPATH", filename, 1); + dbg("udev block, 'DEVPATH' = '%s'", filename); + execute_udev("block", scratch, sizeof(scratch)); + } + } + } + } + } + } + } + + devpath = "class"; + dir = opendir(SYSCLASS); + if (dir) { + for (dent = readdir(dir); dent; dent = readdir(dir)) { + char dirname[MAX_PATHLEN]; + DIR *dir2; + struct dirent *dent2; + if ((strcmp(dent->d_name, ".") == 0) + || (strcmp(dent->d_name, "..") == 0)) + continue; + + snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); + + dir2 = opendir(dirname); + if (dir2) { + for (dent2 = readdir(dir2); dent2; dent2 = readdir(dir2)) { + char dirname2[MAX_PATHLEN]; + DIR *dir3; + struct dirent *dent3; + + if ((strcmp(dent2->d_name, ".") == 0) || (strcmp(dent2->d_name, "..") == 0)) + continue; + + snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); + + dir3 = opendir(dirname2); + if (dir3) { + for (dent3 = readdir(dir3); dent3; dent3 = readdir(dir3)) { + char + filename[MAX_PATHLEN]; + + if (strcmp(dent3->d_name, "dev") == 0) { + snprintf + (filename, + MAX_PATHLEN, + "/class/%s/%s", dent->d_name, dent2->d_name); + setenv("DEVPATH", filename, 1); + dbg("udev '%s', 'DEVPATH' = '%s'", dent->d_name, filename); + execute_udev(dent->d_name, scratch, sizeof(scratch)); + } + } + } + } + } + } + } + + if (retval > 0) + retval = 0; + + return -retval; +} + + +int main(int argc, char **argv, char **envp) +{ + init_logging("udevstart"); + + setenv("ACTION", "add", 1); + setenv("UDEV_NO_SLEEP", "1", 1); + + return udev_scan(); +} From c9043d4597692b5809a40a4aaa9d9b3bd7fadb35 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 20:21:03 -0800 Subject: [PATCH 0612/4284] [PATCH] Add Red Hat rules and permissions files Taken from udev-018-2.src.rpm from Fedora Devel. --- etc/udev/udev.permissions.redhat | 193 +++++++++++++++++++++++++++++++ etc/udev/udev.rules.redhat | 125 ++++++++++++++++++++ 2 files changed, 318 insertions(+) create mode 100644 etc/udev/udev.permissions.redhat create mode 100644 etc/udev/udev.rules.redhat diff --git a/etc/udev/udev.permissions.redhat b/etc/udev/udev.permissions.redhat new file mode 100644 index 0000000000..f73360e34c --- /dev/null +++ b/etc/udev/udev.permissions.redhat @@ -0,0 +1,193 @@ +# /etc/udev/udev.permissions: permission/ownership map for udev + +# console devices +console:root:root:0600 +tty[0-9][0-9]*:root:tty:0660 +vc/[0-9]*:root:tty:0660 + +# pty devices +# Set this to 0660 if you only want users belonging to tty group +# to be able to allocate PTYs +ptmx:root:tty:0666 +pty[p-za-e][0-9a-f]*:root:tty:0660 +tty[p-za-e][0-9a-f]*:root:tty:0660 +pty/m*:root:tty:0660 +vc/s*:root:tty:0660 + +# serial+dialup devices +ttyS*:root:uucp:0660 +ippp*:root:root:0660 +isdn*:root:root:0660 +isdnctrl*:root:root:0660 +capi*:root:root:0660 +dcbri*:root:root:0660 +ircomm*:root:uucp:0660 +ttyUSB*:root:uucp:0660 +tts/[0-9]*:root:uucp:0660 +tts/USB[0-9]*:root:uucp:0660 + +# vc devices +vcs:vcsa:tty:0600 +vcs[0-9]*:vcsa:tty:0600 +vcsa:vcsa:tty:0600 +vcsa[0-9]*:vcsa:tty:0600 +vcc/*:vcsa:tty:0600 + +# memory devices +random:root:root:0666 +urandom:root:root:0444 +mem:root:kmem:0640 +kmem:root:kmem:0640 +port:root:kmem:0640 +full:root:root:0666 +null:root:root:0666 +zero:root:root:0666 + +# misc devices +nvram:root:root:0660 +rtc:root:root:0660 + +# floppy devices +fd[01]*:root:floppy:0660 + +# audio devices +dsp*:root:root:0660 +audio*:root:root:0660 +midi*:root:root:0660 +mixer*:root:root:0660 +sequencer*:root:root:0660 +sound/*:root:root:0660 +snd/*:root:root:0660 +beep:root:root:0660 +admm*:root:root:0660 +adsp*:root:root:0660 +aload*:root:root:0660 +amidi*:root:root:0660 +dmfm*:root:root:0660 +dmmidi*:root:root:0660 +sndstat:root:root:0660 + +# optical devices +sr*:root:disk:660 +scd*:root:disk:660 +pcd*:root:disk:0660 +disk*:root:disk:0660 +dvd:root:disk:0660 +rdvd:root:disk:0660 +cdroms/*:root:disk:0660 + +# pilot/palm devices +pilot:root:uucp:0660 + +# jaz devices +jaz*:root:disk:0660 + +# zip devices +pocketzip*:root:disk:0660 +zip*:root:disk:0660 + +# ls120 devices +ls120:root:disk:0660 +ls120*:root:disk:0660 + +# lp devices +lp*:root:lp:0660 +parport*:root:lp:0660 +irlpt*:root:lp:0660 +usblp*:root:lp:0660 +usb/lp*:root:lp:0660 + +# scanner devices +scanner:root:root:0600 +usb/scanner*:root:root:0600 + +# camera devices +camera*:root:root:0600 +usb/dc2xx*:root:root:0600 +usb/mdc800*:root:root:0600 + +# raw devices +ram*:root:disk:660 +raw/*:root:disk:660 + +# disk devices +hd*:root:disk:660 +sd*:root:disk:660 +dasd*:root:disk:660 +ataraid*:root:disk:660 +loop*:root:disk:660 +md*:root:disk:660 +ide/*/*/*/*/*:root:disk:660 +discs/*/*:root:disk:660 +loop/*:root:disk:660 +md/*:root:disk:660 + +# tape devices +ht*:root:disk:0660 +nht*:root:disk:0660 +pt[0-9]*:root:disk:0660 +npt*:root:disk:0660 +st*:root:disk:0660 +nst*:root:disk:0660 + +# dm devices +dm-*:root:root:0640 + +# memstick devices +memstick*:root:root:0600 + +# flash devices +flash*:root:root:0600 + +# diskonkey devices +diskonkey*:root:disk:0660 + +# rem_ide devices +microdrive*:root:disk:0660 + +# fb devices +fb:root:root:0600 +fb[0-9]*:root:root:0600 +fb/*:root:root:0600 + +# kbd devices +kbd:root:root:0644 + +# joystick devices +js[0-9]*:root:root:0644 +djs[0-9]*:root:root:0644 + +# v4l devices +video*:root:root:0660 +radio*:root:root:0660 +winradio*:root:root:0660 +vtx*:root:root:0660 +vbi*:root:root:0660 +video/*:root:root:0660 +vttuner:root:root:0660 +v4l/*:root:root:0660 + +# input devices +input/*:root:root:644 + +# gpm devices +gpmctl:root:root:0700 + +# dri devices +nvidia*:root:root:0660 +3dfx*:root:root:0660 +dri/*:root:root:0660 + +# mainboard devices +apm_bios:root:root:0600 + +# scsi devices +sg*:root:disk:0660 +pg*:root:disk:0660 +cdwriter:root:disk:0660 + +# usb devices +usb/dabusb*:root:usb:0660 +usb/mdc800*:root:usb:0660 +usb/rio500:root:usb:0660 + diff --git a/etc/udev/udev.rules.redhat b/etc/udev/udev.rules.redhat new file mode 100644 index 0000000000..0a43358bad --- /dev/null +++ b/etc/udev/udev.rules.redhat @@ -0,0 +1,125 @@ +# /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. + +########################################################### +# +# Add your own rules here (examples are commented) +# +########################################################### + +# Looking for scsi bus id 42:0:0:1 +#BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" + +# A usb camera. +#BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" + +# USB Epson printer to be called lp_epson +#BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" + +# USB HP printer to be called lp_hp +#BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" + +# sound card with PCI bus id 00:0b.0 to be the first sound card +#BUS="pci", ID="00:0b.0", NAME="dsp" + +# sound card with PCI bus id 00:07.1 to be the second sound card +#BUS="pci", ID="00:07.1", NAME="dsp1" + +# USB mouse plugged into the third port of the first hub to be called mouse0 +#BUS="usb", PLACE="1.3", NAME="mouse0" + +# USB tablet plugged into the third port of the second hub to be called mouse1 +#BUS="usb", PLACE="2.3", NAME="mouse1" +#BUS="usb", PLACE="2.4", NAME="mouse2" + +# ttyUSB1 should always be called visor +#KERNEL="ttyUSB1", NAME="visor" +#KERNEL="ttyUSB0", NAME="pl2303" + + +########################################################### +# +# For devfs similar /dev layout (neater) +# +########################################################### + +# devfs-names for ide-devices (uncomment only one) +# /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" + +# 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" + +# dm devices (ignore them) +KERNEL="dm-[0-9]*", NAME="" +KERNEL="device-mapper", NAME="mapper/control" + +# fb devices +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" + +# floppy devices +KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k" + +# i2c devices +KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" + +# input devices +KERNEL="mice", NAME="input/mice" +KERNEL="mouse[0-9]*", NAME="input/mouse%n" +KERNEL="event[0-9]*", NAME="input/event%n" +KERNEL="js*", NAME="input/%k" +KERNEL="ts*", NAME="input/%k" + +# loop devices +KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" + +# md block devices +KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" + +# misc devices +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" + +# pty devices +KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" + +# ramdisk devices +KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" + +# sound devices +KERNEL="adsp", NAME="sound/adsp" SYMLINK="%k" +KERNEL="audio", NAME="sound/audio", SYMLINK="%k" +KERNEL="dsp", NAME="sound/dsp", SYMLINK="%k" +KERNEL="mixer", NAME="sound/mixer", SYMLINK="%k" +KERNEL="sequencer", NAME="sound/sequencer", SYMLINK="%k" +KERNEL="sequencer2", NAME="sound/sequencer2", SYMLINK="%k" + +# tty devices +KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" +KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" +KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" + +# vc devices +KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" +KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" +KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" +KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" + +# v4l devices +KERNEL="video[0-9]*", NAME="v4l/video%n" +KERNEL="radio[0-9]*", NAME="v4l/radio%n" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" + From 5ba7d3d603a63b7e2909c40a1e33d365024ba6b0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 20:23:36 -0800 Subject: [PATCH 0613/4284] [PATCH] update the Gentoo rules files. --- etc/udev/udev.rules.gentoo | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 0f871ca7ff..f8419a2925 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -1,5 +1,5 @@ # /etc/udev/udev.rules: device naming rules for udev -# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.rules.post_012,v 1.5 2004/02/08 16:59:29 azarah Exp $ +# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.rules-018,v 1.2 2004/02/29 11:07:39 azarah Exp $ # # 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. @@ -60,6 +60,9 @@ KERNEL="seq", NAME="snd/%k" # 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" # fb devices @@ -100,7 +103,7 @@ KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" # sound devices -KERNEL="adsp", NAME="sound/adsp" SYMLINK="%k" +KERNEL="adsp", NAME="sound/adsp", SYMLINK="%k" KERNEL="audio", NAME="sound/audio", SYMLINK="%k" KERNEL="dsp", NAME="sound/dsp", SYMLINK="%k" KERNEL="mixer", NAME="sound/mixer", SYMLINK="%k" From 2ef3bc2b7094876488c9ac30f64f135b6f88350a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 20:24:26 -0800 Subject: [PATCH 0614/4284] [PATCH] Remove Debian permission files as the Debian maintainer doesn't seem to want to share :( --- etc/udev/udev.permissions.debian | 111 ------------------------------- 1 file changed, 111 deletions(-) delete mode 100644 etc/udev/udev.permissions.debian diff --git a/etc/udev/udev.permissions.debian b/etc/udev/udev.permissions.debian deleted file mode 100644 index 5df3d0feac..0000000000 --- a/etc/udev/udev.permissions.debian +++ /dev/null @@ -1,111 +0,0 @@ -# name:user:group:mode - -# CHARACTER DEVICES - -# tty devices -tty:root:tty:0660 -console:root:tty:0600 -ptmx:root:tty:0666 -ttyACM*:root:dialout:0660 -ttyUSB*:root:dialout:0660 -ttyI*:root:dialout:0660 -ttyS*:root:dialout:0660 -ttySC*:root:dialout:0660 -ttyB*:root:dialout:0660 -ttyC*:root:dialout:0660 -ttyD*:root:dialout:0660 -ttyE*:root:dialout:0660 -ttyH*:root:dialout:0660 -ttyI*:root:dialout:0660 -ttyL*:root:dialout:0660 -ttyM*:root:dialout:0660 -ttyP*:root:dialout:0660 -ttyR*:root:dialout:0660 -ttyV*:root:dialout:0660 -ttyW*:root:dialout:0660 -ttyX*:root:dialout:0660 -tts/*:root:dialout:0660 -ippp*:root:dialout:0660 -isdn*:root:dialout:0660 -isdnctrl*:root:dialout:0660 -capi*:root:dialout:0660 -dcbri*:root:dialout:0660 -ircomm*:root:dialout:0660 - -# Memory devices -random:root:root:0666 -urandom:root:root:0444 -mem:root:kmem:0640 -kmem:root:kmem:0640 -port:root:kmem:0640 -full:root:root:0666 -null:root:root:0666 -zero:root:root:0666 - -# Misc devices -nvram:root:root:0660 -rtc:root:root:0660 - -admmidi*:root:audio:660 -adsp*:root:audio:660 -aload*:root:audio:660 -amidi*:root:audio:660 -amixer*:root:audio:660 -audio*:root:audio:660 -dmfm*:root:audio:660 -dsp*:root:audio:660 -audio*:root:audio:660 -mixer*:root:audio:660 -music:root:audio:660 -sequencer*:root:audio:660 -snd/*:root:audio:660 -sound/*:root:audio:660 - -lp*:root:lp:0660 -parport*:root:lp:0660 -irlpt*:root:lp:0660 -usblp*:root:lp:0660 -usb/lp*:root:lp:0660 - -js:root:root:644 -djs:root:root:644 -input/*:root:root:644 - -dri/card*:root:root:666 - -fb*:root:video:0620 -agpgart:root:video:0660 -video*:root:video:0660 -radio*:root:video:0660 -vbi*:root:video:0660 -vtx*:root:video:0660 -mol:root:root:0600 - - -# BLOCK DEVICES - -floppy*:root:floppy:660 -floppy/*:root:floppy:660 - -ram*:root:disk:660 -raw/*:root:disk:660 - -hd*:root:disk:660 -sd*:root:disk:660 -dasd*:root:disk:660 -ataraid*:root:disk:660 -loop*:root:disk:660 -md*:root:disk:660 - -sr*:root:cdrom:660 -scd*:root:cdrom:660 -sr*:root:cdrom:660 - -ht*:root:tape:0660 -nht*:root:tape:0660 -pt*:root:tape:0660 -npt*:root:tape:0660 -st*:root:tape:0660 -nst*:root:tape:0660 - -dm-*:root:root:0640 From 5ec4899acf4338fec32f8f8c218802a406319971 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 20:27:12 -0800 Subject: [PATCH 0615/4284] [PATCH] bugfix for local user While moving the local user logic in it's own function I missed to change the "secure" string macro. We copy only the first 3 bytes of the username. Guess why I didn't notice it :) --- udev-add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev-add.c b/udev-add.c index c13cce53d4..ed0286d1fc 100644 --- a/udev-add.c +++ b/udev-add.c @@ -158,7 +158,7 @@ static void set_to_local_user(char *user) if (u->ut_time > recent) { recent = u->ut_time; - strfieldcpy(user, u->ut_user); + strnfieldcpy(user, u->ut_user, OWNER_SIZE); dbg("local user is '%s'", user); break; } From c58f8c3000b99db5c3810b9f8b1ecc2044070ac1 Mon Sep 17 00:00:00 2001 From: "rml@ximian.com" Date: Tue, 2 Mar 2004 20:27:53 -0800 Subject: [PATCH 0616/4284] [PATCH] automatically install correct initscript On Mon, 2004-03-01 at 20:08, Robert Love wrote: > Ack, I did not even see that! Thanks. > > Let's rip that out, and always use the new built-in logic to determine > what initscript to install. Hm, looks like we do not need the %{lsb} and USE_LSB logic at all, anymore. Here is the patch, updated, removing both completely. --- Makefile | 17 ++++++++++------- TODO | 1 - udev.spec | 10 ---------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/Makefile b/Makefile index e2c7e42988..c3b33a7be1 100644 --- a/Makefile +++ b/Makefile @@ -347,6 +347,15 @@ uninstall-dbus-policy: - endif +install-initscript: etc/init.d/udev etc/init.d/udev.debian etc/init.d/udev.init.LSB + @if [ -f /etc/redhat-release ]; then \ + $(INSTALL_DATA) etc/init.d/udev $(etcdir)/init.d/udev; \ + elif [ -f /etc/SuSE-release ]; then \ + $(INSTALL_DATA) etc/init.d/udev.init.LSB $(etcdir)/init.d/udev; \ + elif [ -f /etc/debian_version ]; then \ + $(INSTALL_DATA) etc/init.d/udev.debian $(etcdir)/init.d/udev; \ + fi + install-config: $(GEN_CONFIGS) $(INSTALL) -d $(DESTDIR)$(configdir) @if [ ! -r $(DESTDIR)$(configdir)udev.conf ]; then \ @@ -362,7 +371,7 @@ install-config: $(GEN_CONFIGS) $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ fi -install: install-config install-dbus-policy all +install: install-initscript install-config install-dbus-policy all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) @@ -370,12 +379,6 @@ install: install-config install-dbus-policy all $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(HELPER) $(DESTDIR)$(sbindir)/$(HELPER) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(sbindir)/$(TESTER) - @if [ "x$(USE_LSB)" = "xtrue" ]; then \ - $(INSTALL_PROGRAM) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ - ln -s $(DESTDIR)$(initdir)/udev $(sbindir)/rcudev; \ - else \ - $(INSTALL_PROGRAM) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ - fi $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 diff --git a/TODO b/TODO index 2239d7b024..49a134effd 100644 --- a/TODO +++ b/TODO @@ -7,7 +7,6 @@ greg@kroah.com - more documentation (can never have too much.) -- install the proper init.d script based on the distro we are running on. - persuade the distro packagers to submit their changes (or just steal them if we can find them...) - create kernel name to devfs name config file so that all of the devfs users diff --git a/udev.spec b/udev.spec index ae802ca8e5..b9cf5b140e 100644 --- a/udev.spec +++ b/udev.spec @@ -27,11 +27,6 @@ # 1 - debugging enabled %define debug 0 -# if we want to use the LSB version of the init script or the Redhat one -# 0 - use Redhat: etc/init.d/udev -# 1 - use LSB: etc/init.d/udev.init.LSB -%define lsb 0 - # if we want to build the scsi_id "extra" package or not # 0 - do not build the package # 1 - build it @@ -99,11 +94,6 @@ make DESTDIR=$RPM_BUILD_ROOT install \ USE_SELINUX=true \ %else USE_SELINUX=false \ -%endif -%if %{lsb} - USE_LSB=true \ -%else - USE_LSB=false \ %endif EXTRAS=" \ %if %{scsi_id} From e4dc0e11c148df0e907ea23fd902324d856abcb1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 22:15:20 -0800 Subject: [PATCH 0617/4284] [PATCH] cleanup udevstart I just wanted to terminate the snprintf() strings, cause I can see a overflow with closed eyes after all the audit :) But then I changed a bit more to bring it in line with the style of the other files. I replaced the exec_udev() function with the one from udevd, cause we don't need to read the stdout from udev. Please have a look if it still works for you too and not only for usernames with 3 characters :) --- udevstart.c | 190 +++++++++++++++++++--------------------------------- 1 file changed, 69 insertions(+), 121 deletions(-) diff --git a/udevstart.c b/udevstart.c index 867919972a..5c977b5ce6 100644 --- a/udevstart.c +++ b/udevstart.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -47,133 +46,86 @@ void log_message(int level, const char *format, ...) #endif -#define MAX_PATHLEN 1024 -#define SYSBLOCK "/sys/block" -#define SYSCLASS "/sys/class" +#define MAX_PATHLEN 1024 +#define SYSBLOCK "/sys/block" +#define SYSCLASS "/sys/class" +#define UDEV_BIN "/sbin/udev" -static int execute_udev(char *path, char *value, int len) +static void udev_exec(const char *path, const char* subsystem) { - int retval; - int res; - int status; - int fds[2]; pid_t pid; - int value_set = 0; - char buffer[255]; - char *pos; + char action[] = "ACTION=add"; + char devpath[MAX_PATHLEN]; + char nosleep[] = "UDEV_NO_SLEEP=1"; + char *env[] = { action, devpath, nosleep, NULL }; + + snprintf(devpath, MAX_PATHLEN, "DEVPATH=%s", path); + devpath[MAX_PATHLEN-1] = '\0'; - retval = pipe(fds); - if (retval != 0) { - dbg("pipe failed"); - return -1; - } pid = fork(); - switch(pid) { + switch (pid) { case 0: /* child */ - close(STDOUT_FILENO); - - /* dup write side of pipe to STDOUT */ - dup(fds[1]); - - dbg("executing /sbin/udev '%s'", path); - retval = execl("/sbin/udev", "/sbin/udev", path, NULL); - - info("execution of '%s' failed", path); + execle(UDEV_BIN, "udev", subsystem, NULL, env); + dbg("exec of child failed"); exit(1); + break; case -1: - dbg("fork failed"); - return -1; + dbg("fork of child failed"); + break; default: - /* parent reads from fds[0] */ - close(fds[1]); - retval = 0; - while (1) { - res = read(fds[0], buffer, sizeof(buffer) - 1); - if (res <= 0) - break; - buffer[res] = '\0'; - if (res > len) { - dbg("result len %d too short", len); - retval = -1; - } - if (value_set) { - dbg("result value already set"); - retval = -1; - } else { - value_set = 1; - strncpy(value, buffer, len); - pos = value + strlen(value)-1; - if (pos[0] == '\n') - pos[0] = '\0'; - dbg("result is '%s'", value); - } - } - close(fds[0]); - res = wait(&status); - if (res < 0) { - dbg("wait failed result %d", res); - retval = -1; - } - - if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { - dbg("exec program status 0x%x", status); - retval = -1; - } + wait(NULL); } - return retval; } static int udev_scan(void) { - char *devpath; - DIR *dir; - struct dirent *dent; - int retval = -EINVAL; - char scratch[200]; + char *devpath; + DIR *dir; + struct dirent *dent; + int retval = -EINVAL; devpath = "block"; dir = opendir(SYSBLOCK); - if (dir) { - for (dent = readdir(dir); dent; dent = readdir(dir)) { - char dirname[MAX_PATHLEN]; - DIR *dir2; - struct dirent *dent2; - if ((strcmp(dent->d_name, ".") == 0) - || (strcmp(dent->d_name, "..") == 0)) + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[MAX_PATHLEN]; + DIR *dir2; + struct dirent *dent2; + + if ((strcmp(dent->d_name, ".") == 0) || + (strcmp(dent->d_name, "..") == 0)) continue; snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name); - - setenv("DEVPATH", dirname, 1); - dbg("udev block, 'DEVPATH' = '%s'", dirname); - execute_udev("block", scratch, sizeof(scratch)); + dirname[MAX_PATHLEN-1] = '\0'; + udev_exec(dirname, "block"); snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name); - dir2 = opendir(dirname); - if (dir2) { - for (dent2 = readdir(dir2); dent2; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN]; - DIR *dir3; - struct dirent *dent3; + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[MAX_PATHLEN]; + DIR *dir3; + struct dirent *dent3; if ((strcmp(dent2->d_name, ".") == 0) || (strcmp(dent2->d_name, "..") == 0)) continue; snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); + dirname2[MAX_PATHLEN-1] = '\0'; dir3 = opendir(dirname2); - if (dir3) { - for (dent3 = readdir(dir3); dent3; dent3 = readdir(dir3)) { + if (dir3 != NULL) { + for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { char filename[MAX_PATHLEN]; if (strcmp(dent3->d_name, "dev") == 0) { - snprintf(filename, MAX_PATHLEN, "/block/%s/%s", dent->d_name, dent2->d_name); - setenv("DEVPATH", filename, 1); - dbg("udev block, 'DEVPATH' = '%s'", filename); - execute_udev("block", scratch, sizeof(scratch)); + snprintf(filename, MAX_PATHLEN, "/block/%s/%s", + dent->d_name, dent2->d_name); + filename[MAX_PATHLEN-1] = '\0'; + udev_exec(filename, "block"); } } } @@ -184,43 +136,42 @@ static int udev_scan(void) devpath = "class"; dir = opendir(SYSCLASS); - if (dir) { - for (dent = readdir(dir); dent; dent = readdir(dir)) { - char dirname[MAX_PATHLEN]; - DIR *dir2; - struct dirent *dent2; - if ((strcmp(dent->d_name, ".") == 0) - || (strcmp(dent->d_name, "..") == 0)) + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[MAX_PATHLEN]; + DIR *dir2; + struct dirent *dent2; + + if ((strcmp(dent->d_name, ".") == 0) || + (strcmp(dent->d_name, "..") == 0)) continue; snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); - + dirname[MAX_PATHLEN] = '\0'; dir2 = opendir(dirname); - if (dir2) { - for (dent2 = readdir(dir2); dent2; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN]; - DIR *dir3; - struct dirent *dent3; + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[MAX_PATHLEN-1]; + DIR *dir3; + struct dirent *dent3; - if ((strcmp(dent2->d_name, ".") == 0) || (strcmp(dent2->d_name, "..") == 0)) + if ((strcmp(dent2->d_name, ".") == 0) || + (strcmp(dent2->d_name, "..") == 0)) continue; snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); + dirname2[MAX_PATHLEN-1] = '\0'; dir3 = opendir(dirname2); - if (dir3) { - for (dent3 = readdir(dir3); dent3; dent3 = readdir(dir3)) { - char - filename[MAX_PATHLEN]; + if (dir3 != NULL) { + for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { + char filename[MAX_PATHLEN]; if (strcmp(dent3->d_name, "dev") == 0) { - snprintf - (filename, - MAX_PATHLEN, - "/class/%s/%s", dent->d_name, dent2->d_name); - setenv("DEVPATH", filename, 1); - dbg("udev '%s', 'DEVPATH' = '%s'", dent->d_name, filename); - execute_udev(dent->d_name, scratch, sizeof(scratch)); + snprintf(filename, MAX_PATHLEN, "/class/%s/%s", + dent->d_name, dent2->d_name); + filename[MAX_PATHLEN-1] = '\0'; + udev_exec(filename, dent->d_name); } } } @@ -240,8 +191,5 @@ int main(int argc, char **argv, char **envp) { init_logging("udevstart"); - setenv("ACTION", "add", 1); - setenv("UDEV_NO_SLEEP", "1", 1); - return udev_scan(); } From 1f63fbdd30b6a26e9197fab15147356c7040cbf9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 22:34:40 -0800 Subject: [PATCH 0618/4284] [PATCH] install udevstart --- Makefile | 1 + udev.spec | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/Makefile b/Makefile index c3b33a7be1..e423630695 100644 --- a/Makefile +++ b/Makefile @@ -379,6 +379,7 @@ install: install-initscript install-config install-dbus-policy all $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(HELPER) $(DESTDIR)$(sbindir)/$(HELPER) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(sbindir)/$(TESTER) + $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 diff --git a/udev.spec b/udev.spec index b9cf5b140e..49b8b131da 100644 --- a/udev.spec +++ b/udev.spec @@ -120,6 +120,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /sbin/udevsend %attr(755,root,root) /sbin/udevd %attr(755,root,root) /sbin/udevtest +%attr(755,root,root) /sbin/udevstart %attr(755,root,root) %dir /udev/ %attr(755,root,root) %dir /etc/udev/ %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf @@ -140,6 +141,9 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Tue Mar 2 2004 Greg Kroah-Hartman +- added udevstart to the list of files installed + * Fri Feb 27 2004 Greg Kroah-Hartman - added ability to build with SELinux support From b5e0fc320850b7f04608e8e57f43f7ffbdd050a1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 22:43:00 -0800 Subject: [PATCH 0619/4284] [PATCH] man page udevstart --- Makefile | 1 + udevstart.8 | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 udevstart.8 diff --git a/Makefile b/Makefile index e423630695..049b278d4b 100644 --- a/Makefile +++ b/Makefile @@ -382,6 +382,7 @@ install: install-initscript install-config install-dbus-policy all $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 + $(INSTALL_DATA) -D udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug diff --git a/udevstart.8 b/udevstart.8 new file mode 100644 index 0000000000..3e6c61f547 --- /dev/null +++ b/udevstart.8 @@ -0,0 +1,18 @@ +.TH UDEVSTART 8 "March 2004" "" "Linux Administrator's Manual" +.SH NAME +udevstart \- populate device directory with all nodes available in sysfs +.SH SYNOPSIS +.B udevstart +.SH "DESCRIPTION" +.B udevstart +walks trough the sysfs device tree and calls +.B udev +to create the node for every valid device found. It can be used to fill a +empty device directory with nodes for all devices currently available on +the system. +.SH "SEE ALSO" +.BR udev (8) +.SH AUTHORS +.B udevstart +was developed primarily by Harald Hoyer , with much help +from others. From 27abdb46ffb0d817888a75adeaf2c0a2e7d2c7a3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 22:45:22 -0800 Subject: [PATCH 0620/4284] [PATCH] make start_udev use udevstart binary --- extras/start_udev | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/extras/start_udev b/extras/start_udev index 5a7bc63515..0212d4f8c1 100644 --- a/extras/start_udev +++ b/extras/start_udev @@ -88,7 +88,12 @@ mount -n -t ramfs none $udev_root export ACTION=add export UDEV_NO_SLEEP=1 echo "Creating initial udev device nodes:" -run_udev + +# You can use the shell scripts above by calling run_udev or execute udevstart +# which does the same thing, but much faster by not using shell. +# only comment out one of the following lines. +#run_udev +/sbin/udevstart echo "making extra nodes" make_extra_nodes From 43f46b560584b03e281660541373ff97d6406c99 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 22:46:24 -0800 Subject: [PATCH 0621/4284] [PATCH] update the TODO list as we already have a devfs config file. --- TODO | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TODO b/TODO index 49a134effd..63e518feeb 100644 --- a/TODO +++ b/TODO @@ -9,8 +9,6 @@ greg@kroah.com - more documentation (can never have too much.) - persuade the distro packagers to submit their changes (or just steal them if we can find them...) -- create kernel name to devfs name config file so that all of the devfs users - will have an upgrade path. - do early boot logic (putting udev into initramfs, handle pivot-root, etc.) -- lots of other stuff... +- solve world hunger From a8b41e072c01df8b3a31685e44dba145feaafc21 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 22:51:13 -0800 Subject: [PATCH 0622/4284] [PATCH] 020 release --- ChangeLog | 47 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a3cc00c17a..c8eedc3626 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 049b278d4b..45ff672be7 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ SENDER = udevsend HELPER = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 019_bk +VERSION = 020 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 49b8b131da..0778f93dc7 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 019_bk +Version: 020 Release: 1 License: GPL Group: Utilities/System From e729cb0b733390d4955d7f79cc5c7915dd1f41ce Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 22:54:00 -0800 Subject: [PATCH 0623/4284] [PATCH] make spec file turn off selinux support by default. --- udev.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index 0778f93dc7..9289a84e60 100644 --- a/udev.spec +++ b/udev.spec @@ -19,7 +19,7 @@ # if we want to build SELinux support in or not. # 0 - no SELinux support # 1 - SELinux support -%define selinux 1 +%define selinux 0 # if we want to enable debugging support in udev. If it is enabled, lots of # stuff will get sent to the debug syslog. From 789adb79f54b256bce97f05f5d8cbbc5ebbd057a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 23:33:52 -0800 Subject: [PATCH 0624/4284] [PATCH] fix the Makefile to install the init script into the proper directory grrr...robert... --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 45ff672be7..8f06c367c9 100644 --- a/Makefile +++ b/Makefile @@ -349,11 +349,11 @@ endif install-initscript: etc/init.d/udev etc/init.d/udev.debian etc/init.d/udev.init.LSB @if [ -f /etc/redhat-release ]; then \ - $(INSTALL_DATA) etc/init.d/udev $(etcdir)/init.d/udev; \ + $(INSTALL_DATA) etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ elif [ -f /etc/SuSE-release ]; then \ - $(INSTALL_DATA) etc/init.d/udev.init.LSB $(etcdir)/init.d/udev; \ + $(INSTALL_DATA) etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ elif [ -f /etc/debian_version ]; then \ - $(INSTALL_DATA) etc/init.d/udev.debian $(etcdir)/init.d/udev; \ + $(INSTALL_DATA) etc/init.d/udev.debian $(DESTDIR)$(initdir)/udev; \ fi install-config: $(GEN_CONFIGS) From dfe421a9654f5470b96fc6c6841a1f617c8a34f6 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 23:47:22 -0800 Subject: [PATCH 0625/4284] [PATCH] Fix another problem with Makefile installing initscript --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 8f06c367c9..99abff35ff 100644 --- a/Makefile +++ b/Makefile @@ -349,11 +349,11 @@ endif install-initscript: etc/init.d/udev etc/init.d/udev.debian etc/init.d/udev.init.LSB @if [ -f /etc/redhat-release ]; then \ - $(INSTALL_DATA) etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ + $(INSTALL_DATA) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ elif [ -f /etc/SuSE-release ]; then \ - $(INSTALL_DATA) etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ + $(INSTALL_DATA) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ elif [ -f /etc/debian_version ]; then \ - $(INSTALL_DATA) etc/init.d/udev.debian $(DESTDIR)$(initdir)/udev; \ + $(INSTALL_DATA) -D etc/init.d/udev.debian $(DESTDIR)$(initdir)/udev; \ fi install-config: $(GEN_CONFIGS) From e9f504e8d896e301099ffc1108a637e2842ee9ba Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 23:49:04 -0800 Subject: [PATCH 0626/4284] [PATCH] blacklist pcmcia_socket Is this something for the blacklist? /sys/class/pcmcia_socket/ |-- pcmcia_socket0 | |-- device -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.0 | `-- driver -> ../../../bus/pci/drivers/yenta_cardbus `-- pcmcia_socket1 |-- device -> ../../../devices/pci0000:00/0000:00:1e.0/0000:02:00.1 `-- driver -> ../../../bus/pci/drivers/yenta_cardbus --- udev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.c b/udev.c index 4ae4684536..227145982e 100644 --- a/udev.c +++ b/udev.c @@ -73,6 +73,7 @@ static char *subsystem_blacklist[] = { "scsi_device", "usb_host", "pci_bus", + "pcmcia_socket", "", }; From e56f005817ab12a63e91fee06c3f967d55ee6c3c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Mar 2004 23:49:08 -0800 Subject: [PATCH 0627/4284] [PATCH] install udevinfo in /usr/bin Here we rename the former tiny $(HELPER) to $(INFO) cause it's no longer only a helper :) And install it in /usr/bin instead of /sbin cause any user may want to call it and we don't need it on startup. --- Makefile | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 99abff35ff..9c95eeab85 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ USE_DBUS = false ROOT = udev DAEMON = udevd SENDER = udevsend -HELPER = udevinfo +INFO = udevinfo TESTER = udevtest STARTER = udevstart VERSION = 020 @@ -51,6 +51,7 @@ prefix = exec_prefix = ${prefix} etcdir = ${prefix}/etc sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin mandir = ${prefix}/usr/share/man hotplugdir = ${etcdir}/hotplug.d/default dbusdir = ${etcdir}/dbus-1/system.d @@ -173,7 +174,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(SENDER) $(DAEMON) $(HELPER) $(TESTER) $(STARTER) +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -263,7 +264,7 @@ $(LOCAL_CFG_DIR)/udev.conf: $(OBJS): $(GEN_HEADERS) $(ROOT).o: $(GEN_HEADERS) $(TESTER).o: $(GEN_HEADERS) -$(HELPER).o: $(GEN_HEADERS) +$(INFO).o: $(GEN_HEADERS) $(DAEMON).o: $(GEN_HEADERS) $(SENDER).o: $(GEN_HEADERS) $(STARTER).o: $(GEN_HEADERS) @@ -276,7 +277,7 @@ $(TESTER): $(TESTER).o $(OBJS) $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevtest.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(HELPER): $(HELPER).o $(OBJS) $(HEADERS) $(LIBC) +$(INFO): $(INFO).o $(OBJS) $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ @@ -295,7 +296,7 @@ $(STARTER): $(STARTER).o $(HEADERS) $(LIBC) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(HELPER) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ @@ -377,7 +378,7 @@ install: install-initscript install-config install-dbus-policy all $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) - $(INSTALL_PROGRAM) -D $(HELPER) $(DESTDIR)$(sbindir)/$(HELPER) + $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(sbindir)/$(TESTER) $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 @@ -407,7 +408,7 @@ uninstall: uninstall-dbus-policy - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) - - rm $(sbindir)/$(HELPER) + - rm $(usrbindir)/$(INFO) - rmdir $(hotplugdir) - rmdir $(configdir) - rm $(udevdir)/.udev.tdb From 0d1956de0eb112271a1d0d6e189ace3714bf0872 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 2 Mar 2004 23:51:50 -0800 Subject: [PATCH 0628/4284] [PATCH] fix udev.spec to find udevinfo now that it has moved to /usr/bin --- udev.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index 9289a84e60..9437491117 100644 --- a/udev.spec +++ b/udev.spec @@ -116,7 +116,7 @@ rm -rf $RPM_BUILD_ROOT %defattr(-,root,root) %doc COPYING README TODO ChangeLog HOWTO* etc/udev/udev.rules.examples docs/* %attr(755,root,root) /sbin/udev -%attr(755,root,root) /sbin/udevinfo +%attr(755,root,root) /usr/bin/udevinfo %attr(755,root,root) /sbin/udevsend %attr(755,root,root) /sbin/udevd %attr(755,root,root) /sbin/udevtest @@ -143,6 +143,7 @@ rm -rf $RPM_BUILD_ROOT %changelog * Tue Mar 2 2004 Greg Kroah-Hartman - added udevstart to the list of files installed +- udevinfo is now in /usr/bin not /sbin * Fri Feb 27 2004 Greg Kroah-Hartman - added ability to build with SELinux support From 88ed4bbe5605f6fe17993c5b81709f4d12812b9a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 3 Mar 2004 00:01:22 -0800 Subject: [PATCH 0629/4284] [PATCH] 021 release --- ChangeLog | 14 ++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8eedc3626..515450ac6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 9c95eeab85..526139a09b 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 020 +VERSION = 021 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 9437491117..9ead619186 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 020 +Version: 021 Release: 1 License: GPL Group: Utilities/System From 9fe3f9a9389bb06cf645d33cbb2b45e1f63d737c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 3 Mar 2004 18:16:35 -0800 Subject: [PATCH 0630/4284] [PATCH] cleanup mult field string handling Here I try to cleanup our various multifield iteration over the strings. Inspired by our nice list.h we now have a macro to iterate over the string and process the parts of it: It makes the code more readable and we don't change the string while we process it like the former strsep() does. Example: foreach_strpart(dev->symlink, " ", pos, len) { if (strncmp(&dev->symlink[pos], find_name, len) != 0) continue; ... } For the callout part selector %c{2} we separate now not only by space but also newline and return characters, cause some programs may give multiline values back. A possible RESULT match must contain wildcards for these characters. Also a bug in the recent udevinfo symlink query feature is fixed. --- namedev.c | 21 ++++++-------- udev-add.c | 78 ++++++++++++++++++++++++--------------------------- udev-remove.c | 44 +++++++++++++---------------- udev.h | 6 ++++ udevdb.c | 29 +++++++++---------- udevinfo.8 | 2 ++ 6 files changed, 85 insertions(+), 95 deletions(-) diff --git a/namedev.c b/namedev.c index ed8d6c1808..74d4d76467 100644 --- a/namedev.c +++ b/namedev.c @@ -214,14 +214,12 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_device *sysfs_device) { char temp[NAME_SIZE]; - char temp1[NAME_SIZE]; char *tail; char *pos; - char *pos2; - char *pos3; char *attr; int len; int i; + int spos, slen; char c; struct sysfs_attribute *tmpattr; @@ -278,20 +276,17 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, if (attr != NULL) i = atoi(attr); if (i > 0) { - strfieldcpy(temp1, udev->program_result); - pos2 = temp1; - while (i) { + foreach_strpart(udev->program_result, " \n\r", spos, slen) { i--; - pos3 = strsep(&pos2, " "); - if (pos3 == NULL) { - dbg("requested part of result string not found"); + if (i == 0) break; - } } - if (pos3) { - strnfieldcat(string, pos3, maxsize); - dbg("substitute part of result string '%s'", pos3); + if (i > 0) { + dbg("requested part of result string not found"); + break; } + strnfieldcat(string, udev->program_result + spos, slen+1); + dbg("substitute part of result string '%s'", pos); } else { strnfieldcat(string, udev->program_result, maxsize); dbg("substitute result string '%s'", udev->program_result); diff --git a/udev-add.c b/udev-add.c index ed0286d1fc..c28256a5a6 100644 --- a/udev-add.c +++ b/udev-add.c @@ -186,16 +186,16 @@ static int unlink_entry(char *filename) static int create_node(struct udevice *dev, int fake) { - char filename[255]; - char linktarget[255]; - char partitionname[255]; - char *linkname; - char *symlinks; + char filename[NAME_SIZE]; + char linkname[NAME_SIZE]; + char linktarget[NAME_SIZE]; + char partitionname[NAME_SIZE]; int retval = 0; uid_t uid = 0; gid_t gid = 0; int i; int tail; + int pos, len; strfieldcpy(filename, udev_root); strfieldcat(filename, dev->name); @@ -279,47 +279,41 @@ static int create_node(struct udevice *dev, int fake) selinux_add_node(filename); /* create symlink if requested */ - if (dev->symlink[0] != '\0') { - symlinks = dev->symlink; - while (1) { - linkname = strsep(&symlinks, " "); - if (linkname == NULL || linkname[0] == '\0') - break; + foreach_strpart(dev->symlink, " ", pos, len) { + strnfieldcpy(linkname, dev->symlink + pos, len+1); + strfieldcpy(filename, udev_root); + strfieldcat(filename, linkname); + dbg("symlink '%s' to node '%s' requested", filename, dev->name); + if (!fake) + if (strrchr(linkname, '/')) + create_path(filename); - strfieldcpy(filename, udev_root); - strfieldcat(filename, linkname); - dbg("symlink '%s' to node '%s' requested", filename, dev->name); - if (!fake) - if (strrchr(linkname, '/')) - create_path(filename); + /* optimize relative link */ + linktarget[0] = '\0'; + i = 0; + tail = 0; + while ((dev->name[i] == linkname[i]) && dev->name[i]) { + if (dev->name[i] == '/') + tail = i+1; + i++; + } + while (linkname[i] != '\0') { + if (linkname[i] == '/') + strfieldcat(linktarget, "../"); + i++; + } - /* optimize relative link */ - linktarget[0] = '\0'; - i = 0; - tail = 0; - while ((dev->name[i] == linkname[i]) && dev->name[i]) { - if (dev->name[i] == '/') - tail = i+1; - i++; - } - while (linkname[i] != '\0') { - if (linkname[i] == '/') - strfieldcat(linktarget, "../"); - i++; - } + strfieldcat(linktarget, &dev->name[tail]); - strfieldcat(linktarget, &dev->name[tail]); + if (!fake) + unlink_entry(filename); - if (!fake) - unlink_entry(filename); - - dbg("symlink(%s, %s)", linktarget, filename); - if (!fake) { - retval = symlink(linktarget, filename); - if (retval != 0) - dbg("symlink(%s, %s) failed with error '%s'", - linktarget, filename, strerror(errno)); - } + dbg("symlink(%s, %s)", linktarget, filename); + if (!fake) { + retval = symlink(linktarget, filename); + if (retval != 0) + dbg("symlink(%s, %s) failed with error '%s'", + linktarget, filename, strerror(errno)); } } diff --git a/udev-remove.c b/udev-remove.c index dcd460bedc..93adcc7806 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -67,12 +67,12 @@ static int delete_path(char *path) static int delete_node(struct udevice *dev) { - char filename[255]; - char partitionname[255]; - char *symlinks; - char *linkname; + char filename[NAME_SIZE]; + char linkname[NAME_SIZE]; + char partitionname[NAME_SIZE]; int retval; int i; + int pos, len; strfieldcpy(filename, udev_root); strfieldcat(filename, dev->name); @@ -101,28 +101,22 @@ static int delete_node(struct udevice *dev) if (strchr(dev->name, '/')) delete_path(filename); - if (dev->symlink[0] != '\0') { - symlinks = dev->symlink; - while (1) { - linkname = strsep(&symlinks, " "); - if (linkname == NULL) - break; + foreach_strpart(dev->symlink, " ", pos, len) { + strnfieldcpy(linkname, dev->symlink + pos, len+1); + strfieldcpy(filename, udev_root); + strfieldcat(filename, linkname); - strfieldcpy(filename, udev_root); - strfieldcat(filename, linkname); - - dbg("unlinking symlink '%s'", filename); - retval = unlink(filename); - if (errno == ENOENT) - retval = 0; - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - return retval; - } - if (strchr(dev->symlink, '/')) { - delete_path(filename); - } + dbg("unlinking symlink '%s'", filename); + retval = unlink(filename); + if (errno == ENOENT) + retval = 0; + if (retval) { + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + return retval; + } + if (strchr(dev->symlink, '/')) { + delete_path(filename); } } diff --git a/udev.h b/udev.h index 5737c84c9d..9327e90913 100644 --- a/udev.h +++ b/udev.h @@ -97,6 +97,12 @@ do { \ snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ } while (0) +#define foreach_strpart(str, separator, pos, len) \ + for(pos = 0, len = strcspn(str, separator); \ + (pos) < strlen(str); \ + pos = pos + (len) + 1, len = strcspn((str) + pos, separator)) \ + if (len > 0) + static inline char *get_action(void) { char *action; diff --git a/udevdb.c b/udevdb.c index 95bc06ce67..22d439d638 100644 --- a/udevdb.c +++ b/udevdb.c @@ -179,7 +179,8 @@ static int find_found; static int find_device_by_name(char *path, struct udevice *dev) { - int l, i, j; + int pos, len; + if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { memcpy(find_dev, dev, sizeof(struct udevice)); strnfieldcpy(find_path, path, NAME_SIZE); @@ -188,20 +189,18 @@ static int find_device_by_name(char *path, struct udevice *dev) return 1; } /* look for matching symlink*/ - l = strlen(dev->symlink); - if (!l) - return 0; - i = j = 0; - do { - j = strcspn(&dev->symlink[i], " "); - if (j && strncmp(&dev->symlink[i], find_name, j) == 0) { - memcpy(find_dev, dev, sizeof(struct udevice)); - strnfieldcpy(find_path, path, NAME_SIZE); - find_found = 1; - return 1; - } - i = i + j + 1; - } while (i < l); + foreach_strpart(dev->symlink, " ", pos, len) { + if (strncmp(&dev->symlink[pos], find_name, len) != 0) + continue; + + if (len != strlen(find_name)) + continue; + + memcpy(find_dev, dev, sizeof(struct udevice)); + strnfieldcpy(find_path, path, NAME_SIZE); + find_found = 1; + return 1; + } return 0; } diff --git a/udevinfo.8 b/udevinfo.8 index 528fa4ad95..e087e2d1ff 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -35,6 +35,8 @@ Specify the sysfs path of the device to query. .TP .BI \-n " name" Specify the name of the node or the symlink for the device to query. +Partition names generated with the NAME{all_partitons} option can not be +queried, the main device must be used instead. .TP .B \-a Print all From 5895eb31fe86619a9d9070e12bc0c970da9daf6b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 4 Mar 2004 00:51:28 -0800 Subject: [PATCH 0631/4284] [PATCH] fix the build for older versions of gcc --- udev-add.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/udev-add.c b/udev-add.c index c28256a5a6..9562cb5dbb 100644 --- a/udev-add.c +++ b/udev-add.c @@ -226,10 +226,11 @@ static int create_node(struct udevice *dev, int fake) if (endptr[0] == '\0') uid = (uid_t) id; else { + struct passwd *pw; if (strncmp(dev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0) set_to_local_user(dev->owner); - struct passwd *pw = getpwnam(dev->owner); + pw = getpwnam(dev->owner); if (pw == NULL) dbg("specified user unknown '%s'", dev->owner); else From e4f9c4a46de499841939c51da1a1cf6fd5321bb1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 4 Mar 2004 00:52:05 -0800 Subject: [PATCH 0632/4284] [PATCH] 021_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 526139a09b..e4c6184c95 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 021 +VERSION = 021_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 9ead619186..b7e429d077 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 021 +Version: 021_bk Release: 1 License: GPL Group: Utilities/System From 27c3403dd810e53f6c9b8dffe34af7798a4b52d3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 4 Mar 2004 00:54:13 -0800 Subject: [PATCH 0633/4284] [PATCH] fix NAME="foo-%c{N}" gets a truncated name On Wed, Mar 03, 2004 at 02:43:34PM -0800, Patrick Mansfield wrote: > Here is a fix and a new test for the problem Atul hit, where if we have a > NAME based on a result of the form: > > NAME="foo-%c{7}" > > udev truncates the name. Without any prefix (the foo- in this example), > the rule was working OK. Here is a fix for the fix :) Sorry, I broke it yesterday. --- namedev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 74d4d76467..e9b3babd56 100644 --- a/namedev.c +++ b/namedev.c @@ -214,6 +214,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_device *sysfs_device) { char temp[NAME_SIZE]; + char temp2[NAME_SIZE]; char *tail; char *pos; char *attr; @@ -277,6 +278,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, i = atoi(attr); if (i > 0) { foreach_strpart(udev->program_result, " \n\r", spos, slen) { + strnfieldcpy(temp2, udev->program_result + spos, slen+1); i--; if (i == 0) break; @@ -285,8 +287,8 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("requested part of result string not found"); break; } - strnfieldcat(string, udev->program_result + spos, slen+1); - dbg("substitute part of result string '%s'", pos); + strnfieldcat(string, temp2, maxsize); + dbg("substitute part of result string '%s'", temp2); } else { strnfieldcat(string, udev->program_result, maxsize); dbg("substitute result string '%s'", udev->program_result); From 56c963dc4d8a65a8f2f23ae329f2088fabbf3303 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Thu, 4 Mar 2004 00:55:22 -0800 Subject: [PATCH 0634/4284] [PATCH] add tests for NAME="foo-%c{N}" Here is a patch for some new tests. --- test/udev-test.pl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 6b7f515442..60cf16901c 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -259,6 +259,24 @@ EOF expected => "foo9" , conf => < "characters before the %c{N} substitution", + subsys => "block", + devpath => "block/sda/sda3", + expected => "my-foo9" , + conf => < "substitute the second to last argument", + subsys => "block", + devpath => "block/sda/sda3", + expected => "my-foo8" , + conf => < Date: Thu, 4 Mar 2004 00:57:29 -0800 Subject: [PATCH 0635/4284] [PATCH] overall trivial trivial cleanup Here I try to make the style a bit more consistant in the different files, so that new patches just copy the 'right' one :) Some "magic" numbers are replaced and udevtest.c is catched up with udev. --- logging.h | 6 ++++-- namedev_parse.c | 1 - udev.c | 6 +++--- udevd.c | 2 +- udevinfo.c | 2 +- udevsend.c | 2 +- udevstart.c | 4 ++-- udevtest.c | 41 ++++++++++------------------------------- 8 files changed, 22 insertions(+), 42 deletions(-) diff --git a/logging.h b/logging.h index 1c27917f61..40c342c3ab 100644 --- a/logging.h +++ b/logging.h @@ -34,6 +34,8 @@ #include #include +#define LOGNAME_SIZE 42 + #undef info #define info(format, arg...) \ do { \ @@ -61,12 +63,12 @@ extern void log_message(int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); /* each program that uses syslog must declare this variable somewhere */ -extern unsigned char logname[42]; +extern unsigned char logname[LOGNAME_SIZE]; #undef init_logging static inline void init_logging(char *program_name) { - snprintf(logname, 42,"%s[%d]", program_name, getpid()); + snprintf(logname, LOGNAME_SIZE,"%s[%d]", program_name, getpid()); openlog(logname, 0, LOG_DAEMON); } diff --git a/namedev_parse.c b/namedev_parse.c index 19acd96ef0..defb698b26 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -58,7 +58,6 @@ static int add_config_dev(struct config_device *new_dev) void dump_config_dev(struct config_device *dev) { - /*FIXME dump all sysfs's */ dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', " "sysfs_file[0]='%s', sysfs_value[0]='%s', " "kernel='%s', program='%s', result='%s'", diff --git a/udev.c b/udev.c index 227145982e..9b4d91f75c 100644 --- a/udev.c +++ b/udev.c @@ -40,7 +40,7 @@ char **main_argv; char **main_envp; #ifdef LOG -unsigned char logname[42]; +unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) { va_list args; @@ -74,7 +74,7 @@ static char *subsystem_blacklist[] = { "usb_host", "pci_bus", "pcmcia_socket", - "", + "" }; static int udev_hotplug(void) @@ -164,7 +164,7 @@ exit: return -retval; } -int main(int argc, char **argv, char **envp) +int main(int argc, char *argv[], char *envp[]) { main_argv = argv; main_envp = envp; diff --git a/udevd.c b/udevd.c index 2b3dc55788..efcb65bb53 100644 --- a/udevd.c +++ b/udevd.c @@ -52,7 +52,7 @@ static void exec_queue_manager(void); static void msg_queue_manager(void); #ifdef LOG -unsigned char logname[42]; +unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevinfo.c b/udevinfo.c index b15f174e40..3361837a37 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -41,7 +41,7 @@ char **main_argv; int main_argc; #ifdef LOG -unsigned char logname[42]; +unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevsend.c b/udevsend.c index 4b6ef5c2f3..11234808d9 100644 --- a/udevsend.c +++ b/udevsend.c @@ -41,7 +41,7 @@ #include "logging.h" #ifdef LOG -unsigned char logname[42]; +unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevstart.c b/udevstart.c index 5c977b5ce6..21fd93df74 100644 --- a/udevstart.c +++ b/udevstart.c @@ -34,7 +34,7 @@ #ifdef LOG -unsigned char logname[42]; +unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) { va_list args; @@ -187,7 +187,7 @@ static int udev_scan(void) } -int main(int argc, char **argv, char **envp) +int main(int argc, char *argv[], char *envp[]) { init_logging("udevstart"); diff --git a/udevtest.c b/udevtest.c index 4bc094fd90..e67d452577 100644 --- a/udevtest.c +++ b/udevtest.c @@ -38,15 +38,11 @@ char **main_argv; char **main_envp; #ifdef LOG -unsigned char logname[42]; +unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { - va_list args; + va_list args; -// if (!udev_log) -// return; - - /* FIXME use level... */ va_start(args, format); vprintf(format, args); va_end(args); @@ -55,35 +51,24 @@ void log_message (int level, const char *format, ...) } #endif -static void sig_handler(int signum) -{ - switch (signum) { - case SIGINT: - case SIGTERM: - exit(20 + signum); - default: - dbg("unhandled signal"); - } -} - static char *subsystem_blacklist[] = { "net", "scsi_host", "scsi_device", "usb_host", "pci_bus", - "", + "pcmcia_socket", + "" }; -static int udev_hotplug(int argc, char **argv) +static int udev_hotplug(void) { char *devpath; char *subsystem; int retval = -EINVAL; int i; - struct sigaction act; - devpath = argv[1]; + devpath = main_argv[1]; if (!devpath) { dbg("no devpath?"); goto exit; @@ -98,7 +83,7 @@ static int udev_hotplug(int argc, char **argv) } /* skip blacklisted subsystems */ - subsystem = argv[1]; + subsystem = main_argv[1]; i = 0; while (subsystem_blacklist[i][0] != '\0') { if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { @@ -111,16 +96,10 @@ static int udev_hotplug(int argc, char **argv) /* initialize our configuration */ udev_init_config(); - /* set up a default signal handler for now */ - act.sa_handler = sig_handler; - sigemptyset (&act.sa_mask); - act.sa_flags = SA_RESTART; - sigaction(SIGINT, &act, NULL); - sigaction(SIGTERM, &act, NULL); - /* initialize the naming deamon */ namedev_init(); + /* simulate node creation with fake flag */ retval = udev_add_device(devpath, subsystem, 1); exit: @@ -130,14 +109,14 @@ exit: return -retval; } -int main(int argc, char **argv, char **envp) +int main(int argc, char *argv[], char *envp[]) { main_argv = argv; main_envp = envp; dbg("version %s", UDEV_VERSION); - return udev_hotplug(argc, argv); + return udev_hotplug(); } From a3fa7908e25bda3fc8627c7a91878a7825f9391f Mon Sep 17 00:00:00 2001 From: "hannal@us.ibm.com" Date: Thu, 4 Mar 2004 01:17:08 -0800 Subject: [PATCH 0636/4284] [PATCH] Small fix to remove extra "will" in man page remove extraneous word. --- udev.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.8 b/udev.8 index c0dc68b803..bc7308f484 100644 --- a/udev.8 +++ b/udev.8 @@ -25,7 +25,7 @@ The default behavior of .B udev is to wait until all the sysfs files of the device chain are populated. If set .B udev -will will continue, regardless of the state of the device representation. +will continue, regardless of the state of the device representation. .SH "DESCRIPTION" .B udev creates or removes device node files usually located in the /dev directory. From ef672b3dc450846d540cf1a0519fe273bbd62e5f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 4 Mar 2004 18:55:34 -0800 Subject: [PATCH 0637/4284] [PATCH] better fix for NAME="foo-%c{N}" gets a truncated name On Wed, Mar 03, 2004 at 04:56:34PM -0800, Greg KH wrote: > On Wed, Mar 03, 2004 at 03:57:04PM -0800, Patrick Mansfield wrote: > > > > Here is a patch for some new tests. > > Applied, thanks. Here is a small improvement, which looks much better. Hey Pat, thanks a lot for finding the recent bug, hope this one will not break it again :) --- namedev.c | 5 +++-- udev-add.c | 5 +++-- udev-remove.c | 5 +++-- udev.h | 6 +++--- udevdb.c | 5 +++-- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/namedev.c b/namedev.c index e9b3babd56..9182ed1fdc 100644 --- a/namedev.c +++ b/namedev.c @@ -220,8 +220,9 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, char *attr; int len; int i; - int spos, slen; char c; + char *spos; + int slen; struct sysfs_attribute *tmpattr; pos = string; @@ -278,7 +279,6 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, i = atoi(attr); if (i > 0) { foreach_strpart(udev->program_result, " \n\r", spos, slen) { - strnfieldcpy(temp2, udev->program_result + spos, slen+1); i--; if (i == 0) break; @@ -287,6 +287,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("requested part of result string not found"); break; } + strnfieldcpy(temp2, spos, slen+1); strnfieldcat(string, temp2, maxsize); dbg("substitute part of result string '%s'", temp2); } else { diff --git a/udev-add.c b/udev-add.c index 9562cb5dbb..de1fb953c4 100644 --- a/udev-add.c +++ b/udev-add.c @@ -195,7 +195,8 @@ static int create_node(struct udevice *dev, int fake) gid_t gid = 0; int i; int tail; - int pos, len; + char *pos; + int len; strfieldcpy(filename, udev_root); strfieldcat(filename, dev->name); @@ -281,7 +282,7 @@ static int create_node(struct udevice *dev, int fake) /* create symlink if requested */ foreach_strpart(dev->symlink, " ", pos, len) { - strnfieldcpy(linkname, dev->symlink + pos, len+1); + strnfieldcpy(linkname, pos, len+1); strfieldcpy(filename, udev_root); strfieldcat(filename, linkname); dbg("symlink '%s' to node '%s' requested", filename, dev->name); diff --git a/udev-remove.c b/udev-remove.c index 93adcc7806..195b987411 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -72,7 +72,8 @@ static int delete_node(struct udevice *dev) char partitionname[NAME_SIZE]; int retval; int i; - int pos, len; + char *pos; + int len; strfieldcpy(filename, udev_root); strfieldcat(filename, dev->name); @@ -102,7 +103,7 @@ static int delete_node(struct udevice *dev) delete_path(filename); foreach_strpart(dev->symlink, " ", pos, len) { - strnfieldcpy(linkname, dev->symlink + pos, len+1); + strnfieldcpy(linkname, pos, len+1); strfieldcpy(filename, udev_root); strfieldcat(filename, linkname); diff --git a/udev.h b/udev.h index 9327e90913..32fda379e5 100644 --- a/udev.h +++ b/udev.h @@ -98,9 +98,9 @@ do { \ } while (0) #define foreach_strpart(str, separator, pos, len) \ - for(pos = 0, len = strcspn(str, separator); \ - (pos) < strlen(str); \ - pos = pos + (len) + 1, len = strcspn((str) + pos, separator)) \ + for(pos = str, len = 0; \ + (pos) < ((str) + strlen(str)); \ + pos = pos + len + strspn(pos, separator), len = strcspn(pos, separator)) \ if (len > 0) static inline char *get_action(void) diff --git a/udevdb.c b/udevdb.c index 22d439d638..b12f5b3d46 100644 --- a/udevdb.c +++ b/udevdb.c @@ -179,7 +179,8 @@ static int find_found; static int find_device_by_name(char *path, struct udevice *dev) { - int pos, len; + char *pos; + int len; if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { memcpy(find_dev, dev, sizeof(struct udevice)); @@ -190,7 +191,7 @@ static int find_device_by_name(char *path, struct udevice *dev) } /* look for matching symlink*/ foreach_strpart(dev->symlink, " ", pos, len) { - if (strncmp(&dev->symlink[pos], find_name, len) != 0) + if (strncmp(pos, find_name, len) != 0) continue; if (len != strlen(find_name)) From ebc39fefd5cb8249cd09d4b3d1b8c72c9e48bab1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 4 Mar 2004 18:58:02 -0800 Subject: [PATCH 0638/4284] [PATCH] clarify udevinfo text Make udevinfo attribute printing note so clear, that's nearly impossible to misunderstand it in the future. --- udevinfo.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index 3361837a37..ffc5e31f04 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -151,10 +151,10 @@ static int print_device_chain(const char *path) } printf("\nudevinfo starts with the device the node belongs to and then walks up the\n" - "device chain to print for every device found all possibly useful attributes\n" + "device chain, to print for every device found, all possibly useful attributes\n" "in the udev key format.\n" - "Only attributes within one device section may be used in a rule to match the\n" - "device for which the node will be created.\n" + "Only attributes within one device section may be used together in one rule,\n" + "to match the device for which the node will be created.\n" "\n"); printf("device '%s' has major:minor %s", class_dev->path, attr->value); sysfs_close_attribute(attr); From d5f91372dd3241f8b4bbe2a99aaaeda541a76bad Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 4 Mar 2004 18:59:13 -0800 Subject: [PATCH 0639/4284] [PATCH] conditional remove of trailing sysfs whitespace Hey, it may never happen, that one wants to distinguish attributes by trailing spaces, but we should not lose the control over it, just for being lazy :) Here we remove the trailing spaces of the sysfs attribute only if the configured value to match doesn't have any trailing spaces by itself. So if you put a attribute in a rule with spaces at the end, the sysfs attribute _must_ match exactly. Is that cool for everyone? As usual, 2 tests are added for it with a artificial sysfs file and a few words to the man page. --- namedev.c | 14 ++++++++++++++ .../host0/0:0:0:0/whitespace_test | 1 + test/udev-test.pl | 19 +++++++++++++++++++ udev.8 | 3 +++ 4 files changed, 37 insertions(+) create mode 100644 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/whitespace_test diff --git a/namedev.c b/namedev.c index 9182ed1fdc..dfeadee18a 100644 --- a/namedev.c +++ b/namedev.c @@ -525,6 +525,8 @@ attr_found: static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair) { struct sysfs_attribute *tmpattr; + int i; + int len; if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0')) return -ENODEV; @@ -533,6 +535,18 @@ static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct if (tmpattr == NULL) return -ENODEV; + /* strip trailing whitespace of value, if not asked to match for it */ + if (! isspace(pair->value[strlen(pair->value)-1])) { + i = len = strlen(tmpattr->value); + while (i > 0 && isspace(tmpattr->value[i-1])) + i--; + if (i < len) { + tmpattr->value[i] = '\0'; + dbg("remove %i trailing whitespace chars from '%s'", + len - i, tmpattr->value); + } + } + dbg("compare attribute '%s' value '%s' with '%s'", pair->file, tmpattr->value, pair->value); if (strcmp_pattern(pair->value, tmpattr->value) != 0) diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/whitespace_test b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/whitespace_test new file mode 100644 index 0000000000..e3d48f0fe0 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/whitespace_test @@ -0,0 +1 @@ +WHITE SPACE diff --git a/test/udev-test.pl b/test/udev-test.pl index 60cf16901c..38ea0181f6 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -465,6 +465,25 @@ EOF conf => < "ignore SYSFS attribute whitespace", + subsys => "block", + devpath => "block/sda", + expected => "ignored", + conf => < "do not ignore SYSFS attribute whitespace", + subsys => "block", + devpath => "block/sda", + expected => "matched-with-space", + conf => < Date: Thu, 4 Mar 2004 18:59:18 -0800 Subject: [PATCH 0640/4284] [PATCH] Include more examples in the docs area for gentoo and redhat Here's a patch that puts the udev.rules and udev.permissions files in the docs dir. This should help people out who install with just the rpm. --- udev.spec | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index b7e429d077..34e0755fda 100644 --- a/udev.spec +++ b/udev.spec @@ -114,7 +114,9 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) -%doc COPYING README TODO ChangeLog HOWTO* etc/udev/udev.rules.examples docs/* +%doc COPYING README TODO ChangeLog HOWTO* docs/* +%doc etc/udev/udev.rules.{examples,gentoo,redhat} +%doc etc/udev/udev.permissions.{gentoo,redhat} %attr(755,root,root) /sbin/udev %attr(755,root,root) /usr/bin/udevinfo %attr(755,root,root) /sbin/udevsend From 3f20eac0a58dc3987200773a39163e30b60993fc Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Thu, 4 Mar 2004 19:10:02 -0800 Subject: [PATCH 0641/4284] [PATCH] udevstart fixes udevstart_no_retval: currently udevstart will always return rc=22 because of the error handling code. I completely removed it because it is not used, and returning a generic error to the init script is not much useful anyway. --- udevstart.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/udevstart.c b/udevstart.c index 21fd93df74..40dbaf2475 100644 --- a/udevstart.c +++ b/udevstart.c @@ -78,12 +78,11 @@ static void udev_exec(const char *path, const char* subsystem) } } -static int udev_scan(void) +static void udev_scan(void) { char *devpath; DIR *dir; struct dirent *dent; - int retval = -EINVAL; devpath = "block"; dir = opendir(SYSBLOCK); @@ -179,11 +178,6 @@ static int udev_scan(void) } } } - - if (retval > 0) - retval = 0; - - return -retval; } @@ -191,5 +185,7 @@ int main(int argc, char *argv[], char *envp[]) { init_logging("udevstart"); - return udev_scan(); + udev_scan(); + + return 0; } From 17794d77b97fcb8af263bcecbe03dad5d0e9a89a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 9 Mar 2004 19:50:15 -0800 Subject: [PATCH 0642/4284] [PATCH] rename strn*() macros to strmax Hey, I wrote the strn*() macros just 10 days ago and yesterday this trap caught me with the %c{x} bug. The names are misleading cause we all expect that the from field is limited by the size argument, but we actually limit the overall size of the destination string to prevent a overflow. Here we rename all strn*() macros to str*max(). That should be more self-explanatory. --- namedev.c | 24 ++++++++++++------------ udev-add.c | 6 +++--- udev-remove.c | 2 +- udev.h | 6 +++--- udev_config.c | 2 +- udevdb.c | 4 ++-- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/namedev.c b/namedev.c index dfeadee18a..23d46518ea 100644 --- a/namedev.c +++ b/namedev.c @@ -247,27 +247,27 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, case 'b': if (strlen(udev->bus_id) == 0) break; - strnfieldcat(string, udev->bus_id, maxsize); + strfieldcatmax(string, udev->bus_id, maxsize); dbg("substitute bus_id '%s'", udev->bus_id); break; case 'k': if (strlen(udev->kernel_name) == 0) break; - strnfieldcat(string, udev->kernel_name, maxsize); + strfieldcatmax(string, udev->kernel_name, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'n': if (strlen(udev->kernel_number) == 0) break; - strnfieldcat(string, udev->kernel_number, maxsize); + strfieldcatmax(string, udev->kernel_number, maxsize); dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': - strnintcat(string, udev->minor, maxsize); + strintcatmax(string, udev->minor, maxsize); dbg("substitute minor number '%u'", udev->minor); break; case 'M': - strnintcat(string, udev->major, maxsize); + strintcatmax(string, udev->major, maxsize); dbg("substitute major number '%u'", udev->major); break; case 'c': @@ -287,11 +287,11 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("requested part of result string not found"); break; } - strnfieldcpy(temp2, spos, slen+1); - strnfieldcat(string, temp2, maxsize); + strfieldcpymax(temp2, spos, slen+1); + strfieldcatmax(string, temp2, maxsize); dbg("substitute part of result string '%s'", temp2); } else { - strnfieldcat(string, udev->program_result, maxsize); + strfieldcatmax(string, udev->program_result, maxsize); dbg("substitute result string '%s'", udev->program_result); } break; @@ -302,14 +302,14 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("sysfa attribute '%s' not found", attr); break; } - strnfieldcat(string, tmpattr->value, maxsize); + strfieldcatmax(string, tmpattr->value, maxsize); dbg("substitute sysfs value '%s'", tmpattr->value); } else { dbg("missing attribute"); } break; case '%': - strnfieldcat(string, "%", maxsize); + strfieldcatmax(string, "%", maxsize); break; default: dbg("unknown substitution type '%%%c'", c); @@ -319,7 +319,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, if (len > 0) pos[len] = '\0'; - strnfieldcat(string, tail, maxsize); + strfieldcatmax(string, tail, maxsize); } } @@ -428,7 +428,7 @@ static int execute_program(char *path, char *value, int len) dup(fds[1]); /* copy off our path to use incase we have too many args */ - strnfieldcpy(buffer, path, sizeof(buffer)); + strfieldcpymax(buffer, path, sizeof(buffer)); if (strchr(path, ' ')) { /* exec with arguments */ diff --git a/udev-add.c b/udev-add.c index de1fb953c4..ce723e45cc 100644 --- a/udev-add.c +++ b/udev-add.c @@ -141,7 +141,7 @@ static void set_to_local_user(char *user) struct utmp *u; time_t recent = 0; - strnfieldcpy(user, default_owner_str, OWNER_SIZE); + strfieldcpymax(user, default_owner_str, OWNER_SIZE); setutent(); while (1) { u = getutent(); @@ -158,7 +158,7 @@ static void set_to_local_user(char *user) if (u->ut_time > recent) { recent = u->ut_time; - strnfieldcpy(user, u->ut_user, OWNER_SIZE); + strfieldcpymax(user, u->ut_user, OWNER_SIZE); dbg("local user is '%s'", user); break; } @@ -282,7 +282,7 @@ static int create_node(struct udevice *dev, int fake) /* create symlink if requested */ foreach_strpart(dev->symlink, " ", pos, len) { - strnfieldcpy(linkname, pos, len+1); + strfieldcpymax(linkname, pos, len+1); strfieldcpy(filename, udev_root); strfieldcat(filename, linkname); dbg("symlink '%s' to node '%s' requested", filename, dev->name); diff --git a/udev-remove.c b/udev-remove.c index 195b987411..44ad603d4a 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -103,7 +103,7 @@ static int delete_node(struct udevice *dev) delete_path(filename); foreach_strpart(dev->symlink, " ", pos, len) { - strnfieldcpy(linkname, pos, len+1); + strfieldcpymax(linkname, pos, len+1); strfieldcpy(filename, udev_root); strfieldcat(filename, linkname); diff --git a/udev.h b/udev.h index 32fda379e5..8752f595d6 100644 --- a/udev.h +++ b/udev.h @@ -73,13 +73,13 @@ do { \ strncat(to, from, sizeof(to) - strlen(to)-1); \ } while (0) -#define strnfieldcpy(to, from, maxsize) \ +#define strfieldcpymax(to, from, maxsize) \ do { \ to[maxsize-1] = '\0'; \ strncpy(to, from, maxsize-1); \ } while (0) -#define strnfieldcat(to, from, maxsize) \ +#define strfieldcatmax(to, from, maxsize) \ do { \ to[maxsize-1] = '\0'; \ strncat(to, from, maxsize - strlen(to)-1); \ @@ -91,7 +91,7 @@ do { \ snprintf((to) + strlen(to), sizeof(to) - strlen(to)-1, "%u", i); \ } while (0) -#define strnintcat(to, i, maxsize) \ +#define strintcatmax(to, i, maxsize) \ do { \ to[maxsize-1] = '\0'; \ snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ diff --git a/udev_config.c b/udev_config.c index de83ef9c4c..e2031dc64d 100644 --- a/udev_config.c +++ b/udev_config.c @@ -81,7 +81,7 @@ static void init_variables(void) #define set_var(_name, _var) \ if (strcasecmp(variable, _name) == 0) { \ dbg_parse("%s = '%s'", _name, value); \ - strnfieldcpy(_var, value, sizeof(_var));\ + strfieldcpymax(_var, value, sizeof(_var));\ } #define set_bool(_name, _var) \ diff --git a/udevdb.c b/udevdb.c index b12f5b3d46..01df3ba7e1 100644 --- a/udevdb.c +++ b/udevdb.c @@ -184,7 +184,7 @@ static int find_device_by_name(char *path, struct udevice *dev) if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { memcpy(find_dev, dev, sizeof(struct udevice)); - strnfieldcpy(find_path, path, NAME_SIZE); + strfieldcpymax(find_path, path, NAME_SIZE); find_found = 1; /* stop search */ return 1; @@ -198,7 +198,7 @@ static int find_device_by_name(char *path, struct udevice *dev) continue; memcpy(find_dev, dev, sizeof(struct udevice)); - strnfieldcpy(find_path, path, NAME_SIZE); + strfieldcpymax(find_path, path, NAME_SIZE); find_found = 1; return 1; } From 2bd07cf29b30b424d4b5a17882d0cab0b235153b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 9 Mar 2004 19:50:22 -0800 Subject: [PATCH 0643/4284] [PATCH] put symlink only rules to the man page Here we mention the "symlink only - add it to another rule" feature to the man page. Andrey, does this describe what you have implemented :) --- udev.8 | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/udev.8 b/udev.8 index 76b8913f03..24ff4e28a9 100644 --- a/udev.8 +++ b/udev.8 @@ -200,8 +200,7 @@ call. This key may used in any following rule after a call. .TP .B NAME -The name of the node to be created. If the name field is omitted or its -value is empty, the device will be ignored and no node will be created. +The name of the node to be created. .br If given with the attribute .BR NAME{ all_partitions } @@ -211,6 +210,16 @@ This may be useful for removable media devices. .B SYMLINK The name of a symlink targeting the node. Multiple symlinks may be specified by separating the names by the space character. +.br +If both the name and the symlink fields are omitted or its +values empty, the device will be ignored and no node will be created. +.br +If only the symlink field is given and the name field is omitted, +the rule will not be applied immediatly, but the symlink field is added +to the symlink list of the rule which will create the node. +This makes it possible to specify additional symlinks in a possibly +separate rules file, while the device nodes are maintained by the +distribution provided rules file. .P .RB "The " NAME " ," SYMLINK " and " PROGRAM fields support simple printf-like string substitution: From b86f56ff0936b8bf3fddfc60bbb2697b74a3fcf7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 9 Mar 2004 19:50:30 -0800 Subject: [PATCH 0644/4284] [PATCH] man page beauty Thanks to Christian Gierke, he sent me a beauty patch for our man pages. Some typos are fixed and a few word are clarified. --- udev.8 | 83 ++++++++++++++++++++++++++--------------------------- udevd.8 | 11 ++++--- udevinfo.8 | 12 ++++---- udevstart.8 | 4 +-- 4 files changed, 54 insertions(+), 56 deletions(-) diff --git a/udev.8 b/udev.8 index 24ff4e28a9..8ebcf7bd99 100644 --- a/udev.8 +++ b/udev.8 @@ -13,7 +13,7 @@ signifies the connection or disconnection of a device. .B DEVPATH The sysfs devpath of the device without the mountpoint but a leading slash. .P -Additional optional environment variables are: +Additional optional environment variables: .TP .B UDEV_CONFIG_FILE Overrides the default location of the @@ -29,8 +29,8 @@ will continue, regardless of the state of the device representation. .SH "DESCRIPTION" .B udev creates or removes device node files usually located in the /dev directory. -It provides a dynamic device directory that contains only the files for -devices that are actually present. +It provides a dynamic device directory contaning only the files for +actually present devices. .P As part of the .B hotplug @@ -41,7 +41,7 @@ On device creation, .B udev reads the sysfs directory of the given device to collect device attributes like label, serial number or bus device number. -These attributes may used as keys to determine a +These attributes may be used as keys to determine a unique name for device file creation. .B udev maintains a database for devices present on the system. @@ -53,27 +53,27 @@ queries its database for the name of the device file to be deleted. All .B udev configuration files consist of a set of lines of text. All empty -lines, and lines beginning with a '#' will be ignored. +lines and lines beginning with a '#' will be ignored. .P .B udev expects its main configuration file at .IR /etc/udev/udev.conf . -The file consists of a set of variables and values that allow the user to -override default udev values. The current set of variables that can be -overridden in this file is: +The file consists of a set of variables and values allowing the user to +override default udev values. The following variables can be overridden +in this file: .TP .B udev_root -This is the where in the filesystem to place the device nodes. The default -value for this is +Indicates where to place the device nodes in the filesystem. The default +value is .IR /udev/ . .TP .B udev_db -The name and location of the udev database. The default value for this is +The name and location of the udev database. The default value is .IR /udev/.udev.tdb . .TP .B udev_rules -This is the location of the udev rules file. The default value for this is +This is the location of the udev rules file. The default value for this is .IR /etc/udev/udev.rules . If a directory is specified, the whole directory is scanned for files ending with @@ -89,32 +89,32 @@ and all permission files are read in lexical order. .TP .B udev_log If you want udev to log some information to the syslog for every node created or -removed. The default value for this is +removed. The default value is .IR yes . .TP .B default_mode -This is the default mode for all nodes that have no explicit match in the -permissions file. The default value for this is +This is the default mode for all nodes not explicitely matching in the +permissions file. The default value is .IR 0666 . .TP .B default_owner -This is the default owner for all nodes that have no explicit match in the -permissions file. The default value for this is +This is the default owner for all nodes not explicitely matching in the +permissions file. The default value is .IR root . .TP .B default_group -This is the default group for all nodes that have no explicit match in the -permissions file. The default value for this is +This is the default group for all nodes not explicitely matching in the +permissions file. The default value is .IR root . .br .P .RI "A sample " udev.conf " might look like this: .sp .nf -# udev_root - where in the filesystem to place the device nodes +# udev_root - where to place the device nodes in the filesystem udev_root="/udev/" -# udev_db - The name and location of the udev database. +# udev_db - The name and location of the udev database udev_db="/udev/.udev.tdb" # udev_rules - The location of the directory where to look for files @@ -127,22 +127,22 @@ udev_permissions="/etc/udev/udev.permissions" # udev_log - set to "yes" if you want logging, else "no" udev_log="yes" -# default_mode - set the default mode for all nodes that have no -# explicit match in the permissions file +# default_mode - set the default mode for all nodes not +# explicitely matching in the permissions file default_mode="0666" -# default_owner - set the default owner for all nodes that have no -# explicit match in the permissions file +# default_owner - set the default owner for all nodes not +# explicitely matching in the permissions file default_owner="root" -# default_group - set the default group for all nodes that have no -# explicit match in the permissions file +# default_group - set the default group for all nodes not +# explicitely matching in the permissions file default_group="root" .fi .P -The rules for udev to use when naming devices may specified at +The rules for udev to use when naming devices may specified in .I /etc/udev/udev.rules -or specified by the +or by the .I udev_rules value in the .I /etc/udev/udev.conf @@ -159,7 +159,7 @@ Every rule consists of a list a comma separated fields: .sp .IR "key " ,[ "key " ,...] " name " [, " symlink" ] .sp -where possible fields are: +where fields are: .TP .B BUS Match the bus type of the device. @@ -177,7 +177,7 @@ Match the topological position on bus, like physical port of USB device .BI SYSFS{ filename } Match sysfs device attribute like label, vendor, USB serial number, SCSI UUID or file system label. Up to 5 different sysfs files can be checked, with -all of the values being required in order to match the rule. +all of the values being required to match the rule. .br Trailing whitespace characters in the sysfs attribute value are ignored, if the key doesn't have any trailing whitespace characters by itself. @@ -188,14 +188,14 @@ The environment variables of .B udev are also available for the program. .br -The string returned by the program may additionally matched with the +The string returned by the program may be additionally matched with the .B RESULT key. .TP .B RESULT Match the returned string of the last .B PROGRAM -call. This key may used in any following rule after a +call. This key may be used in any following rule after a .B PROGRAM call. .TP @@ -241,15 +241,14 @@ The kernel minor number for the device. The bus id for the device. .TP .B %c -The +The string returned from the execution of .B PROGRAM -returned string. (This does not work within the .B PROGRAM field for the obvious reason.) .br -A single part of the string, separated by the space character -my be selected by specifying the part number as a attribute: +A single part of the string, separated by a space character +may be selected by specifying the part number as a attribute: .BI %c{ part } .TP .BI %s{ filename } @@ -271,7 +270,7 @@ BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="OEM 0815", NAME="disk1" # USB printer to be called lp_color BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_color" -# SCSI disk with a specific vendor and model number is to be called boot +# SCSI disk with a specific vendor and model number will be called boot BUS="scsi", SYSFS{vendor}="IBM", SYSFS{model}="ST336", NAME="boot%n" # sound card with PCI bus id 00:0b.0 to be called dsp @@ -287,9 +286,9 @@ KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" BUS="usb", SYSFS{model}="XV3", NAME="video%n", SYMLINK="webcam%n" .fi .P -Permissions and ownership for the created device files may specified at +Permissions and ownership for the created device files may specified in .I /etc/udev/udev.permissions -or specified by the +or by the .I udev_permission value in the .I /etc/udev/udev.conf @@ -311,7 +310,7 @@ dsp1:::0666 .P The value .I $local -can be substituted for a specific username. In that case, udev will determine +can be used instead of a specific username. In that case, udev will determine the current local user at the time of device node creation and substitute that username as the owner of the new device node. This is useful, for example, to let hot-plugged devices, such as cameras, be owned by the user at @@ -334,7 +333,7 @@ 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 '!' then any character not enclosed is matched. +following the '[' is a '!', any character not enclosed is matched. .SH "FILES" .nf /sbin/udev udev program diff --git a/udevd.8 b/udevd.8 index 30adb94f2b..9d0127b6bc 100644 --- a/udevd.8 +++ b/udevd.8 @@ -23,19 +23,18 @@ If unset, the event bypasses the queue and will be executed immediately. allows the serialization of .BR hotplug (8) events. The events generated by the kernel may arrive in random order -in userspace, that makes it neccessary to reorder it. +in userspace, that makes it neccessary to reorder them. .br .B udevd takes care of the kernel supplied sequence number and arranges the events for -execution in the correct order. Missing sequences are delaying the -execution of the following events until a timeout of a maximum of 5 seconds -is reached. +execution in the correct order. Missing sequences delay the execution of the +following events until a timeout of a maximum of 5 seconds is reached. .br For each event a .BR udev (8) instance is executed in the background. All further events for the same device -are delayed until the execution is finished. This way it will never run more -than one instance for a single device at the same time. +are delayed until the execution is finished. This way there will never be more +than one instance running for a single device at the same time. .br .B udevd receives the events from diff --git a/udevinfo.8 b/udevinfo.8 index e087e2d1ff..bf6a0aded1 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -6,18 +6,18 @@ udevinfo \- retrieve information from udev .RI "[\-q " query_type " \-p " sysfs_path "] [\-drVh]" .SH "DESCRIPTION" .B udevinfo -allows users to query the udev database for information on any of the devices -currently present in the system. It also provides a way to query any device -in the sysfs tree to help in creating +allows users to query the udev database for information on any device +currently present on the system. It also provides a way to query any device +in the sysfs tree to help creating .B udev -rule files. +rules. .SH "OPTIONS" .TP .B \-V Print the version information. .TP .B \-r -Print the the +Print the .B udev_root directory. When used in conjunction with a query for the node name, the .B udev_root @@ -41,7 +41,7 @@ queried, the main device must be used instead. .B \-a Print all .BI SYSFS{ filename } -attributes along the device chain. Useful for for finding +attributes along the device chain. Useful for finding unique attributes to compose a rule. .RB Needs " \-p " specified. .TP diff --git a/udevstart.8 b/udevstart.8 index 3e6c61f547..c64400cc4f 100644 --- a/udevstart.8 +++ b/udevstart.8 @@ -1,13 +1,13 @@ .TH UDEVSTART 8 "March 2004" "" "Linux Administrator's Manual" .SH NAME -udevstart \- populate device directory with all nodes available in sysfs +udevstart \- populate initial device directory .SH SYNOPSIS .B udevstart .SH "DESCRIPTION" .B udevstart walks trough the sysfs device tree and calls .B udev -to create the node for every valid device found. It can be used to fill a +to create the nodes for every valid device found. It can be used to fill a empty device directory with nodes for all devices currently available on the system. .SH "SEE ALSO" From 3e16482d259c4a768b24a82bc0ed0e3a77954210 Mon Sep 17 00:00:00 2001 From: "ken@cgi101.com" Date: Tue, 9 Mar 2004 19:55:17 -0800 Subject: [PATCH 0645/4284] [PATCH] Added line to udev.permissions.redhat Added this line to have xterms provide a prompt. --- etc/udev/udev.permissions.redhat | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/udev/udev.permissions.redhat b/etc/udev/udev.permissions.redhat index f73360e34c..c96663964f 100644 --- a/etc/udev/udev.permissions.redhat +++ b/etc/udev/udev.permissions.redhat @@ -9,6 +9,7 @@ vc/[0-9]*:root:tty:0660 # Set this to 0660 if you only want users belonging to tty group # to be able to allocate PTYs ptmx:root:tty:0666 +tty:root:tty:0666 pty[p-za-e][0-9a-f]*:root:tty:0660 tty[p-za-e][0-9a-f]*:root:tty:0660 pty/m*:root:tty:0660 From e41016d3547ef704c0785ba197d36ef69de51260 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Mar 2004 22:35:37 -0800 Subject: [PATCH 0646/4284] [PATCH] allow to specify node permissions in the rule This allows to set the permissions along with the rule. This is not a general replacement for the permissions config, but it may be easier sometimes for the user to specify the permissions along with the rule, cause the permissions config file wants the final node name to match, which seems sometimes a bit difficult to guess, if format % chars are used in the NAME field. Any value not given in the rule is still be read from the permissions file or set to the default. This one will also work: BUS="usb", KERNEL="video*", NAME="my-%k", OWNER="$local" A few words to man page are also added and add_perm_dev() is moved into namedev_parse.c where it belongs to. --- namedev.c | 58 ++++++++++++++----------------------------------- namedev.h | 15 ++++++++++++- namedev_parse.c | 54 ++++++++++++++++++++++++++++++++++++++++----- udev.8 | 4 ++++ 4 files changed, 82 insertions(+), 49 deletions(-) diff --git a/namedev.c b/namedev.c index 23d46518ea..1e424998f6 100644 --- a/namedev.c +++ b/namedev.c @@ -46,6 +46,7 @@ static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *c LIST_HEAD(config_device_list); LIST_HEAD(perm_device_list); + /* compare string with pattern (supports * ? [0-9] [!A-Z]) */ static int strcmp_pattern(const char *p, const char *s) { @@ -99,39 +100,6 @@ static int strcmp_pattern(const char *p, const char *s) return 1; } -#define copy_var(a, b, var) \ - if (b->var) \ - a->var = b->var; - -#define copy_string(a, b, var) \ - if (strlen(b->var)) \ - strcpy(a->var, b->var); - -int add_perm_dev(struct perm_device *new_dev) -{ - struct perm_device *dev; - struct perm_device *tmp_dev; - - /* update the values if we already have the device */ - list_for_each_entry(dev, &perm_device_list, node) { - if (strcmp(new_dev->name, dev->name)) - continue; - copy_var(dev, new_dev, mode); - copy_string(dev, new_dev, owner); - copy_string(dev, new_dev, group); - return 0; - } - - /* not found, add new structure to the perm list */ - tmp_dev = malloc(sizeof(*tmp_dev)); - if (!tmp_dev) - return -ENOMEM; - memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); - list_add_tail(&tmp_dev->node, &perm_device_list); - //dump_perm_dev(tmp_dev); - return 0; -} - static struct perm_device *find_perm(char *name) { struct perm_device *perm; @@ -865,22 +833,28 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud goto done; found: - /* substitute placeholder */ apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); udev->partitions = dev->partitions; + done: + /* get permissions given in rule */ + set_empty_perms(udev, dev->mode, + dev->owner, + dev->group); + + /* get permissions given in config file or set defaults */ perm = find_perm(udev->name); - if (perm) { - udev->mode = perm->mode; - strfieldcpy(udev->owner, perm->owner); - strfieldcpy(udev->group, perm->group); + if (perm != NULL) { + set_empty_perms(udev, perm->mode, + perm->owner, + perm->group); } else { - /* no matching perms found :( */ - udev->mode = get_default_mode(); - strfieldcpy(udev->owner, get_default_owner()); - strfieldcpy(udev->group, get_default_group()); + set_empty_perms(udev, get_default_mode(), + get_default_owner(), + get_default_group()); } + dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); diff --git a/namedev.h b/namedev.h index 7f875ed603..16a8bffe97 100644 --- a/namedev.h +++ b/namedev.h @@ -44,6 +44,9 @@ struct sysfs_class_device; #define FIELD_KERNEL "KERNEL" #define FIELD_NAME "NAME" #define FIELD_SYMLINK "SYMLINK" +#define FIELD_OWNER "OWNER" +#define FIELD_GROUP "GROUP" +#define FIELD_MODE "MODE" #define ATTR_PARTITIONS "all_partitions" #define PARTITIONS_COUNT 15 @@ -54,6 +57,14 @@ struct sysfs_class_device; #define RULEFILE_EXT ".rules" #define PERMFILE_EXT ".permissions" +#define set_empty_perms(dev, m, o, g) \ + if (dev->mode == 0) \ + dev->mode = m; \ + if (dev->owner[0] == '\0') \ + strfieldcpy(dev->owner, o); \ + if (dev->group[0] == '\0') \ + strfieldcpy(dev->group, g); + struct sysfs_pair { char file[FILE_SIZE]; char value[VALUE_SIZE]; @@ -71,6 +82,9 @@ struct config_device { char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; + char owner[OWNER_SIZE]; + char group[GROUP_SIZE]; + unsigned int mode; int partitions; char config_file[NAME_SIZE]; int config_line; @@ -93,7 +107,6 @@ extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udev extern int namedev_init_permissions(void); extern int namedev_init_rules(void); -extern int add_perm_dev(struct perm_device *new_dev); extern void dump_config_dev(struct config_device *dev); extern void dump_config_dev_list(void); extern void dump_perm_dev(struct perm_device *dev); diff --git a/namedev_parse.c b/namedev_parse.c index defb698b26..fba32a4983 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -43,6 +43,7 @@ LIST_HEAD(file_list); + static int add_config_dev(struct config_device *new_dev) { struct config_device *tmp_dev; @@ -61,9 +62,11 @@ void dump_config_dev(struct config_device *dev) dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', " "sysfs_file[0]='%s', sysfs_value[0]='%s', " "kernel='%s', program='%s', result='%s'", + "owner='%s', group='%s', mode=%#o", dev->name, dev->symlink, dev->bus, dev->place, dev->id, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value, - dev->kernel, dev->program, dev->result); + dev->kernel, dev->program, dev->result,; + dev->owner, dev->group, dev->mode); } void dump_config_dev_list(void) @@ -74,6 +77,31 @@ void dump_config_dev_list(void) dump_config_dev(dev); } +static int add_perm_dev(struct perm_device *new_dev) +{ + struct perm_device *dev; + struct perm_device *tmp_dev; + + /* update the values if we already have the device */ + list_for_each_entry(dev, &perm_device_list, node) { + if (strcmp(new_dev->name, dev->name) != 0) + continue; + + set_empty_perms(dev, new_dev->mode, new_dev->owner, new_dev->group); + return 0; + } + + /* not found, add new structure to the perm list */ + tmp_dev = malloc(sizeof(*tmp_dev)); + if (!tmp_dev) + return -ENOMEM; + + memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); + list_add_tail(&tmp_dev->node, &perm_device_list); + //dump_perm_dev(tmp_dev); + return 0; +} + void dump_perm_dev(struct perm_device *dev) { dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", @@ -240,12 +268,26 @@ static int namedev_parse_rules(char *filename) continue; } + if (strcasecmp(temp2, FIELD_OWNER) == 0) { + strfieldcpy(dev.owner, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_GROUP) == 0) { + strfieldcpy(dev.group, temp3); + continue; + } + + if (strcasecmp(temp2, FIELD_MODE) == 0) { + dev.mode = strtol(temp3, NULL, 8); + continue; + } + dbg("unknown type of field '%s'", temp2); - dbg("You might be using a rules file in the old format, please fix."); goto error; } - /* simple plausibility check for given keys */ + /* simple plausibility checks for given keys */ if ((dev.sysfs_pair[0].file[0] == '\0') ^ (dev.sysfs_pair[0].value[0] == '\0')) { dbg("inconsistency in " FIELD_SYSFS " key"); @@ -336,14 +378,14 @@ static int namedev_parse_permissions(char *filename) strfieldcpy(dev.group, temp2); if (!temp) { - dbg("cannot parse line: %s", line); + dbg("cannot parse line '%s'", line); continue; } dev.mode = strtol(temp, NULL, 8); dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", - dev.name, dev.owner, dev.group, - dev.mode); + dev.name, dev.owner, dev.group, dev.mode); + retval = add_perm_dev(&dev); if (retval) { dbg("add_perm_dev returned with error %d", retval); diff --git a/udev.8 b/udev.8 index 8ebcf7bd99..d5d9549113 100644 --- a/udev.8 +++ b/udev.8 @@ -220,6 +220,10 @@ to the symlink list of the rule which will create the node. This makes it possible to specify additional symlinks in a possibly separate rules file, while the device nodes are maintained by the distribution provided rules file. +.TP +.B OWNER, GROUP, MODE +The permissions for this device. Every specified value overwrites the value +given in the permissions file. .P .RB "The " NAME " ," SYMLINK " and " PROGRAM fields support simple printf-like string substitution: From 49f9acf3844aa5c004b5794e919bd54166e53227 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Mar 2004 22:38:58 -0800 Subject: [PATCH 0647/4284] [PATCH] deleted current extras/multipath directory --- extras/multipath/AUTHOR | 1 - extras/multipath/COPYING | 483 -------- extras/multipath/ChangeLog | 126 -- extras/multipath/Makefile | 80 -- extras/multipath/README | 90 -- extras/multipath/VERSION | 1 - extras/multipath/devinfo.c | 204 --- extras/multipath/devinfo.h | 19 - extras/multipath/devmap_name.8 | 30 - extras/multipath/devmap_name.c | 60 - extras/multipath/libdevmapper/Makefile | 22 - .../libdevmapper/ioctl/libdevmapper.c | 1092 ----------------- .../libdevmapper/ioctl/libdm-compat.h | 111 -- .../libdevmapper/ioctl/libdm-targets.h | 51 - extras/multipath/libdevmapper/libdevmapper.h | 147 --- extras/multipath/libdevmapper/libdm-common.c | 382 ------ extras/multipath/libdevmapper/libdm-common.h | 38 - extras/multipath/libdevmapper/list.h | 99 -- extras/multipath/main.c | 705 ----------- extras/multipath/main.h | 124 -- extras/multipath/multipath.8 | 53 - extras/multipath/multipath.hotplug | 7 - extras/multipath/sg_err.h | 162 --- extras/multipath/sg_include.h | 43 - extras/multipath/unused.c | 95 -- 25 files changed, 4225 deletions(-) delete mode 100644 extras/multipath/AUTHOR delete mode 100644 extras/multipath/COPYING delete mode 100644 extras/multipath/ChangeLog delete mode 100644 extras/multipath/Makefile delete mode 100644 extras/multipath/README delete mode 100644 extras/multipath/VERSION delete mode 100644 extras/multipath/devinfo.c delete mode 100644 extras/multipath/devinfo.h delete mode 100644 extras/multipath/devmap_name.8 delete mode 100644 extras/multipath/devmap_name.c delete mode 100644 extras/multipath/libdevmapper/Makefile delete mode 100644 extras/multipath/libdevmapper/ioctl/libdevmapper.c delete mode 100644 extras/multipath/libdevmapper/ioctl/libdm-compat.h delete mode 100644 extras/multipath/libdevmapper/ioctl/libdm-targets.h delete mode 100644 extras/multipath/libdevmapper/libdevmapper.h delete mode 100644 extras/multipath/libdevmapper/libdm-common.c delete mode 100644 extras/multipath/libdevmapper/libdm-common.h delete mode 100644 extras/multipath/libdevmapper/list.h delete mode 100644 extras/multipath/main.c delete mode 100644 extras/multipath/main.h delete mode 100644 extras/multipath/multipath.8 delete mode 100644 extras/multipath/multipath.hotplug delete mode 100644 extras/multipath/sg_err.h delete mode 100644 extras/multipath/sg_include.h delete mode 100644 extras/multipath/unused.c diff --git a/extras/multipath/AUTHOR b/extras/multipath/AUTHOR deleted file mode 100644 index 4e8eeef5c8..0000000000 --- a/extras/multipath/AUTHOR +++ /dev/null @@ -1 +0,0 @@ -Christophe Varoqui, diff --git a/extras/multipath/COPYING b/extras/multipath/COPYING deleted file mode 100644 index 9e31bbf0b3..0000000000 --- a/extras/multipath/COPYING +++ /dev/null @@ -1,483 +0,0 @@ - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, 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 library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, 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 companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete 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 distribute a copy of this License along with the -Library. - - 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 Library or any portion -of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -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 Library, 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 Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. 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. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library 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. - - 9. 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 Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -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. - - 11. 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 Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library 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 Library. - -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. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library 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 Library -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 Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -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 - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/extras/multipath/ChangeLog b/extras/multipath/ChangeLog deleted file mode 100644 index a2863ec23e..0000000000 --- a/extras/multipath/ChangeLog +++ /dev/null @@ -1,126 +0,0 @@ -2004-02-21 multipath-018 - * From the Debian SID inclusion review (Philipp Matthias Hahn) - * use DESTDIR install prefix in the Makefile - * add man pages for devmap_name & multipath - * correct libsysfs.h includes - * fork the hotplug script in its own shell - * Sync with the kernel device mapper code as of 2.6.3-udm3 - ie. Remove the test interval parameter and its uses - * Remove superfluous scsi parameter passed from hotplug - * Add the man pages to the [un]install targets -2004-02-17 multipath-017 - * remove the restrictive -f flag. - Introduce a more generic "-m iopolicy" one. - * remove useless "int with_sysfs" in env struct -2004-02-04 multipath-016 - * add a GROUP_BY_SERIAL flag. This should be useful for - controlers that activate they spare paths on simple IO - submition with a penalty. The StorageWorks HW defaults to - this mode, even if the MULTIBUS mode is OK. - * remove unused sg_err.c - * big restructuring : split devinfo.c from main.c. Export : - * void basename (char *, char *); - * int get_serial (int, char *); - * int get_lun_strings (char *, char *, char *, char *); - * int get_evpd_wwid(char *, char *); - * long get_disk_size (char *); - * stop passing struct env as param - * add devmap_name proggy for udev to name devmaps as per their - internal DM name and not only by their sysfs enum name (dm-*) - The corresponding udev.rules line is : - KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" - * remove make_dm_node fn & call. Rely on udev for this. - * don't rely on the linux symlink in the udev/klibc dir since - udev build doesn't use it anymore. This corrects build breakage -2004-01-19 multipath-013 - * update the DM target synthax to the 2.6.0-udm5 style -2003-12-29 multipath-012 - * check hotplug event refers to a block device; if not exit early - * refresh doc - * add the uninstall target in Makefile -2003-12-22 multipath-010 - * tweak the install target in Makefile - * stop passing fds as argument : this change enable a strict - segregation of ugly 2.4 code - * sysfs version of get_lun_strings() - * be careful about the return of get_unique_id() since errors - formerly caught up by if(open()) in the caller fn are now returned - by get_unique_id() - * send get_serial() in unused.c - * introduce dm-simplecmd for RESUME & SUSPEND requests - * split add_map() in setup_map() & dm-addmap() - * setup_map() correctly submits "SUSPEND-RELOAD-RESUME or CREATE" - sequences instead of the bogus "RELOAD or CREATE" - * don't print .sg_dev if equal to .dev (2.6) in print_path() - * since the kernel code handles defective paths, remove all - code to cope with them : - * move do_tur() to unused.c - * remove .state from path struct - * remove .state settings & conditionals - * add a cmdline switch to force maps to failover mode, - ie 1 path per priority group - * add default policies to the whitelist array (spread io == - MULTIBUS / io forced to 1 path == FAILOVER) - * move get_disk_size() call out of add_map() to coalesce() - * comment tricky coalesce() fn - * bogus unsused.c file renamed to unused.c -2003-12-20 multipath-010 - * big ChangeLog update - * start to give a little control over target params : - introduce cmdline arg -i to control polling interval - * cope with hotplug-style calling convention : - ie "multipath scsi $DEVPATH" ... to avoid messing with - online maps not concerned by an event - * example hotplug agent to drop in /etc/hotplug.d/scsi - * revert the run & resched patch : unless someone proves me - wrong, this was overdesigned - * move commented out functions in unused.c - * update multipath target params to "udm[23] style" - * mp target now supports nr_path == 1, so do we - * add gratuitous free() - * push version forward -2003-12-15 multipath-009 - * Make the HW-specific get_unique_id switch pretty - * Prepare to field-test by whitelisting all known fibre array, - try to fetch WWID from the standard EVPD 0x83 off 8 for everyone - * configure the multipath target with round-robin path selector and - conservative default for a start (udm1 style) : - yes it makes this release the firstreally useful one. - * temporarily disable map creation for single path device - due to current restrictive defaults in the kernel target. - Sistina should work it out. - * correct the strncmp logic in blacklist function. - * update the Makefiles to autodetect libgcc.a & gcc includes - "ulibc-style". Factorisation of udevdirs & others niceties - * drop a hint about absent /dev/sd? on failed open() - * implement a reschedule flag in /var/run. - Last thing the prog do before exit is check if a call to multipath - was done (but canceled by /var/run/multipath.run check) during its - execution. If so restart themain loop. - * implement a blacklist of sysfs bdev to not bother with for now - (hd,md, dm, sr, scd, ram, raw). - This avoid sending SG_IO to unappropiate devices. - * Adds a /var/run/multipath.run handling to avoid simultaneous runs. - * Remove a commented-out "printf" - * drop a libdevmapper copy in extras/multipath; - maybe discussions w/Sistina folks will bring a better solution in the future. - * drop a putchar usage in libdevmapper to compile cleanly with klibc - * drop another such usage of my own in main.c - * massage the Makefile to compile libdevmapper against klibc - * use "ld" to produce the binary rather than "gcc -static" - * stop being stupid w/ uneeded major, minor & dev in main.c:dm_mk_node() - * reverse to creating striped target for now because the multipath target - is more hairy than expected initialy - * push the version code to 009 to be in synch w/ udev -2003-11-27 multipath-007 - * removes sg_err.[ch] deps - * makes sure the core code play nice with klibc - * port the sysfs calls to dlist helpers - * links against udev's sysfs (need libsysfs.a & dlist.a) - * finally define DM_TARGET as "multipath" as Joe posted the code today (not tested yet) - * push version forward (do you want it in sync with udev version?) -2003-11-19 - * merged in udev-006 tree -2003-09-18 Christophe Varoqui - * multipath 0.0.1 released. - * Initial release. diff --git a/extras/multipath/Makefile b/extras/multipath/Makefile deleted file mode 100644 index ee7f60e472..0000000000 --- a/extras/multipath/Makefile +++ /dev/null @@ -1,80 +0,0 @@ -# Makefile -# -# Copyright (C) 2003 Christophe Varoqui, - -EXEC = multipath - -prefix = -exec_prefix = ${prefix} -bindir = ${exec_prefix}/sbin -udevdir = ../.. -klibcdir = $(udevdir)/klibc -sysfsdir = $(udevdir)/libsysfs -mandir = /usr/share/man/man8 - -CC = gcc -GZIP = /bin/gzip -c - -GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} -KERNEL_DIR = /lib/modules/${shell uname -r}/build -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ - -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ - -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. - -OBJS = devinfo.o main.o -CRT0 = ../../klibc/klibc/crt0.o -LIB = ../../klibc/klibc/libc.a -LIBGCC := $(shell $(CC) -print-libgcc-file-name ) - -DMOBJS = libdevmapper/libdm-common.o libdevmapper/ioctl/libdevmapper.o -SYSFSOBJS = ../../libsysfs/dlist.o ../../libsysfs/sysfs_bus.o \ - ../../libsysfs/sysfs_class.o ../../libsysfs/sysfs_device.o \ - ../../libsysfs/sysfs_dir.o ../../libsysfs/sysfs_driver.o \ - ../../libsysfs/sysfs_utils.o - -SUBDIRS = libdevmapper - -recurse: - @for dir in $(SUBDIRS); do\ - $(MAKE) KERNEL_DIR=$(KERNEL_DIR) -C $$dir ; \ - done - $(MAKE) $(EXEC) - $(MAKE) devmap_name - -all: recurse - @echo "" - @echo "Make complete" - -$(EXEC): $(OBJS) - $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(SYSFSOBJS) $(DMOBJS) $(LIB) $(LIBGCC) - strip $(EXEC) - $(GZIP) $(EXEC).8 > $(EXEC).8.gz - -devmap_name: devmap_name.o - $(LD) -o devmap_name $(CRT0) devmap_name.o $(DMOBJS) $(LIB) $(LIBGCC) - strip devmap_name - $(GZIP) devmap_name.8 > devmap_name.8.gz - -clean: - rm -f core *.o $(EXEC) devmap_name *.gz - $(MAKE) -C libdevmapper clean - -install: - install -d $(DESTDIR)$(bindir) - install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - install -m 755 devmap_name $(DESTDIR)$(bindir)/ - install -d $(DESTDIR)/etc/hotplug.d/scsi/ - install -m 755 multipath.hotplug $(DESTDIR)/etc/hotplug.d/scsi/ - install -d $(DESTDIR)$(mandir) - install -m 644 devmap_name.8.gz $(DESTDIR)$(mandir) - install -m 644 multipath.8.gz $(DESTDIR)$(mandir) - -uninstall: - rm $(DESTDIR)/etc/hotplug.d/scsi/multipath.hotplug - rm $(DESTDIR)$(bindir)/$(EXEC) - rm $(DESTDIR)$(bindir)/devmap_name - rm $(DESTDIR)$(mandir)/devmap_name.8.gz - rm $(DESTDIR)$(mandir)/multipath.8.gz - -# Code dependencies -main.o: main.c main.h sg_include.h devinfo.h diff --git a/extras/multipath/README b/extras/multipath/README deleted file mode 100644 index 80945db438..0000000000 --- a/extras/multipath/README +++ /dev/null @@ -1,90 +0,0 @@ -Dependancies : -============== - -o libdevmapper : comes with device-mapper-XXXX.tar.gz - See www.sistina.com - This lib has been dropped in the multipath tree -o libsysfs : comes with sysutils or udev - See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ -o Linux kernel 2.6.0 with udm5 patchset - http://people.sistina.com/~thornber/dm/ -o udev - See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ - -How it works : -============== - -Fill the all_paths array. Each path store this info : - -struct path { - char dev[FILE_NAME_SIZE]; - char sg_dev[FILE_NAME_SIZE]; - struct scsi_idlun scsi_id; - struct sg_id sg_id; - int state; - char wwid[WWID_SIZE]; -}; - -scsi_id, sg_dev and sg_id are only really useful for 2.4 -kernels, for which SG cmnds must go through sg devs. -In 2.5+ we have the nice opportunity to send SG cmnds -through SCSI bdevs. - -For 2.4 compat, we pivot on idlun tupple to map sg devs -to SCSI bdevs. - -2.4 does not do device enumeration, so we must scan a -defined number of sg devs and scsi bdevs. Good enough. -In 2.5+, we rely on libsysfs (sysutils) to access to -sysfs device enums. - -the wwid is retrieved by a switch fonction. Only White -Listed HW can filled this field. For now every FC array -HW listed in kernel's devinfo.c is White Listed, assuming -the WWID is stored is the SCSI-3 standard 0x83 EVPD page. - -When all_paths is filled, we coalesce the paths and store -the result in mp array. Each mp is a struct like this : - -struct multipath { - char wwid[WWID_SIZE]; - int npaths; - int pindex[MAX_MP_PATHS]; -}; - -When mp is filled, the device maps are fed to the kernel -through libdevmapper. - -The naming of the corresponding block device is handeld -by udev with the help of the devmap_name proggy. It is -called by the following rule in /etc/udev/udev.rules : -KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \ -NAME="%k", SYMLINK="%c" - -Notes : -======= - -o On 2.4, make sure you have enough /dev/sg* nodes - (/dev/MAKEDEV if necesary). Same goes for /dev/sd* - -o path coalescing relies on a path unique id being found. - This unique id, lacking a standard method, is vendor - specific. A switch function (get_unique_id) is present - and an example function is provided for storageworks - arrays (get_evpd_wwid). Feel free to enrich - with hardware you have at hand :) - -o The kernel does NOT manage properly ghosts paths - with StorageWorks HW. Seems nobody cares after a load - of posts to linux-scsi. - -o 2.4.21 version of DM does not like even segment size. - if you enconter pbs with this, upgrade DM. - -Credits : -========= - -o Heavy cut'n paste from sg_utils. Thanks goes to D. - Gilbert. -o Light cut'n paste from dmsetup. Thanks Joe Thornber. -o Greg KH for the nice sysfs API. diff --git a/extras/multipath/VERSION b/extras/multipath/VERSION deleted file mode 100644 index bbdeab6222..0000000000 --- a/extras/multipath/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.0.5 diff --git a/extras/multipath/devinfo.c b/extras/multipath/devinfo.c deleted file mode 100644 index 323da2f2f0..0000000000 --- a/extras/multipath/devinfo.c +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "devinfo.h" -#include "sg_include.h" - -#define FILE_NAME_SIZE 255 - -void -basename(char * str1, char * str2) -{ - char *p = str1 + (strlen(str1) - 1); - - while (*--p != '/') - continue; - strcpy(str2, ++p); -} - -static int -do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, - void *resp, int mx_resp_len, int noisy) -{ - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = - { INQUIRY_CMD, 0, 0, 0, 0, 0 }; - unsigned char sense_b[SENSE_BUFF_LEN]; - struct sg_io_hdr io_hdr; - - if (cmddt) - inqCmdBlk[1] |= 2; - if (evpd) - inqCmdBlk[1] |= 1; - inqCmdBlk[2] = (unsigned char) pg_op; - inqCmdBlk[4] = (unsigned char) mx_resp_len; - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_b); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = mx_resp_len; - io_hdr.dxferp = resp; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sense_b; - io_hdr.timeout = DEF_TIMEOUT; - - if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { - perror("SG_IO (inquiry) error"); - return -1; - } - - /* treat SG_ERR here to get rid of sg_err.[ch] */ - io_hdr.status &= 0x7e; - if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && - (0 == io_hdr.driver_status)) - return 0; - if ((SCSI_CHECK_CONDITION == io_hdr.status) || - (SCSI_COMMAND_TERMINATED == io_hdr.status) || - (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { - if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { - int sense_key; - unsigned char * sense_buffer = io_hdr.sbp; - if (sense_buffer[0] & 0x2) - sense_key = sense_buffer[1] & 0xf; - else - sense_key = sense_buffer[2] & 0xf; - if(RECOVERED_ERROR == sense_key) - return 0; - } - } - return -1; -} - -int -get_serial (char * str, char * devname) -{ - int fd; - int len; - char buff[MX_ALLOC_LEN + 1]; - - if ((fd = open(devname, O_RDONLY)) < 0) - return 0; - - if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { - len = buff[3]; - if (len > 0) { - memcpy(str, buff + 4, len); - buff[len] = '\0'; - } - close(fd); - return 1; - } - close(fd); - return 0; -} - -int -get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname) -{ - int fd; - char buff[36]; - char attr_path[FILE_NAME_SIZE]; - char sysfs_path[FILE_NAME_SIZE]; - char basedev[FILE_NAME_SIZE]; - - if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { - /* sysfs style */ - basename(devname, basedev); - - sprintf(attr_path, "%s/block/%s/device/vendor", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - vendor_id, 8)) return 0; - - sprintf(attr_path, "%s/block/%s/device/model", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - product_id, 16)) return 0; - - sprintf(attr_path, "%s/block/%s/device/rev", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - rev, 4)) return 0; - } else { - /* ioctl style */ - if ((fd = open(devname, O_RDONLY)) < 0) - return 0; - if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) - return 0; - memcpy(vendor_id, &buff[8], 8); - memcpy(product_id, &buff[16], 16); - memcpy(rev, &buff[32], 4); - close(fd); - return 1; - } - return 0; -} - -static void -sprint_wwid(char * buff, const char * str) -{ - int i; - const char *p; - char *cursor; - unsigned char c; - - p = str; - cursor = buff; - for (i = 0; i <= WWID_SIZE / 2 - 1; i++) { - c = *p++; - sprintf(cursor, "%.2x", (int) (unsigned char) c); - cursor += 2; - } - buff[WWID_SIZE - 1] = '\0'; -} - -/* get EVPD page 0x83 off 8 */ -/* tested ok with StorageWorks */ -int -get_evpd_wwid(char * devname, char * wwid) -{ - int fd; - char buff[64]; - - if ((fd = open(devname, O_RDONLY)) < 0) - return 0; - - if (0 == do_inq(fd, 0, 1, 0x83, buff, sizeof (buff), 1)) { - sprint_wwid(wwid, &buff[8]); - close(fd); - return 1; /* success */ - } - close(fd); - return 0; /* not good */ -} - -long -get_disk_size (char * devname) { - long size; - int fd; - char attr_path[FILE_NAME_SIZE]; - char sysfs_path[FILE_NAME_SIZE]; - char buff[FILE_NAME_SIZE]; - char basedev[FILE_NAME_SIZE]; - - if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { - basename(devname, basedev); - sprintf(attr_path, "%s/block/%s/size", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, buff, - FILE_NAME_SIZE * sizeof(char))) - return -1; - size = atoi(buff); - return size; - } else { - if ((fd = open(devname, O_RDONLY)) < 0) - return -1; - if(!ioctl(fd, BLKGETSIZE, &size)) - return size; - } - return -1; -} - diff --git a/extras/multipath/devinfo.h b/extras/multipath/devinfo.h deleted file mode 100644 index 53f2473027..0000000000 --- a/extras/multipath/devinfo.h +++ /dev/null @@ -1,19 +0,0 @@ -#define INQUIRY_CMDLEN 6 -#define INQUIRY_CMD 0x12 -#define SENSE_BUFF_LEN 32 -#define DEF_TIMEOUT 60000 -#define RECOVERED_ERROR 0x01 -#define MX_ALLOC_LEN 255 -#define WWID_SIZE 33 -#define BLKGETSIZE _IO(0x12,96) - -/* exerpt from "sg_err.h" */ -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 - -void basename (char *, char *); -int get_serial (char *, char *); -int get_lun_strings (char *, char *, char *, char *); -int get_evpd_wwid(char *, char *); -long get_disk_size (char *); diff --git a/extras/multipath/devmap_name.8 b/extras/multipath/devmap_name.8 deleted file mode 100644 index f4f03c3ec6..0000000000 --- a/extras/multipath/devmap_name.8 +++ /dev/null @@ -1,30 +0,0 @@ -.TH DEVMAP_NAME 8 "February 2004" "" "Linux Administrator's Manual" -.SH NAME -devmap_name \- Query device-mapper name -.SH SYNOPSIS -.BI devmap_name " major minor" -.SH DESCRIPTION -.B devmap_name -queries the device-mapper for the name for the device -specified by -.I major -and -.I minor -number. -.br -.B devmap_name -can be called from -.B udev -by the following rule in -.IR /etc/udev/udev.rules : -.sp -.nf -KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \\ - NAME="%k", SYMLINK="%c" -.fi -.SH "SEE ALSO" -.BR udev (8), -.BR dmsetup (8) -.SH AUTHORS -.B devmap_name -was developed by Christophe Varoqui, and others. diff --git a/extras/multipath/devmap_name.c b/extras/multipath/devmap_name.c deleted file mode 100644 index 08e526e072..0000000000 --- a/extras/multipath/devmap_name.c +++ /dev/null @@ -1,60 +0,0 @@ -#include "libdevmapper/libdevmapper.h" - -#include -#include -#include -#include - -static void usage(char * progname) { - fprintf(stderr, "usage : %s major minor\n", progname); - exit(1); -} - -int main(int argc, char **argv) -{ - int r = 0; - struct dm_names *names; - unsigned next = 0; - int major, minor; - - /* sanity check */ - if (argc != 3) - usage(argv[0]); - - major = atoi(argv[1]); - minor = atoi(argv[2]); - - struct dm_task *dmt; - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) - return 0; - - if (!dm_task_run(dmt)) - goto out; - - if (!(names = dm_task_get_names(dmt))) - goto out; - - if (!names->dev) { - printf("No devices found\n"); - goto out; - } - - do { - names = (void *) names + next; - if ((int) MAJOR(names->dev) == major && - (int) MINOR(names->dev) == minor) { - printf("%s\n", names->name); - goto out; - } - next = names->next; - } while (next); - - /* No correspondance found */ - r = 1; - - out: - dm_task_destroy(dmt); - return r; -} - diff --git a/extras/multipath/libdevmapper/Makefile b/extras/multipath/libdevmapper/Makefile deleted file mode 100644 index a05a31e85a..0000000000 --- a/extras/multipath/libdevmapper/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Makefile -# -# Copyright (C) 2003 Christophe Varoqui, - -CC = gcc -udevdir = ../../.. -klibcdir = $(udevdir)/klibc - -CC = gcc -GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ - -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ - -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I. -Iioctl - -OBJS = ioctl/libdevmapper.o libdm-common.o - -all: $(OBJS) - @echo "" - @echo "Make complete" - -clean: - rm -f core *.o ioctl/*.o ioctl/*.so diff --git a/extras/multipath/libdevmapper/ioctl/libdevmapper.c b/extras/multipath/libdevmapper/ioctl/libdevmapper.c deleted file mode 100644 index ac7ba0c86a..0000000000 --- a/extras/multipath/libdevmapper/ioctl/libdevmapper.c +++ /dev/null @@ -1,1092 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#include "libdm-targets.h" -#include "libdm-common.h" - -#ifdef DM_COMPAT -# include "libdm-compat.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef linux -# include -# include -# include -#else -# define MAJOR(x) major((x)) -# define MINOR(x) minor((x)) -# define MKDEV(x,y) makedev((x),(y)) -#endif - -/* - * Ensure build compatibility. - * The hard-coded versions here are the highest present - * in the _cmd_data arrays. - */ - -#if !((DM_VERSION_MAJOR == 1 && DM_VERSION_MINOR >= 0) || \ - (DM_VERSION_MAJOR == 4 && DM_VERSION_MINOR >= 0)) -#error The version of dm-ioctl.h included is incompatible. -#endif - -/* dm major version no for running kernel */ -static int _dm_version = DM_VERSION_MAJOR; -static int _log_suppress = 0; - -static int _control_fd = -1; -static int _version_checked = 0; -static int _version_ok = 1; - -/* - * Support both old and new major numbers to ease the transition. - * Clumsy, but only temporary. - */ -#if DM_VERSION_MAJOR == 4 && defined(DM_COMPAT) -const int _dm_compat = 1; -#else -const int _dm_compat = 0; -#endif - - -/* *INDENT-OFF* */ -static struct cmd_data _cmd_data_v4[] = { - {"create", DM_DEV_CREATE, {4, 0, 0}}, - {"reload", DM_TABLE_LOAD, {4, 0, 0}}, - {"remove", DM_DEV_REMOVE, {4, 0, 0}}, - {"remove_all", DM_REMOVE_ALL, {4, 0, 0}}, - {"suspend", DM_DEV_SUSPEND, {4, 0, 0}}, - {"resume", DM_DEV_SUSPEND, {4, 0, 0}}, - {"info", DM_DEV_STATUS, {4, 0, 0}}, - {"deps", DM_TABLE_DEPS, {4, 0, 0}}, - {"rename", DM_DEV_RENAME, {4, 0, 0}}, - {"version", DM_VERSION, {4, 0, 0}}, - {"status", DM_TABLE_STATUS, {4, 0, 0}}, - {"table", DM_TABLE_STATUS, {4, 0, 0}}, - {"waitevent", DM_DEV_WAIT, {4, 0, 0}}, - {"names", DM_LIST_DEVICES, {4, 0, 0}}, - {"clear", DM_TABLE_CLEAR, {4, 0, 0}}, - {"mknodes", DM_DEV_STATUS, {4, 0, 0}}, -}; -/* *INDENT-ON* */ - -#define ALIGNMENT_V1 sizeof(int) -#define ALIGNMENT 8 - -/* FIXME Rejig library to record & use errno instead */ -#ifndef DM_EXISTS_FLAG -# define DM_EXISTS_FLAG 0x00000004 -#endif - -static void *_align(void *ptr, unsigned int a) -{ - register unsigned long agn = --a; - - return (void *) (((unsigned long) ptr + agn) & ~agn); -} - -static int _open_control(void) -{ - char control[PATH_MAX]; - - if (_control_fd != -1) - return 1; - - snprintf(control, sizeof(control), "%s/control", dm_dir()); - - if ((_control_fd = open(control, O_RDWR)) < 0) { - log_error("%s: open failed: %s", control, strerror(errno)); - log_error("Is device-mapper driver missing from kernel?"); - return 0; - } - - return 1; -} - -void dm_task_destroy(struct dm_task *dmt) -{ - struct target *t, *n; - - for (t = dmt->head; t; t = n) { - n = t->next; - free(t->params); - free(t->type); - free(t); - } - - if (dmt->dev_name) - free(dmt->dev_name); - - if (dmt->newname) - free(dmt->newname); - - if (dmt->dmi.v4) - free(dmt->dmi.v4); - - if (dmt->uuid) - free(dmt->uuid); - - free(dmt); -} - -/* - * Protocol Version 1 compatibility functions. - */ - -#ifdef DM_COMPAT - -static int _dm_task_get_driver_version_v1(struct dm_task *dmt, char *version, - size_t size) -{ - unsigned int *v; - - if (!dmt->dmi.v1) { - version[0] = '\0'; - return 0; - } - - v = dmt->dmi.v1->version; - snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); - return 1; -} - -/* Unmarshall the target info returned from a status call */ -static int _unmarshal_status_v1(struct dm_task *dmt, struct dm_ioctl_v1 *dmi) -{ - char *outbuf = (char *) dmi + dmi->data_start; - char *outptr = outbuf; - int32_t i; - struct dm_target_spec_v1 *spec; - - for (i = 0; i < dmi->target_count; i++) { - spec = (struct dm_target_spec_v1 *) outptr; - - if (!dm_task_add_target(dmt, spec->sector_start, - (uint64_t) spec->length, - spec->target_type, - outptr + sizeof(*spec))) - return 0; - - outptr = outbuf + spec->next; - } - - return 1; -} - -static int _dm_format_dev_v1(char *buf, int bufsize, uint32_t dev_major, - uint32_t dev_minor) -{ - int r; - - if (bufsize < 8) - return 0; - - r = snprintf(buf, bufsize, "%03x:%03x", dev_major, dev_minor); - if (r < 0 || r > bufsize - 1) - return 0; - - return 1; -} - -static int _dm_task_get_info_v1(struct dm_task *dmt, struct dm_info *info) -{ - if (!dmt->dmi.v1) - return 0; - - memset(info, 0, sizeof(*info)); - - info->exists = dmt->dmi.v1->flags & DM_EXISTS_FLAG ? 1 : 0; - if (!info->exists) - return 1; - - info->suspended = dmt->dmi.v1->flags & DM_SUSPEND_FLAG ? 1 : 0; - info->read_only = dmt->dmi.v1->flags & DM_READONLY_FLAG ? 1 : 0; - info->target_count = dmt->dmi.v1->target_count; - info->open_count = dmt->dmi.v1->open_count; - info->event_nr = 0; - info->major = MAJOR(dmt->dmi.v1->dev); - info->minor = MINOR(dmt->dmi.v1->dev); - info->live_table = 1; - info->inactive_table = 0; - - return 1; -} - -static const char *_dm_task_get_name_v1(struct dm_task *dmt) -{ - return (dmt->dmi.v1->name); -} - -static const char *_dm_task_get_uuid_v1(struct dm_task *dmt) -{ - return (dmt->dmi.v1->uuid); -} - -static struct dm_deps *_dm_task_get_deps_v1(struct dm_task *dmt) -{ - log_error("deps version 1 no longer supported by libdevmapper"); - return NULL; -} - -static struct dm_names *_dm_task_get_names_v1(struct dm_task *dmt) -{ - return (struct dm_names *) (((void *) dmt->dmi.v1) + - dmt->dmi.v1->data_start); -} - -static void *_add_target_v1(struct target *t, void *out, void *end) -{ - void *out_sp = out; - struct dm_target_spec_v1 sp; - size_t sp_size = sizeof(struct dm_target_spec_v1); - int len; - const char no_space[] = "Ran out of memory building ioctl parameter"; - - out += sp_size; - if (out >= end) { - log_error(no_space); - return NULL; - } - - sp.status = 0; - sp.sector_start = t->start; - sp.length = t->length; - strncpy(sp.target_type, t->type, sizeof(sp.target_type)); - - len = strlen(t->params); - - if ((out + len + 1) >= end) { - log_error(no_space); - - log_error("t->params= '%s'", t->params); - return NULL; - } - strcpy((char *) out, t->params); - out += len + 1; - - /* align next block */ - out = _align(out, ALIGNMENT_V1); - - sp.next = out - out_sp; - - memcpy(out_sp, &sp, sp_size); - - return out; -} - -static struct dm_ioctl_v1 *_flatten_v1(struct dm_task *dmt) -{ - const size_t min_size = 16 * 1024; - const int (*version)[3]; - - struct dm_ioctl_v1 *dmi; - struct target *t; - size_t len = sizeof(struct dm_ioctl_v1); - void *b, *e; - int count = 0; - - for (t = dmt->head; t; t = t->next) { - len += sizeof(struct dm_target_spec_v1); - len += strlen(t->params) + 1 + ALIGNMENT_V1; - count++; - } - - if (count && dmt->newname) { - log_error("targets and newname are incompatible"); - return NULL; - } - - if (dmt->newname) - len += strlen(dmt->newname) + 1; - - /* - * Give len a minimum size so that we have space to store - * dependencies or status information. - */ - if (len < min_size) - len = min_size; - - if (!(dmi = malloc(len))) - return NULL; - - memset(dmi, 0, len); - - version = &_cmd_data_v1[dmt->type].version; - - dmi->version[0] = (*version)[0]; - dmi->version[1] = (*version)[1]; - dmi->version[2] = (*version)[2]; - - dmi->data_size = len; - dmi->data_start = sizeof(struct dm_ioctl_v1); - - if (dmt->dev_name) - strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); - - if (dmt->type == DM_DEVICE_SUSPEND) - dmi->flags |= DM_SUSPEND_FLAG; - if (dmt->read_only) - dmi->flags |= DM_READONLY_FLAG; - - if (dmt->minor >= 0) { - if (dmt->major <= 0) { - log_error("Missing major number for persistent device"); - return NULL; - } - dmi->flags |= DM_PERSISTENT_DEV_FLAG; - dmi->dev = MKDEV(dmt->major, dmt->minor); - } - - if (dmt->uuid) - strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); - - dmi->target_count = count; - - b = (void *) (dmi + 1); - e = (void *) ((char *) dmi + len); - - for (t = dmt->head; t; t = t->next) - if (!(b = _add_target_v1(t, b, e))) - goto bad; - - if (dmt->newname) - strcpy(b, dmt->newname); - - return dmi; - - bad: - free(dmi); - return NULL; -} - -static int _dm_names_v1(struct dm_ioctl_v1 *dmi) -{ - const char *dev_dir = dm_dir(); - int r = 1, len; - const char *name; - struct dirent *dirent; - DIR *d; - struct dm_names *names, *old_names = NULL; - void *end = (void *) dmi + dmi->data_size; - struct stat buf; - char path[PATH_MAX]; - - if (!(d = opendir(dev_dir))) { - log_error("%s: opendir failed: %s", dev_dir, strerror(errno)); - return 0; - } - - names = (struct dm_names *) ((void *) dmi + dmi->data_start); - - names->dev = 0; /* Flags no data */ - - while ((dirent = readdir(d))) { - name = dirent->d_name; - - if (name[0] == '.' || !strcmp(name, "control")) - continue; - - if (old_names) - old_names->next = (uint32_t) ((void *) names - - (void *) old_names); - snprintf(path, sizeof(path), "%s/%s", dev_dir, name); - if (stat(path, &buf)) { - log_error("%s: stat failed: %s", path, strerror(errno)); - continue; - } - if (!S_ISBLK(buf.st_mode)) - continue; - names->dev = (uint64_t) buf.st_rdev; - names->next = 0; - len = strlen(name); - if (((void *) (names + 1) + len + 1) >= end) { - log_error("Insufficient buffer space for device list"); - r = 0; - break; - } - - strcpy(names->name, name); - - old_names = names; - names = _align((void *) ++names + len + 1, ALIGNMENT); - } - - if (closedir(d)) - log_error("%s: closedir failed: %s", dev_dir, strerror(errno)); - - return r; -} - -static int _dm_task_run_v1(struct dm_task *dmt) -{ - struct dm_ioctl_v1 *dmi; - unsigned int command; - - dmi = _flatten_v1(dmt); - if (!dmi) { - log_error("Couldn't create ioctl argument"); - return 0; - } - - if (!_open_control()) - return 0; - - if ((unsigned) dmt->type >= - (sizeof(_cmd_data_v1) / sizeof(*_cmd_data_v1))) { - log_error("Internal error: unknown device-mapper task %d", - dmt->type); - goto bad; - } - - command = _cmd_data_v1[dmt->type].cmd; - - if (dmt->type == DM_DEVICE_TABLE) - dmi->flags |= DM_STATUS_TABLE_FLAG; - - log_debug("dm %s %s %s %s", _cmd_data_v1[dmt->type].name, dmi->name, - dmi->uuid, dmt->newname ? dmt->newname : ""); - if (dmt->type == DM_DEVICE_LIST) { - if (!_dm_names_v1(dmi)) - goto bad; - } else if (ioctl(_control_fd, command, dmi) < 0) { - if (_log_suppress) - log_verbose("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - else - log_error("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - goto bad; - } - - switch (dmt->type) { - case DM_DEVICE_CREATE: - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); - break; - - case DM_DEVICE_REMOVE: - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_RENAME: - rename_dev_node(dmt->dev_name, dmt->newname); - break; - - case DM_DEVICE_MKNODES: - if (dmi->flags & DM_EXISTS_FLAG) - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), - MINOR(dmi->dev)); - else - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_STATUS: - case DM_DEVICE_TABLE: - if (!_unmarshal_status_v1(dmt, dmi)) - goto bad; - break; - - case DM_DEVICE_SUSPEND: - case DM_DEVICE_RESUME: - dmt->type = DM_DEVICE_INFO; - if (!dm_task_run(dmt)) - goto bad; - free(dmi); /* We'll use what info returned */ - return 1; - } - - dmt->dmi.v1 = dmi; - return 1; - - bad: - free(dmi); - return 0; -} - -#endif - -/* - * Protocol Version 4 functions. - */ - -int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size) -{ - unsigned int *v; - -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_driver_version_v1(dmt, version, size); -#endif - - if (!dmt->dmi.v4) { - version[0] = '\0'; - return 0; - } - - v = dmt->dmi.v4->version; - snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); - return 1; -} - -static int _check_version(char *version, size_t size, int log_suppress) -{ - struct dm_task *task; - int r; - - if (!(task = dm_task_create(DM_DEVICE_VERSION))) { - log_error("Failed to get device-mapper version"); - version[0] = '\0'; - return 0; - } - - if (log_suppress) - _log_suppress = 1; - - r = dm_task_run(task); - dm_task_get_driver_version(task, version, size); - dm_task_destroy(task); - _log_suppress = 0; - - return r; -} - -/* - * Find out device-mapper's major version number the first time - * this is called and whether or not we support it. - */ -int dm_check_version(void) -{ - char libversion[64], dmversion[64]; - const char *compat = ""; - - if (_version_checked) - return _version_ok; - - _version_checked = 1; - - if (_check_version(dmversion, sizeof(dmversion), _dm_compat)) - return 1; - - if (!_dm_compat) - goto bad; - - log_verbose("device-mapper ioctl protocol version %d failed. " - "Trying protocol version 1.", _dm_version); - _dm_version = 1; - if (_check_version(dmversion, sizeof(dmversion), 0)) { - log_verbose("Using device-mapper ioctl protocol version 1"); - return 1; - } - - compat = "(compat)"; - - dm_get_library_version(libversion, sizeof(libversion)); - - log_error("Incompatible libdevmapper %s%s and kernel driver %s", - libversion, compat, dmversion); - - bad: - _version_ok = 0; - return 0; -} - -void *dm_get_next_target(struct dm_task *dmt, void *next, - uint64_t *start, uint64_t *length, - char **target_type, char **params) -{ - struct target *t = (struct target *) next; - - if (!t) - t = dmt->head; - - if (!t) - return NULL; - - *start = t->start; - *length = t->length; - *target_type = t->type; - *params = t->params; - - return t->next; -} - -/* Unmarshall the target info returned from a status call */ -static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi) -{ - char *outbuf = (char *) dmi + dmi->data_start; - char *outptr = outbuf; - uint32_t i; - struct dm_target_spec *spec; - - for (i = 0; i < dmi->target_count; i++) { - spec = (struct dm_target_spec *) outptr; - if (!dm_task_add_target(dmt, spec->sector_start, - spec->length, - spec->target_type, - outptr + sizeof(*spec))) - return 0; - - outptr = outbuf + spec->next; - } - - return 1; -} - -int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, - uint32_t dev_minor) -{ - int r; - -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_format_dev_v1(buf, bufsize, dev_major, dev_minor); -#endif - - if (bufsize < 8) - return 0; - - r = snprintf(buf, bufsize, "%03u:%03u", dev_major, dev_minor); - if (r < 0 || r > bufsize - 1) - return 0; - - return 1; -} - -int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_info_v1(dmt, info); -#endif - - if (!dmt->dmi.v4) - return 0; - - memset(info, 0, sizeof(*info)); - - info->exists = dmt->dmi.v4->flags & DM_EXISTS_FLAG ? 1 : 0; - if (!info->exists) - return 1; - - info->suspended = dmt->dmi.v4->flags & DM_SUSPEND_FLAG ? 1 : 0; - info->read_only = dmt->dmi.v4->flags & DM_READONLY_FLAG ? 1 : 0; - info->live_table = dmt->dmi.v4->flags & DM_ACTIVE_PRESENT_FLAG ? 1 : 0; - info->inactive_table = dmt->dmi.v4->flags & DM_INACTIVE_PRESENT_FLAG ? - 1 : 0; - info->target_count = dmt->dmi.v4->target_count; - info->open_count = dmt->dmi.v4->open_count; - info->event_nr = dmt->dmi.v4->event_nr; - info->major = MAJOR(dmt->dmi.v4->dev); - info->minor = MINOR(dmt->dmi.v4->dev); - - return 1; -} - -const char *dm_task_get_name(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_name_v1(dmt); -#endif - - return (dmt->dmi.v4->name); -} - -const char *dm_task_get_uuid(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_uuid_v1(dmt); -#endif - - return (dmt->dmi.v4->uuid); -} - -struct dm_deps *dm_task_get_deps(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_deps_v1(dmt); -#endif - - return (struct dm_deps *) (((void *) dmt->dmi.v4) + - dmt->dmi.v4->data_start); -} - -struct dm_names *dm_task_get_names(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_names_v1(dmt); -#endif - - return (struct dm_names *) (((void *) dmt->dmi.v4) + - dmt->dmi.v4->data_start); -} - -int dm_task_set_ro(struct dm_task *dmt) -{ - dmt->read_only = 1; - return 1; -} - -int dm_task_set_newname(struct dm_task *dmt, const char *newname) -{ - if (!(dmt->newname = strdup(newname))) { - log_error("dm_task_set_newname: strdup(%s) failed", newname); - return 0; - } - - return 1; -} - -int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr) -{ - dmt->event_nr = event_nr; - - return 1; -} - -struct target *create_target(uint64_t start, uint64_t len, const char *type, - const char *params) -{ - struct target *t = malloc(sizeof(*t)); - - if (!t) { - log_error("create_target: malloc(%d) failed", sizeof(*t)); - return NULL; - } - - memset(t, 0, sizeof(*t)); - - if (!(t->params = strdup(params))) { - log_error("create_target: strdup(params) failed"); - goto bad; - } - - if (!(t->type = strdup(type))) { - log_error("create_target: strdup(type) failed"); - goto bad; - } - - t->start = start; - t->length = len; - return t; - - bad: - free(t->params); - free(t->type); - free(t); - return NULL; -} - -static void *_add_target(struct target *t, void *out, void *end) -{ - void *out_sp = out; - struct dm_target_spec sp; - size_t sp_size = sizeof(struct dm_target_spec); - int len; - const char no_space[] = "Ran out of memory building ioctl parameter"; - - out += sp_size; - if (out >= end) { - log_error(no_space); - return NULL; - } - - sp.status = 0; - sp.sector_start = t->start; - sp.length = t->length; - strncpy(sp.target_type, t->type, sizeof(sp.target_type)); - - len = strlen(t->params); - - if ((out + len + 1) >= end) { - log_error(no_space); - - log_error("t->params= '%s'", t->params); - return NULL; - } - strcpy((char *) out, t->params); - out += len + 1; - - /* align next block */ - out = _align(out, ALIGNMENT); - - sp.next = out - out_sp; - memcpy(out_sp, &sp, sp_size); - - return out; -} - -static struct dm_ioctl *_flatten(struct dm_task *dmt) -{ - const size_t min_size = 16 * 1024; - const int (*version)[3]; - - struct dm_ioctl *dmi; - struct target *t; - size_t len = sizeof(struct dm_ioctl); - void *b, *e; - int count = 0; - - for (t = dmt->head; t; t = t->next) { - len += sizeof(struct dm_target_spec); - len += strlen(t->params) + 1 + ALIGNMENT; - count++; - } - - if (count && dmt->newname) { - log_error("targets and newname are incompatible"); - return NULL; - } - - if (dmt->newname) - len += strlen(dmt->newname) + 1; - - /* - * Give len a minimum size so that we have space to store - * dependencies or status information. - */ - if (len < min_size) - len = min_size; - - if (!(dmi = malloc(len))) - return NULL; - - memset(dmi, 0, len); - - version = &_cmd_data_v4[dmt->type].version; - - dmi->version[0] = (*version)[0]; - dmi->version[1] = (*version)[1]; - dmi->version[2] = (*version)[2]; - - dmi->data_size = len; - dmi->data_start = sizeof(struct dm_ioctl); - - if (dmt->dev_name) - strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); - - if (dmt->type == DM_DEVICE_SUSPEND) - dmi->flags |= DM_SUSPEND_FLAG; - if (dmt->read_only) - dmi->flags |= DM_READONLY_FLAG; - - if (dmt->minor >= 0) { - if (dmt->major <= 0) { - log_error("Missing major number for persistent device"); - return NULL; - } - dmi->flags |= DM_PERSISTENT_DEV_FLAG; - dmi->dev = MKDEV(dmt->major, dmt->minor); - } - - if (dmt->uuid) - strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); - - dmi->target_count = count; - dmi->event_nr = dmt->event_nr; - - b = (void *) (dmi + 1); - e = (void *) ((char *) dmi + len); - - for (t = dmt->head; t; t = t->next) - if (!(b = _add_target(t, b, e))) - goto bad; - - if (dmt->newname) - strcpy(b, dmt->newname); - - return dmi; - - bad: - free(dmi); - return NULL; -} - -static int _create_and_load_v4(struct dm_task *dmt) -{ - struct dm_task *task; - int r; - - /* Use new task struct to create the device */ - if (!(task = dm_task_create(DM_DEVICE_CREATE))) { - log_error("Failed to create device-mapper task struct"); - return 0; - } - - /* Copy across relevant fields */ - if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { - dm_task_destroy(task); - return 0; - } - - if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) { - dm_task_destroy(task); - return 0; - } - - task->major = dmt->major; - task->minor = dmt->minor; - - r = dm_task_run(task); - dm_task_destroy(task); - if (!r) - return r; - - /* Next load the table */ - if (!(task = dm_task_create(DM_DEVICE_RELOAD))) { - log_error("Failed to create device-mapper task struct"); - return 0; - } - - /* Copy across relevant fields */ - if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { - dm_task_destroy(task); - return 0; - } - - task->read_only = dmt->read_only; - task->head = dmt->head; - task->tail = dmt->tail; - - r = dm_task_run(task); - - task->head = NULL; - task->tail = NULL; - dm_task_destroy(task); - if (!r) - return r; - - /* Use the original structure last so the info will be correct */ - dmt->type = DM_DEVICE_RESUME; - dmt->uuid = NULL; - free(dmt->uuid); - - r = dm_task_run(dmt); - - return r; -} - -int dm_task_run(struct dm_task *dmt) -{ - struct dm_ioctl *dmi = NULL; - unsigned int command; - -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_run_v1(dmt); -#endif - - if ((unsigned) dmt->type >= - (sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) { - log_error("Internal error: unknown device-mapper task %d", - dmt->type); - goto bad; - } - - command = _cmd_data_v4[dmt->type].cmd; - - /* Old-style creation had a table supplied */ - if (dmt->type == DM_DEVICE_CREATE && dmt->head) - return _create_and_load_v4(dmt); - - if (!_open_control()) - return 0; - - dmi = _flatten(dmt); - if (!dmi) { - log_error("Couldn't create ioctl argument"); - return 0; - } - - if (dmt->type == DM_DEVICE_TABLE) - dmi->flags |= DM_STATUS_TABLE_FLAG; - - dmi->flags |= DM_EXISTS_FLAG; /* FIXME */ - log_debug("dm %s %s %s %s", _cmd_data_v4[dmt->type].name, dmi->name, - dmi->uuid, dmt->newname ? dmt->newname : ""); - if (ioctl(_control_fd, command, dmi) < 0) { - if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) || - (dmt->type == DM_DEVICE_MKNODES))) { - dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */ - goto ignore_error; - } - if (_log_suppress) - log_verbose("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - else - log_error("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - goto bad; - } - - ignore_error: - switch (dmt->type) { - case DM_DEVICE_CREATE: - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); - break; - - case DM_DEVICE_REMOVE: - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_RENAME: - rename_dev_node(dmt->dev_name, dmt->newname); - break; - - case DM_DEVICE_MKNODES: - if (dmi->flags & DM_EXISTS_FLAG) - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), - MINOR(dmi->dev)); - else - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_STATUS: - case DM_DEVICE_TABLE: - case DM_DEVICE_WAITEVENT: - if (!_unmarshal_status(dmt, dmi)) - goto bad; - break; - } - - dmt->dmi.v4 = dmi; - return 1; - - bad: - free(dmi); - return 0; -} - -void dm_lib_release(void) -{ - if (_control_fd != -1) { - close(_control_fd); - _control_fd = -1; - } - update_devs(); -} - -void dm_lib_exit(void) -{ - if (_control_fd != -1) { - close(_control_fd); - _control_fd = -1; - } - _version_ok = 1; - _version_checked = 0; -} diff --git a/extras/multipath/libdevmapper/ioctl/libdm-compat.h b/extras/multipath/libdevmapper/ioctl/libdm-compat.h deleted file mode 100644 index af7a9f1f71..0000000000 --- a/extras/multipath/libdevmapper/ioctl/libdm-compat.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef _LINUX_LIBDM_COMPAT_H -#define _LINUX_LIBDM_COMPAT_H - -#include -#include -#include -#include - -struct dm_task; -struct dm_info; - -/* - * Old versions of structures for backwards compatibility. - */ - -struct dm_ioctl_v1 { - uint32_t version[3]; /* in/out */ - uint32_t data_size; /* total size of data passed in - * including this struct */ - - uint32_t data_start; /* offset to start of data - * relative to start of this struct */ - - int32_t target_count; /* in/out */ - int32_t open_count; /* out */ - uint32_t flags; /* in/out */ - - __kernel_dev_t dev; /* in/out */ - - char name[DM_NAME_LEN]; /* device name */ - char uuid[DM_UUID_LEN]; /* unique identifier for - * the block device */ -}; - -struct dm_target_spec_v1 { - int32_t status; /* used when reading from kernel only */ - uint64_t sector_start; - uint32_t length; - uint32_t next; - - char target_type[DM_MAX_TYPE_NAME]; - -}; - -struct dm_target_deps_v1 { - uint32_t count; - - __kernel_dev_t dev[0]; /* out */ -}; - -enum { - /* Top level cmds */ - DM_VERSION_CMD_V1 = 0, - DM_REMOVE_ALL_CMD_V1, - - /* device level cmds */ - DM_DEV_CREATE_CMD_V1, - DM_DEV_REMOVE_CMD_V1, - DM_DEV_RELOAD_CMD_V1, - DM_DEV_RENAME_CMD_V1, - DM_DEV_SUSPEND_CMD_V1, - DM_DEV_DEPS_CMD_V1, - DM_DEV_STATUS_CMD_V1, - - /* target level cmds */ - DM_TARGET_STATUS_CMD_V1, - DM_TARGET_WAIT_CMD_V1, -}; - -#define DM_VERSION_V1 _IOWR(DM_IOCTL, DM_VERSION_CMD_V1, struct dm_ioctl) -#define DM_REMOVE_ALL_V1 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD_V1, struct dm_ioctl) - -#define DM_DEV_CREATE_V1 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD_V1, struct dm_ioctl) -#define DM_DEV_REMOVE_V1 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD_V1, struct dm_ioctl) -#define DM_DEV_RELOAD_V1 _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD_V1, struct dm_ioctl) -#define DM_DEV_SUSPEND_V1 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD_V1, struct dm_ioctl) -#define DM_DEV_RENAME_V1 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD_V1, struct dm_ioctl) -#define DM_DEV_DEPS_V1 _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD_V1, struct dm_ioctl) -#define DM_DEV_STATUS_V1 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD_V1, struct dm_ioctl) - -#define DM_TARGET_STATUS_V1 _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD_V1, struct dm_ioctl) -#define DM_TARGET_WAIT_V1 _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD_V1, struct dm_ioctl) - -/* *INDENT-OFF* */ -static struct cmd_data _cmd_data_v1[] = { - { "create", DM_DEV_CREATE_V1, {1, 0, 0} }, - { "reload", DM_DEV_RELOAD_V1, {1, 0, 0} }, - { "remove", DM_DEV_REMOVE_V1, {1, 0, 0} }, - { "remove_all", DM_REMOVE_ALL_V1, {1, 0, 0} }, - { "suspend", DM_DEV_SUSPEND_V1, {1, 0, 0} }, - { "resume", DM_DEV_SUSPEND_V1, {1, 0, 0} }, - { "info", DM_DEV_STATUS_V1, {1, 0, 0} }, - { "deps", DM_DEV_DEPS_V1, {1, 0, 0} }, - { "rename", DM_DEV_RENAME_V1, {1, 0, 0} }, - { "version", DM_VERSION_V1, {1, 0, 0} }, - { "status", DM_TARGET_STATUS_V1, {1, 0, 0} }, - { "table", DM_TARGET_STATUS_V1, {1, 0, 0} }, - { "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} }, - { "names", 0, {4, 0, 0} }, - { "clear", 0, {4, 0, 0} }, - { "mknodes", 0, {4, 0, 0} }, -}; -/* *INDENT-ON* */ - -#endif diff --git a/extras/multipath/libdevmapper/ioctl/libdm-targets.h b/extras/multipath/libdevmapper/ioctl/libdm-targets.h deleted file mode 100644 index a8c0e20547..0000000000 --- a/extras/multipath/libdevmapper/ioctl/libdm-targets.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef LIB_DMTARGETS_H -#define LIB_DMTARGETS_H - -#include - -struct dm_ioctl; -struct dm_ioctl_v1; - -struct target { - uint64_t start; - uint64_t length; - char *type; - char *params; - - struct target *next; -}; - -struct dm_task { - int type; - char *dev_name; - - struct target *head, *tail; - - int read_only; - uint32_t event_nr; - int major; - int minor; - union { - struct dm_ioctl *v4; - struct dm_ioctl_v1 *v1; - } dmi; - char *newname; - - char *uuid; -}; - -struct cmd_data { - const char *name; - const int cmd; - const int version[3]; -}; - -int dm_check_version(void); - -#endif diff --git a/extras/multipath/libdevmapper/libdevmapper.h b/extras/multipath/libdevmapper/libdevmapper.h deleted file mode 100644 index 6549af3641..0000000000 --- a/extras/multipath/libdevmapper/libdevmapper.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef LIB_DEVICE_MAPPER_H -#define LIB_DEVICE_MAPPER_H - -#include -#include - -#ifdef linux -# include -#endif - -/* - * Since it is quite laborious to build the ioctl - * arguments for the device-mapper people are - * encouraged to use this library. - * - * You will need to build a struct dm_task for - * each ioctl command you want to execute. - */ - -typedef void (*dm_log_fn) (int level, const char *file, int line, - const char *f, ...); - -/* - * The library user may wish to register their own - * logging function, by default errors go to - * stderr. - */ -void dm_log_init(dm_log_fn fn); -void dm_log_init_verbose(int level); - -enum { - DM_DEVICE_CREATE, - DM_DEVICE_RELOAD, - DM_DEVICE_REMOVE, - DM_DEVICE_REMOVE_ALL, - - DM_DEVICE_SUSPEND, - DM_DEVICE_RESUME, - - DM_DEVICE_INFO, - DM_DEVICE_DEPS, - DM_DEVICE_RENAME, - - DM_DEVICE_VERSION, - - DM_DEVICE_STATUS, - DM_DEVICE_TABLE, - DM_DEVICE_WAITEVENT, - - DM_DEVICE_LIST, - - DM_DEVICE_CLEAR, - - DM_DEVICE_MKNODES -}; - -struct dm_task; - -struct dm_task *dm_task_create(int type); -void dm_task_destroy(struct dm_task *dmt); - -int dm_task_set_name(struct dm_task *dmt, const char *name); -int dm_task_set_uuid(struct dm_task *dmt, const char *uuid); - -/* - * Retrieve attributes after an info. - */ -struct dm_info { - int exists; - int suspended; - int live_table; - int inactive_table; - int32_t open_count; - uint32_t event_nr; - uint32_t major; - uint32_t minor; /* minor device number */ - int read_only; /* 0:read-write; 1:read-only */ - - int32_t target_count; -}; - -struct dm_deps { - uint32_t count; - uint32_t filler; - uint64_t device[0]; -}; - -struct dm_names { - uint64_t dev; - uint32_t next; /* Offset to next struct from start of this struct */ - char name[0]; -}; - -int dm_get_library_version(char *version, size_t size); -int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size); -int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi); -const char *dm_task_get_name(struct dm_task *dmt); -const char *dm_task_get_uuid(struct dm_task *dmt); - -struct dm_deps *dm_task_get_deps(struct dm_task *dmt); -struct dm_names *dm_task_get_names(struct dm_task *dmt); - -int dm_task_set_ro(struct dm_task *dmt); -int dm_task_set_newname(struct dm_task *dmt, const char *newname); -int dm_task_set_minor(struct dm_task *dmt, int minor); -int dm_task_set_major(struct dm_task *dmt, int major); -int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr); - -/* - * Use these to prepare for a create or reload. - */ -int dm_task_add_target(struct dm_task *dmt, - uint64_t start, - uint64_t size, const char *ttype, const char *params); - -/* - * Format major/minor numbers correctly for input to driver - */ -int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor); - -/* Use this to retrive target information returned from a STATUS call */ -void *dm_get_next_target(struct dm_task *dmt, - void *next, uint64_t *start, uint64_t *length, - char **target_type, char **params); - -/* - * Call this to actually run the ioctl. - */ -int dm_task_run(struct dm_task *dmt); - -/* - * Configure the device-mapper directory - */ -int dm_set_dev_dir(const char *dir); -const char *dm_dir(void); - -/* Release library resources */ -void dm_lib_release(void); -void dm_lib_exit(void); - -#endif /* LIB_DEVICE_MAPPER_H */ diff --git a/extras/multipath/libdevmapper/libdm-common.c b/extras/multipath/libdevmapper/libdm-common.c deleted file mode 100644 index b0affd1eed..0000000000 --- a/extras/multipath/libdevmapper/libdm-common.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#include "libdm-targets.h" -#include "libdm-common.h" -#include "list.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEV_DIR "/dev/" - -static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; - -static int _verbose = 0; - -/* - * Library users can provide their own logging - * function. - */ -static void _default_log(int level, const char *file, int line, - const char *f, ...) -{ - va_list ap; - - if (level > _LOG_WARN && !_verbose) - return; - - va_start(ap, f); - - if (level < _LOG_WARN) - vfprintf(stderr, f, ap); - else - vprintf(f, ap); - - va_end(ap); - - if (level < _LOG_WARN) - fprintf(stderr, "\n"); - else - fprintf(stdout, "\n"); -} - -dm_log_fn _log = _default_log; - -void dm_log_init(dm_log_fn fn) -{ - _log = fn; -} - -void dm_log_init_verbose(int level) -{ - _verbose = level; -} - -static void _build_dev_path(char *buffer, size_t len, const char *dev_name) -{ - /* If there's a /, assume caller knows what they're doing */ - if (strchr(dev_name, '/')) - snprintf(buffer, len, "%s", dev_name); - else - snprintf(buffer, len, "%s/%s", _dm_dir, dev_name); -} - -int dm_get_library_version(char *version, size_t size) -{ - strncpy(version, DM_LIB_VERSION, size); - return 1; -} - -struct dm_task *dm_task_create(int type) -{ - struct dm_task *dmt = malloc(sizeof(*dmt)); - - if (!dm_check_version()) - return NULL; - - if (!dmt) { - log_error("dm_task_create: malloc(%d) failed", sizeof(*dmt)); - return NULL; - } - - memset(dmt, 0, sizeof(*dmt)); - - dmt->type = type; - dmt->minor = -1; - dmt->major = -1; - - return dmt; -} - -int dm_task_set_name(struct dm_task *dmt, const char *name) -{ - char *pos; - char path[PATH_MAX]; - struct stat st1, st2; - - if (dmt->dev_name) { - free(dmt->dev_name); - dmt->dev_name = NULL; - } - - /* If path was supplied, remove it if it points to the same device - * as its last component. - */ - if ((pos = strrchr(name, '/'))) { - snprintf(path, sizeof(path), "%s/%s", _dm_dir, pos + 1); - - if (stat(name, &st1) || stat(path, &st2) || - !(st1.st_dev == st2.st_dev)) { - log_error("dm_task_set_name: Device %s not found", - name); - return 0; - } - - name = pos + 1; - } - - if (!(dmt->dev_name = strdup(name))) { - log_error("dm_task_set_name: strdup(%s) failed", name); - return 0; - } - - return 1; -} - -int dm_task_set_uuid(struct dm_task *dmt, const char *uuid) -{ - if (dmt->uuid) { - free(dmt->uuid); - dmt->uuid = NULL; - } - - if (!(dmt->uuid = strdup(uuid))) { - log_error("dm_task_set_uuid: strdup(%s) failed", uuid); - return 0; - } - - return 1; -} - -int dm_task_set_major(struct dm_task *dmt, int major) -{ - dmt->major = major; - log_debug("Setting major: %d", dmt->major); - - return 1; -} - -int dm_task_set_minor(struct dm_task *dmt, int minor) -{ - dmt->minor = minor; - log_debug("Setting minor: %d", dmt->minor); - - return 1; -} - -int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size, - const char *ttype, const char *params) -{ - struct target *t = create_target(start, size, ttype, params); - - if (!t) - return 0; - - if (!dmt->head) - dmt->head = dmt->tail = t; - else { - dmt->tail->next = t; - dmt->tail = t; - } - - return 1; -} - -static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) -{ - char path[PATH_MAX]; - struct stat info; - dev_t dev = MKDEV(major, minor); - - _build_dev_path(path, sizeof(path), dev_name); - - if (stat(path, &info) >= 0) { - if (!S_ISBLK(info.st_mode)) { - log_error("A non-block device file at '%s' " - "is already present", path); - return 0; - } - - if (info.st_rdev == dev) - return 1; - - if (unlink(path) < 0) { - log_error("Unable to unlink device node for '%s'", - dev_name); - return 0; - } - } - - if (mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, dev) < 0) { - log_error("Unable to make device node for '%s'", dev_name); - return 0; - } - - return 1; -} - -static int _rename_dev_node(const char *old_name, const char *new_name) -{ - char oldpath[PATH_MAX]; - char newpath[PATH_MAX]; - struct stat info; - - _build_dev_path(oldpath, sizeof(oldpath), old_name); - _build_dev_path(newpath, sizeof(newpath), new_name); - - if (stat(newpath, &info) == 0) { - if (!S_ISBLK(info.st_mode)) { - log_error("A non-block device file at '%s' " - "is already present", newpath); - return 0; - } - - if (unlink(newpath) < 0) { - if (errno == EPERM) { - /* devfs, entry has already been renamed */ - return 1; - } - log_error("Unable to unlink device node for '%s'", - new_name); - return 0; - } - } - - if (rename(oldpath, newpath) < 0) { - log_error("Unable to rename device node from '%s' to '%s'", - old_name, new_name); - return 0; - } - - return 1; -} - -static int _rm_dev_node(const char *dev_name) -{ - char path[PATH_MAX]; - struct stat info; - - _build_dev_path(path, sizeof(path), dev_name); - - if (stat(path, &info) < 0) - return 1; - - if (unlink(path) < 0) { - log_error("Unable to unlink device node for '%s'", dev_name); - return 0; - } - - return 1; -} - -typedef enum { - NODE_ADD, - NODE_DEL, - NODE_RENAME -} node_op_t; - -static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major, - uint32_t minor, const char *old_name) -{ - switch (type) { - case NODE_ADD: - return _add_dev_node(dev_name, major, minor); - case NODE_DEL: - return _rm_dev_node(dev_name); - case NODE_RENAME: - return _rename_dev_node(old_name, dev_name); - } - - return 1; -} - -static LIST_INIT(_node_ops); - -struct node_op_parms { - struct list list; - node_op_t type; - char *dev_name; - uint32_t major; - uint32_t minor; - char *old_name; - char names[0]; -}; - -static void _store_str(char **pos, char **ptr, const char *str) -{ - strcpy(*pos, str); - *ptr = *pos; - *pos += strlen(*ptr) + 1; -} - -static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major, - uint32_t minor, const char *old_name) -{ - struct node_op_parms *nop; - size_t len = strlen(dev_name) + strlen(old_name) + 2; - char *pos; - - if (!(nop = malloc(sizeof(*nop) + len))) { - log_error("Insufficient memory to stack mknod operation"); - return 0; - } - - pos = nop->names; - nop->type = type; - nop->major = major; - nop->minor = minor; - - _store_str(&pos, &nop->dev_name, dev_name); - _store_str(&pos, &nop->old_name, old_name); - - list_add(&_node_ops, &nop->list); - - return 1; -} - -static void _pop_node_ops(void) -{ - struct list *noph, *nopht; - struct node_op_parms *nop; - - list_iterate_safe(noph, nopht, &_node_ops) { - nop = list_item(noph, struct node_op_parms); - _do_node_op(nop->type, nop->dev_name, nop->major, nop->minor, - nop->old_name); - list_del(&nop->list); - free(nop); - } -} - -int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) -{ - return _stack_node_op(NODE_ADD, dev_name, major, minor, ""); -} - -int rename_dev_node(const char *old_name, const char *new_name) -{ - return _stack_node_op(NODE_RENAME, new_name, 0, 0, old_name); -} - -int rm_dev_node(const char *dev_name) -{ - return _stack_node_op(NODE_DEL, dev_name, 0, 0, ""); -} - -void update_devs(void) -{ - _pop_node_ops(); -} - -int dm_set_dev_dir(const char *dir) -{ - snprintf(_dm_dir, sizeof(_dm_dir), "%s%s", dir, DM_DIR); - return 1; -} - -const char *dm_dir(void) -{ - return _dm_dir; -} diff --git a/extras/multipath/libdevmapper/libdm-common.h b/extras/multipath/libdevmapper/libdm-common.h deleted file mode 100644 index 2b71242861..0000000000 --- a/extras/multipath/libdevmapper/libdm-common.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef LIB_DMCOMMON_H -#define LIB_DMCOMMON_H - -#include "libdevmapper.h" - -#define _LOG_DEBUG 7 -#define _LOG_INFO 6 -#define _LOG_NOTICE 5 -#define _LOG_WARN 4 -#define _LOG_ERR 3 -#define _LOG_FATAL 2 - -extern dm_log_fn _log; - -#define log_error(msg, x...) _log(_LOG_ERR, __FILE__, __LINE__, msg, ## x) -#define log_print(msg, x...) _log(_LOG_WARN, __FILE__, __LINE__, msg, ## x) -#define log_verbose(msg, x...) _log(_LOG_NOTICE, __FILE__, __LINE__, msg, ## x) -#define log_very_verbose(msg, x...) _log(_LOG_INFO, __FILE__, __LINE__, msg, ## x) -#define log_debug(msg, x...) _log(_LOG_DEBUG, __FILE__, __LINE__, msg, ## x) - -struct target *create_target(uint64_t start, - uint64_t len, - const char *type, const char *params); - -int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major); -int rm_dev_node(const char *dev_name); -int rename_dev_node(const char *old_name, const char *new_name); -void update_devs(void); - -#define DM_LIB_VERSION "1.00.07-ioctl (2003-11-21)" - -#endif diff --git a/extras/multipath/libdevmapper/list.h b/extras/multipath/libdevmapper/list.h deleted file mode 100644 index df3d32aea8..0000000000 --- a/extras/multipath/libdevmapper/list.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software - * - * This file is released under the LGPL. - */ - -#ifndef _LVM_LIST_H -#define _LVM_LIST_H - -#include - -struct list { - struct list *n, *p; -}; - -#define LIST_INIT(name) struct list name = { &(name), &(name) } - -static inline void list_init(struct list *head) -{ - head->n = head->p = head; -} - -static inline void list_add(struct list *head, struct list *elem) -{ - assert(head->n); - - elem->n = head; - elem->p = head->p; - - head->p->n = elem; - head->p = elem; -} - -static inline void list_add_h(struct list *head, struct list *elem) -{ - assert(head->n); - - elem->n = head->n; - elem->p = head; - - head->n->p = elem; - head->n = elem; -} - -static inline void list_del(struct list *elem) -{ - elem->n->p = elem->p; - elem->p->n = elem->n; -} - -static inline int list_empty(struct list *head) -{ - return head->n == head; -} - -static inline int list_end(struct list *head, struct list *elem) -{ - return elem->n == head; -} - -static inline struct list *list_next(struct list *head, struct list *elem) -{ - return (list_end(head, elem) ? NULL : elem->n); -} - -#define list_iterate(v, head) \ - for (v = (head)->n; v != head; v = v->n) - -#define list_uniterate(v, head, start) \ - for (v = (start)->p; v != head; v = v->p) - -#define list_iterate_safe(v, t, head) \ - for (v = (head)->n, t = v->n; v != head; v = t, t = v->n) - -static inline unsigned int list_size(const struct list *head) -{ - unsigned int s = 0; - const struct list *v; - - list_iterate(v, head) - s++; - - return s; -} - -#define list_item(v, t) \ - ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list)) - -#define list_struct_base(v, t, h) \ - ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h)) - -/* Given a known element in a known structure, locate another */ -#define struct_field(v, t, e, f) \ - (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f) - -/* Given a known element in a known structure, locate the list head */ -#define list_head(v, t, e) struct_field(v, t, e, list) - -#endif diff --git a/extras/multipath/main.c b/extras/multipath/main.c deleted file mode 100644 index dfaa6867dd..0000000000 --- a/extras/multipath/main.c +++ /dev/null @@ -1,705 +0,0 @@ -/* - * Soft: multipath device mapper target autoconfig - * - * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ - * - * Author: Copyright (C) 2003 Christophe Varoqui - * - * 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. - * - * 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 "libdevmapper/libdevmapper.h" -#include "main.h" -#include "devinfo.h" - -/* White list switch */ -static int -get_unique_id(struct path * mypath) -{ - int i; - static struct { - char * vendor; - char * product; - int iopolicy; - int (*getuid) (char *, char *); - } wlist[] = { - {"COMPAQ ", "HSV110 (C)COMPAQ", GROUP_BY_SERIAL, &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 ", GROUP_BY_SERIAL, &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 VOLUME ", GROUP_BY_SERIAL, &get_evpd_wwid}, - {"DEC ", "HSG80 ", GROUP_BY_SERIAL, &get_evpd_wwid}, - {"HP ", "HSV100 ", GROUP_BY_SERIAL, &get_evpd_wwid}, - {"HP ", "A6189A ", MULTIBUS, &get_evpd_wwid}, - {"HP ", "OPEN- ", MULTIBUS, &get_evpd_wwid}, - {"DDN ", "SAN DataDirector", MULTIBUS, &get_evpd_wwid}, - {"FSC ", "CentricStor ", MULTIBUS, &get_evpd_wwid}, - {"HITACHI ", "DF400 ", MULTIBUS, &get_evpd_wwid}, - {"HITACHI ", "DF500 ", MULTIBUS, &get_evpd_wwid}, - {"HITACHI ", "DF600 ", MULTIBUS, &get_evpd_wwid}, - {"IBM ", "ProFibre 4000R ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9100 ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9300 ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9400 ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9500 ", MULTIBUS, &get_evpd_wwid}, - {NULL, NULL, 0, NULL}, - }; - - for (i = 0; wlist[i].vendor; i++) { - if (strncmp(mypath->vendor_id, wlist[i].vendor, 8) == 0 && - strncmp(mypath->product_id, wlist[i].product, 16) == 0) { - mypath->iopolicy = wlist[i].iopolicy; - if (!wlist[i].getuid(mypath->sg_dev, mypath->wwid)) - return 0; - } - } - return 1; -} - -static int -blacklist (char * dev) { - int i; - static struct { - char * headstr; - int lengh; - } blist[] = { - {"cciss", 5}, - {"hd", 2}, - {"md", 2}, - {"dm", 2}, - {"sr", 2}, - {"scd", 3}, - {"ram", 3}, - {"raw", 3}, - {NULL, 0}, - }; - - for (i = 0; blist[i].lengh; i++) { - if (strncmp(dev, blist[i].headstr, blist[i].lengh) == 0) - return 1; - } - return 0; -} - -static int -get_all_paths_sysfs(struct env * conf, struct path * all_paths) -{ - int k=0; - struct sysfs_directory * sdir; - struct sysfs_directory * devp; - struct sysfs_link * linkp; - char refwwid[WWID_SIZE]; - char empty_buff[WWID_SIZE]; - char buff[FILE_NAME_SIZE]; - char path[FILE_NAME_SIZE]; - struct path curpath; - - /* if called from hotplug, only consider the paths that relate */ - /* to the device pointed by conf.hotplugdev */ - memset(empty_buff, 0, WWID_SIZE); - memset(refwwid, 0, WWID_SIZE); - if (strncmp("/devices", conf->hotplugdev, 8) == 0) { - sprintf(buff, "%s%s/block", - conf->sysfs_path, conf->hotplugdev); - memset(conf->hotplugdev, 0, FILE_NAME_SIZE); - - /* if called from hotplug but with no block, leave */ - if (0 > readlink(buff, conf->hotplugdev, FILE_NAME_SIZE)) - return 0; - - basename(conf->hotplugdev, buff); - sprintf(curpath.sg_dev, "/dev/%s", buff); - - get_lun_strings(curpath.vendor_id, - curpath.product_id, - curpath.rev, - curpath.sg_dev); - get_serial(curpath.serial, curpath.sg_dev); - if (!get_unique_id(&curpath)) - return 0; - strcpy(refwwid, curpath.wwid); - memset(&curpath, 0, sizeof(path)); - } - - sprintf(path, "%s/block", conf->sysfs_path); - sdir = sysfs_open_directory(path); - sysfs_read_directory(sdir); - - dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { - if (blacklist(devp->name)) - continue; - - sysfs_read_directory(devp); - - if(devp->links == NULL) - continue; - - dlist_for_each_data(devp->links, linkp, struct sysfs_link) { - if (!strncmp(linkp->name, "device", 6)) - break; - } - - if (linkp == NULL) { - continue; - } - - basename(devp->path, buff); - sprintf(curpath.sg_dev, "/dev/%s", buff); - - get_lun_strings(curpath.vendor_id, - curpath.product_id, - curpath.rev, - curpath.sg_dev); - get_serial(curpath.serial, curpath.sg_dev); - if(!get_unique_id(&curpath)) { - memset(&curpath, 0, sizeof(path)); - continue; - } - - if (memcmp(empty_buff, refwwid, WWID_SIZE) != 0 && - strncmp(curpath.wwid, refwwid, WWID_SIZE) != 0) { - memset(&curpath, 0, sizeof(path)); - continue; - } - - strcpy(all_paths[k].sg_dev, curpath.sg_dev); - strcpy(all_paths[k].dev, curpath.sg_dev); - strcpy(all_paths[k].wwid, curpath.wwid); - strcpy(all_paths[k].vendor_id, curpath.vendor_id); - strcpy(all_paths[k].product_id, curpath.product_id); - all_paths[k].iopolicy = curpath.iopolicy; - - /* done with curpath, zero for reuse */ - memset(&curpath, 0, sizeof(path)); - - basename(linkp->target, buff); - sscanf(buff, "%i:%i:%i:%i", - &all_paths[k].sg_id.host_no, - &all_paths[k].sg_id.channel, - &all_paths[k].sg_id.scsi_id, - &all_paths[k].sg_id.lun); - k++; - } - sysfs_close_directory(sdir); - return 0; -} - -static int -get_all_paths_nosysfs(struct env * conf, struct path * all_paths, - struct scsi_dev * all_scsi_ids) -{ - int k, i, fd; - char buff[FILE_NAME_SIZE]; - char file_name[FILE_NAME_SIZE]; - - for (k = 0; k < conf->max_devs; k++) { - strcpy(file_name, "/dev/sg"); - sprintf(buff, "%d", k); - strncat(file_name, buff, FILE_NAME_SIZE); - strcpy(all_paths[k].sg_dev, file_name); - - get_lun_strings(all_paths[k].vendor_id, - all_paths[k].product_id, - all_paths[k].rev, - all_paths[k].sg_dev); - get_serial(all_paths[k].serial, all_paths[k].sg_dev); - if (!get_unique_id(&all_paths[k])) - continue; - - if ((fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) - return 0; - - if (0 > ioctl(fd, SG_GET_SCSI_ID, &(all_paths[k].sg_id))) - printf("device %s failed on sg ioctl, skip\n", - file_name); - - close(fd); - - for (i = 0; i < conf->max_devs; i++) { - if ((all_paths[k].sg_id.host_no == - all_scsi_ids[i].host_no) - && (all_paths[k].sg_id.scsi_id == - (all_scsi_ids[i].scsi_id.dev_id & 0xff)) - && (all_paths[k].sg_id.lun == - ((all_scsi_ids[i].scsi_id.dev_id >> 8) & 0xff)) - && (all_paths[k].sg_id.channel == - ((all_scsi_ids[i].scsi_id. - dev_id >> 16) & 0xff))) { - strcpy(all_paths[k].dev, all_scsi_ids[i].dev); - break; - } - } - } - return 0; -} - -static int -get_all_scsi_ids(struct env * conf, struct scsi_dev * all_scsi_ids) -{ - int k, big, little, res, host_no, fd; - char buff[64]; - char fname[FILE_NAME_SIZE]; - struct scsi_idlun my_scsi_id; - - for (k = 0; k < conf->max_devs; k++) { - strcpy(fname, "/dev/sd"); - if (k < 26) { - buff[0] = 'a' + (char) k; - buff[1] = '\0'; - strcat(fname, buff); - } else if (k <= 255) { - /* assumes sequence goes x,y,z,aa,ab,ac etc */ - big = k / 26; - little = k - (26 * big); - big = big - 1; - - buff[0] = 'a' + (char) big; - buff[1] = 'a' + (char) little; - buff[2] = '\0'; - strcat(fname, buff); - } else - strcat(fname, "xxxx"); - - if ((fd = open(fname, O_RDONLY)) < 0) { - if (conf->verbose) - fprintf(stderr, "can't open %s. mknod ?", - fname); - continue; - } - - res = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &my_scsi_id); - if (res < 0) { - close(fd); - printf("Could not get scsi idlun\n"); - continue; - } - - res = ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &host_no); - if (res < 0) { - close(fd); - printf("Could not get host_no\n"); - continue; - } - - close(fd); - - strcpy(all_scsi_ids[k].dev, fname); - all_scsi_ids[k].scsi_id = my_scsi_id; - all_scsi_ids[k].host_no = host_no; - } - return 0; -} - -/* print_path style */ -#define ALL 0 -#define NOWWID 1 - -static void -print_path(struct path * all_paths, int k, int style) -{ - if (style != NOWWID) - printf("%s ", all_paths[k].wwid); - else - printf(" \\_"); - printf("(%i %i %i %i) ", - all_paths[k].sg_id.host_no, - all_paths[k].sg_id.channel, - all_paths[k].sg_id.scsi_id, all_paths[k].sg_id.lun); - if(0 != strcmp(all_paths[k].sg_dev, all_paths[k].dev)) - printf("%s ", all_paths[k].sg_dev); - printf("%s ", all_paths[k].dev); - printf("[%.16s]\n", all_paths[k].product_id); -} - -static void -print_all_path(struct env * conf, struct path * all_paths) -{ - int k; - char empty_buff[WWID_SIZE]; - - memset(empty_buff, 0, WWID_SIZE); - for (k = 0; k < conf->max_devs; k++) { - if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) - continue; - print_path(all_paths, k, ALL); - } -} - -static void -print_all_mp(struct path * all_paths, struct multipath * mp, int nmp) -{ - int k, i; - - for (k = 0; k <= nmp; k++) { - printf("%s\n", mp[k].wwid); - for (i = 0; i <= mp[k].npaths; i++) - print_path(all_paths, PINDEX(k,i), NOWWID); - } -} - -static int -coalesce_paths(struct env * conf, struct multipath * mp, - struct path * all_paths) -{ - int k, i, nmp, np, already_done; - char empty_buff[WWID_SIZE]; - - nmp = -1; - already_done = 0; - memset(empty_buff, 0, WWID_SIZE); - - for (k = 0; k < conf->max_devs - 1; k++) { - /* skip this path for some reason */ - - /* 1. if path has no unique id */ - if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) - continue; - - /* 2. if mp with this uid already instanciated */ - for (i = 0; i <= nmp; i++) { - if (0 == strcmp(mp[i].wwid, all_paths[k].wwid)) - already_done = 1; - } - if (already_done) { - already_done = 0; - continue; - } - - /* at this point, we know we really got a new mp */ - np = 0; - nmp++; - strcpy(mp[nmp].wwid, all_paths[k].wwid); - PINDEX(nmp,np) = k; - - if (mp[nmp].size == 0) - mp[nmp].size = get_disk_size(all_paths[k].dev); - - for (i = k + 1; i < conf->max_devs; i++) { - if (0 == strcmp(all_paths[k].wwid, all_paths[i].wwid)) { - np++; - PINDEX(nmp,np) = i; - mp[nmp].npaths = np; - } - } - } - return nmp; -} - -static void -group_by_serial(struct multipath * mp, struct path * all_paths, char * str) { - int path_count, pg_count = 0; - int i, k; - int * bitmap; - char path_buff[FILE_NAME_SIZE]; - char pg_buff[FILE_NAME_SIZE]; - char * path_buff_p = &path_buff[0]; - char * pg_buff_p = &pg_buff[0]; - - /* init the bitmap */ - bitmap = malloc((mp->npaths + 1) * sizeof(int)); - memset(bitmap, 0, (mp->npaths + 1) * sizeof(int)); - - for (i = 0; i <= mp->npaths; i++) { - if (bitmap[i]) - continue; - - /* here, we really got a new pg */ - pg_count++; - path_count = 1; - memset(&path_buff, 0, FILE_NAME_SIZE * sizeof(char)); - path_buff_p = &path_buff[0]; - - path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[i]].dev); - bitmap[i] = 1; - - for (k = i + 1; k <= mp->npaths; k++) { - if (bitmap[k]) - continue; - if (0 == strcmp(all_paths[mp->pindex[i]].serial, - all_paths[mp->pindex[k]].serial)) { - path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[k]].dev); - bitmap[k] = 1; - path_count++; - } - } - pg_buff_p += sprintf(pg_buff_p, " 1 round-robin %i 0%s", - path_count, path_buff); - } - sprintf(str, " %i%s", pg_count, pg_buff); - free(bitmap); -} - -static int -dm_simplecmd(int task, const char *name) { - int r = 0; - struct dm_task *dmt; - - if (!(dmt = dm_task_create(task))) - return 0; - - if (!dm_task_set_name(dmt, name)) - goto out; - - r = dm_task_run(dmt); - - out: - dm_task_destroy(dmt); - return r; -} - -static int -dm_addmap(int task, const char *name, const char *params, long size) { - struct dm_task *dmt; - - if (!(dmt = dm_task_create(task))) - return 0; - - if (!dm_task_set_name(dmt, name)) - goto addout; - - if (!dm_task_add_target(dmt, 0, size, DM_TARGET, params)) - goto addout; - - if (!dm_task_run(dmt)) - goto addout; - - addout: - dm_task_destroy(dmt); - return 1; -} - -static int -setup_map(struct env * conf, struct path * all_paths, - struct multipath * mp, int index, int op) -{ - char params[255]; - char * params_p; - int i, np; - - /* defaults for multipath target */ - int dm_pg_prio = 1; - char * dm_ps_name = "round-robin"; - int dm_ps_nr_args = 0; - - params_p = ¶ms[0]; - - np = 0; - for (i=0; i<=mp[index].npaths; i++) { - if (0 == all_paths[PINDEX(index,i)].sg_id.scsi_type) - np++; - } - - if (np < 1) - return 0; - - if ((all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && - conf->iopolicy == -1) || conf->iopolicy == MULTIBUS) { - params_p += sprintf(params_p, " 1 %i %s %i %i", - dm_pg_prio, dm_ps_name, np, dm_ps_nr_args); - - for (i=0; i<=mp[index].npaths; i++) { - if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) - continue; - params_p += sprintf(params_p, " %s", - all_paths[PINDEX(index,i)].dev); - } - } - - if ((all_paths[PINDEX(index,0)].iopolicy == FAILOVER && - conf->iopolicy == -1) || conf->iopolicy == FAILOVER) { - params_p += sprintf(params_p, " %i", mp[index].npaths + 1); - for (i=0; i<=mp[index].npaths; i++) { - if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) - continue; - params_p += sprintf(params_p, " %i %s ", - dm_pg_prio, dm_ps_name); - params_p += sprintf(params_p, "1 %i", - dm_ps_nr_args); - params_p += sprintf(params_p, " %s", - all_paths[PINDEX(index,i)].dev); - } - } - - if ((all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_SERIAL && - conf->iopolicy == -1) || conf->iopolicy == GROUP_BY_SERIAL) { - group_by_serial(&mp[index], all_paths, params_p); - } - - if (mp[index].size < 0) - return 0; - - if (!conf->quiet) { - if (op == DM_DEVICE_RELOAD) - printf("U:"); - if (op == DM_DEVICE_CREATE) - printf("N:"); - printf("%s:0 %li %s %s\n", - mp[index].wwid, mp[index].size, DM_TARGET, params); - } - - if (op == DM_DEVICE_RELOAD) - dm_simplecmd(DM_DEVICE_SUSPEND, mp[index].wwid); - - dm_addmap(op, mp[index].wwid, params, mp[index].size); - - if (op == DM_DEVICE_RELOAD) - dm_simplecmd(DM_DEVICE_RESUME, mp[index].wwid); - - return 1; -} - -static int -map_present(char * str) -{ - int r = 0; - struct dm_task *dmt; - struct dm_names *names; - unsigned next = 0; - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) - return 0; - - if (!dm_task_run(dmt)) - goto out; - - if (!(names = dm_task_get_names(dmt))) - goto out; - - if (!names->dev) { - goto out; - } - - do { - if (0 == strcmp(names->name, str)) - r = 1; - next = names->next; - names = (void *) names + next; - } while (next); - - out: - dm_task_destroy(dmt); - return r; -} - -static void -usage(char * progname) -{ - fprintf(stderr, VERSION_STRING); - fprintf(stderr, "Usage: %s [-v|-q] [-d] [-m max_devs]", - progname); - fprintf(stderr, "[-p failover|multibus|group_by_serial] [device]\n"); - fprintf(stderr, "\t-v\t\tverbose, print all paths and multipaths\n"); - fprintf(stderr, "\t-q\t\tquiet, no output at all\n"); - fprintf(stderr, "\t-d\t\tdry run, do not create or update devmaps\n"); - fprintf(stderr, "\t-m max_devs\tscan {max_devs} devices at most\n"); - fprintf(stderr, "\t-p policy\tforce maps to specified policy :\n"); - fprintf(stderr, "\t failover\t\t- 1 path per priority group\n"); - fprintf(stderr, "\t multibus\t\t- all paths in 1 priority group\n"); - fprintf(stderr, "\t group_by_serial\t- 1 priority group per serial\n"); - fprintf(stderr, "\tdevice\t\tlimit scope to the device's multipath\n"); - fprintf(stderr, "\t\t\t(hotplug-style $DEVPATH reference)\n"); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - struct multipath * mp; - struct path * all_paths; - struct scsi_dev * all_scsi_ids; - struct env conf; - int i, k, nmp; - - /* Default behaviour */ - conf.max_devs = MAX_DEVS; - conf.dry_run = 0; /* 1 == Do not Create/Update devmaps */ - conf.verbose = 0; /* 1 == Print all_paths and mp */ - conf.quiet = 0; /* 1 == Do not even print devmaps */ - conf.iopolicy = -1; /* Apply the defaults in get_unique_id() */ - - for (i = 1; i < argc; ++i) { - if (0 == strcmp("-v", argv[i])) { - if (conf.quiet == 1) - usage(argv[0]); - conf.verbose = 1; - } else if (0 == strcmp("-m", argv[i])) { - conf.max_devs = atoi(argv[++i]); - if (conf.max_devs < 2) - usage(argv[0]); - } else if (0 == strcmp("-q", argv[i])) { - if (conf.verbose == 1) - usage(argv[0]); - conf.quiet = 1; - } else if (0 == strcmp("-d", argv[i])) - conf.dry_run = 1; - else if (0 == strcmp("-p", argv[i])) { - i++; - if (!strcmp(argv[i], "failover")) - conf.iopolicy = FAILOVER; - if (!strcmp(argv[i], "multibus")) - conf.iopolicy = MULTIBUS; - if (!strcmp(argv[i], "group_by_serial")) - conf.iopolicy = GROUP_BY_SERIAL; - } else if (*argv[i] == '-') { - fprintf(stderr, "Unknown switch: %s\n", argv[i]); - usage(argv[0]); - } else - strncpy(conf.hotplugdev, argv[i], FILE_NAME_SIZE); - } - - /* dynamic allocations */ - mp = malloc(conf.max_devs * sizeof(struct multipath)); - all_paths = malloc(conf.max_devs * sizeof(struct path)); - all_scsi_ids = malloc(conf.max_devs * sizeof(struct scsi_dev)); - if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) - exit(1); - - if (sysfs_get_mnt_path(conf.sysfs_path, FILE_NAME_SIZE)) { - get_all_scsi_ids(&conf, all_scsi_ids); - get_all_paths_nosysfs(&conf, all_paths, all_scsi_ids); - } else { - get_all_paths_sysfs(&conf, all_paths); - } - nmp = coalesce_paths(&conf, mp, all_paths); - - if (conf.verbose) { - print_all_path(&conf, all_paths); - fprintf(stdout, "\n"); - print_all_mp(all_paths, mp, nmp); - fprintf(stdout, "\n"); - } - - if (conf.dry_run) - exit(0); - - for (k=0; k<=nmp; k++) { - if (map_present(mp[k].wwid)) { - setup_map(&conf, all_paths, mp, k, DM_DEVICE_RELOAD); - } else { - setup_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); - } - } - - /* free allocs */ - free(mp); - free(all_paths); - free(all_scsi_ids); - - exit(0); -} diff --git a/extras/multipath/main.h b/extras/multipath/main.h deleted file mode 100644 index cee99d2b88..0000000000 --- a/extras/multipath/main.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Soft: Description here... - * - * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ - * - * Author: Copyright (C) 2003 Christophe Varoqui - * - * 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. - * - * 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. - */ - -#ifndef _MAIN_H -#define _MAIN_H - -/* local includes */ -#include "sg_include.h" - -/* exerpt from "sg_err.h" */ -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 - -/* exerpt from "scsi.h" */ -#define SCSI_IOCTL_GET_IDLUN 0x5382 -#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 - -/* global defs */ -#define WWID_SIZE 33 -#define SERIAL_SIZE 14 -#define MAX_DEVS 128 -#define MAX_MP MAX_DEVS / 2 -#define MAX_MP_PATHS MAX_DEVS / 4 -#define FILE_NAME_SIZE 256 -#define DEF_TIMEOUT 60000 -#define EBUFF_SZ 256 -#define TUR_CMD_LEN 6 -#define DM_TARGET "multipath" - -/* Storage controlers cpabilities */ -#define FAILOVER 0 -#define MULTIBUS 1 -#define GROUP_BY_SERIAL 2 - -#define PINDEX(x,y) mp[(x)].pindex[(y)] - -/* global types */ -struct scsi_idlun { - int dev_id; - int host_unique_id; - int host_no; -}; - -struct sg_id { - int host_no; - int channel; - int scsi_id; - int lun; - int scsi_type; - short h_cmd_per_lun; - short d_queue_depth; - int unused1; - int unused2; -}; - -struct scsi_dev { - char dev[FILE_NAME_SIZE]; - struct scsi_idlun scsi_id; - int host_no; -}; - -struct path { - char dev[FILE_NAME_SIZE]; - char sg_dev[FILE_NAME_SIZE]; - struct scsi_idlun scsi_id; - struct sg_id sg_id; - char wwid[WWID_SIZE]; - char vendor_id[8]; - char product_id[16]; - char rev[4]; - char serial[SERIAL_SIZE]; - int iopolicy; -}; - -struct multipath { - char wwid[WWID_SIZE]; - int npaths; - long size; - int pindex[MAX_MP_PATHS]; -}; - -struct env { - int max_devs; - int verbose; - int quiet; - int dry_run; - int iopolicy; - int with_sysfs; - char sysfs_path[FILE_NAME_SIZE]; - char hotplugdev[FILE_NAME_SIZE]; -}; - -/* Build version */ -#define PROG "multipath" - -#define VERSION_CODE 0x000012 -#define DATE_CODE 0x021504 - -#define MULTIPATH_VERSION(version) \ - (version >> 16) & 0xFF, \ - (version >> 8) & 0xFF, \ - version & 0xFF - -#define VERSION_STRING PROG" v%d.%d.%d (%.2d/%.2d, 20%.2d)\n", \ - MULTIPATH_VERSION(VERSION_CODE), \ - MULTIPATH_VERSION(DATE_CODE) - -#endif diff --git a/extras/multipath/multipath.8 b/extras/multipath/multipath.8 deleted file mode 100644 index 98746424b4..0000000000 --- a/extras/multipath/multipath.8 +++ /dev/null @@ -1,53 +0,0 @@ -.TH MULTIPATH 8 "February 2004" "" "Linux Administrator's Manual" -.SH NAME -multipath \- Device mapper target autoconfig -.SH SYNOPSIS -.B multipath -.RB [\| \-v | \-q \|] -.RB [\| \-d \|] -.RB [\| \-m\ \c -.IR max_devs \|] -.RB [\| \-p\ \c -.BR failover | multibus | group_by_serial \|] -.RB [\| device \|] -.SH DESCRIPTION -.B multipath -is used to detect multiple paths to devices for fail-over or performance reasons and coalesces them. -.SH OPTIONS -.TP -.B \-v -verbose, print all paths and multipaths -.TP -.B \-q -quiet, no output at all -.TP -.B \-d -dry run, do not create or update devmaps -.TP -.BI \-m " max_devs" -scan -.I max_devs -devices at most -.TP -.BI \-p " policy" -force maps to specified policy: -.RS 1.2i -.TP 1.2i -.B failover -1 path per priority group -.TP -.B multibus -all paths in 1 priority group -.TP -.B group_by_serial -1 priority group per serial -.RE -.TP -.B device -limit the [re]configuration to the specified device's multipath scope. device is given in its hotplug $DEVPATH form like /devices/pci0000:03/0000:03:01.0/host0/0:0:5:1 -.SH "SEE ALSO" -.BR udev (8), -.BR dmsetup (8) -.SH AUTHORS -.B multipath -was developed by Christophe Varoqui, and others. diff --git a/extras/multipath/multipath.hotplug b/extras/multipath/multipath.hotplug deleted file mode 100644 index 9f44f86c9b..0000000000 --- a/extras/multipath/multipath.hotplug +++ /dev/null @@ -1,7 +0,0 @@ -#!bin/sh -. /etc/hotplug/hotplug.functions - -# wait for sysfs -sleep 1 - -mesg `/sbin/multipath $DEVPATH` diff --git a/extras/multipath/sg_err.h b/extras/multipath/sg_err.h deleted file mode 100644 index ef57b5ce38..0000000000 --- a/extras/multipath/sg_err.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef SG_ERR_H -#define SG_ERR_H - -/* Feel free to copy and modify this GPL-ed code into your applications. */ - -/* Version 0.90 (20030519) -*/ - - -/* Some of the following error/status codes are exchanged between the - various layers of the SCSI sub-system in Linux and should never - reach the user. They are placed here for completeness. What appears - here is copied from drivers/scsi/scsi.h which is not visible in - the user space. */ - -#ifndef SCSI_CHECK_CONDITION -/* 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 -#endif - -/* The following are 'host_status' codes */ -#ifndef DID_OK -#define DID_OK 0x00 -#endif -#ifndef DID_NO_CONNECT -#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 DID_BAD_TARGET 0x04 /* Bad target (id?) */ -#define DID_ABORT 0x05 /* Told to abort for some other reason */ -#define DID_PARITY 0x06 /* Parity error (on SCSI bus) */ -#define DID_ERROR 0x07 /* Internal error */ -#define DID_RESET 0x08 /* Reset by somebody */ -#define DID_BAD_INTR 0x09 /* Received an unexpected interrupt */ -#define DID_PASSTHROUGH 0x0a /* Force command past mid-level */ -#define DID_SOFT_ERROR 0x0b /* The low-level driver wants a retry */ -#endif - -/* These defines are to isolate applictaions from kernel define changes */ -#define SG_ERR_DID_OK DID_OK -#define SG_ERR_DID_NO_CONNECT DID_NO_CONNECT -#define SG_ERR_DID_BUS_BUSY DID_BUS_BUSY -#define SG_ERR_DID_TIME_OUT DID_TIME_OUT -#define SG_ERR_DID_BAD_TARGET DID_BAD_TARGET -#define SG_ERR_DID_ABORT DID_ABORT -#define SG_ERR_DID_PARITY DID_PARITY -#define SG_ERR_DID_ERROR DID_ERROR -#define SG_ERR_DID_RESET DID_RESET -#define SG_ERR_DID_BAD_INTR DID_BAD_INTR -#define SG_ERR_DID_PASSTHROUGH DID_PASSTHROUGH -#define SG_ERR_DID_SOFT_ERROR DID_SOFT_ERROR - -/* The following are 'driver_status' codes */ -#ifndef DRIVER_OK -#define DRIVER_OK 0x00 -#endif -#ifndef DRIVER_BUSY -#define DRIVER_BUSY 0x01 -#define DRIVER_SOFT 0x02 -#define DRIVER_MEDIA 0x03 -#define DRIVER_ERROR 0x04 -#define DRIVER_INVALID 0x05 -#define DRIVER_TIMEOUT 0x06 -#define DRIVER_HARD 0x07 -#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ - -/* Following "suggests" are "or-ed" with one of previous 8 entries */ -#define SUGGEST_RETRY 0x10 -#define SUGGEST_ABORT 0x20 -#define SUGGEST_REMAP 0x30 -#define SUGGEST_DIE 0x40 -#define SUGGEST_SENSE 0x80 -#define SUGGEST_IS_OK 0xff -#endif -#ifndef DRIVER_MASK -#define DRIVER_MASK 0x0f -#endif -#ifndef SUGGEST_MASK -#define SUGGEST_MASK 0xf0 -#endif - -/* These defines are to isolate applictaions from kernel define changes */ -#define SG_ERR_DRIVER_OK DRIVER_OK -#define SG_ERR_DRIVER_BUSY DRIVER_BUSY -#define SG_ERR_DRIVER_SOFT DRIVER_SOFT -#define SG_ERR_DRIVER_MEDIA DRIVER_MEDIA -#define SG_ERR_DRIVER_ERROR DRIVER_ERROR -#define SG_ERR_DRIVER_INVALID DRIVER_INVALID -#define SG_ERR_DRIVER_TIMEOUT DRIVER_TIMEOUT -#define SG_ERR_DRIVER_HARD DRIVER_HARD -#define SG_ERR_DRIVER_SENSE DRIVER_SENSE -#define SG_ERR_SUGGEST_RETRY SUGGEST_RETRY -#define SG_ERR_SUGGEST_ABORT SUGGEST_ABORT -#define SG_ERR_SUGGEST_REMAP SUGGEST_REMAP -#define SG_ERR_SUGGEST_DIE SUGGEST_DIE -#define SG_ERR_SUGGEST_SENSE SUGGEST_SENSE -#define SG_ERR_SUGGEST_IS_OK SUGGEST_IS_OK -#define SG_ERR_DRIVER_MASK DRIVER_MASK -#define SG_ERR_SUGGEST_MASK SUGGEST_MASK - - - -/* The following "print" functions send ACSII to stdout */ -extern void sg_print_command(const unsigned char * command); -extern void sg_print_sense(const char * leadin, - const unsigned char * sense_buffer, int sb_len); -extern void sg_print_status(int masked_status); -extern void sg_print_scsi_status(int scsi_status); -extern void sg_print_host_status(int host_status); -extern void sg_print_driver_status(int driver_status); - -/* sg_chk_n_print() returns 1 quietly if there are no errors/warnings - else it prints to standard output and returns 0. */ -extern int sg_chk_n_print(const char * leadin, int masked_status, - int host_status, int driver_status, - const unsigned char * sense_buffer, int sb_len); - -/* The following function declaration is for the sg version 3 driver. - Only version 3 sg_err.c defines it. */ -struct sg_io_hdr; -extern int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp); - - -/* 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_SENSE 98 /* Something else is in the sense buffer */ -#define SG_ERR_CAT_OTHER 99 /* Some other error/warning has occurred */ - -extern int sg_err_category(int masked_status, int host_status, - int driver_status, const unsigned char * sense_buffer, - int sb_len); - -extern int sg_err_category_new(int scsi_status, int host_status, - int driver_status, const unsigned char * sense_buffer, - int sb_len); - -/* The following function declaration is for the sg version 3 driver. - Only version 3 sg_err.c defines it. */ -extern int sg_err_category3(struct sg_io_hdr * hp); - -/* Returns length of SCSI command given the opcode (first byte) */ -extern int sg_get_command_size(unsigned char opcode); - -extern void sg_get_command_name(unsigned char opcode, int buff_len, - char * buff); - -#endif diff --git a/extras/multipath/sg_include.h b/extras/multipath/sg_include.h deleted file mode 100644 index 460506826e..0000000000 --- a/extras/multipath/sg_include.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef SG_KERNEL_INCLUDES - #define __user - typedef unsigned char u8; - #include "/usr/src/linux/include/scsi/sg.h" - #include "/usr/src/linux/include/scsi/scsi.h" -#else - #ifdef SG_TRICK_GNU_INCLUDES - #include - #include - #else - #include - #endif -#endif - -/* - Getting the correct include files for the sg interface can be an ordeal. - In a perfect world, one would just write: - #include - #include - This would include the files found in the /usr/include/scsi directory. - Those files are maintained with the GNU library which may or may not - agree with the kernel and version of sg driver that is running. Any - many cases this will not matter. However in some it might, for example - glibc 2.1's include files match the sg driver found in the lk 2.2 - series. Hence if glibc 2.1 is used with lk 2.4 then the additional - sg v3 interface will not be visible. - If this is a problem then defining SG_KERNEL_INCLUDES will access the - kernel supplied header files (assuming they are in the normal place). - The GNU library maintainers and various kernel people don't like - this approach (but it does work). - The technique selected by defining SG_TRICK_GNU_INCLUDES worked (and - was used) prior to glibc 2.2 . Prior to that version /usr/include/linux - was a symbolic link to /usr/src/linux/include/linux . - - There are other approaches if this include "mixup" causes pain. These - would involve include files being copied or symbolic links being - introduced. - - Sorry about the inconvenience. Typically neither SG_KERNEL_INCLUDES - nor SG_TRICK_GNU_INCLUDES is defined. - - dpg 20010415, 20030522 -*/ diff --git a/extras/multipath/unused.c b/extras/multipath/unused.c deleted file mode 100644 index 08144cf717..0000000000 --- a/extras/multipath/unused.c +++ /dev/null @@ -1,95 +0,0 @@ -static int -get_serial (int fd, char * str) -{ - char buff[MX_ALLOC_LEN + 1]; - int len; - - if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { - len = buff[3]; - if (len > 0) { - memcpy(str, buff + 4, len); - buff[len] = '\0'; - } - return 1; - } - return 0; -} - -static int -do_tur(int fd) -{ - unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; - struct sg_io_hdr io_hdr; - unsigned char sense_buffer[32]; - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (turCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_buffer); - io_hdr.dxfer_direction = SG_DXFER_NONE; - io_hdr.cmdp = turCmdBlk; - io_hdr.sbp = sense_buffer; - io_hdr.timeout = 20000; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - close(fd); - return 0; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - return 0; - } - return 1; -} - -static int -del_map(char * str) { - struct dm_task *dmt; - - if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) - return 0; - if (!dm_task_set_name(dmt, str)) - goto delout; - if (!dm_task_run(dmt)) - goto delout; - - printf("Deleted device map : %s\n", str); - - delout: - dm_task_destroy(dmt); - return 1; -} - -get_table(const char * str) -{ - int r = 0; - struct dm_task *dmt; - void *next = NULL; - uint64_t start, length; - char *target_type = NULL; - char *params; - - if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) - return 0; - - if (!dm_task_set_name(dmt, str)) - goto out; - - if (!dm_task_run(dmt)) - goto out; - - do { - next = dm_get_next_target(dmt, next, &start, &length, - &target_type, ¶ms); - if (target_type) { - printf("%" PRIu64 " %" PRIu64 " %s %s\n", - start, length, target_type, params); - } - } while (next); - - r = 1; - - out: - dm_task_destroy(dmt); - return r; - -} From a3b37a073d52ff01d4ef023a10f13316da4c9966 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Mar 2004 22:40:39 -0800 Subject: [PATCH 0648/4284] [PATCH] Added multipath-tools 0.1.1 release --- extras/multipath-tools/AUTHOR | 1 + extras/multipath-tools/COPYING | 483 ++++++++ extras/multipath-tools/ChangeLog | 137 +++ extras/multipath-tools/Makefile | 41 + extras/multipath-tools/README | 90 ++ extras/multipath-tools/VERSION | 1 + extras/multipath-tools/devmap_name/Makefile | 47 + .../multipath-tools/devmap_name/devmap_name.8 | 30 + .../multipath-tools/devmap_name/devmap_name.c | 60 + extras/multipath-tools/libdevmapper/Makefile | 28 + .../libdevmapper/ioctl/libdevmapper.c | 1092 +++++++++++++++++ .../libdevmapper/ioctl/libdm-compat.h | 111 ++ .../libdevmapper/ioctl/libdm-targets.h | 51 + .../libdevmapper/libdevmapper.h | 147 +++ .../libdevmapper/libdm-common.c | 382 ++++++ .../libdevmapper/libdm-common.h | 38 + extras/multipath-tools/libdevmapper/list.h | 99 ++ extras/multipath-tools/multipath/Makefile | 60 + extras/multipath-tools/multipath/devinfo.c | 240 ++++ extras/multipath-tools/multipath/devinfo.h | 21 + extras/multipath-tools/multipath/main.c | 895 ++++++++++++++ extras/multipath-tools/multipath/main.h | 131 ++ extras/multipath-tools/multipath/multipath.8 | 66 + .../multipath/multipath.hotplug | 7 + extras/multipath-tools/multipath/sg_err.h | 162 +++ extras/multipath-tools/multipath/sg_include.h | 43 + extras/multipath-tools/multipath/unused.c | 95 ++ extras/multipath-tools/multipathd/Makefile | 31 + extras/multipath-tools/multipathd/checkers.c | 62 + extras/multipath-tools/multipathd/checkers.h | 2 + extras/multipath-tools/multipathd/devinfo.c | 82 ++ extras/multipath-tools/multipathd/devinfo.h | 15 + extras/multipath-tools/multipathd/main.c | 674 ++++++++++ .../multipathd/multipathd.init | 42 + .../multipath-tools/multipathd/sg_include.h | 43 + 35 files changed, 5509 insertions(+) create mode 100644 extras/multipath-tools/AUTHOR create mode 100644 extras/multipath-tools/COPYING create mode 100644 extras/multipath-tools/ChangeLog create mode 100644 extras/multipath-tools/Makefile create mode 100644 extras/multipath-tools/README create mode 100644 extras/multipath-tools/VERSION create mode 100644 extras/multipath-tools/devmap_name/Makefile create mode 100644 extras/multipath-tools/devmap_name/devmap_name.8 create mode 100644 extras/multipath-tools/devmap_name/devmap_name.c create mode 100644 extras/multipath-tools/libdevmapper/Makefile create mode 100644 extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c create mode 100644 extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h create mode 100644 extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h create mode 100644 extras/multipath-tools/libdevmapper/libdevmapper.h create mode 100644 extras/multipath-tools/libdevmapper/libdm-common.c create mode 100644 extras/multipath-tools/libdevmapper/libdm-common.h create mode 100644 extras/multipath-tools/libdevmapper/list.h create mode 100644 extras/multipath-tools/multipath/Makefile create mode 100644 extras/multipath-tools/multipath/devinfo.c create mode 100644 extras/multipath-tools/multipath/devinfo.h create mode 100644 extras/multipath-tools/multipath/main.c create mode 100644 extras/multipath-tools/multipath/main.h create mode 100644 extras/multipath-tools/multipath/multipath.8 create mode 100644 extras/multipath-tools/multipath/multipath.hotplug create mode 100644 extras/multipath-tools/multipath/sg_err.h create mode 100644 extras/multipath-tools/multipath/sg_include.h create mode 100644 extras/multipath-tools/multipath/unused.c create mode 100644 extras/multipath-tools/multipathd/Makefile create mode 100644 extras/multipath-tools/multipathd/checkers.c create mode 100644 extras/multipath-tools/multipathd/checkers.h create mode 100644 extras/multipath-tools/multipathd/devinfo.c create mode 100644 extras/multipath-tools/multipathd/devinfo.h create mode 100644 extras/multipath-tools/multipathd/main.c create mode 100644 extras/multipath-tools/multipathd/multipathd.init create mode 100644 extras/multipath-tools/multipathd/sg_include.h diff --git a/extras/multipath-tools/AUTHOR b/extras/multipath-tools/AUTHOR new file mode 100644 index 0000000000..4e8eeef5c8 --- /dev/null +++ b/extras/multipath-tools/AUTHOR @@ -0,0 +1 @@ +Christophe Varoqui, diff --git a/extras/multipath-tools/COPYING b/extras/multipath-tools/COPYING new file mode 100644 index 0000000000..9e31bbf0b3 --- /dev/null +++ b/extras/multipath-tools/COPYING @@ -0,0 +1,483 @@ + + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, 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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, 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 companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "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 +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY 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 +LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, + MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/extras/multipath-tools/ChangeLog b/extras/multipath-tools/ChangeLog new file mode 100644 index 0000000000..0807a42678 --- /dev/null +++ b/extras/multipath-tools/ChangeLog @@ -0,0 +1,137 @@ +2004-03-06 multipath-tools-0.1.1 + * include dlist.h in multipath main.c (PM Hahn) + * typo in hotplug script (PM Hahn) + * pass -9 opt to gzip for manpages (PM Hahn) +2004-03-05 multipath-tools-0.1.0 + * add the group_by_tur policy + * add the multipathd daemon for pathchecking & DM hot-reconfig + * multipath doesn't run twice + * massive cleanups, and code restructuring + * Avoid Kernel Bug when passing too small a buffer in do_inq() + * Sync with 2.6.3-udm4 target synthax (no more PG prio) +2004-02-21 multipath-018 + * From the Debian SID inclusion review (Philipp Matthias Hahn) + * use DESTDIR install prefix in the Makefile + * add man pages for devmap_name & multipath + * correct libsysfs.h includes + * fork the hotplug script in its own shell + * Sync with the kernel device mapper code as of 2.6.3-udm3 + ie. Remove the test interval parameter and its uses + * Remove superfluous scsi parameter passed from hotplug + * Add the man pages to the [un]install targets +2004-02-17 multipath-017 + * remove the restrictive -f flag. + Introduce a more generic "-m iopolicy" one. + * remove useless "int with_sysfs" in env struct +2004-02-04 multipath-016 + * add a GROUP_BY_SERIAL flag. This should be useful for + controlers that activate they spare paths on simple IO + submition with a penalty. The StorageWorks HW defaults to + this mode, even if the MULTIBUS mode is OK. + * remove unused sg_err.c + * big restructuring : split devinfo.c from main.c. Export : + * void basename (char *, char *); + * int get_serial (int, char *); + * int get_lun_strings (char *, char *, char *, char *); + * int get_evpd_wwid(char *, char *); + * long get_disk_size (char *); + * stop passing struct env as param + * add devmap_name proggy for udev to name devmaps as per their + internal DM name and not only by their sysfs enum name (dm-*) + The corresponding udev.rules line is : + KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" + * remove make_dm_node fn & call. Rely on udev for this. + * don't rely on the linux symlink in the udev/klibc dir since + udev build doesn't use it anymore. This corrects build breakage +2004-01-19 multipath-013 + * update the DM target synthax to the 2.6.0-udm5 style +2003-12-29 multipath-012 + * check hotplug event refers to a block device; if not exit early + * refresh doc + * add the uninstall target in Makefile +2003-12-22 multipath-010 + * tweak the install target in Makefile + * stop passing fds as argument : this change enable a strict + segregation of ugly 2.4 code + * sysfs version of get_lun_strings() + * be careful about the return of get_unique_id() since errors + formerly caught up by if(open()) in the caller fn are now returned + by get_unique_id() + * send get_serial() in unused.c + * introduce dm-simplecmd for RESUME & SUSPEND requests + * split add_map() in setup_map() & dm-addmap() + * setup_map() correctly submits "SUSPEND-RELOAD-RESUME or CREATE" + sequences instead of the bogus "RELOAD or CREATE" + * don't print .sg_dev if equal to .dev (2.6) in print_path() + * since the kernel code handles defective paths, remove all + code to cope with them : + * move do_tur() to unused.c + * remove .state from path struct + * remove .state settings & conditionals + * add a cmdline switch to force maps to failover mode, + ie 1 path per priority group + * add default policies to the whitelist array (spread io == + MULTIBUS / io forced to 1 path == FAILOVER) + * move get_disk_size() call out of add_map() to coalesce() + * comment tricky coalesce() fn + * bogus unsused.c file renamed to unused.c +2003-12-20 multipath-010 + * big ChangeLog update + * start to give a little control over target params : + introduce cmdline arg -i to control polling interval + * cope with hotplug-style calling convention : + ie "multipath scsi $DEVPATH" ... to avoid messing with + online maps not concerned by an event + * example hotplug agent to drop in /etc/hotplug.d/scsi + * revert the run & resched patch : unless someone proves me + wrong, this was overdesigned + * move commented out functions in unused.c + * update multipath target params to "udm[23] style" + * mp target now supports nr_path == 1, so do we + * add gratuitous free() + * push version forward +2003-12-15 multipath-009 + * Make the HW-specific get_unique_id switch pretty + * Prepare to field-test by whitelisting all known fibre array, + try to fetch WWID from the standard EVPD 0x83 off 8 for everyone + * configure the multipath target with round-robin path selector and + conservative default for a start (udm1 style) : + yes it makes this release the firstreally useful one. + * temporarily disable map creation for single path device + due to current restrictive defaults in the kernel target. + Sistina should work it out. + * correct the strncmp logic in blacklist function. + * update the Makefiles to autodetect libgcc.a & gcc includes + "ulibc-style". Factorisation of udevdirs & others niceties + * drop a hint about absent /dev/sd? on failed open() + * implement a reschedule flag in /var/run. + Last thing the prog do before exit is check if a call to multipath + was done (but canceled by /var/run/multipath.run check) during its + execution. If so restart themain loop. + * implement a blacklist of sysfs bdev to not bother with for now + (hd,md, dm, sr, scd, ram, raw). + This avoid sending SG_IO to unappropiate devices. + * Adds a /var/run/multipath.run handling to avoid simultaneous runs. + * Remove a commented-out "printf" + * drop a libdevmapper copy in extras/multipath; + maybe discussions w/Sistina folks will bring a better solution in the future. + * drop a putchar usage in libdevmapper to compile cleanly with klibc + * drop another such usage of my own in main.c + * massage the Makefile to compile libdevmapper against klibc + * use "ld" to produce the binary rather than "gcc -static" + * stop being stupid w/ uneeded major, minor & dev in main.c:dm_mk_node() + * reverse to creating striped target for now because the multipath target + is more hairy than expected initialy + * push the version code to 009 to be in synch w/ udev +2003-11-27 multipath-007 + * removes sg_err.[ch] deps + * makes sure the core code play nice with klibc + * port the sysfs calls to dlist helpers + * links against udev's sysfs (need libsysfs.a & dlist.a) + * finally define DM_TARGET as "multipath" as Joe posted the code today (not tested yet) + * push version forward (do you want it in sync with udev version?) +2003-11-19 + * merged in udev-006 tree +2003-09-18 Christophe Varoqui + * multipath 0.0.1 released. + * Initial release. diff --git a/extras/multipath-tools/Makefile b/extras/multipath-tools/Makefile new file mode 100644 index 0000000000..2f21f0d112 --- /dev/null +++ b/extras/multipath-tools/Makefile @@ -0,0 +1,41 @@ +# Makefile +# +# Copyright (C) 2003 Christophe Varoqui, + +SUBDIRS = libdevmapper devmap_name multipath multipathd + +recurse: + @for dir in $(SUBDIRS); do\ + $(MAKE) -C $$dir ; \ + done + +recurse_clean: + @for dir in $(SUBDIRS); do\ + $(MAKE) -C $$dir clean ; \ + done + +recurse_install: + @for dir in $(SUBDIRS); do\ + $(MAKE) -C $$dir install ; \ + done + +recurse_uninstall: + @for dir in $(SUBDIRS); do\ + $(MAKE) -C $$dir uninstall ; \ + done + +all: recurse + @echo "" + @echo "Make complete" + +clean: recurse_clean + @echo "" + @echo "Make complete" + +install: recurse_install + @echo "" + @echo "Make complete" + +uninstall: recurse_uninstall + @echo "" + @echo "Make complete" diff --git a/extras/multipath-tools/README b/extras/multipath-tools/README new file mode 100644 index 0000000000..80945db438 --- /dev/null +++ b/extras/multipath-tools/README @@ -0,0 +1,90 @@ +Dependancies : +============== + +o libdevmapper : comes with device-mapper-XXXX.tar.gz + See www.sistina.com + This lib has been dropped in the multipath tree +o libsysfs : comes with sysutils or udev + See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ +o Linux kernel 2.6.0 with udm5 patchset + http://people.sistina.com/~thornber/dm/ +o udev + See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ + +How it works : +============== + +Fill the all_paths array. Each path store this info : + +struct path { + char dev[FILE_NAME_SIZE]; + char sg_dev[FILE_NAME_SIZE]; + struct scsi_idlun scsi_id; + struct sg_id sg_id; + int state; + char wwid[WWID_SIZE]; +}; + +scsi_id, sg_dev and sg_id are only really useful for 2.4 +kernels, for which SG cmnds must go through sg devs. +In 2.5+ we have the nice opportunity to send SG cmnds +through SCSI bdevs. + +For 2.4 compat, we pivot on idlun tupple to map sg devs +to SCSI bdevs. + +2.4 does not do device enumeration, so we must scan a +defined number of sg devs and scsi bdevs. Good enough. +In 2.5+, we rely on libsysfs (sysutils) to access to +sysfs device enums. + +the wwid is retrieved by a switch fonction. Only White +Listed HW can filled this field. For now every FC array +HW listed in kernel's devinfo.c is White Listed, assuming +the WWID is stored is the SCSI-3 standard 0x83 EVPD page. + +When all_paths is filled, we coalesce the paths and store +the result in mp array. Each mp is a struct like this : + +struct multipath { + char wwid[WWID_SIZE]; + int npaths; + int pindex[MAX_MP_PATHS]; +}; + +When mp is filled, the device maps are fed to the kernel +through libdevmapper. + +The naming of the corresponding block device is handeld +by udev with the help of the devmap_name proggy. It is +called by the following rule in /etc/udev/udev.rules : +KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \ +NAME="%k", SYMLINK="%c" + +Notes : +======= + +o On 2.4, make sure you have enough /dev/sg* nodes + (/dev/MAKEDEV if necesary). Same goes for /dev/sd* + +o path coalescing relies on a path unique id being found. + This unique id, lacking a standard method, is vendor + specific. A switch function (get_unique_id) is present + and an example function is provided for storageworks + arrays (get_evpd_wwid). Feel free to enrich + with hardware you have at hand :) + +o The kernel does NOT manage properly ghosts paths + with StorageWorks HW. Seems nobody cares after a load + of posts to linux-scsi. + +o 2.4.21 version of DM does not like even segment size. + if you enconter pbs with this, upgrade DM. + +Credits : +========= + +o Heavy cut'n paste from sg_utils. Thanks goes to D. + Gilbert. +o Light cut'n paste from dmsetup. Thanks Joe Thornber. +o Greg KH for the nice sysfs API. diff --git a/extras/multipath-tools/VERSION b/extras/multipath-tools/VERSION new file mode 100644 index 0000000000..bbdeab6222 --- /dev/null +++ b/extras/multipath-tools/VERSION @@ -0,0 +1 @@ +0.0.5 diff --git a/extras/multipath-tools/devmap_name/Makefile b/extras/multipath-tools/devmap_name/Makefile new file mode 100644 index 0000000000..a9683341b2 --- /dev/null +++ b/extras/multipath-tools/devmap_name/Makefile @@ -0,0 +1,47 @@ +# Makefile +# +# Copyright (C) 2003 Christophe Varoqui, + +EXEC = devmap_name + +prefix = +exec_prefix = ${prefix} +bindir = ${exec_prefix}/sbin +udevdir = ../../.. +klibcdir = $(udevdir)/klibc +mandir = /usr/share/man/man8 +libdmdir = ../libdevmapper + +CC = gcc +GZIP = /bin/gzip -9 -c + +GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} +KERNEL_DIR = /lib/modules/${shell uname -r}/build +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ + -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ + -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. + +OBJS = devmap_name.o +CRT0 = $(klibcdir)/klibc/crt0.o +LIB = $(klibcdir)/klibc/libc.a +LIBGCC := $(shell $(CC) -print-libgcc-file-name ) + +DMOBJS = $(libdmdir)/libdm-common.o $(libdmdir)/ioctl/libdevmapper.o + +$(EXEC): $(OBJS) + $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(DMOBJS) $(LIB) $(LIBGCC) + strip $(EXEC) + $(GZIP) $(EXEC).8 > $(EXEC).8.gz + +clean: + rm -f core *.o $(EXEC) *.gz + +install: + install -d $(DESTDIR)$(bindir) + install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + install -d $(DESTDIR)$(mandir) + install -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) + +uninstall: + rm $(DESTDIR)$(bindir)/$(EXEC) + rm $(DESTDIR)$(mandir)/$(EXEC).8.gz diff --git a/extras/multipath-tools/devmap_name/devmap_name.8 b/extras/multipath-tools/devmap_name/devmap_name.8 new file mode 100644 index 0000000000..f4f03c3ec6 --- /dev/null +++ b/extras/multipath-tools/devmap_name/devmap_name.8 @@ -0,0 +1,30 @@ +.TH DEVMAP_NAME 8 "February 2004" "" "Linux Administrator's Manual" +.SH NAME +devmap_name \- Query device-mapper name +.SH SYNOPSIS +.BI devmap_name " major minor" +.SH DESCRIPTION +.B devmap_name +queries the device-mapper for the name for the device +specified by +.I major +and +.I minor +number. +.br +.B devmap_name +can be called from +.B udev +by the following rule in +.IR /etc/udev/udev.rules : +.sp +.nf +KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \\ + NAME="%k", SYMLINK="%c" +.fi +.SH "SEE ALSO" +.BR udev (8), +.BR dmsetup (8) +.SH AUTHORS +.B devmap_name +was developed by Christophe Varoqui, and others. diff --git a/extras/multipath-tools/devmap_name/devmap_name.c b/extras/multipath-tools/devmap_name/devmap_name.c new file mode 100644 index 0000000000..0932e4f8bb --- /dev/null +++ b/extras/multipath-tools/devmap_name/devmap_name.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#include "../libdevmapper/libdevmapper.h" + +static void usage(char * progname) { + fprintf(stderr, "usage : %s major minor\n", progname); + exit(1); +} + +int main(int argc, char **argv) +{ + int r = 0; + struct dm_names *names; + unsigned next = 0; + int major, minor; + + /* sanity check */ + if (argc != 3) + usage(argv[0]); + + major = atoi(argv[1]); + minor = atoi(argv[2]); + + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) + return 0; + + if (!dm_task_run(dmt)) + goto out; + + if (!(names = dm_task_get_names(dmt))) + goto out; + + if (!names->dev) { + printf("No devices found\n"); + goto out; + } + + do { + names = (void *) names + next; + if ((int) MAJOR(names->dev) == major && + (int) MINOR(names->dev) == minor) { + printf("%s\n", names->name); + goto out; + } + next = names->next; + } while (next); + + /* No correspondance found */ + r = 1; + + out: + dm_task_destroy(dmt); + return r; +} + diff --git a/extras/multipath-tools/libdevmapper/Makefile b/extras/multipath-tools/libdevmapper/Makefile new file mode 100644 index 0000000000..445263caa8 --- /dev/null +++ b/extras/multipath-tools/libdevmapper/Makefile @@ -0,0 +1,28 @@ +# Makefile +# +# Copyright (C) 2003 Christophe Varoqui, + +CC = gcc +udevdir = ../../.. +klibcdir = $(udevdir)/klibc + +CC = gcc +GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} +KERNEL_DIR = /lib/modules/${shell uname -r}/build + +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ + -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ + -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I. -Iioctl + +OBJS = ioctl/libdevmapper.o libdm-common.o + +all: $(OBJS) + @echo "" + @echo "Make complete" + +clean: + rm -f core *.o ioctl/*.o ioctl/*.so + +install: + +uninstall: diff --git a/extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c b/extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c new file mode 100644 index 0000000000..ac7ba0c86a --- /dev/null +++ b/extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c @@ -0,0 +1,1092 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#include "libdm-targets.h" +#include "libdm-common.h" + +#ifdef DM_COMPAT +# include "libdm-compat.h" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef linux +# include +# include +# include +#else +# define MAJOR(x) major((x)) +# define MINOR(x) minor((x)) +# define MKDEV(x,y) makedev((x),(y)) +#endif + +/* + * Ensure build compatibility. + * The hard-coded versions here are the highest present + * in the _cmd_data arrays. + */ + +#if !((DM_VERSION_MAJOR == 1 && DM_VERSION_MINOR >= 0) || \ + (DM_VERSION_MAJOR == 4 && DM_VERSION_MINOR >= 0)) +#error The version of dm-ioctl.h included is incompatible. +#endif + +/* dm major version no for running kernel */ +static int _dm_version = DM_VERSION_MAJOR; +static int _log_suppress = 0; + +static int _control_fd = -1; +static int _version_checked = 0; +static int _version_ok = 1; + +/* + * Support both old and new major numbers to ease the transition. + * Clumsy, but only temporary. + */ +#if DM_VERSION_MAJOR == 4 && defined(DM_COMPAT) +const int _dm_compat = 1; +#else +const int _dm_compat = 0; +#endif + + +/* *INDENT-OFF* */ +static struct cmd_data _cmd_data_v4[] = { + {"create", DM_DEV_CREATE, {4, 0, 0}}, + {"reload", DM_TABLE_LOAD, {4, 0, 0}}, + {"remove", DM_DEV_REMOVE, {4, 0, 0}}, + {"remove_all", DM_REMOVE_ALL, {4, 0, 0}}, + {"suspend", DM_DEV_SUSPEND, {4, 0, 0}}, + {"resume", DM_DEV_SUSPEND, {4, 0, 0}}, + {"info", DM_DEV_STATUS, {4, 0, 0}}, + {"deps", DM_TABLE_DEPS, {4, 0, 0}}, + {"rename", DM_DEV_RENAME, {4, 0, 0}}, + {"version", DM_VERSION, {4, 0, 0}}, + {"status", DM_TABLE_STATUS, {4, 0, 0}}, + {"table", DM_TABLE_STATUS, {4, 0, 0}}, + {"waitevent", DM_DEV_WAIT, {4, 0, 0}}, + {"names", DM_LIST_DEVICES, {4, 0, 0}}, + {"clear", DM_TABLE_CLEAR, {4, 0, 0}}, + {"mknodes", DM_DEV_STATUS, {4, 0, 0}}, +}; +/* *INDENT-ON* */ + +#define ALIGNMENT_V1 sizeof(int) +#define ALIGNMENT 8 + +/* FIXME Rejig library to record & use errno instead */ +#ifndef DM_EXISTS_FLAG +# define DM_EXISTS_FLAG 0x00000004 +#endif + +static void *_align(void *ptr, unsigned int a) +{ + register unsigned long agn = --a; + + return (void *) (((unsigned long) ptr + agn) & ~agn); +} + +static int _open_control(void) +{ + char control[PATH_MAX]; + + if (_control_fd != -1) + return 1; + + snprintf(control, sizeof(control), "%s/control", dm_dir()); + + if ((_control_fd = open(control, O_RDWR)) < 0) { + log_error("%s: open failed: %s", control, strerror(errno)); + log_error("Is device-mapper driver missing from kernel?"); + return 0; + } + + return 1; +} + +void dm_task_destroy(struct dm_task *dmt) +{ + struct target *t, *n; + + for (t = dmt->head; t; t = n) { + n = t->next; + free(t->params); + free(t->type); + free(t); + } + + if (dmt->dev_name) + free(dmt->dev_name); + + if (dmt->newname) + free(dmt->newname); + + if (dmt->dmi.v4) + free(dmt->dmi.v4); + + if (dmt->uuid) + free(dmt->uuid); + + free(dmt); +} + +/* + * Protocol Version 1 compatibility functions. + */ + +#ifdef DM_COMPAT + +static int _dm_task_get_driver_version_v1(struct dm_task *dmt, char *version, + size_t size) +{ + unsigned int *v; + + if (!dmt->dmi.v1) { + version[0] = '\0'; + return 0; + } + + v = dmt->dmi.v1->version; + snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); + return 1; +} + +/* Unmarshall the target info returned from a status call */ +static int _unmarshal_status_v1(struct dm_task *dmt, struct dm_ioctl_v1 *dmi) +{ + char *outbuf = (char *) dmi + dmi->data_start; + char *outptr = outbuf; + int32_t i; + struct dm_target_spec_v1 *spec; + + for (i = 0; i < dmi->target_count; i++) { + spec = (struct dm_target_spec_v1 *) outptr; + + if (!dm_task_add_target(dmt, spec->sector_start, + (uint64_t) spec->length, + spec->target_type, + outptr + sizeof(*spec))) + return 0; + + outptr = outbuf + spec->next; + } + + return 1; +} + +static int _dm_format_dev_v1(char *buf, int bufsize, uint32_t dev_major, + uint32_t dev_minor) +{ + int r; + + if (bufsize < 8) + return 0; + + r = snprintf(buf, bufsize, "%03x:%03x", dev_major, dev_minor); + if (r < 0 || r > bufsize - 1) + return 0; + + return 1; +} + +static int _dm_task_get_info_v1(struct dm_task *dmt, struct dm_info *info) +{ + if (!dmt->dmi.v1) + return 0; + + memset(info, 0, sizeof(*info)); + + info->exists = dmt->dmi.v1->flags & DM_EXISTS_FLAG ? 1 : 0; + if (!info->exists) + return 1; + + info->suspended = dmt->dmi.v1->flags & DM_SUSPEND_FLAG ? 1 : 0; + info->read_only = dmt->dmi.v1->flags & DM_READONLY_FLAG ? 1 : 0; + info->target_count = dmt->dmi.v1->target_count; + info->open_count = dmt->dmi.v1->open_count; + info->event_nr = 0; + info->major = MAJOR(dmt->dmi.v1->dev); + info->minor = MINOR(dmt->dmi.v1->dev); + info->live_table = 1; + info->inactive_table = 0; + + return 1; +} + +static const char *_dm_task_get_name_v1(struct dm_task *dmt) +{ + return (dmt->dmi.v1->name); +} + +static const char *_dm_task_get_uuid_v1(struct dm_task *dmt) +{ + return (dmt->dmi.v1->uuid); +} + +static struct dm_deps *_dm_task_get_deps_v1(struct dm_task *dmt) +{ + log_error("deps version 1 no longer supported by libdevmapper"); + return NULL; +} + +static struct dm_names *_dm_task_get_names_v1(struct dm_task *dmt) +{ + return (struct dm_names *) (((void *) dmt->dmi.v1) + + dmt->dmi.v1->data_start); +} + +static void *_add_target_v1(struct target *t, void *out, void *end) +{ + void *out_sp = out; + struct dm_target_spec_v1 sp; + size_t sp_size = sizeof(struct dm_target_spec_v1); + int len; + const char no_space[] = "Ran out of memory building ioctl parameter"; + + out += sp_size; + if (out >= end) { + log_error(no_space); + return NULL; + } + + sp.status = 0; + sp.sector_start = t->start; + sp.length = t->length; + strncpy(sp.target_type, t->type, sizeof(sp.target_type)); + + len = strlen(t->params); + + if ((out + len + 1) >= end) { + log_error(no_space); + + log_error("t->params= '%s'", t->params); + return NULL; + } + strcpy((char *) out, t->params); + out += len + 1; + + /* align next block */ + out = _align(out, ALIGNMENT_V1); + + sp.next = out - out_sp; + + memcpy(out_sp, &sp, sp_size); + + return out; +} + +static struct dm_ioctl_v1 *_flatten_v1(struct dm_task *dmt) +{ + const size_t min_size = 16 * 1024; + const int (*version)[3]; + + struct dm_ioctl_v1 *dmi; + struct target *t; + size_t len = sizeof(struct dm_ioctl_v1); + void *b, *e; + int count = 0; + + for (t = dmt->head; t; t = t->next) { + len += sizeof(struct dm_target_spec_v1); + len += strlen(t->params) + 1 + ALIGNMENT_V1; + count++; + } + + if (count && dmt->newname) { + log_error("targets and newname are incompatible"); + return NULL; + } + + if (dmt->newname) + len += strlen(dmt->newname) + 1; + + /* + * Give len a minimum size so that we have space to store + * dependencies or status information. + */ + if (len < min_size) + len = min_size; + + if (!(dmi = malloc(len))) + return NULL; + + memset(dmi, 0, len); + + version = &_cmd_data_v1[dmt->type].version; + + dmi->version[0] = (*version)[0]; + dmi->version[1] = (*version)[1]; + dmi->version[2] = (*version)[2]; + + dmi->data_size = len; + dmi->data_start = sizeof(struct dm_ioctl_v1); + + if (dmt->dev_name) + strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); + + if (dmt->type == DM_DEVICE_SUSPEND) + dmi->flags |= DM_SUSPEND_FLAG; + if (dmt->read_only) + dmi->flags |= DM_READONLY_FLAG; + + if (dmt->minor >= 0) { + if (dmt->major <= 0) { + log_error("Missing major number for persistent device"); + return NULL; + } + dmi->flags |= DM_PERSISTENT_DEV_FLAG; + dmi->dev = MKDEV(dmt->major, dmt->minor); + } + + if (dmt->uuid) + strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); + + dmi->target_count = count; + + b = (void *) (dmi + 1); + e = (void *) ((char *) dmi + len); + + for (t = dmt->head; t; t = t->next) + if (!(b = _add_target_v1(t, b, e))) + goto bad; + + if (dmt->newname) + strcpy(b, dmt->newname); + + return dmi; + + bad: + free(dmi); + return NULL; +} + +static int _dm_names_v1(struct dm_ioctl_v1 *dmi) +{ + const char *dev_dir = dm_dir(); + int r = 1, len; + const char *name; + struct dirent *dirent; + DIR *d; + struct dm_names *names, *old_names = NULL; + void *end = (void *) dmi + dmi->data_size; + struct stat buf; + char path[PATH_MAX]; + + if (!(d = opendir(dev_dir))) { + log_error("%s: opendir failed: %s", dev_dir, strerror(errno)); + return 0; + } + + names = (struct dm_names *) ((void *) dmi + dmi->data_start); + + names->dev = 0; /* Flags no data */ + + while ((dirent = readdir(d))) { + name = dirent->d_name; + + if (name[0] == '.' || !strcmp(name, "control")) + continue; + + if (old_names) + old_names->next = (uint32_t) ((void *) names - + (void *) old_names); + snprintf(path, sizeof(path), "%s/%s", dev_dir, name); + if (stat(path, &buf)) { + log_error("%s: stat failed: %s", path, strerror(errno)); + continue; + } + if (!S_ISBLK(buf.st_mode)) + continue; + names->dev = (uint64_t) buf.st_rdev; + names->next = 0; + len = strlen(name); + if (((void *) (names + 1) + len + 1) >= end) { + log_error("Insufficient buffer space for device list"); + r = 0; + break; + } + + strcpy(names->name, name); + + old_names = names; + names = _align((void *) ++names + len + 1, ALIGNMENT); + } + + if (closedir(d)) + log_error("%s: closedir failed: %s", dev_dir, strerror(errno)); + + return r; +} + +static int _dm_task_run_v1(struct dm_task *dmt) +{ + struct dm_ioctl_v1 *dmi; + unsigned int command; + + dmi = _flatten_v1(dmt); + if (!dmi) { + log_error("Couldn't create ioctl argument"); + return 0; + } + + if (!_open_control()) + return 0; + + if ((unsigned) dmt->type >= + (sizeof(_cmd_data_v1) / sizeof(*_cmd_data_v1))) { + log_error("Internal error: unknown device-mapper task %d", + dmt->type); + goto bad; + } + + command = _cmd_data_v1[dmt->type].cmd; + + if (dmt->type == DM_DEVICE_TABLE) + dmi->flags |= DM_STATUS_TABLE_FLAG; + + log_debug("dm %s %s %s %s", _cmd_data_v1[dmt->type].name, dmi->name, + dmi->uuid, dmt->newname ? dmt->newname : ""); + if (dmt->type == DM_DEVICE_LIST) { + if (!_dm_names_v1(dmi)) + goto bad; + } else if (ioctl(_control_fd, command, dmi) < 0) { + if (_log_suppress) + log_verbose("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + else + log_error("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + goto bad; + } + + switch (dmt->type) { + case DM_DEVICE_CREATE: + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); + break; + + case DM_DEVICE_REMOVE: + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_RENAME: + rename_dev_node(dmt->dev_name, dmt->newname); + break; + + case DM_DEVICE_MKNODES: + if (dmi->flags & DM_EXISTS_FLAG) + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), + MINOR(dmi->dev)); + else + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_STATUS: + case DM_DEVICE_TABLE: + if (!_unmarshal_status_v1(dmt, dmi)) + goto bad; + break; + + case DM_DEVICE_SUSPEND: + case DM_DEVICE_RESUME: + dmt->type = DM_DEVICE_INFO; + if (!dm_task_run(dmt)) + goto bad; + free(dmi); /* We'll use what info returned */ + return 1; + } + + dmt->dmi.v1 = dmi; + return 1; + + bad: + free(dmi); + return 0; +} + +#endif + +/* + * Protocol Version 4 functions. + */ + +int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size) +{ + unsigned int *v; + +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_driver_version_v1(dmt, version, size); +#endif + + if (!dmt->dmi.v4) { + version[0] = '\0'; + return 0; + } + + v = dmt->dmi.v4->version; + snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); + return 1; +} + +static int _check_version(char *version, size_t size, int log_suppress) +{ + struct dm_task *task; + int r; + + if (!(task = dm_task_create(DM_DEVICE_VERSION))) { + log_error("Failed to get device-mapper version"); + version[0] = '\0'; + return 0; + } + + if (log_suppress) + _log_suppress = 1; + + r = dm_task_run(task); + dm_task_get_driver_version(task, version, size); + dm_task_destroy(task); + _log_suppress = 0; + + return r; +} + +/* + * Find out device-mapper's major version number the first time + * this is called and whether or not we support it. + */ +int dm_check_version(void) +{ + char libversion[64], dmversion[64]; + const char *compat = ""; + + if (_version_checked) + return _version_ok; + + _version_checked = 1; + + if (_check_version(dmversion, sizeof(dmversion), _dm_compat)) + return 1; + + if (!_dm_compat) + goto bad; + + log_verbose("device-mapper ioctl protocol version %d failed. " + "Trying protocol version 1.", _dm_version); + _dm_version = 1; + if (_check_version(dmversion, sizeof(dmversion), 0)) { + log_verbose("Using device-mapper ioctl protocol version 1"); + return 1; + } + + compat = "(compat)"; + + dm_get_library_version(libversion, sizeof(libversion)); + + log_error("Incompatible libdevmapper %s%s and kernel driver %s", + libversion, compat, dmversion); + + bad: + _version_ok = 0; + return 0; +} + +void *dm_get_next_target(struct dm_task *dmt, void *next, + uint64_t *start, uint64_t *length, + char **target_type, char **params) +{ + struct target *t = (struct target *) next; + + if (!t) + t = dmt->head; + + if (!t) + return NULL; + + *start = t->start; + *length = t->length; + *target_type = t->type; + *params = t->params; + + return t->next; +} + +/* Unmarshall the target info returned from a status call */ +static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi) +{ + char *outbuf = (char *) dmi + dmi->data_start; + char *outptr = outbuf; + uint32_t i; + struct dm_target_spec *spec; + + for (i = 0; i < dmi->target_count; i++) { + spec = (struct dm_target_spec *) outptr; + if (!dm_task_add_target(dmt, spec->sector_start, + spec->length, + spec->target_type, + outptr + sizeof(*spec))) + return 0; + + outptr = outbuf + spec->next; + } + + return 1; +} + +int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, + uint32_t dev_minor) +{ + int r; + +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_format_dev_v1(buf, bufsize, dev_major, dev_minor); +#endif + + if (bufsize < 8) + return 0; + + r = snprintf(buf, bufsize, "%03u:%03u", dev_major, dev_minor); + if (r < 0 || r > bufsize - 1) + return 0; + + return 1; +} + +int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_info_v1(dmt, info); +#endif + + if (!dmt->dmi.v4) + return 0; + + memset(info, 0, sizeof(*info)); + + info->exists = dmt->dmi.v4->flags & DM_EXISTS_FLAG ? 1 : 0; + if (!info->exists) + return 1; + + info->suspended = dmt->dmi.v4->flags & DM_SUSPEND_FLAG ? 1 : 0; + info->read_only = dmt->dmi.v4->flags & DM_READONLY_FLAG ? 1 : 0; + info->live_table = dmt->dmi.v4->flags & DM_ACTIVE_PRESENT_FLAG ? 1 : 0; + info->inactive_table = dmt->dmi.v4->flags & DM_INACTIVE_PRESENT_FLAG ? + 1 : 0; + info->target_count = dmt->dmi.v4->target_count; + info->open_count = dmt->dmi.v4->open_count; + info->event_nr = dmt->dmi.v4->event_nr; + info->major = MAJOR(dmt->dmi.v4->dev); + info->minor = MINOR(dmt->dmi.v4->dev); + + return 1; +} + +const char *dm_task_get_name(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_name_v1(dmt); +#endif + + return (dmt->dmi.v4->name); +} + +const char *dm_task_get_uuid(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_uuid_v1(dmt); +#endif + + return (dmt->dmi.v4->uuid); +} + +struct dm_deps *dm_task_get_deps(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_deps_v1(dmt); +#endif + + return (struct dm_deps *) (((void *) dmt->dmi.v4) + + dmt->dmi.v4->data_start); +} + +struct dm_names *dm_task_get_names(struct dm_task *dmt) +{ +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_get_names_v1(dmt); +#endif + + return (struct dm_names *) (((void *) dmt->dmi.v4) + + dmt->dmi.v4->data_start); +} + +int dm_task_set_ro(struct dm_task *dmt) +{ + dmt->read_only = 1; + return 1; +} + +int dm_task_set_newname(struct dm_task *dmt, const char *newname) +{ + if (!(dmt->newname = strdup(newname))) { + log_error("dm_task_set_newname: strdup(%s) failed", newname); + return 0; + } + + return 1; +} + +int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr) +{ + dmt->event_nr = event_nr; + + return 1; +} + +struct target *create_target(uint64_t start, uint64_t len, const char *type, + const char *params) +{ + struct target *t = malloc(sizeof(*t)); + + if (!t) { + log_error("create_target: malloc(%d) failed", sizeof(*t)); + return NULL; + } + + memset(t, 0, sizeof(*t)); + + if (!(t->params = strdup(params))) { + log_error("create_target: strdup(params) failed"); + goto bad; + } + + if (!(t->type = strdup(type))) { + log_error("create_target: strdup(type) failed"); + goto bad; + } + + t->start = start; + t->length = len; + return t; + + bad: + free(t->params); + free(t->type); + free(t); + return NULL; +} + +static void *_add_target(struct target *t, void *out, void *end) +{ + void *out_sp = out; + struct dm_target_spec sp; + size_t sp_size = sizeof(struct dm_target_spec); + int len; + const char no_space[] = "Ran out of memory building ioctl parameter"; + + out += sp_size; + if (out >= end) { + log_error(no_space); + return NULL; + } + + sp.status = 0; + sp.sector_start = t->start; + sp.length = t->length; + strncpy(sp.target_type, t->type, sizeof(sp.target_type)); + + len = strlen(t->params); + + if ((out + len + 1) >= end) { + log_error(no_space); + + log_error("t->params= '%s'", t->params); + return NULL; + } + strcpy((char *) out, t->params); + out += len + 1; + + /* align next block */ + out = _align(out, ALIGNMENT); + + sp.next = out - out_sp; + memcpy(out_sp, &sp, sp_size); + + return out; +} + +static struct dm_ioctl *_flatten(struct dm_task *dmt) +{ + const size_t min_size = 16 * 1024; + const int (*version)[3]; + + struct dm_ioctl *dmi; + struct target *t; + size_t len = sizeof(struct dm_ioctl); + void *b, *e; + int count = 0; + + for (t = dmt->head; t; t = t->next) { + len += sizeof(struct dm_target_spec); + len += strlen(t->params) + 1 + ALIGNMENT; + count++; + } + + if (count && dmt->newname) { + log_error("targets and newname are incompatible"); + return NULL; + } + + if (dmt->newname) + len += strlen(dmt->newname) + 1; + + /* + * Give len a minimum size so that we have space to store + * dependencies or status information. + */ + if (len < min_size) + len = min_size; + + if (!(dmi = malloc(len))) + return NULL; + + memset(dmi, 0, len); + + version = &_cmd_data_v4[dmt->type].version; + + dmi->version[0] = (*version)[0]; + dmi->version[1] = (*version)[1]; + dmi->version[2] = (*version)[2]; + + dmi->data_size = len; + dmi->data_start = sizeof(struct dm_ioctl); + + if (dmt->dev_name) + strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); + + if (dmt->type == DM_DEVICE_SUSPEND) + dmi->flags |= DM_SUSPEND_FLAG; + if (dmt->read_only) + dmi->flags |= DM_READONLY_FLAG; + + if (dmt->minor >= 0) { + if (dmt->major <= 0) { + log_error("Missing major number for persistent device"); + return NULL; + } + dmi->flags |= DM_PERSISTENT_DEV_FLAG; + dmi->dev = MKDEV(dmt->major, dmt->minor); + } + + if (dmt->uuid) + strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); + + dmi->target_count = count; + dmi->event_nr = dmt->event_nr; + + b = (void *) (dmi + 1); + e = (void *) ((char *) dmi + len); + + for (t = dmt->head; t; t = t->next) + if (!(b = _add_target(t, b, e))) + goto bad; + + if (dmt->newname) + strcpy(b, dmt->newname); + + return dmi; + + bad: + free(dmi); + return NULL; +} + +static int _create_and_load_v4(struct dm_task *dmt) +{ + struct dm_task *task; + int r; + + /* Use new task struct to create the device */ + if (!(task = dm_task_create(DM_DEVICE_CREATE))) { + log_error("Failed to create device-mapper task struct"); + return 0; + } + + /* Copy across relevant fields */ + if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { + dm_task_destroy(task); + return 0; + } + + if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) { + dm_task_destroy(task); + return 0; + } + + task->major = dmt->major; + task->minor = dmt->minor; + + r = dm_task_run(task); + dm_task_destroy(task); + if (!r) + return r; + + /* Next load the table */ + if (!(task = dm_task_create(DM_DEVICE_RELOAD))) { + log_error("Failed to create device-mapper task struct"); + return 0; + } + + /* Copy across relevant fields */ + if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { + dm_task_destroy(task); + return 0; + } + + task->read_only = dmt->read_only; + task->head = dmt->head; + task->tail = dmt->tail; + + r = dm_task_run(task); + + task->head = NULL; + task->tail = NULL; + dm_task_destroy(task); + if (!r) + return r; + + /* Use the original structure last so the info will be correct */ + dmt->type = DM_DEVICE_RESUME; + dmt->uuid = NULL; + free(dmt->uuid); + + r = dm_task_run(dmt); + + return r; +} + +int dm_task_run(struct dm_task *dmt) +{ + struct dm_ioctl *dmi = NULL; + unsigned int command; + +#ifdef DM_COMPAT + if (_dm_version == 1) + return _dm_task_run_v1(dmt); +#endif + + if ((unsigned) dmt->type >= + (sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) { + log_error("Internal error: unknown device-mapper task %d", + dmt->type); + goto bad; + } + + command = _cmd_data_v4[dmt->type].cmd; + + /* Old-style creation had a table supplied */ + if (dmt->type == DM_DEVICE_CREATE && dmt->head) + return _create_and_load_v4(dmt); + + if (!_open_control()) + return 0; + + dmi = _flatten(dmt); + if (!dmi) { + log_error("Couldn't create ioctl argument"); + return 0; + } + + if (dmt->type == DM_DEVICE_TABLE) + dmi->flags |= DM_STATUS_TABLE_FLAG; + + dmi->flags |= DM_EXISTS_FLAG; /* FIXME */ + log_debug("dm %s %s %s %s", _cmd_data_v4[dmt->type].name, dmi->name, + dmi->uuid, dmt->newname ? dmt->newname : ""); + if (ioctl(_control_fd, command, dmi) < 0) { + if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) || + (dmt->type == DM_DEVICE_MKNODES))) { + dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */ + goto ignore_error; + } + if (_log_suppress) + log_verbose("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + else + log_error("device-mapper ioctl cmd %d failed: %s", + _IOC_NR(command), strerror(errno)); + goto bad; + } + + ignore_error: + switch (dmt->type) { + case DM_DEVICE_CREATE: + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); + break; + + case DM_DEVICE_REMOVE: + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_RENAME: + rename_dev_node(dmt->dev_name, dmt->newname); + break; + + case DM_DEVICE_MKNODES: + if (dmi->flags & DM_EXISTS_FLAG) + add_dev_node(dmt->dev_name, MAJOR(dmi->dev), + MINOR(dmi->dev)); + else + rm_dev_node(dmt->dev_name); + break; + + case DM_DEVICE_STATUS: + case DM_DEVICE_TABLE: + case DM_DEVICE_WAITEVENT: + if (!_unmarshal_status(dmt, dmi)) + goto bad; + break; + } + + dmt->dmi.v4 = dmi; + return 1; + + bad: + free(dmi); + return 0; +} + +void dm_lib_release(void) +{ + if (_control_fd != -1) { + close(_control_fd); + _control_fd = -1; + } + update_devs(); +} + +void dm_lib_exit(void) +{ + if (_control_fd != -1) { + close(_control_fd); + _control_fd = -1; + } + _version_ok = 1; + _version_checked = 0; +} diff --git a/extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h b/extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h new file mode 100644 index 0000000000..af7a9f1f71 --- /dev/null +++ b/extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef _LINUX_LIBDM_COMPAT_H +#define _LINUX_LIBDM_COMPAT_H + +#include +#include +#include +#include + +struct dm_task; +struct dm_info; + +/* + * Old versions of structures for backwards compatibility. + */ + +struct dm_ioctl_v1 { + uint32_t version[3]; /* in/out */ + uint32_t data_size; /* total size of data passed in + * including this struct */ + + uint32_t data_start; /* offset to start of data + * relative to start of this struct */ + + int32_t target_count; /* in/out */ + int32_t open_count; /* out */ + uint32_t flags; /* in/out */ + + __kernel_dev_t dev; /* in/out */ + + char name[DM_NAME_LEN]; /* device name */ + char uuid[DM_UUID_LEN]; /* unique identifier for + * the block device */ +}; + +struct dm_target_spec_v1 { + int32_t status; /* used when reading from kernel only */ + uint64_t sector_start; + uint32_t length; + uint32_t next; + + char target_type[DM_MAX_TYPE_NAME]; + +}; + +struct dm_target_deps_v1 { + uint32_t count; + + __kernel_dev_t dev[0]; /* out */ +}; + +enum { + /* Top level cmds */ + DM_VERSION_CMD_V1 = 0, + DM_REMOVE_ALL_CMD_V1, + + /* device level cmds */ + DM_DEV_CREATE_CMD_V1, + DM_DEV_REMOVE_CMD_V1, + DM_DEV_RELOAD_CMD_V1, + DM_DEV_RENAME_CMD_V1, + DM_DEV_SUSPEND_CMD_V1, + DM_DEV_DEPS_CMD_V1, + DM_DEV_STATUS_CMD_V1, + + /* target level cmds */ + DM_TARGET_STATUS_CMD_V1, + DM_TARGET_WAIT_CMD_V1, +}; + +#define DM_VERSION_V1 _IOWR(DM_IOCTL, DM_VERSION_CMD_V1, struct dm_ioctl) +#define DM_REMOVE_ALL_V1 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD_V1, struct dm_ioctl) + +#define DM_DEV_CREATE_V1 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD_V1, struct dm_ioctl) +#define DM_DEV_REMOVE_V1 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD_V1, struct dm_ioctl) +#define DM_DEV_RELOAD_V1 _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD_V1, struct dm_ioctl) +#define DM_DEV_SUSPEND_V1 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD_V1, struct dm_ioctl) +#define DM_DEV_RENAME_V1 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD_V1, struct dm_ioctl) +#define DM_DEV_DEPS_V1 _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD_V1, struct dm_ioctl) +#define DM_DEV_STATUS_V1 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD_V1, struct dm_ioctl) + +#define DM_TARGET_STATUS_V1 _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD_V1, struct dm_ioctl) +#define DM_TARGET_WAIT_V1 _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD_V1, struct dm_ioctl) + +/* *INDENT-OFF* */ +static struct cmd_data _cmd_data_v1[] = { + { "create", DM_DEV_CREATE_V1, {1, 0, 0} }, + { "reload", DM_DEV_RELOAD_V1, {1, 0, 0} }, + { "remove", DM_DEV_REMOVE_V1, {1, 0, 0} }, + { "remove_all", DM_REMOVE_ALL_V1, {1, 0, 0} }, + { "suspend", DM_DEV_SUSPEND_V1, {1, 0, 0} }, + { "resume", DM_DEV_SUSPEND_V1, {1, 0, 0} }, + { "info", DM_DEV_STATUS_V1, {1, 0, 0} }, + { "deps", DM_DEV_DEPS_V1, {1, 0, 0} }, + { "rename", DM_DEV_RENAME_V1, {1, 0, 0} }, + { "version", DM_VERSION_V1, {1, 0, 0} }, + { "status", DM_TARGET_STATUS_V1, {1, 0, 0} }, + { "table", DM_TARGET_STATUS_V1, {1, 0, 0} }, + { "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} }, + { "names", 0, {4, 0, 0} }, + { "clear", 0, {4, 0, 0} }, + { "mknodes", 0, {4, 0, 0} }, +}; +/* *INDENT-ON* */ + +#endif diff --git a/extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h b/extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h new file mode 100644 index 0000000000..a8c0e20547 --- /dev/null +++ b/extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef LIB_DMTARGETS_H +#define LIB_DMTARGETS_H + +#include + +struct dm_ioctl; +struct dm_ioctl_v1; + +struct target { + uint64_t start; + uint64_t length; + char *type; + char *params; + + struct target *next; +}; + +struct dm_task { + int type; + char *dev_name; + + struct target *head, *tail; + + int read_only; + uint32_t event_nr; + int major; + int minor; + union { + struct dm_ioctl *v4; + struct dm_ioctl_v1 *v1; + } dmi; + char *newname; + + char *uuid; +}; + +struct cmd_data { + const char *name; + const int cmd; + const int version[3]; +}; + +int dm_check_version(void); + +#endif diff --git a/extras/multipath-tools/libdevmapper/libdevmapper.h b/extras/multipath-tools/libdevmapper/libdevmapper.h new file mode 100644 index 0000000000..6549af3641 --- /dev/null +++ b/extras/multipath-tools/libdevmapper/libdevmapper.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef LIB_DEVICE_MAPPER_H +#define LIB_DEVICE_MAPPER_H + +#include +#include + +#ifdef linux +# include +#endif + +/* + * Since it is quite laborious to build the ioctl + * arguments for the device-mapper people are + * encouraged to use this library. + * + * You will need to build a struct dm_task for + * each ioctl command you want to execute. + */ + +typedef void (*dm_log_fn) (int level, const char *file, int line, + const char *f, ...); + +/* + * The library user may wish to register their own + * logging function, by default errors go to + * stderr. + */ +void dm_log_init(dm_log_fn fn); +void dm_log_init_verbose(int level); + +enum { + DM_DEVICE_CREATE, + DM_DEVICE_RELOAD, + DM_DEVICE_REMOVE, + DM_DEVICE_REMOVE_ALL, + + DM_DEVICE_SUSPEND, + DM_DEVICE_RESUME, + + DM_DEVICE_INFO, + DM_DEVICE_DEPS, + DM_DEVICE_RENAME, + + DM_DEVICE_VERSION, + + DM_DEVICE_STATUS, + DM_DEVICE_TABLE, + DM_DEVICE_WAITEVENT, + + DM_DEVICE_LIST, + + DM_DEVICE_CLEAR, + + DM_DEVICE_MKNODES +}; + +struct dm_task; + +struct dm_task *dm_task_create(int type); +void dm_task_destroy(struct dm_task *dmt); + +int dm_task_set_name(struct dm_task *dmt, const char *name); +int dm_task_set_uuid(struct dm_task *dmt, const char *uuid); + +/* + * Retrieve attributes after an info. + */ +struct dm_info { + int exists; + int suspended; + int live_table; + int inactive_table; + int32_t open_count; + uint32_t event_nr; + uint32_t major; + uint32_t minor; /* minor device number */ + int read_only; /* 0:read-write; 1:read-only */ + + int32_t target_count; +}; + +struct dm_deps { + uint32_t count; + uint32_t filler; + uint64_t device[0]; +}; + +struct dm_names { + uint64_t dev; + uint32_t next; /* Offset to next struct from start of this struct */ + char name[0]; +}; + +int dm_get_library_version(char *version, size_t size); +int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size); +int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi); +const char *dm_task_get_name(struct dm_task *dmt); +const char *dm_task_get_uuid(struct dm_task *dmt); + +struct dm_deps *dm_task_get_deps(struct dm_task *dmt); +struct dm_names *dm_task_get_names(struct dm_task *dmt); + +int dm_task_set_ro(struct dm_task *dmt); +int dm_task_set_newname(struct dm_task *dmt, const char *newname); +int dm_task_set_minor(struct dm_task *dmt, int minor); +int dm_task_set_major(struct dm_task *dmt, int major); +int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr); + +/* + * Use these to prepare for a create or reload. + */ +int dm_task_add_target(struct dm_task *dmt, + uint64_t start, + uint64_t size, const char *ttype, const char *params); + +/* + * Format major/minor numbers correctly for input to driver + */ +int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor); + +/* Use this to retrive target information returned from a STATUS call */ +void *dm_get_next_target(struct dm_task *dmt, + void *next, uint64_t *start, uint64_t *length, + char **target_type, char **params); + +/* + * Call this to actually run the ioctl. + */ +int dm_task_run(struct dm_task *dmt); + +/* + * Configure the device-mapper directory + */ +int dm_set_dev_dir(const char *dir); +const char *dm_dir(void); + +/* Release library resources */ +void dm_lib_release(void); +void dm_lib_exit(void); + +#endif /* LIB_DEVICE_MAPPER_H */ diff --git a/extras/multipath-tools/libdevmapper/libdm-common.c b/extras/multipath-tools/libdevmapper/libdm-common.c new file mode 100644 index 0000000000..b0affd1eed --- /dev/null +++ b/extras/multipath-tools/libdevmapper/libdm-common.c @@ -0,0 +1,382 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#include "libdm-targets.h" +#include "libdm-common.h" +#include "list.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEV_DIR "/dev/" + +static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; + +static int _verbose = 0; + +/* + * Library users can provide their own logging + * function. + */ +static void _default_log(int level, const char *file, int line, + const char *f, ...) +{ + va_list ap; + + if (level > _LOG_WARN && !_verbose) + return; + + va_start(ap, f); + + if (level < _LOG_WARN) + vfprintf(stderr, f, ap); + else + vprintf(f, ap); + + va_end(ap); + + if (level < _LOG_WARN) + fprintf(stderr, "\n"); + else + fprintf(stdout, "\n"); +} + +dm_log_fn _log = _default_log; + +void dm_log_init(dm_log_fn fn) +{ + _log = fn; +} + +void dm_log_init_verbose(int level) +{ + _verbose = level; +} + +static void _build_dev_path(char *buffer, size_t len, const char *dev_name) +{ + /* If there's a /, assume caller knows what they're doing */ + if (strchr(dev_name, '/')) + snprintf(buffer, len, "%s", dev_name); + else + snprintf(buffer, len, "%s/%s", _dm_dir, dev_name); +} + +int dm_get_library_version(char *version, size_t size) +{ + strncpy(version, DM_LIB_VERSION, size); + return 1; +} + +struct dm_task *dm_task_create(int type) +{ + struct dm_task *dmt = malloc(sizeof(*dmt)); + + if (!dm_check_version()) + return NULL; + + if (!dmt) { + log_error("dm_task_create: malloc(%d) failed", sizeof(*dmt)); + return NULL; + } + + memset(dmt, 0, sizeof(*dmt)); + + dmt->type = type; + dmt->minor = -1; + dmt->major = -1; + + return dmt; +} + +int dm_task_set_name(struct dm_task *dmt, const char *name) +{ + char *pos; + char path[PATH_MAX]; + struct stat st1, st2; + + if (dmt->dev_name) { + free(dmt->dev_name); + dmt->dev_name = NULL; + } + + /* If path was supplied, remove it if it points to the same device + * as its last component. + */ + if ((pos = strrchr(name, '/'))) { + snprintf(path, sizeof(path), "%s/%s", _dm_dir, pos + 1); + + if (stat(name, &st1) || stat(path, &st2) || + !(st1.st_dev == st2.st_dev)) { + log_error("dm_task_set_name: Device %s not found", + name); + return 0; + } + + name = pos + 1; + } + + if (!(dmt->dev_name = strdup(name))) { + log_error("dm_task_set_name: strdup(%s) failed", name); + return 0; + } + + return 1; +} + +int dm_task_set_uuid(struct dm_task *dmt, const char *uuid) +{ + if (dmt->uuid) { + free(dmt->uuid); + dmt->uuid = NULL; + } + + if (!(dmt->uuid = strdup(uuid))) { + log_error("dm_task_set_uuid: strdup(%s) failed", uuid); + return 0; + } + + return 1; +} + +int dm_task_set_major(struct dm_task *dmt, int major) +{ + dmt->major = major; + log_debug("Setting major: %d", dmt->major); + + return 1; +} + +int dm_task_set_minor(struct dm_task *dmt, int minor) +{ + dmt->minor = minor; + log_debug("Setting minor: %d", dmt->minor); + + return 1; +} + +int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size, + const char *ttype, const char *params) +{ + struct target *t = create_target(start, size, ttype, params); + + if (!t) + return 0; + + if (!dmt->head) + dmt->head = dmt->tail = t; + else { + dmt->tail->next = t; + dmt->tail = t; + } + + return 1; +} + +static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) +{ + char path[PATH_MAX]; + struct stat info; + dev_t dev = MKDEV(major, minor); + + _build_dev_path(path, sizeof(path), dev_name); + + if (stat(path, &info) >= 0) { + if (!S_ISBLK(info.st_mode)) { + log_error("A non-block device file at '%s' " + "is already present", path); + return 0; + } + + if (info.st_rdev == dev) + return 1; + + if (unlink(path) < 0) { + log_error("Unable to unlink device node for '%s'", + dev_name); + return 0; + } + } + + if (mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, dev) < 0) { + log_error("Unable to make device node for '%s'", dev_name); + return 0; + } + + return 1; +} + +static int _rename_dev_node(const char *old_name, const char *new_name) +{ + char oldpath[PATH_MAX]; + char newpath[PATH_MAX]; + struct stat info; + + _build_dev_path(oldpath, sizeof(oldpath), old_name); + _build_dev_path(newpath, sizeof(newpath), new_name); + + if (stat(newpath, &info) == 0) { + if (!S_ISBLK(info.st_mode)) { + log_error("A non-block device file at '%s' " + "is already present", newpath); + return 0; + } + + if (unlink(newpath) < 0) { + if (errno == EPERM) { + /* devfs, entry has already been renamed */ + return 1; + } + log_error("Unable to unlink device node for '%s'", + new_name); + return 0; + } + } + + if (rename(oldpath, newpath) < 0) { + log_error("Unable to rename device node from '%s' to '%s'", + old_name, new_name); + return 0; + } + + return 1; +} + +static int _rm_dev_node(const char *dev_name) +{ + char path[PATH_MAX]; + struct stat info; + + _build_dev_path(path, sizeof(path), dev_name); + + if (stat(path, &info) < 0) + return 1; + + if (unlink(path) < 0) { + log_error("Unable to unlink device node for '%s'", dev_name); + return 0; + } + + return 1; +} + +typedef enum { + NODE_ADD, + NODE_DEL, + NODE_RENAME +} node_op_t; + +static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major, + uint32_t minor, const char *old_name) +{ + switch (type) { + case NODE_ADD: + return _add_dev_node(dev_name, major, minor); + case NODE_DEL: + return _rm_dev_node(dev_name); + case NODE_RENAME: + return _rename_dev_node(old_name, dev_name); + } + + return 1; +} + +static LIST_INIT(_node_ops); + +struct node_op_parms { + struct list list; + node_op_t type; + char *dev_name; + uint32_t major; + uint32_t minor; + char *old_name; + char names[0]; +}; + +static void _store_str(char **pos, char **ptr, const char *str) +{ + strcpy(*pos, str); + *ptr = *pos; + *pos += strlen(*ptr) + 1; +} + +static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major, + uint32_t minor, const char *old_name) +{ + struct node_op_parms *nop; + size_t len = strlen(dev_name) + strlen(old_name) + 2; + char *pos; + + if (!(nop = malloc(sizeof(*nop) + len))) { + log_error("Insufficient memory to stack mknod operation"); + return 0; + } + + pos = nop->names; + nop->type = type; + nop->major = major; + nop->minor = minor; + + _store_str(&pos, &nop->dev_name, dev_name); + _store_str(&pos, &nop->old_name, old_name); + + list_add(&_node_ops, &nop->list); + + return 1; +} + +static void _pop_node_ops(void) +{ + struct list *noph, *nopht; + struct node_op_parms *nop; + + list_iterate_safe(noph, nopht, &_node_ops) { + nop = list_item(noph, struct node_op_parms); + _do_node_op(nop->type, nop->dev_name, nop->major, nop->minor, + nop->old_name); + list_del(&nop->list); + free(nop); + } +} + +int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) +{ + return _stack_node_op(NODE_ADD, dev_name, major, minor, ""); +} + +int rename_dev_node(const char *old_name, const char *new_name) +{ + return _stack_node_op(NODE_RENAME, new_name, 0, 0, old_name); +} + +int rm_dev_node(const char *dev_name) +{ + return _stack_node_op(NODE_DEL, dev_name, 0, 0, ""); +} + +void update_devs(void) +{ + _pop_node_ops(); +} + +int dm_set_dev_dir(const char *dir) +{ + snprintf(_dm_dir, sizeof(_dm_dir), "%s%s", dir, DM_DIR); + return 1; +} + +const char *dm_dir(void) +{ + return _dm_dir; +} diff --git a/extras/multipath-tools/libdevmapper/libdm-common.h b/extras/multipath-tools/libdevmapper/libdm-common.h new file mode 100644 index 0000000000..2b71242861 --- /dev/null +++ b/extras/multipath-tools/libdevmapper/libdm-common.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2001 Sistina Software (UK) Limited. + * + * This file is released under the LGPL. + */ + +#ifndef LIB_DMCOMMON_H +#define LIB_DMCOMMON_H + +#include "libdevmapper.h" + +#define _LOG_DEBUG 7 +#define _LOG_INFO 6 +#define _LOG_NOTICE 5 +#define _LOG_WARN 4 +#define _LOG_ERR 3 +#define _LOG_FATAL 2 + +extern dm_log_fn _log; + +#define log_error(msg, x...) _log(_LOG_ERR, __FILE__, __LINE__, msg, ## x) +#define log_print(msg, x...) _log(_LOG_WARN, __FILE__, __LINE__, msg, ## x) +#define log_verbose(msg, x...) _log(_LOG_NOTICE, __FILE__, __LINE__, msg, ## x) +#define log_very_verbose(msg, x...) _log(_LOG_INFO, __FILE__, __LINE__, msg, ## x) +#define log_debug(msg, x...) _log(_LOG_DEBUG, __FILE__, __LINE__, msg, ## x) + +struct target *create_target(uint64_t start, + uint64_t len, + const char *type, const char *params); + +int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major); +int rm_dev_node(const char *dev_name); +int rename_dev_node(const char *old_name, const char *new_name); +void update_devs(void); + +#define DM_LIB_VERSION "1.00.07-ioctl (2003-11-21)" + +#endif diff --git a/extras/multipath-tools/libdevmapper/list.h b/extras/multipath-tools/libdevmapper/list.h new file mode 100644 index 0000000000..df3d32aea8 --- /dev/null +++ b/extras/multipath-tools/libdevmapper/list.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2001 Sistina Software + * + * This file is released under the LGPL. + */ + +#ifndef _LVM_LIST_H +#define _LVM_LIST_H + +#include + +struct list { + struct list *n, *p; +}; + +#define LIST_INIT(name) struct list name = { &(name), &(name) } + +static inline void list_init(struct list *head) +{ + head->n = head->p = head; +} + +static inline void list_add(struct list *head, struct list *elem) +{ + assert(head->n); + + elem->n = head; + elem->p = head->p; + + head->p->n = elem; + head->p = elem; +} + +static inline void list_add_h(struct list *head, struct list *elem) +{ + assert(head->n); + + elem->n = head->n; + elem->p = head; + + head->n->p = elem; + head->n = elem; +} + +static inline void list_del(struct list *elem) +{ + elem->n->p = elem->p; + elem->p->n = elem->n; +} + +static inline int list_empty(struct list *head) +{ + return head->n == head; +} + +static inline int list_end(struct list *head, struct list *elem) +{ + return elem->n == head; +} + +static inline struct list *list_next(struct list *head, struct list *elem) +{ + return (list_end(head, elem) ? NULL : elem->n); +} + +#define list_iterate(v, head) \ + for (v = (head)->n; v != head; v = v->n) + +#define list_uniterate(v, head, start) \ + for (v = (start)->p; v != head; v = v->p) + +#define list_iterate_safe(v, t, head) \ + for (v = (head)->n, t = v->n; v != head; v = t, t = v->n) + +static inline unsigned int list_size(const struct list *head) +{ + unsigned int s = 0; + const struct list *v; + + list_iterate(v, head) + s++; + + return s; +} + +#define list_item(v, t) \ + ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list)) + +#define list_struct_base(v, t, h) \ + ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h)) + +/* Given a known element in a known structure, locate another */ +#define struct_field(v, t, e, f) \ + (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f) + +/* Given a known element in a known structure, locate the list head */ +#define list_head(v, t, e) struct_field(v, t, e, list) + +#endif diff --git a/extras/multipath-tools/multipath/Makefile b/extras/multipath-tools/multipath/Makefile new file mode 100644 index 0000000000..4121f4fc3b --- /dev/null +++ b/extras/multipath-tools/multipath/Makefile @@ -0,0 +1,60 @@ +# Makefile +# +# Copyright (C) 2003 Christophe Varoqui, + +EXEC = multipath + +prefix = +exec_prefix = ${prefix} +bindir = ${exec_prefix}/sbin +udevdir = ../../.. +klibcdir = $(udevdir)/klibc +sysfsdir = $(udevdir)/libsysfs +mandir = /usr/share/man/man8 +libdmdir = ../libdevmapper +arch = i386 +klibcarch = $(klibcdir)/klibc/arch/$(arch)/include + +CC = gcc +GZIP = /bin/gzip -9 -c + +GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} +KERNEL_DIR = /lib/modules/${shell uname -r}/build +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ + -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ + -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. -I$(klibcarch) + +OBJS = devinfo.o main.o +CRT0 = $(klibcdir)/klibc/crt0.o +LIB = $(klibcdir)/klibc/libc.a +LIBGCC := $(shell $(CC) -print-libgcc-file-name ) + +DMOBJS = $(libdmdir)/libdm-common.o $(libdmdir)/ioctl/libdevmapper.o +SYSFSOBJS = $(sysfsdir)/dlist.o $(sysfsdir)/sysfs_bus.o \ + $(sysfsdir)/sysfs_class.o $(sysfsdir)/sysfs_device.o \ + $(sysfsdir)/sysfs_dir.o $(sysfsdir)/sysfs_driver.o \ + $(sysfsdir)/sysfs_utils.o + +$(EXEC): $(OBJS) + $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(SYSFSOBJS) $(DMOBJS) $(LIB) $(LIBGCC) + strip $(EXEC) + $(GZIP) $(EXEC).8 > $(EXEC).8.gz + +clean: + rm -f core *.o $(EXEC) *.gz + +install: + install -d $(DESTDIR)$(bindir) + install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ + install -d $(DESTDIR)/etc/hotplug.d/scsi/ + install -m 755 multipath.hotplug $(DESTDIR)/etc/hotplug.d/scsi/ + install -d $(DESTDIR)$(mandir) + install -m 644 multipath.8.gz $(DESTDIR)$(mandir) + +uninstall: + rm $(DESTDIR)/etc/hotplug.d/scsi/multipath.hotplug + rm $(DESTDIR)$(bindir)/$(EXEC) + rm $(DESTDIR)$(mandir)/multipath.8.gz + +# Code dependencies +main.o: main.c main.h sg_include.h devinfo.h diff --git a/extras/multipath-tools/multipath/devinfo.c b/extras/multipath-tools/multipath/devinfo.c new file mode 100644 index 0000000000..21890621e0 --- /dev/null +++ b/extras/multipath-tools/multipath/devinfo.c @@ -0,0 +1,240 @@ +#include +#include +#include +#include +#include +#include +#include "devinfo.h" +#include "sg_include.h" + +#define FILE_NAME_SIZE 255 + +void +basename(char * str1, char * str2) +{ + char *p = str1 + (strlen(str1) - 1); + + while (*--p != '/') + continue; + strcpy(str2, ++p); +} + +static int +do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, + void *resp, int mx_resp_len, int noisy) +{ + unsigned char inqCmdBlk[INQUIRY_CMDLEN] = + { INQUIRY_CMD, 0, 0, 0, 0, 0 }; + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_io_hdr io_hdr; + + if (cmddt) + inqCmdBlk[1] |= 2; + if (evpd) + inqCmdBlk[1] |= 1; + inqCmdBlk[2] = (unsigned char) pg_op; + inqCmdBlk[4] = (unsigned char) mx_resp_len; + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (inqCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_b); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = mx_resp_len; + io_hdr.dxferp = resp; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sense_b; + io_hdr.timeout = DEF_TIMEOUT; + + if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { + perror("SG_IO (inquiry) error"); + return -1; + } + + /* treat SG_ERR here to get rid of sg_err.[ch] */ + io_hdr.status &= 0x7e; + if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && + (0 == io_hdr.driver_status)) + return 0; + if ((SCSI_CHECK_CONDITION == io_hdr.status) || + (SCSI_COMMAND_TERMINATED == io_hdr.status) || + (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { + if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { + int sense_key; + unsigned char * sense_buffer = io_hdr.sbp; + if (sense_buffer[0] & 0x2) + sense_key = sense_buffer[1] & 0xf; + else + sense_key = sense_buffer[2] & 0xf; + if(RECOVERED_ERROR == sense_key) + return 0; + } + } + return -1; +} + +int +get_serial (char * str, char * devname) +{ + int fd; + int len; + char buff[MX_ALLOC_LEN + 1]; + + if ((fd = open(devname, O_RDONLY)) < 0) + return 0; + + if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { + len = buff[3]; + if (len > 0) { + memcpy(str, buff + 4, len); + buff[len] = '\0'; + } + close(fd); + return 1; + } + close(fd); + return 0; +} + +int +get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname) +{ + int fd; + char buff[36]; + char attr_path[FILE_NAME_SIZE]; + char sysfs_path[FILE_NAME_SIZE]; + char basedev[FILE_NAME_SIZE]; + + if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { + /* sysfs style */ + basename(devname, basedev); + + sprintf(attr_path, "%s/block/%s/device/vendor", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + vendor_id, 8)) return 0; + + sprintf(attr_path, "%s/block/%s/device/model", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + product_id, 16)) return 0; + + sprintf(attr_path, "%s/block/%s/device/rev", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, + rev, 4)) return 0; + } else { + /* ioctl style */ + if ((fd = open(devname, O_RDONLY)) < 0) + return 0; + if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) + return 0; + memcpy(vendor_id, &buff[8], 8); + memcpy(product_id, &buff[16], 16); + memcpy(rev, &buff[32], 4); + close(fd); + return 1; + } + return 0; +} + +static void +sprint_wwid(char * buff, const char * str) +{ + int i; + const char *p; + char *cursor; + unsigned char c; + + p = str; + cursor = buff; + for (i = 0; i <= WWID_SIZE / 2 - 1; i++) { + c = *p++; + sprintf(cursor, "%.2x", (int) (unsigned char) c); + cursor += 2; + } + buff[WWID_SIZE - 1] = '\0'; +} + +/* get EVPD page 0x83 off 8 */ +/* tested ok with StorageWorks */ +int +get_evpd_wwid(char * devname, char * wwid) +{ + int fd; + char buff[MX_ALLOC_LEN + 1]; + + if ((fd = open(devname, O_RDONLY)) < 0) + return 0; + + if (0 == do_inq(fd, 0, 1, 0x83, buff, MX_ALLOC_LEN, 1)) { + sprint_wwid(wwid, &buff[8]); + close(fd); + return 1; /* success */ + } + + close(fd); + return 0; /* not good */ +} + +long +get_disk_size (char * devname) { + long size; + int fd; + char attr_path[FILE_NAME_SIZE]; + char sysfs_path[FILE_NAME_SIZE]; + char buff[FILE_NAME_SIZE]; + char basedev[FILE_NAME_SIZE]; + + if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { + basename(devname, basedev); + sprintf(attr_path, "%s/block/%s/size", + sysfs_path, basedev); + if (0 > sysfs_read_attribute_value(attr_path, buff, + FILE_NAME_SIZE * sizeof(char))) + return -1; + size = atoi(buff); + return size; + } else { + if ((fd = open(devname, O_RDONLY)) < 0) + return -1; + if(!ioctl(fd, BLKGETSIZE, &size)) + return size; + } + return -1; +} + +int +do_tur(char *dev) +{ + unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; + struct sg_io_hdr io_hdr; + unsigned char sense_buffer[32]; + int fd; + + fd = open(dev, O_RDONLY); + + if (fd < 0) + return 0; + + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (turCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_buffer); + io_hdr.dxfer_direction = SG_DXFER_NONE; + io_hdr.cmdp = turCmdBlk; + io_hdr.sbp = sense_buffer; + io_hdr.timeout = 20000; + io_hdr.pack_id = 0; + + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + close(fd); + return 0; + } + + close(fd); + + if (io_hdr.info & SG_INFO_OK_MASK) + return 0; + + return 1; +} diff --git a/extras/multipath-tools/multipath/devinfo.h b/extras/multipath-tools/multipath/devinfo.h new file mode 100644 index 0000000000..ee17aba923 --- /dev/null +++ b/extras/multipath-tools/multipath/devinfo.h @@ -0,0 +1,21 @@ +#define INQUIRY_CMDLEN 6 +#define INQUIRY_CMD 0x12 +#define SENSE_BUFF_LEN 32 +#define DEF_TIMEOUT 60000 +#define RECOVERED_ERROR 0x01 +#define MX_ALLOC_LEN 255 +#define WWID_SIZE 33 +#define BLKGETSIZE _IO(0x12,96) +#define TUR_CMD_LEN 6 + +/* exerpt from "sg_err.h" */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SG_ERR_DRIVER_SENSE 0x08 + +void basename (char *, char *); +int get_serial (char *, char *); +int get_lun_strings (char *, char *, char *, char *); +int get_evpd_wwid(char *, char *); +long get_disk_size (char *); +int do_tur (char *); diff --git a/extras/multipath-tools/multipath/main.c b/extras/multipath-tools/multipath/main.c new file mode 100644 index 0000000000..8f06a8f94c --- /dev/null +++ b/extras/multipath-tools/multipath/main.c @@ -0,0 +1,895 @@ +/* + * Soft: multipath device mapper target autoconfig + * + * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ + * + * Author: Copyright (C) 2003 Christophe Varoqui + * + * 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. + * + * 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 +#include "../libdevmapper/libdevmapper.h" +#include "main.h" +#include "devinfo.h" + +/* White list switch */ +static int +get_unique_id(struct path * mypath) +{ + int i; + static struct { + char * vendor; + char * product; + int iopolicy; + int (*getuid) (char *, char *); + } wlist[] = { + {"COMPAQ ", "HSV110 (C)COMPAQ", GROUP_BY_TUR, &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 ", GROUP_BY_TUR, &get_evpd_wwid}, + {"COMPAQ ", "MSA1000 VOLUME ", GROUP_BY_TUR, &get_evpd_wwid}, + {"DEC ", "HSG80 ", GROUP_BY_TUR, &get_evpd_wwid}, + {"HP ", "HSV100 ", GROUP_BY_TUR, &get_evpd_wwid}, + {"HP ", "A6189A ", MULTIBUS, &get_evpd_wwid}, + {"HP ", "OPEN- ", MULTIBUS, &get_evpd_wwid}, + {"DDN ", "SAN DataDirector", MULTIBUS, &get_evpd_wwid}, + {"FSC ", "CentricStor ", MULTIBUS, &get_evpd_wwid}, + {"HITACHI ", "DF400 ", MULTIBUS, &get_evpd_wwid}, + {"HITACHI ", "DF500 ", MULTIBUS, &get_evpd_wwid}, + {"HITACHI ", "DF600 ", MULTIBUS, &get_evpd_wwid}, + {"IBM ", "ProFibre 4000R ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9100 ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9300 ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9400 ", MULTIBUS, &get_evpd_wwid}, + {"SGI ", "TP9500 ", MULTIBUS, &get_evpd_wwid}, + {NULL, NULL, 0, NULL}, + }; + + for (i = 0; wlist[i].vendor; i++) { + if (strncmp(mypath->vendor_id, wlist[i].vendor, 8) == 0 && + strncmp(mypath->product_id, wlist[i].product, 16) == 0) { + mypath->iopolicy = wlist[i].iopolicy; + if (!wlist[i].getuid(mypath->sg_dev, mypath->wwid)) + return 0; + } + } + return 1; +} + +static int +sysfsdevice2devname (char *devname, char *device) +{ + char sysfs_path[FILE_NAME_SIZE]; + char block_path[FILE_NAME_SIZE]; + char link_path[FILE_NAME_SIZE]; + int r; + + if (sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { + fprintf(stderr, "[device] feature available with sysfs only\n"); + exit (1); + } + + sprintf(link_path, "%s%s/block", sysfs_path, device); + + r = sysfs_get_link(link_path, block_path, FILE_NAME_SIZE); + + if (r != 0) + return 1; + + sysfs_get_name_from_path(block_path, devname, FILE_NAME_SIZE); + + return 0; +} + + +static int +devt2devname (char *devname, int major, int minor) +{ + struct sysfs_directory * sdir; + struct sysfs_directory * devp; + char sysfs_path[FILE_NAME_SIZE]; + char block_path[FILE_NAME_SIZE]; + char attr_path[FILE_NAME_SIZE]; + char attr_value[16]; + char attr_ref_value[16]; + + if (sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { + fprintf(stderr, "-D feature available with sysfs only\n"); + exit (1); + } + + sprintf(attr_ref_value, "%i:%i\n", major, minor); + sprintf(block_path, "%s/block", sysfs_path); + sdir = sysfs_open_directory(block_path); + sysfs_read_directory(sdir); + + dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { + sprintf(attr_path, "%s/%s/dev", block_path, devp->name); + sysfs_read_attribute_value(attr_path, attr_value, 16); + + if (!strcmp(attr_value, attr_ref_value)) { + sprintf(attr_path, "%s/%s", block_path, devp->name); + sysfs_get_name_from_path(attr_path, devname, FILE_NAME_SIZE); + break; + } + } + + sysfs_close_directory(sdir); + + return 0; +} + +static int +blacklist (char * dev) { + int i; + static struct { + char * headstr; + int lengh; + } blist[] = { + {"cciss", 5}, + {"hd", 2}, + {"md", 2}, + {"dm", 2}, + {"sr", 2}, + {"scd", 3}, + {"ram", 3}, + {"raw", 3}, + {NULL, 0}, + }; + + for (i = 0; blist[i].lengh; i++) { + if (strncmp(dev, blist[i].headstr, blist[i].lengh) == 0) + return 1; + } + return 0; +} + +static int +devinfo (struct path *curpath) +{ + get_lun_strings(curpath->vendor_id, + curpath->product_id, + curpath->rev, + curpath->sg_dev); + get_serial(curpath->serial, curpath->sg_dev); + curpath->tur = do_tur(curpath->sg_dev); + if (!get_unique_id(curpath)) + return 1; + + return 0; +} + + +static int +get_all_paths_sysfs(struct env * conf, struct path * all_paths) +{ + int k=0; + struct sysfs_directory * sdir; + struct sysfs_directory * devp; + struct sysfs_link * linkp; + char refwwid[WWID_SIZE]; + char empty_buff[WWID_SIZE]; + char buff[FILE_NAME_SIZE]; + char path[FILE_NAME_SIZE]; + struct path curpath; + + memset(empty_buff, 0, WWID_SIZE); + memset(refwwid, 0, WWID_SIZE); + + /* if called from hotplug, only consider the paths that relate + to the device pointed by conf.hotplugdev */ + + if (strncmp("/devices", conf->hotplugdev, 8) == 0) { + if (sysfsdevice2devname (buff, conf->hotplugdev)) + return 0; + + sprintf(curpath.sg_dev, "/dev/%s", buff); + + if (devinfo(&curpath)) + return 0; + + strcpy(refwwid, curpath.wwid); + memset(&curpath, 0, sizeof(path)); + } + + /* if major/minor specified on the cmd line, + only consider affiliated paths */ + + if (conf->major >= 0 && conf->minor >= 0) { + if (devt2devname(buff, conf->major, conf->minor)) + return 0; + + sprintf(curpath.sg_dev, "/dev/%s", buff); + + if (devinfo(&curpath)) + return 0; + + strcpy(refwwid, curpath.wwid); + memset(&curpath, 0, sizeof(path)); + } + + + sprintf(path, "%s/block", conf->sysfs_path); + sdir = sysfs_open_directory(path); + sysfs_read_directory(sdir); + + dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { + if (blacklist(devp->name)) + continue; + + sysfs_read_directory(devp); + + if(devp->links == NULL) + continue; + + dlist_for_each_data(devp->links, linkp, struct sysfs_link) { + if (!strncmp(linkp->name, "device", 6)) + break; + } + + if (linkp == NULL) { + continue; + } + + basename(devp->path, buff); + sprintf(curpath.sg_dev, "/dev/%s", buff); + + if(devinfo(&curpath)) { + memset(&curpath, 0, sizeof(path)); + continue; + } + + if (memcmp(empty_buff, refwwid, WWID_SIZE) != 0 && + strncmp(curpath.wwid, refwwid, WWID_SIZE) != 0) { + memset(&curpath, 0, sizeof(path)); + continue; + } + + strcpy(all_paths[k].sg_dev, curpath.sg_dev); + strcpy(all_paths[k].dev, curpath.sg_dev); + strcpy(all_paths[k].wwid, curpath.wwid); + strcpy(all_paths[k].vendor_id, curpath.vendor_id); + strcpy(all_paths[k].product_id, curpath.product_id); + all_paths[k].iopolicy = curpath.iopolicy; + all_paths[k].tur = curpath.tur; + + /* done with curpath, zero for reuse */ + memset(&curpath, 0, sizeof(path)); + + basename(linkp->target, buff); + sscanf(buff, "%i:%i:%i:%i", + &all_paths[k].sg_id.host_no, + &all_paths[k].sg_id.channel, + &all_paths[k].sg_id.scsi_id, + &all_paths[k].sg_id.lun); + k++; + } + sysfs_close_directory(sdir); + return 0; +} + +static int +get_all_paths_nosysfs(struct env * conf, struct path * all_paths, + struct scsi_dev * all_scsi_ids) +{ + int k, i, fd; + char buff[FILE_NAME_SIZE]; + char file_name[FILE_NAME_SIZE]; + + for (k = 0; k < conf->max_devs; k++) { + strcpy(file_name, "/dev/sg"); + sprintf(buff, "%d", k); + strncat(file_name, buff, FILE_NAME_SIZE); + strcpy(all_paths[k].sg_dev, file_name); + + get_lun_strings(all_paths[k].vendor_id, + all_paths[k].product_id, + all_paths[k].rev, + all_paths[k].sg_dev); + get_serial(all_paths[k].serial, all_paths[k].sg_dev); + if (!get_unique_id(&all_paths[k])) + continue; + + if ((fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) + return 0; + + if (0 > ioctl(fd, SG_GET_SCSI_ID, &(all_paths[k].sg_id))) + printf("device %s failed on sg ioctl, skip\n", + file_name); + + close(fd); + + for (i = 0; i < conf->max_devs; i++) { + if ((all_paths[k].sg_id.host_no == + all_scsi_ids[i].host_no) + && (all_paths[k].sg_id.scsi_id == + (all_scsi_ids[i].scsi_id.dev_id & 0xff)) + && (all_paths[k].sg_id.lun == + ((all_scsi_ids[i].scsi_id.dev_id >> 8) & 0xff)) + && (all_paths[k].sg_id.channel == + ((all_scsi_ids[i].scsi_id. + dev_id >> 16) & 0xff))) { + strcpy(all_paths[k].dev, all_scsi_ids[i].dev); + break; + } + } + } + return 0; +} + +static int +get_all_scsi_ids(struct env * conf, struct scsi_dev * all_scsi_ids) +{ + int k, big, little, res, host_no, fd; + char buff[64]; + char fname[FILE_NAME_SIZE]; + struct scsi_idlun my_scsi_id; + + for (k = 0; k < conf->max_devs; k++) { + strcpy(fname, "/dev/sd"); + if (k < 26) { + buff[0] = 'a' + (char) k; + buff[1] = '\0'; + strcat(fname, buff); + } else if (k <= 255) { + /* assumes sequence goes x,y,z,aa,ab,ac etc */ + big = k / 26; + little = k - (26 * big); + big = big - 1; + + buff[0] = 'a' + (char) big; + buff[1] = 'a' + (char) little; + buff[2] = '\0'; + strcat(fname, buff); + } else + strcat(fname, "xxxx"); + + if ((fd = open(fname, O_RDONLY)) < 0) { + if (conf->verbose) + fprintf(stderr, "can't open %s. mknod ?", + fname); + continue; + } + + res = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &my_scsi_id); + if (res < 0) { + close(fd); + printf("Could not get scsi idlun\n"); + continue; + } + + res = ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &host_no); + if (res < 0) { + close(fd); + printf("Could not get host_no\n"); + continue; + } + + close(fd); + + strcpy(all_scsi_ids[k].dev, fname); + all_scsi_ids[k].scsi_id = my_scsi_id; + all_scsi_ids[k].host_no = host_no; + } + return 0; +} + +/* print_path style */ +#define ALL 0 +#define NOWWID 1 + +static void +print_path(struct path * all_paths, int k, int style) +{ + if (style != NOWWID) + printf("%s ", all_paths[k].wwid); + else + printf(" \\_"); + printf("(%i %i %i %i) ", + all_paths[k].sg_id.host_no, + all_paths[k].sg_id.channel, + all_paths[k].sg_id.scsi_id, all_paths[k].sg_id.lun); + if(0 != strcmp(all_paths[k].sg_dev, all_paths[k].dev)) + printf("%s ", all_paths[k].sg_dev); + printf("%s ", all_paths[k].dev); + printf("[%.16s]\n", all_paths[k].product_id); +} + +static void +print_all_path(struct env * conf, struct path * all_paths) +{ + int k; + char empty_buff[WWID_SIZE]; + + memset(empty_buff, 0, WWID_SIZE); + for (k = 0; k < conf->max_devs; k++) { + if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) + continue; + print_path(all_paths, k, ALL); + } +} + +static void +print_all_mp(struct path * all_paths, struct multipath * mp, int nmp) +{ + int k, i; + + for (k = 0; k <= nmp; k++) { + printf("%s\n", mp[k].wwid); + for (i = 0; i <= mp[k].npaths; i++) + print_path(all_paths, PINDEX(k,i), NOWWID); + } +} + +static int +coalesce_paths(struct env * conf, struct multipath * mp, + struct path * all_paths) +{ + int k, i, nmp, np, already_done; + char empty_buff[WWID_SIZE]; + + nmp = -1; + already_done = 0; + memset(empty_buff, 0, WWID_SIZE); + + for (k = 0; k < conf->max_devs - 1; k++) { + /* skip this path for some reason */ + + /* 1. if path has no unique id */ + if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) + continue; + + /* 2. if mp with this uid already instanciated */ + for (i = 0; i <= nmp; i++) { + if (0 == strcmp(mp[i].wwid, all_paths[k].wwid)) + already_done = 1; + } + if (already_done) { + already_done = 0; + continue; + } + + /* at this point, we know we really got a new mp */ + np = 0; + nmp++; + strcpy(mp[nmp].wwid, all_paths[k].wwid); + PINDEX(nmp,np) = k; + + if (mp[nmp].size == 0) + mp[nmp].size = get_disk_size(all_paths[k].dev); + + for (i = k + 1; i < conf->max_devs; i++) { + if (0 == strcmp(all_paths[k].wwid, all_paths[i].wwid)) { + np++; + PINDEX(nmp,np) = i; + mp[nmp].npaths = np; + } + } + } + return nmp; +} + +static void +group_by_tur(struct multipath * mp, struct path * all_paths, char * str) { + int left_path_count = 0; + int right_path_count = 0; + int i; + char left_path_buff[FILE_NAME_SIZE], right_path_buff[FILE_NAME_SIZE]; + char * left_path_buff_p = &left_path_buff[0]; + char * right_path_buff_p = &right_path_buff[0]; + + for (i = 0; i <= mp->npaths; i++) { + if (all_paths[mp->pindex[i]].tur) { + left_path_buff_p += sprintf(left_path_buff_p, " %s", all_paths[mp->pindex[i]].dev); + left_path_count++; + } else { + right_path_buff_p += sprintf(right_path_buff_p, " %s", all_paths[mp->pindex[i]].dev); + right_path_count++; + } + } + if (!left_path_count) + sprintf(str, " 1 round-robin %i 0 %s", right_path_count, right_path_buff); + else if (!right_path_count) + sprintf(str, " 1 round-robin %i 0 %s", left_path_count, left_path_buff); + else + sprintf(str, " 2 round-robin %i 0 %s round-robin %i 0 %s", + left_path_count, left_path_buff, + right_path_count, right_path_buff); +} + +static void +group_by_serial(struct multipath * mp, struct path * all_paths, char * str) { + int path_count, pg_count = 0; + int i, k; + int * bitmap; + char path_buff[FILE_NAME_SIZE]; + char pg_buff[FILE_NAME_SIZE]; + char * path_buff_p = &path_buff[0]; + char * pg_buff_p = &pg_buff[0]; + + /* init the bitmap */ + bitmap = malloc((mp->npaths + 1) * sizeof(int)); + memset(bitmap, 0, (mp->npaths + 1) * sizeof(int)); + + for (i = 0; i <= mp->npaths; i++) { + if (bitmap[i]) + continue; + + /* here, we really got a new pg */ + pg_count++; + path_count = 1; + memset(&path_buff, 0, FILE_NAME_SIZE * sizeof(char)); + path_buff_p = &path_buff[0]; + + path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[i]].dev); + bitmap[i] = 1; + + for (k = i + 1; k <= mp->npaths; k++) { + if (bitmap[k]) + continue; + if (0 == strcmp(all_paths[mp->pindex[i]].serial, + all_paths[mp->pindex[k]].serial)) { + path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[k]].dev); + bitmap[k] = 1; + path_count++; + } + } + pg_buff_p += sprintf(pg_buff_p, " round-robin %i 0%s", + path_count, path_buff); + } + sprintf(str, " %i%s", pg_count, pg_buff); + free(bitmap); +} + +static int +dm_simplecmd(int task, const char *name) { + int r = 0; + struct dm_task *dmt; + + if (!(dmt = dm_task_create(task))) + return 0; + + if (!dm_task_set_name(dmt, name)) + goto out; + + r = dm_task_run(dmt); + + out: + dm_task_destroy(dmt); + return r; +} + +static int +dm_addmap(int task, const char *name, const char *params, long size) { + struct dm_task *dmt; + + if (!(dmt = dm_task_create(task))) + return 0; + + if (!dm_task_set_name(dmt, name)) + goto addout; + + if (!dm_task_add_target(dmt, 0, size, DM_TARGET, params)) + goto addout; + + if (!dm_task_run(dmt)) + goto addout; + + addout: + dm_task_destroy(dmt); + return 1; +} + +static int +setup_map(struct env * conf, struct path * all_paths, + struct multipath * mp, int index, int op) +{ + char params[255]; + char * params_p; + int i, np; + + /* defaults for multipath target */ + char * dm_ps_name = "round-robin"; + int dm_ps_nr_args = 0; + + params_p = ¶ms[0]; + + np = 0; + for (i=0; i<=mp[index].npaths; i++) { + if (0 == all_paths[PINDEX(index,i)].sg_id.scsi_type) + np++; + } + + if (np < 1) + return 0; + + if ((all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && + conf->iopolicy == -1) || conf->iopolicy == MULTIBUS) { + params_p += sprintf(params_p, " 1 %s %i %i", + dm_ps_name, np, dm_ps_nr_args); + + for (i=0; i<=mp[index].npaths; i++) { + if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) + continue; + params_p += sprintf(params_p, " %s", + all_paths[PINDEX(index,i)].dev); + } + } + + if ((all_paths[PINDEX(index,0)].iopolicy == FAILOVER && + conf->iopolicy == -1) || conf->iopolicy == FAILOVER) { + params_p += sprintf(params_p, " %i", mp[index].npaths + 1); + for (i=0; i<=mp[index].npaths; i++) { + if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) + continue; + params_p += sprintf(params_p, " %s ", + dm_ps_name); + params_p += sprintf(params_p, "1 %i", + dm_ps_nr_args); + params_p += sprintf(params_p, " %s", + all_paths[PINDEX(index,i)].dev); + } + } + + if ((all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_SERIAL && + conf->iopolicy == -1) || conf->iopolicy == GROUP_BY_SERIAL) { + group_by_serial(&mp[index], all_paths, params_p); + } + + if ((all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_TUR && + conf->iopolicy == -1) || conf->iopolicy == GROUP_BY_TUR) { + group_by_tur(&mp[index], all_paths, params_p); + } + + if (mp[index].size < 0) + return 0; + + if (!conf->quiet) { + if (op == DM_DEVICE_RELOAD) + printf("U:"); + if (op == DM_DEVICE_CREATE) + printf("N:"); + printf("%s:0 %li %s %s\n", + mp[index].wwid, mp[index].size, DM_TARGET, params); + } + + if (op == DM_DEVICE_RELOAD) + dm_simplecmd(DM_DEVICE_SUSPEND, mp[index].wwid); + + dm_addmap(op, mp[index].wwid, params, mp[index].size); + + if (op == DM_DEVICE_RELOAD) + dm_simplecmd(DM_DEVICE_RESUME, mp[index].wwid); + + return 1; +} + +static int +map_present(char * str) +{ + int r = 0; + struct dm_task *dmt; + struct dm_names *names; + unsigned next = 0; + + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) + return 0; + + if (!dm_task_run(dmt)) + goto out; + + if (!(names = dm_task_get_names(dmt))) + goto out; + + if (!names->dev) { + goto out; + } + + do { + if (0 == strcmp(names->name, str)) + r = 1; + next = names->next; + names = (void *) names + next; + } while (next); + + out: + dm_task_destroy(dmt); + return r; +} + +static void +signal_daemon (void) +{ + FILE *file; + pid_t pid; + char *buf; + + buf = malloc (8); + + file = fopen (PIDFILE, "r"); + + if (!file) { + fprintf(stderr, "cannot signal daemon, pidfile not found\n"); + return; + } + + buf = fgets (buf, 8, file); + fclose (file); + + pid = (pid_t) atol (buf); + free (buf); + + kill(pid, SIGHUP); +} + +static int +filepresent(char * run) { + struct stat buf; + + if(!stat(run, &buf)) + return 1; + return 0; +} + +static void +usage(char * progname) +{ + fprintf(stderr, VERSION_STRING); + fprintf(stderr, "Usage: %s [-v|-q] [-d] [-m max_devs]\n", + progname); + fprintf(stderr, " [-p failover|multibus|group_by_serial]\n" \ + " [device]\n" \ + "\n" \ + "\t-v\t\tverbose, print all paths and multipaths\n" \ + "\t-q\t\tquiet, no output at all\n" \ + "\t-d\t\tdry run, do not create or update devmaps\n" \ + "\t-m max_devs\tscan {max_devs} devices at most\n" \ + "\n" \ + "\t-p policy\tforce maps to specified policy :\n" \ + "\t failover\t\t- 1 path per priority group\n" \ + "\t multibus\t\t- all paths in 1 priority group\n" \ + "\t group_by_serial\t- 1 priority group per serial\n" \ + "\t group_by_tur\t\t- 1 priority group per TUR state\n" \ + "\n" \ + "\t-D maj min\tlimit scope to the device's multipath\n" \ + "\t\t\t(major minor device reference)\n" + "\tdevice\t\tlimit scope to the device's multipath\n" \ + "\t\t\t(hotplug-style $DEVPATH reference)\n" + ); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct multipath * mp; + struct path * all_paths; + struct scsi_dev * all_scsi_ids; + struct env conf; + int i, k, nmp; + int try = 0; + + /* Don't run in parallel */ + while (filepresent(RUN) && try++ < MAXTRY) + usleep(100000); + + if (filepresent(RUN)) { + fprintf(stderr, "waited for to long. exiting\n"); + exit (1); + } + + /* Our turn */ + if (!open(RUN, O_CREAT)) { + fprintf(stderr, "can't create runfile\n"); + exit (1); + } + + /* Default behaviour */ + conf.max_devs = MAX_DEVS; + conf.dry_run = 0; /* 1 == Do not Create/Update devmaps */ + conf.verbose = 0; /* 1 == Print all_paths and mp */ + conf.quiet = 0; /* 1 == Do not even print devmaps */ + conf.iopolicy = -1; /* Apply the defaults in get_unique_id() */ + conf.major = -1; + conf.minor = -1; + + for (i = 1; i < argc; ++i) { + if (0 == strcmp("-v", argv[i])) { + if (conf.quiet == 1) + usage(argv[0]); + conf.verbose = 1; + } else if (0 == strcmp("-m", argv[i])) { + conf.max_devs = atoi(argv[++i]); + if (conf.max_devs < 2) + usage(argv[0]); + } else if (0 == strcmp("-D", argv[i])) { + conf.major = atoi(argv[++i]); + conf.minor = atoi(argv[++i]); + } else if (0 == strcmp("-q", argv[i])) { + if (conf.verbose == 1) + usage(argv[0]); + conf.quiet = 1; + } else if (0 == strcmp("-d", argv[i])) + conf.dry_run = 1; + else if (0 == strcmp("-p", argv[i])) { + i++; + if (!strcmp(argv[i], "failover")) + conf.iopolicy = FAILOVER; + if (!strcmp(argv[i], "multibus")) + conf.iopolicy = MULTIBUS; + if (!strcmp(argv[i], "group_by_serial")) + conf.iopolicy = GROUP_BY_SERIAL; + if (!strcmp(argv[i], "group_by_tur")) + conf.iopolicy = GROUP_BY_TUR; + } else if (*argv[i] == '-') { + fprintf(stderr, "Unknown switch: %s\n", argv[i]); + usage(argv[0]); + } else + strncpy(conf.hotplugdev, argv[i], FILE_NAME_SIZE); + } + + /* dynamic allocations */ + mp = malloc(conf.max_devs * sizeof(struct multipath)); + all_paths = malloc(conf.max_devs * sizeof(struct path)); + all_scsi_ids = malloc(conf.max_devs * sizeof(struct scsi_dev)); + if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) + exit(1); + + if (sysfs_get_mnt_path(conf.sysfs_path, FILE_NAME_SIZE)) { + get_all_scsi_ids(&conf, all_scsi_ids); + get_all_paths_nosysfs(&conf, all_paths, all_scsi_ids); + } else { + get_all_paths_sysfs(&conf, all_paths); + } + + nmp = coalesce_paths(&conf, mp, all_paths); + + if (conf.verbose) { + print_all_path(&conf, all_paths); + fprintf(stdout, "\n"); + print_all_mp(all_paths, mp, nmp); + fprintf(stdout, "\n"); + } + + if (conf.dry_run) + exit(0); + + for (k=0; k<=nmp; k++) { + if (map_present(mp[k].wwid)) { + setup_map(&conf, all_paths, mp, k, DM_DEVICE_RELOAD); + } else { + setup_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); + } + } + + /* signal multipathd that new devmaps may have come up */ + signal_daemon(); + + /* free allocs */ + free(mp); + free(all_paths); + free(all_scsi_ids); + + /* release runfile */ + unlink(RUN); + + exit(0); +} diff --git a/extras/multipath-tools/multipath/main.h b/extras/multipath-tools/multipath/main.h new file mode 100644 index 0000000000..ada7a7394b --- /dev/null +++ b/extras/multipath-tools/multipath/main.h @@ -0,0 +1,131 @@ +/* + * Soft: Description here... + * + * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ + * + * Author: Copyright (C) 2003 Christophe Varoqui + * + * 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. + * + * 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. + */ + +#ifndef _MAIN_H +#define _MAIN_H + +/* local includes */ +#include "sg_include.h" + +/* exerpt from "sg_err.h" */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SG_ERR_DRIVER_SENSE 0x08 + +/* exerpt from "scsi.h" */ +#define SCSI_IOCTL_GET_IDLUN 0x5382 +#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 + +/* global defs */ +#define WWID_SIZE 33 +#define SERIAL_SIZE 14 +#define MAX_DEVS 128 +#define MAX_MP MAX_DEVS / 2 +#define MAX_MP_PATHS MAX_DEVS / 4 +#define FILE_NAME_SIZE 256 +#define DEF_TIMEOUT 60000 +#define EBUFF_SZ 256 +#define TUR_CMD_LEN 6 +#define DM_TARGET "multipath" +#define PIDFILE "/var/run/multipathd.pid" +#define RUN "/var/run/multipath.run" +#define MAXTRY 50 + +/* Storage controlers cpabilities */ +#define FAILOVER 0 +#define MULTIBUS 1 +#define GROUP_BY_SERIAL 2 +#define GROUP_BY_TUR 4 + +#define PINDEX(x,y) mp[(x)].pindex[(y)] + +/* global types */ +struct scsi_idlun { + int dev_id; + int host_unique_id; + int host_no; +}; + +struct sg_id { + int host_no; + int channel; + int scsi_id; + int lun; + int scsi_type; + short h_cmd_per_lun; + short d_queue_depth; + int unused1; + int unused2; +}; + +struct scsi_dev { + char dev[FILE_NAME_SIZE]; + struct scsi_idlun scsi_id; + int host_no; +}; + +struct path { + char dev[FILE_NAME_SIZE]; + char sg_dev[FILE_NAME_SIZE]; + struct scsi_idlun scsi_id; + struct sg_id sg_id; + char wwid[WWID_SIZE]; + char vendor_id[8]; + char product_id[16]; + char rev[4]; + char serial[SERIAL_SIZE]; + int iopolicy; + int tur; +}; + +struct multipath { + char wwid[WWID_SIZE]; + int npaths; + long size; + int pindex[MAX_MP_PATHS]; +}; + +struct env { + int max_devs; + int verbose; + int quiet; + int dry_run; + int iopolicy; + int with_sysfs; + int major; + int minor; + char sysfs_path[FILE_NAME_SIZE]; + char hotplugdev[FILE_NAME_SIZE]; +}; + +/* Build version */ +#define PROG "multipath" + +#define VERSION_CODE 0x000012 +#define DATE_CODE 0x021504 + +#define MULTIPATH_VERSION(version) \ + (version >> 16) & 0xFF, \ + (version >> 8) & 0xFF, \ + version & 0xFF + +#define VERSION_STRING PROG" v%d.%d.%d (%.2d/%.2d, 20%.2d)\n", \ + MULTIPATH_VERSION(VERSION_CODE), \ + MULTIPATH_VERSION(DATE_CODE) + +#endif diff --git a/extras/multipath-tools/multipath/multipath.8 b/extras/multipath-tools/multipath/multipath.8 new file mode 100644 index 0000000000..0856ca8dfc --- /dev/null +++ b/extras/multipath-tools/multipath/multipath.8 @@ -0,0 +1,66 @@ +.TH MULTIPATH 8 "February 2004" "" "Linux Administrator's Manual" +.SH NAME +multipath \- Device mapper target autoconfig +.SH SYNOPSIS +.B multipath +.RB [\| \-v | \-q \|] +.RB [\| \-d \|] +.RB [\| \-i\ \c +.IR int \|] +.RB [\| \-m\ \c +.IR max_devs \|] +.RB [\| \-p\ \c +.BR failover | multibus | group_by_serial \|] +.RB [\| device \|] +.SH DESCRIPTION +.B multipath +is used to detect multiple paths to devices for fail-over or performance reasons and coalesces them. +.SH OPTIONS +.TP +.B \-v +verbose, print all paths and multipaths +.TP +.B \-q +quiet, no output at all +.TP +.B \-d +dry run, do not create or update devmaps +.TP +.BI \-i " int" +multipath target param: polling interval +.TP +.BI \-m " max_devs" +scan +.I max_devs +devices at most +.TP +.BI \-D " major minor" +update only the devmap the path pointed by +.I major minor +is in +.TP +.BI \-p " policy" +force maps to specified policy: +.RS 1.2i +.TP 1.2i +.B failover +1 path per priority group +.TP +.B multibus +all paths in 1 priority group +.TP +.B group_by_serial +1 priority group per serial +.RE +.TP +.BI device +update only the devmap the path pointed by +.I device +is in +.SH "SEE ALSO" +.BR udev (8), +.BR dmsetup (8) +.BR hotplug (8) +.SH AUTHORS +.B multipath +was developed by Christophe Varoqui, and others. diff --git a/extras/multipath-tools/multipath/multipath.hotplug b/extras/multipath-tools/multipath/multipath.hotplug new file mode 100644 index 0000000000..5c411d1edf --- /dev/null +++ b/extras/multipath-tools/multipath/multipath.hotplug @@ -0,0 +1,7 @@ +#!/bin/sh +. /etc/hotplug/hotplug.functions + +# wait for sysfs +sleep 1 + +mesg `/sbin/multipath $DEVPATH` diff --git a/extras/multipath-tools/multipath/sg_err.h b/extras/multipath-tools/multipath/sg_err.h new file mode 100644 index 0000000000..ef57b5ce38 --- /dev/null +++ b/extras/multipath-tools/multipath/sg_err.h @@ -0,0 +1,162 @@ +#ifndef SG_ERR_H +#define SG_ERR_H + +/* Feel free to copy and modify this GPL-ed code into your applications. */ + +/* Version 0.90 (20030519) +*/ + + +/* Some of the following error/status codes are exchanged between the + various layers of the SCSI sub-system in Linux and should never + reach the user. They are placed here for completeness. What appears + here is copied from drivers/scsi/scsi.h which is not visible in + the user space. */ + +#ifndef SCSI_CHECK_CONDITION +/* 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 +#endif + +/* The following are 'host_status' codes */ +#ifndef DID_OK +#define DID_OK 0x00 +#endif +#ifndef DID_NO_CONNECT +#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 DID_BAD_TARGET 0x04 /* Bad target (id?) */ +#define DID_ABORT 0x05 /* Told to abort for some other reason */ +#define DID_PARITY 0x06 /* Parity error (on SCSI bus) */ +#define DID_ERROR 0x07 /* Internal error */ +#define DID_RESET 0x08 /* Reset by somebody */ +#define DID_BAD_INTR 0x09 /* Received an unexpected interrupt */ +#define DID_PASSTHROUGH 0x0a /* Force command past mid-level */ +#define DID_SOFT_ERROR 0x0b /* The low-level driver wants a retry */ +#endif + +/* These defines are to isolate applictaions from kernel define changes */ +#define SG_ERR_DID_OK DID_OK +#define SG_ERR_DID_NO_CONNECT DID_NO_CONNECT +#define SG_ERR_DID_BUS_BUSY DID_BUS_BUSY +#define SG_ERR_DID_TIME_OUT DID_TIME_OUT +#define SG_ERR_DID_BAD_TARGET DID_BAD_TARGET +#define SG_ERR_DID_ABORT DID_ABORT +#define SG_ERR_DID_PARITY DID_PARITY +#define SG_ERR_DID_ERROR DID_ERROR +#define SG_ERR_DID_RESET DID_RESET +#define SG_ERR_DID_BAD_INTR DID_BAD_INTR +#define SG_ERR_DID_PASSTHROUGH DID_PASSTHROUGH +#define SG_ERR_DID_SOFT_ERROR DID_SOFT_ERROR + +/* The following are 'driver_status' codes */ +#ifndef DRIVER_OK +#define DRIVER_OK 0x00 +#endif +#ifndef DRIVER_BUSY +#define DRIVER_BUSY 0x01 +#define DRIVER_SOFT 0x02 +#define DRIVER_MEDIA 0x03 +#define DRIVER_ERROR 0x04 +#define DRIVER_INVALID 0x05 +#define DRIVER_TIMEOUT 0x06 +#define DRIVER_HARD 0x07 +#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ + +/* Following "suggests" are "or-ed" with one of previous 8 entries */ +#define SUGGEST_RETRY 0x10 +#define SUGGEST_ABORT 0x20 +#define SUGGEST_REMAP 0x30 +#define SUGGEST_DIE 0x40 +#define SUGGEST_SENSE 0x80 +#define SUGGEST_IS_OK 0xff +#endif +#ifndef DRIVER_MASK +#define DRIVER_MASK 0x0f +#endif +#ifndef SUGGEST_MASK +#define SUGGEST_MASK 0xf0 +#endif + +/* These defines are to isolate applictaions from kernel define changes */ +#define SG_ERR_DRIVER_OK DRIVER_OK +#define SG_ERR_DRIVER_BUSY DRIVER_BUSY +#define SG_ERR_DRIVER_SOFT DRIVER_SOFT +#define SG_ERR_DRIVER_MEDIA DRIVER_MEDIA +#define SG_ERR_DRIVER_ERROR DRIVER_ERROR +#define SG_ERR_DRIVER_INVALID DRIVER_INVALID +#define SG_ERR_DRIVER_TIMEOUT DRIVER_TIMEOUT +#define SG_ERR_DRIVER_HARD DRIVER_HARD +#define SG_ERR_DRIVER_SENSE DRIVER_SENSE +#define SG_ERR_SUGGEST_RETRY SUGGEST_RETRY +#define SG_ERR_SUGGEST_ABORT SUGGEST_ABORT +#define SG_ERR_SUGGEST_REMAP SUGGEST_REMAP +#define SG_ERR_SUGGEST_DIE SUGGEST_DIE +#define SG_ERR_SUGGEST_SENSE SUGGEST_SENSE +#define SG_ERR_SUGGEST_IS_OK SUGGEST_IS_OK +#define SG_ERR_DRIVER_MASK DRIVER_MASK +#define SG_ERR_SUGGEST_MASK SUGGEST_MASK + + + +/* The following "print" functions send ACSII to stdout */ +extern void sg_print_command(const unsigned char * command); +extern void sg_print_sense(const char * leadin, + const unsigned char * sense_buffer, int sb_len); +extern void sg_print_status(int masked_status); +extern void sg_print_scsi_status(int scsi_status); +extern void sg_print_host_status(int host_status); +extern void sg_print_driver_status(int driver_status); + +/* sg_chk_n_print() returns 1 quietly if there are no errors/warnings + else it prints to standard output and returns 0. */ +extern int sg_chk_n_print(const char * leadin, int masked_status, + int host_status, int driver_status, + const unsigned char * sense_buffer, int sb_len); + +/* The following function declaration is for the sg version 3 driver. + Only version 3 sg_err.c defines it. */ +struct sg_io_hdr; +extern int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp); + + +/* 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_SENSE 98 /* Something else is in the sense buffer */ +#define SG_ERR_CAT_OTHER 99 /* Some other error/warning has occurred */ + +extern int sg_err_category(int masked_status, int host_status, + int driver_status, const unsigned char * sense_buffer, + int sb_len); + +extern int sg_err_category_new(int scsi_status, int host_status, + int driver_status, const unsigned char * sense_buffer, + int sb_len); + +/* The following function declaration is for the sg version 3 driver. + Only version 3 sg_err.c defines it. */ +extern int sg_err_category3(struct sg_io_hdr * hp); + +/* Returns length of SCSI command given the opcode (first byte) */ +extern int sg_get_command_size(unsigned char opcode); + +extern void sg_get_command_name(unsigned char opcode, int buff_len, + char * buff); + +#endif diff --git a/extras/multipath-tools/multipath/sg_include.h b/extras/multipath-tools/multipath/sg_include.h new file mode 100644 index 0000000000..460506826e --- /dev/null +++ b/extras/multipath-tools/multipath/sg_include.h @@ -0,0 +1,43 @@ +#ifdef SG_KERNEL_INCLUDES + #define __user + typedef unsigned char u8; + #include "/usr/src/linux/include/scsi/sg.h" + #include "/usr/src/linux/include/scsi/scsi.h" +#else + #ifdef SG_TRICK_GNU_INCLUDES + #include + #include + #else + #include + #endif +#endif + +/* + Getting the correct include files for the sg interface can be an ordeal. + In a perfect world, one would just write: + #include + #include + This would include the files found in the /usr/include/scsi directory. + Those files are maintained with the GNU library which may or may not + agree with the kernel and version of sg driver that is running. Any + many cases this will not matter. However in some it might, for example + glibc 2.1's include files match the sg driver found in the lk 2.2 + series. Hence if glibc 2.1 is used with lk 2.4 then the additional + sg v3 interface will not be visible. + If this is a problem then defining SG_KERNEL_INCLUDES will access the + kernel supplied header files (assuming they are in the normal place). + The GNU library maintainers and various kernel people don't like + this approach (but it does work). + The technique selected by defining SG_TRICK_GNU_INCLUDES worked (and + was used) prior to glibc 2.2 . Prior to that version /usr/include/linux + was a symbolic link to /usr/src/linux/include/linux . + + There are other approaches if this include "mixup" causes pain. These + would involve include files being copied or symbolic links being + introduced. + + Sorry about the inconvenience. Typically neither SG_KERNEL_INCLUDES + nor SG_TRICK_GNU_INCLUDES is defined. + + dpg 20010415, 20030522 +*/ diff --git a/extras/multipath-tools/multipath/unused.c b/extras/multipath-tools/multipath/unused.c new file mode 100644 index 0000000000..08144cf717 --- /dev/null +++ b/extras/multipath-tools/multipath/unused.c @@ -0,0 +1,95 @@ +static int +get_serial (int fd, char * str) +{ + char buff[MX_ALLOC_LEN + 1]; + int len; + + if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { + len = buff[3]; + if (len > 0) { + memcpy(str, buff + 4, len); + buff[len] = '\0'; + } + return 1; + } + return 0; +} + +static int +do_tur(int fd) +{ + unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; + struct sg_io_hdr io_hdr; + unsigned char sense_buffer[32]; + + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (turCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_buffer); + io_hdr.dxfer_direction = SG_DXFER_NONE; + io_hdr.cmdp = turCmdBlk; + io_hdr.sbp = sense_buffer; + io_hdr.timeout = 20000; + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + close(fd); + return 0; + } + if (io_hdr.info & SG_INFO_OK_MASK) { + return 0; + } + return 1; +} + +static int +del_map(char * str) { + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) + return 0; + if (!dm_task_set_name(dmt, str)) + goto delout; + if (!dm_task_run(dmt)) + goto delout; + + printf("Deleted device map : %s\n", str); + + delout: + dm_task_destroy(dmt); + return 1; +} + +get_table(const char * str) +{ + int r = 0; + struct dm_task *dmt; + void *next = NULL; + uint64_t start, length; + char *target_type = NULL; + char *params; + + if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) + return 0; + + if (!dm_task_set_name(dmt, str)) + goto out; + + if (!dm_task_run(dmt)) + goto out; + + do { + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, ¶ms); + if (target_type) { + printf("%" PRIu64 " %" PRIu64 " %s %s\n", + start, length, target_type, params); + } + } while (next); + + r = 1; + + out: + dm_task_destroy(dmt); + return r; + +} diff --git a/extras/multipath-tools/multipathd/Makefile b/extras/multipath-tools/multipathd/Makefile new file mode 100644 index 0000000000..5bfd58a837 --- /dev/null +++ b/extras/multipath-tools/multipathd/Makefile @@ -0,0 +1,31 @@ +EXEC = multipathd + +CC = gcc +GZIP = /bin/gzip -9 -c + +bindir = /usr/bin +mandir = /usr/share/man/man8 +rcdir = /etc/init.d + +CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -DDEBUG=1 +LDFLAGS = -lpthread -ldevmapper -lsysfs + +OBJS = main.o devinfo.o checkers.o + +$(EXEC): $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) -o $(EXEC) + strip $(EXEC) + +install: + install -d $(bindir) + install -m 755 $(EXEC) $(bindir) + install -d $(rcdir) + install -m 755 multipathd.init $(rcdir)/$(EXEC) + +uninstall: + rm -f $(bindir)/$(EXEC) + rm -f $(rcdir)/$(EXEC) + +clean: + rm -f core *.o $(EXEC) *.gz + diff --git a/extras/multipath-tools/multipathd/checkers.c b/extras/multipath-tools/multipathd/checkers.c new file mode 100644 index 0000000000..7ad32b04e9 --- /dev/null +++ b/extras/multipath-tools/multipathd/checkers.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "sg_include.h" + +#define TUR_CMD_LEN 6 + +/* + * test IO functions : add yours here + * + * returns 0 : path gone valid + * returns 1 : path still failed + */ + +int readsector0 (char *devnode) +{ + int fd, r; + char buf; + + fd = open (devnode, O_RDONLY); + if (read (fd, &buf, 1) != 1) + r = 0; + else + r = 1; + + close (fd); + + return r; +} + +int tur(char *devnode) +{ + unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; + struct sg_io_hdr io_hdr; + unsigned char sense_buffer[32]; + int fd; + + fd = open (devnode, O_RDONLY); + + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (turCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_buffer); + io_hdr.dxfer_direction = SG_DXFER_NONE; + io_hdr.cmdp = turCmdBlk; + io_hdr.sbp = sense_buffer; + io_hdr.timeout = 20000; + io_hdr.pack_id = 0; + if (ioctl(fd, SG_IO, &io_hdr) < 0) { + close(fd); + return 0; + } + if (io_hdr.info & SG_INFO_OK_MASK) { + return 0; + } + return 1; +} diff --git a/extras/multipath-tools/multipathd/checkers.h b/extras/multipath-tools/multipathd/checkers.h new file mode 100644 index 0000000000..057c319d1b --- /dev/null +++ b/extras/multipath-tools/multipathd/checkers.h @@ -0,0 +1,2 @@ +int readsector0 (char *); +int tur (char *); diff --git a/extras/multipath-tools/multipathd/devinfo.c b/extras/multipath-tools/multipathd/devinfo.c new file mode 100644 index 0000000000..46505470f4 --- /dev/null +++ b/extras/multipath-tools/multipathd/devinfo.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include +#include "devinfo.h" +#include "sg_include.h" + +#define FILE_NAME_SIZE 255 + +static int +do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, + void *resp, int mx_resp_len, int noisy) +{ + unsigned char inqCmdBlk[INQUIRY_CMDLEN] = + { INQUIRY_CMD, 0, 0, 0, 0, 0 }; + unsigned char sense_b[SENSE_BUFF_LEN]; + struct sg_io_hdr io_hdr; + + if (cmddt) + inqCmdBlk[1] |= 2; + if (evpd) + inqCmdBlk[1] |= 1; + inqCmdBlk[2] = (unsigned char) pg_op; + inqCmdBlk[4] = (unsigned char) mx_resp_len; + memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); + io_hdr.interface_id = 'S'; + io_hdr.cmd_len = sizeof (inqCmdBlk); + io_hdr.mx_sb_len = sizeof (sense_b); + io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; + io_hdr.dxfer_len = mx_resp_len; + io_hdr.dxferp = resp; + io_hdr.cmdp = inqCmdBlk; + io_hdr.sbp = sense_b; + io_hdr.timeout = DEF_TIMEOUT; + + if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { + perror("SG_IO (inquiry) error"); + return -1; + } + + /* treat SG_ERR here to get rid of sg_err.[ch] */ + io_hdr.status &= 0x7e; + if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && + (0 == io_hdr.driver_status)) + return 0; + if ((SCSI_CHECK_CONDITION == io_hdr.status) || + (SCSI_COMMAND_TERMINATED == io_hdr.status) || + (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { + if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { + int sense_key; + unsigned char * sense_buffer = io_hdr.sbp; + if (sense_buffer[0] & 0x2) + sense_key = sense_buffer[1] & 0xf; + else + sense_key = sense_buffer[2] & 0xf; + if(RECOVERED_ERROR == sense_key) + return 0; + } + } + return -1; +} + +int +get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname) +{ + int fd; + char buff[36]; + + /* ioctl style */ + if ((fd = open(devname, O_RDONLY)) < 0) + return 1; + if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) + return 1; + memcpy(vendor_id, &buff[8], 8); + memcpy(product_id, &buff[16], 16); + memcpy(rev, &buff[32], 4); + close(fd); + + return 0; +} diff --git a/extras/multipath-tools/multipathd/devinfo.h b/extras/multipath-tools/multipathd/devinfo.h new file mode 100644 index 0000000000..46b2894051 --- /dev/null +++ b/extras/multipath-tools/multipathd/devinfo.h @@ -0,0 +1,15 @@ +#define INQUIRY_CMDLEN 6 +#define INQUIRY_CMD 0x12 +#define SENSE_BUFF_LEN 32 +#define DEF_TIMEOUT 60000 +#define RECOVERED_ERROR 0x01 +#define MX_ALLOC_LEN 255 +#define WWID_SIZE 33 +#define BLKGETSIZE _IO(0x12,96) + +/* exerpt from "sg_err.h" */ +#define SCSI_CHECK_CONDITION 0x2 +#define SCSI_COMMAND_TERMINATED 0x22 +#define SG_ERR_DRIVER_SENSE 0x08 + +int get_lun_strings (char *, char *, char *, char *); diff --git a/extras/multipath-tools/multipathd/main.c b/extras/multipath-tools/multipathd/main.c new file mode 100644 index 0000000000..7b5ccfca23 --- /dev/null +++ b/extras/multipath-tools/multipathd/main.c @@ -0,0 +1,674 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devinfo.h" +#include "checkers.h" + +#define CHECKINT 5 +#define MAXPATHS 2048 +#define FILENAMESIZE 256 +#define MAPNAMESIZE 64 +#define TARGETTYPESIZE 16 +#define PARAMSSIZE 2048 +#define MAXMAPS 512 + +#define MULTIPATH "/sbin/multipath" +#define PIDFILE "/var/run/multipathd.pid" + +#ifndef DEBUG +#define DEBUG 1 +#endif +#define LOG(x, y, z...) if (DEBUG >= x) syslog(x, y, ##z) + +struct path +{ + int major; + int minor; + char mapname[MAPNAMESIZE]; + int (*checkfn) (char *); +}; + +struct paths +{ + pthread_mutex_t *lock; + struct path *paths_h; +}; + +struct event_thread +{ + pthread_t *thread; + pthread_mutex_t *waiter_lock; + char mapname[MAPNAMESIZE]; +}; + +struct devmap +{ + char mapname[MAPNAMESIZE]; +}; + +/* global var */ +pthread_mutex_t *event_lock; +pthread_cond_t *event; + +int makenode (char *devnode, int major, int minor) +{ + dev_t dev; + + dev = makedev (major, minor); + unlink (devnode); + + return mknod(devnode, S_IFBLK | S_IRUSR | S_IWUSR, dev); +} + +int select_checkfn(struct path *path_p) +{ + char devnode[FILENAMESIZE]; + char vendor[8]; + char product[16]; + char rev[4]; + int i, r; + + /* default checkfn */ + path_p->checkfn = &readsector0; + + sprintf (devnode, "/tmp/.select.%i.%i", path_p->major, path_p->minor); + + r = makenode (devnode, path_p->major, path_p->minor); + + if (r < 0) { + LOG(2, "[select_checkfn] can not make node %s", devnode); + return r; + } + + r = get_lun_strings(vendor, product, rev, devnode); + + if (r) { + LOG(2, "[select_checkfn] can not get strings"); + return r; + } + + r = unlink (devnode); + + if (r < 0) { + LOG(2, "[select_checkfn] can not unlink %s", devnode); + return r; + } + + static struct { + char * vendor; + char * product; + int (*checkfn) (char *); + } wlist[] = { + {"COMPAQ ", "HSV110 (C)COMPAQ", &tur}, + {"COMPAQ ", "MSA1000 ", &tur}, + {"COMPAQ ", "MSA1000 VOLUME ", &tur}, + {"DEC ", "HSG80 ", &tur}, + {"HP ", "HSV100 ", &readsector0}, + {NULL, NULL, NULL}, + }; + + for (i = 0; wlist[i].vendor; i++) { + if (strncmp(vendor, wlist[i].vendor, 8) == 0 && + strncmp(product, wlist[i].product, 16) == 0) { + path_p->checkfn = wlist[i].checkfn; + } + } + + return 0; +} + +int get_devmaps (struct devmap *devmaps) +{ + struct devmap *devmaps_p; + struct dm_task *dmt, *dmt1; + struct dm_names *names = NULL; + unsigned next = 0; + void *nexttgt; + int r = 0; + long long start, length; + char *target_type = NULL; + char *params; + + memset (devmaps, 0, MAXMAPS * sizeof (struct devmap)); + + if (!(dmt = dm_task_create(DM_DEVICE_LIST))) { + r = 1; + goto out; + } + + if (!dm_task_run(dmt)) { + r = 1; + goto out; + } + + if (!(names = dm_task_get_names(dmt))) { + r = 1; + goto out; + } + + if (!names->dev) { + LOG (1, "[get_devmaps] no devmap found"); + goto out; + } + + devmaps_p = devmaps; + + do { + /* keep only multipath maps */ + + names = (void *) names + next; + nexttgt = NULL; + LOG (3, "[get_devmaps] iterate on devmap names : %s", names->name); + + LOG (3, "[get_devmaps] dm_task_create(DM_DEVICE_STATUS)"); + if (!(dmt1 = dm_task_create(DM_DEVICE_STATUS))) + goto out1; + + LOG (3, "[get_devmaps] dm_task_set_name(dmt1, names->name)"); + if (!dm_task_set_name(dmt1, names->name)) + goto out1; + + LOG (3, "[get_devmaps] dm_task_run(dmt1)"); + if (!dm_task_run(dmt1)) + goto out1; + LOG (3, "[get_devmaps] DM_DEVICE_STATUS ioctl done"); + do { + LOG (3, "[get_devmaps] iterate on devmap's targets"); + nexttgt = dm_get_next_target(dmt1, nexttgt, + &start, + &length, + &target_type, + ¶ms); + + + LOG (3, "[get_devmaps] test target_type existence"); + if (!target_type) + goto out1; + + LOG (3, "[get_devmaps] test target_type is multipath"); + if (!strncmp (target_type, "multipath", 9)) { + strcpy (devmaps_p->mapname, names->name); + devmaps_p++; + + /* test vector overflow */ + if (devmaps_p - devmaps >= MAXMAPS * sizeof (struct devmap)) { + LOG (1, "[get_devmaps] devmaps overflow"); + dm_task_destroy(dmt1); + r = 1; + goto out; + } + } + + } while (nexttgt); + +out1: + dm_task_destroy(dmt1); + next = names->next; + + } while (next); + +out: + dm_task_destroy(dmt); + + LOG (3, "[get_devmaps] done"); + return r; +} + +int checkpath (struct path *path_p) +{ + char devnode[FILENAMESIZE]; + int r; + + LOG (2, "[checkpath] checking path %i:%i", path_p->major, path_p->minor); + sprintf (devnode, "/tmp/.checker.%i.%i", path_p->major, path_p->minor); + + if (path_p->checkfn == NULL) { + LOG (1, "[checkpath] test function not set for path %i:%i", + path_p->major, path_p->minor); + return 1; + } + + r = makenode (devnode, path_p->major, path_p->minor); + + if (r < 0) { + LOG (2, "[checkpath] can not make node for %s", devnode); + return r; + } + + r = path_p->checkfn(devnode); + unlink (devnode); + + return r; +} + +int updatepaths (struct devmap *devmaps, struct paths *failedpaths) +{ + struct path *path_p; + struct devmap *devmaps_p; + void *next; + struct dm_task *dmt; + long long start, length; + char *target_type = NULL; + char *params, *p1, *p2; + char word[6]; + int i; + + path_p = failedpaths->paths_h; + + pthread_mutex_lock (failedpaths->lock); + memset (failedpaths->paths_h, 0, MAXPATHS * sizeof (struct path)); + + /* first pass */ + /* ask DM the failed path list */ + + devmaps_p = devmaps; + + while (*devmaps_p->mapname != 0x0) { + next = NULL; + + if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) + break; + + if (!dm_task_set_name(dmt, devmaps_p->mapname)) + goto out; + + if (!dm_task_run(dmt)) + goto out; + + do { + next = dm_get_next_target(dmt, next, &start, &length, + &target_type, ¶ms); + + /* begin ugly parser */ + p1 = params; + p2 = params; + while (*p1) { + /* p2 lags at the begining of the word p1 parses */ + while (*p1 != ' ') { + /* if the current word is a path */ + if (*p1 == ':') { + /* p1 jumps to path state */ + while (*p1 != 'A' && *p1 != 'F') + p1++; + + /* store path info */ + + path_p->checkfn = NULL; + + i = 0; + memset (&word, 'O', 6 * sizeof (char)); + while (*p2 != ':') { + word[i++] = *p2; + p2++; + } + path_p->major = atoi (word); + + p2++; + i = 0; + memset (&word, 'O', 6 * sizeof (char)); + while (*p2 != ' ') { + word[i++] = *p2; + p2++; + } + path_p->minor = atoi (word); + + strcpy (path_p->mapname, devmaps_p->mapname); + + /* + * discard active paths + * don't trust the A status flag : double check + */ + if (*p1 == 'A' && + !select_checkfn (path_p) && + checkpath (path_p)) { + LOG(2, "[updatepaths] discard %i:%i as valid path", + path_p->major, path_p->minor); + p1++; + memset (path_p, 0, sizeof(struct path)); + continue; + } + + path_p++; + + /* test vector overflow */ + if (path_p - failedpaths->paths_h >= MAXPATHS * sizeof (struct path)) { + LOG (1, "[updatepaths] path_h overflow"); + pthread_mutex_unlock (failedpaths->lock); + return 1; + } + } + p1++; + } + p2 = p1; + p1++; + } + } while (next); + +out: + dm_task_destroy(dmt); + devmaps_p++; + + } + + pthread_mutex_unlock (failedpaths->lock); + return 0; +} + +int geteventnr (char *name) +{ + struct dm_task *dmt; + struct dm_info info; + + if (!(dmt = dm_task_create(DM_DEVICE_INFO))) + return 0; + + if (!dm_task_set_name(dmt, name)) + goto out; + + if (!dm_task_run(dmt)) + goto out; + + if (!dm_task_get_info(dmt, &info)) + return 0; + + if (!info.exists) { + LOG(1, "Device %s does not exist", name); + return 0; + } + +out: + dm_task_destroy(dmt); + + return info.event_nr; +} + +void *waitevent (void * et) +{ + int event_nr; + struct event_thread *waiter; + + waiter = (struct event_thread *)et; + pthread_mutex_lock (waiter->waiter_lock); + + event_nr = geteventnr (waiter->mapname); + + struct dm_task *dmt; + + if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT))) + return 0; + + if (!dm_task_set_name(dmt, waiter->mapname)) + goto out; + + if (event_nr && !dm_task_set_event_nr(dmt, event_nr)) + goto out; + + dm_task_run(dmt); + +out: + dm_task_destroy(dmt); + + /* tell waiterloop we have an event */ + pthread_mutex_lock (event_lock); + pthread_cond_signal(event); + pthread_mutex_unlock (event_lock); + + /* release waiter_lock so that waiterloop knows we are gone */ + pthread_mutex_unlock (waiter->waiter_lock); + pthread_exit(waiter->thread); + + return (NULL); +} + +void *waiterloop (void *ap) +{ + struct paths *failedpaths; + struct devmap *devmaps, *devmaps_p; + struct event_thread *waiters, *waiters_p; + int r; + + /* inits */ + failedpaths = (struct paths *)ap; + devmaps = malloc (MAXMAPS * sizeof (struct devmap)); + waiters = malloc (MAXMAPS * sizeof (struct event_thread)); + memset (waiters, 0, MAXMAPS * sizeof (struct event_thread)); + + while (1) { + + /* update devmap list */ + LOG (1, "[event thread] refresh devmaps list"); + get_devmaps (devmaps); + + /* update failed paths list */ + LOG (1, "[event thread] refresh failpaths list"); + updatepaths (devmaps, failedpaths); + + /* start waiters on all devmaps */ + LOG (1, "[event thread] start up event loops"); + waiters_p = waiters; + devmaps_p = devmaps; + + while (*devmaps_p->mapname != 0x0) { + + /* find out if devmap already has a running waiter thread */ + while (*waiters_p->mapname != 0x0) { + if (!strcmp (waiters_p->mapname, devmaps_p->mapname)) + break; + waiters_p++; + } + + /* no event_thread struct : init it */ + if (*waiters_p->mapname == 0x0) { + strcpy (waiters_p->mapname, devmaps_p->mapname); + waiters_p->thread = malloc (sizeof (pthread_t)); + waiters_p->waiter_lock = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); + pthread_mutex_init (waiters_p->waiter_lock, NULL); + } + + /* event_thread struct found */ + if (*waiters_p->mapname != 0x0) { + r = pthread_mutex_trylock (waiters_p->waiter_lock); + /* thread already running : out */ + + if (r) + goto out; + + pthread_mutex_unlock (waiters_p->waiter_lock); + } + + LOG (1, "[event thread] create event thread for %s", waiters_p->mapname); + pthread_create (waiters_p->thread, NULL, waitevent, waiters_p); +out: + waiters_p = waiters; + devmaps_p++; + } + + /* wait event condition */ + pthread_mutex_lock (event_lock); + pthread_cond_wait(event, event_lock); + pthread_mutex_unlock (event_lock); + + LOG (1, "[event thread] event caught"); + } + + return (NULL); +} + +void *checkerloop (void *ap) +{ + struct paths *failedpaths; + struct path *path_p; + char *cmdargs[4] = {MULTIPATH, "-D", NULL, NULL}; + char major[5]; + char minor[5]; + int status; + + failedpaths = (struct paths *)ap; + + LOG (1, "[checker thread] path checkers start up"); + + while (1) { + path_p = failedpaths->paths_h; + pthread_mutex_lock (failedpaths->lock); + LOG (2, "[checker thread] checking paths"); + while (path_p->major != 0) { + + if (checkpath (path_p)) { + LOG (1, "[checker thread] reconfigure %s\n", path_p->mapname); + snprintf (major, 5, "%i", path_p->major); + snprintf (minor, 5, "%i", path_p->minor); + cmdargs[2] = major; + cmdargs[3] = minor; + if (fork () == 0) + execve (cmdargs[0], cmdargs, NULL); + + wait (&status); + /* MULTIPATH will ask for failedpaths refresh (SIGHUP) */ + } + + path_p++; + + /* test vector overflow */ + if (path_p - failedpaths->paths_h >= MAXPATHS * sizeof (struct path)) { + LOG (1, "[checker thread] path_h overflow"); + pthread_mutex_unlock (failedpaths->lock); + return (NULL); + } + } + pthread_mutex_unlock (failedpaths->lock); + sleep(CHECKINT); + } + + return (NULL); +} + +struct paths *initpaths (void) +{ + struct paths *failedpaths; + + failedpaths = malloc (sizeof (struct paths)); + failedpaths->paths_h = malloc (MAXPATHS * sizeof (struct path)); + failedpaths->lock = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); + pthread_mutex_init (failedpaths->lock, NULL); + event = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + pthread_cond_init (event, NULL); + event_lock = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); + pthread_mutex_init (event_lock, NULL); + + return (failedpaths); +} + +void pidfile (pid_t pid) +{ + FILE *file; + struct stat *buf; + + buf = malloc (sizeof (struct stat)); + + if (!stat (PIDFILE, buf)) { + LOG(1, "[master thread] already running : out"); + free (buf); + exit (1); + } + + umask (022); + pid = setsid (); + + if (pid < -1) { + LOG(1, "[master thread] setsid() error"); + exit (1); + } + + file = fopen (PIDFILE, "w"); + fprintf (file, "%d\n", pid); + fclose (file); + free (buf); +} + +void * +signal_set(int signo, void (*func) (int)) +{ + int r; + struct sigaction sig; + struct sigaction osig; + + sig.sa_handler = func; + sigemptyset(&sig.sa_mask); + sig.sa_flags = 0; + + r = sigaction(signo, &sig, &osig); + + if (r < 0) + return (SIG_ERR); + else + return (osig.sa_handler); +} + +void sighup (int sig) +{ + LOG (1, "[master thread] SIGHUP caught : refresh devmap list"); + + /* ask for failedpaths refresh */ + pthread_mutex_lock (event_lock); + pthread_cond_signal(event); + pthread_mutex_unlock (event_lock); +} + +void sigend (int sig) +{ + LOG (1, "[master thread] unlink pidfile"); + unlink (PIDFILE); + LOG (1, "[master thread] --------shut down-------"); + exit (0); +} + +void signal_init(void) +{ + signal_set(SIGHUP, sighup); + signal_set(SIGINT, sigend); + signal_set(SIGTERM, sigend); + signal_set(SIGKILL, sigend); +} + +int main (int argc, char *argv[]) +{ + pthread_t wait, check; + struct paths *failedpaths; + pid_t pid; + + pid = fork (); + + /* can't fork */ + if (pid < 0) + exit (1); + + /* let the parent die happy */ + if (pid > 0) + exit (0); + + /* child's play */ + openlog (argv[0], 0, LOG_DAEMON); + LOG (1, "[master thread] --------start up--------"); + + pidfile (pid); + signal_init (); + + failedpaths = initpaths (); + + pthread_create (&wait, NULL, waiterloop, failedpaths); + pthread_create (&check, NULL, checkerloop, failedpaths); + pthread_join (wait, NULL); + pthread_join (check, NULL); + + return 0; +} diff --git a/extras/multipath-tools/multipathd/multipathd.init b/extras/multipath-tools/multipathd/multipathd.init new file mode 100644 index 0000000000..860b2b11db --- /dev/null +++ b/extras/multipath-tools/multipathd/multipathd.init @@ -0,0 +1,42 @@ +#!/bin/sh + +PATH=/bin:/usr/bin:/sbin:/usr/sbin +DAEMON=/usr/bin/multipathd +PIDFILE=/var/run/multipathd.pid + +test -x $DAEMON || exit 0 + +case "$1" in + start) + echo -n "Starting multipath daemon: multipathd" + if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name multipathd + then + echo " already running." + exit + fi + /sbin/start-stop-daemon --start --quiet --exec $DAEMON + echo "." + ;; + stop) + echo -n "Stopping multipath daemon: multipathd" + if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name multipathd + then + PID=`cat $PIDFILE` + start-stop-daemon --quiet --stop --exec $DAEMON --pidfile $PIDFILE --name multipathd + # Now we wait for it to die + while kill -0 $PID 2>/dev/null; do sleep 1; done + echo "." + else + echo " not running."; + fi + ;; + force-reload|restart) + $0 stop + $0 start + ;; + *) + echo "Usage: /etc/init.d/multipathd {start|stop|restart|force-reload}" + exit 1 +esac + +exit 0 diff --git a/extras/multipath-tools/multipathd/sg_include.h b/extras/multipath-tools/multipathd/sg_include.h new file mode 100644 index 0000000000..460506826e --- /dev/null +++ b/extras/multipath-tools/multipathd/sg_include.h @@ -0,0 +1,43 @@ +#ifdef SG_KERNEL_INCLUDES + #define __user + typedef unsigned char u8; + #include "/usr/src/linux/include/scsi/sg.h" + #include "/usr/src/linux/include/scsi/scsi.h" +#else + #ifdef SG_TRICK_GNU_INCLUDES + #include + #include + #else + #include + #endif +#endif + +/* + Getting the correct include files for the sg interface can be an ordeal. + In a perfect world, one would just write: + #include + #include + This would include the files found in the /usr/include/scsi directory. + Those files are maintained with the GNU library which may or may not + agree with the kernel and version of sg driver that is running. Any + many cases this will not matter. However in some it might, for example + glibc 2.1's include files match the sg driver found in the lk 2.2 + series. Hence if glibc 2.1 is used with lk 2.4 then the additional + sg v3 interface will not be visible. + If this is a problem then defining SG_KERNEL_INCLUDES will access the + kernel supplied header files (assuming they are in the normal place). + The GNU library maintainers and various kernel people don't like + this approach (but it does work). + The technique selected by defining SG_TRICK_GNU_INCLUDES worked (and + was used) prior to glibc 2.2 . Prior to that version /usr/include/linux + was a symbolic link to /usr/src/linux/include/linux . + + There are other approaches if this include "mixup" causes pain. These + would involve include files being copied or symbolic links being + introduced. + + Sorry about the inconvenience. Typically neither SG_KERNEL_INCLUDES + nor SG_TRICK_GNU_INCLUDES is defined. + + dpg 20010415, 20030522 +*/ From 35b38379bac87ebf4d0cc6884feff588ee859d5f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 11 Mar 2004 01:36:12 -0800 Subject: [PATCH 0649/4284] [PATCH] cleanup callout fork Here I change the callout fork logic. The current cersion is unable to read a pipe which is not flushed at once, Now we read until it's closed. The maximum argument count is calculated by the strlen now. We have 100 chars for our result buffer so we can't have more than 50 parameters. So it's much more clear what will happen now and not some magic boundary where we use shell behind it. Parameter can be combined to one by using apostrophes. this on works now: BUS="scsi", PROGRAM="/bin/sh -c 'echo foo3 foo4 foo5 foo6 foo7 foo8 foo9 | sed s/foo9/bar9/'", KERNEL="sda3", NAME="%c{7}" Two new test are also added. --- namedev.c | 92 ++++++++++++++++++++++++----------------------- namedev.h | 1 - test/udev-test.pl | 18 ++++++++++ 3 files changed, 66 insertions(+), 45 deletions(-) diff --git a/namedev.c b/namedev.c index 1e424998f6..a9142374f4 100644 --- a/namedev.c +++ b/namedev.c @@ -370,22 +370,41 @@ static void fix_kernel_name(struct udevice *udev) static int execute_program(char *path, char *value, int len) { int retval; - int res; + int count; int status; int fds[2]; pid_t pid; - int value_set = 0; - char buffer[255]; char *pos; - char *args[PROGRAM_MAXARG]; + char arg[PROGRAM_SIZE]; + char *argv[sizeof(arg) / 2]; int i; - dbg("executing '%s'", path); + i = 0; + if (strchr(path, ' ')) { + strfieldcpy(arg, path); + pos = arg; + while (pos != NULL) { + if (pos[0] == '\'') { + /* don't separate if in apostrophes */ + pos++; + argv[i] = strsep(&pos, "\'"); + while (pos[0] == ' ') + pos++; + } else { + argv[i] = strsep(&pos, " "); + } + dbg("arg[%i] '%s'", i, argv[i]); + i++; + } + } + argv[i] = NULL; + retval = pipe(fds); if (retval != 0) { dbg("pipe failed"); return -1; } + pid = fork(); switch(pid) { case 0: @@ -394,28 +413,14 @@ static int execute_program(char *path, char *value, int len) /* dup write side of pipe to STDOUT */ dup(fds[1]); - - /* copy off our path to use incase we have too many args */ - strfieldcpymax(buffer, path, sizeof(buffer)); - - if (strchr(path, ' ')) { - /* exec with arguments */ - pos = path; - for (i=0; i < PROGRAM_MAXARG-1; i++) { - args[i] = strsep(&pos, " "); - if (args[i] == NULL) - break; - } - if (args[i]) { - dbg("too many args - %d, using subshell instead '%s'", i, buffer); - retval = execl("/bin/sh", "sh", "-c", buffer, NULL); - } else { - dbg("execute program '%s'", path); - retval = execv(args[0], args); - } + if (argv[0] != NULL) { + dbg("execute '%s' with given arguments", argv[0]); + retval = execv(argv[0], argv); } else { + dbg("execute '%s' with main argument", path); retval = execv(path, main_argv); } + info(FIELD_PROGRAM " execution of '%s' failed", path); exit(1); case -1: @@ -425,34 +430,33 @@ static int execute_program(char *path, char *value, int len) /* parent reads from fds[0] */ close(fds[1]); retval = 0; + i = 0; while (1) { - res = read(fds[0], buffer, sizeof(buffer) - 1); - if (res <= 0) + count = read(fds[0], value + i, len - i-1); + if (count <= 0) break; - buffer[res] = '\0'; - if (res > len) { + + i += count; + if (i >= len-1) { dbg("result len %d too short", len); retval = -1; - } - if (value_set) { - dbg("result value already set"); - retval = -1; - } else { - value_set = 1; - strncpy(value, buffer, len); - pos = value + strlen(value)-1; - if (pos[0] == '\n') - pos[0] = '\0'; - dbg("result is '%s'", value); + break; } } - close(fds[0]); - res = wait(&status); - if (res < 0) { - dbg("wait failed result %d", res); + + if (count < 0) { + dbg("read failed with '%s'", strerror(errno)); retval = -1; } + if (i > 0 && value[i] == '\n') + i--; + value[i] = '\0'; + dbg("result is '%s'", value); + + close(fds[0]); + wait(&status); + if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { dbg("exec program status 0x%x", status); retval = -1; @@ -730,7 +734,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas apply_format(udev, dev->program, sizeof(dev->program), class_dev, sysfs_device); if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { - dbg(FIELD_PROGRAM " returned nozero"); + dbg(FIELD_PROGRAM " returned nonzero"); goto try_parent; } else { dbg(FIELD_PROGRAM " returned successful"); diff --git a/namedev.h b/namedev.h index 16a8bffe97..68100d4f62 100644 --- a/namedev.h +++ b/namedev.h @@ -51,7 +51,6 @@ struct sysfs_class_device; #define ATTR_PARTITIONS "all_partitions" #define PARTITIONS_COUNT 15 -#define PROGRAM_MAXARG 10 #define MAX_SYSFS_PAIRS 5 #define RULEFILE_EXT ".rules" diff --git a/test/udev-test.pl b/test/udev-test.pl index 38ea0181f6..dadec568ba 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -259,6 +259,24 @@ EOF expected => "foo9" , conf => < "program with subshell", + subsys => "block", + devpath => "block/sda/sda3", + expected => "bar9" , + conf => < "program arguments combined with apostrophes", + subsys => "block", + devpath => "block/sda/sda3", + expected => "foo7" , + conf => < Date: Thu, 11 Mar 2004 01:37:18 -0800 Subject: [PATCH 0650/4284] [PATCH] callout part selector tweak Martin Schwenke asked for this feature and posted a patch: The following patch almost let's me have the following configuration: PROGRAM="/sbin/aliaser %b %k %n %M %m", RESULT="?*", NAME="%c{1}", SYMLINK="%c{2+}" allowing me to specify an arbitrary number of symlinks by saying "giveme the second and later words"." Here is the actual version with tests and a few words in the man page. --- namedev.c | 8 ++++++-- test/udev-test.pl | 9 +++++++++ udev.8 | 5 ++++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/namedev.c b/namedev.c index a9142374f4..7305676d42 100644 --- a/namedev.c +++ b/namedev.c @@ -190,6 +190,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, int i; char c; char *spos; + char *rest; int slen; struct sysfs_attribute *tmpattr; @@ -244,7 +245,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, /* get part part of the result string */ i = 0; if (attr != NULL) - i = atoi(attr); + i = strtoul(attr, &rest, 10); if (i > 0) { foreach_strpart(udev->program_result, " \n\r", spos, slen) { i--; @@ -255,7 +256,10 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("requested part of result string not found"); break; } - strfieldcpymax(temp2, spos, slen+1); + if (rest[0] == '+') + strfieldcpy(temp2, spos); + else + strfieldcpymax(temp2, spos, slen+1); strfieldcatmax(string, temp2, maxsize); dbg("substitute part of result string '%s'", temp2); } else { diff --git a/test/udev-test.pl b/test/udev-test.pl index dadec568ba..7db92691d3 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -304,6 +304,15 @@ EOF expected => "link1" , conf => < "program result substitution (numbered part of+)", + subsys => "block", + devpath => "block/sda/sda3", + expected => "link3" , + conf => < Date: Thu, 11 Mar 2004 01:39:53 -0800 Subject: [PATCH 0651/4284] [PATCH] "symlink only" test Here is a test for the "symlink only" rule. Any reason to do the apply_format() inside the loop? I've changed it. --- namedev.c | 15 +++++---------- test/udev-test.pl | 11 +++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/namedev.c b/namedev.c index 7305676d42..025a14aea4 100644 --- a/namedev.c +++ b/namedev.c @@ -815,16 +815,11 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } if (dev->symlink[0] != '\0') { - char temp[NAME_MAX]; - info("configured rule in '%s' at line %i applied, added symlink '%s'", dev->config_file, dev->config_line, dev->symlink); - /* do not clobber dev */ - strfieldcpy(temp, dev->symlink); - apply_format(udev, temp, sizeof(temp), - class_dev, sysfs_device); - strfieldcat(udev->symlink, temp); - strfieldcat(udev->symlink, " "); + if (udev->symlink[0] != '\0') + strfieldcat(udev->symlink, " "); + strfieldcat(udev->symlink, dev->symlink); } if (dev->name[0] != '\0') { @@ -841,8 +836,8 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud goto done; found: - apply_format(udev, udev->name, sizeof(udev->name), - class_dev, sysfs_device); + apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + apply_format(udev, udev->symlink, sizeof(udev->symlink), class_dev, sysfs_device); udev->partitions = dev->partitions; done: diff --git a/test/udev-test.pl b/test/udev-test.pl index 7db92691d3..c12a21ee3d 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -511,6 +511,17 @@ EOF conf => < "SYMLINK only rule", + subsys => "block", + devpath => "block/sda", + expected => "symlink-only2", + conf => < Date: Fri, 12 Mar 2004 00:57:30 -0800 Subject: [PATCH 0652/4284] [PATCH] Libsysfs updates Please find attached a _BIG_ patch to update udev's libsysfs. Patch applies on udev-021 and contains: 1. Updates to get udev's libsysfs to the latest (to be released) level. 2. Changes for C++ compatibility (use "char" and not "unsigned char" unless absolutely necessary). 3. More importantly, take care of buffer overflows. Libsysfs now uses a scaled down version of Kay's "safe" macros. Tested using a usb-storage device. I will send you a doc update shortly. --- libsysfs/dlist.c | 10 ++ libsysfs/dlist.h | 3 +- libsysfs/sysfs/libsysfs.h | 205 ++++++++++++++++++++++---------------- libsysfs/sysfs_bus.c | 114 +++++++-------------- libsysfs/sysfs_class.c | 119 +++++++++++----------- libsysfs/sysfs_device.c | 174 +++++++++++++++++++++----------- libsysfs/sysfs_dir.c | 157 ++++++++++++++++------------- libsysfs/sysfs_driver.c | 73 +++++++------- libsysfs/sysfs_utils.c | 130 +++++++++++++----------- 9 files changed, 534 insertions(+), 451 deletions(-) diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index a94ab1f854..942eccb48c 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -260,6 +260,16 @@ void dlist_unshift(Dlist *list,void *data) dlist_insert(list,data,0); } +void dlist_unshift_sorted(Dlist *list, void *data, + int (*sorter)(void *new, void *old)) +{ + if (list->count == 0) + dlist_unshift(list, data); + else { + list->marker=list->head->next; + dlist_insert_sorted(list, data, sorter); + } +} /* * Remove end node from list. diff --git a/libsysfs/dlist.h b/libsysfs/dlist.h index 83f67e8d44..7fc90e5bf5 100644 --- a/libsysfs/dlist.h +++ b/libsysfs/dlist.h @@ -76,13 +76,14 @@ void dlist_end(Dlist *); void *dlist_insert(Dlist *,void *,int) ; -void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, void *)); +void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *)); void dlist_delete(Dlist *,int); void dlist_push(Dlist *,void *); void dlist_unshift(Dlist *,void *); +void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *)); void *dlist_pop(Dlist *); diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index f3d2dd4d16..cbde2f5783 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -24,6 +24,25 @@ #define _LIBSYSFS_H_ #include +#include + +/* + * Defines to prevent buffer overruns + */ +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) + +#define safestrncpy(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncpy(to, from, maxsize-1); \ +} while (0) + +#define safestrncat(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncat(to, from, maxsize - strlen(to)-1); \ +} while (0) /* * Generic #defines go here.. @@ -46,25 +65,28 @@ #define SYSFS_METHOD_SHOW 0x01 /* attr can be read by user */ #define SYSFS_METHOD_STORE 0x02 /* attr can be changed by user */ -struct dlist; +/* + * NOTE: We have the statically allocated "name" as the first element of all + * the structures. This feature is used in the "sorter" function for dlists + */ struct sysfs_attribute { - unsigned char *value; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char *value; unsigned short len; /* value length */ unsigned short method; /* show and store */ - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; }; struct sysfs_link { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; - unsigned char target[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char target[SYSFS_PATH_MAX]; }; struct sysfs_directory { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *subdirs; @@ -73,8 +95,8 @@ struct sysfs_directory { }; struct sysfs_driver { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *devices; @@ -82,11 +104,11 @@ struct sysfs_driver { }; struct sysfs_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char bus_id[SYSFS_NAME_LEN]; - unsigned char bus[SYSFS_NAME_LEN]; - unsigned char driver_name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char bus_id[SYSFS_NAME_LEN]; + char bus[SYSFS_NAME_LEN]; + char driver_name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct sysfs_device *parent; @@ -95,8 +117,8 @@ struct sysfs_device { }; struct sysfs_root_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *devices; @@ -104,8 +126,8 @@ struct sysfs_root_device { }; struct sysfs_bus { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *drivers; @@ -114,9 +136,9 @@ struct sysfs_bus { }; struct sysfs_class_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char classname[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char classname[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct sysfs_class_device *parent; @@ -126,8 +148,8 @@ struct sysfs_class_device { }; struct sysfs_class { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct dlist *devices; @@ -141,49 +163,47 @@ extern "C" { /* * Function Prototypes */ -extern int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); -extern int sysfs_remove_trailing_slash(unsigned char *path); -extern int sysfs_get_name_from_path(const unsigned char *path, - unsigned char *name, size_t len); -extern int sysfs_path_is_dir(const unsigned char *path); -extern int sysfs_path_is_link(const unsigned char *path); -extern int sysfs_path_is_file(const unsigned char *path); -extern int sysfs_get_link(const unsigned char *path, unsigned char *target, - size_t len); -extern struct dlist *sysfs_open_subsystem_list(unsigned char *name); -extern struct dlist *sysfs_open_bus_devices_list(unsigned char *name); +extern int sysfs_get_mnt_path(char *mnt_path, size_t len); +extern int sysfs_remove_trailing_slash(char *path); +extern int sysfs_get_name_from_path(const char *path, char *name, size_t len); +extern int sysfs_path_is_dir(const char *path); +extern int sysfs_path_is_link(const char *path); +extern int sysfs_path_is_file(const char *path); +extern int sysfs_get_link(const char *path, char *target, size_t len); +extern struct dlist *sysfs_open_subsystem_list(char *name); +extern struct dlist *sysfs_open_bus_devices_list(char *name); extern void sysfs_close_list(struct dlist *list); /* sysfs directory and file access */ extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); -extern struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path); +extern struct sysfs_attribute *sysfs_open_attribute(const char *path); extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); -extern int sysfs_read_attribute_value(const unsigned char *attrpath, - unsigned char *value, size_t vsize); +extern int sysfs_read_attribute_value(const char *attrpath, + char *value, size_t vsize); extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const unsigned char *new_value, size_t len); -extern unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, - const unsigned char * name); + const char *new_value, size_t len); +extern char *sysfs_get_value_from_attributes(struct dlist *attr, + const char *name); extern int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir); extern int sysfs_refresh_dir_links(struct sysfs_directory *sysdir); extern int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir); extern void sysfs_close_directory(struct sysfs_directory *sysdir); -extern struct sysfs_directory *sysfs_open_directory(const unsigned char *path); +extern struct sysfs_directory *sysfs_open_directory(const char *path); extern int sysfs_read_dir_attributes(struct sysfs_directory *sysdir); extern int sysfs_read_dir_links(struct sysfs_directory *sysdir); extern int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir); extern int sysfs_read_directory(struct sysfs_directory *sysdir); extern int sysfs_read_all_subdirs(struct sysfs_directory *sysdir); extern struct sysfs_directory *sysfs_get_subdirectory - (struct sysfs_directory *dir, unsigned char *subname); + (struct sysfs_directory *dir, char *subname); extern void sysfs_close_link(struct sysfs_link *ln); -extern struct sysfs_link *sysfs_open_link(const unsigned char *lnpath); -extern struct sysfs_link *sysfs_get_directory_link(struct sysfs_directory *dir, - unsigned char *linkname); +extern struct sysfs_link *sysfs_open_link(const char *lnpath); +extern struct sysfs_link *sysfs_get_directory_link + (struct sysfs_directory *dir, char *linkname); extern struct sysfs_link *sysfs_get_subdirectory_link - (struct sysfs_directory *dir, unsigned char *linkname); + (struct sysfs_directory *dir, char *linkname); extern struct sysfs_attribute *sysfs_get_directory_attribute - (struct sysfs_directory *dir, unsigned char *attrname); + (struct sysfs_directory *dir, char *attrname); extern struct dlist *sysfs_get_dir_attributes(struct sysfs_directory *dir); extern struct dlist *sysfs_get_dir_links(struct sysfs_directory *dir); extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir); @@ -191,84 +211,101 @@ extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir); /* sysfs driver access */ extern void sysfs_close_driver(struct sysfs_driver *driver); extern struct sysfs_driver *sysfs_open_driver - (const unsigned char *drv_name, const unsigned char *bus_name); -extern struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path); + (const char *bus_name, const char *drv_name); +extern struct sysfs_driver *sysfs_open_driver_path(const char *path); extern struct sysfs_attribute *sysfs_get_driver_attr - (struct sysfs_driver *drv, const unsigned char *name); + (struct sysfs_driver *drv, const char *name); extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); extern struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver); extern struct sysfs_device *sysfs_get_driver_device - (struct sysfs_driver *driver, const unsigned char *name); + (struct sysfs_driver *driver, const char *name); extern struct dlist *sysfs_refresh_driver_attributes - (struct sysfs_driver *driver); -extern struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, - const unsigned char *drv, const unsigned char *attrib); + (struct sysfs_driver *driver); +extern struct sysfs_attribute *sysfs_open_driver_attr + (const char *bus, const char *drv, const char *attrib); /* generic sysfs device access */ extern void sysfs_close_root_device(struct sysfs_root_device *root); -extern struct sysfs_root_device *sysfs_open_root_device - (const unsigned char *name); +extern struct sysfs_root_device *sysfs_open_root_device(const char *name); extern struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root); +extern void sysfs_close_device_tree(struct sysfs_device *device); +extern struct sysfs_device *sysfs_open_device_tree(const char *path); extern void sysfs_close_device(struct sysfs_device *dev); extern struct sysfs_device *sysfs_open_device - (const unsigned char *bus_id, const unsigned char *bus); + (const char *bus, const char *bus_id); extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev); -extern struct sysfs_device *sysfs_open_device_path(const unsigned char *path); +extern struct sysfs_device *sysfs_open_device_path(const char *path); extern int sysfs_get_device_bus(struct sysfs_device *dev); extern struct sysfs_attribute *sysfs_get_device_attr - (struct sysfs_device *dev, const unsigned char *name); + (struct sysfs_device *dev, const char *name); extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); extern struct dlist *sysfs_refresh_device_attributes - (struct sysfs_device *device); -extern struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, - const unsigned char *bus_id, const unsigned char *attrib); + (struct sysfs_device *device); +extern struct sysfs_attribute *sysfs_open_device_attr(const char *bus, + const char *bus_id, const char *attrib); /* generic sysfs bus access */ extern void sysfs_close_bus(struct sysfs_bus *bus); -extern struct sysfs_bus *sysfs_open_bus(const unsigned char *name); -extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, - unsigned char *id); +extern struct sysfs_bus *sysfs_open_bus(const char *name); +extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, + char *id); extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, - unsigned char *drvname); + char *drvname); extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus); extern struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus); -extern struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, - unsigned char *attrname); -extern struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, - unsigned char *dev_id); -extern int sysfs_find_driver_bus(const unsigned char *driver, - unsigned char *busname, size_t bsize); +extern struct sysfs_attribute *sysfs_get_bus_attribute + (struct sysfs_bus *bus, char *attrname); +extern int sysfs_find_driver_bus(const char *driver, char *busname, + size_t bsize); /* generic sysfs class access */ extern void sysfs_close_class_device(struct sysfs_class_device *dev); extern struct sysfs_class_device *sysfs_open_class_device_path - (const unsigned char *path); + (const char *path); extern struct sysfs_class_device *sysfs_open_class_device - (const unsigned char *class, const unsigned char *name); + (const char *classname, const char *name); extern struct sysfs_device *sysfs_get_classdev_device - (struct sysfs_class_device *clsdev); + (struct sysfs_class_device *clsdev); extern struct sysfs_driver *sysfs_get_classdev_driver - (struct sysfs_class_device *clsdev); + (struct sysfs_class_device *clsdev); extern struct sysfs_class_device *sysfs_get_classdev_parent - (struct sysfs_class_device *clsdev); + (struct sysfs_class_device *clsdev); extern void sysfs_close_class(struct sysfs_class *cls); -extern struct sysfs_class *sysfs_open_class(const unsigned char *name); +extern struct sysfs_class *sysfs_open_class(const char *name); extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); extern struct sysfs_class_device *sysfs_get_class_device - (struct sysfs_class *class, unsigned char *name); + (struct sysfs_class *cls, char *name); extern struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *cdev); extern struct dlist *sysfs_refresh_classdev_attributes (struct sysfs_class_device *cdev); extern struct sysfs_attribute *sysfs_get_classdev_attr - (struct sysfs_class_device *clsdev, const unsigned char *name); + (struct sysfs_class_device *clsdev, const char *name); extern struct sysfs_attribute *sysfs_open_classdev_attr - (const unsigned char *classname, const unsigned char *dev, - const unsigned char *attrib); + (const char *classname, const char *dev, + const char *attrib); + +/** + * sort_list: sorter function to keep list elements sorted in alphabetical + * order. Just does a strncmp as you can see :) + * + * Returns 1 if less than 0 otherwise + * + * NOTE: We take care to have a statically allocated "name" as the first + * lement of all libsysfs structures. Hence, this function will work + * AS IS for _ALL_ the lists that have to be sorted. + */ +static inline int sort_list(void *new_elem, void *old_elem) +{ + return ((strncmp(((struct sysfs_attribute *)new_elem)->name, + ((struct sysfs_attribute *)old_elem)->name, + strlen(((struct sysfs_attribute *)new_elem)->name))) < 0 ? 1 : 0); +} + #ifdef __cplusplus } diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 87318c0029..bff7f78f05 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -44,7 +44,7 @@ static int bus_device_id_equal(void *a, void *b) if (a == NULL || b == NULL) return 0; - if (strcmp(((unsigned char *)a), ((struct sysfs_device *)b)->bus_id) + if (strcmp(((char *)a), ((struct sysfs_device *)b)->bus_id) == 0) return 1; return 0; @@ -61,7 +61,7 @@ static int bus_driver_name_equal(void *a, void *b) if (a == NULL || b == NULL) return 0; - if (strcmp(((unsigned char *)a), ((struct sysfs_driver *)b)->name) == 0) + if (strcmp(((char *)a), ((struct sysfs_driver *)b)->name) == 0) return 1; return 0; } @@ -102,16 +102,16 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) struct sysfs_device *bdev = NULL; struct sysfs_directory *devdir = NULL; struct sysfs_link *curl = NULL; - unsigned char path[SYSFS_PATH_MAX]; + char path[SYSFS_PATH_MAX]; if (bus == NULL) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); - strcpy(path, bus->path); - strcat(path, "/"); - strcat(path, SYSFS_DEVICES_NAME); + safestrcpy(path, bus->path); + safestrcat(path, "/"); + safestrcat(path, SYSFS_DEVICES_NAME); devdir = sysfs_open_directory(path); if (devdir == NULL) return NULL; @@ -121,7 +121,7 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) return NULL; } - if (devdir->links != 0) { + if (devdir->links != NULL) { dlist_for_each_data(devdir->links, curl, struct sysfs_link) { bdev = sysfs_open_device_path(curl->target); if (bdev == NULL) { @@ -133,7 +133,7 @@ struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) bus->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev); - dlist_unshift(bus->devices, bdev); + dlist_unshift_sorted(bus->devices, bdev, sort_list); } } sysfs_close_directory(devdir); @@ -151,16 +151,16 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) struct sysfs_driver *driver = NULL; struct sysfs_directory *drvdir = NULL; struct sysfs_directory *cursub = NULL; - unsigned char path[SYSFS_PATH_MAX]; + char path[SYSFS_PATH_MAX]; if (bus == NULL) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); - strcpy(path, bus->path); - strcat(path, "/"); - strcat(path, SYSFS_DRIVERS_NAME); + safestrcpy(path, bus->path); + safestrcat(path, "/"); + safestrcat(path, SYSFS_DRIVERS_NAME); drvdir = sysfs_open_directory(path); if (drvdir == NULL) return NULL; @@ -182,7 +182,7 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) bus->drivers = dlist_new_with_delete (sizeof(struct sysfs_driver), sysfs_close_drv); - dlist_unshift(bus->drivers, driver); + dlist_unshift_sorted(bus->drivers, driver, sort_list); } } sysfs_close_directory(drvdir); @@ -193,10 +193,10 @@ struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) * sysfs_open_bus: opens specific bus and all its devices on system * returns sysfs_bus structure with success or NULL with error. */ -struct sysfs_bus *sysfs_open_bus(const unsigned char *name) +struct sysfs_bus *sysfs_open_bus(const char *name) { struct sysfs_bus *bus = NULL; - unsigned char buspath[SYSFS_PATH_MAX]; + char buspath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; @@ -209,10 +209,10 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name) return NULL; } - strcat(buspath, "/"); - strcat(buspath, SYSFS_BUS_NAME); - strcat(buspath, "/"); - strcat(buspath, name); + safestrcat(buspath, "/"); + safestrcat(buspath, SYSFS_BUS_NAME); + safestrcat(buspath, "/"); + safestrcat(buspath, name); if ((sysfs_path_is_dir(buspath)) != 0) { dprintf("Invalid path to bus: %s\n", buspath); return NULL; @@ -222,8 +222,8 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name) dprintf("calloc failed\n"); return NULL; } - strcpy(bus->name, name); - strcpy(bus->path, buspath); + safestrcpy(bus->name, name); + safestrcpy(bus->path, buspath); if ((sysfs_remove_trailing_slash(bus->path)) != 0) { dprintf("Incorrect path to bus %s\n", bus->path); sysfs_close_bus(bus); @@ -239,8 +239,7 @@ struct sysfs_bus *sysfs_open_bus(const unsigned char *name) * @id: bus_id for device * returns struct sysfs_device reference or NULL if not found. */ -struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, - unsigned char *id) +struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, char *id) { if (bus == NULL || id == NULL) { errno = EINVAL; @@ -264,7 +263,7 @@ struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, * returns struct sysfs_driver reference or NULL if not found. */ struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, - unsigned char *drvname) + char *drvname) { if (bus == NULL || drvname == NULL) { errno = EINVAL; @@ -338,7 +337,7 @@ struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus) * returns reference to sysfs_attribute if found or NULL if not found */ struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, - unsigned char *attrname) + char *attrname) { struct dlist *attrlist = NULL; @@ -353,49 +352,6 @@ struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, return sysfs_get_directory_attribute(bus->directory, attrname); } -/** - * sysfs_open_bus_device: locates a device on a bus and returns it. Device - * must be closed using sysfs_close_device. - * @busname: Name of bus to search - * @dev_id: Id of device on bus. - * returns sysfs_device if found or NULL if not. - */ -struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, - unsigned char *dev_id) -{ - struct sysfs_device *rdev = NULL; - char path[SYSFS_PATH_MAX]; - - if (busname == NULL || dev_id == NULL) { - errno = EINVAL; - return NULL; - } - - memset(path, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(path, SYSFS_PATH_MAX) != 0) { - dprintf("Error getting sysfs mount point\n"); - return NULL; - } - - strcat(path, "/"); - strcat(path, SYSFS_BUS_NAME); - strcat(path, "/"); - strcat(path, busname); - strcat(path, "/"); - strcat(path, SYSFS_DEVICES_NAME); - strcat(path, "/"); - strcat(path, dev_id); - - rdev = sysfs_open_device_path(path); - if (rdev == NULL) { - dprintf("Error getting device %s on bus %s\n", - dev_id, busname); - return NULL; - } - - return rdev; -} - /** * sysfs_find_driver_bus: locates the bus the driver is on. * @driver: name of the driver to locate @@ -403,10 +359,9 @@ struct sysfs_device *sysfs_open_bus_device(unsigned char *busname, * @bsize: buffer size * returns 0 with success, -1 with error */ -int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, - size_t bsize) +int sysfs_find_driver_bus(const char *driver, char *busname, size_t bsize) { - unsigned char subsys[SYSFS_PATH_MAX], *bus = NULL, *curdrv = NULL; + char subsys[SYSFS_PATH_MAX], *bus = NULL, *curdrv = NULL; struct dlist *buslist = NULL, *drivers = NULL; if (driver == NULL || busname == NULL) { @@ -415,23 +370,22 @@ int sysfs_find_driver_bus(const unsigned char *driver, unsigned char *busname, } memset(subsys, 0, SYSFS_PATH_MAX); - strcat(subsys, "/"); - strcpy(subsys, SYSFS_BUS_NAME); + safestrcpy(subsys, SYSFS_BUS_NAME); buslist = sysfs_open_subsystem_list(subsys); if (buslist != NULL) { dlist_for_each_data(buslist, bus, char) { memset(subsys, 0, SYSFS_PATH_MAX); - strcat(subsys, "/"); - strcpy(subsys, SYSFS_BUS_NAME); - strcat(subsys, "/"); - strcat(subsys, bus); - strcat(subsys, "/"); - strcat(subsys, SYSFS_DRIVERS_NAME); + safestrcpy(subsys, SYSFS_BUS_NAME); + safestrcat(subsys, "/"); + safestrcat(subsys, bus); + safestrcat(subsys, "/"); + safestrcat(subsys, SYSFS_DRIVERS_NAME); drivers = sysfs_open_subsystem_list(subsys); if (drivers != NULL) { dlist_for_each_data(drivers, curdrv, char) { if (strcmp(driver, curdrv) == 0) { - strncpy(busname, bus, bsize); + safestrncpy(busname, + bus, bsize); sysfs_close_list(drivers); sysfs_close_list(buslist); return 0; diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 05305056dd..7a696355ca 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -38,8 +38,7 @@ static int class_name_equal(void *a, void *b) if (a == NULL || b == NULL) return 0; - if (strcmp(((unsigned char *)a), ((struct sysfs_class_device *)b)->name) - == 0) + if (strcmp(((char *)a), ((struct sysfs_class_device *)b)->name) == 0) return 1; return 0; @@ -66,7 +65,7 @@ void sysfs_close_class_device(struct sysfs_class_device *dev) /** * sysfs_close_class: close single class - * @class: class structure + * @cls: class structure */ void sysfs_close_class(struct sysfs_class *cls) { @@ -105,7 +104,7 @@ static struct sysfs_class *alloc_class(void) */ static void set_classdev_classname(struct sysfs_class_device *cdev) { - unsigned char *c = NULL, *e = NULL; + char *c = NULL, *e = NULL; int count = 0; c = strstr(cdev->path, SYSFS_CLASS_NAME); @@ -116,7 +115,7 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) } if (c == NULL) - strcpy(cdev->classname, SYSFS_UNKNOWN); + safestrcpy(cdev->classname, SYSFS_UNKNOWN); else { if (*c == '/') c++; @@ -134,8 +133,7 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) * @path: path to class device. * returns struct sysfs_class_device with success and NULL with error. */ -struct sysfs_class_device *sysfs_open_class_device_path - (const unsigned char *path) +struct sysfs_class_device *sysfs_open_class_device_path(const char *path) { struct sysfs_class_device *cdev = NULL; @@ -159,7 +157,7 @@ struct sysfs_class_device *sysfs_open_class_device_path return NULL; } - strcpy(cdev->path, path); + safestrcpy(cdev->path, path); if ((sysfs_remove_trailing_slash(cdev->path)) != 0) { dprintf("Invalid path to class device %s\n", cdev->path); sysfs_close_class_device(cdev); @@ -172,7 +170,7 @@ struct sysfs_class_device *sysfs_open_class_device_path /** * sysfs_get_class_devices: gets all devices for class - * @class: class to get devices for + * @cls: class to get devices for * returns dlist of class_devices with success and NULL with error */ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) @@ -210,7 +208,7 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) cls->devices = dlist_new_with_delete (sizeof(struct sysfs_class_device), sysfs_close_cls_dev); - dlist_unshift(cls->devices, dev); + dlist_unshift_sorted(cls->devices, dev, sort_list); } } return cls->devices; @@ -220,10 +218,10 @@ struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) * sysfs_open_class: opens specific class and all its devices on system * returns sysfs_class structure with success or NULL with error. */ -struct sysfs_class *sysfs_open_class(const unsigned char *name) +struct sysfs_class *sysfs_open_class(const char *name) { struct sysfs_class *cls = NULL; - unsigned char classpath[SYSFS_PATH_MAX]; + char classpath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; @@ -241,13 +239,13 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) * if "name" is "block" and proceed accordingly */ if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { - strcat(classpath, "/"); - strcat(classpath, SYSFS_BLOCK_NAME); + safestrcat(classpath, "/"); + safestrcat(classpath, SYSFS_BLOCK_NAME); } else { - strcat(classpath, "/"); - strcat(classpath, SYSFS_CLASS_NAME); - strcat(classpath, "/"); - strcat(classpath, name); + safestrcat(classpath, "/"); + safestrcat(classpath, SYSFS_CLASS_NAME); + safestrcat(classpath, "/"); + safestrcat(classpath, name); } if ((sysfs_path_is_dir(classpath)) != 0) { dprintf("Class %s not found on the system\n", name); @@ -259,8 +257,8 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) dprintf("calloc failed\n"); return NULL; } - strcpy(cls->name, name); - strcpy(cls->path, classpath); + safestrcpy(cls->name, name); + safestrcpy(cls->path, classpath); if ((sysfs_remove_trailing_slash(cls->path)) != 0) { dprintf("Invalid path to class device %s\n", cls->path); sysfs_close_class(cls); @@ -275,20 +273,20 @@ struct sysfs_class *sysfs_open_class(const unsigned char *name) * @class: class to find device on * @name: class name of the device */ -struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *class, - unsigned char *name) +struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, + char *name) { - if (class == NULL || name == NULL) { + if (cls == NULL || name == NULL) { errno = EINVAL; return NULL; } - if (class->devices == NULL) { - class->devices = sysfs_get_class_devices(class); - if (class->devices == NULL) + if (cls->devices == NULL) { + cls->devices = sysfs_get_class_devices(cls); + if (cls->devices == NULL) return NULL; } - return (struct sysfs_class_device *)dlist_find_custom(class->devices, + return (struct sysfs_class_device *)dlist_find_custom(cls->devices, name, class_name_equal); } @@ -303,14 +301,14 @@ struct sysfs_device *sysfs_get_classdev_device (struct sysfs_class_device *clsdev) { struct sysfs_link *devlink = NULL; - unsigned char devpath[SYSFS_PATH_MAX]; + char devpath[SYSFS_PATH_MAX]; if (clsdev == NULL) { errno = EINVAL; return NULL; } - strcpy(devpath, clsdev->path); - strcat(devpath, "/device"); + safestrcpy(devpath, clsdev->path); + safestrcat(devpath, "/device"); if ((sysfs_path_is_link(devpath)) != 0) { if (clsdev->sysdevice != NULL) { sysfs_close_device(clsdev->sysdevice); @@ -347,8 +345,6 @@ struct sysfs_device *sysfs_get_classdev_device clsdev->sysdevice = sysfs_open_device_path(devlink->target); if (clsdev->sysdevice == NULL) return NULL; - if (clsdev->driver != NULL) - strcpy(clsdev->sysdevice->driver_name, clsdev->driver->name); return (clsdev->sysdevice); } @@ -364,14 +360,14 @@ struct sysfs_driver *sysfs_get_classdev_driver (struct sysfs_class_device *clsdev) { struct sysfs_link *drvlink = NULL; - unsigned char drvpath[SYSFS_PATH_MAX]; + char drvpath[SYSFS_PATH_MAX]; if (clsdev == NULL) { errno = EINVAL; return NULL; } - strcpy(drvpath, clsdev->path); - strcat(drvpath, "/driver"); + safestrcpy(drvpath, clsdev->path); + safestrcat(drvpath, "/driver"); if ((sysfs_path_is_link(drvpath)) != 0) { if (clsdev->driver != NULL) { sysfs_close_driver(clsdev->driver); @@ -407,8 +403,6 @@ struct sysfs_driver *sysfs_get_classdev_driver clsdev->driver = sysfs_open_driver_path(drvlink->target); if (clsdev->driver == NULL) return NULL; - if (clsdev->sysdevice != NULL) - strcpy(clsdev->sysdevice->driver_name, clsdev->driver->name); return (clsdev->driver); } @@ -421,16 +415,15 @@ struct sysfs_driver *sysfs_get_classdev_driver */ static int get_blockdev_parent(struct sysfs_class_device *clsdev) { - unsigned char parent_path[SYSFS_PATH_MAX], *c = NULL; + char parent_path[SYSFS_PATH_MAX], *c = NULL; - strcpy(parent_path, clsdev->path); + safestrcpy(parent_path, clsdev->path); c = strstr(parent_path, SYSFS_BLOCK_NAME); if (c == NULL) { dprintf("Class device %s does not belong to BLOCK subsystem\n", clsdev->name); return 1; } - c += strlen(SYSFS_BLOCK_NAME); if (*c == '/') c++; @@ -486,7 +479,8 @@ struct sysfs_class_device *sysfs_get_classdev_parent * structure. Hence, we now call a specialized function for block and * later we can add support functions for other subsystems as required. */ - if (!(strcmp(clsdev->classname, SYSFS_BLOCK_NAME))) { + if (!(strncmp(clsdev->classname, SYSFS_BLOCK_NAME, + sizeof(SYSFS_BLOCK_NAME)))) { if ((get_blockdev_parent(clsdev)) == 0) return (clsdev->parent); } @@ -502,8 +496,8 @@ struct sysfs_class_device *sysfs_get_classdev_parent * @psize: size of "path" * Returns 0 on SUCCESS or -1 on error */ -static int get_classdev_path(const unsigned char *classname, - const unsigned char *clsdev, unsigned char *path, size_t len) +static int get_classdev_path(const char *classname, const char *clsdev, + char *path, size_t len) { if (classname == NULL || clsdev == NULL || path == NULL) { errno = EINVAL; @@ -513,17 +507,18 @@ static int get_classdev_path(const unsigned char *classname, dprintf("Error getting sysfs mount path\n"); return -1; } - if (strcmp(classname, SYSFS_BLOCK_NAME) == 0) { - strcat(path, "/"); - strcat(path, SYSFS_BLOCK_NAME); + if (strncmp(classname, SYSFS_BLOCK_NAME, + sizeof(SYSFS_BLOCK_NAME)) == 0) { + safestrncat(path, "/", len); + safestrncat(path, SYSFS_BLOCK_NAME, len); } else { - strcat(path, "/"); - strcat(path, SYSFS_CLASS_NAME); - strcat(path, "/"); - strcat(path, classname); + safestrncat(path, "/", len); + safestrncat(path, SYSFS_CLASS_NAME, len); + safestrncat(path, "/", len); + safestrncat(path, classname, len); } - strcat(path, "/"); - strcat(path, clsdev); + safestrncat(path, "/", len); + safestrncat(path, clsdev, len); return 0; } @@ -537,9 +532,9 @@ static int get_classdev_path(const unsigned char *classname, * Call sysfs_close_class_device() to close the class device */ struct sysfs_class_device *sysfs_open_class_device - (const unsigned char *classname, const unsigned char *name) + (const char *classname, const char *name) { - unsigned char devpath[SYSFS_PATH_MAX]; + char devpath[SYSFS_PATH_MAX]; struct sysfs_class_device *cdev = NULL; if (classname == NULL || name == NULL) { @@ -622,7 +617,7 @@ struct dlist *sysfs_refresh_classdev_attributes * returns sysfs_attribute reference with success or NULL with error */ struct sysfs_attribute *sysfs_get_classdev_attr - (struct sysfs_class_device *clsdev, const unsigned char *name) + (struct sysfs_class_device *clsdev, const char *name) { struct sysfs_attribute *cur = NULL; struct sysfs_directory *sdir = NULL; @@ -640,7 +635,7 @@ struct sysfs_attribute *sysfs_get_classdev_attr attrlist = sysfs_get_classdev_attributes(clsdev); if (attrlist != NULL) { cur = sysfs_get_directory_attribute(clsdev->directory, - (unsigned char *)name); + (char *)name); if (cur != NULL) return cur; } @@ -656,7 +651,7 @@ struct sysfs_attribute *sysfs_get_classdev_attr if ((sysfs_path_is_dir(sdir->path)) != 0) continue; cur = sysfs_get_directory_attribute(sdir, - (unsigned char *)name); + (char *)name); if (cur == NULL) continue; } @@ -675,11 +670,11 @@ struct sysfs_attribute *sysfs_get_classdev_attr * A call to sysfs_close_attribute() is required to close the * attribute returned and to free memory */ -struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname, - const unsigned char *dev, const unsigned char *attrib) +struct sysfs_attribute *sysfs_open_classdev_attr(const char *classname, + const char *dev, const char *attrib) { struct sysfs_attribute *attribute = NULL; - unsigned char path[SYSFS_PATH_MAX]; + char path[SYSFS_PATH_MAX]; if (classname == NULL || dev == NULL || attrib == NULL) { errno = EINVAL; @@ -691,8 +686,8 @@ struct sysfs_attribute *sysfs_open_classdev_attr(const unsigned char *classname, dev, classname); return NULL; } - strcat(path, "/"); - strcat(path, attrib); + safestrcat(path, "/"); + safestrcat(path, attrib); attribute = sysfs_open_attribute(path); if (attribute == NULL) { dprintf("Error opening attribute %s on class device %s\n", diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 06b8d2d99a..e3a8977016 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -23,6 +23,57 @@ #include "sysfs/libsysfs.h" #include "sysfs.h" +/** + * get_dev_driver: fills in the dev->driver_name field + * + * Returns 0 on SUCCESS and 1 on error + */ +static int get_dev_driver(struct sysfs_device *dev) +{ + struct dlist *drvlist = NULL; + char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; + char *drv = NULL, *c = NULL; + + if (dev == NULL) { + errno = EINVAL; + return 1; + } + if (dev->bus[0] == '\0') + return 1; + memset(path, 0, SYSFS_PATH_MAX); + memset(devpath, 0, SYSFS_PATH_MAX); + safestrcpy(path, SYSFS_BUS_NAME); + safestrcat(path, "/"); + safestrcat(path, dev->bus); + safestrcat(path, "/"); + safestrcat(path, SYSFS_DRIVERS_NAME); + + safestrcpy(devpath, dev->path); + c = strstr(devpath, SYSFS_DEVICES_NAME); + if (c == NULL) + return 1; + *c = '\0'; + safestrncat(c, path, (sizeof(devpath) - strlen(devpath))); + + drvlist = sysfs_open_subsystem_list(path); + if (drvlist != NULL) { + dlist_for_each_data(drvlist, drv, char) { + safestrcpy(path, devpath); + safestrcat(path, "/"); + safestrcat(path, drv); + safestrcat(path, "/"); + safestrcat(path, dev->bus_id); + if (sysfs_path_is_link(path) == 0) { + safestrcpy(dev->driver_name, drv); + sysfs_close_list(drvlist); + return 0; + } + } + sysfs_close_list(drvlist); + } + return 1; +} + /** * sysfs_get_device_bus: retrieves the bus name the device is on, checks path * to bus' link to make sure it has correct device. @@ -31,8 +82,8 @@ */ int sysfs_get_device_bus(struct sysfs_device *dev) { - unsigned char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX]; - unsigned char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL; + char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX]; + char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL; struct dlist *buslist = NULL; if (dev == NULL) { @@ -41,13 +92,12 @@ int sysfs_get_device_bus(struct sysfs_device *dev) } memset(subsys, 0, SYSFS_NAME_LEN); - strcat(subsys, "/"); - strcpy(subsys, SYSFS_BUS_NAME); /* subsys = /bus */ + safestrcpy(subsys, SYSFS_BUS_NAME); /* subsys = bus */ buslist = sysfs_open_subsystem_list(subsys); if (buslist != NULL) { dlist_for_each_data(buslist, bus, char) { memset(path, 0, SYSFS_PATH_MAX); - strcpy(path, dev->path); + safestrcpy(path, dev->path); c = strstr(path, "/devices"); if (c == NULL) { dprintf("Invalid path to device %s\n", path); @@ -55,25 +105,25 @@ int sysfs_get_device_bus(struct sysfs_device *dev) return -1; } *c = '\0'; - strcat(path, "/"); - strcat(path, SYSFS_BUS_NAME); - strcat(path, "/"); - strcat(path, bus); - strcat(path, "/"); - strcat(path, SYSFS_DEVICES_NAME); - strcat(path, "/"); - strcat(path, dev->bus_id); + safestrcat(path, "/"); + safestrcat(path, SYSFS_BUS_NAME); + safestrcat(path, "/"); + safestrcat(path, bus); + safestrcat(path, "/"); + safestrcat(path, SYSFS_DEVICES_NAME); + safestrcat(path, "/"); + safestrcat(path, dev->bus_id); if ((sysfs_path_is_link(path)) == 0) { memset(target, 0, SYSFS_PATH_MAX); if ((sysfs_get_link(path, target, - SYSFS_PATH_MAX)) != 0) { + SYSFS_PATH_MAX)) != 0) { dprintf("Error getting link target\n"); sysfs_close_list(buslist); return -1; } if (!(strncmp(target, dev->path, SYSFS_PATH_MAX))) { - strcpy(dev->bus, bus); + safestrcpy(dev->bus, bus); sysfs_close_list(buslist); return 0; } @@ -89,7 +139,7 @@ int sysfs_get_device_bus(struct sysfs_device *dev) * closing children only. * @devroot: device root of tree. */ -static void sysfs_close_device_tree(struct sysfs_device *devroot) +void sysfs_close_device_tree(struct sysfs_device *devroot) { if (devroot != NULL) { if (devroot->children != NULL) { @@ -143,7 +193,7 @@ static struct sysfs_device *alloc_device(void) * @name: name of root * returns struct sysfs_directory with success and NULL with error */ -static struct sysfs_directory *open_device_dir(const unsigned char *path) +static struct sysfs_directory *open_device_dir(const char *path) { struct sysfs_directory *rdir = NULL; @@ -172,7 +222,7 @@ static struct sysfs_directory *open_device_dir(const unsigned char *path) * @path: path to device, this is the /sys/devices/ path * returns sysfs_device structure with success or NULL with error */ -struct sysfs_device *sysfs_open_device_path(const unsigned char *path) +struct sysfs_device *sysfs_open_device_path(const char *path) { struct sysfs_device *dev = NULL; @@ -196,7 +246,7 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path) sysfs_close_device(dev); return NULL; } - strcpy(dev->path, path); + safestrcpy(dev->path, path); if ((sysfs_remove_trailing_slash(dev->path)) != 0) { dprintf("Invalid path to device %s\n", dev->path); sysfs_close_device(dev); @@ -207,10 +257,15 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path) * sysfs representation instead, in the "dev->name" field, which * implies that the dev->name and dev->bus_id contain same data. */ - strncpy(dev->name, dev->bus_id, SYSFS_NAME_LEN); + safestrcpy(dev->name, dev->bus_id); if (sysfs_get_device_bus(dev) != 0) dprintf("Could not get device bus\n"); + + if (get_dev_driver(dev) != 0) { + dprintf("Could not get device %s's driver\n", dev->bus_id); + safestrcpy(dev->driver_name, SYSFS_UNKNOWN); + } return dev; } @@ -222,7 +277,7 @@ struct sysfs_device *sysfs_open_device_path(const unsigned char *path) * returns struct sysfs_device and its children with success or NULL with * error. */ -static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path) +struct sysfs_device *sysfs_open_device_tree(const char *path) { struct sysfs_device *rootdev = NULL, *new = NULL; struct sysfs_directory *cur = NULL; @@ -255,7 +310,8 @@ static struct sysfs_device *sysfs_open_device_tree(const unsigned char *path) rootdev->children = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev_tree); - dlist_unshift(rootdev->children, new); + dlist_unshift_sorted(rootdev->children, + new, sort_list); } } @@ -311,7 +367,7 @@ struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root) root->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_dev_tree); - dlist_unshift(root->devices, dev); + dlist_unshift_sorted(root->devices, dev, sort_list); } return root->devices; @@ -323,10 +379,10 @@ struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root) * @name: name of /sys/devices/root to open * returns struct sysfs_root_device if success and NULL with error */ -struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) +struct sysfs_root_device *sysfs_open_root_device(const char *name) { struct sysfs_root_device *root = NULL; - unsigned char rootpath[SYSFS_PATH_MAX]; + char rootpath[SYSFS_PATH_MAX]; if (name == NULL) { errno = EINVAL; @@ -339,10 +395,10 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) return NULL; } - strcat(rootpath, "/"); - strcat(rootpath, SYSFS_DEVICES_NAME); - strcat(rootpath, "/"); - strcat(rootpath, name); + safestrcat(rootpath, "/"); + safestrcat(rootpath, SYSFS_DEVICES_NAME); + safestrcat(rootpath, "/"); + safestrcat(rootpath, name); if ((sysfs_path_is_dir(rootpath)) != 0) { errno = EINVAL; dprintf("Invalid root device: %s\n", name); @@ -354,8 +410,8 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) dprintf("calloc failure\n"); return NULL; } - strcpy(root->name, name); - strcpy(root->path, rootpath); + safestrcpy(root->name, name); + safestrcpy(root->path, rootpath); if ((sysfs_remove_trailing_slash(root->path)) != 0) { dprintf("Invalid path to root device %s\n", root->path); sysfs_close_root_device(root); @@ -371,8 +427,10 @@ struct sysfs_root_device *sysfs_open_root_device(const unsigned char *name) */ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) { - if (device == NULL) + if (device == NULL) { + errno = EINVAL; return NULL; + } if (device->directory == NULL) { device->directory = sysfs_open_directory(device->path); @@ -420,7 +478,7 @@ struct dlist *sysfs_refresh_device_attributes(struct sysfs_device *device) * returns sysfs_attribute reference with success or NULL with error. */ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, - const unsigned char *name) + const char *name) { struct dlist *attrlist = NULL; @@ -433,8 +491,7 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, if (attrlist == NULL) return NULL; - return sysfs_get_directory_attribute(dev->directory, - (unsigned char *)name); + return sysfs_get_directory_attribute(dev->directory, (char *)name); } /** @@ -445,10 +502,10 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, * @psize: size of "path" * Returns 0 on success -1 on failure */ -static int get_device_absolute_path(const unsigned char *device, - const unsigned char *bus, unsigned char *path, size_t psize) +static int get_device_absolute_path(const char *device, const char *bus, + char *path, size_t psize) { - unsigned char bus_path[SYSFS_PATH_MAX]; + char bus_path[SYSFS_PATH_MAX]; if (device == NULL || path == NULL) { errno = EINVAL; @@ -460,19 +517,19 @@ static int get_device_absolute_path(const unsigned char *device, dprintf ("Sysfs not supported on this system\n"); return -1; } - strcat(bus_path, "/"); - strcat(bus_path, SYSFS_BUS_NAME); - strcat(bus_path, "/"); - strcat(bus_path, bus); - strcat(bus_path, "/"); - strcat(bus_path, SYSFS_DEVICES_NAME); - strcat(bus_path, "/"); - strcat(bus_path, device); + safestrcat(bus_path, "/"); + safestrcat(bus_path, SYSFS_BUS_NAME); + safestrcat(bus_path, "/"); + safestrcat(bus_path, bus); + safestrcat(bus_path, "/"); + safestrcat(bus_path, SYSFS_DEVICES_NAME); + safestrcat(bus_path, "/"); + safestrcat(bus_path, device); /* * We now are at /sys/bus/"bus_name"/devices/"device" which is a link. * Now read this link to reach to the device. */ - if ((sysfs_get_link(bus_path, path, SYSFS_PATH_MAX)) != 0) { + if ((sysfs_get_link(bus_path, path, psize)) != 0) { dprintf("Error getting to device %s\n", device); return -1; } @@ -481,17 +538,16 @@ static int get_device_absolute_path(const unsigned char *device, /** * sysfs_open_device: open a device by id (use the "bus" subsystem) + * @bus: bus the device belongs to * @bus_id: bus_id of the device to open - has to be the "bus_id" in * /sys/bus/xxx/devices - * @bus: bus the device belongs to * returns struct sysfs_device if found, NULL otherwise * NOTE: * 1. Use sysfs_close_device to close the device * 2. Bus the device is on must be supplied * Use sysfs_find_device_bus to get the bus name */ -struct sysfs_device *sysfs_open_device(const unsigned char *bus_id, - const unsigned char *bus) +struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) { char sysfs_path[SYSFS_PATH_MAX]; struct sysfs_device *device = NULL; @@ -524,7 +580,7 @@ struct sysfs_device *sysfs_open_device(const unsigned char *bus_id, */ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) { - unsigned char ppath[SYSFS_PATH_MAX], *tmp = NULL; + char ppath[SYSFS_PATH_MAX], *tmp = NULL; if (dev == NULL) { errno = EINVAL; @@ -535,13 +591,13 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) return (dev->parent); memset(ppath, 0, SYSFS_PATH_MAX); - strcpy(ppath, dev->path); + safestrcpy(ppath, dev->path); tmp = strrchr(ppath, '/'); if (tmp == NULL) { dprintf("Invalid path to device %s\n", ppath); return NULL; } - if (*(tmp +1) == '\0') { + if (*(tmp + 1) == '\0') { *tmp = '\0'; tmp = strrchr(tmp, '/'); if (tmp == NULL) { @@ -554,7 +610,7 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) /* * All "devices" have the "detach_state" attribute - validate here */ - strcat(ppath, "/detach_state"); + safestrcat(ppath, "/detach_state"); if ((sysfs_path_is_file(ppath)) != 0) { dprintf("Device at %s does not have a parent\n", dev->path); return NULL; @@ -581,11 +637,11 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) * A call to sysfs_close_attribute() is required to close * the attribute returned and free memory. */ -struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, - const unsigned char *bus_id, const unsigned char *attrib) +struct sysfs_attribute *sysfs_open_device_attr(const char *bus, + const char *bus_id, const char *attrib) { struct sysfs_attribute *attribute = NULL; - unsigned char devpath[SYSFS_PATH_MAX]; + char devpath[SYSFS_PATH_MAX]; if (bus == NULL || bus_id == NULL || attrib == NULL) { errno = EINVAL; @@ -598,8 +654,8 @@ struct sysfs_attribute *sysfs_open_device_attr(const unsigned char *bus, dprintf("Error getting to device %s\n", bus_id); return NULL; } - strcat(devpath, "/"); - strcat(devpath, attrib); + safestrcat(devpath, "/"); + safestrcat(devpath, attrib); attribute = sysfs_open_attribute(devpath); if (attribute == NULL) { dprintf("Error opening attribute %s for device %s\n", diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index 050e674038..be54a1cf86 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -58,9 +58,9 @@ static int dir_attribute_name_equal(void *a, void *b) if (a == NULL || b == NULL) return 0; - if (strcmp(((unsigned char *)a), ((struct sysfs_attribute *)b)->name) - == 0) + if (strcmp(((char *)a), ((struct sysfs_attribute *)b)->name) == 0) return 1; + return 0; } @@ -75,9 +75,9 @@ static int dir_link_name_equal(void *a, void *b) if (a == NULL || b == NULL) return 0; - if (strcmp(((unsigned char *)a), ((struct sysfs_link *)b)->name) - == 0) + if (strcmp(((char *)a), ((struct sysfs_link *)b)->name) == 0) return 1; + return 0; } @@ -92,9 +92,9 @@ static int dir_subdir_name_equal(void *a, void *b) if (a == NULL || b == NULL) return 0; - if (strcmp(((unsigned char *)a), ((struct sysfs_directory *)b)->name) - == 0) + if (strcmp(((char *)a), ((struct sysfs_directory *)b)->name) == 0) return 1; + return 0; } @@ -126,7 +126,7 @@ static struct sysfs_attribute *alloc_attribute(void) * @path: path to attribute. * returns sysfs_attribute struct with success and NULL with error. */ -struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path) +struct sysfs_attribute *sysfs_open_attribute(const char *path) { struct sysfs_attribute *sysattr = NULL; struct stat fileinfo; @@ -140,14 +140,13 @@ struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path) dprintf("Error allocating attribute at %s\n", path); return NULL; } - if (sysfs_get_name_from_path(path, sysattr->name, SYSFS_NAME_LEN) - != 0) { - dprintf("Error retrieving attribute name from path: %s\n", - path); + if (sysfs_get_name_from_path(path, sysattr->name, + SYSFS_NAME_LEN) != 0) { + dprintf("Error retrieving attrib name from path: %s\n", path); sysfs_close_attribute(sysattr); return NULL; } - strncpy(sysattr->path, path, SYSFS_PATH_MAX); + safestrcpy(sysattr->path, path); if ((stat(sysattr->path, &fileinfo)) != 0) { dprintf("Stat failed: No such attribute?\n"); sysattr->method = 0; @@ -171,7 +170,7 @@ struct sysfs_attribute *sysfs_open_attribute(const unsigned char *path) * returns 0 with success and -1 with error. */ int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const unsigned char *new_value, size_t len) + const char *new_value, size_t len) { int fd; int length; @@ -184,6 +183,7 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, if (!(sysattr->method & SYSFS_METHOD_STORE)) { dprintf ("Store method not supported for attribute %s\n", sysattr->path); + errno = EACCES; return -1; } if (sysattr->method & SYSFS_METHOD_SHOW) { @@ -215,7 +215,7 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, sysattr->name); close(fd); return -1; - } else if (length != len) { + } else if ((unsigned int)length != len) { dprintf("Could not write %d bytes to attribute %s\n", len, sysattr->name); /* @@ -236,13 +236,13 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, */ if (sysattr->method & SYSFS_METHOD_SHOW) { if (length != sysattr->len) { - sysattr->value = (char *)realloc(sysattr->value, - length); + sysattr->value = (char *)realloc + (sysattr->value, length); sysattr->len = length; - strncpy(sysattr->value, new_value, length); + safestrncpy(sysattr->value, new_value, length); } else { /*"length" of the new value is same as old one */ - strncpy(sysattr->value, new_value, length); + safestrncpy(sysattr->value, new_value, length); } } @@ -250,7 +250,6 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, return 0; } - /** * sysfs_read_attribute: reads value from attribute * @sysattr: attribute to read @@ -258,8 +257,8 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, */ int sysfs_read_attribute(struct sysfs_attribute *sysattr) { - unsigned char *fbuf = NULL; - unsigned char *vbuf = NULL; + char *fbuf = NULL; + char *vbuf = NULL; ssize_t length = 0; long pgsize = 0; int fd; @@ -271,11 +270,11 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) if (!(sysattr->method & SYSFS_METHOD_SHOW)) { dprintf("Show method not supported for attribute %s\n", sysattr->path); + errno = EACCES; return -1; } - pgsize = getpagesize(); - fbuf = (unsigned char *)calloc(1, pgsize+1); + fbuf = (char *)calloc(1, pgsize+1); if (fbuf == NULL) { dprintf("calloc failed\n"); return -1; @@ -296,13 +295,14 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) if ((sysattr->len == length) && (!(strncmp(sysattr->value, fbuf, length)))) { close(fd); + free(fbuf); return 0; } free(sysattr->value); } sysattr->len = length; close(fd); - vbuf = (unsigned char *)realloc(fbuf, length+1); + vbuf = (char *)realloc(fbuf, length+1); if (vbuf == NULL) { dprintf("realloc failed\n"); free(fbuf); @@ -322,13 +322,13 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) * @vsize: size of value buffer * returns 0 with success and -1 with error. */ -int sysfs_read_attribute_value(const unsigned char *attrpath, - unsigned char *value, size_t vsize) +int sysfs_read_attribute_value(const char *attrpath, + char *value, size_t vsize) { struct sysfs_attribute *attr = NULL; size_t length = 0; - if (attrpath == NULL || value == NULL) { + if (attrpath == NULL || value == NULL || vsize == 0) { errno = EINVAL; return -1; } @@ -348,7 +348,7 @@ int sysfs_read_attribute_value(const unsigned char *attrpath, if (length > vsize) dprintf("Value length %d is larger than supplied buffer %d\n", length, vsize); - strncpy(value, attr->value, vsize); + safestrncpy(value, attr->value, vsize); sysfs_close_attribute(attr); return 0; @@ -359,10 +359,9 @@ int sysfs_read_attribute_value(const unsigned char *attrpath, * attribute name, return its value * @attr: attribute to search * @name: name to look for - * returns unsigned char * value - could be NULL + * returns char * value - could be NULL */ -unsigned char *sysfs_get_value_from_attributes(struct dlist *attr, - const unsigned char *name) +char *sysfs_get_value_from_attributes(struct dlist *attr, const char *name) { struct sysfs_attribute *cur = NULL; @@ -432,6 +431,7 @@ static struct sysfs_link *alloc_link(void) int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) { struct sysfs_directory *cursub = NULL; + int retval = 0; if (sysdir == NULL) { errno = EINVAL; @@ -443,12 +443,16 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) if (sysdir->subdirs != NULL) { dlist_for_each_data(sysdir->subdirs, cursub, struct sysfs_directory) { - if ((sysfs_read_dir_subdirs(cursub)) != 0) + if ((sysfs_read_dir_subdirs(cursub)) != 0) { dprintf ("Error reading subdirectory %s\n", cursub->name); + retval = -1; + } } } - return 0; + if (!retval) + errno = 0; + return retval; } /** @@ -457,7 +461,7 @@ int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) * @path: path of directory to open. * returns: struct sysfs_directory * with success and NULL on error. */ -struct sysfs_directory *sysfs_open_directory(const unsigned char *path) +struct sysfs_directory *sysfs_open_directory(const char *path) { struct sysfs_directory *sdir = NULL; @@ -467,7 +471,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path) } if (sysfs_path_is_dir(path) != 0) { - dprintf("Invalid path directory %s\n", path); + dprintf("Invalid path to directory %s\n", path); errno = EINVAL; return NULL; } @@ -482,7 +486,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path) sysfs_close_directory(sdir); return NULL; } - strncpy(sdir->path, path, SYSFS_PATH_MAX); + safestrcpy(sdir->path, path); return sdir; } @@ -492,7 +496,7 @@ struct sysfs_directory *sysfs_open_directory(const unsigned char *path) * @path: path of link to open. * returns: struct sysfs_link * with success and NULL on error. */ -struct sysfs_link *sysfs_open_link(const unsigned char *linkpath) +struct sysfs_link *sysfs_open_link(const char *linkpath) { struct sysfs_link *ln = NULL; @@ -506,7 +510,7 @@ struct sysfs_link *sysfs_open_link(const unsigned char *linkpath) dprintf("Error allocating link %s\n", linkpath); return NULL; } - strcpy(ln->path, linkpath); + safestrcpy(ln->path, linkpath); if ((sysfs_get_name_from_path(linkpath, ln->name, SYSFS_NAME_LEN)) != 0 || (sysfs_get_link(linkpath, ln->target, SYSFS_PATH_MAX)) != 0) { errno = EINVAL; @@ -523,8 +527,7 @@ struct sysfs_link *sysfs_open_link(const unsigned char *linkpath) * @path: path to attribute * returns 0 with success and -1 with error. */ -static int add_attribute(struct sysfs_directory *sysdir, - const unsigned char *path) +static int add_attribute(struct sysfs_directory *sysdir, const char *path) { struct sysfs_attribute *attr = NULL; @@ -545,7 +548,7 @@ static int add_attribute(struct sysfs_directory *sysdir, sysdir->attributes = dlist_new_with_delete (sizeof(struct sysfs_attribute), sysfs_del_attribute); } - dlist_unshift(sysdir->attributes, attr); + dlist_unshift_sorted(sysdir->attributes, attr, sort_list); return 0; } @@ -556,8 +559,7 @@ static int add_attribute(struct sysfs_directory *sysdir, * @path: path to subdirectory * returns 0 with success and -1 with error. */ -static int add_subdirectory(struct sysfs_directory *sysdir, - const unsigned char *path) +static int add_subdirectory(struct sysfs_directory *sysdir, const char *path) { struct sysfs_directory *subdir = NULL; @@ -569,7 +571,7 @@ static int add_subdirectory(struct sysfs_directory *sysdir, if (sysdir->subdirs == NULL) sysdir->subdirs = dlist_new_with_delete (sizeof(struct sysfs_directory), sysfs_del_directory); - dlist_unshift(sysdir->subdirs, subdir); + dlist_unshift_sorted(sysdir->subdirs, subdir, sort_list); return 0; } @@ -579,7 +581,7 @@ static int add_subdirectory(struct sysfs_directory *sysdir, * @path: path to link * returns 0 with success and -1 with error. */ -static int add_link(struct sysfs_directory *sysdir, const unsigned char *path) +static int add_link(struct sysfs_directory *sysdir, const char *path) { struct sysfs_link *ln = NULL; @@ -591,7 +593,7 @@ static int add_link(struct sysfs_directory *sysdir, const unsigned char *path) if (sysdir->links == NULL) sysdir->links = dlist_new_with_delete (sizeof(struct sysfs_link), sysfs_del_link); - dlist_unshift(sysdir->links, ln); + dlist_unshift_sorted(sysdir->links, ln, sort_list); return 0; } @@ -604,7 +606,7 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir) { DIR *dir = NULL; struct dirent *dirent = NULL; - unsigned char file_path[SYSFS_PATH_MAX]; + char file_path[SYSFS_PATH_MAX]; int retval = 0; if (sysdir == NULL) { @@ -622,13 +624,15 @@ int sysfs_read_dir_attributes(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); - strcat(file_path, "/"); - strcat(file_path, dirent->d_name); + safestrcpy(file_path, sysdir->path); + safestrcat(file_path, "/"); + safestrcat(file_path, dirent->d_name); if ((sysfs_path_is_file(file_path)) == 0) retval = add_attribute(sysdir, file_path); } closedir(dir); + if (!retval) + errno = 0; return(retval); } @@ -641,7 +645,7 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir) { DIR *dir = NULL; struct dirent *dirent = NULL; - unsigned char file_path[SYSFS_PATH_MAX]; + char file_path[SYSFS_PATH_MAX]; int retval = 0; if (sysdir == NULL) { @@ -659,9 +663,9 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); - strcat(file_path, "/"); - strcat(file_path, dirent->d_name); + safestrcpy(file_path, sysdir->path); + safestrcat(file_path, "/"); + safestrcat(file_path, dirent->d_name); if ((sysfs_path_is_link(file_path)) == 0) { retval = add_link(sysdir, file_path); if (retval != 0) @@ -669,6 +673,8 @@ int sysfs_read_dir_links(struct sysfs_directory *sysdir) } } closedir(dir); + if (!retval) + errno = 0; return(retval); } @@ -681,7 +687,7 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir) { DIR *dir = NULL; struct dirent *dirent = NULL; - unsigned char file_path[SYSFS_PATH_MAX]; + char file_path[SYSFS_PATH_MAX]; int retval = 0; if (sysdir == NULL) { @@ -699,13 +705,15 @@ int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); - strcat(file_path, "/"); - strcat(file_path, dirent->d_name); + safestrcpy(file_path, sysdir->path); + safestrcat(file_path, "/"); + safestrcat(file_path, dirent->d_name); if ((sysfs_path_is_dir(file_path)) == 0) retval = add_subdirectory(sysdir, file_path); } closedir(dir); + if (!retval) + errno = 0; return(retval); } @@ -719,7 +727,7 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) DIR *dir = NULL; struct dirent *dirent = NULL; struct stat astats; - unsigned char file_path[SYSFS_PATH_MAX]; + char file_path[SYSFS_PATH_MAX]; int retval = 0; if (sysdir == NULL) { @@ -737,9 +745,9 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) if (0 == strcmp(dirent->d_name, "..")) continue; memset(file_path, 0, SYSFS_PATH_MAX); - strncpy(file_path, sysdir->path, SYSFS_PATH_MAX); - strcat(file_path, "/"); - strcat(file_path, dirent->d_name); + safestrcpy(file_path, sysdir->path); + safestrcat(file_path, "/"); + safestrcat(file_path, dirent->d_name); if ((lstat(file_path, &astats)) != 0) { dprintf("stat failed\n"); continue; @@ -754,6 +762,8 @@ int sysfs_read_directory(struct sysfs_directory *sysdir) retval = add_attribute(sysdir, file_path); } closedir(dir); + if (!retval) + errno = 0; return(retval); } @@ -782,6 +792,7 @@ int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir) sysdir->path); return 1; } + errno = 0; return 0; } @@ -810,6 +821,7 @@ int sysfs_refresh_dir_links(struct sysfs_directory *sysdir) sysdir->path); return 1; } + errno = 0; return 0; } @@ -838,6 +850,7 @@ int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir) sysdir->path); return 1; } + errno = 0; return 0; } @@ -846,13 +859,17 @@ int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir) * directory only * @dir: directory to retrieve attribute from * @attrname: name of attribute to look for + * + * NOTE: Since we know the attribute to look for, this routine looks for the + * attribute if it was created _after_ the attrlist was read initially. + * * returns sysfs_attribute if found and NULL if not found */ struct sysfs_attribute *sysfs_get_directory_attribute - (struct sysfs_directory *dir, unsigned char *attrname) + (struct sysfs_directory *dir, char *attrname) { struct sysfs_attribute *attr = NULL; - unsigned char new_path[SYSFS_PATH_MAX]; + char new_path[SYSFS_PATH_MAX]; if (dir == NULL || attrname == NULL) { errno = EINVAL; @@ -873,9 +890,9 @@ struct sysfs_attribute *sysfs_get_directory_attribute } } else { memset(new_path, 0, SYSFS_PATH_MAX); - strcpy(new_path, dir->path); - strcat(new_path, "/"); - strcat(new_path, attrname); + safestrcpy(new_path, dir->path); + safestrcat(new_path, "/"); + safestrcat(new_path, attrname); if ((sysfs_path_is_file(new_path)) == 0) { if ((add_attribute(dir, new_path)) == 0) { attr = (struct sysfs_attribute *) @@ -895,7 +912,7 @@ struct sysfs_attribute *sysfs_get_directory_attribute * returns reference to sysfs_link if found and NULL if not found */ struct sysfs_link *sysfs_get_directory_link - (struct sysfs_directory *dir, unsigned char *linkname) + (struct sysfs_directory *dir, char *linkname) { if (dir == NULL || linkname == NULL) { errno = EINVAL; @@ -920,7 +937,7 @@ struct sysfs_link *sysfs_get_directory_link * returns reference to subdirectory or NULL if not found */ struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir, - unsigned char *subname) + char *subname) { struct sysfs_directory *sub = NULL, *cursub = NULL; @@ -962,7 +979,7 @@ struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir, * returns reference to link or NULL if not found */ struct sysfs_link *sysfs_get_subdirectory_link(struct sysfs_directory *dir, - unsigned char *linkname) + char *linkname) { struct sysfs_directory *cursub = NULL; struct sysfs_link *ln = NULL; diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index cd202d9f23..9ffa9c9077 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -79,7 +79,7 @@ static struct sysfs_driver *alloc_driver(void) * @path: path to driver directory * returns struct sysfs_driver with success and NULL with error */ -struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path) +struct sysfs_driver *sysfs_open_driver_path(const char *path) { struct sysfs_driver *driver = NULL; @@ -102,7 +102,7 @@ struct sysfs_driver *sysfs_open_driver_path(const unsigned char *path) free(driver); return NULL; } - strcpy(driver->path, path); + safestrcpy(driver->path, path); if ((sysfs_remove_trailing_slash(driver->path)) != 0) { dprintf("Invalid path to driver %s\n", driver->path); sysfs_close_driver(driver); @@ -168,7 +168,7 @@ struct dlist *sysfs_refresh_driver_attributes(struct sysfs_driver *driver) * returns sysfs_attribute reference on success or NULL with error */ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, - const unsigned char *name) + const char *name) { struct dlist *attrlist = NULL; @@ -178,11 +178,10 @@ struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, } attrlist = sysfs_get_driver_attributes(drv); - if (attrlist != NULL) + if (attrlist == NULL) return NULL; - return sysfs_get_directory_attribute(drv->directory, - (unsigned char *)name); + return sysfs_get_directory_attribute(drv->directory, (char *)name); } /** @@ -197,12 +196,15 @@ struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) errno = EINVAL; return NULL; } - if (driver->directory == NULL) { + + if (driver->directory == NULL) if ((open_driver_dir(driver)) == 1) return NULL; + + if (driver->directory->links == NULL) if ((sysfs_read_dir_links(driver->directory)) != 0) return NULL; - } + return(driver->directory->links); } @@ -224,12 +226,11 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) if (driver->devices != NULL) return (driver->devices); - if (driver->directory == NULL) { - if ((open_driver_dir(driver)) == 1) - return NULL; - if ((sysfs_read_dir_links(driver->directory)) != 0) - return NULL; + if (driver->directory == NULL || driver->directory->links == NULL) { + struct dlist *list = NULL; + list = sysfs_get_driver_links(driver); } + if (driver->directory->links != NULL) { dlist_for_each_data(driver->directory->links, curlink, struct sysfs_link) { @@ -239,12 +240,12 @@ struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) curlink->target); return NULL; } - strcpy(device->driver_name, driver->name); if (driver->devices == NULL) driver->devices = dlist_new_with_delete (sizeof(struct sysfs_device), sysfs_close_driver_device); - dlist_unshift(driver->devices, device); + dlist_unshift_sorted(driver->devices, device, + sort_list); } } return (driver->devices); @@ -290,7 +291,7 @@ struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver) * Returns a sysfs_device if found, NULL otherwise */ struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver, - const unsigned char *name) + const char *name) { struct sysfs_device *device = NULL; struct dlist *devlist = NULL; @@ -323,10 +324,10 @@ struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver, * @psize: size of "path" * Returns 0 on success and -1 on error */ -static int get_driver_path(const unsigned char *bus, - const unsigned char *drv, unsigned char *path, size_t psize) +static int get_driver_path(const char *bus, const char *drv, + char *path, size_t psize) { - if (bus == NULL || drv == NULL || path == NULL) { + if (bus == NULL || drv == NULL || path == NULL || psize == 0) { errno = EINVAL; return -1; } @@ -334,14 +335,14 @@ static int get_driver_path(const unsigned char *bus, dprintf("Error getting sysfs mount path\n"); return -1; } - strcat(path, "/"); - strcat(path, SYSFS_BUS_NAME); - strcat(path, "/"); - strcat(path, bus); - strcat(path, "/"); - strcat(path, SYSFS_DRIVERS_NAME); - strcat(path, "/"); - strcat(path, drv); + safestrncat(path, "/", psize); + safestrncat(path, SYSFS_BUS_NAME, psize); + safestrncat(path, "/", psize); + safestrncat(path, bus, psize); + safestrncat(path, "/", psize); + safestrncat(path, SYSFS_DRIVERS_NAME, psize); + safestrncat(path, "/", psize); + safestrncat(path, drv, psize); return 0; } @@ -356,11 +357,11 @@ static int get_driver_path(const unsigned char *bus, * A call to sysfs_close_attribute() is required to close the * attribute returned and to free memory */ -struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, - const unsigned char *drv, const unsigned char *attrib) +struct sysfs_attribute *sysfs_open_driver_attr(const char *bus, + const char *drv, const char *attrib) { struct sysfs_attribute *attribute = NULL; - unsigned char path[SYSFS_PATH_MAX]; + char path[SYSFS_PATH_MAX]; if (bus == NULL || drv == NULL || attrib == NULL) { errno = EINVAL; @@ -372,8 +373,8 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, dprintf("Error getting to driver %s\n", drv); return NULL; } - strcat(path, "/"); - strcat(path, attrib); + safestrcat(path, "/"); + safestrcat(path, attrib); attribute = sysfs_open_attribute(path); if (attribute == NULL) { dprintf("Error opening attribute %s for driver %s\n", @@ -391,14 +392,14 @@ struct sysfs_attribute *sysfs_open_driver_attr(const unsigned char *bus, /** * sysfs_open_driver: open driver by name, given its bus - * @drv_name: Name of the driver * @bus_name: Name of the bus + * @drv_name: Name of the driver * Returns the sysfs_driver reference on success and NULL on failure */ -struct sysfs_driver *sysfs_open_driver(const unsigned char *drv_name, - const unsigned char *bus_name) +struct sysfs_driver *sysfs_open_driver(const char *bus_name, + const char *drv_name) { - unsigned char path[SYSFS_PATH_MAX]; + char path[SYSFS_PATH_MAX]; struct sysfs_driver *driver = NULL; if (drv_name == NULL || bus_name == NULL) { diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 2509c73c98..699a9829b8 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -26,14 +26,20 @@ #include #endif +static int sort_char(void *new_elem, void *old_elem) +{ + return ((strncmp((char *)new_elem, (char *)old_elem, + strlen((char *)new_elem))) < 0 ? 1 : 0); +} + /** * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path * @path: Path to look for the trailing '/' * Returns 0 on success 1 on error */ -int sysfs_remove_trailing_slash(unsigned char *path) +int sysfs_remove_trailing_slash(char *path) { - unsigned char *c = NULL; + char *c = NULL; if (path == NULL) { errno = EINVAL; @@ -51,17 +57,17 @@ int sysfs_remove_trailing_slash(unsigned char *path) } /** - * sysfs_get_mnt_path: Gets the mount point for specified filesystem. + * sysfs_get_fs_mnt_path: Gets the mount point for specified filesystem. * @fs_type: filesystem type to retrieve mount point * @mnt_path: place to put the retrieved mount path * @len: size of mnt_path * returns 0 with success and -1 with error. */ -static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, - unsigned char *mnt_path, size_t len) +static int sysfs_get_fs_mnt_path(const char *fs_type, + char *mnt_path, size_t len) { #ifdef __KLIBC__ - strcpy(mnt_path, "/sys"); + safestrncpy(mnt_path, "/sys", len); return 0; #else FILE *mnt; @@ -70,7 +76,7 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, size_t dirlen = 0; /* check arg */ - if (fs_type == NULL || mnt_path == NULL) { + if (fs_type == NULL || mnt_path == NULL || len == 0) { errno = EINVAL; return -1; } @@ -83,7 +89,7 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, if (strcmp(mntent->mnt_type, fs_type) == 0) { dirlen = strlen(mntent->mnt_dir); if (dirlen <= (len - 1)) { - strcpy(mnt_path, mntent->mnt_dir); + safestrncpy(mnt_path, mntent->mnt_dir, len); } else { dprintf("Error - mount path too long\n"); ret = -1; @@ -109,18 +115,18 @@ static int sysfs_get_fs_mnt_path(const unsigned char *fs_type, * @len: size of mnt_path * returns 0 with success and -1 with error. */ -int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) +int sysfs_get_mnt_path(char *mnt_path, size_t len) { char *sysfs_path = NULL; int ret = 0; - if (mnt_path == NULL) { + if (mnt_path == NULL || len == 0) { errno = EINVAL; return -1; } sysfs_path = getenv(SYSFS_PATH_ENV); if (sysfs_path != NULL) { - strncpy(mnt_path, sysfs_path, len); + safestrncpy(mnt_path, sysfs_path, len); if ((sysfs_remove_trailing_slash(mnt_path)) != 0) return 1; } else @@ -135,18 +141,17 @@ int sysfs_get_mnt_path(unsigned char *mnt_path, size_t len) * @name: where to put name * @len: size of name */ -int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, - size_t len) +int sysfs_get_name_from_path(const char *path, char *name, size_t len) { - unsigned char tmp[SYSFS_PATH_MAX]; - unsigned char *n = NULL; + char tmp[SYSFS_PATH_MAX]; + char *n = NULL; - if (path == NULL || name == NULL) { + if (path == NULL || name == NULL || len == 0) { errno = EINVAL; return -1; } memset(tmp, 0, SYSFS_PATH_MAX); - strcpy(tmp, path); + safestrcpy(tmp, path); n = strrchr(tmp, '/'); if (n == NULL) { errno = EINVAL; @@ -161,7 +166,7 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, } } n++; - strncpy(name, n, len); + safestrncpy(name, n, len); return 0; } @@ -171,21 +176,23 @@ int sysfs_get_name_from_path(const unsigned char *path, unsigned char *name, * @target: where to put name * @len: size of name */ -int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) +int sysfs_get_link(const char *path, char *target, size_t len) { - unsigned char devdir[SYSFS_PATH_MAX]; - unsigned char linkpath[SYSFS_PATH_MAX]; - unsigned char *d = NULL, *s = NULL; + char devdir[SYSFS_PATH_MAX]; + char linkpath[SYSFS_PATH_MAX]; + char temp_path[SYSFS_PATH_MAX]; + char *d = NULL, *s = NULL; int slashes = 0, count = 0; - if (path == NULL || target == NULL) { + if (path == NULL || target == NULL || len == 0) { errno = EINVAL; return -1; } memset(devdir, 0, SYSFS_PATH_MAX); memset(linkpath, 0, SYSFS_PATH_MAX); - strncpy(devdir, path, SYSFS_PATH_MAX); + memset(temp_path, 0, SYSFS_PATH_MAX); + safestrcpy(devdir, path); if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) { return -1; @@ -202,18 +209,19 @@ int sysfs_get_link(const unsigned char *path, unsigned char *target, size_t len) /* * handle the case where link is of type ./abcd/xxx */ - strncpy(target, devdir, len); + safestrcpy(temp_path, devdir); if (*(d+1) == '/') d += 2; else if (*(d+1) == '.') goto parse_path; - s = strrchr(target, '/'); + s = strrchr(temp_path, '/'); if (s != NULL) { *(s+1) = '\0'; - strcat(target, d); + safestrcat(temp_path, d); } else { - strcpy(target, d); + safestrcpy(temp_path, d); } + safestrncpy(target, temp_path, len); break; /* * relative path @@ -232,23 +240,24 @@ parse_path: if (*s == '/') count++; } - strncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir))); - strncpy(target, devdir, len); + safestrncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir))); + safestrncpy(target, devdir, len); break; case '/': /* absolute path - copy as is */ - strncpy(target, linkpath, len); + safestrncpy(target, linkpath, len); break; default: /* relative path from this directory */ - strncpy(target, devdir, len); - s = strrchr(target, '/'); + safestrcpy(temp_path, devdir); + s = strrchr(temp_path, '/'); if (s != NULL) { *(s+1) = '\0'; - strcat(target, linkpath); + safestrcat(temp_path, linkpath); } else { - strcpy(target, linkpath); - } + safestrcpy(temp_path, linkpath); + } + safestrncpy(target, temp_path, len); } return 0; } @@ -280,10 +289,10 @@ void sysfs_close_list(struct dlist *list) * @name: name of the subsystem, eg., "bus", "class", "devices" * Returns a dlist of supported names or NULL if subsystem not supported */ -struct dlist *sysfs_open_subsystem_list(unsigned char *name) +struct dlist *sysfs_open_subsystem_list(char *name) { - unsigned char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL; - unsigned char *c = NULL; + char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL; + char *c = NULL; struct sysfs_directory *dir = NULL, *cur = NULL; struct dlist *list = NULL; @@ -295,8 +304,8 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) return NULL; } - strcat(sysfs_path, "/"); - strcat(sysfs_path, name); + safestrcat(sysfs_path, "/"); + safestrcat(sysfs_path, name); dir = sysfs_open_directory(sysfs_path); if (dir == NULL) { dprintf("Error opening sysfs_directory at %s\n", sysfs_path); @@ -321,8 +330,8 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) dlist_for_each_data(dir->subdirs, cur, struct sysfs_directory) { subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); - strcpy(subsys_name, cur->name); - dlist_unshift(list, subsys_name); + safestrncpy(subsys_name, cur->name, SYSFS_NAME_LEN); + dlist_unshift_sorted(list, subsys_name, sort_char); } } sysfs_close_directory(dir); @@ -335,11 +344,14 @@ struct dlist *sysfs_open_subsystem_list(unsigned char *name) c = strstr(sysfs_path, SYSFS_CLASS_NAME); if (c == NULL) goto out; - strcpy(c, SYSFS_BLOCK_NAME); + *c = '\0'; + safestrncpy(c, SYSFS_BLOCK_NAME, + sizeof(sysfs_path) - strlen(sysfs_path)); if ((sysfs_path_is_dir(sysfs_path)) == 0) { subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); - strcpy(subsys_name, SYSFS_BLOCK_NAME); - dlist_unshift(list, subsys_name); + safestrncpy(subsys_name, SYSFS_BLOCK_NAME, + SYSFS_NAME_LEN); + dlist_unshift_sorted(list, subsys_name, sort_char); } } out: @@ -352,9 +364,9 @@ out: * @name: name of the subsystem, eg., "pci", "scsi", "usb" * Returns a dlist of supported names or NULL if subsystem not supported */ -struct dlist *sysfs_open_bus_devices_list(unsigned char *name) +struct dlist *sysfs_open_bus_devices_list(char *name) { - unsigned char sysfs_path[SYSFS_PATH_MAX], *device_name = NULL; + char sysfs_path[SYSFS_PATH_MAX], *device_name = NULL; struct sysfs_directory *dir = NULL; struct sysfs_link *cur = NULL; struct dlist *list = NULL; @@ -367,12 +379,12 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) return NULL; } - strcat(sysfs_path, "/"); - strcat(sysfs_path, SYSFS_BUS_NAME); - strcat(sysfs_path, "/"); - strcat(sysfs_path, name); - strcat(sysfs_path, "/"); - strcat(sysfs_path, SYSFS_DEVICES_NAME); + safestrcat(sysfs_path, "/"); + safestrcat(sysfs_path, SYSFS_BUS_NAME); + safestrcat(sysfs_path, "/"); + safestrcat(sysfs_path, name); + safestrcat(sysfs_path, "/"); + safestrcat(sysfs_path, SYSFS_DEVICES_NAME); dir = sysfs_open_directory(sysfs_path); if (dir == NULL) { dprintf("Error opening sysfs_directory at %s\n", sysfs_path); @@ -397,8 +409,8 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) dlist_for_each_data(dir->links, cur, struct sysfs_link) { device_name = (char *)calloc(1, SYSFS_NAME_LEN); - strcpy(device_name, cur->name); - dlist_unshift(list, device_name); + safestrncpy(device_name, cur->name, SYSFS_NAME_LEN); + dlist_unshift_sorted(list, device_name, sort_char); } } sysfs_close_directory(dir); @@ -410,7 +422,7 @@ struct dlist *sysfs_open_bus_devices_list(unsigned char *name) * @path: path to validate * Returns 0 if path points to dir, 1 otherwise */ -int sysfs_path_is_dir(const unsigned char *path) +int sysfs_path_is_dir(const char *path) { struct stat astats; @@ -433,7 +445,7 @@ int sysfs_path_is_dir(const unsigned char *path) * @path: path to validate * Returns 0 if path points to link, 1 otherwise */ -int sysfs_path_is_link(const unsigned char *path) +int sysfs_path_is_link(const char *path) { struct stat astats; @@ -456,7 +468,7 @@ int sysfs_path_is_link(const unsigned char *path) * @path: path to validate * Returns 0 if path points to file, 1 otherwise */ -int sysfs_path_is_file(const unsigned char *path) +int sysfs_path_is_file(const char *path) { struct stat astats; From 656703759d7d3eac6e8c86f1121cde7dfd6d8cbd Mon Sep 17 00:00:00 2001 From: "ananth@in.ibm.com" Date: Fri, 12 Mar 2004 00:57:36 -0800 Subject: [PATCH 0653/4284] [PATCH] more Libsysfs updates On Thu, Mar 11, 2004 at 02:36:23PM +0100, Kay Sievers wrote: > On Thu, 2004-03-11 at 15:02, Ananth N Mavinakayanahalli wrote: > > On Thu, Mar 11, 2004 at 02:04:36PM +0100, Kay Sievers wrote: > > > On Thu, Mar 11, 2004 at 11:53:50AM +0500, Ananth N Mavinakayanahalli wrote: > > > > > > > +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) > > > > +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) > > > > > > These strings are not terminated with '\0' if from is longer than > > > the sizeof to. > > > > Did not do it on purpose as the "to" elements are either calloc'd or memset to > > '0' explicitly in the library. Thats the reason I mentioned "scaled down" :) > > Ahh, sounds good. > > > > > +#define safestrncpy(to, from, maxsize) \ > > > > +do { \ > > > > + to[maxsize-1] = '\0'; \ > > > > + strncpy(to, from, maxsize-1); \ > > > > +} while (0) > > > > + > > > > +#define safestrncat(to, from, maxsize) \ > > > > +do { \ > > > > + to[maxsize-1] = '\0'; \ > > > > + strncat(to, from, maxsize - strlen(to)-1); \ > > > > +} while (0) > > > > > > We all expect a similar behavior like strncat/strncpy according to the > > > names, but these macros are limiting by the target size and do not limit > > > the count of chars copied. > > > This is confusing I think and suggest using a different name like > > > 'safestrcopymax()' or something. > > > > Good point.. will make the change > > Nice. I've had these *n* names too and I forgot about the logic and only > 10 days later I introduced a ugly bug cause I can't limit the count of > copied chars :) Inlined is the patch for this... applies on the earlier _BIG_ patch. --- libsysfs/sysfs/libsysfs.h | 12 ++++++------ libsysfs/sysfs_bus.c | 2 +- libsysfs/sysfs_class.c | 16 ++++++++-------- libsysfs/sysfs_device.c | 2 +- libsysfs/sysfs_dir.c | 6 +++--- libsysfs/sysfs_driver.c | 16 ++++++++-------- libsysfs/sysfs_utils.c | 26 +++++++++++++------------- 7 files changed, 40 insertions(+), 40 deletions(-) diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index cbde2f5783..11cffae045 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -32,16 +32,16 @@ #define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) #define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) -#define safestrncpy(to, from, maxsize) \ +#define safestrcpymax(to, from, max) \ do { \ - to[maxsize-1] = '\0'; \ - strncpy(to, from, maxsize-1); \ + to[max-1] = '\0'; \ + strncpy(to, from, max-1); \ } while (0) -#define safestrncat(to, from, maxsize) \ +#define safestrcatmax(to, from, max) \ do { \ - to[maxsize-1] = '\0'; \ - strncat(to, from, maxsize - strlen(to)-1); \ + to[max-1] = '\0'; \ + strncat(to, from, max - strlen(to)-1); \ } while (0) /* diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index bff7f78f05..9ca23c85d8 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -384,7 +384,7 @@ int sysfs_find_driver_bus(const char *driver, char *busname, size_t bsize) if (drivers != NULL) { dlist_for_each_data(drivers, curdrv, char) { if (strcmp(driver, curdrv) == 0) { - safestrncpy(busname, + safestrcpymax(busname, bus, bsize); sysfs_close_list(drivers); sysfs_close_list(buslist); diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 7a696355ca..59ef0be48e 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -509,16 +509,16 @@ static int get_classdev_path(const char *classname, const char *clsdev, } if (strncmp(classname, SYSFS_BLOCK_NAME, sizeof(SYSFS_BLOCK_NAME)) == 0) { - safestrncat(path, "/", len); - safestrncat(path, SYSFS_BLOCK_NAME, len); + safestrcatmax(path, "/", len); + safestrcatmax(path, SYSFS_BLOCK_NAME, len); } else { - safestrncat(path, "/", len); - safestrncat(path, SYSFS_CLASS_NAME, len); - safestrncat(path, "/", len); - safestrncat(path, classname, len); + safestrcatmax(path, "/", len); + safestrcatmax(path, SYSFS_CLASS_NAME, len); + safestrcatmax(path, "/", len); + safestrcatmax(path, classname, len); } - safestrncat(path, "/", len); - safestrncat(path, clsdev, len); + safestrcatmax(path, "/", len); + safestrcatmax(path, clsdev, len); return 0; } diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index e3a8977016..290fd9723e 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -53,7 +53,7 @@ static int get_dev_driver(struct sysfs_device *dev) if (c == NULL) return 1; *c = '\0'; - safestrncat(c, path, (sizeof(devpath) - strlen(devpath))); + safestrcatmax(c, path, (sizeof(devpath) - strlen(devpath))); drvlist = sysfs_open_subsystem_list(path); if (drvlist != NULL) { diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index be54a1cf86..8ce8522200 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -239,10 +239,10 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, sysattr->value = (char *)realloc (sysattr->value, length); sysattr->len = length; - safestrncpy(sysattr->value, new_value, length); + safestrcpymax(sysattr->value, new_value, length); } else { /*"length" of the new value is same as old one */ - safestrncpy(sysattr->value, new_value, length); + safestrcpymax(sysattr->value, new_value, length); } } @@ -348,7 +348,7 @@ int sysfs_read_attribute_value(const char *attrpath, if (length > vsize) dprintf("Value length %d is larger than supplied buffer %d\n", length, vsize); - safestrncpy(value, attr->value, vsize); + safestrcpymax(value, attr->value, vsize); sysfs_close_attribute(attr); return 0; diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 9ffa9c9077..2439b7a567 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -335,14 +335,14 @@ static int get_driver_path(const char *bus, const char *drv, dprintf("Error getting sysfs mount path\n"); return -1; } - safestrncat(path, "/", psize); - safestrncat(path, SYSFS_BUS_NAME, psize); - safestrncat(path, "/", psize); - safestrncat(path, bus, psize); - safestrncat(path, "/", psize); - safestrncat(path, SYSFS_DRIVERS_NAME, psize); - safestrncat(path, "/", psize); - safestrncat(path, drv, psize); + safestrcatmax(path, "/", psize); + safestrcatmax(path, SYSFS_BUS_NAME, psize); + safestrcatmax(path, "/", psize); + safestrcatmax(path, bus, psize); + safestrcatmax(path, "/", psize); + safestrcatmax(path, SYSFS_DRIVERS_NAME, psize); + safestrcatmax(path, "/", psize); + safestrcatmax(path, drv, psize); return 0; } diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 699a9829b8..492c7fa668 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -67,7 +67,7 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, size_t len) { #ifdef __KLIBC__ - safestrncpy(mnt_path, "/sys", len); + safestrcpymax(mnt_path, "/sys", len); return 0; #else FILE *mnt; @@ -89,7 +89,7 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, if (strcmp(mntent->mnt_type, fs_type) == 0) { dirlen = strlen(mntent->mnt_dir); if (dirlen <= (len - 1)) { - safestrncpy(mnt_path, mntent->mnt_dir, len); + safestrcpymax(mnt_path, mntent->mnt_dir, len); } else { dprintf("Error - mount path too long\n"); ret = -1; @@ -126,7 +126,7 @@ int sysfs_get_mnt_path(char *mnt_path, size_t len) } sysfs_path = getenv(SYSFS_PATH_ENV); if (sysfs_path != NULL) { - safestrncpy(mnt_path, sysfs_path, len); + safestrcpymax(mnt_path, sysfs_path, len); if ((sysfs_remove_trailing_slash(mnt_path)) != 0) return 1; } else @@ -166,7 +166,7 @@ int sysfs_get_name_from_path(const char *path, char *name, size_t len) } } n++; - safestrncpy(name, n, len); + safestrcpymax(name, n, len); return 0; } @@ -221,7 +221,7 @@ int sysfs_get_link(const char *path, char *target, size_t len) } else { safestrcpy(temp_path, d); } - safestrncpy(target, temp_path, len); + safestrcpymax(target, temp_path, len); break; /* * relative path @@ -240,12 +240,12 @@ parse_path: if (*s == '/') count++; } - safestrncpy(s, d, (SYSFS_PATH_MAX-strlen(devdir))); - safestrncpy(target, devdir, len); + safestrcpymax(s, d, (SYSFS_PATH_MAX-strlen(devdir))); + safestrcpymax(target, devdir, len); break; case '/': /* absolute path - copy as is */ - safestrncpy(target, linkpath, len); + safestrcpymax(target, linkpath, len); break; default: /* relative path from this directory */ @@ -257,7 +257,7 @@ parse_path: } else { safestrcpy(temp_path, linkpath); } - safestrncpy(target, temp_path, len); + safestrcpymax(target, temp_path, len); } return 0; } @@ -330,7 +330,7 @@ struct dlist *sysfs_open_subsystem_list(char *name) dlist_for_each_data(dir->subdirs, cur, struct sysfs_directory) { subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); - safestrncpy(subsys_name, cur->name, SYSFS_NAME_LEN); + safestrcpymax(subsys_name, cur->name, SYSFS_NAME_LEN); dlist_unshift_sorted(list, subsys_name, sort_char); } } @@ -345,11 +345,11 @@ struct dlist *sysfs_open_subsystem_list(char *name) if (c == NULL) goto out; *c = '\0'; - safestrncpy(c, SYSFS_BLOCK_NAME, + safestrcpymax(c, SYSFS_BLOCK_NAME, sizeof(sysfs_path) - strlen(sysfs_path)); if ((sysfs_path_is_dir(sysfs_path)) == 0) { subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); - safestrncpy(subsys_name, SYSFS_BLOCK_NAME, + safestrcpymax(subsys_name, SYSFS_BLOCK_NAME, SYSFS_NAME_LEN); dlist_unshift_sorted(list, subsys_name, sort_char); } @@ -409,7 +409,7 @@ struct dlist *sysfs_open_bus_devices_list(char *name) dlist_for_each_data(dir->links, cur, struct sysfs_link) { device_name = (char *)calloc(1, SYSFS_NAME_LEN); - safestrncpy(device_name, cur->name, SYSFS_NAME_LEN); + safestrcpymax(device_name, cur->name, SYSFS_NAME_LEN); dlist_unshift_sorted(list, device_name, sort_char); } } From c612a0acc8c45303b5c40538b87e406ac22a26ef Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Mar 2004 00:58:33 -0800 Subject: [PATCH 0654/4284] [PATCH] add permission tests > Any chance on being able to add a test for this kind of stuff to the > udev-test.pl script? Sure, not brilliant but seems to work :) Only numeric id's are supported so far. --- test/udev-test.pl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index c12a21ee3d..e345b20c58 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -522,6 +522,16 @@ EOF BUS="scsi", KERNEL="sda", SYMLINK="symlink-only1" BUS="scsi", KERNEL="sda", SYMLINK="symlink-only2" BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="symlink0" +EOF + }, + { + desc => "permissions test", + subsys => "block", + devpath => "block/sda", + expected => "node", + perms => "5000::0444", + conf => <{subsys}, $config->{devpath}, \$config->{conf}); if (-e "$PWD/$udev_root$config->{expected}") { + if (defined($config->{perms})) { + my $wrong = 0; + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, + $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$config->{expected}"); + + $config->{perms} =~ m/^(.*):(.*):(.*)$/; + if ($1 ne "") { + if ($uid != $1) { $wrong = 1; }; + } + if ($2 ne "") { + if ($gid != $2) { $wrong = 1; }; + } + if ($3 ne "") { + if (($mode & 07777) != oct($3)) { $wrong = 1; }; + } + if ($wrong == 1) { + printf "expected permissions are: %i:%i:%#o\n", $1, $2, oct($3); + printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; + } + } print "add: ok "; } else { print "add: error\n"; From 0c17d02da29a4c41186caabb3f7ff488e0f6c9ea Mon Sep 17 00:00:00 2001 From: "ken@cgi101.com" Date: Fri, 12 Mar 2004 00:58:38 -0800 Subject: [PATCH 0655/4284] [PATCH] fix a type in docs/libsysfs.txt Mary Edie Merideth noticed this typo. I think this is what it was supposed to be. Judging by the pattern. --- docs/libsysfs.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/libsysfs.txt b/docs/libsysfs.txt index 66156e5607..2d68ee4648 100644 --- a/docs/libsysfs.txt +++ b/docs/libsysfs.txt @@ -131,7 +131,7 @@ and devices, here's some examples: #define SYSFS_BUS_DIR "/bus" #define SYSFS_BUS_NAME "bus" #define SYSFS_CLASS_DIR "/class" -#define SYSFS_CLASS_DIR "/class" +#define SYSFS_CLASS_NAME "class" #define SYSFS_BLOCK_DIR "/block" #define SYSFS_BLOCK_NAME "block" #define SYSFS_DEVICES_DIR "/devices" From 60ea6945259ee0336ebd742e701a109c90e5a6ab Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Fri, 12 Mar 2004 01:06:55 -0800 Subject: [PATCH 0656/4284] [PATCH] udev* segfaults with new klibc current klibc uses regparm on i386. This leads to nice segfaults in all udev apps. Using the content of the just included MCONFIG file fixes it. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index e4c6184c95..23aef06666 100644 --- a/Makefile +++ b/Makefile @@ -155,6 +155,7 @@ ifeq ($(strip $(USE_KLIBC)),true) CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) CFLAGS += $(WARNINGS) -nostdinc \ + $(OPTFLAGS) \ -D__KLIBC__ -fno-builtin-printf \ -I$(INCLUDE_DIR) \ -I$(KLIBC_DIR)/arch/$(ARCH)/include \ From 2731fd98c626209362322645c5b283e98bf6f745 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 12 Mar 2004 16:43:31 -0800 Subject: [PATCH 0657/4284] [PATCH] remove extra ; in namedev_parse.c Thanks to Olaf Hering for pointing this out. --- namedev_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev_parse.c b/namedev_parse.c index fba32a4983..8198f7e684 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -65,7 +65,7 @@ void dump_config_dev(struct config_device *dev) "owner='%s', group='%s', mode=%#o", dev->name, dev->symlink, dev->bus, dev->place, dev->id, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value, - dev->kernel, dev->program, dev->result,; + dev->kernel, dev->program, dev->result, dev->owner, dev->group, dev->mode); } From fa19f1811c20b6ec3631cecca9aa18ff2413eebb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Mar 2004 17:13:59 -0800 Subject: [PATCH 0658/4284] [PATCH] add dev node test to udev-test.pl > Nice, that's a good start. Now we need to check the major:minor values > too somehow... I better do it immediately, before you put it in the empty TODO :) Patch is a bit big, cause spaces are changed to tabs to get space for the longer names. --- test/udev-test.pl | 559 ++++++++++++++++++++++++---------------------- 1 file changed, 295 insertions(+), 264 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index e345b20c58..fc682b528a 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -33,30 +33,30 @@ my $conf_tmp = "udev-test.rules"; my @tests = ( { - desc => "label test of scsi disc", - subsys => "block", - devpath => "block/sda", - expected => "boot_disk" , - conf => < "label test of scsi disc", + subsys => "block", + devpath => "block/sda", + exp_name=> "boot_disk" , + conf => < "label test of scsi partition", - subsys => "block", - devpath => "block/sda/sda1", - expected => "boot_disk1" , - conf => < "label test of scsi partition", + subsys => "block", + devpath => "block/sda/sda1", + exp_name=> "boot_disk1" , + conf => < "label test of pattern match", - subsys => "block", - devpath => "block/sda/sda1", - expected => "boot_disk1" , - conf => < "label test of pattern match", + subsys => "block", + devpath => "block/sda/sda1", + exp_name=> "boot_disk1" , + conf => < "label test of multiple sysfs files", - subsys => "block", - devpath => "block/sda/sda1", - expected => "boot_disk1" , - conf => < "label test of multiple sysfs files", + subsys => "block", + devpath => "block/sda/sda1", + exp_name => "boot_disk1" , + conf => < "label test of max sysfs files", - subsys => "block", - devpath => "block/sda/sda1", - expected => "boot_disk1" , - conf => < "label test of max sysfs files", + subsys => "block", + devpath => "block/sda/sda1", + exp_name => "boot_disk1" , + conf => < "catch device by *", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor/0" , - conf => < "catch device by *", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor/0" , + conf => < "catch device by * - take 2", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor/0" , - conf => < "catch device by * - take 2", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor/0" , + conf => < "catch device by ?", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor/0" , - conf => < "catch device by ?", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor/0" , + conf => < "catch device by character class", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor/0" , - conf => < "catch device by character class", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor/0" , + conf => < "replace kernel name", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor" , - conf => < "replace kernel name", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor" , + conf => < "Handle comment lines in config file (and replace kernel name)", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor" , - conf => < "Handle comment lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor" , + conf => < "Handle comment lines in config file with whitespace (and replace kernel name)", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor" , - conf => < "Handle comment lines in config file with whitespace (and replace kernel name)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor" , + conf => < "Handle empty lines in config file (and replace kernel name)", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor" , - conf => < "Handle empty lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor" , + conf => < "subdirectory handling", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "sub/direct/ory/visor" , - conf => < "subdirectory handling", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "sub/direct/ory/visor" , + conf => < "place on bus of scsi partition", - subsys => "block", - devpath => "block/sda/sda3", - expected => "first_disk3" , - conf => < "place on bus of scsi partition", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "first_disk3" , + conf => < "test NAME substitution chars", - subsys => "block", - devpath => "block/sda/sda3", - expected => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , - conf => < "test NAME substitution chars", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , + conf => < "test NAME substitution chars (with length limit)", - subsys => "block", - devpath => "block/sda/sda3", - expected => "M8-m3-n3-b0:0-sIBM" , - conf => < "test NAME substitution chars (with length limit)", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "M8-m3-n3-b0:0-sIBM" , + conf => < "old style SYSFS_ attribute", - subsys => "block", - devpath => "block/sda", - expected => "good" , - conf => < "old style SYSFS_ attribute", + subsys => "block", + devpath => "block/sda", + exp_name => "good" , + conf => < "sustitution of sysfs value (%s{file})", - subsys => "block", - devpath => "block/sda", - expected => "disk-IBM-ESXS-sda" , - conf => < "sustitution of sysfs value (%s{file})", + subsys => "block", + devpath => "block/sda", + exp_name => "disk-IBM-ESXS-sda" , + conf => < "program result substitution", - subsys => "block", - devpath => "block/sda/sda3", - expected => "special-device-3" , - conf => < "program result substitution", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "special-device-3" , + conf => < "block", - devpath => "block/sda/sda3", - expected => "test-0:0:0:0" , - conf => < "program result substitution", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "test-0:0:0:0" , + conf => < "program with escaped format char (tricky: callout returns format char!)", - subsys => "block", - devpath => "block/sda/sda3", - expected => "escape-3" , - conf => < "program with escaped format char (tricky: callout returns format char!)", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "escape-3" , + conf => < "program with lots of arguments", - subsys => "block", - devpath => "block/sda/sda3", - expected => "foo9" , - conf => < "program with lots of arguments", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "foo9" , + conf => < "program with subshell", - subsys => "block", - devpath => "block/sda/sda3", - expected => "bar9" , - conf => < "program with subshell", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "bar9" , + conf => < "program arguments combined with apostrophes", - subsys => "block", - devpath => "block/sda/sda3", - expected => "foo7" , - conf => < "program arguments combined with apostrophes", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "foo7" , + conf => < "characters before the %c{N} substitution", - subsys => "block", - devpath => "block/sda/sda3", - expected => "my-foo9" , - conf => < "characters before the %c{N} substitution", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "my-foo9" , + conf => < "substitute the second to last argument", - subsys => "block", - devpath => "block/sda/sda3", - expected => "my-foo8" , - conf => < "substitute the second to last argument", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "my-foo8" , + conf => < "program result substitution (numbered part of)", - subsys => "block", - devpath => "block/sda/sda3", - expected => "link1" , - conf => < "program result substitution (numbered part of)", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "link1" , + conf => < "program result substitution (numbered part of+)", - subsys => "block", - devpath => "block/sda/sda3", - expected => "link3" , - conf => < "program result substitution (numbered part of+)", + subsys => "block", + devpath => "block/sda/sda3", + exp_name => "link3" , + conf => < "invalid program for device with no bus", - subsys => "tty", - devpath => "class/tty/console", - expected => "TTY" , - conf => < "invalid program for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + exp_name => "TTY" , + conf => < "valid program for device with no bus", - subsys => "tty", - devpath => "class/tty/console", - expected => "foo" , - conf => < "valid program for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + exp_name => "foo" , + conf => < "invalid label for device with no bus", - subsys => "tty", - devpath => "class/tty/console", - expected => "TTY" , - conf => < "invalid label for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + exp_name => "TTY" , + conf => < "valid label for device with no bus", - subsys => "tty", - devpath => "class/tty/console", - expected => "foo" , - conf => < "valid label for device with no bus", + subsys => "tty", + devpath => "class/tty/console", + exp_name => "foo" , + conf => < "program and bus type match", - subsys => "block", - devpath => "block/sda", - expected => "scsi-0:0:0:0" , - conf => < "program and bus type match", + subsys => "block", + devpath => "block/sda", + exp_name => "scsi-0:0:0:0" , + conf => < "symlink creation (same directory)", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor0" , - conf => < "symlink creation (same directory)", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor0" , + conf => < "symlink creation (relative link back)", - subsys => "block", - devpath => "block/sda/sda2", - expected => "1/2/a/b/symlink" , - conf => < "symlink creation (relative link back)", + subsys => "block", + devpath => "block/sda/sda2", + exp_name => "1/2/a/b/symlink" , + conf => < "symlink creation (relative link forward)", - subsys => "block", - devpath => "block/sda/sda2", - expected => "1/2/symlink" , - conf => < "symlink creation (relative link forward)", + subsys => "block", + devpath => "block/sda/sda2", + exp_name => "1/2/symlink" , + conf => < "symlink creation (relative link back and forward)", - subsys => "block", - devpath => "block/sda/sda2", - expected => "1/2/c/d/symlink" , - conf => < "symlink creation (relative link back and forward)", + subsys => "block", + devpath => "block/sda/sda2", + exp_name => "1/2/c/d/symlink" , + conf => < "multiple symlinks", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "second-0" , - conf => < "multiple symlinks", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "second-0" , + conf => < "create all possible partitions", - subsys => "block", - devpath => "block/sda", - expected => "boot_disk15" , - conf => < "create all possible partitions", + subsys => "block", + devpath => "block/sda", + exp_name => "boot_disk15" , + conf => < "sysfs parent hierarchy", - subsys => "tty", - devpath => "class/tty/ttyUSB0", - expected => "visor" , - conf => < "sysfs parent hierarchy", + subsys => "tty", + devpath => "class/tty/ttyUSB0", + exp_name => "visor" , + conf => < "name test with ! in the name", - subsys => "block", - devpath => "block/rd!c0d0", - expected => "rd/c0d0" , - conf => < "name test with ! in the name", + subsys => "block", + devpath => "block/rd!c0d0", + exp_name => "rd/c0d0" , + conf => < "name test with ! in the name, but no matching rule", - subsys => "block", - devpath => "block/rd!c0d0", - expected => "rd/c0d0" , - conf => < "name test with ! in the name, but no matching rule", + subsys => "block", + devpath => "block/rd!c0d0", + exp_name => "rd/c0d0" , + conf => < "ID rule", - subsys => "block", - devpath => "block/sda", - expected => "scsi-0:0:0:0", - conf => < "ID rule", + subsys => "block", + devpath => "block/sda", + exp_name => "scsi-0:0:0:0", + conf => < "ID wildcard all", - subsys => "block", - devpath => "block/sda", - expected => "scsi-0:0:0:0", - conf => < "ID wildcard all", + subsys => "block", + devpath => "block/sda", + exp_name => "scsi-0:0:0:0", + conf => < "ID wildcard partial", - subsys => "block", - devpath => "block/sda", - expected => "scsi-0:0:0:0", - conf => < "ID wildcard partial", + subsys => "block", + devpath => "block/sda", + exp_name => "scsi-0:0:0:0", + conf => < "ID wildcard partial 2", - subsys => "block", - devpath => "block/sda", - expected => "scsi-0:0:0:0", - conf => < "ID wildcard partial 2", + subsys => "block", + devpath => "block/sda", + exp_name => "scsi-0:0:0:0", + conf => < "ignore SYSFS attribute whitespace", - subsys => "block", - devpath => "block/sda", - expected => "ignored", - conf => < "ignore SYSFS attribute whitespace", + subsys => "block", + devpath => "block/sda", + exp_name => "ignored", + conf => < "do not ignore SYSFS attribute whitespace", - subsys => "block", - devpath => "block/sda", - expected => "matched-with-space", - conf => < "do not ignore SYSFS attribute whitespace", + subsys => "block", + devpath => "block/sda", + exp_name => "matched-with-space", + conf => < "SYMLINK only rule", - subsys => "block", - devpath => "block/sda", - expected => "symlink-only2", - conf => < "SYMLINK only rule", + subsys => "block", + devpath => "block/sda", + exp_name => "symlink-only2", + conf => < "permissions test", - subsys => "block", - devpath => "block/sda", - expected => "node", - perms => "5000::0444", - conf => < "permissions test", + subsys => "block", + devpath => "block/sda", + exp_name => "node", + perms => "5000::0444", + conf => < "major/minor number test", + subsys => "block", + devpath => "block/sda", + exp_name => "node", + perms => "5000::0444", + exp_majorminor => "8:0", + conf => <{desc}\n"; - print "device \'$config->{devpath}\' expecting node \'$config->{expected}\'\n"; + print "device \'$config->{devpath}\' expecting node \'$config->{exp_name}\'\n"; udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); - if (-e "$PWD/$udev_root$config->{expected}") { + if (-e "$PWD/$udev_root$config->{exp_name}") { + + my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, + $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$config->{exp_name}"); + if (defined($config->{perms})) { my $wrong = 0; - my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, - $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$config->{expected}"); - $config->{perms} =~ m/^(.*):(.*):(.*)$/; if ($1 ne "") { if ($uid != $1) { $wrong = 1; }; @@ -586,6 +598,25 @@ sub run_test { printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; } } + + if (defined($config->{exp_majorminor})) { + my $major = ($rdev >> 8) & 0xfff; + my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00); + + my $wrong = 0; + $config->{exp_majorminor} =~ m/^(.*):(.*)$/; + if ($1 ne "") { + if ($major != $1) { $wrong = 1; }; + } + if ($2 ne "") { + if ($minor != $2) { $wrong = 1; }; + } + if ($wrong == 1) { + printf "expected major:minor is: %i:%i\n", $1, $2; + printf "created major:minor is : %i:%i\n", $major, $minor; + } + } + print "add: ok "; } else { print "add: error\n"; @@ -595,8 +626,8 @@ sub run_test { } udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf}); - if ((-e "$PWD/$udev_root$config->{expected}") || - (-l "$PWD/$udev_root$config->{expected}")) { + if ((-e "$PWD/$udev_root$config->{exp_name}") || + (-l "$PWD/$udev_root$config->{exp_name}")) { print "remove: error\n\n"; system("tree $udev_root"); $error++; From b9a88fe756d20ea13b8f6da87c784d8aac9c4538 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 12 Mar 2004 17:19:50 -0800 Subject: [PATCH 0659/4284] [PATCH] make perm and major:minor test errors be reported properly. --- test/udev-test.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index fc682b528a..e5407364bb 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -596,6 +596,7 @@ sub run_test { if ($wrong == 1) { printf "expected permissions are: %i:%i:%#o\n", $1, $2, oct($3); printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; + $error++; } } @@ -614,6 +615,7 @@ sub run_test { if ($wrong == 1) { printf "expected major:minor is: %i:%i\n", $1, $2; printf "created major:minor is : %i:%i\n", $major, $minor; + $error++; } } From 7ddb6f47d70ea7a5881d1f2fa6ed856d2cbe0090 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 12 Mar 2004 17:27:44 -0800 Subject: [PATCH 0660/4284] [PATCH] udev-test.pl: print out major:minor and perm test "ok" if is ok. --- test/udev-test.pl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index e5407364bb..300d822d92 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -539,10 +539,9 @@ EOF subsys => "block", devpath => "block/sda", exp_name => "node", - perms => "5000::0444", exp_majorminor => "8:0", conf => < Date: Fri, 12 Mar 2004 17:39:59 -0800 Subject: [PATCH 0661/4284] [PATCH] add a test for a minor over 255 --- test/sys/class/i2c-dev/i2c-300/dev | 1 + test/sys/class/i2c-dev/i2c-300/name | 1 + test/udev-test.pl | 10 ++++++++++ 3 files changed, 12 insertions(+) create mode 100644 test/sys/class/i2c-dev/i2c-300/dev create mode 100644 test/sys/class/i2c-dev/i2c-300/name diff --git a/test/sys/class/i2c-dev/i2c-300/dev b/test/sys/class/i2c-dev/i2c-300/dev new file mode 100644 index 0000000000..e1ffb89f95 --- /dev/null +++ b/test/sys/class/i2c-dev/i2c-300/dev @@ -0,0 +1 @@ +89:300 diff --git a/test/sys/class/i2c-dev/i2c-300/name b/test/sys/class/i2c-dev/i2c-300/name new file mode 100644 index 0000000000..9357009701 --- /dev/null +++ b/test/sys/class/i2c-dev/i2c-300/name @@ -0,0 +1 @@ +foo dev diff --git a/test/udev-test.pl b/test/udev-test.pl index 300d822d92..407ecd3b5b 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -542,6 +542,16 @@ EOF exp_majorminor => "8:0", conf => < "big minor number test", + subsys => "i2c-dev", + devpath => "class/i2c-dev/i2c-300", + exp_name => "node", + exp_majorminor => "89:300", + conf => < Date: Fri, 12 Mar 2004 18:00:39 -0800 Subject: [PATCH 0662/4284] [PATCH] add big major tests to udev-test.pl --- test/sys/class/i2c-dev/i2c-fake1/dev | 1 + test/sys/class/i2c-dev/i2c-fake1/name | 1 + test/sys/class/i2c-dev/i2c-fake2/dev | 1 + test/sys/class/i2c-dev/i2c-fake2/name | 1 + test/udev-test.pl | 20 ++++++++++++++++++++ 5 files changed, 24 insertions(+) create mode 100644 test/sys/class/i2c-dev/i2c-fake1/dev create mode 100644 test/sys/class/i2c-dev/i2c-fake1/name create mode 100644 test/sys/class/i2c-dev/i2c-fake2/dev create mode 100644 test/sys/class/i2c-dev/i2c-fake2/name diff --git a/test/sys/class/i2c-dev/i2c-fake1/dev b/test/sys/class/i2c-dev/i2c-fake1/dev new file mode 100644 index 0000000000..ab453138aa --- /dev/null +++ b/test/sys/class/i2c-dev/i2c-fake1/dev @@ -0,0 +1 @@ +4095:1 diff --git a/test/sys/class/i2c-dev/i2c-fake1/name b/test/sys/class/i2c-dev/i2c-fake1/name new file mode 100644 index 0000000000..ced44c39d4 --- /dev/null +++ b/test/sys/class/i2c-dev/i2c-fake1/name @@ -0,0 +1 @@ +fake1 dev diff --git a/test/sys/class/i2c-dev/i2c-fake2/dev b/test/sys/class/i2c-dev/i2c-fake2/dev new file mode 100644 index 0000000000..d2425b701a --- /dev/null +++ b/test/sys/class/i2c-dev/i2c-fake2/dev @@ -0,0 +1 @@ +4094:89999 diff --git a/test/sys/class/i2c-dev/i2c-fake2/name b/test/sys/class/i2c-dev/i2c-fake2/name new file mode 100644 index 0000000000..b69deec2bf --- /dev/null +++ b/test/sys/class/i2c-dev/i2c-fake2/name @@ -0,0 +1 @@ +fake2 dev diff --git a/test/udev-test.pl b/test/udev-test.pl index 407ecd3b5b..0f623be0d3 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -552,6 +552,26 @@ EOF exp_majorminor => "89:300", conf => < "big major number test", + subsys => "i2c-dev", + devpath => "class/i2c-dev/i2c-fake1", + exp_name => "node", + exp_majorminor => "4095:1", + conf => < "big major and big minor number test", + subsys => "i2c-dev", + devpath => "class/i2c-dev/i2c-fake2", + exp_name => "node", + exp_majorminor => "4094:89999", + conf => < Date: Fri, 12 Mar 2004 18:18:58 -0800 Subject: [PATCH 0663/4284] [PATCH] udev-test.pl cleanup Here is a small name change, so all expected values are named exp_* --- test/udev-test.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 0f623be0d3..d93ebb9cc3 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -36,7 +36,7 @@ my @tests = ( desc => "label test of scsi disc", subsys => "block", devpath => "block/sda", - exp_name=> "boot_disk" , + exp_name => "boot_disk" , conf => < "label test of scsi partition", subsys => "block", devpath => "block/sda/sda1", - exp_name=> "boot_disk1" , + exp_name => "boot_disk1" , conf => < "label test of pattern match", subsys => "block", devpath => "block/sda/sda1", - exp_name=> "boot_disk1" , + exp_name => "boot_disk1" , conf => < "block", devpath => "block/sda", exp_name => "node", - perms => "5000::0444", + exp_perms => "5000::0444", conf => <{exp_name}"); - if (defined($config->{perms})) { + if (defined($config->{exp_perms})) { my $wrong = 0; - $config->{perms} =~ m/^(.*):(.*):(.*)$/; + $config->{exp_perms} =~ m/^(.*):(.*):(.*)$/; if ($1 ne "") { if ($uid != $1) { $wrong = 1; }; } From b1224bc0da0328c44ed8816bb0cf28e7343bab86 Mon Sep 17 00:00:00 2001 From: "async@cc.gatech.edu" Date: Fri, 12 Mar 2004 23:52:17 -0800 Subject: [PATCH 0664/4284] [PATCH] fix HOWTO-udev_for_dev for udevdir --- HOWTO-udev_for_dev | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/HOWTO-udev_for_dev b/HOWTO-udev_for_dev index a6d0892e37..58bf2d4e8c 100644 --- a/HOWTO-udev_for_dev +++ b/HOWTO-udev_for_dev @@ -38,9 +38,11 @@ NOTE NOTE NOTE NOTE NOTE NOTE NOTE I did this with the latest Fedora startup scripts with the patch at the end of this file. - - make sure the /etc/udev/udev.conf file lists the udev_root as /dev. - It should contain the following line in order to work properly. + - make sure the /etc/udev/udev.conf file lists the udev_root as "/dev/" + and the udev_db as "/dev/.udev.tdb". It should contain the + following lines in order to work properly. udev_root="/dev/" + udev_db="/dev/.udev.tdb" - reboot into a 2.6 kernel and watch udev create all of the initial device nodes in /dev From 2761f9b951057c3ed0aaac73f5e003b0d23805f9 Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Fri, 12 Mar 2004 23:52:21 -0800 Subject: [PATCH 0665/4284] [PATCH] make spotless klibc has a target make spotless, this patch makes it possible to clean the whole udev tree and start from scratch. --- Makefile | 2 ++ extras/multipath-tools/Makefile | 2 ++ extras/multipath-tools/devmap_name/Makefile | 2 ++ extras/multipath-tools/libdevmapper/Makefile | 2 ++ extras/multipath-tools/multipath/Makefile | 2 ++ extras/multipath-tools/multipathd/Makefile | 1 + extras/scsi_id/Makefile | 1 + tdb/Makefile | 2 ++ 8 files changed, 14 insertions(+) diff --git a/Makefile b/Makefile index 23aef06666..2c9472a0bb 100644 --- a/Makefile +++ b/Makefile @@ -305,6 +305,8 @@ clean: -C $$target $@ ; \ done ; \ +spotless: clean + DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz$" -e "\/\." -e releases -e BitKeeper -e SCCS -e "\.tdb$" -e test/sys | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . diff --git a/extras/multipath-tools/Makefile b/extras/multipath-tools/Makefile index 2f21f0d112..fa8830082b 100644 --- a/extras/multipath-tools/Makefile +++ b/extras/multipath-tools/Makefile @@ -32,6 +32,8 @@ clean: recurse_clean @echo "" @echo "Make complete" +spotless: clean + install: recurse_install @echo "" @echo "Make complete" diff --git a/extras/multipath-tools/devmap_name/Makefile b/extras/multipath-tools/devmap_name/Makefile index a9683341b2..e3b70a5e0d 100644 --- a/extras/multipath-tools/devmap_name/Makefile +++ b/extras/multipath-tools/devmap_name/Makefile @@ -36,6 +36,8 @@ $(EXEC): $(OBJS) clean: rm -f core *.o $(EXEC) *.gz +spotless: clean + install: install -d $(DESTDIR)$(bindir) install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ diff --git a/extras/multipath-tools/libdevmapper/Makefile b/extras/multipath-tools/libdevmapper/Makefile index 445263caa8..4a8b7723fa 100644 --- a/extras/multipath-tools/libdevmapper/Makefile +++ b/extras/multipath-tools/libdevmapper/Makefile @@ -23,6 +23,8 @@ all: $(OBJS) clean: rm -f core *.o ioctl/*.o ioctl/*.so +spotless: clean + install: uninstall: diff --git a/extras/multipath-tools/multipath/Makefile b/extras/multipath-tools/multipath/Makefile index 4121f4fc3b..4c0fae6d32 100644 --- a/extras/multipath-tools/multipath/Makefile +++ b/extras/multipath-tools/multipath/Makefile @@ -43,6 +43,8 @@ $(EXEC): $(OBJS) clean: rm -f core *.o $(EXEC) *.gz +spotless: clean + install: install -d $(DESTDIR)$(bindir) install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ diff --git a/extras/multipath-tools/multipathd/Makefile b/extras/multipath-tools/multipathd/Makefile index 5bfd58a837..82c77b8351 100644 --- a/extras/multipath-tools/multipathd/Makefile +++ b/extras/multipath-tools/multipathd/Makefile @@ -29,3 +29,4 @@ uninstall: clean: rm -f core *.o $(EXEC) *.gz +spotless: clean diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index bfc2923b34..6af4d7f18e 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -70,5 +70,6 @@ $(OBJS): scsi_id.h scsi.h scsi_id_version.h clean: rm -f $(PROG) $(OBJS) $(GEN_HEADER) +spotless: clean $(PROG): $(OBJS) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) diff --git a/tdb/Makefile b/tdb/Makefile index 021cb35c95..87fb680bdd 100644 --- a/tdb/Makefile +++ b/tdb/Makefile @@ -28,3 +28,5 @@ tdbbackup: tdbbackup.o $(TDB_OBJ) clean: rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm + +spotless: clean From b99c85e440193eb7f7dd84e473cafb16cb75722f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 12 Mar 2004 23:53:38 -0800 Subject: [PATCH 0666/4284] [PATCH] 022 release --- ChangeLog | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 515450ac6a..b78b0b9bbd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,61 @@ +Summary of changes from v021 to v022 +============================================ + +: + o more Libsysfs updates + o Libsysfs updates + +: + o fix HOWTO-udev_for_dev for udevdir + +: + 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 + o 021 release TAG: v021 + +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 ============================================ diff --git a/Makefile b/Makefile index 2c9472a0bb..612911c441 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 021_bk +VERSION = 022 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 34e0755fda..7de035c86e 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 021_bk +Version: 022 Release: 1 License: GPL Group: Utilities/System From 8a0acf85f25d2fb4659aafbad7db2fe48a58307d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Mar 2004 22:18:34 -0800 Subject: [PATCH 0667/4284] [PATCH] make udevtest a real program :) Here are the missing pieces for udevtest. A simple man page is added, the blacklist is removed, cause it can't work without having a subsystem. The Makefile removes all manpages now with a uninstall and installs udevtest in /usr/bin/. Any old version from /sbin/ should be deleted by hand. The only expected argument is the sysfs devpath, here I changed it to be more tolerant to the input. The path may now be specified with or without a leading slash and optionally with the /sys moutpoint prepended. I hope this will end the confusion about the use of this program :) --- Makefile | 7 ++++- udevtest.8 | 17 +++++++++++ udevtest.c | 89 ++++++++++++++++++++++-------------------------------- 3 files changed, 59 insertions(+), 54 deletions(-) create mode 100644 udevtest.8 diff --git a/Makefile b/Makefile index 612911c441..000918573e 100644 --- a/Makefile +++ b/Makefile @@ -382,10 +382,11 @@ install: install-initscript install-config install-dbus-policy all $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) - $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(sbindir)/$(TESTER) + $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 + $(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8 $(INSTALL_DATA) -D udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 @@ -408,6 +409,10 @@ uninstall: uninstall-dbus-policy - rm $(initdir)/udev - rm $(mandir)/man8/udev.8 - rm $(mandir)/man8/udevinfo.8 + - rm $(mandir)/man8/udevtest.8 + - rm $(mandir)/man8/udevstart.8 + - rm $(mandir)/man8/udevd.8 + - rm $(mandir)/man8/udevsend.8 - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) diff --git a/udevtest.8 b/udevtest.8 new file mode 100644 index 0000000000..f23e219244 --- /dev/null +++ b/udevtest.8 @@ -0,0 +1,17 @@ +.TH UDEVTEST 8 "March 2004" "" "Linux Administrator's Manual" +.SH NAME +udevtest \- simulates a udev run to test the configured rules +.SH SYNOPSIS +.BI udevtest " sysfs_device_path" +.SH "DESCRIPTION" +.B udevtest +simulates a +.B udev +run for the given device, and prints out the node names +for the given device, the real udev would have created. +.SH "SEE ALSO" +.BR udev (8) +.SH AUTHORS +.B udevtest +was developed by Greg Kroah-Hartman with much help +from others. diff --git a/udevtest.c b/udevtest.c index e67d452577..95b85dd8be 100644 --- a/udevtest.c +++ b/udevtest.c @@ -37,6 +37,7 @@ char **main_argv; char **main_envp; + #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) @@ -51,72 +52,54 @@ void log_message (int level, const char *format, ...) } #endif -static char *subsystem_blacklist[] = { - "net", - "scsi_host", - "scsi_device", - "usb_host", - "pci_bus", - "pcmcia_socket", - "" -}; - -static int udev_hotplug(void) +int main(int argc, char *argv[], char *envp[]) { char *devpath; - char *subsystem; - int retval = -EINVAL; - int i; + char temp[NAME_SIZE]; + char subsystem[] = ""; + const int fake = 1; - devpath = main_argv[1]; - if (!devpath) { - dbg("no devpath?"); + main_argv = argv; + main_envp = envp; + + info("version %s", UDEV_VERSION); + + if (argv[1] == NULL) { + info("udevinfo expects the DEVPATH of the sysfs device as a argument"); goto exit; } - dbg("looking at '%s'", devpath); - - /* we only care about class devices and block stuff */ - if (!strstr(devpath, "class") && - !strstr(devpath, "block")) { - dbg("not a block or class device"); - goto exit; - } - - /* skip blacklisted subsystems */ - subsystem = main_argv[1]; - i = 0; - while (subsystem_blacklist[i][0] != '\0') { - if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { - dbg("don't care about '%s' devices", subsystem); - goto exit; - } - i++; - } /* initialize our configuration */ udev_init_config(); + /* remove sysfs_path if given */ + if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) + devpath = argv[1] + strlen(sysfs_path); + else + if (argv[1][0] != '/') { + /* prepend '/' if missing */ + strfieldcpy(temp, "/"); + strfieldcat(temp, argv[1]); + devpath = temp; + } else { + devpath = argv[1]; + } + + info("looking at '%s'", devpath); + + /* we only care about class devices and block stuff */ + if (!strstr(devpath, "class") && + !strstr(devpath, "block")) { + info("not a block or class device"); + goto exit; + } + /* initialize the naming deamon */ namedev_init(); /* simulate node creation with fake flag */ - retval = udev_add_device(devpath, subsystem, 1); + udev_add_device(devpath, subsystem, fake); exit: - if (retval > 0) - retval = 0; - - return -retval; + return 0; } - -int main(int argc, char *argv[], char *envp[]) -{ - main_argv = argv; - main_envp = envp; - - dbg("version %s", UDEV_VERSION); - - return udev_hotplug(); -} - - From c58286656e8bd4285e35a1cf12906416dd259aab Mon Sep 17 00:00:00 2001 From: "tytso@mit.edu" Date: Mon, 22 Mar 2004 22:19:37 -0800 Subject: [PATCH 0668/4284] [PATCH] Trivial man page typo fixes to udev Fix minor man page typo's. --- udev.8 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/udev.8 b/udev.8 index b367d39813..417b74bdc5 100644 --- a/udev.8 +++ b/udev.8 @@ -149,13 +149,13 @@ value in the file. .P Every line in the rules file defines the mapping between device attributes -and the device file name. One ore more keys are specified to match a rule +and the device file name. One or more keys are specified to match a rule with the current device. If all keys are matching, the rule will be applied and the name is used for the device node. .br If no matching rule is found, the default kernel device name is used. .P -Every rule consists of a list a comma separated fields: +Every rule consists of a list of comma separated fields: .sp .IR "key " ,[ "key " ,...] " name " [, " symlink" ] .sp @@ -252,7 +252,7 @@ The string returned from the execution of field for the obvious reason.) .br A single part of the string, separated by a space character -may be selected by specifying the part number as a attribute: +may be selected by specifying the part number as an attribute: .BI %c{ N } If the number is followed by the + char this part plus all remaining parts of the result string are substituted: From c81b35c08bbd7789883993ea280e0d3772cce440 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 22 Mar 2004 22:22:20 -0800 Subject: [PATCH 0669/4284] [PATCH] replace fgets() with mmap() and introduce udev_lib.[hc] Here we replace the various fgets() with a mmap() call for the config file reading, due to the reported performance problems with klibc. Thanks to Patrick's testing, it makes a very small, close to nothing speed gain for libc users, but a 6 times speed increase for klibc users with a 1000 line config file. I've created a udev_lib.[hc] for this and also moved all the generic stuff from udev.h in there and uninlined the functions. --- Makefile | 8 ++-- klibc_fixups.c | 30 +++++++++---- namedev.c | 1 + namedev_parse.c | 56 +++++++++++++++--------- udev-add.c | 1 + udev-remove.c | 1 + udev.c | 6 ++- udev.h | 104 +++++---------------------------------------- udev_config.c | 32 +++++++++----- udev_lib.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++ udev_lib.h | 78 ++++++++++++++++++++++++++++++++++ udevd.c | 1 + udevdb.c | 9 ++-- udevinfo.c | 1 + udevsend.c | 1 + 15 files changed, 298 insertions(+), 142 deletions(-) create mode 100644 udev_lib.c create mode 100644 udev_lib.h diff --git a/Makefile b/Makefile index 000918573e..0604c1fa07 100644 --- a/Makefile +++ b/Makefile @@ -201,7 +201,8 @@ SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ $(PWD)/libsysfs/sysfs_utils.o \ $(PWD)/libsysfs/dlist.o -OBJS = udev_config.o \ +OBJS = udev_lib.o \ + udev_config.o \ udev-add.o \ udev-remove.o \ udevdb.o \ @@ -211,6 +212,7 @@ OBJS = udev_config.o \ $(TDB) HEADERS = udev.h \ + udev_lib.h \ namedev.h \ udev_version.h \ udev_dbus.h \ @@ -279,7 +281,7 @@ $(TESTER): $(TESTER).o $(OBJS) $(HEADERS) $(LIBC) $(STRIPCMD) $@ $(INFO): $(INFO).o $(OBJS) $(HEADERS) $(LIBC) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(DAEMON): $(DAEMON).o udevd.h $(LIBC) @@ -287,7 +289,7 @@ $(DAEMON): $(DAEMON).o udevd.h $(LIBC) $(STRIPCMD) $@ $(SENDER): $(SENDER).o udevd.h $(LIBC) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(STARTER): $(STARTER).o $(HEADERS) $(LIBC) diff --git a/klibc_fixups.c b/klibc_fixups.c index 99460c32f7..eaa240c183 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -28,6 +28,7 @@ #include #include +#include "udev.h" #include "klibc_fixups.h" #include "logging.h" @@ -40,22 +41,35 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) { unsigned long id = -1; - FILE *file; - char buf[255]; + char line[255]; + char *buf; + size_t bufsize; + size_t cur; + size_t count; char *pos; char *name; char *idstr; char *tail; - file = fopen(dbfile, "r"); - if (file == NULL) { - dbg("unable to open file '%s'", dbfile); + if (file_map(dbfile, &buf, &bufsize) == 0) { + dbg("reading '%s' as db file", dbfile); + } else { + dbg("can't open '%s' as db file", dbfile); return -1; } + /* loop through the whole file */ + + cur = 0; while (1) { - pos = fgets(buf, sizeof(buf), file); - if (pos == NULL) + count = buf_get_line(buf, bufsize, cur); + + strncpy(line, buf + cur, count); + line[count] = '\0'; + pos = line; + + cur += count+1; + if (cur > bufsize) break; /* get name */ @@ -82,7 +96,7 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) } } - fclose(file); + file_unmap(buf, bufsize); return id; } diff --git a/namedev.c b/namedev.c index 025a14aea4..8f781a66e2 100644 --- a/namedev.c +++ b/namedev.c @@ -36,6 +36,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "list.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" diff --git a/namedev_parse.c b/namedev_parse.c index 8198f7e684..f4ffdb21d6 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -38,6 +37,7 @@ #include #include "udev.h" +#include "udev_lib.h" #include "logging.h" #include "namedev.h" @@ -153,27 +153,36 @@ static int namedev_parse_rules(char *filename) char *temp2; char *temp3; char *attr; - FILE *fd; + char *buf; + size_t bufsize; + size_t cur; + size_t count; int program_given = 0; int retval = 0; struct config_device dev; - fd = fopen(filename, "r"); - if (fd != NULL) { + if (file_map(filename, &buf, &bufsize) == 0) { dbg("reading '%s' as rules file", filename); } else { - dbg("can't open '%s' as a rules file", filename); - return -ENODEV; + dbg("can't open '%s' as rules file", filename); + return -1; } /* loop through the whole file */ + cur = 0; lineno = 0; while (1) { - /* get a line */ - temp = fgets(line, sizeof(line), fd); - if (temp == NULL) - goto exit; + count = buf_get_line(buf, bufsize, cur); + + strncpy(line, buf + cur, count); + line[count] = '\0'; + temp = line; lineno++; + + cur += count+1; + if (cur > bufsize) + break; + dbg_parse("read '%s'", temp); /* eat the whitespace */ @@ -311,8 +320,8 @@ error: filename, lineno, temp - line); } } -exit: - fclose(fd); + + file_unmap(buf, bufsize); return retval; } @@ -321,22 +330,31 @@ static int namedev_parse_permissions(char *filename) char line[255]; char *temp; char *temp2; - FILE *fd; + char *buf; + size_t bufsize; + size_t cur; + size_t count; int retval = 0; struct perm_device dev; - fd = fopen(filename, "r"); - if (fd != NULL) { + if (file_map(filename, &buf, &bufsize) == 0) { dbg("reading '%s' as permissions file", filename); } else { dbg("can't open '%s' as permissions file", filename); - return -ENODEV; + return -1; } /* loop through the whole file */ + cur = 0; while (1) { - temp = fgets(line, sizeof(line), fd); - if (temp == NULL) + count = buf_get_line(buf, bufsize, cur); + + strncpy(line, buf + cur, count); + line[count] = '\0'; + temp = line; + + cur += count+1; + if (cur > bufsize) break; dbg_parse("read '%s'", temp); @@ -394,7 +412,7 @@ static int namedev_parse_permissions(char *filename) } exit: - fclose(fd); + file_unmap(buf, bufsize); return retval; } diff --git a/udev-add.c b/udev-add.c index ce723e45cc..2bd16014f5 100644 --- a/udev-add.c +++ b/udev-add.c @@ -37,6 +37,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udev_dbus.h" #include "udev_selinux.h" diff --git a/udev-remove.c b/udev-remove.c index 44ad603d4a..d909713450 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -29,6 +29,7 @@ #include #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udev_dbus.h" #include "logging.h" diff --git a/udev.c b/udev.c index 9b4d91f75c..d10badc8ea 100644 --- a/udev.c +++ b/udev.c @@ -20,15 +20,17 @@ * */ +#include +#include #include #include -#include -#include #include +#include #include #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udev_dbus.h" #include "logging.h" diff --git a/udev.h b/udev.h index 8752f595d6..54269dfd31 100644 --- a/udev.h +++ b/udev.h @@ -20,25 +20,22 @@ * */ -#ifndef UDEV_H -#define UDEV_H +#ifndef _UDEV_H_ +#define _UDEV_H_ -#include -#include -#include -#include #include +#include "libsysfs/sysfs/libsysfs.h" #define COMMENT_CHARACTER '#' -#define NAME_SIZE 100 -#define OWNER_SIZE 30 -#define GROUP_SIZE 30 -#define MODE_SIZE 8 +#define NAME_SIZE 100 +#define OWNER_SIZE 30 +#define GROUP_SIZE 30 +#define MODE_SIZE 8 -#define ACTION_SIZE 30 -#define DEVPATH_SIZE 255 -#define SUBSYSTEM_SIZE 30 +#define ACTION_SIZE 30 +#define DEVPATH_SIZE 255 +#define SUBSYSTEM_SIZE 30 /* length of public data */ #define UDEVICE_LEN (offsetof(struct udevice, bus_id)) @@ -61,87 +58,6 @@ struct udevice { char kernel_name[NAME_SIZE]; }; -#define strfieldcpy(to, from) \ -do { \ - to[sizeof(to)-1] = '\0'; \ - strncpy(to, from, sizeof(to)-1); \ -} while (0) - -#define strfieldcat(to, from) \ -do { \ - to[sizeof(to)-1] = '\0'; \ - strncat(to, from, sizeof(to) - strlen(to)-1); \ -} while (0) - -#define strfieldcpymax(to, from, maxsize) \ -do { \ - to[maxsize-1] = '\0'; \ - strncpy(to, from, maxsize-1); \ -} while (0) - -#define strfieldcatmax(to, from, maxsize) \ -do { \ - to[maxsize-1] = '\0'; \ - strncat(to, from, maxsize - strlen(to)-1); \ -} while (0) - -#define strintcat(to, i) \ -do { \ - to[sizeof(to)-1] = '\0'; \ - snprintf((to) + strlen(to), sizeof(to) - strlen(to)-1, "%u", i); \ -} while (0) - -#define strintcatmax(to, i, maxsize) \ -do { \ - to[maxsize-1] = '\0'; \ - snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ -} while (0) - -#define foreach_strpart(str, separator, pos, len) \ - for(pos = str, len = 0; \ - (pos) < ((str) + strlen(str)); \ - pos = pos + len + strspn(pos, separator), len = strcspn(pos, separator)) \ - if (len > 0) - -static inline char *get_action(void) -{ - char *action; - - action = getenv("ACTION"); - if (action != NULL && strlen(action) > ACTION_SIZE) - action[ACTION_SIZE-1] = '\0'; - - return action; -} - -static inline char *get_devpath(void) -{ - char *devpath; - - devpath = getenv("DEVPATH"); - if (devpath != NULL && strlen(devpath) > DEVPATH_SIZE) - devpath[DEVPATH_SIZE-1] = '\0'; - - return devpath; -} - -static inline char *get_seqnum(void) -{ - char *seqnum; - - seqnum = getenv("SEQNUM"); - - return seqnum; -} - -static inline char *get_subsystem(char *subsystem) -{ - if (subsystem != NULL && strlen(subsystem) > SUBSYSTEM_SIZE) - subsystem[SUBSYSTEM_SIZE-1] = '\0'; - - return subsystem; -} - extern int udev_add_device(char *path, char *subsystem, int fake); extern int udev_remove_device(char *path, char *subsystem); extern void udev_init_config(void); diff --git a/udev_config.c b/udev_config.c index e2031dc64d..57a512d711 100644 --- a/udev_config.c +++ b/udev_config.c @@ -34,6 +34,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" @@ -131,12 +132,14 @@ static int parse_config_file(void) char *temp; char *variable; char *value; - FILE *fd; - int lineno = 0; + char *buf; + size_t bufsize; + size_t cur; + size_t count; + int lineno; int retval = 0; - - fd = fopen(udev_config_filename, "r"); - if (fd != NULL) { + + if (file_map(udev_config_filename, &buf, &bufsize) == 0) { dbg("reading '%s' as config file", udev_config_filename); } else { dbg("can't open '%s' as config file", udev_config_filename); @@ -144,13 +147,20 @@ static int parse_config_file(void) } /* loop through the whole file */ + lineno = 0; + cur = 0; while (1) { - /* get a line */ - temp = fgets(line, sizeof(line), fd); - if (temp == NULL) - goto exit; + count = buf_get_line(buf, bufsize, cur); + + strncpy(line, buf + cur, count); + line[count] = '\0'; + temp = line; lineno++; + cur += count+1; + if (cur > bufsize) + break; + dbg_parse("read '%s'", temp); /* eat the whitespace at the beginning of the line */ @@ -182,8 +192,8 @@ static int parse_config_file(void) } dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, lineno, temp - line, temp); -exit: - fclose(fd); + + file_unmap(buf, bufsize); return retval; } diff --git a/udev_lib.c b/udev_lib.c new file mode 100644 index 0000000000..50598a4a31 --- /dev/null +++ b/udev_lib.c @@ -0,0 +1,111 @@ +/* + * udev_lib - generic stuff used by udev + * + * 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. + * + * 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. + * + */ + + +#include +#include +#include +#include +#include +#include + +#include "libsysfs/sysfs/libsysfs.h" +#include "udev.h" +#include "udev_lib.h" + + +char *get_action(void) +{ + char *action; + + action = getenv("ACTION"); + if (action != NULL && strlen(action) > ACTION_SIZE) + action[ACTION_SIZE-1] = '\0'; + + return action; +} + +char *get_devpath(void) +{ + char *devpath; + + devpath = getenv("DEVPATH"); + if (devpath != NULL && strlen(devpath) > DEVPATH_SIZE) + devpath[DEVPATH_SIZE-1] = '\0'; + + return devpath; +} + +char *get_seqnum(void) +{ + char *seqnum; + + seqnum = getenv("SEQNUM"); + + return seqnum; +} + +char *get_subsystem(char *subsystem) +{ + if (subsystem != NULL && strlen(subsystem) > SUBSYSTEM_SIZE) + subsystem[SUBSYSTEM_SIZE-1] = '\0'; + + return subsystem; +} + +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) { + return -1; + } + + *buf = mmap(NULL, stats.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (*buf == MAP_FAILED) { + return -1; + } + *bufsize = stats.st_size; + + close(fd); + + return 0; +} + +void file_unmap(char *buf, size_t bufsize) +{ + munmap(buf, bufsize); +} + +size_t buf_get_line(char *buf, size_t buflen, size_t cur) +{ + size_t count = 0; + + for (count = cur; count < buflen && buf[count] != '\n'; count++); + + return count - cur; +} + diff --git a/udev_lib.h b/udev_lib.h new file mode 100644 index 0000000000..565d87e9a5 --- /dev/null +++ b/udev_lib.h @@ -0,0 +1,78 @@ +/* + * udev_lib - generic stuff used by udev + * + * 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. + * + * 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 _UDEV_LIB_H_ +#define _UDEV_LIB_H_ + + +#define strfieldcpy(to, from) \ +do { \ + to[sizeof(to)-1] = '\0'; \ + strncpy(to, from, sizeof(to)-1); \ +} while (0) + +#define strfieldcat(to, from) \ +do { \ + to[sizeof(to)-1] = '\0'; \ + strncat(to, from, sizeof(to) - strlen(to)-1); \ +} while (0) + +#define strfieldcpymax(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncpy(to, from, maxsize-1); \ +} while (0) + +#define strfieldcatmax(to, from, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + strncat(to, from, maxsize - strlen(to)-1); \ +} while (0) + +#define strintcat(to, i) \ +do { \ + to[sizeof(to)-1] = '\0'; \ + snprintf((to) + strlen(to), sizeof(to) - strlen(to)-1, "%u", i); \ +} while (0) + +#define strintcatmax(to, i, maxsize) \ +do { \ + to[maxsize-1] = '\0'; \ + snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ +} while (0) + +#define foreach_strpart(str, separator, pos, len) \ + for(pos = str, len = 0; \ + (pos) < ((str) + strlen(str)); \ + pos = pos + len + strspn(pos, separator), len = strcspn(pos, separator)) \ + if (len > 0) + + +extern char *get_action(void); +extern char *get_devpath(void); +extern char *get_seqnum(void); +extern char *get_subsystem(char *subsystem); +extern int file_map(const char *filename, char **buf, size_t *bufsize); +extern void file_unmap(char *buf, size_t bufsize); +extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); + + +#endif diff --git a/udevd.c b/udevd.c index efcb65bb53..4cb3e1d405 100644 --- a/udevd.c +++ b/udevd.c @@ -36,6 +36,7 @@ #include "list.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udevd.h" #include "logging.h" diff --git a/udevdb.c b/udevdb.c index 01df3ba7e1..40580e5a3b 100644 --- a/udevdb.c +++ b/udevdb.c @@ -1,5 +1,5 @@ /* - * udevdb.c + * udevdb.c - udev database library * * Userspace devfs * @@ -21,13 +21,11 @@ * */ -/* - * udev database library - */ #define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include #include +#include #include #include #include @@ -35,8 +33,9 @@ #include #include "libsysfs/sysfs/libsysfs.h" -#include "udev_version.h" #include "udev.h" +#include "udev_lib.h" +#include "udev_version.h" #include "logging.h" #include "namedev.h" #include "udevdb.h" diff --git a/udevinfo.c b/udevinfo.c index ffc5e31f04..5ad9e64746 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -30,6 +30,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "libsysfs/dlist.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "logging.h" #include "udevdb.h" diff --git a/udevsend.c b/udevsend.c index 11234808d9..f1c46d3367 100644 --- a/udevsend.c +++ b/udevsend.c @@ -36,6 +36,7 @@ #include #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "udevd.h" #include "logging.h" From 30ccd6a3e128c0c32253f9c70f701cab20a8ebf0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Mar 2004 22:32:34 -0800 Subject: [PATCH 0670/4284] [PATCH] fix udevtest to build properly after the big udev_lib change. --- udevtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udevtest.c b/udevtest.c index 95b85dd8be..67ae9cc98f 100644 --- a/udevtest.c +++ b/udevtest.c @@ -29,6 +29,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_lib.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" From e4c89108001a9af3b8c132111d63980e3a1dcaf4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Mar 2004 22:39:39 -0800 Subject: [PATCH 0671/4284] [PATCH] Increase the name size as requested by Richard Gooch --- udev.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.h b/udev.h index 54269dfd31..65cbf42b51 100644 --- a/udev.h +++ b/udev.h @@ -28,7 +28,7 @@ #define COMMENT_CHARACTER '#' -#define NAME_SIZE 100 +#define NAME_SIZE 256 #define OWNER_SIZE 30 #define GROUP_SIZE 30 #define MODE_SIZE 8 From c641a99c6f7de872c291b7d14568d8e7df447f8b Mon Sep 17 00:00:00 2001 From: "rgooch@ras.ucalgary.ca" Date: Mon, 22 Mar 2004 22:43:07 -0800 Subject: [PATCH 0672/4284] [PATCH] SCSI logical and physical names for udev Hi, Greg. Appended is scsi-devfs.sh, a script for udev to implement devfs-style names for SCSI hard discs, CD-ROM's and generic devices. This has been tested with both hard discs and CD-ROM's. The SCSI generic support should be OK for when there is sysfs/udev support for SCSI generic devices. SCSI tapes are not yet implemented because I don't have one to test with. In addition, this script supports physical names, based on PCI bus location, both longhand (/udev/bus/pci/...) and shorthand (/udev/sd/pci/*). --- extras/scsi-devfs.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 extras/scsi-devfs.sh diff --git a/extras/scsi-devfs.sh b/extras/scsi-devfs.sh new file mode 100644 index 0000000000..30f4553a5b --- /dev/null +++ b/extras/scsi-devfs.sh @@ -0,0 +1,88 @@ +#! /bin/sh +# +# scsi-devfs.sh: udev external PROGRAM script +# +# Copyright 2004 Richard Gooch +# Copyright 2004 Fujitsu Ltd. +# Distributed under the GNU Copyleft version 2.0. +# +# return devfs-names for scsi-devices +# Usage in udev.rules: +# BUS="scsi", KERNEL="sd*", PROGRAM="/etc/udev/scsi-devfs.sh sd %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" +# BUS="scsi", KERNEL="sr*", PROGRAM="/etc/udev/scsi-devfs.sh sr %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" +# BUS="scsi", KERNEL="st*", PROGRAM="/etc/udev/scsi-devfs.sh st %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" +# BUS="scsi", KERNEL="sg*", PROGRAM="/etc/udev/scsi-devfs.sh sg %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" + +# Find out where sysfs is mounted. Exit if not available +sysfs=`fgrep sysfs /proc/mounts | awk '{print $2}'` +if [ "$sysfs" = "" ]; then + echo "sysfs is required" + exit 1 +fi +cd $sysfs/bus/scsi/devices + +case "$1" in + sd) + # Extract partition component + if [ "$3" = "" ]; then + lpart="disc" + spart="" + else + lpart="part$3" + spart="p$3" + fi + ;; + sr) + lpart="cdrom" + spart="" + ;; + st) + # Not supported yet + exit 1 + ;; + sg) + lpart="generic" + spart="" + ;; + *) + exit 1 + ;; +esac + +# Extract SCSI logical address components +scsi_host=`echo $2 | cut -f 1 -d:` +scsi_bus=`echo $2 | cut -f 2 -d:` +scsi_target=`echo $2 | cut -f 3 -d:` +scsi_lun=`echo $2 | cut -f 4 -d:` + +# Generate long and short common name parts +l_com="bus$scsi_bus/target$scsi_target/lun$scsi_lun/$lpart" +s_com="b${scsi_bus}t${scsi_target}u${scsi_lun}$spart" + +# Generate long and short logical names +l_log="scsi/host$scsi_host/$l_com" +s_log="$1/c${scsi_host}${s_com}" + +readlink $2 | fgrep -q pci +if [ "$?" != "0" ]; then + # Not a PCI controller, show logical locations only + echo $l_log $s_log + exit 0 +fi + +# Extract PCI address +tmp=`readlink $2 | sed -e 's@/host.*/.*@@'` +pci_addr=`basename "$tmp"` +pci_domain=`echo $pci_addr | cut -f 1 -d:` +pci_bus=`echo $pci_addr | cut -f 2 -d:` +pci_slot=`echo $pci_addr | tr . : | cut -f 3 -d:` +pci_function=`echo $pci_addr | cut -f 2 -d.` + +# Generate long and short physical names +l_pci="domain$pci_domain/bus$pci_bus/slot$pci_slot/function$pci_function" +l_phy="bus/pci/$l_pci/scsi/$l_com" +s_phy="$1/pci/$pci_addr/$s_com" + +echo $l_phy $s_phy $l_log $s_log + + From 166612d79decf5e7331a6bb65a60b4873551dfde Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 23 Mar 2004 18:21:45 -0800 Subject: [PATCH 0673/4284] [PATCH] add a question/answer about automounting usb devices to the FAQ. Thanks to bert hubert for the text. --- FAQ | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/FAQ b/FAQ index a3bec17408..28f7552ae3 100644 --- a/FAQ +++ b/FAQ @@ -84,6 +84,20 @@ Q: How will udev handle devices found before init runs? A: udev will be placed in initramfs and run for every device that is found. Work to get this implemented is still underway. +Q: Can I use udev to automount a USB device when I connect it? +A: Technically, yes, but udev is not intended for this. Projects that do + automount hotplugged storage devices are: + * Usb-mount http://users.actrix.co.nz/michael/usbmount.html + * devlabel http://linux.dell.com/projects.shtml#devlabel + + Alternatively, it is easy to add the following to fstab: + /udev/pendrive /pendrive vfat user,noauto 0 0 + + This means that users can access the device with: + $ mount /pendrive + And don't have to be root but will get full permissions on /pendrive. + This works even without udev if /udev/pendrive is replaced by /dev/sda1 + 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 From b608ade8e4b3df1f2e798dd460ce8ff4e70eb3d9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Mar 2004 18:24:25 -0800 Subject: [PATCH 0674/4284] [PATCH] first stupid try for a rule compose gui On Mon, Mar 15, 2004 at 09:28:17PM +0100, Kay Sievers wrote: > Here is a first simple and pretty stupid try to make a simple tool for > composing of a udev rule. > > It reads the udevdb to get all currently handled devices and presents a > list, where you can choose the device to compose the rule for. > > The composed rule is just printed out in a window, nothing else by now. > > Do we want something like this? > Nevermind, I always wanted to know, how this newt thing works :) Here is the next step, I still can't sleep and there are to many patches pending to make something useful :) Cause nobody wanted to play with me, I've made a screenshot. The device list is sorted in alphabetical order now and if there are only a few recently discovered devices, they are placed on top of the list. For those who want to have a look: http://vrfy.org/projects/udev/udevruler.png The patch applies on top of today's mmap() patch. The db format is changed to have the file and line number of the applied rule. So it should be easy to edit the matching rule with this beast. It compiles with "make all udevruler". --- Makefile | 7 +- namedev.c | 5 + udev.h | 3 + udevinfo.c | 3 + udevruler.c | 503 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 520 insertions(+), 1 deletion(-) create mode 100644 udevruler.c diff --git a/Makefile b/Makefile index 0604c1fa07..3d5288b25d 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart +RULER = udevruler VERSION = 022 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -296,10 +297,14 @@ $(STARTER): $(STARTER).o $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevstart.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ +$(RULER): $(RULER).o $(OBJS) $(HEADERS) $(LIBC) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevruler.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) -lnewt + $(STRIPCMD) $@ + clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) $(RULER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff --git a/namedev.c b/namedev.c index 8f781a66e2..e075e20af5 100644 --- a/namedev.c +++ b/namedev.c @@ -840,6 +840,8 @@ found: apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); apply_format(udev, udev->symlink, sizeof(udev->symlink), class_dev, sysfs_device); udev->partitions = dev->partitions; + strfieldcpy(udev->config_file, dev->config_file); + udev->config_line = dev->config_line; done: /* get permissions given in rule */ @@ -862,6 +864,9 @@ done: dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); + /* store time of action */ + udev->config_time = time(NULL); + return 0; } diff --git a/udev.h b/udev.h index 65cbf42b51..16a212cd2c 100644 --- a/udev.h +++ b/udev.h @@ -50,6 +50,9 @@ struct udevice { unsigned int mode; /* not mode_t due to conflicting definitions in different libcs */ char symlink[NAME_SIZE]; int partitions; + int config_line; + char config_file[NAME_SIZE]; + time_t config_time; /* private data that help us in building strings */ char bus_id[SYSFS_NAME_LEN]; diff --git a/udevinfo.c b/udevinfo.c index 5ad9e64746..dc3f94fffe 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -112,6 +112,9 @@ static int print_record(char *path, struct udevice *dev) printf("S: %s\n", dev->symlink); printf("O: %s\n", dev->owner); printf("G: %s\n", dev->group); + printf("F: %s\n", dev->config_file); + printf("L: %i\n", dev->config_line); + printf("T: %li\n", dev->config_time); printf("\n"); return 0; } diff --git a/udevruler.c b/udevruler.c new file mode 100644 index 0000000000..b66940e944 --- /dev/null +++ b/udevruler.c @@ -0,0 +1,503 @@ +/* + * udevruler.c - simple udev-rule composer + * + * Reads the udev-db to get all currently known devices and + * scans the sysfs device chain for the choosen device to select attributes + * to compose a rule for the udev.rules file to uniquely name this device. + * + * 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_lib.h" +#include "udev_version.h" +#include "udevdb.h" +#include "logging.h" +#include "libsysfs/sysfs.h" +#include "list.h" + +#ifdef LOG +unsigned char logname[LOGNAME_SIZE]; +void log_message(int level, const char *format, ...) +{ + va_list args; + + if (!udev_log) + return; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif + +static char *dev_blacklist[] = { + "tty", + "pty", + "zero", + "null", + "kmsg", + "rtc", + "timer", + "full", + "kmem", + "mem", + "random", + "urandom", + "console", + "port", + "" +}; + +struct device { + struct list_head list; + char name[NAME_SIZE]; + char devpath[DEVPATH_SIZE]; + int config_line; + char config_file[NAME_SIZE]; + time_t config_time; + int added; +}; + +LIST_HEAD(device_list); +int device_count; + +/* callback for database dump */ +static int add_record(char *path, struct udevice *udev) +{ + struct device *dev; + struct device *loop_dev; + int i = 0; + + while (dev_blacklist[i][0] != '\0') { + if (strncmp(udev->name, dev_blacklist[i], strlen(dev_blacklist[i])) == 0) + goto exit; + i++; + } + + dev = malloc(sizeof(struct device)); + if (dev == NULL) { + printf("error malloc\n"); + exit(2); + } + strfieldcpy(dev->name, udev->name); + strfieldcpy(dev->devpath, path); + dev->config_line = udev->config_line; + strfieldcpy(dev->config_file, udev->config_file); + dev->config_time = udev->config_time; + dev->added = 0; + + /* sort in lexical order */ + list_for_each_entry(loop_dev, &device_list, list) { + if (strcmp(loop_dev->name, dev->name) > 0) { + break; + } + } + + list_add_tail(&dev->list, &loop_dev->list); + device_count++; + +exit: + return 0; +} + +/* get all devices from udev database */ +static int get_all_devices(void) +{ + int retval; + + device_count = 0; + INIT_LIST_HEAD(&device_list); + + retval = udevdb_open_ro(); + if (retval != 0) { + printf("unable to open udev database\n"); + exit(1); + } + + udevdb_call_foreach(add_record); + udevdb_exit(); + + return 0; +} + +struct attribute { + struct list_head list; + int level; + char key[NAME_SIZE]; +}; + +LIST_HEAD(attribute_list); +int attribute_count; + +static int add_attribute(const char *key, int level) +{ + struct attribute *attr; + + dbg("add attribute '%s'", key); + attr = malloc(sizeof(struct attribute)); + if (attr == NULL) { + printf("error malloc\n"); + exit(2); + } + + strfieldcpy(attr->key, key); + attr->level = level; + list_add_tail(&attr->list, &attribute_list); + attribute_count++; + return 0; +} + +static int add_all_attributes(const char *path, int level) +{ + struct dlist *attributes; + struct sysfs_attribute *attr; + struct sysfs_directory *sysfs_dir; + char value[NAME_SIZE]; + char key[NAME_SIZE]; + int len; + int retval = 0; + + dbg("look at '%s', level %i", path, level); + + sysfs_dir = sysfs_open_directory(path); + if (sysfs_dir == NULL) + return -1; + + attributes = sysfs_get_dir_attributes(sysfs_dir); + if (attributes == NULL) { + retval = -1; + return 0; + } + + dlist_for_each_data(attributes, attr, struct sysfs_attribute) + if (attr->value != NULL) { + dbg("found attribute '%s'", attr->name); + strfieldcpy(value, attr->value); + len = strlen(value); + if (len == 0) + continue; + + /* skip very long attributes */ + if (len > 40) + continue; + + /* remove trailing newline */ + if (value[len-1] == '\n') { + value[len-1] = '\0'; + len--; + } + + /* skip nonprintable values */ + while (len) { + if (!isprint(value[len-1])) + break; + len--; + } + if (len == 0) { + sprintf(key, "SYSFS{%s}=\"%s\"", attr->name, value); + add_attribute(key, level); + } + } + + return 0; +} + +static int get_all_attributes(char *path) +{ + struct sysfs_class_device *class_dev; + struct sysfs_class_device *class_dev_parent; + struct sysfs_attribute *attr; + struct sysfs_device *sysfs_dev; + struct sysfs_device *sysfs_dev_parent; + char key[NAME_SIZE]; + int retval = 0; + int level = 0; + + attribute_count = 0; + INIT_LIST_HEAD(&attribute_list); + + /* get the class dev */ + class_dev = sysfs_open_class_device_path(path); + if (class_dev == NULL) { + dbg("couldn't get the class device"); + return -1; + } + + /* read the 'dev' file for major/minor*/ + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) { + dbg("couldn't get the \"dev\" file"); + retval = -1; + goto exit; + } + + sysfs_close_attribute(attr); + + /* open sysfs class device directory and get all attributes */ + if (add_all_attributes(class_dev->path, level) != 0) { + dbg("couldn't open class device directory"); + retval = -1; + goto exit; + } + level++; + + /* get the device link (if parent exists look here) */ + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent != NULL) { + //sysfs_close_class_device(class_dev); + class_dev = class_dev_parent; + } + sysfs_dev = sysfs_get_classdev_device(class_dev); + + /* look the device chain upwards */ + while (sysfs_dev != NULL) { + if (sysfs_dev->bus[0] != '\0') { + add_attribute("", level); + sprintf(key, "BUS=\"%s\"", sysfs_dev->bus); + add_attribute(key, level); + sprintf(key, "ID=\"%s\"", sysfs_dev->bus_id); + add_attribute(key, level); + + /* open sysfs device directory and print all attributes */ + add_all_attributes(sysfs_dev->path, level); + } + level++; + + sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev); + if (sysfs_dev_parent == NULL) + break; + + //sysfs_close_device(sysfs_dev); + sysfs_dev = sysfs_dev_parent; + } + sysfs_close_device(sysfs_dev); + +exit: + //sysfs_close_class_device(class_dev); + return retval; +} + + +int main(int argc, char *argv[]) { + newtComponent lbox, run, lattr; + newtComponent quit, form, answer; + newtGrid grid, grid2; + char roottext[81]; + char path[NAME_SIZE]; + struct device *dev; + time_t time_last; + int count_last; + + newtInit(); + newtCls(); + + newtWinMessage("udevruler", "Ok", + "This program lets you select a device currently present " + "on the system and you may choose the attributes to uniquely " + "name the device with a udev rule.\n" + "No configuration will be changed, it just prints the rule " + "to place in a udev.rules configuration file. The \"%k\" in the " + "NAME key of the printed rule may be replaced by the name the " + "node should have."); + + init_logging("udevruler"); + udev_init_config(); + get_all_devices(); + + lbox = newtListbox(2, 1, 10, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); + + /* look for last discovered device */ + time_last = 0; + list_for_each_entry(dev, &device_list, list) + if (dev->config_time > time_last) + time_last = dev->config_time; + + /* skip if more than 16 recent devices */ + count_last = 0; + list_for_each_entry(dev, &device_list, list) { + if (dev->config_time < time_last - 10) + continue; + count_last++; + } + + /* add devices up to 10 seconds older than the last one */ + if (count_last < 16) { + newtListboxAppendEntry(lbox, "--- last dicovered ---", NULL); + list_for_each_entry(dev, &device_list, list) { + if (dev->config_time < time_last - 10) + continue; + + dbg("%s %i", dev->name, dev->config_line); + newtListboxAppendEntry(lbox, dev->name, (void*) dev); + dev->added = 1; + } + newtListboxAppendEntry(lbox, "", NULL); + } + + /* add devices not catched by a rule */ + newtListboxAppendEntry(lbox, "--- not configured by a rule ---", NULL); + list_for_each_entry(dev, &device_list, list) { + if (dev->added) + continue; + + if (dev->config_line != 0) + continue; + + dbg("%s %i", dev->name, dev->config_line); + newtListboxAppendEntry(lbox, dev->name, (void*) dev); + dev->added = 1; + } + newtListboxAppendEntry(lbox, "", NULL); + + /* add remaining devices */ + newtListboxAppendEntry(lbox, "--- configured by a rule ---", NULL); + list_for_each_entry(dev, &device_list, list) { + if (dev->added) + continue; + + dbg("%s %i", dev->name, dev->config_line); + newtListboxAppendEntry(lbox, dev->name, (void*) dev); + } + + newtPushHelpLine(" / between elements | Use to select a device"); + snprintf(roottext, sizeof(roottext), "simple udev rule composer, version %s, (c) 2004 can't sleep team", UDEV_VERSION); + roottext[sizeof(roottext)-1] = '\0'; + newtDrawRootText(0, 0, roottext); + + form = newtForm(NULL, NULL, 0); + grid = newtCreateGrid(1, 2); + grid2 = newtButtonBar("Select device", &run, "Quit", &quit, NULL); + newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, lbox, 1, 0, 1, 0, NEWT_ANCHOR_TOP, 0); + newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, grid2, 0, 1, 0, 0, NEWT_ANCHOR_TOP, 0); + newtFormAddComponents(form, lbox, run, quit, NULL); + newtGridWrappedWindow(grid,"Choose the device for which to compose a rule"); + newtGridFree(grid, 1); + + while (1) { + struct attribute *attr; + newtComponent ok, back, form2, answer2, text; + newtGrid grid3, grid4; + int i; + int numitems; + struct attribute **selattr; + char text_rule[80]; + + answer = newtRunForm(form); + if (answer == quit) + break; + + dev = (struct device *) newtListboxGetCurrent(lbox); + if (dev == NULL) + continue; + + if (dev->config_line > 0) + snprintf(text_rule, sizeof(text_rule), + "The device is handled by a rule in the file '%s', line %i.", + dev->config_file, dev->config_line); + else + strcpy(text_rule, "The device was not handled by a rule."); + + strfieldcpy(path, sysfs_path); + strfieldcat(path, dev->devpath); + dbg("look at sysfs device '%s'", path); + get_all_attributes(path); + + grid3 = newtCreateGrid(1, 3); + form2 = newtForm(NULL, NULL, 0); + grid4 = newtButtonBar("Ok", &ok, "Back", &back, NULL); + + lattr = newtListbox(-1, -1, 10, NEWT_FLAG_MULTIPLE | NEWT_FLAG_BORDER | NEWT_FLAG_RETURNEXIT); + list_for_each_entry(attr, &attribute_list, list) + newtListboxAddEntry(lattr, attr->key, (void *) attr); + + text = newtTextbox(-1, -1, 50, 2, NEWT_FLAG_WRAP); + newtTextboxSetText(text, text_rule); + + newtGridSetField(grid3, 0, 0, NEWT_GRID_COMPONENT, lattr, 0, 0, 0, 1, 0, 0); + newtGridSetField(grid3, 0, 1, NEWT_GRID_COMPONENT, text, 0, 0, 0, 1, 0, 0); + newtGridSetField(grid3, 0, 2, NEWT_GRID_SUBGRID, grid4, 0, 1, 0, 0, NEWT_ANCHOR_TOP, 0); + + newtFormAddComponents(form2, text, lattr, ok, back, NULL); + newtGridWrappedWindow(grid3, "Select one ore more attributes within one section with the space bar"); + newtGridFree(grid3, 1); + + while (1) { + char rule[255]; + int onelevel; + int skipped; + + answer2 = newtRunForm(form2); + if (answer2 == back) + break; + + selattr = (struct attribute **) newtListboxGetSelection(lattr, &numitems); + if (selattr == NULL) + continue; + + rule[0] = '\0'; + onelevel = -1; + skipped = 0; + for (i = 0; i < numitems; i++) { + if (selattr[i]->key[0] == '\0') + continue; + + if (onelevel != -1) { + if (onelevel != selattr[i]->level) { + skipped = 1; + continue; + } + } else { + onelevel = selattr[i]->level; + } + + dbg("'%s'\n", selattr[i]->key); + strfieldcat(rule, selattr[i]->key); + strfieldcat(rule, ", "); + } + if (skipped) { + newtWinMessage("error", "Ok", "Please select only attributes within one section"); + continue; + } + + if (strlen(rule) > 200) { + newtWinMessage("error", "Ok", "The line is too long, please select fewer attributes."); + } else { + if (rule[0] == '\0') + continue; + + strfieldcat(rule, "NAME=\"%k\""); + newtWinMessage("the rule to place in config file", "Ok", rule); + } + } + + newtPopWindow(); + } + + newtPopWindow(); + newtFormDestroy(form); + newtFinished(); + return 0; +} From 93e6b62cbd2ddcd2550f6ea6fb9733b0758146ae Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 23 Mar 2004 18:43:49 -0800 Subject: [PATCH 0675/4284] [PATCH] fix 'make spotless' to really do that in klibc. bah, this took me forever to figure out why I couldn't build with klibc on on box... --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 3d5288b25d..b51b5a6acc 100644 --- a/Makefile +++ b/Makefile @@ -313,6 +313,7 @@ clean: done ; \ spotless: clean + $(MAKE) -C klibc spotless DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz$" -e "\/\." -e releases -e BitKeeper -e SCCS -e "\.tdb$" -e test/sys | sort ) DISTDIR := $(RELEASE_NAME) From fdcfcec707ab48a5285d675412820d4320382e92 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 23 Mar 2004 18:49:56 -0800 Subject: [PATCH 0676/4284] [PATCH] 022_bk tag --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index b51b5a6acc..bd511a83ae 100644 --- a/Makefile +++ b/Makefile @@ -37,7 +37,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 022 +VERSION = 022_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 7de035c86e..017affbc36 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 022 +Version: 022_bk Release: 1 License: GPL Group: Utilities/System From 4474484153f529c1a1c11392e8fc3fa8a588de54 Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Tue, 23 Mar 2004 18:52:52 -0800 Subject: [PATCH 0677/4284] [PATCH] uninitialized variable for mknod and friend mknod gets an uninitialized variable, which leads to interesting file modes. the bug is in namedev, devices with no match must not use the uninitialized stuff were dev points to. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index e075e20af5..6606ce8f79 100644 --- a/namedev.c +++ b/namedev.c @@ -843,12 +843,12 @@ found: strfieldcpy(udev->config_file, dev->config_file); udev->config_line = dev->config_line; -done: /* get permissions given in rule */ set_empty_perms(udev, dev->mode, dev->owner, dev->group); +done: /* get permissions given in config file or set defaults */ perm = find_perm(udev->name); if (perm != NULL) { From 2a94c8777eacff16821a06368092852f7b42882f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Mar 2004 18:54:34 -0800 Subject: [PATCH 0678/4284] [PATCH] don't init namedev on remove Is there any reason to parse the rules for a remove event? Without it, our test script needs only 2.1 seconds instead of 2.5, so we have 19 percent more time for testing now :) --- udev.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/udev.c b/udev.c index d10badc8ea..1220e637e5 100644 --- a/udev.c +++ b/udev.c @@ -140,19 +140,18 @@ static int udev_hotplug(void) sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); - /* initialize the naming deamon */ - namedev_init(); - - if (strcmp(action, "add") == 0) + if (strcmp(action, "add") == 0) { + namedev_init(); retval = udev_add_device(devpath, subsystem, 0); - - else if (strcmp(action, "remove") == 0) - retval = udev_remove_device(devpath, subsystem); - - else { - dbg("unknown action '%s'", action); - retval = -EINVAL; + } else { + if (strcmp(action, "remove") == 0) { + retval = udev_remove_device(devpath, subsystem); + } else { + dbg("unknown action '%s'", action); + retval = -EINVAL; + } } + udevdb_exit(); exit_sysbus: From ddd5b5dc4890d40b7ed412e9de52b33e62447f78 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 24 Mar 2004 17:34:00 -0800 Subject: [PATCH 0679/4284] [PATCH] correct apply_format() for symlink only rules Patch from Andrey, which restores the ability to use RESULT values in a "symlink only" rule. We need to call apply_format() directly after the matching rule, otherwise the RESULT value may be lost. --- namedev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 6606ce8f79..98529cb840 100644 --- a/namedev.c +++ b/namedev.c @@ -816,11 +816,15 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } if (dev->symlink[0] != '\0') { + char temp[NAMESIZE]; + info("configured rule in '%s' at line %i applied, added symlink '%s'", dev->config_file, dev->config_line, dev->symlink); + strfieldcpy(temp, dev->symlink); + apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); if (udev->symlink[0] != '\0') strfieldcat(udev->symlink, " "); - strfieldcat(udev->symlink, dev->symlink); + strfieldcat(udev->symlink, temp); } if (dev->name[0] != '\0') { @@ -838,7 +842,6 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud found: apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - apply_format(udev, udev->symlink, sizeof(udev->symlink), class_dev, sysfs_device); udev->partitions = dev->partitions; strfieldcpy(udev->config_file, dev->config_file); udev->config_line = dev->config_line; From a291a14b9062339134c561453cfbb2409713582d Mon Sep 17 00:00:00 2001 From: "dsteklof@us.ibm.com" Date: Wed, 24 Mar 2004 17:34:38 -0800 Subject: [PATCH 0680/4284] [PATCH] udevinfo patch I think this is what you want for udevinfo. Patched against the latest BK tree. I tested it and it seemed to work. One other question, shouldn't udevinfo.c:print_all_attributes() check to make sure attr->method is SYSFS_METHOD_SHOW along with checking to see if attr->value != NULL or doesn't that matter? Here's the libsysfs fix for print_device_chain(): --- udevinfo.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index dc3f94fffe..800882eb1a 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -161,7 +161,6 @@ static int print_device_chain(const char *path) "to match the device for which the node will be created.\n" "\n"); printf("device '%s' has major:minor %s", class_dev->path, attr->value); - sysfs_close_attribute(attr); /* open sysfs class device directory and print all attributes */ printf(" looking at class device '%s':\n", class_dev->path); @@ -173,11 +172,11 @@ static int print_device_chain(const char *path) /* get the device link (if parent exists look here) */ class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) { - //sysfs_close_class_device(class_dev); - class_dev = class_dev_parent; - } - sysfs_dev = sysfs_get_classdev_device(class_dev); + if (class_dev_parent != NULL) + sysfs_dev = sysfs_get_classdev_device(class_dev_parent); + else + sysfs_dev = sysfs_get_classdev_device(class_dev); + if (sysfs_dev != NULL) printf("follow the class device's \"device\"\n"); @@ -194,13 +193,11 @@ static int print_device_chain(const char *path) if (sysfs_dev_parent == NULL) break; - //sysfs_close_device(sysfs_dev); sysfs_dev = sysfs_dev_parent; } - sysfs_close_device(sysfs_dev); exit: - //sysfs_close_class_device(class_dev); + sysfs_close_class_device(class_dev); return retval; } From 615ba3e82b2e49e06bbf9ad3e6a8ab6f0446ee26 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 17:50:40 -0800 Subject: [PATCH 0681/4284] [PATCH] fix build error in namedev.c caused by previous patch. --- namedev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 98529cb840..b9d8a3db2c 100644 --- a/namedev.c +++ b/namedev.c @@ -816,7 +816,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } if (dev->symlink[0] != '\0') { - char temp[NAMESIZE]; + char temp[NAME_SIZE]; info("configured rule in '%s' at line %i applied, added symlink '%s'", dev->config_file, dev->config_line, dev->symlink); From dd64e26b0c88892b367f57c4c7a7484e35641c7c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 20:46:58 -0800 Subject: [PATCH 0682/4284] [PATCH] add /etc/dev.d/ support for udev add and remove events. --- Makefile | 1 + dev_d.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ udev-add.c | 4 +- udev-remove.c | 1 + udev.h | 1 + 5 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 dev_d.c diff --git a/Makefile b/Makefile index bd511a83ae..f20337bb54 100644 --- a/Makefile +++ b/Makefile @@ -209,6 +209,7 @@ OBJS = udev_lib.o \ udevdb.o \ namedev.o \ namedev_parse.o \ + dev_d.o \ $(SYSFS) \ $(TDB) diff --git a/dev_d.c b/dev_d.c new file mode 100644 index 0000000000..36bee33bd9 --- /dev/null +++ b/dev_d.c @@ -0,0 +1,117 @@ +/* + * dev.d multipleer + * + * Copyright (C) 2004 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. + * + * Based on the klibc version of hotplug written by: + * Author(s) Christian Borntraeger + * which was based on the shell script written by: + * Greg Kroah-Hartman + * + */ + +/* + * This essentially emulates the following shell script logic in C: + DIR="/etc/dev.d" + export DEVNODE="whatever_dev_name_udev_just_gave" + for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do + if [ -f $I ]; then $I $1 ; fi + done + exit 1; + */ + +#include +#include +#include +#include +#include +#include +#include +#include "udev.h" +#include "udev_lib.h" +#include "logging.h" + +#define HOTPLUGDIR "/etc/dev.d" +#define COMMENT_PREFIX '#' + +static void run_program(char *name) +{ + pid_t pid; + + dbg("running %s", name); + + pid = fork(); + + if (pid < 0) { + perror("fork"); + return; + } + + if (pid > 0) { + wait(NULL); + return; + } + + execv(name, main_argv); + exit(1); +} + +static void execute_dir (char *dirname) +{ + DIR *directory; + struct dirent *entry; + char filename[256]; + + dbg("opening %s", dirname); + directory = opendir(dirname); + if (!directory) + return; + + while ((entry = readdir(directory))) { + if (entry->d_name[0] == '\0') + break; + /* Don't run the files '.', '..', or hidden files, + * or files that start with a '#' */ + if ((entry->d_name[0] == '.') || + (entry->d_name[0] == COMMENT_PREFIX)) + continue; + + /* FIXME - need to use file_list_insert() here to run these in sorted order... */ + snprintf(filename, sizeof(filename), "%s%s", dirname, entry->d_name); + filename[sizeof(filename)-1] = '\0'; + run_program(filename); + } + + closedir(directory); +} + +/* runs files in these directories in order: + * name given by udev + * subsystem + * default + */ +void dev_d_send(struct udevice *dev, char *subsystem) +{ + char dirname[256]; + char devnode[NAME_SIZE]; + + strfieldcpy(devnode, udev_root); + strfieldcat(devnode, dev->name); + setenv("DEVNODE", devnode, 1); + + snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", dev->name); + dirname[sizeof(dirname)-1] = '\0'; + execute_dir(dirname); + + snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", subsystem); + dirname[sizeof(dirname)-1] = '\0'; + execute_dir(dirname); + + strcpy(dirname, HOTPLUGDIR "/default/"); + execute_dir(dirname); +} + diff --git a/udev-add.c b/udev-add.c index 2bd16014f5..94a423dc6e 100644 --- a/udev-add.c +++ b/udev-add.c @@ -417,8 +417,10 @@ int udev_add_device(char *path, char *subsystem, int fake) dbg("name='%s'", dev.name); retval = create_node(&dev, fake); - if ((retval == 0) && (!fake)) + if ((retval == 0) && (!fake)) { + dev_d_send(&dev, subsystem); sysbus_send_create(&dev, path); + } exit: if (class_dev) diff --git a/udev-remove.c b/udev-remove.c index d909713450..dc6fcfc331 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -150,6 +150,7 @@ int udev_remove_device(char *path, char *subsystem) dbg("name is '%s'", dev.name); udevdb_delete_dev(path); + dev_d_send(&dev, subsystem); sysbus_send_remove(dev.name, path); retval = delete_node(&dev); diff --git a/udev.h b/udev.h index 16a212cd2c..eb42edce10 100644 --- a/udev.h +++ b/udev.h @@ -65,6 +65,7 @@ extern int udev_add_device(char *path, char *subsystem, int fake); extern int udev_remove_device(char *path, char *subsystem); extern void udev_init_config(void); extern int parse_get_pair(char **orig_string, char **left, char **right); +extern void dev_d_send(struct udevice *dev, char *subsystem); extern char **main_argv; extern char **main_envp; From 7e371e86a420cb82948b72ca3dd93915cb8dd764 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:11:13 -0800 Subject: [PATCH 0683/4284] [PATCH] remove dbus code from core udev code as it's no longer needed to be there. --- udev-add.c | 5 +---- udev-remove.c | 2 -- udev.c | 11 +---------- udev_dbus.h | 23 ----------------------- 4 files changed, 2 insertions(+), 39 deletions(-) delete mode 100644 udev_dbus.h diff --git a/udev-add.c b/udev-add.c index 94a423dc6e..369ea82b6c 100644 --- a/udev-add.c +++ b/udev-add.c @@ -39,7 +39,6 @@ #include "udev.h" #include "udev_lib.h" #include "udev_version.h" -#include "udev_dbus.h" #include "udev_selinux.h" #include "logging.h" #include "namedev.h" @@ -417,10 +416,8 @@ int udev_add_device(char *path, char *subsystem, int fake) dbg("name='%s'", dev.name); retval = create_node(&dev, fake); - if ((retval == 0) && (!fake)) { + if ((retval == 0) && (!fake)) dev_d_send(&dev, subsystem); - sysbus_send_create(&dev, path); - } exit: if (class_dev) diff --git a/udev-remove.c b/udev-remove.c index dc6fcfc331..41636b684e 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -31,7 +31,6 @@ #include "udev.h" #include "udev_lib.h" #include "udev_version.h" -#include "udev_dbus.h" #include "logging.h" #include "namedev.h" #include "udevdb.h" @@ -151,7 +150,6 @@ int udev_remove_device(char *path, char *subsystem) udevdb_delete_dev(path); dev_d_send(&dev, subsystem); - sysbus_send_remove(dev.name, path); retval = delete_node(&dev); return retval; diff --git a/udev.c b/udev.c index 1220e637e5..52b98c8d45 100644 --- a/udev.c +++ b/udev.c @@ -32,7 +32,6 @@ #include "udev.h" #include "udev_lib.h" #include "udev_version.h" -#include "udev_dbus.h" #include "logging.h" #include "namedev.h" #include "udevdb.h" @@ -61,7 +60,6 @@ static void sig_handler(int signum) switch (signum) { case SIGINT: case SIGTERM: - sysbus_disconnect(); udevdb_exit(); exit(20 + signum); default: @@ -123,14 +121,11 @@ static int udev_hotplug(void) i++; } - /* connect to the system message bus */ - sysbus_connect(); - /* initialize udev database */ retval = udevdb_init(UDEVDB_DEFAULT); if (retval != 0) { dbg("unable to initialize database"); - goto exit_sysbus; + goto exit; } /* set up a default signal handler for now */ @@ -154,10 +149,6 @@ static int udev_hotplug(void) udevdb_exit(); -exit_sysbus: - /* disconnect from the system message bus */ - sysbus_disconnect(); - exit: if (retval > 0) retval = 0; diff --git a/udev_dbus.h b/udev_dbus.h deleted file mode 100644 index afa2046548..0000000000 --- a/udev_dbus.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef UDEV_DBUS_H -#define UDEV_DBUS_H - - -#ifdef USE_DBUS - -extern void sysbus_connect(void); -extern void sysbus_disconnect(void); -extern void sysbus_send_create(struct udevice *dev, const char *path); -extern void sysbus_send_remove(const char* name, const char *path); - -#else - -static inline void sysbus_connect(void) { } -static inline void sysbus_disconnect(void) { } -static inline void sysbus_send_create(struct udevice *dev, const char *path) { } -static inline void sysbus_send_remove(const char* name, const char *path) { } - -#endif /* USE_DBUS */ - - - -#endif From 89fe4e00fe0ac4b5125a3a66ffe3d42366feb5da Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:11:36 -0800 Subject: [PATCH 0684/4284] [PATCH] add get_devnode() helper to udev_lib for udev_dbus program --- udev_lib.c | 11 +++++++++++ udev_lib.h | 1 + 2 files changed, 12 insertions(+) diff --git a/udev_lib.c b/udev_lib.c index 50598a4a31..f095513c97 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -53,6 +53,17 @@ char *get_devpath(void) return devpath; } +char *get_devnode(void) +{ + char *devnode; + + devnode = getenv("DEVNODE"); + if (devnode != NULL && strlen(devnode) > NAME_SIZE) + devnode[NAME_SIZE-1] = '\0'; + + return devnode; +} + char *get_seqnum(void) { char *seqnum; diff --git a/udev_lib.h b/udev_lib.h index 565d87e9a5..5db6b5261a 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -68,6 +68,7 @@ do { \ extern char *get_action(void); extern char *get_devpath(void); +extern char *get_devnode(void); extern char *get_seqnum(void); extern char *get_subsystem(char *subsystem); extern int file_map(const char *filename, char **buf, size_t *bufsize); From 3bfbe50bd85feb2b26327032dc5fb68773cc785f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:12:10 -0800 Subject: [PATCH 0685/4284] [PATCH] first cut at standalone udev_dbus program. Will not work, need to finish working on this on a system with dbus installed... --- udev_dbus.c | 89 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 22 deletions(-) diff --git a/udev_dbus.c b/udev_dbus.c index 7b672ef363..a031a41101 100644 --- a/udev_dbus.c +++ b/udev_dbus.c @@ -14,6 +14,20 @@ #include "udev_dbus.h" #include "logging.h" +#ifdef LOG +unsigned char logname[LOGNAME_SIZE]; +void log_message(int level, const char *format, ...) +{ + va_list args; + + if (!udev_log) + return; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif /** variable for the connection the to system message bus or #NULL * if we cannot connect or acquire the org.kernel.udev service @@ -21,7 +35,7 @@ static DBusConnection* sysbus_connection; /** Disconnect from the system message bus */ -void sysbus_disconnect(void) +static void sysbus_disconnect(void) { if (sysbus_connection == NULL) return; @@ -31,7 +45,7 @@ void sysbus_disconnect(void) } /** Connect to the system message bus */ -void sysbus_connect(void) +static void sysbus_connect(void) { DBusError error; @@ -68,28 +82,21 @@ void sysbus_connect(void) /** Send out a signal that a device node is created * - * @param dev udevice object + * @param devnode name of the device node, e.g. /dev/sda1 * @param path Sysfs path of device */ -void sysbus_send_create(struct udevice *dev, const char *path) +static void sysbus_send_create(const char *devnode, const char *path) { - char filename[255]; DBusMessage* message; DBusMessageIter iter; - if (sysbus_connection == NULL) - return; - - strfieldcpy(filename, udev_root); - strfieldcat(filename, dev->name); - /* object, interface, member */ message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", "org.kernel.udev.NodeMonitor", "NodeCreated"); dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, devnode); dbus_message_iter_append_string(&iter, path); if ( !dbus_connection_send(sysbus_connection, message, NULL) ) @@ -102,28 +109,21 @@ void sysbus_send_create(struct udevice *dev, const char *path) /** Send out a signal that a device node is deleted * - * @param name Name of the device node, e.g. /udev/sda1 + * @param devnode Name of the device node, e.g. /udev/sda1 * @param path Sysfs path of device */ -void sysbus_send_remove(const char* name, const char *path) +static void sysbus_send_remove(const char *devnode, const char *path) { - char filename[255]; DBusMessage* message; DBusMessageIter iter; - if (sysbus_connection == NULL) - return; - - strfieldcpy(filename, udev_root); - strfieldcat(filename, name); - /* object, interface, member */ message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", "org.kernel.udev.NodeMonitor", "NodeDeleted"); dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, filename); + dbus_message_iter_append_string(&iter, devnode); dbus_message_iter_append_string(&iter, path); if ( !dbus_connection_send(sysbus_connection, message, NULL) ) @@ -133,3 +133,48 @@ void sysbus_send_remove(const char* name, const char *path) dbus_connection_flush(sysbus_connection); } + +int main(int argc, char *argv[], char *envp[]) +{ + char *action; + char *devpath; + char *devnode; + int retval = 0; + + init_logging("udev_dbus"); + + sysbus_connect(); + if (sysbus_connection == NULL) + return; + + action = get_action(); + if (!action) { + dbg("no action?"); + goto exit; + } + devpath = get_devpath(); + if (!devpath) { + dbg("no devpath?"); + goto exit; + } + devnode = get_devnode(); + if (!devnode) { + dbg("no devnode?"); + goto exit; + } + + if (strcmp(action, "add") == 0) { + sysbus_send_create(devnode, devpath); + } else { + if (strcmp(action, "remove") == 0) { + sysbus_send_remove(devnode, devpath); + } else { + dbg("unknown action '%s'", action); + retval = -EINVAL; + } + } + +exit: + sysbus_disconnect(); + return retval; +} From eddf1bca24d49055aa409315fd218561005fba07 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:14:08 -0800 Subject: [PATCH 0686/4284] [PATCH] remove selinux support from udev core as it's no longer needed. --- udev-add.c | 4 ---- udev_selinux.h | 10 ---------- 2 files changed, 14 deletions(-) delete mode 100644 udev_selinux.h diff --git a/udev-add.c b/udev-add.c index 369ea82b6c..aef755442f 100644 --- a/udev-add.c +++ b/udev-add.c @@ -39,7 +39,6 @@ #include "udev.h" #include "udev_lib.h" #include "udev_version.h" -#include "udev_selinux.h" #include "logging.h" #include "namedev.h" #include "udevdb.h" @@ -277,9 +276,6 @@ static int create_node(struct udevice *dev, int fake) } } - if (!fake) - selinux_add_node(filename); - /* create symlink if requested */ foreach_strpart(dev->symlink, " ", pos, len) { strfieldcpymax(linkname, pos, len+1); diff --git a/udev_selinux.h b/udev_selinux.h deleted file mode 100644 index 77a1f36bd9..0000000000 --- a/udev_selinux.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef UDEV_SELINUX_H -#define UDEV_SELINUX_H - -#ifdef USE_SELINUX -extern void selinux_add_node(char *filename); -#else -static void selinux_add_node(char *filename) { } -#endif - -#endif From b528cd49203c64cf117868b5a5907cb11d934bbb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:18:36 -0800 Subject: [PATCH 0687/4284] [PATCH] first cut at standalone udev_selinux program. Will not work, need to finish working on this on a system with selinux installed... --- udev_selinux.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/udev_selinux.c b/udev_selinux.c index 3728fd0b50..723af9a02f 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -8,10 +8,23 @@ #include #include "udev.h" -#include "udev_version.h" -#include "udev_selinux.h" +#include "udev_lib.h" #include "logging.h" +#ifdef LOG +unsigned char logname[LOGNAME_SIZE]; +void log_message(int level, const char *format, ...) +{ + va_list args; + + if (!udev_log) + return; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif void selinux_add_node(char *filename) { @@ -32,3 +45,29 @@ void selinux_add_node(char *filename) } } +int main(int argc, char *argv[], char *envp[]) +{ + char *action; + char *devpath; + char *devnode; + int retval = 0; + + init_logging("udev_selinux"); + + action = get_action(); + if (!action) { + dbg("no action?"); + goto exit; + } + devnode = get_devnode(); + if (!devnode) { + dbg("no devnode?"); + goto exit; + } + + if (strcmp(action, "add") == 0) + selinux_add_node(devnode); + +exit: + return retval; +} From ddc8f83132368098e63634dd355cde7d787fc85c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:21:21 -0800 Subject: [PATCH 0688/4284] [PATCH] remove udev_dbus.h from Makefile --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index f20337bb54..219ce2cbf0 100644 --- a/Makefile +++ b/Makefile @@ -217,7 +217,6 @@ HEADERS = udev.h \ udev_lib.h \ namedev.h \ udev_version.h \ - udev_dbus.h \ udevdb.h \ klibc_fixups.h \ logging.h \ From c5039077b710dca041b2b36a3fc3247964abc069 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:23:42 -0800 Subject: [PATCH 0689/4284] [PATCH] udev_dbus can now compile properly, but linnking is another story... --- udev_dbus.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/udev_dbus.c b/udev_dbus.c index a031a41101..7e767040f0 100644 --- a/udev_dbus.c +++ b/udev_dbus.c @@ -10,8 +10,7 @@ #include #include "udev.h" -#include "udev_version.h" -#include "udev_dbus.h" +#include "udev_lib.h" #include "logging.h" #ifdef LOG @@ -145,7 +144,7 @@ int main(int argc, char *argv[], char *envp[]) sysbus_connect(); if (sysbus_connection == NULL) - return; + return 0; action = get_action(); if (!action) { From 357f44a534e5e32e52020121c983aca90ae7ac1b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:37:34 -0800 Subject: [PATCH 0690/4284] [PATCH] move udev_dbus to extras/dbus Should build now, but might have linking problems. --- extras/dbus/Makefile | 63 +++++++++++++++++++ .../dbus-1/system.d/udev_sysbus_policy.conf | 0 udev_dbus.c => extras/dbus/udev_dbus.c | 5 +- 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 extras/dbus/Makefile rename {etc => extras/dbus/etc}/dbus-1/system.d/udev_sysbus_policy.conf (100%) rename udev_dbus.c => extras/dbus/udev_dbus.c (98%) diff --git a/extras/dbus/Makefile b/extras/dbus/Makefile new file mode 100644 index 0000000000..99aa33d8fb --- /dev/null +++ b/extras/dbus/Makefile @@ -0,0 +1,63 @@ +# Makefile for udev_dbus +# +# Copyright (C) 2004 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. +# + +# Set the following to `true' to log the debug +# and make a unstripped, unoptimized binary. +# Leave this set to `false' for production use. +DEBUG = false + +PROG = udev_dbus + +all: $(PROG) + +# override this to make udev look in a different location for it's config files +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +mandir = ${prefix}/usr/share/man +hotplugdir = ${etcdir}/hotplug.d/default +dbusdir = ${etcdir}/dbus-1/system.d +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +override CFLAGS+=-Wall -fno-builtin + +override CFLAGS += -DUSE_DBUS +override CFLAGS += $(shell pkg-config --cflags dbus-1) +override LDFLAGS += $(shell pkg-config --libs dbus-1) +OBJS = udev_dbus.o + +$(PROG): $(OBJS) + $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) ../../udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + + +install-dbus-policy: + $(INSTALL) -d $(DESTDIR)$(dbusdir) + $(INSTALL_DATA) etc/dbus-1/system.d/udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) + +uninstall-dbus-policy: + - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf + +install: install-dbus-policy all + +uninstall: uninstall-dbus-policy + diff --git a/etc/dbus-1/system.d/udev_sysbus_policy.conf b/extras/dbus/etc/dbus-1/system.d/udev_sysbus_policy.conf similarity index 100% rename from etc/dbus-1/system.d/udev_sysbus_policy.conf rename to extras/dbus/etc/dbus-1/system.d/udev_sysbus_policy.conf diff --git a/udev_dbus.c b/extras/dbus/udev_dbus.c similarity index 98% rename from udev_dbus.c rename to extras/dbus/udev_dbus.c index 7e767040f0..955a3dbb49 100644 --- a/udev_dbus.c +++ b/extras/dbus/udev_dbus.c @@ -9,9 +9,8 @@ #define DBUS_API_SUBJECT_TO_CHANGE #include -#include "udev.h" -#include "udev_lib.h" -#include "logging.h" +#include "../../udev_lib.h" +#include "../../logging.h" #ifdef LOG unsigned char logname[LOGNAME_SIZE]; From 886069394932f45b43d400289c2761600aa0727b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:39:33 -0800 Subject: [PATCH 0691/4284] [PATCH] remove dbus stuff from main Makefile Not needed now that it's in extras. --- Makefile | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/Makefile b/Makefile index 219ce2cbf0..65d870bf97 100644 --- a/Makefile +++ b/Makefile @@ -25,10 +25,6 @@ USE_LOG = true # Leave this set to `false' for production use. DEBUG = false -# Set the following to `true' to make udev emit a D-BUS signal when a -# new node is created. -USE_DBUS = false - ROOT = udev DAEMON = udevd @@ -55,7 +51,6 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin mandir = ${prefix}/usr/share/man hotplugdir = ${etcdir}/hotplug.d/default -dbusdir = ${etcdir}/dbus-1/system.d configdir = ${etcdir}/udev/ initdir = ${etcdir}/init.d/ srcdir = . @@ -226,13 +221,6 @@ ifeq ($(strip $(USE_KLIBC)),true) OBJS += klibc_fixups.o endif -ifeq ($(USE_DBUS), true) - CFLAGS += -DUSE_DBUS - CFLAGS += $(shell pkg-config --cflags dbus-1) - LDFLAGS += $(shell pkg-config --libs dbus-1) - OBJS += udev_dbus.o -endif - # if USE_SELINUX is enabled, then we do not strip or optimize ifeq ($(strip $(USE_SELINUX)),true) CFLAGS += -DUSE_SELINUX @@ -345,20 +333,6 @@ small_release: $(DISTFILES) clean @echo "Built $(RELEASE_NAME).tar.gz" -ifeq ($(USE_DBUS), true) -install-dbus-policy: - $(INSTALL) -d $(DESTDIR)$(dbusdir) - $(INSTALL_DATA) etc/dbus-1/system.d/udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) - -uninstall-dbus-policy: - - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf -else -install-dbus-policy: - - -uninstall-dbus-policy: - - -endif - install-initscript: etc/init.d/udev etc/init.d/udev.debian etc/init.d/udev.init.LSB @if [ -f /etc/redhat-release ]; then \ $(INSTALL_DATA) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ @@ -383,7 +357,7 @@ install-config: $(GEN_CONFIGS) $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ fi -install: install-initscript install-config install-dbus-policy all +install: install-initscript install-config all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) @@ -409,7 +383,7 @@ endif -C $$target $@ ; \ done ; \ -uninstall: uninstall-dbus-policy +uninstall: - rm $(hotplugdir)/udev.hotplug - rm $(configdir)/udev.permissions - rm $(configdir)/udev.rules From 6fb7313bad16334c4b7bc742ee8cc9416ed1d78e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 21:42:40 -0800 Subject: [PATCH 0692/4284] [PATCH] fix dbus build in the udev.spec file. --- udev.spec | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/udev.spec b/udev.spec index 017affbc36..a0cd75a608 100644 --- a/udev.spec +++ b/udev.spec @@ -11,11 +11,6 @@ # Note, it is not recommend if you use klibc to enable logging. %define log 0 -# if we want to build DBUS support in or not. -# 0 - no DBUS support -# 1 - DBUS support -%define dbus 0 - # if we want to build SELinux support in or not. # 0 - no SELinux support # 1 - SELinux support @@ -27,6 +22,11 @@ # 1 - debugging enabled %define debug 0 +# if we want to build the DBUS "extra package or not +# 0 - no DBUS support +# 1 - DBUS support +%define dbus 0 + # if we want to build the scsi_id "extra" package or not # 0 - do not build the package # 1 - build it @@ -62,11 +62,6 @@ make CC="gcc $RPM_OPT_FLAGS" \ %else USE_LOG=false \ %endif -%if %{dbus} - USE_DBUS=true \ -%else - USE_DBUS=false \ -%endif %if %{selinux} USE_SELINUX=true \ %else @@ -81,15 +76,13 @@ make CC="gcc $RPM_OPT_FLAGS" \ %if %{scsi_id} extras/scsi_id \ %endif +%if %{dbus} + extras/dbus \ +%endif " %install make DESTDIR=$RPM_BUILD_ROOT install \ -%if %{dbus} - USE_DBUS=true \ -%else - USE_DBUS=false \ -%endif %if %{selinux} USE_SELINUX=true \ %else @@ -99,6 +92,9 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %if %{scsi_id} extras/scsi_id \ %endif +%if %{dbus} + extras/dbus \ +%endif " %post @@ -143,6 +139,9 @@ rm -rf $RPM_BUILD_ROOT %endif %changelog +* Wed Mar 24 2004 Greg Kroah-Hartman +- change the way dbus support is built (now an extra) + * Tue Mar 2 2004 Greg Kroah-Hartman - added udevstart to the list of files installed - udevinfo is now in /usr/bin not /sbin From 0384e43ad9cfb85cc32ab926d1780a05ca3ab1dc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 22:41:45 -0800 Subject: [PATCH 0693/4284] [PATCH] move udev_selinux into extras/selinux --- extras/selinux/Makefile | 59 +++++++++++++++++++ .../selinux/udev_selinux.c | 5 +- 2 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 extras/selinux/Makefile rename udev_selinux.c => extras/selinux/udev_selinux.c (95%) diff --git a/extras/selinux/Makefile b/extras/selinux/Makefile new file mode 100644 index 0000000000..813756700b --- /dev/null +++ b/extras/selinux/Makefile @@ -0,0 +1,59 @@ +# Makefile for udev_selinux +# +# Copyright (C) 2004 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. +# + +# Set the following to control the use of syslog +# Set it to `false' to remove all logging +USE_LOG = true + +# Set the following to `true' to log the debug +# and make a unstripped, unoptimized binary. +# Leave this set to `false' for production use. +DEBUG = false + +PROG = udev_selinux + +DESTDIR = + +# override this to make udev look in a different location for it's config files +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +mandir = ${prefix}/usr/share/man +hotplugdir = ${etcdir}/hotplug.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +all: $(PROG) + +OBJS = udev_selinux.o + +override CFLAGS += -DUSE_SELINUX +override LIB_OBJS += -lselinux + +$(PROG): $(OBJS) + $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) ../../udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + + +install: all + +uninstall: + diff --git a/udev_selinux.c b/extras/selinux/udev_selinux.c similarity index 95% rename from udev_selinux.c rename to extras/selinux/udev_selinux.c index 723af9a02f..bbbdd6ba53 100644 --- a/udev_selinux.c +++ b/extras/selinux/udev_selinux.c @@ -7,9 +7,8 @@ #include #include -#include "udev.h" -#include "udev_lib.h" -#include "logging.h" +#include "../../udev_lib.h" +#include "../../logging.h" #ifdef LOG unsigned char logname[LOGNAME_SIZE]; From 7e2fb86463fd6f09125d73c5eb110842511ad04e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 22:46:29 -0800 Subject: [PATCH 0694/4284] [PATCH] remove selinux stuff from the main Makefile --- Makefile | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Makefile b/Makefile index 65d870bf97..4481ee1bfa 100644 --- a/Makefile +++ b/Makefile @@ -221,14 +221,6 @@ ifeq ($(strip $(USE_KLIBC)),true) OBJS += klibc_fixups.o endif -# if USE_SELINUX is enabled, then we do not strip or optimize -ifeq ($(strip $(USE_SELINUX)),true) - CFLAGS += -DUSE_SELINUX - OBJS += udev_selinux.o - LIB_OBJS += -lselinux -endif - - # header files automatically generated GEN_HEADERS = udev_version.h From 5476249ffd3239cbfad91999db3917dc292b158f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 22:47:15 -0800 Subject: [PATCH 0695/4284] [PATCH] remove USE_DBUS and USE_SELINUX flags from the README as they are no longer present. --- README | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/README b/README index 75d642c942..508566b50a 100644 --- a/README +++ b/README @@ -44,16 +44,6 @@ To use: what udev is doing. This is enabled by default. Note, if you are building udev against klibc it is recommended that you disable this option (due to klibc's syslog implementation.) - USE_DBUS - if set to 'true', DBUS messages will be sent everytime udev - creates or removes a device node. This requires that DBUS - development headers and libraries be present on your system to - build properly. Default value is 'false'. - USE_SELINUX - if set to 'true', SELinux support for udev will be built in. - This requires that SELinux development headers and libraries be - present on your system to build properly. Default value is - 'false'. DEBUG if set to 'true', debugging messages will be sent to the syslog as udev is run. Default value is 'false'. @@ -98,8 +88,3 @@ know by sending a message to the linux-hotplug-devel mailing list at: greg k-h greg@kroah.com - - - - - From b658bc09a1ae34f57d7719ecad74caf571d5cdf8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 22:49:03 -0800 Subject: [PATCH 0696/4284] [PATCH] fixed up udev.spec to handle selinux stuff properly now. --- udev.spec | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/udev.spec b/udev.spec index a0cd75a608..8e6c16d6b2 100644 --- a/udev.spec +++ b/udev.spec @@ -11,22 +11,22 @@ # Note, it is not recommend if you use klibc to enable logging. %define log 0 -# if we want to build SELinux support in or not. -# 0 - no SELinux support -# 1 - SELinux support -%define selinux 0 - # if we want to enable debugging support in udev. If it is enabled, lots of # stuff will get sent to the debug syslog. # 0 - debugging disabled # 1 - debugging enabled %define debug 0 -# if we want to build the DBUS "extra package or not +# if we want to build the DBUS "extra" package or not # 0 - no DBUS support # 1 - DBUS support %define dbus 0 +# if we want to build the SELinux "extra" package or not +# 0 - no SELinux support +# 1 - SELinux support +%define selinux 0 + # if we want to build the scsi_id "extra" package or not # 0 - do not build the package # 1 - build it @@ -62,11 +62,6 @@ make CC="gcc $RPM_OPT_FLAGS" \ %else USE_LOG=false \ %endif -%if %{selinux} - USE_SELINUX=true \ -%else - USE_SELINUX=false \ -%endif %if %{debug} DEBUG=true \ %else @@ -79,15 +74,13 @@ make CC="gcc $RPM_OPT_FLAGS" \ %if %{dbus} extras/dbus \ %endif +%if %{selinux} + extras/selinux \ +%endif " %install make DESTDIR=$RPM_BUILD_ROOT install \ -%if %{selinux} - USE_SELINUX=true \ -%else - USE_SELINUX=false \ -%endif EXTRAS=" \ %if %{scsi_id} extras/scsi_id \ @@ -95,6 +88,9 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %if %{dbus} extras/dbus \ %endif +%if %{selinux} + extras/selinux \ +%endif " %post @@ -140,7 +136,7 @@ rm -rf $RPM_BUILD_ROOT %changelog * Wed Mar 24 2004 Greg Kroah-Hartman -- change the way dbus support is built (now an extra) +- change the way dbus and selinux support is built (now an extra) * Tue Mar 2 2004 Greg Kroah-Hartman - added udevstart to the list of files installed From 3e33961b4557f9b709c901b4aa77dfe0220222bd Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 23:11:08 -0800 Subject: [PATCH 0697/4284] [PATCH] added RFC-dev.d document detailing how /etc/dev.d/ works. --- docs/RFC-dev.d | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 docs/RFC-dev.d diff --git a/docs/RFC-dev.d b/docs/RFC-dev.d new file mode 100644 index 0000000000..4985e841be --- /dev/null +++ b/docs/RFC-dev.d @@ -0,0 +1,49 @@ + /etc/dev.d/ How it works, and what it is for + + by Greg Kroah-Hartman March 2004 + +The /etc/dev.d directory works much like the /etc/hotplug.d/ directory +in that it is a place to put symlinks or programs that get called when +an event happens in the system. Programs will get called whenever the +device naming program in the system has either named a new device and +created a /dev node for it, or when a /dev node has been removed from +the system due to a device being removed. + +The directory tree under /etc/dev.d/ dictate which program is run first, +and when some programs will be run or not. The device naming program +calls the programs in the following order: + /etc/dev.d/DEVNODE/*.dev + /etc/dev.d/SUBSYSTEM/*.dev + /etc/dev.d/default/*.dev + +The .dev extension is needed to allow automatic package managers to +deposit backup files in these directories safely. + +The DEVNODE name is the name of the /dev file that has been created. +This value, including the /dev path, will also be exported to userspace +in the DEVNODE environment variable. + +The SUBSYSTEM name is the name of the sysfs subsystem that originally +generated the hotplug event that caused the device naming program to +create or remove the /dev node originally. This value is passed to +userspace as the first argument to the program. + +The default directory will always be run, to enable programs to catch +every device add and remove in a single place. + +All environment variables that were originally passed by the hotplug +call that caused this device action will also be passed to the program +called in the /etc/dev.d/ directories. Examples of these variables are +ACTION, DEVPATH, and others. See the hotplug documentation for full +description of this + +An equivalent shell script that would do this same kind of action would +be: + DIR="/etc/dev.d" + export DEVNODE="whatever_dev_name_udev_just_gave" + for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do + if [ -f $I ]; then $I $1 ; fi + done + exit 1; + + From f61d732a02c8a5e11c39651a70e3e3fd00529495 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 24 Mar 2004 23:19:39 -0800 Subject: [PATCH 0698/4284] [PATCH] hmm, handle net devices with udev? Hmm, Arndt Bergmann sent a patch like this one a few weeks ago and I want to bring the question back, if we want to handle net device naming with udev. With this patch it is actually possible to specify something like this in udev.rules: KERNEL="dummy*", SYSFS{address}="00:00:00:00:00:00", SYSFS{features}="0x0", NAME="blind%n" KERNEL="eth*", SYSFS{address}="00:0d:60:77:30:91", NAME="private" and you will get: [root@pim udev.kay]# cat /proc/net/dev Inter-| Receive | Transmit face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed lo: 1500 30 0 0 0 0 0 0 1500 30 0 0 0 0 0 0 private: 278393 1114 0 0 0 0 0 0 153204 1468 0 0 0 0 0 0 sit0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 blind0: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 The udevinfo program is also working: [root@pim udev.kay]# ./udevinfo -a -p /sys/class/net/private looking at class device '/sys/class/net/private': SYSFS{addr_len}="6" SYSFS{address}="00:0d:60:77:30:91" SYSFS{broadcast}="ff:ff:ff:ff:ff:ff" SYSFS{features}="0x3a9" SYSFS{flags}="0x1003" SYSFS{ifindex}="2" SYSFS{iflink}="2" SYSFS{mtu}="1500" SYSFS{tx_queue_len}="1000" SYSFS{type}="1" follow the class device's "device" looking at the device chain at '/sys/devices/pci0000:00/0000:00:1e.0/0000:02:01.0': BUS="pci" ID="0000:02:01.0" SYSFS{class}="0x020000" SYSFS{detach_state}="0" SYSFS{device}="0x101e" SYSFS{irq}="11" SYSFS{subsystem_device}="0x0549" SYSFS{subsystem_vendor}="0x1014" SYSFS{vendor}="0x8086" The matching device will be renamed to the given name. The device name will not be put into the udev database, cause the kernel renames the device and the sysfs name disappears. I like it, cause it plugs in nicely. We have all the naming features and sysfs queries and walks inside of udev. The sysfs timing races are already solved and the management tools are working for net devices too. nameif can only match the MAC address now. udev can match any sysfs value of the device tree the net device is connected to. But right, net devices do not have device nodes :) --- namedev.c | 10 +++++ test/udev-test.pl | 110 +++++++++++++++++++++++----------------------- udev-add.c | 86 ++++++++++++++++++++++++++++-------- udev-remove.c | 44 +++++++++++++------ udev.c | 26 +++++------ udev_lib.c | 16 +++++++ udev_lib.h | 1 + udevinfo.c | 24 ++++++---- 8 files changed, 208 insertions(+), 109 deletions(-) diff --git a/namedev.c b/namedev.c index b9d8a3db2c..f2aea34719 100644 --- a/namedev.c +++ b/namedev.c @@ -836,12 +836,22 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } } + /* no rule was found for the net device */ + if (udev->type == 'n') { + dbg("no name for net device '%s' configured", udev->kernel_name); + return -1; + } + /* no rule was found so we use the kernel name */ strfieldcpy(udev->name, udev->kernel_name); goto done; found: apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + + if (udev->type == 'n') + return 0; + udev->partitions = dev->partitions; strfieldcpy(udev->config_file, dev->config_file); udev->config_line = dev->config_line; diff --git a/test/udev-test.pl b/test/udev-test.pl index d93ebb9cc3..8ae01c31d4 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -35,7 +35,7 @@ my @tests = ( { desc => "label test of scsi disc", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "boot_disk" , conf => < "label test of scsi partition", subsys => "block", - devpath => "block/sda/sda1", + devpath => "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "label test of pattern match", subsys => "block", - devpath => "block/sda/sda1", + devpath => "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "label test of multiple sysfs files", subsys => "block", - devpath => "block/sda/sda1", + devpath => "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "label test of max sysfs files", subsys => "block", - devpath => "block/sda/sda1", + devpath => "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "catch device by *", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "catch device by * - take 2", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "catch device by ?", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "catch device by character class", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "replace kernel name", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "Handle comment lines in config file (and replace kernel name)", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "Handle comment lines in config file with whitespace (and replace kernel name)", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "Handle empty lines in config file (and replace kernel name)", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "subdirectory handling", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "sub/direct/ory/visor" , conf => < "place on bus of scsi partition", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "first_disk3" , conf => < "test NAME substitution chars", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "test NAME substitution chars (with length limit)", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "M8-m3-n3-b0:0-sIBM" , conf => < "old style SYSFS_ attribute", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "good" , conf => < "sustitution of sysfs value (%s{file})", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "disk-IBM-ESXS-sda" , conf => < "program result substitution", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "special-device-3" , conf => < "program result substitution", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "test-0:0:0:0" , conf => < "program with escaped format char (tricky: callout returns format char!)", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "escape-3" , conf => < "program with lots of arguments", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "foo9" , conf => < "program with subshell", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "bar9" , conf => < "program arguments combined with apostrophes", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "foo7" , conf => < "characters before the %c{N} substitution", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "my-foo9" , conf => < "substitute the second to last argument", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "my-foo8" , conf => < "program result substitution (numbered part of)", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "link1" , conf => < "program result substitution (numbered part of+)", subsys => "block", - devpath => "block/sda/sda3", + devpath => "/block/sda/sda3", exp_name => "link3" , conf => < "invalid program for device with no bus", subsys => "tty", - devpath => "class/tty/console", + devpath => "/class/tty/console", exp_name => "TTY" , conf => < "valid program for device with no bus", subsys => "tty", - devpath => "class/tty/console", + devpath => "/class/tty/console", exp_name => "foo" , conf => < "invalid label for device with no bus", subsys => "tty", - devpath => "class/tty/console", + devpath => "/class/tty/console", exp_name => "TTY" , conf => < "valid label for device with no bus", subsys => "tty", - devpath => "class/tty/console", + devpath => "/class/tty/console", exp_name => "foo" , conf => < "program and bus type match", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "scsi-0:0:0:0" , conf => < "symlink creation (same directory)", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor0" , conf => < "symlink creation (relative link back)", subsys => "block", - devpath => "block/sda/sda2", + devpath => "/block/sda/sda2", exp_name => "1/2/a/b/symlink" , conf => < "symlink creation (relative link forward)", subsys => "block", - devpath => "block/sda/sda2", + devpath => "/block/sda/sda2", exp_name => "1/2/symlink" , conf => < "symlink creation (relative link back and forward)", subsys => "block", - devpath => "block/sda/sda2", + devpath => "/block/sda/sda2", exp_name => "1/2/c/d/symlink" , conf => < "multiple symlinks", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "second-0" , conf => < "create all possible partitions", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "boot_disk15" , conf => < "sysfs parent hierarchy", subsys => "tty", - devpath => "class/tty/ttyUSB0", + devpath => "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "name test with ! in the name", subsys => "block", - devpath => "block/rd!c0d0", + devpath => "/block/rd!c0d0", exp_name => "rd/c0d0" , conf => < "name test with ! in the name, but no matching rule", subsys => "block", - devpath => "block/rd!c0d0", + devpath => "/block/rd!c0d0", exp_name => "rd/c0d0" , conf => < "ID rule", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "ID wildcard all", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "ID wildcard partial", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "ID wildcard partial 2", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "ignore SYSFS attribute whitespace", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "ignored", conf => < "do not ignore SYSFS attribute whitespace", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "matched-with-space", conf => < "SYMLINK only rule", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "symlink-only2", conf => < "permissions test", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "node", exp_perms => "5000::0444", conf => < "major/minor number test", subsys => "block", - devpath => "block/sda", + devpath => "/block/sda", exp_name => "node", exp_majorminor => "8:0", conf => < "big minor number test", subsys => "i2c-dev", - devpath => "class/i2c-dev/i2c-300", + devpath => "/class/i2c-dev/i2c-300", exp_name => "node", exp_majorminor => "89:300", conf => < "big major number test", subsys => "i2c-dev", - devpath => "class/i2c-dev/i2c-fake1", + devpath => "/class/i2c-dev/i2c-fake1", exp_name => "node", exp_majorminor => "4095:1", conf => < "big major and big minor number test", subsys => "i2c-dev", - devpath => "class/i2c-dev/i2c-fake2", + devpath => "/class/i2c-dev/i2c-fake2", exp_name => "node", exp_majorminor => "4094:89999", conf => < #include #include +#include +#include +#include +#include #ifndef __KLIBC__ #include #include @@ -342,16 +346,16 @@ exit: /* wait for the "dev" file to show up in the directory in sysfs. * If it doesn't happen in about 10 seconds, give up. */ -#define SECONDS_TO_WAIT_FOR_DEV 10 -static int sleep_for_dev(char *path) +#define SECONDS_TO_WAIT_FOR_FILE 10 +static int sleep_for_file(char *path, char* file) { char filename[SYSFS_PATH_MAX + 6]; - int loop = SECONDS_TO_WAIT_FOR_DEV; + int loop = SECONDS_TO_WAIT_FOR_FILE; int retval; strfieldcpy(filename, sysfs_path); strfieldcat(filename, path); - strfieldcat(filename, "/dev"); + strfieldcat(filename, file); while (loop--) { struct stat buf; @@ -369,6 +373,30 @@ exit: return retval; } +static int rename_net_if(struct udevice *dev) +{ + int sk; + struct ifreq ifr; + int retval; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) { + dbg("error opening socket"); + return -1; + } + + memset(&ifr, 0x00, sizeof(struct ifreq)); + strfieldcpy(ifr.ifr_name, dev->kernel_name); + strfieldcpy(ifr.ifr_newname, dev->name); + + dbg("changing net interface name from '%s' to '%s'", dev->kernel_name, dev->name); + retval = ioctl(sk, SIOCSIFNAME, &ifr); + if (retval != 0) + dbg("error changing net interface name"); + + return retval; +} + int udev_add_device(char *path, char *subsystem, int fake) { struct sysfs_class_device *class_dev = NULL; @@ -378,39 +406,61 @@ int udev_add_device(char *path, char *subsystem, int fake) memset(&dev, 0x00, sizeof(dev)); /* for now, the block layer is the only place where block devices are */ - if (strcmp(subsystem, "block") == 0) - dev.type = 'b'; - else - dev.type = 'c'; - retval = sleep_for_dev(path); - if (retval != 0) - goto exit; + dev.type = get_device_type(path, subsystem); + + switch (dev.type) { + case 'b': + case 'c': + retval = sleep_for_file(path, "/dev"); + break; + + case 'n': + retval = sleep_for_file(path, "/address"); + break; + + default: + dbg("unknown device type '%c'", dev.type); + retval = -EINVAL; + } class_dev = get_class_dev(path); if (class_dev == NULL) goto exit; - retval = get_major_minor(class_dev, &dev); - if (retval != 0) { - dbg("get_major_minor failed"); - goto exit; + if (dev.type == 'b' || dev.type == 'c') { + retval = get_major_minor(class_dev, &dev); + if (retval != 0) { + dbg("get_major_minor failed"); + goto exit; + } } retval = namedev_name_device(class_dev, &dev); if (retval != 0) goto exit; - if (!fake) { + if (!fake && (dev.type == 'b' || dev.type == 'c')) { retval = udevdb_add_dev(path, &dev); if (retval != 0) dbg("udevdb_add_dev failed, but we are going to try " "to create the node anyway. But remove might not " "work properly for this device."); - } + dbg("name='%s'", dev.name); - retval = create_node(&dev, fake); + switch (dev.type) { + case 'b': + case 'c': + retval = create_node(&dev, fake); + break; + + case 'n': + retval = rename_net_if(&dev); + if (retval != 0) + dbg("net device naming failed"); + break; + } if ((retval == 0) && (!fake)) dev_d_send(&dev, subsystem); diff --git a/udev-remove.c b/udev-remove.c index 41636b684e..98c45d6c33 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -135,22 +135,38 @@ int udev_remove_device(char *path, char *subsystem) char *temp; int retval; - memset(&dev, 0, sizeof(dev)); + memset(&dev, 0x00, sizeof(dev)); - retval = udevdb_get_dev(path, &dev); - if (retval) { - dbg("'%s' not found in database, falling back on default name", path); - temp = strrchr(path, '/'); - if (temp == NULL) - return -ENODEV; - strfieldcpy(dev.name, &temp[1]); + dev.type = get_device_type(path, subsystem); + + switch (dev.type) { + case 'b': + case 'c': + retval = udevdb_get_dev(path, &dev); + if (retval) { + dbg("'%s' not found in database, falling back on default name", path); + temp = strrchr(path, '/'); + if (temp == NULL) + return -ENODEV; + strfieldcpy(dev.name, &temp[1]); + } + + dbg("name='%s'", dev.name); + udevdb_delete_dev(path); + + dev_d_send(&dev, subsystem); + + retval = delete_node(&dev); + break; + + case 'n': + retval = 0; + break; + + default: + dbg("unknown device type '%c'", dev.type); + retval = -EINVAL; } - dbg("name is '%s'", dev.name); - udevdb_delete_dev(path); - - dev_d_send(&dev, subsystem); - - retval = delete_node(&dev); return retval; } diff --git a/udev.c b/udev.c index 52b98c8d45..192bed97d8 100644 --- a/udev.c +++ b/udev.c @@ -68,7 +68,6 @@ static void sig_handler(int signum) } static char *subsystem_blacklist[] = { - "net", "scsi_host", "scsi_device", "usb_host", @@ -85,6 +84,7 @@ static int udev_hotplug(void) int retval = -EINVAL; int i; struct sigaction act; + const int nofake = 0; action = get_action(); if (!action) { @@ -137,23 +137,23 @@ static int udev_hotplug(void) if (strcmp(action, "add") == 0) { namedev_init(); - retval = udev_add_device(devpath, subsystem, 0); - } else { - if (strcmp(action, "remove") == 0) { - retval = udev_remove_device(devpath, subsystem); - } else { - dbg("unknown action '%s'", action); - retval = -EINVAL; - } + retval = udev_add_device(devpath, subsystem, nofake); + goto action_done; } + if (strcmp(action, "remove") == 0) { + retval = udev_remove_device(devpath, subsystem); + goto action_done; + } + + dbg("unknown action '%s'", action); + retval = -EINVAL; + +action_done: udevdb_exit(); exit: - if (retval > 0) - retval = 0; - - return -retval; + return retval; } int main(int argc, char *argv[], char *envp[]) diff --git a/udev_lib.c b/udev_lib.c index f095513c97..4a9eea506c 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -81,6 +81,22 @@ char *get_subsystem(char *subsystem) return subsystem; } +char get_device_type(const char *path, const char *subsystem) +{ + if (strcmp(subsystem, "block") == 0 || + strstr(path, "/block/") != NULL) + return 'b'; + + if (strcmp(subsystem, "net") == 0 || + strstr(path, "/class/net/") != NULL) + return 'n'; + + if (strstr(path, "/class/") != NULL) + return 'c'; + + return '\0'; +} + int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; diff --git a/udev_lib.h b/udev_lib.h index 5db6b5261a..90a42ffe96 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -71,6 +71,7 @@ extern char *get_devpath(void); extern char *get_devnode(void); extern char *get_seqnum(void); extern char *get_subsystem(char *subsystem); +extern char get_device_type(const char *path, const char *subsystem); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); diff --git a/udevinfo.c b/udevinfo.c index 800882eb1a..b23f9d0aef 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -138,6 +138,10 @@ static int print_device_chain(const char *path) struct sysfs_device *sysfs_dev; struct sysfs_device *sysfs_dev_parent; int retval = 0; + char type; + + type = get_device_type(path, ""); + dbg("device type is %c", type); /* get the class dev */ class_dev = sysfs_open_class_device_path(path); @@ -146,21 +150,23 @@ static int print_device_chain(const char *path) return -1; } - /* read the 'dev' file for major/minor*/ - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr == NULL) { - printf("couldn't get the \"dev\" file\n"); - retval = -1; - goto exit; - } - printf("\nudevinfo starts with the device the node belongs to and then walks up the\n" "device chain, to print for every device found, all possibly useful attributes\n" "in the udev key format.\n" "Only attributes within one device section may be used together in one rule,\n" "to match the device for which the node will be created.\n" "\n"); - printf("device '%s' has major:minor %s", class_dev->path, attr->value); + + if (type == 'b' || type =='c') { + /* read the 'dev' file for major/minor*/ + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) { + printf("couldn't get the \"dev\" file\n"); + retval = -1; + goto exit; + } + printf("device '%s' has major:minor %s", class_dev->path, attr->value); + } /* open sysfs class device directory and print all attributes */ printf(" looking at class device '%s':\n", class_dev->path); From 1f5caf43c88a247d36d1c8362009cda59f3ac729 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 24 Mar 2004 23:31:04 -0800 Subject: [PATCH 0699/4284] [PATCH] actually have udev run files ending in .dev in the /etc/dev.d/ directory as documented. --- dev_d.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dev_d.c b/dev_d.c index 36bee33bd9..9412c3da77 100644 --- a/dev_d.c +++ b/dev_d.c @@ -36,6 +36,7 @@ #include "logging.h" #define HOTPLUGDIR "/etc/dev.d" +#define SUFFIX ".dev" #define COMMENT_PREFIX '#' static void run_program(char *name) @@ -64,7 +65,8 @@ static void execute_dir (char *dirname) { DIR *directory; struct dirent *entry; - char filename[256]; + char filename[NAME_SIZE]; + int name_len; dbg("opening %s", dirname); directory = opendir(dirname); @@ -80,6 +82,13 @@ static void execute_dir (char *dirname) (entry->d_name[0] == COMMENT_PREFIX)) continue; + /* Nor do we run files that do not end in ".dev" */ + name_len = strlen(entry->d_name); + if (name_len < strlen(SUFFIX)) + continue; + if (strcmp(&entry->d_name[name_len - sizeof (SUFFIX) + 1], SUFFIX) != 0) + continue; + /* FIXME - need to use file_list_insert() here to run these in sorted order... */ snprintf(filename, sizeof(filename), "%s%s", dirname, entry->d_name); filename[sizeof(filename)-1] = '\0'; From df73b398de73acbf9f9b0e49b872968460f1eb28 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Mar 2004 00:03:28 -0800 Subject: [PATCH 0700/4284] [PATCH] create the /etc/dev.d/ directories in 'make install' --- Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4481ee1bfa..94b873d2f7 100644 --- a/Makefile +++ b/Makefile @@ -53,6 +53,7 @@ mandir = ${prefix}/usr/share/man hotplugdir = ${etcdir}/hotplug.d/default configdir = ${etcdir}/udev/ initdir = ${etcdir}/init.d/ +dev_ddir = ${etcdir}/dev.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -349,7 +350,11 @@ install-config: $(GEN_CONFIGS) $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ fi -install: install-initscript install-config all +install-dev.d: + $(INSTALL) -d $(DESTDIR)$(dev_ddir) + $(INSTALL) -d $(DESTDIR)$(dev_ddir)default/ + +install: install-initscript install-config install-dev.d all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) @@ -393,6 +398,8 @@ uninstall: - rm $(usrbindir)/$(INFO) - rmdir $(hotplugdir) - rmdir $(configdir) + - rmdir $(dev_ddir)default + - rmdir $(dev_ddir) - rm $(udevdir)/.udev.tdb - rmdir $(udevdir) @extras="$(EXTRAS)" ; for target in $$extras ; do \ From 04b902d5bfff632765688ac0f1c7a19a6ef6e0ea Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Mar 2004 00:08:46 -0800 Subject: [PATCH 0701/4284] [PATCH] v023 release --- ChangeLog | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- Makefile | 2 +- udev.spec | 2 +- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index b78b0b9bbd..a9d4f94e06 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +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 + o 022 release TAG: v022 + +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 ============================================ @@ -8,7 +60,7 @@ Summary of changes from v021 to v022 : 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 diff --git a/Makefile b/Makefile index 94b873d2f7..7b48b91610 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 022_bk +VERSION = 023 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 8e6c16d6b2..2445b40de5 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 022_bk +Version: 023 Release: 1 License: GPL Group: Utilities/System From d0dede8f9af8d17d556c969adedd97b40c931920 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 25 Mar 2004 00:14:47 -0800 Subject: [PATCH 0702/4284] [PATCH] fix udev.spec file for where udevtest should be placed. --- udev.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index 2445b40de5..a780acfa98 100644 --- a/udev.spec +++ b/udev.spec @@ -113,7 +113,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /usr/bin/udevinfo %attr(755,root,root) /sbin/udevsend %attr(755,root,root) /sbin/udevd -%attr(755,root,root) /sbin/udevtest +%attr(755,root,root) /usr/bin/udevtest %attr(755,root,root) /sbin/udevstart %attr(755,root,root) %dir /udev/ %attr(755,root,root) %dir /etc/udev/ From c2818554cee064360b8a3ed543fe30349096a74a Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Sat, 27 Mar 2004 01:21:41 -0800 Subject: [PATCH 0703/4284] [PATCH] small ide-devfs.sh fix The file may not exist and errors would be spewed on the console. --- extras/ide-devfs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index e5bf177f8b..22d09d7a5a 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -35,7 +35,7 @@ get_dev_number() { echo $((${num} - 1)) } -if [ -z "$3" ]; then +if [ -z "$3" -a -f /proc/ide/${1}/media ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` From 949e32f2249da55890a6a49208023df30b6b5227 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 27 Mar 2004 01:21:43 -0800 Subject: [PATCH 0704/4284] [PATCH] apply all_partitions rule to main block device only Rules with NAME{all_partitions}= are now applied only to the parent of a block device. We no longer need to exclude the partitions or sg* devices. --- namedev.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/namedev.c b/namedev.c index f2aea34719..7b70f8bcdf 100644 --- a/namedev.c +++ b/namedev.c @@ -619,8 +619,8 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de * possibly have a whitelist for these devices here... */ class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent) - dbg("Really a partition"); + if (class_dev_parent != NULL) + dbg("given class device has a parent, use this instead"); tspec.tv_sec = 0; tspec.tv_nsec = 10000000; /* sleep 10 millisec */ @@ -628,24 +628,21 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de while (loop--) { if (udev_sleep) nanosleep(&tspec, NULL); + if (class_dev_parent) sysfs_device = sysfs_get_classdev_device(class_dev_parent); else sysfs_device = sysfs_get_classdev_device(class_dev); - if (sysfs_device != NULL) goto device_found; } dbg("timed out waiting for device symlink, continuing on anyway..."); - + device_found: /* We have another issue with just the wait above - the sysfs part of * the kernel may not be quick enough to have created the link to the * device under the "bus" subsystem. Due to this, the sysfs_device->bus * will not contain the actual bus name :( - * - * Libsysfs now provides a new API sysfs_get_device_bus(), so use it - * if needed */ if (sysfs_device) { if (sysfs_device->bus[0] != '\0') @@ -828,6 +825,11 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } if (dev->name[0] != '\0') { + /* apply all_partitions flag only at a main block device */ + if (dev->partitions > 0 && + (udev->type != 'b' || udev->kernel_number[0] != '\0')) + continue; + info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", dev->config_file, dev->config_line, udev->kernel_name, dev->name); strfieldcpy(udev->name, dev->name); From 4a539daf1e5daa17b52239478d97f8dc7a6506b6 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 27 Mar 2004 01:21:46 -0800 Subject: [PATCH 0705/4284] [PATCH] dev_d.c file sorting and cleanup On Thu, Mar 25, 2004 at 02:52:13AM +0100, Kay Sievers wrote: > Please have look if it still works for you, I only did a very quick > test. Here is a unified version, with all the functions moved to udev_lib.c. We have a generic function now, to call a given fnct(char *) for every file ending with a specific suffix, sorted in lexical order. We use it to execute the dev.d/ files and read our rules.d/ files. The binary should be a bit smaller now. I've also changed it, to not do the dev.d/ exec for net devices. --- dev_d.c | 114 +++++++++++++++--------------------------------- namedev.h | 4 +- namedev_parse.c | 97 +++++++--------------------------------- udev-add.c | 6 +-- udev_lib.c | 86 ++++++++++++++++++++++++++++++++++++ udev_lib.h | 1 + udevd.c | 6 +-- udevruler.c | 8 ++-- 8 files changed, 151 insertions(+), 171 deletions(-) diff --git a/dev_d.c b/dev_d.c index 9412c3da77..9bb9507b9b 100644 --- a/dev_d.c +++ b/dev_d.c @@ -1,30 +1,23 @@ /* - * dev.d multipleer + * dev_d.c - dev.d/ multiplexer * * Copyright (C) 2004 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. - * - * Based on the klibc version of hotplug written by: - * Author(s) Christian Borntraeger - * which was based on the shell script written by: - * Greg Kroah-Hartman - * */ -/* +/* * This essentially emulates the following shell script logic in C: - DIR="/etc/dev.d" - export DEVNODE="whatever_dev_name_udev_just_gave" - for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do - if [ -f $I ]; then $I $1 ; fi - done - exit 1; + * DIR="/etc/dev.d" + * export DEVNODE="whatever_dev_name_udev_just_gave" + * for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do + * if [ -f $I ]; then $I $1 ; fi + * done + * exit 1; */ -#include #include #include #include @@ -35,73 +28,38 @@ #include "udev_lib.h" #include "logging.h" -#define HOTPLUGDIR "/etc/dev.d" -#define SUFFIX ".dev" -#define COMMENT_PREFIX '#' +#define DEVD_DIR "/etc/dev.d/" +#define DEVD_SUFFIX ".dev" -static void run_program(char *name) +static int run_program(char *name) { pid_t pid; dbg("running %s", name); pid = fork(); - - if (pid < 0) { - perror("fork"); - return; - } - - if (pid > 0) { + switch (pid) { + case 0: + /* child */ + execv(name, main_argv); + dbg("exec of child failed"); + exit(1); + case -1: + dbg("fork of child failed"); + break; + return -1; + default: wait(NULL); - return; } - execv(name, main_argv); - exit(1); + return 0; } -static void execute_dir (char *dirname) -{ - DIR *directory; - struct dirent *entry; - char filename[NAME_SIZE]; - int name_len; - - dbg("opening %s", dirname); - directory = opendir(dirname); - if (!directory) - return; - - while ((entry = readdir(directory))) { - if (entry->d_name[0] == '\0') - break; - /* Don't run the files '.', '..', or hidden files, - * or files that start with a '#' */ - if ((entry->d_name[0] == '.') || - (entry->d_name[0] == COMMENT_PREFIX)) - continue; - - /* Nor do we run files that do not end in ".dev" */ - name_len = strlen(entry->d_name); - if (name_len < strlen(SUFFIX)) - continue; - if (strcmp(&entry->d_name[name_len - sizeof (SUFFIX) + 1], SUFFIX) != 0) - continue; - - /* FIXME - need to use file_list_insert() here to run these in sorted order... */ - snprintf(filename, sizeof(filename), "%s%s", dirname, entry->d_name); - filename[sizeof(filename)-1] = '\0'; - run_program(filename); - } - - closedir(directory); -} - -/* runs files in these directories in order: - * name given by udev - * subsystem - * default +/* + * runs files in these directories in order: + * / + * subsystem/ + * default/ */ void dev_d_send(struct udevice *dev, char *subsystem) { @@ -112,15 +70,15 @@ void dev_d_send(struct udevice *dev, char *subsystem) strfieldcat(devnode, dev->name); setenv("DEVNODE", devnode, 1); - snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", dev->name); - dirname[sizeof(dirname)-1] = '\0'; - execute_dir(dirname); + strcpy(dirname, DEVD_DIR); + strfieldcat(dirname, dev->name); + call_foreach_file(run_program, dirname, DEVD_SUFFIX); - snprintf(dirname, sizeof(dirname), HOTPLUGDIR "/%s/", subsystem); - dirname[sizeof(dirname)-1] = '\0'; - execute_dir(dirname); + strcpy(dirname, DEVD_DIR); + strfieldcat(dirname, subsystem); + call_foreach_file(run_program, dirname, DEVD_SUFFIX); - strcpy(dirname, HOTPLUGDIR "/default/"); - execute_dir(dirname); + strcpy(dirname, DEVD_DIR "default"); + call_foreach_file(run_program, dirname, DEVD_SUFFIX); } diff --git a/namedev.h b/namedev.h index 68100d4f62..fa924b14d9 100644 --- a/namedev.h +++ b/namedev.h @@ -53,8 +53,8 @@ struct sysfs_class_device; #define MAX_SYSFS_PAIRS 5 -#define RULEFILE_EXT ".rules" -#define PERMFILE_EXT ".permissions" +#define RULEFILE_SUFFIX ".rules" +#define PERMFILE_SUFFIX ".permissions" #define set_empty_perms(dev, m, o, g) \ if (dev->mode == 0) \ diff --git a/namedev_parse.c b/namedev_parse.c index f4ffdb21d6..679efae1b5 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "udev.h" @@ -41,8 +40,6 @@ #include "logging.h" #include "namedev.h" -LIST_HEAD(file_list); - static int add_config_dev(struct config_device *new_dev) { @@ -416,88 +413,26 @@ exit: return retval; } -struct files { - struct list_head list; - char name[NAME_SIZE]; -}; - -/* sort files in lexical order */ -static int file_list_insert(char *filename) -{ - struct files *loop_file; - struct files *new_file; - - list_for_each_entry(loop_file, &file_list, list) { - if (strcmp(loop_file->name, filename) > 0) { - break; - } - } - - new_file = malloc(sizeof(struct files)); - if (new_file == NULL) { - dbg("error malloc"); - return -ENOMEM; - } - - strfieldcpy(new_file->name, filename); - list_add_tail(&new_file->list, &loop_file->list); - return 0; -} - -/* calls function for file or every file found in directory */ -static int call_foreach_file(int parser (char *f) , char *filename, char *extension) -{ - struct dirent *ent; - DIR *dir; - char *ext; - char file[NAME_SIZE]; - struct stat stats; - struct files *loop_file; - struct files *tmp_file; - - /* look if we have a plain file or a directory to scan */ - stat(filename, &stats); - if ((stats.st_mode & S_IFMT) != S_IFDIR) - return parser(filename); - - /* sort matching filename into list */ - dbg("open config as directory '%s'", filename); - dir = opendir(filename); - while (1) { - ent = readdir(dir); - if (ent == NULL || ent->d_name[0] == '\0') - break; - - dbg("found file '%s'", ent->d_name); - ext = strrchr(ent->d_name, '.'); - if (ext == NULL) - continue; - - if (strcmp(ext, extension) == 0) { - dbg("put file in list '%s'", ent->d_name); - file_list_insert(ent->d_name); - } - } - - /* parse every file in the list */ - list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { - strfieldcpy(file, filename); - strfieldcat(file, loop_file->name); - parser(file); - list_del(&loop_file->list); - free(loop_file); - } - - closedir(dir); - return 0; -} - int namedev_init_rules() { - return call_foreach_file(namedev_parse_rules, udev_rules_filename, RULEFILE_EXT); + struct stat stats; + + stat(udev_rules_filename, &stats); + if ((stats.st_mode & S_IFMT) != S_IFDIR) + return namedev_parse_rules(udev_rules_filename); + else + return call_foreach_file(namedev_parse_rules, + udev_rules_filename, RULEFILE_SUFFIX); } int namedev_init_permissions() { - return call_foreach_file(namedev_parse_permissions, udev_permissions_filename, PERMFILE_EXT); + struct stat stats; + + stat(udev_permissions_filename, &stats); + if ((stats.st_mode & S_IFMT) != S_IFDIR) + return namedev_parse_permissions(udev_permissions_filename); + else + return call_foreach_file(namedev_parse_permissions, + udev_permissions_filename, PERMFILE_SUFFIX); } diff --git a/udev-add.c b/udev-add.c index 4aff06e15f..6dfd059105 100644 --- a/udev-add.c +++ b/udev-add.c @@ -393,6 +393,7 @@ static int rename_net_if(struct udevice *dev) retval = ioctl(sk, SIOCSIFNAME, &ifr); if (retval != 0) dbg("error changing net interface name"); + close(sk); return retval; } @@ -453,6 +454,8 @@ int udev_add_device(char *path, char *subsystem, int fake) case 'b': case 'c': retval = create_node(&dev, fake); + if ((retval == 0) && (!fake)) + dev_d_send(&dev, subsystem); break; case 'n': @@ -462,9 +465,6 @@ int udev_add_device(char *path, char *subsystem, int fake) break; } - if ((retval == 0) && (!fake)) - dev_d_send(&dev, subsystem); - exit: if (class_dev) sysfs_close_class_device(class_dev); diff --git a/udev_lib.c b/udev_lib.c index 4a9eea506c..e9c16c863a 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -21,14 +21,19 @@ #include #include +#include #include #include +#include +#include #include #include #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "logging.h" #include "udev_lib.h" +#include "list.h" char *get_action(void) @@ -136,3 +141,84 @@ size_t buf_get_line(char *buf, size_t buflen, size_t cur) return count - cur; } +struct files { + struct list_head list; + char name[NAME_SIZE]; +}; + +/* sort files in lexical order */ +static int file_list_insert(char *filename, struct list_head *file_list) +{ + struct files *loop_file; + struct files *new_file; + + list_for_each_entry(loop_file, file_list, list) { + if (strcmp(loop_file->name, filename) > 0) { + break; + } + } + + new_file = malloc(sizeof(struct files)); + if (new_file == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + strfieldcpy(new_file->name, filename); + list_add_tail(&new_file->list, &loop_file->list); + return 0; +} + +/* calls function for file or every file found in directory */ +int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) +{ + struct dirent *ent; + DIR *dir; + char *ext; + char file[NAME_SIZE]; + struct files *loop_file; + struct files *tmp_file; + LIST_HEAD(file_list); + + dbg("open directory '%s'", dirname); + dir = opendir(dirname); + if (dir == NULL) { + dbg("unable to open '%s'", dirname); + 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 with specified suffix */ + ext = strrchr(ent->d_name, '.'); + if (ext == NULL) + continue; + + if (strcmp(ext, suffix) != 0) + continue; + + dbg("put file '%s/%s' in list", dirname, ent->d_name); + file_list_insert(ent->d_name, &file_list); + } + + /* call function for every file in the list */ + list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { + strfieldcpy(file, dirname); + strfieldcat(file, "/"); + strfieldcat(file, loop_file->name); + + fnct(file); + + list_del(&loop_file->list); + free(loop_file); + } + + closedir(dir); + return 0; +} diff --git a/udev_lib.h b/udev_lib.h index 90a42ffe96..e412ba96f4 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -75,6 +75,7 @@ extern char get_device_type(const char *path, const char *subsystem); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); +extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension); #endif diff --git a/udevd.c b/udevd.c index 4cb3e1d405..0757dcaf3d 100644 --- a/udevd.c +++ b/udevd.c @@ -45,9 +45,9 @@ static int expected_seqnum = 0; volatile static int children_waiting; volatile static int msg_q_timeout; -LIST_HEAD(msg_list); -LIST_HEAD(exec_list); -LIST_HEAD(running_list); +static LIST_HEAD(msg_list); +static LIST_HEAD(exec_list); +static LIST_HEAD(running_list); static void exec_queue_manager(void); static void msg_queue_manager(void); diff --git a/udevruler.c b/udevruler.c index b66940e944..af2cf7bb81 100644 --- a/udevruler.c +++ b/udevruler.c @@ -81,8 +81,8 @@ struct device { int added; }; -LIST_HEAD(device_list); -int device_count; +static LIST_HEAD(device_list); +static int device_count; /* callback for database dump */ static int add_record(char *path, struct udevice *udev) @@ -149,8 +149,8 @@ struct attribute { char key[NAME_SIZE]; }; -LIST_HEAD(attribute_list); -int attribute_count; +static LIST_HEAD(attribute_list); +static int attribute_count; static int add_attribute(const char *key, int level) { From 6d472fe777b237d5843dda9e685f225e2c7341b4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 27 Mar 2004 01:23:21 -0800 Subject: [PATCH 0706/4284] [PATCH] 023_bk mark --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7b48b91610..d0ca3a18d9 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 023 +VERSION = 023_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index a780acfa98..1df59ecdb8 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 023 +Version: 023_bk Release: 1 License: GPL Group: Utilities/System From 69b94397d32d8f2ba41a8e2987318b2eb144f673 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 29 Mar 2004 18:33:48 -0800 Subject: [PATCH 0707/4284] [PATCH] fix up udev.rules to handle oss rules better. Patch from Jordan --- etc/udev/udev.rules | 2 +- etc/udev/udev.rules.gentoo | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 370a961de1..725294cede 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -18,7 +18,7 @@ KERNEL="card*", NAME="dri/card%n" 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="midiC[D0-9]*", NAME="snd/%k" KERNEL="timer", NAME="snd/%k" KERNEL="seq", NAME="snd/%k" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index f8419a2925..eb72931c3f 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -54,7 +54,7 @@ BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME 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="midiC[D0-9]*", NAME="snd/%k" KERNEL="timer", NAME="snd/%k" KERNEL="seq", NAME="snd/%k" @@ -103,12 +103,16 @@ KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" # sound devices -KERNEL="adsp", NAME="sound/adsp", SYMLINK="%k" -KERNEL="audio", NAME="sound/audio", SYMLINK="%k" -KERNEL="dsp", NAME="sound/dsp", SYMLINK="%k" -KERNEL="mixer", NAME="sound/mixer", SYMLINK="%k" -KERNEL="sequencer", NAME="sound/sequencer", SYMLINK="%k" -KERNEL="sequencer2", NAME="sound/sequencer2", SYMLINK="%k" +KERNEL="adsp", NAME="sound/%k", SYMLINK="%k" +KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="audio", NAME="sound/%k", SYMLINK="%k" +KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="dsp", NAME="sound/%k", SYMLINK="%k" +KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="mixer", NAME="sound/%k", SYMLINK="%k" +KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k" +KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k" # tty devices KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" From b579916fb53f3916cf27c85072ce87f5b6b84b8b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 29 Mar 2004 18:38:53 -0800 Subject: [PATCH 0708/4284] [PATCH] clean up the gentoo rules file a bit more, adding dri rules. --- etc/udev/udev.rules.gentoo | 51 ++++++++------------------------------ 1 file changed, 10 insertions(+), 41 deletions(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index eb72931c3f..a0681d7dd9 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -1,44 +1,10 @@ # /etc/udev/udev.rules: device naming rules for udev -# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.rules-018,v 1.2 2004/02/29 11:07:39 azarah Exp $ +# +# Gentoo specific rules, based a bit on devfs rules, but much simpler. # # 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. -########################################################### -# -# Add your own rules here (examples are commented) -# -########################################################### - -# Looking for scsi bus id 42:0:0:1 -#BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" - -# A usb camera. -#BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" - -# USB Epson printer to be called lp_epson -#BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" - -# USB HP printer to be called lp_hp -#BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" - -# sound card with PCI bus id 00:0b.0 to be the first sound card -#BUS="pci", ID="00:0b.0", NAME="dsp" - -# sound card with PCI bus id 00:07.1 to be the second sound card -#BUS="pci", ID="00:07.1", NAME="dsp1" - -# USB mouse plugged into the third port of the first hub to be called mouse0 -#BUS="usb", PLACE="1.3", NAME="mouse0" - -# USB tablet plugged into the third port of the second hub to be called mouse1 -#BUS="usb", PLACE="2.3", NAME="mouse1" -#BUS="usb", PLACE="2.4", NAME="mouse2" - -# ttyUSB1 should always be called visor -#KERNEL="ttyUSB1", NAME="visor" -#KERNEL="ttyUSB0", NAME="pl2303" - ########################################################### # @@ -50,6 +16,9 @@ # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" +# DRI devices +KERNEL="card*", NAME="dri/card%n" + # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" KERNEL="hw[CD0-9]*", NAME="snd/%k" @@ -75,11 +44,11 @@ KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k" KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" # input devices -KERNEL="mice", NAME="input/mice" -KERNEL="mouse[0-9]*", NAME="input/mouse%n" -KERNEL="event[0-9]*", NAME="input/event%n" -KERNEL="js*", NAME="input/%k" -KERNEL="ts*", NAME="input/%k" +KERNEL="mice", NAME="input/%k" +KERNEL="mouse*", NAME="input/%k" +KERNEL="event*", NAME="input/%k" +KERNEL="js*", NAME="input/%k" +KERNEL="ts*", NAME="input/%k" # loop devices KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" From b085ec0d561983a2000e122f005439f154dd96f2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 29 Mar 2004 19:46:40 -0800 Subject: [PATCH 0709/4284] [PATCH] added USB device rules to rules files. --- etc/udev/udev.rules | 5 +++++ etc/udev/udev.rules.devfs | 5 +++++ etc/udev/udev.rules.gentoo | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 725294cede..dd934df850 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -29,3 +29,8 @@ KERNEL="event*", NAME="input/%k" KERNEL="js*", NAME="input/%k" KERNEL="ts*", NAME="input/%k" +# USB devices +KERNEL="hiddev*", NAME="usb/%k" +KERNEL="auer*", NAME="usb/%k" +KERNEL="legousbtower*", NAME="usb/%k" +KERNEL="dabusb*", NAME="usb/%k" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 77d3cf5414..c9154e46f3 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -73,3 +73,8 @@ KERNEL="event*", NAME="input/%k" KERNEL="js*", NAME="input/%k" KERNEL="ts*", NAME="input/%k" +# USB devices +KERNEL="hiddev*", NAME="usb/%k" +KERNEL="auer*", NAME="usb/%k" +KERNEL="legousbtower*", NAME="usb/%k" +KERNEL="dabusb*", NAME="usb/%k" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index a0681d7dd9..ced08c9a0b 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -100,3 +100,8 @@ KERNEL="radio[0-9]*", NAME="v4l/radio%n" KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +# USB devices +KERNEL="hiddev*", NAME="usb/%k" +KERNEL="auer*", NAME="usb/%k" +KERNEL="legousbtower*", NAME="usb/%k" +KERNEL="dabusb*", NAME="usb/%k" From 150aa5aaf15d4bd37fded470de8e829b34000d97 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 29 Mar 2004 19:52:56 -0800 Subject: [PATCH 0710/4284] [PATCH] add netlink rules to devfs and gentoo rules files. --- etc/udev/udev.rules.devfs | 14 ++++++++++++++ etc/udev/udev.rules.gentoo | 14 ++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index c9154e46f3..f7903a0d23 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -78,3 +78,17 @@ KERNEL="hiddev*", NAME="usb/%k" KERNEL="auer*", NAME="usb/%k" KERNEL="legousbtower*", NAME="usb/%k" KERNEL="dabusb*", NAME="usb/%k" + +# 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" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index ced08c9a0b..28e92aab1b 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -105,3 +105,17 @@ KERNEL="hiddev*", NAME="usb/%k" KERNEL="auer*", NAME="usb/%k" KERNEL="legousbtower*", NAME="usb/%k" KERNEL="dabusb*", NAME="usb/%k" + +# 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" From 4012ff38d8b2d9ed145d6867102251f87bdc9a1b Mon Sep 17 00:00:00 2001 From: "maryedie@osdl.org" Date: Wed, 31 Mar 2004 18:11:27 -0800 Subject: [PATCH 0711/4284] [PATCH] add OSDL documentation for persistent naming --- docs/persistent_naming/Testing_scsi_notes.txt | 213 ++++ .../udev.rules_1000_scsi_debug | 1014 +++++++++++++++++ 2 files changed, 1227 insertions(+) create mode 100644 docs/persistent_naming/Testing_scsi_notes.txt create mode 100644 docs/persistent_naming/udev.rules_1000_scsi_debug diff --git a/docs/persistent_naming/Testing_scsi_notes.txt b/docs/persistent_naming/Testing_scsi_notes.txt new file mode 100644 index 0000000000..5013c87e1d --- /dev/null +++ b/docs/persistent_naming/Testing_scsi_notes.txt @@ -0,0 +1,213 @@ +Using UDEV to do Persistent storage device naming +for large numbers of storage devices +3/16/2004 + +Here are some lessons we learned at OSDL recently on how to use +UDEV (version 021) to do persistent device naming for lots of storage +devices. We used what was available in udev for scsi devices. Here is +an outline of this report: + +Background information - a list of resources we needed to get +started. +Setup - what we needed to create the right enviroment (kernel, +patches, drivers) +How udev works to assign persistent storage device names - +what the documentation didn't tell us. +Performance - A sanity test we ran to compare with and without +persistent naming. + + +BACKGROUND INFORMATION +To get started, here are some references. Review the overview +articles so that the rest of the information makes sense. + +Download the latest udev stuff from: +http://www.kernel.org/pub/linux/utils/kernel/hotplug/ + +mailing list: +linux-hotplug-devel@lists.sourceforge.net + +Here is a nice overview article to get started (warning, this is from +summer 2003 so many items indicated as "todo" have been done and +configuration file name references have sometime changed): +http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf +(also included when you download udev) + +More general info (also included in the udev package): +http://kernel.org/pub/linux/utils/kernel/hotplug/udev-FAQ +UDEV version 021 Announcement: +http://marc.theaimsgroup.com/?l=linux-hotplug-devel&m=107827264803336&w=2 + +"Managing Dynamic Naming" +http://lwn.net/Articles/28897/ + +If you are a fan of devfs, whatever you do, don't complain until you +read everything you possibly can about udev. This for example: +http://kernel.org/pub/linux/utils/kernel/hotplug/udev_vs_devfs + +You will need to create udev.rules to supply consistent names. (See +etc/udev/udev.rules in the download). This article gives you some +background about udev.rules, but avoids describing the "PROGRAM" +key which is needed for our work. Read it for background: +writing udev rules (current as of udev 018) +http://www.reactivated.net/udevrules.php + +bitkeeper tree: +bk://kernel.bkbits.net/gregkh/udev + +Libsysfs (used to get sysfs information): +http://www-124.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf + +UDEV works using the way hotplug events are handled by the kernel. +Several overview articles about hotplug include: +Hotplug events +http://lwn.net/Articles/52621/ +Overview of Hotplug +http://linux-hotplug.sourceforge.net/ + +Gentoo centric install info: +http://webpages.charter.net/decibelshelp/LinuxHelp_UDEVPrimer.html + +rpms built against Red Hat FC2-test1 may be available at: +http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.i386.rpm + +with the source rpm at: +http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.src.rpm + + + +SETUP + +Here is a brief checklist of what you need on your system for this to +work: + +Kernel must be a 2.6 kernel + +Must use CONFIG_HOTPLUG kernel config option, since the solution +is based on hotplug capabilities. + +To test more than 256 scsi devices you need a patch to the scsi driver +to support that many (available from IBM or SuSE). To see the patch +we used, see this link: +http://developer.osdl.org/maryedie/DCL/PSDN/lotsofdisks.patch + +Your storage device must support (via the driver) a unique identifier for +persistent device naming. (Adaptec RAID device does not, for +example.) + +Your device driver must support sysfs (new in 2.6 kernel). This is +already done for scsi devices and most if not all block devices. + +A program (scsi_id) exists in the udev download +( extras/scsi_id/scsi_id.c) for scsi devices. It can read the identifier and +is needed for persistent naming. + + +HOW UDEV WORKS TO ASSIGN PERSISTENT NAMES: + +There are three places where device information is stored that udev +uses: +(1) /sys maintained by sysfs +(2) /etc/udev/udev.rules - where you can store the identifier to NAME +mapping information. +(3) The tdb (udev-021/tdb/tdb.c), trivial data base, that is held in +memory and holds the valid system configuration. It is not saved +between one boot to the next. It is constructed at boot time and +updated with configuration changes. + +The persistent names are kept (at least this is one way to do it) in +udev.rules (uuid and NAME), one entry per device. If you want to +initially give your 1000 disk devices a default name and then make +sure those names are preserved, here is how : + +Start with no special entry in udev.rules when do you an initial boot of +your system with disks in place. Udev will assign default names (there +are ways to control what you want for default too). + +Once the names are assigned, use a script supplied for scsi devices - +udev-021/extras/scsi_id/gen_scsi_id_udev_rules.sh +to generate the lines needed for udev.rules, one per device. Each line +indicates the identifier and the NAME it was assigned. You could +optionally create this manually if you prefer other names . + +[example entries in udev.rules for scsi disks] +BUS="scsi", PROGRAM="scsi_id", RESULT="",NAME="" +BUS="scsi", RESULT="",NAME="" +... +BUS="scsi", RESULT="",NAME="" + +(The actual file we used is the file udev.rules_1000_scsi_debug in this +directory ) + +Upon reboot, for each device a hotplug event occurs. The udev.rules +file is scanned looking for the device type (BUS) in this case for "scsi". +The first entry generated by the above program references a +PROGRAM in the key field (scsi_id) which is called to probe the device +and determine the unique identifier. sysfs is used to determine the +major/minor number for the device. The result of the program +execution (the uuid) is compared with the RESULT entry in the same +udev.rules line. + +-If it matches, then the NAME entered on this line is used. The uuid +and major/minor number is saved in tdb (newly recreated upon boot). +That device is created in /udev (the target directory name is +configurable) with the assigned NAME. + +-If it doesn't match, the RESULT (uuid) is preserved for use on the next +udev.rules line as long as the bus type (scsi) is the same. So the result +(the uuid) is compared on the next line, and the next until a match +occurs. + +-If no match occurs, the device will be assigned a default name. + +-Tdb is updated with the resulting name assignment. + + +Thus if the uuid and names are enumerated, they will be found, +assigned, and are therefore permanent. + +If the device is removed from a live system, a hotplug event occurs, +and it is removed from tdb and the /udev entry disappears. + +If it is re-inserted at a new location, the udev.rules file is scanned as +above. The new major/minor number goes in tdb with the uuid , the +name in udev.rules is found again, and the /udev name re-appears. + + + +PERFORMANCE + +Now the question becomes, how much longer does it take to scan the +udev.rules table once there are 1000 entries? + +To test this, we created 1000 "scsi " devices using the scsi debug +device driver supplied in the kernel. When this device driver is loaded +you can specify how many fake scsi devices to create. There is no +real I/O involved but it does respond to some scsi commands. It +simulates the uuid by using the device number assigned when the +device is created. + +Then we auto-generated entries into udev.rules with +gen_scsi_id_udev_rules.sh. We then removed the devices and +reassigned them to simulate a reboot. The delta between assigning +defaults and assigning the names enumerated in the udev.rules file +was 7 seconds (that's for 1000 drives). + +Scripts utilized the feature (described above) that saves the "RESULT" +key after one scsi-id program call for later reference with other +udev.rules entries (so only have one PROGRAM key is the moral of +the story). If you repeated the PROGRAM key, you would +unnecessarily call the program up to 999 times! + +The script that creates udev.rules did not work for 1000 drives (the +input line is too long). We determined that a patch for this already +existed but had not yet been checked in. + + + + + + + + + diff --git a/docs/persistent_naming/udev.rules_1000_scsi_debug b/docs/persistent_naming/udev.rules_1000_scsi_debug new file mode 100644 index 0000000000..e1598cb829 --- /dev/null +++ b/docs/persistent_naming/udev.rules_1000_scsi_debug @@ -0,0 +1,1014 @@ +# +# Start of autogenerated scsi_id rules. Edit the NAME portions of these +# rules to your liking. +# +BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="SSEAGATE ST336704LC 3CD1HVVA00007128JK12", NAME="disk-sda%n" + +# Further RESULT keys use the result of the last PROGRAM rule. +# Be careful not to add any rules containing PROGRAM key between here +# and the end of this section + +BUS="scsi", RESULT="3512345600000afc8", NAME="disk-sdaa%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaaa%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaab%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaac%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdaad%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaae%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaaf%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaag%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaah%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaai%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaaj%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaak%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaal%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaam%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdaan%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaao%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaap%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaaq%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaar%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaas%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdaat%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaau%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaav%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaaw%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaax%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaay%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaaz%n" +BUS="scsi", RESULT="3512345600000b3b0", NAME="disk-sdab%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaba%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdabb%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdabc%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdabd%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdabe%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdabf%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdabg%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdabh%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdabi%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdabj%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdabk%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdabl%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdabm%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdabn%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdabo%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdabp%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdabq%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdabr%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdabs%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdabt%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdabu%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdabv%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdabw%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdabx%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaby%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdabz%n" +BUS="scsi", RESULT="3512345600000b798", NAME="disk-sdac%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaca%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdacb%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdacc%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdacd%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdace%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdacf%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdacg%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdach%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaci%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdacj%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdack%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdacl%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdacm%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdacn%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaco%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdacp%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdacq%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdacr%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdacs%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdact%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdacu%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdacv%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdacw%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdacx%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdacy%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdacz%n" +BUS="scsi", RESULT="3512345600000bb80", NAME="disk-sdad%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdada%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdadb%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdadc%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdadd%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdade%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdadf%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdadg%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdadh%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdadi%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdadj%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdadk%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdadl%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdadm%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdadn%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdado%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdadp%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdadq%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdadr%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdads%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdadt%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdadu%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdadv%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdadw%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdadx%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdady%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdadz%n" +BUS="scsi", RESULT="3512345600000bf68", NAME="disk-sdae%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaea%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaeb%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaec%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaed%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaee%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdaef%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaeg%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaeh%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaei%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaej%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaek%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdael%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaem%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaen%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaeo%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaep%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaeq%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaer%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaes%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaet%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaeu%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdaev%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaew%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaex%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaey%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaez%n" +BUS="scsi", RESULT="3512345600000c350", NAME="disk-sdaf%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdafa%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdafb%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdafc%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdafd%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdafe%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaff%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdafg%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdafh%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdafi%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdafj%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdafk%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdafl%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdafm%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdafn%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdafo%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdafp%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdafq%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdafr%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdafs%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaft%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdafu%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdafv%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdafw%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdafx%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdafy%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdafz%n" +BUS="scsi", RESULT="3512345600000c738", NAME="disk-sdag%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaga%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdagb%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdagc%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdagd%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdage%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdagf%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdagg%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdagh%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdagi%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdagj%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdagk%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdagl%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdagm%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdagn%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdago%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdagp%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdagq%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdagr%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdags%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdagt%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdagu%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdagv%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdagw%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdagx%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdagy%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdagz%n" +BUS="scsi", RESULT="3512345600000cb20", NAME="disk-sdah%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaha%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdahb%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdahc%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdahd%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdahe%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdahf%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdahg%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdahh%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdahi%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdahj%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdahk%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdahl%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdahm%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdahn%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaho%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdahp%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdahq%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdahr%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdahs%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaht%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdahu%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdahv%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdahw%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdahx%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdahy%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdahz%n" +BUS="scsi", RESULT="3512345600000cf08", NAME="disk-sdai%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaia%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaib%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaic%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdaid%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaie%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaif%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaig%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaih%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaii%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaij%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaik%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdail%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaim%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdain%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaio%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaip%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaiq%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdair%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdais%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdait%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaiu%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaiv%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaiw%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaix%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaiy%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaiz%n" +BUS="scsi", RESULT="3512345600000d2f0", NAME="disk-sdaj%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaja%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdajb%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdajc%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdajd%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaje%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdajf%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdajg%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdajh%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaji%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdajj%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdajk%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdajl%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdajm%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdajn%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdajo%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdajp%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdajq%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdajr%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdajs%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdajt%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaju%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdajv%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdajw%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdajx%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdajy%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdajz%n" +BUS="scsi", RESULT="3512345600000d6d8", NAME="disk-sdak%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaka%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdakb%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdakc%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdakd%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdake%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdakf%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdakg%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdakh%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaki%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdakj%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdakk%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdakl%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdakm%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdakn%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdako%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdakp%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdakq%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdakr%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaks%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdakt%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaku%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdakv%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdakw%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdakx%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaky%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdakz%n" +BUS="scsi", RESULT="3512345600000dac0", NAME="disk-sdal%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdala%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdalb%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdalc%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdald%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdale%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdalf%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdalg%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdalh%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdali%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdalj%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdalk%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdall%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdalm%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaln%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdalo%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdalp%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdalq%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdalr%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdals%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdalt%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdalu%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdalv%n" +BUS="scsi", RESULT="3512345600000dea8", NAME="disk-sdam%n" +BUS="scsi", RESULT="3512345600000e290", NAME="disk-sdan%n" +BUS="scsi", RESULT="3512345600000e678", NAME="disk-sdao%n" +BUS="scsi", RESULT="3512345600000ea60", NAME="disk-sdap%n" +BUS="scsi", RESULT="3512345600000ee48", NAME="disk-sdaq%n" +BUS="scsi", RESULT="3512345600000f230", NAME="disk-sdar%n" +BUS="scsi", RESULT="3512345600000f618", NAME="disk-sdas%n" +BUS="scsi", RESULT="3512345600000fa00", NAME="disk-sdat%n" +BUS="scsi", RESULT="3512345600000fde8", NAME="disk-sdau%n" +BUS="scsi", RESULT="351234560000101d0", NAME="disk-sdav%n" +BUS="scsi", RESULT="351234560000105b8", NAME="disk-sdaw%n" +BUS="scsi", RESULT="351234560000109a0", NAME="disk-sdax%n" +BUS="scsi", RESULT="35123456000010d88", NAME="disk-sday%n" +BUS="scsi", RESULT="35123456000011170", NAME="disk-sdaz%n" +BUS="scsi", RESULT="SSEAGATE ST336704LC 3CD1HVBC000071283KA0", NAME="disk-sdb%n" +BUS="scsi", RESULT="35123456000011558", NAME="disk-sdba%n" +BUS="scsi", RESULT="35123456000011940", NAME="disk-sdbb%n" +BUS="scsi", RESULT="35123456000011d28", NAME="disk-sdbc%n" +BUS="scsi", RESULT="35123456000012110", NAME="disk-sdbd%n" +BUS="scsi", RESULT="351234560000124f8", NAME="disk-sdbe%n" +BUS="scsi", RESULT="351234560000128e0", NAME="disk-sdbf%n" +BUS="scsi", RESULT="35123456000012cc8", NAME="disk-sdbg%n" +BUS="scsi", RESULT="351234560000130b0", NAME="disk-sdbh%n" +BUS="scsi", RESULT="35123456000013498", NAME="disk-sdbi%n" +BUS="scsi", RESULT="35123456000013880", NAME="disk-sdbj%n" +BUS="scsi", RESULT="35123456000013c68", NAME="disk-sdbk%n" +BUS="scsi", RESULT="35123456000014050", NAME="disk-sdbl%n" +BUS="scsi", RESULT="35123456000014438", NAME="disk-sdbm%n" +BUS="scsi", RESULT="35123456000014820", NAME="disk-sdbn%n" +BUS="scsi", RESULT="35123456000014c08", NAME="disk-sdbo%n" +BUS="scsi", RESULT="35123456000014ff0", NAME="disk-sdbp%n" +BUS="scsi", RESULT="351234560000153d8", NAME="disk-sdbq%n" +BUS="scsi", RESULT="351234560000157c0", NAME="disk-sdbr%n" +BUS="scsi", RESULT="35123456000015ba8", NAME="disk-sdbs%n" +BUS="scsi", RESULT="35123456000015f90", NAME="disk-sdbt%n" +BUS="scsi", RESULT="35123456000016378", NAME="disk-sdbu%n" +BUS="scsi", RESULT="35123456000016760", NAME="disk-sdbv%n" +BUS="scsi", RESULT="35123456000016b48", NAME="disk-sdbw%n" +BUS="scsi", RESULT="35123456000016f30", NAME="disk-sdbx%n" +BUS="scsi", RESULT="35123456000017318", NAME="disk-sdby%n" +BUS="scsi", RESULT="35123456000017700", NAME="disk-sdbz%n" +BUS="scsi", RESULT="35123456000017ae8", NAME="disk-sdca%n" +BUS="scsi", RESULT="35123456000017ed0", NAME="disk-sdcb%n" +BUS="scsi", RESULT="351234560000182b8", NAME="disk-sdcc%n" +BUS="scsi", RESULT="351234560000186a0", NAME="disk-sdcd%n" +BUS="scsi", RESULT="35123456000018a88", NAME="disk-sdce%n" +BUS="scsi", RESULT="35123456000018e70", NAME="disk-sdcf%n" +BUS="scsi", RESULT="35123456000019258", NAME="disk-sdcg%n" +BUS="scsi", RESULT="35123456000019640", NAME="disk-sdch%n" +BUS="scsi", RESULT="35123456000019a28", NAME="disk-sdci%n" +BUS="scsi", RESULT="35123456000019e10", NAME="disk-sdcj%n" +BUS="scsi", RESULT="3512345600001a1f8", NAME="disk-sdck%n" +BUS="scsi", RESULT="3512345600001a5e0", NAME="disk-sdcl%n" +BUS="scsi", RESULT="3512345600001a9c8", NAME="disk-sdcm%n" +BUS="scsi", RESULT="3512345600001adb0", NAME="disk-sdcn%n" +BUS="scsi", RESULT="3512345600001b198", NAME="disk-sdco%n" +BUS="scsi", RESULT="3512345600001b580", NAME="disk-sdcp%n" +BUS="scsi", RESULT="3512345600001b968", NAME="disk-sdcq%n" +BUS="scsi", RESULT="3512345600001bd50", NAME="disk-sdcr%n" +BUS="scsi", RESULT="3512345600001c138", NAME="disk-sdcs%n" +BUS="scsi", RESULT="3512345600001c520", NAME="disk-sdct%n" +BUS="scsi", RESULT="3512345600001c908", NAME="disk-sdcu%n" +BUS="scsi", RESULT="3512345600001ccf0", NAME="disk-sdcv%n" +BUS="scsi", RESULT="3512345600001d0d8", NAME="disk-sdcw%n" +BUS="scsi", RESULT="3512345600001d4c0", NAME="disk-sdcx%n" +BUS="scsi", RESULT="3512345600001d8a8", NAME="disk-sdcy%n" +BUS="scsi", RESULT="3512345600001dc90", NAME="disk-sdcz%n" +BUS="scsi", RESULT="3512345600001e078", NAME="disk-sdda%n" +BUS="scsi", RESULT="3512345600001e460", NAME="disk-sddb%n" +BUS="scsi", RESULT="3512345600001e848", NAME="disk-sddc%n" +BUS="scsi", RESULT="3512345600001ec30", NAME="disk-sddd%n" +BUS="scsi", RESULT="3512345600001f018", NAME="disk-sdde%n" +BUS="scsi", RESULT="3512345600001f400", NAME="disk-sddf%n" +BUS="scsi", RESULT="35123456000007530", NAME="disk-sddg%n" +BUS="scsi", RESULT="35123456000007918", NAME="disk-sddh%n" +BUS="scsi", RESULT="35123456000007d00", NAME="disk-sddi%n" +BUS="scsi", RESULT="351234560000080e8", NAME="disk-sddj%n" +BUS="scsi", RESULT="351234560000084d0", NAME="disk-sddk%n" +BUS="scsi", RESULT="351234560000088b8", NAME="disk-sddl%n" +BUS="scsi", RESULT="35123456000008ca0", NAME="disk-sddm%n" +BUS="scsi", RESULT="35123456000009470", NAME="disk-sddn%n" +BUS="scsi", RESULT="35123456000009858", NAME="disk-sddo%n" +BUS="scsi", RESULT="35123456000009c40", NAME="disk-sddp%n" +BUS="scsi", RESULT="3512345600000a028", NAME="disk-sddq%n" +BUS="scsi", RESULT="3512345600000a410", NAME="disk-sddr%n" +BUS="scsi", RESULT="3512345600000a7f8", NAME="disk-sdds%n" +BUS="scsi", RESULT="3512345600000abe0", NAME="disk-sddt%n" +BUS="scsi", RESULT="3512345600000afc8", NAME="disk-sddu%n" +BUS="scsi", RESULT="3512345600000b3b0", NAME="disk-sddv%n" +BUS="scsi", RESULT="3512345600000b798", NAME="disk-sddw%n" +BUS="scsi", RESULT="3512345600000bb80", NAME="disk-sddx%n" +BUS="scsi", RESULT="3512345600000bf68", NAME="disk-sddy%n" +BUS="scsi", RESULT="3512345600000c350", NAME="disk-sddz%n" +BUS="scsi", RESULT="3512345600000c738", NAME="disk-sdea%n" +BUS="scsi", RESULT="3512345600000cb20", NAME="disk-sdeb%n" +BUS="scsi", RESULT="3512345600000cf08", NAME="disk-sdec%n" +BUS="scsi", RESULT="3512345600000d2f0", NAME="disk-sded%n" +BUS="scsi", RESULT="3512345600000d6d8", NAME="disk-sdee%n" +BUS="scsi", RESULT="3512345600000dac0", NAME="disk-sdef%n" +BUS="scsi", RESULT="3512345600000dea8", NAME="disk-sdeg%n" +BUS="scsi", RESULT="3512345600000e290", NAME="disk-sdeh%n" +BUS="scsi", RESULT="3512345600000e678", NAME="disk-sdei%n" +BUS="scsi", RESULT="3512345600000ea60", NAME="disk-sdej%n" +BUS="scsi", RESULT="3512345600000ee48", NAME="disk-sdek%n" +BUS="scsi", RESULT="3512345600000f230", NAME="disk-sdel%n" +BUS="scsi", RESULT="3512345600000f618", NAME="disk-sdem%n" +BUS="scsi", RESULT="3512345600000fa00", NAME="disk-sden%n" +BUS="scsi", RESULT="3512345600000fde8", NAME="disk-sdeo%n" +BUS="scsi", RESULT="351234560000101d0", NAME="disk-sdep%n" +BUS="scsi", RESULT="351234560000105b8", NAME="disk-sdeq%n" +BUS="scsi", RESULT="351234560000109a0", NAME="disk-sder%n" +BUS="scsi", RESULT="35123456000010d88", NAME="disk-sdes%n" +BUS="scsi", RESULT="35123456000011170", NAME="disk-sdet%n" +BUS="scsi", RESULT="35123456000011558", NAME="disk-sdeu%n" +BUS="scsi", RESULT="35123456000011940", NAME="disk-sdev%n" +BUS="scsi", RESULT="35123456000011d28", NAME="disk-sdew%n" +BUS="scsi", RESULT="35123456000012110", NAME="disk-sdex%n" +BUS="scsi", RESULT="351234560000124f8", NAME="disk-sdey%n" +BUS="scsi", RESULT="351234560000128e0", NAME="disk-sdez%n" +BUS="scsi", RESULT="35123456000012cc8", NAME="disk-sdfa%n" +BUS="scsi", RESULT="351234560000130b0", NAME="disk-sdfb%n" +BUS="scsi", RESULT="35123456000013498", NAME="disk-sdfc%n" +BUS="scsi", RESULT="35123456000013880", NAME="disk-sdfd%n" +BUS="scsi", RESULT="35123456000013c68", NAME="disk-sdfe%n" +BUS="scsi", RESULT="35123456000014050", NAME="disk-sdff%n" +BUS="scsi", RESULT="35123456000014438", NAME="disk-sdfg%n" +BUS="scsi", RESULT="35123456000014820", NAME="disk-sdfh%n" +BUS="scsi", RESULT="35123456000014c08", NAME="disk-sdfi%n" +BUS="scsi", RESULT="35123456000014ff0", NAME="disk-sdfj%n" +BUS="scsi", RESULT="351234560000153d8", NAME="disk-sdfk%n" +BUS="scsi", RESULT="351234560000157c0", NAME="disk-sdfl%n" +BUS="scsi", RESULT="35123456000015ba8", NAME="disk-sdfm%n" +BUS="scsi", RESULT="35123456000015f90", NAME="disk-sdfn%n" +BUS="scsi", RESULT="35123456000016378", NAME="disk-sdfo%n" +BUS="scsi", RESULT="35123456000016760", NAME="disk-sdfp%n" +BUS="scsi", RESULT="35123456000016b48", NAME="disk-sdfq%n" +BUS="scsi", RESULT="35123456000016f30", NAME="disk-sdfr%n" +BUS="scsi", RESULT="35123456000017318", NAME="disk-sdfs%n" +BUS="scsi", RESULT="35123456000017700", NAME="disk-sdft%n" +BUS="scsi", RESULT="35123456000017ae8", NAME="disk-sdfu%n" +BUS="scsi", RESULT="35123456000017ed0", NAME="disk-sdfv%n" +BUS="scsi", RESULT="351234560000182b8", NAME="disk-sdfw%n" +BUS="scsi", RESULT="351234560000186a0", NAME="disk-sdfx%n" +BUS="scsi", RESULT="35123456000018a88", NAME="disk-sdfy%n" +BUS="scsi", RESULT="35123456000018e70", NAME="disk-sdfz%n" +BUS="scsi", RESULT="35123456000019258", NAME="disk-sdga%n" +BUS="scsi", RESULT="35123456000019640", NAME="disk-sdgb%n" +BUS="scsi", RESULT="35123456000019a28", NAME="disk-sdgc%n" +BUS="scsi", RESULT="35123456000019e10", NAME="disk-sdgd%n" +BUS="scsi", RESULT="3512345600001a1f8", NAME="disk-sdge%n" +BUS="scsi", RESULT="3512345600001a5e0", NAME="disk-sdgf%n" +BUS="scsi", RESULT="3512345600001a9c8", NAME="disk-sdgg%n" +BUS="scsi", RESULT="3512345600001adb0", NAME="disk-sdgh%n" +BUS="scsi", RESULT="3512345600001b198", NAME="disk-sdgi%n" +BUS="scsi", RESULT="3512345600001b580", NAME="disk-sdgj%n" +BUS="scsi", RESULT="3512345600001b968", NAME="disk-sdgk%n" +BUS="scsi", RESULT="3512345600001bd50", NAME="disk-sdgl%n" +BUS="scsi", RESULT="3512345600001c138", NAME="disk-sdgm%n" +BUS="scsi", RESULT="3512345600001c520", NAME="disk-sdgn%n" +BUS="scsi", RESULT="3512345600001c908", NAME="disk-sdgo%n" +BUS="scsi", RESULT="3512345600001ccf0", NAME="disk-sdgp%n" +BUS="scsi", RESULT="3512345600001d0d8", NAME="disk-sdgq%n" +BUS="scsi", RESULT="3512345600001d4c0", NAME="disk-sdgr%n" +BUS="scsi", RESULT="3512345600001d8a8", NAME="disk-sdgs%n" +BUS="scsi", RESULT="3512345600001dc90", NAME="disk-sdgt%n" +BUS="scsi", RESULT="3512345600001e078", NAME="disk-sdgu%n" +BUS="scsi", RESULT="3512345600001e460", NAME="disk-sdgv%n" +BUS="scsi", RESULT="3512345600001e848", NAME="disk-sdgw%n" +BUS="scsi", RESULT="3512345600001ec30", NAME="disk-sdgx%n" +BUS="scsi", RESULT="3512345600001f018", NAME="disk-sdgy%n" +BUS="scsi", RESULT="3512345600001f400", NAME="disk-sdgz%n" +BUS="scsi", RESULT="3512345600001f7e8", NAME="disk-sdha%n" +BUS="scsi", RESULT="3512345600001fbd0", NAME="disk-sdhb%n" +BUS="scsi", RESULT="35123456000007d00", NAME="disk-sdhc%n" +BUS="scsi", RESULT="351234560000080e8", NAME="disk-sdhd%n" +BUS="scsi", RESULT="351234560000084d0", NAME="disk-sdhe%n" +BUS="scsi", RESULT="351234560000088b8", NAME="disk-sdhf%n" +BUS="scsi", RESULT="35123456000008ca0", NAME="disk-sdhg%n" +BUS="scsi", RESULT="35123456000009088", NAME="disk-sdhh%n" +BUS="scsi", RESULT="35123456000009470", NAME="disk-sdhi%n" +BUS="scsi", RESULT="35123456000009c40", NAME="disk-sdhj%n" +BUS="scsi", RESULT="3512345600000a028", NAME="disk-sdhk%n" +BUS="scsi", RESULT="3512345600000a410", NAME="disk-sdhl%n" +BUS="scsi", RESULT="3512345600000a7f8", NAME="disk-sdhm%n" +BUS="scsi", RESULT="3512345600000abe0", NAME="disk-sdhn%n" +BUS="scsi", RESULT="3512345600000afc8", NAME="disk-sdho%n" +BUS="scsi", RESULT="3512345600000b3b0", NAME="disk-sdhp%n" +BUS="scsi", RESULT="3512345600000b798", NAME="disk-sdhq%n" +BUS="scsi", RESULT="3512345600000bb80", NAME="disk-sdhr%n" +BUS="scsi", RESULT="3512345600000bf68", NAME="disk-sdhs%n" +BUS="scsi", RESULT="3512345600000c350", NAME="disk-sdht%n" +BUS="scsi", RESULT="3512345600000c738", NAME="disk-sdhu%n" +BUS="scsi", RESULT="3512345600000cb20", NAME="disk-sdhv%n" +BUS="scsi", RESULT="3512345600000cf08", NAME="disk-sdhw%n" +BUS="scsi", RESULT="3512345600000d2f0", NAME="disk-sdhx%n" +BUS="scsi", RESULT="3512345600000d6d8", NAME="disk-sdhy%n" +BUS="scsi", RESULT="3512345600000dac0", NAME="disk-sdhz%n" +BUS="scsi", RESULT="3512345600000dea8", NAME="disk-sdia%n" +BUS="scsi", RESULT="3512345600000e290", NAME="disk-sdib%n" +BUS="scsi", RESULT="3512345600000e678", NAME="disk-sdic%n" +BUS="scsi", RESULT="3512345600000ea60", NAME="disk-sdid%n" +BUS="scsi", RESULT="3512345600000ee48", NAME="disk-sdie%n" +BUS="scsi", RESULT="3512345600000f230", NAME="disk-sdif%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdig%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdih%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdii%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdij%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdik%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdil%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdim%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdin%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdio%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdip%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdiq%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdir%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdis%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdit%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdiu%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdiv%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdiw%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdix%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdiy%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdiz%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdja%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdjb%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdjc%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdjd%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdje%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdjf%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdjg%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdjh%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdji%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdjj%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdjk%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdjl%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdjm%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdjn%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdjo%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdjp%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdjq%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdjr%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdjs%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdjt%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdju%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdjv%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdjw%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdjx%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdjy%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdjz%n" +BUS="scsi", RESULT="35123456000006d60", NAME="disk-sdk%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdka%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdkb%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdkc%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdkd%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdke%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdkf%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdkg%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdkh%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdki%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdkj%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdkk%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdkl%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdkm%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdkn%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdko%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdkp%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdkq%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdkr%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdks%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdkt%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdku%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdkv%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdkw%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdkx%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdky%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdkz%n" +BUS="scsi", RESULT="35123456000007148", NAME="disk-sdl%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdla%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdlb%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdlc%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdld%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdle%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdlf%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdlg%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdlh%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdli%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdlj%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdlk%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdll%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdlm%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdln%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdlo%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdlp%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdlq%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdlr%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdls%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdlt%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdlu%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdlv%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdlw%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdlx%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdly%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdlz%n" +BUS="scsi", RESULT="35123456000007530", NAME="disk-sdm%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdma%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdmb%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdmc%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdmd%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdme%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdmf%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdmg%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdmh%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdmi%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdmj%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdmk%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdml%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdmm%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdmn%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdmo%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdmp%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdmq%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdmr%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdms%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdmt%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdmu%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdmv%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdmw%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdmx%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdmy%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdmz%n" +BUS="scsi", RESULT="35123456000007918", NAME="disk-sdn%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdna%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdnb%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdnc%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdnd%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdne%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdnf%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdng%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdnh%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdni%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdnj%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdnk%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdnl%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdnm%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdnn%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdno%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdnp%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdnq%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdnr%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdns%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdnt%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdnu%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdnv%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdnw%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdnx%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdny%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdnz%n" +BUS="scsi", RESULT="35123456000007d00", NAME="disk-sdo%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdoa%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdob%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdoc%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdod%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdoe%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdof%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdog%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdoh%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdoi%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdoj%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdok%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdol%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdom%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdon%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdoo%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdop%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdoq%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdor%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdos%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdot%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdou%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdov%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdow%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdox%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdoy%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdoz%n" +BUS="scsi", RESULT="351234560000080e8", NAME="disk-sdp%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdpa%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdpb%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdpc%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdpd%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdpe%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdpf%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdpg%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdph%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdpi%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdpj%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdpk%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdpl%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdpm%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdpn%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdpo%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdpp%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdpq%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdpr%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdps%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdpt%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdpu%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdpv%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdpw%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdpx%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdpy%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdpz%n" +BUS="scsi", RESULT="351234560000084d0", NAME="disk-sdq%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdqa%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdqb%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdqc%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdqd%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdqe%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdqf%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdqg%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdqh%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdqi%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdqj%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdqk%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdql%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdqm%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdqn%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdqo%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdqp%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdqq%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdqr%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdqs%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdqt%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdqu%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdqv%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdqw%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdqx%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdqy%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdqz%n" +BUS="scsi", RESULT="35123456000008ca0", NAME="disk-sdr%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdra%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdrb%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdrc%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdrd%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdre%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdrf%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdrg%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdrh%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdri%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdrj%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdrk%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdrl%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdrm%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdrn%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdro%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdrp%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdrq%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdrr%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdrs%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdrt%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdru%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdrv%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdrw%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdrx%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdry%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdrz%n" +BUS="scsi", RESULT="35123456000009088", NAME="disk-sds%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdsa%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdsb%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdsc%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdsd%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdse%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdsf%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdsg%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdsh%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdsi%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdsj%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdsk%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdsl%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdsm%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdsn%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdso%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdsp%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdsq%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdsr%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdss%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdst%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdsu%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdsv%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdsw%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdsx%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdsy%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdsz%n" +BUS="scsi", RESULT="35123456000009470", NAME="disk-sdt%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdta%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdtb%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdtc%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdtd%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdte%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdtf%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdtg%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdth%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdti%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdtj%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdtk%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdtl%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdtm%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdtn%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdto%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdtp%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdtq%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdtr%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdts%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdtt%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdtu%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdtv%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdtw%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdtx%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdty%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdtz%n" +BUS="scsi", RESULT="35123456000009858", NAME="disk-sdu%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdua%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdub%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sduc%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdud%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdue%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sduf%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdug%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sduh%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdui%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sduj%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sduk%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdul%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdum%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdun%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sduo%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdup%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sduq%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdur%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdus%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdut%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sduu%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sduv%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sduw%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdux%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sduy%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sduz%n" +BUS="scsi", RESULT="35123456000009c40", NAME="disk-sdv%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdva%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdvb%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdvc%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdvd%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdve%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdvf%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdvg%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdvh%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdvi%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdvj%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdvk%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdvl%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdvm%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdvn%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdvo%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdvp%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdvq%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdvr%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdvs%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdvt%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdvu%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdvv%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdvw%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdvx%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdvy%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdvz%n" +BUS="scsi", RESULT="3512345600000a028", NAME="disk-sdw%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdwa%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdwb%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdwc%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdwd%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdwe%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdwf%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdwg%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdwh%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdwi%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdwj%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdwk%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdwl%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdwm%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdwn%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdwo%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdwp%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdwq%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdwr%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdws%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdwt%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdwu%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdwv%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdww%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdwx%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdwy%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdwz%n" +BUS="scsi", RESULT="3512345600000a410", NAME="disk-sdx%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdxa%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdxb%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdxc%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdxd%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdxe%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdxf%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdxg%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdxh%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdxi%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdxj%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdxk%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdxl%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdxm%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdxn%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdxo%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdxp%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdxq%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdxr%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdxs%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdxt%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdxu%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdxv%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdxw%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdxx%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdxy%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdxz%n" +BUS="scsi", RESULT="3512345600000a7f8", NAME="disk-sdy%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdya%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdyb%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdyc%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdyd%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdye%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdyf%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdyg%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdyh%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdyi%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdyj%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdyk%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdyl%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdym%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdyn%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdyo%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdyp%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdyq%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdyr%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdys%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdyt%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdyu%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdyv%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdyw%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdyx%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdyy%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdyz%n" +BUS="scsi", RESULT="3512345600000abe0", NAME="disk-sdz%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdza%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdzb%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdzc%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdzd%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdze%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdzf%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdzg%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdzh%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdzi%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdzj%n" +BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdzk%n" +BUS="scsi", RESULT="35123456000023280", NAME="disk-sdzl%n" +BUS="scsi", RESULT="35123456000023668", NAME="disk-sdzm%n" +BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdzn%n" +BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdzo%n" +BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdzp%n" +BUS="scsi", RESULT="35123456000020788", NAME="disk-sdzq%n" +BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdzr%n" +BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdzs%n" +BUS="scsi", RESULT="35123456000021340", NAME="disk-sdzt%n" +BUS="scsi", RESULT="35123456000021728", NAME="disk-sdzu%n" +BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdzv%n" +BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdzw%n" +BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdzx%n" +BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdzy%n" +BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdzz%n" +# +# End of autogenerated scsi_id rules +# From 52a8572366c15cc2676e3fad433f366ba3bc279c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Mar 2004 18:17:38 -0800 Subject: [PATCH 0712/4284] [PATCH] clean up the OSDL document formatting a bit --- docs/persistent_naming/Testing_scsi_notes.txt | 213 ------------------ docs/persistent_naming/testing_scsi_notes.txt | 203 +++++++++++++++++ 2 files changed, 203 insertions(+), 213 deletions(-) delete mode 100644 docs/persistent_naming/Testing_scsi_notes.txt create mode 100644 docs/persistent_naming/testing_scsi_notes.txt diff --git a/docs/persistent_naming/Testing_scsi_notes.txt b/docs/persistent_naming/Testing_scsi_notes.txt deleted file mode 100644 index 5013c87e1d..0000000000 --- a/docs/persistent_naming/Testing_scsi_notes.txt +++ /dev/null @@ -1,213 +0,0 @@ -Using UDEV to do Persistent storage device naming -for large numbers of storage devices -3/16/2004 - -Here are some lessons we learned at OSDL recently on how to use -UDEV (version 021) to do persistent device naming for lots of storage -devices. We used what was available in udev for scsi devices. Here is -an outline of this report: - -Background information - a list of resources we needed to get -started. -Setup - what we needed to create the right enviroment (kernel, -patches, drivers) -How udev works to assign persistent storage device names - -what the documentation didn't tell us. -Performance - A sanity test we ran to compare with and without -persistent naming. - - -BACKGROUND INFORMATION -To get started, here are some references. Review the overview -articles so that the rest of the information makes sense. - -Download the latest udev stuff from: -http://www.kernel.org/pub/linux/utils/kernel/hotplug/ - -mailing list: -linux-hotplug-devel@lists.sourceforge.net - -Here is a nice overview article to get started (warning, this is from -summer 2003 so many items indicated as "todo" have been done and -configuration file name references have sometime changed): -http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf -(also included when you download udev) - -More general info (also included in the udev package): -http://kernel.org/pub/linux/utils/kernel/hotplug/udev-FAQ -UDEV version 021 Announcement: -http://marc.theaimsgroup.com/?l=linux-hotplug-devel&m=107827264803336&w=2 - -"Managing Dynamic Naming" -http://lwn.net/Articles/28897/ - -If you are a fan of devfs, whatever you do, don't complain until you -read everything you possibly can about udev. This for example: -http://kernel.org/pub/linux/utils/kernel/hotplug/udev_vs_devfs - -You will need to create udev.rules to supply consistent names. (See -etc/udev/udev.rules in the download). This article gives you some -background about udev.rules, but avoids describing the "PROGRAM" -key which is needed for our work. Read it for background: -writing udev rules (current as of udev 018) -http://www.reactivated.net/udevrules.php - -bitkeeper tree: -bk://kernel.bkbits.net/gregkh/udev - -Libsysfs (used to get sysfs information): -http://www-124.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf - -UDEV works using the way hotplug events are handled by the kernel. -Several overview articles about hotplug include: -Hotplug events -http://lwn.net/Articles/52621/ -Overview of Hotplug -http://linux-hotplug.sourceforge.net/ - -Gentoo centric install info: -http://webpages.charter.net/decibelshelp/LinuxHelp_UDEVPrimer.html - -rpms built against Red Hat FC2-test1 may be available at: -http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.i386.rpm - -with the source rpm at: -http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.src.rpm - - - -SETUP - -Here is a brief checklist of what you need on your system for this to -work: - -Kernel must be a 2.6 kernel - -Must use CONFIG_HOTPLUG kernel config option, since the solution -is based on hotplug capabilities. - -To test more than 256 scsi devices you need a patch to the scsi driver -to support that many (available from IBM or SuSE). To see the patch -we used, see this link: -http://developer.osdl.org/maryedie/DCL/PSDN/lotsofdisks.patch - -Your storage device must support (via the driver) a unique identifier for -persistent device naming. (Adaptec RAID device does not, for -example.) - -Your device driver must support sysfs (new in 2.6 kernel). This is -already done for scsi devices and most if not all block devices. - -A program (scsi_id) exists in the udev download -( extras/scsi_id/scsi_id.c) for scsi devices. It can read the identifier and -is needed for persistent naming. - - -HOW UDEV WORKS TO ASSIGN PERSISTENT NAMES: - -There are three places where device information is stored that udev -uses: -(1) /sys maintained by sysfs -(2) /etc/udev/udev.rules - where you can store the identifier to NAME -mapping information. -(3) The tdb (udev-021/tdb/tdb.c), trivial data base, that is held in -memory and holds the valid system configuration. It is not saved -between one boot to the next. It is constructed at boot time and -updated with configuration changes. - -The persistent names are kept (at least this is one way to do it) in -udev.rules (uuid and NAME), one entry per device. If you want to -initially give your 1000 disk devices a default name and then make -sure those names are preserved, here is how : - -Start with no special entry in udev.rules when do you an initial boot of -your system with disks in place. Udev will assign default names (there -are ways to control what you want for default too). - -Once the names are assigned, use a script supplied for scsi devices - -udev-021/extras/scsi_id/gen_scsi_id_udev_rules.sh -to generate the lines needed for udev.rules, one per device. Each line -indicates the identifier and the NAME it was assigned. You could -optionally create this manually if you prefer other names . - -[example entries in udev.rules for scsi disks] -BUS="scsi", PROGRAM="scsi_id", RESULT="",NAME="" -BUS="scsi", RESULT="",NAME="" -... -BUS="scsi", RESULT="",NAME="" - -(The actual file we used is the file udev.rules_1000_scsi_debug in this -directory ) - -Upon reboot, for each device a hotplug event occurs. The udev.rules -file is scanned looking for the device type (BUS) in this case for "scsi". -The first entry generated by the above program references a -PROGRAM in the key field (scsi_id) which is called to probe the device -and determine the unique identifier. sysfs is used to determine the -major/minor number for the device. The result of the program -execution (the uuid) is compared with the RESULT entry in the same -udev.rules line. - --If it matches, then the NAME entered on this line is used. The uuid -and major/minor number is saved in tdb (newly recreated upon boot). -That device is created in /udev (the target directory name is -configurable) with the assigned NAME. - --If it doesn't match, the RESULT (uuid) is preserved for use on the next -udev.rules line as long as the bus type (scsi) is the same. So the result -(the uuid) is compared on the next line, and the next until a match -occurs. - --If no match occurs, the device will be assigned a default name. - --Tdb is updated with the resulting name assignment. - - -Thus if the uuid and names are enumerated, they will be found, -assigned, and are therefore permanent. - -If the device is removed from a live system, a hotplug event occurs, -and it is removed from tdb and the /udev entry disappears. - -If it is re-inserted at a new location, the udev.rules file is scanned as -above. The new major/minor number goes in tdb with the uuid , the -name in udev.rules is found again, and the /udev name re-appears. - - - -PERFORMANCE - -Now the question becomes, how much longer does it take to scan the -udev.rules table once there are 1000 entries? - -To test this, we created 1000 "scsi " devices using the scsi debug -device driver supplied in the kernel. When this device driver is loaded -you can specify how many fake scsi devices to create. There is no -real I/O involved but it does respond to some scsi commands. It -simulates the uuid by using the device number assigned when the -device is created. - -Then we auto-generated entries into udev.rules with -gen_scsi_id_udev_rules.sh. We then removed the devices and -reassigned them to simulate a reboot. The delta between assigning -defaults and assigning the names enumerated in the udev.rules file -was 7 seconds (that's for 1000 drives). - -Scripts utilized the feature (described above) that saves the "RESULT" -key after one scsi-id program call for later reference with other -udev.rules entries (so only have one PROGRAM key is the moral of -the story). If you repeated the PROGRAM key, you would -unnecessarily call the program up to 999 times! - -The script that creates udev.rules did not work for 1000 drives (the -input line is too long). We determined that a patch for this already -existed but had not yet been checked in. - - - - - - - - - diff --git a/docs/persistent_naming/testing_scsi_notes.txt b/docs/persistent_naming/testing_scsi_notes.txt new file mode 100644 index 0000000000..8d94c842b4 --- /dev/null +++ b/docs/persistent_naming/testing_scsi_notes.txt @@ -0,0 +1,203 @@ +Using UDEV to do Persistent storage device naming +for large numbers of storage devices +3/16/2004 + +Here are some lessons we learned at OSDL recently on how to use UDEV +(version 021) to do persistent device naming for lots of storage devices. +We used what was available in udev for scsi devices. Here is an outline of +this report: + +Background information + a list of resources we needed to get started. +Setup + what we needed to create the right enviroment (kernel, patches, + drivers) +How udev works to assign persistent storage device names + what the documentation didn't tell us. +Performance + A sanity test we ran to compare with and without persistent naming. + + +BACKGROUND INFORMATION +To get started, here are some references. Review the overview articles so +that the rest of the information makes sense. + +Download the latest udev stuff from: + http://www.kernel.org/pub/linux/utils/kernel/hotplug/ + +mailing list: + linux-hotplug-devel@lists.sourceforge.net + +Here is a nice overview article to get started (warning, this is from +summer 2003 so many items indicated as "todo" have been done and +configuration file name references have sometime changed): +http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf +(also included when you download udev) + +More general info (also included in the udev package): + http://kernel.org/pub/linux/utils/kernel/hotplug/udev-FAQ +UDEV version 021 Announcement: + http://marc.theaimsgroup.com/?l=linux-hotplug-devel&m=107827264803336&w=2 + +"Managing Dynamic Naming": + http://lwn.net/Articles/28897/ + +If you are a fan of devfs, whatever you do, don't complain until you read +everything you possibly can about udev. This for example: + http://kernel.org/pub/linux/utils/kernel/hotplug/udev_vs_devfs + +You will need to create udev.rules to supply consistent names. (See +etc/udev/udev.rules in the download). This article gives you some +background about udev.rules, but avoids describing the "PROGRAM" key which +is needed for our work. Read it for background: writing udev rules +(current as of udev 018) + http://www.reactivated.net/udevrules.php + +bitkeeper tree: + bk://kernel.bkbits.net/gregkh/udev + +Libsysfs used to get sysfs information): + http://www-124.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf + +UDEV works using the way hotplug events are handled by the kernel. +Several overview articles about hotplug include: +Hotplug events +http://lwn.net/Articles/52621/ +Overview of Hotplug +http://linux-hotplug.sourceforge.net/ + +Gentoo centric install info: +http://webpages.charter.net/decibelshelp/LinuxHelp_UDEVPrimer.html + +rpms built against Red Hat FC2-test1 may be available at: +http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.i386.rpm + +with the source rpm at: +http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.src.rpm + + + +SETUP + +Here is a brief checklist of what you need on your system for this to +work: + +Kernel must be a 2.6 kernel + +Must use CONFIG_HOTPLUG kernel config option, since the solution is based +on hotplug capabilities. + +To test more than 256 scsi devices you need a patch to the scsi driver to +support that many (available from IBM or SuSE). To see the patch we used, +see this link: +http://developer.osdl.org/maryedie/DCL/PSDN/lotsofdisks.patch + +Your storage device must support (via the driver) a unique identifier for +persistent device naming. (Adaptec RAID device does not, for example.) + +Your device driver must support sysfs (new in 2.6 kernel). This is already +done for scsi devices and most if not all block devices. + +A program (scsi_id) exists in the udev download (extras/scsi_id/scsi_id.c) +for scsi devices. It can read the identifier and is needed for persistent +naming. + + +HOW UDEV WORKS TO ASSIGN PERSISTENT NAMES: + +There are three places where device information is stored that udev +uses: +(1) /sys maintained by sysfs +(2) /etc/udev/udev.rules - where you can store the identifier to NAME + mapping information. +(3) The tdb (udev-021/tdb/tdb.c), trivial data base, that is held in + memory and holds the valid system configuration. It is not saved + between one boot to the next. It is constructed at boot time and + updated with configuration changes. + +The persistent names are kept (at least this is one way to do it) in +udev.rules (uuid and NAME), one entry per device. If you want to initially +give your 1000 disk devices a default name and then make sure those names +are preserved, here is how : + +Start with no special entry in udev.rules when do you an initial boot of +your system with disks in place. Udev will assign default names (there +are ways to control what you want for default too). + +Once the names are assigned, use a script supplied for scsi devices - +udev-021/extras/scsi_id/gen_scsi_id_udev_rules.sh to generate the lines +needed for udev.rules, one per device. Each line indicates the identifier +and the NAME it was assigned. You could optionally create this manually if +you prefer other names . + +[example entries in udev.rules for scsi disks] +BUS="scsi", PROGRAM="scsi_id", RESULT="",NAME="" +BUS="scsi", RESULT="",NAME="" +... +BUS="scsi", RESULT="",NAME="" + +(The actual file we used is the file udev.rules_1000_scsi_debug in this +directory ) + +Upon reboot, for each device a hotplug event occurs. The udev.rules file +is scanned looking for the device type (BUS) in this case for "scsi". The +first entry generated by the above program references a PROGRAM in the key +field (scsi_id) which is called to probe the device and determine the +unique identifier. sysfs is used to determine the major/minor number for +the device. The result of the program execution (the uuid) is compared +with the RESULT entry in the same udev.rules line. + +- If it matches, then the NAME entered on this line is used. The uuid and + major/minor number is saved in tdb (newly recreated upon boot). That + device is created in /udev (the target directory name is configurable) + with the assigned NAME. + +- If it doesn't match, the RESULT (uuid) is preserved for use on the next + udev.rules line as long as the bus type (scsi) is the same. So the + result (the uuid) is compared on the next line, and the next until a + match occurs. + +- If no match occurs, the device will be assigned a default name. + +- Tdb is updated with the resulting name assignment. + + +Thus if the uuid and names are enumerated, they will be found, assigned, +and are therefore permanent. + +If the device is removed from a live system, a hotplug event occurs, and it +is removed from tdb and the /udev entry disappears. + +If it is re-inserted at a new location, the udev.rules file is scanned as +above. The new major/minor number goes in tdb with the uuid , the name in +udev.rules is found again, and the /udev name re-appears. + + + +PERFORMANCE + +Now the question becomes, how much longer does it take to scan the +udev.rules table once there are 1000 entries? + +To test this, we created 1000 "scsi " devices using the scsi debug device +driver supplied in the kernel. When this device driver is loaded you can +specify how many fake scsi devices to create. There is no real I/O +involved but it does respond to some scsi commands. It simulates the uuid +by using the device number assigned when the device is created. + +Then we auto-generated entries into udev.rules with +gen_scsi_id_udev_rules.sh. We then removed the devices and reassigned them +to simulate a reboot. The delta between assigning defaults and assigning +the names enumerated in the udev.rules file was 7 seconds (that's for 1000 +drives). + +Scripts utilized the feature (described above) that saves the "RESULT" key +after one scsi-id program call for later reference with other udev.rules +entries (so only have one PROGRAM key is the moral of the story). If you +repeated the PROGRAM key, you would unnecessarily call the program up to +999 times! + +The script that creates udev.rules did not work for 1000 drives (the input +line is too long). We determined that a patch for this already existed but +had not yet been checked in. + From fa5acd760db98d8f7ec810e44e8d4527b115e43c Mon Sep 17 00:00:00 2001 From: "atul.sabharwal@intel.com" Date: Wed, 31 Mar 2004 18:18:58 -0800 Subject: [PATCH 0713/4284] [PATCH] Add chassis_id program to extras directory --- extras/chassis_id/Makefile | 26 ++++++++ extras/chassis_id/chassis_id.c | 112 ++++++++++++++++++++++++++++++++ extras/chassis_id/chassis_id.h | 34 ++++++++++ extras/chassis_id/provision.tbl | 5 ++ extras/chassis_id/table.c | 102 +++++++++++++++++++++++++++++ 5 files changed, 279 insertions(+) create mode 100644 extras/chassis_id/Makefile create mode 100644 extras/chassis_id/chassis_id.c create mode 100644 extras/chassis_id/chassis_id.h create mode 100644 extras/chassis_id/provision.tbl create mode 100644 extras/chassis_id/table.c diff --git a/extras/chassis_id/Makefile b/extras/chassis_id/Makefile new file mode 100644 index 0000000000..d3152e863c --- /dev/null +++ b/extras/chassis_id/Makefile @@ -0,0 +1,26 @@ +# +# ** +# ** (C) 2003 Intel Corporation +# ** Atul Sabharwal +# ** +# ** $Id: Makefile,v 1.3 2004/03/22 23:54:54 atul Exp $ +# ** +# ** Distributed under the terms of the GNU Public License, v2.0 or +# ** later. +# ** +# ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; +# ** with his permission, they have been re-licensed GPL, and his +# ** copyright still applies on them. +# ** +# */ +# +CFLAGS = -g +TARGET = chassis_id + +all: chassis_id + +chassis_id: chassis_id.c table.c + gcc -o $(TARGET) $(CFLAGS) chassis_id.c table.c + +clean: + rm -rf core a.out $(TARGET) diff --git a/extras/chassis_id/chassis_id.c b/extras/chassis_id/chassis_id.c new file mode 100644 index 0000000000..8f878b2c6e --- /dev/null +++ b/extras/chassis_id/chassis_id.c @@ -0,0 +1,112 @@ + + /* -*-c-*-: + ** + ** (C) 2003 Intel Corporation + ** Atul Sabharwal + ** + ** $Id: chassis_id.c,v 1.8 2004/03/22 23:33:10 atul Exp $ + ** + ** Distributed under the terms of the GNU Public License, v2.0 or + ** later. + ** + ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; + ** with his permission, they have been re-licensed GPL, and his + ** copyright still applies on them. + ** + */ + +#include +#include +#include + +#include "chassis_id.h" + +//#define DEBUG 1 + +int main(int argc, char **argv, char ** envp) +{ + int chassis_num, slot_num, retval, host_num; + char disk_snum[255], devpath[255]; + char * ptr; + int disk_index; + + syslog( LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", "starting chassis_id" ); + +#if 0 + ptr = (char *) getenv( "CHASSIS"); + if( ptr == NULL ) + return -ERROR_NO_CHASSIS; + + sscanf(ptr, "%d", &chassis_num); + #ifdef DEBUG + syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "Chassis %d", chassis_num); + #endif + + + ptr = (char *) getenv( "SLOT" ); + if( ptr== NULL ) + return -ERROR_NO_SLOT; + + sscanf(ptr, "%d", &slot_num); + #ifdef DEBUG + syslog( LOG_PID|LOG_DAEMON| LOG_ERR, "Slot %d", slot_num); + #endif +#endif + ptr = (char *) getenv( "DEVPATH"); + if( ptr == NULL ) + return -ERROR_NO_DEVPATH; + + sscanf(ptr, "%s", &devpath[0]); + #ifdef DEBUG + syslog( LOG_PID|LOG_DAEMON| LOG_ERR, "Devpath %s", devpath); + #endif + + retval = table_init(); + if(retval < 0 ) + return -ERROR_BAD_TABLE; + + getserial_number( devpath, disk_snum); + + + /* Now we open the provisioning table t find actual entry for the serial number*/ + disk_index = table_find_disk(disk_snum, &host_num, &chassis_num, &slot_num); + if ( disk_index == -1 ) + { + //typical provisioning error + return -ERROR_NO_DISK; + } + else + { + table_select_disk( disk_index ); + } + return 0; +} + + +/* Run SCSI id to find serial number of the device */ +int getserial_number( char * devpath, char * snumber ) +{ + FILE *fp; + char vendor [255], model[255], cmd[255]; + int retval; + + sprintf(cmd, "/sbin/scsi_id -s %s -p 0x80", devpath); + + fp = popen( cmd, "r"); + + if (fp == NULL) + return -ERROR_BAD_SNUMBER; + + fscanf( fp, "%s %s %s", vendor, model, snumber); + #ifdef DEBUG + syslog( LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", snumber ); + #endif + + retval = pclose(fp); + if (retval == -1) + return -ERROR_BAD_SNUMBER; + else + return NO_ERROR; + +} + diff --git a/extras/chassis_id/chassis_id.h b/extras/chassis_id/chassis_id.h new file mode 100644 index 0000000000..db5db90c21 --- /dev/null +++ b/extras/chassis_id/chassis_id.h @@ -0,0 +1,34 @@ + + /* -*-c-*-: + ** + ** (C) 2003 Intel Corporation + ** Atul Sabharwal + ** + ** $Id: chassis_id.h,v 1.1 2004/03/16 18:24:44 atul Exp $ + ** + ** Distributed under the terms of the GNU Public License, v2.0 or + ** later. + ** + ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; + ** with his permission, they have been re-licensed GPL, and his + ** copyright still applies on them. + ** + */ + +#ifndef _CHASSIS_ID_H +#define _CHASSIS_ID_H + +//#define DEBUG 1 +#define ERROR 1 +#define ERROR_NO_SLOT 2 +#define ERROR_NO_CHASSIS 3 +#define ERROR_NO_DEVPATH 4 +#define ERROR_BAD_SNUMBER 5 +#define ERROR_NO_DISK 6 +#define ERROR_BAD_TABLE 7 +#define ERROR_BAD_SCAN 8 +#define NO_ERROR 0 + +extern int table_init(); + +#endif diff --git a/extras/chassis_id/provision.tbl b/extras/chassis_id/provision.tbl new file mode 100644 index 0000000000..c137fd537f --- /dev/null +++ b/extras/chassis_id/provision.tbl @@ -0,0 +1,5 @@ +id host number_of_disks chassis# slot# serial# name +1 1 2 1 2 3BM07NKA000070456Z6B disk1 +2 1 2 1 2 3BM07R68000070456ZCK disk2 +3 2 2 1 3 3EV08ANK00007219JAVA disk3 +4 2 2 1 4 3EV00NZB000072190Y90 disk4 diff --git a/extras/chassis_id/table.c b/extras/chassis_id/table.c new file mode 100644 index 0000000000..418497edbe --- /dev/null +++ b/extras/chassis_id/table.c @@ -0,0 +1,102 @@ + /* -*-c-*-: + ** + ** (C) 2003 Intel Corporation + ** Atul Sabharwal + ** + ** $Id: table.c,v 1.4 2004/03/18 21:56:24 atul Exp $ + ** + ** Distributed under the terms of the GNU Public License, v2.0 or + ** later. + ** + ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; + ** with his permission, they have been re-licensed GPL, and his + ** copyright still applies on them. + ** + */ + +#include +#define TABLE_SIZE 100 +#define PROVISION_DB "/usr/local/bin/provision.tbl" + +struct provision_record +{ + int id; + int host_num; //port # or adaptor number + int num_disks; + int chassis_num; + int slot_num; + char serial_num[32]; + char name[32]; + +} ptable[TABLE_SIZE]; + +int ptable_size; + +/* Initialize the provisioning table by reading the data from special file provision.tbl * + Return error if something does not work appropriately. */ +int table_init() +{ + FILE *fp; + char ptr[255]; + int i; + + fp=fopen( PROVISION_DB, "r"); + + if ((fp== NULL) || feof(fp)) + return -1; + + //skip the first line of text which contains descriptive details. + fgets(ptr, 80, fp); + i = 0; + while (!feof(fp)) + { + fgets(ptr, 80, fp); + sscanf( ptr, "%d %d %d %d %d %s %s", &ptable[i].id, &ptable[i].host_num, + &ptable[i].num_disks, &ptable[i].chassis_num, &ptable[i].slot_num, + ptable[i].serial_num, ptable[i].name ); + i++; + } + + ptable_size = i; + fclose(fp); + return 0; +} + + +/* return -1 when no disk found. Otherwise return index of disk */ +int table_find_disk( char * serialnumber , int * host_num, int * chassis_num, int *slot_num) +{ + + int i; + + for(i = 0; i < ptable_size; i++) + { + + if(strcmp(ptable[i].serial_num, serialnumber) == 0) + { + + *host_num = ptable[i].host_num; + *chassis_num = ptable[i].chassis_num; + *slot_num = ptable[i].slot_num; + break; + } + } + + if(i == ptable_size) + return -1; + else + return i; +} + +/* This function is primarily there for passing the selected disk entry to udev so that * + * it can create descriptive GDN for it. So, for that we need to output this data to * + * stdout. */ +int table_select_disk( int diskindex ) +{ + printf("%d ", ptable[diskindex].chassis_num); + printf("%d ", ptable[diskindex].slot_num); + printf("%d ", ptable[diskindex].host_num); + printf("%s ", ptable[diskindex].name); + +} + From 0bcdc8498cdeaaef37444d38f39a19ff9557914d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 31 Mar 2004 18:27:02 -0800 Subject: [PATCH 0714/4284] [PATCH] clean up chassis_id coding style. --- extras/chassis_id/chassis_id.c | 146 ++++++++++++++++----------------- extras/chassis_id/chassis_id.h | 49 ++++++----- extras/chassis_id/table.c | 137 +++++++++++++++---------------- 3 files changed, 158 insertions(+), 174 deletions(-) diff --git a/extras/chassis_id/chassis_id.c b/extras/chassis_id/chassis_id.c index 8f878b2c6e..857707eac7 100644 --- a/extras/chassis_id/chassis_id.c +++ b/extras/chassis_id/chassis_id.c @@ -1,19 +1,16 @@ - - /* -*-c-*-: - ** - ** (C) 2003 Intel Corporation - ** Atul Sabharwal - ** - ** $Id: chassis_id.c,v 1.8 2004/03/22 23:33:10 atul Exp $ - ** - ** Distributed under the terms of the GNU Public License, v2.0 or - ** later. - ** - ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; - ** with his permission, they have been re-licensed GPL, and his - ** copyright still applies on them. - ** - */ +/* -*-c-*-: + ** + ** (C) 2003 Intel Corporation + ** Atul Sabharwal + ** + ** Distributed under the terms of the GNU Public License, v2.0 or + ** later. + ** + ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; + ** with his permission, they have been re-licensed GPL, and his + ** copyright still applies on them + ** + */ #include #include @@ -25,88 +22,83 @@ int main(int argc, char **argv, char ** envp) { - int chassis_num, slot_num, retval, host_num; - char disk_snum[255], devpath[255]; - char * ptr; - int disk_index; + int chassis_num, slot_num, retval, host_num; + char disk_snum[255], devpath[255]; + char *ptr; + int disk_index; - syslog( LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", "starting chassis_id" ); + syslog( LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", "starting chassis_id" ); #if 0 - ptr = (char *) getenv( "CHASSIS"); - if( ptr == NULL ) - return -ERROR_NO_CHASSIS; + ptr = getenv("CHASSIS"); + if (ptr == NULL) + return -ERROR_NO_CHASSIS; - sscanf(ptr, "%d", &chassis_num); - #ifdef DEBUG - syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "Chassis %d", chassis_num); - #endif + sscanf(ptr, "%d", &chassis_num); + #ifdef DEBUG + syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "Chassis %d", chassis_num); + #endif - ptr = (char *) getenv( "SLOT" ); - if( ptr== NULL ) - return -ERROR_NO_SLOT; + ptr = getenv("SLOT"); + if (ptr== NULL) + return -ERROR_NO_SLOT; - sscanf(ptr, "%d", &slot_num); - #ifdef DEBUG - syslog( LOG_PID|LOG_DAEMON| LOG_ERR, "Slot %d", slot_num); - #endif + sscanf(ptr, "%d", &slot_num); + #ifdef DEBUG + syslog( LOG_PID|LOG_DAEMON| LOG_ERR, "Slot %d", slot_num); + #endif #endif - ptr = (char *) getenv( "DEVPATH"); - if( ptr == NULL ) - return -ERROR_NO_DEVPATH; + ptr = getenv("DEVPATH"); + if (ptr == NULL) + return -ERROR_NO_DEVPATH; - sscanf(ptr, "%s", &devpath[0]); - #ifdef DEBUG - syslog( LOG_PID|LOG_DAEMON| LOG_ERR, "Devpath %s", devpath); - #endif + sscanf(ptr, "%s", &devpath[0]); + #ifdef DEBUG + syslog(LOG_PID|LOG_DAEMON| LOG_ERR, "Devpath %s", devpath); + #endif - retval = table_init(); - if(retval < 0 ) - return -ERROR_BAD_TABLE; - - getserial_number( devpath, disk_snum); - + retval = table_init(); + if (retval < 0) + return -ERROR_BAD_TABLE; - /* Now we open the provisioning table t find actual entry for the serial number*/ - disk_index = table_find_disk(disk_snum, &host_num, &chassis_num, &slot_num); - if ( disk_index == -1 ) - { - //typical provisioning error - return -ERROR_NO_DISK; - } - else - { - table_select_disk( disk_index ); - } - return 0; + getserial_number(devpath, disk_snum); + + /* Now we open the provisioning table t find actual entry for the serial number*/ + disk_index = table_find_disk(disk_snum, &host_num, &chassis_num, &slot_num); + if ( disk_index == -1 ) { + // typical provisioning error + return -ERROR_NO_DISK; + } else { + table_select_disk( disk_index ); + } + return 0; } /* Run SCSI id to find serial number of the device */ int getserial_number( char * devpath, char * snumber ) { - FILE *fp; - char vendor [255], model[255], cmd[255]; - int retval; + FILE *fp; + char vendor[255], model[255], cmd[255]; + int retval; - sprintf(cmd, "/sbin/scsi_id -s %s -p 0x80", devpath); + sprintf(cmd, "/sbin/scsi_id -s %s -p 0x80", devpath); - fp = popen( cmd, "r"); + fp = popen(cmd, "r"); - if (fp == NULL) - return -ERROR_BAD_SNUMBER; + if (fp == NULL) + return -ERROR_BAD_SNUMBER; - fscanf( fp, "%s %s %s", vendor, model, snumber); - #ifdef DEBUG - syslog( LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", snumber ); - #endif - - retval = pclose(fp); - if (retval == -1) - return -ERROR_BAD_SNUMBER; - else - return NO_ERROR; + fscanf(fp, "%s %s %s", vendor, model, snumber); + #ifdef DEBUG + syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", snumber ); + #endif + retval = pclose(fp); + if (retval == -1) + return -ERROR_BAD_SNUMBER; + else + return NO_ERROR; } diff --git a/extras/chassis_id/chassis_id.h b/extras/chassis_id/chassis_id.h index db5db90c21..253e603bfd 100644 --- a/extras/chassis_id/chassis_id.h +++ b/extras/chassis_id/chassis_id.h @@ -1,33 +1,30 @@ - - /* -*-c-*-: - ** - ** (C) 2003 Intel Corporation - ** Atul Sabharwal - ** - ** $Id: chassis_id.h,v 1.1 2004/03/16 18:24:44 atul Exp $ - ** - ** Distributed under the terms of the GNU Public License, v2.0 or - ** later. - ** - ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; - ** with his permission, they have been re-licensed GPL, and his - ** copyright still applies on them. - ** - */ +/* -*-c-*-: + ** + ** (C) 2003 Intel Corporation + ** Atul Sabharwal + ** + ** Distributed under the terms of the GNU Public License, v2.0 or + ** later. + ** + ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; + ** with his permission, they have been re-licensed GPL, and his + ** copyright still applies on them. + ** + */ #ifndef _CHASSIS_ID_H #define _CHASSIS_ID_H -//#define DEBUG 1 -#define ERROR 1 -#define ERROR_NO_SLOT 2 -#define ERROR_NO_CHASSIS 3 -#define ERROR_NO_DEVPATH 4 -#define ERROR_BAD_SNUMBER 5 -#define ERROR_NO_DISK 6 -#define ERROR_BAD_TABLE 7 -#define ERROR_BAD_SCAN 8 -#define NO_ERROR 0 +//#define DEBUG 1 +#define ERROR 1 +#define ERROR_NO_SLOT 2 +#define ERROR_NO_CHASSIS 3 +#define ERROR_NO_DEVPATH 4 +#define ERROR_BAD_SNUMBER 5 +#define ERROR_NO_DISK 6 +#define ERROR_BAD_TABLE 7 +#define ERROR_BAD_SCAN 8 +#define NO_ERROR 0 extern int table_init(); diff --git a/extras/chassis_id/table.c b/extras/chassis_id/table.c index 418497edbe..e619fa9ef3 100644 --- a/extras/chassis_id/table.c +++ b/extras/chassis_id/table.c @@ -1,33 +1,33 @@ - /* -*-c-*-: - ** - ** (C) 2003 Intel Corporation - ** Atul Sabharwal - ** - ** $Id: table.c,v 1.4 2004/03/18 21:56:24 atul Exp $ - ** - ** Distributed under the terms of the GNU Public License, v2.0 or - ** later. - ** - ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; - ** with his permission, they have been re-licensed GPL, and his - ** copyright still applies on them. - ** - */ +/* -*-c-*-: + ** + ** (C) 2003 Intel Corporation + ** Atul Sabharwal + ** + ** $Id: table.c,v 1.4 2004/03/18 21:56:24 atul Exp $ + ** + ** Distributed under the terms of the GNU Public License, v2.0 or + ** later. + ** + ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; + ** with his permission, they have been re-licensed GPL, and his + ** copyright still applies on them. + ** + */ #include + #define TABLE_SIZE 100 #define PROVISION_DB "/usr/local/bin/provision.tbl" struct provision_record { - int id; - int host_num; //port # or adaptor number - int num_disks; - int chassis_num; - int slot_num; - char serial_num[32]; - char name[32]; - + int id; + int host_num; //port # or adaptor number + int num_disks; + int chassis_num; + int slot_num; + char serial_num[32]; + char name[32]; } ptable[TABLE_SIZE]; int ptable_size; @@ -36,67 +36,62 @@ int ptable_size; Return error if something does not work appropriately. */ int table_init() { - FILE *fp; - char ptr[255]; - int i; - - fp=fopen( PROVISION_DB, "r"); + FILE *fp; + char ptr[255]; + int i; - if ((fp== NULL) || feof(fp)) - return -1; + fp = fopen( PROVISION_DB, "r"); - //skip the first line of text which contains descriptive details. - fgets(ptr, 80, fp); - i = 0; - while (!feof(fp)) - { - fgets(ptr, 80, fp); - sscanf( ptr, "%d %d %d %d %d %s %s", &ptable[i].id, &ptable[i].host_num, - &ptable[i].num_disks, &ptable[i].chassis_num, &ptable[i].slot_num, - ptable[i].serial_num, ptable[i].name ); - i++; - } + if ((fp== NULL) || feof(fp)) + return -1; - ptable_size = i; - fclose(fp); - return 0; + // skip the first line of text which contains descriptive details. + fgets(ptr, 80, fp); + i = 0; + while (!feof(fp)) { + fgets(ptr, 80, fp); + sscanf(ptr, "%d %d %d %d %d %s %s", &ptable[i].id, + &ptable[i].host_num, &ptable[i].num_disks, + &ptable[i].chassis_num, &ptable[i].slot_num, + ptable[i].serial_num, ptable[i].name); + i++; + } + + ptable_size = i; + fclose(fp); + return 0; } -/* return -1 when no disk found. Otherwise return index of disk */ +/* return -1 when no disk found. Otherwise return index of disk */ int table_find_disk( char * serialnumber , int * host_num, int * chassis_num, int *slot_num) { - - int i; - - for(i = 0; i < ptable_size; i++) - { + int i; - if(strcmp(ptable[i].serial_num, serialnumber) == 0) - { + for (i = 0; i < ptable_size; i++) { + if (strcmp(ptable[i].serial_num, serialnumber) == 0) { + *host_num = ptable[i].host_num; + *chassis_num = ptable[i].chassis_num; + *slot_num = ptable[i].slot_num; + break; + } + } - *host_num = ptable[i].host_num; - *chassis_num = ptable[i].chassis_num; - *slot_num = ptable[i].slot_num; - break; - } - } - - if(i == ptable_size) - return -1; - else - return i; + if (i == ptable_size) + return -1; + else + return i; } -/* This function is primarily there for passing the selected disk entry to udev so that * - * it can create descriptive GDN for it. So, for that we need to output this data to * - * stdout. */ +/* This function is primarily there for passing the selected disk entry to udev + * so that it can create descriptive GDN for it. So, for that we need to output + * this data to stdout. + */ int table_select_disk( int diskindex ) { - printf("%d ", ptable[diskindex].chassis_num); - printf("%d ", ptable[diskindex].slot_num); - printf("%d ", ptable[diskindex].host_num); - printf("%s ", ptable[diskindex].name); - + printf("%d ", ptable[diskindex].chassis_num); + printf("%d ", ptable[diskindex].slot_num); + printf("%d ", ptable[diskindex].host_num); + printf("%s ", ptable[diskindex].name); } From 0536819cca9468cf383807037dbaa5ad0d48b60f Mon Sep 17 00:00:00 2001 From: "hare@suse.de" Date: Wed, 31 Mar 2004 22:56:45 -0800 Subject: [PATCH 0715/4284] [PATCH] fix SEGV in libsysfs/dlist.c Hi all, Greg, libsysfs/dlist.c: _dlist_mark_move() is missing checks for empty lists and may (and indeed, does) crash when=20 called with empty dlists. --- libsysfs/dlist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index 942eccb48c..b440d65bed 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -74,14 +74,14 @@ inline void *_dlist_mark_move(Dlist *list,int direction) { if(direction) { - if( list->marker->next!=NULL) + if( list->marker && list->marker->next!=NULL) list->marker=list->marker->next; else return(NULL); } else { - if( list->marker->prev!=NULL) + if( list->marker && list->marker->prev!=NULL) list->marker=list->marker->prev; else return(NULL); From c1f8ea9562765d920881d46aeac69cce554d7ce3 Mon Sep 17 00:00:00 2001 From: "atul.sabharwal@intel.com" Date: Wed, 31 Mar 2004 22:56:51 -0800 Subject: [PATCH 0716/4284] [PATCH] Add README for chassis_id --- extras/chassis_id/README | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 extras/chassis_id/README diff --git a/extras/chassis_id/README b/extras/chassis_id/README new file mode 100644 index 0000000000..51add4945e --- /dev/null +++ b/extras/chassis_id/README @@ -0,0 +1,28 @@ + README.txt + ~~~~~~~~~~ +Chassis_id is a callout program which is used to give geographic names to devices. It uses +another callout program scsi_id to determine the serial number of a device and then looks up +the provisioning table based on this key. It retrieves geographic information +( chassis#, slot# and host# ) about the device and prints it to stdout. These fields are +used by udev to create the device entry. + +Using Udev: +~~~~~~~~~~ +Chassis_id gets invoked by udev using the udev as below: + +BUS="scsi", PROGRAM="/usr/local/bin/chassis_id", NAME="/chassis%c{1}/slot%c{2}/host%c{3}/disk-%c{4} + +The provisioning table ( file provision.tbl ) has to be put in /usr/local/bin and as of now has +to be populated manually. This is the only place where the geographic map of devices is kept +in the system. + + +Usage Model: +~~~~~~~~~~~~ +On ATCA based blade architecture systems, blade insertion/removal is common. We create names +in a 3 level deep tree which represent the geographic map of the devices. + + +CONTACT: +~~~~~~~~ +Please feel free to contact atul.sabharwal@intel.com with questions, comments, suggestions. From 7b9b18392182e5cfa5d731288e8592549bdf67df Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 31 Mar 2004 23:00:45 -0800 Subject: [PATCH 0717/4284] [PATCH] udevinfo patch On Fri, Mar 26, 2004 at 06:36:32PM +0500, Ananth N Mavinakayanahalli wrote: > On Fri, Mar 26, 2004 at 11:24:39AM +0100, Kay Sievers wrote: > > On Fri, Mar 26, 2004 at 11:21:29AM +0500, Ananth N Mavinakayanahalli wrote: > > > On Fri, Mar 26, 2004 at 04:47:35AM +0100, Kay Sievers wrote: > > > > On Fri, Mar 26, 2004 at 01:26:46AM +0100, Carl-Daniel Hailfinger wrote: > > > > > Greg KH wrote: > > > > > > On Tue, Mar 23, 2004 at 01:51:01PM -0800, Daniel Stekloff wrote: > > > > > > > > No, it breaks the net device handling. I think we should change > > > > libsysfs instead, not to return a class device for '/block', if > > > > we want to fix it. > > > > > > /sys/block is considered a sysfs "class" and not a class_device. So, > > > going by udevinfo's help, -p expects path to a class_device and _not_ > > > a class itself and hence option /sys/block with -p is not a valid query. > > > > > > Kay? > > > > Yes, it's invalid, but we shouldn't print major minor for a invalid > > path. sysfs_open_class_device_path("/block") returns a device. If this is > > the right behavior for libsysfs, I will change the get_device_type("/block") > > not to return a 'b'-type. > > Libsysfs validates the path given to it for opening a class_device to be > a valid directory; it does not however validate if the path is a valid > class_device path. So, in the case of udevinfo, a 'b' type should not > be returned if the path is just /sys/block or /sys/block/ This may prevent it. --- udev_lib.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/udev_lib.c b/udev_lib.c index e9c16c863a..db1096ebf7 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -86,17 +86,28 @@ char *get_subsystem(char *subsystem) return subsystem; } +#define BLOCK_PATH "/block/" +#define CLASS_PATH "/class/" +#define NET_PATH "/class/net/" + char get_device_type(const char *path, const char *subsystem) { - if (strcmp(subsystem, "block") == 0 || - strstr(path, "/block/") != NULL) + if (strcmp(subsystem, "block") == 0) return 'b'; - if (strcmp(subsystem, "net") == 0 || - strstr(path, "/class/net/") != NULL) + if (strcmp(subsystem, "net") == 0) return 'n'; - if (strstr(path, "/class/") != NULL) + if (strncmp(path, BLOCK_PATH, strlen(BLOCK_PATH)) == 0 && + strlen(path) > strlen(BLOCK_PATH)) + return 'b'; + + if (strncmp(path, NET_PATH, strlen(NET_PATH)) == 0 && + strlen(path) > strlen(NET_PATH)) + return 'n'; + + if (strncmp(path, CLASS_PATH, strlen(CLASS_PATH)) == 0 && + strlen(path) > strlen(CLASS_PATH)) return 'c'; return '\0'; From f27125f98f6487e881a957726da895aebd799f0d Mon Sep 17 00:00:00 2001 From: "chris_friesen@sympatico.ca" Date: Wed, 31 Mar 2004 23:03:07 -0800 Subject: [PATCH 0718/4284] [PATCH] udevd race conditions and performance, assorted cleanups This patch covers a number of areas: 1) sysfs.h is fixed up to use the common dbg() macro. This fixes the case where DEBUG is defined but USE_LOG isn't. 2) udevstart.c is modified to include the proper headers, rather than getting them indirectly which can break depending on Makefile flags 3) udevd.c gets some major changes: a) I added a pipe from the signal handler. This fixes the race conditions that I mentioned earlier. Basically, the point of the pipe is to force the select() call to return immediately if a signal handler fired before we actually started the select() call. This then lets us run the appropriate code based on flags set in the signal handler proper. b) I added a number of flags to coalesce calls to common routines. This should make things slightly more efficient. c) since most calls will tend to come in with a sequence number larger than what has been received, I switched msg_queue_insert() to scan the msg_list backwards to improve performance. filename="udevd.diff" --- libsysfs/sysfs.h | 4 +- udevd.c | 165 ++++++++++++++++++++++++++++++++++++++--------- udevstart.c | 2 + 3 files changed, 139 insertions(+), 32 deletions(-) diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 1b800ddcd2..0fdb38af19 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -37,9 +37,7 @@ #ifdef DEBUG #include "../logging.h" #define dprintf(format, arg...) \ - do { \ - log_message (LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ - } while (0) + dbg(format, ##arg) #else #define dprintf(format, arg...) do { } while (0) #endif diff --git a/udevd.c b/udevd.c index 0757dcaf3d..3b91a458da 100644 --- a/udevd.c +++ b/udevd.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "list.h" #include "udev.h" @@ -41,9 +42,12 @@ #include "udevd.h" #include "logging.h" +static int pipefds[2]; static int expected_seqnum = 0; volatile static int children_waiting; -volatile static int msg_q_timeout; +volatile static int run_msg_q; +volatile static int sig_flag; +static int run_exec_q; static LIST_HEAD(msg_list); static LIST_HEAD(exec_list); @@ -51,6 +55,8 @@ static LIST_HEAD(running_list); static void exec_queue_manager(void); static void msg_queue_manager(void); +static void user_sighandler(void); +static void reap_kids(void); #ifdef LOG unsigned char logname[LOGNAME_SIZE]; @@ -66,10 +72,12 @@ void log_message (int level, const char *format, ...) static void msg_dump_queue(void) { +#ifdef DEBUG struct hotplug_msg *msg; list_for_each_entry(msg, &msg_list, list) dbg("sequence %d in queue", msg->seqnum); +#endif } static void msg_dump(struct hotplug_msg *msg) @@ -92,7 +100,6 @@ static void run_queue_delete(struct hotplug_msg *msg) { list_del(&msg->list); free(msg); - exec_queue_manager(); } /* orders the message in the queue by sequence number */ @@ -100,18 +107,20 @@ static void msg_queue_insert(struct hotplug_msg *msg) { struct hotplug_msg *loop_msg; - /* sort message by sequence number into list*/ - list_for_each_entry(loop_msg, &msg_list, list) - if (loop_msg->seqnum > msg->seqnum) + /* sort message by sequence number into list. events + * will tend to come in order, so scan the list backwards + */ + list_for_each_entry_reverse(loop_msg, &msg_list, list) + if (loop_msg->seqnum < msg->seqnum) break; - list_add_tail(&msg->list, &loop_msg->list); + list_add(&msg->list, &loop_msg->list); dbg("queued message seq %d", msg->seqnum); /* store timestamp of queuing */ msg->queue_time = time(NULL); /* run msg queue manager */ - msg_queue_manager(); + run_msg_q = 1; return ; } @@ -138,6 +147,9 @@ static void udev_run(struct hotplug_msg *msg) case -1: dbg("fork of child failed"); run_queue_delete(msg); + /* note: we never managed to run, so we had no impact on + * running_with_devpath(), so don't bother setting run_exec_q + */ break; default: /* get SIGCHLD in main loop */ @@ -180,7 +192,7 @@ static void exec_queue_manager() static void msg_move_exec(struct hotplug_msg *msg) { list_move_tail(&msg->list, &exec_list); - exec_queue_manager(); + run_exec_q = 1; expected_seqnum = msg->seqnum+1; dbg("moved seq %d to exec, next expected is %d", msg->seqnum, expected_seqnum); @@ -276,7 +288,7 @@ static void handle_msg(int sock) /* if no seqnum is given, we move straight to exec queue */ if (msg->seqnum == -1) { list_add(&msg->list, &exec_list); - exec_queue_manager(); + run_exec_q = 1; } else { msg_queue_insert(msg); } @@ -289,19 +301,37 @@ skip: static void sig_handler(int signum) { + int rc; switch (signum) { case SIGINT: case SIGTERM: exit(20 + signum); break; case SIGALRM: - msg_q_timeout = 1; + /* set flag, then write to pipe if needed */ + run_msg_q = 1; + goto do_write; break; case SIGCHLD: + /* set flag, then write to pipe if needed */ children_waiting = 1; + goto do_write; break; default: dbg("unhandled signal"); + return; + } + +do_write: + /* if pipe is empty, write to pipe to force select to return + * immediately when it gets called + */ + if (!sig_flag) { + rc = write(pipefds[1],&signum,sizeof(signum)); + if (rc < 0) + dbg("unable to write to pipe"); + else + sig_flag = 1; } } @@ -314,19 +344,53 @@ static void udev_done(int pid) if (msg->pid == pid) { dbg("<== exec seq %d came back", msg->seqnum); run_queue_delete(msg); + + /* we want to run the exec queue manager since there may + * be events waiting with the devpath of the one that + * just finished + */ + run_exec_q = 1; return; } } } +static void reap_kids() +{ + /* reap all dead children */ + while(1) { + int pid = waitpid(-1, 0, WNOHANG); + if ((pid == -1) || (pid == 0)) + break; + udev_done(pid); + } +} + +/* just read everything from the pipe and clear the flag, + * the useful flags were set in the signal handler + */ +static void user_sighandler() +{ + int sig; + while(1) { + int rc = read(pipefds[0],&sig,sizeof(sig)); + if (rc < 0) + break; + + sig_flag = 0; + } +} + + int main(int argc, char *argv[]) { - int ssock; + int ssock, maxsockplus; struct sockaddr_un saddr; socklen_t addrlen; int retval; const int on = 1; struct sigaction act; + fd_set readfds; init_logging("udevd"); dbg("version %s", UDEV_VERSION); @@ -335,16 +399,32 @@ int main(int argc, char *argv[]) dbg("need to be root, exit"); exit(1); } + + /* setup signal handler pipe */ + retval = pipe(pipefds); + if (retval < 0) { + dbg("error getting pipes: %s", strerror(errno)); + exit(1); + } + + retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); + if (retval < 0) { + dbg("fcntl on read pipe: %s", strerror(errno)); + exit(1); + } + + retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); + if (retval < 0) { + dbg("fcntl on write pipe: %s", strerror(errno)); + exit(1); + } - /* set signal handler */ + /* set signal handlers */ act.sa_handler = sig_handler; - sigemptyset (&act.sa_mask); + sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); - - /* we want these two to interrupt system calls */ - act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); sigaction(SIGCHLD, &act, NULL); @@ -370,23 +450,50 @@ int main(int argc, char *argv[]) /* enable receiving of the sender credentials */ setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + FD_ZERO(&readfds); + FD_SET(ssock, &readfds); + FD_SET(pipefds[0], &readfds); + maxsockplus = ssock+1; while (1) { - handle_msg(ssock); - - while(msg_q_timeout) { - msg_q_timeout = 0; + fd_set workreadfds = readfds; + retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); + + if (retval < 0) { + dbg("error in select: %s", strerror(errno)); + continue; + } + + if (FD_ISSET(ssock, &workreadfds)) + handle_msg(ssock); + + if (FD_ISSET(pipefds[0], &workreadfds)) + user_sighandler(); + + if (children_waiting) { + children_waiting = 0; + reap_kids(); + } + + if (run_msg_q) { + run_msg_q = 0; msg_queue_manager(); } - - while(children_waiting) { - children_waiting = 0; - /* reap all dead children */ - while(1) { - int pid = waitpid(-1, 0, WNOHANG); - if ((pid == -1) || (pid == 0)) - break; - udev_done(pid); + + if (run_exec_q) { + + /* this is tricky. exec_queue_manager() loops over exec_list, and + * calls running_with_devpath(), which loops over running_list. This gives + * O(N*M), which can get *nasty*. Clean up running_list before + * calling exec_queue_manager(). + */ + + if (children_waiting) { + children_waiting = 0; + reap_kids(); } + + run_exec_q = 0; + exec_queue_manager(); } } exit: diff --git a/udevstart.c b/udevstart.c index 40dbaf2475..eda6355b53 100644 --- a/udevstart.c +++ b/udevstart.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "logging.h" From e5a2989efbae81f40b60885a8f92ea1f87df7ea9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 31 Mar 2004 23:03:46 -0800 Subject: [PATCH 0719/4284] [PATCH] udevd race conditions and performance, assorted cleanups - take 2 here is a patch on top of your nice improvements. I fixed the whitespace and it hopefully fixes the stupid timestamp bug in udevd. Some stupid OS sets the hwclock to localtime and linux changes it to UTC while starting. If any events are pending they may be delayed by the users time distance from UTC :) So we use the uptime seconds now. --- Makefile | 5 +-- klibc_fixups.c | 2 ++ klibc_fixups.h | 5 +++ libsysfs/sysfs.h | 3 +- udevd.c | 87 ++++++++++++++++++++++++++---------------------- udevd.h | 2 +- udevsend.c | 17 +++++----- 7 files changed, 67 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index d0ca3a18d9..652e712d77 100644 --- a/Makefile +++ b/Makefile @@ -220,6 +220,7 @@ HEADERS = udev.h \ ifeq ($(strip $(USE_KLIBC)),true) OBJS += klibc_fixups.o + KLIBC_FIXUP = klibc_fixups.o endif # header files automatically generated @@ -266,8 +267,8 @@ $(INFO): $(INFO).o $(OBJS) $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(DAEMON): $(DAEMON).o udevd.h $(LIBC) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(DAEMON): $(DAEMON).o $(OBJS) udevd.h $(LIBC) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_lib.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(SENDER): $(SENDER).o udevd.h $(LIBC) diff --git a/klibc_fixups.c b/klibc_fixups.c index eaa240c183..c4d44bbc49 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -30,12 +30,14 @@ #include "udev.h" #include "klibc_fixups.h" +#include "udev_lib.h" #include "logging.h" #define PW_FILE "/etc/passwd" #define GR_FILE "/etc/group" #define UTMP_FILE "/var/run/utmp" +_syscall1(int, sysinfo, struct sysinfo *, info); /* return the id of a passwd style line, selected by the users name */ static unsigned long get_id_by_name(const char *uname, const char *dbfile) diff --git a/klibc_fixups.h b/klibc_fixups.h index f6c91cdd94..6dfd5a5c17 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -3,6 +3,11 @@ #ifndef KLIBC_FIXUPS_H #define KLIBC_FIXUPS_H +#include +#include + +int sysinfo(struct sysinfo *info); + struct passwd { char *pw_name; /* user name */ char *pw_passwd; /* user password */ diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 0fdb38af19..7ac6efc678 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -36,8 +36,7 @@ /* Debugging */ #ifdef DEBUG #include "../logging.h" -#define dprintf(format, arg...) \ - dbg(format, ##arg) +#define dprintf(format, arg...) dbg(format, ##arg) #else #define dprintf(format, arg...) do { } while (0) #endif diff --git a/udevd.c b/udevd.c index 3b91a458da..301625fd92 100644 --- a/udevd.c +++ b/udevd.c @@ -28,12 +28,15 @@ #include #include #include -#include +#include #include #include #include -#include #include +#include "klibc_fixups.h" +#ifndef __KLIBC__ +#include +#endif #include "list.h" #include "udev.h" @@ -106,6 +109,7 @@ static void run_queue_delete(struct hotplug_msg *msg) static void msg_queue_insert(struct hotplug_msg *msg) { struct hotplug_msg *loop_msg; + struct sysinfo info; /* sort message by sequence number into list. events * will tend to come in order, so scan the list backwards @@ -113,11 +117,13 @@ static void msg_queue_insert(struct hotplug_msg *msg) list_for_each_entry_reverse(loop_msg, &msg_list, list) if (loop_msg->seqnum < msg->seqnum) break; - list_add(&msg->list, &loop_msg->list); - dbg("queued message seq %d", msg->seqnum); /* store timestamp of queuing */ - msg->queue_time = time(NULL); + sysinfo(&info); + msg->queue_time = info.uptime; + + list_add(&msg->list, &loop_msg->list); + dbg("queued message seq %d", msg->seqnum); /* run msg queue manager */ run_msg_q = 1; @@ -203,7 +209,8 @@ static void msg_queue_manager() { struct hotplug_msg *loop_msg; struct hotplug_msg *tmp_msg; - time_t msg_age = 0; + struct sysinfo info; + long msg_age = 0; dbg("msg queue manager, next expected is %d", expected_seqnum); recheck: @@ -215,7 +222,9 @@ recheck: } /* move event with expired timeout to the exec list */ - msg_age = time(NULL) - loop_msg->queue_time; + sysinfo(&info); + msg_age = info.uptime - loop_msg->queue_time; + dbg("seq %d is %li seconds old", loop_msg->seqnum, msg_age); if (msg_age > EVENT_TIMEOUT_SEC-1) { msg_move_exec(loop_msg); goto recheck; @@ -226,11 +235,10 @@ recheck: msg_dump_queue(); + /* set timeout for remaining queued events */ if (list_empty(&msg_list) == 0) { - /* set timeout for remaining queued events */ struct itimerval itv = {{0, 0}, {EVENT_TIMEOUT_SEC - msg_age, 0}}; - dbg("next event expires in %li seconds", - EVENT_TIMEOUT_SEC - msg_age); + dbg("next event expires in %li seconds", EVENT_TIMEOUT_SEC - msg_age); setitimer(ITIMER_REAL, &itv, 0); } } @@ -399,25 +407,25 @@ int main(int argc, char *argv[]) dbg("need to be root, exit"); exit(1); } - + /* setup signal handler pipe */ - retval = pipe(pipefds); - if (retval < 0) { - dbg("error getting pipes: %s", strerror(errno)); - exit(1); - } - - retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); - if (retval < 0) { - dbg("fcntl on read pipe: %s", strerror(errno)); - exit(1); - } - - retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); - if (retval < 0) { - dbg("fcntl on write pipe: %s", strerror(errno)); - exit(1); - } + retval = pipe(pipefds); + if (retval < 0) { + dbg("error getting pipes: %s", strerror(errno)); + exit(1); + } + + retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); + if (retval < 0) { + dbg("error fcntl on read pipe: %s", strerror(errno)); + exit(1); + } + + retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); + if (retval < 0) { + dbg("error fcntl on write pipe: %s", strerror(errno)); + exit(1); + } /* set signal handlers */ act.sa_handler = sig_handler; @@ -450,43 +458,42 @@ int main(int argc, char *argv[]) /* enable receiving of the sender credentials */ setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); - FD_ZERO(&readfds); - FD_SET(ssock, &readfds); - FD_SET(pipefds[0], &readfds); + FD_ZERO(&readfds); + FD_SET(ssock, &readfds); + FD_SET(pipefds[0], &readfds); maxsockplus = ssock+1; while (1) { fd_set workreadfds = readfds; retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); - + if (retval < 0) { - dbg("error in select: %s", strerror(errno)); + if (errno != EINTR) + dbg("error in select: %s", strerror(errno)); continue; } - + if (FD_ISSET(ssock, &workreadfds)) handle_msg(ssock); - + if (FD_ISSET(pipefds[0], &workreadfds)) user_sighandler(); - + if (children_waiting) { children_waiting = 0; reap_kids(); } - + if (run_msg_q) { run_msg_q = 0; msg_queue_manager(); } - + if (run_exec_q) { - /* this is tricky. exec_queue_manager() loops over exec_list, and * calls running_with_devpath(), which loops over running_list. This gives * O(N*M), which can get *nasty*. Clean up running_list before * calling exec_queue_manager(). */ - if (children_waiting) { children_waiting = 0; reap_kids(); diff --git a/udevd.h b/udevd.h index 8b82ff9a70..96f179ad44 100644 --- a/udevd.h +++ b/udevd.h @@ -34,7 +34,7 @@ struct hotplug_msg { struct list_head list; pid_t pid; int seqnum; - time_t queue_time; + long queue_time; char action[ACTION_SIZE]; char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; diff --git a/udevsend.c b/udevsend.c index f1c46d3367..f28e445433 100644 --- a/udevsend.c +++ b/udevsend.c @@ -26,13 +26,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include "udev.h" @@ -53,16 +53,15 @@ void log_message (int level, const char *format, ...) } #endif -static int build_hotplugmsg(struct hotplug_msg *msg, char *action, - char *devpath, char *subsystem, int seqnum) +static void build_hotplugmsg(struct hotplug_msg *msg, char *action, + char *devpath, char *subsystem, int seqnum) { - memset(msg, 0x00, sizeof(*msg)); + memset(msg, 0x00, sizeof(struct hotplug_msg)); strfieldcpy(msg->magic, UDEV_MAGIC); msg->seqnum = seqnum; strfieldcpy(msg->action, action); strfieldcpy(msg->devpath, devpath); strfieldcpy(msg->subsystem, subsystem); - return sizeof(struct hotplug_msg); } static int start_daemon(void) @@ -108,7 +107,6 @@ int main(int argc, char* argv[]) char *seqnum; int seq; int retval = 1; - int size; int loop; struct timespec tspec; int sock; @@ -155,18 +153,19 @@ int main(int argc, char* argv[]) goto exit; } - memset(&saddr, 0x00, sizeof(saddr)); + memset(&saddr, 0x00, sizeof(struct sockaddr_un)); saddr.sun_family = AF_LOCAL; /* use abstract namespace for socket path */ strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - size = build_hotplugmsg(&msg, action, devpath, subsystem, seq); + build_hotplugmsg(&msg, action, devpath, subsystem, seq); /* If we can't send, try to start daemon and resend message */ loop = UDEVSEND_CONNECT_RETRY; while (loop--) { - retval = sendto(sock, &msg, size, 0, (struct sockaddr *)&saddr, addrlen); + retval = sendto(sock, &msg, sizeof(struct hotplug_msg), 0, + (struct sockaddr *)&saddr, addrlen); if (retval != -1) { retval = 0; goto close_and_exit; From bbbe503ec1a5623a5a8abd003f46fdd8c3581054 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 31 Mar 2004 23:12:57 -0800 Subject: [PATCH 0720/4284] [PATCH] netdev - udevdb+dev.d changes Here is a patch to change the netdev handling in the database and for the dev.d/ calls. I applies on top of the udevd.patch, cause klibc has no sysinfo(). o netdev's are also put into our database now. I want this for the udevruler gui to get a list of all handled devices. All devices in the db are stamped with the system uptime value at the creation time. 'udevinfo -d' prints it. o the DEVPATH value is the key for udevdb, but if we rename a netdev, the name is replaced in the kernel, so we add the changed name to the db to match with the remove event. NOTE: The dev.d/ scripts still get the original name from the hotplug call. Should we replace DEVPATH with the new name too? o We now only add a device to the db, if we have successfully created the main node or successfully renamed a netdev. This is the main part of the patch, cause I needed to clean the retval passing trough all the functions used for node creation. o DEVNODE sounds a bit ugly for netdev's so I exported DEVNAME too. Can we change the name? o I've added a UDEV_NO_DEVD to possibly skip the script execution and used it in udev-test.pl. udevstart is the same horror now, if you have scripts with logging statements in dev.d/ it takes minutes to finish, can we skip the scripts here too? o The get_device_type() function is changed to be more strict, cause 'udevinfo -a -p /block/' gets a class device for it and tries to print the major/minor values. o bugfix, the RESULT value has now a working newline removal and a test for this case. --- dev_d.c | 18 +++++--- namedev.c | 26 +++++------ test/udev-test.pl | 11 +++++ udev-add.c | 107 +++++++++++++++++++++++++--------------------- udev-remove.c | 46 ++++++++------------ udev.h | 3 +- udev_config.c | 5 +++ udevdb.c | 1 + udevinfo.c | 3 +- udevruler.c | 14 +++--- 10 files changed, 131 insertions(+), 103 deletions(-) diff --git a/dev_d.c b/dev_d.c index 9bb9507b9b..0910e4d323 100644 --- a/dev_d.c +++ b/dev_d.c @@ -64,11 +64,20 @@ static int run_program(char *name) void dev_d_send(struct udevice *dev, char *subsystem) { char dirname[256]; - char devnode[NAME_SIZE]; + char devname[NAME_SIZE]; - strfieldcpy(devnode, udev_root); - strfieldcat(devnode, dev->name); - setenv("DEVNODE", devnode, 1); + if (udev_dev_d == 0) + return; + + if (dev->type == 'b' || dev->type == 'c') { + strfieldcpy(devname, udev_root); + strfieldcat(devname, dev->name); + } else if (dev->type == 'n') { + strfieldcpy(devname, dev->name); + } + setenv("DEVNODE", devname, 1); /* FIXME: bad name for netif */ + setenv("DEVNAME", devname, 1); + dbg("DEVNAME='%s'", devname); strcpy(dirname, DEVD_DIR); strfieldcat(dirname, dev->name); @@ -81,4 +90,3 @@ void dev_d_send(struct udevice *dev, char *subsystem) strcpy(dirname, DEVD_DIR "default"); call_foreach_file(run_program, dirname, DEVD_SUFFIX); } - diff --git a/namedev.c b/namedev.c index 7b70f8bcdf..a3ae1d36b3 100644 --- a/namedev.c +++ b/namedev.c @@ -32,6 +32,9 @@ #include #include #include +#ifndef __KLIBC__ +#include +#endif #include "libsysfs/sysfs/libsysfs.h" #include "list.h" @@ -454,7 +457,7 @@ static int execute_program(char *path, char *value, int len) retval = -1; } - if (i > 0 && value[i] == '\n') + if (i > 0 && value[i-1] == '\n') i--; value[i] = '\0'; dbg("result is '%s'", value); @@ -776,6 +779,7 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud struct sysfs_device *sysfs_device = NULL; struct config_device *dev; struct perm_device *perm; + struct sysinfo info; char *pos; udev->mode = 0; @@ -837,22 +841,18 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } } } - - /* no rule was found for the net device */ - if (udev->type == 'n') { - dbg("no name for net device '%s' configured", udev->kernel_name); - return -1; - } - /* no rule was found so we use the kernel name */ strfieldcpy(udev->name, udev->kernel_name); - goto done; + if (udev->type == 'n') + goto done; + else + goto perms; found: apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); if (udev->type == 'n') - return 0; + goto done; udev->partitions = dev->partitions; strfieldcpy(udev->config_file, dev->config_file); @@ -863,7 +863,7 @@ found: dev->owner, dev->group); -done: +perms: /* get permissions given in config file or set defaults */ perm = find_perm(udev->name); if (perm != NULL) { @@ -879,8 +879,10 @@ done: dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); +done: /* store time of action */ - udev->config_time = time(NULL); + sysinfo(&info); + udev->config_uptime = info.uptime; return 0; } diff --git a/test/udev-test.pl b/test/udev-test.pl index 8ae01c31d4..31bc990b81 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -232,6 +232,15 @@ BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special--*", NAME="%c BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-device-", NAME="%c-3-%n" BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-devic", NAME="%c-4-%n" BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-*", NAME="%c-%n" +EOF + }, + { + desc => "program result substitution (newline removal)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "newline_removed" , + conf => <value); if (sscanf(attr->value, "%u:%u", &udev->major, &udev->minor) != 2) - goto exit; + goto error; dbg("found major=%d, minor=%d", udev->major, udev->minor); - retval = 0; -exit: - return retval; + return 0; +error: + return -1; } static int create_path(char *file) @@ -114,28 +113,27 @@ static int make_node(char *filename, int major, int minor, unsigned int mode, ui if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", filename, mode, major, minor, strerror(errno)); - return retval; + goto exit; } dbg("chmod(%s, %#o)", filename, mode); - retval = chmod(filename, mode); - if (retval != 0) { + if (chmod(filename, mode) != 0) { dbg("chmod(%s, %#o) failed with error '%s'", filename, mode, strerror(errno)); - return retval; + goto exit; } if (uid != 0 || gid != 0) { dbg("chown(%s, %u, %u)", filename, uid, gid); - retval = chown(filename, uid, gid); - if (retval != 0) { + if (chown(filename, uid, gid) != 0) { dbg("chown(%s, %u, %u) failed with error '%s'", filename, uid, gid, strerror(errno)); - return retval; + goto exit; } } - return 0; +exit: + return retval; } /* get the local logged in user */ @@ -169,7 +167,6 @@ static void set_to_local_user(char *user) endutent(); } -/* Used to unlink existing files to ensure that our new file/symlink is created */ static int unlink_entry(char *filename) { struct stat stats; @@ -193,7 +190,6 @@ static int create_node(struct udevice *dev, int fake) char linkname[NAME_SIZE]; char linktarget[NAME_SIZE]; char partitionname[NAME_SIZE]; - int retval = 0; uid_t uid = 0; gid_t gid = 0; int i; @@ -259,14 +255,15 @@ static int create_node(struct udevice *dev, int fake) if (!fake) { unlink_entry(filename); info("creating device node '%s'", filename); - make_node(filename, dev->major, dev->minor, dev->mode, uid, gid); + if (make_node(filename, dev->major, dev->minor, dev->mode, uid, gid) != 0) + goto error; } else { info("creating device node '%s', major = '%d', minor = '%d', " "mode = '%#o', uid = '%d', gid = '%d'", filename, dev->major, dev->minor, (mode_t)dev->mode, uid, gid); } - /* create partitions if requested */ + /* create all_partitions if requested */ if (dev->partitions > 0) { info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions); if (!fake) { @@ -280,7 +277,7 @@ static int create_node(struct udevice *dev, int fake) } } - /* create symlink if requested */ + /* create symlink(s) if requested */ foreach_strpart(dev->symlink, " ", pos, len) { strfieldcpymax(linkname, pos, len+1); strfieldcpy(filename, udev_root); @@ -312,14 +309,15 @@ static int create_node(struct udevice *dev, int fake) dbg("symlink(%s, %s)", linktarget, filename); if (!fake) { - retval = symlink(linktarget, filename); - if (retval != 0) + if (symlink(linktarget, filename) != 0) dbg("symlink(%s, %s) failed with error '%s'", linktarget, filename, strerror(errno)); } } - return retval; + return 0; +error: + return -1; } static struct sysfs_class_device *get_class_dev(char *device_name) @@ -373,12 +371,16 @@ exit: return retval; } -static int rename_net_if(struct udevice *dev) +static int rename_net_if(struct udevice *dev, int fake) { int sk; struct ifreq ifr; int retval; + dbg("changing net interface name from '%s' to '%s'", dev->kernel_name, dev->name); + if (fake) + return 0; + sk = socket(PF_INET, SOCK_DGRAM, 0); if (sk < 0) { dbg("error opening socket"); @@ -389,7 +391,6 @@ static int rename_net_if(struct udevice *dev) strfieldcpy(ifr.ifr_name, dev->kernel_name); strfieldcpy(ifr.ifr_newname, dev->name); - dbg("changing net interface name from '%s' to '%s'", dev->kernel_name, dev->name); retval = ioctl(sk, SIOCSIFNAME, &ifr); if (retval != 0) dbg("error changing net interface name"); @@ -400,16 +401,15 @@ static int rename_net_if(struct udevice *dev) int udev_add_device(char *path, char *subsystem, int fake) { - struct sysfs_class_device *class_dev = NULL; + struct sysfs_class_device *class_dev; struct udevice dev; - int retval = -EINVAL; + char key[DEVPATH_SIZE]; + char *pos; + int retval; memset(&dev, 0x00, sizeof(dev)); - /* for now, the block layer is the only place where block devices are */ - dev.type = get_device_type(path, subsystem); - switch (dev.type) { case 'b': case 'c': @@ -422,12 +422,12 @@ int udev_add_device(char *path, char *subsystem, int fake) default: dbg("unknown device type '%c'", dev.type); - retval = -EINVAL; + return -1; } class_dev = get_class_dev(path); if (class_dev == NULL) - goto exit; + return -1; if (dev.type == 'b' || dev.type == 'c') { retval = get_major_minor(class_dev, &dev); @@ -437,37 +437,48 @@ int udev_add_device(char *path, char *subsystem, int fake) } } - retval = namedev_name_device(class_dev, &dev); - if (retval != 0) + if (namedev_name_device(class_dev, &dev) != 0) goto exit; - if (!fake && (dev.type == 'b' || dev.type == 'c')) { - retval = udevdb_add_dev(path, &dev); - if (retval != 0) - dbg("udevdb_add_dev failed, but we are going to try " - "to create the node anyway. But remove might not " - "work properly for this device."); - } - dbg("name='%s'", dev.name); + switch (dev.type) { case 'b': case 'c': retval = create_node(&dev, fake); - if ((retval == 0) && (!fake)) - dev_d_send(&dev, subsystem); + if (fake || retval != 0) + goto exit; + if (udevdb_add_dev(path, &dev) != 0) + dbg("udevdb_add_dev failed, but we are going to try " + "to create the node anyway. But remove might not " + "work properly for this device."); break; case 'n': - retval = rename_net_if(&dev); - if (retval != 0) - dbg("net device naming failed"); + strfieldcpy(key, path); + if (strcmp(dev.name, dev.kernel_name) != 0) { + retval = rename_net_if(&dev, fake); + if (fake || retval != 0) + goto exit; + /* netif's are keyed with the configured name, cause + * the original kernel name sleeps with the fishes + */ + pos = strrchr(key, '/'); + if (pos != NULL) { + pos[1] = '\0'; + strfieldcat(key, dev.name); + } + } + if (udevdb_add_dev(key, &dev) != 0) + dbg("udevdb_add_dev failed"); break; } + /* execute programs in dev.d/ with the name in the environment */ + dev_d_send(&dev, subsystem); + exit: - if (class_dev) - sysfs_close_class_device(class_dev); + sysfs_close_class_device(class_dev); return retval; } diff --git a/udev-remove.c b/udev-remove.c index 98c45d6c33..c838f15ce3 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -137,36 +137,24 @@ int udev_remove_device(char *path, char *subsystem) memset(&dev, 0x00, sizeof(dev)); - dev.type = get_device_type(path, subsystem); - - switch (dev.type) { - case 'b': - case 'c': - retval = udevdb_get_dev(path, &dev); - if (retval) { - dbg("'%s' not found in database, falling back on default name", path); - temp = strrchr(path, '/'); - if (temp == NULL) - return -ENODEV; - strfieldcpy(dev.name, &temp[1]); - } - - dbg("name='%s'", dev.name); - udevdb_delete_dev(path); - - dev_d_send(&dev, subsystem); - - retval = delete_node(&dev); - break; - - case 'n': - retval = 0; - break; - - default: - dbg("unknown device type '%c'", dev.type); - retval = -EINVAL; + retval = udevdb_get_dev(path, &dev); + if (retval != 0) { + dbg("'%s' not found in database, falling back on default name", path); + temp = strrchr(path, '/'); + if (temp == NULL) + return -ENODEV; + strfieldcpy(dev.name, &temp[1]); } + dbg("name='%s'", dev.name); + + dev.type = get_device_type(path, subsystem); + dev_d_send(&dev, subsystem); + udevdb_delete_dev(path); + + if (dev.type == 'b' || dev.type == 'c') + retval = delete_node(&dev); + else if (dev.type == 'n') + retval = 0; return retval; } diff --git a/udev.h b/udev.h index eb42edce10..8d13fb5bc3 100644 --- a/udev.h +++ b/udev.h @@ -52,7 +52,7 @@ struct udevice { int partitions; int config_line; char config_file[NAME_SIZE]; - time_t config_time; + long config_uptime; /* private data that help us in building strings */ char bus_id[SYSFS_NAME_LEN]; @@ -80,5 +80,6 @@ extern char default_owner_str[OWNER_SIZE]; extern char default_group_str[GROUP_SIZE]; extern int udev_log; extern int udev_sleep; +extern int udev_dev_d; #endif diff --git a/udev_config.c b/udev_config.c index 57a512d711..fe26850a87 100644 --- a/udev_config.c +++ b/udev_config.c @@ -51,6 +51,7 @@ char default_owner_str[OWNER_SIZE]; char default_group_str[GROUP_SIZE]; int udev_log; int udev_sleep; +int udev_dev_d; static int string_is_true(char *str) @@ -77,6 +78,10 @@ static void init_variables(void) udev_sleep = 1; if (getenv("UDEV_NO_SLEEP") != NULL) udev_sleep = 0; + + udev_dev_d = 1; + if (getenv("UDEV_NO_DEVD") != NULL) + udev_dev_d = 0; } #define set_var(_name, _var) \ diff --git a/udevdb.c b/udevdb.c index 40580e5a3b..f246936710 100644 --- a/udevdb.c +++ b/udevdb.c @@ -59,6 +59,7 @@ int udevdb_add_dev(const char *path, const struct udevice *dev) data.dptr = (void *)dev; data.dsize = UDEVICE_LEN; + dbg("store key '%s' for device '%s'", path, dev->name); return tdb_store(udevdb, key, data, TDB_REPLACE); } diff --git a/udevinfo.c b/udevinfo.c index b23f9d0aef..8329fe7d06 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -108,13 +108,14 @@ static int print_record(char *path, struct udevice *dev) { printf("P: %s\n", path); printf("N: %s\n", dev->name); + printf("T: %c\n", dev->type); printf("M: %#o\n", dev->mode); printf("S: %s\n", dev->symlink); printf("O: %s\n", dev->owner); printf("G: %s\n", dev->group); printf("F: %s\n", dev->config_file); printf("L: %i\n", dev->config_line); - printf("T: %li\n", dev->config_time); + printf("U: %li\n", dev->config_uptime); printf("\n"); return 0; } diff --git a/udevruler.c b/udevruler.c index af2cf7bb81..a13bd625a8 100644 --- a/udevruler.c +++ b/udevruler.c @@ -77,7 +77,7 @@ struct device { char devpath[DEVPATH_SIZE]; int config_line; char config_file[NAME_SIZE]; - time_t config_time; + long config_uptime; int added; }; @@ -106,7 +106,7 @@ static int add_record(char *path, struct udevice *udev) strfieldcpy(dev->devpath, path); dev->config_line = udev->config_line; strfieldcpy(dev->config_file, udev->config_file); - dev->config_time = udev->config_time; + dev->config_uptime = udev->config_uptime; dev->added = 0; /* sort in lexical order */ @@ -308,7 +308,7 @@ int main(int argc, char *argv[]) { char roottext[81]; char path[NAME_SIZE]; struct device *dev; - time_t time_last; + long time_last; int count_last; newtInit(); @@ -332,13 +332,13 @@ int main(int argc, char *argv[]) { /* look for last discovered device */ time_last = 0; list_for_each_entry(dev, &device_list, list) - if (dev->config_time > time_last) - time_last = dev->config_time; + if (dev->config_uptime > time_last) + time_last = dev->config_uptime; /* skip if more than 16 recent devices */ count_last = 0; list_for_each_entry(dev, &device_list, list) { - if (dev->config_time < time_last - 10) + if (dev->config_uptime < time_last - 10) continue; count_last++; } @@ -347,7 +347,7 @@ int main(int argc, char *argv[]) { if (count_last < 16) { newtListboxAppendEntry(lbox, "--- last dicovered ---", NULL); list_for_each_entry(dev, &device_list, list) { - if (dev->config_time < time_last - 10) + if (dev->config_uptime < time_last - 10) continue; dbg("%s %i", dev->name, dev->config_line); From 9b28a52a0ac9b7993c932bbfe9d86dfc814be218 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 1 Apr 2004 00:59:58 -0800 Subject: [PATCH 0721/4284] [PATCH] DEVPATH for netdev Here we change the DEVPATH for netdev's in the environment of the dev.d/ scripts to the name the device is renamed to. The original name doesn't exist in the kernel after rename. --- dev_d.c | 4 ++-- udev-add.c | 17 +++++++++-------- udev-remove.c | 2 +- udev.h | 2 +- udev_config.c | 6 +++--- udevd.c | 6 ++++-- udevstart.c | 5 +++-- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/dev_d.c b/dev_d.c index 0910e4d323..483ceb4b1b 100644 --- a/dev_d.c +++ b/dev_d.c @@ -61,7 +61,7 @@ static int run_program(char *name) * subsystem/ * default/ */ -void dev_d_send(struct udevice *dev, char *subsystem) +void dev_d_send(struct udevice *dev, char *subsystem, char *devpath) { char dirname[256]; char devname[NAME_SIZE]; @@ -74,8 +74,8 @@ void dev_d_send(struct udevice *dev, char *subsystem) strfieldcat(devname, dev->name); } else if (dev->type == 'n') { strfieldcpy(devname, dev->name); + setenv("DEVPATH", devpath, 1); } - setenv("DEVNODE", devname, 1); /* FIXME: bad name for netif */ setenv("DEVNAME", devname, 1); dbg("DEVNAME='%s'", devname); diff --git a/udev-add.c b/udev-add.c index 1f17f50bc3..09c2ac6d3e 100644 --- a/udev-add.c +++ b/udev-add.c @@ -403,7 +403,7 @@ int udev_add_device(char *path, char *subsystem, int fake) { struct sysfs_class_device *class_dev; struct udevice dev; - char key[DEVPATH_SIZE]; + char devpath[DEVPATH_SIZE]; char *pos; int retval; @@ -452,10 +452,11 @@ int udev_add_device(char *path, char *subsystem, int fake) dbg("udevdb_add_dev failed, but we are going to try " "to create the node anyway. But remove might not " "work properly for this device."); + + dev_d_send(&dev, subsystem, path); break; case 'n': - strfieldcpy(key, path); if (strcmp(dev.name, dev.kernel_name) != 0) { retval = rename_net_if(&dev, fake); if (fake || retval != 0) @@ -463,20 +464,20 @@ int udev_add_device(char *path, char *subsystem, int fake) /* netif's are keyed with the configured name, cause * the original kernel name sleeps with the fishes */ - pos = strrchr(key, '/'); + strfieldcpy(devpath, path); + pos = strrchr(devpath, '/'); if (pos != NULL) { pos[1] = '\0'; - strfieldcat(key, dev.name); + strfieldcat(devpath, dev.name); } } - if (udevdb_add_dev(key, &dev) != 0) + if (udevdb_add_dev(devpath, &dev) != 0) dbg("udevdb_add_dev failed"); + + dev_d_send(&dev, subsystem, devpath); break; } - /* execute programs in dev.d/ with the name in the environment */ - dev_d_send(&dev, subsystem); - exit: sysfs_close_class_device(class_dev); diff --git a/udev-remove.c b/udev-remove.c index c838f15ce3..27ff5bc0a2 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -148,7 +148,7 @@ int udev_remove_device(char *path, char *subsystem) dbg("name='%s'", dev.name); dev.type = get_device_type(path, subsystem); - dev_d_send(&dev, subsystem); + dev_d_send(&dev, subsystem, path); udevdb_delete_dev(path); if (dev.type == 'b' || dev.type == 'c') diff --git a/udev.h b/udev.h index 8d13fb5bc3..da02e26bba 100644 --- a/udev.h +++ b/udev.h @@ -65,7 +65,7 @@ extern int udev_add_device(char *path, char *subsystem, int fake); extern int udev_remove_device(char *path, char *subsystem); extern void udev_init_config(void); extern int parse_get_pair(char **orig_string, char **left, char **right); -extern void dev_d_send(struct udevice *dev, char *subsystem); +extern void dev_d_send(struct udevice *dev, char *subsystem, char *devpath); extern char **main_argv; extern char **main_envp; diff --git a/udev_config.c b/udev_config.c index fe26850a87..ba04003e90 100644 --- a/udev_config.c +++ b/udev_config.c @@ -86,13 +86,13 @@ static void init_variables(void) #define set_var(_name, _var) \ if (strcasecmp(variable, _name) == 0) { \ - dbg_parse("%s = '%s'", _name, value); \ - strfieldcpymax(_var, value, sizeof(_var));\ + dbg_parse("%s='%s'", _name, value); \ + strfieldcpy(_var, value);\ } #define set_bool(_name, _var) \ if (strcasecmp(variable, _name) == 0) { \ - dbg_parse("%s = '%s'", _name, value); \ + dbg_parse("%s='%s'", _name, value); \ _var = string_is_true(value); \ } diff --git a/udevd.c b/udevd.c index 301625fd92..d464b9a196 100644 --- a/udevd.c +++ b/udevd.c @@ -139,8 +139,10 @@ static void udev_run(struct hotplug_msg *msg) char devpath[DEVPATH_SIZE]; char *env[] = { action, devpath, NULL }; - snprintf(action, sizeof(action), "ACTION=%s", msg->action); - snprintf(devpath, sizeof(devpath), "DEVPATH=%s", msg->devpath); + strcpy(action, "ACTION="); + strfieldcat(action, msg->action); + strcpy(devpath, "DEVPATH="); + strfieldcat(devpath, msg->devpath); pid = fork(); switch (pid) { diff --git a/udevstart.c b/udevstart.c index eda6355b53..7e19c379a5 100644 --- a/udevstart.c +++ b/udevstart.c @@ -33,6 +33,7 @@ #include #include "logging.h" +#include "udev_lib.h" #ifdef LOG @@ -61,8 +62,8 @@ static void udev_exec(const char *path, const char* subsystem) char nosleep[] = "UDEV_NO_SLEEP=1"; char *env[] = { action, devpath, nosleep, NULL }; - snprintf(devpath, MAX_PATHLEN, "DEVPATH=%s", path); - devpath[MAX_PATHLEN-1] = '\0'; + strcpy(action, "DEVPATH=%s"); + strfieldcat(action, path); pid = fork(); switch (pid) { From 5cd749f342ae95649a628668918e622b94bfdf4e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 01:02:53 -0800 Subject: [PATCH 0722/4284] [PATCH] update RFC-dev.d docs due to DEVNODE to DEVNAME change --- docs/RFC-dev.d | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/RFC-dev.d b/docs/RFC-dev.d index 4985e841be..1aca1aa393 100644 --- a/docs/RFC-dev.d +++ b/docs/RFC-dev.d @@ -12,16 +12,17 @@ the system due to a device being removed. The directory tree under /etc/dev.d/ dictate which program is run first, and when some programs will be run or not. The device naming program calls the programs in the following order: - /etc/dev.d/DEVNODE/*.dev + /etc/dev.d/DEVNAME/*.dev /etc/dev.d/SUBSYSTEM/*.dev /etc/dev.d/default/*.dev The .dev extension is needed to allow automatic package managers to deposit backup files in these directories safely. -The DEVNODE name is the name of the /dev file that has been created. -This value, including the /dev path, will also be exported to userspace -in the DEVNODE environment variable. +The DEVNAME name is the name of the /dev file that has been created, or +for network devices, the name of the newly named network device. This +value, including the /dev path, will also be exported to userspace in +the DEVNAME environment variable. The SUBSYSTEM name is the name of the sysfs subsystem that originally generated the hotplug event that caused the device naming program to @@ -40,8 +41,8 @@ description of this An equivalent shell script that would do this same kind of action would be: DIR="/etc/dev.d" - export DEVNODE="whatever_dev_name_udev_just_gave" - for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do + export DEVNAME="whatever_dev_name_udev_just_gave" + for I in "${DIR}/$DEVNAME/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do if [ -f $I ]; then $I $1 ; fi done exit 1; From a008521bb8a619b63a2d6e9c1e16b3a113a6cf20 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 19:25:41 -0800 Subject: [PATCH 0723/4284] [PATCH] add a bunch of network class devices to the test sysfs tree --- test/sys/class/net/eth0/addr_len | 1 + test/sys/class/net/eth0/address | 1 + test/sys/class/net/eth0/broadcast | 1 + test/sys/class/net/eth0/features | 1 + test/sys/class/net/eth0/flags | 1 + test/sys/class/net/eth0/ifindex | 1 + test/sys/class/net/eth0/iflink | 1 + test/sys/class/net/eth0/mtu | 1 + test/sys/class/net/eth0/tx_queue_len | 1 + test/sys/class/net/eth0/type | 1 + test/sys/class/net/eth1/addr_len | 1 + test/sys/class/net/eth1/address | 1 + test/sys/class/net/eth1/broadcast | 1 + test/sys/class/net/eth1/features | 1 + test/sys/class/net/eth1/flags | 1 + test/sys/class/net/eth1/ifindex | 1 + test/sys/class/net/eth1/iflink | 1 + test/sys/class/net/eth1/mtu | 1 + test/sys/class/net/eth1/tx_queue_len | 1 + test/sys/class/net/eth1/type | 1 + test/sys/class/net/eth1/wireless/beacon | 1 + test/sys/class/net/eth1/wireless/crypt | 1 + test/sys/class/net/eth1/wireless/fragment | 1 + test/sys/class/net/eth1/wireless/level | 1 + test/sys/class/net/eth1/wireless/link | 1 + test/sys/class/net/eth1/wireless/misc | 1 + test/sys/class/net/eth1/wireless/noise | 1 + test/sys/class/net/eth1/wireless/nwid | 1 + test/sys/class/net/eth1/wireless/retries | 1 + test/sys/class/net/eth1/wireless/status | 1 + test/sys/class/net/lo/addr_len | 1 + test/sys/class/net/lo/address | 1 + test/sys/class/net/lo/broadcast | 1 + test/sys/class/net/lo/features | 1 + test/sys/class/net/lo/flags | 1 + test/sys/class/net/lo/ifindex | 1 + test/sys/class/net/lo/iflink | 1 + test/sys/class/net/lo/mtu | 1 + test/sys/class/net/lo/tx_queue_len | 1 + test/sys/class/net/lo/type | 1 + 40 files changed, 40 insertions(+) create mode 100644 test/sys/class/net/eth0/addr_len create mode 100644 test/sys/class/net/eth0/address create mode 100644 test/sys/class/net/eth0/broadcast create mode 100644 test/sys/class/net/eth0/features create mode 100644 test/sys/class/net/eth0/flags create mode 100644 test/sys/class/net/eth0/ifindex create mode 100644 test/sys/class/net/eth0/iflink create mode 100644 test/sys/class/net/eth0/mtu create mode 100644 test/sys/class/net/eth0/tx_queue_len create mode 100644 test/sys/class/net/eth0/type create mode 100644 test/sys/class/net/eth1/addr_len create mode 100644 test/sys/class/net/eth1/address create mode 100644 test/sys/class/net/eth1/broadcast create mode 100644 test/sys/class/net/eth1/features create mode 100644 test/sys/class/net/eth1/flags create mode 100644 test/sys/class/net/eth1/ifindex create mode 100644 test/sys/class/net/eth1/iflink create mode 100644 test/sys/class/net/eth1/mtu create mode 100644 test/sys/class/net/eth1/tx_queue_len create mode 100644 test/sys/class/net/eth1/type create mode 100644 test/sys/class/net/eth1/wireless/beacon create mode 100644 test/sys/class/net/eth1/wireless/crypt create mode 100644 test/sys/class/net/eth1/wireless/fragment create mode 100644 test/sys/class/net/eth1/wireless/level create mode 100644 test/sys/class/net/eth1/wireless/link create mode 100644 test/sys/class/net/eth1/wireless/misc create mode 100644 test/sys/class/net/eth1/wireless/noise create mode 100644 test/sys/class/net/eth1/wireless/nwid create mode 100644 test/sys/class/net/eth1/wireless/retries create mode 100644 test/sys/class/net/eth1/wireless/status create mode 100644 test/sys/class/net/lo/addr_len create mode 100644 test/sys/class/net/lo/address create mode 100644 test/sys/class/net/lo/broadcast create mode 100644 test/sys/class/net/lo/features create mode 100644 test/sys/class/net/lo/flags create mode 100644 test/sys/class/net/lo/ifindex create mode 100644 test/sys/class/net/lo/iflink create mode 100644 test/sys/class/net/lo/mtu create mode 100644 test/sys/class/net/lo/tx_queue_len create mode 100644 test/sys/class/net/lo/type diff --git a/test/sys/class/net/eth0/addr_len b/test/sys/class/net/eth0/addr_len new file mode 100644 index 0000000000..1e8b314962 --- /dev/null +++ b/test/sys/class/net/eth0/addr_len @@ -0,0 +1 @@ +6 diff --git a/test/sys/class/net/eth0/address b/test/sys/class/net/eth0/address new file mode 100644 index 0000000000..4e0cdd519d --- /dev/null +++ b/test/sys/class/net/eth0/address @@ -0,0 +1 @@ +00:e0:00:fb:04:e1 diff --git a/test/sys/class/net/eth0/broadcast b/test/sys/class/net/eth0/broadcast new file mode 100644 index 0000000000..d516b03245 --- /dev/null +++ b/test/sys/class/net/eth0/broadcast @@ -0,0 +1 @@ +ff:ff:ff:ff:ff:ff diff --git a/test/sys/class/net/eth0/features b/test/sys/class/net/eth0/features new file mode 100644 index 0000000000..bf73d73743 --- /dev/null +++ b/test/sys/class/net/eth0/features @@ -0,0 +1 @@ +0x29 diff --git a/test/sys/class/net/eth0/flags b/test/sys/class/net/eth0/flags new file mode 100644 index 0000000000..4af9ab2807 --- /dev/null +++ b/test/sys/class/net/eth0/flags @@ -0,0 +1 @@ +0x1023 diff --git a/test/sys/class/net/eth0/ifindex b/test/sys/class/net/eth0/ifindex new file mode 100644 index 0000000000..ec635144f6 --- /dev/null +++ b/test/sys/class/net/eth0/ifindex @@ -0,0 +1 @@ +9 diff --git a/test/sys/class/net/eth0/iflink b/test/sys/class/net/eth0/iflink new file mode 100644 index 0000000000..ec635144f6 --- /dev/null +++ b/test/sys/class/net/eth0/iflink @@ -0,0 +1 @@ +9 diff --git a/test/sys/class/net/eth0/mtu b/test/sys/class/net/eth0/mtu new file mode 100644 index 0000000000..3d86ec6498 --- /dev/null +++ b/test/sys/class/net/eth0/mtu @@ -0,0 +1 @@ +1500 diff --git a/test/sys/class/net/eth0/tx_queue_len b/test/sys/class/net/eth0/tx_queue_len new file mode 100644 index 0000000000..83b33d238d --- /dev/null +++ b/test/sys/class/net/eth0/tx_queue_len @@ -0,0 +1 @@ +1000 diff --git a/test/sys/class/net/eth0/type b/test/sys/class/net/eth0/type new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/class/net/eth0/type @@ -0,0 +1 @@ +1 diff --git a/test/sys/class/net/eth1/addr_len b/test/sys/class/net/eth1/addr_len new file mode 100644 index 0000000000..1e8b314962 --- /dev/null +++ b/test/sys/class/net/eth1/addr_len @@ -0,0 +1 @@ +6 diff --git a/test/sys/class/net/eth1/address b/test/sys/class/net/eth1/address new file mode 100644 index 0000000000..7325095c16 --- /dev/null +++ b/test/sys/class/net/eth1/address @@ -0,0 +1 @@ +00:e0:00:8d:9f:25 diff --git a/test/sys/class/net/eth1/broadcast b/test/sys/class/net/eth1/broadcast new file mode 100644 index 0000000000..d516b03245 --- /dev/null +++ b/test/sys/class/net/eth1/broadcast @@ -0,0 +1 @@ +ff:ff:ff:ff:ff:ff diff --git a/test/sys/class/net/eth1/features b/test/sys/class/net/eth1/features new file mode 100644 index 0000000000..9982566dc0 --- /dev/null +++ b/test/sys/class/net/eth1/features @@ -0,0 +1 @@ +0x0 diff --git a/test/sys/class/net/eth1/flags b/test/sys/class/net/eth1/flags new file mode 100644 index 0000000000..7f97d854fc --- /dev/null +++ b/test/sys/class/net/eth1/flags @@ -0,0 +1 @@ +0x1002 diff --git a/test/sys/class/net/eth1/ifindex b/test/sys/class/net/eth1/ifindex new file mode 100644 index 0000000000..f599e28b8a --- /dev/null +++ b/test/sys/class/net/eth1/ifindex @@ -0,0 +1 @@ +10 diff --git a/test/sys/class/net/eth1/iflink b/test/sys/class/net/eth1/iflink new file mode 100644 index 0000000000..f599e28b8a --- /dev/null +++ b/test/sys/class/net/eth1/iflink @@ -0,0 +1 @@ +10 diff --git a/test/sys/class/net/eth1/mtu b/test/sys/class/net/eth1/mtu new file mode 100644 index 0000000000..3d86ec6498 --- /dev/null +++ b/test/sys/class/net/eth1/mtu @@ -0,0 +1 @@ +1500 diff --git a/test/sys/class/net/eth1/tx_queue_len b/test/sys/class/net/eth1/tx_queue_len new file mode 100644 index 0000000000..83b33d238d --- /dev/null +++ b/test/sys/class/net/eth1/tx_queue_len @@ -0,0 +1 @@ +1000 diff --git a/test/sys/class/net/eth1/type b/test/sys/class/net/eth1/type new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/class/net/eth1/type @@ -0,0 +1 @@ +1 diff --git a/test/sys/class/net/eth1/wireless/beacon b/test/sys/class/net/eth1/wireless/beacon new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/beacon @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/eth1/wireless/crypt b/test/sys/class/net/eth1/wireless/crypt new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/crypt @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/eth1/wireless/fragment b/test/sys/class/net/eth1/wireless/fragment new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/fragment @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/eth1/wireless/level b/test/sys/class/net/eth1/wireless/level new file mode 100644 index 0000000000..e702a30b33 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/level @@ -0,0 +1 @@ +188 diff --git a/test/sys/class/net/eth1/wireless/link b/test/sys/class/net/eth1/wireless/link new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/link @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/eth1/wireless/misc b/test/sys/class/net/eth1/wireless/misc new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/misc @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/eth1/wireless/noise b/test/sys/class/net/eth1/wireless/noise new file mode 100644 index 0000000000..405e2afe8e --- /dev/null +++ b/test/sys/class/net/eth1/wireless/noise @@ -0,0 +1 @@ +134 diff --git a/test/sys/class/net/eth1/wireless/nwid b/test/sys/class/net/eth1/wireless/nwid new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/nwid @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/eth1/wireless/retries b/test/sys/class/net/eth1/wireless/retries new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/retries @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/eth1/wireless/status b/test/sys/class/net/eth1/wireless/status new file mode 100644 index 0000000000..9982566dc0 --- /dev/null +++ b/test/sys/class/net/eth1/wireless/status @@ -0,0 +1 @@ +0x0 diff --git a/test/sys/class/net/lo/addr_len b/test/sys/class/net/lo/addr_len new file mode 100644 index 0000000000..1e8b314962 --- /dev/null +++ b/test/sys/class/net/lo/addr_len @@ -0,0 +1 @@ +6 diff --git a/test/sys/class/net/lo/address b/test/sys/class/net/lo/address new file mode 100644 index 0000000000..34e09d077c --- /dev/null +++ b/test/sys/class/net/lo/address @@ -0,0 +1 @@ +00:00:00:00:00:00 diff --git a/test/sys/class/net/lo/broadcast b/test/sys/class/net/lo/broadcast new file mode 100644 index 0000000000..34e09d077c --- /dev/null +++ b/test/sys/class/net/lo/broadcast @@ -0,0 +1 @@ +00:00:00:00:00:00 diff --git a/test/sys/class/net/lo/features b/test/sys/class/net/lo/features new file mode 100644 index 0000000000..e8768d26fc --- /dev/null +++ b/test/sys/class/net/lo/features @@ -0,0 +1 @@ +0x65 diff --git a/test/sys/class/net/lo/flags b/test/sys/class/net/lo/flags new file mode 100644 index 0000000000..4bc4da19ae --- /dev/null +++ b/test/sys/class/net/lo/flags @@ -0,0 +1 @@ +0x9 diff --git a/test/sys/class/net/lo/ifindex b/test/sys/class/net/lo/ifindex new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/class/net/lo/ifindex @@ -0,0 +1 @@ +1 diff --git a/test/sys/class/net/lo/iflink b/test/sys/class/net/lo/iflink new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/test/sys/class/net/lo/iflink @@ -0,0 +1 @@ +1 diff --git a/test/sys/class/net/lo/mtu b/test/sys/class/net/lo/mtu new file mode 100644 index 0000000000..e20e16cfe8 --- /dev/null +++ b/test/sys/class/net/lo/mtu @@ -0,0 +1 @@ +16436 diff --git a/test/sys/class/net/lo/tx_queue_len b/test/sys/class/net/lo/tx_queue_len new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/test/sys/class/net/lo/tx_queue_len @@ -0,0 +1 @@ +0 diff --git a/test/sys/class/net/lo/type b/test/sys/class/net/lo/type new file mode 100644 index 0000000000..6d629c4a23 --- /dev/null +++ b/test/sys/class/net/lo/type @@ -0,0 +1 @@ +772 From d5853b48fb098ca63af813ae74cd6af3a9400d01 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 21:38:59 -0800 Subject: [PATCH 0724/4284] [PATCH] add hotplug.dev script to handle renamed network devices. --- etc/dev.d/net/hotplug.dev | 23 ++++++++++++++++++ test/net_test | 49 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 etc/dev.d/net/hotplug.dev create mode 100644 test/net_test diff --git a/etc/dev.d/net/hotplug.dev b/etc/dev.d/net/hotplug.dev new file mode 100644 index 0000000000..ed64c08cf2 --- /dev/null +++ b/etc/dev.d/net/hotplug.dev @@ -0,0 +1,23 @@ +#!/bin/sh +# +# Script to ensure that any network device that udev renames +# still gets the hotplug script run with the proper name. +# +# Released under the GPL v2 +# +# Copyright (C) 2004 Greg Kroah-Hartman +# + +# See if we really did rename this device. +if [ "$INTERFACE" = "$DEVNAME" ]; then + exit 0 +fi + +# ok, we have renamed this device, so let's set $INTERFACE to the new name +# and call the network hotplug script to handle it properly... +INTERFACE=$DEVNAME +export INTERFACE +if [ -f /etc/hotplug.d/default/default.hotplug ]; then + /etc/hotplug.d/default/default.hotplug net +fi + diff --git a/test/net_test b/test/net_test new file mode 100644 index 0000000000..b99a4acd54 --- /dev/null +++ b/test/net_test @@ -0,0 +1,49 @@ +#!/bin/bash + +RULES=label_test.rules +CONFIG=label_test.conf + +export UDEV_TEST=yes +export SYSFS_PATH=$PWD/sys/ +export UDEV_CONFIG_FILE=$PWD/$CONFIG + +cat > $RULES << EOF +BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_diskX%n" +BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_disk%n" +EOF + +cat > $CONFIG << EOF +udev_root="$PWD/udev/" +udev_db="$PWD/udev/.udev.tdb" +udev_rules="$PWD/$RULES" +udev_permissions="$PWD/udev.permissions" +EOF + +mkdir udev + +export ACTION=add +export DEVPATH=block/sda + +../udev block +ls -l udev + +export DEVPATH=block/sda/sda3 + +../udev block +ls -l udev + +export ACTION=remove +export DEVPATH=block/sda + +../udev block +ls -l udev + +export DEVPATH=block/sda/sda3 + +../udev block +ls -l udev + + +rm $RULES +rm $CONFIG +rm -rf udev From ce4256bdc5012b9b63abca392bc0ead7ad70d20a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 21:46:07 -0800 Subject: [PATCH 0725/4284] [PATCH] handle the subsytem if provided in udevtest. this is needed to test the /etc/dev.d/ stuff properly. --- udevtest.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/udevtest.c b/udevtest.c index 67ae9cc98f..36f223e1e5 100644 --- a/udevtest.c +++ b/udevtest.c @@ -57,7 +57,7 @@ int main(int argc, char *argv[], char *envp[]) { char *devpath; char temp[NAME_SIZE]; - char subsystem[] = ""; + char *subsystem = ""; const int fake = 1; main_argv = argv; @@ -98,6 +98,9 @@ int main(int argc, char *argv[], char *envp[]) /* initialize the naming deamon */ namedev_init(); + if (argv[2] != NULL) + subsystem = argv[2]; + /* simulate node creation with fake flag */ udev_add_device(devpath, subsystem, fake); From cfdfda10783b2764de6d22946c5a6159c8caaea3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 21:51:17 -0800 Subject: [PATCH 0726/4284] [PATCH] make a net_test test script using udevtest. --- test/net_test | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/test/net_test b/test/net_test index b99a4acd54..fcc21e1b94 100644 --- a/test/net_test +++ b/test/net_test @@ -8,8 +8,7 @@ export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG cat > $RULES << EOF -BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_diskX%n" -BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_disk%n" +SYSFS{address}="00:e0:00:8d:9f:25", NAME="wireless" EOF cat > $CONFIG << EOF @@ -22,28 +21,17 @@ EOF mkdir udev export ACTION=add -export DEVPATH=block/sda +export DEVPATH=class/net/eth1 -../udev block -ls -l udev - -export DEVPATH=block/sda/sda3 - -../udev block +../udevtest class/net/eth1 net ls -l udev export ACTION=remove -export DEVPATH=block/sda +export DEVPATH=class/net/eth1 -../udev block +../udevtest net ls -l udev -export DEVPATH=block/sda/sda3 - -../udev block -ls -l udev - - rm $RULES rm $CONFIG rm -rf udev From c4603a0726b30ce30472a6dfdeb1a76c365dd89f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 21:52:46 -0800 Subject: [PATCH 0727/4284] [PATCH] fix some segfaults when running udevtest for network devices. --- udev-add.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/udev-add.c b/udev-add.c index 09c2ac6d3e..20599822d3 100644 --- a/udev-add.c +++ b/udev-add.c @@ -446,9 +446,9 @@ int udev_add_device(char *path, char *subsystem, int fake) case 'b': case 'c': retval = create_node(&dev, fake); - if (fake || retval != 0) + if (retval != 0) goto exit; - if (udevdb_add_dev(path, &dev) != 0) + if ((!fake) && (udevdb_add_dev(path, &dev) != 0)) dbg("udevdb_add_dev failed, but we are going to try " "to create the node anyway. But remove might not " "work properly for this device."); @@ -459,7 +459,7 @@ int udev_add_device(char *path, char *subsystem, int fake) case 'n': if (strcmp(dev.name, dev.kernel_name) != 0) { retval = rename_net_if(&dev, fake); - if (fake || retval != 0) + if (retval != 0) goto exit; /* netif's are keyed with the configured name, cause * the original kernel name sleeps with the fishes @@ -471,7 +471,7 @@ int udev_add_device(char *path, char *subsystem, int fake) strfieldcat(devpath, dev.name); } } - if (udevdb_add_dev(devpath, &dev) != 0) + if ((!fake) && (udevdb_add_dev(devpath, &dev) != 0)) dbg("udevdb_add_dev failed"); dev_d_send(&dev, subsystem, devpath); From fc238cffafab6518564ebfefaece5d24a8423daa Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 1 Apr 2004 22:59:56 -0800 Subject: [PATCH 0728/4284] [PATCH] put netdev handling and dev.d/ in manpages Mention the recently added netdev handling and the dev.d/ directories in the man pages. --- udev.8 | 56 +++++++++++++++++++++++++++++++++++++++++++----------- udevinfo.8 | 9 +++++---- udevtest.8 | 5 +++-- 3 files changed, 53 insertions(+), 17 deletions(-) diff --git a/udev.8 b/udev.8 index 417b74bdc5..680587a270 100644 --- a/udev.8 +++ b/udev.8 @@ -23,14 +23,25 @@ config file. .B UDEV_NO_SLEEP The default behavior of .B udev -is to wait until all the sysfs files of the device chain are populated. If set +is to wait until all the sysfs files of the device chain are populated. If set, .B udev will continue, regardless of the state of the device representation. +.TP +.B UDEV_NO_DEVD +The default behavior of +.B udev +is to execute programs in the +.I /etc/dev.d/ +directory after device handling. If set, +.B udev +will skip this step. .SH "DESCRIPTION" .B udev -creates or removes device node files usually located in the /dev directory. -It provides a dynamic device directory contaning only the files for -actually present devices. +provides a dynamic device directory containing only the files for actually +present devices. It creates or removes device node files usually located in +the /dev directory, or it renames network interfaces. +.br + .P As part of the .B hotplug @@ -42,7 +53,7 @@ On device creation, reads the sysfs directory of the given device to collect device attributes like label, serial number or bus device number. These attributes may be used as keys to determine a -unique name for device file creation. +unique name for the device. .B udev maintains a database for devices present on the system. .br @@ -88,8 +99,8 @@ If a directory is specified, the whole directory is scanned for files ending wit and all permission files are read in lexical order. .TP .B udev_log -If you want udev to log some information to the syslog for every node created or -removed. The default value is +If you want udev to log some information to the syslog for every device handled. +The default value is .IR yes . .TP .B default_mode @@ -149,9 +160,9 @@ value in the file. .P Every line in the rules file defines the mapping between device attributes -and the device file name. One or more keys are specified to match a rule -with the current device. If all keys are matching, the rule will be applied -and the name is used for the device node. +and the device name. One or more keys are specified to match a rule with +the current device. If all keys are matching, the rule will be applied and +the name is used to name the device file or the network interface. .br If no matching rule is found, the default kernel device name is used. .P @@ -200,7 +211,8 @@ call. This key may be used in any following rule after a call. .TP .B NAME -The name of the node to be created. +The name of the node to be created, or the name, the network interface +should be renamed to. .br If given with the attribute .BR NAME{ all_partitions } @@ -341,11 +353,33 @@ 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 character not enclosed is matched. +.P +After device node creation, removal, or network device renaming, +.B udev +executes the programs in the directory tree under +.IR /etc/dev.d/ . +The name of a program must end with +.I .dev +suffix, to be recognized. +.br +In addition to the hotplug environment variables, +.B DEVNAME +is exported to make the name of the created node, or the name the network +device is renamed to, available to the executed program. The programs in every +directory are sorted in lexical order, while the directories are searched in +the following order: +.sp +.nf +/etc/dev.d/$(DEVNAME)/*.dev +/etc/dev.d/$(SUBSYSTEM)/*.dev +/etc/dev.d/default/*.dev +.fi .SH "FILES" .nf /sbin/udev udev program /etc/udev/* udev config files /etc/hotplug.d/default/udev.hotplug hotplug symlink to udev program +/etc/dev.d/* programs invoked by udev .fi .LP .SH "SEE ALSO" diff --git a/udevinfo.8 b/udevinfo.8 index bf6a0aded1..0588084cac 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -24,7 +24,8 @@ directory. When used in conjunction with a query for the node name, the will be prepended. .TP .BI \-q " query_type" -Query the database for specified value of a created device node. +Query the database for specified value of a created device node or network +interface. .RB Needs " \-p " or " \-n " specified. .br Valid types are: @@ -34,9 +35,9 @@ Valid types are: Specify the sysfs path of the device to query. .TP .BI \-n " name" -Specify the name of the node or the symlink for the device to query. -Partition names generated with the NAME{all_partitons} option can not be -queried, the main device must be used instead. +Specify the name of the node, the symlink or the network interface for the +device to query. Partition names generated with the NAME{all_partitons} option +can not be queried, the main device must be used instead. .TP .B \-a Print all diff --git a/udevtest.8 b/udevtest.8 index f23e219244..6be7e089cf 100644 --- a/udevtest.8 +++ b/udevtest.8 @@ -7,8 +7,9 @@ udevtest \- simulates a udev run to test the configured rules .B udevtest simulates a .B udev -run for the given device, and prints out the node names -for the given device, the real udev would have created. +run for the given device, and prints out the name of the node +the real udev would have created, or the name of the renamed network +interface. .SH "SEE ALSO" .BR udev (8) .SH AUTHORS From c40f61e6e86943c3e1342b20b1c7d19ce30cc5a5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 23:36:58 -0800 Subject: [PATCH 0729/4284] [PATCH] tweak net_test a bit. --- test/net_test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/net_test b/test/net_test index fcc21e1b94..56a6847d19 100644 --- a/test/net_test +++ b/test/net_test @@ -29,7 +29,7 @@ ls -l udev export ACTION=remove export DEVPATH=class/net/eth1 -../udevtest net +../udevtest class/net/eth1 net ls -l udev rm $RULES From 42e4b6819ff91725fc101e1169e30ed27a7da3ca Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 23:37:43 -0800 Subject: [PATCH 0730/4284] [PATCH] add install and uninstall the etc/dev.d/net/hotplug.dev file to the Makefile --- Makefile | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 652e712d77..2504034b13 100644 --- a/Makefile +++ b/Makefile @@ -354,6 +354,13 @@ install-config: $(GEN_CONFIGS) install-dev.d: $(INSTALL) -d $(DESTDIR)$(dev_ddir) $(INSTALL) -d $(DESTDIR)$(dev_ddir)default/ + $(INSTALL_PROGRAM) -D etc/dev.d/net/hotplug.dev $(DESTDIR)$(dev_ddir)net/hotplug.dev + +uninstall-dev.d: + - rm $(dev_ddir)net/hotplug.dev + - rmdir $(dev_ddir)net + - rmdir $(dev_ddir)default + - rmdir $(dev_ddir) install: install-initscript install-config install-dev.d all $(INSTALL) -d $(DESTDIR)$(udevdir) @@ -381,7 +388,7 @@ endif -C $$target $@ ; \ done ; \ -uninstall: +uninstall: uninstall-dev.d - rm $(hotplugdir)/udev.hotplug - rm $(configdir)/udev.permissions - rm $(configdir)/udev.rules @@ -399,8 +406,6 @@ uninstall: - rm $(usrbindir)/$(INFO) - rmdir $(hotplugdir) - rmdir $(configdir) - - rmdir $(dev_ddir)default - - rmdir $(dev_ddir) - rm $(udevdir)/.udev.tdb - rmdir $(udevdir) @extras="$(EXTRAS)" ; for target in $$extras ; do \ From 438ac360e803c5b05d3c50c7bc93babbe0bea37d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 23:47:23 -0800 Subject: [PATCH 0731/4284] [PATCH] first step of making man pages dynamically generated. Based on a an original patch from Olaf Hering --- Makefile | 40 ++++++++++++++++++++++------------- udev.8 => udev.8.in | 0 udevd.8 => udevd.8.in | 0 udevinfo.8 => udevinfo.8.in | 0 udevstart.8 => udevstart.8.in | 0 udevtest.8 => udevtest.8.in | 0 6 files changed, 25 insertions(+), 15 deletions(-) rename udev.8 => udev.8.in (100%) rename udevd.8 => udevd.8.in (100%) rename udevinfo.8 => udevinfo.8.in (100%) rename udevstart.8 => udevstart.8.in (100%) rename udevtest.8 => udevtest.8.in (100%) diff --git a/Makefile b/Makefile index 2504034b13..01fb2a4486 100644 --- a/Makefile +++ b/Makefile @@ -246,6 +246,12 @@ GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf $(LOCAL_CFG_DIR)/udev.conf: sed -e "s:@udevdir@:$(udevdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ +GEN_MANPAGES = udev.8 udevd.8 udevinfo.8 udevstart.8 udevtest.8 +GEN_MANPAGESIN = udev.8.in udevd.8.in udevinfo.8.in udevstart.8.in udevtest.8.in +# Rules on how to create the man pages +$(GEN_MANPAGES): $(GEN_MANPAGESIN) + sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ + $(OBJS): $(GEN_HEADERS) $(ROOT).o: $(GEN_HEADERS) @@ -286,7 +292,7 @@ $(RULER): $(RULER).o $(OBJS) $(HEADERS) $(LIBC) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) $(RULER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) $(RULER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ @@ -362,7 +368,23 @@ uninstall-dev.d: - rmdir $(dev_ddir)default - rmdir $(dev_ddir) -install: install-initscript install-config install-dev.d all +install-man: $(GEN_MANPAGES) + $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 + $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 + $(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8 + $(INSTALL_DATA) -D udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 + $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 + - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 + +uninstall-man: + - rm $(mandir)/man8/udev.8 + - rm $(mandir)/man8/udevinfo.8 + - rm $(mandir)/man8/udevtest.8 + - rm $(mandir)/man8/udevstart.8 + - rm $(mandir)/man8/udevd.8 + - rm $(mandir)/man8/udevsend.8 + +install: install-initscript install-config install-man install-dev.d all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) @@ -371,12 +393,6 @@ install: install-initscript install-config install-dev.d all $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) - $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 - $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 - $(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8 - $(INSTALL_DATA) -D udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 - $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 - - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug ifndef DESTDIR - killall udevd @@ -388,18 +404,12 @@ endif -C $$target $@ ; \ done ; \ -uninstall: uninstall-dev.d +uninstall: uninstall-man uninstall-dev.d - rm $(hotplugdir)/udev.hotplug - rm $(configdir)/udev.permissions - rm $(configdir)/udev.rules - rm $(configdir)/udev.conf - rm $(initdir)/udev - - rm $(mandir)/man8/udev.8 - - rm $(mandir)/man8/udevinfo.8 - - rm $(mandir)/man8/udevtest.8 - - rm $(mandir)/man8/udevstart.8 - - rm $(mandir)/man8/udevd.8 - - rm $(mandir)/man8/udevsend.8 - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) diff --git a/udev.8 b/udev.8.in similarity index 100% rename from udev.8 rename to udev.8.in diff --git a/udevd.8 b/udevd.8.in similarity index 100% rename from udevd.8 rename to udevd.8.in diff --git a/udevinfo.8 b/udevinfo.8.in similarity index 100% rename from udevinfo.8 rename to udevinfo.8.in diff --git a/udevstart.8 b/udevstart.8.in similarity index 100% rename from udevstart.8 rename to udevstart.8.in diff --git a/udevtest.8 b/udevtest.8.in similarity index 100% rename from udevtest.8 rename to udevtest.8.in From 326e0876e40eb7559e7fbbde47785685013cb624 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Apr 2004 23:55:45 -0800 Subject: [PATCH 0732/4284] [PATCH] convert udev.8.in to use @udevdir@ macro for make install. --- udev.8.in | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/udev.8.in b/udev.8.in index 680587a270..76e727f598 100644 --- a/udev.8.in +++ b/udev.8.in @@ -77,11 +77,11 @@ in this file: .B udev_root Indicates where to place the device nodes in the filesystem. The default value is -.IR /udev/ . +.IR @udevdir@ . .TP .B udev_db The name and location of the udev database. The default value is -.IR /udev/.udev.tdb . +.IR @udevdir@/.udev.tdb . .TP .B udev_rules This is the location of the udev rules file. The default value for this is @@ -123,10 +123,10 @@ permissions file. The default value is .sp .nf # udev_root - where to place the device nodes in the filesystem -udev_root="/udev/" +udev_root="@udevdir@" # udev_db - The name and location of the udev database -udev_db="/udev/.udev.tdb" +udev_db="@udevdir@/.udev.tdb" # udev_rules - The location of the directory where to look for files which names ending with .rules From 487c1b35ba1d0a2f76d99dc9b9454e2895f915bb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 2 Apr 2004 00:01:58 -0800 Subject: [PATCH 0733/4284] [PATCH] switch to generate the man pages during the normal build, not during the install. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 01fb2a4486..d82fea0690 100644 --- a/Makefile +++ b/Makefile @@ -261,7 +261,7 @@ $(DAEMON).o: $(GEN_HEADERS) $(SENDER).o: $(GEN_HEADERS) $(STARTER).o: $(GEN_HEADERS) -$(ROOT): $(ROOT).o $(OBJS) $(HEADERS) $(LIBC) +$(ROOT): $(ROOT).o $(OBJS) $(HEADERS) $(LIBC) $(GEN_MANPAGES) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ @@ -368,7 +368,7 @@ uninstall-dev.d: - rmdir $(dev_ddir)default - rmdir $(dev_ddir) -install-man: $(GEN_MANPAGES) +install-man: $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 $(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8 From c19b069189fc31ff07bf482cf77fcf25549501b4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 2 Apr 2004 00:13:20 -0800 Subject: [PATCH 0734/4284] [PATCH] update bk ignore list some more. --- udevd.8.in => udevd.8 | 0 udevinfo.8.in => udevinfo.8 | 0 udevstart.8.in => udevstart.8 | 0 udevtest.8.in => udevtest.8 | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename udevd.8.in => udevd.8 (100%) rename udevinfo.8.in => udevinfo.8 (100%) rename udevstart.8.in => udevstart.8 (100%) rename udevtest.8.in => udevtest.8 (100%) diff --git a/udevd.8.in b/udevd.8 similarity index 100% rename from udevd.8.in rename to udevd.8 diff --git a/udevinfo.8.in b/udevinfo.8 similarity index 100% rename from udevinfo.8.in rename to udevinfo.8 diff --git a/udevstart.8.in b/udevstart.8 similarity index 100% rename from udevstart.8.in rename to udevstart.8 diff --git a/udevtest.8.in b/udevtest.8 similarity index 100% rename from udevtest.8.in rename to udevtest.8 From 08b5da6a030f86810c100e465d9bfaa5113ba34d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 2 Apr 2004 00:13:50 -0800 Subject: [PATCH 0735/4284] [PATCH] only generate udev.8 on the fly, not all other man pages. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d82fea0690..4c194cd0fc 100644 --- a/Makefile +++ b/Makefile @@ -246,8 +246,8 @@ GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf $(LOCAL_CFG_DIR)/udev.conf: sed -e "s:@udevdir@:$(udevdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ -GEN_MANPAGES = udev.8 udevd.8 udevinfo.8 udevstart.8 udevtest.8 -GEN_MANPAGESIN = udev.8.in udevd.8.in udevinfo.8.in udevstart.8.in udevtest.8.in +GEN_MANPAGES = udev.8 +GEN_MANPAGESIN = udev.8.in # Rules on how to create the man pages $(GEN_MANPAGES): $(GEN_MANPAGESIN) sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ From 5df33ccd8e03043597ff2b1777bbf5219e7080e3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 2 Apr 2004 16:58:57 -0800 Subject: [PATCH 0736/4284] [PATCH] udevstart fix Sorry, udevstart needs a small cleanup after my recent copy/pastes. --- udevstart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevstart.c b/udevstart.c index 7e19c379a5..5e6606d535 100644 --- a/udevstart.c +++ b/udevstart.c @@ -62,8 +62,8 @@ static void udev_exec(const char *path, const char* subsystem) char nosleep[] = "UDEV_NO_SLEEP=1"; char *env[] = { action, devpath, nosleep, NULL }; - strcpy(action, "DEVPATH=%s"); - strfieldcat(action, path); + strcpy(devpath, "DEVPATH="); + strfieldcat(devpath, path); pid = fork(); switch (pid) { From 4ef51da90ceec73aafacf32d1eba427236763ce1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 2 Apr 2004 16:58:59 -0800 Subject: [PATCH 0737/4284] [PATCH] increase udevd event timeout I have a very slow Bluetooth adapter hotplug event call, so we need to increase the event timeout to something larger than 6 seconds. Apr 1 02:54:08 pim udevsend[12119]: main: DEVPATH = '/class/tty/ttyUB0' Apr 1 02:54:08 pim udevsend[12119]: main: SEQNUM = '340' Apr 1 02:54:08 pim udevsend[12120]: main: DEVPATH = '/devices/pci0000:00/0000:00:1d.2/usb4/4-1' Apr 1 02:54:08 pim udevsend[12120]: main: SEQNUM = '344' Apr 1 02:54:09 pim udevsend[12133]: main: DEVPATH = '/devices/pci0000:00/0000:00:1d.2/usb4/4-1/4-1:1.1' Apr 1 02:54:09 pim udevsend[12133]: main: SEQNUM = '342' Apr 1 02:54:10 pim udevsend[12136]: main: DEVPATH = '/devices/pci0000:00/0000:00:1d.2/usb4/4-1/4-1:1.2' Apr 1 02:54:10 pim udevsend[12136]: main: SEQNUM = '343' Apr 1 02:54:13 pim udevsend[12141]: main: DEVPATH = '/devices/pci0000:00/0000:00:1d.2/usb4/4-1/4-1:1.0' Apr 1 02:54:13 pim udevsend[12141]: main: SEQNUM = '341' --- udevd.8 | 2 +- udevd.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/udevd.8 b/udevd.8 index 9d0127b6bc..52c270add8 100644 --- a/udevd.8 +++ b/udevd.8 @@ -28,7 +28,7 @@ in userspace, that makes it neccessary to reorder them. .B udevd takes care of the kernel supplied sequence number and arranges the events for execution in the correct order. Missing sequences delay the execution of the -following events until a timeout of a maximum of 5 seconds is reached. +following events until a timeout is reached. .br For each event a .BR udev (8) diff --git a/udevd.h b/udevd.h index 96f179ad44..5fdd62d323 100644 --- a/udevd.h +++ b/udevd.h @@ -25,7 +25,7 @@ #include "list.h" #define UDEV_MAGIC "udevd_" UDEV_VERSION -#define EVENT_TIMEOUT_SEC 5 +#define EVENT_TIMEOUT_SEC 10 #define UDEVSEND_CONNECT_RETRY 20 /* x 100 millisec */ #define UDEVD_SOCK_PATH "udevd" From 1e799babb6f37b2d52f1a0a3bfaf85c0405cf10a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 2 Apr 2004 16:59:01 -0800 Subject: [PATCH 0738/4284] [PATCH] put config info in db for netdev Small change, to put the config informations for handled network interfaces into the database. --- namedev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index a3ae1d36b3..51a4639abe 100644 --- a/namedev.c +++ b/namedev.c @@ -850,13 +850,13 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud found: apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + strfieldcpy(udev->config_file, dev->config_file); + udev->config_line = dev->config_line; if (udev->type == 'n') goto done; udev->partitions = dev->partitions; - strfieldcpy(udev->config_file, dev->config_file); - udev->config_line = dev->config_line; /* get permissions given in rule */ set_empty_perms(udev, dev->mode, From a53277558395dd30ed15dec3c9af6bab01fadfea Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 2 Apr 2004 16:59:04 -0800 Subject: [PATCH 0739/4284] [PATCH] man page cleanup Small cleanup of the wording in the udev. man page. --- udev.8.in | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/udev.8.in b/udev.8.in index 76e727f598..f803578968 100644 --- a/udev.8.in +++ b/udev.8.in @@ -84,38 +84,36 @@ The name and location of the udev database. The default value is .IR @udevdir@/.udev.tdb . .TP .B udev_rules -This is the location of the udev rules file. The default value for this is +The name of the udev rules file or directory to look for files with the suffix +.IR .rules . +All rule files are read in lexical order. The default value is .IR /etc/udev/udev.rules . -If a directory is specified, the whole directory is -scanned for files ending with -.I .rules -and all rule files are read in lexical order. .TP .B udev_permissions -This is the location of the udev permission file. The default value for this is +The name of the udev permission file or directory to look for files with the +suffix +.IR .permissions . +All permission files are read in lexical order. The default value is .IR /etc/udev/udev.permissions . -If a directory is specified, the whole directory is scanned for files ending with -.I .permissions -and all permission files are read in lexical order. .TP .B udev_log -If you want udev to log some information to the syslog for every device handled. +The switch, if udev logs some information for every device handled. The default value is .IR yes . .TP .B default_mode -This is the default mode for all nodes not explicitely matching in the -permissions file. The default value is +The default mode for all nodes not explicitely matching in the permissions +file. The default value is .IR 0666 . .TP .B default_owner -This is the default owner for all nodes not explicitely matching in the -permissions file. The default value is +The default owner for all nodes not explicitely matching in the permissions +file. The default value is .IR root . .TP .B default_group -This is the default group for all nodes not explicitely matching in the -permissions file. The default value is +The default group for all nodes not explicitely matching in the permissions +file. The default value is .IR root . .br .P @@ -128,11 +126,12 @@ udev_root="@udevdir@" # udev_db - The name and location of the udev database udev_db="@udevdir@/.udev.tdb" -# udev_rules - The location of the directory where to look for files - which names ending with .rules -udev_rules="/etc/udev/" +# udev_rules - The name of the udev rules file or directory to look + for files with the suffix .rules +udev_rules="/etc/udev/rules.d/" -# udev_permissions - The name and location of the udev permission file +# udev_permissions - The name of the udev permission file or directry to look + for files with the suffix .permissions udev_permissions="/etc/udev/udev.permissions" # udev_log - set to "yes" if you want logging, else "no" From 9a689d5863f2794aa71674dce4d251bec20ef0fb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 2 Apr 2004 17:02:09 -0800 Subject: [PATCH 0740/4284] [PATCH] remove compiler warning from udevd.c --- udevd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udevd.c b/udevd.c index d464b9a196..1bbb0a98e7 100644 --- a/udevd.c +++ b/udevd.c @@ -83,11 +83,13 @@ static void msg_dump_queue(void) #endif } +#if 0 static void msg_dump(struct hotplug_msg *msg) { dbg("sequence %d, '%s', '%s', '%s'", msg->seqnum, msg->action, msg->devpath, msg->subsystem); } +#endif static struct hotplug_msg *msg_create(void) { From dd785ba628d89ae2f67f2fac0f36d0d2393f4109 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 2 Apr 2004 20:10:35 -0800 Subject: [PATCH 0741/4284] [PATCH] handle netdev in udevruler Here we get the netdev handling for udevruler, after all information is available now in the udev database. It also fixes the way libsysfs is used. --- udevruler.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/udevruler.c b/udevruler.c index a13bd625a8..a065591cd1 100644 --- a/udevruler.c +++ b/udevruler.c @@ -222,6 +222,7 @@ static int add_all_attributes(const char *path, int level) } } + sysfs_close_directory(sysfs_dir); return 0; } @@ -229,7 +230,6 @@ static int get_all_attributes(char *path) { struct sysfs_class_device *class_dev; struct sysfs_class_device *class_dev_parent; - struct sysfs_attribute *attr; struct sysfs_device *sysfs_dev; struct sysfs_device *sysfs_dev_parent; char key[NAME_SIZE]; @@ -246,16 +246,6 @@ static int get_all_attributes(char *path) return -1; } - /* read the 'dev' file for major/minor*/ - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr == NULL) { - dbg("couldn't get the \"dev\" file"); - retval = -1; - goto exit; - } - - sysfs_close_attribute(attr); - /* open sysfs class device directory and get all attributes */ if (add_all_attributes(class_dev->path, level) != 0) { dbg("couldn't open class device directory"); @@ -266,11 +256,10 @@ static int get_all_attributes(char *path) /* get the device link (if parent exists look here) */ class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) { - //sysfs_close_class_device(class_dev); - class_dev = class_dev_parent; - } - sysfs_dev = sysfs_get_classdev_device(class_dev); + if (class_dev_parent != NULL) + sysfs_dev = sysfs_get_classdev_device(class_dev_parent); + else + sysfs_dev = sysfs_get_classdev_device(class_dev); /* look the device chain upwards */ while (sysfs_dev != NULL) { @@ -290,13 +279,11 @@ static int get_all_attributes(char *path) if (sysfs_dev_parent == NULL) break; - //sysfs_close_device(sysfs_dev); sysfs_dev = sysfs_dev_parent; } - sysfs_close_device(sysfs_dev); exit: - //sysfs_close_class_device(class_dev); + sysfs_close_class_device(class_dev); return retval; } @@ -403,7 +390,7 @@ int main(int argc, char *argv[]) { int i; int numitems; struct attribute **selattr; - char text_rule[80]; + char text_rule[255]; answer = newtRunForm(form); if (answer == quit) From b6bf0b123635cb0902a95d9d6d4584edef43ed19 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 2 Apr 2004 20:10:37 -0800 Subject: [PATCH 0742/4284] [PATCH] switch udevd's msg_dump() to #define Here we switch the msg_dump() to #define instead of commenting it out. --- udevd.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/udevd.c b/udevd.c index 1bbb0a98e7..b2cb62f386 100644 --- a/udevd.c +++ b/udevd.c @@ -73,6 +73,10 @@ void log_message (int level, const char *format, ...) } #endif +#define msg_dump(msg) \ + dbg("msg_dump: sequence %d, '%s', '%s', '%s'", \ + msg->seqnum, msg->action, msg->devpath, msg->subsystem); + static void msg_dump_queue(void) { #ifdef DEBUG @@ -83,14 +87,6 @@ static void msg_dump_queue(void) #endif } -#if 0 -static void msg_dump(struct hotplug_msg *msg) -{ - dbg("sequence %d, '%s', '%s', '%s'", - msg->seqnum, msg->action, msg->devpath, msg->subsystem); -} -#endif - static struct hotplug_msg *msg_create(void) { struct hotplug_msg *new_msg; From 49747bdc374d6f98846e86d57016d8009aacb1cb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 2 Apr 2004 22:16:38 -0800 Subject: [PATCH 0743/4284] [PATCH] tweak node unlink handling Based on a patch from Olaf Hering we remove the node now only if the requested dev_t is different from the already existing node, so any run of udevstart should preserve the inode number of the node file. syslog while the right node is already there: creating device node '/udev/hda' make_node: preserve file '/udev/hda', cause it has correct dev_t make_node: chmod(/udev/hda, 060600) syslog for wrong file already there: creating device node '/udev/hda' make_node: already present file '/udev/hda' unlinked make_node: chmod(/udev/hda, 060600) syslog for directory with same name already there: creating device node '/udev/hda' make_node: unlink(/udev/hda) failed with error '21' --- udev-add.c | 62 +++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/udev-add.c b/udev-add.c index 20599822d3..5dc46cf2a7 100644 --- a/udev-add.c +++ b/udev-add.c @@ -105,29 +105,46 @@ static int create_path(char *file) return 0; } -static int make_node(char *filename, int major, int minor, unsigned int mode, uid_t uid, gid_t gid) +static int make_node(char *file, int major, int minor, unsigned int mode, uid_t uid, gid_t gid) { - int retval; + struct stat stats; + int retval = 0; - retval = mknod(filename, mode, makedev(major, minor)); + if (stat(file, &stats) != 0) + goto create; + + /* preserve node with already correct numbers, to not change the inode number */ + if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && + (stats.st_rdev == makedev(major, minor))) { + dbg("preserve file '%s', cause it has correct dev_t", file); + goto perms; + } + + if (unlink(file) != 0) + dbg("unlink(%s) failed with error '%s'", file, strerror(errno)); + else + dbg("already present file '%s' unlinked", file); + +create: + retval = mknod(file, mode, makedev(major, minor)); if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", - filename, mode, major, minor, strerror(errno)); + file, mode, major, minor, strerror(errno)); goto exit; } - dbg("chmod(%s, %#o)", filename, mode); - if (chmod(filename, mode) != 0) { - dbg("chmod(%s, %#o) failed with error '%s'", - filename, mode, strerror(errno)); +perms: + dbg("chmod(%s, %#o)", file, mode); + if (chmod(file, mode) != 0) { + dbg("chmod(%s, %#o) failed with error '%s'", file, mode, strerror(errno)); goto exit; } if (uid != 0 || gid != 0) { - dbg("chown(%s, %u, %u)", filename, uid, gid); - if (chown(filename, uid, gid) != 0) { + dbg("chown(%s, %u, %u)", file, uid, gid); + if (chown(file, uid, gid) != 0) { dbg("chown(%s, %u, %u) failed with error '%s'", - filename, uid, gid, strerror(errno)); + file, uid, gid, strerror(errno)); goto exit; } } @@ -167,23 +184,6 @@ static void set_to_local_user(char *user) endutent(); } -static int unlink_entry(char *filename) -{ - struct stat stats; - int retval = 0; - - if (lstat(filename, &stats) == 0) { - if ((stats.st_mode & S_IFMT) != S_IFDIR) { - retval = unlink(filename); - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - } - } - } - return retval; -} - static int create_node(struct udevice *dev, int fake) { char filename[NAME_SIZE]; @@ -253,7 +253,6 @@ static int create_node(struct udevice *dev, int fake) } if (!fake) { - unlink_entry(filename); info("creating device node '%s'", filename); if (make_node(filename, dev->major, dev->minor, dev->mode, uid, gid) != 0) goto error; @@ -270,7 +269,6 @@ static int create_node(struct udevice *dev, int fake) for (i = 1; i <= dev->partitions; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); - unlink_entry(partitionname); make_node(partitionname, dev->major, dev->minor + i, dev->mode, uid, gid); } @@ -304,11 +302,9 @@ static int create_node(struct udevice *dev, int fake) strfieldcat(linktarget, &dev->name[tail]); - if (!fake) - unlink_entry(filename); - dbg("symlink(%s, %s)", linktarget, filename); if (!fake) { + unlink(filename); if (symlink(linktarget, filename) != 0) dbg("symlink(%s, %s) failed with error '%s'", linktarget, filename, strerror(errno)); From 1321258af575f1e704aedfb3b6ed8aa341632a50 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 2 Apr 2004 22:47:22 -0800 Subject: [PATCH 0744/4284] [PATCH] v024 release --- ChangeLog | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 64 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a9d4f94e06..abbab093bd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,65 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 4c194cd0fc..85620779ac 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 023_bk +VERSION = 024 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 1df59ecdb8..cacaf2868a 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 023_bk +Version: 024 Release: 1 License: GPL Group: Utilities/System From 4b06c852cb7da274b50f665a75367f901d8064ae Mon Sep 17 00:00:00 2001 From: "sjoerd@spring.luon.net" Date: Thu, 8 Apr 2004 18:48:56 -0700 Subject: [PATCH 0745/4284] [PATCH] DEVNODE -> DEVNAME transition fixes It seems that the transition from DEVNODE to DEVNAME wasn't done everywhere. This broke udev_dbus for me. Attached patch does the transition in the places it wasn't done yet. --- dev_d.c | 4 ++-- extras/dbus/udev_dbus.c | 24 ++++++++++++------------ extras/selinux/udev_selinux.c | 10 +++++----- udev_lib.c | 12 ++++++------ udev_lib.h | 2 +- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/dev_d.c b/dev_d.c index 483ceb4b1b..81c7013315 100644 --- a/dev_d.c +++ b/dev_d.c @@ -11,8 +11,8 @@ /* * This essentially emulates the following shell script logic in C: * DIR="/etc/dev.d" - * export DEVNODE="whatever_dev_name_udev_just_gave" - * for I in "${DIR}/$DEVNODE/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do + * export DEVNAME="whatever_dev_name_udev_just_gave" + * for I in "${DIR}/$DEVNAME/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do * if [ -f $I ]; then $I $1 ; fi * done * exit 1; diff --git a/extras/dbus/udev_dbus.c b/extras/dbus/udev_dbus.c index 955a3dbb49..e99e92ec87 100644 --- a/extras/dbus/udev_dbus.c +++ b/extras/dbus/udev_dbus.c @@ -80,10 +80,10 @@ static void sysbus_connect(void) /** Send out a signal that a device node is created * - * @param devnode name of the device node, e.g. /dev/sda1 + * @param devname name of the device node, e.g. /dev/sda1 * @param path Sysfs path of device */ -static void sysbus_send_create(const char *devnode, const char *path) +static void sysbus_send_create(const char *devname, const char *path) { DBusMessage* message; DBusMessageIter iter; @@ -94,7 +94,7 @@ static void sysbus_send_create(const char *devnode, const char *path) "NodeCreated"); dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, devnode); + dbus_message_iter_append_string(&iter, devname); dbus_message_iter_append_string(&iter, path); if ( !dbus_connection_send(sysbus_connection, message, NULL) ) @@ -107,10 +107,10 @@ static void sysbus_send_create(const char *devnode, const char *path) /** Send out a signal that a device node is deleted * - * @param devnode Name of the device node, e.g. /udev/sda1 + * @param devname Name of the device node, e.g. /udev/sda1 * @param path Sysfs path of device */ -static void sysbus_send_remove(const char *devnode, const char *path) +static void sysbus_send_remove(const char *devname, const char *path) { DBusMessage* message; DBusMessageIter iter; @@ -121,7 +121,7 @@ static void sysbus_send_remove(const char *devnode, const char *path) "NodeDeleted"); dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, devnode); + dbus_message_iter_append_string(&iter, devname); dbus_message_iter_append_string(&iter, path); if ( !dbus_connection_send(sysbus_connection, message, NULL) ) @@ -136,7 +136,7 @@ int main(int argc, char *argv[], char *envp[]) { char *action; char *devpath; - char *devnode; + char *devname; int retval = 0; init_logging("udev_dbus"); @@ -155,17 +155,17 @@ int main(int argc, char *argv[], char *envp[]) dbg("no devpath?"); goto exit; } - devnode = get_devnode(); - if (!devnode) { - dbg("no devnode?"); + devname = get_devname(); + if (!devname) { + dbg("no devname?"); goto exit; } if (strcmp(action, "add") == 0) { - sysbus_send_create(devnode, devpath); + sysbus_send_create(devname, devpath); } else { if (strcmp(action, "remove") == 0) { - sysbus_send_remove(devnode, devpath); + sysbus_send_remove(devname, devpath); } else { dbg("unknown action '%s'", action); retval = -EINVAL; diff --git a/extras/selinux/udev_selinux.c b/extras/selinux/udev_selinux.c index bbbdd6ba53..df23d9e6a7 100644 --- a/extras/selinux/udev_selinux.c +++ b/extras/selinux/udev_selinux.c @@ -48,7 +48,7 @@ int main(int argc, char *argv[], char *envp[]) { char *action; char *devpath; - char *devnode; + char *devname; int retval = 0; init_logging("udev_selinux"); @@ -58,14 +58,14 @@ int main(int argc, char *argv[], char *envp[]) dbg("no action?"); goto exit; } - devnode = get_devnode(); - if (!devnode) { - dbg("no devnode?"); + devname = get_devname(); + if (!devname) { + dbg("no devname?"); goto exit; } if (strcmp(action, "add") == 0) - selinux_add_node(devnode); + selinux_add_node(devname); exit: return retval; diff --git a/udev_lib.c b/udev_lib.c index db1096ebf7..381492db01 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -58,15 +58,15 @@ char *get_devpath(void) return devpath; } -char *get_devnode(void) +char *get_devname(void) { - char *devnode; + char *devname; - devnode = getenv("DEVNODE"); - if (devnode != NULL && strlen(devnode) > NAME_SIZE) - devnode[NAME_SIZE-1] = '\0'; + devname = getenv("DEVNAME"); + if (devname != NULL && strlen(devname) > NAME_SIZE) + devname[NAME_SIZE-1] = '\0'; - return devnode; + return devname; } char *get_seqnum(void) diff --git a/udev_lib.h b/udev_lib.h index e412ba96f4..cc264fa9b4 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -68,7 +68,7 @@ do { \ extern char *get_action(void); extern char *get_devpath(void); -extern char *get_devnode(void); +extern char *get_devname(void); extern char *get_seqnum(void); extern char *get_subsystem(char *subsystem); extern char get_device_type(const char *path, const char *subsystem); From a41de03083de75a972ee48dbe2c8c03f5d73cf57 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 8 Apr 2004 18:49:27 -0700 Subject: [PATCH 0746/4284] [PATCH] fix devpath for netdev Fix the devpath string for unhandled netdev's. --- udev-add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev-add.c b/udev-add.c index 5dc46cf2a7..900e4795aa 100644 --- a/udev-add.c +++ b/udev-add.c @@ -453,6 +453,7 @@ int udev_add_device(char *path, char *subsystem, int fake) break; case 'n': + strfieldcpy(devpath, path); if (strcmp(dev.name, dev.kernel_name) != 0) { retval = rename_net_if(&dev, fake); if (retval != 0) @@ -460,7 +461,6 @@ int udev_add_device(char *path, char *subsystem, int fake) /* netif's are keyed with the configured name, cause * the original kernel name sleeps with the fishes */ - strfieldcpy(devpath, path); pos = strrchr(devpath, '/'); if (pos != NULL) { pos[1] = '\0'; From 0e404ee1efdb941d1c287434abe1e56f571dc7ba Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 8 Apr 2004 21:51:47 -0700 Subject: [PATCH 0747/4284] [PATCH] added a dev.d alsa script to help people out. Originally by Marco d'Itri --- etc/dev.d/snd/controlC0/alsa.dev | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 etc/dev.d/snd/controlC0/alsa.dev diff --git a/etc/dev.d/snd/controlC0/alsa.dev b/etc/dev.d/snd/controlC0/alsa.dev new file mode 100644 index 0000000000..642dde4f36 --- /dev/null +++ b/etc/dev.d/snd/controlC0/alsa.dev @@ -0,0 +1,2 @@ +#!/bin/sh -e +exec /usr/sbin/alsactl restore 0 From a04913b56858448ed42724ab7d544f70289bb2bf Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Apr 2004 00:43:14 -0700 Subject: [PATCH 0748/4284] [PATCH] added rules for CAPI devices. Thanks to Marcel Holtmann for the information. --- etc/udev/udev.rules | 4 ++++ etc/udev/udev.rules.gentoo | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index dd934df850..27a11ae900 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -34,3 +34,7 @@ KERNEL="hiddev*", NAME="usb/%k" KERNEL="auer*", NAME="usb/%k" KERNEL="legousbtower*", NAME="usb/%k" KERNEL="dabusb*", NAME="usb/%k" + +# CAPI devices +KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" +KERNEL="capi*", NAME="capi/%n" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 28e92aab1b..da41b3e2e5 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -119,3 +119,7 @@ KERNEL="route6", NAME="netlink/%k" KERNEL="ip6_fw", NAME="netlink/%k" KERNEL="dnrtmsg", NAME="netlink/%k" KERNEL="tap*", NAME="netlink/%k" + +# CAPI devices +KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" +KERNEL="capi*", NAME="capi/%n" From e3f83d532e2e7415c003e2759750c96ecb635e81 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Apr 2004 01:19:41 -0700 Subject: [PATCH 0749/4284] [PATCH] added rule to put USB printers in their proper places. Thanks to Dan Weber for the info. --- etc/udev/udev.rules | 1 + etc/udev/udev.rules.devfs | 1 + etc/udev/udev.rules.gentoo | 1 + 3 files changed, 3 insertions(+) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index 27a11ae900..ef61eafb8d 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -34,6 +34,7 @@ KERNEL="hiddev*", NAME="usb/%k" KERNEL="auer*", NAME="usb/%k" KERNEL="legousbtower*", NAME="usb/%k" KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" # CAPI devices KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index f7903a0d23..3934fc6984 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -78,6 +78,7 @@ KERNEL="hiddev*", NAME="usb/%k" KERNEL="auer*", NAME="usb/%k" KERNEL="legousbtower*", NAME="usb/%k" KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" # netlink devices KERNEL="route", NAME="netlink/%k" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index da41b3e2e5..ab6f3bd405 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -105,6 +105,7 @@ KERNEL="hiddev*", NAME="usb/%k" KERNEL="auer*", NAME="usb/%k" KERNEL="legousbtower*", NAME="usb/%k" KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" # netlink devices KERNEL="route", NAME="netlink/%k" From eab52c24431b4305708a7579a823585555b8f33b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 13 Apr 2004 01:21:46 -0700 Subject: [PATCH 0750/4284] [PATCH] udev_dbus changes On Sun, Apr 11, 2004 at 03:51:07AM +0200, Kay Sievers wrote: > Here we change extras/dbus/* to > o install the binary in /etc/dev.d > o append .dev to the binary > o add David's copyright > o add the listener script to watch the sent dbus messages > o removed the undefined udev_log variable > o switch printf() to dbg() Here we install the binary in /usr/sbin/ and symlink it to /etc/dev.d/ with the .dev suffix. --- extras/dbus/Makefile | 7 ++++- extras/dbus/dbus-listen-test.py | 26 +++++++++++++++++++ extras/dbus/udev_dbus.c | 45 +++++++++++++++++++++++---------- 3 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 extras/dbus/dbus-listen-test.py diff --git a/extras/dbus/Makefile b/extras/dbus/Makefile index 99aa33d8fb..04f17605e8 100644 --- a/extras/dbus/Makefile +++ b/extras/dbus/Makefile @@ -22,8 +22,9 @@ exec_prefix = ${prefix} etcdir = ${prefix}/etc sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -hotplugdir = ${etcdir}/hotplug.d/default +devddir = ${etcdir}/dev.d/default dbusdir = ${etcdir}/dbus-1/system.d configdir = ${etcdir}/udev/ initdir = ${etcdir}/init.d/ @@ -53,9 +54,13 @@ spotless: clean install-dbus-policy: $(INSTALL) -d $(DESTDIR)$(dbusdir) $(INSTALL_DATA) etc/dbus-1/system.d/udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(usrsbindir)/$(PROG) + - ln -s -f $(DESTDIR)$(usrsbindir)/$(PROG) $(DESTDIR)$(devddir)/$(PROG).dev uninstall-dbus-policy: - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf + - rm $(DESTDIR)$(devddir)/$(PROG).dev + - rm $(DESTDIR)$(usrsbindir)/$(PROG) install: install-dbus-policy all diff --git a/extras/dbus/dbus-listen-test.py b/extras/dbus/dbus-listen-test.py new file mode 100644 index 0000000000..6a68b5d2aa --- /dev/null +++ b/extras/dbus/dbus-listen-test.py @@ -0,0 +1,26 @@ +#!/usr/bin/python + +# receives and prints the messages udev_dbus sent +# to the org.kernel.udev.NodeMonitor interface + +import dbus +import gtk + +def udev_signal_received(dbus_iface, member, service, object_path, message): + [filename, sysfs_path] = message.get_args_list() + if member=='NodeCreated': + print 'Node %s created for %s'%(filename, sysfs_path) + elif member=='NodeDeleted': + print 'Node %s deleted for %s'%(filename, sysfs_path) + +def main(): + bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) + bus.add_signal_receiver(udev_signal_received, + 'org.kernel.udev.NodeMonitor', # interface + 'org.kernel.udev', # service + '/org/kernel/udev/NodeMonitor') # object + gtk.mainloop() + +if __name__ == '__main__': + main() + diff --git a/extras/dbus/udev_dbus.c b/extras/dbus/udev_dbus.c index e99e92ec87..4852d429f8 100644 --- a/extras/dbus/udev_dbus.c +++ b/extras/dbus/udev_dbus.c @@ -1,3 +1,23 @@ +/* + * udev_dbus.c + * + * Copyright (C) 2003 David Zeuthen + * + * 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. + * + */ + #include #include #include @@ -18,21 +38,18 @@ void log_message(int level, const char *format, ...) { va_list args; - if (!udev_log) - return; - va_start(args, format); vsyslog(level, format, args); va_end(args); } #endif -/** variable for the connection the to system message bus or #NULL +/* Variable for the connection the to system message bus or NULL * if we cannot connect or acquire the org.kernel.udev service */ static DBusConnection* sysbus_connection; -/** Disconnect from the system message bus */ +/* Disconnect from the system message bus */ static void sysbus_disconnect(void) { if (sysbus_connection == NULL) @@ -42,7 +59,7 @@ static void sysbus_disconnect(void) sysbus_connection = NULL; } -/** Connect to the system message bus */ +/* Connect to the system message bus */ static void sysbus_connect(void) { DBusError error; @@ -70,18 +87,18 @@ static void sysbus_connect(void) dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, &error); if (dbus_error_is_set(&error)) { - printf("cannot acquire org.kernel.udev service, error %s: %s'", - error.name, error.message); + dbg("cannot acquire org.kernel.udev service, error %s: %s'", + error.name, error.message); sysbus_disconnect(); return; } } -/** Send out a signal that a device node is created +/* Send out a signal that a device node is created * - * @param devname name of the device node, e.g. /dev/sda1 - * @param path Sysfs path of device + * @param devname Name of the device node, e.g. /dev/sda1 + * @param path Sysfs path of device */ static void sysbus_send_create(const char *devname, const char *path) { @@ -105,10 +122,10 @@ static void sysbus_send_create(const char *devname, const char *path) dbus_connection_flush(sysbus_connection); } -/** Send out a signal that a device node is deleted +/* Send out a signal that a device node is deleted * - * @param devname Name of the device node, e.g. /udev/sda1 - * @param path Sysfs path of device + * @param devname Name of the device node, e.g. /udev/sda1 + * @param path Sysfs path of device */ static void sysbus_send_remove(const char *devname, const char *path) { From b1ea9f3ef5aad038b4d31cb3e79749de9afb41f8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 13 Apr 2004 01:28:05 -0700 Subject: [PATCH 0751/4284] [PATCH] added execelent "writing udev rules" document from Daniel Drake --- docs/writing_udev_rules/index.html | 408 +++++++++++++++++++++++++++++ 1 file changed, 408 insertions(+) create mode 100644 docs/writing_udev_rules/index.html diff --git a/docs/writing_udev_rules/index.html b/docs/writing_udev_rules/index.html new file mode 100644 index 0000000000..0e4d54cfaf --- /dev/null +++ b/docs/writing_udev_rules/index.html @@ -0,0 +1,408 @@ + + +Writing udev rules [reactivated.net] + + + + + +

Writing udev rules

+by Daniel Drake (dsd)
+Version 0.51

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

Contents

+
    +
  1. About this document
  2. +
  3. History
  4. +
  5. Software versions used at time of writing
  6. +
  7. Terminology: devfs, sysfs, nodes, etc.
  8. + +
  9. Why? (The purpose of this document)
  10. +
  11. The basics of writing rules
  12. +
  13. Additional automated customisation for NAME and SYMLINK parameters
  14. +
  15. Using regular expressions and wildcards in keys
  16. +
  17. Key-writing basics
  18. +
  19. Identifying devices through basic keys
  20. +
  21. Identifying devices through SYSFS files
  22. +
  23. Example: Writing a rule for my USB printer
  24. +
  25. Example: Writing a rule for my USB-Storage digital camera
  26. + +
  27. Additional notes on writing rules for USB storage
  28. +
  29. Example: Writing convenience rules for my CD drives
  30. +
  31. Tips for finding the appropriate places in SYSFS
  32. +
  33. udev vs Nvidia's graphics drivers
  34. +
  35. Author and credits
  36. +
+ + +

About this document

+udev is targetted at Linux kernels 2.6 and beyond to provide a userspace solution for a dynamic /dev directory, with persistant 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.

+ +udev is a well thought out solution, but I was initially very confused how I might customise it for my system. This document attempts to make the process of rule writing a little bit clearer.

+ +I'm all open to feedback - please contact me with any comments, problems, and suggested improvements.

+ +This document assumes that you have udev/hotplug installed and running OK with default configurations. If you do not yet have udev configured and running, I would suggest that you follow Decibels udev Primer to get to this stage (contains some Gentoo Linux specifics, but should be useful for other distro's too).

+ + + +

History

+ +April 6th 2004: I now write suggest users to use their own "local.rules" file rather than prepending "udev.rules".

+ +April 3rd 2004: Minor cleanups and preparations for possible inclusion in the udev distribution.

+February 15th 2004: Initial publication.

+February 18th 2004: Fixed a small omission in an example. Updated section on identifying mass-storage devices. Updated section on nvidia.

+February 23rd 2004: 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.

+March 20th 2004: General improvements, clarifications, and cleanups. Added more information about writing rules for usb-storage.

+ + +

Software versions used at time of writing

+Linux Kernel 2.6.5-rc3
+ +udev 024
+hotplug 20040401

+ + +

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, XFree86 will "listen to" /dev/input/mice so that it can relate the users 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 managable approach (noticably, 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 browsable. 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?

+ +As stated above, writing rules for udev is an optional process. By default, you can plug a device in, and the a relevant node (e.g. /dev/sda for a mass-storage device) will be there, just like in previous /dev implementations.

+ +However, udev allows you to customise the naming of device nodes. There are two reasons why you might want to do this: convenience, and persistant naming.

+ +Take the example of using udev, so that when your printer is plugged in, it gets named as /dev/printer and also as the usual /dev/lp0. It's not only convenience (e.g. reading and interpreting "printer" as opposed to "lp0"), its a solution for non-persistant naming. Say that I have two printers - a HP laser printer and an Epson inkjet. When they are both plugged in and on, I have /dev/lp0 and /dev/lp1.
+ +How do I know which node refers to which printer? There is no easy way. The first printer that got connected was assigned name "lp0", and the second "lp1". Plugging in my printers in a different order would swap the names here, and that would mess up my scripts that always expect my HP laser printer to be lp1.

+ +However, if my HP laser printer got named lp_hp (as well as lpX) and my other printer got named lp_epson (as well as lpY), then my scripts could just refer to those names. udev magic can control this and ensure that these persistant names always point to the device that I intended.

+ +For external mass-storage devices (e.g. usb hard disks), persistant naming is very helpful in that it allows you to hardcode accurate device paths into your /etc/fstab.

+ + +

The basics of writing rules

+ +When populating /dev, udev decides which nodes to include, and how to name them, by reading a rules file. The default rules file includes some examples, and defaults to giving a devfs-style layout. The examples may safely be removed, but it is generally sensible to keep the devfs rules and simply make your own amendments and modifications.

+ +Default udev rules are stored in /etc/udev/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, to reduce hassle while updating your udev installation in the future.

+ +Files in /etc/udev are parsed in lexical order. udev will stop processing rules as soon as it finds a matching rule in a file for the new item of hardware that has been detected. It is important that your own rules get processed before the udev defaults, otherwise your own naming schemes will not take effect! I suggest that you keep your own rules in a file at /etc/udev/local.rules (this doesn't exist by default - create it). As L comes before U, you know that your rules will be looked at first.

+ +As your own rules will effectively mask out the udev defaults which create the base /dev layout, it is recommended that you also specify devfs-style names/symlinks for the rules you write, so that you get the sensible defaults plus your own names.

+ +In rule files, lines starting with a "#" are treated as comments. Every uncommented line in the file corresponds to a rule.

+ +The basic form for a rule is: +
key,[key,...] name [, symlink]
+ +
    +
  1. At least one key must be specified. Keys are used to identify which devices the rule matches.
  2. +
  3. The name parameter is required. It tells udev what that device should be named as in the /dev tree. It is written in the format NAME="X", where X is what the node will be named. You can specify multiple symlinks here, seperate them with a space.
  4. +
  5. The symlink parameter (optional) allows for you to specify additional places where this node will be linked.
  6. +
+ +Remember that udev will only create one node for one device. If you want it to be accessible through multiple nodes, then you have to specify the other nodes in the SYMLINK parameter.

+ +I'll take a slightly modified udev example rule to illustrate this: +
BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson", SYMLINK="printers/epson_stylus"
+ +The keys here are the BUS and SYSFS{serial} parameters. udev will match this rule against a device that is connected through the USB bus and with a serial number of HXOLL0012202323480. Note that all (as opposed to any) specified keys must be matched for udev to use the rule to name a device.
+ +udev will name this node lp_epson, and it will be located at /dev/lp_epson.
+udev will also create a symlink to /dev/lp_epson, located at /dev/printers/epson_stylus (the printers directory will be automatically created). You can now print to your Epson printer by sending data to /dev/printers/epson_stylus or /dev/lp_epson.

+ + +

Additional automated customisation for NAME and SYMLINK parameters

+ +In the NAME and SYMLINK parameters of your rules, you are able to use basic operators to assist the naming of devices. Hackers will know this sort of thing as printf-like string substitution. + +There are a number of operators which can compose some or all of your NAME/SYMLINK parameters. These operators refer to kernel-data relating to the device. Take this example: + +
BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n"
+ +The %n operator will be replaced with the "kernel number" for the camera device, to produce a NAME such as camera0, camera1, etc.

+ +Another common operator is %k. This represents what the kernel would name the device, e.g. "hda1". You may often see rules which have NAME="%k" to produce the default names for the hardware. In these rules, customisation is usually done through the SYMLINK parameter.

+ +A full list of operators, with explanations, can be found in the udev man page.

+ + +

Using regular expressions and wildcards in keys

+ +You can use wildcards and basic regular-expression style matching to provide even more flexibility when writing keys. Taking a default udev rule: + +
KERNEL="ts*", NAME="input/%k"
+ +The * operator is used here, which matches literally anything - zero, one, or more characters of any kind. The rule literally says:
+ +
Match a device identified by a KERNEL name starting with the letters "ts" optionally followed by anything at all, and name it with the KERNEL name (%k) under the input directory.
+ +The ? operator is similar, and matches any single character (but not zero characters).

+ +You can also use square brackets [ ] to match any single character. Direct quote from udev man page:
+
For example, the pattern string "tty[SR]" would match either "ttyS" or "ttyR".
+ +You can also specify ranges that can be matched, e.g. [0-9] would match any single digit. Using an example rule from a default udev installation: + +
KERNEL="fd[0-9]*", NAME="floppy/%n"
+ +This rule says:
+ +
Match a device identified by a KERNEL name starting with the letters "fd", followed by any single digit, optionally followed by anything at all. Name the device with the kernel number of the device (%n) under the floppy directory.
+ +You can use these wildcards/regular-expression matches in any type of key, including both basic keys and sysfs-based identification (see below for explanations of these key types).

+ +I have purposely left out some information on this topic (particularly the flexibility of using [ ] operators) that is out of the scope of basic rule-writing documentation. More information on this topic can be found in the udev man page.

+ + +

Key-writing basics

+ +udev provides a few basic key matching methods, and also provides flexible ways of matching information in SYSFS. A typical rule will match both normal keys (e.g. BUS and KERNEL), as well as SYSFS keys to differentiate between different hardware plugged in throught the same port.

+ +You may be wondering, "How do I find the serial number of my printer? What is the model of my camera?". Rule writing isn't as hard as it sounds. The trickiest bit is finding your device in /sys, and deciding which info to use.

+ + +

Identifying devices through basic keys

+ +See the udev man page for more info on these keys.

+ +The valid keys are: +
  • BUS - match the bus type of the device.
  • +
  • KERNEL - match the kernel device name.
  • +
  • ID - match the device number on the bus (e.g. PCI bus ID).
  • +
  • PLACE - match the physical position where the device is plugged into (useful for USB).
  • + +
+ +The ID and PLACE keys do have their uses, but they are not commonly used in rules. This document focuses on using BUS and KERNEL keys, as well as SYSFS{...} keys (detailed in the next section). I will show how to use these keys by example.

+ +For extra flexibility, udev also provides keys to call external scripts and examine their result. This is out of scope of this document. Look at the udev man page for more details. + + +

Identifying devices through SYSFS files

+ +Background information: SYSFS stores many small files under a tree of directories which provide information about your hardware. One file typically contains just one "data item" - e.g. device name, manufacturer, or product ID.

+Note that SYSFS{...} keys can be combined with the basic keys described in the previous section.


+ +You can use keys in the format SYSFS{filename} to match specific info from SYSFS, where filename corresponds to a file in your SYSFS tree. For example, when my camera is connected, there is a file located at /sys/block/sda/device/model which contains "USB 2.0M DSC". To match this, I could use the following key: SYSFS{model} = "USB 2.0M DSC"

+ +Note that any file in sysfs can be matched in this manner, but if you match more than one file (through multiple keys), then you must only match files that exist in the same directory. Typically, there will be several directories giving information about one device. You cannot mix and match (as shown by example below).

+ +Luckily, the process of rule writing does not entail hunting through millions of files in SYSFS, the udevinfo utility does the hard work. This program is included in the udev distribution.

+ +The first thing you need to do is find a directory somewhere in /sys that corresponds to your hardware, and includes a file named "dev", as udevinfo can only work on directories of this type. These directories are all found under either /sys/block or /sys/class - there is no point looking anywhere else! However, udevinfo will follow links through this directory and read info found from other sections of sysfs.

+ +Once you have found a directory of this type, you can use the following command to assist you in the creation of writing keys for udev rules: +
# udevinfo -a -p /sys/path/to/hardware/info
+ +Some snipped output of the results of my "udevinfo -a -p /sys/block/sda" command is shown below, with colour added.
+ +

+follow the class device's "device"
+  looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3/3-3:1.0/host0/0:0:0:0':
+    BUS="scsi"
+    ID="0:0:0:0"
+    SYSFS{detach_state}="0"
+    SYSFS{type}="0"
+    SYSFS{max_sectors}="240"
+    SYSFS{device_blocked}="0"
+    SYSFS{queue_depth}="1"
+    SYSFS{scsi_level}="3"
+    SYSFS{vendor}="        "
+    SYSFS{model}="USB 2.0M DSC    "
+    SYSFS{rev}="1.00"
+    SYSFS{online}="1"
+
+  looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3':
+    BUS="usb"
+    ID="3-3"
+    SYSFS{detach_state}="0"
+    SYSFS{bNumInterfaces}=" 1"
+    SYSFS{bConfigurationValue}="1"
+    SYSFS{bmAttributes}="c0"
+    SYSFS{bMaxPower}="  0mA"
+    SYSFS{idVendor}="052b"
+    SYSFS{idProduct}="1514"
+    SYSFS{bcdDevice}="0100"
+    SYSFS{bDeviceClass}="00"
+    SYSFS{bDeviceSubClass}="00"
+    SYSFS{bDeviceProtocol}="00"
+    SYSFS{bNumConfigurations}="1"
+    SYSFS{speed}="12"
+    SYSFS{manufacturer}="Tekom Technologies, Inc"
+    SYSFS{product}="USB 2.0M DSC"
+
+ +The udevinfo tool provides a lot of information which you can simply copy-paste as udev rules. The reason that I have colour coded the above output is to point out that you generally cannot mix and match information from different parts of the udevinfo output. In the above output, I could not combine information from the different coloured sections - this is because each section of output refers to a different directory in SYSFS. For example, the following rule would not work: +
BUS="scsi", SYSFS{manufacturer}="Tekom Technologies, Inc", NAME="%k"
+This rule would not work because I am combining information found in the section beginning with BUS="scsi" (green) with information only found in the blue section. The rule would work if I used BUS="usb", sticking only to information found in the blue section above.

+ +You will notice that a lot of information is not relevant for writing basic rules (there is so much of it!), you should generally be looking for information that you recognise and know will not change (e.g. model name).

+ +Note that if you write your own rule to identify a device, the default devfs-style rules will not take effect! It is usually sensible to use NAME="%k" and specify your own extra names in the SYMLINK parameter so that you do not lose the default sensible names.

+ +I will show three examples of this rule writing based on udevinfo output process below. I will then attempt to list some device-dependant tips and tricks for locating the correct info.

+ +A reader wrote to me and informed me that he found KDE's control centre useful for writing rules. Apparently, information about USB devices (and others) can be found in the "Info Centre" section of the KDE Control Centre. This interface shows information such as serial number, vendor ID, etc. If you prefer a GUI-like approach, you might want to investigate this. + + +

Example: Writing a rule for my USB printer

+ +After plugging in my printer, I started looking around some /sys directories for a relevant place to start. I didn't get anywhere, but I noticed that my printer had been given device node /dev/lp0. I used this command sequence to find an answer: +
+# cd /sys
+# find | grep lp0
+./class/usb/lp0
+./class/usb/lp0/dev
+./class/usb/lp0/driver
+./class/usb/lp0/device
+
+ +Running "udevinfo -a -p /sys/class/usb/lp0" provided me with a heap of info, as usual. I picked out the relevant bits for unique device identification: +
+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 udev rule becomes: +
BUS="usb", SYSFS{serial}="L72010011070626380", NAME="%k", SYMLINK="epson_680"
+ +And my printer nodes exist at /dev/lp0 (or /dev/lp1 if another printer was plugged in beforehand) and /dev/epson_680 always points at the device node for that particular printer.

+ + +

Example: Writing a rule for my USB-Storage digital camera

+ +Quick Intro: My camera identifies itself as an external SCSI hard disk (it uses the usb-storage driver which is also used by devices such as USB hard disks and flash-card readers). I can then mount the partition on that disk and copy images over. Not all cameras work like this - many require external software (e.g. gphoto2) to be able to access photos.

+ +This one is a bit tricky. Two nodes are created by default when my camera is connected : /dev/sda and /dev/sda1. sda1 is the node that I would like as my /dev/camera, as that is what gets mounted. The problem is that there are only small details which can be used as udev rules to show the difference between sda and sda1.

+ +As these nodes (sda, sda1) are treated as block devices, looking in /sys/block would be a good place to start.

+ +In my /sys/block, I have a directory named sda. In my /sys/block/sda, I have a directory named sda1. Both of these directories have dev files in, so they are OK for udev rules. Running the following dumps a lot of information about my camera and the USB ports it is connected through. + +
+# udevinfo -a -p /sys/block/sda
+# udevinfo -a -p /sys/block/sda/sda1
+
+ +The output of both of these command was almost identical, so that does not help in writing keys to differentiate between sda and sda1.
+ +To differentiate between sda and sda1, I decided that matching KERNEL names would be most appropriate here. Some examples of KERNEL names for this type of device are: sda, sda1, sdb, sdb1, sdc, ...

+ +udev's support for wildcards in key expressions comes in handy here. A key such as KERNEL="sd?1" would match KERNEL names such as "sda1", "sdb1", "sdc1", and equally importantly, it will not match KERNEL names such as sda, sdb (because the name must have a "1" on the end). The purpose of this key is to ignore the /dev/sda node. The device is a digital camera - I would not dream of fdisking it or anything like that, so this node is pretty useless to me. The key attempts to capture the /dev/sda1 node, which is mountable and therefore useful!

+ +In the udevinfo output, I also noticed this bit of useful and understandable information: +
SYSFS{product}="USB 2.0M DSC"
+ +So that gives me my rule. For completeness, I also include a BUS key (this was also found in the udevinfo output). +
BUS="usb", SYSFS{product}="USB 2.0M DSC", KERNEL="sd?1", NAME="%k", SYMLINK="camera"
+ +Now, when my camera is plugged in, it will be named /dev/sda1 (or, if sda1 isnt available, it might be called /dev/sdb1) and will always be correctly linked to from /dev/camera. The /dev/sda (or sdb) node still appears as normal, but the important thing is that my custom persistant "camera" symlink points to the mountable partition.

+ + +

Additional notes on writing rules for USB storage

+ +Carl Streeter, the owner of a large USB hard disk, wrote to me and explained that unlike in my digital camera example, the /dev/sda node is useful to him. He pointed out that he does occasionally need to use tools such as fdisk and hdparm on that node.

+ +Carl's rule is: +
BUS="usb", KERNEL="sd*", SYSFS{product}="USB 2.0 Storage Device", NAME="%k", SYMLINK="usbhd%n"
+ +This rule creates symlinks such as: +
    +
  • /dev/usbhdd - The fdiskable node
  • +
  • /dev/usbhdd1 - The first partition (mountable)
  • +
  • /dev/usbhdd2 - The second partition (mountable)
  • + +
+ +We agreed that depending on the situation and device in question, there are reasons for both wanting and not wanting the non-mountable /dev/sda node. Use whichever setup suits you best.

+ + +

Example: Writing convenience rules for my CD drives

+I have two CD drives in my PC - a DVD reader, and a CD rewriter. My DVD is hdc and my CDRW is hdd. I would not expect this to change, unless I manually changed the cabling of my system.

+ +Still, some people (myself included) like to have nodes such as /dev/dvd and /dev/cdrw for convenience. Since we know the "hdX" values for these drives, writing rules is simple. The examples below should be self explanatory. + + +
+BUS="ide", KERNEL="hdc", NAME="%k", SYMLINK="dvd cdroms/cdrom%n"
+BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n"
+
+ +You may have noticed that the default udev.rules file contains a rule which runs a script to produces names for block devices. Do not be confused by this - as usual, because your own rules in local.rules are processed before the default rules, the default rules will not be used when naming the hardware you have written rules for.

+ + +

Tips for finding the appropriate places in SYSFS

+I'm looking for some more device specific tips here. Please contact me with any you can provide. + +
    +
  • Always use udevinfo to assist the rule-writing process. Always use udevinfo to look under /sys/block or /sys/class (it will not start reading a chain from anywhere else).
  • +
  • If you get totally stuck, use the following command to find all "dev" files under /sys (udevinfo can work on directories containing this file): find /sys -iname dev
  • +
  • If your device is a flash-card reader, usb flash-drive, or digital camera that acts as usb-storage, that is created as /dev/sdX, then start looking in /sys/block/sdX.
  • +
  • If applicable, make sure you identify the difference between sdX and sdX1 in the above situation. This can be done with the key KERNEL="sd?1" to match sdX1, or KERNEL="sd?" to match sdX.
  • +
  • For USB printers that are created as /dev/lpX, then you should start looking in /sys/class/usb/lpX.
  • + +
  • The usb scanner driver has recently been removed from the kernel and re-implemented in userspace (as part of the SANE package). You do not (and can not) write rules for this hardware as it does not rely on specific kernel drivers.
  • +
  • Remember that unfortunately, the kernel does not export information for all devices into sysfs, meaning that you simply can't write rules for some devices yet. On 20/02/04, the udev author stated that there are 162 drivers left to convert to sysfs.
  • +
+ + +

udev vs Nvidia's graphics drivers

+ +This section isn't really relevant to the purpose of this document, but judging from the hits I get from google, this is a hot topic. I will leave it here for now.

+ +Nvidia's graphics drivers (the closed-source ones, not the ones that come with XFree) do not work with a default installation of udev - you are unable to start X. This is because the nvidia module is loaded by X, but the /dev/nvidia* nodes are not created quick enough, so X bails out.

+ +The solution to this problem is to autoload the nvidia module on bootup. Yes - you are *supposed* to do this - the NVidia FAQ confirms this! On devfs-based systems, devfs did this automatically at bootup anyway. Your linux distribution will have created a file which you can list modules to be loaded on bootup (e.g. /etc/modules.autoload.d/kernel-2.6 for Gentoo).

+ +This isn't all - you will also need to patch the nvidia kernel interface to export some basic info to SYSFS so that udev will create the devices. Martin Schlemmer has written a patch against the 1.0.5336 version of the nvidia drivers, which can be found here. The Gentoo package nvidia-kernel-1.0.5336-r1 contains this patch.

+ +Another solution is to simply create the nvidia specific nodes on bootup. X will then load the module when required, and as the nodes are already in existance, you will not run into the problem described above. Place these commands in a file that is automatically executed on bootup (e.g. /etc/conf.d/local.start for Gentoo): +
+mknod /dev/nvidia0 c 195 0
+mknod /dev/nvidiactl c 195 255
+
+ +You should now be able to get into X with no problems.

+ + +

Author and Credits

+This document is written by Daniel Drake <dan@reactivated.net>
+Please do not hesitate to send feedback!

+ +Additional thanks to: +
    +
  • The udev developers!
  • +
  • agrippa_cash (usb-storage info)
  • +
  • Carl Streeter (usb-storage info)
  • +
  • Decibels
  • +
  • Frank Pieczynski
  • +
  • Jim (KDE info)
  • +
  • Patrick Dreker
  • +
  • Tuna
  • +
  • Ueli Schläpfer
  • +
  • ...and anyone else who provided information or feedback
  • +
+ +

Copyright (C) 2003-2004 Daniel Drake
+This document is licensed under the GNU General Public License, Version 2. + + + \ No newline at end of file From b86691919a5687c3749d8e3324dd3b8eae22a435 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 15 Apr 2004 23:14:49 -0700 Subject: [PATCH 0752/4284] [PATCH] Added expanded tests to the test framework from Leann Ogasawara --- test/udev-test.pl | 713 ++++++++++++++++++++++++++++++++++-------- test/udev.permissions | 16 + 2 files changed, 607 insertions(+), 122 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 31bc990b81..ebd3c6a8a0 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -16,7 +16,12 @@ # # happy testing, # Kay Sievers , 2003 - +# +# Modified April 9, 2004 by Leann Ogasawara +# - expanded @tests array to add more symlinks and permissions tests +# - some of the symlinks tests also test lack of node creation +# - added symlink_test() function +# - moved permissions and major_minor tests into their own functions use warnings; use strict; @@ -304,24 +309,6 @@ EOF exp_name => "my-foo8" , conf => < "program result substitution (numbered part of)", - subsys => "block", - devpath => "/block/sda/sda3", - exp_name => "link1" , - conf => < "program result substitution (numbered part of+)", - subsys => "block", - devpath => "/block/sda/sda3", - exp_name => "link3" , - conf => < "symlink creation (same directory)", - subsys => "tty", - devpath => "/class/tty/ttyUSB0", - exp_name => "visor0" , - conf => < "symlink creation (relative link back)", - subsys => "block", - devpath => "/block/sda/sda2", - exp_name => "1/2/a/b/symlink" , - conf => < "symlink creation (relative link forward)", - subsys => "block", - devpath => "/block/sda/sda2", - exp_name => "1/2/symlink" , - conf => < "symlink creation (relative link back and forward)", - subsys => "block", - devpath => "/block/sda/sda2", - exp_name => "1/2/c/d/symlink" , - conf => < "multiple symlinks", - subsys => "tty", - devpath => "/class/tty/ttyUSB0", - exp_name => "second-0" , - conf => < < "SYMLINK only rule", - subsys => "block", - devpath => "/block/sda", - exp_name => "symlink-only2", - conf => < "5000::0444", conf => < "permissions ttyUSB0:root:uucp:0660", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "0:14:0660", + conf => < "permissions tty0::root:0444", + subsys => "tty", + devpath => "/class/tty/tty0", + exp_name => "tty0", + exp_perms => "0:0:0444", + conf => < "permissions tty1:root::0555", + subsys => "tty", + devpath => "/class/tty/tty1", + exp_name => "tty1", + exp_perms => "0:0:0555", + conf => < "permissions tty2:::0777", + subsys => "tty", + devpath => "/class/tty/tty2", + exp_name => "tty2", + exp_perms => "0:0:0777", + conf => < "permissions tty3:::", + subsys => "tty", + devpath => "/class/tty/tty3", + exp_name => "tty3", + exp_perms => "0:0:0", + conf => < "permissions i2c-300:root:sys:0744", + subsys => "i2c-dev", + devpath => "/class/i2c-dev/i2c-300", + exp_name => "i2c-300", + exp_perms => "0:3:0744", + conf => < "permissions i2c-fake1:root:7:0007", + subsys => "i2c-dev", + devpath => "/class/i2c-dev/i2c-fake1", + exp_name => "i2c-fake1", + exp_perms => "0:7:0007", + conf => < "permissions ttyS[01]:0:5:0700", + subsys => "tty", + devpath => "/class/tty/ttyS1", + exp_name => "ttyS1", + exp_perms => "0:5:0700", + conf => < "permissions ttyS[4-9]:tty:5:0060", + subsys => "tty", + devpath => "/class/tty/ttyS7", + exp_name => "ttyS7", + exp_perms => "0:5:0060", + conf => < "permissions tty4:0:5:0707", + subsys => "ttyS4", + devpath => "/class/tty/tty4", + exp_name => "tty4", + exp_perms => "0:5:0707", + conf => < "permissions tty4?:0:5:0007", + subsys => "tty", + devpath => "/class/tty/tty44", + exp_name => "tty44", + exp_perms => "0:5:0007", + conf => < "permissions tty3[!3]:::0467", + subsys => "tty", + devpath => "/class/tty/tty35", + exp_name => "tty35", + exp_perms => "0:0:0467", + conf => < "permissions tty33:bad:name:0500", + subsys => "tty", + devpath => "/class/tty/tty33", + exp_name => "tty33", + exp_perms => "0:0:0500", + conf => < "permissions rtc:0:users:0600", + subsys => "misc", + devpath => "/class/misc/rtc", + exp_name => "misc/rtc", + exp_perms => "0:100:0600", + conf => < "permissions misc:0:users:0600", + subsys => "misc", + devpath => "/class/misc/psaux", + exp_name => "misc/psaux", + exp_perms => "0:100:0600", + conf => < "permissions set OWNER=5000", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "5000::0600", + conf => < "permissions set GROUP=100", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => ":100:0600", + conf => < "permissions set mode=0777", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "::0777", + conf => < "permissions set OWNER=5000 GROUP=100 MODE=0777", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "5000:100:0777", + conf => < "permissions override OWNER to 5000", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "5000:14:0660", + conf => < "permissions override GROUP to 100", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => ":100:0660", + conf => < "permissions override MODE to 0060", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => ":14:0060", + conf => < "permissions override OWNER, GROUP, MODE", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "5000:100:0777", + conf => < "4094:89999", conf => < "symlink creation (same directory)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor0", + exp_target => "ttyUSB0", + conf => < "symlink creation (relative link forward)", + subsys => "block", + devpath => "/block/sda/sda2", + exp_name => "1/2/symlink" , + exp_target => "a/b/node", + conf => < "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", + conf => < "multiple symlinks", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "second-0" , + exp_target => "visor" , + conf => < "symlink only rule", + subsys => "block", + devpath => "/block/sda", + exp_name => "symlink-only2", + exp_target => "link", + conf => < "symlink name empty", + subsys => "block", + devpath => "/block/sda", + exp_name => "", + exp_target => "link", + exp_error => "yes", + conf => < "symlink name '.'", + subsys => "block", + devpath => "/block/sda", + exp_name => ".", + exp_target => "link", + exp_error => "yes", + conf => < "symlink to empty name", + subsys => "block", + devpath => "/block/sda", + exp_name => "symlink", + exp_target => "", + exp_error => "yes", + conf => < "symlink and name empty", + subsys => "block", + devpath => "/block/sda", + exp_name => "", + exp_target => "", + exp_error => "yes", + conf => < "symlink node to itself", + subsys => "tty", + devpath => "/class/tty/tty0", + exp_name => "link", + exp_target => "link", + conf => < "symlink %n substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "symlink0", + exp_target => "ttyUSB0", + conf => < "symlink %k substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "symlink-ttyUSB0", + exp_target => "ttyUSB0", + conf => < "symlink %M:%m substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "major-188:0", + exp_target => "ttyUSB0", + conf => < "symlink %b substitution", + subsys => "block", + devpath => "/block/sda", + exp_name => "symlink-0:0:0:0", + exp_target => "node", + conf => < "symlink %c substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "test", + exp_target => "ttyUSB0", + conf => < "symlink %c{N} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "test", + exp_target => "ttyUSB0", + conf => < "symlink %c{N+} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "this", + exp_target => "ttyUSB0", + conf => < "symlink only rule with %c{N+}", + subsys => "block", + devpath => "/block/sda", + exp_name => "test", + exp_target => "link", + conf => < "symlink %s{filename} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "188:0", + exp_target => "ttyUSB0", + conf => < "symlink %Ns{filename} substitution", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "188", + exp_target => "ttyUSB0", + conf => < "symlink with '%' in name", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "percent%sign", + exp_target => "ttyUSB0", + conf => < "symlink with '%' in name", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "%ttyUSB0_name", + exp_target => "ttyUSB0", + conf => < "program result substitution (numbered part of)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "link1", + exp_target => "node", + conf => < "program result substitution (numbered part of+)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "link4", + exp_target => "node", + conf => <{exp_perms} =~ m/^(.*):(.*):(.*)$/; + if ($1 ne "") { + if ($uid != $1) { $wrong = 1; }; + } + if ($2 ne "") { + if ($gid != $2) { $wrong = 1; }; + } + if ($3 ne "") { + if (($mode & 07777) != oct($3)) { $wrong = 1; }; + } + if ($wrong == 0) { + print "permissions: ok "; + } else { + printf "expected permissions are: %i:%i:%#o\n", $1, $2, oct($3); + printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; + $error++; + } +} + +sub major_minor_test { + my($config, $rdev) = @_; + + my $major = ($rdev >> 8) & 0xfff; + my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00); + my $wrong = 0; + + $config->{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 "; + } 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 "; + $error++; + } +} + +sub symlink_test { + my ($config) = @_; + + my $output = `ls -l $PWD/$udev_root$config->{exp_name}`; + + if ($output =~ m/(.*)-> (.*)/) { + if ($2 eq $config->{exp_target}) { + print "symlink: ok "; + } else { + print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; + print "created symlink from: \'$config->{exp_name}\' to \'$2\'\n"; + if ($config->{exp_error}) { + print "as expected "; + } else { + $error++; + } + } + } else { + print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; + print "symlink: not created "; + if ($config->{exp_error}) { + print "as expected "; + } else { + $error++; + } + } +} + sub run_test { my ($config, $number) = @_; print "TEST $number: $config->{desc}\n"; - print "device \'$config->{devpath}\' expecting node \'$config->{exp_name}\'\n"; + + if ($config->{exp_target}) { + print "device \'$config->{devpath}\' expecting symlink '$config->{exp_name}' to node \'$config->{exp_target}\'\n"; + } else { + print "device \'$config->{devpath}\' expecting node \'$config->{exp_name}\'\n"; + } + udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); - if (-e "$PWD/$udev_root$config->{exp_name}") { + + if ((-e "$PWD/$udev_root$config->{exp_name}") || + (-l "$PWD/$udev_root$config->{exp_name}")) { my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$config->{exp_name}"); if (defined($config->{exp_perms})) { - my $wrong = 0; - $config->{exp_perms} =~ m/^(.*):(.*):(.*)$/; - if ($1 ne "") { - if ($uid != $1) { $wrong = 1; }; - } - if ($2 ne "") { - if ($gid != $2) { $wrong = 1; }; - } - if ($3 ne "") { - if (($mode & 07777) != oct($3)) { $wrong = 1; }; - } - if ($wrong == 0) { - print "permissions: ok "; - } else { - printf "expected permissions are: %i:%i:%#o\n", $1, $2, oct($3); - printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; - $error++; - } + permissions_test($config, $uid, $gid, $mode); } - if (defined($config->{exp_majorminor})) { - my $major = ($rdev >> 8) & 0xfff; - my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00); - - my $wrong = 0; - $config->{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 "; - } else { - printf "expected major:minor is: %i:%i\n", $1, $2; - printf "created major:minor is : %i:%i\n", $major, $minor; - $error++; - } + major_minor_test($config, $rdev); + } + if (defined($config->{exp_target})) { + symlink_test($config); } - print "add: ok "; } else { - print "add: error\n"; - system("tree $udev_root"); - print "\n"; - $error++; + print "add: error "; + if ($config->{exp_error}) { + print "as expected "; + } else { + print "\n\n"; + system("tree $udev_root"); + print "\n"; + $error++; + } } udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf}); if ((-e "$PWD/$udev_root$config->{exp_name}") || (-l "$PWD/$udev_root$config->{exp_name}")) { - print "remove: error\n\n"; - system("tree $udev_root"); - $error++; + print "remove: error "; + if ($config->{exp_error}) { + print "as expected\n\n"; + } else { + print "\n\n"; + system("tree $udev_root"); + print "\n"; + $error++; + } } else { print "remove: ok\n\n"; } diff --git a/test/udev.permissions b/test/udev.permissions index 44ef3d43e5..b7baeea7b4 100644 --- a/test/udev.permissions +++ b/test/udev.permissions @@ -4,3 +4,19 @@ ttyUSB1:root:uucp:0666 visor:500:500:0666 dsp1:::0666 boot_disk?:::0666 + +#used for permissions tests in udev-test.pl +tty0::root:0444 +tty1:root::0555 +tty2:::0777 +tty3::: +rtc:0:6:0770 +misc/*:0:users:0600 +i2c-fake1:root:7:0007 +i2c*:root:sys:0744 +ttyS[01]:0:5:0700 +ttyS[5-9]:root:5:0060 +tty4::tty:0707 +tty4?::tty:0007 +tty3[!3]:::0467 +tty33:bad:name:0500 From 1352a36fbe768904cc76c44c81a8522a15782548 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 16 Apr 2004 19:34:01 -0700 Subject: [PATCH 0753/4284] [PATCH] Fix build process for users who have LC_ALL set to a non-english language. Many thanks to jack_mort for helping track this down. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 85620779ac..dd7de95dc3 100644 --- a/Makefile +++ b/Makefile @@ -92,7 +92,7 @@ ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sp -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/powerpc/ppc/g'} # code taken from uClibc to determine the gcc include dir -GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} +GCCINCDIR := ${shell LC_ALL=C $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} # code taken from uClibc to determine the libgcc.a filename GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) From af5b5178fa9cb8b75d00fb364f266c3919f12cd2 Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Fri, 16 Apr 2004 23:58:02 -0700 Subject: [PATCH 0754/4284] [PATCH] devfs.sh-ide-floppy --- extras/ide-devfs.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 22d09d7a5a..4d021c5e87 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -39,6 +39,8 @@ if [ -z "$3" -a -f /proc/ide/${1}/media ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` + elif [ "${MEDIA}" = "floppy" ]; then + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc floppies/floppy`get_dev_number $1 floppy`/disc elif [ "${MEDIA}" = "disk" ]; then echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc fi From 7d855c3116ec9ddab9adde96b568681930d9855b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 16 Apr 2004 23:58:05 -0700 Subject: [PATCH 0755/4284] [PATCH] udevd test script Thanks to Yin, Hu , who made a nice perl script to test the expected behavior of the udevd sequence number handling. The test sends different SEQNUM sequences to udevd, while analyzing the reordering and timeout handling of udevd. --- test/udevd-test/udev-log-amplify.pl | 87 ++++ test/udevd-test/udev-log-script.pl | 82 ++++ test/udevd-test/udevd-test.pl | 669 ++++++++++++++++++++++++++++ udevd.c | 10 +- 4 files changed, 847 insertions(+), 1 deletion(-) create mode 100644 test/udevd-test/udev-log-amplify.pl create mode 100644 test/udevd-test/udev-log-script.pl create mode 100644 test/udevd-test/udevd-test.pl diff --git a/test/udevd-test/udev-log-amplify.pl b/test/udevd-test/udev-log-amplify.pl new file mode 100644 index 0000000000..c2d4723974 --- /dev/null +++ b/test/udevd-test/udev-log-amplify.pl @@ -0,0 +1,87 @@ +#!/usr/bin/perl -w +# +# udev-log-amplify +# +# Copyright (C) Intel Corp, 2004 +# +# Author: Yin Hu +# +# This is a script for replacing udev binary during udevsend/udevd testing. +# It first amplifies the execution time ( sleep 5 ) and then logs the event +# information sent by udved in order that test script udevd-test.pl can +# analyze whether udved execute as we expected. +# You should not execute this script directly because it will be invoked by +# udevd automatically. +# +# Before you run your test please modify $log_file to designate where the udev +# log file should be placed, in fact, the default value is ok. +# +# +# 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. +# + +use warnings; +use strict; + +# modifiable settings +my $udev_exe_time = 5; +my $log_file = "/tmp/udev_log.txt"; + +# global variables +my $devpath; +my $action; +my $subsystem; + +# common functions +sub getDate { + # Get current date/time + # If we want GTM time, simply pass GMT as first argument to this function. + + my $format = @_; + my $date; + + if( $format =~ /GMT/i ) { + $date = gmtime() . " GMT"; + } else { + $date = localtime(); + } + return $date; +} + +# main program +if ($ARGV[0]) { + $subsystem = $ARGV[0]; + $devpath = $ENV{DEVPATH}; + $action = $ENV{ACTION}; + + # Get current system date + my $time = getDate(); + + # Logging + if (open(LOGF, ">>$log_file")) { + print LOGF "$devpath,$action,$subsystem,$time\n"; + } else { + print "File open failed. \n"; + exit 1; + } + close(LOGF); + + # Amplify the execution time of udev + sleep 5; + + exit 0; +} else { + print "Too less argument count.\n"; + exit 1; +} diff --git a/test/udevd-test/udev-log-script.pl b/test/udevd-test/udev-log-script.pl new file mode 100644 index 0000000000..5f4f8a4495 --- /dev/null +++ b/test/udevd-test/udev-log-script.pl @@ -0,0 +1,82 @@ +#!/usr/bin/perl -w +# +# udev-log-script +# +# Copyright (C) Intel Corp, 2004 +# +# Author: Yin Hu +# +# This is a script for replacing udev binary during udevsend/udevd testing. +# It just simply logs the event information sent by udved in order to +# test script udevd-test.pl can analyze whether udved execute as we expected. +# You should not execute this script directly because it will be invoked by +# udevd automatically. +# +# Before you run your test please modify $log_file to designate where the udev +# log file should be placed, in fact, the default value is ok. +# +# +# 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. +# + +use warnings; +use strict; + +# modifiable settings +my $log_file = "/tmp/udev_log.txt"; + +# global variables +my $devpath; +my $action; +my $subsystem; + +# common functions +sub getDate { + # Get current date/time + # If we want GTM time, simply pass GMT as first argument to this function. + my $format = @_; + my $date; + + if( $format =~ /GMT/i ) { + $date = gmtime() . " GMT"; + } else { + $date = localtime(); + } + return $date; +} + +# main program +if ($ARGV[0]) { + # prepare + $subsystem = $ARGV[0]; + $devpath = $ENV{DEVPATH}; + $action = $ENV{ACTION}; + + # Get current system date + my $time = getDate(); + + # Logging + if (open(LOGF, ">>$log_file")) { + print LOGF "$devpath,$action,$subsystem,$time\n"; + } else { + print "File open failed. \n"; + exit 1; + } + close(LOGF); + + exit 0; +} else { + print "Too less argument count.\n"; + exit 1; +} diff --git a/test/udevd-test/udevd-test.pl b/test/udevd-test/udevd-test.pl new file mode 100644 index 0000000000..060c3ec5f2 --- /dev/null +++ b/test/udevd-test/udevd-test.pl @@ -0,0 +1,669 @@ +#!/usr/bin/perl -w +# +# udevd-test +# +# Copyright (C) Intel Corp, 2004 +# +# Author: Yin Hu +# Kay Sievers +# +# Provides automated testing of the udevd binary.This test script is self-contained. +# Before you run this script please modify $sysfs to locate your sysfs filesystem, +# modify $udevd_bin to locate your udevsend binary, +# modify $udev_bin to locate dummy udev script, +# modify $udev_bin2 to locate another dummy udev script ( amplify the execution time for test), +# modify $log_file to locate where udev script have placed the log file, +# modify $time_out to decide the time out for events, +# modify $udev_exe_time to decide the execution time for dummy udev script. +# +# Detail information of each test case please refer to the header of corresponding +# test case function. +# +# +# 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. +# + +use warnings; +use strict; + +# modifiable settings +my $sysfs = "../sys"; +my $udevd_bin = "../../udevsend"; +my $udev_bin = "$ENV{PWD}/udev-log-script.pl"; +my $udev_bin2 = "$ENV{PWD}/udev-log-amplify.pl"; +my $log_file = "/tmp/udev_log.txt"; +my $time_out = 10; +my $udev_exe_time = 5; + +# global variables +my $test_case = 0; + +# common functions + +sub kill_daemon { + system("killall udevd"); + system("rm -f $log_file"); + sleep 1; +} + +sub udevsend { + # This function prepares corresponding environment variables + # and then call $udevd_bin to send event. + + my ($seqnum, $devpath, $action, $subsystem, $udev_bin_tmp) = @_; + + $ENV{DEVPATH} = $devpath; + $ENV{ACTION} = $action; + $udev_bin_tmp = $udev_bin if ( not $udev_bin_tmp ); + $ENV{UDEV_BIN} = $udev_bin_tmp; + if ( $seqnum != -1) { + $ENV{SEQNUM} = $seqnum; + } else { + delete $ENV{SEQNUM}; + } + + return system("$udevd_bin $subsystem"); +} + +sub getDate { + # Get current date function + # If we want GTM time, simply pass GMT as first argument to this function. + + my $format = @_; + my $date; + + if( $format =~ /GMT/i ) { + $date = gmtime() . " GMT"; + } else { + $date = localtime(); + } + + return $date; +} + +sub cmpDate { + # This function should return a difference betweent date1 and date2 + + my ($date1, $date2) = @_; + my @monList = ( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", + "Aug", "Sep", "Oct", "Nov", "Dec" ); + my ( $m1, $m2, $tmp ); + + $date1 =~ s/([\D]*)$//g; + $date2 =~ s/([\D]*)$//g; + + return if( (not $date1) or (not $date2) ); + + my $mon = 0; + + my ( @T1 ) = + ( $date1 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g ); + my ( @T2 ) = + ( $date2 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g ); + + foreach $tmp (@monList) { + $m1 = sprintf("%2.2d",$mon) if( $date1 =~ /$tmp/i ); + $m2 = sprintf("%2.2d",$mon) if( $date2 =~ /$tmp/i ); + $mon++; + } + + my $dt1 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T1[4], $m1, $T1[0], + $T1[1], $T1[2], $T1[3]); + my $dt2 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T2[4], $m2, $T2[0], + $T2[1], $T2[2], $T2[3]); + + my $ret = $dt1 - $dt2; + + if ( $ret > 40 ) { + $ret = abs($ret-40); + } + + return $ret; +} + +sub check_count_and_time { + my $event_recv_time; + my $udev_fork_time; + my $log_ln_count = 0; + my $line; + my @content; + my @line_items; + my $diff; + + ($event_recv_time) = @_; + + print " event receiving time: $event_recv_time\n\n"; + + open(LOGF, $log_file) || die "Opening file $log_file: $!"; + @content = ; + foreach $line ( @content ) { + @line_items = split(/,/,$line); + print " device: $line_items[0], action: $line_items[1] \n"; + print " forking udev time: $line_items[-1]"; + $diff = cmpDate($line_items[-1], $event_recv_time); + print " the delay time is: $diff s \n\n"; + if ( $diff > $time_out ) { + print " the delay time is: $diff \n"; + print " udevd doesn't act properly. \n"; + exit 1; + } + $log_ln_count++; + } + close(LOGF); + + return $log_ln_count; +} + +sub check_sysfs_device_exist { + # check if the designated devices exist + my @dev_list = @_; + my $dev; + + foreach $dev (@dev_list) { + if (! -e $dev) { + print "the designated device $dev doesn't exist. please change a device!\n"; + exit 1; + } + } +} + +sub show_result { + my $event_recv_time; + my $udev_fork_time; + my $line; + my @content; + my @line_items; + my $diff; + + ($event_recv_time) = @_; + + print " event receiving time: $event_recv_time\n\n"; + + open(LOGF, $log_file) || die "Opening file $log_file: $!"; + @content = ; + foreach $line ( @content ) { + @line_items = split(/,/,$line); + print " device: $line_items[0], action: $line_items[1] \n"; + print " forking udev time: $line_items[-1]"; + $diff = cmpDate($line_items[-1], $event_recv_time); + print " the delay time is: $diff s \n\n"; + } + close(LOGF); +} + +sub show_result_tm_out { + my $event_recv_time; + my $udev_fork_time; + my $line; + my @content; + my @line_items; + my $diff; + + ($event_recv_time) = @_; + + print " event receiving time: $event_recv_time\n\n"; + + open(LOGF, $log_file) || die "Opening file $log_file: $!"; + @content = ; + foreach $line ( @content ) { + @line_items = split(/,/,$line); + print " device: $line_items[0], action: $line_items[1] \n"; + print " forking udev time: $line_items[-1]"; + $diff = cmpDate($line_items[-1], $event_recv_time); + print " the delay time is: $diff s \n\n"; + if ( $diff < $time_out ) { + print " the delay time is: $diff \n"; + print " udevd doesn't act properly. \n"; + exit 1; + } + } + close(LOGF); +} + +sub show_result_immediate { + my $event_recv_time; + my $udev_fork_time; + my $line; + my @content; + my @line_items; + my $diff; + + ($event_recv_time) = @_; + + print " event receiving time: $event_recv_time\n\n"; + + open(LOGF, $log_file) || die "Opening file $log_file: $!"; + @content = ; + foreach $line ( @content ) { + @line_items = split(/,/,$line); + print " device: $line_items[0], action: $line_items[1] \n"; + print " forking udev time: $line_items[-1]"; + $diff = cmpDate($line_items[-1], $event_recv_time); + print " the delay time is: $diff s \n\n"; + if ( $diff > $time_out ) { + print " the delay time is: $diff \n"; + print " udevd doesn't act properly. \n"; + exit 1; + } + } + close(LOGF); +} + +sub check_exe_time { + my @exe_time; + my $i = 0; + my $line; + my @content; + my @line_items; + my $diff; + + open(LOGF, $log_file) || die "Opening file $log_file: $!"; + @content = ; + close(LOGF); + foreach $line ( @content ) { + @line_items = split(/,/,$line); + $exe_time[$i] = $line_items[-1]; + $i++; + } + $diff = cmpDate($exe_time[1], $exe_time[0]); + if ( $diff < $udev_exe_time ) { + print " there are more than one udev instance for a single device at the same time. \n"; + exit 1; + } else { + print " there is just one udev instance for a single device at the same time. \n"; + } +} + +# test case functions +sub run_no_seq_test { + print "Test case name: no sequence number test\n"; + print "Test case purpose: check whether udevd forks udev immediately when environment variable SEQNUM is null.\n"; + print "Test expected visible results: \n"; + print " the delay time between event receiving and forking udev for udevd should be negligible, \n"; + print " that is, udev should be forked at once. please notice the following time...\n\n"; + + # local variables + my $time; + + # + # add devices event test + # + kill_daemon(); + + # check if devices /block/sda exist + check_sysfs_device_exist("$sysfs/block/sda"); + + # log current system date/time + $time = getDate(); + + # fork udevd + udevsend(-1, "/block/sda", "add", "block"); + + # check if execution is successful in time + sleep 1; + show_result_immediate($time); + print " fork udev (add device) at once successfully.\n\n"; + + # + # remove devices event test + # + system("rm -f $log_file"); + + # log current system date/time + $time = getDate(); + + # fork udevd + udevsend(-1, "/block/sda", "remove", "block"); + + # check if execution is successful in time + sleep 1; + show_result_immediate($time); + print " fork udev (remove device) at once successfully.\n\n"; + print "this case is ok\n\n"; +} + +sub run_normal_seq_test { + print "Test case name: normal sequence number stress test\n"; + print "Test case purpose: check whether udevd can fork massive udev instances for \n"; + print " massive sequential events successfully. \n"; + print "Test expected visible results: \n"; + print " Populate all the devices in directory $sysfs/class/tty, fork udved to send add/remove \n"; + print " event to udev for each device. \n"; + print " We can see the delay time for each device should be negligible. \n\n"; + + # local variables + my @file_list; + my $file; + my $seq = 0; + my $time; + my $ret_seq; + + # prepare + kill_daemon(); + @file_list = glob "$sysfs/class/tty/*"; + + # log current system date/time for device add events + $time = getDate(); + + # + # add devices event test + # + print "add device events test: \n"; + foreach $file (@file_list) { + udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "add", "tty"); + # check if execution is successful + if ($? == 0) { + $seq++; + } else { + print "add event: error\n\n"; + exit 1; + } + } + + # we'd better wait the udev to create all the device for a few seconds + print " wait for udevd processing about $time_out s... \n\n"; + sleep $time_out; + + $ret_seq = check_count_and_time($time); + if ( $ret_seq != $seq ) { + print " add event: failed. some device-adding events fail to execute.\n\n"; + exit 1; + } else { + print " $seq pieces of device-adding events have executed successfully.\n\n"; + } + + # log current system date/time for device remove events + $time = getDate(); + + # + # remove devices event test + # + print "remove device events test: \n"; + kill_daemon(); + @file_list = glob "$sysfs/class/tty/*"; + $seq = 0; + foreach $file (@file_list) { + udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "remove", "tty"); + # check if execution is successful + if ($? == 0) { + $seq++; + } else { + print "remove event: error\n\n"; + exit 1; + } + } + + # we'd better wait the udev to create all the device for a few seconds + print " waiting for udev removing devices (about $time_out s)...\n"; + sleep $time_out; + + # show results + $ret_seq = check_count_and_time($time); + if ( $ret_seq != $seq ) { + print " remove event: failed. some device-removing events fail to execute.\n\n"; + exit 1; + } else { + print " $seq pieces of device-removing events have executed successfully.\n\n"; + print "this case is ok.\n\n"; + } +} + +sub run_random_seq_test { + print "Test case name: random sequence number test case,\n"; + print "Test case purpose: check whether udevd can order the events with random sequence number \n"; + print " and fork udev correctly. \n"; + print "Test expected visible results: \n"; + print " We have disordered the events sent to udevd, if udevd can order them correctly, the devices' \n"; + print " add/remove sequence should be tty0, tty1, tty2. \n\n"; + + # local variables + my $time; + + # check if devices /class/tty/tty0, tty1, tty2 exist + check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2"); + + # + # add device events test + # + print "add device events test: \n"; + kill_daemon(); + + # log current system date/time for device remove events + $time = getDate(); + + # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem + udevsend(3, "/class/tty/tty2", "add", "tty"); + udevsend(1, "/class/tty/tty0", "add", "tty"); + udevsend(2, "/class/tty/tty1", "add", "tty"); + print " wait for udevd processing about $time_out s... \n\n"; + sleep $time_out+1; + show_result_tm_out($time); + + # + # remove device events test + # + print "\nremove device events test: \n"; + kill_daemon(); + + # log current system date/time for device remove events + $time = getDate(); + + # fork udevd + udevsend(3, "/class/tty/tty2", "remove", "tty"); + udevsend(2, "/class/tty/tty1", "remove", "tty"); + udevsend(1, "/class/tty/tty0", "remove", "tty"); + + # show results + print " wait for udevd processing about $time_out s... \n\n"; + sleep $time_out+1; + show_result_tm_out($time); + print "this case is ok.\n\n"; +} + +sub run_expected_seq_test { + print "Test case name: expected sequence number test \n"; + print "Test case purpose: check whether udevd fork udev immediately when the incoming event\n"; + print " is exactly the expected event sequence number.\n"; + print "Test expected visible results:\n"; + print " first, udevd disposes disorder events(sequence number is 3,1,2,5,4,6),\n"; + print " thus after disposed the expected event number for udevd is 7, when incoming event is 7, udevd\n"; + print " should fork udev immediately, the delay time should be negligible. \n"; + print " where: event 7 is (add device /class/tty/tty2) \n\n"; + + # local variables + my $time; + + # check if devices /class/tty0, tty1, tty2 exist + check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2"); + + # prepare + kill_daemon(); + + # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem + udevsend(3, "/class/tty/tty2", "add", "tty"); + udevsend(1, "/class/tty/tty0", "add", "tty"); + udevsend(2, "/class/tty/tty1", "add", "tty"); + udevsend(5, "/class/tty/tty1", "remove", "tty"); + udevsend(4, "/class/tty/tty0", "remove", "tty"); + udevsend(6, "/class/tty/tty2", "remove", "tty"); + + print " wait for udevd timing out for disorder events (about $time_out s) \n\n"; + sleep $time_out+1; + system("rm -f $log_file"); + + # log current system date/time for device remove events + $time = getDate(); + + # show results + udevsend(7, "/class/tty/tty2", "add", "tty"); + sleep 1; + print " event sequence number: 7 \n"; + show_result_immediate($time); + + print "this case is ok.\n\n"; +} + +sub run_single_instance_test { + print "Test case name: single instance running for a single device test \n"; + print "Test case purpose: check whether udevd only fork one udev instance for a single\n"; + print " device at the same time. For each event a udev instance is \n"; + print " executed in the background. All further events for the same \n"; + print " device are delayed until the execution is finished. This way \n"; + print " there will never be more than one instance running for a single \n"; + print " device at the same time.\n"; + print "Test expected visible results:\n"; + print " In this test we amplify the execution time of udev (about 5 seconds), first, \n"; + print " we send a add event for device /block/sda, and then we send a remove event, so the \n"; + print " execution of remove event should be delayed until add is finished. \n\n"; + + # local variables + my $time; + + # prepare + kill_daemon(); + + # check if device exists + check_sysfs_device_exist("$sysfs/block/sda"); + + # log current system date/time + $time = getDate(); + + # fork udved + udevsend(-1, "/block/sda", "add", "block", $udev_bin2); + udevsend(-1, "/block/sda", "remove", "block", $udev_bin2); + + # show results + print " wait for udevd processing about $udev_exe_time s... \n\n"; + sleep $udev_exe_time+1; + show_result_immediate($time); + check_exe_time(); + print "this case is ok\n\n"; +} + +sub run_same_events_test { + print "Test case name: event sequence number overlap test \n"; + print "Test case purpose: check whether udevd doesn't fork udev untill time out\n"; + print " when encountering a event with sequence number same as the pevious event. \n"; + print "Test expected visible results:\n"; + print " event ( remove device /block/sda ) should be no delay, \n"; + print " event ( add device /class/tty/tty1 ) should be delayed for $time_out s than its previous \n"; + print " event ( remove device /block/sda ) \n\n"; + + # local variables + my $time; + + # prepare + kill_daemon(); + + # check if device exist + check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1"); + + # fork udevd + udevsend(0, "/block/sda", "add", "block"); + + # log current system date/time + sleep 1; + $time = getDate(); + system("rm -f $log_file"); + + # fork udevd + udevsend(1, "/block/sda", "remove", "block"); + udevsend(1, "/class/tty/tty1", "add", "tty"); + + # show results + print " wait for udevd processing about $time_out s... \n\n"; + sleep $time_out+1; + show_result($time); + print "this case is ok\n\n"; +} + +sub run_missing_seq_test { + print "Test case name: missing sequence number test \n"; + print "Test case purpose: check whether udevd doesn't fork udev untill time out\n"; + print " when certain event sequence number is missing.\n"; + print "Test expected visible results:\n"; + print " the delay time for event(add device /block/sda) should be about $time_out s.\n\n"; + + # local variables + my $time; + + # prepare + kill_daemon(); + + # check if device exist + check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1"); + + # fork udevd + udevsend(0, "/class/tty/tty1", "add", "tty"); + udevsend(1, "/class/tty/tty1", "remove", "tty"); + sleep 1; + + # log current system date/time + $time = getDate(); + system("rm -f $log_file"); + + # fork udevd + udevsend(3, "/block/sda", "add", "block"); + + # show results + print " wait for udevd processing about $time_out s... \n\n"; + sleep $time_out+1; + show_result($time); + print "this case is ok\n\n"; +} + +sub run_all_cases_test { + run_no_seq_test(); + run_normal_seq_test(); + run_random_seq_test(); + run_missing_seq_test(); + run_expected_seq_test(); + run_same_events_test(); + run_single_instance_test(); +} + +# main program +if ($ARGV[0]) { + $test_case = $ARGV[0]; + + if ($test_case == 1) { + run_no_seq_test(); + } elsif ($test_case == 2) { + run_normal_seq_test(); + } elsif ($test_case == 3) { + run_random_seq_test(); + } elsif ($test_case == 4) { + run_missing_seq_test(); + } elsif ($test_case == 5) { + run_expected_seq_test(); + } elsif ($test_case == 6) { + run_single_instance_test(); + } elsif ($test_case == 7) { + run_same_events_test(); + } else { + run_all_cases_test(); + } +} else { + # echo usage + print "command format: perl udevd-test.pl \n"; + print " test case:\n"; + print " 1: no event sequence number\n"; + print " 2: sequential event sequence number\n"; + print " 3: random event sequence number\n"; + print " 4: missing event sequence number\n"; + print " 5: the incoming event sequence number is right the expected sequence number\n"; + print " 6: single udev instance on a single device at the same time\n"; + print " 7: test event sequence number overlap\n"; + print " 9: all the cases\n\n"; +} diff --git a/udevd.c b/udevd.c index b2cb62f386..d807e4168d 100644 --- a/udevd.c +++ b/udevd.c @@ -60,6 +60,7 @@ static void exec_queue_manager(void); static void msg_queue_manager(void); static void user_sighandler(void); static void reap_kids(void); +char *udev_bin; #ifdef LOG unsigned char logname[LOGNAME_SIZE]; @@ -146,7 +147,7 @@ static void udev_run(struct hotplug_msg *msg) switch (pid) { case 0: /* child */ - execle(UDEV_BIN, "udev", msg->subsystem, NULL, env); + execle(udev_bin, "udev", msg->subsystem, NULL, env); dbg("exec of child failed"); exit(1); break; @@ -458,6 +459,13 @@ int main(int argc, char *argv[]) /* enable receiving of the sender credentials */ setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + /* possible override of udev binary, used for testing */ + udev_bin = getenv("UDEV_BIN"); + if (udev_bin != NULL) + dbg("udev binary is set to '%s'", udev_bin); + else + udev_bin = UDEV_BIN; + FD_ZERO(&readfds); FD_SET(ssock, &readfds); FD_SET(pipefds[0], &readfds); From f2bd44417bf2c6c99037b430f3f97cfd65a21f76 Mon Sep 17 00:00:00 2001 From: "dan@reactivated.net" Date: Fri, 16 Apr 2004 23:58:08 -0700 Subject: [PATCH 0756/4284] [PATCH] Update writing udev rules docs Here's an update for the writing udev rules document. - Minor corrections/clarifications - Added info about using NAME{all_partitions} - Added more info about udevinfo, simplifying the rule-writing process You can ignore the diff I sent you yesterday - according to the 20040415 bk snapshot on codemonkey.org, you haven't applied it yet. This patch incorporates that update, and some other changes I just made. --- docs/writing_udev_rules/index.html | 69 ++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 23 deletions(-) diff --git a/docs/writing_udev_rules/index.html b/docs/writing_udev_rules/index.html index 0e4d54cfaf..1a2702aeaf 100644 --- a/docs/writing_udev_rules/index.html +++ b/docs/writing_udev_rules/index.html @@ -1,6 +1,6 @@ -Writing udev rules [reactivated.net] +Writing udev rules @@ -8,7 +8,7 @@

Writing udev rules

by Daniel Drake (dsd)
-Version 0.51

+Version 0.53

The most recent version of this document can always be found at:
http://www.reactivated.net/udevrules.php @@ -23,7 +23,7 @@ The most recent version of this document can always be found at:
  • Why? (The purpose of this document)
  • The basics of writing rules
  • Additional automated customisation for NAME and SYMLINK parameters
  • -
  • Using regular expressions and wildcards in keys
  • +
  • Using shell-style pattern matching in keys
  • Key-writing basics
  • Identifying devices through basic keys
  • Identifying devices through SYSFS files
  • @@ -51,8 +51,9 @@ This document assumes that you have udev/hotplug installed and running OK with d

    History

    +April 15th 2004: Minor corrections. Added info about NAME{all_partitions}. Added info about other udevinfo tricks.

    +April 14th 2004: Reverted to suggesting using "udev.rules" until the udev defaults allow for other files. Minor work.

    April 6th 2004: I now write suggest users to use their own "local.rules" file rather than prepending "udev.rules".

    - April 3rd 2004: Minor cleanups and preparations for possible inclusion in the udev distribution.

    February 15th 2004: Initial publication.

    February 18th 2004: Fixed a small omission in an example. Updated section on identifying mass-storage devices. Updated section on nvidia.

    @@ -96,11 +97,13 @@ For external mass-storage devices (e.g. usb hard disks), persistant naming is ve

    The basics of writing rules

    -When populating /dev, udev decides which nodes to include, and how to name them, by reading a rules file. The default rules file includes some examples, and defaults to giving a devfs-style layout. The examples may safely be removed, but it is generally sensible to keep the devfs rules and simply make your own amendments and modifications.

    +When populating /dev, udev decides which nodes to include, and how to name them, by reading a rules file. This rules file is processed from top to bottom, and udev will stop processing rules for a device once it finds one that matches.

    -Default udev rules are stored in /etc/udev/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, to reduce hassle while updating your udev installation in the future.

    +Default udev rules are stored in /etc/udev/udev.rules. The default file includes some examples, and defaults to giving a devfs-style layout. The examples may safely be removed, but it is generally sensible to keep the devfs rules and simply make your own amendments and modifications. You should write your rules in this file, above the examples and default devfs-style rules.

    -Files in /etc/udev are parsed in lexical order. udev will stop processing rules as soon as it finds a matching rule in a file for the new item of hardware that has been detected. It is important that your own rules get processed before the udev defaults, otherwise your own naming schemes will not take effect! I suggest that you keep your own rules in a file at /etc/udev/local.rules (this doesn't exist by default - create it). As L comes before U, you know that your rules will be looked at first.

    + As your own rules will effectively mask out the udev defaults which create the base /dev layout, it is recommended that you also specify devfs-style names/symlinks for the rules you write, so that you get the sensible defaults plus your own names.

    @@ -141,9 +144,9 @@ Another common operator is %k. This represents what the kernel would name A full list of operators, with explanations, can be found in the udev man page.

    -

    Using regular expressions and wildcards in keys

    +

    Using shell-style pattern matching in keys

    -You can use wildcards and basic regular-expression style matching to provide even more flexibility when writing keys. Taking a default udev rule: +You can use shell style pattern matching to provide even more flexibility when writing keys. Taking a default udev rule:
    KERNEL="ts*", NAME="input/%k"
    @@ -164,7 +167,7 @@ This rule says:
    Match a device identified by a KERNEL name starting with the letters "fd", followed by any single digit, optionally followed by anything at all. Name the device with the kernel number of the device (%n) under the floppy directory.
    -You can use these wildcards/regular-expression matches in any type of key, including both basic keys and sysfs-based identification (see below for explanations of these key types).

    +You can use these wildcards/pattern matches in any type of key, including both basic keys and sysfs-based identification (see below for explanations of these key types).

    I have purposely left out some information on this topic (particularly the flexibility of using [ ] operators) that is out of the scope of basic rule-writing documentation. More information on this topic can be found in the udev man page.

    @@ -209,7 +212,18 @@ The first thing you need to do is find a directory somewhere in /sys that corres Once you have found a directory of this type, you can use the following command to assist you in the creation of writing keys for udev rules:
    # udevinfo -a -p /sys/path/to/hardware/info
    -Some snipped output of the results of my "udevinfo -a -p /sys/block/sda" command is shown below, with colour added.
    +You may find that finding the correct place in /sys to run udevinfo on is not obvious. Chances are the device you just plugged in has already careted a device node (e.g. /dev/sda), in which case, udevinfo can be helpful! Taking the example of my /dev/sda node, running the following command will point you to the appropriate area of sysfs: +
    +# udevinfo -q path -n /dev/sda
    +
    +/block/sda
    +
    + +The output of the command (shown above) is telling me that the sysfs path to start at is /sys/block/sda. I would now run "udevinfo -a -p /sys/block/sda". These two commands can be stringed together, like so: + +
    # udevinfo -a -p `udevinfo -q path -n /dev/sda`
    + +Moving on to rule-writing, some snipped output of the results of my "udevinfo -a -p /sys/block/sda" command is shown below, with colour added.
    
     follow the class device's "device"
    @@ -262,14 +276,10 @@ I will show three examples of this rule writing based on udevinfo output
     
     

    Example: Writing a rule for my USB printer

    -After plugging in my printer, I started looking around some /sys directories for a relevant place to start. I didn't get anywhere, but I noticed that my printer had been given device node /dev/lp0. I used this command sequence to find an answer: +After plugging in my printer, I started looking around some /sys directories for a relevant place to start. I didn't get anywhere, but I noticed that my printer had been given device node /dev/lp0. udevinfo was able to provide me with a useful path:
    -# cd /sys
    -# find | grep lp0
    -./class/usb/lp0
    -./class/usb/lp0/dev
    -./class/usb/lp0/driver
    -./class/usb/lp0/device
    +# udevinfo -q path -n /dev/lp0
    +/class/usb/lp0
     
    Running "udevinfo -a -p /sys/class/usb/lp0" provided me with a heap of info, as usual. I picked out the relevant bits for unique device identification: @@ -326,14 +336,23 @@ Carl's rule is: This rule creates symlinks such as:
      -
    • /dev/usbhdd - The fdiskable node
    • -
    • /dev/usbhdd1 - The first partition (mountable)
    • -
    • /dev/usbhdd2 - The second partition (mountable)
    • +
    • /dev/usbhd - The fdiskable node
    • +
    • /dev/usbhd1 - The first partition (mountable)
    • +
    • /dev/usbhd2 - The second partition (mountable)
    We agreed that depending on the situation and device in question, there are reasons for both wanting and not wanting the non-mountable /dev/sda node. Use whichever setup suits you best.

    +Another difficult situation is having a multiple-slot USB-storage card reader. These types of device generally do not inform the host when new cards are plugged in or out, so plugging a card into an unused slot while the reader is plugged in will not create the extra device node needed for mounting!
    +This problem also applies to other USB disks - e.g. if you create a new partition, the new partition node will not appear until you re-plug the device.

    + +udev provides a solution here - it is able to create nodes for all partitions of a block device. For every rule that you specify, the block device will have all 16 partition nodes created. To achieve this, you can simply modify the NAME key, as shown below:
    + +
    BUS="usb", SYSFS{product}="USB 2.0 Storage Device", NAME{all_partitions}="usbhd%n"
    + +You will now have nodes named: usbhd, usbhd1, usbhd2, usbhd3, ..., usbhd15.

    +

    Example: Writing convenience rules for my CD drives

    I have two CD drives in my PC - a DVD reader, and a CD rewriter. My DVD is hdc and my CDRW is hdd. I would not expect this to change, unless I manually changed the cabling of my system.

    @@ -346,13 +365,14 @@ BUS="ide", KERNEL="hdc", NAME="%k", SYMLINK="dvd cdroms/cdrom%n" BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n"
    -You may have noticed that the default udev.rules file contains a rule which runs a script to produces names for block devices. Do not be confused by this - as usual, because your own rules in local.rules are processed before the default rules, the default rules will not be used when naming the hardware you have written rules for.

    +You may have noticed that the default udev.rules file contains a rule which runs a script to produces names for block devices. Do not be confused by this - as usual, because your own rules are located at the top of the rules file, they are processed before the default rules, so the default rules will not be used when naming the hardware you have written rules for.

    Tips for finding the appropriate places in SYSFS

    I'm looking for some more device specific tips here. Please contact me with any you can provide.
      +
    • If the device you are looking to write rules for has created a device node under /dev, then you are in luck! Run the following command to get an appropriate /sys path: udevinfo -q path -n /dev/yournode
    • Always use udevinfo to assist the rule-writing process. Always use udevinfo to look under /sys/block or /sys/class (it will not start reading a chain from anywhere else).
    • If you get totally stuck, use the following command to find all "dev" files under /sys (udevinfo can work on directories containing this file): find /sys -iname dev
    • If your device is a flash-card reader, usb flash-drive, or digital camera that acts as usb-storage, that is created as /dev/sdX, then start looking in /sys/block/sdX.
    • @@ -394,8 +414,11 @@ Additional thanks to:
    • Carl Streeter (usb-storage info)
    • Decibels
    • Frank Pieczynski
    • +
    • Feth Arezki
    • Jim (KDE info)
    • +
    • Kay Sievers
    • Patrick Dreker
    • +
    • Todd Musall
    • Tuna
    • Ueli Schläpfer
    • ...and anyone else who provided information or feedback
    • @@ -405,4 +428,4 @@ Additional thanks to: This document is licensed under the GNU General Public License, Version 2. - \ No newline at end of file + From b2983b9d4a05b44c9230e17a3d6737d185d1c749 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 16 Apr 2004 23:58:27 -0700 Subject: [PATCH 0757/4284] [PATCH] udev_selinux changes Here is the fix for extras/seliux/* o install the binary in /sbin/ o add symlink to /etc/dev.d/ with suffix .dev o removed the undefined udev_log variable o fixed compiler warnings --- extras/dbus/Makefile | 12 ++++++------ extras/selinux/Makefile | 9 +++++++-- extras/selinux/udev_selinux.c | 31 ++++++++++++++++++++++--------- 3 files changed, 35 insertions(+), 17 deletions(-) diff --git a/extras/dbus/Makefile b/extras/dbus/Makefile index 04f17605e8..0cfc650c4b 100644 --- a/extras/dbus/Makefile +++ b/extras/dbus/Makefile @@ -53,16 +53,16 @@ spotless: clean install-dbus-policy: $(INSTALL) -d $(DESTDIR)$(dbusdir) + +uninstall-dbus-policy: + - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf + +install: install-dbus-policy all $(INSTALL_DATA) etc/dbus-1/system.d/udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(usrsbindir)/$(PROG) - ln -s -f $(DESTDIR)$(usrsbindir)/$(PROG) $(DESTDIR)$(devddir)/$(PROG).dev -uninstall-dbus-policy: - - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf +uninstall: uninstall-dbus-policy - rm $(DESTDIR)$(devddir)/$(PROG).dev - rm $(DESTDIR)$(usrsbindir)/$(PROG) -install: install-dbus-policy all - -uninstall: uninstall-dbus-policy - diff --git a/extras/selinux/Makefile b/extras/selinux/Makefile index 813756700b..35d2e9e6da 100644 --- a/extras/selinux/Makefile +++ b/extras/selinux/Makefile @@ -26,7 +26,9 @@ exec_prefix = ${prefix} etcdir = ${prefix}/etc sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default hotplugdir = ${etcdir}/hotplug.d/default configdir = ${etcdir}/udev/ initdir = ${etcdir}/init.d/ @@ -52,8 +54,11 @@ clean: spotless: clean - install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + - ln -s -f $(DESTDIR)$(sbindir)/$(PROG) $(DESTDIR)$(devddir)/$(PROG).dev -uninstall: +uninstall: + - rm $(DESTDIR)$(devddir)/$(PROG).dev + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/selinux/udev_selinux.c b/extras/selinux/udev_selinux.c index df23d9e6a7..8b1c2c7da8 100644 --- a/extras/selinux/udev_selinux.c +++ b/extras/selinux/udev_selinux.c @@ -1,10 +1,27 @@ +/* + * udev_selinux.c + * + * Copyright (C) 2004 Daniel J 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + #include #include #include -#include -#include #include -#include #include #include "../../udev_lib.h" @@ -16,16 +33,13 @@ void log_message(int level, const char *format, ...) { va_list args; - if (!udev_log) - return; - va_start(args, format); vsyslog(level, format, args); va_end(args); } #endif -void selinux_add_node(char *filename) +static void selinux_add_node(char *filename) { int retval; @@ -35,7 +49,7 @@ void selinux_add_node(char *filename) if (retval < 0) { dbg("matchpathcon(%s) failed\n", filename); } else { - retval=setfilecon(filename,scontext); + retval = setfilecon(filename,scontext); if (retval < 0) dbg("setfiles %s failed with error '%s'", filename, strerror(errno)); @@ -47,7 +61,6 @@ void selinux_add_node(char *filename) int main(int argc, char *argv[], char *envp[]) { char *action; - char *devpath; char *devname; int retval = 0; From d9154d11760bc650ca396d19bd31240616d4f80a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 17 Apr 2004 00:09:17 -0700 Subject: [PATCH 0758/4284] [PATCH] add scripts to run gcov for udev from Leann Ogasawara --- README-gcov_for_udev | 116 +++++++++++++++++++++++++++++++++++++++++++ make_gcov.sh | 53 ++++++++++++++++++++ run_gcov.sh | 40 +++++++++++++++ 3 files changed, 209 insertions(+) create mode 100644 README-gcov_for_udev create mode 100644 make_gcov.sh create mode 100644 run_gcov.sh diff --git a/README-gcov_for_udev b/README-gcov_for_udev new file mode 100644 index 0000000000..fa377bc4af --- /dev/null +++ b/README-gcov_for_udev @@ -0,0 +1,116 @@ +################################################ + +Using GCC's code coverage tool, gcov, with udev + +################################################ + +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. I've also compiled a udev_for_dev + toubleshooting document for Red Hat which can be found at: + + http://developer.osdl.org/ogasawara/gcov_for_udev/rh_udev_for_dev.txt + +- Get the following files: + make_gcov.sh + run_gcov.sh + + These can be found at http://developer.osdl.org/ogasawara/gcov_for_udev/ + +- After grabbing these files, copy both make_gcov.sh and run_gcov.sh + into the top level of your udev directory. + +- execute make_gcov.sh + + ./make_gcov.sh + + 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. + + make_gcov.sh will assume the same default parameters as the regular + make but also accepts the same parameters. For example if you want + to get code coverage analysis for udev with the DEBUG flag turned + on, you would just execute: + + ./make_gcov.sh DEBUG=true + + There is one exception, gcov will not work with klibc as it does not + compile cleanly with the -fprofile-arcs and -ftest-coverage flags. + With this said it is pretty much useless to set the KERNEL_DIR flag + when using make_gcov.sh as well. + + Don't be alarmed if you look into your udev directory and see that it + has been polluted with a bunch of *.bb, *.bbg, *.da, 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. + +- To get the udev code coverage analysis, execute run_gcov.sh. You need to + be root to do this. + + su to root + ./run_gcov.sh + +- This creates udev_gcov.txt 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. Simply, + + ./make_gcov.sh clean + + This will clean out all the *.bb, *.bbg, *.da, *.gcov files produced by gcov. + It will also 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 + su to root + make isntall diff --git a/make_gcov.sh b/make_gcov.sh new file mode 100644 index 0000000000..907c1ebd48 --- /dev/null +++ b/make_gcov.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# +# gcov capability for udev +# +# Provides code coverage analysis for udev. +# +# make_gcov.sh assumes the same same default parameters as make, but also +# accepts the same parameters as make (see README file in udev/ for +# parameter info). There is one exception, klibc can not be used with +# gcov as it will not compile cleanly. +# +# make_gcov.sh then overrides CFLAGS to strip out optimization in order +# for gcov to get correct code coverage analysis. +# +# Leann Ogasawara , April 2004 + +# clean up udev dir +clean_udev () { + find -name "*.da" -exec rm -f "{}" \; + find -name "*.bb" -exec rm -f "{}" \; + find -name "*.bbg" -exec rm -f "{}" \; + find -name "*.gcov" -exec rm -f "{}" \; + make clean +} + +PWD=`pwd` +GCCINCDIR=`gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"` +LIBSYSFS="-I$PWD/libsysfs" +WARNINGS="-Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations" +GCC="-I$GCCINCDIR" +USE_LOG="-DLOG" +DEBUG="-D_GNU_SOURCE" +GCOV_FLAGS="-pipe -fprofile-arcs -ftest-coverage" + +for i in $*; do + pre=`echo $i | sed 's/=.*//g'` + post=`echo $i | sed 's/.*=//g'` + if [ $pre = "USE_KLIBC" ] && [ $post = "true" ]; then + echo "cannot use gcov with klibc, will not compile" + exit + elif [ $pre = "USE_LOG" ] && [ $post = "false" ]; then + USE_LOG="" + elif [ $pre = "DEBUG" ] && [ $post = "true" ]; then + DEBUG="-g -DDEBUG -D_GNU_SOURCE" + elif [ $pre = "clean" ]; then + clean_udev + exit + fi +done + +clean_udev + +make $* CFLAGS="$WARNINGS $GCOV_FLAGS $USE_LOG $DEBUG $GCC $LIBSYSFS" diff --git a/run_gcov.sh b/run_gcov.sh new file mode 100644 index 0000000000..4fe936199f --- /dev/null +++ b/run_gcov.sh @@ -0,0 +1,40 @@ +#!/bin/sh + +# +# run gcov on udev +# +# Generate code coverage analysis for udev files +# +# This requires that you compiled udev with gcov flags i.e. +# you should have compiled udev with the make_gcov.sh script. +# +# Leann Ogasawara , April 2004 + +PWD=`pwd` + +# check if root else may not have access to *.da files +# and gcov analysis will fail. +if [ $(id -u) -ne 0 ]; then + echo "please become root before executing run_gcov.sh" + exit 1 +fi + +echo > udev_gcov.txt +echo "CODE COVERAGE ANALYSIS FOR UDEV" >> udev_gcov.txt +echo >> udev_gcov.txt + +for file in `find -maxdepth 1 -name "*.bb"`; do + name=`basename $file .bb` + echo "################" >> udev_gcov.txt + echo "$name.c" >> udev_gcov.txt + echo "################" >> udev_gcov.txt + if [ -e "$name.da" ]; then + gcov -l "$name.c" >> udev_gcov.txt 2>&1 + else + echo "code for $name.c was never executed" >> udev_gcov.txt 2>&1 + echo "no code coverage analysis to be done" >> udev_gcov.txt 2>&1 + fi + echo >> udev_gcov.txt +done + +echo "udev gcov analysis done. View udev_gcov.txt for results." From 0e3dcb3dc6f4aab5625e033a112a5e03703b87b9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 17 Apr 2004 00:09:32 -0700 Subject: [PATCH 0759/4284] [PATCH] add hints for red hat users from Leann Ogasawara --- docs/rh_udev_for_dev.txt | 68 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 docs/rh_udev_for_dev.txt diff --git a/docs/rh_udev_for_dev.txt b/docs/rh_udev_for_dev.txt new file mode 100644 index 0000000000..1a21c0e59b --- /dev/null +++ b/docs/rh_udev_for_dev.txt @@ -0,0 +1,68 @@ +Troubleshooting udev for dev on Red Hat distro + +1) Make sure you have a rescue disk/cd in case you hose your machine. You've + been forewarned. +2) Grab latest udev tarball or clone udev bitkeeper tree + (bk://linuxusb.bkbits.net.udev) +3) Follow README and HOWTO-udev_for_dev documents + +The following is some additional help to get udev for dev up and running on RH. + +Q. I login as my normal self from the login screen and RH just hangs on an + empty blue screen. What's wrong? + +A. You have some wrong permissions. I'm guessing you can probably log in as root + but not as your normal user. Basically you need to edit the + /etc/udev/udev.permissions file to set the correct permissions to the nodes + in /dev. I added the following: + + null:root:users:0666 + urandom:root:users:0644 + + setting the correct permissions to null and urandom allowed me to login + as myself and not at root. + + While you are there you might want to set the permissions to ptmx as well + or you may have trouble getting a bash prompt in an xterm. i.e. + ptmx:root:users:0666 Also refer to the next question. + +Q. I'm having trouble getting a bash prompt from my xterm. i.e. I bring up a + terminal and all I have is a blank screen with a blinking cursor. + +A. First make sure you have the correct permissions set for ptmx. See above + Q&A for help on this. But I'm guessing that something is wrong with your + /dev/pts, thanks Captain Obvious, heh:) You probably have devpts mounted + to /dev/pts from /etc/fstab. I'm also guessing that you have sysfs mounted + to /sys from /etc/fstab as well. If this is the case then the line in + /etc/rc.sysinit + + action $"Mounting local filesystems:" mount -a -t nonfs,smbfs,ncpfs -O no_netdev + + will have mounted these for you. As a result you placed your call to + start_udev directly after this because the HOWTO-udev_for_dev document + told you to insert start_udev after /proc and /sys have been mounted. + Well start_udev actually overwrites /dev thus anything you had mounted in + /dev prior to start_udev being called will be blown away. So basically, + you mounted devpts to /dev/pts because everything in /etc/fstab was mounted + and then it was blown away by calling start_udev. A simple fix is to remove + the mount devpts line from /etc/fstab and mount it after calling start_udev. + I did the following: + + action $"Mounting local filesystems:" mount -a -t nonfs,smbfs,ncpfs -O no_netdev + /etc/rc.d/start_udev + action $"Mounting devpts: " mount -t devpts none /dev/pts + + After doing so I rebooted and was able to get my prompt from my xterm. + +Q. I'm getting some error messages during boot. How do I get rid of them? + +A. For me it was a matter of setting up Symlinks. Basically, some /dev entries + were being looked for and not being found so an error was thrown. For example, + /dev/cdrom was needed but udev had named it /dev/hdc by default. Basically I + edited my /etc/udev/udev.rules file to create a symlink from /dev/cdrom to + /dev/hdc and my error went away. + +These are some of the things I ran into. NOTE: I hosed my machine more than once +trying to figure this out and a rescue disk was my best friend. If you have any +other experiences and would like to add to this Q&A list feel free to send me a +patch (ogasawara@osdl.org). Hopefully this helped someone. Thanks. From b4eafd94677a12f1dc3d6cade21cece0fd858339 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 17 Apr 2004 00:23:17 -0700 Subject: [PATCH 0760/4284] [PATCH] add dbus.dev, pam_console.dev and selinux.dev files for /etc/dev.d/default/ usage Thanks to Red Hat for them. --- etc/dev.d/default/dbus.dev | 11 +++++++++++ etc/dev.d/default/pam_console.dev | 14 ++++++++++++++ etc/dev.d/default/selinux.dev | 14 ++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 etc/dev.d/default/dbus.dev create mode 100644 etc/dev.d/default/pam_console.dev create mode 100644 etc/dev.d/default/selinux.dev diff --git a/etc/dev.d/default/dbus.dev b/etc/dev.d/default/dbus.dev new file mode 100644 index 0000000000..0e79632b30 --- /dev/null +++ b/etc/dev.d/default/dbus.dev @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ -f /etc/sysconfig/udev ]; then + . /etc/sysconfig/udev +fi + +[ "$UDEV_DBUS" != "yes" ] && exit 0 + +if [ -x /usr/sbin/udev_dbus ]; then + exec /usr/sbin/udev_dbus "$@" +fi diff --git a/etc/dev.d/default/pam_console.dev b/etc/dev.d/default/pam_console.dev new file mode 100644 index 0000000000..324c4fd804 --- /dev/null +++ b/etc/dev.d/default/pam_console.dev @@ -0,0 +1,14 @@ +#!/bin/sh + +if [ -f /etc/sysconfig/udev ]; then + . /etc/sysconfig/udev +fi + +[ "$UDEV_CONSOLE" != "yes" ] && exit 0 + +if [ -x /sbin/pam_console_setowner ]; then + if [ "$UDEV_LOG" = "yes" -a -x /usr/bin/logger ]; then + /usr/bin/logger -p auth.debug "Restoring console permissions for $DEVNAME" + fi + exec /sbin/pam_console_setowner $DEVNAME +fi diff --git a/etc/dev.d/default/selinux.dev b/etc/dev.d/default/selinux.dev new file mode 100644 index 0000000000..f168eefc42 --- /dev/null +++ b/etc/dev.d/default/selinux.dev @@ -0,0 +1,14 @@ +#!/bin/sh + +if [ -f /etc/sysconfig/udev ]; then + . /etc/sysconfig/udev +fi + +[ "$UDEV_SELINUX" != "yes" ] && exit 0 + +if [ -x /sbin/restorecon ]; then + if [ "$UDEV_LOG" = "yes" -a -x /usr/bin/logger ]; then + /usr/bin/logger -p auth.debug "Restoring file security contexts for $DEVNAME" + fi + /sbin/restorecon $DEVNAME +fi From 6763c8a5a1d954c6453c2b01e331ae95b1bcfe2a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 17 Apr 2004 00:25:20 -0700 Subject: [PATCH 0761/4284] [PATCH] update the Red Hat .dev files to work on other distros --- etc/dev.d/default/dbus.dev | 4 ++++ etc/dev.d/default/pam_console.dev | 4 ++++ etc/dev.d/default/selinux.dev | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/etc/dev.d/default/dbus.dev b/etc/dev.d/default/dbus.dev index 0e79632b30..2fe1ed9b3a 100644 --- a/etc/dev.d/default/dbus.dev +++ b/etc/dev.d/default/dbus.dev @@ -4,6 +4,10 @@ if [ -f /etc/sysconfig/udev ]; then . /etc/sysconfig/udev fi +if [ -f /etc/conf.d/udev ]; then + . /etc/conf.d/udev +fi + [ "$UDEV_DBUS" != "yes" ] && exit 0 if [ -x /usr/sbin/udev_dbus ]; then diff --git a/etc/dev.d/default/pam_console.dev b/etc/dev.d/default/pam_console.dev index 324c4fd804..7e95810e2c 100644 --- a/etc/dev.d/default/pam_console.dev +++ b/etc/dev.d/default/pam_console.dev @@ -4,6 +4,10 @@ if [ -f /etc/sysconfig/udev ]; then . /etc/sysconfig/udev fi +if [ -f /etc/conf.d/udev ]; then + . /etc/conf.d/udev +fi + [ "$UDEV_CONSOLE" != "yes" ] && exit 0 if [ -x /sbin/pam_console_setowner ]; then diff --git a/etc/dev.d/default/selinux.dev b/etc/dev.d/default/selinux.dev index f168eefc42..7911d345b9 100644 --- a/etc/dev.d/default/selinux.dev +++ b/etc/dev.d/default/selinux.dev @@ -4,6 +4,10 @@ if [ -f /etc/sysconfig/udev ]; then . /etc/sysconfig/udev fi +if [ -f /etc/conf.d/udev ]; then + . /etc/conf.d/udev +fi + [ "$UDEV_SELINUX" != "yes" ] && exit 0 if [ -x /sbin/restorecon ]; then From 87afc6dea0aca3cb9e40cba526e2241e4a887a54 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 17 Apr 2004 00:25:46 -0700 Subject: [PATCH 0762/4284] [PATCH] Switch the default config to point to a directory for the rules and permission files. --- etc/udev/udev.conf.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 3e73bedbf5..9b6b9c7ee2 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -12,10 +12,10 @@ udev_root="@udevdir@/" udev_db="@udevdir@/.udev.tdb" # udev_rules - The name and location of the udev rules file -udev_rules="/etc/udev/udev.rules" +udev_rules="/etc/udev/rules.d/" # udev_permissions - The name and location of the udev permission file -udev_permissions="/etc/udev/udev.permissions" +udev_permissions="/etc/udev/permissions.d/" # default_mode - set the default mode for all nodes that have no # explicit match in the permissions file From 56dbd7dfb000f082d34f36883873f2f266725494 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 17 Apr 2004 00:29:36 -0700 Subject: [PATCH 0763/4284] [PATCH] add udev conf.d file. --- etc/conf.d/udev | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 etc/conf.d/udev diff --git a/etc/conf.d/udev b/etc/conf.d/udev new file mode 100644 index 0000000000..50eda3a970 --- /dev/null +++ b/etc/conf.d/udev @@ -0,0 +1,11 @@ +# if selinux file attributes +# should be restored (leave to yes, if unsure) +UDEV_SELINUX="yes" + +# if console permissions (pam_console) +# should be restored (leave to yes, if unsure) +UDEV_CONSOLE="yes" + +# if dbus messages should be sent +UDEV_DBUS="no" + From 3a0b657b76ea3844e8bc7f742adba1d7f16f7d2c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 21 Apr 2004 17:43:17 -0700 Subject: [PATCH 0764/4284] [PATCH] added rules for tun and raw devices --- etc/udev/udev.rules | 6 ++++++ etc/udev/udev.rules.devfs | 10 ++++++++++ etc/udev/udev.rules.gentoo | 6 ++++++ 3 files changed, 22 insertions(+) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index ef61eafb8d..bc8c8bdd6c 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -39,3 +39,9 @@ BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" # CAPI devices KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" KERNEL="capi*", NAME="capi/%n" + +# Network devices +KERNEL="tun", NAME="net/%k" + +# raw devices +KERNEL="raw[0-9]*", NAME="raw/%k" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 3934fc6984..867f95029c 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -93,3 +93,13 @@ KERNEL="route6", NAME="netlink/%k" KERNEL="ip6_fw", NAME="netlink/%k" KERNEL="dnrtmsg", NAME="netlink/%k" KERNEL="tap*", NAME="netlink/%k" + +# CAPI devices +KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" +KERNEL="capi*", NAME="capi/%n" + +# Network devices +KERNEL="tun", NAME="net/%k" + +# raw devices +KERNEL="raw[0-9]*", NAME="raw/%k" diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index ab6f3bd405..1a84baa9d4 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -124,3 +124,9 @@ KERNEL="tap*", NAME="netlink/%k" # CAPI devices KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" KERNEL="capi*", NAME="capi/%n" + +# Network devices +KERNEL="tun", NAME="net/%k" + +# raw devices +KERNEL="raw[0-9]*", NAME="raw/%k" From a36a3c3a44286e77d6ec05c7579f61b4eb0ee344 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 21 Apr 2004 17:49:44 -0700 Subject: [PATCH 0765/4284] [PATCH] fix test regressions On Sat, Apr 17, 2004 at 03:30:29AM +0200, Kay Sievers wrote: > On Sat, Apr 17, 2004 at 02:04:55AM +0200, Kay Sievers wrote: > > On Fri, Apr 16, 2004 at 04:04:42PM -0700, Greg KH wrote: > > > Oh, and if you run the latest udev_test.pl, we have a bunch more tests, > > > including a few that fail, if you were looking for something to do :) > > > > Will do it. We need to change apply_format(). I tries to expand the '%%' > > with the next iteration over the string and removes the '%'. The tests are all successful now. If this patch breaks something else, we simply have too few tests :) --- namedev.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/namedev.c b/namedev.c index 51a4639abe..b3a2a8ae4b 100644 --- a/namedev.c +++ b/namedev.c @@ -199,23 +199,21 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_attribute *tmpattr; pos = string; - while (1) { - pos = strchr(string, '%'); - if (pos != NULL) { - pos[0] = '\0'; - tail = pos+1; - len = get_format_len(&tail); - c = tail[0]; - strfieldcpy(temp, tail+1); - tail = temp; - } else { + pos = strchr(pos, '%'); + if (pos == NULL) break; - } - dbg("format=%c, string='%s', tail='%s'",c , string, tail); + pos[0] = '\0'; + tail = pos+1; + len = get_format_len(&tail); + c = tail[0]; + strfieldcpy(temp, tail+1); + tail = temp; + dbg("format=%c, string='%s', tail='%s'",c , string, tail); attr = get_format_attribute(&tail); + switch (c) { case 'b': if (strlen(udev->bus_id) == 0) @@ -286,6 +284,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, break; case '%': strfieldcatmax(string, "%", maxsize); + pos++; break; default: dbg("unknown substitution type '%%%c'", c); From 738e5c3f28ec5b4907b6bbef41ca721ba8b353ff Mon Sep 17 00:00:00 2001 From: "ogasawara@osdl.org" Date: Wed, 21 Apr 2004 17:49:49 -0700 Subject: [PATCH 0766/4284] [PATCH] gcov for udev Sorry for the late email regarding the gcov code coverage information for udev. For those of you who have not yet noticed, udev can now be compiled with gcov support and provide code coverage analysis. All pertinent scripts and information can be found in the udev tree. Please refer to "README-gcov_for_udev" for detailed information on compiling gcov into udev and obtaining code coverage analysis. I've enclosed a patch that updates the README-gcov_for_udev. Also, "udev-test.pl" in udev/test/ was expanded to test symlinks, permissions, and some lack of node creation a little more thoroughly. All comments and feedback would be greatly welcomed. Also, any extra testing would be appreciated. Thanks, --- README-gcov_for_udev | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/README-gcov_for_udev b/README-gcov_for_udev index fa377bc4af..ca832803a2 100644 --- a/README-gcov_for_udev +++ b/README-gcov_for_udev @@ -14,20 +14,11 @@ 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. I've also compiled a udev_for_dev - toubleshooting document for Red Hat which can be found at: + toubleshooting document for Red Hat which can be found in: - http://developer.osdl.org/ogasawara/gcov_for_udev/rh_udev_for_dev.txt + docs/rh_udev_for_dev.txt -- Get the following files: - make_gcov.sh - run_gcov.sh - - These can be found at http://developer.osdl.org/ogasawara/gcov_for_udev/ - -- After grabbing these files, copy both make_gcov.sh and run_gcov.sh - into the top level of your udev directory. - -- execute make_gcov.sh +- execute make_gcov.sh from udev top level directory ./make_gcov.sh @@ -60,17 +51,18 @@ Note that this was developed with udev version 024. - 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. + 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. You need to - be root to do this. +- 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 ./run_gcov.sh -- This creates udev_gcov.txt 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: +- 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 From 477f5b63ec9b208e29350f242482bd2290a8a164 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 21 Apr 2004 17:53:52 -0700 Subject: [PATCH 0767/4284] [PATCH] add more permissions based on SuSE's recommendations. --- etc/udev/udev.permissions | 3 +++ etc/udev/udev.permissions.gentoo | 3 +++ 2 files changed, 6 insertions(+) diff --git a/etc/udev/udev.permissions b/etc/udev/udev.permissions index e87b4ddc67..dd56bbec4c 100644 --- a/etc/udev/udev.permissions +++ b/etc/udev/udev.permissions @@ -5,3 +5,6 @@ pl2303:500:500:0666 visor:root:uucp:0666 dsp1:::0666 camera*:500:500:0666 +sgi_fetchop:root:root:666 +iseries/vcd*:root:disk:660 +iseries/vd*:root:disk:660 diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index d5ef9eaa37..6c422b8ce7 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -192,3 +192,6 @@ usb/dabusb*:root:usb:0660 usb/mdc800*:root:usb:0660 usb/rio500:root:usb:0660 +sgi_fetchop:root:root:666 +iseries/vcd*:root:disk:660 +iseries/vd*:root:disk:660 From ffcd3851b22b28e5ac8a9756b486050a2c915f11 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 21 Apr 2004 20:23:47 -0700 Subject: [PATCH 0768/4284] [PATCH] add devd_test script. --- test/devd_test | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/devd_test diff --git a/test/devd_test b/test/devd_test new file mode 100644 index 0000000000..007a0bec90 --- /dev/null +++ b/test/devd_test @@ -0,0 +1,39 @@ +#!/bin/bash + +RULES=label_test.rules +CONFIG=label_test.conf + +export UDEV_TEST=yes +export SYSFS_PATH=$PWD/sys/ +export UDEV_CONFIG_FILE=$PWD/$CONFIG + +cat > $RULES << EOF +BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_diskX%n" +BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="a/nice/place/to/put/a/boot_disk%n" +EOF + +cat > $CONFIG << EOF +udev_root="$PWD/udev/" +udev_db="$PWD/udev/.udev.tdb" +udev_rules="$PWD/$RULES" +udev_permissions="$PWD/udev.permissions" +EOF + +mkdir udev + +export ACTION=add +export DEVPATH=block/sda + +../udev block +ls -l udev + +export ACTION=remove +export DEVPATH=block/sda + +../udev block +ls -l udev + + +rm $RULES +rm $CONFIG +rm -rf udev From a3e6c80049137722cf75d65de8d1e6d5a35bc252 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 21 Apr 2004 20:24:51 -0700 Subject: [PATCH 0769/4284] [PATCH] make dev.d call each directory in the directory chain of the device name, instead of just the whole name. This lets /etc/dev.d/sound/ work better. --- dev_d.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/dev_d.c b/dev_d.c index 81c7013315..97c552647b 100644 --- a/dev_d.c +++ b/dev_d.c @@ -64,20 +64,41 @@ static int run_program(char *name) void dev_d_send(struct udevice *dev, char *subsystem, char *devpath) { char dirname[256]; - char devname[NAME_SIZE]; + char env_devname[NAME_SIZE]; + char *devname; + char *temp; if (udev_dev_d == 0) return; if (dev->type == 'b' || dev->type == 'c') { - strfieldcpy(devname, udev_root); - strfieldcat(devname, dev->name); + strfieldcpy(env_devname, udev_root); + strfieldcat(env_devname, dev->name); } else if (dev->type == 'n') { - strfieldcpy(devname, dev->name); + strfieldcpy(env_devname, dev->name); setenv("DEVPATH", devpath, 1); } - setenv("DEVNAME", devname, 1); - dbg("DEVNAME='%s'", devname); + setenv("DEVNAME", env_devname, 1); + dbg("DEVNAME='%s'", env_devname); + + devname = strdup(dev->name); + if (!devname) { + dbg("out of memory"); + return; + } + + /* Chop the device name up into pieces based on '/' */ + temp = strchr(devname, '/'); + while (temp != NULL) { + *temp = 0x00; + strcpy(dirname, DEVD_DIR); + strfieldcat(dirname, devname); + call_foreach_file(run_program, dirname, DEVD_SUFFIX); + + *temp = '/'; + ++temp; + temp = strchr(temp, '/'); + } strcpy(dirname, DEVD_DIR); strfieldcat(dirname, dev->name); From da361dd7dfd451153e9dc10866a79de8a9f2f414 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 21 Apr 2004 22:31:17 -0700 Subject: [PATCH 0770/4284] [PATCH] v025 release --- ChangeLog | 43 +++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index abbab093bd..c37e615487 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +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 + o v024 release TAG: v024 + +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 ============================================ diff --git a/Makefile b/Makefile index dd7de95dc3..7969c0f51d 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 024 +VERSION = 025 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index cacaf2868a..f183f5b3d2 100644 --- a/udev.spec +++ b/udev.spec @@ -34,7 +34,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 024 +Version: 025 Release: 1 License: GPL Group: Utilities/System From aef6bb132ef2f5b4c446e42f6050033d4f5c177b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 23 Apr 2004 21:50:27 -0700 Subject: [PATCH 0771/4284] [PATCH] udev default config layout changes Here we catch up, after the default config changes. o the man page is updated to reflect the new default config o /etc/udev/rules.d/ + permissions.d/ dirs are created now o udev.rules is installed in /etc/udev/rules.d/50-udev.rules so the user can easily order the files by prepending a number. (RedHat has the same name in the last rpm.) o defined directory names in the Makefile are all without slashes now, not the first half with and the remaining without. o all binaries are uninstalled now o leading slashes in config values are now removed or prepended while the config is parsed, so we are more robust if the usere changes something. o replaced the macros from udev_config.c with real code, cause we can skip if the value matches and not useless iterate over the remaining fields. o config parsing errors are logged with info() now, fixes the bug where we report a error with debug_parse(), even when there isn't one --- Makefile | 64 ++++++++++++++++--------------- udev.8.in | 29 +++++++------- udev_config.c | 104 +++++++++++++++++++++++++++++++------------------- udev_lib.c | 22 ++++++++++- udev_lib.h | 2 + 5 files changed, 136 insertions(+), 85 deletions(-) diff --git a/Makefile b/Makefile index 7969c0f51d..7c716e852e 100644 --- a/Makefile +++ b/Makefile @@ -51,9 +51,9 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin mandir = ${prefix}/usr/share/man hotplugdir = ${etcdir}/hotplug.d/default -configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ -dev_ddir = ${etcdir}/dev.d/ +configdir = ${etcdir}/udev +initdir = ${etcdir}/init.d +dev_ddir = ${etcdir}/dev.d srcdir = . INSTALL = /usr/bin/install -c @@ -228,16 +228,16 @@ GEN_HEADERS = udev_version.h # Rules on how to create the generated header files udev_version.h: - @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ - @echo \#define UDEV_ROOT \"$(udevdir)/\" >> $@ - @echo \#define UDEV_DB \"$(udevdir)/\.udev.tdb\" >> $@ - @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ - @echo \#define UDEV_CONFIG_FILE \"$(configdir)\udev.conf\" >> $@ - @echo \#define UDEV_RULES_FILE \"$(configdir)\udev.rules\" >> $@ - @echo \#define UDEV_PERMISSION_FILE \"$(configdir)\udev.permissions\" >> $@ - @echo \#define UDEV_LOG_DEFAULT \"yes\" >> $@ - @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ - @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ + @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + @echo \#define UDEV_ROOT \"$(udevdir)/\" >> $@ + @echo \#define UDEV_DB \"$(udevdir)/.udev.tdb\" >> $@ + @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ + @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ + @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ + @echo \#define UDEV_PERMISSION_FILE \"$(configdir)/permissions.d\" >> $@ + @echo \#define UDEV_LOG_DEFAULT \"yes\" >> $@ + @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ + @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf @@ -343,29 +343,29 @@ install-initscript: etc/init.d/udev etc/init.d/udev.debian etc/init.d/udev.init. fi install-config: $(GEN_CONFIGS) - $(INSTALL) -d $(DESTDIR)$(configdir) - @if [ ! -r $(DESTDIR)$(configdir)udev.conf ]; then \ + $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d + $(INSTALL) -d $(DESTDIR)$(configdir)/permissions.d + @if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \ echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ fi - @if [ ! -r $(DESTDIR)$(configdir)udev.rules ]; then \ - echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir); \ - $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir); \ + @if [ ! -r $(DESTDIR)$(configdir)/rules.d/50-udev.rules ]; then \ + echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir)/rules.d/50-udev.rules; \ + $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir)/rules.d/50-udev.rules; \ fi - @if [ ! -r $(DESTDIR)$(configdir)udev.permissions ]; then \ - echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ - $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir); \ + @if [ ! -r $(DESTDIR)$(configdir)/permissions.d/50-udev.permissions ]; then \ + echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir)/permissions.d/50-udev.permissions; \ + $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir)/permissions.d/50-udev.permissions; \ fi install-dev.d: - $(INSTALL) -d $(DESTDIR)$(dev_ddir) - $(INSTALL) -d $(DESTDIR)$(dev_ddir)default/ - $(INSTALL_PROGRAM) -D etc/dev.d/net/hotplug.dev $(DESTDIR)$(dev_ddir)net/hotplug.dev + $(INSTALL) -d $(DESTDIR)$(dev_ddir)/default + $(INSTALL_PROGRAM) -D etc/dev.d/net/hotplug.dev $(DESTDIR)$(dev_ddir)/net/hotplug.dev uninstall-dev.d: - - rm $(dev_ddir)net/hotplug.dev - - rmdir $(dev_ddir)net - - rmdir $(dev_ddir)default + - rm $(dev_ddir)/net/hotplug.dev + - rmdir $(dev_ddir)/net + - rmdir $(dev_ddir)/default - rmdir $(dev_ddir) install-man: @@ -406,16 +406,20 @@ endif uninstall: uninstall-man uninstall-dev.d - rm $(hotplugdir)/udev.hotplug - - rm $(configdir)/udev.permissions - - rm $(configdir)/udev.rules + - rm $(configdir)/rules.d/50-udev.rules + - rm $(configdir)/permissions.d/50-udev.permissions - rm $(configdir)/udev.conf + - rmdir $(configdir)/rules.d + - rmdir $(configdir)/permissions.d + - rmdir $(configdir) - rm $(initdir)/udev - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) + - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) + - rm $(usrbindir)/$(TESTER) - rmdir $(hotplugdir) - - rmdir $(configdir) - rm $(udevdir)/.udev.tdb - rmdir $(udevdir) @extras="$(EXTRAS)" ; for target in $$extras ; do \ diff --git a/udev.8.in b/udev.8.in index f803578968..6d1dfd9d18 100644 --- a/udev.8.in +++ b/udev.8.in @@ -77,7 +77,7 @@ in this file: .B udev_root Indicates where to place the device nodes in the filesystem. The default value is -.IR @udevdir@ . +.IR @udevdir@/ . .TP .B udev_db The name and location of the udev database. The default value is @@ -87,14 +87,14 @@ The name and location of the udev database. The default value is The name of the udev rules file or directory to look for files with the suffix .IR .rules . All rule files are read in lexical order. The default value is -.IR /etc/udev/udev.rules . +.IR /etc/udev/rules.d/ . .TP .B udev_permissions The name of the udev permission file or directory to look for files with the suffix .IR .permissions . All permission files are read in lexical order. The default value is -.IR /etc/udev/udev.permissions . +.IR /etc/udev/permissions.d/ . .TP .B udev_log The switch, if udev logs some information for every device handled. @@ -121,17 +121,17 @@ file. The default value is .sp .nf # udev_root - where to place the device nodes in the filesystem -udev_root="@udevdir@" +udev_root="/udev" # udev_db - The name and location of the udev database -udev_db="@udevdir@/.udev.tdb" +udev_db="/udev/.udev.tdb" # udev_rules - The name of the udev rules file or directory to look for files with the suffix .rules udev_rules="/etc/udev/rules.d/" -# udev_permissions - The name of the udev permission file or directry to look - for files with the suffix .permissions +# udev_permissions - The name of the udev permission file or directory + to look for files with the suffix .permissions udev_permissions="/etc/udev/udev.permissions" # udev_log - set to "yes" if you want logging, else "no" @@ -150,14 +150,14 @@ default_owner="root" default_group="root" .fi .P -The rules for udev to use when naming devices may specified in -.I /etc/udev/udev.rules -or by the +The rules for device naming, are read from the files located in the +.I /etc/udev/rules.d/ +directory, or at the location specified by the .I udev_rules value in the .I /etc/udev/udev.conf file. -.P +.br Every line in the rules file defines the mapping between device attributes and the device name. One or more keys are specified to match a rule with the current device. If all keys are matching, the rule will be applied and @@ -304,9 +304,10 @@ KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" BUS="usb", SYSFS{model}="XV3", NAME="video%n", SYMLINK="webcam%n" .fi .P -Permissions and ownership for the created device files may specified in -.I /etc/udev/udev.permissions -or by the +The permissions and ownership of the created device file is read from +the files located in the +.I /etc/udev/permissions.d/ +directory, or at the location specified by the .I udev_permission value in the .I /etc/udev/udev.conf diff --git a/udev_config.c b/udev_config.c index ba04003e90..51a91d0092 100644 --- a/udev_config.c +++ b/udev_config.c @@ -84,18 +84,6 @@ static void init_variables(void) udev_dev_d = 0; } -#define set_var(_name, _var) \ - if (strcasecmp(variable, _name) == 0) { \ - dbg_parse("%s='%s'", _name, value); \ - strfieldcpy(_var, value);\ - } - -#define set_bool(_name, _var) \ - if (strcasecmp(variable, _name) == 0) { \ - dbg_parse("%s='%s'", _name, value); \ - _var = string_is_true(value); \ - } - int parse_get_pair(char **orig_string, char **left, char **right) { char *temp; @@ -181,22 +169,58 @@ static int parse_config_file(void) continue; retval = parse_get_pair(&temp, &variable, &value); - if (retval) - break; - - dbg_parse("variable = '%s', value = '%s'", variable, value); + if (retval != 0) + info("%s:%d:%Zd: error parsing '%s'", + udev_config_filename, lineno, temp-line, temp); - set_var("udev_root", udev_root); - set_var("udev_db", udev_db_filename); - set_var("udev_rules", udev_rules_filename); - set_var("udev_permissions", udev_permissions_filename); - set_var("default_mode", default_mode_str); - set_var("default_owner", default_owner_str); - set_var("default_group", default_group_str); - set_bool("udev_log", udev_log); + dbg_parse("variable='%s', value='%s'", variable, value); + + if (strcasecmp(variable, "udev_root") == 0) { + strfieldcpy(udev_root, value); + leading_slash(udev_root); + continue; + } + + if (strcasecmp(variable, "udev_db") == 0) { + strfieldcpy(udev_db_filename, value); + continue; + } + + if (strcasecmp(variable, "udev_rules") == 0) { + strfieldcpy(udev_rules_filename, value); + no_leading_slash(udev_rules_filename); + continue; + } + + if (strcasecmp(variable, "udev_permissions") == 0) { + strfieldcpy(udev_permissions_filename, value); + no_leading_slash(udev_permissions_filename); + continue; + } + + if (strcasecmp(variable, "default_mode") == 0) { + strfieldcpy(default_mode_str, value); + continue; + } + + if (strcasecmp(variable, "default_owner") == 0) { + strfieldcpy(default_owner_str, value); + continue; + } + + if (strcasecmp(variable, "default_group") == 0) { + strfieldcpy(default_group_str, value); + continue; + } + + if (strcasecmp(variable, "udev_log") == 0) { + udev_log = string_is_true(value); + continue; + } + + info("%s:%d:%Zd: unknown key '%s'", + udev_config_filename, lineno, temp-line, temp); } - dbg_parse("%s:%d:%Zd: error parsing '%s'", udev_config_filename, - lineno, temp - line, temp); file_unmap(buf, bufsize); return retval; @@ -212,32 +236,34 @@ static void get_dirs(void) dbg("sysfs_get_mnt_path failed"); /* see if we should try to override any of the default values */ - temp = getenv("UDEV_TEST"); - if (temp != NULL) { - /* hm testing is happening, use the specified values, if they are present */ + if (getenv("UDEV_TEST") != NULL) { temp = getenv("SYSFS_PATH"); - if (temp) + if (temp != NULL) { strfieldcpy(sysfs_path, temp); + no_leading_slash(sysfs_path); + } + temp = getenv("UDEV_CONFIG_FILE"); - if (temp) + if (temp != NULL) strfieldcpy(udev_config_filename, temp); } - dbg("sysfs_path='%s'", sysfs_path); + dbg("sysfs_path='%s'", sysfs_path); dbg_parse("udev_root = %s", udev_root); dbg_parse("udev_config_filename = %s", udev_config_filename); dbg_parse("udev_db_filename = %s", udev_db_filename); dbg_parse("udev_rules_filename = %s", udev_rules_filename); dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); dbg_parse("udev_log = %d", udev_log); + parse_config_file(); - dbg_parse("udev_root = %s", udev_root); - dbg_parse("udev_config_filename = %s", udev_config_filename); - dbg_parse("udev_db_filename = %s", udev_db_filename); - dbg_parse("udev_rules_filename = %s", udev_rules_filename); - dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); - dbg_parse("udev_log_str = %d", udev_log); + dbg("udev_root = %s", udev_root); + dbg("udev_config_filename = %s", udev_config_filename); + dbg("udev_db_filename = %s", udev_db_filename); + dbg("udev_rules_filename = %s", udev_rules_filename); + dbg("udev_permissions_filename = %s", udev_permissions_filename); + dbg("udev_log_str = %d", udev_log); } void udev_init_config(void) @@ -245,5 +271,3 @@ void udev_init_config(void) init_variables(); get_dirs(); } - - diff --git a/udev_lib.c b/udev_lib.c index 381492db01..16b473f576 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -152,6 +152,26 @@ size_t buf_get_line(char *buf, size_t buflen, size_t cur) return count - cur; } +void leading_slash(char *path) +{ + int len; + + len = strlen(path); + if (len > 0 && path[len-1] != '/') { + path[len] = '/'; + path[len+1] = '\0'; + } +} + +void no_leading_slash(char *path) +{ + int len; + + len = strlen(path); + if (len > 0 && path[len-1] == '/') + path[len-1] = '\0'; +} + struct files { struct list_head list; char name[NAME_SIZE]; @@ -180,7 +200,7 @@ static int file_list_insert(char *filename, struct list_head *file_list) return 0; } -/* calls function for file or every file found in directory */ +/* calls function for every file found in specified directory */ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) { struct dirent *ent; diff --git a/udev_lib.h b/udev_lib.h index cc264fa9b4..18ce25ccc7 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -75,6 +75,8 @@ extern char get_device_type(const char *path, const char *subsystem); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); +extern void leading_slash(char *path); +extern void no_leading_slash(char *path); extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension); From e13fa59953d64e478025fd1200bb5fd0baf671b2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 23 Apr 2004 21:55:57 -0700 Subject: [PATCH 0772/4284] [PATCH] udevstart: close open directories. Based on a munged patch from Olaf Hering --- udevstart.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/udevstart.c b/udevstart.c index 5e6606d535..1d9b60464c 100644 --- a/udevstart.c +++ b/udevstart.c @@ -130,10 +130,13 @@ static void udev_scan(void) udev_exec(filename, "block"); } } + closedir(dir3); } } + closedir(dir2); } } + closedir(dir); } devpath = "class"; @@ -176,10 +179,13 @@ static void udev_scan(void) udev_exec(filename, dent->d_name); } } + closedir(dir3); } } + closedir(dir2); } } + closedir(dir); } } From 3611d5820c0fc0863d15c04884b05c9e04492f45 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 30 Apr 2004 23:26:33 -0700 Subject: [PATCH 0773/4284] [PATCH] udev callout for reading filesystem labels here is a small udev toy, which enables udev to name partitions by its filesystem label or uuid's. The following udev rule: KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -M%M -m%m -u", SYMLINK="%c" creates a symlink with the uuid read from the filesystem. If no label or uuid is found the program exits with nonzero and the rule will fail. ext2, ext3, reiserfs, xfs, jfs, vfat, msdos volume labels are supported, ntfs and swap partitions can be recognized. It's possible to compile with klibc and the static binary takes 13kb. --- extras/volume_id/Makefile | 50 +++ extras/volume_id/udev_volume_id.c | 120 +++++++ extras/volume_id/volume_id.c | 550 ++++++++++++++++++++++++++++++ extras/volume_id/volume_id.h | 72 ++++ 4 files changed, 792 insertions(+) create mode 100644 extras/volume_id/Makefile create mode 100644 extras/volume_id/udev_volume_id.c create mode 100644 extras/volume_id/volume_id.c create mode 100644 extras/volume_id/volume_id.h diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile new file mode 100644 index 0000000000..6a3d2866c4 --- /dev/null +++ b/extras/volume_id/Makefile @@ -0,0 +1,50 @@ +# Makefile for udev_volume_id +# +# 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. +# + +PROG = udev_volume_id + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +override CFLAGS+=-Wall -fno-builtin +OBJS = volume_id.o udev_volume_id.o +HEADERS = volume_id.h + +$(OBJS): $(HEADERS) + +$(PROG): $(OBJS) $(HEADERS) + $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(usrsbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(usrsbindir)/$(PROG) + diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c new file mode 100644 index 0000000000..88779ccd36 --- /dev/null +++ b/extras/volume_id/udev_volume_id.c @@ -0,0 +1,120 @@ +/* + * udev_volume_id - udev callout to read filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * sample udev rule for creation of a symlink with the filsystem uuid: + * KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -M%M -m%m -u", SYMLINK="%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 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. + * + */ + +#include +#include +#include + +#include "volume_id.h" + +int main(int argc, char *argv[]) +{ + struct volume_id *vid; + const char help[] = "usage: udev_volume_id -m -M [-t|-l|-u]\n"; + int major = -1; + int minor = -1; + char *tail; + static const char short_options[] = "M:m:htlu"; + int option; + char print = '\0'; + int rc; + + + while (1) { + option = getopt(argc, argv, short_options); + if (option == -1) + break; + + switch (option) { + case 'M': + major = (int) strtoul(optarg, &tail, 10); + if (tail[0] != '\0') { + printf("invalid major\n"); + exit(1); + } + break; + case 'm': + minor = (int) strtoul(optarg, &tail, 10); + if (tail[0] != '\0') { + printf("invalid minor\n"); + exit(1); + } + break; + case 't': + print = 't'; + break; + case 'l': + print = 'l'; + break; + case 'u': + print = 'u'; + break; + case 'h': + case '?': + default: + printf(help); + exit(1); + } + } + + if (major == -1 || minor == -1) { + printf(help); + exit(1); + } + + vid = volume_id_open_dev_t(makedev(major, minor)); + if (vid == NULL) { + printf("error open volume\n"); + exit(1); + } + + rc = volume_id_probe(vid, ALL); + if (rc != 0) { + printf("error probing volume\n"); + exit(1); + } + + switch (print) { + case 't': + printf("%s\n", vid->fs_name); + break; + case 'l': + if (vid->label_string[0] == '\0') + exit(2); + printf("%s\n", vid->label_string); + break; + case 'u': + if (vid->uuid_string[0] == '\0') + exit(2); + printf("%s\n", vid->uuid_string); + break; + default: + printf("T:%s\n", vid->fs_name); + printf("L:%s\n", vid->label_string); + printf("U:%s\n", vid->uuid_string); + } + + volume_id_close(vid); + + exit(0); +} diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c new file mode 100644 index 0000000000..cc5475fc8d --- /dev/null +++ b/extras/volume_id/volume_id.c @@ -0,0 +1,550 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * The superblock structs are taken from the libblkid living inside + * the e2fsprogs. This is a simple straightforward implementation for + * reading the label strings of only the most common filesystems. + * If you need a full featured library with attribute caching, support for + * much more partition/media types or non-root data access, you may have + * a look at: + * http://e2fsprogs.sourceforge.net. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" + + +#define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \ + (((__u32)(x) & 0x00ff0000u) >> 8) | \ + (((__u32)(x) & 0x0000ff00u) << 8) | \ + (((__u32)(x) & 0x000000ffu) << 24)) + +#if (__BYTE_ORDER == __LITTLE_ENDIAN) +#define cpu_to_le32(x) (x) +#elif (__BYTE_ORDER == __BIG_ENDIAN) +#define cpu_to_le32(x) bswap32(x) +#endif + +#define VOLUME_ID_BUFFER_SIZE 0x11000 /* reiser offset is 64k */ + + +static void set_label(struct volume_id *id, char *buf, int count) +{ + int i; + + memcpy(id->label, buf, count); + + memcpy(id->label_string, buf, count); + + /* remove trailing whitespace */ + i = strlen(id->label_string); + while (i--) { + if (! isspace(id->label_string[i])) + break; + } + id->label_string[i+1] = '\0'; +} + +static void set_uuid(struct volume_id *id, unsigned char *buf, int count) +{ + int i; + + memcpy(id->uuid, buf, count); + + /* create string if uuid is set */ + for (i = 0; i < count; i++) + if (buf[i] != 0) + goto set; + return; + +set: + switch(count) { + case 4: + sprintf(id->uuid_string, "%02X%02X-%02X%02X", + buf[3], buf[2], buf[1], buf[0]); + break; + case 16: + sprintf(id->uuid_string, + "%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; + } +} + +static int open_superblock(struct volume_id *id) +{ + /* get buffer to read the first block */ + if (id->buf == NULL) { + id->buf = malloc(VOLUME_ID_BUFFER_SIZE); + if (id->buf == NULL) + return -1; + } + + /* try to read the first 64k, but at least the first block */ + memset(id->buf, 0x00, VOLUME_ID_BUFFER_SIZE); + lseek(id->fd, 0, SEEK_SET); + if (read(id->fd, id->buf, VOLUME_ID_BUFFER_SIZE) < 0x200) + return -1; + + return 0; +} + +static void close_superblock(struct volume_id *id) +{ + if (id->buf != NULL) { + free(id->buf); + id->buf = NULL; + } +} + +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 +#define EXT_SUPERBLOCK_OFFSET 0x400 +static int probe_ext(struct volume_id *id) +{ + struct ext2_super_block { + __u32 s_inodes_count; + __u32 s_blocks_count; + __u32 s_r_blocks_count; + __u32 s_free_blocks_count; + __u32 s_free_inodes_count; + __u32 s_first_data_block; + __u32 s_log_block_size; + __u32 s_dummy3[7]; + unsigned char s_magic[2]; + __u16 s_state; + __u32 s_dummy5[8]; + __u32 s_feature_compat; + __u32 s_feature_incompat; + __u32 s_feature_ro_compat; + unsigned char s_uuid[16]; + char s_volume_name[16]; + } *es; + + es = (struct ext2_super_block *) (id->buf + EXT_SUPERBLOCK_OFFSET); + + if (es->s_magic[0] != 0123 || + es->s_magic[1] != 0357) + return -1; + + set_label(id, es->s_volume_name, 16); + set_uuid(id, es->s_uuid, 16); + + if ((cpu_to_le32(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { + id->fs_type = EXT3; + id->fs_name = "ext3"; + } else { + id->fs_type = EXT2; + id->fs_name = "ext2"; + } + + return 0; +} + +#define REISER1_SUPERBLOCK_OFFSET 0x2000 +#define REISER_SUPERBLOCK_OFFSET 0x10000 +static int probe_reiser(struct volume_id *id) +{ + struct reiser_super_block { + __u32 rs_blocks_count; + __u32 rs_free_blocks; + __u32 rs_root_block; + __u32 rs_journal_block; + __u32 rs_journal_dev; + __u32 rs_orig_journal_size; + __u32 rs_dummy2[5]; + __u16 rs_blocksize; + __u16 rs_dummy3[3]; + unsigned char rs_magic[12]; + __u32 rs_dummy4[5]; + unsigned char rs_uuid[16]; + char rs_label[16]; + } *rs; + + rs = (struct reiser_super_block *) &(id->buf[REISER1_SUPERBLOCK_OFFSET]); + + if (strncmp(rs->rs_magic, "ReIsErFs", 8) == 0) + goto found; + + rs = (struct reiser_super_block *) &(id->buf[REISER_SUPERBLOCK_OFFSET]); + + if (strncmp(rs->rs_magic, "ReIsEr2Fs", 9) == 0) + goto found; + if (strncmp(rs->rs_magic, "ReIsEr3Fs", 9) == 0) + goto found; + + return -1; + +found: + set_label(id, rs->rs_label, 16); + set_uuid(id, rs->rs_uuid, 16); + + id->fs_type = REISER; + id->fs_name = "reiser"; + + return 0; +} + +static int probe_xfs(struct volume_id *id) +{ + struct xfs_super_block { + unsigned char xs_magic[4]; + __u32 xs_blocksize; + __u64 xs_dblocks; + __u64 xs_rblocks; + __u32 xs_dummy1[2]; + unsigned char xs_uuid[16]; + __u32 xs_dummy2[15]; + char xs_fname[12]; + __u32 xs_dummy3[2]; + __u64 xs_icount; + __u64 xs_ifree; + __u64 xs_fdblocks; + } *xs; + + xs = (struct xfs_super_block *) id->buf; + + if (strncmp(xs->xs_magic, "XFSB", 4) != 0) + return -1; + + set_label(id, xs->xs_fname, 12); + set_uuid(id, xs->xs_uuid, 16); + + id->fs_type = XFS; + id->fs_name = "xfs"; + + return 0; +} + +#define JFS_SUPERBLOCK_OFFSET 0x8000 +static int probe_jfs(struct volume_id *id) +{ + struct jfs_super_block { + unsigned char js_magic[4]; + __u32 js_version; + __u64 js_size; + __u32 js_bsize; + __u32 js_dummy1; + __u32 js_pbsize; + __u32 js_dummy2[27]; + unsigned char js_uuid[16]; + unsigned char js_label[16]; + unsigned char js_loguuid[16]; + } *js; + + js = (struct jfs_super_block *) &(id->buf[JFS_SUPERBLOCK_OFFSET]); + + if (strncmp(js->js_magic, "JFS1", 4) != 0) + return -1; + + set_label(id, js->js_label, 16); + set_uuid(id, js->js_uuid, 16); + + id->fs_type = JFS; + id->fs_name = "jfs"; + + return 0; +} + +static int probe_vfat(struct volume_id *id) +{ + struct vfat_super_block { + unsigned char vs_ignored[3]; + unsigned char vs_sysid[8]; + unsigned char vs_sector_size[2]; + __u8 vs_cluster_size; + __u16 vs_reserved; + __u8 vs_fats; + unsigned char vs_dir_entries[2]; + unsigned char vs_sectors[2]; + unsigned char vs_media; + __u16 vs_fat_length; + __u16 vs_secs_track; + __u16 vs_heads; + __u32 vs_hidden; + __u32 vs_total_sect; + __u32 vs_fat32_length; + __u16 vs_flags; + __u8 vs_version[2]; + __u32 vs_root_cluster; + __u16 vs_insfo_sector; + __u16 vs_backup_boot; + __u16 vs_reserved2[6]; + unsigned char vs_unknown[3]; + unsigned char vs_serno[4]; + char vs_label[11]; + unsigned char vs_magic[8]; + unsigned char vs_dummy2[164]; + unsigned char vs_pmagic[2]; + } *vs; + + vs = (struct vfat_super_block *) id->buf; + + if (strncmp(vs->vs_magic, "MSWIN", 5) == 0) + goto found; + if (strncmp(vs->vs_magic, "FAT32 ", 8) == 0) + goto found; + return -1; + +found: + memcpy(id->label, vs->vs_label, 11); + memcpy(id->uuid, vs->vs_serno, 4); + + id->fs_type = VFAT; + id->fs_name = "vfat"; + + return 0; +} + +static int probe_msdos(struct volume_id *id) +{ + struct msdos_super_block { + unsigned char ms_ignored[3]; + unsigned char ms_sysid[8]; + unsigned char ms_sector_size[2]; + __u8 ms_cluster_size; + __u16 ms_reserved; + __u8 ms_fats; + unsigned char ms_dir_entries[2]; + unsigned char ms_sectors[2]; + unsigned char ms_media; + __u16 ms_fat_length; + __u16 ms_secs_track; + __u16 ms_heads; + __u32 ms_hidden; + __u32 ms_total_sect; + unsigned char ms_unknown[3]; + unsigned char ms_serno[4]; + char ms_label[11]; + unsigned char ms_magic[8]; + unsigned char ms_dummy2[192]; + unsigned char ms_pmagic[2]; + } *ms; + + ms = (struct msdos_super_block *) id->buf; + + if (strncmp(ms->ms_magic, "MSDOS", 5) == 0) + goto found; + if (strncmp(ms->ms_magic, "FAT16 ", 8) == 0) + goto found; + if (strncmp(ms->ms_magic, "FAT12 ", 8) == 0) + goto found; + return -1; + +found: + set_label(id, ms->ms_label, 11); + set_uuid(id, ms->ms_serno, 4); + + id->fs_type = MSDOS; + id->fs_name = "msdos"; + + return 0; +} + +static int probe_ntfs(struct volume_id *id) +{ + struct ntfs_super_block { + char jump[3]; + char oem_id[4]; + } *ns; + + ns = (struct ntfs_super_block *) id->buf; + + if (strncmp(ns->oem_id, "NTFS", 4) != 0) + return -1; + + id->fs_type = NTFS; + id->fs_name = "ntfs"; + + return 0; +} + +static int probe_swap(struct volume_id *id) +{ + int magic; + + /* huhh, the swap signature is on the end of the PAGE_SIZE */ + for (magic = 0x1000; magic <= 0x4000; magic <<= 1) { + if (strncmp(&(id->buf[magic -10]), "SWAP-SPACE", 10) == 0) + goto found; + if (strncmp(&(id->buf[magic -10]), "SWAPSPACE2", 10) == 0) + goto found; + } + return -1; + +found: + id->fs_type = SWAP; + id->fs_name = "swap"; + + return 0; +} + +/* probe volume for filesystem type and try to read label+uuid */ +int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type) +{ + int rc; + + if (id == NULL) + return -EINVAL; + + if (open_superblock(id) != 0) + return -EACCES; + + switch (fs_type) { + case EXT3: + case EXT2: + rc = probe_ext(id); + break; + case REISER: + rc = probe_reiser(id); + break; + case XFS: + rc = probe_xfs(id); + break; + case JFS: + rc = probe_jfs(id); + break; + case MSDOS: + rc = probe_msdos(id); + break; + case VFAT: + rc = probe_vfat(id); + break; + case NTFS: + rc = probe_ntfs(id); + break; + case SWAP: + rc = probe_swap(id); + break; + default: + rc = probe_ext(id); + if (rc == 0) + break; + rc = probe_reiser(id); + if (rc == 0) + break; + rc = probe_xfs(id); + if (rc == 0) + break; + rc = probe_jfs(id); + if (rc == 0) + break; + rc = probe_msdos(id); + if (rc == 0) + break; + rc = probe_vfat(id); + if (rc == 0) + break; + rc = probe_ntfs(id); + if (rc == 0) + break; + rc = probe_swap(id); + if (rc == 0) + break; + rc = -1; + } + + if (rc == 0) + close_superblock(id); + + return rc; +} + +/* open volume by already open file descriptor */ +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; +} + +/* open volume by device node */ +struct volume_id *volume_id_open_node(const char *path) +{ + struct volume_id *id; + int fd; + + fd = open(path, O_RDONLY); + if (fd < 0) + return NULL; + + id = volume_id_open_fd(fd); + if (id == NULL) + return NULL; + + /* close fd on device close */ + id->fd_close = 1; + + return id; +} + +/* open volume by major/minor */ +struct volume_id *volume_id_open_dev_t(dev_t devt) +{ + struct volume_id *id; + char tmp_node[VOLUME_ID_PATH_MAX]; + + snprintf(tmp_node, VOLUME_ID_PATH_MAX, + "/tmp/volume-%u-%u", major(devt), minor(devt)); + tmp_node[VOLUME_ID_PATH_MAX] = '\0'; + + /* create tempory node to open the block device */ + if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0) + return NULL; + + id = volume_id_open_node(tmp_node); + + unlink(tmp_node); + + return id; +} + +/* free allocated volume info */ +void volume_id_close(struct volume_id *id) +{ + if (id == NULL) + return; + + if (id->fd_close != 0) + close(id->fd); + + close_superblock(id); + + free(id); +} diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h new file mode 100644 index 0000000000..a0d2acda22 --- /dev/null +++ b/extras/volume_id/volume_id.h @@ -0,0 +1,72 @@ +/* + * volume_id - reads partition 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _VOLUME_ID_H_ +#define _VOLUME_ID_H_ + +#define VOLUME_ID_VERSION 001 + +#define VOLUME_ID_LABEL_SIZE 16 +#define VOLUME_ID_UUID_SIZE 16 +#define VOLUME_ID_UUID_STRING_SIZE 37 +#define VOLUME_ID_PATH_MAX 255 + + +enum filesystem_type { + ALL, + EXT2, + EXT3, + REISER, + XFS, + JFS, + MSDOS, + VFAT, + NTFS, + SWAP +}; + +struct volume_id { + char label[VOLUME_ID_LABEL_SIZE]; + char label_string[VOLUME_ID_LABEL_SIZE+1]; + unsigned char uuid[VOLUME_ID_UUID_SIZE]; + char uuid_string[VOLUME_ID_UUID_STRING_SIZE]; + enum filesystem_type fs_type; + char *fs_name; + int fd; + char *buf; + int fd_close; +}; + +/* open volume by already open file descriptor */ +extern struct volume_id *volume_id_open_fd(int fd); + +/* open volume by device node */ +extern struct volume_id *volume_id_open_node(const char *path); + +/* open volume by major/minor */ +extern struct volume_id *volume_id_open_dev_t(dev_t devt); + +/* probe volume for filesystem type and try to read label/uuid */ +extern int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type); + +/* free allocated device info */ +extern void volume_id_close(struct volume_id *id); + +#endif From 599b626127f420236b8757a1e9bccc8b07081a01 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 5 May 2004 22:21:48 -0700 Subject: [PATCH 0774/4284] [PATCH] udev callout for reading filesystem labels On Fri, Apr 30, 2004 at 03:29:54PM -0700, Greg KH wrote: > On Thu, Apr 29, 2004 at 11:04:46PM +0200, Kay Sievers wrote: > > Hi, > > here is a small udev toy, which enables udev to name partitions by > > its filesystem label or uuid's. > > > > The following udev rule: > > > > KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -M%M -m%m -u", SYMLINK="%c" > > > > creates a symlink with the uuid read from the filesystem. If no label or > > uuid is found the program exits with nonzero and the rule will fail. > > > > ext2, ext3, reiserfs, xfs, jfs, vfat, msdos volume labels are supported, > > ntfs and swap partitions can be recognized. > > > > It's possible to compile with klibc and the static binary takes 13kb. > > Very nice, I was wondering who was going to use that library to make > such a tool. This is even better as we can use klibc for it. Here is a update, which supports iso9660 and udf labels. Not very useful in the udev case, but I've added it for hal, so we just catch up with the latest version. --- extras/volume_id/volume_id.c | 678 +++++++++++++++++++++++++---------- extras/volume_id/volume_id.h | 53 +-- 2 files changed, 528 insertions(+), 203 deletions(-) diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index cc5475fc8d..8eba4b22f2 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -11,19 +11,19 @@ * a look at: * http://e2fsprogs.sourceforge.net. * - * 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 library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. + * This library 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 + * Lesser General Public License for more details. * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include @@ -38,6 +38,17 @@ #include "volume_id.h" +#ifdef DEBUG +#define dbg(format, arg...) \ + do { \ + printf("%s: " format "\n", __FUNCTION__ , ## arg); \ + } while (0) +#else +#define dbg(format, arg...) do {} while (0) +#endif + +#define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \ + (((__u32)(x) & 0xff00u) >> 8)) #define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \ (((__u32)(x) & 0x00ff0000u) >> 8) | \ @@ -45,20 +56,29 @@ (((__u32)(x) & 0x000000ffu) << 24)) #if (__BYTE_ORDER == __LITTLE_ENDIAN) -#define cpu_to_le32(x) (x) +#define le16_to_cpu(x) (x) +#define le32_to_cpu(x) (x) #elif (__BYTE_ORDER == __BIG_ENDIAN) -#define cpu_to_le32(x) bswap32(x) +#define le16_to_cpu(x) bswap16(x) +#define le32_to_cpu(x) bswap32(x) #endif -#define VOLUME_ID_BUFFER_SIZE 0x11000 /* reiser offset is 64k */ +/* size of superblock buffer, reiser block is at 64k */ +#define SB_BUFFER_SIZE 0x11000 +/* size of seek buffer 2k */ +#define SEEK_BUFFER_SIZE 0x800 -static void set_label(struct volume_id *id, char *buf, int count) +static void set_label_raw(struct volume_id *id, char *buf, int count) +{ + memcpy(id->label_raw, buf, count); + id->label_raw_len = count; +} + +static void set_label_string(struct volume_id *id, char *buf, int count) { int i; - memcpy(id->label, buf, count); - memcpy(id->label_string, buf, count); /* remove trailing whitespace */ @@ -90,7 +110,8 @@ set: break; case 16: sprintf(id->uuid_string, - "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", + "%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], @@ -100,29 +121,67 @@ set: } } -static int open_superblock(struct volume_id *id) +static char *get_buffer(struct volume_id *id, size_t off, size_t len) { - /* get buffer to read the first block */ - if (id->buf == NULL) { - id->buf = malloc(VOLUME_ID_BUFFER_SIZE); - if (id->buf == NULL) - return -1; + size_t buf_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) + return NULL; + } + + /* check if we need to read */ + if ((off + len) > id->sbbuf_len) { + dbg("read sbbuf len:0x%x", off + len); + lseek(id->fd, 0, SEEK_SET); + buf_len = read(id->fd, id->sbbuf, off + len); + id->sbbuf_len = buf_len; + if (buf_len < off + len) + return NULL; + } + + return &(id->sbbuf[off]); + } else { + if (len > SEEK_BUFFER_SIZE) + len = SEEK_BUFFER_SIZE; + + /* get seek buffer */ + if (id->seekbuf == NULL) { + id->seekbuf = malloc(SEEK_BUFFER_SIZE); + if (id->seekbuf == NULL) + return NULL; + } + + /* check if we need to read */ + if ((off < id->seekbuf_off) || + ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { + dbg("read seekbuf off:0x%x len:0x%x", off, len); + lseek(id->fd, off, SEEK_SET); + buf_len = read(id->fd, id->seekbuf, len); + id->seekbuf_off = off; + id->seekbuf_len = buf_len; + if (buf_len < len) + return NULL; + } + + return &(id->seekbuf[off - id->seekbuf_off]); } - - /* try to read the first 64k, but at least the first block */ - memset(id->buf, 0x00, VOLUME_ID_BUFFER_SIZE); - lseek(id->fd, 0, SEEK_SET); - if (read(id->fd, id->buf, VOLUME_ID_BUFFER_SIZE) < 0x200) - return -1; - - return 0; } -static void close_superblock(struct volume_id *id) +static void free_buffer(struct volume_id *id) { - if (id->buf != NULL) { - free(id->buf); - id->buf = NULL; + 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; } } @@ -132,34 +191,39 @@ static void close_superblock(struct volume_id *id) static int probe_ext(struct volume_id *id) { struct ext2_super_block { - __u32 s_inodes_count; - __u32 s_blocks_count; - __u32 s_r_blocks_count; - __u32 s_free_blocks_count; - __u32 s_free_inodes_count; - __u32 s_first_data_block; - __u32 s_log_block_size; - __u32 s_dummy3[7]; - unsigned char s_magic[2]; - __u16 s_state; - __u32 s_dummy5[8]; - __u32 s_feature_compat; - __u32 s_feature_incompat; - __u32 s_feature_ro_compat; - unsigned char s_uuid[16]; - char s_volume_name[16]; + __u32 inodes_count; + __u32 blocks_count; + __u32 r_blocks_count; + __u32 free_blocks_count; + __u32 free_inodes_count; + __u32 first_data_block; + __u32 log_block_size; + __u32 dummy3[7]; + unsigned char magic[2]; + __u16 state; + __u32 dummy5[8]; + __u32 feature_compat; + __u32 feature_incompat; + __u32 feature_ro_compat; + unsigned char uuid[16]; + char volume_name[16]; } *es; - es = (struct ext2_super_block *) (id->buf + EXT_SUPERBLOCK_OFFSET); - - if (es->s_magic[0] != 0123 || - es->s_magic[1] != 0357) + es = (struct ext2_super_block *) + get_buffer(id, EXT_SUPERBLOCK_OFFSET, 0x200); + if (es == NULL) return -1; - set_label(id, es->s_volume_name, 16); - set_uuid(id, es->s_uuid, 16); + if (es->magic[0] != 0123 || + es->magic[1] != 0357) + return -1; - if ((cpu_to_le32(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { + set_label_raw(id, es->volume_name, 16); + set_label_string(id, es->volume_name, 16); + set_uuid(id, es->uuid, 16); + + if ((le32_to_cpu(es->feature_compat) & + EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { id->fs_type = EXT3; id->fs_name = "ext3"; } else { @@ -175,38 +239,45 @@ static int probe_ext(struct volume_id *id) static int probe_reiser(struct volume_id *id) { struct reiser_super_block { - __u32 rs_blocks_count; - __u32 rs_free_blocks; - __u32 rs_root_block; - __u32 rs_journal_block; - __u32 rs_journal_dev; - __u32 rs_orig_journal_size; - __u32 rs_dummy2[5]; - __u16 rs_blocksize; - __u16 rs_dummy3[3]; - unsigned char rs_magic[12]; - __u32 rs_dummy4[5]; - unsigned char rs_uuid[16]; - char rs_label[16]; + __u32 blocks_count; + __u32 free_blocks; + __u32 root_block; + __u32 journal_block; + __u32 journal_dev; + __u32 orig_journal_size; + __u32 dummy2[5]; + __u16 blocksize; + __u16 dummy3[3]; + unsigned char magic[12]; + __u32 dummy4[5]; + unsigned char uuid[16]; + char label[16]; } *rs; - rs = (struct reiser_super_block *) &(id->buf[REISER1_SUPERBLOCK_OFFSET]); + rs = (struct reiser_super_block *) + get_buffer(id, REISER_SUPERBLOCK_OFFSET, 0x200); + if (rs == NULL) + return -1; - if (strncmp(rs->rs_magic, "ReIsErFs", 8) == 0) + if (strncmp(rs->magic, "ReIsEr2Fs", 9) == 0) + goto found; + if (strncmp(rs->magic, "ReIsEr3Fs", 9) == 0) goto found; - rs = (struct reiser_super_block *) &(id->buf[REISER_SUPERBLOCK_OFFSET]); + rs = (struct reiser_super_block *) + get_buffer(id, REISER1_SUPERBLOCK_OFFSET, 0x200); + if (rs == NULL) + return -1; - if (strncmp(rs->rs_magic, "ReIsEr2Fs", 9) == 0) - goto found; - if (strncmp(rs->rs_magic, "ReIsEr3Fs", 9) == 0) + if (strncmp(rs->magic, "ReIsErFs", 8) == 0) goto found; return -1; found: - set_label(id, rs->rs_label, 16); - set_uuid(id, rs->rs_uuid, 16); + set_label_raw(id, rs->label, 16); + set_label_string(id, rs->label, 16); + set_uuid(id, rs->uuid, 16); id->fs_type = REISER; id->fs_name = "reiser"; @@ -217,27 +288,30 @@ found: static int probe_xfs(struct volume_id *id) { struct xfs_super_block { - unsigned char xs_magic[4]; - __u32 xs_blocksize; - __u64 xs_dblocks; - __u64 xs_rblocks; - __u32 xs_dummy1[2]; - unsigned char xs_uuid[16]; - __u32 xs_dummy2[15]; - char xs_fname[12]; - __u32 xs_dummy3[2]; - __u64 xs_icount; - __u64 xs_ifree; - __u64 xs_fdblocks; + unsigned char magic[4]; + __u32 blocksize; + __u64 dblocks; + __u64 rblocks; + __u32 dummy1[2]; + unsigned char uuid[16]; + __u32 dummy2[15]; + char fname[12]; + __u32 dummy3[2]; + __u64 icount; + __u64 ifree; + __u64 fdblocks; } *xs; - xs = (struct xfs_super_block *) id->buf; - - if (strncmp(xs->xs_magic, "XFSB", 4) != 0) + xs = (struct xfs_super_block *) get_buffer(id, 0, 0x200); + if (xs == NULL) return -1; - set_label(id, xs->xs_fname, 12); - set_uuid(id, xs->xs_uuid, 16); + if (strncmp(xs->magic, "XFSB", 4) != 0) + return -1; + + set_label_raw(id, xs->fname, 12); + set_label_string(id, xs->fname, 12); + set_uuid(id, xs->uuid, 16); id->fs_type = XFS; id->fs_name = "xfs"; @@ -249,25 +323,29 @@ static int probe_xfs(struct volume_id *id) static int probe_jfs(struct volume_id *id) { struct jfs_super_block { - unsigned char js_magic[4]; - __u32 js_version; - __u64 js_size; - __u32 js_bsize; - __u32 js_dummy1; - __u32 js_pbsize; - __u32 js_dummy2[27]; - unsigned char js_uuid[16]; - unsigned char js_label[16]; - unsigned char js_loguuid[16]; + unsigned char magic[4]; + __u32 version; + __u64 size; + __u32 bsize; + __u32 dummy1; + __u32 pbsize; + __u32 dummy2[27]; + unsigned char uuid[16]; + unsigned char label[16]; + unsigned char loguuid[16]; } *js; - js = (struct jfs_super_block *) &(id->buf[JFS_SUPERBLOCK_OFFSET]); - - if (strncmp(js->js_magic, "JFS1", 4) != 0) + js = (struct jfs_super_block *) + get_buffer(id, JFS_SUPERBLOCK_OFFSET, 0x200); + if (js == NULL) return -1; - set_label(id, js->js_label, 16); - set_uuid(id, js->js_uuid, 16); + if (strncmp(js->magic, "JFS1", 4) != 0) + return -1; + + set_label_raw(id, js->label, 16); + set_label_string(id, js->label, 16); + set_uuid(id, js->uuid, 16); id->fs_type = JFS; id->fs_name = "jfs"; @@ -278,46 +356,49 @@ static int probe_jfs(struct volume_id *id) static int probe_vfat(struct volume_id *id) { struct vfat_super_block { - unsigned char vs_ignored[3]; - unsigned char vs_sysid[8]; - unsigned char vs_sector_size[2]; - __u8 vs_cluster_size; - __u16 vs_reserved; - __u8 vs_fats; - unsigned char vs_dir_entries[2]; - unsigned char vs_sectors[2]; - unsigned char vs_media; - __u16 vs_fat_length; - __u16 vs_secs_track; - __u16 vs_heads; - __u32 vs_hidden; - __u32 vs_total_sect; - __u32 vs_fat32_length; - __u16 vs_flags; - __u8 vs_version[2]; - __u32 vs_root_cluster; - __u16 vs_insfo_sector; - __u16 vs_backup_boot; - __u16 vs_reserved2[6]; - unsigned char vs_unknown[3]; - unsigned char vs_serno[4]; - char vs_label[11]; - unsigned char vs_magic[8]; - unsigned char vs_dummy2[164]; - unsigned char vs_pmagic[2]; + unsigned char ignored[3]; + unsigned char sysid[8]; + unsigned char sector_size[2]; + __u8 cluster_size; + __u16 reserved; + __u8 fats; + unsigned char dir_entries[2]; + unsigned char sectors[2]; + unsigned char media; + __u16 fat_length; + __u16 secs_track; + __u16 heads; + __u32 hidden; + __u32 total_sect; + __u32 fat32_length; + __u16 flags; + __u8 version[2]; + __u32 root_cluster; + __u16 insfo_sector; + __u16 backup_boot; + __u16 reserved2[6]; + unsigned char unknown[3]; + unsigned char serno[4]; + char label[11]; + unsigned char magic[8]; + unsigned char dummy2[164]; + unsigned char pmagic[2]; } *vs; - vs = (struct vfat_super_block *) id->buf; + vs = (struct vfat_super_block *) get_buffer(id, 0, 0x200); + if (vs == NULL) + return -1; - if (strncmp(vs->vs_magic, "MSWIN", 5) == 0) + if (strncmp(vs->magic, "MSWIN", 5) == 0) goto found; - if (strncmp(vs->vs_magic, "FAT32 ", 8) == 0) + if (strncmp(vs->magic, "FAT32 ", 8) == 0) goto found; return -1; found: - memcpy(id->label, vs->vs_label, 11); - memcpy(id->uuid, vs->vs_serno, 4); + set_label_raw(id, vs->label, 11); + set_label_string(id, vs->label, 11); + set_uuid(id, vs->serno, 4); id->fs_type = VFAT; id->fs_name = "vfat"; @@ -328,41 +409,44 @@ found: static int probe_msdos(struct volume_id *id) { struct msdos_super_block { - unsigned char ms_ignored[3]; - unsigned char ms_sysid[8]; - unsigned char ms_sector_size[2]; - __u8 ms_cluster_size; - __u16 ms_reserved; - __u8 ms_fats; - unsigned char ms_dir_entries[2]; - unsigned char ms_sectors[2]; - unsigned char ms_media; - __u16 ms_fat_length; - __u16 ms_secs_track; - __u16 ms_heads; - __u32 ms_hidden; - __u32 ms_total_sect; - unsigned char ms_unknown[3]; - unsigned char ms_serno[4]; - char ms_label[11]; - unsigned char ms_magic[8]; - unsigned char ms_dummy2[192]; - unsigned char ms_pmagic[2]; + unsigned char ignored[3]; + unsigned char sysid[8]; + unsigned char sector_size[2]; + __u8 cluster_size; + __u16 reserved; + __u8 fats; + unsigned char dir_entries[2]; + unsigned char sectors[2]; + unsigned char media; + __u16 fat_length; + __u16 secs_track; + __u16 heads; + __u32 hidden; + __u32 total_sect; + unsigned char unknown[3]; + unsigned char serno[4]; + char label[11]; + unsigned char magic[8]; + unsigned char dummy2[192]; + unsigned char pmagic[2]; } *ms; - ms = (struct msdos_super_block *) id->buf; + ms = (struct msdos_super_block *) get_buffer(id, 0, 0x200); + if (ms == NULL) + return -1; - if (strncmp(ms->ms_magic, "MSDOS", 5) == 0) + if (strncmp(ms->magic, "MSDOS", 5) == 0) goto found; - if (strncmp(ms->ms_magic, "FAT16 ", 8) == 0) + if (strncmp(ms->magic, "FAT16 ", 8) == 0) goto found; - if (strncmp(ms->ms_magic, "FAT12 ", 8) == 0) + if (strncmp(ms->magic, "FAT12 ", 8) == 0) goto found; return -1; found: - set_label(id, ms->ms_label, 11); - set_uuid(id, ms->ms_serno, 4); + set_label_raw(id, ms->label, 11); + set_label_string(id, ms->label, 11); + set_uuid(id, ms->serno, 4); id->fs_type = MSDOS; id->fs_name = "msdos"; @@ -370,6 +454,218 @@ found: return 0; } +#define UDF_VSD_OFFSET 0x8000 +static int probe_udf(struct volume_id *id) +{ + struct volume_descriptor { + struct descriptor_tag { + __u16 id; + __u16 version; + unsigned char checksum; + unsigned char reserved; + __u16 serial; + __u16 crc; + __u16 crc_len; + __u32 location; + } tag; + union { + struct anchor_descriptor { + __u32 length; + __u32 location; + } anchor; + struct primary_descriptor { + __u32 seq_num; + __u32 desc_num; + struct dstring { + char clen; + char c[31]; + } ident; + } primary; + } type; + } *vd; + + struct volume_structure_descriptor { + unsigned char type; + char id[5]; + unsigned char version; + } *vsd; + + size_t bs; + size_t b; + int type; + int count; + int loc; + int clen; + int i,j; + int c; + + vsd = (struct volume_structure_descriptor *) + get_buffer(id, UDF_VSD_OFFSET, 0x200); + if (vsd == NULL) + return -1; + + if (strncmp(vsd->id, "NSR02", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "NSR03", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "BEA01", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "BOOT2", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "CD001", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "CDW02", 5) == 0) + goto blocksize; + if (strncmp(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 *) + get_buffer(id, 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 *) + get_buffer(id, 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 (strncmp(vsd->id, "NSR02", 5) == 0) + goto anchor; + if (strncmp(vsd->id, "NSR03", 5) == 0) + goto anchor; + } + return -1; + +anchor: + /* read anchor volume descriptor */ + vd = (struct volume_descriptor *) get_buffer(id, 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 *) + get_buffer(id, (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: + 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) { + set_label_string(id, vd->type.primary.ident.c, 31); + } else if (clen == 16) { + /* convert unicode OSTA dstring to UTF-8 */ + j = 0; + for (i = 0; i < 32; i += 2) { + c = (vd->type.primary.ident.c[i] << 8) | + vd->type.primary.ident.c[i+1]; + if (c == 0) { + id->label_string[j] = '\0'; + break; + }else if (c < 0x80U) { + id->label_string[j++] = (char) c; + } else if (c < 0x800U) { + id->label_string[j++] = (char) (0xc0 | (c >> 6)); + id->label_string[j++] = (char) (0x80 | (c & 0x3f)); + } else { + id->label_string[j++] = (char) (0xe0 | (c >> 12)); + id->label_string[j++] = (char) (0x80 | ((c >> 6) & 0x3f)); + id->label_string[j++] = (char) (0x80 | (c & 0x3f)); + } + } + } + +found: + id->fs_type = UDF; + id->fs_name = "udf"; + + return 0; +} + +#define ISO_SUPERBLOCK_OFFSET 0x8000 +static int probe_iso9660(struct volume_id *id) +{ + union iso_super_block { + struct iso_header { + unsigned char type; + char id[5]; + unsigned char version; + unsigned char unused1; + char system_id[32]; + char volume_id[32]; + } iso; + struct hs_header { + char foo[8]; + unsigned char type; + char id[4]; + unsigned char version; + } hs; + } *is; + + is = (union iso_super_block *) + get_buffer(id, ISO_SUPERBLOCK_OFFSET, 0x200); + if (is == NULL) + return -1; + + if (strncmp(is->iso.id, "CD001", 5) == 0) { + set_label_raw(id, is->iso.volume_id, 32); + set_label_string(id, is->iso.volume_id, 32); + goto found; + } + if (strncmp(is->hs.id, "CDROM", 5) == 0) + goto found; + return -1; + +found: + id->fs_type = ISO9660; + id->fs_name = "iso9660"; + + return 0; +} + static int probe_ntfs(struct volume_id *id) { struct ntfs_super_block { @@ -377,7 +673,9 @@ static int probe_ntfs(struct volume_id *id) char oem_id[4]; } *ns; - ns = (struct ntfs_super_block *) id->buf; + ns = (struct ntfs_super_block *) get_buffer(id, 0, 0x200); + if (ns == NULL) + return -1; if (strncmp(ns->oem_id, "NTFS", 4) != 0) return -1; @@ -388,15 +686,21 @@ static int probe_ntfs(struct volume_id *id) return 0; } +#define LARGEST_PAGESIZE 0x4000 static int probe_swap(struct volume_id *id) { - int magic; + char *sig; + size_t page; /* huhh, the swap signature is on the end of the PAGE_SIZE */ - for (magic = 0x1000; magic <= 0x4000; magic <<= 1) { - if (strncmp(&(id->buf[magic -10]), "SWAP-SPACE", 10) == 0) + for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { + sig = get_buffer(id, page-10, 10); + if (sig == NULL) + return -1; + + if (strncmp(sig, "SWAP-SPACE", 10) == 0) goto found; - if (strncmp(&(id->buf[magic -10]), "SWAPSPACE2", 10) == 0) + if (strncmp(sig, "SWAPSPACE2", 10) == 0) goto found; } return -1; @@ -416,9 +720,6 @@ int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type) if (id == NULL) return -EINVAL; - if (open_superblock(id) != 0) - return -EACCES; - switch (fs_type) { case EXT3: case EXT2: @@ -439,13 +740,22 @@ int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type) case VFAT: rc = probe_vfat(id); break; + case UDF: + rc = probe_udf(id); + break; + case ISO9660: + rc = probe_iso9660(id); + break; case NTFS: rc = probe_ntfs(id); break; case SWAP: rc = probe_swap(id); break; + case ALL: default: + /* fill buffer with maximum */ + get_buffer(id, 0, SB_BUFFER_SIZE); rc = probe_ext(id); if (rc == 0) break; @@ -462,6 +772,12 @@ int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type) if (rc == 0) break; rc = probe_vfat(id); + if (rc == 0) + break; + rc = probe_udf(id); + if (rc == 0) + break; + rc = probe_iso9660(id); if (rc == 0) break; rc = probe_ntfs(id); @@ -473,8 +789,10 @@ int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type) rc = -1; } + /* If the filestystem in recognized, we free the allocated buffers, + otherwise they will stay in place for the possible next probe call */ if (rc == 0) - close_superblock(id); + free_buffer(id); return rc; } @@ -544,7 +862,7 @@ void volume_id_close(struct volume_id *id) if (id->fd_close != 0) close(id->fd); - close_superblock(id); + free_buffer(id); free(id); } diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index a0d2acda22..2f20244c7c 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -3,27 +3,27 @@ * * 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. - * - * 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. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 001 +#define VOLUME_ID_VERSION 002 -#define VOLUME_ID_LABEL_SIZE 16 +#define VOLUME_ID_LABEL_SIZE 32 #define VOLUME_ID_UUID_SIZE 16 #define VOLUME_ID_UUID_STRING_SIZE 37 #define VOLUME_ID_PATH_MAX 255 @@ -38,20 +38,27 @@ enum filesystem_type { JFS, MSDOS, VFAT, + UDF, + ISO9660, NTFS, SWAP }; struct volume_id { - char label[VOLUME_ID_LABEL_SIZE]; - char label_string[VOLUME_ID_LABEL_SIZE+1]; - unsigned char uuid[VOLUME_ID_UUID_SIZE]; - char uuid_string[VOLUME_ID_UUID_STRING_SIZE]; - enum filesystem_type fs_type; - char *fs_name; - int fd; - char *buf; - int fd_close; + char label_raw[VOLUME_ID_LABEL_SIZE]; + size_t label_raw_len; + char label_string[VOLUME_ID_LABEL_SIZE+1]; + unsigned char uuid[VOLUME_ID_UUID_SIZE]; + char uuid_string[VOLUME_ID_UUID_STRING_SIZE]; + enum filesystem_type fs_type; + char *fs_name; + int fd; + char *sbbuf; + size_t sbbuf_len; + char *seekbuf; + size_t seekbuf_off; + size_t seekbuf_len; + int fd_close; }; /* open volume by already open file descriptor */ From 7f639ff99e3857870e4e0f41843dff7ad48ad784 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 5 May 2004 22:32:05 -0700 Subject: [PATCH 0775/4284] [PATCH] add udev.permissions.slackware file. From Lucas de Souza Santos --- etc/udev/udev.permissions.slackware | 133 ++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 etc/udev/udev.permissions.slackware diff --git a/etc/udev/udev.permissions.slackware b/etc/udev/udev.permissions.slackware new file mode 100644 index 0000000000..2edc1aaa53 --- /dev/null +++ b/etc/udev/udev.permissions.slackware @@ -0,0 +1,133 @@ +#name:user:group:mode +pl2303:500:500:0666 +visor:root:uucp:0666 +camera*:500:500:0666 + +# console devices +console:root:tty:0600 +tty[0-9][0-9]*:root:tty:0666 +vcs*:root:tty:0620 +tty[CIS]*:root:uucp:0660 +ttyUB[0-9]:root:uucp:0660 +ttyUSB0:root:uucp:0660 +ttyUSB1:root:uucp:0666 + +# pty devices +ptmx:root:tty:0666 +pty[p-za-e][0-9a-f]*:root:tty:0666 +tty[p-za-e][0-9a-f]*:root:tty:0666 +cu[abiu]*:root:uucp:0660 + +# sound devices +audio*:root:sys:0662 +beep:root:root:0644 +dsp*:root:sys:0662 +midi*:root:sys:0662 +mixer*:root:sys:0666 +music:root:sys:0662 +sequencer*:root:sys:0662 +snd/*:root:root:0666 +sndstat:root:sys:0662 +speaker:root:root:0644 +sound/*:root:root:0666 +admmidi*:root:root:0666 +adsp*:root:root:0666 +aload*:root:root:0666 +amidi*:root:root:0666 +amixer*:root:root:0666 + +# input devices (mouse, joystick, etc) +input/*:root:root:0644 +input/js*:root:games:0666 +djs[0-3]:root:games:0660 +psaux:root:sys:0660 +crash:roor:root:0660 +logibm:root:sys:0660 +jbm:root:sys:0660 +hwtrap:root:root:0644 +inportbm:root:sys:0660 +sexec:root:root:0660 +jsflash:roo:root:0660 + +# power manager device +apm_bios:root:root:0644 + +# printer device +lp[0-9]:root:lp:0660 +parport*:root:root:0660 + +# video devices +dri/card[0-9]*:root:root:0666 +fb[0-9]:root:tty:0660 +agpgart:root:root:0660 +nvidia*:root:root:0666 +video*:root:sys:0660 + +# DISK devices +ed[ab]*:root:disk:0640 +gscd0:root:disk:0640 +initrd:root:disk:0640 +lmscd:root:disk:0640 +mcd*:root:disk:0640 +md*:root:disk:0660 +mtd*:root:disk:0640 +userdma:root:root:0660 + +# floppy devices +fd[0-3]*:root:floppy:0660 + +# IDE devices (hd, cdrom) +hd*:root:disk:0660 +ht0:root:disk:0640 + +# RAID IDE +ataraid[0-9]*:root:disk:0660 +ataraid/*:root:disk:0660 + +# SCSI devices +scsi/*/cd:root:disk:0660 +scsi/*:root:disk:0660 +sd[a-h]*:root:disk:0640 +s[rt][0-9]*:root:disk:0640 +scd*:root:disk:0660 + +# generic scsi devices +sg*:root:root:0600 + +# old CD-ROM +sbpcd*:root:disk:0640 + +# loop devices +loop[0-9]*:root:disk:0660 + +# network block devices +nb[0-7]:root:disk:0660 +nht0:root:disk:0640 +npt[0-3]:root:disk:0660 +n[qrs]*:root:disk:0640 + +# memory access devices +kmem:root:kmem:0640 +mem:root:kmem:0640 +null:root:sys:0666 +nvram:root:root:0640 +port:root:kmem:0640 +ram[0-9]*:root:disk:0640 +random:root:root:0644 +rtc:root:root:0444 +urandom:root:root:0644 +full:root:sys:0666 +zero:root:root:0664 +raw/*:root:disk:0660 +modreq:root:root:0644 +msr:root:root:0660 +profile*:root:root:0640 + +# ISDN devices +isdn*:root:tty:0660 + +# net devices +ippp*:root:root:0644 +ipstate:root:root:0660 +spx:root:root:0644 +fwmonitor:root:root:0660 From cde5a756ce10530136b8d387346c48260a69dbfb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 12 May 2004 00:52:52 -0700 Subject: [PATCH 0776/4284] [PATCH] udev_volume_id update Here is a update to extras/volume_id/* o The device is now specified by the DEVPATH in the environment, it's no longer needed to pass the major/minor to the callout. o leading spaces and slashes are now removed from the returned string and spaces are replaced by underscore, to not to confuse udev. o Arnd Bergmann provided the code to recognize s390 dasd disk labels. The -d switch tries to read the main block device instead of the partition. --- extras/volume_id/Makefile | 17 ++- extras/volume_id/README | 49 +++++++ extras/volume_id/dasdlabel.c | 178 ++++++++++++++++++++++++++ extras/volume_id/dasdlabel.h | 26 ++++ extras/volume_id/s390-dasd.rules | 7 + extras/volume_id/udev_volume_id.c | 206 +++++++++++++++++++++++------- extras/volume_id/volume_id.c | 5 +- 7 files changed, 437 insertions(+), 51 deletions(-) create mode 100644 extras/volume_id/README create mode 100644 extras/volume_id/dasdlabel.c create mode 100644 extras/volume_id/dasdlabel.h create mode 100644 extras/volume_id/s390-dasd.rules diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 6a3d2866c4..307fdc2f16 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -1,6 +1,6 @@ # Makefile for udev_volume_id # -# Copyright (C) 2004 Kay Sievers +# 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 @@ -29,8 +29,19 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} override CFLAGS+=-Wall -fno-builtin -OBJS = volume_id.o udev_volume_id.o -HEADERS = volume_id.h + +SYSFS = ../../libsysfs/sysfs_bus.o \ + ../../libsysfs/sysfs_class.o \ + ../../libsysfs/sysfs_device.o \ + ../../libsysfs/sysfs_dir.o \ + ../../libsysfs/sysfs_driver.o \ + ../../libsysfs/sysfs_utils.o \ + ../../libsysfs/dlist.o + + + +OBJS = volume_id.o udev_volume_id.o dasdlabel.o $(SYSFS) +HEADERS = volume_id.h dasdlabel.h $(OBJS): $(HEADERS) diff --git a/extras/volume_id/README b/extras/volume_id/README new file mode 100644 index 0000000000..9d881a1a05 --- /dev/null +++ b/extras/volume_id/README @@ -0,0 +1,49 @@ + +udev_volume_id - partition, filesystem, disklabel reader + +This program is normally called from a udev rule, to provide udev with the +name, uuid or the filesystem type of a partition to name a device node. +udev_volume_id opens the blockdevice specified by the environment variable +DEVPATH and searches for a filesystem superblock to read the label. The +following commandline switches are supported to specify what udev_volume_id +should print to stdout: + + no option prints all values + -h prints help text + -l prints the label of the partition + -u prints the uuid of the partition + -d read disk instead of partition + +If -d is specified udev_volume_id tries to read the label from the main +block device where the partition belongs to. For now this is only useful +for s390 dasd labels. + +udev_volume_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. + +The following rule will create a symlink named with the label string: + KERNEL="[hs]d*", PROGRAM="/sbin/udev_volume_id -l", SYMLINK="%c" + +If no label is found udev_volume_id exits with nonzero and the rule will be +ignored. + +To give it a try, you may call it on the commandline: + + [root@pim udev.kay]# DEVPATH=/block/hda/hda3 extras/volume_id/udev_volume_id + T:ext3 + L:Music Store + N:Music_Store + U:d2da42b5-bbd9-44eb-a72c-cc4542fcb71e + + [root@pim udev.kay]# DEVPATH=/block/hda/hda3 extras/volume_id/udev_volume_id -l + Music_Store + + [root@pim udev.kay]# DEVPATH=/block/hda/hda1 extras/volume_id/udev_volume_id -t + swap + + +Please send any comment/questions/concerns to me or: + linux-hotplug-devel@lists.sourceforge.net + +Kay Sievers diff --git a/extras/volume_id/dasdlabel.c b/extras/volume_id/dasdlabel.c new file mode 100644 index 0000000000..cbbe88179d --- /dev/null +++ b/extras/volume_id/dasdlabel.c @@ -0,0 +1,178 @@ +/* + * dasdlabel - read label from s390 block device + * + * Copyright (C) 2004 Arnd Bergmann + * + * 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. + * + */ + + +#include +#include +#include +#include +#include +#include + +#include "dasdlabel.h" + +static unsigned char EBCtoASC[256] = +{ +/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ + 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, +/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ + 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC + -ENP ->LF */ + 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, +/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB + -IUS */ + 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC + -INP */ + 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, +/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL + -SW */ + 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, +/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ + 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, +/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ + 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, +/* 0x40 SP RSP ä ---- */ + 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, +/* 0x48 . < ( + | */ + 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, +/* 0x50 & ---- */ + 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, +/* 0x58 ß ! $ * ) ; */ + 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, +/* 0x60 - / ---- Ä ---- ---- ---- */ + 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, +/* 0x68 ---- , % _ > ? */ + 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, +/* 0x70 --- ---- ---- ---- ---- ---- ---- */ + 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* 0x78 * ` : # @ ' = " */ + 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, +/* 0x80 * a b c d e f g */ + 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +/* 0x88 h i ---- ---- ---- */ + 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, +/* 0x90 ° j k l m n o p */ + 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, +/* 0x98 q r ---- ---- */ + 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, +/* 0xA0 ~ s t u v w x */ + 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, +/* 0xA8 y z ---- ---- ---- ---- */ + 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, +/* 0xB0 ^ ---- § ---- */ + 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, +/* 0xB8 ---- [ ] ---- ---- ---- ---- */ + 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, +/* 0xC0 { A B C D E F G */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, +/* 0xC8 H I ---- ö ---- */ + 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, +/* 0xD0 } J K L M N O P */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, +/* 0xD8 Q R ---- ü */ + 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, +/* 0xE0 \ S T U V W X */ + 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, +/* 0xE8 Y Z ---- Ö ---- ---- ---- */ + 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, +/* 0xF0 0 1 2 3 4 5 6 7 */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */ + 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 +}; + +static void vtoc_ebcdic_dec (unsigned char *source, unsigned char *target, int l) +{ + int i; + + for (i = 0; i < l; i++) + target[i]=EBCtoASC[(unsigned char)(source[i])]; +} + +/* + * struct dasd_information_t + * represents any data about the data, which is visible to userspace + */ +typedef struct dasd_information_t { + unsigned int devno; /* S/390 devno */ + unsigned int real_devno; /* for aliases */ + unsigned int schid; /* S/390 subchannel identifier */ + unsigned int cu_type : 16; /* from SenseID */ + unsigned int cu_model : 8; /* from SenseID */ + unsigned int dev_type : 16; /* from SenseID */ + unsigned int dev_model : 8; /* from SenseID */ + unsigned int open_count; + unsigned int req_queue_len; + unsigned int chanq_len; /* length of chanq */ + char type[4]; /* from discipline.name, 'none' for unknown */ + unsigned int status; /* current device level */ + unsigned int label_block; /* where to find the VOLSER */ + unsigned int FBA_layout; /* fixed block size (like AIXVOL) */ + unsigned int characteristics_size; + unsigned int confdata_size; + char characteristics[64]; /* from read_device_characteristics */ + char configuration_data[256]; /* from read_configuration_data */ +} dasd_information_t; + +#define _IOC_NRBITS 8 +#define _IOC_TYPEBITS 8 +#define _IOC_SIZEBITS 14 +#define _IOC_DIRBITS 2 +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) +#define _IOC_NRSHIFT 0 +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) +#define DASD_IOCTL_LETTER 'D' + +#define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) +#define BLKSSZGET _IO(0x12,104) + +int probe_ibm_partition(int fd, char *out) +{ + int blocksize; + dasd_information_t info; + char name[7] = {0,}; + unsigned char data[16]; + + if (ioctl(fd, BIODASDINFO, (unsigned long)&info) != 0) + return -1; + + if (ioctl(fd, BLKSSZGET, (unsigned long)&blocksize)) + return -1; + + lseek(fd, info.label_block * blocksize, SEEK_SET); + if (read(fd, &data, 16) != 16) + return -1; + + if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) + strncpy(name, data + 8, 6); + else + strncpy(name, data + 4, 6); + + vtoc_ebcdic_dec(name, out, 6); + + return 0; +} diff --git a/extras/volume_id/dasdlabel.h b/extras/volume_id/dasdlabel.h new file mode 100644 index 0000000000..1501d3ff89 --- /dev/null +++ b/extras/volume_id/dasdlabel.h @@ -0,0 +1,26 @@ +/* + * dasdlabel - read label from s390 block device + * + * Copyright (C) 2004 Arnd Bergmann + * + * 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 _DASDLABEL_H_ +#define _DASDLABEL_H_ + +extern int probe_ibm_partition(int fd, char *out); + +#endif diff --git a/extras/volume_id/s390-dasd.rules b/extras/volume_id/s390-dasd.rules new file mode 100644 index 0000000000..a870d87e04 --- /dev/null +++ b/extras/volume_id/s390-dasd.rules @@ -0,0 +1,7 @@ +# s390 block devices named by disk label +KERNEL="dasd*[a-z]", PROGRAM="/sbin/udev_volume_id -d -l" RESULT="[0-9A-Z]*", SYMLINK="dasd/%c/disc dasd/%b/disc" +KERNEL="dasd*[0-9]", PROGRAM="/sbin/udev_volume_id -d -l" RESULT="[0-9A-Z]*", SYMLINK="dasd/%c/part%n dasd/%b/part%n" +KERNEL="dasd*[a-z]", SYMLINK="dasd/%b/disc" +KERNEL="dasd*[0-9]", SYMLINK="dasd/%b/part%n" +KERNEL="dcssblk*", NAME="%k", SYMLINK="dcssblk/%b" + diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 88779ccd36..18915cb62b 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -4,7 +4,7 @@ * Copyright (C) 2004 Kay Sievers * * sample udev rule for creation of a symlink with the filsystem uuid: - * KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -M%M -m%m -u", SYMLINK="%c" + * KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -u", SYMLINK="%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 @@ -24,21 +24,75 @@ #include #include #include +#include +#include "../../libsysfs/sysfs/libsysfs.h" +#include "../../udev_lib.h" +#include "../../logging.h" #include "volume_id.h" +#include "dasdlabel.h" + +#ifdef LOG +unsigned char logname[LOGNAME_SIZE]; +void log_message(int level, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif + +static struct volume_id *open_classdev(struct sysfs_class_device *class_dev) +{ + struct volume_id *vid; + struct sysfs_attribute *attr; + int major, minor; + + attr = sysfs_get_classdev_attr(class_dev, "dev"); + + if (attr == NULL) { + printf("error reading 'dev' attribute\n"); + return NULL; + } + + if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) { + printf("error getting major/minor number\n"); + return NULL; + } + + vid = volume_id_open_dev_t(makedev(major, minor)); + if (vid == NULL) { + printf("error open volume\n"); + return NULL; + } + + return vid; +} int main(int argc, char *argv[]) { - struct volume_id *vid; - const char help[] = "usage: udev_volume_id -m -M [-t|-l|-u]\n"; - int major = -1; - int minor = -1; - char *tail; - static const char short_options[] = "M:m:htlu"; + const char help[] = "usage: udev_volume_id [-t|-l|-u|-d]\n" + " -t filesystem type\n" + " -l filesystem label\n" + " -u filesystem uuid\n" + " -d disk label from main device\n" + "\n"; + static const char short_options[] = "htlud"; int option; - char print = '\0'; - int rc; - + char sysfs_path[SYSFS_PATH_MAX]; + char dev_path[SYSFS_PATH_MAX]; + struct sysfs_class_device *class_dev = NULL; + struct sysfs_class_device *class_dev_parent = NULL; + struct volume_id *vid = NULL; + char *devpath; + char probe = 'p'; + char print = 'a'; + char dasd_label[7]; + static char name[VOLUME_ID_LABEL_SIZE]; + int len, i, j; + int rc = 1; while (1) { option = getopt(argc, argv, short_options); @@ -46,29 +100,18 @@ int main(int argc, char *argv[]) break; switch (option) { - case 'M': - major = (int) strtoul(optarg, &tail, 10); - if (tail[0] != '\0') { - printf("invalid major\n"); - exit(1); - } - break; - case 'm': - minor = (int) strtoul(optarg, &tail, 10); - if (tail[0] != '\0') { - printf("invalid minor\n"); - exit(1); - } - break; case 't': print = 't'; - break; + continue; case 'l': print = 'l'; - break; + continue; case 'u': print = 'u'; - break; + continue; + case 'd': + probe = 'd'; + continue; case 'h': case '?': default: @@ -77,44 +120,115 @@ int main(int argc, char *argv[]) } } - if (major == -1 || minor == -1) { - printf(help); - exit(1); + devpath = getenv("DEVPATH"); + if (devpath == NULL) { + printf("error DEVPATH empty\n"); + goto exit; } - vid = volume_id_open_dev_t(makedev(major, minor)); - if (vid == NULL) { - printf("error open volume\n"); - exit(1); + if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { + printf("error getting sysfs mount path\n"); + goto exit; } - rc = volume_id_probe(vid, ALL); - if (rc != 0) { - printf("error probing volume\n"); - exit(1); + strfieldcpy(dev_path, sysfs_path); + strfieldcat(dev_path, devpath); + + class_dev = sysfs_open_class_device_path(dev_path); + if (class_dev == NULL) { + printf("error getting class device\n"); + goto exit; } + switch(probe) { + case 'p' : + /* open block device */ + vid = open_classdev(class_dev); + if (vid == NULL) + goto exit; + if (volume_id_probe(vid, ALL) == 0) + goto print; + break; + case 'd' : + /* if we are on a partition, close it and open main block device */ + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent != NULL) { + volume_id_close(vid); + vid = open_classdev(class_dev_parent); + } else { + vid = open_classdev(class_dev_parent); + } + if (vid == NULL) + goto exit; + if (probe_ibm_partition(vid->fd, dasd_label) == 0) { + vid->fs_name = "dasd"; + strncpy(vid->label_string, dasd_label, 6); + vid->label_string[6] = '\0'; + goto print; + } + break; + } + + printf("unknown volume type\n"); + goto exit; + + +print: + len = strnlen(vid->label_string, VOLUME_ID_LABEL_SIZE); + + /* remove trailing spaces */ + while (len > 0 && isspace(vid->label_string[len-1])) + len--; + name[len] = '\0'; + + /* substitute chars */ + i = 0; + j = 0; + while (j < len) { + switch(vid->label_string[j]) { + case '/' : + break; + case ' ' : + name[i++] = '_'; + break; + default : + name[i++] = vid->label_string[j]; + } + j++; + } + name[i] = '\0'; + switch (print) { case 't': printf("%s\n", vid->fs_name); break; case 'l': - if (vid->label_string[0] == '\0') - exit(2); - printf("%s\n", vid->label_string); + if (name[0] == '\0') { + rc = 2; + goto exit; + } + printf("%s\n", name); break; case 'u': - if (vid->uuid_string[0] == '\0') - exit(2); + if (vid->uuid_string[0] == '\0') { + rc = 2; + goto exit; + } printf("%s\n", vid->uuid_string); break; - default: + case 'a': printf("T:%s\n", vid->fs_name); printf("L:%s\n", vid->label_string); + printf("N:%s\n", name); printf("U:%s\n", vid->uuid_string); } + rc = 0; - volume_id_close(vid); +exit: + if (class_dev != NULL) + sysfs_close_class_device(class_dev); + if (vid != NULL) + volume_id_close(vid); - exit(0); + exit(rc); } diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index 8eba4b22f2..dcc341c4dd 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -82,7 +82,7 @@ static void set_label_string(struct volume_id *id, char *buf, int count) memcpy(id->label_string, buf, count); /* remove trailing whitespace */ - i = strlen(id->label_string); + i = strnlen(id->label_string, count); while (i--) { if (! isspace(id->label_string[i])) break; @@ -839,10 +839,11 @@ struct volume_id *volume_id_open_dev_t(dev_t devt) char tmp_node[VOLUME_ID_PATH_MAX]; snprintf(tmp_node, VOLUME_ID_PATH_MAX, - "/tmp/volume-%u-%u", major(devt), minor(devt)); + "/tmp/volume-%u-%u-%u", getpid(), major(devt), minor(devt)); tmp_node[VOLUME_ID_PATH_MAX] = '\0'; /* create tempory node to open the block device */ + unlink(tmp_node); if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0) return NULL; From d7a4f62d3d2a9c13239131da57d23e85eab23529 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 14 May 2004 23:03:15 -0700 Subject: [PATCH 0777/4284] [PATCH] Deleted the udev_dbus extra as it didn't really work properly and HAL has a real solution now. --- extras/dbus/Makefile | 68 ------ extras/dbus/dbus-listen-test.py | 26 --- .../dbus-1/system.d/udev_sysbus_policy.conf | 23 --- extras/dbus/udev_dbus.c | 195 ------------------ 4 files changed, 312 deletions(-) delete mode 100644 extras/dbus/Makefile delete mode 100644 extras/dbus/dbus-listen-test.py delete mode 100644 extras/dbus/etc/dbus-1/system.d/udev_sysbus_policy.conf delete mode 100644 extras/dbus/udev_dbus.c diff --git a/extras/dbus/Makefile b/extras/dbus/Makefile deleted file mode 100644 index 0cfc650c4b..0000000000 --- a/extras/dbus/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -# Makefile for udev_dbus -# -# Copyright (C) 2004 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. -# - -# Set the following to `true' to log the debug -# and make a unstripped, unoptimized binary. -# Leave this set to `false' for production use. -DEBUG = false - -PROG = udev_dbus - -all: $(PROG) - -# override this to make udev look in a different location for it's config files -prefix = -exec_prefix = ${prefix} -etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin -mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default -dbusdir = ${etcdir}/dbus-1/system.d -configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ -srcdir = . - -INSTALL = /usr/bin/install -c -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_SCRIPT = ${INSTALL_PROGRAM} - -override CFLAGS+=-Wall -fno-builtin - -override CFLAGS += -DUSE_DBUS -override CFLAGS += $(shell pkg-config --cflags dbus-1) -override LDFLAGS += $(shell pkg-config --libs dbus-1) -OBJS = udev_dbus.o - -$(PROG): $(OBJS) - $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) ../../udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) - -clean: - rm -f $(PROG) $(OBJS) - -spotless: clean - - -install-dbus-policy: - $(INSTALL) -d $(DESTDIR)$(dbusdir) - -uninstall-dbus-policy: - - rm $(DESTDIR)$(dbusdir)/udev_sysbus_policy.conf - -install: install-dbus-policy all - $(INSTALL_DATA) etc/dbus-1/system.d/udev_sysbus_policy.conf $(DESTDIR)$(dbusdir) - $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(usrsbindir)/$(PROG) - - ln -s -f $(DESTDIR)$(usrsbindir)/$(PROG) $(DESTDIR)$(devddir)/$(PROG).dev - -uninstall: uninstall-dbus-policy - - rm $(DESTDIR)$(devddir)/$(PROG).dev - - rm $(DESTDIR)$(usrsbindir)/$(PROG) - diff --git a/extras/dbus/dbus-listen-test.py b/extras/dbus/dbus-listen-test.py deleted file mode 100644 index 6a68b5d2aa..0000000000 --- a/extras/dbus/dbus-listen-test.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/python - -# receives and prints the messages udev_dbus sent -# to the org.kernel.udev.NodeMonitor interface - -import dbus -import gtk - -def udev_signal_received(dbus_iface, member, service, object_path, message): - [filename, sysfs_path] = message.get_args_list() - if member=='NodeCreated': - print 'Node %s created for %s'%(filename, sysfs_path) - elif member=='NodeDeleted': - print 'Node %s deleted for %s'%(filename, sysfs_path) - -def main(): - bus = dbus.Bus(dbus.Bus.TYPE_SYSTEM) - bus.add_signal_receiver(udev_signal_received, - 'org.kernel.udev.NodeMonitor', # interface - 'org.kernel.udev', # service - '/org/kernel/udev/NodeMonitor') # object - gtk.mainloop() - -if __name__ == '__main__': - main() - diff --git a/extras/dbus/etc/dbus-1/system.d/udev_sysbus_policy.conf b/extras/dbus/etc/dbus-1/system.d/udev_sysbus_policy.conf deleted file mode 100644 index b2660e65cf..0000000000 --- a/extras/dbus/etc/dbus-1/system.d/udev_sysbus_policy.conf +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/extras/dbus/udev_dbus.c b/extras/dbus/udev_dbus.c deleted file mode 100644 index 4852d429f8..0000000000 --- a/extras/dbus/udev_dbus.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * udev_dbus.c - * - * Copyright (C) 2003 David Zeuthen - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DBUS_API_SUBJECT_TO_CHANGE -#include - -#include "../../udev_lib.h" -#include "../../logging.h" - -#ifdef LOG -unsigned char logname[LOGNAME_SIZE]; -void log_message(int level, const char *format, ...) -{ - va_list args; - - va_start(args, format); - vsyslog(level, format, args); - va_end(args); -} -#endif - -/* Variable for the connection the to system message bus or NULL - * if we cannot connect or acquire the org.kernel.udev service - */ -static DBusConnection* sysbus_connection; - -/* Disconnect from the system message bus */ -static void sysbus_disconnect(void) -{ - if (sysbus_connection == NULL) - return; - - dbus_connection_disconnect(sysbus_connection); - sysbus_connection = NULL; -} - -/* Connect to the system message bus */ -static void sysbus_connect(void) -{ - DBusError error; - - /* Connect to a well-known bus instance, the system bus */ - dbus_error_init(&error); - sysbus_connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - if (sysbus_connection == NULL) { - dbg("cannot connect to system message bus, error %s: %s", - error.name, error.message); - dbus_error_free(&error); - return; - } - - /* Acquire the org.kernel.udev service such that listeners - * know that the message is really from us and not from a - * random attacker. See the file udev_sysbus_policy.conf for - * details. - * - * Note that a service can have multiple owners (though there - * is a concept of a primary owner for reception of messages) - * so no race is introduced if two copies of udev is running - * at the same time. - */ - dbus_bus_acquire_service(sysbus_connection, "org.kernel.udev", 0, - &error); - if (dbus_error_is_set(&error)) { - dbg("cannot acquire org.kernel.udev service, error %s: %s'", - error.name, error.message); - sysbus_disconnect(); - return; - } -} - - -/* Send out a signal that a device node is created - * - * @param devname Name of the device node, e.g. /dev/sda1 - * @param path Sysfs path of device - */ -static void sysbus_send_create(const char *devname, const char *path) -{ - DBusMessage* message; - DBusMessageIter iter; - - /* object, interface, member */ - message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", - "org.kernel.udev.NodeMonitor", - "NodeCreated"); - - dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, devname); - dbus_message_iter_append_string(&iter, path); - - if ( !dbus_connection_send(sysbus_connection, message, NULL) ) - dbg("error sending d-bus signal"); - - dbus_message_unref(message); - - dbus_connection_flush(sysbus_connection); -} - -/* Send out a signal that a device node is deleted - * - * @param devname Name of the device node, e.g. /udev/sda1 - * @param path Sysfs path of device - */ -static void sysbus_send_remove(const char *devname, const char *path) -{ - DBusMessage* message; - DBusMessageIter iter; - - /* object, interface, member */ - message = dbus_message_new_signal("/org/kernel/udev/NodeMonitor", - "org.kernel.udev.NodeMonitor", - "NodeDeleted"); - - dbus_message_iter_init(message, &iter); - dbus_message_iter_append_string(&iter, devname); - dbus_message_iter_append_string(&iter, path); - - if ( !dbus_connection_send(sysbus_connection, message, NULL) ) - dbg("error sending d-bus signal"); - - dbus_message_unref(message); - - dbus_connection_flush(sysbus_connection); -} - -int main(int argc, char *argv[], char *envp[]) -{ - char *action; - char *devpath; - char *devname; - int retval = 0; - - init_logging("udev_dbus"); - - sysbus_connect(); - if (sysbus_connection == NULL) - return 0; - - action = get_action(); - if (!action) { - dbg("no action?"); - goto exit; - } - devpath = get_devpath(); - if (!devpath) { - dbg("no devpath?"); - goto exit; - } - devname = get_devname(); - if (!devname) { - dbg("no devname?"); - goto exit; - } - - if (strcmp(action, "add") == 0) { - sysbus_send_create(devname, devpath); - } else { - if (strcmp(action, "remove") == 0) { - sysbus_send_remove(devname, devpath); - } else { - dbg("unknown action '%s'", action); - retval = -EINVAL; - } - } - -exit: - sysbus_disconnect(); - return retval; -} From bd2598afb628257c23cee57040ed22f8064cfee3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 14 May 2004 23:03:50 -0700 Subject: [PATCH 0778/4284] [PATCH] delete udev_selinux as it doesn't work properly and is the wrong way to do it... --- extras/selinux/Makefile | 64 -------------------------- extras/selinux/udev_selinux.c | 85 ----------------------------------- 2 files changed, 149 deletions(-) delete mode 100644 extras/selinux/Makefile delete mode 100644 extras/selinux/udev_selinux.c diff --git a/extras/selinux/Makefile b/extras/selinux/Makefile deleted file mode 100644 index 35d2e9e6da..0000000000 --- a/extras/selinux/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -# Makefile for udev_selinux -# -# Copyright (C) 2004 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. -# - -# Set the following to control the use of syslog -# Set it to `false' to remove all logging -USE_LOG = true - -# Set the following to `true' to log the debug -# and make a unstripped, unoptimized binary. -# Leave this set to `false' for production use. -DEBUG = false - -PROG = udev_selinux - -DESTDIR = - -# override this to make udev look in a different location for it's config files -prefix = -exec_prefix = ${prefix} -etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin -mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default -hotplugdir = ${etcdir}/hotplug.d/default -configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ -srcdir = . - -INSTALL = /usr/bin/install -c -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 -INSTALL_SCRIPT = ${INSTALL_PROGRAM} - -all: $(PROG) - -OBJS = udev_selinux.o - -override CFLAGS += -DUSE_SELINUX -override LIB_OBJS += -lselinux - -$(PROG): $(OBJS) - $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) ../../udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) - -clean: - rm -f $(PROG) $(OBJS) - -spotless: clean - -install: all - $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) - - ln -s -f $(DESTDIR)$(sbindir)/$(PROG) $(DESTDIR)$(devddir)/$(PROG).dev - -uninstall: - - rm $(DESTDIR)$(devddir)/$(PROG).dev - - rm $(DESTDIR)$(sbindir)/$(PROG) - diff --git a/extras/selinux/udev_selinux.c b/extras/selinux/udev_selinux.c deleted file mode 100644 index 8b1c2c7da8..0000000000 --- a/extras/selinux/udev_selinux.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * udev_selinux.c - * - * Copyright (C) 2004 Daniel J 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include - -#include "../../udev_lib.h" -#include "../../logging.h" - -#ifdef LOG -unsigned char logname[LOGNAME_SIZE]; -void log_message(int level, const char *format, ...) -{ - va_list args; - - va_start(args, format); - vsyslog(level, format, args); - va_end(args); -} -#endif - -static void selinux_add_node(char *filename) -{ - int retval; - - if (is_selinux_enabled() > 0) { - security_context_t scontext; - retval = matchpathcon(filename, 0, &scontext); - if (retval < 0) { - dbg("matchpathcon(%s) failed\n", filename); - } else { - retval = setfilecon(filename,scontext); - if (retval < 0) - dbg("setfiles %s failed with error '%s'", - filename, strerror(errno)); - free(scontext); - } - } -} - -int main(int argc, char *argv[], char *envp[]) -{ - char *action; - char *devname; - int retval = 0; - - init_logging("udev_selinux"); - - action = get_action(); - if (!action) { - dbg("no action?"); - goto exit; - } - devname = get_devname(); - if (!devname) { - dbg("no devname?"); - goto exit; - } - - if (strcmp(action, "add") == 0) - selinux_add_node(devname); - -exit: - return retval; -} From 91cb2628950fc80e719983fa86dbb616af3e94f0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 14 May 2004 23:05:05 -0700 Subject: [PATCH 0779/4284] [PATCH] remove dbus and selinux stuff from the udev.spec file. --- udev.spec | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/udev.spec b/udev.spec index f183f5b3d2..0c8969dfac 100644 --- a/udev.spec +++ b/udev.spec @@ -17,16 +17,6 @@ # 1 - debugging enabled %define debug 0 -# if we want to build the DBUS "extra" package or not -# 0 - no DBUS support -# 1 - DBUS support -%define dbus 0 - -# if we want to build the SELinux "extra" package or not -# 0 - no SELinux support -# 1 - SELinux support -%define selinux 0 - # if we want to build the scsi_id "extra" package or not # 0 - do not build the package # 1 - build it @@ -71,12 +61,6 @@ make CC="gcc $RPM_OPT_FLAGS" \ %if %{scsi_id} extras/scsi_id \ %endif -%if %{dbus} - extras/dbus \ -%endif -%if %{selinux} - extras/selinux \ -%endif " %install @@ -85,12 +69,6 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %if %{scsi_id} extras/scsi_id \ %endif -%if %{dbus} - extras/dbus \ -%endif -%if %{selinux} - extras/selinux \ -%endif " %post @@ -124,10 +102,6 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev*.8* -%if %{dbus} - %config(noreplace) %attr(0644,root,root) /etc/dbus-1/system.d/udev_sysbus_policy.conf -%endif - %if %{scsi_id} %attr(755,root,root) /sbin/scsi_id %config(noreplace) %attr(0644,root,root) /etc/scsi_id.config From 1eae2f3f712ff839bf80721bf9c44a76a78460dc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 14 May 2004 23:08:04 -0700 Subject: [PATCH 0780/4284] [PATCH] add volume_id support to the udev.spec file --- udev.spec | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/udev.spec b/udev.spec index 0c8969dfac..79b6952415 100644 --- a/udev.spec +++ b/udev.spec @@ -22,6 +22,11 @@ # 1 - build it %define scsi_id 1 +# if we want to build the volume_id "extra" package or not +# 0 - do not build the package +# 1 - build it +%define volume_id 1 + Summary: A userspace implementation of devfs Name: udev Version: 025 @@ -61,6 +66,9 @@ make CC="gcc $RPM_OPT_FLAGS" \ %if %{scsi_id} extras/scsi_id \ %endif +%if %{volume_id} + extras/volume_id \ +%endif " %install @@ -69,6 +77,9 @@ make DESTDIR=$RPM_BUILD_ROOT install \ %if %{scsi_id} extras/scsi_id \ %endif +%if %{volume_id} + extras/volume_id \ +%endif " %post @@ -107,8 +118,15 @@ rm -rf $RPM_BUILD_ROOT %config(noreplace) %attr(0644,root,root) /etc/scsi_id.config %attr(0644,root,root) %{_mandir}/man8/scsi_id*.8* %endif +%if %{volume_id} + %attr(755,root,root) /sbin/udev_volume_id +%endif %changelog +* Fri May 14 2004 Greg Kroah-Hartman +- remove dbus and selinux stuff from here +- added volume_id option + * Wed Mar 24 2004 Greg Kroah-Hartman - change the way dbus and selinux support is built (now an extra) From 28e169f067aa96b406342677922e34e7361a7d1b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 14 May 2004 23:18:41 -0700 Subject: [PATCH 0781/4284] [PATCH] udevsend fallback On Tue, May 11, 2004 at 04:54:44PM -0700, Greg KH wrote: > On Tue, May 11, 2004 at 01:16:41PM +0200, Kay Sievers wrote: > > Hi, > > the execution of udev depends on the proper fuction of udevd, the > > serializing daemon. If we can't connect to udevd within a 20 second we > > give up and the request to create a node is lost. Hope this never happens, > > but a broken udevd may prevent udev from working. > > > > What do you think? Should we call the udev binary directly from udevsend > > instead of discarding the event? This way we would create the node, regardless > > of the state of udevd. It would be 20 seconds later and maybe not in the right > > sequence order - but the node will propably be there. > > > > Does it sound sane? What do you think? > > That sounds like a good "failsafe" thing to do. Here we go: Add a fallback udev call to udevsend. If udevsend is unable to send the event to udevd, we call the udev binary instead of doing nothing and exiting. --- udevsend.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/udevsend.c b/udevsend.c index f28e445433..a52d6ec165 100644 --- a/udevsend.c +++ b/udevsend.c @@ -98,6 +98,26 @@ static int start_daemon(void) return 0; } +static void run_udev(const char *subsystem) +{ + pid_t pid; + + pid = fork(); + switch (pid) { + case 0: + /* child */ + execl(UDEV_BIN, "udev", subsystem, NULL); + dbg("exec of child failed"); + exit(1); + break; + case -1: + dbg("fork of child failed"); + break; + default: + wait(NULL); + } +} + int main(int argc, char* argv[]) { struct hotplug_msg msg; @@ -109,14 +129,12 @@ int main(int argc, char* argv[]) int retval = 1; int loop; struct timespec tspec; - int sock; + int sock = -1; struct sockaddr_un saddr; socklen_t addrlen; int started_daemon = 0; -#ifdef DEBUG init_logging("udevsend"); -#endif dbg("version %s", UDEV_VERSION); subsystem = get_subsystem(argv[1]); @@ -150,7 +168,7 @@ int main(int argc, char* argv[]) sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { dbg("error getting socket"); - goto exit; + goto fallback; } memset(&saddr, 0x00, sizeof(struct sockaddr_un)); @@ -168,22 +186,21 @@ int main(int argc, char* argv[]) (struct sockaddr *)&saddr, addrlen); if (retval != -1) { retval = 0; - goto close_and_exit; + goto exit; } - + if (errno != ECONNREFUSED) { dbg("error sending message"); - goto close_and_exit; + goto fallback; } - + if (!started_daemon) { - dbg("connect failed, try starting daemon..."); + info("starting udevd daemon"); retval = start_daemon(); if (retval) { - dbg("error starting daemon"); - goto exit; + info("error starting daemon"); + goto fallback; } - dbg("daemon started"); started_daemon = 1; } else { @@ -193,9 +210,14 @@ int main(int argc, char* argv[]) nanosleep(&tspec, NULL); } } - -close_and_exit: - close(sock); + +fallback: + info("unable to connect to event daemon, try to call udev directly"); + run_udev(subsystem); + exit: + if (sock != -1) + close(sock); + return retval; } From c33359307b4a337d6c4f2f4fbe4451544fa5cc1f Mon Sep 17 00:00:00 2001 From: "ogasawara@osdl.org" Date: Fri, 14 May 2004 23:18:46 -0700 Subject: [PATCH 0782/4284] [PATCH] evaluate getenv() return value for udev_config.c Small patch to fix the evaluation logic for the return value of getenv() in udev_config.c file. Basically, the actual values for the environment variables "UDEV_NO_SLEEP" and "UDEV_NO_DEVD" were not being checked. For example UDEV_NO_SLEEP could have been set to false but the line: if (getenv("UDEV_NO_SLEEP") != NULL) in this case would always evaluate to true, since getenv() returns char*, thus the "udev_sleep" variable would be set incorrectly. The patch makes sure to check the value returned by getenv() not just if getenv() returned a value. Hope this made sense. Thanks, --- udev_config.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/udev_config.c b/udev_config.c index 51a91d0092..19f690c7e8 100644 --- a/udev_config.c +++ b/udev_config.c @@ -60,11 +60,15 @@ static int string_is_true(char *str) return 1; if (strcasecmp(str, "yes") == 0) return 1; + if (strcasecmp(str, "1") == 0) + return 1; return 0; } static void init_variables(void) { + char *env; + /* fill up the defaults. * If any config values are specified, they will * override these values. */ @@ -76,11 +80,13 @@ static void init_variables(void) udev_log = string_is_true(UDEV_LOG_DEFAULT); udev_sleep = 1; - if (getenv("UDEV_NO_SLEEP") != NULL) + env = getenv("UDEV_NO_SLEEP"); + if (env && string_is_true(env)) udev_sleep = 0; udev_dev_d = 1; - if (getenv("UDEV_NO_DEVD") != NULL) + env = getenv("UDEV_NO_DEVD"); + if (env && string_is_true(env)) udev_dev_d = 0; } From 3c60abb55ad438857248c4e5c5ba8acde887ba26 Mon Sep 17 00:00:00 2001 From: "arnd@arndb.de" Date: Thu, 20 May 2004 19:14:09 -0700 Subject: [PATCH 0783/4284] [PATCH] udev rpm fix Some file locations have changed since the spec file was last updated. Also a failed build might leave behind a stale buildroot directory. This patch should fix both problems. --- udev.spec | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/udev.spec b/udev.spec index 79b6952415..e53b3598fc 100644 --- a/udev.spec +++ b/udev.spec @@ -72,6 +72,7 @@ make CC="gcc $RPM_OPT_FLAGS" \ " %install +rm -rf $RPM_BUILD_ROOT make DESTDIR=$RPM_BUILD_ROOT install \ EXTRAS=" \ %if %{scsi_id} @@ -107,11 +108,16 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) %dir /udev/ %attr(755,root,root) %dir /etc/udev/ %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf -%config(noreplace) %attr(0644,root,root) /etc/udev/udev.rules -%config(noreplace) %attr(0644,root,root) /etc/udev/udev.permissions +%attr(755,root,root) %dir /etc/udev/rules.d/ +%attr(755,root,root) %dir /etc/udev/permissions.d/ +%config(noreplace) %attr(0644,root,root) /etc/udev/rules.d/50-udev.rules +%config(noreplace) %attr(0644,root,root) /etc/udev/permissions.d/50-udev.permissions %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev*.8* +%attr(755,root,root) %dir /etc/dev.d/ +%attr(755,root,root) %dir /etc/dev.d/net/ +%attr(0755,root,root) /etc/dev.d/net/hotplug.dev %if %{scsi_id} %attr(755,root,root) /sbin/scsi_id From 73028bc3322c9ec88e046c57e7b297fdd1c02b1a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 20 May 2004 23:14:08 -0700 Subject: [PATCH 0784/4284] [PATCH] Update to version 117 of klibc (from version 108) --- klibc/MCONFIG | 11 ++- klibc/MRULES | 4 + klibc/klibc/Makefile | 5 +- klibc/klibc/README | 4 +- klibc/klibc/SYSCALLS | 3 +- klibc/klibc/__static_init.c | 2 - klibc/klibc/arch/i386/MCONFIG | 9 +- klibc/klibc/arch/i386/crt0.S | 1 - klibc/klibc/arch/parisc/Makefile.inc | 5 ++ klibc/klibc/arch/parisc/crt0.S | 34 +++++++ .../arch/parisc/include/klibc/archsignal.h | 13 ++- klibc/klibc/arch/parisc/setjmp.S | 88 +++++++++++++++++++ klibc/klibc/getpgrp.c | 9 ++ klibc/klibc/getpt.c | 17 ++++ klibc/klibc/include/klibc/compiler.h | 4 + klibc/klibc/include/stdlib.h | 6 +- klibc/klibc/include/sys/sysinfo.h | 12 +++ klibc/klibc/include/sys/un.h | 8 +- klibc/klibc/include/unistd.h | 5 +- klibc/klibc/open.c | 17 ++++ klibc/klibc/pty.c | 2 +- klibc/version | 2 +- 22 files changed, 233 insertions(+), 28 deletions(-) create mode 100644 klibc/klibc/arch/parisc/crt0.S create mode 100644 klibc/klibc/arch/parisc/setjmp.S create mode 100644 klibc/klibc/getpgrp.c create mode 100644 klibc/klibc/getpt.c create mode 100644 klibc/klibc/include/sys/sysinfo.h create mode 100644 klibc/klibc/open.c diff --git a/klibc/MCONFIG b/klibc/MCONFIG index de8b332d98..ec8b65c0e4 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -25,9 +25,14 @@ HOST_CFLAGS = -g -O HOST_LDFLAGS = HOST_LIBS = -CRT0 = $(KLIBSRC)/crt0.o -KLIBC = $(KLIBSRC)/libc.a -LIBGCC = $(shell $(CC) --print-libgcc) +# Static library paths +CRT0 = $(KLIBSRC)/crt0.o +KLIBC = $(KLIBSRC)/libc.a +LIBGCC = $(shell $(CC) --print-libgcc) + +# Shared library paths +CRTSHARED = $(KLIBSRC)/interp.o +LIBSHARED = $(KLIBSRC)/libc.so # # This indicates the location of the final version of the shared library. diff --git a/klibc/MRULES b/klibc/MRULES index 8a8831c348..41fdd07af8 100644 --- a/klibc/MRULES +++ b/klibc/MRULES @@ -5,6 +5,10 @@ .SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss +% : %.c # Cancel default rule + +% : %.S + .c.o: $(CC) $(CFLAGS) -c -o $@ $< diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 0d5b197f0d..7ed03a8e87 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -17,7 +17,8 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ strtoimax.o strtoumax.o \ globals.o exitc.o atexit.o onexit.o \ execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \ - fork.o wait.o wait3.o waitpid.o system.o setpgrp.o \ + fork.o wait.o wait3.o waitpid.o system.o setpgrp.o getpgrp.o \ + open.o \ printf.o vprintf.o fprintf.o vfprintf.o perror.o \ fopen.o fread.o fread2.o fgetc.o fgets.o \ fwrite.o fwrite2.o fputc.o fputs.o puts.o \ @@ -35,7 +36,7 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ seteuid.o setegid.o setresuid.o setresgid.o \ getenv.o setenv.o putenv.o __put_env.o unsetenv.o \ getopt.o readdir.o \ - syslog.o closelog.o pty.o isatty.o reboot.o \ + syslog.o closelog.o pty.o getpt.o isatty.o reboot.o \ time.o utime.o fdatasync.o llseek.o select.o nice.o getpriority.o \ qsort.o lrand48.o srand48.o seed48.o \ inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ diff --git a/klibc/klibc/README b/klibc/klibc/README index 4495908a22..d69fa8de41 100644 --- a/klibc/klibc/README +++ b/klibc/klibc/README @@ -36,9 +36,9 @@ b) If you're cross-compiling, change ARCH in the main MCONFIG file to Known to work: alpha arm ia64 i386 ppc s390 s390x sparc sparc64 x86_64* - Works static, not shared: mips* arm-thumb sh* + Works static, not shared: mips* arm-thumb sh* parisc Might work: ppc64 - Need porting work: cris m68k mips64 parisc + Need porting work: cris m68k mips64 v850 x86_64: requires a kernel header patch (to be created) mips, sh: linker problem; might work with fixed linker diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS index 00883cc098..82081201b4 100644 --- a/klibc/klibc/SYSCALLS +++ b/klibc/klibc/SYSCALLS @@ -19,7 +19,6 @@ int setpgid(pid_t, pid_t) pid_t getpgid(pid_t) pid_t getppid() pid_t getxpid@dual1::getppid() - pid_t getpgrp() pid_t setsid() pid_t getsid(pid_t) pid_t wait4(pid_t, int *, int, struct rusage *) @@ -92,7 +91,6 @@ int lchown(const char *, uid_t, gid_t) # ssize_t read(int, void *, size_t) ssize_t write(int, const void *, size_t) -int open(const char *, int, mode_t) int close(int) off_t lseek(int, off_t, int) int dup(int) @@ -145,6 +143,7 @@ long delete_module(const char *, unsigned int) int query_module(const char *, int, void *, size_t, size_t) int reboot::__reboot(int, int, int, void *) int syslog::klogctl(int, char *, int) +int sysinfo(struct sysinfo *) # # Low-level I/O (generally architecture-specific) diff --git a/klibc/klibc/__static_init.c b/klibc/klibc/__static_init.c index dcb8d01856..5a90b5cd88 100644 --- a/klibc/klibc/__static_init.c +++ b/klibc/klibc/__static_init.c @@ -36,5 +36,3 @@ __noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void)) environ = envp; exit(main(argc, argv, envp)); } - - diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG index 367ee89773..516b1b6738 100644 --- a/klibc/klibc/arch/i386/MCONFIG +++ b/klibc/klibc/arch/i386/MCONFIG @@ -7,17 +7,16 @@ # accordingly. # -# Comment this out to compile with register parameter passing -# This doesn't work right now because gcc 3.2 (at least) calls -# libgcc with the default calling convention instead of forcing -# them to be cdecl -# REGPARM = -mregparm=3 -DREGPARM +# Enable this to compile with register parameters; only safe for +# gcc > 3 +REGPARM_OPT := -mregparm=3 -DREGPARM gcc_major := $(shell $(CC) -v 2>&1 | awk '/gcc version/{print int($$3)}') OPTFLAGS = $(REGPARM) -march=i386 -Os ifeq ($(gcc_major),3) +REGPARM := $(REGPARM_OPT) OPTFLAGS += -falign-functions=0 -falign-jumps=0 -falign-loops=0 else OPTFLAGS += -malign-functions=0 -malign-jumps=0 -malign-loops=0 diff --git a/klibc/klibc/arch/i386/crt0.S b/klibc/klibc/arch/i386/crt0.S index 1c82eda513..0f3a7db35e 100644 --- a/klibc/klibc/arch/i386/crt0.S +++ b/klibc/klibc/arch/i386/crt0.S @@ -26,7 +26,6 @@ _start: #endif call __libc_init # If __libc_init returns, problem... - ud2 hlt .size _start, .-_start diff --git a/klibc/klibc/arch/parisc/Makefile.inc b/klibc/klibc/arch/parisc/Makefile.inc index f7a983da7f..abe9155bf4 100644 --- a/klibc/klibc/arch/parisc/Makefile.inc +++ b/klibc/klibc/arch/parisc/Makefile.inc @@ -7,4 +7,9 @@ # accordingly. # +ARCHOBJS = \ + arch/$(ARCH)/setjmp.o + +ARCHOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS)) + archclean: diff --git a/klibc/klibc/arch/parisc/crt0.S b/klibc/klibc/arch/parisc/crt0.S new file mode 100644 index 0000000000..fb0bd373ee --- /dev/null +++ b/klibc/klibc/arch/parisc/crt0.S @@ -0,0 +1,34 @@ + .align 4 + + .import $global$, data + .import __libc_init, code + + .global _start + .export _start, ENTRY + .type _start,@function + + .proc + .callinfo + +_start: +/* extend the stack by 64-bytes */ + ldo 64(%sp), %sp + +/* %r25 = argc + * %r24 = argv + * envp = argv + (argc + 1) + * elfdata = (argv - 4) + */ + ldo -4(%r24), %r26 + +/* load global data */ + ldil L%$global$, %dp + ldo R%$global$(%dp), %dp + +/* branch to __libc_init */ + bl __libc_init,%r2 + nop +/* break miserably if we ever return */ + iitlbp %r0,(%r0) /* illegal instruction */ + nop + .procend diff --git a/klibc/klibc/arch/parisc/include/klibc/archsignal.h b/klibc/klibc/arch/parisc/include/klibc/archsignal.h index 511d774b2d..3190e8528e 100644 --- a/klibc/klibc/arch/parisc/include/klibc/archsignal.h +++ b/klibc/klibc/arch/parisc/include/klibc/archsignal.h @@ -8,6 +8,17 @@ #ifndef _KLIBC_ARCHSIGNAL_H #define _KLIBC_ARCHSIGNAL_H -/* No special stuff for this architecture */ +#define _NSIG 64 +#define _NSIG_SZ (_NSIG / LONG_BIT) + +typedef struct { + unsigned long sig[_NSIG_SZ]; +} sigset_t; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; #endif diff --git a/klibc/klibc/arch/parisc/setjmp.S b/klibc/klibc/arch/parisc/setjmp.S new file mode 100644 index 0000000000..51b2b1a58b --- /dev/null +++ b/klibc/klibc/arch/parisc/setjmp.S @@ -0,0 +1,88 @@ +/* + * parisc specific setjmp/longjmp routines + * + */ + + .text + .align 4 + .global setjmp + .export setjmp, code + .proc + .callinfo +setjmp: + stw %r3,0(%r26) + stw %r4,8(%r26) + stw %r5,12(%r26) + stw %r6,16(%r26) + stw %r7,20(%r26) + stw %r8,24(%r26) + stw %r9,28(%r26) + stw %r10,32(%r26) + stw %r11,36(%r26) + stw %r12,40(%r26) + stw %r13,44(%r26) + stw %r14,48(%r26) + stw %r15,52(%r26) + stw %r16,56(%r26) + stw %r17,60(%r26) + stw %r18,64(%r26) + stw %r19,68(%r26) + stw %dp,72(%r26) + stw %r30,76(%r26) + stw %rp,80(%r26) + ldo 88(%r26),%r19 + fstd,ma %fr12,8(%r19) + fstd,ma %fr13,8(%r19) + fstd,ma %fr14,8(%r19) + fstd,ma %fr15,8(%r19) + fstd,ma %fr16,8(%r19) + fstd,ma %fr17,8(%r19) + fstd,ma %fr18,8(%r19) + fstd,ma %fr19,8(%r19) + fstd,ma %fr20,8(%r19) + fstd %fr21,0(%r19) + bv %r0(%rp) + copy %r0,%r28 + .procend + + .text + .align 4 + .global longjmp + .export longjmp, code + .proc + .callinfo +longjmp: + ldw 0(%r26),%r3 + ldw 8(%r26),%r4 + ldw 12(%r26),%r5 + ldw 16(%r26),%r6 + ldw 20(%r26),%r7 + ldw 24(%r26),%r8 + ldw 28(%r26),%r9 + ldw 32(%r26),%r10 + ldw 36(%r26),%r11 + ldw 40(%r26),%r12 + ldw 44(%r26),%r13 + ldw 48(%r26),%r14 + ldw 52(%r26),%r15 + ldw 56(%r26),%r16 + ldw 60(%r26),%r17 + ldw 64(%r26),%r18 + ldw 68(%r26),%r19 + ldw 72(%r26),%r27 + ldw 76(%r26),%r30 + ldw 80(%r26),%rp + ldo 88(%r26),%r20 + fldd,ma 8(%r20),%fr12 + fldd,ma 8(%r20),%fr13 + fldd,ma 8(%r20),%fr14 + fldd,ma 8(%r20),%fr15 + fldd,ma 8(%r20),%fr16 + fldd,ma 8(%r20),%fr17 + fldd,ma 8(%r20),%fr18 + fldd,ma 8(%r20),%fr19 + fldd,ma 8(%r20),%fr20 + fldd 0(%r20),%fr21 + bv %r0(%rp) + copy %r25,%r28 + .procend diff --git a/klibc/klibc/getpgrp.c b/klibc/klibc/getpgrp.c new file mode 100644 index 0000000000..c92369807b --- /dev/null +++ b/klibc/klibc/getpgrp.c @@ -0,0 +1,9 @@ +/* + * getpgrp.c + */ + +#include + +pid_t getpgrp(void) { + return getpgid(0); +} diff --git a/klibc/klibc/getpt.c b/klibc/klibc/getpt.c new file mode 100644 index 0000000000..a05903062c --- /dev/null +++ b/klibc/klibc/getpt.c @@ -0,0 +1,17 @@ +/* + * getpt.c + * + * GNU extension to the standard Unix98 pty suite + */ + +#include +#include +#include +#include +#include +#include + +int getpt(void) +{ + return open("/dev/ptmx", O_RDWR|O_NOCTTY); +} diff --git a/klibc/klibc/include/klibc/compiler.h b/klibc/klibc/include/klibc/compiler.h index 49872b89d4..6c01474cc1 100644 --- a/klibc/klibc/include/klibc/compiler.h +++ b/klibc/klibc/include/klibc/compiler.h @@ -8,12 +8,16 @@ #define _KLIBC_COMPILER_H /* Specific calling conventions */ +/* __cdecl is used when we want varadic and non-varadic functions to have + the same binary calling convention. */ #ifdef __i386__ # ifdef __GNUC__ # define __cdecl __attribute__((cdecl,regparm(0))) # else /* Most other C compilers have __cdecl as a keyword */ # endif +#else +# define __cdecl /* Meaningless on non-i386 */ #endif /* How to declare a function that *must* be inlined */ diff --git a/klibc/klibc/include/stdlib.h b/klibc/klibc/include/stdlib.h index 38dd1624a5..af97eea636 100644 --- a/klibc/klibc/include/stdlib.h +++ b/klibc/klibc/include/stdlib.h @@ -83,12 +83,14 @@ static __inline__ void srandom(unsigned int __s) /* Basic PTY functions. These only work if devpts is mounted! */ +__extern int unlockpt(int); +__extern char *ptsname(int); +__extern int getpt(void); + static __inline__ int grantpt(int __fd) { (void)__fd; return 0; /* devpts does this all for us! */ } -__extern int unlockpt(int); -__extern char *ptsname(int); #endif /* _STDLIB_H */ diff --git a/klibc/klibc/include/sys/sysinfo.h b/klibc/klibc/include/sys/sysinfo.h new file mode 100644 index 0000000000..4051c6897a --- /dev/null +++ b/klibc/klibc/include/sys/sysinfo.h @@ -0,0 +1,12 @@ +/* + * sys/sysinfo.h + */ + +#ifndef _SYS_SYSINFO_H +#define _SYS_SYSINFO_H + +#include + +extern int sysinfo (struct sysinfo *info); + +#endif /* _SYS_SYSINFO_H */ diff --git a/klibc/klibc/include/sys/un.h b/klibc/klibc/include/sys/un.h index 85822ba6a4..df42d719f7 100644 --- a/klibc/klibc/include/sys/un.h +++ b/klibc/klibc/include/sys/un.h @@ -1,10 +1,10 @@ /* - * sys/un.h + * */ -#ifndef _UN_H -#define _UN_H +#ifndef _SYS_UN_H +#define _SYS_UN_H #include -#endif /* _UN_H */ +#endif /* _SYS_UN_H */ diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h index f1cde2376e..13ff03b012 100644 --- a/klibc/klibc/include/unistd.h +++ b/klibc/klibc/include/unistd.h @@ -17,6 +17,7 @@ __extern __noreturn _exit(int); __extern pid_t fork(void); __extern pid_t vfork(void); __extern pid_t getpid(void); +__extern pid_t getpgid(pid_t); __extern int setpgid(pid_t, pid_t); __extern pid_t getppid(void); __extern pid_t getpgrp(void); @@ -76,8 +77,8 @@ __extern int sync(void); __extern ssize_t read(int, void *, size_t); __extern ssize_t write(int, const void *, size_t); -#ifndef __IN_SYS_COMMON -__extern int open(const char *, int, ...); +#ifndef __IN_OPEN_C +__extern __cdecl int open(const char *, int, ...); #endif __extern int close(int); __extern off_t lseek(int, off_t, int); diff --git a/klibc/klibc/open.c b/klibc/klibc/open.c new file mode 100644 index 0000000000..0d7db10c4a --- /dev/null +++ b/klibc/klibc/open.c @@ -0,0 +1,17 @@ +/* + * open.c + * + * The open syscall is weird, because it's defined as a varadic + * function, but implementing it as such generally sucks for + * performance. Thus we generate it as a 3-argument function, + * but with explicit __cdecl assuming the __cdecl convention is + * independent of being varadic. + */ + +#define __IN_OPEN_C +#include +#include +#include +#include + +__cdecl _syscall3(int,open,const char *,file,int,flags,mode_t,mode) diff --git a/klibc/klibc/pty.c b/klibc/klibc/pty.c index 5907ca2ff5..2fe01ab204 100644 --- a/klibc/klibc/pty.c +++ b/klibc/klibc/pty.c @@ -1,7 +1,7 @@ /* * pty.c * - * Basic Unix98 PTY functionality; assumes devpts + * Basic Unix98 PTY functionality; assumes devpts mounted on /dev/pts */ #include diff --git a/klibc/version b/klibc/version index 4b0a18ac52..31ba1bdaa5 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.108 +0.117 From 9e86e12e10ad147d27cb19bc3a6f799f38fd4502 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 20 May 2004 23:53:50 -0700 Subject: [PATCH 0785/4284] [PATCH] 025_bk mark because kernel.org is down, no release just yet... --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 7c716e852e..e471f02475 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 025 +VERSION = 025_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index e53b3598fc..d82c656ef5 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 025 +Version: 025_bk Release: 1 License: GPL Group: Utilities/System From 84df02dd63bf53acb5a61e9db1da067760b927e9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 26 May 2004 19:40:27 -0700 Subject: [PATCH 0786/4284] [PATCH] catchup with recent klibc Our own implementation of the sysinfo system call is no longer needed, cause it's merged it into klibc now. --- klibc_fixups.c | 2 -- klibc_fixups.h | 5 ----- namedev.c | 2 -- udevd.c | 2 -- 4 files changed, 11 deletions(-) diff --git a/klibc_fixups.c b/klibc_fixups.c index c4d44bbc49..bbacfbdc75 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -37,8 +37,6 @@ #define GR_FILE "/etc/group" #define UTMP_FILE "/var/run/utmp" -_syscall1(int, sysinfo, struct sysinfo *, info); - /* return the id of a passwd style line, selected by the users name */ static unsigned long get_id_by_name(const char *uname, const char *dbfile) { diff --git a/klibc_fixups.h b/klibc_fixups.h index 6dfd5a5c17..f6c91cdd94 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -3,11 +3,6 @@ #ifndef KLIBC_FIXUPS_H #define KLIBC_FIXUPS_H -#include -#include - -int sysinfo(struct sysinfo *info); - struct passwd { char *pw_name; /* user name */ char *pw_passwd; /* user password */ diff --git a/namedev.c b/namedev.c index b3a2a8ae4b..5e3db1326c 100644 --- a/namedev.c +++ b/namedev.c @@ -32,9 +32,7 @@ #include #include #include -#ifndef __KLIBC__ #include -#endif #include "libsysfs/sysfs/libsysfs.h" #include "list.h" diff --git a/udevd.c b/udevd.c index d807e4168d..5756b46122 100644 --- a/udevd.c +++ b/udevd.c @@ -34,9 +34,7 @@ #include #include #include "klibc_fixups.h" -#ifndef __KLIBC__ #include -#endif #include "list.h" #include "udev.h" From 0f36e68e8a28e02981b90a3a4712f198b58746ba Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 4 Jun 2004 22:01:53 -0700 Subject: [PATCH 0787/4284] [PATCH] add test for ! in partition name --- test/sys/block/cciss!c0d0/cciss!c0d0p1/dev | 1 + test/sys/block/cciss!c0d0/cciss!c0d0p2/dev | 1 + test/sys/block/cciss!c0d0/cciss!c0d0p5/dev | 1 + test/sys/block/cciss!c0d0/dev | 1 + test/udev-test.pl | 10 ++++++++++ 5 files changed, 14 insertions(+) create mode 100644 test/sys/block/cciss!c0d0/cciss!c0d0p1/dev create mode 100644 test/sys/block/cciss!c0d0/cciss!c0d0p2/dev create mode 100644 test/sys/block/cciss!c0d0/cciss!c0d0p5/dev create mode 100644 test/sys/block/cciss!c0d0/dev diff --git a/test/sys/block/cciss!c0d0/cciss!c0d0p1/dev b/test/sys/block/cciss!c0d0/cciss!c0d0p1/dev new file mode 100644 index 0000000000..92c4b9b088 --- /dev/null +++ b/test/sys/block/cciss!c0d0/cciss!c0d0p1/dev @@ -0,0 +1 @@ +8:1 diff --git a/test/sys/block/cciss!c0d0/cciss!c0d0p2/dev b/test/sys/block/cciss!c0d0/cciss!c0d0p2/dev new file mode 100644 index 0000000000..9799a2674a --- /dev/null +++ b/test/sys/block/cciss!c0d0/cciss!c0d0p2/dev @@ -0,0 +1 @@ +8:2 diff --git a/test/sys/block/cciss!c0d0/cciss!c0d0p5/dev b/test/sys/block/cciss!c0d0/cciss!c0d0p5/dev new file mode 100644 index 0000000000..b3d5042192 --- /dev/null +++ b/test/sys/block/cciss!c0d0/cciss!c0d0p5/dev @@ -0,0 +1 @@ +8:5 diff --git a/test/sys/block/cciss!c0d0/dev b/test/sys/block/cciss!c0d0/dev new file mode 100644 index 0000000000..fae0a50572 --- /dev/null +++ b/test/sys/block/cciss!c0d0/dev @@ -0,0 +1 @@ +8:0 diff --git a/test/udev-test.pl b/test/udev-test.pl index ebd3c6a8a0..1e7c51e556 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -397,6 +397,16 @@ EOF exp_name => "rd/c0d0" , conf => < "name test with ! in the name for a partition", + subsys => "block", + devpath => "/block/cciss!c0d0/cciss!c0d0p1", + exp_name => "cciss/c0d0p1" , + conf => < Date: Mon, 7 Jun 2004 02:56:47 -0700 Subject: [PATCH 0788/4284] [PATCH] fix udevd zombies The recent version of klibc switched to -mregparm=3. This broke the signal handlers parameter, cause it is called directly from the kernel with the parameter on the stack not in a register. --- udev.c | 6 +++--- udevd.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/udev.c b/udev.c index 192bed97d8..eb21f75461 100644 --- a/udev.c +++ b/udev.c @@ -55,7 +55,7 @@ void log_message(int level, const char *format, ...) } #endif -static void sig_handler(int signum) +__attribute__((regparm(0))) static void sig_handler(int signum) { switch (signum) { case SIGINT: @@ -63,7 +63,7 @@ static void sig_handler(int signum) udevdb_exit(); exit(20 + signum); default: - dbg("unhandled signal"); + dbg("unhandled signal %d", signum); } } @@ -128,7 +128,7 @@ static int udev_hotplug(void) goto exit; } - /* set up a default signal handler for now */ + /* set signal handlers */ act.sa_handler = sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = SA_RESTART; diff --git a/udevd.c b/udevd.c index 5756b46122..e0c5bf5c77 100644 --- a/udevd.c +++ b/udevd.c @@ -306,9 +306,10 @@ skip: return; } -static void sig_handler(int signum) +__attribute__((regparm(0))) static void sig_handler(int signum) { int rc; + switch (signum) { case SIGINT: case SIGTERM: @@ -325,7 +326,7 @@ static void sig_handler(int signum) goto do_write; break; default: - dbg("unhandled signal"); + dbg("unhandled signal %d", signum); return; } From e3496f5932ab1460519db5c789bf6fdb242dd4c5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 7 Jun 2004 23:43:46 -0700 Subject: [PATCH 0789/4284] [PATCH] 026 release --- ChangeLog | 30 ++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index c37e615487..8fea6a7f91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +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 ============================================ diff --git a/Makefile b/Makefile index e471f02475..625c21efc0 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 025_bk +VERSION = 026 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index d82c656ef5..591a60bc87 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 025_bk +Version: 026 Release: 1 License: GPL Group: Utilities/System From 686cecf24216770190133aa6f270bb2b124329a7 Mon Sep 17 00:00:00 2001 From: "fork0@users.sf.net" Date: Tue, 8 Jun 2004 16:47:16 -0700 Subject: [PATCH 0790/4284] [PATCH] fix handle leak in udev_lib.c There is a handle leak in failure path in file_map, and the result of file_map (or the result of the caller of the file_map) is not always checked. --- udev_lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_lib.c b/udev_lib.c index 16b473f576..8f6aa42377 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -124,11 +124,13 @@ int file_map(const char *filename, char **buf, size_t *bufsize) } 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; From e978da492b7bef4c465f0461db034f55124b72a0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 14 Jun 2004 21:33:01 -0700 Subject: [PATCH 0791/4284] [PATCH] tweak the gentoo default permission rules as they are wrong for tty and misc devices. --- etc/udev/udev.permissions.gentoo | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index 6c422b8ce7..e257151512 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -3,7 +3,8 @@ # console devices console:root:tty:0600 -tty[0-9][0-9]*:root:tty:0660 +tty:root:tty:0666 +tty[0-9]*:root:tty:0660 vc/[0-9]*:root:tty:0660 # pty devices @@ -45,8 +46,8 @@ null:root:root:0666 zero:root:root:0666 # misc devices -nvram:root:root:0660 -rtc:root:root:0660 +misc/nvram:root:root:0660 +misc/rtc:root:root:0660 # floppy devices fd[01]*:root:floppy:0660 From ff0977b12e8b92963c687b593c3f1bc33e3d8a9c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Jul 2004 00:29:06 -0700 Subject: [PATCH 0792/4284] [PATCH] change default perms of misc/rtc to be readable by anyone. --- etc/udev/udev.permissions.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index e257151512..7bde9833d7 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -47,7 +47,7 @@ zero:root:root:0666 # misc devices misc/nvram:root:root:0660 -misc/rtc:root:root:0660 +misc/rtc:root:root:0664 # floppy devices fd[01]*:root:floppy:0660 From 8108813b5f52d92625003bc42bdd522aca02e8a2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 14 Jun 2004 21:36:50 -0700 Subject: [PATCH 0793/4284] [PATCH] 027 release --- ChangeLog | 10 ++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8fea6a7f91..cc754dc9d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 625c21efc0..1e683cb35c 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 026 +VERSION = 027 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 591a60bc87..07fafbbc79 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 026 +Version: 027 Release: 1 License: GPL Group: Utilities/System From 57218a087303505b01fb20cbe4c6961bd13fe411 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 26 Jun 2004 01:08:47 -0700 Subject: [PATCH 0794/4284] [PATCH] reverse order of scanning of udevstart to look at class before block. this should fix the startup issue for lvm, hopefully... --- udevstart.c | 104 +++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/udevstart.c b/udevstart.c index 1d9b60464c..2d11edeca2 100644 --- a/udevstart.c +++ b/udevstart.c @@ -87,6 +87,60 @@ static void udev_scan(void) DIR *dir; struct dirent *dent; + /* + * We want to scan the class tree first as lvm and dm needs to be able + * to have access to the char control device when probing the block + * devices. + */ + devpath = "class"; + dir = opendir(SYSCLASS); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[MAX_PATHLEN]; + DIR *dir2; + struct dirent *dent2; + + if ((strcmp(dent->d_name, ".") == 0) || + (strcmp(dent->d_name, "..") == 0)) + continue; + + snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); + dirname[MAX_PATHLEN] = '\0'; + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[MAX_PATHLEN-1]; + DIR *dir3; + struct dirent *dent3; + + if ((strcmp(dent2->d_name, ".") == 0) || + (strcmp(dent2->d_name, "..") == 0)) + continue; + + snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); + dirname2[MAX_PATHLEN-1] = '\0'; + + dir3 = opendir(dirname2); + if (dir3 != NULL) { + for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { + char filename[MAX_PATHLEN]; + + if (strcmp(dent3->d_name, "dev") == 0) { + snprintf(filename, MAX_PATHLEN, "/class/%s/%s", + dent->d_name, dent2->d_name); + filename[MAX_PATHLEN-1] = '\0'; + udev_exec(filename, dent->d_name); + } + } + closedir(dir3); + } + } + closedir(dir2); + } + } + closedir(dir); + } + devpath = "block"; dir = opendir(SYSBLOCK); if (dir != NULL) { @@ -138,58 +192,8 @@ static void udev_scan(void) } closedir(dir); } - - devpath = "class"; - dir = opendir(SYSCLASS); - if (dir != NULL) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[MAX_PATHLEN]; - DIR *dir2; - struct dirent *dent2; - - if ((strcmp(dent->d_name, ".") == 0) || - (strcmp(dent->d_name, "..") == 0)) - continue; - - snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); - dirname[MAX_PATHLEN] = '\0'; - dir2 = opendir(dirname); - if (dir2 != NULL) { - for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN-1]; - DIR *dir3; - struct dirent *dent3; - - if ((strcmp(dent2->d_name, ".") == 0) || - (strcmp(dent2->d_name, "..") == 0)) - continue; - - snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); - dirname2[MAX_PATHLEN-1] = '\0'; - - dir3 = opendir(dirname2); - if (dir3 != NULL) { - for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { - char filename[MAX_PATHLEN]; - - if (strcmp(dent3->d_name, "dev") == 0) { - snprintf(filename, MAX_PATHLEN, "/class/%s/%s", - dent->d_name, dent2->d_name); - filename[MAX_PATHLEN-1] = '\0'; - udev_exec(filename, dent->d_name); - } - } - closedir(dir3); - } - } - closedir(dir2); - } - } - closedir(dir); - } } - int main(int argc, char *argv[], char *envp[]) { init_logging("udevstart"); From c5d046b6c7f4dbd2072933b792f95f2793b28178 Mon Sep 17 00:00:00 2001 From: "atul.sabharwal@intel.com" Date: Sat, 26 Jun 2004 01:18:08 -0700 Subject: [PATCH 0795/4284] [PATCH] Patch for chassis_id exras module --- extras/chassis_id/Makefile | 38 +++++++++++++---------- extras/chassis_id/chassis_id.c | 57 ++++++++++++++-------------------- extras/chassis_id/chassis_id.h | 33 +++++++++++++------- extras/chassis_id/install.txt | 49 +++++++++++++++++++++++++++++ extras/chassis_id/table.c | 40 +++++++++++++----------- extras/chassis_id/udev.rules | 7 +++++ 6 files changed, 144 insertions(+), 80 deletions(-) create mode 100644 extras/chassis_id/install.txt create mode 100644 extras/chassis_id/udev.rules diff --git a/extras/chassis_id/Makefile b/extras/chassis_id/Makefile index d3152e863c..1b641cafda 100644 --- a/extras/chassis_id/Makefile +++ b/extras/chassis_id/Makefile @@ -1,19 +1,25 @@ -# -# ** -# ** (C) 2003 Intel Corporation -# ** Atul Sabharwal -# ** -# ** $Id: Makefile,v 1.3 2004/03/22 23:54:54 atul Exp $ -# ** -# ** Distributed under the terms of the GNU Public License, v2.0 or -# ** later. -# ** -# ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; -# ** with his permission, they have been re-licensed GPL, and his -# ** copyright still applies on them. -# ** -# */ -# +# * +# * Makefile +# * +# * Copyright (C) 2004 Intel Corporation. All rights reserved. +# * +# * This program is free software; you can redistribute it and/or +# * modify it under the terms of the GNU General Public +# * License v2.0 as published by the Free Software Foundation; +# * +# * 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., 59 Temple Place - Suite 330, +# * Boston, MA 021110-1307, USA. +# * +# * Authors: Atul Sabharwal +# * +# * CFLAGS = -g TARGET = chassis_id diff --git a/extras/chassis_id/chassis_id.c b/extras/chassis_id/chassis_id.c index 857707eac7..3fdfa96018 100644 --- a/extras/chassis_id/chassis_id.c +++ b/extras/chassis_id/chassis_id.c @@ -1,15 +1,24 @@ -/* -*-c-*-: - ** - ** (C) 2003 Intel Corporation - ** Atul Sabharwal - ** - ** Distributed under the terms of the GNU Public License, v2.0 or - ** later. - ** - ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; - ** with his permission, they have been re-licensed GPL, and his - ** copyright still applies on them - ** +/* + * chassis_id.c + * + * Copyright (C) 2004 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v 2.0 as published by the Free Software Foundation; + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + * Authors: Atul Sabharwal + * */ #include @@ -22,33 +31,13 @@ int main(int argc, char **argv, char ** envp) { - int chassis_num, slot_num, retval, host_num; + int chassis_num, slot_num, retval; char disk_snum[255], devpath[255]; char *ptr; int disk_index; syslog( LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", "starting chassis_id" ); -#if 0 - ptr = getenv("CHASSIS"); - if (ptr == NULL) - return -ERROR_NO_CHASSIS; - - sscanf(ptr, "%d", &chassis_num); - #ifdef DEBUG - syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "Chassis %d", chassis_num); - #endif - - - ptr = getenv("SLOT"); - if (ptr== NULL) - return -ERROR_NO_SLOT; - - sscanf(ptr, "%d", &slot_num); - #ifdef DEBUG - syslog( LOG_PID|LOG_DAEMON| LOG_ERR, "Slot %d", slot_num); - #endif -#endif ptr = getenv("DEVPATH"); if (ptr == NULL) return -ERROR_NO_DEVPATH; @@ -65,7 +54,7 @@ int main(int argc, char **argv, char ** envp) getserial_number(devpath, disk_snum); /* Now we open the provisioning table t find actual entry for the serial number*/ - disk_index = table_find_disk(disk_snum, &host_num, &chassis_num, &slot_num); + disk_index = table_find_disk(disk_snum, &chassis_num, &slot_num); if ( disk_index == -1 ) { // typical provisioning error return -ERROR_NO_DISK; diff --git a/extras/chassis_id/chassis_id.h b/extras/chassis_id/chassis_id.h index 253e603bfd..9937e3dfac 100644 --- a/extras/chassis_id/chassis_id.h +++ b/extras/chassis_id/chassis_id.h @@ -1,15 +1,24 @@ -/* -*-c-*-: - ** - ** (C) 2003 Intel Corporation - ** Atul Sabharwal - ** - ** Distributed under the terms of the GNU Public License, v2.0 or - ** later. - ** - ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; - ** with his permission, they have been re-licensed GPL, and his - ** copyright still applies on them. - ** +/* + * chassis_id.h + * + * Copyright (C) 2004 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v 2.0 as published by the Free Software Foundation; + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + * Authors: Atul Sabharwal + * */ #ifndef _CHASSIS_ID_H diff --git a/extras/chassis_id/install.txt b/extras/chassis_id/install.txt new file mode 100644 index 0000000000..a567afedcf --- /dev/null +++ b/extras/chassis_id/install.txt @@ -0,0 +1,49 @@ + +Udev does not come pre-installed on a Linux system. Hence, we need to do the following before +a Linux system is ready :: + +Steps: +~~~~~ +1. Install libsysfs shared libraries by installing sysfsutils-0.4.0. + +2. Download latest version of udev from www.kernel.org site. It is + under repository->utils->kernel path chain. + + Do make and make install so as to install udev. To install scsi_id, + go into extras/scsi_id folder to compile scsi_id. Typically, this + would be in /sbin folder. Now, change scsi_id.cfg and set the + global option to work with all devices ( -g) and comment out the + black list option ( -b ). + +3. Download chassis_id callout code and compile. Install chassis_id and + provision.tbl file in /usr/local/bin. + +4. In /etc/rc.sysinit, add mount command to mount the sys memory file + system. ( mount -t sysfs sys /sys ). The /sys is necessary as + lot of the software components expect it to be in /sys. + +5. Now, in /etc/udev/udev.rules, install the udev rules file. This + is the GDN config file which is used by udev to create folders + in the form chasis/slot/port/disk

      . + +6. Now, you are almost there. Refer to PROVISIONING file. + + +PROVISIONING: +1. For GDN, the provisioning file is in the format : + + + SCSI host on which the device is connected + how many disks on this blade ? + chassis Number + Physical slot number + Serial Number for the disk + Name of the disk device. + +2. To fill the provisioning table, the user needs to collect this information and + fill provision.tbl. + + The serial number is found from the command scsi_id -p 0x80 -s . + + The host number is availble from the sys file system. The chassis & slot + are visual data and should be enetered into provision.tbl. diff --git a/extras/chassis_id/table.c b/extras/chassis_id/table.c index e619fa9ef3..f4689ae243 100644 --- a/extras/chassis_id/table.c +++ b/extras/chassis_id/table.c @@ -1,17 +1,24 @@ -/* -*-c-*-: - ** - ** (C) 2003 Intel Corporation - ** Atul Sabharwal - ** - ** $Id: table.c,v 1.4 2004/03/18 21:56:24 atul Exp $ - ** - ** Distributed under the terms of the GNU Public License, v2.0 or - ** later. - ** - ** Many parts heavily based on test-skeleton.c, by Ulrich Drepper; - ** with his permission, they have been re-licensed GPL, and his - ** copyright still applies on them. - ** +/* + * table.c + * + * Copyright (C) 2004 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2.0 as published by the Free Software Foundation; + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + * + * Authors: Atul Sabharwal + * */ #include @@ -22,7 +29,6 @@ struct provision_record { int id; - int host_num; //port # or adaptor number int num_disks; int chassis_num; int slot_num; @@ -51,7 +57,7 @@ int table_init() while (!feof(fp)) { fgets(ptr, 80, fp); sscanf(ptr, "%d %d %d %d %d %s %s", &ptable[i].id, - &ptable[i].host_num, &ptable[i].num_disks, + &ptable[i].num_disks, &ptable[i].chassis_num, &ptable[i].slot_num, ptable[i].serial_num, ptable[i].name); i++; @@ -70,7 +76,6 @@ int table_find_disk( char * serialnumber , int * host_num, int * chassis_num, in for (i = 0; i < ptable_size; i++) { if (strcmp(ptable[i].serial_num, serialnumber) == 0) { - *host_num = ptable[i].host_num; *chassis_num = ptable[i].chassis_num; *slot_num = ptable[i].slot_num; break; @@ -91,7 +96,6 @@ int table_select_disk( int diskindex ) { printf("%d ", ptable[diskindex].chassis_num); printf("%d ", ptable[diskindex].slot_num); - printf("%d ", ptable[diskindex].host_num); printf("%s ", ptable[diskindex].name); } diff --git a/extras/chassis_id/udev.rules b/extras/chassis_id/udev.rules new file mode 100644 index 0000000000..b1618c1b0b --- /dev/null +++ b/extras/chassis_id/udev.rules @@ -0,0 +1,7 @@ +# There are a number of modifiers that are allowed to be used in some of the +# fields. See the udev man page for a full description of them. +# +# See the udev.rules.examples file for more examples of how to create rules +# + +BUS="scsi", PROGRAM="/usr/local/bin/chassis_id", NAME="/chassis%c{1}/slot%c{2}/%c{3}" From c59a72105d0ff8a47b31f1829dd3c166ebd859d0 Mon Sep 17 00:00:00 2001 From: "dsd@gentoo.org" Date: Sat, 26 Jun 2004 01:18:12 -0700 Subject: [PATCH 0796/4284] [PATCH] Writing udev rules doc update Here's an update to the documentation. It makes a few minor corrections and adds info about multiple-symlinks. It also seems that the patch I sent on April 27th (patching v0.53 to 0.54) was not applied, so this patch includes that update too, which was also just some small corrections plus added info on renaming network devices. --- docs/writing_udev_rules/index.html | 114 +++++++++++++++++++---------- 1 file changed, 74 insertions(+), 40 deletions(-) diff --git a/docs/writing_udev_rules/index.html b/docs/writing_udev_rules/index.html index 1a2702aeaf..9396184366 100644 --- a/docs/writing_udev_rules/index.html +++ b/docs/writing_udev_rules/index.html @@ -8,7 +8,7 @@

      Writing udev rules

      by Daniel Drake (dsd)
      -Version 0.53

      +Version 0.55

      The most recent version of this document can always be found at:
      http://www.reactivated.net/udevrules.php @@ -32,14 +32,16 @@ The most recent version of this document can always be found at:
    • Additional notes on writing rules for USB storage
    • Example: Writing convenience rules for my CD drives
    • +
    • Example: Writing a rule to name my network interface
    • Tips for finding the appropriate places in SYSFS
    • +
    • Using multiple SYMLINK style rules
    • udev vs Nvidia's graphics drivers
    • Author and credits
    • About this document

      -udev is targetted at Linux kernels 2.6 and beyond to provide a userspace solution for a dynamic /dev directory, with persistant 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.

      +udev is targetted 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.

      udev is a well thought out solution, but I was initially very confused how I might customise it for my system. This document attempts to make the process of rule writing a little bit clearer.

      @@ -51,20 +53,21 @@ This document assumes that you have udev/hotplug installed and running OK with d

      History

      -April 15th 2004: Minor corrections. Added info about NAME{all_partitions}. Added info about other udevinfo tricks.

      -April 14th 2004: Reverted to suggesting using "udev.rules" until the udev defaults allow for other files. Minor work.

      -April 6th 2004: I now write suggest users to use their own "local.rules" file rather than prepending "udev.rules".

      -April 3rd 2004: Minor cleanups and preparations for possible inclusion in the udev distribution.

      -February 15th 2004: Initial publication.

      -February 18th 2004: Fixed a small omission in an example. Updated section on identifying mass-storage devices. Updated section on nvidia.

      -February 23rd 2004: 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.

      -March 20th 2004: General improvements, clarifications, and cleanups. Added more information about writing rules for usb-storage.

      +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.

      Software versions used at time of writing

      -Linux Kernel 2.6.5-rc3
      - -udev 024
      +Linux Kernel 2.6.7
      +udev 027
      hotplug 20040401

      @@ -84,26 +87,24 @@ The original /dev directories were just populated with every device that As stated above, writing rules for udev is an optional process. By default, you can plug a device in, and the a relevant node (e.g. /dev/sda for a mass-storage device) will be there, just like in previous /dev implementations.

      -However, udev allows you to customise the naming of device nodes. There are two reasons why you might want to do this: convenience, and persistant naming.

      +However, udev allows you to customise the naming of device nodes. There are two reasons why you might want to do this: convenience, and persistent naming.

      -Take the example of using udev, so that when your printer is plugged in, it gets named as /dev/printer and also as the usual /dev/lp0. It's not only convenience (e.g. reading and interpreting "printer" as opposed to "lp0"), its a solution for non-persistant naming. Say that I have two printers - a HP laser printer and an Epson inkjet. When they are both plugged in and on, I have /dev/lp0 and /dev/lp1.
      +Take the example of using udev, so that when your printer is plugged in, it gets named as /dev/printer and also as the usual /dev/lp0. It's not only convenience (e.g. reading and interpreting "printer" as opposed to "lp0"), its a solution for non-persistent naming. Say that I have two printers - a HP laser printer and an Epson inkjet. When they are both plugged in and on, I have /dev/lp0 and /dev/lp1.
      How do I know which node refers to which printer? There is no easy way. The first printer that got connected was assigned name "lp0", and the second "lp1". Plugging in my printers in a different order would swap the names here, and that would mess up my scripts that always expect my HP laser printer to be lp1.

      -However, if my HP laser printer got named lp_hp (as well as lpX) and my other printer got named lp_epson (as well as lpY), then my scripts could just refer to those names. udev magic can control this and ensure that these persistant names always point to the device that I intended.

      +However, if my HP laser printer got named lp_hp (as well as lpX) and my other printer got named lp_epson (as well as lpY), then my scripts could just refer to those names. udev magic can control this and ensure that these persistent names always point to the device that I intended.

      -For external mass-storage devices (e.g. usb hard disks), persistant naming is very helpful in that it allows you to hardcode accurate device paths into your /etc/fstab.

      +For external mass-storage devices (e.g. usb hard disks), persistent naming is very helpful in that it allows you to hardcode accurate device paths into your /etc/fstab.

      The basics of writing rules

      -When populating /dev, udev decides which nodes to include, and how to name them, by reading a rules file. This rules file is processed from top to bottom, and udev will stop processing rules for a device once it finds one that matches.

      +When populating /dev, udev decides which nodes to include, and how to name them, by reading a series of rules files.

      -Default udev rules are stored in /etc/udev/udev.rules. The default file includes some examples, and defaults to giving a devfs-style layout. The examples may safely be removed, but it is generally sensible to keep the devfs rules and simply make your own amendments and modifications. You should write your rules in this file, above the examples and default devfs-style rules.

      +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, to reduce hassle while updating your udev installation in the future.

      - +Files in /etc/udev/rules.d/ are parsed in lexical order. udev will stop processing rules as soon as it finds a matching rule in a file for the new item of hardware that has been detected. It is important that your own rules get processed before the udev defaults, otherwise your own naming schemes will not take effect! I suggest that you keep your own rules in a file at /etc/udev/rules.d/10-local.rules (this doesn't exist by default - create it). As 10 comes before 50, you know that your rules will be looked at first.

      As your own rules will effectively mask out the udev defaults which create the base /dev layout, it is recommended that you also specify devfs-style names/symlinks for the rules you write, so that you get the sensible defaults plus your own names.

      @@ -271,7 +272,13 @@ You will notice that a lot of information is not relevant for writing basic rule I will show three examples of this rule writing based on udevinfo output process below. I will then attempt to list some device-dependant tips and tricks for locating the correct info.

      -A reader wrote to me and informed me that he found KDE's control centre useful for writing rules. Apparently, information about USB devices (and others) can be found in the "Info Centre" section of the KDE Control Centre. This interface shows information such as serial number, vendor ID, etc. If you prefer a GUI-like approach, you might want to investigate this. +A reader wrote to me and informed me that he found KDE's control centre useful for writing rules. Apparently, information about USB devices (and others) can be found in the "Info Centre" section of the KDE Control Centre. This interface shows information such as serial number, vendor ID, etc. If you prefer a GUI-like approach, you might want to investigate this.

      + +The current releases of gnome-volume-manager are unable to treat symlink-nodes as real devices. Conversely as described above, you may wish to specify your own naming in the NAME parameter and specify %k in the SYMLINK parameter.

      + +The behaviour of your own rules masking the defaults can be overcome if you write multiple-SYMLINK style rules. + +

      Example: Writing a rule for my USB printer

      @@ -301,22 +308,17 @@ And my printer nodes exist at /dev/lp0 (or /dev/lp1 if another pri Quick Intro: My camera identifies itself as an external SCSI hard disk (it uses the usb-storage driver which is also used by devices such as USB hard disks and flash-card readers). I can then mount the partition on that disk and copy images over. Not all cameras work like this - many require external software (e.g. gphoto2) to be able to access photos.

      -This one is a bit tricky. Two nodes are created by default when my camera is connected : /dev/sda and /dev/sda1. sda1 is the node that I would like as my /dev/camera, as that is what gets mounted. The problem is that there are only small details which can be used as udev rules to show the difference between sda and sda1.

      +This one is a bit tricky. Several nodes are created by default when my camera is connected : /dev/sda and /dev/sda1, and possibly even /dev/sg1. This is an example where specifity is important - if your rule is not specific enough, it could match any of the above 3 nodes.

      -As these nodes (sda, sda1) are treated as block devices, looking in /sys/block would be a good place to start.

      +sda1 is the node that I would like as my /dev/camera, as that is what gets mounted. udevinfo did not point out any useful differences between sda, sda1, and sg1. I decided that a reliable way to differentiate between these 3 nodes would be to look at the KERNEL name.

      -In my /sys/block, I have a directory named sda. In my /sys/block/sda, I have a directory named sda1. Both of these directories have dev files in, so they are OK for udev rules. Running the following dumps a lot of information about my camera and the USB ports it is connected through. +A key such as KERNEL="sd?1" would match KERNEL names such as "sda1", "sdb1", "sdc1", and equally importantly, it will not match KERNEL names such as sda, sdb, or sg1. The purpose of this key is to ignore the /dev/sda and /dev/sg1 nodes. The device is a digital camera - I would not dream of fdisking it or anything like that, so these 2 nodes are pretty useless to me. The key attempts to capture the /dev/sda1 node, which is mountable and therefore useful!

      -
      -# udevinfo -a -p /sys/block/sda
      -# udevinfo -a -p /sys/block/sda/sda1
      -
      +As this node (sda1) is treated as a block device, looking in /sys/block would be a good place to start.

      -The output of both of these command was almost identical, so that does not help in writing keys to differentiate between sda and sda1.
      +In my /sys/block, I have a directory named sda. In my /sys/block/sda, I have a directory named sda1. Both of these directories have dev files in, so they are OK to run udevinfo on. Running the following dumps a lot of information about my camera and the USB port it is connected through. -To differentiate between sda and sda1, I decided that matching KERNEL names would be most appropriate here. Some examples of KERNEL names for this type of device are: sda, sda1, sdb, sdb1, sdc, ...

      - -udev's support for wildcards in key expressions comes in handy here. A key such as KERNEL="sd?1" would match KERNEL names such as "sda1", "sdb1", "sdc1", and equally importantly, it will not match KERNEL names such as sda, sdb (because the name must have a "1" on the end). The purpose of this key is to ignore the /dev/sda node. The device is a digital camera - I would not dream of fdisking it or anything like that, so this node is pretty useless to me. The key attempts to capture the /dev/sda1 node, which is mountable and therefore useful!

      +
      # udevinfo -a -p /sys/block/sda/sda1
      In the udevinfo output, I also noticed this bit of useful and understandable information:
      SYSFS{product}="USB 2.0M DSC"
      @@ -324,7 +326,7 @@ In the udevinfo output, I also noticed this bit of useful and understandable inf So that gives me my rule. For completeness, I also include a BUS key (this was also found in the udevinfo output).
      BUS="usb", SYSFS{product}="USB 2.0M DSC", KERNEL="sd?1", NAME="%k", SYMLINK="camera"
      -Now, when my camera is plugged in, it will be named /dev/sda1 (or, if sda1 isnt available, it might be called /dev/sdb1) and will always be correctly linked to from /dev/camera. The /dev/sda (or sdb) node still appears as normal, but the important thing is that my custom persistant "camera" symlink points to the mountable partition.

      +Now, when my camera is plugged in, it will be named /dev/sda1 (or, if sda1 isnt available, it might be called /dev/sdb1) and will always be correctly linked to from /dev/camera. The /dev/sda (or sdb) node still appears as normal, but the important thing is that my custom persistent "camera" symlink points to the mountable partition.

      Additional notes on writing rules for USB storage

      @@ -349,7 +351,7 @@ This problem also applies to other USB disks - e.g. if you create a new partitio udev provides a solution here - it is able to create nodes for all partitions of a block device. For every rule that you specify, the block device will have all 16 partition nodes created. To achieve this, you can simply modify the NAME key, as shown below:
      -
      BUS="usb", SYSFS{product}="USB 2.0 Storage Device", NAME{all_partitions}="usbhd%n"
      +
      BUS="usb", SYSFS{product}="USB 2.0 Storage Device", NAME{all_partitions}="usbhd"
      You will now have nodes named: usbhd, usbhd1, usbhd2, usbhd3, ..., usbhd15.

      @@ -359,13 +361,31 @@ I have two CD drives in my PC - a DVD reader, and a CD rewriter. My DVD is hdc a Still, some people (myself included) like to have nodes such as /dev/dvd and /dev/cdrw for convenience. Since we know the "hdX" values for these drives, writing rules is simple. The examples below should be self explanatory. -
       BUS="ide", KERNEL="hdc", NAME="%k", SYMLINK="dvd cdroms/cdrom%n"
       BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n"
       
      -You may have noticed that the default udev.rules file contains a rule which runs a script to produces names for block devices. Do not be confused by this - as usual, because your own rules are located at the top of the rules file, they are processed before the default rules, so the default rules will not be used when naming the hardware you have written rules for.

      +You may have noticed that the default 50-udev.rules file contains a rule which runs a script to produces names for block devices. Do not be confused by this - as usual, because your own rules are located in a file which is processed before the default rules, the defaults will not be used when naming the hardware you have written rules for.

      + + +

      Example: Writing a rule to name my network interface

      +An interesting new feature in recent udev versions is the ability to write rules to name your network interfaces. Network interfaces do not show up in /dev, but they are generally referenced by names (e.g. with ifconfig). Despite the differences, the rule writing process is almost identical.

      + +As usual, udevinfo comes to our aid in rule-writing. In my example, I wish to rename my "eth0" network device (the following output is snipped): + +
      +# udevinfo -a -p /sys/class/net/eth0/
      +  looking at class device '/sys/class/net/eth0':
      +    SYSFS{address}="00:52:8b:d5:04:48"
      +
      + +Every network adapter has its own unique MAC-address, so I chose to use this when writing my rule. This will not change, unless you change your network card. An example rule is shown below: + +
      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.

      Tips for finding the appropriate places in SYSFS

      @@ -383,6 +403,18 @@ BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n"
    • Remember that unfortunately, the kernel does not export information for all devices into sysfs, meaning that you simply can't write rules for some devices yet. On 20/02/04, the udev author stated that there are 162 drivers left to convert to sysfs.
    + +

    Using multiple SYMLINK style rules

    +Another recent feature is the ability to write rules that do not specify a NAME, but instead they simply specify SYMLINK keys. This allows you to avoid the issue where your own rules effectively mask the udev defaults.

    + +Take the rule:
    +
    KERNEL="hdc", SYMLINK="dvd"
    + +When udev finds this rule, it will take a mental note of it. Upon finding another rule matching the same device which also includes a NAME parameter, udev will create the node as specified by the NAME parameter, plus symbolic links as specified by the SYMLINK parameters of both rules.
    +To put it into practical terms, when udev is naming nodes for my hdc device, it will use the default rules for block devices as usual, with the addition of my personal symlink "dvd".

    + +Similarly to normal rules, rules of this type will only take effect if udev is able to find them before it finds a rule specifying a NAME parameter.

    +

    udev vs Nvidia's graphics drivers

    @@ -390,9 +422,9 @@ BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n" Nvidia's graphics drivers (the closed-source ones, not the ones that come with XFree) do not work with a default installation of udev - you are unable to start X. This is because the nvidia module is loaded by X, but the /dev/nvidia* nodes are not created quick enough, so X bails out.

    -The solution to this problem is to autoload the nvidia module on bootup. Yes - you are *supposed* to do this - the NVidia FAQ confirms this! On devfs-based systems, devfs did this automatically at bootup anyway. Your linux distribution will have created a file which you can list modules to be loaded on bootup (e.g. /etc/modules.autoload.d/kernel-2.6 for Gentoo).

    +The solution to this problem is to autoload the nvidia module on bootup. Yes - you are *supposed* to do this - the NVidia FAQ confirms this! On devfs-based systems, devfs did this automatically at bootup anyway. Your linux distribution will have created a file which you can list modules to be loaded on bootup (e.g. /etc/modules.autoload.d/kernel-2.6 for Gentoo, /etc/modules for Debian).

    -This isn't all - you will also need to patch the nvidia kernel interface to export some basic info to SYSFS so that udev will create the devices. Martin Schlemmer has written a patch against the 1.0.5336 version of the nvidia drivers, which can be found here. The Gentoo package nvidia-kernel-1.0.5336-r1 contains this patch.

    +This isn't all - you will also need to patch the nvidia kernel interface to export some basic info to SYSFS so that udev will create the devices. Martin Schlemmer has written a patch against the 1.0.5336 version of the nvidia drivers, which can be found here. The Gentoo package nvidia-kernel-1.0.5336-r4 contains this patch.

    Another solution is to simply create the nvidia specific nodes on bootup. X will then load the module when required, and as the nodes are already in existance, you will not run into the problem described above. Place these commands in a file that is automatically executed on bootup (e.g. /etc/conf.d/local.start for Gentoo):
    @@ -412,10 +444,12 @@ Additional thanks to:
     
  • The udev developers!
  • agrippa_cash (usb-storage info)
  • Carl Streeter (usb-storage info)
  • +
  • David Watson
  • Decibels
  • Frank Pieczynski
  • Feth Arezki
  • Jim (KDE info)
  • +
  • Johannes Jordens
  • Kay Sievers
  • Patrick Dreker
  • Todd Musall
  • From 062db23d5eb303ef49d2ff805381229932f44246 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Sat, 26 Jun 2004 01:18:17 -0700 Subject: [PATCH 0797/4284] [PATCH] update udev scsi_id to scsi_id 0.5 This patch syncs the scsi_id in the udev tree to version 0.5. --- extras/scsi_id/ChangeLog | 39 +++++++++++++++++++ extras/scsi_id/Makefile | 3 +- extras/scsi_id/TODO | 9 +++-- extras/scsi_id/gen_scsi_id_udev_rules.sh | 35 ++++++++--------- extras/scsi_id/release-notes | 49 ++++++++++-------------- extras/scsi_id/scsi_id.8 | 20 +++++----- extras/scsi_id/scsi_id.c | 21 +++++----- extras/scsi_id/scsi_id.config | 12 +++--- extras/scsi_id/scsi_id.h | 6 +-- extras/scsi_id/scsi_serial.c | 8 ++++ 10 files changed, 119 insertions(+), 83 deletions(-) diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog index 095d84f2d0..bfa353431b 100644 --- a/extras/scsi_id/ChangeLog +++ b/extras/scsi_id/ChangeLog @@ -1,3 +1,42 @@ +2004-jun-23: + * scsi_id.h: increase MAX_SERIAL_LEN from 128 to 256, as some + devices (maybe broken ones) are giving really long id's. + +2004-jun-17: + * Makefile: Olaf Hering add spotless target (already in udev). + +2004-jun-17: + * scsi_serial.c: Include linux/compiler.h so we can build with + klibc using kernel headers. + +2004-may-24: + * scsi_id.c: Rename major and minor to maj min to avoid compiler + warnings when compiled with -D_GNU_SOURCE. + +2004-mar-30: + * scsi_id.config: Minor wording changes + +2004-mar-30: + * scsi_id.h: Don't supply a makedev() when built under klibc. + +2004-mar-30: + * scsi_id.c: Ken Brush Have the command line + options override generic options. + +2004-mar-05: + * scsi_serial.c: Log INQUIRY failure, including the + failing page code and vpd values. And add a dprintf() to + the scsi_inquiry function. + +2004-mar-02: + * gen_scsi_id_udev_rules.sh: Per bug report from Atul Sabharwal + change to not require that sysfs be + in the mount tab (and default to "/sys"), and fix so scsi_id + results containing spaces work correctly. + +2004-mar-02: + * scsi_id.8: Escape '-' with '\-'. + 2004-feb-25: * scsi_id.8: Add verbage about usage with udev, and running via hotplug. diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 6af4d7f18e..8fe29f3647 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.4 +SCSI_ID_VERSION=0.5 prefix = etcdir = ${prefix}/etc @@ -71,5 +71,6 @@ clean: rm -f $(PROG) $(OBJS) $(GEN_HEADER) spotless: clean + $(PROG): $(OBJS) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO index 4f302ea0a4..e0283cf444 100644 --- a/extras/scsi_id/TODO +++ b/extras/scsi_id/TODO @@ -1,6 +1,9 @@ -- Document that config file options override command line options, or fix - the code. This means a '-b' in the config file disables any -g on the - command line. +- Add an option to replace blanks with spaces, so the generated id can be + more easily used as a /dev name. + +- Add a bus white/black list option. So for example, all scsi devices + under USB could easily be blacklisted. This should allow multiple busses + to be listed. - Add code to check that SCSI commands get back enough data for their intended usage, mainly callers of scsi_inquiry(). diff --git a/extras/scsi_id/gen_scsi_id_udev_rules.sh b/extras/scsi_id/gen_scsi_id_udev_rules.sh index 07e21ebd50..874e94e8bb 100644 --- a/extras/scsi_id/gen_scsi_id_udev_rules.sh +++ b/extras/scsi_id/gen_scsi_id_udev_rules.sh @@ -27,22 +27,12 @@ prefix=disk- scsi_id=/sbin/scsi_id -dump_ids() -{ - cd ${sysfs_dir}/block - for b in sd* - do - echo -n "$b " - $scsi_id -s /block/$b - if [ $? != 0 ] - then - echo $0 failed for device $b >&2 - exit 1 - fi - done -} - sysfs_dir=$(mount | awk '$5 == "sysfs" {print $3}') +if [ "$sysfs_dir" = "" ] +then + sysfs_dir="/sys" + echo "Using sysfs mount point \"$sysfs_dir\"" >&2 +fi c=$(ls /${sysfs_dir}/block/sd* 2>/dev/null | wc -l) if [ $c = 0 ] @@ -56,12 +46,17 @@ echo "# Start of autogenerated scsi_id rules. Edit the NAME portions of these" echo "# rules to your liking." echo "#" first_line=yes -dump_ids | while read in + +# +cd ${sysfs_dir}/block +for name in sd* do - set $in - name=$1 - shift - id="$*" + id=$($scsi_id -s /block/$name) + if [ $? != 0 ] + then + echo $0 failed for device $name exiting >&2 + exit 1 + fi if [ $first_line = "yes" ] then first_line=no diff --git a/extras/scsi_id/release-notes b/extras/scsi_id/release-notes index a10b569c2d..2996713117 100644 --- a/extras/scsi_id/release-notes +++ b/extras/scsi_id/release-notes @@ -1,49 +1,42 @@ -Version 0.4 of scsi_id is available at: +Version 0.5 of scsi_id is available at: -http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.4.tar.gz +http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.5.tar.gz scsi_id is a program to generate a unique identifier for a given SCSI device. -It is primarily for use with the udev callout key. It could also be used -for automatic multi-path configuration or device mapper configuration. +It is primarily for use with the udev program key, or hotplug scripts that +want persistent naming of scsi devices. It could also be used for +automatic multi-path configuration or device mapper configuration. -Version 0.4 requires: +Version 0.5 requires: - Linux kernel 2.6 - libsysfs 0.4.0 Major changes since the last release: - - Support block device partitions + - Ken Brush have the command line options + override generic options. - - Added a script to auto-generate udev rules. The script is not - installed but is part of the tarball. + - Fix the gen_scsi_id_udev_rules.sh to handle spaces in the id. -Detailed changes: + - Don't supply a makedev() when built with klibc. Also, the + scsi_id supplied makedev() was using the old major/minor method. - - Add man page verbage about usage with udev, and running via - hotplug + - Include compiler.h so we can build against klibc, as recent sg.h + changes need a define for __user. - - Disable support for -e (all output to stderr) as it cannot be - used in any useful way, and the -c (device specific callout) as - the code is incomplete and has no users. +Other changes: - - Don't print errno for NULL return from sysfs_get_classdev_device. + - Increase the MAX_SERIAL_LEN from 128 to 256, as some (possibly + broken devics) are returning very long id's - - Get rid of dead/leftover code that checked if we are on a scsi - bus. + - Add spotless target (via Olaf Hering's udev patch) - - ":" consistently in output messages. + - minor wording changes in scsi_id.config - - Add missing new lines for some error messages. + - Log INQUIRY failure, including the failing page code and vpd + values - - open O_NONBLOCK so we handle tape drives without tapes loaded. - - - Remove hacks based on KLIBC define to get around problems when - building with udev (udev libsysfs files were rearranged). - - - As done in udev code, support partitions via looking for a - parent of the target path. Uses libsysfs functions to do most of - the work, and includes changing a lot of variables to be struct - sysfs_device instead of sysfs_class_device. + - Escape '-' with '\-' in the man page. diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index db3effbc45..69dd2a998a 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -12,12 +12,12 @@ 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. +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-g\fP option must +By default all devices are assume black listed, the \fB\-g\fP option must be specified on the command line or in the config file for any useful behaviour. @@ -58,18 +58,18 @@ mode, and expects the environment variable DEVPATH to specify the corresponding sysfs device. See section below on usage with \fBudev\fP. .TP .BI \-b -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. +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 \-d "\| 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 +entry as done for the \fB\-s\fP, send SG_IO commands to \fBdevice\fP, such as \fB/dev/sdc\fP. .TP -.BI \-f "\| config-file" +.BI \-f "\| config\-file" Read configuration and black/white list entries from -.B config-file +.B config\-file rather than the default .B /etc/scsi_id.config file. @@ -89,9 +89,9 @@ Use SCSI INQUIRY VPD page code 0x80 or 0x83. The default behaviour is to query the available VPD pages, and use page 0x83 if found, else page 0x80 if found, else nothing. .TP -.BI \-s "\| sysfs-device" +.BI \-s "\| sysfs\-device" Generate an id for the -.B sysfs-device. +.B sysfs\-device. The sysfs mount point must not be included. For example, use /block/sd, not /sys/block/sd. .TP @@ -113,7 +113,7 @@ and the results will likely not be as expected. When in this mode, all errors and warnings are sent via syslog. -To determine the specific value needed in a RESULT key, use the -s option, +To determine the specific value needed in a RESULT key, use the \-s option, for example: .sp diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 1cd6981e5e..e893987868 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -111,7 +111,7 @@ int sysfs_get_attr(const char *devpath, const char *attr, char *value, return sysfs_read_attribute_value(attr_path, value, SYSFS_NAME_LEN); } -static int get_major_minor(const char *devpath, int *major, int *minor) +static int get_major_minor(const char *devpath, int *maj, int *min) { char dev_value[MAX_ATTR_LEN]; @@ -129,7 +129,7 @@ static int get_major_minor(const char *devpath, int *major, int *minor) } dprintf("dev value %s", dev_value); /* dev_value has a trailing \n */ - if (sscanf(dev_value, "%u:%u", major, minor) != 2) { + if (sscanf(dev_value, "%u:%u", maj, min) != 2) { log_message(LOG_WARNING, "%s: invalid dev major/minor\n", devpath); return -1; @@ -140,18 +140,18 @@ static int get_major_minor(const char *devpath, int *major, int *minor) static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) { - int major, minor; + int maj, min; dprintf("(%s)\n", devpath); - if (get_major_minor(devpath, &major, &minor)) + if (get_major_minor(devpath, &maj, &min)) return -1; snprintf(tmpdev, MAX_NAME_LEN, "%s/%s-maj%d-min%d-%u", - TMP_DIR, TMP_PREFIX, major, minor, getpid()); + TMP_DIR, TMP_PREFIX, maj, min, getpid()); dprintf("tmpdev '%s'\n", tmpdev); - if (mknod(tmpdev, 0600 | dev_type, makedev(major, minor))) { + if (mknod(tmpdev, 0600 | dev_type, makedev(maj, min))) { log_message(LOG_WARNING, "mknod failed: %s\n", strerror(errno)); return -1; } @@ -759,10 +759,6 @@ int main(int argc, char **argv) strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); strncat(target_path, devpath, MAX_NAME_LEN); - } else { - if (set_options(argc, argv, short_options, target_path, - maj_min_dev) < 0) - exit(1); } /* @@ -779,6 +775,11 @@ int main(int argc, char **argv) exit(1); free(newargv); } + if (!hotplug_mode) { + if (set_options(argc, argv, short_options, target_path, + maj_min_dev) < 0) + exit(1); + } if (!sys_specified) { log_message(LOG_WARNING, "-s must be specified\n"); diff --git a/extras/scsi_id/scsi_id.config b/extras/scsi_id/scsi_id.config index f3fc4b3fda..0567ecb7d6 100644 --- a/extras/scsi_id/scsi_id.config +++ b/extras/scsi_id/scsi_id.config @@ -9,12 +9,12 @@ # INQUIRY product identification field. Per the SCSI INQUIRY, the vendor # is limited to 8 bytes, model to 16 bytes. # -# The first maching line found is used. Short matches match longer ones, +# 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. # -# The "option" line is searched when scsi_id first starts up (for use with -# hotplug during boot). +# The "options" line is searched for when scsi_id starts up, and is +# primarily for use with hotplug. # # options= # @@ -32,12 +32,12 @@ options=-b # vendor=someone, model=nicedrive, options=-g -# If you all the scsi devices are your system support valid id's, remove -# the -b line above, and mark all devices as good: +# If you know all the scsi devices on your system support valid id's, +# remove the options=-b line, and mark all devices as good: ## options=-g # Then black list any offenders. Missing entries here could be dangerous -# if you rely on the id for naming or multi-path configuration! +# if you rely on the id for persistent naming or multi-path configuration. ## vendor=ELBONIA, model=borken, options=-b diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 9edb39ec49..10599ebb5f 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -37,7 +37,7 @@ * MAX_SERIAL_LEN: the maximum length of the serial number, including * added prefixes such as vendor and product (model) strings. */ -#define MAX_SERIAL_LEN 128 +#define MAX_SERIAL_LEN 256 /* * MAX_BUFFER_LEN: maximum buffer size and line length used while reading @@ -53,10 +53,6 @@ extern int scsi_get_serial (struct sysfs_device *scsi_dev, const char extern void log_message (int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); -#ifdef __KLIBC__ -#define makedev(major, minor) ((major) << 8) | (minor) -#endif - #ifndef u8 typedef unsigned char u8; #endif diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index ae83330c30..e0074b662d 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -30,6 +30,7 @@ #include #include #include +#include /* need __user when built via klibc */ #include #include #include "scsi_id.h" @@ -312,6 +313,8 @@ static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned buffer = inq + OFFSET; resend: + dprintf("%s evpd %d, page 0x%x\n", scsi_dev->name, evpd, page); + memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); io_hdr.interface_id = 'S'; io_hdr.cmd_len = sizeof(inq_cmd); @@ -352,6 +355,11 @@ resend: retval = -1; } + if (retval < 0) + log_message(LOG_WARNING, + "%s: Unable to get INQUIRY vpd %d page 0x%x.\n", + scsi_dev->name, evpd, page); + free(inq); return retval; } From b99f344fde90ddc131ea6e2ec8520e018e1274e2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 26 Jun 2004 01:18:21 -0700 Subject: [PATCH 0798/4284] [PATCH] update udev_volume_id volume_id is now able to read NTFS labels. Not very exciting, but we keep up to date with the version in HAL. Also __packed__ was needed for the structs, cause the gcc 3.4 compiled version was no longer working properly. --- extras/volume_id/volume_id.c | 540 +++++++++++++++++++++++------------ extras/volume_id/volume_id.h | 18 +- 2 files changed, 361 insertions(+), 197 deletions(-) diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index dcc341c4dd..ac7e76b9d4 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -7,7 +7,7 @@ * the e2fsprogs. This is a simple straightforward implementation for * reading the label strings of only the most common filesystems. * If you need a full featured library with attribute caching, support for - * much more partition/media types or non-root data access, you may have + * much more partition/media types or non-root disk access, you may have * a look at: * http://e2fsprogs.sourceforge.net. * @@ -26,6 +26,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + #include #include #include @@ -55,12 +59,23 @@ (((__u32)(x) & 0x0000ff00u) << 8) | \ (((__u32)(x) & 0x000000ffu) << 24)) +#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000u) >> 56) | \ + (((__u64)(x) & 0x00ff000000000000u) >> 40) | \ + (((__u64)(x) & 0x0000ff0000000000u) >> 24) | \ + (((__u64)(x) & 0x000000ff00000000u) >> 8) | \ + (((__u64)(x) & 0x00000000ff000000u) << 8) | \ + (((__u64)(x) & 0x0000000000ff0000u) << 24) | \ + (((__u64)(x) & 0x000000000000ff00u) << 40) | \ + (((__u64)(x) & 0x00000000000000ffu) << 56)) + #if (__BYTE_ORDER == __LITTLE_ENDIAN) #define le16_to_cpu(x) (x) #define le32_to_cpu(x) (x) +#define le64_to_cpu(x) (x) #elif (__BYTE_ORDER == __BIG_ENDIAN) #define le16_to_cpu(x) bswap16(x) #define le32_to_cpu(x) bswap32(x) +#define le64_to_cpu(x) bswap64(x) #endif /* size of superblock buffer, reiser block is at 64k */ @@ -69,15 +84,17 @@ #define SEEK_BUFFER_SIZE 0x800 -static void set_label_raw(struct volume_id *id, char *buf, int count) +static void set_label_raw(struct volume_id *id, + const __u8 *buf, unsigned int count) { memcpy(id->label_raw, buf, count); id->label_raw_len = count; } -static void set_label_string(struct volume_id *id, char *buf, int count) +static void set_label_string(struct volume_id *id, + const __u8 *buf, unsigned int count) { - int i; + unsigned int i; memcpy(id->label_string, buf, count); @@ -90,9 +107,42 @@ static void set_label_string(struct volume_id *id, char *buf, int count) id->label_string[i+1] = '\0'; } -static void set_uuid(struct volume_id *id, unsigned char *buf, int count) +#define LE 0 +#define BE 1 +static void set_label_unicode16(struct volume_id *id, + const __u8 *buf, + unsigned int endianess, + unsigned int count) { - int i; + unsigned int i, j; + __u16 c; + + j = 0; + for (i = 0; i <= count-2; i += 2) { + if (endianess == LE) + c = (buf[i+1] << 8) | buf[i]; + else + c = (buf[i] << 8) | buf[i+1]; + if (c == 0) { + id->label_string[j] = '\0'; + break; + } else if (c < 0x80) { + id->label_string[j++] = (__u8) c; + } else if (c < 0x800) { + id->label_string[j++] = (__u8) (0xc0 | (c >> 6)); + id->label_string[j++] = (__u8) (0x80 | (c & 0x3f)); + } else { + id->label_string[j++] = (__u8) (0xe0 | (c >> 12)); + id->label_string[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); + id->label_string[j++] = (__u8) (0x80 | (c & 0x3f)); + } + } +} + +static void set_uuid(struct volume_id *id, + const __u8 *buf, unsigned int count) +{ + unsigned int i; memcpy(id->uuid, buf, count); @@ -121,9 +171,10 @@ set: } } -static char *get_buffer(struct volume_id *id, size_t off, size_t len) +static __u8 *get_buffer(struct volume_id *id, + unsigned long off, unsigned int len) { - size_t buf_len; + unsigned int buf_len; /* check if requested area fits in superblock buffer */ if (off + len <= SB_BUFFER_SIZE) { @@ -135,8 +186,8 @@ static char *get_buffer(struct volume_id *id, size_t off, size_t len) /* check if we need to read */ if ((off + len) > id->sbbuf_len) { - dbg("read sbbuf len:0x%x", off + len); - lseek(id->fd, 0, SEEK_SET); + dbg("read sbbuf len:0x%lx", off + len); + lseek64(id->fd, 0, SEEK_SET); buf_len = read(id->fd, id->sbbuf, off + len); id->sbbuf_len = buf_len; if (buf_len < off + len) @@ -158,9 +209,10 @@ static char *get_buffer(struct volume_id *id, size_t off, size_t len) /* check if we need to read */ if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { - dbg("read seekbuf off:0x%x len:0x%x", off, len); - lseek(id->fd, off, SEEK_SET); + dbg("read seekbuf off:0x%lx len:0x%x", off, len); + lseek64(id->fd, off, SEEK_SET); buf_len = read(id->fd, id->seekbuf, len); + dbg("got 0x%x (%i) bytes", buf_len, buf_len); id->seekbuf_off = off; id->seekbuf_len = buf_len; if (buf_len < len) @@ -191,23 +243,23 @@ static void free_buffer(struct volume_id *id) static int probe_ext(struct volume_id *id) { struct ext2_super_block { - __u32 inodes_count; - __u32 blocks_count; - __u32 r_blocks_count; - __u32 free_blocks_count; - __u32 free_inodes_count; - __u32 first_data_block; - __u32 log_block_size; - __u32 dummy3[7]; - unsigned char magic[2]; - __u16 state; - __u32 dummy5[8]; - __u32 feature_compat; - __u32 feature_incompat; - __u32 feature_ro_compat; - unsigned char uuid[16]; - char volume_name[16]; - } *es; + __u32 inodes_count; + __u32 blocks_count; + __u32 r_blocks_count; + __u32 free_blocks_count; + __u32 free_inodes_count; + __u32 first_data_block; + __u32 log_block_size; + __u32 dummy3[7]; + __u8 magic[2]; + __u16 state; + __u32 dummy5[8]; + __u32 feature_compat; + __u32 feature_incompat; + __u32 feature_ro_compat; + __u8 uuid[16]; + __u8 volume_name[16]; + } __attribute__((__packed__)) *es; es = (struct ext2_super_block *) get_buffer(id, EXT_SUPERBLOCK_OFFSET, 0x200); @@ -239,20 +291,20 @@ static int probe_ext(struct volume_id *id) static int probe_reiser(struct volume_id *id) { struct reiser_super_block { - __u32 blocks_count; - __u32 free_blocks; - __u32 root_block; - __u32 journal_block; - __u32 journal_dev; - __u32 orig_journal_size; - __u32 dummy2[5]; - __u16 blocksize; - __u16 dummy3[3]; - unsigned char magic[12]; - __u32 dummy4[5]; - unsigned char uuid[16]; - char label[16]; - } *rs; + __u32 blocks_count; + __u32 free_blocks; + __u32 root_block; + __u32 journal_block; + __u32 journal_dev; + __u32 orig_journal_size; + __u32 dummy2[5]; + __u16 blocksize; + __u16 dummy3[3]; + __u8 magic[12]; + __u32 dummy4[5]; + __u8 uuid[16]; + __u8 label[16]; + } __attribute__((__packed__)) *rs; rs = (struct reiser_super_block *) get_buffer(id, REISER_SUPERBLOCK_OFFSET, 0x200); @@ -288,19 +340,19 @@ found: static int probe_xfs(struct volume_id *id) { struct xfs_super_block { - unsigned char magic[4]; - __u32 blocksize; - __u64 dblocks; - __u64 rblocks; - __u32 dummy1[2]; - unsigned char uuid[16]; - __u32 dummy2[15]; - char fname[12]; - __u32 dummy3[2]; - __u64 icount; - __u64 ifree; - __u64 fdblocks; - } *xs; + __u8 magic[4]; + __u32 blocksize; + __u64 dblocks; + __u64 rblocks; + __u32 dummy1[2]; + __u8 uuid[16]; + __u32 dummy2[15]; + __u8 fname[12]; + __u32 dummy3[2]; + __u64 icount; + __u64 ifree; + __u64 fdblocks; + } __attribute__((__packed__)) *xs; xs = (struct xfs_super_block *) get_buffer(id, 0, 0x200); if (xs == NULL) @@ -323,17 +375,17 @@ static int probe_xfs(struct volume_id *id) static int probe_jfs(struct volume_id *id) { struct jfs_super_block { - unsigned char magic[4]; - __u32 version; - __u64 size; - __u32 bsize; - __u32 dummy1; - __u32 pbsize; - __u32 dummy2[27]; - unsigned char uuid[16]; - unsigned char label[16]; - unsigned char loguuid[16]; - } *js; + __u8 magic[4]; + __u32 version; + __u64 size; + __u32 bsize; + __u32 dummy1; + __u32 pbsize; + __u32 dummy2[27]; + __u8 uuid[16]; + __u8 label[16]; + __u8 loguuid[16]; + } __attribute__((__packed__)) *js; js = (struct jfs_super_block *) get_buffer(id, JFS_SUPERBLOCK_OFFSET, 0x200); @@ -356,34 +408,34 @@ static int probe_jfs(struct volume_id *id) static int probe_vfat(struct volume_id *id) { struct vfat_super_block { - unsigned char ignored[3]; - unsigned char sysid[8]; - unsigned char sector_size[2]; - __u8 cluster_size; - __u16 reserved; - __u8 fats; - unsigned char dir_entries[2]; - unsigned char sectors[2]; - unsigned char media; - __u16 fat_length; - __u16 secs_track; - __u16 heads; - __u32 hidden; - __u32 total_sect; - __u32 fat32_length; - __u16 flags; - __u8 version[2]; - __u32 root_cluster; - __u16 insfo_sector; - __u16 backup_boot; - __u16 reserved2[6]; - unsigned char unknown[3]; - unsigned char serno[4]; - char label[11]; - unsigned char magic[8]; - unsigned char dummy2[164]; - unsigned char pmagic[2]; - } *vs; + __u8 ignored[3]; + __u8 sysid[8]; + __u8 sector_size[2]; + __u8 cluster_size; + __u16 reserved; + __u8 fats; + __u8 dir_entries[2]; + __u8 sectors[2]; + __u8 media; + __u16 fat_length; + __u16 secs_track; + __u16 heads; + __u32 hidden; + __u32 total_sect; + __u32 fat32_length; + __u16 flags; + __u8 version[2]; + __u32 root_cluster; + __u16 insfo_sector; + __u16 backup_boot; + __u16 reserved2[6]; + __u8 unknown[3]; + __u8 serno[4]; + __u8 label[11]; + __u8 magic[8]; + __u8 dummy2[164]; + __u8 pmagic[2]; + } __attribute__((__packed__)) *vs; vs = (struct vfat_super_block *) get_buffer(id, 0, 0x200); if (vs == NULL) @@ -409,27 +461,27 @@ found: static int probe_msdos(struct volume_id *id) { struct msdos_super_block { - unsigned char ignored[3]; - unsigned char sysid[8]; - unsigned char sector_size[2]; - __u8 cluster_size; - __u16 reserved; - __u8 fats; - unsigned char dir_entries[2]; - unsigned char sectors[2]; - unsigned char media; - __u16 fat_length; - __u16 secs_track; - __u16 heads; - __u32 hidden; - __u32 total_sect; - unsigned char unknown[3]; - unsigned char serno[4]; - char label[11]; - unsigned char magic[8]; - unsigned char dummy2[192]; - unsigned char pmagic[2]; - } *ms; + __u8 ignored[3]; + __u8 sysid[8]; + __u8 sector_size[2]; + __u8 cluster_size; + __u16 reserved; + __u8 fats; + __u8 dir_entries[2]; + __u8 sectors[2]; + __u8 media; + __u16 fat_length; + __u16 secs_track; + __u16 heads; + __u32 hidden; + __u32 total_sect; + __u8 unknown[3]; + __u8 serno[4]; + __u8 label[11]; + __u8 magic[8]; + __u8 dummy2[192]; + __u8 pmagic[2]; + } __attribute__((__packed__)) *ms; ms = (struct msdos_super_block *) get_buffer(id, 0, 0x200); if (ms == NULL) @@ -459,45 +511,43 @@ static int probe_udf(struct volume_id *id) { struct volume_descriptor { struct descriptor_tag { - __u16 id; - __u16 version; - unsigned char checksum; - unsigned char reserved; - __u16 serial; - __u16 crc; - __u16 crc_len; - __u32 location; - } tag; + __u16 id; + __u16 version; + __u8 checksum; + __u8 reserved; + __u16 serial; + __u16 crc; + __u16 crc_len; + __u32 location; + } __attribute__((__packed__)) tag; union { struct anchor_descriptor { - __u32 length; - __u32 location; - } anchor; + __u32 length; + __u32 location; + } __attribute__((__packed__)) anchor; struct primary_descriptor { - __u32 seq_num; - __u32 desc_num; + __u32 seq_num; + __u32 desc_num; struct dstring { - char clen; - char c[31]; - } ident; - } primary; - } type; - } *vd; + __u8 clen; + __u8 c[31]; + } __attribute__((__packed__)) ident; + } __attribute__((__packed__)) primary; + } __attribute__((__packed__)) type; + } __attribute__((__packed__)) *vd; struct volume_structure_descriptor { - unsigned char type; - char id[5]; - unsigned char version; + __u8 type; + __u8 id[5]; + __u8 version; } *vsd; - size_t bs; - size_t b; - int type; - int count; - int loc; - int clen; - int i,j; - int c; + unsigned int bs; + unsigned int b; + unsigned int type; + unsigned int count; + unsigned int loc; + unsigned int clen; vsd = (struct volume_structure_descriptor *) get_buffer(id, UDF_VSD_OFFSET, 0x200); @@ -594,29 +644,10 @@ pvd: clen = vd->type.primary.ident.clen; dbg("label string charsize=%i bit", clen); - if (clen == 8) { + if (clen == 8) set_label_string(id, vd->type.primary.ident.c, 31); - } else if (clen == 16) { - /* convert unicode OSTA dstring to UTF-8 */ - j = 0; - for (i = 0; i < 32; i += 2) { - c = (vd->type.primary.ident.c[i] << 8) | - vd->type.primary.ident.c[i+1]; - if (c == 0) { - id->label_string[j] = '\0'; - break; - }else if (c < 0x80U) { - id->label_string[j++] = (char) c; - } else if (c < 0x800U) { - id->label_string[j++] = (char) (0xc0 | (c >> 6)); - id->label_string[j++] = (char) (0x80 | (c & 0x3f)); - } else { - id->label_string[j++] = (char) (0xe0 | (c >> 12)); - id->label_string[j++] = (char) (0x80 | ((c >> 6) & 0x3f)); - id->label_string[j++] = (char) (0x80 | (c & 0x3f)); - } - } - } + else if (clen == 16) + set_label_unicode16(id, vd->type.primary.ident.c, BE,31); found: id->fs_type = UDF; @@ -630,20 +661,20 @@ static int probe_iso9660(struct volume_id *id) { union iso_super_block { struct iso_header { - unsigned char type; - char id[5]; - unsigned char version; - unsigned char unused1; - char system_id[32]; - char volume_id[32]; - } iso; + __u8 type; + __u8 id[5]; + __u8 version; + __u8 unused1; + __u8 system_id[32]; + __u8 volume_id[32]; + } __attribute__((__packed__)) iso; struct hs_header { - char foo[8]; - unsigned char type; - char id[4]; - unsigned char version; - } hs; - } *is; + __u8 foo[8]; + __u8 type; + __u8 id[4]; + __u8 version; + } __attribute__((__packed__)) hs; + } __attribute__((__packed__)) *is; is = (union iso_super_block *) get_buffer(id, ISO_SUPERBLOCK_OFFSET, 0x200); @@ -666,12 +697,73 @@ found: return 0; } +#define MFT_RECORD_VOLUME 3 +#define MFT_RECORD_ATTR_VOLUME_NAME 0x60u +#define MFT_RECORD_ATTR_OBJECT_ID 0x40u +#define MFT_RECORD_ATTR_END 0xffffffffu static int probe_ntfs(struct volume_id *id) { struct ntfs_super_block { - char jump[3]; - char oem_id[4]; - } *ns; + __u8 jump[3]; + __u8 oem_id[8]; + struct bios_param_block { + __u16 bytes_per_sector; + __u8 sectors_per_cluster; + __u16 reserved_sectors; + __u8 fats; + __u16 root_entries; + __u16 sectors; + __u8 media_type; /* 0xf8 = hard disk */ + __u16 sectors_per_fat; + __u16 sectors_per_track; + __u16 heads; + __u32 hidden_sectors; + __u32 large_sectors; + } __attribute__((__packed__)) bpb; + __u8 unused[4]; + __u64 number_of_sectors; + __u64 mft_cluster_location; + __u64 mft_mirror_cluster_location; + __s8 cluster_per_mft_record; + } __attribute__((__packed__)) *ns; + + struct master_file_table_record { + __u8 magic[4]; + __u16 usa_ofs; + __u16 usa_count; + __u64 lsn; + __u16 sequence_number; + __u16 link_count; + __u16 attrs_offset; + __u16 flags; + __u32 bytes_in_use; + __u32 bytes_allocated; + } __attribute__((__packed__)) *mftr; + + struct file_attribute { + __u32 type; + __u32 len; + __u8 non_resident; + __u8 name_len; + __u16 name_offset; + __u16 flags; + __u16 instance; + __u32 value_len; + __u16 value_offset; + } __attribute__((__packed__)) *attr; + + unsigned int sector_size; + unsigned int cluster_size; + unsigned long mft_cluster; + unsigned long 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 __u8 *buf; + const __u8 *val; ns = (struct ntfs_super_block *) get_buffer(id, 0, 0x200); if (ns == NULL) @@ -680,6 +772,78 @@ static int probe_ntfs(struct volume_id *id) if (strncmp(ns->oem_id, "NTFS", 4) != 0) return -1; + sector_size = le16_to_cpu(ns->bpb.bytes_per_sector); + cluster_size = ns->bpb.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 %li", mft_cluster); + dbg("mftoffset 0x%lx", mft_off); + dbg("cluster per mft_record %i", ns->cluster_per_mft_record); + dbg("mft record size %i", mft_record_size); + + buf = get_buffer(id, 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[0] = '%c' %03d, 0x%02x", mftr->magic[0], mftr->magic[0], mftr->magic[0]); + dbg("mftr->magic[1] = '%c' %03d, 0x%02x", mftr->magic[1], mftr->magic[1], mftr->magic[1]); + dbg("mftr->magic[2] = '%c' %03d, 0x%02x", mftr->magic[2], mftr->magic[2], mftr->magic[2]); + dbg("mftr->magic[3] = '%c' %03d, 0x%02x", mftr->magic[3], mftr->magic[3], mftr->magic[3]); + if (strncmp(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); + + 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_NAME) { + dbg("found label, len %i", val_len); + if (val_len > VOLUME_ID_LABEL_SIZE) + val_len = VOLUME_ID_LABEL_SIZE; + + val = &((__u8 *) attr)[val_off]; + set_label_raw(id, val, val_len); + set_label_unicode16(id, val, LE, val_len); + } + + if (attr_type == MFT_RECORD_ATTR_OBJECT_ID) { + dbg("found uuid"); + val = &((__u8 *) attr)[val_off]; + set_uuid(id, val, 16); + } + + if (attr_len == 0) + break; + attr_off += attr_len; + if (attr_off >= mft_record_size) + break; + } + +found: id->fs_type = NTFS; id->fs_name = "ntfs"; @@ -689,8 +853,8 @@ static int probe_ntfs(struct volume_id *id) #define LARGEST_PAGESIZE 0x4000 static int probe_swap(struct volume_id *id) { - char *sig; - size_t page; + const __u8 *sig; + unsigned int page; /* huhh, the swap signature is on the end of the PAGE_SIZE */ for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { @@ -836,7 +1000,7 @@ struct volume_id *volume_id_open_node(const char *path) struct volume_id *volume_id_open_dev_t(dev_t devt) { struct volume_id *id; - char tmp_node[VOLUME_ID_PATH_MAX]; + __u8 tmp_node[VOLUME_ID_PATH_MAX]; snprintf(tmp_node, VOLUME_ID_PATH_MAX, "/tmp/volume-%u-%u-%u", getpid(), major(devt), minor(devt)); diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index 2f20244c7c..a939743dc1 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -21,9 +21,9 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 002 +#define VOLUME_ID_VERSION 004 -#define VOLUME_ID_LABEL_SIZE 32 +#define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 #define VOLUME_ID_UUID_STRING_SIZE 37 #define VOLUME_ID_PATH_MAX 255 @@ -45,19 +45,19 @@ enum filesystem_type { }; struct volume_id { - char label_raw[VOLUME_ID_LABEL_SIZE]; - size_t label_raw_len; + unsigned char label_raw[VOLUME_ID_LABEL_SIZE]; + unsigned int label_raw_len; char label_string[VOLUME_ID_LABEL_SIZE+1]; unsigned char uuid[VOLUME_ID_UUID_SIZE]; char uuid_string[VOLUME_ID_UUID_STRING_SIZE]; enum filesystem_type fs_type; char *fs_name; int fd; - char *sbbuf; - size_t sbbuf_len; - char *seekbuf; - size_t seekbuf_off; - size_t seekbuf_len; + unsigned char *sbbuf; + unsigned int sbbuf_len; + unsigned char *seekbuf; + unsigned int seekbuf_off; + unsigned int seekbuf_len; int fd_close; }; From 9a52390cfe0882df3a24b75cc9d8b36878a3982d Mon Sep 17 00:00:00 2001 From: "ogasawara@osdl.org" Date: Sat, 26 Jun 2004 01:18:31 -0700 Subject: [PATCH 0799/4284] [PATCH] udevstart performance increase I noticed a comment in namedev.c which stated "Figure out where the device symlink is at. For char devices this will always be in the class_dev->path. But for block devices, it's different. The main block device will have the device symlink in it's path, but all partitions have the symlink in its parent directory. But we need to watch out for block devices that do not have parents, yet look like a partition (fd0, loop0, etc.). They all do not have a device symlink yet. We do a sit and spin on waiting for them right now, we should possibly have a whitelist for these devices here..." I went ahead and created a whitelist for the block devices that look like partitions (mainly by using devices.txt) and tested for any performance increase that we would see. The whitelist only impacts udevstart time depending on the state of UDEV_NO_SLEEP. Since the list was short, I just did a sequential search and ordered the list in such a way that those block devices which have more /dev entires (ex. loop0, loop1, loop2, etc) appear sooner in the list and will thus be found quicker. I've enclosed the patch and some of the performance results I saw below. Basically, as the number of block devices without device symlinks increased, the use of the whitelist improved udevstart performance compared to just sitting and spinning. I just thought it was interesting and thought I'd share. If you feel the patch is beneficial please consider for merging. Also, if you'd be interested in expanding the whitelist for other devices which are missing device symlinks and seeing if there are added performance increases let me know and I'll do what I can. Thanks, Leann Note: ex. loop represents all the loop devices (i.e. loop0, loop1, loop2, etc) block devices present with whitelist time --- namedev.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/namedev.c b/namedev.c index 5e3db1326c..7f3a6a7783 100644 --- a/namedev.c +++ b/namedev.c @@ -602,6 +602,43 @@ static int match_place(struct config_device *dev, struct sysfs_class_device *cla return 0; } +static int whitelist_search(struct sysfs_class_device *class_dev) +{ + int i; + int list_size = 17; + int sysblock = 10; + + static char *list[] = { + "nb", + "ram", + "loop", + "fd", + "md", + "dos_cd", + "double", + "flash", + "msd", + "rflash", + "rom", + "rrom", + "sbpcd", + "pcd", + "pf", + "scd", + "ubd", + }; + + if (!strncmp(class_dev->path, "/sys/block", sysblock)) { + for (i=0; i < list_size; i++) { + if (!strncmp(class_dev->name, list[i], strlen(list[i]))) { + return 1; + } + } + } + + return 0; +} + static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev) { struct sysfs_device *sysfs_device; @@ -615,8 +652,8 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de * all partitions have the symlink in its parent directory. * But we need to watch out for block devices that do not have parents, yet * look like a partition (fd0, loop0, etc.) They all do not have a device - * symlink yet. We do sit and spin on waiting for them right now, we should - * possibly have a whitelist for these devices here... + * symlink yet. We do sit and spin on waiting for them right now unless + * they happen to be in the whitelist in which case we exit. */ class_dev_parent = sysfs_get_classdev_parent(class_dev); if (class_dev_parent != NULL) @@ -626,8 +663,13 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de tspec.tv_nsec = 10000000; /* sleep 10 millisec */ loop = 10; while (loop--) { - if (udev_sleep) + if (udev_sleep) { + if (whitelist_search(class_dev)) { + sysfs_device = NULL; + goto exit; + } nanosleep(&tspec, NULL); + } if (class_dev_parent) sysfs_device = sysfs_get_classdev_device(class_dev_parent); From fcf3ce3417ea0805572873451d2a4f49deefdc10 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 26 Jun 2004 01:27:12 -0700 Subject: [PATCH 0800/4284] [PATCH] clean up block whitelist search logic a bit. --- namedev.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/namedev.c b/namedev.c index 7f3a6a7783..52417e3793 100644 --- a/namedev.c +++ b/namedev.c @@ -604,9 +604,8 @@ static int match_place(struct config_device *dev, struct sysfs_class_device *cla static int whitelist_search(struct sysfs_class_device *class_dev) { + char *sysblock = "/sys/block"; int i; - int list_size = 17; - int sysblock = 10; static char *list[] = { "nb", @@ -626,15 +625,15 @@ static int whitelist_search(struct sysfs_class_device *class_dev) "pf", "scd", "ubd", + NULL, }; - if (!strncmp(class_dev->path, "/sys/block", sysblock)) { - for (i=0; i < list_size; i++) { - if (!strncmp(class_dev->name, list[i], strlen(list[i]))) { - return 1; - } - } - } + if (strncmp(class_dev->path, sysblock, strlen(sysblock))) + return 0; + + for (i=0; list[i] != NULL; i++) + if (!strncmp(class_dev->name, list[i], strlen(list[i]))) + return 1; return 0; } From 099602aaad8ebcc4969ee35e4167fd093325db50 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 26 Jun 2004 01:32:43 -0700 Subject: [PATCH 0801/4284] [PATCH] 028 release --- ChangeLog | 23 +++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc754dc9d5..8fe59ce796 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 1e683cb35c..ba876966f8 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 027 +VERSION = 028 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 07fafbbc79..95fe6b719f 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 027 +Version: 028 Release: 1 License: GPL Group: Utilities/System From 58ecc5d77ffaa6e1f941ae7dd9ef3f6a249950eb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Jul 2004 22:01:50 -0700 Subject: [PATCH 0802/4284] [PATCH] fix permission problem with input event and ts nodes for gentoo --- etc/udev/udev.permissions.gentoo | 2 ++ 1 file changed, 2 insertions(+) diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index 7bde9833d7..d8d5c53a0c 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -170,6 +170,8 @@ vttuner:root:video:0660 v4l/*:root:video:0660 # input devices +input/event*:root:root:600 +input/ts*:root:root:600 input/*:root:root:644 # gpm devices From 0e306d087daa0f6c5517c41743b948457013252c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Jul 2004 22:19:18 -0700 Subject: [PATCH 0803/4284] [PATCH] make a "last list" of devices for udevstart to operate on last. Should fix the dm startup issues, hopefully... --- udevstart.c | 197 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 136 insertions(+), 61 deletions(-) diff --git a/udevstart.c b/udevstart.c index 2d11edeca2..6f90de7d18 100644 --- a/udevstart.c +++ b/udevstart.c @@ -23,6 +23,7 @@ */ #include +#include #include #include #include @@ -34,6 +35,7 @@ #include "logging.h" #include "udev_lib.h" +#include "list.h" #ifdef LOG @@ -54,6 +56,36 @@ void log_message(int level, const char *format, ...) #define SYSCLASS "/sys/class" #define UDEV_BIN "/sbin/udev" +struct device { + struct list_head list; + char path[MAX_PATHLEN]; + char subsys[MAX_PATHLEN]; +}; + +/* sort files in lexical order */ +static int device_list_insert(char *path, char *subsystem, struct list_head *device_list) +{ + struct device *loop_device; + struct device *new_device; + + list_for_each_entry(loop_device, device_list, list) { + if (strcmp(loop_device->path, path) > 0) { + break; + } + } + + new_device = malloc(sizeof(struct device)); + if (new_device == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + strfieldcpy(new_device->path, path); + strfieldcpy(new_device->subsys, subsystem); + list_add_tail(&new_device->list, &loop_device->list); + return 0; +} + static void udev_exec(const char *path, const char* subsystem) { pid_t pid; @@ -62,6 +94,7 @@ static void udev_exec(const char *path, const char* subsystem) char nosleep[] = "UDEV_NO_SLEEP=1"; char *env[] = { action, devpath, nosleep, NULL }; + return; strcpy(devpath, "DEVPATH="); strfieldcat(devpath, path); @@ -81,18 +114,109 @@ static void udev_exec(const char *path, const char* subsystem) } } -static void udev_scan(void) +/* 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, +}; + +static void exec_list(struct list_head *device_list) +{ + struct device *loop_device; + struct device *tmp_device; + + /* handle the devices we are allowed to, excluding the "last" type devices */ + list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { + int found = 0; + int i; + 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; + + udev_exec(loop_device->path, loop_device->subsys); + list_del(&loop_device->list); + free(loop_device); + } + + /* handle the rest of the devices left over, if any */ + list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { + udev_exec(loop_device->path, loop_device->subsys); + list_del(&loop_device->list); + free(loop_device); + } +} + +static void udev_scan_block(void) { - char *devpath; DIR *dir; struct dirent *dent; + LIST_HEAD(device_list); + + dir = opendir(SYSBLOCK); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char dirname[MAX_PATHLEN]; + DIR *dir2; + struct dirent *dent2; + + if ((strcmp(dent->d_name, ".") == 0) || + (strcmp(dent->d_name, "..") == 0)) + continue; + + snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name); + dirname[MAX_PATHLEN-1] = '\0'; + device_list_insert(dirname, "block", &device_list); + + snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name); + dir2 = opendir(dirname); + if (dir2 != NULL) { + for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { + char dirname2[MAX_PATHLEN]; + DIR *dir3; + struct dirent *dent3; + + if ((strcmp(dent2->d_name, ".") == 0) || + (strcmp(dent2->d_name, "..") == 0)) + continue; + + snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); + dirname2[MAX_PATHLEN-1] = '\0'; + + dir3 = opendir(dirname2); + if (dir3 != NULL) { + for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { + char filename[MAX_PATHLEN]; + + if (strcmp(dent3->d_name, "dev") == 0) { + snprintf(filename, MAX_PATHLEN, "/block/%s/%s", + dent->d_name, dent2->d_name); + filename[MAX_PATHLEN-1] = '\0'; + device_list_insert(filename, "block", &device_list); + } + } + closedir(dir3); + } + } + closedir(dir2); + } + } + closedir(dir); + } + + exec_list(&device_list); +} + +static void udev_scan_class(void) +{ + DIR *dir; + struct dirent *dent; + LIST_HEAD(device_list); - /* - * We want to scan the class tree first as lvm and dm needs to be able - * to have access to the char control device when probing the block - * devices. - */ - devpath = "class"; dir = opendir(SYSCLASS); if (dir != NULL) { for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { @@ -129,7 +253,7 @@ static void udev_scan(void) snprintf(filename, MAX_PATHLEN, "/class/%s/%s", dent->d_name, dent2->d_name); filename[MAX_PATHLEN-1] = '\0'; - udev_exec(filename, dent->d_name); + device_list_insert(filename, dent->d_name, &device_list); } } closedir(dir3); @@ -141,64 +265,15 @@ static void udev_scan(void) closedir(dir); } - devpath = "block"; - dir = opendir(SYSBLOCK); - if (dir != NULL) { - for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[MAX_PATHLEN]; - DIR *dir2; - struct dirent *dent2; - - if ((strcmp(dent->d_name, ".") == 0) || - (strcmp(dent->d_name, "..") == 0)) - continue; - - snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name); - dirname[MAX_PATHLEN-1] = '\0'; - udev_exec(dirname, "block"); - - snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name); - dir2 = opendir(dirname); - if (dir2 != NULL) { - for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN]; - DIR *dir3; - struct dirent *dent3; - - if ((strcmp(dent2->d_name, ".") == 0) || - (strcmp(dent2->d_name, "..") == 0)) - continue; - - snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); - dirname2[MAX_PATHLEN-1] = '\0'; - - dir3 = opendir(dirname2); - if (dir3 != NULL) { - for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { - char filename[MAX_PATHLEN]; - - if (strcmp(dent3->d_name, "dev") == 0) { - snprintf(filename, MAX_PATHLEN, "/block/%s/%s", - dent->d_name, dent2->d_name); - filename[MAX_PATHLEN-1] = '\0'; - udev_exec(filename, "block"); - } - } - closedir(dir3); - } - } - closedir(dir2); - } - } - closedir(dir); - } + exec_list(&device_list); } int main(int argc, char *argv[], char *envp[]) { init_logging("udevstart"); - udev_scan(); + udev_scan_class(); + udev_scan_block(); return 0; } From fd87429578a01e8cc0c9ca4b54f458280808adfb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 1 Jul 2004 22:49:13 -0700 Subject: [PATCH 0804/4284] [PATCH] fix dumb bug I added to udevstart --- udevstart.c | 1 - 1 file changed, 1 deletion(-) diff --git a/udevstart.c b/udevstart.c index 6f90de7d18..19f588ab33 100644 --- a/udevstart.c +++ b/udevstart.c @@ -94,7 +94,6 @@ static void udev_exec(const char *path, const char* subsystem) char nosleep[] = "UDEV_NO_SLEEP=1"; char *env[] = { action, devpath, nosleep, NULL }; - return; strcpy(devpath, "DEVPATH="); strfieldcat(devpath, path); From ea08d6fc3eff4ca20a195451d7f3e154e50acb1f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 2 Jul 2004 18:30:37 -0700 Subject: [PATCH 0805/4284] [PATCH] add permission rule for jogdial device. --- etc/udev/udev.permissions.gentoo | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index d8d5c53a0c..8d2acc01fe 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -174,6 +174,9 @@ input/event*:root:root:600 input/ts*:root:root:600 input/*:root:root:644 +# Sony Vaio Jogdial sonypi device +sonypi:root:root:0666 + # gpm devices gpmctl:root:root:0700 From cf9ffc8d9c02553b9698a795f26208fc121c8f1a Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Fri, 2 Jul 2004 18:59:30 -0700 Subject: [PATCH 0806/4284] [PATCH] allow NAME_SIZE > SYSFS_PATH_MAX NAME_SIZE is too small for some configurations. This patch allows more or longer names, it just keeps the stack in a sane state. --- udevdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevdb.c b/udevdb.c index f246936710..c4dc4f005c 100644 --- a/udevdb.c +++ b/udevdb.c @@ -52,7 +52,7 @@ int udevdb_add_dev(const char *path, const struct udevice *dev) if ((path == NULL) || (dev == NULL)) return -ENODEV; - memset(keystr, 0, NAME_SIZE); + memset(keystr, 0, SYSFS_PATH_MAX); strfieldcpy(keystr, path); key.dptr = keystr; key.dsize = strlen(keystr) + 1; From bf21ea08b3f7b2a93141d98448c78bc3dbe87f84 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 2 Jul 2004 19:15:10 -0700 Subject: [PATCH 0807/4284] [PATCH] 029 release --- ChangeLog | 14 ++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8fe59ce796..84a5bd35bf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +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 ============================================ diff --git a/Makefile b/Makefile index ba876966f8..0dfec46b71 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 028 +VERSION = 029 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 95fe6b719f..e537a917db 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 028 +Version: 029 Release: 1 License: GPL Group: Utilities/System From 462be028f18d94ab06c913768da78e30a1a66b68 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 9 Jul 2004 18:46:08 -0700 Subject: [PATCH 0808/4284] [PATCH] fix stupid off-by-one bug that caused udevstart to die on x86-64 boxes. --- udevstart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevstart.c b/udevstart.c index 19f588ab33..3ecfd4cb61 100644 --- a/udevstart.c +++ b/udevstart.c @@ -228,7 +228,7 @@ static void udev_scan_class(void) continue; snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); - dirname[MAX_PATHLEN] = '\0'; + dirname[MAX_PATHLEN-1] = '\0'; dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { From 16ddbbe10a6484daf63596818a19890225388a71 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 9 Jul 2004 18:59:03 -0700 Subject: [PATCH 0809/4284] [PATCH] 030 release --- ChangeLog | 7 +++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84a5bd35bf..6a65376488 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 0dfec46b71..162a78d39d 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 029 +VERSION = 030 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index e537a917db..bdbcb4129e 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 029 +Version: 030 Release: 1 License: GPL Group: Utilities/System From e2eef6d4dc31158b812b0ee2690fec3f41b92703 Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Tue, 10 Aug 2004 00:46:38 -0700 Subject: [PATCH 0810/4284] [PATCH] Try to provide a bit of security for hardlinks to /dev entries. --- udev-remove.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/udev-remove.c b/udev-remove.c index 27ff5bc0a2..4f2cd479c0 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -65,6 +65,41 @@ static int delete_path(char *path) return 0; } +/** Remove all permissions on the device node, before + * unlinking it. This fixes a security issue. + * If the user created a hard-link to the device node, + * he can't use it any longer, because he lost permission + * to do so. + */ +static int secure_unlink(const char *filename) +{ + int retval; + + retval = chown(filename, 0, 0); + if (retval) { + dbg("chown(%s, 0, 0) failed with error '%s'", + filename, strerror(errno)); + /* We continue nevertheless. + * I think it's very unlikely for chown + * to fail here, if the file exists. + */ + } + retval = chmod(filename, 0000); + if (retval) { + dbg("chmod(%s, 0000) failed with error '%s'", + filename, strerror(errno)); + /* We continue nevertheless. */ + } + retval = unlink(filename); + if (errno == ENOENT) + retval = 0; + if (retval) { + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + } + return retval; +} + static int delete_node(struct udevice *dev) { char filename[NAME_SIZE]; @@ -79,14 +114,9 @@ static int delete_node(struct udevice *dev) strfieldcat(filename, dev->name); info("removing device node '%s'", filename); - retval = unlink(filename); - if (errno == ENOENT) - retval = 0; - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); + retval = secure_unlink(filename); + if (retval) return retval; - } /* remove partition nodes */ if (dev->partitions > 0) { @@ -94,7 +124,7 @@ static int delete_node(struct udevice *dev) for (i = 1; i <= dev->partitions; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); - unlink(partitionname); + secure_unlink(partitionname); } } From 4723bf98c0835bc779f627d7125417aa4f84121d Mon Sep 17 00:00:00 2001 From: "Ballarin.Marc@gmx.de" Date: Tue, 10 Aug 2004 00:49:36 -0700 Subject: [PATCH 0811/4284] [PATCH] Update the FAQ with info about hardlink security --- FAQ | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/FAQ b/FAQ index 28f7552ae3..45337bf635 100644 --- a/FAQ +++ b/FAQ @@ -23,7 +23,7 @@ A: To quote Al Viro (Linux VFS kernel maintainer): - 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 stoped maintaining + - 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 @@ -98,6 +98,19 @@ A: Technically, yes, but udev is not intended for this. Projects that do And don't have to be root but will get full permissions on /pendrive. This works even without udev if /udev/pendrive is replaced by /dev/sda1 +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 in a separate filesystem (tmpfs, ramfs, ...). + 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 From 807755776d294a9811c0c8e835538e83abf734bc Mon Sep 17 00:00:00 2001 From: "trini@kernel.crashing.org" Date: Tue, 10 Aug 2004 00:49:42 -0700 Subject: [PATCH 0812/4284] [PATCH] Add 'asmlinkage' to udev-030 The following patch adds 'asmlinkage' defines to udev, to kill off 2 warnings on !i386. Signed-off-by: Tom Rini Signed-off-by: Greg Kroah-Hartman --- Makefile | 4 ++-- udev.c | 2 +- udevd.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 162a78d39d..f4f371d463 100644 --- a/Makefile +++ b/Makefile @@ -114,9 +114,9 @@ ifeq ($(strip $(TARGET_ARCH)),i386) /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi} OPTIMIZATION += ${shell if $(CC) -malign-functions=0 -malign-jumps=0 -S -o /dev/null -xc \ /dev/null >/dev/null 2>&1; then echo "-malign-functions=0 -malign-jumps=0"; fi} - CFLAGS+=-pipe + CFLAGS+=-pipe -Dasmlinkage=__attribute__((regparm(0))) else - CFLAGS+=-pipe + CFLAGS+=-pipe -Dasmlinkage= endif ifeq ($(strip $(USE_LOG)),true) diff --git a/udev.c b/udev.c index eb21f75461..cc6ce10542 100644 --- a/udev.c +++ b/udev.c @@ -55,7 +55,7 @@ void log_message(int level, const char *format, ...) } #endif -__attribute__((regparm(0))) static void sig_handler(int signum) +asmlinkage static void sig_handler(int signum) { switch (signum) { case SIGINT: diff --git a/udevd.c b/udevd.c index e0c5bf5c77..79de11248e 100644 --- a/udevd.c +++ b/udevd.c @@ -306,7 +306,7 @@ skip: return; } -__attribute__((regparm(0))) static void sig_handler(int signum) +asmlinkage static void sig_handler(int signum) { int rc; From eb6c7cd03635ffc28798734f0b87b9e21dae6f9e Mon Sep 17 00:00:00 2001 From: "trini@kernel.crashing.org" Date: Tue, 10 Aug 2004 00:50:21 -0700 Subject: [PATCH 0813/4284] [PATCH] Make udev/udevstart be one binary Hi, The following patch makes udev/udevstart be a common binary. First, doing this grows udev by a total of 1.8kB (ppc32, stripped) whereas udevstart by itself is 6.4kB. I know you mentioned being able to replace udevstart with a script, but at 1.8kB I don't think it'll be easy to beat this with size there. Next, the following are by-eye timings of before, after, and with devfs on a slow, but still usable embedded platform (config stripped down to more-or-less bare for ramdisk): -- Embedded Planet RPX LITE, 64Mhz MPC 823e -- devfs : 15.333s, 15.253s, 14.988s (15.191s avg) udev-pristine : 18.675s, 18.079s, 18.418s (18.390s avg) udev-multi : 14.587s, 14.747s, 14.868s (14.734s avg) The patch ends up being rather large to add this, as in doing so I ended up making all refs (that I hit..) to devpath/subsystem be marked as 'const'. Signed-off-by: Tom Rini Signed-off-by: Greg Kroah-Hartman --- Makefile | 14 ++++------- dev_d.c | 2 +- udev-add.c | 6 ++--- udev-remove.c | 2 +- udev.c | 66 ++++++++++++++++++++++++++++++++------------------- udev.h | 10 +++++--- udevstart.c | 45 ++++++----------------------------- 7 files changed, 66 insertions(+), 79 deletions(-) diff --git a/Makefile b/Makefile index f4f371d463..d4d3ac8b05 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -261,8 +261,8 @@ $(DAEMON).o: $(GEN_HEADERS) $(SENDER).o: $(GEN_HEADERS) $(STARTER).o: $(GEN_HEADERS) -$(ROOT): $(ROOT).o $(OBJS) $(HEADERS) $(LIBC) $(GEN_MANPAGES) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(ROOT): $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(LIBC) $(GEN_MANPAGES) + $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ $(TESTER): $(TESTER).o $(OBJS) $(HEADERS) $(LIBC) @@ -281,10 +281,6 @@ $(SENDER): $(SENDER).o udevd.h $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(STARTER): $(STARTER).o $(HEADERS) $(LIBC) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevstart.o $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $@ - $(RULER): $(RULER).o $(OBJS) $(HEADERS) $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevruler.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) -lnewt $(STRIPCMD) $@ @@ -292,7 +288,7 @@ $(RULER): $(RULER).o $(OBJS) $(HEADERS) $(LIBC) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(STARTER) $(RULER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(RULER) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ @@ -392,7 +388,7 @@ install: install-initscript install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) - $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) + ln -sf $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER) - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug ifndef DESTDIR - killall udevd diff --git a/dev_d.c b/dev_d.c index 97c552647b..1ad599ead5 100644 --- a/dev_d.c +++ b/dev_d.c @@ -61,7 +61,7 @@ static int run_program(char *name) * subsystem/ * default/ */ -void dev_d_send(struct udevice *dev, char *subsystem, char *devpath) +void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath) { char dirname[256]; char env_devname[NAME_SIZE]; diff --git a/udev-add.c b/udev-add.c index 900e4795aa..1f69329788 100644 --- a/udev-add.c +++ b/udev-add.c @@ -316,7 +316,7 @@ error: return -1; } -static struct sysfs_class_device *get_class_dev(char *device_name) +static struct sysfs_class_device *get_class_dev(const char *device_name) { char dev_path[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev = NULL; @@ -341,7 +341,7 @@ exit: * If it doesn't happen in about 10 seconds, give up. */ #define SECONDS_TO_WAIT_FOR_FILE 10 -static int sleep_for_file(char *path, char* file) +static int sleep_for_file(const char *path, char* file) { char filename[SYSFS_PATH_MAX + 6]; int loop = SECONDS_TO_WAIT_FOR_FILE; @@ -395,7 +395,7 @@ static int rename_net_if(struct udevice *dev, int fake) return retval; } -int udev_add_device(char *path, char *subsystem, int fake) +int udev_add_device(const char *path, const char *subsystem, int fake) { struct sysfs_class_device *class_dev; struct udevice dev; diff --git a/udev-remove.c b/udev-remove.c index 4f2cd479c0..7ad7c2402a 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -159,7 +159,7 @@ static int delete_node(struct udevice *dev) * something different from the kernel name. If we have, us it. If not, use * the default kernel name for lack of anything else to know to do. */ -int udev_remove_device(char *path, char *subsystem) +int udev_remove_device(const char *path, const char *subsystem) { struct udevice dev; char *temp; diff --git a/udev.c b/udev.c index cc6ce10542..0ef4cf8657 100644 --- a/udev.c +++ b/udev.c @@ -40,6 +40,9 @@ char **main_argv; char **main_envp; +/* local variables */ +static int is_udevstart; + #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) @@ -76,27 +79,13 @@ static char *subsystem_blacklist[] = { "" }; -static int udev_hotplug(void) +int __udev_hotplug(char *action, const char *devpath, const char *subsystem) { - char *action; - char *devpath; - char *subsystem; int retval = -EINVAL; int i; struct sigaction act; const int nofake = 0; - action = get_action(); - if (!action) { - dbg("no action?"); - goto exit; - } - - devpath = get_devpath(); - if (!devpath) { - dbg("no devpath?"); - goto exit; - } dbg("looking at '%s'", devpath); /* we only care about class devices and block stuff */ @@ -106,12 +95,6 @@ static int udev_hotplug(void) goto exit; } - /* skip blacklisted subsystems */ - subsystem = get_subsystem(main_argv[1]); - if (!subsystem) { - dbg("no subsystem?"); - goto exit; - } i = 0; while (subsystem_blacklist[i][0] != '\0') { if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { @@ -136,7 +119,9 @@ static int udev_hotplug(void) sigaction(SIGTERM, &act, NULL); if (strcmp(action, "add") == 0) { - namedev_init(); + /* Already done. */ + if (!is_udevstart) + namedev_init(); retval = udev_add_device(devpath, subsystem, nofake); goto action_done; } @@ -156,17 +141,50 @@ exit: return retval; } +static int udev_hotplug(void) +{ + char *action; + char *devpath; + char *subsystem; + + action = get_action(); + if (!action) { + dbg("no action?"); + return -EINVAL; + } + + devpath = get_devpath(); + if (!devpath) { + dbg("no devpath?"); + return -EINVAL; + } + + /* skip blacklisted subsystems */ + subsystem = get_subsystem(main_argv[1]); + if (!subsystem) { + dbg("no subsystem?"); + return -EINVAL; + } + + return __udev_hotplug(action, devpath, subsystem); +} + int main(int argc, char *argv[], char *envp[]) { main_argv = argv; main_envp = envp; - init_logging("udev"); + if (strstr(argv[0], "udevstart")) + is_udevstart = 1; /* initialize our configuration */ udev_init_config(); dbg("version %s", UDEV_VERSION); - return udev_hotplug(); + if (is_udevstart) { + namedev_init(); + return udev_start(); + } else + return udev_hotplug(); } diff --git a/udev.h b/udev.h index da02e26bba..310154f55d 100644 --- a/udev.h +++ b/udev.h @@ -61,11 +61,15 @@ struct udevice { char kernel_name[NAME_SIZE]; }; -extern int udev_add_device(char *path, char *subsystem, int fake); -extern int udev_remove_device(char *path, char *subsystem); +extern int udev_add_device(const char *path, const char *subsystem, int fake); +extern int udev_remove_device(const char *path, const char *subsystem); extern void udev_init_config(void); +extern int udev_start(void); +extern int __udev_hotplug(char *action, const char *devpath, + const char *subsystem); extern int parse_get_pair(char **orig_string, char **left, char **right); -extern void dev_d_send(struct udevice *dev, char *subsystem, char *devpath); +extern void dev_d_send(struct udevice *dev, const char *subsystem, + const char *devpath); extern char **main_argv; extern char **main_envp; diff --git a/udevstart.c b/udevstart.c index 3ecfd4cb61..d94c9501c9 100644 --- a/udevstart.c +++ b/udevstart.c @@ -36,25 +36,12 @@ #include "logging.h" #include "udev_lib.h" #include "list.h" - - -#ifdef LOG -unsigned char logname[LOGNAME_SIZE]; -void log_message(int level, const char *format, ...) -{ - va_list args; - - va_start(args, format); - vsyslog(level, format, args); - va_end(args); -} -#endif +#include "udev.h" #define MAX_PATHLEN 1024 #define SYSBLOCK "/sys/block" #define SYSCLASS "/sys/class" -#define UDEV_BIN "/sbin/udev" struct device { struct list_head list; @@ -88,28 +75,13 @@ static int device_list_insert(char *path, char *subsystem, struct list_head *dev static void udev_exec(const char *path, const char* subsystem) { - pid_t pid; - char action[] = "ACTION=add"; - char devpath[MAX_PATHLEN]; - char nosleep[] = "UDEV_NO_SLEEP=1"; - char *env[] = { action, devpath, nosleep, NULL }; + /* Setup env variables. */ + setenv("UDEV_NO_SLEEP", "1", 1); - strcpy(devpath, "DEVPATH="); - strfieldcat(devpath, path); - - pid = fork(); - switch (pid) { - case 0: - /* child */ - execle(UDEV_BIN, "udev", subsystem, NULL, env); - dbg("exec of child failed"); + /* Now call __udev_hotplug(). */ + if (__udev_hotplug("add", path, subsystem)) { + dbg("Calling of udev_hotplug failed"); exit(1); - break; - case -1: - dbg("fork of child failed"); - break; - default: - wait(NULL); } } @@ -267,12 +239,9 @@ static void udev_scan_class(void) exec_list(&device_list); } -int main(int argc, char *argv[], char *envp[]) +int udev_start(void) { - init_logging("udevstart"); - udev_scan_class(); udev_scan_block(); - return 0; } From 41ffb32e8de6fd0c2817775472514fe9a687d887 Mon Sep 17 00:00:00 2001 From: "azarah@gentoo.org" Date: Wed, 11 Aug 2004 01:02:54 -0700 Subject: [PATCH 0814/4284] [PATCH] add microcode rule to permissions.gentoo file Add microcode rule, remove duplicate rtc and psaux rules, and order alphabetically. --- etc/udev/udev.rules.gentoo | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 1a84baa9d4..c2a8ef54b1 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -57,12 +57,11 @@ KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" # misc devices -KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" -KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" -KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" -KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" -KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" -KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" +KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" +KERNEL="microcode", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" # pty devices KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" From a4f5eb034bdbb77236f24f24c09286aa03f404ab Mon Sep 17 00:00:00 2001 From: "trini@kernel.crashing.org" Date: Wed, 11 Aug 2004 01:02:56 -0700 Subject: [PATCH 0815/4284] [PATCH] clean up start_udev a bit First, update extras/start_udev. udevstart always internally set UDEV_NO_SLEEP as well as setting the ACTION variable, so that only needs to be done in the run_udev script case. Signed-off-by: Tom Rini Signed-off-by: Greg Kroah-Hartman --- extras/start_udev | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extras/start_udev b/extras/start_udev index 0212d4f8c1..4908d05b70 100644 --- a/extras/start_udev +++ b/extras/start_udev @@ -29,6 +29,9 @@ bin=/sbin/udev udevd=/sbin/udevd run_udev () { + export ACTION=add + export UDEV_NO_SLEEP=1 + # handle block devices and their partitions for i in ${sysfs_dir}/block/*; do # add each drive @@ -85,8 +88,6 @@ echo "mounting... ramfs at $udev_root" mount -n -t ramfs none $udev_root # propogate /udev from /sys -export ACTION=add -export UDEV_NO_SLEEP=1 echo "Creating initial udev device nodes:" # You can use the shell scripts above by calling run_udev or execute udevstart From 2410242aa4d21335026d3b90116078c9146a32f3 Mon Sep 17 00:00:00 2001 From: "trini@kernel.crashing.org" Date: Wed, 11 Aug 2004 01:02:59 -0700 Subject: [PATCH 0816/4284] [PATCH] fix UDEV_NO_SLEEP Move setting UDEV_NO_SLEEP into main(). I thought about moving udev_init_config() around, but it still must be invoked in both udev and udevstart cases, and before udev_hotplug() is called. An alternative would be to have main() do: if (is_udevstart) { ... current ... } else { udev_init_config(); return udev_hotplug(); } And move setting UDEV_NO_SLEEP into udev_start(). I can redo it that way, if you prefer. Signed-off-by: Tom Rini Signed-off-by: Greg Kroah-Hartman --- udev.c | 5 ++++- udevstart.c | 3 --- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/udev.c b/udev.c index 0ef4cf8657..90c34d800a 100644 --- a/udev.c +++ b/udev.c @@ -174,8 +174,11 @@ int main(int argc, char *argv[], char *envp[]) main_argv = argv; main_envp = envp; - if (strstr(argv[0], "udevstart")) + if (strstr(argv[0], "udevstart")) { + /* Setup env variables. */ + setenv("UDEV_NO_SLEEP", "1", 1); is_udevstart = 1; + } /* initialize our configuration */ udev_init_config(); diff --git a/udevstart.c b/udevstart.c index d94c9501c9..2d5553e955 100644 --- a/udevstart.c +++ b/udevstart.c @@ -75,9 +75,6 @@ static int device_list_insert(char *path, char *subsystem, struct list_head *dev static void udev_exec(const char *path, const char* subsystem) { - /* Setup env variables. */ - setenv("UDEV_NO_SLEEP", "1", 1); - /* Now call __udev_hotplug(). */ if (__udev_hotplug("add", path, subsystem)) { dbg("Calling of udev_hotplug failed"); From b9e3301c3b68a1c6464a0bf0ac6e61fc0e4063d1 Mon Sep 17 00:00:00 2001 From: "tao@kernel.org" Date: Wed, 11 Aug 2004 01:03:03 -0700 Subject: [PATCH 0817/4284] [PATCH] Minor POSIX-fixes for udev The attached patch contains a few patches against udev, to remove use of various XSI:isms and bash:isms, and to change two scripts form /bin/bash to /bin/sh. None of the bash-scripts in test/ uses any bash-specific functions as far as I know, but I didn't touch them since they aren't used runtime. Rationale: * Both of the /bin/bash-scripts are totally free from bashisms, hence they don't need to be /bin/bash; using /bin/sh instead helps (mainly) embedded-people * local and source are bash:isms (well, they exist in several other shells as well, but they aren't part of POSIX or any of its extensions) * -a in tests is an XSI-extension, not part of strict POSIX, and is easily replaced by && | http://www.opengroup.org/onlinepubs/009695399/utilities/test.html * Use of fgrep is deprecated in POSIX in favour of grep -F (though fgrep will remain in use for a long time...) | http://www.opengroup.org/onlinepubs/009695399/utilities/grep.html The fgrep-change isn't really necessary, since fgrep can always be implemented as a shell-script, but the rest of the changes would really be appreciated. --- etc/dev.d/default/pam_console.dev | 2 +- etc/dev.d/default/selinux.dev | 2 +- etc/init.d/udev | 2 +- etc/init.d/udev.debian | 2 +- etc/init.d/udev.init.lfs | 6 +++--- extras/ide-devfs.sh | 12 +++++------- extras/scsi-devfs.sh | 4 ++-- extras/start_udev | 2 +- 8 files changed, 15 insertions(+), 17 deletions(-) diff --git a/etc/dev.d/default/pam_console.dev b/etc/dev.d/default/pam_console.dev index 7e95810e2c..563051d7f6 100644 --- a/etc/dev.d/default/pam_console.dev +++ b/etc/dev.d/default/pam_console.dev @@ -11,7 +11,7 @@ fi [ "$UDEV_CONSOLE" != "yes" ] && exit 0 if [ -x /sbin/pam_console_setowner ]; then - if [ "$UDEV_LOG" = "yes" -a -x /usr/bin/logger ]; then + if [ "$UDEV_LOG" = "yes" ] && [ -x /usr/bin/logger ]; then /usr/bin/logger -p auth.debug "Restoring console permissions for $DEVNAME" fi exec /sbin/pam_console_setowner $DEVNAME diff --git a/etc/dev.d/default/selinux.dev b/etc/dev.d/default/selinux.dev index 7911d345b9..9682658aad 100644 --- a/etc/dev.d/default/selinux.dev +++ b/etc/dev.d/default/selinux.dev @@ -11,7 +11,7 @@ fi [ "$UDEV_SELINUX" != "yes" ] && exit 0 if [ -x /sbin/restorecon ]; then - if [ "$UDEV_LOG" = "yes" -a -x /usr/bin/logger ]; then + if [ "$UDEV_LOG" = "yes" ] && [ -x /usr/bin/logger ]; then /usr/bin/logger -p auth.debug "Restoring file security contexts for $DEVNAME" fi /sbin/restorecon $DEVNAME diff --git a/etc/init.d/udev b/etc/init.d/udev index cd9074de09..7e6305a45b 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -1,4 +1,4 @@ -#! /bin/bash +#! /bin/sh # # udev init script to setup /udev # diff --git a/etc/init.d/udev.debian b/etc/init.d/udev.debian index 776a73644c..8268fe6c2f 100644 --- a/etc/init.d/udev.debian +++ b/etc/init.d/udev.debian @@ -1,4 +1,4 @@ -#! /bin/bash +#! /bin/sh # # random init script to setup /udev # diff --git a/etc/init.d/udev.init.lfs b/etc/init.d/udev.init.lfs index c738369081..41a3fecf0f 100644 --- a/etc/init.d/udev.init.lfs +++ b/etc/init.d/udev.init.lfs @@ -5,9 +5,9 @@ # 2003, 2004 by Michael Buesch # -source /etc/sysconfig/rc -source $rc_functions -source /etc/udev/udev.conf +. /etc/sysconfig/rc +. $rc_functions +. /etc/udev/udev.conf sysfs_dir="/sys" bin="/sbin/udev" diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 4d021c5e87..4f20259480 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -15,15 +15,13 @@ else fi get_dev_number() { - local x= - local num=0 - local MEDIA= - local DRIVE="${1%%[0-9]*}" + num=0 + DRIVE="${1%%[0-9]*}" for x in /proc/ide/*/media; do if [ -e "${x}" ]; then - MEDIA=`cat ${x}` - if [ "${MEDIA}" = "$2" ]; then + lMEDIA=`cat ${x}` + if [ "${lMEDIA}" = "$2" ]; then num=$((${num} + 1)) fi if [ "${x}" = "/proc/ide/${DRIVE}/media" ]; then @@ -35,7 +33,7 @@ get_dev_number() { echo $((${num} - 1)) } -if [ -z "$3" -a -f /proc/ide/${1}/media ]; then +if [ -z "$3" ] && [ -f /proc/ide/${1}/media ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` diff --git a/extras/scsi-devfs.sh b/extras/scsi-devfs.sh index 30f4553a5b..12c8aa8eb5 100644 --- a/extras/scsi-devfs.sh +++ b/extras/scsi-devfs.sh @@ -14,7 +14,7 @@ # BUS="scsi", KERNEL="sg*", PROGRAM="/etc/udev/scsi-devfs.sh sg %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" # Find out where sysfs is mounted. Exit if not available -sysfs=`fgrep sysfs /proc/mounts | awk '{print $2}'` +sysfs=`grep -F sysfs /proc/mounts | awk '{print $2}'` if [ "$sysfs" = "" ]; then echo "sysfs is required" exit 1 @@ -63,7 +63,7 @@ s_com="b${scsi_bus}t${scsi_target}u${scsi_lun}$spart" l_log="scsi/host$scsi_host/$l_com" s_log="$1/c${scsi_host}${s_com}" -readlink $2 | fgrep -q pci +readlink $2 | grep -F -q pci if [ "$?" != "0" ]; then # Not a PCI controller, show logical locations only echo $l_log $s_log diff --git a/extras/start_udev b/extras/start_udev index 4908d05b70..bbf32a1bb9 100644 --- a/extras/start_udev +++ b/extras/start_udev @@ -1,4 +1,4 @@ -#! /bin/bash +#! /bin/sh # # start_udev # From 9d009843750a055efe095f7139e0788f71de8f03 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 11 Aug 2004 01:03:06 -0700 Subject: [PATCH 0818/4284] [PATCH] fix manpages based on esr's spambot On Mon, Jul 12, 2004 at 11:14:28AM -0400, esr@thyrsus.com wrote: > This is automatically generated email about problems in a man page for which > you appear to be responsible. If you are not the right person or list, tell > me and I will attempt to correct my database. > > See http://catb.org/~esr/doclifter/problems.html for details on how and > why these patches were generated. Feel free to email me with any questions. > > Note: This patch does not change the mod date of the manual page. You > may wish to do that by hand. > > Problems with udevd.8: > > 1. There are multiple name lines. This makes it impossible to translate > the page to DocBook. It may also confuse some implementations > of man -k. > > --- udevd.8-orig 2004-07-10 06:35:12.032545856 -0400 > +++ udevd.8 2004-07-10 06:36:19.301319448 -0400 > @@ -1,8 +1,6 @@ > .TH UDEVD 8 "February 2004" "" "Linux Administrator's Manual" > .SH NAME > -udevd \- udev event serializer daemon > -.br > -udevsend \- sends the event to udevd > +udevd, udevdsend \- udev event serializer daemon and udev event sender > .SH SYNOPSIS > -- > Eric S. Raymond > Thanks Eric, udevsend.8 is only a symlink to udevd.8, so I attached a stripped down patch to this mail. --- udevd.8 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/udevd.8 b/udevd.8 index 52c270add8..1de7a3cba2 100644 --- a/udevd.8 +++ b/udevd.8 @@ -1,8 +1,6 @@ .TH UDEVD 8 "February 2004" "" "Linux Administrator's Manual" .SH NAME -udevd \- udev event serializer daemon -.br -udevsend \- sends the event to udevd +udevd, udevdsend \- udev event serializer daemon and udev event sender .SH SYNOPSIS .BI udevsend " hotplug-subsystem" .sp From bf9c3576333c061051574ea043ce0bde7984d448 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 5 Sep 2004 17:52:51 +0200 Subject: [PATCH 0819/4284] [PATCH] add permission for legotower usb devices. --- etc/udev/udev.permissions.gentoo | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index 8d2acc01fe..edd8e39cde 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -197,6 +197,7 @@ cdwriter:root:disk:0660 usb/dabusb*:root:usb:0660 usb/mdc800*:root:usb:0660 usb/rio500:root:usb:0660 +usb/legousbtower*:root:usb:0660 sgi_fetchop:root:root:666 iseries/vcd*:root:disk:660 From c449ee6f7f328c66468988da5f07dff53e141f0f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 5 Sep 2004 17:53:11 +0200 Subject: [PATCH 0820/4284] [PATCH] add rules for i386 cpu devices. --- etc/udev/udev.rules.gentoo | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index c2a8ef54b1..a2b878d4a3 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -128,4 +128,9 @@ KERNEL="capi*", NAME="capi/%n" KERNEL="tun", NAME="net/%k" # raw devices -KERNEL="raw[0-9]*", NAME="raw/%k" +KERNEL="raw[0-9]*", NAME="raw/%k" + +# cpu devices +KERNEL="cpu[0-9]*", NAME="cpu/%n/cpuid" +KERNEL="msr[0-9]*", NAME="cpu/%n/cpuid" +KERNEL="microcode", NAME="cpu/microcode" From 00d063985a209444d7252f622149351a5cff8939 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 5 Sep 2004 17:56:08 +0200 Subject: [PATCH 0821/4284] [PATCH] Fix old-style pty breakage in rules file for tty device. Thanks to Martin Schlemmer for the fix. --- etc/udev/udev.rules.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index a2b878d4a3..f8208d9495 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -65,7 +65,7 @@ KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" # pty devices KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k" # ramdisk devices KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" From 3169e8d1ee24c7d23d7e535eb22fced869104ff8 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 5 Sep 2004 18:05:29 +0200 Subject: [PATCH 0822/4284] [PATCH] pass SEQNUM trough udevd here we change udevd to pass the SEQNUM from the hotplug environment to udev and the dev.d/ scripts. We need this for HAL to match the hotplug event with the dev.d/ events. It also changes the type from int to long to match the kernel. --- udev.h | 7 ++++--- udev_lib.h | 6 ++++++ udevd.c | 27 +++++++++++++++------------ udevd.h | 2 +- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/udev.h b/udev.h index 310154f55d..717c1218eb 100644 --- a/udev.h +++ b/udev.h @@ -33,9 +33,10 @@ #define GROUP_SIZE 30 #define MODE_SIZE 8 -#define ACTION_SIZE 30 -#define DEVPATH_SIZE 255 -#define SUBSYSTEM_SIZE 30 +#define ACTION_SIZE 32 +#define DEVPATH_SIZE 256 +#define SUBSYSTEM_SIZE 32 +#define SEQNUM_SIZE 32 /* length of public data */ #define UDEVICE_LEN (offsetof(struct udevice, bus_id)) diff --git a/udev_lib.h b/udev_lib.h index 18ce25ccc7..53ad92d505 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -59,6 +59,12 @@ do { \ snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ } while (0) +#define strlongcat(to, i) \ +do { \ + to[sizeof(to)-1] = '\0'; \ + snprintf((to) + strlen(to), sizeof(to) - strlen(to)-1, "%li", i); \ +} while (0) + #define foreach_strpart(str, separator, pos, len) \ for(pos = str, len = 0; \ (pos) < ((str) + strlen(str)); \ diff --git a/udevd.c b/udevd.c index 79de11248e..50720c2450 100644 --- a/udevd.c +++ b/udevd.c @@ -44,7 +44,7 @@ #include "logging.h" static int pipefds[2]; -static int expected_seqnum = 0; +static long expected_seqnum = 0; volatile static int children_waiting; volatile static int run_msg_q; volatile static int sig_flag; @@ -82,7 +82,7 @@ static void msg_dump_queue(void) struct hotplug_msg *msg; list_for_each_entry(msg, &msg_list, list) - dbg("sequence %d in queue", msg->seqnum); + dbg("sequence %li in queue", msg->seqnum); #endif } @@ -120,7 +120,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) msg->queue_time = info.uptime; list_add(&msg->list, &loop_msg->list); - dbg("queued message seq %d", msg->seqnum); + dbg("queued message seq %li", msg->seqnum); /* run msg queue manager */ run_msg_q = 1; @@ -134,12 +134,15 @@ static void udev_run(struct hotplug_msg *msg) pid_t pid; char action[ACTION_SIZE]; char devpath[DEVPATH_SIZE]; - char *env[] = { action, devpath, NULL }; + char seqnum[SEQNUM_SIZE]; + char *env[] = { action, devpath, seqnum, NULL }; strcpy(action, "ACTION="); strfieldcat(action, msg->action); strcpy(devpath, "DEVPATH="); strfieldcat(devpath, msg->devpath); + strcpy(seqnum, "SEQNUM="); + strlongcat(seqnum, msg->seqnum); pid = fork(); switch (pid) { @@ -158,7 +161,7 @@ static void udev_run(struct hotplug_msg *msg) break; default: /* get SIGCHLD in main loop */ - dbg("==> exec seq %d [%d] working at '%s'", msg->seqnum, pid, msg->devpath); + dbg("==> exec seq %li [%d] working at '%s'", msg->seqnum, pid, msg->devpath); msg->pid = pid; } } @@ -186,9 +189,9 @@ static void exec_queue_manager() /* move event to run list */ list_move_tail(&loop_msg->list, &running_list); udev_run(loop_msg); - dbg("moved seq %d to running list", loop_msg->seqnum); + dbg("moved seq %li to running list", loop_msg->seqnum); } else { - dbg("delay seq %d, cause seq %d already working on '%s'", + dbg("delay seq %li, cause seq %li already working on '%s'", loop_msg->seqnum, msg->seqnum, msg->devpath); } } @@ -199,7 +202,7 @@ static void msg_move_exec(struct hotplug_msg *msg) list_move_tail(&msg->list, &exec_list); run_exec_q = 1; expected_seqnum = msg->seqnum+1; - dbg("moved seq %d to exec, next expected is %d", + dbg("moved seq %li to exec, next expected is %li", msg->seqnum, expected_seqnum); } @@ -211,7 +214,7 @@ static void msg_queue_manager() struct sysinfo info; long msg_age = 0; - dbg("msg queue manager, next expected is %d", expected_seqnum); + dbg("msg queue manager, next expected is %li", expected_seqnum); recheck: list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, list) { /* move event with expected sequence to the exec list */ @@ -223,7 +226,7 @@ recheck: /* move event with expired timeout to the exec list */ sysinfo(&info); msg_age = info.uptime - loop_msg->queue_time; - dbg("seq %d is %li seconds old", loop_msg->seqnum, msg_age); + dbg("seq %li is %li seconds old", loop_msg->seqnum, msg_age); if (msg_age > EVENT_TIMEOUT_SEC-1) { msg_move_exec(loop_msg); goto recheck; @@ -350,9 +353,9 @@ static void udev_done(int pid) list_for_each_entry(msg, &running_list, list) { if (msg->pid == pid) { - dbg("<== exec seq %d came back", msg->seqnum); + dbg("<== exec seq %li came back", msg->seqnum); run_queue_delete(msg); - + /* we want to run the exec queue manager since there may * be events waiting with the devpath of the one that * just finished diff --git a/udevd.h b/udevd.h index 5fdd62d323..cced75d5f6 100644 --- a/udevd.h +++ b/udevd.h @@ -33,7 +33,7 @@ struct hotplug_msg { char magic[20]; struct list_head list; pid_t pid; - int seqnum; + long seqnum; long queue_time; char action[ACTION_SIZE]; char devpath[DEVPATH_SIZE]; From cb7c281b8dfb4b1c53902b197c98ac7bd4c7e421 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 5 Sep 2004 18:05:32 +0200 Subject: [PATCH 0823/4284] [PATCH] let /sbin/hotplug execute udev earlier We ran into problems with all the /etc/hotplug.d/ scripts that sleep for the sysfs files or for other reasons. Anyway, it takes much too much time before udev is executed. HAL has its own notifier in /etc/hotplug.d/ and also waits for the dev.d/events with the same SEQNUM. Sometimes it take 25 seconds between these two events, cause the other scripts are sleeping too much :) Attached is a patch that installs the udevsend symlink as 10-udev.hotplug instead of udev.hotplug, to be executed earlier. [kay@pim udev.kay]$ tree /etc/hotplug.d/ /etc/hotplug.d/ `-- default |-- 10-udev.hotplug -> /sbin/udevsend |-- 20-hal.hotplug -> /usr/libexec/hal.hotplug `-- default.hotplug --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index d4d3ac8b05..5083bed7f5 100644 --- a/Makefile +++ b/Makefile @@ -389,7 +389,7 @@ install: install-initscript install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) ln -sf $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER) - - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/$(ROOT).hotplug + - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug ifndef DESTDIR - killall udevd - rm -f $(udevdir)/.udev.tdb @@ -401,7 +401,7 @@ endif done ; \ uninstall: uninstall-man uninstall-dev.d - - rm $(hotplugdir)/udev.hotplug + - rm $(hotplugdir)/10-udev.hotplug - rm $(configdir)/rules.d/50-udev.rules - rm $(configdir)/permissions.d/50-udev.permissions - rm $(configdir)/udev.conf From c506c4087efe567b3cb382bd228644cde3453b04 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 5 Sep 2004 18:05:36 +0200 Subject: [PATCH 0824/4284] [PATCH] update udev_volume_id Here is an update for the volume_id callout to catch up to the latest and greatest: o It is able to skip the label reading of linux raid members, which are otherwise recognized as a normal filesystem. o It reads FAT labels stored in the directory instead of the superblock (Windows only writes in the directory). o The NTFS uuid is the right one now. o It reads all the Apple HFS(+) formats with the labels. o UFS volumes are recognized but no labels are extracted. o We use CFLAGS+=-D_FILE_OFFSET_BITS=64 instead of lsee64() which may fix a bug mentioned on the klibc mailing list. A lot of other new features are only used in HAL and not needed in this simple callout. But if someone stumbles over it and want's to send a patch for some exotic formats, we better keep it up to date :) --- extras/volume_id/Makefile | 6 +- extras/volume_id/udev_volume_id.c | 80 +- extras/volume_id/volume_id.c | 1554 ++++++++++++++++++++++++----- extras/volume_id/volume_id.h | 75 +- 4 files changed, 1430 insertions(+), 285 deletions(-) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 307fdc2f16..8813f9fca5 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -28,7 +28,11 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-Wall -fno-builtin +override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts -Wmissing-declarations \ + -Wnested-externs -Wpointer-arith -Wcast-align \ + -Wsign-compare + +override CFLAGS+=-D_FILE_OFFSET_BITS=64 SYSFS = ../../libsysfs/sysfs_bus.o \ ../../libsysfs/sysfs_class.o \ diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 18915cb62b..e88445054b 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "../../libsysfs/sysfs/libsysfs.h" #include "../../udev_lib.h" @@ -71,6 +73,36 @@ static struct volume_id *open_classdev(struct sysfs_class_device *class_dev) return vid; } +static unsigned long long get_size(struct volume_id *vid) +{ + unsigned long long size; + + if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) + size = 0; + + return size; +} + +static char *usage_id_name(enum volume_id_usage usage) +{ + switch(usage) { + case VOLUME_ID_UNUSED: + return "unused"; + case VOLUME_ID_UNPROBED: + return "unprobed"; + case VOLUME_ID_OTHER: + return "other"; + case VOLUME_ID_PARTITIONTABLE: + return "partitiontable"; + case VOLUME_ID_FILESYSTEM: + return "filesystem"; + case VOLUME_ID_RAID: + return "raid"; + default: + return "unknown type_id"; + } +} + int main(int argc, char *argv[]) { const char help[] = "usage: udev_volume_id [-t|-l|-u|-d]\n" @@ -80,7 +112,6 @@ int main(int argc, char *argv[]) " -d disk label from main device\n" "\n"; static const char short_options[] = "htlud"; - int option; char sysfs_path[SYSFS_PATH_MAX]; char dev_path[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev = NULL; @@ -92,9 +123,12 @@ int main(int argc, char *argv[]) char dasd_label[7]; static char name[VOLUME_ID_LABEL_SIZE]; int len, i, j; + unsigned long long size; int rc = 1; while (1) { + int option; + option = getopt(argc, argv, short_options); if (option == -1) break; @@ -146,24 +180,26 @@ int main(int argc, char *argv[]) vid = open_classdev(class_dev); if (vid == NULL) goto exit; - if (volume_id_probe(vid, ALL) == 0) + + size = get_size(vid); + + if (volume_id_probe(vid, VOLUME_ID_ALL, 0, size) == 0) goto print; break; case 'd' : - /* if we are on a partition, close it and open main block device */ + /* if we are on a partition, open main block device instead */ class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) { - volume_id_close(vid); + if (class_dev_parent != NULL) vid = open_classdev(class_dev_parent); - } else { + else vid = open_classdev(class_dev_parent); - } if (vid == NULL) goto exit; + if (probe_ibm_partition(vid->fd, dasd_label) == 0) { - vid->fs_name = "dasd"; - strncpy(vid->label_string, dasd_label, 6); - vid->label_string[6] = '\0'; + vid->type = "dasd"; + strncpy(vid->label, dasd_label, 6); + vid->label[6] = '\0'; goto print; } break; @@ -174,10 +210,10 @@ int main(int argc, char *argv[]) print: - len = strnlen(vid->label_string, VOLUME_ID_LABEL_SIZE); + len = strnlen(vid->label, VOLUME_ID_LABEL_SIZE); /* remove trailing spaces */ - while (len > 0 && isspace(vid->label_string[len-1])) + while (len > 0 && isspace(vid->label[len-1])) len--; name[len] = '\0'; @@ -185,14 +221,14 @@ print: i = 0; j = 0; while (j < len) { - switch(vid->label_string[j]) { + switch(vid->label[j]) { case '/' : break; case ' ' : name[i++] = '_'; break; default : - name[i++] = vid->label_string[j]; + name[i++] = vid->label[j]; } j++; } @@ -200,27 +236,29 @@ print: switch (print) { case 't': - printf("%s\n", vid->fs_name); + printf("%s\n", vid->type); break; case 'l': - if (name[0] == '\0') { + if (name[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) { rc = 2; goto exit; } printf("%s\n", name); break; case 'u': - if (vid->uuid_string[0] == '\0') { + if (vid->uuid[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) { rc = 2; goto exit; } - printf("%s\n", vid->uuid_string); + printf("%s\n", vid->uuid); break; case 'a': - printf("T:%s\n", vid->fs_name); - printf("L:%s\n", vid->label_string); + printf("F:%s\n", usage_id_name(vid->usage_id)); + printf("T:%s\n", vid->type); + printf("V:%s\n", vid->type_version); + printf("L:%s\n", vid->label); printf("N:%s\n", name); - printf("U:%s\n", vid->uuid_string); + printf("U:%s\n", vid->uuid); } rc = 0; diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index ac7e76b9d4..daeb00038a 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -3,13 +3,10 @@ * * Copyright (C) 2004 Kay Sievers * - * The superblock structs are taken from the libblkid living inside - * the e2fsprogs. This is a simple straightforward implementation for - * reading the label strings of only the most common filesystems. - * If you need a full featured library with attribute caching, support for - * much more partition/media types or non-root disk access, you may have - * a look at: - * http://e2fsprogs.sourceforge.net. + * The superblock structs are taken from the linux kernel sources + * and the libblkid living inside the e2fsprogs. This is a simple + * straightforward implementation for reading the label strings of the + * most common filesystems. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,6 +27,10 @@ #define _GNU_SOURCE #endif +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include #include @@ -49,7 +50,7 @@ } while (0) #else #define dbg(format, arg...) do {} while (0) -#endif +#endif /* DEBUG */ #define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \ (((__u32)(x) & 0xff00u) >> 8)) @@ -68,20 +69,24 @@ (((__u64)(x) & 0x000000000000ff00u) << 40) | \ (((__u64)(x) & 0x00000000000000ffu) << 56)) -#if (__BYTE_ORDER == __LITTLE_ENDIAN) +#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) bswap16(x) +#define be32_to_cpu(x) bswap32(x) #elif (__BYTE_ORDER == __BIG_ENDIAN) #define le16_to_cpu(x) bswap16(x) #define le32_to_cpu(x) bswap32(x) #define le64_to_cpu(x) bswap64(x) +#define be16_to_cpu(x) (x) +#define be32_to_cpu(x) (x) #endif -/* size of superblock buffer, reiser block is at 64k */ +/* size of superblock buffer, reiserfs block is at 64k */ #define SB_BUFFER_SIZE 0x11000 -/* size of seek buffer 2k */ -#define SEEK_BUFFER_SIZE 0x800 +/* size of seek buffer 4k */ +#define SEEK_BUFFER_SIZE 0x1000 static void set_label_raw(struct volume_id *id, @@ -96,15 +101,15 @@ static void set_label_string(struct volume_id *id, { unsigned int i; - memcpy(id->label_string, buf, count); + memcpy(id->label, buf, count); /* remove trailing whitespace */ - i = strnlen(id->label_string, count); + i = strnlen(id->label, count); while (i--) { - if (! isspace(id->label_string[i])) + if (! isspace(id->label[i])) break; } - id->label_string[i+1] = '\0'; + id->label[i+1] = '\0'; } #define LE 0 @@ -118,23 +123,23 @@ static void set_label_unicode16(struct volume_id *id, __u16 c; j = 0; - for (i = 0; i <= count-2; i += 2) { + 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) { - id->label_string[j] = '\0'; + id->label[j] = '\0'; break; } else if (c < 0x80) { - id->label_string[j++] = (__u8) c; + id->label[j++] = (__u8) c; } else if (c < 0x800) { - id->label_string[j++] = (__u8) (0xc0 | (c >> 6)); - id->label_string[j++] = (__u8) (0x80 | (c & 0x3f)); + id->label[j++] = (__u8) (0xc0 | (c >> 6)); + id->label[j++] = (__u8) (0x80 | (c & 0x3f)); } else { - id->label_string[j++] = (__u8) (0xe0 | (c >> 12)); - id->label_string[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); - id->label_string[j++] = (__u8) (0x80 | (c & 0x3f)); + id->label[j++] = (__u8) (0xe0 | (c >> 12)); + id->label[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); + id->label[j++] = (__u8) (0x80 | (c & 0x3f)); } } } @@ -144,10 +149,10 @@ static void set_uuid(struct volume_id *id, { unsigned int i; - memcpy(id->uuid, buf, count); + memcpy(id->uuid_raw, buf, count); /* create string if uuid is set */ - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) if (buf[i] != 0) goto set; return; @@ -155,11 +160,16 @@ static void set_uuid(struct volume_id *id, set: switch(count) { case 4: - sprintf(id->uuid_string, "%02X%02X-%02X%02X", + sprintf(id->uuid, "%02X%02X-%02X%02X", + buf[3], buf[2], buf[1], buf[0]); + break; + case 8: + 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 16: - sprintf(id->uuid_string, + 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], @@ -171,11 +181,11 @@ set: } } -static __u8 *get_buffer(struct volume_id *id, - unsigned long off, unsigned int len) +static __u8 *get_buffer(struct volume_id *id, __u64 off, unsigned int len) { unsigned int buf_len; + dbg("get buffer off 0x%llx, len 0x%x", off, len); /* check if requested area fits in superblock buffer */ if (off + len <= SB_BUFFER_SIZE) { if (id->sbbuf == NULL) { @@ -186,9 +196,10 @@ static __u8 *get_buffer(struct volume_id *id, /* check if we need to read */ if ((off + len) > id->sbbuf_len) { - dbg("read sbbuf len:0x%lx", off + len); - lseek64(id->fd, 0, SEEK_SET); + dbg("read sbbuf len:0x%llx", off + len); + lseek(id->fd, 0, SEEK_SET); buf_len = read(id->fd, id->sbbuf, off + len); + dbg("got 0x%x (%i) bytes", buf_len, buf_len); id->sbbuf_len = buf_len; if (buf_len < off + len) return NULL; @@ -209,8 +220,9 @@ static __u8 *get_buffer(struct volume_id *id, /* check if we need to read */ if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { - dbg("read seekbuf off:0x%lx len:0x%x", off, len); - lseek64(id->fd, off, SEEK_SET); + dbg("read seekbuf off:0x%llx len:0x%x", off, len); + if (lseek(id->fd, off, SEEK_SET) == -1) + return NULL; buf_len = read(id->fd, id->seekbuf, len); dbg("got 0x%x (%i) bytes", buf_len, buf_len); id->seekbuf_off = off; @@ -237,10 +249,298 @@ static void free_buffer(struct volume_id *id) } } +#define LVM1_SB_OFF 0x400 +#define LVM1_MAGIC "HM" +static int probe_lvm1(struct volume_id *id, __u64 off) +{ + struct lvm2_super_block { + __u8 id[2]; + } __attribute__((packed)) *lvm; + + const __u8 *buf; + + buf = get_buffer(id, off + LVM1_SB_OFF, 0x800); + if (buf == NULL) + return -1; + + lvm = (struct lvm2_super_block *) buf; + + if (strncmp(lvm->id, LVM1_MAGIC, 2) != 0) + return -1; + + id->usage_id = VOLUME_ID_RAID; + id->type_id = VOLUME_ID_LVM1; + id->type = "LVM1_member"; + + return 0; +} + +#define LVM2_LABEL_ID "LABELONE" +#define LVM2LABEL_SCAN_SECTORS 4 +static int probe_lvm2(struct volume_id *id, __u64 off) +{ + struct lvm2_super_block { + __u8 id[8]; + __u64 sector_xl; + __u32 crc_xl; + __u32 offset_xl; + __u8 type[8]; + } __attribute__((packed)) *lvm; + + const __u8 *buf; + unsigned int soff; + + buf = 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 (strncmp(lvm->id, LVM2_LABEL_ID, 8) == 0) + goto found; + } + + return -1; + +found: + strncpy(id->type_version, lvm->type, 8); + id->usage_id = VOLUME_ID_RAID; + id->type_id = VOLUME_ID_LVM1; + id->type = "LVM2_member"; + + return 0; +} + +#define MD_RESERVED_BYTES 0x10000 +#define MD_MAGIC 0xa92b4efc +static int probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) +{ + struct mdp_super_block { + __u32 md_magic; + __u32 major_version; + __u32 minor_version; + __u32 patch_version; + __u32 gvalid_words; + __u32 set_uuid0; + __u32 ctime; + __u32 level; + __u32 size; + __u32 nr_disks; + __u32 raid_disks; + __u32 md_minor; + __u32 not_persistent; + __u32 set_uuid1; + __u32 set_uuid2; + __u32 set_uuid3; + } __attribute__((packed)) *mdp; + + const __u8 *buf; + __u64 sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; + __u8 uuid[16]; + + if (size < 0x10000) + return -1; + + buf = get_buffer(id, off + sboff, 0x800); + if (buf == NULL) + return -1; + + mdp = (struct mdp_super_block *) buf; + + if (le32_to_cpu(mdp->md_magic) != MD_MAGIC) + return -1; + + memcpy(uuid, &mdp->set_uuid0, 4); + memcpy(&uuid[4], &mdp->set_uuid1, 12); + set_uuid(id, uuid, 16); + + snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u", + le32_to_cpu(mdp->major_version), + le32_to_cpu(mdp->minor_version), + le32_to_cpu(mdp->patch_version)); + + dbg("found raid signature"); + id->usage_id = VOLUME_ID_RAID; + id->type = "linux_raid_member"; + + return 0; +} + +#define MSDOS_MAGIC "\x55\xaa" +#define MSDOS_PARTTABLE_OFFSET 0x1be +#define MSDOS_SIG_OFF 0x1fe +#define BSIZE 0x200 +#define DOS_EXTENDED_PARTITION 0x05 +#define LINUX_EXTENDED_PARTITION 0x85 +#define WIN98_EXTENDED_PARTITION 0x0f +#define LINUX_RAID_PARTITION 0xfd +#define is_extended(type) \ + (type == DOS_EXTENDED_PARTITION || \ + type == WIN98_EXTENDED_PARTITION || \ + type == LINUX_EXTENDED_PARTITION) +#define is_raid(type) \ + (type == LINUX_RAID_PARTITION) +static int probe_msdos_part_table(struct volume_id *id, __u64 off) +{ + struct msdos_partition_entry { + __u8 boot_ind; + __u8 head; + __u8 sector; + __u8 cyl; + __u8 sys_ind; + __u8 end_head; + __u8 end_sector; + __u8 end_cyl; + __u32 start_sect; + __u32 nr_sects; + } __attribute__((packed)) *part; + + const __u8 *buf; + int i; + __u64 poff; + __u64 plen; + __u64 extended = 0; + __u64 current; + __u64 next; + int limit; + int empty = 1; + struct volume_id_partition *p; + + buf = get_buffer(id, off, 0x200); + if (buf == NULL) + return -1; + + if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + return -1; + + /* check flags on all entries for a valid partition table */ + part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; + for (i = 0; i < 4; i++) { + if (part[i].boot_ind != 0 && + part[i].boot_ind != 0x80) + return -1; + + if (le32_to_cpu(part[i].nr_sects) != 0) + empty = 0; + } + if (empty == 1) + return -1; + + if (id->partitions != NULL) + free(id->partitions); + id->partitions = malloc(VOLUME_ID_PARTITIONS_MAX * + sizeof(struct volume_id_partition)); + if (id->partitions == NULL) + return -1; + memset(id->partitions, 0x00, + VOLUME_ID_PARTITIONS_MAX * sizeof(struct volume_id_partition)); + + for (i = 0; i < 4; i++) { + poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; + plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; + + if (plen == 0) + continue; + + p = &id->partitions[i]; + + if (is_extended(part[i].sys_ind)) { + dbg("found extended partition at 0x%llx", poff); + p->usage_id = VOLUME_ID_PARTITIONTABLE; + p->type_id = VOLUME_ID_MSDOSEXTENDED; + p->type = "msdos_extended_partition"; + if (extended == 0) + extended = off + poff; + } else { + dbg("found 0x%x data partition at 0x%llx, len 0x%llx", + part[i].sys_ind, poff, plen); + + if (is_raid(part[i].sys_ind)) + p->usage_id = VOLUME_ID_RAID; + else + p->usage_id = VOLUME_ID_UNPROBED; + } + + p->off = off + poff; + p->len = plen; + id->partition_count = i+1; + } + + next = extended; + current = extended; + limit = 50; + + /* follow extended partition chain and add data partitions */ + while (next != 0) { + if (limit-- == 0) { + dbg("extended chain limit reached"); + break; + } + + buf = get_buffer(id, current, 0x200); + if (buf == NULL) + break; + + part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; + + if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + break; + + next = 0; + + for (i = 0; i < 4; i++) { + poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; + plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; + + if (plen == 0) + continue; + + if (is_extended(part[i].sys_ind)) { + dbg("found extended partition at 0x%llx", poff); + if (next == 0) + next = extended + poff; + } else { + dbg("found 0x%x data partition at 0x%llx, len 0x%llx", + part[i].sys_ind, poff, plen); + + /* we always start at the 5th entry */ + while (id->partition_count < 4) + id->partitions[id->partition_count++].usage_id = + VOLUME_ID_UNUSED; + + p = &id->partitions[id->partition_count]; + + if (is_raid(part[i].sys_ind)) + p->usage_id = VOLUME_ID_RAID; + else + p->usage_id = VOLUME_ID_UNPROBED; + + p->off = current + poff; + p->len = plen; + id->partition_count++; + if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) { + dbg("to many partitions"); + next = 0; + } + } + } + + current = next; + } + + id->usage_id = VOLUME_ID_PARTITIONTABLE; + id->type_id = VOLUME_ID_MSDOSPARTTABLE; + id->type = "msdos_partition_table"; + + return 0; +} + #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 #define EXT_SUPERBLOCK_OFFSET 0x400 -static int probe_ext(struct volume_id *id) +static int probe_ext(struct volume_id *id, __u64 off) { struct ext2_super_block { __u32 inodes_count; @@ -262,7 +562,7 @@ static int probe_ext(struct volume_id *id) } __attribute__((__packed__)) *es; es = (struct ext2_super_block *) - get_buffer(id, EXT_SUPERBLOCK_OFFSET, 0x200); + get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); if (es == NULL) return -1; @@ -276,21 +576,23 @@ static int probe_ext(struct volume_id *id) if ((le32_to_cpu(es->feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { - id->fs_type = EXT3; - id->fs_name = "ext3"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_EXT3; + id->type = "ext3"; } else { - id->fs_type = EXT2; - id->fs_name = "ext2"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_EXT2; + id->type = "ext2"; } return 0; } -#define REISER1_SUPERBLOCK_OFFSET 0x2000 -#define REISER_SUPERBLOCK_OFFSET 0x10000 -static int probe_reiser(struct volume_id *id) +#define REISERFS1_SUPERBLOCK_OFFSET 0x2000 +#define REISERFS_SUPERBLOCK_OFFSET 0x10000 +static int probe_reiserfs(struct volume_id *id, __u64 off) { - struct reiser_super_block { + struct reiserfs_super_block { __u32 blocks_count; __u32 free_blocks; __u32 root_block; @@ -306,23 +608,30 @@ static int probe_reiser(struct volume_id *id) __u8 label[16]; } __attribute__((__packed__)) *rs; - rs = (struct reiser_super_block *) - get_buffer(id, REISER_SUPERBLOCK_OFFSET, 0x200); + rs = (struct reiserfs_super_block *) + get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); if (rs == NULL) return -1; - if (strncmp(rs->magic, "ReIsEr2Fs", 9) == 0) - goto found; - if (strncmp(rs->magic, "ReIsEr3Fs", 9) == 0) + if (strncmp(rs->magic, "ReIsEr2Fs", 9) == 0) { + strcpy(id->type_version, "3.6"); goto found; + } - rs = (struct reiser_super_block *) - get_buffer(id, REISER1_SUPERBLOCK_OFFSET, 0x200); + if (strncmp(rs->magic, "ReIsEr3Fs", 9) == 0) { + strcpy(id->type_version, "JR"); + goto found; + } + + rs = (struct reiserfs_super_block *) + get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200); if (rs == NULL) return -1; - if (strncmp(rs->magic, "ReIsErFs", 8) == 0) + if (strncmp(rs->magic, "ReIsErFs", 8) == 0) { + strcpy(id->type_version, "3.5"); goto found; + } return -1; @@ -331,13 +640,14 @@ found: set_label_string(id, rs->label, 16); set_uuid(id, rs->uuid, 16); - id->fs_type = REISER; - id->fs_name = "reiser"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_REISERFS; + id->type = "reiserfs"; return 0; } -static int probe_xfs(struct volume_id *id) +static int probe_xfs(struct volume_id *id, __u64 off) { struct xfs_super_block { __u8 magic[4]; @@ -354,7 +664,7 @@ static int probe_xfs(struct volume_id *id) __u64 fdblocks; } __attribute__((__packed__)) *xs; - xs = (struct xfs_super_block *) get_buffer(id, 0, 0x200); + xs = (struct xfs_super_block *) get_buffer(id, off, 0x200); if (xs == NULL) return -1; @@ -365,14 +675,15 @@ static int probe_xfs(struct volume_id *id) set_label_string(id, xs->fname, 12); set_uuid(id, xs->uuid, 16); - id->fs_type = XFS; - id->fs_name = "xfs"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_XFS; + id->type = "xfs"; return 0; } #define JFS_SUPERBLOCK_OFFSET 0x8000 -static int probe_jfs(struct volume_id *id) +static int probe_jfs(struct volume_id *id, __u64 off) { struct jfs_super_block { __u8 magic[4]; @@ -388,7 +699,7 @@ static int probe_jfs(struct volume_id *id) } __attribute__((__packed__)) *js; js = (struct jfs_super_block *) - get_buffer(id, JFS_SUPERBLOCK_OFFSET, 0x200); + get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200); if (js == NULL) return -1; @@ -399,115 +710,294 @@ static int probe_jfs(struct volume_id *id) set_label_string(id, js->label, 16); set_uuid(id, js->uuid, 16); - id->fs_type = JFS; - id->fs_name = "jfs"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_JFS; + id->type = "jfs"; return 0; } -static int probe_vfat(struct volume_id *id) +#define FAT12_MAX 0xff5 +#define FAT16_MAX 0xfff5 +#define FAT_ATTR_VOLUME 0x08 +struct vfat_dir_entry { + __u8 name[11]; + __u8 attr; + __u16 time_creat; + __u16 date_creat; + __u16 time_acc; + __u16 date_acc; + __u16 cluster_high; + __u16 time_write; + __u16 date_write; + __u16 cluster_low; + __u32 size; +} __attribute__((__packed__)); + +static char *vfat_search_label_in_dir(const __u8 *buf, __u16 size) +{ + struct vfat_dir_entry *dir; + int i; + __u16 count; + + dir = (struct vfat_dir_entry*) buf; + count = size / sizeof(struct vfat_dir_entry); + dbg("expected entries 0x%x", count); + + for (i = 0; i <= count; i++) { + /* end marker */ + if (dir[i].attr == 0x00) { + dbg("end of dir"); + return NULL; + } + + /* empty entry */ + if (dir[i].attr == 0xe5) + continue; + + if (dir[i].attr == FAT_ATTR_VOLUME) { + dbg("found ATTR_VOLUME id in root dir"); + return dir[i].name; + } + + dbg("skip dir entry"); + } + + return NULL; +} + +static int probe_vfat(struct volume_id *id, __u64 off) { struct vfat_super_block { - __u8 ignored[3]; + __u8 boot_jump[3]; __u8 sysid[8]; - __u8 sector_size[2]; - __u8 cluster_size; + __u16 sector_size; + __u8 sectors_per_cluster; __u16 reserved; __u8 fats; - __u8 dir_entries[2]; - __u8 sectors[2]; + __u16 dir_entries; + __u16 sectors; __u8 media; __u16 fat_length; __u16 secs_track; __u16 heads; __u32 hidden; __u32 total_sect; - __u32 fat32_length; - __u16 flags; - __u8 version[2]; - __u32 root_cluster; - __u16 insfo_sector; - __u16 backup_boot; - __u16 reserved2[6]; - __u8 unknown[3]; - __u8 serno[4]; - __u8 label[11]; - __u8 magic[8]; - __u8 dummy2[164]; - __u8 pmagic[2]; + union { + struct fat_super_block { + __u8 unknown[3]; + __u8 serno[4]; + __u8 label[11]; + __u8 magic[8]; + __u8 dummy2[192]; + __u8 pmagic[2]; + } __attribute__((__packed__)) fat; + struct fat32_super_block { + __u32 fat32_length; + __u16 flags; + __u8 version[2]; + __u32 root_cluster; + __u16 insfo_sector; + __u16 backup_boot; + __u16 reserved2[6]; + __u8 unknown[3]; + __u8 serno[4]; + __u8 label[11]; + __u8 magic[8]; + __u8 dummy2[164]; + __u8 pmagic[2]; + } __attribute__((__packed__)) fat32; + } __attribute__((__packed__)) type; } __attribute__((__packed__)) *vs; - vs = (struct vfat_super_block *) get_buffer(id, 0, 0x200); + __u16 sector_size; + __u16 dir_entries; + __u32 sect_count; + __u16 reserved; + __u16 fat_size; + __u32 root_cluster; + __u32 dir_size; + __u32 cluster_count; + __u32 fat_length; + __u64 root_start; + __u32 start_data_sect; + __u16 root_dir_entries; + __u8 *buf; + __u32 buf_size; + __u8 *label = NULL; + __u32 next; + + vs = (struct vfat_super_block *) get_buffer(id, off, 0x200); if (vs == NULL) return -1; - if (strncmp(vs->magic, "MSWIN", 5) == 0) - goto found; - if (strncmp(vs->magic, "FAT32 ", 8) == 0) - goto found; - return -1; + /* believe only that's fat, don't trust the version + * the cluster_count will tell us + */ + if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0) + goto valid; -found: - set_label_raw(id, vs->label, 11); - set_label_string(id, vs->label, 11); - set_uuid(id, vs->serno, 4); + if (strncmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) + goto valid; - id->fs_type = VFAT; - id->fs_name = "vfat"; + if (strncmp(vs->type.fat.magic, "FAT16 ", 8) == 0) + goto valid; - return 0; -} + if (strncmp(vs->type.fat.magic, "MSDOS", 5) == 0) + goto valid; -static int probe_msdos(struct volume_id *id) -{ - struct msdos_super_block { - __u8 ignored[3]; - __u8 sysid[8]; - __u8 sector_size[2]; - __u8 cluster_size; - __u16 reserved; - __u8 fats; - __u8 dir_entries[2]; - __u8 sectors[2]; - __u8 media; - __u16 fat_length; - __u16 secs_track; - __u16 heads; - __u32 hidden; - __u32 total_sect; - __u8 unknown[3]; - __u8 serno[4]; - __u8 label[11]; - __u8 magic[8]; - __u8 dummy2[192]; - __u8 pmagic[2]; - } __attribute__((__packed__)) *ms; + if (strncmp(vs->type.fat.magic, "FAT12 ", 8) == 0) + goto valid; - ms = (struct msdos_super_block *) get_buffer(id, 0, 0x200); - if (ms == NULL) + /* + * There are old floppies out there without a magic, so we check + * for well known values and guess if it's a fat volume + */ + + /* boot jump address check */ + if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) && + vs->boot_jump[0] != 0xe9) return -1; - if (strncmp(ms->magic, "MSDOS", 5) == 0) + /* heads check */ + if (vs->heads == 0) + return -1; + + /* cluster size check*/ + if (vs->sectors_per_cluster == 0 || + (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))) + return -1; + + /* media check */ + if (vs->media < 0xf8 && vs->media != 0xf0) + return -1; + + /* fat count*/ + if (vs->fats != 2) + return -1; + +valid: + /* 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 = vs->total_sect; + dbg("sect_count 0x%x", sect_count); + + fat_length = le16_to_cpu(vs->fat_length); + if (fat_length == 0) + fat_length = le32_to_cpu(vs->type.fat32.fat32_length); + dbg("fat_length 0x%x", fat_length); + + fat_size = fat_length * vs->fats; + 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); + + if (cluster_count < FAT12_MAX) { + strcpy(id->type_version, "FAT12"); + } else if (cluster_count < FAT16_MAX) { + strcpy(id->type_version, "FAT16"); + } else { + strcpy(id->type_version, "FAT32"); + goto fat32; + } + + /* the label may be an attribute in the root directory */ + root_start = (reserved + fat_size) * sector_size; + root_dir_entries = le16_to_cpu(vs->dir_entries); + dbg("root dir start 0x%x", root_start); + + buf_size = root_dir_entries * sizeof(struct vfat_dir_entry); + buf = get_buffer(id, off + root_start, buf_size); + if (buf == NULL) goto found; - if (strncmp(ms->magic, "FAT16 ", 8) == 0) - goto found; - if (strncmp(ms->magic, "FAT12 ", 8) == 0) - goto found; - return -1; + + label = vfat_search_label_in_dir(buf, buf_size); + + if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { + set_label_raw(id, label, 11); + set_label_string(id, label, 11); + } else if (strncmp(vs->type.fat.label, "NO NAME ", 11) != 0) { + set_label_raw(id, vs->type.fat.label, 11); + set_label_string(id, vs->type.fat.label, 11); + } + set_uuid(id, vs->type.fat.serno, 4); + goto found; + +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; + while (1) { + __u32 next_sect_off; + __u64 next_off; + __u64 fat_entry_off; + + 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%x", next_off); + + /* get cluster */ + buf = get_buffer(id, off + next_off, buf_size); + if (buf == NULL) + goto found; + + label = vfat_search_label_in_dir(buf, buf_size); + if (label != NULL) + break; + + /* get FAT entry */ + fat_entry_off = (reserved * sector_size) + (next * sizeof(__u32)); + buf = get_buffer(id, off + fat_entry_off, buf_size); + if (buf == NULL) + goto found; + + /* set next cluster */ + next = le32_to_cpu(*((__u32 *) buf) & 0x0fffffff); + if (next == 0) + break; + } + + if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { + set_label_raw(id, label, 11); + set_label_string(id, label, 11); + } else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) == 0) { + set_label_raw(id, vs->type.fat32.label, 11); + set_label_string(id, vs->type.fat32.label, 11); + } + set_uuid(id, vs->type.fat32.serno, 4); found: - set_label_raw(id, ms->label, 11); - set_label_string(id, ms->label, 11); - set_uuid(id, ms->serno, 4); - - id->fs_type = MSDOS; - id->fs_name = "msdos"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_VFAT; + id->type = "vfat"; return 0; } #define UDF_VSD_OFFSET 0x8000 -static int probe_udf(struct volume_id *id) +static int probe_udf(struct volume_id *id, __u64 off) { struct volume_descriptor { struct descriptor_tag { @@ -550,7 +1040,7 @@ static int probe_udf(struct volume_id *id) unsigned int clen; vsd = (struct volume_structure_descriptor *) - get_buffer(id, UDF_VSD_OFFSET, 0x200); + get_buffer(id, off + UDF_VSD_OFFSET, 0x200); if (vsd == NULL) return -1; @@ -574,7 +1064,7 @@ 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 *) - get_buffer(id, UDF_VSD_OFFSET + bs, 0x800); + get_buffer(id, off + UDF_VSD_OFFSET + bs, 0x800); if (vsd == NULL) return -1; dbg("test for blocksize: 0x%x", bs); @@ -587,7 +1077,7 @@ nsr: /* search the list of VSDs for a NSR descriptor */ for (b = 0; b < 64; b++) { vsd = (struct volume_structure_descriptor *) - get_buffer(id, UDF_VSD_OFFSET + (b * bs), 0x800); + get_buffer(id, off + UDF_VSD_OFFSET + (b * bs), 0x800); if (vsd == NULL) return -1; @@ -605,7 +1095,8 @@ nsr: anchor: /* read anchor volume descriptor */ - vd = (struct volume_descriptor *) get_buffer(id, 256 * bs, 0x200); + vd = (struct volume_descriptor *) + get_buffer(id, off + (256 * bs), 0x200); if (vd == NULL) return -1; @@ -621,7 +1112,7 @@ anchor: /* pick the primary descriptor from the list */ for (b = 0; b < count; b++) { vd = (struct volume_descriptor *) - get_buffer(id, (loc + b) * bs, 0x200); + get_buffer(id, off + ((loc + b) * bs), 0x200); if (vd == NULL) return -1; @@ -644,20 +1135,21 @@ pvd: clen = vd->type.primary.ident.clen; dbg("label string charsize=%i bit", clen); - if (clen == 8) + if (clen == 8) set_label_string(id, vd->type.primary.ident.c, 31); else if (clen == 16) set_label_unicode16(id, vd->type.primary.ident.c, BE,31); found: - id->fs_type = UDF; - id->fs_name = "udf"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_UDF; + id->type = "udf"; return 0; } #define ISO_SUPERBLOCK_OFFSET 0x8000 -static int probe_iso9660(struct volume_id *id) +static int probe_iso9660(struct volume_id *id, __u64 off) { union iso_super_block { struct iso_header { @@ -677,7 +1169,7 @@ static int probe_iso9660(struct volume_id *id) } __attribute__((__packed__)) *is; is = (union iso_super_block *) - get_buffer(id, ISO_SUPERBLOCK_OFFSET, 0x200); + get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); if (is == NULL) return -1; @@ -691,40 +1183,557 @@ static int probe_iso9660(struct volume_id *id) return -1; found: - id->fs_type = ISO9660; - id->fs_name = "iso9660"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_ISO9660; + id->type = "iso9660"; + + return 0; +} + +#define UFS_MAGIC 0x00011954 +#define UFS2_MAGIC 0x19540119 +#define UFS_MAGIC_FEA 0x00195612 +#define UFS_MAGIC_LFN 0x00095014 + + +static int probe_ufs(struct volume_id *id, __u64 off) +{ + struct ufs_super_block { + __u32 fs_link; + __u32 fs_rlink; + __u32 fs_sblkno; + __u32 fs_cblkno; + __u32 fs_iblkno; + __u32 fs_dblkno; + __u32 fs_cgoffset; + __u32 fs_cgmask; + __u32 fs_time; + __u32 fs_size; + __u32 fs_dsize; + __u32 fs_ncg; + __u32 fs_bsize; + __u32 fs_fsize; + __u32 fs_frag; + __u32 fs_minfree; + __u32 fs_rotdelay; + __u32 fs_rps; + __u32 fs_bmask; + __u32 fs_fmask; + __u32 fs_bshift; + __u32 fs_fshift; + __u32 fs_maxcontig; + __u32 fs_maxbpg; + __u32 fs_fragshift; + __u32 fs_fsbtodb; + __u32 fs_sbsize; + __u32 fs_csmask; + __u32 fs_csshift; + __u32 fs_nindir; + __u32 fs_inopb; + __u32 fs_nspf; + __u32 fs_optim; + __u32 fs_npsect_state; + __u32 fs_interleave; + __u32 fs_trackskew; + __u32 fs_id[2]; + __u32 fs_csaddr; + __u32 fs_cssize; + __u32 fs_cgsize; + __u32 fs_ntrak; + __u32 fs_nsect; + __u32 fs_spc; + __u32 fs_ncyl; + __u32 fs_cpg; + __u32 fs_ipg; + __u32 fs_fpg; + struct ufs_csum { + __u32 cs_ndir; + __u32 cs_nbfree; + __u32 cs_nifree; + __u32 cs_nffree; + } __attribute__((__packed__)) fs_cstotal; + __s8 fs_fmod; + __s8 fs_clean; + __s8 fs_ronly; + __s8 fs_flags; + union { + struct { + __s8 fs_fsmnt[512]; + __u32 fs_cgrotor; + __u32 fs_csp[31]; + __u32 fs_maxcluster; + __u32 fs_cpc; + __u16 fs_opostbl[16][8]; + } __attribute__((__packed__)) fs_u1; + struct { + __s8 fs_fsmnt[468]; + __u8 fs_volname[32]; + __u64 fs_swuid; + __s32 fs_pad; + __u32 fs_cgrotor; + __u32 fs_ocsp[28]; + __u32 fs_contigdirs; + __u32 fs_csp; + __u32 fs_maxcluster; + __u32 fs_active; + __s32 fs_old_cpc; + __s32 fs_maxbsize; + __s64 fs_sparecon64[17]; + __s64 fs_sblockloc; + struct ufs2_csum_total { + __u64 cs_ndir; + __u64 cs_nbfree; + __u64 cs_nifree; + __u64 cs_nffree; + __u64 cs_numclusters; + __u64 cs_spare[3]; + } __attribute__((__packed__)) fs_cstotal; + struct ufs_timeval { + __s32 tv_sec; + __s32 tv_usec; + } __attribute__((__packed__)) fs_time; + __s64 fs_size; + __s64 fs_dsize; + __u64 fs_csaddr; + __s64 fs_pendingblocks; + __s32 fs_pendinginodes; + } __attribute__((__packed__)) fs_u2; + } fs_u11; + union { + struct { + __s32 fs_sparecon[53]; + __s32 fs_reclaim; + __s32 fs_sparecon2[1]; + __s32 fs_state; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + } __attribute__((__packed__)) fs_sun; + struct { + __s32 fs_sparecon[53]; + __s32 fs_reclaim; + __s32 fs_sparecon2[1]; + __u32 fs_npsect; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + } __attribute__((__packed__)) fs_sunx86; + struct { + __s32 fs_sparecon[50]; + __s32 fs_contigsumsize; + __s32 fs_maxsymlinklen; + __s32 fs_inodefmt; + __u32 fs_maxfilesize[2]; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + __s32 fs_state; + } __attribute__((__packed__)) fs_44; + } fs_u2; + __s32 fs_postblformat; + __s32 fs_nrpos; + __s32 fs_postbloff; + __s32 fs_rotbloff; + __u32 fs_magic; + __u8 fs_space[1]; + } __attribute__((__packed__)) *ufs; + + __u32 magic; + int i; + int offsets[] = {0, 8, 64, 256, -1}; + + for (i = 0; offsets[i] >= 0; i++) { + ufs = (struct ufs_super_block *) + 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: + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_UFS; + id->type = "ufs"; + + return 0; +} + +static int probe_mac_partition_map(struct volume_id *id, __u64 off) +{ + struct mac_driver_desc { + __u8 signature[2]; + __u16 block_size; + __u32 block_count; + } __attribute__((__packed__)) *driver; + + struct mac_partition { + __u8 signature[2]; + __u16 res1; + __u32 map_count; + __u32 start_block; + __u32 block_count; + __u8 name[32]; + __u8 type[32]; + } __attribute__((__packed__)) *part; + + const __u8 *buf; + + buf = get_buffer(id, off, 0x200); + if (buf == NULL) + return -1; + + part = (struct mac_partition *) buf; + if ((strncmp(part->signature, "PM", 2) == 0) && + (strncmp(part->type, "Apple_partition_map", 19) == 0)) { + /* linux creates an own subdevice for the map + * just return the type if the drive header is missing */ + id->usage_id = VOLUME_ID_PARTITIONTABLE; + id->type_id = VOLUME_ID_MACPARTMAP; + id->type = "mac_partition_map"; + return 0; + } + + driver = (struct mac_driver_desc *) buf; + if (strncmp(driver->signature, "ER", 2) == 0) { + /* we are on a main device, like a CD + * just try to probe the first partition from the map */ + unsigned int bsize = be16_to_cpu(driver->block_size); + int part_count; + int i; + + /* get first entry of partition table */ + buf = get_buffer(id, off + bsize, 0x200); + if (buf == NULL) + return -1; + + part = (struct mac_partition *) buf; + if (strncmp(part->signature, "PM", 2) != 0) + return -1; + + part_count = be32_to_cpu(part->map_count); + dbg("expecting %d partition entries", part_count); + + if (id->partitions != NULL) + free(id->partitions); + id->partitions = + malloc(part_count * sizeof(struct volume_id_partition)); + if (id->partitions == NULL) + return -1; + memset(id->partitions, 0x00, sizeof(struct volume_id_partition)); + + id->partition_count = part_count; + + for (i = 0; i < part_count; i++) { + __u64 poff; + __u64 plen; + + buf = get_buffer(id, off + ((i+1) * bsize), 0x200); + if (buf == NULL) + return -1; + + part = (struct mac_partition *) buf; + if (strncmp(part->signature, "PM", 2) != 0) + return -1; + + poff = be32_to_cpu(part->start_block) * bsize; + plen = be32_to_cpu(part->block_count) * bsize; + dbg("found '%s' partition entry at 0x%llx, len 0x%llx", + part->type, poff, plen); + + id->partitions[i].off = poff; + id->partitions[i].len = plen; + + if (strncmp(part->type, "Apple_Free", 10) == 0) { + id->partitions[i].usage_id = VOLUME_ID_UNUSED; + } else if (strncmp(part->type, "Apple_partition_map", 19) == 0) { + id->partitions[i].usage_id = VOLUME_ID_PARTITIONTABLE; + id->partitions[i].type_id = VOLUME_ID_MACPARTMAP; + } else { + id->partitions[i].usage_id = VOLUME_ID_UNPROBED; + } + } + id->usage_id = VOLUME_ID_PARTITIONTABLE; + id->type_id = VOLUME_ID_MACPARTMAP; + id->type = "mac_partition_map"; + return 0; + } + + return -1; +} + +#define HFS_SUPERBLOCK_OFFSET 0x400 +#define HFS_NODE_LEAF 0xff +#define HFSPLUS_POR_CNID 1 +static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) +{ + struct finder_info { + __u32 boot_folder; + __u32 start_app; + __u32 open_folder; + __u32 os9_folder; + __u32 reserved; + __u32 osx_folder; + __u8 id[8]; + } __attribute__((__packed__)); + + struct hfs_mdb { + __u8 signature[2]; + __u32 cr_date; + __u32 ls_Mod; + __u16 atrb; + __u16 nm_fls; + __u16 vbm_st; + __u16 alloc_ptr; + __u16 nm_al_blks; + __u32 al_blk_size; + __u32 clp_size; + __u16 al_bl_st; + __u32 nxt_cnid; + __u16 free_bks; + __u8 label_len; + __u8 label[27]; + __u32 vol_bkup; + __u16 vol_seq_num; + __u32 wr_cnt; + __u32 xt_clump_size; + __u32 ct_clump_size; + __u16 num_root_dirs; + __u32 file_count; + __u32 dir_count; + struct finder_info finfo; + __u8 embed_sig[2]; + __u16 embed_startblock; + __u16 embed_blockcount; + } __attribute__((__packed__)) *hfs; + + struct hfsplus_bnode_descriptor { + __u32 next; + __u32 prev; + __u8 type; + __u8 height; + __u16 num_recs; + __u16 reserved; + } __attribute__((__packed__)); + + struct hfsplus_bheader_record { + __u16 depth; + __u32 root; + __u32 leaf_count; + __u32 leaf_head; + __u32 leaf_tail; + __u16 node_size; + } __attribute__((__packed__)); + + struct hfsplus_catalog_key { + __u16 key_len; + __u32 parent_id; + __u16 unicode_len; + __u8 unicode[255 * 2]; + } __attribute__((__packed__)); + + struct hfsplus_extent { + __u32 start_block; + __u32 block_count; + } __attribute__((__packed__)); + + struct hfsplus_fork { + __u64 total_size; + __u32 clump_size; + __u32 total_blocks; + struct hfsplus_extent extents[8]; + } __attribute__((__packed__)); + + struct hfsplus_vol_header { + __u8 signature[2]; + __u16 version; + __u32 attributes; + __u32 last_mount_vers; + __u32 reserved; + __u32 create_date; + __u32 modify_date; + __u32 backup_date; + __u32 checked_date; + __u32 file_count; + __u32 folder_count; + __u32 blocksize; + __u32 total_blocks; + __u32 free_blocks; + __u32 next_alloc; + __u32 rsrc_clump_sz; + __u32 data_clump_sz; + __u32 next_cnid; + __u32 write_count; + __u64 encodings_bmp; + struct finder_info finfo; + 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; + } __attribute__((__packed__)) *hfsplus; + + unsigned int blocksize; + unsigned int cat_block; + unsigned int cat_block_count; + unsigned int cat_off; + unsigned int cat_len; + unsigned int leaf_node_head; + unsigned int leaf_node_size; + unsigned int alloc_block_size; + unsigned int alloc_first_block; + unsigned int embed_first_block; + struct hfsplus_bnode_descriptor *descr; + struct hfsplus_bheader_record *bnode; + struct hfsplus_catalog_key *key; + unsigned int label_len; + const __u8 *buf; + + buf = get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + + hfs = (struct hfs_mdb *) buf; + if (strncmp(hfs->signature, "BD", 2) != 0) + goto checkplus; + + /* it may be just a hfs wrapper for hfs+ */ + if (strncmp(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", off); + + buf = get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + goto checkplus; + } + + if (hfs->label_len > 0 && hfs->label_len < 28) { + set_label_raw(id, hfs->label, hfs->label_len); + set_label_string(id, hfs->label, hfs->label_len) ; + } + + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_HFS; + id->type = "hfs"; + + return 0; + +checkplus: + hfsplus = (struct hfsplus_vol_header *) buf; + if (strncmp(hfsplus->signature, "H+", 2) == 0) + goto hfsplus; + if (strncmp(hfsplus->signature, "HX", 2) == 0) + goto hfsplus; + return -1; + +hfsplus: + blocksize = be32_to_cpu(hfsplus->blocksize); + cat_block = be32_to_cpu(hfsplus->cat_file.extents[0].start_block); + cat_block_count = be32_to_cpu(hfsplus->cat_file.extents[0].block_count); + cat_off = (cat_block * blocksize); + cat_len = cat_block_count * blocksize; + dbg("catalog start 0x%llx, len 0x%x", off + cat_off, cat_len); + + buf = get_buffer(id, off + cat_off, 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); + leaf_node_size = be16_to_cpu(bnode->node_size); + + dbg("catalog leaf node 0x%x, size 0x%x", + leaf_node_head, leaf_node_size); + + buf = get_buffer(id, off + cat_off + (leaf_node_head * leaf_node_size), + leaf_node_size); + if (buf == NULL) + goto found; + + descr = (struct hfsplus_bnode_descriptor *) buf; + dbg("descriptor type 0x%x", descr->type); + 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); + set_label_raw(id, key->unicode, label_len); + set_label_unicode16(id, key->unicode, BE, label_len); + +found: + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_HFSPLUS; + id->type = "hfsplus"; return 0; } #define MFT_RECORD_VOLUME 3 -#define MFT_RECORD_ATTR_VOLUME_NAME 0x60u -#define MFT_RECORD_ATTR_OBJECT_ID 0x40u +#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 -static int probe_ntfs(struct volume_id *id) +static int probe_ntfs(struct volume_id *id, __u64 off) { struct ntfs_super_block { __u8 jump[3]; __u8 oem_id[8]; - struct bios_param_block { - __u16 bytes_per_sector; - __u8 sectors_per_cluster; - __u16 reserved_sectors; - __u8 fats; - __u16 root_entries; - __u16 sectors; - __u8 media_type; /* 0xf8 = hard disk */ - __u16 sectors_per_fat; - __u16 sectors_per_track; - __u16 heads; - __u32 hidden_sectors; - __u32 large_sectors; - } __attribute__((__packed__)) bpb; - __u8 unused[4]; + __u16 bytes_per_sector; + __u8 sectors_per_cluster; + __u16 reserved_sectors; + __u8 fats; + __u16 root_entries; + __u16 sectors; + __u8 media_type; + __u16 sectors_per_fat; + __u16 sectors_per_track; + __u16 heads; + __u32 hidden_sectors; + __u32 large_sectors; + __u16 unused[2]; __u64 number_of_sectors; __u64 mft_cluster_location; __u64 mft_mirror_cluster_location; __s8 cluster_per_mft_record; + __u8 reserved1[3]; + __s8 cluster_per_index_record; + __u8 reserved2[3]; + __u8 volume_serial[8]; + __u16 checksum; } __attribute__((__packed__)) *ns; struct master_file_table_record { @@ -752,28 +1761,36 @@ static int probe_ntfs(struct volume_id *id) __u16 value_offset; } __attribute__((__packed__)) *attr; - unsigned int sector_size; - unsigned int cluster_size; - unsigned long mft_cluster; - unsigned long 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; + struct volume_info { + __u64 reserved; + __u8 major_ver; + __u8 minor_ver; + } __attribute__((__packed__)) *info; + + unsigned int sector_size; + unsigned int cluster_size; + __u64 mft_cluster; + __u64 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 __u8 *buf; const __u8 *val; - ns = (struct ntfs_super_block *) get_buffer(id, 0, 0x200); + ns = (struct ntfs_super_block *) get_buffer(id, off, 0x200); if (ns == NULL) return -1; if (strncmp(ns->oem_id, "NTFS", 4) != 0) return -1; - sector_size = le16_to_cpu(ns->bpb.bytes_per_sector); - cluster_size = ns->bpb.sectors_per_cluster * sector_size; + set_uuid(id, ns->volume_serial, 8); + + 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; @@ -785,22 +1802,19 @@ static int probe_ntfs(struct volume_id *id) dbg("sectorsize 0x%x", sector_size); dbg("clustersize 0x%x", cluster_size); - dbg("mftcluster %li", mft_cluster); - dbg("mftoffset 0x%lx", mft_off); + dbg("mftcluster %lli", mft_cluster); + dbg("mftoffset 0x%llx", mft_off); dbg("cluster per mft_record %i", ns->cluster_per_mft_record); dbg("mft record size %i", mft_record_size); - buf = get_buffer(id, mft_off + (MFT_RECORD_VOLUME * mft_record_size), + buf = 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[0] = '%c' %03d, 0x%02x", mftr->magic[0], mftr->magic[0], mftr->magic[0]); - dbg("mftr->magic[1] = '%c' %03d, 0x%02x", mftr->magic[1], mftr->magic[1], mftr->magic[1]); - dbg("mftr->magic[2] = '%c' %03d, 0x%02x", mftr->magic[2], mftr->magic[2], mftr->magic[2]); - dbg("mftr->magic[3] = '%c' %03d, 0x%02x", mftr->magic[3], mftr->magic[3], mftr->magic[3]); + dbg("mftr->magic '%c%c%c%c'", mftr->magic[0], mftr->magic[1], mftr->magic[2], mftr->magic[3]); if (strncmp(mftr->magic, "FILE", 4) != 0) goto found; @@ -813,6 +1827,13 @@ static int probe_ntfs(struct volume_id *id) 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; @@ -820,136 +1841,182 @@ static int probe_ntfs(struct volume_id *id) 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*) (((__u8 *) attr) + val_off); + snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-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 = &((__u8 *) attr)[val_off]; + val = ((__u8 *) attr) + val_off; set_label_raw(id, val, val_len); set_label_unicode16(id, val, LE, val_len); } - - if (attr_type == MFT_RECORD_ATTR_OBJECT_ID) { - dbg("found uuid"); - val = &((__u8 *) attr)[val_off]; - set_uuid(id, val, 16); - } - - if (attr_len == 0) - break; - attr_off += attr_len; - if (attr_off >= mft_record_size) - break; } found: - id->fs_type = NTFS; - id->fs_name = "ntfs"; + id->usage_id = VOLUME_ID_FILESYSTEM; + id->type_id = VOLUME_ID_NTFS; + id->type = "ntfs"; return 0; } #define LARGEST_PAGESIZE 0x4000 -static int probe_swap(struct volume_id *id) +static int probe_swap(struct volume_id *id, __u64 off) { const __u8 *sig; unsigned int page; /* huhh, the swap signature is on the end of the PAGE_SIZE */ for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { - sig = get_buffer(id, page-10, 10); + sig = get_buffer(id, off + page-10, 10); if (sig == NULL) return -1; - if (strncmp(sig, "SWAP-SPACE", 10) == 0) + if (strncmp(sig, "SWAP-SPACE", 10) == 0) { + strcpy(id->type_version, "1"); goto found; - if (strncmp(sig, "SWAPSPACE2", 10) == 0) + } + if (strncmp(sig, "SWAPSPACE2", 10) == 0) { + strcpy(id->type_version, "2"); goto found; + } } return -1; found: - id->fs_type = SWAP; - id->fs_name = "swap"; + id->usage_id = VOLUME_ID_OTHER; + id->type_id = VOLUME_ID_SWAP; + id->type = "swap"; return 0; } /* probe volume for filesystem type and try to read label+uuid */ -int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type) +int volume_id_probe(struct volume_id *id, + enum volume_id_type type, + unsigned long long off, + unsigned long long size) { int rc; if (id == NULL) return -EINVAL; - switch (fs_type) { - case EXT3: - case EXT2: - rc = probe_ext(id); + switch (type) { + case VOLUME_ID_MSDOSPARTTABLE: + rc = probe_msdos_part_table(id, off); break; - case REISER: - rc = probe_reiser(id); + case VOLUME_ID_EXT3: + case VOLUME_ID_EXT2: + rc = probe_ext(id, off); break; - case XFS: - rc = probe_xfs(id); + case VOLUME_ID_REISERFS: + rc = probe_reiserfs(id, off); break; - case JFS: - rc = probe_jfs(id); + case VOLUME_ID_XFS: + rc = probe_xfs(id, off); break; - case MSDOS: - rc = probe_msdos(id); + case VOLUME_ID_JFS: + rc = probe_jfs(id, off); break; - case VFAT: - rc = probe_vfat(id); + case VOLUME_ID_VFAT: + rc = probe_vfat(id, off); break; - case UDF: - rc = probe_udf(id); + case VOLUME_ID_UDF: + rc = probe_udf(id, off); break; - case ISO9660: - rc = probe_iso9660(id); + case VOLUME_ID_ISO9660: + rc = probe_iso9660(id, off); break; - case NTFS: - rc = probe_ntfs(id); + case VOLUME_ID_MACPARTMAP: + rc = probe_mac_partition_map(id, off); break; - case SWAP: - rc = probe_swap(id); + case VOLUME_ID_HFS: + case VOLUME_ID_HFSPLUS: + rc = probe_hfs_hfsplus(id, off); break; - case ALL: + case VOLUME_ID_UFS: + rc = probe_ufs(id, off); + break; + case VOLUME_ID_NTFS: + rc = probe_ntfs(id, off); + break; + case VOLUME_ID_SWAP: + rc = probe_swap(id, off); + break; + case VOLUME_ID_LINUX_RAID: + rc = probe_linux_raid(id, off, size); + break; + case VOLUME_ID_LVM1: + rc = probe_lvm1(id, off); + break; + case VOLUME_ID_LVM2: + rc = probe_lvm2(id, off); + break; + case VOLUME_ID_ALL: default: + rc = probe_linux_raid(id, off, size); + if (rc == 0) + break; + + /* signature in the first block */ + rc = probe_ntfs(id, off); + if (rc == 0) + break; + rc = probe_vfat(id, off); + if (rc == 0) + break; + rc = probe_msdos_part_table(id, off); + if (rc == 0) + break; + rc = probe_mac_partition_map(id, off); + if (rc == 0) + break; + rc = probe_xfs(id, off); + if (rc == 0) + break; + /* fill buffer with maximum */ get_buffer(id, 0, SB_BUFFER_SIZE); - rc = probe_ext(id); + + rc = probe_swap(id, off); if (rc == 0) break; - rc = probe_reiser(id); + rc = probe_ext(id, off); if (rc == 0) break; - rc = probe_xfs(id); + rc = probe_reiserfs(id, off); if (rc == 0) break; - rc = probe_jfs(id); + rc = probe_jfs(id, off); if (rc == 0) break; - rc = probe_msdos(id); + rc = probe_udf(id, off); if (rc == 0) break; - rc = probe_vfat(id); + rc = probe_iso9660(id, off); if (rc == 0) break; - rc = probe_udf(id); + rc = probe_hfs_hfsplus(id, off); if (rc == 0) break; - rc = probe_iso9660(id); + rc = probe_ufs(id, off); if (rc == 0) break; - rc = probe_ntfs(id); + rc = probe_lvm1(id, off); if (rc == 0) break; - rc = probe_swap(id); + rc = probe_lvm2(id, off); if (rc == 0) break; + rc = -1; } @@ -982,9 +2049,11 @@ struct volume_id *volume_id_open_node(const char *path) struct volume_id *id; int fd; - fd = open(path, O_RDONLY); - if (fd < 0) + fd = open(path, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + dbg("unable to open '%s'", path); return NULL; + } id = volume_id_open_fd(fd); if (id == NULL) @@ -1029,5 +2098,8 @@ void volume_id_close(struct volume_id *id) free_buffer(id); + if (id->partitions != NULL) + free(id->partitions); + free(id); } diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index a939743dc1..eb90390617 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -21,42 +21,72 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 004 +#define VOLUME_ID_VERSION 022 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 #define VOLUME_ID_UUID_STRING_SIZE 37 -#define VOLUME_ID_PATH_MAX 255 +#define VOLUME_ID_FORMAT_SIZE 32 +#define VOLUME_ID_PATH_MAX 256 +#define VOLUME_ID_PARTITIONS_MAX 16 +enum volume_id_usage { + VOLUME_ID_UNUSED, + VOLUME_ID_UNPROBED, + VOLUME_ID_OTHER, + VOLUME_ID_FILESYSTEM, + VOLUME_ID_PARTITIONTABLE, + VOLUME_ID_RAID +}; -enum filesystem_type { - ALL, - EXT2, - EXT3, - REISER, - XFS, - JFS, - MSDOS, - VFAT, - UDF, - ISO9660, - NTFS, - SWAP +enum volume_id_type { + VOLUME_ID_ALL, + VOLUME_ID_MSDOSPARTTABLE, + VOLUME_ID_MSDOSEXTENDED, + VOLUME_ID_SWAP, + VOLUME_ID_EXT2, + VOLUME_ID_EXT3, + VOLUME_ID_REISERFS, + VOLUME_ID_XFS, + VOLUME_ID_JFS, + VOLUME_ID_VFAT, + VOLUME_ID_UDF, + VOLUME_ID_ISO9660, + VOLUME_ID_NTFS, + VOLUME_ID_MACPARTMAP, + VOLUME_ID_HFS, + VOLUME_ID_HFSPLUS, + VOLUME_ID_UFS, + VOLUME_ID_LINUX_RAID, + VOLUME_ID_LVM1, + VOLUME_ID_LVM2 +}; + +struct volume_id_partition { + enum volume_id_usage usage_id; + enum volume_id_type type_id; + char *type; + unsigned long long off; + unsigned long long len; }; struct volume_id { unsigned char label_raw[VOLUME_ID_LABEL_SIZE]; unsigned int label_raw_len; - char label_string[VOLUME_ID_LABEL_SIZE+1]; - unsigned char uuid[VOLUME_ID_UUID_SIZE]; - char uuid_string[VOLUME_ID_UUID_STRING_SIZE]; - enum filesystem_type fs_type; - char *fs_name; + char label[VOLUME_ID_LABEL_SIZE+1]; + unsigned char uuid_raw[VOLUME_ID_UUID_SIZE]; + char uuid[VOLUME_ID_UUID_STRING_SIZE]; + enum volume_id_usage usage_id; + enum volume_id_type type_id; + char *type; + char type_version[VOLUME_ID_FORMAT_SIZE]; + struct volume_id_partition *partitions; + unsigned int partition_count; int fd; unsigned char *sbbuf; unsigned int sbbuf_len; unsigned char *seekbuf; - unsigned int seekbuf_off; + unsigned long long seekbuf_off; unsigned int seekbuf_len; int fd_close; }; @@ -71,7 +101,8 @@ extern struct volume_id *volume_id_open_node(const char *path); extern struct volume_id *volume_id_open_dev_t(dev_t devt); /* probe volume for filesystem type and try to read label/uuid */ -extern int volume_id_probe(struct volume_id *id, enum filesystem_type fs_type); +extern int volume_id_probe(struct volume_id *id, enum volume_id_type type, + unsigned long long off, unsigned long long size); /* free allocated device info */ extern void volume_id_close(struct volume_id *id); From bdde56de3993d8793b9af853f389f26f19541292 Mon Sep 17 00:00:00 2001 From: "olh@suse.de" Date: Tue, 7 Sep 2004 00:55:07 -0700 Subject: [PATCH 0825/4284] [PATCH] udevsend depends on udev_lib.o make -j doesnt work with current udev. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5083bed7f5..2f1f71090d 100644 --- a/Makefile +++ b/Makefile @@ -277,7 +277,7 @@ $(DAEMON): $(DAEMON).o $(OBJS) udevd.h $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_lib.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(SENDER): $(SENDER).o udevd.h $(LIBC) +$(SENDER): $(SENDER).o $(OBJS) udevd.h $(LIBC) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ From 3e4414508b409a21b023b9ca4532f62003e0db97 Mon Sep 17 00:00:00 2001 From: "arun@codemovers.org" Date: Fri, 10 Sep 2004 20:54:04 -0700 Subject: [PATCH 0826/4284] [PATCH] udev - read long lines from config files overflow fix Hi Kay, On 23:12 Sat 04 Sep , Kay Sievers wrote: > Cool, a real bug :) > Thanks, for the patch. I think it would be better to skip lenghth exceeding > lines instead of cutting it and continue. While looking at it I restructured > the buffer reading logic a bit and fixed another stupid bug. Thanks for the cleanup. You may have overlooked the fix for udev_config.c(parsing udev.conf) in your patch. So, I've adapted the fixes you applied to namedev_parse.c to this file also. Also, while 'eating' the whitespace the 'count' doesn't get decremented. This leads strncpy to copy the number of whitespace minus 1 characters from the next line. Minus 1 because it copies '\n' from the current line. while (isspace(bufline[0])) { bufline++; + count--; } . . . strncpy(line, bufline, count); Included patch(against udev-030) contains the above fixes as well as your fixes. Signed-off-by: Arun Bhanu --- klibc_fixups.c | 17 +++---- namedev_parse.c | 118 ++++++++++++++++++++++++++++++------------------ udev.h | 2 + udev_config.c | 40 +++++++++------- 4 files changed, 109 insertions(+), 68 deletions(-) diff --git a/klibc_fixups.c b/klibc_fixups.c index bbacfbdc75..d1a452a449 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -41,8 +41,9 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) { unsigned long id = -1; - char line[255]; + char line[LINE_SIZE]; char *buf; + char *bufline; size_t bufsize; size_t cur; size_t count; @@ -59,19 +60,19 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) } /* loop through the whole file */ - cur = 0; - while (1) { + while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; - strncpy(line, buf + cur, count); + if (count >= LINE_SIZE) + continue; + + strncpy(line, bufline, count); line[count] = '\0'; pos = line; - cur += count+1; - if (cur > bufsize) - break; - /* get name */ name = strsep(&pos, ":"); if (name == NULL) diff --git a/namedev_parse.c b/namedev_parse.c index 679efae1b5..4bb1a97ce9 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -58,7 +58,7 @@ void dump_config_dev(struct config_device *dev) { dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', " "sysfs_file[0]='%s', sysfs_value[0]='%s', " - "kernel='%s', program='%s', result='%s'", + "kernel='%s', program='%s', result='%s'" "owner='%s', group='%s', mode=%#o", dev->name, dev->symlink, dev->bus, dev->place, dev->id, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value, @@ -144,7 +144,8 @@ static char *get_key_attribute(char *str) static int namedev_parse_rules(char *filename) { - char line[255]; + char line[LINE_SIZE]; + char *bufline; int lineno; char *temp; char *temp2; @@ -155,6 +156,7 @@ static int namedev_parse_rules(char *filename) size_t cur; size_t count; int program_given = 0; + int valid; int retval = 0; struct config_device dev; @@ -168,35 +170,41 @@ static int namedev_parse_rules(char *filename) /* loop through the whole file */ cur = 0; lineno = 0; - while (1) { + while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); - - strncpy(line, buf + cur, count); - line[count] = '\0'; - temp = line; + bufline = &buf[cur]; + cur += count+1; lineno++; - cur += count+1; - if (cur > bufsize) - break; - - dbg_parse("read '%s'", temp); - - /* eat the whitespace */ - while (isspace(*temp)) - ++temp; + if (count >= LINE_SIZE) { + info("line too long, rule skipped %s, line %d", + filename, lineno); + continue; + } /* empty line? */ - if ((*temp == '\0') || (*temp == '\n')) + if (bufline[0] == '\0' || bufline[0] == '\n') continue; + /* eat the whitespace */ + while (isspace(bufline[0])) { + bufline++; + count--; + } + /* see if this is a comment */ - if (*temp == COMMENT_CHARACTER) + if (bufline[0] == COMMENT_CHARACTER) continue; - memset(&dev, 0x00, sizeof(struct config_device)); + strncpy(line, bufline, count); + line[count] = '\0'; + dbg_parse("read '%s'", line); /* get all known keys */ + memset(&dev, 0x00, sizeof(struct config_device)); + temp = line; + valid = 0; + while (1) { retval = parse_get_pair(&temp, &temp2, &temp3); if (retval) @@ -204,16 +212,19 @@ static int namedev_parse_rules(char *filename) if (strcasecmp(temp2, FIELD_BUS) == 0) { strfieldcpy(dev.bus, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_ID) == 0) { strfieldcpy(dev.id, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_PLACE) == 0) { strfieldcpy(dev.place, temp3); + valid = 1; continue; } @@ -238,54 +249,62 @@ static int namedev_parse_rules(char *filename) } strfieldcpy(pair->file, attr); strfieldcpy(pair->value, temp3); + valid = 1; } continue; } if (strcasecmp(temp2, FIELD_KERNEL) == 0) { strfieldcpy(dev.kernel, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { program_given = 1; strfieldcpy(dev.program, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_RESULT) == 0) { strfieldcpy(dev.result, temp3); + valid = 1; continue; } if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) { attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1); - if (attr != NULL) - if (strcasecmp(attr, ATTR_PARTITIONS) == 0) { + if (attr != NULL && strcasecmp(attr, ATTR_PARTITIONS) == 0) { dbg_parse("creation of partition nodes requested"); dev.partitions = PARTITIONS_COUNT; } strfieldcpy(dev.name, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_SYMLINK) == 0) { strfieldcpy(dev.symlink, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_OWNER) == 0) { strfieldcpy(dev.owner, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_GROUP) == 0) { strfieldcpy(dev.group, temp3); + valid = 1; continue; } if (strcasecmp(temp2, FIELD_MODE) == 0) { dev.mode = strtol(temp3, NULL, 8); + valid = 1; continue; } @@ -293,16 +312,20 @@ static int namedev_parse_rules(char *filename) goto error; } + /* skip line if not any valid key was found */ + if (!valid) + goto error; + /* simple plausibility checks for given keys */ if ((dev.sysfs_pair[0].file[0] == '\0') ^ (dev.sysfs_pair[0].value[0] == '\0')) { - dbg("inconsistency in " FIELD_SYSFS " key"); + info("inconsistency in " FIELD_SYSFS " key"); goto error; } if ((dev.result[0] != '\0') && (program_given == 0)) { - dbg(FIELD_RESULT " is only useful when " - FIELD_PROGRAM " is called in any rule before"); + info(FIELD_RESULT " is only useful when " + FIELD_PROGRAM " is called in any rule before"); goto error; } @@ -313,8 +336,8 @@ static int namedev_parse_rules(char *filename) dbg("add_config_dev returned with error %d", retval); continue; error: - dbg("%s:%d:%d: parse error, rule skipped", - filename, lineno, temp - line); + info("parse error %s, line %d:%d, rule skipped", + filename, lineno, temp - line); } } @@ -324,7 +347,8 @@ error: static int namedev_parse_permissions(char *filename) { - char line[255]; + char line[LINE_SIZE]; + char *bufline; char *temp; char *temp2; char *buf; @@ -333,6 +357,7 @@ static int namedev_parse_permissions(char *filename) size_t count; int retval = 0; struct perm_device dev; + int lineno; if (file_map(filename, &buf, &bufsize) == 0) { dbg("reading '%s' as permissions file", filename); @@ -343,34 +368,41 @@ static int namedev_parse_permissions(char *filename) /* loop through the whole file */ cur = 0; - while (1) { + lineno = 0; + while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); - - strncpy(line, buf + cur, count); - line[count] = '\0'; - temp = line; - + bufline = &buf[cur]; cur += count+1; - if (cur > bufsize) - break; + lineno++; - dbg_parse("read '%s'", temp); - - /* eat the whitespace at the beginning of the line */ - while (isspace(*temp)) - ++temp; + if (count >= LINE_SIZE) { + info("line too long, rule skipped %s, line %d", + filename, lineno); + continue; + } /* empty line? */ - if ((*temp == '\0') || (*temp == '\n')) + if (bufline[0] == '\0' || bufline[0] == '\n') continue; + /* eat the whitespace */ + while (isspace(bufline[0])) { + bufline++; + count--; + } + /* see if this is a comment */ - if (*temp == COMMENT_CHARACTER) + if (bufline[0] == COMMENT_CHARACTER) continue; - memset(&dev, 0x00, sizeof(dev)); + strncpy(line, bufline, count); + line[count] = '\0'; + dbg_parse("read '%s'", line); /* parse the line */ + memset(&dev, 0x00, sizeof(struct perm_device)); + temp = line; + temp2 = strsep(&temp, ":"); if (!temp2) { dbg("cannot parse line '%s'", line); diff --git a/udev.h b/udev.h index 717c1218eb..7c5d18a3d0 100644 --- a/udev.h +++ b/udev.h @@ -38,6 +38,8 @@ #define SUBSYSTEM_SIZE 32 #define SEQNUM_SIZE 32 +#define LINE_SIZE 256 + /* length of public data */ #define UDEVICE_LEN (offsetof(struct udevice, bus_id)) diff --git a/udev_config.c b/udev_config.c index 19f690c7e8..20b6c75d32 100644 --- a/udev_config.c +++ b/udev_config.c @@ -127,7 +127,8 @@ int parse_get_pair(char **orig_string, char **left, char **right) static int parse_config_file(void) { - char line[255]; + char line[LINE_SIZE]; + char *bufline; char *temp; char *variable; char *value; @@ -148,32 +149,37 @@ static int parse_config_file(void) /* loop through the whole file */ lineno = 0; cur = 0; - while (1) { + while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); - - strncpy(line, buf + cur, count); - line[count] = '\0'; - temp = line; + bufline = &buf[cur]; + cur += count+1; lineno++; - cur += count+1; - if (cur > bufsize) - break; - - dbg_parse("read '%s'", temp); - - /* eat the whitespace at the beginning of the line */ - while (isspace(*temp)) - ++temp; + if (count >= LINE_SIZE) { + info("line too long, conf line skipped %s, line %d", + udev_config_filename, lineno); + continue; + } /* empty line? */ - if (*temp == 0x00) + if (bufline[0] == '\0' || bufline[0] == '\n') continue; + /* eat the whitespace */ + while (isspace(bufline[0])) { + bufline++; + count--; + } + /* see if this is a comment */ - if (*temp == COMMENT_CHARACTER) + if (bufline[0] == COMMENT_CHARACTER) continue; + strncpy(line, bufline, count); + line[count] = '\0'; + temp = line; + dbg_parse("read '%s'", temp); + retval = parse_get_pair(&temp, &variable, &value); if (retval != 0) info("%s:%d:%Zd: error parsing '%s'", From 0a8dd7f37c6f788c74aa528949c45aca66638e5a Mon Sep 17 00:00:00 2001 From: "david@fubar.dk" Date: Fri, 10 Sep 2004 21:04:13 -0700 Subject: [PATCH 0827/4284] [PATCH] compatibility symlinks for udev On Mon, 2004-09-06 at 17:45 +0200, Kay Sievers wrote: > On Mon, 2004-09-06 at 16:46 +0200, David Zeuthen wrote: > > Nice, I like it. It's a easy way to group device nodes of the same type, > but coming from different kernel subsystems. > That's a good way of putting it, yeah. > > Here's a patch against udev-030 that can help create compatibility > > symlinks like /dev/cdrom, /dev/cdrom1 etc. The patch introduces a new > > substitution type %C (for Compatibility) that can be used as follows > > I suggest using %e for enumeration here, cause "compatibility" can > easily be misunderstood. > Good point, I've changed that. > And we need a few lines added to the man page at udev.8.in :) > Done. I've also added an example. Also, Kay pointed out offlist that the rules can be written to not require a shell script; this actually works KERNEL="sr*", NAME="%k", SYMLINK="cdrom%e" KERNEL="scd*", NAME="%k", SYMLINK="cdrom%e" KERNEL="pcd*", NAME="%k", SYMLINK="cdrom%e" KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="\%k", SYMLINK="cdrom%e" KERNEL="fd[0-9]", NAME="%k", SYMLINK="floppy%e" KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy", NAME=\"%k", SYMLINK="floppy%e" New patch is attached. David --- namedev.c | 40 ++++++++++++++++++++++++++++++++++++++++ udev.8.in | 15 +++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/namedev.c b/namedev.c index 52417e3793..466016c297 100644 --- a/namedev.c +++ b/namedev.c @@ -42,6 +42,7 @@ #include "logging.h" #include "namedev.h" #include "klibc_fixups.h" +#include "udevdb.h" static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr); @@ -179,6 +180,37 @@ static int get_format_len(char **str) return -1; } +/** Finds the lowest positive N such that N isn't present in + * $(udevroot) either as a file or a symlink. + * + * @param name Name to check for + * @return 0 if didn't exist and N otherwise. + */ +static unsigned int find_free_number (struct udevice *udev, char *name) +{ + char temp[NAME_SIZE]; + char path[NAME_SIZE]; + struct udevice dev; + int result; + + /* have to sweep the database for each lookup */ + result = 0; + strncpy(temp, name, sizeof (temp)); + while (1) { + if (udevdb_get_dev_byname(temp, path, &dev) != 0) + goto found; + /* symlink might be stale if $(udevroot) isn't cleaned; check + * on major/minor to see if it's the same device + */ + if (dev.major == udev->major && dev.minor == udev->minor) + goto found; + snprintf (temp, sizeof(temp), "%s%d", name, ++result); + } + +found: + return result; +} + static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) @@ -195,6 +227,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, char *rest; int slen; struct sysfs_attribute *tmpattr; + unsigned int next_free_number; pos = string; while (1) { @@ -284,6 +317,13 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strfieldcatmax(string, "%", maxsize); pos++; break; + case 'e': + next_free_number = find_free_number(udev, string); + if (next_free_number > 0) { + snprintf(temp2, sizeof(temp2), "%d", next_free_number); + strfieldcatmax(string, temp2, maxsize); + } + break; default: dbg("unknown substitution type '%%%c'", c); break; diff --git a/udev.8.in b/udev.8.in index 6d1dfd9d18..9c22f8aa63 100644 --- a/udev.8.in +++ b/udev.8.in @@ -272,6 +272,13 @@ all remaining parts of the result string are substituted: .BI %s{ filename } The content of a sysfs attribute. .TP +.B %e +If a device node already exists with the name, the smallest positive +decimal integer N is substituted such that the resulting name doesn't +match an existing device node. Otherwise nothing is substituted. This +can be used to create compatibility symlinks and enumerate devices of +the same type originating from different kernel subsystems. +.TP .B %% The '%' character itself. .P @@ -302,6 +309,14 @@ KERNEL="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" # multiple USB webcams with symlinks to be called webcam0, webcam1, ... BUS="usb", SYSFS{model}="XV3", NAME="video%n", SYMLINK="webcam%n" + +# grouping of optical drives from multiple kernel subsystems +KERNEL="sr*", NAME="%k", SYMLINK="cdrom%e" +KERNEL="scd*", NAME="%k", SYMLINK="cdrom%e" +KERNEL="pcd*", NAME="%k", SYMLINK="cdrom%e" +KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", + NAME="%k", SYMLINK="cdrom%e" + .fi .P The permissions and ownership of the created device file is read from From aee380b6d8f849c21a5cc54e5d8f2a43fb88b2f2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 10 Sep 2004 21:09:25 -0700 Subject: [PATCH 0828/4284] [PATCH] Fix naming ethernet devices in udevstart On Tue, Sep 07, 2004 at 12:46:43PM +0200, Kay Sievers wrote: > On Mon, 2004-09-06 at 20:18 -0700, Tom Rini wrote: > > I noticed somewhat recently that my enet devices weren't being renamed > > on boot anymore. I don't quite know when this got broken (or rather, if > > it was supposed to be working. I swear it worked for me once..), but > > the following seems to do it. > > I think it never worked in the udevstart case. It worked only with the > hotplug-event-udev, I expect. > > > In udev_scan_class(), look for not just > > %s/%s/dev (which everything with a dev node has), but %s/%s/dev* (both > > of my enet devices, sis900 & 3c59x only have device) and if that > > exists, pass this along to udev. > > Yeah, network devices don't have a devnode and therefore no "dev", but > they are all in /sys/class/net/. We may just test if we are there > instead of the "device" match. How about something like this. It adds all the net devices without looking at the attributes and keeps the remaining logic like it is. It also removes certain levels of indirection and much simplifies the udevstart process. We surely don't need to open and close the udevdb for every node while iterating over the list. (We are about 5% faster on my box) It's not well tested, so it would be nice if someone can have a look at it, before a broken udevstart renders any system unbootable. --- udev.c | 164 ++++++++++++++++++++++++---------------------------- udev.h | 3 + udevstart.c | 24 ++++---- udevtest.c | 2 +- 4 files changed, 92 insertions(+), 101 deletions(-) diff --git a/udev.c b/udev.c index 90c34d800a..114ca0a52b 100644 --- a/udev.c +++ b/udev.c @@ -40,9 +40,6 @@ char **main_argv; char **main_envp; -/* local variables */ -static int is_udevstart; - #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) @@ -79,36 +76,72 @@ static char *subsystem_blacklist[] = { "" }; -int __udev_hotplug(char *action, const char *devpath, const char *subsystem) +int main(int argc, char *argv[], char *envp[]) { - int retval = -EINVAL; - int i; + main_argv = argv; + main_envp = envp; struct sigaction act; - const int nofake = 0; + char *action; + char *devpath = ""; + char *subsystem = ""; + int i; + int retval = -EINVAL; + enum { + ADD, + REMOVE, + UDEVSTART, + } act_type; - dbg("looking at '%s'", devpath); + dbg("version %s", UDEV_VERSION); - /* we only care about class devices and block stuff */ - if (!strstr(devpath, "class") && - !strstr(devpath, "block")) { - dbg("not a block or class device"); - goto exit; - } + /* initialize our configuration */ + udev_init_config(); - i = 0; - while (subsystem_blacklist[i][0] != '\0') { - if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { - dbg("don't care about '%s' devices", subsystem); + if (strstr(argv[0], "udevstart")) { + act_type = UDEVSTART; + } else { + action = get_action(); + if (!action) { + dbg("no action?"); + goto exit; + } + if (strcmp(action, "add") == 0) { + act_type = ADD; + } else if (strcmp(action, "remove") == 0) { + act_type = REMOVE; + } else { + dbg("unknown action '%s'", action); goto exit; } - i++; - } - /* initialize udev database */ - retval = udevdb_init(UDEVDB_DEFAULT); - if (retval != 0) { - dbg("unable to initialize database"); - goto exit; + devpath = get_devpath(); + if (!devpath) { + dbg("no devpath?"); + goto exit; + } + dbg("looking at '%s'", devpath); + + /* we only care about class devices and block stuff */ + if (strstr(devpath, "class") && strstr(devpath, "block")) { + dbg("not a block or class device"); + goto exit; + } + + subsystem = get_subsystem(main_argv[1]); + if (!subsystem) { + dbg("no subsystem?"); + goto exit; + } + + /* skip blacklisted subsystems */ + i = 0; + while (subsystem_blacklist[i][0] != '\0') { + if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { + dbg("don't care about '%s' devices", subsystem); + goto exit; + } + i++; + } } /* set signal handlers */ @@ -118,76 +151,31 @@ int __udev_hotplug(char *action, const char *devpath, const char *subsystem) sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); - if (strcmp(action, "add") == 0) { - /* Already done. */ - if (!is_udevstart) - namedev_init(); - retval = udev_add_device(devpath, subsystem, nofake); - goto action_done; + /* initialize udev database */ + if (udevdb_init(UDEVDB_DEFAULT) != 0) { + dbg("unable to initialize database"); + goto exit; } - if (strcmp(action, "remove") == 0) { + switch(act_type) { + case UDEVSTART: + dbg("udevstart"); + namedev_init(); + udev_sleep = 0; + retval = udev_start(); + break; + case ADD: + dbg("udev add"); + namedev_init(); + retval = udev_add_device(devpath, subsystem, NOFAKE); + break; + case REMOVE: + dbg("udev remove"); retval = udev_remove_device(devpath, subsystem); - goto action_done; } - dbg("unknown action '%s'", action); - retval = -EINVAL; - -action_done: udevdb_exit(); exit: return retval; } - -static int udev_hotplug(void) -{ - char *action; - char *devpath; - char *subsystem; - - action = get_action(); - if (!action) { - dbg("no action?"); - return -EINVAL; - } - - devpath = get_devpath(); - if (!devpath) { - dbg("no devpath?"); - return -EINVAL; - } - - /* skip blacklisted subsystems */ - subsystem = get_subsystem(main_argv[1]); - if (!subsystem) { - dbg("no subsystem?"); - return -EINVAL; - } - - return __udev_hotplug(action, devpath, subsystem); -} - -int main(int argc, char *argv[], char *envp[]) -{ - main_argv = argv; - main_envp = envp; - - if (strstr(argv[0], "udevstart")) { - /* Setup env variables. */ - setenv("UDEV_NO_SLEEP", "1", 1); - is_udevstart = 1; - } - - /* initialize our configuration */ - udev_init_config(); - - dbg("version %s", UDEV_VERSION); - - if (is_udevstart) { - namedev_init(); - return udev_start(); - } else - return udev_hotplug(); -} diff --git a/udev.h b/udev.h index 7c5d18a3d0..d049fc1fd0 100644 --- a/udev.h +++ b/udev.h @@ -40,6 +40,9 @@ #define LINE_SIZE 256 +#define FAKE 1 +#define NOFAKE 0 + /* length of public data */ #define UDEVICE_LEN (offsetof(struct udevice, bus_id)) diff --git a/udevstart.c b/udevstart.c index 2d5553e955..cb1c78888c 100644 --- a/udevstart.c +++ b/udevstart.c @@ -70,18 +70,10 @@ static int device_list_insert(char *path, char *subsystem, struct list_head *dev strfieldcpy(new_device->path, path); strfieldcpy(new_device->subsys, subsystem); list_add_tail(&new_device->list, &loop_device->list); + dbg("add '%s' from subsys '%s'", new_device->path, new_device->subsys); return 0; } -static void udev_exec(const char *path, const char* subsystem) -{ - /* Now call __udev_hotplug(). */ - if (__udev_hotplug("add", path, subsystem)) { - dbg("Calling of udev_hotplug failed"); - exit(1); - } -} - /* 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 */ @@ -106,14 +98,14 @@ static void exec_list(struct list_head *device_list) if (found) continue; - udev_exec(loop_device->path, loop_device->subsys); + udev_add_device(loop_device->path, loop_device->subsys, NOFAKE); list_del(&loop_device->list); free(loop_device); } /* handle the rest of the devices left over, if any */ list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { - udev_exec(loop_device->path, loop_device->subsys); + udev_add_device(loop_device->path, loop_device->subsys, NOFAKE); list_del(&loop_device->list); free(loop_device); } @@ -209,19 +201,27 @@ static void udev_scan_class(void) (strcmp(dent2->d_name, "..") == 0)) continue; + /* pass the net class as it is */ + if (strcmp(dent->d_name, "net") == 0) { + snprintf(dirname2, MAX_PATHLEN, "/class/net/%s", dent2->d_name); + device_list_insert(dirname2, "net", &device_list); + continue; + } + snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); dirname2[MAX_PATHLEN-1] = '\0'; - dir3 = opendir(dirname2); if (dir3 != NULL) { for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { char filename[MAX_PATHLEN]; + /* pass devices with a "dev" file */ if (strcmp(dent3->d_name, "dev") == 0) { snprintf(filename, MAX_PATHLEN, "/class/%s/%s", dent->d_name, dent2->d_name); filename[MAX_PATHLEN-1] = '\0'; device_list_insert(filename, dent->d_name, &device_list); + break; } } closedir(dir3); diff --git a/udevtest.c b/udevtest.c index 36f223e1e5..f24c7e4ba5 100644 --- a/udevtest.c +++ b/udevtest.c @@ -102,7 +102,7 @@ int main(int argc, char *argv[], char *envp[]) subsystem = argv[2]; /* simulate node creation with fake flag */ - udev_add_device(devpath, subsystem, fake); + udev_add_device(devpath, subsystem, FAKE); exit: return 0; From 41bc97a0aded14db263b60f7902cc482c28fcfd9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 10 Sep 2004 21:13:18 -0700 Subject: [PATCH 0829/4284] [PATCH] fix compiler warning in udevtest.c --- udevtest.c | 1 - 1 file changed, 1 deletion(-) diff --git a/udevtest.c b/udevtest.c index f24c7e4ba5..df882d2d8c 100644 --- a/udevtest.c +++ b/udevtest.c @@ -58,7 +58,6 @@ int main(int argc, char *argv[], char *envp[]) char *devpath; char temp[NAME_SIZE]; char *subsystem = ""; - const int fake = 1; main_argv = argv; main_envp = envp; From 70f630f64b4fd86af12ecb882c25ca8bce76b90c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 10 Sep 2004 21:44:15 -0700 Subject: [PATCH 0830/4284] [PATCH] add a "first" list to udevstart and make it contain the class/mem/ devices Seems some programs really want /dev/null to work properly :) --- udevstart.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/udevstart.c b/udevstart.c index cb1c78888c..9c1d69503d 100644 --- a/udevstart.c +++ b/udevstart.c @@ -80,15 +80,33 @@ static char *last_list[] = { NULL, }; +/* list of devices that we should run first due to any one of a number of reasons */ +static char *first_list[] = { + "/class/mem", /* people tend to like their memory devices around first... */ + NULL, +}; + 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, list) { + for (i=0; first_list[i] != NULL; i++) { + if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) { + udev_add_device(loop_device->path, loop_device->subsys, NOFAKE); + list_del(&loop_device->list); + 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, list) { int found = 0; - int i; for (i=0; last_list[i] != NULL; i++) { if (strncmp(loop_device->path, last_list[i], strlen(last_list[i])) == 0) { found = 1; From a2383407b3c77f63234c482a2b27b0d45cd4a791 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 10 Sep 2004 21:58:59 -0700 Subject: [PATCH 0831/4284] [PATCH] add symlink for video rule. --- etc/udev/udev.rules.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index f8208d9495..429762b8da 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -94,7 +94,7 @@ KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" # v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n" +KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n" KERNEL="radio[0-9]*", NAME="v4l/radio%n" KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" From 10014f7c9d67b38d10a8a12d1aa79491f5a852bd Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 10 Sep 2004 22:09:58 -0700 Subject: [PATCH 0832/4284] [PATCH] 031 release --- ChangeLog | 47 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6a65376488..701b447828 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,50 @@ +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 + o 030 release TAG: v030 + +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 ============================================ diff --git a/Makefile b/Makefile index 2f1f71090d..c43bbddab6 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 030 +VERSION = 031 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index bdbcb4129e..b751295ed7 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 030 +Version: 031 Release: 1 License: GPL Group: Utilities/System From 29a3cead404d2043a7a3f98d1fb9c7139222b0df Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 14 Sep 2004 06:50:28 -0700 Subject: [PATCH 0833/4284] [PATCH] fix udevstart badly broken in udev 031 On Mon, 2004-09-13 at 01:56 +0200, Marco d'Itri wrote: > Starting from udev 031, the %-arguments passed to PROGRAMs are not > correct when the new udevstart code is being used. > > KERNEL="event[0-9]*", NAME="input/%k", PROGRAM="/etc/udev/inputdev.sh %k %n %M %m", RESULT="inputdev", MODE="0664", GROUP="video" > > generates this log (just echo $*): > > event0 0 13 64 > event0 0 13 64 > event0 0 13 64 > > while the correct log (generated using the old shell script instead of > udevstart) would be: > > event0 0 13 64 > event1 1 13 65 > event2 2 13 66 Yes, I can simulate this, please try the attached patch. I expect, that it fixes it, cause we better not mangle the parsed config while matching the rules. --- namedev.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/namedev.c b/namedev.c index 466016c297..e86f88f433 100644 --- a/namedev.c +++ b/namedev.c @@ -813,10 +813,12 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas /* execute external program */ if (dev->program[0] != '\0') { + char program[PROGRAM_SIZE]; + dbg("check " FIELD_PROGRAM); - apply_format(udev, dev->program, sizeof(dev->program), - class_dev, sysfs_device); - if (execute_program(dev->program, udev->program_result, NAME_SIZE) != 0) { + strfieldcpy(program, dev->program); + apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + if (execute_program(program, udev->program_result, NAME_SIZE) != 0) { dbg(FIELD_PROGRAM " returned nonzero"); goto try_parent; } else { From 6d74f9967b54104895e49c05549121026515fa58 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 14 Sep 2004 06:50:33 -0700 Subject: [PATCH 0834/4284] [PATCH] handle only block and class devices Fix a stupid logic bug, I introduced with the udev.c simplification. We want to look at class and block devices only. --- udev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.c b/udev.c index 114ca0a52b..e6f2744fcb 100644 --- a/udev.c +++ b/udev.c @@ -122,7 +122,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("looking at '%s'", devpath); /* we only care about class devices and block stuff */ - if (strstr(devpath, "class") && strstr(devpath, "block")) { + if (!strstr(devpath, "class") && !strstr(devpath, "block")) { dbg("not a block or class device"); goto exit; } From a75e2c14f9bc098966f39f26358e6de4dc167192 Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Tue, 14 Sep 2004 06:50:38 -0700 Subject: [PATCH 0835/4284] [PATCH] udev parse bug There is a bug parsing PROGRAMs after apostrophes. Try PROGRAM="/bin/echo 'test test". --- namedev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index e86f88f433..c8217024c8 100644 --- a/namedev.c +++ b/namedev.c @@ -433,9 +433,9 @@ static int execute_program(char *path, char *value, int len) /* don't separate if in apostrophes */ pos++; argv[i] = strsep(&pos, "\'"); - while (pos[0] == ' ') + while (pos && pos[0] == ' ') pos++; - } else { + } else { argv[i] = strsep(&pos, " "); } dbg("arg[%i] '%s'", i, argv[i]); From cb5203fb48d2c28f264b175aa560f08d6e368320 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 14 Sep 2004 06:55:08 -0700 Subject: [PATCH 0836/4284] [PATCH] 032 release --- ChangeLog | 11 +++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 701b447828..ab1dfa54d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +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 ============================================ diff --git a/Makefile b/Makefile index c43bbddab6..764618e1b4 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 031 +VERSION = 032 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index b751295ed7..193befca6c 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 031 +Version: 032 Release: 1 License: GPL Group: Utilities/System From 3db7fa27027110fde92a1b6061fab434fe708e9f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 14 Sep 2004 17:45:48 -0700 Subject: [PATCH 0837/4284] [PATCH] fix udev segfaults with bad permissions file On Tue, Sep 14, 2004 at 02:53:12PM +0200, Loleslaw wrote: > Hi, > Since I started using udev-031 on my gentoo udevstart would just segfault > (udev-030 worked). As it turned out I had a file in /etc/udev/permissions.d > with a single space in one line. I've cleaned the file and it works all > right, but I thought you could be interested. > I've traced it to function namedev_init_permissions in namedev_parse.c > I don't know C well enough to suggest a patch. Yeah, thanks for pointing that out. It only happens if the file ends with whitespace-only lines. Here is a fix and a test for udev-test.pl to cover that case. --- namedev_parse.c | 16 ++++++---------- test/udev-test.pl | 16 ++++++++++++++++ udev_config.c | 8 +++----- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 4bb1a97ce9..7e37833202 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -182,15 +182,13 @@ static int namedev_parse_rules(char *filename) continue; } - /* empty line? */ - if (bufline[0] == '\0' || bufline[0] == '\n') - continue; - /* eat the whitespace */ - while (isspace(bufline[0])) { + while ((count > 0) && isspace(bufline[0])) { bufline++; count--; } + if (count == 0) + continue; /* see if this is a comment */ if (bufline[0] == COMMENT_CHARACTER) @@ -381,15 +379,13 @@ static int namedev_parse_permissions(char *filename) continue; } - /* empty line? */ - if (bufline[0] == '\0' || bufline[0] == '\n') - continue; - /* eat the whitespace */ - while (isspace(bufline[0])) { + while ((count > 0) && isspace(bufline[0])) { bufline++; count--; } + if (count == 0) + continue; /* see if this is a comment */ if (bufline[0] == COMMENT_CHARACTER) diff --git a/test/udev-test.pl b/test/udev-test.pl index 1e7c51e556..9feb28a7ba 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -158,6 +158,22 @@ EOF # this is a comment with whitespace before the comment KERNEL="ttyUSB0", NAME="visor" +EOF + }, + { + desc => "Handle whitespace only lines (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "whitespace" , + conf => < 0) && isspace(bufline[0])) { bufline++; count--; } + if (count == 0) + continue; /* see if this is a comment */ if (bufline[0] == COMMENT_CHARACTER) From 0345b8623581497f49184ffd1d8143fe20f71893 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 14 Sep 2004 21:44:55 -0700 Subject: [PATCH 0838/4284] [PATCH] add enum tests On Fri, Sep 10, 2004 at 01:09:07PM -0700, Greg KH wrote: > On Tue, Sep 07, 2004 at 01:19:34PM +0200, David Zeuthen wrote: > > > > KERNEL="sr*", NAME="%k", SYMLINK="cdrom%e" > > KERNEL="scd*", NAME="%k", SYMLINK="cdrom%e" > > KERNEL="pcd*", NAME="%k", SYMLINK="cdrom%e" > > KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="\%k", SYMLINK="cdrom%e" > > KERNEL="fd[0-9]", NAME="%k", SYMLINK="floppy%e" > > KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy", NAME=\"%k", SYMLINK="floppy%e" > > > > New patch is attached. > > Nice, I've applied this. > > How about sending a patch for the test/udev-test.pl script that adds a > test for this new paramater, so we make sure to not break it in the > future. Here are the tests for the enumeration character %e. I've added a option string to be able to do a whole sequence of tests without node removal, so we can skip the "remove" event and get an increasing number to append to the name. After the sequence test the whole directory is cleaned for the next tests. --- test/udev-test.pl | 89 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 9feb28a7ba..590b551dfe 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1015,6 +1015,74 @@ EOF exp_target => "node", conf => < "enumeration char test (single test)", + subsys => "block", + devpath => "/block/sda", + exp_name => "cdrom", + conf => < "enumeration char test sequence (1/5 keep)", + subsys => "block", + devpath => "/block/sda", + exp_name => "cdrom", + option => "keep", + conf => < "enumeration char test sequence 2/5 (keep)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "enum", + option => "keep", + conf => < "enumeration char test sequence 3/5 (keep)", + subsys => "block", + devpath => "/block/sda/sda2", + exp_name => "cdrom1", + option => "keep", + conf => < "enumeration char test sequence 4/5 (keep)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "enum1", + option => "keep", + conf => < "enumeration char test sequence 5/5 (clean)", + subsys => "block", + devpath => "/block/sda/sda4", + exp_name => "cdrom2", + option => "clear", + conf => < "enumeration char test after cleanup (single test)", + subsys => "block", + devpath => "/block/sda", + exp_name => "cdrom", + conf => <{option}) && $config->{option} eq "keep") { + print "\n\n"; + return; + } + udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf}); if ((-e "$PWD/$udev_root$config->{exp_name}") || (-l "$PWD/$udev_root$config->{exp_name}")) { @@ -1175,6 +1248,13 @@ sub run_test { } else { print "remove: ok\n\n"; } + + if (defined($config->{option}) && $config->{option} eq "clear") { + unlink($udev_db); + system("rm -rf $udev_root"); + mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; + } + } # prepare @@ -1194,9 +1274,13 @@ my $test_num = 1; if ($ARGV[0]) { # only run one test $test_num = $ARGV[0]; - print "udev-test will run test number $test_num only\n"; - run_test($tests[$test_num-1], $test_num); + 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"; @@ -1204,7 +1288,6 @@ if ($ARGV[0]) { foreach my $config (@tests) { run_test($config, $test_num); $test_num++; - } } From cdc60e8afb06a0688e4b9f166625d4d0b8805e68 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 15 Sep 2004 22:36:31 -0700 Subject: [PATCH 0839/4284] [PATCH] switch udev's seqnum to u64 The kernel will use a u64 for the sequence number, so we want the same. --- udev.h | 4 +--- udev_lib.h | 6 ------ udevd.c | 35 +++++++++++++++++------------------ udevd.h | 2 +- udevsend.c | 26 ++++++++++---------------- 5 files changed, 29 insertions(+), 44 deletions(-) diff --git a/udev.h b/udev.h index d049fc1fd0..46c961c2d5 100644 --- a/udev.h +++ b/udev.h @@ -43,7 +43,7 @@ #define FAKE 1 #define NOFAKE 0 -/* length of public data */ +/* length of public data to store in udevdb */ #define UDEVICE_LEN (offsetof(struct udevice, bus_id)) struct udevice { @@ -71,8 +71,6 @@ extern int udev_add_device(const char *path, const char *subsystem, int fake); extern int udev_remove_device(const char *path, const char *subsystem); extern void udev_init_config(void); extern int udev_start(void); -extern int __udev_hotplug(char *action, const char *devpath, - const char *subsystem); extern int parse_get_pair(char **orig_string, char **left, char **right); extern void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath); diff --git a/udev_lib.h b/udev_lib.h index 53ad92d505..18ce25ccc7 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -59,12 +59,6 @@ do { \ snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ } while (0) -#define strlongcat(to, i) \ -do { \ - to[sizeof(to)-1] = '\0'; \ - snprintf((to) + strlen(to), sizeof(to) - strlen(to)-1, "%li", i); \ -} while (0) - #define foreach_strpart(str, separator, pos, len) \ for(pos = str, len = 0; \ (pos) < ((str) + strlen(str)); \ diff --git a/udevd.c b/udevd.c index 50720c2450..88131d63ab 100644 --- a/udevd.c +++ b/udevd.c @@ -44,7 +44,7 @@ #include "logging.h" static int pipefds[2]; -static long expected_seqnum = 0; +static unsigned long long expected_seqnum = 0; volatile static int children_waiting; volatile static int run_msg_q; volatile static int sig_flag; @@ -73,7 +73,7 @@ void log_message (int level, const char *format, ...) #endif #define msg_dump(msg) \ - dbg("msg_dump: sequence %d, '%s', '%s', '%s'", \ + dbg("msg_dump: sequence %llu, '%s', '%s', '%s'", \ msg->seqnum, msg->action, msg->devpath, msg->subsystem); static void msg_dump_queue(void) @@ -82,7 +82,7 @@ static void msg_dump_queue(void) struct hotplug_msg *msg; list_for_each_entry(msg, &msg_list, list) - dbg("sequence %li in queue", msg->seqnum); + dbg("sequence %llu in queue", msg->seqnum); #endif } @@ -120,7 +120,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) msg->queue_time = info.uptime; list_add(&msg->list, &loop_msg->list); - dbg("queued message seq %li", msg->seqnum); + dbg("queued message seq %llu", msg->seqnum); /* run msg queue manager */ run_msg_q = 1; @@ -137,12 +137,11 @@ static void udev_run(struct hotplug_msg *msg) char seqnum[SEQNUM_SIZE]; char *env[] = { action, devpath, seqnum, NULL }; - strcpy(action, "ACTION="); - strfieldcat(action, msg->action); - strcpy(devpath, "DEVPATH="); - strfieldcat(devpath, msg->devpath); - strcpy(seqnum, "SEQNUM="); - strlongcat(seqnum, msg->seqnum); + snprintf(action, ACTION_SIZE-1, "ACTION=%s", msg->action); + action[ACTION_SIZE-1] = '\0'; + snprintf(devpath, DEVPATH_SIZE-1, "DEVPATH=%s", msg->devpath); + devpath[DEVPATH_SIZE-1] = '\0'; + sprintf(seqnum, "SEQNUM=%llu", msg->seqnum); pid = fork(); switch (pid) { @@ -161,7 +160,7 @@ static void udev_run(struct hotplug_msg *msg) break; default: /* get SIGCHLD in main loop */ - dbg("==> exec seq %li [%d] working at '%s'", msg->seqnum, pid, msg->devpath); + dbg("==> exec seq %llu [%d] working at '%s'", msg->seqnum, pid, msg->devpath); msg->pid = pid; } } @@ -189,9 +188,9 @@ static void exec_queue_manager() /* move event to run list */ list_move_tail(&loop_msg->list, &running_list); udev_run(loop_msg); - dbg("moved seq %li to running list", loop_msg->seqnum); + dbg("moved seq %llu to running list", loop_msg->seqnum); } else { - dbg("delay seq %li, cause seq %li already working on '%s'", + dbg("delay seq %llu, cause seq %llu already working on '%s'", loop_msg->seqnum, msg->seqnum, msg->devpath); } } @@ -202,7 +201,7 @@ static void msg_move_exec(struct hotplug_msg *msg) list_move_tail(&msg->list, &exec_list); run_exec_q = 1; expected_seqnum = msg->seqnum+1; - dbg("moved seq %li to exec, next expected is %li", + dbg("moved seq %llu to exec, next expected is %llu", msg->seqnum, expected_seqnum); } @@ -214,7 +213,7 @@ static void msg_queue_manager() struct sysinfo info; long msg_age = 0; - dbg("msg queue manager, next expected is %li", expected_seqnum); + dbg("msg queue manager, next expected is %llu", expected_seqnum); recheck: list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, list) { /* move event with expected sequence to the exec list */ @@ -226,7 +225,7 @@ recheck: /* move event with expired timeout to the exec list */ sysinfo(&info); msg_age = info.uptime - loop_msg->queue_time; - dbg("seq %li is %li seconds old", loop_msg->seqnum, msg_age); + dbg("seq %llu is %li seconds old", loop_msg->seqnum, msg_age); if (msg_age > EVENT_TIMEOUT_SEC-1) { msg_move_exec(loop_msg); goto recheck; @@ -296,7 +295,7 @@ static void handle_msg(int sock) } /* if no seqnum is given, we move straight to exec queue */ - if (msg->seqnum == -1) { + if (msg->seqnum == 0) { list_add(&msg->list, &exec_list); run_exec_q = 1; } else { @@ -353,7 +352,7 @@ static void udev_done(int pid) list_for_each_entry(msg, &running_list, list) { if (msg->pid == pid) { - dbg("<== exec seq %li came back", msg->seqnum); + dbg("<== exec seq %llu came back", msg->seqnum); run_queue_delete(msg); /* we want to run the exec queue manager since there may diff --git a/udevd.h b/udevd.h index cced75d5f6..9be581d420 100644 --- a/udevd.h +++ b/udevd.h @@ -33,7 +33,7 @@ struct hotplug_msg { char magic[20]; struct list_head list; pid_t pid; - long seqnum; + unsigned long long seqnum; long queue_time; char action[ACTION_SIZE]; char devpath[DEVPATH_SIZE]; diff --git a/udevsend.c b/udevsend.c index a52d6ec165..842a2a4bc4 100644 --- a/udevsend.c +++ b/udevsend.c @@ -53,17 +53,6 @@ void log_message (int level, const char *format, ...) } #endif -static void build_hotplugmsg(struct hotplug_msg *msg, char *action, - char *devpath, char *subsystem, int seqnum) -{ - memset(msg, 0x00, sizeof(struct hotplug_msg)); - strfieldcpy(msg->magic, UDEV_MAGIC); - msg->seqnum = seqnum; - strfieldcpy(msg->action, action); - strfieldcpy(msg->devpath, devpath); - strfieldcpy(msg->subsystem, subsystem); -} - static int start_daemon(void) { pid_t pid; @@ -125,7 +114,7 @@ int main(int argc, char* argv[]) char *devpath; char *subsystem; char *seqnum; - int seq; + unsigned long long seq; int retval = 1; int loop; struct timespec tspec; @@ -160,10 +149,10 @@ int main(int argc, char* argv[]) seqnum = get_seqnum(); if (seqnum == NULL) - seq = -1; + seq = 0; else - seq = atoi(seqnum); - dbg("SEQNUM = '%d'", seq); + seq = strtoull(seqnum, NULL, 10); + dbg("SEQNUM = '%llu'", seq); sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { @@ -177,7 +166,12 @@ int main(int argc, char* argv[]) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - build_hotplugmsg(&msg, action, devpath, subsystem, seq); + memset(&msg, 0x00, sizeof(struct hotplug_msg)); + strcpy(msg.magic, UDEV_MAGIC); + msg.seqnum = seq; + strfieldcpy(msg.action, action); + strfieldcpy(msg.devpath, devpath); + strfieldcpy(msg.subsystem, subsystem); /* If we can't send, try to start daemon and resend message */ loop = UDEVSEND_CONNECT_RETRY; From 9e8a3a095d955538acbdf28dba02582f6b2330e5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Sep 2004 23:22:27 -0700 Subject: [PATCH 0840/4284] [PATCH] volume-id build fix and update Let's try it another way: We define BLKGETSIZE64 in udev-volume_id.c now, cause including does also not work with klibc. This hopefully fixes your compile problem too. Also included is an update to udev_volume_id with the latest fixes for volume_id. It adds a simple logging file to map the debug function, that we can use exactly the same files in HAL and udev. --- extras/volume_id/udev_volume_id.c | 17 +- extras/volume_id/volume_id.c | 297 +++++++++++++++++---------- extras/volume_id/volume_id.h | 2 +- extras/volume_id/volume_id_logging.h | 21 ++ 4 files changed, 212 insertions(+), 125 deletions(-) create mode 100644 extras/volume_id/volume_id_logging.h diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index e88445054b..6b62db0775 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include #include #include "../../libsysfs/sysfs/libsysfs.h" @@ -34,6 +34,8 @@ #include "volume_id.h" #include "dasdlabel.h" +#define BLKGETSIZE64 _IOR(0x12,114,size_t) + #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) @@ -73,16 +75,6 @@ static struct volume_id *open_classdev(struct sysfs_class_device *class_dev) return vid; } -static unsigned long long get_size(struct volume_id *vid) -{ - unsigned long long size; - - if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) - size = 0; - - return size; -} - static char *usage_id_name(enum volume_id_usage usage) { switch(usage) { @@ -181,7 +173,8 @@ int main(int argc, char *argv[]) if (vid == NULL) goto exit; - size = get_size(vid); + if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) + size = 0; if (volume_id_probe(vid, VOLUME_ID_ALL, 0, size) == 0) goto print; diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index daeb00038a..99aed6c96b 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -24,17 +24,17 @@ */ #ifndef _GNU_SOURCE -#define _GNU_SOURCE +#define _GNU_SOURCE 1 #endif #ifdef HAVE_CONFIG_H # include #endif -#include #include -#include +#include #include +#include #include #include #include @@ -42,32 +42,24 @@ #include #include "volume_id.h" - -#ifdef DEBUG -#define dbg(format, arg...) \ - do { \ - printf("%s: " format "\n", __FUNCTION__ , ## arg); \ - } while (0) -#else -#define dbg(format, arg...) do {} while (0) -#endif /* DEBUG */ +#include "volume_id_logging.h" #define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \ - (((__u32)(x) & 0xff00u) >> 8)) + (((__u16)(x) & 0xff00u) >> 8)) #define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \ (((__u32)(x) & 0x00ff0000u) >> 8) | \ (((__u32)(x) & 0x0000ff00u) << 8) | \ (((__u32)(x) & 0x000000ffu) << 24)) -#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000u) >> 56) | \ - (((__u64)(x) & 0x00ff000000000000u) >> 40) | \ - (((__u64)(x) & 0x0000ff0000000000u) >> 24) | \ - (((__u64)(x) & 0x000000ff00000000u) >> 8) | \ - (((__u64)(x) & 0x00000000ff000000u) << 8) | \ - (((__u64)(x) & 0x0000000000ff0000u) << 24) | \ - (((__u64)(x) & 0x000000000000ff00u) << 40) | \ - (((__u64)(x) & 0x00000000000000ffu) << 56)) +#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000ull) >> 56) | \ + (((__u64)(x) & 0x00ff000000000000ull) >> 40) | \ + (((__u64)(x) & 0x0000ff0000000000ull) >> 24) | \ + (((__u64)(x) & 0x000000ff00000000ull) >> 8) | \ + (((__u64)(x) & 0x00000000ff000000ull) << 8) | \ + (((__u64)(x) & 0x0000000000ff0000ull) << 24) | \ + (((__u64)(x) & 0x000000000000ff00ull) << 40) | \ + (((__u64)(x) & 0x00000000000000ffull) << 56)) #if (__BYTE_ORDER == __LITTLE_ENDIAN) #define le16_to_cpu(x) (x) @@ -144,34 +136,56 @@ static void set_label_unicode16(struct volume_id *id, } } -static void set_uuid(struct volume_id *id, - const __u8 *buf, unsigned int count) +enum uuid_format { + UUID_DCE, + UUID_DOS, + UUID_NTFS, + UUID_HFS, +}; + +static void set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format) { unsigned int i; + unsigned int count = 0; + switch(format) { + case UUID_DOS: + count = 4; + break; + case UUID_NTFS: + case UUID_HFS: + count = 8; + break; + case UUID_DCE: + count = 16; + } memcpy(id->uuid_raw, buf, count); - /* create string if uuid is set */ + /* 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(count) { - case 4: + switch(format) { + case UUID_DOS: sprintf(id->uuid, "%02X%02X-%02X%02X", buf[3], buf[2], buf[1], buf[0]); break; - case 8: - sprintf(id->uuid,"%02X%02X-%02X%02X-%02X%02X-%02X%02X", + case UUID_NTFS: + 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 16: + case UUID_HFS: + 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", + "%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], @@ -337,12 +351,13 @@ static int probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) } __attribute__((packed)) *mdp; const __u8 *buf; - __u64 sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; + __u64 sboff; __u8 uuid[16]; if (size < 0x10000) return -1; + sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; buf = get_buffer(id, off + sboff, 0x800); if (buf == NULL) return -1; @@ -354,7 +369,7 @@ static int probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) memcpy(uuid, &mdp->set_uuid0, 4); memcpy(&uuid[4], &mdp->set_uuid1, 12); - set_uuid(id, uuid, 16); + set_uuid(id, uuid, UUID_DCE); snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u", le32_to_cpu(mdp->major_version), @@ -572,7 +587,7 @@ static int probe_ext(struct volume_id *id, __u64 off) set_label_raw(id, es->volume_name, 16); set_label_string(id, es->volume_name, 16); - set_uuid(id, es->uuid, 16); + set_uuid(id, es->uuid, UUID_DCE); if ((le32_to_cpu(es->feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { @@ -638,7 +653,7 @@ static int probe_reiserfs(struct volume_id *id, __u64 off) found: set_label_raw(id, rs->label, 16); set_label_string(id, rs->label, 16); - set_uuid(id, rs->uuid, 16); + set_uuid(id, rs->uuid, UUID_DCE); id->usage_id = VOLUME_ID_FILESYSTEM; id->type_id = VOLUME_ID_REISERFS; @@ -673,7 +688,7 @@ static int probe_xfs(struct volume_id *id, __u64 off) set_label_raw(id, xs->fname, 12); set_label_string(id, xs->fname, 12); - set_uuid(id, xs->uuid, 16); + set_uuid(id, xs->uuid, UUID_DCE); id->usage_id = VOLUME_ID_FILESYSTEM; id->type_id = VOLUME_ID_XFS; @@ -708,7 +723,7 @@ static int probe_jfs(struct volume_id *id, __u64 off) set_label_raw(id, js->label, 16); set_label_string(id, js->label, 16); - set_uuid(id, js->uuid, 16); + set_uuid(id, js->uuid, UUID_DCE); id->usage_id = VOLUME_ID_FILESYSTEM; id->type_id = VOLUME_ID_JFS; @@ -720,52 +735,6 @@ static int probe_jfs(struct volume_id *id, __u64 off) #define FAT12_MAX 0xff5 #define FAT16_MAX 0xfff5 #define FAT_ATTR_VOLUME 0x08 -struct vfat_dir_entry { - __u8 name[11]; - __u8 attr; - __u16 time_creat; - __u16 date_creat; - __u16 time_acc; - __u16 date_acc; - __u16 cluster_high; - __u16 time_write; - __u16 date_write; - __u16 cluster_low; - __u32 size; -} __attribute__((__packed__)); - -static char *vfat_search_label_in_dir(const __u8 *buf, __u16 size) -{ - struct vfat_dir_entry *dir; - int i; - __u16 count; - - dir = (struct vfat_dir_entry*) buf; - count = size / sizeof(struct vfat_dir_entry); - dbg("expected entries 0x%x", count); - - for (i = 0; i <= count; i++) { - /* end marker */ - if (dir[i].attr == 0x00) { - dbg("end of dir"); - return NULL; - } - - /* empty entry */ - if (dir[i].attr == 0xe5) - continue; - - if (dir[i].attr == FAT_ATTR_VOLUME) { - dbg("found ATTR_VOLUME id in root dir"); - return dir[i].name; - } - - dbg("skip dir entry"); - } - - return NULL; -} - static int probe_vfat(struct volume_id *id, __u64 off) { struct vfat_super_block { @@ -810,6 +779,20 @@ static int probe_vfat(struct volume_id *id, __u64 off) } __attribute__((__packed__)) type; } __attribute__((__packed__)) *vs; + struct vfat_dir_entry { + __u8 name[11]; + __u8 attr; + __u16 time_creat; + __u16 date_creat; + __u16 time_acc; + __u16 date_acc; + __u16 cluster_high; + __u16 time_write; + __u16 date_write; + __u16 cluster_low; + __u32 size; + } __attribute__((__packed__)) *dir; + __u16 sector_size; __u16 dir_entries; __u32 sect_count; @@ -826,6 +809,8 @@ static int probe_vfat(struct volume_id *id, __u64 off) __u32 buf_size; __u8 *label = NULL; __u32 next; + int maxloop; + int i; vs = (struct vfat_super_block *) get_buffer(id, off, 0x200); if (vs == NULL) @@ -892,7 +877,7 @@ valid: sect_count = le16_to_cpu(vs->sectors); if (sect_count == 0) - sect_count = vs->total_sect; + sect_count = le32_to_cpu(vs->total_sect); dbg("sect_count 0x%x", sect_count); fat_length = le16_to_cpu(vs->fat_length); @@ -920,15 +905,35 @@ valid: /* the label may be an attribute in the root directory */ root_start = (reserved + fat_size) * sector_size; + dbg("root dir start 0x%llx", root_start); root_dir_entries = le16_to_cpu(vs->dir_entries); - dbg("root dir start 0x%x", root_start); + dbg("expected entries 0x%x", root_dir_entries); buf_size = root_dir_entries * sizeof(struct vfat_dir_entry); buf = get_buffer(id, off + root_start, buf_size); if (buf == NULL) goto found; - label = vfat_search_label_in_dir(buf, buf_size); + dir = (struct vfat_dir_entry*) buf; + + for (i = 0; i <= root_dir_entries; i++) { + /* end marker */ + if (dir[i].attr == 0x00) { + dbg("end of dir"); + break; + } + + /* empty entry */ + if (dir[i].attr == 0xe5) + continue; + + if (dir[i].attr == FAT_ATTR_VOLUME) { + dbg("found ATTR_VOLUME id in root dir"); + label = dir[i].name; + } + + dbg("skip dir entry"); + } if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { set_label_raw(id, label, 11); @@ -937,7 +942,7 @@ valid: set_label_raw(id, vs->type.fat.label, 11); set_label_string(id, vs->type.fat.label, 11); } - set_uuid(id, vs->type.fat.serno, 4); + set_uuid(id, vs->type.fat.serno, UUID_DOS); goto found; fat32: @@ -948,24 +953,46 @@ fat32: start_data_sect = reserved + fat_size; next = root_cluster; - while (1) { + maxloop = 100; + while (--maxloop) { __u32 next_sect_off; __u64 next_off; __u64 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%x", next_off); + dbg("cluster offset 0x%llx", next_off); /* get cluster */ buf = get_buffer(id, off + next_off, buf_size); if (buf == NULL) goto found; - label = vfat_search_label_in_dir(buf, buf_size); - if (label != NULL) - break; + dir = (struct vfat_dir_entry*) buf; + count = buf_size / sizeof(struct vfat_dir_entry); + dbg("expected entries 0x%x", count); + + for (i = 0; i <= count; i++) { + /* end marker */ + if (dir[i].attr == 0x00) { + dbg("end of dir"); + goto fat32_label; + } + + /* empty entry */ + if (dir[i].attr == 0xe5) + continue; + + if (dir[i].attr == FAT_ATTR_VOLUME) { + dbg("found ATTR_VOLUME id in root dir"); + label = dir[i].name; + goto fat32_label; + } + + dbg("skip dir entry"); + } /* get FAT entry */ fat_entry_off = (reserved * sector_size) + (next * sizeof(__u32)); @@ -978,7 +1005,10 @@ fat32: if (next == 0) break; } + if (maxloop == 0) + dbg("reached maximum follow count of root cluster chain, give up"); +fat32_label: if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { set_label_raw(id, label, 11); set_label_string(id, label, 11); @@ -986,7 +1016,7 @@ fat32: set_label_raw(id, vs->type.fat32.label, 11); set_label_string(id, vs->type.fat32.label, 11); } - set_uuid(id, vs->type.fat32.serno, 4); + set_uuid(id, vs->type.fat32.serno, UUID_DCE); found: id->usage_id = VOLUME_ID_FILESYSTEM; @@ -1479,9 +1509,10 @@ static int probe_mac_partition_map(struct volume_id *id, __u64 off) #define HFS_SUPERBLOCK_OFFSET 0x400 #define HFS_NODE_LEAF 0xff #define HFSPLUS_POR_CNID 1 +#define HFSPLUS_EXTENT_COUNT 8 static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) { - struct finder_info { + struct hfs_finder_info{ __u32 boot_folder; __u32 start_app; __u32 open_folder; @@ -1515,7 +1546,7 @@ static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) __u16 num_root_dirs; __u32 file_count; __u32 dir_count; - struct finder_info finfo; + struct hfs_finder_info finder_info; __u8 embed_sig[2]; __u16 embed_startblock; __u16 embed_blockcount; @@ -1555,7 +1586,7 @@ static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) __u64 total_size; __u32 clump_size; __u32 total_blocks; - struct hfsplus_extent extents[8]; + struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; } __attribute__((__packed__)); struct hfsplus_vol_header { @@ -1579,7 +1610,7 @@ static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) __u32 next_cnid; __u32 write_count; __u64 encodings_bmp; - struct finder_info finfo; + struct hfs_finder_info finder_info; struct hfsplus_fork alloc_file; struct hfsplus_fork ext_file; struct hfsplus_fork cat_file; @@ -1589,18 +1620,23 @@ static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) unsigned int blocksize; unsigned int cat_block; - unsigned int cat_block_count; - unsigned int cat_off; - unsigned int cat_len; + 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; + __u64 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 __u8 *buf; buf = get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); @@ -1637,6 +1673,8 @@ static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) set_label_string(id, hfs->label, hfs->label_len) ; } + set_uuid(id, hfs->finder_info.id, UUID_HFS); + id->usage_id = VOLUME_ID_FILESYSTEM; id->type_id = VOLUME_ID_HFS; id->type = "hfs"; @@ -1652,14 +1690,16 @@ checkplus: return -1; hfsplus: - blocksize = be32_to_cpu(hfsplus->blocksize); - cat_block = be32_to_cpu(hfsplus->cat_file.extents[0].start_block); - cat_block_count = be32_to_cpu(hfsplus->cat_file.extents[0].block_count); - cat_off = (cat_block * blocksize); - cat_len = cat_block_count * blocksize; - dbg("catalog start 0x%llx, len 0x%x", off + cat_off, cat_len); + set_uuid(id, hfsplus->finder_info.id, UUID_HFS); - buf = get_buffer(id, off + cat_off, 0x2000); + 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 = get_buffer(id, off + (cat_block * blocksize), 0x2000); if (buf == NULL) goto found; @@ -1667,18 +1707,51 @@ hfsplus: &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); - dbg("catalog leaf node 0x%x, size 0x%x", - leaf_node_head, 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; - buf = get_buffer(id, off + cat_off + (leaf_node_head * leaf_node_size), - leaf_node_size); + 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 = 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; @@ -1787,7 +1860,7 @@ static int probe_ntfs(struct volume_id *id, __u64 off) if (strncmp(ns->oem_id, "NTFS", 4) != 0) return -1; - set_uuid(id, ns->volume_serial, 8); + set_uuid(id, ns->volume_serial, UUID_NTFS); sector_size = le16_to_cpu(ns->bytes_per_sector); cluster_size = ns->sectors_per_cluster * sector_size; diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index eb90390617..e68c42c3cf 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 022 +#define VOLUME_ID_VERSION 024 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 diff --git a/extras/volume_id/volume_id_logging.h b/extras/volume_id/volume_id_logging.h new file mode 100644 index 0000000000..e978ce197c --- /dev/null +++ b/extras/volume_id/volume_id_logging.h @@ -0,0 +1,21 @@ +/* + * volume_id_logging - this file is used to map the dbg() function + * to the host logging facility + * + */ + +#ifndef _VOLUME_ID_LOGGING_H_ +#define _VOLUME_ID_LOGGING_H_ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +/* just use the udev version*/ +#include "../../logging.h" + +#endif /* _VOLUME_ID_LOGGING_H_ */ From a0622777688ad84ef3d789e0171cfb0ca3dc21d2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Oct 2004 18:32:12 -0700 Subject: [PATCH 0841/4284] [PATCH] update klibc to version 0.181 --- klibc/MCONFIG | 33 +- klibc/Makefile | 2 +- klibc/README | 3 +- klibc/klibc.spec | 157 ++++++ klibc/klibc.spec.in | 48 +- klibc/klibc/MCONFIG | 5 + klibc/klibc/Makefile | 70 ++- klibc/klibc/README | 44 +- klibc/klibc/SOCKETCALLS | 21 - klibc/klibc/SOCKETCALLS.def | 21 + klibc/klibc/SYSCALLS | 153 ------ klibc/klibc/SYSCALLS.def | 207 ++++++++ klibc/klibc/__shared_init.c | 58 +-- klibc/klibc/__static_init.c | 40 +- klibc/klibc/alarm.c | 6 +- klibc/klibc/arch/alpha/Makefile.inc | 6 +- klibc/klibc/arch/alpha/crt0.S | 11 +- .../arch/alpha/include/klibc/archsetjmp.h | 33 -- .../arch/alpha/include/klibc/archsignal.h | 13 - .../klibc/arch/alpha/include/klibc/archsys.h | 53 -- klibc/klibc/arch/alpha/include/machine/asm.h | 44 -- klibc/klibc/arch/alpha/setjmp.S | 32 +- klibc/klibc/arch/alpha/syscall.S | 26 + klibc/klibc/arch/alpha/sysdual.S | 33 ++ klibc/klibc/arch/alpha/sysstub.ph | 37 ++ klibc/klibc/arch/arm/Makefile.inc | 14 +- klibc/klibc/arch/arm/crt0.S | 6 +- .../klibc/arch/arm/include/klibc/archsetjmp.h | 14 - .../klibc/arch/arm/include/klibc/archsignal.h | 13 - klibc/klibc/arch/arm/include/klibc/archsys.h | 12 - klibc/klibc/arch/arm/setjmp-arm.S | 3 +- klibc/klibc/arch/arm/syscall.S | 50 ++ klibc/klibc/arch/arm/sysstub.ph | 44 ++ klibc/klibc/arch/cris/MCONFIG | 15 + klibc/klibc/arch/cris/Makefile.inc | 23 + klibc/klibc/arch/cris/__negdi2.S | 25 + klibc/klibc/arch/cris/crt0.S | 28 ++ klibc/klibc/arch/cris/divide.c | 92 ++++ .../arch/cris/include/klibc/archsignal.h | 13 - klibc/klibc/arch/cris/include/klibc/archsys.h | 12 - klibc/klibc/arch/cris/setjmp.S | 37 ++ klibc/klibc/arch/cris/syscall.S | 30 ++ klibc/klibc/arch/cris/sysstub.ph | 29 ++ klibc/klibc/arch/i386/MCONFIG | 6 +- klibc/klibc/arch/i386/Makefile.inc | 4 +- .../arch/i386/include/klibc/archsetjmp.h | 19 - .../arch/i386/include/klibc/archsignal.h | 13 - klibc/klibc/arch/i386/include/klibc/archsys.h | 96 ---- klibc/klibc/arch/i386/include/klibc/diverr.h | 16 - klibc/klibc/arch/i386/include/sys/io.h | 126 ----- klibc/klibc/arch/i386/include/sys/vm86.h | 41 -- klibc/klibc/arch/i386/open.S | 29 ++ klibc/klibc/arch/i386/socketcall.S | 28 +- klibc/klibc/arch/i386/syscall.S | 60 +++ klibc/klibc/arch/i386/sysstub.ph | 32 ++ klibc/klibc/arch/ia64/Makefile.inc | 1 + .../arch/ia64/include/klibc/archsetjmp.h | 17 - .../arch/ia64/include/klibc/archsignal.h | 31 -- klibc/klibc/arch/ia64/include/klibc/archsys.h | 218 --------- klibc/klibc/arch/ia64/pipe.c | 2 +- klibc/klibc/arch/ia64/syscall.S | 20 + klibc/klibc/arch/ia64/sysstub.ph | 29 ++ klibc/klibc/arch/ia64/vfork.S | 4 +- .../arch/m68k/include/klibc/archsignal.h | 13 - klibc/klibc/arch/m68k/include/klibc/archsys.h | 12 - klibc/klibc/arch/mips/MCONFIG | 7 +- klibc/klibc/arch/mips/Makefile.inc | 1 + .../arch/mips/include/klibc/archsetjmp.h | 39 -- .../arch/mips/include/klibc/archsignal.h | 13 - klibc/klibc/arch/mips/include/klibc/archsys.h | 12 - klibc/klibc/arch/mips/include/machine/asm.h | 11 - klibc/klibc/arch/mips/include/sgidefs.h | 20 - klibc/klibc/arch/mips/klibc.ld | 217 +++++++++ klibc/klibc/arch/mips/syscall.S | 15 + klibc/klibc/arch/mips/sysstub.ph | 30 ++ klibc/klibc/arch/mips/vfork.S | 11 +- .../arch/mips64/include/klibc/archsignal.h | 13 - .../klibc/arch/mips64/include/klibc/archsys.h | 12 - klibc/klibc/arch/parisc/Makefile.inc | 6 +- .../arch/parisc/include/klibc/archsignal.h | 24 - .../klibc/arch/parisc/include/klibc/archsys.h | 12 - klibc/klibc/arch/parisc/syscall.c | 29 ++ klibc/klibc/arch/parisc/sysstub.ph | 29 ++ klibc/klibc/arch/ppc/MCONFIG | 7 + klibc/klibc/arch/ppc/Makefile.inc | 1 + .../klibc/arch/ppc/include/klibc/archsetjmp.h | 36 -- .../klibc/arch/ppc/include/klibc/archsignal.h | 13 - klibc/klibc/arch/ppc/include/klibc/archsys.h | 61 --- klibc/klibc/arch/ppc/syscall.S | 16 + klibc/klibc/arch/ppc/sysstub.ph | 25 + klibc/klibc/arch/ppc64/MCONFIG | 7 + klibc/klibc/arch/ppc64/Makefile.inc | 12 +- .../arch/ppc64/include/klibc/archsetjmp.h | 36 -- .../arch/ppc64/include/klibc/archsignal.h | 13 - .../klibc/arch/ppc64/include/klibc/archsys.h | 52 -- klibc/klibc/arch/ppc64/setjmp.S | 69 ++- klibc/klibc/arch/ppc64/syscall.c | 14 + klibc/klibc/arch/ppc64/sysstub.ph | 34 ++ klibc/klibc/arch/s390/Makefile.inc | 2 + .../arch/s390/include/klibc/archsetjmp.h | 15 - .../arch/s390/include/klibc/archsignal.h | 13 - klibc/klibc/arch/s390/include/klibc/archsys.h | 41 -- klibc/klibc/arch/s390/mmap.c | 41 ++ klibc/klibc/arch/s390/syscall.c | 16 + klibc/klibc/arch/s390/sysstub.ph | 31 ++ klibc/klibc/arch/s390x/Makefile.inc | 4 +- .../arch/s390x/include/klibc/archsetjmp.h | 15 - .../arch/s390x/include/klibc/archsignal.h | 13 - .../klibc/arch/s390x/include/klibc/archsys.h | 41 -- klibc/klibc/arch/s390x/mmap.c | 41 ++ klibc/klibc/arch/s390x/syscall.c | 16 + klibc/klibc/arch/s390x/sysstub.ph | 28 ++ klibc/klibc/arch/sh/Makefile.inc | 3 +- klibc/klibc/arch/sh/crt0.S | 11 +- .../klibc/arch/sh/include/klibc/archsetjmp.h | 22 - .../klibc/arch/sh/include/klibc/archsignal.h | 13 - klibc/klibc/arch/sh/include/klibc/archsys.h | 12 - klibc/klibc/arch/sh/syscall.S | 35 ++ klibc/klibc/arch/sh/sysstub.ph | 34 ++ klibc/klibc/arch/sparc/Makefile.inc | 4 +- .../arch/sparc/include/klibc/archsetjmp.h | 16 - .../arch/sparc/include/klibc/archsignal.h | 13 - .../klibc/arch/sparc/include/klibc/archsys.h | 65 --- klibc/klibc/arch/sparc/include/machine/asm.h | 192 -------- .../klibc/arch/sparc/include/machine/frame.h | 138 ------ klibc/klibc/arch/sparc/include/machine/trap.h | 141 ------ klibc/klibc/arch/sparc/syscall.S | 19 + klibc/klibc/arch/sparc/sysfork.S | 25 + klibc/klibc/arch/sparc/sysstub.ph | 25 + klibc/klibc/arch/sparc64/Makefile.inc | 4 +- .../arch/sparc64/include/klibc/archsetjmp.h | 16 - .../arch/sparc64/include/klibc/archsignal.h | 13 - .../arch/sparc64/include/klibc/archsys.h | 157 ------ klibc/klibc/arch/sparc64/syscall.S | 18 + klibc/klibc/arch/sparc64/sysfork.S | 26 + klibc/klibc/arch/sparc64/sysstub.ph | 25 + klibc/klibc/arch/x86_64/MCONFIG | 8 +- klibc/klibc/arch/x86_64/Makefile.inc | 3 +- .../arch/x86_64/include/klibc/archsetjmp.h | 21 - .../arch/x86_64/include/klibc/archsignal.h | 13 - .../klibc/arch/x86_64/include/klibc/archsys.h | 109 ----- klibc/klibc/arch/x86_64/include/sys/io.h | 126 ----- klibc/klibc/arch/x86_64/syscall.S | 28 ++ klibc/klibc/arch/x86_64/sysstub.ph | 23 + klibc/klibc/asprintf.c | 30 ++ klibc/klibc/ctypes.c | 382 +++++++-------- klibc/klibc/daemon.c | 38 ++ klibc/klibc/fdatasync.c | 15 - klibc/klibc/fork.c | 14 +- klibc/klibc/fstatfs.c | 19 + klibc/klibc/getcwd.c | 5 +- klibc/klibc/getpagesize.c | 26 - klibc/klibc/getpriority.c | 12 +- klibc/klibc/include/alloca.h | 13 - klibc/klibc/include/arpa/inet.h | 24 - klibc/klibc/include/assert.h | 22 - klibc/klibc/include/bits32/bitsize/limits.h | 14 - klibc/klibc/include/bits32/bitsize/stddef.h | 18 - klibc/klibc/include/bits32/bitsize/stdint.h | 34 -- .../include/bits32/bitsize/stdintconst.h | 18 - .../include/bits32/bitsize/stdintlimits.h | 22 - klibc/klibc/include/bits64/bitsize/limits.h | 14 - klibc/klibc/include/bits64/bitsize/stddef.h | 13 - klibc/klibc/include/bits64/bitsize/stdint.h | 36 -- .../include/bits64/bitsize/stdintconst.h | 18 - .../include/bits64/bitsize/stdintlimits.h | 22 - klibc/klibc/include/ctype.h | 118 ----- klibc/klibc/include/dirent.h | 20 - klibc/klibc/include/elf.h | 12 - klibc/klibc/include/endian.h | 42 -- klibc/klibc/include/errno.h | 8 - klibc/klibc/include/fcntl.h | 11 - klibc/klibc/include/grp.h | 13 - klibc/klibc/include/inttypes.h | 226 --------- klibc/klibc/include/klibc/compiler.h | 106 ---- klibc/klibc/include/klibc/diverr.h | 16 - klibc/klibc/include/klibc/extern.h | 14 - klibc/klibc/include/limits.h | 40 -- klibc/klibc/include/net/if.h | 1 - klibc/klibc/include/net/if_arp.h | 1 - klibc/klibc/include/net/if_ether.h | 1 - klibc/klibc/include/net/if_packet.h | 1 - klibc/klibc/include/netinet/in.h | 33 -- klibc/klibc/include/netinet/in6.h | 10 - klibc/klibc/include/netinet/ip.h | 13 - klibc/klibc/include/netinet/tcp.h | 11 - klibc/klibc/include/netinet/udp.h | 19 - klibc/klibc/include/poll.h | 16 - klibc/klibc/include/sched.h | 23 - klibc/klibc/include/setjmp.h | 43 -- klibc/klibc/include/signal.h | 80 ---- klibc/klibc/include/stdarg.h | 14 - klibc/klibc/include/stddef.h | 24 - klibc/klibc/include/stdint.h | 116 ----- klibc/klibc/include/stdio.h | 115 ----- klibc/klibc/include/stdlib.h | 96 ---- klibc/klibc/include/string.h | 40 -- klibc/klibc/include/sys/dirent.h | 13 - klibc/klibc/include/sys/elf32.h | 115 ----- klibc/klibc/include/sys/elf64.h | 115 ----- klibc/klibc/include/sys/elfcommon.h | 186 ------- klibc/klibc/include/sys/fsuid.h | 14 - klibc/klibc/include/sys/ioctl.h | 14 - klibc/klibc/include/sys/klog.h | 24 - klibc/klibc/include/sys/mman.h | 21 - klibc/klibc/include/sys/mount.h | 55 --- klibc/klibc/include/sys/param.h | 11 - klibc/klibc/include/sys/reboot.h | 25 - klibc/klibc/include/sys/resource.h | 15 - klibc/klibc/include/sys/select.h | 13 - klibc/klibc/include/sys/socket.h | 50 -- klibc/klibc/include/sys/socketcalls.h | 28 -- klibc/klibc/include/sys/stat.h | 23 - klibc/klibc/include/sys/syscall.h | 15 - klibc/klibc/include/sys/sysinfo.h | 12 - klibc/klibc/include/sys/sysmacros.h | 31 -- klibc/klibc/include/sys/time.h | 17 - klibc/klibc/include/sys/types.h | 125 ----- klibc/klibc/include/sys/uio.h | 15 - klibc/klibc/include/sys/un.h | 10 - klibc/klibc/include/sys/utime.h | 10 - klibc/klibc/include/sys/utsname.h | 23 - klibc/klibc/include/sys/vfs.h | 14 - klibc/klibc/include/sys/wait.h | 28 -- klibc/klibc/include/syslog.h | 55 --- klibc/klibc/include/termios.h | 86 ---- klibc/klibc/include/time.h | 14 - klibc/klibc/include/unistd.h | 122 ----- klibc/klibc/include/utime.h | 15 - klibc/klibc/inet/bindresvport.c | 21 +- klibc/klibc/interp.S | 4 +- klibc/klibc/jrand48.c | 24 + klibc/klibc/libc_init.c | 86 ++++ klibc/klibc/llseek.c | 25 +- klibc/klibc/lrand48.c | 32 +- klibc/klibc/makeerrlist.pl | 21 +- klibc/klibc/malloc.c | 7 +- klibc/klibc/malloc.h | 8 +- klibc/klibc/mmap.c | 34 +- klibc/klibc/mrand48.c | 13 + klibc/klibc/nice.c | 6 +- klibc/klibc/nrand48.c | 11 + klibc/klibc/open.c | 22 +- klibc/klibc/pause.c | 6 +- klibc/klibc/perror.c | 3 +- klibc/klibc/putchar.c | 15 + klibc/klibc/qsort.c | 4 +- klibc/klibc/readdir.c | 23 +- klibc/klibc/sbrk.c | 30 +- klibc/klibc/seed48.c | 2 +- klibc/klibc/select.c | 9 - klibc/klibc/setresgid.c | 29 -- klibc/klibc/setresuid.c | 30 -- klibc/klibc/sha1hash.c | 2 +- klibc/klibc/sigaction.c | 6 +- klibc/klibc/sigpending.c | 6 +- klibc/klibc/sigprocmask.c | 6 +- klibc/klibc/sigsuspend.c | 6 +- klibc/klibc/socketcalls.pl | 61 ++- klibc/klibc/socketcommon.h | 11 +- klibc/klibc/srand48.c | 3 +- klibc/klibc/statfs.c | 19 + klibc/klibc/strerror.c | 20 +- klibc/klibc/strlcat.c | 31 ++ klibc/klibc/strlcpy.c | 26 + klibc/klibc/strncat.c | 16 +- klibc/klibc/strncpy.c | 8 +- klibc/klibc/strnlen.c | 19 + klibc/klibc/strtotimespec.c | 5 + klibc/klibc/strtotimeval.c | 5 + klibc/klibc/strtotimex.c | 39 ++ klibc/klibc/syscalls.pl | 129 +++-- klibc/klibc/syslog.c | 19 +- klibc/klibc/tests/fcntl.c | 53 ++ klibc/klibc/tests/getpagesize.c | 11 + klibc/klibc/tests/malloctest2.c | 60 +++ klibc/klibc/tests/microhello.c | 2 +- klibc/klibc/tests/minips.c | 453 ------------------ klibc/klibc/tests/mmaptest.c | 28 ++ klibc/klibc/tests/opentest.c | 17 + klibc/klibc/tests/stat.c | 65 +++ klibc/klibc/tests/statfs.c | 43 ++ klibc/klibc/tests/strtoimax.c | 24 + klibc/klibc/tests/strtotime.c | 27 ++ klibc/klibc/time.c | 6 +- klibc/klibc/utime.c | 8 +- klibc/klibc/vasprintf.c | 25 + klibc/version | 2 +- 288 files changed, 3415 insertions(+), 6722 deletions(-) create mode 100644 klibc/klibc.spec delete mode 100644 klibc/klibc/SOCKETCALLS create mode 100644 klibc/klibc/SOCKETCALLS.def delete mode 100644 klibc/klibc/SYSCALLS create mode 100644 klibc/klibc/SYSCALLS.def delete mode 100644 klibc/klibc/arch/alpha/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/alpha/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/alpha/include/klibc/archsys.h delete mode 100644 klibc/klibc/arch/alpha/include/machine/asm.h create mode 100644 klibc/klibc/arch/alpha/syscall.S create mode 100644 klibc/klibc/arch/alpha/sysdual.S create mode 100644 klibc/klibc/arch/alpha/sysstub.ph delete mode 100644 klibc/klibc/arch/arm/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/arm/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/arm/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/arm/syscall.S create mode 100644 klibc/klibc/arch/arm/sysstub.ph create mode 100644 klibc/klibc/arch/cris/__negdi2.S create mode 100644 klibc/klibc/arch/cris/crt0.S create mode 100644 klibc/klibc/arch/cris/divide.c delete mode 100644 klibc/klibc/arch/cris/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/cris/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/cris/setjmp.S create mode 100644 klibc/klibc/arch/cris/syscall.S create mode 100644 klibc/klibc/arch/cris/sysstub.ph delete mode 100644 klibc/klibc/arch/i386/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/i386/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/i386/include/klibc/archsys.h delete mode 100644 klibc/klibc/arch/i386/include/klibc/diverr.h delete mode 100644 klibc/klibc/arch/i386/include/sys/io.h delete mode 100644 klibc/klibc/arch/i386/include/sys/vm86.h create mode 100644 klibc/klibc/arch/i386/open.S create mode 100644 klibc/klibc/arch/i386/syscall.S create mode 100644 klibc/klibc/arch/i386/sysstub.ph delete mode 100644 klibc/klibc/arch/ia64/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/ia64/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/ia64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/ia64/syscall.S create mode 100644 klibc/klibc/arch/ia64/sysstub.ph delete mode 100644 klibc/klibc/arch/m68k/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/m68k/include/klibc/archsys.h delete mode 100644 klibc/klibc/arch/mips/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/mips/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/mips/include/klibc/archsys.h delete mode 100644 klibc/klibc/arch/mips/include/machine/asm.h delete mode 100644 klibc/klibc/arch/mips/include/sgidefs.h create mode 100644 klibc/klibc/arch/mips/klibc.ld create mode 100644 klibc/klibc/arch/mips/syscall.S create mode 100644 klibc/klibc/arch/mips/sysstub.ph delete mode 100644 klibc/klibc/arch/mips64/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/mips64/include/klibc/archsys.h delete mode 100644 klibc/klibc/arch/parisc/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/parisc/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/parisc/syscall.c create mode 100644 klibc/klibc/arch/parisc/sysstub.ph delete mode 100644 klibc/klibc/arch/ppc/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/ppc/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/ppc/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/ppc/syscall.S create mode 100644 klibc/klibc/arch/ppc/sysstub.ph delete mode 100644 klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/ppc64/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/ppc64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/ppc64/syscall.c create mode 100644 klibc/klibc/arch/ppc64/sysstub.ph delete mode 100644 klibc/klibc/arch/s390/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/s390/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/s390/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/s390/mmap.c create mode 100644 klibc/klibc/arch/s390/syscall.c create mode 100644 klibc/klibc/arch/s390/sysstub.ph delete mode 100644 klibc/klibc/arch/s390x/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/s390x/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/s390x/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/s390x/mmap.c create mode 100644 klibc/klibc/arch/s390x/syscall.c create mode 100644 klibc/klibc/arch/s390x/sysstub.ph delete mode 100644 klibc/klibc/arch/sh/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/sh/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/sh/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/sh/syscall.S create mode 100644 klibc/klibc/arch/sh/sysstub.ph delete mode 100644 klibc/klibc/arch/sparc/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/sparc/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/sparc/include/klibc/archsys.h delete mode 100644 klibc/klibc/arch/sparc/include/machine/asm.h delete mode 100644 klibc/klibc/arch/sparc/include/machine/frame.h delete mode 100644 klibc/klibc/arch/sparc/include/machine/trap.h create mode 100644 klibc/klibc/arch/sparc/syscall.S create mode 100644 klibc/klibc/arch/sparc/sysfork.S create mode 100644 klibc/klibc/arch/sparc/sysstub.ph delete mode 100644 klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/sparc64/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/sparc64/include/klibc/archsys.h create mode 100644 klibc/klibc/arch/sparc64/syscall.S create mode 100644 klibc/klibc/arch/sparc64/sysfork.S create mode 100644 klibc/klibc/arch/sparc64/sysstub.ph delete mode 100644 klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h delete mode 100644 klibc/klibc/arch/x86_64/include/klibc/archsignal.h delete mode 100644 klibc/klibc/arch/x86_64/include/klibc/archsys.h delete mode 100644 klibc/klibc/arch/x86_64/include/sys/io.h create mode 100644 klibc/klibc/arch/x86_64/syscall.S create mode 100644 klibc/klibc/arch/x86_64/sysstub.ph create mode 100644 klibc/klibc/asprintf.c create mode 100644 klibc/klibc/daemon.c delete mode 100644 klibc/klibc/fdatasync.c create mode 100644 klibc/klibc/fstatfs.c delete mode 100644 klibc/klibc/getpagesize.c delete mode 100644 klibc/klibc/include/alloca.h delete mode 100644 klibc/klibc/include/arpa/inet.h delete mode 100644 klibc/klibc/include/assert.h delete mode 100644 klibc/klibc/include/bits32/bitsize/limits.h delete mode 100644 klibc/klibc/include/bits32/bitsize/stddef.h delete mode 100644 klibc/klibc/include/bits32/bitsize/stdint.h delete mode 100644 klibc/klibc/include/bits32/bitsize/stdintconst.h delete mode 100644 klibc/klibc/include/bits32/bitsize/stdintlimits.h delete mode 100644 klibc/klibc/include/bits64/bitsize/limits.h delete mode 100644 klibc/klibc/include/bits64/bitsize/stddef.h delete mode 100644 klibc/klibc/include/bits64/bitsize/stdint.h delete mode 100644 klibc/klibc/include/bits64/bitsize/stdintconst.h delete mode 100644 klibc/klibc/include/bits64/bitsize/stdintlimits.h delete mode 100644 klibc/klibc/include/ctype.h delete mode 100644 klibc/klibc/include/dirent.h delete mode 100644 klibc/klibc/include/elf.h delete mode 100644 klibc/klibc/include/endian.h delete mode 100644 klibc/klibc/include/errno.h delete mode 100644 klibc/klibc/include/fcntl.h delete mode 100644 klibc/klibc/include/grp.h delete mode 100644 klibc/klibc/include/inttypes.h delete mode 100644 klibc/klibc/include/klibc/compiler.h delete mode 100644 klibc/klibc/include/klibc/diverr.h delete mode 100644 klibc/klibc/include/klibc/extern.h delete mode 100644 klibc/klibc/include/limits.h delete mode 100644 klibc/klibc/include/net/if.h delete mode 100644 klibc/klibc/include/net/if_arp.h delete mode 100644 klibc/klibc/include/net/if_ether.h delete mode 100644 klibc/klibc/include/net/if_packet.h delete mode 100644 klibc/klibc/include/netinet/in.h delete mode 100644 klibc/klibc/include/netinet/in6.h delete mode 100644 klibc/klibc/include/netinet/ip.h delete mode 100644 klibc/klibc/include/netinet/tcp.h delete mode 100644 klibc/klibc/include/netinet/udp.h delete mode 100644 klibc/klibc/include/poll.h delete mode 100644 klibc/klibc/include/sched.h delete mode 100644 klibc/klibc/include/setjmp.h delete mode 100644 klibc/klibc/include/signal.h delete mode 100644 klibc/klibc/include/stdarg.h delete mode 100644 klibc/klibc/include/stddef.h delete mode 100644 klibc/klibc/include/stdint.h delete mode 100644 klibc/klibc/include/stdio.h delete mode 100644 klibc/klibc/include/stdlib.h delete mode 100644 klibc/klibc/include/string.h delete mode 100644 klibc/klibc/include/sys/dirent.h delete mode 100644 klibc/klibc/include/sys/elf32.h delete mode 100644 klibc/klibc/include/sys/elf64.h delete mode 100644 klibc/klibc/include/sys/elfcommon.h delete mode 100644 klibc/klibc/include/sys/fsuid.h delete mode 100644 klibc/klibc/include/sys/ioctl.h delete mode 100644 klibc/klibc/include/sys/klog.h delete mode 100644 klibc/klibc/include/sys/mman.h delete mode 100644 klibc/klibc/include/sys/mount.h delete mode 100644 klibc/klibc/include/sys/param.h delete mode 100644 klibc/klibc/include/sys/reboot.h delete mode 100644 klibc/klibc/include/sys/resource.h delete mode 100644 klibc/klibc/include/sys/select.h delete mode 100644 klibc/klibc/include/sys/socket.h delete mode 100644 klibc/klibc/include/sys/socketcalls.h delete mode 100644 klibc/klibc/include/sys/stat.h delete mode 100644 klibc/klibc/include/sys/syscall.h delete mode 100644 klibc/klibc/include/sys/sysinfo.h delete mode 100644 klibc/klibc/include/sys/sysmacros.h delete mode 100644 klibc/klibc/include/sys/time.h delete mode 100644 klibc/klibc/include/sys/types.h delete mode 100644 klibc/klibc/include/sys/uio.h delete mode 100644 klibc/klibc/include/sys/un.h delete mode 100644 klibc/klibc/include/sys/utime.h delete mode 100644 klibc/klibc/include/sys/utsname.h delete mode 100644 klibc/klibc/include/sys/vfs.h delete mode 100644 klibc/klibc/include/sys/wait.h delete mode 100644 klibc/klibc/include/syslog.h delete mode 100644 klibc/klibc/include/termios.h delete mode 100644 klibc/klibc/include/time.h delete mode 100644 klibc/klibc/include/unistd.h delete mode 100644 klibc/klibc/include/utime.h create mode 100644 klibc/klibc/jrand48.c create mode 100644 klibc/klibc/libc_init.c create mode 100644 klibc/klibc/mrand48.c create mode 100644 klibc/klibc/nrand48.c create mode 100644 klibc/klibc/putchar.c delete mode 100644 klibc/klibc/select.c delete mode 100644 klibc/klibc/setresgid.c delete mode 100644 klibc/klibc/setresuid.c create mode 100644 klibc/klibc/statfs.c create mode 100644 klibc/klibc/strlcat.c create mode 100644 klibc/klibc/strlcpy.c create mode 100644 klibc/klibc/strnlen.c create mode 100644 klibc/klibc/strtotimespec.c create mode 100644 klibc/klibc/strtotimeval.c create mode 100644 klibc/klibc/strtotimex.c create mode 100644 klibc/klibc/tests/fcntl.c create mode 100644 klibc/klibc/tests/getpagesize.c create mode 100644 klibc/klibc/tests/malloctest2.c delete mode 100644 klibc/klibc/tests/minips.c create mode 100644 klibc/klibc/tests/mmaptest.c create mode 100644 klibc/klibc/tests/opentest.c create mode 100644 klibc/klibc/tests/stat.c create mode 100644 klibc/klibc/tests/statfs.c create mode 100644 klibc/klibc/tests/strtoimax.c create mode 100644 klibc/klibc/tests/strtotime.c create mode 100644 klibc/klibc/vasprintf.c diff --git a/klibc/MCONFIG b/klibc/MCONFIG index ec8b65c0e4..d2aa23626c 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -3,22 +3,29 @@ # Makefile configuration, without explicit rules # +# Eventually support separate compilation, but we don't have it yet... +OBJROOT = $(SRCROOT) + ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) CROSS = CC = $(CROSS)gcc LD = $(CROSS)ld KLIBSRC = $(SRCROOT)/klibc -REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include -I$(KLIBSRC) \ - -I$(KLIBSRC)/arch/$(ARCH)/include \ - -I$(KLIBSRC)/include/bits$(BITSIZE) \ - -D__KLIBC__ -DBITSIZE=$(BITSIZE) -I$(KLIBSRC)/include \ - -I$(KERNEL_DIR)/include +KLIBOBJ = $(OBJROOT)/klibc +REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include \ + -D__KLIBC__ -DBITSIZE=$(BITSIZE) \ + -I$(SRCROOT)/include/arch/$(ARCH) \ + -I$(SRCROOT)/include/bits$(BITSIZE) \ + -I$(SRCROOT)/include \ + -I$(SRCROOT)/linux/include -I$(SRCROOT)/linux/include2 + LDFLAGS = AR = $(CROSS)ar RANLIB = $(CROSS)ranlib NM = $(CROSS)nm PERL = perl STRIP = $(CROSS)strip --strip-all -R .comment -R .note +OBJCOPY = $(CROSS)objcopy HOST_CC = gcc HOST_CFLAGS = -g -O @@ -26,13 +33,13 @@ HOST_LDFLAGS = HOST_LIBS = # Static library paths -CRT0 = $(KLIBSRC)/crt0.o -KLIBC = $(KLIBSRC)/libc.a +CRT0 = $(KLIBOBJ)/crt0.o +KLIBC = $(KLIBOBJ)/libc.a LIBGCC = $(shell $(CC) --print-libgcc) # Shared library paths -CRTSHARED = $(KLIBSRC)/interp.o -LIBSHARED = $(KLIBSRC)/libc.so +CRTSHARED = $(KLIBOBJ)/interp.o +LIBSHARED = $(KLIBOBJ)/libc.so # # This indicates the location of the final version of the shared library. @@ -41,7 +48,15 @@ LIBSHARED = $(KLIBSRC)/libc.so # SHLIBDIR = /lib +# Enable this to make perror/strerror return real error messages +# This makes klibc.so and any static binary which uses these functions +# about 4K bigger. +ERRLIST = 1 + # # Include arch-specific rule fragments # include $(KLIBSRC)/arch/$(ARCH)/MCONFIG + +# How to tell the linker main() is the entrypoint +EMAIN ?= -e main diff --git a/klibc/Makefile b/klibc/Makefile index ef5fbabff8..8823a33bfd 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -10,7 +10,7 @@ klibc.spec: klibc.spec.in version .PHONY: rpm rpm: klibc.spec - +$(rpmbuild) -bb klibc.spec + +$(rpmbuild) -bb klibc.spec --target=$(ARCH) %: @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done diff --git a/klibc/README b/klibc/README index 4381364874..eb72e1c239 100644 --- a/klibc/README +++ b/klibc/README @@ -1,4 +1,5 @@ -Please see klibc/README for build instructions. +Please see klibc/README for build instructions and for the status of +various platforms. diff --git a/klibc/klibc.spec b/klibc/klibc.spec new file mode 100644 index 0000000000..6166a35c4d --- /dev/null +++ b/klibc/klibc.spec @@ -0,0 +1,157 @@ +Summary: A minimal libc subset for use with initramfs. +Name: klibc +Version: 0.181 +Release: 1 +License: BSD/GPL +Group: Development/Libraries +URL: http://www.zytor.com/mailman/listinfo/klibc +Source: http://www.kernel.org/pub/linux/libs/klibc-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +BuildRequires: kernel-source >= 2.6.0 +Packager: H. Peter Anvin +Prefix: /usr +Vendor: Starving Linux Artists + +%description +%{name} is intended to be a minimalistic libc subset for use with +initramfs. It is deliberately written for small size, minimal +entanglement, and portability, not speed. It is definitely a work in +progress, and a lot of things are still missing. + +%package kernheaders +Summary: Kernel headers used during the build of klibc. +Group: Development/Libraries + +%description kernheaders +This package contains the set of kernel headers that were required to +build %{name} and the utilities that ship with it. This may or may +not be a complete enough set to build other programs that link against +%{name}. If in doubt, use real kernel headers instead. + +%package utils +Summary: Small statically-linked utilities built with klibc. +Group: Utilities/System + +%description utils + +This package contains a collection of programs that are statically +linked against klibc. These duplicate some of the functionality of a +regular Linux toolset, but are typically much smaller than their +full-function counterparts. They are intended for inclusion in +initramfs images and embedded systems. + +%prep +%setup -q +cp -as /usr/src/linux-`rpm -q kernel-source | tail -1 | cut -d- -f3-` ./linux +make -C linux defconfig ARCH=%{_target_cpu} +make -C linux prepare ARCH=%{_target_cpu} +# Deal with braindamage in RedHat's kernel-source RPM +rm -f linux/include/linux/config.h +cat < linux/include/linux/config.h +#ifndef _LINUX_CONFIG_H +#define _LINUX_CONFIG_H + +#include + +#endif +EOF +mkdir -p %{buildroot} + +%build +make ARCH=%{_target_cpu} + +%install +rm -rf %{buildroot} + +dest=%{buildroot}/%{prefix} +lib=$dest/%{_lib}/klibc +inc=$dest/include/klibc +exe=$dest/libexec/klibc +doc=$dest/share/doc/%{name}-%{version} +udoc=$dest/share/doc/%{name}-utils-%{version} + +# First, the library. + +install -dD -m 755 $lib $inc/kernel $exe $doc $udoc +install -m 755 klibc/klibc.so $lib +install -m 644 klibc/libc.a $lib +install -m 644 klibc/crt0.o $lib +install -m 644 klibc/libc.so.hash $lib +ln $lib/klibc.so $lib/libc.so +ln $lib/klibc.so $lib/klibc-$(cat $lib/libc.so.hash).so + +# Next, the generated binaries. +# These are currently static binaries, should we go for shared? + +install -m 755 ash/sh $exe +install -m 755 gzip/gzip $exe +ln $exe/gzip $exe/gunzip +ln $exe/gzip $exe/zcat +install -m 755 ipconfig/ipconfig $exe +install -m 755 kinit/kinit $exe +install -m 755 nfsmount/nfsmount $exe +install -m 755 utils/static/* $exe + +# The docs. + +install -m 444 README $doc +install -m 444 klibc/README $doc/README.klibc +install -m 444 klibc/arch/README $doc/README.klibc.arch + +install -m 444 gzip/COPYING $udoc/COPYING.gzip +install -m 444 gzip/README $udoc/README.gzip +install -m 444 ipconfig/README $udoc/README.ipconfig +install -m 444 kinit/README $udoc/README.kinit + +# Finally, the include files. + +bitsize=$(make --no-print-directory -C klibc bitsize ARCH=%{_target_cpu}) +cp --parents $(find klibc/include \( -name CVS -o -name SCCS \) -prune \ + -o -name '*.h' -print) $inc +mv $inc/klibc $inc/klibc.$$ +mv $inc/klibc.$$/include/* $inc +mv $inc/bits$bitsize/bitsize $inc +rm -rf $inc/klibc.$$ $inc/bits[0-9]* +pushd klibc/arch/%{_arch}/include +cp --parents -f $(find . \( -name CVS -o -name SCCS \) -prune \ + -o -name '*.h' -print) $inc +popd + +# Yeugh. Find the transitive closure over all kernel headers included +# by klibc, and copy them into place. + +find . -name '.*.d' | xargs -r sed -e 's,[ \t][ \t]*,\n,g' | sed -n -e 's,^\.\./linux/include/,,p' | sort | uniq | (cd linux/include && xargs -ri cp --parents '{}' $inc/kernel) + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root,-) +%docdir %{prefix}/share/doc/%{name}-%{version} +%{prefix}/%{_lib}/klibc +%dir %{prefix}/include/klibc +%{prefix}/include/klibc/*.h +%{prefix}/include/klibc/arpa +%{prefix}/include/klibc/bitsize +%{prefix}/include/klibc/klibc +%{prefix}/include/klibc/net +%{prefix}/include/klibc/netinet +%{prefix}/include/klibc/sys +%{prefix}/share/doc/%{name}-%{version} + +%files kernheaders +%defattr(-,root,root,-) +%{prefix}/include/klibc/kernel + +%files utils +%defattr(-,root,root,-) +%{prefix}/libexec/klibc +%docdir %{prefix}/share/doc/%{name}-utils-%{version} +%{prefix}/share/doc/%{name}-utils-%{version} + +%changelog +* Tue Jul 6 2004 H. Peter Anvin +- Update to use kernel-source RPM for the kernel symlink. + +* Sat Nov 29 2003 Bryan O'Sullivan - +- Initial build. diff --git a/klibc/klibc.spec.in b/klibc/klibc.spec.in index f8bccc390e..8f5b2618d0 100644 --- a/klibc/klibc.spec.in +++ b/klibc/klibc.spec.in @@ -1,16 +1,14 @@ -%define _rpmdir rpms -%define _builddir . - Summary: A minimal libc subset for use with initramfs. Name: klibc -Version: 0.89 +Version: @@VERSION@@ Release: 1 License: BSD/GPL Group: Development/Libraries -URL: http://www.zytor.com/klibc -Source: /dev/null +URL: http://www.zytor.com/mailman/listinfo/klibc +Source: http://www.kernel.org/pub/linux/libs/klibc-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -Packager: Bryan O'Sullivan +BuildRequires: kernel-source >= 2.6.0 +Packager: H. Peter Anvin Prefix: /usr Vendor: Starving Linux Artists @@ -43,18 +41,24 @@ full-function counterparts. They are intended for inclusion in initramfs images and embedded systems. %prep -if [ ! -L linux ]; then - echo "*** You must have a symlink named linux to build klibc" 1>&2 - exit 1 -fi -if [ ! -f linux/include/asm/page.h ]; then - echo "*** You need to 'make prepare' in the linux tree before building klibc" 1>&2 - exit 1 -fi -mkdir -p %{buildroot} %{_rpmdir} +%setup -q +cp -as /usr/src/linux-`rpm -q kernel-source | tail -1 | cut -d- -f3-` ./linux +make -C linux defconfig ARCH=%{_target_cpu} +make -C linux prepare ARCH=%{_target_cpu} +# Deal with braindamage in RedHat's kernel-source RPM +rm -f linux/include/linux/config.h +cat < linux/include/linux/config.h +#ifndef _LINUX_CONFIG_H +#define _LINUX_CONFIG_H + +#include + +#endif +EOF +mkdir -p %{buildroot} %build -make +make ARCH=%{_target_cpu} %install rm -rf %{buildroot} @@ -77,6 +81,7 @@ ln $lib/klibc.so $lib/libc.so ln $lib/klibc.so $lib/klibc-$(cat $lib/libc.so.hash).so # Next, the generated binaries. +# These are currently static binaries, should we go for shared? install -m 755 ash/sh $exe install -m 755 gzip/gzip $exe @@ -85,9 +90,7 @@ ln $exe/gzip $exe/zcat install -m 755 ipconfig/ipconfig $exe install -m 755 kinit/kinit $exe install -m 755 nfsmount/nfsmount $exe -for i in chroot dd fstype mkdir mkfifo mount umount; do - install -m 755 utils/$i $exe -done +install -m 755 utils/static/* $exe # The docs. @@ -102,7 +105,7 @@ install -m 444 kinit/README $udoc/README.kinit # Finally, the include files. -bitsize=$(make --no-print-directory -C klibc bitsize) +bitsize=$(make --no-print-directory -C klibc bitsize ARCH=%{_target_cpu}) cp --parents $(find klibc/include \( -name CVS -o -name SCCS \) -prune \ -o -name '*.h' -print) $inc mv $inc/klibc $inc/klibc.$$ @@ -147,5 +150,8 @@ rm -rf $RPM_BUILD_ROOT %{prefix}/share/doc/%{name}-utils-%{version} %changelog +* Tue Jul 6 2004 H. Peter Anvin +- Update to use kernel-source RPM for the kernel symlink. + * Sat Nov 29 2003 Bryan O'Sullivan - - Initial build. diff --git a/klibc/klibc/MCONFIG b/klibc/klibc/MCONFIG index 253a9461b7..5b6eecd037 100644 --- a/klibc/klibc/MCONFIG +++ b/klibc/klibc/MCONFIG @@ -8,6 +8,11 @@ include ../MCONFIG include ../MRULES WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline + +ifeq ($(ERRLIST),1) +REQFLAGS += -DWITH_ERRLIST +endif + CFLAGS = -Wp,-MD,$(dir $*).$(notdir $*).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) SOFLAGS = -fPIC diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 7ed03a8e87..d7e75f1814 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -10,6 +10,7 @@ include MCONFIG TESTS = $(patsubst %.c,%,$(wildcard tests/*.c)) \ $(patsubst %.c,%.shared,$(wildcard tests/*.c)) LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ + asprintf.o vasprintf.o \ vsscanf.o sscanf.o ctypes.o \ strntoumax.o strntoimax.o \ atoi.o atol.o atoll.o \ @@ -18,41 +19,51 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ globals.o exitc.o atexit.o onexit.o \ execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \ fork.o wait.o wait3.o waitpid.o system.o setpgrp.o getpgrp.o \ - open.o \ + daemon.o \ printf.o vprintf.o fprintf.o vfprintf.o perror.o \ - fopen.o fread.o fread2.o fgetc.o fgets.o \ - fwrite.o fwrite2.o fputc.o fputs.o puts.o \ - sleep.o usleep.o raise.o abort.o assert.o alarm.o pause.o \ + statfs.o fstatfs.o umount.o \ + open.o fopen.o fread.o fread2.o fgetc.o fgets.o \ + fwrite.o fwrite2.o fputc.o fputs.o puts.o putchar.o \ + sleep.o usleep.o strtotimespec.o strtotimeval.o \ + raise.o abort.o assert.o alarm.o pause.o \ __signal.o sysv_signal.o bsd_signal.o siglist.o siglongjmp.o \ sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ - brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o getpagesize.o \ + brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ - memmove.o \ + memmove.o memchr.o \ strcasecmp.o strncasecmp.o strndup.o strerror.o \ - strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o \ - strncat.o strstr.o strncmp.o strncpy.o strrchr.o strspn.o \ + strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o strnlen.o \ + strncat.o strlcpy.o strlcat.o \ + strstr.o strncmp.o strncpy.o strrchr.o strspn.o \ strsep.o strtok.o \ gethostname.o getdomainname.o getcwd.o \ - seteuid.o setegid.o setresuid.o setresgid.o \ + seteuid.o setegid.o \ getenv.o setenv.o putenv.o __put_env.o unsetenv.o \ getopt.o readdir.o \ syslog.o closelog.o pty.o getpt.o isatty.o reboot.o \ - time.o utime.o fdatasync.o llseek.o select.o nice.o getpriority.o \ - qsort.o lrand48.o srand48.o seed48.o \ + time.o utime.o llseek.o nice.o getpriority.o \ + qsort.o \ + lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \ inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \ send.o recv.o +ifeq ($(ERRLIST),1) +LIBOBJS += errlist.o +endif + SOLIB = libc.so SOHASH = klibc.so CRT0 = crt0.o LIB = libc.a -#all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so -all: $(CRT0) $(LIB) $(SOLIB) klibc.so +INTERP_O = interp.o + +all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so # Add any architecture-specific rules include arch/$(ARCH)/Makefile.inc +EMAIN ?= -e main tests: $(TESTS) @@ -71,19 +82,20 @@ tests/% : tests/%.o $(LIB) $(CRT0) $(STRIP) $@.stripped tests/%.shared : tests/%.o interp.o $(SOLIB) - $(LD) $(LDFLAGS) -o $@ -e main interp.o tests/$*.o -R $(SOLIB) $(LIBGCC) + $(LD) $(LDFLAGS) -o $@ $(EMAIN) interp.o tests/$*.o -R $(SOLIB) $(LIBGCC) cp $@ $@.stripped $(STRIP) $@.stripped $(LIB): __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj rm -f $(LIB) - $(AR) cq $(LIB) __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/*.o socketcalls/*.o + $(AR) cq $(LIB) __static_init.o $(LIBOBJS) $(ARCHOBJS) \ + $(wildcard syscalls/*.o) $(wildcard socketcalls/*.o) $(RANLIB) $(LIB) $(SOLIB): $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj $(LD) $(LDFLAGS) $(SHAREDFLAGS) -o $@ \ $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) \ - syscalls/*.o socketcalls/*.o \ + $(wildcard syscalls/*.o) $(wildcard socketcalls/*.o) \ $(LIBGCC) sha1hash: sha1hash.c @@ -99,7 +111,7 @@ $(SOHASH): $(SOLIB) $(SOLIB).hash rm -f klibc-??????????????????????.so ln -f $@ klibc-`cat $(SOLIB).hash`.so -interp.o: interp.S $(SOLIB).hash +$(INTERP_O): interp.S $(SOLIB).hash $(CC) $(CFLAGS) -D__ASSEMBLY__ -DLIBDIR=\"$(SHLIBDIR)\" \ -DSOHASH=\"`cat $(SOLIB).hash`\" \ -c -o $@ $< @@ -107,16 +119,29 @@ interp.o: interp.S $(SOLIB).hash crt0.o: arch/$(ARCH)/crt0.o cp arch/$(ARCH)/crt0.o . -syscalls.dir: SYSCALLS syscalls.pl syscommon.h +errlist.c: + $(PERL) makeerrlist.pl -errlist > $@ || rm -f $@ + +# We pass -ansi to keep cpp from define e.g. "i386" as well as "__i386__" +SYSCALLS.i: SYSCALLS.def + $(CC) $(CFLAGS) -D__ASSEMBLY__ -ansi -x assembler-with-cpp -E -o $@ $< + +syscalls.nrs: ../include/sys/syscall.h ../include/arch/$(ARCH)/klibc/archsys.h ../linux/include/asm/unistd.h + $(CC) $(CFLAGS) -Wp,-dM -x c -E -o $@ ../include/sys/syscall.h + +syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscalls.nrs rm -rf syscalls mkdir syscalls - $(PERL) syscalls.pl $(ARCH) SYSCALLS + $(PERL) syscalls.pl SYSCALLS.i $(ARCH) $(BITSIZE) syscalls.nrs ../include/klibc/havesyscall.h touch $@ -socketcalls.dir: SOCKETCALLS socketcalls.pl socketcommon.h +../include/klibc/havesyscall.h: syscalls.dir + : Generated by side effect + +socketcalls.dir: SOCKETCALLS.def socketcalls.pl socketcommon.h rm -rf socketcalls mkdir socketcalls - $(PERL) socketcalls.pl $(ARCH) SOCKETCALLS + $(PERL) socketcalls.pl SOCKETCALLS.def $(ARCH) touch $@ %/static.obj: %.dir @@ -133,9 +158,10 @@ clean: archclean rm -f $(TESTS) tests/*.stripped rm -rf syscalls syscalls.dir rm -rf socketcalls socketcalls.dir - rm -f sha1hash + rm -f sha1hash errlist.c spotless: clean + rm -f ../include/klibc/havesyscall.h syscalls.nrs find . \( -name \*~ -o -name '.*.d' \) -not -type d -print0 | \ xargs -0rt rm -f diff --git a/klibc/klibc/README b/klibc/klibc/README index d69fa8de41..edc8524f22 100644 --- a/klibc/klibc/README +++ b/klibc/klibc/README @@ -1,6 +1,6 @@ This is klibc, what is intended to be a minimalistic libc subset for use with initramfs. It is deliberately written for small size, -minimal entaglement and portability, not speed. It is definitely a +minimal entaglement, and portability, not speed. It is definitely a work in progress, and a lot of things are still missing. @@ -34,20 +34,38 @@ b) If you're cross-compiling, change ARCH in the main MCONFIG file to The following is the last known status of various architectures: - Known to work: alpha arm ia64 i386 ppc s390 s390x sparc - sparc64 x86_64* - Works static, not shared: mips* arm-thumb sh* parisc - Might work: ppc64 - Need porting work: cris m68k mips64 v850 + alpha: Working static, shared untested + arm-thumb: Untested + arm26: Not yet ported + arm: Working + cris: Untested + h8300: Not yet ported + i386: Working + ia64: Working + m68k: Not yet ported + mips64: Not yet ported + mips: Working + parisc: Untested + ppc64: Working + ppc: Working + s390: Working static, shared untested + s390x: Working + sh: Untested + sparc64: sigaction() fails in ash for unknown reason + sparc: Working + v850: Not yet ported + x86-64: Working + + Shared library support requires recent binutils on many + architectures. - x86_64: requires a kernel header patch (to be created) - mips, sh: linker problem; might work with fixed linker + "Need sysstub.ph" means the architectural changes first implemented + in klibc-0.117 has not yet been implemented; klibc-0.116 did, + however, work. "Not yet ported" means no porting work has been + done on this architecture. - Shared library support requires binutils 2.13.90.0.4 or later on - many architectures. - - Note that even the "known to work" ones likely have bugs. Please - report them if you run into them. + Note that even the "working" ones likely have bugs. Please report + them if you run into them. c) Type "make" and pray... diff --git a/klibc/klibc/SOCKETCALLS b/klibc/klibc/SOCKETCALLS deleted file mode 100644 index 1ab4e367a2..0000000000 --- a/klibc/klibc/SOCKETCALLS +++ /dev/null @@ -1,21 +0,0 @@ -# -*- fundamental -*- -# -# These are calls that are invoked via the socketcall mechanism -# -int socket(int, int, int) -int bind(int, struct sockaddr *, int) -int connect(int, struct sockaddr *, socklen_t) -int listen(int, int) -int accept(int, struct sockaddr *, socklen_t *) -int getsockname(int, struct sockaddr *, socklen_t *) -int getpeername(int, struct sockaddr *, socklen_t *) -int socketpair(int, int, int, int *) -# int send(int, const void *, size_t, unsigned int) -int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t) -# int recv(int, void *, size_t, unsigned int) -int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *) -int shutdown(int, int) -int setsockopt(int, int, int, const void *, socklen_t) -int getsockopt(int, int, int, void *, socklen_t *) -int sendmsg(int, const struct msghdr *, unsigned int) -int recvmsg(int, struct msghdr *, unsigned int) diff --git a/klibc/klibc/SOCKETCALLS.def b/klibc/klibc/SOCKETCALLS.def new file mode 100644 index 0000000000..e70b3fc16e --- /dev/null +++ b/klibc/klibc/SOCKETCALLS.def @@ -0,0 +1,21 @@ +; -*- fundamental -*- +; +; These are calls that are invoked via the socketcall mechanism +; Note that on most architectures this is simply #included into +; SYSCALLS.def. +; + int socket(int, int, int) + int bind(int, struct sockaddr *, int) + int connect(int, struct sockaddr *, socklen_t) + int listen(int, int) + int accept(int, struct sockaddr *, socklen_t *) + int getsockname(int, struct sockaddr *, socklen_t *) + int getpeername(int, struct sockaddr *, socklen_t *) + int socketpair(int, int, int, int *) + int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t) + int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *) + int shutdown(int, int) + int setsockopt(int, int, int, const void *, socklen_t) + int getsockopt(int, int, int, void *, socklen_t *) + int sendmsg(int, const struct msghdr *, unsigned int) + int recvmsg(int, struct msghdr *, unsigned int) diff --git a/klibc/klibc/SYSCALLS b/klibc/klibc/SYSCALLS deleted file mode 100644 index 82081201b4..0000000000 --- a/klibc/klibc/SYSCALLS +++ /dev/null @@ -1,153 +0,0 @@ -# -*- fundamental -*- -# -# This is a list of system calls we invoke "directly". These -# are generated into syscall stubs in their own C files, so the -# linker can do its job properly. -# -# The full description of a line is: -# [<[!]arch,...>] type sysname[@systype][::funcname](args) -# - -# -# Process-related syscalls -# - pid_t vfork() - pid_t vfork@forkish() - pid_t getpid() - pid_t getxpid@dual0::getpid() -int setpgid(pid_t, pid_t) -pid_t getpgid(pid_t) - pid_t getppid() - pid_t getxpid@dual1::getppid() -pid_t setsid() -pid_t getsid(pid_t) -pid_t wait4(pid_t, int *, int, struct rusage *) -int execve(const char *, char * const *, char * const *) -int setpriority(int, int, int) -int sched_setscheduler(pid_t, int, const struct sched_param *) -int sched_yield() - -# -# User and group IDs -# -int setuid(uid_t) -int setgid(gid_t) - uid_t getuid() - uid_t getxuid@dual0::getuid() - gid_t getgid() - gid_t getxgid@dual0::getgid() - uid_t geteuid() - uid_t getxuid@dual1::geteuid() - gid_t getegid() - uid_t getxgid@dual1::getegid() -int getgroups(int, gid_t *) -int setgroups(size_t, const gid_t *) -int setreuid(uid_t, uid_t) -int setregid(gid_t, gid_t) -int setfsuid(uid_t) -int setfsgid(gid_t) - -# -# Filesystem-related system calls -# -int mount(const char *, const char *, const char *, unsigned long, const void *) - int umount2(const char *, int) - int umount::umount2(const char *, int) - int pivot_root(const char *, const char *) -int sync() -int statfs(const char *, struct statfs *) -int fstatfs(int, struct statfs *) -int swapon(const char *, int) -int swapoff(const char *) - -# -# Inode-related system calls -# -int access(const char *, int) -int link(const char *, const char *) -int unlink(const char *) -int chdir(const char *) -int rename(const char *, const char *) -int mknod(const char *, mode_t, dev_t) -int chmod(const char *, mode_t) -int fchmod(int, mode_t) -int mkdir(const char *, mode_t) -int rmdir(const char *) - int pipe(int *) -mode_t umask(mode_t) -int chroot(const char *) -int symlink(const char *, const char *) -int readlink(const char *, char *, size_t) -int stat(const char *, struct stat *) -int lstat(const char *, struct stat *) -int fstat(int, struct stat *) -int getdents(unsigned int, struct dirent *, unsigned int) -int chown(const char *, uid_t, gid_t) -int fchown(int, uid_t, gid_t) -int lchown(const char *, uid_t, gid_t) - -# -# I/O operations -# -ssize_t read(int, void *, size_t) -ssize_t write(int, const void *, size_t) -int close(int) -off_t lseek(int, off_t, int) -int dup(int) -int dup2(int, int) -int fcntl(int, int, long) -int ioctl(int, int, void *) -int flock(int, int) -int poll(struct pollfd *, nfds_t, long) -int fsync(int) -int readv(int, const struct iovec *, int) -int writev(int, const struct iovec *, int) -int ftruncate(int, off_t) - -# -# Signal operations -# -int kill(pid_t, int) -int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) -int rt_sigsuspend(const sigset_t *, size_t) -int rt_sigpending(sigset_t *, size_t) -int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t) -int getitimer(int, struct itimerval *) -int setitimer(int, const struct itimerval *, struct itimerval *) - -# -# Time-related system calls -# -clock_t times(struct tms *) -int gettimeofday(struct timeval *, struct timezone *) -int settimeofday(const struct timeval *, const struct timezone *) -int nanosleep(const struct timespec *, struct timespec *) - -# -# Memory -# -void * brk::__brk(void *) -int munmap(void *, size_t) -void * mremap(void *, size_t, size_t, unsigned long) -int msync(const void *, size_t, int) -int mprotect(const void *, size_t, int) - -# -# System stuff -# -int uname(struct utsname *) -int setdomainname(const char *, size_t) -int sethostname(const char *, size_t) -long init_module(void *, unsigned long, const char *) -long delete_module(const char *, unsigned int) - int query_module(const char *, int, void *, size_t, size_t) -int reboot::__reboot(int, int, int, void *) -int syslog::klogctl(int, char *, int) -int sysinfo(struct sysinfo *) - -# -# Low-level I/O (generally architecture-specific) -# - int iopl(int) - int ioperm(unsigned long, unsigned long, int) - int vm86(struct vm86_struct *) diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def new file mode 100644 index 0000000000..dbd7dc8434 --- /dev/null +++ b/klibc/klibc/SYSCALLS.def @@ -0,0 +1,207 @@ +; -*- fundamental -*- +; +; This is a list of system calls we invoke "directly". These +; are generated into syscall stubs in their own files, so the +; linker can do its job properly. +; +; The full description of a line is: +; [<[?][!]arch,...>] type [sysname,...][@systype][::funcname](args) +; +; ? means only instantiate this system call if present in asm/unistd.h +; + +#include + +; +; Process-related syscalls +; + pid_t clone::__clone(unsigned long, void *) + pid_t clone::__clone2(unsigned long, void *, void *) + pid_t fork() + pid_t fork@forkish() + pid_t vfork() + pid_t vfork@forkish() + pid_t getpid() + pid_t getxpid@dual0::getpid() +int setpgid(pid_t, pid_t) +pid_t getpgid(pid_t) + pid_t getppid() + pid_t getxpid@dual1::getppid() +pid_t setsid() +pid_t getsid(pid_t) +pid_t wait4(pid_t, int *, int, struct rusage *) +int execve(const char *, char * const *, char * const *) + int nice(int) + int getpriority(int, int) + int getpriority::__getpriority(int, int) +int setpriority(int, int, int) +int sched_setscheduler(pid_t, int, const struct sched_param *) +int sched_yield() + +; +; User and group IDs +; +int setuid32,setuid::setuid(uid_t) +int setgid32,setgid::setgid(gid_t) + uid_t getuid32,getuid::getuid() + uid_t getxuid@dual0::getuid() + gid_t getgid32,getgid::getgid() + gid_t getxgid@dual0::getgid() + uid_t geteuid32,geteuid::geteuid() + uid_t getxuid@dual1::geteuid() + gid_t getegid32,getegid::getegid() + gid_t getxgid@dual1::getegid() +int getgroups32,getgroups::getgroups(int, gid_t *) +int setgroups32,setgroups::setgroups(size_t, const gid_t *) +int setreuid32,setreuid::setreuid(uid_t, uid_t) +int setregid32,setregid::setregid(gid_t, gid_t) +int setfsuid32,setfsuid::setfsuid(uid_t) +int setfsgid32,setfsgid::setfsgid(gid_t) +int setresuid32,setresuid::setresuid(int, uid_t, uid, uid_t) + +; +; Filesystem-related system calls +; +int mount(const char *, const char *, const char *, unsigned long, const void *) + int umount2(const char *, int) + int umount::umount2(const char *, int) + int pivot_root(const char *, const char *) +int sync() +#ifdef __NR_statfs64 +int statfs64::__statfs64(const char *, size_t, struct statfs *) +#else +int statfs(const char *, struct statfs *) +#endif +#ifdef __NR_fstatfs64 +int fstatfs64::__fstatfs64(int, size_t, struct statfs *) +#else +int fstatfs(int, struct statfs *) +#endif +int swapon(const char *, int) +int swapoff(const char *) + +; +; Inode-related system calls +; +int access(const char *, int) +int link(const char *, const char *) +int unlink(const char *) +int chdir(const char *) +int fchdir(int) +int rename(const char *, const char *) +int mknod(const char *, mode_t, dev_t) +int chmod(const char *, mode_t) +int fchmod(int, mode_t) +int mkdir(const char *, mode_t) +int rmdir(const char *) + int pipe(int *) +mode_t umask(mode_t) +int chroot(const char *) +int symlink(const char *, const char *) +int readlink(const char *, char *, size_t) +int stat64,stat::stat(const char *, struct stat *) +int lstat64,lstat::lstat(const char *, struct stat *) +int fstat64,fstat::fstat(int, struct stat *) +int getdents64,getdents::getdents(unsigned int, struct dirent *, unsigned int) +int chown32,chown::chown(const char *, uid_t, gid_t) +int fchown32,fchown::fchown(int, uid_t, gid_t) +int lchown32,lchown::lchown(const char *, uid_t, gid_t) +int getcwd::__getcwd(char *, size_t) + int utime(const char *, const struct utimbuf *) + int utimes(const char *, const struct timeval *) + +; +; I/O operations +; + int open::__open(const char *, int, mode_t) +<64> int open(const char *, int, mode_t) +ssize_t read(int, void *, size_t) +ssize_t write(int, const void *, size_t) +int close(int) +<64> off_t lseek(int, off_t, int) +<32> int _llseek::__llseek(int, unsigned long, unsigned long, off_t *, int) +int dup(int) +int dup2(int, int) + int fcntl64@varadic::fcntl(int, int, unsigned long) + int fcntl64,fcntl::fcntl(int, int, unsigned long) +int ioctl(int, int, void *) +int flock(int, int) +int _newselect,select::select(int, fd_set *, fd_set *, fd_set *, struct timeval *) +int poll(struct pollfd *, nfds_t, long) +int fsync(int) +int fdatasync,fsync::fdatasync(int) +int readv(int, const struct iovec *, int) +int writev(int, const struct iovec *, int) +int ftruncate64,ftruncate::ftruncate(int, off_t) +ssize_t pread64,pread::pread(int, void *, size_t, off_t) +ssize_t pwrite64,pwrite::pwrite(int, void *, size_t, off_t) + +; +; Signal operations +; +int kill(pid_t, int) + int sigaction(int, const struct sigaction *, struct sigaction *) +int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) + int sigsuspend(const sigset_t *) +int rt_sigsuspend(const sigset_t *, size_t) + int sigpending(sigset_t) +int rt_sigpending(sigset_t *, size_t) + int sigprocmask(int, const sigset_t *, sigset_t *) +int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t) + unsigned int alarm(unsigned int) +int getitimer(int, struct itimerval *) +int setitimer(int, const struct itimerval *, struct itimerval *) + +; +; Time-related system calls +; + time_t time(time_t *) +clock_t times(struct tms *) +int gettimeofday(struct timeval *, struct timezone *) +int settimeofday(const struct timeval *, const struct timezone *) +int nanosleep(const struct timespec *, struct timespec *) + int pause() + +; +; Memory +; +void * brk::__brk(void *) +int munmap(void *, size_t) +void * mremap(void *, size_t, size_t, unsigned long) +int msync(const void *, size_t, int) +int mprotect(const void *, size_t, int) +#if (BITSIZE == 32 && defined(__NR_mmap2)) || (BITSIZE == 64 && !defined(__NR_mmap)) + void * mmap2::__mmap2(void *, size_t, int, int, int, long) +#else + void * mmap(void *, size_t, int, int, int, long) +#endif +int mlockall(int) +int munlockall() +int mlock(const void *, size_t) +int munlock(const void *, size_t) + +; +; System stuff +; +int uname(struct utsname *) +int setdomainname(const char *, size_t) +int sethostname(const char *, size_t) +long init_module(void *, unsigned long, const char *) +long delete_module(const char *, unsigned int) +int reboot::__reboot(int, int, int, void *) +int syslog::klogctl(int, char *, int) +int sysinfo(struct sysinfo *) + +; +; Low-level I/O (generally architecture-specific) +; + int iopl(int) + int ioperm(unsigned long, unsigned long, int) + int vm86(struct vm86_struct *) + +; +; Most architectures have the socket interfaces using regular +; system calls. +; + long socketcall::__socketcall(int, const unsigned long *) +#include "SOCKETCALLS.def" diff --git a/klibc/klibc/__shared_init.c b/klibc/klibc/__shared_init.c index 63e3f4644e..592a3db6f5 100644 --- a/klibc/klibc/__shared_init.c +++ b/klibc/klibc/__shared_init.c @@ -1,56 +1,2 @@ -/* - * __shared_init.c - * - * This function takes the raw data block set up by the ELF loader - * in the kernel and parses it. It is invoked by crt0.S which makes - * any necessary adjustments and passes calls this function using - * the standard C calling convention. - * - * The arguments are: - * uintptr_t *elfdata -- The ELF loader data block; usually from the stack. - * Basically a pointer to argc. - * void (*onexit)(void) -- Function to install into onexit - */ - -#include -#include -#include -#include -#include - -char **environ; - -__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void)) -{ - int argc; - char **argv, **envp, **envend; - struct auxentry { - uintptr_t type; - uintptr_t v; - } *auxentry; - typedef int (*main_t)(int, char **, char **); - main_t main_ptr = NULL; - - (void)onexit; /* For now, we ignore this... */ - - argc = (int)*elfdata++; - argv = (char **)elfdata; - envp = argv+(argc+1); - - /* The auxillary entry vector is after all the environment vars */ - for ( envend = envp ; *envend ; envend++ ); - auxentry = (struct auxentry *)(envend+1); - - while ( auxentry->type ) { - if ( auxentry->type == AT_ENTRY ) { - main_ptr = (main_t)(auxentry->v); - break; - } - auxentry++; - } - - environ = envp; - exit(main_ptr(argc, argv, envp)); -} - - +#define SHARED 1 +#include "libc_init.c" diff --git a/klibc/klibc/__static_init.c b/klibc/klibc/__static_init.c index 5a90b5cd88..0b59eedaa7 100644 --- a/klibc/klibc/__static_init.c +++ b/klibc/klibc/__static_init.c @@ -1,38 +1,2 @@ -/* - * __static_init.c - * - * This function takes the raw data block set up by the ELF loader - * in the kernel and parses it. It is invoked by crt0.S which makes - * any necessary adjustments and passes calls this function using - * the standard C calling convention. - * - * The arguments are: - * uintptr_t *elfdata -- The ELF loader data block; usually from the stack. - * Basically a pointer to argc. - * void (*onexit)(void) -- Function to install into onexit - */ - -#include -#include -#include -#include -#include - -char **environ; - -extern int main(int, char **, char **); - -__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void)) -{ - int argc; - char **argv, **envp; - - (void)onexit; /* For now, we ignore this... */ - - argc = (int)*elfdata++; - argv = (char **)elfdata; - envp = argv+(argc+1); - - environ = envp; - exit(main(argc, argv, envp)); -} +#define SHARED 0 +#include "libc_init.c" diff --git a/klibc/klibc/alarm.c b/klibc/klibc/alarm.c index ca7bb37f92..40c0969432 100644 --- a/klibc/klibc/alarm.c +++ b/klibc/klibc/alarm.c @@ -5,11 +5,7 @@ #include #include -#ifdef __NR_alarm - -_syscall1(unsigned int,alarm,unsigned int,seconds); - -#else +#ifndef __NR_alarm /* Emulate alarm() via setitimer() */ diff --git a/klibc/klibc/arch/alpha/Makefile.inc b/klibc/klibc/arch/alpha/Makefile.inc index 2a1100f962..62fce9dc28 100644 --- a/klibc/klibc/arch/alpha/Makefile.inc +++ b/klibc/klibc/arch/alpha/Makefile.inc @@ -11,7 +11,7 @@ DIVCFLAGS = $(REQFLAGS) \ -O3 -fomit-frame-pointer -fcall-saved-1 -fcall-saved-2 \ -fcall-saved-3 -fcall-saved-4 -fcall-saved-5 -fcall-saved-6 \ - -fcall-saved-7 -fcall-saved-8 -fcall-saved-15 -fcall-saved-16 \ + -fcall-saved-7 -fcall-saved-8 -ffixed-15 -fcall-saved-16 \ -fcall-saved-17 -fcall-saved-18 -fcall-saved-19 -fcall-saved-20 \ -fcall-saved-21 -fcall-saved-22 -ffixed-23 -fcall-saved-24 \ -ffixed-25 -ffixed-27 @@ -26,7 +26,9 @@ ARCHOBJS = \ arch/$(ARCH)/__divl.o \ arch/$(ARCH)/__reml.o \ arch/$(ARCH)/pipe.o \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ + arch/$(ARCH)/sysdual.o ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) diff --git a/klibc/klibc/arch/alpha/crt0.S b/klibc/klibc/arch/alpha/crt0.S index 6c2958117d..904b539741 100644 --- a/klibc/klibc/arch/alpha/crt0.S +++ b/klibc/klibc/arch/alpha/crt0.S @@ -3,10 +3,10 @@ # .text - .type __start,@function - .ent __start, 0 - .globl __start -__start: + .type _start,@function + .ent _start, 0 + .globl _start +_start: .frame $30, 0, $26, 0 mov $31, $15 br $29, 1f @@ -18,4 +18,5 @@ __start: jsr $26, __libc_init - .size __start,.-__start + .size _start,.-_start + .end _start diff --git a/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h b/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h deleted file mode 100644 index 9dc570a6f5..0000000000 --- a/klibc/klibc/arch/alpha/include/klibc/archsetjmp.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/alpha/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __s0; - unsigned long __s1; - unsigned long __s2; - unsigned long __s3; - unsigned long __s4; - unsigned long __s5; - unsigned long __fp; - unsigned long __ra; - unsigned long __gp; - unsigned long __sp; - - unsigned long __f2; - unsigned long __f3; - unsigned long __f4; - unsigned long __f5; - unsigned long __f6; - unsigned long __f7; - unsigned long __f8; - unsigned long __f9; -}; - -/* Must be an array so it will decay to a pointer when a function is called */ -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/klibc/arch/alpha/include/klibc/archsignal.h b/klibc/klibc/arch/alpha/include/klibc/archsignal.h deleted file mode 100644 index b870a05131..0000000000 --- a/klibc/klibc/arch/alpha/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/alpha/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/alpha/include/klibc/archsys.h b/klibc/klibc/arch/alpha/include/klibc/archsys.h deleted file mode 100644 index 16ed658987..0000000000 --- a/klibc/klibc/arch/alpha/include/klibc/archsys.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * arch/alpha/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* Alpha has some bizarre Tru64-derived system calls which return two - different values in $0 and $20(!), respectively. The standard - macros can't deal with these; even the ones that give the right - return value have the wrong clobbers. */ - -#define _syscall0_dual0(type, name) \ -type name(void) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_19 __asm__("$19"); \ - register long _sc_20 __asm__("$20"); \ - \ - _sc_0 = __NR_##name; \ - __asm__("callsys" \ - : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ - : "0"(_sc_0) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; (void)(_sc_20); \ - } \ - _syscall_return(type); \ -} - -#define _syscall0_dual1(type, name) \ -type name(void) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_19 __asm__("$19"); \ - register long _sc_20 __asm__("$20"); \ - \ - _sc_0 = __NR_##name; \ - __asm__("callsys" \ - : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ - : "0"(_sc_0) \ - : _syscall_clobbers); \ - _sc_ret = _sc_20, _sc_err = _sc_19; (void)(_sc_0); \ - } \ - _syscall_return(type); \ -} - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/alpha/include/machine/asm.h b/klibc/klibc/arch/alpha/include/machine/asm.h deleted file mode 100644 index e22db90412..0000000000 --- a/klibc/klibc/arch/alpha/include/machine/asm.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * machine/asm.h - */ - -#ifndef _MACHINE_ASM_H -#define _MACHINE_ASM_H - -/* Standard aliases for Alpha register names */ - -#define v0 $0 -#define t0 $1 -#define t1 $2 -#define t2 $3 -#define t3 $4 -#define t4 $5 -#define t5 $6 -#define t6 $7 -#define t7 $8 -#define s0 $9 -#define s1 $10 -#define s2 $11 -#define s3 $12 -#define s4 $13 -#define s5 $14 -#define fp $15 -#define a0 $16 -#define a1 $17 -#define a2 $18 -#define a3 $19 -#define a4 $20 -#define a5 $21 -#define t8 $22 -#define t9 $23 -#define t10 $24 -#define t11 $25 -#define ra $26 -#define t12 $27 /* t12 and pv are both used for $27 */ -#define pv $27 /* t12 and pv are both used for $27 */ -#define at $28 -#define gp $29 -#define sp $30 -#define zero $31 - -#endif /* _MACHINE_ASM_H */ diff --git a/klibc/klibc/arch/alpha/setjmp.S b/klibc/klibc/arch/alpha/setjmp.S index e1ad642539..5d915f2dbe 100644 --- a/klibc/klibc/arch/alpha/setjmp.S +++ b/klibc/klibc/arch/alpha/setjmp.S @@ -31,14 +31,14 @@ setjmp: stq ra, 56(a0) stq gp, 64(a0) stq sp, 72(a0) - stt f2, 80(a0) - stt f3, 88(a0) - stt f4, 96(a0) - stt f5, 104(a0) - stt f6, 112(a0) - stt f7, 120(a0) - stt f8, 128(a0) - stt f9, 136(a0) + stt $f2, 80(a0) + stt $f3, 88(a0) + stt $f4, 96(a0) + stt $f5, 104(a0) + stt $f6, 112(a0) + stt $f7, 120(a0) + stt $f8, 128(a0) + stt $f9, 136(a0) ret zero,(ra),1 .size setjmp,.-setjmp @@ -59,14 +59,14 @@ longjmp: ldq ra, 56(a0) ldq gp, 64(a0) ldq sp, 72(a0) - ldt f2, 80(a0) - ldt f3, 88(a0) - ldt f4, 96(a0) - ldt f5, 104(a0) - ldt f6, 112(a0) - ldt f7, 120(a0) - ldt f8, 128(a0) - ldt f9, 136(a0) + ldt $f2, 80(a0) + ldt $f3, 88(a0) + ldt $f4, 96(a0) + ldt $f5, 104(a0) + ldt $f6, 112(a0) + ldt $f7, 120(a0) + ldt $f8, 128(a0) + ldt $f9, 136(a0) /* We're bound to get a mispredict here, but at least give us a chance to get the return stack back in sync... */ ret zero,(ra),1 diff --git a/klibc/klibc/arch/alpha/syscall.S b/klibc/klibc/arch/alpha/syscall.S new file mode 100644 index 0000000000..0c87414b1a --- /dev/null +++ b/klibc/klibc/arch/alpha/syscall.S @@ -0,0 +1,26 @@ +# +# arch/alpha/syscall.S +# + +#include + + .text + .align 3 + .type __syscall_common,@function + .ent __syscall_common, 0 + .globl __syscall_common +__syscall_common: + .frame sp,0,ra,0 + callsys + beq a3, 1f + br pv, 2f # pv <- pc +2: + ldgp gp, 0(pv) + lda a1, errno + lda v0, -1(zero) + stl a3, 0(a1) +1: + ret zero,(ra),1 + + .size __syscall_common,.-__syscall_common + .end __syscall_common diff --git a/klibc/klibc/arch/alpha/sysdual.S b/klibc/klibc/arch/alpha/sysdual.S new file mode 100644 index 0000000000..c00db88960 --- /dev/null +++ b/klibc/klibc/arch/alpha/sysdual.S @@ -0,0 +1,33 @@ +# +# arch/alpha/sysdual.S +# + +# +# Some system calls have an alternate return value in r20 (a4). +# This system call stub is for system calls where that is +# the "real" return value. +# + +#include + + .text + .align 3 + .type __syscall_dual1,@function + .ent __syscall_dual1, 0 + .globl __syscall_dual1 +__syscall_dual1: + .frame sp,0,ra,0 + callsys + mov v0, a4 + beq a3, 1f + br pv, 2f # pv <- pc +2: + ldgp gp, 0(pv) + lda a1, errno + lda v0, -1(zero) + stl a3, 0(a1) +1: + ret zero,(ra),1 + + .size __syscall_dual1,.-__syscall_dual1 + .end __syscall_dual1 diff --git a/klibc/klibc/arch/alpha/sysstub.ph b/klibc/klibc/arch/alpha/sysstub.ph new file mode 100644 index 0000000000..a24b6c07dc --- /dev/null +++ b/klibc/klibc/arch/alpha/sysstub.ph @@ -0,0 +1,37 @@ +# -*- perl -*- +# +# arch/alpha/sysstub.ph +# +# Script to generate system call stubs +# + +# On Alpha, most system calls follow the standard convention, with the +# system call number in r0 (v0), return an error value in r19 (a3) as +# well as the return value in r0 (v0). +# +# A few system calls are dual-return with the second return value in +# r20 (a4). + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + $stype = $stype || 'common'; + $stype = 'common' if ( $stype eq 'dual0' ); + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.text\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.ent\t${fname}, 0\n"; # What is this? + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT "\tlda\tv0, __NR_${sname}(zero)\n"; + print OUT "\tbr __syscall_${stype}\n"; + print OUT "\t.size\t${fname},.-${fname}\n"; + print OUT "\t.end\t${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/arm/Makefile.inc b/klibc/klibc/arch/arm/Makefile.inc index 3ec8c051b2..0603d850bd 100644 --- a/klibc/klibc/arch/arm/Makefile.inc +++ b/klibc/klibc/arch/arm/Makefile.inc @@ -17,7 +17,8 @@ ARCHOBJS = \ libgcc/__moddi3.o \ libgcc/__udivdi3.o \ libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o + libgcc/__udivmoddi4.o \ + arch/arm/syscall.o ifeq ($(THUMB),y) ARCHOBJS += arch/arm/setjmp-thumb.o @@ -26,6 +27,17 @@ else ARCHOBJS += arch/arm/setjmp-arm.o endif +arch/arm/sysstubs.a: arch/arm/sysstubs.pl + mkdir -p arch/arm/sysstubs + $(PERL) $< arch/arm/sysstubs + $(MAKE) $(patsubst %.S,%.o,$(wildcard arch/arm/sysstubs/*.S)) + -rm -f $@ + $(AR) cq $@ arch/arm/sysstubs/*.o + $(RANLIB) $@ + + ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) archclean: + -rm -rf arch/arm/sysstubs + -rm -f arch/arm/sysstubs.a diff --git a/klibc/klibc/arch/arm/crt0.S b/klibc/klibc/arch/arm/crt0.S index 8cd3640c30..fc1104ef0e 100644 --- a/klibc/klibc/arch/arm/crt0.S +++ b/klibc/klibc/arch/arm/crt0.S @@ -3,10 +3,8 @@ # # void _start(void) # { -# /* Divine up argc, argv, and envp */ -# environ = envp; -# exit(main(argc, argv, envp)); -# } +# __libc_init(elf_structure, atexit_ptr); +# } # .text diff --git a/klibc/klibc/arch/arm/include/klibc/archsetjmp.h b/klibc/klibc/arch/arm/include/klibc/archsetjmp.h deleted file mode 100644 index c956b50a90..0000000000 --- a/klibc/klibc/arch/arm/include/klibc/archsetjmp.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * arch/i386/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned int regs[10]; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/arm/include/klibc/archsignal.h b/klibc/klibc/arch/arm/include/klibc/archsignal.h deleted file mode 100644 index 77685e62f0..0000000000 --- a/klibc/klibc/arch/arm/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/arm/include/klibc/archsys.h b/klibc/klibc/arch/arm/include/klibc/archsys.h deleted file mode 100644 index 1a77e53a65..0000000000 --- a/klibc/klibc/arch/arm/include/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/arm/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/arm/setjmp-arm.S b/klibc/klibc/arch/arm/setjmp-arm.S index bcb30b4221..1a29ee7f71 100644 --- a/klibc/klibc/arch/arm/setjmp-arm.S +++ b/klibc/klibc/arch/arm/setjmp-arm.S @@ -34,7 +34,6 @@ setjmp: .type longjmp, #function longjmp: ldmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr} - movs r0, r1 - moveq r0, #1 + mov r0, r1 mov pc, lr .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/arm/syscall.S b/klibc/klibc/arch/arm/syscall.S new file mode 100644 index 0000000000..0e73f68ed0 --- /dev/null +++ b/klibc/klibc/arch/arm/syscall.S @@ -0,0 +1,50 @@ +/* + * arch/arm/syscall.S + * + * System call common handling + */ + + .type __syscall_common,#function + .globl __syscall_common +#ifndef __thumb__ + /* ARM version - this is executed after the swi */ + + .align 4 +__syscall_common: + cmn r0, #4096 + rsbcs r2, r0, #0 + ldrcs r3, 1f + mvncs r0, #0 + strcs r2, [r3] + ldmfd sp!,{r4,r5,pc} + + .align 4 +1: + .word errno + +#else + /* Thumb version - must still load r4 and r5 and run swi */ + + .thumb_func + .align 2 +__syscall_common: + ldr r4, [sp #12] + ldr r5, [sp #16] + swi 0 + ldr r1, 2f + cmp r0, r1 + bcc 1f + ldr r1, 3f + neg r2, r0 + mvn r0, #0 + str r2, [r1] +1: + pop {r4,r5,r7,pc} + + .align 4 +2: + .word #-4095 +3: + .word errno + +#endif diff --git a/klibc/klibc/arch/arm/sysstub.ph b/klibc/klibc/arch/arm/sysstub.ph new file mode 100644 index 0000000000..bf953ccd80 --- /dev/null +++ b/klibc/klibc/arch/arm/sysstub.ph @@ -0,0 +1,44 @@ +# -*- perl -*- +# +# arch/arm/sysstub.ph +# +# Script to generate system call stubs +# + + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + + print OUT "\t.text\n"; + print OUT "\t.type\t${fname}, #function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "\t.align\t4\n"; + + print OUT "#ifndef __thumb__\n"; + + # ARM version first + print OUT "${fname}:\n"; + print OUT "\tstmfd\tsp!,{r4,r5,lr}\n"; + print OUT "\tldr\tr4,[sp,#12]\n"; + print OUT "\tldr\tr5,[sp,#16]\n"; + print OUT "\tswi\t# __NR_${sname}\n"; + print OUT "\tb\t__syscall_common\n"; + + print OUT "#else\n"; + + # Thumb version + print OUT "\t.thumb_func\n"; + print OUT "${fname}:\n"; + print OUT "\tpush\t{r4,r5,r7,pc}\n"; + print OUT "\tmov\tr7, # __NR_${sname}\n"; + print OUT "\tb\t__syscall_common\n"; + + print OUT "#endif\n"; + + print OUT "\t.size\t__syscall${i},.-__syscall${i}\n"; +} + +1; diff --git a/klibc/klibc/arch/cris/MCONFIG b/klibc/klibc/arch/cris/MCONFIG index 27809ebbe7..2762494a30 100644 --- a/klibc/klibc/arch/cris/MCONFIG +++ b/klibc/klibc/arch/cris/MCONFIG @@ -9,3 +9,18 @@ OPTFLAGS = -Os -fomit-frame-pointer BITSIZE = 32 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 224 MB - normal binaries start at 0 +# (lib?)gcc on cris seems to insist on producing .init and .fini sections +SHAREDFLAGS = --section-start .init=0x0e000100 + +# The CRIS compiler needs an -iprefix to find libgcc includes when +# nostdinc is used. It also needs -mlinux to compile linux applications. +INCLUDE_PREFIX = $(shell $(CC) -print-libgcc-file-name | sed -e s/libgcc.a//) +ARCHREQFLAGS = -iprefix $(INCLUDE_PREFIX) -mlinux + +# Special flags needed for linking +LDFLAGS += -mcrislinux diff --git a/klibc/klibc/arch/cris/Makefile.inc b/klibc/klibc/arch/cris/Makefile.inc index 41183fd64b..75fa17ba99 100644 --- a/klibc/klibc/arch/cris/Makefile.inc +++ b/klibc/klibc/arch/cris/Makefile.inc @@ -7,4 +7,27 @@ # accordingly. # +ARCHOBJS = \ + arch/$(ARCH)/__Umod.o \ + arch/$(ARCH)/__Udiv.o \ + arch/$(ARCH)/__Mod.o \ + arch/$(ARCH)/__Div.o \ + arch/$(ARCH)/__negdi2.o \ + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o + +arch/$(ARCH)/__Umod.o: arch/$(ARCH)/divide.c + $(CC) $(CFLAGS) -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__Umod -c -o $@ $< +arch/$(ARCH)/__Udiv.o: arch/$(ARCH)/divide.c + $(CC) $(CFLAGS) -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__Udiv -c -o $@ $< +arch/$(ARCH)/__Mod.o: arch/$(ARCH)/divide.c + $(CC) $(CFLAGS) -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__Mod -c -o $@ $< +arch/$(ARCH)/__Div.o: arch/$(ARCH)/divide.c + $(CC) $(CFLAGS) -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__Div -c -o $@ $< + archclean: diff --git a/klibc/klibc/arch/cris/__negdi2.S b/klibc/klibc/arch/cris/__negdi2.S new file mode 100644 index 0000000000..3cca9edfa8 --- /dev/null +++ b/klibc/klibc/arch/cris/__negdi2.S @@ -0,0 +1,25 @@ +/* + * arch/cris/__negdi2.c + */ + +/* + * In 2's complement arithmetric, -x == (~x + 1), so + * -{h,l} = (~{h,l} + {0,1) + * -{h,l} = {~h,~l} + {0,1} + * -{h,l} = {~h + cy, ~l + 1} + * ... where cy = (l == 0) + * -{h,l} = {~h + cy, -l} + */ + + .text + .balign 4 + .type __negdi2,@function + .globl __negdi2 +__negdi2: + neg.d $r10,$r10 + seq $r12 + not $r11 + ret + add.d $r12,$r11 + + .size __negdi2, .-__negdi2 diff --git a/klibc/klibc/arch/cris/crt0.S b/klibc/klibc/arch/cris/crt0.S new file mode 100644 index 0000000000..989c82b2ba --- /dev/null +++ b/klibc/klibc/arch/cris/crt0.S @@ -0,0 +1,28 @@ +# +# arch/cris/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + + .text + .balign 4 + .type _start,@function + .globl _start +_start: + /* Save the address of the ELF argument array */ + move.d $sp,$r10 /* Address of ELF arguments */ + + /* atexit() function (assume null) */ + moveq 0,$r11 + + /* Set up a dummy stack frame to keep gcc from getting confused */ + push $r11 + push $r11 + jump __libc_init + + .size _start, .-_start + diff --git a/klibc/klibc/arch/cris/divide.c b/klibc/klibc/arch/cris/divide.c new file mode 100644 index 0000000000..29081dc953 --- /dev/null +++ b/klibc/klibc/arch/cris/divide.c @@ -0,0 +1,92 @@ +#include +#include + +#if BITS == 64 +typedef uint64_t unum; +typedef int64_t snum; +#else +typedef uint32_t unum; +typedef int32_t snum; +#endif + +#ifdef SIGNED +typedef snum xnum; +#else +typedef unum xnum; +#endif + +#ifdef __cris__ +static inline unum __attribute__((const)) dstep(unum rs, unum rd) { + asm("dstep %1,%0" : "+r" (rd) : "r" (rs)); + return rd; +} + +static inline unum __attribute__((const)) lz(unum rs) { + unum rd; + asm("lz %1,%0" : "=r" (rd) : "r" (rs)); + return rd; +} + +#else +/* For testing */ +static inline unum __attribute__ ((const)) dstep(unum rs, unum rd) { + rd <<= 1; + if ( rd >= rs ) + rd -= rs; + + return rd; +} + +static inline unum __attribute__((const)) lz(unum rs) { + unum rd = 0; + while ( rs >= 0x7fffffff ) { + rd++; + rs <<= 1; + } + return rd; +} + +#endif + +xnum NAME (unum num, unum den) +{ + unum quot = 0, qbit = 1; + int minus = 0; + xnum v; + + if ( den == 0 ) { + raise(SIGFPE); + return 0; /* If signal ignored... */ + } + + if (den == 1) return (xnum)(REM ? 0 : num); + +#if SIGNED + if ( (snum)(num^den) < 0 ) + minus = 1; + if ( (snum)num < 0 ) num = -num; + if ( (snum)den < 0 ) den = -den; +#endif + + den--; + + + /* Left-justify denominator and count shift */ + while ( (snum)den >= 0 ) { + den <<= 1; + qbit <<= 1; + } + + while ( qbit ) { + if ( den <= num ) { + num -= den; + quot += qbit; + } + den >>= 1; + qbit >>= 1; + } + + v = (xnum)(REM ? num : quot); + if ( minus ) v = -v; + return v; +} diff --git a/klibc/klibc/arch/cris/include/klibc/archsignal.h b/klibc/klibc/arch/cris/include/klibc/archsignal.h deleted file mode 100644 index 73b2e196c9..0000000000 --- a/klibc/klibc/arch/cris/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/cris/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/cris/include/klibc/archsys.h b/klibc/klibc/arch/cris/include/klibc/archsys.h deleted file mode 100644 index dfdc70a6de..0000000000 --- a/klibc/klibc/arch/cris/include/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/cris/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/cris/setjmp.S b/klibc/klibc/arch/cris/setjmp.S new file mode 100644 index 0000000000..43162418af --- /dev/null +++ b/klibc/klibc/arch/cris/setjmp.S @@ -0,0 +1,37 @@ +# +# arch/cris/setjmp.S +# +# setjmp/longjmp for the cris architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# $r8..$r0 (in that order) +# $sp ($r14) +# return address +# + + .text + .balign 4 + .globl setjmp + .type setjmp, @function +setjmp: + movem $r8,[$r10+] /* Save $r8..$r0 at $r10... */ + move.d $sp,[$r10+] + move $srp,[$r10] + ret + moveq 0,$r10 + + .size setjmp,.-setjmp + + .text + .balign 4 + .globl longjmp + .type longjmp, @function +longjmp: + movem [$r10+],$r8 /* Load $r8..$r0 from $r10... */ + move.d [$r10+],$sp + jump [$r10] + move.d $r11,$r10 + + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/cris/syscall.S b/klibc/klibc/arch/cris/syscall.S new file mode 100644 index 0000000000..d71495aba2 --- /dev/null +++ b/klibc/klibc/arch/cris/syscall.S @@ -0,0 +1,30 @@ +/* + * arch/cris/syscall.S + * + * On cris, r9 contains the syscall number (set by generated stub); + * r10..r13 contain arguments 0-3 per the standard calling convention, + * and arguments 4-5 are passed in $mof and $srp; however, we have + * to save $srp around the system call. + */ + + .section ".text","ax" + .balign 4 + .globl __syscall_common + .type __syscall_common,@function +__syscall_common: + push $srp + move [$sp+4],$mof + move [$sp+8],$srp + break 13 + + cmps.w -4096,$r10 + blo 1f + neg.d $r10,$r11 + move.d $r11,[errno] + moveq -1,$r10 +1: + pop $srp + ret + nop + + .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/cris/sysstub.ph b/klibc/klibc/arch/cris/sysstub.ph new file mode 100644 index 0000000000..6c894f62f5 --- /dev/null +++ b/klibc/klibc/arch/cris/sysstub.ph @@ -0,0 +1,29 @@ +# -*- perl -*- +# +# arch/cris/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.text\n"; + print OUT "\t.type\t${fname},\@function\n"; + print OUT "\t.globl\t${fname}\n"; + print OUT "\t.balign\t4\n"; + print OUT "${fname}:\n"; + print OUT "#if __NR_${sname} <= 31\n"; + print OUT "\t moveq\t__NR_${sname}, \$r9\n"; + print OUT "#else\n"; + print OUT "\t move.d\t__NR_${sname}, \$r9\n"; + print OUT "#endif\n"; + print OUT "\tjump\t__syscall_common\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG index 516b1b6738..2421452eea 100644 --- a/klibc/klibc/arch/i386/MCONFIG +++ b/klibc/klibc/arch/i386/MCONFIG @@ -9,11 +9,11 @@ # Enable this to compile with register parameters; only safe for # gcc > 3 -REGPARM_OPT := -mregparm=3 -DREGPARM +REGPARM_OPT := -mregparm=3 -DREGPARM=3 -gcc_major := $(shell $(CC) -v 2>&1 | awk '/gcc version/{print int($$3)}') +gcc_major := $(shell echo __GNUC__ | $(CC) -E -xc - | tail -n 1) -OPTFLAGS = $(REGPARM) -march=i386 -Os +OPTFLAGS = $(REGPARM) -march=i386 -Os -g ifeq ($(gcc_major),3) REGPARM := $(REGPARM_OPT) diff --git a/klibc/klibc/arch/i386/Makefile.inc b/klibc/klibc/arch/i386/Makefile.inc index 171248a796..5c320cb453 100644 --- a/klibc/klibc/arch/i386/Makefile.inc +++ b/klibc/klibc/arch/i386/Makefile.inc @@ -11,6 +11,8 @@ ARCHOBJS = \ arch/$(ARCH)/exits.o \ arch/$(ARCH)/socketcall.o \ arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ + arch/$(ARCH)/open.o \ arch/$(ARCH)/libgcc/__ashldi3.o \ arch/$(ARCH)/libgcc/__ashrdi3.o \ arch/$(ARCH)/libgcc/__lshrdi3.o \ @@ -22,6 +24,4 @@ ARCHOBJS = \ libgcc/__umoddi3.o \ libgcc/__udivmoddi4.o -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - archclean: diff --git a/klibc/klibc/arch/i386/include/klibc/archsetjmp.h b/klibc/klibc/arch/i386/include/klibc/archsetjmp.h deleted file mode 100644 index db04314b8c..0000000000 --- a/klibc/klibc/arch/i386/include/klibc/archsetjmp.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/i386/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned int __ebx; - unsigned int __esp; - unsigned int __ebp; - unsigned int __esi; - unsigned int __edi; - unsigned int __eip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/i386/include/klibc/archsignal.h b/klibc/klibc/arch/i386/include/klibc/archsignal.h deleted file mode 100644 index b092ba6d3a..0000000000 --- a/klibc/klibc/arch/i386/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/i386/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/i386/include/klibc/archsys.h b/klibc/klibc/arch/i386/include/klibc/archsys.h deleted file mode 100644 index e21487b256..0000000000 --- a/klibc/klibc/arch/i386/include/klibc/archsys.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * arch/i386/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* - * If we're compiling i386 in PIC mode, we need to treat %ebx - * specially. Most of these are copied from the equivalent file in - * newlib and were written by Werner Almesberger. - */ -#if defined(__PIC__) - -/* _syscall0() is the same as non-PIC */ - -#undef _syscall1 -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -long __res; \ -__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"r" ((long)(arg1))); \ -__syscall_return(type,__res); \ -} - -#undef _syscall2 -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -long __res; \ -__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2))); \ -__syscall_return(type,__res); \ -} - -#undef _syscall3 -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ - "d" ((long)(arg3))); \ -__syscall_return(type,__res); \ -} - -#undef _syscall4 -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -long __res; \ -__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"r" ((long)(arg1)),"c" ((long)(arg2)), \ - "d" ((long)(arg3)),"S" ((long)(arg4))); \ -__syscall_return(type,__res); \ -} - -#undef _syscall5 -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -__asm__ __volatile__ ("push %%ebx; movl %2,%%ebx; int $0x80; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \ - "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \ -__syscall_return(type,__res); \ -} - -#undef _syscall6 -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ -long __res; \ -__asm__ __volatile__ ("push %%ebx; pushl %%ebp; movl %2,%%ebx; " \ - "movl %%eax,%%ebp; movl %1,%%eax; int $0x80; " \ - "pop %%ebp ; pop %%ebx" \ - : "=a" (__res) \ - : "i" (__NR_##name),"m" ((long)(arg1)),"c" ((long)(arg2)), \ - "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)), \ - "a" ((long)(arg6))); \ -__syscall_return(type,__res); \ -} - -#endif /* __PIC__ */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/i386/include/klibc/diverr.h b/klibc/klibc/arch/i386/include/klibc/diverr.h deleted file mode 100644 index 410aba06d3..0000000000 --- a/klibc/klibc/arch/i386/include/klibc/diverr.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/i386/include/klibc/diverr.h - */ - -#ifndef _KLIBC_DIVERR_H -#define _KLIBC_DIVERR_H - -#include - -static __inline__ void -__divide_error(void) -{ - asm volatile("divl %0" :: "rm" (0) : "eax", "edx"); -} - -#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/klibc/arch/i386/include/sys/io.h b/klibc/klibc/arch/i386/include/sys/io.h deleted file mode 100644 index b051464dfc..0000000000 --- a/klibc/klibc/arch/i386/include/sys/io.h +++ /dev/null @@ -1,126 +0,0 @@ -#ident "$Id: io.h,v 1.2 2004/01/25 07:49:39 hpa Exp $" -/* ----------------------------------------------------------------------- * - * - * Copyright 2004 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * sys/io.h for the i386 architecture - * - * Basic I/O macros - */ - -#ifndef _SYS_IO_H -#define _SYS_IO_H 1 - -/* I/O-related system calls */ - -int iopl(int); -int ioperm(unsigned long, unsigned long, int); - -/* Basic I/O macros */ - -static __inline__ void -outb(unsigned char __v, unsigned short __p) -{ - asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outw(unsigned short __v, unsigned short __p) -{ - asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outl(unsigned int __v, unsigned short __p) -{ - asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ unsigned char -inb(unsigned short __p) -{ - unsigned char __v; - asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); - return __v; -} - -static __inline__ unsigned short -inw(unsigned short __p) -{ - unsigned short __v; - asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); - return __v; -} - -static __inline__ unsigned int -inl(unsigned short __p) -{ - unsigned int __v; - asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); - return __v; -} - -/* String I/O macros */ - -static __inline__ void -outsb (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsw (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsl (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - - -static __inline__ void -insb (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insw (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insl (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -#endif /* _SYS_IO_H */ diff --git a/klibc/klibc/arch/i386/include/sys/vm86.h b/klibc/klibc/arch/i386/include/sys/vm86.h deleted file mode 100644 index d3272393dc..0000000000 --- a/klibc/klibc/arch/i386/include/sys/vm86.h +++ /dev/null @@ -1,41 +0,0 @@ -#ident "$Id: vm86.h,v 1.1 2004/01/25 01:34:28 hpa Exp $" -/* ----------------------------------------------------------------------- * - * - * Copyright 2004 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * sys/vm86.h for i386 - */ - -#ifndef _SYS_VM86_H -#define _SYS_VM86_H 1 - -#include - -/* Actual system call */ -int vm86(struct vm86_struct *); - -#endif diff --git a/klibc/klibc/arch/i386/open.S b/klibc/klibc/arch/i386/open.S new file mode 100644 index 0000000000..4f492a1566 --- /dev/null +++ b/klibc/klibc/arch/i386/open.S @@ -0,0 +1,29 @@ +/* + * arch/i386/open.S + * + * Handle the open() system call - oddball due to the varadic + * prototype, which forces the use of the cdecl calling convention, + * and the need for O_LARGEFILE. + */ + +#include + +/* , despite the name, isn't assembly-safe */ +#define O_LARGEFILE 0100000 + + .globl open + .type open,@function + +open: +#ifdef REGPARM + movl 4(%esp),%eax + movl 8(%esp),%edx + movl 12(%esp),%ecx + orl $O_LARGEFILE,%edx +#else + orl $O_LARGEFILE,8(%esp) +#endif + pushl $__NR_open + jmp __syscall_common + + .size open,.-open diff --git a/klibc/klibc/arch/i386/socketcall.S b/klibc/klibc/arch/i386/socketcall.S index 6bac1e6913..b13d204c32 100644 --- a/klibc/klibc/arch/i386/socketcall.S +++ b/klibc/klibc/arch/i386/socketcall.S @@ -16,18 +16,22 @@ .type __socketcall_common, @function __socketcall_common: - pushl %ebx - movzbl %al,%ebx # The socketcall number is passed in in %al - leal 8(%esp),%ecx # Argument pointer - movl $__NR_socketcall, %eax - int $0x80 - cmpl $-125,%eax # Error return? - popl %ebx - jb 1f - neg %eax - movl %eax,errno - xorl %eax,%eax - decl %eax # Return = -1 + pushl %ebx + + movzbl %al,%ebx # The socketcall number is passed in in %al + leal 8(%esp),%ecx # Argument pointer + movl $__NR_socketcall,%eax + int $0x80 + + cmpl $-4096,%eax # Error return? + + popl %ebx + + jb 1f + + negl %eax + movl %eax,errno + orl $-1,%eax # Return -1 1: ret diff --git a/klibc/klibc/arch/i386/syscall.S b/klibc/klibc/arch/i386/syscall.S new file mode 100644 index 0000000000..f8fa7b4dd3 --- /dev/null +++ b/klibc/klibc/arch/i386/syscall.S @@ -0,0 +1,60 @@ +/* + * arch/i386/syscall.S + * + * Common tail-handling code for system calls. Because of __syscalldecl + * we are using the stack even on if we are compiling with regparm. + * + * The arguments are on the stack; the system call number in %eax. + */ + +#define ARG(n) (4*n+20)(%esp) + + .text + .align 4 + .globl __syscall_common + .type __syscall_common,@function +__syscall_common: +#ifdef REGPARM + xchgl %ebx,(%esp) +#else + popl %eax + pushl %ebx +#endif + pushl %esi + pushl %edi + pushl %ebp + +#ifdef REGPARM + xchgl %eax,%ebx + xchgl %ecx,%edx + movl ARG(0),%esi + movl ARG(1),%edi + movl ARG(2),%ebp +#else + movl ARG(0),%ebx # Syscall arguments + movl ARG(1),%ecx + movl ARG(2),%edx + movl ARG(3),%esi + movl ARG(4),%edi + movl ARG(5),%ebp +#endif + int $0x80 + + cmpl $-4096,%eax + + popl %ebp + popl %edi + popl %esi + popl %ebx + + jb 1f + + # Error return, must set errno + negl %eax + movl %eax,errno + orl $-1,%eax # Return -1 + +1: + ret + + .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/i386/sysstub.ph b/klibc/klibc/arch/i386/sysstub.ph new file mode 100644 index 0000000000..eaa8180911 --- /dev/null +++ b/klibc/klibc/arch/i386/sysstub.ph @@ -0,0 +1,32 @@ +# -*- perl -*- +# +# arch/i386/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + + if ( $stype eq 'varadic' ) { + print OUT "#ifdef REGPARM\n"; + print OUT "\tmovl 4(%esp),%eax\n"; + print OUT "\tmovl 8(%esp),%edx\n"; + print OUT "\tmovl 12(%esp),%ecx\n"; + print OUT "#endif\n"; + } + + print OUT "\tpushl \$__NR_${sname}\n"; + print OUT "\tjmp __syscall_common\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/ia64/Makefile.inc b/klibc/klibc/arch/ia64/Makefile.inc index 781448770e..6363c1f948 100644 --- a/klibc/klibc/arch/ia64/Makefile.inc +++ b/klibc/klibc/arch/ia64/Makefile.inc @@ -11,6 +11,7 @@ ARCHOBJS = \ arch/$(ARCH)/vfork.o \ arch/$(ARCH)/setjmp.o \ arch/$(ARCH)/pipe.o \ + arch/$(ARCH)/syscall.o \ libgcc/__divdi3.o \ libgcc/__divsi3.o \ libgcc/__udivdi3.o \ diff --git a/klibc/klibc/arch/ia64/include/klibc/archsetjmp.h b/klibc/klibc/arch/ia64/include/klibc/archsetjmp.h deleted file mode 100644 index bd639c0b00..0000000000 --- a/klibc/klibc/arch/ia64/include/klibc/archsetjmp.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/ia64/include/klibc/archsetjmp.h - * - * Code borrowed from the FreeBSD kernel. - * - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -/* User code must not depend on the internal representation of jmp_buf. */ -#define _JBLEN 0x200 - -/* guaranteed 128-bit alignment! */ -typedef char jmp_buf[_JBLEN] __attribute__ ((aligned (16))); - -#endif diff --git a/klibc/klibc/arch/ia64/include/klibc/archsignal.h b/klibc/klibc/arch/ia64/include/klibc/archsignal.h deleted file mode 100644 index 5b01f19bc2..0000000000 --- a/klibc/klibc/arch/ia64/include/klibc/archsignal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/ia64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions. - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -#define _NSIG 64 -#define _NSIG_BPW 64 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - int sa_flags; -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif diff --git a/klibc/klibc/arch/ia64/include/klibc/archsys.h b/klibc/klibc/arch/ia64/include/klibc/archsys.h deleted file mode 100644 index fe331acf55..0000000000 --- a/klibc/klibc/arch/ia64/include/klibc/archsys.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * arch/ia64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -#define __IA64_BREAK "break 0x100000;;\n\t" - -#define _syscall0(type,name) \ -type \ -name (void) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15) \ - : "2" (_r15) ASM_ARGS_0 \ - : "memory" ASM_CLOBBERS_0); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return _retval; \ -} - -#define _syscall1(type,name,type1,arg1) \ -type \ -name (type1 arg1) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_1(arg1); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_1 \ - : "2" (_r15) ASM_ARGS_1 \ - : "memory" ASM_CLOBBERS_1); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return _retval; \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type \ -name (type1 arg1, type2 arg2) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_2(arg1, arg2); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_2 \ - : "2" (_r15) ASM_ARGS_2 \ - : "memory" ASM_CLOBBERS_2); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return _retval; \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_3(arg1, arg2, arg3); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_3 \ - : "2" (_r15) ASM_ARGS_3 \ - : "memory" ASM_CLOBBERS_3); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return _retval; \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_4(arg1, arg2, arg3, arg4); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_4 \ - : "2" (_r15) ASM_ARGS_4 \ - : "memory" ASM_CLOBBERS_4); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return _retval; \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_5(arg1, arg2, arg3, arg4, arg5); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_5 \ - : "2" (_r15) ASM_ARGS_5 \ - : "memory" ASM_CLOBBERS_5); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return _retval; \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_6 \ - : "2" (_r15) ASM_ARGS_6 \ - : "memory" ASM_CLOBBERS_6); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return _retval; \ -} - - -#define LOAD_ARGS_0() do { } while (0) -#define LOAD_ARGS_1(out0) \ - register long _out0 asm ("out0") = (long) (out0); \ - LOAD_ARGS_0 () -#define LOAD_ARGS_2(out0, out1) \ - register long _out1 asm ("out1") = (long) (out1); \ - LOAD_ARGS_1 (out0) -#define LOAD_ARGS_3(out0, out1, out2) \ - register long _out2 asm ("out2") = (long) (out2); \ - LOAD_ARGS_2 (out0, out1) -#define LOAD_ARGS_4(out0, out1, out2, out3) \ - register long _out3 asm ("out3") = (long) (out3); \ - LOAD_ARGS_3 (out0, out1, out2) -#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \ - register long _out4 asm ("out4") = (long) (out4); \ - LOAD_ARGS_4 (out0, out1, out2, out3) -#define LOAD_ARGS_6(out0, out1, out2, out3, out4, out5) \ - register long _out5 asm ("out5") = (long) (out5); \ - LOAD_ARGS_5 (out0, out1, out2, out3, out4) - -#define ASM_OUTARGS_1 "=r" (_out0) -#define ASM_OUTARGS_2 ASM_OUTARGS_1, "=r" (_out1) -#define ASM_OUTARGS_3 ASM_OUTARGS_2, "=r" (_out2) -#define ASM_OUTARGS_4 ASM_OUTARGS_3, "=r" (_out3) -#define ASM_OUTARGS_5 ASM_OUTARGS_4, "=r" (_out4) -#define ASM_OUTARGS_6 ASM_OUTARGS_5, "=r" (_out5) - -#define ASM_ARGS_0 -#define ASM_ARGS_1 ASM_ARGS_0, "3" (_out0) -#define ASM_ARGS_2 ASM_ARGS_1, "4" (_out1) -#define ASM_ARGS_3 ASM_ARGS_2, "5" (_out2) -#define ASM_ARGS_4 ASM_ARGS_3, "6" (_out3) -#define ASM_ARGS_5 ASM_ARGS_4, "7" (_out4) -#define ASM_ARGS_6 ASM_ARGS_5, "8" (_out5) - -#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0" -#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1" -#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2" -#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3" -#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4" -#define ASM_CLOBBERS_5 ASM_CLOBBERS_6, "out5" -#define ASM_CLOBBERS_6 , "out6", "out7", \ - /* Non-stacked integer registers, minus r8, r10, r15. */ \ - "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \ - "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \ - "r28", "r29", "r30", "r31", \ - /* Predicate registers. */ \ - "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \ - /* Non-rotating fp registers. */ \ - "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ - /* Branch registers. */ \ - "b6", "b7" - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/ia64/pipe.c b/klibc/klibc/arch/ia64/pipe.c index 5f5dd05727..0b641e8702 100644 --- a/klibc/klibc/arch/ia64/pipe.c +++ b/klibc/klibc/arch/ia64/pipe.c @@ -27,7 +27,7 @@ int pipe(int *filedes) long _retval; __asm __volatile (__IA64_BREAK : "=r" (_r8), "=r" (_r10), "=r" (_r15), - "=r" (_out0) + "=r" (_out0), "=r" (_r9) : "2" (_r15), "3" (_out0) : "memory" ASM_CLOBBERS); if (_r10 == -1) { diff --git a/klibc/klibc/arch/ia64/syscall.S b/klibc/klibc/arch/ia64/syscall.S new file mode 100644 index 0000000000..e3f264c0e4 --- /dev/null +++ b/klibc/klibc/arch/ia64/syscall.S @@ -0,0 +1,20 @@ +# +# arch/ia64/syscall.S +# + +#include + + .text + .align 32 + .proc __syscall_error + .globl __syscall_error +__syscall_error: + addl r2 = @ltoffx(errno),gp + ;; + ld8.mov r3 = [r2],errno + ;; + st4 [r3] = r8 + mov r8 = -1 + br.ret.sptk.many b0 + .size __syscall_error, .-__syscall_error + .endp __syscall_error diff --git a/klibc/klibc/arch/ia64/sysstub.ph b/klibc/klibc/arch/ia64/sysstub.ph new file mode 100644 index 0000000000..34031a29ae --- /dev/null +++ b/klibc/klibc/arch/ia64/sysstub.ph @@ -0,0 +1,29 @@ +# -*- perl -*- +# +# arch/ia64/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.text\n"; + print OUT "\t.align 32\n"; + print OUT "\t.proc ${fname}\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT "\tmov\tr15 = __NR_${sname}\n"; + print OUT "\tbreak __BREAK_SYSCALL\n"; + print OUT "\tcmp.eq p6,p0 = -1,r10\n"; + print OUT "(p6)\tbr.few __syscall_error\n"; + print OUT "\tbr.ret.sptk.many b0\n"; + print OUT "\t.size\t${fname},.-${fname}\n"; + print OUT "\t.endp\t${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/ia64/vfork.S b/klibc/klibc/arch/ia64/vfork.S index 0354fa9ef7..efcd03f7f1 100644 --- a/klibc/klibc/arch/ia64/vfork.S +++ b/klibc/klibc/arch/ia64/vfork.S @@ -27,8 +27,8 @@ vfork: mov out0=CLONE_VM|CLONE_VFORK|SIGCHLD mov out1=0 ;; - __IA64_BREAK // Do the syscall - + break 0x100000 // Do the syscall + ;; addl r15=0,r1 cmp.eq p7,p6 = -1,r10 ;; diff --git a/klibc/klibc/arch/m68k/include/klibc/archsignal.h b/klibc/klibc/arch/m68k/include/klibc/archsignal.h deleted file mode 100644 index 714527f6b0..0000000000 --- a/klibc/klibc/arch/m68k/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/m68k/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/m68k/include/klibc/archsys.h b/klibc/klibc/arch/m68k/include/klibc/archsys.h deleted file mode 100644 index 8f6bed8e94..0000000000 --- a/klibc/klibc/arch/m68k/include/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/m68k/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/mips/MCONFIG b/klibc/klibc/arch/mips/MCONFIG index 52b518461f..a248973815 100644 --- a/klibc/klibc/arch/mips/MCONFIG +++ b/klibc/klibc/arch/mips/MCONFIG @@ -7,12 +7,9 @@ # accordingly. # -ARCHREQFLAGS = -fno-pic -mno-abicalls +ARCHREQFLAGS = -fno-pic -mno-abicalls -G 0 OPTFLAGS = -Os -fomit-frame-pointer BITSIZE = 32 # Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 2 MB -- the normal starting point for text is 4 MB. -SHAREDFLAGS = -Ttext 0x00200200 +SHAREDFLAGS = -T arch/$(ARCH)/klibc.ld diff --git a/klibc/klibc/arch/mips/Makefile.inc b/klibc/klibc/arch/mips/Makefile.inc index 09a2d2f736..e257023f34 100644 --- a/klibc/klibc/arch/mips/Makefile.inc +++ b/klibc/klibc/arch/mips/Makefile.inc @@ -11,6 +11,7 @@ ARCHOBJS = \ arch/$(ARCH)/pipe.o \ arch/$(ARCH)/vfork.o \ arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ libgcc/__divdi3.o \ libgcc/__moddi3.o \ libgcc/__udivdi3.o \ diff --git a/klibc/klibc/arch/mips/include/klibc/archsetjmp.h b/klibc/klibc/arch/mips/include/klibc/archsetjmp.h deleted file mode 100644 index 40e5be2736..0000000000 --- a/klibc/klibc/arch/mips/include/klibc/archsetjmp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * arch/mips/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __s0; - unsigned long __s1; - unsigned long __s2; - unsigned long __s3; - unsigned long __s4; - unsigned long __s5; - unsigned long __s6; - unsigned long __s7; - unsigned long __gp; - unsigned long __sp; - unsigned long __s8; - unsigned long __ra; - unsigned long __f20; - unsigned long __f21; - unsigned long __f22; - unsigned long __f23; - unsigned long __f24; - unsigned long __f25; - unsigned long __f26; - unsigned long __f27; - unsigned long __f28; - unsigned long __f29; - unsigned long __f30; - unsigned long __f31; - unsigned long __fcr31; - unsigned long __unused; -} __attribute__((aligned(8))); - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/klibc/arch/mips/include/klibc/archsignal.h b/klibc/klibc/arch/mips/include/klibc/archsignal.h deleted file mode 100644 index 3b72908636..0000000000 --- a/klibc/klibc/arch/mips/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/mips/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/mips/include/klibc/archsys.h b/klibc/klibc/arch/mips/include/klibc/archsys.h deleted file mode 100644 index f696cdfaa7..0000000000 --- a/klibc/klibc/arch/mips/include/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/mips/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/mips/include/machine/asm.h b/klibc/klibc/arch/mips/include/machine/asm.h deleted file mode 100644 index e5239a6cef..0000000000 --- a/klibc/klibc/arch/mips/include/machine/asm.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * arch/mips/include/machine/asm.h - */ - -#ifndef _MACHINE_ASM_H -#define _MACHINE_ASM_H - -#include -#include - -#endif /* _MACHINE_ASM_H */ diff --git a/klibc/klibc/arch/mips/include/sgidefs.h b/klibc/klibc/arch/mips/include/sgidefs.h deleted file mode 100644 index eb103ace2c..0000000000 --- a/klibc/klibc/arch/mips/include/sgidefs.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/mips/include/sgidefs.h - */ - -/* Some ABI constants */ - -#ifndef _SGIDEFS_H -#define _SGIDEFS_H - -#define _MIPS_ISA_MIPS1 1 -#define _MIPS_ISA_MIPS2 2 -#define _MIPS_ISA_MIPS3 3 -#define _MIPS_ISA_MIPS4 4 -#define _MIPS_ISA_MIPS5 5 - -#define _MIPS_SIM_ABI32 1 -#define _MIPS_SIM_NABI32 2 -#define _MIPS_SIM_ABI64 3 - -#endif /* _SGIDEFS_H */ diff --git a/klibc/klibc/arch/mips/klibc.ld b/klibc/klibc/arch/mips/klibc.ld new file mode 100644 index 0000000000..d75c9de70c --- /dev/null +++ b/klibc/klibc/arch/mips/klibc.ld @@ -0,0 +1,217 @@ +/* Linker script for klibc.so, needed because of the the damned + GNU ld script headers problem */ + +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", + "elf32-tradlittlemips") +OUTPUT_ARCH(mips) +ENTRY(__start) +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + /* This address needs to be reachable using normal inter-module + calls, and work on the memory models for this architecture */ + /* 2 MB -- the normal starting point for text is 4 MB */ + . = 0x00200400; + .interp : { *(.interp) } + .reginfo : { *(.reginfo) } + .dynamic : { *(.dynamic) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_d : { *(.gnu.version_d) } + .gnu.version_r : { *(.gnu.version_r) } + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) + *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) + *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) + *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) + *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) + *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) + *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : + { + KEEP (*(.init)) + } =0 + .plt : { *(.plt) } + .text : + { + _ftext = . ; + *(.text .stub .text.* .gnu.linkonce.t.*) + /* .gnu.warning sections are handled specially by elf32.em. */ + *(.gnu.warning) + *(.mips16.fn.*) *(.mips16.call.*) + } =0 + .fini : + { + KEEP (*(.fini)) + } =0 + PROVIDE (__etext = .); + PROVIDE (_etext = .); + PROVIDE (etext = .); + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } + .rodata1 : { *(.rodata1) } + .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } + .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } + .eh_frame_hdr : { *(.eh_frame_hdr) } + /* Adjust the address for the data segment. We want to adjust up to + the same address within the page on the next page up. */ + . = ALIGN(8192); + /* Ensure the __preinit_array_start label is properly aligned. We + could instead move the label definition inside the section, but + the linker would then create the section even if it turns out to + be empty, which isn't pretty. */ + . = ALIGN(32 / 8); + PROVIDE (__preinit_array_start = .); + .preinit_array : { *(.preinit_array) } + PROVIDE (__preinit_array_end = .); + PROVIDE (__init_array_start = .); + .init_array : { *(.init_array) } + PROVIDE (__init_array_end = .); + PROVIDE (__fini_array_start = .); + .fini_array : { *(.fini_array) } + PROVIDE (__fini_array_end = .); + .data : + { + _fdata = . ; + *(.data .data.* .gnu.linkonce.d.*) + SORT(CONSTRUCTORS) + } + .data1 : { *(.data1) } + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } + .eh_frame : { KEEP (*(.eh_frame)) } + .gcc_except_table : { *(.gcc_except_table) } + .ctors : + { + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin*.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } + .dtors : + { + KEEP (*crtbegin*.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } + .jcr : { KEEP (*(.jcr)) } + _gp = ALIGN(16) + 0x7ff0; + .got : { *(.got.plt) *(.got) } + /* We want the small data sections together, so single-instruction offsets + can access them all, and initialized data all before uninitialized, so + we can shorten the on-disk segment size. */ + .sdata : + { + *(.sdata .sdata.* .gnu.linkonce.s.*) + } + .lit8 : { *(.lit8) } + .lit4 : { *(.lit4) } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + _fbss = .; + .sbss : + { + PROVIDE (__sbss_start = .); + PROVIDE (___sbss_start = .); + *(.dynsbss) + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + PROVIDE (__sbss_end = .); + PROVIDE (___sbss_end = .); + } + .bss : + { + *(.dynbss) + *(.bss .bss.* .gnu.linkonce.b.*) + *(COMMON) + /* Align here to ensure that the .bss section occupies space up to + _end. Align after .bss to ensure correct alignment even if the + .bss section disappears because there are no input sections. */ + . = ALIGN(32 / 8); + } + . = ALIGN(32 / 8); + _end = .; + PROVIDE (end = .); + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1 */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2 */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2 */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } + .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } + /DISCARD/ : { *(.note.GNU-stack) } +} diff --git a/klibc/klibc/arch/mips/syscall.S b/klibc/klibc/arch/mips/syscall.S new file mode 100644 index 0000000000..d5c1fe1c7d --- /dev/null +++ b/klibc/klibc/arch/mips/syscall.S @@ -0,0 +1,15 @@ +#include +#include +#include + + .set noreorder + +LEAF(__syscall_common) + syscall + beqz a3, 1f + # sw is actually two instructions; the first one goes + # in the branch delay slot + sw v0, errno + li v0, -1 +1: jr ra + END(__syscall_common) diff --git a/klibc/klibc/arch/mips/sysstub.ph b/klibc/klibc/arch/mips/sysstub.ph new file mode 100644 index 0000000000..abe599c17d --- /dev/null +++ b/klibc/klibc/arch/mips/sysstub.ph @@ -0,0 +1,30 @@ +# -*- perl -*- +# +# arch/mips/sysstub.ph +# +# Script to generate system call stubs +# + +# On MIPS, most system calls follow the standard convention, with the +# system call number in r0 (v0), return an error value in r19 (a3) as +# well as the return value in r0 (v0). + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + $stype = $stype || 'common'; + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "#include \n"; + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.set noreorder\n"; + print OUT "\n"; + print OUT "LEAF(${fname})\n"; + print OUT "\tj\t__syscall_${stype}\n"; + print OUT "\t li\tv0, __NR_${sname}\n"; + print OUT "\tEND(${fname})\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/mips/vfork.S b/klibc/klibc/arch/mips/vfork.S index aca8083aa4..9829867fab 100644 --- a/klibc/klibc/arch/mips/vfork.S +++ b/klibc/klibc/arch/mips/vfork.S @@ -6,14 +6,11 @@ #define CLONE_VFORK 0x00004000 #define SIGCHLD 18 + .set noreorder + LEAF(vfork) li a0, CLONE_VFORK | CLONE_VM | SIGCHLD li a1, 0 - li v0, __NR_clone - syscall - bnez a3, 1f - b 2f -1: sw v0, errno - li v0, -1 -2: jr ra + j __syscall_common + li v0, __NR_clone END(vfork) diff --git a/klibc/klibc/arch/mips64/include/klibc/archsignal.h b/klibc/klibc/arch/mips64/include/klibc/archsignal.h deleted file mode 100644 index 56b0fd323e..0000000000 --- a/klibc/klibc/arch/mips64/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/mips64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/mips64/include/klibc/archsys.h b/klibc/klibc/arch/mips64/include/klibc/archsys.h deleted file mode 100644 index 81e5106e16..0000000000 --- a/klibc/klibc/arch/mips64/include/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/mips64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/parisc/Makefile.inc b/klibc/klibc/arch/parisc/Makefile.inc index abe9155bf4..980a543ed2 100644 --- a/klibc/klibc/arch/parisc/Makefile.inc +++ b/klibc/klibc/arch/parisc/Makefile.inc @@ -8,8 +8,12 @@ # ARCHOBJS = \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o ARCHOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS)) archclean: + +arch/$(ARCH)/syscall.o: arch/$(ARCH)/syscall.c + $(CC) $(CFLAGS) -ffixed-r20 -c -o $@ $< diff --git a/klibc/klibc/arch/parisc/include/klibc/archsignal.h b/klibc/klibc/arch/parisc/include/klibc/archsignal.h deleted file mode 100644 index 3190e8528e..0000000000 --- a/klibc/klibc/arch/parisc/include/klibc/archsignal.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/parisc/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -#define _NSIG 64 -#define _NSIG_SZ (_NSIG / LONG_BIT) - -typedef struct { - unsigned long sig[_NSIG_SZ]; -} sigset_t; - -struct sigaction { - __sighandler_t sa_handler; - unsigned long sa_flags; - sigset_t sa_mask; -}; - -#endif diff --git a/klibc/klibc/arch/parisc/include/klibc/archsys.h b/klibc/klibc/arch/parisc/include/klibc/archsys.h deleted file mode 100644 index 5013ba8794..0000000000 --- a/klibc/klibc/arch/parisc/include/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/parisc/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/parisc/syscall.c b/klibc/klibc/arch/parisc/syscall.c new file mode 100644 index 0000000000..99ef5fe103 --- /dev/null +++ b/klibc/klibc/arch/parisc/syscall.c @@ -0,0 +1,29 @@ +/* + * arch/parisc/syscall.c + * + * This function is called from a stub with %r20 already set up. + * Compile this function with -ffixed-r20 so that it doesn't clobber + * this register by mistake. + */ + +#include +#include + +long __syscall_common(long a0, long a1, long a2, long a3, long a4, long a5) +{ + register unsigned long rv asm ("r28"); + + asm volatile("\tble 0x100(%%sr2, %%r0)\n" + : "=r" (rv) + : "r" (a0), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5) + : "%r1", "%r2", "%r29", "%r31"); + + if ( __unlikely(rv >= -4095UL) ) { + errno = -rv; + return -1L; + } else { + return (long)rv; + } +} + + diff --git a/klibc/klibc/arch/parisc/sysstub.ph b/klibc/klibc/arch/parisc/sysstub.ph new file mode 100644 index 0000000000..eb6b5dd92a --- /dev/null +++ b/klibc/klibc/arch/parisc/sysstub.ph @@ -0,0 +1,29 @@ +# -*- perl -*- +# +# arch/parisc/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.text\n"; + print OUT "\t.align 4\n"; + print OUT "\t.import __syscall_common, code\n"; + print OUT "\t.global ${fname}\n"; + print OUT "\t.export ${fname}, code\n"; + print OUT "\t.type ${fname}, @function\n"; + print OUT "\t.proc\n"; + print OUT "\.callinfo\n"; + print OUT "${fname}:\n"; + print OUT "\tb\t__syscall_common\n"; + print OUT "\t ldo\t__NR_${sname}(%r0),%r20\n"; + print OUT "\t.procend\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/ppc/MCONFIG b/klibc/klibc/arch/ppc/MCONFIG index fcb0992150..ff7c44db9a 100644 --- a/klibc/klibc/arch/ppc/MCONFIG +++ b/klibc/klibc/arch/ppc/MCONFIG @@ -9,3 +9,10 @@ OPTFLAGS = -Os -fomit-frame-pointer BITSIZE = 32 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 256-16 MB - normal binaries start at 256 MB, and jumps are limited +# to +/- 16 MB +SHAREDFLAGS = -Ttext 0x0f000200 diff --git a/klibc/klibc/arch/ppc/Makefile.inc b/klibc/klibc/arch/ppc/Makefile.inc index 3bd2c0643c..c6bb975f0f 100644 --- a/klibc/klibc/arch/ppc/Makefile.inc +++ b/klibc/klibc/arch/ppc/Makefile.inc @@ -9,6 +9,7 @@ ARCHOBJS = \ arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ libgcc/__divdi3.o \ libgcc/__moddi3.o \ libgcc/__udivdi3.o \ diff --git a/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h b/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h deleted file mode 100644 index 53e2fccc3b..0000000000 --- a/klibc/klibc/arch/ppc/include/klibc/archsetjmp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/ppc/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __r2; - unsigned long __sp; - unsigned long __lr; - unsigned long __cr; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __r16; - unsigned long __r17; - unsigned long __r18; - unsigned long __r19; - unsigned long __r20; - unsigned long __r21; - unsigned long __r22; - unsigned long __r23; - unsigned long __r24; - unsigned long __r25; - unsigned long __r26; - unsigned long __r27; - unsigned long __r28; - unsigned long __r29; - unsigned long __r30; - unsigned long __r31; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/ppc/include/klibc/archsignal.h b/klibc/klibc/arch/ppc/include/klibc/archsignal.h deleted file mode 100644 index 567a547ef9..0000000000 --- a/klibc/klibc/arch/ppc/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/ppc/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/ppc/include/klibc/archsys.h b/klibc/klibc/arch/ppc/include/klibc/archsys.h deleted file mode 100644 index 17a28859e5..0000000000 --- a/klibc/klibc/arch/ppc/include/klibc/archsys.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * arch/ppc/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* PowerPC seems to lack _syscall6() in its headers */ -/* This seems to work on both 32- and 64-bit ppc */ - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_7 = (unsigned long) (arg5); \ - __sc_8 = (unsigned long) (arg6); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "+r" (__sc_3), \ - "+r" (__sc_0), \ - "+r" (__sc_4), \ - "+r" (__sc_5), \ - "+r" (__sc_6), \ - "+r" (__sc_7), \ - "+r" (__sc_8) \ - : : "cr0", "ctr", "memory", \ - "r9", "r10", "r11", "r12"); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - if (__sc_err & 0x10000000) \ - { \ - errno = (int)__sc_ret; \ - __sc_ret = -1; \ - } \ - return (type)__sc_ret; \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/ppc/syscall.S b/klibc/klibc/arch/ppc/syscall.S new file mode 100644 index 0000000000..0a7c37c903 --- /dev/null +++ b/klibc/klibc/arch/ppc/syscall.S @@ -0,0 +1,16 @@ +/* + * arch/ppc/syscall.S + * + * Common error-handling path for system calls. + */ + + .text + .align 2 + .globl __syscall_error + .type __syscall_error,@function +__syscall_error: + lis 9,errno@ha + stw 3,errno@l(9) + li 3,-1 + blr + .size __syscall_error,.-__syscall_error diff --git a/klibc/klibc/arch/ppc/sysstub.ph b/klibc/klibc/arch/ppc/sysstub.ph new file mode 100644 index 0000000000..542ab5575c --- /dev/null +++ b/klibc/klibc/arch/ppc/sysstub.ph @@ -0,0 +1,25 @@ +# -*- perl -*- +# +# arch/ppc/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT "\tli 0,__NR_${sname}\n"; + print OUT "\tsc\n"; + print OUT "\tbnslr\n"; + print OUT "\tb __syscall_error\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/ppc64/MCONFIG b/klibc/klibc/arch/ppc64/MCONFIG index 6997693e99..86526f895c 100644 --- a/klibc/klibc/arch/ppc64/MCONFIG +++ b/klibc/klibc/arch/ppc64/MCONFIG @@ -9,3 +9,10 @@ OPTFLAGS = -Os -fomit-frame-pointer BITSIZE = 64 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 256-16 MB - normal binaries start at 256 MB, and jumps are limited +# to +/- 16 MB +SHAREDFLAGS = -Ttext 0x0f000200 diff --git a/klibc/klibc/arch/ppc64/Makefile.inc b/klibc/klibc/arch/ppc64/Makefile.inc index 3ab3a8c8e6..928df1aeb7 100644 --- a/klibc/klibc/arch/ppc64/Makefile.inc +++ b/klibc/klibc/arch/ppc64/Makefile.inc @@ -8,8 +8,18 @@ # ARCHOBJS = \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) +INTERP_O = interp1.o + +interp.o: interp1.o klibc.got + $(LD) $(LDFLAGS) -r -o $@ interp1.o klibc.got + +klibc.got: $(SOHASH) + $(OBJCOPY) -j.got $< $@ + archclean: + rm -f klibc.got diff --git a/klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h b/klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h deleted file mode 100644 index 006a2e27be..0000000000 --- a/klibc/klibc/arch/ppc64/include/klibc/archsetjmp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/ppc64/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __r2; - unsigned long __sp; - unsigned long __lr; - unsigned long __cr; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __r16; - unsigned long __r17; - unsigned long __r18; - unsigned long __r19; - unsigned long __r20; - unsigned long __r21; - unsigned long __r22; - unsigned long __r23; - unsigned long __r24; - unsigned long __r25; - unsigned long __r26; - unsigned long __r27; - unsigned long __r28; - unsigned long __r29; - unsigned long __r30; - unsigned long __r31; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/ppc64/include/klibc/archsignal.h b/klibc/klibc/arch/ppc64/include/klibc/archsignal.h deleted file mode 100644 index 8452f6e4bc..0000000000 --- a/klibc/klibc/arch/ppc64/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/ppc64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/ppc64/include/klibc/archsys.h b/klibc/klibc/arch/ppc64/include/klibc/archsys.h deleted file mode 100644 index 4f81fee00d..0000000000 --- a/klibc/klibc/arch/ppc64/include/klibc/archsys.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * arch/ppc64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_7 = (unsigned long) (arg5); \ - __sc_8 = (unsigned long) (arg6); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6), \ - "r" (__sc_7), \ - "r" (__sc_8) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/ppc64/setjmp.S b/klibc/klibc/arch/ppc64/setjmp.S index 1dcc67035e..30db419140 100644 --- a/klibc/klibc/arch/ppc64/setjmp.S +++ b/klibc/klibc/arch/ppc64/setjmp.S @@ -2,7 +2,6 @@ # arch/ppc64/setjmp.S # # Basic setjmp/longjmp implementation -# This file was derived from the equivalent file in NetBSD # .text @@ -17,13 +16,33 @@ setjmp: .globl setjmp .globl .setjmp .setjmp: - mflr %r11 /* save return address */ - mfcr %r12 /* save condition register */ - mr %r10,%r1 /* save stack pointer */ - mr %r9,%r2 /* save GPR2 (not needed) */ - stmw %r9,0(%r3) /* save r9..r31 */ - li %r3,0 /* indicate success */ - blr /* return */ + mflr %r11 /* save return address */ + mfcr %r12 /* save condition register */ + std %r2,0(%r3) /* save TOC pointer (not needed) */ + stdu %r1,8(%r3) /* save stack pointer */ + stdu %r11,8(%r3) + stdu %r12,8(%r3) + stdu %r13,8(%r3) /* save caller saved regs */ + stdu %r14,8(%r3) + stdu %r15,8(%r3) + stdu %r16,8(%r3) + stdu %r17,8(%r3) + stdu %r18,8(%r3) + stdu %r19,8(%r3) + stdu %r20,8(%r3) + stdu %r21,8(%r3) + stdu %r22,8(%r3) + stdu %r23,8(%r3) + stdu %r24,8(%r3) + stdu %r25,8(%r3) + stdu %r26,8(%r3) + stdu %r27,8(%r3) + stdu %r28,8(%r3) + stdu %r29,8(%r3) + stdu %r30,8(%r3) + std %r31,8(%r3) + li %r3,0 /* indicate success */ + blr /* return */ .size .setjmp,.-.setjmp .section ".opd","aw" @@ -35,12 +54,32 @@ longjmp: .globl longjmp .globl .longjmp .longjmp: - lmw %r9,0(%r3) /* save r9..r31 */ - mtlr %r11 /* restore LR */ - mtcr %r12 /* restore CR */ - mr %r2,%r9 /* restore GPR2 (not needed) */ - mr %r1,%r10 /* restore stack */ - mr %r3,%r4 /* get return value */ - blr /* return */ + ld %r2,0(%r3) /* restore TOC pointer (not needed) */ + ldu %r1,8(%r3) /* restore stack */ + ldu %r11,8(%r3) + ldu %r12,8(%r3) + ldu %r13,8(%r3) /* restore caller saved regs */ + ldu %r14,8(%r3) + ldu %r15,8(%r3) + ldu %r16,8(%r3) + ldu %r17,8(%r3) + ldu %r18,8(%r3) + ldu %r19,8(%r3) + ldu %r20,8(%r3) + ldu %r21,8(%r3) + ldu %r22,8(%r3) + ldu %r23,8(%r3) + ldu %r24,8(%r3) + ldu %r25,8(%r3) + ldu %r26,8(%r3) + ldu %r27,8(%r3) + ldu %r28,8(%r3) + ldu %r29,8(%r3) + ldu %r30,8(%r3) + ld %r31,8(%r3) + mtlr %r11 /* restore LR */ + mtcr %r12 /* restore CR */ + mr %r3,%r4 /* get return value */ + blr /* return */ .size .longjmp,.-.longjmp diff --git a/klibc/klibc/arch/ppc64/syscall.c b/klibc/klibc/arch/ppc64/syscall.c new file mode 100644 index 0000000000..a5895fe88e --- /dev/null +++ b/klibc/klibc/arch/ppc64/syscall.c @@ -0,0 +1,14 @@ +/* + * arch/ppc64/syscall.c + * + * Common error-handling path for system calls. + * The return value from __syscall_error becomes the + * return value from the system call. + */ +#include + +long int __syscall_error(long int err) +{ + errno = err; + return -1; +} diff --git a/klibc/klibc/arch/ppc64/sysstub.ph b/klibc/klibc/arch/ppc64/sysstub.ph new file mode 100644 index 0000000000..1469cc6071 --- /dev/null +++ b/klibc/klibc/arch/ppc64/sysstub.ph @@ -0,0 +1,34 @@ +# -*- perl -*- +# +# arch/ppc64/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "\t.section \".opd\",\"aw\"\n"; + print OUT "\t.align 3\n"; + print OUT "${fname}:\n"; + print OUT "\t.quad .${fname},.TOC.\@tocbase,0\n"; + print OUT "\t.size ${fname},24\n"; + print OUT "\t.text\n"; + print OUT "\t.type .${fname},\@function\n"; + print OUT "\t.globl .${fname}\n"; + print OUT ".${fname}:\n"; + print OUT "\tli 0,__NR_${sname}\n"; + print OUT "\tsc\n"; + print OUT "\tmfcr 0\n"; + print OUT "\trldicl. 9,0,36,63\n"; + print OUT "\tbeqlr- 0\n"; + print OUT "\tb .__syscall_error\n"; + print OUT "\t.size .${fname},.-.${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/s390/Makefile.inc b/klibc/klibc/arch/s390/Makefile.inc index c50f4f2886..49b64ddbc6 100644 --- a/klibc/klibc/arch/s390/Makefile.inc +++ b/klibc/klibc/arch/s390/Makefile.inc @@ -9,6 +9,8 @@ ARCHOBJS = \ arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/mmap.o \ + arch/$(ARCH)/syscall.o \ libgcc/__divdi3.o \ libgcc/__moddi3.o \ libgcc/__udivdi3.o \ diff --git a/klibc/klibc/arch/s390/include/klibc/archsetjmp.h b/klibc/klibc/arch/s390/include/klibc/archsetjmp.h deleted file mode 100644 index 11a641ed5a..0000000000 --- a/klibc/klibc/arch/s390/include/klibc/archsetjmp.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/s390/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - uint32_t __gregs[10]; /* general registers r6-r15 */ - uint64_t __fpregs[2]; /* fp registers f4 and f6 */ -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/s390/include/klibc/archsignal.h b/klibc/klibc/arch/s390/include/klibc/archsignal.h deleted file mode 100644 index 1f8de28b4b..0000000000 --- a/klibc/klibc/arch/s390/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/s390/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/s390/include/klibc/archsys.h b/klibc/klibc/arch/s390/include/klibc/archsys.h deleted file mode 100644 index 1cd0948f3c..0000000000 --- a/klibc/klibc/arch/s390/include/klibc/archsys.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/s390/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* S/390 only has five syscall parameters, and uses a structure for - 6-argument syscalls. */ - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ - type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - unsigned long __arg[6] = { \ - (unsigned long) arg1, \ - (unsigned long) arg2, \ - (unsigned long) arg3, \ - (unsigned long) arg4, \ - (unsigned long) arg5, \ - (unsigned long) arg6 \ - }; \ - register void *__argp asm("2") = &__arg; \ - long __res; \ - __asm__ __volatile__ ( \ - " svc %b1\n" \ - " lr %0,2" \ - : "=d" (__res) \ - : "i" (__NR_##name), \ - "d" (__argp) \ - : _svc_clobber); \ - __syscall_return(type, __res); \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/s390/mmap.c b/klibc/klibc/arch/s390/mmap.c new file mode 100644 index 0000000000..51ff07f44c --- /dev/null +++ b/klibc/klibc/arch/s390/mmap.c @@ -0,0 +1,41 @@ +#include +#include + +struct mmap_arg_struct { + unsigned long addr; + unsigned long len; + unsigned long prot; + unsigned long flags; + unsigned long fd; + unsigned long offset; +}; + +void * __mmap2(void * addr, size_t len, int prot, int flags, + int fd, long offset) +{ + struct mmap_arg_struct args = { + (unsigned long) addr, + (unsigned long) len, + (unsigned long) prot, + (unsigned long) flags, + (unsigned long) fd, + (unsigned long) offset, + }; + + register struct mmap_arg_struct *__arg1 asm("2") = &args; + register long __svcres asm("2"); + unsigned long __res; + + __asm__ __volatile__ ( + " svc %b1\n" + : "=d" (__svcres) + : "i" (__NR_mmap2), + "0" (__arg1) + : "1", "cc", "memory"); + __res = __svcres; + if (__res >= (unsigned long)-125) { + errno = -__res; + __res = -1; + } + return (void *)__res; +} diff --git a/klibc/klibc/arch/s390/syscall.c b/klibc/klibc/arch/s390/syscall.c new file mode 100644 index 0000000000..c0f17c453c --- /dev/null +++ b/klibc/klibc/arch/s390/syscall.c @@ -0,0 +1,16 @@ +/* + * arch/s390/syscall.c + * + * Common error-handling path for system calls. + * The return value from __syscall_common becomes the + * return value from the system call. + */ +#include + +long int __syscall_common(long int err) +{ + if ((unsigned long)(err) < (unsigned long)(-125)) + return err; + errno = err; + return -1; +} diff --git a/klibc/klibc/arch/s390/sysstub.ph b/klibc/klibc/arch/s390/sysstub.ph new file mode 100644 index 0000000000..3838a1f1b2 --- /dev/null +++ b/klibc/klibc/arch/s390/sysstub.ph @@ -0,0 +1,31 @@ +# -*- perl -*- +# +# arch/s390/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT ".if __NR_${sname} < 256\n"; + print OUT "\tsvc __NR_${sname}\n"; + print OUT ".else\n"; + print OUT "\tlhi %r1,__NR_${sname}\n"; + print OUT "\tsvc 0\n"; + print OUT ".endif\n"; + print OUT "\tbras %r3,1f\n"; + print OUT "\t.long __syscall_common\n"; + print OUT "1:\tl %r3,0(%r3)\n"; + print OUT "\tbr %r3\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/s390x/Makefile.inc b/klibc/klibc/arch/s390x/Makefile.inc index eff8f951ac..9d614e07b2 100644 --- a/klibc/klibc/arch/s390x/Makefile.inc +++ b/klibc/klibc/arch/s390x/Makefile.inc @@ -8,7 +8,9 @@ # ARCHOBJS = \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/mmap.o \ + arch/$(ARCH)/syscall.o ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) diff --git a/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h b/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h deleted file mode 100644 index dd3ed0d47c..0000000000 --- a/klibc/klibc/arch/s390x/include/klibc/archsetjmp.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/s390x/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - uint64_t __gregs[10]; /* general registers r6-r15 */ - uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */ -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/s390x/include/klibc/archsignal.h b/klibc/klibc/arch/s390x/include/klibc/archsignal.h deleted file mode 100644 index 08c9a0073a..0000000000 --- a/klibc/klibc/arch/s390x/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/s390x/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/s390x/include/klibc/archsys.h b/klibc/klibc/arch/s390x/include/klibc/archsys.h deleted file mode 100644 index 15f7113bb4..0000000000 --- a/klibc/klibc/arch/s390x/include/klibc/archsys.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/s390x/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* S/390X only has five syscall parameters, and uses a structure for - 6-argument syscalls. */ - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ - type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - unsigned long __arg[6] = { \ - (unsigned long) arg1, \ - (unsigned long) arg2, \ - (unsigned long) arg3, \ - (unsigned long) arg4, \ - (unsigned long) arg5, \ - (unsigned long) arg6 \ - }; \ - register void *__argp asm("2") = &__arg; \ - long __res; \ - __asm__ __volatile__ ( \ - " svc %b1\n" \ - " lgr %0,2" \ - : "=d" (__res) \ - : "i" (__NR_##name), \ - "d" (__argp) \ - : _svc_clobber); \ - __syscall_return(type, __res); \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/s390x/mmap.c b/klibc/klibc/arch/s390x/mmap.c new file mode 100644 index 0000000000..158f0933a4 --- /dev/null +++ b/klibc/klibc/arch/s390x/mmap.c @@ -0,0 +1,41 @@ +#include +#include + +struct mmap_arg_struct { + unsigned long addr; + unsigned long len; + unsigned long prot; + unsigned long flags; + unsigned long fd; + unsigned long offset; +}; + +void * mmap(void * addr, size_t len, int prot, int flags, + int fd, off_t offset) +{ + struct mmap_arg_struct args = { + (unsigned long) addr, + (unsigned long) len, + (unsigned long) prot, + (unsigned long) flags, + (unsigned long) fd, + (unsigned long) offset, + }; + + register struct mmap_arg_struct *__arg1 asm("2") = &args; + register long __svcres asm("2"); + unsigned long __res; + + __asm__ __volatile__ ( + " svc %b1\n" + : "=d" (__svcres) + : "i" (__NR_mmap), + "0" (__arg1) + : "1", "cc", "memory"); + __res = __svcres; + if (__res >= (unsigned long)-125) { + errno = -__res; + __res = -1; + } + return (void *)__res; +} diff --git a/klibc/klibc/arch/s390x/syscall.c b/klibc/klibc/arch/s390x/syscall.c new file mode 100644 index 0000000000..c0f17c453c --- /dev/null +++ b/klibc/klibc/arch/s390x/syscall.c @@ -0,0 +1,16 @@ +/* + * arch/s390/syscall.c + * + * Common error-handling path for system calls. + * The return value from __syscall_common becomes the + * return value from the system call. + */ +#include + +long int __syscall_common(long int err) +{ + if ((unsigned long)(err) < (unsigned long)(-125)) + return err; + errno = err; + return -1; +} diff --git a/klibc/klibc/arch/s390x/sysstub.ph b/klibc/klibc/arch/s390x/sysstub.ph new file mode 100644 index 0000000000..10a47f7b07 --- /dev/null +++ b/klibc/klibc/arch/s390x/sysstub.ph @@ -0,0 +1,28 @@ +# -*- perl -*- +# +# arch/s390x/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT ".if __NR_${sname} < 256\n"; + print OUT "\tsvc __NR_${sname}\n"; + print OUT ".else\n"; + print OUT "\tlghi %r1,__NR_${sname}\n"; + print OUT "\tsvc 0\n"; + print OUT ".endif\n"; + print OUT "\tbrasl %r3,__syscall_common\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/sh/Makefile.inc b/klibc/klibc/arch/sh/Makefile.inc index 16d7ea1e18..ccabfa496b 100644 --- a/klibc/klibc/arch/sh/Makefile.inc +++ b/klibc/klibc/arch/sh/Makefile.inc @@ -7,7 +7,8 @@ # accordingly. # -ARCHOBJS = arch/sh/setjmp.o +ARCHOBJS = arch/sh/setjmp.o \ + arch/sh/syscall.o ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) diff --git a/klibc/klibc/arch/sh/crt0.S b/klibc/klibc/arch/sh/crt0.S index c9938a5612..21a37655f2 100644 --- a/klibc/klibc/arch/sh/crt0.S +++ b/klibc/klibc/arch/sh/crt0.S @@ -1,12 +1,11 @@ # # arch/sh/crt0.S # -# void _start(void) -# { -# /* Divine up argc, argv, and envp */ -# environ = envp; -# exit(main(argc, argv, envp)); -# } +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. # .text diff --git a/klibc/klibc/arch/sh/include/klibc/archsetjmp.h b/klibc/klibc/arch/sh/include/klibc/archsetjmp.h deleted file mode 100644 index 28dd932fbc..0000000000 --- a/klibc/klibc/arch/sh/include/klibc/archsetjmp.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/sh/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long r11; - unsigned long r12; - unsigned long r13; - unsigned long r14; - unsigned long r15; - unsigned long pr; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/klibc/arch/sh/include/klibc/archsignal.h b/klibc/klibc/arch/sh/include/klibc/archsignal.h deleted file mode 100644 index 6c4e5976ad..0000000000 --- a/klibc/klibc/arch/sh/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/sh/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/sh/include/klibc/archsys.h b/klibc/klibc/arch/sh/include/klibc/archsys.h deleted file mode 100644 index 5f8050a536..0000000000 --- a/klibc/klibc/arch/sh/include/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/sh/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/sh/syscall.S b/klibc/klibc/arch/sh/syscall.S new file mode 100644 index 0000000000..41a0486679 --- /dev/null +++ b/klibc/klibc/arch/sh/syscall.S @@ -0,0 +1,35 @@ +/* + * arch/sh/syscall.S + * + * On sh, r3 contains the syscall number (set by generated stub); + * r4..r7 contain arguments 0-3 per the standard calling convention, + * and arguments 4-5 are passed in r0 and r1. + * + * The return value is in r3 rather than standard r0. + */ + + .section ".text.syscall","ax" + .align 2 + .globl ___syscall_common + .type ___syscall_common,@function +___syscall_common: + mov.l @(sp),r0 + mov.l @(4,sp),r1 + trapa #0x15 + mov.l 1f,r0 + cmp/hs r0,r3 + bt/s 3f + neg r3,r4 + mov.l 2f,r5 + mov.l r4,@r5 + rts + mov #-1,r0 +3: + rts + mov r3,r0 + + .align 2 +1: .long -4096 /* Errno limit */ +2: .long errno + + .size ___syscall_common,.-___syscall_common diff --git a/klibc/klibc/arch/sh/sysstub.ph b/klibc/klibc/arch/sh/sysstub.ph new file mode 100644 index 0000000000..add5d35892 --- /dev/null +++ b/klibc/klibc/arch/sh/sysstub.ph @@ -0,0 +1,34 @@ +# -*- perl -*- +# +# arch/sh/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.section\t\".text.syscall\",\"ax\"\n"; + print OUT "\t.type\t${fname},\#function\n"; + print OUT "\t.globl\t${fname}\n"; + print OUT "\t.align\t2\n"; + print OUT "${fname}:\n"; + print OUT "\tbra\t__syscall_common\n"; + print OUT "#if __NR_${sname} >= 128\n"; + print OUT "\t mov.l\t1f, r3\n"; + print OUT "#else\n"; + print OUT "\t mov\t# __NR_${sname}, r3\n"; + print OUT "#endif\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + print OUT "\n"; + print OUT "#if __NR_${sname} >= 128\n"; + print OUT "\t.align\t2\n"; + print OUT "1:\t.long\t__NR_${sname}\n"; + print OUT "#endif\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/sparc/Makefile.inc b/klibc/klibc/arch/sparc/Makefile.inc index 0186810aca..6ea66114fa 100644 --- a/klibc/klibc/arch/sparc/Makefile.inc +++ b/klibc/klibc/arch/sparc/Makefile.inc @@ -14,7 +14,9 @@ ARCHOBJS = \ arch/$(ARCH)/urem.o \ arch/$(ARCH)/smul.o \ arch/$(ARCH)/umul.o \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ + arch/$(ARCH)/sysfork.o arch/$(ARCH)/sdiv.S: arch/$(ARCH)/divrem.m4 @echo 'building $@ from $^' diff --git a/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h b/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h deleted file mode 100644 index 92c1c74c9d..0000000000 --- a/klibc/klibc/arch/sparc/include/klibc/archsetjmp.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/sparc/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __sp; - unsigned long __fp; - unsigned long __pc; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/sparc/include/klibc/archsignal.h b/klibc/klibc/arch/sparc/include/klibc/archsignal.h deleted file mode 100644 index 6af3709033..0000000000 --- a/klibc/klibc/arch/sparc/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/sparc/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/sparc/include/klibc/archsys.h b/klibc/klibc/arch/sparc/include/klibc/archsys.h deleted file mode 100644 index fe6e68df8a..0000000000 --- a/klibc/klibc/arch/sparc/include/klibc/archsys.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * arch/sparc/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* fork and vfork return the "other process" pid in %o0 and an - "is child" flag in %o1... */ - -#define _syscall0_forkish(type,name) \ -type name(void) \ -{ \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register unsigned long __o0 __asm__ ("o0"); \ -register unsigned long __o1 __asm__ ("o1"); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__o0), "=r" (__o1)\ - : "r" (__g1) \ - : "cc"); \ -if ((unsigned long)__o0 < (unsigned long)-255) \ - return (type)(__o0 & (__o1-1)); \ -errno = (int)-__o0; \ -return -1; \ -} - -/* SPARC seems to lack _syscall6() in its headers */ - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -register long __o3 __asm__ ("o3") = (long)(arg4); \ -register long __o4 __asm__ ("o4") = (long)(arg5); \ -register long __o5 __asm__ ("o5") = (long)(arg6); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__o5), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res>=0) \ -return (type) __res; \ -errno = -__res; \ -return (type)-1; \ -} - -#endif /* _syscall6 missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/sparc/include/machine/asm.h b/klibc/klibc/arch/sparc/include/machine/asm.h deleted file mode 100644 index b622bd8cf1..0000000000 --- a/klibc/klibc/arch/sparc/include/machine/asm.h +++ /dev/null @@ -1,192 +0,0 @@ -/* $NetBSD: asm.h,v 1.14 2002/07/20 08:37:30 mrg Exp $ */ - -/* - * Copyright (c) 1994 Allen Briggs - * All rights reserved. - * - * Gleaned from locore.s and sun3 asm.h which had the following copyrights: - * locore.s: - * Copyright (c) 1988 University of Utah. - * Copyright (c) 1982, 1990 The Regents of the University of California. - * sun3/include/asm.h: - * Copyright (c) 1993 Adam Glass - * Copyright (c) 1990 The Regents of the University of California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _ASM_H_ -#define _ASM_H_ - -/* Pull in CCFSZ, CC64FSZ, and BIAS from frame.h */ -#ifndef _LOCORE -#define _LOCORE -#endif -#include - -#ifdef __ELF__ -#define _C_LABEL(name) name -#else -#ifdef __STDC__ -#define _C_LABEL(name) _ ## name -#else -#define _C_LABEL(name) _/**/name -#endif -#endif -#define _ASM_LABEL(name) name - -#ifdef PIC -/* - * PIC_PROLOGUE() is akin to the compiler generated function prologue for - * PIC code. It leaves the address of the Global Offset Table in DEST, - * clobbering register TMP in the process. - * - * We can use two code sequences. We can read the %pc or use the call - * instruction that saves the pc in %o7. Call requires the branch unit and - * IEU1, and clobbers %o7 which needs to be restored. This instruction - * sequence takes about 4 cycles due to instruction interdependence. Reading - * the pc takes 4 cycles to dispatch and is always dispatched alone. That - * sequence takes 7 cycles. - */ -#ifdef __arch64__ -#define PIC_PROLOGUE(dest,tmp) \ - mov %o7, tmp; \ - sethi %hi(_GLOBAL_OFFSET_TABLE_-4),dest; \ - call 0f; \ - or dest,%lo(_GLOBAL_OFFSET_TABLE_+4),dest; \ -0: \ - add dest,%o7,dest; \ - mov tmp, %o7 -#else -#define PIC_PROLOGUE(dest,tmp) \ - mov %o7,tmp; 3: call 4f; nop; 4: \ - sethi %hi(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ - or dest,%lo(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ - add dest,%o7,dest; mov tmp,%o7 -#endif - -/* - * PICCY_SET() does the equivalent of a `set var, %dest' instruction in - * a PIC-like way, but without involving the Global Offset Table. This - * only works for VARs defined in the same file *and* in the text segment. - */ -#ifdef __arch64__ -#define PICCY_SET(var,dest,tmp) \ - 3: rd %pc, tmp; add tmp,(var-3b),dest -#else -#define PICCY_SET(var,dest,tmp) \ - mov %o7,tmp; 3: call 4f; nop; 4: \ - add %o7,(var-3b),dest; mov tmp,%o7 -#endif -#else -#define PIC_PROLOGUE(dest,tmp) -#define PICCY_OFFSET(var,dest,tmp) -#endif - -#define FTYPE(x) .type x,@function -#define OTYPE(x) .type x,@object - -#define _ENTRY(name) \ - .align 4; .globl name; .proc 1; FTYPE(name); name: - -#ifdef GPROF -/* see _MCOUNT_ENTRY in profile.h */ -#ifdef __ELF__ -#ifdef __arch64__ -#define _PROF_PROLOGUE \ - .data; .align 8; 1: .uaword 0; .uaword 0; \ - .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call _mcount; \ - or %o0,%lo(1b),%o0; restore -#else -#define _PROF_PROLOGUE \ - .data; .align 4; 1: .long 0; \ - .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call _mcount; \ - or %o0,%lo(1b),%o0; restore -#endif -#else -#ifdef __arch64__ -#define _PROF_PROLOGUE \ - .data; .align 8; 1: .uaword 0; .uaword 0; \ - .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call mcount; \ - or %o0,%lo(1b),%o0; restore -#else -#define _PROF_PROLOGUE \ - .data; .align 4; 1: .long 0; \ - .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call mcount; \ - or %o0,%lo(1b),%o0; restore -#endif -#endif -#else -#define _PROF_PROLOGUE -#endif - -#define ENTRY(name) _ENTRY(_C_LABEL(name)); _PROF_PROLOGUE -#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name)) -#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)); _PROF_PROLOGUE -#define FUNC(name) ASENTRY(name) -#define RODATA(name) .align 4; .text; .globl _C_LABEL(name); \ - OTYPE(_C_LABEL(name)); _C_LABEL(name): - - -#define ASMSTR .asciz - -#define RCSID(name) .asciz name - -#ifdef __ELF__ -#define WEAK_ALIAS(alias,sym) \ - .weak alias; \ - alias = sym -#endif - -/* - * WARN_REFERENCES: create a warning if the specified symbol is referenced. - */ -#ifdef __ELF__ -#ifdef __STDC__ -#define WARN_REFERENCES(_sym,_msg) \ - .section .gnu.warning. ## _sym ; .ascii _msg ; .text -#else -#define WARN_REFERENCES(_sym,_msg) \ - .section .gnu.warning./**/_sym ; .ascii _msg ; .text -#endif /* __STDC__ */ -#else -#ifdef __STDC__ -#define __STRING(x) #x -#define WARN_REFERENCES(sym,msg) \ - .stabs msg ## ,30,0,0,0 ; \ - .stabs __STRING(_ ## sym) ## ,1,0,0,0 -#else -#define __STRING(x) "x" -#define WARN_REFERENCES(sym,msg) \ - .stabs msg,30,0,0,0 ; \ - .stabs __STRING(_/**/sym),1,0,0,0 -#endif /* __STDC__ */ -#endif /* __ELF__ */ - -#endif /* _ASM_H_ */ diff --git a/klibc/klibc/arch/sparc/include/machine/frame.h b/klibc/klibc/arch/sparc/include/machine/frame.h deleted file mode 100644 index b09175c7f4..0000000000 --- a/klibc/klibc/arch/sparc/include/machine/frame.h +++ /dev/null @@ -1,138 +0,0 @@ -/* $NetBSD: frame.h,v 1.4 2001/12/04 00:05:05 darrenr Exp $ */ - -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)frame.h 8.1 (Berkeley) 6/11/93 - */ - -#if defined(_KERNEL_OPT) -#include "opt_sparc_arch.h" -#endif - -/* - * Sparc stack frame format. - * - * Note that the contents of each stack frame may be held only in - * machine register windows. In order to get an accurate picture - * of the frame, you must first force the kernel to write any such - * windows to the stack. - */ -#ifndef _LOCORE -#ifndef SUN4U -struct frame { - int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ - int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ - struct frame *fr_fp; /* space to save frame pointer (%i6) */ - int32_t fr_pc; /* space to save return pc (%i7) */ - /* - * SunOS reserves another 8 words here; this is pointless - * but we do it for compatibility. - */ - int32_t fr_xxx; /* `structure return pointer' (unused) */ - int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ - int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ -}; -#else -struct frame32 { - int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ - int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ - u_int32_t fr_fp; /* space to save frame pointer (%i6) */ - u_int32_t fr_pc; /* space to save return pc (%i7) */ - /* - * SunOS reserves another 8 words here; this is pointless - * but we do it for compatibility. - */ - int32_t fr_xxx; /* `structure return pointer' (unused) */ - int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ - int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ -}; -#endif -#endif - -/* - * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if - * a function is to call C code. It should be just 64, but Sun defined - * their frame with space to hold arguments 0 through 5 (plus some junk), - * and varargs routines (such as kprintf) demand this, and gcc uses this - * area at times anyway. - */ -#define CCFSZ 96 - -/* - * Sparc v9 stack frame format. - * - * Note that the contents of each stack frame may be held only in - * machine register windows. In order to get an accurate picture - * of the frame, you must first force the kernel to write any such - * windows to the stack. - * - * V9 frames have an odd bias, so you can tall a v9 frame from - * a v8 frame by testing the stack pointer's lsb. - */ -#if !defined(_LOCORE) && !defined(_LIBC) -struct frame64 { - int64_t fr_local[8]; /* space to save locals (%l0..%l7) */ - int64_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ - u_int64_t fr_fp; /* space to save frame pointer (%i6) */ - u_int64_t fr_pc; /* space to save return pc (%i7) */ - /* - * SVR4 reserves a bunch of extra stuff. - */ - int64_t fr_argd[6]; /* `register save area' (lunacy) */ - int64_t fr_argx[0]; /* arg extension (args 7..n; variable size) */ -}; - -#define v9next_frame(f) ((struct frame64*)(f->fr_fp+BIAS)) -#endif - -/* - * CC64FSZ (C Compiler 64-bit Frame SiZe) is the size of a stack frame used - * by the compiler in 64-bit mode. It is (16)*8; space for 8 ins, 8 outs. - */ -#define CC64FSZ 176 - -/* - * v9 stacks all have a bias of 2047 added to the %sp and %fp, so you can easily - * detect it by testing the register for an odd value. Why 2K-1 I don't know. - */ -#define BIAS (2048-1) - diff --git a/klibc/klibc/arch/sparc/include/machine/trap.h b/klibc/klibc/arch/sparc/include/machine/trap.h deleted file mode 100644 index 42c3ef6ae2..0000000000 --- a/klibc/klibc/arch/sparc/include/machine/trap.h +++ /dev/null @@ -1,141 +0,0 @@ -/* $NetBSD: trap.h,v 1.11 1999/01/20 00:15:08 pk Exp $ */ - -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)trap.h 8.1 (Berkeley) 6/11/93 - */ -/* - * Sun4m support by Aaron Brown, Harvard University. - * Changes Copyright (c) 1995 The President and Fellows of Harvard College. - * All rights reserved. - */ - -#ifndef _MACHINE_TRAP_H -#define _MACHINE_TRAP_H - -/* trap vec (pri) description */ -#define T_RESET 0x00 /* (1) not actually vectored; jumps to 0 */ -#define T_TEXTFAULT 0x01 /* (2) address fault during instr fetch */ -#define T_ILLINST 0x02 /* (3) illegal instruction */ -#define T_PRIVINST 0x03 /* (4) privileged instruction */ -#define T_FPDISABLED 0x04 /* (5) fp instr while fp disabled */ -#define T_WINOF 0x05 /* (6) register window overflow */ -#define T_WINUF 0x06 /* (7) register window underflow */ -#define T_ALIGN 0x07 /* (8) address not properly aligned */ -#define T_FPE 0x08 /* (9) floating point exception */ -#define T_DATAFAULT 0x09 /* (10) address fault during data fetch */ -#define T_TAGOF 0x0a /* (11) tag overflow */ -/* 0x0b unused */ -/* 0x0c unused */ -/* 0x0d unused */ -/* 0x0e unused */ -/* 0x0f unused */ -/* 0x10 unused */ -#define T_L1INT 0x11 /* (27) level 1 interrupt */ -#define T_L2INT 0x12 /* (26) level 2 interrupt */ -#define T_L3INT 0x13 /* (25) level 3 interrupt */ -#define T_L4INT 0x14 /* (24) level 4 interrupt */ -#define T_L5INT 0x15 /* (23) level 5 interrupt */ -#define T_L6INT 0x16 /* (22) level 6 interrupt */ -#define T_L7INT 0x17 /* (21) level 7 interrupt */ -#define T_L8INT 0x18 /* (20) level 8 interrupt */ -#define T_L9INT 0x19 /* (19) level 9 interrupt */ -#define T_L10INT 0x1a /* (18) level 10 interrupt */ -#define T_L11INT 0x1b /* (17) level 11 interrupt */ -#define T_L12INT 0x1c /* (16) level 12 interrupt */ -#define T_L13INT 0x1d /* (15) level 13 interrupt */ -#define T_L14INT 0x1e /* (14) level 14 interrupt */ -#define T_L15INT 0x1f /* (13) level 15 interrupt */ -/* 0x20 unused */ -/* through 0x23 unused */ -#define T_CPDISABLED 0x24 /* (5) coprocessor instr while disabled */ -#define T_UNIMPLFLUSH 0x25 /* Unimplemented FLUSH */ -/* through 0x27 unused */ -#define T_CPEXCEPTION 0x28 /* (9) coprocessor exception */ -/* 0x29 unused */ -#define T_IDIV0 0x2a /* divide by zero (from hw [su]div instr) */ -#define T_STOREBUFFAULT 0x2b /* SuperSPARC: Store buffer copy-back fault */ -/* 0x2c unused */ -/* through 0x7f unused */ - -/* beginning of `user' vectors (from trap instructions) - all priority 12 */ -#define T_SUN_SYSCALL 0x80 /* system call */ -#define T_BREAKPOINT 0x81 /* breakpoint `instruction' */ -#define T_DIV0 0x82 /* division routine was handed 0 */ -#define T_FLUSHWIN 0x83 /* flush windows */ -#define T_CLEANWIN 0x84 /* provide clean windows */ -#define T_RANGECHECK 0x85 /* ? */ -#define T_FIXALIGN 0x86 /* fix up unaligned accesses */ -#define T_INTOF 0x87 /* integer overflow ? */ -#define T_SVR4_SYSCALL 0x88 /* SVR4 system call */ -#define T_BSD_SYSCALL 0x89 /* BSD system call */ -#define T_KGDB_EXEC 0x8a /* for kernel gdb */ - -/* 0x8b..0xff are currently unallocated, except the following */ -#define T_SVR4_GETCC 0xa0 -#define T_SVR4_SETCC 0xa1 -#define T_SVR4_GETPSR 0xa2 -#define T_SVR4_SETPSR 0xa3 -#define T_SVR4_GETHRTIME 0xa4 -#define T_SVR4_GETHRVTIME 0xa5 -#define T_SVR4_GETHRESTIME 0xa7 - - -#ifdef _KERNEL /* pseudo traps for locore.s */ -#define T_RWRET -1 /* need first user window for trap return */ -#define T_AST -2 /* no-op, just needed reschedule or profile */ -#endif - -/* flags to system call (flags in %g1 along with syscall number) */ -#define SYSCALL_G2RFLAG 0x400 /* on success, return to %g2 rather than npc */ -#define SYSCALL_G7RFLAG 0x800 /* use %g7 as above (deprecated) */ - -/* - * `software trap' macros to keep people happy (sparc v8 manual says not - * to set the upper bits). - */ -#define ST_BREAKPOINT (T_BREAKPOINT & 0x7f) -#define ST_DIV0 (T_DIV0 & 0x7f) -#define ST_FLUSHWIN (T_FLUSHWIN & 0x7f) -#define ST_SYSCALL (T_SUN_SYSCALL & 0x7f) - -#endif /* _MACHINE_TRAP_H_ */ diff --git a/klibc/klibc/arch/sparc/syscall.S b/klibc/klibc/arch/sparc/syscall.S new file mode 100644 index 0000000000..c0273f77ca --- /dev/null +++ b/klibc/klibc/arch/sparc/syscall.S @@ -0,0 +1,19 @@ +/* + * arch/sparc/syscall.S + * + * Common system-call stub; %g1 already set to syscall number + */ + + .globl __syscall_common + .type __syscall_common,#function + .align 4 +__syscall_common: + t 0x10 + bcc 1f + sethi %hi(errno), %g4 + or %g4, %lo(errno), %g4 + st %o0,[%g4] + mov -1, %o0 +1: + retl + nop diff --git a/klibc/klibc/arch/sparc/sysfork.S b/klibc/klibc/arch/sparc/sysfork.S new file mode 100644 index 0000000000..a66c76e9db --- /dev/null +++ b/klibc/klibc/arch/sparc/sysfork.S @@ -0,0 +1,25 @@ +/* + * arch/sparc/sysfork.S + * + * The fork and vfork system calls are special on sparc[64]: + * they return the "other process" pid in %o0 and the + * "is child" flag in %o1 + * + * Common system-call stub; %g1 already set to syscall number + */ + + .globl __syscall_forkish + .type __syscall_forkish,#function + .align 4 +__syscall_forkish: + t 0x10 + sub %o1, 1, %o1 + bcc,a 1f + and %o0, %o1, %o0 + sethi %hi(errno), %g4 + or %g4, %lo(errno), %g4 + st %o0,[%g4] + mov -1, %o0 +1: + retl + nop diff --git a/klibc/klibc/arch/sparc/sysstub.ph b/klibc/klibc/arch/sparc/sysstub.ph new file mode 100644 index 0000000000..baad9e3d82 --- /dev/null +++ b/klibc/klibc/arch/sparc/sysstub.ph @@ -0,0 +1,25 @@ +# -*- perl -*- +# +# arch/sparc32/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + $stype = $stype || 'common'; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT "\tb __syscall_${stype}\n"; + print OUT "\t mov\t__NR_${sname}, %g1\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/sparc64/Makefile.inc b/klibc/klibc/arch/sparc64/Makefile.inc index d59f9878e9..06b79537a3 100644 --- a/klibc/klibc/arch/sparc64/Makefile.inc +++ b/klibc/klibc/arch/sparc64/Makefile.inc @@ -8,6 +8,8 @@ # ARCHOBJS = \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ + arch/$(ARCH)/sysfork.o archclean: diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h b/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h deleted file mode 100644 index 022a31e542..0000000000 --- a/klibc/klibc/arch/sparc64/include/klibc/archsetjmp.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/sparc64/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __sp; - unsigned long __fp; - unsigned long __pc; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsignal.h b/klibc/klibc/arch/sparc64/include/klibc/archsignal.h deleted file mode 100644 index f81bd668bb..0000000000 --- a/klibc/klibc/arch/sparc64/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/sparc64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/sparc64/include/klibc/archsys.h b/klibc/klibc/arch/sparc64/include/klibc/archsys.h deleted file mode 100644 index 651e4f7f09..0000000000 --- a/klibc/klibc/arch/sparc64/include/klibc/archsys.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * arch/sparc64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* The Linux 2.5.31 SPARC64 syscall macros are just plain broken */ - -#undef _syscall0 -#undef _syscall1 -#undef _syscall2 -#undef _syscall3 -#undef _syscall4 -#undef _syscall5 -#undef _syscall6 - -#define _syscall0(type,name) \ -type name (void) \ -{ \ - register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ - register unsigned long __ret __asm__("o0"); \ - __asm__ __volatile__ ("t 0x6d\n\t" \ - "bcs,a %%xcc, 1f\n\t" \ - " st %0,%1\n\t" \ - "1:" \ - "movcs %%xcc,-1,%0\n" \ - : "=&r" (__ret), "+m" (errno) \ - : "r" (__g1) \ - : "cc"); \ - return (type) __ret; \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name (type1 arg1) \ -{ \ - register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ - register unsigned long __ret __asm__("o0"); \ - type1 __o0 = (arg1); \ - __asm__ __volatile__ ("t 0x6d\n\t" \ - "bcs,a %%xcc, 1f\n\t" \ - " st %0,%1\n\t" \ - "1:" \ - "movcs %%xcc,-1,%0\n" \ - : "=&r" (__ret), "+m" (errno) \ - : "0" (__o0), "r" (__g1) \ - : "cc"); \ - return (type) __ret; \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name (type1 arg1,type2 arg2) \ -{ \ - register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ - register unsigned long __ret __asm__("o0"); \ - type1 __o0 = (arg1); \ - register type2 __o1 __asm__ ("o1") = (arg2); \ - __asm__ __volatile__ ("t 0x6d\n\t" \ - "bcs,a %%xcc, 1f\n\t" \ - " st %0,%1\n\t" \ - "1:" \ - "movcs %%xcc,-1,%0\n" \ - : "=&r" (__ret), "+m" (errno) \ - : "0" (__o0), "r" (__o1), "r" (__g1) \ - : "cc"); \ - return (type) __ret; \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name (type1 arg1,type2 arg2,type3 arg3) \ -{ \ - register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ - register unsigned long __ret __asm__("o0"); \ - type1 __o0 = (arg1); \ - register type2 __o1 __asm__ ("o1") = (arg2); \ - register type3 __o2 __asm__ ("o2") = (arg3); \ - __asm__ __volatile__ ("t 0x6d\n\t" \ - "bcs,a %%xcc, 1f\n\t" \ - " st %0,%1\n\t" \ - "1:" \ - "movcs %%xcc,-1,%0\n" \ - : "=&r" (__ret), "+m" (errno) \ - : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ - : "cc"); \ - return (type) __ret; \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ -{ \ - register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ - register unsigned long __ret __asm__("o0"); \ - type1 __o0 = (arg1); \ - register type2 __o1 __asm__ ("o1") = (arg2); \ - register type3 __o2 __asm__ ("o2") = (arg3); \ - register type4 __o3 __asm__ ("o3") = (arg4); \ - __asm__ __volatile__ ("t 0x6d\n\t" \ - "bcs,a %%xcc, 1f\n\t" \ - " st %0,%1\n\t" \ - "1:" \ - "movcs %%xcc,-1,%0\n" \ - : "=&r" (__ret), "+m" (errno) \ - : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ - : "cc"); \ - return (type) __ret; \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,\ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ - register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ - register unsigned long __ret __asm__("o0"); \ - type1 __o0 = (arg1); \ - register type2 __o1 __asm__ ("o1") = (arg2); \ - register type3 __o2 __asm__ ("o2") = (arg3); \ - register type4 __o3 __asm__ ("o3") = (arg4); \ - register type5 __o4 __asm__ ("o4") = (arg5); \ - __asm__ __volatile__ ("t 0x6d\n\t" \ - "bcs,a %%xcc, 1f\n\t" \ - " st %0,%1\n\t" \ - "1:" \ - "movcs %%xcc,-1,%0\n" \ - : "=&r" (__ret), "+m" (errno) \ - : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), \ - "r" (__g1) \ - : "cc"); \ - return (type) __ret; \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ - register unsigned long __g1 __asm__ ("g1") = __NR_##name; \ - register unsigned long __ret __asm__("o0"); \ - type1 __o0 = (arg1); \ - register type2 __o1 __asm__ ("o1") = (arg2); \ - register type3 __o2 __asm__ ("o2") = (arg3); \ - register type4 __o3 __asm__ ("o3") = (arg4); \ - register type5 __o4 __asm__ ("o4") = (arg5); \ - register type6 __o5 __asm__ ("o5") = (arg6); \ - __asm__ __volatile__ ("t 0x6d\n\t" \ - "bcs,a %%xcc, 1f\n\t" \ - " st %0,%1\n\t" \ - "1:" \ - "movcs %%xcc,-1,%0\n" \ - : "=&r" (__ret), "+m" (errno) \ - : "0" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), \ - "r" (__o5), "r" (__g1) \ - : "cc"); \ - return (type) __ret; \ -} - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/sparc64/syscall.S b/klibc/klibc/arch/sparc64/syscall.S new file mode 100644 index 0000000000..7ab9d95f11 --- /dev/null +++ b/klibc/klibc/arch/sparc64/syscall.S @@ -0,0 +1,18 @@ +/* + * arch/sparc64/syscall.S + * + * Common system-call stub; %g1 already set to syscall number + */ + + .globl __syscall_common + .type __syscall_common,#function + .align 4 +__syscall_common: + t 0x6d + bcc %xcc, 1f + sethi %hi(errno), %g4 + or %g4, %lo(errno), %g4 + st %o0,[%g4] +1: + retl + movcs %xcc, -1, %o0 diff --git a/klibc/klibc/arch/sparc64/sysfork.S b/klibc/klibc/arch/sparc64/sysfork.S new file mode 100644 index 0000000000..739c35ede3 --- /dev/null +++ b/klibc/klibc/arch/sparc64/sysfork.S @@ -0,0 +1,26 @@ +/* + * arch/sparc64/sysfork.S + * + * The fork and vfork system calls are special on sparc[64]: + * they return the "other process" pid in %o0 and the + * "is child" flag in %o1 + * + * Common system-call stub; %g1 already set to syscall number + * + * IS THIS CORRECT FOR SPARC64? + */ + + .globl __syscall_forkish + .type __syscall_forkish,#function + .align 4 +__syscall_forkish: + t 0x6d + sub %o1, 1, %o1 + bcc,a %xcc, 1f + and %o0, %o1, %o0 + sethi %hi(errno), %g4 + or %g4, %lo(errno), %g4 + st %o0,[%g4] +1: + retl + movcs %xcc, -1, %o0 diff --git a/klibc/klibc/arch/sparc64/sysstub.ph b/klibc/klibc/arch/sparc64/sysstub.ph new file mode 100644 index 0000000000..2ef2c6b66e --- /dev/null +++ b/klibc/klibc/arch/sparc64/sysstub.ph @@ -0,0 +1,25 @@ +# -*- perl -*- +# +# arch/sparc64/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + $stype = $stype || 'common'; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT "\tb __syscall_${stype}\n"; + print OUT "\t mov\t__NR_${sname}, %g1\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG index ecb14ccb70..f3c87410a6 100644 --- a/klibc/klibc/arch/x86_64/MCONFIG +++ b/klibc/klibc/arch/x86_64/MCONFIG @@ -9,8 +9,14 @@ # Blatantly copied and modified from i386 version by Mats Petersson, AMD. # +# +# NOTE: -fno-asynchronous-unwind-tables produce significantly smaller +# binaries (20% smaller), but makes the code completely useless for +# debugging using gdb. +# ARCHREQFLAGS = -m64 -OPTFLAGS = -Os -fomit-frame-pointer -falign-functions=0 -falign-jumps=0 -falign-loops=0 +OPTFLAGS = -Os -fno-asynchronous-unwind-tables -fomit-frame-pointer \ + -falign-functions=0 -falign-jumps=0 -falign-loops=0 BITSIZE = 64 LDFLAGS = -m elf_x86_64 diff --git a/klibc/klibc/arch/x86_64/Makefile.inc b/klibc/klibc/arch/x86_64/Makefile.inc index c84443f4e1..d6cc1204e4 100644 --- a/klibc/klibc/arch/x86_64/Makefile.inc +++ b/klibc/klibc/arch/x86_64/Makefile.inc @@ -9,7 +9,8 @@ ARCHOBJS = \ arch/$(ARCH)/exits.o \ - arch/$(ARCH)/setjmp.o + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h b/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h deleted file mode 100644 index 90d0a0d263..0000000000 --- a/klibc/klibc/arch/x86_64/include/klibc/archsetjmp.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/x86_64/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __rbx; - unsigned long __rsp; - unsigned long __rbp; - unsigned long __r12; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __rip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsignal.h b/klibc/klibc/arch/x86_64/include/klibc/archsignal.h deleted file mode 100644 index 74e82e1dd0..0000000000 --- a/klibc/klibc/arch/x86_64/include/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/x86_64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/klibc/arch/x86_64/include/klibc/archsys.h b/klibc/klibc/arch/x86_64/include/klibc/archsys.h deleted file mode 100644 index 2ec72cd397..0000000000 --- a/klibc/klibc/arch/x86_64/include/klibc/archsys.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * arch/x86_64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* The x86-64 syscall headers are needlessly inefficient */ - -#undef _syscall0 -#undef _syscall1 -#undef _syscall2 -#undef _syscall3 -#undef _syscall4 -#undef _syscall5 -#undef _syscall6 - -#define _syscall0(type,name) \ -type name (void) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name (type1 arg1) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name (type1 arg1,type2 arg2) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name (type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ -{ \ -long __res; \ -register type4 __r10 asm("%r10") = arg4; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3),"r" (__r10) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -register type4 __r10 asm("%r10") = arg4; \ -register type5 __r8 asm("%r8") = arg5; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3),"r" (__r10),"r" (__r8) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ -long __res; \ -register type4 __r10 asm("%r10") = arg4; \ -register type5 __r8 asm("%r8") = arg5; \ -register type6 __r9 asm("%r9") = arg6; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3),"r" (__r10),"r" (__r8), "r" (__r9) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/klibc/arch/x86_64/include/sys/io.h b/klibc/klibc/arch/x86_64/include/sys/io.h deleted file mode 100644 index 4a0ae44985..0000000000 --- a/klibc/klibc/arch/x86_64/include/sys/io.h +++ /dev/null @@ -1,126 +0,0 @@ -#ident "$Id: io.h,v 1.1 2004/01/25 01:34:29 hpa Exp $" -/* ----------------------------------------------------------------------- * - * - * Copyright 2004 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * sys/io.h for the i386 architecture - * - * Basic I/O macros - */ - -#ifndef _SYS_IO_H -#define _SYS_IO_H 1 - -/* I/O-related system calls */ - -int iopl(int); -int ioperm(unsigned long, unsigned long, int); - -/* Basic I/O macros */ - -static __inline__ void -outb(unsigned char __v, unsigned short __p) -{ - asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outw(unsigned short __v, unsigned short __p) -{ - asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outl(unsigned int __v, unsigned short __p) -{ - asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ unsigned char -inb(unsigned short __p) -{ - unsigned char __v; - asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); - return v; -} - -static __inline__ unsigned short -inw(unsigned short __p) -{ - unsigned short __v; - asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); - return v; -} - -static __inline__ unsigned int -inl(unsigned short __p) -{ - unsigned int __v; - asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); - return v; -} - -/* String I/O macros */ - -static __inline__ void -outsb (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsw (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsl (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - - -static __inline__ void -insb (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insw (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insl (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -#endif /* _SYS_IO_H */ diff --git a/klibc/klibc/arch/x86_64/syscall.S b/klibc/klibc/arch/x86_64/syscall.S new file mode 100644 index 0000000000..f2c74ae974 --- /dev/null +++ b/klibc/klibc/arch/x86_64/syscall.S @@ -0,0 +1,28 @@ +/* + * arch/x86-64/syscall.S + * + * Common tail-handling code for system calls. + * + * The arguments are in the standard argument registers; the system + * call number in %eax. + */ + .text + .align 4 + .globl __syscall_common + .type __syscall_common,@function +__syscall_common: + movq %rcx,%r10 # The kernel uses %r10 istf %rcx + syscall + + cmpq $-4095,%rax + jb 1f + + # Error return, must set errno + negl %eax + movl %eax,errno(%rip) # errno is type int, so 32 bits + orq $-1,%rax # orq $-1 smaller than movq $-1 + +1: + ret + + .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/x86_64/sysstub.ph b/klibc/klibc/arch/x86_64/sysstub.ph new file mode 100644 index 0000000000..07af1227ca --- /dev/null +++ b/klibc/klibc/arch/x86_64/sysstub.ph @@ -0,0 +1,23 @@ +# -*- perl -*- +# +# arch/x86_64/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.type ${fname},\@function\n"; + print OUT "\t.globl ${fname}\n"; + print OUT "${fname}:\n"; + print OUT "\tmovl \$__NR_${sname},%eax\n"; # Zero-extends to 64 bits + print OUT "\tjmp __syscall_common\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/asprintf.c b/klibc/klibc/asprintf.c new file mode 100644 index 0000000000..457d34bb15 --- /dev/null +++ b/klibc/klibc/asprintf.c @@ -0,0 +1,30 @@ +/* + * asprintf.c + */ + +#include +#include +#include + +int asprintf(char **bufp, const char *format, ...) +{ + va_list ap, ap1; + int rv; + int bytes; + char *p; + + va_start(ap, format); + va_copy(ap1, ap); + + bytes = vsnprintf(NULL, 0, format, ap1); + va_end(ap1); + + *bufp = p = malloc(bytes+1); + if ( !p ) + return -1; + + rv = vsnprintf(p, bytes, format, ap); + va_end(ap); + + return rv; +} diff --git a/klibc/klibc/ctypes.c b/klibc/klibc/ctypes.c index c7adc9882c..acfa05ab65 100644 --- a/klibc/klibc/ctypes.c +++ b/klibc/klibc/ctypes.c @@ -10,41 +10,41 @@ const unsigned char __ctypes[257] = { 0, /* EOF */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - __ctype_space, /* BS */ - __ctype_space, /* TAB */ - __ctype_space, /* LF */ - __ctype_space, /* VT */ - __ctype_space, /* FF */ - __ctype_space, /* CR */ - 0, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl|__ctype_space, /* BS */ + __ctype_cntrl|__ctype_space, /* TAB */ + __ctype_cntrl|__ctype_space, /* LF */ + __ctype_cntrl|__ctype_space, /* VT */ + __ctype_cntrl|__ctype_space, /* FF */ + __ctype_cntrl|__ctype_space, /* CR */ + __ctype_cntrl, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ - __ctype_space|__ctype_print, /* space */ + __ctype_print|__ctype_space, /* space */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ @@ -61,16 +61,16 @@ const unsigned char __ctypes[257] = { __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ - __ctype_digit|__ctype_xdigit|__ctype_print, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ + __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ @@ -79,33 +79,33 @@ const unsigned char __ctypes[257] = { __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ - __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ - __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ - __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ - __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ - __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ - __ctype_upper|__ctype_print|__ctype_xdigit, /* A-F */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ + __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ + __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ + __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ + __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ + __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ + __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ - __ctype_upper|__ctype_print, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ + __ctype_print|__ctype_upper, /* G-Z */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ @@ -113,74 +113,74 @@ const unsigned char __ctypes[257] = { __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ - __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ - __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ - __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ - __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ - __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ - __ctype_lower|__ctype_print|__ctype_xdigit, /* a-f */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ + __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ + __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ + __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ + __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ + __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ + __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ - __ctype_lower|__ctype_print, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ + __ctype_print|__ctype_lower, /* g-z */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ - 0, /* control character */ + __ctype_cntrl, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ - 0, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ + __ctype_cntrl, /* control character */ - __ctype_space|__ctype_print, /* NBSP */ + __ctype_print|__ctype_space, /* NBSP */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ @@ -214,71 +214,71 @@ const unsigned char __ctypes[257] = { __ctype_print|__ctype_punct, /* punctuation */ __ctype_print|__ctype_punct, /* punctuation */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ __ctype_print|__ctype_punct, /* punctuation */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_upper|__ctype_print, /* upper accented */ - __ctype_lower|__ctype_print, /* lower accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_upper, /* upper accented */ + __ctype_print|__ctype_lower, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ __ctype_print|__ctype_punct, /* punctuation */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ - __ctype_lower|__ctype_print, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ + __ctype_print|__ctype_lower, /* lower accented */ }; diff --git a/klibc/klibc/daemon.c b/klibc/klibc/daemon.c new file mode 100644 index 0000000000..75d7146205 --- /dev/null +++ b/klibc/klibc/daemon.c @@ -0,0 +1,38 @@ +/* + * daemon.c - "daemonize" a process + */ + +#include +#include +#include + +int daemon(int nochdir, int noclose) +{ + int nullfd; + pid_t f; + + if ( !nochdir ) { + if ( chdir("/") ) + return -1; + } + + if ( !noclose ) { + if ( (nullfd = open("/dev/null", O_RDWR)) < 0 || + dup2(nullfd, 0) < 0 || + dup2(nullfd, 1) < 0 || + dup2(nullfd, 2) < 0 ) + return -1; + close(nullfd); + } + + f = fork(); + if ( f < 0 ) + return -1; + else if ( f > 0 ) + _exit(0); + + + return setsid(); +} + + diff --git a/klibc/klibc/fdatasync.c b/klibc/klibc/fdatasync.c deleted file mode 100644 index 53079b09d6..0000000000 --- a/klibc/klibc/fdatasync.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * fdatasync.c - * - * Some systems don't have this (alpha?) ... this is really a bug, - * but mimic using fsync() - */ - -#include -#include - -#ifndef __NR_fdatasync -#define __NR_fdatasync __NR_fsync -#endif - -_syscall1(int,fdatasync,int,fd); diff --git a/klibc/klibc/fork.c b/klibc/klibc/fork.c index d7e4db89a1..daf313eaf2 100644 --- a/klibc/klibc/fork.c +++ b/klibc/klibc/fork.c @@ -9,21 +9,13 @@ #include #include -#ifdef __NR_fork +#ifndef __NR_fork -#ifdef _syscall0_forkish -_syscall0_forkish(pid_t,fork); -#else -_syscall0(pid_t,fork); -#endif - -#else /* __NR_fork */ - -static inline _syscall2(pid_t,clone,unsigned long,flags,void *,newsp); +extern pid_t __clone(unsigned long flags, void * newsp); pid_t fork(void) { - return clone(SIGCHLD, 0); + return __clone(SIGCHLD, 0); } #endif /* __NR_fork */ diff --git a/klibc/klibc/fstatfs.c b/klibc/klibc/fstatfs.c new file mode 100644 index 0000000000..09e4674947 --- /dev/null +++ b/klibc/klibc/fstatfs.c @@ -0,0 +1,19 @@ +/* + * fstatfs.c + * + * On architectures which do fstatfs64, wrap the system call + */ + +#include +#include + +#ifdef __NR_fstatfs64 + +extern int __fstatfs64(int, size_t, struct statfs *); + +int fstatfs(int fd, struct statfs *buf) +{ + return __fstatfs64(fd, sizeof *buf, buf); +} + +#endif diff --git a/klibc/klibc/getcwd.c b/klibc/klibc/getcwd.c index 350ec69a63..613ca0529c 100644 --- a/klibc/klibc/getcwd.c +++ b/klibc/klibc/getcwd.c @@ -1,12 +1,13 @@ /* * getcwd.c + * + * The system call behaves differently than the library function. */ #include #include -#define __NR___getcwd __NR_getcwd -static inline _syscall2(int,__getcwd,char *,buf,size_t,size); +extern int __getcwd(char * buf, size_t size); char *getcwd(char *buf, size_t size) { diff --git a/klibc/klibc/getpagesize.c b/klibc/klibc/getpagesize.c deleted file mode 100644 index 2d975b1586..0000000000 --- a/klibc/klibc/getpagesize.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * getpagesize.c - */ - -#include -#include - -/* Presumably there is a better way to do this... */ -#ifdef __ia64__ -# define __NR_getpagesize 1171 -#endif - -#ifdef __NR_getpagesize - -_syscall0(int,getpagesize); - -#else - -int getpagesize(void) -{ - return PAGE_SIZE; -} - -#endif - - diff --git a/klibc/klibc/getpriority.c b/klibc/klibc/getpriority.c index d6db2cc6b9..4ea630487d 100644 --- a/klibc/klibc/getpriority.c +++ b/klibc/klibc/getpriority.c @@ -10,16 +10,14 @@ #include #include -#define __NR__getpriority __NR_getpriority +#if !defined(__alpha__) && !defined(__ia64__) -static inline _syscall2(int,_getpriority,int,which,int,who); +extern int __getpriority(int, int); int getpriority(int which, int who) { -#if defined(__alpha__) || defined(__ia64__) - return _getpriority(which, who); -#else - int rv = _getpriority(which, who); + int rv = __getpriority(which, who); return ( rv < 0 ) ? rv : 20-rv; -#endif } + +#endif diff --git a/klibc/klibc/include/alloca.h b/klibc/klibc/include/alloca.h deleted file mode 100644 index 41a4d94d44..0000000000 --- a/klibc/klibc/include/alloca.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * alloca.h - * - * Just call the builtin alloca() function - */ - -#ifndef _ALLOCA_H -#define _ALLOCA_H - -#define alloca(size) __builtin_alloca(size) - -#endif /* _ALLOCA_H */ - diff --git a/klibc/klibc/include/arpa/inet.h b/klibc/klibc/include/arpa/inet.h deleted file mode 100644 index 043b148e17..0000000000 --- a/klibc/klibc/include/arpa/inet.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arpa/inet.h - */ - -#ifndef _ARPA_INET_H -#define _ARPA_INET_H - -#include -#include -#include -#include -#include - -__extern uint32_t inet_addr(const char *); -__extern int inet_aton(const char *, struct in_addr *); -__extern char *inet_ntoa(struct in_addr); -__extern int inet_pton(int, const char *, void *); -__extern const char *inet_ntop(int, const void *, char *, size_t); -__extern unsigned int inet_nsap_addr(const char *, unsigned char *, int); -__extern char *inet_nsap_ntoa(int, const unsigned char *, char *); - -#endif /* _ARPA_INET_H */ - - diff --git a/klibc/klibc/include/assert.h b/klibc/klibc/include/assert.h deleted file mode 100644 index 58cc37c487..0000000000 --- a/klibc/klibc/include/assert.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * assert.h - */ - -#ifndef _ASSERT_H -#define _ASSERT_H - -#ifdef NDEBUG - -#define assert(x) ((void)(x)) - -#else - -extern void __assert_fail(const char *, const char *, - unsigned int); - -#define assert(x) ((x) ? (void)0 : __assert_fail(#x, __FILE__, __LINE__)) - -#endif - -#endif /* _ASSERT_H */ - diff --git a/klibc/klibc/include/bits32/bitsize/limits.h b/klibc/klibc/include/bits32/bitsize/limits.h deleted file mode 100644 index f90e524b2b..0000000000 --- a/klibc/klibc/include/bits32/bitsize/limits.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * bits32/limits.h - */ - -#ifndef _BITSIZE_LIMITS_H -#define _BITSIZE_LIMITS_H - -#define LONG_BIT 32 - -#define LONG_MIN (-2147483647L-1) -#define LONG_MAX 2147483647L -#define ULONG_MAX 4294967295UL - -#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stddef.h b/klibc/klibc/include/bits32/bitsize/stddef.h deleted file mode 100644 index bf6e695ed3..0000000000 --- a/klibc/klibc/include/bits32/bitsize/stddef.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bits32/stddef.h - */ - -#ifndef _BITSIZE_STDDEF_H -#define _BITSIZE_STDDEF_H - -#define _SIZE_T -#if (defined(__s390__) || defined(__hppa__) || defined(__cris__)) -typedef unsigned long size_t; -#else -typedef unsigned int size_t; -#endif - -#define _PTRDIFF_T -typedef signed int ptrdiff_t; - -#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stdint.h b/klibc/klibc/include/bits32/bitsize/stdint.h deleted file mode 100644 index 40b464961c..0000000000 --- a/klibc/klibc/include/bits32/bitsize/stdint.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * bits32/stdint.h - */ - -#ifndef _BITSIZE_STDINT_H -#define _BITSIZE_STDINT_H - -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long int uint64_t; - -typedef int int_fast16_t; -typedef int int_fast32_t; - -typedef unsigned int uint_fast16_t; -typedef unsigned int uint_fast32_t; - -typedef int intptr_t; -typedef unsigned int uintptr_t; - -#define __INT64_C(c) c ## LL -#define __UINT64_C(c) c ## ULL - -#define __PRI64_RANK "ll" -#define __PRIFAST_RANK "" -#define __PRIPTR_RANK "" - -#endif /* _BITSIZE_STDINT_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stdintconst.h b/klibc/klibc/include/bits32/bitsize/stdintconst.h deleted file mode 100644 index 8157dd06e0..0000000000 --- a/klibc/klibc/include/bits32/bitsize/stdintconst.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bits32/stdintconst.h - */ - -#ifndef _BITSIZE_STDINTCONST_H -#define _BITSIZE_STDINTCONST_H - -#define INT_FAST16_C(c) INT32_C(c) -#define INT_FAST32_C(c) INT32_C(c) - -#define UINT_FAST16_C(c) UINT32_C(c) -#define UINT_FAST32_C(c) UINT32_C(c) - -#define INTPTR_C(c) INT32_C(c) -#define UINTPTR_C(c) UINT32_C(c) -#define PTRDIFF_C(c) INT32_C(c) - -#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/klibc/include/bits32/bitsize/stdintlimits.h b/klibc/klibc/include/bits32/bitsize/stdintlimits.h deleted file mode 100644 index b44fe01186..0000000000 --- a/klibc/klibc/include/bits32/bitsize/stdintlimits.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * bits32/stdintlimits.h - */ - -#ifndef _BITSIZE_STDINTLIMITS_H -#define _BITSIZE_STDINTLIMITS_H - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX - -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX - -#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/klibc/include/bits64/bitsize/limits.h b/klibc/klibc/include/bits64/bitsize/limits.h deleted file mode 100644 index 7b20da085b..0000000000 --- a/klibc/klibc/include/bits64/bitsize/limits.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * bits64/limits.h - */ - -#ifndef _BITSIZE_LIMITS_H -#define _BITSIZE_LIMITS_H - -#define LONG_BIT 64 - -#define LONG_MIN (-9223372036854775807L-1) -#define LONG_MAX 9223372036854775807L -#define ULONG_MAX 18446744073709551615UL - -#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/klibc/include/bits64/bitsize/stddef.h b/klibc/klibc/include/bits64/bitsize/stddef.h deleted file mode 100644 index 3e72621862..0000000000 --- a/klibc/klibc/include/bits64/bitsize/stddef.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * bits64/stddef.h - */ - -#ifndef _BITSIZE_STDDEF_H -#define _BITSIZE_STDDEF_H - -#define _SIZE_T -typedef unsigned long size_t; -#define _PTRDIFF_T -typedef signed long ptrdiff_t; - -#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/klibc/include/bits64/bitsize/stdint.h b/klibc/klibc/include/bits64/bitsize/stdint.h deleted file mode 100644 index f569f526b6..0000000000 --- a/klibc/klibc/include/bits64/bitsize/stdint.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * bits64/stdint.h - */ - -#ifndef _BITSIZE_STDINT_H -#define _BITSIZE_STDINT_H - -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long int uint64_t; - -typedef long int int_fast16_t; -typedef long int int_fast32_t; - -typedef unsigned long int uint_fast16_t; -typedef unsigned long int uint_fast32_t; - -typedef long int intptr_t; -typedef unsigned long int uintptr_t; - -#define __INT64_C(c) c ## L -#define __UINT64_C(c) c ## UL - -#define __PRI64_RANK "l" -#define __PRIFAST_RANK "l" -#define __PRIPTR_RANK "l" - -#endif /* _BITSIZE_STDINT_H */ - - diff --git a/klibc/klibc/include/bits64/bitsize/stdintconst.h b/klibc/klibc/include/bits64/bitsize/stdintconst.h deleted file mode 100644 index 65f2db0501..0000000000 --- a/klibc/klibc/include/bits64/bitsize/stdintconst.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bits64/stdintconst.h - */ - -#ifndef _BITSIZE_STDINTCONST_H -#define _BITSIZE_STDINTCONST_H - -#define INT_FAST16_C(c) INT64_C(c) -#define INT_FAST32_C(c) INT64_C(c) - -#define UINT_FAST16_C(c) UINT64_C(c) -#define UINT_FAST32_C(c) UINT64_C(c) - -#define INTPTR_C(c) INT64_C(c) -#define UINTPTR_C(c) UINT64_C(c) -#define PTRDIFF_C(c) INT64_C(c) - -#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/klibc/include/bits64/bitsize/stdintlimits.h b/klibc/klibc/include/bits64/bitsize/stdintlimits.h deleted file mode 100644 index d110d17d2d..0000000000 --- a/klibc/klibc/include/bits64/bitsize/stdintlimits.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * bits64/stdintlimits.h - */ - -#ifndef _BITSIZE_STDINTLIMITS_H -#define _BITSIZE_STDINTLIMITS_H - -#define INT_FAST16_MIN INT64_MIN -#define INT_FAST32_MIN INT64_MIN -#define INT_FAST16_MAX INT64_MAX -#define INT_FAST32_MAX INT64_MAX -#define UINT_FAST16_MAX UINT64_MAX -#define UINT_FAST32_MAX UINT64_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX - -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX - -#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/klibc/include/ctype.h b/klibc/klibc/include/ctype.h deleted file mode 100644 index 3f5cfad558..0000000000 --- a/klibc/klibc/include/ctype.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * ctype.h - * - * This assumes ISO 8859-1, being a reasonable superset of ASCII. - */ - -#ifndef _CTYPE_H -#define _CTYPE_H - -#ifndef __CTYPE_NO_INLINE -# define __ctype_inline extern __inline__ -#else -# define __ctype_inline -#endif - -/* - * This relies on the following definitions: - * - * cntrl = !print - * alpha = upper|lower - * graph = punct|alpha|digit - * blank = '\t' || ' ' (per POSIX requirement) - */ -enum { - __ctype_upper = (1 << 0), - __ctype_lower = (1 << 1), - __ctype_digit = (1 << 2), - __ctype_xdigit = (1 << 3), - __ctype_space = (1 << 4), - __ctype_print = (1 << 5), - __ctype_punct = (1 << 6) -}; - -extern const unsigned char __ctypes[]; - -__ctype_inline int isalnum(int __c) -{ - return __ctypes[__c+1] & - (__ctype_upper|__ctype_lower|__ctype_digit); -} - -__ctype_inline int isalpha(int __c) -{ - return __ctypes[__c+1] & - (__ctype_upper|__ctype_lower); -} - -__ctype_inline int isascii(int __c) -{ - return !(__c & ~0x7f); -} - -__ctype_inline int isblank(int __c) -{ - return (__c == '\t') || (__c == ' '); -} - -__ctype_inline int iscntrl(int __c) -{ - return (__c >= 0) && !(__ctypes[__c+1] & __ctype_print); -} - -__ctype_inline int isdigit(int __c) -{ - return __ctypes[__c+1] & __ctype_digit; -} - -__ctype_inline int isgraph(int __c) -{ - return __ctypes[__c+1] & - (__ctype_upper|__ctype_lower|__ctype_digit|__ctype_punct); -} - -__ctype_inline int islower(int __c) -{ - return __ctypes[__c+1] & __ctype_lower; -} - -__ctype_inline int isprint(int __c) -{ - return __ctypes[__c+1] & __ctype_print; -} - -__ctype_inline int ispunct(int __c) -{ - return __ctypes[__c+1] & __ctype_punct; -} - -__ctype_inline int isspace(int __c) -{ - return __ctypes[__c+1] & __ctype_space; -} - -__ctype_inline int isupper(int __c) -{ - return __ctypes[__c+1] & __ctype_upper; -} - -__ctype_inline int isxdigit(int __c) -{ - return __ctypes[__c+1] & __ctype_xdigit; -} - -/* Note: this is decimal, not hex, to avoid accidental promotion to unsigned */ -#define _toupper(__c) ((__c) & ~32) -#define _tolower(__c) ((__c) | 32) - -__ctype_inline int toupper(int __c) -{ - return islower(__c) ? _toupper(__c) : __c; -} - -__ctype_inline int tolower(int __c) -{ - return isupper(__c) ? _tolower(__c) : __c; -} - -#endif /* _CTYPE_H */ diff --git a/klibc/klibc/include/dirent.h b/klibc/klibc/include/dirent.h deleted file mode 100644 index 10dd138ee5..0000000000 --- a/klibc/klibc/include/dirent.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * dirent.h - */ - -#ifndef _DIRENT_H -#define _DIRENT_H - -#include -#include - -#ifndef __IO_DIR_DEFINED -struct _IO_dir; -#endif -typedef struct _IO_dir DIR; - -__extern DIR *opendir(const char *); -__extern struct dirent *readdir(DIR *); -__extern int closedir(DIR *); - -#endif /* _DIRENT_H */ diff --git a/klibc/klibc/include/elf.h b/klibc/klibc/include/elf.h deleted file mode 100644 index 52f47d042e..0000000000 --- a/klibc/klibc/include/elf.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * elf.h - */ - -#ifndef _ELF_H -#define _ELF_H - -#include -#include - -#endif /* _ELF_H */ - diff --git a/klibc/klibc/include/endian.h b/klibc/klibc/include/endian.h deleted file mode 100644 index 44f89ccbbc..0000000000 --- a/klibc/klibc/include/endian.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * endian.h - */ - -#ifndef _ENDIAN_H -#define _ENDIAN_H - -#include -#include - -/* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or - __BIG_ENDIAN, but the glibc/BSD-ish macros expect both to be - defined with __BYTE_ORDER defining which is actually used... */ - -#if defined(__LITTLE_ENDIAN) -# undef __LITTLE_ENDIAN -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# define __PDP_ENDIAN 3412 -# define __BYTE_ORDER __LITTLE_ENDIAN -#elif defined(__BIG_ENDIAN) -# undef __BIG_ENDIAN -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# define __PDP_ENDIAN 3412 -# define __BYTE_ORDER __BIG_ENDIAN -#elif defined(__PDP_ENDIAN) -# undef __PDP_ENDIAN -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# define __PDP_ENDIAN 3412 -# define __BYTE_ORDER __PDP_ENDIAN -#else -# error "Unknown byte order!" -#endif - -#define LITTLE_ENDIAN __LITTLE_ENDIAN -#define BIG_ENDIAN __BIG_ENDIAN -#define PDP_ENDIAN __PDP_ENDIAN -#define BYTE_ORDER __BYTE_ORDER - -#endif /* _ENDIAN_H */ diff --git a/klibc/klibc/include/errno.h b/klibc/klibc/include/errno.h deleted file mode 100644 index b2e666504d..0000000000 --- a/klibc/klibc/include/errno.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * errno.h - */ - -#include -#include - -__extern int errno; diff --git a/klibc/klibc/include/fcntl.h b/klibc/klibc/include/fcntl.h deleted file mode 100644 index e90959c7e9..0000000000 --- a/klibc/klibc/include/fcntl.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * fcntl.h - */ - -#ifndef _FCNTL_H -#define _FCNTL_H - -#include -#include - -#endif /* _FCNTL_H */ diff --git a/klibc/klibc/include/grp.h b/klibc/klibc/include/grp.h deleted file mode 100644 index 03ceb31560..0000000000 --- a/klibc/klibc/include/grp.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * grp.h - */ - -#ifndef _GRP_H -#define _GRP_H - -#include -#include - -__extern int setgroups(size_t, const gid_t *); - -#endif /* _GRP_H */ diff --git a/klibc/klibc/include/inttypes.h b/klibc/klibc/include/inttypes.h deleted file mode 100644 index e00fa63160..0000000000 --- a/klibc/klibc/include/inttypes.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * inttypes.h - */ - -#ifndef _INTTYPES_H -#define _INTTYPES_H - -#include -#include -#include - -static __inline__ intmax_t imaxabs(intmax_t __n) -{ - return (__n < (intmax_t)0) ? -__n : __n; -} - -__extern intmax_t strtoimax(const char *, char **, int); -__extern uintmax_t strtoumax(const char *, char **, int); - -/* extensions */ -__extern intmax_t strntoimax(const char *, char **, int, size_t); -__extern uintmax_t strntoumax(const char *, char **, int, size_t); - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) - -#define PRId8 "d" -#define PRId16 "d" -#define PRId32 "d" -#define PRId64 __PRI64_RANK "d" - -#define PRIdLEAST8 "d" -#define PRIdLEAST16 "d" -#define PRIdLEAST32 "d" -#define PRIdLEAST64 __PRI64_RANK "d" - -#define PRIdFAST8 "d" -#define PRIdFAST16 __PRIFAST_RANK "d" -#define PRIdFAST32 __PRIFAST_RANK "d" -#define PRIdFAST64 __PRI64_RANK "d" - -#define PRIdMAX __PRI64_RANK "d" -#define PRIdPTR __PRIPTR_RANK "d" - -#define PRIi8 "i" -#define PRIi16 "i" -#define PRIi32 "i" -#define PRIi64 __PRI64_RANK "i" - -#define PRIiLEAST8 "i" -#define PRIiLEAST16 "i" -#define PRIiLEAST32 "i" -#define PRIiLEAST64 __PRI64_RANK "i" - -#define PRIiFAST8 "i" -#define PRIiFAST16 __PRIFAST_RANK "i" -#define PRIiFAST32 __PRIFAST_RANK "i" -#define PRIiFAST64 __PRI64_RANK "i" - -#define PRIiMAX __PRI64_RANK "i" -#define PRIiPTR __PRIPTR_RANK "i" - -#define PRIo8 "o" -#define PRIo16 "o" -#define PRIo32 "o" -#define PRIo64 __PRI64_RANK "o" - -#define PRIoLEAST8 "o" -#define PRIoLEAST16 "o" -#define PRIoLEAST32 "o" -#define PRIoLEAST64 __PRI64_RANK "o" - -#define PRIoFAST8 "o" -#define PRIoFAST16 __PRIFAST_RANK "o" -#define PRIoFAST32 __PRIFAST_RANK "o" -#define PRIoFAST64 __PRI64_RANK "o" - -#define PRIoMAX __PRI64_RANK "o" -#define PRIoPTR __PRIPTR_RANK "o" - -#define PRIu8 "u" -#define PRIu16 "u" -#define PRIu32 "u" -#define PRIu64 __PRI64_RANK "u" - -#define PRIuLEAST8 "u" -#define PRIuLEAST16 "u" -#define PRIuLEAST32 "u" -#define PRIuLEAST64 __PRI64_RANK "u" - -#define PRIuFAST8 "u" -#define PRIuFAST16 __PRIFAST_RANK "u" -#define PRIuFAST32 __PRIFAST_RANK "u" -#define PRIuFAST64 __PRI64_RANK "u" - -#define PRIuMAX __PRI64_RANK "u" -#define PRIuPTR __PRIPTR_RANK "u" - -#define PRIx8 "x" -#define PRIx16 "x" -#define PRIx32 "x" -#define PRIx64 __PRI64_RANK "x" - -#define PRIxLEAST8 "x" -#define PRIxLEAST16 "x" -#define PRIxLEAST32 "x" -#define PRIxLEAST64 __PRI64_RANK "x" - -#define PRIxFAST8 "x" -#define PRIxFAST16 __PRIFAST_RANK "x" -#define PRIxFAST32 __PRIFAST_RANK "x" -#define PRIxFAST64 __PRI64_RANK "x" - -#define PRIxMAX __PRI64_RANK "x" -#define PRIxPTR __PRIPTR_RANK "x" - -#define PRIX8 "X" -#define PRIX16 "X" -#define PRIX32 "X" -#define PRIX64 __PRI64_RANK "X" - -#define PRIXLEAST8 "X" -#define PRIXLEAST16 "X" -#define PRIXLEAST32 "X" -#define PRIXLEAST64 __PRI64_RANK "X" - -#define PRIXFAST8 "X" -#define PRIXFAST16 __PRIFAST_RANK "X" -#define PRIXFAST32 __PRIFAST_RANK "X" -#define PRIXFAST64 __PRI64_RANK "X" - -#define PRIXMAX __PRI64_RANK "X" -#define PRIXPTR __PRIPTR_RANK "X" - -#define SCNd8 "hhd" -#define SCNd16 "hd" -#define SCNd32 "d" -#define SCNd64 __PRI64_RANK "d" - -#define SCNdLEAST8 "hhd" -#define SCNdLEAST16 "hd" -#define SCNdLEAST32 "d" -#define SCNdLEAST64 __PRI64_RANK "d" - -#define SCNdFAST8 "hhd" -#define SCNdFAST16 __PRIFAST_RANK "d" -#define SCNdFAST32 __PRIFAST_RANK "d" -#define SCNdFAST64 __PRI64_RANK "d" - -#define SCNdMAX __PRI64_RANK "d" -#define SCNdPTR __PRIPTR_RANK "d" - -#define SCNi8 "hhi" -#define SCNi16 "hi" -#define SCNi32 "i" -#define SCNi64 __PRI64_RANK "i" - -#define SCNiLEAST8 "hhi" -#define SCNiLEAST16 "hi" -#define SCNiLEAST32 "i" -#define SCNiLEAST64 __PRI64_RANK "i" - -#define SCNiFAST8 "hhi" -#define SCNiFAST16 __PRIFAST_RANK "i" -#define SCNiFAST32 __PRIFAST_RANK "i" -#define SCNiFAST64 __PRI64_RANK "i" - -#define SCNiMAX __PRI64_RANK "i" -#define SCNiPTR __PRIPTR_RANK "i" - -#define SCNo8 "hho" -#define SCNo16 "ho" -#define SCNo32 "o" -#define SCNo64 __PRI64_RANK "o" - -#define SCNoLEAST8 "hho" -#define SCNoLEAST16 "ho" -#define SCNoLEAST32 "o" -#define SCNoLEAST64 __PRI64_RANK "o" - -#define SCNoFAST8 "hho" -#define SCNoFAST16 __PRIFAST_RANK "o" -#define SCNoFAST32 __PRIFAST_RANK "o" -#define SCNoFAST64 __PRI64_RANK "o" - -#define SCNoMAX __PRI64_RANK "o" -#define SCNoPTR __PRIPTR_RANK "o" - -#define SCNu8 "hhu" -#define SCNu16 "hu" -#define SCNu32 "u" -#define SCNu64 __PRI64_RANK "u" - -#define SCNuLEAST8 "hhu" -#define SCNuLEAST16 "hu" -#define SCNuLEAST32 "u" -#define SCNuLEAST64 __PRI64_RANK "u" - -#define SCNuFAST8 "hhu" -#define SCNuFAST16 __PRIFAST_RANK "u" -#define SCNuFAST32 __PRIFAST_RANK "u" -#define SCNuFAST64 __PRI64_RANK "u" - -#define SCNuMAX __PRI64_RANK "u" -#define SCNuPTR __PRIPTR_RANK "u" - -#define SCNx8 "hhx" -#define SCNx16 "hx" -#define SCNx32 "x" -#define SCNx64 __PRI64_RANK "x" - -#define SCNxLEAST8 "hhx" -#define SCNxLEAST16 "hx" -#define SCNxLEAST32 "x" -#define SCNxLEAST64 __PRI64_RANK "x" - -#define SCNxFAST8 "hhx" -#define SCNxFAST16 __PRIFAST_RANK "x" -#define SCNxFAST32 __PRIFAST_RANK "x" -#define SCNxFAST64 __PRI64_RANK "x" - -#define SCNxMAX __PRI64_RANK "x" -#define SCNxPTR __PRIPTR_RANK "x" - -#endif - -#endif /* _INTTYPES_H */ diff --git a/klibc/klibc/include/klibc/compiler.h b/klibc/klibc/include/klibc/compiler.h deleted file mode 100644 index 6c01474cc1..0000000000 --- a/klibc/klibc/include/klibc/compiler.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * klibc/compiler.h - * - * Various compiler features - */ - -#ifndef _KLIBC_COMPILER_H -#define _KLIBC_COMPILER_H - -/* Specific calling conventions */ -/* __cdecl is used when we want varadic and non-varadic functions to have - the same binary calling convention. */ -#ifdef __i386__ -# ifdef __GNUC__ -# define __cdecl __attribute__((cdecl,regparm(0))) -# else - /* Most other C compilers have __cdecl as a keyword */ -# endif -#else -# define __cdecl /* Meaningless on non-i386 */ -#endif - -/* How to declare a function that *must* be inlined */ -#ifdef __GNUC__ -# if __GNUC_MAJOR__ >= 3 -# define __must_inline static __inline__ __attribute__((always_inline)) -# else -# define __must_inline extern __inline__ -# endif -#else -# define __must_inline inline /* Just hope this works... */ -#endif - -/* How to declare a function that does not return */ -#ifdef __GNUC__ -# define __noreturn void __attribute__((noreturn)) -#else -# define __noreturn void -#endif - -/* How to declare a "constant" function (a function in the - mathematical sense) */ -#ifdef __GNUC__ -# define __constfunc __attribute__((const)) -#else -# define __constfunc -#endif - -/* Format attribute */ -#ifdef __GNUC__ -# define __formatfunc(t,f,a) __attribute__((format(t,f,a))) -#else -# define __formatfunc(t,f,a) -#endif - -/* likely/unlikely */ -#if defined(__GNUC__) && (__GNUC_MAJOR__ > 2 || (__GNUC_MAJOR__ == 2 && __GNUC_MINOR__ >= 95)) -# define __likely(x) __builtin_expect((x), 1) -# define __unlikely(x) __builtin_expect((x), 0) -#else -# define __likely(x) (x) -# define __unlikely(x) (x) -#endif - -/* Possibly unused function */ -#ifdef __GNUC__ -# define __unusedfunc __attribute__((unused)) -#else -# define __unusedfunc -#endif - -/* "pure" function: - - Many functions have no effects except the return value and their - return value depends only on the parameters and/or global - variables. Such a function can be subject to common subexpression - elimination and loop optimization just as an arithmetic operator - would be. These functions should be declared with the attribute - `pure'. -*/ -#ifdef __GNUC__ -# define __attribute_pure__ __attribute__((pure)) -#else -# define __attribute_pure__ -#endif - -/* "const" function: - - Many functions do not examine any values except their arguments, - and have no effects except the return value. Basically this is - just slightly more strict class than the `pure' attribute above, - since function is not allowed to read global memory. - - Note that a function that has pointer arguments and examines the - data pointed to must _not_ be declared `const'. Likewise, a - function that calls a non-`const' function usually must not be - `const'. It does not make sense for a `const' function to return - `void'. -*/ -#ifdef __GNUC__ -# define __attribute_const__ __attribute__((const)) -#else -# define __attribute_const__ -#endif - -#endif diff --git a/klibc/klibc/include/klibc/diverr.h b/klibc/klibc/include/klibc/diverr.h deleted file mode 100644 index 4d8c8d36c2..0000000000 --- a/klibc/klibc/include/klibc/diverr.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * klibc/diverr.h - */ - -#ifndef _KLIBC_DIVERR_H -#define _KLIBC_DIVERR_H - -#include - -static __inline__ void -__divide_error(void) -{ - raise(SIGFPE); -} - -#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/klibc/include/klibc/extern.h b/klibc/klibc/include/klibc/extern.h deleted file mode 100644 index f9c3467211..0000000000 --- a/klibc/klibc/include/klibc/extern.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * klibc/extern.h - */ - -#ifndef _KLIBC_EXTERN_H -#define _KLIBC_EXTERN_H - -#ifdef __cplusplus -#define __extern extern "C" -#else -#define __extern extern -#endif - -#endif /* _KLIBC_EXTERN_H */ diff --git a/klibc/klibc/include/limits.h b/klibc/klibc/include/limits.h deleted file mode 100644 index f1532e5323..0000000000 --- a/klibc/klibc/include/limits.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * limits.h - */ - -#ifndef _LIMITS_H -#define _LIMITS_H - -#define CHAR_BIT 8 -#define SHRT_BIT 16 -#define INT_BIT 32 -#define LONGLONG_BIT 64 - -#define SCHAR_MIN (-128) -#define SCHAR_MAX 127 -#define UCHAR_MAX 255 - -#ifdef __CHAR_UNSIGNED__ -# define CHAR_MIN 0 -# define CHAR_MAX UCHAR_MAX -#else -# define CHAR_MIN SCHAR_MIN -# define CHAR_MAX SCHAR_MAX -#endif - -#define SHRT_MIN (-32768) -#define SHRT_MAX 32767 -#define USHRT_MAX 65535 - -#define INT_MIN (-2147483647-1) -#define INT_MAX 2147483647 -#define UINT_MAX 4294967295U - -#define LONGLONG_MIN (-9223372036854775807LL-1) -#define LONGLONG_MAX 9223372036854775807LL -#define ULONGLONG_MAX 18446744073709551615ULL - -#include -#include - -#endif /* _LIMITS_H */ diff --git a/klibc/klibc/include/net/if.h b/klibc/klibc/include/net/if.h deleted file mode 100644 index 1aa8e7b90c..0000000000 --- a/klibc/klibc/include/net/if.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/klibc/include/net/if_arp.h b/klibc/klibc/include/net/if_arp.h deleted file mode 100644 index a25f1b4759..0000000000 --- a/klibc/klibc/include/net/if_arp.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/klibc/include/net/if_ether.h b/klibc/klibc/include/net/if_ether.h deleted file mode 100644 index 060ef22070..0000000000 --- a/klibc/klibc/include/net/if_ether.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/klibc/include/net/if_packet.h b/klibc/klibc/include/net/if_packet.h deleted file mode 100644 index b5e8e0e11f..0000000000 --- a/klibc/klibc/include/net/if_packet.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/klibc/include/netinet/in.h b/klibc/klibc/include/netinet/in.h deleted file mode 100644 index 92dc843bb1..0000000000 --- a/klibc/klibc/include/netinet/in.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * netinet/in.h - */ - -#ifndef _NETINET_IN_H -#define _NETINET_IN_H - -/* added this include by Mats Petersson */ -#include - -#include -#include -#include /* Must be included *before* */ -#include - -#ifndef htons -# define htons(x) __cpu_to_be16(x) -#endif -#ifndef ntohs -# define ntohs(x) __be16_to_cpu(x) -#endif -#ifndef htonl -# define htonl(x) __cpu_to_be32(x) -#endif -#ifndef ntohl -# define ntohl(x) __be32_to_cpu(x) -#endif - -#define IPPORT_RESERVED 1024 - -__extern int bindresvport (int sd, struct sockaddr_in *sin); - -#endif /* _NETINET_IN_H */ diff --git a/klibc/klibc/include/netinet/in6.h b/klibc/klibc/include/netinet/in6.h deleted file mode 100644 index 46584ca627..0000000000 --- a/klibc/klibc/include/netinet/in6.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * netinet/in6.h - */ - -#ifndef _NETINET_IN6_H -#define _NETINET_IN6_H - -#include - -#endif /* _NETINET_IN6_H */ diff --git a/klibc/klibc/include/netinet/ip.h b/klibc/klibc/include/netinet/ip.h deleted file mode 100644 index 8aecbe66a3..0000000000 --- a/klibc/klibc/include/netinet/ip.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * netinet/ip.h - */ - -#ifndef _NETINET_IP_H -#define _NETINET_IP_H - -#include -#include - -#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ - -#endif /* _NETINET_IP_H */ diff --git a/klibc/klibc/include/netinet/tcp.h b/klibc/klibc/include/netinet/tcp.h deleted file mode 100644 index bb5d307e98..0000000000 --- a/klibc/klibc/include/netinet/tcp.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * netinet/tcp.h - */ - -#ifndef _NETINET_TCP_H -#define _NETINET_TCP_H - -#include /* Include *before* linux/tcp.h */ -#include - -#endif /* _NETINET_TCP_H */ diff --git a/klibc/klibc/include/netinet/udp.h b/klibc/klibc/include/netinet/udp.h deleted file mode 100644 index b809b4ee6e..0000000000 --- a/klibc/klibc/include/netinet/udp.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * netinet/udp.h - */ - -#ifndef _NETINET_UDP_H -#define _NETINET_UDP_H - -/* - * We would include linux/udp.h, but it brings in too much other stuff - */ - -struct udphdr { - __u16 source; - __u16 dest; - __u16 len; - __u16 check; -}; - -#endif /* _NETINET_UDP_H */ diff --git a/klibc/klibc/include/poll.h b/klibc/klibc/include/poll.h deleted file mode 100644 index 8710d92ebd..0000000000 --- a/klibc/klibc/include/poll.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * poll.h - */ - -#ifndef _POLL_H -#define _POLL_H - -#include -#include - -/* POSIX specifies "int" for the timeout, Linux seems to use long... */ - -typedef unsigned int nfds_t; -__extern int poll(struct pollfd *, nfds_t, long); - -#endif /* _POLL_H */ diff --git a/klibc/klibc/include/sched.h b/klibc/klibc/include/sched.h deleted file mode 100644 index 5e6103965f..0000000000 --- a/klibc/klibc/include/sched.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * sched.h - */ - -#ifndef _SCHED_H -#define _SCHED_H - -#include - -/* linux/sched.h is unusable; put the declarations we need here... */ - -#define SCHED_NORMAL 0 -#define SCHED_FIFO 1 -#define SCHED_RR 2 - -struct sched_param { - int sched_priority; -}; - -__extern int sched_setschedule(pid_t, int, const struct sched_param *); -__extern int sched_yield(void); - -#endif /* _SCHED_H */ diff --git a/klibc/klibc/include/setjmp.h b/klibc/klibc/include/setjmp.h deleted file mode 100644 index b504eb6d08..0000000000 --- a/klibc/klibc/include/setjmp.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * setjmp.h - */ - -#ifndef _SETJMP_H -#define _SETJMP_H - -#include -#include -#include -#include - -#include - -__extern int setjmp(jmp_buf); -__extern __noreturn longjmp(jmp_buf, int); - -/* - Whose bright idea was it to add unrelated functionality to just about - the only function in the standard C library (setjmp) which cannot be - wrapped by an ordinary function wrapper? Anyway, the damage is done, - and therefore, this wrapper *must* be inline. However, gcc will - complain if this is an inline function for unknown reason, and - therefore sigsetjmp() needs to be a macro. -*/ - -struct __sigjmp_buf { - jmp_buf __jmpbuf; - sigset_t __sigs; -}; - -typedef struct __sigjmp_buf sigjmp_buf[1]; - -#define sigsetjmp(__env, __save) \ -({ \ - struct __sigjmp_buf *__e = (__env); \ - sigprocmask(0, NULL, &__e->__sigs); \ - setjmp(__e->__jmpbuf); \ -}) - -__extern __noreturn siglongjmp(sigjmp_buf, int); - -#endif /* _SETJMP_H */ diff --git a/klibc/klibc/include/signal.h b/klibc/klibc/include/signal.h deleted file mode 100644 index 513b4e5a04..0000000000 --- a/klibc/klibc/include/signal.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * signal.h - */ - -#ifndef _SIGNAL_H -#define _SIGNAL_H - -#include -#include /* For memset() */ -#include /* For LONG_BIT */ -#include -#include - -#include - -/* glibc seems to use sig_atomic_t as "int" pretty much on all architectures. - Do the same, but allow the architecture to override. */ -#ifdef _KLIBC_HAS_ARCH_SIG_ATOMIC_T -typedef int sig_atomic_t; -#endif - -/* Some architectures don't define these */ -#ifndef SA_RESETHAND -# define SA_RESETHAND SA_ONESHOT -#endif -#ifndef SA_NODEFER -# define SA_NODEFER SA_NOMASK -#endif -#ifndef NSIG -# define NSIG _NSIG -#endif - -__extern const char * const sys_siglist[]; - -/* This assumes sigset_t is either an unsigned long or an array of such, - and that _NSIG_BPW in the kernel is always LONG_BIT */ - -static __inline__ int sigemptyset(sigset_t *__set) -{ - memset(__set, 0, sizeof *__set); - return 0; -} -static __inline__ int sigfillset(sigset_t *__set) -{ - memset(__set, ~0, sizeof *__set); - return 0; -} -static __inline__ int sigaddset(sigset_t *__set, int __signum) -{ - unsigned long *__lset = (unsigned long *)__set; - __lset[__signum/LONG_BIT] |= 1UL << (__signum%LONG_BIT); - return 0; -} -static __inline__ int sigdelset(sigset_t *__set, int __signum) -{ - unsigned long *__lset = (unsigned long *)__set; - __lset[__signum/LONG_BIT] &= ~(1UL << (__signum%LONG_BIT)); - return 0; -} -static __inline__ int sigismember(sigset_t *__set, int __signum) -{ - unsigned long *__lset = (unsigned long *)__set; - return (int)((__lset[__signum/LONG_BIT] >> (__signum%LONG_BIT)) & 1); -} - -__extern __sighandler_t __signal(int, __sighandler_t, int); -__extern __sighandler_t sysv_signal(int, __sighandler_t); -__extern __sighandler_t bsd_signal(int, __sighandler_t); -__extern int sigaction(int, const struct sigaction *, struct sigaction *); -__extern int sigprocmask(int, const sigset_t *, sigset_t *); -__extern int sigpending(sigset_t *); -__extern int sigsuspend(const sigset_t *); -__extern int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); -__extern int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); -__extern int rt_sigpending(sigset_t *, size_t); -__extern int rt_sigsuspend(const sigset_t *, size_t); -__extern int raise(int); -__extern int kill(pid_t, int); - -#endif /* _SIGNAL_H */ diff --git a/klibc/klibc/include/stdarg.h b/klibc/klibc/include/stdarg.h deleted file mode 100644 index cc324b825d..0000000000 --- a/klibc/klibc/include/stdarg.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * stdarg.h - * - * This is just a wrapper for the gcc one, but defines va_copy() - * even if gcc doesn't. - */ - -/* Note: the _STDARG_H macro belongs to the gcc header... */ -#include_next - -/* Older gcc considers this an extension, so it's double underbar only */ -#ifndef va_copy -#define va_copy(d,s) __va_copy(d,s) -#endif diff --git a/klibc/klibc/include/stddef.h b/klibc/klibc/include/stddef.h deleted file mode 100644 index 125d2352ec..0000000000 --- a/klibc/klibc/include/stddef.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * stddef.h - */ - -#ifndef _STDDEF_H -#define _STDDEF_H - -#ifndef __KLIBC__ -# define __KLIBC__ 1 -#endif - -#include - -#undef NULL -#ifdef __cplusplus -# define NULL 0 -#else -# define NULL ((void *)0) -#endif - -#undef offsetof -#define offsetof(t,m) ((size_t)&((t *)0)->m) - -#endif /* _STDDEF_H */ diff --git a/klibc/klibc/include/stdint.h b/klibc/klibc/include/stdint.h deleted file mode 100644 index 47fec18594..0000000000 --- a/klibc/klibc/include/stdint.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * stdint.h - */ - -#ifndef _STDINT_H -#define _STDINT_H - -#include - -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; - -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -typedef int8_t int_fast8_t; -typedef int64_t int_fast64_t; - -typedef uint8_t uint_fast8_t; -typedef uint64_t uint_fast64_t; - -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) - -#define INT8_MIN (-128) -#define INT16_MIN (-32768) -#define INT32_MIN (-2147483647-1) -#define INT64_MIN (__INT64_C(-9223372036854775807)-1) - -#define INT8_MAX (127) -#define INT16_MAX (32767) -#define INT32_MAX (2147483647) -#define INT64_MAX (__INT64_C(9223372036854775807)) - -#define UINT8_MAX (255U) -#define UINT16_MAX (65535U) -#define UINT32_MAX (4294967295U) -#define UINT64_MAX (__UINT64_C(18446744073709551615)) - -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST64_MIN INT64_MIN - -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MAX INT64_MAX - -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST64_MIN INT64_MIN - -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST64_MAX INT64_MAX - -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST64_MAX UINT64_MAX - -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -#include - -#endif - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) - -#define INT8_C(c) c -#define INT16_C(c) c -#define INT32_C(c) c -#define INT64_C(c) __INT64_C(c) - -#define UINT8_C(c) c ## U -#define UINT16_C(c) c ## U -#define UINT32_C(c) c ## U -#define UINT64_C(c) __UINT64_C(c) - -#define INT_LEAST8_C(c) INT8_C(c) -#define INT_LEAST16_C(c) INT16_C(c) -#define INT_LEAST32_C(c) INT32_C(c) -#define INT_LEAST64_C(c) INT64_C(c) - -#define UINT_LEAST8_C(c) UINT8_C(c) -#define UINT_LEAST16_C(c) UINT16_C(c) -#define UINT_LEAST32_C(c) UINT32_C(c) -#define UINT_LEAST64_C(c) UINT64_C(c) - -#define INT_FAST8_C(c) INT8_C(c) -#define INT_FAST64_C(c) INT64_C(c) - -#define UINT_FAST8_C(c) UINT8_C(c) -#define UINT_FAST64_C(c) UINT64_C(c) - -#define INTMAX_C(c) INT64_C(c) -#define UINTMAX_C(c) UINT64_C(c) - -#include - -#endif - -/* Keep the kernel from trying to define these types... */ -#define __BIT_TYPES_DEFINED__ - -#endif /* _STDINT_H */ diff --git a/klibc/klibc/include/stdio.h b/klibc/klibc/include/stdio.h deleted file mode 100644 index fba1e30746..0000000000 --- a/klibc/klibc/include/stdio.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * stdio.h - */ - -#ifndef _STDIO_H -#define _STDIO_H - -#include -#include -#include -#include - -/* This structure doesn't really exist, but it gives us something - to define FILE * with */ -struct _IO_file; -typedef struct _IO_file FILE; - -#ifndef EOF -# define EOF (-1) -#endif - -#ifndef BUFSIZ -# define BUFSIZ 4096 -#endif - -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -/* - * Convert between a FILE * and a file descriptor. We don't actually - * have any in-memory data, so we just abuse the pointer itself to - * hold the data. Note, however, that for file descriptors, -1 is - * error and 0 is a valid value; for FILE *, NULL (0) is error and - * non-NULL are valid. - */ -static __inline__ int fileno(FILE *__f) -{ - /* This should really be intptr_t, but size_t should be the same size */ - return (int)(size_t)__f - 1; -} - -/* This is a macro so it can be used as initializer */ -#define __create_file(__fd) ((FILE *)(size_t)((__fd) + 1)) - -#define stdin __create_file(0) -#define stdout __create_file(1) -#define stderr __create_file(2) - -__extern FILE *fopen(const char *, const char *); - -static __inline__ FILE *fdopen(int __fd, const char *__m) -{ - (void)__m; return __create_file(__fd); -} -static __inline__ int fclose(FILE *__f) -{ - extern int close(int); - return close(fileno(__f)); -} -static __inline__ int fseek(FILE *__f, off_t __o, int __w) -{ - extern off_t lseek(int, off_t, int); - return (lseek(fileno(__f), __o, __w) == (off_t)-1) ? -1 : 0; -} -static __inline__ off_t ftell(FILE *__f) -{ - extern off_t lseek(int, off_t, int); - return lseek(fileno(__f), 0, SEEK_CUR); -} - -__extern int fputs(const char *, FILE *); -__extern int puts(const char *); -__extern int fputc(int, FILE *); -#define putc(c,f) fputc((c),(f)) -#define putchar(c) fputc((c),stdout) - -__extern int fgetc(FILE *); -__extern char * fgets(char *, int, FILE *); -#define getc(f) fgetc(f) - -__extern size_t _fread(void *, size_t, FILE *); -__extern size_t _fwrite(const void *, size_t, FILE *); - -#ifndef __NO_FREAD_FWRITE_INLINES -extern __inline__ size_t -fread(void *__p, size_t __s, size_t __n, FILE *__f) -{ - return _fread(__p, __s*__n, __f)/__s; -} - -extern __inline__ size_t -fwrite(void *__p, size_t __s, size_t __n, FILE *__f) -{ - return _fwrite(__p, __s*__n, __f)/__s; -} -#endif - -__extern int printf(const char *, ...); -__extern int vprintf(const char *, va_list); -__extern int fprintf(FILE *, const char *, ...); -__extern int vfprintf(FILE *, const char *, va_list); -__extern int sprintf(char *, const char *, ...); -__extern int vsprintf(char *, const char *, va_list); -__extern int snprintf(char *, size_t n, const char *, ...); -__extern int vsnprintf(char *, size_t n, const char *, va_list); - -__extern int sscanf(const char *, const char *, ...); -__extern int vsscanf(const char *, const char *, va_list); - -__extern void perror(const char *); - -__extern int rename(const char *, const char *); - -#endif /* _STDIO_H */ diff --git a/klibc/klibc/include/stdlib.h b/klibc/klibc/include/stdlib.h deleted file mode 100644 index af97eea636..0000000000 --- a/klibc/klibc/include/stdlib.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * stdlib.h - */ - -#ifndef _STDLIB_H -#define _STDLIB_H - -#include -#include -#include - -#define EXIT_FAILURE 1 -#define EXIT_SUCCESS 0 - -static __inline__ __noreturn _Exit(int __n) { - __extern __noreturn _exit(int); - _exit(__n); - for(;;); /* Some gcc versions are stupid */ -} -__extern __noreturn abort(void); -static __inline__ int abs(int __n) { - return (__n < 0) ? -__n : __n; -} -__extern int atexit(void (*)(void)); -__extern int on_exit(void (*)(int, void *), void *); -__extern int atoi(const char *); -__extern long atol(const char *); -__extern long long atoll(const char *); -__extern __noreturn exit(int); -__extern void free(void *); -static __inline__ long labs(long __n) { - return (__n < 0L) ? -__n : __n; -} - -static __inline__ long long llabs(long long __n) { - return (__n < 0LL) ? -__n : __n; -} - -#if defined(__GNUC__) && __GNUC_MAJOR__ >= 3 -# define __attribute_malloc __attribute__((malloc)) -#else -# define __attribute_malloc -#endif - -__extern __attribute_malloc void *malloc(size_t); -__extern __attribute_malloc void *calloc(size_t, size_t); -__extern void *realloc(void *, size_t); -__extern long strtol(const char *, char **, int); -__extern long long strtoll(const char *, char **, int); -__extern unsigned long strtoul(const char *, char **, int); -__extern unsigned long long strtoull(const char *, char **, int); - -__extern char *getenv(const char *); -__extern int putenv(const char *); -__extern int setenv(const char *, const char *, int); -__extern int unsetenv(const char *); - -__extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); - - -__extern long jrand48(unsigned short *); -__extern long mrand48(void); -__extern long nrand48(unsigned short *); -__extern long lrand48(void); -__extern unsigned short *seed48(const unsigned short *); -__extern void srand48(long); - -#define RAND_MAX 0x7fffffff -static __inline__ int rand(void) { - return (int)lrand48(); -} -static __inline__ void srand(unsigned int __s) { - srand48(__s); -} -static __inline__ long random(void) -{ - return lrand48(); -} -static __inline__ void srandom(unsigned int __s) -{ - srand48(__s); -} - -/* Basic PTY functions. These only work if devpts is mounted! */ - -__extern int unlockpt(int); -__extern char *ptsname(int); -__extern int getpt(void); - -static __inline__ int grantpt(int __fd) -{ - (void)__fd; - return 0; /* devpts does this all for us! */ -} - -#endif /* _STDLIB_H */ diff --git a/klibc/klibc/include/string.h b/klibc/klibc/include/string.h deleted file mode 100644 index 1debb55af0..0000000000 --- a/klibc/klibc/include/string.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * string.h - */ - -#ifndef _STRING_H -#define _STRING_H - -#include -#include - -__extern void *memccpy(void *, const void *, int, size_t); -__extern void *memchr(const void *, int, size_t); -__extern int memcmp(const void *, const void *, size_t); -__extern void *memcpy(void *, const void *, size_t); -__extern void *memmove(void *, const void *, size_t); -__extern void *memset(void *, int, size_t); -__extern void *memmem(const void *, size_t, const void *, size_t); -__extern void memswap(void *, void *, size_t); -__extern int strcasecmp(const char *, const char *); -__extern int strncasecmp(const char *, const char *, size_t); -__extern char *strcat(char *, const char *); -__extern char *strchr(const char *, int); -__extern int strcmp(const char *, const char *); -__extern char *strcpy(char *, const char *); -__extern size_t strcspn(const char *, const char *); -__extern char *strdup(const char *); -__extern char *strndup(const char *, size_t); -__extern char *strerror(int); -__extern size_t strlen(const char *); -__extern char *strncat(char *, const char *, size_t); -__extern int strncmp(const char *, const char *, size_t); -__extern char *strncpy(char *, const char *, size_t); -__extern char *strpbrk(const char *, const char *); -__extern char *strrchr(const char *, int); -__extern char *strsep(char **, const char *); -__extern size_t strspn(const char *, const char *); -__extern char *strstr(const char *, const char *); -__extern char *strtok(char *, const char *); - -#endif /* _STRING_H */ diff --git a/klibc/klibc/include/sys/dirent.h b/klibc/klibc/include/sys/dirent.h deleted file mode 100644 index 0700f4b561..0000000000 --- a/klibc/klibc/include/sys/dirent.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * sys/dirent.h - */ - -#ifndef _SYS_DIRENT_H -#define _SYS_DIRENT_H - -#include -#include - -__extern int getdents(unsigned int, struct dirent *, unsigned int); - -#endif /* _SYS_DIRENT_H */ diff --git a/klibc/klibc/include/sys/elf32.h b/klibc/klibc/include/sys/elf32.h deleted file mode 100644 index 652de5bc5f..0000000000 --- a/klibc/klibc/include/sys/elf32.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * sys/elf32.h - */ - -#ifndef _SYS_ELF32_H -#define _SYS_ELF32_H - -#include - -/* ELF standard typedefs (yet more proof that was way overdue) */ -typedef uint16_t Elf32_Half; -typedef int16_t Elf32_SHalf; -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; - -typedef uint32_t Elf32_Off; -typedef uint32_t Elf32_Addr; -typedef uint16_t Elf32_Section; - -/* Dynamic header */ - -typedef struct elf32_dyn { - Elf32_Sword d_tag; - union{ - Elf32_Sword d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - -/* Relocations */ - -#define ELF32_R_SYM(x) ((x) >> 8) -#define ELF32_R_TYPE(x) ((x) & 0xff) - -typedef struct elf32_rel { - Elf32_Addr r_offset; - Elf32_Word r_info; -} Elf32_Rel; - -typedef struct elf32_rela { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; -} Elf32_Rela; - -/* Symbol */ - -typedef struct elf32_sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; -} Elf32_Sym; - -/* Main file header */ - -typedef struct elf32_hdr { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -} Elf32_Ehdr; - -/* Program header */ - -typedef struct elf32_phdr { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - - -/* Section header */ - -typedef struct elf32_shdr { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -} Elf32_Shdr; - -/* Note header */ -typedef struct elf32_note { - Elf32_Word n_namesz; /* Name size */ - Elf32_Word n_descsz; /* Content size */ - Elf32_Word n_type; /* Content type */ -} Elf32_Nhdr; - -#endif /* _SYS_ELF32_H */ - diff --git a/klibc/klibc/include/sys/elf64.h b/klibc/klibc/include/sys/elf64.h deleted file mode 100644 index 750ddac4d9..0000000000 --- a/klibc/klibc/include/sys/elf64.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * sys/elf64.h - */ - -#ifndef _SYS_ELF64_H -#define _SYS_ELF64_H - -#include - -/* ELF standard typedefs (yet more proof that was way overdue) */ -typedef uint16_t Elf64_Half; -typedef int16_t Elf64_SHalf; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; - -typedef uint64_t Elf64_Off; -typedef uint64_t Elf64_Addr; -typedef uint16_t Elf64_Section; - -/* Dynamic header */ - -typedef struct elf64_dyn { - Elf64_Sxword d_tag; - union{ - Elf64_Xword d_val; - Elf64_Addr d_ptr; - } d_un; -} Elf64_Dyn; - -/* Relocations */ - -#define ELF64_R_SYM(x) ((x) >> 32) -#define ELF64_R_TYPE(x) ((x) & 0xffffffff) - -typedef struct elf64_rel { - Elf64_Addr r_offset; - Elf64_Xword r_info; -} Elf64_Rel; - -typedef struct elf64_rela { - Elf64_Addr r_offset; - Elf64_Xword r_info; - Elf64_Sxword r_addend; -} Elf64_Rela; - -/* Symbol */ - -typedef struct elf64_sym { - Elf64_Word st_name; - unsigned char st_info; - unsigned char st_other; - Elf64_Half st_shndx; - Elf64_Addr st_value; - Elf64_Xword st_size; -} Elf64_Sym; - -/* Main file header */ - -typedef struct elf64_hdr { - unsigned char e_ident[EI_NIDENT]; - Elf64_Half e_type; - Elf64_Half e_machine; - Elf64_Word e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - Elf64_Word e_flags; - Elf64_Half e_ehsize; - Elf64_Half e_phentsize; - Elf64_Half e_phnum; - Elf64_Half e_shentsize; - Elf64_Half e_shnum; - Elf64_Half e_shstrndx; -} Elf64_Ehdr; - -/* Program header */ - -typedef struct elf64_phdr { - Elf64_Word p_type; - Elf64_Word p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; - Elf64_Xword p_filesz; - Elf64_Xword p_memsz; - Elf64_Xword p_align; -} Elf64_Phdr; - - -/* Section header */ - -typedef struct elf64_shdr { - Elf64_Word sh_name; - Elf64_Word sh_type; - Elf64_Xword sh_flags; - Elf64_Addr sh_addr; - Elf64_Off sh_offset; - Elf64_Xword sh_size; - Elf64_Word sh_link; - Elf64_Word sh_info; - Elf64_Xword sh_addralign; - Elf64_Xword sh_entsize; -} Elf64_Shdr; - -/* Note header */ -typedef struct elf64_note { - Elf64_Word n_namesz; /* Name size */ - Elf64_Word n_descsz; /* Content size */ - Elf64_Word n_type; /* Content type */ -} Elf64_Nhdr; - -#endif /* _SYS_ELF64_H */ - diff --git a/klibc/klibc/include/sys/elfcommon.h b/klibc/klibc/include/sys/elfcommon.h deleted file mode 100644 index f984f6a56b..0000000000 --- a/klibc/klibc/include/sys/elfcommon.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * sys/elfcommon.h - */ - -#ifndef _SYS_ELFCOMMON_H -#define _SYS_ELFCOMMON_H - -/* Segment types */ -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_LOOS 0x60000000 -#define PT_HIOS 0x6fffffff -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff -#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */ - -/* ELF file types */ -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 -#define ET_LOPROC 0xff00 -#define ET_HIPROC 0xffff - -/* ELF machine types */ -#define EM_NONE 0 -#define EM_M32 1 -#define EM_SPARC 2 -#define EM_386 3 -#define EM_68K 4 -#define EM_88K 5 -#define EM_486 6 /* Not used in Linux at least */ -#define EM_860 7 -#define EM_MIPS 8 /* R3k, bigendian(?) */ -#define EM_MIPS_RS4_BE 10 /* R4k BE */ -#define EM_PARISC 15 -#define EM_SPARC32PLUS 18 -#define EM_PPC 20 -#define EM_PPC64 21 -#define EM_S390 22 -#define EM_SH 42 -#define EM_SPARCV9 43 /* v9 = SPARC64 */ -#define EM_H8_300H 47 -#define EM_H8S 48 -#define EM_IA_64 50 /* Itanic */ -#define EM_X86_64 62 -#define EM_CRIS 76 -#define EM_V850 87 -#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */ -#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */ -#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ - -/* Dynamic type values */ -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff - -/* Auxilliary table entries */ -#define AT_NULL 0 /* end of vector */ -#define AT_IGNORE 1 /* entry should be ignored */ -#define AT_EXECFD 2 /* file descriptor of program */ -#define AT_PHDR 3 /* program headers for program */ -#define AT_PHENT 4 /* size of program header entry */ -#define AT_PHNUM 5 /* number of program headers */ -#define AT_PAGESZ 6 /* system page size */ -#define AT_BASE 7 /* base address of interpreter */ -#define AT_FLAGS 8 /* flags */ -#define AT_ENTRY 9 /* entry point of program */ -#define AT_NOTELF 10 /* program is not ELF */ -#define AT_UID 11 /* real uid */ -#define AT_EUID 12 /* effective uid */ -#define AT_GID 13 /* real gid */ -#define AT_EGID 14 /* effective gid */ -#define AT_PLATFORM 15 /* string identifying CPU for optimizations */ -#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ -#define AT_CLKTCK 17 /* frequency at which times() increments */ -/* 18..22 = ? */ -#define AT_SECURE 23 /* secure mode boolean */ - -/* Program header permission flags */ -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 - -/* Section header types */ -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_NUM 12 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - -/* Section header flags */ -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_MASKPROC 0xf0000000 - -/* Special section numbers */ -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - -/* Lenght of magic at the start of a file */ -#define EI_NIDENT 16 - -/* Magic number constants... */ -#define EI_MAG0 0 /* e_ident[] indexes */ -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_OSABI 7 -#define EI_PAD 8 - -#define ELFMAG0 0x7f /* EI_MAG */ -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define ELFCLASSNONE 0 /* EI_CLASS */ -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFCLASSNUM 3 - -#define ELFDATANONE 0 /* e_ident[EI_DATA] */ -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 - -#define EV_NONE 0 /* e_version, EI_VERSION */ -#define EV_CURRENT 1 -#define EV_NUM 2 - -#define ELFOSABI_NONE 0 -#define ELFOSABI_LINUX 3 - -#endif /* _SYS_ELFCOMMON_H */ - diff --git a/klibc/klibc/include/sys/fsuid.h b/klibc/klibc/include/sys/fsuid.h deleted file mode 100644 index 823486b776..0000000000 --- a/klibc/klibc/include/sys/fsuid.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/fsuid.h - */ - -#ifndef _SYS_FSUID_H -#define _SYS_FSUID_H - -#include -#include - -__extern int setfsuid(uid_t); -__extern int setfsgid(gid_t); - -#endif /* _SYS_FSUID_H */ diff --git a/klibc/klibc/include/sys/ioctl.h b/klibc/klibc/include/sys/ioctl.h deleted file mode 100644 index b0cee4c02c..0000000000 --- a/klibc/klibc/include/sys/ioctl.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/ioctl.h - */ - -#ifndef _SYS_IOCTL_H -#define _SYS_IOCTL_H - -#include -#include -#include - -__extern int ioctl(int, int, void *); - -#endif /* _SYS_IOCTL_H */ diff --git a/klibc/klibc/include/sys/klog.h b/klibc/klibc/include/sys/klog.h deleted file mode 100644 index 0fc5f5d945..0000000000 --- a/klibc/klibc/include/sys/klog.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * sys/klog.h - */ - -#ifndef _SYS_KLOG_H -#define _SYS_KLOG_H - -#include - -#define KLOG_CLOSE 0 -#define KLOG_OPEN 1 -#define KLOG_READ 2 -#define KLOG_READ_ALL 3 -#define KLOG_READ_CLEAR 4 -#define KLOG_CLEAR 5 -#define KLOG_DISABLE 6 -#define KLOG_ENABLE 7 -#define KLOG_SETLEVEL 8 -#define KLOG_UNREADSIZE 9 -#define KLOG_WRITE 10 - -__extern int klogctl(int, char *, int); - -#endif /* _SYS_KLOG_H */ diff --git a/klibc/klibc/include/sys/mman.h b/klibc/klibc/include/sys/mman.h deleted file mode 100644 index 3d8a2f63c2..0000000000 --- a/klibc/klibc/include/sys/mman.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * sys/mman.h - */ - -#ifndef _SYS_MMAN_H -#define _SYS_MMAN_H - -#include -#include -#include -#include /* For PAGE_SIZE */ - -#define MAP_FAILED ((void *)-1) - -__extern void *mmap(void *, size_t, int, int, int, off_t); -__extern int munmap(void *, size_t); -__extern void *mremap(void *, size_t, size_t, unsigned long); -__extern int msync(const void *, size_t, int); -__extern int mprotect(const void *, size_t, int); - -#endif /* _SYS_MMAN_H */ diff --git a/klibc/klibc/include/sys/mount.h b/klibc/klibc/include/sys/mount.h deleted file mode 100644 index 313c90ec0e..0000000000 --- a/klibc/klibc/include/sys/mount.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * sys/mount.h - */ - -#ifndef _SYS_MOUNT_H -#define _SYS_MOUNT_H - -#include - -/* - * These are the fs-independent mount-flags: up to 32 flags are supported - */ -#define MS_RDONLY 1 /* Mount read-only */ -#define MS_NOSUID 2 /* Ignore suid and sgid bits */ -#define MS_NODEV 4 /* Disallow access to device special files */ -#define MS_NOEXEC 8 /* Disallow program execution */ -#define MS_SYNCHRONOUS 16 /* Writes are synced at once */ -#define MS_REMOUNT 32 /* Alter flags of a mounted FS */ -#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ -#define MS_DIRSYNC 128 /* Directory modifications are synchronous */ -#define MS_NOATIME 1024 /* Do not update access times. */ -#define MS_NODIRATIME 2048 /* Do not update directory access times */ -#define MS_BIND 4096 -#define MS_MOVE 8192 -#define MS_REC 16384 -#define MS_VERBOSE 32768 -#define MS_NOUSER (1<<31) - -/* - * Superblock flags that can be altered by MS_REMOUNT - */ -#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|MS_NODIRATIME) - -/* - * Old magic mount flag and mask - */ -#define MS_MGC_VAL 0xC0ED0000 -#define MS_MGC_MSK 0xffff0000 - -/* - * umount2() flags - */ -#define MNT_FORCE 1 - -/* - * Prototypes - */ -__extern int mount(const char *, const char *, - const char *, unsigned long, - const void *); -__extern int umount(const char *); -__extern int umount2(const char *, int); -__extern int pivot_root(const char *, const char *); - -#endif /* _SYS_MOUNT_H */ diff --git a/klibc/klibc/include/sys/param.h b/klibc/klibc/include/sys/param.h deleted file mode 100644 index 63a0661f43..0000000000 --- a/klibc/klibc/include/sys/param.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * sys/param.h - */ - -#ifndef _SYS_PARAM_H -#define _SYS_PARAM_H - -#include -#include - -#endif /* _SYS_PARAM_H */ diff --git a/klibc/klibc/include/sys/reboot.h b/klibc/klibc/include/sys/reboot.h deleted file mode 100644 index eaf56610d7..0000000000 --- a/klibc/klibc/include/sys/reboot.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * sys/reboot.h - */ - -#ifndef _SYS_REBOOT_H -#define _SYS_REBOOT_H - -#include -#include - -/* glibc names these constants differently; allow both versions */ - -#define RB_AUTOBOOT LINUX_REBOOT_CMD_RESTART -#define RB_HALT_SYSTEM LINUX_REBOOT_CMD_HALT -#define RB_ENABLE_CAD LINUX_REBOOT_CMD_CAD_ON -#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF -#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF - -/* glibc-ish one-argument version */ -__extern int reboot(int); - -/* Native four-argument system call */ -__extern int __reboot(int, int, int, void *); - -#endif /* _SYS_REBOOT_H */ diff --git a/klibc/klibc/include/sys/resource.h b/klibc/klibc/include/sys/resource.h deleted file mode 100644 index ef14bde9f6..0000000000 --- a/klibc/klibc/include/sys/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * sys/resource.h - */ - -#ifndef _SYS_RESOURCE_H -#define _SYS_RESOURCE_H - -#include -#include /* MUST be included before linux/resource.h */ -#include - -__extern int getpriority(int, int); -__extern int setpriority(int, int, int); - -#endif /* _SYS_RESOURCE_H */ diff --git a/klibc/klibc/include/sys/select.h b/klibc/klibc/include/sys/select.h deleted file mode 100644 index 7caf8c931b..0000000000 --- a/klibc/klibc/include/sys/select.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * sys/select.h - */ - -#ifndef _SYS_SELECT_H -#define _SYS_SELECT_H - -#include -#include - -__extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); - -#endif /* _SYS_SELECT_H */ diff --git a/klibc/klibc/include/sys/socket.h b/klibc/klibc/include/sys/socket.h deleted file mode 100644 index cbc2b89591..0000000000 --- a/klibc/klibc/include/sys/socket.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * sys/socket.h - */ - -#ifndef _SYS_SOCKET_H -#define _SYS_SOCKET_H - -#include -#include -#include - -/* For some reason these may be protected by __KERNEL__ in asm/socket.h */ -#ifndef SOCK_STREAM -# define SOCK_STREAM 1 -# define SOCK_DGRAM 2 -# define SOCK_RAW 3 -# define SOCK_RDM 4 -# define SOCK_SEQPACKET 5 -# define SOCK_PACKET 10 -#endif - -#ifdef __i386__ -# define __socketcall __extern __cdecl -#else -# define __socketcall __extern -#endif - -typedef int socklen_t; - -__socketcall int socket(int, int, int); -__socketcall int bind(int, struct sockaddr *, int); -__socketcall int connect(int, struct sockaddr *, socklen_t); -__socketcall int listen(int, int); -__socketcall int accept(int, struct sockaddr *, socklen_t *); -__socketcall int getsockname(int, struct sockaddr *, socklen_t *); -__socketcall int getpeername(int, struct sockaddr *, socklen_t *); -__socketcall int socketpair(int, int, int, int *); -__extern int send(int, const void *, size_t, unsigned int); -__socketcall int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); -__extern int recv(int, void *, size_t, unsigned int); -__socketcall int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *); -__socketcall int shutdown(int, int); -__socketcall int setsockopt(int, int, int, const void *, socklen_t); -__socketcall int getsockopt(int, int, int, void *, socklen_t *); -__socketcall int sendmsg(int, const struct msghdr *, unsigned int); -__socketcall int recvmsg(int, struct msghdr *, unsigned int); - -#undef __socketcall - -#endif /* _SYS_SOCKET_H */ diff --git a/klibc/klibc/include/sys/socketcalls.h b/klibc/klibc/include/sys/socketcalls.h deleted file mode 100644 index dac9f9aab6..0000000000 --- a/klibc/klibc/include/sys/socketcalls.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * sys/socketcalls.h - */ - -#ifndef _SYS_SOCKETCALLS_H -#define _SYS_SOCKETCALLS_H - -/* socketcalls by number, since isn't usable for assembly */ - -#define SYS_SOCKET 1 /* sys_socket(2) */ -#define SYS_BIND 2 /* sys_bind(2) */ -#define SYS_CONNECT 3 /* sys_connect(2) */ -#define SYS_LISTEN 4 /* sys_listen(2) */ -#define SYS_ACCEPT 5 /* sys_accept(2) */ -#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ -#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ -#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ -#define SYS_SEND 9 /* sys_send(2) */ -#define SYS_RECV 10 /* sys_recv(2) */ -#define SYS_SENDTO 11 /* sys_sendto(2) */ -#define SYS_RECVFROM 12 /* sys_recvfrom(2) */ -#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ -#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ -#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ -#define SYS_SENDMSG 16 /* sys_sendmsg(2) */ -#define SYS_RECVMSG 17 /* sys_recvmsg(2) */ - -#endif /* _SYS_SOCKETCALLS_H */ diff --git a/klibc/klibc/include/sys/stat.h b/klibc/klibc/include/sys/stat.h deleted file mode 100644 index f7bb5aacc5..0000000000 --- a/klibc/klibc/include/sys/stat.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * sys/stat.h - */ - -#ifndef _SYS_STAT_H -#define _SYS_STAT_H - -#include -#include -#include -#include - -__extern int stat(const char *, struct stat *); -__extern int fstat(int, struct stat *); -__extern int lstat(const char *, struct stat *); -__extern mode_t umask(mode_t); -__extern int mknod(const char *, mode_t, dev_t); -static __inline__ int mkfifo(const char *__p, mode_t __m) -{ - return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0); -} - -#endif /* _SYS_STAT_H */ diff --git a/klibc/klibc/include/sys/syscall.h b/klibc/klibc/include/sys/syscall.h deleted file mode 100644 index 907c7f9b9a..0000000000 --- a/klibc/klibc/include/sys/syscall.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * sys/syscall.h - * - * Generic system call interface macros - */ -#ifndef _SYS_SYSCALL_H -#define _SYS_SYSCALL_H - -#include -#include - -/* Many architectures have incomplete or defective syscall macros */ -#include - -#endif /* _SYS_SYSCALL_H */ diff --git a/klibc/klibc/include/sys/sysinfo.h b/klibc/klibc/include/sys/sysinfo.h deleted file mode 100644 index 4051c6897a..0000000000 --- a/klibc/klibc/include/sys/sysinfo.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * sys/sysinfo.h - */ - -#ifndef _SYS_SYSINFO_H -#define _SYS_SYSINFO_H - -#include - -extern int sysinfo (struct sysinfo *info); - -#endif /* _SYS_SYSINFO_H */ diff --git a/klibc/klibc/include/sys/sysmacros.h b/klibc/klibc/include/sys/sysmacros.h deleted file mode 100644 index 7f1e0822b3..0000000000 --- a/klibc/klibc/include/sys/sysmacros.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * sys/sysmacros.h - * - * Constructs to create and pick apart dev_t. This applies to the Linux 2.6 - * 32-bit dev_t format. - */ - -#ifndef _SYS_SYSMACROS_H -#define _SYS_SYSMACROS_H - -#ifndef _SYS_TYPES_H -# include -#endif - -static __inline__ int major(dev_t __d) -{ - return (__d >> 8) & 0xfff; -} - -static __inline__ int minor(dev_t __d) -{ - return (__d & 0xff) | ((__d >> 12) & 0xfff00); -} - -static __inline__ dev_t makedev(int __ma, int __mi) -{ - return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12); -} - -#endif /* _SYS_SYSMACROS_H */ - diff --git a/klibc/klibc/include/sys/time.h b/klibc/klibc/include/sys/time.h deleted file mode 100644 index b503d21076..0000000000 --- a/klibc/klibc/include/sys/time.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * sys/time.h - */ - -#ifndef _SYS_TIME_H -#define _SYS_TIME_H - -#include -#include -#include - -__extern int gettimeofday(struct timeval *, struct timezone *); -__extern int settimeofday(const struct timeval *, const struct timezone *); -__extern int getitimer(int, struct itimerval *); -__extern int setitimer(int, const struct itimerval *, struct itimerval *); - -#endif /* _SYS_TIME_H */ diff --git a/klibc/klibc/include/sys/types.h b/klibc/klibc/include/sys/types.h deleted file mode 100644 index 0aaeeb1612..0000000000 --- a/klibc/klibc/include/sys/types.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * sys/types.h - */ - -#ifndef _SYS_TYPES_H -#define _SYS_TYPES_H - -#include -#include - -#define _SSIZE_T -typedef ptrdiff_t ssize_t; - -#include -#include - -/* Keeps linux/types.h from getting included elsewhere */ -#define _LINUX_TYPES_H - -typedef __kernel_fd_set fd_set; -typedef uint32_t dev_t; -typedef __kernel_ino_t ino_t; -typedef __kernel_mode_t mode_t; -typedef __kernel_nlink_t nlink_t; -typedef __kernel_off_t off_t; /* Should become __kernel_loff_t... */ -typedef __kernel_pid_t pid_t; -typedef __kernel_daddr_t daddr_t; -typedef __kernel_key_t key_t; -typedef __kernel_suseconds_t suseconds_t; -typedef __kernel_timer_t timer_t; - -typedef __kernel_uid32_t uid_t; -typedef __kernel_gid32_t gid_t; - -typedef __kernel_loff_t loff_t; - -/* - * The following typedefs are also protected by individual ifdefs for - * historical reasons: - */ -#ifndef _SIZE_T -#define _SIZE_T -typedef __kernel_size_t size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __kernel_ssize_t ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef __kernel_ptrdiff_t ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef __kernel_time_t time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef __kernel_clock_t clock_t; -#endif - -#ifndef _CADDR_T -#define _CADDR_T -typedef __kernel_caddr_t caddr_t; -#endif - -/* bsd */ -typedef unsigned char u_char; -typedef unsigned short u_short; -typedef unsigned int u_int; -typedef unsigned long u_long; - -/* sysv */ -typedef unsigned char unchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - -/* Linux-specific? */ -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; -typedef uint64_t u_int64_t; - -/* - * transition to 64-bit sector_t, possibly making it an option... - */ -#undef BLK_64BIT_SECTOR - -#ifdef BLK_64BIT_SECTOR -typedef u64 sector_t; -#else -typedef unsigned long sector_t; -#endif - -/* - * The type of an index into the pagecache. Use a #define so asm/types.h - * can override it. - */ -#ifndef pgoff_t -#define pgoff_t unsigned long -#endif - -/* - * Below are truly Linux-specific types that should never collide with - * any application/library that wants linux/types.h. - */ - -struct ustat { - __kernel_daddr_t f_tfree; - __kernel_ino_t f_tinode; - char f_fname[6]; - char f_fpack[6]; -}; - -/* - * Some apps want this in - */ -#include - -#endif diff --git a/klibc/klibc/include/sys/uio.h b/klibc/klibc/include/sys/uio.h deleted file mode 100644 index fc2525d11a..0000000000 --- a/klibc/klibc/include/sys/uio.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * sys/uio.h - */ - -#ifndef _SYS_UIO_H -#define _SYS_UIO_H - -#include -#include -#include - -__extern int readv(int, const struct iovec *, int); -__extern int writev(int, const struct iovec *, int); - -#endif /* _SYS_UIO_H */ diff --git a/klibc/klibc/include/sys/un.h b/klibc/klibc/include/sys/un.h deleted file mode 100644 index df42d719f7..0000000000 --- a/klibc/klibc/include/sys/un.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * - */ - -#ifndef _SYS_UN_H -#define _SYS_UN_H - -#include - -#endif /* _SYS_UN_H */ diff --git a/klibc/klibc/include/sys/utime.h b/klibc/klibc/include/sys/utime.h deleted file mode 100644 index d1d635d242..0000000000 --- a/klibc/klibc/include/sys/utime.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * sys/utime.h - */ - -#ifndef _SYS_UTIME_H -#define _SYS_UTIME_H - -#include - -#endif /* _SYS_UTIME_H */ diff --git a/klibc/klibc/include/sys/utsname.h b/klibc/klibc/include/sys/utsname.h deleted file mode 100644 index f2990f5711..0000000000 --- a/klibc/klibc/include/sys/utsname.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * sys/utsname.h - */ - -#ifndef _SYS_UTSNAME_H -#define _SYS_UTSNAME_H - -#include - -#define SYS_NMLN 65 - -struct utsname { - char sysname[SYS_NMLN]; - char nodename[SYS_NMLN]; - char release[SYS_NMLN]; - char version[SYS_NMLN]; - char machine[SYS_NMLN]; - char domainname[SYS_NMLN]; -}; - -__extern int uname(struct utsname *); - -#endif /* _SYS_UTSNAME_H */ diff --git a/klibc/klibc/include/sys/vfs.h b/klibc/klibc/include/sys/vfs.h deleted file mode 100644 index 8c1577c4bf..0000000000 --- a/klibc/klibc/include/sys/vfs.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/vfs.h - */ - -#ifndef _SYS_VFS_H -#define _SYS_VFS_H - -#include -#include - -__extern int statfs(const char *, struct statfs *); -__extern int fstatfs(int, struct statfs *); - -#endif /* _SYS_VFS_H */ diff --git a/klibc/klibc/include/sys/wait.h b/klibc/klibc/include/sys/wait.h deleted file mode 100644 index 4cfafc9408..0000000000 --- a/klibc/klibc/include/sys/wait.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * sys/wait.h - */ - -#ifndef _SYS_WAIT_H -#define _SYS_WAIT_H - -#include -#include -#include - -#include - -#define WEXITSTATUS(s) (((s) & 0xff00) >> 8) -#define WTERMSIG(s) ((s) & 0x7f) -#define WIFEXITED(s) (WTERMSIG(s) == 0) -#define WIFSTOPPED(s) (WTERMSIG(s) == 0x7f) -/* Ugly hack to avoid multiple evaluation of "s" */ -#define WIFSIGNALED(s) (WTERMSIG((s)+1) >= 2) -#define WCOREDUMP(s) ((s) & 0x80) -#define WSTOPSIG(s) WEXITSTATUS(s) - -__extern pid_t wait(int *); -__extern pid_t waitpid(pid_t, int *, int); -__extern pid_t wait3(int *, int, struct rusage *); -__extern pid_t wait4(pid_t, int *, int, struct rusage *); - -#endif /* _SYS_WAIT_H */ diff --git a/klibc/klibc/include/syslog.h b/klibc/klibc/include/syslog.h deleted file mode 100644 index 551527a042..0000000000 --- a/klibc/klibc/include/syslog.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * syslog.h - */ - -#ifndef _SYSLOG_H -#define _SYSLOG_H - -#include -#include - -/* Alert levels */ -#define LOG_EMERG 0 -#define LOG_ALERT 1 -#define LOG_CRIT 2 -#define LOG_ERR 3 -#define LOG_WARNING 4 -#define LOG_NOTICE 5 -#define LOG_INFO 6 -#define LOG_DEBUG 7 - -#define LOG_PRIMASK 7 -#define LOG_PRI(x) ((x) & LOG_PRIMASK) - - -/* Facilities; not actually used */ -#define LOG_KERN 0000 -#define LOG_USER 0010 -#define LOG_MAIL 0020 -#define LOG_DAEMON 0030 -#define LOG_AUTH 0040 -#define LOG_SYSLOG 0050 -#define LOG_LPR 0060 -#define LOG_NEWS 0070 -#define LOG_UUCP 0100 -#define LOG_CRON 0110 -#define LOG_AUTHPRIV 0120 -#define LOG_FTP 0130 -#define LOG_LOCAL0 0200 -#define LOG_LOCAL1 0210 -#define LOG_LOCAL2 0220 -#define LOG_LOCAL3 0230 -#define LOG_LOCAL4 0240 -#define LOG_LOCAL5 0250 -#define LOG_LOCAL6 0260 -#define LOG_LOCAL7 0270 - -#define LOG_FACMASK 01770 -#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3)) - -__extern void openlog(const char *, int, int); -__extern void syslog(int, const char *, ...); -__extern void vsyslog(int, const char *, va_list); -__extern void closelog(void); - -#endif /* _SYSLOG_H */ diff --git a/klibc/klibc/include/termios.h b/klibc/klibc/include/termios.h deleted file mode 100644 index 08a5e56855..0000000000 --- a/klibc/klibc/include/termios.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * termios.h - */ - -#ifndef _TERMIOS_H -#define _TERMIOS_H - -#include -#include -#include -#include -#include - -/* Redefine these so the magic constants == the ioctl number to use. */ -#undef TCSANOW -#undef TCSADRAIN -#undef TCSAFLUSH -#define TCSANOW TCSETS -#define TCSADRAIN TCSETSW -#define TCSAFLUSH TCSETSF - -static __inline__ int tcgetattr(int __fd, struct termios *__s) -{ - return ioctl(__fd, TCGETS, __s); -} - -static __inline__ int tcsetattr(int __fd, int __opt, const struct termios *__s) -{ - return ioctl(__fd, __opt, (void *)__s); -} - -static __inline__ int tcflow(int __fd, int __action) -{ - return ioctl(__fd, TCXONC, (void *)(intptr_t)__action); -} - -static __inline__ int tcflush(int __fd, int __queue) -{ - return ioctl(__fd, TCFLSH, (void *)(intptr_t)__queue); -} - -static __inline__ pid_t tcgetpgrp(int __fd) -{ - pid_t __p; - return ioctl(__fd, TIOCGPGRP, &__p) ? (pid_t)-1 : __p; -} - -static __inline__ pid_t tcgetsid(int __fd) -{ - pid_t __p; - return ioctl(__fd, TIOCGSID, &__p) ? (pid_t)-1 : __p; -} - -static __inline__ int tcsendbreak(int __fd, int __duration) -{ - return ioctl(__fd, TCSBRKP, (void *)(uintptr_t)__duration); -} - -static __inline__ int tcsetpgrp(int __fd, pid_t __p) -{ - return ioctl(__fd, TIOCSPGRP, &__p); -} - -static __inline__ speed_t cfgetospeed(const struct termios *__s) -{ - return (speed_t)(__s->c_cflag & CBAUD); -} - -static __inline__ speed_t cfgetispeed(const struct termios *__s) -{ - return (speed_t)(__s->c_cflag & CBAUD); -} - -static __inline__ int cfsetospeed(struct termios *__s, speed_t __v) -{ - __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); - return 0; -} - -static __inline__ int cfsetispeed(struct termios *__s, speed_t __v) -{ - __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); - return 0; -} - -#endif /* _TERMIOS_H */ diff --git a/klibc/klibc/include/time.h b/klibc/klibc/include/time.h deleted file mode 100644 index c69c231ec8..0000000000 --- a/klibc/klibc/include/time.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * time.h - */ - -#ifndef _TIME_H -#define _TIME_H - -#include -#include - -__extern time_t time(time_t *); -__extern int nanosleep(const struct timespec *, struct timespec *); - -#endif /* _TIME_H */ diff --git a/klibc/klibc/include/unistd.h b/klibc/klibc/include/unistd.h deleted file mode 100644 index 13ff03b012..0000000000 --- a/klibc/klibc/include/unistd.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * unistd.h - */ - -#ifndef _UNISTD_H -#define _UNISTD_H - -#include -#include -#include -#include -#include - -__extern char **environ; -__extern __noreturn _exit(int); - -__extern pid_t fork(void); -__extern pid_t vfork(void); -__extern pid_t getpid(void); -__extern pid_t getpgid(pid_t); -__extern int setpgid(pid_t, pid_t); -__extern pid_t getppid(void); -__extern pid_t getpgrp(void); -__extern int setpgrp(void); -__extern pid_t setsid(void); -__extern pid_t getsid(pid_t); -__extern int execv(const char *, char * const *); -__extern int execvp(const char *, char * const *); -__extern int execve(const char *, char * const *, char * const *); -__extern int execvpe(const char *, char * const *, char * const *); -__extern int execl(const char *, const char *, ...); -__extern int execlp(const char *, const char *, ...); -__extern int execle(const char *, const char *, ...); -__extern int execlpe(const char *, const char *, ...); - -__extern int setuid(uid_t); -__extern uid_t getuid(void); -__extern int seteuid(uid_t); -__extern uid_t geteuid(void); -__extern int setgid(gid_t); -__extern gid_t getgid(void); -__extern int setegid(gid_t); -__extern gid_t getegid(void); -__extern int getgroups(int, gid_t *); -__extern int setgroups(size_t, const gid_t *); -__extern int setreuid(uid_t, uid_t); -__extern int setregid(gid_t, gid_t); -__extern int setresuid(uid_t, uid_t, uid_t); -__extern int setresgid(gid_t, gid_t, gid_t); -__extern int getfsuid(uid_t); -__extern int setfsuid(uid_t); - -/* Macros for access() */ -#define R_OK 4 /* Read */ -#define W_OK 2 /* Write */ -#define X_OK 1 /* Execute */ -#define F_OK 0 /* Existence */ - -__extern int access(const char *, int); -__extern int link(const char *, const char *); -__extern int unlink(const char *); -__extern int chdir(const char *); -__extern int chmod(const char *, mode_t); -__extern int fchmod(int, mode_t); -__extern int mkdir(const char *, mode_t); -__extern int rmdir(const char *); -__extern int pipe(int *); -__extern int chroot(const char *); -__extern int symlink(const char *, const char *); -__extern int readlink(const char *, char *, size_t); -__extern int chown(const char *, uid_t, gid_t); -__extern int fchown(int, uid_t, gid_t); -__extern int lchown(const char *, uid_t, gid_t); -__extern char *getcwd(char *, size_t); - -__extern int sync(void); - -__extern ssize_t read(int, void *, size_t); -__extern ssize_t write(int, const void *, size_t); -#ifndef __IN_OPEN_C -__extern __cdecl int open(const char *, int, ...); -#endif -__extern int close(int); -__extern off_t lseek(int, off_t, int); -__extern loff_t llseek(int, loff_t, int); -__extern int dup(int); -__extern int dup2(int, int); -__extern int fcntl(int, int, long); -__extern int ioctl(int, int, void *); -__extern int flock(int, int); -__extern int fsync(int); -__extern int fdatasync(int); -__extern int ftruncate(int, off_t); - -__extern int pause(void); -__extern unsigned int alarm(unsigned int); -__extern unsigned int sleep(unsigned int); -__extern void usleep(unsigned long); - -__extern int gethostname(char *, size_t); -__extern int sethostname(const char *, size_t); -__extern int getdomainname(char *, size_t); -__extern int setdomainname(const char *, size_t); - -__extern void *__brk(void *); -__extern int brk(void *); -__extern void *sbrk(ptrdiff_t); - -__extern int getopt(int, char * const *, const char *); -__extern char *optarg; -__extern int optind, opterr, optopt; - -__extern int isatty(int); - -__extern int getpagesize(void); - -/* Standard file descriptor numbers. */ -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 - -#endif /* _UNISTD_H */ diff --git a/klibc/klibc/include/utime.h b/klibc/klibc/include/utime.h deleted file mode 100644 index 3dfa03a14a..0000000000 --- a/klibc/klibc/include/utime.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * utime.h - */ - -#ifndef _UTIME_H -#define _UTIME_H - -#include -#include -#include - -__extern int utime(const char *, const struct utimbuf *); - -#endif /* _UTIME_H */ - diff --git a/klibc/klibc/inet/bindresvport.c b/klibc/klibc/inet/bindresvport.c index c30054edfd..750bd709c4 100644 --- a/klibc/klibc/inet/bindresvport.c +++ b/klibc/klibc/inet/bindresvport.c @@ -9,8 +9,8 @@ #include #include -#define START_PORT 600 -#define END_PORT (IPPORT_RESERVED - 1) +#define START_PORT 768 +#define END_PORT IPPORT_RESERVED #define NUM_PORTS (END_PORT - START_PORT) int bindresvport(int sd, struct sockaddr_in *sin) @@ -21,14 +21,12 @@ int bindresvport(int sd, struct sockaddr_in *sin) int i; if (sin == NULL) { + memset(&me, 0, sizeof(me)); sin = &me; - memset(sin, 0, sizeof(me)); - sin->sin_port = AF_INET; - } - else if (sin->sin_family != AF_INET) { + sin->sin_family = AF_INET; + } else if (sin->sin_family != AF_INET) { errno = EPFNOSUPPORT; - ret = -1; - goto bail; + return -1; } if (port == 0) { @@ -36,13 +34,12 @@ int bindresvport(int sd, struct sockaddr_in *sin) } for (i = 0; i < NUM_PORTS; i++, port++) { - sin->sin_port = htons(port); - if ((ret = bind(sd, (struct sockaddr *)&sin, sizeof(*sin))) != -1) - break; if (port == END_PORT) port = START_PORT; + sin->sin_port = htons(port); + if ((ret = bind(sd, (struct sockaddr *)sin, sizeof(*sin))) != -1) + break; } - bail: return ret; } diff --git a/klibc/klibc/interp.S b/klibc/klibc/interp.S index 303943697b..b1a2701999 100644 --- a/klibc/klibc/interp.S +++ b/klibc/klibc/interp.S @@ -2,7 +2,9 @@ # This is a hack to generate the .intrp section, which then # ld turns into an PT_INTERP header. # - +# NOTE: The .interp section needs to be "a", or it doesnt work... +# + .section ".interp","a" .ascii LIBDIR .ascii "/klibc-" diff --git a/klibc/klibc/jrand48.c b/klibc/klibc/jrand48.c new file mode 100644 index 0000000000..a2ead11e5f --- /dev/null +++ b/klibc/klibc/jrand48.c @@ -0,0 +1,24 @@ +/* + * jrand48.c + */ + +#include +#include + +long jrand48(unsigned short xsubi[3]) +{ + uint64_t x; + + /* The xsubi[] array is littleendian by spec */ + x = (uint64_t)xsubi[0] + + ((uint64_t)xsubi[1] << 16) + + ((uint64_t)xsubi[2] << 32); + + x = (0x5deece66dULL * x) + 0xb; + + xsubi[0] = (unsigned short)x; + xsubi[1] = (unsigned short)(x >> 16); + xsubi[2] = (unsigned short)(x >> 32); + + return (long)(int32_t)(x >> 16); +} diff --git a/klibc/klibc/libc_init.c b/klibc/klibc/libc_init.c new file mode 100644 index 0000000000..e91edc44a3 --- /dev/null +++ b/klibc/klibc/libc_init.c @@ -0,0 +1,86 @@ +/* + * libc_init.c + * + * This function takes the raw data block set up by the ELF loader + * in the kernel and parses it. It is invoked by crt0.S which makes + * any necessary adjustments and passes calls this function using + * the standard C calling convention. + * + * The arguments are: + * uintptr_t *elfdata -- The ELF loader data block; usually from the stack. + * Basically a pointer to argc. + * void (*onexit)(void) -- Function to install into onexit + */ + +#include +#include +#include +#include +#include + +/* This file is included from __static_init.c or __shared_init.c */ +#ifndef SHARED +# error "SHARED should be defined to 0 or 1" +#endif + +char **environ; +unsigned int __page_size, __page_shift; + +struct auxentry { + uintptr_t type; + uintptr_t v; +}; + +__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void)) +{ + int argc; + char **argv, **envp, **envend; + struct auxentry *auxentry; +#if SHARED + typedef int (*main_t)(int, char **, char **); + main_t MAIN = NULL; +#else + extern int main(int, char **, char **); +#define MAIN main +#endif + unsigned int page_size = 0, page_shift = 0; + + (void)onexit; /* For now, we ignore this... */ + + argc = (int)*elfdata++; + argv = (char **)elfdata; + envp = argv+(argc+1); + + /* The auxillary entry vector is after all the environment vars */ + for ( envend = envp ; *envend ; envend++ ); + auxentry = (struct auxentry *)(envend+1); + + while ( auxentry->type ) { + switch ( auxentry->type ) { +#if SHARED + case AT_ENTRY: + MAIN = (main_t)(auxentry->v); + break; +#endif + case AT_PAGESZ: + page_size = (int)(auxentry->v); + break; + } + auxentry++; + } + + __page_size = page_size; + +#if defined(__i386__) || defined(__x86_64__) + asm("bsrl %1,%0" : "=r" (page_shift) : "rm" (page_size)); +#else + while ( page_size > 1 ) { + page_shift++; + page_size >>= 1; + } +#endif + __page_shift = page_shift; + + environ = envp; + exit(MAIN(argc, argv, envp)); +} diff --git a/klibc/klibc/llseek.c b/klibc/klibc/llseek.c index fdffc16e2c..2102a503e9 100644 --- a/klibc/klibc/llseek.c +++ b/klibc/klibc/llseek.c @@ -1,8 +1,10 @@ /* * llseek.c * - * On 32-bit platforms, we need llseek() as well as lseek() to be - * able to handle large disks + * On 32-bit platforms, we need to use the _llseek() system call + * rather than lseek(), to be able to handle large disks. _llseek() + * isn't just a normal syscall which takes a 64-bit argument; it needs + * to return a 64-bit value and so takes an extra pointer. */ #include @@ -10,24 +12,17 @@ #if BITSIZE == 32 -static inline _syscall5(int, _llseek, int, fd, unsigned long, hi, unsigned long, lo, loff_t *,res, int, whence); +extern int __llseek(int fd, unsigned long hi, unsigned long lo, off_t *res, int whence); -loff_t llseek(int fd, loff_t offset, int whence) +off_t lseek(int fd, off_t offset, int whence) { - loff_t result; + off_t result; int rv; - rv = _llseek(fd, (unsigned long)(offset >> 32), - (unsigned long)offset, &result, whence); + rv = __llseek(fd, (unsigned long)(offset >> 32), (unsigned long)offset, + &result, whence); - return rv ? (loff_t)-1 : result; -} - -#else - -loff_t llseek(int fd, loff_t offset, int whence) -{ - return lseek(fd, offset, whence); + return rv ? (off_t)-1 : result; } #endif diff --git a/klibc/klibc/lrand48.c b/klibc/klibc/lrand48.c index 4d05de2e89..8c0a3de176 100644 --- a/klibc/klibc/lrand48.c +++ b/klibc/klibc/lrand48.c @@ -5,38 +5,10 @@ #include #include -unsigned short __rand48_seed[3]; - -long jrand48(unsigned short xsubi[3]) -{ - uint64_t x; - - /* The xsubi[] array is littleendian by spec */ - x = (uint64_t)xsubi[0] + - ((uint64_t)xsubi[1] << 16) + - ((uint64_t)xsubi[2] << 32); - - x = (0x5deece66dULL * x) + 0xb; - - xsubi[0] = (unsigned short)x; - xsubi[1] = (unsigned short)(x >> 16); - xsubi[2] = (unsigned short)(x >> 32); - - return (long)(int32_t)(x >> 16); -} - -long mrand48(void) -{ - return jrand48(__rand48_seed); -} - -long nrand48(unsigned short xsubi[3]) -{ - return (long)((uint32_t)jrand48(xsubi) >> 1); -} +unsigned short __rand48_seed[3]; /* Common with mrand48.c, srand48.c */ long lrand48(void) { - return (long)((uint32_t)(mrand48() >> 1)); + return (uint32_t)jrand48(__rand48_seed) >> 1; } diff --git a/klibc/klibc/makeerrlist.pl b/klibc/klibc/makeerrlist.pl index 00acb8a3d5..f42704f88a 100644 --- a/klibc/klibc/makeerrlist.pl +++ b/klibc/klibc/makeerrlist.pl @@ -20,7 +20,7 @@ sub parse_file($) { $file = $rootdir.$file; - print STDERR "opening $file\n"; + print STDERR "opening $file\n" unless ( $quiet ); if ( !($fh->open("< ".$file)) ) { die "$0: cannot open $file\n"; @@ -38,7 +38,7 @@ sub parse_file($) { $error = $1; $errno = $2+0; $msg = $3; - print STDERR "$error ($errno) => \"$msg\"\n"; + print STDERR "$error ($errno) => \"$msg\"\n" unless ( $quiet ); $errors{$errno} = $error; $errmsg{$errno} = $msg; $maxerr = $errno if ( $errno > $maxerr ); @@ -50,12 +50,23 @@ sub parse_file($) { } } close($fh); - print STDERR "closing $file\n"; + print STDERR "closing $file\n" unless ( $quiet ); } -parse_file('linux/errno.h'); +$v = $ENV{'KBUILD_VERBOSE'}; +$quiet = defined($v) ? !$v : 0; -($type) = @ARGV; +foreach $arg ( @ARGV ) { + if ( $arg eq '-q' ) { + $quiet = 1; + } elsif ( $arg =~ /^-(errlist|errnos|maxerr)$/ ) { + $type = $arg; + } else { + die "$0: Unknown option: $arg\n"; + } +} + +parse_file('linux/errno.h'); if ( $type eq '-errlist' ) { print "#include \n"; diff --git a/klibc/klibc/malloc.c b/klibc/klibc/malloc.c index 20a2350d71..976353c201 100644 --- a/klibc/klibc/malloc.c +++ b/klibc/klibc/malloc.c @@ -133,9 +133,14 @@ void *malloc(size_t size) } /* Nothing found... need to request a block from the kernel */ - fsize = (size+MALLOC_CHUNK_MASK) & ~MALLOC_CHUNK_MASK; + fsize = (size+MALLOC_CHUNK_MASK) & ~MALLOC_CHUNK_MASK; + +#ifdef MALLOC_USING_SBRK + fp = (struct free_arena_header *) sbrk(fsize); +#else fp = (struct free_arena_header *) mmap(NULL, fsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); +#endif if ( fp == (struct free_arena_header *)MAP_FAILED ) { return NULL; /* Failed to get a block */ diff --git a/klibc/klibc/malloc.h b/klibc/klibc/malloc.h index e053f71401..456295069a 100644 --- a/klibc/klibc/malloc.h +++ b/klibc/klibc/malloc.h @@ -6,13 +6,7 @@ #include #include - -/* - * This is the minimum chunk size we will ask the kernel for; this should - * be a multiple of the page size on all architectures. - */ -#define MALLOC_CHUNK_SIZE 65536 -#define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) +#include /* * This structure should be a power of two. This becomes the diff --git a/klibc/klibc/mmap.c b/klibc/klibc/mmap.c index 89cf3a6a8f..196f1c088f 100644 --- a/klibc/klibc/mmap.c +++ b/klibc/klibc/mmap.c @@ -6,46 +6,44 @@ #include #include #include +#include #include /* For PAGE_SHIFT */ #if defined(__sparc__) # define MMAP2_SHIFT 12 /* Fixed by syscall definition */ +#elif defined(__mips__) || defined(__powerpc__) +# define MMAP2_SHIFT __getpageshift() /* Variable */ #else # define MMAP2_SHIFT PAGE_SHIFT #endif -#define MMAP2_MASK ((1UL << MMAP2_SHIFT)-1) /* - * Prefer mmap2() over mmap(), except on the architectures listed + * Set in SYSCALLS whether or not we should use an unadorned mmap() system + * call (typical on 64-bit architectures). */ +#if (BITSIZE == 32 && defined(__NR_mmap2)) || (BITSIZE == 64 && !defined(__NR_mmap)) -#if defined(__NR_mmap2) && !defined(__sparc__) && !defined(__ia64__) && !defined(__powerpc__) && !defined(__powerpc64__) +/* This architecture uses mmap2(). The Linux mmap2() system call takes + a page offset as the offset argument. We need to make sure we have + the proper conversion in place. */ -/* This architecture uses mmap2() */ - -static inline _syscall6(void *,mmap2,void *,start,size_t,length,int,prot,int,flags,int,fd,off_t,offset); - -/* The Linux mmap2() system call takes a page offset as the offset argument. - We need to make sure we have the proper conversion in place. */ +extern void *__mmap2(void *, size_t, int, int, int, size_t); void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { - if ( offset & MMAP2_MASK ) { + const int mmap2_shift = MMAP2_SHIFT; + const unsigned long mmap2_mask = (1UL << mmap2_shift) - 1; + + if ( offset & mmap2_mask ) { errno = EINVAL; return MAP_FAILED; } - return mmap2(start, length, prot, flags, fd, (size_t)offset >> MMAP2_SHIFT); + return __mmap2(start, length, prot, flags, fd, (size_t)offset >> mmap2_shift); } -#else - -/* This architecture uses a plain mmap() system call */ -/* Only use this for architectures where mmap() is a real 6-argument system call! */ - -_syscall6(void *,mmap,void *,start,size_t,length,int,prot,int,flags,int,fd,off_t,offset) - #endif + diff --git a/klibc/klibc/mrand48.c b/klibc/klibc/mrand48.c new file mode 100644 index 0000000000..886ae9f03c --- /dev/null +++ b/klibc/klibc/mrand48.c @@ -0,0 +1,13 @@ +/* + * mrand48.c + */ + +#include +#include + +unsigned short __rand48_seed[3]; /* Common with lrand48.c, srand48.c */ + +long mrand48(void) +{ + return jrand48(__rand48_seed); +} diff --git a/klibc/klibc/nice.c b/klibc/klibc/nice.c index f0d97a3cd0..5a18de9091 100644 --- a/klibc/klibc/nice.c +++ b/klibc/klibc/nice.c @@ -7,11 +7,7 @@ #include #include -#ifdef __NR_nice - -_syscall1(int,nice,int,inc); - -#else +#ifndef __NR_nice int nice(int inc) { diff --git a/klibc/klibc/nrand48.c b/klibc/klibc/nrand48.c new file mode 100644 index 0000000000..fb7c5772fd --- /dev/null +++ b/klibc/klibc/nrand48.c @@ -0,0 +1,11 @@ +/* + * nrand48.c + */ + +#include +#include + +long nrand48(unsigned short xsubi[3]) +{ + return (long)((uint32_t)jrand48(xsubi) >> 1); +} diff --git a/klibc/klibc/open.c b/klibc/klibc/open.c index 0d7db10c4a..d52b53a699 100644 --- a/klibc/klibc/open.c +++ b/klibc/klibc/open.c @@ -1,17 +1,21 @@ /* * open.c * - * The open syscall is weird, because it's defined as a varadic - * function, but implementing it as such generally sucks for - * performance. Thus we generate it as a 3-argument function, - * but with explicit __cdecl assuming the __cdecl convention is - * independent of being varadic. + * On 32-bit platforms we need to pass O_LARGEFILE to the open() + * system call, to indicate that we're 64-bit safe. */ -#define __IN_OPEN_C +#define _KLIBC_IN_OPEN_C #include #include -#include -#include -__cdecl _syscall3(int,open,const char *,file,int,flags,mode_t,mode) +#if BITSIZE == 32 && !defined(__i386__) + +extern int __open(const char *, int, mode_t); + +int open(const char *pathname, int flags, mode_t mode) +{ + return __open(pathname, flags|O_LARGEFILE, mode); +} + +#endif diff --git a/klibc/klibc/pause.c b/klibc/klibc/pause.c index 5748728472..1f7b9342de 100644 --- a/klibc/klibc/pause.c +++ b/klibc/klibc/pause.c @@ -7,11 +7,7 @@ #include #include -#ifdef __NR_pause - -_syscall0(int,pause); - -#else +#ifndef __NR_pause int pause(void) { diff --git a/klibc/klibc/perror.c b/klibc/klibc/perror.c index 45585cd577..26f8ce8f6d 100644 --- a/klibc/klibc/perror.c +++ b/klibc/klibc/perror.c @@ -8,5 +8,6 @@ void perror(const char *s) { - fprintf(stderr, "%s: error %d\n", s, errno); + int e = errno; + fprintf(stderr, "%s: %s\n", s, strerror(e)); } diff --git a/klibc/klibc/putchar.c b/klibc/klibc/putchar.c new file mode 100644 index 0000000000..0e35adda17 --- /dev/null +++ b/klibc/klibc/putchar.c @@ -0,0 +1,15 @@ +/* + * putchar.c + * + * - gcc wants this + */ + +#include + +#undef putchar /* Defined as a macro */ +int putchar(int); + +int putchar(int c) +{ + return fputc(c, stdout); +} diff --git a/klibc/klibc/qsort.c b/klibc/klibc/qsort.c index e2197ea2ae..185f4dac69 100644 --- a/klibc/klibc/qsort.c +++ b/klibc/klibc/qsort.c @@ -23,14 +23,14 @@ void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, co { size_t gap = nmemb; size_t i, j; - void *p1, *p2; + char *p1, *p2; int swapped; do { gap = newgap(gap); swapped = 0; - for ( i = 0, p1 = base ; i < nmemb-gap ; i++, (char *)p1 += size ) { + for ( i = 0, p1 = base ; i < nmemb-gap ; i++, p1 += size ) { j = i+gap; if ( compar(p1, p2 = (char *)base+j*size) > 0 ) { memswap(p1, p2, size); diff --git a/klibc/klibc/readdir.c b/klibc/klibc/readdir.c index bb216a1951..acfe588713 100644 --- a/klibc/klibc/readdir.c +++ b/klibc/klibc/readdir.c @@ -1,21 +1,12 @@ /* - * opendir/readdir/closedir + * readdir.c: opendir/readdir/closedir */ #include #include #include -#include -#include - -#define __IO_DIR_DEFINED -struct _IO_dir { - int fd; - size_t bytes_left; - struct dirent *next; - struct dirent buffer[15]; /* 15 times max dirent size =~ 4K */ -}; +#define __KLIBC_DIRENT_INTERNALS #include DIR *opendir(const char *name) @@ -25,9 +16,9 @@ DIR *opendir(const char *name) if ( !dp ) return NULL; - dp->fd = open(name, O_DIRECTORY|O_RDONLY); + dp->__fd = open(name, O_DIRECTORY|O_RDONLY); - if ( dp->fd < 0 ) { + if ( dp->__fd < 0 ) { free(dp); return NULL; } @@ -43,7 +34,7 @@ struct dirent *readdir(DIR *dir) int rv; if ( !dir->bytes_left ) { - rv = getdents(dir->fd, dir->buffer, sizeof(dir->buffer)); + rv = getdents(dir->__fd, dir->buffer, sizeof(dir->buffer)); if ( rv <= 0 ) return NULL; dir->bytes_left = rv; @@ -51,7 +42,7 @@ struct dirent *readdir(DIR *dir) } dent = dir->next; - ((char *)dir->next) += dent->d_reclen; + dir->next = (struct dirent *)((char *)dir->next + dent->d_reclen); dir->bytes_left -= dent->d_reclen; return dent; @@ -60,7 +51,7 @@ struct dirent *readdir(DIR *dir) int closedir(DIR *dir) { int rv; - rv = close(dir->fd); + rv = close(dir->__fd); free(dir); return rv; } diff --git a/klibc/klibc/sbrk.c b/klibc/klibc/sbrk.c index 03ab3c14bb..f7401dcfe2 100644 --- a/klibc/klibc/sbrk.c +++ b/klibc/klibc/sbrk.c @@ -1,23 +1,41 @@ /* sbrk.c - Change data segment size */ /* Written 2000 by Werner Almesberger */ +/* Modified 2003-2004 for klibc by H. Peter Anvin */ #include #include -#include +#include +#include +#include "malloc.h" char *__current_brk; /* Common with brk.c */ +/* p is an address, a is alignment; must be a power of 2 */ +static inline void *align_up(void *p, uintptr_t a) +{ + return (void *) (((uintptr_t)p + a-1) & ~(a-1)); +} + void *sbrk(ptrdiff_t increment) { - char *old_brk, *new_brk; + char *start, *end, *new_brk; if (!__current_brk) __current_brk = __brk(NULL); - new_brk = __brk(__current_brk+increment); - if (new_brk != __current_brk+increment) + + start = align_up(__current_brk, SBRK_ALIGNMENT); + end = start + increment; + + new_brk = __brk(end); + + if (new_brk == (void *)-1) + return (void *)-1; + else if (new_brk < end) { + errno = ENOMEM; return (void *) -1; - old_brk = __current_brk; + } + __current_brk = new_brk; - return old_brk; + return end; } diff --git a/klibc/klibc/seed48.c b/klibc/klibc/seed48.c index f8353c8715..ac916d6165 100644 --- a/klibc/klibc/seed48.c +++ b/klibc/klibc/seed48.c @@ -6,7 +6,7 @@ #include #include -extern unsigned short __rand48_seed[3]; +unsigned short __rand48_seed[3]; unsigned short *seed48(const unsigned short xsubi[3]) { diff --git a/klibc/klibc/select.c b/klibc/klibc/select.c deleted file mode 100644 index 2404bb1e64..0000000000 --- a/klibc/klibc/select.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -#ifdef __NR__newselect -#undef __NR_select -#define __NR_select __NR__newselect -#endif - -_syscall5(int,select,int,a0,fd_set *,a1,fd_set *,a2,fd_set *,a3,struct timeval *,a4); diff --git a/klibc/klibc/setresgid.c b/klibc/klibc/setresgid.c deleted file mode 100644 index f1a8c6b45c..0000000000 --- a/klibc/klibc/setresgid.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * setresgid.c - */ - -#include -#include - -#ifdef __NR_setresgid - -_syscall3(int,setresgid,gid_t,a0,gid_t,a1,gid_t,a2); - -#elif defined(__NR_setresgid32) - -static inline _syscall3(int,setresgid32,gid_t,a0,gid_t,a1,gid_t,a2); - -int setresgid(gid_t a0, gid_t a1, gid_t a2) -{ - if ( sizeof(gid_t) == sizeof(uint32_t) ) { - return setresgid32(a0,a1,a2); - } else { - uint32_t x0 = (a0 == (gid_t)-1) ? (uint32_t)-1 : a0; - uint32_t x1 = (a1 == (gid_t)-1) ? (uint32_t)-1 : a1; - uint32_t x2 = (a2 == (gid_t)-1) ? (uint32_t)-1 : a2; - - return setresgid32(x0,x1,x2); - } -} - -#endif diff --git a/klibc/klibc/setresuid.c b/klibc/klibc/setresuid.c deleted file mode 100644 index a587acbae3..0000000000 --- a/klibc/klibc/setresuid.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * setresuid.c - */ - -#include -#include - -#ifdef __NR_setresuid - -_syscall3(int,setresuid,uid_t,a0,uid_t,a1,uid_t,a2); - -#elif defined(__NR_setresuid32) - -static inline _syscall3(int,setresuid32,uid_t,a0,uid_t,a1,uid_t,a2); - -int setresuid(uid_t a0, uid_t a1, uid_t a2) -{ - if ( sizeof(uid_t) == sizeof(uint32_t) ) { - return setresuid32(a0,a1,a2); - } else { - uint32_t x0 = (a0 == (uid_t)-1) ? (uint32_t)-1 : a0; - uint32_t x1 = (a1 == (uid_t)-1) ? (uint32_t)-1 : a1; - uint32_t x2 = (a2 == (uid_t)-1) ? (uint32_t)-1 : a2; - - return setresuid32(x0,x1,x2); - } -} - -#endif - diff --git a/klibc/klibc/sha1hash.c b/klibc/klibc/sha1hash.c index 600d51248c..f81e08b17c 100644 --- a/klibc/klibc/sha1hash.c +++ b/klibc/klibc/sha1hash.c @@ -289,7 +289,7 @@ char *mybase64(uint8_t digest[20]) int main(int argc, char** argv) { - int i, j; + int i; SHA1_CTX context; uint8_t digest[20], buffer[16384]; FILE* file; diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c index ebd34710f1..885bc6a4a4 100644 --- a/klibc/klibc/sigaction.c +++ b/klibc/klibc/sigaction.c @@ -5,11 +5,7 @@ #include #include -#ifdef __NR_sigaction - -_syscall3(int,sigaction,int,sig,const struct sigaction *,act,struct sigaction *,oact); - -#else +#if !defined(__NR_sigaction) int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { diff --git a/klibc/klibc/sigpending.c b/klibc/klibc/sigpending.c index afbcf3cf34..76d2b1a7f6 100644 --- a/klibc/klibc/sigpending.c +++ b/klibc/klibc/sigpending.c @@ -5,11 +5,7 @@ #include #include -#ifdef __NR_sigpending - -_syscall1(int,sigpending,sigset_t *,set); - -#else +#ifndef __NR_sigpending int sigpending(sigset_t *set) { diff --git a/klibc/klibc/sigprocmask.c b/klibc/klibc/sigprocmask.c index 3a90f67732..b5e58b28b8 100644 --- a/klibc/klibc/sigprocmask.c +++ b/klibc/klibc/sigprocmask.c @@ -5,11 +5,7 @@ #include #include -#ifdef __NR_sigprocmask - -_syscall3(int,sigprocmask,int,how,const sigset_t *,set,sigset_t *,oset); - -#else +#ifndef __NR_sigprocmask int sigprocmask(int how, const sigset_t *set, sigset_t *oset) { diff --git a/klibc/klibc/sigsuspend.c b/klibc/klibc/sigsuspend.c index 85cdea20ca..a927999ae6 100644 --- a/klibc/klibc/sigsuspend.c +++ b/klibc/klibc/sigsuspend.c @@ -5,11 +5,7 @@ #include #include -#ifdef __NR_sigsuspend - -_syscall1(int,sigsuspend,const sigset_t *,mask); - -#else +#ifndef __NR_sigsuspend int sigsuspend(const sigset_t *mask) { diff --git a/klibc/klibc/socketcalls.pl b/klibc/klibc/socketcalls.pl index cf4daf6036..fd82b2b49f 100644 --- a/klibc/klibc/socketcalls.pl +++ b/klibc/klibc/socketcalls.pl @@ -1,17 +1,32 @@ #!/usr/bin/perl -($arch, $file) = @ARGV; + +$v = $ENV{'KBUILD_VERBOSE'}; +$quiet = defined($v) ? !$v : 0; + +@args = (); +for $arg ( @ARGV ) { + if ( $arg =~ /^-/ ) { + if ( $arg eq '-q' ) { + $quiet = 1; + } else { + die "$0: Unknown option: $arg\n"; + } + } else { + push(@args, $arg); + } +} +($file, $arch) = @args; if (!open(FILE, "< $file")) { - print STDERR "$file: $!\n"; - exit(1); + die "$file: $!\n"; } while ( defined($line = ) ) { chomp $line; - $line =~ s/\s*\#.*$//; # Strip comments and trailing blanks + $line =~ s/\s*[\#\;].*$//; # Strip comments and trailing blanks next unless $line; - if ( $line =~ /^\s*(.*)\s+([_a-zA-Z][_a-zA-Z0-9]+)\s*\((.*)\)$/ ) { + if ( $line =~ /^\s*\<\?\>\s*(.*)\s+([_a-zA-Z][_a-zA-Z0-9]+)\s*\((.*)\)$/ ) { $type = $1; $name = $2; $argv = $3; @@ -26,7 +41,7 @@ while ( defined($line = ) ) { $nargs = $i; if ( $arch eq 'i386' ) { - open(OUT, "> socketcalls/${name}.S") + open(OUT, '>', "socketcalls/${name}.S") or die "$0: Cannot open socketcalls/${name}.S\n"; print OUT "#include \n"; @@ -39,33 +54,31 @@ while ( defined($line = ) ) { print OUT "\tmovb \$SYS_\U${name}\E,%al\n"; print OUT "\tjmp __socketcall_common\n"; print OUT "\t.size ${name},.-${name}\n"; + close(OUT); } else { - open(OUT, "> socketcalls/${name}.c") + open(OUT, '>', "socketcalls/${name}.c") or die "$0: Cannot open socketcalls/${name}.c\n"; - print OUT "#include \"socketcommon.h\"\n\n"; - - print OUT "#ifdef __NR_$name\n\n"; - print OUT "_syscall", scalar(@args), "(", $type, ',', $name; - $i = 0; - foreach $arg ( @args ) { - print OUT ",", $arg, ",a",$i++; - } - print OUT ");\n"; - print OUT "\n#else\n\n"; - + + print OUT "#include \"../socketcommon.h\"\n"; + print OUT "\n"; + print OUT "#ifndef __NR_${name}\n\n"; + + print OUT "extern long __socketcall(int, const unsigned long *);\n\n"; + print OUT "$type $name (", join(', ', @cargs), ")\n"; print OUT "{\n"; print OUT " unsigned long args[$nargs];\n"; for ( $i = 0 ; $i < $nargs ; $i++ ) { print OUT " args[$i] = (unsigned long)a$i;\n"; } - print OUT " return ($type) socketcall(SYS_\U${name}\E, args);\n"; - print OUT "}\n"; - print OUT "\n#endif\n"; + print OUT " return ($type) __socketcall(SYS_\U${name}\E, args);\n"; + print OUT "}\n\n"; + + print OUT "#endif\n"; + + close(OUT); } - close(OUT); } else { - print STDERR "$file:$.: Could not parse input\n"; - exit(1); + die "$file:$.: Could not parse input\n"; } } diff --git a/klibc/klibc/socketcommon.h b/klibc/klibc/socketcommon.h index 7a5acaadaf..9c4b11fab8 100644 --- a/klibc/klibc/socketcommon.h +++ b/klibc/klibc/socketcommon.h @@ -13,13 +13,4 @@ #include #include #include - -/* - * Some architectures have socketcall(), some have real syscalls, - * and some have both, but the syscall version is always preferred. - * Look for __NR_ to probe for the existence of a syscall. - */ - -#ifdef __NR_socketcall -static inline _syscall2(int,socketcall,int,call,unsigned long *,args); -#endif +#include diff --git a/klibc/klibc/srand48.c b/klibc/klibc/srand48.c index a3df16d95c..5f201d2047 100644 --- a/klibc/klibc/srand48.c +++ b/klibc/klibc/srand48.c @@ -5,8 +5,7 @@ #include #include -extern unsigned short __rand48_seed[3]; - +unsigned short __rand48_seed[3]; /* Common with mrand48.c, lrand48.c */ void srand48(long seedval) { diff --git a/klibc/klibc/statfs.c b/klibc/klibc/statfs.c new file mode 100644 index 0000000000..60e9188a09 --- /dev/null +++ b/klibc/klibc/statfs.c @@ -0,0 +1,19 @@ +/* + * statfs.c + * + * On architectures which do statfs64, wrap the system call + */ + +#include +#include + +#ifdef __NR_statfs64 + +extern int __statfs64(const char *, size_t, struct statfs *); + +int statfs(const char *path, struct statfs *buf) +{ + return __statfs64(path, sizeof *buf, buf); +} + +#endif diff --git a/klibc/klibc/strerror.c b/klibc/klibc/strerror.c index 62705553a6..c8e3eac793 100644 --- a/klibc/klibc/strerror.c +++ b/klibc/klibc/strerror.c @@ -7,18 +7,28 @@ char *strerror(int errnum) { static char message[32] = "error "; /* enough for error 2^63-1 */ - char numbuf[32]; char *p; + unsigned int e = (unsigned int)errnum; + +#ifdef WITH_ERRLIST + extern const int sys_nerr; + extern const char * const sys_errlist[]; + + if ( e < (unsigned int)sys_nerr && sys_errlist[e] ) + return (char *)sys_errlist[e]; +#endif p = numbuf+sizeof numbuf; *--p = '\0'; do { - *--p = (errnum % 10) + '0'; - errnum /= 10; - } while ( errnum ); + *--p = (e % 10) + '0'; + e /= 10; + } while ( e ); - return (char *)memcpy(message+6, p, (numbuf+sizeof numbuf)-p); + memcpy(message+6, p, (numbuf+sizeof numbuf)-p); + + return message; } diff --git a/klibc/klibc/strlcat.c b/klibc/klibc/strlcat.c new file mode 100644 index 0000000000..6111445f06 --- /dev/null +++ b/klibc/klibc/strlcat.c @@ -0,0 +1,31 @@ +/* + * strlcat.c + */ + +#include +#include + +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++; + } + + while ( (ch = *p++) ) { + if ( bytes < size ) + *q++ = ch; + + bytes++; + } + + *q = '\0'; + return bytes; +} + + diff --git a/klibc/klibc/strlcpy.c b/klibc/klibc/strlcpy.c new file mode 100644 index 0000000000..eb384c9885 --- /dev/null +++ b/klibc/klibc/strlcpy.c @@ -0,0 +1,26 @@ +/* + * strlcpy.c + */ + +#include +#include + +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 < size ) + *q++ = ch; + + bytes++; + } + + *q = '\0'; + return bytes; +} + + diff --git a/klibc/klibc/strncat.c b/klibc/klibc/strncat.c index 99d957594c..0dd9deb984 100644 --- a/klibc/klibc/strncat.c +++ b/klibc/klibc/strncat.c @@ -3,9 +3,23 @@ */ #include +#include char *strncat(char *dst, const char *src, size_t n) { - strncpy(strchr(dst, '\0'), src, n); + char *q = strchr(dst, '\0'); + const char *p = src; + char ch; + size_t nn = q-dst; + + if ( __likely(nn <= n) ) + n -= nn; + + while (n--) { + *q++ = ch = *p++; + if ( !ch ) + break; + } + return dst; } diff --git a/klibc/klibc/strncpy.c b/klibc/klibc/strncpy.c index a8fe45fcbb..06964f31d6 100644 --- a/klibc/klibc/strncpy.c +++ b/klibc/klibc/strncpy.c @@ -1,7 +1,5 @@ /* * strncpy.c - * - * strncpy() */ #include @@ -12,11 +10,15 @@ char *strncpy(char *dst, const char *src, size_t n) const char *p = src; char ch; - while ( n-- ) { + while (n) { + n--; *q++ = ch = *p++; if ( !ch ) break; } + /* The specs say strncpy() fills the entire buffer with NUL. Sigh. */ + memset(q, 0, n); + return dst; } diff --git a/klibc/klibc/strnlen.c b/klibc/klibc/strnlen.c new file mode 100644 index 0000000000..06b54c3189 --- /dev/null +++ b/klibc/klibc/strnlen.c @@ -0,0 +1,19 @@ +/* + * strnlen() + */ + +#include + +size_t strnlen(const char *s, size_t maxlen) +{ + const char *ss = s; + + /* Important: the maxlen test must precede the reference through ss; + since the byte beyond the maximum may segfault */ + while ((maxlen > 0) && *ss) { + ss++; + maxlen--; + } + return ss-s; +} + diff --git a/klibc/klibc/strtotimespec.c b/klibc/klibc/strtotimespec.c new file mode 100644 index 0000000000..b426bf8d0f --- /dev/null +++ b/klibc/klibc/strtotimespec.c @@ -0,0 +1,5 @@ +#define NAME strtotimespec +#define TIMEX struct timespec +#define FSEC tv_nsec +#define DECIMALS 9 +#include "strtotimex.c" diff --git a/klibc/klibc/strtotimeval.c b/klibc/klibc/strtotimeval.c new file mode 100644 index 0000000000..280d4bcd3a --- /dev/null +++ b/klibc/klibc/strtotimeval.c @@ -0,0 +1,5 @@ +#define NAME strtotimeval +#define TIMEX struct timeval +#define FSEC tv_usec +#define DECIMALS 6 +#include "strtotimex.c" diff --git a/klibc/klibc/strtotimex.c b/klibc/klibc/strtotimex.c new file mode 100644 index 0000000000..0f6c2f9181 --- /dev/null +++ b/klibc/klibc/strtotimex.c @@ -0,0 +1,39 @@ +/* + * strtotimex.c + * + * Nonstandard function which takes a string and converts it to a + * struct timespec/timeval. Returns a pointer to the first non-numeric + * character in the string. + * + */ + +#include +#include +#include +#include + +char * NAME (const char *str, TIMEX *ts) +{ + int n; + char *s, *s0; + __typeof__(ts->FSEC) fs; /* Fractional seconds */ + + ts->tv_sec = strntoumax(str, &s, 10, ~(size_t)0); + fs = 0; + + if ( *s == '.' ) { + s0 = s+1; + + fs = strntoumax(s0, &s, 10, DECIMALS); + n = s-s0; + + while ( isdigit(*s) ) + s++; + + for ( ; n < DECIMALS ; n++ ) + fs *= 10; + } + + ts->FSEC = fs; + return s; +} diff --git a/klibc/klibc/syscalls.pl b/klibc/klibc/syscalls.pl index b530a9b8c7..1c48ce58ff 100644 --- a/klibc/klibc/syscalls.pl +++ b/klibc/klibc/syscalls.pl @@ -1,46 +1,99 @@ #!/usr/bin/perl -($arch, $file) = @ARGV; +# +# Script to parse the SYSCALLS file and generate appropriate +# stubs. -if (!open(FILE, "< $file")) { - print STDERR "$file: $!\n"; - exit(1); +$v = $ENV{'KBUILD_VERBOSE'}; +$quiet = defined($v) ? !$v : 0; + +@args = (); +for $arg ( @ARGV ) { + if ( $arg =~ /^-/ ) { + if ( $arg eq '-q' ) { + $quiet = 1; + } else { + die "$0: Unknown option: $arg\n"; + } + } else { + push(@args, $arg); + } +} +($file, $arch, $bits, $unistd, $havesyscall) = @args; + +require "arch/$arch/sysstub.ph"; + +if (!open(UNISTD, '<', $unistd)) { + die "$0: $unistd: $!\n"; +} +while ( defined($line = ) ) { + chomp $line; + + if ( $line =~ /^\#\s*define\s+__NR_([A-Za-z0-9_]+)\s+(.*\S)\s*$/ ) { + $syscalls{$1} = $2; + print STDERR "SYSCALL FOUND: $1\n" unless ( $quiet ); + } +} +close(UNISTD); + +if (!open(HAVESYS, '>', $havesyscall)) { + die "$0: $havesyscall: $!\n"; +} + +print HAVESYS "#ifndef _KLIBC_HAVESYSCALL_H\n"; +print HAVESYS "#define _KLIBC_HAVESYSCALL_H 1\n\n"; + +if (!open(FILE, '<', $file)) { + die "$0: $file: $!\n"; } while ( defined($line = ) ) { chomp $line; - $line =~ s/\s*\#.*$//; # Strip comments and trailing blanks + $line =~ s/\s*(|[\#;].*)$//; # Strip comments and trailing blanks next unless $line; - if ( $line =~ /^\s*(\<[^\>]+\>\s+|)([^\(\<\>]+[^\@\:A-Za-z0-9_])([A-Za-z0-9_]+)(|\@[A-Za-z0-9_]+)(|\:\:[A-Za-z0-9_]+)\s*\(([^\:\)]*)\)\s*$/ ) { - $archs = $1; - $type = $2; - $sname = $3; - $stype = $4; - $fname = $5; - $argv = $6; + if ( $line =~ /^\s*(\<[^\>]+\>\s+|)([A-Za-z0-9_\*\s]+)\s+([A-Za-z0-9_,]+)(|\@[A-Za-z0-9_]+)(|\:\:[A-Za-z0-9_]+)\s*\(([^\:\)]*)\)\s*$/ ) { + $archs = $1; + $type = $2; + $snames = $3; + $stype = $4; + $fname = $5; + $argv = $6; - $doit = 1; + $doit = 1; + $maybe = 0; if ( $archs ne '' ) { - die "$0: Internal error" - unless ( $archs =~ /^\<(|\!)([^\>\!]+)\>/ ); - $not = $1; - $list = $2; + die "$file:$.: Invalid architecture spec: <$archs>\n" + unless ( $archs =~ /^\<(|\?)(|\!)([^\>\!\?]*)\>/ ); + $maybe = $1 ne ''; + $not = $2 ne ''; + $list = $3; - $doit = ($not eq '') ? 0 : 1; + $doit = $not || ($list eq ''); @list = split(/,/, $list); foreach $a ( @list ) { - if ( $a eq $arch ) { - $doit = ($not eq '') ? 1 : 0; + if ( $a eq $arch || $a eq $bits ) { + $doit = !$not; last; } } } next if ( ! $doit ); - $type =~ s/\s*$//; + undef $sname; + foreach $sn ( split(/,/, $snames) ) { + if ( defined $syscalls{$sn} ) { + $sname = $sn; + last; + } + } + if ( !defined($sname) ) { + next if ( $maybe ); + die "$file:$.: Undefined system call: $snames\n"; + } - $stype =~ s/^\@/_/; + $type =~ s/\s*$//; + $stype =~ s/^\@//; if ( $fname eq '' ) { $fname = $sname; @@ -50,32 +103,12 @@ while ( defined($line = ) ) { @args = split(/\s*\,\s*/, $argv); - open(OUT, "> syscalls/${fname}.c") - or die "$0: Cannot open syscalls/${fname}.c\n"; - - if ( $fname eq "rt_sigaction") { - print OUT "#ifdef __x86_64__\n\n"; - print OUT "struct sigaction;\n\n"; - print OUT "#endif\n\n" - } - - print OUT "#include \"syscommon.h\"\n\n"; - - if ( $fname ne $sname ) { - print OUT "#undef __NR_${fname}\n"; - print OUT "#define __NR_${fname} __NR_${sname}\n\n"; - } - - print OUT "_syscall", scalar(@args), $stype, "(", $type, ',', $fname; - - $i = 0; - foreach $arg ( @args ) { - print OUT ",", $arg, ",a",$i++; - } - print OUT ");\n"; - close(OUT); + print HAVESYS "#define _KLIBC_HAVE_SYSCALL_${fname} ${sname}\n"; + make_sysstub($fname, $type, $sname, $stype, @args); } else { - print STDERR "$file:$.: Could not parse input\n"; - exit(1); + die "$file:$.: Could not parse input: \"$line\"\n"; } } + +print HAVESYS "\n#endif\n"; +close(HAVESYS); diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c index 10a2dce405..592992ba6b 100644 --- a/klibc/klibc/syslog.c +++ b/klibc/klibc/syslog.c @@ -18,7 +18,7 @@ #define LOGDEV "/dev/kmsg" /* Max length of ID string */ -#define MAXID 31 +#define MAXID 31 /* MAXID+6 must be < BUFLEN */ int __syslog_fd = -1; static char id[MAXID+1]; @@ -43,16 +43,12 @@ void openlog(const char *ident, int option, int facility) void vsyslog(int prio, const char *format, va_list ap) { char buf[BUFLEN]; - int rv, len; + int len; int fd; if ( __syslog_fd == -1 ) openlog(NULL, 0, 0); - fd = __syslog_fd; - if ( fd == -1 ) - fd = 2; /* Failed to open log, write to stderr */ - buf[0] = '<'; buf[1] = LOG_PRI(prio)+'0'; buf[2] = '>'; @@ -61,13 +57,16 @@ void vsyslog(int prio, const char *format, va_list ap) if ( *id ) len += sprintf(buf+3, "%s: ", id); - rv = vsnprintf(buf+len, BUFLEN-len, format, ap); + len += vsnprintf(buf+len, BUFLEN-len, format, ap); - len += rv; if ( len > BUFLEN-1 ) len = BUFLEN-1; - buf[len] = '\n'; + buf[len++] = '\n'; - write(fd, buf, len+1); + fd = __syslog_fd; + if ( fd == -1 ) + fd = 2; /* Failed to open log, write to stderr */ + + write(fd, buf, len); } void syslog(int prio, const char *format, ...) diff --git a/klibc/klibc/tests/fcntl.c b/klibc/klibc/tests/fcntl.c new file mode 100644 index 0000000000..f504ad90f7 --- /dev/null +++ b/klibc/klibc/tests/fcntl.c @@ -0,0 +1,53 @@ +/* + * Simple test of fcntl + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int fd = open(argv[0], O_RDONLY); + struct flock l; + long flags; + + (void)argc; + + if ( fd < 0 ) { + perror("open"); + exit(1); + } + + /* Get the flags on this FD */ + + if ( (flags = fcntl(fd, F_GETFL)) == -1 ) { + perror("F_GETFL"); + exit(1); + } + + if ( flags != (O_RDONLY|O_LARGEFILE) ) + fprintf(stderr, "flags = %#lx\n", flags); + + /* Set a lock on this FD */ + memset(&l, 0, sizeof l); + l.l_type = F_RDLCK; + l.l_whence = SEEK_SET; + l.l_start = 123; + l.l_len = 456; + + if ( fcntl(fd, F_SETLK, &l) == -1 ) { + perror("F_SETLK"); + exit(1); + } + + /* Eventually, fork and try to conflict with this lock... */ + + return 0; +} + + + diff --git a/klibc/klibc/tests/getpagesize.c b/klibc/klibc/tests/getpagesize.c new file mode 100644 index 0000000000..bda37e1f6b --- /dev/null +++ b/klibc/klibc/tests/getpagesize.c @@ -0,0 +1,11 @@ +#include +#include + +int main(void) +{ + printf("getpagesize() = %d\n" + "__getpageshift() = %d\n", + getpagesize(), __getpageshift()); + + return 0; +} diff --git a/klibc/klibc/tests/malloctest2.c b/klibc/klibc/tests/malloctest2.c new file mode 100644 index 0000000000..b392046929 --- /dev/null +++ b/klibc/klibc/tests/malloctest2.c @@ -0,0 +1,60 @@ +#include +#include +#include + +#define NCYCLES 32768 +#define NSLOTS 4096 + +struct slot { + char *ptr; + size_t size; +}; + +struct slot s[NSLOTS]; + +int main(void) +{ + size_t sp, sq; + char *p, *ep, *q, *eq; + int r, i, j; + int ok; + int err = 0; + + for ( r = 0 ; r < NCYCLES ; r++ ) { + i = lrand48() % NSLOTS; + + if ( s[i].ptr ) { + free(s[i].ptr); + printf("Freed %8zu bytes at %p\n", s[i].size, s[i].ptr); + s[i].ptr = NULL; + s[i].size = 0; + } else { + sp = lrand48(); /* 32-bit random number */ + sp >>= 12+(lrand48() % 20); + + s[i].size = sp; + s[i].ptr = p = malloc(sp); + ep = p+sp; + ok = 1; + for ( j = 0 ; j < NSLOTS ; j++ ) { + q = s[j].ptr; + if ( i != j && q ) { + sq = s[j].size; + eq = q+sq; + + if ( (p < q && ep > q) || (p >= q && p < eq) ) { + ok = 0; + err = 1; + break; + } + } + } + printf("Allocated %8zu bytes at %p, ok = %d\n", sp, p, ok); + + if ( p ) + memset(p, 0xee, sp); /* Poison this memory */ + } + } + return err; +} + diff --git a/klibc/klibc/tests/microhello.c b/klibc/klibc/tests/microhello.c index e57cd05a50..f0f5a40379 100644 --- a/klibc/klibc/tests/microhello.c +++ b/klibc/klibc/tests/microhello.c @@ -3,7 +3,7 @@ int main(void) { - const char hello[] = "Hello, World!\n"; + static const char hello[] = "Hello, World!\n"; _fwrite(hello, sizeof hello-1, stdout); return 0; } diff --git a/klibc/klibc/tests/minips.c b/klibc/klibc/tests/minips.c deleted file mode 100644 index 20898270f4..0000000000 --- a/klibc/klibc/tests/minips.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Copyright 1998 by Albert Cahalan; all rights reserved. - * This file may be used subject to the terms and conditions of the - * GNU Library General Public License Version 2, or any later version - * at your option, as published by the Free Software Foundation. - * 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 Library General Public License for more details. - */ - -/* This is a minimal /bin/ps, designed to be smaller than the old ps - * while still supporting some of the more important features of the - * new ps. (for total size, note that this ps does not need libproc) - * It is suitable for Linux-on-a-floppy systems only. - * - * Maintainers: do not compile or install for normal systems. - * Anyone needing this will want to tweak their compiler anyway. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* HZ */ -#include /* PAGE_SIZE */ - -static int P_euid; -static int P_pid; -static char P_cmd[16]; -static char P_state; -static int P_ppid, P_pgrp, P_session, P_tty, P_tpgid; -static unsigned long P_flags, P_min_flt, P_cmin_flt, P_maj_flt, P_cmaj_flt, P_utime, P_stime; -static long P_cutime, P_cstime, P_priority, P_nice, P_timeout, P_it_real_value; -static unsigned long P_start_time, P_vsize; -static long P_rss; -static unsigned long P_rss_rlim, P_start_code, P_end_code, P_start_stack, P_kstk_esp, P_kstk_eip; -static unsigned P_signal, P_blocked, P_sigignore, P_sigcatch; -static unsigned long P_wchan, P_nswap, P_cnswap; - - -#if 0 -static int screen_cols = 80; -static int w_count; -#endif - -static int want_one_pid; -static const char *want_one_command; -static int select_notty; -static int select_all; - -static int ps_format; -static int old_h_option; - -/* we only pretend to support this */ -static int show_args; /* implicit with -f and all BSD options */ -static int bsd_c_option; /* this option overrides the above */ - -static int ps_argc; /* global argc */ -static char **ps_argv; /* global argv */ -static int thisarg; /* index into ps_argv */ -static char *flagptr; /* current location in ps_argv[thisarg] */ - - -#ifndef PAGE_SIZE -#warning PAGE_SIZE not defined, assuming it is 4096 -#define PAGE_SIZE 4096 -#endif - -#ifndef HZ -#warning HZ not defined, assuming it is 100 -#define HZ 100 -#endif - - - -static void usage(void){ - fprintf(stderr, - "-C select by command name (minimal ps only accepts one)\n" - "-p select by process ID (minimal ps only accepts one)\n" - "-e all processes (same as ax)\n" - "a all processes w/ tty, including other users\n" - "x processes w/o controlling ttys\n" - "-f full format\n" - "-j,j job control format\n" - "v virtual memory format\n" - "-l,l long format\n" - "u user-oriented format\n" - "-o user-defined format (limited support, only \"ps -o pid=\")\n" - "h no header\n" -/* - "-A all processes (same as ax)\n" - "c true command name\n" - "-w,w wide output\n" -*/ - ); - exit(1); -} - -/* - * Return the next argument, or call the usage function. - * This handles both: -oFOO -o FOO - */ -static const char *get_opt_arg(void){ - const char *ret; - ret = flagptr+1; /* assume argument is part of ps_argv[thisarg] */ - if(*ret) return ret; - if(++thisarg >= ps_argc) usage(); /* there is nothing left */ - /* argument is the new ps_argv[thisarg] */ - ret = ps_argv[thisarg]; - if(!ret || !*ret) usage(); - return ret; -} - - -/* return the PID, or 0 if nothing good */ -static void parse_pid(const char *str){ - char *endp; - int num; - if(!str) goto bad; - num = strtol(str, &endp, 0); - if(*endp != '\0') goto bad; - if(num<1) goto bad; - if(want_one_pid) goto bad; - want_one_pid = num; - return; -bad: - usage(); -} - -/***************** parse SysV options, including Unix98 *****************/ -static void parse_sysv_option(void){ - do{ - switch(*flagptr){ - /**** selection ****/ - case 'C': /* end */ - if(want_one_command) usage(); - want_one_command = get_opt_arg(); - return; /* can't have any more options */ - case 'p': /* end */ - parse_pid(get_opt_arg()); - return; /* can't have any more options */ - case 'A': - case 'e': - select_all++; - select_notty++; -case 'w': /* here for now, since the real one is not used */ - break; - /**** output format ****/ - case 'f': - show_args = 1; - /* FALL THROUGH */ - case 'j': - case 'l': - if(ps_format) usage(); - ps_format = *flagptr; - break; - case 'o': /* end */ - /* We only support a limited form: "ps -o pid=" (yes, just "pid=") */ - if(strcmp(get_opt_arg(),"pid=")) usage(); - if(ps_format) usage(); - ps_format = 'o'; - old_h_option++; - return; /* can't have any more options */ - /**** other stuff ****/ -#if 0 - case 'w': - w_count++; - break; -#endif - default: - usage(); - } /* switch */ - }while(*++flagptr); -} - -/************************* parse BSD options **********************/ -static void parse_bsd_option(void){ - do{ - switch(*flagptr){ - /**** selection ****/ - case 'a': - select_all++; - break; - case 'x': - select_notty++; - break; - case 'p': /* end */ - parse_pid(get_opt_arg()); - return; /* can't have any more options */ - /**** output format ****/ - case 'j': - case 'l': - case 'u': - case 'v': - if(ps_format) usage(); - ps_format = 0x80 | *flagptr; /* use 0x80 to tell BSD from SysV */ - break; - /**** other stuff ****/ - case 'c': - bsd_c_option++; -#if 0 - break; -#endif - case 'w': -#if 0 - w_count++; -#endif - break; - case 'h': - old_h_option++; - break; - default: - usage(); - } /* switch */ - }while(*++flagptr); -} - -#if 0 -/* not used yet */ -static void choose_dimensions(void){ - struct winsize ws; - char *columns; - /* screen_cols is 80 by default */ - if(ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col>30) screen_cols = ws.ws_col; - columns = getenv("COLUMNS"); - if(columns && *columns){ - long t; - char *endptr; - t = strtol(columns, &endptr, 0); - if(!*endptr && (t>30) && (t<(long)999999999)) screen_cols = (int)t; - } - if(w_count && (screen_cols<132)) screen_cols=132; - if(w_count>1) screen_cols=999999999; -} -#endif - -static void arg_parse(int argc, char *argv[]){ - int sel = 0; /* to verify option sanity */ - ps_argc = argc; - ps_argv = argv; - thisarg = 0; - /**** iterate over the args ****/ - while(++thisarg < ps_argc){ - flagptr = ps_argv[thisarg]; - switch(*flagptr){ - case '0' ... '9': - show_args = 1; - parse_pid(flagptr); - break; - case '-': - flagptr++; - parse_sysv_option(); - break; - default: - show_args = 1; - parse_bsd_option(); - break; - } - } - /**** sanity check and clean-up ****/ - if(want_one_pid) sel++; - if(want_one_command) sel++; - if(select_notty || select_all) sel++; - if(sel>1 || select_notty>1 || select_all>1 || bsd_c_option>1 || old_h_option>1) usage(); - if(bsd_c_option) show_args = 0; -} - -/* return 1 if it works, or 0 for failure */ -static int stat2proc(int pid) { - char buf[800]; /* about 40 fields, 64-bit decimal is about 20 chars */ - int num; - int fd; - char* tmp; - struct stat sb; /* stat() used to get EUID */ - snprintf(buf, 32, "/proc/%d/stat", pid); - if ( (fd = open(buf, O_RDONLY, 0) ) == -1 ) return 0; - num = read(fd, buf, sizeof buf - 1); - fstat(fd, &sb); - P_euid = sb.st_uid; - close(fd); - if(num<80) return 0; - buf[num] = '\0'; - tmp = strrchr(buf, ')'); /* split into "PID (cmd" and "" */ - *tmp = '\0'; /* replace trailing ')' with NUL */ - /* parse these two strings separately, skipping the leading "(". */ - memset(P_cmd, 0, sizeof P_cmd); /* clear */ - sscanf(buf, "%d (%15c", &P_pid, P_cmd); /* comm[16] in kernel */ - num = sscanf(tmp + 2, /* skip space after ')' too */ - "%c " - "%d %d %d %d %d " - "%lu %lu %lu %lu %lu %lu %lu " - "%ld %ld %ld %ld %ld %ld " - "%lu %lu " - "%ld " - "%lu %lu %lu %lu %lu %lu " - "%u %u %u %u " /* no use for RT signals */ - "%lu %lu %lu", - &P_state, - &P_ppid, &P_pgrp, &P_session, &P_tty, &P_tpgid, - &P_flags, &P_min_flt, &P_cmin_flt, &P_maj_flt, &P_cmaj_flt, &P_utime, &P_stime, - &P_cutime, &P_cstime, &P_priority, &P_nice, &P_timeout, &P_it_real_value, - &P_start_time, &P_vsize, - &P_rss, - &P_rss_rlim, &P_start_code, &P_end_code, &P_start_stack, &P_kstk_esp, &P_kstk_eip, - &P_signal, &P_blocked, &P_sigignore, &P_sigcatch, - &P_wchan, &P_nswap, &P_cnswap - ); -/* fprintf(stderr, "stat2proc converted %d fields.\n",num); */ - P_vsize /= 1024; - P_rss *= (PAGE_SIZE/1024); - if(num < 30) return 0; - if(P_pid != pid) return 0; - return 1; -} - -static const char *do_time(unsigned long t){ - int hh,mm,ss; - static char buf[32]; - int cnt = 0; - t /= HZ; - ss = t%60; - t /= 60; - mm = t%60; - t /= 60; - hh = t%24; - t /= 24; - if(t) cnt = snprintf(buf, sizeof buf, "%d-", (int)t); - snprintf(cnt + buf, sizeof(buf)-cnt, "%02d:%02d:%02d", hh, mm, ss); - return buf; -} - -static void print_proc(void){ - char tty[16]; - snprintf(tty, sizeof tty, "%3d,%-3d", (P_tty>>8)&0xff, P_tty&0xff); - switch(ps_format){ - case 0: - printf("%5d %s %s", P_pid, tty, do_time(P_utime+P_stime)); - break; - case 'o': - printf("%d\n", P_pid); - return; /* don't want the command */ - case 'l': - printf( - "%03x %c %5d %5d %5d - %3d %3d - " - "%5ld %06x %s %s", - (unsigned)P_flags&0x777, P_state, P_euid, P_pid, P_ppid, - (int)P_priority, (int)P_nice, P_vsize/(PAGE_SIZE/1024), - (unsigned)(P_wchan&0xffffff), tty, do_time(P_utime+P_stime) - ); - break; - case 'f': - printf( - "%5d %5d %5d - - %s %s", - P_euid, P_pid, P_ppid, tty, do_time(P_utime+P_stime) - ); - break; - case 'j': - printf( - "%5d %5d %5d %s %s", - P_pid, P_pgrp, P_session, tty, do_time(P_utime+P_stime) - ); - break; - case 'u'|0x80: - printf( - "%5d %5d - - %5ld %5ld %s %c - %s", - P_euid, P_pid, P_vsize, P_rss, tty, P_state, - do_time(P_utime+P_stime) - ); - break; - case 'v'|0x80: - printf( - "%5d %s %c %s %6d - - %5d -", - P_pid, tty, P_state, do_time(P_utime+P_stime), (int)P_maj_flt, - (int)P_rss - ); - break; - case 'j'|0x80: - printf( - "%5d %5d %5d %5d %s %5d %c %5d %s", - P_ppid, P_pid, P_pgrp, P_session, tty, P_tpgid, P_state, P_euid, do_time(P_utime+P_stime) - ); - break; - case 'l'|0x80: - printf( - "%03x %5d %5d %5d %3d %3d " - "%5ld %4ld %06x %c %s %s", - (unsigned)P_flags&0x777, P_euid, P_pid, P_ppid, (int)P_priority, (int)P_nice, - P_vsize, P_rss, (unsigned)(P_wchan&0xffffff), P_state, tty, do_time(P_utime+P_stime) - ); - break; - default: - break; - } - if(show_args) printf(" [%s]\n", P_cmd); - else printf(" %s\n", P_cmd); -} - - -int main(int argc, char *argv[]){ - arg_parse(argc, argv); -#if 0 - choose_dimensions(); -#endif - if(!old_h_option){ - const char *head; - switch(ps_format){ - default: /* can't happen */ - case 0: head = " PID TTY TIME CMD"; break; - case 'l': head = " F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD"; break; - case 'f': head = " UID PID PPID C STIME TTY TIME CMD"; break; - case 'j': head = " PID PGID SID TTY TIME CMD"; break; - case 'u'|0x80: head = " UID PID %CPU %MEM VSZ RSS TTY S START TIME COMMAND"; break; - case 'v'|0x80: head = " PID TTY S TIME MAJFL TRS DRS RSS %MEM COMMAND"; break; - case 'j'|0x80: head = " PPID PID PGID SID TTY TPGID S UID TIME COMMAND"; break; - case 'l'|0x80: head = " F UID PID PPID PRI NI VSZ RSS WCHAN S TTY TIME COMMAND"; break; - } - printf("%s\n",head); - } - if(want_one_pid){ - if(stat2proc(want_one_pid)) print_proc(); - else exit(1); - }else{ - struct dirent *ent; /* dirent handle */ - DIR *dir; - int ouruid; - int found_a_proc; - found_a_proc = 0; - ouruid = getuid(); - dir = opendir("/proc"); - while(( ent = readdir(dir) )){ - if(*ent->d_name<'0' || *ent->d_name>'9') continue; - if(!stat2proc(atoi(ent->d_name))) continue; - if(want_one_command){ - if(strcmp(want_one_command,P_cmd)) continue; - }else{ - if(!select_notty && P_tty==-1) continue; - if(!select_all && P_euid!=ouruid) continue; - } - found_a_proc++; - print_proc(); - } - closedir(dir); - exit(!found_a_proc); - } - return 0; -} diff --git a/klibc/klibc/tests/mmaptest.c b/klibc/klibc/tests/mmaptest.c new file mode 100644 index 0000000000..a654affb83 --- /dev/null +++ b/klibc/klibc/tests/mmaptest.c @@ -0,0 +1,28 @@ +/* + * mmaptest.c + * + * Test some simple cases of mmap() + */ + +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + void *foo; + + (void)argc; (void)argv; + + /* Important case, this is how we get memory for malloc() */ + errno = 0; + foo = mmap(0, 65536, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); + + printf("mmap() returned %p, errno = %d\n", foo, errno); + + return 0; +} diff --git a/klibc/klibc/tests/opentest.c b/klibc/klibc/tests/opentest.c new file mode 100644 index 0000000000..5a54d2fce2 --- /dev/null +++ b/klibc/klibc/tests/opentest.c @@ -0,0 +1,17 @@ +#include + +int main(void) +{ + char buffer[1024]; + FILE *f; + + f = fopen("/etc/passwd", "r"); + fgets(buffer, 1024, f); + fclose(f); + + printf("Line 1 = %s", buffer); + + return 0; +} + + diff --git a/klibc/klibc/tests/stat.c b/klibc/klibc/tests/stat.c new file mode 100644 index 0000000000..74b0bddf44 --- /dev/null +++ b/klibc/klibc/tests/stat.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include + +static void do_stat(const char *path) +{ + struct stat st; + + if ( stat(path, &st) ) { + perror(path); + exit(1); + } + + printf("Path = %s\n" + " st_dev = %#jx (%u,%u)\n" + " st_ino = %ju\n" + " st_mode = %#jo\n" + " st_nlink = %ju\n" + " st_uid = %ju\n" + " st_gid = %ju\n" + " st_rdev = %#jx (%u,%u)\n" + " st_size = %ju\n" + " st_blksize = %ju\n" + " st_blocks = %ju\n", + path, + (uintmax_t)st.st_dev, major(st.st_dev), minor(st.st_dev), + (uintmax_t)st.st_ino, + (uintmax_t)st.st_mode, + (uintmax_t)st.st_nlink, + (uintmax_t)st.st_uid, + (uintmax_t)st.st_gid, + (uintmax_t)st.st_rdev, major(st.st_rdev), minor(st.st_rdev), + (uintmax_t)st.st_size, + (uintmax_t)st.st_blksize, + (uintmax_t)st.st_blocks); + +#ifdef _STATBUF_ST_NSEC + printf(" st_atim = %jd.%09u\n" + " st.mtim = %jd.%09u\n" + " st.ctim = %jd.%09u\n", + (uintmax_t)st.st_atim.tv_sec, (unsigned int)st.st_atim.tv_nsec, + (uintmax_t)st.st_mtim.tv_sec, (unsigned int)st.st_mtim.tv_nsec, + (uintmax_t)st.st_ctim.tv_sec, (unsigned int)st.st_ctim.tv_nsec); +#else + printf(" st_atime = %jd\n" + " st.mtime = %jd\n" + " st.ctime = %jd\n", + (uintmax_t)st.st_atime, + (uintmax_t)st.st_mtime, + (uintmax_t)st.st_ctime); +#endif +} + +int main(int argc, char *argv[]) +{ + int i; + + for ( i = 1 ; i < argc ; i++ ) + do_stat(argv[i]); + + return 0; +} diff --git a/klibc/klibc/tests/statfs.c b/klibc/klibc/tests/statfs.c new file mode 100644 index 0000000000..9b7a26d916 --- /dev/null +++ b/klibc/klibc/tests/statfs.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include + +static void do_statfs(const char *path) +{ + struct statfs sfs; + + if ( statfs(path, &sfs) ) { + perror(path); + exit(1); + } + + printf("Path = %s\n" + " f_type = %#jx\n" + " f_bsize = %jd\n" + " f_blocks = %jd\n" + " f_bfree = %jd\n" + " f_bavail = %jd\n" + " f_files = %jd\n" + " f_ffree = %jd\n" + " f_namelen = %jd\n", + path, + (uintmax_t)sfs.f_type, + (intmax_t)sfs.f_bsize, + (intmax_t)sfs.f_blocks, + (intmax_t)sfs.f_bfree, + (intmax_t)sfs.f_bavail, + (intmax_t)sfs.f_files, + (intmax_t)sfs.f_ffree, + (intmax_t)sfs.f_namelen); +} + +int main(int argc, char *argv[]) +{ + int i; + + for ( i = 1 ; i < argc ; i++ ) + do_statfs(argv[i]); + + return 0; +} diff --git a/klibc/klibc/tests/strtoimax.c b/klibc/klibc/tests/strtoimax.c new file mode 100644 index 0000000000..5af0d7912b --- /dev/null +++ b/klibc/klibc/tests/strtoimax.c @@ -0,0 +1,24 @@ +/* + * strtoimaxtest.c + */ + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int i; + char *ep; + intmax_t iv; + + for ( i = 1 ; i < argc ; i++ ) { + iv = strtoimax(argv[i], &ep, 0); + printf("strtoimax(\"%s\") = %jd\n", argv[i], iv); + if ( *ep ) + printf(" ep = \"%s\"\n", ep); + } + + return 0; +} + diff --git a/klibc/klibc/tests/strtotime.c b/klibc/klibc/tests/strtotime.c new file mode 100644 index 0000000000..815d40da99 --- /dev/null +++ b/klibc/klibc/tests/strtotime.c @@ -0,0 +1,27 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + struct timeval tv; + struct timespec ts; + int i; + const char *rv, *rs; + + for ( i = 1 ; i < argc ; i++ ) { + rs = strtotimespec(argv[i], &ts); + rv = strtotimeval(argv[i], &tv); + printf("String: \"%s\"\n" + "Timespec: %ld.%09ld\n" + "Residual: \"%s\"\n" + "Timeval: %ld.%06ld\n" + "Residual: \"%s\"\n", + argv[i], + (long)ts.tv_sec, (long)ts.tv_nsec, rs, + (long)tv.tv_sec, (long)tv.tv_usec, rv); + } + + return 0; +} + + diff --git a/klibc/klibc/time.c b/klibc/klibc/time.c index 8f6e89738d..92f82ccee0 100644 --- a/klibc/klibc/time.c +++ b/klibc/klibc/time.c @@ -6,11 +6,7 @@ #include #include -#ifdef __NR_time - -_syscall1(time_t,time,time_t *,t); - -#else +#ifndef __NR_time time_t time(time_t *t) { diff --git a/klibc/klibc/utime.c b/klibc/klibc/utime.c index a00b589629..2c8607756a 100644 --- a/klibc/klibc/utime.c +++ b/klibc/klibc/utime.c @@ -7,13 +7,7 @@ #include #include -#ifdef __NR_utime - -_syscall2(int,utime,const char *,filename,const struct utimbuf *,buf); - -#else - -static inline _syscall2(int,utimes,const char *,filename, const struct timeval *,tvp); +#ifndef __NR_utime int utime(const char *filename, const struct utimbuf *buf) { diff --git a/klibc/klibc/vasprintf.c b/klibc/klibc/vasprintf.c new file mode 100644 index 0000000000..5066dbbfaf --- /dev/null +++ b/klibc/klibc/vasprintf.c @@ -0,0 +1,25 @@ +/* + * vasprintf.c + */ + +#include +#include +#include + +int vasprintf(char **bufp, const char *format, va_list ap) +{ + va_list ap1; + int bytes; + char *p; + + va_copy(ap1, ap); + + bytes = vsnprintf(NULL, 0, format, ap1); + va_end(ap1); + + *bufp = p = malloc(bytes+1); + if ( !p ) + return -1; + + return vsnprintf(p, bytes, format, ap); +} diff --git a/klibc/version b/klibc/version index 31ba1bdaa5..30a3f4aab8 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.117 +0.181 From 60d1e263f0da2976938fa54efec88ab777a6b3c3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Oct 2004 18:51:53 -0700 Subject: [PATCH 0842/4284] [PATCH] oops forgot to add the new klibc/include directory --- klibc/include/alloca.h | 13 + klibc/include/arch/alpha/klibc/archsetjmp.h | 33 +++ klibc/include/arch/alpha/klibc/archsignal.h | 13 + klibc/include/arch/alpha/klibc/archstat.h | 26 ++ klibc/include/arch/alpha/klibc/archsys.h | 53 ++++ klibc/include/arch/alpha/machine/asm.h | 44 ++++ klibc/include/arch/arm/klibc/archsetjmp.h | 14 ++ klibc/include/arch/arm/klibc/archsignal.h | 13 + klibc/include/arch/arm/klibc/archstat.h | 45 ++++ klibc/include/arch/arm/klibc/archsys.h | 12 + klibc/include/arch/cris/klibc/archsetjmp.h | 24 ++ klibc/include/arch/cris/klibc/archsignal.h | 13 + klibc/include/arch/cris/klibc/archstat.h | 37 +++ klibc/include/arch/cris/klibc/archsys.h | 12 + klibc/include/arch/i386/klibc/archsetjmp.h | 19 ++ klibc/include/arch/i386/klibc/archsignal.h | 13 + klibc/include/arch/i386/klibc/archstat.h | 37 +++ klibc/include/arch/i386/klibc/archsys.h | 12 + klibc/include/arch/i386/klibc/diverr.h | 16 ++ klibc/include/arch/i386/sys/io.h | 126 ++++++++++ klibc/include/arch/i386/sys/vm86.h | 41 ++++ klibc/include/arch/ia64/klibc/archsetjmp.h | 17 ++ klibc/include/arch/ia64/klibc/archsignal.h | 31 +++ klibc/include/arch/ia64/klibc/archstat.h | 24 ++ klibc/include/arch/ia64/klibc/archsys.h | 218 +++++++++++++++++ klibc/include/arch/m68k/klibc/archsignal.h | 13 + klibc/include/arch/m68k/klibc/archstat.h | 37 +++ klibc/include/arch/m68k/klibc/archsys.h | 12 + klibc/include/arch/mips/klibc/archfcntl.h | 87 +++++++ klibc/include/arch/mips/klibc/archsetjmp.h | 39 +++ klibc/include/arch/mips/klibc/archsignal.h | 13 + klibc/include/arch/mips/klibc/archstat.h | 39 +++ klibc/include/arch/mips/klibc/archsys.h | 12 + klibc/include/arch/mips/machine/asm.h | 11 + klibc/include/arch/mips/sgidefs.h | 20 ++ klibc/include/arch/mips/spaces.h | 1 + klibc/include/arch/mips64/klibc/archsignal.h | 13 + klibc/include/arch/mips64/klibc/archstat.h | 33 +++ klibc/include/arch/mips64/klibc/archsys.h | 12 + klibc/include/arch/parisc/klibc/archsignal.h | 24 ++ klibc/include/arch/parisc/klibc/archstat.h | 27 +++ klibc/include/arch/parisc/klibc/archsys.h | 12 + klibc/include/arch/ppc/klibc/archsetjmp.h | 36 +++ klibc/include/arch/ppc/klibc/archsignal.h | 13 + klibc/include/arch/ppc/klibc/archstat.h | 28 +++ klibc/include/arch/ppc/klibc/archsys.h | 61 +++++ klibc/include/arch/ppc64/klibc/archsetjmp.h | 36 +++ klibc/include/arch/ppc64/klibc/archsignal.h | 13 + klibc/include/arch/ppc64/klibc/archstat.h | 25 ++ klibc/include/arch/ppc64/klibc/archsys.h | 52 ++++ klibc/include/arch/s390/klibc/archsetjmp.h | 15 ++ klibc/include/arch/s390/klibc/archsignal.h | 13 + klibc/include/arch/s390/klibc/archstat.h | 31 +++ klibc/include/arch/s390/klibc/archsys.h | 41 ++++ klibc/include/arch/s390x/klibc/archsetjmp.h | 15 ++ klibc/include/arch/s390x/klibc/archsignal.h | 13 + klibc/include/arch/s390x/klibc/archstat.h | 24 ++ klibc/include/arch/s390x/klibc/archsys.h | 41 ++++ klibc/include/arch/sh/klibc/archsetjmp.h | 22 ++ klibc/include/arch/sh/klibc/archsignal.h | 13 + klibc/include/arch/sh/klibc/archstat.h | 45 ++++ klibc/include/arch/sh/klibc/archsys.h | 12 + klibc/include/arch/sparc/klibc/archsetjmp.h | 16 ++ klibc/include/arch/sparc/klibc/archsignal.h | 13 + klibc/include/arch/sparc/klibc/archstat.h | 35 +++ klibc/include/arch/sparc/klibc/archsys.h | 10 + klibc/include/arch/sparc/machine/asm.h | 192 +++++++++++++++ klibc/include/arch/sparc/machine/frame.h | 138 +++++++++++ klibc/include/arch/sparc/machine/trap.h | 141 +++++++++++ klibc/include/arch/sparc64/klibc/archsetjmp.h | 16 ++ klibc/include/arch/sparc64/klibc/archsignal.h | 13 + klibc/include/arch/sparc64/klibc/archstat.h | 22 ++ klibc/include/arch/sparc64/klibc/archsys.h | 10 + klibc/include/arch/x86_64/klibc/archsetjmp.h | 21 ++ klibc/include/arch/x86_64/klibc/archsignal.h | 13 + klibc/include/arch/x86_64/klibc/archstat.h | 26 ++ klibc/include/arch/x86_64/klibc/archsys.h | 109 +++++++++ klibc/include/arch/x86_64/sys/io.h | 126 ++++++++++ klibc/include/arpa/inet.h | 24 ++ klibc/include/assert.h | 22 ++ klibc/include/bits32/bitsize/limits.h | 14 ++ klibc/include/bits32/bitsize/stddef.h | 18 ++ klibc/include/bits32/bitsize/stdint.h | 34 +++ klibc/include/bits32/bitsize/stdintconst.h | 18 ++ klibc/include/bits32/bitsize/stdintlimits.h | 22 ++ klibc/include/bits64/bitsize/limits.h | 14 ++ klibc/include/bits64/bitsize/stddef.h | 13 + klibc/include/bits64/bitsize/stdint.h | 36 +++ klibc/include/bits64/bitsize/stdintconst.h | 18 ++ klibc/include/bits64/bitsize/stdintlimits.h | 22 ++ klibc/include/ctype.h | 119 +++++++++ klibc/include/dirent.h | 32 +++ klibc/include/elf.h | 12 + klibc/include/endian.h | 42 ++++ klibc/include/errno.h | 8 + klibc/include/fcntl.h | 46 ++++ klibc/include/grp.h | 13 + klibc/include/inttypes.h | 226 ++++++++++++++++++ klibc/include/klibc/compiler.h | 119 +++++++++ klibc/include/klibc/diverr.h | 16 ++ klibc/include/klibc/extern.h | 14 ++ klibc/include/klibc/sysconfig.h | 34 +++ klibc/include/limits.h | 40 ++++ klibc/include/net/if.h | 1 + klibc/include/net/if_arp.h | 1 + klibc/include/net/if_ether.h | 1 + klibc/include/net/if_packet.h | 1 + klibc/include/netinet/in.h | 39 +++ klibc/include/netinet/in6.h | 10 + klibc/include/netinet/ip.h | 13 + klibc/include/netinet/tcp.h | 11 + klibc/include/netinet/udp.h | 19 ++ klibc/include/paths.h | 74 ++++++ klibc/include/poll.h | 16 ++ klibc/include/sched.h | 34 +++ klibc/include/setjmp.h | 43 ++++ klibc/include/signal.h | 81 +++++++ klibc/include/stdarg.h | 14 ++ klibc/include/stddef.h | 24 ++ klibc/include/stdint.h | 116 +++++++++ klibc/include/stdio.h | 123 ++++++++++ klibc/include/stdlib.h | 90 +++++++ klibc/include/string.h | 43 ++++ klibc/include/sys/dirent.h | 21 ++ klibc/include/sys/elf32.h | 115 +++++++++ klibc/include/sys/elf64.h | 115 +++++++++ klibc/include/sys/elfcommon.h | 188 +++++++++++++++ klibc/include/sys/fsuid.h | 14 ++ klibc/include/sys/ioctl.h | 14 ++ klibc/include/sys/klog.h | 24 ++ klibc/include/sys/mman.h | 25 ++ klibc/include/sys/mount.h | 55 +++++ klibc/include/sys/param.h | 11 + klibc/include/sys/reboot.h | 25 ++ klibc/include/sys/resource.h | 15 ++ klibc/include/sys/select.h | 13 + klibc/include/sys/socket.h | 50 ++++ klibc/include/sys/socketcalls.h | 28 +++ klibc/include/sys/stat.h | 31 +++ klibc/include/sys/statfs.h | 1 + klibc/include/sys/syscall.h | 17 ++ klibc/include/sys/sysinfo.h | 12 + klibc/include/sys/sysmacros.h | 31 +++ klibc/include/sys/time.h | 18 ++ klibc/include/sys/times.h | 14 ++ klibc/include/sys/types.h | 104 ++++++++ klibc/include/sys/uio.h | 15 ++ klibc/include/sys/un.h | 10 + klibc/include/sys/utime.h | 10 + klibc/include/sys/utsname.h | 23 ++ klibc/include/sys/vfs.h | 111 +++++++++ klibc/include/sys/wait.h | 28 +++ klibc/include/syslog.h | 55 +++++ klibc/include/termios.h | 86 +++++++ klibc/include/time.h | 18 ++ klibc/include/unistd.h | 140 +++++++++++ klibc/include/utime.h | 15 ++ 157 files changed, 5943 insertions(+) create mode 100644 klibc/include/alloca.h create mode 100644 klibc/include/arch/alpha/klibc/archsetjmp.h create mode 100644 klibc/include/arch/alpha/klibc/archsignal.h create mode 100644 klibc/include/arch/alpha/klibc/archstat.h create mode 100644 klibc/include/arch/alpha/klibc/archsys.h create mode 100644 klibc/include/arch/alpha/machine/asm.h create mode 100644 klibc/include/arch/arm/klibc/archsetjmp.h create mode 100644 klibc/include/arch/arm/klibc/archsignal.h create mode 100644 klibc/include/arch/arm/klibc/archstat.h create mode 100644 klibc/include/arch/arm/klibc/archsys.h create mode 100644 klibc/include/arch/cris/klibc/archsetjmp.h create mode 100644 klibc/include/arch/cris/klibc/archsignal.h create mode 100644 klibc/include/arch/cris/klibc/archstat.h create mode 100644 klibc/include/arch/cris/klibc/archsys.h create mode 100644 klibc/include/arch/i386/klibc/archsetjmp.h create mode 100644 klibc/include/arch/i386/klibc/archsignal.h create mode 100644 klibc/include/arch/i386/klibc/archstat.h create mode 100644 klibc/include/arch/i386/klibc/archsys.h create mode 100644 klibc/include/arch/i386/klibc/diverr.h create mode 100644 klibc/include/arch/i386/sys/io.h create mode 100644 klibc/include/arch/i386/sys/vm86.h create mode 100644 klibc/include/arch/ia64/klibc/archsetjmp.h create mode 100644 klibc/include/arch/ia64/klibc/archsignal.h create mode 100644 klibc/include/arch/ia64/klibc/archstat.h create mode 100644 klibc/include/arch/ia64/klibc/archsys.h create mode 100644 klibc/include/arch/m68k/klibc/archsignal.h create mode 100644 klibc/include/arch/m68k/klibc/archstat.h create mode 100644 klibc/include/arch/m68k/klibc/archsys.h create mode 100644 klibc/include/arch/mips/klibc/archfcntl.h create mode 100644 klibc/include/arch/mips/klibc/archsetjmp.h create mode 100644 klibc/include/arch/mips/klibc/archsignal.h create mode 100644 klibc/include/arch/mips/klibc/archstat.h create mode 100644 klibc/include/arch/mips/klibc/archsys.h create mode 100644 klibc/include/arch/mips/machine/asm.h create mode 100644 klibc/include/arch/mips/sgidefs.h create mode 100644 klibc/include/arch/mips/spaces.h create mode 100644 klibc/include/arch/mips64/klibc/archsignal.h create mode 100644 klibc/include/arch/mips64/klibc/archstat.h create mode 100644 klibc/include/arch/mips64/klibc/archsys.h create mode 100644 klibc/include/arch/parisc/klibc/archsignal.h create mode 100644 klibc/include/arch/parisc/klibc/archstat.h create mode 100644 klibc/include/arch/parisc/klibc/archsys.h create mode 100644 klibc/include/arch/ppc/klibc/archsetjmp.h create mode 100644 klibc/include/arch/ppc/klibc/archsignal.h create mode 100644 klibc/include/arch/ppc/klibc/archstat.h create mode 100644 klibc/include/arch/ppc/klibc/archsys.h create mode 100644 klibc/include/arch/ppc64/klibc/archsetjmp.h create mode 100644 klibc/include/arch/ppc64/klibc/archsignal.h create mode 100644 klibc/include/arch/ppc64/klibc/archstat.h create mode 100644 klibc/include/arch/ppc64/klibc/archsys.h create mode 100644 klibc/include/arch/s390/klibc/archsetjmp.h create mode 100644 klibc/include/arch/s390/klibc/archsignal.h create mode 100644 klibc/include/arch/s390/klibc/archstat.h create mode 100644 klibc/include/arch/s390/klibc/archsys.h create mode 100644 klibc/include/arch/s390x/klibc/archsetjmp.h create mode 100644 klibc/include/arch/s390x/klibc/archsignal.h create mode 100644 klibc/include/arch/s390x/klibc/archstat.h create mode 100644 klibc/include/arch/s390x/klibc/archsys.h create mode 100644 klibc/include/arch/sh/klibc/archsetjmp.h create mode 100644 klibc/include/arch/sh/klibc/archsignal.h create mode 100644 klibc/include/arch/sh/klibc/archstat.h create mode 100644 klibc/include/arch/sh/klibc/archsys.h create mode 100644 klibc/include/arch/sparc/klibc/archsetjmp.h create mode 100644 klibc/include/arch/sparc/klibc/archsignal.h create mode 100644 klibc/include/arch/sparc/klibc/archstat.h create mode 100644 klibc/include/arch/sparc/klibc/archsys.h create mode 100644 klibc/include/arch/sparc/machine/asm.h create mode 100644 klibc/include/arch/sparc/machine/frame.h create mode 100644 klibc/include/arch/sparc/machine/trap.h create mode 100644 klibc/include/arch/sparc64/klibc/archsetjmp.h create mode 100644 klibc/include/arch/sparc64/klibc/archsignal.h create mode 100644 klibc/include/arch/sparc64/klibc/archstat.h create mode 100644 klibc/include/arch/sparc64/klibc/archsys.h create mode 100644 klibc/include/arch/x86_64/klibc/archsetjmp.h create mode 100644 klibc/include/arch/x86_64/klibc/archsignal.h create mode 100644 klibc/include/arch/x86_64/klibc/archstat.h create mode 100644 klibc/include/arch/x86_64/klibc/archsys.h create mode 100644 klibc/include/arch/x86_64/sys/io.h create mode 100644 klibc/include/arpa/inet.h create mode 100644 klibc/include/assert.h create mode 100644 klibc/include/bits32/bitsize/limits.h create mode 100644 klibc/include/bits32/bitsize/stddef.h create mode 100644 klibc/include/bits32/bitsize/stdint.h create mode 100644 klibc/include/bits32/bitsize/stdintconst.h create mode 100644 klibc/include/bits32/bitsize/stdintlimits.h create mode 100644 klibc/include/bits64/bitsize/limits.h create mode 100644 klibc/include/bits64/bitsize/stddef.h create mode 100644 klibc/include/bits64/bitsize/stdint.h create mode 100644 klibc/include/bits64/bitsize/stdintconst.h create mode 100644 klibc/include/bits64/bitsize/stdintlimits.h create mode 100644 klibc/include/ctype.h create mode 100644 klibc/include/dirent.h create mode 100644 klibc/include/elf.h create mode 100644 klibc/include/endian.h create mode 100644 klibc/include/errno.h create mode 100644 klibc/include/fcntl.h create mode 100644 klibc/include/grp.h create mode 100644 klibc/include/inttypes.h create mode 100644 klibc/include/klibc/compiler.h create mode 100644 klibc/include/klibc/diverr.h create mode 100644 klibc/include/klibc/extern.h create mode 100644 klibc/include/klibc/sysconfig.h create mode 100644 klibc/include/limits.h create mode 100644 klibc/include/net/if.h create mode 100644 klibc/include/net/if_arp.h create mode 100644 klibc/include/net/if_ether.h create mode 100644 klibc/include/net/if_packet.h create mode 100644 klibc/include/netinet/in.h create mode 100644 klibc/include/netinet/in6.h create mode 100644 klibc/include/netinet/ip.h create mode 100644 klibc/include/netinet/tcp.h create mode 100644 klibc/include/netinet/udp.h create mode 100644 klibc/include/paths.h create mode 100644 klibc/include/poll.h create mode 100644 klibc/include/sched.h create mode 100644 klibc/include/setjmp.h create mode 100644 klibc/include/signal.h create mode 100644 klibc/include/stdarg.h create mode 100644 klibc/include/stddef.h create mode 100644 klibc/include/stdint.h create mode 100644 klibc/include/stdio.h create mode 100644 klibc/include/stdlib.h create mode 100644 klibc/include/string.h create mode 100644 klibc/include/sys/dirent.h create mode 100644 klibc/include/sys/elf32.h create mode 100644 klibc/include/sys/elf64.h create mode 100644 klibc/include/sys/elfcommon.h create mode 100644 klibc/include/sys/fsuid.h create mode 100644 klibc/include/sys/ioctl.h create mode 100644 klibc/include/sys/klog.h create mode 100644 klibc/include/sys/mman.h create mode 100644 klibc/include/sys/mount.h create mode 100644 klibc/include/sys/param.h create mode 100644 klibc/include/sys/reboot.h create mode 100644 klibc/include/sys/resource.h create mode 100644 klibc/include/sys/select.h create mode 100644 klibc/include/sys/socket.h create mode 100644 klibc/include/sys/socketcalls.h create mode 100644 klibc/include/sys/stat.h create mode 100644 klibc/include/sys/statfs.h create mode 100644 klibc/include/sys/syscall.h create mode 100644 klibc/include/sys/sysinfo.h create mode 100644 klibc/include/sys/sysmacros.h create mode 100644 klibc/include/sys/time.h create mode 100644 klibc/include/sys/times.h create mode 100644 klibc/include/sys/types.h create mode 100644 klibc/include/sys/uio.h create mode 100644 klibc/include/sys/un.h create mode 100644 klibc/include/sys/utime.h create mode 100644 klibc/include/sys/utsname.h create mode 100644 klibc/include/sys/vfs.h create mode 100644 klibc/include/sys/wait.h create mode 100644 klibc/include/syslog.h create mode 100644 klibc/include/termios.h create mode 100644 klibc/include/time.h create mode 100644 klibc/include/unistd.h create mode 100644 klibc/include/utime.h diff --git a/klibc/include/alloca.h b/klibc/include/alloca.h new file mode 100644 index 0000000000..41a4d94d44 --- /dev/null +++ b/klibc/include/alloca.h @@ -0,0 +1,13 @@ +/* + * alloca.h + * + * Just call the builtin alloca() function + */ + +#ifndef _ALLOCA_H +#define _ALLOCA_H + +#define alloca(size) __builtin_alloca(size) + +#endif /* _ALLOCA_H */ + diff --git a/klibc/include/arch/alpha/klibc/archsetjmp.h b/klibc/include/arch/alpha/klibc/archsetjmp.h new file mode 100644 index 0000000000..9dc570a6f5 --- /dev/null +++ b/klibc/include/arch/alpha/klibc/archsetjmp.h @@ -0,0 +1,33 @@ +/* + * arch/alpha/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __s0; + unsigned long __s1; + unsigned long __s2; + unsigned long __s3; + unsigned long __s4; + unsigned long __s5; + unsigned long __fp; + unsigned long __ra; + unsigned long __gp; + unsigned long __sp; + + unsigned long __f2; + unsigned long __f3; + unsigned long __f4; + unsigned long __f5; + unsigned long __f6; + unsigned long __f7; + unsigned long __f8; + unsigned long __f9; +}; + +/* Must be an array so it will decay to a pointer when a function is called */ +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/alpha/klibc/archsignal.h b/klibc/include/arch/alpha/klibc/archsignal.h new file mode 100644 index 0000000000..b870a05131 --- /dev/null +++ b/klibc/include/arch/alpha/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/alpha/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/alpha/klibc/archstat.h b/klibc/include/arch/alpha/klibc/archstat.h new file mode 100644 index 0000000000..23302d737d --- /dev/null +++ b/klibc/include/arch/alpha/klibc/archstat.h @@ -0,0 +1,26 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned long st_rdev; + long st_size; + unsigned long st_blocks; + + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int st_blksize; + unsigned int st_nlink; + unsigned int __pad0; + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + long __unused[3]; +}; + +#endif diff --git a/klibc/include/arch/alpha/klibc/archsys.h b/klibc/include/arch/alpha/klibc/archsys.h new file mode 100644 index 0000000000..16ed658987 --- /dev/null +++ b/klibc/include/arch/alpha/klibc/archsys.h @@ -0,0 +1,53 @@ +/* + * arch/alpha/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* Alpha has some bizarre Tru64-derived system calls which return two + different values in $0 and $20(!), respectively. The standard + macros can't deal with these; even the ones that give the right + return value have the wrong clobbers. */ + +#define _syscall0_dual0(type, name) \ +type name(void) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_19 __asm__("$19"); \ + register long _sc_20 __asm__("$20"); \ + \ + _sc_0 = __NR_##name; \ + __asm__("callsys" \ + : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ + : "0"(_sc_0) \ + : _syscall_clobbers); \ + _sc_ret = _sc_0, _sc_err = _sc_19; (void)(_sc_20); \ + } \ + _syscall_return(type); \ +} + +#define _syscall0_dual1(type, name) \ +type name(void) \ +{ \ + long _sc_ret, _sc_err; \ + { \ + register long _sc_0 __asm__("$0"); \ + register long _sc_19 __asm__("$19"); \ + register long _sc_20 __asm__("$20"); \ + \ + _sc_0 = __NR_##name; \ + __asm__("callsys" \ + : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ + : "0"(_sc_0) \ + : _syscall_clobbers); \ + _sc_ret = _sc_20, _sc_err = _sc_19; (void)(_sc_0); \ + } \ + _syscall_return(type); \ +} + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/alpha/machine/asm.h b/klibc/include/arch/alpha/machine/asm.h new file mode 100644 index 0000000000..e22db90412 --- /dev/null +++ b/klibc/include/arch/alpha/machine/asm.h @@ -0,0 +1,44 @@ +/* + * machine/asm.h + */ + +#ifndef _MACHINE_ASM_H +#define _MACHINE_ASM_H + +/* Standard aliases for Alpha register names */ + +#define v0 $0 +#define t0 $1 +#define t1 $2 +#define t2 $3 +#define t3 $4 +#define t4 $5 +#define t5 $6 +#define t6 $7 +#define t7 $8 +#define s0 $9 +#define s1 $10 +#define s2 $11 +#define s3 $12 +#define s4 $13 +#define s5 $14 +#define fp $15 +#define a0 $16 +#define a1 $17 +#define a2 $18 +#define a3 $19 +#define a4 $20 +#define a5 $21 +#define t8 $22 +#define t9 $23 +#define t10 $24 +#define t11 $25 +#define ra $26 +#define t12 $27 /* t12 and pv are both used for $27 */ +#define pv $27 /* t12 and pv are both used for $27 */ +#define at $28 +#define gp $29 +#define sp $30 +#define zero $31 + +#endif /* _MACHINE_ASM_H */ diff --git a/klibc/include/arch/arm/klibc/archsetjmp.h b/klibc/include/arch/arm/klibc/archsetjmp.h new file mode 100644 index 0000000000..c956b50a90 --- /dev/null +++ b/klibc/include/arch/arm/klibc/archsetjmp.h @@ -0,0 +1,14 @@ +/* + * arch/i386/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned int regs[10]; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/arm/klibc/archsignal.h b/klibc/include/arch/arm/klibc/archsignal.h new file mode 100644 index 0000000000..77685e62f0 --- /dev/null +++ b/klibc/include/arch/arm/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/arm/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/arm/klibc/archstat.h b/klibc/include/arch/arm/klibc/archstat.h new file mode 100644 index 0000000000..42b1409f67 --- /dev/null +++ b/klibc/include/arch/arm/klibc/archstat.h @@ -0,0 +1,45 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#include + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + * Note: The kernel zero's the padded region because glibc might read them + * in the hope that the kernel has stretched to using larger sizes. + */ +struct stat { + unsigned long long st_dev; + unsigned char __pad0[4]; + + unsigned long __st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned long __pad4; /* Future possible st_blocks hi bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ +#else /* Must be little */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* Future possible st_blocks hi bits */ +#endif + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long long st_ino; +}; + +#endif diff --git a/klibc/include/arch/arm/klibc/archsys.h b/klibc/include/arch/arm/klibc/archsys.h new file mode 100644 index 0000000000..dfdc70a6de --- /dev/null +++ b/klibc/include/arch/arm/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/cris/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/cris/klibc/archsetjmp.h b/klibc/include/arch/cris/klibc/archsetjmp.h new file mode 100644 index 0000000000..8d20800609 --- /dev/null +++ b/klibc/include/arch/cris/klibc/archsetjmp.h @@ -0,0 +1,24 @@ +/* + * arch/cris/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r0; + unsigned long __r1; + unsigned long __r2; + unsigned long __r3; + unsigned long __r4; + unsigned long __r5; + unsigned long __r6; + unsigned long __r7; + unsigned long __r8; + unsigned long __sp; + unsigned long __srp; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/cris/klibc/archsignal.h b/klibc/include/arch/cris/klibc/archsignal.h new file mode 100644 index 0000000000..73b2e196c9 --- /dev/null +++ b/klibc/include/arch/cris/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/cris/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/cris/klibc/archstat.h b/klibc/include/arch/cris/klibc/archstat.h new file mode 100644 index 0000000000..154820755f --- /dev/null +++ b/klibc/include/arch/cris/klibc/archstat.h @@ -0,0 +1,37 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat { + unsigned long long st_dev; + unsigned char __pad0[4]; + + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long long st_ino; +}; + +#endif diff --git a/klibc/include/arch/cris/klibc/archsys.h b/klibc/include/arch/cris/klibc/archsys.h new file mode 100644 index 0000000000..dfdc70a6de --- /dev/null +++ b/klibc/include/arch/cris/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/cris/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/i386/klibc/archsetjmp.h b/klibc/include/arch/i386/klibc/archsetjmp.h new file mode 100644 index 0000000000..db04314b8c --- /dev/null +++ b/klibc/include/arch/i386/klibc/archsetjmp.h @@ -0,0 +1,19 @@ +/* + * arch/i386/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned int __ebx; + unsigned int __esp; + unsigned int __ebp; + unsigned int __esi; + unsigned int __edi; + unsigned int __eip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/i386/klibc/archsignal.h b/klibc/include/arch/i386/klibc/archsignal.h new file mode 100644 index 0000000000..b092ba6d3a --- /dev/null +++ b/klibc/include/arch/i386/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/i386/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/i386/klibc/archstat.h b/klibc/include/arch/i386/klibc/archstat.h new file mode 100644 index 0000000000..154820755f --- /dev/null +++ b/klibc/include/arch/i386/klibc/archstat.h @@ -0,0 +1,37 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat { + unsigned long long st_dev; + unsigned char __pad0[4]; + + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long long st_ino; +}; + +#endif diff --git a/klibc/include/arch/i386/klibc/archsys.h b/klibc/include/arch/i386/klibc/archsys.h new file mode 100644 index 0000000000..dfdc70a6de --- /dev/null +++ b/klibc/include/arch/i386/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/cris/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/i386/klibc/diverr.h b/klibc/include/arch/i386/klibc/diverr.h new file mode 100644 index 0000000000..410aba06d3 --- /dev/null +++ b/klibc/include/arch/i386/klibc/diverr.h @@ -0,0 +1,16 @@ +/* + * arch/i386/include/klibc/diverr.h + */ + +#ifndef _KLIBC_DIVERR_H +#define _KLIBC_DIVERR_H + +#include + +static __inline__ void +__divide_error(void) +{ + asm volatile("divl %0" :: "rm" (0) : "eax", "edx"); +} + +#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/include/arch/i386/sys/io.h b/klibc/include/arch/i386/sys/io.h new file mode 100644 index 0000000000..b051464dfc --- /dev/null +++ b/klibc/include/arch/i386/sys/io.h @@ -0,0 +1,126 @@ +#ident "$Id: io.h,v 1.2 2004/01/25 07:49:39 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * sys/io.h for the i386 architecture + * + * Basic I/O macros + */ + +#ifndef _SYS_IO_H +#define _SYS_IO_H 1 + +/* I/O-related system calls */ + +int iopl(int); +int ioperm(unsigned long, unsigned long, int); + +/* Basic I/O macros */ + +static __inline__ void +outb(unsigned char __v, unsigned short __p) +{ + asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outw(unsigned short __v, unsigned short __p) +{ + asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outl(unsigned int __v, unsigned short __p) +{ + asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ unsigned char +inb(unsigned short __p) +{ + unsigned char __v; + asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); + return __v; +} + +static __inline__ unsigned short +inw(unsigned short __p) +{ + unsigned short __v; + asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); + return __v; +} + +static __inline__ unsigned int +inl(unsigned short __p) +{ + unsigned int __v; + asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); + return __v; +} + +/* String I/O macros */ + +static __inline__ void +outsb (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsw (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsl (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + + +static __inline__ void +insb (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insw (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insl (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +#endif /* _SYS_IO_H */ diff --git a/klibc/include/arch/i386/sys/vm86.h b/klibc/include/arch/i386/sys/vm86.h new file mode 100644 index 0000000000..d3272393dc --- /dev/null +++ b/klibc/include/arch/i386/sys/vm86.h @@ -0,0 +1,41 @@ +#ident "$Id: vm86.h,v 1.1 2004/01/25 01:34:28 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * sys/vm86.h for i386 + */ + +#ifndef _SYS_VM86_H +#define _SYS_VM86_H 1 + +#include + +/* Actual system call */ +int vm86(struct vm86_struct *); + +#endif diff --git a/klibc/include/arch/ia64/klibc/archsetjmp.h b/klibc/include/arch/ia64/klibc/archsetjmp.h new file mode 100644 index 0000000000..bd639c0b00 --- /dev/null +++ b/klibc/include/arch/ia64/klibc/archsetjmp.h @@ -0,0 +1,17 @@ +/* + * arch/ia64/include/klibc/archsetjmp.h + * + * Code borrowed from the FreeBSD kernel. + * + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +/* User code must not depend on the internal representation of jmp_buf. */ +#define _JBLEN 0x200 + +/* guaranteed 128-bit alignment! */ +typedef char jmp_buf[_JBLEN] __attribute__ ((aligned (16))); + +#endif diff --git a/klibc/include/arch/ia64/klibc/archsignal.h b/klibc/include/arch/ia64/klibc/archsignal.h new file mode 100644 index 0000000000..5b01f19bc2 --- /dev/null +++ b/klibc/include/arch/ia64/klibc/archsignal.h @@ -0,0 +1,31 @@ +/* + * arch/ia64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions. + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +#define _NSIG 64 +#define _NSIG_BPW 64 +#define _NSIG_WORDS (_NSIG / _NSIG_BPW) + +typedef struct { + unsigned long sig[_NSIG_WORDS]; +} sigset_t; + +struct sigaction { + union { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, struct siginfo *, void *); + } _u; + sigset_t sa_mask; + int sa_flags; +}; + +#define sa_handler _u._sa_handler +#define sa_sigaction _u._sa_sigaction + +#endif diff --git a/klibc/include/arch/ia64/klibc/archstat.h b/klibc/include/arch/ia64/klibc/archstat.h new file mode 100644 index 0000000000..9475c0b797 --- /dev/null +++ b/klibc/include/arch/ia64/klibc/archstat.h @@ -0,0 +1,24 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned long st_nlink; + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int __pad0; + unsigned long st_rdev; + unsigned long st_size; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned long st_blksize; + long st_blocks; + unsigned long __unused[3]; +}; + +#endif diff --git a/klibc/include/arch/ia64/klibc/archsys.h b/klibc/include/arch/ia64/klibc/archsys.h new file mode 100644 index 0000000000..4c795a43ca --- /dev/null +++ b/klibc/include/arch/ia64/klibc/archsys.h @@ -0,0 +1,218 @@ +/* + * arch/ia64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +#define __IA64_BREAK "break 0x100000;;\n\t" + +#define _syscall0(type,name) \ +type \ +name (void) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15) \ + : "2" (_r15) ASM_ARGS_0 \ + : "memory" ASM_CLOBBERS_0); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return (type)_retval; \ +} + +#define _syscall1(type,name,type1,arg1) \ +type \ +name (type1 arg1) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_1(arg1); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_1 \ + : "2" (_r15) ASM_ARGS_1 \ + : "memory" ASM_CLOBBERS_1); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return (type)_retval; \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type \ +name (type1 arg1, type2 arg2) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_2(arg1, arg2); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_2 \ + : "2" (_r15) ASM_ARGS_2 \ + : "memory" ASM_CLOBBERS_2); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return (type)_retval; \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_3(arg1, arg2, arg3); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_3 \ + : "2" (_r15) ASM_ARGS_3 \ + : "memory" ASM_CLOBBERS_3); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return (type)_retval; \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_4(arg1, arg2, arg3, arg4); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_4 \ + : "2" (_r15) ASM_ARGS_4 \ + : "memory" ASM_CLOBBERS_4); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return (type)_retval; \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_5(arg1, arg2, arg3, arg4, arg5); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_5 \ + : "2" (_r15) ASM_ARGS_5 \ + : "memory" ASM_CLOBBERS_5); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return (type)_retval; \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ +type \ +name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ +{ \ + register long _r8 asm ("r8"); \ + register long _r10 asm ("r10"); \ + register long _r15 asm ("r15") = __NR_##name; \ + long _retval; \ + LOAD_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6); \ + __asm __volatile (__IA64_BREAK \ + : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ + ASM_OUTARGS_6 \ + : "2" (_r15) ASM_ARGS_6 \ + : "memory" ASM_CLOBBERS_6); \ + _retval = _r8; \ + if (_r10 == -1) { \ + errno = (_retval); \ + _retval = -1; \ + } \ + return (type)_retval; \ +} + + +#define LOAD_ARGS_0() do { } while (0) +#define LOAD_ARGS_1(out0) \ + register long _out0 asm ("out0") = (long) (out0); \ + LOAD_ARGS_0 () +#define LOAD_ARGS_2(out0, out1) \ + register long _out1 asm ("out1") = (long) (out1); \ + LOAD_ARGS_1 (out0) +#define LOAD_ARGS_3(out0, out1, out2) \ + register long _out2 asm ("out2") = (long) (out2); \ + LOAD_ARGS_2 (out0, out1) +#define LOAD_ARGS_4(out0, out1, out2, out3) \ + register long _out3 asm ("out3") = (long) (out3); \ + LOAD_ARGS_3 (out0, out1, out2) +#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \ + register long _out4 asm ("out4") = (long) (out4); \ + LOAD_ARGS_4 (out0, out1, out2, out3) +#define LOAD_ARGS_6(out0, out1, out2, out3, out4, out5) \ + register long _out5 asm ("out5") = (long) (out5); \ + LOAD_ARGS_5 (out0, out1, out2, out3, out4) + +#define ASM_OUTARGS_1 "=r" (_out0) +#define ASM_OUTARGS_2 ASM_OUTARGS_1, "=r" (_out1) +#define ASM_OUTARGS_3 ASM_OUTARGS_2, "=r" (_out2) +#define ASM_OUTARGS_4 ASM_OUTARGS_3, "=r" (_out3) +#define ASM_OUTARGS_5 ASM_OUTARGS_4, "=r" (_out4) +#define ASM_OUTARGS_6 ASM_OUTARGS_5, "=r" (_out5) + +#define ASM_ARGS_0 +#define ASM_ARGS_1 ASM_ARGS_0, "3" (_out0) +#define ASM_ARGS_2 ASM_ARGS_1, "4" (_out1) +#define ASM_ARGS_3 ASM_ARGS_2, "5" (_out2) +#define ASM_ARGS_4 ASM_ARGS_3, "6" (_out3) +#define ASM_ARGS_5 ASM_ARGS_4, "7" (_out4) +#define ASM_ARGS_6 ASM_ARGS_5, "8" (_out5) + +#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0" +#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1" +#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2" +#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3" +#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4" +#define ASM_CLOBBERS_5 ASM_CLOBBERS_6, "out5" +#define ASM_CLOBBERS_6 , "out6", "out7", \ + /* Non-stacked integer registers, minus r8, r10, r15. */ \ + "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \ + "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \ + "r28", "r29", "r30", "r31", \ + /* Predicate registers. */ \ + "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \ + /* Non-rotating fp registers. */ \ + "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ + /* Branch registers. */ \ + "b6", "b7" + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/m68k/klibc/archsignal.h b/klibc/include/arch/m68k/klibc/archsignal.h new file mode 100644 index 0000000000..714527f6b0 --- /dev/null +++ b/klibc/include/arch/m68k/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/m68k/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/m68k/klibc/archstat.h b/klibc/include/arch/m68k/klibc/archstat.h new file mode 100644 index 0000000000..9c0a05da09 --- /dev/null +++ b/klibc/include/arch/m68k/klibc/archstat.h @@ -0,0 +1,37 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat { + unsigned long long st_dev; + unsigned char __pad1[2]; + + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[2]; + + long long st_size; + unsigned long st_blksize; + + unsigned long __pad4; /* future possible st_blocks high bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long long st_ino; +}; + +#endif diff --git a/klibc/include/arch/m68k/klibc/archsys.h b/klibc/include/arch/m68k/klibc/archsys.h new file mode 100644 index 0000000000..8f6bed8e94 --- /dev/null +++ b/klibc/include/arch/m68k/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/m68k/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/mips/klibc/archfcntl.h b/klibc/include/arch/mips/klibc/archfcntl.h new file mode 100644 index 0000000000..54462ea69f --- /dev/null +++ b/klibc/include/arch/mips/klibc/archfcntl.h @@ -0,0 +1,87 @@ +/* + * arch/mips/include/klibc/archfcntl.h + * + * On MIPS, isn't usable (compiling struct stat with + * the correct definitions doesn't "just work"), so we need to provide + * our own definitions. + */ + +#ifndef _KLIBC_ARCHFCNTL_H +#define _KLIBC_ARCHFCNTL_H + +#ifdef _ASM_FCNTL_H /* We were too late! */ +# error " included before " +#endif +#define _ASM_FCNTL_H /* Keep from getting included */ + +#define O_ACCMODE 0x0003 +#define O_RDONLY 0x0000 +#define O_WRONLY 0x0001 +#define O_RDWR 0x0002 +#define O_APPEND 0x0008 +#define O_SYNC 0x0010 +#define O_NONBLOCK 0x0080 +#define O_CREAT 0x0100 +#define O_TRUNC 0x0200 +#define O_EXCL 0x0400 +#define O_NOCTTY 0x0800 +#define FASYNC 0x1000 +#define O_LARGEFILE 0x2000 +#define O_DIRECT 0x8000 +#define O_DIRECTORY 0x10000 +#define O_NOFOLLOW 0x20000 +#define O_NOATIME 0x40000 + +#define O_NDELAY O_NONBLOCK + +#define F_DUPFD 0 +#define F_GETFD 1 +#define F_SETFD 2 +#define F_GETFL 3 +#define F_SETFL 4 +#define F_GETLK 14 +#define F_SETLK 6 +#define F_SETLKW 7 + +#define F_SETOWN 24 +#define F_GETOWN 23 +#define F_SETSIG 10 +#define F_GETSIG 11 + +#define F_GETLK64 33 +#define F_SETLK64 34 +#define F_SETLKW64 35 + +#define FD_CLOEXEC 1 + +#define F_RDLCK 0 +#define F_WRLCK 1 +#define F_UNLCK 2 + +#define F_EXLCK 4 +#define F_SHLCK 8 + +#define F_INPROGRESS 16 + +#define LOCK_SH 1 +#define LOCK_EX 2 +#define LOCK_NB 4 +#define LOCK_UN 8 + +#define LOCK_MAND 32 +#define LOCK_READ 64 +#define LOCK_WRITE 128 +#define LOCK_RW 192 + +typedef struct flock { + short l_type; + short l_whence; + loff_t l_start; + loff_t l_len; + pid_t l_pid; +} flock_t; + +#define F_LINUX_SPECIFIC_BASE 1024 + +#endif /* _KLIBC_ARCHFCNTL_H */ + diff --git a/klibc/include/arch/mips/klibc/archsetjmp.h b/klibc/include/arch/mips/klibc/archsetjmp.h new file mode 100644 index 0000000000..40e5be2736 --- /dev/null +++ b/klibc/include/arch/mips/klibc/archsetjmp.h @@ -0,0 +1,39 @@ +/* + * arch/mips/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __s0; + unsigned long __s1; + unsigned long __s2; + unsigned long __s3; + unsigned long __s4; + unsigned long __s5; + unsigned long __s6; + unsigned long __s7; + unsigned long __gp; + unsigned long __sp; + unsigned long __s8; + unsigned long __ra; + unsigned long __f20; + unsigned long __f21; + unsigned long __f22; + unsigned long __f23; + unsigned long __f24; + unsigned long __f25; + unsigned long __f26; + unsigned long __f27; + unsigned long __f28; + unsigned long __f29; + unsigned long __f30; + unsigned long __f31; + unsigned long __fcr31; + unsigned long __unused; +} __attribute__((aligned(8))); + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/mips/klibc/archsignal.h b/klibc/include/arch/mips/klibc/archsignal.h new file mode 100644 index 0000000000..3b72908636 --- /dev/null +++ b/klibc/include/arch/mips/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/mips/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/mips/klibc/archstat.h b/klibc/include/arch/mips/klibc/archstat.h new file mode 100644 index 0000000000..612bbfa85b --- /dev/null +++ b/klibc/include/arch/mips/klibc/archstat.h @@ -0,0 +1,39 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +/* + * This matches struct stat64 in glibc2.1, hence the absolutely insane + * amounts of padding around dev_t's. The memory layout is the same as of + * struct stat of the 64-bit kernel. + */ + +struct stat { + unsigned long st_dev; + unsigned long st_pad0[3]; /* Reserved for st_dev expansion */ + + unsigned long long st_ino; + + mode_t st_mode; + nlink_t st_nlink; + + uid_t st_uid; + gid_t st_gid; + + unsigned long st_rdev; + unsigned long st_pad1[3]; /* Reserved for st_rdev expansion */ + + long long st_size; + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long st_blksize; + unsigned long st_pad2; + + long long st_blocks; +}; + +#endif diff --git a/klibc/include/arch/mips/klibc/archsys.h b/klibc/include/arch/mips/klibc/archsys.h new file mode 100644 index 0000000000..f696cdfaa7 --- /dev/null +++ b/klibc/include/arch/mips/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/mips/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/mips/machine/asm.h b/klibc/include/arch/mips/machine/asm.h new file mode 100644 index 0000000000..e5239a6cef --- /dev/null +++ b/klibc/include/arch/mips/machine/asm.h @@ -0,0 +1,11 @@ +/* + * arch/mips/include/machine/asm.h + */ + +#ifndef _MACHINE_ASM_H +#define _MACHINE_ASM_H + +#include +#include + +#endif /* _MACHINE_ASM_H */ diff --git a/klibc/include/arch/mips/sgidefs.h b/klibc/include/arch/mips/sgidefs.h new file mode 100644 index 0000000000..eb103ace2c --- /dev/null +++ b/klibc/include/arch/mips/sgidefs.h @@ -0,0 +1,20 @@ +/* + * arch/mips/include/sgidefs.h + */ + +/* Some ABI constants */ + +#ifndef _SGIDEFS_H +#define _SGIDEFS_H + +#define _MIPS_ISA_MIPS1 1 +#define _MIPS_ISA_MIPS2 2 +#define _MIPS_ISA_MIPS3 3 +#define _MIPS_ISA_MIPS4 4 +#define _MIPS_ISA_MIPS5 5 + +#define _MIPS_SIM_ABI32 1 +#define _MIPS_SIM_NABI32 2 +#define _MIPS_SIM_ABI64 3 + +#endif /* _SGIDEFS_H */ diff --git a/klibc/include/arch/mips/spaces.h b/klibc/include/arch/mips/spaces.h new file mode 100644 index 0000000000..b5f530b753 --- /dev/null +++ b/klibc/include/arch/mips/spaces.h @@ -0,0 +1 @@ +/* Included by but not actually needed */ diff --git a/klibc/include/arch/mips64/klibc/archsignal.h b/klibc/include/arch/mips64/klibc/archsignal.h new file mode 100644 index 0000000000..56b0fd323e --- /dev/null +++ b/klibc/include/arch/mips64/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/mips64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/mips64/klibc/archstat.h b/klibc/include/arch/mips64/klibc/archstat.h new file mode 100644 index 0000000000..d237e3a3e8 --- /dev/null +++ b/klibc/include/arch/mips64/klibc/archstat.h @@ -0,0 +1,33 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned int st_dev; + unsigned int st_pad0[3]; /* Reserved for st_dev expansion */ + + unsigned long st_ino; + + mode_t st_mode; + nlink_t st_nlink; + + uid_t st_uid; + gid_t st_gid; + + unsigned int st_rdev; + unsigned int st_pad1[3]; /* Reserved for st_rdev expansion */ + + off_t st_size; + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned int st_blksize; + unsigned int st_pad2; + + unsigned long st_blocks; +}; + +#endif diff --git a/klibc/include/arch/mips64/klibc/archsys.h b/klibc/include/arch/mips64/klibc/archsys.h new file mode 100644 index 0000000000..81e5106e16 --- /dev/null +++ b/klibc/include/arch/mips64/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/mips64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/parisc/klibc/archsignal.h b/klibc/include/arch/parisc/klibc/archsignal.h new file mode 100644 index 0000000000..3190e8528e --- /dev/null +++ b/klibc/include/arch/parisc/klibc/archsignal.h @@ -0,0 +1,24 @@ +/* + * arch/parisc/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +#define _NSIG 64 +#define _NSIG_SZ (_NSIG / LONG_BIT) + +typedef struct { + unsigned long sig[_NSIG_SZ]; +} sigset_t; + +struct sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; +}; + +#endif diff --git a/klibc/include/arch/parisc/klibc/archstat.h b/klibc/include/arch/parisc/klibc/archstat.h new file mode 100644 index 0000000000..7d28f459ee --- /dev/null +++ b/klibc/include/arch/parisc/klibc/archstat.h @@ -0,0 +1,27 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned long long st_dev; + unsigned int __pad1; + + unsigned int __st_ino; /* Not actually filled in */ + unsigned int st_mode; + unsigned int st_nlink; + unsigned int st_uid; + unsigned int st_gid; + unsigned long long st_rdev; + unsigned int __pad2; + signed long long st_size; + signed int st_blksize; + + signed long long st_blocks; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned long long st_ino; +}; + +#endif diff --git a/klibc/include/arch/parisc/klibc/archsys.h b/klibc/include/arch/parisc/klibc/archsys.h new file mode 100644 index 0000000000..5013ba8794 --- /dev/null +++ b/klibc/include/arch/parisc/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/parisc/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/ppc/klibc/archsetjmp.h b/klibc/include/arch/ppc/klibc/archsetjmp.h new file mode 100644 index 0000000000..53e2fccc3b --- /dev/null +++ b/klibc/include/arch/ppc/klibc/archsetjmp.h @@ -0,0 +1,36 @@ +/* + * arch/ppc/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r2; + unsigned long __sp; + unsigned long __lr; + unsigned long __cr; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __r16; + unsigned long __r17; + unsigned long __r18; + unsigned long __r19; + unsigned long __r20; + unsigned long __r21; + unsigned long __r22; + unsigned long __r23; + unsigned long __r24; + unsigned long __r25; + unsigned long __r26; + unsigned long __r27; + unsigned long __r28; + unsigned long __r29; + unsigned long __r30; + unsigned long __r31; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/ppc/klibc/archsignal.h b/klibc/include/arch/ppc/klibc/archsignal.h new file mode 100644 index 0000000000..567a547ef9 --- /dev/null +++ b/klibc/include/arch/ppc/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/ppc/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/ppc/klibc/archstat.h b/klibc/include/arch/ppc/klibc/archstat.h new file mode 100644 index 0000000000..1d0487b47f --- /dev/null +++ b/klibc/include/arch/ppc/klibc/archstat.h @@ -0,0 +1,28 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1. + */ +struct stat { + unsigned long long st_dev; /* Device. */ + unsigned long long st_ino; /* File serial number. */ + unsigned int st_mode; /* File mode. */ + unsigned int st_nlink; /* Link count. */ + unsigned int st_uid; /* User ID of the file's owner. */ + unsigned int st_gid; /* Group ID of the file's group. */ + unsigned long long st_rdev; /* Device number, if device. */ + unsigned short int __pad2; + long long st_size; /* Size of file, in bytes. */ + long st_blksize; /* Optimal block size for I/O. */ + + long long st_blocks; /* Number 512-byte blocks allocated. */ + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ + unsigned long int __unused4; + unsigned long int __unused5; +}; + +#endif diff --git a/klibc/include/arch/ppc/klibc/archsys.h b/klibc/include/arch/ppc/klibc/archsys.h new file mode 100644 index 0000000000..17a28859e5 --- /dev/null +++ b/klibc/include/arch/ppc/klibc/archsys.h @@ -0,0 +1,61 @@ +/* + * arch/ppc/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* PowerPC seems to lack _syscall6() in its headers */ +/* This seems to work on both 32- and 64-bit ppc */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ + unsigned long __sc_ret, __sc_err; \ + { \ + register unsigned long __sc_0 __asm__ ("r0"); \ + register unsigned long __sc_3 __asm__ ("r3"); \ + register unsigned long __sc_4 __asm__ ("r4"); \ + register unsigned long __sc_5 __asm__ ("r5"); \ + register unsigned long __sc_6 __asm__ ("r6"); \ + register unsigned long __sc_7 __asm__ ("r7"); \ + register unsigned long __sc_8 __asm__ ("r8"); \ + \ + __sc_3 = (unsigned long) (arg1); \ + __sc_4 = (unsigned long) (arg2); \ + __sc_5 = (unsigned long) (arg3); \ + __sc_6 = (unsigned long) (arg4); \ + __sc_7 = (unsigned long) (arg5); \ + __sc_8 = (unsigned long) (arg6); \ + __sc_0 = __NR_##name; \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %1 " \ + : "+r" (__sc_3), \ + "+r" (__sc_0), \ + "+r" (__sc_4), \ + "+r" (__sc_5), \ + "+r" (__sc_6), \ + "+r" (__sc_7), \ + "+r" (__sc_8) \ + : : "cr0", "ctr", "memory", \ + "r9", "r10", "r11", "r12"); \ + __sc_ret = __sc_3; \ + __sc_err = __sc_0; \ + } \ + if (__sc_err & 0x10000000) \ + { \ + errno = (int)__sc_ret; \ + __sc_ret = -1; \ + } \ + return (type)__sc_ret; \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/ppc64/klibc/archsetjmp.h b/klibc/include/arch/ppc64/klibc/archsetjmp.h new file mode 100644 index 0000000000..006a2e27be --- /dev/null +++ b/klibc/include/arch/ppc64/klibc/archsetjmp.h @@ -0,0 +1,36 @@ +/* + * arch/ppc64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r2; + unsigned long __sp; + unsigned long __lr; + unsigned long __cr; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __r16; + unsigned long __r17; + unsigned long __r18; + unsigned long __r19; + unsigned long __r20; + unsigned long __r21; + unsigned long __r22; + unsigned long __r23; + unsigned long __r24; + unsigned long __r25; + unsigned long __r26; + unsigned long __r27; + unsigned long __r28; + unsigned long __r29; + unsigned long __r30; + unsigned long __r31; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/ppc64/klibc/archsignal.h b/klibc/include/arch/ppc64/klibc/archsignal.h new file mode 100644 index 0000000000..8452f6e4bc --- /dev/null +++ b/klibc/include/arch/ppc64/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/ppc64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/ppc64/klibc/archstat.h b/klibc/include/arch/ppc64/klibc/archstat.h new file mode 100644 index 0000000000..71f4748690 --- /dev/null +++ b/klibc/include/arch/ppc64/klibc/archstat.h @@ -0,0 +1,25 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned long st_dev; + ino_t st_ino; + nlink_t st_nlink; + mode_t st_mode; + uid_t st_uid; + gid_t st_gid; + unsigned long st_rdev; + off_t st_size; + unsigned long st_blksize; + unsigned long st_blocks; + struct timespec st_atim; /* Time of last access. */ + struct timespec st_mtim; /* Time of last modification. */ + struct timespec st_ctim; /* Time of last status change. */ + unsigned long __unused4; + unsigned long __unused5; + unsigned long __unused6; +}; + +#endif diff --git a/klibc/include/arch/ppc64/klibc/archsys.h b/klibc/include/arch/ppc64/klibc/archsys.h new file mode 100644 index 0000000000..4f81fee00d --- /dev/null +++ b/klibc/include/arch/ppc64/klibc/archsys.h @@ -0,0 +1,52 @@ +/* + * arch/ppc64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ + unsigned long __sc_ret, __sc_err; \ + { \ + register unsigned long __sc_0 __asm__ ("r0"); \ + register unsigned long __sc_3 __asm__ ("r3"); \ + register unsigned long __sc_4 __asm__ ("r4"); \ + register unsigned long __sc_5 __asm__ ("r5"); \ + register unsigned long __sc_6 __asm__ ("r6"); \ + register unsigned long __sc_7 __asm__ ("r7"); \ + register unsigned long __sc_8 __asm__ ("r8"); \ + \ + __sc_3 = (unsigned long) (arg1); \ + __sc_4 = (unsigned long) (arg2); \ + __sc_5 = (unsigned long) (arg3); \ + __sc_6 = (unsigned long) (arg4); \ + __sc_7 = (unsigned long) (arg5); \ + __sc_8 = (unsigned long) (arg6); \ + __sc_0 = __NR_##name; \ + __asm__ __volatile__ \ + ("sc \n\t" \ + "mfcr %1 " \ + : "=&r" (__sc_3), "=&r" (__sc_0) \ + : "0" (__sc_3), "1" (__sc_0), \ + "r" (__sc_4), \ + "r" (__sc_5), \ + "r" (__sc_6), \ + "r" (__sc_7), \ + "r" (__sc_8) \ + : __syscall_clobbers); \ + __sc_ret = __sc_3; \ + __sc_err = __sc_0; \ + } \ + __syscall_return (type); \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/s390/klibc/archsetjmp.h b/klibc/include/arch/s390/klibc/archsetjmp.h new file mode 100644 index 0000000000..11a641ed5a --- /dev/null +++ b/klibc/include/arch/s390/klibc/archsetjmp.h @@ -0,0 +1,15 @@ +/* + * arch/s390/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + uint32_t __gregs[10]; /* general registers r6-r15 */ + uint64_t __fpregs[2]; /* fp registers f4 and f6 */ +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/s390/klibc/archsignal.h b/klibc/include/arch/s390/klibc/archsignal.h new file mode 100644 index 0000000000..1f8de28b4b --- /dev/null +++ b/klibc/include/arch/s390/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/s390/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/s390/klibc/archstat.h b/klibc/include/arch/s390/klibc/archstat.h new file mode 100644 index 0000000000..866c3d4f4c --- /dev/null +++ b/klibc/include/arch/s390/klibc/archstat.h @@ -0,0 +1,31 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat { + unsigned long long st_dev; + unsigned int __pad1; +#define STAT64_HAS_BROKEN_ST_INO 1 + unsigned long __st_ino; + unsigned int st_mode; + unsigned int st_nlink; + unsigned long st_uid; + unsigned long st_gid; + unsigned long long st_rdev; + unsigned int __pad3; + long long st_size; + unsigned long st_blksize; + unsigned char __pad4[4]; + unsigned long __pad5; /* future possible st_blocks high bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned long long st_ino; +}; + +#endif diff --git a/klibc/include/arch/s390/klibc/archsys.h b/klibc/include/arch/s390/klibc/archsys.h new file mode 100644 index 0000000000..1cd0948f3c --- /dev/null +++ b/klibc/include/arch/s390/klibc/archsys.h @@ -0,0 +1,41 @@ +/* + * arch/s390/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* S/390 only has five syscall parameters, and uses a structure for + 6-argument syscalls. */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ + type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5, type6 arg6) { \ + unsigned long __arg[6] = { \ + (unsigned long) arg1, \ + (unsigned long) arg2, \ + (unsigned long) arg3, \ + (unsigned long) arg4, \ + (unsigned long) arg5, \ + (unsigned long) arg6 \ + }; \ + register void *__argp asm("2") = &__arg; \ + long __res; \ + __asm__ __volatile__ ( \ + " svc %b1\n" \ + " lr %0,2" \ + : "=d" (__res) \ + : "i" (__NR_##name), \ + "d" (__argp) \ + : _svc_clobber); \ + __syscall_return(type, __res); \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/s390x/klibc/archsetjmp.h b/klibc/include/arch/s390x/klibc/archsetjmp.h new file mode 100644 index 0000000000..dd3ed0d47c --- /dev/null +++ b/klibc/include/arch/s390x/klibc/archsetjmp.h @@ -0,0 +1,15 @@ +/* + * arch/s390x/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + uint64_t __gregs[10]; /* general registers r6-r15 */ + uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */ +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/s390x/klibc/archsignal.h b/klibc/include/arch/s390x/klibc/archsignal.h new file mode 100644 index 0000000000..08c9a0073a --- /dev/null +++ b/klibc/include/arch/s390x/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/s390x/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/s390x/klibc/archstat.h b/klibc/include/arch/s390x/klibc/archstat.h new file mode 100644 index 0000000000..0de73cb2b6 --- /dev/null +++ b/klibc/include/arch/s390x/klibc/archstat.h @@ -0,0 +1,24 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned long st_nlink; + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int __pad1; + unsigned long st_rdev; + unsigned long st_size; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + unsigned long st_blksize; + long st_blocks; + unsigned long __unused[3]; +}; + +#endif diff --git a/klibc/include/arch/s390x/klibc/archsys.h b/klibc/include/arch/s390x/klibc/archsys.h new file mode 100644 index 0000000000..15f7113bb4 --- /dev/null +++ b/klibc/include/arch/s390x/klibc/archsys.h @@ -0,0 +1,41 @@ +/* + * arch/s390x/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* S/390X only has five syscall parameters, and uses a structure for + 6-argument syscalls. */ + +#ifndef _syscall6 + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ + type4,arg4,type5,arg5,type6,arg6) \ +type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ + type5 arg5, type6 arg6) { \ + unsigned long __arg[6] = { \ + (unsigned long) arg1, \ + (unsigned long) arg2, \ + (unsigned long) arg3, \ + (unsigned long) arg4, \ + (unsigned long) arg5, \ + (unsigned long) arg6 \ + }; \ + register void *__argp asm("2") = &__arg; \ + long __res; \ + __asm__ __volatile__ ( \ + " svc %b1\n" \ + " lgr %0,2" \ + : "=d" (__res) \ + : "i" (__NR_##name), \ + "d" (__argp) \ + : _svc_clobber); \ + __syscall_return(type, __res); \ +} + +#endif /* _syscall6() missing */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/sh/klibc/archsetjmp.h b/klibc/include/arch/sh/klibc/archsetjmp.h new file mode 100644 index 0000000000..28dd932fbc --- /dev/null +++ b/klibc/include/arch/sh/klibc/archsetjmp.h @@ -0,0 +1,22 @@ +/* + * arch/sh/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long r14; + unsigned long r15; + unsigned long pr; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/sh/klibc/archsignal.h b/klibc/include/arch/sh/klibc/archsignal.h new file mode 100644 index 0000000000..6c4e5976ad --- /dev/null +++ b/klibc/include/arch/sh/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/sh/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/sh/klibc/archstat.h b/klibc/include/arch/sh/klibc/archstat.h new file mode 100644 index 0000000000..73caceb593 --- /dev/null +++ b/klibc/include/arch/sh/klibc/archstat.h @@ -0,0 +1,45 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#include + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat64 { + unsigned long long st_dev; + unsigned char __pad0[4]; + + unsigned long st_ino; + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + +#if __BYTE_ORDER == __BIG_ENDIAN + unsigned long __pad4; /* Future possible st_blocks hi bits */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ +#else /* Must be little */ + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* Future possible st_blocks hi bits */ +#endif + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long __unused1; + unsigned long __unused2; +}; + +#endif + diff --git a/klibc/include/arch/sh/klibc/archsys.h b/klibc/include/arch/sh/klibc/archsys.h new file mode 100644 index 0000000000..5f8050a536 --- /dev/null +++ b/klibc/include/arch/sh/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/sh/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/sparc/klibc/archsetjmp.h b/klibc/include/arch/sparc/klibc/archsetjmp.h new file mode 100644 index 0000000000..92c1c74c9d --- /dev/null +++ b/klibc/include/arch/sparc/klibc/archsetjmp.h @@ -0,0 +1,16 @@ +/* + * arch/sparc/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __sp; + unsigned long __fp; + unsigned long __pc; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/sparc/klibc/archsignal.h b/klibc/include/arch/sparc/klibc/archsignal.h new file mode 100644 index 0000000000..6af3709033 --- /dev/null +++ b/klibc/include/arch/sparc/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/sparc/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/sparc/klibc/archstat.h b/klibc/include/arch/sparc/klibc/archstat.h new file mode 100644 index 0000000000..0ff68785e5 --- /dev/null +++ b/klibc/include/arch/sparc/klibc/archstat.h @@ -0,0 +1,35 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned long long st_dev; + + unsigned long long st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned int st_uid; + unsigned int st_gid; + + unsigned long long st_rdev; + + unsigned char __pad3[8]; + + long long st_size; + unsigned int st_blksize; + + unsigned char __pad4[8]; + unsigned int st_blocks; + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned int __unused4; + unsigned int __unused5; +}; + +#endif diff --git a/klibc/include/arch/sparc/klibc/archsys.h b/klibc/include/arch/sparc/klibc/archsys.h new file mode 100644 index 0000000000..20de8a8b44 --- /dev/null +++ b/klibc/include/arch/sparc/klibc/archsys.h @@ -0,0 +1,10 @@ +/* + * arch/sparc/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/sparc/machine/asm.h b/klibc/include/arch/sparc/machine/asm.h new file mode 100644 index 0000000000..b622bd8cf1 --- /dev/null +++ b/klibc/include/arch/sparc/machine/asm.h @@ -0,0 +1,192 @@ +/* $NetBSD: asm.h,v 1.14 2002/07/20 08:37:30 mrg Exp $ */ + +/* + * Copyright (c) 1994 Allen Briggs + * All rights reserved. + * + * Gleaned from locore.s and sun3 asm.h which had the following copyrights: + * locore.s: + * Copyright (c) 1988 University of Utah. + * Copyright (c) 1982, 1990 The Regents of the University of California. + * sun3/include/asm.h: + * Copyright (c) 1993 Adam Glass + * Copyright (c) 1990 The Regents of the University of California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _ASM_H_ +#define _ASM_H_ + +/* Pull in CCFSZ, CC64FSZ, and BIAS from frame.h */ +#ifndef _LOCORE +#define _LOCORE +#endif +#include + +#ifdef __ELF__ +#define _C_LABEL(name) name +#else +#ifdef __STDC__ +#define _C_LABEL(name) _ ## name +#else +#define _C_LABEL(name) _/**/name +#endif +#endif +#define _ASM_LABEL(name) name + +#ifdef PIC +/* + * PIC_PROLOGUE() is akin to the compiler generated function prologue for + * PIC code. It leaves the address of the Global Offset Table in DEST, + * clobbering register TMP in the process. + * + * We can use two code sequences. We can read the %pc or use the call + * instruction that saves the pc in %o7. Call requires the branch unit and + * IEU1, and clobbers %o7 which needs to be restored. This instruction + * sequence takes about 4 cycles due to instruction interdependence. Reading + * the pc takes 4 cycles to dispatch and is always dispatched alone. That + * sequence takes 7 cycles. + */ +#ifdef __arch64__ +#define PIC_PROLOGUE(dest,tmp) \ + mov %o7, tmp; \ + sethi %hi(_GLOBAL_OFFSET_TABLE_-4),dest; \ + call 0f; \ + or dest,%lo(_GLOBAL_OFFSET_TABLE_+4),dest; \ +0: \ + add dest,%o7,dest; \ + mov tmp, %o7 +#else +#define PIC_PROLOGUE(dest,tmp) \ + mov %o7,tmp; 3: call 4f; nop; 4: \ + sethi %hi(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ + or dest,%lo(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ + add dest,%o7,dest; mov tmp,%o7 +#endif + +/* + * PICCY_SET() does the equivalent of a `set var, %dest' instruction in + * a PIC-like way, but without involving the Global Offset Table. This + * only works for VARs defined in the same file *and* in the text segment. + */ +#ifdef __arch64__ +#define PICCY_SET(var,dest,tmp) \ + 3: rd %pc, tmp; add tmp,(var-3b),dest +#else +#define PICCY_SET(var,dest,tmp) \ + mov %o7,tmp; 3: call 4f; nop; 4: \ + add %o7,(var-3b),dest; mov tmp,%o7 +#endif +#else +#define PIC_PROLOGUE(dest,tmp) +#define PICCY_OFFSET(var,dest,tmp) +#endif + +#define FTYPE(x) .type x,@function +#define OTYPE(x) .type x,@object + +#define _ENTRY(name) \ + .align 4; .globl name; .proc 1; FTYPE(name); name: + +#ifdef GPROF +/* see _MCOUNT_ENTRY in profile.h */ +#ifdef __ELF__ +#ifdef __arch64__ +#define _PROF_PROLOGUE \ + .data; .align 8; 1: .uaword 0; .uaword 0; \ + .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call _mcount; \ + or %o0,%lo(1b),%o0; restore +#else +#define _PROF_PROLOGUE \ + .data; .align 4; 1: .long 0; \ + .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call _mcount; \ + or %o0,%lo(1b),%o0; restore +#endif +#else +#ifdef __arch64__ +#define _PROF_PROLOGUE \ + .data; .align 8; 1: .uaword 0; .uaword 0; \ + .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call mcount; \ + or %o0,%lo(1b),%o0; restore +#else +#define _PROF_PROLOGUE \ + .data; .align 4; 1: .long 0; \ + .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call mcount; \ + or %o0,%lo(1b),%o0; restore +#endif +#endif +#else +#define _PROF_PROLOGUE +#endif + +#define ENTRY(name) _ENTRY(_C_LABEL(name)); _PROF_PROLOGUE +#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name)) +#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)); _PROF_PROLOGUE +#define FUNC(name) ASENTRY(name) +#define RODATA(name) .align 4; .text; .globl _C_LABEL(name); \ + OTYPE(_C_LABEL(name)); _C_LABEL(name): + + +#define ASMSTR .asciz + +#define RCSID(name) .asciz name + +#ifdef __ELF__ +#define WEAK_ALIAS(alias,sym) \ + .weak alias; \ + alias = sym +#endif + +/* + * WARN_REFERENCES: create a warning if the specified symbol is referenced. + */ +#ifdef __ELF__ +#ifdef __STDC__ +#define WARN_REFERENCES(_sym,_msg) \ + .section .gnu.warning. ## _sym ; .ascii _msg ; .text +#else +#define WARN_REFERENCES(_sym,_msg) \ + .section .gnu.warning./**/_sym ; .ascii _msg ; .text +#endif /* __STDC__ */ +#else +#ifdef __STDC__ +#define __STRING(x) #x +#define WARN_REFERENCES(sym,msg) \ + .stabs msg ## ,30,0,0,0 ; \ + .stabs __STRING(_ ## sym) ## ,1,0,0,0 +#else +#define __STRING(x) "x" +#define WARN_REFERENCES(sym,msg) \ + .stabs msg,30,0,0,0 ; \ + .stabs __STRING(_/**/sym),1,0,0,0 +#endif /* __STDC__ */ +#endif /* __ELF__ */ + +#endif /* _ASM_H_ */ diff --git a/klibc/include/arch/sparc/machine/frame.h b/klibc/include/arch/sparc/machine/frame.h new file mode 100644 index 0000000000..b09175c7f4 --- /dev/null +++ b/klibc/include/arch/sparc/machine/frame.h @@ -0,0 +1,138 @@ +/* $NetBSD: frame.h,v 1.4 2001/12/04 00:05:05 darrenr Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)frame.h 8.1 (Berkeley) 6/11/93 + */ + +#if defined(_KERNEL_OPT) +#include "opt_sparc_arch.h" +#endif + +/* + * Sparc stack frame format. + * + * Note that the contents of each stack frame may be held only in + * machine register windows. In order to get an accurate picture + * of the frame, you must first force the kernel to write any such + * windows to the stack. + */ +#ifndef _LOCORE +#ifndef SUN4U +struct frame { + int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ + int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ + struct frame *fr_fp; /* space to save frame pointer (%i6) */ + int32_t fr_pc; /* space to save return pc (%i7) */ + /* + * SunOS reserves another 8 words here; this is pointless + * but we do it for compatibility. + */ + int32_t fr_xxx; /* `structure return pointer' (unused) */ + int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ + int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ +}; +#else +struct frame32 { + int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ + int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ + u_int32_t fr_fp; /* space to save frame pointer (%i6) */ + u_int32_t fr_pc; /* space to save return pc (%i7) */ + /* + * SunOS reserves another 8 words here; this is pointless + * but we do it for compatibility. + */ + int32_t fr_xxx; /* `structure return pointer' (unused) */ + int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ + int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ +}; +#endif +#endif + +/* + * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if + * a function is to call C code. It should be just 64, but Sun defined + * their frame with space to hold arguments 0 through 5 (plus some junk), + * and varargs routines (such as kprintf) demand this, and gcc uses this + * area at times anyway. + */ +#define CCFSZ 96 + +/* + * Sparc v9 stack frame format. + * + * Note that the contents of each stack frame may be held only in + * machine register windows. In order to get an accurate picture + * of the frame, you must first force the kernel to write any such + * windows to the stack. + * + * V9 frames have an odd bias, so you can tall a v9 frame from + * a v8 frame by testing the stack pointer's lsb. + */ +#if !defined(_LOCORE) && !defined(_LIBC) +struct frame64 { + int64_t fr_local[8]; /* space to save locals (%l0..%l7) */ + int64_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ + u_int64_t fr_fp; /* space to save frame pointer (%i6) */ + u_int64_t fr_pc; /* space to save return pc (%i7) */ + /* + * SVR4 reserves a bunch of extra stuff. + */ + int64_t fr_argd[6]; /* `register save area' (lunacy) */ + int64_t fr_argx[0]; /* arg extension (args 7..n; variable size) */ +}; + +#define v9next_frame(f) ((struct frame64*)(f->fr_fp+BIAS)) +#endif + +/* + * CC64FSZ (C Compiler 64-bit Frame SiZe) is the size of a stack frame used + * by the compiler in 64-bit mode. It is (16)*8; space for 8 ins, 8 outs. + */ +#define CC64FSZ 176 + +/* + * v9 stacks all have a bias of 2047 added to the %sp and %fp, so you can easily + * detect it by testing the register for an odd value. Why 2K-1 I don't know. + */ +#define BIAS (2048-1) + diff --git a/klibc/include/arch/sparc/machine/trap.h b/klibc/include/arch/sparc/machine/trap.h new file mode 100644 index 0000000000..42c3ef6ae2 --- /dev/null +++ b/klibc/include/arch/sparc/machine/trap.h @@ -0,0 +1,141 @@ +/* $NetBSD: trap.h,v 1.11 1999/01/20 00:15:08 pk Exp $ */ + +/* + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This software was developed by the Computer Systems Engineering group + * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and + * contributed to Berkeley. + * + * All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Lawrence Berkeley Laboratory. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)trap.h 8.1 (Berkeley) 6/11/93 + */ +/* + * Sun4m support by Aaron Brown, Harvard University. + * Changes Copyright (c) 1995 The President and Fellows of Harvard College. + * All rights reserved. + */ + +#ifndef _MACHINE_TRAP_H +#define _MACHINE_TRAP_H + +/* trap vec (pri) description */ +#define T_RESET 0x00 /* (1) not actually vectored; jumps to 0 */ +#define T_TEXTFAULT 0x01 /* (2) address fault during instr fetch */ +#define T_ILLINST 0x02 /* (3) illegal instruction */ +#define T_PRIVINST 0x03 /* (4) privileged instruction */ +#define T_FPDISABLED 0x04 /* (5) fp instr while fp disabled */ +#define T_WINOF 0x05 /* (6) register window overflow */ +#define T_WINUF 0x06 /* (7) register window underflow */ +#define T_ALIGN 0x07 /* (8) address not properly aligned */ +#define T_FPE 0x08 /* (9) floating point exception */ +#define T_DATAFAULT 0x09 /* (10) address fault during data fetch */ +#define T_TAGOF 0x0a /* (11) tag overflow */ +/* 0x0b unused */ +/* 0x0c unused */ +/* 0x0d unused */ +/* 0x0e unused */ +/* 0x0f unused */ +/* 0x10 unused */ +#define T_L1INT 0x11 /* (27) level 1 interrupt */ +#define T_L2INT 0x12 /* (26) level 2 interrupt */ +#define T_L3INT 0x13 /* (25) level 3 interrupt */ +#define T_L4INT 0x14 /* (24) level 4 interrupt */ +#define T_L5INT 0x15 /* (23) level 5 interrupt */ +#define T_L6INT 0x16 /* (22) level 6 interrupt */ +#define T_L7INT 0x17 /* (21) level 7 interrupt */ +#define T_L8INT 0x18 /* (20) level 8 interrupt */ +#define T_L9INT 0x19 /* (19) level 9 interrupt */ +#define T_L10INT 0x1a /* (18) level 10 interrupt */ +#define T_L11INT 0x1b /* (17) level 11 interrupt */ +#define T_L12INT 0x1c /* (16) level 12 interrupt */ +#define T_L13INT 0x1d /* (15) level 13 interrupt */ +#define T_L14INT 0x1e /* (14) level 14 interrupt */ +#define T_L15INT 0x1f /* (13) level 15 interrupt */ +/* 0x20 unused */ +/* through 0x23 unused */ +#define T_CPDISABLED 0x24 /* (5) coprocessor instr while disabled */ +#define T_UNIMPLFLUSH 0x25 /* Unimplemented FLUSH */ +/* through 0x27 unused */ +#define T_CPEXCEPTION 0x28 /* (9) coprocessor exception */ +/* 0x29 unused */ +#define T_IDIV0 0x2a /* divide by zero (from hw [su]div instr) */ +#define T_STOREBUFFAULT 0x2b /* SuperSPARC: Store buffer copy-back fault */ +/* 0x2c unused */ +/* through 0x7f unused */ + +/* beginning of `user' vectors (from trap instructions) - all priority 12 */ +#define T_SUN_SYSCALL 0x80 /* system call */ +#define T_BREAKPOINT 0x81 /* breakpoint `instruction' */ +#define T_DIV0 0x82 /* division routine was handed 0 */ +#define T_FLUSHWIN 0x83 /* flush windows */ +#define T_CLEANWIN 0x84 /* provide clean windows */ +#define T_RANGECHECK 0x85 /* ? */ +#define T_FIXALIGN 0x86 /* fix up unaligned accesses */ +#define T_INTOF 0x87 /* integer overflow ? */ +#define T_SVR4_SYSCALL 0x88 /* SVR4 system call */ +#define T_BSD_SYSCALL 0x89 /* BSD system call */ +#define T_KGDB_EXEC 0x8a /* for kernel gdb */ + +/* 0x8b..0xff are currently unallocated, except the following */ +#define T_SVR4_GETCC 0xa0 +#define T_SVR4_SETCC 0xa1 +#define T_SVR4_GETPSR 0xa2 +#define T_SVR4_SETPSR 0xa3 +#define T_SVR4_GETHRTIME 0xa4 +#define T_SVR4_GETHRVTIME 0xa5 +#define T_SVR4_GETHRESTIME 0xa7 + + +#ifdef _KERNEL /* pseudo traps for locore.s */ +#define T_RWRET -1 /* need first user window for trap return */ +#define T_AST -2 /* no-op, just needed reschedule or profile */ +#endif + +/* flags to system call (flags in %g1 along with syscall number) */ +#define SYSCALL_G2RFLAG 0x400 /* on success, return to %g2 rather than npc */ +#define SYSCALL_G7RFLAG 0x800 /* use %g7 as above (deprecated) */ + +/* + * `software trap' macros to keep people happy (sparc v8 manual says not + * to set the upper bits). + */ +#define ST_BREAKPOINT (T_BREAKPOINT & 0x7f) +#define ST_DIV0 (T_DIV0 & 0x7f) +#define ST_FLUSHWIN (T_FLUSHWIN & 0x7f) +#define ST_SYSCALL (T_SUN_SYSCALL & 0x7f) + +#endif /* _MACHINE_TRAP_H_ */ diff --git a/klibc/include/arch/sparc64/klibc/archsetjmp.h b/klibc/include/arch/sparc64/klibc/archsetjmp.h new file mode 100644 index 0000000000..022a31e542 --- /dev/null +++ b/klibc/include/arch/sparc64/klibc/archsetjmp.h @@ -0,0 +1,16 @@ +/* + * arch/sparc64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __sp; + unsigned long __fp; + unsigned long __pc; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/sparc64/klibc/archsignal.h b/klibc/include/arch/sparc64/klibc/archsignal.h new file mode 100644 index 0000000000..f81bd668bb --- /dev/null +++ b/klibc/include/arch/sparc64/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/sparc64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/sparc64/klibc/archstat.h b/klibc/include/arch/sparc64/klibc/archstat.h new file mode 100644 index 0000000000..c22905d30c --- /dev/null +++ b/klibc/include/arch/sparc64/klibc/archstat.h @@ -0,0 +1,22 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +/* No nsec fields?! */ +struct stat { + unsigned st_dev; + ino_t st_ino; + mode_t st_mode; + short st_nlink; + uid_t st_uid; + gid_t st_gid; + unsigned st_rdev; + off_t st_size; + time_t st_atime; + time_t st_mtime; + time_t st_ctime; + off_t st_blksize; + off_t st_blocks; + unsigned long __unused4[2]; +}; + +#endif diff --git a/klibc/include/arch/sparc64/klibc/archsys.h b/klibc/include/arch/sparc64/klibc/archsys.h new file mode 100644 index 0000000000..6a3a7b25bc --- /dev/null +++ b/klibc/include/arch/sparc64/klibc/archsys.h @@ -0,0 +1,10 @@ +/* + * arch/sparc64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/x86_64/klibc/archsetjmp.h b/klibc/include/arch/x86_64/klibc/archsetjmp.h new file mode 100644 index 0000000000..90d0a0d263 --- /dev/null +++ b/klibc/include/arch/x86_64/klibc/archsetjmp.h @@ -0,0 +1,21 @@ +/* + * arch/x86_64/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __rbx; + unsigned long __rsp; + unsigned long __rbp; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; + unsigned long __rip; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/x86_64/klibc/archsignal.h b/klibc/include/arch/x86_64/klibc/archsignal.h new file mode 100644 index 0000000000..74e82e1dd0 --- /dev/null +++ b/klibc/include/arch/x86_64/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/x86_64/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/x86_64/klibc/archstat.h b/klibc/include/arch/x86_64/klibc/archstat.h new file mode 100644 index 0000000000..53e141daea --- /dev/null +++ b/klibc/include/arch/x86_64/klibc/archstat.h @@ -0,0 +1,26 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +struct stat { + unsigned long st_dev; + unsigned long st_ino; + unsigned long st_nlink; + + unsigned int st_mode; + unsigned int st_uid; + unsigned int st_gid; + unsigned int __pad0; + unsigned long st_rdev; + long st_size; + long st_blksize; + long st_blocks; /* Number 512-byte blocks allocated. */ + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + long __unused[3]; +}; + +#endif diff --git a/klibc/include/arch/x86_64/klibc/archsys.h b/klibc/include/arch/x86_64/klibc/archsys.h new file mode 100644 index 0000000000..2ec72cd397 --- /dev/null +++ b/klibc/include/arch/x86_64/klibc/archsys.h @@ -0,0 +1,109 @@ +/* + * arch/x86_64/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* The x86-64 syscall headers are needlessly inefficient */ + +#undef _syscall0 +#undef _syscall1 +#undef _syscall2 +#undef _syscall3 +#undef _syscall4 +#undef _syscall5 +#undef _syscall6 + +#define _syscall0(type,name) \ +type name (void) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall1(type,name,type1,arg1) \ +type name (type1 arg1) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name (type1 arg1,type2 arg2) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name (type1 arg1,type2 arg2,type3 arg3) \ +{ \ +long __res; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ +{ \ +long __res; \ +register type4 __r10 asm("%r10") = arg4; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3),"r" (__r10) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ +long __res; \ +register type4 __r10 asm("%r10") = arg4; \ +register type5 __r8 asm("%r8") = arg5; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3),"r" (__r10),"r" (__r8) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5,type6,arg6) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ +{ \ +long __res; \ +register type4 __r10 asm("%r10") = arg4; \ +register type5 __r8 asm("%r8") = arg5; \ +register type6 __r9 asm("%r9") = arg6; \ +__asm__ volatile (__syscall \ + : "=a" (__res) \ + : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ + "d" (arg3),"r" (__r10),"r" (__r8), "r" (__r9) \ + : __syscall_clobber); \ +__syscall_return(type,__res); \ +} + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/x86_64/sys/io.h b/klibc/include/arch/x86_64/sys/io.h new file mode 100644 index 0000000000..4a0ae44985 --- /dev/null +++ b/klibc/include/arch/x86_64/sys/io.h @@ -0,0 +1,126 @@ +#ident "$Id: io.h,v 1.1 2004/01/25 01:34:29 hpa Exp $" +/* ----------------------------------------------------------------------- * + * + * Copyright 2004 H. Peter Anvin - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * sys/io.h for the i386 architecture + * + * Basic I/O macros + */ + +#ifndef _SYS_IO_H +#define _SYS_IO_H 1 + +/* I/O-related system calls */ + +int iopl(int); +int ioperm(unsigned long, unsigned long, int); + +/* Basic I/O macros */ + +static __inline__ void +outb(unsigned char __v, unsigned short __p) +{ + asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outw(unsigned short __v, unsigned short __p) +{ + asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ void +outl(unsigned int __v, unsigned short __p) +{ + asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); +} + +static __inline__ unsigned char +inb(unsigned short __p) +{ + unsigned char __v; + asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); + return v; +} + +static __inline__ unsigned short +inw(unsigned short __p) +{ + unsigned short __v; + asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); + return v; +} + +static __inline__ unsigned int +inl(unsigned short __p) +{ + unsigned int __v; + asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); + return v; +} + +/* String I/O macros */ + +static __inline__ void +outsb (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsw (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +outsl (unsigned short __p, const void *__d, unsigned long __n) +{ + asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); +} + + +static __inline__ void +insb (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insw (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +static __inline__ void +insl (unsigned short __p, void *__d, unsigned long __n) +{ + asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); +} + +#endif /* _SYS_IO_H */ diff --git a/klibc/include/arpa/inet.h b/klibc/include/arpa/inet.h new file mode 100644 index 0000000000..043b148e17 --- /dev/null +++ b/klibc/include/arpa/inet.h @@ -0,0 +1,24 @@ +/* + * arpa/inet.h + */ + +#ifndef _ARPA_INET_H +#define _ARPA_INET_H + +#include +#include +#include +#include +#include + +__extern uint32_t inet_addr(const char *); +__extern int inet_aton(const char *, struct in_addr *); +__extern char *inet_ntoa(struct in_addr); +__extern int inet_pton(int, const char *, void *); +__extern const char *inet_ntop(int, const void *, char *, size_t); +__extern unsigned int inet_nsap_addr(const char *, unsigned char *, int); +__extern char *inet_nsap_ntoa(int, const unsigned char *, char *); + +#endif /* _ARPA_INET_H */ + + diff --git a/klibc/include/assert.h b/klibc/include/assert.h new file mode 100644 index 0000000000..58cc37c487 --- /dev/null +++ b/klibc/include/assert.h @@ -0,0 +1,22 @@ +/* + * assert.h + */ + +#ifndef _ASSERT_H +#define _ASSERT_H + +#ifdef NDEBUG + +#define assert(x) ((void)(x)) + +#else + +extern void __assert_fail(const char *, const char *, + unsigned int); + +#define assert(x) ((x) ? (void)0 : __assert_fail(#x, __FILE__, __LINE__)) + +#endif + +#endif /* _ASSERT_H */ + diff --git a/klibc/include/bits32/bitsize/limits.h b/klibc/include/bits32/bitsize/limits.h new file mode 100644 index 0000000000..f90e524b2b --- /dev/null +++ b/klibc/include/bits32/bitsize/limits.h @@ -0,0 +1,14 @@ +/* + * bits32/limits.h + */ + +#ifndef _BITSIZE_LIMITS_H +#define _BITSIZE_LIMITS_H + +#define LONG_BIT 32 + +#define LONG_MIN (-2147483647L-1) +#define LONG_MAX 2147483647L +#define ULONG_MAX 4294967295UL + +#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/include/bits32/bitsize/stddef.h b/klibc/include/bits32/bitsize/stddef.h new file mode 100644 index 0000000000..c486041fe0 --- /dev/null +++ b/klibc/include/bits32/bitsize/stddef.h @@ -0,0 +1,18 @@ +/* + * bits32/stddef.h + */ + +#ifndef _BITSIZE_STDDEF_H +#define _BITSIZE_STDDEF_H + +#define _SIZE_T +#if defined(__s390__) || defined(__hppa__) || defined(__cris__) +typedef unsigned long size_t; +#else +typedef unsigned int size_t; +#endif + +#define _PTRDIFF_T +typedef signed int ptrdiff_t; + +#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/include/bits32/bitsize/stdint.h b/klibc/include/bits32/bitsize/stdint.h new file mode 100644 index 0000000000..40b464961c --- /dev/null +++ b/klibc/include/bits32/bitsize/stdint.h @@ -0,0 +1,34 @@ +/* + * bits32/stdint.h + */ + +#ifndef _BITSIZE_STDINT_H +#define _BITSIZE_STDINT_H + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef long long int int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long int uint64_t; + +typedef int int_fast16_t; +typedef int int_fast32_t; + +typedef unsigned int uint_fast16_t; +typedef unsigned int uint_fast32_t; + +typedef int intptr_t; +typedef unsigned int uintptr_t; + +#define __INT64_C(c) c ## LL +#define __UINT64_C(c) c ## ULL + +#define __PRI64_RANK "ll" +#define __PRIFAST_RANK "" +#define __PRIPTR_RANK "" + +#endif /* _BITSIZE_STDINT_H */ diff --git a/klibc/include/bits32/bitsize/stdintconst.h b/klibc/include/bits32/bitsize/stdintconst.h new file mode 100644 index 0000000000..8157dd06e0 --- /dev/null +++ b/klibc/include/bits32/bitsize/stdintconst.h @@ -0,0 +1,18 @@ +/* + * bits32/stdintconst.h + */ + +#ifndef _BITSIZE_STDINTCONST_H +#define _BITSIZE_STDINTCONST_H + +#define INT_FAST16_C(c) INT32_C(c) +#define INT_FAST32_C(c) INT32_C(c) + +#define UINT_FAST16_C(c) UINT32_C(c) +#define UINT_FAST32_C(c) UINT32_C(c) + +#define INTPTR_C(c) INT32_C(c) +#define UINTPTR_C(c) UINT32_C(c) +#define PTRDIFF_C(c) INT32_C(c) + +#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/include/bits32/bitsize/stdintlimits.h b/klibc/include/bits32/bitsize/stdintlimits.h new file mode 100644 index 0000000000..b44fe01186 --- /dev/null +++ b/klibc/include/bits32/bitsize/stdintlimits.h @@ -0,0 +1,22 @@ +/* + * bits32/stdintlimits.h + */ + +#ifndef _BITSIZE_STDINTLIMITS_H +#define _BITSIZE_STDINTLIMITS_H + +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MAX INT32_MAX +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX + +#define INTPTR_MIN INT32_MIN +#define INTPTR_MAX INT32_MAX +#define UINTPTR_MAX UINT32_MAX + +#define PTRDIFF_MIN INT32_MIN +#define PTRDIFF_MAX INT32_MAX + +#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/include/bits64/bitsize/limits.h b/klibc/include/bits64/bitsize/limits.h new file mode 100644 index 0000000000..7b20da085b --- /dev/null +++ b/klibc/include/bits64/bitsize/limits.h @@ -0,0 +1,14 @@ +/* + * bits64/limits.h + */ + +#ifndef _BITSIZE_LIMITS_H +#define _BITSIZE_LIMITS_H + +#define LONG_BIT 64 + +#define LONG_MIN (-9223372036854775807L-1) +#define LONG_MAX 9223372036854775807L +#define ULONG_MAX 18446744073709551615UL + +#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/include/bits64/bitsize/stddef.h b/klibc/include/bits64/bitsize/stddef.h new file mode 100644 index 0000000000..3e72621862 --- /dev/null +++ b/klibc/include/bits64/bitsize/stddef.h @@ -0,0 +1,13 @@ +/* + * bits64/stddef.h + */ + +#ifndef _BITSIZE_STDDEF_H +#define _BITSIZE_STDDEF_H + +#define _SIZE_T +typedef unsigned long size_t; +#define _PTRDIFF_T +typedef signed long ptrdiff_t; + +#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/include/bits64/bitsize/stdint.h b/klibc/include/bits64/bitsize/stdint.h new file mode 100644 index 0000000000..8e16cf0909 --- /dev/null +++ b/klibc/include/bits64/bitsize/stdint.h @@ -0,0 +1,36 @@ +/* + * bits64/stdint.h + */ + +#ifndef _BITSIZE_STDINT_H +#define _BITSIZE_STDINT_H + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef long int int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long int uint64_t; + +typedef long int int_fast16_t; +typedef long int int_fast32_t; + +typedef unsigned long int uint_fast16_t; +typedef unsigned long int uint_fast32_t; + +typedef long int intptr_t; +typedef unsigned long int uintptr_t; + +#define __INT64_C(c) c ## L +#define __UINT64_C(c) c ## UL + +#define __PRI64_RANK "l" +#define __PRIFAST_RANK "l" +#define __PRIPTR_RANK "l" + +#endif /* _BITSIZE_STDINT_H */ + + diff --git a/klibc/include/bits64/bitsize/stdintconst.h b/klibc/include/bits64/bitsize/stdintconst.h new file mode 100644 index 0000000000..65f2db0501 --- /dev/null +++ b/klibc/include/bits64/bitsize/stdintconst.h @@ -0,0 +1,18 @@ +/* + * bits64/stdintconst.h + */ + +#ifndef _BITSIZE_STDINTCONST_H +#define _BITSIZE_STDINTCONST_H + +#define INT_FAST16_C(c) INT64_C(c) +#define INT_FAST32_C(c) INT64_C(c) + +#define UINT_FAST16_C(c) UINT64_C(c) +#define UINT_FAST32_C(c) UINT64_C(c) + +#define INTPTR_C(c) INT64_C(c) +#define UINTPTR_C(c) UINT64_C(c) +#define PTRDIFF_C(c) INT64_C(c) + +#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/include/bits64/bitsize/stdintlimits.h b/klibc/include/bits64/bitsize/stdintlimits.h new file mode 100644 index 0000000000..d110d17d2d --- /dev/null +++ b/klibc/include/bits64/bitsize/stdintlimits.h @@ -0,0 +1,22 @@ +/* + * bits64/stdintlimits.h + */ + +#ifndef _BITSIZE_STDINTLIMITS_H +#define _BITSIZE_STDINTLIMITS_H + +#define INT_FAST16_MIN INT64_MIN +#define INT_FAST32_MIN INT64_MIN +#define INT_FAST16_MAX INT64_MAX +#define INT_FAST32_MAX INT64_MAX +#define UINT_FAST16_MAX UINT64_MAX +#define UINT_FAST32_MAX UINT64_MAX + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX + +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX + +#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/include/ctype.h b/klibc/include/ctype.h new file mode 100644 index 0000000000..daa6a8eff4 --- /dev/null +++ b/klibc/include/ctype.h @@ -0,0 +1,119 @@ +/* + * ctype.h + * + * This assumes ISO 8859-1, being a reasonable superset of ASCII. + */ + +#ifndef _CTYPE_H +#define _CTYPE_H + +#ifndef __CTYPE_NO_INLINE +# define __ctype_inline extern __inline__ +#else +# define __ctype_inline +#endif + +/* + * This relies on the following definitions: + * + * cntrl = !print + * alpha = upper|lower + * graph = punct|alpha|digit + * blank = '\t' || ' ' (per POSIX requirement) + */ +enum { + __ctype_upper = (1 << 0), + __ctype_lower = (1 << 1), + __ctype_digit = (1 << 2), + __ctype_xdigit = (1 << 3), + __ctype_space = (1 << 4), + __ctype_print = (1 << 5), + __ctype_punct = (1 << 6), + __ctype_cntrl = (1 << 7), +}; + +extern const unsigned char __ctypes[]; + +__ctype_inline int isalnum(int __c) +{ + return __ctypes[__c+1] & + (__ctype_upper|__ctype_lower|__ctype_digit); +} + +__ctype_inline int isalpha(int __c) +{ + return __ctypes[__c+1] & + (__ctype_upper|__ctype_lower); +} + +__ctype_inline int isascii(int __c) +{ + return !(__c & ~0x7f); +} + +__ctype_inline int isblank(int __c) +{ + return (__c == '\t') || (__c == ' '); +} + +__ctype_inline int iscntrl(int __c) +{ + return __ctypes[__c+1] & __ctype_cntrl; +} + +__ctype_inline int isdigit(int __c) +{ + return ((unsigned)__c - '0') <= 9; +} + +__ctype_inline int isgraph(int __c) +{ + return __ctypes[__c+1] & + (__ctype_upper|__ctype_lower|__ctype_digit|__ctype_punct); +} + +__ctype_inline int islower(int __c) +{ + return __ctypes[__c+1] & __ctype_lower; +} + +__ctype_inline int isprint(int __c) +{ + return __ctypes[__c+1] & __ctype_print; +} + +__ctype_inline int ispunct(int __c) +{ + return __ctypes[__c+1] & __ctype_punct; +} + +__ctype_inline int isspace(int __c) +{ + return __ctypes[__c+1] & __ctype_space; +} + +__ctype_inline int isupper(int __c) +{ + return __ctypes[__c+1] & __ctype_upper; +} + +__ctype_inline int isxdigit(int __c) +{ + return __ctypes[__c+1] & __ctype_xdigit; +} + +/* Note: this is decimal, not hex, to avoid accidental promotion to unsigned */ +#define _toupper(__c) ((__c) & ~32) +#define _tolower(__c) ((__c) | 32) + +__ctype_inline int toupper(int __c) +{ + return islower(__c) ? _toupper(__c) : __c; +} + +__ctype_inline int tolower(int __c) +{ + return isupper(__c) ? _tolower(__c) : __c; +} + +#endif /* _CTYPE_H */ diff --git a/klibc/include/dirent.h b/klibc/include/dirent.h new file mode 100644 index 0000000000..4db479592b --- /dev/null +++ b/klibc/include/dirent.h @@ -0,0 +1,32 @@ +/* + * dirent.h + */ + +#ifndef _DIRENT_H +#define _DIRENT_H + +#include +#include + +struct _IO_dir { + int __fd; + +#ifdef __KLIBC_DIRENT_INTERNALS + /* These fields for internal use only */ + + size_t bytes_left; + struct dirent *next; + /* Declaring this as an array of struct enforces correct alignment */ + struct dirent buffer[15]; /* 15 times max dirent size =~ 4K */ +#endif +}; +typedef struct _IO_dir DIR; + +__extern DIR *opendir(const char *); +__extern struct dirent *readdir(DIR *); +__extern int closedir(DIR *); +static __inline__ int dirfd (DIR *__d) { + return __d->__fd; +} + +#endif /* _DIRENT_H */ diff --git a/klibc/include/elf.h b/klibc/include/elf.h new file mode 100644 index 0000000000..52f47d042e --- /dev/null +++ b/klibc/include/elf.h @@ -0,0 +1,12 @@ +/* + * elf.h + */ + +#ifndef _ELF_H +#define _ELF_H + +#include +#include + +#endif /* _ELF_H */ + diff --git a/klibc/include/endian.h b/klibc/include/endian.h new file mode 100644 index 0000000000..44f89ccbbc --- /dev/null +++ b/klibc/include/endian.h @@ -0,0 +1,42 @@ +/* + * endian.h + */ + +#ifndef _ENDIAN_H +#define _ENDIAN_H + +#include +#include + +/* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or + __BIG_ENDIAN, but the glibc/BSD-ish macros expect both to be + defined with __BYTE_ORDER defining which is actually used... */ + +#if defined(__LITTLE_ENDIAN) +# undef __LITTLE_ENDIAN +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# define __PDP_ENDIAN 3412 +# define __BYTE_ORDER __LITTLE_ENDIAN +#elif defined(__BIG_ENDIAN) +# undef __BIG_ENDIAN +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# define __PDP_ENDIAN 3412 +# define __BYTE_ORDER __BIG_ENDIAN +#elif defined(__PDP_ENDIAN) +# undef __PDP_ENDIAN +# define __LITTLE_ENDIAN 1234 +# define __BIG_ENDIAN 4321 +# define __PDP_ENDIAN 3412 +# define __BYTE_ORDER __PDP_ENDIAN +#else +# error "Unknown byte order!" +#endif + +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#define BIG_ENDIAN __BIG_ENDIAN +#define PDP_ENDIAN __PDP_ENDIAN +#define BYTE_ORDER __BYTE_ORDER + +#endif /* _ENDIAN_H */ diff --git a/klibc/include/errno.h b/klibc/include/errno.h new file mode 100644 index 0000000000..b2e666504d --- /dev/null +++ b/klibc/include/errno.h @@ -0,0 +1,8 @@ +/* + * errno.h + */ + +#include +#include + +__extern int errno; diff --git a/klibc/include/fcntl.h b/klibc/include/fcntl.h new file mode 100644 index 0000000000..c9650f76b5 --- /dev/null +++ b/klibc/include/fcntl.h @@ -0,0 +1,46 @@ +/* + * fcntl.h + */ + +#ifndef _FCNTL_H +#define _FCNTL_H + +#include +#include +#include +#if defined(__mips__) && !defined(__mips64__) +# include +#endif +#include + +/* This is ugly, but "struct flock" has actually been defined with + a long off_t, so it's really "struct flock64". It just happens + to work. Gag. Barf. + + This happens to work on all 32-bit architectures except MIPS. */ + +#ifdef F_GETLK64 +# undef F_GETLK +# define F_GETLK F_GETLK64 +#endif + +#ifdef F_SETLK64 +# undef F_SETLK +# define F_SETLK F_SETLK64 +#endif + +#ifdef F_SETLKW64 +# undef F_SETLKW +# define F_SETLKW F_SETLKW64 +#endif + +/* This is defined here as well as in since old-style code + would still include when using open(), and open() being + a varadic function changes its calling convention on some architectures. */ +#ifndef _KLIBC_IN_OPEN_C +__extern int open(const char *, int, ...); +#endif + +__extern int fcntl(int, int, ...); + +#endif /* _FCNTL_H */ diff --git a/klibc/include/grp.h b/klibc/include/grp.h new file mode 100644 index 0000000000..03ceb31560 --- /dev/null +++ b/klibc/include/grp.h @@ -0,0 +1,13 @@ +/* + * grp.h + */ + +#ifndef _GRP_H +#define _GRP_H + +#include +#include + +__extern int setgroups(size_t, const gid_t *); + +#endif /* _GRP_H */ diff --git a/klibc/include/inttypes.h b/klibc/include/inttypes.h new file mode 100644 index 0000000000..e00fa63160 --- /dev/null +++ b/klibc/include/inttypes.h @@ -0,0 +1,226 @@ +/* + * inttypes.h + */ + +#ifndef _INTTYPES_H +#define _INTTYPES_H + +#include +#include +#include + +static __inline__ intmax_t imaxabs(intmax_t __n) +{ + return (__n < (intmax_t)0) ? -__n : __n; +} + +__extern intmax_t strtoimax(const char *, char **, int); +__extern uintmax_t strtoumax(const char *, char **, int); + +/* extensions */ +__extern intmax_t strntoimax(const char *, char **, int, size_t); +__extern uintmax_t strntoumax(const char *, char **, int, size_t); + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) + +#define PRId8 "d" +#define PRId16 "d" +#define PRId32 "d" +#define PRId64 __PRI64_RANK "d" + +#define PRIdLEAST8 "d" +#define PRIdLEAST16 "d" +#define PRIdLEAST32 "d" +#define PRIdLEAST64 __PRI64_RANK "d" + +#define PRIdFAST8 "d" +#define PRIdFAST16 __PRIFAST_RANK "d" +#define PRIdFAST32 __PRIFAST_RANK "d" +#define PRIdFAST64 __PRI64_RANK "d" + +#define PRIdMAX __PRI64_RANK "d" +#define PRIdPTR __PRIPTR_RANK "d" + +#define PRIi8 "i" +#define PRIi16 "i" +#define PRIi32 "i" +#define PRIi64 __PRI64_RANK "i" + +#define PRIiLEAST8 "i" +#define PRIiLEAST16 "i" +#define PRIiLEAST32 "i" +#define PRIiLEAST64 __PRI64_RANK "i" + +#define PRIiFAST8 "i" +#define PRIiFAST16 __PRIFAST_RANK "i" +#define PRIiFAST32 __PRIFAST_RANK "i" +#define PRIiFAST64 __PRI64_RANK "i" + +#define PRIiMAX __PRI64_RANK "i" +#define PRIiPTR __PRIPTR_RANK "i" + +#define PRIo8 "o" +#define PRIo16 "o" +#define PRIo32 "o" +#define PRIo64 __PRI64_RANK "o" + +#define PRIoLEAST8 "o" +#define PRIoLEAST16 "o" +#define PRIoLEAST32 "o" +#define PRIoLEAST64 __PRI64_RANK "o" + +#define PRIoFAST8 "o" +#define PRIoFAST16 __PRIFAST_RANK "o" +#define PRIoFAST32 __PRIFAST_RANK "o" +#define PRIoFAST64 __PRI64_RANK "o" + +#define PRIoMAX __PRI64_RANK "o" +#define PRIoPTR __PRIPTR_RANK "o" + +#define PRIu8 "u" +#define PRIu16 "u" +#define PRIu32 "u" +#define PRIu64 __PRI64_RANK "u" + +#define PRIuLEAST8 "u" +#define PRIuLEAST16 "u" +#define PRIuLEAST32 "u" +#define PRIuLEAST64 __PRI64_RANK "u" + +#define PRIuFAST8 "u" +#define PRIuFAST16 __PRIFAST_RANK "u" +#define PRIuFAST32 __PRIFAST_RANK "u" +#define PRIuFAST64 __PRI64_RANK "u" + +#define PRIuMAX __PRI64_RANK "u" +#define PRIuPTR __PRIPTR_RANK "u" + +#define PRIx8 "x" +#define PRIx16 "x" +#define PRIx32 "x" +#define PRIx64 __PRI64_RANK "x" + +#define PRIxLEAST8 "x" +#define PRIxLEAST16 "x" +#define PRIxLEAST32 "x" +#define PRIxLEAST64 __PRI64_RANK "x" + +#define PRIxFAST8 "x" +#define PRIxFAST16 __PRIFAST_RANK "x" +#define PRIxFAST32 __PRIFAST_RANK "x" +#define PRIxFAST64 __PRI64_RANK "x" + +#define PRIxMAX __PRI64_RANK "x" +#define PRIxPTR __PRIPTR_RANK "x" + +#define PRIX8 "X" +#define PRIX16 "X" +#define PRIX32 "X" +#define PRIX64 __PRI64_RANK "X" + +#define PRIXLEAST8 "X" +#define PRIXLEAST16 "X" +#define PRIXLEAST32 "X" +#define PRIXLEAST64 __PRI64_RANK "X" + +#define PRIXFAST8 "X" +#define PRIXFAST16 __PRIFAST_RANK "X" +#define PRIXFAST32 __PRIFAST_RANK "X" +#define PRIXFAST64 __PRI64_RANK "X" + +#define PRIXMAX __PRI64_RANK "X" +#define PRIXPTR __PRIPTR_RANK "X" + +#define SCNd8 "hhd" +#define SCNd16 "hd" +#define SCNd32 "d" +#define SCNd64 __PRI64_RANK "d" + +#define SCNdLEAST8 "hhd" +#define SCNdLEAST16 "hd" +#define SCNdLEAST32 "d" +#define SCNdLEAST64 __PRI64_RANK "d" + +#define SCNdFAST8 "hhd" +#define SCNdFAST16 __PRIFAST_RANK "d" +#define SCNdFAST32 __PRIFAST_RANK "d" +#define SCNdFAST64 __PRI64_RANK "d" + +#define SCNdMAX __PRI64_RANK "d" +#define SCNdPTR __PRIPTR_RANK "d" + +#define SCNi8 "hhi" +#define SCNi16 "hi" +#define SCNi32 "i" +#define SCNi64 __PRI64_RANK "i" + +#define SCNiLEAST8 "hhi" +#define SCNiLEAST16 "hi" +#define SCNiLEAST32 "i" +#define SCNiLEAST64 __PRI64_RANK "i" + +#define SCNiFAST8 "hhi" +#define SCNiFAST16 __PRIFAST_RANK "i" +#define SCNiFAST32 __PRIFAST_RANK "i" +#define SCNiFAST64 __PRI64_RANK "i" + +#define SCNiMAX __PRI64_RANK "i" +#define SCNiPTR __PRIPTR_RANK "i" + +#define SCNo8 "hho" +#define SCNo16 "ho" +#define SCNo32 "o" +#define SCNo64 __PRI64_RANK "o" + +#define SCNoLEAST8 "hho" +#define SCNoLEAST16 "ho" +#define SCNoLEAST32 "o" +#define SCNoLEAST64 __PRI64_RANK "o" + +#define SCNoFAST8 "hho" +#define SCNoFAST16 __PRIFAST_RANK "o" +#define SCNoFAST32 __PRIFAST_RANK "o" +#define SCNoFAST64 __PRI64_RANK "o" + +#define SCNoMAX __PRI64_RANK "o" +#define SCNoPTR __PRIPTR_RANK "o" + +#define SCNu8 "hhu" +#define SCNu16 "hu" +#define SCNu32 "u" +#define SCNu64 __PRI64_RANK "u" + +#define SCNuLEAST8 "hhu" +#define SCNuLEAST16 "hu" +#define SCNuLEAST32 "u" +#define SCNuLEAST64 __PRI64_RANK "u" + +#define SCNuFAST8 "hhu" +#define SCNuFAST16 __PRIFAST_RANK "u" +#define SCNuFAST32 __PRIFAST_RANK "u" +#define SCNuFAST64 __PRI64_RANK "u" + +#define SCNuMAX __PRI64_RANK "u" +#define SCNuPTR __PRIPTR_RANK "u" + +#define SCNx8 "hhx" +#define SCNx16 "hx" +#define SCNx32 "x" +#define SCNx64 __PRI64_RANK "x" + +#define SCNxLEAST8 "hhx" +#define SCNxLEAST16 "hx" +#define SCNxLEAST32 "x" +#define SCNxLEAST64 __PRI64_RANK "x" + +#define SCNxFAST8 "hhx" +#define SCNxFAST16 __PRIFAST_RANK "x" +#define SCNxFAST32 __PRIFAST_RANK "x" +#define SCNxFAST64 __PRI64_RANK "x" + +#define SCNxMAX __PRI64_RANK "x" +#define SCNxPTR __PRIPTR_RANK "x" + +#endif + +#endif /* _INTTYPES_H */ diff --git a/klibc/include/klibc/compiler.h b/klibc/include/klibc/compiler.h new file mode 100644 index 0000000000..823996e777 --- /dev/null +++ b/klibc/include/klibc/compiler.h @@ -0,0 +1,119 @@ +/* + * klibc/compiler.h + * + * Various compiler features + */ + +#ifndef _KLIBC_COMPILER_H +#define _KLIBC_COMPILER_H + +/* Specific calling conventions */ +/* __cdecl is used when we want varadic and non-varadic functions to have + the same binary calling convention. */ +#ifdef __i386__ +# ifdef __GNUC__ +# define __cdecl __attribute__((cdecl,regparm(0))) +# else + /* Most other C compilers have __cdecl as a keyword */ +# endif +#else +# define __cdecl /* Meaningless on non-i386 */ +#endif + +/* How to declare a function that *must* be inlined */ +#ifdef __GNUC__ +# if __GNUC_MAJOR__ >= 3 +# define __must_inline static __inline__ __attribute__((always_inline)) +# else +# define __must_inline extern __inline__ +# endif +#else +# define __must_inline inline /* Just hope this works... */ +#endif + +/* How to declare a function that does not return */ +#ifdef __GNUC__ +# define __noreturn void __attribute__((noreturn)) +#else +# define __noreturn void +#endif + +/* "const" function: + + Many functions do not examine any values except their arguments, + and have no effects except the return value. Basically this is + just slightly more strict class than the `pure' attribute above, + since function is not allowed to read global memory. + + Note that a function that has pointer arguments and examines the + data pointed to must _not_ be declared `const'. Likewise, a + function that calls a non-`const' function usually must not be + `const'. It does not make sense for a `const' function to return + `void'. +*/ +#ifdef __GNUC__ +# define __constfunc __attribute__((const)) +#else +# define __constfunc +#endif +#undef __attribute_const__ +#define __attribute_const__ __constfunc + +/* "pure" function: + + Many functions have no effects except the return value and their + return value depends only on the parameters and/or global + variables. Such a function can be subject to common subexpression + elimination and loop optimization just as an arithmetic operator + would be. These functions should be declared with the attribute + `pure'. +*/ +#ifdef __GNUC__ +# define __purefunc __attribute__((pure)) +#else +# define __purefunc +#endif +#undef __attribute_pure__ +#define __attribute_pure__ __purefunc + +/* Format attribute */ +#ifdef __GNUC__ +# define __formatfunc(t,f,a) __attribute__((format(t,f,a))) +#else +# define __formatfunc(t,f,a) +#endif + +/* malloc() function (returns unaliased pointer) */ +#if defined(__GNUC__) && (__GNUC_MAJOR__ >= 3) +# define __mallocfunc __attribute__((malloc)) +#else +# define __mallocfunc +#endif + +/* likely/unlikely */ +#if defined(__GNUC__) && (__GNUC_MAJOR__ > 2 || (__GNUC_MAJOR__ == 2 && __GNUC_MINOR__ >= 95)) +# define __likely(x) __builtin_expect((x), 1) +# define __unlikely(x) __builtin_expect((x), 0) +#else +# define __likely(x) (x) +# define __unlikely(x) (x) +#endif + +/* Possibly unused function */ +#ifdef __GNUC__ +# define __unusedfunc __attribute__((unused)) +#else +# define __unusedfunc +#endif + +/* It's all user space... */ +#define __user + +/* The bitwise attribute: disallow arithmetric operations */ +#ifdef __CHECKER__ /* sparse only */ +# define __bitwise __attribute__((bitwise)) +#else +# define __bitwise +#endif + +#endif diff --git a/klibc/include/klibc/diverr.h b/klibc/include/klibc/diverr.h new file mode 100644 index 0000000000..4d8c8d36c2 --- /dev/null +++ b/klibc/include/klibc/diverr.h @@ -0,0 +1,16 @@ +/* + * klibc/diverr.h + */ + +#ifndef _KLIBC_DIVERR_H +#define _KLIBC_DIVERR_H + +#include + +static __inline__ void +__divide_error(void) +{ + raise(SIGFPE); +} + +#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/include/klibc/extern.h b/klibc/include/klibc/extern.h new file mode 100644 index 0000000000..f9c3467211 --- /dev/null +++ b/klibc/include/klibc/extern.h @@ -0,0 +1,14 @@ +/* + * klibc/extern.h + */ + +#ifndef _KLIBC_EXTERN_H +#define _KLIBC_EXTERN_H + +#ifdef __cplusplus +#define __extern extern "C" +#else +#define __extern extern +#endif + +#endif /* _KLIBC_EXTERN_H */ diff --git a/klibc/include/klibc/sysconfig.h b/klibc/include/klibc/sysconfig.h new file mode 100644 index 0000000000..ce01c23593 --- /dev/null +++ b/klibc/include/klibc/sysconfig.h @@ -0,0 +1,34 @@ +/* + * klibc/sysconfig.h + * + * Allows for definitions of some things which may be system-dependent + */ + +#ifndef _KLIBC_SYSCONFIG_H +#define _KLIBC_SYSCONFIG_H + +/* + * Define this to obtain memory using sbrk() instead + * of mmap(). This should make it friendlier on + * non-MMU architectures. This should become a + * per-architecture configurable. + */ +#undef MALLOC_USING_SBRK + +/* + * This is the minimum chunk size we will ask the kernel for using + * malloc(); this should be a multiple of the page size on all + * architectures. + */ +#define MALLOC_CHUNK_SIZE 65536 +#define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) + +/* + * This is the minimum alignment for the memory returned by sbrk(). + * It must be a power of 2. If MALLOC_USING_SBRK is defined it should + * be no smaller than the size of struct arena_header in malloc.h (4 + * pointers.) + */ +#define SBRK_ALIGNMENT 32 + +#endif /* _KLIBC_SYSCONFIG_H */ diff --git a/klibc/include/limits.h b/klibc/include/limits.h new file mode 100644 index 0000000000..f1532e5323 --- /dev/null +++ b/klibc/include/limits.h @@ -0,0 +1,40 @@ +/* + * limits.h + */ + +#ifndef _LIMITS_H +#define _LIMITS_H + +#define CHAR_BIT 8 +#define SHRT_BIT 16 +#define INT_BIT 32 +#define LONGLONG_BIT 64 + +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 + +#ifdef __CHAR_UNSIGNED__ +# define CHAR_MIN 0 +# define CHAR_MAX UCHAR_MAX +#else +# define CHAR_MIN SCHAR_MIN +# define CHAR_MAX SCHAR_MAX +#endif + +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 +#define USHRT_MAX 65535 + +#define INT_MIN (-2147483647-1) +#define INT_MAX 2147483647 +#define UINT_MAX 4294967295U + +#define LONGLONG_MIN (-9223372036854775807LL-1) +#define LONGLONG_MAX 9223372036854775807LL +#define ULONGLONG_MAX 18446744073709551615ULL + +#include +#include + +#endif /* _LIMITS_H */ diff --git a/klibc/include/net/if.h b/klibc/include/net/if.h new file mode 100644 index 0000000000..1aa8e7b90c --- /dev/null +++ b/klibc/include/net/if.h @@ -0,0 +1 @@ +#include diff --git a/klibc/include/net/if_arp.h b/klibc/include/net/if_arp.h new file mode 100644 index 0000000000..a25f1b4759 --- /dev/null +++ b/klibc/include/net/if_arp.h @@ -0,0 +1 @@ +#include diff --git a/klibc/include/net/if_ether.h b/klibc/include/net/if_ether.h new file mode 100644 index 0000000000..060ef22070 --- /dev/null +++ b/klibc/include/net/if_ether.h @@ -0,0 +1 @@ +#include diff --git a/klibc/include/net/if_packet.h b/klibc/include/net/if_packet.h new file mode 100644 index 0000000000..b5e8e0e11f --- /dev/null +++ b/klibc/include/net/if_packet.h @@ -0,0 +1 @@ +#include diff --git a/klibc/include/netinet/in.h b/klibc/include/netinet/in.h new file mode 100644 index 0000000000..27b778700e --- /dev/null +++ b/klibc/include/netinet/in.h @@ -0,0 +1,39 @@ +/* + * netinet/in.h + */ + +#ifndef _NETINET_IN_H +#define _NETINET_IN_H + +/* added this include by Mats Petersson */ +#include + +#include +#include +#include /* Must be included *before* */ +#include + +#ifndef htons +# define htons(x) __cpu_to_be16(x) +#endif +#ifndef ntohs +# define ntohs(x) __be16_to_cpu(x) +#endif +#ifndef htonl +# define htonl(x) __cpu_to_be32(x) +#endif +#ifndef ntohl +# define ntohl(x) __be32_to_cpu(x) +#endif +#ifndef htonq +# define htonq(x) __cpu_to_be64(x) +#endif +#ifndef ntohq +# define ntohq(x) __be64_to_cpu(x) +#endif + +#define IPPORT_RESERVED 1024 + +__extern int bindresvport (int sd, struct sockaddr_in *sin); + +#endif /* _NETINET_IN_H */ diff --git a/klibc/include/netinet/in6.h b/klibc/include/netinet/in6.h new file mode 100644 index 0000000000..46584ca627 --- /dev/null +++ b/klibc/include/netinet/in6.h @@ -0,0 +1,10 @@ +/* + * netinet/in6.h + */ + +#ifndef _NETINET_IN6_H +#define _NETINET_IN6_H + +#include + +#endif /* _NETINET_IN6_H */ diff --git a/klibc/include/netinet/ip.h b/klibc/include/netinet/ip.h new file mode 100644 index 0000000000..8aecbe66a3 --- /dev/null +++ b/klibc/include/netinet/ip.h @@ -0,0 +1,13 @@ +/* + * netinet/ip.h + */ + +#ifndef _NETINET_IP_H +#define _NETINET_IP_H + +#include +#include + +#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ + +#endif /* _NETINET_IP_H */ diff --git a/klibc/include/netinet/tcp.h b/klibc/include/netinet/tcp.h new file mode 100644 index 0000000000..bb5d307e98 --- /dev/null +++ b/klibc/include/netinet/tcp.h @@ -0,0 +1,11 @@ +/* + * netinet/tcp.h + */ + +#ifndef _NETINET_TCP_H +#define _NETINET_TCP_H + +#include /* Include *before* linux/tcp.h */ +#include + +#endif /* _NETINET_TCP_H */ diff --git a/klibc/include/netinet/udp.h b/klibc/include/netinet/udp.h new file mode 100644 index 0000000000..b809b4ee6e --- /dev/null +++ b/klibc/include/netinet/udp.h @@ -0,0 +1,19 @@ +/* + * netinet/udp.h + */ + +#ifndef _NETINET_UDP_H +#define _NETINET_UDP_H + +/* + * We would include linux/udp.h, but it brings in too much other stuff + */ + +struct udphdr { + __u16 source; + __u16 dest; + __u16 len; + __u16 check; +}; + +#endif /* _NETINET_UDP_H */ diff --git a/klibc/include/paths.h b/klibc/include/paths.h new file mode 100644 index 0000000000..a87831e74a --- /dev/null +++ b/klibc/include/paths.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)paths.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _PATHS_H_ +#define _PATHS_H_ + +/* Default search path. */ +#define _PATH_DEFPATH "/usr/bin:/bin" +/* All standard utilities path. */ +#define _PATH_STDPATH \ + "/usr/bin:/bin:/usr/sbin:/sbin" + +#define _PATH_BSHELL "/bin/sh" +#define _PATH_CONSOLE "/dev/console" +#define _PATH_CSHELL "/bin/csh" +#define _PATH_DEVDB "/var/run/dev.db" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_DRUM "/dev/drum" +#define _PATH_KLOG "/proc/kmsg" +#define _PATH_KMEM "/dev/kmem" +#define _PATH_LASTLOG "/var/log/lastlog" +#define _PATH_MAILDIR "/var/mail" +#define _PATH_MAN "/usr/share/man" +#define _PATH_MEM "/dev/mem" +#define _PATH_MNTTAB "/etc/fstab" +#define _PATH_MOUNTED "/etc/mtab" +#define _PATH_NOLOGIN "/etc/nologin" +#define _PATH_PRESERVE "/var/lib" +#define _PATH_RWHODIR "/var/spool/rwho" +#define _PATH_SENDMAIL "/usr/sbin/sendmail" +#define _PATH_SHADOW "/etc/shadow" +#define _PATH_SHELLS "/etc/shells" +#define _PATH_TTY "/dev/tty" +#define _PATH_UNIX "/boot/vmlinux" +#define _PATH_UTMP "/var/run/utmp" +#define _PATH_VI "/bin/vi" +#define _PATH_WTMP "/var/log/wtmp" + +/* Provide trailing slash, since mostly used for building pathnames. */ +#define _PATH_DEV "/dev/" +#define _PATH_TMP "/tmp/" +#define _PATH_VARDB "/var/db/" +#define _PATH_VARRUN "/var/run/" +#define _PATH_VARTMP "/var/tmp/" + +#endif /* !_PATHS_H_ */ diff --git a/klibc/include/poll.h b/klibc/include/poll.h new file mode 100644 index 0000000000..8710d92ebd --- /dev/null +++ b/klibc/include/poll.h @@ -0,0 +1,16 @@ +/* + * poll.h + */ + +#ifndef _POLL_H +#define _POLL_H + +#include +#include + +/* POSIX specifies "int" for the timeout, Linux seems to use long... */ + +typedef unsigned int nfds_t; +__extern int poll(struct pollfd *, nfds_t, long); + +#endif /* _POLL_H */ diff --git a/klibc/include/sched.h b/klibc/include/sched.h new file mode 100644 index 0000000000..fcf62a6e4f --- /dev/null +++ b/klibc/include/sched.h @@ -0,0 +1,34 @@ +/* + * sched.h + */ + +#ifndef _SCHED_H +#define _SCHED_H + +#include + +/* linux/sched.h is unusable; put the declarations we need here... */ + +#define SCHED_NORMAL 0 +#define SCHED_FIFO 1 +#define SCHED_RR 2 + +struct sched_param { + int sched_priority; +}; + +__extern int sched_setscheduler(pid_t, int, const struct sched_param *); +__extern int sched_yield(void); + +/* Raw interfaces to clone(2); only actually usable for non-VM-cloning */ +#ifdef __ia64__ +__extern pid_t __clone2(int, void *, void *); +static __inline__ pid_t __clone(int _f, void *_sp) +{ + return __clone2(_f, _sp, 0); +} +#else +__extern pid_t __clone(int, void *); +#endif + +#endif /* _SCHED_H */ diff --git a/klibc/include/setjmp.h b/klibc/include/setjmp.h new file mode 100644 index 0000000000..b504eb6d08 --- /dev/null +++ b/klibc/include/setjmp.h @@ -0,0 +1,43 @@ +/* + * setjmp.h + */ + +#ifndef _SETJMP_H +#define _SETJMP_H + +#include +#include +#include +#include + +#include + +__extern int setjmp(jmp_buf); +__extern __noreturn longjmp(jmp_buf, int); + +/* + Whose bright idea was it to add unrelated functionality to just about + the only function in the standard C library (setjmp) which cannot be + wrapped by an ordinary function wrapper? Anyway, the damage is done, + and therefore, this wrapper *must* be inline. However, gcc will + complain if this is an inline function for unknown reason, and + therefore sigsetjmp() needs to be a macro. +*/ + +struct __sigjmp_buf { + jmp_buf __jmpbuf; + sigset_t __sigs; +}; + +typedef struct __sigjmp_buf sigjmp_buf[1]; + +#define sigsetjmp(__env, __save) \ +({ \ + struct __sigjmp_buf *__e = (__env); \ + sigprocmask(0, NULL, &__e->__sigs); \ + setjmp(__e->__jmpbuf); \ +}) + +__extern __noreturn siglongjmp(sigjmp_buf, int); + +#endif /* _SETJMP_H */ diff --git a/klibc/include/signal.h b/klibc/include/signal.h new file mode 100644 index 0000000000..1b439077f2 --- /dev/null +++ b/klibc/include/signal.h @@ -0,0 +1,81 @@ +/* + * signal.h + */ + +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include +#include +#include /* For memset() */ +#include /* For LONG_BIT */ +#include +#include + +#include + +/* glibc seems to use sig_atomic_t as "int" pretty much on all architectures. + Do the same, but allow the architecture to override. */ +#ifdef _KLIBC_HAS_ARCH_SIG_ATOMIC_T +typedef int sig_atomic_t; +#endif + +/* Some architectures don't define these */ +#ifndef SA_RESETHAND +# define SA_RESETHAND SA_ONESHOT +#endif +#ifndef SA_NODEFER +# define SA_NODEFER SA_NOMASK +#endif +#ifndef NSIG +# define NSIG _NSIG +#endif + +__extern const char * const sys_siglist[]; + +/* This assumes sigset_t is either an unsigned long or an array of such, + and that _NSIG_BPW in the kernel is always LONG_BIT */ + +static __inline__ int sigemptyset(sigset_t *__set) +{ + memset(__set, 0, sizeof *__set); + return 0; +} +static __inline__ int sigfillset(sigset_t *__set) +{ + memset(__set, ~0, sizeof *__set); + return 0; +} +static __inline__ int sigaddset(sigset_t *__set, int __signum) +{ + unsigned long *__lset = (unsigned long *)__set; + __lset[__signum/LONG_BIT] |= 1UL << (__signum%LONG_BIT); + return 0; +} +static __inline__ int sigdelset(sigset_t *__set, int __signum) +{ + unsigned long *__lset = (unsigned long *)__set; + __lset[__signum/LONG_BIT] &= ~(1UL << (__signum%LONG_BIT)); + return 0; +} +static __inline__ int sigismember(sigset_t *__set, int __signum) +{ + unsigned long *__lset = (unsigned long *)__set; + return (int)((__lset[__signum/LONG_BIT] >> (__signum%LONG_BIT)) & 1); +} + +__extern __sighandler_t __signal(int, __sighandler_t, int); +__extern __sighandler_t sysv_signal(int, __sighandler_t); +__extern __sighandler_t bsd_signal(int, __sighandler_t); +__extern int sigaction(int, const struct sigaction *, struct sigaction *); +__extern int sigprocmask(int, const sigset_t *, sigset_t *); +__extern int sigpending(sigset_t *); +__extern int sigsuspend(const sigset_t *); +__extern int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); +__extern int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); +__extern int rt_sigpending(sigset_t *, size_t); +__extern int rt_sigsuspend(const sigset_t *, size_t); +__extern int raise(int); +__extern int kill(pid_t, int); + +#endif /* _SIGNAL_H */ diff --git a/klibc/include/stdarg.h b/klibc/include/stdarg.h new file mode 100644 index 0000000000..cc324b825d --- /dev/null +++ b/klibc/include/stdarg.h @@ -0,0 +1,14 @@ +/* + * stdarg.h + * + * This is just a wrapper for the gcc one, but defines va_copy() + * even if gcc doesn't. + */ + +/* Note: the _STDARG_H macro belongs to the gcc header... */ +#include_next + +/* Older gcc considers this an extension, so it's double underbar only */ +#ifndef va_copy +#define va_copy(d,s) __va_copy(d,s) +#endif diff --git a/klibc/include/stddef.h b/klibc/include/stddef.h new file mode 100644 index 0000000000..125d2352ec --- /dev/null +++ b/klibc/include/stddef.h @@ -0,0 +1,24 @@ +/* + * stddef.h + */ + +#ifndef _STDDEF_H +#define _STDDEF_H + +#ifndef __KLIBC__ +# define __KLIBC__ 1 +#endif + +#include + +#undef NULL +#ifdef __cplusplus +# define NULL 0 +#else +# define NULL ((void *)0) +#endif + +#undef offsetof +#define offsetof(t,m) ((size_t)&((t *)0)->m) + +#endif /* _STDDEF_H */ diff --git a/klibc/include/stdint.h b/klibc/include/stdint.h new file mode 100644 index 0000000000..47fec18594 --- /dev/null +++ b/klibc/include/stdint.h @@ -0,0 +1,116 @@ +/* + * stdint.h + */ + +#ifndef _STDINT_H +#define _STDINT_H + +#include + +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; + +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +typedef int8_t int_fast8_t; +typedef int64_t int_fast64_t; + +typedef uint8_t uint_fast8_t; +typedef uint64_t uint_fast64_t; + +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) + +#define INT8_MIN (-128) +#define INT16_MIN (-32768) +#define INT32_MIN (-2147483647-1) +#define INT64_MIN (__INT64_C(-9223372036854775807)-1) + +#define INT8_MAX (127) +#define INT16_MAX (32767) +#define INT32_MAX (2147483647) +#define INT64_MAX (__INT64_C(9223372036854775807)) + +#define UINT8_MAX (255U) +#define UINT16_MAX (65535U) +#define UINT32_MAX (4294967295U) +#define UINT64_MAX (__UINT64_C(18446744073709551615)) + +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST64_MIN INT64_MIN + +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MAX INT64_MAX + +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST64_MIN INT64_MIN + +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST64_MAX INT64_MAX + +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST64_MAX UINT64_MAX + +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +#include + +#endif + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) + +#define INT8_C(c) c +#define INT16_C(c) c +#define INT32_C(c) c +#define INT64_C(c) __INT64_C(c) + +#define UINT8_C(c) c ## U +#define UINT16_C(c) c ## U +#define UINT32_C(c) c ## U +#define UINT64_C(c) __UINT64_C(c) + +#define INT_LEAST8_C(c) INT8_C(c) +#define INT_LEAST16_C(c) INT16_C(c) +#define INT_LEAST32_C(c) INT32_C(c) +#define INT_LEAST64_C(c) INT64_C(c) + +#define UINT_LEAST8_C(c) UINT8_C(c) +#define UINT_LEAST16_C(c) UINT16_C(c) +#define UINT_LEAST32_C(c) UINT32_C(c) +#define UINT_LEAST64_C(c) UINT64_C(c) + +#define INT_FAST8_C(c) INT8_C(c) +#define INT_FAST64_C(c) INT64_C(c) + +#define UINT_FAST8_C(c) UINT8_C(c) +#define UINT_FAST64_C(c) UINT64_C(c) + +#define INTMAX_C(c) INT64_C(c) +#define UINTMAX_C(c) UINT64_C(c) + +#include + +#endif + +/* Keep the kernel from trying to define these types... */ +#define __BIT_TYPES_DEFINED__ + +#endif /* _STDINT_H */ diff --git a/klibc/include/stdio.h b/klibc/include/stdio.h new file mode 100644 index 0000000000..e00fac4d5e --- /dev/null +++ b/klibc/include/stdio.h @@ -0,0 +1,123 @@ +/* + * stdio.h + */ + +#ifndef _STDIO_H +#define _STDIO_H + +#include +#include +#include +#include + +/* This structure doesn't really exist, but it gives us something + to define FILE * with */ +struct _IO_file; +typedef struct _IO_file FILE; + +#ifndef EOF +# define EOF (-1) +#endif + +#ifndef BUFSIZ +# define BUFSIZ 4096 +#endif + +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 + +/* + * Convert between a FILE * and a file descriptor. We don't actually + * have any in-memory data, so we just abuse the pointer itself to + * hold the data. Note, however, that for file descriptors, -1 is + * error and 0 is a valid value; for FILE *, NULL (0) is error and + * non-NULL are valid. + */ +static __inline__ int fileno(FILE *__f) +{ + /* This should really be intptr_t, but size_t should be the same size */ + return (int)(size_t)__f - 1; +} + +/* This is a macro so it can be used as initializer */ +#define __create_file(__fd) ((FILE *)(size_t)((__fd) + 1)) + +#define stdin __create_file(0) +#define stdout __create_file(1) +#define stderr __create_file(2) + +__extern FILE *fopen(const char *, const char *); + +static __inline__ FILE *fdopen(int __fd, const char *__m) +{ + (void)__m; return __create_file(__fd); +} +static __inline__ int fclose(FILE *__f) +{ + extern int close(int); + return close(fileno(__f)); +} +static __inline__ int fseek(FILE *__f, off_t __o, int __w) +{ + extern off_t lseek(int, off_t, int); + return (lseek(fileno(__f), __o, __w) == (off_t)-1) ? -1 : 0; +} +static __inline__ off_t ftell(FILE *__f) +{ + extern off_t lseek(int, off_t, int); + return lseek(fileno(__f), 0, SEEK_CUR); +} + +__extern int fputs(const char *, FILE *); +__extern int puts(const char *); +__extern int fputc(int, FILE *); +#define putc(c,f) fputc((c),(f)) +#define putchar(c) fputc((c),stdout) + +__extern int fgetc(FILE *); +__extern char * fgets(char *, int, FILE *); +#define getc(f) fgetc(f) + +__extern size_t _fread(void *, size_t, FILE *); +__extern size_t _fwrite(const void *, size_t, FILE *); + +#ifndef __NO_FREAD_FWRITE_INLINES +extern __inline__ size_t +fread(void *__p, size_t __s, size_t __n, FILE *__f) +{ + return _fread(__p, __s*__n, __f)/__s; +} + +extern __inline__ size_t +fwrite(void *__p, size_t __s, size_t __n, FILE *__f) +{ + return _fwrite(__p, __s*__n, __f)/__s; +} +#endif + +__extern int printf(const char *, ...); +__extern int vprintf(const char *, va_list); +__extern int fprintf(FILE *, const char *, ...); +__extern int vfprintf(FILE *, const char *, va_list); +__extern int sprintf(char *, const char *, ...); +__extern int vsprintf(char *, const char *, va_list); +__extern int snprintf(char *, size_t n, const char *, ...); +__extern int vsnprintf(char *, size_t n, const char *, va_list); + +/* No buffering, so no flushing needed */ +extern __inline__ int +fflush(FILE *__f) +{ + (void)__f; + return 0; +} + +__extern int sscanf(const char *, const char *, ...); +__extern int vsscanf(const char *, const char *, va_list); + +__extern void perror(const char *); + +__extern int rename(const char *, const char *); + +#endif /* _STDIO_H */ diff --git a/klibc/include/stdlib.h b/klibc/include/stdlib.h new file mode 100644 index 0000000000..be4e76ed9f --- /dev/null +++ b/klibc/include/stdlib.h @@ -0,0 +1,90 @@ +/* + * stdlib.h + */ + +#ifndef _STDLIB_H +#define _STDLIB_H + +#include +#include +#include + +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +static __inline__ __noreturn _Exit(int __n) { + __extern __noreturn _exit(int); + _exit(__n); + for(;;); /* Some gcc versions are stupid */ +} +__extern __noreturn abort(void); +static __inline__ int abs(int __n) { + return (__n < 0) ? -__n : __n; +} +__extern int atexit(void (*)(void)); +__extern int on_exit(void (*)(int, void *), void *); +__extern int atoi(const char *); +__extern long atol(const char *); +__extern long long atoll(const char *); +__extern __noreturn exit(int); +__extern void free(void *); +static __inline__ long labs(long __n) { + return (__n < 0L) ? -__n : __n; +} + +static __inline__ long long llabs(long long __n) { + return (__n < 0LL) ? -__n : __n; +} + +__extern __mallocfunc void *malloc(size_t); +__extern __mallocfunc void *calloc(size_t, size_t); +__extern __mallocfunc void *realloc(void *, size_t); +__extern long strtol(const char *, char **, int); +__extern long long strtoll(const char *, char **, int); +__extern unsigned long strtoul(const char *, char **, int); +__extern unsigned long long strtoull(const char *, char **, int); + +__extern char *getenv(const char *); +__extern int putenv(const char *); +__extern int setenv(const char *, const char *, int); +__extern int unsetenv(const char *); + +__extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); + + +__extern long jrand48(unsigned short *); +__extern long mrand48(void); +__extern long nrand48(unsigned short *); +__extern long lrand48(void); +__extern unsigned short *seed48(const unsigned short *); +__extern void srand48(long); + +#define RAND_MAX 0x7fffffff +static __inline__ int rand(void) { + return (int)lrand48(); +} +static __inline__ void srand(unsigned int __s) { + srand48(__s); +} +static __inline__ long random(void) +{ + return lrand48(); +} +static __inline__ void srandom(unsigned int __s) +{ + srand48(__s); +} + +/* Basic PTY functions. These only work if devpts is mounted! */ + +__extern int unlockpt(int); +__extern char *ptsname(int); +__extern int getpt(void); + +static __inline__ int grantpt(int __fd) +{ + (void)__fd; + return 0; /* devpts does this all for us! */ +} + +#endif /* _STDLIB_H */ diff --git a/klibc/include/string.h b/klibc/include/string.h new file mode 100644 index 0000000000..3bbb217e98 --- /dev/null +++ b/klibc/include/string.h @@ -0,0 +1,43 @@ +/* + * string.h + */ + +#ifndef _STRING_H +#define _STRING_H + +#include +#include + +__extern void *memccpy(void *, const void *, int, size_t); +__extern void *memchr(const void *, int, size_t); +__extern int memcmp(const void *, const void *, size_t); +__extern void *memcpy(void *, const void *, size_t); +__extern void *memmove(void *, const void *, size_t); +__extern void *memset(void *, int, size_t); +__extern void *memmem(const void *, size_t, const void *, size_t); +__extern void memswap(void *, void *, size_t); +__extern int strcasecmp(const char *, const char *); +__extern int strncasecmp(const char *, const char *, size_t); +__extern char *strcat(char *, const char *); +__extern char *strchr(const char *, int); +__extern int strcmp(const char *, const char *); +__extern char *strcpy(char *, const char *); +__extern size_t strcspn(const char *, const char *); +__extern char *strdup(const char *); +__extern char *strndup(const char *, size_t); +__extern char *strerror(int); +__extern size_t strlen(const char *); +__extern size_t strnlen(const char *, size_t); +__extern char *strncat(char *, const char *, size_t); +__extern size_t strlcat(char *, const char *, size_t); +__extern int strncmp(const char *, const char *, size_t); +__extern char *strncpy(char *, const char *, size_t); +__extern size_t strlcpy(char *, const char *, size_t); +__extern char *strpbrk(const char *, const char *); +__extern char *strrchr(const char *, int); +__extern char *strsep(char **, const char *); +__extern size_t strspn(const char *, const char *); +__extern char *strstr(const char *, const char *); +__extern char *strtok(char *, const char *); + +#endif /* _STRING_H */ diff --git a/klibc/include/sys/dirent.h b/klibc/include/sys/dirent.h new file mode 100644 index 0000000000..eec470ce1a --- /dev/null +++ b/klibc/include/sys/dirent.h @@ -0,0 +1,21 @@ +/* + * sys/dirent.h + */ + +#ifndef _SYS_DIRENT_H +#define _SYS_DIRENT_H + +#include + +/* The kernel calls this struct dirent64 */ +struct dirent { + uint64_t d_ino; + int64_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[256]; +}; + +__extern int getdents(unsigned int, struct dirent *, unsigned int); + +#endif /* _SYS_DIRENT_H */ diff --git a/klibc/include/sys/elf32.h b/klibc/include/sys/elf32.h new file mode 100644 index 0000000000..652de5bc5f --- /dev/null +++ b/klibc/include/sys/elf32.h @@ -0,0 +1,115 @@ +/* + * sys/elf32.h + */ + +#ifndef _SYS_ELF32_H +#define _SYS_ELF32_H + +#include + +/* ELF standard typedefs (yet more proof that was way overdue) */ +typedef uint16_t Elf32_Half; +typedef int16_t Elf32_SHalf; +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; + +typedef uint32_t Elf32_Off; +typedef uint32_t Elf32_Addr; +typedef uint16_t Elf32_Section; + +/* Dynamic header */ + +typedef struct elf32_dyn { + Elf32_Sword d_tag; + union{ + Elf32_Sword d_val; + Elf32_Addr d_ptr; + } d_un; +} Elf32_Dyn; + +/* Relocations */ + +#define ELF32_R_SYM(x) ((x) >> 8) +#define ELF32_R_TYPE(x) ((x) & 0xff) + +typedef struct elf32_rel { + Elf32_Addr r_offset; + Elf32_Word r_info; +} Elf32_Rel; + +typedef struct elf32_rela { + Elf32_Addr r_offset; + Elf32_Word r_info; + Elf32_Sword r_addend; +} Elf32_Rela; + +/* Symbol */ + +typedef struct elf32_sym { + Elf32_Word st_name; + Elf32_Addr st_value; + Elf32_Word st_size; + unsigned char st_info; + unsigned char st_other; + Elf32_Half st_shndx; +} Elf32_Sym; + +/* Main file header */ + +typedef struct elf32_hdr { + unsigned char e_ident[EI_NIDENT]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} Elf32_Ehdr; + +/* Program header */ + +typedef struct elf32_phdr { + Elf32_Word p_type; + Elf32_Off p_offset; + Elf32_Addr p_vaddr; + Elf32_Addr p_paddr; + Elf32_Word p_filesz; + Elf32_Word p_memsz; + Elf32_Word p_flags; + Elf32_Word p_align; +} Elf32_Phdr; + + +/* Section header */ + +typedef struct elf32_shdr { + Elf32_Word sh_name; + Elf32_Word sh_type; + Elf32_Word sh_flags; + Elf32_Addr sh_addr; + Elf32_Off sh_offset; + Elf32_Word sh_size; + Elf32_Word sh_link; + Elf32_Word sh_info; + Elf32_Word sh_addralign; + Elf32_Word sh_entsize; +} Elf32_Shdr; + +/* Note header */ +typedef struct elf32_note { + Elf32_Word n_namesz; /* Name size */ + Elf32_Word n_descsz; /* Content size */ + Elf32_Word n_type; /* Content type */ +} Elf32_Nhdr; + +#endif /* _SYS_ELF32_H */ + diff --git a/klibc/include/sys/elf64.h b/klibc/include/sys/elf64.h new file mode 100644 index 0000000000..750ddac4d9 --- /dev/null +++ b/klibc/include/sys/elf64.h @@ -0,0 +1,115 @@ +/* + * sys/elf64.h + */ + +#ifndef _SYS_ELF64_H +#define _SYS_ELF64_H + +#include + +/* ELF standard typedefs (yet more proof that was way overdue) */ +typedef uint16_t Elf64_Half; +typedef int16_t Elf64_SHalf; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +typedef uint64_t Elf64_Off; +typedef uint64_t Elf64_Addr; +typedef uint16_t Elf64_Section; + +/* Dynamic header */ + +typedef struct elf64_dyn { + Elf64_Sxword d_tag; + union{ + Elf64_Xword d_val; + Elf64_Addr d_ptr; + } d_un; +} Elf64_Dyn; + +/* Relocations */ + +#define ELF64_R_SYM(x) ((x) >> 32) +#define ELF64_R_TYPE(x) ((x) & 0xffffffff) + +typedef struct elf64_rel { + Elf64_Addr r_offset; + Elf64_Xword r_info; +} Elf64_Rel; + +typedef struct elf64_rela { + Elf64_Addr r_offset; + Elf64_Xword r_info; + Elf64_Sxword r_addend; +} Elf64_Rela; + +/* Symbol */ + +typedef struct elf64_sym { + Elf64_Word st_name; + unsigned char st_info; + unsigned char st_other; + Elf64_Half st_shndx; + Elf64_Addr st_value; + Elf64_Xword st_size; +} Elf64_Sym; + +/* Main file header */ + +typedef struct elf64_hdr { + unsigned char e_ident[EI_NIDENT]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} Elf64_Ehdr; + +/* Program header */ + +typedef struct elf64_phdr { + Elf64_Word p_type; + Elf64_Word p_flags; + Elf64_Off p_offset; + Elf64_Addr p_vaddr; + Elf64_Addr p_paddr; + Elf64_Xword p_filesz; + Elf64_Xword p_memsz; + Elf64_Xword p_align; +} Elf64_Phdr; + + +/* Section header */ + +typedef struct elf64_shdr { + Elf64_Word sh_name; + Elf64_Word sh_type; + Elf64_Xword sh_flags; + Elf64_Addr sh_addr; + Elf64_Off sh_offset; + Elf64_Xword sh_size; + Elf64_Word sh_link; + Elf64_Word sh_info; + Elf64_Xword sh_addralign; + Elf64_Xword sh_entsize; +} Elf64_Shdr; + +/* Note header */ +typedef struct elf64_note { + Elf64_Word n_namesz; /* Name size */ + Elf64_Word n_descsz; /* Content size */ + Elf64_Word n_type; /* Content type */ +} Elf64_Nhdr; + +#endif /* _SYS_ELF64_H */ + diff --git a/klibc/include/sys/elfcommon.h b/klibc/include/sys/elfcommon.h new file mode 100644 index 0000000000..d25804e483 --- /dev/null +++ b/klibc/include/sys/elfcommon.h @@ -0,0 +1,188 @@ +/* + * sys/elfcommon.h + */ + +#ifndef _SYS_ELFCOMMON_H +#define _SYS_ELFCOMMON_H + +#include + +/* Segment types */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOOS 0x60000000 +#define PT_HIOS 0x6fffffff +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff +#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */ + +/* ELF file types */ +#define ET_NONE 0 +#define ET_REL 1 +#define ET_EXEC 2 +#define ET_DYN 3 +#define ET_CORE 4 +#define ET_LOPROC 0xff00 +#define ET_HIPROC 0xffff + +/* ELF machine types */ +#define EM_NONE 0 +#define EM_M32 1 +#define EM_SPARC 2 +#define EM_386 3 +#define EM_68K 4 +#define EM_88K 5 +#define EM_486 6 /* Not used in Linux at least */ +#define EM_860 7 +#define EM_MIPS 8 /* R3k, bigendian(?) */ +#define EM_MIPS_RS4_BE 10 /* R4k BE */ +#define EM_PARISC 15 +#define EM_SPARC32PLUS 18 +#define EM_PPC 20 +#define EM_PPC64 21 +#define EM_S390 22 +#define EM_SH 42 +#define EM_SPARCV9 43 /* v9 = SPARC64 */ +#define EM_H8_300H 47 +#define EM_H8S 48 +#define EM_IA_64 50 /* Itanic */ +#define EM_X86_64 62 +#define EM_CRIS 76 +#define EM_V850 87 +#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */ +#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */ +#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ + +/* Dynamic type values */ +#define DT_NULL 0 +#define DT_NEEDED 1 +#define DT_PLTRELSZ 2 +#define DT_PLTGOT 3 +#define DT_HASH 4 +#define DT_STRTAB 5 +#define DT_SYMTAB 6 +#define DT_RELA 7 +#define DT_RELASZ 8 +#define DT_RELAENT 9 +#define DT_STRSZ 10 +#define DT_SYMENT 11 +#define DT_INIT 12 +#define DT_FINI 13 +#define DT_SONAME 14 +#define DT_RPATH 15 +#define DT_SYMBOLIC 16 +#define DT_REL 17 +#define DT_RELSZ 18 +#define DT_RELENT 19 +#define DT_PLTREL 20 +#define DT_DEBUG 21 +#define DT_TEXTREL 22 +#define DT_JMPREL 23 +#define DT_LOPROC 0x70000000 +#define DT_HIPROC 0x7fffffff + +/* Auxilliary table entries */ +#define AT_NULL 0 /* end of vector */ +#define AT_IGNORE 1 /* entry should be ignored */ +#define AT_EXECFD 2 /* file descriptor of program */ +#define AT_PHDR 3 /* program headers for program */ +#define AT_PHENT 4 /* size of program header entry */ +#define AT_PHNUM 5 /* number of program headers */ +#define AT_PAGESZ 6 /* system page size */ +#define AT_BASE 7 /* base address of interpreter */ +#define AT_FLAGS 8 /* flags */ +#define AT_ENTRY 9 /* entry point of program */ +#define AT_NOTELF 10 /* program is not ELF */ +#define AT_UID 11 /* real uid */ +#define AT_EUID 12 /* effective uid */ +#define AT_GID 13 /* real gid */ +#define AT_EGID 14 /* effective gid */ +#define AT_PLATFORM 15 /* string identifying CPU for optimizations */ +#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ +#define AT_CLKTCK 17 /* frequency at which times() increments */ +/* 18..22 = ? */ +#define AT_SECURE 23 /* secure mode boolean */ + +/* Program header permission flags */ +#define PF_X 0x1 +#define PF_W 0x2 +#define PF_R 0x4 + +/* Section header types */ +#define SHT_NULL 0 +#define SHT_PROGBITS 1 +#define SHT_SYMTAB 2 +#define SHT_STRTAB 3 +#define SHT_RELA 4 +#define SHT_HASH 5 +#define SHT_DYNAMIC 6 +#define SHT_NOTE 7 +#define SHT_NOBITS 8 +#define SHT_REL 9 +#define SHT_SHLIB 10 +#define SHT_DYNSYM 11 +#define SHT_NUM 12 +#define SHT_LOPROC 0x70000000 +#define SHT_HIPROC 0x7fffffff +#define SHT_LOUSER 0x80000000 +#define SHT_HIUSER 0xffffffff + +/* Section header flags */ +#define SHF_WRITE 0x1 +#define SHF_ALLOC 0x2 +#define SHF_EXECINSTR 0x4 +#define SHF_MASKPROC 0xf0000000 + +/* Special section numbers */ +#define SHN_UNDEF 0 +#define SHN_LORESERVE 0xff00 +#define SHN_LOPROC 0xff00 +#define SHN_HIPROC 0xff1f +#define SHN_ABS 0xfff1 +#define SHN_COMMON 0xfff2 +#define SHN_HIRESERVE 0xffff + +/* Lenght of magic at the start of a file */ +#define EI_NIDENT 16 + +/* Magic number constants... */ +#define EI_MAG0 0 /* e_ident[] indexes */ +#define EI_MAG1 1 +#define EI_MAG2 2 +#define EI_MAG3 3 +#define EI_CLASS 4 +#define EI_DATA 5 +#define EI_VERSION 6 +#define EI_OSABI 7 +#define EI_PAD 8 + +#define ELFMAG0 0x7f /* EI_MAG */ +#define ELFMAG1 'E' +#define ELFMAG2 'L' +#define ELFMAG3 'F' +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define ELFCLASSNONE 0 /* EI_CLASS */ +#define ELFCLASS32 1 +#define ELFCLASS64 2 +#define ELFCLASSNUM 3 + +#define ELFDATANONE 0 /* e_ident[EI_DATA] */ +#define ELFDATA2LSB 1 +#define ELFDATA2MSB 2 + +#define EV_NONE 0 /* e_version, EI_VERSION */ +#define EV_CURRENT 1 +#define EV_NUM 2 + +#define ELFOSABI_NONE 0 +#define ELFOSABI_LINUX 3 + +#endif /* _SYS_ELFCOMMON_H */ + diff --git a/klibc/include/sys/fsuid.h b/klibc/include/sys/fsuid.h new file mode 100644 index 0000000000..823486b776 --- /dev/null +++ b/klibc/include/sys/fsuid.h @@ -0,0 +1,14 @@ +/* + * sys/fsuid.h + */ + +#ifndef _SYS_FSUID_H +#define _SYS_FSUID_H + +#include +#include + +__extern int setfsuid(uid_t); +__extern int setfsgid(gid_t); + +#endif /* _SYS_FSUID_H */ diff --git a/klibc/include/sys/ioctl.h b/klibc/include/sys/ioctl.h new file mode 100644 index 0000000000..b0cee4c02c --- /dev/null +++ b/klibc/include/sys/ioctl.h @@ -0,0 +1,14 @@ +/* + * sys/ioctl.h + */ + +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H + +#include +#include +#include + +__extern int ioctl(int, int, void *); + +#endif /* _SYS_IOCTL_H */ diff --git a/klibc/include/sys/klog.h b/klibc/include/sys/klog.h new file mode 100644 index 0000000000..0fc5f5d945 --- /dev/null +++ b/klibc/include/sys/klog.h @@ -0,0 +1,24 @@ +/* + * sys/klog.h + */ + +#ifndef _SYS_KLOG_H +#define _SYS_KLOG_H + +#include + +#define KLOG_CLOSE 0 +#define KLOG_OPEN 1 +#define KLOG_READ 2 +#define KLOG_READ_ALL 3 +#define KLOG_READ_CLEAR 4 +#define KLOG_CLEAR 5 +#define KLOG_DISABLE 6 +#define KLOG_ENABLE 7 +#define KLOG_SETLEVEL 8 +#define KLOG_UNREADSIZE 9 +#define KLOG_WRITE 10 + +__extern int klogctl(int, char *, int); + +#endif /* _SYS_KLOG_H */ diff --git a/klibc/include/sys/mman.h b/klibc/include/sys/mman.h new file mode 100644 index 0000000000..7f8f3e2f96 --- /dev/null +++ b/klibc/include/sys/mman.h @@ -0,0 +1,25 @@ +/* + * sys/mman.h + */ + +#ifndef _SYS_MMAN_H +#define _SYS_MMAN_H + +#include +#include +#include +#include /* For PAGE_SIZE */ + +#define MAP_FAILED ((void *)-1) + +__extern void *mmap(void *, size_t, int, int, int, off_t); +__extern int munmap(void *, size_t); +__extern void *mremap(void *, size_t, size_t, unsigned long); +__extern int msync(const void *, size_t, int); +__extern int mprotect(const void *, size_t, int); +__extern int mlockall(int); +__extern int munlockall(void); +__extern int mlock(const void *, size_t); +__extern int munlock(const void *, size_t); + +#endif /* _SYS_MMAN_H */ diff --git a/klibc/include/sys/mount.h b/klibc/include/sys/mount.h new file mode 100644 index 0000000000..313c90ec0e --- /dev/null +++ b/klibc/include/sys/mount.h @@ -0,0 +1,55 @@ +/* + * sys/mount.h + */ + +#ifndef _SYS_MOUNT_H +#define _SYS_MOUNT_H + +#include + +/* + * These are the fs-independent mount-flags: up to 32 flags are supported + */ +#define MS_RDONLY 1 /* Mount read-only */ +#define MS_NOSUID 2 /* Ignore suid and sgid bits */ +#define MS_NODEV 4 /* Disallow access to device special files */ +#define MS_NOEXEC 8 /* Disallow program execution */ +#define MS_SYNCHRONOUS 16 /* Writes are synced at once */ +#define MS_REMOUNT 32 /* Alter flags of a mounted FS */ +#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ +#define MS_DIRSYNC 128 /* Directory modifications are synchronous */ +#define MS_NOATIME 1024 /* Do not update access times. */ +#define MS_NODIRATIME 2048 /* Do not update directory access times */ +#define MS_BIND 4096 +#define MS_MOVE 8192 +#define MS_REC 16384 +#define MS_VERBOSE 32768 +#define MS_NOUSER (1<<31) + +/* + * Superblock flags that can be altered by MS_REMOUNT + */ +#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|MS_NODIRATIME) + +/* + * Old magic mount flag and mask + */ +#define MS_MGC_VAL 0xC0ED0000 +#define MS_MGC_MSK 0xffff0000 + +/* + * umount2() flags + */ +#define MNT_FORCE 1 + +/* + * Prototypes + */ +__extern int mount(const char *, const char *, + const char *, unsigned long, + const void *); +__extern int umount(const char *); +__extern int umount2(const char *, int); +__extern int pivot_root(const char *, const char *); + +#endif /* _SYS_MOUNT_H */ diff --git a/klibc/include/sys/param.h b/klibc/include/sys/param.h new file mode 100644 index 0000000000..63a0661f43 --- /dev/null +++ b/klibc/include/sys/param.h @@ -0,0 +1,11 @@ +/* + * sys/param.h + */ + +#ifndef _SYS_PARAM_H +#define _SYS_PARAM_H + +#include +#include + +#endif /* _SYS_PARAM_H */ diff --git a/klibc/include/sys/reboot.h b/klibc/include/sys/reboot.h new file mode 100644 index 0000000000..eaf56610d7 --- /dev/null +++ b/klibc/include/sys/reboot.h @@ -0,0 +1,25 @@ +/* + * sys/reboot.h + */ + +#ifndef _SYS_REBOOT_H +#define _SYS_REBOOT_H + +#include +#include + +/* glibc names these constants differently; allow both versions */ + +#define RB_AUTOBOOT LINUX_REBOOT_CMD_RESTART +#define RB_HALT_SYSTEM LINUX_REBOOT_CMD_HALT +#define RB_ENABLE_CAD LINUX_REBOOT_CMD_CAD_ON +#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF +#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF + +/* glibc-ish one-argument version */ +__extern int reboot(int); + +/* Native four-argument system call */ +__extern int __reboot(int, int, int, void *); + +#endif /* _SYS_REBOOT_H */ diff --git a/klibc/include/sys/resource.h b/klibc/include/sys/resource.h new file mode 100644 index 0000000000..ef14bde9f6 --- /dev/null +++ b/klibc/include/sys/resource.h @@ -0,0 +1,15 @@ +/* + * sys/resource.h + */ + +#ifndef _SYS_RESOURCE_H +#define _SYS_RESOURCE_H + +#include +#include /* MUST be included before linux/resource.h */ +#include + +__extern int getpriority(int, int); +__extern int setpriority(int, int, int); + +#endif /* _SYS_RESOURCE_H */ diff --git a/klibc/include/sys/select.h b/klibc/include/sys/select.h new file mode 100644 index 0000000000..7caf8c931b --- /dev/null +++ b/klibc/include/sys/select.h @@ -0,0 +1,13 @@ +/* + * sys/select.h + */ + +#ifndef _SYS_SELECT_H +#define _SYS_SELECT_H + +#include +#include + +__extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); + +#endif /* _SYS_SELECT_H */ diff --git a/klibc/include/sys/socket.h b/klibc/include/sys/socket.h new file mode 100644 index 0000000000..cbc2b89591 --- /dev/null +++ b/klibc/include/sys/socket.h @@ -0,0 +1,50 @@ +/* + * sys/socket.h + */ + +#ifndef _SYS_SOCKET_H +#define _SYS_SOCKET_H + +#include +#include +#include + +/* For some reason these may be protected by __KERNEL__ in asm/socket.h */ +#ifndef SOCK_STREAM +# define SOCK_STREAM 1 +# define SOCK_DGRAM 2 +# define SOCK_RAW 3 +# define SOCK_RDM 4 +# define SOCK_SEQPACKET 5 +# define SOCK_PACKET 10 +#endif + +#ifdef __i386__ +# define __socketcall __extern __cdecl +#else +# define __socketcall __extern +#endif + +typedef int socklen_t; + +__socketcall int socket(int, int, int); +__socketcall int bind(int, struct sockaddr *, int); +__socketcall int connect(int, struct sockaddr *, socklen_t); +__socketcall int listen(int, int); +__socketcall int accept(int, struct sockaddr *, socklen_t *); +__socketcall int getsockname(int, struct sockaddr *, socklen_t *); +__socketcall int getpeername(int, struct sockaddr *, socklen_t *); +__socketcall int socketpair(int, int, int, int *); +__extern int send(int, const void *, size_t, unsigned int); +__socketcall int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); +__extern int recv(int, void *, size_t, unsigned int); +__socketcall int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *); +__socketcall int shutdown(int, int); +__socketcall int setsockopt(int, int, int, const void *, socklen_t); +__socketcall int getsockopt(int, int, int, void *, socklen_t *); +__socketcall int sendmsg(int, const struct msghdr *, unsigned int); +__socketcall int recvmsg(int, struct msghdr *, unsigned int); + +#undef __socketcall + +#endif /* _SYS_SOCKET_H */ diff --git a/klibc/include/sys/socketcalls.h b/klibc/include/sys/socketcalls.h new file mode 100644 index 0000000000..dac9f9aab6 --- /dev/null +++ b/klibc/include/sys/socketcalls.h @@ -0,0 +1,28 @@ +/* + * sys/socketcalls.h + */ + +#ifndef _SYS_SOCKETCALLS_H +#define _SYS_SOCKETCALLS_H + +/* socketcalls by number, since isn't usable for assembly */ + +#define SYS_SOCKET 1 /* sys_socket(2) */ +#define SYS_BIND 2 /* sys_bind(2) */ +#define SYS_CONNECT 3 /* sys_connect(2) */ +#define SYS_LISTEN 4 /* sys_listen(2) */ +#define SYS_ACCEPT 5 /* sys_accept(2) */ +#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ +#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ +#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ +#define SYS_SEND 9 /* sys_send(2) */ +#define SYS_RECV 10 /* sys_recv(2) */ +#define SYS_SENDTO 11 /* sys_sendto(2) */ +#define SYS_RECVFROM 12 /* sys_recvfrom(2) */ +#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ +#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ +#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ +#define SYS_SENDMSG 16 /* sys_sendmsg(2) */ +#define SYS_RECVMSG 17 /* sys_recvmsg(2) */ + +#endif /* _SYS_SOCKETCALLS_H */ diff --git a/klibc/include/sys/stat.h b/klibc/include/sys/stat.h new file mode 100644 index 0000000000..1bf6a75f79 --- /dev/null +++ b/klibc/include/sys/stat.h @@ -0,0 +1,31 @@ +/* + * sys/stat.h + */ + +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include +#include +#include /* For struct timespec */ +#include +#include + +#ifdef _STATBUF_ST_NSEC + /* struct stat has struct timespec instead of time_t */ +# define st_atime st_atim.tv_sec +# define st_mtime st_mtim.tv_sec +# define st_ctime st_ctim.tv_sec +#endif + +__extern int stat(const char *, struct stat *); +__extern int fstat(int, struct stat *); +__extern int lstat(const char *, struct stat *); +__extern mode_t umask(mode_t); +__extern int mknod(const char *, mode_t, dev_t); +static __inline__ int mkfifo(const char *__p, mode_t __m) +{ + return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0); +} + +#endif /* _SYS_STAT_H */ diff --git a/klibc/include/sys/statfs.h b/klibc/include/sys/statfs.h new file mode 100644 index 0000000000..53b3b5e4da --- /dev/null +++ b/klibc/include/sys/statfs.h @@ -0,0 +1 @@ +#include diff --git a/klibc/include/sys/syscall.h b/klibc/include/sys/syscall.h new file mode 100644 index 0000000000..c2c7684c4a --- /dev/null +++ b/klibc/include/sys/syscall.h @@ -0,0 +1,17 @@ +/* + * sys/syscall.h + * + * Generic system call interface macros + */ +#ifndef _SYS_SYSCALL_H +#define _SYS_SYSCALL_H + +#include +#include +#include + +/* Many architectures have incomplete, defective or non-applicable + syscall macros */ +#include + +#endif /* _SYS_SYSCALL_H */ diff --git a/klibc/include/sys/sysinfo.h b/klibc/include/sys/sysinfo.h new file mode 100644 index 0000000000..4051c6897a --- /dev/null +++ b/klibc/include/sys/sysinfo.h @@ -0,0 +1,12 @@ +/* + * sys/sysinfo.h + */ + +#ifndef _SYS_SYSINFO_H +#define _SYS_SYSINFO_H + +#include + +extern int sysinfo (struct sysinfo *info); + +#endif /* _SYS_SYSINFO_H */ diff --git a/klibc/include/sys/sysmacros.h b/klibc/include/sys/sysmacros.h new file mode 100644 index 0000000000..7f1e0822b3 --- /dev/null +++ b/klibc/include/sys/sysmacros.h @@ -0,0 +1,31 @@ +/* + * sys/sysmacros.h + * + * Constructs to create and pick apart dev_t. This applies to the Linux 2.6 + * 32-bit dev_t format. + */ + +#ifndef _SYS_SYSMACROS_H +#define _SYS_SYSMACROS_H + +#ifndef _SYS_TYPES_H +# include +#endif + +static __inline__ int major(dev_t __d) +{ + return (__d >> 8) & 0xfff; +} + +static __inline__ int minor(dev_t __d) +{ + return (__d & 0xff) | ((__d >> 12) & 0xfff00); +} + +static __inline__ dev_t makedev(int __ma, int __mi) +{ + return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12); +} + +#endif /* _SYS_SYSMACROS_H */ + diff --git a/klibc/include/sys/time.h b/klibc/include/sys/time.h new file mode 100644 index 0000000000..2767a1bce3 --- /dev/null +++ b/klibc/include/sys/time.h @@ -0,0 +1,18 @@ +/* + * sys/time.h + */ + +#ifndef _SYS_TIME_H +#define _SYS_TIME_H + +#include +#include +#include + +__extern int gettimeofday(struct timeval *, struct timezone *); +__extern int settimeofday(const struct timeval *, const struct timezone *); +__extern int getitimer(int, struct itimerval *); +__extern int setitimer(int, const struct itimerval *, struct itimerval *); +__extern int utimes(const char *, const struct timeval *); + +#endif /* _SYS_TIME_H */ diff --git a/klibc/include/sys/times.h b/klibc/include/sys/times.h new file mode 100644 index 0000000000..657f9c4b1c --- /dev/null +++ b/klibc/include/sys/times.h @@ -0,0 +1,14 @@ +/* + * sys/times.h + */ + +#ifndef _SYS_TIMES_H +#define _SYS_TIMES_H + +#include + +__extern clock_t times(struct tms *); +__extern int gettimeofday(struct timeval *, struct timezone *); +__extern int settimeofday(const struct timeval *, const struct timezone *); + +#endif /* _SYS_TIMES_H */ diff --git a/klibc/include/sys/types.h b/klibc/include/sys/types.h new file mode 100644 index 0000000000..ddec242922 --- /dev/null +++ b/klibc/include/sys/types.h @@ -0,0 +1,104 @@ +/* + * sys/types.h + */ + +#ifndef _SYS_TYPES_H +#define _SYS_TYPES_H + +#include +#include +#include + +#define _SSIZE_T +typedef ptrdiff_t ssize_t; + +#include +#include + +/* Keeps linux/types.h from getting included elsewhere */ +#define _LINUX_TYPES_H + +typedef __kernel_fd_set fd_set; +typedef uint32_t dev_t; +typedef __kernel_ino_t ino_t; +typedef __kernel_mode_t mode_t; +typedef __kernel_nlink_t nlink_t; +typedef __kernel_loff_t off_t; +typedef __kernel_loff_t loff_t; +typedef __kernel_pid_t pid_t; +typedef __kernel_daddr_t daddr_t; +typedef __kernel_key_t key_t; +typedef __kernel_suseconds_t suseconds_t; +/* typedef __kernel_timer_t timer_t; */ +typedef int timer_t; + +typedef __kernel_uid32_t uid_t; +typedef __kernel_gid32_t gid_t; + +typedef __kernel_fsid_t fsid_t; + +/* + * The following typedefs are also protected by individual ifdefs for + * historical reasons: + */ +#ifndef _SIZE_T +#define _SIZE_T +typedef __kernel_size_t size_t; +#endif + +#ifndef _SSIZE_T +#define _SSIZE_T +typedef __kernel_ssize_t ssize_t; +#endif + +#ifndef _PTRDIFF_T +#define _PTRDIFF_T +typedef __kernel_ptrdiff_t ptrdiff_t; +#endif + +#ifndef _TIME_T +#define _TIME_T +typedef __kernel_time_t time_t; +#endif + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef __kernel_clock_t clock_t; +#endif + +#ifndef _CADDR_T +#define _CADDR_T +typedef __kernel_caddr_t caddr_t; +#endif + +/* bsd */ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +/* sysv */ +typedef unsigned char unchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; + +/* Linux-specific? */ +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +typedef uint64_t u_int64_t; + +typedef uint16_t __bitwise __le16; +typedef uint16_t __bitwise __be16; +typedef uint32_t __bitwise __le32; +typedef uint32_t __bitwise __be32; +typedef uint64_t __bitwise __le64; +typedef uint64_t __bitwise __be64; + +/* + * Some apps want this in + */ +#include + +#endif diff --git a/klibc/include/sys/uio.h b/klibc/include/sys/uio.h new file mode 100644 index 0000000000..fc2525d11a --- /dev/null +++ b/klibc/include/sys/uio.h @@ -0,0 +1,15 @@ +/* + * sys/uio.h + */ + +#ifndef _SYS_UIO_H +#define _SYS_UIO_H + +#include +#include +#include + +__extern int readv(int, const struct iovec *, int); +__extern int writev(int, const struct iovec *, int); + +#endif /* _SYS_UIO_H */ diff --git a/klibc/include/sys/un.h b/klibc/include/sys/un.h new file mode 100644 index 0000000000..df42d719f7 --- /dev/null +++ b/klibc/include/sys/un.h @@ -0,0 +1,10 @@ +/* + * + */ + +#ifndef _SYS_UN_H +#define _SYS_UN_H + +#include + +#endif /* _SYS_UN_H */ diff --git a/klibc/include/sys/utime.h b/klibc/include/sys/utime.h new file mode 100644 index 0000000000..d1d635d242 --- /dev/null +++ b/klibc/include/sys/utime.h @@ -0,0 +1,10 @@ +/* + * sys/utime.h + */ + +#ifndef _SYS_UTIME_H +#define _SYS_UTIME_H + +#include + +#endif /* _SYS_UTIME_H */ diff --git a/klibc/include/sys/utsname.h b/klibc/include/sys/utsname.h new file mode 100644 index 0000000000..f2990f5711 --- /dev/null +++ b/klibc/include/sys/utsname.h @@ -0,0 +1,23 @@ +/* + * sys/utsname.h + */ + +#ifndef _SYS_UTSNAME_H +#define _SYS_UTSNAME_H + +#include + +#define SYS_NMLN 65 + +struct utsname { + char sysname[SYS_NMLN]; + char nodename[SYS_NMLN]; + char release[SYS_NMLN]; + char version[SYS_NMLN]; + char machine[SYS_NMLN]; + char domainname[SYS_NMLN]; +}; + +__extern int uname(struct utsname *); + +#endif /* _SYS_UTSNAME_H */ diff --git a/klibc/include/sys/vfs.h b/klibc/include/sys/vfs.h new file mode 100644 index 0000000000..b60d1a572f --- /dev/null +++ b/klibc/include/sys/vfs.h @@ -0,0 +1,111 @@ +/* + * sys/vfs.h + */ + +#ifndef _SYS_VFS_H +#define _SYS_VFS_H + +#include +#include +#include + +/* struct statfs64 -- there seems to be two standards - + one for 32 and one for 64 bits, and they're incompatible... */ + +#if BITSIZE == 32 || defined(__s390__) + +struct statfs { + uint32_t f_type; + uint32_t f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + __kernel_fsid_t f_fsid; + uint32_t f_namelen; + uint32_t f_frsize; + uint32_t f_spare[5]; +}; + +#else /* BITSIZE == 64 */ + +struct statfs { + uint64_t f_type; + uint64_t f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + __kernel_fsid_t f_fsid; + uint64_t f_namelen; + uint64_t f_frsize; + uint64_t f_spare[5]; +}; + +#endif /* BITSIZE */ + +__extern int statfs(const char *, struct statfs *); +__extern int fstatfs(int, struct statfs *); + +/* Various filesystem types */ +#define ADFS_SUPER_MAGIC 0xadf5 +#define AFFS_SUPER_MAGIC 0xadff +#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ +#define AUTOFS_SUPER_MAGIC 0x0187 +#define BFS_MAGIC 0x1BADFACE +#define CAPIFS_SUPER_MAGIC 0x434e +#define CIFS_MAGIC_NUMBER 0xFF534D42 +#define CODA_SUPER_MAGIC 0x73757245 +#define CRAMFS_MAGIC 0x28cd3d45 +#define DEVFS_SUPER_MAGIC 0x1373 +#define DEVPTS_SUPER_MAGIC 0x1cd1 +#define EFS_SUPER_MAGIC 0x414A53 +#define EVENTPOLLFS_MAGIC 0x03111965 +#define EXT2_SUPER_MAGIC 0xEF53 +#define EXT3_SUPER_MAGIC 0xEF53 +#define GADGETFS_MAGIC 0xaee71ee7 +#define HFSPLUS_SUPER_MAGIC 0x482b +#define HFS_MFS_SUPER_MAGIC 0xD2D7 /* MFS MDB (super block) */ +#define HFS_SUPER_MAGIC 0x4244 /* "BD": HFS MDB (super block) */ +#define HPFS_SUPER_MAGIC 0xf995e849 +#define HUGETLBFS_MAGIC 0x958458f6 +#define HWGFS_MAGIC 0x12061983 +#define IBMASMFS_MAGIC 0x66726f67 +#define ISOFS_SUPER_MAGIC 0x9660 +#define JFFS2_SUPER_MAGIC 0x72b6 +#define JFFS_MAGIC_BITMASK 0x34383931 /* "1984" */ +#define JFFS_MAGIC_SB_BITMASK 0x07c0 /* 1984 */ +#define JFS_SUPER_MAGIC 0x3153464a /* "JFS1" */ +#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ +#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ +#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ +#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ +#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ +#define NCP_SUPER_MAGIC 0x564c +#define NFS_SUPER_MAGIC 0x6969 +#define NFS_SUPER_MAGIC 0x6969 +#define OPENPROM_SUPER_MAGIC 0x9fa1 +#define OPROFILEFS_MAGIC 0x6f70726f +#define PFMFS_MAGIC 0xa0b4d889 +#define PIPEFS_MAGIC 0x50495045 +#define PROC_SUPER_MAGIC 0x9fa0 +#define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */ +#define RAMFS_MAGIC 0x858458f6 +#define REISERFS_SUPER_MAGIC 0x52654973 +#define ROMFS_MAGIC 0x7275 +#define SMB_SUPER_MAGIC 0x517B +#define SOCKFS_MAGIC 0x534F434B +#define SYSFS_MAGIC 0x62656572 +#define TMPFS_MAGIC 0x01021994 +#define UDF_SUPER_MAGIC 0x15013346 +#define UFS_MAGIC 0x00011954 +#define UFS_MAGIC_4GB 0x05231994 /* fs > 4 GB && fs_featurebits */ +#define UFS_MAGIC_FEA 0x00195612 /* fs_featurebits supported */ +#define UFS_MAGIC_LFN 0x00095014 /* fs supports filenames > 14 chars */ +#define UFS_MAGIC_SEC 0x00612195 /* B1 security fs */ +#define USBDEVICE_SUPER_MAGIC 0x9fa2 +#define VXFS_SUPER_MAGIC 0xa501FCF5 + +#endif /* _SYS_VFS_H */ diff --git a/klibc/include/sys/wait.h b/klibc/include/sys/wait.h new file mode 100644 index 0000000000..4cfafc9408 --- /dev/null +++ b/klibc/include/sys/wait.h @@ -0,0 +1,28 @@ +/* + * sys/wait.h + */ + +#ifndef _SYS_WAIT_H +#define _SYS_WAIT_H + +#include +#include +#include + +#include + +#define WEXITSTATUS(s) (((s) & 0xff00) >> 8) +#define WTERMSIG(s) ((s) & 0x7f) +#define WIFEXITED(s) (WTERMSIG(s) == 0) +#define WIFSTOPPED(s) (WTERMSIG(s) == 0x7f) +/* Ugly hack to avoid multiple evaluation of "s" */ +#define WIFSIGNALED(s) (WTERMSIG((s)+1) >= 2) +#define WCOREDUMP(s) ((s) & 0x80) +#define WSTOPSIG(s) WEXITSTATUS(s) + +__extern pid_t wait(int *); +__extern pid_t waitpid(pid_t, int *, int); +__extern pid_t wait3(int *, int, struct rusage *); +__extern pid_t wait4(pid_t, int *, int, struct rusage *); + +#endif /* _SYS_WAIT_H */ diff --git a/klibc/include/syslog.h b/klibc/include/syslog.h new file mode 100644 index 0000000000..551527a042 --- /dev/null +++ b/klibc/include/syslog.h @@ -0,0 +1,55 @@ +/* + * syslog.h + */ + +#ifndef _SYSLOG_H +#define _SYSLOG_H + +#include +#include + +/* Alert levels */ +#define LOG_EMERG 0 +#define LOG_ALERT 1 +#define LOG_CRIT 2 +#define LOG_ERR 3 +#define LOG_WARNING 4 +#define LOG_NOTICE 5 +#define LOG_INFO 6 +#define LOG_DEBUG 7 + +#define LOG_PRIMASK 7 +#define LOG_PRI(x) ((x) & LOG_PRIMASK) + + +/* Facilities; not actually used */ +#define LOG_KERN 0000 +#define LOG_USER 0010 +#define LOG_MAIL 0020 +#define LOG_DAEMON 0030 +#define LOG_AUTH 0040 +#define LOG_SYSLOG 0050 +#define LOG_LPR 0060 +#define LOG_NEWS 0070 +#define LOG_UUCP 0100 +#define LOG_CRON 0110 +#define LOG_AUTHPRIV 0120 +#define LOG_FTP 0130 +#define LOG_LOCAL0 0200 +#define LOG_LOCAL1 0210 +#define LOG_LOCAL2 0220 +#define LOG_LOCAL3 0230 +#define LOG_LOCAL4 0240 +#define LOG_LOCAL5 0250 +#define LOG_LOCAL6 0260 +#define LOG_LOCAL7 0270 + +#define LOG_FACMASK 01770 +#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3)) + +__extern void openlog(const char *, int, int); +__extern void syslog(int, const char *, ...); +__extern void vsyslog(int, const char *, va_list); +__extern void closelog(void); + +#endif /* _SYSLOG_H */ diff --git a/klibc/include/termios.h b/klibc/include/termios.h new file mode 100644 index 0000000000..08a5e56855 --- /dev/null +++ b/klibc/include/termios.h @@ -0,0 +1,86 @@ +/* + * termios.h + */ + +#ifndef _TERMIOS_H +#define _TERMIOS_H + +#include +#include +#include +#include +#include + +/* Redefine these so the magic constants == the ioctl number to use. */ +#undef TCSANOW +#undef TCSADRAIN +#undef TCSAFLUSH +#define TCSANOW TCSETS +#define TCSADRAIN TCSETSW +#define TCSAFLUSH TCSETSF + +static __inline__ int tcgetattr(int __fd, struct termios *__s) +{ + return ioctl(__fd, TCGETS, __s); +} + +static __inline__ int tcsetattr(int __fd, int __opt, const struct termios *__s) +{ + return ioctl(__fd, __opt, (void *)__s); +} + +static __inline__ int tcflow(int __fd, int __action) +{ + return ioctl(__fd, TCXONC, (void *)(intptr_t)__action); +} + +static __inline__ int tcflush(int __fd, int __queue) +{ + return ioctl(__fd, TCFLSH, (void *)(intptr_t)__queue); +} + +static __inline__ pid_t tcgetpgrp(int __fd) +{ + pid_t __p; + return ioctl(__fd, TIOCGPGRP, &__p) ? (pid_t)-1 : __p; +} + +static __inline__ pid_t tcgetsid(int __fd) +{ + pid_t __p; + return ioctl(__fd, TIOCGSID, &__p) ? (pid_t)-1 : __p; +} + +static __inline__ int tcsendbreak(int __fd, int __duration) +{ + return ioctl(__fd, TCSBRKP, (void *)(uintptr_t)__duration); +} + +static __inline__ int tcsetpgrp(int __fd, pid_t __p) +{ + return ioctl(__fd, TIOCSPGRP, &__p); +} + +static __inline__ speed_t cfgetospeed(const struct termios *__s) +{ + return (speed_t)(__s->c_cflag & CBAUD); +} + +static __inline__ speed_t cfgetispeed(const struct termios *__s) +{ + return (speed_t)(__s->c_cflag & CBAUD); +} + +static __inline__ int cfsetospeed(struct termios *__s, speed_t __v) +{ + __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); + return 0; +} + +static __inline__ int cfsetispeed(struct termios *__s, speed_t __v) +{ + __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); + return 0; +} + +#endif /* _TERMIOS_H */ diff --git a/klibc/include/time.h b/klibc/include/time.h new file mode 100644 index 0000000000..0f094c2806 --- /dev/null +++ b/klibc/include/time.h @@ -0,0 +1,18 @@ +/* + * time.h + */ + +#ifndef _TIME_H +#define _TIME_H + +#include +#include + +__extern time_t time(time_t *); +__extern int nanosleep(const struct timespec *, struct timespec *); + +/* klibc-specific but useful since we don't have floating point */ +__extern char *strtotimeval(const char *str, struct timeval *tv); +__extern char *strtotimespec(const char *str, struct timespec *tv); + +#endif /* _TIME_H */ diff --git a/klibc/include/unistd.h b/klibc/include/unistd.h new file mode 100644 index 0000000000..51fd7b769e --- /dev/null +++ b/klibc/include/unistd.h @@ -0,0 +1,140 @@ +/* + * unistd.h + */ + +#ifndef _UNISTD_H +#define _UNISTD_H + +#include +#include +#include +#include +#include + +__extern char **environ; +__extern __noreturn _exit(int); + +__extern pid_t fork(void); +__extern pid_t vfork(void); +__extern pid_t getpid(void); +__extern pid_t getpgid(pid_t); +__extern int setpgid(pid_t, pid_t); +__extern pid_t getppid(void); +__extern pid_t getpgrp(void); +__extern int setpgrp(void); +__extern pid_t setsid(void); +__extern pid_t getsid(pid_t); +__extern int execv(const char *, char * const *); +__extern int execvp(const char *, char * const *); +__extern int execve(const char *, char * const *, char * const *); +__extern int execvpe(const char *, char * const *, char * const *); +__extern int execl(const char *, const char *, ...); +__extern int execlp(const char *, const char *, ...); +__extern int execle(const char *, const char *, ...); +__extern int execlpe(const char *, const char *, ...); + +__extern int setuid(uid_t); +__extern uid_t getuid(void); +__extern int seteuid(uid_t); +__extern uid_t geteuid(void); +__extern int setgid(gid_t); +__extern gid_t getgid(void); +__extern int setegid(gid_t); +__extern gid_t getegid(void); +__extern int getgroups(int, gid_t *); +__extern int setgroups(size_t, const gid_t *); +__extern int setreuid(uid_t, uid_t); +__extern int setregid(gid_t, gid_t); +__extern int setresuid(uid_t, uid_t, uid_t); +__extern int setresgid(gid_t, gid_t, gid_t); +__extern int getfsuid(uid_t); +__extern int setfsuid(uid_t); + +/* Macros for access() */ +#define R_OK 4 /* Read */ +#define W_OK 2 /* Write */ +#define X_OK 1 /* Execute */ +#define F_OK 0 /* Existence */ + +__extern int access(const char *, int); +__extern int link(const char *, const char *); +__extern int unlink(const char *); +__extern int chdir(const char *); +__extern int fchdir(int); +__extern int chmod(const char *, mode_t); +__extern int fchmod(int, mode_t); +__extern int mkdir(const char *, mode_t); +__extern int rmdir(const char *); +__extern int pipe(int *); +__extern int chroot(const char *); +__extern int symlink(const char *, const char *); +__extern int readlink(const char *, char *, size_t); +__extern int chown(const char *, uid_t, gid_t); +__extern int fchown(int, uid_t, gid_t); +__extern int lchown(const char *, uid_t, gid_t); +__extern char *getcwd(char *, size_t); + +__extern int sync(void); + +/* Also in */ +#ifndef _KLIBC_IN_OPEN_C +__extern int open(const char *, int, ...); +#endif +__extern int close(int); +__extern off_t lseek(int, off_t, int); +/* off_t is 64 bits now even on 32-bit platforms; see llseek.c */ +static __inline__ off_t llseek(int __f, off_t __o, int __w) { + return lseek(__f, __o, __w); +} + +__extern ssize_t read(int, void *, size_t); +__extern ssize_t write(int, const void *, size_t); +__extern ssize_t pread(int, void *, size_t, off_t); +__extern ssize_t pwrite(int, void *, size_t, off_t); + +__extern int dup(int); +__extern int dup2(int, int); +__extern int fcntl(int, int, ...); +__extern int ioctl(int, int, void *); +__extern int flock(int, int); +__extern int fsync(int); +__extern int fdatasync(int); +__extern int ftruncate(int, off_t); + +__extern int pause(void); +__extern unsigned int alarm(unsigned int); +__extern unsigned int sleep(unsigned int); +__extern void usleep(unsigned long); + +__extern int gethostname(char *, size_t); +__extern int sethostname(const char *, size_t); +__extern int getdomainname(char *, size_t); +__extern int setdomainname(const char *, size_t); + +__extern void *__brk(void *); +__extern int brk(void *); +__extern void *sbrk(ptrdiff_t); + +__extern int getopt(int, char * const *, const char *); +__extern char *optarg; +__extern int optind, opterr, optopt; + +__extern int isatty(int); + +static __inline__ int getpagesize(void) { + extern unsigned int __page_size; + return __page_size; +} +static __inline__ int __getpageshift(void) { + extern unsigned int __page_shift; + return __page_shift; +} + +__extern int daemon(int, int); + +/* Standard file descriptor numbers. */ +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + +#endif /* _UNISTD_H */ diff --git a/klibc/include/utime.h b/klibc/include/utime.h new file mode 100644 index 0000000000..3dfa03a14a --- /dev/null +++ b/klibc/include/utime.h @@ -0,0 +1,15 @@ +/* + * utime.h + */ + +#ifndef _UTIME_H +#define _UTIME_H + +#include +#include +#include + +__extern int utime(const char *, const struct utimbuf *); + +#endif /* _UTIME_H */ + From e7c4f85f8a96b6b52e8885685eb6f36df48bbeba Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Oct 2004 19:01:12 -0700 Subject: [PATCH 0843/4284] [PATCH] fix up Makefiles to get the klibc build working properly. Based on a patch from Kay Sievers --- Makefile | 31 +++++++++++++++++-------------- klibc/klibc/Makefile | 2 +- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 764618e1b4..bc2f852614 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ # Makefile for udev # -# Copyright (C) 2003 Greg Kroah-Hartman +# Copyright (C) 2003,2004 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 @@ -33,7 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler -VERSION = 032 +VERSION = 032_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev @@ -140,9 +140,8 @@ endif ifeq ($(strip $(USE_KLIBC)),true) KLIBC_BASE = $(PWD)/klibc KLIBC_DIR = $(KLIBC_BASE)/klibc - INCLUDE_DIR := $(KLIBC_DIR)/include + INCLUDE_DIR := $(KLIBC_BASE)/include LINUX_INCLUDE_DIR := $(KERNEL_DIR)/include -# LINUX_INCLUDE_DIR := $(KLIBC_BASE)/linux/include include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG # arch specific objects ARCH_LIB_OBJS = \ @@ -150,12 +149,12 @@ ifeq ($(strip $(USE_KLIBC)),true) CRT0 = $(KLIBC_DIR)/crt0.o - LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) + LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) CFLAGS += $(WARNINGS) -nostdinc \ $(OPTFLAGS) \ -D__KLIBC__ -fno-builtin-printf \ -I$(INCLUDE_DIR) \ - -I$(KLIBC_DIR)/arch/$(ARCH)/include \ + -I$(INCLUDE_DIR)/arch/$(ARCH) \ -I$(INCLUDE_DIR)/bits$(BITSIZE) \ -I$(GCCINCDIR) \ -I$(LINUX_INCLUDE_DIR) @@ -164,7 +163,7 @@ ifeq ($(strip $(USE_KLIBC)),true) else WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations CRT0 = - LIBC = + LIBC = CFLAGS += $(WARNINGS) -I$(GCCINCDIR) LIB_OBJS = -lc LDFLAGS = @@ -185,7 +184,10 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(ARCH_LIB_OBJS) : $(CRT0) $(CRT0): - $(MAKE) -C klibc KERNEL_DIR=$(KERNEL_DIR) + @if [ ! -r klibc/linux ]; then \ + ln -f -s $(KERNEL_DIR) klibc/linux; \ + fi + $(MAKE) -C klibc SUBDIRS=klibc TDB = tdb/tdb.o \ tdb/spinlock.o @@ -261,27 +263,27 @@ $(DAEMON).o: $(GEN_HEADERS) $(SENDER).o: $(GEN_HEADERS) $(STARTER).o: $(GEN_HEADERS) -$(ROOT): $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(LIBC) $(GEN_MANPAGES) +$(ROOT): $(LIBC) $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(TESTER): $(TESTER).o $(OBJS) $(HEADERS) $(LIBC) +$(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevtest.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(INFO): $(INFO).o $(OBJS) $(HEADERS) $(LIBC) +$(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(DAEMON): $(DAEMON).o $(OBJS) udevd.h $(LIBC) +$(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_lib.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(SENDER): $(SENDER).o $(OBJS) udevd.h $(LIBC) +$(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(STRIPCMD) $@ -$(RULER): $(RULER).o $(OBJS) $(HEADERS) $(LIBC) +$(RULER): $(LIBC) $(RULER).o $(OBJS) $(HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevruler.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) -lnewt $(STRIPCMD) $@ @@ -298,6 +300,7 @@ clean: spotless: clean $(MAKE) -C klibc spotless + -rm -f klibc/linux DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz$" -e "\/\." -e releases -e BitKeeper -e SCCS -e "\.tdb$" -e test/sys | sort ) DISTDIR := $(RELEASE_NAME) diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index d7e75f1814..3519b45089 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -59,7 +59,7 @@ LIB = libc.a INTERP_O = interp.o -all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so +all: $(CRT0) $(LIB) $(SOLIB) klibc.so # Add any architecture-specific rules include arch/$(ARCH)/Makefile.inc From 01f950e2eb86563255a269ecadd386cbe5361d0c Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Tue, 5 Oct 2004 21:30:54 -0700 Subject: [PATCH 0844/4284] [PATCH] update udev to include scsi_id 0.6 Here's a patch updating udev's copy of scsi_id to version 0.6. --- extras/scsi_id/ChangeLog | 23 ++++++++++++++++++++++ extras/scsi_id/Makefile | 2 +- extras/scsi_id/TODO | 3 --- extras/scsi_id/release-notes | 36 ++++++++++------------------------- extras/scsi_id/scsi.h | 7 +++++++ extras/scsi_id/scsi_id.8 | 3 +++ extras/scsi_id/scsi_id.c | 34 +++++++++++++++++++++++++++++++-- extras/scsi_id/scsi_id.h | 1 - extras/scsi_id/scsi_serial.c | 37 +++++++++++++++++------------------- 9 files changed, 93 insertions(+), 53 deletions(-) diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog index bfa353431b..724977dbf4 100644 --- a/extras/scsi_id/ChangeLog +++ b/extras/scsi_id/ChangeLog @@ -1,3 +1,26 @@ +2004-jul-30: + * scsi_id.c, scsi_serial.c: Align the buffer passed to scsi_serial, + don't bother aligning and memcpy-ing the result in scsi_inquiry. + Aligning to 512 probably does not help, since the IO length of + 254 is not a multiple of 512. + +2004-jul-30: + * scsi.h, scsi_serial.c: Use a define for the SCSI INQUIRY buffer + length. + +2004-jul-30: + * scsi_id.c: Patch from add a -u flag + to substitute white space with underscores so it is easier to use + the output as a device name. + +2004-jul-30: + * scsi_serial.c: Patch from Hannes Reinecke use 254 + bytes for SCSI INQUIRY commands. + +2004-jul-28: + * scsi_id.h, scsi_serial.c: get rid of dumb/dead code, and use a + 512 byte aligned buffer. + 2004-jun-23: * scsi_id.h: increase MAX_SERIAL_LEN from 128 to 256, as some devices (maybe broken ones) are giving really long id's. diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 8fe29f3647..7ccc4c5118 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.5 +SCSI_ID_VERSION=0.6 prefix = etcdir = ${prefix}/etc diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO index e0283cf444..857c22b87a 100644 --- a/extras/scsi_id/TODO +++ b/extras/scsi_id/TODO @@ -1,6 +1,3 @@ -- Add an option to replace blanks with spaces, so the generated id can be - more easily used as a /dev name. - - Add a bus white/black list option. So for example, all scsi devices under USB could easily be blacklisted. This should allow multiple busses to be listed. diff --git a/extras/scsi_id/release-notes b/extras/scsi_id/release-notes index 2996713117..302817ea7f 100644 --- a/extras/scsi_id/release-notes +++ b/extras/scsi_id/release-notes @@ -1,6 +1,6 @@ -Version 0.5 of scsi_id is available at: +Version 0.6 of scsi_id is available at: -http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.5.tar.gz +http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.6.tar.gz scsi_id is a program to generate a unique identifier for a given SCSI device. @@ -9,34 +9,18 @@ It is primarily for use with the udev program key, or hotplug scripts that want persistent naming of scsi devices. It could also be used for automatic multi-path configuration or device mapper configuration. -Version 0.5 requires: +Requires: - Linux kernel 2.6 - libsysfs 0.4.0 Major changes since the last release: + + - add -u option, patch from Christoph Varoqui, to substitute white + space with underscores so it is easier to use the output as a + device name. - - Ken Brush have the command line options - override generic options. + - Use 254 bytes for SCSI INQUIRY commands, patch from Hannes + Reinecke. - - Fix the gen_scsi_id_udev_rules.sh to handle spaces in the id. - - - Don't supply a makedev() when built with klibc. Also, the - scsi_id supplied makedev() was using the old major/minor method. - - - Include compiler.h so we can build against klibc, as recent sg.h - changes need a define for __user. - -Other changes: - - - Increase the MAX_SERIAL_LEN from 128 to 256, as some (possibly - broken devics) are returning very long id's - - - Add spotless target (via Olaf Hering's udev patch) - - - minor wording changes in scsi_id.config - - - Log INQUIRY failure, including the failing page code and vpd - values - - - Escape '-' with '\-' in the man page. +See ChangeLog for more details. diff --git a/extras/scsi_id/scsi.h b/extras/scsi_id/scsi.h index 780e001576..212765a17d 100644 --- a/extras/scsi_id/scsi.h +++ b/extras/scsi_id/scsi.h @@ -37,6 +37,13 @@ struct scsi_ioctl_command { #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. */ diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index 69dd2a998a..591bb79366 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -95,6 +95,9 @@ Generate an id for the The sysfs mount point must not be included. For example, use /block/sd, not /sys/block/sd. .TP +.BI \-u +Reformat the output : replace all whitespaces by underscores +.TP .BI \-v Generate verbose debugging output. .TP diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index e893987868..6395b822ce 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -52,7 +52,7 @@ * options are not supported, but other code is still left in place for * now. */ -static const char short_options[] = "bd:f:gip:s:vV"; +static const char short_options[] = "bd:f:gip:s:uvV"; /* * Just duplicate per dev options. */ @@ -70,6 +70,7 @@ static int default_page_code; static int use_stderr; static int debug; static int hotplug_mode; +static int reformat_serial; void log_message (int level, const char *format, ...) { @@ -469,6 +470,10 @@ static int set_options(int argc, char **argv, const char *short_opts, strncat(target, optarg, MAX_NAME_LEN); break; + case 'u': + reformat_serial = 1; + break; + case 'v': debug++; break; @@ -572,6 +577,23 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, return retval; } +/* + * 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; + + while (*p != '\0') { + if (isspace(*p)) + *p = '_'; + p++; + } + return; +} + /* * 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 @@ -583,7 +605,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) { int retval; int dev_type = 0; - char serial[MAX_SERIAL_LEN]; + char *serial, *unaligned_buf; struct sysfs_class_device *class_dev; /* of target_path */ struct sysfs_class_device *class_dev_parent; /* for partitions */ struct sysfs_device *scsi_dev; /* the scsi_device */ @@ -689,6 +711,12 @@ static int scsi_id(const char *target_path, char *maj_min_dev) dprintf("per dev options: good %d; page code 0x%x; callout '%s'\n", good_dev, page_code, callout); +#define ALIGN 512 + unaligned_buf = malloc(MAX_SERIAL_LEN + ALIGN); + serial = (char*) (((int) unaligned_buf + (ALIGN - 1)) & ~(ALIGN - 1)); + dprintf("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial); +#undef ALIGN + if (!good_dev) { retval = 1; } else if (callout[0] != '\0') { @@ -703,6 +731,8 @@ static int scsi_id(const char *target_path, char *maj_min_dev) retval = 0; } if (!retval) { + if (reformat_serial) + format_serial(serial); if (display_bus_id) printf("%s: ", scsi_dev->name); printf("%s", serial); diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 10599ebb5f..0ca7cd4206 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -25,7 +25,6 @@ log_message(LOG_DEBUG, "%s: " format, __FUNCTION__ , ## arg) #define MAX_NAME_LEN 72 -#define OFFSET (2 * sizeof(unsigned int)) /* * MAX_ATTR_LEN: maximum length of the result of reading a sysfs diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index e0074b662d..0db756404c 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -300,17 +300,12 @@ static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned unsigned char sense[SENSE_BUFF_LEN]; struct sg_io_hdr io_hdr; int retval; - unsigned char *inq; - unsigned char *buffer; int retry = 3; /* rather random */ - if (buflen > 255) { + if (buflen > SCSI_INQ_BUFF_LEN) { log_message(LOG_WARNING, "buflen %d too long\n", buflen); return -1; } - inq = malloc(OFFSET + sizeof (inq_cmd) + 512); - memset(inq, 0, OFFSET + sizeof (inq_cmd) + 512); - buffer = inq + OFFSET; resend: dprintf("%s evpd %d, page 0x%x\n", scsi_dev->name, evpd, page); @@ -321,7 +316,7 @@ resend: io_hdr.mx_sb_len = sizeof(sense); io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; io_hdr.dxfer_len = buflen; - io_hdr.dxferp = buffer; + io_hdr.dxferp = buf; io_hdr.cmdp = inq_cmd; io_hdr.sbp = sense; io_hdr.timeout = DEF_TIMEOUT; @@ -329,7 +324,8 @@ resend: if (ioctl(fd, SG_IO, &io_hdr) < 0) { log_message(LOG_WARNING, "%s: ioctl failed: %s\n", scsi_dev->name, strerror(errno)); - return -1; + retval = -1; + goto error; } retval = sg_err_category3(&io_hdr); @@ -346,7 +342,6 @@ resend: if (!retval) { retval = buflen; - memcpy(buf, buffer, retval); } else if (retval > 0) { if (--retry > 0) { dprintf("%s: Retrying ...\n", scsi_dev->name); @@ -355,15 +350,16 @@ resend: retval = -1; } +error: if (retval < 0) log_message(LOG_WARNING, "%s: Unable to get INQUIRY vpd %d page 0x%x.\n", scsi_dev->name, evpd, page); - free(inq); return retval; } +/* Get list of supported EVPD pages */ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, char *buffer, int len) { @@ -552,15 +548,17 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev, char return 0; } +/* Get device identification VPD page */ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int len) { int retval; int id_ind, j; - unsigned char page_83[256]; + unsigned char page_83[SCSI_INQ_BUFF_LEN]; - memset(page_83, 0, 256); - retval = scsi_inquiry(scsi_dev, fd, 1, 0x83, page_83, 255); + memset(page_83, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(scsi_dev, fd, 1, 0x83, page_83, + SCSI_INQ_BUFF_LEN); if (retval < 0) return 1; @@ -609,6 +607,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, return 1; } +/* Get unit serial number VPD page */ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int max_len) { @@ -616,10 +615,10 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, int ser_ind; int i; int len; - unsigned char buf[256]; + unsigned char buf[SCSI_INQ_BUFF_LEN]; - memset(buf, 0, 256); - retval = scsi_inquiry(scsi_dev, fd, 1, 0x80, buf, 255); + memset(buf, 0, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(scsi_dev, fd, 1, 0x80, buf, SCSI_INQ_BUFF_LEN); if (retval < 0) return retval; @@ -652,13 +651,11 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, int page_code, char *serial, int len) { - unsigned char page0[256]; + unsigned char page0[SCSI_INQ_BUFF_LEN]; int fd; int ind; int retval; - if (len > 255) { - } memset(serial, 0, len); dprintf("opening %s\n", devname); fd = open(devname, O_RDONLY | O_NONBLOCK); @@ -694,7 +691,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, * 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(scsi_dev, fd, page0, 255)) { + if (do_scsi_page0_inquiry(scsi_dev, 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 From a8b5267a629f21c30d4e94ec82be193009803ddd Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 5 Oct 2004 21:35:39 -0700 Subject: [PATCH 0845/4284] [PATCH] finally solve the bad sysfs-timing for all of us On Tue, Sep 21, 2004 at 07:17:34PM +0200, Kay Sievers wrote: > During the integration of HAL into the linux hotplug system, we dicover > every week a new signaling path that fails cause of the delayed > population of the sysfs files, which are connected by symlinks and > appear in something like a random order in userspace. > > It's pretty complicated to understand the connection between all these > files for all the different subsystems with all the exceptions, so most > of the users simply sleep a few seconds, but that is not acceptable for > our integration work. > > Here I try to get all the special knowledge about that behavior together > and place that in a simple binary. That program _must_ run first of all > other hotplug processsing and every later script, udev or HAL all can get > rid of the wild guesses about the right time sysfs is ready. > > It will not only wait for the "dev"-file events we handle with udev, also > for every /device-device with the corresponding bus link. > > It is provided as a patch against the current udev tree and a "install" will > place the new program in the hotplug.d directory: > > [kay@pim ~]$ tree /etc/hotplug.d/ > /etc/hotplug.d/ > `-- default > |-- 00-wait_for_sysfs.hotplug -> /sbin/wait_for_sysfs > |-- 10-udev.hotplug -> /sbin/udevsend > |-- 20-hal.hotplug -> /usr/libexec/hal.hotplug > |-- default.hotplug > `-- log.hotplug > > > For now, it logs the result of the waiting to syslog, to catch any > device, that needs special treatment. All newly discovered delay problems, > device black/whitelist updates should go into that program and we may remove > that kind of specialisation from all the other hotplug programs. > > Any patches, reports, testing is more than welcome. > > Sample debug: > Sep 21 18:44:07 localhost kernel: usb 3-2: new full speed USB device using address 12 > Sep 21 18:44:07 localhost kernel: hub 3-2:1.0: USB hub found > Sep 21 18:44:07 localhost kernel: hub 3-2:1.0: 2 ports detected > Sep 21 18:44:07 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/devices/pci0000:00/0000:00:1d.1/usb3/3-2' > Sep 21 18:44:07 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2:1.0' > Sep 21 18:44:08 localhost kernel: usb 3-2.1: new full speed USB device using address 13 > Sep 21 18:44:08 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/class/usb/lp0' > Sep 21 18:44:08 localhost kernel: drivers/usb/class/usblp.c: usblp0: USB Bidirectional printer dev 13 if 0 alt 1 proto 2 vid 0x067B pid 0x2305 > Sep 21 18:44:08 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2.1/3-2.1:1.0' > Sep 21 18:44:08 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2.1' > Sep 21 18:44:08 localhost udev: configured rule in '/etc/udev/rules.d/50-udev.rules' at line 29 applied, 'lp0' becomes 'usb/%k' > Sep 21 18:44:08 localhost udev: creating device node '/udev/usb/lp0' > Sep 21 18:44:09 localhost kernel: usb 3-2.2: new full speed USB device using address 14 > Sep 21 18:44:09 localhost kernel: pl2303 3-2.2:1.0: PL-2303 converter detected > Sep 21 18:44:09 localhost kernel: usb 3-2.2: PL-2303 converter now attached to ttyUSB0 > Sep 21 18:44:09 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2.2' > Sep 21 18:44:09 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2.2/3-2.2:1.0' > Sep 21 18:44:09 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/devices/pci0000:00/0000:00:1d.1/usb3/3-2/3-2.2/3-2.2:1.0/ttyUSB0' > Sep 21 18:44:09 localhost 00-wait_for_sysfs.hotplug: result: waiting for sysfs successful '/class/tty/ttyUSB0' > Sep 21 18:44:09 localhost udev: creating device node '/udev/ttyUSB0' New version with more devices excluded from /device-link saerch and a better maching for device names. --- Makefile | 15 ++- wait_for_sysfs.c | 334 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 346 insertions(+), 3 deletions(-) create mode 100644 wait_for_sysfs.c diff --git a/Makefile b/Makefile index bc2f852614..67a7d46525 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart RULER = udevruler +WAIT = wait_for_sysfs VERSION = 032_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -171,7 +172,7 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -287,10 +288,14 @@ $(RULER): $(LIBC) $(RULER).o $(OBJS) $(HEADERS) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevruler.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) -lnewt $(STRIPCMD) $@ +$(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) + $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(STRIPCMD) $@ + clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(RULER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(RULER) $(WAIT) $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ @@ -391,8 +396,10 @@ install: install-initscript install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) - ln -sf $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER) + $(INSTALL_PROGRAM) -D $(WAIT) $(DESTDIR)$(sbindir)/$(WAIT) + - ln -f -s $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER) - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug + - ln -f -s $(sbindir)/$(WAIT) $(DESTDIR)$(hotplugdir)/00-wait_for_sysfs.hotplug ifndef DESTDIR - killall udevd - rm -f $(udevdir)/.udev.tdb @@ -405,6 +412,7 @@ endif uninstall: uninstall-man uninstall-dev.d - rm $(hotplugdir)/10-udev.hotplug + - rm $(hotplugdir)/00-wait_for_sysfs.hotplug - rm $(configdir)/rules.d/50-udev.rules - rm $(configdir)/permissions.d/50-udev.permissions - rm $(configdir)/udev.conf @@ -418,6 +426,7 @@ uninstall: uninstall-man uninstall-dev.d - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) - rm $(usrbindir)/$(TESTER) + - rm $(usrbindir)/$(WAIT) - rmdir $(hotplugdir) - rm $(udevdir)/.udev.tdb - rmdir $(udevdir) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c new file mode 100644 index 0000000000..b9efcddf87 --- /dev/null +++ b/wait_for_sysfs.c @@ -0,0 +1,334 @@ +/* + * wait_for_sysfs.c - small program to delay the execution + * of /etc/hotplug.d/ programs, until sysfs + * is populated by the kernel. Depending on + * the type of device, we wait for all expected + * directories and then just exit. + * + * 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "logging.h" +#include "libsysfs/sysfs/libsysfs.h" + +#ifdef LOG +unsigned char logname[LOGNAME_SIZE]; +void log_message(int level, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif + +#define WAIT_MAX_SECONDS 5 +#define WAIT_LOOP_PER_SECOND 20 + +static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev) +{ + static struct class_file { + char *subsystem; + char *file; + } class_files[] = { + { .subsystem = "net", .file = "ifindex" }, + { .subsystem = "usb_host", .file = NULL }, + { .subsystem = "pcmcia_socket", .file = NULL }, + { NULL, NULL } + }; + struct class_file *classfile; + const char *file = "dev"; + int loop; + + /* look if we want to look for another file instead of "dev" */ + for (classfile = class_files; classfile->subsystem != NULL; classfile++) { + if (strcmp(class_dev->classname, classfile->subsystem) == 0) { + if (classfile->file == NULL) { + dbg("class '%s' has no file to wait for", class_dev->classname); + return 0; + } + file = classfile->file; + break; + } + } + dbg("looking at class '%s' for specific file '%s'", class_dev->classname, file); + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + if (sysfs_get_classdev_attr(class_dev, file) != NULL) { + dbg("class '%s' specific file '%s' found", class_dev->classname, file); + return 0; + } + } + + dbg("error: getting bus '%s' specific file '%s'", class_dev->classname, file); + return -1; +} + +static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) +{ + char **device; + + static char *devices_without_link[] = { + "nb", + "ram", + "loop", + "fd", + "md", + "dos_cd", + "double", + "flash", + "msd", + "rflash", + "rom", + "rrom", + "sbpcd", + "pcd", + "pf", + "scd", + "sit", + "lp", + "ubd", + "vcs", + "vcsa", + "console", + "tty", + "ttyS", + NULL + }; + + for (device = devices_without_link; *device != NULL; device++) { + int len = strlen(*device); + + /* look if name matches */ + if (strncmp(class_dev->name, *device, len) != 0) + continue; + + /* exact match */ + if (strlen(class_dev->name) == len) + return 1; + + /* instance numbers are matching too */ + if (isdigit(class_dev->name[len])) + return 1; + } + + return 0; +} + +static int wait_for_bus_device(struct sysfs_device *device_dev) +{ + static struct bus_file { + char *bus; + char *file; + } bus_files[] = { + { .bus = "scsi", .file = "vendor" }, + { .bus = "usb", .file = "idVendor" }, + { .bus = "usb", .file = "iInterface" }, + { .bus = "usb-serial", .file = "detach_state" }, + { .bus = "ide", .file = "detach_state" }, + { .bus = "pci", .file = "vendor" }, + { NULL } + }; + struct bus_file *busfile; + int loop; + + /* wait for the /bus-device link to the /device-device */ + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + if (sysfs_get_device_bus(device_dev) == 0) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + if (loop == 0) { + dbg("error: getting /bus-device link"); + return -1; + } + dbg("/bus-device link found for bus '%s'", device_dev->bus); + + /* wait for a bus specific file to show up */ + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + for (busfile = bus_files; busfile->bus != NULL; busfile++) { + if (strcmp(device_dev->bus, busfile->bus) == 0) { + dbg("looking at bus '%s' for specific file '%s'", device_dev->bus, busfile->file); + if (sysfs_get_device_attr(device_dev, busfile->file) != NULL) { + dbg("bus '%s' specific file '%s' found", device_dev->bus, busfile->file); + return 0; + } + if (busfile->bus == NULL) { + info("error: unknown bus, update the build-in list '%s'", device_dev->bus); + return -1; + } + } + } + } + + dbg("error: getting bus '%s' specific file '%s'", device_dev->bus, busfile->file); + return -1; +} + +int main(int argc, char *argv[], char *envp[]) +{ + const char *devpath = ""; + const char *action; + const char *subsystem; + char sysfs_path[SYSFS_PATH_MAX]; + char filename[SYSFS_PATH_MAX]; + struct sysfs_class_device *class_dev; + struct sysfs_class_device *class_dev_parent; + struct sysfs_device *device_dev = NULL; + int loop; + int rc = 0; + + if (argc != 2) { + dbg("error: subsystem"); + return 1; + } + subsystem = argv[1]; + + devpath = getenv ("DEVPATH"); + if (!devpath) { + dbg("error: no DEVPATH"); + return 1; + } + + action = getenv ("ACTION"); + if (!action) { + dbg("error: no ACTION"); + return 1; + } + + if (strcmp(action, "add") != 0) + return 0; + + if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { + dbg("error: no sysfs path"); + return 2; + } + + if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) { + /* open the class device we are called for */ + snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); + filename[SYSFS_PATH_MAX-1] = '\0'; + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + class_dev = sysfs_open_class_device_path(filename); + if (class_dev) + break; + } + if (class_dev == NULL) { + dbg("error: getting class_device"); + rc = 4; + goto exit; + } + dbg("class_device opened '%s'", filename); + + wait_for_class_device_attributes(class_dev); + + if (class_device_expect_no_device_link(class_dev)) { + dbg("no device symlink expected"); + sysfs_close_class_device(class_dev); + goto exit; + } + + /* the symlink may be on the parent device */ + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent) + dbg("looking at parent device for device link '%s'", class_dev_parent->path); + + /* wait for the symlink to the /device-device */ + dbg("waiting for symlink to /device-device"); + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + if (class_dev_parent) + device_dev = sysfs_get_classdev_device(class_dev_parent); + else + device_dev = sysfs_get_classdev_device(class_dev); + + if (device_dev) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + if (device_dev == NULL) { + dbg("error: getting /device-device"); + sysfs_close_class_device(class_dev); + rc = 5; + goto exit; + } + dbg("device symlink found pointing to '%s'", device_dev->path); + + /* wait for the bus value */ + if (wait_for_bus_device(device_dev) != 0) + rc = 6; + sysfs_close_class_device(class_dev); + + /* finished */ + goto exit; + + } else if ((strncmp(devpath, "/devices/", 9) == 0)) { + /* open the path we are called for */ + snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); + filename[SYSFS_PATH_MAX-1] = '\0'; + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + device_dev = sysfs_open_device_path(filename); + if (device_dev) + break; + } + if (device_dev == NULL) { + dbg("error: getting /device-device"); + rc = 4; + goto exit; + } + dbg("device_device opened '%s'", filename); + + /* wait for the bus value */ + if (wait_for_bus_device(device_dev) != 0) + rc = 9; + + sysfs_close_device(device_dev); + + /* finished */ + goto exit; + + } else { + dbg("unhandled sysfs path, no need to wait"); + } + +exit: + if (rc == 0) + info("result: waiting for sysfs successful '%s'", devpath); + else + info("result: waiting for sysfs failed '%s'", devpath); + + return rc; +} From 186f7b23623b044e4e38a886c6440fe06d800184 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Oct 2004 21:56:39 -0700 Subject: [PATCH 0846/4284] [PATCH] update comments in scsi-devfs.sh --- extras/scsi-devfs.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extras/scsi-devfs.sh b/extras/scsi-devfs.sh index 12c8aa8eb5..b1a17cb21e 100644 --- a/extras/scsi-devfs.sh +++ b/extras/scsi-devfs.sh @@ -8,10 +8,10 @@ # # return devfs-names for scsi-devices # Usage in udev.rules: -# BUS="scsi", KERNEL="sd*", PROGRAM="/etc/udev/scsi-devfs.sh sd %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" -# BUS="scsi", KERNEL="sr*", PROGRAM="/etc/udev/scsi-devfs.sh sr %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" -# BUS="scsi", KERNEL="st*", PROGRAM="/etc/udev/scsi-devfs.sh st %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" -# BUS="scsi", KERNEL="sg*", PROGRAM="/etc/udev/scsi-devfs.sh sg %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" +# BUS="scsi", KERNEL="sd*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh sd %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" +# BUS="scsi", KERNEL="sr*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh sr %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" +# BUS="scsi", KERNEL="st*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh st %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" +# BUS="scsi", KERNEL="sg*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh sg %b %n", NAME="%c{1}", SYMLINK="%c{2} %k %c{3} %c{4}" # Find out where sysfs is mounted. Exit if not available sysfs=`grep -F sysfs /proc/mounts | awk '{print $2}'` From 1764266da0ce245d3a06c526d69f550b10913375 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Oct 2004 22:13:30 -0700 Subject: [PATCH 0847/4284] [PATCH] kdetv wants to see device nodes in /dev --- etc/udev/udev.rules.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 429762b8da..9245f6adcf 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -96,7 +96,7 @@ KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" # v4l devices KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n" KERNEL="radio[0-9]*", NAME="v4l/radio%n" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n" KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" # USB devices From b88988007310c6dd76c1b388baf2390549cce719 Mon Sep 17 00:00:00 2001 From: "kpfleming@backtobasicsmgmt.com" Date: Tue, 5 Oct 2004 22:15:16 -0700 Subject: [PATCH 0848/4284] [PATCH] respect prefix= setting in built udev.conf (updated) Here is a revised version of the patch. Again, it modifies the Makefile to respect the prefix= setting when putting paths to /etc/udev/{rules.s,permissions.d} into the built /etc/udev/udev.conf file. It also changes the Makefile to create this file at "make" time, not "make install" time. This allows for udevdir to be specified at "make" time (thus putting the correct path into udev.conf), but not specified at "make install" time (thus allowing the installation to proceed without trying to use the wrong directory). Submitted By: Kevin P. Fleming Date: 2004-09-16 Initial Package Version: 032 Origin: David Jensen Description: correct udev's Makefile and template config file to respect the "prefix=" setting supplied when it is built; also build etc/udev/udev.conf at "make" time, not "make install" time --- Makefile | 12 ++++++------ etc/udev/udev.conf.in | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 67a7d46525..24677d4194 100644 --- a/Makefile +++ b/Makefile @@ -172,7 +172,10 @@ endif CFLAGS += -I$(PWD)/libsysfs -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) +# config files automatically generated +GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf + +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) $(GEN_CONFIGS) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -242,12 +245,9 @@ udev_version.h: @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ -# config files automatically generated -GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf - # Rules on how to create the generated config files $(LOCAL_CFG_DIR)/udev.conf: - sed -e "s:@udevdir@:$(udevdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ + sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ GEN_MANPAGES = udev.8 GEN_MANPAGESIN = udev.8.in @@ -346,7 +346,7 @@ install-initscript: etc/init.d/udev etc/init.d/udev.debian etc/init.d/udev.init. $(INSTALL_DATA) -D etc/init.d/udev.debian $(DESTDIR)$(initdir)/udev; \ fi -install-config: $(GEN_CONFIGS) +install-config: $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d $(INSTALL) -d $(DESTDIR)$(configdir)/permissions.d @if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \ diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 9b6b9c7ee2..4c71b1dfec 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -12,10 +12,10 @@ udev_root="@udevdir@/" udev_db="@udevdir@/.udev.tdb" # udev_rules - The name and location of the udev rules file -udev_rules="/etc/udev/rules.d/" +udev_rules="@configdir@/rules.d/" # udev_permissions - The name and location of the udev permission file -udev_permissions="/etc/udev/permissions.d/" +udev_permissions="@configdir@/permissions.d/" # default_mode - set the default mode for all nodes that have no # explicit match in the permissions file From ff213aecf68b3427f0a8b2c8a1074851b1511299 Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Tue, 5 Oct 2004 22:20:12 -0700 Subject: [PATCH 0849/4284] [PATCH] cleanup PATCH for extras/chassis_id/Makefile for "make install" --- extras/chassis_id/Makefile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/extras/chassis_id/Makefile b/extras/chassis_id/Makefile index 1b641cafda..141d23c7b8 100644 --- a/extras/chassis_id/Makefile +++ b/extras/chassis_id/Makefile @@ -23,6 +23,11 @@ CFLAGS = -g TARGET = chassis_id +exec_prefix = ${prefix} +sbindir = ${exec_prefix}/sbin +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 all: chassis_id chassis_id: chassis_id.c table.c @@ -30,3 +35,7 @@ chassis_id: chassis_id.c table.c clean: rm -rf core a.out $(TARGET) + +install: all + $(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(sbindir)/$(TARGET) + From 9825617b078c2122d130676e934ce21714b60e8b Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Tue, 5 Oct 2004 23:39:05 -0700 Subject: [PATCH 0850/4284] [PATCH] PATCH selinux for udev Daniel Walsh's working selinux patch --- Makefile | 8 ++++ selinux.h | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++ udev-add.c | 10 ++++ 3 files changed, 149 insertions(+) create mode 100644 selinux.h diff --git a/Makefile b/Makefile index 24677d4194..9405b25c5f 100644 --- a/Makefile +++ b/Makefile @@ -25,6 +25,8 @@ USE_LOG = true # Leave this set to `false' for production use. DEBUG = false +# Set this to compile with Security-Enhanced Linux support. +USE_SELINUX = false ROOT = udev DAEMON = udevd @@ -170,6 +172,11 @@ else LDFLAGS = endif +ifeq ($(strip $(USE_SELINUX)),true) + CFLAGS += -DUSE_SELINUX + LIB_OBJS += -lselinux +endif + CFLAGS += -I$(PWD)/libsysfs # config files automatically generated @@ -222,6 +229,7 @@ HEADERS = udev.h \ udevdb.h \ klibc_fixups.h \ logging.h \ + selinux.h \ list.h ifeq ($(strip $(USE_KLIBC)),true) diff --git a/selinux.h b/selinux.h new file mode 100644 index 0000000000..475a60d6d2 --- /dev/null +++ b/selinux.h @@ -0,0 +1,131 @@ +#ifndef SELINUX_H +#define SELINUX_H + +#ifndef USE_SELINUX + +static inline void selinux_setfilecon(char *file, unsigned int mode) { } +static inline void selinux_setfscreatecon(char *file, unsigned int mode) {} +static inline void selinux_init(void) {} +static inline void selinux_restore(void) {} + +#else + +#include +#include +#include +#include + + +static int selinux_enabled=-1; +static security_context_t prev_scontext=NULL; + +static inline int is_selinux_running(void) { + if ( selinux_enabled==-1 ) + return selinux_enabled=is_selinux_enabled()>0; + return selinux_enabled; +} + +static inline int selinux_get_media(char *path, int mode, char **media) +{ + FILE *fp; + char buf[PATH_MAX]; + char mediabuf[PATH_MAX]; + *media=NULL; + if (!( mode && S_IFBLK )) { + return -1; + } + snprintf(buf,sizeof(buf), "/proc/ide/%s/media", basename(path)); + fp=fopen(buf,"r"); + if (fp) { + if (fgets(mediabuf,sizeof(mediabuf), fp)) { + int size=strlen(mediabuf); + while (size-- > 0) { + if (isspace(mediabuf[size])) { + mediabuf[size]='\0'; + } else { + break; + } + } + *media=strdup(mediabuf); + info("selinux_get_media(%s)->%s \n", path, *media); + } + fclose(fp); + return 0; + } else { + return -1; + } +} + +static inline void selinux_setfilecon(char *file, unsigned int mode) { + if (is_selinux_running()) { + security_context_t scontext=NULL; + char *media; + int ret=selinux_get_media(file, mode, &media); + if ( ret== 0) { + ret = matchmediacon(media, &scontext); + free(media); + } + if (ret==-1) + if (matchpathcon(file, mode, &scontext) < 0) { + dbg("matchpathcon(%s) failed\n", file); + return; + } + if (setfilecon(file, scontext) < 0) + dbg("setfiles %s failed with error '%s'", + file, strerror(errno)); + freecon(scontext); + } +} + +static inline void selinux_setfscreatecon(char *file, unsigned int mode) { + int retval = 0; + security_context_t scontext=NULL; + + if (is_selinux_running()) { + char *media; + int ret=selinux_get_media(file, mode, &media); + if ( ret== 0) { + ret = matchmediacon(media, &scontext); + free(media); + } + + if (ret==-1) + if (matchpathcon(file, mode, &scontext) < 0) { + dbg("matchpathcon(%s) failed\n", file); + return; + } + + retval=setfscreatecon(scontext); + if (retval < 0) + dbg("setfiles %s failed with error '%s'", + file, strerror(errno)); + freecon(scontext); + } +} +static inline void selinux_init(void) { + /* record the present security context, for file-creation + * restoration creation purposes. + * + */ + + if (is_selinux_running()) + { + if (getfscreatecon(&prev_scontext) < 0) { + dbg("getfscreatecon failed\n"); + } + prev_scontext=NULL; + } +} +static inline void selinux_restore(void) { + if (is_selinux_running()) { + /* reset the file create context to its former glory */ + if ( setfscreatecon(prev_scontext) < 0 ) + dbg("setfscreatecon failed\n"); + if (prev_scontext) { + freecon(prev_scontext); + prev_scontext=NULL; + } + } +} +#endif /* USE_SELINUX */ +#endif /* SELINUX_H */ diff --git a/udev-add.c b/udev-add.c index 1f69329788..e1e145de8a 100644 --- a/udev-add.c +++ b/udev-add.c @@ -50,6 +50,8 @@ #define LOCAL_USER "$local" +#include "selinux.h" + /* * Right now the major/minor of a device is stored in a file called * "dev" in sysfs. @@ -92,6 +94,7 @@ static int create_path(char *file) break; *pos = 0x00; if (stat(p, &stats)) { + selinux_setfscreatecon(p, S_IFDIR); retval = mkdir(p, 0755); if (retval != 0) { dbg("mkdir(%s) failed with error '%s'", @@ -99,6 +102,8 @@ static int create_path(char *file) return retval; } dbg("created '%s'", p); + } else { + selinux_setfilecon(p, S_IFDIR); } *pos = '/'; } @@ -117,6 +122,7 @@ static int make_node(char *file, int major, int minor, unsigned int mode, uid_t if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && (stats.st_rdev == makedev(major, minor))) { dbg("preserve file '%s', cause it has correct dev_t", file); + selinux_setfilecon(file,stats.st_mode); goto perms; } @@ -126,6 +132,7 @@ static int make_node(char *file, int major, int minor, unsigned int mode, uid_t dbg("already present file '%s' unlinked", file); create: + selinux_setfscreatecon(file, mode); retval = mknod(file, mode, makedev(major, minor)); if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", @@ -304,6 +311,7 @@ static int create_node(struct udevice *dev, int fake) dbg("symlink(%s, %s)", linktarget, filename); if (!fake) { + selinux_setfscreatecon(filename, S_IFLNK); unlink(filename); if (symlink(linktarget, filename) != 0) dbg("symlink(%s, %s) failed with error '%s'", @@ -438,6 +446,7 @@ int udev_add_device(const char *path, const char *subsystem, int fake) dbg("name='%s'", dev.name); + selinux_init(); switch (dev.type) { case 'b': case 'c': @@ -475,6 +484,7 @@ int udev_add_device(const char *path, const char *subsystem, int fake) } exit: + selinux_restore(); sysfs_close_class_device(class_dev); return retval; From 8f2f874ae8d5bfdc1eda9b1f9d77f6637f6940a5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Oct 2004 23:49:50 -0700 Subject: [PATCH 0851/4284] [PATCH] update the selinux.h file to start to look sane and I told them to follow the proper coding style... bleah... --- selinux.h | 110 +++++++++++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/selinux.h b/selinux.h index 475a60d6d2..38c60a3588 100644 --- a/selinux.h +++ b/selinux.h @@ -3,7 +3,7 @@ #ifndef USE_SELINUX -static inline void selinux_setfilecon(char *file, unsigned int mode) { } +static inline void selinux_setfilecon(char *file, unsigned int mode) {} static inline void selinux_setfscreatecon(char *file, unsigned int mode) {} static inline void selinux_init(void) {} static inline void selinux_restore(void) {} @@ -15,57 +15,59 @@ static inline void selinux_restore(void) {} #include #include - static int selinux_enabled=-1; static security_context_t prev_scontext=NULL; -static inline int is_selinux_running(void) { - if ( selinux_enabled==-1 ) - return selinux_enabled=is_selinux_enabled()>0; +static inline int is_selinux_running(void) +{ + if (selinux_enabled == -1) + return selinux_enabled = is_selinux_enabled() > 0; return selinux_enabled; } static inline int selinux_get_media(char *path, int mode, char **media) { - FILE *fp; - char buf[PATH_MAX]; - char mediabuf[PATH_MAX]; - *media=NULL; - if (!( mode && S_IFBLK )) { - return -1; - } - snprintf(buf,sizeof(buf), "/proc/ide/%s/media", basename(path)); - fp=fopen(buf,"r"); - if (fp) { - if (fgets(mediabuf,sizeof(mediabuf), fp)) { - int size=strlen(mediabuf); - while (size-- > 0) { - if (isspace(mediabuf[size])) { - mediabuf[size]='\0'; - } else { - break; - } - } - *media=strdup(mediabuf); - info("selinux_get_media(%s)->%s \n", path, *media); - } - fclose(fp); - return 0; - } else { - return -1; - } + FILE *fp; + char buf[PATH_MAX]; + char mediabuf[PATH_MAX]; + + *media = NULL; + if (!(mode && S_IFBLK)) { + return -1; + } + snprintf(buf,sizeof(buf), "/proc/ide/%s/media", basename(path)); + fp=fopen(buf,"r"); + if (fp) { + if (fgets(mediabuf,sizeof(mediabuf), fp)) { + int size = strlen(mediabuf); + while (size-- > 0) { + if (isspace(mediabuf[size])) { + mediabuf[size]='\0'; + } else { + break; + } + } + *media = strdup(mediabuf); + info("selinux_get_media(%s)->%s \n", path, *media); + } + fclose(fp); + return 0; + } else { + return -1; + } } -static inline void selinux_setfilecon(char *file, unsigned int mode) { +static inline void selinux_setfilecon(char *file, unsigned int mode) +{ if (is_selinux_running()) { security_context_t scontext=NULL; char *media; int ret=selinux_get_media(file, mode, &media); - if ( ret== 0) { + if (ret == 0) { ret = matchmediacon(media, &scontext); free(media); } - if (ret==-1) + if (ret == -1) if (matchpathcon(file, mode, &scontext) < 0) { dbg("matchpathcon(%s) failed\n", file); return; @@ -77,55 +79,61 @@ static inline void selinux_setfilecon(char *file, unsigned int mode) { } } -static inline void selinux_setfscreatecon(char *file, unsigned int mode) { +static inline void selinux_setfscreatecon(char *file, unsigned int mode) +{ int retval = 0; security_context_t scontext=NULL; if (is_selinux_running()) { char *media; - int ret=selinux_get_media(file, mode, &media); - if ( ret== 0) { + int ret = selinux_get_media(file, mode, &media); + + if (ret == 0) { ret = matchmediacon(media, &scontext); free(media); } - if (ret==-1) + if (ret == -1) if (matchpathcon(file, mode, &scontext) < 0) { dbg("matchpathcon(%s) failed\n", file); return; } - retval=setfscreatecon(scontext); + retval = setfscreatecon(scontext); if (retval < 0) dbg("setfiles %s failed with error '%s'", file, strerror(errno)); freecon(scontext); } } -static inline void selinux_init(void) { - /* record the present security context, for file-creation - * restoration creation purposes. - * - */ - if (is_selinux_running()) - { +static inline void selinux_init(void) +{ + /* + * record the present security context, for file-creation + * restoration creation purposes. + */ + if (is_selinux_running()) { if (getfscreatecon(&prev_scontext) < 0) { dbg("getfscreatecon failed\n"); } - prev_scontext=NULL; + prev_scontext = NULL; } } -static inline void selinux_restore(void) { + +static inline void selinux_restore(void) +{ if (is_selinux_running()) { /* reset the file create context to its former glory */ - if ( setfscreatecon(prev_scontext) < 0 ) + if (setfscreatecon(prev_scontext) < 0) dbg("setfscreatecon failed\n"); if (prev_scontext) { freecon(prev_scontext); - prev_scontext=NULL; + prev_scontext = NULL; } } } + #endif /* USE_SELINUX */ + #endif /* SELINUX_H */ From 057f2bdbf65ba6276209869feb74097d73c06b99 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 5 Oct 2004 23:51:24 -0700 Subject: [PATCH 0852/4284] [PATCH] add USE_SELINUX to README documentation so people have a chance to see what is going on. --- README | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README b/README index 508566b50a..c0475dc904 100644 --- a/README +++ b/README @@ -44,6 +44,9 @@ To use: what udev is doing. This is enabled by default. Note, if you are building udev against klibc it is recommended that you disable this option (due to klibc's syslog implementation.) + USE_SELINUX + if set to 'true', udev will be built with SELinux support + enabled. This is disabled by default. DEBUG if set to 'true', debugging messages will be sent to the syslog as udev is run. Default value is 'false'. @@ -88,3 +91,4 @@ know by sending a message to the linux-hotplug-devel mailing list at: greg k-h greg@kroah.com + From 470c0ef2a6483d1b150d52319eb03b87f7744ea0 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 6 Oct 2004 00:23:37 -0700 Subject: [PATCH 0853/4284] [PATCH] be paranoid in dev_d.c --- dev_d.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dev_d.c b/dev_d.c index 1ad599ead5..e6081b3993 100644 --- a/dev_d.c +++ b/dev_d.c @@ -71,6 +71,7 @@ void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath) if (udev_dev_d == 0) return; + memset(env_devname, 0x00, sizeof(env_devname)); if (dev->type == 'b' || dev->type == 'c') { strfieldcpy(env_devname, udev_root); strfieldcat(env_devname, dev->name); From a551c7b0ceb72145a5256cdd53b0b52ff9f766de Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Wed, 6 Oct 2004 00:27:10 -0700 Subject: [PATCH 0854/4284] [PATCH] PATCH some cleanups and security fixes posted by Steve Grubb on https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=130351 --- udevstart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevstart.c b/udevstart.c index 9c1d69503d..ba63745620 100644 --- a/udevstart.c +++ b/udevstart.c @@ -211,7 +211,7 @@ static void udev_scan_class(void) dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN-1]; + char dirname2[MAX_PATHLEN]; DIR *dir3; struct dirent *dent3; From c8fa2d8b413f7cf1ab42d1c35865952649bfccad Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Wed, 6 Oct 2004 00:48:10 -0700 Subject: [PATCH 0855/4284] [PATCH] PATCH some cleanups and security fixes posted by Steve Grubb on https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=130351 --- udevd.c | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/udevd.c b/udevd.c index 88131d63ab..2bcb4a9e1e 100644 --- a/udevd.c +++ b/udevd.c @@ -45,9 +45,9 @@ static int pipefds[2]; static unsigned long long expected_seqnum = 0; -volatile static int children_waiting; -volatile static int run_msg_q; -volatile static int sig_flag; +static volatile int children_waiting; +static volatile int run_msg_q; +static volatile int sig_flag; static int run_exec_q; static LIST_HEAD(msg_list); @@ -397,7 +397,7 @@ int main(int argc, char *argv[]) int ssock, maxsockplus; struct sockaddr_un saddr; socklen_t addrlen; - int retval; + int retval, fd; const int on = 1; struct sigaction act; fd_set readfds; @@ -409,6 +409,22 @@ int main(int argc, char *argv[]) dbg("need to be root, exit"); exit(1); } + /* make sure we are at top of dir */ + chdir("/"); + umask( umask( 077 ) | 022 ); + /* Set fds to dev/null */ + fd = open( "/dev/null", O_RDWR ); + if ( fd < 0 ) { + dbg("error opening /dev/null %s", strerror(errno)); + exit(1); + } + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + if (fd > 2) + close(fd); + /* Get new session id so stray signals don't come our way. */ + setsid(); /* setup signal handler pipe */ retval = pipe(pipefds); @@ -418,7 +434,12 @@ int main(int argc, char *argv[]) } retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); - if (retval < 0) { + if (retval < 0) { + dbg("error fcntl on read pipe: %s", strerror(errno)); + exit(1); + } + retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); + if (retval < 0) { dbg("error fcntl on read pipe: %s", strerror(errno)); exit(1); } @@ -428,7 +449,13 @@ int main(int argc, char *argv[]) dbg("error fcntl on write pipe: %s", strerror(errno)); exit(1); } + retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC); + if (retval < 0) { + dbg("error fcntl on write pipe: %s", strerror(errno)); + exit(1); + } + /* set signal handlers */ act.sa_handler = sig_handler; sigemptyset(&act.sa_mask); @@ -456,6 +483,11 @@ int main(int argc, char *argv[]) dbg("bind failed, exit"); goto exit; } + retval = fcntl(ssock, F_SETFD, FD_CLOEXEC); + if (retval < 0) { + dbg("error fcntl on ssock: %s", strerror(errno)); + exit(1); + } /* enable receiving of the sender credentials */ setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); From 6e3e3c3416864eca74cb885f64c453eb531eed63 Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Wed, 6 Oct 2004 00:54:08 -0700 Subject: [PATCH 0856/4284] [PATCH] PATCH udev close on exec selinux wants a clean fd set, so better close all open fds --- dev_d.c | 13 +++++++++++++ namedev.c | 6 ++---- tdb/tdb.c | 7 +++++++ udev_lib.c | 19 +++++++++++++++++++ udev_lib.h | 2 +- udevd.c | 2 ++ udevsend.c | 2 ++ 7 files changed, 46 insertions(+), 5 deletions(-) diff --git a/dev_d.c b/dev_d.c index e6081b3993..c091f11c28 100644 --- a/dev_d.c +++ b/dev_d.c @@ -23,9 +23,13 @@ #include #include #include +#include #include +#include + #include "udev.h" #include "udev_lib.h" +#include "udevdb.h" #include "logging.h" #define DEVD_DIR "/etc/dev.d/" @@ -34,6 +38,7 @@ static int run_program(char *name) { pid_t pid; + int fd; dbg("running %s", name); @@ -41,6 +46,14 @@ static int run_program(char *name) switch (pid) { case 0: /* child */ + udevdb_exit(); /* close udevdb */ + fd = open("/dev/null", O_RDWR); + if ( fd >= 0) { + dup2(fd, STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + dup2(fd, STDERR_FILENO); + } + close(fd); execv(name, main_argv); dbg("exec of child failed"); exit(1); diff --git a/namedev.c b/namedev.c index c8217024c8..fe7dddaf55 100644 --- a/namedev.c +++ b/namedev.c @@ -454,10 +454,8 @@ static int execute_program(char *path, char *value, int len) switch(pid) { case 0: /* child */ - close(STDOUT_FILENO); - - /* dup write side of pipe to STDOUT */ - dup(fds[1]); + /* dup2 write side of pipe to STDOUT */ + dup2(fds[1], STDOUT_FILENO); if (argv[0] != NULL) { dbg("execute '%s' with given arguments", argv[0]); retval = execv(argv[0], argv); diff --git a/tdb/tdb.c b/tdb/tdb.c index 9ae57a974e..e87ea3692e 100644 --- a/tdb/tdb.c +++ b/tdb/tdb.c @@ -65,6 +65,7 @@ #include #include "tdb.h" #include "spinlock.h" +#include "../udev_lib.h" #else #include "includes.h" #endif @@ -1736,6 +1737,12 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, goto fail; /* errno set by open(2) */ } + /* + Close file when execing another process. + Prevents SELinux access errors. + */ + set_cloexec_flag(tdb->fd, 1); + /* ensure there is only one process initialising at once */ if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) { TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n", diff --git a/udev_lib.c b/udev_lib.c index 8f6aa42377..4991ec3acb 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -255,3 +255,22 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) closedir(dir); return 0; } + +/* Set the FD_CLOEXEC flag of desc if value is nonzero, + or clear the flag if value is 0. + Return 0 on success, or -1 on error with errno set. */ + +int set_cloexec_flag (int desc, int value) +{ + int oldflags = fcntl (desc, F_GETFD, 0); + /* If reading the flags failed, return error indication now. */ + if (oldflags < 0) + return oldflags; + /* Set just the flag we want to set. */ + if (value != 0) + oldflags |= FD_CLOEXEC; + else + oldflags &= ~FD_CLOEXEC; + /* Store modified flag word in the descriptor. */ + return fcntl (desc, F_SETFD, oldflags); +} diff --git a/udev_lib.h b/udev_lib.h index 18ce25ccc7..2f1965ea32 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -78,6 +78,6 @@ extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); extern void leading_slash(char *path); extern void no_leading_slash(char *path); extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension); - +extern int set_cloexec_flag (int desc, int value); #endif diff --git a/udevd.c b/udevd.c index 2bcb4a9e1e..81f4474a89 100644 --- a/udevd.c +++ b/udevd.c @@ -477,6 +477,8 @@ int main(int argc, char *argv[]) exit(1); } + set_cloexec_flag(ssock, 1); + /* the bind takes care of ensuring only one copy running */ retval = bind(ssock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { diff --git a/udevsend.c b/udevsend.c index 842a2a4bc4..23ba1a1b00 100644 --- a/udevsend.c +++ b/udevsend.c @@ -160,6 +160,8 @@ int main(int argc, char* argv[]) goto fallback; } + set_cloexec_flag(sock, 1); + memset(&saddr, 0x00, sizeof(struct sockaddr_un)); saddr.sun_family = AF_LOCAL; /* use abstract namespace for socket path */ From 33eae955e24feb2e473b905d64de17ad641e57e0 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 6 Oct 2004 00:58:04 -0700 Subject: [PATCH 0857/4284] [PATCH] update volume_id Here is an update to the latest volume_id which fixes a few bugs with FAT volumes. --- extras/volume_id/volume_id.c | 38 +++++++++++++++++++++--------------- extras/volume_id/volume_id.h | 3 ++- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index 99aed6c96b..f18baec6ee 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -321,7 +321,7 @@ static int probe_lvm2(struct volume_id *id, __u64 off) found: strncpy(id->type_version, lvm->type, 8); id->usage_id = VOLUME_ID_RAID; - id->type_id = VOLUME_ID_LVM1; + id->type_id = VOLUME_ID_LVM2; id->type = "LVM2_member"; return 0; @@ -461,6 +461,8 @@ static int probe_msdos_part_table(struct volume_id *id, __u64 off) p = &id->partitions[i]; + p->partition_type_raw = part[i].sys_ind; + if (is_extended(part[i].sys_ind)) { dbg("found extended partition at 0x%llx", poff); p->usage_id = VOLUME_ID_PARTITIONTABLE; @@ -535,6 +537,9 @@ static int probe_msdos_part_table(struct volume_id *id, __u64 off) p->off = current + poff; p->len = plen; id->partition_count++; + + p->partition_type_raw = part[i].sys_ind; + if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) { dbg("to many partitions"); next = 0; @@ -918,13 +923,13 @@ valid: for (i = 0; i <= root_dir_entries; i++) { /* end marker */ - if (dir[i].attr == 0x00) { + if (dir[i].name[0] == 0x00) { dbg("end of dir"); break; } /* empty entry */ - if (dir[i].attr == 0xe5) + if (dir[i].name[0] == 0xe5) continue; if (dir[i].attr == FAT_ATTR_VOLUME) { @@ -976,13 +981,13 @@ fat32: for (i = 0; i <= count; i++) { /* end marker */ - if (dir[i].attr == 0x00) { + if (dir[i].name[0] == 0x00) { dbg("end of dir"); goto fat32_label; } /* empty entry */ - if (dir[i].attr == 0xe5) + if (dir[i].name[0] == 0xe5) continue; if (dir[i].attr == FAT_ATTR_VOLUME) { @@ -1016,7 +1021,7 @@ fat32_label: set_label_raw(id, vs->type.fat32.label, 11); set_label_string(id, vs->type.fat32.label, 11); } - set_uuid(id, vs->type.fat32.serno, UUID_DCE); + set_uuid(id, vs->type.fat32.serno, UUID_DOS); found: id->usage_id = VOLUME_ID_FILESYSTEM; @@ -2035,18 +2040,25 @@ int volume_id_probe(struct volume_id *id, break; case VOLUME_ID_ALL: default: + /* probe for raid first, cause fs probes may be successful on raid members */ rc = probe_linux_raid(id, off, size); + if (rc == 0) + break; + rc = probe_lvm1(id, off); + if (rc == 0) + break; + rc = probe_lvm2(id, off); if (rc == 0) break; - /* signature in the first block */ + /* signature in the first block, only small buffer needed */ + rc = probe_msdos_part_table(id, off); + if (rc == 0) + break; rc = probe_ntfs(id, off); if (rc == 0) break; rc = probe_vfat(id, off); - if (rc == 0) - break; - rc = probe_msdos_part_table(id, off); if (rc == 0) break; rc = probe_mac_partition_map(id, off); @@ -2081,12 +2093,6 @@ int volume_id_probe(struct volume_id *id, if (rc == 0) break; rc = probe_ufs(id, off); - if (rc == 0) - break; - rc = probe_lvm1(id, off); - if (rc == 0) - break; - rc = probe_lvm2(id, off); if (rc == 0) break; diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index e68c42c3cf..c6f52bec41 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 024 +#define VOLUME_ID_VERSION 25 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 @@ -68,6 +68,7 @@ struct volume_id_partition { char *type; unsigned long long off; unsigned long long len; + unsigned int partition_type_raw; }; struct volume_id { From 71144b744acb191d357dbfeb85a256389d4fac3b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 6 Oct 2004 18:32:41 -0700 Subject: [PATCH 0858/4284] [PATCH] delete extras/multipath-tools as per the author's request This is now a standalone package. --- extras/multipath-tools/AUTHOR | 1 - extras/multipath-tools/COPYING | 483 -------- extras/multipath-tools/ChangeLog | 137 --- extras/multipath-tools/Makefile | 43 - extras/multipath-tools/README | 90 -- extras/multipath-tools/VERSION | 1 - extras/multipath-tools/devmap_name/Makefile | 49 - .../multipath-tools/devmap_name/devmap_name.8 | 30 - .../multipath-tools/devmap_name/devmap_name.c | 60 - extras/multipath-tools/libdevmapper/Makefile | 30 - .../libdevmapper/ioctl/libdevmapper.c | 1092 ----------------- .../libdevmapper/ioctl/libdm-compat.h | 111 -- .../libdevmapper/ioctl/libdm-targets.h | 51 - .../libdevmapper/libdevmapper.h | 147 --- .../libdevmapper/libdm-common.c | 382 ------ .../libdevmapper/libdm-common.h | 38 - extras/multipath-tools/libdevmapper/list.h | 99 -- extras/multipath-tools/multipath/Makefile | 62 - extras/multipath-tools/multipath/devinfo.c | 240 ---- extras/multipath-tools/multipath/devinfo.h | 21 - extras/multipath-tools/multipath/main.c | 895 -------------- extras/multipath-tools/multipath/main.h | 131 -- extras/multipath-tools/multipath/multipath.8 | 66 - .../multipath/multipath.hotplug | 7 - extras/multipath-tools/multipath/sg_err.h | 162 --- extras/multipath-tools/multipath/sg_include.h | 43 - extras/multipath-tools/multipath/unused.c | 95 -- extras/multipath-tools/multipathd/Makefile | 32 - extras/multipath-tools/multipathd/checkers.c | 62 - extras/multipath-tools/multipathd/checkers.h | 2 - extras/multipath-tools/multipathd/devinfo.c | 82 -- extras/multipath-tools/multipathd/devinfo.h | 15 - extras/multipath-tools/multipathd/main.c | 674 ---------- .../multipathd/multipathd.init | 42 - .../multipath-tools/multipathd/sg_include.h | 43 - 35 files changed, 5518 deletions(-) delete mode 100644 extras/multipath-tools/AUTHOR delete mode 100644 extras/multipath-tools/COPYING delete mode 100644 extras/multipath-tools/ChangeLog delete mode 100644 extras/multipath-tools/Makefile delete mode 100644 extras/multipath-tools/README delete mode 100644 extras/multipath-tools/VERSION delete mode 100644 extras/multipath-tools/devmap_name/Makefile delete mode 100644 extras/multipath-tools/devmap_name/devmap_name.8 delete mode 100644 extras/multipath-tools/devmap_name/devmap_name.c delete mode 100644 extras/multipath-tools/libdevmapper/Makefile delete mode 100644 extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c delete mode 100644 extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h delete mode 100644 extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h delete mode 100644 extras/multipath-tools/libdevmapper/libdevmapper.h delete mode 100644 extras/multipath-tools/libdevmapper/libdm-common.c delete mode 100644 extras/multipath-tools/libdevmapper/libdm-common.h delete mode 100644 extras/multipath-tools/libdevmapper/list.h delete mode 100644 extras/multipath-tools/multipath/Makefile delete mode 100644 extras/multipath-tools/multipath/devinfo.c delete mode 100644 extras/multipath-tools/multipath/devinfo.h delete mode 100644 extras/multipath-tools/multipath/main.c delete mode 100644 extras/multipath-tools/multipath/main.h delete mode 100644 extras/multipath-tools/multipath/multipath.8 delete mode 100644 extras/multipath-tools/multipath/multipath.hotplug delete mode 100644 extras/multipath-tools/multipath/sg_err.h delete mode 100644 extras/multipath-tools/multipath/sg_include.h delete mode 100644 extras/multipath-tools/multipath/unused.c delete mode 100644 extras/multipath-tools/multipathd/Makefile delete mode 100644 extras/multipath-tools/multipathd/checkers.c delete mode 100644 extras/multipath-tools/multipathd/checkers.h delete mode 100644 extras/multipath-tools/multipathd/devinfo.c delete mode 100644 extras/multipath-tools/multipathd/devinfo.h delete mode 100644 extras/multipath-tools/multipathd/main.c delete mode 100644 extras/multipath-tools/multipathd/multipathd.init delete mode 100644 extras/multipath-tools/multipathd/sg_include.h diff --git a/extras/multipath-tools/AUTHOR b/extras/multipath-tools/AUTHOR deleted file mode 100644 index 4e8eeef5c8..0000000000 --- a/extras/multipath-tools/AUTHOR +++ /dev/null @@ -1 +0,0 @@ -Christophe Varoqui, diff --git a/extras/multipath-tools/COPYING b/extras/multipath-tools/COPYING deleted file mode 100644 index 9e31bbf0b3..0000000000 --- a/extras/multipath-tools/COPYING +++ /dev/null @@ -1,483 +0,0 @@ - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, 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 library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, 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 companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete 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 distribute a copy of this License along with the -Library. - - 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 Library or any portion -of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -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 Library, 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 Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. 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. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library 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. - - 9. 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 Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -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. - - 11. 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 Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library 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 Library. - -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. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library 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 Library -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 Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -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 - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. 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 library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/extras/multipath-tools/ChangeLog b/extras/multipath-tools/ChangeLog deleted file mode 100644 index 0807a42678..0000000000 --- a/extras/multipath-tools/ChangeLog +++ /dev/null @@ -1,137 +0,0 @@ -2004-03-06 multipath-tools-0.1.1 - * include dlist.h in multipath main.c (PM Hahn) - * typo in hotplug script (PM Hahn) - * pass -9 opt to gzip for manpages (PM Hahn) -2004-03-05 multipath-tools-0.1.0 - * add the group_by_tur policy - * add the multipathd daemon for pathchecking & DM hot-reconfig - * multipath doesn't run twice - * massive cleanups, and code restructuring - * Avoid Kernel Bug when passing too small a buffer in do_inq() - * Sync with 2.6.3-udm4 target synthax (no more PG prio) -2004-02-21 multipath-018 - * From the Debian SID inclusion review (Philipp Matthias Hahn) - * use DESTDIR install prefix in the Makefile - * add man pages for devmap_name & multipath - * correct libsysfs.h includes - * fork the hotplug script in its own shell - * Sync with the kernel device mapper code as of 2.6.3-udm3 - ie. Remove the test interval parameter and its uses - * Remove superfluous scsi parameter passed from hotplug - * Add the man pages to the [un]install targets -2004-02-17 multipath-017 - * remove the restrictive -f flag. - Introduce a more generic "-m iopolicy" one. - * remove useless "int with_sysfs" in env struct -2004-02-04 multipath-016 - * add a GROUP_BY_SERIAL flag. This should be useful for - controlers that activate they spare paths on simple IO - submition with a penalty. The StorageWorks HW defaults to - this mode, even if the MULTIBUS mode is OK. - * remove unused sg_err.c - * big restructuring : split devinfo.c from main.c. Export : - * void basename (char *, char *); - * int get_serial (int, char *); - * int get_lun_strings (char *, char *, char *, char *); - * int get_evpd_wwid(char *, char *); - * long get_disk_size (char *); - * stop passing struct env as param - * add devmap_name proggy for udev to name devmaps as per their - internal DM name and not only by their sysfs enum name (dm-*) - The corresponding udev.rules line is : - KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" - * remove make_dm_node fn & call. Rely on udev for this. - * don't rely on the linux symlink in the udev/klibc dir since - udev build doesn't use it anymore. This corrects build breakage -2004-01-19 multipath-013 - * update the DM target synthax to the 2.6.0-udm5 style -2003-12-29 multipath-012 - * check hotplug event refers to a block device; if not exit early - * refresh doc - * add the uninstall target in Makefile -2003-12-22 multipath-010 - * tweak the install target in Makefile - * stop passing fds as argument : this change enable a strict - segregation of ugly 2.4 code - * sysfs version of get_lun_strings() - * be careful about the return of get_unique_id() since errors - formerly caught up by if(open()) in the caller fn are now returned - by get_unique_id() - * send get_serial() in unused.c - * introduce dm-simplecmd for RESUME & SUSPEND requests - * split add_map() in setup_map() & dm-addmap() - * setup_map() correctly submits "SUSPEND-RELOAD-RESUME or CREATE" - sequences instead of the bogus "RELOAD or CREATE" - * don't print .sg_dev if equal to .dev (2.6) in print_path() - * since the kernel code handles defective paths, remove all - code to cope with them : - * move do_tur() to unused.c - * remove .state from path struct - * remove .state settings & conditionals - * add a cmdline switch to force maps to failover mode, - ie 1 path per priority group - * add default policies to the whitelist array (spread io == - MULTIBUS / io forced to 1 path == FAILOVER) - * move get_disk_size() call out of add_map() to coalesce() - * comment tricky coalesce() fn - * bogus unsused.c file renamed to unused.c -2003-12-20 multipath-010 - * big ChangeLog update - * start to give a little control over target params : - introduce cmdline arg -i to control polling interval - * cope with hotplug-style calling convention : - ie "multipath scsi $DEVPATH" ... to avoid messing with - online maps not concerned by an event - * example hotplug agent to drop in /etc/hotplug.d/scsi - * revert the run & resched patch : unless someone proves me - wrong, this was overdesigned - * move commented out functions in unused.c - * update multipath target params to "udm[23] style" - * mp target now supports nr_path == 1, so do we - * add gratuitous free() - * push version forward -2003-12-15 multipath-009 - * Make the HW-specific get_unique_id switch pretty - * Prepare to field-test by whitelisting all known fibre array, - try to fetch WWID from the standard EVPD 0x83 off 8 for everyone - * configure the multipath target with round-robin path selector and - conservative default for a start (udm1 style) : - yes it makes this release the firstreally useful one. - * temporarily disable map creation for single path device - due to current restrictive defaults in the kernel target. - Sistina should work it out. - * correct the strncmp logic in blacklist function. - * update the Makefiles to autodetect libgcc.a & gcc includes - "ulibc-style". Factorisation of udevdirs & others niceties - * drop a hint about absent /dev/sd? on failed open() - * implement a reschedule flag in /var/run. - Last thing the prog do before exit is check if a call to multipath - was done (but canceled by /var/run/multipath.run check) during its - execution. If so restart themain loop. - * implement a blacklist of sysfs bdev to not bother with for now - (hd,md, dm, sr, scd, ram, raw). - This avoid sending SG_IO to unappropiate devices. - * Adds a /var/run/multipath.run handling to avoid simultaneous runs. - * Remove a commented-out "printf" - * drop a libdevmapper copy in extras/multipath; - maybe discussions w/Sistina folks will bring a better solution in the future. - * drop a putchar usage in libdevmapper to compile cleanly with klibc - * drop another such usage of my own in main.c - * massage the Makefile to compile libdevmapper against klibc - * use "ld" to produce the binary rather than "gcc -static" - * stop being stupid w/ uneeded major, minor & dev in main.c:dm_mk_node() - * reverse to creating striped target for now because the multipath target - is more hairy than expected initialy - * push the version code to 009 to be in synch w/ udev -2003-11-27 multipath-007 - * removes sg_err.[ch] deps - * makes sure the core code play nice with klibc - * port the sysfs calls to dlist helpers - * links against udev's sysfs (need libsysfs.a & dlist.a) - * finally define DM_TARGET as "multipath" as Joe posted the code today (not tested yet) - * push version forward (do you want it in sync with udev version?) -2003-11-19 - * merged in udev-006 tree -2003-09-18 Christophe Varoqui - * multipath 0.0.1 released. - * Initial release. diff --git a/extras/multipath-tools/Makefile b/extras/multipath-tools/Makefile deleted file mode 100644 index fa8830082b..0000000000 --- a/extras/multipath-tools/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# Makefile -# -# Copyright (C) 2003 Christophe Varoqui, - -SUBDIRS = libdevmapper devmap_name multipath multipathd - -recurse: - @for dir in $(SUBDIRS); do\ - $(MAKE) -C $$dir ; \ - done - -recurse_clean: - @for dir in $(SUBDIRS); do\ - $(MAKE) -C $$dir clean ; \ - done - -recurse_install: - @for dir in $(SUBDIRS); do\ - $(MAKE) -C $$dir install ; \ - done - -recurse_uninstall: - @for dir in $(SUBDIRS); do\ - $(MAKE) -C $$dir uninstall ; \ - done - -all: recurse - @echo "" - @echo "Make complete" - -clean: recurse_clean - @echo "" - @echo "Make complete" - -spotless: clean - -install: recurse_install - @echo "" - @echo "Make complete" - -uninstall: recurse_uninstall - @echo "" - @echo "Make complete" diff --git a/extras/multipath-tools/README b/extras/multipath-tools/README deleted file mode 100644 index 80945db438..0000000000 --- a/extras/multipath-tools/README +++ /dev/null @@ -1,90 +0,0 @@ -Dependancies : -============== - -o libdevmapper : comes with device-mapper-XXXX.tar.gz - See www.sistina.com - This lib has been dropped in the multipath tree -o libsysfs : comes with sysutils or udev - See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ -o Linux kernel 2.6.0 with udm5 patchset - http://people.sistina.com/~thornber/dm/ -o udev - See ftp.kernel.org/pub/linux/utils/kernel/hotplug/ - -How it works : -============== - -Fill the all_paths array. Each path store this info : - -struct path { - char dev[FILE_NAME_SIZE]; - char sg_dev[FILE_NAME_SIZE]; - struct scsi_idlun scsi_id; - struct sg_id sg_id; - int state; - char wwid[WWID_SIZE]; -}; - -scsi_id, sg_dev and sg_id are only really useful for 2.4 -kernels, for which SG cmnds must go through sg devs. -In 2.5+ we have the nice opportunity to send SG cmnds -through SCSI bdevs. - -For 2.4 compat, we pivot on idlun tupple to map sg devs -to SCSI bdevs. - -2.4 does not do device enumeration, so we must scan a -defined number of sg devs and scsi bdevs. Good enough. -In 2.5+, we rely on libsysfs (sysutils) to access to -sysfs device enums. - -the wwid is retrieved by a switch fonction. Only White -Listed HW can filled this field. For now every FC array -HW listed in kernel's devinfo.c is White Listed, assuming -the WWID is stored is the SCSI-3 standard 0x83 EVPD page. - -When all_paths is filled, we coalesce the paths and store -the result in mp array. Each mp is a struct like this : - -struct multipath { - char wwid[WWID_SIZE]; - int npaths; - int pindex[MAX_MP_PATHS]; -}; - -When mp is filled, the device maps are fed to the kernel -through libdevmapper. - -The naming of the corresponding block device is handeld -by udev with the help of the devmap_name proggy. It is -called by the following rule in /etc/udev/udev.rules : -KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \ -NAME="%k", SYMLINK="%c" - -Notes : -======= - -o On 2.4, make sure you have enough /dev/sg* nodes - (/dev/MAKEDEV if necesary). Same goes for /dev/sd* - -o path coalescing relies on a path unique id being found. - This unique id, lacking a standard method, is vendor - specific. A switch function (get_unique_id) is present - and an example function is provided for storageworks - arrays (get_evpd_wwid). Feel free to enrich - with hardware you have at hand :) - -o The kernel does NOT manage properly ghosts paths - with StorageWorks HW. Seems nobody cares after a load - of posts to linux-scsi. - -o 2.4.21 version of DM does not like even segment size. - if you enconter pbs with this, upgrade DM. - -Credits : -========= - -o Heavy cut'n paste from sg_utils. Thanks goes to D. - Gilbert. -o Light cut'n paste from dmsetup. Thanks Joe Thornber. -o Greg KH for the nice sysfs API. diff --git a/extras/multipath-tools/VERSION b/extras/multipath-tools/VERSION deleted file mode 100644 index bbdeab6222..0000000000 --- a/extras/multipath-tools/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.0.5 diff --git a/extras/multipath-tools/devmap_name/Makefile b/extras/multipath-tools/devmap_name/Makefile deleted file mode 100644 index e3b70a5e0d..0000000000 --- a/extras/multipath-tools/devmap_name/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -# Makefile -# -# Copyright (C) 2003 Christophe Varoqui, - -EXEC = devmap_name - -prefix = -exec_prefix = ${prefix} -bindir = ${exec_prefix}/sbin -udevdir = ../../.. -klibcdir = $(udevdir)/klibc -mandir = /usr/share/man/man8 -libdmdir = ../libdevmapper - -CC = gcc -GZIP = /bin/gzip -9 -c - -GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} -KERNEL_DIR = /lib/modules/${shell uname -r}/build -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ - -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ - -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. - -OBJS = devmap_name.o -CRT0 = $(klibcdir)/klibc/crt0.o -LIB = $(klibcdir)/klibc/libc.a -LIBGCC := $(shell $(CC) -print-libgcc-file-name ) - -DMOBJS = $(libdmdir)/libdm-common.o $(libdmdir)/ioctl/libdevmapper.o - -$(EXEC): $(OBJS) - $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(DMOBJS) $(LIB) $(LIBGCC) - strip $(EXEC) - $(GZIP) $(EXEC).8 > $(EXEC).8.gz - -clean: - rm -f core *.o $(EXEC) *.gz - -spotless: clean - -install: - install -d $(DESTDIR)$(bindir) - install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - install -d $(DESTDIR)$(mandir) - install -m 644 $(EXEC).8.gz $(DESTDIR)$(mandir) - -uninstall: - rm $(DESTDIR)$(bindir)/$(EXEC) - rm $(DESTDIR)$(mandir)/$(EXEC).8.gz diff --git a/extras/multipath-tools/devmap_name/devmap_name.8 b/extras/multipath-tools/devmap_name/devmap_name.8 deleted file mode 100644 index f4f03c3ec6..0000000000 --- a/extras/multipath-tools/devmap_name/devmap_name.8 +++ /dev/null @@ -1,30 +0,0 @@ -.TH DEVMAP_NAME 8 "February 2004" "" "Linux Administrator's Manual" -.SH NAME -devmap_name \- Query device-mapper name -.SH SYNOPSIS -.BI devmap_name " major minor" -.SH DESCRIPTION -.B devmap_name -queries the device-mapper for the name for the device -specified by -.I major -and -.I minor -number. -.br -.B devmap_name -can be called from -.B udev -by the following rule in -.IR /etc/udev/udev.rules : -.sp -.nf -KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", \\ - NAME="%k", SYMLINK="%c" -.fi -.SH "SEE ALSO" -.BR udev (8), -.BR dmsetup (8) -.SH AUTHORS -.B devmap_name -was developed by Christophe Varoqui, and others. diff --git a/extras/multipath-tools/devmap_name/devmap_name.c b/extras/multipath-tools/devmap_name/devmap_name.c deleted file mode 100644 index 0932e4f8bb..0000000000 --- a/extras/multipath-tools/devmap_name/devmap_name.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include - -#include "../libdevmapper/libdevmapper.h" - -static void usage(char * progname) { - fprintf(stderr, "usage : %s major minor\n", progname); - exit(1); -} - -int main(int argc, char **argv) -{ - int r = 0; - struct dm_names *names; - unsigned next = 0; - int major, minor; - - /* sanity check */ - if (argc != 3) - usage(argv[0]); - - major = atoi(argv[1]); - minor = atoi(argv[2]); - - struct dm_task *dmt; - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) - return 0; - - if (!dm_task_run(dmt)) - goto out; - - if (!(names = dm_task_get_names(dmt))) - goto out; - - if (!names->dev) { - printf("No devices found\n"); - goto out; - } - - do { - names = (void *) names + next; - if ((int) MAJOR(names->dev) == major && - (int) MINOR(names->dev) == minor) { - printf("%s\n", names->name); - goto out; - } - next = names->next; - } while (next); - - /* No correspondance found */ - r = 1; - - out: - dm_task_destroy(dmt); - return r; -} - diff --git a/extras/multipath-tools/libdevmapper/Makefile b/extras/multipath-tools/libdevmapper/Makefile deleted file mode 100644 index 4a8b7723fa..0000000000 --- a/extras/multipath-tools/libdevmapper/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# Makefile -# -# Copyright (C) 2003 Christophe Varoqui, - -CC = gcc -udevdir = ../../.. -klibcdir = $(udevdir)/klibc - -CC = gcc -GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} -KERNEL_DIR = /lib/modules/${shell uname -r}/build - -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ - -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ - -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I. -Iioctl - -OBJS = ioctl/libdevmapper.o libdm-common.o - -all: $(OBJS) - @echo "" - @echo "Make complete" - -clean: - rm -f core *.o ioctl/*.o ioctl/*.so - -spotless: clean - -install: - -uninstall: diff --git a/extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c b/extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c deleted file mode 100644 index ac7ba0c86a..0000000000 --- a/extras/multipath-tools/libdevmapper/ioctl/libdevmapper.c +++ /dev/null @@ -1,1092 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#include "libdm-targets.h" -#include "libdm-common.h" - -#ifdef DM_COMPAT -# include "libdm-compat.h" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef linux -# include -# include -# include -#else -# define MAJOR(x) major((x)) -# define MINOR(x) minor((x)) -# define MKDEV(x,y) makedev((x),(y)) -#endif - -/* - * Ensure build compatibility. - * The hard-coded versions here are the highest present - * in the _cmd_data arrays. - */ - -#if !((DM_VERSION_MAJOR == 1 && DM_VERSION_MINOR >= 0) || \ - (DM_VERSION_MAJOR == 4 && DM_VERSION_MINOR >= 0)) -#error The version of dm-ioctl.h included is incompatible. -#endif - -/* dm major version no for running kernel */ -static int _dm_version = DM_VERSION_MAJOR; -static int _log_suppress = 0; - -static int _control_fd = -1; -static int _version_checked = 0; -static int _version_ok = 1; - -/* - * Support both old and new major numbers to ease the transition. - * Clumsy, but only temporary. - */ -#if DM_VERSION_MAJOR == 4 && defined(DM_COMPAT) -const int _dm_compat = 1; -#else -const int _dm_compat = 0; -#endif - - -/* *INDENT-OFF* */ -static struct cmd_data _cmd_data_v4[] = { - {"create", DM_DEV_CREATE, {4, 0, 0}}, - {"reload", DM_TABLE_LOAD, {4, 0, 0}}, - {"remove", DM_DEV_REMOVE, {4, 0, 0}}, - {"remove_all", DM_REMOVE_ALL, {4, 0, 0}}, - {"suspend", DM_DEV_SUSPEND, {4, 0, 0}}, - {"resume", DM_DEV_SUSPEND, {4, 0, 0}}, - {"info", DM_DEV_STATUS, {4, 0, 0}}, - {"deps", DM_TABLE_DEPS, {4, 0, 0}}, - {"rename", DM_DEV_RENAME, {4, 0, 0}}, - {"version", DM_VERSION, {4, 0, 0}}, - {"status", DM_TABLE_STATUS, {4, 0, 0}}, - {"table", DM_TABLE_STATUS, {4, 0, 0}}, - {"waitevent", DM_DEV_WAIT, {4, 0, 0}}, - {"names", DM_LIST_DEVICES, {4, 0, 0}}, - {"clear", DM_TABLE_CLEAR, {4, 0, 0}}, - {"mknodes", DM_DEV_STATUS, {4, 0, 0}}, -}; -/* *INDENT-ON* */ - -#define ALIGNMENT_V1 sizeof(int) -#define ALIGNMENT 8 - -/* FIXME Rejig library to record & use errno instead */ -#ifndef DM_EXISTS_FLAG -# define DM_EXISTS_FLAG 0x00000004 -#endif - -static void *_align(void *ptr, unsigned int a) -{ - register unsigned long agn = --a; - - return (void *) (((unsigned long) ptr + agn) & ~agn); -} - -static int _open_control(void) -{ - char control[PATH_MAX]; - - if (_control_fd != -1) - return 1; - - snprintf(control, sizeof(control), "%s/control", dm_dir()); - - if ((_control_fd = open(control, O_RDWR)) < 0) { - log_error("%s: open failed: %s", control, strerror(errno)); - log_error("Is device-mapper driver missing from kernel?"); - return 0; - } - - return 1; -} - -void dm_task_destroy(struct dm_task *dmt) -{ - struct target *t, *n; - - for (t = dmt->head; t; t = n) { - n = t->next; - free(t->params); - free(t->type); - free(t); - } - - if (dmt->dev_name) - free(dmt->dev_name); - - if (dmt->newname) - free(dmt->newname); - - if (dmt->dmi.v4) - free(dmt->dmi.v4); - - if (dmt->uuid) - free(dmt->uuid); - - free(dmt); -} - -/* - * Protocol Version 1 compatibility functions. - */ - -#ifdef DM_COMPAT - -static int _dm_task_get_driver_version_v1(struct dm_task *dmt, char *version, - size_t size) -{ - unsigned int *v; - - if (!dmt->dmi.v1) { - version[0] = '\0'; - return 0; - } - - v = dmt->dmi.v1->version; - snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); - return 1; -} - -/* Unmarshall the target info returned from a status call */ -static int _unmarshal_status_v1(struct dm_task *dmt, struct dm_ioctl_v1 *dmi) -{ - char *outbuf = (char *) dmi + dmi->data_start; - char *outptr = outbuf; - int32_t i; - struct dm_target_spec_v1 *spec; - - for (i = 0; i < dmi->target_count; i++) { - spec = (struct dm_target_spec_v1 *) outptr; - - if (!dm_task_add_target(dmt, spec->sector_start, - (uint64_t) spec->length, - spec->target_type, - outptr + sizeof(*spec))) - return 0; - - outptr = outbuf + spec->next; - } - - return 1; -} - -static int _dm_format_dev_v1(char *buf, int bufsize, uint32_t dev_major, - uint32_t dev_minor) -{ - int r; - - if (bufsize < 8) - return 0; - - r = snprintf(buf, bufsize, "%03x:%03x", dev_major, dev_minor); - if (r < 0 || r > bufsize - 1) - return 0; - - return 1; -} - -static int _dm_task_get_info_v1(struct dm_task *dmt, struct dm_info *info) -{ - if (!dmt->dmi.v1) - return 0; - - memset(info, 0, sizeof(*info)); - - info->exists = dmt->dmi.v1->flags & DM_EXISTS_FLAG ? 1 : 0; - if (!info->exists) - return 1; - - info->suspended = dmt->dmi.v1->flags & DM_SUSPEND_FLAG ? 1 : 0; - info->read_only = dmt->dmi.v1->flags & DM_READONLY_FLAG ? 1 : 0; - info->target_count = dmt->dmi.v1->target_count; - info->open_count = dmt->dmi.v1->open_count; - info->event_nr = 0; - info->major = MAJOR(dmt->dmi.v1->dev); - info->minor = MINOR(dmt->dmi.v1->dev); - info->live_table = 1; - info->inactive_table = 0; - - return 1; -} - -static const char *_dm_task_get_name_v1(struct dm_task *dmt) -{ - return (dmt->dmi.v1->name); -} - -static const char *_dm_task_get_uuid_v1(struct dm_task *dmt) -{ - return (dmt->dmi.v1->uuid); -} - -static struct dm_deps *_dm_task_get_deps_v1(struct dm_task *dmt) -{ - log_error("deps version 1 no longer supported by libdevmapper"); - return NULL; -} - -static struct dm_names *_dm_task_get_names_v1(struct dm_task *dmt) -{ - return (struct dm_names *) (((void *) dmt->dmi.v1) + - dmt->dmi.v1->data_start); -} - -static void *_add_target_v1(struct target *t, void *out, void *end) -{ - void *out_sp = out; - struct dm_target_spec_v1 sp; - size_t sp_size = sizeof(struct dm_target_spec_v1); - int len; - const char no_space[] = "Ran out of memory building ioctl parameter"; - - out += sp_size; - if (out >= end) { - log_error(no_space); - return NULL; - } - - sp.status = 0; - sp.sector_start = t->start; - sp.length = t->length; - strncpy(sp.target_type, t->type, sizeof(sp.target_type)); - - len = strlen(t->params); - - if ((out + len + 1) >= end) { - log_error(no_space); - - log_error("t->params= '%s'", t->params); - return NULL; - } - strcpy((char *) out, t->params); - out += len + 1; - - /* align next block */ - out = _align(out, ALIGNMENT_V1); - - sp.next = out - out_sp; - - memcpy(out_sp, &sp, sp_size); - - return out; -} - -static struct dm_ioctl_v1 *_flatten_v1(struct dm_task *dmt) -{ - const size_t min_size = 16 * 1024; - const int (*version)[3]; - - struct dm_ioctl_v1 *dmi; - struct target *t; - size_t len = sizeof(struct dm_ioctl_v1); - void *b, *e; - int count = 0; - - for (t = dmt->head; t; t = t->next) { - len += sizeof(struct dm_target_spec_v1); - len += strlen(t->params) + 1 + ALIGNMENT_V1; - count++; - } - - if (count && dmt->newname) { - log_error("targets and newname are incompatible"); - return NULL; - } - - if (dmt->newname) - len += strlen(dmt->newname) + 1; - - /* - * Give len a minimum size so that we have space to store - * dependencies or status information. - */ - if (len < min_size) - len = min_size; - - if (!(dmi = malloc(len))) - return NULL; - - memset(dmi, 0, len); - - version = &_cmd_data_v1[dmt->type].version; - - dmi->version[0] = (*version)[0]; - dmi->version[1] = (*version)[1]; - dmi->version[2] = (*version)[2]; - - dmi->data_size = len; - dmi->data_start = sizeof(struct dm_ioctl_v1); - - if (dmt->dev_name) - strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); - - if (dmt->type == DM_DEVICE_SUSPEND) - dmi->flags |= DM_SUSPEND_FLAG; - if (dmt->read_only) - dmi->flags |= DM_READONLY_FLAG; - - if (dmt->minor >= 0) { - if (dmt->major <= 0) { - log_error("Missing major number for persistent device"); - return NULL; - } - dmi->flags |= DM_PERSISTENT_DEV_FLAG; - dmi->dev = MKDEV(dmt->major, dmt->minor); - } - - if (dmt->uuid) - strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); - - dmi->target_count = count; - - b = (void *) (dmi + 1); - e = (void *) ((char *) dmi + len); - - for (t = dmt->head; t; t = t->next) - if (!(b = _add_target_v1(t, b, e))) - goto bad; - - if (dmt->newname) - strcpy(b, dmt->newname); - - return dmi; - - bad: - free(dmi); - return NULL; -} - -static int _dm_names_v1(struct dm_ioctl_v1 *dmi) -{ - const char *dev_dir = dm_dir(); - int r = 1, len; - const char *name; - struct dirent *dirent; - DIR *d; - struct dm_names *names, *old_names = NULL; - void *end = (void *) dmi + dmi->data_size; - struct stat buf; - char path[PATH_MAX]; - - if (!(d = opendir(dev_dir))) { - log_error("%s: opendir failed: %s", dev_dir, strerror(errno)); - return 0; - } - - names = (struct dm_names *) ((void *) dmi + dmi->data_start); - - names->dev = 0; /* Flags no data */ - - while ((dirent = readdir(d))) { - name = dirent->d_name; - - if (name[0] == '.' || !strcmp(name, "control")) - continue; - - if (old_names) - old_names->next = (uint32_t) ((void *) names - - (void *) old_names); - snprintf(path, sizeof(path), "%s/%s", dev_dir, name); - if (stat(path, &buf)) { - log_error("%s: stat failed: %s", path, strerror(errno)); - continue; - } - if (!S_ISBLK(buf.st_mode)) - continue; - names->dev = (uint64_t) buf.st_rdev; - names->next = 0; - len = strlen(name); - if (((void *) (names + 1) + len + 1) >= end) { - log_error("Insufficient buffer space for device list"); - r = 0; - break; - } - - strcpy(names->name, name); - - old_names = names; - names = _align((void *) ++names + len + 1, ALIGNMENT); - } - - if (closedir(d)) - log_error("%s: closedir failed: %s", dev_dir, strerror(errno)); - - return r; -} - -static int _dm_task_run_v1(struct dm_task *dmt) -{ - struct dm_ioctl_v1 *dmi; - unsigned int command; - - dmi = _flatten_v1(dmt); - if (!dmi) { - log_error("Couldn't create ioctl argument"); - return 0; - } - - if (!_open_control()) - return 0; - - if ((unsigned) dmt->type >= - (sizeof(_cmd_data_v1) / sizeof(*_cmd_data_v1))) { - log_error("Internal error: unknown device-mapper task %d", - dmt->type); - goto bad; - } - - command = _cmd_data_v1[dmt->type].cmd; - - if (dmt->type == DM_DEVICE_TABLE) - dmi->flags |= DM_STATUS_TABLE_FLAG; - - log_debug("dm %s %s %s %s", _cmd_data_v1[dmt->type].name, dmi->name, - dmi->uuid, dmt->newname ? dmt->newname : ""); - if (dmt->type == DM_DEVICE_LIST) { - if (!_dm_names_v1(dmi)) - goto bad; - } else if (ioctl(_control_fd, command, dmi) < 0) { - if (_log_suppress) - log_verbose("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - else - log_error("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - goto bad; - } - - switch (dmt->type) { - case DM_DEVICE_CREATE: - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); - break; - - case DM_DEVICE_REMOVE: - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_RENAME: - rename_dev_node(dmt->dev_name, dmt->newname); - break; - - case DM_DEVICE_MKNODES: - if (dmi->flags & DM_EXISTS_FLAG) - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), - MINOR(dmi->dev)); - else - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_STATUS: - case DM_DEVICE_TABLE: - if (!_unmarshal_status_v1(dmt, dmi)) - goto bad; - break; - - case DM_DEVICE_SUSPEND: - case DM_DEVICE_RESUME: - dmt->type = DM_DEVICE_INFO; - if (!dm_task_run(dmt)) - goto bad; - free(dmi); /* We'll use what info returned */ - return 1; - } - - dmt->dmi.v1 = dmi; - return 1; - - bad: - free(dmi); - return 0; -} - -#endif - -/* - * Protocol Version 4 functions. - */ - -int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size) -{ - unsigned int *v; - -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_driver_version_v1(dmt, version, size); -#endif - - if (!dmt->dmi.v4) { - version[0] = '\0'; - return 0; - } - - v = dmt->dmi.v4->version; - snprintf(version, size, "%u.%u.%u", v[0], v[1], v[2]); - return 1; -} - -static int _check_version(char *version, size_t size, int log_suppress) -{ - struct dm_task *task; - int r; - - if (!(task = dm_task_create(DM_DEVICE_VERSION))) { - log_error("Failed to get device-mapper version"); - version[0] = '\0'; - return 0; - } - - if (log_suppress) - _log_suppress = 1; - - r = dm_task_run(task); - dm_task_get_driver_version(task, version, size); - dm_task_destroy(task); - _log_suppress = 0; - - return r; -} - -/* - * Find out device-mapper's major version number the first time - * this is called and whether or not we support it. - */ -int dm_check_version(void) -{ - char libversion[64], dmversion[64]; - const char *compat = ""; - - if (_version_checked) - return _version_ok; - - _version_checked = 1; - - if (_check_version(dmversion, sizeof(dmversion), _dm_compat)) - return 1; - - if (!_dm_compat) - goto bad; - - log_verbose("device-mapper ioctl protocol version %d failed. " - "Trying protocol version 1.", _dm_version); - _dm_version = 1; - if (_check_version(dmversion, sizeof(dmversion), 0)) { - log_verbose("Using device-mapper ioctl protocol version 1"); - return 1; - } - - compat = "(compat)"; - - dm_get_library_version(libversion, sizeof(libversion)); - - log_error("Incompatible libdevmapper %s%s and kernel driver %s", - libversion, compat, dmversion); - - bad: - _version_ok = 0; - return 0; -} - -void *dm_get_next_target(struct dm_task *dmt, void *next, - uint64_t *start, uint64_t *length, - char **target_type, char **params) -{ - struct target *t = (struct target *) next; - - if (!t) - t = dmt->head; - - if (!t) - return NULL; - - *start = t->start; - *length = t->length; - *target_type = t->type; - *params = t->params; - - return t->next; -} - -/* Unmarshall the target info returned from a status call */ -static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi) -{ - char *outbuf = (char *) dmi + dmi->data_start; - char *outptr = outbuf; - uint32_t i; - struct dm_target_spec *spec; - - for (i = 0; i < dmi->target_count; i++) { - spec = (struct dm_target_spec *) outptr; - if (!dm_task_add_target(dmt, spec->sector_start, - spec->length, - spec->target_type, - outptr + sizeof(*spec))) - return 0; - - outptr = outbuf + spec->next; - } - - return 1; -} - -int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, - uint32_t dev_minor) -{ - int r; - -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_format_dev_v1(buf, bufsize, dev_major, dev_minor); -#endif - - if (bufsize < 8) - return 0; - - r = snprintf(buf, bufsize, "%03u:%03u", dev_major, dev_minor); - if (r < 0 || r > bufsize - 1) - return 0; - - return 1; -} - -int dm_task_get_info(struct dm_task *dmt, struct dm_info *info) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_info_v1(dmt, info); -#endif - - if (!dmt->dmi.v4) - return 0; - - memset(info, 0, sizeof(*info)); - - info->exists = dmt->dmi.v4->flags & DM_EXISTS_FLAG ? 1 : 0; - if (!info->exists) - return 1; - - info->suspended = dmt->dmi.v4->flags & DM_SUSPEND_FLAG ? 1 : 0; - info->read_only = dmt->dmi.v4->flags & DM_READONLY_FLAG ? 1 : 0; - info->live_table = dmt->dmi.v4->flags & DM_ACTIVE_PRESENT_FLAG ? 1 : 0; - info->inactive_table = dmt->dmi.v4->flags & DM_INACTIVE_PRESENT_FLAG ? - 1 : 0; - info->target_count = dmt->dmi.v4->target_count; - info->open_count = dmt->dmi.v4->open_count; - info->event_nr = dmt->dmi.v4->event_nr; - info->major = MAJOR(dmt->dmi.v4->dev); - info->minor = MINOR(dmt->dmi.v4->dev); - - return 1; -} - -const char *dm_task_get_name(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_name_v1(dmt); -#endif - - return (dmt->dmi.v4->name); -} - -const char *dm_task_get_uuid(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_uuid_v1(dmt); -#endif - - return (dmt->dmi.v4->uuid); -} - -struct dm_deps *dm_task_get_deps(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_deps_v1(dmt); -#endif - - return (struct dm_deps *) (((void *) dmt->dmi.v4) + - dmt->dmi.v4->data_start); -} - -struct dm_names *dm_task_get_names(struct dm_task *dmt) -{ -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_get_names_v1(dmt); -#endif - - return (struct dm_names *) (((void *) dmt->dmi.v4) + - dmt->dmi.v4->data_start); -} - -int dm_task_set_ro(struct dm_task *dmt) -{ - dmt->read_only = 1; - return 1; -} - -int dm_task_set_newname(struct dm_task *dmt, const char *newname) -{ - if (!(dmt->newname = strdup(newname))) { - log_error("dm_task_set_newname: strdup(%s) failed", newname); - return 0; - } - - return 1; -} - -int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr) -{ - dmt->event_nr = event_nr; - - return 1; -} - -struct target *create_target(uint64_t start, uint64_t len, const char *type, - const char *params) -{ - struct target *t = malloc(sizeof(*t)); - - if (!t) { - log_error("create_target: malloc(%d) failed", sizeof(*t)); - return NULL; - } - - memset(t, 0, sizeof(*t)); - - if (!(t->params = strdup(params))) { - log_error("create_target: strdup(params) failed"); - goto bad; - } - - if (!(t->type = strdup(type))) { - log_error("create_target: strdup(type) failed"); - goto bad; - } - - t->start = start; - t->length = len; - return t; - - bad: - free(t->params); - free(t->type); - free(t); - return NULL; -} - -static void *_add_target(struct target *t, void *out, void *end) -{ - void *out_sp = out; - struct dm_target_spec sp; - size_t sp_size = sizeof(struct dm_target_spec); - int len; - const char no_space[] = "Ran out of memory building ioctl parameter"; - - out += sp_size; - if (out >= end) { - log_error(no_space); - return NULL; - } - - sp.status = 0; - sp.sector_start = t->start; - sp.length = t->length; - strncpy(sp.target_type, t->type, sizeof(sp.target_type)); - - len = strlen(t->params); - - if ((out + len + 1) >= end) { - log_error(no_space); - - log_error("t->params= '%s'", t->params); - return NULL; - } - strcpy((char *) out, t->params); - out += len + 1; - - /* align next block */ - out = _align(out, ALIGNMENT); - - sp.next = out - out_sp; - memcpy(out_sp, &sp, sp_size); - - return out; -} - -static struct dm_ioctl *_flatten(struct dm_task *dmt) -{ - const size_t min_size = 16 * 1024; - const int (*version)[3]; - - struct dm_ioctl *dmi; - struct target *t; - size_t len = sizeof(struct dm_ioctl); - void *b, *e; - int count = 0; - - for (t = dmt->head; t; t = t->next) { - len += sizeof(struct dm_target_spec); - len += strlen(t->params) + 1 + ALIGNMENT; - count++; - } - - if (count && dmt->newname) { - log_error("targets and newname are incompatible"); - return NULL; - } - - if (dmt->newname) - len += strlen(dmt->newname) + 1; - - /* - * Give len a minimum size so that we have space to store - * dependencies or status information. - */ - if (len < min_size) - len = min_size; - - if (!(dmi = malloc(len))) - return NULL; - - memset(dmi, 0, len); - - version = &_cmd_data_v4[dmt->type].version; - - dmi->version[0] = (*version)[0]; - dmi->version[1] = (*version)[1]; - dmi->version[2] = (*version)[2]; - - dmi->data_size = len; - dmi->data_start = sizeof(struct dm_ioctl); - - if (dmt->dev_name) - strncpy(dmi->name, dmt->dev_name, sizeof(dmi->name)); - - if (dmt->type == DM_DEVICE_SUSPEND) - dmi->flags |= DM_SUSPEND_FLAG; - if (dmt->read_only) - dmi->flags |= DM_READONLY_FLAG; - - if (dmt->minor >= 0) { - if (dmt->major <= 0) { - log_error("Missing major number for persistent device"); - return NULL; - } - dmi->flags |= DM_PERSISTENT_DEV_FLAG; - dmi->dev = MKDEV(dmt->major, dmt->minor); - } - - if (dmt->uuid) - strncpy(dmi->uuid, dmt->uuid, sizeof(dmi->uuid)); - - dmi->target_count = count; - dmi->event_nr = dmt->event_nr; - - b = (void *) (dmi + 1); - e = (void *) ((char *) dmi + len); - - for (t = dmt->head; t; t = t->next) - if (!(b = _add_target(t, b, e))) - goto bad; - - if (dmt->newname) - strcpy(b, dmt->newname); - - return dmi; - - bad: - free(dmi); - return NULL; -} - -static int _create_and_load_v4(struct dm_task *dmt) -{ - struct dm_task *task; - int r; - - /* Use new task struct to create the device */ - if (!(task = dm_task_create(DM_DEVICE_CREATE))) { - log_error("Failed to create device-mapper task struct"); - return 0; - } - - /* Copy across relevant fields */ - if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { - dm_task_destroy(task); - return 0; - } - - if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) { - dm_task_destroy(task); - return 0; - } - - task->major = dmt->major; - task->minor = dmt->minor; - - r = dm_task_run(task); - dm_task_destroy(task); - if (!r) - return r; - - /* Next load the table */ - if (!(task = dm_task_create(DM_DEVICE_RELOAD))) { - log_error("Failed to create device-mapper task struct"); - return 0; - } - - /* Copy across relevant fields */ - if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) { - dm_task_destroy(task); - return 0; - } - - task->read_only = dmt->read_only; - task->head = dmt->head; - task->tail = dmt->tail; - - r = dm_task_run(task); - - task->head = NULL; - task->tail = NULL; - dm_task_destroy(task); - if (!r) - return r; - - /* Use the original structure last so the info will be correct */ - dmt->type = DM_DEVICE_RESUME; - dmt->uuid = NULL; - free(dmt->uuid); - - r = dm_task_run(dmt); - - return r; -} - -int dm_task_run(struct dm_task *dmt) -{ - struct dm_ioctl *dmi = NULL; - unsigned int command; - -#ifdef DM_COMPAT - if (_dm_version == 1) - return _dm_task_run_v1(dmt); -#endif - - if ((unsigned) dmt->type >= - (sizeof(_cmd_data_v4) / sizeof(*_cmd_data_v4))) { - log_error("Internal error: unknown device-mapper task %d", - dmt->type); - goto bad; - } - - command = _cmd_data_v4[dmt->type].cmd; - - /* Old-style creation had a table supplied */ - if (dmt->type == DM_DEVICE_CREATE && dmt->head) - return _create_and_load_v4(dmt); - - if (!_open_control()) - return 0; - - dmi = _flatten(dmt); - if (!dmi) { - log_error("Couldn't create ioctl argument"); - return 0; - } - - if (dmt->type == DM_DEVICE_TABLE) - dmi->flags |= DM_STATUS_TABLE_FLAG; - - dmi->flags |= DM_EXISTS_FLAG; /* FIXME */ - log_debug("dm %s %s %s %s", _cmd_data_v4[dmt->type].name, dmi->name, - dmi->uuid, dmt->newname ? dmt->newname : ""); - if (ioctl(_control_fd, command, dmi) < 0) { - if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) || - (dmt->type == DM_DEVICE_MKNODES))) { - dmi->flags &= ~DM_EXISTS_FLAG; /* FIXME */ - goto ignore_error; - } - if (_log_suppress) - log_verbose("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - else - log_error("device-mapper ioctl cmd %d failed: %s", - _IOC_NR(command), strerror(errno)); - goto bad; - } - - ignore_error: - switch (dmt->type) { - case DM_DEVICE_CREATE: - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), MINOR(dmi->dev)); - break; - - case DM_DEVICE_REMOVE: - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_RENAME: - rename_dev_node(dmt->dev_name, dmt->newname); - break; - - case DM_DEVICE_MKNODES: - if (dmi->flags & DM_EXISTS_FLAG) - add_dev_node(dmt->dev_name, MAJOR(dmi->dev), - MINOR(dmi->dev)); - else - rm_dev_node(dmt->dev_name); - break; - - case DM_DEVICE_STATUS: - case DM_DEVICE_TABLE: - case DM_DEVICE_WAITEVENT: - if (!_unmarshal_status(dmt, dmi)) - goto bad; - break; - } - - dmt->dmi.v4 = dmi; - return 1; - - bad: - free(dmi); - return 0; -} - -void dm_lib_release(void) -{ - if (_control_fd != -1) { - close(_control_fd); - _control_fd = -1; - } - update_devs(); -} - -void dm_lib_exit(void) -{ - if (_control_fd != -1) { - close(_control_fd); - _control_fd = -1; - } - _version_ok = 1; - _version_checked = 0; -} diff --git a/extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h b/extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h deleted file mode 100644 index af7a9f1f71..0000000000 --- a/extras/multipath-tools/libdevmapper/ioctl/libdm-compat.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef _LINUX_LIBDM_COMPAT_H -#define _LINUX_LIBDM_COMPAT_H - -#include -#include -#include -#include - -struct dm_task; -struct dm_info; - -/* - * Old versions of structures for backwards compatibility. - */ - -struct dm_ioctl_v1 { - uint32_t version[3]; /* in/out */ - uint32_t data_size; /* total size of data passed in - * including this struct */ - - uint32_t data_start; /* offset to start of data - * relative to start of this struct */ - - int32_t target_count; /* in/out */ - int32_t open_count; /* out */ - uint32_t flags; /* in/out */ - - __kernel_dev_t dev; /* in/out */ - - char name[DM_NAME_LEN]; /* device name */ - char uuid[DM_UUID_LEN]; /* unique identifier for - * the block device */ -}; - -struct dm_target_spec_v1 { - int32_t status; /* used when reading from kernel only */ - uint64_t sector_start; - uint32_t length; - uint32_t next; - - char target_type[DM_MAX_TYPE_NAME]; - -}; - -struct dm_target_deps_v1 { - uint32_t count; - - __kernel_dev_t dev[0]; /* out */ -}; - -enum { - /* Top level cmds */ - DM_VERSION_CMD_V1 = 0, - DM_REMOVE_ALL_CMD_V1, - - /* device level cmds */ - DM_DEV_CREATE_CMD_V1, - DM_DEV_REMOVE_CMD_V1, - DM_DEV_RELOAD_CMD_V1, - DM_DEV_RENAME_CMD_V1, - DM_DEV_SUSPEND_CMD_V1, - DM_DEV_DEPS_CMD_V1, - DM_DEV_STATUS_CMD_V1, - - /* target level cmds */ - DM_TARGET_STATUS_CMD_V1, - DM_TARGET_WAIT_CMD_V1, -}; - -#define DM_VERSION_V1 _IOWR(DM_IOCTL, DM_VERSION_CMD_V1, struct dm_ioctl) -#define DM_REMOVE_ALL_V1 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD_V1, struct dm_ioctl) - -#define DM_DEV_CREATE_V1 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD_V1, struct dm_ioctl) -#define DM_DEV_REMOVE_V1 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD_V1, struct dm_ioctl) -#define DM_DEV_RELOAD_V1 _IOWR(DM_IOCTL, DM_DEV_RELOAD_CMD_V1, struct dm_ioctl) -#define DM_DEV_SUSPEND_V1 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD_V1, struct dm_ioctl) -#define DM_DEV_RENAME_V1 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD_V1, struct dm_ioctl) -#define DM_DEV_DEPS_V1 _IOWR(DM_IOCTL, DM_DEV_DEPS_CMD_V1, struct dm_ioctl) -#define DM_DEV_STATUS_V1 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD_V1, struct dm_ioctl) - -#define DM_TARGET_STATUS_V1 _IOWR(DM_IOCTL, DM_TARGET_STATUS_CMD_V1, struct dm_ioctl) -#define DM_TARGET_WAIT_V1 _IOWR(DM_IOCTL, DM_TARGET_WAIT_CMD_V1, struct dm_ioctl) - -/* *INDENT-OFF* */ -static struct cmd_data _cmd_data_v1[] = { - { "create", DM_DEV_CREATE_V1, {1, 0, 0} }, - { "reload", DM_DEV_RELOAD_V1, {1, 0, 0} }, - { "remove", DM_DEV_REMOVE_V1, {1, 0, 0} }, - { "remove_all", DM_REMOVE_ALL_V1, {1, 0, 0} }, - { "suspend", DM_DEV_SUSPEND_V1, {1, 0, 0} }, - { "resume", DM_DEV_SUSPEND_V1, {1, 0, 0} }, - { "info", DM_DEV_STATUS_V1, {1, 0, 0} }, - { "deps", DM_DEV_DEPS_V1, {1, 0, 0} }, - { "rename", DM_DEV_RENAME_V1, {1, 0, 0} }, - { "version", DM_VERSION_V1, {1, 0, 0} }, - { "status", DM_TARGET_STATUS_V1, {1, 0, 0} }, - { "table", DM_TARGET_STATUS_V1, {1, 0, 0} }, - { "waitevent", DM_TARGET_WAIT_V1, {1, 0, 0} }, - { "names", 0, {4, 0, 0} }, - { "clear", 0, {4, 0, 0} }, - { "mknodes", 0, {4, 0, 0} }, -}; -/* *INDENT-ON* */ - -#endif diff --git a/extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h b/extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h deleted file mode 100644 index a8c0e20547..0000000000 --- a/extras/multipath-tools/libdevmapper/ioctl/libdm-targets.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef LIB_DMTARGETS_H -#define LIB_DMTARGETS_H - -#include - -struct dm_ioctl; -struct dm_ioctl_v1; - -struct target { - uint64_t start; - uint64_t length; - char *type; - char *params; - - struct target *next; -}; - -struct dm_task { - int type; - char *dev_name; - - struct target *head, *tail; - - int read_only; - uint32_t event_nr; - int major; - int minor; - union { - struct dm_ioctl *v4; - struct dm_ioctl_v1 *v1; - } dmi; - char *newname; - - char *uuid; -}; - -struct cmd_data { - const char *name; - const int cmd; - const int version[3]; -}; - -int dm_check_version(void); - -#endif diff --git a/extras/multipath-tools/libdevmapper/libdevmapper.h b/extras/multipath-tools/libdevmapper/libdevmapper.h deleted file mode 100644 index 6549af3641..0000000000 --- a/extras/multipath-tools/libdevmapper/libdevmapper.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef LIB_DEVICE_MAPPER_H -#define LIB_DEVICE_MAPPER_H - -#include -#include - -#ifdef linux -# include -#endif - -/* - * Since it is quite laborious to build the ioctl - * arguments for the device-mapper people are - * encouraged to use this library. - * - * You will need to build a struct dm_task for - * each ioctl command you want to execute. - */ - -typedef void (*dm_log_fn) (int level, const char *file, int line, - const char *f, ...); - -/* - * The library user may wish to register their own - * logging function, by default errors go to - * stderr. - */ -void dm_log_init(dm_log_fn fn); -void dm_log_init_verbose(int level); - -enum { - DM_DEVICE_CREATE, - DM_DEVICE_RELOAD, - DM_DEVICE_REMOVE, - DM_DEVICE_REMOVE_ALL, - - DM_DEVICE_SUSPEND, - DM_DEVICE_RESUME, - - DM_DEVICE_INFO, - DM_DEVICE_DEPS, - DM_DEVICE_RENAME, - - DM_DEVICE_VERSION, - - DM_DEVICE_STATUS, - DM_DEVICE_TABLE, - DM_DEVICE_WAITEVENT, - - DM_DEVICE_LIST, - - DM_DEVICE_CLEAR, - - DM_DEVICE_MKNODES -}; - -struct dm_task; - -struct dm_task *dm_task_create(int type); -void dm_task_destroy(struct dm_task *dmt); - -int dm_task_set_name(struct dm_task *dmt, const char *name); -int dm_task_set_uuid(struct dm_task *dmt, const char *uuid); - -/* - * Retrieve attributes after an info. - */ -struct dm_info { - int exists; - int suspended; - int live_table; - int inactive_table; - int32_t open_count; - uint32_t event_nr; - uint32_t major; - uint32_t minor; /* minor device number */ - int read_only; /* 0:read-write; 1:read-only */ - - int32_t target_count; -}; - -struct dm_deps { - uint32_t count; - uint32_t filler; - uint64_t device[0]; -}; - -struct dm_names { - uint64_t dev; - uint32_t next; /* Offset to next struct from start of this struct */ - char name[0]; -}; - -int dm_get_library_version(char *version, size_t size); -int dm_task_get_driver_version(struct dm_task *dmt, char *version, size_t size); -int dm_task_get_info(struct dm_task *dmt, struct dm_info *dmi); -const char *dm_task_get_name(struct dm_task *dmt); -const char *dm_task_get_uuid(struct dm_task *dmt); - -struct dm_deps *dm_task_get_deps(struct dm_task *dmt); -struct dm_names *dm_task_get_names(struct dm_task *dmt); - -int dm_task_set_ro(struct dm_task *dmt); -int dm_task_set_newname(struct dm_task *dmt, const char *newname); -int dm_task_set_minor(struct dm_task *dmt, int minor); -int dm_task_set_major(struct dm_task *dmt, int major); -int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr); - -/* - * Use these to prepare for a create or reload. - */ -int dm_task_add_target(struct dm_task *dmt, - uint64_t start, - uint64_t size, const char *ttype, const char *params); - -/* - * Format major/minor numbers correctly for input to driver - */ -int dm_format_dev(char *buf, int bufsize, uint32_t dev_major, uint32_t dev_minor); - -/* Use this to retrive target information returned from a STATUS call */ -void *dm_get_next_target(struct dm_task *dmt, - void *next, uint64_t *start, uint64_t *length, - char **target_type, char **params); - -/* - * Call this to actually run the ioctl. - */ -int dm_task_run(struct dm_task *dmt); - -/* - * Configure the device-mapper directory - */ -int dm_set_dev_dir(const char *dir); -const char *dm_dir(void); - -/* Release library resources */ -void dm_lib_release(void); -void dm_lib_exit(void); - -#endif /* LIB_DEVICE_MAPPER_H */ diff --git a/extras/multipath-tools/libdevmapper/libdm-common.c b/extras/multipath-tools/libdevmapper/libdm-common.c deleted file mode 100644 index b0affd1eed..0000000000 --- a/extras/multipath-tools/libdevmapper/libdm-common.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#include "libdm-targets.h" -#include "libdm-common.h" -#include "list.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEV_DIR "/dev/" - -static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR; - -static int _verbose = 0; - -/* - * Library users can provide their own logging - * function. - */ -static void _default_log(int level, const char *file, int line, - const char *f, ...) -{ - va_list ap; - - if (level > _LOG_WARN && !_verbose) - return; - - va_start(ap, f); - - if (level < _LOG_WARN) - vfprintf(stderr, f, ap); - else - vprintf(f, ap); - - va_end(ap); - - if (level < _LOG_WARN) - fprintf(stderr, "\n"); - else - fprintf(stdout, "\n"); -} - -dm_log_fn _log = _default_log; - -void dm_log_init(dm_log_fn fn) -{ - _log = fn; -} - -void dm_log_init_verbose(int level) -{ - _verbose = level; -} - -static void _build_dev_path(char *buffer, size_t len, const char *dev_name) -{ - /* If there's a /, assume caller knows what they're doing */ - if (strchr(dev_name, '/')) - snprintf(buffer, len, "%s", dev_name); - else - snprintf(buffer, len, "%s/%s", _dm_dir, dev_name); -} - -int dm_get_library_version(char *version, size_t size) -{ - strncpy(version, DM_LIB_VERSION, size); - return 1; -} - -struct dm_task *dm_task_create(int type) -{ - struct dm_task *dmt = malloc(sizeof(*dmt)); - - if (!dm_check_version()) - return NULL; - - if (!dmt) { - log_error("dm_task_create: malloc(%d) failed", sizeof(*dmt)); - return NULL; - } - - memset(dmt, 0, sizeof(*dmt)); - - dmt->type = type; - dmt->minor = -1; - dmt->major = -1; - - return dmt; -} - -int dm_task_set_name(struct dm_task *dmt, const char *name) -{ - char *pos; - char path[PATH_MAX]; - struct stat st1, st2; - - if (dmt->dev_name) { - free(dmt->dev_name); - dmt->dev_name = NULL; - } - - /* If path was supplied, remove it if it points to the same device - * as its last component. - */ - if ((pos = strrchr(name, '/'))) { - snprintf(path, sizeof(path), "%s/%s", _dm_dir, pos + 1); - - if (stat(name, &st1) || stat(path, &st2) || - !(st1.st_dev == st2.st_dev)) { - log_error("dm_task_set_name: Device %s not found", - name); - return 0; - } - - name = pos + 1; - } - - if (!(dmt->dev_name = strdup(name))) { - log_error("dm_task_set_name: strdup(%s) failed", name); - return 0; - } - - return 1; -} - -int dm_task_set_uuid(struct dm_task *dmt, const char *uuid) -{ - if (dmt->uuid) { - free(dmt->uuid); - dmt->uuid = NULL; - } - - if (!(dmt->uuid = strdup(uuid))) { - log_error("dm_task_set_uuid: strdup(%s) failed", uuid); - return 0; - } - - return 1; -} - -int dm_task_set_major(struct dm_task *dmt, int major) -{ - dmt->major = major; - log_debug("Setting major: %d", dmt->major); - - return 1; -} - -int dm_task_set_minor(struct dm_task *dmt, int minor) -{ - dmt->minor = minor; - log_debug("Setting minor: %d", dmt->minor); - - return 1; -} - -int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size, - const char *ttype, const char *params) -{ - struct target *t = create_target(start, size, ttype, params); - - if (!t) - return 0; - - if (!dmt->head) - dmt->head = dmt->tail = t; - else { - dmt->tail->next = t; - dmt->tail = t; - } - - return 1; -} - -static int _add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) -{ - char path[PATH_MAX]; - struct stat info; - dev_t dev = MKDEV(major, minor); - - _build_dev_path(path, sizeof(path), dev_name); - - if (stat(path, &info) >= 0) { - if (!S_ISBLK(info.st_mode)) { - log_error("A non-block device file at '%s' " - "is already present", path); - return 0; - } - - if (info.st_rdev == dev) - return 1; - - if (unlink(path) < 0) { - log_error("Unable to unlink device node for '%s'", - dev_name); - return 0; - } - } - - if (mknod(path, S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP, dev) < 0) { - log_error("Unable to make device node for '%s'", dev_name); - return 0; - } - - return 1; -} - -static int _rename_dev_node(const char *old_name, const char *new_name) -{ - char oldpath[PATH_MAX]; - char newpath[PATH_MAX]; - struct stat info; - - _build_dev_path(oldpath, sizeof(oldpath), old_name); - _build_dev_path(newpath, sizeof(newpath), new_name); - - if (stat(newpath, &info) == 0) { - if (!S_ISBLK(info.st_mode)) { - log_error("A non-block device file at '%s' " - "is already present", newpath); - return 0; - } - - if (unlink(newpath) < 0) { - if (errno == EPERM) { - /* devfs, entry has already been renamed */ - return 1; - } - log_error("Unable to unlink device node for '%s'", - new_name); - return 0; - } - } - - if (rename(oldpath, newpath) < 0) { - log_error("Unable to rename device node from '%s' to '%s'", - old_name, new_name); - return 0; - } - - return 1; -} - -static int _rm_dev_node(const char *dev_name) -{ - char path[PATH_MAX]; - struct stat info; - - _build_dev_path(path, sizeof(path), dev_name); - - if (stat(path, &info) < 0) - return 1; - - if (unlink(path) < 0) { - log_error("Unable to unlink device node for '%s'", dev_name); - return 0; - } - - return 1; -} - -typedef enum { - NODE_ADD, - NODE_DEL, - NODE_RENAME -} node_op_t; - -static int _do_node_op(node_op_t type, const char *dev_name, uint32_t major, - uint32_t minor, const char *old_name) -{ - switch (type) { - case NODE_ADD: - return _add_dev_node(dev_name, major, minor); - case NODE_DEL: - return _rm_dev_node(dev_name); - case NODE_RENAME: - return _rename_dev_node(old_name, dev_name); - } - - return 1; -} - -static LIST_INIT(_node_ops); - -struct node_op_parms { - struct list list; - node_op_t type; - char *dev_name; - uint32_t major; - uint32_t minor; - char *old_name; - char names[0]; -}; - -static void _store_str(char **pos, char **ptr, const char *str) -{ - strcpy(*pos, str); - *ptr = *pos; - *pos += strlen(*ptr) + 1; -} - -static int _stack_node_op(node_op_t type, const char *dev_name, uint32_t major, - uint32_t minor, const char *old_name) -{ - struct node_op_parms *nop; - size_t len = strlen(dev_name) + strlen(old_name) + 2; - char *pos; - - if (!(nop = malloc(sizeof(*nop) + len))) { - log_error("Insufficient memory to stack mknod operation"); - return 0; - } - - pos = nop->names; - nop->type = type; - nop->major = major; - nop->minor = minor; - - _store_str(&pos, &nop->dev_name, dev_name); - _store_str(&pos, &nop->old_name, old_name); - - list_add(&_node_ops, &nop->list); - - return 1; -} - -static void _pop_node_ops(void) -{ - struct list *noph, *nopht; - struct node_op_parms *nop; - - list_iterate_safe(noph, nopht, &_node_ops) { - nop = list_item(noph, struct node_op_parms); - _do_node_op(nop->type, nop->dev_name, nop->major, nop->minor, - nop->old_name); - list_del(&nop->list); - free(nop); - } -} - -int add_dev_node(const char *dev_name, uint32_t major, uint32_t minor) -{ - return _stack_node_op(NODE_ADD, dev_name, major, minor, ""); -} - -int rename_dev_node(const char *old_name, const char *new_name) -{ - return _stack_node_op(NODE_RENAME, new_name, 0, 0, old_name); -} - -int rm_dev_node(const char *dev_name) -{ - return _stack_node_op(NODE_DEL, dev_name, 0, 0, ""); -} - -void update_devs(void) -{ - _pop_node_ops(); -} - -int dm_set_dev_dir(const char *dir) -{ - snprintf(_dm_dir, sizeof(_dm_dir), "%s%s", dir, DM_DIR); - return 1; -} - -const char *dm_dir(void) -{ - return _dm_dir; -} diff --git a/extras/multipath-tools/libdevmapper/libdm-common.h b/extras/multipath-tools/libdevmapper/libdm-common.h deleted file mode 100644 index 2b71242861..0000000000 --- a/extras/multipath-tools/libdevmapper/libdm-common.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software (UK) Limited. - * - * This file is released under the LGPL. - */ - -#ifndef LIB_DMCOMMON_H -#define LIB_DMCOMMON_H - -#include "libdevmapper.h" - -#define _LOG_DEBUG 7 -#define _LOG_INFO 6 -#define _LOG_NOTICE 5 -#define _LOG_WARN 4 -#define _LOG_ERR 3 -#define _LOG_FATAL 2 - -extern dm_log_fn _log; - -#define log_error(msg, x...) _log(_LOG_ERR, __FILE__, __LINE__, msg, ## x) -#define log_print(msg, x...) _log(_LOG_WARN, __FILE__, __LINE__, msg, ## x) -#define log_verbose(msg, x...) _log(_LOG_NOTICE, __FILE__, __LINE__, msg, ## x) -#define log_very_verbose(msg, x...) _log(_LOG_INFO, __FILE__, __LINE__, msg, ## x) -#define log_debug(msg, x...) _log(_LOG_DEBUG, __FILE__, __LINE__, msg, ## x) - -struct target *create_target(uint64_t start, - uint64_t len, - const char *type, const char *params); - -int add_dev_node(const char *dev_name, uint32_t minor, uint32_t major); -int rm_dev_node(const char *dev_name); -int rename_dev_node(const char *old_name, const char *new_name); -void update_devs(void); - -#define DM_LIB_VERSION "1.00.07-ioctl (2003-11-21)" - -#endif diff --git a/extras/multipath-tools/libdevmapper/list.h b/extras/multipath-tools/libdevmapper/list.h deleted file mode 100644 index df3d32aea8..0000000000 --- a/extras/multipath-tools/libdevmapper/list.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (C) 2001 Sistina Software - * - * This file is released under the LGPL. - */ - -#ifndef _LVM_LIST_H -#define _LVM_LIST_H - -#include - -struct list { - struct list *n, *p; -}; - -#define LIST_INIT(name) struct list name = { &(name), &(name) } - -static inline void list_init(struct list *head) -{ - head->n = head->p = head; -} - -static inline void list_add(struct list *head, struct list *elem) -{ - assert(head->n); - - elem->n = head; - elem->p = head->p; - - head->p->n = elem; - head->p = elem; -} - -static inline void list_add_h(struct list *head, struct list *elem) -{ - assert(head->n); - - elem->n = head->n; - elem->p = head; - - head->n->p = elem; - head->n = elem; -} - -static inline void list_del(struct list *elem) -{ - elem->n->p = elem->p; - elem->p->n = elem->n; -} - -static inline int list_empty(struct list *head) -{ - return head->n == head; -} - -static inline int list_end(struct list *head, struct list *elem) -{ - return elem->n == head; -} - -static inline struct list *list_next(struct list *head, struct list *elem) -{ - return (list_end(head, elem) ? NULL : elem->n); -} - -#define list_iterate(v, head) \ - for (v = (head)->n; v != head; v = v->n) - -#define list_uniterate(v, head, start) \ - for (v = (start)->p; v != head; v = v->p) - -#define list_iterate_safe(v, t, head) \ - for (v = (head)->n, t = v->n; v != head; v = t, t = v->n) - -static inline unsigned int list_size(const struct list *head) -{ - unsigned int s = 0; - const struct list *v; - - list_iterate(v, head) - s++; - - return s; -} - -#define list_item(v, t) \ - ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->list)) - -#define list_struct_base(v, t, h) \ - ((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->h)) - -/* Given a known element in a known structure, locate another */ -#define struct_field(v, t, e, f) \ - (((t *)((uintptr_t)(v) - (uintptr_t)&((t *) 0)->e))->f) - -/* Given a known element in a known structure, locate the list head */ -#define list_head(v, t, e) struct_field(v, t, e, list) - -#endif diff --git a/extras/multipath-tools/multipath/Makefile b/extras/multipath-tools/multipath/Makefile deleted file mode 100644 index 4c0fae6d32..0000000000 --- a/extras/multipath-tools/multipath/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -# Makefile -# -# Copyright (C) 2003 Christophe Varoqui, - -EXEC = multipath - -prefix = -exec_prefix = ${prefix} -bindir = ${exec_prefix}/sbin -udevdir = ../../.. -klibcdir = $(udevdir)/klibc -sysfsdir = $(udevdir)/libsysfs -mandir = /usr/share/man/man8 -libdmdir = ../libdevmapper -arch = i386 -klibcarch = $(klibcdir)/klibc/arch/$(arch)/include - -CC = gcc -GZIP = /bin/gzip -9 -c - -GCCINCDIR := ${shell $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} -KERNEL_DIR = /lib/modules/${shell uname -r}/build -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -nostdinc \ - -I$(klibcdir)/klibc/include -I$(klibcdir)/klibc/include/bits32 \ - -I$(GCCINCDIR) -I$(KERNEL_DIR)/include -I$(sysfsdir) -I. -I$(klibcarch) - -OBJS = devinfo.o main.o -CRT0 = $(klibcdir)/klibc/crt0.o -LIB = $(klibcdir)/klibc/libc.a -LIBGCC := $(shell $(CC) -print-libgcc-file-name ) - -DMOBJS = $(libdmdir)/libdm-common.o $(libdmdir)/ioctl/libdevmapper.o -SYSFSOBJS = $(sysfsdir)/dlist.o $(sysfsdir)/sysfs_bus.o \ - $(sysfsdir)/sysfs_class.o $(sysfsdir)/sysfs_device.o \ - $(sysfsdir)/sysfs_dir.o $(sysfsdir)/sysfs_driver.o \ - $(sysfsdir)/sysfs_utils.o - -$(EXEC): $(OBJS) - $(LD) -o $(EXEC) $(CRT0) $(OBJS) $(SYSFSOBJS) $(DMOBJS) $(LIB) $(LIBGCC) - strip $(EXEC) - $(GZIP) $(EXEC).8 > $(EXEC).8.gz - -clean: - rm -f core *.o $(EXEC) *.gz - -spotless: clean - -install: - install -d $(DESTDIR)$(bindir) - install -m 755 $(EXEC) $(DESTDIR)$(bindir)/ - install -d $(DESTDIR)/etc/hotplug.d/scsi/ - install -m 755 multipath.hotplug $(DESTDIR)/etc/hotplug.d/scsi/ - install -d $(DESTDIR)$(mandir) - install -m 644 multipath.8.gz $(DESTDIR)$(mandir) - -uninstall: - rm $(DESTDIR)/etc/hotplug.d/scsi/multipath.hotplug - rm $(DESTDIR)$(bindir)/$(EXEC) - rm $(DESTDIR)$(mandir)/multipath.8.gz - -# Code dependencies -main.o: main.c main.h sg_include.h devinfo.h diff --git a/extras/multipath-tools/multipath/devinfo.c b/extras/multipath-tools/multipath/devinfo.c deleted file mode 100644 index 21890621e0..0000000000 --- a/extras/multipath-tools/multipath/devinfo.c +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "devinfo.h" -#include "sg_include.h" - -#define FILE_NAME_SIZE 255 - -void -basename(char * str1, char * str2) -{ - char *p = str1 + (strlen(str1) - 1); - - while (*--p != '/') - continue; - strcpy(str2, ++p); -} - -static int -do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, - void *resp, int mx_resp_len, int noisy) -{ - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = - { INQUIRY_CMD, 0, 0, 0, 0, 0 }; - unsigned char sense_b[SENSE_BUFF_LEN]; - struct sg_io_hdr io_hdr; - - if (cmddt) - inqCmdBlk[1] |= 2; - if (evpd) - inqCmdBlk[1] |= 1; - inqCmdBlk[2] = (unsigned char) pg_op; - inqCmdBlk[4] = (unsigned char) mx_resp_len; - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_b); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = mx_resp_len; - io_hdr.dxferp = resp; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sense_b; - io_hdr.timeout = DEF_TIMEOUT; - - if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { - perror("SG_IO (inquiry) error"); - return -1; - } - - /* treat SG_ERR here to get rid of sg_err.[ch] */ - io_hdr.status &= 0x7e; - if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && - (0 == io_hdr.driver_status)) - return 0; - if ((SCSI_CHECK_CONDITION == io_hdr.status) || - (SCSI_COMMAND_TERMINATED == io_hdr.status) || - (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { - if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { - int sense_key; - unsigned char * sense_buffer = io_hdr.sbp; - if (sense_buffer[0] & 0x2) - sense_key = sense_buffer[1] & 0xf; - else - sense_key = sense_buffer[2] & 0xf; - if(RECOVERED_ERROR == sense_key) - return 0; - } - } - return -1; -} - -int -get_serial (char * str, char * devname) -{ - int fd; - int len; - char buff[MX_ALLOC_LEN + 1]; - - if ((fd = open(devname, O_RDONLY)) < 0) - return 0; - - if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { - len = buff[3]; - if (len > 0) { - memcpy(str, buff + 4, len); - buff[len] = '\0'; - } - close(fd); - return 1; - } - close(fd); - return 0; -} - -int -get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname) -{ - int fd; - char buff[36]; - char attr_path[FILE_NAME_SIZE]; - char sysfs_path[FILE_NAME_SIZE]; - char basedev[FILE_NAME_SIZE]; - - if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { - /* sysfs style */ - basename(devname, basedev); - - sprintf(attr_path, "%s/block/%s/device/vendor", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - vendor_id, 8)) return 0; - - sprintf(attr_path, "%s/block/%s/device/model", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - product_id, 16)) return 0; - - sprintf(attr_path, "%s/block/%s/device/rev", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, - rev, 4)) return 0; - } else { - /* ioctl style */ - if ((fd = open(devname, O_RDONLY)) < 0) - return 0; - if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) - return 0; - memcpy(vendor_id, &buff[8], 8); - memcpy(product_id, &buff[16], 16); - memcpy(rev, &buff[32], 4); - close(fd); - return 1; - } - return 0; -} - -static void -sprint_wwid(char * buff, const char * str) -{ - int i; - const char *p; - char *cursor; - unsigned char c; - - p = str; - cursor = buff; - for (i = 0; i <= WWID_SIZE / 2 - 1; i++) { - c = *p++; - sprintf(cursor, "%.2x", (int) (unsigned char) c); - cursor += 2; - } - buff[WWID_SIZE - 1] = '\0'; -} - -/* get EVPD page 0x83 off 8 */ -/* tested ok with StorageWorks */ -int -get_evpd_wwid(char * devname, char * wwid) -{ - int fd; - char buff[MX_ALLOC_LEN + 1]; - - if ((fd = open(devname, O_RDONLY)) < 0) - return 0; - - if (0 == do_inq(fd, 0, 1, 0x83, buff, MX_ALLOC_LEN, 1)) { - sprint_wwid(wwid, &buff[8]); - close(fd); - return 1; /* success */ - } - - close(fd); - return 0; /* not good */ -} - -long -get_disk_size (char * devname) { - long size; - int fd; - char attr_path[FILE_NAME_SIZE]; - char sysfs_path[FILE_NAME_SIZE]; - char buff[FILE_NAME_SIZE]; - char basedev[FILE_NAME_SIZE]; - - if (0 == sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { - basename(devname, basedev); - sprintf(attr_path, "%s/block/%s/size", - sysfs_path, basedev); - if (0 > sysfs_read_attribute_value(attr_path, buff, - FILE_NAME_SIZE * sizeof(char))) - return -1; - size = atoi(buff); - return size; - } else { - if ((fd = open(devname, O_RDONLY)) < 0) - return -1; - if(!ioctl(fd, BLKGETSIZE, &size)) - return size; - } - return -1; -} - -int -do_tur(char *dev) -{ - unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; - struct sg_io_hdr io_hdr; - unsigned char sense_buffer[32]; - int fd; - - fd = open(dev, O_RDONLY); - - if (fd < 0) - return 0; - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (turCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_buffer); - io_hdr.dxfer_direction = SG_DXFER_NONE; - io_hdr.cmdp = turCmdBlk; - io_hdr.sbp = sense_buffer; - io_hdr.timeout = 20000; - io_hdr.pack_id = 0; - - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - close(fd); - return 0; - } - - close(fd); - - if (io_hdr.info & SG_INFO_OK_MASK) - return 0; - - return 1; -} diff --git a/extras/multipath-tools/multipath/devinfo.h b/extras/multipath-tools/multipath/devinfo.h deleted file mode 100644 index ee17aba923..0000000000 --- a/extras/multipath-tools/multipath/devinfo.h +++ /dev/null @@ -1,21 +0,0 @@ -#define INQUIRY_CMDLEN 6 -#define INQUIRY_CMD 0x12 -#define SENSE_BUFF_LEN 32 -#define DEF_TIMEOUT 60000 -#define RECOVERED_ERROR 0x01 -#define MX_ALLOC_LEN 255 -#define WWID_SIZE 33 -#define BLKGETSIZE _IO(0x12,96) -#define TUR_CMD_LEN 6 - -/* exerpt from "sg_err.h" */ -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 - -void basename (char *, char *); -int get_serial (char *, char *); -int get_lun_strings (char *, char *, char *, char *); -int get_evpd_wwid(char *, char *); -long get_disk_size (char *); -int do_tur (char *); diff --git a/extras/multipath-tools/multipath/main.c b/extras/multipath-tools/multipath/main.c deleted file mode 100644 index 8f06a8f94c..0000000000 --- a/extras/multipath-tools/multipath/main.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Soft: multipath device mapper target autoconfig - * - * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ - * - * Author: Copyright (C) 2003 Christophe Varoqui - * - * 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. - * - * 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 -#include "../libdevmapper/libdevmapper.h" -#include "main.h" -#include "devinfo.h" - -/* White list switch */ -static int -get_unique_id(struct path * mypath) -{ - int i; - static struct { - char * vendor; - char * product; - int iopolicy; - int (*getuid) (char *, char *); - } wlist[] = { - {"COMPAQ ", "HSV110 (C)COMPAQ", GROUP_BY_TUR, &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 ", GROUP_BY_TUR, &get_evpd_wwid}, - {"COMPAQ ", "MSA1000 VOLUME ", GROUP_BY_TUR, &get_evpd_wwid}, - {"DEC ", "HSG80 ", GROUP_BY_TUR, &get_evpd_wwid}, - {"HP ", "HSV100 ", GROUP_BY_TUR, &get_evpd_wwid}, - {"HP ", "A6189A ", MULTIBUS, &get_evpd_wwid}, - {"HP ", "OPEN- ", MULTIBUS, &get_evpd_wwid}, - {"DDN ", "SAN DataDirector", MULTIBUS, &get_evpd_wwid}, - {"FSC ", "CentricStor ", MULTIBUS, &get_evpd_wwid}, - {"HITACHI ", "DF400 ", MULTIBUS, &get_evpd_wwid}, - {"HITACHI ", "DF500 ", MULTIBUS, &get_evpd_wwid}, - {"HITACHI ", "DF600 ", MULTIBUS, &get_evpd_wwid}, - {"IBM ", "ProFibre 4000R ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9100 ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9300 ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9400 ", MULTIBUS, &get_evpd_wwid}, - {"SGI ", "TP9500 ", MULTIBUS, &get_evpd_wwid}, - {NULL, NULL, 0, NULL}, - }; - - for (i = 0; wlist[i].vendor; i++) { - if (strncmp(mypath->vendor_id, wlist[i].vendor, 8) == 0 && - strncmp(mypath->product_id, wlist[i].product, 16) == 0) { - mypath->iopolicy = wlist[i].iopolicy; - if (!wlist[i].getuid(mypath->sg_dev, mypath->wwid)) - return 0; - } - } - return 1; -} - -static int -sysfsdevice2devname (char *devname, char *device) -{ - char sysfs_path[FILE_NAME_SIZE]; - char block_path[FILE_NAME_SIZE]; - char link_path[FILE_NAME_SIZE]; - int r; - - if (sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { - fprintf(stderr, "[device] feature available with sysfs only\n"); - exit (1); - } - - sprintf(link_path, "%s%s/block", sysfs_path, device); - - r = sysfs_get_link(link_path, block_path, FILE_NAME_SIZE); - - if (r != 0) - return 1; - - sysfs_get_name_from_path(block_path, devname, FILE_NAME_SIZE); - - return 0; -} - - -static int -devt2devname (char *devname, int major, int minor) -{ - struct sysfs_directory * sdir; - struct sysfs_directory * devp; - char sysfs_path[FILE_NAME_SIZE]; - char block_path[FILE_NAME_SIZE]; - char attr_path[FILE_NAME_SIZE]; - char attr_value[16]; - char attr_ref_value[16]; - - if (sysfs_get_mnt_path(sysfs_path, FILE_NAME_SIZE)) { - fprintf(stderr, "-D feature available with sysfs only\n"); - exit (1); - } - - sprintf(attr_ref_value, "%i:%i\n", major, minor); - sprintf(block_path, "%s/block", sysfs_path); - sdir = sysfs_open_directory(block_path); - sysfs_read_directory(sdir); - - dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { - sprintf(attr_path, "%s/%s/dev", block_path, devp->name); - sysfs_read_attribute_value(attr_path, attr_value, 16); - - if (!strcmp(attr_value, attr_ref_value)) { - sprintf(attr_path, "%s/%s", block_path, devp->name); - sysfs_get_name_from_path(attr_path, devname, FILE_NAME_SIZE); - break; - } - } - - sysfs_close_directory(sdir); - - return 0; -} - -static int -blacklist (char * dev) { - int i; - static struct { - char * headstr; - int lengh; - } blist[] = { - {"cciss", 5}, - {"hd", 2}, - {"md", 2}, - {"dm", 2}, - {"sr", 2}, - {"scd", 3}, - {"ram", 3}, - {"raw", 3}, - {NULL, 0}, - }; - - for (i = 0; blist[i].lengh; i++) { - if (strncmp(dev, blist[i].headstr, blist[i].lengh) == 0) - return 1; - } - return 0; -} - -static int -devinfo (struct path *curpath) -{ - get_lun_strings(curpath->vendor_id, - curpath->product_id, - curpath->rev, - curpath->sg_dev); - get_serial(curpath->serial, curpath->sg_dev); - curpath->tur = do_tur(curpath->sg_dev); - if (!get_unique_id(curpath)) - return 1; - - return 0; -} - - -static int -get_all_paths_sysfs(struct env * conf, struct path * all_paths) -{ - int k=0; - struct sysfs_directory * sdir; - struct sysfs_directory * devp; - struct sysfs_link * linkp; - char refwwid[WWID_SIZE]; - char empty_buff[WWID_SIZE]; - char buff[FILE_NAME_SIZE]; - char path[FILE_NAME_SIZE]; - struct path curpath; - - memset(empty_buff, 0, WWID_SIZE); - memset(refwwid, 0, WWID_SIZE); - - /* if called from hotplug, only consider the paths that relate - to the device pointed by conf.hotplugdev */ - - if (strncmp("/devices", conf->hotplugdev, 8) == 0) { - if (sysfsdevice2devname (buff, conf->hotplugdev)) - return 0; - - sprintf(curpath.sg_dev, "/dev/%s", buff); - - if (devinfo(&curpath)) - return 0; - - strcpy(refwwid, curpath.wwid); - memset(&curpath, 0, sizeof(path)); - } - - /* if major/minor specified on the cmd line, - only consider affiliated paths */ - - if (conf->major >= 0 && conf->minor >= 0) { - if (devt2devname(buff, conf->major, conf->minor)) - return 0; - - sprintf(curpath.sg_dev, "/dev/%s", buff); - - if (devinfo(&curpath)) - return 0; - - strcpy(refwwid, curpath.wwid); - memset(&curpath, 0, sizeof(path)); - } - - - sprintf(path, "%s/block", conf->sysfs_path); - sdir = sysfs_open_directory(path); - sysfs_read_directory(sdir); - - dlist_for_each_data(sdir->subdirs, devp, struct sysfs_directory) { - if (blacklist(devp->name)) - continue; - - sysfs_read_directory(devp); - - if(devp->links == NULL) - continue; - - dlist_for_each_data(devp->links, linkp, struct sysfs_link) { - if (!strncmp(linkp->name, "device", 6)) - break; - } - - if (linkp == NULL) { - continue; - } - - basename(devp->path, buff); - sprintf(curpath.sg_dev, "/dev/%s", buff); - - if(devinfo(&curpath)) { - memset(&curpath, 0, sizeof(path)); - continue; - } - - if (memcmp(empty_buff, refwwid, WWID_SIZE) != 0 && - strncmp(curpath.wwid, refwwid, WWID_SIZE) != 0) { - memset(&curpath, 0, sizeof(path)); - continue; - } - - strcpy(all_paths[k].sg_dev, curpath.sg_dev); - strcpy(all_paths[k].dev, curpath.sg_dev); - strcpy(all_paths[k].wwid, curpath.wwid); - strcpy(all_paths[k].vendor_id, curpath.vendor_id); - strcpy(all_paths[k].product_id, curpath.product_id); - all_paths[k].iopolicy = curpath.iopolicy; - all_paths[k].tur = curpath.tur; - - /* done with curpath, zero for reuse */ - memset(&curpath, 0, sizeof(path)); - - basename(linkp->target, buff); - sscanf(buff, "%i:%i:%i:%i", - &all_paths[k].sg_id.host_no, - &all_paths[k].sg_id.channel, - &all_paths[k].sg_id.scsi_id, - &all_paths[k].sg_id.lun); - k++; - } - sysfs_close_directory(sdir); - return 0; -} - -static int -get_all_paths_nosysfs(struct env * conf, struct path * all_paths, - struct scsi_dev * all_scsi_ids) -{ - int k, i, fd; - char buff[FILE_NAME_SIZE]; - char file_name[FILE_NAME_SIZE]; - - for (k = 0; k < conf->max_devs; k++) { - strcpy(file_name, "/dev/sg"); - sprintf(buff, "%d", k); - strncat(file_name, buff, FILE_NAME_SIZE); - strcpy(all_paths[k].sg_dev, file_name); - - get_lun_strings(all_paths[k].vendor_id, - all_paths[k].product_id, - all_paths[k].rev, - all_paths[k].sg_dev); - get_serial(all_paths[k].serial, all_paths[k].sg_dev); - if (!get_unique_id(&all_paths[k])) - continue; - - if ((fd = open(all_paths[k].sg_dev, O_RDONLY)) < 0) - return 0; - - if (0 > ioctl(fd, SG_GET_SCSI_ID, &(all_paths[k].sg_id))) - printf("device %s failed on sg ioctl, skip\n", - file_name); - - close(fd); - - for (i = 0; i < conf->max_devs; i++) { - if ((all_paths[k].sg_id.host_no == - all_scsi_ids[i].host_no) - && (all_paths[k].sg_id.scsi_id == - (all_scsi_ids[i].scsi_id.dev_id & 0xff)) - && (all_paths[k].sg_id.lun == - ((all_scsi_ids[i].scsi_id.dev_id >> 8) & 0xff)) - && (all_paths[k].sg_id.channel == - ((all_scsi_ids[i].scsi_id. - dev_id >> 16) & 0xff))) { - strcpy(all_paths[k].dev, all_scsi_ids[i].dev); - break; - } - } - } - return 0; -} - -static int -get_all_scsi_ids(struct env * conf, struct scsi_dev * all_scsi_ids) -{ - int k, big, little, res, host_no, fd; - char buff[64]; - char fname[FILE_NAME_SIZE]; - struct scsi_idlun my_scsi_id; - - for (k = 0; k < conf->max_devs; k++) { - strcpy(fname, "/dev/sd"); - if (k < 26) { - buff[0] = 'a' + (char) k; - buff[1] = '\0'; - strcat(fname, buff); - } else if (k <= 255) { - /* assumes sequence goes x,y,z,aa,ab,ac etc */ - big = k / 26; - little = k - (26 * big); - big = big - 1; - - buff[0] = 'a' + (char) big; - buff[1] = 'a' + (char) little; - buff[2] = '\0'; - strcat(fname, buff); - } else - strcat(fname, "xxxx"); - - if ((fd = open(fname, O_RDONLY)) < 0) { - if (conf->verbose) - fprintf(stderr, "can't open %s. mknod ?", - fname); - continue; - } - - res = ioctl(fd, SCSI_IOCTL_GET_IDLUN, &my_scsi_id); - if (res < 0) { - close(fd); - printf("Could not get scsi idlun\n"); - continue; - } - - res = ioctl(fd, SCSI_IOCTL_GET_BUS_NUMBER, &host_no); - if (res < 0) { - close(fd); - printf("Could not get host_no\n"); - continue; - } - - close(fd); - - strcpy(all_scsi_ids[k].dev, fname); - all_scsi_ids[k].scsi_id = my_scsi_id; - all_scsi_ids[k].host_no = host_no; - } - return 0; -} - -/* print_path style */ -#define ALL 0 -#define NOWWID 1 - -static void -print_path(struct path * all_paths, int k, int style) -{ - if (style != NOWWID) - printf("%s ", all_paths[k].wwid); - else - printf(" \\_"); - printf("(%i %i %i %i) ", - all_paths[k].sg_id.host_no, - all_paths[k].sg_id.channel, - all_paths[k].sg_id.scsi_id, all_paths[k].sg_id.lun); - if(0 != strcmp(all_paths[k].sg_dev, all_paths[k].dev)) - printf("%s ", all_paths[k].sg_dev); - printf("%s ", all_paths[k].dev); - printf("[%.16s]\n", all_paths[k].product_id); -} - -static void -print_all_path(struct env * conf, struct path * all_paths) -{ - int k; - char empty_buff[WWID_SIZE]; - - memset(empty_buff, 0, WWID_SIZE); - for (k = 0; k < conf->max_devs; k++) { - if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) - continue; - print_path(all_paths, k, ALL); - } -} - -static void -print_all_mp(struct path * all_paths, struct multipath * mp, int nmp) -{ - int k, i; - - for (k = 0; k <= nmp; k++) { - printf("%s\n", mp[k].wwid); - for (i = 0; i <= mp[k].npaths; i++) - print_path(all_paths, PINDEX(k,i), NOWWID); - } -} - -static int -coalesce_paths(struct env * conf, struct multipath * mp, - struct path * all_paths) -{ - int k, i, nmp, np, already_done; - char empty_buff[WWID_SIZE]; - - nmp = -1; - already_done = 0; - memset(empty_buff, 0, WWID_SIZE); - - for (k = 0; k < conf->max_devs - 1; k++) { - /* skip this path for some reason */ - - /* 1. if path has no unique id */ - if (memcmp(empty_buff, all_paths[k].wwid, WWID_SIZE) == 0) - continue; - - /* 2. if mp with this uid already instanciated */ - for (i = 0; i <= nmp; i++) { - if (0 == strcmp(mp[i].wwid, all_paths[k].wwid)) - already_done = 1; - } - if (already_done) { - already_done = 0; - continue; - } - - /* at this point, we know we really got a new mp */ - np = 0; - nmp++; - strcpy(mp[nmp].wwid, all_paths[k].wwid); - PINDEX(nmp,np) = k; - - if (mp[nmp].size == 0) - mp[nmp].size = get_disk_size(all_paths[k].dev); - - for (i = k + 1; i < conf->max_devs; i++) { - if (0 == strcmp(all_paths[k].wwid, all_paths[i].wwid)) { - np++; - PINDEX(nmp,np) = i; - mp[nmp].npaths = np; - } - } - } - return nmp; -} - -static void -group_by_tur(struct multipath * mp, struct path * all_paths, char * str) { - int left_path_count = 0; - int right_path_count = 0; - int i; - char left_path_buff[FILE_NAME_SIZE], right_path_buff[FILE_NAME_SIZE]; - char * left_path_buff_p = &left_path_buff[0]; - char * right_path_buff_p = &right_path_buff[0]; - - for (i = 0; i <= mp->npaths; i++) { - if (all_paths[mp->pindex[i]].tur) { - left_path_buff_p += sprintf(left_path_buff_p, " %s", all_paths[mp->pindex[i]].dev); - left_path_count++; - } else { - right_path_buff_p += sprintf(right_path_buff_p, " %s", all_paths[mp->pindex[i]].dev); - right_path_count++; - } - } - if (!left_path_count) - sprintf(str, " 1 round-robin %i 0 %s", right_path_count, right_path_buff); - else if (!right_path_count) - sprintf(str, " 1 round-robin %i 0 %s", left_path_count, left_path_buff); - else - sprintf(str, " 2 round-robin %i 0 %s round-robin %i 0 %s", - left_path_count, left_path_buff, - right_path_count, right_path_buff); -} - -static void -group_by_serial(struct multipath * mp, struct path * all_paths, char * str) { - int path_count, pg_count = 0; - int i, k; - int * bitmap; - char path_buff[FILE_NAME_SIZE]; - char pg_buff[FILE_NAME_SIZE]; - char * path_buff_p = &path_buff[0]; - char * pg_buff_p = &pg_buff[0]; - - /* init the bitmap */ - bitmap = malloc((mp->npaths + 1) * sizeof(int)); - memset(bitmap, 0, (mp->npaths + 1) * sizeof(int)); - - for (i = 0; i <= mp->npaths; i++) { - if (bitmap[i]) - continue; - - /* here, we really got a new pg */ - pg_count++; - path_count = 1; - memset(&path_buff, 0, FILE_NAME_SIZE * sizeof(char)); - path_buff_p = &path_buff[0]; - - path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[i]].dev); - bitmap[i] = 1; - - for (k = i + 1; k <= mp->npaths; k++) { - if (bitmap[k]) - continue; - if (0 == strcmp(all_paths[mp->pindex[i]].serial, - all_paths[mp->pindex[k]].serial)) { - path_buff_p += sprintf(path_buff_p, " %s", all_paths[mp->pindex[k]].dev); - bitmap[k] = 1; - path_count++; - } - } - pg_buff_p += sprintf(pg_buff_p, " round-robin %i 0%s", - path_count, path_buff); - } - sprintf(str, " %i%s", pg_count, pg_buff); - free(bitmap); -} - -static int -dm_simplecmd(int task, const char *name) { - int r = 0; - struct dm_task *dmt; - - if (!(dmt = dm_task_create(task))) - return 0; - - if (!dm_task_set_name(dmt, name)) - goto out; - - r = dm_task_run(dmt); - - out: - dm_task_destroy(dmt); - return r; -} - -static int -dm_addmap(int task, const char *name, const char *params, long size) { - struct dm_task *dmt; - - if (!(dmt = dm_task_create(task))) - return 0; - - if (!dm_task_set_name(dmt, name)) - goto addout; - - if (!dm_task_add_target(dmt, 0, size, DM_TARGET, params)) - goto addout; - - if (!dm_task_run(dmt)) - goto addout; - - addout: - dm_task_destroy(dmt); - return 1; -} - -static int -setup_map(struct env * conf, struct path * all_paths, - struct multipath * mp, int index, int op) -{ - char params[255]; - char * params_p; - int i, np; - - /* defaults for multipath target */ - char * dm_ps_name = "round-robin"; - int dm_ps_nr_args = 0; - - params_p = ¶ms[0]; - - np = 0; - for (i=0; i<=mp[index].npaths; i++) { - if (0 == all_paths[PINDEX(index,i)].sg_id.scsi_type) - np++; - } - - if (np < 1) - return 0; - - if ((all_paths[PINDEX(index,0)].iopolicy == MULTIBUS && - conf->iopolicy == -1) || conf->iopolicy == MULTIBUS) { - params_p += sprintf(params_p, " 1 %s %i %i", - dm_ps_name, np, dm_ps_nr_args); - - for (i=0; i<=mp[index].npaths; i++) { - if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) - continue; - params_p += sprintf(params_p, " %s", - all_paths[PINDEX(index,i)].dev); - } - } - - if ((all_paths[PINDEX(index,0)].iopolicy == FAILOVER && - conf->iopolicy == -1) || conf->iopolicy == FAILOVER) { - params_p += sprintf(params_p, " %i", mp[index].npaths + 1); - for (i=0; i<=mp[index].npaths; i++) { - if (0 != all_paths[PINDEX(index,i)].sg_id.scsi_type) - continue; - params_p += sprintf(params_p, " %s ", - dm_ps_name); - params_p += sprintf(params_p, "1 %i", - dm_ps_nr_args); - params_p += sprintf(params_p, " %s", - all_paths[PINDEX(index,i)].dev); - } - } - - if ((all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_SERIAL && - conf->iopolicy == -1) || conf->iopolicy == GROUP_BY_SERIAL) { - group_by_serial(&mp[index], all_paths, params_p); - } - - if ((all_paths[PINDEX(index,0)].iopolicy == GROUP_BY_TUR && - conf->iopolicy == -1) || conf->iopolicy == GROUP_BY_TUR) { - group_by_tur(&mp[index], all_paths, params_p); - } - - if (mp[index].size < 0) - return 0; - - if (!conf->quiet) { - if (op == DM_DEVICE_RELOAD) - printf("U:"); - if (op == DM_DEVICE_CREATE) - printf("N:"); - printf("%s:0 %li %s %s\n", - mp[index].wwid, mp[index].size, DM_TARGET, params); - } - - if (op == DM_DEVICE_RELOAD) - dm_simplecmd(DM_DEVICE_SUSPEND, mp[index].wwid); - - dm_addmap(op, mp[index].wwid, params, mp[index].size); - - if (op == DM_DEVICE_RELOAD) - dm_simplecmd(DM_DEVICE_RESUME, mp[index].wwid); - - return 1; -} - -static int -map_present(char * str) -{ - int r = 0; - struct dm_task *dmt; - struct dm_names *names; - unsigned next = 0; - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) - return 0; - - if (!dm_task_run(dmt)) - goto out; - - if (!(names = dm_task_get_names(dmt))) - goto out; - - if (!names->dev) { - goto out; - } - - do { - if (0 == strcmp(names->name, str)) - r = 1; - next = names->next; - names = (void *) names + next; - } while (next); - - out: - dm_task_destroy(dmt); - return r; -} - -static void -signal_daemon (void) -{ - FILE *file; - pid_t pid; - char *buf; - - buf = malloc (8); - - file = fopen (PIDFILE, "r"); - - if (!file) { - fprintf(stderr, "cannot signal daemon, pidfile not found\n"); - return; - } - - buf = fgets (buf, 8, file); - fclose (file); - - pid = (pid_t) atol (buf); - free (buf); - - kill(pid, SIGHUP); -} - -static int -filepresent(char * run) { - struct stat buf; - - if(!stat(run, &buf)) - return 1; - return 0; -} - -static void -usage(char * progname) -{ - fprintf(stderr, VERSION_STRING); - fprintf(stderr, "Usage: %s [-v|-q] [-d] [-m max_devs]\n", - progname); - fprintf(stderr, " [-p failover|multibus|group_by_serial]\n" \ - " [device]\n" \ - "\n" \ - "\t-v\t\tverbose, print all paths and multipaths\n" \ - "\t-q\t\tquiet, no output at all\n" \ - "\t-d\t\tdry run, do not create or update devmaps\n" \ - "\t-m max_devs\tscan {max_devs} devices at most\n" \ - "\n" \ - "\t-p policy\tforce maps to specified policy :\n" \ - "\t failover\t\t- 1 path per priority group\n" \ - "\t multibus\t\t- all paths in 1 priority group\n" \ - "\t group_by_serial\t- 1 priority group per serial\n" \ - "\t group_by_tur\t\t- 1 priority group per TUR state\n" \ - "\n" \ - "\t-D maj min\tlimit scope to the device's multipath\n" \ - "\t\t\t(major minor device reference)\n" - "\tdevice\t\tlimit scope to the device's multipath\n" \ - "\t\t\t(hotplug-style $DEVPATH reference)\n" - ); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - struct multipath * mp; - struct path * all_paths; - struct scsi_dev * all_scsi_ids; - struct env conf; - int i, k, nmp; - int try = 0; - - /* Don't run in parallel */ - while (filepresent(RUN) && try++ < MAXTRY) - usleep(100000); - - if (filepresent(RUN)) { - fprintf(stderr, "waited for to long. exiting\n"); - exit (1); - } - - /* Our turn */ - if (!open(RUN, O_CREAT)) { - fprintf(stderr, "can't create runfile\n"); - exit (1); - } - - /* Default behaviour */ - conf.max_devs = MAX_DEVS; - conf.dry_run = 0; /* 1 == Do not Create/Update devmaps */ - conf.verbose = 0; /* 1 == Print all_paths and mp */ - conf.quiet = 0; /* 1 == Do not even print devmaps */ - conf.iopolicy = -1; /* Apply the defaults in get_unique_id() */ - conf.major = -1; - conf.minor = -1; - - for (i = 1; i < argc; ++i) { - if (0 == strcmp("-v", argv[i])) { - if (conf.quiet == 1) - usage(argv[0]); - conf.verbose = 1; - } else if (0 == strcmp("-m", argv[i])) { - conf.max_devs = atoi(argv[++i]); - if (conf.max_devs < 2) - usage(argv[0]); - } else if (0 == strcmp("-D", argv[i])) { - conf.major = atoi(argv[++i]); - conf.minor = atoi(argv[++i]); - } else if (0 == strcmp("-q", argv[i])) { - if (conf.verbose == 1) - usage(argv[0]); - conf.quiet = 1; - } else if (0 == strcmp("-d", argv[i])) - conf.dry_run = 1; - else if (0 == strcmp("-p", argv[i])) { - i++; - if (!strcmp(argv[i], "failover")) - conf.iopolicy = FAILOVER; - if (!strcmp(argv[i], "multibus")) - conf.iopolicy = MULTIBUS; - if (!strcmp(argv[i], "group_by_serial")) - conf.iopolicy = GROUP_BY_SERIAL; - if (!strcmp(argv[i], "group_by_tur")) - conf.iopolicy = GROUP_BY_TUR; - } else if (*argv[i] == '-') { - fprintf(stderr, "Unknown switch: %s\n", argv[i]); - usage(argv[0]); - } else - strncpy(conf.hotplugdev, argv[i], FILE_NAME_SIZE); - } - - /* dynamic allocations */ - mp = malloc(conf.max_devs * sizeof(struct multipath)); - all_paths = malloc(conf.max_devs * sizeof(struct path)); - all_scsi_ids = malloc(conf.max_devs * sizeof(struct scsi_dev)); - if (mp == NULL || all_paths == NULL || all_scsi_ids == NULL) - exit(1); - - if (sysfs_get_mnt_path(conf.sysfs_path, FILE_NAME_SIZE)) { - get_all_scsi_ids(&conf, all_scsi_ids); - get_all_paths_nosysfs(&conf, all_paths, all_scsi_ids); - } else { - get_all_paths_sysfs(&conf, all_paths); - } - - nmp = coalesce_paths(&conf, mp, all_paths); - - if (conf.verbose) { - print_all_path(&conf, all_paths); - fprintf(stdout, "\n"); - print_all_mp(all_paths, mp, nmp); - fprintf(stdout, "\n"); - } - - if (conf.dry_run) - exit(0); - - for (k=0; k<=nmp; k++) { - if (map_present(mp[k].wwid)) { - setup_map(&conf, all_paths, mp, k, DM_DEVICE_RELOAD); - } else { - setup_map(&conf, all_paths, mp, k, DM_DEVICE_CREATE); - } - } - - /* signal multipathd that new devmaps may have come up */ - signal_daemon(); - - /* free allocs */ - free(mp); - free(all_paths); - free(all_scsi_ids); - - /* release runfile */ - unlink(RUN); - - exit(0); -} diff --git a/extras/multipath-tools/multipath/main.h b/extras/multipath-tools/multipath/main.h deleted file mode 100644 index ada7a7394b..0000000000 --- a/extras/multipath-tools/multipath/main.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Soft: Description here... - * - * Version: $Id: main.h,v 0.0.1 2003/09/18 15:13:38 cvaroqui Exp $ - * - * Author: Copyright (C) 2003 Christophe Varoqui - * - * 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. - * - * 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. - */ - -#ifndef _MAIN_H -#define _MAIN_H - -/* local includes */ -#include "sg_include.h" - -/* exerpt from "sg_err.h" */ -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 - -/* exerpt from "scsi.h" */ -#define SCSI_IOCTL_GET_IDLUN 0x5382 -#define SCSI_IOCTL_GET_BUS_NUMBER 0x5386 - -/* global defs */ -#define WWID_SIZE 33 -#define SERIAL_SIZE 14 -#define MAX_DEVS 128 -#define MAX_MP MAX_DEVS / 2 -#define MAX_MP_PATHS MAX_DEVS / 4 -#define FILE_NAME_SIZE 256 -#define DEF_TIMEOUT 60000 -#define EBUFF_SZ 256 -#define TUR_CMD_LEN 6 -#define DM_TARGET "multipath" -#define PIDFILE "/var/run/multipathd.pid" -#define RUN "/var/run/multipath.run" -#define MAXTRY 50 - -/* Storage controlers cpabilities */ -#define FAILOVER 0 -#define MULTIBUS 1 -#define GROUP_BY_SERIAL 2 -#define GROUP_BY_TUR 4 - -#define PINDEX(x,y) mp[(x)].pindex[(y)] - -/* global types */ -struct scsi_idlun { - int dev_id; - int host_unique_id; - int host_no; -}; - -struct sg_id { - int host_no; - int channel; - int scsi_id; - int lun; - int scsi_type; - short h_cmd_per_lun; - short d_queue_depth; - int unused1; - int unused2; -}; - -struct scsi_dev { - char dev[FILE_NAME_SIZE]; - struct scsi_idlun scsi_id; - int host_no; -}; - -struct path { - char dev[FILE_NAME_SIZE]; - char sg_dev[FILE_NAME_SIZE]; - struct scsi_idlun scsi_id; - struct sg_id sg_id; - char wwid[WWID_SIZE]; - char vendor_id[8]; - char product_id[16]; - char rev[4]; - char serial[SERIAL_SIZE]; - int iopolicy; - int tur; -}; - -struct multipath { - char wwid[WWID_SIZE]; - int npaths; - long size; - int pindex[MAX_MP_PATHS]; -}; - -struct env { - int max_devs; - int verbose; - int quiet; - int dry_run; - int iopolicy; - int with_sysfs; - int major; - int minor; - char sysfs_path[FILE_NAME_SIZE]; - char hotplugdev[FILE_NAME_SIZE]; -}; - -/* Build version */ -#define PROG "multipath" - -#define VERSION_CODE 0x000012 -#define DATE_CODE 0x021504 - -#define MULTIPATH_VERSION(version) \ - (version >> 16) & 0xFF, \ - (version >> 8) & 0xFF, \ - version & 0xFF - -#define VERSION_STRING PROG" v%d.%d.%d (%.2d/%.2d, 20%.2d)\n", \ - MULTIPATH_VERSION(VERSION_CODE), \ - MULTIPATH_VERSION(DATE_CODE) - -#endif diff --git a/extras/multipath-tools/multipath/multipath.8 b/extras/multipath-tools/multipath/multipath.8 deleted file mode 100644 index 0856ca8dfc..0000000000 --- a/extras/multipath-tools/multipath/multipath.8 +++ /dev/null @@ -1,66 +0,0 @@ -.TH MULTIPATH 8 "February 2004" "" "Linux Administrator's Manual" -.SH NAME -multipath \- Device mapper target autoconfig -.SH SYNOPSIS -.B multipath -.RB [\| \-v | \-q \|] -.RB [\| \-d \|] -.RB [\| \-i\ \c -.IR int \|] -.RB [\| \-m\ \c -.IR max_devs \|] -.RB [\| \-p\ \c -.BR failover | multibus | group_by_serial \|] -.RB [\| device \|] -.SH DESCRIPTION -.B multipath -is used to detect multiple paths to devices for fail-over or performance reasons and coalesces them. -.SH OPTIONS -.TP -.B \-v -verbose, print all paths and multipaths -.TP -.B \-q -quiet, no output at all -.TP -.B \-d -dry run, do not create or update devmaps -.TP -.BI \-i " int" -multipath target param: polling interval -.TP -.BI \-m " max_devs" -scan -.I max_devs -devices at most -.TP -.BI \-D " major minor" -update only the devmap the path pointed by -.I major minor -is in -.TP -.BI \-p " policy" -force maps to specified policy: -.RS 1.2i -.TP 1.2i -.B failover -1 path per priority group -.TP -.B multibus -all paths in 1 priority group -.TP -.B group_by_serial -1 priority group per serial -.RE -.TP -.BI device -update only the devmap the path pointed by -.I device -is in -.SH "SEE ALSO" -.BR udev (8), -.BR dmsetup (8) -.BR hotplug (8) -.SH AUTHORS -.B multipath -was developed by Christophe Varoqui, and others. diff --git a/extras/multipath-tools/multipath/multipath.hotplug b/extras/multipath-tools/multipath/multipath.hotplug deleted file mode 100644 index 5c411d1edf..0000000000 --- a/extras/multipath-tools/multipath/multipath.hotplug +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh -. /etc/hotplug/hotplug.functions - -# wait for sysfs -sleep 1 - -mesg `/sbin/multipath $DEVPATH` diff --git a/extras/multipath-tools/multipath/sg_err.h b/extras/multipath-tools/multipath/sg_err.h deleted file mode 100644 index ef57b5ce38..0000000000 --- a/extras/multipath-tools/multipath/sg_err.h +++ /dev/null @@ -1,162 +0,0 @@ -#ifndef SG_ERR_H -#define SG_ERR_H - -/* Feel free to copy and modify this GPL-ed code into your applications. */ - -/* Version 0.90 (20030519) -*/ - - -/* Some of the following error/status codes are exchanged between the - various layers of the SCSI sub-system in Linux and should never - reach the user. They are placed here for completeness. What appears - here is copied from drivers/scsi/scsi.h which is not visible in - the user space. */ - -#ifndef SCSI_CHECK_CONDITION -/* 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 -#endif - -/* The following are 'host_status' codes */ -#ifndef DID_OK -#define DID_OK 0x00 -#endif -#ifndef DID_NO_CONNECT -#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 DID_BAD_TARGET 0x04 /* Bad target (id?) */ -#define DID_ABORT 0x05 /* Told to abort for some other reason */ -#define DID_PARITY 0x06 /* Parity error (on SCSI bus) */ -#define DID_ERROR 0x07 /* Internal error */ -#define DID_RESET 0x08 /* Reset by somebody */ -#define DID_BAD_INTR 0x09 /* Received an unexpected interrupt */ -#define DID_PASSTHROUGH 0x0a /* Force command past mid-level */ -#define DID_SOFT_ERROR 0x0b /* The low-level driver wants a retry */ -#endif - -/* These defines are to isolate applictaions from kernel define changes */ -#define SG_ERR_DID_OK DID_OK -#define SG_ERR_DID_NO_CONNECT DID_NO_CONNECT -#define SG_ERR_DID_BUS_BUSY DID_BUS_BUSY -#define SG_ERR_DID_TIME_OUT DID_TIME_OUT -#define SG_ERR_DID_BAD_TARGET DID_BAD_TARGET -#define SG_ERR_DID_ABORT DID_ABORT -#define SG_ERR_DID_PARITY DID_PARITY -#define SG_ERR_DID_ERROR DID_ERROR -#define SG_ERR_DID_RESET DID_RESET -#define SG_ERR_DID_BAD_INTR DID_BAD_INTR -#define SG_ERR_DID_PASSTHROUGH DID_PASSTHROUGH -#define SG_ERR_DID_SOFT_ERROR DID_SOFT_ERROR - -/* The following are 'driver_status' codes */ -#ifndef DRIVER_OK -#define DRIVER_OK 0x00 -#endif -#ifndef DRIVER_BUSY -#define DRIVER_BUSY 0x01 -#define DRIVER_SOFT 0x02 -#define DRIVER_MEDIA 0x03 -#define DRIVER_ERROR 0x04 -#define DRIVER_INVALID 0x05 -#define DRIVER_TIMEOUT 0x06 -#define DRIVER_HARD 0x07 -#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */ - -/* Following "suggests" are "or-ed" with one of previous 8 entries */ -#define SUGGEST_RETRY 0x10 -#define SUGGEST_ABORT 0x20 -#define SUGGEST_REMAP 0x30 -#define SUGGEST_DIE 0x40 -#define SUGGEST_SENSE 0x80 -#define SUGGEST_IS_OK 0xff -#endif -#ifndef DRIVER_MASK -#define DRIVER_MASK 0x0f -#endif -#ifndef SUGGEST_MASK -#define SUGGEST_MASK 0xf0 -#endif - -/* These defines are to isolate applictaions from kernel define changes */ -#define SG_ERR_DRIVER_OK DRIVER_OK -#define SG_ERR_DRIVER_BUSY DRIVER_BUSY -#define SG_ERR_DRIVER_SOFT DRIVER_SOFT -#define SG_ERR_DRIVER_MEDIA DRIVER_MEDIA -#define SG_ERR_DRIVER_ERROR DRIVER_ERROR -#define SG_ERR_DRIVER_INVALID DRIVER_INVALID -#define SG_ERR_DRIVER_TIMEOUT DRIVER_TIMEOUT -#define SG_ERR_DRIVER_HARD DRIVER_HARD -#define SG_ERR_DRIVER_SENSE DRIVER_SENSE -#define SG_ERR_SUGGEST_RETRY SUGGEST_RETRY -#define SG_ERR_SUGGEST_ABORT SUGGEST_ABORT -#define SG_ERR_SUGGEST_REMAP SUGGEST_REMAP -#define SG_ERR_SUGGEST_DIE SUGGEST_DIE -#define SG_ERR_SUGGEST_SENSE SUGGEST_SENSE -#define SG_ERR_SUGGEST_IS_OK SUGGEST_IS_OK -#define SG_ERR_DRIVER_MASK DRIVER_MASK -#define SG_ERR_SUGGEST_MASK SUGGEST_MASK - - - -/* The following "print" functions send ACSII to stdout */ -extern void sg_print_command(const unsigned char * command); -extern void sg_print_sense(const char * leadin, - const unsigned char * sense_buffer, int sb_len); -extern void sg_print_status(int masked_status); -extern void sg_print_scsi_status(int scsi_status); -extern void sg_print_host_status(int host_status); -extern void sg_print_driver_status(int driver_status); - -/* sg_chk_n_print() returns 1 quietly if there are no errors/warnings - else it prints to standard output and returns 0. */ -extern int sg_chk_n_print(const char * leadin, int masked_status, - int host_status, int driver_status, - const unsigned char * sense_buffer, int sb_len); - -/* The following function declaration is for the sg version 3 driver. - Only version 3 sg_err.c defines it. */ -struct sg_io_hdr; -extern int sg_chk_n_print3(const char * leadin, struct sg_io_hdr * hp); - - -/* 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_SENSE 98 /* Something else is in the sense buffer */ -#define SG_ERR_CAT_OTHER 99 /* Some other error/warning has occurred */ - -extern int sg_err_category(int masked_status, int host_status, - int driver_status, const unsigned char * sense_buffer, - int sb_len); - -extern int sg_err_category_new(int scsi_status, int host_status, - int driver_status, const unsigned char * sense_buffer, - int sb_len); - -/* The following function declaration is for the sg version 3 driver. - Only version 3 sg_err.c defines it. */ -extern int sg_err_category3(struct sg_io_hdr * hp); - -/* Returns length of SCSI command given the opcode (first byte) */ -extern int sg_get_command_size(unsigned char opcode); - -extern void sg_get_command_name(unsigned char opcode, int buff_len, - char * buff); - -#endif diff --git a/extras/multipath-tools/multipath/sg_include.h b/extras/multipath-tools/multipath/sg_include.h deleted file mode 100644 index 460506826e..0000000000 --- a/extras/multipath-tools/multipath/sg_include.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef SG_KERNEL_INCLUDES - #define __user - typedef unsigned char u8; - #include "/usr/src/linux/include/scsi/sg.h" - #include "/usr/src/linux/include/scsi/scsi.h" -#else - #ifdef SG_TRICK_GNU_INCLUDES - #include - #include - #else - #include - #endif -#endif - -/* - Getting the correct include files for the sg interface can be an ordeal. - In a perfect world, one would just write: - #include - #include - This would include the files found in the /usr/include/scsi directory. - Those files are maintained with the GNU library which may or may not - agree with the kernel and version of sg driver that is running. Any - many cases this will not matter. However in some it might, for example - glibc 2.1's include files match the sg driver found in the lk 2.2 - series. Hence if glibc 2.1 is used with lk 2.4 then the additional - sg v3 interface will not be visible. - If this is a problem then defining SG_KERNEL_INCLUDES will access the - kernel supplied header files (assuming they are in the normal place). - The GNU library maintainers and various kernel people don't like - this approach (but it does work). - The technique selected by defining SG_TRICK_GNU_INCLUDES worked (and - was used) prior to glibc 2.2 . Prior to that version /usr/include/linux - was a symbolic link to /usr/src/linux/include/linux . - - There are other approaches if this include "mixup" causes pain. These - would involve include files being copied or symbolic links being - introduced. - - Sorry about the inconvenience. Typically neither SG_KERNEL_INCLUDES - nor SG_TRICK_GNU_INCLUDES is defined. - - dpg 20010415, 20030522 -*/ diff --git a/extras/multipath-tools/multipath/unused.c b/extras/multipath-tools/multipath/unused.c deleted file mode 100644 index 08144cf717..0000000000 --- a/extras/multipath-tools/multipath/unused.c +++ /dev/null @@ -1,95 +0,0 @@ -static int -get_serial (int fd, char * str) -{ - char buff[MX_ALLOC_LEN + 1]; - int len; - - if (0 == do_inq(fd, 0, 1, 0x80, buff, MX_ALLOC_LEN, 0)) { - len = buff[3]; - if (len > 0) { - memcpy(str, buff + 4, len); - buff[len] = '\0'; - } - return 1; - } - return 0; -} - -static int -do_tur(int fd) -{ - unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; - struct sg_io_hdr io_hdr; - unsigned char sense_buffer[32]; - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (turCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_buffer); - io_hdr.dxfer_direction = SG_DXFER_NONE; - io_hdr.cmdp = turCmdBlk; - io_hdr.sbp = sense_buffer; - io_hdr.timeout = 20000; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - close(fd); - return 0; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - return 0; - } - return 1; -} - -static int -del_map(char * str) { - struct dm_task *dmt; - - if (!(dmt = dm_task_create(DM_DEVICE_REMOVE))) - return 0; - if (!dm_task_set_name(dmt, str)) - goto delout; - if (!dm_task_run(dmt)) - goto delout; - - printf("Deleted device map : %s\n", str); - - delout: - dm_task_destroy(dmt); - return 1; -} - -get_table(const char * str) -{ - int r = 0; - struct dm_task *dmt; - void *next = NULL; - uint64_t start, length; - char *target_type = NULL; - char *params; - - if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) - return 0; - - if (!dm_task_set_name(dmt, str)) - goto out; - - if (!dm_task_run(dmt)) - goto out; - - do { - next = dm_get_next_target(dmt, next, &start, &length, - &target_type, ¶ms); - if (target_type) { - printf("%" PRIu64 " %" PRIu64 " %s %s\n", - start, length, target_type, params); - } - } while (next); - - r = 1; - - out: - dm_task_destroy(dmt); - return r; - -} diff --git a/extras/multipath-tools/multipathd/Makefile b/extras/multipath-tools/multipathd/Makefile deleted file mode 100644 index 82c77b8351..0000000000 --- a/extras/multipath-tools/multipathd/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -EXEC = multipathd - -CC = gcc -GZIP = /bin/gzip -9 -c - -bindir = /usr/bin -mandir = /usr/share/man/man8 -rcdir = /etc/init.d - -CFLAGS = -pipe -g -O2 -Wall -Wunused -Wstrict-prototypes -DDEBUG=1 -LDFLAGS = -lpthread -ldevmapper -lsysfs - -OBJS = main.o devinfo.o checkers.o - -$(EXEC): $(OBJS) - $(CC) $(LDFLAGS) $(OBJS) -o $(EXEC) - strip $(EXEC) - -install: - install -d $(bindir) - install -m 755 $(EXEC) $(bindir) - install -d $(rcdir) - install -m 755 multipathd.init $(rcdir)/$(EXEC) - -uninstall: - rm -f $(bindir)/$(EXEC) - rm -f $(rcdir)/$(EXEC) - -clean: - rm -f core *.o $(EXEC) *.gz - -spotless: clean diff --git a/extras/multipath-tools/multipathd/checkers.c b/extras/multipath-tools/multipathd/checkers.c deleted file mode 100644 index 7ad32b04e9..0000000000 --- a/extras/multipath-tools/multipathd/checkers.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "sg_include.h" - -#define TUR_CMD_LEN 6 - -/* - * test IO functions : add yours here - * - * returns 0 : path gone valid - * returns 1 : path still failed - */ - -int readsector0 (char *devnode) -{ - int fd, r; - char buf; - - fd = open (devnode, O_RDONLY); - if (read (fd, &buf, 1) != 1) - r = 0; - else - r = 1; - - close (fd); - - return r; -} - -int tur(char *devnode) -{ - unsigned char turCmdBlk[TUR_CMD_LEN] = { 0x00, 0, 0, 0, 0, 0 }; - struct sg_io_hdr io_hdr; - unsigned char sense_buffer[32]; - int fd; - - fd = open (devnode, O_RDONLY); - - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (turCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_buffer); - io_hdr.dxfer_direction = SG_DXFER_NONE; - io_hdr.cmdp = turCmdBlk; - io_hdr.sbp = sense_buffer; - io_hdr.timeout = 20000; - io_hdr.pack_id = 0; - if (ioctl(fd, SG_IO, &io_hdr) < 0) { - close(fd); - return 0; - } - if (io_hdr.info & SG_INFO_OK_MASK) { - return 0; - } - return 1; -} diff --git a/extras/multipath-tools/multipathd/checkers.h b/extras/multipath-tools/multipathd/checkers.h deleted file mode 100644 index 057c319d1b..0000000000 --- a/extras/multipath-tools/multipathd/checkers.h +++ /dev/null @@ -1,2 +0,0 @@ -int readsector0 (char *); -int tur (char *); diff --git a/extras/multipath-tools/multipathd/devinfo.c b/extras/multipath-tools/multipathd/devinfo.c deleted file mode 100644 index 46505470f4..0000000000 --- a/extras/multipath-tools/multipathd/devinfo.c +++ /dev/null @@ -1,82 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "devinfo.h" -#include "sg_include.h" - -#define FILE_NAME_SIZE 255 - -static int -do_inq(int sg_fd, int cmddt, int evpd, unsigned int pg_op, - void *resp, int mx_resp_len, int noisy) -{ - unsigned char inqCmdBlk[INQUIRY_CMDLEN] = - { INQUIRY_CMD, 0, 0, 0, 0, 0 }; - unsigned char sense_b[SENSE_BUFF_LEN]; - struct sg_io_hdr io_hdr; - - if (cmddt) - inqCmdBlk[1] |= 2; - if (evpd) - inqCmdBlk[1] |= 1; - inqCmdBlk[2] = (unsigned char) pg_op; - inqCmdBlk[4] = (unsigned char) mx_resp_len; - memset(&io_hdr, 0, sizeof (struct sg_io_hdr)); - io_hdr.interface_id = 'S'; - io_hdr.cmd_len = sizeof (inqCmdBlk); - io_hdr.mx_sb_len = sizeof (sense_b); - io_hdr.dxfer_direction = SG_DXFER_FROM_DEV; - io_hdr.dxfer_len = mx_resp_len; - io_hdr.dxferp = resp; - io_hdr.cmdp = inqCmdBlk; - io_hdr.sbp = sense_b; - io_hdr.timeout = DEF_TIMEOUT; - - if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) { - perror("SG_IO (inquiry) error"); - return -1; - } - - /* treat SG_ERR here to get rid of sg_err.[ch] */ - io_hdr.status &= 0x7e; - if ((0 == io_hdr.status) && (0 == io_hdr.host_status) && - (0 == io_hdr.driver_status)) - return 0; - if ((SCSI_CHECK_CONDITION == io_hdr.status) || - (SCSI_COMMAND_TERMINATED == io_hdr.status) || - (SG_ERR_DRIVER_SENSE == (0xf & io_hdr.driver_status))) { - if (io_hdr.sbp && (io_hdr.sb_len_wr > 2)) { - int sense_key; - unsigned char * sense_buffer = io_hdr.sbp; - if (sense_buffer[0] & 0x2) - sense_key = sense_buffer[1] & 0xf; - else - sense_key = sense_buffer[2] & 0xf; - if(RECOVERED_ERROR == sense_key) - return 0; - } - } - return -1; -} - -int -get_lun_strings(char * vendor_id, char * product_id, char * rev, char * devname) -{ - int fd; - char buff[36]; - - /* ioctl style */ - if ((fd = open(devname, O_RDONLY)) < 0) - return 1; - if (0 != do_inq(fd, 0, 0, 0, buff, 36, 1)) - return 1; - memcpy(vendor_id, &buff[8], 8); - memcpy(product_id, &buff[16], 16); - memcpy(rev, &buff[32], 4); - close(fd); - - return 0; -} diff --git a/extras/multipath-tools/multipathd/devinfo.h b/extras/multipath-tools/multipathd/devinfo.h deleted file mode 100644 index 46b2894051..0000000000 --- a/extras/multipath-tools/multipathd/devinfo.h +++ /dev/null @@ -1,15 +0,0 @@ -#define INQUIRY_CMDLEN 6 -#define INQUIRY_CMD 0x12 -#define SENSE_BUFF_LEN 32 -#define DEF_TIMEOUT 60000 -#define RECOVERED_ERROR 0x01 -#define MX_ALLOC_LEN 255 -#define WWID_SIZE 33 -#define BLKGETSIZE _IO(0x12,96) - -/* exerpt from "sg_err.h" */ -#define SCSI_CHECK_CONDITION 0x2 -#define SCSI_COMMAND_TERMINATED 0x22 -#define SG_ERR_DRIVER_SENSE 0x08 - -int get_lun_strings (char *, char *, char *, char *); diff --git a/extras/multipath-tools/multipathd/main.c b/extras/multipath-tools/multipathd/main.c deleted file mode 100644 index 7b5ccfca23..0000000000 --- a/extras/multipath-tools/multipathd/main.c +++ /dev/null @@ -1,674 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "devinfo.h" -#include "checkers.h" - -#define CHECKINT 5 -#define MAXPATHS 2048 -#define FILENAMESIZE 256 -#define MAPNAMESIZE 64 -#define TARGETTYPESIZE 16 -#define PARAMSSIZE 2048 -#define MAXMAPS 512 - -#define MULTIPATH "/sbin/multipath" -#define PIDFILE "/var/run/multipathd.pid" - -#ifndef DEBUG -#define DEBUG 1 -#endif -#define LOG(x, y, z...) if (DEBUG >= x) syslog(x, y, ##z) - -struct path -{ - int major; - int minor; - char mapname[MAPNAMESIZE]; - int (*checkfn) (char *); -}; - -struct paths -{ - pthread_mutex_t *lock; - struct path *paths_h; -}; - -struct event_thread -{ - pthread_t *thread; - pthread_mutex_t *waiter_lock; - char mapname[MAPNAMESIZE]; -}; - -struct devmap -{ - char mapname[MAPNAMESIZE]; -}; - -/* global var */ -pthread_mutex_t *event_lock; -pthread_cond_t *event; - -int makenode (char *devnode, int major, int minor) -{ - dev_t dev; - - dev = makedev (major, minor); - unlink (devnode); - - return mknod(devnode, S_IFBLK | S_IRUSR | S_IWUSR, dev); -} - -int select_checkfn(struct path *path_p) -{ - char devnode[FILENAMESIZE]; - char vendor[8]; - char product[16]; - char rev[4]; - int i, r; - - /* default checkfn */ - path_p->checkfn = &readsector0; - - sprintf (devnode, "/tmp/.select.%i.%i", path_p->major, path_p->minor); - - r = makenode (devnode, path_p->major, path_p->minor); - - if (r < 0) { - LOG(2, "[select_checkfn] can not make node %s", devnode); - return r; - } - - r = get_lun_strings(vendor, product, rev, devnode); - - if (r) { - LOG(2, "[select_checkfn] can not get strings"); - return r; - } - - r = unlink (devnode); - - if (r < 0) { - LOG(2, "[select_checkfn] can not unlink %s", devnode); - return r; - } - - static struct { - char * vendor; - char * product; - int (*checkfn) (char *); - } wlist[] = { - {"COMPAQ ", "HSV110 (C)COMPAQ", &tur}, - {"COMPAQ ", "MSA1000 ", &tur}, - {"COMPAQ ", "MSA1000 VOLUME ", &tur}, - {"DEC ", "HSG80 ", &tur}, - {"HP ", "HSV100 ", &readsector0}, - {NULL, NULL, NULL}, - }; - - for (i = 0; wlist[i].vendor; i++) { - if (strncmp(vendor, wlist[i].vendor, 8) == 0 && - strncmp(product, wlist[i].product, 16) == 0) { - path_p->checkfn = wlist[i].checkfn; - } - } - - return 0; -} - -int get_devmaps (struct devmap *devmaps) -{ - struct devmap *devmaps_p; - struct dm_task *dmt, *dmt1; - struct dm_names *names = NULL; - unsigned next = 0; - void *nexttgt; - int r = 0; - long long start, length; - char *target_type = NULL; - char *params; - - memset (devmaps, 0, MAXMAPS * sizeof (struct devmap)); - - if (!(dmt = dm_task_create(DM_DEVICE_LIST))) { - r = 1; - goto out; - } - - if (!dm_task_run(dmt)) { - r = 1; - goto out; - } - - if (!(names = dm_task_get_names(dmt))) { - r = 1; - goto out; - } - - if (!names->dev) { - LOG (1, "[get_devmaps] no devmap found"); - goto out; - } - - devmaps_p = devmaps; - - do { - /* keep only multipath maps */ - - names = (void *) names + next; - nexttgt = NULL; - LOG (3, "[get_devmaps] iterate on devmap names : %s", names->name); - - LOG (3, "[get_devmaps] dm_task_create(DM_DEVICE_STATUS)"); - if (!(dmt1 = dm_task_create(DM_DEVICE_STATUS))) - goto out1; - - LOG (3, "[get_devmaps] dm_task_set_name(dmt1, names->name)"); - if (!dm_task_set_name(dmt1, names->name)) - goto out1; - - LOG (3, "[get_devmaps] dm_task_run(dmt1)"); - if (!dm_task_run(dmt1)) - goto out1; - LOG (3, "[get_devmaps] DM_DEVICE_STATUS ioctl done"); - do { - LOG (3, "[get_devmaps] iterate on devmap's targets"); - nexttgt = dm_get_next_target(dmt1, nexttgt, - &start, - &length, - &target_type, - ¶ms); - - - LOG (3, "[get_devmaps] test target_type existence"); - if (!target_type) - goto out1; - - LOG (3, "[get_devmaps] test target_type is multipath"); - if (!strncmp (target_type, "multipath", 9)) { - strcpy (devmaps_p->mapname, names->name); - devmaps_p++; - - /* test vector overflow */ - if (devmaps_p - devmaps >= MAXMAPS * sizeof (struct devmap)) { - LOG (1, "[get_devmaps] devmaps overflow"); - dm_task_destroy(dmt1); - r = 1; - goto out; - } - } - - } while (nexttgt); - -out1: - dm_task_destroy(dmt1); - next = names->next; - - } while (next); - -out: - dm_task_destroy(dmt); - - LOG (3, "[get_devmaps] done"); - return r; -} - -int checkpath (struct path *path_p) -{ - char devnode[FILENAMESIZE]; - int r; - - LOG (2, "[checkpath] checking path %i:%i", path_p->major, path_p->minor); - sprintf (devnode, "/tmp/.checker.%i.%i", path_p->major, path_p->minor); - - if (path_p->checkfn == NULL) { - LOG (1, "[checkpath] test function not set for path %i:%i", - path_p->major, path_p->minor); - return 1; - } - - r = makenode (devnode, path_p->major, path_p->minor); - - if (r < 0) { - LOG (2, "[checkpath] can not make node for %s", devnode); - return r; - } - - r = path_p->checkfn(devnode); - unlink (devnode); - - return r; -} - -int updatepaths (struct devmap *devmaps, struct paths *failedpaths) -{ - struct path *path_p; - struct devmap *devmaps_p; - void *next; - struct dm_task *dmt; - long long start, length; - char *target_type = NULL; - char *params, *p1, *p2; - char word[6]; - int i; - - path_p = failedpaths->paths_h; - - pthread_mutex_lock (failedpaths->lock); - memset (failedpaths->paths_h, 0, MAXPATHS * sizeof (struct path)); - - /* first pass */ - /* ask DM the failed path list */ - - devmaps_p = devmaps; - - while (*devmaps_p->mapname != 0x0) { - next = NULL; - - if (!(dmt = dm_task_create(DM_DEVICE_STATUS))) - break; - - if (!dm_task_set_name(dmt, devmaps_p->mapname)) - goto out; - - if (!dm_task_run(dmt)) - goto out; - - do { - next = dm_get_next_target(dmt, next, &start, &length, - &target_type, ¶ms); - - /* begin ugly parser */ - p1 = params; - p2 = params; - while (*p1) { - /* p2 lags at the begining of the word p1 parses */ - while (*p1 != ' ') { - /* if the current word is a path */ - if (*p1 == ':') { - /* p1 jumps to path state */ - while (*p1 != 'A' && *p1 != 'F') - p1++; - - /* store path info */ - - path_p->checkfn = NULL; - - i = 0; - memset (&word, 'O', 6 * sizeof (char)); - while (*p2 != ':') { - word[i++] = *p2; - p2++; - } - path_p->major = atoi (word); - - p2++; - i = 0; - memset (&word, 'O', 6 * sizeof (char)); - while (*p2 != ' ') { - word[i++] = *p2; - p2++; - } - path_p->minor = atoi (word); - - strcpy (path_p->mapname, devmaps_p->mapname); - - /* - * discard active paths - * don't trust the A status flag : double check - */ - if (*p1 == 'A' && - !select_checkfn (path_p) && - checkpath (path_p)) { - LOG(2, "[updatepaths] discard %i:%i as valid path", - path_p->major, path_p->minor); - p1++; - memset (path_p, 0, sizeof(struct path)); - continue; - } - - path_p++; - - /* test vector overflow */ - if (path_p - failedpaths->paths_h >= MAXPATHS * sizeof (struct path)) { - LOG (1, "[updatepaths] path_h overflow"); - pthread_mutex_unlock (failedpaths->lock); - return 1; - } - } - p1++; - } - p2 = p1; - p1++; - } - } while (next); - -out: - dm_task_destroy(dmt); - devmaps_p++; - - } - - pthread_mutex_unlock (failedpaths->lock); - return 0; -} - -int geteventnr (char *name) -{ - struct dm_task *dmt; - struct dm_info info; - - if (!(dmt = dm_task_create(DM_DEVICE_INFO))) - return 0; - - if (!dm_task_set_name(dmt, name)) - goto out; - - if (!dm_task_run(dmt)) - goto out; - - if (!dm_task_get_info(dmt, &info)) - return 0; - - if (!info.exists) { - LOG(1, "Device %s does not exist", name); - return 0; - } - -out: - dm_task_destroy(dmt); - - return info.event_nr; -} - -void *waitevent (void * et) -{ - int event_nr; - struct event_thread *waiter; - - waiter = (struct event_thread *)et; - pthread_mutex_lock (waiter->waiter_lock); - - event_nr = geteventnr (waiter->mapname); - - struct dm_task *dmt; - - if (!(dmt = dm_task_create(DM_DEVICE_WAITEVENT))) - return 0; - - if (!dm_task_set_name(dmt, waiter->mapname)) - goto out; - - if (event_nr && !dm_task_set_event_nr(dmt, event_nr)) - goto out; - - dm_task_run(dmt); - -out: - dm_task_destroy(dmt); - - /* tell waiterloop we have an event */ - pthread_mutex_lock (event_lock); - pthread_cond_signal(event); - pthread_mutex_unlock (event_lock); - - /* release waiter_lock so that waiterloop knows we are gone */ - pthread_mutex_unlock (waiter->waiter_lock); - pthread_exit(waiter->thread); - - return (NULL); -} - -void *waiterloop (void *ap) -{ - struct paths *failedpaths; - struct devmap *devmaps, *devmaps_p; - struct event_thread *waiters, *waiters_p; - int r; - - /* inits */ - failedpaths = (struct paths *)ap; - devmaps = malloc (MAXMAPS * sizeof (struct devmap)); - waiters = malloc (MAXMAPS * sizeof (struct event_thread)); - memset (waiters, 0, MAXMAPS * sizeof (struct event_thread)); - - while (1) { - - /* update devmap list */ - LOG (1, "[event thread] refresh devmaps list"); - get_devmaps (devmaps); - - /* update failed paths list */ - LOG (1, "[event thread] refresh failpaths list"); - updatepaths (devmaps, failedpaths); - - /* start waiters on all devmaps */ - LOG (1, "[event thread] start up event loops"); - waiters_p = waiters; - devmaps_p = devmaps; - - while (*devmaps_p->mapname != 0x0) { - - /* find out if devmap already has a running waiter thread */ - while (*waiters_p->mapname != 0x0) { - if (!strcmp (waiters_p->mapname, devmaps_p->mapname)) - break; - waiters_p++; - } - - /* no event_thread struct : init it */ - if (*waiters_p->mapname == 0x0) { - strcpy (waiters_p->mapname, devmaps_p->mapname); - waiters_p->thread = malloc (sizeof (pthread_t)); - waiters_p->waiter_lock = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); - pthread_mutex_init (waiters_p->waiter_lock, NULL); - } - - /* event_thread struct found */ - if (*waiters_p->mapname != 0x0) { - r = pthread_mutex_trylock (waiters_p->waiter_lock); - /* thread already running : out */ - - if (r) - goto out; - - pthread_mutex_unlock (waiters_p->waiter_lock); - } - - LOG (1, "[event thread] create event thread for %s", waiters_p->mapname); - pthread_create (waiters_p->thread, NULL, waitevent, waiters_p); -out: - waiters_p = waiters; - devmaps_p++; - } - - /* wait event condition */ - pthread_mutex_lock (event_lock); - pthread_cond_wait(event, event_lock); - pthread_mutex_unlock (event_lock); - - LOG (1, "[event thread] event caught"); - } - - return (NULL); -} - -void *checkerloop (void *ap) -{ - struct paths *failedpaths; - struct path *path_p; - char *cmdargs[4] = {MULTIPATH, "-D", NULL, NULL}; - char major[5]; - char minor[5]; - int status; - - failedpaths = (struct paths *)ap; - - LOG (1, "[checker thread] path checkers start up"); - - while (1) { - path_p = failedpaths->paths_h; - pthread_mutex_lock (failedpaths->lock); - LOG (2, "[checker thread] checking paths"); - while (path_p->major != 0) { - - if (checkpath (path_p)) { - LOG (1, "[checker thread] reconfigure %s\n", path_p->mapname); - snprintf (major, 5, "%i", path_p->major); - snprintf (minor, 5, "%i", path_p->minor); - cmdargs[2] = major; - cmdargs[3] = minor; - if (fork () == 0) - execve (cmdargs[0], cmdargs, NULL); - - wait (&status); - /* MULTIPATH will ask for failedpaths refresh (SIGHUP) */ - } - - path_p++; - - /* test vector overflow */ - if (path_p - failedpaths->paths_h >= MAXPATHS * sizeof (struct path)) { - LOG (1, "[checker thread] path_h overflow"); - pthread_mutex_unlock (failedpaths->lock); - return (NULL); - } - } - pthread_mutex_unlock (failedpaths->lock); - sleep(CHECKINT); - } - - return (NULL); -} - -struct paths *initpaths (void) -{ - struct paths *failedpaths; - - failedpaths = malloc (sizeof (struct paths)); - failedpaths->paths_h = malloc (MAXPATHS * sizeof (struct path)); - failedpaths->lock = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); - pthread_mutex_init (failedpaths->lock, NULL); - event = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); - pthread_cond_init (event, NULL); - event_lock = (pthread_mutex_t *) malloc (sizeof (pthread_mutex_t)); - pthread_mutex_init (event_lock, NULL); - - return (failedpaths); -} - -void pidfile (pid_t pid) -{ - FILE *file; - struct stat *buf; - - buf = malloc (sizeof (struct stat)); - - if (!stat (PIDFILE, buf)) { - LOG(1, "[master thread] already running : out"); - free (buf); - exit (1); - } - - umask (022); - pid = setsid (); - - if (pid < -1) { - LOG(1, "[master thread] setsid() error"); - exit (1); - } - - file = fopen (PIDFILE, "w"); - fprintf (file, "%d\n", pid); - fclose (file); - free (buf); -} - -void * -signal_set(int signo, void (*func) (int)) -{ - int r; - struct sigaction sig; - struct sigaction osig; - - sig.sa_handler = func; - sigemptyset(&sig.sa_mask); - sig.sa_flags = 0; - - r = sigaction(signo, &sig, &osig); - - if (r < 0) - return (SIG_ERR); - else - return (osig.sa_handler); -} - -void sighup (int sig) -{ - LOG (1, "[master thread] SIGHUP caught : refresh devmap list"); - - /* ask for failedpaths refresh */ - pthread_mutex_lock (event_lock); - pthread_cond_signal(event); - pthread_mutex_unlock (event_lock); -} - -void sigend (int sig) -{ - LOG (1, "[master thread] unlink pidfile"); - unlink (PIDFILE); - LOG (1, "[master thread] --------shut down-------"); - exit (0); -} - -void signal_init(void) -{ - signal_set(SIGHUP, sighup); - signal_set(SIGINT, sigend); - signal_set(SIGTERM, sigend); - signal_set(SIGKILL, sigend); -} - -int main (int argc, char *argv[]) -{ - pthread_t wait, check; - struct paths *failedpaths; - pid_t pid; - - pid = fork (); - - /* can't fork */ - if (pid < 0) - exit (1); - - /* let the parent die happy */ - if (pid > 0) - exit (0); - - /* child's play */ - openlog (argv[0], 0, LOG_DAEMON); - LOG (1, "[master thread] --------start up--------"); - - pidfile (pid); - signal_init (); - - failedpaths = initpaths (); - - pthread_create (&wait, NULL, waiterloop, failedpaths); - pthread_create (&check, NULL, checkerloop, failedpaths); - pthread_join (wait, NULL); - pthread_join (check, NULL); - - return 0; -} diff --git a/extras/multipath-tools/multipathd/multipathd.init b/extras/multipath-tools/multipathd/multipathd.init deleted file mode 100644 index 860b2b11db..0000000000 --- a/extras/multipath-tools/multipathd/multipathd.init +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh - -PATH=/bin:/usr/bin:/sbin:/usr/sbin -DAEMON=/usr/bin/multipathd -PIDFILE=/var/run/multipathd.pid - -test -x $DAEMON || exit 0 - -case "$1" in - start) - echo -n "Starting multipath daemon: multipathd" - if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name multipathd - then - echo " already running." - exit - fi - /sbin/start-stop-daemon --start --quiet --exec $DAEMON - echo "." - ;; - stop) - echo -n "Stopping multipath daemon: multipathd" - if start-stop-daemon --quiet --stop --signal 0 --pidfile $PIDFILE --name multipathd - then - PID=`cat $PIDFILE` - start-stop-daemon --quiet --stop --exec $DAEMON --pidfile $PIDFILE --name multipathd - # Now we wait for it to die - while kill -0 $PID 2>/dev/null; do sleep 1; done - echo "." - else - echo " not running."; - fi - ;; - force-reload|restart) - $0 stop - $0 start - ;; - *) - echo "Usage: /etc/init.d/multipathd {start|stop|restart|force-reload}" - exit 1 -esac - -exit 0 diff --git a/extras/multipath-tools/multipathd/sg_include.h b/extras/multipath-tools/multipathd/sg_include.h deleted file mode 100644 index 460506826e..0000000000 --- a/extras/multipath-tools/multipathd/sg_include.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef SG_KERNEL_INCLUDES - #define __user - typedef unsigned char u8; - #include "/usr/src/linux/include/scsi/sg.h" - #include "/usr/src/linux/include/scsi/scsi.h" -#else - #ifdef SG_TRICK_GNU_INCLUDES - #include - #include - #else - #include - #endif -#endif - -/* - Getting the correct include files for the sg interface can be an ordeal. - In a perfect world, one would just write: - #include - #include - This would include the files found in the /usr/include/scsi directory. - Those files are maintained with the GNU library which may or may not - agree with the kernel and version of sg driver that is running. Any - many cases this will not matter. However in some it might, for example - glibc 2.1's include files match the sg driver found in the lk 2.2 - series. Hence if glibc 2.1 is used with lk 2.4 then the additional - sg v3 interface will not be visible. - If this is a problem then defining SG_KERNEL_INCLUDES will access the - kernel supplied header files (assuming they are in the normal place). - The GNU library maintainers and various kernel people don't like - this approach (but it does work). - The technique selected by defining SG_TRICK_GNU_INCLUDES worked (and - was used) prior to glibc 2.2 . Prior to that version /usr/include/linux - was a symbolic link to /usr/src/linux/include/linux . - - There are other approaches if this include "mixup" causes pain. These - would involve include files being copied or symbolic links being - introduced. - - Sorry about the inconvenience. Typically neither SG_KERNEL_INCLUDES - nor SG_TRICK_GNU_INCLUDES is defined. - - dpg 20010415, 20030522 -*/ From f608f8ac16889ce0e7e800c7f11dacc558d097c1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 6 Oct 2004 23:20:39 -0700 Subject: [PATCH 0859/4284] [PATCH] fix problems using scsi_id with udevstart when udevstart was running we didn't set the environment and the subsystem argument for the callouts the dev.d/ scripts. Here is a fix, that sets that with every udevstart iteration, corrects argv[0] to be the basename() only not the whole path and adds a test for invoking callouts without arguments. --- namedev.c | 27 ++++++++++++++++----------- test/udev-test.pl | 9 +++++++++ udevstart.c | 21 ++++++++++++++++++--- 3 files changed, 43 insertions(+), 14 deletions(-) diff --git a/namedev.c b/namedev.c index fe7dddaf55..3843d02869 100644 --- a/namedev.c +++ b/namedev.c @@ -412,7 +412,7 @@ static void fix_kernel_name(struct udevice *udev) } } -static int execute_program(char *path, char *value, int len) +static int execute_program(const char *path, char *value, int len) { int retval; int count; @@ -421,12 +421,12 @@ static int execute_program(char *path, char *value, int len) pid_t pid; char *pos; char arg[PROGRAM_SIZE]; - char *argv[sizeof(arg) / 2]; + char *argv[(PROGRAM_SIZE / 2) + 1]; int i; + strfieldcpy(arg, path); i = 0; if (strchr(path, ' ')) { - strfieldcpy(arg, path); pos = arg; while (pos != NULL) { if (pos[0] == '\'') { @@ -441,8 +441,19 @@ static int execute_program(char *path, char *value, int len) dbg("arg[%i] '%s'", i, argv[i]); i++; } + argv[i] = NULL; + dbg("execute '%s' with parsed arguments", arg); + } else { + argv[0] = arg; + argv[1] = main_argv[1]; + argv[2] = NULL; + dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); } - argv[i] = NULL; + + /* set basename() only */ + pos = strrchr(argv[0], '/'); + if (pos != NULL) + argv[0] = &pos[1]; retval = pipe(fds); if (retval != 0) { @@ -456,13 +467,7 @@ static int execute_program(char *path, char *value, int len) /* child */ /* dup2 write side of pipe to STDOUT */ dup2(fds[1], STDOUT_FILENO); - if (argv[0] != NULL) { - dbg("execute '%s' with given arguments", argv[0]); - retval = execv(argv[0], argv); - } else { - dbg("execute '%s' with main argument", path); - retval = execv(path, main_argv); - } + retval = execv(arg, argv); info(FIELD_PROGRAM " execution of '%s' failed", path); exit(1); diff --git a/test/udev-test.pl b/test/udev-test.pl index 590b551dfe..9e4e192c51 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -253,6 +253,15 @@ BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special--*", NAME="%c BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-device-", NAME="%c-3-%n" BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-devic", NAME="%c-4-%n" BUS="scsi", PROGRAM="/bin/echo -n special-device", RESULT="special-*", NAME="%c-%n" +EOF + }, + { + desc => "program result substitution (no argument should be subsystem)", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "subsys_block" , + conf => <path, first_list[i], strlen(first_list[i])) == 0) { - udev_add_device(loop_device->path, loop_device->subsys, NOFAKE); + add_device(loop_device->path, loop_device->subsys, NOFAKE); list_del(&loop_device->list); free(loop_device); break; @@ -116,14 +131,14 @@ static void exec_list(struct list_head *device_list) if (found) continue; - udev_add_device(loop_device->path, loop_device->subsys, NOFAKE); + add_device(loop_device->path, loop_device->subsys, NOFAKE); list_del(&loop_device->list); free(loop_device); } /* handle the rest of the devices left over, if any */ list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { - udev_add_device(loop_device->path, loop_device->subsys, NOFAKE); + add_device(loop_device->path, loop_device->subsys, NOFAKE); list_del(&loop_device->list); free(loop_device); } From 12901d995fe7c99af36148d8d596f967c6ad68a3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 6 Oct 2004 23:40:35 -0700 Subject: [PATCH 0860/4284] [PATCH] enable native tdb spinlocks on i386 platforms. also clean out some stuff in the makefile that was never getting used. --- Makefile | 18 +++++------------- tdb/spinlock.c | 3 ++- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index 9405b25c5f..1b7c71c57c 100644 --- a/Makefile +++ b/Makefile @@ -107,19 +107,11 @@ OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2> # add -Wredundant-decls when libsysfs gets cleaned up WARNINGS := -Wall -# Some nice architecture specific optimizations -ifeq ($(strip $(TARGET_ARCH)),arm) - OPTIMIZATION+=-fstrict-aliasing -endif -ifeq ($(strip $(TARGET_ARCH)),i386) - OPTIMIZATION+=-march=i386 - OPTIMIZATION += ${shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc \ - /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi} - OPTIMIZATION += ${shell if $(CC) -malign-functions=0 -malign-jumps=0 -S -o /dev/null -xc \ - /dev/null >/dev/null 2>&1; then echo "-malign-functions=0 -malign-jumps=0"; fi} - CFLAGS+=-pipe -Dasmlinkage=__attribute__((regparm(0))) -else - CFLAGS+=-pipe -Dasmlinkage= +CFLAGS := -pipe -Dasmlinkage= + +# set up the proper tdb spinlock code if we can +ifeq ($(strip $(ARCH)),i386) + CFLAGS += -DUSE_SPINLOCKS -DINTEL_SPINLOCKS endif ifeq ($(strip $(USE_LOG)),true) diff --git a/tdb/spinlock.c b/tdb/spinlock.c index 50cd952c72..451617fade 100644 --- a/tdb/spinlock.c +++ b/tdb/spinlock.c @@ -21,7 +21,6 @@ #define STANDALONE #define TDB_DEBUG #define HAVE_MMAP 1 -#include "../udev.h" #if HAVE_CONFIG_H #include @@ -40,6 +39,8 @@ #include #include "tdb.h" #include "spinlock.h" +#include "../udev.h" +#include "../logging.h" #else #include "includes.h" From e629ca3f499baae644deae8c151e86e052f02113 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 6 Oct 2004 23:45:30 -0700 Subject: [PATCH 0861/4284] [PATCH] wait_for_sysfs debug cleanup > Sorry, I left my debug code in. Oops, just realized it now. You've applied a older version and not the latest. Here is a new patch to catch up. --- Makefile | 4 +- wait_for_sysfs.c | 98 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 72 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 1b7c71c57c..0b635ffb25 100644 --- a/Makefile +++ b/Makefile @@ -399,7 +399,7 @@ install: install-initscript install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(WAIT) $(DESTDIR)$(sbindir)/$(WAIT) - ln -f -s $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER) - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug - - ln -f -s $(sbindir)/$(WAIT) $(DESTDIR)$(hotplugdir)/00-wait_for_sysfs.hotplug + - ln -f -s $(sbindir)/$(WAIT) $(DESTDIR)$(hotplugdir)/05-wait_for_sysfs.hotplug ifndef DESTDIR - killall udevd - rm -f $(udevdir)/.udev.tdb @@ -412,7 +412,7 @@ endif uninstall: uninstall-man uninstall-dev.d - rm $(hotplugdir)/10-udev.hotplug - - rm $(hotplugdir)/00-wait_for_sysfs.hotplug + - rm $(hotplugdir)/05-wait_for_sysfs.hotplug - rm $(configdir)/rules.d/50-udev.rules - rm $(configdir)/permissions.d/50-udev.permissions - rm $(configdir)/udev.conf diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index b9efcddf87..6275db23b1 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -1,7 +1,7 @@ /* * wait_for_sysfs.c - small program to delay the execution * of /etc/hotplug.d/ programs, until sysfs - * is populated by the kernel. Depending on + * is fully populated by the kernel. Depending on * the type of device, we wait for all expected * directories and then just exit. * @@ -49,6 +49,7 @@ void log_message(int level, const char *format, ...) #define WAIT_MAX_SECONDS 5 #define WAIT_LOOP_PER_SECOND 20 +/* wait for specific file to show up, normally the "dev"-file */ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev) { static struct class_file { @@ -56,8 +57,10 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev char *file; } class_files[] = { { .subsystem = "net", .file = "ifindex" }, + { .subsystem = "scsi_host", .file = "unique_id" }, + { .subsystem = "scsi_device", .file = NULL }, + { .subsystem = "pcmcia_socket", .file = "card_type" }, { .subsystem = "usb_host", .file = NULL }, - { .subsystem = "pcmcia_socket", .file = NULL }, { NULL, NULL } }; struct class_file *classfile; @@ -83,16 +86,17 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev dbg("class '%s' specific file '%s' found", class_dev->classname, file); return 0; } + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } - dbg("error: getting bus '%s' specific file '%s'", class_dev->classname, file); + dbg("error: getting class '%s' specific file '%s'", class_dev->classname, file); return -1; } +/* skip waiting for physical device */ static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) { - char **device; - static char *devices_without_link[] = { "nb", "ram", @@ -120,6 +124,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d "ttyS", NULL }; + char **device; for (device = devices_without_link; *device != NULL; device++) { int len = strlen(*device); @@ -140,6 +145,26 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d return 0; } +/* skip waiting for the bus */ +static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) +{ + static char *devices_without_bus[] = { + "scsi_host", + NULL + }; + char **device; + + for (device = devices_without_bus; *device != NULL; device++) { + int len = strlen(*device); + + if (strncmp(class_dev->classname, *device, len) == 0) + return 1; + } + + return 0; +} + +/* wait for the bus and for a bus specific file to show up */ static int wait_for_bus_device(struct sysfs_device *device_dev) { static struct bus_file { @@ -152,6 +177,7 @@ static int wait_for_bus_device(struct sysfs_device *device_dev) { .bus = "usb-serial", .file = "detach_state" }, { .bus = "ide", .file = "detach_state" }, { .bus = "pci", .file = "vendor" }, + { .bus = "platform", .file = "detach_state" }, { NULL } }; struct bus_file *busfile; @@ -174,19 +200,24 @@ static int wait_for_bus_device(struct sysfs_device *device_dev) /* wait for a bus specific file to show up */ loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { + int found = 0; + for (busfile = bus_files; busfile->bus != NULL; busfile++) { if (strcmp(device_dev->bus, busfile->bus) == 0) { + found = 1; dbg("looking at bus '%s' for specific file '%s'", device_dev->bus, busfile->file); if (sysfs_get_device_attr(device_dev, busfile->file) != NULL) { dbg("bus '%s' specific file '%s' found", device_dev->bus, busfile->file); return 0; } - if (busfile->bus == NULL) { - info("error: unknown bus, update the build-in list '%s'", device_dev->bus); - return -1; - } } } + if (found == 0) { + info("error: unknown bus, please report to " + " '%s'", device_dev->bus); + return -1; + } + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } dbg("error: getting bus '%s' specific file '%s'", device_dev->bus, busfile->file); @@ -206,6 +237,8 @@ int main(int argc, char *argv[], char *envp[]) int loop; int rc = 0; + init_logging("wait_for_sysfs"); + if (argc != 2) { dbg("error: subsystem"); return 1; @@ -224,6 +257,7 @@ int main(int argc, char *argv[], char *envp[]) return 1; } + /* we only wait on an add event */ if (strcmp(action, "add") != 0) return 0; @@ -242,20 +276,25 @@ int main(int argc, char *argv[], char *envp[]) class_dev = sysfs_open_class_device_path(filename); if (class_dev) break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } if (class_dev == NULL) { dbg("error: getting class_device"); - rc = 4; + rc = 3; goto exit; } dbg("class_device opened '%s'", filename); - wait_for_class_device_attributes(class_dev); + if (wait_for_class_device_attributes(class_dev) != 0) { + rc = 4; + goto exit_class; + } + /* skip devices without /device-link */ if (class_device_expect_no_device_link(class_dev)) { - dbg("no device symlink expected"); - sysfs_close_class_device(class_dev); - goto exit; + dbg("no device symlink expected for '%s', ", class_dev->name); + goto exit_class; } /* the symlink may be on the parent device */ @@ -279,19 +318,21 @@ int main(int argc, char *argv[], char *envp[]) } if (device_dev == NULL) { dbg("error: getting /device-device"); - sysfs_close_class_device(class_dev); rc = 5; - goto exit; + goto exit_class; } dbg("device symlink found pointing to '%s'", device_dev->path); /* wait for the bus value */ - if (wait_for_bus_device(device_dev) != 0) - rc = 6; - sysfs_close_class_device(class_dev); + if (class_device_expect_no_bus(class_dev)) { + dbg("no bus device expected for '%s', ", class_dev->classname); + } else { + if (wait_for_bus_device(device_dev) != 0) + rc = 6; + } - /* finished */ - goto exit; +exit_class: + sysfs_close_class_device(class_dev); } else if ((strncmp(devpath, "/devices/", 9) == 0)) { /* open the path we are called for */ @@ -303,32 +344,33 @@ int main(int argc, char *argv[], char *envp[]) device_dev = sysfs_open_device_path(filename); if (device_dev) break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } if (device_dev == NULL) { dbg("error: getting /device-device"); - rc = 4; + rc = 7; goto exit; } dbg("device_device opened '%s'", filename); /* wait for the bus value */ if (wait_for_bus_device(device_dev) != 0) - rc = 9; + rc = 8; sysfs_close_device(device_dev); - /* finished */ - goto exit; - } else { dbg("unhandled sysfs path, no need to wait"); } exit: if (rc == 0) - info("result: waiting for sysfs successful '%s'", devpath); + dbg("result: waiting for sysfs successful '%s'", devpath); else - info("result: waiting for sysfs failed '%s'", devpath); + info("error: wait_for_sysfs needs an update to handle the device '%s' " + "properly, please report to ", + devpath); return rc; } From e284ecba7646562da9ad4c3c22871f6c341960d4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 00:11:04 -0700 Subject: [PATCH 0862/4284] [PATCH] add support for usb interfaces to wait_for_sysfs to keep it quiet. --- wait_for_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 6275db23b1..28ff43bdb5 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -174,6 +174,7 @@ static int wait_for_bus_device(struct sysfs_device *device_dev) { .bus = "scsi", .file = "vendor" }, { .bus = "usb", .file = "idVendor" }, { .bus = "usb", .file = "iInterface" }, + { .bus = "usb", .file = "bNumEndpoints" }, { .bus = "usb-serial", .file = "detach_state" }, { .bus = "ide", .file = "detach_state" }, { .bus = "pci", .file = "vendor" }, From 1059b07a143fac796a4ae8a7235cab9665a7622e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 7 Oct 2004 00:17:11 -0700 Subject: [PATCH 0863/4284] [PATCH] fix problems with dev.d and udevstart Here is the correction for the dev.d/ scripts too. We should pass the right argv[0] here too. A script may depend on the right value, as udev does with udev/udevstart. Here is the old version: [pid 4692] execve("/etc/dev.d/default/log.dev", ["./udev", "block"], [/* 41 vars */]) = 0 this the new one: [pid 9832] execve("/etc/dev.d/default/log.dev", ["/etc/dev.d/default/log.dev", "block"], [/* 41 vars */]) = 0 --- dev_d.c | 8 +++++++- namedev.c | 5 ----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/dev_d.c b/dev_d.c index c091f11c28..eaf9b1dc12 100644 --- a/dev_d.c +++ b/dev_d.c @@ -39,6 +39,7 @@ static int run_program(char *name) { pid_t pid; int fd; + char *argv[3]; dbg("running %s", name); @@ -54,7 +55,12 @@ static int run_program(char *name) dup2(fd, STDERR_FILENO); } close(fd); - execv(name, main_argv); + + argv[0] = name; + argv[1] = main_argv[1]; + argv[2] = NULL; + + execv(name, argv); dbg("exec of child failed"); exit(1); case -1: diff --git a/namedev.c b/namedev.c index 3843d02869..695fb55413 100644 --- a/namedev.c +++ b/namedev.c @@ -450,11 +450,6 @@ static int execute_program(const char *path, char *value, int len) dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); } - /* set basename() only */ - pos = strrchr(argv[0], '/'); - if (pos != NULL) - argv[0] = &pos[1]; - retval = pipe(fds); if (retval != 0) { dbg("pipe failed"); From 5cb8eb82e01d01b16483ec59c8ab2d8a4100d807 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 00:27:03 -0700 Subject: [PATCH 0864/4284] [PATCH] 033 release --- ChangeLog | 43 +++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ab1dfa54d9..ade31556b5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,46 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 0b635ffb25..5ff74b4afe 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TESTER = udevtest STARTER = udevstart RULER = udevruler WAIT = wait_for_sysfs -VERSION = 032_bk +VERSION = 033 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 193befca6c..e145ad2431 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 032 +Version: 033 Release: 1 License: GPL Group: Utilities/System From 90852564d01bb7d2835b159ba2e572dad1afb37d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 7 Oct 2004 01:34:31 -0700 Subject: [PATCH 0865/4284] [PATCH] wait_for_sysfs bluetooth class update Here is the file to wait for the bluetooth class, as it is not a "dev" file. udev waits for 10 seconds here too. --- wait_for_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 28ff43bdb5..0881b619c7 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -61,6 +61,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { .subsystem = "scsi_device", .file = NULL }, { .subsystem = "pcmcia_socket", .file = "card_type" }, { .subsystem = "usb_host", .file = NULL }, + { .subsystem = "bluetooth", .file = "address" }, { NULL, NULL } }; struct class_file *classfile; From 1a13fcb3dd814107d20ff2d26659cb2d6e63b354 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 18:43:31 -0700 Subject: [PATCH 0866/4284] [PATCH] add support for i2c-adapter devices to wait_for_sysfs.c --- wait_for_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 0881b619c7..5e8874cf7c 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -62,6 +62,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { .subsystem = "pcmcia_socket", .file = "card_type" }, { .subsystem = "usb_host", .file = NULL }, { .subsystem = "bluetooth", .file = "address" }, + { .subsystem = "i2c-adapter", .file = NULL }, { NULL, NULL } }; struct class_file *classfile; @@ -151,6 +152,7 @@ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) { static char *devices_without_bus[] = { "scsi_host", + "i2c-adapter", NULL }; char **device; From 606397db856af2b66947daed4a4a927c37951fe8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 19:12:10 -0700 Subject: [PATCH 0867/4284] [PATCH] added support for i2c devices in wait_for_sysfs.c --- wait_for_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 5e8874cf7c..16ee50e4a7 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -182,6 +182,7 @@ static int wait_for_bus_device(struct sysfs_device *device_dev) { .bus = "ide", .file = "detach_state" }, { .bus = "pci", .file = "vendor" }, { .bus = "platform", .file = "detach_state" }, + { .bus = "i2c", .file = "detach_state" }, { NULL } }; struct bus_file *busfile; From b19e47764c5a5baf4bf7b0d19528f8f456b05d61 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 20:56:08 -0700 Subject: [PATCH 0868/4284] [PATCH] get rid of annoying extra lines in the syslog for some libsysfs debug messages. --- libsysfs/sysfs_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 492c7fa668..f65e5df3aa 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -454,7 +454,7 @@ int sysfs_path_is_link(const char *path) return 1; } if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed\n"); + dprintf("stat() failed"); return 1; } if (S_ISLNK(astats.st_mode)) @@ -477,7 +477,7 @@ int sysfs_path_is_file(const char *path) return 1; } if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed\n"); + dprintf("stat() failed"); return 1; } if (S_ISREG(astats.st_mode)) From b9b659ae606c8583b052d663c5858028848b1878 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 21:06:07 -0700 Subject: [PATCH 0869/4284] [PATCH] wait_for_sysfs: clean up the logic for the list of devices that we do not expect device symlinks for This makes it a lot easier to test for these devices, otherwise the list would have gotten very large --- wait_for_sysfs.c | 97 +++++++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 16ee50e4a7..cb94b64404 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -99,49 +99,70 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev /* skip waiting for physical device */ static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) { - static char *devices_without_link[] = { - "nb", - "ram", - "loop", - "fd", - "md", - "dos_cd", - "double", - "flash", - "msd", - "rflash", - "rom", - "rrom", - "sbpcd", - "pcd", - "pf", - "scd", - "sit", - "lp", - "ubd", - "vcs", - "vcsa", - "console", - "tty", - "ttyS", - NULL + /* List of devices without a "device" symlink */ + static struct class_device { + char *subsystem; + char *device; + } class_device[] = { + { .subsystem = "block", .device = "double" }, + { .subsystem = "block", .device = "nb" }, + { .subsystem = "block", .device = "ram" }, + { .subsystem = "block", .device = "loop" }, + { .subsystem = "block", .device = "fd" }, + { .subsystem = "block", .device = "md" }, + { .subsystem = "block", .device = "dos_cd" }, + { .subsystem = "block", .device = "rflash" }, + { .subsystem = "block", .device = "rom" }, + { .subsystem = "block", .device = "rrom" }, + { .subsystem = "block", .device = "flash" }, + { .subsystem = "block", .device = "msd" }, + { .subsystem = "block", .device = "sbpcd" }, + { .subsystem = "block", .device = "pcd" }, + { .subsystem = "block", .device = "pf" }, + { .subsystem = "block", .device = "scd" }, + { .subsystem = "block", .device = "ubd" }, + { .subsystem = "input", .device = "event" }, + { .subsystem = "input", .device = "mice" }, + { .subsystem = "input", .device = "mouse" }, + { .subsystem = "input", .device = "ts" }, + { .subsystem = "vc", .device = "vcs" }, + { .subsystem = "vc", .device = "vcsa" }, + { .subsystem = "tty", .device = NULL }, + { .subsystem = "cpuid", .device = "cpu" }, + { .subsystem = "graphics", .device = "fb" }, + { .subsystem = "mem", .device = NULL }, + { .subsystem = "misc", .device = NULL }, + { .subsystem = "msr", .device = NULL }, + { .subsystem = "netlink", .device = NULL }, + { .subsystem = "sound", .device = NULL }, + { .subsystem = "snd", .device = NULL }, + { .subsystem = "printer", .device = "lp" }, + { NULL, NULL } }; - char **device; + struct class_device *classdevice; + int len; - for (device = devices_without_link; *device != NULL; device++) { - int len = strlen(*device); + /* look if we want to look for another file instead of "dev" */ + for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) { + if (strcmp(class_dev->classname, classdevice->subsystem) == 0) { + /* if device is NULL, all devices in this class are ok */ + if (classdevice->device == NULL) + return 1; - /* look if name matches */ - if (strncmp(class_dev->name, *device, len) != 0) - continue; + len = strlen(classdevice->device); - /* exact match */ - if (strlen(class_dev->name) == len) - return 1; + /* see if device name matches */ + if (strncmp(class_dev->name, classdevice->device, len) != 0) + continue; - /* instance numbers are matching too */ - if (isdigit(class_dev->name[len])) - return 1; + /* exact match */ + if (strlen(class_dev->name) == len) + return 1; + + /* instance numbers are matching too */ + if (isdigit(class_dev->name[len])) + return 1; + } } return 0; From bab16df879b33e9dd33e37c12581d60cbfb6fe71 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 21:39:40 -0700 Subject: [PATCH 0870/4284] [PATCH] 33_bk mark for the makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5ff74b4afe..2c4cb1e56f 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TESTER = udevtest STARTER = udevstart RULER = udevruler WAIT = wait_for_sysfs -VERSION = 033 +VERSION = 033_bk INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev From f35fb62819d017880d6008b65179a3528eaba623 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 21:40:01 -0700 Subject: [PATCH 0871/4284] [PATCH] hm, somethings odd with DEVPATH, see if this fixes it... --- dev_d.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev_d.c b/dev_d.c index eaf9b1dc12..050df7bbec 100644 --- a/dev_d.c +++ b/dev_d.c @@ -96,8 +96,9 @@ void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath) strfieldcat(env_devname, dev->name); } else if (dev->type == 'n') { strfieldcpy(env_devname, dev->name); - setenv("DEVPATH", devpath, 1); } + + setenv("DEVPATH", devpath, 1); setenv("DEVNAME", env_devname, 1); dbg("DEVNAME='%s'", env_devname); From da767d0739c86a04a0c0326cebff6c08ffe1228c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 7 Oct 2004 22:26:02 -0700 Subject: [PATCH 0872/4284] [PATCH] Revert previous dev_d.c change, it's not what is causing HAL problems. Cset exclude: greg@kroah.com|ChangeSet|20041007204001|14326 --- dev_d.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dev_d.c b/dev_d.c index 050df7bbec..eaf9b1dc12 100644 --- a/dev_d.c +++ b/dev_d.c @@ -96,9 +96,8 @@ void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath) strfieldcat(env_devname, dev->name); } else if (dev->type == 'n') { strfieldcpy(env_devname, dev->name); + setenv("DEVPATH", devpath, 1); } - - setenv("DEVPATH", devpath, 1); setenv("DEVNAME", env_devname, 1); dbg("DEVNAME='%s'", env_devname); From 2cb3973610958ea3991e3be8e6848060069ca458 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 8 Oct 2004 00:28:16 -0700 Subject: [PATCH 0873/4284] [PATCH] add comment in wait_for_sysfs to explain the structure better. --- wait_for_sysfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index cb94b64404..2504b2e0c3 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -99,7 +99,8 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev /* skip waiting for physical device */ static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) { - /* List of devices without a "device" symlink */ + /* List of devices without a "device" symlink + * set .device to NULL to accept all devices in that subsystem */ static struct class_device { char *subsystem; char *device; From d1f382f026ce03b9f2ef9111bacd821cbb33f743 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 8 Oct 2004 00:36:33 -0700 Subject: [PATCH 0874/4284] [PATCH] 034 release --- ChangeLog | 16 ++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ade31556b5..4472f0c8ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 2c4cb1e56f..90b69420a8 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TESTER = udevtest STARTER = udevstart RULER = udevruler WAIT = wait_for_sysfs -VERSION = 033_bk +VERSION = 034 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index e145ad2431..0b843e9228 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 033 +Version: 034 Release: 1 License: GPL Group: Utilities/System From 10eb67ec70bf1a41dd1b94fc74a952e3845ab59b Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 12 Oct 2004 00:16:24 -0700 Subject: [PATCH 0875/4284] [PATCH] update wait_for_sysfs with a bunch more devices thanks to user reports. --- wait_for_sysfs.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 2504b2e0c3..86422c24c0 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -63,6 +63,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { .subsystem = "usb_host", .file = NULL }, { .subsystem = "bluetooth", .file = "address" }, { .subsystem = "i2c-adapter", .file = NULL }, + { .subsystem = "pci_bus", .file = NULL }, { NULL, NULL } }; struct class_file *classfile; @@ -126,8 +127,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "input", .device = "mice" }, { .subsystem = "input", .device = "mouse" }, { .subsystem = "input", .device = "ts" }, - { .subsystem = "vc", .device = "vcs" }, - { .subsystem = "vc", .device = "vcsa" }, + { .subsystem = "vc", .device = NULL }, { .subsystem = "tty", .device = NULL }, { .subsystem = "cpuid", .device = "cpu" }, { .subsystem = "graphics", .device = "fb" }, @@ -135,9 +135,15 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "misc", .device = NULL }, { .subsystem = "msr", .device = NULL }, { .subsystem = "netlink", .device = NULL }, + { .subsystem = "net", .device = NULL }, { .subsystem = "sound", .device = NULL }, - { .subsystem = "snd", .device = NULL }, { .subsystem = "printer", .device = "lp" }, + { .subsystem = "nvidia", .device = NULL }, + { .subsystem = "video4linux", .device = NULL }, + { .subsystem = "lirc", .device = NULL }, + { .subsystem = "firmware", .device = NULL }, + { .subsystem = "drm", .device = NULL }, + { .subsystem = "pci_bus", .device = NULL }, { NULL, NULL } }; struct class_device *classdevice; From 8372907752159970c86c3f7cc565c35cf2fa1ef9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 12 Oct 2004 00:47:27 -0700 Subject: [PATCH 0876/4284] [PATCH] added ieee1394 support to wait_for_sysfs --- wait_for_sysfs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 86422c24c0..bce60731fa 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -64,6 +64,9 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { .subsystem = "bluetooth", .file = "address" }, { .subsystem = "i2c-adapter", .file = NULL }, { .subsystem = "pci_bus", .file = NULL }, + { .subsystem = "ieee1394", .file = NULL }, + { .subsystem = "ieee1394_host", .file = NULL }, + { .subsystem = "ieee1394_node", .file = NULL }, { NULL, NULL } }; struct class_file *classfile; @@ -144,6 +147,9 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "firmware", .device = NULL }, { .subsystem = "drm", .device = NULL }, { .subsystem = "pci_bus", .device = NULL }, + { .subsystem = "ieee1394", .device = NULL }, + { .subsystem = "ieee1394_host", .device = NULL }, + { .subsystem = "ieee1394_node", .device = NULL }, { NULL, NULL } }; struct class_device *classdevice; From 858e0e81d041877d88ae4608ac569e9208661865 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 12 Oct 2004 00:53:57 -0700 Subject: [PATCH 0877/4284] [PATCH] 035 release --- ChangeLog | 7 +++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4472f0c8ec..4ea4d32a35 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 90b69420a8..c08f92b0eb 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TESTER = udevtest STARTER = udevstart RULER = udevruler WAIT = wait_for_sysfs -VERSION = 034 +VERSION = 035 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 0b843e9228..dcc96a7a30 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 034 +Version: 035 Release: 1 License: GPL Group: Utilities/System From 788b94201bcb354bf7d9c160371f52ecc6b1a458 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 12 Oct 2004 21:48:49 -0700 Subject: [PATCH 0878/4284] [PATCH] add the error number to the error message in wait_for_sysfs to help out in debugging problems. --- wait_for_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index bce60731fa..c1d7aa0a0c 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -408,8 +408,8 @@ exit: dbg("result: waiting for sysfs successful '%s'", devpath); else info("error: wait_for_sysfs needs an update to handle the device '%s' " - "properly, please report to ", - devpath); + "properly (%d), please report to ", + devpath, rc); return rc; } From b808414477b07ee827ebc41390b812fe8488297a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 12 Oct 2004 21:50:15 -0700 Subject: [PATCH 0879/4284] [PATCH] 036 release --- ChangeLog | 6 ++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ea4d32a35..7b16430849 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +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 ============================================ diff --git a/Makefile b/Makefile index c08f92b0eb..1f246b7307 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TESTER = udevtest STARTER = udevstart RULER = udevruler WAIT = wait_for_sysfs -VERSION = 035 +VERSION = 036 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index dcc96a7a30..d466804659 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 035 +Version: 036 Release: 1 License: GPL Group: Utilities/System From d30ef6b192a39cf69f9e6037a4c984ccf533f721 Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Wed, 13 Oct 2004 20:53:52 -0700 Subject: [PATCH 0880/4284] [PATCH] small udev patch You should also remove etc/dev.d/default/dbus.dev which does not exist anymore. BTW, please remove etc/init.d/udev.debian because it is broken. --- etc/dev.d/net/hotplug.dev | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/dev.d/net/hotplug.dev b/etc/dev.d/net/hotplug.dev index ed64c08cf2..15cc5cb52e 100644 --- a/etc/dev.d/net/hotplug.dev +++ b/etc/dev.d/net/hotplug.dev @@ -18,6 +18,6 @@ fi INTERFACE=$DEVNAME export INTERFACE if [ -f /etc/hotplug.d/default/default.hotplug ]; then - /etc/hotplug.d/default/default.hotplug net + exec /etc/hotplug.d/default/default.hotplug net fi From 91d55528e1cbea6a590b5f9298125c300be0fabf Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 20:54:43 -0700 Subject: [PATCH 0881/4284] [PATCH] remove the debian specific file, as they don't want to share with the rest of the world :( --- etc/init.d/udev.debian | 114 ----------------------------------------- 1 file changed, 114 deletions(-) delete mode 100644 etc/init.d/udev.debian diff --git a/etc/init.d/udev.debian b/etc/init.d/udev.debian deleted file mode 100644 index 8268fe6c2f..0000000000 --- a/etc/init.d/udev.debian +++ /dev/null @@ -1,114 +0,0 @@ -#! /bin/sh -# -# random init script to setup /udev -# -# chkconfig: 2345 20 80 -# description: manage user-space device nodes in /udev -# -# 2003-12-23: - some tweaks to run silently on a debian system -# 2003-12-30: - manage creation (and deletion) of /proc/self/fd->fd and -# fd/[0,1,2]->std[in,out,err] links -# - creation and deletion of /proc/kcore->core link -# - creation and deletion of /proc/asound/oss/sndstat->sndstat link - - - -udev_dir=/udev -sysfs_dir=/sys -bin=/sbin/udev - -action () { - if test $2 ; then - echo $1 - else - echo "Assertion $2 failed" - echo "Aborting" - exit 1 - fi -} - -run_udev () { - # handle block devices and their partitions - for i in ${sysfs_dir}/block/*; do - # add each drive - export DEVPATH=${i#${sysfs_dir}} - $bin block & - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - $bin block & - fi - done - done - # all other device classes - for i in ${sysfs_dir}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - CLASS=`echo ${i#${sysfs_dir}} | \ - cut --delimiter='/' --fields=3-` - $bin $CLASS & - fi - done - done -} - - -case "$1" in - start) - if [ ! -d $udev_dir ]; then - mkdir $udev_dir - fi - # don't use udev if sysfs is not mounted - if [ ! -d $sysfs_dir/block ]; then - exit 1 - fi - # propogate /udev from /sys - we only need this while we do not - # have initramfs and an early user-space with which to do early - # device bring up - action "Creating initial udev device nodes: " /bin/true - export ACTION=add - run_udev - - # hack to create stdin node - cd $udev_dir && ln -s /proc/self/fd fd - cd $udev_dir && ln -s fd/0 stdin - cd $udev_dir && ln -s fd/1 stdout - cd $udev_dir && ln -s fd/2 stderr - cd $udev_dir && ln -s /proc/kcore core - cd $udev_dir && ln -s /proc/asound/oss/sndstat sndstat - ;; - stop) - # be careful - action "Removing udev device nodes: " /bin/true - export ACTION=remove - run_udev - rm -f $udev_dir/sndstat - rm -f $udev_dir/core - rm -f $udev_dir/stderr - rm -f $udev_dir/stdout - rm -f $udev_dir/stdin - rm -f $udev_dir/fd - ;; - status) - if [ -d $udev_dir ]; then - echo "the udev device node directory exists" - else - echo "the udev device node directory does not exist" - fi - ;; - restart) - $0 stop - $0 start - ;; - reload) - # nothing to do here - ;; - *) - echo "Usage: $0 {start|stop|status|restart}" - exit 1 -esac - -exit 0 From cdd95f9a2d80beb3e4e32a10349fe6a69aa95f5a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 13 Oct 2004 20:55:01 -0700 Subject: [PATCH 0882/4284] [PATCH] wait_for_sysfs_update Here is an update to wait_for_sysfs to print the udev version to syslog, let hardware net interfaces wait again for the device link and revert the video4linux to wait for the device. The error here was caused by a out-of-tree media-driver, that needs the fix, not the our program. I've added a small comment for that to the log as I expect more of this to show up and the recent desktop integration work depends heavily on proper sysfs support, so the drivers should be fixed. --- wait_for_sysfs.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index c1d7aa0a0c..2252c30cd8 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -32,6 +32,7 @@ #include #include "logging.h" +#include "udev_version.h" #include "libsysfs/sysfs/libsysfs.h" #ifdef LOG @@ -138,11 +139,14 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "misc", .device = NULL }, { .subsystem = "msr", .device = NULL }, { .subsystem = "netlink", .device = NULL }, - { .subsystem = "net", .device = NULL }, + { .subsystem = "net", .device = "sit" }, + { .subsystem = "net", .device = "ppp" }, + { .subsystem = "net", .device = "lo" }, + { .subsystem = "net", .device = "tap" }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, { .subsystem = "nvidia", .device = NULL }, - { .subsystem = "video4linux", .device = NULL }, + { .subsystem = "video4linux", .device = "vbi" }, { .subsystem = "lirc", .device = NULL }, { .subsystem = "firmware", .device = NULL }, { .subsystem = "drm", .device = NULL }, @@ -407,9 +411,10 @@ exit: if (rc == 0) dbg("result: waiting for sysfs successful '%s'", devpath); else - info("error: wait_for_sysfs needs an update to handle the device '%s' " - "properly (%d), please report to ", - devpath, rc); + info("either wait_for_sysfs (udev %s) needs an update to handle the device '%s' " + "properly (%d) or the sysfs-support of your device's driver needs to be fixed, " + "please report to ", + UDEV_VERSION, devpath, rc); return rc; } From a5e425369c9eccb35c7d0533e7a9dbdee864a6b5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 21:08:57 -0700 Subject: [PATCH 0883/4284] [PATCH] fix up Makefile for wait_for_sysfs udev_version.h dependancy --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 1f246b7307..70499e079a 100644 --- a/Makefile +++ b/Makefile @@ -263,6 +263,7 @@ $(INFO).o: $(GEN_HEADERS) $(DAEMON).o: $(GEN_HEADERS) $(SENDER).o: $(GEN_HEADERS) $(STARTER).o: $(GEN_HEADERS) +$(WAIT).o: $(GEN_HEADERS) $(ROOT): $(LIBC) $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) From 2b29bb4f75bb6f7abb7e5957c812c9d41496aacf Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 21:09:28 -0700 Subject: [PATCH 0884/4284] [PATCH] add support for class/raw/ to wait_for_sysfs --- wait_for_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 2252c30cd8..86499a42cd 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -154,6 +154,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "ieee1394", .device = NULL }, { .subsystem = "ieee1394_host", .device = NULL }, { .subsystem = "ieee1394_node", .device = NULL }, + { .subsystem = "raw", .device = NULL }, { NULL, NULL } }; struct class_device *classdevice; From fa7aa5ecbb4af0c027c250d0ed4e1c16a0b3fd80 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 21:19:49 -0700 Subject: [PATCH 0885/4284] [PATCH] change max time to wait in wait_for_sysfs to 10 seconds to hopefully handle some slow machines. --- wait_for_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 86499a42cd..f87253d044 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -47,7 +47,7 @@ void log_message(int level, const char *format, ...) } #endif -#define WAIT_MAX_SECONDS 5 +#define WAIT_MAX_SECONDS 10 #define WAIT_LOOP_PER_SECOND 20 /* wait for specific file to show up, normally the "dev"-file */ From c850706e84e3a86484ca806f898f3c0672dae4cd Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 21:25:11 -0700 Subject: [PATCH 0886/4284] [PATCH] rename files to have '_' instead of '-' in them. We should be consistent in our madness... --- Makefile | 4 ++-- udev-add.c => udev_add.c | 0 udev-remove.c => udev_remove.c | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename udev-add.c => udev_add.c (100%) rename udev-remove.c => udev_remove.c (100%) diff --git a/Makefile b/Makefile index 70499e079a..b55b5bcbe0 100644 --- a/Makefile +++ b/Makefile @@ -205,8 +205,8 @@ SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ OBJS = udev_lib.o \ udev_config.o \ - udev-add.o \ - udev-remove.o \ + udev_add.o \ + udev_remove.o \ udevdb.o \ namedev.o \ namedev_parse.o \ diff --git a/udev-add.c b/udev_add.c similarity index 100% rename from udev-add.c rename to udev_add.c diff --git a/udev-remove.c b/udev_remove.c similarity index 100% rename from udev-remove.c rename to udev_remove.c From c04a16479f5c3bde13e7e2400f384922196ec97f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 22:28:06 -0700 Subject: [PATCH 0887/4284] [PATCH] Make the build silent, thanks to a helper program from ncftp --- Makefile | 72 +++++++---- ccdv.c | 384 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 432 insertions(+), 24 deletions(-) create mode 100644 ccdv.c diff --git a/Makefile b/Makefile index b55b5bcbe0..356d1a9f59 100644 --- a/Makefile +++ b/Makefile @@ -75,6 +75,10 @@ udevdir = ${prefix}/udev # than the local version of klibc #USE_KLIBC = true +# make the build silent (well, at least the udev part) Set this +# to something else to make it noisy again. +V=false + # set up PWD so that older versions of make will work with our build. PWD = $(shell pwd) @@ -87,6 +91,7 @@ LD = $(CROSS)gcc AR = $(CROSS)ar STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib +HOSTCC = gcc export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH_LIB_OBJS CRT0 @@ -195,13 +200,13 @@ $(CRT0): TDB = tdb/tdb.o \ tdb/spinlock.o -SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ - $(PWD)/libsysfs/sysfs_class.o \ - $(PWD)/libsysfs/sysfs_device.o \ - $(PWD)/libsysfs/sysfs_dir.o \ - $(PWD)/libsysfs/sysfs_driver.o \ - $(PWD)/libsysfs/sysfs_utils.o \ - $(PWD)/libsysfs/dlist.o +SYSFS = libsysfs/sysfs_bus.o \ + libsysfs/sysfs_class.o \ + libsysfs/sysfs_device.o \ + libsysfs/sysfs_dir.o \ + libsysfs/sysfs_driver.o \ + libsysfs/sysfs_utils.o \ + libsysfs/dlist.o OBJS = udev_lib.o \ udev_config.o \ @@ -229,9 +234,21 @@ ifeq ($(strip $(USE_KLIBC)),true) KLIBC_FIXUP = klibc_fixups.o endif +ifeq ($(strip $(V)),false) + QUIET=@./ccdv + HOST_PROGS=ccdv +else + QUIET= + HOST_PROGS= +endif + # header files automatically generated GEN_HEADERS = udev_version.h +ccdv: + @echo "Building ccdv" + @$(HOSTCC) -O1 ccdv.c -o ccdv + # Rules on how to create the generated header files udev_version.h: @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ @@ -247,17 +264,17 @@ udev_version.h: # Rules on how to create the generated config files $(LOCAL_CFG_DIR)/udev.conf: - sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ + @./ccdv sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ GEN_MANPAGES = udev.8 GEN_MANPAGESIN = udev.8.in # Rules on how to create the man pages $(GEN_MANPAGES): $(GEN_MANPAGESIN) - sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ + @./ccdv sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ $(OBJS): $(GEN_HEADERS) -$(ROOT).o: $(GEN_HEADERS) +$(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) $(TESTER).o: $(GEN_HEADERS) $(INFO).o: $(GEN_HEADERS) $(DAEMON).o: $(GEN_HEADERS) @@ -266,37 +283,44 @@ $(STARTER).o: $(GEN_HEADERS) $(WAIT).o: $(GEN_HEADERS) $(ROOT): $(LIBC) $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $@ + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevtest.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $@ + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevtest.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ $(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEADERS) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $@ + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ $(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_lib.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $@ + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_lib.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $@ + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ $(RULER): $(LIBC) $(RULER).o $(OBJS) $(HEADERS) - $(LD) $(LDFLAGS) -o $@ $(CRT0) udevruler.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) -lnewt - $(STRIPCMD) $@ + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevruler.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) -lnewt + $(QUIET) $(STRIPCMD) $@ $(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) - $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(STRIPCMD) $@ + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + +#.c.o: +# $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) -c -o $@ $< +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(RULER) $(WAIT) + - rm -f ccdv $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff --git a/ccdv.c b/ccdv.c new file mode 100644 index 0000000000..069cc461de --- /dev/null +++ b/ccdv.c @@ -0,0 +1,384 @@ +/* ccdv.c + * + * Copyright (C) 2002-2003, by Mike Gleason, NcFTP Software. + * All Rights Reserved. + * + * Licensed under the GNU Public License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SETCOLOR_SUCCESS (gANSIEscapes ? "\033\1331;32m" : "") +#define SETCOLOR_FAILURE (gANSIEscapes ? "\033\1331;31m" : "") +#define SETCOLOR_WARNING (gANSIEscapes ? "\033\1331;33m" : "") +#define SETCOLOR_NORMAL (gANSIEscapes ? "\033\1330;39m" : "") + +#define TEXT_BLOCK_SIZE 8192 +#define INDENT 2 + +#define TERMS "vt100:vt102:vt220:vt320:xterm:xterm-color:ansi:linux:scoterm:scoansi:dtterm:cons25:cygwin" + +size_t gNBufUsed = 0, gNBufAllocated = 0; +char *gBuf = NULL; +int gCCPID; +char gAction[64] = ""; +char gTarget[64] = ""; +char gAr[32] = ""; +char gArLibraryTarget[64] = ""; +int gDumpCmdArgs = 0; +char gArgsStr[800]; +int gColumns = 80; +int gANSIEscapes = 0; +int gExitStatus = 95; + +static void DumpFormattedOutput(void) +{ + char *cp; + char spaces[8 + 1] = " "; + char *saved; + int curcol; + int i; + + curcol = 0; + saved = NULL; + for (cp = gBuf + ((gDumpCmdArgs == 0) ? strlen(gArgsStr) : 0); ; cp++) { + if (*cp == '\0') { + if (saved != NULL) { + cp = saved; + saved = NULL; + } else break; + } + if (*cp == '\r') + continue; + if (*cp == '\t') { + saved = cp + 1; + cp = spaces + 8 - (8 - ((curcol - INDENT - 1) % 8)); + } + if (curcol == 0) { + for (i = INDENT; --i >= 0; ) + putchar(' '); + curcol = INDENT; + } + putchar(*cp); + if (++curcol == (gColumns - 1)) { + putchar('\n'); + curcol = 0; + } else if (*cp == '\n') + curcol = 0; + } + free(gBuf); +} /* DumpFormattedOutput */ + + + +/* Difftime(), only for timeval structures. */ +static void TimeValSubtract(struct timeval *tdiff, struct timeval *t1, struct timeval *t0) +{ + tdiff->tv_sec = t1->tv_sec - t0->tv_sec; + tdiff->tv_usec = t1->tv_usec - t0->tv_usec; + if (tdiff->tv_usec < 0) { + tdiff->tv_sec--; + tdiff->tv_usec += 1000000; + } +} /* TimeValSubtract */ + + + +static void Wait(void) +{ + int pid2, status; + + do { + status = 0; + pid2 = (int) waitpid(gCCPID, &status, 0); + } while (((pid2 >= 0) && (! WIFEXITED(status))) || ((pid2 < 0) && (errno == EINTR))); + if (WIFEXITED(status)) + gExitStatus = WEXITSTATUS(status); +} /* Wait */ + + + +static int SlurpProgress(int fd) +{ + char s1[71]; + char *newbuf; + int nready; + size_t ntoread; + ssize_t nread; + struct timeval now, tnext, tleft; + fd_set ss; + fd_set ss2; + const char *trail = "/-\\|", *trailcp; + + trailcp = trail; + snprintf(s1, sizeof(s1), "%s%s%s... ", gAction, gTarget[0] ? " " : "", gTarget); + printf("\r%-70s%-9s", s1, ""); + fflush(stdout); + + gettimeofday(&now, NULL); + tnext = now; + tnext.tv_sec++; + tleft.tv_sec = 1; + tleft.tv_usec = 0; + FD_ZERO(&ss2); + FD_SET(fd, &ss2); + for(;;) { + if (gNBufUsed == (gNBufAllocated - 1)) { + if ((newbuf = (char *) realloc(gBuf, gNBufAllocated + TEXT_BLOCK_SIZE)) == NULL) { + perror("ccdv: realloc"); + return (-1); + } + gNBufAllocated += TEXT_BLOCK_SIZE; + gBuf = newbuf; + } + for (;;) { + ss = ss2; + nready = select(fd + 1, &ss, NULL, NULL, &tleft); + if (nready == 1) + break; + if (nready < 0) { + if (errno != EINTR) { + perror("ccdv: select"); + return (-1); + } + continue; + } + gettimeofday(&now, NULL); + if ((now.tv_sec > tnext.tv_sec) || ((now.tv_sec == tnext.tv_sec) && (now.tv_usec >= tnext.tv_usec))) { + tnext = now; + tnext.tv_sec++; + tleft.tv_sec = 1; + tleft.tv_usec = 0; + printf("\r%-71s%c%-7s", s1, *trailcp, ""); + fflush(stdout); + if (*++trailcp == '\0') + trailcp = trail; + } else { + TimeValSubtract(&tleft, &tnext, &now); + } + } + ntoread = (gNBufAllocated - gNBufUsed - 1); + nread = read(fd, gBuf + gNBufUsed, ntoread); + if (nread < 0) { + if (errno == EINTR) + continue; + perror("ccdv: read"); + return (-1); + } else if (nread == 0) { + break; + } + gNBufUsed += nread; + gBuf[gNBufUsed] = '\0'; + } + snprintf(s1, sizeof(s1), "%s%s%s: ", gAction, gTarget[0] ? " " : "", gTarget); + Wait(); + if (gExitStatus == 0) { + printf("\r%-70s", s1); + printf("[%s%s%s]", ((gNBufUsed - strlen(gArgsStr)) < 4) ? SETCOLOR_SUCCESS : SETCOLOR_WARNING, "OK", SETCOLOR_NORMAL); + printf("%-5s\n", " "); + } else { + printf("\r%-70s", s1); + printf("[%s%s%s]", SETCOLOR_FAILURE, "ERROR", SETCOLOR_NORMAL); + printf("%-2s\n", " "); + gDumpCmdArgs = 1; /* print cmd when there are errors */ + } + fflush(stdout); + return (0); +} /* SlurpProgress */ + + + +static int SlurpAll(int fd) +{ + char *newbuf; + size_t ntoread; + ssize_t nread; + + printf("%s%s%s.\n", gAction, gTarget[0] ? " " : "", gTarget); + fflush(stdout); + + for(;;) { + if (gNBufUsed == (gNBufAllocated - 1)) { + if ((newbuf = (char *) realloc(gBuf, gNBufAllocated + TEXT_BLOCK_SIZE)) == NULL) { + perror("ccdv: realloc"); + return (-1); + } + gNBufAllocated += TEXT_BLOCK_SIZE; + gBuf = newbuf; + } + ntoread = (gNBufAllocated - gNBufUsed - 1); + nread = read(fd, gBuf + gNBufUsed, ntoread); + if (nread < 0) { + if (errno == EINTR) + continue; + perror("ccdv: read"); + return (-1); + } else if (nread == 0) { + break; + } + gNBufUsed += nread; + gBuf[gNBufUsed] = '\0'; + } + Wait(); + gDumpCmdArgs = (gExitStatus != 0); /* print cmd when there are errors */ + return (0); +} /* SlurpAll */ + + + +static const char *Basename(const char *path) +{ + const char *cp; + cp = strrchr(path, '/'); + if (cp == NULL) + return (path); + return (cp + 1); +} /* Basename */ + + + +static const char * Extension(const char *path) +{ + const char *cp = path; + cp = strrchr(path, '.'); + if (cp == NULL) + return (""); + return (cp); +} /* Extension */ + + + +static void Usage(void) +{ + fprintf(stderr, "Usage: ccdv /path/to/cc CFLAGS...\n\n"); + fprintf(stderr, "I wrote this to reduce the deluge Make output to make finding actual problems\n"); + fprintf(stderr, "easier. It is intended to be invoked from Makefiles, like this. Instead of:\n\n"); + fprintf(stderr, "\t.c.o:\n"); + fprintf(stderr, "\t\t$(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n"); + fprintf(stderr, "\nRewrite your rule so it looks like:\n\n"); + fprintf(stderr, "\t.c.o:\n"); + fprintf(stderr, "\t\t@ccdv $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\n"); + fprintf(stderr, "ccdv 1.1.0 is Free under the GNU Public License. Enjoy!\n"); + fprintf(stderr, " -- Mike Gleason, NcFTP Software \n"); + exit(96); +} /* Usage */ + + + +int main(int argc, char **argv) +{ + int pipe1[2]; + int devnull; + char emerg[256]; + int fd; + int nread; + int i; + int cc = 0, pch = 0; + const char *quote; + + if (argc < 2) + Usage(); + + snprintf(gAction, sizeof(gAction), "Running %s", Basename(argv[1])); + memset(gArgsStr, 0, sizeof(gArgsStr)); + for (i = 1; i < argc; i++) { + quote = (strchr(argv[i], ' ') != NULL) ? "\"" : ""; + snprintf(gArgsStr + strlen(gArgsStr), sizeof(gArgsStr) - strlen(gArgsStr), "%s%s%s%s%s", (i == 1) ? "" : " ", quote, argv[i], quote, (i == (argc - 1)) ? "\n" : ""); + if ((strcmp(argv[i], "-o") == 0) && ((i + 1) < argc)) { + if (strcasecmp(Extension(argv[i + 1]), ".o") != 0) { + strcpy(gAction, "Linking"); + snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i + 1])); + } + } else if (strchr("-+/", (int) argv[i][0]) != NULL) { + continue; + } else if (strncasecmp(Extension(argv[i]), ".c", 2) == 0) { + cc++; + snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); + } else if ((strncasecmp(Extension(argv[i]), ".h", 2) == 0) && (cc == 0)) { + pch++; + snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); + } else if ((i == 1) && (strcmp(Basename(argv[i]), "ar") == 0)) { + snprintf(gAr, sizeof(gAr), "%s", Basename(argv[i])); + } else if ((gArLibraryTarget[0] == '\0') && (strcasecmp(Extension(argv[i]), ".a") == 0)) { + snprintf(gArLibraryTarget, sizeof(gArLibraryTarget), "%s", Basename(argv[i])); + } + } + if ((gAr[0] != '\0') && (gArLibraryTarget[0] != '\0')) { + strcpy(gAction, "Creating library"); + snprintf(gTarget, sizeof(gTarget), "%s", gArLibraryTarget); + } else if (pch > 0) { + strcpy(gAction, "Precompiling"); + } else if (cc > 0) { + strcpy(gAction, "Compiling"); + } + + if (pipe(pipe1) < 0) { + perror("ccdv: pipe"); + exit(97); + } + + (void) close(0); + devnull = open("/dev/null", O_RDWR, 00666); + if ((devnull != 0) && (dup2(devnull, 0) == 0)) + close(devnull); + + gCCPID = (int) fork(); + if (gCCPID < 0) { + (void) close(pipe1[0]); + (void) close(pipe1[1]); + perror("ccdv: fork"); + exit(98); + } else if (gCCPID == 0) { + /* Child */ + (void) close(pipe1[0]); /* close read end */ + if (pipe1[1] != 1) { /* use write end on stdout */ + (void) dup2(pipe1[1], 1); + (void) close(pipe1[1]); + } + (void) dup2(1, 2); /* use write end on stderr */ + execvp(argv[1], argv + 1); + perror(argv[1]); + exit(99); + } + + /* parent */ + (void) close(pipe1[1]); /* close write end */ + fd = pipe1[0]; /* use read end */ + + gColumns = (getenv("COLUMNS") != NULL) ? atoi(getenv("COLUMNS")) : 80; + gANSIEscapes = (getenv("TERM") != NULL) && (strstr(TERMS, getenv("TERM")) != NULL); + gBuf = (char *) malloc(TEXT_BLOCK_SIZE); + if (gBuf == NULL) + goto panic; + gNBufUsed = 0; + gNBufAllocated = TEXT_BLOCK_SIZE; + if (strlen(gArgsStr) < (gNBufAllocated - 1)) { + strcpy(gBuf, gArgsStr); + gNBufUsed = strlen(gArgsStr); + } + + if (isatty(1)) { + if (SlurpProgress(fd) < 0) + goto panic; + } else { + if (SlurpAll(fd) < 0) + goto panic; + } + DumpFormattedOutput(); + exit(gExitStatus); + +panic: + gDumpCmdArgs = 1; /* print cmd when there are errors */ + DumpFormattedOutput(); + while ((nread = read(fd, emerg, (size_t) sizeof(emerg))) > 0) + (void) write(2, emerg, (size_t) nread); + Wait(); + exit(gExitStatus); +} /* main */ From c36f0ac34fa3bf8b952889b9197a5ee1ea5d2714 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 22:33:09 -0700 Subject: [PATCH 0888/4284] [PATCH] a few more Makefile tweaks for the quiet feature. --- Makefile | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 356d1a9f59..4107b96a3f 100644 --- a/Makefile +++ b/Makefile @@ -251,6 +251,7 @@ ccdv: # Rules on how to create the generated header files udev_version.h: + @echo "Creating udev_version.h" @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ @echo \#define UDEV_ROOT \"$(udevdir)/\" >> $@ @echo \#define UDEV_DB \"$(udevdir)/.udev.tdb\" >> $@ @@ -264,23 +265,23 @@ udev_version.h: # Rules on how to create the generated config files $(LOCAL_CFG_DIR)/udev.conf: - @./ccdv sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ + $(QUIET) sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ GEN_MANPAGES = udev.8 GEN_MANPAGESIN = udev.8.in # Rules on how to create the man pages $(GEN_MANPAGES): $(GEN_MANPAGESIN) - @./ccdv sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ + $(QUIET) sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ $(OBJS): $(GEN_HEADERS) $(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) -$(TESTER).o: $(GEN_HEADERS) -$(INFO).o: $(GEN_HEADERS) -$(DAEMON).o: $(GEN_HEADERS) -$(SENDER).o: $(GEN_HEADERS) -$(STARTER).o: $(GEN_HEADERS) -$(WAIT).o: $(GEN_HEADERS) +$(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) +$(INFO).o: $(GEN_HEADERS) $(HOST_PROGS) +$(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS) +$(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) +$(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) +$(WAIT).o: $(GEN_HEADERS) $(HOST_PROGS) $(ROOT): $(LIBC) $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) @@ -320,7 +321,7 @@ clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(RULER) $(WAIT) - - rm -f ccdv + -rm -f ccdv $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ From 7e89a569cc4db0c1482662dc4df5f60df7aef3ff Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 13 Oct 2004 23:13:26 -0700 Subject: [PATCH 0889/4284] [PATCH] prevent deadlocks on an corrupt udev database Here is the patch, that should prevent all of the known deadlocks with corrupt tdb databases we discovered. Thanks to Frank Steiner , who tested all this endlessly with a NFS mounted /dev. The conclusion is, that udev will not work on filesystems without proper record locking, but we should prevent the endless loops anyway. This patch implements: o recovery from a corrupted udev database. udev will continue without database support now, instead of doing nothing. So the node should be generated in any case, remove will obviously not work for custom names. o added iteration limits to the tdb-code at the places we discovered endless loops. In the case tdb tries to find more than 100.000 entries with the same hash, we better give up :) o prevent a {all_partitions} loop caused by corrupt db data o log all tdb errors to syslog o switch sleep() to usleep() cause we want to use alarm() --- namedev.c | 22 +++++++------------ tdb/tdb.c | 56 ++++++++++++++++++++++++++++++++++++++++++------ udev.c | 23 ++++++++++++++------ udev.h | 3 +++ udev_add.c | 5 ++--- udev_remove.c | 14 ++++++++---- udevdb.c | 16 +++++++++++++- wait_for_sysfs.c | 13 ++++++----- 8 files changed, 110 insertions(+), 42 deletions(-) diff --git a/namedev.c b/namedev.c index 695fb55413..9276b0cbba 100644 --- a/namedev.c +++ b/namedev.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -353,7 +352,6 @@ static struct bus_file { {} }; -#define SECONDS_TO_WAIT_FOR_FILE 10 static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) { /* sleep until we see the file for this specific bus type show up this @@ -367,14 +365,14 @@ static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) struct bus_file *b = &bus_files[0]; struct sysfs_attribute *tmpattr; int found = 0; - int loop = SECONDS_TO_WAIT_FOR_FILE; + int loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ; while (1) { if (b->bus == NULL) { if (!found) break; - /* sleep to give the kernel a chance to create the file */ - sleep(1); + /* give the kernel a chance to create the file */ + usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); --loop; if (loop == 0) break; @@ -394,7 +392,8 @@ static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) } if (!found) dbg("did not find bus type '%s' on list of bus_id_files, " - "contact greg@kroah.com", sysfs_device->bus); + "please report to ", + sysfs_device->bus); exit: return; /* here to prevent compiler warning... */ } @@ -680,7 +679,6 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de { struct sysfs_device *sysfs_device; struct sysfs_class_device *class_dev_parent; - struct timespec tspec; int loop; /* Figure out where the device symlink is at. For char devices this will @@ -696,16 +694,14 @@ static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_de if (class_dev_parent != NULL) dbg("given class device has a parent, use this instead"); - tspec.tv_sec = 0; - tspec.tv_nsec = 10000000; /* sleep 10 millisec */ - loop = 10; + loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ; while (loop--) { if (udev_sleep) { if (whitelist_search(class_dev)) { sysfs_device = NULL; goto exit; } - nanosleep(&tspec, NULL); + usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); } if (class_dev_parent) @@ -727,11 +723,9 @@ device_found: if (sysfs_device->bus[0] != '\0') goto bus_found; - loop = 10; - tspec.tv_nsec = 10000000; while (loop--) { if (udev_sleep) - nanosleep(&tspec, NULL); + usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); sysfs_get_device_bus(sysfs_device); if (sysfs_device->bus[0] != '\0') diff --git a/tdb/tdb.c b/tdb/tdb.c index e87ea3692e..4cc1e07024 100644 --- a/tdb/tdb.c +++ b/tdb/tdb.c @@ -45,7 +45,12 @@ #define STANDALONE #define TDB_DEBUG #define HAVE_MMAP 1 - +/* this should prevent deadlocks loops on corrupt databases + * we've discovered. Most deadlocks happend by iterating over the + * list of entries with the same hash value. */ +#define LOOP_MAX 100000 +#define TDB_LOG(x) TDB_LOG_UDEV x +#define TDB_LOG_UDEV(tdb, level, format, arg...) info(format, ##arg) #ifdef STANDALONE #if HAVE_CONFIG_H @@ -66,6 +71,7 @@ #include "tdb.h" #include "spinlock.h" #include "../udev_lib.h" +#include "../logging.h" #else #include "includes.h" #endif @@ -89,7 +95,9 @@ /* NB assumes there is a local variable called "tdb" that is the * current context, also takes doubly-parenthesized print-style * argument. */ +#ifndef TDB_LOG #define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0) +#endif /* lock offsets */ #define GLOBAL_LOCK 0 @@ -268,7 +276,7 @@ static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) if (tdb->locked[list+1].count == 0) { if (!tdb->read_only && tdb->header.rwlocks) { if (tdb_spinlock(tdb, list, ltype)) { - TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list ltype=%d\n", + TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list %d ltype=%d\n", list, ltype)); return -1; } @@ -481,7 +489,7 @@ static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) if (rec->magic == TDB_MAGIC) { /* this happens when a app is showdown while deleting a record - we should not completely fail when this happens */ - TDB_LOG((tdb, 0,"rec_free_read non-free magic at offset=%d - fixing\n", + TDB_LOG((tdb, 0,"rec_free_read non-free magic 0x%x at offset=%d - fixing\n", rec->magic, off)); rec->magic = TDB_FREE_MAGIC; if (tdb_write(tdb, off, rec, sizeof(*rec)) == -1) @@ -617,8 +625,10 @@ int tdb_printfreelist(TDB_CONTEXT *tdb) static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) { tdb_off last_ptr, i; + int maxloop; /* read in the freelist top */ + maxloop = LOOP_MAX; last_ptr = FREELIST_TOP; while (ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { if (i == off) { @@ -627,6 +637,12 @@ static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) } /* Follow chain (next offset is at start of record) */ last_ptr = i; + + maxloop--; + if (maxloop == 0) { + TDB_LOG((tdb, 0, "remove_from_freelist: maxloop reached; corrupt database!\n")); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } } TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off)); return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); @@ -853,6 +869,7 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, { tdb_off rec_ptr, last_ptr, newrec_ptr; struct list_struct newrec; + int maxloop; if (tdb_lock(tdb, -1, F_WRLCK) == -1) return 0; @@ -868,6 +885,7 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, goto fail; /* keep looking until we find a freelist record big enough */ + maxloop = LOOP_MAX; while (rec_ptr) { if (rec_free_read(tdb, rec_ptr, rec) == -1) goto fail; @@ -919,6 +937,12 @@ static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, /* move to the next record */ last_ptr = rec_ptr; rec_ptr = rec->next; + + maxloop--; + if (maxloop == 0) { + TDB_LOG((tdb, 0, "tdb_allocate: maxloop reached; corrupt database!\n")); + return TDB_ERRCODE(TDB_ERR_CORRUPT, 0); + } } /* we didn't find enough space. See if we can expand the database and if we can then try again */ @@ -981,12 +1005,14 @@ static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, struct list_struct *r) { tdb_off rec_ptr; - + int maxloop; + /* read in the hash top */ if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) return 0; /* keep looking until we find the right record */ + maxloop = LOOP_MAX; while (rec_ptr) { if (rec_read(tdb, rec_ptr, r) == -1) return 0; @@ -1006,6 +1032,12 @@ static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, SAFE_FREE(k); } rec_ptr = r->next; + + maxloop--; + if (maxloop == 0) { + TDB_LOG((tdb, 0, "tdb_find maxloop reached; corrupt database!\n")); + return TDB_ERRCODE(TDB_ERR_CORRUPT, 0); + } } return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); } @@ -1188,6 +1220,7 @@ static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec) { tdb_off last_ptr, i; struct list_struct lastrec; + int maxloop; if (tdb->read_only) return -1; @@ -1202,10 +1235,19 @@ static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec) /* find previous record in hash chain */ if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) return -1; - for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) + + maxloop = LOOP_MAX; + for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) { if (rec_read(tdb, i, &lastrec) == -1) return -1; + maxloop--; + if (maxloop == 0) { + TDB_LOG((tdb, 0, "(tdb)do_delete: maxloop reached; corrupt database!\n")); + return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); + } + } + /* unlink it: next ptr is at start of record. */ if (last_ptr == 0) last_ptr = TDB_HASH_TOP(rec->full_hash); @@ -1789,8 +1831,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, /* Is it already in the open list? If so, fail. */ if (tdb_already_open(st.st_dev, st.st_ino)) { TDB_LOG((tdb, 2, "tdb_open_ex: " - "%s (%d,%d) is already open in this process\n", - name, st.st_dev, st.st_ino)); + "%s (%d:%d,%ld) is already open in this process\n", + name, major(st.st_dev), minor(st.st_dev), st.st_ino)); errno = EBUSY; goto fail; } diff --git a/udev.c b/udev.c index e6f2744fcb..974b9582d0 100644 --- a/udev.c +++ b/udev.c @@ -36,6 +36,9 @@ #include "namedev.h" #include "udevdb.h" +/* timeout flag for udevdb */ +extern sig_atomic_t gotalarm; + /* global variables */ char **main_argv; char **main_envp; @@ -58,6 +61,10 @@ void log_message(int level, const char *format, ...) asmlinkage static void sig_handler(int signum) { switch (signum) { + case SIGALRM: + gotalarm = 1; + info("error: timeout reached, event probably not handled correctly"); + break; case SIGINT: case SIGTERM: udevdb_exit(); @@ -94,7 +101,8 @@ int main(int argc, char *argv[], char *envp[]) dbg("version %s", UDEV_VERSION); - /* initialize our configuration */ + init_logging("udev"); + udev_init_config(); if (strstr(argv[0], "udevstart")) { @@ -146,16 +154,19 @@ int main(int argc, char *argv[], char *envp[]) /* set signal handlers */ act.sa_handler = sig_handler; + sigemptyset (&act.sa_mask); - act.sa_flags = SA_RESTART; + /* alarm must interrupt syscalls*/ + sigaction(SIGALRM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); + /* trigger timout to interrupt blocking syscalls */ + alarm(ALARM_TIMEOUT); + /* initialize udev database */ - if (udevdb_init(UDEVDB_DEFAULT) != 0) { - dbg("unable to initialize database"); - goto exit; - } + if (udevdb_init(UDEVDB_DEFAULT) != 0) + info("error: unable to initialize database, continuing without database"); switch(act_type) { case UDEVSTART: diff --git a/udev.h b/udev.h index 46c961c2d5..d66e9f626e 100644 --- a/udev.h +++ b/udev.h @@ -26,6 +26,9 @@ #include #include "libsysfs/sysfs/libsysfs.h" +#define ALARM_TIMEOUT 30 +#define WAIT_FOR_FILE_SECONDS 10 +#define WAIT_FOR_FILE_RETRY_FREQ 10 #define COMMENT_CHARACTER '#' #define NAME_SIZE 256 diff --git a/udev_add.c b/udev_add.c index e1e145de8a..78c78a1100 100644 --- a/udev_add.c +++ b/udev_add.c @@ -348,11 +348,10 @@ exit: /* wait for the "dev" file to show up in the directory in sysfs. * If it doesn't happen in about 10 seconds, give up. */ -#define SECONDS_TO_WAIT_FOR_FILE 10 static int sleep_for_file(const char *path, char* file) { char filename[SYSFS_PATH_MAX + 6]; - int loop = SECONDS_TO_WAIT_FOR_FILE; + int loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ; int retval; strfieldcpy(filename, sysfs_path); @@ -368,7 +367,7 @@ static int sleep_for_file(const char *path, char* file) goto exit; /* sleep to give the kernel a chance to create the dev file */ - sleep(1); + usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); } retval = -ENODEV; exit: diff --git a/udev_remove.c b/udev_remove.c index 7ad7c2402a..d4be8bd6f9 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -109,6 +109,7 @@ static int delete_node(struct udevice *dev) int i; char *pos; int len; + int num; strfieldcpy(filename, udev_root); strfieldcat(filename, dev->name); @@ -118,10 +119,15 @@ static int delete_node(struct udevice *dev) if (retval) return retval; - /* remove partition nodes */ - if (dev->partitions > 0) { - info("removing partitions '%s[1-%i]'", filename, dev->partitions); - for (i = 1; i <= dev->partitions; i++) { + /* remove all_partitions nodes */ + num = dev->partitions; + if (num > 0) { + info("removing all_partitions '%s[1-%i]'", filename, num); + if (num > PARTITIONS_COUNT) { + info("garbage from udev database, skip all_partitions removal"); + return -1; + } + for (i = 1; i <= num; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); secure_unlink(partitionname); diff --git a/udevdb.c b/udevdb.c index c4dc4f005c..a218b66179 100644 --- a/udevdb.c +++ b/udevdb.c @@ -42,13 +42,16 @@ #include "tdb/tdb.h" static TDB_CONTEXT *udevdb; - +sig_atomic_t gotalarm; int udevdb_add_dev(const char *path, const struct udevice *dev) { TDB_DATA key, data; char keystr[SYSFS_PATH_MAX]; + if (udevdb == NULL) + return -1; + if ((path == NULL) || (dev == NULL)) return -ENODEV; @@ -68,6 +71,9 @@ int udevdb_get_dev(const char *path, struct udevice *dev) { TDB_DATA key, data; + if (udevdb == NULL) + return -1; + if (path == NULL) return -ENODEV; @@ -88,6 +94,9 @@ int udevdb_delete_dev(const char *path) TDB_DATA key; char keystr[SYSFS_PATH_MAX]; + if (udevdb == NULL) + return -1; + if (path == NULL) return -EINVAL; @@ -121,6 +130,8 @@ int udevdb_init(int init_flag) if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) return -EINVAL; + tdb_set_lock_alarm(&gotalarm); + udevdb = tdb_open(udev_db_filename, 0, init_flag, O_RDWR | O_CREAT, 0644); if (udevdb == NULL) { if (init_flag == UDEVDB_INTERNAL) @@ -160,6 +171,9 @@ int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice * { int retval = 0; + if (udevdb == NULL) + return -1; + if (user_record_handler == NULL) { dbg("invalid user record handling function"); return -EINVAL; diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index f87253d044..a5d8ab4111 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -101,11 +101,11 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev return -1; } -/* skip waiting for physical device */ +/* check if we need to wait for a physical device */ static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) { - /* List of devices without a "device" symlink - * set .device to NULL to accept all devices in that subsystem */ + /* list of devices without a "device" symlink to the physical device + * if device is set to NULL, no devices in that subsystem has a link */ static struct class_device { char *subsystem; char *device; @@ -160,10 +160,9 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d struct class_device *classdevice; int len; - /* look if we want to look for another file instead of "dev" */ for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) { if (strcmp(class_dev->classname, classdevice->subsystem) == 0) { - /* if device is NULL, all devices in this class are ok */ + /* see if no device in this class is expected to have a device-link */ if (classdevice->device == NULL) return 1; @@ -173,11 +172,11 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d if (strncmp(class_dev->name, classdevice->device, len) != 0) continue; - /* exact match */ + /* exact name match */ if (strlen(class_dev->name) == len) return 1; - /* instance numbers are matching too */ + /* name match with instance number */ if (isdigit(class_dev->name[len])) return 1; } From dc117daa28c87c6be5846a23f06e16c2b6ff6bc1 Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Wed, 13 Oct 2004 22:37:59 -0700 Subject: [PATCH 0890/4284] [PATCH] fix incompatible pointer type warning This patch fixes two warning: assignment from incompatible pointer type asmlinkage is the reason for the warning. We can simply cast to avoid it. It also fixes this warning: warning: implicit declaration of function `umask' --- udev.c | 2 +- udevd.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/udev.c b/udev.c index 974b9582d0..78da715fec 100644 --- a/udev.c +++ b/udev.c @@ -153,7 +153,7 @@ int main(int argc, char *argv[], char *envp[]) } /* set signal handlers */ - act.sa_handler = sig_handler; + act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); /* alarm must interrupt syscalls*/ diff --git a/udevd.c b/udevd.c index 81f4474a89..380511d47e 100644 --- a/udevd.c +++ b/udevd.c @@ -35,6 +35,7 @@ #include #include "klibc_fixups.h" #include +#include #include "list.h" #include "udev.h" @@ -457,7 +458,7 @@ int main(int argc, char *argv[]) /* set signal handlers */ - act.sa_handler = sig_handler; + act.sa_handler = (void (*) (int))sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; sigaction(SIGINT, &act, NULL); From e5a5b54ab675988febeaa9cd831e21e675d5947b Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Wed, 13 Oct 2004 22:38:15 -0700 Subject: [PATCH 0891/4284] [PATCH] fix asmlinkage This patch fixes the reintroduced bug with the sig_handler(), if we link against a -mregparm=3 compiled klibc on i386. It also fixes some compiler warnings about redefined asmlinkage on some systems. Also some (broken?) compilers on distros throw out warnings if asmlinkage is before "static void". This fixes it, too. --- Makefile | 2 +- udev.c | 2 +- udev_lib.h | 9 +++++++++ udevd.c | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4107b96a3f..4b8df13985 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,7 @@ OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2> # add -Wredundant-decls when libsysfs gets cleaned up WARNINGS := -Wall -CFLAGS := -pipe -Dasmlinkage= +CFLAGS := -pipe # set up the proper tdb spinlock code if we can ifeq ($(strip $(ARCH)),i386) diff --git a/udev.c b/udev.c index 78da715fec..94888d6a43 100644 --- a/udev.c +++ b/udev.c @@ -58,7 +58,7 @@ void log_message(int level, const char *format, ...) } #endif -asmlinkage static void sig_handler(int signum) +static void asmlinkage sig_handler(int signum) { switch (signum) { case SIGALRM: diff --git a/udev_lib.h b/udev_lib.h index 2f1965ea32..e9ff379fc6 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -65,6 +65,15 @@ do { \ pos = pos + len + strspn(pos, separator), len = strcspn(pos, separator)) \ if (len > 0) +#ifdef asmlinkage +# undef asmlinkage +#endif +#ifdef __i386__ +# define asmlinkage __attribute__((regparm(0))) +#endif +#ifndef asmlinkage +# define asmlinkage /* nothing */ +#endif extern char *get_action(void); extern char *get_devpath(void); diff --git a/udevd.c b/udevd.c index 380511d47e..811f62243e 100644 --- a/udevd.c +++ b/udevd.c @@ -309,7 +309,7 @@ skip: return; } -asmlinkage static void sig_handler(int signum) +static void asmlinkage sig_handler(int signum) { int rc; From d38c486a519b7ba2acb06d57e0335a4a09adc355 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 22:51:41 -0700 Subject: [PATCH 0892/4284] [PATCH] add ipsec to wait_for_sysfs ignore list. --- wait_for_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index a5d8ab4111..6f396b96ca 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -143,6 +143,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "ppp" }, { .subsystem = "net", .device = "lo" }, { .subsystem = "net", .device = "tap" }, + { .subsystem = "net", .device = "ipsec" }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, { .subsystem = "nvidia", .device = NULL }, From a6150f4a8a45b0d53162b92e574f53a01d94c432 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 22:52:08 -0700 Subject: [PATCH 0893/4284] [PATCH] add wait_for_sysfs test script to the tarball to help people debug their boxes. --- test/wait_for_sysfs_test.sh | 40 +++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 test/wait_for_sysfs_test.sh diff --git a/test/wait_for_sysfs_test.sh b/test/wait_for_sysfs_test.sh new file mode 100644 index 0000000000..f299d23c94 --- /dev/null +++ b/test/wait_for_sysfs_test.sh @@ -0,0 +1,40 @@ +#! /bin/sh +# + +# Check for missing binaries (stale symlinks should not happen) +UDEV_BIN=../wait_for_sysfs +test -x $UDEV_BIN || exit 5 + +# Directory where sysfs is mounted +SYSFS_DIR=/sys + +run_udev () { + # handle block devices and their partitions + for i in ${SYSFS_DIR}/block/*; do + # add each drive + export DEVPATH=${i#${SYSFS_DIR}} + $UDEV_BIN block & + + # add each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + export DEVPATH=${j#${SYSFS_DIR}} + $UDEV_BIN block + fi + done + done + # all other device classes + for i in ${SYSFS_DIR}/class/*; do + for j in $i/*; do +# if [ -f $j/dev ]; then + export DEVPATH=${j#${SYSFS_DIR}} + CLASS=`echo ${i#${SYSFS_DIR}} | \ + cut --delimiter='/' --fields=3-` + $UDEV_BIN $CLASS +# fi + done + done +} + +export ACTION=add +run_udev From f93987240e34ceb5cc4f9cdde59a54b1a0011ee1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 23:16:02 -0700 Subject: [PATCH 0894/4284] [PATCH] merge --- udev.c | 1 - 1 file changed, 1 deletion(-) diff --git a/udev.c b/udev.c index 94888d6a43..d7fa327576 100644 --- a/udev.c +++ b/udev.c @@ -154,7 +154,6 @@ int main(int argc, char *argv[], char *envp[]) /* set signal handlers */ act.sa_handler = (void (*) (int))sig_handler; - sigemptyset (&act.sa_mask); /* alarm must interrupt syscalls*/ sigaction(SIGALRM, &act, NULL); From 8dc0e1382d5a0103e169b95b583e4b03b9080161 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 23:22:37 -0700 Subject: [PATCH 0895/4284] [PATCH] Fix build error with klibc due to recent changes. --- udev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.c b/udev.c index d7fa327576..a13f7013b6 100644 --- a/udev.c +++ b/udev.c @@ -20,6 +20,7 @@ * */ +#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include #include From b51a038ca59d50fb089fd92addaf815994e6d3e7 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 23:26:05 -0700 Subject: [PATCH 0896/4284] [PATCH] fix compilation warning in tdb log message. --- tdb/tdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tdb/tdb.c b/tdb/tdb.c index 4cc1e07024..af475bb7ad 100644 --- a/tdb/tdb.c +++ b/tdb/tdb.c @@ -1831,8 +1831,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, /* Is it already in the open list? If so, fail. */ if (tdb_already_open(st.st_dev, st.st_ino)) { TDB_LOG((tdb, 2, "tdb_open_ex: " - "%s (%d:%d,%ld) is already open in this process\n", - name, major(st.st_dev), minor(st.st_dev), st.st_ino)); + "%s (%d:%d,%lld) is already open in this process\n", + name, major(st.st_dev), minor(st.st_dev), (unsigned long long)st.st_ino)); errno = EBUSY; goto fail; } From e457f010b1360ce92a26018a933eefaaed03d520 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 13 Oct 2004 23:58:54 -0700 Subject: [PATCH 0897/4284] [PATCH] 037 release --- ChangeLog | 31 +++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7b16430849..c01448ee42 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +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 :( + o 036 release TAG: v036 + +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 ============================================ diff --git a/Makefile b/Makefile index 4b8df13985..e51a050926 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TESTER = udevtest STARTER = udevstart RULER = udevruler WAIT = wait_for_sysfs -VERSION = 036 +VERSION = 037 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index d466804659..a2ef95fb38 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 036 +Version: 037 Release: 1 License: GPL Group: Utilities/System From c008fe93f5252d47f82d7f00e423983bda9ce1e3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 14 Oct 2004 00:38:08 -0700 Subject: [PATCH 0898/4284] [PATCH] fix up error in building extras and libsysfs --- Makefile | 1 - extras/scsi_id/Makefile | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e51a050926..1f9578e7f4 100644 --- a/Makefile +++ b/Makefile @@ -184,7 +184,6 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) $(GEN_CONFIGS) echo $$target ; \ $(MAKE) prefix=$(prefix) \ LD="$(LD)" \ - SYSFS="$(SYSFS)" \ KERNEL_DIR="$(KERNEL_DIR)" \ -C $$target $@ ; \ done ; \ diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 7ccc4c5118..6a73e33785 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -31,8 +31,14 @@ INSTALL_DATA = ${INSTALL} -m 644 override CFLAGS+=-Wall -fno-builtin PROG=scsi_id -SYSFS=-lsysfs +SYSFS = ../../libsysfs/sysfs_bus.o \ + ../../libsysfs/sysfs_class.o \ + ../../libsysfs/sysfs_device.o \ + ../../libsysfs/sysfs_dir.o \ + ../../libsysfs/sysfs_driver.o \ + ../../libsysfs/sysfs_utils.o \ + ../../libsysfs/dlist.o # # Built static and stripped when built with udev. # From 1fa26490e0d3b0df595fc7d327be46e4d9586bf7 Mon Sep 17 00:00:00 2001 From: "andrew.patterson@hp.com" Date: Thu, 14 Oct 2004 00:47:38 -0700 Subject: [PATCH 0899/4284] [PATCH] Problem parsing %s in udev rules > > > > That explains the spaces. What about stuff trailing %s, if %s does not > > > > contain spaces. I.e, in the above example, model is ST336753LC and the > > > > resulting device file is /dev/scsi_disks/some-proceding-stuff- > > > > ST336753LC. > > > > > > I expect the model value has trailing spaces. > > > > > > You may look with: > > > udevinfo -a -p /block/sdX > > > > Yes it does, and it seems for most SCSI devices, vendor and model will > > have trailing spaces. > > It all depends on the vendor and model :) > > > I have included a patch to udev-036 to deal with > > this issue. It trims off trailing whitespace for all sysfs attributes. > > It might be better to trim off leading whitespace as well. > > We already trim it off when matching, but we also allow matching if you > do put the spaces in there. This patch breaks that, right? Correct, I have a new patch that trims after the comparison, so it should work in both cases. --- namedev.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/namedev.c b/namedev.c index 9276b0cbba..8a4436363d 100644 --- a/namedev.c +++ b/namedev.c @@ -306,6 +306,17 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("sysfa attribute '%s' not found", attr); break; } + /* strip trailing whitespace of matching value */ + if (isspace(tmpattr->value[strlen(tmpattr->value)-1])) { + i = len = strlen(tmpattr->value); + while (i > 0 && isspace(tmpattr->value[i-1])) + i--; + if (i < len) { + tmpattr->value[i] = '\0'; + dbg("remove %i trailing whitespace chars from '%s'", + len - i, tmpattr->value); + } + } strfieldcatmax(string, tmpattr->value, maxsize); dbg("substitute sysfs value '%s'", tmpattr->value); } else { From 817c223af360b7ca518c9fe3065c641f6a17fbd3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 14 Oct 2004 00:49:55 -0700 Subject: [PATCH 0900/4284] [PATCH] 038 release --- ChangeLog | 18 +++++++++--------- Makefile | 2 +- udev.spec | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index c01448ee42..0c190852d8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +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 ============================================ @@ -18,7 +27,6 @@ Greg Kroah-Hartman: 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 :( - o 036 release TAG: v036 Kay Sievers: o prevent deadlocks on an corrupt udev database @@ -134,7 +142,6 @@ Greg Kroah-Hartman: 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 - o 030 release TAG: v030 Kay Sievers: o Fix naming ethernet devices in udevstart @@ -273,7 +280,6 @@ Greg Kroah-Hartman: 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 - o v024 release TAG: v024 Kay Sievers: o fix test regressions @@ -388,7 +394,6 @@ Greg Kroah-Hartman: 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 - o 022 release TAG: v022 Olaf Hering: o uninitialized variable for mknod and friend @@ -446,7 +451,6 @@ Greg Kroah-Hartman: o deleted current extras/multipath directory o 021_bk mark o fix the build for older versions of gcc - o 021 release TAG: v021 Hanna V. Linder: o Small fix to remove extra "will" in man page @@ -594,7 +598,6 @@ Greg Kroah-Hartman: 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 - o v017 release TAG: v017 Patrick Mansfield: o udev use new libsysfs header file location @@ -757,7 +760,6 @@ Greg Kroah-Hartman: 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 - o v013 release TAG: v013 Hanna V. Linder: o set default owner/group in db @@ -1227,7 +1229,6 @@ Greg Kroah-Hartman: 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 - o 004 changelog entrys TAG: v004 Robert Love: o udev: sleep_for_dev() bits @@ -1254,7 +1255,6 @@ Greg Kroah-Hartman: 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 - o update changelog for 003 release TAG: v003 Kay Sievers: o man file update diff --git a/Makefile b/Makefile index 1f9578e7f4..4849eff46d 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ TESTER = udevtest STARTER = udevstart RULER = udevruler WAIT = wait_for_sysfs -VERSION = 037 +VERSION = 038 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index a2ef95fb38..cb0686ea2b 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 037 +Version: 038 Release: 1 License: GPL Group: Utilities/System From 218f11bcf1ab339216337405a70e6cd0ec56a644 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 14 Oct 2004 01:42:33 -0700 Subject: [PATCH 0901/4284] [PATCH] Makefile fix Remove the rest of the debian stuff too, to make install working again. --- Makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 4849eff46d..9922d6f173 100644 --- a/Makefile +++ b/Makefile @@ -362,13 +362,11 @@ small_release: $(DISTFILES) clean @echo "Built $(RELEASE_NAME).tar.gz" -install-initscript: etc/init.d/udev etc/init.d/udev.debian etc/init.d/udev.init.LSB +install-initscript: etc/init.d/udev etc/init.d/udev.init.LSB @if [ -f /etc/redhat-release ]; then \ $(INSTALL_DATA) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ elif [ -f /etc/SuSE-release ]; then \ $(INSTALL_DATA) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ - elif [ -f /etc/debian_version ]; then \ - $(INSTALL_DATA) -D etc/init.d/udev.debian $(DESTDIR)$(initdir)/udev; \ fi install-config: From 053083431ff02dd365eb8c6fe12749b90d2a2a1f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 14 Oct 2004 19:42:52 -0700 Subject: [PATCH 0902/4284] [PATCH] fix broken 'make -j5' functionality. --- Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 9922d6f173..28823d7f2a 100644 --- a/Makefile +++ b/Makefile @@ -263,17 +263,16 @@ udev_version.h: @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ # Rules on how to create the generated config files -$(LOCAL_CFG_DIR)/udev.conf: +$(LOCAL_CFG_DIR)/udev.conf: $(HOST_PROGS) $(QUIET) sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ GEN_MANPAGES = udev.8 GEN_MANPAGESIN = udev.8.in # Rules on how to create the man pages -$(GEN_MANPAGES): $(GEN_MANPAGESIN) +$(GEN_MANPAGES): $(GEN_MANPAGESIN) $(HOST_PROGS) $(QUIET) sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ - -$(OBJS): $(GEN_HEADERS) +$(OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) $(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(INFO).o: $(GEN_HEADERS) $(HOST_PROGS) From 32935a50ea9d0f97f9416da1512c11a346888d28 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 14 Oct 2004 20:36:04 -0700 Subject: [PATCH 0903/4284] [PATCH] delete udevruler? Hey, we got consistent source filenames today. Let's go ahead :) I once started this ambitiuos curses gui to edit udev rules files. udevruler still lays dead around in the tree. I will not finish it and it is not really useful at his state. If nobody wants to do something for it, I'm for deleting it. --- Makefile | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 28823d7f2a..167c88e55e 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,6 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -RULER = udevruler WAIT = wait_for_sysfs VERSION = 038 INSTALL_DIR = /usr/local/bin @@ -301,10 +300,6 @@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -$(RULER): $(LIBC) $(RULER).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevruler.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) -lnewt - $(QUIET) $(STRIPCMD) $@ - $(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ @@ -318,7 +313,7 @@ $(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(RULER) $(WAIT) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(WAIT) -rm -f ccdv $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ From 707680b1cf08369da365de1a5e06089621ff8c77 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 14 Oct 2004 20:36:07 -0700 Subject: [PATCH 0904/4284] [PATCH] remove sleeps from udev as it is external now Here we remove all the sysfs sleep loops from udev as wait_for_sysfs will do this for us and any other hotplug user. We still keep a small blacklist of subsystems we don't care about but any missing entry here will no longer lead to a spinning udev waiting for files. --- namedev.c | 189 +++++--------------------------------------------- udev.8.in | 7 -- udev.c | 52 +++++++++----- udev.h | 3 - udev_add.c | 61 ++-------------- udev_config.c | 6 -- 6 files changed, 57 insertions(+), 261 deletions(-) diff --git a/namedev.c b/namedev.c index 8a4436363d..39f033726c 100644 --- a/namedev.c +++ b/namedev.c @@ -346,69 +346,6 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } } -/* - * Note, we can have multiple files for different busses in here due - * to the mess that USB has for its device tree... - */ -static struct bus_file { - char *bus; - char *file; -} bus_files[] = { - { .bus = "scsi", .file = "vendor" }, - { .bus = "usb", .file = "idVendor" }, - { .bus = "usb", .file = "iInterface" }, - { .bus = "usb-serial", .file = "detach_state" }, - { .bus = "ide", .file = "detach_state" }, - { .bus = "pci", .file = "vendor" }, - {} -}; - -static void wait_for_device_to_initialize(struct sysfs_device *sysfs_device) -{ - /* sleep until we see the file for this specific bus type show up this - * is needed because we can easily out-run the kernel in looking for - * these files before the paticular subsystem has created them in the - * sysfs tree properly. - * - * And people thought that the /sbin/hotplug event system was going to - * be slow, poo on you for arguing that before even testing it... - */ - struct bus_file *b = &bus_files[0]; - struct sysfs_attribute *tmpattr; - int found = 0; - int loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ; - - while (1) { - if (b->bus == NULL) { - if (!found) - break; - /* give the kernel a chance to create the file */ - usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); - --loop; - if (loop == 0) - break; - b = &bus_files[0]; - } - if (strcmp(sysfs_device->bus, b->bus) == 0) { - found = 1; - dbg("looking for file '%s' on bus '%s'", b->file, b->bus); - tmpattr = sysfs_get_device_attr(sysfs_device, b->file); - if (tmpattr) { - /* found it! */ - goto exit; - } - dbg("can't find '%s' file", b->file); - } - ++b; - } - if (!found) - dbg("did not find bus type '%s' on list of bus_id_files, " - "please report to ", - sysfs_device->bus); -exit: - return; /* here to prevent compiler warning... */ -} - static void fix_kernel_name(struct udevice *udev) { char *temp = udev->kernel_name; @@ -650,108 +587,6 @@ static int match_place(struct config_device *dev, struct sysfs_class_device *cla return 0; } -static int whitelist_search(struct sysfs_class_device *class_dev) -{ - char *sysblock = "/sys/block"; - int i; - - static char *list[] = { - "nb", - "ram", - "loop", - "fd", - "md", - "dos_cd", - "double", - "flash", - "msd", - "rflash", - "rom", - "rrom", - "sbpcd", - "pcd", - "pf", - "scd", - "ubd", - NULL, - }; - - if (strncmp(class_dev->path, sysblock, strlen(sysblock))) - return 0; - - for (i=0; list[i] != NULL; i++) - if (!strncmp(class_dev->name, list[i], strlen(list[i]))) - return 1; - - return 0; -} - -static struct sysfs_device *get_sysfs_device(struct sysfs_class_device *class_dev) -{ - struct sysfs_device *sysfs_device; - struct sysfs_class_device *class_dev_parent; - int loop; - - /* Figure out where the device symlink is at. For char devices this will - * always be in the class_dev->path. But for block devices, it's different. - * The main block device will have the device symlink in it's path, but - * all partitions have the symlink in its parent directory. - * But we need to watch out for block devices that do not have parents, yet - * look like a partition (fd0, loop0, etc.) They all do not have a device - * symlink yet. We do sit and spin on waiting for them right now unless - * they happen to be in the whitelist in which case we exit. - */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) - dbg("given class device has a parent, use this instead"); - - loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ; - while (loop--) { - if (udev_sleep) { - if (whitelist_search(class_dev)) { - sysfs_device = NULL; - goto exit; - } - usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); - } - - if (class_dev_parent) - sysfs_device = sysfs_get_classdev_device(class_dev_parent); - else - sysfs_device = sysfs_get_classdev_device(class_dev); - if (sysfs_device != NULL) - goto device_found; - } - dbg("timed out waiting for device symlink, continuing on anyway..."); - -device_found: - /* We have another issue with just the wait above - the sysfs part of - * the kernel may not be quick enough to have created the link to the - * device under the "bus" subsystem. Due to this, the sysfs_device->bus - * will not contain the actual bus name :( - */ - if (sysfs_device) { - if (sysfs_device->bus[0] != '\0') - goto bus_found; - - while (loop--) { - if (udev_sleep) - usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); - sysfs_get_device_bus(sysfs_device); - - if (sysfs_device->bus[0] != '\0') - goto bus_found; - } - dbg("timed out waiting to find the device bus, continuing on anyway"); - goto exit; -bus_found: - dbg("device %s is registered with bus '%s'", - sysfs_device->name, sysfs_device->bus); - } -exit: - return sysfs_device; -} - static int match_rule(struct config_device *dev, struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) { while (1) { @@ -859,6 +694,7 @@ try_parent: int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) { + struct sysfs_class_device *class_dev_parent; struct sysfs_device *sysfs_device = NULL; struct config_device *dev; struct perm_device *perm; @@ -866,17 +702,26 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud char *pos; udev->mode = 0; + dbg("class_dev->name='%s'", class_dev->name); - /* find the sysfs_device associated with this class device */ - sysfs_device = get_sysfs_device(class_dev); + /* Figure out where the "device"-symlink is at. For char devices this will + * always be in the class_dev->path. On block devices, only the main block + * device will have the device symlink in it's path. All partition devices + * need to look at the symlink in its parent directory. + */ + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent != NULL) { + dbg("given class device has a parent, use this instead"); + sysfs_device = sysfs_get_classdev_device(class_dev_parent); + } else { + sysfs_device = sysfs_get_classdev_device(class_dev); + } + if (sysfs_device) { - dbg("sysfs_device->path='%s'", sysfs_device->path); - dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); - dbg("sysfs_device->bus='%s'", sysfs_device->bus); + dbg("found /device-device: path='%s', bus_id='%s', bus='%s'", + sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus); strfieldcpy(udev->bus_id, sysfs_device->bus_id); - wait_for_device_to_initialize(sysfs_device); } - dbg("class_dev->name = '%s'", class_dev->name); strfieldcpy(udev->kernel_name, class_dev->name); fix_kernel_name(udev); diff --git a/udev.8.in b/udev.8.in index 9c22f8aa63..c842e7befb 100644 --- a/udev.8.in +++ b/udev.8.in @@ -20,13 +20,6 @@ Overrides the default location of the .B udev config file. .TP -.B UDEV_NO_SLEEP -The default behavior of -.B udev -is to wait until all the sysfs files of the device chain are populated. If set, -.B udev -will continue, regardless of the state of the device representation. -.TP .B UDEV_NO_DEVD The default behavior of .B udev diff --git a/udev.c b/udev.c index a13f7013b6..d98a017396 100644 --- a/udev.c +++ b/udev.c @@ -75,14 +75,34 @@ static void asmlinkage sig_handler(int signum) } } -static char *subsystem_blacklist[] = { - "scsi_host", - "scsi_device", - "usb_host", - "pci_bus", - "pcmcia_socket", - "" -}; +/* list of subsystems we don't care about. not listing such systems here + * is not critical, but it makes it faster as we don't look for the "dev" file + */ +static int subsystem_without_dev(const char *subsystem) +{ + char *subsystem_blacklist[] = { + "scsi_host", + "scsi_device", + "usb_host", + "pci_bus", + "pcmcia_socket", + "bluetooth", + "i2c-adapter", + "pci_bus", + "ieee1394", + "ieee1394_host", + "ieee1394_node", + NULL + }; + char **subsys; + + for (subsys = subsystem_blacklist; *subsys != NULL; subsys++) { + if (strcmp(subsystem, *subsys) == 0) + return 1; + } + + return 0; +} int main(int argc, char *argv[], char *envp[]) { @@ -92,7 +112,6 @@ int main(int argc, char *argv[], char *envp[]) char *action; char *devpath = ""; char *subsystem = ""; - int i; int retval = -EINVAL; enum { ADD, @@ -143,20 +162,16 @@ int main(int argc, char *argv[], char *envp[]) } /* skip blacklisted subsystems */ - i = 0; - while (subsystem_blacklist[i][0] != '\0') { - if (strcmp(subsystem, subsystem_blacklist[i]) == 0) { - dbg("don't care about '%s' devices", subsystem); - goto exit; - } - i++; - } + if (subsystem_without_dev(subsystem)) { + dbg("don't care about '%s' devices", subsystem); + exit(0); + }; } /* set signal handlers */ act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); - /* alarm must interrupt syscalls*/ + /* alarm must not restart syscalls*/ sigaction(SIGALRM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); @@ -172,7 +187,6 @@ int main(int argc, char *argv[], char *envp[]) case UDEVSTART: dbg("udevstart"); namedev_init(); - udev_sleep = 0; retval = udev_start(); break; case ADD: diff --git a/udev.h b/udev.h index d66e9f626e..642b30b517 100644 --- a/udev.h +++ b/udev.h @@ -27,8 +27,6 @@ #include "libsysfs/sysfs/libsysfs.h" #define ALARM_TIMEOUT 30 -#define WAIT_FOR_FILE_SECONDS 10 -#define WAIT_FOR_FILE_RETRY_FREQ 10 #define COMMENT_CHARACTER '#' #define NAME_SIZE 256 @@ -90,7 +88,6 @@ extern char default_mode_str[MODE_SIZE]; extern char default_owner_str[OWNER_SIZE]; extern char default_group_str[GROUP_SIZE]; extern int udev_log; -extern int udev_sleep; extern int udev_dev_d; #endif diff --git a/udev_add.c b/udev_add.c index 78c78a1100..08257609ad 100644 --- a/udev_add.c +++ b/udev_add.c @@ -52,14 +52,9 @@ #include "selinux.h" -/* - * Right now the major/minor of a device is stored in a file called - * "dev" in sysfs. - * The number is stored as: - * MM:mm - * MM is the major - * mm is the minor - * The value is in decimal. +/* + * the major/minor of a device is stored in a file called "dev" + * The number is stored in decimal values in the format: M:m */ static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev) { @@ -345,35 +340,6 @@ exit: return class_dev; } -/* wait for the "dev" file to show up in the directory in sysfs. - * If it doesn't happen in about 10 seconds, give up. - */ -static int sleep_for_file(const char *path, char* file) -{ - char filename[SYSFS_PATH_MAX + 6]; - int loop = WAIT_FOR_FILE_SECONDS * WAIT_FOR_FILE_RETRY_FREQ; - int retval; - - strfieldcpy(filename, sysfs_path); - strfieldcat(filename, path); - strfieldcat(filename, file); - - while (loop--) { - struct stat buf; - - dbg("looking for '%s'", filename); - retval = stat(filename, &buf); - if (retval == 0) - goto exit; - - /* sleep to give the kernel a chance to create the dev file */ - usleep(1000 * 1000 / WAIT_FOR_FILE_RETRY_FREQ); - } - retval = -ENODEV; -exit: - return retval; -} - static int rename_net_if(struct udevice *dev, int fake) { int sk; @@ -408,25 +374,11 @@ int udev_add_device(const char *path, const char *subsystem, int fake) struct udevice dev; char devpath[DEVPATH_SIZE]; char *pos; - int retval; + int retval = 0; memset(&dev, 0x00, sizeof(dev)); dev.type = get_device_type(path, subsystem); - switch (dev.type) { - case 'b': - case 'c': - retval = sleep_for_file(path, "/dev"); - break; - - case 'n': - retval = sleep_for_file(path, "/address"); - break; - - default: - dbg("unknown device type '%c'", dev.type); - return -1; - } class_dev = get_class_dev(path); if (class_dev == NULL) @@ -435,8 +387,8 @@ int udev_add_device(const char *path, const char *subsystem, int fake) if (dev.type == 'b' || dev.type == 'c') { retval = get_major_minor(class_dev, &dev); if (retval != 0) { - dbg("get_major_minor failed"); - goto exit; + dbg("no dev-file found, do nothing"); + goto close; } } @@ -484,6 +436,7 @@ int udev_add_device(const char *path, const char *subsystem, int fake) exit: selinux_restore(); +close: sysfs_close_class_device(class_dev); return retval; diff --git a/udev_config.c b/udev_config.c index ba2b3d2b88..ae755f39fd 100644 --- a/udev_config.c +++ b/udev_config.c @@ -50,7 +50,6 @@ char default_mode_str[MODE_SIZE]; char default_owner_str[OWNER_SIZE]; char default_group_str[GROUP_SIZE]; int udev_log; -int udev_sleep; int udev_dev_d; @@ -79,11 +78,6 @@ static void init_variables(void) strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); udev_log = string_is_true(UDEV_LOG_DEFAULT); - udev_sleep = 1; - env = getenv("UDEV_NO_SLEEP"); - if (env && string_is_true(env)) - udev_sleep = 0; - udev_dev_d = 1; env = getenv("UDEV_NO_DEVD"); if (env && string_is_true(env)) From a75910b4c071c6033e72e18197284eda0bd08f4a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 14 Oct 2004 20:36:10 -0700 Subject: [PATCH 0905/4284] [PATCH] fix unusual sysfs behavior for pcmcia_socket All files in /sys/class/pcmcia_socket/pcmcia_socket0/* are unreadable without a card inserted: read(3, 0x9167858, 4096) = -1 ENODEV (No such device) So we need to skip that step for now. --- wait_for_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 6f396b96ca..292edfad13 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -60,7 +60,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { .subsystem = "net", .file = "ifindex" }, { .subsystem = "scsi_host", .file = "unique_id" }, { .subsystem = "scsi_device", .file = NULL }, - { .subsystem = "pcmcia_socket", .file = "card_type" }, + { .subsystem = "pcmcia_socket", .file = NULL }, /* all files are unreadable in empty slot :( */ { .subsystem = "usb_host", .file = NULL }, { .subsystem = "bluetooth", .file = "address" }, { .subsystem = "i2c-adapter", .file = NULL }, From 139087e844b5e2a7f029b608db6a855cb2ca1ac3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 14 Oct 2004 20:36:12 -0700 Subject: [PATCH 0906/4284] [PATCH] wait_for_sysfs update for /class/firmware and /class/net/irda devices update for /class/firmware and /class/net/irda devices --- wait_for_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 292edfad13..25a3fb4eef 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -63,6 +63,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { .subsystem = "pcmcia_socket", .file = NULL }, /* all files are unreadable in empty slot :( */ { .subsystem = "usb_host", .file = NULL }, { .subsystem = "bluetooth", .file = "address" }, + { .subsystem = "firmware", .file = "data" }, { .subsystem = "i2c-adapter", .file = NULL }, { .subsystem = "pci_bus", .file = NULL }, { .subsystem = "ieee1394", .file = NULL }, @@ -144,6 +145,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "lo" }, { .subsystem = "net", .device = "tap" }, { .subsystem = "net", .device = "ipsec" }, + { .subsystem = "net", .device = "irda" }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, { .subsystem = "nvidia", .device = NULL }, From 31a6e02871315a298b906b0915c779369dcf3f62 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 17:15:52 -0700 Subject: [PATCH 0907/4284] [PATCH] crap, I messed up the 'sed' instances pretty badly, this fixes the config and man page mess. --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 167c88e55e..fd46a93a41 100644 --- a/Makefile +++ b/Makefile @@ -262,14 +262,14 @@ udev_version.h: @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ # Rules on how to create the generated config files -$(LOCAL_CFG_DIR)/udev.conf: $(HOST_PROGS) - $(QUIET) sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ +$(LOCAL_CFG_DIR)/udev.conf: + sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ GEN_MANPAGES = udev.8 GEN_MANPAGESIN = udev.8.in # Rules on how to create the man pages -$(GEN_MANPAGES): $(GEN_MANPAGESIN) $(HOST_PROGS) - $(QUIET) sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ +$(GEN_MANPAGES): $(GEN_MANPAGESIN) + sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ $(OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) From 92307b9e7bb08e1086d213617df3552e3ff53d75 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Fri, 15 Oct 2004 18:18:54 -0700 Subject: [PATCH 0908/4284] [PATCH] move assignments past local variables I'm using an older C compiler, and it doesn't like assignments mixed with declarations, but this is also a style cleanup. --- udev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/udev.c b/udev.c index d98a017396..b4b08b335b 100644 --- a/udev.c +++ b/udev.c @@ -106,8 +106,6 @@ static int subsystem_without_dev(const char *subsystem) int main(int argc, char *argv[], char *envp[]) { - main_argv = argv; - main_envp = envp; struct sigaction act; char *action; char *devpath = ""; @@ -121,6 +119,9 @@ int main(int argc, char *argv[], char *envp[]) dbg("version %s", UDEV_VERSION); + main_argv = argv; + main_envp = envp; + init_logging("udev"); udev_init_config(); From f837727408d862f0f23fe46f617d2060f0bd3aed Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 18:42:42 -0700 Subject: [PATCH 0909/4284] [PATCH] tweak the ccdv program to handle files in subdirectories being built. --- ccdv.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ccdv.c b/ccdv.c index 069cc461de..e3ae9da91a 100644 --- a/ccdv.c +++ b/ccdv.c @@ -28,12 +28,12 @@ size_t gNBufUsed = 0, gNBufAllocated = 0; char *gBuf = NULL; int gCCPID; -char gAction[64] = ""; -char gTarget[64] = ""; +char gAction[200] = ""; +char gTarget[200] = ""; char gAr[32] = ""; char gArLibraryTarget[64] = ""; int gDumpCmdArgs = 0; -char gArgsStr[800]; +char gArgsStr[1000]; int gColumns = 80; int gANSIEscapes = 0; int gExitStatus = 95; @@ -250,6 +250,7 @@ static const char * Extension(const char *path) cp = strrchr(path, '.'); if (cp == NULL) return (""); + // printf("Extension='%s'\n", cp); return (cp); } /* Extension */ @@ -289,6 +290,7 @@ int main(int argc, char **argv) snprintf(gAction, sizeof(gAction), "Running %s", Basename(argv[1])); memset(gArgsStr, 0, sizeof(gArgsStr)); for (i = 1; i < argc; i++) { + // printf("argv[%d]='%s'\n", i, argv[i]); quote = (strchr(argv[i], ' ') != NULL) ? "\"" : ""; snprintf(gArgsStr + strlen(gArgsStr), sizeof(gArgsStr) - strlen(gArgsStr), "%s%s%s%s%s", (i == 1) ? "" : " ", quote, argv[i], quote, (i == (argc - 1)) ? "\n" : ""); if ((strcmp(argv[i], "-o") == 0) && ((i + 1) < argc)) { @@ -296,11 +298,12 @@ int main(int argc, char **argv) strcpy(gAction, "Linking"); snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i + 1])); } - } else if (strchr("-+/", (int) argv[i][0]) != NULL) { + } else if (strchr("-+", (int) argv[i][0]) != NULL) { continue; } else if (strncasecmp(Extension(argv[i]), ".c", 2) == 0) { cc++; snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); + // printf("gTarget='%s'\n", gTarget); } else if ((strncasecmp(Extension(argv[i]), ".h", 2) == 0) && (cc == 0)) { pch++; snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); From 125930b45492c315f03d4b7a685d129a67338245 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Fri, 15 Oct 2004 18:42:53 -0700 Subject: [PATCH 0910/4284] [PATCH] pass SYSFS setting down for extras builds Modify SYSFS to specify the full path, and pass it down for the extras builds. Change the scsi_id Makefile so it will work with and without udev. --- Makefile | 15 ++++++++------- extras/scsi_id/Makefile | 8 +------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/Makefile b/Makefile index fd46a93a41..890667be9d 100644 --- a/Makefile +++ b/Makefile @@ -183,6 +183,7 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) $(GEN_CONFIGS) echo $$target ; \ $(MAKE) prefix=$(prefix) \ LD="$(LD)" \ + SYSFS="$(SYSFS)" \ KERNEL_DIR="$(KERNEL_DIR)" \ -C $$target $@ ; \ done ; \ @@ -198,13 +199,13 @@ $(CRT0): TDB = tdb/tdb.o \ tdb/spinlock.o -SYSFS = libsysfs/sysfs_bus.o \ - libsysfs/sysfs_class.o \ - libsysfs/sysfs_device.o \ - libsysfs/sysfs_dir.o \ - libsysfs/sysfs_driver.o \ - libsysfs/sysfs_utils.o \ - libsysfs/dlist.o +SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ + $(PWD)/libsysfs/sysfs_class.o \ + $(PWD)/libsysfs/sysfs_device.o \ + $(PWD)/libsysfs/sysfs_dir.o \ + $(PWD)/libsysfs/sysfs_driver.o \ + $(PWD)/libsysfs/sysfs_utils.o \ + $(PWD)/libsysfs/dlist.o OBJS = udev_lib.o \ udev_config.o \ diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 6a73e33785..7ccc4c5118 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -31,14 +31,8 @@ INSTALL_DATA = ${INSTALL} -m 644 override CFLAGS+=-Wall -fno-builtin PROG=scsi_id +SYSFS=-lsysfs -SYSFS = ../../libsysfs/sysfs_bus.o \ - ../../libsysfs/sysfs_class.o \ - ../../libsysfs/sysfs_device.o \ - ../../libsysfs/sysfs_dir.o \ - ../../libsysfs/sysfs_driver.o \ - ../../libsysfs/sysfs_utils.o \ - ../../libsysfs/dlist.o # # Built static and stripped when built with udev. # From 396bb4c3d33dfd68c5817da5e03251fbd82e2713 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 18:49:27 -0700 Subject: [PATCH 0911/4284] [PATCH] let the extras/ programs build "pretty" also --- Makefile | 1 + extras/scsi_id/Makefile | 5 ++++- extras/volume_id/Makefile | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 890667be9d..fffc3c4c15 100644 --- a/Makefile +++ b/Makefile @@ -185,6 +185,7 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) $(GEN_CONFIGS) LD="$(LD)" \ SYSFS="$(SYSFS)" \ KERNEL_DIR="$(KERNEL_DIR)" \ + QUIET="@$(PWD)/ccdv" \ -C $$target $@ ; \ done ; \ diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 7ccc4c5118..2f134bcdbd 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -72,5 +72,8 @@ clean: spotless: clean +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + $(PROG): $(OBJS) - $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 8813f9fca5..d0c6e40fa3 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -49,8 +49,11 @@ HEADERS = volume_id.h dasdlabel.h $(OBJS): $(HEADERS) +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + $(PROG): $(OBJS) $(HEADERS) - $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) clean: rm -f $(PROG) $(OBJS) From 13299c29e7d87d38079fd8a25def44103564d9f4 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 19:18:25 -0700 Subject: [PATCH 0912/4284] [PATCH] add debian config files. taken from latest udev debian package. --- etc/udev/udev.permissions.debian | 121 +++++++++++++++++++++++++++++++ etc/udev/udev.rules.debian | 69 ++++++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 etc/udev/udev.permissions.debian create mode 100644 etc/udev/udev.rules.debian diff --git a/etc/udev/udev.permissions.debian b/etc/udev/udev.permissions.debian new file mode 100644 index 0000000000..6429519eec --- /dev/null +++ b/etc/udev/udev.permissions.debian @@ -0,0 +1,121 @@ +# name:user:group:mode + +# character devices + +ptmx:root:tty:0666 +random:root:root:0666 +urandom:root:root:0444 +kmem:root:kmem:0640 +mem:root:kmem:0640 +port:root:kmem:0640 +null:root:root:0666 +zero:root:root:0666 +full:root:root:0666 + +misc/nvram:root:nvram:660 +nvram:root:nvram:660 +misc/rtc:root:audio:0664 +rtc:root:audio:0664 + +tts/*:root:dialout:0660 +bluetooth/rfcomm/*:root:dialout:0660 +tty[BCDEFHILMPRSTUVWX][0-9]*:root:dialout:0660 +ttyS[ACIR][0-9]*:root:dialout:0660 +ttyUSB[0-9]*:root:dialout:0660 +ttyACM[0-9]*:root:dialout:0660 +ippp[0-9]*:root:dialout:0660 +isdn[0-9]*:root:dialout:0660 +isdnctrl[0-9]*:root:dialout:0660 +capi[0-9.]*:root:dialout:0660 +dcbri[0-9]*:root:dialout:0660 +ircomm[0-9]*:root:dialout:0660 +rfcomm[0-9]*:root:dialout:0660 +tty:root:tty:0666 + +snd/*:root:audio:0660 +sound/*:root:audio:0660 +admmidi*:root:audio:0660 +adsp*:root:audio:0660 +aload*:root:audio:0660 +amidi*:root:audio:0660 +amixer*:root:audio:0660 +audio*:root:audio:0660 +dmfm*:root:audio:0660 +dsp*:root:audio:0660 +audio*:root:audio:0660 +mixer*:root:audio:0660 +music:root:audio:0660 +sequencer*:root:audio:0660 + +printers/*:root:lp:0660 +usb/lp[0-9]*:root:lp:0660 +usb/legousbtower[0-9]*:root:root:666 +lp[0-9]*:root:lp:0660 +parport[0-9]*:root:lp:0660 +irlpt[0-9]*:root:lp:0660 +usblp[0-9]*:root:lp:0660 + +input/mice:root:root:0600 +input/mouse[0-9]*:root:root:0600 +input/js[0-9]*:root:root:0644 +input/*:root:root:0600 +mouse[0-9]*:root:root:0600 +js[0-9]*:root:root:0644 + +dri/card[0-9]*:root:video:0660 +fb/*:root:video:0660 +fb[0-9]*:root:video:0660 +agpgart:root:video:0660 +nvidia*:root:video:0660 + +v4l/*:root:video:0660 +video[0-9]*:root:video:0660 +radio[0-9]*:root:video:0660 +vbi[0-9]*:root:video:0660 +vtx[0-9]*:root:video:0660 +dvb/*:root:video:0660 + +# block devices + +floppy/*:root:floppy:0660 +fd[0-9]*:root:floppy:0660 +cdemu/*:root:cdrom:0660 +pktcdvd[0-9]*:root:cdrom:0660 + +ram[0-9]*:root:disk:0660 +raw/*:root:disk:0660 + +ide/*/cd:root:cdrom:0660 +ide/*:root:disk:0660 +hd[a-s]:root:disk:0660 +hd[a-s][0-9]*:root:disk:0660 + +scsi/*/cd:root:cdrom:0660 +scsi/*:root:disk:0660 +sd[a-z]:root:disk:0660 +sd[a-z][0-9]*:root:disk:0660 +sd[a-i][a-z]:root:disk:0660 +sd[a-i][a-z][0-9]*:root:disk:0660 +s[gr][0-9]*:root:disk:0660 +scd[0-9]*:root:cdrom:0660 + +dasd[0-9]*:root:disk:0660 +ataraid[0-9]*:root:disk:0660 + +loop/*:root:disk:0660 +loop[0-9]*:root:disk:0660 +md/*:root:disk:0660 +md[0-9]*:root:disk:0660 +dm-*:root:disk:0640 + +ht[0-9]*:root:tape:0660 +nht[0-9]*:root:tape:0660 +pt[0-9]*:root:tape:0660 +npt[0-9]*:root:tape:0660 +st[0-9]*:root:tape:0660 +nst[0-9]*:root:tape:0660 + +sgi_fetchop:root:root:666 +iseries/vcd*:root:disk:660 +iseries/vd*:root:disk:660 + diff --git a/etc/udev/udev.rules.debian b/etc/udev/udev.rules.debian new file mode 100644 index 0000000000..cdc0505418 --- /dev/null +++ b/etc/udev/udev.rules.debian @@ -0,0 +1,69 @@ +# 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. (Note, this doesn't work within +# the PROGRAM field for the obvious reason.) +# %s{filename} - the content of a sysfs attribute. +# %% - the '%' char itself. +# + +# /dev/cdrom symlink +BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" + +# permissions for SCSI sg devices +BUS="scsi", KERNEL="s[grt][0-9]*", SYSFS{type}="5", NAME="%k", MODE="0660", GROUP="cdrom" + +# permissions for IDE CD devices +BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", NAME="%k", MODE="0660", GROUP="cdrom" + +# permissions for IDE floppy devices +BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", NAME="%k", MODE="0660", GROUP="floppy" + +# USB devices +BUS="usb", KERNEL="hiddev*", NAME="usb/%k" +BUS="usb", KERNEL="auer*", NAME="usb/%k" +BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" +BUS="usb", KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" + +KERNEL="dvb*", PROGRAM="/etc/udev/dvb.sh %k", NAME="%c" + +KERNEL="card*", NAME="dri/card%n" +KERNEL="cdemu[0-9]*", NAME="cdemu/%n" +KERNEL="cpu[0-9]*", NAME="cpu/%n/cpuid" +KERNEL="msr[0-9]*", NAME="cpu/%n/msr" +KERNEL="microcode", NAME="cpu/microcode" + +# 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[0-9]*", NAME="input/%k" +KERNEL="event[0-9]*", NAME="input/%k", PROGRAM="/etc/udev/inputdev.sh %k", RESULT="inputdev", MODE="0664", GROUP="video" +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" + +KERNEL="tap*", NAME="net/%k" +KERNEL="tun", NAME="net/%k" + +# CAPI devices +KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" +KERNEL="capi[0-9]*", NAME="capi/%n" + +# device mapper creates its own device nodes, so ignore these +KERNEL="dm-[0-9]*", NAME="" +KERNEL="device-mapper", NAME="mapper/control" + From 29afcc5f111f780869a7b091600b106136e11b6d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 19:18:58 -0700 Subject: [PATCH 0913/4284] [PATCH] add some helper scripts for dvb and input devices. --- extras/dvb.sh | 3 +++ extras/inputdev.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 extras/dvb.sh create mode 100644 extras/inputdev.sh diff --git a/extras/dvb.sh b/extras/dvb.sh new file mode 100644 index 0000000000..b14a6d0d7b --- /dev/null +++ b/extras/dvb.sh @@ -0,0 +1,3 @@ +#!/bin/sh -e +echo $1 | sed -e 's#^dvb\([0-9]\)\.\([^0-9]*\)\([0-9]\)#dvb/adapter\1/\2\3#' +exit 0 diff --git a/extras/inputdev.sh b/extras/inputdev.sh new file mode 100644 index 0000000000..82e4fdc374 --- /dev/null +++ b/extras/inputdev.sh @@ -0,0 +1,30 @@ +#!/bin/sh -e +# +# Scans /proc/bus/input/devices for the given device. +# +# (c) 2004 Darren Salt +# GPL v2 or later applies. + +[ "$1" ] || exit 0 + +# input device name, less leading "input/" +DEVICE=${1#input/} + +# "|"-separated list. +# The first found in the given device's "N:" line will be output. +DEFAULT_KEYWORDS='dvb|saa7134' +KEYWORDS=${2:-$DEFAULT_KEYWORDS} + +exec sed -nre ' + /^I:/ { + : gather + N + /\nH:/! b gather + /'"$DEVICE"'/ { + s/^.*\nN:[^\n]*("|\b)('"$KEYWORDS"')("|\b)[^\n]*\n.*$/inputdev/ + T + p + } + } +' < /proc/bus/input/devices + From 79db6912cf8827bf4293d2d15b84cc9633dd7d4e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 19:19:53 -0700 Subject: [PATCH 0914/4284] [PATCH] add very nice cdsymlinks scripts. These are from Darren Salt --- extras/cdsymlinks.c | 532 +++++++++++++++++++++++++++++++++++++++++ extras/cdsymlinks.conf | 12 + extras/cdsymlinks.sh | 184 ++++++++++++++ 3 files changed, 728 insertions(+) create mode 100644 extras/cdsymlinks.c create mode 100644 extras/cdsymlinks.conf create mode 100644 extras/cdsymlinks.sh diff --git a/extras/cdsymlinks.c b/extras/cdsymlinks.c new file mode 100644 index 0000000000..2889ff446c --- /dev/null +++ b/extras/cdsymlinks.c @@ -0,0 +1,532 @@ +/* cdsymlinks.c + * + * Map cdrom, cd-r, cdrw, dvd, dvdrw, dvdram to suitable devices. + * Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices. + * First parameter is the kernel device name. + * Second parameter, if present, must be "-d" => output the full mapping. + * + * Usage: + * BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" + * BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" + * BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" + * (this last one is "just in case") + * + * (c) 2004 Darren Salt + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +static const char *progname; + +/* This file provides us with our devices and capabilities information. */ +#define CDROM_INFO "/proc/sys/dev/cdrom/info" + +/* This file contains our default settings. */ +#define CONFIGURATION "/etc/udev/cdsymlinks.conf" +/* Default output types configuration, in the presence of an empty list */ +#define OUTPUT_DEFAULT "CD CDRW DVD DVDRW DVDRAM" + +static int debug = 0; + +/* List item */ +struct list_item_t { + struct list_item_t *next; + char *data; +}; + +/* List root. Note offset of list_t->head and list_item_t->next */ +struct list_t { + struct list_item_t *head, *tail; +}; + +/* Configuration variables */ +static struct list_t allowed_output = {0}; +static int numbered_links = 1; + +/* Available devices */ +static struct list_t Devices = {0}; + +/* Devices' capabilities in full (same order as available devices list). + * There's no cap_CD; all are assumed able to read CDs. + */ +static struct list_t cap_DVDRAM = {0}, cap_DVDRW = {0}, cap_DVD = {0}, + cap_CDRW = {0}, cap_CDR = {0}, cap_CDWMRW = {0}, + cap_CDMRW = {0}; + +/* Device capabilities by name */ +static struct list_t dev_DVDRAM = {0}, dev_DVDRW = {0}, dev_DVD = {0}, + dev_CDRW = {0}, dev_CDR = {0}, dev_CDWMRW = {0}, + dev_CDMRW = {0}; +#define dev_CD Devices + + +/* + * Some library-like bits first... + */ + +static void +errexit (const char *reason) +{ + fprintf (stderr, "%s: %s: %s\n", progname, reason, strerror (errno)); + exit (2); +} + + +static void +msgexit (const char *reason) +{ + fprintf (stderr, "%s: %s\n", progname, reason); + exit (2); +} + + +static void +errwarn (const char *reason) +{ + fprintf (stderr, "%s: warning: %s: %s\n", progname, reason, strerror (errno)); +} + + +static void +msgwarn (const char *reason) +{ + fprintf (stderr, "%s: warning: %s\n", progname, reason); +} + + +static void * +xmalloc (size_t size) +{ + void *mem = malloc (size); + if (size && !mem) + msgexit ("malloc failed"); + return mem; +} + + +static char * +xstrdup (const char *text) +{ + char *mem = xmalloc (strlen (text) + 1); + return strcpy (mem, text); +} + + +/* Append a string to a list. The string is duplicated. */ +static void +list_append (struct list_t *list, const char *data) +{ + struct list_item_t *node = xmalloc (sizeof (struct list_item_t)); + node->next = NULL; + if (list->tail) + list->tail->next = node; + list->tail = node; + if (!list->head) + list->head = node; + node->data = xstrdup (data); +} + + +/* Prepend a string to a list. The string is duplicated. */ +static void +list_prepend (struct list_t *list, const char *data) +{ + struct list_item_t *node = xmalloc (sizeof (struct list_item_t)); + node->next = list->head; + list->head = node; + if (!list->tail) + list->tail = node; + node->data = xstrdup (data); +} + + +/* Delete a lists's contents, freeing claimed memory */ +static void +list_delete (struct list_t *list) +{ + struct list_item_t *node = list->head; + while (node) + { + struct list_item_t *n = node; + node = node->next; + free (n->data); + free (n); + } + list->tail = list->head = NULL; +} + + +/* Print out a list on one line, each item space-prefixed, no LF */ +static void +list_print (const struct list_t *list, FILE *stream) +{ + const struct list_item_t *node = (const struct list_item_t *)list; + while ((node = node->next) != NULL) + fprintf (stream, " %s", node->data); +} + + +/* Return the nth item in a list (count from 0) + * If there aren't enough items in the list, return the requested default + */ +static const struct list_item_t * +list_nth (const struct list_t *list, size_t nth) +{ + const struct list_item_t *node = list->head; + while (nth && node) + { + node = node->next; + --nth; + } + return node; +} + + +/* Return the first matching item in a list, or NULL */ +static const struct list_item_t * +list_search (const struct list_t *list, const char *data) +{ + const struct list_item_t *node = list->head; + while (node) + { + if (!strcmp (node->data, data)) + return node; + node = node->next; + } + return NULL; +} + + +/* Split up a string on whitespace & assign the resulting tokens to a list. + * Ignore everything up until the first colon (if present). + */ +static void +list_assign_split (struct list_t *list, char *text) +{ + char *token = strchr (text, ':'); + token = strtok (token ? token + 1 : text, " \t"); + while (token) + { + list_prepend (list, token); + token = strtok (0, " \t\n"); + } +} + + + +/* Gather the default settings. */ +static void +read_defaults (void) +{ + FILE *conf = fopen (CONFIGURATION, "r"); + if (!conf) + { + if (errno != ENOENT) + errwarn ("error accessing configuration"); + } + else + { + char *text = NULL; + size_t textlen; + while (getline (&text, &textlen, conf) != -1) + { + wordexp_t p = {0}; + int len = strlen (text); + if (len && text[len - 1] == '\n') + text[--len] = '\0'; + if (len && text[len - 1] == '\r') + text[--len] = '\0'; + if (!len) + continue; + char *token = text + strspn (text, " \t"); + if (!*token || *token == '#') + continue; + switch (len = wordexp (text, &p, 0)) + { + case WRDE_NOSPACE: + msgexit ("malloc failed"); + case 0: + if (p.we_wordc == 1) + { + if (!strncmp (p.we_wordv[0], "OUTPUT=", 7)) + { + list_delete (&allowed_output); + list_assign_split (&allowed_output, p.we_wordv[0] + 7); + } + else if (!strncmp (p.we_wordv[0], "NUMBERED_LINKS=", 14)) + numbered_links = atoi (p.we_wordv[0] + 14); + break; + } + /* fall through */ + default: + msgwarn ("syntax error in configuration file"); + } + wordfree (&p); + } + if (!feof (conf)) + errwarn ("error accessing configuration"); + if (fclose (conf)) + errwarn ("error accessing configuration"); + free (text); + } + if (!allowed_output.head) + { + char *dflt = strdup (OUTPUT_DEFAULT); + list_assign_split (&allowed_output, dflt); + free (dflt); + } +} + + +/* From information supplied by the kernel: + * + get the names of the available devices + * + populate our capability lists + * Order is significant: device item N maps to each capability item N. + */ +static void +populate_capability_lists (void) +{ + FILE *info = fopen (CDROM_INFO, "r"); + if (!info) + { + if (errno == ENOENT) + exit (0); + errexit ("error accessing CD/DVD info"); + } + + char *text = 0; + size_t textlen = 0; + + while (getline (&text, &textlen, info) != -1) + { + if (!strncasecmp (text, "drive name", 10)) + list_assign_split (&Devices, text); + else if (!strncasecmp (text, "Can write DVD-RAM", 17)) + list_assign_split (&cap_DVDRAM, text); + else if (!strncasecmp (text, "Can write DVD-R", 15)) + list_assign_split (&cap_DVDRW, text); + else if (!strncasecmp (text, "Can read DVD", 12)) + list_assign_split (&cap_DVD, text); + else if (!strncasecmp (text, "Can write CD-RW", 15)) + list_assign_split (&cap_CDRW, text); + else if (!strncasecmp (text, "Can write CD-R", 14)) + list_assign_split (&cap_CDR, text); + else if (!strncasecmp (text, "Can read MRW", 14)) + list_assign_split (&cap_CDMRW, text); + else if (!strncasecmp (text, "Can write MRW", 14)) + list_assign_split (&cap_CDWMRW, text); + } + if (!feof (info)) + errexit ("error accessing CD/DVD info"); + fclose (info); + free (text); +} + + +/* Write out the links of type LINK which should be created for device NAME, + * taking into account existing links and the capability list for type LINK. + */ +static void +do_output (const char *name, const char *link, const struct list_t *dev) +{ + const struct list_item_t *i = (const struct list_item_t *)dev; + if (!i->next) + return; + + errno = 0; + + size_t link_len = strlen (link); + DIR *dir = opendir ("/dev"); + if (!dir) + errexit ("error reading /dev"); + + struct list_t devls = {0}; /* symlinks whose name matches LINK */ + struct list_t devlinks = {0}; /* those symlinks' targets */ + struct dirent *entry; + while ((entry = readdir (dir)) != NULL) + { + if (strncmp (entry->d_name, link, link_len)) + continue; /* wrong name: ignore it */ + + /* The rest of the name must be null or consist entirely of digits. */ + const char *p = entry->d_name + link_len - 1; + while (*++p) + if (!isdigit (*p)) + break; + if (*p) + continue; /* wrong format - ignore */ + + /* Assume that it's a symlink and try to read its target. */ + char buf[sizeof (entry->d_name)]; + int r = readlink (entry->d_name, buf, sizeof (buf) - 1); + if (r < 0) + { + if (errno == EINVAL) + continue; /* not a symlink - ignore */ + errexit ("error reading link in /dev"); + } + /* We have the name and the target, so update our lists. */ + buf[r] = 0; + list_append (&devls, entry->d_name); + list_append (&devlinks, buf); + } + if (errno) + errexit ("error reading /dev"); + if (closedir (dir)) + errexit ("error closing /dev"); + + /* Now we write our output... */ + size_t count = 0; + while ((i = i->next) != NULL) + { + int isdev = !strcmp (name, i->data); /* current dev == target dev? */ + int present = 0; + size_t li = -1; + const struct list_item_t *l = (const struct list_item_t *)&devlinks; + + /* First, we look for existing symlinks to the target device. */ + while (++li, (l = l->next) != NULL) + { + if (strcmp (l->data, i->data)) + continue; + /* Existing symlink found - don't output a new one. + * If ISDEV, we output the name of the existing symlink. + */ + present = 1; + if (isdev) + printf (" %s", list_nth (&devls, li)->data); + } + + /* If we found no existing symlinks for the target device... */ + if (!present) + { + char buf[256]; + snprintf (buf, sizeof (buf), count ? "%s%d" : "%s", link, count); + /* Find the next available (not present) symlink name. + * We always need to do this for reasons of output consistency: if a + * symlink is created by udev as a result of use of this program, we + * DON'T want different output! + */ + while (list_search (&devls, buf)) + snprintf (buf, sizeof (buf), "%s%d", link, ++count); + /* If ISDEV, output it. */ + if (isdev && (numbered_links || count == 0)) + printf (" %s", buf); + /* If the link isn't in our "existing links" list, add it and increment + * our counter. + */ + if (!list_search (&devls, buf)) + { + list_append (&devls, buf); + ++count; + } + } + } + + list_delete (&devls); + list_delete (&devlinks); +} + + +/* Populate a device list from a capabilities list. */ +static void +populate_device_list (struct list_t *out, const struct list_t *caps) +{ + const struct list_item_t *cap, *dev; + cap = (const struct list_item_t *)caps; + dev = (const struct list_item_t *)&Devices; + while ((cap = cap->next) != NULL && (dev = dev->next) != NULL) + if (cap->data[0] != '0') + list_append (out, dev->data); +} + + +int +main (int argc, char *argv[]) +{ + progname = argv[0]; + debug = argc > 2 && !strcmp (argv[2], "-d"); + + if (argc < 2 || argc > 2 + debug) + msgexit ("usage: cdsymlinks DEVICE [-d]"); + + if (chdir ("/dev")) + errexit ("can't chdir /dev"); + + read_defaults (); + populate_capability_lists (); + + /* Construct the device lists from the capability lists. */ + populate_device_list (&dev_DVDRAM, &cap_DVDRAM); + populate_device_list (&dev_DVDRW, &cap_DVDRW); + populate_device_list (&dev_DVD, &cap_DVD); + populate_device_list (&dev_CDRW, &cap_CDRW); + populate_device_list (&dev_CDR, &cap_CDR); + populate_device_list (&dev_CDWMRW, &cap_CDWMRW); + populate_device_list (&dev_CDMRW, &cap_CDMRW); + /* (All devices can read CDs.) */ + + if (debug) + { +#define printdev(DEV) \ + printf ("%-7s:", #DEV); \ + list_print (&cap_##DEV, stdout); \ + list_print (&dev_##DEV, stdout); \ + puts (""); + + printf ("Devices:"); + const struct list_item_t *item = (const struct list_item_t *)&Devices; + while ((item = item->next) != NULL) + printf (" %s", item->data); + puts (""); + + printdev (DVDRAM); + printdev (DVDRW); + printdev (DVD); + printdev (CDRW); + printdev (CDR); + printdev (CDWMRW); + printdev (CDMRW); + + printf ("CDROM : (all)"); + item = (const struct list_item_t *)&dev_CD; + while ((item = item->next) != NULL) + printf (" %s", item->data); + puts (""); + } + + /* Write the symlink names. */ + if (list_search (&allowed_output, "CD")) + do_output (argv[1], "cdrom", &dev_CD); + if (list_search (&allowed_output, "CDR")) + do_output (argv[1], "cd-r", &dev_CDR); + if (list_search (&allowed_output, "CDRW")) + do_output (argv[1], "cdrw", &dev_CDRW); + if (list_search (&allowed_output, "DVD")) + do_output (argv[1], "dvd", &dev_DVD); + if (list_search (&allowed_output, "DVDRW")) + do_output (argv[1], "dvdrw", &dev_DVDRW); + if (list_search (&allowed_output, "DVDRAM")) + do_output (argv[1], "dvdram", &dev_DVDRAM); + if (list_search (&allowed_output, "CDMRW")) + do_output (argv[1], "cdmrw", &dev_CDMRW); + if (list_search (&allowed_output, "CDWMRW")) + do_output (argv[1], "cdwmrw", &dev_CDWMRW); + puts (""); + + return 0; +} diff --git a/extras/cdsymlinks.conf b/extras/cdsymlinks.conf new file mode 100644 index 0000000000..e50a2e6082 --- /dev/null +++ b/extras/cdsymlinks.conf @@ -0,0 +1,12 @@ +# Configuration file for cdsymlinks + +# Output links for these types of devices. +# Allowed keywords are CD, CDR, CDRW, DVD, DVDRW, DVDRAM, CDMRW, CDWMRW. +# Other words are accepted but ignored. +#OUTPUT="CD CDRW DVD DVDRW DVDRAM" + +# Whether to output numbered links. +# 1 = output 'cdrom1', 'dvd1' etc. for other devices +# 0 = don't output 'cdrom1', 'dvd1' etc. +# We always output 'cdrom', 'dvd' etc. for the best-match devices. +#NUMBERED_LINKS=1 diff --git a/extras/cdsymlinks.sh b/extras/cdsymlinks.sh new file mode 100644 index 0000000000..e99be2e544 --- /dev/null +++ b/extras/cdsymlinks.sh @@ -0,0 +1,184 @@ +#! /bin/sh -e +# +# Map cdrom, cdm, cdmrw, cd-r, cdrw, dvd, dvdrw, dvdram to suitable devices. +# Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices. +# First parameter is the kernel device name. +# Second parameter, if present, must be "-d" => output the full mapping. +# +# Usage: +# BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +# BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +# BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +# (this last one is "just in case") +# +# (c) 2004 Darren Salt + +test -e /proc/sys/dev/cdrom/info || exit 0 + +# Defaults; it's better that you alter them in /etc/udev/cdsymlinks.conf +OUTPUT='CD CDRW DVD DVDRW DVDRAM' +NUMBERED_LINKS=1 + +test -e /etc/udev/cdsymlinks.conf && . /etc/udev/cdsymlinks.conf + +DEBUG='' +test "$2" = '-d' && DEBUG=1 + + +# Array emulation. 'setArray FOO a b c' gives FOO=3 FOO_1=a FOO_2=b FOO_3=c +setArray () { + local _ARRAY=$1 + local _INDEX=0 + shift + while test $# -ne 0; do + eval ${_ARRAY}_$_INDEX="$1" + _INDEX=$(($_INDEX+1)) + shift + done + eval $_ARRAY=$_INDEX +} + +ix () { eval echo -n \$$1_$2; } +ixs () { eval $1_$2="$3"; } + +# Args: variable, value +# Returns true if value is not in variable (a whitespace-separated list) +notin () { + test "$2" = '' && return 0 + local i + for i in `eval echo '$'$1`; do + test "$i" != "$2" || return 1 + done +} + + +# Scan /proc/sys/dev/cdrom/info for details on the present devices +setArray DEVICES `sed -re '/^drive name:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray DVDRAMs `sed -re '/^Can write DVD-RAM:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray DVDRWs `sed -re '/^Can write DVD-R:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray DVDs `sed -re '/^Can read DVD:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray CDRWs `sed -re '/^Can write CD-RW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray CDRs `sed -re '/^Can write CD-R:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray CDMRWs `sed -re '/^Can write MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray CDMs `sed -re '/^Can read MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` + +# How many devices do we have? +NumDevs=$(($DEVICES-1)) +Count='' +i=-1 +while test $i -ne $NumDevs; do + i=$(($i+1)); + Count="$i${Count:+ }$Count"; +done + +# Fill in any missing capabilities information (assume not capable) +for i in $Count; do + test "`ix DVDRAMs $i`" != '' || ixs DVDRAMs $i 0 + test "`ix DVDRWs $i`" != '' || ixs DVDRWs $i 0 + test "`ix DVDs $i`" != '' || ixs DVDs $i 0 + test "`ix CDRWs $i`" != '' || ixs CDRWs $i 0 + test "`ix CDRs $i`" != '' || ixs CDRs $i 0 + test "`ix CDMRWs $i`" != '' || ixs CDMRWs $i 0 + test "`ix CDMs $i`" != '' || ixs CDMs $i 0 +done + +DVDRAM='' +DVDRW='' +DVD='' +CDRW='' +CDR='' +CDMRW='' +CDM='' +CD='' + +# Calculate symlink->device mappings. +# We need to be careful about how we assign mappings because we want +# read-only devices to have /dev/cdrom and /dev/dvd. +# Hot-plugged CD/DVD devices may well cause this scheme some problems. +for i in $Count; do + test "`ix DVDRAMs $i`" = 1 && DVDRAM="$DVDRAM `ix DEVICES $i`" +done +for i in $Count; do + test "`ix DVDRWs $i`" = 1 && DVDRW="$DVDRW `ix DEVICES $i`" +done +for i in $Count; do + test "`ix DVDs $i`" = 1 && DVD="$DVD `ix DEVICES $i`" +done +for i in $Count; do + test "`ix CDRWs $i`" = 1 && CDRW="$CDRW `ix DEVICES $i`" +done +for i in $Count; do + test "`ix CDRs $i`" = 1 && CDR="$CDR `ix DEVICES $i`" +done +for i in $Count; do + test "`ix CDMRWs $i`" = 1 && CDMRW="$CDMRW `ix DEVICES $i`" +done +for i in $Count; do + test "`ix CDMs $i`" = 1 && CDM="$CDM `ix DEVICES $i`" +done +for i in $Count; do + CD="$CD `ix DEVICES $i`" +done + +# Debug output +if test "$DEBUG" = 1; then + echo 'Devices:' `for i in $Count; do ix DEVICES $i; echo -n \ ; done` + echo 'DVDRAM :' `for i in $Count; do ix DVDRAMs $i; echo -n \ ; done` $DVDRAM + echo 'DVDRW :' `for i in $Count; do ix DVDRWs $i; echo -n \ ; done` $DVDRW + echo 'DVD :' `for i in $Count; do ix DVDs $i; echo -n \ ; done` $DVD + echo 'CDRW :' `for i in $Count; do ix CDRWs $i; echo -n \ ; done` $CDRW + echo 'CD-R :' `for i in $Count; do ix CDRs $i; echo -n \ ; done` $CDR + echo 'CDMRW :' `for i in $Count; do ix CDMRWs $i; echo -n \ ; done` $CDMRW + echo 'CDM :' `for i in $Count; do ix CDMs $i; echo -n \ ; done` $CDM + echo 'CDROM : (all)' $CD +fi + +# Prepare symlink names output +output () { + test "`eval echo '$'$3`" = '' && return + local i + local COUNT='' + local DEVLS="`ls -dl \"/dev/$2\" \"/dev/$2\"[0-9]* 2>/dev/null`" + local PRESENT="`echo "$DEVLS" | + sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> [^[:space:]]+$!\1!'`" + for i in `eval echo '$'$3`; do + # First, we look for existing symlinks to the target device. + local DEVPRESENT="`echo "$DEVLS" | + sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> '$i'$!\1!; t X; d; :X'`" + if test "$DEVPRESENT" != ""; then + # Existing symlinks found - don't output a new one. + # If the target dev ($1) is the current dev ($i), we output their names. + test "$1" = "$i" && echo " $DEVPRESENT" | sed -e 'N; $ s/\n/ /' + else + # If we found no existing symlinks for the target device... + # Find the next available (not present) symlink name. + # We always need to do this for reasons of output consistency: if a + # symlink is created by udev as a result of use of this program, we + # DON'T want different output! + until notin PRESENT "$2$COUNT"; do + COUNT=$(($COUNT+1)) + done + # If the target dev ($1) is the current dev ($i), we output its name. + if test $(($NUMBERED_LINKS)) -ne 0 || test "$COUNT" -eq 0; then + test "$i" = "$1" && echo -n " $2$COUNT" + fi + # If the link isn't in our "existing links" list, add it and increment + # our counter. + if test ! -e "/dev/$2$COUNT"; then + PRESENT="$PRESENT\n$2$COUNT" + COUNT=$(($COUNT+1)) + fi + fi + done +} + +# And output it +notin OUTPUT CD || echo -n "`output "$1" cdrom CD`" +notin OUTPUT CDMRW || echo -n "`output "$1" cdmrw CDM`" +notin OUTPUT CDWMRW || echo -n "`output "$1" cdwmrw CDMRW`" +notin OUTPUT CDR || echo -n "`output "$1" cd-r CDR`" +notin OUTPUT CDRW || echo -n "`output "$1" cdrw CDRW`" +notin OUTPUT DVD || echo -n "`output "$1" dvd DVD`" +notin OUTPUT DVDRW || echo -n "`output "$1" dvdrw DVDRW`" +notin OUTPUT DVDRAM || echo -n "`output "$1" dvdram DVDRAM`" +echo From 1946fec4deba1ea5505c286ef2dd4ff2c6863b1c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 15 Oct 2004 19:45:56 -0700 Subject: [PATCH 0915/4284] [PATCH] swich attribute open() to simple stat() Here we switch to a simple stat() to recognize the file creation. This will make it possible to wait for files, which are unreadable. I've switched the timout back to 5 seconds cause the our /class/vc errors seems like a bug in the vc layer not a sysfs delay. --- wait_for_sysfs.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 25a3fb4eef..72368efac8 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -47,7 +47,7 @@ void log_message(int level, const char *format, ...) } #endif -#define WAIT_MAX_SECONDS 10 +#define WAIT_MAX_SECONDS 5 #define WAIT_LOOP_PER_SECOND 20 /* wait for specific file to show up, normally the "dev"-file */ @@ -60,7 +60,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { .subsystem = "net", .file = "ifindex" }, { .subsystem = "scsi_host", .file = "unique_id" }, { .subsystem = "scsi_device", .file = NULL }, - { .subsystem = "pcmcia_socket", .file = NULL }, /* all files are unreadable in empty slot :( */ + { .subsystem = "pcmcia_socket", .file = "card_type" }, { .subsystem = "usb_host", .file = NULL }, { .subsystem = "bluetooth", .file = "address" }, { .subsystem = "firmware", .file = "data" }, @@ -86,11 +86,14 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev break; } } - dbg("looking at class '%s' for specific file '%s'", class_dev->classname, file); + + dbg("looking at class '%s' for specific file '%s'", class_dev->classname, class_dev->path); loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { - if (sysfs_get_classdev_attr(class_dev, file) != NULL) { + struct stat stats; + + if (stat(class_dev->path, &stats) == 0) { dbg("class '%s' specific file '%s' found", class_dev->classname, file); return 0; } From 052de0cec6cb3d92befd3d2de3e9e69e5f097a26 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 22:38:46 -0700 Subject: [PATCH 0916/4284] [PATCH] take out & from wait_for_sysfs_test that I previously missed. --- test/wait_for_sysfs_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/wait_for_sysfs_test.sh b/test/wait_for_sysfs_test.sh index f299d23c94..659d99a9fe 100644 --- a/test/wait_for_sysfs_test.sh +++ b/test/wait_for_sysfs_test.sh @@ -13,7 +13,7 @@ run_udev () { for i in ${SYSFS_DIR}/block/*; do # add each drive export DEVPATH=${i#${SYSFS_DIR}} - $UDEV_BIN block & + $UDEV_BIN block # add each partition, on each device for j in $i/*; do From a8f2703adaf21620bb92c04d3b8371f228cd11d2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 22:54:12 -0700 Subject: [PATCH 0917/4284] [PATCH] Hopefully fix the vcs issue in wait_for_sysfs --- wait_for_sysfs.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 72368efac8..d775eb1c95 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -6,6 +6,7 @@ * directories and then just exit. * * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2004 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 @@ -35,6 +36,10 @@ #include "udev_version.h" #include "libsysfs/sysfs/libsysfs.h" +#ifndef FILENAME_MAX +#define FILENAME_MAX 4096 +#endif + #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) @@ -73,6 +78,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev }; struct class_file *classfile; const char *file = "dev"; + char filename[FILENAME_MAX]; int loop; /* look if we want to look for another file instead of "dev" */ @@ -87,13 +93,21 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev } } - dbg("looking at class '%s' for specific file '%s'", class_dev->classname, class_dev->path); + strcpy(filename, class_dev->path); + strcat(filename, "/"); + strcat(filename, file); + dbg("looking at class '%s' for specific file '%s' with full name %s", class_dev->classname, class_dev->path, filename); loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { struct stat stats; - if (stat(class_dev->path, &stats) == 0) { + if (stat(class_dev->path, &stats) == -1) { + dbg("oops, the directory '%s' just disappeared.", class_dev->path); + return -ENODEV; + } + + if (stat(filename, &stats) == 0) { dbg("class '%s' specific file '%s' found", class_dev->classname, file); return 0; } @@ -102,7 +116,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev } dbg("error: getting class '%s' specific file '%s'", class_dev->classname, file); - return -1; + return -ENOENT; } /* check if we need to wait for a physical device */ @@ -284,6 +298,7 @@ int main(int argc, char *argv[], char *envp[]) struct sysfs_class_device *class_dev_parent; struct sysfs_device *device_dev = NULL; int loop; + int retval; int rc = 0; init_logging("wait_for_sysfs"); @@ -335,7 +350,10 @@ int main(int argc, char *argv[], char *envp[]) } dbg("class_device opened '%s'", filename); - if (wait_for_class_device_attributes(class_dev) != 0) { + retval = wait_for_class_device_attributes(class_dev); + if (retval == -ENODEV) + goto exit_class; + if (retval != 0) { rc = 4; goto exit_class; } From b337e60790382589e8e9f088f0ff41a496a85615 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Fri, 15 Oct 2004 23:04:44 -0700 Subject: [PATCH 0918/4284] [PATCH] update udev to scsi_id 0.7 Update udev's scsi_id to version 0.7, this fixes a bad bug in scsi_id on 64 bit systems. --- extras/scsi_id/ChangeLog | 6 ++++++ extras/scsi_id/Makefile | 2 +- extras/scsi_id/release-notes | 17 +++++++---------- extras/scsi_id/scsi_id.c | 3 ++- 4 files changed, 16 insertions(+), 12 deletions(-) diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog index 724977dbf4..d2a8be5b18 100644 --- a/extras/scsi_id/ChangeLog +++ b/extras/scsi_id/ChangeLog @@ -1,3 +1,9 @@ +2004-oct-15: + * Makefile: Add $(QUIET) to sync with the udev version. + +2004-oct-06: + * scsi_id.c: fix alignment for use with 64 bit pointers + 2004-jul-30: * scsi_id.c, scsi_serial.c: Align the buffer passed to scsi_serial, don't bother aligning and memcpy-ing the result in scsi_inquiry. diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 2f134bcdbd..610faac4b7 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.6 +SCSI_ID_VERSION=0.7 prefix = etcdir = ${prefix}/etc diff --git a/extras/scsi_id/release-notes b/extras/scsi_id/release-notes index 302817ea7f..c7ea51679c 100644 --- a/extras/scsi_id/release-notes +++ b/extras/scsi_id/release-notes @@ -1,6 +1,6 @@ -Version 0.6 of scsi_id is available at: +Version 0.7 of scsi_id is available at: -http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.6.tar.gz +http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.7.tar.gz scsi_id is a program to generate a unique identifier for a given SCSI device. @@ -14,13 +14,10 @@ Requires: - Linux kernel 2.6 - libsysfs 0.4.0 -Major changes since the last release: +Changes since the last release: - - add -u option, patch from Christoph Varoqui, to substitute white - space with underscores so it is easier to use the output as a - device name. + - Fix a bug introduced in version 0.6 so that buffer alignement + works on 64 bit systems. Without this fix, it crashes on 64 bit + systems. - - Use 254 bytes for SCSI INQUIRY commands, patch from Hannes - Reinecke. - -See ChangeLog for more details. + - Add $(QUIET) to sync up with the udev Makefile diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 6395b822ce..d2155e6866 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -713,7 +713,8 @@ static int scsi_id(const char *target_path, char *maj_min_dev) #define ALIGN 512 unaligned_buf = malloc(MAX_SERIAL_LEN + ALIGN); - serial = (char*) (((int) unaligned_buf + (ALIGN - 1)) & ~(ALIGN - 1)); + serial = (char*) (((unsigned long) unaligned_buf + (ALIGN - 1)) + & ~(ALIGN - 1)); dprintf("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial); #undef ALIGN From 4a330247992f9a558dc3f906be139ff8deddfdc2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 15 Oct 2004 23:08:08 -0700 Subject: [PATCH 0919/4284] [PATCH] 039 release --- ChangeLog | 28 ++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0c190852d8..ca7532a3fb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,31 @@ +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 ============================================ diff --git a/Makefile b/Makefile index fffc3c4c15..11f4781e0e 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart WAIT = wait_for_sysfs -VERSION = 038 +VERSION = 039 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index cb0686ea2b..44164124ed 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 038 +Version: 039 Release: 1 License: GPL Group: Utilities/System From dcb9c852f563ce8c38c3558f8462be2d324c8de7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 18:13:13 -0700 Subject: [PATCH 0920/4284] [PATCH] Fix wait_for_sysfs messages (more debugging info) On Sat, Oct 16, 2004 at 02:48:42PM -0400, Jeff wrote: > Kay Sievers wrote: > >On Sat, Oct 16, 2004 at 04:40:51AM +0200, Kay Sievers wrote: > > > >Here is a better version. We return successful in the case, that the > >advertised device does not appear within the timeout or goes completely > >away while waiting for the attributes. All magic numbers should be > >readable as a string now. > > > >This hopefully fixes the last vc errors. > > > K, first patch produced a couple of device unavailables & a slew of no > device symlinks. Second patch-no messages at all :) > > Thank god, if I have to reboot again I'm going to puke. Nice to hear that we covered all the vc errors now. I think we should apply the same logic to the /devices device wait loops, as they may go with a remove event too. Here is the 3rd version of the patch :) --- wait_for_sysfs.c | 248 +++++++++++++++++++++++++++-------------------- 1 file changed, 141 insertions(+), 107 deletions(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index d775eb1c95..aac42e2421 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -56,7 +56,8 @@ void log_message(int level, const char *format, ...) #define WAIT_LOOP_PER_SECOND 20 /* wait for specific file to show up, normally the "dev"-file */ -static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev) +static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev, + const char **error) { static struct class_file { char *subsystem; @@ -77,7 +78,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev { NULL, NULL } }; struct class_file *classfile; - const char *file = "dev"; + char *file = "dev"; char filename[FILENAME_MAX]; int loop; @@ -103,11 +104,11 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev struct stat stats; if (stat(class_dev->path, &stats) == -1) { - dbg("oops, the directory '%s' just disappeared.", class_dev->path); + dbg("'%s' now disappeared (probably remove has beaten us)", class_dev->path); return -ENODEV; } - if (stat(filename, &stats) == 0) { + if (stat(filename, &stats) == 0) { dbg("class '%s' specific file '%s' found", class_dev->classname, file); return 0; } @@ -116,6 +117,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev } dbg("error: getting class '%s' specific file '%s'", class_dev->classname, file); + *error = "class specific file unavailable"; return -ENOENT; } @@ -226,7 +228,8 @@ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) } /* wait for the bus and for a bus specific file to show up */ -static int wait_for_bus_device(struct sysfs_device *device_dev) +static int wait_for_bus_device(struct sysfs_device *devices_dev, + const char **error) { static struct bus_file { char *bus; @@ -246,19 +249,20 @@ static int wait_for_bus_device(struct sysfs_device *device_dev) struct bus_file *busfile; int loop; - /* wait for the /bus-device link to the /device-device */ + /* wait for the bus device link to the devices device */ loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { - if (sysfs_get_device_bus(device_dev) == 0) + if (sysfs_get_device_bus(devices_dev) == 0) break; usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } if (loop == 0) { - dbg("error: getting /bus-device link"); + dbg("error: getting bus device link"); + *error = "no bus device link"; return -1; } - dbg("/bus-device link found for bus '%s'", device_dev->bus); + dbg("bus device link found for bus '%s'", devices_dev->bus); /* wait for a bus specific file to show up */ loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; @@ -266,27 +270,115 @@ static int wait_for_bus_device(struct sysfs_device *device_dev) int found = 0; for (busfile = bus_files; busfile->bus != NULL; busfile++) { - if (strcmp(device_dev->bus, busfile->bus) == 0) { + if (strcmp(devices_dev->bus, busfile->bus) == 0) { found = 1; - dbg("looking at bus '%s' for specific file '%s'", device_dev->bus, busfile->file); - if (sysfs_get_device_attr(device_dev, busfile->file) != NULL) { - dbg("bus '%s' specific file '%s' found", device_dev->bus, busfile->file); + dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, busfile->file); + if (sysfs_get_device_attr(devices_dev, busfile->file) != NULL) { + dbg("bus '%s' specific file '%s' found", devices_dev->bus, busfile->file); return 0; } } } if (found == 0) { + *error = "unknown bus"; info("error: unknown bus, please report to " - " '%s'", device_dev->bus); + " '%s'", devices_dev->bus); return -1; } usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } - dbg("error: getting bus '%s' specific file '%s'", device_dev->bus, busfile->file); + dbg("error: getting bus '%s' specific file '%s'", devices_dev->bus, busfile->file); + *error = "bus specific file unavailable"; return -1; } + +static struct sysfs_class_device *open_class_device(const char *path) +{ + struct sysfs_class_device *class_dev; + int loop; + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + class_dev = sysfs_open_class_device_path(path); + if (class_dev) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + + return (class_dev); +} + +static int wait_for_class_device(struct sysfs_class_device *class_dev, + const char **error) +{ + struct sysfs_class_device *class_dev_parent; + struct sysfs_device *devices_dev = NULL; + int loop; + + if (wait_for_class_device_attributes(class_dev, error) != 0) + return -ENOENT; + + /* skip devices without devices-link */ + if (class_device_expect_no_device_link(class_dev)) { + dbg("no device symlink expected for '%s', ", class_dev->name); + return -ENODEV; + } + + /* the symlink may be on the parent device */ + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent) + dbg("looking at parent device for device link '%s'", class_dev_parent->path); + + /* wait for the symlink to the devices device */ + dbg("waiting for symlink to devices device"); + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + if (class_dev_parent) + devices_dev = sysfs_get_classdev_device(class_dev_parent); + else + devices_dev = sysfs_get_classdev_device(class_dev); + + if (devices_dev) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + if (!devices_dev) { + dbg(" error: no devices device symlink found"); + *error = "no device symlink"; + return -ENODEV; + } + dbg("device symlink found pointing to '%s'", devices_dev->path); + + /* wait for the bus value */ + if (class_device_expect_no_bus(class_dev)) { + dbg("no bus device expected for '%s', ", class_dev->classname); + return 0; + } else { + return wait_for_bus_device(devices_dev, error); + } +} + +static struct sysfs_device *open_devices_device(const char *path) +{ + struct sysfs_device *devices_dev; + int loop; + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + devices_dev = sysfs_open_device_path(path); + if (devices_dev) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + + return(devices_dev); +} + int main(int argc, char *argv[], char *envp[]) { const char *devpath = ""; @@ -295,11 +387,9 @@ int main(int argc, char *argv[], char *envp[]) char sysfs_path[SYSFS_PATH_MAX]; char filename[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev; - struct sysfs_class_device *class_dev_parent; - struct sysfs_device *device_dev = NULL; - int loop; - int retval; + struct sysfs_device *devices_dev; int rc = 0; + const char *error = NULL; init_logging("wait_for_sysfs"); @@ -312,133 +402,77 @@ int main(int argc, char *argv[], char *envp[]) devpath = getenv ("DEVPATH"); if (!devpath) { dbg("error: no DEVPATH"); - return 1; + rc = 1; + goto exit; } action = getenv ("ACTION"); if (!action) { dbg("error: no ACTION"); - return 1; + rc = 1; + goto exit; } /* we only wait on an add event */ - if (strcmp(action, "add") != 0) - return 0; + if (strcmp(action, "add") != 0) { + dbg("no add ACTION"); + goto exit; + } if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { dbg("error: no sysfs path"); - return 2; + rc = 2; + goto exit; } if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) { - /* open the class device we are called for */ snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); filename[SYSFS_PATH_MAX-1] = '\0'; - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - class_dev = sysfs_open_class_device_path(filename); - if (class_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - if (class_dev == NULL) { - dbg("error: getting class_device"); - rc = 3; + /* open the class device we are called for */ + class_dev = open_class_device(filename); + if (!class_dev) { + dbg("error: class device unavailable (probably remove has beaten us)"); goto exit; } - dbg("class_device opened '%s'", filename); + dbg("class device opened '%s'", filename); - retval = wait_for_class_device_attributes(class_dev); - if (retval == -ENODEV) - goto exit_class; - if (retval != 0) { - rc = 4; - goto exit_class; - } + /* wait for the class device with possible physical device and bus */ + wait_for_class_device(class_dev, &error); - /* skip devices without /device-link */ - if (class_device_expect_no_device_link(class_dev)) { - dbg("no device symlink expected for '%s', ", class_dev->name); - goto exit_class; - } - - /* the symlink may be on the parent device */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent) - dbg("looking at parent device for device link '%s'", class_dev_parent->path); - - /* wait for the symlink to the /device-device */ - dbg("waiting for symlink to /device-device"); - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - if (class_dev_parent) - device_dev = sysfs_get_classdev_device(class_dev_parent); - else - device_dev = sysfs_get_classdev_device(class_dev); - - if (device_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - if (device_dev == NULL) { - dbg("error: getting /device-device"); - rc = 5; - goto exit_class; - } - dbg("device symlink found pointing to '%s'", device_dev->path); - - /* wait for the bus value */ - if (class_device_expect_no_bus(class_dev)) { - dbg("no bus device expected for '%s', ", class_dev->classname); - } else { - if (wait_for_bus_device(device_dev) != 0) - rc = 6; - } - -exit_class: sysfs_close_class_device(class_dev); } else if ((strncmp(devpath, "/devices/", 9) == 0)) { - /* open the path we are called for */ snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); filename[SYSFS_PATH_MAX-1] = '\0'; - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - device_dev = sysfs_open_device_path(filename); - if (device_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - if (device_dev == NULL) { - dbg("error: getting /device-device"); - rc = 7; + /* open the path we are called for */ + devices_dev = open_devices_device(filename); + if (!devices_dev) { + dbg("error: devices device unavailable (probably remove has beaten us)"); goto exit; } - dbg("device_device opened '%s'", filename); + dbg("devices device opened '%s'", filename); /* wait for the bus value */ - if (wait_for_bus_device(device_dev) != 0) - rc = 8; + wait_for_bus_device(devices_dev, &error); - sysfs_close_device(device_dev); + sysfs_close_device(devices_dev); } else { dbg("unhandled sysfs path, no need to wait"); } exit: - if (rc == 0) - dbg("result: waiting for sysfs successful '%s'", devpath); - else + if (error) { info("either wait_for_sysfs (udev %s) needs an update to handle the device '%s' " - "properly (%d) or the sysfs-support of your device's driver needs to be fixed, " + "properly (%s) or the sysfs-support of your device's driver needs to be fixed, " "please report to ", - UDEV_VERSION, devpath, rc); + UDEV_VERSION, devpath, error); + rc =3; + } else { + dbg("result: waiting for sysfs successful '%s'", devpath); + } - return rc; + exit(rc); } From 0f634c33d7eb634737915dc1aa3b7d7342d1a5f2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 18:13:40 -0700 Subject: [PATCH 0921/4284] [PATCH] Fix ppp net devices in wait_for_sysfs On Sat, Oct 16, 2004 at 10:32:47AM -0500, Jason Dravet wrote: > FYI > > wait_for_sysfs[2986]: either wait_for_sysfs (udev 038) needs an update to > handle the device '/class/ppp/ppp' properly (5) or the sysfs-support of > your device's driver needs to be fixed, please report to > > > I am running udev 38-2 and ppp-2.4.2-6.3 Yeah, the ppp-class is missing, we only covered the net ppp-devices. --- wait_for_sysfs.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index aac42e2421..1d7044c61f 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -160,11 +160,12 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "msr", .device = NULL }, { .subsystem = "netlink", .device = NULL }, { .subsystem = "net", .device = "sit" }, - { .subsystem = "net", .device = "ppp" }, { .subsystem = "net", .device = "lo" }, { .subsystem = "net", .device = "tap" }, { .subsystem = "net", .device = "ipsec" }, { .subsystem = "net", .device = "irda" }, + { .subsystem = "net", .device = "ppp" }, + { .subsystem = "ppp", .device = NULL }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, { .subsystem = "nvidia", .device = NULL }, From 7257cb18458e6b51cc9655887b7f9745f704b71f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 18:15:10 -0700 Subject: [PATCH 0922/4284] [PATCH] close the syslog Seems that we never closed the opened syslog. Here is a patch to do this in all our binaries. --- logging.h | 13 ++++++++++--- udev.c | 3 ++- udevd.c | 5 +++-- udevinfo.c | 12 ++++++------ udevsend.c | 4 +++- wait_for_sysfs.c | 3 ++- 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/logging.h b/logging.h index 40c342c3ab..30f52c84ce 100644 --- a/logging.h +++ b/logging.h @@ -27,7 +27,8 @@ #define info(format, arg...) do { } while (0) #define dbg(format, arg...) do { } while (0) #define dbg_parse(format, arg...) do { } while (0) -#define init_logging(foo) do { } while (0) +#define logging_init(foo) do { } while (0) +#define logging_close(foo) do { } while (0) #ifdef LOG #include @@ -65,13 +66,19 @@ extern void log_message(int level, const char *format, ...) /* each program that uses syslog must declare this variable somewhere */ extern unsigned char logname[LOGNAME_SIZE]; -#undef init_logging -static inline void init_logging(char *program_name) +#undef logging_init +static inline void logging_init(char *program_name) { snprintf(logname, LOGNAME_SIZE,"%s[%d]", program_name, getpid()); openlog(logname, 0, LOG_DAEMON); } +#undef logging_close +static inline void logging_close(void) +{ + closelog(); +} + #endif /* LOG */ #endif diff --git a/udev.c b/udev.c index b4b08b335b..10a937e472 100644 --- a/udev.c +++ b/udev.c @@ -122,7 +122,7 @@ int main(int argc, char *argv[], char *envp[]) main_argv = argv; main_envp = envp; - init_logging("udev"); + logging_init("udev"); udev_init_config(); @@ -203,5 +203,6 @@ int main(int argc, char *argv[], char *envp[]) udevdb_exit(); exit: + logging_close(); return retval; } diff --git a/udevd.c b/udevd.c index 811f62243e..421c25a6e8 100644 --- a/udevd.c +++ b/udevd.c @@ -150,7 +150,7 @@ static void udev_run(struct hotplug_msg *msg) /* child */ execle(udev_bin, "udev", msg->subsystem, NULL, env); dbg("exec of child failed"); - exit(1); + _exit(1); break; case -1: dbg("fork of child failed"); @@ -403,7 +403,7 @@ int main(int argc, char *argv[]) struct sigaction act; fd_set readfds; - init_logging("udevd"); + logging_init("udevd"); dbg("version %s", UDEV_VERSION); if (getuid() != 0) { @@ -549,5 +549,6 @@ int main(int argc, char *argv[]) } exit: close(ssock); + logging_close(); exit(1); } diff --git a/udevinfo.c b/udevinfo.c index 8329fe7d06..763cfd139f 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -447,18 +447,18 @@ help: int main(int argc, char *argv[], char *envp[]) { - int retval; + int rc = 0; main_argv = argv; main_argc = argc; - init_logging("udevinfo"); + logging_init("udevinfo"); /* initialize our configuration */ udev_init_config(); - retval = process_options(); - if (retval != 0) - exit(1); - exit(0); + rc = process_options(); + + logging_close(); + exit(rc); } diff --git a/udevsend.c b/udevsend.c index 23ba1a1b00..883181c1b6 100644 --- a/udevsend.c +++ b/udevsend.c @@ -123,7 +123,7 @@ int main(int argc, char* argv[]) socklen_t addrlen; int started_daemon = 0; - init_logging("udevsend"); + logging_init("udevsend"); dbg("version %s", UDEV_VERSION); subsystem = get_subsystem(argv[1]); @@ -215,5 +215,7 @@ exit: if (sock != -1) close(sock); + logging_close(); + return retval; } diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 1d7044c61f..37de02261d 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -392,7 +392,7 @@ int main(int argc, char *argv[], char *envp[]) int rc = 0; const char *error = NULL; - init_logging("wait_for_sysfs"); + logging_init("wait_for_sysfs"); if (argc != 2) { dbg("error: subsystem"); @@ -475,5 +475,6 @@ exit: dbg("result: waiting for sysfs successful '%s'", devpath); } + logging_close(); exit(rc); } From 74d2a1d53024d10145dc1e9e5e6124d9d14e9fbe Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 18:16:12 -0700 Subject: [PATCH 0923/4284] [PATCH] don't wait for dummy devices No need to wait for dummy net devices. --- wait_for_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 37de02261d..8f142f488b 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -163,6 +163,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "lo" }, { .subsystem = "net", .device = "tap" }, { .subsystem = "net", .device = "ipsec" }, + { .subsystem = "net", .device = "dummy" }, { .subsystem = "net", .device = "irda" }, { .subsystem = "net", .device = "ppp" }, { .subsystem = "ppp", .device = NULL }, From 8e0871196c916be60a9d0327ce8483c4f9763c17 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 18 Oct 2004 19:04:20 -0700 Subject: [PATCH 0924/4284] [PATCH] fix up the wait_for_sysfs_test script a bit. We also emit the same things the -mm tree does now, so to make that easier to test for. --- test/wait_for_sysfs_test.sh | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/wait_for_sysfs_test.sh b/test/wait_for_sysfs_test.sh index 659d99a9fe..9b80a42271 100644 --- a/test/wait_for_sysfs_test.sh +++ b/test/wait_for_sysfs_test.sh @@ -1,4 +1,4 @@ -#! /bin/sh +#! /bin/bash # # Check for missing binaries (stale symlinks should not happen) @@ -25,13 +25,17 @@ run_udev () { done # all other device classes for i in ${SYSFS_DIR}/class/*; do - for j in $i/*; do -# if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFS_DIR}} - CLASS=`echo ${i#${SYSFS_DIR}} | \ - cut --delimiter='/' --fields=3-` - $UDEV_BIN $CLASS -# fi + # try adding empty classes, just to test stuff... + export DEVPATH=${i#${SYSFS_DIR}} + CLASS=`echo ${i#${SYSFS_DIR}} | cut --delimiter='/' --fields=3-` + $UDEV_BIN $CLASS + + for j in `ls $i/`; do + x=$i/$j + export DEVPATH=${x#${SYSFS_DIR}} + CLASS=`echo ${i#${SYSFS_DIR}} | \ + cut --delimiter='/' --fields=3-` + $UDEV_BIN $CLASS done done } From 7a947ce51586fd4212447643df90580542777ab9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 19:11:51 -0700 Subject: [PATCH 0925/4284] [PATCH] big cleanup of internal udev api Here is the first patch to cleanup the internal processing of the various stages of an udev event. It should not change any behavior, but if your system depends on udev, please always test it before reboot :) We pass only one generic structure around between add, remove, namedev, db and dev_d handling and make all relevant data available to all internal stages. All udev structures are renamed to "udev". We replace the fake parameter by a flag in the udev structure. We open the class device in the main binaries and not in udev_add, to make it possible to use libsysfs for udevstart directory crawling. The last sleep parameters are removed. --- dev_d.c | 18 +++--- extras/start_udev | 1 - namedev.c | 5 +- namedev.h | 2 +- test/udev-test.pl | 1 - udev.c | 40 +++++++++---- udev.h | 18 +++--- udev_add.c | 140 ++++++++++++++++++---------------------------- udev_lib.c | 9 ++- udev_lib.h | 2 + udev_remove.c | 39 +++++++------ udevdb.c | 36 ++++++------ udevdb.h | 4 +- udevinfo.c | 2 +- udevstart.c | 28 +++++++--- udevtest.c | 22 ++++++-- 16 files changed, 193 insertions(+), 174 deletions(-) diff --git a/dev_d.c b/dev_d.c index eaf9b1dc12..5580b5a362 100644 --- a/dev_d.c +++ b/dev_d.c @@ -80,7 +80,7 @@ static int run_program(char *name) * subsystem/ * default/ */ -void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath) +void dev_d_send(struct udevice *udev) { char dirname[256]; char env_devname[NAME_SIZE]; @@ -91,17 +91,17 @@ void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath) return; memset(env_devname, 0x00, sizeof(env_devname)); - if (dev->type == 'b' || dev->type == 'c') { + if (udev->type == 'b' || udev->type == 'c') { strfieldcpy(env_devname, udev_root); - strfieldcat(env_devname, dev->name); - } else if (dev->type == 'n') { - strfieldcpy(env_devname, dev->name); - setenv("DEVPATH", devpath, 1); + strfieldcat(env_devname, udev->name); + } else if (udev->type == 'n') { + strfieldcpy(env_devname, udev->name); + setenv("DEVPATH", udev->devpath, 1); } setenv("DEVNAME", env_devname, 1); dbg("DEVNAME='%s'", env_devname); - devname = strdup(dev->name); + devname = strdup(udev->name); if (!devname) { dbg("out of memory"); return; @@ -121,11 +121,11 @@ void dev_d_send(struct udevice *dev, const char *subsystem, const char *devpath) } strcpy(dirname, DEVD_DIR); - strfieldcat(dirname, dev->name); + strfieldcat(dirname, udev->name); call_foreach_file(run_program, dirname, DEVD_SUFFIX); strcpy(dirname, DEVD_DIR); - strfieldcat(dirname, subsystem); + strfieldcat(dirname, udev->subsystem); call_foreach_file(run_program, dirname, DEVD_SUFFIX); strcpy(dirname, DEVD_DIR "default"); diff --git a/extras/start_udev b/extras/start_udev index bbf32a1bb9..c2518761e3 100644 --- a/extras/start_udev +++ b/extras/start_udev @@ -30,7 +30,6 @@ udevd=/sbin/udevd run_udev () { export ACTION=add - export UDEV_NO_SLEEP=1 # handle block devices and their partitions for i in ${sysfs_dir}/block/*; do diff --git a/namedev.c b/namedev.c index 39f033726c..03fc41d234 100644 --- a/namedev.c +++ b/namedev.c @@ -692,7 +692,7 @@ try_parent: } -int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *udev) +int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev) { struct sysfs_class_device *class_dev_parent; struct sysfs_device *sysfs_device = NULL; @@ -718,9 +718,10 @@ int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *ud } if (sysfs_device) { - dbg("found /device-device: path='%s', bus_id='%s', bus='%s'", + dbg("found devices device: path='%s', bus_id='%s', bus='%s'", sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus); strfieldcpy(udev->bus_id, sysfs_device->bus_id); + strfieldcpy(udev->bus, sysfs_device->bus); } strfieldcpy(udev->kernel_name, class_dev->name); diff --git a/namedev.h b/namedev.h index fa924b14d9..f1e0082241 100644 --- a/namedev.h +++ b/namedev.h @@ -102,7 +102,7 @@ extern struct list_head config_device_list; extern struct list_head perm_device_list; extern int namedev_init(void); -extern int namedev_name_device(struct sysfs_class_device *class_dev, struct udevice *dev); +extern int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev); extern int namedev_init_permissions(void); extern int namedev_init_rules(void); diff --git a/test/udev-test.pl b/test/udev-test.pl index 9e4e192c51..a7becf99df 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1100,7 +1100,6 @@ EOF $ENV{UDEV_TEST} = "yes"; $ENV{SYSFS_PATH} = $sysfs; $ENV{UDEV_CONFIG_FILE} = $main_conf; -$ENV{UDEV_NO_SLEEP} = "yes"; $ENV{UDEV_NO_DEVD} = "yes"; diff --git a/udev.c b/udev.c index 10a937e472..8d5be0542e 100644 --- a/udev.c +++ b/udev.c @@ -107,9 +107,9 @@ static int subsystem_without_dev(const char *subsystem) int main(int argc, char *argv[], char *envp[]) { struct sigaction act; - char *action; - char *devpath = ""; - char *subsystem = ""; + struct sysfs_class_device *class_dev; + struct udevice udev; + char path[SYSFS_PATH_MAX]; int retval = -EINVAL; enum { ADD, @@ -129,7 +129,10 @@ int main(int argc, char *argv[], char *envp[]) if (strstr(argv[0], "udevstart")) { act_type = UDEVSTART; } else { - action = get_action(); + const char *action = get_action(); + const char *devpath = get_devpath(); + const char *subsystem = get_subsystem(main_argv[1]); + if (!action) { dbg("no action?"); goto exit; @@ -139,16 +142,15 @@ int main(int argc, char *argv[], char *envp[]) } else if (strcmp(action, "remove") == 0) { act_type = REMOVE; } else { - dbg("unknown action '%s'", action); + dbg("no action '%s' for us", action); goto exit; } - devpath = get_devpath(); if (!devpath) { dbg("no devpath?"); goto exit; } - dbg("looking at '%s'", devpath); + dbg("looking at '%s'", udev.devpath); /* we only care about class devices and block stuff */ if (!strstr(devpath, "class") && !strstr(devpath, "block")) { @@ -156,17 +158,18 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - subsystem = get_subsystem(main_argv[1]); if (!subsystem) { - dbg("no subsystem?"); + dbg("no subsystem"); goto exit; } /* skip blacklisted subsystems */ if (subsystem_without_dev(subsystem)) { dbg("don't care about '%s' devices", subsystem); - exit(0); + goto exit; }; + + udev_set_values(&udev, devpath, subsystem); } /* set signal handlers */ @@ -192,12 +195,25 @@ int main(int argc, char *argv[], char *envp[]) break; case ADD: dbg("udev add"); + + /* init rules */ namedev_init(); - retval = udev_add_device(devpath, subsystem, NOFAKE); + + /* open the device */ + snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); + class_dev = sysfs_open_class_device_path(path); + if (class_dev == NULL) { + dbg ("sysfs_open_class_device_path failed"); + break; + } + dbg("opened class_dev->name='%s'", class_dev->name); + + /* name, create node, store in db */ + retval = udev_add_device(&udev, class_dev); break; case REMOVE: dbg("udev remove"); - retval = udev_remove_device(devpath, subsystem); + retval = udev_remove_device(&udev); } udevdb_exit(); diff --git a/udev.h b/udev.h index 642b30b517..70de729f30 100644 --- a/udev.h +++ b/udev.h @@ -41,11 +41,8 @@ #define LINE_SIZE 256 -#define FAKE 1 -#define NOFAKE 0 - /* length of public data to store in udevdb */ -#define UDEVICE_LEN (offsetof(struct udevice, bus_id)) +#define UDEVICE_DB_LEN (offsetof(struct udevice, devpath)) struct udevice { char name[NAME_SIZE]; @@ -61,20 +58,23 @@ struct udevice { char config_file[NAME_SIZE]; long config_uptime; - /* private data that help us in building strings */ + /* private data, not stored in udevdb */ + char devpath[DEVPATH_SIZE]; + char subsystem[SUBSYSTEM_SIZE]; char bus_id[SYSFS_NAME_LEN]; + char bus[SYSFS_NAME_LEN]; char program_result[NAME_SIZE]; char kernel_number[NAME_SIZE]; char kernel_name[NAME_SIZE]; + int test_run; }; -extern int udev_add_device(const char *path, const char *subsystem, int fake); -extern int udev_remove_device(const char *path, const char *subsystem); +extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev); +extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); extern int parse_get_pair(char **orig_string, char **left, char **right); -extern void dev_d_send(struct udevice *dev, const char *subsystem, - const char *devpath); +extern void dev_d_send(struct udevice *udev); extern char **main_argv; extern char **main_envp; diff --git a/udev_add.c b/udev_add.c index 08257609ad..d07120de62 100644 --- a/udev_add.c +++ b/udev_add.c @@ -186,7 +186,7 @@ static void set_to_local_user(char *user) endutent(); } -static int create_node(struct udevice *dev, int fake) +static int create_node(struct udevice *udev) { char filename[NAME_SIZE]; char linkname[NAME_SIZE]; @@ -200,90 +200,89 @@ static int create_node(struct udevice *dev, int fake) int len; strfieldcpy(filename, udev_root); - strfieldcat(filename, dev->name); + strfieldcat(filename, udev->name); - switch (dev->type) { + switch (udev->type) { case 'b': - dev->mode |= S_IFBLK; + udev->mode |= S_IFBLK; break; case 'c': case 'u': - dev->mode |= S_IFCHR; + udev->mode |= S_IFCHR; break; case 'p': - dev->mode |= S_IFIFO; + udev->mode |= S_IFIFO; break; default: - dbg("unknown node type %c\n", dev->type); + dbg("unknown node type %c\n", udev->type); return -EINVAL; } /* create parent directories if needed */ - if (strrchr(dev->name, '/')) + if (strrchr(udev->name, '/')) create_path(filename); - if (dev->owner[0] != '\0') { + if (udev->owner[0] != '\0') { char *endptr; - unsigned long id = strtoul(dev->owner, &endptr, 10); + unsigned long id = strtoul(udev->owner, &endptr, 10); if (endptr[0] == '\0') uid = (uid_t) id; else { struct passwd *pw; - if (strncmp(dev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0) - set_to_local_user(dev->owner); + if (strncmp(udev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0) + set_to_local_user(udev->owner); - pw = getpwnam(dev->owner); + pw = getpwnam(udev->owner); if (pw == NULL) - dbg("specified user unknown '%s'", dev->owner); + dbg("specified user unknown '%s'", udev->owner); else uid = pw->pw_uid; } } - if (dev->group[0] != '\0') { + if (udev->group[0] != '\0') { char *endptr; - unsigned long id = strtoul(dev->group, &endptr, 10); + unsigned long id = strtoul(udev->group, &endptr, 10); if (endptr[0] == '\0') gid = (gid_t) id; else { - struct group *gr = getgrnam(dev->group); + struct group *gr = getgrnam(udev->group); if (gr == NULL) - dbg("specified group unknown '%s'", dev->group); + dbg("specified group unknown '%s'", udev->group); else gid = gr->gr_gid; } } - if (!fake) { + if (!udev->test_run) { info("creating device node '%s'", filename); - if (make_node(filename, dev->major, dev->minor, dev->mode, uid, gid) != 0) + if (make_node(filename, udev->major, udev->minor, udev->mode, uid, gid) != 0) goto error; } else { info("creating device node '%s', major = '%d', minor = '%d', " "mode = '%#o', uid = '%d', gid = '%d'", filename, - dev->major, dev->minor, (mode_t)dev->mode, uid, gid); + udev->major, udev->minor, (mode_t)udev->mode, uid, gid); } /* create all_partitions if requested */ - if (dev->partitions > 0) { - info("creating device partition nodes '%s[1-%i]'", filename, dev->partitions); - if (!fake) { - for (i = 1; i <= dev->partitions; i++) { + if (udev->partitions > 0) { + info("creating device partition nodes '%s[1-%i]'", filename, udev->partitions); + if (!udev->test_run) { + for (i = 1; i <= udev->partitions; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); - make_node(partitionname, dev->major, - dev->minor + i, dev->mode, uid, gid); + make_node(partitionname, udev->major, udev->minor + i, udev->mode, uid, gid); } } } /* create symlink(s) if requested */ - foreach_strpart(dev->symlink, " ", pos, len) { + foreach_strpart(udev->symlink, " ", pos, len) { strfieldcpymax(linkname, pos, len+1); strfieldcpy(filename, udev_root); strfieldcat(filename, linkname); - dbg("symlink '%s' to node '%s' requested", filename, dev->name); - if (!fake) + dbg("symlink '%s' to node '%s' requested", filename, udev->name); + if (!udev->test_run) if (strrchr(linkname, '/')) create_path(filename); @@ -291,8 +290,8 @@ static int create_node(struct udevice *dev, int fake) linktarget[0] = '\0'; i = 0; tail = 0; - while ((dev->name[i] == linkname[i]) && dev->name[i]) { - if (dev->name[i] == '/') + while ((udev->name[i] == linkname[i]) && udev->name[i]) { + if (udev->name[i] == '/') tail = i+1; i++; } @@ -302,10 +301,10 @@ static int create_node(struct udevice *dev, int fake) i++; } - strfieldcat(linktarget, &dev->name[tail]); + strfieldcat(linktarget, &udev->name[tail]); dbg("symlink(%s, %s)", linktarget, filename); - if (!fake) { + if (!udev->test_run) { selinux_setfscreatecon(filename, S_IFLNK); unlink(filename); if (symlink(linktarget, filename) != 0) @@ -319,35 +318,14 @@ error: return -1; } -static struct sysfs_class_device *get_class_dev(const char *device_name) -{ - char dev_path[SYSFS_PATH_MAX]; - struct sysfs_class_device *class_dev = NULL; - - strfieldcpy(dev_path, sysfs_path); - strfieldcat(dev_path, device_name); - dbg("looking at '%s'", dev_path); - - /* open up the sysfs class device for this thing... */ - class_dev = sysfs_open_class_device_path(dev_path); - if (class_dev == NULL) { - dbg ("sysfs_open_class_device_path failed"); - goto exit; - } - dbg("class_dev->name='%s'", class_dev->name); - -exit: - return class_dev; -} - -static int rename_net_if(struct udevice *dev, int fake) +static int rename_net_if(struct udevice *udev) { int sk; struct ifreq ifr; int retval; - dbg("changing net interface name from '%s' to '%s'", dev->kernel_name, dev->name); - if (fake) + dbg("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name); + if (udev->test_run) return 0; sk = socket(PF_INET, SOCK_DGRAM, 0); @@ -357,8 +335,8 @@ static int rename_net_if(struct udevice *dev, int fake) } memset(&ifr, 0x00, sizeof(struct ifreq)); - strfieldcpy(ifr.ifr_name, dev->kernel_name); - strfieldcpy(ifr.ifr_newname, dev->name); + strfieldcpy(ifr.ifr_name, udev->kernel_name); + strfieldcpy(ifr.ifr_newname, udev->name); retval = ioctl(sk, SIOCSIFNAME, &ifr); if (retval != 0) @@ -368,69 +346,57 @@ static int rename_net_if(struct udevice *dev, int fake) return retval; } -int udev_add_device(const char *path, const char *subsystem, int fake) +int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) { - struct sysfs_class_device *class_dev; - struct udevice dev; - char devpath[DEVPATH_SIZE]; char *pos; int retval = 0; - memset(&dev, 0x00, sizeof(dev)); - - dev.type = get_device_type(path, subsystem); - - class_dev = get_class_dev(path); - if (class_dev == NULL) - return -1; - - if (dev.type == 'b' || dev.type == 'c') { - retval = get_major_minor(class_dev, &dev); + if (udev->type == 'b' || udev->type == 'c') { + retval = get_major_minor(class_dev, udev); if (retval != 0) { dbg("no dev-file found, do nothing"); goto close; } } - if (namedev_name_device(class_dev, &dev) != 0) + if (namedev_name_device(udev, class_dev) != 0) goto exit; - dbg("name='%s'", dev.name); + dbg("adding name='%s'", udev->name); selinux_init(); - switch (dev.type) { + switch (udev->type) { case 'b': case 'c': - retval = create_node(&dev, fake); + retval = create_node(udev); if (retval != 0) goto exit; - if ((!fake) && (udevdb_add_dev(path, &dev) != 0)) + if ((!udev->test_run) && (udevdb_add_dev(udev) != 0)) dbg("udevdb_add_dev failed, but we are going to try " "to create the node anyway. But remove might not " "work properly for this device."); - dev_d_send(&dev, subsystem, path); + dev_d_send(udev); break; case 'n': - strfieldcpy(devpath, path); - if (strcmp(dev.name, dev.kernel_name) != 0) { - retval = rename_net_if(&dev, fake); + if (strcmp(udev->name, udev->kernel_name) != 0) { + retval = rename_net_if(udev); if (retval != 0) goto exit; /* netif's are keyed with the configured name, cause * the original kernel name sleeps with the fishes */ - pos = strrchr(devpath, '/'); + pos = strrchr(udev->devpath, '/'); if (pos != NULL) { pos[1] = '\0'; - strfieldcat(devpath, dev.name); + strfieldcat(udev->devpath, udev->name); } } - if ((!fake) && (udevdb_add_dev(devpath, &dev) != 0)) + if ((!udev->test_run) && (udevdb_add_dev(udev) != 0)) dbg("udevdb_add_dev failed"); - dev_d_send(&dev, subsystem, devpath); + dev_d_send(udev); break; } diff --git a/udev_lib.c b/udev_lib.c index 4991ec3acb..bd3eeba661 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -29,7 +29,6 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "logging.h" #include "udev_lib.h" @@ -113,6 +112,14 @@ char get_device_type(const char *path, const char *subsystem) return '\0'; } +void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem) +{ + memset(udev, 0x00, sizeof(struct udevice)); + strfieldcpy(udev->devpath, devpath); + strfieldcpy(udev->subsystem, subsystem); + udev->type = get_device_type(devpath, subsystem); +} + int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; diff --git a/udev_lib.h b/udev_lib.h index e9ff379fc6..8a14ef00b6 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -22,6 +22,7 @@ #ifndef _UDEV_LIB_H_ #define _UDEV_LIB_H_ +#include "udev.h" #define strfieldcpy(to, from) \ do { \ @@ -81,6 +82,7 @@ extern char *get_devname(void); extern char *get_seqnum(void); extern char *get_subsystem(char *subsystem); extern char get_device_type(const char *path, const char *subsystem); +extern void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); diff --git a/udev_remove.c b/udev_remove.c index d4be8bd6f9..d97a2411f4 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -161,35 +162,37 @@ static int delete_node(struct udevice *dev) } /* - * Look up the sysfs path in the database to see if we have named this device - * something different from the kernel name. If we have, us it. If not, use - * the default kernel name for lack of anything else to know to do. + * look up the sysfs path in the database to get the node name to remove + * If we can't find it, use kernel name for lack of anything else to know to do */ -int udev_remove_device(const char *path, const char *subsystem) +int udev_remove_device(struct udevice *udev) { - struct udevice dev; + struct udevice db_dev; char *temp; int retval; - memset(&dev, 0x00, sizeof(dev)); + memset(&db_dev, 0x00, sizeof(struct udevice)); - retval = udevdb_get_dev(path, &dev); - if (retval != 0) { - dbg("'%s' not found in database, falling back on default name", path); - temp = strrchr(path, '/'); + retval = udevdb_get_dev(udev->devpath, &db_dev); + if (retval == 0) { + /* get stored values in our device */ + memcpy(udev, &db_dev, UDEVICE_DB_LEN); + } else { + /* fall back to kernel name */ + temp = strrchr(udev->devpath, '/'); if (temp == NULL) return -ENODEV; - strfieldcpy(dev.name, &temp[1]); + strfieldcpy(udev->name, &temp[1]); + dbg("'%s' not found in database, falling back on default name", udev->name); } - dbg("name='%s'", dev.name); + dbg("remove name='%s'", udev->name); - dev.type = get_device_type(path, subsystem); - dev_d_send(&dev, subsystem, path); - udevdb_delete_dev(path); + dev_d_send(udev); + udevdb_delete_dev(udev->devpath); - if (dev.type == 'b' || dev.type == 'c') - retval = delete_node(&dev); - else if (dev.type == 'n') + if (udev->type == 'b' || udev->type == 'c') + retval = delete_node(udev); + else retval = 0; return retval; diff --git a/udevdb.c b/udevdb.c index a218b66179..3d0a9ea3c2 100644 --- a/udevdb.c +++ b/udevdb.c @@ -44,7 +44,7 @@ static TDB_CONTEXT *udevdb; sig_atomic_t gotalarm; -int udevdb_add_dev(const char *path, const struct udevice *dev) +int udevdb_add_dev(struct udevice *udev) { TDB_DATA key, data; char keystr[SYSFS_PATH_MAX]; @@ -52,22 +52,19 @@ int udevdb_add_dev(const char *path, const struct udevice *dev) if (udevdb == NULL) return -1; - if ((path == NULL) || (dev == NULL)) - return -ENODEV; - - memset(keystr, 0, SYSFS_PATH_MAX); - strfieldcpy(keystr, path); + memset(keystr, 0x00, SYSFS_PATH_MAX); + strfieldcpy(keystr, udev->devpath); key.dptr = keystr; key.dsize = strlen(keystr) + 1; - data.dptr = (void *)dev; - data.dsize = UDEVICE_LEN; - dbg("store key '%s' for device '%s'", path, dev->name); + data.dptr = (void *) udev; + data.dsize = UDEVICE_DB_LEN; + dbg("store key '%s' for device '%s'", keystr, udev->name); return tdb_store(udevdb, key, data, TDB_REPLACE); } -int udevdb_get_dev(const char *path, struct udevice *dev) +int udevdb_get_dev(const char *path, struct udevice *udev) { TDB_DATA key, data; @@ -84,8 +81,9 @@ int udevdb_get_dev(const char *path, struct udevice *dev) if (data.dptr == NULL || data.dsize == 0) return -ENODEV; - memset(dev, 0, sizeof(struct udevice)); - memcpy(dev, data.dptr, UDEVICE_LEN); + memset(udev, 0x00, sizeof(struct udevice)); + memcpy(udev, data.dptr, UDEVICE_DB_LEN); + return 0; } @@ -156,7 +154,7 @@ int udevdb_open_ro(void) return 0; } -static int (*user_record_callback) (char *path, struct udevice *dev); +static int (*user_record_callback) (const char *path, struct udevice *dev); static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) { @@ -167,7 +165,7 @@ static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void * udevdb_call_foreach: dumps whole database by passing record data to user function * @user_record_handler: user function called for every record in the database */ -int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev)) +int udevdb_call_foreach(int (*user_record_handler) (const char *path, struct udevice *dev)) { int retval = 0; @@ -191,27 +189,27 @@ static char *find_path; static const char *find_name; static int find_found; -static int find_device_by_name(char *path, struct udevice *dev) +static int find_device_by_name(const char *path, struct udevice *udev) { char *pos; int len; - if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { - memcpy(find_dev, dev, sizeof(struct udevice)); + if (strncmp(udev->name, find_name, sizeof(udev->name)) == 0) { + memcpy(find_dev, udev, sizeof(struct udevice)); strfieldcpymax(find_path, path, NAME_SIZE); find_found = 1; /* stop search */ return 1; } /* look for matching symlink*/ - foreach_strpart(dev->symlink, " ", pos, len) { + foreach_strpart(udev->symlink, " ", pos, len) { if (strncmp(pos, find_name, len) != 0) continue; if (len != strlen(find_name)) continue; - memcpy(find_dev, dev, sizeof(struct udevice)); + memcpy(find_dev, udev, sizeof(struct udevice)); strfieldcpymax(find_path, path, NAME_SIZE); find_found = 1; return 1; diff --git a/udevdb.h b/udevdb.h index 6eaeb25668..6986a0a113 100644 --- a/udevdb.h +++ b/udevdb.h @@ -12,9 +12,9 @@ extern void udevdb_exit(void); extern int udevdb_init(int init_flag); extern int udevdb_open_ro(void); -extern int udevdb_call_foreach(int (*user_record_handler) (char *path, struct udevice *dev)); +extern int udevdb_call_foreach(int (*user_record_handler) (const char *path, struct udevice *dev)); -extern int udevdb_add_dev(const char *path, const struct udevice *dev); +extern int udevdb_add_dev(struct udevice *dev); extern int udevdb_get_dev(const char *path, struct udevice *dev); extern int udevdb_delete_dev(const char *path); extern int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev); diff --git a/udevinfo.c b/udevinfo.c index 763cfd139f..af2346c8f5 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -104,7 +104,7 @@ exit: } /* callback for database dump */ -static int print_record(char *path, struct udevice *dev) +static int print_record(const char *path, struct udevice *dev) { printf("P: %s\n", path); printf("N: %s\n", dev->name); diff --git a/udevstart.c b/udevstart.c index cabafb0abc..c4ec0f7b7a 100644 --- a/udevstart.c +++ b/udevstart.c @@ -33,6 +33,7 @@ #include #include +#include "libsysfs/sysfs/libsysfs.h" #include "logging.h" #include "udev_lib.h" #include "list.h" @@ -86,19 +87,32 @@ static char *first_list[] = { NULL, }; -static void add_device(char *path, char *subsys, int fake) +static int add_device(char *devpath, char *subsystem) { + struct udevice udev; + char path[SYSFS_PATH_MAX]; + struct sysfs_class_device *class_dev; char *argv[3]; /* fake argument vector and environment for callouts and dev.d/ */ argv[0] = "udev"; - argv[1] = subsys; + argv[1] = subsystem; argv[2] = NULL; main_argv = argv; - setenv("DEVPATH", path, 1); + setenv("DEVPATH", devpath, 1); setenv("ACTION", "add", 1); - udev_add_device(path, subsys, fake); + + snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath); + class_dev = sysfs_open_class_device_path(path); + if (class_dev == NULL) { + dbg ("sysfs_open_class_device_path failed"); + return -ENODEV; + } + + udev_set_values(&udev, devpath, subsystem); + + return udev_add_device(&udev, class_dev); } static void exec_list(struct list_head *device_list) @@ -111,7 +125,7 @@ static void exec_list(struct list_head *device_list) list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { for (i=0; first_list[i] != NULL; i++) { if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) { - add_device(loop_device->path, loop_device->subsys, NOFAKE); + add_device(loop_device->path, loop_device->subsys); list_del(&loop_device->list); free(loop_device); break; @@ -131,14 +145,14 @@ static void exec_list(struct list_head *device_list) if (found) continue; - add_device(loop_device->path, loop_device->subsys, NOFAKE); + add_device(loop_device->path, loop_device->subsys); list_del(&loop_device->list); free(loop_device); } /* handle the rest of the devices left over, if any */ list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { - add_device(loop_device->path, loop_device->subsys, NOFAKE); + add_device(loop_device->path, loop_device->subsys); list_del(&loop_device->list); free(loop_device); } diff --git a/udevtest.c b/udevtest.c index df882d2d8c..fa1629af25 100644 --- a/udevtest.c +++ b/udevtest.c @@ -55,9 +55,12 @@ void log_message (int level, const char *format, ...) int main(int argc, char *argv[], char *envp[]) { + struct sysfs_class_device *class_dev; char *devpath; + char path[SYSFS_PATH_MAX]; char temp[NAME_SIZE]; char *subsystem = ""; + struct udevice udev; main_argv = argv; main_envp = envp; @@ -88,9 +91,8 @@ int main(int argc, char *argv[], char *envp[]) info("looking at '%s'", devpath); /* we only care about class devices and block stuff */ - if (!strstr(devpath, "class") && - !strstr(devpath, "block")) { - info("not a block or class device"); + if (!strstr(devpath, "class") && !strstr(devpath, "block")) { + dbg("not a block or class device"); goto exit; } @@ -100,8 +102,20 @@ int main(int argc, char *argv[], char *envp[]) if (argv[2] != NULL) subsystem = argv[2]; + /* fill in values and test_run flag*/ + udev_set_values(&udev, devpath, subsystem); + udev.test_run = 1; + + /* open the device */ + snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); + class_dev = sysfs_open_class_device_path(path); + if (class_dev == NULL) + dbg ("sysfs_open_class_device_path failed"); + else + dbg("opened class_dev->name='%s'", class_dev->name); + /* simulate node creation with fake flag */ - udev_add_device(devpath, subsystem, FAKE); + udev_add_device(&udev, class_dev); exit: return 0; From 5d24c6ca364c6232efa626049b03d02c15ab5e85 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 19:28:39 -0700 Subject: [PATCH 0926/4284] [PATCH] cleanup netif handling and netif-dev.d/ events Here we supress the dev.d/ execution if we didn't change a network interface's name with a rule. This should solve the issue of two running dhclients for the same interface, cause the /etc/dev.d/net/hotplug.dev script that fakes the hotplug event runs with every udevstart for every interface and fakes a second identical hotplug event on bootup. With this patch netif interfaces are no longer stored in the udevdb. It is not needed, cause we don't have permissions or symlinks :) and all information is available in sysfs. This patch also moves the dev_d execution calls out of the udev_add/udev_remove. As with the former api-cleanup-patch we have all processed data in one udev struct and can place the execution calls where needed. --- dev_d.c | 37 +++++++++++++++---------------------- udev.c | 10 ++++++++++ udev.h | 3 ++- udev_add.c | 39 +++++++++++++++++++-------------------- udev_remove.c | 20 +++++++++----------- udevdb.c | 3 +++ udevstart.c | 10 ++++++++-- udevtest.c | 17 +++++++++-------- 8 files changed, 75 insertions(+), 64 deletions(-) diff --git a/dev_d.c b/dev_d.c index 5580b5a362..be85f52775 100644 --- a/dev_d.c +++ b/dev_d.c @@ -62,7 +62,7 @@ static int run_program(char *name) execv(name, argv); dbg("exec of child failed"); - exit(1); + _exit(1); case -1: dbg("fork of child failed"); break; @@ -80,42 +80,35 @@ static int run_program(char *name) * subsystem/ * default/ */ -void dev_d_send(struct udevice *udev) +void dev_d_execute(struct udevice *udev) { - char dirname[256]; - char env_devname[NAME_SIZE]; - char *devname; + char dirname[PATH_MAX]; + char devname[NAME_SIZE]; char *temp; + /* skip if UDEV_NO_DEVD is set */ if (udev_dev_d == 0) return; - memset(env_devname, 0x00, sizeof(env_devname)); - if (udev->type == 'b' || udev->type == 'c') { - strfieldcpy(env_devname, udev_root); - strfieldcat(env_devname, udev->name); - } else if (udev->type == 'n') { - strfieldcpy(env_devname, udev->name); - setenv("DEVPATH", udev->devpath, 1); - } - setenv("DEVNAME", env_devname, 1); - dbg("DEVNAME='%s'", env_devname); - - devname = strdup(udev->name); - if (!devname) { - dbg("out of memory"); + /* skip if udev did nothing, like unchanged netif or no "dev" file */ + if (udev->devname[0] == '\0') return; - } + + /* add the node name or the netif name to the environment */ + setenv("DEVNAME", udev->devname, 1); + dbg("DEVNAME='%s'", udev->devname); + + strfieldcpy(devname, udev->name); /* Chop the device name up into pieces based on '/' */ temp = strchr(devname, '/'); while (temp != NULL) { - *temp = 0x00; + temp[0] = '\0'; strcpy(dirname, DEVD_DIR); strfieldcat(dirname, devname); call_foreach_file(run_program, dirname, DEVD_SUFFIX); - *temp = '/'; + temp[0] = '/'; ++temp; temp = strchr(temp, '/'); } diff --git a/udev.c b/udev.c index 8d5be0542e..dfb2baddbc 100644 --- a/udev.c +++ b/udev.c @@ -210,10 +210,20 @@ int main(int argc, char *argv[], char *envp[]) /* name, create node, store in db */ retval = udev_add_device(&udev, class_dev); + + /* run scripts */ + dev_d_execute(&udev); + + sysfs_close_class_device(class_dev); break; case REMOVE: dbg("udev remove"); + + /* get node from db, delete it*/ retval = udev_remove_device(&udev); + + /* run scripts */ + dev_d_execute(&udev); } udevdb_exit(); diff --git a/udev.h b/udev.h index 70de729f30..f7a13a634b 100644 --- a/udev.h +++ b/udev.h @@ -66,6 +66,7 @@ struct udevice { char program_result[NAME_SIZE]; char kernel_number[NAME_SIZE]; char kernel_name[NAME_SIZE]; + char devname[NAME_SIZE]; int test_run; }; @@ -74,7 +75,7 @@ extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); extern int parse_get_pair(char **orig_string, char **left, char **right); -extern void dev_d_send(struct udevice *udev); +extern void dev_d_execute(struct udevice *udev); extern char **main_argv; extern char **main_envp; diff --git a/udev_add.c b/udev_add.c index d07120de62..809a33cedb 100644 --- a/udev_add.c +++ b/udev_add.c @@ -355,7 +355,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) retval = get_major_minor(class_dev, udev); if (retval != 0) { dbg("no dev-file found, do nothing"); - goto close; + return 0; } } @@ -365,45 +365,44 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) dbg("adding name='%s'", udev->name); selinux_init(); - switch (udev->type) { - case 'b': - case 'c': + + if (udev->type == 'b' || udev->type == 'c') { retval = create_node(udev); if (retval != 0) goto exit; - if ((!udev->test_run) && (udevdb_add_dev(udev) != 0)) - dbg("udevdb_add_dev failed, but we are going to try " - "to create the node anyway. But remove might not " - "work properly for this device."); - dev_d_send(udev); - break; + if (udevdb_add_dev(udev) != 0) + dbg("udevdb_add_dev failed, but we create the node anyway, " + "remove might not work for custom names"); - case 'n': + /* use full path to the environment */ + snprintf(udev->devname, NAME_SIZE-1, "%s%s", udev_root, udev->name); + + } else if (udev->type == 'n') { + /* look if we want to change the name of the netif */ if (strcmp(udev->name, udev->kernel_name) != 0) { retval = rename_net_if(udev); if (retval != 0) goto exit; - /* netif's are keyed with the configured name, cause - * the original kernel name sleeps with the fishes + + /* we've changed the name, now fake the devpath, + * cause original kernel name sleeps with the fishes + * and we don't get any event from the kernel now */ pos = strrchr(udev->devpath, '/'); if (pos != NULL) { pos[1] = '\0'; strfieldcat(udev->devpath, udev->name); + setenv("DEVPATH", udev->devpath, 1); } - } - if ((!udev->test_run) && (udevdb_add_dev(udev) != 0)) - dbg("udevdb_add_dev failed"); - dev_d_send(udev); - break; + /* use netif name for the environment */ + strfieldcpy(udev->devname, udev->name); + } } exit: selinux_restore(); -close: - sysfs_close_class_device(class_dev); return retval; } diff --git a/udev_remove.c b/udev_remove.c index d97a2411f4..0dcec731ea 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -36,7 +36,7 @@ #include "namedev.h" #include "udevdb.h" -static int delete_path(char *path) +static int delete_path(const char *path) { char *pos; int retval; @@ -168,14 +168,15 @@ static int delete_node(struct udevice *dev) int udev_remove_device(struct udevice *udev) { struct udevice db_dev; - char *temp; + const char *temp; int retval; - memset(&db_dev, 0x00, sizeof(struct udevice)); + if (udev->type != 'b' && udev->type != 'c') + return 0; retval = udevdb_get_dev(udev->devpath, &db_dev); if (retval == 0) { - /* get stored values in our device */ + /* copy over the stored values to our device */ memcpy(udev, &db_dev, UDEVICE_DB_LEN); } else { /* fall back to kernel name */ @@ -185,15 +186,12 @@ int udev_remove_device(struct udevice *udev) strfieldcpy(udev->name, &temp[1]); dbg("'%s' not found in database, falling back on default name", udev->name); } - dbg("remove name='%s'", udev->name); - dev_d_send(udev); + dbg("remove name='%s'", udev->name); udevdb_delete_dev(udev->devpath); - if (udev->type == 'b' || udev->type == 'c') - retval = delete_node(udev); - else - retval = 0; + /* use full path to the environment */ + snprintf(udev->devname, NAME_SIZE-1, "%s%s", udev_root, udev->name); - return retval; + return delete_node(udev); } diff --git a/udevdb.c b/udevdb.c index 3d0a9ea3c2..23de22751d 100644 --- a/udevdb.c +++ b/udevdb.c @@ -49,6 +49,9 @@ int udevdb_add_dev(struct udevice *udev) TDB_DATA key, data; char keystr[SYSFS_PATH_MAX]; + if (udev->test_run) + return 0; + if (udevdb == NULL) return -1; diff --git a/udevstart.c b/udevstart.c index c4ec0f7b7a..fd490f0791 100644 --- a/udevstart.c +++ b/udevstart.c @@ -103,7 +103,7 @@ static int add_device(char *devpath, char *subsystem) setenv("DEVPATH", devpath, 1); setenv("ACTION", "add", 1); - snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath); + snprintf(path, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg ("sysfs_open_class_device_path failed"); @@ -111,8 +111,14 @@ static int add_device(char *devpath, char *subsystem) } udev_set_values(&udev, devpath, subsystem); + udev_add_device(&udev, class_dev); - return udev_add_device(&udev, class_dev); + /* run scripts */ + dev_d_execute(&udev); + + sysfs_close_class_device(class_dev); + + return 0; } static void exec_list(struct list_head *device_list) diff --git a/udevtest.c b/udevtest.c index fa1629af25..f2b0c98edb 100644 --- a/udevtest.c +++ b/udevtest.c @@ -69,12 +69,9 @@ int main(int argc, char *argv[], char *envp[]) if (argv[1] == NULL) { info("udevinfo expects the DEVPATH of the sysfs device as a argument"); - goto exit; + return 1; } - /* initialize our configuration */ - udev_init_config(); - /* remove sysfs_path if given */ if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) devpath = argv[1] + strlen(sysfs_path); @@ -93,9 +90,12 @@ int main(int argc, char *argv[], char *envp[]) /* we only care about class devices and block stuff */ if (!strstr(devpath, "class") && !strstr(devpath, "block")) { dbg("not a block or class device"); - goto exit; + return 2; } + /* initialize our configuration */ + udev_init_config(); + /* initialize the naming deamon */ namedev_init(); @@ -104,7 +104,6 @@ int main(int argc, char *argv[], char *envp[]) /* fill in values and test_run flag*/ udev_set_values(&udev, devpath, subsystem); - udev.test_run = 1; /* open the device */ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); @@ -114,9 +113,11 @@ int main(int argc, char *argv[], char *envp[]) else dbg("opened class_dev->name='%s'", class_dev->name); - /* simulate node creation with fake flag */ + /* simulate node creation with test flag */ + udev.test_run = 1; udev_add_device(&udev, class_dev); -exit: + sysfs_close_class_device(class_dev); + return 0; } From 1da6b0d0a71960f49e1ecf8bd9f1bc9e14c2b90e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 18 Oct 2004 19:40:21 -0700 Subject: [PATCH 0927/4284] [PATCH] delete udevruler.c as per Kay's request. --- udevruler.c | 490 ---------------------------------------------------- 1 file changed, 490 deletions(-) delete mode 100644 udevruler.c diff --git a/udevruler.c b/udevruler.c deleted file mode 100644 index a065591cd1..0000000000 --- a/udevruler.c +++ /dev/null @@ -1,490 +0,0 @@ -/* - * udevruler.c - simple udev-rule composer - * - * Reads the udev-db to get all currently known devices and - * scans the sysfs device chain for the choosen device to select attributes - * to compose a rule for the udev.rules file to uniquely name this device. - * - * 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. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "udev.h" -#include "udev_lib.h" -#include "udev_version.h" -#include "udevdb.h" -#include "logging.h" -#include "libsysfs/sysfs.h" -#include "list.h" - -#ifdef LOG -unsigned char logname[LOGNAME_SIZE]; -void log_message(int level, const char *format, ...) -{ - va_list args; - - if (!udev_log) - return; - - va_start(args, format); - vsyslog(level, format, args); - va_end(args); -} -#endif - -static char *dev_blacklist[] = { - "tty", - "pty", - "zero", - "null", - "kmsg", - "rtc", - "timer", - "full", - "kmem", - "mem", - "random", - "urandom", - "console", - "port", - "" -}; - -struct device { - struct list_head list; - char name[NAME_SIZE]; - char devpath[DEVPATH_SIZE]; - int config_line; - char config_file[NAME_SIZE]; - long config_uptime; - int added; -}; - -static LIST_HEAD(device_list); -static int device_count; - -/* callback for database dump */ -static int add_record(char *path, struct udevice *udev) -{ - struct device *dev; - struct device *loop_dev; - int i = 0; - - while (dev_blacklist[i][0] != '\0') { - if (strncmp(udev->name, dev_blacklist[i], strlen(dev_blacklist[i])) == 0) - goto exit; - i++; - } - - dev = malloc(sizeof(struct device)); - if (dev == NULL) { - printf("error malloc\n"); - exit(2); - } - strfieldcpy(dev->name, udev->name); - strfieldcpy(dev->devpath, path); - dev->config_line = udev->config_line; - strfieldcpy(dev->config_file, udev->config_file); - dev->config_uptime = udev->config_uptime; - dev->added = 0; - - /* sort in lexical order */ - list_for_each_entry(loop_dev, &device_list, list) { - if (strcmp(loop_dev->name, dev->name) > 0) { - break; - } - } - - list_add_tail(&dev->list, &loop_dev->list); - device_count++; - -exit: - return 0; -} - -/* get all devices from udev database */ -static int get_all_devices(void) -{ - int retval; - - device_count = 0; - INIT_LIST_HEAD(&device_list); - - retval = udevdb_open_ro(); - if (retval != 0) { - printf("unable to open udev database\n"); - exit(1); - } - - udevdb_call_foreach(add_record); - udevdb_exit(); - - return 0; -} - -struct attribute { - struct list_head list; - int level; - char key[NAME_SIZE]; -}; - -static LIST_HEAD(attribute_list); -static int attribute_count; - -static int add_attribute(const char *key, int level) -{ - struct attribute *attr; - - dbg("add attribute '%s'", key); - attr = malloc(sizeof(struct attribute)); - if (attr == NULL) { - printf("error malloc\n"); - exit(2); - } - - strfieldcpy(attr->key, key); - attr->level = level; - list_add_tail(&attr->list, &attribute_list); - attribute_count++; - return 0; -} - -static int add_all_attributes(const char *path, int level) -{ - struct dlist *attributes; - struct sysfs_attribute *attr; - struct sysfs_directory *sysfs_dir; - char value[NAME_SIZE]; - char key[NAME_SIZE]; - int len; - int retval = 0; - - dbg("look at '%s', level %i", path, level); - - sysfs_dir = sysfs_open_directory(path); - if (sysfs_dir == NULL) - return -1; - - attributes = sysfs_get_dir_attributes(sysfs_dir); - if (attributes == NULL) { - retval = -1; - return 0; - } - - dlist_for_each_data(attributes, attr, struct sysfs_attribute) - if (attr->value != NULL) { - dbg("found attribute '%s'", attr->name); - strfieldcpy(value, attr->value); - len = strlen(value); - if (len == 0) - continue; - - /* skip very long attributes */ - if (len > 40) - continue; - - /* remove trailing newline */ - if (value[len-1] == '\n') { - value[len-1] = '\0'; - len--; - } - - /* skip nonprintable values */ - while (len) { - if (!isprint(value[len-1])) - break; - len--; - } - if (len == 0) { - sprintf(key, "SYSFS{%s}=\"%s\"", attr->name, value); - add_attribute(key, level); - } - } - - sysfs_close_directory(sysfs_dir); - return 0; -} - -static int get_all_attributes(char *path) -{ - struct sysfs_class_device *class_dev; - struct sysfs_class_device *class_dev_parent; - struct sysfs_device *sysfs_dev; - struct sysfs_device *sysfs_dev_parent; - char key[NAME_SIZE]; - int retval = 0; - int level = 0; - - attribute_count = 0; - INIT_LIST_HEAD(&attribute_list); - - /* get the class dev */ - class_dev = sysfs_open_class_device_path(path); - if (class_dev == NULL) { - dbg("couldn't get the class device"); - return -1; - } - - /* open sysfs class device directory and get all attributes */ - if (add_all_attributes(class_dev->path, level) != 0) { - dbg("couldn't open class device directory"); - retval = -1; - goto exit; - } - level++; - - /* get the device link (if parent exists look here) */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) - sysfs_dev = sysfs_get_classdev_device(class_dev_parent); - else - sysfs_dev = sysfs_get_classdev_device(class_dev); - - /* look the device chain upwards */ - while (sysfs_dev != NULL) { - if (sysfs_dev->bus[0] != '\0') { - add_attribute("", level); - sprintf(key, "BUS=\"%s\"", sysfs_dev->bus); - add_attribute(key, level); - sprintf(key, "ID=\"%s\"", sysfs_dev->bus_id); - add_attribute(key, level); - - /* open sysfs device directory and print all attributes */ - add_all_attributes(sysfs_dev->path, level); - } - level++; - - sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev); - if (sysfs_dev_parent == NULL) - break; - - sysfs_dev = sysfs_dev_parent; - } - -exit: - sysfs_close_class_device(class_dev); - return retval; -} - - -int main(int argc, char *argv[]) { - newtComponent lbox, run, lattr; - newtComponent quit, form, answer; - newtGrid grid, grid2; - char roottext[81]; - char path[NAME_SIZE]; - struct device *dev; - long time_last; - int count_last; - - newtInit(); - newtCls(); - - newtWinMessage("udevruler", "Ok", - "This program lets you select a device currently present " - "on the system and you may choose the attributes to uniquely " - "name the device with a udev rule.\n" - "No configuration will be changed, it just prints the rule " - "to place in a udev.rules configuration file. The \"%k\" in the " - "NAME key of the printed rule may be replaced by the name the " - "node should have."); - - init_logging("udevruler"); - udev_init_config(); - get_all_devices(); - - lbox = newtListbox(2, 1, 10, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT); - - /* look for last discovered device */ - time_last = 0; - list_for_each_entry(dev, &device_list, list) - if (dev->config_uptime > time_last) - time_last = dev->config_uptime; - - /* skip if more than 16 recent devices */ - count_last = 0; - list_for_each_entry(dev, &device_list, list) { - if (dev->config_uptime < time_last - 10) - continue; - count_last++; - } - - /* add devices up to 10 seconds older than the last one */ - if (count_last < 16) { - newtListboxAppendEntry(lbox, "--- last dicovered ---", NULL); - list_for_each_entry(dev, &device_list, list) { - if (dev->config_uptime < time_last - 10) - continue; - - dbg("%s %i", dev->name, dev->config_line); - newtListboxAppendEntry(lbox, dev->name, (void*) dev); - dev->added = 1; - } - newtListboxAppendEntry(lbox, "", NULL); - } - - /* add devices not catched by a rule */ - newtListboxAppendEntry(lbox, "--- not configured by a rule ---", NULL); - list_for_each_entry(dev, &device_list, list) { - if (dev->added) - continue; - - if (dev->config_line != 0) - continue; - - dbg("%s %i", dev->name, dev->config_line); - newtListboxAppendEntry(lbox, dev->name, (void*) dev); - dev->added = 1; - } - newtListboxAppendEntry(lbox, "", NULL); - - /* add remaining devices */ - newtListboxAppendEntry(lbox, "--- configured by a rule ---", NULL); - list_for_each_entry(dev, &device_list, list) { - if (dev->added) - continue; - - dbg("%s %i", dev->name, dev->config_line); - newtListboxAppendEntry(lbox, dev->name, (void*) dev); - } - - newtPushHelpLine(" / between elements | Use to select a device"); - snprintf(roottext, sizeof(roottext), "simple udev rule composer, version %s, (c) 2004 can't sleep team", UDEV_VERSION); - roottext[sizeof(roottext)-1] = '\0'; - newtDrawRootText(0, 0, roottext); - - form = newtForm(NULL, NULL, 0); - grid = newtCreateGrid(1, 2); - grid2 = newtButtonBar("Select device", &run, "Quit", &quit, NULL); - newtGridSetField(grid, 0, 0, NEWT_GRID_COMPONENT, lbox, 1, 0, 1, 0, NEWT_ANCHOR_TOP, 0); - newtGridSetField(grid, 0, 1, NEWT_GRID_SUBGRID, grid2, 0, 1, 0, 0, NEWT_ANCHOR_TOP, 0); - newtFormAddComponents(form, lbox, run, quit, NULL); - newtGridWrappedWindow(grid,"Choose the device for which to compose a rule"); - newtGridFree(grid, 1); - - while (1) { - struct attribute *attr; - newtComponent ok, back, form2, answer2, text; - newtGrid grid3, grid4; - int i; - int numitems; - struct attribute **selattr; - char text_rule[255]; - - answer = newtRunForm(form); - if (answer == quit) - break; - - dev = (struct device *) newtListboxGetCurrent(lbox); - if (dev == NULL) - continue; - - if (dev->config_line > 0) - snprintf(text_rule, sizeof(text_rule), - "The device is handled by a rule in the file '%s', line %i.", - dev->config_file, dev->config_line); - else - strcpy(text_rule, "The device was not handled by a rule."); - - strfieldcpy(path, sysfs_path); - strfieldcat(path, dev->devpath); - dbg("look at sysfs device '%s'", path); - get_all_attributes(path); - - grid3 = newtCreateGrid(1, 3); - form2 = newtForm(NULL, NULL, 0); - grid4 = newtButtonBar("Ok", &ok, "Back", &back, NULL); - - lattr = newtListbox(-1, -1, 10, NEWT_FLAG_MULTIPLE | NEWT_FLAG_BORDER | NEWT_FLAG_RETURNEXIT); - list_for_each_entry(attr, &attribute_list, list) - newtListboxAddEntry(lattr, attr->key, (void *) attr); - - text = newtTextbox(-1, -1, 50, 2, NEWT_FLAG_WRAP); - newtTextboxSetText(text, text_rule); - - newtGridSetField(grid3, 0, 0, NEWT_GRID_COMPONENT, lattr, 0, 0, 0, 1, 0, 0); - newtGridSetField(grid3, 0, 1, NEWT_GRID_COMPONENT, text, 0, 0, 0, 1, 0, 0); - newtGridSetField(grid3, 0, 2, NEWT_GRID_SUBGRID, grid4, 0, 1, 0, 0, NEWT_ANCHOR_TOP, 0); - - newtFormAddComponents(form2, text, lattr, ok, back, NULL); - newtGridWrappedWindow(grid3, "Select one ore more attributes within one section with the space bar"); - newtGridFree(grid3, 1); - - while (1) { - char rule[255]; - int onelevel; - int skipped; - - answer2 = newtRunForm(form2); - if (answer2 == back) - break; - - selattr = (struct attribute **) newtListboxGetSelection(lattr, &numitems); - if (selattr == NULL) - continue; - - rule[0] = '\0'; - onelevel = -1; - skipped = 0; - for (i = 0; i < numitems; i++) { - if (selattr[i]->key[0] == '\0') - continue; - - if (onelevel != -1) { - if (onelevel != selattr[i]->level) { - skipped = 1; - continue; - } - } else { - onelevel = selattr[i]->level; - } - - dbg("'%s'\n", selattr[i]->key); - strfieldcat(rule, selattr[i]->key); - strfieldcat(rule, ", "); - } - if (skipped) { - newtWinMessage("error", "Ok", "Please select only attributes within one section"); - continue; - } - - if (strlen(rule) > 200) { - newtWinMessage("error", "Ok", "The line is too long, please select fewer attributes."); - } else { - if (rule[0] == '\0') - continue; - - strfieldcat(rule, "NAME=\"%k\""); - newtWinMessage("the rule to place in config file", "Ok", rule); - } - } - - newtPopWindow(); - } - - newtPopWindow(); - newtFormDestroy(form); - newtFinished(); - return 0; -} From 9cd1b46a138dbdd6c3fad2e23f88e34740b3a054 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 20:51:13 -0700 Subject: [PATCH 0928/4284] [PATCH] $local user We once implemented the devfsd feature to set the owner of a device node to the "local" user. This was before we had the dev.d/ scripts. We discussed a similar issue with D-BUS recently and this should be better handled depending on the distributions way to do such a thing. I'm for removing this here as this can be easily covered by a dev.d/ script. Here is the patch if nobody objects :) --- klibc_fixups.c | 34 ---------------------------------- klibc_fixups.h | 5 ----- udev.8.in | 11 ----------- udev_add.c | 35 ----------------------------------- 4 files changed, 85 deletions(-) diff --git a/klibc_fixups.c b/klibc_fixups.c index d1a452a449..e68ce22b50 100644 --- a/klibc_fixups.c +++ b/klibc_fixups.c @@ -125,38 +125,4 @@ struct group *getgrnam(const char *name) return &gr; } - -int ufd = -1; - -void setutent() -{ - if (ufd < 0) - ufd = open(UTMP_FILE, O_RDONLY); - fcntl(ufd, F_SETFD, FD_CLOEXEC); - lseek(ufd, 0, SEEK_SET); -} - -void endutent() { - if (ufd < 0) - return; - close(ufd); - ufd = -1; -} - -struct utmp *getutent(void) -{ - static struct utmp utmp; - int retval; - - if (ufd < 0) { - setutent(); - if (ufd < 0) - return NULL; - } - retval = read(ufd, &utmp, sizeof(struct utmp)); - if (retval < 1) - return NULL; - return &utmp; -} - #endif diff --git a/klibc_fixups.h b/klibc_fixups.h index f6c91cdd94..082105eb8e 100644 --- a/klibc_fixups.h +++ b/klibc_fixups.h @@ -62,10 +62,5 @@ struct utmp char __unused[20]; /* reserved for future use */ }; -struct utmp *getutent(void); -void setutent(void); -void endutent(void); - - #endif /* KLIBC_FIXUPS_H */ #endif /* __KLIBC__ */ diff --git a/udev.8.in b/udev.8.in index c842e7befb..a7f0bf0392 100644 --- a/udev.8.in +++ b/udev.8.in @@ -335,17 +335,6 @@ video*:root:video:0660 dsp1:::0666 .fi .P -The value -.I $local -can be used instead of a specific username. In that case, udev will determine -the current local user at the time of device node creation and substitute -that username as the owner of the new device node. This is useful, for -example, to let hot-plugged devices, such as cameras, be owned by the user at -the current console. Note that if no user is currently logged in, or if udev -otherwise fails to determine a current user, the -.I default_owner -value is used in lieu. -.P A number of different fields in the above configuration files support a simple form of shell style pattern matching. It supports the following pattern characters: .TP diff --git a/udev_add.c b/udev_add.c index 809a33cedb..0e7d575d58 100644 --- a/udev_add.c +++ b/udev_add.c @@ -48,8 +48,6 @@ #include "udevdb.h" #include "klibc_fixups.h" -#define LOCAL_USER "$local" - #include "selinux.h" /* @@ -155,37 +153,6 @@ exit: return retval; } -/* get the local logged in user */ -static void set_to_local_user(char *user) -{ - struct utmp *u; - time_t recent = 0; - - strfieldcpymax(user, default_owner_str, OWNER_SIZE); - setutent(); - while (1) { - u = getutent(); - if (u == NULL) - break; - - /* is this a user login ? */ - if (u->ut_type != USER_PROCESS) - continue; - - /* is this a local login ? */ - if (strcmp(u->ut_host, "")) - continue; - - if (u->ut_time > recent) { - recent = u->ut_time; - strfieldcpymax(user, u->ut_user, OWNER_SIZE); - dbg("local user is '%s'", user); - break; - } - } - endutent(); -} - static int create_node(struct udevice *udev) { char filename[NAME_SIZE]; @@ -229,8 +196,6 @@ static int create_node(struct udevice *udev) uid = (uid_t) id; else { struct passwd *pw; - if (strncmp(udev->owner, LOCAL_USER, sizeof(LOCAL_USER)) == 0) - set_to_local_user(udev->owner); pw = getpwnam(udev->owner); if (pw == NULL) From 1b1ba9336508dd1a06bb81bbf89b049e9e38f126 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 20:51:16 -0700 Subject: [PATCH 0929/4284] [PATCH] volume_id fix I've been told that open() should not pass O_NONBLOCK. --- extras/volume_id/volume_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index f18baec6ee..0b43bc8efb 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -2128,7 +2128,7 @@ struct volume_id *volume_id_open_node(const char *path) struct volume_id *id; int fd; - fd = open(path, O_RDONLY | O_NONBLOCK); + fd = open(path, O_RDONLY); if (fd < 0) { dbg("unable to open '%s'", path); return NULL; From 4a760b333459003055816bc6a296c54327d521dc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 18 Oct 2004 21:42:23 -0700 Subject: [PATCH 0930/4284] [PATCH] fix stupid cut-and-paste error for msr devices on gentoo boxes. --- etc/udev/udev.rules.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 9245f6adcf..b33df81d25 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -132,5 +132,5 @@ KERNEL="raw[0-9]*", NAME="raw/%k" # cpu devices KERNEL="cpu[0-9]*", NAME="cpu/%n/cpuid" -KERNEL="msr[0-9]*", NAME="cpu/%n/cpuid" +KERNEL="msr[0-9]*", NAME="cpu/%n/msr" KERNEL="microcode", NAME="cpu/microcode" From 3b2382de5192057d4c3ac25ddce9c70348d756f9 Mon Sep 17 00:00:00 2001 From: "jk@blackdown.de" Date: Mon, 18 Oct 2004 22:10:38 -0700 Subject: [PATCH 0931/4284] [PATCH] wait_for_sysfs update for dm devices Hi, I got these when creating LVM2 snapshots: ,---- | Oct 17 04:23:09 server wait_for_sysfs[5120]: error: wait_for_sysfs needs an update to handle the device '/block/dm-6' properly, please report to | Oct 17 04:23:09 server wait_for_sysfs[5129]: error: wait_for_sysfs needs an update to handle the device '/block/dm-6' properly, please report to | Oct 17 04:23:09 server wait_for_sysfs[5131]: error: wait_for_sysfs needs an update to handle the device '/block/dm-7' properly, please report to | [...] `---- --- wait_for_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 8f142f488b..b6de3947c8 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -147,6 +147,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "block", .device = "pf" }, { .subsystem = "block", .device = "scd" }, { .subsystem = "block", .device = "ubd" }, + { .subsystem = "block", .device = "dm-" }, { .subsystem = "input", .device = "event" }, { .subsystem = "input", .device = "mice" }, { .subsystem = "input", .device = "mouse" }, From ff694eca172deb298e806246f6e88bc66235534a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Oct 2004 22:57:41 -0700 Subject: [PATCH 0932/4284] [PATCH] fix debug in volume id / fix clashing global var name Here we get the logging for udev_volume_id working if it is compiled with DEBUG=true. Also fixed is a name clash with a global variable. --- extras/volume_id/Makefile | 5 ++--- extras/volume_id/udev_volume_id.c | 10 +++++++--- wait_for_sysfs.c | 8 ++++---- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index d0c6e40fa3..c419e8860f 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -28,9 +28,8 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts -Wmissing-declarations \ - -Wnested-externs -Wpointer-arith -Wcast-align \ - -Wsign-compare +override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \ + -Wpointer-arith -Wcast-align -Wsign-compare override CFLAGS+=-D_FILE_OFFSET_BITS=64 diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 6b62db0775..5d1ccf6a89 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -104,7 +104,7 @@ int main(int argc, char *argv[]) " -d disk label from main device\n" "\n"; static const char short_options[] = "htlud"; - char sysfs_path[SYSFS_PATH_MAX]; + char sysfs_mnt_path[SYSFS_PATH_MAX]; char dev_path[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev = NULL; struct sysfs_class_device *class_dev_parent = NULL; @@ -118,6 +118,8 @@ int main(int argc, char *argv[]) unsigned long long size; int rc = 1; + logging_init("udev_volume_id"); + while (1) { int option; @@ -152,12 +154,12 @@ int main(int argc, char *argv[]) goto exit; } - if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { + if (sysfs_get_mnt_path(sysfs_mnt_path, SYSFS_PATH_MAX) != 0) { printf("error getting sysfs mount path\n"); goto exit; } - strfieldcpy(dev_path, sysfs_path); + strfieldcpy(dev_path, sysfs_mnt_path); strfieldcat(dev_path, devpath); class_dev = sysfs_open_class_device_path(dev_path); @@ -261,5 +263,7 @@ exit: if (vid != NULL) volume_id_close(vid); + logging_close(); + exit(rc); } diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index b6de3947c8..45f84606b1 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -387,7 +387,7 @@ int main(int argc, char *argv[], char *envp[]) const char *devpath = ""; const char *action; const char *subsystem; - char sysfs_path[SYSFS_PATH_MAX]; + char sysfs_mnt_path[SYSFS_PATH_MAX]; char filename[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev; struct sysfs_device *devices_dev; @@ -422,14 +422,14 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { + if (sysfs_get_mnt_path(sysfs_mnt_path, SYSFS_PATH_MAX) != 0) { dbg("error: no sysfs path"); rc = 2; goto exit; } if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) { - snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); + snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_mnt_path, devpath); filename[SYSFS_PATH_MAX-1] = '\0'; /* open the class device we are called for */ @@ -446,7 +446,7 @@ int main(int argc, char *argv[], char *envp[]) sysfs_close_class_device(class_dev); } else if ((strncmp(devpath, "/devices/", 9) == 0)) { - snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); + snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_mnt_path, devpath); filename[SYSFS_PATH_MAX-1] = '\0'; /* open the path we are called for */ From 1ceba9360b4de2f9ad3f20c23133bbfec027c036 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 18 Oct 2004 23:14:20 -0700 Subject: [PATCH 0933/4284] [PATCH] sparse cleanups on the tree --- namedev_parse.c | 4 ++-- udev.c | 1 + udev_remove.c | 1 + udevd.c | 12 ++++++------ 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 7e37833202..22e3523f3d 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -441,7 +441,7 @@ exit: return retval; } -int namedev_init_rules() +int namedev_init_rules(void) { struct stat stats; @@ -453,7 +453,7 @@ int namedev_init_rules() udev_rules_filename, RULEFILE_SUFFIX); } -int namedev_init_permissions() +int namedev_init_permissions(void) { struct stat stats; diff --git a/udev.c b/udev.c index dfb2baddbc..839bfa6520 100644 --- a/udev.c +++ b/udev.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" diff --git a/udev_remove.c b/udev_remove.c index 0dcec731ea..cd9d27f8dc 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "udev.h" #include "udev_lib.h" diff --git a/udevd.c b/udevd.c index 421c25a6e8..9e0f71b583 100644 --- a/udevd.c +++ b/udevd.c @@ -177,7 +177,7 @@ static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) } /* exec queue management routine executes the events and delays events for the same devpath */ -static void exec_queue_manager() +static void exec_queue_manager(void) { struct hotplug_msg *loop_msg; struct hotplug_msg *tmp_msg; @@ -207,7 +207,7 @@ static void msg_move_exec(struct hotplug_msg *msg) } /* msg queue management routine handles the timeouts and dispatches the events */ -static void msg_queue_manager() +static void msg_queue_manager(void) { struct hotplug_msg *loop_msg; struct hotplug_msg *tmp_msg; @@ -241,7 +241,7 @@ recheck: if (list_empty(&msg_list) == 0) { struct itimerval itv = {{0, 0}, {EVENT_TIMEOUT_SEC - msg_age, 0}}; dbg("next event expires in %li seconds", EVENT_TIMEOUT_SEC - msg_age); - setitimer(ITIMER_REAL, &itv, 0); + setitimer(ITIMER_REAL, &itv, NULL); } } @@ -366,11 +366,11 @@ static void udev_done(int pid) } } -static void reap_kids() +static void reap_kids(void) { /* reap all dead children */ while(1) { - int pid = waitpid(-1, 0, WNOHANG); + int pid = waitpid(-1, NULL, WNOHANG); if ((pid == -1) || (pid == 0)) break; udev_done(pid); @@ -380,7 +380,7 @@ static void reap_kids() /* just read everything from the pipe and clear the flag, * the useful flags were set in the signal handler */ -static void user_sighandler() +static void user_sighandler(void) { int sig; while(1) { From 796ed8851b2fe8c592c2e903ff218352c418b9fc Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 19 Oct 2004 01:20:30 -0700 Subject: [PATCH 0934/4284] [PATCH] 040 release --- ChangeLog | 25 +++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index ca7532a3fb..73d52d46a4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,28 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 11f4781e0e..d0633b70af 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart WAIT = wait_for_sysfs -VERSION = 039 +VERSION = 040 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 44164124ed..9055512332 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 039 +Version: 040 Release: 1 License: GPL Group: Utilities/System From f071348004c8069b610effd95309ff47c515cf3e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 19 Oct 2004 04:37:22 -0700 Subject: [PATCH 0935/4284] [PATCH] expose sysfs functions for sharing it This patch exposes the wait_for_sysfs functions to all possible users, so we need to maintain only one list of exceptions. The last list is hereby removed from udev.c. --- Makefile | 4 +- udev.c | 43 +----- udev_sysfs.c | 387 +++++++++++++++++++++++++++++++++++++++++++++++ udev_sysfs.h | 36 +++++ wait_for_sysfs.c | 339 +---------------------------------------- 5 files changed, 437 insertions(+), 372 deletions(-) create mode 100644 udev_sysfs.c create mode 100644 udev_sysfs.h diff --git a/Makefile b/Makefile index d0633b70af..4d25aee73e 100644 --- a/Makefile +++ b/Makefile @@ -212,6 +212,7 @@ OBJS = udev_lib.o \ udev_config.o \ udev_add.o \ udev_remove.o \ + udev_sysfs.o \ udevdb.o \ namedev.o \ namedev_parse.o \ @@ -224,6 +225,7 @@ HEADERS = udev.h \ namedev.h \ udev_version.h \ udevdb.h \ + udev_sysfs.h \ klibc_fixups.h \ logging.h \ selinux.h \ @@ -303,7 +305,7 @@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h $(QUIET) $(STRIPCMD) $@ $(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o udev_sysfs.o udev_lib.o udev_config.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ #.c.o: diff --git a/udev.c b/udev.c index 839bfa6520..5064bbd175 100644 --- a/udev.c +++ b/udev.c @@ -33,6 +33,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "udev_lib.h" +#include "udev_sysfs.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" @@ -76,35 +77,6 @@ static void asmlinkage sig_handler(int signum) } } -/* list of subsystems we don't care about. not listing such systems here - * is not critical, but it makes it faster as we don't look for the "dev" file - */ -static int subsystem_without_dev(const char *subsystem) -{ - char *subsystem_blacklist[] = { - "scsi_host", - "scsi_device", - "usb_host", - "pci_bus", - "pcmcia_socket", - "bluetooth", - "i2c-adapter", - "pci_bus", - "ieee1394", - "ieee1394_host", - "ieee1394_node", - NULL - }; - char **subsys; - - for (subsys = subsystem_blacklist; *subsys != NULL; subsys++) { - if (strcmp(subsystem, *subsys) == 0) - return 1; - } - - return 0; -} - int main(int argc, char *argv[], char *envp[]) { struct sigaction act; @@ -151,7 +123,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("no devpath?"); goto exit; } - dbg("looking at '%s'", udev.devpath); + dbg("looking at '%s'", devpath); /* we only care about class devices and block stuff */ if (!strstr(devpath, "class") && !strstr(devpath, "block")) { @@ -164,13 +136,14 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + udev_set_values(&udev, devpath, subsystem); + /* skip blacklisted subsystems */ - if (subsystem_without_dev(subsystem)) { + if (udev.type != 'n' && subsystem_expect_no_dev(subsystem)) { dbg("don't care about '%s' devices", subsystem); goto exit; }; - udev_set_values(&udev, devpath, subsystem); } /* set signal handlers */ @@ -197,9 +170,6 @@ int main(int argc, char *argv[], char *envp[]) case ADD: dbg("udev add"); - /* init rules */ - namedev_init(); - /* open the device */ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); class_dev = sysfs_open_class_device_path(path); @@ -209,6 +179,9 @@ int main(int argc, char *argv[], char *envp[]) } dbg("opened class_dev->name='%s'", class_dev->name); + /* init rules */ + namedev_init(); + /* name, create node, store in db */ retval = udev_add_device(&udev, class_dev); diff --git a/udev_sysfs.c b/udev_sysfs.c new file mode 100644 index 0000000000..624f53586f --- /dev/null +++ b/udev_sysfs.c @@ -0,0 +1,387 @@ +/* + * udev_sysfs.c - sysfs linux kernel specific knowledge + * + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2004 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "logging.h" +#include "udev_version.h" +#include "udev_sysfs.h" +#include "libsysfs/sysfs/libsysfs.h" + +/* list of subsystem specific files + * NULL if there is no file to wait for + */ +static struct subsystem_file { + char *subsystem; + char *file; +} subsystem_files[] = { + { .subsystem = "net", .file = "ifindex" }, + { .subsystem = "scsi_host", .file = "unique_id" }, + { .subsystem = "scsi_device", .file = NULL }, + { .subsystem = "pcmcia_socket", .file = "card_type" }, + { .subsystem = "usb_host", .file = NULL }, + { .subsystem = "bluetooth", .file = "address" }, + { .subsystem = "firmware", .file = "data" }, + { .subsystem = "i2c-adapter", .file = NULL }, + { .subsystem = "pci_bus", .file = NULL }, + { .subsystem = "ieee1394", .file = NULL }, + { .subsystem = "ieee1394_host", .file = NULL }, + { .subsystem = "ieee1394_node", .file = NULL }, + { NULL, NULL } +}; + +int subsystem_expect_no_dev(const char *subsystem) +{ + struct subsystem_file *file; + + for (file = subsystem_files; file->subsystem != NULL; file++) + if (strcmp(subsystem, file->subsystem) == 0) + return 1; + + return 0; +} + +/* get subsystem specific files, returns "dev" if no other found */ +static char *get_subsystem_specific_file(const char *subsystem) +{ + struct subsystem_file *file; + + /* look if we want to look for another file instead of "dev" */ + for (file = subsystem_files; file->subsystem != NULL; file++) + if (strcmp(subsystem, file->subsystem) == 0) + return file->file; + + return "dev"; +} + +/* wait for class pecific file to show up */ +static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev, + const char **error) +{ + const char *file; + char filename[SYSFS_PATH_MAX]; + int loop; + + file = get_subsystem_specific_file(class_dev->classname); + if (file == NULL) { + dbg("class '%s' has no file to wait for", class_dev->classname); + return 0; + } + + strcpy(filename, class_dev->path); + strcat(filename, "/"); + strcat(filename, file); + dbg("looking at class '%s' for specific file '%s' with full name %s", class_dev->classname, file, filename); + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + struct stat stats; + + if (stat(class_dev->path, &stats) == -1) { + dbg("'%s' now disappeared (probably remove has beaten us)", class_dev->path); + return -ENODEV; + } + + if (stat(filename, &stats) == 0) { + dbg("class '%s' specific file '%s' found", class_dev->classname, file); + return 0; + } + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + + dbg("error: getting class '%s' specific file '%s'", class_dev->classname, file); + if (error) + *error = "class specific file unavailable"; + return -ENOENT; +} + +/* check if we need to wait for a physical device */ +static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) +{ + /* list of devices without a "device" symlink to the physical device + * if device is set to NULL, no devices in that subsystem has a link */ + static struct class_device { + char *subsystem; + char *device; + } class_device[] = { + { .subsystem = "block", .device = "double" }, + { .subsystem = "block", .device = "nb" }, + { .subsystem = "block", .device = "ram" }, + { .subsystem = "block", .device = "loop" }, + { .subsystem = "block", .device = "fd" }, + { .subsystem = "block", .device = "md" }, + { .subsystem = "block", .device = "dos_cd" }, + { .subsystem = "block", .device = "rflash" }, + { .subsystem = "block", .device = "rom" }, + { .subsystem = "block", .device = "rrom" }, + { .subsystem = "block", .device = "flash" }, + { .subsystem = "block", .device = "msd" }, + { .subsystem = "block", .device = "sbpcd" }, + { .subsystem = "block", .device = "pcd" }, + { .subsystem = "block", .device = "pf" }, + { .subsystem = "block", .device = "scd" }, + { .subsystem = "block", .device = "ubd" }, + { .subsystem = "block", .device = "dm-" }, + { .subsystem = "input", .device = "event" }, + { .subsystem = "input", .device = "mice" }, + { .subsystem = "input", .device = "mouse" }, + { .subsystem = "input", .device = "ts" }, + { .subsystem = "vc", .device = NULL }, + { .subsystem = "tty", .device = NULL }, + { .subsystem = "cpuid", .device = "cpu" }, + { .subsystem = "graphics", .device = "fb" }, + { .subsystem = "mem", .device = NULL }, + { .subsystem = "misc", .device = NULL }, + { .subsystem = "msr", .device = NULL }, + { .subsystem = "netlink", .device = NULL }, + { .subsystem = "net", .device = "sit" }, + { .subsystem = "net", .device = "lo" }, + { .subsystem = "net", .device = "tap" }, + { .subsystem = "net", .device = "ipsec" }, + { .subsystem = "net", .device = "dummy" }, + { .subsystem = "net", .device = "irda" }, + { .subsystem = "net", .device = "ppp" }, + { .subsystem = "ppp", .device = NULL }, + { .subsystem = "sound", .device = NULL }, + { .subsystem = "printer", .device = "lp" }, + { .subsystem = "nvidia", .device = NULL }, + { .subsystem = "video4linux", .device = "vbi" }, + { .subsystem = "lirc", .device = NULL }, + { .subsystem = "firmware", .device = NULL }, + { .subsystem = "drm", .device = NULL }, + { .subsystem = "pci_bus", .device = NULL }, + { .subsystem = "ieee1394", .device = NULL }, + { .subsystem = "ieee1394_host", .device = NULL }, + { .subsystem = "ieee1394_node", .device = NULL }, + { .subsystem = "raw", .device = NULL }, + { NULL, NULL } + }; + struct class_device *classdevice; + int len; + + for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) { + if (strcmp(class_dev->classname, classdevice->subsystem) == 0) { + /* see if no device in this class is expected to have a device-link */ + if (classdevice->device == NULL) + return 1; + + len = strlen(classdevice->device); + + /* see if device name matches */ + if (strncmp(class_dev->name, classdevice->device, len) != 0) + continue; + + /* exact name match */ + if (strlen(class_dev->name) == len) + return 1; + + /* name match with instance number */ + if (isdigit(class_dev->name[len])) + return 1; + } + } + + return 0; +} + +/* skip waiting for the bus */ +static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) +{ + static char *devices_without_bus[] = { + "scsi_host", + "i2c-adapter", + NULL + }; + char **device; + + for (device = devices_without_bus; *device != NULL; device++) { + int len = strlen(*device); + + if (strncmp(class_dev->classname, *device, len) == 0) + return 1; + } + + return 0; +} + +/* wait for the bus and for a bus specific file to show up */ +int wait_for_bus_device(struct sysfs_device *devices_dev, + const char **error) +{ + static struct bus_file { + char *bus; + char *file; + } bus_files[] = { + { .bus = "scsi", .file = "vendor" }, + { .bus = "usb", .file = "idVendor" }, + { .bus = "usb", .file = "iInterface" }, + { .bus = "usb", .file = "bNumEndpoints" }, + { .bus = "usb-serial", .file = "detach_state" }, + { .bus = "ide", .file = "detach_state" }, + { .bus = "pci", .file = "vendor" }, + { .bus = "platform", .file = "detach_state" }, + { .bus = "i2c", .file = "detach_state" }, + { NULL } + }; + struct bus_file *busfile; + int loop; + + /* wait for the bus device link to the devices device */ + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + if (sysfs_get_device_bus(devices_dev) == 0) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + if (loop == 0) { + dbg("error: getting bus device link"); + if (error) + *error = "no bus device link"; + return -1; + } + dbg("bus device link found for bus '%s'", devices_dev->bus); + + /* wait for a bus specific file to show up */ + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + int found = 0; + + for (busfile = bus_files; busfile->bus != NULL; busfile++) { + if (strcmp(devices_dev->bus, busfile->bus) == 0) { + found = 1; + dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, busfile->file); + if (sysfs_get_device_attr(devices_dev, busfile->file) != NULL) { + dbg("bus '%s' specific file '%s' found", devices_dev->bus, busfile->file); + return 0; + } + } + } + if (found == 0) { + if (error) + *error = "unknown bus"; + info("error: unknown bus, please report to " + " '%s'", devices_dev->bus); + return -1; + } + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + + dbg("error: getting bus '%s' specific file '%s'", devices_dev->bus, busfile->file); + if (error) + *error = "bus specific file unavailable"; + return -1; +} + + +struct sysfs_class_device *open_class_device_wait(const char *path) +{ + struct sysfs_class_device *class_dev; + int loop; + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + class_dev = sysfs_open_class_device_path(path); + if (class_dev) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + + return (class_dev); +} + +int wait_for_class_device(struct sysfs_class_device *class_dev, + const char **error) +{ + struct sysfs_class_device *class_dev_parent; + struct sysfs_device *devices_dev = NULL; + int loop; + + if (wait_for_class_device_attributes(class_dev, error) != 0) + return -ENOENT; + + /* skip devices without devices-link */ + if (class_device_expect_no_device_link(class_dev)) { + dbg("no device symlink expected for '%s', ", class_dev->name); + return -ENODEV; + } + + /* the symlink may be on the parent device */ + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent) + dbg("looking at parent device for device link '%s'", class_dev_parent->path); + + /* wait for the symlink to the devices device */ + dbg("waiting for symlink to devices device"); + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + if (class_dev_parent) + devices_dev = sysfs_get_classdev_device(class_dev_parent); + else + devices_dev = sysfs_get_classdev_device(class_dev); + + if (devices_dev) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + if (!devices_dev) { + dbg(" error: no devices device symlink found"); + if (error) + *error = "no device symlink"; + return -ENODEV; + } + dbg("device symlink found pointing to '%s'", devices_dev->path); + + /* wait for the bus value */ + if (class_device_expect_no_bus(class_dev)) { + dbg("no bus device expected for '%s', ", class_dev->classname); + return 0; + } else { + return wait_for_bus_device(devices_dev, error); + } +} + +struct sysfs_device *open_devices_device_wait(const char *path) +{ + struct sysfs_device *devices_dev; + int loop; + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + devices_dev = sysfs_open_device_path(path); + if (devices_dev) + break; + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + + return(devices_dev); +} diff --git a/udev_sysfs.h b/udev_sysfs.h new file mode 100644 index 0000000000..922db1be79 --- /dev/null +++ b/udev_sysfs.h @@ -0,0 +1,36 @@ +/* + * udev_sysfs.h + * + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2004 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. + * + * 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 _UDEV_SYSFS_H_ +#define _UDEV_SYSFS_H_ + +#include "libsysfs/sysfs/libsysfs.h" + +#define WAIT_MAX_SECONDS 5 +#define WAIT_LOOP_PER_SECOND 20 + +extern int subsystem_expect_no_dev(const char *subsystem); +extern int wait_for_bus_device(struct sysfs_device *devices_dev, const char **error); +extern int wait_for_class_device(struct sysfs_class_device *class_dev, const char **error); +extern struct sysfs_class_device *open_class_device_wait(const char *path); +extern struct sysfs_device *open_devices_device_wait(const char *path); + +#endif /* _UDEV_SYSFS_H_ */ diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 45f84606b1..e7eed441ee 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -34,12 +34,9 @@ #include "logging.h" #include "udev_version.h" +#include "udev_sysfs.h" #include "libsysfs/sysfs/libsysfs.h" -#ifndef FILENAME_MAX -#define FILENAME_MAX 4096 -#endif - #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) @@ -52,336 +49,6 @@ void log_message(int level, const char *format, ...) } #endif -#define WAIT_MAX_SECONDS 5 -#define WAIT_LOOP_PER_SECOND 20 - -/* wait for specific file to show up, normally the "dev"-file */ -static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev, - const char **error) -{ - static struct class_file { - char *subsystem; - char *file; - } class_files[] = { - { .subsystem = "net", .file = "ifindex" }, - { .subsystem = "scsi_host", .file = "unique_id" }, - { .subsystem = "scsi_device", .file = NULL }, - { .subsystem = "pcmcia_socket", .file = "card_type" }, - { .subsystem = "usb_host", .file = NULL }, - { .subsystem = "bluetooth", .file = "address" }, - { .subsystem = "firmware", .file = "data" }, - { .subsystem = "i2c-adapter", .file = NULL }, - { .subsystem = "pci_bus", .file = NULL }, - { .subsystem = "ieee1394", .file = NULL }, - { .subsystem = "ieee1394_host", .file = NULL }, - { .subsystem = "ieee1394_node", .file = NULL }, - { NULL, NULL } - }; - struct class_file *classfile; - char *file = "dev"; - char filename[FILENAME_MAX]; - int loop; - - /* look if we want to look for another file instead of "dev" */ - for (classfile = class_files; classfile->subsystem != NULL; classfile++) { - if (strcmp(class_dev->classname, classfile->subsystem) == 0) { - if (classfile->file == NULL) { - dbg("class '%s' has no file to wait for", class_dev->classname); - return 0; - } - file = classfile->file; - break; - } - } - - strcpy(filename, class_dev->path); - strcat(filename, "/"); - strcat(filename, file); - dbg("looking at class '%s' for specific file '%s' with full name %s", class_dev->classname, class_dev->path, filename); - - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - struct stat stats; - - if (stat(class_dev->path, &stats) == -1) { - dbg("'%s' now disappeared (probably remove has beaten us)", class_dev->path); - return -ENODEV; - } - - if (stat(filename, &stats) == 0) { - dbg("class '%s' specific file '%s' found", class_dev->classname, file); - return 0; - } - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - dbg("error: getting class '%s' specific file '%s'", class_dev->classname, file); - *error = "class specific file unavailable"; - return -ENOENT; -} - -/* check if we need to wait for a physical device */ -static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) -{ - /* list of devices without a "device" symlink to the physical device - * if device is set to NULL, no devices in that subsystem has a link */ - static struct class_device { - char *subsystem; - char *device; - } class_device[] = { - { .subsystem = "block", .device = "double" }, - { .subsystem = "block", .device = "nb" }, - { .subsystem = "block", .device = "ram" }, - { .subsystem = "block", .device = "loop" }, - { .subsystem = "block", .device = "fd" }, - { .subsystem = "block", .device = "md" }, - { .subsystem = "block", .device = "dos_cd" }, - { .subsystem = "block", .device = "rflash" }, - { .subsystem = "block", .device = "rom" }, - { .subsystem = "block", .device = "rrom" }, - { .subsystem = "block", .device = "flash" }, - { .subsystem = "block", .device = "msd" }, - { .subsystem = "block", .device = "sbpcd" }, - { .subsystem = "block", .device = "pcd" }, - { .subsystem = "block", .device = "pf" }, - { .subsystem = "block", .device = "scd" }, - { .subsystem = "block", .device = "ubd" }, - { .subsystem = "block", .device = "dm-" }, - { .subsystem = "input", .device = "event" }, - { .subsystem = "input", .device = "mice" }, - { .subsystem = "input", .device = "mouse" }, - { .subsystem = "input", .device = "ts" }, - { .subsystem = "vc", .device = NULL }, - { .subsystem = "tty", .device = NULL }, - { .subsystem = "cpuid", .device = "cpu" }, - { .subsystem = "graphics", .device = "fb" }, - { .subsystem = "mem", .device = NULL }, - { .subsystem = "misc", .device = NULL }, - { .subsystem = "msr", .device = NULL }, - { .subsystem = "netlink", .device = NULL }, - { .subsystem = "net", .device = "sit" }, - { .subsystem = "net", .device = "lo" }, - { .subsystem = "net", .device = "tap" }, - { .subsystem = "net", .device = "ipsec" }, - { .subsystem = "net", .device = "dummy" }, - { .subsystem = "net", .device = "irda" }, - { .subsystem = "net", .device = "ppp" }, - { .subsystem = "ppp", .device = NULL }, - { .subsystem = "sound", .device = NULL }, - { .subsystem = "printer", .device = "lp" }, - { .subsystem = "nvidia", .device = NULL }, - { .subsystem = "video4linux", .device = "vbi" }, - { .subsystem = "lirc", .device = NULL }, - { .subsystem = "firmware", .device = NULL }, - { .subsystem = "drm", .device = NULL }, - { .subsystem = "pci_bus", .device = NULL }, - { .subsystem = "ieee1394", .device = NULL }, - { .subsystem = "ieee1394_host", .device = NULL }, - { .subsystem = "ieee1394_node", .device = NULL }, - { .subsystem = "raw", .device = NULL }, - { NULL, NULL } - }; - struct class_device *classdevice; - int len; - - for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) { - if (strcmp(class_dev->classname, classdevice->subsystem) == 0) { - /* see if no device in this class is expected to have a device-link */ - if (classdevice->device == NULL) - return 1; - - len = strlen(classdevice->device); - - /* see if device name matches */ - if (strncmp(class_dev->name, classdevice->device, len) != 0) - continue; - - /* exact name match */ - if (strlen(class_dev->name) == len) - return 1; - - /* name match with instance number */ - if (isdigit(class_dev->name[len])) - return 1; - } - } - - return 0; -} - -/* skip waiting for the bus */ -static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) -{ - static char *devices_without_bus[] = { - "scsi_host", - "i2c-adapter", - NULL - }; - char **device; - - for (device = devices_without_bus; *device != NULL; device++) { - int len = strlen(*device); - - if (strncmp(class_dev->classname, *device, len) == 0) - return 1; - } - - return 0; -} - -/* wait for the bus and for a bus specific file to show up */ -static int wait_for_bus_device(struct sysfs_device *devices_dev, - const char **error) -{ - static struct bus_file { - char *bus; - char *file; - } bus_files[] = { - { .bus = "scsi", .file = "vendor" }, - { .bus = "usb", .file = "idVendor" }, - { .bus = "usb", .file = "iInterface" }, - { .bus = "usb", .file = "bNumEndpoints" }, - { .bus = "usb-serial", .file = "detach_state" }, - { .bus = "ide", .file = "detach_state" }, - { .bus = "pci", .file = "vendor" }, - { .bus = "platform", .file = "detach_state" }, - { .bus = "i2c", .file = "detach_state" }, - { NULL } - }; - struct bus_file *busfile; - int loop; - - /* wait for the bus device link to the devices device */ - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - if (sysfs_get_device_bus(devices_dev) == 0) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - if (loop == 0) { - dbg("error: getting bus device link"); - *error = "no bus device link"; - return -1; - } - dbg("bus device link found for bus '%s'", devices_dev->bus); - - /* wait for a bus specific file to show up */ - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - int found = 0; - - for (busfile = bus_files; busfile->bus != NULL; busfile++) { - if (strcmp(devices_dev->bus, busfile->bus) == 0) { - found = 1; - dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, busfile->file); - if (sysfs_get_device_attr(devices_dev, busfile->file) != NULL) { - dbg("bus '%s' specific file '%s' found", devices_dev->bus, busfile->file); - return 0; - } - } - } - if (found == 0) { - *error = "unknown bus"; - info("error: unknown bus, please report to " - " '%s'", devices_dev->bus); - return -1; - } - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - dbg("error: getting bus '%s' specific file '%s'", devices_dev->bus, busfile->file); - *error = "bus specific file unavailable"; - return -1; -} - - -static struct sysfs_class_device *open_class_device(const char *path) -{ - struct sysfs_class_device *class_dev; - int loop; - - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - class_dev = sysfs_open_class_device_path(path); - if (class_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - return (class_dev); -} - -static int wait_for_class_device(struct sysfs_class_device *class_dev, - const char **error) -{ - struct sysfs_class_device *class_dev_parent; - struct sysfs_device *devices_dev = NULL; - int loop; - - if (wait_for_class_device_attributes(class_dev, error) != 0) - return -ENOENT; - - /* skip devices without devices-link */ - if (class_device_expect_no_device_link(class_dev)) { - dbg("no device symlink expected for '%s', ", class_dev->name); - return -ENODEV; - } - - /* the symlink may be on the parent device */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent) - dbg("looking at parent device for device link '%s'", class_dev_parent->path); - - /* wait for the symlink to the devices device */ - dbg("waiting for symlink to devices device"); - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - if (class_dev_parent) - devices_dev = sysfs_get_classdev_device(class_dev_parent); - else - devices_dev = sysfs_get_classdev_device(class_dev); - - if (devices_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - if (!devices_dev) { - dbg(" error: no devices device symlink found"); - *error = "no device symlink"; - return -ENODEV; - } - dbg("device symlink found pointing to '%s'", devices_dev->path); - - /* wait for the bus value */ - if (class_device_expect_no_bus(class_dev)) { - dbg("no bus device expected for '%s', ", class_dev->classname); - return 0; - } else { - return wait_for_bus_device(devices_dev, error); - } -} - -static struct sysfs_device *open_devices_device(const char *path) -{ - struct sysfs_device *devices_dev; - int loop; - - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - devices_dev = sysfs_open_device_path(path); - if (devices_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - return(devices_dev); -} - int main(int argc, char *argv[], char *envp[]) { const char *devpath = ""; @@ -433,7 +100,7 @@ int main(int argc, char *argv[], char *envp[]) filename[SYSFS_PATH_MAX-1] = '\0'; /* open the class device we are called for */ - class_dev = open_class_device(filename); + class_dev = open_class_device_wait(filename); if (!class_dev) { dbg("error: class device unavailable (probably remove has beaten us)"); goto exit; @@ -450,7 +117,7 @@ int main(int argc, char *argv[], char *envp[]) filename[SYSFS_PATH_MAX-1] = '\0'; /* open the path we are called for */ - devices_dev = open_devices_device(filename); + devices_dev = open_devices_device_wait(filename); if (!devices_dev) { dbg("error: devices device unavailable (probably remove has beaten us)"); goto exit; From 1ad9a8c1b8479d88f2e83fc21c2b5d2d366932f1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 23 Oct 2004 12:12:28 +0200 Subject: [PATCH 0936/4284] [PATCH] switch wait for bus_file to stat() instead of open() --- udev_sysfs.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index 624f53586f..d849a8eba7 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -93,10 +93,8 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev return 0; } - strcpy(filename, class_dev->path); - strcat(filename, "/"); - strcat(filename, file); - dbg("looking at class '%s' for specific file '%s' with full name %s", class_dev->classname, file, filename); + snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", class_dev->path, file); + dbg("looking at class '%s' for specific file '%s'", class_dev->classname, filename); loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { @@ -167,6 +165,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "dummy" }, { .subsystem = "net", .device = "irda" }, { .subsystem = "net", .device = "ppp" }, + { .subsystem = "net", .device = "tun" }, { .subsystem = "ppp", .device = NULL }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, @@ -247,7 +246,10 @@ int wait_for_bus_device(struct sysfs_device *devices_dev, { .bus = "pci", .file = "vendor" }, { .bus = "platform", .file = "detach_state" }, { .bus = "i2c", .file = "detach_state" }, - { NULL } + { .bus = "ieee1394", .file = "node_count" }, + { .bus = "ieee1394", .file = "nodeid" }, + { .bus = "ieee1394", .file = "address" }, + { NULL, NULL } }; struct bus_file *busfile; int loop; @@ -271,19 +273,24 @@ int wait_for_bus_device(struct sysfs_device *devices_dev, /* wait for a bus specific file to show up */ loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { - int found = 0; + int found_bus_type = 0; for (busfile = bus_files; busfile->bus != NULL; busfile++) { if (strcmp(devices_dev->bus, busfile->bus) == 0) { - found = 1; - dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, busfile->file); - if (sysfs_get_device_attr(devices_dev, busfile->file) != NULL) { + char filename[SYSFS_PATH_MAX]; + struct stat stats; + + found_bus_type = 1; + snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, busfile->file); + dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, filename); + + if (stat(filename, &stats) == 0) { dbg("bus '%s' specific file '%s' found", devices_dev->bus, busfile->file); return 0; } } } - if (found == 0) { + if (found_bus_type == 0) { if (error) *error = "unknown bus"; info("error: unknown bus, please report to " From 21d2888a0a0d238594e4124fe8020f54bfa29df5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 23 Oct 2004 12:13:01 +0200 Subject: [PATCH 0937/4284] [PATCH] add net/pan and net/bnep handling --- udev_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index d849a8eba7..7fc1099ee5 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -166,6 +166,8 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "irda" }, { .subsystem = "net", .device = "ppp" }, { .subsystem = "net", .device = "tun" }, + { .subsystem = "net", .device = "pan" }, + { .subsystem = "net", .device = "bnep" }, { .subsystem = "ppp", .device = NULL }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, From ab51035617d5725305b8ef98eff6b7c64f3ccec6 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 23 Oct 2004 12:15:22 +0200 Subject: [PATCH 0938/4284] [PATCH] skip waiting for device if we get a bad event for class creation --- wait_for_sysfs.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index e7eed441ee..91a2b6b628 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -99,6 +99,12 @@ int main(int argc, char *argv[], char *envp[]) snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_mnt_path, devpath); filename[SYSFS_PATH_MAX-1] = '\0'; + /* skip bad events where we get no device for the class */ + if (strncmp(devpath, "/class/", 7) == 0 && strchr(&devpath[7], '/') == NULL) { + dbg("no device name for '%s', bad event", devpath); + goto exit; + } + /* open the class device we are called for */ class_dev = open_class_device_wait(filename); if (!class_dev) { From 5cab7caa2a767b16211c15f0051a2e21a96ebfd9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 19 Oct 2004 04:37:30 -0700 Subject: [PATCH 0939/4284] [PATCH] cleanup udevd/udevstart Change to the same timeout loop we use in the rest of the code. Change some comments and names to be more descriptive. I'm mostly finished with the overall cleanup. I will post a new patch for the udevd-nofork experiment, which will be much smaller now. --- udevd.c | 52 ++++++++++++++++++++++++---------------------------- udevd.h | 4 +++- udevsend.c | 15 ++++++--------- 3 files changed, 33 insertions(+), 38 deletions(-) diff --git a/udevd.c b/udevd.c index 9e0f71b583..c5267d6d9f 100644 --- a/udevd.c +++ b/udevd.c @@ -46,7 +46,7 @@ static int pipefds[2]; static unsigned long long expected_seqnum = 0; -static volatile int children_waiting; +static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int sig_flag; static int run_exec_q; @@ -58,7 +58,7 @@ static LIST_HEAD(running_list); static void exec_queue_manager(void); static void msg_queue_manager(void); static void user_sighandler(void); -static void reap_kids(void); +static void reap_sigchilds(void); char *udev_bin; #ifdef LOG @@ -325,7 +325,7 @@ static void asmlinkage sig_handler(int signum) break; case SIGCHLD: /* set flag, then write to pipe if needed */ - children_waiting = 1; + sigchilds_waiting = 1; goto do_write; break; default: @@ -366,9 +366,8 @@ static void udev_done(int pid) } } -static void reap_kids(void) +static void reap_sigchilds(void) { - /* reap all dead children */ while(1) { int pid = waitpid(-1, NULL, WNOHANG); if ((pid == -1) || (pid == 0)) @@ -378,13 +377,13 @@ static void reap_kids(void) } /* just read everything from the pipe and clear the flag, - * the useful flags were set in the signal handler + * the flags was set in the signal handler */ static void user_sighandler(void) { int sig; while(1) { - int rc = read(pipefds[0],&sig,sizeof(sig)); + int rc = read(pipefds[0], &sig, sizeof(sig)); if (rc < 0) break; @@ -392,14 +391,13 @@ static void user_sighandler(void) } } - -int main(int argc, char *argv[]) +int main(int argc, char *argv[], char *envp[]) { int ssock, maxsockplus; struct sockaddr_un saddr; socklen_t addrlen; int retval, fd; - const int on = 1; + const int feature_on = 1; struct sigaction act; fd_set readfds; @@ -408,11 +406,13 @@ int main(int argc, char *argv[]) if (getuid() != 0) { dbg("need to be root, exit"); - exit(1); + _exit(1); } - /* make sure we are at top of dir */ + + /* make sure we don't lock any path */ chdir("/"); - umask( umask( 077 ) | 022 ); + umask(umask(077) | 022); + /* Set fds to dev/null */ fd = open( "/dev/null", O_RDWR ); if ( fd < 0 ) { @@ -424,7 +424,8 @@ int main(int argc, char *argv[]) dup2(fd, 2); if (fd > 2) close(fd); - /* Get new session id so stray signals don't come our way. */ + + /* become session leader */ setsid(); /* setup signal handler pipe */ @@ -456,7 +457,6 @@ int main(int argc, char *argv[]) exit(1); } - /* set signal handlers */ act.sa_handler = (void (*) (int))sig_handler; sigemptyset(&act.sa_mask); @@ -493,7 +493,7 @@ int main(int argc, char *argv[]) } /* enable receiving of the sender credentials */ - setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); + setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); /* possible override of udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); @@ -522,9 +522,9 @@ int main(int argc, char *argv[]) if (FD_ISSET(pipefds[0], &workreadfds)) user_sighandler(); - if (children_waiting) { - children_waiting = 0; - reap_kids(); + if (sigchilds_waiting) { + sigchilds_waiting = 0; + reap_sigchilds(); } if (run_msg_q) { @@ -533,14 +533,10 @@ int main(int argc, char *argv[]) } if (run_exec_q) { - /* this is tricky. exec_queue_manager() loops over exec_list, and - * calls running_with_devpath(), which loops over running_list. This gives - * O(N*M), which can get *nasty*. Clean up running_list before - * calling exec_queue_manager(). - */ - if (children_waiting) { - children_waiting = 0; - reap_kids(); + /* clean up running_list before calling exec_queue_manager() */ + if (sigchilds_waiting) { + sigchilds_waiting = 0; + reap_sigchilds(); } run_exec_q = 0; @@ -550,5 +546,5 @@ int main(int argc, char *argv[]) exit: close(ssock); logging_close(); - exit(1); + return 1; } diff --git a/udevd.h b/udevd.h index 9be581d420..657f684e3f 100644 --- a/udevd.h +++ b/udevd.h @@ -26,8 +26,10 @@ #define UDEV_MAGIC "udevd_" UDEV_VERSION #define EVENT_TIMEOUT_SEC 10 -#define UDEVSEND_CONNECT_RETRY 20 /* x 100 millisec */ #define UDEVD_SOCK_PATH "udevd" +#define SEND_WAIT_MAX_SECONDS 3 +#define SEND_WAIT_LOOP_PER_SECOND 10 + struct hotplug_msg { char magic[20]; diff --git a/udevsend.c b/udevsend.c index 883181c1b6..84c46bc0c2 100644 --- a/udevsend.c +++ b/udevsend.c @@ -95,9 +95,9 @@ static void run_udev(const char *subsystem) switch (pid) { case 0: /* child */ - execl(UDEV_BIN, "udev", subsystem, NULL); + execl(UDEV_BIN, UDEV_BIN, subsystem, NULL); dbg("exec of child failed"); - exit(1); + _exit(1); break; case -1: dbg("fork of child failed"); @@ -117,7 +117,6 @@ int main(int argc, char* argv[]) unsigned long long seq; int retval = 1; int loop; - struct timespec tspec; int sock = -1; struct sockaddr_un saddr; socklen_t addrlen; @@ -176,8 +175,8 @@ int main(int argc, char* argv[]) strfieldcpy(msg.subsystem, subsystem); /* If we can't send, try to start daemon and resend message */ - loop = UDEVSEND_CONNECT_RETRY; - while (loop--) { + loop = SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND; + while (--loop) { retval = sendto(sock, &msg, sizeof(struct hotplug_msg), 0, (struct sockaddr *)&saddr, addrlen); if (retval != -1) { @@ -200,10 +199,8 @@ int main(int argc, char* argv[]) dbg("daemon started"); started_daemon = 1; } else { - dbg("retry to connect %d", UDEVSEND_CONNECT_RETRY - loop); - tspec.tv_sec = 0; - tspec.tv_nsec = 100000000; /* 100 millisec */ - nanosleep(&tspec, NULL); + dbg("retry to connect %d", SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND - loop); + usleep(1000 * 1000 / SEND_WAIT_LOOP_PER_SECOND); } } From f8c1ccde6aaf08c858616c9a8a83c06d609f52f5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 20 Oct 2004 11:59:11 +0200 Subject: [PATCH 0940/4284] [PATCH] improve klibc fixup integration --- Makefile | 25 +++---- klibc_fixups.h | 66 ------------------- klibc_fixups.c => klibc_fixups/klibc_fixups.c | 11 ++-- klibc_fixups/klibc_fixups.h | 12 ++++ klibc_fixups/pwd.h | 27 ++++++++ namedev.c | 1 - udev_add.c | 4 -- udevd.c | 1 - 8 files changed, 58 insertions(+), 89 deletions(-) delete mode 100644 klibc_fixups.h rename klibc_fixups.c => klibc_fixups/klibc_fixups.c (95%) create mode 100644 klibc_fixups/klibc_fixups.h create mode 100644 klibc_fixups/pwd.h diff --git a/Makefile b/Makefile index 4d25aee73e..19dc72d952 100644 --- a/Makefile +++ b/Makefile @@ -137,6 +137,7 @@ endif # link udev against it statically. # Otherwise, use glibc and link dynamically. ifeq ($(strip $(USE_KLIBC)),true) + KLIBC_FIXUPS_DIR= $(PWD)/klibc_fixups KLIBC_BASE = $(PWD)/klibc KLIBC_DIR = $(KLIBC_BASE)/klibc INCLUDE_DIR := $(KLIBC_BASE)/include @@ -149,13 +150,15 @@ ifeq ($(strip $(USE_KLIBC)),true) CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) - CFLAGS += $(WARNINGS) -nostdinc \ - $(OPTFLAGS) \ - -D__KLIBC__ -fno-builtin-printf \ - -I$(INCLUDE_DIR) \ - -I$(INCLUDE_DIR)/arch/$(ARCH) \ - -I$(INCLUDE_DIR)/bits$(BITSIZE) \ - -I$(GCCINCDIR) \ + CFLAGS += $(WARNINGS) -nostdinc \ + $(OPTFLAGS) \ + -D__KLIBC__ -fno-builtin-printf \ + -I$(KLIBC_FIXUPS_DIR) \ + -include $(KLIBC_FIXUPS_DIR)/klibc_fixups.h \ + -I$(INCLUDE_DIR) \ + -I$(INCLUDE_DIR)/arch/$(ARCH) \ + -I$(INCLUDE_DIR)/bits$(BITSIZE) \ + -I$(GCCINCDIR) \ -I$(LINUX_INCLUDE_DIR) LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs @@ -226,14 +229,14 @@ HEADERS = udev.h \ udev_version.h \ udevdb.h \ udev_sysfs.h \ - klibc_fixups.h \ logging.h \ selinux.h \ - list.h + list.h \ + klibc_fixups/klibc_fixups.h ifeq ($(strip $(USE_KLIBC)),true) - OBJS += klibc_fixups.o - KLIBC_FIXUP = klibc_fixups.o + OBJS += klibc_fixups/klibc_fixups.o + KLIBC_FIXUP = klibc_fixups/klibc_fixups.o endif ifeq ($(strip $(V)),false) diff --git a/klibc_fixups.h b/klibc_fixups.h deleted file mode 100644 index 082105eb8e..0000000000 --- a/klibc_fixups.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifdef __KLIBC__ - -#ifndef KLIBC_FIXUPS_H -#define KLIBC_FIXUPS_H - -struct passwd { - char *pw_name; /* user name */ - char *pw_passwd; /* user password */ - uid_t pw_uid; /* user id */ - gid_t pw_gid; /* group id */ - char *pw_gecos; /* real name */ - char *pw_dir; /* home directory */ - char *pw_shell; /* shell program */ -}; - -struct group { - char *gr_name; /* group name */ - char *gr_passwd; /* group password */ - gid_t gr_gid; /* group id */ - char **gr_mem; /* group members */ -}; - -struct passwd *getpwnam(const char *name); -struct group *getgrnam(const char *name); - - -#define UT_LINESIZE 32 -#define UT_NAMESIZE 32 -#define UT_HOSTSIZE 256 -#define USER_PROCESS 7 /* normal process */ -#define ut_time ut_tv.tv_sec - - -extern int ufd; - -struct exit_status { - short int e_termination; /* process termination status */ - short int e_exit; /* process exit status */ -}; - -struct utmp -{ - short int ut_type; /* type of login */ - pid_t ut_pid; /* pid of login process */ - char ut_line[UT_LINESIZE]; /* devicename */ - char ut_id[4]; /* Inittab id */ - char ut_user[UT_NAMESIZE]; /* username */ - char ut_host[UT_HOSTSIZE]; /* hostname for remote login */ - struct exit_status ut_exit; /* exit status of a process marked as DEAD_PROCESS */ - /* The ut_session and ut_tv fields must be the same size for 32 and 64-bit */ -#if __WORDSIZE == 64 && defined __WORDSIZE_COMPAT32 - int32_t ut_session; /* sid used for windowing */ - struct { - int32_t tv_sec; /* seconds */ - int32_t tv_usec; /* microseconds */ - } ut_tv; -#else - long int ut_session; - struct timeval ut_tv; -#endif - int32_t ut_addr_v6[4]; /* internet address of remote host */ - char __unused[20]; /* reserved for future use */ -}; - -#endif /* KLIBC_FIXUPS_H */ -#endif /* __KLIBC__ */ diff --git a/klibc_fixups.c b/klibc_fixups/klibc_fixups.c similarity index 95% rename from klibc_fixups.c rename to klibc_fixups/klibc_fixups.c index e68ce22b50..2d673d8ca9 100644 --- a/klibc_fixups.c +++ b/klibc_fixups/klibc_fixups.c @@ -28,14 +28,13 @@ #include #include -#include "udev.h" -#include "klibc_fixups.h" -#include "udev_lib.h" -#include "logging.h" +#include "pwd.h" +#include "../udev.h" +#include "../udev_lib.h" +#include "../logging.h" #define PW_FILE "/etc/passwd" #define GR_FILE "/etc/group" -#define UTMP_FILE "/var/run/utmp" /* return the id of a passwd style line, selected by the users name */ static unsigned long get_id_by_name(const char *uname, const char *dbfile) @@ -125,4 +124,4 @@ struct group *getgrnam(const char *name) return &gr; } -#endif +#endif /* __KLIBC__ */ diff --git a/klibc_fixups/klibc_fixups.h b/klibc_fixups/klibc_fixups.h new file mode 100644 index 0000000000..8d2933b1b6 --- /dev/null +++ b/klibc_fixups/klibc_fixups.h @@ -0,0 +1,12 @@ +#ifdef __KLIBC__ + +#ifndef _KLIBC_FIXUPS_H +#define _KLIBC_FIXUPS_H + +struct exit_status { + short int e_termination; /* process termination status */ + short int e_exit; /* process exit status */ +}; + +#endif /* KLIBC_FIXUPS_H */ +#endif /* __KLIBC__ */ diff --git a/klibc_fixups/pwd.h b/klibc_fixups/pwd.h new file mode 100644 index 0000000000..f5de6c50b8 --- /dev/null +++ b/klibc_fixups/pwd.h @@ -0,0 +1,27 @@ +#ifdef __KLIBC__ + +#ifndef _PWD_H +#define _PWD_H + +struct passwd { + char *pw_name; /* user name */ + char *pw_passwd; /* user password */ + uid_t pw_uid; /* user id */ + gid_t pw_gid; /* group id */ + char *pw_gecos; /* real name */ + char *pw_dir; /* home directory */ + char *pw_shell; /* shell program */ +}; + +struct group { + char *gr_name; /* group name */ + char *gr_passwd; /* group password */ + gid_t gr_gid; /* group id */ + char **gr_mem; /* group members */ +}; + +struct passwd *getpwnam(const char *name); +struct group *getgrnam(const char *name); + +#endif /* _PWD_H */ +#endif /* __KLIBC__ */ diff --git a/namedev.c b/namedev.c index 03fc41d234..80d5f1a499 100644 --- a/namedev.c +++ b/namedev.c @@ -40,7 +40,6 @@ #include "udev_version.h" #include "logging.h" #include "namedev.h" -#include "klibc_fixups.h" #include "udevdb.h" static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr); diff --git a/udev_add.c b/udev_add.c index 0e7d575d58..689c2dceec 100644 --- a/udev_add.c +++ b/udev_add.c @@ -34,10 +34,7 @@ #include #include #include -#ifndef __KLIBC__ #include -#include -#endif #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" @@ -46,7 +43,6 @@ #include "logging.h" #include "namedev.h" #include "udevdb.h" -#include "klibc_fixups.h" #include "selinux.h" diff --git a/udevd.c b/udevd.c index c5267d6d9f..0150837143 100644 --- a/udevd.c +++ b/udevd.c @@ -33,7 +33,6 @@ #include #include #include -#include "klibc_fixups.h" #include #include From 993a633ab848487b8e546f66087595e2dc5aa4af Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 20 Oct 2004 13:15:26 +0200 Subject: [PATCH 0941/4284] [PATCH] update to libsysfs 1.2.0 and add some stuff klib_fixup --- Makefile | 10 +- klibc_fixups/klibc_fixups.h | 11 ++ klibc_fixups/malloc.h | 9 ++ klibc_fixups/mntent.h | 39 ++++++ libsysfs/dlist.c | 267 +++++++++++++++++++++++++++++++++++- libsysfs/dlist.h | 12 +- libsysfs/sysfs.h | 7 +- libsysfs/sysfs/libsysfs.h | 1 + libsysfs/sysfs_bus.c | 2 +- libsysfs/sysfs_class.c | 2 +- libsysfs/sysfs_device.c | 6 +- libsysfs/sysfs_dir.c | 8 +- libsysfs/sysfs_driver.c | 2 +- libsysfs/sysfs_utils.c | 20 +-- 14 files changed, 365 insertions(+), 31 deletions(-) create mode 100644 klibc_fixups/malloc.h create mode 100644 klibc_fixups/mntent.h diff --git a/Makefile b/Makefile index 19dc72d952..d1a0bfb645 100644 --- a/Makefile +++ b/Makefile @@ -176,7 +176,8 @@ ifeq ($(strip $(USE_SELINUX)),true) LIB_OBJS += -lselinux endif -CFLAGS += -I$(PWD)/libsysfs +CFLAGS += -I$(PWD)/libsysfs/sysfs \ + -I$(PWD)/libsysfs # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf @@ -231,10 +232,13 @@ HEADERS = udev.h \ udev_sysfs.h \ logging.h \ selinux.h \ - list.h \ - klibc_fixups/klibc_fixups.h + list.h ifeq ($(strip $(USE_KLIBC)),true) + HEADERS += klibc_fixups/klibc_fixups.h \ + klibc_fixups/mntent.h \ + klibc_fixups/pwd.h + OBJS += klibc_fixups/klibc_fixups.o KLIBC_FIXUP = klibc_fixups/klibc_fixups.o endif diff --git a/klibc_fixups/klibc_fixups.h b/klibc_fixups/klibc_fixups.h index 8d2933b1b6..a39ec42e5f 100644 --- a/klibc_fixups/klibc_fixups.h +++ b/klibc_fixups/klibc_fixups.h @@ -3,6 +3,17 @@ #ifndef _KLIBC_FIXUPS_H #define _KLIBC_FIXUPS_H +#include + +#define _SC_PAGESIZE 0x66 +static inline long int sysconf(int name) +{ + if (name == _SC_PAGESIZE) + return getpagesize(); + + return -1; +} + struct exit_status { short int e_termination; /* process termination status */ short int e_exit; /* process exit status */ diff --git a/klibc_fixups/malloc.h b/klibc_fixups/malloc.h new file mode 100644 index 0000000000..439608e3c4 --- /dev/null +++ b/klibc_fixups/malloc.h @@ -0,0 +1,9 @@ +#ifdef __KLIBC__ + +#ifndef _MALLOC_H +#define _MALLOC_H + +#include + +#endif /* _MALLOC_H */ +#endif /* __KLIBC__ */ diff --git a/klibc_fixups/mntent.h b/klibc_fixups/mntent.h new file mode 100644 index 0000000000..ea79a2dd63 --- /dev/null +++ b/klibc_fixups/mntent.h @@ -0,0 +1,39 @@ +#ifdef __KLIBC__ + +#ifndef _MNTENT_H +#define _MNTENT_H + +#include + +struct mntent +{ + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; + int mnt_freq; + int mnt_passno; +}; + +static inline FILE *setmntent (const char *file, const char *mode) +{ + return (FILE *) 1; +} + +static inline struct mntent *getmntent (FILE *stream) +{ + static struct mntent mntent = { + .mnt_dir = "/sys", + .mnt_type = "sysfs" + }; + + return &mntent; +} + +static inline int endmntent (FILE *stream) +{ + return 0; +} + +#endif /* _MNTENT_H */ +#endif /* __KLIBC__ */ diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index b440d65bed..5f2c00be9b 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -27,7 +27,6 @@ * delete function. Otherwise dlist will just use free. */ -#include #include "dlist.h" /* @@ -207,6 +206,46 @@ void *dlist_insert(Dlist *list,void *data,int direction) return(list->marker->data); } +/* internal use only + * Insert dl_node at marker. + * If direction true it inserts after. + * If direction false it inserts before. + * move marker to inserted node + * return pointer to inserted node + */ +void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction) +{ + if(list==NULL || new_node==NULL) + return(NULL); + if(list->marker==NULL) //in case the marker ends up unset + list->marker=list->head; + list->count++; + if(list->head->next==NULL) + { + list->head->next=list->head->prev=new_node; + new_node->prev=list->head; + new_node->next=list->head; + } + else if(direction) + { + new_node->next=list->marker->next; + new_node->prev=list->marker; + list->marker->next->prev=new_node; + list->marker->next=new_node; + } + else + { + new_node->prev=list->marker->prev; + new_node->next=list->marker; + list->marker->prev->next=new_node; + list->marker->prev=new_node; + } + list->marker=new_node; + return(list->marker); +} + + + /* * Remove DL_node from list without deallocating data. * if marker == killme . @@ -239,6 +278,54 @@ void *_dlist_remove(Dlist *list,DL_node *killme,int direction) return (NULL); } +/* + * move dl_node from source to dest + * if marker == target . + * when direction true it moves marker after + * when direction false it moves marker before. + * to previous if there is no next. + */ +void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction) +{ + + if(target!=NULL) + { + if(target==source->head) + { + //not even going to try + } + else + { + // take care of head and marker pointers. + if(source->marker==target) + _dlist_mark_move(source,direction); + if(target ==source->head->next) + source->head->next=target->next; + if(target==source->head->prev) + source->head->prev=target->prev; + // remove from list + if(source->count==1) + { + target->prev=NULL; + target->next=NULL; + source->head->next=NULL; + source->head->prev=NULL; + } + else + { + if(target->prev !=NULL) + target->prev->next=target->next; + if(target->next !=NULL) + target->next->prev=target->prev; + target->prev=NULL; + target->next=NULL; + } + source->count--; + _dlist_insert_dlnode(dest,target,direction); + } + } +} + /* * Insert node containing data after end. @@ -261,7 +348,7 @@ void dlist_unshift(Dlist *list,void *data) } void dlist_unshift_sorted(Dlist *list, void *data, - int (*sorter)(void *new, void *old)) + int (*sorter)(void *new_elem, void *old_elem)) { if (list->count == 0) dlist_unshift(list, data); @@ -352,3 +439,179 @@ void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, v list->marker!=list->head && !sorter(new,list->marker->data);dlist_next(list)); return(dlist_insert_before(list,new)); } + +/* + * NOTE: internal use only + */ +int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)) +{ + + struct dl_node *l1head; + struct dl_node *l2head; + struct dl_node *target; + unsigned int l1count=0; + unsigned int l2count=0; + unsigned int mergecount=0; + while(listsource->count>0) + { + l1head=listsource->head->next; + l2head=l1head; + while((l1counthead)) + { + l2head=l2head->next; + l1count++; + } + // so now we have two lists to merge + + if(l2head==listsource->head) + {// l2count + l2count=0; + } + else + { + l2count=passcount; + } + while(l1count>0 || l2count>0) + { + mergecount++; + if((l2count>0)&&(l1count>0)) + { + // we have things to merge + int result=compare(l1head->data,l2head->data); + if(result>0) + { + // move from l2 + target=l2head; + l2head=l2head->next; + dlist_move(listsource,listdest,target,1); + l2count--; + if(l2head==listsource->head) + l2count=0; + } + else + { + // move from l1 + target=l1head; + l1head=l1head->next; + dlist_move(listsource,listdest,target,1); + l1count--; + } + } + else if(l1count>0) + { + // only have l1 to work with + while(l1count>0) + { + target=l1head; + l1head=l1head->next; + dlist_move(listsource,listdest,target,1); + l1count--; + } + } + else if(l2count>0) + { + // only have l2 to work with + while(l2count>0) + { + if(l2head==listsource->head) + { + l2count=0; + } + else + { + target=l2head; + l2head=l2head->next; + dlist_move(listsource,listdest,target,1); + l2count--; + } + } + } + else + { //nothing left and this should be unreachable + } + } + } + return(mergecount); +} + +/** + * mergesort the list based on compare + * compare function in form int sorter(void * a,void * b) + * must return >0 for a after b + * must return <0 for a before b + * else 0 + + * NOTE: mergesort changes the mark pointer + */ +void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)) +{ + + dlist_start(list); + struct dlist *listsource, *listdest, *swap; + struct dlist *templist = dlist_new(list->data_size); + unsigned int passcount = 1; + unsigned int mergecount = 1; + // do nothing if there isn't anything to sort + listsource = list; + listdest = templist; + if(listsource->count<2) + { //nothing to do + return; + } + else + { + while(mergecount>0) + { + mergecount=_dlist_merge(listsource, listdest, passcount, compare); + if(mergecount>1) + { + passcount=passcount*2; + //start new pass + swap=listsource; + listsource=listdest; + listdest=swap; + } + } + } + // now put the input list pointers right + // list pointers = newlist pointers + // including the forward and next nodes prev and back pointers + if(list->count==0) + {//copy + list->marker = listdest->marker; + list->count = listdest->count; + list->data_size = listdest->data_size; + list->del_func = listdest->del_func; + list->head->prev = listdest->head->prev; + list->head->next = listdest->head->next; + list->head->data = listdest->head->data; + list->head->next->prev=list->head; + list->head->prev->next=list->head; + templist->head->next=NULL; + templist->head->prev=NULL; + templist->count=0; + } + else + {// no need to copy + + } + + dlist_destroy(templist); +} + + + +/* internal use function + swaps elements a and b + No sense in juggling node pointers when we can just swap the data pointers +*/ + +void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b) +{ + + void *swap=a->data; + a->data=b->data; + b->data=swap; + +} + diff --git a/libsysfs/dlist.h b/libsysfs/dlist.h index 7fc90e5bf5..9e3a6c96de 100644 --- a/libsysfs/dlist.h +++ b/libsysfs/dlist.h @@ -52,6 +52,7 @@ * to think about it. */ +#include typedef struct dl_node { struct dl_node *prev; struct dl_node *next; @@ -73,7 +74,7 @@ void *_dlist_mark_move(Dlist *list,int direction); void *dlist_mark(Dlist *); void dlist_start(Dlist *); void dlist_end(Dlist *); - +void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction); void *dlist_insert(Dlist *,void *,int) ; void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *)); @@ -91,7 +92,15 @@ void *dlist_shift(Dlist *); void dlist_destroy(Dlist *); +int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)); + void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)); + +void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)); + + +void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b); + void dlist_transform(struct dlist *list, void (*node_operation)(void *)); @@ -100,6 +109,7 @@ void dlist_transform(struct dlist *list, void (*node_operation)(void *)); * _dlist_mark_move is for internal use only */ void *_dlist_remove(struct dlist *,struct dl_node *,int ); +void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction); #define dlist_prev(A) _dlist_mark_move((A),0) #define dlist_next(A) _dlist_mark_move((A),1) diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 7ac6efc678..1e58e8abb4 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -27,15 +27,18 @@ #include #include #include +#include #include #include #include #include -#include "dlist.h" + +/* external library functions */ +extern int isascii(int c); /* Debugging */ #ifdef DEBUG -#include "../logging.h" +#include "../logging.h" #define dprintf(format, arg...) dbg(format, ##arg) #else #define dprintf(format, arg...) do { } while (0) diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index 11cffae045..29194f61a6 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -25,6 +25,7 @@ #include #include +#include "dlist.h" /* * Defines to prevent buffer overruns diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c index 9ca23c85d8..d47b94ca24 100644 --- a/libsysfs/sysfs_bus.c +++ b/libsysfs/sysfs_bus.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" static void sysfs_close_dev(void *dev) diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 59ef0be48e..db59aef90f 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" static void sysfs_close_cls_dev(void *dev) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 290fd9723e..f2f8d2d611 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" /** @@ -502,7 +502,7 @@ struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, * @psize: size of "path" * Returns 0 on success -1 on failure */ -static int get_device_absolute_path(const char *device, const char *bus, +static int get_device_absolute_path(const char *device, const char *bus, char *path, size_t psize) { char bus_path[SYSFS_PATH_MAX]; @@ -547,7 +547,7 @@ static int get_device_absolute_path(const char *device, const char *bus, * 2. Bus the device is on must be supplied * Use sysfs_find_device_bus to get the bus name */ -struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) +struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) { char sysfs_path[SYSFS_PATH_MAX]; struct sysfs_device *device = NULL; diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index 8ce8522200..52769916cc 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" /** @@ -273,7 +273,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) errno = EACCES; return -1; } - pgsize = getpagesize(); + pgsize = sysconf(_SC_PAGESIZE); fbuf = (char *)calloc(1, pgsize+1); if (fbuf == NULL) { dprintf("calloc failed\n"); @@ -513,6 +513,7 @@ struct sysfs_link *sysfs_open_link(const char *linkpath) safestrcpy(ln->path, linkpath); if ((sysfs_get_name_from_path(linkpath, ln->name, SYSFS_NAME_LEN)) != 0 || (sysfs_get_link(linkpath, ln->target, SYSFS_PATH_MAX)) != 0) { + sysfs_close_link(ln); errno = EINVAL; dprintf("Invalid link path %s\n", linkpath); return NULL; @@ -884,7 +885,8 @@ struct sysfs_attribute *sysfs_get_directory_attribute attr = (struct sysfs_attribute *)dlist_find_custom (dir->attributes, attrname, dir_attribute_name_equal); if (attr != NULL) { - if ((sysfs_read_attribute(attr)) != 0) { + if ((attr->method & SYSFS_METHOD_SHOW) && + (sysfs_read_attribute(attr)) != 0) { dprintf("Error reading attribute %s\n", attr->name); return NULL; } diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 2439b7a567..88d26b56dd 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -20,7 +20,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" static void sysfs_close_driver_device(void *device) diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index f65e5df3aa..8b1f56ed14 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -20,16 +20,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ -#include "sysfs/libsysfs.h" +#include "libsysfs.h" #include "sysfs.h" -#ifndef __KLIBC__ -#include -#endif -static int sort_char(void *new_elem, void *old_elem) +static int sort_char(void *new, void *old) { - return ((strncmp((char *)new_elem, (char *)old_elem, - strlen((char *)new_elem))) < 0 ? 1 : 0); + return ((strncmp((char *)new, (char *)old, + strlen((char *)new))) < 0 ? 1 : 0); } /** @@ -66,10 +63,6 @@ int sysfs_remove_trailing_slash(char *path) static int sysfs_get_fs_mnt_path(const char *fs_type, char *mnt_path, size_t len) { -#ifdef __KLIBC__ - safestrcpymax(mnt_path, "/sys", len); - return 0; -#else FILE *mnt; struct mntent *mntent; int ret = 0; @@ -106,7 +99,6 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, ret = -1; return ret; -#endif } /* @@ -454,7 +446,7 @@ int sysfs_path_is_link(const char *path) return 1; } if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed"); + dprintf("stat() failed\n"); return 1; } if (S_ISLNK(astats.st_mode)) @@ -477,7 +469,7 @@ int sysfs_path_is_file(const char *path) return 1; } if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed"); + dprintf("stat() failed\n"); return 1; } if (S_ISREG(astats.st_mode)) From f4949c53e66a4a8697b1bd5aa3f8265faf3423b1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 20 Oct 2004 14:13:33 +0200 Subject: [PATCH 0942/4284] [PATCH] Remove the last klibc specific line from the main udev code --- klibc_fixups/klibc_fixups.h | 1 + udev.c | 1 - udevdb.c | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/klibc_fixups/klibc_fixups.h b/klibc_fixups/klibc_fixups.h index a39ec42e5f..13011b6888 100644 --- a/klibc_fixups/klibc_fixups.h +++ b/klibc_fixups/klibc_fixups.h @@ -3,6 +3,7 @@ #ifndef _KLIBC_FIXUPS_H #define _KLIBC_FIXUPS_H +#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #define _SC_PAGESIZE 0x66 diff --git a/udev.c b/udev.c index 5064bbd175..cac60fd932 100644 --- a/udev.c +++ b/udev.c @@ -20,7 +20,6 @@ * */ -#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include #include diff --git a/udevdb.c b/udevdb.c index 23de22751d..6a3357d0bb 100644 --- a/udevdb.c +++ b/udevdb.c @@ -21,7 +21,6 @@ * */ -#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T #include #include #include From 069410dbb4769595f57d6208c4a524b2eaa2659c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 23 Oct 2004 05:44:44 -0700 Subject: [PATCH 0943/4284] [PATCH] add inotify to the rules for gentoo --- etc/udev/udev.permissions.gentoo | 1 + etc/udev/udev.rules.gentoo | 1 + 2 files changed, 2 insertions(+) diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/udev.permissions.gentoo index edd8e39cde..51dd9f290e 100644 --- a/etc/udev/udev.permissions.gentoo +++ b/etc/udev/udev.permissions.gentoo @@ -48,6 +48,7 @@ zero:root:root:0666 # misc devices misc/nvram:root:root:0660 misc/rtc:root:root:0664 +misc/inotify:root:root:0666 # floppy devices fd[01]*:root:floppy:0660 diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index b33df81d25..ffc56ee7e4 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -62,6 +62,7 @@ KERNEL="microcode", NAME="misc/%k", SYMLINK="%k" KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" +KERNEL="inotify", NAME="misc/%k", SYMLINK="%k" # pty devices KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" From 1a04bce13adb853131a5be3eecc79ceab22ced49 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 23 Oct 2004 06:44:29 -0700 Subject: [PATCH 0944/4284] [PATCH] 042 release In the grand tradition of releasing free software projects on my birthday for the past few years. And yes, I skipped version 041, call it grumpyness in my old age... --- ChangeLog | 18 ++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 73d52d46a4..907314150c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +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 ============================================ diff --git a/Makefile b/Makefile index d1a0bfb645..f75721e1f3 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart WAIT = wait_for_sysfs -VERSION = 040 +VERSION = 042 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 9055512332..ac2a874cf0 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 040 +Version: 042 Release: 1 License: GPL Group: Utilities/System From 948736dde7791e19528f829703042c7c843a43ca Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 25 Oct 2004 07:53:15 -0700 Subject: [PATCH 0945/4284] [PATCH] add dumb script to show all sysfs devices in the system. --- test/show_all_devices.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 test/show_all_devices.sh diff --git a/test/show_all_devices.sh b/test/show_all_devices.sh new file mode 100644 index 0000000000..921b8e6163 --- /dev/null +++ b/test/show_all_devices.sh @@ -0,0 +1,27 @@ +#! /bin/bash +# +# Directory where sysfs is mounted +SYSFS_DIR=/sys + +# handle block devices and their partitions +for i in ${SYSFS_DIR}/block/*; do + # each drive + echo ${i#${SYSFS_DIR}/block/} + + # each partition, on each device + for j in $i/*; do + if [ -f $j/dev ]; then + echo ${j#${SYSFS_DIR}} | cut --delimiter='/' --fields=4- + fi + done +done + +# all other device classes +for i in ${SYSFS_DIR}/class/*; do + for j in $i/*; do + if [ -f $j/dev ]; then + echo ${j#${SYSFS_DIR}} | cut --delimiter='/' --fields=4- + fi + done +done + From bd842ba41aba926d5842c350593127594bba5d08 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 28 Oct 2004 10:19:13 -0500 Subject: [PATCH 0946/4284] [PATCH] add test target to makefile Will help distros that have a test phase of their build. --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index f75721e1f3..c90baba582 100644 --- a/Makefile +++ b/Makefile @@ -463,3 +463,6 @@ uninstall: uninstall-man uninstall-dev.d $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ -C $$target $@ ; \ done ; \ + +test: all + @ cd test && sudo ./udev-test.pl From 6628a2ea38112451218fc21aec40db6ff7de8d63 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 30 Oct 2004 13:27:36 +0200 Subject: [PATCH 0947/4284] [PATCH] Add net/vmnet and class/zaptel to the list of devices without physical device --- udev_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 7fc1099ee5..95a46a6ecd 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -168,6 +168,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "tun" }, { .subsystem = "net", .device = "pan" }, { .subsystem = "net", .device = "bnep" }, + { .subsystem = "net", .device = "vmnet" }, { .subsystem = "ppp", .device = NULL }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, @@ -181,6 +182,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "ieee1394_host", .device = NULL }, { .subsystem = "ieee1394_node", .device = NULL }, { .subsystem = "raw", .device = NULL }, + { .subsystem = "zaptel", .device = NULL }, { NULL, NULL } }; struct class_device *classdevice; From 2b0f835ccc67ae3209bc89be22cedfc8341ab5e3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 30 Oct 2004 13:29:52 +0200 Subject: [PATCH 0948/4284] [PATCH] add test for format chars in multiple symlinks to replace --- test/udev-test.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index a7becf99df..2b9fa8a238 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -777,6 +777,16 @@ EOF exp_majorminor => "4094:89999", conf => < "multiple symlinks with format char", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "symlink2-ttyUSB0", + exp_target => "ttyUSB0", + conf => < Date: Sat, 30 Oct 2004 13:33:06 +0200 Subject: [PATCH 0949/4284] [PATCH] Apply the default permissions even if we found a entry in --- namedev.c | 7 +++---- test/udev-test.pl | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/namedev.c b/namedev.c index 80d5f1a499..b142dda4fe 100644 --- a/namedev.c +++ b/namedev.c @@ -798,11 +798,10 @@ perms: set_empty_perms(udev, perm->mode, perm->owner, perm->group); - } else { - set_empty_perms(udev, get_default_mode(), - get_default_owner(), - get_default_group()); } + set_empty_perms(udev, get_default_mode(), + get_default_owner(), + get_default_group()); dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); diff --git a/test/udev-test.pl b/test/udev-test.pl index 2b9fa8a238..e615a1eda8 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -550,11 +550,11 @@ KERNEL="tty2", NAME="tty2" EOF }, { - desc => "permissions tty3:::", + desc => "permissions tty3::: (default mode applied)", subsys => "tty", devpath => "/class/tty/tty3", exp_name => "tty3", - exp_perms => "0:0:0", + exp_perms => "0:0:600", conf => < Date: Sat, 30 Oct 2004 13:37:48 +0200 Subject: [PATCH 0950/4284] [PATCH] Patches from Harald Hoyer . --- extras/volume_id/Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index c419e8860f..8605811cf5 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -33,13 +33,13 @@ override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \ override CFLAGS+=-D_FILE_OFFSET_BITS=64 -SYSFS = ../../libsysfs/sysfs_bus.o \ - ../../libsysfs/sysfs_class.o \ - ../../libsysfs/sysfs_device.o \ - ../../libsysfs/sysfs_dir.o \ - ../../libsysfs/sysfs_driver.o \ - ../../libsysfs/sysfs_utils.o \ - ../../libsysfs/dlist.o +override SYSFS = ../../libsysfs/sysfs_bus.o \ + ../../libsysfs/sysfs_class.o \ + ../../libsysfs/sysfs_device.o \ + ../../libsysfs/sysfs_dir.o \ + ../../libsysfs/sysfs_driver.o \ + ../../libsysfs/sysfs_utils.o \ + ../../libsysfs/dlist.o @@ -60,8 +60,8 @@ clean: spotless: clean install: all - $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(usrsbindir)/$(PROG) + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) uninstall: - - rm $(DESTDIR)$(usrsbindir)/$(PROG) + - rm $(DESTDIR)$(sbindir)/$(PROG) From e5e2ea95a4b21ebc5297881e7e8c5ab4425bac5e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 30 Oct 2004 13:44:46 +0200 Subject: [PATCH 0951/4284] [PATCH] Exit, if udevtest cannot open the device (segfault). --- udevtest.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/udevtest.c b/udevtest.c index f2b0c98edb..8af2120fb1 100644 --- a/udevtest.c +++ b/udevtest.c @@ -108,10 +108,12 @@ int main(int argc, char *argv[], char *envp[]) /* open the device */ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); class_dev = sysfs_open_class_device_path(path); - if (class_dev == NULL) - dbg ("sysfs_open_class_device_path failed"); - else - dbg("opened class_dev->name='%s'", class_dev->name); + if (class_dev == NULL) { + info("sysfs_open_class_device_path failed"); + return 1; + } + + dbg("opened class_dev->name='%s'", class_dev->name); /* simulate node creation with test flag */ udev.test_run = 1; From 56b979e00d87d1766b61716f07870701aca20ead Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Nov 2004 10:20:31 +0100 Subject: [PATCH 0952/4284] [PATCH] Add a bunch of devices without "device" symlinks. --- udev_sysfs.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 95a46a6ecd..886e9f403b 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -174,6 +174,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "printer", .device = "lp" }, { .subsystem = "nvidia", .device = NULL }, { .subsystem = "video4linux", .device = "vbi" }, + { .subsystem = "dvb", .device = NULL }, { .subsystem = "lirc", .device = NULL }, { .subsystem = "firmware", .device = NULL }, { .subsystem = "drm", .device = NULL }, @@ -183,6 +184,21 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "ieee1394_node", .device = NULL }, { .subsystem = "raw", .device = NULL }, { .subsystem = "zaptel", .device = NULL }, + { .subsystem = "tiglusb", .device = NULL }, + { .subsystem = "ppdev", .device = NULL }, + { .subsystem = "ticables", .device = NULL }, + { .subsystem = "snsc", .device = NULL }, + { .subsystem = "staliomem", .device = NULL }, + { .subsystem = "tape", .device = NULL }, + { .subsystem = "ip2", .device = NULL }, + { .subsystem = "tpqic02", .device = NULL }, + { .subsystem = "dsp56k", .device = NULL }, + { .subsystem = "zft", .device = NULL }, + { .subsystem = "adb", .device = NULL }, + { .subsystem = "cosa", .device = NULL }, + { .subsystem = "pg", .device = NULL }, + { .subsystem = "pt", .device = NULL }, + { .subsystem = "capi", .device = NULL }, { NULL, NULL } }; struct class_device *classdevice; From a5d00f9d3725c701d5a2d7a14dfcc7864aac27fb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 2 Nov 2004 10:22:11 +0100 Subject: [PATCH 0953/4284] [PATCH] Add support for highpoint ataraid to volume_id to suppress --- extras/volume_id/volume_id.c | 42 +++++++++++++++++++++++++++++++++--- extras/volume_id/volume_id.h | 7 +++--- 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index 0b43bc8efb..42d658895f 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -263,6 +263,36 @@ static void free_buffer(struct volume_id *id) } } +#define HPT37X_CONFIG_OFF 0x1200 +#define HPT37X_MAGIC_OK 0x5a7816f0 +#define HPT37X_MAGIC_BAD 0x5a7816fd +static int probe_highpoint_ataraid(struct volume_id *id, __u64 off) +{ + struct hpt37x { + __u8 filler1[32]; + __u32 magic; + __u32 magic_0; + __u32 magic_1; + } __attribute__((packed)) *hpt; + + const __u8 *buf; + + buf = get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); + if (buf == NULL) + return -1; + + hpt = (struct hpt37x *) buf; + + if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD) + return -1; + + id->usage_id = VOLUME_ID_RAID; + id->type_id = VOLUME_ID_HPTRAID; + id->type = "hpt_ataraid_member"; + + return 0; +} + #define LVM1_SB_OFF 0x400 #define LVM1_MAGIC "HM" static int probe_lvm1(struct volume_id *id, __u64 off) @@ -2038,6 +2068,9 @@ int volume_id_probe(struct volume_id *id, case VOLUME_ID_LVM2: rc = probe_lvm2(id, off); break; + case VOLUME_ID_HPTRAID: + rc = probe_highpoint_ataraid(id, off); + break; case VOLUME_ID_ALL: default: /* probe for raid first, cause fs probes may be successful on raid members */ @@ -2048,14 +2081,14 @@ int volume_id_probe(struct volume_id *id, if (rc == 0) break; rc = probe_lvm2(id, off); + if (rc == 0) + break; + rc = probe_highpoint_ataraid(id, off); if (rc == 0) break; /* signature in the first block, only small buffer needed */ rc = probe_msdos_part_table(id, off); - if (rc == 0) - break; - rc = probe_ntfs(id, off); if (rc == 0) break; rc = probe_vfat(id, off); @@ -2093,6 +2126,9 @@ int volume_id_probe(struct volume_id *id, if (rc == 0) break; rc = probe_ufs(id, off); + if (rc == 0) + break; + rc = probe_ntfs(id, off); if (rc == 0) break; diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index c6f52bec41..d135f44e50 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 25 +#define VOLUME_ID_VERSION 26 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 @@ -36,7 +36,7 @@ enum volume_id_usage { VOLUME_ID_OTHER, VOLUME_ID_FILESYSTEM, VOLUME_ID_PARTITIONTABLE, - VOLUME_ID_RAID + VOLUME_ID_RAID, }; enum volume_id_type { @@ -59,7 +59,8 @@ enum volume_id_type { VOLUME_ID_UFS, VOLUME_ID_LINUX_RAID, VOLUME_ID_LVM1, - VOLUME_ID_LVM2 + VOLUME_ID_LVM2, + VOLUME_ID_HPTRAID, }; struct volume_id_partition { From 5a73b25fd6673134328443af04afe7bde0060d72 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 5 Nov 2004 13:16:32 +0100 Subject: [PATCH 0954/4284] [PATCH] Don't use any syslog() in signal handler, cause it may deadlock. --- udev.c | 5 +---- udev.h | 2 +- udevd.c | 9 ++------- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/udev.c b/udev.c index cac60fd932..7809060520 100644 --- a/udev.c +++ b/udev.c @@ -65,14 +65,10 @@ static void asmlinkage sig_handler(int signum) switch (signum) { case SIGALRM: gotalarm = 1; - info("error: timeout reached, event probably not handled correctly"); break; case SIGINT: case SIGTERM: - udevdb_exit(); exit(20 + signum); - default: - dbg("unhandled signal %d", signum); } } @@ -148,6 +144,7 @@ int main(int argc, char *argv[], char *envp[]) /* set signal handlers */ act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); + act.sa_flags = 0; /* alarm must not restart syscalls*/ sigaction(SIGALRM, &act, NULL); sigaction(SIGINT, &act, NULL); diff --git a/udev.h b/udev.h index f7a13a634b..e8954338d9 100644 --- a/udev.h +++ b/udev.h @@ -26,7 +26,7 @@ #include #include "libsysfs/sysfs/libsysfs.h" -#define ALARM_TIMEOUT 30 +#define ALARM_TIMEOUT 120 #define COMMENT_CHARACTER '#' #define NAME_SIZE 256 diff --git a/udevd.c b/udevd.c index 0150837143..395cdca88b 100644 --- a/udevd.c +++ b/udevd.c @@ -327,20 +327,15 @@ static void asmlinkage sig_handler(int signum) sigchilds_waiting = 1; goto do_write; break; - default: - dbg("unhandled signal %d", signum); - return; } - + do_write: /* if pipe is empty, write to pipe to force select to return * immediately when it gets called */ if (!sig_flag) { rc = write(pipefds[1],&signum,sizeof(signum)); - if (rc < 0) - dbg("unable to write to pipe"); - else + if (rc >= 0) sig_flag = 1; } } From e920fed3499aa1445657b62499a11348faa3b24e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 5 Nov 2004 13:16:56 +0100 Subject: [PATCH 0955/4284] [PATCH] wait() for specific pid to return from fork(). --- dev_d.c | 2 +- namedev.c | 2 +- udevsend.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev_d.c b/dev_d.c index be85f52775..64c2544248 100644 --- a/dev_d.c +++ b/dev_d.c @@ -68,7 +68,7 @@ static int run_program(char *name) break; return -1; default: - wait(NULL); + waitpid(pid, NULL, 0); } return 0; diff --git a/namedev.c b/namedev.c index b142dda4fe..f3fb3ff7ed 100644 --- a/namedev.c +++ b/namedev.c @@ -444,7 +444,7 @@ static int execute_program(const char *path, char *value, int len) dbg("result is '%s'", value); close(fds[0]); - wait(&status); + waitpid(pid, &status, 0); if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { dbg("exec program status 0x%x", status); diff --git a/udevsend.c b/udevsend.c index 84c46bc0c2..b564d6453f 100644 --- a/udevsend.c +++ b/udevsend.c @@ -82,7 +82,7 @@ static int start_daemon(void) dbg("fork of helper failed"); return -1; default: - wait(NULL); + waitpid(pid, NULL, 0); } return 0; } @@ -103,7 +103,7 @@ static void run_udev(const char *subsystem) dbg("fork of child failed"); break; default: - wait(NULL); + waitpid(pid, NULL, 0); } } From 52a6ef66f2e98491b40b176619035abca3777a2c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 5 Nov 2004 13:17:30 +0100 Subject: [PATCH 0956/4284] [PATCH] Shut up wait_for_sysfs class/net failure messages, as it's not possible --- wait_for_sysfs.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 91a2b6b628..3b1b0cd248 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -116,6 +116,15 @@ int main(int argc, char *argv[], char *envp[]) /* wait for the class device with possible physical device and bus */ wait_for_class_device(class_dev, &error); + /* + * we got too many unfixable class/net errors, kernel later than 2.6.10-rc1 will + * solve this by exporting the needed information with the hotplug event + * until we use this just don't print any error for net devices, but still + * wait for it. + */ + if (strncmp(devpath, "/class/net/", 11) == 0) + error = NULL; + sysfs_close_class_device(class_dev); } else if ((strncmp(devpath, "/devices/", 9) == 0)) { From 800ab95bd55c9beebd14fd23ef34ea7f3e055e6a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Nov 2004 18:11:00 -0800 Subject: [PATCH 0957/4284] [PATCH] make udev-test.pl test for root permissions before running Should prevent false error reports from happening. --- test/udev-test.pl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index e615a1eda8..e8ce0b44dd 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1275,6 +1275,13 @@ sub run_test { } +# 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"; From e9f653894e04621d217ca5143a92c803d9995dc5 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Nov 2004 18:11:40 -0800 Subject: [PATCH 0958/4284] [PATCH] remove 'sudo' usage from the Makefile should fix a lot of gentoo bug reports --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index c90baba582..b62cd89702 100644 --- a/Makefile +++ b/Makefile @@ -465,4 +465,4 @@ uninstall: uninstall-man uninstall-dev.d done ; \ test: all - @ cd test && sudo ./udev-test.pl + @ cd test && ./udev-test.pl From 3874126807efcc61eded424aace7e40c79a025a7 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Nov 2004 18:13:11 -0800 Subject: [PATCH 0959/4284] [PATCH] fix gentoo legacy tty rule I thought I had fixed this a long time ago... --- etc/udev/udev.rules.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index ffc56ee7e4..08bc9f99d1 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -66,7 +66,7 @@ KERNEL="inotify", NAME="misc/%k", SYMLINK="%k" # pty devices KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" # ramdisk devices KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" From 97a0e3c06e8a92af3cdf1110fe15cb693be0886a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Nov 2004 18:46:01 -0800 Subject: [PATCH 0960/4284] [PATCH] add cdsymlinks.sh support to gentoo rules file. --- etc/udev/udev.rules.gentoo | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 08bc9f99d1..2e2f89f26a 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -12,6 +12,11 @@ # ########################################################### +# cdrom symlinks and other good cdrom naming +BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS="scsi", KERNEL="sr[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" + # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" From a258d159f4d0e1167d038b879164155e4bb8cad2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Nov 2004 19:04:38 -0800 Subject: [PATCH 0961/4284] [PATCH] add i2c-dev to the list of devices without a bus --- udev_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 886e9f403b..a11c430df0 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -235,6 +235,7 @@ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) static char *devices_without_bus[] = { "scsi_host", "i2c-adapter", + "i2c-dev", NULL }; char **device; From c072fd0112b3cb93dd65537f59db74692f69664c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Nov 2004 19:05:20 -0800 Subject: [PATCH 0962/4284] [PATCH] reduce syslog noise of udevsend if multiple instances try to start udevd --- udevsend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevsend.c b/udevsend.c index b564d6453f..c0c72b9c19 100644 --- a/udevsend.c +++ b/udevsend.c @@ -190,13 +190,13 @@ int main(int argc, char* argv[]) } if (!started_daemon) { - info("starting udevd daemon"); + dbg("try to start udevd daemon"); retval = start_daemon(); if (retval) { info("error starting daemon"); goto fallback; } - dbg("daemon started"); + info("udevd daemon started"); started_daemon = 1; } else { dbg("retry to connect %d", SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND - loop); From 5ca6ff64574430d9394bb6417a38295902116bab Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 5 Nov 2004 06:52:53 -0800 Subject: [PATCH 0963/4284] [PATCH] 043 release --- ChangeLog | 24 ++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 907314150c..85a5f07d0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +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 ============================================ diff --git a/Makefile b/Makefile index b62cd89702..0f95aaed9a 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart WAIT = wait_for_sysfs -VERSION = 042 +VERSION = 043 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index ac2a874cf0..310883e03f 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 042 +Version: 043 Release: 1 License: GPL Group: Utilities/System From 0bac7bab72648fe9f2667287b38d371929341b4f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 10 Nov 2004 19:38:07 -0800 Subject: [PATCH 0964/4284] [PATCH] 044 release --- ChangeLog | 14 ++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 85a5f07d0f..29abba679d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 0f95aaed9a..a3aa2ecb8b 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart WAIT = wait_for_sysfs -VERSION = 043 +VERSION = 044 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 310883e03f..bbaf076733 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 043 +Version: 044 Release: 1 License: GPL Group: Utilities/System From 9dfe20eff709a251da92c473ea94615887497e0a Mon Sep 17 00:00:00 2001 From: "azarah@nosferatu.za.org" Date: Wed, 17 Nov 2004 19:10:07 -0800 Subject: [PATCH 0965/4284] [PATCH] Some updates for Gentoo's udev rules Hi, Here is a few updates for the udev.rules.gentoo from udev package. I will summarise it briefly: 1) The last change you did to legacy tty's is wrong. I say this because: 1a) The original devfs rules had both master and slave in /dev/pty: nosferatu linux # grep devfs_name drivers/char/pty.c pty_driver->devfs_name = "pty/m"; pty_slave_driver->devfs_name = "pty/s"; nosferatu linux # 1b) If you refer to '2.6.8.1-mm1 Tty problems?', you will see that the /dev/tty/ directory our rules create, replaces this symlink: nosferatu portage # ls -l /dev/tty crw-rw-rw- 1 root tty 5, 0 Nov 14 17:06 /dev/tty nosferatu portage # which is used to determine the controlling tty. 2) Somebody added the /dev/cpu/microcode rule, but it was not run as there was an older rule before that placing it in /dev/misc (which is wrong). Just remove the first broken rule 3) Some form/tab cleanups. Reorder rules alphabetically according to device class to make searching/editing easier. --- etc/udev/udev.rules.gentoo | 148 ++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 74 deletions(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 2e2f89f26a..1809232ed0 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -21,32 +21,41 @@ BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYM # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" -# DRI devices -KERNEL="card*", NAME="dri/card%n" +# dri devices +KERNEL="card*", NAME="dri/card%n" # alsa devices 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" +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" +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="" +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" +#KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" +KERNEL="device-mapper", NAME="mapper/control" # fb devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" # floppy devices -KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k" +KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k" # i2c devices -KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" +KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" # input devices KERNEL="mice", NAME="input/%k" @@ -56,61 +65,17 @@ KERNEL="js*", NAME="input/%k" KERNEL="ts*", NAME="input/%k" # loop devices -KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" +KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" # md block devices -KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" +KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" # misc devices -KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" -KERNEL="microcode", NAME="misc/%k", SYMLINK="%k" -KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" -KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" -KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" -KERNEL="inotify", NAME="misc/%k", SYMLINK="%k" - -# pty devices -KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" - -# ramdisk devices -KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" - -# sound devices -KERNEL="adsp", NAME="sound/%k", SYMLINK="%k" -KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="audio", NAME="sound/%k", SYMLINK="%k" -KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="dsp", NAME="sound/%k", SYMLINK="%k" -KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="mixer", NAME="sound/%k", SYMLINK="%k" -KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k" -KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k" - -# tty devices -KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" -KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" -KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" - -# vc devices -KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" -KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" -KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" -KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" - -# v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n" -KERNEL="radio[0-9]*", NAME="v4l/radio%n" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n" -KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" - -# USB devices -KERNEL="hiddev*", NAME="usb/%k" -KERNEL="auer*", NAME="usb/%k" -KERNEL="legousbtower*", NAME="usb/%k" -KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" +KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" +KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" +KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" +KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" +KERNEL="inotify", NAME="misc/%k", SYMLINK="%k" # netlink devices KERNEL="route", NAME="netlink/%k" @@ -126,17 +91,52 @@ KERNEL="ip6_fw", NAME="netlink/%k" KERNEL="dnrtmsg", NAME="netlink/%k" KERNEL="tap*", NAME="netlink/%k" -# CAPI devices -KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" -KERNEL="capi*", NAME="capi/%n" - -# Network devices +# network devices KERNEL="tun", NAME="net/%k" +# pty devices +KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k" + +# ramdisk devices +KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" + # raw devices -KERNEL="raw[0-9]*", NAME="raw/%k" +KERNEL="raw[0-9]*", NAME="raw/%k" + +# sound devices +KERNEL="adsp", NAME="sound/%k", SYMLINK="%k" +KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="audio", NAME="sound/%k", SYMLINK="%k" +KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="dsp", NAME="sound/%k", SYMLINK="%k" +KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="mixer", NAME="sound/%k", SYMLINK="%k" +KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k" +KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k" + +# tty devices +KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" +KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" +KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" + +# usb devices +KERNEL="hiddev*", NAME="usb/%k" +KERNEL="auer*", NAME="usb/%k" +KERNEL="legousbtower*", NAME="usb/%k" +KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" + +# vc devices +KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" +KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" +KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" +KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" + +# v4l devices +KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n" +KERNEL="radio[0-9]*", NAME="v4l/radio%n" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n" +KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" -# cpu devices -KERNEL="cpu[0-9]*", NAME="cpu/%n/cpuid" -KERNEL="msr[0-9]*", NAME="cpu/%n/msr" -KERNEL="microcode", NAME="cpu/microcode" From 482b0ecd8fcc2651c003c6f1ae9a2d3301ecf34a Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 17 Nov 2004 19:28:03 -0800 Subject: [PATCH 0966/4284] [PATCH] 045 release --- ChangeLog | 7 +++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 29abba679d..5088273e62 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Summary of changes from v044 to v045 +============================================ + +Martin Schlemmer: + o Some updates for Gentoo's udev rules + + Summary of changes from v043 to v044 ============================================ diff --git a/Makefile b/Makefile index a3aa2ecb8b..676302819d 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart WAIT = wait_for_sysfs -VERSION = 044 +VERSION = 045 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index bbaf076733..edb033e864 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 044 +Version: 045 Release: 1 License: GPL Group: Utilities/System From 2b41e68a08548ce44b4d145900dab2bb04cd34f7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 6 Nov 2004 14:28:01 +0100 Subject: [PATCH 0967/4284] [PATCH] replace tdb database by simple lockless file database This makes the udev operation completely lockless by storing a file for every node in /dev/.udevdb/* This solved the problem with deadlocking concurrent udev processes waiting for each other to release the file lock under heavy load. --- HOWTO-udev_for_dev | 4 +- Makefile | 29 +- dev_d.c | 1 - docs/persistent_naming/testing_scsi_notes.txt | 20 +- etc/init.d/udev | 4 +- etc/udev/udev.conf.in | 8 +- namedev.c | 40 +- tdb/Makefile | 32 - tdb/README | 167 -- tdb/spinlock.c | 433 ---- tdb/spinlock.h | 55 - tdb/tdb.c | 2099 ----------------- tdb/tdb.h | 150 -- tdb/tdb.magic | 10 - tdb/tdbback.c | 201 -- tdb/tdbback.h | 23 - tdb/tdbbackup.c | 137 -- tdb/tdbdump.c | 89 - tdb/tdbutil.c | 830 ------- tdb/tdbutil.h | 37 - test/devd_test | 2 +- test/ignore_test | 2 +- test/label_test | 2 +- test/modifier_test | 2 +- test/net_test | 2 +- test/replace_test | 2 +- test/topo_test | 2 +- test/udev-test.pl | 6 +- udev.8.in | 4 +- udev.c | 11 +- udev.h | 13 +- udev_add.c | 48 +- udev_config.c | 19 +- udev_lib.c | 45 +- udev_lib.h | 4 +- udev_remove.c | 33 +- udevdb.c | 306 ++- udevdb.h | 38 +- udevinfo.8 | 5 +- udevinfo.c | 98 +- udevsend.c | 2 +- 41 files changed, 326 insertions(+), 4689 deletions(-) delete mode 100644 tdb/Makefile delete mode 100644 tdb/README delete mode 100644 tdb/spinlock.c delete mode 100644 tdb/spinlock.h delete mode 100644 tdb/tdb.c delete mode 100644 tdb/tdb.h delete mode 100644 tdb/tdb.magic delete mode 100644 tdb/tdbback.c delete mode 100644 tdb/tdbback.h delete mode 100644 tdb/tdbbackup.c delete mode 100644 tdb/tdbdump.c delete mode 100644 tdb/tdbutil.c delete mode 100644 tdb/tdbutil.h diff --git a/HOWTO-udev_for_dev b/HOWTO-udev_for_dev index 58bf2d4e8c..9833dd1411 100644 --- a/HOWTO-udev_for_dev +++ b/HOWTO-udev_for_dev @@ -39,10 +39,10 @@ NOTE NOTE NOTE NOTE NOTE NOTE NOTE the end of this file. - make sure the /etc/udev/udev.conf file lists the udev_root as "/dev/" - and the udev_db as "/dev/.udev.tdb". It should contain the + and the udev_db as "/dev/.udevdb". It should contain the following lines in order to work properly. udev_root="/dev/" - udev_db="/dev/.udev.tdb" + udev_db="/dev/.udevdb" - reboot into a 2.6 kernel and watch udev create all of the initial device nodes in /dev diff --git a/Makefile b/Makefile index 676302819d..ef66213dd8 100644 --- a/Makefile +++ b/Makefile @@ -68,7 +68,8 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} EXTRAS= # place to put our device nodes -udevdir = ${prefix}/udev +udevdir = ${prefix}/udev +udevdb = ${udevdir}/.udevdb # Comment out this line to build with something other # than the local version of klibc @@ -113,11 +114,6 @@ WARNINGS := -Wall CFLAGS := -pipe -# set up the proper tdb spinlock code if we can -ifeq ($(strip $(ARCH)),i386) - CFLAGS += -DUSE_SPINLOCKS -DINTEL_SPINLOCKS -endif - ifeq ($(strip $(USE_LOG)),true) CFLAGS += -DLOG endif @@ -201,9 +197,6 @@ $(CRT0): fi $(MAKE) -C klibc SUBDIRS=klibc -TDB = tdb/tdb.o \ - tdb/spinlock.o - SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ $(PWD)/libsysfs/sysfs_class.o \ $(PWD)/libsysfs/sysfs_device.o \ @@ -221,8 +214,7 @@ OBJS = udev_lib.o \ namedev.o \ namedev_parse.o \ dev_d.o \ - $(SYSFS) \ - $(TDB) + $(SYSFS) HEADERS = udev.h \ udev_lib.h \ @@ -262,8 +254,8 @@ ccdv: udev_version.h: @echo "Creating udev_version.h" @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ - @echo \#define UDEV_ROOT \"$(udevdir)/\" >> $@ - @echo \#define UDEV_DB \"$(udevdir)/.udev.tdb\" >> $@ + @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ + @echo \#define UDEV_DB \"$(udevdb)\" >> $@ @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ @@ -300,7 +292,7 @@ $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) $(QUIET) $(STRIPCMD) $@ $(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(TDB) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h @@ -337,7 +329,7 @@ spotless: clean $(MAKE) -C klibc spotless -rm -f klibc/linux -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz$" -e "\/\." -e releases -e BitKeeper -e SCCS -e "\.tdb$" -e test/sys | sort ) +DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz" -e "\/\." -e releases -e BitKeeper -e SCCS -e test/sys | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . release: clean @@ -429,8 +421,8 @@ install: install-initscript install-config install-man install-dev.d all - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug - ln -f -s $(sbindir)/$(WAIT) $(DESTDIR)$(hotplugdir)/05-wait_for_sysfs.hotplug ifndef DESTDIR - - killall udevd - - rm -f $(udevdir)/.udev.tdb + - killall $(DAEMON) + - rm -rf $(udevdb) endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ @@ -456,8 +448,9 @@ uninstall: uninstall-man uninstall-dev.d - rm $(usrbindir)/$(TESTER) - rm $(usrbindir)/$(WAIT) - rmdir $(hotplugdir) - - rm $(udevdir)/.udev.tdb + - rm -rf $(udevdb) - rmdir $(udevdir) + - killall $(DAEMON) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ diff --git a/dev_d.c b/dev_d.c index 64c2544248..6e35f55ca2 100644 --- a/dev_d.c +++ b/dev_d.c @@ -47,7 +47,6 @@ static int run_program(char *name) switch (pid) { case 0: /* child */ - udevdb_exit(); /* close udevdb */ fd = open("/dev/null", O_RDWR); if ( fd >= 0) { dup2(fd, STDOUT_FILENO); diff --git a/docs/persistent_naming/testing_scsi_notes.txt b/docs/persistent_naming/testing_scsi_notes.txt index 8d94c842b4..728b40b0fe 100644 --- a/docs/persistent_naming/testing_scsi_notes.txt +++ b/docs/persistent_naming/testing_scsi_notes.txt @@ -110,10 +110,8 @@ uses: (1) /sys maintained by sysfs (2) /etc/udev/udev.rules - where you can store the identifier to NAME mapping information. -(3) The tdb (udev-021/tdb/tdb.c), trivial data base, that is held in - memory and holds the valid system configuration. It is not saved - between one boot to the next. It is constructed at boot time and - updated with configuration changes. +(3) The udevdb, that keeps track the valid system configuration. + It is constructed at boot time and updated with configuration changes. The persistent names are kept (at least this is one way to do it) in udev.rules (uuid and NAME), one entry per device. If you want to initially @@ -148,9 +146,9 @@ the device. The result of the program execution (the uuid) is compared with the RESULT entry in the same udev.rules line. - If it matches, then the NAME entered on this line is used. The uuid and - major/minor number is saved in tdb (newly recreated upon boot). That - device is created in /udev (the target directory name is configurable) - with the assigned NAME. + major/minor number is saved in the udevdb (newly recreated upon boot). + That device is created in /udev (the target directory name is configurable) + with the assigned NAME. - If it doesn't match, the RESULT (uuid) is preserved for use on the next udev.rules line as long as the bus type (scsi) is the same. So the @@ -159,18 +157,18 @@ with the RESULT entry in the same udev.rules line. - If no match occurs, the device will be assigned a default name. -- Tdb is updated with the resulting name assignment. +- The udevdb is updated with the resulting name assignment. Thus if the uuid and names are enumerated, they will be found, assigned, and are therefore permanent. If the device is removed from a live system, a hotplug event occurs, and it -is removed from tdb and the /udev entry disappears. +is removed from udevdb and the /udev entry disappears. If it is re-inserted at a new location, the udev.rules file is scanned as -above. The new major/minor number goes in tdb with the uuid , the name in -udev.rules is found again, and the /udev name re-appears. +above. The rule matches again against the uuid, the name in udev.rules +is applied again and the /udev name re-appears. diff --git a/etc/init.d/udev b/etc/init.d/udev index 7e6305a45b..8726090d44 100644 --- a/etc/init.d/udev +++ b/etc/init.d/udev @@ -79,8 +79,8 @@ case "$1" in fi # remove the database if it is there as we always want to start fresh - if [ -f $udev_root/.udev.tdb ]; then - rm -f $udev_root/.udev.tdb + if [ -f $udev_root/.udevdb ]; then + rm -rf $udev_root/.udevdb fi # propogate /udev from /sys - we only need this while we do not diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 4c71b1dfec..bbbb1a93a2 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -6,16 +6,16 @@ # udev_root - where in the filesystem to place the device nodes -udev_root="@udevdir@/" +udev_root="@udevdir@" # udev_db - The name and location of the udev database. -udev_db="@udevdir@/.udev.tdb" +udev_db="@udevdir@/.udevdb" # udev_rules - The name and location of the udev rules file -udev_rules="@configdir@/rules.d/" +udev_rules="@configdir@/rules.d" # udev_permissions - The name and location of the udev permission file -udev_permissions="@configdir@/permissions.d/" +udev_permissions="@configdir@/permissions.d" # default_mode - set the default mode for all nodes that have no # explicit match in the permissions file diff --git a/namedev.c b/namedev.c index f3fb3ff7ed..d63e36e18a 100644 --- a/namedev.c +++ b/namedev.c @@ -184,29 +184,29 @@ static int get_format_len(char **str) * @param name Name to check for * @return 0 if didn't exist and N otherwise. */ -static unsigned int find_free_number (struct udevice *udev, char *name) +static int find_free_number(struct udevice *udev, const char *name) { - char temp[NAME_SIZE]; - char path[NAME_SIZE]; - struct udevice dev; - int result; + char filename[NAME_SIZE]; + int num = 0; + struct udevice db_udev; - /* have to sweep the database for each lookup */ - result = 0; - strncpy(temp, name, sizeof (temp)); + strfieldcpy(filename, name); while (1) { - if (udevdb_get_dev_byname(temp, path, &dev) != 0) - goto found; - /* symlink might be stale if $(udevroot) isn't cleaned; check - * on major/minor to see if it's the same device - */ - if (dev.major == udev->major && dev.minor == udev->minor) - goto found; - snprintf (temp, sizeof(temp), "%s%d", name, ++result); - } + dbg("look for existing node '%s'", filename); + memset(&db_udev, 0x00, sizeof(struct udevice)); + if (udevdb_get_dev_byname(&db_udev, filename) != 0) { + dbg("free num=%d", num); + return num; + } -found: - return result; + num++; + if (num > 1000) { + info("find_free_number gone crazy (num=%d), aborted", num); + return -1; + } + snprintf(filename, NAME_SIZE-1, "%s%d", name, num); + filename[NAME_SIZE-1] = '\0'; + } } static void apply_format(struct udevice *udev, char *string, size_t maxsize, @@ -329,7 +329,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, case 'e': next_free_number = find_free_number(udev, string); if (next_free_number > 0) { - snprintf(temp2, sizeof(temp2), "%d", next_free_number); + sprintf(temp2, "%d", next_free_number); strfieldcatmax(string, temp2, maxsize); } break; diff --git a/tdb/Makefile b/tdb/Makefile deleted file mode 100644 index 87fb680bdd..0000000000 --- a/tdb/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -# -# Makefile for tdb directory -# - -CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1 - -PROGS = tdbtest tdbtool tdbtorture -TDB_OBJ = tdb.o spinlock.o - -default: $(TDB_OBJ) - -progs: $(PROGS) - -tdbtest: tdbtest.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbtest tdbtest.o $(TDB_OBJ) -lgdbm - -tdbtool: tdbtool.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbtool tdbtool.o $(TDB_OBJ) - -tdbtorture: tdbtorture.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o $(TDB_OBJ) - -tdbdump: tdbdump.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbdump tdbdump.o $(TDB_OBJ) - -tdbbackup: tdbbackup.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbbackup tdbbackup.o $(TDB_OBJ) - -clean: - rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm - -spotless: clean diff --git a/tdb/README b/tdb/README deleted file mode 100644 index fac3eacb4d..0000000000 --- a/tdb/README +++ /dev/null @@ -1,167 +0,0 @@ -tdb - a trivial database system -tridge@linuxcare.com December 1999 -================================== - -This is a simple database API. It was inspired by the realisation that -in Samba we have several ad-hoc bits of code that essentially -implement small databases for sharing structures between parts of -Samba. As I was about to add another I realised that a generic -database module was called for to replace all the ad-hoc bits. - -I based the interface on gdbm. I couldn't use gdbm as we need to be -able to have multiple writers to the databases at one time. - -Compilation ------------ - -add HAVE_MMAP=1 to use mmap instead of read/write -add TDB_DEBUG=1 for verbose debug info -add NOLOCK=1 to disable locking code - -Testing -------- - -Compile tdbtest.c and link with gdbm for testing. tdbtest will perform -identical operations via tdb and gdbm then make sure the result is the -same - -Also included is tdbtool, which allows simple database manipulation -on the commandline. - -tdbtest and tdbtool are not built as part of Samba, but are included -for completeness. - -Interface ---------- - -The interface is very similar to gdbm except for the following: - -- different open interface. The tdb_open call is more similar to a - traditional open() -- no tdbm_reorganise() function -- no tdbm_sync() function. No operations are cached in the library anyway -- added a tdb_traverse() function for traversing the whole database - -A general rule for using tdb is that the caller frees any returned -TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA -return value called p. This is the same as gdbm. - -here is a full list of tdb functions with brief descriptions. - - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) - - open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the database - file. A flags value of O_WRONLY is invalid - - The hash size is advisory, use zero for a default value. - - return is NULL on error - - possible tdb_flags are: - TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open - TDB_INTERNAL - don't use a file, instaed store the data in - memory. The filename is ignored in this case. - TDB_NOLOCK - don't do any locking - TDB_NOMMAP - don't use mmap - ----------------------------------------------------------------------- -char *tdb_error(TDB_CONTEXT *tdb); - - return a error string for the last tdb error - ----------------------------------------------------------------------- -int tdb_close(TDB_CONTEXT *tdb); - - close a database - ----------------------------------------------------------------------- -int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf); - - update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1 - ----------------------------------------------------------------------- -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); - - fetch an entry in the database given a key - if the return value has a null dptr then a error occurred - - caller must free the resulting data - ----------------------------------------------------------------------- -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); - - check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm - ----------------------------------------------------------------------- -int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on each - element. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal should stop - ----------------------------------------------------------------------- -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); - - find the first entry in the database and return its key - - the caller must free the returned data - ----------------------------------------------------------------------- -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); - - find the next entry in the database, returning its key - - the caller must free the returned data - ----------------------------------------------------------------------- -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); - - delete an entry in the database given a key - ----------------------------------------------------------------------- -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); - - store an element in the database, replacing any existing element - with the same key - - If flag==TDB_INSERT then don't overwrite an existing entry - If flag==TDB_MODIFY then don't create a new entry - - return 0 on success, -1 on failure - ----------------------------------------------------------------------- -int tdb_writelock(TDB_CONTEXT *tdb); - - lock the database. If we already have it locked then don't do anything - ----------------------------------------------------------------------- -int tdb_writeunlock(TDB_CONTEXT *tdb); - unlock the database - ----------------------------------------------------------------------- -int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - lock one hash chain. This is meant to be used to reduce locking - contention - it cannot guarantee how many records will be locked - ----------------------------------------------------------------------- -int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - unlock one hash chain diff --git a/tdb/spinlock.c b/tdb/spinlock.c deleted file mode 100644 index 451617fade..0000000000 --- a/tdb/spinlock.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba database functions - Copyright (C) Anton Blanchard 2001 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* udev defines */ -#define STANDALONE -#define TDB_DEBUG -#define HAVE_MMAP 1 - -#if HAVE_CONFIG_H -#include -#endif - -#ifdef STANDALONE -#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" -#include "spinlock.h" -#include "../udev.h" -#include "../logging.h" - -#else -#include "includes.h" -#endif - -#ifdef USE_SPINLOCKS - -/* - * ARCH SPECIFIC - */ - -#if defined(SPARC_SPINLOCKS) - -static inline int __spin_trylock(spinlock_t *lock) -{ - unsigned int result; - - asm volatile("ldstub [%1], %0" - : "=r" (result) - : "r" (lock) - : "memory"); - - return (result == 0) ? 0 : EBUSY; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("":::"memory"); - *lock = 0; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 0; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 0); -} - -#elif defined(POWERPC_SPINLOCKS) - -static inline int __spin_trylock(spinlock_t *lock) -{ - unsigned int result; - - __asm__ __volatile__( -"1: lwarx %0,0,%1\n\ - cmpwi 0,%0,0\n\ - li %0,0\n\ - bne- 2f\n\ - li %0,1\n\ - stwcx. %0,0,%1\n\ - bne- 1b\n\ - isync\n\ -2:" : "=&r"(result) - : "r"(lock) - : "cr0", "memory"); - - return (result == 1) ? 0 : EBUSY; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("eieio":::"memory"); - *lock = 0; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 0; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 0); -} - -#elif defined(INTEL_SPINLOCKS) - -static inline int __spin_trylock(spinlock_t *lock) -{ - int oldval; - - asm volatile("xchgl %0,%1" - : "=r" (oldval), "=m" (*lock) - : "0" (0) - : "memory"); - - return oldval > 0 ? 0 : EBUSY; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("":::"memory"); - *lock = 1; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 1; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 1); -} - -#elif defined(MIPS_SPINLOCKS) - -static inline unsigned int load_linked(unsigned long addr) -{ - unsigned int res; - - __asm__ __volatile__("ll\t%0,(%1)" - : "=r" (res) - : "r" (addr)); - - return res; -} - -static inline unsigned int store_conditional(unsigned long addr, unsigned int value) -{ - unsigned int res; - - __asm__ __volatile__("sc\t%0,(%2)" - : "=r" (res) - : "0" (value), "r" (addr)); - return res; -} - -static inline int __spin_trylock(spinlock_t *lock) -{ - unsigned int mw; - - do { - mw = load_linked(lock); - if (mw) - return EBUSY; - } while (!store_conditional(lock, 1)); - - asm volatile("":::"memory"); - - return 0; -} - -static inline void __spin_unlock(spinlock_t *lock) -{ - asm volatile("":::"memory"); - *lock = 0; -} - -static inline void __spin_lock_init(spinlock_t *lock) -{ - *lock = 0; -} - -static inline int __spin_is_locked(spinlock_t *lock) -{ - return (*lock != 0); -} - -#else -#error Need to implement spinlock code in spinlock.c -#endif - -/* - * OS SPECIFIC - */ - -static void yield_cpu(void) -{ - struct timespec tm; - -#ifdef USE_SCHED_YIELD - sched_yield(); -#else - /* Linux will busy loop for delays < 2ms on real time tasks */ - tm.tv_sec = 0; - tm.tv_nsec = 2000000L + 1; - nanosleep(&tm, NULL); -#endif -} - -static int this_is_smp(void) -{ - return 0; -} - -/* - * GENERIC - */ - -static int smp_machine = 0; - -static inline void __spin_lock(spinlock_t *lock) -{ - int ntries = 0; - - while(__spin_trylock(lock)) { - while(__spin_is_locked(lock)) { - if (smp_machine && ntries++ < MAX_BUSY_LOOPS) - continue; - yield_cpu(); - } - } -} - -static void __read_lock(tdb_rwlock_t *rwlock) -{ - int ntries = 0; - - while(1) { - __spin_lock(&rwlock->lock); - - if (!(rwlock->count & RWLOCK_BIAS)) { - rwlock->count++; - __spin_unlock(&rwlock->lock); - return; - } - - __spin_unlock(&rwlock->lock); - - while(rwlock->count & RWLOCK_BIAS) { - if (smp_machine && ntries++ < MAX_BUSY_LOOPS) - continue; - yield_cpu(); - } - } -} - -static void __write_lock(tdb_rwlock_t *rwlock) -{ - int ntries = 0; - - while(1) { - __spin_lock(&rwlock->lock); - - if (rwlock->count == 0) { - rwlock->count |= RWLOCK_BIAS; - __spin_unlock(&rwlock->lock); - return; - } - - __spin_unlock(&rwlock->lock); - - while(rwlock->count != 0) { - if (smp_machine && ntries++ < MAX_BUSY_LOOPS) - continue; - yield_cpu(); - } - } -} - -static void __write_unlock(tdb_rwlock_t *rwlock) -{ - __spin_lock(&rwlock->lock); - - if (!(rwlock->count & RWLOCK_BIAS)) - dbg("bug: write_unlock"); - - rwlock->count &= ~RWLOCK_BIAS; - __spin_unlock(&rwlock->lock); -} - -static void __read_unlock(tdb_rwlock_t *rwlock) -{ - __spin_lock(&rwlock->lock); - - if (!rwlock->count) - dbg("bug: read_unlock"); - - if (rwlock->count & RWLOCK_BIAS) - dbg("bug: read_unlock"); - - rwlock->count--; - __spin_unlock(&rwlock->lock); -} - -/* TDB SPECIFIC */ - -/* lock a list in the database. list -1 is the alloc list */ -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) -{ - tdb_rwlock_t *rwlocks; - - if (!tdb->map_ptr) return -1; - rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); - - switch(rw_type) { - case F_RDLCK: - __read_lock(&rwlocks[list+1]); - break; - - case F_WRLCK: - __write_lock(&rwlocks[list+1]); - break; - - default: - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - return 0; -} - -/* unlock the database. */ -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) -{ - tdb_rwlock_t *rwlocks; - - if (!tdb->map_ptr) return -1; - rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); - - switch(rw_type) { - case F_RDLCK: - __read_unlock(&rwlocks[list+1]); - break; - - case F_WRLCK: - __write_unlock(&rwlocks[list+1]); - break; - - default: - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - - return 0; -} - -int tdb_create_rwlocks(int fd, unsigned int hash_size) -{ - unsigned size, i; - tdb_rwlock_t *rwlocks; - - size = (hash_size + 1) * sizeof(tdb_rwlock_t); - rwlocks = malloc(size); - if (!rwlocks) - return -1; - - for(i = 0; i < hash_size+1; i++) { - __spin_lock_init(&rwlocks[i].lock); - rwlocks[i].count = 0; - } - - /* Write it out (appending to end) */ - if (write(fd, rwlocks, size) != size) { - free(rwlocks); - return -1; - } - smp_machine = this_is_smp(); - free(rwlocks); - return 0; -} - -int tdb_clear_spinlocks(TDB_CONTEXT *tdb) -{ - tdb_rwlock_t *rwlocks; - unsigned i; - - if (tdb->header.rwlocks == 0) return 0; - if (!tdb->map_ptr) return -1; - - /* We're mmapped here */ - rwlocks = (tdb_rwlock_t *)((char *)tdb->map_ptr + tdb->header.rwlocks); - for(i = 0; i < tdb->header.hash_size+1; i++) { - __spin_lock_init(&rwlocks[i].lock); - rwlocks[i].count = 0; - } - return 0; -} -#else -int tdb_create_rwlocks(int fd, unsigned int hash_size) { return 0; } -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type) { return -1; } - -/* Non-spinlock version: remove spinlock pointer */ -int tdb_clear_spinlocks(TDB_CONTEXT *tdb) -{ - tdb_off off = (tdb_off)((char *)&tdb->header.rwlocks - - (char *)&tdb->header); - - tdb->header.rwlocks = 0; - if (lseek(tdb->fd, off, SEEK_SET) != off - || write(tdb->fd, (void *)&tdb->header.rwlocks, - sizeof(tdb->header.rwlocks)) - != sizeof(tdb->header.rwlocks)) - return -1; - return 0; -} -#endif diff --git a/tdb/spinlock.h b/tdb/spinlock.h deleted file mode 100644 index 8b0e833ff5..0000000000 --- a/tdb/spinlock.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __SPINLOCK_H__ -#define __SPINLOCK_H__ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "tdb.h" - -#ifdef USE_SPINLOCKS - -#define RWLOCK_BIAS 0x1000UL - -/* OS SPECIFIC */ -#define MAX_BUSY_LOOPS 1000 -#undef USE_SCHED_YIELD - -/* ARCH SPECIFIC */ -/* We should make sure these are padded to a cache line */ -#if defined(SPARC_SPINLOCKS) -typedef volatile char spinlock_t; -#elif defined(POWERPC_SPINLOCKS) -typedef volatile unsigned long spinlock_t; -#elif defined(INTEL_SPINLOCKS) -typedef volatile int spinlock_t; -#elif defined(MIPS_SPINLOCKS) -typedef volatile unsigned long spinlock_t; -#else -#error Need to implement spinlock code in spinlock.h -#endif - -typedef struct { - spinlock_t lock; - volatile int count; -} tdb_rwlock_t; - -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_create_rwlocks(int fd, unsigned int hash_size); -int tdb_clear_spinlocks(TDB_CONTEXT *tdb); - -#else /* !USE_SPINLOCKS */ -#if 0 -#define tdb_create_rwlocks(fd, hash_size) 0 -#define tdb_spinlock(tdb, list, rw_type) (-1) -#define tdb_spinunlock(tdb, list, rw_type) (-1) -#else -int tdb_spinlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_spinunlock(TDB_CONTEXT *tdb, int list, int rw_type); -int tdb_create_rwlocks(int fd, unsigned int hash_size); -#endif -int tdb_clear_spinlocks(TDB_CONTEXT *tdb); -#endif - -#endif diff --git a/tdb/tdb.c b/tdb/tdb.c deleted file mode 100644 index af475bb7ad..0000000000 --- a/tdb/tdb.c +++ /dev/null @@ -1,2099 +0,0 @@ - /* - Unix SMB/CIFS implementation. - Samba database functions - Copyright (C) Andrew Tridgell 1999-2000 - Copyright (C) Luke Kenneth Casson Leighton 2000 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000-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; 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -/* NOTE: If you use tdbs under valgrind, and in particular if you run - * tdbtorture, you may get spurious "uninitialized value" warnings. I - * think this is because valgrind doesn't understand that the mmap'd - * area may be written to by other processes. Memory can, from the - * point of view of the grinded process, spontaneously become - * initialized. - * - * I can think of a few solutions. [mbp 20030311] - * - * 1 - Write suppressions for Valgrind so that it doesn't complain - * about this. Probably the most reasonable but people need to - * remember to use them. - * - * 2 - Use IO not mmap when running under valgrind. Not so nice. - * - * 3 - Use the special valgrind macros to mark memory as valid at the - * right time. Probably too hard -- the process just doesn't know. - */ - -/* udev defines */ -#define STANDALONE -#define TDB_DEBUG -#define HAVE_MMAP 1 -/* this should prevent deadlocks loops on corrupt databases - * we've discovered. Most deadlocks happend by iterating over the - * list of entries with the same hash value. */ -#define LOOP_MAX 100000 -#define TDB_LOG(x) TDB_LOG_UDEV x -#define TDB_LOG_UDEV(tdb, level, format, arg...) info(format, ##arg) - -#ifdef STANDALONE -#if HAVE_CONFIG_H -#include -#endif - -#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" -#include "spinlock.h" -#include "../udev_lib.h" -#include "../logging.h" -#else -#include "includes.h" -#endif - -#define TDB_MAGIC_FOOD "TDB file\n" -#define TDB_VERSION (0x26011967 + 6) -#define TDB_MAGIC (0x26011999U) -#define TDB_FREE_MAGIC (~TDB_MAGIC) -#define TDB_DEAD_MAGIC (0xFEE1DEAD) -#define TDB_ALIGNMENT 4 -#define MIN_REC_SIZE (2*sizeof(struct list_struct) + TDB_ALIGNMENT) -#define DEFAULT_HASH_SIZE 131 -#define TDB_PAGE_SIZE 0x2000 -#define FREELIST_TOP (sizeof(struct tdb_header)) -#define TDB_ALIGN(x,a) (((x) + (a)-1) & ~((a)-1)) -#define TDB_BYTEREV(x) (((((x)&0xff)<<24)|((x)&0xFF00)<<8)|(((x)>>8)&0xFF00)|((x)>>24)) -#define TDB_DEAD(r) ((r)->magic == TDB_DEAD_MAGIC) -#define TDB_BAD_MAGIC(r) ((r)->magic != TDB_MAGIC && !TDB_DEAD(r)) -#define TDB_HASH_TOP(hash) (FREELIST_TOP + (BUCKET(hash)+1)*sizeof(tdb_off)) - -/* NB assumes there is a local variable called "tdb" that is the - * current context, also takes doubly-parenthesized print-style - * argument. */ -#ifndef TDB_LOG -#define TDB_LOG(x) (tdb->log_fn?((tdb->log_fn x),0) : 0) -#endif - -/* lock offsets */ -#define GLOBAL_LOCK 0 -#define ACTIVE_LOCK 4 - -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif - -#ifndef MAP_FAILED -#define MAP_FAILED ((void *)-1) -#endif - -/* free memory if the pointer is valid and zero the pointer */ -#ifndef SAFE_FREE -#define SAFE_FREE(x) do { if ((x) != NULL) {free((x)); (x)=NULL;} } while(0) -#endif - -#define BUCKET(hash) ((hash) % tdb->header.hash_size) -TDB_DATA tdb_null; - -/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ -static TDB_CONTEXT *tdbs = NULL; - -static int tdb_munmap(TDB_CONTEXT *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return 0; - -#ifdef HAVE_MMAP - if (tdb->map_ptr) { - int ret = munmap(tdb->map_ptr, tdb->map_size); - if (ret != 0) - return ret; - } -#endif - tdb->map_ptr = NULL; - return 0; -} - -static void tdb_mmap(TDB_CONTEXT *tdb) -{ - if (tdb->flags & TDB_INTERNAL) - return; - -#ifdef HAVE_MMAP - if (!(tdb->flags & TDB_NOMMAP)) { - tdb->map_ptr = mmap(NULL, tdb->map_size, - PROT_READ|(tdb->read_only? 0:PROT_WRITE), - MAP_SHARED|MAP_FILE, tdb->fd, 0); - - /* - * NB. When mmap fails it returns MAP_FAILED *NOT* NULL !!!! - */ - - if (tdb->map_ptr == MAP_FAILED) { - tdb->map_ptr = NULL; - TDB_LOG((tdb, 2, "tdb_mmap failed for size %d (%s)\n", - tdb->map_size, strerror(errno))); - } - } else { - tdb->map_ptr = NULL; - } -#else - tdb->map_ptr = NULL; -#endif -} - -/* Endian conversion: we only ever deal with 4 byte quantities */ -static void *convert(void *buf, u32 size) -{ - u32 i, *p = buf; - for (i = 0; i < size / 4; i++) - p[i] = TDB_BYTEREV(p[i]); - return buf; -} -#define DOCONV() (tdb->flags & TDB_CONVERT) -#define CONVERT(x) (DOCONV() ? convert(&x, sizeof(x)) : &x) - -/* the body of the database is made of one list_struct for the free space - plus a separate data list for each hash value */ -struct list_struct { - tdb_off next; /* offset of the next record in the list */ - tdb_len rec_len; /* total byte length of record */ - tdb_len key_len; /* byte length of key */ - tdb_len data_len; /* byte length of data */ - u32 full_hash; /* the full 32 bit hash of the key */ - u32 magic; /* try to catch errors */ - /* the following union is implied: - union { - char record[rec_len]; - struct { - char key[key_len]; - char data[data_len]; - } - u32 totalsize; (tailer) - } - */ -}; - -/*************************************************************** - Allow a caller to set a "alarm" flag that tdb can check to abort - a blocking lock on SIGALRM. -***************************************************************/ - -static sig_atomic_t *palarm_fired; - -void tdb_set_lock_alarm(sig_atomic_t *palarm) -{ - palarm_fired = palarm; -} - -/* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. - - On error, errno is also set so that errors are passed back properly - through tdb_open(). */ -static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset, - int rw_type, int lck_type, int probe) -{ - struct flock fl; - int ret; - - if (tdb->flags & TDB_NOLOCK) - return 0; - if ((rw_type == F_WRLCK) && (tdb->read_only)) { - errno = EACCES; - return -1; - } - - fl.l_type = rw_type; - fl.l_whence = SEEK_SET; - fl.l_start = offset; - fl.l_len = 1; - fl.l_pid = 0; - - do { - ret = fcntl(tdb->fd,lck_type,&fl); - if (ret == -1 && errno == EINTR && palarm_fired && *palarm_fired) - break; - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - if (!probe && lck_type != F_SETLK) { - /* Ensure error code is set for log fun to examine. */ - if (errno == EINTR && palarm_fired && *palarm_fired) - tdb->ecode = TDB_ERR_LOCK_TIMEOUT; - else - tdb->ecode = TDB_ERR_LOCK; - TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n", - tdb->fd, offset, rw_type, lck_type)); - } - /* Was it an alarm timeout ? */ - if (errno == EINTR && palarm_fired && *palarm_fired) - return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1); - /* Otherwise - generic lock error. */ - /* errno set by fcntl */ - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - } - return 0; -} - -/* lock a list in the database. list -1 is the alloc list */ -static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) -{ - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, 0,"tdb_lock: invalid list %d for ltype=%d\n", - list, ltype)); - return -1; - } - if (tdb->flags & TDB_NOLOCK) - return 0; - - /* Since fcntl locks don't nest, we do a lock for the first one, - and simply bump the count for future ones */ - if (tdb->locked[list+1].count == 0) { - if (!tdb->read_only && tdb->header.rwlocks) { - if (tdb_spinlock(tdb, list, ltype)) { - TDB_LOG((tdb, 0, "tdb_lock spinlock failed on list %d ltype=%d\n", - list, ltype)); - return -1; - } - } else if (tdb_brlock(tdb,FREELIST_TOP+4*list,ltype,F_SETLKW, 0)) { - TDB_LOG((tdb, 0,"tdb_lock failed on list %d ltype=%d (%s)\n", - list, ltype, strerror(errno))); - return -1; - } - tdb->locked[list+1].ltype = ltype; - } - tdb->locked[list+1].count++; - return 0; -} - -/* unlock the database: returns void because it's too late for errors. */ - /* changed to return int it may be interesting to know there - has been an error --simo */ -static int tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) -{ - int ret = -1; - - if (tdb->flags & TDB_NOLOCK) - return 0; - - /* Sanity checks */ - if (list < -1 || list >= (int)tdb->header.hash_size) { - TDB_LOG((tdb, 0, "tdb_unlock: list %d invalid (%d)\n", list, tdb->header.hash_size)); - return ret; - } - - if (tdb->locked[list+1].count==0) { - TDB_LOG((tdb, 0, "tdb_unlock: count is 0\n")); - return ret; - } - - if (tdb->locked[list+1].count == 1) { - /* Down to last nested lock: unlock underneath */ - if (!tdb->read_only && tdb->header.rwlocks) { - ret = tdb_spinunlock(tdb, list, ltype); - } else { - ret = tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0); - } - } else { - ret = 0; - } - tdb->locked[list+1].count--; - - if (ret) - TDB_LOG((tdb, 0,"tdb_unlock: An error occurred unlocking!\n")); - return ret; -} - -/* This is based on the hash algorithm from gdbm */ -static u32 tdb_hash(TDB_DATA *key) -{ - u32 value; /* Used to compute the hash value. */ - u32 i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) - value = (value + (key->dptr[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - -/* check for an out of bounds access - if it is out of bounds then - see if the database has been expanded by someone else and expand - if necessary - note that "len" is the minimum length needed for the db -*/ -static int tdb_oob(TDB_CONTEXT *tdb, tdb_off len, int probe) -{ - struct stat st; - if (len <= tdb->map_size) - return 0; - if (tdb->flags & TDB_INTERNAL) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_oob len %d beyond internal malloc size %d\n", - (int)len, (int)tdb->map_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - if (fstat(tdb->fd, &st) == -1) - return TDB_ERRCODE(TDB_ERR_IO, -1); - - if (st.st_size < (size_t)len) { - if (!probe) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_oob len %d beyond eof at %d\n", - (int)len, (int)st.st_size)); - } - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - - /* Unmap, update size, remap */ - if (tdb_munmap(tdb) == -1) - return TDB_ERRCODE(TDB_ERR_IO, -1); - tdb->map_size = st.st_size; - tdb_mmap(tdb); - return 0; -} - -/* write a lump of data at a specified offset */ -static int tdb_write(TDB_CONTEXT *tdb, tdb_off off, void *buf, tdb_len len) -{ - if (tdb_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->map_ptr) - memcpy(off + (char *)tdb->map_ptr, buf, len); -#ifdef HAVE_PWRITE - else if (pwrite(tdb->fd, buf, len, off) != (ssize_t)len) { -#else - else if (lseek(tdb->fd, off, SEEK_SET) != off - || write(tdb->fd, buf, len) != (ssize_t)len) { -#endif - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_write failed at %d len=%d (%s)\n", - off, len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - return 0; -} - -/* read a lump of data at a specified offset, maybe convert */ -static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv) -{ - if (tdb_oob(tdb, off + len, 0) != 0) - return -1; - - if (tdb->map_ptr) - memcpy(buf, off + (char *)tdb->map_ptr, len); -#ifdef HAVE_PREAD - else if (pread(tdb->fd, buf, len, off) != (ssize_t)len) { -#else - else if (lseek(tdb->fd, off, SEEK_SET) != off - || read(tdb->fd, buf, len) != (ssize_t)len) { -#endif - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_IO; - TDB_LOG((tdb, 0,"tdb_read failed at %d len=%d (%s)\n", - off, len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_IO, -1); - } - if (cv) - convert(buf, len); - return 0; -} - -/* read a lump of data, allocating the space for it */ -static char *tdb_alloc_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_len len) -{ - char *buf; - - if (!(buf = malloc(len))) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_OOM; - TDB_LOG((tdb, 0,"tdb_alloc_read malloc failed len=%d (%s)\n", - len, strerror(errno))); - return TDB_ERRCODE(TDB_ERR_OOM, buf); - } - if (tdb_read(tdb, offset, buf, len, 0) == -1) { - SAFE_FREE(buf); - return NULL; - } - return buf; -} - -/* read/write a tdb_off */ -static int ofs_read(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) -{ - return tdb_read(tdb, offset, (char*)d, sizeof(*d), DOCONV()); -} -static int ofs_write(TDB_CONTEXT *tdb, tdb_off offset, tdb_off *d) -{ - tdb_off off = *d; - return tdb_write(tdb, offset, CONVERT(off), sizeof(*d)); -} - -/* read/write a record */ -static int rec_read(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - if (tdb_read(tdb, offset, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - if (TDB_BAD_MAGIC(rec)) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, 0,"rec_read bad magic 0x%x at offset=%d\n", rec->magic, offset)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - return tdb_oob(tdb, rec->next+sizeof(*rec), 0); -} -static int rec_write(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - struct list_struct r = *rec; - return tdb_write(tdb, offset, CONVERT(r), sizeof(r)); -} - -/* read a freelist record and check for simple errors */ -static int rec_free_read(TDB_CONTEXT *tdb, tdb_off off, struct list_struct *rec) -{ - if (tdb_read(tdb, off, rec, sizeof(*rec),DOCONV()) == -1) - return -1; - - if (rec->magic == TDB_MAGIC) { - /* this happens when a app is showdown while deleting a record - we should - not completely fail when this happens */ - TDB_LOG((tdb, 0,"rec_free_read non-free magic 0x%x at offset=%d - fixing\n", - rec->magic, off)); - rec->magic = TDB_FREE_MAGIC; - if (tdb_write(tdb, off, rec, sizeof(*rec)) == -1) - return -1; - } - - if (rec->magic != TDB_FREE_MAGIC) { - /* Ensure ecode is set for log fn. */ - tdb->ecode = TDB_ERR_CORRUPT; - TDB_LOG((tdb, 0,"rec_free_read bad magic 0x%x at offset=%d\n", - rec->magic, off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - if (tdb_oob(tdb, rec->next+sizeof(*rec), 0) != 0) - return -1; - return 0; -} - -/* update a record tailer (must hold allocation lock) */ -static int update_tailer(TDB_CONTEXT *tdb, tdb_off offset, - const struct list_struct *rec) -{ - tdb_off totalsize; - - /* Offset of tailer from record header */ - totalsize = sizeof(*rec) + rec->rec_len; - return ofs_write(tdb, offset + totalsize - sizeof(tdb_off), - &totalsize); -} - -static tdb_off tdb_dump_record(TDB_CONTEXT *tdb, tdb_off offset) -{ - struct list_struct rec; - tdb_off tailer_ofs, tailer; - - if (tdb_read(tdb, offset, (char *)&rec, sizeof(rec), DOCONV()) == -1) { - printf("ERROR: failed to read record at %u\n", offset); - return 0; - } - - printf(" rec: offset=%u next=%d rec_len=%d key_len=%d data_len=%d full_hash=0x%x magic=0x%x\n", - offset, rec.next, rec.rec_len, rec.key_len, rec.data_len, rec.full_hash, rec.magic); - - tailer_ofs = offset + sizeof(rec) + rec.rec_len - sizeof(tdb_off); - if (ofs_read(tdb, tailer_ofs, &tailer) == -1) { - printf("ERROR: failed to read tailer at %u\n", tailer_ofs); - return rec.next; - } - - if (tailer != rec.rec_len + sizeof(rec)) { - printf("ERROR: tailer does not match record! tailer=%u totalsize=%u\n", - (unsigned)tailer, (unsigned)(rec.rec_len + sizeof(rec))); - } - return rec.next; -} - -static int tdb_dump_chain(TDB_CONTEXT *tdb, int i) -{ - tdb_off rec_ptr, top; - - top = TDB_HASH_TOP(i); - - if (tdb_lock(tdb, i, F_WRLCK) != 0) - return -1; - - if (ofs_read(tdb, top, &rec_ptr) == -1) - return tdb_unlock(tdb, i, F_WRLCK); - - if (rec_ptr) - printf("hash=%d\n", i); - - while (rec_ptr) { - rec_ptr = tdb_dump_record(tdb, rec_ptr); - } - - return tdb_unlock(tdb, i, F_WRLCK); -} - -void tdb_dump_all(TDB_CONTEXT *tdb) -{ - int i; - for (i=0;iheader.hash_size;i++) { - tdb_dump_chain(tdb, i); - } - printf("freelist:\n"); - tdb_dump_chain(tdb, -1); -} - -int tdb_printfreelist(TDB_CONTEXT *tdb) -{ - int ret; - long total_free = 0; - tdb_off offset, rec_ptr; - struct list_struct rec; - - if ((ret = tdb_lock(tdb, -1, F_WRLCK)) != 0) - return ret; - - offset = FREELIST_TOP; - - /* read in the freelist top */ - if (ofs_read(tdb, offset, &rec_ptr) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - } - - printf("freelist top=[0x%08x]\n", rec_ptr ); - while (rec_ptr) { - if (tdb_read(tdb, rec_ptr, (char *)&rec, sizeof(rec), DOCONV()) == -1) { - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - if (rec.magic != TDB_FREE_MAGIC) { - printf("bad magic 0x%08x in free list\n", rec.magic); - tdb_unlock(tdb, -1, F_WRLCK); - return -1; - } - - printf("entry offset=[0x%08x], rec.rec_len = [0x%08x (%d)]\n", rec.next, rec.rec_len, rec.rec_len ); - total_free += rec.rec_len; - - /* move to the next record */ - rec_ptr = rec.next; - } - printf("total rec_len = [0x%08x (%d)]\n", (int)total_free, - (int)total_free); - - return tdb_unlock(tdb, -1, F_WRLCK); -} - -/* Remove an element from the freelist. Must have alloc lock. */ -static int remove_from_freelist(TDB_CONTEXT *tdb, tdb_off off, tdb_off next) -{ - tdb_off last_ptr, i; - int maxloop; - - /* read in the freelist top */ - maxloop = LOOP_MAX; - last_ptr = FREELIST_TOP; - while (ofs_read(tdb, last_ptr, &i) != -1 && i != 0) { - if (i == off) { - /* We've found it! */ - return ofs_write(tdb, last_ptr, &next); - } - /* Follow chain (next offset is at start of record) */ - last_ptr = i; - - maxloop--; - if (maxloop == 0) { - TDB_LOG((tdb, 0, "remove_from_freelist: maxloop reached; corrupt database!\n")); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - } - TDB_LOG((tdb, 0,"remove_from_freelist: not on list at off=%d\n", off)); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); -} - -/* Add an element into the freelist. Merge adjacent records if - neccessary. */ -static int tdb_free(TDB_CONTEXT *tdb, tdb_off offset, struct list_struct *rec) -{ - tdb_off right, left; - - /* Allocation and tailer lock */ - if (tdb_lock(tdb, -1, F_WRLCK) != 0) - return -1; - - /* set an initial tailer, so if we fail we don't leave a bogus record */ - if (update_tailer(tdb, offset, rec) != 0) { - TDB_LOG((tdb, 0, "tdb_free: upfate_tailer failed!\n")); - goto fail; - } - - /* Look right first (I'm an Australian, dammit) */ - right = offset + sizeof(*rec) + rec->rec_len; - if (right + sizeof(*rec) <= tdb->map_size) { - struct list_struct r; - - if (tdb_read(tdb, right, &r, sizeof(r), DOCONV()) == -1) { - TDB_LOG((tdb, 0, "tdb_free: right read failed at %u\n", right)); - goto left; - } - - /* If it's free, expand to include it. */ - if (r.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, right, r.next) == -1) { - TDB_LOG((tdb, 0, "tdb_free: right free failed at %u\n", right)); - goto left; - } - rec->rec_len += sizeof(r) + r.rec_len; - } - } - -left: - /* Look left */ - left = offset - sizeof(tdb_off); - if (left > TDB_HASH_TOP(tdb->header.hash_size-1)) { - struct list_struct l; - tdb_off leftsize; - - /* Read in tailer and jump back to header */ - if (ofs_read(tdb, left, &leftsize) == -1) { - TDB_LOG((tdb, 0, "tdb_free: left offset read failed at %u\n", left)); - goto update; - } - left = offset - leftsize; - - /* Now read in record */ - if (tdb_read(tdb, left, &l, sizeof(l), DOCONV()) == -1) { - TDB_LOG((tdb, 0, "tdb_free: left read failed at %u (%u)\n", left, leftsize)); - goto update; - } - - /* If it's free, expand to include it. */ - if (l.magic == TDB_FREE_MAGIC) { - if (remove_from_freelist(tdb, left, l.next) == -1) { - TDB_LOG((tdb, 0, "tdb_free: left free failed at %u\n", left)); - goto update; - } else { - offset = left; - rec->rec_len += leftsize; - } - } - } - -update: - if (update_tailer(tdb, offset, rec) == -1) { - TDB_LOG((tdb, 0, "tdb_free: update_tailer failed at %u\n", offset)); - goto fail; - } - - /* Now, prepend to free list */ - rec->magic = TDB_FREE_MAGIC; - - if (ofs_read(tdb, FREELIST_TOP, &rec->next) == -1 || - rec_write(tdb, offset, rec) == -1 || - ofs_write(tdb, FREELIST_TOP, &offset) == -1) { - TDB_LOG((tdb, 0, "tdb_free record write failed at offset=%d\n", offset)); - goto fail; - } - - /* And we're done. */ - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - - -/* expand a file. we prefer to use ftruncate, as that is what posix - says to use for mmap expansion */ -static int expand_file(TDB_CONTEXT *tdb, tdb_off size, tdb_off addition) -{ - char buf[1024]; -#if HAVE_FTRUNCATE_EXTEND - if (ftruncate(tdb->fd, size+addition) != 0) { - TDB_LOG((tdb, 0, "expand_file ftruncate to %d failed (%s)\n", - size+addition, strerror(errno))); - return -1; - } -#else - char b = 0; - -#ifdef HAVE_PWRITE - if (pwrite(tdb->fd, &b, 1, (size+addition) - 1) != 1) { -#else - if (lseek(tdb->fd, (size+addition) - 1, SEEK_SET) != (size+addition) - 1 || - write(tdb->fd, &b, 1) != 1) { -#endif - TDB_LOG((tdb, 0, "expand_file to %d failed (%s)\n", - size+addition, strerror(errno))); - return -1; - } -#endif - - /* now fill the file with something. This ensures that the file isn't sparse, which would be - very bad if we ran out of disk. This must be done with write, not via mmap */ - memset(buf, 0x42, sizeof(buf)); - while (addition) { - int n = addition>sizeof(buf)?sizeof(buf):addition; -#ifdef HAVE_PWRITE - int ret = pwrite(tdb->fd, buf, n, size); -#else - int ret; - if (lseek(tdb->fd, size, SEEK_SET) != size) - return -1; - ret = write(tdb->fd, buf, n); -#endif - if (ret != n) { - TDB_LOG((tdb, 0, "expand_file write of %d failed (%s)\n", - n, strerror(errno))); - return -1; - } - addition -= n; - size += n; - } - return 0; -} - - -/* expand the database at least size bytes by expanding the underlying - file and doing the mmap again if necessary */ -static int tdb_expand(TDB_CONTEXT *tdb, tdb_off size) -{ - struct list_struct rec; - tdb_off offset; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) { - TDB_LOG((tdb, 0, "lock failed in tdb_expand\n")); - return -1; - } - - /* must know about any previous expansions by another process */ - tdb_oob(tdb, tdb->map_size + 1, 1); - - /* always make room for at least 10 more records, and round - the database up to a multiple of TDB_PAGE_SIZE */ - size = TDB_ALIGN(tdb->map_size + size*10, TDB_PAGE_SIZE) - tdb->map_size; - - if (!(tdb->flags & TDB_INTERNAL)) - tdb_munmap(tdb); - - /* - * We must ensure the file is unmapped before doing this - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* expand the file itself */ - if (!(tdb->flags & TDB_INTERNAL)) { - if (expand_file(tdb, tdb->map_size, size) != 0) - goto fail; - } - - tdb->map_size += size; - - if (tdb->flags & TDB_INTERNAL) - tdb->map_ptr = realloc(tdb->map_ptr, tdb->map_size); - else { - /* - * We must ensure the file is remapped before adding the space - * to ensure consistency with systems like OpenBSD where - * writes and mmaps are not consistent. - */ - - /* We're ok if the mmap fails as we'll fallback to read/write */ - tdb_mmap(tdb); - } - - /* form a new freelist record */ - memset(&rec,'\0',sizeof(rec)); - rec.rec_len = size - sizeof(rec); - - /* link it into the free list */ - offset = tdb->map_size - size; - if (tdb_free(tdb, offset, &rec) == -1) - goto fail; - - tdb_unlock(tdb, -1, F_WRLCK); - return 0; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return -1; -} - -/* allocate some space from the free list. The offset returned points - to a unconnected list_struct within the database with room for at - least length bytes of total data - - 0 is returned if the space could not be allocated - */ -static tdb_off tdb_allocate(TDB_CONTEXT *tdb, tdb_len length, - struct list_struct *rec) -{ - tdb_off rec_ptr, last_ptr, newrec_ptr; - struct list_struct newrec; - int maxloop; - - if (tdb_lock(tdb, -1, F_WRLCK) == -1) - return 0; - - /* Extra bytes required for tailer */ - length += sizeof(tdb_off); - - again: - last_ptr = FREELIST_TOP; - - /* read in the freelist top */ - if (ofs_read(tdb, FREELIST_TOP, &rec_ptr) == -1) - goto fail; - - /* keep looking until we find a freelist record big enough */ - maxloop = LOOP_MAX; - while (rec_ptr) { - if (rec_free_read(tdb, rec_ptr, rec) == -1) - goto fail; - - if (rec->rec_len >= length) { - /* found it - now possibly split it up */ - if (rec->rec_len > length + MIN_REC_SIZE) { - /* Length of left piece */ - length = TDB_ALIGN(length, TDB_ALIGNMENT); - - /* Right piece to go on free list */ - newrec.rec_len = rec->rec_len - - (sizeof(*rec) + length); - newrec_ptr = rec_ptr + sizeof(*rec) + length; - - /* And left record is shortened */ - rec->rec_len = length; - } else - newrec_ptr = 0; - - /* Remove allocated record from the free list */ - if (ofs_write(tdb, last_ptr, &rec->next) == -1) - goto fail; - - /* Update header: do this before we drop alloc - lock, otherwise tdb_free() might try to - merge with us, thinking we're free. - (Thanks Jeremy Allison). */ - rec->magic = TDB_MAGIC; - if (rec_write(tdb, rec_ptr, rec) == -1) - goto fail; - - /* Did we create new block? */ - if (newrec_ptr) { - /* Update allocated record tailer (we - shortened it). */ - if (update_tailer(tdb, rec_ptr, rec) == -1) - goto fail; - - /* Free new record */ - if (tdb_free(tdb, newrec_ptr, &newrec) == -1) - goto fail; - } - - /* all done - return the new record offset */ - tdb_unlock(tdb, -1, F_WRLCK); - return rec_ptr; - } - /* move to the next record */ - last_ptr = rec_ptr; - rec_ptr = rec->next; - - maxloop--; - if (maxloop == 0) { - TDB_LOG((tdb, 0, "tdb_allocate: maxloop reached; corrupt database!\n")); - return TDB_ERRCODE(TDB_ERR_CORRUPT, 0); - } - } - /* we didn't find enough space. See if we can expand the - database and if we can then try again */ - if (tdb_expand(tdb, length + sizeof(*rec)) == 0) - goto again; - fail: - tdb_unlock(tdb, -1, F_WRLCK); - return 0; -} - -/* initialise a new database with a specified hash size */ -static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) -{ - struct tdb_header *newdb; - int size, ret = -1; - - /* We make it up in memory, then write it out if not internal */ - size = sizeof(struct tdb_header) + (hash_size+1)*sizeof(tdb_off); - if (!(newdb = calloc(size, 1))) - return TDB_ERRCODE(TDB_ERR_OOM, -1); - - /* Fill in the header */ - newdb->version = TDB_VERSION; - newdb->hash_size = hash_size; -#ifdef USE_SPINLOCKS - newdb->rwlocks = size; -#endif - if (tdb->flags & TDB_INTERNAL) { - tdb->map_size = size; - tdb->map_ptr = (char *)newdb; - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Convert the `ondisk' version if asked. */ - CONVERT(*newdb); - return 0; - } - if (lseek(tdb->fd, 0, SEEK_SET) == -1) - goto fail; - - if (ftruncate(tdb->fd, 0) == -1) - goto fail; - - /* This creates an endian-converted header, as if read from disk */ - CONVERT(*newdb); - memcpy(&tdb->header, newdb, sizeof(tdb->header)); - /* Don't endian-convert the magic food! */ - memcpy(newdb->magic_food, TDB_MAGIC_FOOD, strlen(TDB_MAGIC_FOOD)+1); - if (write(tdb->fd, newdb, size) != size) - ret = -1; - else - ret = tdb_create_rwlocks(tdb->fd, hash_size); - - fail: - SAFE_FREE(newdb); - return ret; -} - -/* Returns 0 on fail. On success, return offset of record, and fills - in rec */ -static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, - struct list_struct *r) -{ - tdb_off rec_ptr; - int maxloop; - - /* read in the hash top */ - if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) - return 0; - - /* keep looking until we find the right record */ - maxloop = LOOP_MAX; - while (rec_ptr) { - if (rec_read(tdb, rec_ptr, r) == -1) - return 0; - - if (!TDB_DEAD(r) && hash==r->full_hash && key.dsize==r->key_len) { - char *k; - /* a very likely hit - read the key */ - k = tdb_alloc_read(tdb, rec_ptr + sizeof(*r), - r->key_len); - if (!k) - return 0; - - if (memcmp(key.dptr, k, key.dsize) == 0) { - SAFE_FREE(k); - return rec_ptr; - } - SAFE_FREE(k); - } - rec_ptr = r->next; - - maxloop--; - if (maxloop == 0) { - TDB_LOG((tdb, 0, "tdb_find maxloop reached; corrupt database!\n")); - return TDB_ERRCODE(TDB_ERR_CORRUPT, 0); - } - } - return TDB_ERRCODE(TDB_ERR_NOEXIST, 0); -} - -/* If they do lockkeys, check that this hash is one they locked */ -static int tdb_keylocked(TDB_CONTEXT *tdb, u32 hash) -{ - u32 i; - if (!tdb->lockedkeys) - return 1; - for (i = 0; i < tdb->lockedkeys[0]; i++) - if (tdb->lockedkeys[i+1] == hash) - return 1; - return TDB_ERRCODE(TDB_ERR_NOLOCK, 0); -} - -/* As tdb_find, but if you succeed, keep the lock */ -static tdb_off tdb_find_lock(TDB_CONTEXT *tdb, TDB_DATA key, int locktype, - struct list_struct *rec) -{ - u32 hash, rec_ptr; - - hash = tdb_hash(&key); - if (!tdb_keylocked(tdb, hash)) - return 0; - if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) - return 0; - if (!(rec_ptr = tdb_find(tdb, key, hash, rec))) - tdb_unlock(tdb, BUCKET(hash), locktype); - return rec_ptr; -} - -enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb) -{ - return tdb->ecode; -} - -static struct tdb_errname { - enum TDB_ERROR ecode; const char *estring; -} emap[] = { {TDB_SUCCESS, "Success"}, - {TDB_ERR_CORRUPT, "Corrupt database"}, - {TDB_ERR_IO, "IO Error"}, - {TDB_ERR_LOCK, "Locking error"}, - {TDB_ERR_OOM, "Out of memory"}, - {TDB_ERR_EXISTS, "Record exists"}, - {TDB_ERR_NOLOCK, "Lock exists on other keys"}, - {TDB_ERR_NOEXIST, "Record does not exist"} }; - -/* Error string for the last tdb error */ -const char *tdb_errorstr(TDB_CONTEXT *tdb) -{ - u32 i; - for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) - if (tdb->ecode == emap[i].ecode) - return emap[i].estring; - return "Invalid error code"; -} - -/* update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. -*/ - -static int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf) -{ - struct list_struct rec; - tdb_off rec_ptr; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec))) - return -1; - - /* must be long enough key, data and tailer */ - if (rec.rec_len < key.dsize + dbuf.dsize + sizeof(tdb_off)) { - tdb->ecode = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len, - dbuf.dptr, dbuf.dsize) == -1) - return -1; - - if (dbuf.dsize != rec.data_len) { - /* update size */ - rec.data_len = dbuf.dsize; - return rec_write(tdb, rec_ptr, &rec); - } - - return 0; -} - -/* find an entry in the database given a key */ -/* If an entry doesn't exist tdb_err will be set to - * TDB_ERR_NOEXIST. If a key has no data attached - * tdb_err will not be set. Both will return a - * zero pptr and zero dsize. - */ - -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) -{ - tdb_off rec_ptr; - struct list_struct rec; - TDB_DATA ret; - - /* find which hash bucket it is in */ - if (!(rec_ptr = tdb_find_lock(tdb,key,F_RDLCK,&rec))) - return tdb_null; - - if (rec.data_len) - ret.dptr = tdb_alloc_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, - rec.data_len); - else - ret.dptr = NULL; - ret.dsize = rec.data_len; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return ret; -} - -/* check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm -*/ -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) -{ - struct list_struct rec; - - if (tdb_find_lock(tdb, key, F_RDLCK, &rec) == 0) - return 0; - tdb_unlock(tdb, BUCKET(rec.full_hash), F_RDLCK); - return 1; -} - -/* record lock stops delete underneath */ -static int lock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0; -} -/* - Write locks override our own fcntl readlocks, so check it here. - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ - -static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - struct tdb_traverse_lock *i; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - return -1; - return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1); -} - -/* - Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not - an error to fail to get the lock here. -*/ - -static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0); -} -/* fcntl locks don't stack: avoid unlocking someone else's */ -static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) -{ - struct tdb_traverse_lock *i; - u32 count = 0; - - if (off == 0) - return 0; - for (i = &tdb->travlocks; i; i = i->next) - if (i->off == off) - count++; - return (count == 1 ? tdb_brlock(tdb, off, F_UNLCK, F_SETLKW, 0) : 0); -} - -/* actually delete an entry in the database given the offset */ -static int do_delete(TDB_CONTEXT *tdb, tdb_off rec_ptr, struct list_struct*rec) -{ - tdb_off last_ptr, i; - struct list_struct lastrec; - int maxloop; - - if (tdb->read_only) return -1; - - if (write_lock_record(tdb, rec_ptr) == -1) { - /* Someone traversing here: mark it as dead */ - rec->magic = TDB_DEAD_MAGIC; - return rec_write(tdb, rec_ptr, rec); - } - if (write_unlock_record(tdb, rec_ptr) != 0) - return -1; - - /* find previous record in hash chain */ - if (ofs_read(tdb, TDB_HASH_TOP(rec->full_hash), &i) == -1) - return -1; - - maxloop = LOOP_MAX; - for (last_ptr = 0; i != rec_ptr; last_ptr = i, i = lastrec.next) { - if (rec_read(tdb, i, &lastrec) == -1) - return -1; - - maxloop--; - if (maxloop == 0) { - TDB_LOG((tdb, 0, "(tdb)do_delete: maxloop reached; corrupt database!\n")); - return TDB_ERRCODE(TDB_ERR_CORRUPT, -1); - } - } - - /* unlink it: next ptr is at start of record. */ - if (last_ptr == 0) - last_ptr = TDB_HASH_TOP(rec->full_hash); - if (ofs_write(tdb, last_ptr, &rec->next) == -1) - return -1; - - /* recover the space */ - if (tdb_free(tdb, rec_ptr, rec) == -1) - return -1; - return 0; -} - -/* Uses traverse lock: 0 = finish, -1 = error, other = record offset */ -static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, - struct list_struct *rec) -{ - int want_next = (tlock->off != 0); - - /* No traversal allows if you've called tdb_lockkeys() */ - if (tdb->lockedkeys) - return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); - - /* Lock each chain from the start one. */ - for (; tlock->hash < tdb->header.hash_size; tlock->hash++) { - if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1) - return -1; - - /* No previous record? Start at top of chain. */ - if (!tlock->off) { - if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), - &tlock->off) == -1) - goto fail; - } else { - /* Otherwise unlock the previous record. */ - if (unlock_record(tdb, tlock->off) != 0) - goto fail; - } - - if (want_next) { - /* We have offset of old record: grab next */ - if (rec_read(tdb, tlock->off, rec) == -1) - goto fail; - tlock->off = rec->next; - } - - /* Iterate through chain */ - while( tlock->off) { - tdb_off current; - if (rec_read(tdb, tlock->off, rec) == -1) - goto fail; - if (!TDB_DEAD(rec)) { - /* Woohoo: we found one! */ - if (lock_record(tdb, tlock->off) != 0) - goto fail; - return tlock->off; - } - /* Try to clean dead ones from old traverses */ - current = tlock->off; - tlock->off = rec->next; - if (!tdb->read_only && - do_delete(tdb, current, rec) != 0) - goto fail; - } - tdb_unlock(tdb, tlock->hash, F_WRLCK); - want_next = 0; - } - /* We finished iteration without finding anything */ - return TDB_ERRCODE(TDB_SUCCESS, 0); - - fail: - tlock->off = 0; - if (tdb_unlock(tdb, tlock->hash, F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_next_lock: On error unlock failed!\n")); - return -1; -} - -/* traverse the entire database - calling fn(tdb, key, data) on each element. - return -1 on error or the record count traversed - if fn is NULL then it is not called - a non-zero return value from fn() indicates that the traversal should stop - */ -int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state) -{ - TDB_DATA key, dbuf; - struct list_struct rec; - struct tdb_traverse_lock tl = { NULL, 0, 0 }; - int ret, count = 0; - - /* This was in the initializaton, above, but the IRIX compiler - * did not like it. crh - */ - tl.next = tdb->travlocks.next; - - /* fcntl locks don't stack: beware traverse inside traverse */ - tdb->travlocks.next = &tl; - - /* tdb_next_lock places locks on the record returned, and its chain */ - while ((ret = tdb_next_lock(tdb, &tl, &rec)) > 0) { - count++; - /* now read the full record */ - key.dptr = tdb_alloc_read(tdb, tl.off + sizeof(rec), - rec.key_len + rec.data_len); - if (!key.dptr) { - ret = -1; - if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) - goto out; - if (unlock_record(tdb, tl.off) != 0) - TDB_LOG((tdb, 0, "tdb_traverse: key.dptr == NULL and unlock_record failed!\n")); - goto out; - } - key.dsize = rec.key_len; - dbuf.dptr = key.dptr + rec.key_len; - dbuf.dsize = rec.data_len; - - /* Drop chain lock, call out */ - if (tdb_unlock(tdb, tl.hash, F_WRLCK) != 0) { - ret = -1; - goto out; - } - if (fn && fn(tdb, key, dbuf, state)) { - /* They want us to terminate traversal */ - ret = count; - if (unlock_record(tdb, tl.off) != 0) { - TDB_LOG((tdb, 0, "tdb_traverse: unlock_record failed!\n"));; - ret = -1; - } - tdb->travlocks.next = tl.next; - SAFE_FREE(key.dptr); - return count; - } - SAFE_FREE(key.dptr); - } -out: - tdb->travlocks.next = tl.next; - if (ret < 0) - return -1; - else - return count; -} - -/* find the first entry in the database and return its key */ -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) -{ - TDB_DATA key; - struct list_struct rec; - - /* release any old lock */ - if (unlock_record(tdb, tdb->travlocks.off) != 0) - return tdb_null; - tdb->travlocks.off = tdb->travlocks.hash = 0; - - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) <= 0) - return tdb_null; - /* now read the key */ - key.dsize = rec.key_len; - key.dptr =tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec),key.dsize); - if (tdb_unlock(tdb, BUCKET(tdb->travlocks.hash), F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_firstkey: error occurred while tdb_unlocking!\n")); - return key; -} - -/* find the next entry in the database, returning its key */ -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) -{ - u32 oldhash; - TDB_DATA key = tdb_null; - struct list_struct rec; - char *k = NULL; - - /* Is locked key the old key? If so, traverse will be reliable. */ - if (tdb->travlocks.off) { - if (tdb_lock(tdb,tdb->travlocks.hash,F_WRLCK)) - return tdb_null; - if (rec_read(tdb, tdb->travlocks.off, &rec) == -1 - || !(k = tdb_alloc_read(tdb,tdb->travlocks.off+sizeof(rec), - rec.key_len)) - || memcmp(k, oldkey.dptr, oldkey.dsize) != 0) { - /* No, it wasn't: unlock it and start from scratch */ - if (unlock_record(tdb, tdb->travlocks.off) != 0) - return tdb_null; - if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) - return tdb_null; - tdb->travlocks.off = 0; - } - - SAFE_FREE(k); - } - - if (!tdb->travlocks.off) { - /* No previous element: do normal find, and lock record */ - tdb->travlocks.off = tdb_find_lock(tdb, oldkey, F_WRLCK, &rec); - if (!tdb->travlocks.off) - return tdb_null; - tdb->travlocks.hash = BUCKET(rec.full_hash); - if (lock_record(tdb, tdb->travlocks.off) != 0) { - TDB_LOG((tdb, 0, "tdb_nextkey: lock_record failed (%s)!\n", strerror(errno))); - return tdb_null; - } - } - oldhash = tdb->travlocks.hash; - - /* Grab next record: locks chain and returned record, - unlocks old record */ - if (tdb_next_lock(tdb, &tdb->travlocks, &rec) > 0) { - key.dsize = rec.key_len; - key.dptr = tdb_alloc_read(tdb, tdb->travlocks.off+sizeof(rec), - key.dsize); - /* Unlock the chain of this new record */ - if (tdb_unlock(tdb, tdb->travlocks.hash, F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - } - /* Unlock the chain of old record */ - if (tdb_unlock(tdb, BUCKET(oldhash), F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_nextkey: WARNING tdb_unlock failed!\n")); - return key; -} - -/* delete an entry in the database given a key */ -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) -{ - tdb_off rec_ptr; - struct list_struct rec; - int ret; - - if (!(rec_ptr = tdb_find_lock(tdb, key, F_WRLCK, &rec))) - return -1; - ret = do_delete(tdb, rec_ptr, &rec); - if (tdb_unlock(tdb, BUCKET(rec.full_hash), F_WRLCK) != 0) - TDB_LOG((tdb, 0, "tdb_delete: WARNING tdb_unlock failed!\n")); - return ret; -} - -/* store an element in the database, replacing any existing element - with the same key - - return 0 on success, -1 on failure -*/ -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) -{ - struct list_struct rec; - u32 hash; - tdb_off rec_ptr; - char *p = NULL; - int ret = 0; - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - if (!tdb_keylocked(tdb, hash)) - return -1; - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - /* check for it existing, on insert. */ - if (flag == TDB_INSERT) { - if (tdb_exists(tdb, key)) { - tdb->ecode = TDB_ERR_EXISTS; - goto fail; - } - } else { - /* first try in-place update, on modify or replace. */ - if (tdb_update(tdb, key, dbuf) == 0) - goto out; - if (flag == TDB_MODIFY && tdb->ecode == TDB_ERR_NOEXIST) - goto fail; - } - /* reset the error code potentially set by the tdb_update() */ - tdb->ecode = TDB_SUCCESS; - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - if (flag != TDB_INSERT) - tdb_delete(tdb, key); - - /* Copy key+value *before* allocating free space in case malloc - fails and we are left with a dead spot in the tdb. */ - - if (!(p = (char *)malloc(key.dsize + dbuf.dsize))) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - memcpy(p, key.dptr, key.dsize); - if (dbuf.dsize) - memcpy(p+key.dsize, dbuf.dptr, dbuf.dsize); - - /* now we're into insert / modify / replace of a record which - * we know could not be optimised by an in-place store (for - * various reasons). */ - if (!(rec_ptr = tdb_allocate(tdb, key.dsize + dbuf.dsize, &rec))) - goto fail; - - /* Read hash top into next ptr */ - if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = dbuf.dsize; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - /* write out and point the top of the hash chain at it */ - if (rec_write(tdb, rec_ptr, &rec) == -1 - || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+dbuf.dsize)==-1 - || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { - /* Need to tdb_unallocate() here */ - goto fail; - } - out: - SAFE_FREE(p); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; -fail: - ret = -1; - goto out; -} - -/* Attempt to append data to an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1. Record must be locked before calling. -*/ -static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) -{ - struct list_struct rec; - tdb_off rec_ptr; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, tdb_hash(&key), &rec))) - return -1; - - /* Append of 0 is always ok. */ - if (new_dbuf.dsize == 0) - return 0; - - /* must be long enough for key, old data + new data and tailer */ - if (rec.rec_len < key.dsize + rec.data_len + new_dbuf.dsize + sizeof(tdb_off)) { - /* No room. */ - tdb->ecode = TDB_SUCCESS; /* Not really an error */ - return -1; - } - - if (tdb_write(tdb, rec_ptr + sizeof(rec) + rec.key_len + rec.data_len, - new_dbuf.dptr, new_dbuf.dsize) == -1) - return -1; - - /* update size */ - rec.data_len += new_dbuf.dsize; - return rec_write(tdb, rec_ptr, &rec); -} - -/* Append to an entry. Create if not exist. */ - -int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) -{ - struct list_struct rec; - u32 hash; - tdb_off rec_ptr; - char *p = NULL; - int ret = 0; - size_t new_data_size = 0; - - /* find which hash bucket it is in */ - hash = tdb_hash(&key); - if (!tdb_keylocked(tdb, hash)) - return -1; - if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) - return -1; - - /* first try in-place. */ - if (tdb_append_inplace(tdb, key, new_dbuf) == 0) - goto out; - - /* reset the error code potentially set by the tdb_append_inplace() */ - tdb->ecode = TDB_SUCCESS; - - /* find entry */ - if (!(rec_ptr = tdb_find(tdb, key, hash, &rec))) { - if (tdb->ecode != TDB_ERR_NOEXIST) - goto fail; - - /* Not found - create. */ - - ret = tdb_store(tdb, key, new_dbuf, TDB_INSERT); - goto out; - } - - new_data_size = rec.data_len + new_dbuf.dsize; - - /* Copy key+old_value+value *before* allocating free space in case malloc - fails and we are left with a dead spot in the tdb. */ - - if (!(p = (char *)malloc(key.dsize + new_data_size))) { - tdb->ecode = TDB_ERR_OOM; - goto fail; - } - - /* Copy the key in place. */ - memcpy(p, key.dptr, key.dsize); - - /* Now read the old data into place. */ - if (rec.data_len && - tdb_read(tdb, rec_ptr + sizeof(rec) + rec.key_len, p + key.dsize, rec.data_len, 0) == -1) - goto fail; - - /* Finally append the new data. */ - if (new_dbuf.dsize) - memcpy(p+key.dsize+rec.data_len, new_dbuf.dptr, new_dbuf.dsize); - - /* delete any existing record - if it doesn't exist we don't - care. Doing this first reduces fragmentation, and avoids - coalescing with `allocated' block before it's updated. */ - - tdb_delete(tdb, key); - - if (!(rec_ptr = tdb_allocate(tdb, key.dsize + new_data_size, &rec))) - goto fail; - - /* Read hash top into next ptr */ - if (ofs_read(tdb, TDB_HASH_TOP(hash), &rec.next) == -1) - goto fail; - - rec.key_len = key.dsize; - rec.data_len = new_data_size; - rec.full_hash = hash; - rec.magic = TDB_MAGIC; - - /* write out and point the top of the hash chain at it */ - if (rec_write(tdb, rec_ptr, &rec) == -1 - || tdb_write(tdb, rec_ptr+sizeof(rec), p, key.dsize+new_data_size)==-1 - || ofs_write(tdb, TDB_HASH_TOP(hash), &rec_ptr) == -1) { - /* Need to tdb_unallocate() here */ - goto fail; - } - - out: - SAFE_FREE(p); - tdb_unlock(tdb, BUCKET(hash), F_WRLCK); - return ret; - -fail: - ret = -1; - goto out; -} - -static int tdb_already_open(dev_t device, - ino_t ino) -{ - TDB_CONTEXT *i; - - for (i = tdbs; i; i = i->next) { - if (i->device == device && i->inode == ino) { - return 1; - } - } - - return 0; -} - -/* open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the - database file. A flags value of O_WRONLY is invalid. The hash size - is advisory, use zero for a default value. - - Return is NULL on error, in which case errno is also set. Don't - try to call tdb_error or tdb_errname, just do strerror(errno). - - @param name may be NULL for internal databases. */ -TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - return tdb_open_ex(name, hash_size, tdb_flags, open_flags, mode, NULL); -} - - -TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn) -{ - TDB_CONTEXT *tdb; - struct stat st; - int rev = 0, locked; - unsigned char *vp; - u32 vertest; - - if (!(tdb = calloc(1, sizeof *tdb))) { - /* Can't log this */ - errno = ENOMEM; - goto fail; - } - tdb->fd = -1; - tdb->name = NULL; - tdb->map_ptr = NULL; - tdb->lockedkeys = NULL; - tdb->flags = tdb_flags; - tdb->open_flags = open_flags; - tdb->log_fn = log_fn; - - if ((open_flags & O_ACCMODE) == O_WRONLY) { - TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n", - name)); - errno = EINVAL; - goto fail; - } - - if (hash_size == 0) - hash_size = DEFAULT_HASH_SIZE; - if ((open_flags & O_ACCMODE) == O_RDONLY) { - tdb->read_only = 1; - /* read only databases don't do locking or clear if first */ - tdb->flags |= TDB_NOLOCK; - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - } - - /* internal databases don't mmap or lock, and start off cleared */ - if (tdb->flags & TDB_INTERNAL) { - tdb->flags |= (TDB_NOLOCK | TDB_NOMMAP); - tdb->flags &= ~TDB_CLEAR_IF_FIRST; - if (tdb_new_database(tdb, hash_size) != 0) { - TDB_LOG((tdb, 0, "tdb_open_ex: tdb_new_database failed!")); - goto fail; - } - goto internal; - } - - if ((tdb->fd = open(name, open_flags, mode)) == -1) { - TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by open(2) */ - } - - /* - Close file when execing another process. - Prevents SELinux access errors. - */ - set_cloexec_flag(tdb->fd, 1); - - /* ensure there is only one process initialising at once */ - if (tdb_brlock(tdb, GLOBAL_LOCK, F_WRLCK, F_SETLKW, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_open_ex: failed to get global lock on %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by tdb_brlock */ - } - - /* we need to zero database if we are the only one with it open */ - if ((locked = (tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0) == 0)) - && (tdb_flags & TDB_CLEAR_IF_FIRST)) { - open_flags |= O_CREAT; - if (ftruncate(tdb->fd, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_open_ex: " - "failed to truncate %s: %s\n", - name, strerror(errno))); - goto fail; /* errno set by ftruncate */ - } - } - - if (read(tdb->fd, &tdb->header, sizeof(tdb->header)) != sizeof(tdb->header) - || strcmp(tdb->header.magic_food, TDB_MAGIC_FOOD) != 0 - || (tdb->header.version != TDB_VERSION - && !(rev = (tdb->header.version==TDB_BYTEREV(TDB_VERSION))))) { - /* its not a valid database - possibly initialise it */ - if (!(open_flags & O_CREAT) || tdb_new_database(tdb, hash_size) == -1) { - errno = EIO; /* ie bad format or something */ - goto fail; - } - rev = (tdb->flags & TDB_CONVERT); - } - vp = (unsigned char *)&tdb->header.version; - vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) | - (((u32)vp[2]) << 8) | (u32)vp[3]; - tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; - if (!rev) - tdb->flags &= ~TDB_CONVERT; - else { - tdb->flags |= TDB_CONVERT; - convert(&tdb->header, sizeof(tdb->header)); - } - if (fstat(tdb->fd, &st) == -1) - goto fail; - - /* Is it already in the open list? If so, fail. */ - if (tdb_already_open(st.st_dev, st.st_ino)) { - TDB_LOG((tdb, 2, "tdb_open_ex: " - "%s (%d:%d,%lld) is already open in this process\n", - name, major(st.st_dev), minor(st.st_dev), (unsigned long long)st.st_ino)); - errno = EBUSY; - goto fail; - } - - if (!(tdb->name = (char *)strdup(name))) { - errno = ENOMEM; - goto fail; - } - - tdb->map_size = st.st_size; - tdb->device = st.st_dev; - tdb->inode = st.st_ino; - tdb->locked = calloc(tdb->header.hash_size+1, sizeof(tdb->locked[0])); - if (!tdb->locked) { - TDB_LOG((tdb, 2, "tdb_open_ex: " - "failed to allocate lock structure for %s\n", - name)); - errno = ENOMEM; - goto fail; - } - tdb_mmap(tdb); - if (locked) { - if (!tdb->read_only) - if (tdb_clear_spinlocks(tdb) != 0) { - TDB_LOG((tdb, 0, "tdb_open_ex: " - "failed to clear spinlock\n")); - goto fail; - } - if (tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_open_ex: " - "failed to take ACTIVE_LOCK on %s: %s\n", - name, strerror(errno))); - goto fail; - } - } - /* leave this lock in place to indicate it's in use */ - if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) - goto fail; - - internal: - /* Internal (memory-only) databases skip all the code above to - * do with disk files, and resume here by releasing their - * global lock and hooking into the active list. */ - if (tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0) == -1) - goto fail; - tdb->next = tdbs; - tdbs = tdb; - return tdb; - - fail: - { int save_errno = errno; - - if (!tdb) - return NULL; - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - if (close(tdb->fd) != 0) - TDB_LOG((tdb, 5, "tdb_open_ex: failed to close tdb->fd on error!\n")); - SAFE_FREE(tdb->locked); - SAFE_FREE(tdb); - errno = save_errno; - return NULL; - } -} - -/** - * Close a database. - * - * @returns -1 for error; 0 for success. - **/ -int tdb_close(TDB_CONTEXT *tdb) -{ - TDB_CONTEXT **i; - int ret = 0; - - if (tdb->map_ptr) { - if (tdb->flags & TDB_INTERNAL) - SAFE_FREE(tdb->map_ptr); - else - tdb_munmap(tdb); - } - SAFE_FREE(tdb->name); - if (tdb->fd != -1) - ret = close(tdb->fd); - SAFE_FREE(tdb->locked); - SAFE_FREE(tdb->lockedkeys); - - /* Remove from contexts list */ - for (i = &tdbs; *i; i = &(*i)->next) { - if (*i == tdb) { - *i = tdb->next; - break; - } - } - - memset(tdb, 0, sizeof(*tdb)); - SAFE_FREE(tdb); - - return ret; -} - -/* lock/unlock entire database */ -int tdb_lockall(TDB_CONTEXT *tdb) -{ - u32 i; - - /* There are no locks on read-only dbs */ - if (tdb->read_only) - return TDB_ERRCODE(TDB_ERR_LOCK, -1); - if (tdb->lockedkeys) - return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); - for (i = 0; i < tdb->header.hash_size; i++) - if (tdb_lock(tdb, i, F_WRLCK)) - break; - - /* If error, release locks we have... */ - if (i < tdb->header.hash_size) { - u32 j; - - for ( j = 0; j < i; j++) - tdb_unlock(tdb, j, F_WRLCK); - return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); - } - - return 0; -} -void tdb_unlockall(TDB_CONTEXT *tdb) -{ - u32 i; - for (i=0; i < tdb->header.hash_size; i++) - tdb_unlock(tdb, i, F_WRLCK); -} - -int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]) -{ - u32 i, j, hash; - - /* Can't lock more keys if already locked */ - if (tdb->lockedkeys) - return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); - if (!(tdb->lockedkeys = malloc(sizeof(u32) * (number+1)))) - return TDB_ERRCODE(TDB_ERR_OOM, -1); - /* First number in array is # keys */ - tdb->lockedkeys[0] = number; - - /* Insertion sort by bucket */ - for (i = 0; i < number; i++) { - hash = tdb_hash(&keys[i]); - for (j = 0; j < i && BUCKET(tdb->lockedkeys[j+1]) < BUCKET(hash); j++); - memmove(&tdb->lockedkeys[j+2], &tdb->lockedkeys[j+1], sizeof(u32) * (i-j)); - tdb->lockedkeys[j+1] = hash; - } - /* Finally, lock in order */ - for (i = 0; i < number; i++) - if (tdb_lock(tdb, i, F_WRLCK)) - break; - - /* If error, release locks we have... */ - if (i < number) { - for ( j = 0; j < i; j++) - tdb_unlock(tdb, j, F_WRLCK); - SAFE_FREE(tdb->lockedkeys); - return TDB_ERRCODE(TDB_ERR_NOLOCK, -1); - } - return 0; -} - -/* Unlock the keys previously locked by tdb_lockkeys() */ -void tdb_unlockkeys(TDB_CONTEXT *tdb) -{ - u32 i; - if (!tdb->lockedkeys) - return; - for (i = 0; i < tdb->lockedkeys[0]; i++) - tdb_unlock(tdb, tdb->lockedkeys[i+1], F_WRLCK); - SAFE_FREE(tdb->lockedkeys); -} - -/* lock/unlock one hash chain. This is meant to be used to reduce - contention - it cannot guarantee how many records will be locked */ -int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK); -} - -int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK); -} - -int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK); -} - -int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key) -{ - return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK); -} - - -/* register a loging function */ -void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , const char *, ...)) -{ - tdb->log_fn = fn; -} - - -/* reopen a tdb - this is used after a fork to ensure that we have an independent - seek pointer from our parent and to re-establish locks */ -int tdb_reopen(TDB_CONTEXT *tdb) -{ - struct stat st; - - if (tdb_munmap(tdb) != 0) { - TDB_LOG((tdb, 0, "tdb_reopen: munmap failed (%s)\n", strerror(errno))); - goto fail; - } - if (close(tdb->fd) != 0) - TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n")); - tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); - if (tdb->fd == -1) { - TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno))); - goto fail; - } - if (fstat(tdb->fd, &st) != 0) { - TDB_LOG((tdb, 0, "tdb_reopen: fstat failed (%s)\n", strerror(errno))); - goto fail; - } - if (st.st_ino != tdb->inode || st.st_dev != tdb->device) { - TDB_LOG((tdb, 0, "tdb_reopen: file dev/inode has changed!\n")); - goto fail; - } - tdb_mmap(tdb); - if (tdb_brlock(tdb, ACTIVE_LOCK, F_RDLCK, F_SETLKW, 0) == -1) { - TDB_LOG((tdb, 0, "tdb_reopen: failed to obtain active lock\n")); - goto fail; - } - - return 0; - -fail: - tdb_close(tdb); - return -1; -} - -/* reopen all tdb's */ -int tdb_reopen_all(void) -{ - TDB_CONTEXT *tdb; - - for (tdb=tdbs; tdb; tdb = tdb->next) { - if (tdb_reopen(tdb) != 0) return -1; - } - - return 0; -} diff --git a/tdb/tdb.h b/tdb/tdb.h deleted file mode 100644 index cac172adce..0000000000 --- a/tdb/tdb.h +++ /dev/null @@ -1,150 +0,0 @@ -#ifndef __TDB_H__ -#define __TDB_H__ - -/* - Unix SMB/CIFS implementation. - Samba database functions - Copyright (C) Andrew Tridgell 1999 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifdef __cplusplus -extern "C" { -#endif - -#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T -#include - -/* flags to tdb_store() */ -#define TDB_REPLACE 1 -#define TDB_INSERT 2 -#define TDB_MODIFY 3 - -/* flags for tdb_open() */ -#define TDB_DEFAULT 0 /* just a readability place holder */ -#define TDB_CLEAR_IF_FIRST 1 -#define TDB_INTERNAL 2 /* don't store on disk */ -#define TDB_NOLOCK 4 /* don't do any locking */ -#define TDB_NOMMAP 8 /* don't use mmap */ -#define TDB_CONVERT 16 /* convert endian (internal use) */ -#define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ - -#define TDB_ERRCODE(code, ret) ((tdb->ecode = (code)), ret) - -/* error codes */ -enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, - TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT }; - -#ifndef u32 -#define u32 unsigned -#endif - -typedef struct { - char *dptr; - size_t dsize; -} TDB_DATA; - -typedef u32 tdb_len; -typedef u32 tdb_off; - -/* this is stored at the front of every database */ -struct tdb_header { - char magic_food[32]; /* for /etc/magic */ - u32 version; /* version of the code */ - u32 hash_size; /* number of hash entries */ - tdb_off rwlocks; - tdb_off reserved[31]; -}; - -struct tdb_lock_type { - u32 count; - u32 ltype; -}; - -struct tdb_traverse_lock { - struct tdb_traverse_lock *next; - u32 off; - u32 hash; -}; - -/* this is the context structure that is returned from a db open */ -typedef struct tdb_context { - char *name; /* the name of the database */ - void *map_ptr; /* where it is currently mapped */ - int fd; /* open file descriptor for the database */ - tdb_len map_size; /* how much space has been mapped */ - int read_only; /* opened read-only */ - struct tdb_lock_type *locked; /* array of chain locks */ - enum TDB_ERROR ecode; /* error code for last tdb error */ - struct tdb_header header; /* a cached copy of the header */ - u32 flags; /* the flags passed to tdb_open */ - u32 *lockedkeys; /* array of locked keys: first is #keys */ - struct tdb_traverse_lock travlocks; /* current traversal locks */ - struct tdb_context *next; /* all tdbs to avoid multiple opens */ - dev_t device; /* uniquely identifies this tdb */ - ino_t inode; /* uniquely identifies this tdb */ - void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...); /* logging function */ - int open_flags; /* flags used in the open - needed by reopen */ -} TDB_CONTEXT; - -typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); -typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...); - -TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode); -TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn); - -int tdb_reopen(TDB_CONTEXT *tdb); -int tdb_reopen_all(void); -void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func); -enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); -const char *tdb_errorstr(TDB_CONTEXT *tdb); -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); -int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf); -int tdb_close(TDB_CONTEXT *tdb); -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state); -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]); -void tdb_unlockkeys(TDB_CONTEXT *tdb); -int tdb_lockall(TDB_CONTEXT *tdb); -void tdb_unlockall(TDB_CONTEXT *tdb); - -/* Low level locking functions: use with care */ -void tdb_set_lock_alarm(sig_atomic_t *palarm); -int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); - -/* Debug functions. Not used in production. */ -void tdb_dump_all(TDB_CONTEXT *tdb); -int tdb_printfreelist(TDB_CONTEXT *tdb); - -/* used only in tdbutil.c */ -int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key); - -extern TDB_DATA tdb_null; - -#ifdef __cplusplus -} -#endif - -#endif /* tdb.h */ diff --git a/tdb/tdb.magic b/tdb/tdb.magic deleted file mode 100644 index f5619e7327..0000000000 --- a/tdb/tdb.magic +++ /dev/null @@ -1,10 +0,0 @@ -# Magic file(1) information about tdb files. -# -# Install this into /etc/magic or the corresponding location for your -# system, or pass as a -m argument to file(1). - -# You may use and redistribute this file without restriction. - -0 string TDB\ file TDB database ->32 lelong =0x2601196D version 6, little-endian ->>36 lelong x hash size %d bytes diff --git a/tdb/tdbback.c b/tdb/tdbback.c deleted file mode 100644 index 744cface55..0000000000 --- a/tdb/tdbback.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" - -static int failed; - -char *add_suffix(const char *name, const char *suffix) -{ - char *ret; - int len = strlen(name) + strlen(suffix) + 1; - ret = malloc(len); - if (!ret) { - fprintf(stderr,"Out of memory!\n"); - exit(1); - } - strncpy(ret, name, len); - strncat(ret, suffix, len); - return ret; -} - -static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; - - if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { - fprintf(stderr,"Failed to insert into %s\n", tdb_new->name); - failed = 1; - return 1; - } - return 0; -} - - -static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - return 0; -} - -/* - carefully backup a tdb, validating the contents and - only doing the backup if its OK - this function is also used for restore -*/ -int backup_tdb(const char *old_name, const char *new_name) -{ - TDB_CONTEXT *tdb; - TDB_CONTEXT *tdb_new; - char *tmp_name; - struct stat st; - int count1, count2; - - tmp_name = add_suffix(new_name, ".tmp"); - - /* stat the old tdb to find its permissions */ - if (stat(old_name, &st) != 0) { - perror(old_name); - return 1; - } - - /* open the old tdb */ - tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); - if (!tdb) { - printf("Failed to open %s\n", old_name); - return 1; - } - - /* create the new tdb */ - unlink(tmp_name); - tdb_new = tdb_open(tmp_name, tdb->header.hash_size, - TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, - st.st_mode & 0777); - if (!tdb_new) { - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* lock the old tdb */ - if (tdb_lockall(tdb) != 0) { - fprintf(stderr,"Failed to lock %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - failed = 0; - - /* traverse and copy */ - count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); - if (count1 < 0 || failed) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* close the old tdb */ - tdb_close(tdb); - - /* close the new tdb and re-open read-only */ - tdb_close(tdb_new); - tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); - if (!tdb_new) { - fprintf(stderr,"failed to reopen %s\n", tmp_name); - unlink(tmp_name); - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* traverse the new tdb to confirm */ - count2 = tdb_traverse(tdb_new, test_fn, 0); - if (count2 != count1) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* make sure the new tdb has reached stable storage */ - fsync(tdb_new->fd); - - /* close the new tdb and rename it to .bak */ - tdb_close(tdb_new); - unlink(new_name); - if (rename(tmp_name, new_name) != 0) { - perror(new_name); - free(tmp_name); - return 1; - } - - free(tmp_name); - - return 0; -} - - - -/* - verify a tdb and if it is corrupt then restore from *.bak -*/ -int verify_tdb(const char *fname, const char *bak_name) -{ - TDB_CONTEXT *tdb; - int count = -1; - - /* open the tdb */ - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - - /* traverse the tdb, then close it */ - if (tdb) { - count = tdb_traverse(tdb, test_fn, NULL); - tdb_close(tdb); - } - - /* count is < 0 means an error */ - if (count < 0) { - printf("restoring %s\n", fname); - return backup_tdb(bak_name, fname); - } - - printf("%s : %d records\n", fname, count); - - return 0; -} diff --git a/tdb/tdbback.h b/tdb/tdbback.h deleted file mode 100644 index 7ebeaa494d..0000000000 --- a/tdb/tdbback.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -char *add_suffix(const char *name, const char *suffix); -int backup_tdb(const char *old_name, const char *new_name); -int verify_tdb(const char *fname, const char *bak_name); diff --git a/tdb/tdbbackup.c b/tdb/tdbbackup.c deleted file mode 100644 index 0eaf6b6c0b..0000000000 --- a/tdb/tdbbackup.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* - - This program is meant for backup/restore of tdb databases. Typical usage would be: - tdbbackup *.tdb - when Samba shuts down cleanly, which will make a backup of all the local databases - to *.bak files. Then on Samba startup you would use: - tdbbackup -v *.tdb - and this will check the databases for corruption and if corruption is detected then - the backup will be restored. - - You may also like to do a backup on a regular basis while Samba is - running, perhaps using cron. - - The reason this program is needed is to cope with power failures - while Samba is running. A power failure could lead to database - corruption and Samba will then not start correctly. - - Note that many of the databases in Samba are transient and thus - don't need to be backed up, so you can optimise the above a little - by only running the backup on the critical databases. - - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" -#include "tdbback.h" - -/* - see if one file is newer than another -*/ -static int file_newer(const char *fname1, const char *fname2) -{ - struct stat st1, st2; - if (stat(fname1, &st1) != 0) { - return 0; - } - if (stat(fname2, &st2) != 0) { - return 1; - } - return (st1.st_mtime > st2.st_mtime); -} - -static void usage(void) -{ - printf("Usage: tdbbackup [options] \n\n"); - printf(" -h this help message\n"); - printf(" -s suffix set the backup suffix\n"); - printf(" -v verify mode (restore if corrupt)\n"); -} - - - int main(int argc, char *argv[]) -{ - int i; - int ret = 0; - int c; - int verify = 0; - const char *suffix = ".bak"; - extern int optind; - extern char *optarg; - - while ((c = getopt(argc, argv, "vhs:")) != -1) { - switch (c) { - case 'h': - usage(); - exit(0); - case 'v': - verify = 1; - break; - case 's': - suffix = optarg; - break; - } - } - - argc -= optind; - argv += optind; - - if (argc < 1) { - usage(); - exit(1); - } - - for (i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "tdb.h" - -static void print_data(TDB_DATA d) -{ - unsigned char *p = d.dptr; - int len = d.dsize; - while (len--) { - if (isprint(*p) && !strchr("\"\\", *p)) { - fputc(*p, stdout); - } else { - printf("\\%02X", *p); - } - p++; - } -} - -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("{\n"); - printf("key = \""); - print_data(key); - printf("\"\n"); - printf("data = \""); - print_data(dbuf); - printf("\"\n"); - printf("}\n"); - return 0; -} - -static int dump_tdb(const char *fname) -{ - TDB_CONTEXT *tdb; - - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - if (!tdb) { - printf("Failed to open %s\n", fname); - return 1; - } - - tdb_traverse(tdb, traverse_fn, NULL); - return 0; -} - - int main(int argc, char *argv[]) -{ - char *fname; - - if (argc < 2) { - printf("Usage: tdbdump \n"); - exit(1); - } - - fname = argv[1]; - - return dump_tdb(fname); -} diff --git a/tdb/tdbutil.c b/tdb/tdbutil.c deleted file mode 100644 index b01dacd0f5..0000000000 --- a/tdb/tdbutil.c +++ /dev/null @@ -1,830 +0,0 @@ -/* - Unix SMB/CIFS implementation. - tdb utility functions - Copyright (C) Andrew Tridgell 1992-1998 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" -#include - -/* these are little tdb utility functions that are meant to make - dealing with a tdb database a little less cumbersome in Samba */ - -static SIG_ATOMIC_T gotalarm; - -/*************************************************************** - Signal function to tell us we timed out. -****************************************************************/ - -static void gotalarm_sig(void) -{ - gotalarm = 1; -} - -/*************************************************************** - Make a TDB_DATA and keep the const warning in one place -****************************************************************/ - -static TDB_DATA make_tdb_data(const char *dptr, size_t dsize) -{ - TDB_DATA ret; - ret.dptr = dptr; - ret.dsize = dsize; - return ret; -} - -/**************************************************************************** - Lock a chain with timeout (in seconds). -****************************************************************************/ - -static int tdb_chainlock_with_timeout_internal( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout, int rw_type) -{ - /* Allow tdb_chainlock to be interrupted by an alarm. */ - int ret; - gotalarm = 0; - tdb_set_lock_alarm(&gotalarm); - - if (timeout) { - CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); - alarm(timeout); - } - - if (rw_type == F_RDLCK) - ret = tdb_chainlock_read(tdb, key); - else - ret = tdb_chainlock(tdb, key); - - if (timeout) { - alarm(0); - CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); - if (gotalarm) { - DEBUG(0,("tdb_chainlock_with_timeout_internal: alarm (%u) timed out for key %s in tdb %s\n", - timeout, key.dptr, tdb->name )); - /* TODO: If we time out waiting for a lock, it might - * be nice to use F_GETLK to get the pid of the - * process currently holding the lock and print that - * as part of the debugging message. -- mbp */ - return -1; - } - } - - return ret; -} - -/**************************************************************************** - Write lock a chain. Return -1 if timeout or lock failed. -****************************************************************************/ - -int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout) -{ - return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK); -} - -/**************************************************************************** - Lock a chain by string. Return -1 if timeout or lock failed. -****************************************************************************/ - -int tdb_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_WRLCK); -} - -/**************************************************************************** - Unlock a chain by string. -****************************************************************************/ - -void tdb_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - tdb_chainunlock(tdb, key); -} - -/**************************************************************************** - Read lock a chain by string. Return -1 if timeout or lock failed. -****************************************************************************/ - -int tdb_read_lock_bystring(TDB_CONTEXT *tdb, const char *keyval, unsigned int timeout) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - return tdb_chainlock_with_timeout_internal(tdb, key, timeout, F_RDLCK); -} - -/**************************************************************************** - Read unlock a chain by string. -****************************************************************************/ - -void tdb_read_unlock_bystring(TDB_CONTEXT *tdb, const char *keyval) -{ - TDB_DATA key = make_tdb_data(keyval, strlen(keyval)+1); - - tdb_chainunlock_read(tdb, key); -} - - -/**************************************************************************** - Fetch a int32 value by a arbitrary blob key, return -1 if not found. - Output is int32 in native byte order. -****************************************************************************/ - -int32 tdb_fetch_int32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len) -{ - TDB_DATA key = make_tdb_data(keyval, len); - TDB_DATA data; - int32 ret; - - data = tdb_fetch(tdb, key); - if (!data.dptr || data.dsize != sizeof(int32)) { - SAFE_FREE(data.dptr); - return -1; - } - - ret = IVAL(data.dptr,0); - SAFE_FREE(data.dptr); - return ret; -} - -/**************************************************************************** - Fetch a int32 value by string key, return -1 if not found. - Output is int32 in native byte order. -****************************************************************************/ - -int32 tdb_fetch_int32(TDB_CONTEXT *tdb, const char *keystr) -{ - return tdb_fetch_int32_byblob(tdb, keystr, strlen(keystr) + 1); -} - -/**************************************************************************** - Store a int32 value by an arbitary blob key, return 0 on success, -1 on failure. - Input is int32 in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -int tdb_store_int32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, int32 v) -{ - TDB_DATA key = make_tdb_data(keystr, len); - TDB_DATA data; - int32 v_store; - - SIVAL(&v_store,0,v); - data.dptr = (void *)&v_store; - data.dsize = sizeof(int32); - - return tdb_store(tdb, key, data, TDB_REPLACE); -} - -/**************************************************************************** - Store a int32 value by string key, return 0 on success, -1 on failure. - Input is int32 in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -int tdb_store_int32(TDB_CONTEXT *tdb, const char *keystr, int32 v) -{ - return tdb_store_int32_byblob(tdb, keystr, strlen(keystr) + 1, v); -} - -/**************************************************************************** - Fetch a uint32 value by a arbitrary blob key, return -1 if not found. - Output is uint32 in native byte order. -****************************************************************************/ - -BOOL tdb_fetch_uint32_byblob(TDB_CONTEXT *tdb, const char *keyval, size_t len, uint32 *value) -{ - TDB_DATA key = make_tdb_data(keyval, len); - TDB_DATA data; - - data = tdb_fetch(tdb, key); - if (!data.dptr || data.dsize != sizeof(uint32)) { - SAFE_FREE(data.dptr); - return False; - } - - *value = IVAL(data.dptr,0); - SAFE_FREE(data.dptr); - return True; -} - -/**************************************************************************** - Fetch a uint32 value by string key, return -1 if not found. - Output is uint32 in native byte order. -****************************************************************************/ - -BOOL tdb_fetch_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 *value) -{ - return tdb_fetch_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); -} - -/**************************************************************************** - Store a uint32 value by an arbitary blob key, return 0 on success, -1 on failure. - Input is uint32 in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -BOOL tdb_store_uint32_byblob(TDB_CONTEXT *tdb, const char *keystr, size_t len, uint32 value) -{ - TDB_DATA key = make_tdb_data(keystr, len); - TDB_DATA data; - uint32 v_store; - BOOL ret = True; - - SIVAL(&v_store, 0, value); - data.dptr = (void *)&v_store; - data.dsize = sizeof(uint32); - - if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) - ret = False; - - return ret; -} - -/**************************************************************************** - Store a uint32 value by string key, return 0 on success, -1 on failure. - Input is uint32 in native byte order. Output in tdb is in little-endian. -****************************************************************************/ - -BOOL tdb_store_uint32(TDB_CONTEXT *tdb, const char *keystr, uint32 value) -{ - return tdb_store_uint32_byblob(tdb, keystr, strlen(keystr) + 1, value); -} -/**************************************************************************** - Store a buffer by a null terminated string key. Return 0 on success, -1 - on failure. -****************************************************************************/ - -int tdb_store_bystring(TDB_CONTEXT *tdb, const char *keystr, TDB_DATA data, int flags) -{ - TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); - - return tdb_store(tdb, key, data, flags); -} - -/**************************************************************************** - Fetch a buffer using a null terminated string key. Don't forget to call - free() on the result dptr. -****************************************************************************/ - -TDB_DATA tdb_fetch_bystring(TDB_CONTEXT *tdb, const char *keystr) -{ - TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); - - return tdb_fetch(tdb, key); -} - -/**************************************************************************** - Delete an entry using a null terminated string key. -****************************************************************************/ - -int tdb_delete_bystring(TDB_CONTEXT *tdb, const char *keystr) -{ - TDB_DATA key = make_tdb_data(keystr, strlen(keystr)+1); - - return tdb_delete(tdb, key); -} - -/**************************************************************************** - Atomic integer change. Returns old value. To create, set initial value in *oldval. -****************************************************************************/ - -int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, const char *keystr, int32 *oldval, int32 change_val) -{ - int32 val; - int32 ret = -1; - - if (tdb_lock_bystring(tdb, keystr,0) == -1) - return -1; - - if ((val = tdb_fetch_int32(tdb, keystr)) == -1) { - /* The lookup failed */ - if (tdb_error(tdb) != TDB_ERR_NOEXIST) { - /* but not because it didn't exist */ - goto err_out; - } - - /* Start with 'old' value */ - val = *oldval; - - } else { - /* It worked, set return value (oldval) to tdb data */ - *oldval = val; - } - - /* Increment value for storage and return next time */ - val += change_val; - - if (tdb_store_int32(tdb, keystr, val) == -1) - goto err_out; - - ret = 0; - - err_out: - - tdb_unlock_bystring(tdb, keystr); - return ret; -} - -/**************************************************************************** - Atomic unsigned integer change. Returns old value. To create, set initial value in *oldval. -****************************************************************************/ - -BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, const char *keystr, uint32 *oldval, uint32 change_val) -{ - uint32 val; - BOOL ret = False; - - if (tdb_lock_bystring(tdb, keystr,0) == -1) - return False; - - if (!tdb_fetch_uint32(tdb, keystr, &val)) { - /* It failed */ - if (tdb_error(tdb) != TDB_ERR_NOEXIST) { - /* and not because it didn't exist */ - goto err_out; - } - - /* Start with 'old' value */ - val = *oldval; - - } else { - /* it worked, set return value (oldval) to tdb data */ - *oldval = val; - - } - - /* get a new value to store */ - val += change_val; - - if (!tdb_store_uint32(tdb, keystr, val)) - goto err_out; - - ret = True; - - err_out: - - tdb_unlock_bystring(tdb, keystr); - return ret; -} - -/**************************************************************************** - Useful pair of routines for packing/unpacking data consisting of - integers and strings. -****************************************************************************/ - -size_t tdb_pack(char *buf, int bufsize, const char *fmt, ...) -{ - va_list ap; - uint8 bt; - uint16 w; - uint32 d; - int i; - void *p; - int len; - char *s; - char c; - char *buf0 = buf; - const char *fmt0 = fmt; - int bufsize0 = bufsize; - - va_start(ap, fmt); - - while (*fmt) { - switch ((c = *fmt++)) { - case 'b': /* unsigned 8-bit integer */ - len = 1; - bt = (uint8)va_arg(ap, int); - if (bufsize && bufsize >= len) - SSVAL(buf, 0, bt); - break; - case 'w': /* unsigned 16-bit integer */ - len = 2; - w = (uint16)va_arg(ap, int); - if (bufsize && bufsize >= len) - SSVAL(buf, 0, w); - break; - case 'd': /* signed 32-bit integer (standard int in most systems) */ - len = 4; - d = va_arg(ap, uint32); - if (bufsize && bufsize >= len) - SIVAL(buf, 0, d); - break; - case 'p': /* pointer */ - len = 4; - p = va_arg(ap, void *); - d = p?1:0; - if (bufsize && bufsize >= len) - SIVAL(buf, 0, d); - break; - case 'P': /* null-terminated string */ - s = va_arg(ap,char *); - w = strlen(s); - len = w + 1; - if (bufsize && bufsize >= len) - memcpy(buf, s, len); - break; - case 'f': /* null-terminated string */ - s = va_arg(ap,char *); - w = strlen(s); - len = w + 1; - if (bufsize && bufsize >= len) - memcpy(buf, s, len); - break; - case 'B': /* fixed-length string */ - i = va_arg(ap, int); - s = va_arg(ap, char *); - len = 4+i; - if (bufsize && bufsize >= len) { - SIVAL(buf, 0, i); - memcpy(buf+4, s, i); - } - break; - default: - DEBUG(0,("Unknown tdb_pack format %c in %s\n", - c, fmt)); - len = 0; - break; - } - - buf += len; - if (bufsize) - bufsize -= len; - if (bufsize < 0) - bufsize = 0; - } - - va_end(ap); - - DEBUG(18,("tdb_pack(%s, %d) -> %d\n", - fmt0, bufsize0, (int)PTR_DIFF(buf, buf0))); - - return PTR_DIFF(buf, buf0); -} - -/**************************************************************************** - Useful pair of routines for packing/unpacking data consisting of - integers and strings. -****************************************************************************/ - -int tdb_unpack(char *buf, int bufsize, const char *fmt, ...) -{ - va_list ap; - uint8 *bt; - uint16 *w; - uint32 *d; - int len; - int *i; - void **p; - char *s, **b; - char c; - char *buf0 = buf; - const char *fmt0 = fmt; - int bufsize0 = bufsize; - - va_start(ap, fmt); - - while (*fmt) { - switch ((c=*fmt++)) { - case 'b': - len = 1; - bt = va_arg(ap, uint8 *); - if (bufsize < len) - goto no_space; - *bt = SVAL(buf, 0); - break; - case 'w': - len = 2; - w = va_arg(ap, uint16 *); - if (bufsize < len) - goto no_space; - *w = SVAL(buf, 0); - break; - case 'd': - len = 4; - d = va_arg(ap, uint32 *); - if (bufsize < len) - goto no_space; - *d = IVAL(buf, 0); - break; - case 'p': - len = 4; - p = va_arg(ap, void **); - if (bufsize < len) - goto no_space; - *p = (void *)IVAL(buf, 0); - break; - case 'P': - s = va_arg(ap,char *); - len = strlen(buf) + 1; - if (bufsize < len || len > sizeof(pstring)) - goto no_space; - memcpy(s, buf, len); - break; - case 'f': - s = va_arg(ap,char *); - len = strlen(buf) + 1; - if (bufsize < len || len > sizeof(fstring)) - goto no_space; - memcpy(s, buf, len); - break; - case 'B': - i = va_arg(ap, int *); - b = va_arg(ap, char **); - len = 4; - if (bufsize < len) - goto no_space; - *i = IVAL(buf, 0); - if (! *i) { - *b = NULL; - break; - } - len += *i; - if (bufsize < len) - goto no_space; - *b = (char *)malloc(*i); - if (! *b) - goto no_space; - memcpy(*b, buf+4, *i); - break; - default: - DEBUG(0,("Unknown tdb_unpack format %c in %s\n", - c, fmt)); - - len = 0; - break; - } - - buf += len; - bufsize -= len; - } - - va_end(ap); - - DEBUG(18,("tdb_unpack(%s, %d) -> %d\n", - fmt0, bufsize0, (int)PTR_DIFF(buf, buf0))); - - return PTR_DIFF(buf, buf0); - - no_space: - return -1; -} - - -/** - * Pack SID passed by pointer - * - * @param pack_buf pointer to buffer which is to be filled with packed data - * @param bufsize size of packing buffer - * @param sid pointer to sid to be packed - * - * @return length of the packed representation of the whole structure - **/ -size_t tdb_sid_pack(char* pack_buf, int bufsize, DOM_SID* sid) -{ - int idx; - size_t len = 0; - - if (!sid || !pack_buf) return -1; - - len += tdb_pack(pack_buf + len, bufsize - len, "bb", sid->sid_rev_num, - sid->num_auths); - - for (idx = 0; idx < 6; idx++) { - len += tdb_pack(pack_buf + len, bufsize - len, "b", sid->id_auth[idx]); - } - - for (idx = 0; idx < MAXSUBAUTHS; idx++) { - len += tdb_pack(pack_buf + len, bufsize - len, "d", sid->sub_auths[idx]); - } - - return len; -} - - -/** - * Unpack SID into a pointer - * - * @param pack_buf pointer to buffer with packed representation - * @param bufsize size of the buffer - * @param sid pointer to sid structure to be filled with unpacked data - * - * @return size of structure unpacked from buffer - **/ -size_t tdb_sid_unpack(char* pack_buf, int bufsize, DOM_SID* sid) -{ - int idx, len = 0; - - if (!sid || !pack_buf) return -1; - - len += tdb_unpack(pack_buf + len, bufsize - len, "bb", - &sid->sid_rev_num, &sid->num_auths); - - for (idx = 0; idx < 6; idx++) { - len += tdb_unpack(pack_buf + len, bufsize - len, "b", &sid->id_auth[idx]); - } - - for (idx = 0; idx < MAXSUBAUTHS; idx++) { - len += tdb_unpack(pack_buf + len, bufsize - len, "d", &sid->sub_auths[idx]); - } - - return len; -} - - -/** - * Pack TRUSTED_DOM_PASS passed by pointer - * - * @param pack_buf pointer to buffer which is to be filled with packed data - * @param bufsize size of the buffer - * @param pass pointer to trusted domain password to be packed - * - * @return length of the packed representation of the whole structure - **/ -size_t tdb_trusted_dom_pass_pack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass) -{ - int idx, len = 0; - - if (!pack_buf || !pass) return -1; - - /* packing unicode domain name and password */ - len += tdb_pack(pack_buf + len, bufsize - len, "d", pass->uni_name_len); - - for (idx = 0; idx < 32; idx++) - len += tdb_pack(pack_buf + len, bufsize - len, "w", pass->uni_name[idx]); - - len += tdb_pack(pack_buf + len, bufsize - len, "dPd", pass->pass_len, - pass->pass, pass->mod_time); - - /* packing SID structure */ - len += tdb_sid_pack(pack_buf + len, bufsize - len, &pass->domain_sid); - - return len; -} - - -/** - * Unpack TRUSTED_DOM_PASS passed by pointer - * - * @param pack_buf pointer to buffer with packed representation - * @param bufsize size of the buffer - * @param pass pointer to trusted domain password to be filled with unpacked data - * - * @return size of structure unpacked from buffer - **/ -size_t tdb_trusted_dom_pass_unpack(char* pack_buf, int bufsize, TRUSTED_DOM_PASS* pass) -{ - int idx, len = 0; - - if (!pack_buf || !pass) return -1; - - /* unpack unicode domain name and plaintext password */ - len += tdb_unpack(pack_buf, bufsize - len, "d", &pass->uni_name_len); - - for (idx = 0; idx < 32; idx++) - len += tdb_unpack(pack_buf + len, bufsize - len, "w", &pass->uni_name[idx]); - - len += tdb_unpack(pack_buf + len, bufsize - len, "dPd", &pass->pass_len, &pass->pass, - &pass->mod_time); - - /* unpack domain sid */ - len += tdb_sid_unpack(pack_buf + len, bufsize - len, &pass->domain_sid); - - return len; -} - - -/**************************************************************************** - Log tdb messages via DEBUG(). -****************************************************************************/ - -static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) -{ - va_list ap; - char *ptr = NULL; - - va_start(ap, format); - vasprintf(&ptr, format, ap); - va_end(ap); - - if (!ptr || !*ptr) - return; - - DEBUG(level, ("tdb(%s): %s", tdb->name ? tdb->name : "unnamed", ptr)); - SAFE_FREE(ptr); -} - -/**************************************************************************** - Like tdb_open() but also setup a logging function that redirects to - the samba DEBUG() system. -****************************************************************************/ - -TDB_CONTEXT *tdb_open_log(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) -{ - TDB_CONTEXT *tdb; - - if (!lp_use_mmap()) - tdb_flags |= TDB_NOMMAP; - - tdb = tdb_open_ex(name, hash_size, tdb_flags, - open_flags, mode, tdb_log); - if (!tdb) - return NULL; - - return tdb; -} - - -/**************************************************************************** - Allow tdb_delete to be used as a tdb_traversal_fn. -****************************************************************************/ - -int tdb_traverse_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - return tdb_delete(the_tdb, key); -} - - - -/** - * Search across the whole tdb for keys that match the given pattern - * return the result as a list of keys - * - * @param tdb pointer to opened tdb file context - * @param pattern searching pattern used by fnmatch(3) functions - * - * @return list of keys found by looking up with given pattern - **/ -TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT *tdb, const char* pattern) -{ - TDB_DATA key, next; - TDB_LIST_NODE *list = NULL; - TDB_LIST_NODE *rec = NULL; - TDB_LIST_NODE *tmp = NULL; - - for (key = tdb_firstkey(tdb); key.dptr; key = next) { - /* duplicate key string to ensure null-termination */ - char *key_str = (char*) strndup(key.dptr, key.dsize); - if (!key_str) { - DEBUG(0, ("tdb_search_keys: strndup() failed!\n")); - smb_panic("strndup failed!\n"); - } - - DEBUG(18, ("checking %s for match to pattern %s\n", key_str, pattern)); - - next = tdb_nextkey(tdb, key); - - /* do the pattern checking */ - if (fnmatch(pattern, key_str, 0) == 0) { - rec = (TDB_LIST_NODE*) malloc(sizeof(*rec)); - ZERO_STRUCTP(rec); - - rec->node_key = key; - - DLIST_ADD_END(list, rec, tmp); - - DEBUG(18, ("checking %s matched pattern %s\n", key_str, pattern)); - } else { - free(key.dptr); - } - - /* free duplicated key string */ - free(key_str); - } - - return list; - -}; - - -/** - * Free the list returned by tdb_search_keys - * - * @param node list of results found by tdb_search_keys - **/ -void tdb_search_list_free(TDB_LIST_NODE* node) -{ - TDB_LIST_NODE *next_node; - - while (node) { - next_node = node->next; - SAFE_FREE(node->node_key.dptr); - SAFE_FREE(node); - node = next_node; - }; -}; - - diff --git a/tdb/tdbutil.h b/tdb/tdbutil.h deleted file mode 100644 index 01473446a1..0000000000 --- a/tdb/tdbutil.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - Unix SMB/CIFS implementation. - tdb utility functions - Copyright (C) Andrew Tridgell 1999 - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifndef __TDBUTIL_H__ -#define __TDBUTIL_H__ - - -/* single node of a list returned by tdb_search_keys */ -typedef struct keys_node -{ - struct keys_node *prev, *next; - TDB_DATA node_key; -} TDB_LIST_NODE; - - -TDB_LIST_NODE *tdb_search_keys(TDB_CONTEXT*, const char*); -void tdb_search_list_free(TDB_LIST_NODE*); - - -#endif /* __TDBUTIL_H__ */ diff --git a/test/devd_test b/test/devd_test index 007a0bec90..6e4c206352 100644 --- a/test/devd_test +++ b/test/devd_test @@ -14,7 +14,7 @@ EOF cat > $CONFIG << EOF udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udev.tdb" +udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF diff --git a/test/ignore_test b/test/ignore_test index ca51e9a1ab..d22a4d7b5f 100644 --- a/test/ignore_test +++ b/test/ignore_test @@ -13,7 +13,7 @@ EOF cat > $CONFIG << EOF udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udev.tdb" +udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" udev_log="true" diff --git a/test/label_test b/test/label_test index b99a4acd54..fbb7309045 100644 --- a/test/label_test +++ b/test/label_test @@ -14,7 +14,7 @@ EOF cat > $CONFIG << EOF udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udev.tdb" +udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF diff --git a/test/modifier_test b/test/modifier_test index 7ffc7b16a1..c2b5ec6830 100644 --- a/test/modifier_test +++ b/test/modifier_test @@ -13,7 +13,7 @@ EOF cat > $CONFIG << EOF udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udev.tdb" +udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF diff --git a/test/net_test b/test/net_test index 56a6847d19..ec0dea4642 100644 --- a/test/net_test +++ b/test/net_test @@ -13,7 +13,7 @@ EOF cat > $CONFIG << EOF udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udev.tdb" +udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF diff --git a/test/replace_test b/test/replace_test index 10215b0f24..9445b7262a 100644 --- a/test/replace_test +++ b/test/replace_test @@ -13,7 +13,7 @@ EOF cat > $CONFIG << EOF udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udev.tdb" +udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF diff --git a/test/topo_test b/test/topo_test index 18b2549b97..77333a978c 100644 --- a/test/topo_test +++ b/test/topo_test @@ -13,7 +13,7 @@ EOF cat > $CONFIG << EOF udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udev.tdb" +udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" udev_permissions="$PWD/udev.permissions" EOF diff --git a/test/udev-test.pl b/test/udev-test.pl index e8ce0b44dd..2ba63fe83f 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -30,7 +30,7 @@ my $PWD = $ENV{PWD}; my $sysfs = "sys/"; my $udev_bin = "../udev"; my $udev_root = "udev-root/"; # !!! directory will be removed !!! -my $udev_db = ".udev.tdb"; +my $udev_db = ".udevdb"; my $perm = "udev.permissions"; my $main_conf = "udev-test.conf"; my $conf_tmp = "udev-test.rules"; @@ -1268,7 +1268,7 @@ sub run_test { } if (defined($config->{option}) && $config->{option} eq "clear") { - unlink($udev_db); + system("rm -rf $udev_db"); system("rm -rf $udev_root"); mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; } @@ -1319,7 +1319,7 @@ if ($ARGV[0]) { print "$error errors occured\n\n"; # cleanup -unlink($udev_db); +system("rm -rf $udev_db"); system("rm -rf $udev_root"); unlink($conf_tmp); unlink($main_conf); diff --git a/udev.8.in b/udev.8.in index a7f0bf0392..168842d435 100644 --- a/udev.8.in +++ b/udev.8.in @@ -74,7 +74,7 @@ value is .TP .B udev_db The name and location of the udev database. The default value is -.IR @udevdir@/.udev.tdb . +.IR @udevdir@/.udevdb . .TP .B udev_rules The name of the udev rules file or directory to look for files with the suffix @@ -117,7 +117,7 @@ file. The default value is udev_root="/udev" # udev_db - The name and location of the udev database -udev_db="/udev/.udev.tdb" +udev_db="/udev/.udevdb" # udev_rules - The name of the udev rules file or directory to look for files with the suffix .rules diff --git a/udev.c b/udev.c index 7809060520..d8cb4365fd 100644 --- a/udev.c +++ b/udev.c @@ -38,8 +38,6 @@ #include "namedev.h" #include "udevdb.h" -/* timeout flag for udevdb */ -extern sig_atomic_t gotalarm; /* global variables */ char **main_argv; @@ -64,8 +62,7 @@ static void asmlinkage sig_handler(int signum) { switch (signum) { case SIGALRM: - gotalarm = 1; - break; + exit(1); case SIGINT: case SIGTERM: exit(20 + signum); @@ -153,10 +150,6 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timout to interrupt blocking syscalls */ alarm(ALARM_TIMEOUT); - /* initialize udev database */ - if (udevdb_init(UDEVDB_DEFAULT) != 0) - info("error: unable to initialize database, continuing without database"); - switch(act_type) { case UDEVSTART: dbg("udevstart"); @@ -196,8 +189,6 @@ int main(int argc, char *argv[], char *envp[]) dev_d_execute(&udev); } - udevdb_exit(); - exit: logging_close(); return retval; diff --git a/udev.h b/udev.h index e8954338d9..1cf4ad7eae 100644 --- a/udev.h +++ b/udev.h @@ -41,26 +41,21 @@ #define LINE_SIZE 256 -/* length of public data to store in udevdb */ -#define UDEVICE_DB_LEN (offsetof(struct udevice, devpath)) - struct udevice { + char devpath[DEVPATH_SIZE]; + char subsystem[SUBSYSTEM_SIZE]; char name[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; char type; int major; int minor; - unsigned int mode; /* not mode_t due to conflicting definitions in different libcs */ + mode_t mode; char symlink[NAME_SIZE]; int partitions; int config_line; char config_file[NAME_SIZE]; long config_uptime; - - /* private data, not stored in udevdb */ - char devpath[DEVPATH_SIZE]; - char subsystem[SUBSYSTEM_SIZE]; char bus_id[SYSFS_NAME_LEN]; char bus[SYSFS_NAME_LEN]; char program_result[NAME_SIZE]; @@ -81,7 +76,7 @@ extern char **main_argv; extern char **main_envp; extern char sysfs_path[SYSFS_PATH_MAX]; extern char udev_root[PATH_MAX]; -extern char udev_db_filename[PATH_MAX+NAME_MAX]; +extern char udev_db_path[PATH_MAX+NAME_MAX]; extern char udev_permissions_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; diff --git a/udev_add.c b/udev_add.c index 689c2dceec..60506b4243 100644 --- a/udev_add.c +++ b/udev_add.c @@ -68,37 +68,6 @@ error: return -1; } -static int create_path(char *file) -{ - char p[NAME_SIZE]; - char *pos; - int retval; - struct stat stats; - - strfieldcpy(p, file); - pos = strchr(p+1, '/'); - while (1) { - pos = strchr(pos+1, '/'); - if (pos == NULL) - break; - *pos = 0x00; - if (stat(p, &stats)) { - selinux_setfscreatecon(p, S_IFDIR); - retval = mkdir(p, 0755); - if (retval != 0) { - dbg("mkdir(%s) failed with error '%s'", - p, strerror(errno)); - return retval; - } - dbg("created '%s'", p); - } else { - selinux_setfilecon(p, S_IFDIR); - } - *pos = '/'; - } - return 0; -} - static int make_node(char *file, int major, int minor, unsigned int mode, uid_t uid, gid_t gid) { struct stat stats; @@ -152,8 +121,6 @@ exit: static int create_node(struct udevice *udev) { char filename[NAME_SIZE]; - char linkname[NAME_SIZE]; - char linktarget[NAME_SIZE]; char partitionname[NAME_SIZE]; uid_t uid = 0; gid_t gid = 0; @@ -162,8 +129,8 @@ static int create_node(struct udevice *udev) char *pos; int len; - strfieldcpy(filename, udev_root); - strfieldcat(filename, udev->name); + snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, udev->name); + filename[NAME_SIZE-1] = '\0'; switch (udev->type) { case 'b': @@ -239,9 +206,13 @@ static int create_node(struct udevice *udev) /* create symlink(s) if requested */ foreach_strpart(udev->symlink, " ", pos, len) { + char linkname[NAME_SIZE]; + char linktarget[NAME_SIZE]; + strfieldcpymax(linkname, pos, len+1); - strfieldcpy(filename, udev_root); - strfieldcat(filename, linkname); + snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, linkname); + filename[NAME_SIZE-1] = '\0'; + dbg("symlink '%s' to node '%s' requested", filename, udev->name); if (!udev->test_run) if (strrchr(linkname, '/')) @@ -337,7 +308,8 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) "remove might not work for custom names"); /* use full path to the environment */ - snprintf(udev->devname, NAME_SIZE-1, "%s%s", udev_root, udev->name); + snprintf(udev->devname, NAME_SIZE-1, "%s/%s", udev_root, udev->name); + udev->devname[NAME_SIZE-1] = '\0'; } else if (udev->type == 'n') { /* look if we want to change the name of the netif */ diff --git a/udev_config.c b/udev_config.c index ae755f39fd..198473936f 100644 --- a/udev_config.c +++ b/udev_config.c @@ -42,7 +42,7 @@ /* global variables */ char sysfs_path[SYSFS_PATH_MAX]; char udev_root[PATH_MAX]; -char udev_db_filename[PATH_MAX+NAME_MAX]; +char udev_db_path[PATH_MAX+NAME_MAX]; char udev_permissions_filename[PATH_MAX+NAME_MAX]; char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; @@ -72,7 +72,7 @@ static void init_variables(void) * If any config values are specified, they will * override these values. */ strfieldcpy(udev_root, UDEV_ROOT); - strfieldcpy(udev_db_filename, UDEV_DB); + strfieldcpy(udev_db_path, UDEV_DB); strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE); strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); @@ -181,24 +181,25 @@ static int parse_config_file(void) if (strcasecmp(variable, "udev_root") == 0) { strfieldcpy(udev_root, value); - leading_slash(udev_root); + no_trailing_slash(udev_root); continue; } if (strcasecmp(variable, "udev_db") == 0) { - strfieldcpy(udev_db_filename, value); + strfieldcpy(udev_db_path, value); + no_trailing_slash(udev_db_path); continue; } if (strcasecmp(variable, "udev_rules") == 0) { strfieldcpy(udev_rules_filename, value); - no_leading_slash(udev_rules_filename); + no_trailing_slash(udev_rules_filename); continue; } if (strcasecmp(variable, "udev_permissions") == 0) { strfieldcpy(udev_permissions_filename, value); - no_leading_slash(udev_permissions_filename); + no_trailing_slash(udev_permissions_filename); continue; } @@ -244,7 +245,7 @@ static void get_dirs(void) temp = getenv("SYSFS_PATH"); if (temp != NULL) { strfieldcpy(sysfs_path, temp); - no_leading_slash(sysfs_path); + no_trailing_slash(sysfs_path); } temp = getenv("UDEV_CONFIG_FILE"); @@ -255,7 +256,7 @@ static void get_dirs(void) dbg("sysfs_path='%s'", sysfs_path); dbg_parse("udev_root = %s", udev_root); dbg_parse("udev_config_filename = %s", udev_config_filename); - dbg_parse("udev_db_filename = %s", udev_db_filename); + dbg_parse("udev_db_path = %s", udev_db_path); dbg_parse("udev_rules_filename = %s", udev_rules_filename); dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); dbg_parse("udev_log = %d", udev_log); @@ -264,7 +265,7 @@ static void get_dirs(void) dbg("udev_root = %s", udev_root); dbg("udev_config_filename = %s", udev_config_filename); - dbg("udev_db_filename = %s", udev_db_filename); + dbg("udev_db_path = %s", udev_db_path); dbg("udev_rules_filename = %s", udev_rules_filename); dbg("udev_permissions_filename = %s", udev_permissions_filename); dbg("udev_log_str = %d", udev_log); diff --git a/udev_lib.c b/udev_lib.c index bd3eeba661..7fb45f0b5f 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -120,6 +120,33 @@ void udev_set_values(struct udevice *udev, const char* devpath, const char *subs udev->type = get_device_type(devpath, subsystem); } +int create_path(const char *path) +{ + char p[NAME_SIZE]; + char *pos; + struct stat stats; + + strcpy (p, path); + pos = strrchr(p, '/'); + if (pos == p || pos == NULL) + return 0; + + while (pos[-1] == '/') + pos--; + + pos[0] = '\0'; + + dbg("stat '%s'\n", 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'\n", p); + return mkdir(p, 0755); +} + int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; @@ -161,18 +188,7 @@ size_t buf_get_line(char *buf, size_t buflen, size_t cur) return count - cur; } -void leading_slash(char *path) -{ - int len; - - len = strlen(path); - if (len > 0 && path[len-1] != '/') { - path[len] = '/'; - path[len+1] = '\0'; - } -} - -void no_leading_slash(char *path) +void no_trailing_slash(char *path) { int len; @@ -249,9 +265,8 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) /* call function for every file in the list */ list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { - strfieldcpy(file, dirname); - strfieldcat(file, "/"); - strfieldcat(file, loop_file->name); + snprintf(file, NAME_SIZE-1, "%s/%s", dirname, loop_file->name); + file[NAME_SIZE-1] = '\0'; fnct(file); diff --git a/udev_lib.h b/udev_lib.h index 8a14ef00b6..94649b645f 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -83,11 +83,11 @@ extern char *get_seqnum(void); extern char *get_subsystem(char *subsystem); extern char get_device_type(const char *path, const char *subsystem); extern void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem); +extern int create_path(const char *path); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); -extern void leading_slash(char *path); -extern void no_leading_slash(char *path); +extern void no_trailing_slash(char *path); extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension); extern int set_cloexec_flag (int desc, int value); diff --git a/udev_remove.c b/udev_remove.c index cd9d27f8dc..d855fce52c 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -102,10 +102,9 @@ static int secure_unlink(const char *filename) return retval; } -static int delete_node(struct udevice *dev) +static int delete_node(struct udevice *udev) { char filename[NAME_SIZE]; - char linkname[NAME_SIZE]; char partitionname[NAME_SIZE]; int retval; int i; @@ -113,8 +112,8 @@ static int delete_node(struct udevice *dev) int len; int num; - strfieldcpy(filename, udev_root); - strfieldcat(filename, dev->name); + snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, udev->name); + filename[NAME_SIZE-1] = '\0'; info("removing device node '%s'", filename); retval = secure_unlink(filename); @@ -122,7 +121,7 @@ static int delete_node(struct udevice *dev) return retval; /* remove all_partitions nodes */ - num = dev->partitions; + num = udev->partitions; if (num > 0) { info("removing all_partitions '%s[1-%i]'", filename, num); if (num > PARTITIONS_COUNT) { @@ -137,13 +136,15 @@ static int delete_node(struct udevice *dev) } /* remove subdirectories */ - if (strchr(dev->name, '/')) + if (strchr(udev->name, '/')) delete_path(filename); - foreach_strpart(dev->symlink, " ", pos, len) { + foreach_strpart(udev->symlink, " ", pos, len) { + char linkname[NAME_SIZE]; + strfieldcpymax(linkname, pos, len+1); - strfieldcpy(filename, udev_root); - strfieldcat(filename, linkname); + snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, linkname); + filename[NAME_SIZE-1] = '\0'; dbg("unlinking symlink '%s'", filename); retval = unlink(filename); @@ -154,7 +155,7 @@ static int delete_node(struct udevice *dev) filename, strerror(errno)); return retval; } - if (strchr(dev->symlink, '/')) { + if (strchr(udev->symlink, '/')) { delete_path(filename); } } @@ -168,18 +169,14 @@ static int delete_node(struct udevice *dev) */ int udev_remove_device(struct udevice *udev) { - struct udevice db_dev; const char *temp; int retval; if (udev->type != 'b' && udev->type != 'c') return 0; - retval = udevdb_get_dev(udev->devpath, &db_dev); - if (retval == 0) { - /* copy over the stored values to our device */ - memcpy(udev, &db_dev, UDEVICE_DB_LEN); - } else { + retval = udevdb_get_dev(udev); + if (retval) { /* fall back to kernel name */ temp = strrchr(udev->devpath, '/'); if (temp == NULL) @@ -189,10 +186,10 @@ int udev_remove_device(struct udevice *udev) } dbg("remove name='%s'", udev->name); - udevdb_delete_dev(udev->devpath); + udevdb_delete_dev(udev); /* use full path to the environment */ - snprintf(udev->devname, NAME_SIZE-1, "%s%s", udev_root, udev->name); + snprintf(udev->devname, NAME_SIZE-1, "%s/%s", udev_root, udev->name); return delete_node(udev); } diff --git a/udevdb.c b/udevdb.c index 6a3357d0bb..fc579a9451 100644 --- a/udevdb.c +++ b/udevdb.c @@ -1,10 +1,10 @@ /* - * udevdb.c - udev database library + * udevdb.c * * Userspace devfs * * Copyright (C) 2003 Greg Kroah-Hartman - * Copyright (C) 2003 IBM Corp. + * 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 @@ -21,216 +21,194 @@ * */ + #include #include #include #include #include #include -#include #include -#include +#include #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "udev_lib.h" -#include "udev_version.h" #include "logging.h" -#include "namedev.h" #include "udevdb.h" -#include "tdb/tdb.h" -static TDB_CONTEXT *udevdb; -sig_atomic_t gotalarm; +#define PATH_TO_NAME_CHAR '@' + +static int get_db_filename(struct udevice *udev, char *filename, int len) +{ + char devpath[SYSFS_PATH_MAX]; + char *pos; + + /* replace '/' to transform path into a filename */ + strfieldcpy(devpath, udev->devpath); + pos = strchr(&devpath[1], '/'); + while (pos) { + pos[0] = PATH_TO_NAME_CHAR; + pos = strchr(&pos[1], '/'); + } + snprintf(filename, len-1, "%s%s", udev_db_path, devpath); + filename[len-1] = '\0'; + + return 0; +} int udevdb_add_dev(struct udevice *udev) { - TDB_DATA key, data; - char keystr[SYSFS_PATH_MAX]; + char filename[SYSFS_PATH_MAX]; + FILE *f; if (udev->test_run) return 0; - if (udevdb == NULL) + get_db_filename(udev, filename, SYSFS_PATH_MAX); + + create_path(filename); + + f = fopen(filename, "w"); + if (f == NULL) { + dbg("unable to create db file '%s'", filename); return -1; + } + dbg("storing data for device '%s' in '%s'", udev->devpath, filename); - memset(keystr, 0x00, SYSFS_PATH_MAX); - strfieldcpy(keystr, udev->devpath); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; + fprintf(f, "P:%s\n", udev->devpath); + fprintf(f, "N:%s\n", udev->name); + fprintf(f, "S:%s\n", udev->symlink); + fprintf(f, "A:%d\n", udev->partitions); - data.dptr = (void *) udev; - data.dsize = UDEVICE_DB_LEN; - dbg("store key '%s' for device '%s'", keystr, udev->name); - - return tdb_store(udevdb, key, data, TDB_REPLACE); -} - -int udevdb_get_dev(const char *path, struct udevice *udev) -{ - TDB_DATA key, data; - - if (udevdb == NULL) - return -1; - - if (path == NULL) - return -ENODEV; - - key.dptr = (void *)path; - key.dsize = strlen(path) + 1; - - data = tdb_fetch(udevdb, key); - if (data.dptr == NULL || data.dsize == 0) - return -ENODEV; - - memset(udev, 0x00, sizeof(struct udevice)); - memcpy(udev, data.dptr, UDEVICE_DB_LEN); + fclose(f); return 0; } -int udevdb_delete_dev(const char *path) +static int parse_db_file(struct udevice *udev, const char *filename) { - TDB_DATA key; - char keystr[SYSFS_PATH_MAX]; + char line[NAME_SIZE]; + char *bufline; + char *buf; + size_t bufsize; + size_t cur; + size_t count; - if (udevdb == NULL) + if (file_map(filename, &buf, &bufsize) != 0) { + dbg("unable to read db file '%s'", filename); + return -1; + } + + cur = 0; + while (cur < bufsize) { + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + + switch(bufline[0]) { + case 'P': + if (count > DEVPATH_SIZE) + count = DEVPATH_SIZE-1; + strncpy(udev->devpath, &bufline[2], count-2); + break; + case 'N': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(udev->name, &bufline[2], count-2); + break; + case 'S': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(udev->symlink, &bufline[2], count-2); + break; + case 'A': + strfieldcpy(line, &bufline[2]); + udev->partitions = atoi(line); + break; + } + } + + if (udev->name[0] == '\0') return -1; - if (path == NULL) - return -EINVAL; - - memset(keystr, 0, sizeof(keystr)); - strfieldcpy(keystr, path); - - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - return tdb_delete(udevdb, key); -} - -/** - * udevdb_exit: closes database - */ -void udevdb_exit(void) -{ - if (udevdb != NULL) { - tdb_close(udevdb); - udevdb = NULL; - } -} - -/** - * udevdb_init: initializes database - * @init_flag: UDEVDB_INTERNAL - database stays in memory - * UDEVDB_DEFAULT - database is written to a file - */ -int udevdb_init(int init_flag) -{ - if (init_flag != UDEVDB_DEFAULT && init_flag != UDEVDB_INTERNAL) - return -EINVAL; - - tdb_set_lock_alarm(&gotalarm); - - udevdb = tdb_open(udev_db_filename, 0, init_flag, O_RDWR | O_CREAT, 0644); - if (udevdb == NULL) { - if (init_flag == UDEVDB_INTERNAL) - dbg("unable to initialize in-memory database"); - else - dbg("unable to initialize database at '%s'", udev_db_filename); - return -EACCES; - } return 0; } -/** - * udevdb_open_ro: open database for reading - */ -int udevdb_open_ro(void) +int udevdb_get_dev(struct udevice *udev) { - udevdb = tdb_open(udev_db_filename, 0, 0, O_RDONLY, 0); - if (udevdb == NULL) { - dbg("unable to open database at '%s'", udev_db_filename); - return -EACCES; - } + char filename[SYSFS_PATH_MAX]; + + get_db_filename(udev, filename, SYSFS_PATH_MAX); + + return parse_db_file(udev, filename); +} + +int udevdb_delete_dev(struct udevice *udev) +{ + char filename[SYSFS_PATH_MAX]; + + get_db_filename(udev, filename, SYSFS_PATH_MAX); + unlink(filename); + return 0; } -static int (*user_record_callback) (const char *path, struct udevice *dev); - -static int traverse_callback(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) +int udevdb_get_dev_byname(struct udevice *udev, const char *name) { - return user_record_callback((char*) key.dptr, (struct udevice*) dbuf.dptr); -} + struct dirent *ent; + DIR *dir; + char filename[NAME_SIZE]; + struct udevice db_udev; -/** - * udevdb_call_foreach: dumps whole database by passing record data to user function - * @user_record_handler: user function called for every record in the database - */ -int udevdb_call_foreach(int (*user_record_handler) (const char *path, struct udevice *dev)) -{ - int retval = 0; - - if (udevdb == NULL) + dir = opendir(udev_db_path); + if (dir == NULL) { + dbg("unable to udev db '%s'", udev_db_path); return -1; - - if (user_record_handler == NULL) { - dbg("invalid user record handling function"); - return -EINVAL; } - user_record_callback = user_record_handler; - retval = tdb_traverse(udevdb, traverse_callback, NULL); - if (retval < 0) - return -ENODEV; - else - return 0; -} -static struct udevice *find_dev; -static char *find_path; -static const char *find_name; -static int find_found; + while (1) { + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; -static int find_device_by_name(const char *path, struct udevice *udev) -{ - char *pos; - int len; - - if (strncmp(udev->name, find_name, sizeof(udev->name)) == 0) { - memcpy(find_dev, udev, sizeof(struct udevice)); - strfieldcpymax(find_path, path, NAME_SIZE); - find_found = 1; - /* stop search */ - return 1; - } - /* look for matching symlink*/ - foreach_strpart(udev->symlink, " ", pos, len) { - if (strncmp(pos, find_name, len) != 0) + if (ent->d_name[0] == '.') continue; - if (len != strlen(find_name)) - continue; + snprintf(filename, NAME_SIZE-1, "%s/%s", udev_db_path, ent->d_name); + filename[NAME_SIZE-1] = '\0'; - memcpy(find_dev, udev, sizeof(struct udevice)); - strfieldcpymax(find_path, path, NAME_SIZE); - find_found = 1; - return 1; + memset(&db_udev, 0x00, sizeof(struct udevice)); + if (parse_db_file(&db_udev, filename) == 0) { + char *pos; + int len; + + if (strncmp(name, db_udev.name, NAME_SIZE) == 0) { + goto found; + } + + foreach_strpart(db_udev.symlink, " ", pos, len) { + if (strncmp(name, pos, len) != 0) + continue; + + if (len == strlen(name)) + goto found; + } + + } } + + closedir(dir); + + return -1; + +found: + closedir(dir); + + strfieldcpy(udev->devpath, db_udev.devpath); + strfieldcpy(udev->name, db_udev.name); + strfieldcpy(udev->symlink, db_udev.symlink); + udev->partitions = db_udev.partitions; + return 0; } - -/** - * udevdb_get_dev_byname: search device with given name by traversing the whole database - */ -int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev) -{ - find_found = 0; - find_path = path; - find_dev = dev; - find_name = name; - udevdb_call_foreach(find_device_by_name); - if (find_found == 1) - return 0; - else - return -1; -} diff --git a/udevdb.h b/udevdb.h index 6986a0a113..4f6b5de90c 100644 --- a/udevdb.h +++ b/udevdb.h @@ -1,22 +1,34 @@ /* - * udevdb header file + * udevdb.h + * + * Userspace devfs + * + * Copyright (C) 2003 Greg Kroah-Hartman + * 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. + * + * 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 _UDEVDB_H_ #define _UDEVDB_H_ -/* Udevdb initialization flags */ -#define UDEVDB_DEFAULT 0 /* defaults database to use file */ -#define UDEVDB_INTERNAL 1 /* don't store db on disk, use in memory */ - -/* function prototypes */ -extern void udevdb_exit(void); -extern int udevdb_init(int init_flag); -extern int udevdb_open_ro(void); -extern int udevdb_call_foreach(int (*user_record_handler) (const char *path, struct udevice *dev)); extern int udevdb_add_dev(struct udevice *dev); -extern int udevdb_get_dev(const char *path, struct udevice *dev); -extern int udevdb_delete_dev(const char *path); -extern int udevdb_get_dev_byname(const char *name, char *path, struct udevice *dev); +extern int udevdb_get_dev(struct udevice *dev); +extern int udevdb_delete_dev(struct udevice *dev); + +extern int udevdb_get_dev_byname(struct udevice *udev, const char *name); #endif /* _UDEVDB_H_ */ diff --git a/udevinfo.8 b/udevinfo.8 index 0588084cac..a04e6df463 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -29,7 +29,7 @@ interface. .RB Needs " \-p " or " \-n " specified. .br Valid types are: -.BR name ", " symlink ", " mode " ," owner " , " group " , " path " or " all. +.BR name ", " symlink ", " path " or " all. .TP .BI \-p " sysfs_path" Specify the sysfs path of the device to query. @@ -46,9 +46,6 @@ attributes along the device chain. Useful for finding unique attributes to compose a rule. .RB Needs " \-p " specified. .TP -.B \-d -Dump the whole database. -.TP .B \-h Print help text. .SH "FILES" diff --git a/udevinfo.c b/udevinfo.c index af2346c8f5..a90bbe1138 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -103,19 +103,11 @@ exit: return retval; } -/* callback for database dump */ -static int print_record(const char *path, struct udevice *dev) +static int print_record(struct udevice *udev) { - printf("P: %s\n", path); - printf("N: %s\n", dev->name); - printf("T: %c\n", dev->type); - printf("M: %#o\n", dev->mode); - printf("S: %s\n", dev->symlink); - printf("O: %s\n", dev->owner); - printf("G: %s\n", dev->group); - printf("F: %s\n", dev->config_file); - printf("L: %i\n", dev->config_line); - printf("U: %li\n", dev->config_uptime); + printf("P: %s\n", udev->devpath); + printf("N: %s\n", udev->name); + printf("S: %s\n", udev->symlink); printf("\n"); return 0; } @@ -125,9 +117,6 @@ enum query_type { NAME, PATH, SYMLINK, - MODE, - OWNER, - GROUP, ALL }; @@ -213,7 +202,7 @@ static int process_options(void) static const char short_options[] = "adn:p:q:rVh"; int option; int retval = 1; - struct udevice dev; + struct udevice udev; int root = 0; int attributes = 0; enum query_type query = NONE; @@ -254,21 +243,6 @@ static int process_options(void) break; } - if (strcmp(optarg, "mode") == 0) { - query = MODE; - break; - } - - if (strcmp(optarg, "owner") == 0) { - query = OWNER; - break; - } - - if (strcmp(optarg, "group") == 0) { - query = GROUP; - break; - } - if (strcmp(optarg, "path") == 0) { query = PATH; break; @@ -290,16 +264,6 @@ static int process_options(void) attributes = 1; break; - case 'd': - retval = udevdb_open_ro(); - if (retval != 0) { - printf("unable to open udev database\n"); - exit(2); - } - udevdb_call_foreach(print_record); - udevdb_exit(); - exit(0); - case 'V': printf("udevinfo, version %s\n", UDEV_VERSION); exit(0); @@ -314,12 +278,6 @@ static int process_options(void) /* process options */ if (query != NONE) { - retval = udevdb_open_ro(); - if (retval != 0) { - printf("unable to open udev database\n"); - return -EACCES; - } - if (path[0] != '\0') { /* remove sysfs_path if given */ if (strncmp(path, sysfs_path, strlen(sysfs_path)) == 0) { @@ -334,7 +292,9 @@ static int process_options(void) pos = path; } } - retval = udevdb_get_dev(pos, &dev); + memset(&udev, 0x00, sizeof(struct udevice)); + strfieldcpy(udev.devpath, pos); + retval = udevdb_get_dev(&udev); if (retval != 0) { printf("device not found in database\n"); goto exit; @@ -344,15 +304,21 @@ static int process_options(void) if (name[0] != '\0') { /* remove udev_root if given */ - if (strncmp(name, udev_root, strlen(udev_root)) == 0) { - pos = name + strlen(udev_root); + int len = strlen(udev_root); + + if (strncmp(name, udev_root, len) == 0) { + pos = &name[len+1]; } else pos = name; - retval = udevdb_get_dev_byname(pos, path, &dev); + + memset(&udev, 0x00, sizeof(struct udevice)); + strfieldcpy(udev.name, pos); + retval = udevdb_get_dev_byname(&udev, pos); if (retval != 0) { printf("device not found in database\n"); goto exit; } + goto print; } @@ -362,25 +328,16 @@ static int process_options(void) print: switch(query) { case NAME: - if (root) - strfieldcpy(result, udev_root); - strfieldcat(result, dev.name); + if (root) { + snprintf(result, NAME_SIZE-1, "%s/%s", udev_root, udev.name); + result[NAME_SIZE-1] = '\0'; + } else { + strfieldcpy(result, udev.name); + } break; case SYMLINK: - strfieldcpy(result, dev.symlink); - break; - - case MODE: - sprintf(result, "%#o", dev.mode); - break; - - case GROUP: - strfieldcpy(result, dev.group); - break; - - case OWNER: - strfieldcpy(result, dev.owner); + strfieldcpy(result, udev.symlink); break; case PATH: @@ -388,7 +345,7 @@ print: break; case ALL: - print_record(path, &dev); + print_record(&udev); goto exit; default: @@ -397,7 +354,6 @@ print: printf("%s\n", result); exit: - udevdb_exit(); return retval; } @@ -427,9 +383,6 @@ help: " -q TYPE query database for the specified value:\n" " 'name' name of device node\n" " 'symlink' pointing to node\n" - " 'mode' permissions of node\n" - " 'owner' of node\n" - " 'group' of node\n" " 'path' sysfs device path\n" " 'all' all values\n" "\n" @@ -438,7 +391,6 @@ help: "\n" " -r print udev root\n" " -a print all SYSFS_attributes along the device chain\n" - " -d dump whole database\n" " -V print udev version\n" " -h print this help text\n" "\n"); diff --git a/udevsend.c b/udevsend.c index c0c72b9c19..19922f3870 100644 --- a/udevsend.c +++ b/udevsend.c @@ -95,7 +95,7 @@ static void run_udev(const char *subsystem) switch (pid) { case 0: /* child */ - execl(UDEV_BIN, UDEV_BIN, subsystem, NULL); + execl(UDEV_BIN, "udev", subsystem, NULL); dbg("exec of child failed"); _exit(1); break; From 04b49aab9addcc628381d187d0586c20a8c2cfad Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 12 Nov 2004 23:43:34 -0800 Subject: [PATCH 0968/4284] [PATCH] make spotless for releases. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index ef66213dd8..e1a4b9fe27 100644 --- a/Makefile +++ b/Makefile @@ -332,7 +332,7 @@ spotless: clean DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz" -e "\/\." -e releases -e BitKeeper -e SCCS -e test/sys | sort ) DISTDIR := $(RELEASE_NAME) srcdir = . -release: clean +release: spotless -rm -rf $(DISTDIR) mkdir $(DISTDIR) chmod 777 $(DISTDIR) @@ -342,7 +342,7 @@ release: clean @echo "$(RELEASE_NAME).tar.gz created" -small_release: $(DISTFILES) clean +small_release: $(DISTFILES) spotless # @echo $(DISTFILES) @-rm -rf $(DISTDIR) @mkdir $(DISTDIR) From 4a231017ff6e9f66a685b0d1e4e49dc46645bb40 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 6 Nov 2004 14:30:15 +0100 Subject: [PATCH 0969/4284] [PATCH] pass the whole event environment to udevd Make _all_ hotplug variables available to the forked udev, the udev callouts and the udev dev.d/ scripts. We put the whole environment into a buffer and send it over the udevd socket. udevd recreates *envp[] and passes it to the exec(). --- udevd.c | 94 ++++++++++++++++++++++++++++++------------------------ udevd.h | 19 ++++++++--- udevsend.c | 90 ++++++++++++++++++++++++++------------------------- 3 files changed, 112 insertions(+), 91 deletions(-) diff --git a/udevd.c b/udevd.c index 395cdca88b..12fbe1725f 100644 --- a/udevd.c +++ b/udevd.c @@ -86,16 +86,6 @@ static void msg_dump_queue(void) #endif } -static struct hotplug_msg *msg_create(void) -{ - struct hotplug_msg *new_msg; - - new_msg = malloc(sizeof(struct hotplug_msg)); - if (new_msg == NULL) - dbg("error malloc"); - return new_msg; -} - static void run_queue_delete(struct hotplug_msg *msg) { list_del(&msg->list); @@ -132,22 +122,12 @@ static void msg_queue_insert(struct hotplug_msg *msg) static void udev_run(struct hotplug_msg *msg) { pid_t pid; - char action[ACTION_SIZE]; - char devpath[DEVPATH_SIZE]; - char seqnum[SEQNUM_SIZE]; - char *env[] = { action, devpath, seqnum, NULL }; - - snprintf(action, ACTION_SIZE-1, "ACTION=%s", msg->action); - action[ACTION_SIZE-1] = '\0'; - snprintf(devpath, DEVPATH_SIZE-1, "DEVPATH=%s", msg->devpath); - devpath[DEVPATH_SIZE-1] = '\0'; - sprintf(seqnum, "SEQNUM=%llu", msg->seqnum); pid = fork(); switch (pid) { case 0: /* child */ - execle(udev_bin, "udev", msg->subsystem, NULL, env); + execle(udev_bin, "udev", msg->subsystem, NULL, msg->envp); dbg("exec of child failed"); _exit(1); break; @@ -245,24 +225,23 @@ recheck: } /* receive the msg, do some basic sanity checks, and queue it */ -static void handle_msg(int sock) +static void handle_udevsend_msg(int sock) { + static struct udevsend_msg usend_msg; struct hotplug_msg *msg; - int retval; + int bufpos; + int i; + ssize_t size; struct msghdr smsg; struct cmsghdr *cmsg; struct iovec iov; struct ucred *cred; char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; + int envbuf_size; - msg = msg_create(); - if (msg == NULL) { - dbg("unable to store message"); - return; - } - - iov.iov_base = msg; - iov.iov_len = sizeof(struct hotplug_msg); + memset(&usend_msg, 0x00, sizeof(struct udevsend_msg)); + iov.iov_base = &usend_msg; + iov.iov_len = sizeof(struct udevsend_msg); memset(&smsg, 0x00, sizeof(struct msghdr)); smsg.msg_iov = &iov; @@ -270,8 +249,8 @@ static void handle_msg(int sock) smsg.msg_control = cred_msg; smsg.msg_controllen = sizeof(cred_msg); - retval = recvmsg(sock, &smsg, 0); - if (retval < 0) { + size = recvmsg(sock, &smsg, 0); + if (size < 0) { if (errno != EINTR) dbg("unable to receive message"); return; @@ -281,19 +260,52 @@ static void handle_msg(int sock) if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { dbg("no sender credentials received, message ignored"); - goto skip; + goto exit; } if (cred->uid != 0) { dbg("sender uid=%i, message ignored", cred->uid); - goto skip; + goto exit; } - if (strncmp(msg->magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { - dbg("message magic '%s' doesn't match, ignore it", msg->magic); - goto skip; + if (strncmp(usend_msg.magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { + dbg("message magic '%s' doesn't match, ignore it", usend_msg.magic); + goto exit; } + envbuf_size = size - offsetof(struct udevsend_msg, envbuf); + dbg("envbuf_size=%i", envbuf_size); + msg = malloc(sizeof(struct hotplug_msg) + envbuf_size); + memset(msg, 0x00, sizeof(struct hotplug_msg) + envbuf_size); + + /* copy environment buffer and reconstruct envp */ + memcpy(msg->envbuf, usend_msg.envbuf, envbuf_size); + bufpos = 0; + for (i = 0; (bufpos < envbuf_size) && (i < HOTPLUG_NUM_ENVP-1); 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]; + + if (strncmp(key, "DEVPATH=", 8) == 0) + msg->devpath = &key[8]; + + if (strncmp(key, "SUBSYSTEM=", 10) == 0) + msg->subsystem = &key[10]; + + if (strncmp(key, "SEQNUM=", 7) == 0) + msg->seqnum = strtoull(&key[7], NULL, 10); + } + msg->envp[i] = NULL; + /* if no seqnum is given, we move straight to exec queue */ if (msg->seqnum == 0) { list_add(&msg->list, &exec_list); @@ -301,10 +313,8 @@ static void handle_msg(int sock) } else { msg_queue_insert(msg); } - return; -skip: - free(msg); +exit: return; } @@ -511,7 +521,7 @@ int main(int argc, char *argv[], char *envp[]) } if (FD_ISSET(ssock, &workreadfds)) - handle_msg(ssock); + handle_udevsend_msg(ssock); if (FD_ISSET(pipefds[0], &workreadfds)) user_sighandler(); diff --git a/udevd.h b/udevd.h index 657f684e3f..b393a28bf9 100644 --- a/udevd.h +++ b/udevd.h @@ -30,14 +30,23 @@ #define SEND_WAIT_MAX_SECONDS 3 #define SEND_WAIT_LOOP_PER_SECOND 10 +/* environment buffer, should match the kernel's size in lib/kobject_uevent.h */ +#define HOTPLUG_BUFFER_SIZE 1024 +#define HOTPLUG_NUM_ENVP 32 + +struct udevsend_msg { + char magic[20]; + char envbuf[HOTPLUG_BUFFER_SIZE]; +}; struct hotplug_msg { - char magic[20]; struct list_head list; pid_t pid; - unsigned long long seqnum; long queue_time; - char action[ACTION_SIZE]; - char devpath[DEVPATH_SIZE]; - char subsystem[SUBSYSTEM_SIZE]; + char *action; + char *devpath; + char *subsystem; + unsigned long long seqnum; + char *envp[HOTPLUG_NUM_ENVP]; + char envbuf[]; }; diff --git a/udevsend.c b/udevsend.c index 19922f3870..7db2378b83 100644 --- a/udevsend.c +++ b/udevsend.c @@ -70,7 +70,7 @@ static int start_daemon(void) chdir("/"); execl(UDEVD_BIN, "udevd", NULL); dbg("exec of daemon failed"); - exit(1); + _exit(1); case -1: dbg("fork of daemon failed"); return -1; @@ -107,51 +107,29 @@ static void run_udev(const char *subsystem) } } -int main(int argc, char* argv[]) +int main(int argc, char *argv[], char *envp[]) { - struct hotplug_msg msg; - char *action; - char *devpath; - char *subsystem; - char *seqnum; - unsigned long long seq; - int retval = 1; + static struct udevsend_msg usend_msg; + int usend_msg_len; + int i; int loop; - int sock = -1; struct sockaddr_un saddr; socklen_t addrlen; + const char *subsystem_argv; + int subsystem_env = 0; + int bufpos = 0; + int retval = 1; + int sock = -1; int started_daemon = 0; logging_init("udevsend"); dbg("version %s", UDEV_VERSION); - subsystem = get_subsystem(argv[1]); - if (subsystem == NULL) { + subsystem_argv = argv[1]; + if (subsystem_argv == NULL) { dbg("no subsystem"); goto exit; } - dbg("subsystem = '%s'", subsystem); - - devpath = get_devpath(); - if (devpath == NULL) { - dbg("no devpath"); - goto exit; - } - dbg("DEVPATH = '%s'", devpath); - - action = get_action(); - if (action == NULL) { - dbg("no action"); - goto exit; - } - dbg("ACTION = '%s'", action); - - seqnum = get_seqnum(); - if (seqnum == NULL) - seq = 0; - else - seq = strtoull(seqnum, NULL, 10); - dbg("SEQNUM = '%llu'", seq); sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { @@ -167,25 +145,49 @@ int main(int argc, char* argv[]) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - memset(&msg, 0x00, sizeof(struct hotplug_msg)); - strcpy(msg.magic, UDEV_MAGIC); - msg.seqnum = seq; - strfieldcpy(msg.action, action); - strfieldcpy(msg.devpath, devpath); - strfieldcpy(msg.subsystem, subsystem); + memset(&usend_msg, 0x00, sizeof(struct udevsend_msg)); + + strcpy(usend_msg.magic, UDEV_MAGIC); + + /* copy all keys to send buffer */ + for (i = 0; envp[i]; i++) { + const char *key; + int keylen; + + key = envp[i]; + keylen = strlen(key); + if (bufpos + keylen >= HOTPLUG_BUFFER_SIZE-1) { + dbg("environment buffer too small, probably not called by the kernel"); + continue; + } + + /* older kernels do not have the SUBSYSTEM in the environment */ + if (strncmp(key, "SUBSYSTEM=", 10) == 0) + subsystem_env = 1; + + dbg("add '%s' to env[%i] buffer", key, i); + strcpy(&usend_msg.envbuf[bufpos], key); + bufpos += keylen + 1; + } + if (!subsystem_env) { + bufpos += sprintf(&usend_msg.envbuf[bufpos], "SUBSYSTEM=%s", subsystem_argv) + 1; + dbg("add 'SUBSYSTEM=%s' to env[%i] buffer from argv", subsystem_argv, i); + } + + usend_msg_len = offsetof(struct udevsend_msg, envbuf) + bufpos; + dbg("usend_msg_len=%i", usend_msg_len); /* If we can't send, try to start daemon and resend message */ loop = SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND; while (--loop) { - retval = sendto(sock, &msg, sizeof(struct hotplug_msg), 0, - (struct sockaddr *)&saddr, addrlen); + retval = sendto(sock, &usend_msg, usend_msg_len, 0, (struct sockaddr *)&saddr, addrlen); if (retval != -1) { retval = 0; goto exit; } if (errno != ECONNREFUSED) { - dbg("error sending message"); + dbg("error sending message (%s)", strerror(errno)); goto fallback; } @@ -206,7 +208,7 @@ int main(int argc, char* argv[]) fallback: info("unable to connect to event daemon, try to call udev directly"); - run_udev(subsystem); + run_udev(subsystem_argv); exit: if (sock != -1) From f156b6d2037ff09f7218e11d5326c05488356ea1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 9 Nov 2004 12:11:46 +0100 Subject: [PATCH 0970/4284] [PATCH] add sysfs info walk to udevinfo The option "-s" will get information about the major/minor, the physical device, the bus value and the driver from sysfs for all class and block devices: kay@pim udev.kay]$ ./udevinfo -s DEVPATH '/sys/block/sda' SUBSYSTEM 'block' NAME 'sda' MAJORMINOR '8:0' PHYSDEVPATH '/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-3/1-3:1.0/host2/target2:0:0/2:0:0:0' PHYSDEVPATHBUS 'scsi' DRIVER 'sd' DEVPATH '/sys/class/input/mice' SUBSYSTEM 'input' NAME 'mice' MAJORMINOR '13:63' DEVPATH '/sys/class/input/mouse0' SUBSYSTEM 'input' NAME 'mouse0' MAJORMINOR '13:32' ... --- udevinfo.8 | 4 ++++ udevinfo.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/udevinfo.8 b/udevinfo.8 index a04e6df463..599a0033f8 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -46,6 +46,10 @@ attributes along the device chain. Useful for finding unique attributes to compose a rule. .RB Needs " \-p " specified. .TP +.B \-s +Print all sysfs devices with the major/minor number, the physical device and +the bus value. +.TP .B \-h Print help text. .SH "FILES" diff --git a/udevinfo.c b/udevinfo.c index a90bbe1138..f1b74fc8f6 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -197,9 +197,67 @@ exit: return retval; } +/* print all class/block devices with major/minor, physical device and bus*/ +static void print_sysfs_devices(void) +{ + struct dlist *subsyslist; + char *class; + + subsyslist = sysfs_open_subsystem_list("class"); + if (!subsyslist) + exit(1); + + dlist_for_each_data(subsyslist, class, char) { + struct sysfs_class *cls; + struct dlist *class_devices; + struct sysfs_class_device *class_dev; + struct sysfs_device *phys_dev; + + cls = sysfs_open_class(class); + if (!cls) + continue; + + class_devices = sysfs_get_class_devices(cls); + if (!class_devices) + continue; + + dlist_for_each_data(class_devices, class_dev, struct sysfs_class_device) { + struct sysfs_attribute *attr; + + printf("\n"); + printf("DEVPATH '%s'\n", class_dev->path); + printf("SUBSYSTEM '%s'\n", class_dev->classname); + printf("NAME '%s'\n", class_dev->name); + + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr) { + char *pos = &(attr->value[strlen(attr->value)-1]); + + if (pos[0] == '\n') + pos[0] = '\0'; + + printf("MAJORMINOR '%s'\n", attr->value); + } + + phys_dev = sysfs_get_classdev_device(class_dev); + if (phys_dev) { + printf("PHYSDEVPATH '%s'\n", phys_dev->path); + if (phys_dev->bus[0] != '\0') + printf("PHYSDEVPATHBUS '%s'\n", phys_dev->bus); + if (phys_dev->driver_name[0] != '\0') + printf("DRIVER '%s'\n", phys_dev->driver_name); + } + } + + sysfs_close_class(cls); + } + + sysfs_close_list(subsyslist); +} + static int process_options(void) { - static const char short_options[] = "adn:p:q:rVh"; + static const char short_options[] = "adn:p:q:rsVh"; int option; int retval = 1; struct udevice udev; @@ -260,6 +318,10 @@ static int process_options(void) root = 1; break; + case 's': + print_sysfs_devices(); + exit(0); + case 'a': attributes = 1; break; @@ -391,6 +453,7 @@ help: "\n" " -r print udev root\n" " -a print all SYSFS_attributes along the device chain\n" + " -s print all sysfs devices with major/minor, physical device and bus\n" " -V print udev version\n" " -h print this help text\n" "\n"); From 3bdef3939d6501b26dac82fdc6f8e74d854a1f14 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Nov 2004 02:15:27 +0100 Subject: [PATCH 0971/4284] [PATCH] improve udevinfo sysfs info walk --- udevinfo.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index f1b74fc8f6..8fab86ca8c 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -197,21 +197,22 @@ exit: return retval; } -/* print all class/block devices with major/minor, physical device and bus*/ -static void print_sysfs_devices(void) +/* print all class/main block devices with major/minor, physical device, driver and bus */ +static int print_sysfs_devices(void) { struct dlist *subsyslist; char *class; subsyslist = sysfs_open_subsystem_list("class"); if (!subsyslist) - exit(1); + return -1; dlist_for_each_data(subsyslist, class, char) { struct sysfs_class *cls; struct dlist *class_devices; struct sysfs_class_device *class_dev; struct sysfs_device *phys_dev; + struct sysfs_driver *driver; cls = sysfs_open_class(class); if (!cls) @@ -227,7 +228,6 @@ static void print_sysfs_devices(void) printf("\n"); printf("DEVPATH '%s'\n", class_dev->path); printf("SUBSYSTEM '%s'\n", class_dev->classname); - printf("NAME '%s'\n", class_dev->name); attr = sysfs_get_classdev_attr(class_dev, "dev"); if (attr) { @@ -236,23 +236,25 @@ static void print_sysfs_devices(void) if (pos[0] == '\n') pos[0] = '\0'; - printf("MAJORMINOR '%s'\n", attr->value); + printf("DEVMAJORMINOR '%s'\n", attr->value); } + driver = sysfs_get_classdev_driver(class_dev); + if (driver) + printf("DEVDRIVER '%s'\n", driver->name); + phys_dev = sysfs_get_classdev_device(class_dev); if (phys_dev) { printf("PHYSDEVPATH '%s'\n", phys_dev->path); if (phys_dev->bus[0] != '\0') - printf("PHYSDEVPATHBUS '%s'\n", phys_dev->bus); - if (phys_dev->driver_name[0] != '\0') - printf("DRIVER '%s'\n", phys_dev->driver_name); + printf("PHYSDEVBUS '%s'\n", phys_dev->bus); } } - sysfs_close_class(cls); } - sysfs_close_list(subsyslist); + + return 0; } static int process_options(void) From 38753167e4e49879f97003f075158cc642bf0b0d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Nov 2004 09:44:58 +0100 Subject: [PATCH 0972/4284] [PATCH] let udev act as udevstart if argv[1] == "udevstart" "udev udevstart" will run udev as udevstart. This makes it easier to run a test in the source tree without the need to create a symlink. --- udev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.c b/udev.c index d8cb4365fd..b54896669b 100644 --- a/udev.c +++ b/udev.c @@ -91,7 +91,7 @@ int main(int argc, char *argv[], char *envp[]) udev_init_config(); - if (strstr(argv[0], "udevstart")) { + if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { act_type = UDEVSTART; } else { const char *action = get_action(); From 31fd340352236c06c30a85fa9fbdbfbbd10bd439 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 10 Nov 2004 10:19:39 +0100 Subject: [PATCH 0973/4284] [PATCH] make udevinfo's -r option also workimg for symlink queries [kay@pim udev.kay]$ ./udevinfo -r -q symlink -p /class/video4linux/video0 /dev/camera0 /dev/kamera0 /dev/videocam0 /dev/webcam0 [kay@pim udev.kay]$ ./udevinfo -q symlink -p /class/video4linux/video0 camera0 kamera0 videocam0 webcam0 --- udevinfo.8 | 5 +++-- udevinfo.c | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/udevinfo.8 b/udevinfo.8 index 599a0033f8..bbcc3d8f49 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -19,9 +19,10 @@ Print the version information. .B \-r Print the .B udev_root -directory. When used in conjunction with a query for the node name, the +directory. When used in conjunction with a query for the node name or the +symlink names, the .B udev_root -will be prepended. +will be prepended to query result. .TP .BI \-q " query_type" Query the database for specified value of a created device node or network diff --git a/udevinfo.c b/udevinfo.c index 8fab86ca8c..290a09e880 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -266,7 +266,7 @@ static int process_options(void) int root = 0; int attributes = 0; enum query_type query = NONE; - char result[NAME_SIZE] = ""; + char result[1024] = ""; char path[NAME_SIZE] = ""; char name[NAME_SIZE] = ""; char temp[NAME_SIZE]; @@ -401,7 +401,20 @@ print: break; case SYMLINK: - strfieldcpy(result, udev.symlink); + if (root) { + int slen; + char *spos; + char slink[NAME_SIZE]; + + pos = result; + foreach_strpart(udev.symlink, " \n\r", spos, slen) { + strncpy(slink, spos, slen); + slink[slen] = '\0'; + pos += sprintf(pos, "%s/%s ", udev_root, slink); + } + } else { + strfieldcpy(result, udev.symlink); + } break; case PATH: From c6478ec1e128f0a92c2123ed110a651b88d43569 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Nov 2004 06:17:35 +0100 Subject: [PATCH 0974/4284] [PATCH] add ACTION to udev object to expose it to the whole process --- udev.c | 8 ++++---- udev.h | 5 +++-- udev_lib.c | 54 +++-------------------------------------------------- udev_lib.h | 8 ++------ udevstart.c | 2 +- udevtest.c | 2 +- 6 files changed, 14 insertions(+), 65 deletions(-) diff --git a/udev.c b/udev.c index b54896669b..480a1cdca2 100644 --- a/udev.c +++ b/udev.c @@ -94,9 +94,9 @@ int main(int argc, char *argv[], char *envp[]) if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { act_type = UDEVSTART; } else { - const char *action = get_action(); - const char *devpath = get_devpath(); - const char *subsystem = get_subsystem(main_argv[1]); + const char *action = getenv("ACTION"); + const char *devpath = getenv("DEVPATH"); + const char *subsystem = argv[1]; if (!action) { dbg("no action?"); @@ -128,7 +128,7 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - udev_set_values(&udev, devpath, subsystem); + udev_set_values(&udev, devpath, subsystem, action); /* skip blacklisted subsystems */ if (udev.type != 'n' && subsystem_expect_no_dev(subsystem)) { diff --git a/udev.h b/udev.h index 1cf4ad7eae..3f9f2c8612 100644 --- a/udev.h +++ b/udev.h @@ -30,8 +30,8 @@ #define COMMENT_CHARACTER '#' #define NAME_SIZE 256 -#define OWNER_SIZE 30 -#define GROUP_SIZE 30 +#define OWNER_SIZE 32 +#define GROUP_SIZE 32 #define MODE_SIZE 8 #define ACTION_SIZE 32 @@ -44,6 +44,7 @@ struct udevice { char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; + char action[ACTION_SIZE]; char name[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; diff --git a/udev_lib.c b/udev_lib.c index 7fb45f0b5f..951d36b1d7 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -35,56 +35,6 @@ #include "list.h" -char *get_action(void) -{ - char *action; - - action = getenv("ACTION"); - if (action != NULL && strlen(action) > ACTION_SIZE) - action[ACTION_SIZE-1] = '\0'; - - return action; -} - -char *get_devpath(void) -{ - char *devpath; - - devpath = getenv("DEVPATH"); - if (devpath != NULL && strlen(devpath) > DEVPATH_SIZE) - devpath[DEVPATH_SIZE-1] = '\0'; - - return devpath; -} - -char *get_devname(void) -{ - char *devname; - - devname = getenv("DEVNAME"); - if (devname != NULL && strlen(devname) > NAME_SIZE) - devname[NAME_SIZE-1] = '\0'; - - return devname; -} - -char *get_seqnum(void) -{ - char *seqnum; - - seqnum = getenv("SEQNUM"); - - return seqnum; -} - -char *get_subsystem(char *subsystem) -{ - if (subsystem != NULL && strlen(subsystem) > SUBSYSTEM_SIZE) - subsystem[SUBSYSTEM_SIZE-1] = '\0'; - - return subsystem; -} - #define BLOCK_PATH "/block/" #define CLASS_PATH "/class/" #define NET_PATH "/class/net/" @@ -112,11 +62,13 @@ char get_device_type(const char *path, const char *subsystem) return '\0'; } -void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem) +void udev_set_values(struct udevice *udev, const char* devpath, + const char *subsystem, const char* action) { memset(udev, 0x00, sizeof(struct udevice)); strfieldcpy(udev->devpath, devpath); strfieldcpy(udev->subsystem, subsystem); + strfieldcpy(udev->action, action); udev->type = get_device_type(devpath, subsystem); } diff --git a/udev_lib.h b/udev_lib.h index 94649b645f..30d839461a 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -76,13 +76,9 @@ do { \ # define asmlinkage /* nothing */ #endif -extern char *get_action(void); -extern char *get_devpath(void); -extern char *get_devname(void); -extern char *get_seqnum(void); -extern char *get_subsystem(char *subsystem); extern char get_device_type(const char *path, const char *subsystem); -extern void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem); +extern void udev_set_values(struct udevice *udev, const char* devpath, + const char *subsystem, const char* action); extern int create_path(const char *path); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); diff --git a/udevstart.c b/udevstart.c index fd490f0791..e05680aa93 100644 --- a/udevstart.c +++ b/udevstart.c @@ -110,7 +110,7 @@ static int add_device(char *devpath, char *subsystem) return -ENODEV; } - udev_set_values(&udev, devpath, subsystem); + udev_set_values(&udev, devpath, subsystem, "add"); udev_add_device(&udev, class_dev); /* run scripts */ diff --git a/udevtest.c b/udevtest.c index 8af2120fb1..e67af0df67 100644 --- a/udevtest.c +++ b/udevtest.c @@ -103,7 +103,7 @@ int main(int argc, char *argv[], char *envp[]) subsystem = argv[2]; /* fill in values and test_run flag*/ - udev_set_values(&udev, devpath, subsystem); + udev_set_values(&udev, devpath, subsystem, "add"); /* open the device */ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); From 13f24d596c5638443ffc7bc48c10a66758335c74 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Nov 2004 06:18:28 +0100 Subject: [PATCH 0975/4284] [PATCH] remove udev_lib dependency from udevsend, which makes it smaller --- Makefile | 2 +- udev_lib.c | 19 ------------------- udev_lib.h | 1 - udevd.c | 31 ++++++++++++++----------------- udevsend.c | 9 ++++----- 5 files changed, 19 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index e1a4b9fe27..50c72279f8 100644 --- a/Makefile +++ b/Makefile @@ -300,7 +300,7 @@ $(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h $(QUIET) $(STRIPCMD) $@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o udev_lib.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) diff --git a/udev_lib.c b/udev_lib.c index 951d36b1d7..84daf9fd19 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -229,22 +229,3 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) closedir(dir); return 0; } - -/* Set the FD_CLOEXEC flag of desc if value is nonzero, - or clear the flag if value is 0. - Return 0 on success, or -1 on error with errno set. */ - -int set_cloexec_flag (int desc, int value) -{ - int oldflags = fcntl (desc, F_GETFD, 0); - /* If reading the flags failed, return error indication now. */ - if (oldflags < 0) - return oldflags; - /* Set just the flag we want to set. */ - if (value != 0) - oldflags |= FD_CLOEXEC; - else - oldflags &= ~FD_CLOEXEC; - /* Store modified flag word in the descriptor. */ - return fcntl (desc, F_SETFD, oldflags); -} diff --git a/udev_lib.h b/udev_lib.h index 30d839461a..3777a7caa3 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -85,6 +85,5 @@ extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); extern void no_trailing_slash(char *path); extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension); -extern int set_cloexec_flag (int desc, int value); #endif diff --git a/udevd.c b/udevd.c index 12fbe1725f..43f3f0324b 100644 --- a/udevd.c +++ b/udevd.c @@ -43,6 +43,9 @@ #include "udevd.h" #include "logging.h" +/* global variables*/ +static int udevsendsock; + static int pipefds[2]; static unsigned long long expected_seqnum = 0; static volatile int sigchilds_waiting; @@ -127,6 +130,7 @@ static void udev_run(struct hotplug_msg *msg) switch (pid) { case 0: /* child */ + close(udevsendsock); execle(udev_bin, "udev", msg->subsystem, NULL, msg->envp); dbg("exec of child failed"); _exit(1); @@ -397,7 +401,7 @@ static void user_sighandler(void) int main(int argc, char *argv[], char *envp[]) { - int ssock, maxsockplus; + int maxsockplus; struct sockaddr_un saddr; socklen_t addrlen; int retval, fd; @@ -476,28 +480,21 @@ int main(int argc, char *argv[], char *envp[]) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - ssock = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (ssock == -1) { + udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (udevsendsock == -1) { dbg("error getting socket, exit"); exit(1); } - set_cloexec_flag(ssock, 1); - /* the bind takes care of ensuring only one copy running */ - retval = bind(ssock, (struct sockaddr *) &saddr, addrlen); + retval = bind(udevsendsock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { dbg("bind failed, exit"); goto exit; } - retval = fcntl(ssock, F_SETFD, FD_CLOEXEC); - if (retval < 0) { - dbg("error fcntl on ssock: %s", strerror(errno)); - exit(1); - } /* enable receiving of the sender credentials */ - setsockopt(ssock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); + setsockopt(udevsendsock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); /* possible override of udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); @@ -507,9 +504,9 @@ int main(int argc, char *argv[], char *envp[]) udev_bin = UDEV_BIN; FD_ZERO(&readfds); - FD_SET(ssock, &readfds); + FD_SET(udevsendsock, &readfds); FD_SET(pipefds[0], &readfds); - maxsockplus = ssock+1; + maxsockplus = udevsendsock+1; while (1) { fd_set workreadfds = readfds; retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); @@ -520,8 +517,8 @@ int main(int argc, char *argv[], char *envp[]) continue; } - if (FD_ISSET(ssock, &workreadfds)) - handle_udevsend_msg(ssock); + if (FD_ISSET(udevsendsock, &workreadfds)) + handle_udevsend_msg(udevsendsock); if (FD_ISSET(pipefds[0], &workreadfds)) user_sighandler(); @@ -548,7 +545,7 @@ int main(int argc, char *argv[], char *envp[]) } } exit: - close(ssock); + close(udevsendsock); logging_close(); return 1; } diff --git a/udevsend.c b/udevsend.c index 7db2378b83..9f324077b3 100644 --- a/udevsend.c +++ b/udevsend.c @@ -41,6 +41,9 @@ #include "udevd.h" #include "logging.h" +/* global variables */ +static int sock = -1; + #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) @@ -66,8 +69,7 @@ static int start_daemon(void) switch (child_pid) { case 0: /* daemon */ - setsid(); - chdir("/"); + close(sock); execl(UDEVD_BIN, "udevd", NULL); dbg("exec of daemon failed"); _exit(1); @@ -119,7 +121,6 @@ int main(int argc, char *argv[], char *envp[]) int subsystem_env = 0; int bufpos = 0; int retval = 1; - int sock = -1; int started_daemon = 0; logging_init("udevsend"); @@ -137,8 +138,6 @@ int main(int argc, char *argv[], char *envp[]) goto fallback; } - set_cloexec_flag(sock, 1); - memset(&saddr, 0x00, sizeof(struct sockaddr_un)); saddr.sun_family = AF_LOCAL; /* use abstract namespace for socket path */ From af4b05d4917fdfa55eff3d8d53a830464d8162a1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Nov 2004 06:20:22 +0100 Subject: [PATCH 0976/4284] [PATCH] make the udev object available to more processing stages Remove the overwriting of main_argv[] hack and use the values from the udev object. Pass the udev object to call_foreach_file(). In the udevstart case, export SUBSYSTEM and UDEVSTART to the environment. --- dev_d.c | 20 ++++++++------------ namedev.c | 6 +++--- namedev_parse.c | 16 ++++++++-------- udev.c | 9 --------- udev.h | 2 -- udev_lib.c | 12 +++++++----- udev_lib.h | 5 ++++- udevinfo.c | 16 +++++----------- udevstart.c | 15 +++++++-------- udevtest.c | 7 ------- 10 files changed, 42 insertions(+), 66 deletions(-) diff --git a/dev_d.c b/dev_d.c index 6e35f55ca2..1108c8cee4 100644 --- a/dev_d.c +++ b/dev_d.c @@ -35,13 +35,13 @@ #define DEVD_DIR "/etc/dev.d/" #define DEVD_SUFFIX ".dev" -static int run_program(char *name) +static int run_program(const char *filename, void *data) { pid_t pid; int fd; - char *argv[3]; + struct udevice *udev = data; - dbg("running %s", name); + dbg("running %s", filename); pid = fork(); switch (pid) { @@ -55,11 +55,7 @@ static int run_program(char *name) } close(fd); - argv[0] = name; - argv[1] = main_argv[1]; - argv[2] = NULL; - - execv(name, argv); + execl(filename, filename, udev->subsystem, NULL); dbg("exec of child failed"); _exit(1); case -1: @@ -105,7 +101,7 @@ void dev_d_execute(struct udevice *udev) temp[0] = '\0'; strcpy(dirname, DEVD_DIR); strfieldcat(dirname, devname); - call_foreach_file(run_program, dirname, DEVD_SUFFIX); + call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); temp[0] = '/'; ++temp; @@ -114,12 +110,12 @@ void dev_d_execute(struct udevice *udev) strcpy(dirname, DEVD_DIR); strfieldcat(dirname, udev->name); - call_foreach_file(run_program, dirname, DEVD_SUFFIX); + call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); strcpy(dirname, DEVD_DIR); strfieldcat(dirname, udev->subsystem); - call_foreach_file(run_program, dirname, DEVD_SUFFIX); + call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); strcpy(dirname, DEVD_DIR "default"); - call_foreach_file(run_program, dirname, DEVD_SUFFIX); + call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); } diff --git a/namedev.c b/namedev.c index d63e36e18a..268a3d5be6 100644 --- a/namedev.c +++ b/namedev.c @@ -358,7 +358,7 @@ static void fix_kernel_name(struct udevice *udev) } } -static int execute_program(const char *path, char *value, int len) +static int execute_program(struct udevice *udev, const char *path, char *value, int len) { int retval; int count; @@ -391,7 +391,7 @@ static int execute_program(const char *path, char *value, int len) dbg("execute '%s' with parsed arguments", arg); } else { argv[0] = arg; - argv[1] = main_argv[1]; + argv[1] = udev->subsystem; argv[2] = NULL; dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); } @@ -655,7 +655,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas dbg("check " FIELD_PROGRAM); strfieldcpy(program, dev->program); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - if (execute_program(program, udev->program_result, NAME_SIZE) != 0) { + if (execute_program(udev, program, udev->program_result, NAME_SIZE) != 0) { dbg(FIELD_PROGRAM " returned nonzero"); goto try_parent; } else { diff --git a/namedev_parse.c b/namedev_parse.c index 22e3523f3d..73828a83b2 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -142,7 +142,7 @@ static char *get_key_attribute(char *str) return NULL; } -static int namedev_parse_rules(char *filename) +static int namedev_parse_rules(const char *filename, void *data) { char line[LINE_SIZE]; char *bufline; @@ -343,7 +343,7 @@ error: return retval; } -static int namedev_parse_permissions(char *filename) +static int namedev_parse_permissions(const char *filename, void *data) { char line[LINE_SIZE]; char *bufline; @@ -447,10 +447,10 @@ int namedev_init_rules(void) stat(udev_rules_filename, &stats); if ((stats.st_mode & S_IFMT) != S_IFDIR) - return namedev_parse_rules(udev_rules_filename); + return namedev_parse_rules(udev_rules_filename, NULL); else - return call_foreach_file(namedev_parse_rules, - udev_rules_filename, RULEFILE_SUFFIX); + return call_foreach_file(namedev_parse_rules, udev_rules_filename, + RULEFILE_SUFFIX, NULL); } int namedev_init_permissions(void) @@ -459,8 +459,8 @@ int namedev_init_permissions(void) stat(udev_permissions_filename, &stats); if ((stats.st_mode & S_IFMT) != S_IFDIR) - return namedev_parse_permissions(udev_permissions_filename); + return namedev_parse_permissions(udev_permissions_filename, NULL); else - return call_foreach_file(namedev_parse_permissions, - udev_permissions_filename, PERMFILE_SUFFIX); + return call_foreach_file(namedev_parse_permissions, udev_permissions_filename, + PERMFILE_SUFFIX, NULL); } diff --git a/udev.c b/udev.c index 480a1cdca2..300e85ceb0 100644 --- a/udev.c +++ b/udev.c @@ -39,10 +39,6 @@ #include "udevdb.h" -/* global variables */ -char **main_argv; -char **main_envp; - #ifdef LOG unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) @@ -83,12 +79,7 @@ int main(int argc, char *argv[], char *envp[]) } act_type; dbg("version %s", UDEV_VERSION); - - main_argv = argv; - main_envp = envp; - logging_init("udev"); - udev_init_config(); if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { diff --git a/udev.h b/udev.h index 3f9f2c8612..d031b9699c 100644 --- a/udev.h +++ b/udev.h @@ -73,8 +73,6 @@ extern int udev_start(void); extern int parse_get_pair(char **orig_string, char **left, char **right); extern void dev_d_execute(struct udevice *udev); -extern char **main_argv; -extern char **main_envp; extern char sysfs_path[SYSFS_PATH_MAX]; extern char udev_root[PATH_MAX]; extern char udev_db_path[PATH_MAX+NAME_MAX]; diff --git a/udev_lib.c b/udev_lib.c index 84daf9fd19..012d60b0ea 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -178,12 +178,12 @@ static int file_list_insert(char *filename, struct list_head *file_list) } /* calls function for every file found in specified directory */ -int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) +int call_foreach_file(file_fnct_t fnct, const char *dirname, + const char *suffix, void *data) { struct dirent *ent; DIR *dir; char *ext; - char file[NAME_SIZE]; struct files *loop_file; struct files *tmp_file; LIST_HEAD(file_list); @@ -217,10 +217,12 @@ int call_foreach_file(int fnct(char *f) , char *dirname, char *suffix) /* call function for every file in the list */ list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { - snprintf(file, NAME_SIZE-1, "%s/%s", dirname, loop_file->name); - file[NAME_SIZE-1] = '\0'; + char filename[NAME_SIZE]; - fnct(file); + snprintf(filename, NAME_SIZE-1, "%s/%s", dirname, loop_file->name); + filename[NAME_SIZE-1] = '\0'; + + fnct(filename, data); list_del(&loop_file->list); free(loop_file); diff --git a/udev_lib.h b/udev_lib.h index 3777a7caa3..2bc9ba82ab 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -84,6 +84,9 @@ extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); extern void no_trailing_slash(char *path); -extern int call_foreach_file(int fnct(char *f) , char *filename, char *extension); + +typedef int (*file_fnct_t)(const char *filename, void *data); +extern int call_foreach_file(file_fnct_t fnct, const char *dirname, + const char *suffix, void *data); #endif diff --git a/udevinfo.c b/udevinfo.c index 290a09e880..1148272743 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -36,10 +36,7 @@ #include "udevdb.h" -# define SYSFS_VALUE_MAX 200 - -char **main_argv; -int main_argc; +#define SYSFS_VALUE_SIZE 256 #ifdef LOG unsigned char logname[LOGNAME_SIZE]; @@ -58,7 +55,7 @@ static int print_all_attributes(const char *path) struct dlist *attributes; struct sysfs_attribute *attr; struct sysfs_directory *sysfs_dir; - char value[SYSFS_VALUE_MAX]; + char value[SYSFS_VALUE_SIZE]; int len; int retval = 0; @@ -257,7 +254,7 @@ static int print_sysfs_devices(void) return 0; } -static int process_options(void) +static int process_options(int argc, char *argv[]) { static const char short_options[] = "adn:p:q:rsVh"; int option; @@ -274,7 +271,7 @@ static int process_options(void) /* get command line options */ while (1) { - option = getopt(main_argc, main_argv, short_options); + option = getopt(argc, argv, short_options); if (option == -1) break; @@ -479,15 +476,12 @@ int main(int argc, char *argv[], char *envp[]) { int rc = 0; - main_argv = argv; - main_argc = argc; - logging_init("udevinfo"); /* initialize our configuration */ udev_init_config(); - rc = process_options(); + rc = process_options(argc, argv); logging_close(); exit(rc); diff --git a/udevstart.c b/udevstart.c index e05680aa93..0433e568d4 100644 --- a/udevstart.c +++ b/udevstart.c @@ -92,16 +92,10 @@ static int add_device(char *devpath, char *subsystem) struct udevice udev; char path[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev; - char *argv[3]; - /* fake argument vector and environment for callouts and dev.d/ */ - argv[0] = "udev"; - argv[1] = subsystem; - argv[2] = NULL; - - main_argv = argv; + /* set environment for callouts and dev.d/ */ setenv("DEVPATH", devpath, 1); - setenv("ACTION", "add", 1); + setenv("SUBSYSTEM", subsystem, 1); snprintf(path, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); class_dev = sysfs_open_class_device_path(path); @@ -291,7 +285,12 @@ static void udev_scan_class(void) int udev_start(void) { + /* set environment for callouts and dev.d/ */ + setenv("ACTION", "add", 1); + setenv("UDEVSTART", "1", 1); + udev_scan_class(); udev_scan_block(); + return 0; } diff --git a/udevtest.c b/udevtest.c index e67af0df67..14c511584b 100644 --- a/udevtest.c +++ b/udevtest.c @@ -34,10 +34,6 @@ #include "logging.h" #include "namedev.h" -/* global variables */ -char **main_argv; -char **main_envp; - #ifdef LOG unsigned char logname[LOGNAME_SIZE]; @@ -62,9 +58,6 @@ int main(int argc, char *argv[], char *envp[]) char *subsystem = ""; struct udevice udev; - main_argv = argv; - main_envp = envp; - info("version %s", UDEV_VERSION); if (argv[1] == NULL) { From 8673dcb84299fd2adba6281c5359bed4399d5b2d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Nov 2004 06:21:16 +0100 Subject: [PATCH 0977/4284] [PATCH] Make dev.d/ handling a separate processing stage Move the logic when and how to call the dev.d/ scripts into the main processing path. --- dev_d.c | 38 ++++++++++++++------------------------ namedev.c | 2 +- udev.c | 9 ++++++--- udev.h | 5 ++++- udev_add.c | 6 +++--- udev_lib.c | 2 +- udev_remove.c | 6 +++--- udevdb.c | 4 ++-- udevstart.c | 10 +++++++--- wait_for_sysfs.c | 4 ++-- 10 files changed, 43 insertions(+), 43 deletions(-) diff --git a/dev_d.c b/dev_d.c index 1108c8cee4..b3d05d9220 100644 --- a/dev_d.c +++ b/dev_d.c @@ -32,9 +32,6 @@ #include "udevdb.h" #include "logging.h" -#define DEVD_DIR "/etc/dev.d/" -#define DEVD_SUFFIX ".dev" - static int run_program(const char *filename, void *data) { pid_t pid; @@ -75,7 +72,7 @@ static int run_program(const char *filename, void *data) * subsystem/ * default/ */ -void dev_d_execute(struct udevice *udev) +void dev_d_execute(struct udevice *udev, const char *basedir, const char *suffix) { char dirname[PATH_MAX]; char devname[NAME_SIZE]; @@ -85,37 +82,30 @@ void dev_d_execute(struct udevice *udev) if (udev_dev_d == 0) return; - /* skip if udev did nothing, like unchanged netif or no "dev" file */ - if (udev->devname[0] == '\0') - return; - - /* add the node name or the netif name to the environment */ - setenv("DEVNAME", udev->devname, 1); - dbg("DEVNAME='%s'", udev->devname); - strfieldcpy(devname, udev->name); - /* Chop the device name up into pieces based on '/' */ + /* chop the device name up into pieces based on '/' */ temp = strchr(devname, '/'); while (temp != NULL) { temp[0] = '\0'; - strcpy(dirname, DEVD_DIR); - strfieldcat(dirname, devname); - call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); + snprintf(dirname, PATH_MAX, "%s/%s", basedir, devname); + dirname[PATH_MAX-1] = '\0'; + call_foreach_file(run_program, dirname, suffix, udev); temp[0] = '/'; ++temp; temp = strchr(temp, '/'); } - strcpy(dirname, DEVD_DIR); - strfieldcat(dirname, udev->name); - call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); + snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->name); + dirname[PATH_MAX-1] = '\0'; + call_foreach_file(run_program, dirname, suffix, udev); - strcpy(dirname, DEVD_DIR); - strfieldcat(dirname, udev->subsystem); - call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); + snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->subsystem); + dirname[PATH_MAX-1] = '\0'; + call_foreach_file(run_program, dirname, suffix, udev); - strcpy(dirname, DEVD_DIR "default"); - call_foreach_file(run_program, dirname, DEVD_SUFFIX, udev); + snprintf(dirname, PATH_MAX, "%s/default", basedir); + dirname[PATH_MAX-1] = '\0'; + call_foreach_file(run_program, dirname, suffix, udev); } diff --git a/namedev.c b/namedev.c index 268a3d5be6..9c94e69082 100644 --- a/namedev.c +++ b/namedev.c @@ -204,7 +204,7 @@ static int find_free_number(struct udevice *udev, const char *name) info("find_free_number gone crazy (num=%d), aborted", num); return -1; } - snprintf(filename, NAME_SIZE-1, "%s%d", name, num); + snprintf(filename, NAME_SIZE, "%s%d", name, num); filename[NAME_SIZE-1] = '\0'; } } diff --git a/udev.c b/udev.c index 300e85ceb0..bb3385e67d 100644 --- a/udev.c +++ b/udev.c @@ -165,8 +165,11 @@ int main(int argc, char *argv[], char *envp[]) /* name, create node, store in db */ retval = udev_add_device(&udev, class_dev); - /* run scripts */ - dev_d_execute(&udev); + /* run dev.d/ scripts if we created a node or changed a netif name */ + if (udev.devname[0] != '\0') { + setenv("DEVNAME", udev.devname, 1); + dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + } sysfs_close_class_device(class_dev); break; @@ -177,7 +180,7 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_remove_device(&udev); /* run scripts */ - dev_d_execute(&udev); + dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); } exit: diff --git a/udev.h b/udev.h index d031b9699c..73733ad3bb 100644 --- a/udev.h +++ b/udev.h @@ -41,6 +41,9 @@ #define LINE_SIZE 256 +#define DEVD_DIR "/etc/dev.d" +#define DEVD_SUFFIX ".dev" + struct udevice { char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; @@ -71,7 +74,7 @@ extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); extern int parse_get_pair(char **orig_string, char **left, char **right); -extern void dev_d_execute(struct udevice *udev); +extern void dev_d_execute(struct udevice *udev, const char *basedir, const char *suffix); extern char sysfs_path[SYSFS_PATH_MAX]; extern char udev_root[PATH_MAX]; diff --git a/udev_add.c b/udev_add.c index 60506b4243..c139bd38bf 100644 --- a/udev_add.c +++ b/udev_add.c @@ -129,7 +129,7 @@ static int create_node(struct udevice *udev) char *pos; int len; - snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, udev->name); + snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); filename[NAME_SIZE-1] = '\0'; switch (udev->type) { @@ -210,7 +210,7 @@ static int create_node(struct udevice *udev) char linktarget[NAME_SIZE]; strfieldcpymax(linkname, pos, len+1); - snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, linkname); + snprintf(filename, NAME_SIZE, "%s/%s", udev_root, linkname); filename[NAME_SIZE-1] = '\0'; dbg("symlink '%s' to node '%s' requested", filename, udev->name); @@ -308,7 +308,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) "remove might not work for custom names"); /* use full path to the environment */ - snprintf(udev->devname, NAME_SIZE-1, "%s/%s", udev_root, udev->name); + snprintf(udev->devname, NAME_SIZE, "%s/%s", udev_root, udev->name); udev->devname[NAME_SIZE-1] = '\0'; } else if (udev->type == 'n') { diff --git a/udev_lib.c b/udev_lib.c index 012d60b0ea..6807f817a1 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -219,7 +219,7 @@ int call_foreach_file(file_fnct_t fnct, const char *dirname, list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { char filename[NAME_SIZE]; - snprintf(filename, NAME_SIZE-1, "%s/%s", dirname, loop_file->name); + snprintf(filename, NAME_SIZE, "%s/%s", dirname, loop_file->name); filename[NAME_SIZE-1] = '\0'; fnct(filename, data); diff --git a/udev_remove.c b/udev_remove.c index d855fce52c..56834a45b9 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -112,7 +112,7 @@ static int delete_node(struct udevice *udev) int len; int num; - snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, udev->name); + snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); filename[NAME_SIZE-1] = '\0'; info("removing device node '%s'", filename); @@ -143,7 +143,7 @@ static int delete_node(struct udevice *udev) char linkname[NAME_SIZE]; strfieldcpymax(linkname, pos, len+1); - snprintf(filename, NAME_SIZE-1, "%s/%s", udev_root, linkname); + snprintf(filename, NAME_SIZE, "%s/%s", udev_root, linkname); filename[NAME_SIZE-1] = '\0'; dbg("unlinking symlink '%s'", filename); @@ -189,7 +189,7 @@ int udev_remove_device(struct udevice *udev) udevdb_delete_dev(udev); /* use full path to the environment */ - snprintf(udev->devname, NAME_SIZE-1, "%s/%s", udev_root, udev->name); + snprintf(udev->devname, NAME_SIZE, "%s/%s", udev_root, udev->name); return delete_node(udev); } diff --git a/udevdb.c b/udevdb.c index fc579a9451..38830b098e 100644 --- a/udevdb.c +++ b/udevdb.c @@ -51,7 +51,7 @@ static int get_db_filename(struct udevice *udev, char *filename, int len) pos[0] = PATH_TO_NAME_CHAR; pos = strchr(&pos[1], '/'); } - snprintf(filename, len-1, "%s%s", udev_db_path, devpath); + snprintf(filename, len, "%s%s", udev_db_path, devpath); filename[len-1] = '\0'; return 0; @@ -175,7 +175,7 @@ int udevdb_get_dev_byname(struct udevice *udev, const char *name) if (ent->d_name[0] == '.') continue; - snprintf(filename, NAME_SIZE-1, "%s/%s", udev_db_path, ent->d_name); + snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name); filename[NAME_SIZE-1] = '\0'; memset(&db_udev, 0x00, sizeof(struct udevice)); diff --git a/udevstart.c b/udevstart.c index 0433e568d4..c1d877fb37 100644 --- a/udevstart.c +++ b/udevstart.c @@ -97,7 +97,8 @@ static int add_device(char *devpath, char *subsystem) setenv("DEVPATH", devpath, 1); setenv("SUBSYSTEM", subsystem, 1); - snprintf(path, SYSFS_PATH_MAX-1, "%s%s", sysfs_path, devpath); + snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath); + path[SYSFS_PATH_MAX-1] = '\0'; class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg ("sysfs_open_class_device_path failed"); @@ -107,8 +108,11 @@ static int add_device(char *devpath, char *subsystem) udev_set_values(&udev, devpath, subsystem, "add"); udev_add_device(&udev, class_dev); - /* run scripts */ - dev_d_execute(&udev); + /* run dev.d/ scripts if we created a node or changed a netif name */ + if (udev.devname[0] != '\0') { + setenv("DEVNAME", udev.devname, 1); + dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + } sysfs_close_class_device(class_dev); diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 3b1b0cd248..42b9d383dc 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -96,7 +96,7 @@ int main(int argc, char *argv[], char *envp[]) } if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) { - snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_mnt_path, devpath); + snprintf(filename, SYSFS_PATH_MAX, "%s%s", sysfs_mnt_path, devpath); filename[SYSFS_PATH_MAX-1] = '\0'; /* skip bad events where we get no device for the class */ @@ -128,7 +128,7 @@ int main(int argc, char *argv[], char *envp[]) sysfs_close_class_device(class_dev); } else if ((strncmp(devpath, "/devices/", 9) == 0)) { - snprintf(filename, SYSFS_PATH_MAX-1, "%s%s", sysfs_mnt_path, devpath); + snprintf(filename, SYSFS_PATH_MAX, "%s%s", sysfs_mnt_path, devpath); filename[SYSFS_PATH_MAX-1] = '\0'; /* open the path we are called for */ From 02fa9ae58920b431bc37182716dd863f1c482651 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Nov 2004 06:32:19 +0100 Subject: [PATCH 0978/4284] [PATCH] rename udevdb* to udev_db* --- Makefile | 6 +++--- dev_d.c | 1 - namedev.c | 4 ++-- udev.c | 3 +-- udev_add.c | 6 +++--- udevdb.c => udev_db.c | 12 ++++++------ udevdb.h => udev_db.h | 16 ++++++++-------- udev_remove.c | 8 ++++---- udevinfo.c | 6 +++--- udevtest.c | 2 +- 10 files changed, 31 insertions(+), 33 deletions(-) rename udevdb.c => udev_db.c (94%) rename udevdb.h => udev_db.h (71%) diff --git a/Makefile b/Makefile index 50c72279f8..09b74fcde7 100644 --- a/Makefile +++ b/Makefile @@ -210,7 +210,7 @@ OBJS = udev_lib.o \ udev_add.o \ udev_remove.o \ udev_sysfs.o \ - udevdb.o \ + udev_db.o \ namedev.o \ namedev_parse.o \ dev_d.o \ @@ -220,7 +220,7 @@ HEADERS = udev.h \ udev_lib.h \ namedev.h \ udev_version.h \ - udevdb.h \ + udev_db.h \ udev_sysfs.h \ logging.h \ selinux.h \ @@ -292,7 +292,7 @@ $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) $(QUIET) $(STRIPCMD) $@ $(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udevdb.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udev_db.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h diff --git a/dev_d.c b/dev_d.c index b3d05d9220..d14c70c256 100644 --- a/dev_d.c +++ b/dev_d.c @@ -29,7 +29,6 @@ #include "udev.h" #include "udev_lib.h" -#include "udevdb.h" #include "logging.h" static int run_program(const char *filename, void *data) diff --git a/namedev.c b/namedev.c index 9c94e69082..3ab45d4ec6 100644 --- a/namedev.c +++ b/namedev.c @@ -40,7 +40,7 @@ #include "udev_version.h" #include "logging.h" #include "namedev.h" -#include "udevdb.h" +#include "udev_db.h" static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr); @@ -194,7 +194,7 @@ static int find_free_number(struct udevice *udev, const char *name) while (1) { dbg("look for existing node '%s'", filename); memset(&db_udev, 0x00, sizeof(struct udevice)); - if (udevdb_get_dev_byname(&db_udev, filename) != 0) { + if (udev_db_get_device_byname(&db_udev, filename) != 0) { dbg("free num=%d", num); return num; } diff --git a/udev.c b/udev.c index bb3385e67d..a41f222778 100644 --- a/udev.c +++ b/udev.c @@ -34,9 +34,8 @@ #include "udev_lib.h" #include "udev_sysfs.h" #include "udev_version.h" -#include "logging.h" #include "namedev.h" -#include "udevdb.h" +#include "logging.h" #ifdef LOG diff --git a/udev_add.c b/udev_add.c index c139bd38bf..4fb5ef18c0 100644 --- a/udev_add.c +++ b/udev_add.c @@ -42,7 +42,7 @@ #include "udev_version.h" #include "logging.h" #include "namedev.h" -#include "udevdb.h" +#include "udev_db.h" #include "selinux.h" @@ -303,8 +303,8 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) if (retval != 0) goto exit; - if (udevdb_add_dev(udev) != 0) - dbg("udevdb_add_dev failed, but we create the node anyway, " + if (udev_db_add_device(udev) != 0) + dbg("udev_db_add_dev failed, but we create the node anyway, " "remove might not work for custom names"); /* use full path to the environment */ diff --git a/udevdb.c b/udev_db.c similarity index 94% rename from udevdb.c rename to udev_db.c index 38830b098e..f2a890ea42 100644 --- a/udevdb.c +++ b/udev_db.c @@ -1,5 +1,5 @@ /* - * udevdb.c + * udev_db.c * * Userspace devfs * @@ -35,7 +35,7 @@ #include "udev.h" #include "udev_lib.h" #include "logging.h" -#include "udevdb.h" +#include "udev_db.h" #define PATH_TO_NAME_CHAR '@' @@ -57,7 +57,7 @@ static int get_db_filename(struct udevice *udev, char *filename, int len) return 0; } -int udevdb_add_dev(struct udevice *udev) +int udev_db_add_device(struct udevice *udev) { char filename[SYSFS_PATH_MAX]; FILE *f; @@ -135,7 +135,7 @@ static int parse_db_file(struct udevice *udev, const char *filename) return 0; } -int udevdb_get_dev(struct udevice *udev) +int udev_db_get_device(struct udevice *udev) { char filename[SYSFS_PATH_MAX]; @@ -144,7 +144,7 @@ int udevdb_get_dev(struct udevice *udev) return parse_db_file(udev, filename); } -int udevdb_delete_dev(struct udevice *udev) +int udev_db_delete_device(struct udevice *udev) { char filename[SYSFS_PATH_MAX]; @@ -154,7 +154,7 @@ int udevdb_delete_dev(struct udevice *udev) return 0; } -int udevdb_get_dev_byname(struct udevice *udev, const char *name) +int udev_db_get_device_byname(struct udevice *udev, const char *name) { struct dirent *ent; DIR *dir; diff --git a/udevdb.h b/udev_db.h similarity index 71% rename from udevdb.h rename to udev_db.h index 4f6b5de90c..141c586f24 100644 --- a/udevdb.h +++ b/udev_db.h @@ -1,5 +1,5 @@ /* - * udevdb.h + * udev_db.h * * Userspace devfs * @@ -21,14 +21,14 @@ * */ -#ifndef _UDEVDB_H_ -#define _UDEVDB_H_ +#ifndef _UDEV_DB_H_ +#define _UDEV_DB_H_ -extern int udevdb_add_dev(struct udevice *dev); -extern int udevdb_get_dev(struct udevice *dev); -extern int udevdb_delete_dev(struct udevice *dev); +extern int udev_db_add_device(struct udevice *dev); +extern int udev_db_get_device(struct udevice *dev); +extern int udev_db_delete_device(struct udevice *dev); -extern int udevdb_get_dev_byname(struct udevice *udev, const char *name); +extern int udev_db_get_device_byname(struct udevice *udev, const char *name); -#endif /* _UDEVDB_H_ */ +#endif /* _UDEV_DB_H_ */ diff --git a/udev_remove.c b/udev_remove.c index 56834a45b9..32cd785984 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -33,9 +33,9 @@ #include "udev.h" #include "udev_lib.h" #include "udev_version.h" -#include "logging.h" #include "namedev.h" -#include "udevdb.h" +#include "udev_db.h" +#include "logging.h" static int delete_path(const char *path) { @@ -175,7 +175,7 @@ int udev_remove_device(struct udevice *udev) if (udev->type != 'b' && udev->type != 'c') return 0; - retval = udevdb_get_dev(udev); + retval = udev_db_get_device(udev); if (retval) { /* fall back to kernel name */ temp = strrchr(udev->devpath, '/'); @@ -186,7 +186,7 @@ int udev_remove_device(struct udevice *udev) } dbg("remove name='%s'", udev->name); - udevdb_delete_dev(udev); + udev_db_delete_device(udev); /* use full path to the environment */ snprintf(udev->devname, NAME_SIZE, "%s/%s", udev_root, udev->name); diff --git a/udevinfo.c b/udevinfo.c index 1148272743..08c25d3a04 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -32,8 +32,8 @@ #include "udev.h" #include "udev_lib.h" #include "udev_version.h" +#include "udev_db.h" #include "logging.h" -#include "udevdb.h" #define SYSFS_VALUE_SIZE 256 @@ -355,7 +355,7 @@ static int process_options(int argc, char *argv[]) } memset(&udev, 0x00, sizeof(struct udevice)); strfieldcpy(udev.devpath, pos); - retval = udevdb_get_dev(&udev); + retval = udev_db_get_device(&udev); if (retval != 0) { printf("device not found in database\n"); goto exit; @@ -374,7 +374,7 @@ static int process_options(int argc, char *argv[]) memset(&udev, 0x00, sizeof(struct udevice)); strfieldcpy(udev.name, pos); - retval = udevdb_get_dev_byname(&udev, pos); + retval = udev_db_get_device_byname(&udev, pos); if (retval != 0) { printf("device not found in database\n"); goto exit; diff --git a/udevtest.c b/udevtest.c index 14c511584b..b9a5fea489 100644 --- a/udevtest.c +++ b/udevtest.c @@ -31,8 +31,8 @@ #include "udev.h" #include "udev_lib.h" #include "udev_version.h" -#include "logging.h" #include "namedev.h" +#include "logging.h" #ifdef LOG From 6818c51d7abeab9914eb7193968b1efa9459a853 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 12 Nov 2004 06:52:55 +0100 Subject: [PATCH 0979/4284] [PATCH] support SUBSYSTEM as a rule key This should make it easier to catch e.g all block or net devices with a single rule. --- namedev.c | 13 ++++++++++++- namedev.h | 2 ++ namedev_parse.c | 6 ++++++ test/udev-test.pl | 11 +++++++++++ udev.8.in | 4 ++++ 5 files changed, 35 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 3ab45d4ec6..8bf3c0e73e 100644 --- a/namedev.c +++ b/namedev.c @@ -604,7 +604,7 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas } } - /* check for matching kernel name*/ + /* check for matching kernel name */ if (dev->kernel[0] != '\0') { dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { @@ -615,6 +615,17 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas } } + /* check for matching subsystem */ + if (dev->subsystem[0] != '\0') { + dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' class_dev->name='%s'", dev->subsystem, class_dev->name); + if (strcmp_pattern(dev->subsystem, udev->subsystem) != 0) { + dbg(FIELD_SUBSYSTEM " is not matching"); + goto try_parent; + } else { + dbg(FIELD_SUBSYSTEM " matches"); + } + } + /* check for matching bus id */ if (dev->id[0] != '\0') { dbg("check " FIELD_ID); diff --git a/namedev.h b/namedev.h index f1e0082241..3837e864a0 100644 --- a/namedev.h +++ b/namedev.h @@ -42,6 +42,7 @@ struct sysfs_class_device; #define FIELD_PROGRAM "PROGRAM" #define FIELD_RESULT "RESULT" #define FIELD_KERNEL "KERNEL" +#define FIELD_SUBSYSTEM "SUBSYSTEM" #define FIELD_NAME "NAME" #define FIELD_SYMLINK "SYMLINK" #define FIELD_OWNER "OWNER" @@ -78,6 +79,7 @@ struct config_device { char kernel[NAME_SIZE]; char program[PROGRAM_SIZE]; char result[PROGRAM_SIZE]; + char subsystem[SUBSYSTEM_SIZE]; char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; diff --git a/namedev_parse.c b/namedev_parse.c index 73828a83b2..cc02d25555 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -258,6 +258,12 @@ static int namedev_parse_rules(const char *filename, void *data) continue; } + if (strcasecmp(temp2, FIELD_SUBSYSTEM) == 0) { + strfieldcpy(dev.subsystem, temp3); + valid = 1; + continue; + } + if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { program_given = 1; strfieldcpy(dev.program, temp3); diff --git a/test/udev-test.pl b/test/udev-test.pl index 2ba63fe83f..5f6f864df2 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1102,6 +1102,17 @@ EOF exp_name => "cdrom", conf => < "SUBSYSTEM test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + conf => < Date: Sat, 13 Nov 2004 05:21:12 +0100 Subject: [PATCH 0980/4284] [PATCH] support DRIVER as a rule key Match with a rule against a device with a specific kernel driver. --- namedev.c | 11 +++++++++++ namedev.h | 15 +++++++++------ namedev_parse.c | 6 ++++++ test/udev-test.pl | 10 ++++++++++ udev.8.in | 4 +++- 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/namedev.c b/namedev.c index 8bf3c0e73e..c5c7929ab2 100644 --- a/namedev.c +++ b/namedev.c @@ -626,6 +626,17 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas } } + /* check for matching driver */ + if (dev->driver[0] != '\0') { + dbg("check for " FIELD_DRIVER " dev->driver='%s' sysfs_device->driver_name='%s'", dev->driver, sysfs_device->driver_name); + if (strcmp_pattern(dev->driver, sysfs_device->driver_name) != 0) { + dbg(FIELD_DRIVER " is not matching"); + goto try_parent; + } else { + dbg(FIELD_DRIVER " matches"); + } + } + /* check for matching bus id */ if (dev->id[0] != '\0') { dbg("check " FIELD_ID); diff --git a/namedev.h b/namedev.h index 3837e864a0..7a98d66c24 100644 --- a/namedev.h +++ b/namedev.h @@ -28,12 +28,13 @@ struct sysfs_class_device; -#define BUS_SIZE 30 -#define FILE_SIZE 50 -#define VALUE_SIZE 100 -#define ID_SIZE 50 -#define PLACE_SIZE 50 -#define PROGRAM_SIZE 100 +#define BUS_SIZE 32 +#define FILE_SIZE 64 +#define VALUE_SIZE 128 +#define ID_SIZE 64 +#define PLACE_SIZE 64 +#define DRIVER_SIZE 64 +#define PROGRAM_SIZE 128 #define FIELD_BUS "BUS" #define FIELD_SYSFS "SYSFS" @@ -43,6 +44,7 @@ struct sysfs_class_device; #define FIELD_RESULT "RESULT" #define FIELD_KERNEL "KERNEL" #define FIELD_SUBSYSTEM "SUBSYSTEM" +#define FIELD_DRIVER "DRIVER" #define FIELD_NAME "NAME" #define FIELD_SYMLINK "SYMLINK" #define FIELD_OWNER "OWNER" @@ -80,6 +82,7 @@ struct config_device { char program[PROGRAM_SIZE]; char result[PROGRAM_SIZE]; char subsystem[SUBSYSTEM_SIZE]; + char driver[DRIVER_SIZE]; char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; diff --git a/namedev_parse.c b/namedev_parse.c index cc02d25555..ccacceceb4 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -264,6 +264,12 @@ static int namedev_parse_rules(const char *filename, void *data) continue; } + if (strcasecmp(temp2, FIELD_DRIVER) == 0) { + strfieldcpy(dev.driver, temp3); + valid = 1; + continue; + } + if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { program_given = 1; strfieldcpy(dev.program, temp3); diff --git a/test/udev-test.pl b/test/udev-test.pl index 5f6f864df2..1e06df5220 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1113,6 +1113,16 @@ EOF BUS="scsi", KERNEL="sda", NAME="should_not_match", SUBSYSTEM="vc" BUS="scsi", KERNEL="sda", NAME="node", SUBSYSTEM="block" BUS="scsi", KERNEL="sda", NAME="should_not_match2", SUBSYSTEM="vc" +EOF + }, + { + desc => "DRIVER test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + conf => < Date: Sat, 13 Nov 2004 12:36:47 +0100 Subject: [PATCH 0981/4284] [PATCH] don't wait for sysfs if the kernel(2.6.10-rc2) tells us what not to expect Newer kernels will tell us if we should wait for the "device" or the "bus" link. So don't waste the time with our lists or wait for the timeout. --- udev_lib.c | 24 ++++++++++++++++++ udev_lib.h | 2 +- udev_sysfs.c | 63 +++++++++++++++++++++++++++++------------------- udev_sysfs.h | 10 +++++--- wait_for_sysfs.c | 13 +++++----- 5 files changed, 77 insertions(+), 35 deletions(-) diff --git a/udev_lib.c b/udev_lib.c index 6807f817a1..a3fab9632d 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "udev.h" #include "logging.h" @@ -72,6 +73,29 @@ void udev_set_values(struct udevice *udev, const char* devpath, udev->type = get_device_type(devpath, subsystem); } +int kernel_release_satisfactory(int version, int patchlevel, int sublevel) +{ + static struct utsname uts; + static int kversion = 0; + static int kpatchlevel; + static int ksublevel; + + if (kversion == 0) { + if (uname(&uts) != 0) + return -1; + + if (sscanf (uts.release, "%u.%u.%u", &kversion, &kpatchlevel, &ksublevel) != 3) { + kversion = 0; + return -1; + } + } + + if (kversion >= version && kpatchlevel >= patchlevel && ksublevel >= sublevel) + return 1; + else + return 0; +} + int create_path(const char *path) { char p[NAME_SIZE]; diff --git a/udev_lib.h b/udev_lib.h index 2bc9ba82ab..80dc49cd54 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -79,12 +79,12 @@ do { \ extern char get_device_type(const char *path, const char *subsystem); extern void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem, const char* action); +extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel); extern int create_path(const char *path); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); extern void no_trailing_slash(char *path); - typedef int (*file_fnct_t)(const char *filename, void *data); extern int call_foreach_file(file_fnct_t fnct, const char *dirname, const char *suffix, void *data); diff --git a/udev_sysfs.c b/udev_sysfs.c index a11c430df0..1953dd7775 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -28,14 +28,13 @@ #include #include -#include "logging.h" +#include "libsysfs/sysfs/libsysfs.h" #include "udev_version.h" #include "udev_sysfs.h" -#include "libsysfs/sysfs/libsysfs.h" +#include "udev_lib.h" +#include "logging.h" -/* list of subsystem specific files - * NULL if there is no file to wait for - */ +/* list of subsystem specific files, NULL if there is no file to wait for */ static struct subsystem_file { char *subsystem; char *file; @@ -204,6 +203,13 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d struct class_device *classdevice; int len; + /* the kernel may tell us what to wait for */ + if (kernel_release_satisfactory(2,6,10) > 0) + if (getenv("PHYSDEVPATH") == NULL) { + dbg("the kernel says, that there is no physical device for '%s'", class_dev->path); + return 1; + } + for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) { if (strcmp(class_dev->classname, classdevice->subsystem) == 0) { /* see if no device in this class is expected to have a device-link */ @@ -229,7 +235,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d return 0; } -/* skip waiting for the bus */ +/* skip waiting for the bus of the devices device */ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) { static char *devices_without_bus[] = { @@ -250,14 +256,14 @@ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) return 0; } -/* wait for the bus and for a bus specific file to show up */ -int wait_for_bus_device(struct sysfs_device *devices_dev, +/* wait for a devices device specific file to show up */ +int wait_for_devices_device(struct sysfs_device *devices_dev, const char **error) { - static struct bus_file { + static struct device_file { char *bus; char *file; - } bus_files[] = { + } device_files[] = { { .bus = "scsi", .file = "vendor" }, { .bus = "usb", .file = "idVendor" }, { .bus = "usb", .file = "iInterface" }, @@ -272,9 +278,16 @@ int wait_for_bus_device(struct sysfs_device *devices_dev, { .bus = "ieee1394", .file = "address" }, { NULL, NULL } }; - struct bus_file *busfile; + struct device_file *devicefile; int loop; + /* the kernel may tell us what to wait for */ + if (kernel_release_satisfactory(2,6,10) > 0) + if (getenv("PHYSDEVBUS") == NULL) { + dbg("the kernel says, that there is no bus for '%s'", devices_dev->path); + return 0; + } + /* wait for the bus device link to the devices device */ loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { @@ -291,22 +304,22 @@ int wait_for_bus_device(struct sysfs_device *devices_dev, } dbg("bus device link found for bus '%s'", devices_dev->bus); - /* wait for a bus specific file to show up */ + /* wait for a bus device specific file to show up */ loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; while (--loop) { int found_bus_type = 0; - for (busfile = bus_files; busfile->bus != NULL; busfile++) { - if (strcmp(devices_dev->bus, busfile->bus) == 0) { + for (devicefile = device_files; devicefile->bus != NULL; devicefile++) { + if (strcmp(devices_dev->bus, devicefile->bus) == 0) { char filename[SYSFS_PATH_MAX]; struct stat stats; found_bus_type = 1; - snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, busfile->file); - dbg("looking at bus '%s' for specific file '%s'", devices_dev->bus, filename); + snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, devicefile->file); + dbg("looking at bus '%s' device for specific file '%s'", devices_dev->bus, filename); if (stat(filename, &stats) == 0) { - dbg("bus '%s' specific file '%s' found", devices_dev->bus, busfile->file); + dbg("bus '%s' device specific file '%s' found", devices_dev->bus, devicefile->file); return 0; } } @@ -321,14 +334,14 @@ int wait_for_bus_device(struct sysfs_device *devices_dev, usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } - dbg("error: getting bus '%s' specific file '%s'", devices_dev->bus, busfile->file); + dbg("error: getting '%s' device specific file '%s'", devices_dev->bus, devicefile->file); if (error) - *error = "bus specific file unavailable"; + *error = "bus device specific file unavailable"; return -1; } -struct sysfs_class_device *open_class_device_wait(const char *path) +struct sysfs_class_device *wait_class_device_open(const char *path) { struct sysfs_class_device *class_dev; int loop; @@ -358,7 +371,7 @@ int wait_for_class_device(struct sysfs_class_device *class_dev, /* skip devices without devices-link */ if (class_device_expect_no_device_link(class_dev)) { dbg("no device symlink expected for '%s', ", class_dev->name); - return -ENODEV; + return 0; } /* the symlink may be on the parent device */ @@ -388,16 +401,16 @@ int wait_for_class_device(struct sysfs_class_device *class_dev, } dbg("device symlink found pointing to '%s'", devices_dev->path); - /* wait for the bus value */ + /* wait for the devices device */ if (class_device_expect_no_bus(class_dev)) { dbg("no bus device expected for '%s', ", class_dev->classname); return 0; - } else { - return wait_for_bus_device(devices_dev, error); } + + return wait_for_devices_device(devices_dev, error); } -struct sysfs_device *open_devices_device_wait(const char *path) +struct sysfs_device *wait_devices_device_open(const char *path) { struct sysfs_device *devices_dev; int loop; diff --git a/udev_sysfs.h b/udev_sysfs.h index 922db1be79..98ff53e11a 100644 --- a/udev_sysfs.h +++ b/udev_sysfs.h @@ -28,9 +28,13 @@ #define WAIT_LOOP_PER_SECOND 20 extern int subsystem_expect_no_dev(const char *subsystem); -extern int wait_for_bus_device(struct sysfs_device *devices_dev, const char **error); + +/* /sys/class /sys/block devices */ +extern struct sysfs_class_device *wait_class_device_open(const char *path); extern int wait_for_class_device(struct sysfs_class_device *class_dev, const char **error); -extern struct sysfs_class_device *open_class_device_wait(const char *path); -extern struct sysfs_device *open_devices_device_wait(const char *path); + +/* /sys/devices devices */ +extern struct sysfs_device *wait_devices_device_open(const char *path); +extern int wait_for_devices_device(struct sysfs_device *devices_dev, const char **error); #endif /* _UDEV_SYSFS_H_ */ diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c index 42b9d383dc..84a25adb97 100644 --- a/wait_for_sysfs.c +++ b/wait_for_sysfs.c @@ -32,10 +32,11 @@ #include #include -#include "logging.h" +#include "libsysfs/sysfs/libsysfs.h" +#include "udev_lib.h" #include "udev_version.h" #include "udev_sysfs.h" -#include "libsysfs/sysfs/libsysfs.h" +#include "logging.h" #ifdef LOG unsigned char logname[LOGNAME_SIZE]; @@ -106,7 +107,7 @@ int main(int argc, char *argv[], char *envp[]) } /* open the class device we are called for */ - class_dev = open_class_device_wait(filename); + class_dev = wait_class_device_open(filename); if (!class_dev) { dbg("error: class device unavailable (probably remove has beaten us)"); goto exit; @@ -132,15 +133,15 @@ int main(int argc, char *argv[], char *envp[]) filename[SYSFS_PATH_MAX-1] = '\0'; /* open the path we are called for */ - devices_dev = open_devices_device_wait(filename); + devices_dev = wait_devices_device_open(filename); if (!devices_dev) { dbg("error: devices device unavailable (probably remove has beaten us)"); goto exit; } dbg("devices device opened '%s'", filename); - /* wait for the bus value */ - wait_for_bus_device(devices_dev, &error); + /* wait for the devices device */ + wait_for_devices_device(devices_dev, &error); sysfs_close_device(devices_dev); From d4a32aa2e4804de9189574213749616dda57faa7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 13 Nov 2004 12:50:44 +0100 Subject: [PATCH 0982/4284] [PATCH] remove historical SYSFS_attr="value" format This is long ago replaced by the unified key attribute format SYSFS{attr}="value". --- namedev_parse.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index ccacceceb4..4afa85cfa9 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -113,7 +113,7 @@ void dump_perm_dev_list(void) dump_perm_dev(dev); } -/* extract possible KEY{attr} or KEY_attr */ +/* extract possible KEY{attr} */ static char *get_key_attribute(char *str) { char *pos; @@ -132,13 +132,6 @@ static char *get_key_attribute(char *str) return attr; } - attr = strchr(str, '_'); - if (attr != NULL) { - attr++; - dbg("attribute='%s'", attr); - return attr; - } - return NULL; } From 7efa217db0db946e68e6274e2b9cbe0a973ec47a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 13 Nov 2004 14:43:24 +0100 Subject: [PATCH 0983/4284] [PATCH] add NAME{ignore_remove} attribute Some broken ide drivers are generating high event traffic, with add/remove events. With this attribute, it can be specified, that the node is always available. It may be used in conjunction with the new DRIVER= match to catch specific kernel device drivers. --- namedev.c | 1 + namedev.h | 2 ++ namedev_parse.c | 8 +++++++- test/udev-test.pl | 25 +++++++++++++++++++++++-- udev.8.in | 7 +++++++ udev.h | 1 + udev_db.c | 18 ++++++++++++++++-- udev_remove.c | 5 +++++ 8 files changed, 62 insertions(+), 5 deletions(-) diff --git a/namedev.c b/namedev.c index c5c7929ab2..69669709df 100644 --- a/namedev.c +++ b/namedev.c @@ -807,6 +807,7 @@ found: goto done; udev->partitions = dev->partitions; + udev->ignore_remove = dev->ignore_remove; /* get permissions given in rule */ set_empty_perms(udev, dev->mode, diff --git a/namedev.h b/namedev.h index 7a98d66c24..8e552c8568 100644 --- a/namedev.h +++ b/namedev.h @@ -52,6 +52,7 @@ struct sysfs_class_device; #define FIELD_MODE "MODE" #define ATTR_PARTITIONS "all_partitions" +#define ATTR_IGNORE_REMOVE "ignore_remove" #define PARTITIONS_COUNT 15 #define MAX_SYSFS_PAIRS 5 @@ -90,6 +91,7 @@ struct config_device { char group[GROUP_SIZE]; unsigned int mode; int partitions; + int ignore_remove; char config_file[NAME_SIZE]; int config_line; }; diff --git a/namedev_parse.c b/namedev_parse.c index 4afa85cfa9..cb1760fd57 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -278,10 +278,16 @@ static int namedev_parse_rules(const char *filename, void *data) if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) { attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1); - if (attr != NULL && strcasecmp(attr, ATTR_PARTITIONS) == 0) { + if (attr != NULL) { + if (strstr(attr, ATTR_PARTITIONS) != NULL) { dbg_parse("creation of partition nodes requested"); dev.partitions = PARTITIONS_COUNT; } + if (strstr(attr, ATTR_IGNORE_REMOVE) != NULL) { + dbg_parse("remove event should be ignored"); + dev.ignore_remove = 1; + } + } strfieldcpy(dev.name, temp3); valid = 1; continue; diff --git a/test/udev-test.pl b/test/udev-test.pl index 1e06df5220..d584579584 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1105,7 +1105,28 @@ KERNEL="sda", NAME="cdrom%e" EOF }, { - desc => "SUBSYSTEM test", + desc => "ignore remove event test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_error => "yes", + conf => < "ignore remove event test (with all partitions)", + subsys => "block", + devpath => "/block/sda", + exp_name => "node14", + exp_error => "yes", + option => "clear", + conf => < "SUBSYSTEM match test", subsys => "block", devpath => "/block/sda", exp_name => "node", @@ -1116,7 +1137,7 @@ BUS="scsi", KERNEL="sda", NAME="should_not_match2", SUBSYSTEM="vc" EOF }, { - desc => "DRIVER test", + desc => "DRIVER match test", subsys => "block", devpath => "/block/sda", exp_name => "node", diff --git a/udev.8.in b/udev.8.in index b5296b472d..728ddb1a45 100644 --- a/udev.8.in +++ b/udev.8.in @@ -216,6 +216,13 @@ If given with the attribute .BR NAME{ all_partitions } it will create all 15 partitions of a blockdevice. This may be useful for removable media devices. +.br +If given with the attribute +.BR NAME{ ignore_remove } +it will will ignore any later remove event for this device. +This may be useful as a workaround for broken device drivers. +.sp +Multiple attributes may be separated by comma. .TP .B SYMLINK The name of a symlink targeting the node. Multiple symlinks may be diff --git a/udev.h b/udev.h index 73733ad3bb..d9a775ae91 100644 --- a/udev.h +++ b/udev.h @@ -57,6 +57,7 @@ struct udevice { mode_t mode; char symlink[NAME_SIZE]; int partitions; + int ignore_remove; int config_line; char config_file[NAME_SIZE]; long config_uptime; diff --git a/udev_db.c b/udev_db.c index f2a890ea42..e07e72b858 100644 --- a/udev_db.c +++ b/udev_db.c @@ -79,7 +79,8 @@ int udev_db_add_device(struct udevice *udev) fprintf(f, "P:%s\n", udev->devpath); fprintf(f, "N:%s\n", udev->name); fprintf(f, "S:%s\n", udev->symlink); - fprintf(f, "A:%d\n", udev->partitions); + fprintf(f, "A:%u\n", udev->partitions); + fprintf(f, "R:%u\n", udev->ignore_remove); fclose(f); @@ -111,21 +112,34 @@ static int parse_db_file(struct udevice *udev, const char *filename) if (count > DEVPATH_SIZE) count = DEVPATH_SIZE-1; strncpy(udev->devpath, &bufline[2], count-2); + udev->devpath[count-2] = '\0'; break; case 'N': if (count > NAME_SIZE) count = NAME_SIZE-1; strncpy(udev->name, &bufline[2], count-2); + udev->name[count-2] = '\0'; break; case 'S': if (count > NAME_SIZE) count = NAME_SIZE-1; strncpy(udev->symlink, &bufline[2], count-2); + udev->symlink[count-2] = '\0'; break; case 'A': - strfieldcpy(line, &bufline[2]); + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(line, &bufline[2], count-2); + line[count-2] = '\0'; udev->partitions = atoi(line); break; + case 'R': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(line, &bufline[2], count-2); + line[count-2] = '\0'; + udev->ignore_remove = atoi(line); + break; } } diff --git a/udev_remove.c b/udev_remove.c index 32cd785984..8887125dd8 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -185,6 +185,11 @@ int udev_remove_device(struct udevice *udev) dbg("'%s' not found in database, falling back on default name", udev->name); } + if (udev->ignore_remove) { + dbg("remove event for '%s' requested to be ignored by rule", udev->name); + return 0; + } + dbg("remove name='%s'", udev->name); udev_db_delete_device(udev); From 7225821d631f37f3c2b11e1d62aeb516b2acec30 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 13 Nov 2004 14:51:10 +0100 Subject: [PATCH 0984/4284] [PATCH] disable logging for udevstart The slow logging facilites on some systems are a reason for the reported slowness of udevstart. On one of my boxes udevstart is down from 9 second to 0.3 seconds. --- Makefile | 4 ++-- udev.c | 1 + udevstart.c => udev_start.c | 0 3 files changed, 3 insertions(+), 2 deletions(-) rename udevstart.c => udev_start.c (100%) diff --git a/Makefile b/Makefile index 09b74fcde7..efbb74355a 100644 --- a/Makefile +++ b/Makefile @@ -283,8 +283,8 @@ $(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(WAIT).o: $(GEN_HEADERS) $(HOST_PROGS) -$(ROOT): $(LIBC) $(ROOT).o $(STARTER).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udevstart.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(ROOT): $(LIBC) $(ROOT).o udev_start.o $(OBJS) $(HEADERS) $(GEN_MANPAGES) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udev_start.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) diff --git a/udev.c b/udev.c index a41f222778..78fe82cfbb 100644 --- a/udev.c +++ b/udev.c @@ -143,6 +143,7 @@ int main(int argc, char *argv[], char *envp[]) switch(act_type) { case UDEVSTART: dbg("udevstart"); + udev_log = 0; namedev_init(); retval = udev_start(); break; diff --git a/udevstart.c b/udev_start.c similarity index 100% rename from udevstart.c rename to udev_start.c From e4ad54a302773d8b1c197e32fe67541f1b60518e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 13 Nov 2004 05:33:25 +0100 Subject: [PATCH 0985/4284] [PATCH] change key names in udevinfo sysfs walk to match the kernel --- udevinfo.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index 08c25d3a04..097c91c21b 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -209,7 +209,7 @@ static int print_sysfs_devices(void) struct dlist *class_devices; struct sysfs_class_device *class_dev; struct sysfs_device *phys_dev; - struct sysfs_driver *driver; + unsigned int major, minor; cls = sysfs_open_class(class); if (!cls) @@ -228,23 +228,19 @@ static int print_sysfs_devices(void) attr = sysfs_get_classdev_attr(class_dev, "dev"); if (attr) { - char *pos = &(attr->value[strlen(attr->value)-1]); - - if (pos[0] == '\n') - pos[0] = '\0'; - - printf("DEVMAJORMINOR '%s'\n", attr->value); + sscanf(attr->value, "%u:%u", &major, &minor); + printf("MAJOR %u\n", minor); + printf("MINOR %u\n", major); } - driver = sysfs_get_classdev_driver(class_dev); - if (driver) - printf("DEVDRIVER '%s'\n", driver->name); - phys_dev = sysfs_get_classdev_device(class_dev); if (phys_dev) { printf("PHYSDEVPATH '%s'\n", phys_dev->path); if (phys_dev->bus[0] != '\0') printf("PHYSDEVBUS '%s'\n", phys_dev->bus); + + if (phys_dev->driver_name[0] != '\0') + printf("PHYSDEVDRIVER '%s'\n", phys_dev->driver_name); } } sysfs_close_class(cls); From 90e84c81486d757f1eec263565e605c1df500e7c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Nov 2004 03:41:38 +0100 Subject: [PATCH 0986/4284] [PATCH] let klibc add the trailing newline to syslog conditionally We get an empty line after every debug print from libsysfs, so don't add a second if we already have one. --- klibc/klibc/syslog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c index 592992ba6b..e9d84d9ddc 100644 --- a/klibc/klibc/syslog.c +++ b/klibc/klibc/syslog.c @@ -60,7 +60,8 @@ void vsyslog(int prio, const char *format, va_list ap) len += vsnprintf(buf+len, BUFLEN-len, format, ap); if ( len > BUFLEN-1 ) len = BUFLEN-1; - buf[len++] = '\n'; + if (buf[len-1] != '\n') + buf[len++] = '\n'; fd = __syslog_fd; if ( fd == -1 ) From 4bee99940511a0e5ea5a3352ba2e8c0c97580e25 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Nov 2004 03:43:43 +0100 Subject: [PATCH 0987/4284] [PATCH] add ippp and bcrypt to the exception lists of wait_for_sysfs --- udev_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 1953dd7775..fae3996406 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -145,6 +145,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "block", .device = "scd" }, { .subsystem = "block", .device = "ubd" }, { .subsystem = "block", .device = "dm-" }, + { .subsystem = "block", .device = "bcrypt" }, { .subsystem = "input", .device = "event" }, { .subsystem = "input", .device = "mice" }, { .subsystem = "input", .device = "mouse" }, @@ -168,6 +169,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "pan" }, { .subsystem = "net", .device = "bnep" }, { .subsystem = "net", .device = "vmnet" }, + { .subsystem = "net", .device = "ippp" }, { .subsystem = "ppp", .device = NULL }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, From 80513ea38f66855fe9232d6eab3ab9469c379cad Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Nov 2004 03:49:13 +0100 Subject: [PATCH 0988/4284] [PATCH] prevent udevd crash if DEVPATH is not set Just move the event straight to the exec list and don't try to compare a NULL pointer. --- udevd.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/udevd.c b/udevd.c index 43f3f0324b..dd505d03d9 100644 --- a/udevd.c +++ b/udevd.c @@ -153,9 +153,14 @@ static void udev_run(struct hotplug_msg *msg) static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) { struct hotplug_msg *loop_msg; - list_for_each_entry(loop_msg, &running_list, list) - if (strncmp(loop_msg->devpath, msg->devpath, sizeof(loop_msg->devpath)) == 0) + list_for_each_entry(loop_msg, &running_list, list) { + if (loop_msg->devpath == NULL || msg->devpath == NULL) + continue; + + if (strcmp(loop_msg->devpath, msg->devpath) == 0) return loop_msg; + } + return NULL; } From fc2aa296137017ad748ef2a7fa08bf9de1336272 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Nov 2004 03:50:05 +0100 Subject: [PATCH 0989/4284] [PATCH] remove get_device_type and merge that into udev_set_values() --- udev_lib.c | 52 +++++++++++++++++++++------------------------------- udev_lib.h | 1 - udevinfo.c | 16 +++------------- 3 files changed, 24 insertions(+), 45 deletions(-) diff --git a/udev_lib.c b/udev_lib.c index a3fab9632d..d745c9bd86 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -36,41 +36,31 @@ #include "list.h" -#define BLOCK_PATH "/block/" -#define CLASS_PATH "/class/" -#define NET_PATH "/class/net/" - -char get_device_type(const char *path, const char *subsystem) -{ - if (strcmp(subsystem, "block") == 0) - return 'b'; - - if (strcmp(subsystem, "net") == 0) - return 'n'; - - if (strncmp(path, BLOCK_PATH, strlen(BLOCK_PATH)) == 0 && - strlen(path) > strlen(BLOCK_PATH)) - return 'b'; - - if (strncmp(path, NET_PATH, strlen(NET_PATH)) == 0 && - strlen(path) > strlen(NET_PATH)) - return 'n'; - - if (strncmp(path, CLASS_PATH, strlen(CLASS_PATH)) == 0 && - strlen(path) > strlen(CLASS_PATH)) - return 'c'; - - return '\0'; -} - void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem, const char* action) { memset(udev, 0x00, sizeof(struct udevice)); - strfieldcpy(udev->devpath, devpath); - strfieldcpy(udev->subsystem, subsystem); - strfieldcpy(udev->action, action); - udev->type = get_device_type(devpath, subsystem); + if (devpath) + strfieldcpy(udev->devpath, devpath); + if (subsystem) + strfieldcpy(udev->subsystem, subsystem); + if (action) + strfieldcpy(udev->action, action); + + if (strcmp(udev->subsystem, "block") == 0) + udev->type = 'b'; + + if (strcmp(udev->subsystem, "net") == 0) + udev->type = 'n'; + + if (strncmp(udev->devpath, "/block/", 7) == 0) + udev->type = 'b'; + + if (strncmp(udev->devpath, "/class/net/", 11) == 0) + udev->type = 'n'; + + if (strncmp(udev->devpath, "/class/", 7) == 0) + udev->type = 'c'; } int kernel_release_satisfactory(int version, int patchlevel, int sublevel) diff --git a/udev_lib.h b/udev_lib.h index 80dc49cd54..b9b0fda678 100644 --- a/udev_lib.h +++ b/udev_lib.h @@ -76,7 +76,6 @@ do { \ # define asmlinkage /* nothing */ #endif -extern char get_device_type(const char *path, const char *subsystem); extern void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem, const char* action); extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel); diff --git a/udevinfo.c b/udevinfo.c index 097c91c21b..013068541e 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -125,10 +125,6 @@ static int print_device_chain(const char *path) struct sysfs_device *sysfs_dev; struct sysfs_device *sysfs_dev_parent; int retval = 0; - char type; - - type = get_device_type(path, ""); - dbg("device type is %c", type); /* get the class dev */ class_dev = sysfs_open_class_device_path(path); @@ -144,16 +140,10 @@ static int print_device_chain(const char *path) "to match the device for which the node will be created.\n" "\n"); - if (type == 'b' || type =='c') { - /* read the 'dev' file for major/minor*/ - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr == NULL) { - printf("couldn't get the \"dev\" file\n"); - retval = -1; - goto exit; - } + /* look for the 'dev' file */ + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) printf("device '%s' has major:minor %s", class_dev->path, attr->value); - } /* open sysfs class device directory and print all attributes */ printf(" looking at class device '%s':\n", class_dev->path); From c02ae2fe332e871b3132bfbc20ba8db359a71657 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Nov 2004 04:03:52 +0100 Subject: [PATCH 0990/4284] [PATCH] Don't try to print major/minor for devices without a dev file. --- udevinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevinfo.c b/udevinfo.c index 013068541e..901990ede6 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -142,7 +142,7 @@ static int print_device_chain(const char *path) /* look for the 'dev' file */ attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr == NULL) + if (attr != NULL) printf("device '%s' has major:minor %s", class_dev->path, attr->value); /* open sysfs class device directory and print all attributes */ From 162c0ee8b95228676a83aaaaf5adf64ba56b0be8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 18 Nov 2004 19:39:05 -0800 Subject: [PATCH 0991/4284] [PATCH] 046 release --- ChangeLog | 32 ++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5088273e62..6319845aa7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +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 ============================================ diff --git a/Makefile b/Makefile index efbb74355a..1819dbecbb 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart WAIT = wait_for_sysfs -VERSION = 045 +VERSION = 046 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index edb033e864..05cee524c0 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 045 +Version: 046 Release: 1 License: GPL Group: Utilities/System From 8825e9e71b3eaac8ce90f4fede2bb07a7ea7a969 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 19 Nov 2004 22:42:19 -0800 Subject: [PATCH 0992/4284] [PATCH] fix network device naming bug --- udev_lib.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/udev_lib.c b/udev_lib.c index d745c9bd86..f388d23f3e 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -40,6 +40,7 @@ void udev_set_values(struct udevice *udev, const char* devpath, const char *subsystem, const char* action) { memset(udev, 0x00, sizeof(struct udevice)); + if (devpath) strfieldcpy(udev->devpath, devpath); if (subsystem) @@ -49,17 +50,13 @@ void udev_set_values(struct udevice *udev, const char* devpath, if (strcmp(udev->subsystem, "block") == 0) udev->type = 'b'; - - if (strcmp(udev->subsystem, "net") == 0) + else if (strcmp(udev->subsystem, "net") == 0) udev->type = 'n'; - - if (strncmp(udev->devpath, "/block/", 7) == 0) + else if (strncmp(udev->devpath, "/block/", 7) == 0) udev->type = 'b'; - - if (strncmp(udev->devpath, "/class/net/", 11) == 0) + else if (strncmp(udev->devpath, "/class/net/", 11) == 0) udev->type = 'n'; - - if (strncmp(udev->devpath, "/class/", 7) == 0) + else if (strncmp(udev->devpath, "/class/", 7) == 0) udev->type = 'c'; } From ec9cc0127d3b50885723dd4f54d4851e7160ec22 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 03:28:41 +0100 Subject: [PATCH 0993/4284] [PATCH] udevd exit path cleanup --- udevd.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/udevd.c b/udevd.c index dd505d03d9..3ad8c47f22 100644 --- a/udevd.c +++ b/udevd.c @@ -419,7 +419,7 @@ int main(int argc, char *argv[], char *envp[]) if (getuid() != 0) { dbg("need to be root, exit"); - _exit(1); + goto exit; } /* make sure we don't lock any path */ @@ -430,7 +430,7 @@ int main(int argc, char *argv[], char *envp[]) fd = open( "/dev/null", O_RDWR ); if ( fd < 0 ) { dbg("error opening /dev/null %s", strerror(errno)); - exit(1); + goto exit; } dup2(fd, 0); dup2(fd, 1); @@ -445,29 +445,29 @@ int main(int argc, char *argv[], char *envp[]) retval = pipe(pipefds); if (retval < 0) { dbg("error getting pipes: %s", strerror(errno)); - exit(1); + goto exit; } retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); if (retval < 0) { dbg("error fcntl on read pipe: %s", strerror(errno)); - exit(1); + goto exit; } retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); if (retval < 0) { dbg("error fcntl on read pipe: %s", strerror(errno)); - exit(1); + goto exit; } retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); if (retval < 0) { dbg("error fcntl on write pipe: %s", strerror(errno)); - exit(1); + goto exit; } retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC); if (retval < 0) { dbg("error fcntl on write pipe: %s", strerror(errno)); - exit(1); + goto exit; } /* set signal handlers */ @@ -488,13 +488,14 @@ int main(int argc, char *argv[], char *envp[]) udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (udevsendsock == -1) { dbg("error getting socket, exit"); - exit(1); + goto exit; } /* the bind takes care of ensuring only one copy running */ retval = bind(udevsendsock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { dbg("bind failed, exit"); + close(udevsendsock); goto exit; } @@ -549,8 +550,8 @@ int main(int argc, char *argv[], char *envp[]) exec_queue_manager(); } } + exit: - close(udevsendsock); logging_close(); return 1; } From f602ccf0723f116c2c3a77e057a0540027aa38b8 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 03:30:13 +0100 Subject: [PATCH 0994/4284] [PATCH] close connection to syslog in forked udevd child --- udevd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udevd.c b/udevd.c index 3ad8c47f22..2337493f1e 100644 --- a/udevd.c +++ b/udevd.c @@ -131,6 +131,7 @@ static void udev_run(struct hotplug_msg *msg) case 0: /* child */ close(udevsendsock); + logging_close(); execle(udev_bin, "udev", msg->subsystem, NULL, msg->envp); dbg("exec of child failed"); _exit(1); From 8474ff500fa5671185f6203f5f20162304a5c7df Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 03:36:32 +0100 Subject: [PATCH 0995/4284] [PATCH] add a bunch of busses to the list of what to wait for --- udev_sysfs.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index fae3996406..e2c706c6f5 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -278,6 +278,28 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "ieee1394", .file = "node_count" }, { .bus = "ieee1394", .file = "nodeid" }, { .bus = "ieee1394", .file = "address" }, + { .bus = "bttv-sub", .file = "detach_state" }, + { .bus = "pnp", .file = "detach_state" }, + { .bus = "eisa", .file = "detach_state" }, + { .bus = "pseudo", .file = "detach_state" }, + { .bus = "mmc", .file = "detach_state" }, + { .bus = "macio", .file = "detach_state" }, + { .bus = "of_platform", .file = "detach_state" }, + { .bus = "vio", .file = "detach_state" }, + { .bus = "ecard", .file = "detach_state" }, + { .bus = "sa1111-rab", .file = "detach_state" }, + { .bus = "amba", .file = "detach_state" }, + { .bus = "locomo-bus", .file = "detach_state" }, + { .bus = "logicmodule", .file = "detach_state" }, + { .bus = "parisc", .file = "detach_state" }, + { .bus = "ocp", .file = "detach_state" }, + { .bus = "dio", .file = "detach_state" }, + { .bus = "MCA", .file = "detach_state" }, + { .bus = "wl", .file = "detach_state" }, + { .bus = "ccwgroup", .file = "detach_state" }, + { .bus = "css", .file = "detach_state" }, + { .bus = "ccw", .file = "detach_state" }, + { .bus = "iucv", .file = "detach_state" }, { NULL, NULL } }; struct device_file *devicefile; From a4f0cc793a9a2053f9733c5ebd1445c9a2678445 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 03:43:37 +0100 Subject: [PATCH 0996/4284] [PATCH] Patch from Alex Riesen > I just put const's at some places. It cut down data segments, but > increased code size. > Overall still smaller: > > -rwxr-xr-x 1 user users 50420 Nov 19 10:53 ../udev-046/udev > -rwxr-xr-x 1 user users 49556 Nov 19 10:53 udev > text data bss dec hex filename > 47245 968 22480 70693 11425 ../udev-046/udev > 48089 104 22064 70257 11271 udev > > Also, the instance of utsname in udev_lib.c is used only once. --- udev_lib.c | 2 +- udev_sysfs.c | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/udev_lib.c b/udev_lib.c index f388d23f3e..86a526f7e8 100644 --- a/udev_lib.c +++ b/udev_lib.c @@ -62,12 +62,12 @@ void udev_set_values(struct udevice *udev, const char* devpath, int kernel_release_satisfactory(int version, int patchlevel, int sublevel) { - static struct utsname uts; static int kversion = 0; static int kpatchlevel; static int ksublevel; if (kversion == 0) { + struct utsname uts; if (uname(&uts) != 0) return -1; diff --git a/udev_sysfs.c b/udev_sysfs.c index e2c706c6f5..a25223ef46 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -35,9 +35,9 @@ #include "logging.h" /* list of subsystem specific files, NULL if there is no file to wait for */ -static struct subsystem_file { - char *subsystem; - char *file; +static const struct subsystem_file { + const char *subsystem; + const char *file; } subsystem_files[] = { { .subsystem = "net", .file = "ifindex" }, { .subsystem = "scsi_host", .file = "unique_id" }, @@ -56,7 +56,7 @@ static struct subsystem_file { int subsystem_expect_no_dev(const char *subsystem) { - struct subsystem_file *file; + const struct subsystem_file *file; for (file = subsystem_files; file->subsystem != NULL; file++) if (strcmp(subsystem, file->subsystem) == 0) @@ -66,9 +66,9 @@ int subsystem_expect_no_dev(const char *subsystem) } /* get subsystem specific files, returns "dev" if no other found */ -static char *get_subsystem_specific_file(const char *subsystem) +static const char *get_subsystem_specific_file(const char *subsystem) { - struct subsystem_file *file; + const struct subsystem_file *file; /* look if we want to look for another file instead of "dev" */ for (file = subsystem_files; file->subsystem != NULL; file++) @@ -123,9 +123,9 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { /* list of devices without a "device" symlink to the physical device * if device is set to NULL, no devices in that subsystem has a link */ - static struct class_device { - char *subsystem; - char *device; + static const struct class_device { + const char *subsystem; + const char *device; } class_device[] = { { .subsystem = "block", .device = "double" }, { .subsystem = "block", .device = "nb" }, @@ -202,7 +202,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "capi", .device = NULL }, { NULL, NULL } }; - struct class_device *classdevice; + const struct class_device *classdevice; int len; /* the kernel may tell us what to wait for */ @@ -240,13 +240,13 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d /* skip waiting for the bus of the devices device */ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) { - static char *devices_without_bus[] = { + static const char *devices_without_bus[] = { "scsi_host", "i2c-adapter", "i2c-dev", NULL }; - char **device; + const char **device; for (device = devices_without_bus; *device != NULL; device++) { int len = strlen(*device); @@ -262,9 +262,9 @@ static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) int wait_for_devices_device(struct sysfs_device *devices_dev, const char **error) { - static struct device_file { - char *bus; - char *file; + static const struct device_file { + const char *bus; + const char *file; } device_files[] = { { .bus = "scsi", .file = "vendor" }, { .bus = "usb", .file = "idVendor" }, @@ -302,7 +302,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "iucv", .file = "detach_state" }, { NULL, NULL } }; - struct device_file *devicefile; + const struct device_file *devicefile; int loop; /* the kernel may tell us what to wait for */ From ff5761c9727a5df9ac348fb9f8feed2469d6861f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Mon, 22 Nov 2004 19:23:00 -0800 Subject: [PATCH 0997/4284] [PATCH] fix parallel build error --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1819dbecbb..de08f7cf52 100644 --- a/Makefile +++ b/Makefile @@ -209,6 +209,7 @@ OBJS = udev_lib.o \ udev_config.o \ udev_add.o \ udev_remove.o \ + udev_start.o \ udev_sysfs.o \ udev_db.o \ namedev.o \ @@ -283,8 +284,8 @@ $(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(WAIT).o: $(GEN_HEADERS) $(HOST_PROGS) -$(ROOT): $(LIBC) $(ROOT).o udev_start.o $(OBJS) $(HEADERS) $(GEN_MANPAGES) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o udev_start.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(ROOT): $(LIBC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) From 7a0643a93f53cd5e7a05ae3d0c384e9e3160a94f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 03:55:24 +0100 Subject: [PATCH 0998/4284] [PATCH] add support for /devices-devices without any file to wait for --- udev_sysfs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index a25223ef46..7293407be1 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -267,6 +267,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, const char *file; } device_files[] = { { .bus = "scsi", .file = "vendor" }, + { .bus = "usb", .file = NULL }, { .bus = "usb", .file = "idVendor" }, { .bus = "usb", .file = "iInterface" }, { .bus = "usb", .file = "bNumEndpoints" }, @@ -278,7 +279,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "ieee1394", .file = "node_count" }, { .bus = "ieee1394", .file = "nodeid" }, { .bus = "ieee1394", .file = "address" }, - { .bus = "bttv-sub", .file = "detach_state" }, + { .bus = "bttv-sub", .file = NULL }, { .bus = "pnp", .file = "detach_state" }, { .bus = "eisa", .file = "detach_state" }, { .bus = "pseudo", .file = "detach_state" }, @@ -338,6 +339,11 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, char filename[SYSFS_PATH_MAX]; struct stat stats; + if (devicefile->file == NULL) { + dbg("bus '%s' has no file to wait for", devices_dev->bus); + return 0; + } + found_bus_type = 1; snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, devicefile->file); dbg("looking at bus '%s' device for specific file '%s'", devices_dev->bus, filename); From 69d2dbd66fdd52b5ebbc6545ef693fdd3f0638ec Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 04:47:06 +0100 Subject: [PATCH 0999/4284] [PATCH] export udev_log flag to the environment Forked scripts and callouts may want to follow udev's configured behavior and log only if udev is logging itself. --- udev.c | 10 +++++++++- udev_start.c | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/udev.c b/udev.c index 78fe82cfbb..39c16c2e77 100644 --- a/udev.c +++ b/udev.c @@ -81,6 +81,10 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udev"); udev_init_config(); + /* export logging flag, callouts may want to do the same as udev */ + if (udev_log) + setenv("UDEV_LOG", "1", 1); + if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { act_type = UDEVSTART; } else { @@ -143,7 +147,11 @@ int main(int argc, char *argv[], char *envp[]) switch(act_type) { case UDEVSTART: dbg("udevstart"); + + /* disable all logging as it's much too slow on some facilities */ udev_log = 0; + unsetenv("UDEV_LOG"); + namedev_init(); retval = udev_start(); break; @@ -155,7 +163,7 @@ int main(int argc, char *argv[], char *envp[]) class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg ("sysfs_open_class_device_path failed"); - break; + goto exit; } dbg("opened class_dev->name='%s'", class_dev->name); diff --git a/udev_start.c b/udev_start.c index c1d877fb37..3e3062c019 100644 --- a/udev_start.c +++ b/udev_start.c @@ -291,7 +291,7 @@ int udev_start(void) { /* set environment for callouts and dev.d/ */ setenv("ACTION", "add", 1); - setenv("UDEVSTART", "1", 1); + setenv("UDEV_START", "1", 1); udev_scan_class(); udev_scan_block(); From a97b06483e3006a7d21e534694e8d67d3b3c694d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 05:05:37 +0100 Subject: [PATCH 1000/4284] [PATCH] export DEVNAME on remove event Fix from Sjoerd Simons , it got lost on the recent reorganization of the udev processing stages. --- udev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/udev.c b/udev.c index 39c16c2e77..605a55bf19 100644 --- a/udev.c +++ b/udev.c @@ -187,8 +187,11 @@ int main(int argc, char *argv[], char *envp[]) /* get node from db, delete it*/ retval = udev_remove_device(&udev); - /* run scripts */ - dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + /* run dev.d/ scripts if we're not instructed to ignore the event */ + if (udev.devname[0] != '\0') { + setenv("DEVNAME", udev.devname, 1); + dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + } } exit: From 6f59ed5547426ddaf6bedf574d19a19f6bd20e1f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 06:14:21 +0100 Subject: [PATCH 1001/4284] [PATCH] add MANAGED_EVENT to the forked udev environment This will prevent a loop, if udev sends events back into the daemon. --- udevd.c | 3 ++- udevd.h | 4 ++-- udevsend.c | 6 ++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/udevd.c b/udevd.c index 2337493f1e..bd36d2c192 100644 --- a/udevd.c +++ b/udevd.c @@ -291,7 +291,7 @@ static void handle_udevsend_msg(int sock) /* copy environment buffer and reconstruct envp */ memcpy(msg->envbuf, usend_msg.envbuf, envbuf_size); bufpos = 0; - for (i = 0; (bufpos < envbuf_size) && (i < HOTPLUG_NUM_ENVP-1); i++) { + for (i = 0; (bufpos < envbuf_size) && (i < HOTPLUG_NUM_ENVP-2); i++) { int keylen; char *key; @@ -314,6 +314,7 @@ static void handle_udevsend_msg(int sock) if (strncmp(key, "SEQNUM=", 7) == 0) msg->seqnum = strtoull(&key[7], NULL, 10); } + msg->envp[i++] = "MANAGED_EVENT=1"; msg->envp[i] = NULL; /* if no seqnum is given, we move straight to exec queue */ diff --git a/udevd.h b/udevd.h index b393a28bf9..31f07de826 100644 --- a/udevd.h +++ b/udevd.h @@ -36,7 +36,7 @@ struct udevsend_msg { char magic[20]; - char envbuf[HOTPLUG_BUFFER_SIZE]; + char envbuf[HOTPLUG_BUFFER_SIZE+256]; }; struct hotplug_msg { @@ -47,6 +47,6 @@ struct hotplug_msg { char *devpath; char *subsystem; unsigned long long seqnum; - char *envp[HOTPLUG_NUM_ENVP]; + char *envp[HOTPLUG_NUM_ENVP+1]; char envbuf[]; }; diff --git a/udevsend.c b/udevsend.c index 9f324077b3..7d865573c2 100644 --- a/udevsend.c +++ b/udevsend.c @@ -132,6 +132,12 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + /* prevent loops in the scripts we execute */ + if (getenv("MANAGED_EVENT") != NULL) { + dbg("seems that the event source is not the kernel, just exit"); + goto exit; + } + sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { dbg("error getting socket"); From 491b02acd95904f17829f792c5a69c26bee1f2a7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 06:22:26 +0100 Subject: [PATCH 1002/4284] [PATCH] make the searched multiplex directories conditionally If we don't have "name" or a "subsystem" don't look for it. --- dev_d.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/dev_d.c b/dev_d.c index d14c70c256..817355af60 100644 --- a/dev_d.c +++ b/dev_d.c @@ -96,13 +96,17 @@ void dev_d_execute(struct udevice *udev, const char *basedir, const char *suffix temp = strchr(temp, '/'); } - snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->name); - dirname[PATH_MAX-1] = '\0'; - call_foreach_file(run_program, dirname, suffix, udev); + if (udev->name[0] != '\0') { + snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->name); + dirname[PATH_MAX-1] = '\0'; + call_foreach_file(run_program, dirname, suffix, udev); + } - snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->subsystem); - dirname[PATH_MAX-1] = '\0'; - call_foreach_file(run_program, dirname, suffix, udev); + if (udev->subsystem[0] != '\0') { + snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->subsystem); + dirname[PATH_MAX-1] = '\0'; + call_foreach_file(run_program, dirname, suffix, udev); + } snprintf(dirname, PATH_MAX, "%s/default", basedir); dirname[PATH_MAX-1] = '\0'; From cc0e9bfc350e6a8b3fff79a9a0f2a97afa9b3825 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 04:22:16 +0100 Subject: [PATCH 1003/4284] [PATCH] remove my test code --- udev_sysfs.c | 1 - 1 file changed, 1 deletion(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index 7293407be1..4976b8f308 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -267,7 +267,6 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, const char *file; } device_files[] = { { .bus = "scsi", .file = "vendor" }, - { .bus = "usb", .file = NULL }, { .bus = "usb", .file = "idVendor" }, { .bus = "usb", .file = "iInterface" }, { .bus = "usb", .file = "bNumEndpoints" }, From c449b25e3f998efe8f5988632126fb468ee55fc5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 07:34:56 +0100 Subject: [PATCH 1004/4284] [PATCH] integrate wait_for_sysfs in udev Move the wait_for_sysfs logic into the udev binary. udev is called for every hotplug event. It also waits for /devices events. --- Makefile | 14 +--- udev.c | 190 ++++++++++++++++++++++++----------------------- wait_for_sysfs.c | 165 ---------------------------------------- 3 files changed, 99 insertions(+), 270 deletions(-) delete mode 100644 wait_for_sysfs.c diff --git a/Makefile b/Makefile index de08f7cf52..c89fa0feee 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,6 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -WAIT = wait_for_sysfs VERSION = 046 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) @@ -178,7 +177,7 @@ CFLAGS += -I$(PWD)/libsysfs/sysfs \ # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(WAIT) $(GEN_CONFIGS) +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(GEN_CONFIGS) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -282,7 +281,6 @@ $(INFO).o: $(GEN_HEADERS) $(HOST_PROGS) $(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS) $(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) -$(WAIT).o: $(GEN_HEADERS) $(HOST_PROGS) $(ROOT): $(LIBC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) @@ -304,10 +302,6 @@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -$(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(WAIT).o udev_sysfs.o udev_lib.o udev_config.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - #.c.o: # $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) -c -o $@ $< .c.o: @@ -317,7 +311,7 @@ $(WAIT): $(WAIT).o $(OBJS) $(HEADERS) $(LIBC) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) $(WAIT) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) -rm -f ccdv $(MAKE) -C klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ @@ -417,10 +411,8 @@ install: install-initscript install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) - $(INSTALL_PROGRAM) -D $(WAIT) $(DESTDIR)$(sbindir)/$(WAIT) - ln -f -s $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER) - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug - - ln -f -s $(sbindir)/$(WAIT) $(DESTDIR)$(hotplugdir)/05-wait_for_sysfs.hotplug ifndef DESTDIR - killall $(DAEMON) - rm -rf $(udevdb) @@ -433,7 +425,6 @@ endif uninstall: uninstall-man uninstall-dev.d - rm $(hotplugdir)/10-udev.hotplug - - rm $(hotplugdir)/05-wait_for_sysfs.hotplug - rm $(configdir)/rules.d/50-udev.rules - rm $(configdir)/permissions.d/50-udev.permissions - rm $(configdir)/udev.conf @@ -447,7 +438,6 @@ uninstall: uninstall-man uninstall-dev.d - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) - rm $(usrbindir)/$(TESTER) - - rm $(usrbindir)/$(WAIT) - rmdir $(hotplugdir) - rm -rf $(udevdb) - rmdir $(udevdir) diff --git a/udev.c b/udev.c index 605a55bf19..8e6d06f1bd 100644 --- a/udev.c +++ b/udev.c @@ -4,6 +4,7 @@ * Userspace devfs * * Copyright (C) 2003,2004 Greg Kroah-Hartman + * 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 @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -68,70 +70,19 @@ int main(int argc, char *argv[], char *envp[]) { struct sigaction act; struct sysfs_class_device *class_dev; + struct sysfs_device *devices_dev; struct udevice udev; char path[SYSFS_PATH_MAX]; int retval = -EINVAL; - enum { - ADD, - REMOVE, - UDEVSTART, - } act_type; + const char *error; + const char *action = getenv("ACTION"); + const char *devpath = getenv("DEVPATH"); + const char *subsystem = argv[1]; dbg("version %s", UDEV_VERSION); logging_init("udev"); udev_init_config(); - /* export logging flag, callouts may want to do the same as udev */ - if (udev_log) - setenv("UDEV_LOG", "1", 1); - - if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { - act_type = UDEVSTART; - } else { - const char *action = getenv("ACTION"); - const char *devpath = getenv("DEVPATH"); - const char *subsystem = argv[1]; - - if (!action) { - dbg("no action?"); - goto exit; - } - if (strcmp(action, "add") == 0) { - act_type = ADD; - } else if (strcmp(action, "remove") == 0) { - act_type = REMOVE; - } else { - dbg("no action '%s' for us", action); - goto exit; - } - - if (!devpath) { - dbg("no devpath?"); - goto exit; - } - dbg("looking at '%s'", devpath); - - /* we only care about class devices and block stuff */ - if (!strstr(devpath, "class") && !strstr(devpath, "block")) { - dbg("not a block or class device"); - goto exit; - } - - if (!subsystem) { - dbg("no subsystem"); - goto exit; - } - - udev_set_values(&udev, devpath, subsystem, action); - - /* skip blacklisted subsystems */ - if (udev.type != 'n' && subsystem_expect_no_dev(subsystem)) { - dbg("don't care about '%s' devices", subsystem); - goto exit; - }; - - } - /* set signal handlers */ act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); @@ -141,57 +92,110 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); - /* trigger timout to interrupt blocking syscalls */ + /* trigger timeout to interrupt blocking syscalls */ alarm(ALARM_TIMEOUT); - switch(act_type) { - case UDEVSTART: + udev_set_values(&udev, devpath, subsystem, action); + + if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { dbg("udevstart"); - /* disable all logging as it's much too slow on some facilities */ + /* disable all logging, as it's much too slow on some facilities */ udev_log = 0; - unsetenv("UDEV_LOG"); namedev_init(); retval = udev_start(); - break; - case ADD: - dbg("udev add"); + goto exit; + } + + if (!action) { + dbg("no action"); + goto exit; + } + + if (!subsystem) { + dbg("no subsystem"); + goto exit; + } + + if (!devpath) { + dbg("no devpath"); + goto exit; + } + + /* export logging flag, called scripts may want to do the same as udev */ + if (udev_log) + setenv("UDEV_LOG", "1", 1); + + if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) { + if (strcmp(action, "add") == 0) { + /* wait for sysfs and possibly add node */ + dbg("udev add"); + + /* skip blacklisted subsystems */ + if (udev.type != 'n' && subsystem_expect_no_dev(udev.subsystem)) { + dbg("don't care about '%s' devices", udev.subsystem); + goto exit; + }; + + snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); + class_dev = wait_class_device_open(path); + if (class_dev == NULL) { + dbg ("open class device failed"); + goto exit; + } + dbg("opened class_dev->name='%s'", class_dev->name); + + wait_for_class_device(class_dev, &error); + + /* init rules, permissions */ + namedev_init(); + + /* name, create node, store in db */ + retval = udev_add_device(&udev, class_dev); + + /* run dev.d/ scripts if we created a node or changed a netif name */ + if (udev.devname[0] != '\0') { + setenv("DEVNAME", udev.devname, 1); + dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + } + + sysfs_close_class_device(class_dev); + } else if (strcmp(action, "remove") == 0) { + /* possibly remove a node */ + dbg("udev remove"); + + /* get node from db, delete it */ + retval = udev_remove_device(&udev); + + /* run dev.d/ scripts if we're not instructed to ignore the event */ + if (udev.devname[0] != '\0') { + setenv("DEVNAME", udev.devname, 1); + dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + } - /* open the device */ - snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); - class_dev = sysfs_open_class_device_path(path); - if (class_dev == NULL) { - dbg ("sysfs_open_class_device_path failed"); - goto exit; } - dbg("opened class_dev->name='%s'", class_dev->name); + } else if ((strncmp(devpath, "/devices/", 9) == 0)) { + if (strcmp(action, "add") == 0) { + /* wait for sysfs */ + dbg("devices add"); - /* init rules */ - namedev_init(); + snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath); + devices_dev = wait_devices_device_open(path); + if (!devices_dev) { + dbg("devices device unavailable (probably remove has beaten us)"); + goto exit; + } + dbg("devices device opened '%s'", path); - /* name, create node, store in db */ - retval = udev_add_device(&udev, class_dev); + wait_for_devices_device(devices_dev, &error); - /* run dev.d/ scripts if we created a node or changed a netif name */ - if (udev.devname[0] != '\0') { - setenv("DEVNAME", udev.devname, 1); - dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); - } - - sysfs_close_class_device(class_dev); - break; - case REMOVE: - dbg("udev remove"); - - /* get node from db, delete it*/ - retval = udev_remove_device(&udev); - - /* run dev.d/ scripts if we're not instructed to ignore the event */ - if (udev.devname[0] != '\0') { - setenv("DEVNAME", udev.devname, 1); - dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + sysfs_close_device(devices_dev); + } else if (strcmp(action, "remove") == 0) { + dbg("devices remove"); } + } else { + dbg("unhandled"); } exit: diff --git a/wait_for_sysfs.c b/wait_for_sysfs.c deleted file mode 100644 index 84a25adb97..0000000000 --- a/wait_for_sysfs.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * wait_for_sysfs.c - small program to delay the execution - * of /etc/hotplug.d/ programs, until sysfs - * is fully populated by the kernel. Depending on - * the type of device, we wait for all expected - * directories and then just exit. - * - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2004 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. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_lib.h" -#include "udev_version.h" -#include "udev_sysfs.h" -#include "logging.h" - -#ifdef LOG -unsigned char logname[LOGNAME_SIZE]; -void log_message(int level, const char *format, ...) -{ - va_list args; - - va_start(args, format); - vsyslog(level, format, args); - va_end(args); -} -#endif - -int main(int argc, char *argv[], char *envp[]) -{ - const char *devpath = ""; - const char *action; - const char *subsystem; - char sysfs_mnt_path[SYSFS_PATH_MAX]; - char filename[SYSFS_PATH_MAX]; - struct sysfs_class_device *class_dev; - struct sysfs_device *devices_dev; - int rc = 0; - const char *error = NULL; - - logging_init("wait_for_sysfs"); - - if (argc != 2) { - dbg("error: subsystem"); - return 1; - } - subsystem = argv[1]; - - devpath = getenv ("DEVPATH"); - if (!devpath) { - dbg("error: no DEVPATH"); - rc = 1; - goto exit; - } - - action = getenv ("ACTION"); - if (!action) { - dbg("error: no ACTION"); - rc = 1; - goto exit; - } - - /* we only wait on an add event */ - if (strcmp(action, "add") != 0) { - dbg("no add ACTION"); - goto exit; - } - - if (sysfs_get_mnt_path(sysfs_mnt_path, SYSFS_PATH_MAX) != 0) { - dbg("error: no sysfs path"); - rc = 2; - goto exit; - } - - if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) { - snprintf(filename, SYSFS_PATH_MAX, "%s%s", sysfs_mnt_path, devpath); - filename[SYSFS_PATH_MAX-1] = '\0'; - - /* skip bad events where we get no device for the class */ - if (strncmp(devpath, "/class/", 7) == 0 && strchr(&devpath[7], '/') == NULL) { - dbg("no device name for '%s', bad event", devpath); - goto exit; - } - - /* open the class device we are called for */ - class_dev = wait_class_device_open(filename); - if (!class_dev) { - dbg("error: class device unavailable (probably remove has beaten us)"); - goto exit; - } - dbg("class device opened '%s'", filename); - - /* wait for the class device with possible physical device and bus */ - wait_for_class_device(class_dev, &error); - - /* - * we got too many unfixable class/net errors, kernel later than 2.6.10-rc1 will - * solve this by exporting the needed information with the hotplug event - * until we use this just don't print any error for net devices, but still - * wait for it. - */ - if (strncmp(devpath, "/class/net/", 11) == 0) - error = NULL; - - sysfs_close_class_device(class_dev); - - } else if ((strncmp(devpath, "/devices/", 9) == 0)) { - snprintf(filename, SYSFS_PATH_MAX, "%s%s", sysfs_mnt_path, devpath); - filename[SYSFS_PATH_MAX-1] = '\0'; - - /* open the path we are called for */ - devices_dev = wait_devices_device_open(filename); - if (!devices_dev) { - dbg("error: devices device unavailable (probably remove has beaten us)"); - goto exit; - } - dbg("devices device opened '%s'", filename); - - /* wait for the devices device */ - wait_for_devices_device(devices_dev, &error); - - sysfs_close_device(devices_dev); - - } else { - dbg("unhandled sysfs path, no need to wait"); - } - -exit: - if (error) { - info("either wait_for_sysfs (udev %s) needs an update to handle the device '%s' " - "properly (%s) or the sysfs-support of your device's driver needs to be fixed, " - "please report to ", - UDEV_VERSION, devpath, error); - rc =3; - } else { - dbg("result: waiting for sysfs successful '%s'", devpath); - } - - logging_close(); - exit(rc); -} From d07557b9b6ba72f50c6b80ea06cecac61cf9eeb1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 23 Nov 2004 08:01:57 +0100 Subject: [PATCH 1005/4284] [PATCH] handle whole hotplug event with udevd/udev If /proc/sys/kernel/hotplug points to /sbin/udevsend we handle the whole hotplug event with multiplexing /etc/hotplug.d/. --- udev.c | 44 ++++++++++++++++++++++++++++++++++++-------- udev.h | 3 +++ 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/udev.c b/udev.c index 8e6d06f1bd..dad64288a9 100644 --- a/udev.c +++ b/udev.c @@ -55,6 +55,30 @@ void log_message(int level, const char *format, ...) } #endif +/* (for now) true if udevsend is the helper */ +static int manage_hotplug_event(void) { + char helper[256]; + int fd; + int len; + + fd = open("/proc/sys/kernel/hotplug", O_RDONLY); + if (fd < 0) + goto exit; + + len = read(fd, helper, 256); + close(fd); + + if (len < 0) + goto exit; + helper[len] = '\0'; + + if (strstr(helper, "udevsend")) + return 1; + +exit: + return 0; +} + static void asmlinkage sig_handler(int signum) { switch (signum) { @@ -110,20 +134,20 @@ int main(int argc, char *argv[], char *envp[]) if (!action) { dbg("no action"); - goto exit; + goto hotplug; } if (!subsystem) { dbg("no subsystem"); - goto exit; + goto hotplug; } if (!devpath) { dbg("no devpath"); - goto exit; + goto hotplug; } - /* export logging flag, called scripts may want to do the same as udev */ + /* export logging flag, as called scripts may want to do the same as udev */ if (udev_log) setenv("UDEV_LOG", "1", 1); @@ -135,14 +159,14 @@ int main(int argc, char *argv[], char *envp[]) /* skip blacklisted subsystems */ if (udev.type != 'n' && subsystem_expect_no_dev(udev.subsystem)) { dbg("don't care about '%s' devices", udev.subsystem); - goto exit; + goto hotplug; }; snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); class_dev = wait_class_device_open(path); if (class_dev == NULL) { dbg ("open class device failed"); - goto exit; + goto hotplug; } dbg("opened class_dev->name='%s'", class_dev->name); @@ -165,7 +189,7 @@ int main(int argc, char *argv[], char *envp[]) /* possibly remove a node */ dbg("udev remove"); - /* get node from db, delete it */ + /* get node from db, remove db-entry, delete created node */ retval = udev_remove_device(&udev); /* run dev.d/ scripts if we're not instructed to ignore the event */ @@ -184,7 +208,7 @@ int main(int argc, char *argv[], char *envp[]) devices_dev = wait_devices_device_open(path); if (!devices_dev) { dbg("devices device unavailable (probably remove has beaten us)"); - goto exit; + goto hotplug; } dbg("devices device opened '%s'", path); @@ -198,6 +222,10 @@ int main(int argc, char *argv[], char *envp[]) dbg("unhandled"); } +hotplug: + if (manage_hotplug_event()) + dev_d_execute(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); + exit: logging_close(); return retval; diff --git a/udev.h b/udev.h index d9a775ae91..e834f1e5b9 100644 --- a/udev.h +++ b/udev.h @@ -44,6 +44,9 @@ #define DEVD_DIR "/etc/dev.d" #define DEVD_SUFFIX ".dev" +#define HOTPLUGD_DIR "/etc/hotplug.d" +#define HOTPLUG_SUFFIX ".hotplug" + struct udevice { char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; From 0d1ecb44a0b8c00b0fc6314d19e1bc8efd0f32bb Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 2 Dec 2004 21:45:26 -0800 Subject: [PATCH 1006/4284] [PATCH] fix udevinfo '-q path' option as it was not working --- udevinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevinfo.c b/udevinfo.c index 901990ede6..9ba302cbdc 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -401,7 +401,7 @@ print: break; case PATH: - strfieldcpy(result, path); + strfieldcpy(result, udev.devpath); break; case ALL: From 67aca2c50984d0b463c714eba142f33bb07f45a2 Mon Sep 17 00:00:00 2001 From: "sjoerd@spring.luon.net" Date: Tue, 23 Nov 2004 07:49:55 -0800 Subject: [PATCH 1007/4284] [PATCH] DEVNAME on device removal I just noticed that the DEVNAME enviroment variable isn't being set anymore in udev 0.046 on device removal, while it was being set in 0.042. We're using the property tto do umount -l when a block device is removed. Afaik there is no other way to associate a device with it's DEVNAME on removal ? Also are there cases where doing umount -l on the removed devices is wrong? I guess the device is gone, so there is no sense in keeping it mounted (it's not like the filesystem is gonna come back in a sane state again).. Attached (trivial) patch brings back the DEVNAME variable on device removal. --- udev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/udev.c b/udev.c index dad64288a9..efeb1b5050 100644 --- a/udev.c +++ b/udev.c @@ -192,6 +192,10 @@ int main(int argc, char *argv[], char *envp[]) /* get node from db, remove db-entry, delete created node */ retval = udev_remove_device(&udev); + /* Set the DEVNAME if known */ + if (udev.devname[0] != '\0') { + setenv("DEVNAME", udev.devname, 1); + } /* run dev.d/ scripts if we're not instructed to ignore the event */ if (udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); From aa8666f77b1f605dced47a822a8b74b9c1326fed Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 2 Dec 2004 22:14:57 -0800 Subject: [PATCH 1008/4284] [PATCH] fix spurious valgrind warning in udev. --- udev.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev.c b/udev.c index efeb1b5050..e71cddd3ee 100644 --- a/udev.c +++ b/udev.c @@ -108,6 +108,7 @@ int main(int argc, char *argv[], char *envp[]) udev_init_config(); /* set signal handlers */ + memset(&act, 0x00, sizeof(act)); act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = 0; From ad89f2be3b045f37b7e17de10f5ad46dbb09664f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 2 Dec 2004 22:16:54 -0800 Subject: [PATCH 1009/4284] [PATCH] comment out ability to run udev-test.pl with valgrind --- test/udev-test.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index d584579584..c2d8e27a52 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -35,6 +35,9 @@ my $perm = "udev.permissions"; my $main_conf = "udev-test.conf"; my $conf_tmp = "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 = ( { @@ -1259,7 +1262,6 @@ sub run_test { udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); - if ((-e "$PWD/$udev_root$config->{exp_name}") || (-l "$PWD/$udev_root$config->{exp_name}")) { From 8a0dc204e902a47a5b251c6d4a29eddb8f4a634a Mon Sep 17 00:00:00 2001 From: "sschweizer@gmail.com" Date: Thu, 2 Dec 2004 22:23:21 -0800 Subject: [PATCH 1010/4284] [PATCH] Allow GROUP to have modifiers in it --- etc/udev/udev.rules.gentoo | 2 +- extras/ide-devfs.sh | 6 +++--- namedev.c | 5 +++++ 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 1809232ed0..997acb8a34 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -19,7 +19,7 @@ BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYM # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" # dri devices KERNEL="card*", NAME="dri/card%n" diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 4f20259480..580a751abe 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -36,11 +36,11 @@ get_dev_number() { if [ -z "$3" ] && [ -f /proc/ide/${1}/media ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` ${MEDIA} elif [ "${MEDIA}" = "floppy" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc floppies/floppy`get_dev_number $1 floppy`/disc + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc floppies/floppy`get_dev_number $1 floppy`/disc ${MEDIA} elif [ "${MEDIA}" = "disk" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc ${MEDIA} fi else echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/part$3 discs/disc`get_dev_number $1 disk`/part$3 diff --git a/namedev.c b/namedev.c index 69669709df..dca405ceba 100644 --- a/namedev.c +++ b/namedev.c @@ -809,6 +809,11 @@ found: udev->partitions = dev->partitions; udev->ignore_remove = dev->ignore_remove; + if (dev->group[0] != '\0') { + strfieldcpy(udev->group, dev->group); + apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); + } + /* get permissions given in rule */ set_empty_perms(udev, dev->mode, dev->owner, From 9af5bb2f8fdbf54c064ddbd319d61092f28a4132 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 25 Nov 2004 02:44:38 +0100 Subject: [PATCH 1011/4284] [PATCH] rename udev_lib to udev_utils and dev_d to udev_multiplex --- Makefile | 10 +++++----- klibc_fixups/klibc_fixups.c | 2 +- namedev.c | 2 +- namedev_parse.c | 2 +- udev.c | 8 ++++---- udev.h | 2 +- udev_add.c | 2 +- udev_config.c | 2 +- udev_db.c | 2 +- dev_d.c => udev_multiplex.c | 6 +++--- udev_remove.c | 2 +- udev_start.c | 4 ++-- udev_sysfs.c | 2 +- udev_lib.c => udev_utils.c | 2 +- udev_lib.h => udev_utils.h | 0 udevd.c | 2 +- udevinfo.c | 2 +- udevsend.c | 1 - udevtest.c | 2 +- 19 files changed, 27 insertions(+), 28 deletions(-) rename dev_d.c => udev_multiplex.c (93%) rename udev_lib.c => udev_utils.c (99%) rename udev_lib.h => udev_utils.h (100%) diff --git a/Makefile b/Makefile index c89fa0feee..4d48b3c9e0 100644 --- a/Makefile +++ b/Makefile @@ -204,20 +204,20 @@ SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ $(PWD)/libsysfs/sysfs_utils.o \ $(PWD)/libsysfs/dlist.o -OBJS = udev_lib.o \ +OBJS = udev_utils.o \ udev_config.o \ udev_add.o \ udev_remove.o \ udev_start.o \ udev_sysfs.o \ udev_db.o \ + udev_multiplex.o\ namedev.o \ namedev_parse.o \ - dev_d.o \ $(SYSFS) HEADERS = udev.h \ - udev_lib.h \ + udev_utils.h \ namedev.h \ udev_version.h \ udev_db.h \ @@ -291,11 +291,11 @@ $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) $(QUIET) $(STRIPCMD) $@ $(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_lib.o udev_config.o udev_db.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_utils.o udev_config.o udev_db.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_lib.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_utils.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h diff --git a/klibc_fixups/klibc_fixups.c b/klibc_fixups/klibc_fixups.c index 2d673d8ca9..175cf27fe4 100644 --- a/klibc_fixups/klibc_fixups.c +++ b/klibc_fixups/klibc_fixups.c @@ -30,7 +30,7 @@ #include "pwd.h" #include "../udev.h" -#include "../udev_lib.h" +#include "../udev_utils.h" #include "../logging.h" #define PW_FILE "/etc/passwd" diff --git a/namedev.c b/namedev.c index dca405ceba..126453cc89 100644 --- a/namedev.c +++ b/namedev.c @@ -36,7 +36,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "list.h" #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" diff --git a/namedev_parse.c b/namedev_parse.c index cb1760fd57..d39141bfc7 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -36,7 +36,7 @@ #include #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "logging.h" #include "namedev.h" diff --git a/udev.c b/udev.c index e71cddd3ee..9b0a00fb78 100644 --- a/udev.c +++ b/udev.c @@ -33,7 +33,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "udev_sysfs.h" #include "udev_version.h" #include "namedev.h" @@ -182,7 +182,7 @@ int main(int argc, char *argv[], char *envp[]) /* run dev.d/ scripts if we created a node or changed a netif name */ if (udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); - dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } sysfs_close_class_device(class_dev); @@ -200,7 +200,7 @@ int main(int argc, char *argv[], char *envp[]) /* run dev.d/ scripts if we're not instructed to ignore the event */ if (udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); - dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } } @@ -229,7 +229,7 @@ int main(int argc, char *argv[], char *envp[]) hotplug: if (manage_hotplug_event()) - dev_d_execute(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); + udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); exit: logging_close(); diff --git a/udev.h b/udev.h index e834f1e5b9..1e3db5af27 100644 --- a/udev.h +++ b/udev.h @@ -78,7 +78,7 @@ extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); extern int parse_get_pair(char **orig_string, char **left, char **right); -extern void dev_d_execute(struct udevice *udev, const char *basedir, const char *suffix); +extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix); extern char sysfs_path[SYSFS_PATH_MAX]; extern char udev_root[PATH_MAX]; diff --git a/udev_add.c b/udev_add.c index 4fb5ef18c0..f537f567cc 100644 --- a/udev_add.c +++ b/udev_add.c @@ -38,7 +38,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" diff --git a/udev_config.c b/udev_config.c index 198473936f..51bdc720a7 100644 --- a/udev_config.c +++ b/udev_config.c @@ -34,7 +34,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" diff --git a/udev_db.c b/udev_db.c index e07e72b858..36da264716 100644 --- a/udev_db.c +++ b/udev_db.c @@ -33,7 +33,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "logging.h" #include "udev_db.h" diff --git a/dev_d.c b/udev_multiplex.c similarity index 93% rename from dev_d.c rename to udev_multiplex.c index 817355af60..7e3dc656d6 100644 --- a/dev_d.c +++ b/udev_multiplex.c @@ -1,5 +1,5 @@ /* - * dev_d.c - dev.d/ multiplexer + * udev_multiplex.c directory multiplexer * * Copyright (C) 2004 Greg Kroah-Hartman * @@ -28,7 +28,7 @@ #include #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "logging.h" static int run_program(const char *filename, void *data) @@ -71,7 +71,7 @@ static int run_program(const char *filename, void *data) * subsystem/ * default/ */ -void dev_d_execute(struct udevice *udev, const char *basedir, const char *suffix) +void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix) { char dirname[PATH_MAX]; char devname[NAME_SIZE]; diff --git a/udev_remove.c b/udev_remove.c index 8887125dd8..142503589a 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -31,7 +31,7 @@ #include #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "udev_version.h" #include "namedev.h" #include "udev_db.h" diff --git a/udev_start.c b/udev_start.c index 3e3062c019..129af4291a 100644 --- a/udev_start.c +++ b/udev_start.c @@ -35,7 +35,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "logging.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "list.h" #include "udev.h" @@ -111,7 +111,7 @@ static int add_device(char *devpath, char *subsystem) /* run dev.d/ scripts if we created a node or changed a netif name */ if (udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); - dev_d_execute(&udev, DEVD_DIR, DEVD_SUFFIX); + udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } sysfs_close_class_device(class_dev); diff --git a/udev_sysfs.c b/udev_sysfs.c index 4976b8f308..6655968433 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -31,7 +31,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev_version.h" #include "udev_sysfs.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "logging.h" /* list of subsystem specific files, NULL if there is no file to wait for */ diff --git a/udev_lib.c b/udev_utils.c similarity index 99% rename from udev_lib.c rename to udev_utils.c index 86a526f7e8..bdf0233e3a 100644 --- a/udev_lib.c +++ b/udev_utils.c @@ -32,7 +32,7 @@ #include "udev.h" #include "logging.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "list.h" diff --git a/udev_lib.h b/udev_utils.h similarity index 100% rename from udev_lib.h rename to udev_utils.h diff --git a/udevd.c b/udevd.c index bd36d2c192..06b172bc25 100644 --- a/udevd.c +++ b/udevd.c @@ -38,8 +38,8 @@ #include "list.h" #include "udev.h" -#include "udev_lib.h" #include "udev_version.h" +#include "udev_utils.h" #include "udevd.h" #include "logging.h" diff --git a/udevinfo.c b/udevinfo.c index 9ba302cbdc..6e6b9aeb3e 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -30,7 +30,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "libsysfs/dlist.h" #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "udev_version.h" #include "udev_db.h" #include "logging.h" diff --git a/udevsend.c b/udevsend.c index 7d865573c2..341ed4cc36 100644 --- a/udevsend.c +++ b/udevsend.c @@ -36,7 +36,6 @@ #include #include "udev.h" -#include "udev_lib.h" #include "udev_version.h" #include "udevd.h" #include "logging.h" diff --git a/udevtest.c b/udevtest.c index b9a5fea489..37ec767e13 100644 --- a/udevtest.c +++ b/udevtest.c @@ -29,7 +29,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" -#include "udev_lib.h" +#include "udev_utils.h" #include "udev_version.h" #include "namedev.h" #include "logging.h" From 7c2aae11ff58b4e495a351d8025b5d4bbb0ce502 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 25 Nov 2004 08:38:06 +0100 Subject: [PATCH 1012/4284] [PATCH] link archive insted of objects This cuts the size of the binaries, as only objects that are actually used are linked into the binary: 45592 -> 43608 udev 4380 -> 4380 udevsend 10380 -> 4652 udevd 34732 -> 33100 udevinfo 45432 -> 37208 udevtest --- Makefile | 102 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index 4d48b3c9e0..55c51fd2a8 100644 --- a/Makefile +++ b/Makefile @@ -139,8 +139,7 @@ ifeq ($(strip $(USE_KLIBC)),true) LINUX_INCLUDE_DIR := $(KERNEL_DIR)/include include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG # arch specific objects - ARCH_LIB_OBJS = \ - $(KLIBC_DIR)/libc.a + ARCH_LIB_OBJS = $(KLIBC_DIR)/libc.a CRT0 = $(KLIBC_DIR)/crt0.o @@ -171,7 +170,7 @@ ifeq ($(strip $(USE_SELINUX)),true) LIB_OBJS += -lselinux endif -CFLAGS += -I$(PWD)/libsysfs/sysfs \ +CFLAGS += -I$(PWD)/libsysfs/sysfs \ -I$(PWD)/libsysfs # config files automatically generated @@ -196,43 +195,52 @@ $(CRT0): fi $(MAKE) -C klibc SUBDIRS=klibc -SYSFS = $(PWD)/libsysfs/sysfs_bus.o \ - $(PWD)/libsysfs/sysfs_class.o \ - $(PWD)/libsysfs/sysfs_device.o \ - $(PWD)/libsysfs/sysfs_dir.o \ - $(PWD)/libsysfs/sysfs_driver.o \ - $(PWD)/libsysfs/sysfs_utils.o \ - $(PWD)/libsysfs/dlist.o +HEADERS = \ + udev.h \ + udev_utils.h \ + namedev.h \ + udev_version.h \ + udev_db.h \ + udev_sysfs.h \ + logging.h \ + selinux.h \ + list.h -OBJS = udev_utils.o \ - udev_config.o \ - udev_add.o \ - udev_remove.o \ - udev_start.o \ - udev_sysfs.o \ - udev_db.o \ - udev_multiplex.o\ - namedev.o \ - namedev_parse.o \ - $(SYSFS) +SYSFS_OBJS = \ + libsysfs/sysfs_bus.o \ + libsysfs/sysfs_class.o \ + libsysfs/sysfs_device.o \ + libsysfs/sysfs_dir.o \ + libsysfs/sysfs_driver.o \ + libsysfs/sysfs_utils.o \ + libsysfs/dlist.o -HEADERS = udev.h \ - udev_utils.h \ - namedev.h \ - udev_version.h \ - udev_db.h \ - udev_sysfs.h \ - logging.h \ - selinux.h \ - list.h +UDEV_OBJS = \ + udev_utils.o \ + udev_config.o \ + udev_add.o \ + udev_remove.o \ + udev_start.o \ + udev_sysfs.o \ + udev_db.o \ + udev_multiplex.o \ + namedev.o \ + namedev_parse.o + +OBJS = \ + libsysfs/sysfs.a \ + udev.a ifeq ($(strip $(USE_KLIBC)),true) - HEADERS += klibc_fixups/klibc_fixups.h \ - klibc_fixups/mntent.h \ - klibc_fixups/pwd.h + HEADERS += \ + klibc_fixups/klibc_fixups.h \ + klibc_fixups/mntent.h \ + klibc_fixups/pwd.h - OBJS += klibc_fixups/klibc_fixups.o - KLIBC_FIXUP = klibc_fixups/klibc_fixups.o + KLIBC_FIXUP_OBJS = \ + klibc_fixups/klibc_fixups.o + + OBJS += klibc_fixups/klibc_fixups.a endif ifeq ($(strip $(V)),false) @@ -243,6 +251,18 @@ else HOST_PROGS= endif +udev.a: $(UDEV_OBJS) + $(QUIET) $(AR) cq $@ $(UDEV_OBJS) + $(QUIET) $(RANLIB) $@ + +libsysfs/sysfs.a: $(SYSFS_OBJS) + $(QUIET) $(AR) cq $@ $(SYSFS_OBJS) + $(QUIET) $(RANLIB) $@ + +klibc_fixups/klibc_fixups.a: $(KLIBC_FIXUP_OBJS) + $(QUIET) $(AR) cq $@ $(KLIBC_FIXUP_OBJS) + $(QUIET) $(RANLIB) $@ + # header files automatically generated GEN_HEADERS = udev_version.h @@ -283,27 +303,25 @@ $(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(ROOT): $(LIBC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udev.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(ROOT).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevtest.o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(TESTER).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevinfo.o udev_utils.o udev_config.o udev_db.o $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(INFO).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevd.o udev_utils.o $(KLIBC_FIXUP) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(DAEMON).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) udevsend.o $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(SENDER).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -#.c.o: -# $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) -c -o $@ $< .c.o: $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< From 9aa0485c97d1b02a39550e3be31c37520a0d0620 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 25 Nov 2004 09:52:19 +0100 Subject: [PATCH 1013/4284] [PATCH] remove archive file if we changed something --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 55c51fd2a8..e966591b52 100644 --- a/Makefile +++ b/Makefile @@ -252,14 +252,17 @@ else endif udev.a: $(UDEV_OBJS) + rm -f $@ $(QUIET) $(AR) cq $@ $(UDEV_OBJS) $(QUIET) $(RANLIB) $@ libsysfs/sysfs.a: $(SYSFS_OBJS) + rm -f $@ $(QUIET) $(AR) cq $@ $(SYSFS_OBJS) $(QUIET) $(RANLIB) $@ klibc_fixups/klibc_fixups.a: $(KLIBC_FIXUP_OBJS) + rm -f $@ $(QUIET) $(AR) cq $@ $(KLIBC_FIXUP_OBJS) $(QUIET) $(RANLIB) $@ From 7757db1f859616171693ed9a54d1d16d3d5ed8e9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 25 Nov 2004 09:55:54 +0100 Subject: [PATCH 1014/4284] [PATCH] don't call dev.d/ scripts twice, if directory = subsystem The /etc/dev.d/input/input.dev was called twice for /dev/input/mouse. Skip the execution if we get a directory named after the subsystem. Move UDEV_NO_DEVD where it belongs. --- udev.c | 4 ++-- udev_multiplex.c | 36 +++++++++++++++++++----------------- udev_start.c | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/udev.c b/udev.c index 9b0a00fb78..5ad7e425e6 100644 --- a/udev.c +++ b/udev.c @@ -180,7 +180,7 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_add_device(&udev, class_dev); /* run dev.d/ scripts if we created a node or changed a netif name */ - if (udev.devname[0] != '\0') { + if (udev_dev_d && udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } @@ -198,7 +198,7 @@ int main(int argc, char *argv[], char *envp[]) setenv("DEVNAME", udev.devname, 1); } /* run dev.d/ scripts if we're not instructed to ignore the event */ - if (udev.devname[0] != '\0') { + if (udev_dev_d && udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } diff --git a/udev_multiplex.c b/udev_multiplex.c index 7e3dc656d6..3a484068ff 100644 --- a/udev_multiplex.c +++ b/udev_multiplex.c @@ -74,26 +74,28 @@ static int run_program(const char *filename, void *data) void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix) { char dirname[PATH_MAX]; - char devname[NAME_SIZE]; - char *temp; - - /* skip if UDEV_NO_DEVD is set */ - if (udev_dev_d == 0) - return; - - strfieldcpy(devname, udev->name); /* chop the device name up into pieces based on '/' */ - temp = strchr(devname, '/'); - while (temp != NULL) { - temp[0] = '\0'; - snprintf(dirname, PATH_MAX, "%s/%s", basedir, devname); - dirname[PATH_MAX-1] = '\0'; - call_foreach_file(run_program, dirname, suffix, udev); + if (udev->name[0] != '\0') { + char devname[NAME_SIZE]; + char *temp; - temp[0] = '/'; - ++temp; - temp = strchr(temp, '/'); + strfieldcpy(devname, udev->name); + temp = strchr(devname, '/'); + while (temp != NULL) { + temp[0] = '\0'; + + /* don't call the subsystem directory here */ + if (strcmp(devname, udev->subsystem) != 0) { + snprintf(dirname, PATH_MAX, "%s/%s", basedir, devname); + dirname[PATH_MAX-1] = '\0'; + call_foreach_file(run_program, dirname, suffix, udev); + } + + temp[0] = '/'; + ++temp; + temp = strchr(temp, '/'); + } } if (udev->name[0] != '\0') { diff --git a/udev_start.c b/udev_start.c index 129af4291a..1a86163cd5 100644 --- a/udev_start.c +++ b/udev_start.c @@ -109,7 +109,7 @@ static int add_device(char *devpath, char *subsystem) udev_add_device(&udev, class_dev); /* run dev.d/ scripts if we created a node or changed a netif name */ - if (udev.devname[0] != '\0') { + if (udev_dev_d && udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } From b1e95455d2683f43f47ea94a7b79af64f0738d36 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 26 Apr 2005 22:52:57 -0700 Subject: [PATCH 1015/4284] fixups to get back to proper patch order Damm, it's hard to merge a multi-line tree into one flat line at times... --- test/udev-test.pl | 4 +--- udev.c | 5 ----- udevinfo.c | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index c2d8e27a52..d584579584 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -35,9 +35,6 @@ my $perm = "udev.permissions"; my $main_conf = "udev-test.conf"; my $conf_tmp = "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 = ( { @@ -1262,6 +1259,7 @@ sub run_test { udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); + if ((-e "$PWD/$udev_root$config->{exp_name}") || (-l "$PWD/$udev_root$config->{exp_name}")) { diff --git a/udev.c b/udev.c index 5ad7e425e6..35fa533a4e 100644 --- a/udev.c +++ b/udev.c @@ -108,7 +108,6 @@ int main(int argc, char *argv[], char *envp[]) udev_init_config(); /* set signal handlers */ - memset(&act, 0x00, sizeof(act)); act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = 0; @@ -193,10 +192,6 @@ int main(int argc, char *argv[], char *envp[]) /* get node from db, remove db-entry, delete created node */ retval = udev_remove_device(&udev); - /* Set the DEVNAME if known */ - if (udev.devname[0] != '\0') { - setenv("DEVNAME", udev.devname, 1); - } /* run dev.d/ scripts if we're not instructed to ignore the event */ if (udev_dev_d && udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); diff --git a/udevinfo.c b/udevinfo.c index 6e6b9aeb3e..fe847b875f 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -401,7 +401,7 @@ print: break; case PATH: - strfieldcpy(result, udev.devpath); + strfieldcpy(result, path); break; case ALL: From 97adaace4f8f89ce175657d3ec71811715cc4dae Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 26 Apr 2005 22:54:32 -0700 Subject: [PATCH 1016/4284] more fixups --- etc/udev/udev.rules.gentoo | 2 +- extras/ide-devfs.sh | 6 +++--- namedev.c | 5 ----- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 997acb8a34..1809232ed0 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -19,7 +19,7 @@ BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYM # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" # dri devices KERNEL="card*", NAME="dri/card%n" diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 580a751abe..4f20259480 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -36,11 +36,11 @@ get_dev_number() { if [ -z "$3" ] && [ -f /proc/ide/${1}/media ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` ${MEDIA} + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` elif [ "${MEDIA}" = "floppy" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc floppies/floppy`get_dev_number $1 floppy`/disc ${MEDIA} + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc floppies/floppy`get_dev_number $1 floppy`/disc elif [ "${MEDIA}" = "disk" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc ${MEDIA} + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc fi else echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/part$3 discs/disc`get_dev_number $1 disk`/part$3 diff --git a/namedev.c b/namedev.c index 126453cc89..8976b8d40a 100644 --- a/namedev.c +++ b/namedev.c @@ -809,11 +809,6 @@ found: udev->partitions = dev->partitions; udev->ignore_remove = dev->ignore_remove; - if (dev->group[0] != '\0') { - strfieldcpy(udev->group, dev->group); - apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); - } - /* get permissions given in rule */ set_empty_perms(udev, dev->mode, dev->owner, From 16ac31aaee34f1085daf1c43a8645b174712b2d4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 25 Nov 2004 10:15:32 +0100 Subject: [PATCH 1017/4284] [PATCH] don't call the hotplug scripts with a test run --- test/udev-test.pl | 1 + udev.c | 2 +- udev.h | 1 + udev_config.c | 8 +++++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index d584579584..593e34e885 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1153,6 +1153,7 @@ $ENV{UDEV_TEST} = "yes"; $ENV{SYSFS_PATH} = $sysfs; $ENV{UDEV_CONFIG_FILE} = $main_conf; $ENV{UDEV_NO_DEVD} = "yes"; +$ENV{UDEV_NO_HOTPLUGD} = "yes"; sub udev { diff --git a/udev.c b/udev.c index 35fa533a4e..3a97eb1046 100644 --- a/udev.c +++ b/udev.c @@ -223,7 +223,7 @@ int main(int argc, char *argv[], char *envp[]) } hotplug: - if (manage_hotplug_event()) + if (udev_hotplug_d && manage_hotplug_event()) udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); exit: diff --git a/udev.h b/udev.h index 1e3db5af27..ace843f0ad 100644 --- a/udev.h +++ b/udev.h @@ -91,5 +91,6 @@ extern char default_owner_str[OWNER_SIZE]; extern char default_group_str[GROUP_SIZE]; extern int udev_log; extern int udev_dev_d; +extern int udev_hotplug_d; #endif diff --git a/udev_config.c b/udev_config.c index 51bdc720a7..9549471b8b 100644 --- a/udev_config.c +++ b/udev_config.c @@ -51,6 +51,7 @@ char default_owner_str[OWNER_SIZE]; char default_group_str[GROUP_SIZE]; int udev_log; int udev_dev_d; +int udev_hotplug_d; static int string_is_true(char *str) @@ -68,7 +69,7 @@ static void init_variables(void) { char *env; - /* fill up the defaults. + /* fill up the defaults. * If any config values are specified, they will * override these values. */ strfieldcpy(udev_root, UDEV_ROOT); @@ -82,6 +83,11 @@ static void init_variables(void) env = getenv("UDEV_NO_DEVD"); if (env && string_is_true(env)) udev_dev_d = 0; + + udev_hotplug_d = 1; + env = getenv("UDEV_NO_HOTPLUGD"); + if (env && string_is_true(env)) + udev_hotplug_d = 0; } int parse_get_pair(char **orig_string, char **left, char **right) From a0294b76252d8c84656218cafd458e6739361247 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 28 Nov 2004 13:41:15 +0100 Subject: [PATCH 1018/4284] [PATCH] update the man pages and correct Usage: hints Add UDEV_LOG to the man udev man page. Remove mention of specific variables from the udevd/udevsend man page as we changed to pass the whole environment. Correct printed Usage: of udevtest and udevinfo. Init the config in udevtest earlier to accept input with and without the sysfs mount point. --- udev.8.in | 20 ++++++++++++-------- udevd.8 | 29 ++++++++++------------------- udevinfo.c | 2 +- udevtest.8 | 3 ++- udevtest.c | 19 ++++++++++--------- 5 files changed, 35 insertions(+), 38 deletions(-) diff --git a/udev.8.in b/udev.8.in index 728ddb1a45..7bdf560970 100644 --- a/udev.8.in +++ b/udev.8.in @@ -4,22 +4,24 @@ udev \- Linux configurable dynamic device naming support .SH SYNOPSIS .BI udev " hotplug-subsystem" .P -The environment must provide the following variables: +The following variables are read from the environment: .TP .B ACTION .IR add " or " remove -signifies the connection or disconnection of a device. -.TP +signifies the addition or the removal of a device. +.P .B DEVPATH The sysfs devpath of the device without the mountpoint but a leading slash. .P -Additional optional environment variables: -.TP +.B SUBSYSTEM +The subsystem the device belongs to. Alternatively the subsystem may +be passed as the first argument. +.P .B UDEV_CONFIG_FILE Overrides the default location of the .B udev config file. -.TP +.P .B UDEV_NO_DEVD The default behavior of .B udev @@ -34,7 +36,6 @@ provides a dynamic device directory containing only the files for actually present devices. It creates or removes device node files usually located in the /dev directory, or it renames network interfaces. .br - .P As part of the .B hotplug @@ -373,9 +374,12 @@ The name of a program must end with suffix, to be recognized. .br In addition to the hotplug environment variables, +.B UDEV_LOG +is set if udev is configured to use the syslog facility. Executed programs may +want to follow that setting. .B DEVNAME is exported to make the name of the created node, or the name the network -device is renamed to, available to the executed program. The programs in every +device is renamed to, available to the executed program. The programs in every directory are sorted in lexical order, while the directories are searched in the following order: .sp diff --git a/udevd.8 b/udevd.8 index 1de7a3cba2..1a5940fef5 100644 --- a/udevd.8 +++ b/udevd.8 @@ -3,19 +3,6 @@ udevd, udevdsend \- udev event serializer daemon and udev event sender .SH SYNOPSIS .BI udevsend " hotplug-subsystem" -.sp -The environment must provide the following variables: -.TP -.B ACTION -.IR add " or " remove -signifies the connection or disconnection of a device. -.TP -.B DEVPATH -The sysfs devpath of the device without the mountpoint but a leading slash. -.TP -.B SEQNUM -The sequence number of the event provided by the kernel. -If unset, the event bypasses the queue and will be executed immediately. .SH "DESCRIPTION" .B udevd allows the serialization of @@ -24,15 +11,19 @@ events. The events generated by the kernel may arrive in random order in userspace, that makes it neccessary to reorder them. .br .B udevd -takes care of the kernel supplied sequence number and arranges the events for -execution in the correct order. Missing sequences delay the execution of the -following events until a timeout is reached. +takes care of the kernel supplied +.B SEQNUM +sequence number and arranges the events for execution in the correct order. +Missing sequences delay the execution of the following events until a timeout +is reached. Events without any sequence number are bypassing the queue and +will be executed immediately. .br For each event a .BR udev (8) -instance is executed in the background. All further events for the same device -are delayed until the execution is finished. This way there will never be more -than one instance running for a single device at the same time. +instance is executed in the background with the complete environment received +by the hotplug event. All further events for the same device are delayed until +the execution is finished. This way there will never be more than one instance +running for a single device at the same time. .br .B udevd receives the events from diff --git a/udevinfo.c b/udevinfo.c index fe847b875f..340496b42b 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -439,7 +439,7 @@ exit: } help: - printf("Usage: [-anpqrdVh]\n" + printf("Usage: udevinfo [-anpqrdVh]\n" " -q TYPE query database for the specified value:\n" " 'name' name of device node\n" " 'symlink' pointing to node\n" diff --git a/udevtest.8 b/udevtest.8 index 6be7e089cf..13b57f03b6 100644 --- a/udevtest.8 +++ b/udevtest.8 @@ -2,7 +2,8 @@ .SH NAME udevtest \- simulates a udev run to test the configured rules .SH SYNOPSIS -.BI udevtest " sysfs_device_path" +.B udevtest +.IR "sysfs_device_path " [ subsystem ] .SH "DESCRIPTION" .B udevtest simulates a diff --git a/udevtest.c b/udevtest.c index 37ec767e13..9cc23f0ac7 100644 --- a/udevtest.c +++ b/udevtest.c @@ -55,19 +55,23 @@ int main(int argc, char *argv[], char *envp[]) char *devpath; char path[SYSFS_PATH_MAX]; char temp[NAME_SIZE]; - char *subsystem = ""; struct udevice udev; + char *subsystem = NULL; info("version %s", UDEV_VERSION); - if (argv[1] == NULL) { - info("udevinfo expects the DEVPATH of the sysfs device as a argument"); + if (argc < 2 || argc > 3) { + info("Usage: udevtest [subsystem]"); return 1; } + /* initialize our configuration */ + udev_init_config(); + /* remove sysfs_path if given */ - if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) - devpath = argv[1] + strlen(sysfs_path); + if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) { + devpath = &argv[1][strlen(sysfs_path)] ; + } else if (argv[1][0] != '/') { /* prepend '/' if missing */ @@ -86,13 +90,10 @@ int main(int argc, char *argv[], char *envp[]) return 2; } - /* initialize our configuration */ - udev_init_config(); - /* initialize the naming deamon */ namedev_init(); - if (argv[2] != NULL) + if (argc == 3) subsystem = argv[2]; /* fill in values and test_run flag*/ From 9a50eb497fa9d54e0dbb249f5a58d3c16bb937d0 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 28 Nov 2004 13:47:36 +0100 Subject: [PATCH 1019/4284] [PATCH] use blacklist on device "remove" and remove dev.d/ call code duplication --- udev.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/udev.c b/udev.c index 3a97eb1046..958fa4eb0a 100644 --- a/udev.c +++ b/udev.c @@ -156,11 +156,11 @@ int main(int argc, char *argv[], char *envp[]) /* wait for sysfs and possibly add node */ dbg("udev add"); - /* skip blacklisted subsystems */ + /* skip subsystems without "dev", but handle net devices */ if (udev.type != 'n' && subsystem_expect_no_dev(udev.subsystem)) { dbg("don't care about '%s' devices", udev.subsystem); goto hotplug; - }; + } snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); class_dev = wait_class_device_open(path); @@ -178,26 +178,25 @@ int main(int argc, char *argv[], char *envp[]) /* name, create node, store in db */ retval = udev_add_device(&udev, class_dev); - /* run dev.d/ scripts if we created a node or changed a netif name */ - if (udev_dev_d && udev.devname[0] != '\0') { - setenv("DEVNAME", udev.devname, 1); - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); - } - sysfs_close_class_device(class_dev); } else if (strcmp(action, "remove") == 0) { /* possibly remove a node */ dbg("udev remove"); - /* get node from db, remove db-entry, delete created node */ - retval = udev_remove_device(&udev); - - /* run dev.d/ scripts if we're not instructed to ignore the event */ - if (udev_dev_d && udev.devname[0] != '\0') { - setenv("DEVNAME", udev.devname, 1); - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); + /* skip subsystems without "dev" */ + if (subsystem_expect_no_dev(udev.subsystem)) { + dbg("don't care about '%s' devices", udev.subsystem); + goto hotplug; } + /* get node from db, remove db-entry, delete created node */ + retval = udev_remove_device(&udev); + } + + /* run dev.d/ scripts if we created/deleted a node or changed a netif name */ + if (udev_dev_d && udev.devname[0] != '\0') { + setenv("DEVNAME", udev.devname, 1); + udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } } else if ((strncmp(devpath, "/devices/", 9) == 0)) { if (strcmp(action, "add") == 0) { From 4497fcbf7159975560b680fd8130adcd414d3d67 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 28 Nov 2004 13:56:22 +0100 Subject: [PATCH 1020/4284] [PATCH] udevsend/udevd handle events without a subsystem Accept event without a subsystem and pass it through udevd. Pass empty environment while starting udevd. --- udevd.c | 3 ++- udevsend.c | 44 ++++++++++++++++++++------------------------ 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/udevd.c b/udevd.c index 06b172bc25..58f5be94bc 100644 --- a/udevd.c +++ b/udevd.c @@ -124,6 +124,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) /* forks event and removes event from run queue when finished */ static void udev_run(struct hotplug_msg *msg) { + char *const argv[] = { "udev", msg->subsystem, NULL }; pid_t pid; pid = fork(); @@ -132,7 +133,7 @@ static void udev_run(struct hotplug_msg *msg) /* child */ close(udevsendsock); logging_close(); - execle(udev_bin, "udev", msg->subsystem, NULL, msg->envp); + execve(udev_bin, argv, msg->envp); dbg("exec of child failed"); _exit(1); break; diff --git a/udevsend.c b/udevsend.c index 341ed4cc36..16174f5e46 100644 --- a/udevsend.c +++ b/udevsend.c @@ -59,6 +59,8 @@ static int start_daemon(void) { pid_t pid; pid_t child_pid; + char *const argv[] = { "udevd", NULL }; + char *const envp[] = { NULL }; pid = fork(); switch (pid) { @@ -67,9 +69,9 @@ static int start_daemon(void) child_pid = fork(); switch (child_pid) { case 0: - /* daemon */ + /* daemon with empty environment */ close(sock); - execl(UDEVD_BIN, "udevd", NULL); + execve(UDEVD_BIN, argv, envp); dbg("exec of daemon failed"); _exit(1); case -1: @@ -90,13 +92,14 @@ static int start_daemon(void) static void run_udev(const char *subsystem) { + char *const argv[] = { "udev", (char *)subsystem, NULL }; pid_t pid; pid = fork(); switch (pid) { case 0: /* child */ - execl(UDEV_BIN, "udev", subsystem, NULL); + execv(UDEV_BIN, argv); dbg("exec of child failed"); _exit(1); break; @@ -116,27 +119,14 @@ int main(int argc, char *argv[], char *envp[]) int loop; struct sockaddr_un saddr; socklen_t addrlen; - const char *subsystem_argv; - int subsystem_env = 0; int bufpos = 0; int retval = 1; int started_daemon = 0; + const char *subsystem = NULL; logging_init("udevsend"); dbg("version %s", UDEV_VERSION); - subsystem_argv = argv[1]; - if (subsystem_argv == NULL) { - dbg("no subsystem"); - goto exit; - } - - /* prevent loops in the scripts we execute */ - if (getenv("MANAGED_EVENT") != NULL) { - dbg("seems that the event source is not the kernel, just exit"); - goto exit; - } - sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { dbg("error getting socket"); @@ -150,7 +140,6 @@ int main(int argc, char *argv[], char *envp[]) addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; memset(&usend_msg, 0x00, sizeof(struct udevsend_msg)); - strcpy(usend_msg.magic, UDEV_MAGIC); /* copy all keys to send buffer */ @@ -165,17 +154,24 @@ int main(int argc, char *argv[], char *envp[]) continue; } - /* older kernels do not have the SUBSYSTEM in the environment */ + /* prevent loops in the scripts we execute */ + if (strncmp(key, "MANAGED_EVENT=", 14) == 0) { + dbg("seems that the event source is not the kernel, just exit"); + goto exit; + } + + /* remember the SUBSYSTEM */ if (strncmp(key, "SUBSYSTEM=", 10) == 0) - subsystem_env = 1; + subsystem = &key[10]; dbg("add '%s' to env[%i] buffer", key, i); strcpy(&usend_msg.envbuf[bufpos], key); bufpos += keylen + 1; } - if (!subsystem_env) { - bufpos += sprintf(&usend_msg.envbuf[bufpos], "SUBSYSTEM=%s", subsystem_argv) + 1; - dbg("add 'SUBSYSTEM=%s' to env[%i] buffer from argv", subsystem_argv, i); + /* older kernels passed the SUBSYSTEM only as the first argument */ + if (!subsystem && argc == 2) { + bufpos += sprintf(&usend_msg.envbuf[bufpos], "SUBSYSTEM=%s", argv[1]) + 1; + dbg("add 'SUBSYSTEM=%s' to env[%i] buffer from argv", argv[1], i); } usend_msg_len = offsetof(struct udevsend_msg, envbuf) + bufpos; @@ -212,7 +208,7 @@ int main(int argc, char *argv[], char *envp[]) fallback: info("unable to connect to event daemon, try to call udev directly"); - run_udev(subsystem_argv); + run_udev(subsystem); exit: if (sock != -1) From 45a7b668eca398831c0cfc39e4237494b3d603e9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 28 Nov 2004 14:01:43 +0100 Subject: [PATCH 1021/4284] [PATCH] remove unused variables Remove udev.bus, cause it's currently unused and newer kernels will pass it in the hotplug environment as PHYSDEVBUS. Remove udev.action, cause it's unused. Rename udev_set_values() to udev_init_device(). --- namedev.c | 2 -- udev.c | 2 +- udev.h | 2 -- udev_start.c | 2 +- udev_utils.c | 5 +---- udev_utils.h | 3 +-- udevtest.c | 2 +- 7 files changed, 5 insertions(+), 13 deletions(-) diff --git a/namedev.c b/namedev.c index 8976b8d40a..c043cf339e 100644 --- a/namedev.c +++ b/namedev.c @@ -708,7 +708,6 @@ try_parent: return -ENODEV; dbg("sysfs_device->path='%s'", sysfs_device->path); dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); - dbg("sysfs_device->bus='%s'", sysfs_device->bus); } } @@ -742,7 +741,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("found devices device: path='%s', bus_id='%s', bus='%s'", sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus); strfieldcpy(udev->bus_id, sysfs_device->bus_id); - strfieldcpy(udev->bus, sysfs_device->bus); } strfieldcpy(udev->kernel_name, class_dev->name); diff --git a/udev.c b/udev.c index 958fa4eb0a..847cc5dade 100644 --- a/udev.c +++ b/udev.c @@ -119,7 +119,7 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to interrupt blocking syscalls */ alarm(ALARM_TIMEOUT); - udev_set_values(&udev, devpath, subsystem, action); + udev_init_device(&udev, devpath, subsystem); if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { dbg("udevstart"); diff --git a/udev.h b/udev.h index ace843f0ad..2c5270a4c3 100644 --- a/udev.h +++ b/udev.h @@ -50,7 +50,6 @@ struct udevice { char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; - char action[ACTION_SIZE]; char name[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; @@ -65,7 +64,6 @@ struct udevice { char config_file[NAME_SIZE]; long config_uptime; char bus_id[SYSFS_NAME_LEN]; - char bus[SYSFS_NAME_LEN]; char program_result[NAME_SIZE]; char kernel_number[NAME_SIZE]; char kernel_name[NAME_SIZE]; diff --git a/udev_start.c b/udev_start.c index 1a86163cd5..8c7a06b5af 100644 --- a/udev_start.c +++ b/udev_start.c @@ -105,7 +105,7 @@ static int add_device(char *devpath, char *subsystem) return -ENODEV; } - udev_set_values(&udev, devpath, subsystem, "add"); + udev_init_device(&udev, devpath, subsystem); udev_add_device(&udev, class_dev); /* run dev.d/ scripts if we created a node or changed a netif name */ diff --git a/udev_utils.c b/udev_utils.c index bdf0233e3a..aa5c75f74d 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -36,8 +36,7 @@ #include "list.h" -void udev_set_values(struct udevice *udev, const char* devpath, - const char *subsystem, const char* action) +void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem) { memset(udev, 0x00, sizeof(struct udevice)); @@ -45,8 +44,6 @@ void udev_set_values(struct udevice *udev, const char* devpath, strfieldcpy(udev->devpath, devpath); if (subsystem) strfieldcpy(udev->subsystem, subsystem); - if (action) - strfieldcpy(udev->action, action); if (strcmp(udev->subsystem, "block") == 0) udev->type = 'b'; diff --git a/udev_utils.h b/udev_utils.h index b9b0fda678..e36255f526 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -76,8 +76,7 @@ do { \ # define asmlinkage /* nothing */ #endif -extern void udev_set_values(struct udevice *udev, const char* devpath, - const char *subsystem, const char* action); +extern void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel); extern int create_path(const char *path); extern int file_map(const char *filename, char **buf, size_t *bufsize); diff --git a/udevtest.c b/udevtest.c index 9cc23f0ac7..38e2bb7562 100644 --- a/udevtest.c +++ b/udevtest.c @@ -97,7 +97,7 @@ int main(int argc, char *argv[], char *envp[]) subsystem = argv[2]; /* fill in values and test_run flag*/ - udev_set_values(&udev, devpath, subsystem, "add"); + udev_init_device(&udev, devpath, subsystem); /* open the device */ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); From 2af003feb21e79b68b048c212bb898b293b75421 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 29 Nov 2004 02:15:55 +0100 Subject: [PATCH 1022/4284] [PATCH] trivial cleanups and change some comments --- udev.c | 11 ++++++++--- udev.h | 8 +++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/udev.c b/udev.c index 847cc5dade..ca79bb4ec0 100644 --- a/udev.c +++ b/udev.c @@ -111,17 +111,22 @@ int main(int argc, char *argv[], char *envp[]) act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = 0; - /* alarm must not restart syscalls*/ sigaction(SIGALRM, &act, NULL); sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); - /* trigger timeout to interrupt blocking syscalls */ + /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); + action = getenv("ACTION"); + devpath = getenv("DEVPATH"); + subsystem = getenv("SUBSYSTEM"); + /* older kernels passed the SUBSYSTEM only as argument */ + if (!subsystem && argc == 2) + subsystem = argv[1]; udev_init_device(&udev, devpath, subsystem); - if (strstr(argv[0], "udevstart") || (argv[1] != NULL && strstr(argv[1], "udevstart"))) { + if (strstr(argv[0], "udevstart") || (argc == 2 && strstr(argv[1], "udevstart"))) { dbg("udevstart"); /* disable all logging, as it's much too slow on some facilities */ diff --git a/udev.h b/udev.h index 2c5270a4c3..0703b884cf 100644 --- a/udev.h +++ b/udev.h @@ -50,14 +50,17 @@ struct udevice { char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; + char name[NAME_SIZE]; + char symlink[NAME_SIZE]; char owner[OWNER_SIZE]; char group[GROUP_SIZE]; + mode_t mode; char type; int major; int minor; - mode_t mode; - char symlink[NAME_SIZE]; + + char devname[NAME_SIZE]; int partitions; int ignore_remove; int config_line; @@ -67,7 +70,6 @@ struct udevice { char program_result[NAME_SIZE]; char kernel_number[NAME_SIZE]; char kernel_name[NAME_SIZE]; - char devname[NAME_SIZE]; int test_run; }; From 927bda379205dfccd2fae8f5c54523230e0771a9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 29 Nov 2004 04:47:59 +0100 Subject: [PATCH 1023/4284] [PATCH] handle /etc/hotplug.d/ only if the event comes from udevd --- udev.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/udev.c b/udev.c index ca79bb4ec0..507f2be943 100644 --- a/udev.c +++ b/udev.c @@ -61,6 +61,10 @@ static int manage_hotplug_event(void) { int fd; int len; + /* false, if we are called directly */ + if (!getenv("MANAGED_EVENT")) + goto exit; + fd = open("/proc/sys/kernel/hotplug", O_RDONLY); if (fd < 0) goto exit; From 5f72c470ad244020f65784c33eb6bcd4ae149403 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 29 Nov 2004 13:44:01 +0100 Subject: [PATCH 1024/4284] [PATCH] simplify permission handling Initialize the defaults in udev_config.c instead of namedev.c. Replace macro by expanded code. Switch to mode_t instead of string value. Add and clarify some comments. --- namedev.c | 108 +++++++++++++++++++++--------------------------- namedev.h | 18 +++----- namedev_parse.c | 14 +++++-- udev.h | 14 +++---- udev_config.c | 37 +++++++++-------- 5 files changed, 90 insertions(+), 101 deletions(-) diff --git a/namedev.c b/namedev.c index c043cf339e..0bc28bd028 100644 --- a/namedev.c +++ b/namedev.c @@ -101,7 +101,7 @@ static int strcmp_pattern(const char *p, const char *s) return 1; } -static struct perm_device *find_perm(char *name) +static struct perm_device *find_perm_entry(const char *name) { struct perm_device *perm; @@ -113,32 +113,6 @@ static struct perm_device *find_perm(char *name) return NULL; } -static mode_t get_default_mode(void) -{ - mode_t mode = 0600; /* default to owner rw only */ - - if (strlen(default_mode_str) != 0) - mode = strtol(default_mode_str, NULL, 8); - - return mode; -} - -static char *get_default_owner(void) -{ - if (strlen(default_owner_str) == 0) - strfieldcpy(default_owner_str, "root"); - - return default_owner_str; -} - -static char *get_default_group(void) -{ - if (strlen(default_group_str) == 0) - strfieldcpy(default_group_str, "root"); - - return default_group_str; -} - /* extract possible {attr} and move str behind it */ static char *get_format_attribute(char **str) { @@ -586,7 +560,8 @@ static int match_place(struct config_device *dev, struct sysfs_class_device *cla return 0; } -static int match_rule(struct config_device *dev, struct sysfs_class_device *class_dev, struct udevice *udev, struct sysfs_device *sysfs_device) +static int match_rule(struct udevice *udev, struct config_device *dev, + struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { while (1) { /* check for matching bus value */ @@ -595,7 +570,8 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas dbg("device has no bus"); goto try_parent; } - dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", dev->bus, sysfs_device->bus); + dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", + dev->bus, sysfs_device->bus); if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { dbg(FIELD_BUS " is not matching"); goto try_parent; @@ -606,7 +582,8 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas /* check for matching kernel name */ if (dev->kernel[0] != '\0') { - dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); + dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", + dev->kernel, class_dev->name); if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { dbg(FIELD_KERNEL " is not matching"); goto try_parent; @@ -617,7 +594,8 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas /* check for matching subsystem */ if (dev->subsystem[0] != '\0') { - dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' class_dev->name='%s'", dev->subsystem, class_dev->name); + dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' class_dev->name='%s'", + dev->subsystem, class_dev->name); if (strcmp_pattern(dev->subsystem, udev->subsystem) != 0) { dbg(FIELD_SUBSYSTEM " is not matching"); goto try_parent; @@ -628,7 +606,8 @@ static int match_rule(struct config_device *dev, struct sysfs_class_device *clas /* check for matching driver */ if (dev->driver[0] != '\0') { - dbg("check for " FIELD_DRIVER " dev->driver='%s' sysfs_device->driver_name='%s'", dev->driver, sysfs_device->driver_name); + dbg("check for " FIELD_DRIVER " dev->driver='%s' sysfs_device->driver_name='%s'", + dev->driver, sysfs_device->driver_name); if (strcmp_pattern(dev->driver, sysfs_device->driver_name) != 0) { dbg(FIELD_DRIVER " is not matching"); goto try_parent; @@ -757,13 +736,15 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d /* look for a matching rule to apply */ list_for_each_entry(dev, &config_device_list, node) { dbg("process rule"); - if (match_rule(dev, class_dev, udev, sysfs_device) == 0) { + if (match_rule(udev, dev, class_dev, sysfs_device) == 0) { + /* empty name and symlink will not create any node */ if (dev->name[0] == '\0' && dev->symlink[0] == '\0') { info("configured rule in '%s' at line %i applied, '%s' is ignored", dev->config_file, dev->config_line, udev->kernel_name); return -1; } + /* collect symlinks for the final matching rule */ if (dev->symlink[0] != '\0') { char temp[NAME_SIZE]; @@ -776,6 +757,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d strfieldcat(udev->symlink, temp); } + /* rule matches */ if (dev->name[0] != '\0') { /* apply all_partitions flag only at a main block device */ if (dev->partitions > 0 && @@ -784,45 +766,51 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", dev->config_file, dev->config_line, udev->kernel_name, dev->name); + strfieldcpy(udev->name, dev->name); - goto found; + apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + strfieldcpy(udev->config_file, dev->config_file); + udev->config_line = dev->config_line; + udev->ignore_remove = dev->ignore_remove; + + if (udev->type == 'n') + goto done; + + udev->partitions = dev->partitions; + udev->mode = dev->mode; + strfieldcpy(udev->owner, dev->owner); + strfieldcpy(udev->group, dev->group); + + goto perms; } } } - /* no rule was found so we use the kernel name */ + + /* no rule matched, so we use the kernel name */ strfieldcpy(udev->name, udev->kernel_name); - if (udev->type == 'n') - goto done; - else - goto perms; - -found: - apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - strfieldcpy(udev->config_file, dev->config_file); - udev->config_line = dev->config_line; if (udev->type == 'n') goto done; - udev->partitions = dev->partitions; - udev->ignore_remove = dev->ignore_remove; - - /* get permissions given in rule */ - set_empty_perms(udev, dev->mode, - dev->owner, - dev->group); - perms: - /* get permissions given in config file or set defaults */ - perm = find_perm(udev->name); + /* apply permissions from permissions file to empty fields */ + perm = find_perm_entry(udev->name); if (perm != NULL) { - set_empty_perms(udev, perm->mode, - perm->owner, - perm->group); + if (udev->mode == 0000) + udev->mode = perm->mode; + if (udev->owner[0] == '\0') + strfieldcpy(udev->owner, perm->owner); + if (udev->group[0] == '\0') + strfieldcpy(udev->group, perm->group); } - set_empty_perms(udev, get_default_mode(), - get_default_owner(), - get_default_group()); + + /* apply permissions from config to empty fields */ + if (udev->mode == 0000) + udev->mode = default_mode; + if (udev->owner[0] == '\0') + strfieldcpy(udev->owner, default_owner); + if (udev->group[0] == '\0') + strfieldcpy(udev->group, default_group); dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); diff --git a/namedev.h b/namedev.h index 8e552c8568..e29279243b 100644 --- a/namedev.h +++ b/namedev.h @@ -60,14 +60,6 @@ struct sysfs_class_device; #define RULEFILE_SUFFIX ".rules" #define PERMFILE_SUFFIX ".permissions" -#define set_empty_perms(dev, m, o, g) \ - if (dev->mode == 0) \ - dev->mode = m; \ - if (dev->owner[0] == '\0') \ - strfieldcpy(dev->owner, o); \ - if (dev->group[0] == '\0') \ - strfieldcpy(dev->group, g); - struct sysfs_pair { char file[FILE_SIZE]; char value[VALUE_SIZE]; @@ -87,9 +79,9 @@ struct config_device { char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; - char owner[OWNER_SIZE]; - char group[GROUP_SIZE]; - unsigned int mode; + char owner[USER_SIZE]; + char group[USER_SIZE]; + mode_t mode; int partitions; int ignore_remove; char config_file[NAME_SIZE]; @@ -100,8 +92,8 @@ struct perm_device { struct list_head node; char name[NAME_SIZE]; - char owner[OWNER_SIZE]; - char group[GROUP_SIZE]; + char owner[USER_SIZE]; + char group[USER_SIZE]; unsigned int mode; }; diff --git a/namedev_parse.c b/namedev_parse.c index d39141bfc7..5b8c5ab2d6 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -79,12 +79,19 @@ static int add_perm_dev(struct perm_device *new_dev) struct perm_device *dev; struct perm_device *tmp_dev; - /* update the values if we already have the device */ + /* if we already have that entry, just update the values */ list_for_each_entry(dev, &perm_device_list, node) { if (strcmp(new_dev->name, dev->name) != 0) continue; - set_empty_perms(dev, new_dev->mode, new_dev->owner, new_dev->group); + /* don't overwrite values from earlier entries */ + if (dev->mode == 0000) + dev->mode = new_dev->mode; + if (dev->owner[0] == '\0') + strfieldcpy(dev->owner, new_dev->owner); + if (dev->owner[0] == '\0') + strfieldcpy(dev->group, new_dev->group); + return 0; } @@ -95,7 +102,8 @@ static int add_perm_dev(struct perm_device *new_dev) memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); list_add_tail(&tmp_dev->node, &perm_device_list); - //dump_perm_dev(tmp_dev); + /* dump_perm_dev(tmp_dev); */ + return 0; } diff --git a/udev.h b/udev.h index 0703b884cf..cff991e57a 100644 --- a/udev.h +++ b/udev.h @@ -30,9 +30,7 @@ #define COMMENT_CHARACTER '#' #define NAME_SIZE 256 -#define OWNER_SIZE 32 -#define GROUP_SIZE 32 -#define MODE_SIZE 8 +#define USER_SIZE 32 #define ACTION_SIZE 32 #define DEVPATH_SIZE 256 @@ -53,8 +51,8 @@ struct udevice { char name[NAME_SIZE]; char symlink[NAME_SIZE]; - char owner[OWNER_SIZE]; - char group[GROUP_SIZE]; + char owner[USER_SIZE]; + char group[USER_SIZE]; mode_t mode; char type; int major; @@ -86,9 +84,9 @@ extern char udev_db_path[PATH_MAX+NAME_MAX]; extern char udev_permissions_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; -extern char default_mode_str[MODE_SIZE]; -extern char default_owner_str[OWNER_SIZE]; -extern char default_group_str[GROUP_SIZE]; +extern mode_t default_mode; +extern char default_owner[USER_SIZE]; +extern char default_group[USER_SIZE]; extern int udev_log; extern int udev_dev_d; extern int udev_hotplug_d; diff --git a/udev_config.c b/udev_config.c index 9549471b8b..62eb728ea3 100644 --- a/udev_config.c +++ b/udev_config.c @@ -46,15 +46,15 @@ char udev_db_path[PATH_MAX+NAME_MAX]; char udev_permissions_filename[PATH_MAX+NAME_MAX]; char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; -char default_mode_str[MODE_SIZE]; -char default_owner_str[OWNER_SIZE]; -char default_group_str[GROUP_SIZE]; +mode_t default_mode; +char default_owner[USER_SIZE]; +char default_group[USER_SIZE]; int udev_log; int udev_dev_d; int udev_hotplug_d; -static int string_is_true(char *str) +static int string_is_true(const char *str) { if (strcasecmp(str, "true") == 0) return 1; @@ -67,16 +67,19 @@ static int string_is_true(char *str) static void init_variables(void) { - char *env; + const char *env; + + /* If any config values are specified, they will override these values. */ + strcpy(udev_root, UDEV_ROOT); + strcpy(udev_db_path, UDEV_DB); + strcpy(udev_config_filename, UDEV_CONFIG_FILE); + strcpy(udev_rules_filename, UDEV_RULES_FILE); + strcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); + + strcpy(default_owner, "root"); + strcpy(default_group, "root"); + default_mode = 0600; - /* fill up the defaults. - * If any config values are specified, they will - * override these values. */ - strfieldcpy(udev_root, UDEV_ROOT); - strfieldcpy(udev_db_path, UDEV_DB); - strfieldcpy(udev_config_filename, UDEV_CONFIG_FILE); - strfieldcpy(udev_rules_filename, UDEV_RULES_FILE); - strfieldcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); udev_log = string_is_true(UDEV_LOG_DEFAULT); udev_dev_d = 1; @@ -210,17 +213,17 @@ static int parse_config_file(void) } if (strcasecmp(variable, "default_mode") == 0) { - strfieldcpy(default_mode_str, value); + default_mode = strtol(value, NULL, 8); continue; } if (strcasecmp(variable, "default_owner") == 0) { - strfieldcpy(default_owner_str, value); + strfieldcpy(default_owner, value); continue; } if (strcasecmp(variable, "default_group") == 0) { - strfieldcpy(default_group_str, value); + strfieldcpy(default_group, value); continue; } @@ -274,7 +277,7 @@ static void get_dirs(void) dbg("udev_db_path = %s", udev_db_path); dbg("udev_rules_filename = %s", udev_rules_filename); dbg("udev_permissions_filename = %s", udev_permissions_filename); - dbg("udev_log_str = %d", udev_log); + dbg("udev_log = %d", udev_log); } void udev_init_config(void) From 3fd7a9bfc068a5598a97de5e4b4fff167917f362 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 29 Nov 2004 13:51:20 +0100 Subject: [PATCH 1025/4284] [PATCH] remove unused timestamp field --- namedev.c | 12 +++--------- udev.h | 1 - 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/namedev.c b/namedev.c index 0bc28bd028..7045637e79 100644 --- a/namedev.c +++ b/namedev.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "libsysfs/sysfs/libsysfs.h" #include "list.h" @@ -697,7 +696,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d struct sysfs_device *sysfs_device = NULL; struct config_device *dev; struct perm_device *perm; - struct sysinfo info; char *pos; udev->mode = 0; @@ -774,7 +772,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d udev->ignore_remove = dev->ignore_remove; if (udev->type == 'n') - goto done; + goto exit; udev->partitions = dev->partitions; udev->mode = dev->mode; @@ -790,7 +788,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d strfieldcpy(udev->name, udev->kernel_name); if (udev->type == 'n') - goto done; + goto exit; perms: /* apply permissions from permissions file to empty fields */ @@ -815,11 +813,7 @@ perms: dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", udev->name, udev->owner, udev->group, udev->mode); -done: - /* store time of action */ - sysinfo(&info); - udev->config_uptime = info.uptime; - +exit: return 0; } diff --git a/udev.h b/udev.h index cff991e57a..7038376b3c 100644 --- a/udev.h +++ b/udev.h @@ -63,7 +63,6 @@ struct udevice { int ignore_remove; int config_line; char config_file[NAME_SIZE]; - long config_uptime; char bus_id[SYSFS_NAME_LEN]; char program_result[NAME_SIZE]; char kernel_number[NAME_SIZE]; From d2fe701e9c312be019118d0cc7326d3466164159 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 30 Nov 2004 11:36:36 +0100 Subject: [PATCH 1026/4284] [PATCH] add "pcmcia" and "fc_transport" to the wait_for_sysfs lists --- udev_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 6655968433..ada413c484 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -51,6 +51,7 @@ static const struct subsystem_file { { .subsystem = "ieee1394", .file = NULL }, { .subsystem = "ieee1394_host", .file = NULL }, { .subsystem = "ieee1394_node", .file = NULL }, + { .subsystem = "fc_transport", .file = "port_id" }, { NULL, NULL } }; @@ -274,6 +275,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "ide", .file = "detach_state" }, { .bus = "pci", .file = "vendor" }, { .bus = "platform", .file = "detach_state" }, + { .bus = "pcmcia", .file = "detach_state" }, { .bus = "i2c", .file = "detach_state" }, { .bus = "ieee1394", .file = "node_count" }, { .bus = "ieee1394", .file = "nodeid" }, From f2503c9792555e72f3a6ffedaf9dc6413fb12376 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 2 Dec 2004 19:30:23 +0100 Subject: [PATCH 1027/4284] [PATCH] add net/nlv* devices to the exception list --- udev_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index ada413c484..1c7cb16d93 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -171,6 +171,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "bnep" }, { .subsystem = "net", .device = "vmnet" }, { .subsystem = "net", .device = "ippp" }, + { .subsystem = "net", .device = "nlv" }, { .subsystem = "ppp", .device = NULL }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, From e1b7e62a2676bf679f3eae8997caf0ea703e573d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 5 Dec 2004 15:03:43 +0100 Subject: [PATCH 1028/4284] [PATCH] add net/atml and class/ppdev to the wait_for_sysfs exception list --- udev_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 1c7cb16d93..5f7c63d31d 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -172,9 +172,11 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "net", .device = "vmnet" }, { .subsystem = "net", .device = "ippp" }, { .subsystem = "net", .device = "nlv" }, + { .subsystem = "net", .device = "atml" }, { .subsystem = "ppp", .device = NULL }, { .subsystem = "sound", .device = NULL }, { .subsystem = "printer", .device = "lp" }, + { .subsystem = "ppdev", .device = NULL }, { .subsystem = "nvidia", .device = NULL }, { .subsystem = "video4linux", .device = "vbi" }, { .subsystem = "dvb", .device = NULL }, From 8e2bf855bddfb8df2b61ad78cb082b7bf2af317e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 5 Dec 2004 15:07:39 +0100 Subject: [PATCH 1029/4284] [PATCH] fix udev-test/udev-test.pl to work with again --- test/udevd-test/udevd-test.pl | 97 ++++++++++++++++------------------- 1 file changed, 43 insertions(+), 54 deletions(-) diff --git a/test/udevd-test/udevd-test.pl b/test/udevd-test/udevd-test.pl index 060c3ec5f2..e81aadd938 100644 --- a/test/udevd-test/udevd-test.pl +++ b/test/udevd-test/udevd-test.pl @@ -5,11 +5,10 @@ # Copyright (C) Intel Corp, 2004 # # Author: Yin Hu -# Kay Sievers # # Provides automated testing of the udevd binary.This test script is self-contained. # Before you run this script please modify $sysfs to locate your sysfs filesystem, -# modify $udevd_bin to locate your udevsend binary, +# modify $udevsend_bin to locate your udevsend binary, # modify $udev_bin to locate dummy udev script, # modify $udev_bin2 to locate another dummy udev script ( amplify the execution time for test), # modify $log_file to locate where udev script have placed the log file, @@ -38,42 +37,52 @@ use warnings; use strict; # modifiable settings -my $sysfs = "../sys"; -my $udevd_bin = "../../udevsend"; -my $udev_bin = "$ENV{PWD}/udev-log-script.pl"; -my $udev_bin2 = "$ENV{PWD}/udev-log-amplify.pl"; -my $log_file = "/tmp/udev_log.txt"; -my $time_out = 10; -my $udev_exe_time = 5; +my $sysfs = "../sys"; +my $udevd_bin = "../../udevd"; +my $udevsend_bin = "../../udevsend"; +my $udev_bin = "$ENV{'PWD'}/udev-log-script.pl"; +my $udev_bin2 = "$ENV{'PWD'}/udev-log-amplify.pl"; +my $log_file = "/tmp/udev_log.txt"; +my $time_out = 10; +my $udev_exe_time = 5; # global variables my $test_case = 0; # common functions -sub kill_daemon { +sub restart_daemon { + my ($udev_binary) = @_; + system("killall udevd"); system("rm -f $log_file"); sleep 1; + + if (!defined($udev_binary)) { + $udev_binary = $udev_bin; + } + + $ENV{'UDEV_BIN'} = $udev_binary; + system("/bin/sh -c $udevd_bin&"); + sleep(1); } sub udevsend { # This function prepares corresponding environment variables - # and then call $udevd_bin to send event. + # and then call $udevsend_bin to send event. - my ($seqnum, $devpath, $action, $subsystem, $udev_bin_tmp) = @_; + my ($seqnum, $devpath, $action, $subsystem, $script) = @_; + + %ENV = (); + $ENV{'DEVPATH'} = $devpath; + $ENV{'ACTION'} = $action; + $ENV{'SUBSYSTEM'} = $subsystem; - $ENV{DEVPATH} = $devpath; - $ENV{ACTION} = $action; - $udev_bin_tmp = $udev_bin if ( not $udev_bin_tmp ); - $ENV{UDEV_BIN} = $udev_bin_tmp; if ( $seqnum != -1) { $ENV{SEQNUM} = $seqnum; - } else { - delete $ENV{SEQNUM}; } - return system("$udevd_bin $subsystem"); + return system("$udevsend_bin $subsystem"); } sub getDate { @@ -153,7 +162,7 @@ sub check_count_and_time { print " forking udev time: $line_items[-1]"; $diff = cmpDate($line_items[-1], $event_recv_time); print " the delay time is: $diff s \n\n"; - if ( $diff > $time_out ) { + if ( $diff > $time_out+10 ) { print " the delay time is: $diff \n"; print " udevd doesn't act properly. \n"; exit 1; @@ -293,13 +302,12 @@ sub run_no_seq_test { print " the delay time between event receiving and forking udev for udevd should be negligible, \n"; print " that is, udev should be forked at once. please notice the following time...\n\n"; - # local variables my $time; # # add devices event test # - kill_daemon(); + restart_daemon(); # check if devices /block/sda exist check_sysfs_device_exist("$sysfs/block/sda"); @@ -307,7 +315,6 @@ sub run_no_seq_test { # log current system date/time $time = getDate(); - # fork udevd udevsend(-1, "/block/sda", "add", "block"); # check if execution is successful in time @@ -323,7 +330,6 @@ sub run_no_seq_test { # log current system date/time $time = getDate(); - # fork udevd udevsend(-1, "/block/sda", "remove", "block"); # check if execution is successful in time @@ -342,15 +348,13 @@ sub run_normal_seq_test { print " event to udev for each device. \n"; print " We can see the delay time for each device should be negligible. \n\n"; - # local variables my @file_list; my $file; my $seq = 0; my $time; my $ret_seq; - # prepare - kill_daemon(); + restart_daemon(); @file_list = glob "$sysfs/class/tty/*"; # log current system date/time for device add events @@ -373,7 +377,7 @@ sub run_normal_seq_test { # we'd better wait the udev to create all the device for a few seconds print " wait for udevd processing about $time_out s... \n\n"; - sleep $time_out; + sleep $time_out + 5; $ret_seq = check_count_and_time($time); if ( $ret_seq != $seq ) { @@ -390,7 +394,7 @@ sub run_normal_seq_test { # remove devices event test # print "remove device events test: \n"; - kill_daemon(); + restart_daemon(); @file_list = glob "$sysfs/class/tty/*"; $seq = 0; foreach $file (@file_list) { @@ -406,7 +410,7 @@ sub run_normal_seq_test { # we'd better wait the udev to create all the device for a few seconds print " waiting for udev removing devices (about $time_out s)...\n"; - sleep $time_out; + sleep $time_out + 5; # show results $ret_seq = check_count_and_time($time); @@ -427,7 +431,6 @@ sub run_random_seq_test { print " We have disordered the events sent to udevd, if udevd can order them correctly, the devices' \n"; print " add/remove sequence should be tty0, tty1, tty2. \n\n"; - # local variables my $time; # check if devices /class/tty/tty0, tty1, tty2 exist @@ -437,7 +440,7 @@ sub run_random_seq_test { # add device events test # print "add device events test: \n"; - kill_daemon(); + restart_daemon(); # log current system date/time for device remove events $time = getDate(); @@ -454,12 +457,11 @@ sub run_random_seq_test { # remove device events test # print "\nremove device events test: \n"; - kill_daemon(); + restart_daemon(); # log current system date/time for device remove events $time = getDate(); - # fork udevd udevsend(3, "/class/tty/tty2", "remove", "tty"); udevsend(2, "/class/tty/tty1", "remove", "tty"); udevsend(1, "/class/tty/tty0", "remove", "tty"); @@ -481,14 +483,12 @@ sub run_expected_seq_test { print " should fork udev immediately, the delay time should be negligible. \n"; print " where: event 7 is (add device /class/tty/tty2) \n\n"; - # local variables my $time; # check if devices /class/tty0, tty1, tty2 exist check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2"); - # prepare - kill_daemon(); + restart_daemon(); # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem udevsend(3, "/class/tty/tty2", "add", "tty"); @@ -499,7 +499,7 @@ sub run_expected_seq_test { udevsend(6, "/class/tty/tty2", "remove", "tty"); print " wait for udevd timing out for disorder events (about $time_out s) \n\n"; - sleep $time_out+1; + sleep $udev_exe_time + $time_out+1; system("rm -f $log_file"); # log current system date/time for device remove events @@ -527,11 +527,9 @@ sub run_single_instance_test { print " we send a add event for device /block/sda, and then we send a remove event, so the \n"; print " execution of remove event should be delayed until add is finished. \n\n"; - # local variables my $time; - # prepare - kill_daemon(); + restart_daemon($udev_bin2); # check if device exists check_sysfs_device_exist("$sysfs/block/sda"); @@ -539,9 +537,8 @@ sub run_single_instance_test { # log current system date/time $time = getDate(); - # fork udved - udevsend(-1, "/block/sda", "add", "block", $udev_bin2); - udevsend(-1, "/block/sda", "remove", "block", $udev_bin2); + udevsend(-1, "/block/sda", "add", "block"); + udevsend(-1, "/block/sda", "remove", "block"); # show results print " wait for udevd processing about $udev_exe_time s... \n\n"; @@ -560,16 +557,13 @@ sub run_same_events_test { print " event ( add device /class/tty/tty1 ) should be delayed for $time_out s than its previous \n"; print " event ( remove device /block/sda ) \n\n"; - # local variables my $time; - # prepare - kill_daemon(); + restart_daemon(); # check if device exist check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1"); - # fork udevd udevsend(0, "/block/sda", "add", "block"); # log current system date/time @@ -577,7 +571,6 @@ sub run_same_events_test { $time = getDate(); system("rm -f $log_file"); - # fork udevd udevsend(1, "/block/sda", "remove", "block"); udevsend(1, "/class/tty/tty1", "add", "tty"); @@ -595,16 +588,13 @@ sub run_missing_seq_test { print "Test expected visible results:\n"; print " the delay time for event(add device /block/sda) should be about $time_out s.\n\n"; - # local variables my $time; - # prepare - kill_daemon(); + restart_daemon(); # check if device exist check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1"); - # fork udevd udevsend(0, "/class/tty/tty1", "add", "tty"); udevsend(1, "/class/tty/tty1", "remove", "tty"); sleep 1; @@ -613,7 +603,6 @@ sub run_missing_seq_test { $time = getDate(); system("rm -f $log_file"); - # fork udevd udevsend(3, "/block/sda", "add", "block"); # show results From e608ba5d457c8876da58e3877da21d014d4868e0 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 5 Dec 2004 16:31:51 +0100 Subject: [PATCH 1030/4284] [PATCH] make gcov compile scripts working with recent gcc --- make_gcov.sh | 10 +++++----- run_gcov.sh | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/make_gcov.sh b/make_gcov.sh index 907c1ebd48..4d5f63f1dd 100644 --- a/make_gcov.sh +++ b/make_gcov.sh @@ -16,16 +16,16 @@ # clean up udev dir clean_udev () { - find -name "*.da" -exec rm -f "{}" \; - find -name "*.bb" -exec rm -f "{}" \; - find -name "*.bbg" -exec rm -f "{}" \; + find -name "*.gcno" -exec rm -f "{}" \; + find -name "*.gcda" -exec rm -f "{}" \; find -name "*.gcov" -exec rm -f "{}" \; + rm -f udev_gcov.txt make clean } PWD=`pwd` GCCINCDIR=`gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"` -LIBSYSFS="-I$PWD/libsysfs" +LIBSYSFS="-I$PWD/libsysfs/sysfs -I$PWD/libsysfs" WARNINGS="-Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations" GCC="-I$GCCINCDIR" USE_LOG="-DLOG" @@ -50,4 +50,4 @@ done clean_udev -make $* CFLAGS="$WARNINGS $GCOV_FLAGS $USE_LOG $DEBUG $GCC $LIBSYSFS" +make $* CFLAGS="$WARNINGS $GCOV_FLAGS $USE_LOG $DEBUG $GCC $LIBSYSFS" LDFLAGS="-Wl,-warn-common -fprofile-arcs" diff --git a/run_gcov.sh b/run_gcov.sh index 4fe936199f..ad6a62b130 100644 --- a/run_gcov.sh +++ b/run_gcov.sh @@ -23,12 +23,12 @@ echo > udev_gcov.txt echo "CODE COVERAGE ANALYSIS FOR UDEV" >> udev_gcov.txt echo >> udev_gcov.txt -for file in `find -maxdepth 1 -name "*.bb"`; do - name=`basename $file .bb` +for file in `find -maxdepth 1 -name "*.gcno"`; do + name=`basename $file .gcno` echo "################" >> udev_gcov.txt echo "$name.c" >> udev_gcov.txt echo "################" >> udev_gcov.txt - if [ -e "$name.da" ]; then + if [ -e "$name.gcda" ]; then gcov -l "$name.c" >> udev_gcov.txt 2>&1 else echo "code for $name.c was never executed" >> udev_gcov.txt 2>&1 From 0ba5bb106b19d808c2e68af4ff34740854f78290 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 7 Dec 2004 22:38:40 +0100 Subject: [PATCH 1031/4284] [PATCH] restore OWNER/GROUP assignment in rule coming from RESULT --- namedev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 7045637e79..9cfc4283be 100644 --- a/namedev.c +++ b/namedev.c @@ -665,8 +665,7 @@ static int match_rule(struct udevice *udev, struct config_device *dev, /* check for matching result of external program */ if (dev->result[0] != '\0') { - dbg("check for " FIELD_RESULT - " dev->result='%s', udev->program_result='%s'", + dbg("check for " FIELD_RESULT " dev->result='%s', udev->program_result='%s'", dev->result, udev->program_result); if (strcmp_pattern(dev->result, udev->program_result) != 0) { dbg(FIELD_RESULT " is not matching"); @@ -777,7 +776,9 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d udev->partitions = dev->partitions; udev->mode = dev->mode; strfieldcpy(udev->owner, dev->owner); + apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); strfieldcpy(udev->group, dev->group); + apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); goto perms; } From c64081980e7dc693327ad18995bc25e3eec61eea Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 7 Dec 2004 22:45:36 +0100 Subject: [PATCH 1032/4284] [PATCH] don't install distribution specific init script on "make install" Leave that part up to the one who itegrates udev into a system as there is much more to care of than to call a init stript for a dynamic dev. --- Makefile | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Makefile b/Makefile index e966591b52..6494c1bf19 100644 --- a/Makefile +++ b/Makefile @@ -374,14 +374,6 @@ small_release: $(DISTFILES) spotless @rm -rf $(DISTDIR) @echo "Built $(RELEASE_NAME).tar.gz" - -install-initscript: etc/init.d/udev etc/init.d/udev.init.LSB - @if [ -f /etc/redhat-release ]; then \ - $(INSTALL_DATA) -D etc/init.d/udev $(DESTDIR)$(initdir)/udev; \ - elif [ -f /etc/SuSE-release ]; then \ - $(INSTALL_DATA) -D etc/init.d/udev.init.LSB $(DESTDIR)$(initdir)/udev; \ - fi - install-config: $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d $(INSTALL) -d $(DESTDIR)$(configdir)/permissions.d @@ -424,7 +416,7 @@ uninstall-man: - rm $(mandir)/man8/udevd.8 - rm $(mandir)/man8/udevsend.8 -install: install-initscript install-config install-man install-dev.d all +install: install-config install-man install-dev.d all $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) @@ -452,7 +444,6 @@ uninstall: uninstall-man uninstall-dev.d - rmdir $(configdir)/rules.d - rmdir $(configdir)/permissions.d - rmdir $(configdir) - - rm $(initdir)/udev - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) From e4b5f339c7b63e9f67fccf2d0ef549ca34d56a7d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 7 Dec 2004 22:55:08 +0100 Subject: [PATCH 1033/4284] [PATCH] update Fedora dev.d/ example and remove unused conf.d/ directory --- etc/conf.d/udev | 11 ------ etc/dev.d/default/pam_console.dev | 56 +++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 22 deletions(-) delete mode 100644 etc/conf.d/udev diff --git a/etc/conf.d/udev b/etc/conf.d/udev deleted file mode 100644 index 50eda3a970..0000000000 --- a/etc/conf.d/udev +++ /dev/null @@ -1,11 +0,0 @@ -# if selinux file attributes -# should be restored (leave to yes, if unsure) -UDEV_SELINUX="yes" - -# if console permissions (pam_console) -# should be restored (leave to yes, if unsure) -UDEV_CONSOLE="yes" - -# if dbus messages should be sent -UDEV_DBUS="no" - diff --git a/etc/dev.d/default/pam_console.dev b/etc/dev.d/default/pam_console.dev index 563051d7f6..4c69ea3576 100644 --- a/etc/dev.d/default/pam_console.dev +++ b/etc/dev.d/default/pam_console.dev @@ -1,18 +1,52 @@ #!/bin/sh -if [ -f /etc/sysconfig/udev ]; then - . /etc/sysconfig/udev -fi +# Fedora solution to set the ownership/permissions of s device to the local +# logged in user. Uses the program pam_console_setowner to match the names of +# the device node and the symlinks against a device list and applies the +# configured ownership and permission to the node. -if [ -f /etc/conf.d/udev ]; then - . /etc/conf.d/udev -fi +[ "$ACTION" != "add" ] && exit 0 -[ "$UDEV_CONSOLE" != "yes" ] && exit 0 +# we do not have console users in rc.sysinit +[ -n "$IN_INITLOG" ] && exit 0 -if [ -x /sbin/pam_console_setowner ]; then - if [ "$UDEV_LOG" = "yes" ] && [ -x /usr/bin/logger ]; then - /usr/bin/logger -p auth.debug "Restoring console permissions for $DEVNAME" +if [ -x /sbin/pam_console_setowner -a -f /var/run/console/console.lock \ + -a -e "$DEVNAME" ]; then + + if [ -x /usr/bin/logger ]; then + LOGGER=/usr/bin/logger + elif [ -x /bin/logger ]; then + LOGGER=/bin/logger + else + unset LOGGER fi - exec /sbin/pam_console_setowner $DEVNAME + # + # for diagnostics + # + if [ -t 1 -o -z "$LOGGER" ]; then + mesg () { + echo "$@" + } + else + mesg () { + $LOGGER -t $(basename $0)"[$$]" "$@" + } + fi + + debug_mesg () { + test "$udev_log" = "" -o "$udev_log" = "no" && return + mesg "$@" + } + + if [ -f /etc/udev/udev.conf ]; then + . /etc/udev/udev.conf + fi + + SYMLINKS="" + for i in $(/usr/bin/udevinfo -q symlink -p "$DEVPATH"); do + [ $? -gt 0 ] && break + SYMLINKS="$SYMLINKS ${udev_root%%/}/$i" + done + debug_mesg "Restoring console permissions for $DEVNAME $SYMLINKS" + /sbin/pam_console_setowner "$DEVNAME" $SYMLINKS fi From 5bc597fecaf6a2535aa4b66a21e609e80cfefcb1 Mon Sep 17 00:00:00 2001 From: "klauser@access.unizh.ch" Date: Tue, 7 Dec 2004 23:01:44 +0100 Subject: [PATCH 1034/4284] [PATCH] Various typos and other litte errors in udev.8.in Thanks-To: Tobias Klauser While crawling through the udev manpage I noticed some typos and other grammatical errors. English is not my native language, so I'm not sure if I fixed everything right. I would be glad if any English-speaking person could check this patch before applying. --- udev.8.in | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/udev.8.in b/udev.8.in index 7bdf560970..07bd7bce30 100644 --- a/udev.8.in +++ b/udev.8.in @@ -58,7 +58,7 @@ queries its database for the name of the device file to be deleted. All .B udev configuration files consist of a set of lines of text. All empty -lines and lines beginning with a '#' will be ignored. +lines or lines beginning with '#' will be ignored. .P .B udev @@ -91,22 +91,22 @@ All permission files are read in lexical order. The default value is .IR /etc/udev/permissions.d/ . .TP .B udev_log -The switch, if udev logs some information for every device handled. +The switch to enable/disable logging of udev information The default value is .IR yes . .TP .B default_mode -The default mode for all nodes not explicitely matching in the permissions +The default mode for all nodes not explicitly matching in the permissions file. The default value is .IR 0666 . .TP .B default_owner -The default owner for all nodes not explicitely matching in the permissions +The default owner for all nodes not explicitly matching in the permissions file. The default value is .IR root . .TP .B default_group -The default group for all nodes not explicitely matching in the permissions +The default group for all nodes not explicitly matching in the permissions file. The default value is .IR root . .br @@ -132,19 +132,19 @@ udev_permissions="/etc/udev/udev.permissions" udev_log="yes" # default_mode - set the default mode for all nodes not -# explicitely matching in the permissions file +# explicitly matching in the permissions file default_mode="0666" # default_owner - set the default owner for all nodes not -# explicitely matching in the permissions file +# explicitly matching in the permissions file default_owner="root" # default_group - set the default group for all nodes not -# explicitely matching in the permissions file +# explicitly matching in the permissions file default_group="root" .fi .P -The rules for device naming, are read from the files located in the +The rules for device naming are read from the files located in the .I /etc/udev/rules.d/ directory, or at the location specified by the .I udev_rules @@ -230,10 +230,10 @@ The name of a symlink targeting the node. Multiple symlinks may be specified by separating the names by the space character. .br If both the name and the symlink fields are omitted or its -values empty, the device will be ignored and no node will be created. +values are empty, the device will be ignored and no node will be created. .br If only the symlink field is given and the name field is omitted, -the rule will not be applied immediatly, but the symlink field is added +the rule will not be applied immediately, but the symlink field is added to the symlink list of the rule which will create the node. This makes it possible to specify additional symlinks in a possibly separate rules file, while the device nodes are maintained by the @@ -244,7 +244,7 @@ The permissions for this device. Every specified value overwrites the value given in the permissions file. .P .RB "The " NAME " ," SYMLINK " and " PROGRAM -fields support simple printf-like string substitution: +fields support simple printf-like string substitutions: .TP .B %n The "kernel number" of the device. @@ -263,7 +263,7 @@ The kernel minor number for the device. The bus id for the device. .TP .B %c -The string returned from the execution of +The string returned by the external program, specified in .B PROGRAM (This does not work within the .B PROGRAM @@ -296,7 +296,7 @@ the first three characters of the sysfs attribute. .RI "A sample " udev.rules " might look like this:" .sp .nf -# if /sbin/scsi_id returns "OEM 0815" device will be called disk1 +# if /sbin/scsi_id returns "OEM 0815", the device will be called disk1 BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="OEM 0815", NAME="disk1" # USB printer to be called lp_color @@ -326,7 +326,7 @@ KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", .fi .P -The permissions and ownership of the created device file is read from +The permissions and ownership of the created device file are read from the files located in the .I /etc/udev/permissions.d/ directory, or at the location specified by the @@ -363,15 +363,15 @@ 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 character not enclosed is matched. +following the '[' is a '!', any characters not enclosed are matched. .P After device node creation, removal, or network device renaming, .B udev executes the programs in the directory tree under .IR /etc/dev.d/ . -The name of a program must end with +The name of a program must have the suffix .I .dev -suffix, to be recognized. +to be recognized. .br In addition to the hotplug environment variables, .B UDEV_LOG From 69bef84191f12dd82f7520f57e195f510bc9f96f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 5 Dec 2004 08:31:04 -0800 Subject: [PATCH 1035/4284] [PATCH] delete a bunch of files no longer needed. Thanks to Kay for pointing it out. --- etc/dev.d/default/dbus.dev | 15 ---- etc/dev.d/default/selinux.dev | 18 ----- etc/init.d/udev | 132 ---------------------------------- test/ignore_test | 36 ---------- test/label_test | 49 ------------- test/modifier_test | 47 ------------ test/topo_test | 47 ------------ test/udevd_test.sh | 88 ----------------------- test/wait_for_sysfs_test.sh | 44 ------------ 9 files changed, 476 deletions(-) delete mode 100644 etc/dev.d/default/dbus.dev delete mode 100644 etc/dev.d/default/selinux.dev delete mode 100644 etc/init.d/udev delete mode 100644 test/ignore_test delete mode 100644 test/label_test delete mode 100644 test/modifier_test delete mode 100644 test/topo_test delete mode 100644 test/udevd_test.sh delete mode 100644 test/wait_for_sysfs_test.sh diff --git a/etc/dev.d/default/dbus.dev b/etc/dev.d/default/dbus.dev deleted file mode 100644 index 2fe1ed9b3a..0000000000 --- a/etc/dev.d/default/dbus.dev +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -if [ -f /etc/sysconfig/udev ]; then - . /etc/sysconfig/udev -fi - -if [ -f /etc/conf.d/udev ]; then - . /etc/conf.d/udev -fi - -[ "$UDEV_DBUS" != "yes" ] && exit 0 - -if [ -x /usr/sbin/udev_dbus ]; then - exec /usr/sbin/udev_dbus "$@" -fi diff --git a/etc/dev.d/default/selinux.dev b/etc/dev.d/default/selinux.dev deleted file mode 100644 index 9682658aad..0000000000 --- a/etc/dev.d/default/selinux.dev +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -if [ -f /etc/sysconfig/udev ]; then - . /etc/sysconfig/udev -fi - -if [ -f /etc/conf.d/udev ]; then - . /etc/conf.d/udev -fi - -[ "$UDEV_SELINUX" != "yes" ] && exit 0 - -if [ -x /sbin/restorecon ]; then - if [ "$UDEV_LOG" = "yes" ] && [ -x /usr/bin/logger ]; then - /usr/bin/logger -p auth.debug "Restoring file security contexts for $DEVNAME" - fi - /sbin/restorecon $DEVNAME -fi diff --git a/etc/init.d/udev b/etc/init.d/udev deleted file mode 100644 index 8726090d44..0000000000 --- a/etc/init.d/udev +++ /dev/null @@ -1,132 +0,0 @@ -#! /bin/sh -# -# udev init script to setup /udev -# -# chkconfig: 2345 20 80 -# description: manage user-space device nodes in /udev - -. /etc/rc.d/init.d/functions - -. /etc/udev/udev.conf - -prog=udev -sysfs_dir=/sys -bin=/sbin/udev -udevd=/sbin/udevd -udev_root=/udev - -run_udev () { - # handle block devices and their partitions - for i in ${sysfs_dir}/block/*; do - # add each drive - export DEVPATH=${i#${sysfs_dir}} - $bin block & - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - $bin block & - fi - done - done - # all other device classes - for i in ${sysfs_dir}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - CLASS=`echo ${i#${sysfs_dir}} | \ - cut --delimiter='/' --fields=3-` - $bin $CLASS & - fi - done - done - return 0 -} - -make_extra_nodes () { - # there are a few things that sysfs does not export for us. - # these things go here (and remember to remove them in - # remove_extra_nodes() - # - # Thanks to Gentoo for the initial list of these. - ln -snf /proc/self/fd $udev_root/fd - ln -snf /proc/self/fd/0 $udev_root/stdin - ln -snf /proc/self/fd/1 $udev_root/stdout - ln -snf /proc/self/fd/2 $udev_root/stderr - ln -snf /proc/kcore $udev_root/core - #ln -snf /proc/asound/oss/sndstat $udev_root/sndstat -} - -remove_extra_nodes () { - # get rid of the extra nodes created in make_extra_nodes() - rm $udev_root/fd - rm $udev_root/stdin - rm $udev_root/stdout - rm $udev_root/stderr - rm $udev_root/core - #rm $udev_root/sndstat -} - -case "$1" in - start) - # don't use udev if sysfs is not mounted. - if [ ! -d $sysfs_dir/block ]; then - exit 1 - fi - if [ ! -d $udev_root ]; then - mkdir $udev_root - fi - - # remove the database if it is there as we always want to start fresh - if [ -f $udev_root/.udevdb ]; then - rm -rf $udev_root/.udevdb - fi - - # propogate /udev from /sys - we only need this while we do not - # have initramfs and an early user-space with which to do early - # device bring up - export ACTION=add - echo -n $"Creating initial udev device nodes:" - run_udev - make_extra_nodes - - # We want to start udevd ourselves if it isn't already running. This - # lets udevd run at a sane nice level... - $udevd & - - success /bin/true - echo - touch /var/lock/subsys/udev - ;; - stop) - # be careful - echo -n $"Removing udev device nodes: " - export ACTION=remove - run_udev - remove_extra_nodes - success /bin/true - echo - rm -f /var/lock/subsys/udev - ;; - status) - if [ -f /var/lock/subsys/udev ]; then - echo $"$prog has run" - exit 0 - fi - echo $"$prog is stopped" - exit 3 - ;; - restart) - $0 stop - $0 start - ;; - reload) - # nothing to do here - ;; - *) - echo "Usage: $0 {start|stop|status|restart}" - exit 1 -esac - -exit 0 diff --git a/test/ignore_test b/test/ignore_test deleted file mode 100644 index d22a4d7b5f..0000000000 --- a/test/ignore_test +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -RULES=ignore_test.rules -CONFIG=ignore_test.conf - -export UDEV_TEST=yes -export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_FILE=$PWD/$CONFIG - -cat > $RULES << EOF -KERNEL="ttyUSB0", NAME="" -EOF - -cat > $CONFIG << EOF -udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udevdb" -udev_rules="$PWD/$RULES" -udev_permissions="$PWD/udev.permissions" -udev_log="true" -EOF - -mkdir udev - -export DEVPATH=class/tty/ttyUSB0 -export ACTION=add - -../udev tty -ls -l udev - -export ACTION=remove -../udev tty -ls -l udev - -rm $RULES -rm $CONFIG -rm -rf udev diff --git a/test/label_test b/test/label_test deleted file mode 100644 index fbb7309045..0000000000 --- a/test/label_test +++ /dev/null @@ -1,49 +0,0 @@ -#!/bin/bash - -RULES=label_test.rules -CONFIG=label_test.conf - -export UDEV_TEST=yes -export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_FILE=$PWD/$CONFIG - -cat > $RULES << EOF -BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_diskX%n" -BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_disk%n" -EOF - -cat > $CONFIG << EOF -udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udevdb" -udev_rules="$PWD/$RULES" -udev_permissions="$PWD/udev.permissions" -EOF - -mkdir udev - -export ACTION=add -export DEVPATH=block/sda - -../udev block -ls -l udev - -export DEVPATH=block/sda/sda3 - -../udev block -ls -l udev - -export ACTION=remove -export DEVPATH=block/sda - -../udev block -ls -l udev - -export DEVPATH=block/sda/sda3 - -../udev block -ls -l udev - - -rm $RULES -rm $CONFIG -rm -rf udev diff --git a/test/modifier_test b/test/modifier_test deleted file mode 100644 index c2b5ec6830..0000000000 --- a/test/modifier_test +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -RULES=modifier_test.rules -CONFIG=modifier_test.conf - -export UDEV_TEST=yes -export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_FILE=$PWD/$CONFIG - -cat > $RULES << EOF -BUS="scsi", place="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" -EOF - -cat > $CONFIG << EOF -udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udevdb" -udev_rules="$PWD/$RULES" -udev_permissions="$PWD/udev.permissions" -EOF - -mkdir udev - -export ACTION=add -export DEVPATH=block/sda - -../udev block -ls udev - -export DEVPATH=block/sda/sda3 - -../udev block -ls udev - -export ACTION=remove -export DEVPATH=block/sda - -../udev block -ls udev - -export DEVPATH=block/sda/sda3 - -../udev block -ls udev - -rm $RULES -rm $CONFIG -rm -rf udev diff --git a/test/topo_test b/test/topo_test deleted file mode 100644 index 77333a978c..0000000000 --- a/test/topo_test +++ /dev/null @@ -1,47 +0,0 @@ -#!/bin/bash - -RULES=replace_test.rules -CONFIG=replace_test.conf - -export UDEV_TEST=yes -export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_FILE=$PWD/$CONFIG - -cat > $RULES << EOF -BUS="scsi", place="0:0:0:0", NAME="first_disk%n" -EOF - -cat > $CONFIG << EOF -udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udevdb" -udev_rules="$PWD/$RULES" -udev_permissions="$PWD/udev.permissions" -EOF - -mkdir udev - -export ACTION=add -export DEVPATH=block/sda - -../udev block -ls udev - -export DEVPATH=block/sda/sda3 - -../udev block -ls udev - -export ACTION=remove -export DEVPATH=block/sda - -../udev block -ls udev - -export DEVPATH=block/sda/sda3 - -../udev block -ls udev - -rm $RULES -rm $CONFIG -rm -rf udev diff --git a/test/udevd_test.sh b/test/udevd_test.sh deleted file mode 100644 index 981a39d01d..0000000000 --- a/test/udevd_test.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/sh - -# add/rem/add/rem/add sequence of sda/sdb/sdc -# a few days longer and the socket of my usb-flash-reader is gone :) - -export SEQNUM=0 -export ACTION=add -export DEVPATH=/test/init -./udevsend test - -export SEQNUM=3 -export ACTION=add -export DEVPATH=/test/sdc -./udevsend test - -export SEQNUM=1 -export ACTION=add -export DEVPATH=/test/sda -./udevsend test - -export SEQNUM=2 -export ACTION=add -export DEVPATH=/test/sdb -./udevsend test - -export SEQNUM=4 -export ACTION=remove -export DEVPATH=/test/sdc -./udevsend test - -export SEQNUM=5 -export ACTION=remove -export DEVPATH=/test/sdb -./udevsend test - -export SEQNUM=8 -export ACTION=add -export DEVPATH=/test/sdb -./udevsend test - -export SEQNUM=6 -export ACTION=remove -export DEVPATH=/test/sda -./udevsend test - -export SEQNUM=7 -export ACTION=add -export DEVPATH=/test/sda -#./udevsend test - -sleep 2 - -export SEQNUM=9 -export ACTION=add -export DEVPATH=/test/sdc -./udevsend test - -export SEQNUM=11 -export ACTION=remove -export DEVPATH=/test/sdb -./udevsend test - -export SEQNUM=10 -export ACTION=remove -export DEVPATH=/test/sdc -./udevsend test - -export SEQNUM=13 -export ACTION=add -export DEVPATH=/test/sda -./udevsend test - -export SEQNUM=14 -export ACTION=add -export DEVPATH=/test/sdb -./udevsend test - -export SEQNUM=15 -export ACTION=add -export DEVPATH=/test/sdc -./udevsend test - -sleep 2 - -export SEQNUM=12 -export ACTION=remove -export DEVPATH=/test/sda -./udevsend test diff --git a/test/wait_for_sysfs_test.sh b/test/wait_for_sysfs_test.sh deleted file mode 100644 index 9b80a42271..0000000000 --- a/test/wait_for_sysfs_test.sh +++ /dev/null @@ -1,44 +0,0 @@ -#! /bin/bash -# - -# Check for missing binaries (stale symlinks should not happen) -UDEV_BIN=../wait_for_sysfs -test -x $UDEV_BIN || exit 5 - -# Directory where sysfs is mounted -SYSFS_DIR=/sys - -run_udev () { - # handle block devices and their partitions - for i in ${SYSFS_DIR}/block/*; do - # add each drive - export DEVPATH=${i#${SYSFS_DIR}} - $UDEV_BIN block - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFS_DIR}} - $UDEV_BIN block - fi - done - done - # all other device classes - for i in ${SYSFS_DIR}/class/*; do - # try adding empty classes, just to test stuff... - export DEVPATH=${i#${SYSFS_DIR}} - CLASS=`echo ${i#${SYSFS_DIR}} | cut --delimiter='/' --fields=3-` - $UDEV_BIN $CLASS - - for j in `ls $i/`; do - x=$i/$j - export DEVPATH=${x#${SYSFS_DIR}} - CLASS=`echo ${i#${SYSFS_DIR}} | \ - cut --delimiter='/' --fields=3-` - $UDEV_BIN $CLASS - done - done -} - -export ACTION=add -run_udev From d18c91df7fe7134b7aea6f68b183296ac94633ed Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sun, 5 Dec 2004 08:31:37 -0800 Subject: [PATCH 1036/4284] [PATCH] use udevstart for udev.init.* files. Thanks to Kay for pointing it out. --- etc/init.d/udev.init.LSB | 38 +++----------------------------------- etc/init.d/udev.init.lfs | 39 ++------------------------------------- 2 files changed, 5 insertions(+), 72 deletions(-) diff --git a/etc/init.d/udev.init.LSB b/etc/init.d/udev.init.LSB index 0f5881c416..0fb0f0c205 100644 --- a/etc/init.d/udev.init.LSB +++ b/etc/init.d/udev.init.LSB @@ -49,34 +49,6 @@ SYSFS_DIR=/sys # Source LSB init functions . /lib/lsb/init-functions -run_udev () { - # handle block devices and their partitions - for i in ${SYSFS_DIR}/block/*; do - # add each drive - export DEVPATH=${i#${SYSFS_DIR}} - $UDEV_BIN block & - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFS_DIR}} - $UDEV_BIN block & - fi - done - done - # all other device classes - for i in ${SYSFS_DIR}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFS_DIR}} - CLASS=`echo ${i#${SYSFS_DIR}} | \ - cut --delimiter='/' --fields=3-` - $UDEV_BIN $CLASS & - fi - done - done -} - case "$1" in start) if [ ! -d $SYSFS_DIR ]; then @@ -91,16 +63,12 @@ case "$1" in # device bring up echo -n "Creating initial udev device nodes: " export ACTION=add - run_udev + udevstart log_success_msg ;; stop) - # be careful - echo -n "Removing udev device nodes: " - export ACTION=remove - run_udev - rm -f $udev_db || exit 1 - rmdir $udev_root || exit 1 + # nothing to do here + echo -n "Stopping udev: " log_success_msg ;; restart) diff --git a/etc/init.d/udev.init.lfs b/etc/init.d/udev.init.lfs index 41a3fecf0f..d4f64062b8 100644 --- a/etc/init.d/udev.init.lfs +++ b/etc/init.d/udev.init.lfs @@ -10,38 +10,6 @@ . /etc/udev/udev.conf sysfs_dir="/sys" -bin="/sbin/udev" - - -run_udev () -{ - # handle block devices and their partitions - for i in ${sysfs_dir}/block/*; do - # add each drive - export DEVPATH=${i#${sysfs_dir}} - $bin block & - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - $bin block & - fi - done - done - # all other device classes - for i in ${sysfs_dir}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - CLASS=`echo ${i#${sysfs_dir}} | \ - cut --delimiter='/' --fields=3-` - $bin $CLASS & - fi - done - done - return 0 -} case "$1" in start) @@ -62,14 +30,11 @@ case "$1" in # propogate /udev from /sys - we only need this while we do not # have initramfs and an early user-space with which to do early # device bring up - export ACTION=add - run_udev + udevstart evaluate_retval ;; stop) - echo "Removing udev device nodes ..." - export ACTION=remove - run_udev + echo "Stopping udev ..." evaluate_retval ;; reload) From 3efc93cc40464e83cc202b40e6290e8759130ca2 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 3 Dec 2004 01:04:53 -0800 Subject: [PATCH 1037/4284] [PATCH] Fix the multithreaded build again... --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 6494c1bf19..1fe5c23f58 100644 --- a/Makefile +++ b/Makefile @@ -297,6 +297,9 @@ GEN_MANPAGESIN = udev.8.in $(GEN_MANPAGES): $(GEN_MANPAGESIN) sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ +$(UDEV_OBJS): $(GEN_HEADERS) $(HOST_PROGS) +$(SYSFS_OBJS): $(HOST_PROGS) +$(KLIBC_FIXUP_OBJS): $(HOST_PROGS) $(OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) $(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) From de5d2ee0a7192500b1c48f8d52a68b30258157a9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Fri, 3 Dec 2004 18:50:05 -0800 Subject: [PATCH 1038/4284] [PATCH] fix gentoo scsi cdrom rule http://bugs.gentoo.org/show_bug.cgi?id=73208 --- etc/udev/udev.rules.gentoo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 1809232ed0..83407ea9d0 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -14,7 +14,7 @@ # cdrom symlinks and other good cdrom naming BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS="scsi", KERNEL="sr[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" # devfs-names for ide-devices (uncomment only one) From 55b0508969652acc71114b0b1205226ad3d27f39 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 16:55:27 -0800 Subject: [PATCH 1039/4284] [PATCH] added asterix rules to the gentoo file. --- etc/udev/udev.rules.gentoo | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 83407ea9d0..64e020f83e 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -140,3 +140,10 @@ KERNEL="radio[0-9]*", NAME="v4l/radio%n" KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n" KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +# 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" + From e0a17b749f00ef42dda0efe71f7f26637c4ca9a9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 17:05:20 -0800 Subject: [PATCH 1040/4284] [PATCH] update debian rules files. --- etc/udev/udev.rules.debian | 58 ++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/etc/udev/udev.rules.debian b/etc/udev/udev.rules.debian index cdc0505418..65a89ae593 100644 --- a/etc/udev/udev.rules.debian +++ b/etc/udev/udev.rules.debian @@ -1,28 +1,28 @@ # 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. (Note, this doesn't work within -# the PROGRAM field for the obvious reason.) -# %s{filename} - the content of a sysfs attribute. -# %% - the '%' char itself. +# +# %n the "kernel number" of the device. +# For example, 'sda3' has a "kernel number" of '3' +# %e the smallest number for that name which does not matches an existing node +# %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. # -# /dev/cdrom symlink -BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - -# permissions for SCSI sg devices -BUS="scsi", KERNEL="s[grt][0-9]*", SYSFS{type}="5", NAME="%k", MODE="0660", GROUP="cdrom" - # permissions for IDE CD devices -BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", NAME="%k", MODE="0660", GROUP="cdrom" +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", NAME="%k", MODE="0660", GROUP="cdrom" # permissions for IDE floppy devices -BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", NAME="%k", MODE="0660", GROUP="floppy" +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", NAME="%k", MODE="0660", GROUP="floppy" + +# permissions for SCSI CD devices +BUS="scsi", KERNEL="sr[0-9]*", SYSFS{type}="5", NAME="scd%n", MODE="0660", GROUP="cdrom", SYMLINK="sr%n" +BUS="scsi", KERNEL="sg[0-9]*", SYSFS{type}="5", NAME="%k", MODE="0660", GROUP="cdrom" + # USB devices BUS="usb", KERNEL="hiddev*", NAME="usb/%k" @@ -30,39 +30,49 @@ BUS="usb", KERNEL="auer*", NAME="usb/%k" BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" BUS="usb", KERNEL="dabusb*", NAME="usb/%k" BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" -KERNEL="dvb*", PROGRAM="/etc/udev/dvb.sh %k", NAME="%c" +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" KERNEL="card*", NAME="dri/card%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" # 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="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" # input devices KERNEL="mice", NAME="input/%k" KERNEL="mouse[0-9]*", NAME="input/%k" -KERNEL="event[0-9]*", NAME="input/%k", PROGRAM="/etc/udev/inputdev.sh %k", RESULT="inputdev", MODE="0664", GROUP="video" +KERNEL="event[0-9]*", NAME="input/%k", PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", MODE="0664", GROUP="video" 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" -KERNEL="tap*", NAME="net/%k" +KERNEL="tap[0-9]*", NAME="net/%k" KERNEL="tun", NAME="net/%k" # CAPI devices KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" KERNEL="capi[0-9]*", NAME="capi/%n" +# 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" + # device mapper creates its own device nodes, so ignore these KERNEL="dm-[0-9]*", NAME="" KERNEL="device-mapper", NAME="mapper/control" From 5e7d9f4060f0d1f11048c8735aa5d7ef6a4932e8 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 26 Apr 2005 23:10:15 -0700 Subject: [PATCH 1041/4284] more merge fixups --- etc/udev/udev.rules.gentoo | 2 +- extras/ide-devfs.sh | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/udev.rules.gentoo index 64e020f83e..6a53e88d9d 100644 --- a/etc/udev/udev.rules.gentoo +++ b/etc/udev/udev.rules.gentoo @@ -19,7 +19,7 @@ BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYM # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" # dri devices KERNEL="card*", NAME="dri/card%n" diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 4f20259480..580a751abe 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -36,11 +36,11 @@ get_dev_number() { if [ -z "$3" ] && [ -f /proc/ide/${1}/media ]; then MEDIA=`cat /proc/ide/${1}/media` if [ "${MEDIA}" = "cdrom" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/cd cdroms/cdrom`get_dev_number $1 cdrom` ${MEDIA} elif [ "${MEDIA}" = "floppy" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc floppies/floppy`get_dev_number $1 floppy`/disc + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc floppies/floppy`get_dev_number $1 floppy`/disc ${MEDIA} elif [ "${MEDIA}" = "disk" ]; then - echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc + echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/disc discs/disc`get_dev_number $1 disk`/disc ${MEDIA} fi else echo ide/host${HOST}/bus${BUS}/target${TARGET}/lun0/part$3 discs/disc`get_dev_number $1 disk`/part$3 From f01a9ca1a2824e07908457ef01db238b77d21f96 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 17:08:20 -0800 Subject: [PATCH 1042/4284] [PATCH] move distro specific config files into their own directories --- etc/udev/{udev.permissions.debian => debian/udev.permissions} | 0 etc/udev/{udev.rules.debian => debian/udev.rules} | 0 etc/udev/{udev.permissions.gentoo => gentoo/udev.permissions} | 0 etc/udev/{udev.rules.gentoo => gentoo/udev.rules} | 0 etc/udev/{udev.permissions.redhat => redhat/udev.permissions} | 0 etc/udev/{udev.rules.redhat => redhat/udev.rules} | 0 .../{udev.permissions.slackware => slackware/udev.permissions} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename etc/udev/{udev.permissions.debian => debian/udev.permissions} (100%) rename etc/udev/{udev.rules.debian => debian/udev.rules} (100%) rename etc/udev/{udev.permissions.gentoo => gentoo/udev.permissions} (100%) rename etc/udev/{udev.rules.gentoo => gentoo/udev.rules} (100%) rename etc/udev/{udev.permissions.redhat => redhat/udev.permissions} (100%) rename etc/udev/{udev.rules.redhat => redhat/udev.rules} (100%) rename etc/udev/{udev.permissions.slackware => slackware/udev.permissions} (100%) diff --git a/etc/udev/udev.permissions.debian b/etc/udev/debian/udev.permissions similarity index 100% rename from etc/udev/udev.permissions.debian rename to etc/udev/debian/udev.permissions diff --git a/etc/udev/udev.rules.debian b/etc/udev/debian/udev.rules similarity index 100% rename from etc/udev/udev.rules.debian rename to etc/udev/debian/udev.rules diff --git a/etc/udev/udev.permissions.gentoo b/etc/udev/gentoo/udev.permissions similarity index 100% rename from etc/udev/udev.permissions.gentoo rename to etc/udev/gentoo/udev.permissions diff --git a/etc/udev/udev.rules.gentoo b/etc/udev/gentoo/udev.rules similarity index 100% rename from etc/udev/udev.rules.gentoo rename to etc/udev/gentoo/udev.rules diff --git a/etc/udev/udev.permissions.redhat b/etc/udev/redhat/udev.permissions similarity index 100% rename from etc/udev/udev.permissions.redhat rename to etc/udev/redhat/udev.permissions diff --git a/etc/udev/udev.rules.redhat b/etc/udev/redhat/udev.rules similarity index 100% rename from etc/udev/udev.rules.redhat rename to etc/udev/redhat/udev.rules diff --git a/etc/udev/udev.permissions.slackware b/etc/udev/slackware/udev.permissions similarity index 100% rename from etc/udev/udev.permissions.slackware rename to etc/udev/slackware/udev.permissions From 06ed11be3ea3f7343ab8b027c121496f2075d3e8 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 17:09:40 -0800 Subject: [PATCH 1043/4284] [PATCH] add more debian rules files. --- etc/udev/debian/cd-aliases.rules | 11 +++ etc/udev/debian/compat.rules | 37 +++++++ etc/udev/debian/devfs.rules | 126 ++++++++++++++++++++++++ etc/udev/debian/simple-cd-aliases.rules | 5 + 4 files changed, 179 insertions(+) create mode 100644 etc/udev/debian/cd-aliases.rules create mode 100644 etc/udev/debian/compat.rules create mode 100644 etc/udev/debian/devfs.rules create mode 100644 etc/udev/debian/simple-cd-aliases.rules diff --git a/etc/udev/debian/cd-aliases.rules b/etc/udev/debian/cd-aliases.rules new file mode 100644 index 0000000000..7137527628 --- /dev/null +++ b/etc/udev/debian/cd-aliases.rules @@ -0,0 +1,11 @@ +# These rules create the /dev/{cdrom,dvd,...} symlinks. Also see the +# /etc/udev/cdsymlinks.conf config file. +# +# If you would like to statically configure the aliases instead, you can +# use rules like: +# BUS="ide", ID="1.0", SYMLINK="cdrom" + +BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS="ide", KERNEL="pcd[0-9]*", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" + diff --git a/etc/udev/debian/compat.rules b/etc/udev/debian/compat.rules new file mode 100644 index 0000000000..ec386ea8c4 --- /dev/null +++ b/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="video0", SYMLINK="%k" +KERNEL="radio0", SYMLINK="%k" +KERNEL="vbi0", SYMLINK="%k" +KERNEL="vtx0", 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/etc/udev/debian/devfs.rules b/etc/udev/debian/devfs.rules new file mode 100644 index 0000000000..8d305cd657 --- /dev/null +++ b/etc/udev/debian/devfs.rules @@ -0,0 +1,126 @@ +# 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' +# %e the smallest number for that name which does not matches an existing node +# %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. +# + +# IDE block devices +BUS="ide", KERNEL="hd[a-z]*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" + +# permissions for SCSI CD devices +BUS="scsi", KERNEL="s[grt][0-9]*", SYSFS{type}="5", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}", MODE="0660", GROUP="cdrom" + +# SCSI block devices +BUS="scsi", KERNEL="sd[a-z]", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="sd[a-z][0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="sd[a-i][a-z]", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="sd[a-i][a-z][0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="s[grt][0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="st[0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="nst[0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" + +# USB devices +BUS="usb", KERNEL="hiddev*", NAME="usb/%k" +BUS="usb", KERNEL="auer*", NAME="usb/%k" +BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" +BUS="usb", KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" + +# block devices +KERNEL="md[0-9]*", NAME="md/%n", +KERNEL="loop[0-9]*", NAME="loop/%n" + +# tty devices +KERNEL="tty[0-9]*", NAME="vc/%n" +KERNEL="ttyS[0-9]*", NAME="tts/%n" +KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" +KERNEL="rfcomm[0-9]*", NAME="bluetooth/rfcomm/%n" + +# vc devices +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" +KERNEL="fb[0-9]*", NAME="fb/%n", + +# v4l devices +KERNEL="video[0-9]*", NAME="v4l/video%n" +KERNEL="radio[0-9]*", NAME="v4l/radio%n" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" +KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" + +# misc devices +KERNEL="apm_bios", NAME="misc/apm_bios", +KERNEL="agpgart", NAME="misc/agpgart", +KERNEL="nvram", NAME="misc/nvram" +KERNEL="psaux", NAME="misc/psaux" +KERNEL="rtc", NAME="misc/rtc" + +KERNEL="card[0-9]*", NAME="dri/card%n" +KERNEL="i2c-[0-9]*", NAME="i2c/%n" +KERNEL="ram[0-9]*", NAME="rd/%n" +KERNEL="lp[0-9]*", NAME="printers/%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" + +# 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" + +# input devices +KERNEL="mice", NAME="input/%k" +KERNEL="mouse[0-9]*", NAME="input/%k" +KERNEL="event[0-9]*", NAME="input/%k", PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", MODE="0664", GROUP="video" +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" + +KERNEL="tap[0-9]*", NAME="net/%k" +KERNEL="tun", NAME="net/%k" + +# CAPI devices +KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" +KERNEL="capi[0-9]*", NAME="capi/%n" + +# 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" + +# device mapper creates its own device nodes, so ignore these +KERNEL="dm-[0-9]*", NAME="" +KERNEL="device-mapper", NAME="mapper/control" + diff --git a/etc/udev/debian/simple-cd-aliases.rules b/etc/udev/debian/simple-cd-aliases.rules new file mode 100644 index 0000000000..bd700bc29f --- /dev/null +++ b/etc/udev/debian/simple-cd-aliases.rules @@ -0,0 +1,5 @@ +# grouping of optical drives from multiple kernel subsystems +BUS="scsi", KERNEL="sr[0-9]*", SYMLINK="cdrom%e" +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", SYMLINK="cdrom%e", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom" +BUS="ide", KERNEL="pcd[0-9]*", SYSFS{removable}="1", SYMLINK="cdrom%e" + From 6fbecf3547a02be2475f275d6862ed9dcfcce2fe Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 18:29:04 -0800 Subject: [PATCH 1044/4284] [PATCH] 047 release --- ChangeLog | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6319845aa7..84c4ffab3a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,68 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 1fe5c23f58..942c8ccb19 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 046 +VERSION = 047 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 05cee524c0..05cd4933b7 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 046 +Version: 047 Release: 1 License: GPL Group: Utilities/System From 09f275607119e848be4888518a6a3fcd58a32c6d Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 19:30:41 -0800 Subject: [PATCH 1045/4284] [PATCH] fix scsi_id build errors due to changes in the main udev makefile also fixed up the QUIET issue when it was disabled for the extras programs --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 942c8ccb19..7d4396b9ed 100644 --- a/Makefile +++ b/Makefile @@ -183,7 +183,7 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(GEN_CONFIGS) LD="$(LD)" \ SYSFS="$(SYSFS)" \ KERNEL_DIR="$(KERNEL_DIR)" \ - QUIET="@$(PWD)/ccdv" \ + QUIET="$(QUIET)" \ -C $$target $@ ; \ done ; \ @@ -231,6 +231,8 @@ OBJS = \ libsysfs/sysfs.a \ udev.a +SYSFS = $(PWD)/libsysfs/sysfs.a + ifeq ($(strip $(USE_KLIBC)),true) HEADERS += \ klibc_fixups/klibc_fixups.h \ @@ -244,7 +246,7 @@ ifeq ($(strip $(USE_KLIBC)),true) endif ifeq ($(strip $(V)),false) - QUIET=@./ccdv + QUIET=@$(PWD)/ccdv HOST_PROGS=ccdv else QUIET= From c93053663f2287b32549851f55798219b9b2d8d7 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 19:35:29 -0800 Subject: [PATCH 1046/4284] [PATCH] fix udev_volume_id so it will now build properly. --- extras/volume_id/udev_volume_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 5d1ccf6a89..9e8c3bfb11 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -29,7 +29,7 @@ #include #include "../../libsysfs/sysfs/libsysfs.h" -#include "../../udev_lib.h" +#include "../../udev_utils.h" #include "../../logging.h" #include "volume_id.h" #include "dasdlabel.h" From 7d92b28f3971f1d80a85964c1bbde6146e411379 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 8 Dec 2004 19:42:47 -0800 Subject: [PATCH 1047/4284] [PATCH] 048 release --- ChangeLog | 8 ++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 84c4ffab3a..6ac004fd4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 7d4396b9ed..01ebcc22b5 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 047 +VERSION = 048 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 05cd4933b7..56ca479113 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 047 +Version: 048 Release: 1 License: GPL Group: Utilities/System From c2fe814e305aaede3b03cfa2e86f1a317e1a66c4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 9 Dec 2004 06:06:17 +0100 Subject: [PATCH 1048/4284] [PATCH] udev_volume_id: links sysfs.a instead of all objects cuts down the size from: dynamically linked: 48.030 -> 45.187 statically linked: 149.177 -> 142.362 --- extras/volume_id/Makefile | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 8605811cf5..5c8adb065b 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -33,16 +33,6 @@ override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \ override CFLAGS+=-D_FILE_OFFSET_BITS=64 -override SYSFS = ../../libsysfs/sysfs_bus.o \ - ../../libsysfs/sysfs_class.o \ - ../../libsysfs/sysfs_device.o \ - ../../libsysfs/sysfs_dir.o \ - ../../libsysfs/sysfs_driver.o \ - ../../libsysfs/sysfs_utils.o \ - ../../libsysfs/dlist.o - - - OBJS = volume_id.o udev_volume_id.o dasdlabel.o $(SYSFS) HEADERS = volume_id.h dasdlabel.h From 0dfbe9451b47cfa0464f5d3ba232ceccf26ae189 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 11 Dec 2004 06:07:31 +0100 Subject: [PATCH 1049/4284] [PATCH] add a class/fc_host file to the list of what to wait for --- udev_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 5f7c63d31d..ac8e4c1060 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -52,6 +52,7 @@ static const struct subsystem_file { { .subsystem = "ieee1394_host", .file = NULL }, { .subsystem = "ieee1394_node", .file = NULL }, { .subsystem = "fc_transport", .file = "port_id" }, + { .subsystem = "fc_host", .file = "port_id" }, { NULL, NULL } }; From 79721e0a7770b1a5874ef96cbf93a4c6bd19e138 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 11 Dec 2004 21:43:08 +0100 Subject: [PATCH 1050/4284] [PATCH] udevd: serialization of the event sequence of a chain of devices Currently udevd delays only events for the same DEVPATH. Example of an "add" event sequence: /block/sda /block/sda/sda1 With this change, we make sure, that the udev process handling /block/sda has finished its work (waited for all attributes, created the node) before we fork the udev event for /block/sda/sda1. This way the event for sda1 can be sure, that the node for the main device is already created (may be useful for disk labels). It will not affect any parallel device handling, only the sequence of the devices directory chain is serialized. The 10.000 disks plugged in will still run as parallel events. :) The main motivation to do this is the program execution of the dev.d/ and hotplug.d/ directory. If we don't wait for the parent event to exit, we can't be sure that the executed scripts are run in the right order. On Thu, Dec 09, 2004 at 09:18:28AM +0100, Kay Sievers wrote: > On Wed, 2004-12-08 at 19:07 -0800, David Brownell wrote: > > Could that argument apply to the underlying hardware, too? > We now make sure that the sequence of events for a device > is serialized for every device chain and the class/block > devices which have a "device" link to a physical device are > handled after the physical device is fully populated and > notified to userspace. It will only work this way on kernels > later than 2.6.10-rc1 cause it depends on the PHYSDEVPATH > value in the hotplug environment. --- udevd.8 | 2 -- udevd.c | 33 +++++++++++++++++++++++++++------ udevd.h | 1 + 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/udevd.8 b/udevd.8 index 1a5940fef5..b06a2b7af1 100644 --- a/udevd.8 +++ b/udevd.8 @@ -28,8 +28,6 @@ running for a single device at the same time. .B udevd receives the events from .B udevsend -which is called by -.BR hotplug (8). If .B udevd isn't already running, diff --git a/udevd.c b/udevd.c index 58f5be94bc..2e6f5793d3 100644 --- a/udevd.c +++ b/udevd.c @@ -151,22 +151,40 @@ static void udev_run(struct hotplug_msg *msg) } } -/* returns already running task with devpath */ +/* returns still running task for the same event sequence */ static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) { struct hotplug_msg *loop_msg; + int i; + list_for_each_entry(loop_msg, &running_list, list) { if (loop_msg->devpath == NULL || msg->devpath == NULL) continue; - if (strcmp(loop_msg->devpath, msg->devpath) == 0) - return loop_msg; + /* is a parent or child device event still running */ + for (i = 0; i < DEVPATH_SIZE; i++) { + if (loop_msg->devpath[i] == '\0' || msg->devpath[i] == '\0') + return loop_msg; + + if (loop_msg->devpath[i] != msg->devpath[i]) + break; + } + + /* is the physical device event still running on an add sequence */ + if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0) + for (i = 0; i < DEVPATH_SIZE; i++) { + if (loop_msg->devpath[i] == '\0' || msg->physdevpath[i] == '\0') + return loop_msg; + + if (loop_msg->devpath[i] != msg->physdevpath[i]) + break; + } } return NULL; } -/* exec queue management routine executes the events and delays events for the same devpath */ +/* exec queue management routine executes the events and serializes events in the same sequence */ static void exec_queue_manager(void) { struct hotplug_msg *loop_msg; @@ -181,8 +199,8 @@ static void exec_queue_manager(void) udev_run(loop_msg); dbg("moved seq %llu to running list", loop_msg->seqnum); } else { - dbg("delay seq %llu, cause seq %llu already working on '%s'", - loop_msg->seqnum, msg->seqnum, msg->devpath); + dbg("delay seq %llu (%s), cause seq %llu (%s) is still running", + loop_msg->seqnum, loop_msg->devpath, msg->seqnum, msg->devpath); } } } @@ -314,6 +332,9 @@ static void handle_udevsend_msg(int sock) if (strncmp(key, "SEQNUM=", 7) == 0) msg->seqnum = strtoull(&key[7], NULL, 10); + + if (strncmp(key, "PHYSDEVPATH=", 12) == 0) + msg->physdevpath = &key[12]; } msg->envp[i++] = "MANAGED_EVENT=1"; msg->envp[i] = NULL; diff --git a/udevd.h b/udevd.h index 31f07de826..1c4b1b88c2 100644 --- a/udevd.h +++ b/udevd.h @@ -47,6 +47,7 @@ struct hotplug_msg { char *devpath; char *subsystem; unsigned long long seqnum; + char *physdevpath; char *envp[HOTPLUG_NUM_ENVP+1]; char envbuf[]; }; From 5ce120d366b54ea2bae12ec6ce01bb0d38ff1f50 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 12 Dec 2004 02:03:14 +0100 Subject: [PATCH 1051/4284] [PATCH] prevent udev node creatinon for "class" registration I've found a /dev/video4linux node and just realized, that libsysfs searches all subdirs for an attribute name. So it found /class/video4linux/video0/dev for the videodev class creation event /class/video4linux and created a node. Just ignore the SUBSYSTEM="class" events now. --- udev_sysfs.c | 1 + udevtest.c | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index ac8e4c1060..a4f293ef13 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -39,6 +39,7 @@ static const struct subsystem_file { const char *subsystem; const char *file; } subsystem_files[] = { + { .subsystem = "class", .file = NULL }, { .subsystem = "net", .file = "ifindex" }, { .subsystem = "scsi_host", .file = "unique_id" }, { .subsystem = "scsi_device", .file = NULL }, diff --git a/udevtest.c b/udevtest.c index 38e2bb7562..19cf9ec4f4 100644 --- a/udevtest.c +++ b/udevtest.c @@ -84,12 +84,6 @@ int main(int argc, char *argv[], char *envp[]) info("looking at '%s'", devpath); - /* we only care about class devices and block stuff */ - if (!strstr(devpath, "class") && !strstr(devpath, "block")) { - dbg("not a block or class device"); - return 2; - } - /* initialize the naming deamon */ namedev_init(); @@ -99,6 +93,12 @@ int main(int argc, char *argv[], char *envp[]) /* fill in values and test_run flag*/ udev_init_device(&udev, devpath, subsystem); + /* skip subsystems without "dev", but handle net devices */ + if (udev.type != 'n' && subsystem_expect_no_dev(udev.subsystem)) { + info("don't care about '%s' devices", udev.subsystem); + return 2; + } + /* open the device */ snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); class_dev = sysfs_open_class_device_path(path); @@ -107,7 +107,7 @@ int main(int argc, char *argv[], char *envp[]) return 1; } - dbg("opened class_dev->name='%s'", class_dev->name); + info("opened class_dev->name='%s'", class_dev->name); /* simulate node creation with test flag */ udev.test_run = 1; From 51737eb8b8087d3d9c0cbad8caeaed9efde907fe Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 12 Dec 2004 02:27:50 +0100 Subject: [PATCH 1052/4284] [PATCH] add -V option to udev to print the version number On Sat, 2004-12-11 at 18:44 +0200, Martin Schlemmer [c] wrote: > > Any suggestions to determining the version of the installed udev? > This is now during startup, to see if we can make use of using > udevsend as hotplug agent. If the system was up, udevinfo could > be used, but that is in /usr/bin that might be on a seperate /usr. > I know we might move udevinfo to /bin, but that might be an issue > for some, and adding a -V switch to /sbin/udev might be a better > choice. --- udev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/udev.c b/udev.c index 507f2be943..b1ba1435e7 100644 --- a/udev.c +++ b/udev.c @@ -107,8 +107,14 @@ int main(int argc, char *argv[], char *envp[]) const char *devpath = getenv("DEVPATH"); const char *subsystem = argv[1]; - dbg("version %s", UDEV_VERSION); + if (argc == 2 && strcmp(argv[1], "-V") == 0) { + printf("%s\n", UDEV_VERSION); + exit(0); + } + logging_init("udev"); + dbg("version %s", UDEV_VERSION); + udev_init_config(); /* set signal handlers */ From d7190b051391163187325a3d39d55893527270a4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 12 Dec 2004 02:32:25 +0100 Subject: [PATCH 1053/4284] [PATCH] include missing header to udevtest.c --- udevtest.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udevtest.c b/udevtest.c index 19cf9ec4f4..388818d495 100644 --- a/udevtest.c +++ b/udevtest.c @@ -29,6 +29,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" +#include "udev_sysfs.h" #include "udev_utils.h" #include "udev_version.h" #include "namedev.h" From 8544c9ad4febef602d640905a70c350364f98967 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 12 Dec 2004 02:54:55 +0100 Subject: [PATCH 1054/4284] [PATCH] remove double initialization --- udev.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/udev.c b/udev.c index b1ba1435e7..4d25ed267a 100644 --- a/udev.c +++ b/udev.c @@ -101,11 +101,11 @@ int main(int argc, char *argv[], char *envp[]) struct sysfs_device *devices_dev; struct udevice udev; char path[SYSFS_PATH_MAX]; - int retval = -EINVAL; const char *error; - const char *action = getenv("ACTION"); - const char *devpath = getenv("DEVPATH"); - const char *subsystem = argv[1]; + const char *action; + const char *devpath; + const char *subsystem; + int retval = -EINVAL; if (argc == 2 && strcmp(argv[1], "-V") == 0) { printf("%s\n", UDEV_VERSION); From 7e0bd584756b87d57b3f3e62dcbac208476f1804 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 12 Dec 2004 03:29:59 +0100 Subject: [PATCH 1055/4284] [PATCH] check earlier if we should run as udevstart --- udev.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/udev.c b/udev.c index 4d25ed267a..0ee70529c4 100644 --- a/udev.c +++ b/udev.c @@ -128,14 +128,6 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); - action = getenv("ACTION"); - devpath = getenv("DEVPATH"); - subsystem = getenv("SUBSYSTEM"); - /* older kernels passed the SUBSYSTEM only as argument */ - if (!subsystem && argc == 2) - subsystem = argv[1]; - udev_init_device(&udev, devpath, subsystem); - if (strstr(argv[0], "udevstart") || (argc == 2 && strstr(argv[1], "udevstart"))) { dbg("udevstart"); @@ -147,6 +139,14 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + action = getenv("ACTION"); + devpath = getenv("DEVPATH"); + subsystem = getenv("SUBSYSTEM"); + /* older kernels passed the SUBSYSTEM only as argument */ + if (!subsystem && argc == 2) + subsystem = argv[1]; + udev_init_device(&udev, devpath, subsystem); + if (!action) { dbg("no action"); goto hotplug; From 98446db5533596fd4d32f5019479d37d9495f1a1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 12 Dec 2004 03:35:39 +0100 Subject: [PATCH 1056/4284] [PATCH] udevd-test.pl: remove wrong date calculation A hour wrap during the test run does not work :) Just remove all the useless date conversions as we are only interested in the seconds it takes to process. [root@pim udevd-test]# ./udevd-test.pl 9 ... device: /class/tty/console, action: remove forking udev time: Sat Dec 11 18:59:57 2004 the delay time is: 3 s device: /class/tty/ptmx, action: remove forking udev time: Sat Dec 11 19:00:07 2004 the delay time is: 4013 s the delay time is: 4013 udevd doesn't act properly. --- test/udevd-test/udev-log-amplify.pl | 32 ++--------- test/udevd-test/udev-log-script.pl | 32 ++--------- test/udevd-test/udevd-test.pl | 86 +++++------------------------ 3 files changed, 23 insertions(+), 127 deletions(-) diff --git a/test/udevd-test/udev-log-amplify.pl b/test/udevd-test/udev-log-amplify.pl index c2d4723974..9e2692ac0c 100644 --- a/test/udevd-test/udev-log-amplify.pl +++ b/test/udevd-test/udev-log-amplify.pl @@ -38,35 +38,11 @@ use strict; my $udev_exe_time = 5; my $log_file = "/tmp/udev_log.txt"; -# global variables -my $devpath; -my $action; -my $subsystem; - -# common functions -sub getDate { - # Get current date/time - # If we want GTM time, simply pass GMT as first argument to this function. - - my $format = @_; - my $date; - - if( $format =~ /GMT/i ) { - $date = gmtime() . " GMT"; - } else { - $date = localtime(); - } - return $date; -} - -# main program if ($ARGV[0]) { - $subsystem = $ARGV[0]; - $devpath = $ENV{DEVPATH}; - $action = $ENV{ACTION}; - - # Get current system date - my $time = getDate(); + my $subsystem = $ARGV[0]; + my $devpath = $ENV{DEVPATH}; + my $action = $ENV{ACTION}; + my $time = time(); # Logging if (open(LOGF, ">>$log_file")) { diff --git a/test/udevd-test/udev-log-script.pl b/test/udevd-test/udev-log-script.pl index 5f4f8a4495..5d7ca71181 100644 --- a/test/udevd-test/udev-log-script.pl +++ b/test/udevd-test/udev-log-script.pl @@ -36,35 +36,11 @@ use strict; # modifiable settings my $log_file = "/tmp/udev_log.txt"; -# global variables -my $devpath; -my $action; -my $subsystem; - -# common functions -sub getDate { - # Get current date/time - # If we want GTM time, simply pass GMT as first argument to this function. - my $format = @_; - my $date; - - if( $format =~ /GMT/i ) { - $date = gmtime() . " GMT"; - } else { - $date = localtime(); - } - return $date; -} - -# main program if ($ARGV[0]) { - # prepare - $subsystem = $ARGV[0]; - $devpath = $ENV{DEVPATH}; - $action = $ENV{ACTION}; - - # Get current system date - my $time = getDate(); + my $subsystem = $ARGV[0]; + my $devpath = $ENV{DEVPATH}; + my $action = $ENV{ACTION}; + my $time = time(); # Logging if (open(LOGF, ">>$log_file")) { diff --git a/test/udevd-test/udevd-test.pl b/test/udevd-test/udevd-test.pl index e81aadd938..2328de814f 100644 --- a/test/udevd-test/udevd-test.pl +++ b/test/udevd-test/udevd-test.pl @@ -85,62 +85,6 @@ sub udevsend { return system("$udevsend_bin $subsystem"); } -sub getDate { - # Get current date function - # If we want GTM time, simply pass GMT as first argument to this function. - - my $format = @_; - my $date; - - if( $format =~ /GMT/i ) { - $date = gmtime() . " GMT"; - } else { - $date = localtime(); - } - - return $date; -} - -sub cmpDate { - # This function should return a difference betweent date1 and date2 - - my ($date1, $date2) = @_; - my @monList = ( "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", - "Aug", "Sep", "Oct", "Nov", "Dec" ); - my ( $m1, $m2, $tmp ); - - $date1 =~ s/([\D]*)$//g; - $date2 =~ s/([\D]*)$//g; - - return if( (not $date1) or (not $date2) ); - - my $mon = 0; - - my ( @T1 ) = - ( $date1 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g ); - my ( @T2 ) = - ( $date2 =~ /([\d]+)[\s]+([\d]+):([\d]+):([\d]+)[\s]+([\d]+)/g ); - - foreach $tmp (@monList) { - $m1 = sprintf("%2.2d",$mon) if( $date1 =~ /$tmp/i ); - $m2 = sprintf("%2.2d",$mon) if( $date2 =~ /$tmp/i ); - $mon++; - } - - my $dt1 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T1[4], $m1, $T1[0], - $T1[1], $T1[2], $T1[3]); - my $dt2 = sprintf("%4.4d%s%2.2d%2.2d%2.2d%2.2d", $T2[4], $m2, $T2[0], - $T2[1], $T2[2], $T2[3]); - - my $ret = $dt1 - $dt2; - - if ( $ret > 40 ) { - $ret = abs($ret-40); - } - - return $ret; -} - sub check_count_and_time { my $event_recv_time; my $udev_fork_time; @@ -160,7 +104,7 @@ sub check_count_and_time { @line_items = split(/,/,$line); print " device: $line_items[0], action: $line_items[1] \n"; print " forking udev time: $line_items[-1]"; - $diff = cmpDate($line_items[-1], $event_recv_time); + $diff = $line_items[-1] - $event_recv_time; print " the delay time is: $diff s \n\n"; if ( $diff > $time_out+10 ) { print " the delay time is: $diff \n"; @@ -205,7 +149,7 @@ sub show_result { @line_items = split(/,/,$line); print " device: $line_items[0], action: $line_items[1] \n"; print " forking udev time: $line_items[-1]"; - $diff = cmpDate($line_items[-1], $event_recv_time); + $diff = $line_items[-1] - $event_recv_time; print " the delay time is: $diff s \n\n"; } close(LOGF); @@ -229,7 +173,7 @@ sub show_result_tm_out { @line_items = split(/,/,$line); print " device: $line_items[0], action: $line_items[1] \n"; print " forking udev time: $line_items[-1]"; - $diff = cmpDate($line_items[-1], $event_recv_time); + $diff = $line_items[-1] - $event_recv_time; print " the delay time is: $diff s \n\n"; if ( $diff < $time_out ) { print " the delay time is: $diff \n"; @@ -258,7 +202,7 @@ sub show_result_immediate { @line_items = split(/,/,$line); print " device: $line_items[0], action: $line_items[1] \n"; print " forking udev time: $line_items[-1]"; - $diff = cmpDate($line_items[-1], $event_recv_time); + $diff = $line_items[-1] - $event_recv_time; print " the delay time is: $diff s \n\n"; if ( $diff > $time_out ) { print " the delay time is: $diff \n"; @@ -285,7 +229,7 @@ sub check_exe_time { $exe_time[$i] = $line_items[-1]; $i++; } - $diff = cmpDate($exe_time[1], $exe_time[0]); + $diff = $exe_time[1] - $exe_time[0]; if ( $diff < $udev_exe_time ) { print " there are more than one udev instance for a single device at the same time. \n"; exit 1; @@ -313,7 +257,7 @@ sub run_no_seq_test { check_sysfs_device_exist("$sysfs/block/sda"); # log current system date/time - $time = getDate(); + $time = time(); udevsend(-1, "/block/sda", "add", "block"); @@ -328,7 +272,7 @@ sub run_no_seq_test { system("rm -f $log_file"); # log current system date/time - $time = getDate(); + $time = time(); udevsend(-1, "/block/sda", "remove", "block"); @@ -358,7 +302,7 @@ sub run_normal_seq_test { @file_list = glob "$sysfs/class/tty/*"; # log current system date/time for device add events - $time = getDate(); + $time = time(); # # add devices event test @@ -388,7 +332,7 @@ sub run_normal_seq_test { } # log current system date/time for device remove events - $time = getDate(); + $time = time(); # # remove devices event test @@ -443,7 +387,7 @@ sub run_random_seq_test { restart_daemon(); # log current system date/time for device remove events - $time = getDate(); + $time = time(); # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem udevsend(3, "/class/tty/tty2", "add", "tty"); @@ -460,7 +404,7 @@ sub run_random_seq_test { restart_daemon(); # log current system date/time for device remove events - $time = getDate(); + $time = time(); udevsend(3, "/class/tty/tty2", "remove", "tty"); udevsend(2, "/class/tty/tty1", "remove", "tty"); @@ -503,7 +447,7 @@ sub run_expected_seq_test { system("rm -f $log_file"); # log current system date/time for device remove events - $time = getDate(); + $time = time(); # show results udevsend(7, "/class/tty/tty2", "add", "tty"); @@ -535,7 +479,7 @@ sub run_single_instance_test { check_sysfs_device_exist("$sysfs/block/sda"); # log current system date/time - $time = getDate(); + $time = time(); udevsend(-1, "/block/sda", "add", "block"); udevsend(-1, "/block/sda", "remove", "block"); @@ -568,7 +512,7 @@ sub run_same_events_test { # log current system date/time sleep 1; - $time = getDate(); + $time = time(); system("rm -f $log_file"); udevsend(1, "/block/sda", "remove", "block"); @@ -600,7 +544,7 @@ sub run_missing_seq_test { sleep 1; # log current system date/time - $time = getDate(); + $time = time(); system("rm -f $log_file"); udevsend(3, "/block/sda", "add", "block"); From 4be25ce1d0e1cef62120a5605f8472761a26689e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 12 Dec 2004 08:34:46 +0100 Subject: [PATCH 1057/4284] [PATCH] add class specific files for class/spi_transport and class/spi_host --- udev_sysfs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index a4f293ef13..d46f1f26d8 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -54,6 +54,8 @@ static const struct subsystem_file { { .subsystem = "ieee1394_node", .file = NULL }, { .subsystem = "fc_transport", .file = "port_id" }, { .subsystem = "fc_host", .file = "port_id" }, + { .subsystem = "spi_transport", .file = "width" }, + { .subsystem = "spi_host", .file = "width" }, { NULL, NULL } }; From 9af175553d89d2a9fbc68d623f7ae213258e492b Mon Sep 17 00:00:00 2001 From: "azarah@nosferatu.za.org" Date: Tue, 14 Dec 2004 09:42:20 +0100 Subject: [PATCH 1058/4284] [PATCH] remove leftover from udevinfo's -d option --- udevinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index 340496b42b..ce9804e216 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -242,7 +242,7 @@ static int print_sysfs_devices(void) static int process_options(int argc, char *argv[]) { - static const char short_options[] = "adn:p:q:rsVh"; + static const char short_options[] = "an:p:q:rsVh"; int option; int retval = 1; struct udevice udev; @@ -439,7 +439,7 @@ exit: } help: - printf("Usage: udevinfo [-anpqrdVh]\n" + printf("Usage: udevinfo [-anpqrVh]\n" " -q TYPE query database for the specified value:\n" " 'name' name of device node\n" " 'symlink' pointing to node\n" From bc0410fdb64e295ae74d990185fa0bbc883e5432 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 14 Dec 2004 11:06:49 +0100 Subject: [PATCH 1059/4284] [PATCH] export DEVNAME regardless of the state of udev_dev_d --- udev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/udev.c b/udev.c index 0ee70529c4..a9da014ea6 100644 --- a/udev.c +++ b/udev.c @@ -209,9 +209,10 @@ int main(int argc, char *argv[], char *envp[]) } /* run dev.d/ scripts if we created/deleted a node or changed a netif name */ - if (udev_dev_d && udev.devname[0] != '\0') { + if (udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); + if (udev_dev_d) + udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } } else if ((strncmp(devpath, "/devices/", 9) == 0)) { if (strcmp(action, "add") == 0) { From 027263f0056e7cbd43c0860ba5dcafd9e4cac916 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 14 Dec 2004 11:42:06 +0100 Subject: [PATCH 1060/4284] [PATCH] update klibc to 0.194 --- klibc/MCONFIG | 14 +++-- klibc/Makefile | 2 +- klibc/include/arch/m32r/klibc/archsetjmp.h | 21 ++++++++ klibc/include/arch/m32r/klibc/archsignal.h | 13 +++++ klibc/include/arch/m32r/klibc/archstat.h | 37 +++++++++++++ klibc/include/arch/m32r/klibc/archsys.h | 12 +++++ klibc/include/sched.h | 4 +- klibc/include/stdio.h | 4 +- klibc/include/stdlib.h | 1 + klibc/include/sys/mount.h | 23 ++++++-- klibc/include/syslog.h | 9 ++++ klibc/klibc.spec | 2 +- klibc/klibc/MCONFIG | 2 +- klibc/klibc/Makefile | 12 ++--- klibc/klibc/README | 5 +- klibc/klibc/SYSCALLS.def | 15 ++++-- klibc/klibc/arch/ia64/pipe.c | 2 +- klibc/klibc/arch/m32r/MCONFIG | 18 +++++++ klibc/klibc/arch/m32r/Makefile.inc | 19 +++++++ klibc/klibc/arch/m32r/crt0.S | 25 +++++++++ klibc/klibc/arch/m32r/setjmp.S | 47 ++++++++++++++++ klibc/klibc/arch/m32r/syscall.S | 29 ++++++++++ klibc/klibc/arch/m32r/sysstub.ph | 25 +++++++++ klibc/klibc/arch/ppc/setjmp.S | 2 +- klibc/klibc/arch/ppc64/MCONFIG | 6 ++- klibc/klibc/arch/ppc64/Makefile.inc | 2 +- klibc/klibc/arch/ppc64/sysstub.ph | 5 +- klibc/klibc/arch/x86_64/MCONFIG | 6 +++ klibc/klibc/asprintf.c | 4 +- klibc/klibc/atexit.h | 2 - klibc/klibc/exitc.c | 15 +----- klibc/klibc/fork.c | 3 +- klibc/klibc/jrand48.c | 12 ++--- klibc/klibc/makeerrlist.pl | 21 +++++--- klibc/klibc/sbrk.c | 2 +- klibc/klibc/strcspn.c | 11 ++++ klibc/klibc/strpbrk.c | 14 +++++ klibc/klibc/strspn.c | 62 ++-------------------- klibc/klibc/strxspn.c | 30 +++++++++++ klibc/klibc/strxspn.h | 13 +++++ klibc/klibc/syslog.c | 13 +++-- klibc/klibc/vasprintf.c | 4 +- klibc/version | 2 +- 43 files changed, 437 insertions(+), 133 deletions(-) create mode 100644 klibc/include/arch/m32r/klibc/archsetjmp.h create mode 100644 klibc/include/arch/m32r/klibc/archsignal.h create mode 100644 klibc/include/arch/m32r/klibc/archstat.h create mode 100644 klibc/include/arch/m32r/klibc/archsys.h create mode 100644 klibc/klibc/arch/m32r/MCONFIG create mode 100644 klibc/klibc/arch/m32r/Makefile.inc create mode 100644 klibc/klibc/arch/m32r/crt0.S create mode 100644 klibc/klibc/arch/m32r/setjmp.S create mode 100644 klibc/klibc/arch/m32r/syscall.S create mode 100644 klibc/klibc/arch/m32r/sysstub.ph create mode 100644 klibc/klibc/strcspn.c create mode 100644 klibc/klibc/strpbrk.c create mode 100644 klibc/klibc/strxspn.c create mode 100644 klibc/klibc/strxspn.h diff --git a/klibc/MCONFIG b/klibc/MCONFIG index d2aa23626c..7da150d031 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -6,19 +6,23 @@ # Eventually support separate compilation, but we don't have it yet... OBJROOT = $(SRCROOT) +# Kernel trees (source and obj) - can potentially be different +KRNLSRC = $(SRCROOT)/linux +KRNLOBJ = $(SRCROOT)/linux + ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) CROSS = CC = $(CROSS)gcc LD = $(CROSS)ld KLIBSRC = $(SRCROOT)/klibc KLIBOBJ = $(OBJROOT)/klibc -REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include \ - -D__KLIBC__ -DBITSIZE=$(BITSIZE) \ - -I$(SRCROOT)/include/arch/$(ARCH) \ +INCLUDE = -I$(SRCROOT)/include/arch/$(ARCH) \ -I$(SRCROOT)/include/bits$(BITSIZE) \ -I$(SRCROOT)/include \ - -I$(SRCROOT)/linux/include -I$(SRCROOT)/linux/include2 - + -I$(KRNLOBJ)/include -I$(KRNLOBJ)/include2 -I$(KRNLSRC)/include +REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include \ + -D__KLIBC__ -DBITSIZE=$(BITSIZE) \ + $(INCLUDE) LDFLAGS = AR = $(CROSS)ar RANLIB = $(CROSS)ranlib diff --git a/klibc/Makefile b/klibc/Makefile index 8823a33bfd..2506417ef5 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -1,5 +1,5 @@ VERSION := $(shell cat version) -SUBDIRS = klibc +SUBDIRS = klibc ash ipconfig nfsmount utils kinit gzip all: diff --git a/klibc/include/arch/m32r/klibc/archsetjmp.h b/klibc/include/arch/m32r/klibc/archsetjmp.h new file mode 100644 index 0000000000..e16a83517a --- /dev/null +++ b/klibc/include/arch/m32r/klibc/archsetjmp.h @@ -0,0 +1,21 @@ +/* + * arch/m32r/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + unsigned long __r8; + unsigned long __r9; + unsigned long __r10; + unsigned long __r11; + unsigned long __r12; + unsigned long __r13; + unsigned long __r14; + unsigned long __r15; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/m32r/klibc/archsignal.h b/klibc/include/arch/m32r/klibc/archsignal.h new file mode 100644 index 0000000000..02596e9a1c --- /dev/null +++ b/klibc/include/arch/m32r/klibc/archsignal.h @@ -0,0 +1,13 @@ +/* + * arch/m32r/include/klibc/archsignal.h + * + * Architecture-specific signal definitions + * + */ + +#ifndef _KLIBC_ARCHSIGNAL_H +#define _KLIBC_ARCHSIGNAL_H + +/* No special stuff for this architecture */ + +#endif diff --git a/klibc/include/arch/m32r/klibc/archstat.h b/klibc/include/arch/m32r/klibc/archstat.h new file mode 100644 index 0000000000..154820755f --- /dev/null +++ b/klibc/include/arch/m32r/klibc/archstat.h @@ -0,0 +1,37 @@ +#ifndef _KLIBC_ARCHSTAT_H +#define _KLIBC_ARCHSTAT_H + +#define _STATBUF_ST_NSEC + +/* This matches struct stat64 in glibc2.1, hence the absolutely + * insane amounts of padding around dev_t's. + */ +struct stat { + unsigned long long st_dev; + unsigned char __pad0[4]; + + unsigned long __st_ino; + + unsigned int st_mode; + unsigned int st_nlink; + + unsigned long st_uid; + unsigned long st_gid; + + unsigned long long st_rdev; + unsigned char __pad3[4]; + + long long st_size; + unsigned long st_blksize; + + unsigned long st_blocks; /* Number 512-byte blocks allocated. */ + unsigned long __pad4; /* future possible st_blocks high bits */ + + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + + unsigned long long st_ino; +}; + +#endif diff --git a/klibc/include/arch/m32r/klibc/archsys.h b/klibc/include/arch/m32r/klibc/archsys.h new file mode 100644 index 0000000000..386db8b505 --- /dev/null +++ b/klibc/include/arch/m32r/klibc/archsys.h @@ -0,0 +1,12 @@ +/* + * arch/m32r/include/klibc/archsys.h + * + * Architecture-specific syscall definitions + */ + +#ifndef _KLIBC_ARCHSYS_H +#define _KLIBC_ARCHSYS_H + +/* No special syscall definitions for this architecture */ + +#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/sched.h b/klibc/include/sched.h index fcf62a6e4f..3465b5705c 100644 --- a/klibc/include/sched.h +++ b/klibc/include/sched.h @@ -25,7 +25,9 @@ __extern int sched_yield(void); __extern pid_t __clone2(int, void *, void *); static __inline__ pid_t __clone(int _f, void *_sp) { - return __clone2(_f, _sp, 0); + /* If this is used with _sp != 0 it will have the effect of the sp + and rsp growing away from a single point in opposite directions. */ + return __clone2(_f, _sp, _sp); } #else __extern pid_t __clone(int, void *); diff --git a/klibc/include/stdio.h b/klibc/include/stdio.h index e00fac4d5e..d30622cfb2 100644 --- a/klibc/include/stdio.h +++ b/klibc/include/stdio.h @@ -90,7 +90,7 @@ fread(void *__p, size_t __s, size_t __n, FILE *__f) } extern __inline__ size_t -fwrite(void *__p, size_t __s, size_t __n, FILE *__f) +fwrite(const void *__p, size_t __s, size_t __n, FILE *__f) { return _fwrite(__p, __s*__n, __f)/__s; } @@ -104,6 +104,8 @@ __extern int sprintf(char *, const char *, ...); __extern int vsprintf(char *, const char *, va_list); __extern int snprintf(char *, size_t n, const char *, ...); __extern int vsnprintf(char *, size_t n, const char *, va_list); +__extern int asprintf(char **, const char *, ...); +__extern int vasprintf(char **, const char *, va_list); /* No buffering, so no flushing needed */ extern __inline__ int diff --git a/klibc/include/stdlib.h b/klibc/include/stdlib.h index be4e76ed9f..54d45043f7 100644 --- a/klibc/include/stdlib.h +++ b/klibc/include/stdlib.h @@ -21,6 +21,7 @@ __extern __noreturn abort(void); static __inline__ int abs(int __n) { return (__n < 0) ? -__n : __n; } +__extern int system(const char * string); __extern int atexit(void (*)(void)); __extern int on_exit(void (*)(int, void *), void *); __extern int atoi(const char *); diff --git a/klibc/include/sys/mount.h b/klibc/include/sys/mount.h index 313c90ec0e..0e1bce49bf 100644 --- a/klibc/include/sys/mount.h +++ b/klibc/include/sys/mount.h @@ -6,6 +6,7 @@ #define _SYS_MOUNT_H #include +#include /* * These are the fs-independent mount-flags: up to 32 flags are supported @@ -17,13 +18,16 @@ #define MS_SYNCHRONOUS 16 /* Writes are synced at once */ #define MS_REMOUNT 32 /* Alter flags of a mounted FS */ #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ -#define MS_DIRSYNC 128 /* Directory modifications are synchronous */ +#define MS_DIRSYNC 128 /* Directory modifications are synchronous */ #define MS_NOATIME 1024 /* Do not update access times. */ #define MS_NODIRATIME 2048 /* Do not update directory access times */ #define MS_BIND 4096 -#define MS_MOVE 8192 +#define MS_MOVE 8192 #define MS_REC 16384 #define MS_VERBOSE 32768 +#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ +#define MS_ONE_SECOND (1<<17) /* fs has 1 sec a/m/ctime resolution */ +#define MS_ACTIVE (1<<30) #define MS_NOUSER (1<<31) /* @@ -40,7 +44,20 @@ /* * umount2() flags */ -#define MNT_FORCE 1 +#define MNT_FORCE 1 /* Forcibly unmount */ +#define MNT_DETACH 2 /* Detach from tree only */ +#define MNT_EXPIRE 4 /* Mark for expiry */ + +/* + * Block device ioctls + */ +#define BLKROSET _IO(0x12, 93) /* Set device read-only (0 = read-write). */ +#define BLKROGET _IO(0x12, 94) /* Get read-only status (0 = read_write). */ +#define BLKRRPART _IO(0x12, 95) /* Re-read partition table. */ +#define BLKGETSIZE _IO(0x12, 96) /* Return device size. */ +#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */ +#define BLKRASET _IO(0x12, 98) /* Set read ahead for block device. */ +#define BLKRAGET _IO(0x12, 99) /* Get current read ahead setting. */ /* * Prototypes diff --git a/klibc/include/syslog.h b/klibc/include/syslog.h index 551527a042..061dbcd5a7 100644 --- a/klibc/include/syslog.h +++ b/klibc/include/syslog.h @@ -47,6 +47,15 @@ #define LOG_FACMASK 01770 #define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3)) +/* openlog() flags; only LOG_PID and LOG_PERROR supported */ +#define LOG_PID 0x01 /* include pid with message */ +#define LOG_CONS 0x02 /* write to console on logger error */ +#define LOG_ODELAY 0x04 /* delay connection until syslog() */ +#define LOG_NDELAY 0x08 /* open connection immediately */ +#define LOG_NOWAIT 0x10 /* wait for child processes (unused on linux) */ +#define LOG_PERROR 0x20 /* additional logging to stderr */ + + __extern void openlog(const char *, int, int); __extern void syslog(int, const char *, ...); __extern void vsyslog(int, const char *, va_list); diff --git a/klibc/klibc.spec b/klibc/klibc.spec index 6166a35c4d..272e52bc1a 100644 --- a/klibc/klibc.spec +++ b/klibc/klibc.spec @@ -1,6 +1,6 @@ Summary: A minimal libc subset for use with initramfs. Name: klibc -Version: 0.181 +Version: 0.194 Release: 1 License: BSD/GPL Group: Development/Libraries diff --git a/klibc/klibc/MCONFIG b/klibc/klibc/MCONFIG index 5b6eecd037..499b6e8b56 100644 --- a/klibc/klibc/MCONFIG +++ b/klibc/klibc/MCONFIG @@ -13,6 +13,6 @@ ifeq ($(ERRLIST),1) REQFLAGS += -DWITH_ERRLIST endif -CFLAGS = -Wp,-MD,$(dir $*).$(notdir $*).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) +CFLAGS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) SOFLAGS = -fPIC diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 3519b45089..0d44ce5494 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -34,8 +34,8 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ strcasecmp.o strncasecmp.o strndup.o strerror.o \ strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o strnlen.o \ strncat.o strlcpy.o strlcat.o \ - strstr.o strncmp.o strncpy.o strrchr.o strspn.o \ - strsep.o strtok.o \ + strstr.o strncmp.o strncpy.o strrchr.o \ + strxspn.o strspn.o strcspn.o strpbrk.o strsep.o strtok.o \ gethostname.o getdomainname.o getcwd.o \ seteuid.o setegid.o \ getenv.o setenv.o putenv.o __put_env.o unsetenv.o \ @@ -59,7 +59,7 @@ LIB = libc.a INTERP_O = interp.o -all: $(CRT0) $(LIB) $(SOLIB) klibc.so +all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so # Add any architecture-specific rules include arch/$(ARCH)/Makefile.inc @@ -120,14 +120,14 @@ crt0.o: arch/$(ARCH)/crt0.o cp arch/$(ARCH)/crt0.o . errlist.c: - $(PERL) makeerrlist.pl -errlist > $@ || rm -f $@ + $(PERL) makeerrlist.pl -q $(INCLUDE) -errlist > $@ || rm -f $@ # We pass -ansi to keep cpp from define e.g. "i386" as well as "__i386__" SYSCALLS.i: SYSCALLS.def $(CC) $(CFLAGS) -D__ASSEMBLY__ -ansi -x assembler-with-cpp -E -o $@ $< -syscalls.nrs: ../include/sys/syscall.h ../include/arch/$(ARCH)/klibc/archsys.h ../linux/include/asm/unistd.h - $(CC) $(CFLAGS) -Wp,-dM -x c -E -o $@ ../include/sys/syscall.h +syscalls.nrs: ../include/sys/syscall.h + $(CC) $(CFLAGS) -Wp,-dM -x c -E -o $@ $< syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscalls.nrs rm -rf syscalls diff --git a/klibc/klibc/README b/klibc/klibc/README index edc8524f22..3a53a8809f 100644 --- a/klibc/klibc/README +++ b/klibc/klibc/README @@ -38,10 +38,11 @@ b) If you're cross-compiling, change ARCH in the main MCONFIG file to arm-thumb: Untested arm26: Not yet ported arm: Working - cris: Untested + cris: Working h8300: Not yet ported i386: Working ia64: Working + m32r: Untested m68k: Not yet ported mips64: Not yet ported mips: Working @@ -51,7 +52,7 @@ b) If you're cross-compiling, change ARCH in the main MCONFIG file to s390: Working static, shared untested s390x: Working sh: Untested - sparc64: sigaction() fails in ash for unknown reason + sparc64: Untested sparc: Working v850: Not yet ported x86-64: Working diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def index dbd7dc8434..4591d0b983 100644 --- a/klibc/klibc/SYSCALLS.def +++ b/klibc/klibc/SYSCALLS.def @@ -15,6 +15,7 @@ ; ; Process-related syscalls ; + void _exit,exit::_exit(int) pid_t clone::__clone(unsigned long, void *) pid_t clone::__clone2(unsigned long, void *, void *) pid_t fork() @@ -65,7 +66,7 @@ int setresuid32,setresuid::setresuid(int, uid_t, uid, uid_t) int mount(const char *, const char *, const char *, unsigned long, const void *) int umount2(const char *, int) int umount::umount2(const char *, int) - int pivot_root(const char *, const char *) + int pivot_root(const char *, const char *) int sync() #ifdef __NR_statfs64 int statfs64::__statfs64(const char *, size_t, struct statfs *) @@ -99,9 +100,12 @@ mode_t umask(mode_t) int chroot(const char *) int symlink(const char *, const char *) int readlink(const char *, char *, size_t) -int stat64,stat::stat(const char *, struct stat *) -int lstat64,lstat::lstat(const char *, struct stat *) -int fstat64,fstat::fstat(int, struct stat *) + int stat64,stat::stat(const char *, struct stat *) + int lstat64,lstat::lstat(const char *, struct stat *) + int fstat64,fstat::fstat(int, struct stat *) + int stat::stat(const char *, struct stat *) + int lstat::lstat(const char *, struct stat *) + int fstat::fstat(int, struct stat *) int getdents64,getdents::getdents(unsigned int, struct dirent *, unsigned int) int chown32,chown::chown(const char *, uid_t, gid_t) int fchown32,fchown::fchown(int, uid_t, gid_t) @@ -123,7 +127,8 @@ int close(int) int dup(int) int dup2(int, int) int fcntl64@varadic::fcntl(int, int, unsigned long) - int fcntl64,fcntl::fcntl(int, int, unsigned long) + int fcntl(int, int, unsigned long) + int fcntl64,fcntl::fcntl(int, int, unsigned long) int ioctl(int, int, void *) int flock(int, int) int _newselect,select::select(int, fd_set *, fd_set *, fd_set *, struct timeval *) diff --git a/klibc/klibc/arch/ia64/pipe.c b/klibc/klibc/arch/ia64/pipe.c index 0b641e8702..87a6981e55 100644 --- a/klibc/klibc/arch/ia64/pipe.c +++ b/klibc/klibc/arch/ia64/pipe.c @@ -2,7 +2,7 @@ * pipe.c */ -#include "syscommon.h" +#include #include #define ASM_CLOBBERS ,"out2", "out3", "out4", "out5", "out6", "out7", \ diff --git a/klibc/klibc/arch/m32r/MCONFIG b/klibc/klibc/arch/m32r/MCONFIG new file mode 100644 index 0000000000..6706d9ddc1 --- /dev/null +++ b/klibc/klibc/arch/m32r/MCONFIG @@ -0,0 +1,18 @@ +# -*- makefile -*- +# +# arch/m32r/MCONFIG +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 32 + +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 224 MB - normal binaries start at 0 (?) +# (lib?)gcc on cris seems to insist on producing .init and .fini sections +SHAREDFLAGS = --section-start .init=0x0e000100 diff --git a/klibc/klibc/arch/m32r/Makefile.inc b/klibc/klibc/arch/m32r/Makefile.inc new file mode 100644 index 0000000000..43cb44ef8f --- /dev/null +++ b/klibc/klibc/arch/m32r/Makefile.inc @@ -0,0 +1,19 @@ +# -*- makefile -*- +# +# arch/m32r/Makefile.inc +# +# Special rules for this architecture. Note that this is actually +# included from the main Makefile, and that pathnames should be +# accordingly. +# + +ARCHOBJS = \ + arch/$(ARCH)/setjmp.o \ + arch/$(ARCH)/syscall.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o + +archclean: diff --git a/klibc/klibc/arch/m32r/crt0.S b/klibc/klibc/arch/m32r/crt0.S new file mode 100644 index 0000000000..1589a774a2 --- /dev/null +++ b/klibc/klibc/arch/m32r/crt0.S @@ -0,0 +1,25 @@ +# +# arch/m32r/crt0.S +# +# Does arch-specific initialization and invokes __libc_init +# with the appropriate arguments. +# +# See __static_init.c or __shared_init.c for the expected +# arguments. +# + + .text + .balign 4 + .type _start,@function + .globl _start +_start: + /* Save the address of the ELF argument array */ + mv r0, sp + + /* atexit() function (assume null) */ + xor r1, r1 + + bl __libc_init + + .size _start, .-_start + diff --git a/klibc/klibc/arch/m32r/setjmp.S b/klibc/klibc/arch/m32r/setjmp.S new file mode 100644 index 0000000000..14ef7e3577 --- /dev/null +++ b/klibc/klibc/arch/m32r/setjmp.S @@ -0,0 +1,47 @@ +# +# arch/m32r/setjmp.S +# +# setjmp/longjmp for the M32R architecture +# + +# +# The jmp_buf is assumed to contain the following, in order: +# r8-r15 +# +# Note that r14 is the return address register and +# r15 is the stack pointer. +# + + .text + .balign 4 + .globl setjmp + .type setjmp, @function +setjmp: + st r8, @r0 + st r9, @+r0 + st r10, @+r0 + st r11, @+r0 + st r12, @+r0 + st r13, @+r0 + st r14, @+r0 + st r15, @+r0 + xor r0, r0 + jmp r14 + .size setjmp,.-setjmp + + .text + .balign 4 + .globl longjmp + .type longjmp, @function +longjmp: + ld r8, @r0+ + ld r9, @r0+ + ld r10, @r0+ + ld r11, @r0+ + ld r12, @r0+ + ld r13, @r0+ + ld r14, @r0+ + ld r15, @r0 + mv r0, r1 + jmp r14 + .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/m32r/syscall.S b/klibc/klibc/arch/m32r/syscall.S new file mode 100644 index 0000000000..a20a33667f --- /dev/null +++ b/klibc/klibc/arch/m32r/syscall.S @@ -0,0 +1,29 @@ +/* + * arch/m32r/syscall.S + * + * r7 contains the syscall number (set by stub); + * r0..r3 contains arguments 0-3 per standard calling convention; + * r4..r5 contains arguments 4-5, but we have to get those from + * the stack. + */ + + .section ".text","ax" + .balign 4 + .globl __syscall_common + .type __syscall_common,@function +__syscall_common: + ld r4,@sp + ld r5,@(4,sp) + trap #2 + cmpi r0, #-4096 + bnc 1f + jmp r14 +1: + seth r2,#high(errno) + or3 r2,r2,#low(errno) + neg r1,r0 + st r1,@r7 + ldi r0,#-1 + jmp r14 + + .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/m32r/sysstub.ph b/klibc/klibc/arch/m32r/sysstub.ph new file mode 100644 index 0000000000..3813ea4144 --- /dev/null +++ b/klibc/klibc/arch/m32r/sysstub.ph @@ -0,0 +1,25 @@ +# -*- perl -*- +# +# arch/m32r/sysstub.ph +# +# Script to generate system call stubs +# + +sub make_sysstub($$$$@) { + my($fname, $type, $sname, $stype, @args) = @_; + + open(OUT, '>', "syscalls/${fname}.S"); + print OUT "#include \n"; + print OUT "\n"; + print OUT "\t.text\n"; + print OUT "\t.type\t${fname},\@function\n"; + print OUT "\t.globl\t${fname}\n"; + print OUT "\t.balign\t4\n"; + print OUT "${fname}:\n"; + print OUT "\tldi\tr7,#__NR_${sname}\n"; + print OUT "\tbra\t__syscall_common\n"; + print OUT "\t.size ${fname},.-${fname}\n"; + close(OUT); +} + +1; diff --git a/klibc/klibc/arch/ppc/setjmp.S b/klibc/klibc/arch/ppc/setjmp.S index 1c50301707..3012de3ea6 100644 --- a/klibc/klibc/arch/ppc/setjmp.S +++ b/klibc/klibc/arch/ppc/setjmp.S @@ -32,4 +32,4 @@ longjmp: blr /* return */ .size longjmp,.-longjmp - \ No newline at end of file + diff --git a/klibc/klibc/arch/ppc64/MCONFIG b/klibc/klibc/arch/ppc64/MCONFIG index 86526f895c..09881b8d40 100644 --- a/klibc/klibc/arch/ppc64/MCONFIG +++ b/klibc/klibc/arch/ppc64/MCONFIG @@ -7,8 +7,10 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer -BITSIZE = 64 +ARCHREQFLAGS = -m64 -mcall-aixdesc +OPTFLAGS = -Os -fomit-frame-pointer +BITSIZE = 64 +LDFLAGS = -m elf64ppc # Extra linkflags when building the shared version of the library # This address needs to be reachable using normal inter-module diff --git a/klibc/klibc/arch/ppc64/Makefile.inc b/klibc/klibc/arch/ppc64/Makefile.inc index 928df1aeb7..d1e128fdce 100644 --- a/klibc/klibc/arch/ppc64/Makefile.inc +++ b/klibc/klibc/arch/ppc64/Makefile.inc @@ -19,7 +19,7 @@ interp.o: interp1.o klibc.got $(LD) $(LDFLAGS) -r -o $@ interp1.o klibc.got klibc.got: $(SOHASH) - $(OBJCOPY) -j.got $< $@ + $(OBJCOPY) -j .got $< $@ archclean: rm -f klibc.got diff --git a/klibc/klibc/arch/ppc64/sysstub.ph b/klibc/klibc/arch/ppc64/sysstub.ph index 1469cc6071..0a379158e1 100644 --- a/klibc/klibc/arch/ppc64/sysstub.ph +++ b/klibc/klibc/arch/ppc64/sysstub.ph @@ -16,16 +16,13 @@ sub make_sysstub($$$$@) { print OUT "\t.align 3\n"; print OUT "${fname}:\n"; print OUT "\t.quad .${fname},.TOC.\@tocbase,0\n"; - print OUT "\t.size ${fname},24\n"; print OUT "\t.text\n"; print OUT "\t.type .${fname},\@function\n"; print OUT "\t.globl .${fname}\n"; print OUT ".${fname}:\n"; print OUT "\tli 0,__NR_${sname}\n"; print OUT "\tsc\n"; - print OUT "\tmfcr 0\n"; - print OUT "\trldicl. 9,0,36,63\n"; - print OUT "\tbeqlr- 0\n"; + print OUT "\tbnslr\n"; print OUT "\tb .__syscall_error\n"; print OUT "\t.size .${fname},.-.${fname}\n"; close(OUT); diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG index f3c87410a6..a2a2367633 100644 --- a/klibc/klibc/arch/x86_64/MCONFIG +++ b/klibc/klibc/arch/x86_64/MCONFIG @@ -20,3 +20,9 @@ OPTFLAGS = -Os -fno-asynchronous-unwind-tables -fomit-frame-pointer \ BITSIZE = 64 LDFLAGS = -m elf_x86_64 +# Extra linkflags when building the shared version of the library +# This address needs to be reachable using normal inter-module +# calls, and work on the memory models for this architecture +# 2 MB - normal binaries start at 4 MB +SHAREDFLAGS = -Ttext 0x00200200 + diff --git a/klibc/klibc/asprintf.c b/klibc/klibc/asprintf.c index 457d34bb15..6002b576e1 100644 --- a/klibc/klibc/asprintf.c +++ b/klibc/klibc/asprintf.c @@ -16,10 +16,10 @@ int asprintf(char **bufp, const char *format, ...) va_start(ap, format); va_copy(ap1, ap); - bytes = vsnprintf(NULL, 0, format, ap1); + bytes = vsnprintf(NULL, 0, format, ap1) + 1; va_end(ap1); - *bufp = p = malloc(bytes+1); + *bufp = p = malloc(bytes); if ( !p ) return -1; diff --git a/klibc/klibc/atexit.h b/klibc/klibc/atexit.h index a60d641e23..792141def5 100644 --- a/klibc/klibc/atexit.h +++ b/klibc/klibc/atexit.h @@ -13,7 +13,5 @@ struct atexit { struct atexit *next; }; -extern struct atexit *__atexit_list; - #endif /* ATEXIT_H */ diff --git a/klibc/klibc/exitc.c b/klibc/klibc/exitc.c index 6e5d78979d..8819737fb7 100644 --- a/klibc/klibc/exitc.c +++ b/klibc/klibc/exitc.c @@ -1,9 +1,7 @@ /* * exit.c * - * Note: all programs need exit(), since it's invoked from - * crt0.o. Therefore there is no point in breaking apart - * exit() and _exit(). + * Implement exit() */ #include @@ -14,11 +12,6 @@ #if !defined(__i386__) && !defined(__x86_64__) -#define __NR___exit __NR_exit - -/* Syscalls can't return void... */ -static inline _syscall1(int,__exit,int,rv); - /* This allows atexit/on_exit to install a hook */ __noreturn (*__exit_handler)(int) = _exit; @@ -27,10 +20,4 @@ __noreturn exit(int rv) __exit_handler(rv); } -__noreturn _exit(int rv) -{ - __exit(rv); - for(;;); -} - #endif diff --git a/klibc/klibc/fork.c b/klibc/klibc/fork.c index daf313eaf2..fcd73bd60b 100644 --- a/klibc/klibc/fork.c +++ b/klibc/klibc/fork.c @@ -8,11 +8,10 @@ #include #include #include +#include #ifndef __NR_fork -extern pid_t __clone(unsigned long flags, void * newsp); - pid_t fork(void) { return __clone(SIGCHLD, 0); diff --git a/klibc/klibc/jrand48.c b/klibc/klibc/jrand48.c index a2ead11e5f..660a6e5a71 100644 --- a/klibc/klibc/jrand48.c +++ b/klibc/klibc/jrand48.c @@ -10,15 +10,15 @@ long jrand48(unsigned short xsubi[3]) uint64_t x; /* The xsubi[] array is littleendian by spec */ - x = (uint64_t)xsubi[0] + - ((uint64_t)xsubi[1] << 16) + - ((uint64_t)xsubi[2] << 32); + x = (uint64_t)(uint16_t)xsubi[0] + + ((uint64_t)(uint16_t)xsubi[1] << 16) + + ((uint64_t)(uint16_t)xsubi[2] << 32); x = (0x5deece66dULL * x) + 0xb; - xsubi[0] = (unsigned short)x; - xsubi[1] = (unsigned short)(x >> 16); - xsubi[2] = (unsigned short)(x >> 32); + xsubi[0] = (unsigned short)(uint16_t)x; + xsubi[1] = (unsigned short)(uint16_t)(x >> 16); + xsubi[2] = (unsigned short)(uint16_t)(x >> 32); return (long)(int32_t)(x >> 16); } diff --git a/klibc/klibc/makeerrlist.pl b/klibc/klibc/makeerrlist.pl index f42704f88a..14498d880a 100644 --- a/klibc/klibc/makeerrlist.pl +++ b/klibc/klibc/makeerrlist.pl @@ -10,20 +10,27 @@ use FileHandle; %errors = (); %errmsg = (); $maxerr = -1; -$rootdir = '../linux/include/'; # Must have trailing / +@includelist = (); # Include directories sub parse_file($) { my($file) = @_; my($fh) = new FileHandle; my($line, $error, $msg); my($kernelonly) = 0; - - $file = $rootdir.$file; + my($root); print STDERR "opening $file\n" unless ( $quiet ); - if ( !($fh->open("< ".$file)) ) { - die "$0: cannot open $file\n"; + $ok = 0; + foreach $root ( @includelist ) { + if ( $fh->open($root.'//'.$file, '<') ) { + $ok = 1; + last; + } + } + + if ( ! $ok ) { + die "$0: Cannot find file $file\n"; } while ( defined($line = <$fh>) ) { @@ -61,8 +68,10 @@ foreach $arg ( @ARGV ) { $quiet = 1; } elsif ( $arg =~ /^-(errlist|errnos|maxerr)$/ ) { $type = $arg; + } elsif ( $arg =~ '^\-I' ) { + push(@includelist, "$'"); } else { - die "$0: Unknown option: $arg\n"; + die "$0: Unknown option: $arg\n"; } } diff --git a/klibc/klibc/sbrk.c b/klibc/klibc/sbrk.c index f7401dcfe2..cb0efb21b9 100644 --- a/klibc/klibc/sbrk.c +++ b/klibc/klibc/sbrk.c @@ -37,5 +37,5 @@ void *sbrk(ptrdiff_t increment) } __current_brk = new_brk; - return end; + return start; } diff --git a/klibc/klibc/strcspn.c b/klibc/klibc/strcspn.c new file mode 100644 index 0000000000..87d644551e --- /dev/null +++ b/klibc/klibc/strcspn.c @@ -0,0 +1,11 @@ +/* + * strcspn + */ + +#include "strxspn.h" + +size_t +strcspn(const char *s, const char *reject) +{ + return __strxspn(s, reject, 1); +} diff --git a/klibc/klibc/strpbrk.c b/klibc/klibc/strpbrk.c new file mode 100644 index 0000000000..86ea236308 --- /dev/null +++ b/klibc/klibc/strpbrk.c @@ -0,0 +1,14 @@ +/* + * strpbrk + */ + +#include "strxspn.h" + +char * +strpbrk(const char *s, const char *accept) +{ + const char *ss = s+__strxspn(s, accept, 1); + + return *ss ? (char *)ss : NULL; +} + diff --git a/klibc/klibc/strspn.c b/klibc/klibc/strspn.c index 856a964197..10b1dfc5fa 100644 --- a/klibc/klibc/strspn.c +++ b/klibc/klibc/strspn.c @@ -1,67 +1,11 @@ /* - * strspn, strcspn + * strspn */ -#include -#include -#include -#include - -#ifndef LONG_BIT -#define LONG_BIT (CHAR_BIT*sizeof(long)) -#endif - -static inline void -set_bit(unsigned long *bitmap, unsigned int bit) -{ - bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT); -} - -static inline int -test_bit(unsigned long *bitmap, unsigned int bit) -{ - return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1; -} - -static size_t -strxspn(const char *s, const char *map, int parity) -{ - unsigned long matchmap[((1 << CHAR_BIT)+LONG_BIT-1)/LONG_BIT]; - size_t n = 0; - - /* Create bitmap */ - memset(matchmap, 0, sizeof matchmap); - while ( *map ) - set_bit(matchmap, (unsigned char) *map++); - - /* Make sure the null character never matches */ - if ( parity ) - set_bit(matchmap, 0); - - /* Calculate span length */ - while ( test_bit(matchmap, (unsigned char) *s++)^parity ) - n++; - - return n; -} +#include "strxspn.h" size_t strspn(const char *s, const char *accept) { - return strxspn(s, accept, 0); + return __strxspn(s, accept, 0); } - -size_t -strcspn(const char *s, const char *reject) -{ - return strxspn(s, reject, 1); -} - -char * -strpbrk(const char *s, const char *accept) -{ - const char *ss = s+strxspn(s, accept, 1); - - return *ss ? (char *)ss : NULL; -} - diff --git a/klibc/klibc/strxspn.c b/klibc/klibc/strxspn.c new file mode 100644 index 0000000000..618c0bcdb5 --- /dev/null +++ b/klibc/klibc/strxspn.c @@ -0,0 +1,30 @@ +/* + * strpbrk + */ + +#include +#include +#include +#include +#include "strxspn.h" + +size_t +__strxspn(const char *s, const char *map, int parity) +{ + char matchmap[UCHAR_MAX+1]; + size_t n = 0; + + /* Create bitmap */ + memset(matchmap, 0, sizeof matchmap); + while ( *map ) + matchmap[(unsigned char) *map++] = 1; + + /* Make sure the null character never matches */ + matchmap[0] = parity; + + /* Calculate span length */ + while ( matchmap[(unsigned char) *s++] ^ parity ) + n++; + + return n; +} diff --git a/klibc/klibc/strxspn.h b/klibc/klibc/strxspn.h new file mode 100644 index 0000000000..5e1a21922f --- /dev/null +++ b/klibc/klibc/strxspn.h @@ -0,0 +1,13 @@ +/* + * strxspn.h + */ + +#ifndef STRXSPN_H +#define STRXSPN_H + +#include + +extern size_t +__strxspn(const char *s, const char *map, int parity); + +#endif diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c index e9d84d9ddc..0cd296ab85 100644 --- a/klibc/klibc/syslog.c +++ b/klibc/klibc/syslog.c @@ -18,10 +18,11 @@ #define LOGDEV "/dev/kmsg" /* Max length of ID string */ -#define MAXID 31 /* MAXID+6 must be < BUFLEN */ +#define MAXID 31 /* MAXID+5 must be < BUFLEN */ int __syslog_fd = -1; static char id[MAXID+1]; +static int syslog_flags = 0; void openlog(const char *ident, int option, int facility) { @@ -36,8 +37,9 @@ void openlog(const char *ident, int option, int facility) fcntl(fd, F_SETFD, (long)FD_CLOEXEC); } + syslog_flags = option; + strncpy(id, ident?ident:"", MAXID); - id[MAXID] = '\0'; /* Make sure it's null-terminated */ } void vsyslog(int prio, const char *format, va_list ap) @@ -54,7 +56,9 @@ void vsyslog(int prio, const char *format, va_list ap) buf[2] = '>'; len = 3; - if ( *id ) + if ( syslog_flags & LOG_PID ) + len += sprintf(buf+3, "%s[%u]: ", id, getpid()); + else if ( *id ) len += sprintf(buf+3, "%s: ", id); len += vsnprintf(buf+len, BUFLEN-len, format, ap); @@ -68,6 +72,9 @@ void vsyslog(int prio, const char *format, va_list ap) fd = 2; /* Failed to open log, write to stderr */ write(fd, buf, len); + + if ( syslog_flags & LOG_PERROR ) + _fwrite(buf+3, len-3, stderr); } void syslog(int prio, const char *format, ...) diff --git a/klibc/klibc/vasprintf.c b/klibc/klibc/vasprintf.c index 5066dbbfaf..657bfdc3ef 100644 --- a/klibc/klibc/vasprintf.c +++ b/klibc/klibc/vasprintf.c @@ -14,10 +14,10 @@ int vasprintf(char **bufp, const char *format, va_list ap) va_copy(ap1, ap); - bytes = vsnprintf(NULL, 0, format, ap1); + bytes = vsnprintf(NULL, 0, format, ap1) + 1; va_end(ap1); - *bufp = p = malloc(bytes+1); + *bufp = p = malloc(bytes); if ( !p ) return -1; diff --git a/klibc/version b/klibc/version index 30a3f4aab8..b553d446e1 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.181 +0.194 From c39f31e51d37feb711252cb580683a665db7af33 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 14 Dec 2004 17:51:58 -0800 Subject: [PATCH 1061/4284] [PATCH] fix 'make clean' error in klibc --- klibc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/klibc/Makefile b/klibc/Makefile index 2506417ef5..8823a33bfd 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -1,5 +1,5 @@ VERSION := $(shell cat version) -SUBDIRS = klibc ash ipconfig nfsmount utils kinit gzip +SUBDIRS = klibc all: From e3686a8858ff0797af5daf97eef8c0fe08b5f46f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 14 Dec 2004 23:00:33 -0800 Subject: [PATCH 1062/4284] [PATCH] 049 release --- ChangeLog | 24 ++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 6ac004fd4c..f0f01b5446 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 01ebcc22b5..36c0b474ce 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 048 +VERSION = 049 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 56ca479113..cc6d53baa1 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 048 +Version: 049 Release: 1 License: GPL Group: Utilities/System From 0d9057a1cebf2058c36879278b7ba03a5c8ed81f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 15 Dec 2004 11:26:05 +0100 Subject: [PATCH 1063/4284] [PATCH] avoid building klibc test programs and pass SUBDIRS= to klibc clean --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 36c0b474ce..04ac59bcfc 100644 --- a/Makefile +++ b/Makefile @@ -193,7 +193,7 @@ $(CRT0): @if [ ! -r klibc/linux ]; then \ ln -f -s $(KERNEL_DIR) klibc/linux; \ fi - $(MAKE) -C klibc SUBDIRS=klibc + $(MAKE) -C klibc SUBDIRS=klibc TESTS= HEADERS = \ udev.h \ @@ -339,7 +339,7 @@ clean: | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) -rm -f ccdv - $(MAKE) -C klibc clean + $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ @@ -347,7 +347,7 @@ clean: done ; \ spotless: clean - $(MAKE) -C klibc spotless + $(MAKE) -C klibc SUBDIRS=klibc spotless -rm -f klibc/linux DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz" -e "\/\." -e releases -e BitKeeper -e SCCS -e test/sys | sort ) From 18ebc4305034401648e343b27981ef1badafef1c Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 26 Apr 2005 23:15:56 -0700 Subject: [PATCH 1064/4284] bleah, more merge fixes... --- test/udev-test.pl | 4 +++- udev.c | 1 + udevinfo.c | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 593e34e885..3f9a848490 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -35,6 +35,9 @@ my $perm = "udev.permissions"; my $main_conf = "udev-test.conf"; my $conf_tmp = "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 = ( { @@ -1260,7 +1263,6 @@ sub run_test { udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); - if ((-e "$PWD/$udev_root$config->{exp_name}") || (-l "$PWD/$udev_root$config->{exp_name}")) { diff --git a/udev.c b/udev.c index a9da014ea6..cf66e7cc89 100644 --- a/udev.c +++ b/udev.c @@ -118,6 +118,7 @@ int main(int argc, char *argv[], char *envp[]) udev_init_config(); /* set signal handlers */ + memset(&act, 0x00, sizeof(act)); act.sa_handler = (void (*) (int))sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = 0; diff --git a/udevinfo.c b/udevinfo.c index ce9804e216..116aedbc21 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -401,7 +401,7 @@ print: break; case PATH: - strfieldcpy(result, path); + strfieldcpy(result, udev.devpath); break; case ALL: From 82ca88904d1c9bf17f4434f54e12754c00eddcbd Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 15 Dec 2004 11:27:10 +0100 Subject: [PATCH 1065/4284] [PATCH] klibc supports LOG_PID now, so remove our own implementation --- logging.h | 24 +++++++++--------------- udev.c | 1 - udevd.c | 1 - udevinfo.c | 1 - udevsend.c | 1 - udevtest.c | 1 - 6 files changed, 9 insertions(+), 20 deletions(-) diff --git a/logging.h b/logging.h index 30f52c84ce..4f51217b9a 100644 --- a/logging.h +++ b/logging.h @@ -35,18 +35,16 @@ #include #include -#define LOGNAME_SIZE 42 - #undef info -#define info(format, arg...) \ - do { \ - log_message(LOG_INFO , format , ## arg); \ +#define info(format, arg...) \ + do { \ + log_message(LOG_INFO , format , ## arg); \ } while (0) #ifdef DEBUG #undef dbg -#define dbg(format, arg...) \ - do { \ +#define dbg(format, arg...) \ + do { \ log_message(LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ } while (0) #endif @@ -54,8 +52,8 @@ /* Parser needs it's own debugging statement, we usually don't care about this at all */ #ifdef DEBUG_PARSER #undef dbg_parse -#define dbg_parse(format, arg...) \ - do { \ +#define dbg_parse(format, arg...) \ + do { \ log_message(LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ } while (0) #endif @@ -63,14 +61,10 @@ extern void log_message(int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); -/* each program that uses syslog must declare this variable somewhere */ -extern unsigned char logname[LOGNAME_SIZE]; - #undef logging_init -static inline void logging_init(char *program_name) +static inline void logging_init(const char *program_name) { - snprintf(logname, LOGNAME_SIZE,"%s[%d]", program_name, getpid()); - openlog(logname, 0, LOG_DAEMON); + openlog(program_name, LOG_PID, LOG_DAEMON); } #undef logging_close diff --git a/udev.c b/udev.c index cf66e7cc89..0895e437ba 100644 --- a/udev.c +++ b/udev.c @@ -41,7 +41,6 @@ #ifdef LOG -unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) { va_list args; diff --git a/udevd.c b/udevd.c index 2e6f5793d3..91189eb861 100644 --- a/udevd.c +++ b/udevd.c @@ -64,7 +64,6 @@ static void reap_sigchilds(void); char *udev_bin; #ifdef LOG -unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevinfo.c b/udevinfo.c index 116aedbc21..00af081eac 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -39,7 +39,6 @@ #define SYSFS_VALUE_SIZE 256 #ifdef LOG -unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevsend.c b/udevsend.c index 16174f5e46..74cc09b330 100644 --- a/udevsend.c +++ b/udevsend.c @@ -44,7 +44,6 @@ static int sock = -1; #ifdef LOG -unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevtest.c b/udevtest.c index 388818d495..4b94442608 100644 --- a/udevtest.c +++ b/udevtest.c @@ -37,7 +37,6 @@ #ifdef LOG -unsigned char logname[LOGNAME_SIZE]; void log_message (int level, const char *format, ...) { va_list args; From 83c35223ed164b95f53633b97846d0963c7bcea9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 16 Dec 2004 16:05:01 +0100 Subject: [PATCH 1066/4284] [PATCH] update libsysfs to CVS version and fix segfaulting attribute reading --- libsysfs/sysfs_class.c | 3 +++ libsysfs/sysfs_device.c | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index db59aef90f..a132bb64cb 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -640,6 +640,9 @@ struct sysfs_attribute *sysfs_get_classdev_attr return cur; } + if (clsdev->directory == NULL) + return NULL; + if (clsdev->directory->subdirs == NULL) if ((sysfs_read_dir_subdirs(clsdev->directory)) != 0 || clsdev->directory->subdirs == NULL) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index f2f8d2d611..83c3adc080 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -24,7 +24,9 @@ #include "sysfs.h" /** - * get_dev_driver: fills in the dev->driver_name field + * get_dev_driver: fills in the dev->driver_name field, but searches by + * opening subsystem. Only to be used if no driver link exists in + * device directory. * * Returns 0 on SUCCESS and 1 on error */ @@ -73,6 +75,32 @@ static int get_dev_driver(struct sysfs_device *dev) } return 1; } + +/* + * get_device_driver_name: gets device's driver name, searches for driver + * link first before going the brute force route. + * @dev: device to retrieve driver + * returns 0 with success and 1 with error + */ +static int get_device_driver_name(struct sysfs_device *dev) +{ + char devpath[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX]; + + if (dev == NULL) { + errno = EINVAL; + return 1; + } + memset(devpath, 0, SYSFS_PATH_MAX); + memset(drvpath, 0, SYSFS_PATH_MAX); + safestrcpy(devpath, dev->path); + safestrcat(devpath, "/driver"); + + if ((sysfs_get_link(devpath, drvpath, SYSFS_PATH_MAX)) != 0) + return(get_dev_driver(dev)); + + return (sysfs_get_name_from_path(drvpath, dev->driver_name, + SYSFS_NAME_LEN)); +} /** * sysfs_get_device_bus: retrieves the bus name the device is on, checks path @@ -262,7 +290,7 @@ struct sysfs_device *sysfs_open_device_path(const char *path) if (sysfs_get_device_bus(dev) != 0) dprintf("Could not get device bus\n"); - if (get_dev_driver(dev) != 0) { + if (get_device_driver_name(dev) != 0) { dprintf("Could not get device %s's driver\n", dev->bus_id); safestrcpy(dev->driver_name, SYSFS_UNKNOWN); } From b817644b5b4bdb805c55cbec749258b7ff545f51 Mon Sep 17 00:00:00 2001 From: "harald@redhat.com" Date: Fri, 17 Dec 2004 03:59:22 +0100 Subject: [PATCH 1067/4284] [PATCH] selinux patch https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=142713 /sbin/udevstart segfaults on an ATIIXP chipset which is not supported well by the kernel yet. There, /proc/ide/hda/media can not be read (EIO error) and udevstart seems to give a null-pointer to an SELinux function checking the media-type. --- selinux.h | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/selinux.h b/selinux.h index 38c60a3588..df5bab69d7 100644 --- a/selinux.h +++ b/selinux.h @@ -30,31 +30,40 @@ static inline int selinux_get_media(char *path, int mode, char **media) FILE *fp; char buf[PATH_MAX]; char mediabuf[PATH_MAX]; + int ret = -1; *media = NULL; if (!(mode && S_IFBLK)) { return -1; } - snprintf(buf,sizeof(buf), "/proc/ide/%s/media", basename(path)); + + snprintf(buf, sizeof(buf), "/proc/ide/%s/media", basename(path)); + fp=fopen(buf,"r"); - if (fp) { - if (fgets(mediabuf,sizeof(mediabuf), fp)) { - int size = strlen(mediabuf); - while (size-- > 0) { - if (isspace(mediabuf[size])) { - mediabuf[size]='\0'; - } else { - break; - } - } - *media = strdup(mediabuf); - info("selinux_get_media(%s)->%s \n", path, *media); + if (!fp) + goto out; + + mediabuf[0] = '\0'; + + if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL) + goto close_out; + + int size = strlen(mediabuf); + while (size-- > 0) { + if (isspace(mediabuf[size])) { + mediabuf[size]='\0'; + } else { + break; } - fclose(fp); - return 0; - } else { - return -1; } + *media = strdup(mediabuf); + info("selinux_get_media(%s)->%s \n", path, *media); + ret = 0; + +close_out: + fclose(fp); +out: + return ret; } static inline void selinux_setfilecon(char *file, unsigned int mode) From 35413b2b88838de180ccfe6e2307c04caf24c393 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 18 Dec 2004 05:52:25 -0800 Subject: [PATCH 1068/4284] [PATCH] 050 release --- ChangeLog | 15 +++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f0f01b5446..4f34bacdb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 04ac59bcfc..4fc6ce72ef 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 049 +VERSION = 050 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index cc6d53baa1..c0aacc954c 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 049 +Version: 050 Release: 1 License: GPL Group: Utilities/System From ce5c75b8e1ea17aeb4b7e117e934c6df0f550ee3 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Sat, 18 Dec 2004 06:19:12 -0800 Subject: [PATCH 1069/4284] [PATCH] fix udev_volume_id build error. bah, when will I remember to check the extras _before_ I do a release... --- extras/volume_id/udev_volume_id.c | 1 - 1 file changed, 1 deletion(-) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 9e8c3bfb11..3fab54786b 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -37,7 +37,6 @@ #define BLKGETSIZE64 _IOR(0x12,114,size_t) #ifdef LOG -unsigned char logname[LOGNAME_SIZE]; void log_message(int level, const char *format, ...) { va_list args; From 3ac0326962c93f381bec325583e26f47fb7d4833 Mon Sep 17 00:00:00 2001 From: "tklauser@access.unizh.ch" Date: Sat, 18 Dec 2004 00:19:35 +0100 Subject: [PATCH 1070/4284] [PATCH] I made some more changes to the manpage of udev including: Patch-From: Tobias Klauser - Move the description of the environment variables to a new section called "ENVIRONMENT" (as stated in man(7)) - Pointer to the "official" udev homepage - Fixes for various typos and whitespace damages --- udev.8.in | 88 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 43 deletions(-) diff --git a/udev.8.in b/udev.8.in index 07bd7bce30..328f602e03 100644 --- a/udev.8.in +++ b/udev.8.in @@ -3,33 +3,6 @@ udev \- Linux configurable dynamic device naming support .SH SYNOPSIS .BI udev " hotplug-subsystem" -.P -The following variables are read from the environment: -.TP -.B ACTION -.IR add " or " remove -signifies the addition or the removal of a device. -.P -.B DEVPATH -The sysfs devpath of the device without the mountpoint but a leading slash. -.P -.B SUBSYSTEM -The subsystem the device belongs to. Alternatively the subsystem may -be passed as the first argument. -.P -.B UDEV_CONFIG_FILE -Overrides the default location of the -.B udev -config file. -.P -.B UDEV_NO_DEVD -The default behavior of -.B udev -is to execute programs in the -.I /etc/dev.d/ -directory after device handling. If set, -.B udev -will skip this step. .SH "DESCRIPTION" .B udev provides a dynamic device directory containing only the files for actually @@ -57,10 +30,9 @@ queries its database for the name of the device file to be deleted. .SH "CONFIGURATION" All .B udev -configuration files consist of a set of lines of text. All empty +configuration files consist of a set of lines of text. All empty lines or lines beginning with '#' will be ignored. .P - .B udev expects its main configuration file at .IR /etc/udev/udev.conf . @@ -111,7 +83,7 @@ file. The default value is .IR root . .br .P -.RI "A sample " udev.conf " might look like this: +.RI "A sample " udev.conf " file might look like this: .sp .nf # udev_root - where to place the device nodes in the filesystem @@ -186,7 +158,7 @@ Match the topological position on bus, like physical port of USB device .TP .BI SYSFS{ filename } Match sysfs device attribute like label, vendor, USB serial number, SCSI UUID -or file system label. Up to 5 different sysfs files can be checked, with +or file system label. Up to 5 different sysfs files can be checked, with all of the values being required to match the rule. .br Trailing whitespace characters in the sysfs attribute value are ignored, if @@ -215,12 +187,14 @@ should be renamed to. .br If given with the attribute .BR NAME{ all_partitions } -it will create all 15 partitions of a blockdevice. +.B udev +will create device nodes for all 15 partitions of a blockdevice. This may be useful for removable media devices. .br If given with the attribute .BR NAME{ ignore_remove } -it will will ignore any later remove event for this device. +.B udev +will ignore any later remove event for this device. This may be useful as a workaround for broken device drivers. .sp Multiple attributes may be separated by comma. @@ -293,7 +267,7 @@ The count of charcters to insert may be limited by specifying the format length value. For example, '%3s{file}' will only insert the first three characters of the sysfs attribute. .P -.RI "A sample " udev.rules " might look like this:" +.RI "A sample " udev.rules " file might look like this:" .sp .nf # if /sbin/scsi_id returns "OEM 0815", the device will be called disk1 @@ -323,7 +297,6 @@ KERNEL="scd*", NAME="%k", SYMLINK="cdrom%e" KERNEL="pcd*", NAME="%k", SYMLINK="cdrom%e" KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom%e" - .fi .P The permissions and ownership of the created device file are read from @@ -339,7 +312,7 @@ Every line lists a device name followed by owner, group and permission mode. All values are separated by colons. The name field may contain a pattern to apply the values to a whole class of devices. .sp -.RI "A sample " udev.permissions " might look like this:" +.RI "A sample " udev.permissions " file might look like this:" .sp .nf #name:user:group:mode @@ -360,14 +333,14 @@ Matches any single character, but does not match zero characters. .TP .B [ ] 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 +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. .P After device node creation, removal, or network device renaming, .B udev -executes the programs in the directory tree under +executes the programs located in the directory tree under .IR /etc/dev.d/ . The name of a program must have the suffix .I .dev @@ -379,7 +352,7 @@ is set if udev is configured to use the syslog facility. Executed programs may want to follow that setting. .B DEVNAME is exported to make the name of the created node, or the name the network -device is renamed to, available to the executed program. The programs in every +device is renamed to, available to the executed program. The programs in every directory are sorted in lexical order, while the directories are searched in the following order: .sp @@ -388,6 +361,34 @@ the following order: /etc/dev.d/$(SUBSYSTEM)/*.dev /etc/dev.d/default/*.dev .fi +.SH "ENVIRONMENT" +.P +The following variables are read from the environment: +.TP +.B ACTION +.IR add " or " remove +signifies the addition or the removal of a device. +.TP +.B DEVPATH +The sysfs devpath of the device without the mountpoint but a leading slash. +.TP +.B SUBSYSTEM +The subsystem the device belongs to. Alternatively the subsystem may +be passed as the first argument. +.TP +.B UDEV_CONFIG_FILE +Overrides the default location of the +.B udev +config file. +.TP +.B UDEV_NO_DEVD +The default behavior of +.B udev +is to execute programs in the +.I /etc/dev.d/ +directory after device handling. If set, +.B udev +will skip this step. .SH "FILES" .nf /sbin/udev udev program @@ -395,15 +396,16 @@ the following order: /etc/hotplug.d/default/udev.hotplug hotplug symlink to udev program /etc/dev.d/* programs invoked by udev .fi -.LP .SH "SEE ALSO" .BR udevinfo (8), .BR udevd (8), .BR hotplug (8) .PP -The +.B Web resources: +.nf .I http://linux\-hotplug.sourceforge.net/ -web site. +.I http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html +.fi .SH AUTHORS .B udev was developed by Greg Kroah-Hartman with much help from From 8b36cc0f179ee35176016ab67ae53078df4110fa Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Dec 2004 11:34:17 +0100 Subject: [PATCH 1071/4284] [PATCH] complete removal of explicit udev permissions config file --- FAQ | 4 - Makefile | 8 -- docs/rh_udev_for_dev.txt | 16 ++-- etc/udev/udev.conf.in | 9 +- namedev.c | 47 +--------- namedev.h | 15 ---- namedev_parse.c | 172 +++--------------------------------- test/devd_test | 1 - test/net_test | 1 - test/replace_test | 1 - test/udev-test.pl | 183 ++++----------------------------------- test/udev.permissions | 22 ----- udev.8.in | 38 +------- udev.c | 2 +- udev.h | 1 - udev.spec | 3 - udev_config.c | 10 --- 17 files changed, 39 insertions(+), 494 deletions(-) delete mode 100644 test/udev.permissions diff --git a/FAQ b/FAQ index 45337bf635..bd9d63a4d5 100644 --- a/FAQ +++ b/FAQ @@ -72,10 +72,6 @@ A: udev is entirely in userspace. If the kernel supports a greater number Q: Will udev support symlinks? A: Yes, It now does. Multiple symlinks per device node too. -Q: How will udev support changes to device permissions? -A: On shutdown, udev will save the state of existing device permissions to - its database, and then used the on the next boot time. - Q: How will udev handle the /dev filesystem? A: /dev can be a ramfs, or a backing filesystem. udev does not care what kind of filesystem it runs on. diff --git a/Makefile b/Makefile index 4fc6ce72ef..52c1d47b2d 100644 --- a/Makefile +++ b/Makefile @@ -284,7 +284,6 @@ udev_version.h: @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ - @echo \#define UDEV_PERMISSION_FILE \"$(configdir)/permissions.d\" >> $@ @echo \#define UDEV_LOG_DEFAULT \"yes\" >> $@ @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ @@ -381,7 +380,6 @@ small_release: $(DISTFILES) spotless install-config: $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d - $(INSTALL) -d $(DESTDIR)$(configdir)/permissions.d @if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \ echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ @@ -390,10 +388,6 @@ install-config: echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir)/rules.d/50-udev.rules; \ $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir)/rules.d/50-udev.rules; \ fi - @if [ ! -r $(DESTDIR)$(configdir)/permissions.d/50-udev.permissions ]; then \ - echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir)/permissions.d/50-udev.permissions; \ - $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.permissions $(DESTDIR)$(configdir)/permissions.d/50-udev.permissions; \ - fi install-dev.d: $(INSTALL) -d $(DESTDIR)$(dev_ddir)/default @@ -444,10 +438,8 @@ endif uninstall: uninstall-man uninstall-dev.d - rm $(hotplugdir)/10-udev.hotplug - rm $(configdir)/rules.d/50-udev.rules - - rm $(configdir)/permissions.d/50-udev.permissions - rm $(configdir)/udev.conf - rmdir $(configdir)/rules.d - - rmdir $(configdir)/permissions.d - rmdir $(configdir) - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) diff --git a/docs/rh_udev_for_dev.txt b/docs/rh_udev_for_dev.txt index 1a21c0e59b..0b66868d79 100644 --- a/docs/rh_udev_for_dev.txt +++ b/docs/rh_udev_for_dev.txt @@ -12,19 +12,13 @@ Q. I login as my normal self from the login screen and RH just hangs on an empty blue screen. What's wrong? A. You have some wrong permissions. I'm guessing you can probably log in as root - but not as your normal user. Basically you need to edit the - /etc/udev/udev.permissions file to set the correct permissions to the nodes - in /dev. I added the following: - - null:root:users:0666 - urandom:root:users:0644 - - setting the correct permissions to null and urandom allowed me to login - as myself and not at root. + but not as your normal user. Basically you need to set the right + permissions with a rule. Setting the correct permissions to null and urandom + allowed me to login as myself and not at root. While you are there you might want to set the permissions to ptmx as well - or you may have trouble getting a bash prompt in an xterm. i.e. - ptmx:root:users:0666 Also refer to the next question. + or you may have trouble getting a bash prompt in an xterm. Also refer to the + next question. Q. I'm having trouble getting a bash prompt from my xterm. i.e. I bring up a terminal and all I have is a blank screen with a blinking cursor. diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index bbbb1a93a2..295e39ffd2 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -14,19 +14,16 @@ udev_db="@udevdir@/.udevdb" # udev_rules - The name and location of the udev rules file udev_rules="@configdir@/rules.d" -# udev_permissions - The name and location of the udev permission file -udev_permissions="@configdir@/permissions.d" - # default_mode - set the default mode for all nodes that have no -# explicit match in the permissions file +# permissions specified default_mode="0600" # default_owner - set the default owner for all nodes that have no -# explicit match in the permissions file + # permissions specified default_owner="root" # default_group - set the default group for all nodes that have no -# explicit match in the permissions file + # permissions specified default_group="root" # udev_log - set to "yes" if you want logging, else "no" diff --git a/namedev.c b/namedev.c index 9cfc4283be..be7ae12cd5 100644 --- a/namedev.c +++ b/namedev.c @@ -43,10 +43,6 @@ static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr); -LIST_HEAD(config_device_list); -LIST_HEAD(perm_device_list); - - /* compare string with pattern (supports * ? [0-9] [!A-Z]) */ static int strcmp_pattern(const char *p, const char *s) { @@ -100,18 +96,6 @@ static int strcmp_pattern(const char *p, const char *s) return 1; } -static struct perm_device *find_perm_entry(const char *name) -{ - struct perm_device *perm; - - list_for_each_entry(perm, &perm_device_list, node) { - if (strcmp_pattern(perm->name, name)) - continue; - return perm; - } - return NULL; -} - /* extract possible {attr} and move str behind it */ static char *get_format_attribute(char **str) { @@ -694,7 +678,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d struct sysfs_class_device *class_dev_parent; struct sysfs_device *sysfs_device = NULL; struct config_device *dev; - struct perm_device *perm; char *pos; udev->mode = 0; @@ -792,18 +775,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d goto exit; perms: - /* apply permissions from permissions file to empty fields */ - perm = find_perm_entry(udev->name); - if (perm != NULL) { - if (udev->mode == 0000) - udev->mode = perm->mode; - if (udev->owner[0] == '\0') - strfieldcpy(udev->owner, perm->owner); - if (udev->group[0] == '\0') - strfieldcpy(udev->group, perm->group); - } - - /* apply permissions from config to empty fields */ + /* apply default permissions to empty fields */ if (udev->mode == 0000) udev->mode = default_mode; if (udev->owner[0] == '\0') @@ -817,20 +789,3 @@ perms: exit: return 0; } - -int namedev_init(void) -{ - int retval; - - retval = namedev_init_rules(); - if (retval) - return retval; - - retval = namedev_init_permissions(); - if (retval) - return retval; - - dump_config_dev_list(); - dump_perm_dev_list(); - return retval; -} diff --git a/namedev.h b/namedev.h index e29279243b..8a3569ec7c 100644 --- a/namedev.h +++ b/namedev.h @@ -58,7 +58,6 @@ struct sysfs_class_device; #define MAX_SYSFS_PAIRS 5 #define RULEFILE_SUFFIX ".rules" -#define PERMFILE_SUFFIX ".permissions" struct sysfs_pair { char file[FILE_SIZE]; @@ -88,26 +87,12 @@ struct config_device { int config_line; }; -struct perm_device { - struct list_head node; - - char name[NAME_SIZE]; - char owner[USER_SIZE]; - char group[USER_SIZE]; - unsigned int mode; -}; - extern struct list_head config_device_list; -extern struct list_head perm_device_list; extern int namedev_init(void); extern int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev); -extern int namedev_init_permissions(void); -extern int namedev_init_rules(void); extern void dump_config_dev(struct config_device *dev); extern void dump_config_dev_list(void); -extern void dump_perm_dev(struct perm_device *dev); -extern void dump_perm_dev_list(void); #endif diff --git a/namedev_parse.c b/namedev_parse.c index 5b8c5ab2d6..7190cdd1a8 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -40,6 +40,7 @@ #include "logging.h" #include "namedev.h" +LIST_HEAD(config_device_list); static int add_config_dev(struct config_device *new_dev) { @@ -74,53 +75,6 @@ void dump_config_dev_list(void) dump_config_dev(dev); } -static int add_perm_dev(struct perm_device *new_dev) -{ - struct perm_device *dev; - struct perm_device *tmp_dev; - - /* if we already have that entry, just update the values */ - list_for_each_entry(dev, &perm_device_list, node) { - if (strcmp(new_dev->name, dev->name) != 0) - continue; - - /* don't overwrite values from earlier entries */ - if (dev->mode == 0000) - dev->mode = new_dev->mode; - if (dev->owner[0] == '\0') - strfieldcpy(dev->owner, new_dev->owner); - if (dev->owner[0] == '\0') - strfieldcpy(dev->group, new_dev->group); - - return 0; - } - - /* not found, add new structure to the perm list */ - tmp_dev = malloc(sizeof(*tmp_dev)); - if (!tmp_dev) - return -ENOMEM; - - memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); - list_add_tail(&tmp_dev->node, &perm_device_list); - /* dump_perm_dev(tmp_dev); */ - - return 0; -} - -void dump_perm_dev(struct perm_device *dev) -{ - dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", - dev->name, dev->owner, dev->group, dev->mode); -} - -void dump_perm_dev_list(void) -{ - struct perm_device *dev; - - list_for_each_entry(dev, &perm_device_list, node) - dump_perm_dev(dev); -} - /* extract possible KEY{attr} */ static char *get_key_attribute(char *str) { @@ -143,7 +97,7 @@ static char *get_key_attribute(char *str) return NULL; } -static int namedev_parse_rules(const char *filename, void *data) +static int namedev_parse(const char *filename, void *data) { char line[LINE_SIZE]; char *bufline; @@ -362,124 +316,18 @@ error: return retval; } -static int namedev_parse_permissions(const char *filename, void *data) +int namedev_init(void) { - char line[LINE_SIZE]; - char *bufline; - char *temp; - char *temp2; - char *buf; - size_t bufsize; - size_t cur; - size_t count; - int retval = 0; - struct perm_device dev; - int lineno; + struct stat stats; + int retval; - if (file_map(filename, &buf, &bufsize) == 0) { - dbg("reading '%s' as permissions file", filename); - } else { - dbg("can't open '%s' as permissions file", filename); + if (stat(udev_rules_filename, &stats) != 0) return -1; - } - /* loop through the whole file */ - cur = 0; - lineno = 0; - while (cur < bufsize) { - count = buf_get_line(buf, bufsize, cur); - bufline = &buf[cur]; - cur += count+1; - lineno++; + if ((stats.st_mode & S_IFMT) != S_IFDIR) + retval = namedev_parse(udev_rules_filename, NULL); + else + retval = call_foreach_file(namedev_parse, udev_rules_filename, RULEFILE_SUFFIX, NULL); - if (count >= LINE_SIZE) { - info("line too long, rule skipped %s, line %d", - 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; - - strncpy(line, bufline, count); - line[count] = '\0'; - dbg_parse("read '%s'", line); - - /* parse the line */ - memset(&dev, 0x00, sizeof(struct perm_device)); - temp = line; - - temp2 = strsep(&temp, ":"); - if (!temp2) { - dbg("cannot parse line '%s'", line); - continue; - } - strfieldcpy(dev.name, temp2); - - temp2 = strsep(&temp, ":"); - if (!temp2) { - dbg("cannot parse line '%s'", line); - continue; - } - strfieldcpy(dev.owner, temp2); - - temp2 = strsep(&temp, ":"); - if (!temp2) { - dbg("cannot parse line '%s'", line); - continue; - } - strfieldcpy(dev.group, temp2); - - if (!temp) { - dbg("cannot parse line '%s'", line); - continue; - } - dev.mode = strtol(temp, NULL, 8); - - dbg_parse("name='%s', owner='%s', group='%s', mode=%#o", - dev.name, dev.owner, dev.group, dev.mode); - - retval = add_perm_dev(&dev); - if (retval) { - dbg("add_perm_dev returned with error %d", retval); - goto exit; - } - } - -exit: - file_unmap(buf, bufsize); return retval; } - -int namedev_init_rules(void) -{ - struct stat stats; - - stat(udev_rules_filename, &stats); - if ((stats.st_mode & S_IFMT) != S_IFDIR) - return namedev_parse_rules(udev_rules_filename, NULL); - else - return call_foreach_file(namedev_parse_rules, udev_rules_filename, - RULEFILE_SUFFIX, NULL); -} - -int namedev_init_permissions(void) -{ - struct stat stats; - - stat(udev_permissions_filename, &stats); - if ((stats.st_mode & S_IFMT) != S_IFDIR) - return namedev_parse_permissions(udev_permissions_filename, NULL); - else - return call_foreach_file(namedev_parse_permissions, udev_permissions_filename, - PERMFILE_SUFFIX, NULL); -} diff --git a/test/devd_test b/test/devd_test index 6e4c206352..269c2b11da 100644 --- a/test/devd_test +++ b/test/devd_test @@ -16,7 +16,6 @@ cat > $CONFIG << EOF udev_root="$PWD/udev/" udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" -udev_permissions="$PWD/udev.permissions" EOF mkdir udev diff --git a/test/net_test b/test/net_test index ec0dea4642..9686f99258 100644 --- a/test/net_test +++ b/test/net_test @@ -15,7 +15,6 @@ cat > $CONFIG << EOF udev_root="$PWD/udev/" udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" -udev_permissions="$PWD/udev.permissions" EOF mkdir udev diff --git a/test/replace_test b/test/replace_test index 9445b7262a..19260765ba 100644 --- a/test/replace_test +++ b/test/replace_test @@ -15,7 +15,6 @@ cat > $CONFIG << EOF udev_root="$PWD/udev/" udev_db="$PWD/udev/.udevdb" udev_rules="$PWD/$RULES" -udev_permissions="$PWD/udev.permissions" EOF mkdir udev diff --git a/test/udev-test.pl b/test/udev-test.pl index 3f9a848490..8ee8ba5414 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -31,7 +31,6 @@ my $sysfs = "sys/"; my $udev_bin = "../udev"; my $udev_root = "udev-root/"; # !!! directory will be removed !!! my $udev_db = ".udevdb"; -my $perm = "udev.permissions"; my $main_conf = "udev-test.conf"; my $conf_tmp = "udev-test.rules"; @@ -503,167 +502,17 @@ BUS="scsi", SYSFS{whitespace_test}="WHITE SPACE ", NAME="matched-with-space" EOF }, { - desc => "permissions test", - subsys => "block", - devpath => "/block/sda", - exp_name => "node", - exp_perms => "5000::0444", - conf => < "permissions ttyUSB0:root:uucp:0660", - subsys => "tty", - devpath => "/class/tty/ttyUSB0", - exp_name => "ttyUSB0", - exp_perms => "0:14:0660", - conf => < "permissions tty0::root:0444", - subsys => "tty", - devpath => "/class/tty/tty0", - exp_name => "tty0", - exp_perms => "0:0:0444", - conf => < "permissions tty1:root::0555", - subsys => "tty", - devpath => "/class/tty/tty1", - exp_name => "tty1", - exp_perms => "0:0:0555", - conf => < "permissions tty2:::0777", - subsys => "tty", - devpath => "/class/tty/tty2", - exp_name => "tty2", - exp_perms => "0:0:0777", - conf => < "permissions tty3::: (default mode applied)", - subsys => "tty", - devpath => "/class/tty/tty3", - exp_name => "tty3", - exp_perms => "0:0:600", - conf => < "permissions i2c-300:root:sys:0744", - subsys => "i2c-dev", - devpath => "/class/i2c-dev/i2c-300", - exp_name => "i2c-300", - exp_perms => "0:3:0744", - conf => < "permissions i2c-fake1:root:7:0007", - subsys => "i2c-dev", - devpath => "/class/i2c-dev/i2c-fake1", - exp_name => "i2c-fake1", - exp_perms => "0:7:0007", - conf => < "permissions ttyS[01]:0:5:0700", - subsys => "tty", - devpath => "/class/tty/ttyS1", - exp_name => "ttyS1", - exp_perms => "0:5:0700", - conf => < "permissions ttyS[4-9]:tty:5:0060", - subsys => "tty", - devpath => "/class/tty/ttyS7", - exp_name => "ttyS7", - exp_perms => "0:5:0060", - conf => < "permissions tty4:0:5:0707", - subsys => "ttyS4", - devpath => "/class/tty/tty4", - exp_name => "tty4", - exp_perms => "0:5:0707", - conf => < "permissions tty4?:0:5:0007", - subsys => "tty", - devpath => "/class/tty/tty44", - exp_name => "tty44", - exp_perms => "0:5:0007", - conf => < "permissions tty3[!3]:::0467", - subsys => "tty", - devpath => "/class/tty/tty35", - exp_name => "tty35", - exp_perms => "0:0:0467", - conf => < "permissions tty33:bad:name:0500", + desc => "permissions USER=bad GROUP=name", subsys => "tty", devpath => "/class/tty/tty33", exp_name => "tty33", - exp_perms => "0:0:0500", + exp_perms => "0:0:0600", conf => < "permissions rtc:0:users:0600", - subsys => "misc", - devpath => "/class/misc/rtc", - exp_name => "misc/rtc", - exp_perms => "0:100:0600", - conf => < "permissions misc:0:users:0600", - subsys => "misc", - devpath => "/class/misc/psaux", - exp_name => "misc/psaux", - exp_perms => "0:100:0600", - conf => < "permissions set OWNER=5000", + desc => "permissions OWNER=5000", subsys => "block", devpath => "/block/sda", exp_name => "node", @@ -673,7 +522,7 @@ BUS="scsi", KERNEL="sda", NAME="node", OWNER="5000" EOF }, { - desc => "permissions set GROUP=100", + desc => "permissions GROUP=100", subsys => "block", devpath => "/block/sda", exp_name => "node", @@ -683,7 +532,7 @@ BUS="scsi", KERNEL="sda", NAME="node", GROUP="100" EOF }, { - desc => "permissions set mode=0777", + desc => "permissions MODE=0777", subsys => "block", devpath => "/block/sda", exp_name => "node", @@ -693,7 +542,7 @@ BUS="scsi", KERNEL="sda", NAME="node", MODE="0777" EOF }, { - desc => "permissions set OWNER=5000 GROUP=100 MODE=0777", + desc => "permissions OWNER=5000 GROUP=100 MODE=0777", subsys => "block", devpath => "/block/sda", exp_name => "node", @@ -703,37 +552,37 @@ BUS="scsi", KERNEL="sda", NAME="node", OWNER="5000", GROUP="100", MODE="0777" EOF }, { - desc => "permissions override OWNER to 5000", + desc => "permissions OWNER to 5000", subsys => "tty", devpath => "/class/tty/ttyUSB0", exp_name => "ttyUSB0", - exp_perms => "5000:14:0660", + exp_perms => "5000::", conf => < "permissions override GROUP to 100", + desc => "permissions GROUP to 100", subsys => "tty", devpath => "/class/tty/ttyUSB0", exp_name => "ttyUSB0", - exp_perms => ":100:0660", + exp_perms => ":100:0600", conf => < "permissions override MODE to 0060", + desc => "permissions MODE to 0060", subsys => "tty", devpath => "/class/tty/ttyUSB0", exp_name => "ttyUSB0", - exp_perms => ":14:0060", + exp_perms => "::0060", conf => < "permissions override OWNER, GROUP, MODE", + desc => "permissions OWNER, GROUP, MODE", subsys => "tty", devpath => "/class/tty/ttyUSB0", exp_name => "ttyUSB0", @@ -1336,7 +1185,9 @@ open CONF, ">$main_conf" || die "unable to create config file: $main_conf"; print CONF "udev_root=\"$udev_root\"\n"; print CONF "udev_db=\"$udev_db\"\n"; print CONF "udev_rules=\"$conf_tmp\"\n"; -print CONF "udev_permissions=\"$perm\"\n"; +print CONF "default_mode=\"0600\"\n"; +print CONF "default_owner=\"root\"\n"; +print CONF "default_group=\"root\"\n"; close CONF; my $test_num = 1; diff --git a/test/udev.permissions b/test/udev.permissions deleted file mode 100644 index b7baeea7b4..0000000000 --- a/test/udev.permissions +++ /dev/null @@ -1,22 +0,0 @@ -#name:user:group:mode -ttyUSB0:root:uucp:0660 -ttyUSB1:root:uucp:0666 -visor:500:500:0666 -dsp1:::0666 -boot_disk?:::0666 - -#used for permissions tests in udev-test.pl -tty0::root:0444 -tty1:root::0555 -tty2:::0777 -tty3::: -rtc:0:6:0770 -misc/*:0:users:0600 -i2c-fake1:root:7:0007 -i2c*:root:sys:0744 -ttyS[01]:0:5:0700 -ttyS[5-9]:root:5:0060 -tty4::tty:0707 -tty4?::tty:0007 -tty3[!3]:::0467 -tty33:bad:name:0500 diff --git a/udev.8.in b/udev.8.in index 328f602e03..90b7d83309 100644 --- a/udev.8.in +++ b/udev.8.in @@ -55,13 +55,6 @@ The name of the udev rules file or directory to look for files with the suffix All rule files are read in lexical order. The default value is .IR /etc/udev/rules.d/ . .TP -.B udev_permissions -The name of the udev permission file or directory to look for files with the -suffix -.IR .permissions . -All permission files are read in lexical order. The default value is -.IR /etc/udev/permissions.d/ . -.TP .B udev_log The switch to enable/disable logging of udev information The default value is @@ -96,10 +89,6 @@ udev_db="/udev/.udevdb" for files with the suffix .rules udev_rules="/etc/udev/rules.d/" -# udev_permissions - The name of the udev permission file or directory - to look for files with the suffix .permissions -udev_permissions="/etc/udev/udev.permissions" - # udev_log - set to "yes" if you want logging, else "no" udev_log="yes" @@ -214,8 +203,8 @@ separate rules file, while the device nodes are maintained by the distribution provided rules file. .TP .B OWNER, GROUP, MODE -The permissions for this device. Every specified value overwrites the value -given in the permissions file. +The permissions for this device. Every specified value overwrites the default +value specified in the config file. .P .RB "The " NAME " ," SYMLINK " and " PROGRAM fields support simple printf-like string substitutions: @@ -299,29 +288,6 @@ KERNEL="hd[a-z]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom%e" .fi .P -The permissions and ownership of the created device file are read from -the files located in the -.I /etc/udev/permissions.d/ -directory, or at the location specified by the -.I udev_permission -value in the -.I /etc/udev/udev.conf -file. -.br -Every line lists a device name followed by owner, group and permission -mode. All values are separated by colons. The name field may contain a -pattern to apply the values to a whole class of devices. -.sp -.RI "A sample " udev.permissions " file might look like this:" -.sp -.nf -#name:user:group:mode -input/*:root:root:644 -ttyUSB1:0:8:0660 -video*:root:video:0660 -dsp1:::0666 -.fi -.P A number of different fields in the above configuration files support a simple form of shell style pattern matching. It supports the following pattern characters: .TP diff --git a/udev.c b/udev.c index 0895e437ba..e5d7800ecf 100644 --- a/udev.c +++ b/udev.c @@ -187,7 +187,7 @@ int main(int argc, char *argv[], char *envp[]) wait_for_class_device(class_dev, &error); - /* init rules, permissions */ + /* init rules */ namedev_init(); /* name, create node, store in db */ diff --git a/udev.h b/udev.h index 7038376b3c..0111644eff 100644 --- a/udev.h +++ b/udev.h @@ -80,7 +80,6 @@ extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, extern char sysfs_path[SYSFS_PATH_MAX]; extern char udev_root[PATH_MAX]; extern char udev_db_path[PATH_MAX+NAME_MAX]; -extern char udev_permissions_filename[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; extern mode_t default_mode; diff --git a/udev.spec b/udev.spec index c0aacc954c..46eaf698f8 100644 --- a/udev.spec +++ b/udev.spec @@ -98,7 +98,6 @@ rm -rf $RPM_BUILD_ROOT %defattr(-,root,root) %doc COPYING README TODO ChangeLog HOWTO* docs/* %doc etc/udev/udev.rules.{examples,gentoo,redhat} -%doc etc/udev/udev.permissions.{gentoo,redhat} %attr(755,root,root) /sbin/udev %attr(755,root,root) /usr/bin/udevinfo %attr(755,root,root) /sbin/udevsend @@ -109,9 +108,7 @@ rm -rf $RPM_BUILD_ROOT %attr(755,root,root) %dir /etc/udev/ %config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf %attr(755,root,root) %dir /etc/udev/rules.d/ -%attr(755,root,root) %dir /etc/udev/permissions.d/ %config(noreplace) %attr(0644,root,root) /etc/udev/rules.d/50-udev.rules -%config(noreplace) %attr(0644,root,root) /etc/udev/permissions.d/50-udev.permissions %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev*.8* diff --git a/udev_config.c b/udev_config.c index 62eb728ea3..a5f6467748 100644 --- a/udev_config.c +++ b/udev_config.c @@ -43,7 +43,6 @@ char sysfs_path[SYSFS_PATH_MAX]; char udev_root[PATH_MAX]; char udev_db_path[PATH_MAX+NAME_MAX]; -char udev_permissions_filename[PATH_MAX+NAME_MAX]; char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; mode_t default_mode; @@ -74,7 +73,6 @@ static void init_variables(void) strcpy(udev_db_path, UDEV_DB); strcpy(udev_config_filename, UDEV_CONFIG_FILE); strcpy(udev_rules_filename, UDEV_RULES_FILE); - strcpy(udev_permissions_filename, UDEV_PERMISSION_FILE); strcpy(default_owner, "root"); strcpy(default_group, "root"); @@ -206,12 +204,6 @@ static int parse_config_file(void) continue; } - if (strcasecmp(variable, "udev_permissions") == 0) { - strfieldcpy(udev_permissions_filename, value); - no_trailing_slash(udev_permissions_filename); - continue; - } - if (strcasecmp(variable, "default_mode") == 0) { default_mode = strtol(value, NULL, 8); continue; @@ -267,7 +259,6 @@ static void get_dirs(void) dbg_parse("udev_config_filename = %s", udev_config_filename); dbg_parse("udev_db_path = %s", udev_db_path); dbg_parse("udev_rules_filename = %s", udev_rules_filename); - dbg_parse("udev_permissions_filename = %s", udev_permissions_filename); dbg_parse("udev_log = %d", udev_log); parse_config_file(); @@ -276,7 +267,6 @@ static void get_dirs(void) dbg("udev_config_filename = %s", udev_config_filename); dbg("udev_db_path = %s", udev_db_path); dbg("udev_rules_filename = %s", udev_rules_filename); - dbg("udev_permissions_filename = %s", udev_permissions_filename); dbg("udev_log = %d", udev_log); } From 1e473f4c45f8cfd233f5731b2282074f5d8e054e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Dec 2004 12:20:41 +0100 Subject: [PATCH 1072/4284] [PATCH] update Fedora config files --- etc/udev/redhat/udev.rules | 152 +++++++++++++------------------------ 1 file changed, 53 insertions(+), 99 deletions(-) diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 0a43358bad..6605915446 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -1,53 +1,15 @@ -# /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. - -########################################################### # -# Add your own rules here (examples are commented) +# See the udev.rules.examples file for more examples of how to create rules # -########################################################### -# Looking for scsi bus id 42:0:0:1 -#BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" +# 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" -# A usb camera. -#BUS="usb", SYSFS_vendor="FUJIFILM", SYSFS_model="M100", NAME="camera%n" - -# USB Epson printer to be called lp_epson -#BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" - -# USB HP printer to be called lp_hp -#BUS="usb", SYSFS_serial="W09090207101241330", NAME="lp_hp" - -# sound card with PCI bus id 00:0b.0 to be the first sound card -#BUS="pci", ID="00:0b.0", NAME="dsp" - -# sound card with PCI bus id 00:07.1 to be the second sound card -#BUS="pci", ID="00:07.1", NAME="dsp1" - -# USB mouse plugged into the third port of the first hub to be called mouse0 -#BUS="usb", PLACE="1.3", NAME="mouse0" - -# USB tablet plugged into the third port of the second hub to be called mouse1 -#BUS="usb", PLACE="2.3", NAME="mouse1" -#BUS="usb", PLACE="2.4", NAME="mouse2" - -# ttyUSB1 should always be called visor -#KERNEL="ttyUSB1", NAME="visor" -#KERNEL="ttyUSB0", NAME="pl2303" - - -########################################################### -# -# For devfs similar /dev layout (neater) -# -########################################################### - -# devfs-names for ide-devices (uncomment only one) -# /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" +# DRI devices always go into a subdirectory (as per the LSB spec) +KERNEL="card*", NAME="dri/card%n" # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" @@ -57,69 +19,61 @@ KERNEL="midi[CD0-9]*", NAME="snd/%k" KERNEL="timer", NAME="snd/%k" KERNEL="seq", NAME="snd/%k" -# dm devices (ignore them) -KERNEL="dm-[0-9]*", NAME="" -KERNEL="device-mapper", NAME="mapper/control" - -# fb devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" - -# floppy devices -KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k" - -# i2c devices -KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" - # input devices -KERNEL="mice", NAME="input/mice" -KERNEL="mouse[0-9]*", NAME="input/mouse%n" -KERNEL="event[0-9]*", NAME="input/event%n" -KERNEL="js*", NAME="input/%k" -KERNEL="ts*", NAME="input/%k" +KERNEL="mice", NAME="input/%k" +KERNEL="mouse*", NAME="input/%k" +KERNEL="event*", NAME="input/%k" +KERNEL="js*", NAME="input/%k" +KERNEL="ts*", NAME="input/%k" -# loop devices -KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" +KERNEL="raw[0-9]*", NAME="raw/%k" -# md block devices -KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" +KERNEL="lp[0-9]*", SYMLINK="par%n" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" -# misc devices -KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" -KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" -KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" -KERNEL="rtc", NAME="misc/%k", SYMLINK="%k" -KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" -KERNEL="uinput", NAME="misc/%k", SYMLINK="%k" +KERNEL="microcode", SYMLINK="cpu/0/%k" +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" -# pty devices -KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="tty/s%n", SYMLINK="%k" +KERNEL="tun", NAME="net/%k" -# ramdisk devices -KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" +KERNEL="device-mapper", NAME="mapper/control" -# sound devices -KERNEL="adsp", NAME="sound/adsp" SYMLINK="%k" -KERNEL="audio", NAME="sound/audio", SYMLINK="%k" -KERNEL="dsp", NAME="sound/dsp", SYMLINK="%k" -KERNEL="mixer", NAME="sound/mixer", SYMLINK="%k" -KERNEL="sequencer", NAME="sound/sequencer", SYMLINK="%k" -KERNEL="sequencer2", NAME="sound/sequencer2", SYMLINK="%k" +# old compat symlinks with enumeration +KERNEL="sr[0-9]*", SYMLINK="cdrom%e" +KERNEL="scd[0-9]*", SYMLINK="cdrom%e" +KERNEL="pcd[0-9]*", SYMLINK="cdrom%e" +KERNEL="fd[0-9]*", SYMLINK="floppy%e" +KERNEL="nst[0-9]*", SYMLINK="tape%e" -# tty devices -KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" -KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" -KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" +KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ide-media.sh %k", RESULT="floppy", SYMLINK="floppy%e, NAME{ignore_remove, all_partitions}="%k" -# vc devices -KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" -KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" -KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" -KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" +KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", RESULT="cdrom", SYMLINK="cdrom%e" -# v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n" -KERNEL="radio[0-9]*", NAME="v4l/radio%n" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" -KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" +KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" +KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" +KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" + +KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" +KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" + +# rename sr* to scd* +KERNEL="sr[0-9]*", BUS="scsi", NAME="scd%n" +KERNEL="hd[a-z]*", BUS="ide", SYSFS{removable}="1", NAME{ignore_remove}="%k" + +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" From 09a9ba58c6eaa3a24652c5f1250b694cd6ba9494 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Dec 2004 12:21:21 +0100 Subject: [PATCH 1073/4284] [PATCH] update Fedora config files --- etc/udev/redhat/udev.permissions | 38 ++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/etc/udev/redhat/udev.permissions b/etc/udev/redhat/udev.permissions index c96663964f..00bdff4aaf 100644 --- a/etc/udev/redhat/udev.permissions +++ b/etc/udev/redhat/udev.permissions @@ -2,6 +2,8 @@ # console devices console:root:root:0600 +tty:root:root:0666 +tty[0-9]:root:tty:0660 tty[0-9][0-9]*:root:tty:0660 vc/[0-9]*:root:tty:0660 @@ -9,7 +11,6 @@ vc/[0-9]*:root:tty:0660 # Set this to 0660 if you only want users belonging to tty group # to be able to allocate PTYs ptmx:root:tty:0666 -tty:root:tty:0666 pty[p-za-e][0-9a-f]*:root:tty:0660 tty[p-za-e][0-9a-f]*:root:tty:0660 pty/m*:root:tty:0660 @@ -46,7 +47,7 @@ zero:root:root:0666 # misc devices nvram:root:root:0660 -rtc:root:root:0660 +rtc:root:root:0644 # floppy devices fd[01]*:root:floppy:0660 @@ -69,8 +70,8 @@ dmmidi*:root:root:0660 sndstat:root:root:0660 # optical devices -sr*:root:disk:660 -scd*:root:disk:660 +sr*:root:disk:0660 +scd*:root:disk:0660 pcd*:root:disk:0660 disk*:root:disk:0660 dvd:root:disk:0660 @@ -108,20 +109,20 @@ usb/dc2xx*:root:root:0600 usb/mdc800*:root:root:0600 # raw devices -ram*:root:disk:660 -raw/*:root:disk:660 +ram*:root:disk:0660 +raw/*:root:disk:0660 # disk devices -hd*:root:disk:660 -sd*:root:disk:660 -dasd*:root:disk:660 -ataraid*:root:disk:660 -loop*:root:disk:660 -md*:root:disk:660 -ide/*/*/*/*/*:root:disk:660 -discs/*/*:root:disk:660 -loop/*:root:disk:660 -md/*:root:disk:660 +hd*:root:disk:0660 +sd*:root:disk:0660 +dasd*:root:disk:0660 +ataraid*:root:disk:0660 +loop*:root:disk:0660 +md*:root:disk:0660 +ide/*/*/*/*/*:root:disk:0660 +discs/*/*:root:disk:0660 +loop/*:root:disk:0660 +md/*:root:disk:0660 # tape devices ht*:root:disk:0660 @@ -169,7 +170,7 @@ vttuner:root:root:0660 v4l/*:root:root:0660 # input devices -input/*:root:root:644 +input/*:root:root:0644 # gpm devices gpmctl:root:root:0700 @@ -192,3 +193,6 @@ usb/dabusb*:root:usb:0660 usb/mdc800*:root:usb:0660 usb/rio500:root:usb:0660 +# s390 devices +z90crypt:root:root:0666 + From 878f3218e109df0afde4fe8936f6920295b282a4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Dec 2004 12:22:16 +0100 Subject: [PATCH 1074/4284] [PATCH] initial merge of gentoo udev.permissions into udev.rules --- etc/udev/gentoo/udev.rules | 151 ++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 42 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 6a53e88d9d..0787bcc230 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -19,10 +19,17 @@ BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYM # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}", MODE="0660" + +# disk devices +KERNEL="sd*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="dasd*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="ataraid*", NAME="%k", GROUP="disk", MODE="0660" # dri devices -KERNEL="card*", NAME="dri/card%n" +KERNEL="card*", NAME="dri/card%n", GROUP="video", MODE="0660" +KERNEL="nvidia*", NAME="%k", GROUP="video", MODE="0660" +KERNEL="3dfx*", NAME="%k", GROUP="video", MODE="0660" # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" @@ -52,30 +59,30 @@ KERNEL="device-mapper", NAME="mapper/control" KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" # floppy devices -KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k" +KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy", MODE="0660" # i2c devices KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" # input devices -KERNEL="mice", NAME="input/%k" -KERNEL="mouse*", NAME="input/%k" -KERNEL="event*", NAME="input/%k" -KERNEL="js*", NAME="input/%k" -KERNEL="ts*", NAME="input/%k" +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="664" +KERNEL="ts*", NAME="input/%k", MODE="0600" # loop devices -KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k" +KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k", GROUP="disk", MODE="0660" # md block devices -KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k" +KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k", GROUP="disk", MODE="0660" # misc devices KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" -KERNEL="rtc", 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" +KERNEL="inotify", NAME="misc/%k", SYMLINK="%k", MODE="0666" # netlink devices KERNEL="route", NAME="netlink/%k" @@ -94,51 +101,69 @@ KERNEL="tap*", NAME="netlink/%k" # network devices KERNEL="tun", NAME="net/%k" -# pty devices -KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k" - # ramdisk devices KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" # raw devices -KERNEL="raw[0-9]*", NAME="raw/%k" +KERNEL="raw[0-9]*", NAME="raw/%k", GROUP="disk", MODE="0660" +KERNEL="ram*", NAME="%k", GROUP="disk", MODE="0660" # sound devices -KERNEL="adsp", NAME="sound/%k", SYMLINK="%k" -KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="audio", NAME="sound/%k", SYMLINK="%k" -KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="dsp", NAME="sound/%k", SYMLINK="%k" -KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="mixer", NAME="sound/%k", SYMLINK="%k" -KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k" -KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k" -KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k" +KERNEL="adsp", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="audio", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="dsp", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="mixer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" # tty devices -KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k" -KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k" -KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" +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", MODE="0660" +KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k", GROUP="tty", MODE="0660" +KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n", GROUP="tty", MODE="0600" +KERNEL="ippp0", NAME="", GROUP="tty", MODE="0660" +KERNEL="isdn*", NAME="", GROUP="tty", MODE="0660" +KERNEL="dcbri*", NAME="", GROUP="tty", MODE="0660" +KERNEL="ircomm*", NAME="", GROUP="tty", MODE="0660" + +# pty devices +KERNEL="ptmx", NAME="%k", GROUP="tty", MODE="0666" +KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k", GROUP="tty", MODE="0660" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k", GROUP="tty", MODE="0660" + +# vc devices +KERNEL="vcs", NAME="vcc/0", SYMLINK="%k", GROUP="tty", MODE="0660" +KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k", GROUP="tty", MODE="0660" +KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k", GROUP="tty", MODE="0660" +KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k", GROUP="tty", MODE="0660" + +# 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" +KERNEL="legousbtower*", NAME="usb/%k", GROUP="usb", MODE="0660" KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" - -# vc devices -KERNEL="vcs", NAME="vcc/0", SYMLINK="%k" -KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k" -KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k" -KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k", GROUP="lp", MODE="0660" # v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n" -KERNEL="radio[0-9]*", NAME="v4l/radio%n" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n" -KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" +KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n", GROUP="video", MODE="0660" +KERNEL="radio[0-9]*", NAME="v4l/radio%n", GROUP="video", MODE="0660" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n", GROUP="video", MODE="0660" +KERNEL="vtx[0-9]*", NAME="v4l/vtx%n", GROUP="video", MODE="0660" # Asterix Zaptel devices KERNEL="zapctl", NAME="zap/ctl" @@ -147,3 +172,45 @@ 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", MODE="0660" +¶ +# jaz devices +KERNEL="jaz*", NAME="%k", GROUP="disk", MODE="0660" +¶ +# zip devices +KERNEL="pocketzip*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="zip*", NAME="%k", GROUP="disk", MODE="0660" + +# ls120 devices +KERNEL="ls120", NAME="%k", GROUP="disk", MODE="0660" + +# lp devices +KERNEL="lp*", NAME="%k", GROUP="lp", MODE="0660" +KERNEL="irlpt", NAME="%k", GROUP="lp", MODE="0660" +KERNEL="usblp", NAME="%k", GROUP="lp", MODE="0660" +KERNEL="lp*", NAME="%k", GROUP="lp", MODE="0660" + +# tape devices +KERNEL="ht*", NAME="%k", GROUP="tape", MODE="0660" +KERNEL="nht*", NAME="%k", GROUP="tape", MODE="0660" +KERNEL="pt*", NAME="%k", GROUP="tape", MODE="0660" +KERNEL="npt*", NAME="%k", GROUP="tape", MODE="0660" +KERNEL="st*", NAME="%k", GROUP="tape", MODE="0660" +KERNEL="nst*", NAME="%k", GROUP="tape", MODE="0660" + +# diskonkey devices +KERNEL="diskonkey*", NAME="%k", GROUP="disk", MODE="0660" + +# rem_ide devices +KERNEL="microdrive*", NAME="%k", GROUP="disk", MODE="0660" + +# kbd devices +KERNEL="kbd", NAME="%k", MODE="0664" + +# Sony Vaio Jogdial sonypi device +KERNEL="sonypi", NAME="%k", MODE="0666" + +# gpm devices +KERNEL="gpmctl", NAME="%k", MODE="0700" + From 90726e43c97721ae7367cb465ac7924813b59a9d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Dec 2004 22:57:49 +0100 Subject: [PATCH 1075/4284] [PATCH] fix some typos in gentoo's udev.rules introduced by the merge --- etc/udev/gentoo/udev.rules | 70 +++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 0787bcc230..d91363c6d2 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -13,8 +13,8 @@ ########################################################### # cdrom symlinks and other good cdrom naming -BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" # devfs-names for ide-devices (uncomment only one) @@ -32,12 +32,12 @@ KERNEL="nvidia*", NAME="%k", GROUP="video", MODE="0660" KERNEL="3dfx*", NAME="%k", GROUP="video", MODE="0660" # alsa devices -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" +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" @@ -109,16 +109,16 @@ KERNEL="raw[0-9]*", NAME="raw/%k", GROUP="disk", MODE="0660" KERNEL="ram*", NAME="%k", GROUP="disk", MODE="0660" # sound devices -KERNEL="adsp", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="audio", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="dsp", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="mixer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="adsp", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="audio", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="dsp", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="mixer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" # tty devices KERNEL="console", NAME="%k", GROUP="tty", MODE="0600" @@ -126,10 +126,10 @@ KERNEL="tty", NAME="%k", GROUP="tty", MODE="0666" KERNEL="tty[0-9]*", NAME="vc/%n", SYMLINK="%k", GROUP="tty", MODE="0660" KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k", GROUP="tty", MODE="0660" KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n", GROUP="tty", MODE="0600" -KERNEL="ippp0", NAME="", GROUP="tty", MODE="0660" -KERNEL="isdn*", NAME="", GROUP="tty", MODE="0660" -KERNEL="dcbri*", NAME="", GROUP="tty", MODE="0660" -KERNEL="ircomm*", NAME="", GROUP="tty", MODE="0660" +KERNEL="ippp0", NAME="%k", GROUP="tty", MODE="0660" +KERNEL="isdn*", NAME="%k", GROUP="tty", MODE="0660" +KERNEL="dcbri*", NAME="%k", GROUP="tty", MODE="0660" +KERNEL="ircomm*", NAME="%k", GROUP="tty", MODE="0660" # pty devices KERNEL="ptmx", NAME="%k", GROUP="tty", MODE="0666" @@ -142,15 +142,15 @@ KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k", GROUP="tty", MODE="0660" KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k", GROUP="tty", MODE="0660" KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k", GROUP="tty", MODE="0660" -# 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" +# 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" @@ -160,9 +160,9 @@ KERNEL="dabusb*", NAME="usb/%k" BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k", GROUP="lp", MODE="0660" # v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n", GROUP="video", MODE="0660" +KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n", GROUP="video", MODE="0660" KERNEL="radio[0-9]*", NAME="v4l/radio%n", GROUP="video", MODE="0660" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n", GROUP="video", MODE="0660" +KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n", GROUP="video", MODE="0660" KERNEL="vtx[0-9]*", NAME="v4l/vtx%n", GROUP="video", MODE="0660" # Asterix Zaptel devices @@ -174,10 +174,10 @@ KERNEL="zap[0-9]*", NAME="zap/%n" # pilot/palm devices KERNEL="pilot", NAME="%k", GROUP="uucp", MODE="0660" -¶ + # jaz devices KERNEL="jaz*", NAME="%k", GROUP="disk", MODE="0660" -¶ + # zip devices KERNEL="pocketzip*", NAME="%k", GROUP="disk", MODE="0660" KERNEL="zip*", NAME="%k", GROUP="disk", MODE="0660" From a866c0a305372305bc8363b8f3b24832082711aa Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Dec 2004 22:58:37 +0100 Subject: [PATCH 1076/4284] [PATCH] remove permissions file mentioning from the udev man page --- udev.8.in | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/udev.8.in b/udev.8.in index 90b7d83309..581d6f4ed5 100644 --- a/udev.8.in +++ b/udev.8.in @@ -61,18 +61,18 @@ The default value is .IR yes . .TP .B default_mode -The default mode for all nodes not explicitly matching in the permissions -file. The default value is -.IR 0666 . +The default mode for all nodes where no explicit value is given by a rule. +The default value is +.IR 0600 . .TP .B default_owner -The default owner for all nodes not explicitly matching in the permissions -file. The default value is +The default owner for all nodes where no explicit value is given by a rule. +The default value is .IR root . .TP .B default_group -The default group for all nodes not explicitly matching in the permissions -file. The default value is +The default group for all nodes where no explicitly value is given by a rule. +The default value is .IR root . .br .P @@ -92,16 +92,16 @@ udev_rules="/etc/udev/rules.d/" # udev_log - set to "yes" if you want logging, else "no" udev_log="yes" -# default_mode - set the default mode for all nodes not -# explicitly matching in the permissions file +# default_mode - set the default mode for all nodes that have no +# permissions specified default_mode="0666" -# default_owner - set the default owner for all nodes not -# explicitly matching in the permissions file +# default_owner - set the default owner for all nodes that have no +# permissions specified default_owner="root" -# default_group - set the default group for all nodes not -# explicitly matching in the permissions file +# default_group - set the default group for all nodes that have no +# permissions specified default_group="root" .fi .P From 2c97d705dc2550885ecc392765755511b549bfc7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 18 Dec 2004 22:59:21 +0100 Subject: [PATCH 1077/4284] [PATCH] initial merge of fedora udev.permissions into udev.rules --- etc/udev/redhat/udev.rules | 50 +++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 6605915446..f95d2c1a10 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -8,16 +8,44 @@ # note devmap_name comes with extras/multipath #KERNEL="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" +KERNEL="console", NAME="%k", GROUP="tty", MODE="0600" +KERNEL="tty", NAME="%k", GROUP="tty", MODE="0666" +KERNEL="tty[0-9]*", NAME="%k", GROUP="tty", MODE="0660 + +KERNEL="ptmx", NAME="%k", GROUP="tty", MODE="0666" +KERNEL="pty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty", MODE="0660" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty", MODE="0660" + +KERNEL="ttyS[0-9]*", NAME="%k", GROUP="uucp", MODE="0660" +KERNEL="ttyUSB[0-9]*", NAME="%k", GROUP="uucp", MODE="0600" +KERNEL="ippp0", NAME="%k", MODE="0660" +KERNEL="isdn*", NAME="%k", MODE="0660" +KERNEL="dcbri*", NAME="%k", MODE="0660" +KERNEL="ircomm*", NAME="%k", GROUP="uucp", MODE="0660" + +KERNEL="vcs", NAME="%k", OWNER="vcsa", GROUP="tty", MODE="0600" +KERNEL="vcsa[0-9]*", NAME="%k", OWNER="vcsa", GROUP="tty", MODE="0600 + +# 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" + # DRI devices always go into a subdirectory (as per the LSB spec) KERNEL="card*", NAME="dri/card%n" # 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" +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" @@ -53,11 +81,11 @@ KERNEL="tun", NAME="net/%k" KERNEL="device-mapper", NAME="mapper/control" # old compat symlinks with enumeration -KERNEL="sr[0-9]*", SYMLINK="cdrom%e" -KERNEL="scd[0-9]*", SYMLINK="cdrom%e" -KERNEL="pcd[0-9]*", SYMLINK="cdrom%e" -KERNEL="fd[0-9]*", SYMLINK="floppy%e" -KERNEL="nst[0-9]*", SYMLINK="tape%e" +KERNEL="sr[0-9]*", SYMLINK="cdrom%e" +KERNEL="scd[0-9]*", SYMLINK="cdrom%e" +KERNEL="pcd[0-9]*", SYMLINK="cdrom%e" +KERNEL="fd[0-9]*", SYMLINK="floppy%e" +KERNEL="nst[0-9]*", SYMLINK="tape%e" KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ide-media.sh %k", RESULT="floppy", SYMLINK="floppy%e, NAME{ignore_remove, all_partitions}="%k" From 2a270316e4c0afa1efe98d665e2e329b7bae6c0a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 19 Dec 2004 02:39:52 +0100 Subject: [PATCH 1078/4284] [PATCH] I broke the extras/ again. Add simple build test script now. --- test/simple-build-check.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 test/simple-build-check.sh diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh new file mode 100644 index 0000000000..8919fcfcf0 --- /dev/null +++ b/test/simple-build-check.sh @@ -0,0 +1,26 @@ +#/bin/sh + +EXTRA="extras/chassis_id extras/scsi_id extras/volume_id" + +make spotless EXTRAS="$EXTRA" >/dev/null +make all EXTRAS="$EXTRA" || exit +echo -e "\n\n" + +make spotless EXTRAS="$EXTRA" >/dev/null +make all DEBUG=true EXTRAS="$EXTRA" || exit +echo -e "\n\n" + +make spotless EXTRAS="$EXTRA" >/dev/null +make all USE_LOG=false EXTRAS="$EXTRA" || exit +echo -e "\n\n" + +make spotless EXTRAS="$EXTRA" >/dev/null +make all USE_KLIBC=true DEBUG=true EXTRAS="$EXTRA" || exit +echo -e "\n\n" + +make spotless EXTRAS="$EXTRA" >/dev/null +make all USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRA" || exit +echo -e "\n\n" + +make spotless EXTRAS="$EXTRA" >/dev/null + From 65ab1334122b6ed427ce39f48fb40757d44f8d71 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 01:31:56 +0100 Subject: [PATCH 1079/4284] [PATCH] simplify permission application We have only one source of permissions now, so apply the default permissions at udev init. --- namedev.c | 37 +++++++++++++++---------------------- udev_add.c | 2 +- udev_utils.c | 4 ++++ 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/namedev.c b/namedev.c index be7ae12cd5..3da783b55d 100644 --- a/namedev.c +++ b/namedev.c @@ -680,7 +680,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d struct config_device *dev; char *pos; - udev->mode = 0; dbg("class_dev->name='%s'", class_dev->name); /* Figure out where the "device"-symlink is at. For char devices this will @@ -757,34 +756,28 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d goto exit; udev->partitions = dev->partitions; - udev->mode = dev->mode; - strfieldcpy(udev->owner, dev->owner); - apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); - strfieldcpy(udev->group, dev->group); - apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); + if (dev->mode != 0000) + udev->mode = dev->mode; + if (dev->owner[0] != '\0') { + strfieldcpy(udev->owner, dev->owner); + apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); + } + if (dev->group[0] != '\0') { + strfieldcpy(udev->group, dev->group); + apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); + } - goto perms; + dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", + udev->name, udev->owner, udev->group, udev->mode); + + goto exit; } } } /* no rule matched, so we use the kernel name */ strfieldcpy(udev->name, udev->kernel_name); - - if (udev->type == 'n') - goto exit; - -perms: - /* apply default permissions to empty fields */ - if (udev->mode == 0000) - udev->mode = default_mode; - if (udev->owner[0] == '\0') - strfieldcpy(udev->owner, default_owner); - if (udev->group[0] == '\0') - strfieldcpy(udev->group, default_group); - - dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", - udev->name, udev->owner, udev->group, udev->mode); + dbg("no rule found, use kernel name '%s'", udev->name); exit: return 0; diff --git a/udev_add.c b/udev_add.c index f537f567cc..c9b30bad90 100644 --- a/udev_add.c +++ b/udev_add.c @@ -189,7 +189,7 @@ static int create_node(struct udevice *udev) } else { info("creating device node '%s', major = '%d', minor = '%d', " "mode = '%#o', uid = '%d', gid = '%d'", filename, - udev->major, udev->minor, (mode_t)udev->mode, uid, gid); + udev->major, udev->minor, udev->mode, uid, gid); } /* create all_partitions if requested */ diff --git a/udev_utils.c b/udev_utils.c index aa5c75f74d..0b730d565b 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -55,6 +55,10 @@ void udev_init_device(struct udevice *udev, const char* devpath, const char *sub udev->type = 'n'; else if (strncmp(udev->devpath, "/class/", 7) == 0) udev->type = 'c'; + + udev->mode = default_mode; + strfieldcpy(udev->owner, default_owner); + strfieldcpy(udev->group, default_group); } int kernel_release_satisfactory(int version, int patchlevel, int sublevel) From 4ae6d03f394684722e7d5710fb2585e7c388f119 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 03:04:11 +0100 Subject: [PATCH 1080/4284] [PATCH] simplify rules file by setting default mode to 0660 On Sun, 2004-12-19 at 18:31 +0100, Marco d'Itri wrote: > It may be better to use default_mode="0660", I do not think that there > are any mode 600 devices. This would allow setting only the group for > most of them. --- etc/udev/gentoo/udev.rules | 114 ++++++++++++++++++------------------- etc/udev/redhat/udev.rules | 18 +++--- etc/udev/udev.conf.in | 2 +- test/udev-test.pl | 10 ++-- udev.8.in | 4 +- udev_config.c | 2 +- 6 files changed, 75 insertions(+), 75 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index d91363c6d2..7d5aaa7d72 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -19,17 +19,17 @@ BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYM # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}", MODE="0660" +BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" # disk devices -KERNEL="sd*", NAME="%k", GROUP="disk", MODE="0660" -KERNEL="dasd*", NAME="%k", GROUP="disk", MODE="0660" -KERNEL="ataraid*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="sd*", NAME="%k", GROUP="disk" +KERNEL="dasd*", NAME="%k", GROUP="disk" +KERNEL="ataraid*", NAME="%k", GROUP="disk" # dri devices -KERNEL="card*", NAME="dri/card%n", GROUP="video", MODE="0660" -KERNEL="nvidia*", NAME="%k", GROUP="video", MODE="0660" -KERNEL="3dfx*", NAME="%k", GROUP="video", MODE="0660" +KERNEL="card*", NAME="dri/card%n", GROUP="video" +KERNEL="nvidia*", NAME="%k", GROUP="video" +KERNEL="3dfx*", NAME="%k", GROUP="video" # alsa devices KERNEL="controlC[0-9]*", NAME="snd/%k" @@ -59,7 +59,7 @@ KERNEL="device-mapper", NAME="mapper/control" KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" # floppy devices -KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy", MODE="0660" +KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy" # i2c devices KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" @@ -72,10 +72,10 @@ KERNEL="js*", NAME="input/%k", MODE="664" KERNEL="ts*", NAME="input/%k", MODE="0600" # loop devices -KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k", GROUP="disk", MODE="0660" +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", MODE="0660" +KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k", GROUP="disk" # misc devices KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" @@ -105,42 +105,42 @@ KERNEL="tun", NAME="net/%k" KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" # raw devices -KERNEL="raw[0-9]*", NAME="raw/%k", GROUP="disk", MODE="0660" -KERNEL="ram*", NAME="%k", GROUP="disk", MODE="0660" +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="0660" -KERNEL="adsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="audio", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="audio[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="dsp", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="dsp[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="mixer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="mixer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="sequencer", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" -KERNEL="sequencer[0-9]*", NAME="sound/%k", SYMLINK="%k", GROUP="audio", MODE="0660" +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" # 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", MODE="0660" -KERNEL="ttyS[0-9]*", NAME="tts/%n", SYMLINK="%k", GROUP="tty", MODE="0660" +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="0600" -KERNEL="ippp0", NAME="%k", GROUP="tty", MODE="0660" -KERNEL="isdn*", NAME="%k", GROUP="tty", MODE="0660" -KERNEL="dcbri*", NAME="%k", GROUP="tty", MODE="0660" -KERNEL="ircomm*", NAME="%k", 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%n", SYMLINK="%k", GROUP="tty", MODE="0660" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k", GROUP="tty", MODE="0660" +KERNEL="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK="%k", GROUP="tty" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k", GROUP="tty" # vc devices -KERNEL="vcs", NAME="vcc/0", SYMLINK="%k", GROUP="tty", MODE="0660" -KERNEL="vcs[0-9]*", NAME="vcc/%n", SYMLINK="%k", GROUP="tty", MODE="0660" -KERNEL="vcsa", NAME="vcc/a0", SYMLINK="%k", GROUP="tty", MODE="0660" -KERNEL="vcsa[0-9]*", NAME="vcc/a%n", SYMLINK="%k", GROUP="tty", MODE="0660" +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="0666" @@ -155,15 +155,15 @@ 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", MODE="0660" +KERNEL="legousbtower*", NAME="usb/%k", GROUP="usb" KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k", GROUP="lp", MODE="0660" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k", GROUP="lp" # v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n", GROUP="video", MODE="0660" -KERNEL="radio[0-9]*", NAME="v4l/radio%n", GROUP="video", MODE="0660" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n", SYMLINK="vbi%n", GROUP="video", MODE="0660" -KERNEL="vtx[0-9]*", NAME="v4l/vtx%n", GROUP="video", MODE="0660" +KERNEL="video[0-9]*", NAME="v4l/video%n", SYMLINK="video%n", GROUP="video" +KERNEL="radio[0-9]*", NAME="v4l/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" # Asterix Zaptel devices KERNEL="zapctl", NAME="zap/ctl" @@ -173,37 +173,37 @@ KERNEL="zappseudo", NAME="zap/pseudo" KERNEL="zap[0-9]*", NAME="zap/%n" # pilot/palm devices -KERNEL="pilot", NAME="%k", GROUP="uucp", MODE="0660" +KERNEL="pilot", NAME="%k", GROUP="uucp" # jaz devices -KERNEL="jaz*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="jaz*", NAME="%k", GROUP="disk" # zip devices -KERNEL="pocketzip*", NAME="%k", GROUP="disk", MODE="0660" -KERNEL="zip*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="pocketzip*", NAME="%k", GROUP="disk" +KERNEL="zip*", NAME="%k", GROUP="disk" # ls120 devices -KERNEL="ls120", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="ls120", NAME="%k", GROUP="disk" # lp devices -KERNEL="lp*", NAME="%k", GROUP="lp", MODE="0660" -KERNEL="irlpt", NAME="%k", GROUP="lp", MODE="0660" -KERNEL="usblp", NAME="%k", GROUP="lp", MODE="0660" -KERNEL="lp*", NAME="%k", GROUP="lp", MODE="0660" +KERNEL="lp*", NAME="%k", GROUP="lp" +KERNEL="irlpt", NAME="%k", GROUP="lp" +KERNEL="usblp", NAME="%k", GROUP="lp" +KERNEL="lp*", NAME="%k", GROUP="lp" # tape devices -KERNEL="ht*", NAME="%k", GROUP="tape", MODE="0660" -KERNEL="nht*", NAME="%k", GROUP="tape", MODE="0660" -KERNEL="pt*", NAME="%k", GROUP="tape", MODE="0660" -KERNEL="npt*", NAME="%k", GROUP="tape", MODE="0660" -KERNEL="st*", NAME="%k", GROUP="tape", MODE="0660" -KERNEL="nst*", NAME="%k", GROUP="tape", MODE="0660" +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" # diskonkey devices -KERNEL="diskonkey*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="diskonkey*", NAME="%k", GROUP="disk" # rem_ide devices -KERNEL="microdrive*", NAME="%k", GROUP="disk", MODE="0660" +KERNEL="microdrive*", NAME="%k", GROUP="disk" # kbd devices KERNEL="kbd", NAME="%k", MODE="0664" diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index f95d2c1a10..5dc68237e7 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -10,18 +10,18 @@ KERNEL="console", NAME="%k", GROUP="tty", MODE="0600" KERNEL="tty", NAME="%k", GROUP="tty", MODE="0666" -KERNEL="tty[0-9]*", NAME="%k", GROUP="tty", MODE="0660 +KERNEL="tty[0-9]*", NAME="%k", GROUP="tty" KERNEL="ptmx", NAME="%k", GROUP="tty", MODE="0666" -KERNEL="pty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty", MODE="0660" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty", MODE="0660" +KERNEL="pty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty" -KERNEL="ttyS[0-9]*", NAME="%k", GROUP="uucp", MODE="0660" -KERNEL="ttyUSB[0-9]*", NAME="%k", GROUP="uucp", MODE="0600" -KERNEL="ippp0", NAME="%k", MODE="0660" -KERNEL="isdn*", NAME="%k", MODE="0660" -KERNEL="dcbri*", NAME="%k", MODE="0660" -KERNEL="ircomm*", NAME="%k", GROUP="uucp", MODE="0660" +KERNEL="ttyS[0-9]*", NAME="%k", GROUP="uucp" +KERNEL="ttyUSB[0-9]*", NAME="%k", GROUP="uucp" +KERNEL="ippp0", NAME="%k" +KERNEL="isdn*", NAME="%k" +KERNEL="dcbri*", NAME="%k" +KERNEL="ircomm*", NAME="%k", GROUP="uucp" KERNEL="vcs", NAME="%k", OWNER="vcsa", GROUP="tty", MODE="0600" KERNEL="vcsa[0-9]*", NAME="%k", OWNER="vcsa", GROUP="tty", MODE="0600 diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 295e39ffd2..a4a79ad5c2 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -16,7 +16,7 @@ udev_rules="@configdir@/rules.d" # default_mode - set the default mode for all nodes that have no # permissions specified -default_mode="0600" +default_mode="0660" # default_owner - set the default owner for all nodes that have no # permissions specified diff --git a/test/udev-test.pl b/test/udev-test.pl index 8ee8ba5414..9a581ce527 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -506,7 +506,7 @@ EOF subsys => "tty", devpath => "/class/tty/tty33", exp_name => "tty33", - exp_perms => "0:0:0600", + exp_perms => "0:0:0660", conf => < "block", devpath => "/block/sda", exp_name => "node", - exp_perms => "5000::0600", + exp_perms => "5000::0660", conf => < "block", devpath => "/block/sda", exp_name => "node", - exp_perms => ":100:0600", + exp_perms => ":100:0660", conf => < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "ttyUSB0", - exp_perms => ":100:0600", + exp_perms => ":100:0660", conf => <$main_conf" || die "unable to create config file: $main_conf"; print CONF "udev_root=\"$udev_root\"\n"; print CONF "udev_db=\"$udev_db\"\n"; print CONF "udev_rules=\"$conf_tmp\"\n"; -print CONF "default_mode=\"0600\"\n"; +print CONF "default_mode=\"0660\"\n"; print CONF "default_owner=\"root\"\n"; print CONF "default_group=\"root\"\n"; close CONF; diff --git a/udev.8.in b/udev.8.in index 581d6f4ed5..5d55b3282c 100644 --- a/udev.8.in +++ b/udev.8.in @@ -63,7 +63,7 @@ The default value is .B default_mode The default mode for all nodes where no explicit value is given by a rule. The default value is -.IR 0600 . +.IR 0660 . .TP .B default_owner The default owner for all nodes where no explicit value is given by a rule. @@ -94,7 +94,7 @@ udev_log="yes" # default_mode - set the default mode for all nodes that have no # permissions specified -default_mode="0666" +default_mode="0660" # default_owner - set the default owner for all nodes that have no # permissions specified diff --git a/udev_config.c b/udev_config.c index a5f6467748..31c2a86ed1 100644 --- a/udev_config.c +++ b/udev_config.c @@ -76,7 +76,7 @@ static void init_variables(void) strcpy(default_owner, "root"); strcpy(default_group, "root"); - default_mode = 0600; + default_mode = 0660; udev_log = string_is_true(UDEV_LOG_DEFAULT); From a07dc29e602440541ce531e03737bc1f926a0ef3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 03:11:22 +0100 Subject: [PATCH 1081/4284] [PATCH] add OnStream tape drive rules On Sun, 2004-12-19 at 17:36 +0000, Willem Riede wrote: Would you mind adding OnStream tape drives? > > KERNEL="osst*", NAME="%k", GROUP="tape", MODE="0660" > KERNEL="nosst*", NAME="%k", GROUP="tape", MODE="0660" --- etc/udev/gentoo/udev.rules | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 7d5aaa7d72..dbb0e6f51e 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -198,6 +198,8 @@ 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" @@ -211,6 +213,3 @@ KERNEL="kbd", NAME="%k", MODE="0664" # Sony Vaio Jogdial sonypi device KERNEL="sonypi", NAME="%k", MODE="0666" -# gpm devices -KERNEL="gpmctl", NAME="%k", MODE="0700" - From 9f8dfa19cfd2b502bf794f39a421cbb7c4cc0404 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 07:38:33 +0100 Subject: [PATCH 1082/4284] [PATCH] allow multiline rules by backslash at the end of the line On Sun, 2004-12-19 at 18:31 +0100, Marco d'Itri wrote: > > On Dec 19, Kay Sievers wrote: > > > (Feature request: would it be possible to extend the rules files parser > > to support continuation lines? I'd like it to consider lines starting > > with white space as part of the previous line.) > > How about the usual backslash at the end of the line. Here is a simple > patch. --- namedev_parse.c | 15 +++++++++---- test/udev-test.pl | 30 ++++++++++++++++++++++++++ udev.8.in | 6 +++--- udev.h | 3 +-- udev_config.c | 54 ++++++----------------------------------------- udev_utils.c | 52 ++++++++++++++++++++++++++++++++++++++++++--- udev_utils.h | 3 ++- 7 files changed, 102 insertions(+), 61 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index 7190cdd1a8..3b14a6a500 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -126,14 +126,15 @@ static int namedev_parse(const char *filename, void *data) cur = 0; lineno = 0; while (cur < bufsize) { + int i, j; + count = buf_get_line(buf, bufsize, cur); bufline = &buf[cur]; cur += count+1; lineno++; if (count >= LINE_SIZE) { - info("line too long, rule skipped %s, line %d", - filename, lineno); + info("line too long, rule skipped %s, line %d", filename, lineno); continue; } @@ -149,8 +150,14 @@ static int namedev_parse(const char *filename, void *data) if (bufline[0] == COMMENT_CHARACTER) continue; - strncpy(line, bufline, count); - line[count] = '\0'; + /* skip backslash and newline from multi line rules */ + for (i = j = 0; i < count; i++) { + if (bufline[i] == '\\' || bufline[i] == '\n') + continue; + + line[j++] = bufline[i]; + } + line[j] = '\0'; dbg_parse("read '%s'", line); /* get all known keys */ diff --git a/test/udev-test.pl b/test/udev-test.pl index 9a581ce527..53eee35457 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -187,6 +187,36 @@ EOF KERNEL="ttyUSB0", NAME="visor" +EOF + }, + { + desc => "Handle backslashed multi lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + conf => < "Handle stupid backslashed multi lines in config file (and replace kernel name)", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "visor" , + conf => < #include #include +#include #include #include #include @@ -111,6 +112,41 @@ int create_path(const char *path) return mkdir(p, 0755); } +int parse_get_pair(char **orig_string, char **left, char **right) +{ + char *temp; + char *string = *orig_string; + + if (!string) + return -ENODEV; + + /* eat any whitespace */ + while (isspace(*string) || *string == ',') + ++string; + + /* split based on '=' */ + temp = strsep(&string, "="); + *left = temp; + if (!string) + return -ENODEV; + + /* take the right side and strip off the '"' */ + while (isspace(*string)) + ++string; + if (*string == '"') + ++string; + else + return -ENODEV; + + temp = strsep(&string, "\""); + if (!string || *temp == '\0') + return -ENODEV; + *right = temp; + *orig_string = string; + + return 0; +} + int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; @@ -143,11 +179,21 @@ void file_unmap(char *buf, size_t bufsize) munmap(buf, bufsize); } -size_t buf_get_line(char *buf, size_t buflen, size_t cur) +/* 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) { - size_t count = 0; + int escape = 0; + size_t count; - for (count = cur; count < buflen && buf[count] != '\n'; 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/udev_utils.h b/udev_utils.h index e36255f526..cc9dd704de 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -79,9 +79,10 @@ do { \ extern void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel); extern int create_path(const char *path); +extern int parse_get_pair(char **orig_string, char **left, char **right); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); -extern size_t buf_get_line(char *buf, size_t buflen, size_t cur); +extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); extern void no_trailing_slash(char *path); typedef int (*file_fnct_t)(const char *filename, void *data); extern int call_foreach_file(file_fnct_t fnct, const char *dirname, From eabfc9736703ce0dc81b233d78821d408aa565f2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 08:57:31 +0100 Subject: [PATCH 1083/4284] [PATCH] handle renamed network interfaces properly if we manage hotplug.d/ If we take over the hotplug call and manage the events we don't need to call the event fake script in dev.d/. Just set all expected values to the new network interface name and call hotplug.d/. This way the device renaming is completely handled inside of udev and userspace can't get confused. --- etc/dev.d/net/hotplug.dev | 10 ++++------ udev.c | 23 +++++++++++++++-------- udev_add.c | 7 ++++--- udevd.c | 2 +- udevsend.c | 2 +- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/etc/dev.d/net/hotplug.dev b/etc/dev.d/net/hotplug.dev index 15cc5cb52e..e195b0f034 100644 --- a/etc/dev.d/net/hotplug.dev +++ b/etc/dev.d/net/hotplug.dev @@ -8,15 +8,13 @@ # Copyright (C) 2004 Greg Kroah-Hartman # -# See if we really did rename this device. -if [ "$INTERFACE" = "$DEVNAME" ]; then +# Do nothing if udev handles hotplug.d. +if [ "$MANAGED_EVENT" == "1" ]; then exit 0 fi -# ok, we have renamed this device, so let's set $INTERFACE to the new name -# and call the network hotplug script to handle it properly... -INTERFACE=$DEVNAME -export INTERFACE +# ok, we have renamed this device, so let the network hotplug script +# know about it to setup the device properly... if [ -f /etc/hotplug.d/default/default.hotplug ]; then exec /etc/hotplug.d/default/default.hotplug net fi diff --git a/udev.c b/udev.c index e5d7800ecf..122d34c1a5 100644 --- a/udev.c +++ b/udev.c @@ -54,31 +54,32 @@ void log_message(int level, const char *format, ...) } #endif -/* (for now) true if udevsend is the helper */ +/* decide if we should manage the whole hotplug event + * for now look if the kernel calls udevsend instead of /sbin/hotplug + */ static int manage_hotplug_event(void) { char helper[256]; int fd; int len; - /* false, if we are called directly */ - if (!getenv("MANAGED_EVENT")) - goto exit; + /* don't handle hotplug.d if we are called directly */ + if (!getenv("UDEVD_EVENT")) + return 0; fd = open("/proc/sys/kernel/hotplug", O_RDONLY); if (fd < 0) - goto exit; + return 0; len = read(fd, helper, 256); close(fd); if (len < 0) - goto exit; + return 0; helper[len] = '\0'; if (strstr(helper, "udevsend")) return 1; -exit: return 0; } @@ -104,6 +105,7 @@ int main(int argc, char *argv[], char *envp[]) const char *action; const char *devpath; const char *subsystem; + int managed_event; int retval = -EINVAL; if (argc == 2 && strcmp(argv[1], "-V") == 0) { @@ -139,6 +141,11 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + /* let the executed programs know if we handle the whole hotplug event */ + managed_event = manage_hotplug_event(); + if (managed_event) + setenv("MANAGED_EVENT", "1", 1); + action = getenv("ACTION"); devpath = getenv("DEVPATH"); subsystem = getenv("SUBSYSTEM"); @@ -238,7 +245,7 @@ int main(int argc, char *argv[], char *envp[]) } hotplug: - if (udev_hotplug_d && manage_hotplug_event()) + if (udev_hotplug_d && managed_event) udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); exit: diff --git a/udev_add.c b/udev_add.c index c9b30bad90..acd678ffba 100644 --- a/udev_add.c +++ b/udev_add.c @@ -318,15 +318,16 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) if (retval != 0) goto exit; - /* we've changed the name, now fake the devpath, - * cause original kernel name sleeps with the fishes - * and we don't get any event from the kernel now + /* we've changed the name, now fake the devpath, cause the + * original kernel name sleeps with the fishes and we don't + * get an event from the kernel with the new name */ pos = strrchr(udev->devpath, '/'); if (pos != NULL) { pos[1] = '\0'; strfieldcat(udev->devpath, udev->name); setenv("DEVPATH", udev->devpath, 1); + setenv("INTERFACE", udev->name, 1); } /* use netif name for the environment */ diff --git a/udevd.c b/udevd.c index 91189eb861..3c29c2be6e 100644 --- a/udevd.c +++ b/udevd.c @@ -335,7 +335,7 @@ static void handle_udevsend_msg(int sock) if (strncmp(key, "PHYSDEVPATH=", 12) == 0) msg->physdevpath = &key[12]; } - msg->envp[i++] = "MANAGED_EVENT=1"; + msg->envp[i++] = "UDEVD_EVENT=1"; msg->envp[i] = NULL; /* if no seqnum is given, we move straight to exec queue */ diff --git a/udevsend.c b/udevsend.c index 74cc09b330..05a50facc5 100644 --- a/udevsend.c +++ b/udevsend.c @@ -154,7 +154,7 @@ int main(int argc, char *argv[], char *envp[]) } /* prevent loops in the scripts we execute */ - if (strncmp(key, "MANAGED_EVENT=", 14) == 0) { + if (strncmp(key, "UDEVD_EVENT=", 12) == 0) { dbg("seems that the event source is not the kernel, just exit"); goto exit; } From c07068d5e0b153634c4457aff3dd16700161be00 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 09:53:32 +0100 Subject: [PATCH 1084/4284] [PATCH] update Fedora config files --- etc/udev/redhat/udev.permissions | 74 +++++++++++++++++--------------- etc/udev/redhat/udev.rules | 9 ++-- 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/etc/udev/redhat/udev.permissions b/etc/udev/redhat/udev.permissions index 00bdff4aaf..19de177c82 100644 --- a/etc/udev/redhat/udev.permissions +++ b/etc/udev/redhat/udev.permissions @@ -70,27 +70,27 @@ dmmidi*:root:root:0660 sndstat:root:root:0660 # optical devices -sr*:root:disk:0660 -scd*:root:disk:0660 -pcd*:root:disk:0660 -disk*:root:disk:0660 -dvd:root:disk:0660 -rdvd:root:disk:0660 -cdroms/*:root:disk:0660 +sr*:root:disk:0640 +scd*:root:disk:0640 +pcd*:root:disk:0640 +disk*:root:disk:0640 +dvd:root:disk:0640 +rdvd:root:disk:0640 +cdroms/*:root:disk:0640 # pilot/palm devices pilot:root:uucp:0660 # jaz devices -jaz*:root:disk:0660 +jaz*:root:disk:0640 # zip devices -pocketzip*:root:disk:0660 -zip*:root:disk:0660 +pocketzip*:root:disk:0640 +zip*:root:disk:0640 # ls120 devices -ls120:root:disk:0660 -ls120*:root:disk:0660 +ls120:root:disk:0640 +ls120*:root:disk:0640 # lp devices lp*:root:lp:0660 @@ -109,28 +109,28 @@ usb/dc2xx*:root:root:0600 usb/mdc800*:root:root:0600 # raw devices -ram*:root:disk:0660 -raw/*:root:disk:0660 +ram*:root:disk:0640 +raw/*:root:disk:0640 # disk devices -hd*:root:disk:0660 -sd*:root:disk:0660 -dasd*:root:disk:0660 -ataraid*:root:disk:0660 -loop*:root:disk:0660 -md*:root:disk:0660 -ide/*/*/*/*/*:root:disk:0660 -discs/*/*:root:disk:0660 -loop/*:root:disk:0660 -md/*:root:disk:0660 +hd*:root:disk:0640 +sd*:root:disk:0640 +dasd*:root:disk:0640 +ataraid*:root:disk:0640 +loop*:root:disk:0640 +md*:root:disk:0640 +ide/*/*/*/*/*:root:disk:0640 +discs/*/*:root:disk:0640 +loop/*:root:disk:0640 +md/*:root:disk:0640 # tape devices -ht*:root:disk:0660 -nht*:root:disk:0660 -pt[0-9]*:root:disk:0660 -npt*:root:disk:0660 -st*:root:disk:0660 -nst*:root:disk:0660 +ht*:root:disk:0640 +nht*:root:disk:0640 +pt[0-9]*:root:disk:0640 +npt*:root:disk:0640 +st*:root:disk:0640 +nst*:root:disk:0640 # dm devices dm-*:root:root:0640 @@ -142,10 +142,10 @@ memstick*:root:root:0600 flash*:root:root:0600 # diskonkey devices -diskonkey*:root:disk:0660 +diskonkey*:root:disk:0640 # rem_ide devices -microdrive*:root:disk:0660 +microdrive*:root:disk:0640 # fb devices fb:root:root:0600 @@ -184,9 +184,9 @@ dri/*:root:root:0660 apm_bios:root:root:0600 # scsi devices -sg*:root:disk:0660 -pg*:root:disk:0660 -cdwriter:root:disk:0660 +sg*:root:disk:0640 +pg*:root:disk:0640 +cdwriter:root:disk:0640 # usb devices usb/dabusb*:root:usb:0660 @@ -196,3 +196,7 @@ usb/rio500:root:usb:0660 # s390 devices z90crypt:root:root:0666 +# DVB +dvb/*:root:root:0660 +dvb:root:root:0660 +dvb/adapter*:root:root:0660 diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 5dc68237e7..d394e99016 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -87,7 +87,7 @@ KERNEL="pcd[0-9]*", SYMLINK="cdrom%e" KERNEL="fd[0-9]*", SYMLINK="floppy%e" KERNEL="nst[0-9]*", SYMLINK="tape%e" -KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ide-media.sh %k", RESULT="floppy", SYMLINK="floppy%e, NAME{ignore_remove, all_partitions}="%k" +KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ide-media.sh %k", RESULT="floppy", SYMLINK="floppy%e, NAME{ignore_remove, all_partitions}="%k", GROUP="floppy" KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", RESULT="cdrom", SYMLINK="cdrom%e" @@ -101,7 +101,10 @@ KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ch KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" # rename sr* to scd* -KERNEL="sr[0-9]*", BUS="scsi", NAME="scd%n" -KERNEL="hd[a-z]*", BUS="ide", SYSFS{removable}="1", NAME{ignore_remove}="%k" +KERNEL="sr[0-9]*", BUS="scsi", NAME="scd%n", GROUP="disk", MODE="0640" +KERNEL="hd[a-z]*", BUS="ide", SYSFS{removable}="1", NAME{ignore_remove}="%k", GROUP="disk", MODE="0640" + +KERNEL="hd[a-z]*", NAME="%k", GROUP="disk", MODE="0640" +KERNEL="sd[a-z]*", NAME="%k", GROUP="disk", MODE="0640" KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" From 87da5b2c65e0a889093c27189212505328aea4ab Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 22:24:19 +0100 Subject: [PATCH 1085/4284] [PATCH] add SUBSYSTEM rule to catch all block devices and apply the disk permissions --- etc/udev/gentoo/udev.rules | 3 +++ etc/udev/redhat/udev.rules | 4 ++-- test/udev-test.pl | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index dbb0e6f51e..d89d8d0a2c 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -207,6 +207,9 @@ KERNEL="diskonkey*", NAME="%k", GROUP="disk" # rem_ide devices KERNEL="microdrive*", NAME="%k", GROUP="disk" +# all block devices +SUBSYSTEM="block", NAME="%k", GROUP="disk" + # kbd devices KERNEL="kbd", NAME="%k", MODE="0664" diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index d394e99016..30d8ba7c98 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -104,7 +104,7 @@ KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD- KERNEL="sr[0-9]*", BUS="scsi", NAME="scd%n", GROUP="disk", MODE="0640" KERNEL="hd[a-z]*", BUS="ide", SYSFS{removable}="1", NAME{ignore_remove}="%k", GROUP="disk", MODE="0640" -KERNEL="hd[a-z]*", NAME="%k", GROUP="disk", MODE="0640" -KERNEL="sd[a-z]*", NAME="%k", GROUP="disk", MODE="0640" +# all block devices +SUBSYSTEM="block", NAME="%k", GROUP="disk", MODE="0640" KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" diff --git a/test/udev-test.pl b/test/udev-test.pl index 53eee35457..bc8c4560d3 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -215,7 +215,7 @@ EOF #\\ KERNEL="ttyUSB0", \\ -NAME="visor" + NAME="visor" EOF }, From e93901468c668f3dda6f57ee7f4b953e287b1622 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 20 Dec 2004 23:44:57 +0100 Subject: [PATCH 1086/4284] [PATCH] allow permissions only rules On Mon, 2004-12-20 at 15:03 +0100, Marco d'Itri wrote: > +# all block devices > > +SUBSYSTEM="block", NAME="%k", GROUP="disk" > > + > NAME="%k" here and in similar rules does not add any new information, > what about making it optional, like it is for SYMLINK-only rules? --- namedev.c | 29 +++++++++++++++++++++++------ test/udev-test.pl | 12 ++++++++++++ 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/namedev.c b/namedev.c index 3da783b55d..58615ad5d0 100644 --- a/namedev.c +++ b/namedev.c @@ -716,18 +716,35 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d list_for_each_entry(dev, &config_device_list, node) { dbg("process rule"); if (match_rule(udev, dev, class_dev, sysfs_device) == 0) { - /* empty name and symlink will not create any node */ if (dev->name[0] == '\0' && dev->symlink[0] == '\0') { - info("configured rule in '%s' at line %i applied, '%s' is ignored", - dev->config_file, dev->config_line, udev->kernel_name); - return -1; + /* empty name, symlink, perms will not create any node */ + if (dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0') { + info("configured rule in '%s[%i]' applied, '%s' is ignored", + dev->config_file, dev->config_line, udev->kernel_name); + return -1; + } + + if (dev->mode != 0000) { + udev->mode = dev->mode; + dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name); + } + if (dev->owner[0] != '\0') { + strfieldcpy(udev->owner, dev->owner); + apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); + dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); + } + if (dev->group[0] != '\0') { + strfieldcpy(udev->group, dev->group); + apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); + dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); + } } /* collect symlinks for the final matching rule */ if (dev->symlink[0] != '\0') { char temp[NAME_SIZE]; - info("configured rule in '%s' at line %i applied, added symlink '%s'", + info("configured symlink-only rule in '%s[%i]' applied, added symlink '%s'", dev->config_file, dev->config_line, dev->symlink); strfieldcpy(temp, dev->symlink); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); @@ -743,7 +760,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d (udev->type != 'b' || udev->kernel_number[0] != '\0')) continue; - info("configured rule in '%s' at line %i applied, '%s' becomes '%s'", + info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", dev->config_file, dev->config_line, udev->kernel_name, dev->name); strfieldcpy(udev->name, dev->name); diff --git a/test/udev-test.pl b/test/udev-test.pl index bc8c4560d3..578adc4df1 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -619,6 +619,18 @@ EOF exp_perms => "5000:100:0777", conf => < "permissions only rule", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "5000:100:0777", + conf => < Date: Tue, 21 Dec 2004 00:19:34 +0100 Subject: [PATCH 1087/4284] [PATCH] update Fedora config files and add some more tests --- etc/udev/redhat/udev.rules | 10 +++++----- test/udev-test.pl | 28 ++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 30d8ba7c98..9df77b3339 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -87,6 +87,9 @@ KERNEL="pcd[0-9]*", SYMLINK="cdrom%e" KERNEL="fd[0-9]*", SYMLINK="floppy%e" KERNEL="nst[0-9]*", SYMLINK="tape%e" +# default permissions for all block devices +SUBSYSTEM="block", GROUP="disk", MODE="0640" + KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ide-media.sh %k", RESULT="floppy", SYMLINK="floppy%e, NAME{ignore_remove, all_partitions}="%k", GROUP="floppy" KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", RESULT="cdrom", SYMLINK="cdrom%e" @@ -101,10 +104,7 @@ KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ch KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" # rename sr* to scd* -KERNEL="sr[0-9]*", BUS="scsi", NAME="scd%n", GROUP="disk", MODE="0640" -KERNEL="hd[a-z]*", BUS="ide", SYSFS{removable}="1", NAME{ignore_remove}="%k", GROUP="disk", MODE="0640" - -# all block devices -SUBSYSTEM="block", NAME="%k", GROUP="disk", MODE="0640" +KERNEL="sr[0-9]*", BUS="scsi", NAME="scd%n" +KERNEL="hd[a-z]*", BUS="ide", SYSFS{removable}="1", NAME{ignore_remove}="%k" KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" diff --git a/test/udev-test.pl b/test/udev-test.pl index 578adc4df1..b50554ceb9 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -631,6 +631,34 @@ EOF KERNEL="ttyUSB[0-9]*", OWNER="5000", GROUP="100", MODE="0777" KERNEL="ttyUSX[0-9]*", OWNER="5001", GROUP="101", MODE="0444" KERNEL="ttyUSB[0-9]*", NAME="ttyUSB%n" +EOF + }, + { + desc => "multiple permissions only rule", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "3000:4000:0777", + conf => < "permissions only rule with override at NAME rule", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "ttyUSB0", + exp_perms => "3000:8000:0777", + conf => < Date: Tue, 21 Dec 2004 06:10:57 +0100 Subject: [PATCH 1088/4284] [PATCH] remove default_* permissions from udev.conf file With the "permissions only rules" we can just place: MODE="0660", OWNER="root", GROUP="root" at the beginning of the rules file and get exactly the same behavior. If no values are given the compiled-in defaults are used. --- etc/udev/udev.conf.in | 12 ------------ test/udev-test.pl | 3 --- udev.8.in | 28 ---------------------------- udev.h | 3 --- udev_config.c | 22 ---------------------- udev_utils.c | 6 +++--- 6 files changed, 3 insertions(+), 71 deletions(-) diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index a4a79ad5c2..72e25ed482 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -14,18 +14,6 @@ udev_db="@udevdir@/.udevdb" # udev_rules - The name and location of the udev rules file udev_rules="@configdir@/rules.d" -# default_mode - set the default mode for all nodes that have no -# permissions specified -default_mode="0660" - -# default_owner - set the default owner for all nodes that have no - # permissions specified -default_owner="root" - -# default_group - set the default group for all nodes that have no - # permissions specified -default_group="root" - # udev_log - set to "yes" if you want logging, else "no" udev_log="yes" diff --git a/test/udev-test.pl b/test/udev-test.pl index b50554ceb9..67c0672759 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1255,9 +1255,6 @@ open CONF, ">$main_conf" || die "unable to create config file: $main_conf"; print CONF "udev_root=\"$udev_root\"\n"; print CONF "udev_db=\"$udev_db\"\n"; print CONF "udev_rules=\"$conf_tmp\"\n"; -print CONF "default_mode=\"0660\"\n"; -print CONF "default_owner=\"root\"\n"; -print CONF "default_group=\"root\"\n"; close CONF; my $test_num = 1; diff --git a/udev.8.in b/udev.8.in index 0cc2f939e3..4b8691f842 100644 --- a/udev.8.in +++ b/udev.8.in @@ -59,22 +59,6 @@ All rule files are read in lexical order. The default value is The switch to enable/disable logging of udev information The default value is .IR yes . -.TP -.B default_mode -The default mode for all nodes where no explicit value is given by a rule. -The default value is -.IR 0660 . -.TP -.B default_owner -The default owner for all nodes where no explicit value is given by a rule. -The default value is -.IR root . -.TP -.B default_group -The default group for all nodes where no explicitly value is given by a rule. -The default value is -.IR root . -.br .P .RI "A sample " udev.conf " file might look like this: .sp @@ -91,18 +75,6 @@ udev_rules="/etc/udev/rules.d/" # udev_log - set to "yes" if you want logging, else "no" udev_log="yes" - -# default_mode - set the default mode for all nodes that have no -# permissions specified -default_mode="0660" - -# default_owner - set the default owner for all nodes that have no -# permissions specified -default_owner="root" - -# default_group - set the default group for all nodes that have no -# permissions specified -default_group="root" .fi .P The rules for device naming are read from the files located in the diff --git a/udev.h b/udev.h index 80eafb0d46..07385ccec5 100644 --- a/udev.h +++ b/udev.h @@ -81,9 +81,6 @@ extern char udev_root[PATH_MAX]; extern char udev_db_path[PATH_MAX+NAME_MAX]; extern char udev_config_filename[PATH_MAX+NAME_MAX]; extern char udev_rules_filename[PATH_MAX+NAME_MAX]; -extern mode_t default_mode; -extern char default_owner[USER_SIZE]; -extern char default_group[USER_SIZE]; extern int udev_log; extern int udev_dev_d; extern int udev_hotplug_d; diff --git a/udev_config.c b/udev_config.c index da8c676d04..21b62488c0 100644 --- a/udev_config.c +++ b/udev_config.c @@ -45,9 +45,6 @@ char udev_root[PATH_MAX]; char udev_db_path[PATH_MAX+NAME_MAX]; char udev_rules_filename[PATH_MAX+NAME_MAX]; char udev_config_filename[PATH_MAX+NAME_MAX]; -mode_t default_mode; -char default_owner[USER_SIZE]; -char default_group[USER_SIZE]; int udev_log; int udev_dev_d; int udev_hotplug_d; @@ -74,10 +71,6 @@ static void init_variables(void) strcpy(udev_config_filename, UDEV_CONFIG_FILE); strcpy(udev_rules_filename, UDEV_RULES_FILE); - strcpy(default_owner, "root"); - strcpy(default_group, "root"); - default_mode = 0660; - udev_log = string_is_true(UDEV_LOG_DEFAULT); udev_dev_d = 1; @@ -169,21 +162,6 @@ static int parse_config_file(void) continue; } - if (strcasecmp(variable, "default_mode") == 0) { - default_mode = strtol(value, NULL, 8); - continue; - } - - if (strcasecmp(variable, "default_owner") == 0) { - strfieldcpy(default_owner, value); - continue; - } - - if (strcasecmp(variable, "default_group") == 0) { - strfieldcpy(default_group, value); - continue; - } - if (strcasecmp(variable, "udev_log") == 0) { udev_log = string_is_true(value); continue; diff --git a/udev_utils.c b/udev_utils.c index fe18892de1..3c5344a8f9 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -57,9 +57,9 @@ void udev_init_device(struct udevice *udev, const char* devpath, const char *sub else if (strncmp(udev->devpath, "/class/", 7) == 0) udev->type = 'c'; - udev->mode = default_mode; - strfieldcpy(udev->owner, default_owner); - strfieldcpy(udev->group, default_group); + udev->mode = 0660; + strcpy(udev->owner, "root"); + strcpy(udev->group, "root"); } int kernel_release_satisfactory(int version, int patchlevel, int sublevel) From 3908058c10dea619e1c676ee8a167ef3e590a3bd Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 22 Dec 2004 01:41:03 +0100 Subject: [PATCH 1089/4284] [PATCH] correct log statement --- namedev.c | 3 ++- udev.8.in | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/namedev.c b/namedev.c index 58615ad5d0..26c68fadf6 100644 --- a/namedev.c +++ b/namedev.c @@ -724,6 +724,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d return -1; } + /* apply permissions only rule values */ if (dev->mode != 0000) { udev->mode = dev->mode; dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name); @@ -744,7 +745,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d if (dev->symlink[0] != '\0') { char temp[NAME_SIZE]; - info("configured symlink-only rule in '%s[%i]' applied, added symlink '%s'", + info("configured rule in '%s[%i]' applied, added symlink '%s'", dev->config_file, dev->config_line, dev->symlink); strfieldcpy(temp, dev->symlink); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); diff --git a/udev.8.in b/udev.8.in index 4b8691f842..aaaf231636 100644 --- a/udev.8.in +++ b/udev.8.in @@ -176,7 +176,7 @@ distribution provided rules file. .TP .B OWNER, GROUP, MODE The permissions for the device node. Every specified value overwrites the -default value specified in the config file. +compiled-in default value. .P .RB "The " NAME ", " SYMLINK ", " PROGRAM ", " OWNER " and " GROUP fields support simple printf-like string substitutions: From d3c3763530955a898e1d50c6844765e94ac957c2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 5 Jan 2005 05:31:42 +0100 Subject: [PATCH 1090/4284] [PATCH] correct detection of hotplug.d/ udevsend loop If udevsend is called from the commandline the env may be too big to fit in our buffer and we tag the message. --- udevsend.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/udevsend.c b/udevsend.c index 05a50facc5..d86004ba3b 100644 --- a/udevsend.c +++ b/udevsend.c @@ -148,10 +148,6 @@ int main(int argc, char *argv[], char *envp[]) key = envp[i]; keylen = strlen(key); - if (bufpos + keylen >= HOTPLUG_BUFFER_SIZE-1) { - dbg("environment buffer too small, probably not called by the kernel"); - continue; - } /* prevent loops in the scripts we execute */ if (strncmp(key, "UDEVD_EVENT=", 12) == 0) { @@ -159,6 +155,11 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + if (bufpos + keylen >= HOTPLUG_BUFFER_SIZE-1) { + dbg("environment buffer too small, probably not called by the kernel"); + continue; + } + /* remember the SUBSYSTEM */ if (strncmp(key, "SUBSYSTEM=", 10) == 0) subsystem = &key[10]; From 8b72687876747186d5f1a5a45464bf64b1a166f5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 5 Jan 2005 05:33:26 +0100 Subject: [PATCH 1091/4284] [PATCH] limit the initial timeout of the udevd event handling Define an inititialization phase, where we delay the events only for a short time to eventually recollect the event sequence instead of delaying the very first events for 10 seconds, which breaks the firmware loader. --- udevd.c | 21 ++++++++++++++++++--- udevd.h | 4 +++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/udevd.c b/udevd.c index 3c29c2be6e..c6642f4359 100644 --- a/udevd.c +++ b/udevd.c @@ -47,6 +47,7 @@ static int udevsendsock; static int pipefds[2]; +static long startup_time; static unsigned long long expected_seqnum = 0; static volatile int sigchilds_waiting; static volatile int run_msg_q; @@ -220,6 +221,8 @@ static void msg_queue_manager(void) struct hotplug_msg *tmp_msg; struct sysinfo info; long msg_age = 0; + static int timeout = EVENT_INIT_TIMEOUT_SEC; + static int init = 1; dbg("msg queue manager, next expected is %llu", expected_seqnum); recheck: @@ -230,11 +233,18 @@ recheck: continue; } + /* see if we are in the initialization phase and wait for the very first events */ + if (init && (info.uptime - startup_time >= INIT_TIME_SEC)) { + init = 0; + timeout = EVENT_TIMEOUT_SEC; + dbg("initialization phase passed, set timeout to %i seconds", EVENT_TIMEOUT_SEC); + } + /* move event with expired timeout to the exec list */ sysinfo(&info); msg_age = info.uptime - loop_msg->queue_time; dbg("seq %llu is %li seconds old", loop_msg->seqnum, msg_age); - if (msg_age > EVENT_TIMEOUT_SEC-1) { + if (msg_age >= timeout) { msg_move_exec(loop_msg); goto recheck; } else { @@ -246,8 +256,8 @@ recheck: /* set timeout for remaining queued events */ if (list_empty(&msg_list) == 0) { - struct itimerval itv = {{0, 0}, {EVENT_TIMEOUT_SEC - msg_age, 0}}; - dbg("next event expires in %li seconds", EVENT_TIMEOUT_SEC - msg_age); + struct itimerval itv = {{0, 0}, {timeout - msg_age, 0}}; + dbg("next event expires in %li seconds", timeout - msg_age); setitimer(ITIMER_REAL, &itv, NULL); } } @@ -429,6 +439,7 @@ static void user_sighandler(void) int main(int argc, char *argv[], char *envp[]) { + struct sysinfo info; int maxsockplus; struct sockaddr_un saddr; socklen_t addrlen; @@ -532,6 +543,10 @@ int main(int argc, char *argv[], char *envp[]) else udev_bin = UDEV_BIN; + /* handle special startup timeout*/ + sysinfo(&info); + startup_time = info.uptime; + FD_ZERO(&readfds); FD_SET(udevsendsock, &readfds); FD_SET(pipefds[0], &readfds); diff --git a/udevd.h b/udevd.h index 1c4b1b88c2..28f62cf528 100644 --- a/udevd.h +++ b/udevd.h @@ -25,10 +25,12 @@ #include "list.h" #define UDEV_MAGIC "udevd_" UDEV_VERSION -#define EVENT_TIMEOUT_SEC 10 #define UDEVD_SOCK_PATH "udevd" #define SEND_WAIT_MAX_SECONDS 3 #define SEND_WAIT_LOOP_PER_SECOND 10 +#define INIT_TIME_SEC 5 +#define EVENT_INIT_TIMEOUT_SEC 2 +#define EVENT_TIMEOUT_SEC 10 /* environment buffer, should match the kernel's size in lib/kobject_uevent.h */ #define HOTPLUG_BUFFER_SIZE 1024 From e750d24b0552f4fb11672ab5bdf72f536a047446 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 5 Jan 2005 05:33:49 +0100 Subject: [PATCH 1092/4284] [PATCH] remove udevsend syslog noise on udevd startup --- udevsend.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevsend.c b/udevsend.c index d86004ba3b..5fe0f456a1 100644 --- a/udevsend.c +++ b/udevsend.c @@ -195,10 +195,10 @@ int main(int argc, char *argv[], char *envp[]) dbg("try to start udevd daemon"); retval = start_daemon(); if (retval) { - info("error starting daemon"); + dbg("error starting daemon"); goto fallback; } - info("udevd daemon started"); + dbg("udevd daemon started"); started_daemon = 1; } else { dbg("retry to connect %d", SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND - loop); From 7b6571a9fc1909a7231ec9018ddd6602389363d3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 5 Jan 2005 05:35:24 +0100 Subject: [PATCH 1093/4284] [PATCH] improve event sequence serialization We delay the execution of events if there is already an event running for the same device, a parent or a child device. "add" events with a reference to a physical device will also wait for the physical device to finish. Here we fix the devpath comparison logic to return "busy" only if a complete device names is matching. /block/sdaa will not longer block a /block/sda event. --- udevd.c | 55 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/udevd.c b/udevd.c index c6642f4359..5694584840 100644 --- a/udevd.c +++ b/udevd.c @@ -151,34 +151,51 @@ static void udev_run(struct hotplug_msg *msg) } } -/* returns still running task for the same event sequence */ +static int compare_devpath(const char *running, const char *waiting) +{ + int i; + + for (i = 0; i < DEVPATH_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; +} + +/* returns still running task for the same device, its parent or its physical device */ static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) { struct hotplug_msg *loop_msg; - int i; + + if (msg->devpath == NULL) + return NULL; list_for_each_entry(loop_msg, &running_list, list) { - if (loop_msg->devpath == NULL || msg->devpath == NULL) + if (loop_msg->devpath == NULL) continue; - /* is a parent or child device event still running */ - for (i = 0; i < DEVPATH_SIZE; i++) { - if (loop_msg->devpath[i] == '\0' || msg->devpath[i] == '\0') - return loop_msg; + /* return running parent/child device event */ + if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) + return loop_msg; - if (loop_msg->devpath[i] != msg->devpath[i]) - break; - } - - /* is the physical device event still running on an add sequence */ + /* return running physical device event */ if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0) - for (i = 0; i < DEVPATH_SIZE; i++) { - if (loop_msg->devpath[i] == '\0' || msg->physdevpath[i] == '\0') - return loop_msg; - - if (loop_msg->devpath[i] != msg->physdevpath[i]) - break; - } + if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0) + return loop_msg; } return NULL; From ddf695023f501001ad35fd8f7d9ecb72e6cea472 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 5 Jan 2005 05:37:01 +0100 Subject: [PATCH 1094/4284] [PATCH] remove useless warning if udev.conf contains keys not read by udev itself --- udev_config.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/udev_config.c b/udev_config.c index 21b62488c0..5e204488d2 100644 --- a/udev_config.c +++ b/udev_config.c @@ -166,9 +166,6 @@ static int parse_config_file(void) udev_log = string_is_true(value); continue; } - - info("%s:%d:%Zd: unknown key '%s'", - udev_config_filename, lineno, temp-line, temp); } file_unmap(buf, bufsize); From 021a294c04ad9e96706914765fe83148c287aded Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 5 Jan 2005 05:37:50 +0100 Subject: [PATCH 1095/4284] [PATCH] udevd: split up message receiving an queueing --- udevd.c | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/udevd.c b/udevd.c index 5694584840..0049e696f1 100644 --- a/udevd.c +++ b/udevd.c @@ -101,9 +101,14 @@ static void msg_queue_insert(struct hotplug_msg *msg) struct hotplug_msg *loop_msg; struct sysinfo info; - /* sort message by sequence number into list. events - * will tend to come in order, so scan the list backwards - */ + if (msg->seqnum == 0) { + dbg("no SEQNUM, move straight to the exec queue"); + list_add(&msg->list, &exec_list); + run_exec_q = 1; + return; + } + + /* sort message by sequence number into list */ list_for_each_entry_reverse(loop_msg, &msg_list, list) if (loop_msg->seqnum < msg->seqnum) break; @@ -279,8 +284,8 @@ recheck: } } -/* receive the msg, do some basic sanity checks, and queue it */ -static void handle_udevsend_msg(int sock) +/* receive the udevsend message and do some sanity checks */ +static struct hotplug_msg *get_udevsend_msg(void) { static struct udevsend_msg usend_msg; struct hotplug_msg *msg; @@ -304,33 +309,36 @@ static void handle_udevsend_msg(int sock) smsg.msg_control = cred_msg; smsg.msg_controllen = sizeof(cred_msg); - size = recvmsg(sock, &smsg, 0); + size = recvmsg(udevsendsock, &smsg, 0); if (size < 0) { if (errno != EINTR) - dbg("unable to receive message"); - return; + dbg("unable to receive udevsend message"); + return NULL; } cmsg = CMSG_FIRSTHDR(&smsg); cred = (struct ucred *) CMSG_DATA(cmsg); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { dbg("no sender credentials received, message ignored"); - goto exit; + return NULL; } if (cred->uid != 0) { dbg("sender uid=%i, message ignored", cred->uid); - goto exit; + return NULL; } if (strncmp(usend_msg.magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { dbg("message magic '%s' doesn't match, ignore it", usend_msg.magic); - goto exit; + return NULL; } envbuf_size = size - offsetof(struct udevsend_msg, envbuf); dbg("envbuf_size=%i", envbuf_size); msg = malloc(sizeof(struct hotplug_msg) + envbuf_size); + if (msg == NULL) + return NULL; + memset(msg, 0x00, sizeof(struct hotplug_msg) + envbuf_size); /* copy environment buffer and reconstruct envp */ @@ -365,16 +373,7 @@ static void handle_udevsend_msg(int sock) msg->envp[i++] = "UDEVD_EVENT=1"; msg->envp[i] = NULL; - /* if no seqnum is given, we move straight to exec queue */ - if (msg->seqnum == 0) { - list_add(&msg->list, &exec_list); - run_exec_q = 1; - } else { - msg_queue_insert(msg); - } - -exit: - return; + return msg; } static void asmlinkage sig_handler(int signum) @@ -569,6 +568,8 @@ int main(int argc, char *argv[], char *envp[]) FD_SET(pipefds[0], &readfds); maxsockplus = udevsendsock+1; while (1) { + struct hotplug_msg *msg; + fd_set workreadfds = readfds; retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); @@ -578,8 +579,11 @@ int main(int argc, char *argv[], char *envp[]) continue; } - if (FD_ISSET(udevsendsock, &workreadfds)) - handle_udevsend_msg(udevsendsock); + if (FD_ISSET(udevsendsock, &workreadfds)) { + msg = get_udevsend_msg(); + if (msg) + msg_queue_insert(msg); + } if (FD_ISSET(pipefds[0], &workreadfds)) user_sighandler(); From adf3af8c359775e00c6323fde61264ed15ee0721 Mon Sep 17 00:00:00 2001 From: "roland@digitalvampire.org" Date: Wed, 12 Jan 2005 10:34:02 +0100 Subject: [PATCH 1096/4284] [PATCH] This fixes a silly mistake in how udevinfo prints the major and minor --- udevinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index 00af081eac..a80ca82e12 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -218,8 +218,8 @@ static int print_sysfs_devices(void) attr = sysfs_get_classdev_attr(class_dev, "dev"); if (attr) { sscanf(attr->value, "%u:%u", &major, &minor); - printf("MAJOR %u\n", minor); - printf("MINOR %u\n", major); + printf("MAJOR %u\n", major); + printf("MINOR %u\n", minor); } phys_dev = sysfs_get_classdev_device(class_dev); From 240ce551799c78c6e77362e7b7feaaf09b72309b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 12 Jan 2005 10:44:52 +0100 Subject: [PATCH 1097/4284] [PATCH] udev_volume_id: version 27 Fix FAT label reading bug for very large volumes. Recognize FAT label at Win98 formatted volumes. Read iso9660 joliet descriptor for unicode labels. Support uuid/label of swap partitions. --- extras/volume_id/volume_id.c | 109 ++++++++++++++++++++++++++--------- extras/volume_id/volume_id.h | 4 +- 2 files changed, 84 insertions(+), 29 deletions(-) diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index 42d658895f..e28c730326 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -78,7 +78,7 @@ /* size of superblock buffer, reiserfs block is at 64k */ #define SB_BUFFER_SIZE 0x11000 /* size of seek buffer 4k */ -#define SEEK_BUFFER_SIZE 0x1000 +#define SEEK_BUFFER_SIZE 0x10000 static void set_label_raw(struct volume_id *id, @@ -221,8 +221,10 @@ static __u8 *get_buffer(struct volume_id *id, __u64 off, unsigned int len) return &(id->sbbuf[off]); } else { - if (len > SEEK_BUFFER_SIZE) - len = SEEK_BUFFER_SIZE; + if (len > SEEK_BUFFER_SIZE) { + dbg("seek buffer too small %d", SEEK_BUFFER_SIZE); + return NULL; + } /* get seek buffer */ if (id->seekbuf == NULL) { @@ -232,8 +234,7 @@ static __u8 *get_buffer(struct volume_id *id, __u64 off, unsigned int len) } /* check if we need to read */ - if ((off < id->seekbuf_off) || - ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { + if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { dbg("read seekbuf off:0x%llx len:0x%x", off, len); if (lseek(id->fd, off, SEEK_SET) == -1) return NULL; @@ -241,8 +242,10 @@ static __u8 *get_buffer(struct volume_id *id, __u64 off, unsigned int len) dbg("got 0x%x (%i) bytes", buf_len, buf_len); id->seekbuf_off = off; id->seekbuf_len = buf_len; - if (buf_len < len) + if (buf_len < len) { + dbg("requested 0x%x bytes, got only 0x%x bytes", len, buf_len); return NULL; + } } return &(id->seekbuf[off - id->seekbuf_off]); @@ -571,7 +574,7 @@ static int probe_msdos_part_table(struct volume_id *id, __u64 off) p->partition_type_raw = part[i].sys_ind; if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) { - dbg("to many partitions"); + dbg("too many partitions"); next = 0; } } @@ -769,7 +772,9 @@ static int probe_jfs(struct volume_id *id, __u64 off) #define FAT12_MAX 0xff5 #define FAT16_MAX 0xfff5 -#define FAT_ATTR_VOLUME 0x08 +#define FAT_ATTR_VOLUME_ID 0x08 +#define FAT_ATTR_DIR 0x10 +#define FAT_ENTRY_FREE 0xe5 static int probe_vfat(struct volume_id *id, __u64 off) { struct vfat_super_block { @@ -832,7 +837,7 @@ static int probe_vfat(struct volume_id *id, __u64 off) __u16 dir_entries; __u32 sect_count; __u16 reserved; - __u16 fat_size; + __u32 fat_size; __u32 root_cluster; __u32 dir_size; __u32 cluster_count; @@ -959,12 +964,13 @@ valid: } /* empty entry */ - if (dir[i].name[0] == 0xe5) + if (dir[i].name[0] == FAT_ENTRY_FREE) continue; - if (dir[i].attr == FAT_ATTR_VOLUME) { - dbg("found ATTR_VOLUME id in root dir"); + if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { + dbg("found ATTR_VOLUME_ID id in root dir"); label = dir[i].name; + break; } dbg("skip dir entry"); @@ -1017,11 +1023,11 @@ fat32: } /* empty entry */ - if (dir[i].name[0] == 0xe5) + if (dir[i].name[0] == FAT_ENTRY_FREE) continue; - if (dir[i].attr == FAT_ATTR_VOLUME) { - dbg("found ATTR_VOLUME id in root dir"); + if ((dir[i].attr & (FAT_ATTR_VOLUME_ID | FAT_ATTR_DIR)) == FAT_ATTR_VOLUME_ID) { + dbg("found ATTR_VOLUME_ID id in root dir"); label = dir[i].name; goto fat32_label; } @@ -1047,7 +1053,7 @@ fat32_label: if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { set_label_raw(id, label, 11); set_label_string(id, label, 11); - } else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) == 0) { + } else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) != 0) { set_label_raw(id, vs->type.fat32.label, 11); set_label_string(id, vs->type.fat32.label, 11); } @@ -1214,6 +1220,12 @@ found: } #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 static int probe_iso9660(struct volume_id *id, __u64 off) { union iso_super_block { @@ -1239,8 +1251,36 @@ static int probe_iso9660(struct volume_id *id, __u64 off) return -1; if (strncmp(is->iso.id, "CD001", 5) == 0) { - set_label_raw(id, is->iso.volume_id, 32); - set_label_string(id, is->iso.volume_id, 32); + int vd_offset; + int i; + int found_svd; + + found_svd = 0; + vd_offset = ISO_VD_OFFSET; + for (i = 0; i < ISO_VD_MAX; i++) { + is = (union iso_super_block *) + get_buffer (id, off + vd_offset, 0x200); + if (is == NULL || is->iso.type == ISO_VD_END) + break; + if (is->iso.type == ISO_VD_SUPPLEMENTARY) { + dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset); + found_svd = 1; + break; + } + vd_offset += ISO_SECTOR_SIZE; + } + + if (!found_svd) { + is = (union iso_super_block *) + get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); + if (is == NULL) + return -1; + set_label_raw(id, is->iso.volume_id, 32); + set_label_string(id, is->iso.volume_id, 32); + } else { + set_label_raw(id, is->iso.volume_id, 32); + set_label_unicode16(id, is->iso.volume_id, BE, 32); + } goto found; } if (strncmp(is->hs.id, "CDROM", 5) == 0) @@ -1978,21 +2018,37 @@ found: #define LARGEST_PAGESIZE 0x4000 static int probe_swap(struct volume_id *id, __u64 off) { - const __u8 *sig; + struct swap_header_v1_2 { + __u8 bootbits[1024]; + __u32 version; + __u32 last_page; + __u32 nr_badpages; + __u8 uuid[16]; + __u8 volume_name[16]; + } __attribute__((__packed__)) *sw; + + const __u8 *buf; unsigned int page; - /* huhh, the swap signature is on the end of the PAGE_SIZE */ + /* the swap signature is at the end of the PAGE_SIZE */ for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { - sig = get_buffer(id, off + page-10, 10); - if (sig == NULL) + buf = get_buffer(id, off + page-10, 10); + if (buf == NULL) return -1; - if (strncmp(sig, "SWAP-SPACE", 10) == 0) { + if (strncmp(buf, "SWAP-SPACE", 10) == 0) { strcpy(id->type_version, "1"); goto found; } - if (strncmp(sig, "SWAPSPACE2", 10) == 0) { + + if (strncmp(buf, "SWAPSPACE2", 10) == 0) { + sw = (struct swap_header_v1_2 *) get_buffer(id, off, sizeof(struct swap_header_v1_2)); + if (sw == NULL) + return -1; strcpy(id->type_version, "2"); + set_label_raw(id, sw->volume_name, 16); + set_label_string(id, sw->volume_name, 16); + set_uuid(id, sw->uuid, UUID_DCE); goto found; } } @@ -2014,6 +2070,8 @@ int volume_id_probe(struct volume_id *id, { int rc; + dbg("called with size=0x%llx", size); + if (id == NULL) return -EINVAL; @@ -2088,9 +2146,6 @@ int volume_id_probe(struct volume_id *id, break; /* signature in the first block, only small buffer needed */ - rc = probe_msdos_part_table(id, off); - if (rc == 0) - break; rc = probe_vfat(id, off); if (rc == 0) break; diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index d135f44e50..c26d1e4daf 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -21,14 +21,14 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 26 +#define VOLUME_ID_VERSION 27 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 #define VOLUME_ID_UUID_STRING_SIZE 37 #define VOLUME_ID_FORMAT_SIZE 32 #define VOLUME_ID_PATH_MAX 256 -#define VOLUME_ID_PARTITIONS_MAX 16 +#define VOLUME_ID_PARTITIONS_MAX 256 enum volume_id_usage { VOLUME_ID_UNUSED, From 78b574cfcde57a93994f73ee6aca31e499b9dd09 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Jan 2005 07:38:49 -0800 Subject: [PATCH 1098/4284] [PATCH] add aoe block and char device rules to the gentoo rule file. --- etc/udev/gentoo/udev.rules | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index d89d8d0a2c..3c09d072da 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -77,6 +77,15 @@ 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, +# we might have to add a "CLASS" type one of these days to make this a bit saner +KERNEL="discover", NAME="etherd/%k", GROUP="disk", MODE="0220" +KERNEL="err", NAME="etherd/%k", GROUP="disk", MODE="0440" +KERNEL="interfaces", NAME="etherd/%k", GROUP="disk", MODE="0220" + +# aoe block devices +KERNEL="etherd*", NAME="%k", GROUP="disk" + # misc devices KERNEL="agpgart", NAME="misc/%k", SYMLINK="%k" KERNEL="psaux", NAME="misc/%k", SYMLINK="%k" From f15515b59ff373c3b9524a0842e96c1d105f5a62 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 16 Jan 2005 04:06:22 +0100 Subject: [PATCH 1099/4284] [PATCH] udevd: support -d switch to become a daemon --- udevd.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/udevd.c b/udevd.c index 0049e696f1..f1e28d9ca3 100644 --- a/udevd.c +++ b/udevd.c @@ -472,6 +472,24 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + /* daemonize on request */ + if (argc == 2 && strcmp(argv[1], "-d") == 0) { + pid_t pid; + + pid = fork(); + switch (pid) { + case 0: + dbg("damonized fork running"); + break; + case -1: + dbg("fork of daemon failed"); + goto exit; + default: + logging_close(); + exit(0); + } + } + /* make sure we don't lock any path */ chdir("/"); umask(umask(077) | 022); From c2cf40123f836b0f24da2604aba177b86b93823d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 16 Jan 2005 04:08:54 +0100 Subject: [PATCH 1100/4284] [PATCH] udevd: separate socket handling to prepare for other event sources --- udevd.c | 73 +++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 25 deletions(-) diff --git a/udevd.c b/udevd.c index f1e28d9ca3..7ae7a5b232 100644 --- a/udevd.c +++ b/udevd.c @@ -109,10 +109,16 @@ static void msg_queue_insert(struct hotplug_msg *msg) } /* sort message by sequence number into list */ - list_for_each_entry_reverse(loop_msg, &msg_list, list) + list_for_each_entry_reverse(loop_msg, &msg_list, list) { if (loop_msg->seqnum < msg->seqnum) break; + if (loop_msg->seqnum == msg->seqnum) { + dbg("ignoring duplicate message seq %llu", msg->seqnum); + return; + } + } + /* store timestamp of queuing */ sysinfo(&info); msg->queue_time = info.uptime; @@ -123,7 +129,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) /* run msg queue manager */ run_msg_q = 1; - return ; + return; } /* forks event and removes event from run queue when finished */ @@ -453,14 +459,45 @@ static void user_sighandler(void) } } +static int init_udevsend_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_SOCK_PATH); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (udevsendsock == -1) { + dbg("error getting socket, %s", strerror(errno)); + return -1; + } + + /* the bind takes care of ensuring only one copy running */ + retval = bind(udevsendsock, (struct sockaddr *) &saddr, addrlen); + if (retval < 0) { + dbg("bind failed, %s", strerror(errno)); + close(udevsendsock); + return -1; + } + + /* enable receiving of the sender credentials */ + setsockopt(udevsendsock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); + + return 0; +} + int main(int argc, char *argv[], char *envp[]) { struct sysinfo info; int maxsockplus; - struct sockaddr_un saddr; - socklen_t addrlen; - int retval, fd; - const int feature_on = 1; + int retval; + int fd; struct sigaction act; fd_set readfds; @@ -547,29 +584,15 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGALRM, &act, NULL); sigaction(SIGCHLD, &act, NULL); - memset(&saddr, 0x00, sizeof(saddr)); - saddr.sun_family = AF_LOCAL; - /* use abstract namespace for socket path */ - strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); - addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + if (init_udevsend_socket() < 0) { + if (errno == EADDRINUSE) + dbg("another udevd is running, exit"); + else + dbg("error initialising udevsend socket: %s", strerror(errno)); - udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (udevsendsock == -1) { - dbg("error getting socket, exit"); goto exit; } - /* the bind takes care of ensuring only one copy running */ - retval = bind(udevsendsock, (struct sockaddr *) &saddr, addrlen); - if (retval < 0) { - dbg("bind failed, exit"); - close(udevsendsock); - goto exit; - } - - /* enable receiving of the sender credentials */ - setsockopt(udevsendsock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); - /* possible override of udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); if (udev_bin != NULL) From ce043f851d4cb963cc0f566e590903dadb6c9fc1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 16 Jan 2005 04:39:02 +0100 Subject: [PATCH 1101/4284] [PATCH] udevd: it's obviously not the brightest idea to exit a device node manager if it doesn't find /dev/null --- udevd.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/udevd.c b/udevd.c index 7ae7a5b232..64abbe59a3 100644 --- a/udevd.c +++ b/udevd.c @@ -450,6 +450,7 @@ static void reap_sigchilds(void) static void user_sighandler(void) { int sig; + while(1) { int rc = read(pipefds[0], &sig, sizeof(sig)); if (rc < 0) @@ -533,15 +534,14 @@ int main(int argc, char *argv[], char *envp[]) /* Set fds to dev/null */ fd = open( "/dev/null", O_RDWR ); - if ( fd < 0 ) { + if (fd >= 0) { + dup2(fd, 0); + dup2(fd, 1); + dup2(fd, 2); + if (fd > 2) + close(fd); + } else dbg("error opening /dev/null %s", strerror(errno)); - goto exit; - } - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); /* become session leader */ setsid(); @@ -559,10 +559,8 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); - if (retval < 0) { + if (retval < 0) dbg("error fcntl on read pipe: %s", strerror(errno)); - goto exit; - } retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); if (retval < 0) { @@ -570,10 +568,8 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC); - if (retval < 0) { + if (retval < 0) dbg("error fcntl on write pipe: %s", strerror(errno)); - goto exit; - } /* set signal handlers */ act.sa_handler = (void (*) (int))sig_handler; @@ -586,7 +582,7 @@ int main(int argc, char *argv[], char *envp[]) if (init_udevsend_socket() < 0) { if (errno == EADDRINUSE) - dbg("another udevd is running, exit"); + dbg("another udevd running, exit"); else dbg("error initialising udevsend socket: %s", strerror(errno)); From 1e26698933e89c11dc6806d8bd37fd4386814239 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 16 Jan 2005 05:53:29 +0100 Subject: [PATCH 1102/4284] [PATCH] udevd: add possible initialization of expected_seqnum UDEVD_EXPECTED_SEQNUM=$[`cat /sys/kernel/hotplug_seqnum` + 1] ./udevd -d will init udevd, so the next event will not wait for any timeout. --- udevd.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/udevd.c b/udevd.c index 64abbe59a3..a8328bbb81 100644 --- a/udevd.c +++ b/udevd.c @@ -501,6 +501,7 @@ int main(int argc, char *argv[], char *envp[]) int fd; struct sigaction act; fd_set readfds; + const char *udevd_expected_seqnum; logging_init("udevd"); dbg("version %s", UDEV_VERSION); @@ -596,7 +597,14 @@ int main(int argc, char *argv[], char *envp[]) else udev_bin = UDEV_BIN; - /* handle special startup timeout*/ + /* possible set of expected_seqnum number */ + udevd_expected_seqnum = getenv("UDEVD_EXPECTED_SEQNUM"); + if (udevd_expected_seqnum != NULL) { + expected_seqnum = strtoull(udevd_expected_seqnum, NULL, 10); + dbg("initialize expected_seqnum to %llu", expected_seqnum); + } + + /* get current time to provide shorter startup timeout */ sysinfo(&info); startup_time = info.uptime; From 085cce379a4256cd039ccda3c8198aba058c8720 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 17 Jan 2005 00:53:08 +0100 Subject: [PATCH 1103/4284] [PATCH] udevd: throttle the forking of processes If the system reaches a defined limit of processes in running state, udevd starts to count its own processes in running state from its session (all forked hotplug child processes, subprocesses and callouts) and throttles further process forking if the limit is reached. This should help setups with hundreds of events emitted hotplug events in parallel with hundreds of processes in "R" state. which makes the machine unresponsible. I placed a 100% cpu time consuming program in /etc/hotplug.d/ which runs for 5 seconds. With this patch I can load "scsi_debug add_host=100" without any major problem. Without the patch the box is completly unresponsible for many minutes. --- udevd.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- udevd.h | 10 +++++ 2 files changed, 136 insertions(+), 9 deletions(-) diff --git a/udevd.c b/udevd.c index a8328bbb81..53c7bf3df1 100644 --- a/udevd.c +++ b/udevd.c @@ -28,11 +28,13 @@ #include #include #include +#include +#include +#include #include #include #include #include -#include #include #include @@ -45,6 +47,7 @@ /* global variables*/ static int udevsendsock; +static pid_t sid; static int pipefds[2]; static long startup_time; @@ -144,6 +147,8 @@ static void udev_run(struct hotplug_msg *msg) /* child */ close(udevsendsock); logging_close(); + + setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); execve(udev_bin, argv, msg->envp); dbg("exec of child failed"); _exit(1); @@ -151,9 +156,6 @@ static void udev_run(struct hotplug_msg *msg) case -1: dbg("fork of child failed"); run_queue_delete(msg); - /* note: we never managed to run, so we had no impact on - * running_with_devpath(), so don't bother setting run_exec_q - */ break; default: /* get SIGCHLD in main loop */ @@ -162,6 +164,100 @@ static void udev_run(struct hotplug_msg *msg) } } +static int running_processes(void) +{ + int f; + static char buf[4096]; + int len; + int running; + const char *pos; + + f = open("/proc/stat", O_RDONLY); + if (f == -1) + return -1; + + len = read(f, buf, sizeof(buf)); + close(f); + + if (len <= 0) + return -1; + else + buf[len] = '\0'; + + pos = strstr(buf, "procs_running "); + if (pos == NULL) + return -1; + + if (sscanf(pos, "procs_running %u", &running) != 1) + return -1; + + 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)); + 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; @@ -218,13 +314,30 @@ static void exec_queue_manager(void) struct hotplug_msg *loop_msg; struct hotplug_msg *tmp_msg; struct hotplug_msg *msg; + int running; + + running = running_processes(); + dbg("%d processes runnning on system", running); + if (running < 0) + running = THROTTLE_MAX_RUNNING_CHILDS; list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, list) { + /* check running processes in our session and possibly throttle */ + if (running >= THROTTLE_MAX_RUNNING_CHILDS) { + running = running_processes_in_session(sid, THROTTLE_MAX_RUNNING_CHILDS+10); + dbg("%d processes running in session", running); + if (running >= THROTTLE_MAX_RUNNING_CHILDS) { + dbg("delay seq %llu, cause too many processes already running", loop_msg->seqnum); + return; + } + } + msg = running_with_devpath(loop_msg); if (!msg) { /* move event to run list */ list_move_tail(&loop_msg->list, &running_list); udev_run(loop_msg); + running++; dbg("moved seq %llu to running list", loop_msg->seqnum); } else { dbg("delay seq %llu (%s), cause seq %llu (%s) is still running", @@ -529,10 +642,17 @@ int main(int argc, char *argv[], char *envp[]) } } + /* become session leader */ + sid = setsid(); + dbg("our session is %d", sid); + /* make sure we don't lock any path */ chdir("/"); umask(umask(077) | 022); + /*set a reasonable scheduling priority for the daemon */ + setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); + /* Set fds to dev/null */ fd = open( "/dev/null", O_RDWR ); if (fd >= 0) { @@ -544,9 +664,6 @@ int main(int argc, char *argv[], char *envp[]) } else dbg("error opening /dev/null %s", strerror(errno)); - /* become session leader */ - setsid(); - /* setup signal handler pipe */ retval = pipe(pipefds); if (retval < 0) { @@ -597,14 +714,14 @@ int main(int argc, char *argv[], char *envp[]) else udev_bin = UDEV_BIN; - /* possible set of expected_seqnum number */ + /* possible init of expected_seqnum value */ udevd_expected_seqnum = getenv("UDEVD_EXPECTED_SEQNUM"); if (udevd_expected_seqnum != NULL) { expected_seqnum = strtoull(udevd_expected_seqnum, NULL, 10); dbg("initialize expected_seqnum to %llu", expected_seqnum); } - /* get current time to provide shorter startup timeout */ + /* get current time to provide shorter timeout on startup */ sysinfo(&info); startup_time = info.uptime; diff --git a/udevd.h b/udevd.h index 28f62cf528..ae1d20e5ec 100644 --- a/udevd.h +++ b/udevd.h @@ -28,10 +28,20 @@ #define UDEVD_SOCK_PATH "udevd" #define SEND_WAIT_MAX_SECONDS 3 #define SEND_WAIT_LOOP_PER_SECOND 10 + +#define UDEVD_PRIORITY -4 +#define UDEV_PRIORITY -2 + +/* duration of initialization phase with shorter timeout */ #define INIT_TIME_SEC 5 #define EVENT_INIT_TIMEOUT_SEC 2 + +/* timeout to wait for missing events */ #define EVENT_TIMEOUT_SEC 10 +/* start to throttle forking if maximum number of running childs in our session is reached */ +#define THROTTLE_MAX_RUNNING_CHILDS 10 + /* environment buffer, should match the kernel's size in lib/kobject_uevent.h */ #define HOTPLUG_BUFFER_SIZE 1024 #define HOTPLUG_NUM_ENVP 32 From 5178355672901e2514e69cd0264f95ba155b8aba Mon Sep 17 00:00:00 2001 From: "tklauser@access.unizh.chbk" Date: Mon, 17 Jan 2005 03:54:26 +0100 Subject: [PATCH 1104/4284] [PATCH] I tried to compile udev 050plus with the GCC 4.0 snapshot 200412119 and --- udev_sysfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index d46f1f26d8..1b3603df6d 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -381,7 +381,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, struct sysfs_class_device *wait_class_device_open(const char *path) { - struct sysfs_class_device *class_dev; + struct sysfs_class_device *class_dev = NULL; int loop; loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; @@ -393,7 +393,7 @@ struct sysfs_class_device *wait_class_device_open(const char *path) usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } - return (class_dev); + return class_dev; } int wait_for_class_device(struct sysfs_class_device *class_dev, @@ -450,7 +450,7 @@ int wait_for_class_device(struct sysfs_class_device *class_dev, struct sysfs_device *wait_devices_device_open(const char *path) { - struct sysfs_device *devices_dev; + struct sysfs_device *devices_dev = NULL; int loop; loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; @@ -462,5 +462,5 @@ struct sysfs_device *wait_devices_device_open(const char *path) usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } - return(devices_dev); + return devices_dev; } From c3a8dac6ff48eb52e3529b23f3db84021bbc2f4a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 17 Jan 2005 09:26:07 +0100 Subject: [PATCH 1105/4284] [PATCH] klibc: update to version 0.196 --- klibc/Makefile | 2 +- klibc/include/string.h | 3 ++- klibc/klibc/Makefile | 2 +- klibc/klibc/getopt.c | 1 + klibc/klibc/memchr.c | 1 + klibc/klibc/memrchr.c | 20 ++++++++++++++++++++ klibc/version | 2 +- 7 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 klibc/klibc/memrchr.c diff --git a/klibc/Makefile b/klibc/Makefile index 8823a33bfd..2506417ef5 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -1,5 +1,5 @@ VERSION := $(shell cat version) -SUBDIRS = klibc +SUBDIRS = klibc ash ipconfig nfsmount utils kinit gzip all: diff --git a/klibc/include/string.h b/klibc/include/string.h index 3bbb217e98..5608a3c963 100644 --- a/klibc/include/string.h +++ b/klibc/include/string.h @@ -10,6 +10,7 @@ __extern void *memccpy(void *, const void *, int, size_t); __extern void *memchr(const void *, int, size_t); +__extern void *memrchr(const void *, int, size_t); __extern int memcmp(const void *, const void *, size_t); __extern void *memcpy(void *, const void *, size_t); __extern void *memmove(void *, const void *, size_t); @@ -20,6 +21,7 @@ __extern int strcasecmp(const char *, const char *); __extern int strncasecmp(const char *, const char *, size_t); __extern char *strcat(char *, const char *); __extern char *strchr(const char *, int); +__extern char *strrchr(const char *, int); __extern int strcmp(const char *, const char *); __extern char *strcpy(char *, const char *); __extern size_t strcspn(const char *, const char *); @@ -34,7 +36,6 @@ __extern int strncmp(const char *, const char *, size_t); __extern char *strncpy(char *, const char *, size_t); __extern size_t strlcpy(char *, const char *, size_t); __extern char *strpbrk(const char *, const char *); -__extern char *strrchr(const char *, int); __extern char *strsep(char **, const char *); __extern size_t strspn(const char *, const char *); __extern char *strstr(const char *, const char *); diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 0d44ce5494..d01b2e4326 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -30,7 +30,7 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ - memmove.o memchr.o \ + memmove.o memchr.o memrchr.o \ strcasecmp.o strncasecmp.o strndup.o strerror.o \ strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o strnlen.o \ strncat.o strlcpy.o strlcat.o \ diff --git a/klibc/klibc/getopt.c b/klibc/klibc/getopt.c index 5a992dcdd7..cd534bf304 100644 --- a/klibc/klibc/getopt.c +++ b/klibc/klibc/getopt.c @@ -51,6 +51,7 @@ int getopt(int argc, char * const *argv, const char *optstring) optind += 2; } else { /* Missing argument */ + optind++; return (optstring[0] == ':') ? ':' : '?'; } } diff --git a/klibc/klibc/memchr.c b/klibc/klibc/memchr.c index c5c5fa2963..2e5e4cc7f2 100644 --- a/klibc/klibc/memchr.c +++ b/klibc/klibc/memchr.c @@ -12,6 +12,7 @@ void *memchr(const void *s, int c, size_t n) while ( n-- ) { if ( *sp == (unsigned char)c ) return (void *)sp; + sp++; } return NULL; diff --git a/klibc/klibc/memrchr.c b/klibc/klibc/memrchr.c new file mode 100644 index 0000000000..10d9c29851 --- /dev/null +++ b/klibc/klibc/memrchr.c @@ -0,0 +1,20 @@ +/* + * memrchr.c + */ + +#include +#include + +void *memrchr(const void *s, int c, size_t n) +{ + const unsigned char *sp = + (const unsigned char *)s + n - 1; + + while ( n-- ) { + if ( *sp == (unsigned char)c ) + return (void *)sp; + sp--; + } + + return NULL; +} diff --git a/klibc/version b/klibc/version index b553d446e1..3759b0aad0 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.194 +0.196 From eb064000ca62e1f854db88c5011f308492d526d6 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 18 Jan 2005 09:13:01 +0100 Subject: [PATCH 1106/4284] [PATCH] udev_volume_id: fix FAT label reading --- extras/volume_id/volume_id.c | 54 ++++++++++++++++++++++++++++-------- extras/volume_id/volume_id.h | 2 +- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c index e28c730326..3bf7886aaa 100644 --- a/extras/volume_id/volume_id.c +++ b/extras/volume_id/volume_id.c @@ -774,6 +774,8 @@ static int probe_jfs(struct volume_id *id, __u64 off) #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 static int probe_vfat(struct volume_id *id, __u64 off) { @@ -859,6 +861,9 @@ static int probe_vfat(struct volume_id *id, __u64 off) /* believe only that's fat, don't trust the version * the cluster_count will tell us */ + if (strncmp(vs->sysid, "NTFS", 4) == 0) + return -1; + if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0) goto valid; @@ -956,7 +961,7 @@ valid: dir = (struct vfat_dir_entry*) buf; - for (i = 0; i <= root_dir_entries; i++) { + for (i = 0; i < root_dir_entries; i++) { /* end marker */ if (dir[i].name[0] == 0x00) { dbg("end of dir"); @@ -967,7 +972,15 @@ valid: 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"); label = dir[i].name; break; @@ -976,6 +989,10 @@ valid: dbg("skip dir entry"); } + vs = (struct vfat_super_block *) get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { set_label_raw(id, label, 11); set_label_string(id, label, 11); @@ -1015,7 +1032,7 @@ fat32: count = buf_size / sizeof(struct vfat_dir_entry); dbg("expected entries 0x%x", count); - for (i = 0; i <= count; i++) { + for (i = 0; i < count; i++) { /* end marker */ if (dir[i].name[0] == 0x00) { dbg("end of dir"); @@ -1026,7 +1043,15 @@ fat32: 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"); label = dir[i].name; goto fat32_label; @@ -1050,6 +1075,10 @@ fat32: dbg("reached maximum follow count of root cluster chain, give up"); fat32_label: + vs = (struct vfat_super_block *) get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { set_label_raw(id, label, 11); set_label_string(id, label, 11); @@ -1251,10 +1280,14 @@ static int probe_iso9660(struct volume_id *id, __u64 off) return -1; if (strncmp(is->iso.id, "CD001", 5) == 0) { + char root_label[VOLUME_ID_LABEL_SIZE+1]; int vd_offset; int i; int found_svd; + memset(root_label, 0, sizeof(root_label)); + strncpy(root_label, is->iso.volume_id, sizeof(root_label)-1); + found_svd = 0; vd_offset = ISO_VD_OFFSET; for (i = 0; i < ISO_VD_MAX; i++) { @@ -1264,22 +1297,19 @@ static int probe_iso9660(struct volume_id *id, __u64 off) break; if (is->iso.type == ISO_VD_SUPPLEMENTARY) { dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset); + set_label_raw(id, is->iso.volume_id, 32); + set_label_unicode16(id, is->iso.volume_id, BE, 32); found_svd = 1; break; } vd_offset += ISO_SECTOR_SIZE; } - if (!found_svd) { - is = (union iso_super_block *) - get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); - if (is == NULL) - return -1; - set_label_raw(id, is->iso.volume_id, 32); - set_label_string(id, is->iso.volume_id, 32); - } else { - set_label_raw(id, is->iso.volume_id, 32); - set_label_unicode16(id, is->iso.volume_id, BE, 32); + if (!found_svd || + (found_svd && !strncmp(root_label, id->label, 16))) + { + set_label_raw(id, root_label, 32); + set_label_string(id, root_label, 32); } goto found; } diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id.h index c26d1e4daf..9d66b196b7 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 27 +#define VOLUME_ID_VERSION 28 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 From 94f88ba5eebfcb45ecc99bc0c32b167204ad427a Mon Sep 17 00:00:00 2001 From: "hare@suse.de" Date: Thu, 20 Jan 2005 04:44:36 +0100 Subject: [PATCH 1107/4284] [PATCH] rearrange link order in Makefile The link-order in the main Makefile is not quite correct (sysfs should be linked after udev.a) which might cause the build to fail. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 52c1d47b2d..d56f22d0df 100644 --- a/Makefile +++ b/Makefile @@ -228,8 +228,8 @@ UDEV_OBJS = \ namedev_parse.o OBJS = \ - libsysfs/sysfs.a \ - udev.a + udev.a \ + libsysfs/sysfs.a SYSFS = $(PWD)/libsysfs/sysfs.a From aa7f11f4709798d5173d289475103cb078996f58 Mon Sep 17 00:00:00 2001 From: "greg@bucket.kroah.org" Date: Wed, 12 Jan 2005 08:15:22 -0800 Subject: [PATCH 1108/4284] [PATCH] fix gcc 2.96 issue in libsysfs --- libsysfs/dlist.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index 5f2c00be9b..c4ee324573 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -546,11 +546,14 @@ int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)) { - dlist_start(list); struct dlist *listsource, *listdest, *swap; - struct dlist *templist = dlist_new(list->data_size); + struct dlist *templist; unsigned int passcount = 1; unsigned int mergecount = 1; + + dlist_start(list); + templist = dlist_new(list->data_size); + // do nothing if there isn't anything to sort listsource = list; listdest = templist; From 83e1f809c93c5d3770504e13ed06041af8252d20 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 12 Jan 2005 17:46:50 -0800 Subject: [PATCH 1109/4284] [PATCH] clean up the aoe char device rules, and delete the block one as it's not needed. --- etc/udev/gentoo/udev.rules | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 3c09d072da..6f71321fb8 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -78,13 +78,9 @@ KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k", GROUP="disk" KERNEL="md[0-9]*", NAME="md/%n", SYMLINK="%k", GROUP="disk" # aoe char devices, -# we might have to add a "CLASS" type one of these days to make this a bit saner -KERNEL="discover", NAME="etherd/%k", GROUP="disk", MODE="0220" -KERNEL="err", NAME="etherd/%k", GROUP="disk", MODE="0440" -KERNEL="interfaces", NAME="etherd/%k", GROUP="disk", MODE="0220" - -# aoe block devices -KERNEL="etherd*", NAME="%k", GROUP="disk" +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" From 614238630687c6b7375f0adbc2692fcc0f3c7f9c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Wed, 19 Jan 2005 22:04:54 -0800 Subject: [PATCH 1110/4284] [PATCH] remove the lfs startup script on request of the author. The distro now has its own version, so this one is not needed. --- etc/init.d/udev.init.lfs | 60 ---------------------------------------- 1 file changed, 60 deletions(-) delete mode 100644 etc/init.d/udev.init.lfs diff --git a/etc/init.d/udev.init.lfs b/etc/init.d/udev.init.lfs deleted file mode 100644 index d4f64062b8..0000000000 --- a/etc/init.d/udev.init.lfs +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/sh -# -# LinuxFromScratch udev init script -# derived from original RedHat udev init script -# 2003, 2004 by Michael Buesch -# - -. /etc/sysconfig/rc -. $rc_functions -. /etc/udev/udev.conf - -sysfs_dir="/sys" - -case "$1" in - start) - echo "Creating initial udev device nodes ..." - if [ ! -d $sysfs_dir ]; then - echo "sysfs_dir $sysfs_dir does not exist!" - print_status failure - exit 1 - fi - if [ ! -d $udev_root ]; then - mkdir $udev_root - if [ $? -ne 0 ]; then - print_status failure - exit 1 - fi - fi - - # propogate /udev from /sys - we only need this while we do not - # have initramfs and an early user-space with which to do early - # device bring up - udevstart - evaluate_retval - ;; - stop) - echo "Stopping udev ..." - evaluate_retval - ;; - reload) - # nothing to do here - ;; - restart) - $0 stop - sleep 1 - $0 start - ;; - status) - if [ -d $udev_dir ]; then - echo "the udev device node directory exists" - else - echo "the udev device node directory does not exist" - fi - ;; - *) - echo "Usage: $0 {start|stop|restart|status}" - exit 1 - ;; -esac -exit 0 From 43ca395e49c854b6c3bb9abb633e9e072e5df793 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 28 Jan 2005 07:53:22 +0100 Subject: [PATCH 1111/4284] [PATCH] klibc: update to version 0.198 --- klibc/klibc.spec | 2 +- klibc/klibc/Makefile | 2 +- klibc/klibc/fread.c | 5 +++-- klibc/klibc/fwrite.c | 7 ++++--- klibc/klibc/sha1hash.c | 2 +- klibc/klibc/strncat.c | 6 ++---- klibc/version | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/klibc/klibc.spec b/klibc/klibc.spec index 272e52bc1a..02131c7f25 100644 --- a/klibc/klibc.spec +++ b/klibc/klibc.spec @@ -1,6 +1,6 @@ Summary: A minimal libc subset for use with initramfs. Name: klibc -Version: 0.194 +Version: 0.198 Release: 1 License: BSD/GPL Group: Development/Libraries diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index d01b2e4326..8a9a68bcf7 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -59,7 +59,7 @@ LIB = libc.a INTERP_O = interp.o -all: tests $(CRT0) $(LIB) $(SOLIB) klibc.so +all: tests $(CRT0) $(LIB) $(SOLIB) $(SOHASH) $(INTERP_O) # Add any architecture-specific rules include arch/$(ARCH)/Makefile.inc diff --git a/klibc/klibc/fread.c b/klibc/klibc/fread.c index 8f7dba9c19..a49f0d8210 100644 --- a/klibc/klibc/fread.c +++ b/klibc/klibc/fread.c @@ -15,9 +15,10 @@ size_t _fread(void *buf, size_t count, FILE *f) while ( count ) { rv = read(fileno(f), p, count); if ( rv == -1 ) { - if ( errno == EINTR ) + if ( errno == EINTR ) { + errno = 0; continue; - else + } else break; } else if ( rv == 0 ) { break; diff --git a/klibc/klibc/fwrite.c b/klibc/klibc/fwrite.c index 0a73188c67..ad61c86b88 100644 --- a/klibc/klibc/fwrite.c +++ b/klibc/klibc/fwrite.c @@ -15,9 +15,10 @@ size_t _fwrite(const void *buf, size_t count, FILE *f) while ( count ) { rv = write(fileno(f), p, count); if ( rv == -1 ) { - if ( errno == EINTR ) - continue; - else + if ( errno == EINTR ) { + errno = 0; + continue; + } else break; } else if ( rv == 0 ) { break; diff --git a/klibc/klibc/sha1hash.c b/klibc/klibc/sha1hash.c index f81e08b17c..28e3399967 100644 --- a/klibc/klibc/sha1hash.c +++ b/klibc/klibc/sha1hash.c @@ -263,7 +263,7 @@ unsigned char finalcount[8]; char *mybase64(uint8_t digest[20]) { static const char charz[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+_"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; uint8_t input[21]; static char output[28]; int i, j; diff --git a/klibc/klibc/strncat.c b/klibc/klibc/strncat.c index 0dd9deb984..4d8458d5ec 100644 --- a/klibc/klibc/strncat.c +++ b/klibc/klibc/strncat.c @@ -12,14 +12,12 @@ char *strncat(char *dst, const char *src, size_t n) char ch; size_t nn = q-dst; - if ( __likely(nn <= n) ) - n -= nn; - while (n--) { *q++ = ch = *p++; if ( !ch ) - break; + return dst; } + *q = '\0'; return dst; } diff --git a/klibc/version b/klibc/version index 3759b0aad0..129efcc007 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.196 +0.198 From 61b24e5e19fb189cfce7ff323c58e1bb1d7cce4d Mon Sep 17 00:00:00 2001 From: "cborntra@de.ibm.com" Date: Sun, 30 Jan 2005 13:09:38 +0100 Subject: [PATCH 1112/4284] [PATCH] udev_volume_id: fix -d option The -d option in udev_allows to go from a partition to the underlying disk for s390 dasd labels. If the device is already the disk itself, finding the parent will fail, therefore -d on /sys/block/dasda/ for example gives no result at all. --- extras/volume_id/udev_volume_id.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 3fab54786b..7b69856804 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -186,7 +186,7 @@ int main(int argc, char *argv[]) if (class_dev_parent != NULL) vid = open_classdev(class_dev_parent); else - vid = open_classdev(class_dev_parent); + vid = open_classdev(class_dev); if (vid == NULL) goto exit; From c033fd9f01b3cd5771875069c26d3af06969a300 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 31 Jan 2005 05:28:44 +0100 Subject: [PATCH 1113/4284] [PATCH] udev_volume_id: new version of volume_id Every filesystem has its own subdirectory. The IBM dasd label reading is included into volume_id. --- extras/volume_id/Makefile | 47 +- extras/volume_id/udev_volume_id.c | 35 +- extras/volume_id/volume_id.c | 2305 ----------------- .../{dasdlabel.c => volume_id/dasd/dasd.c} | 40 +- .../{dasdlabel.h => volume_id/dasd/dasd.h} | 6 +- extras/volume_id/volume_id/ext/ext.c | 86 + extras/volume_id/volume_id/ext/ext.h | 26 + extras/volume_id/volume_id/fat/fat.c | 350 +++ extras/volume_id/volume_id/fat/fat.h | 26 + extras/volume_id/volume_id/hfs/hfs.c | 308 +++ extras/volume_id/volume_id/hfs/hfs.h | 26 + .../volume_id/volume_id/highpoint/highpoint.c | 70 + .../volume_id/volume_id/highpoint/highpoint.h | 26 + extras/volume_id/volume_id/iso9660/iso9660.c | 115 + extras/volume_id/volume_id/iso9660/iso9660.h | 26 + extras/volume_id/volume_id/jfs/jfs.c | 74 + extras/volume_id/volume_id/jfs/jfs.h | 26 + .../volume_id/linux_raid/linux_raid.c | 97 + .../volume_id/linux_raid/linux_raid.h | 26 + .../volume_id/linux_swap/linux_swap.c | 87 + .../volume_id/linux_swap/linux_swap.h | 26 + .../logging.h} | 4 +- extras/volume_id/volume_id/lvm/lvm.c | 104 + extras/volume_id/volume_id/lvm/lvm.h | 27 + extras/volume_id/volume_id/mac/mac.c | 140 + extras/volume_id/volume_id/mac/mac.h | 26 + extras/volume_id/volume_id/msdos/msdos.c | 212 ++ extras/volume_id/volume_id/msdos/msdos.h | 26 + extras/volume_id/volume_id/ntfs/ntfs.c | 205 ++ extras/volume_id/volume_id/ntfs/ntfs.h | 26 + .../volume_id/volume_id/reiserfs/reiserfs.c | 97 + .../volume_id/volume_id/reiserfs/reiserfs.h | 26 + extras/volume_id/volume_id/udf/udf.c | 187 ++ extras/volume_id/volume_id/udf/udf.h | 26 + extras/volume_id/volume_id/ufs/ufs.c | 220 ++ extras/volume_id/volume_id/ufs/ufs.h | 26 + extras/volume_id/volume_id/util.c | 245 ++ extras/volume_id/volume_id/util.h | 91 + extras/volume_id/volume_id/volume_id.c | 202 ++ extras/volume_id/{ => volume_id}/volume_id.h | 47 +- extras/volume_id/volume_id/xfs/xfs.c | 74 + extras/volume_id/volume_id/xfs/xfs.h | 26 + 42 files changed, 3471 insertions(+), 2394 deletions(-) delete mode 100644 extras/volume_id/volume_id.c rename extras/volume_id/{dasdlabel.c => volume_id/dasd/dasd.c} (88%) rename extras/volume_id/{dasdlabel.h => volume_id/dasd/dasd.h} (87%) create mode 100644 extras/volume_id/volume_id/ext/ext.c create mode 100644 extras/volume_id/volume_id/ext/ext.h create mode 100644 extras/volume_id/volume_id/fat/fat.c create mode 100644 extras/volume_id/volume_id/fat/fat.h create mode 100644 extras/volume_id/volume_id/hfs/hfs.c create mode 100644 extras/volume_id/volume_id/hfs/hfs.h create mode 100644 extras/volume_id/volume_id/highpoint/highpoint.c create mode 100644 extras/volume_id/volume_id/highpoint/highpoint.h create mode 100644 extras/volume_id/volume_id/iso9660/iso9660.c create mode 100644 extras/volume_id/volume_id/iso9660/iso9660.h create mode 100644 extras/volume_id/volume_id/jfs/jfs.c create mode 100644 extras/volume_id/volume_id/jfs/jfs.h create mode 100644 extras/volume_id/volume_id/linux_raid/linux_raid.c create mode 100644 extras/volume_id/volume_id/linux_raid/linux_raid.h create mode 100644 extras/volume_id/volume_id/linux_swap/linux_swap.c create mode 100644 extras/volume_id/volume_id/linux_swap/linux_swap.h rename extras/volume_id/{volume_id_logging.h => volume_id/logging.h} (77%) create mode 100644 extras/volume_id/volume_id/lvm/lvm.c create mode 100644 extras/volume_id/volume_id/lvm/lvm.h create mode 100644 extras/volume_id/volume_id/mac/mac.c create mode 100644 extras/volume_id/volume_id/mac/mac.h create mode 100644 extras/volume_id/volume_id/msdos/msdos.c create mode 100644 extras/volume_id/volume_id/msdos/msdos.h create mode 100644 extras/volume_id/volume_id/ntfs/ntfs.c create mode 100644 extras/volume_id/volume_id/ntfs/ntfs.h create mode 100644 extras/volume_id/volume_id/reiserfs/reiserfs.c create mode 100644 extras/volume_id/volume_id/reiserfs/reiserfs.h create mode 100644 extras/volume_id/volume_id/udf/udf.c create mode 100644 extras/volume_id/volume_id/udf/udf.h create mode 100644 extras/volume_id/volume_id/ufs/ufs.c create mode 100644 extras/volume_id/volume_id/ufs/ufs.h create mode 100644 extras/volume_id/volume_id/util.c create mode 100644 extras/volume_id/volume_id/util.h create mode 100644 extras/volume_id/volume_id/volume_id.c rename extras/volume_id/{ => volume_id}/volume_id.h (70%) create mode 100644 extras/volume_id/volume_id/xfs/xfs.c create mode 100644 extras/volume_id/volume_id/xfs/xfs.h diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 5c8adb065b..f0c15b8fec 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -33,8 +33,50 @@ override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \ override CFLAGS+=-D_FILE_OFFSET_BITS=64 -OBJS = volume_id.o udev_volume_id.o dasdlabel.o $(SYSFS) -HEADERS = volume_id.h dasdlabel.h +VOLUME_ID_OBJS= \ + volume_id/ext/ext.o \ + volume_id/fat/fat.o \ + volume_id/hfs/hfs.o \ + volume_id/highpoint/highpoint.o \ + volume_id/iso9660/iso9660.o \ + volume_id/jfs/jfs.o \ + volume_id/linux_raid/linux_raid.o \ + volume_id/linux_swap/linux_swap.o \ + volume_id/lvm/lvm.o \ + volume_id/mac/mac.o \ + volume_id/msdos/msdos.o \ + volume_id/ntfs/ntfs.o \ + volume_id/reiserfs/reiserfs.o \ + volume_id/udf/udf.o \ + volume_id/ufs/ufs.o \ + volume_id/xfs/xfs.o \ + volume_id/dasd/dasd.o \ + volume_id/volume_id.o \ + volume_id/util.o + +VOLUME_ID_HEADERS= \ + volume_id/ext/ext.h \ + volume_id/fat/fat.h \ + volume_id/hfs/hfs.h \ + volume_id/highpoint/highpoint.h \ + volume_id/iso9660/iso9660.h \ + volume_id/jfs/jfs.h \ + volume_id/linux_raid/linux_raid.h \ + volume_id/linux_swap/linux_swap.h \ + volume_id/lvm/lvm.h \ + volume_id/mac/mac.h \ + volume_id/msdos/msdos.h \ + volume_id/ntfs/ntfs.h \ + volume_id/reiserfs/reiserfs.h \ + volume_id/udf/udf.h \ + volume_id/ufs/ufs.h \ + volume_id/xfs/xfs.h \ + volume_id/dasd/dasd.h \ + volume_id/volume_id.h \ + volume_id/util.h + +OBJS = udev_volume_id.o $(VOLUME_ID_OBJS) $(SYSFS) +HEADERS = $(VOLUME_ID_HEADERS) $(OBJS): $(HEADERS) @@ -54,4 +96,3 @@ install: all uninstall: - rm $(DESTDIR)$(sbindir)/$(PROG) - diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 7b69856804..915c1c4117 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -31,8 +31,8 @@ #include "../../libsysfs/sysfs/libsysfs.h" #include "../../udev_utils.h" #include "../../logging.h" -#include "volume_id.h" -#include "dasdlabel.h" +#include "volume_id/volume_id.h" +#include "volume_id/dasd/dasd.h" #define BLKGETSIZE64 _IOR(0x12,114,size_t) @@ -74,26 +74,6 @@ static struct volume_id *open_classdev(struct sysfs_class_device *class_dev) return vid; } -static char *usage_id_name(enum volume_id_usage usage) -{ - switch(usage) { - case VOLUME_ID_UNUSED: - return "unused"; - case VOLUME_ID_UNPROBED: - return "unprobed"; - case VOLUME_ID_OTHER: - return "other"; - case VOLUME_ID_PARTITIONTABLE: - return "partitiontable"; - case VOLUME_ID_FILESYSTEM: - return "filesystem"; - case VOLUME_ID_RAID: - return "raid"; - default: - return "unknown type_id"; - } -} - int main(int argc, char *argv[]) { const char help[] = "usage: udev_volume_id [-t|-l|-u|-d]\n" @@ -111,7 +91,6 @@ int main(int argc, char *argv[]) char *devpath; char probe = 'p'; char print = 'a'; - char dasd_label[7]; static char name[VOLUME_ID_LABEL_SIZE]; int len, i, j; unsigned long long size; @@ -177,7 +156,7 @@ int main(int argc, char *argv[]) if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) size = 0; - if (volume_id_probe(vid, VOLUME_ID_ALL, 0, size) == 0) + if (volume_id_probe_all(vid, 0, size) == 0) goto print; break; case 'd' : @@ -190,12 +169,8 @@ int main(int argc, char *argv[]) if (vid == NULL) goto exit; - if (probe_ibm_partition(vid->fd, dasd_label) == 0) { - vid->type = "dasd"; - strncpy(vid->label, dasd_label, 6); - vid->label[6] = '\0'; + if (probe_ibm_partition(vid) == 0) goto print; - } break; } @@ -247,7 +222,7 @@ print: printf("%s\n", vid->uuid); break; case 'a': - printf("F:%s\n", usage_id_name(vid->usage_id)); + printf("F:%s\n", vid->usage); printf("T:%s\n", vid->type); printf("V:%s\n", vid->type_version); printf("L:%s\n", vid->label); diff --git a/extras/volume_id/volume_id.c b/extras/volume_id/volume_id.c deleted file mode 100644 index 3bf7886aaa..0000000000 --- a/extras/volume_id/volume_id.c +++ /dev/null @@ -1,2305 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * The superblock structs are taken from the linux kernel sources - * and the libblkid living inside the e2fsprogs. This is a simple - * straightforward implementation for reading the label strings of the - * most common filesystems. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "volume_id.h" -#include "volume_id_logging.h" - -#define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \ - (((__u16)(x) & 0xff00u) >> 8)) - -#define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \ - (((__u32)(x) & 0x00ff0000u) >> 8) | \ - (((__u32)(x) & 0x0000ff00u) << 8) | \ - (((__u32)(x) & 0x000000ffu) << 24)) - -#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000ull) >> 56) | \ - (((__u64)(x) & 0x00ff000000000000ull) >> 40) | \ - (((__u64)(x) & 0x0000ff0000000000ull) >> 24) | \ - (((__u64)(x) & 0x000000ff00000000ull) >> 8) | \ - (((__u64)(x) & 0x00000000ff000000ull) << 8) | \ - (((__u64)(x) & 0x0000000000ff0000ull) << 24) | \ - (((__u64)(x) & 0x000000000000ff00ull) << 40) | \ - (((__u64)(x) & 0x00000000000000ffull) << 56)) - -#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) bswap16(x) -#define be32_to_cpu(x) bswap32(x) -#elif (__BYTE_ORDER == __BIG_ENDIAN) -#define le16_to_cpu(x) bswap16(x) -#define le32_to_cpu(x) bswap32(x) -#define le64_to_cpu(x) bswap64(x) -#define be16_to_cpu(x) (x) -#define be32_to_cpu(x) (x) -#endif - -/* size of superblock buffer, reiserfs block is at 64k */ -#define SB_BUFFER_SIZE 0x11000 -/* size of seek buffer 4k */ -#define SEEK_BUFFER_SIZE 0x10000 - - -static void set_label_raw(struct volume_id *id, - const __u8 *buf, unsigned int count) -{ - memcpy(id->label_raw, buf, count); - id->label_raw_len = count; -} - -static void set_label_string(struct volume_id *id, - const __u8 *buf, unsigned int count) -{ - unsigned int i; - - memcpy(id->label, buf, count); - - /* remove trailing whitespace */ - i = strnlen(id->label, count); - while (i--) { - if (! isspace(id->label[i])) - break; - } - id->label[i+1] = '\0'; -} - -#define LE 0 -#define BE 1 -static void set_label_unicode16(struct volume_id *id, - const __u8 *buf, - unsigned int endianess, - unsigned int count) -{ - unsigned int i, j; - __u16 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) { - id->label[j] = '\0'; - break; - } else if (c < 0x80) { - id->label[j++] = (__u8) c; - } else if (c < 0x800) { - id->label[j++] = (__u8) (0xc0 | (c >> 6)); - id->label[j++] = (__u8) (0x80 | (c & 0x3f)); - } else { - id->label[j++] = (__u8) (0xe0 | (c >> 12)); - id->label[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); - id->label[j++] = (__u8) (0x80 | (c & 0x3f)); - } - } -} - -enum uuid_format { - UUID_DCE, - UUID_DOS, - UUID_NTFS, - UUID_HFS, -}; - -static void set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format) -{ - unsigned int i; - unsigned int count = 0; - - switch(format) { - case UUID_DOS: - count = 4; - break; - case UUID_NTFS: - case UUID_HFS: - count = 8; - break; - case UUID_DCE: - count = 16; - } - memcpy(id->uuid_raw, buf, 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_NTFS: - 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_HFS: - 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; - } -} - -static __u8 *get_buffer(struct volume_id *id, __u64 off, unsigned int len) -{ - unsigned int buf_len; - - dbg("get buffer off 0x%llx, len 0x%x", 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) - return NULL; - } - - /* check if we need to read */ - if ((off + len) > id->sbbuf_len) { - dbg("read sbbuf len:0x%llx", off + len); - lseek(id->fd, 0, SEEK_SET); - buf_len = read(id->fd, id->sbbuf, off + len); - dbg("got 0x%x (%i) bytes", buf_len, buf_len); - id->sbbuf_len = buf_len; - if (buf_len < off + 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) - return NULL; - } - - /* check if we need to read */ - if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { - dbg("read seekbuf off:0x%llx len:0x%x", off, len); - if (lseek(id->fd, off, SEEK_SET) == -1) - return NULL; - buf_len = read(id->fd, id->seekbuf, len); - dbg("got 0x%x (%i) bytes", buf_len, buf_len); - id->seekbuf_off = off; - id->seekbuf_len = buf_len; - if (buf_len < len) { - dbg("requested 0x%x bytes, got only 0x%x bytes", len, buf_len); - return NULL; - } - } - - return &(id->seekbuf[off - id->seekbuf_off]); - } -} - -static void 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; - } -} - -#define HPT37X_CONFIG_OFF 0x1200 -#define HPT37X_MAGIC_OK 0x5a7816f0 -#define HPT37X_MAGIC_BAD 0x5a7816fd -static int probe_highpoint_ataraid(struct volume_id *id, __u64 off) -{ - struct hpt37x { - __u8 filler1[32]; - __u32 magic; - __u32 magic_0; - __u32 magic_1; - } __attribute__((packed)) *hpt; - - const __u8 *buf; - - buf = get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); - if (buf == NULL) - return -1; - - hpt = (struct hpt37x *) buf; - - if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD) - return -1; - - id->usage_id = VOLUME_ID_RAID; - id->type_id = VOLUME_ID_HPTRAID; - id->type = "hpt_ataraid_member"; - - return 0; -} - -#define LVM1_SB_OFF 0x400 -#define LVM1_MAGIC "HM" -static int probe_lvm1(struct volume_id *id, __u64 off) -{ - struct lvm2_super_block { - __u8 id[2]; - } __attribute__((packed)) *lvm; - - const __u8 *buf; - - buf = get_buffer(id, off + LVM1_SB_OFF, 0x800); - if (buf == NULL) - return -1; - - lvm = (struct lvm2_super_block *) buf; - - if (strncmp(lvm->id, LVM1_MAGIC, 2) != 0) - return -1; - - id->usage_id = VOLUME_ID_RAID; - id->type_id = VOLUME_ID_LVM1; - id->type = "LVM1_member"; - - return 0; -} - -#define LVM2_LABEL_ID "LABELONE" -#define LVM2LABEL_SCAN_SECTORS 4 -static int probe_lvm2(struct volume_id *id, __u64 off) -{ - struct lvm2_super_block { - __u8 id[8]; - __u64 sector_xl; - __u32 crc_xl; - __u32 offset_xl; - __u8 type[8]; - } __attribute__((packed)) *lvm; - - const __u8 *buf; - unsigned int soff; - - buf = 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 (strncmp(lvm->id, LVM2_LABEL_ID, 8) == 0) - goto found; - } - - return -1; - -found: - strncpy(id->type_version, lvm->type, 8); - id->usage_id = VOLUME_ID_RAID; - id->type_id = VOLUME_ID_LVM2; - id->type = "LVM2_member"; - - return 0; -} - -#define MD_RESERVED_BYTES 0x10000 -#define MD_MAGIC 0xa92b4efc -static int probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) -{ - struct mdp_super_block { - __u32 md_magic; - __u32 major_version; - __u32 minor_version; - __u32 patch_version; - __u32 gvalid_words; - __u32 set_uuid0; - __u32 ctime; - __u32 level; - __u32 size; - __u32 nr_disks; - __u32 raid_disks; - __u32 md_minor; - __u32 not_persistent; - __u32 set_uuid1; - __u32 set_uuid2; - __u32 set_uuid3; - } __attribute__((packed)) *mdp; - - const __u8 *buf; - __u64 sboff; - __u8 uuid[16]; - - if (size < 0x10000) - return -1; - - sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; - buf = get_buffer(id, off + sboff, 0x800); - if (buf == NULL) - return -1; - - mdp = (struct mdp_super_block *) buf; - - if (le32_to_cpu(mdp->md_magic) != MD_MAGIC) - return -1; - - memcpy(uuid, &mdp->set_uuid0, 4); - memcpy(&uuid[4], &mdp->set_uuid1, 12); - set_uuid(id, uuid, UUID_DCE); - - snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u", - le32_to_cpu(mdp->major_version), - le32_to_cpu(mdp->minor_version), - le32_to_cpu(mdp->patch_version)); - - dbg("found raid signature"); - id->usage_id = VOLUME_ID_RAID; - id->type = "linux_raid_member"; - - return 0; -} - -#define MSDOS_MAGIC "\x55\xaa" -#define MSDOS_PARTTABLE_OFFSET 0x1be -#define MSDOS_SIG_OFF 0x1fe -#define BSIZE 0x200 -#define DOS_EXTENDED_PARTITION 0x05 -#define LINUX_EXTENDED_PARTITION 0x85 -#define WIN98_EXTENDED_PARTITION 0x0f -#define LINUX_RAID_PARTITION 0xfd -#define is_extended(type) \ - (type == DOS_EXTENDED_PARTITION || \ - type == WIN98_EXTENDED_PARTITION || \ - type == LINUX_EXTENDED_PARTITION) -#define is_raid(type) \ - (type == LINUX_RAID_PARTITION) -static int probe_msdos_part_table(struct volume_id *id, __u64 off) -{ - struct msdos_partition_entry { - __u8 boot_ind; - __u8 head; - __u8 sector; - __u8 cyl; - __u8 sys_ind; - __u8 end_head; - __u8 end_sector; - __u8 end_cyl; - __u32 start_sect; - __u32 nr_sects; - } __attribute__((packed)) *part; - - const __u8 *buf; - int i; - __u64 poff; - __u64 plen; - __u64 extended = 0; - __u64 current; - __u64 next; - int limit; - int empty = 1; - struct volume_id_partition *p; - - buf = get_buffer(id, off, 0x200); - if (buf == NULL) - return -1; - - if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) - return -1; - - /* check flags on all entries for a valid partition table */ - part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; - for (i = 0; i < 4; i++) { - if (part[i].boot_ind != 0 && - part[i].boot_ind != 0x80) - return -1; - - if (le32_to_cpu(part[i].nr_sects) != 0) - empty = 0; - } - if (empty == 1) - return -1; - - if (id->partitions != NULL) - free(id->partitions); - id->partitions = malloc(VOLUME_ID_PARTITIONS_MAX * - sizeof(struct volume_id_partition)); - if (id->partitions == NULL) - return -1; - memset(id->partitions, 0x00, - VOLUME_ID_PARTITIONS_MAX * sizeof(struct volume_id_partition)); - - for (i = 0; i < 4; i++) { - poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; - plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; - - if (plen == 0) - continue; - - p = &id->partitions[i]; - - p->partition_type_raw = part[i].sys_ind; - - if (is_extended(part[i].sys_ind)) { - dbg("found extended partition at 0x%llx", poff); - p->usage_id = VOLUME_ID_PARTITIONTABLE; - p->type_id = VOLUME_ID_MSDOSEXTENDED; - p->type = "msdos_extended_partition"; - if (extended == 0) - extended = off + poff; - } else { - dbg("found 0x%x data partition at 0x%llx, len 0x%llx", - part[i].sys_ind, poff, plen); - - if (is_raid(part[i].sys_ind)) - p->usage_id = VOLUME_ID_RAID; - else - p->usage_id = VOLUME_ID_UNPROBED; - } - - p->off = off + poff; - p->len = plen; - id->partition_count = i+1; - } - - next = extended; - current = extended; - limit = 50; - - /* follow extended partition chain and add data partitions */ - while (next != 0) { - if (limit-- == 0) { - dbg("extended chain limit reached"); - break; - } - - buf = get_buffer(id, current, 0x200); - if (buf == NULL) - break; - - part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; - - if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) - break; - - next = 0; - - for (i = 0; i < 4; i++) { - poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; - plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; - - if (plen == 0) - continue; - - if (is_extended(part[i].sys_ind)) { - dbg("found extended partition at 0x%llx", poff); - if (next == 0) - next = extended + poff; - } else { - dbg("found 0x%x data partition at 0x%llx, len 0x%llx", - part[i].sys_ind, poff, plen); - - /* we always start at the 5th entry */ - while (id->partition_count < 4) - id->partitions[id->partition_count++].usage_id = - VOLUME_ID_UNUSED; - - p = &id->partitions[id->partition_count]; - - if (is_raid(part[i].sys_ind)) - p->usage_id = VOLUME_ID_RAID; - else - p->usage_id = VOLUME_ID_UNPROBED; - - p->off = current + poff; - p->len = plen; - id->partition_count++; - - p->partition_type_raw = part[i].sys_ind; - - if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) { - dbg("too many partitions"); - next = 0; - } - } - } - - current = next; - } - - id->usage_id = VOLUME_ID_PARTITIONTABLE; - id->type_id = VOLUME_ID_MSDOSPARTTABLE; - id->type = "msdos_partition_table"; - - return 0; -} - -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 -#define EXT_SUPERBLOCK_OFFSET 0x400 -static int probe_ext(struct volume_id *id, __u64 off) -{ - struct ext2_super_block { - __u32 inodes_count; - __u32 blocks_count; - __u32 r_blocks_count; - __u32 free_blocks_count; - __u32 free_inodes_count; - __u32 first_data_block; - __u32 log_block_size; - __u32 dummy3[7]; - __u8 magic[2]; - __u16 state; - __u32 dummy5[8]; - __u32 feature_compat; - __u32 feature_incompat; - __u32 feature_ro_compat; - __u8 uuid[16]; - __u8 volume_name[16]; - } __attribute__((__packed__)) *es; - - es = (struct ext2_super_block *) - get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); - if (es == NULL) - return -1; - - if (es->magic[0] != 0123 || - es->magic[1] != 0357) - return -1; - - set_label_raw(id, es->volume_name, 16); - set_label_string(id, es->volume_name, 16); - set_uuid(id, es->uuid, UUID_DCE); - - if ((le32_to_cpu(es->feature_compat) & - EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) { - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_EXT3; - id->type = "ext3"; - } else { - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_EXT2; - id->type = "ext2"; - } - - return 0; -} - -#define REISERFS1_SUPERBLOCK_OFFSET 0x2000 -#define REISERFS_SUPERBLOCK_OFFSET 0x10000 -static int probe_reiserfs(struct volume_id *id, __u64 off) -{ - struct reiserfs_super_block { - __u32 blocks_count; - __u32 free_blocks; - __u32 root_block; - __u32 journal_block; - __u32 journal_dev; - __u32 orig_journal_size; - __u32 dummy2[5]; - __u16 blocksize; - __u16 dummy3[3]; - __u8 magic[12]; - __u32 dummy4[5]; - __u8 uuid[16]; - __u8 label[16]; - } __attribute__((__packed__)) *rs; - - rs = (struct reiserfs_super_block *) - get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); - if (rs == NULL) - return -1; - - if (strncmp(rs->magic, "ReIsEr2Fs", 9) == 0) { - strcpy(id->type_version, "3.6"); - goto found; - } - - if (strncmp(rs->magic, "ReIsEr3Fs", 9) == 0) { - strcpy(id->type_version, "JR"); - goto found; - } - - rs = (struct reiserfs_super_block *) - get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200); - if (rs == NULL) - return -1; - - if (strncmp(rs->magic, "ReIsErFs", 8) == 0) { - strcpy(id->type_version, "3.5"); - goto found; - } - - return -1; - -found: - set_label_raw(id, rs->label, 16); - set_label_string(id, rs->label, 16); - set_uuid(id, rs->uuid, UUID_DCE); - - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_REISERFS; - id->type = "reiserfs"; - - return 0; -} - -static int probe_xfs(struct volume_id *id, __u64 off) -{ - struct xfs_super_block { - __u8 magic[4]; - __u32 blocksize; - __u64 dblocks; - __u64 rblocks; - __u32 dummy1[2]; - __u8 uuid[16]; - __u32 dummy2[15]; - __u8 fname[12]; - __u32 dummy3[2]; - __u64 icount; - __u64 ifree; - __u64 fdblocks; - } __attribute__((__packed__)) *xs; - - xs = (struct xfs_super_block *) get_buffer(id, off, 0x200); - if (xs == NULL) - return -1; - - if (strncmp(xs->magic, "XFSB", 4) != 0) - return -1; - - set_label_raw(id, xs->fname, 12); - set_label_string(id, xs->fname, 12); - set_uuid(id, xs->uuid, UUID_DCE); - - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_XFS; - id->type = "xfs"; - - return 0; -} - -#define JFS_SUPERBLOCK_OFFSET 0x8000 -static int probe_jfs(struct volume_id *id, __u64 off) -{ - struct jfs_super_block { - __u8 magic[4]; - __u32 version; - __u64 size; - __u32 bsize; - __u32 dummy1; - __u32 pbsize; - __u32 dummy2[27]; - __u8 uuid[16]; - __u8 label[16]; - __u8 loguuid[16]; - } __attribute__((__packed__)) *js; - - js = (struct jfs_super_block *) - get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200); - if (js == NULL) - return -1; - - if (strncmp(js->magic, "JFS1", 4) != 0) - return -1; - - set_label_raw(id, js->label, 16); - set_label_string(id, js->label, 16); - set_uuid(id, js->uuid, UUID_DCE); - - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_JFS; - id->type = "jfs"; - - return 0; -} - -#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 -static int probe_vfat(struct volume_id *id, __u64 off) -{ - struct vfat_super_block { - __u8 boot_jump[3]; - __u8 sysid[8]; - __u16 sector_size; - __u8 sectors_per_cluster; - __u16 reserved; - __u8 fats; - __u16 dir_entries; - __u16 sectors; - __u8 media; - __u16 fat_length; - __u16 secs_track; - __u16 heads; - __u32 hidden; - __u32 total_sect; - union { - struct fat_super_block { - __u8 unknown[3]; - __u8 serno[4]; - __u8 label[11]; - __u8 magic[8]; - __u8 dummy2[192]; - __u8 pmagic[2]; - } __attribute__((__packed__)) fat; - struct fat32_super_block { - __u32 fat32_length; - __u16 flags; - __u8 version[2]; - __u32 root_cluster; - __u16 insfo_sector; - __u16 backup_boot; - __u16 reserved2[6]; - __u8 unknown[3]; - __u8 serno[4]; - __u8 label[11]; - __u8 magic[8]; - __u8 dummy2[164]; - __u8 pmagic[2]; - } __attribute__((__packed__)) fat32; - } __attribute__((__packed__)) type; - } __attribute__((__packed__)) *vs; - - struct vfat_dir_entry { - __u8 name[11]; - __u8 attr; - __u16 time_creat; - __u16 date_creat; - __u16 time_acc; - __u16 date_acc; - __u16 cluster_high; - __u16 time_write; - __u16 date_write; - __u16 cluster_low; - __u32 size; - } __attribute__((__packed__)) *dir; - - __u16 sector_size; - __u16 dir_entries; - __u32 sect_count; - __u16 reserved; - __u32 fat_size; - __u32 root_cluster; - __u32 dir_size; - __u32 cluster_count; - __u32 fat_length; - __u64 root_start; - __u32 start_data_sect; - __u16 root_dir_entries; - __u8 *buf; - __u32 buf_size; - __u8 *label = NULL; - __u32 next; - int maxloop; - int i; - - vs = (struct vfat_super_block *) get_buffer(id, off, 0x200); - if (vs == NULL) - return -1; - - /* believe only that's fat, don't trust the version - * the cluster_count will tell us - */ - if (strncmp(vs->sysid, "NTFS", 4) == 0) - return -1; - - if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0) - goto valid; - - if (strncmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) - goto valid; - - if (strncmp(vs->type.fat.magic, "FAT16 ", 8) == 0) - goto valid; - - if (strncmp(vs->type.fat.magic, "MSDOS", 5) == 0) - goto valid; - - if (strncmp(vs->type.fat.magic, "FAT12 ", 8) == 0) - goto valid; - - /* - * There are old floppies out there without a magic, so we check - * for well known values and guess if it's a fat volume - */ - - /* boot jump address check */ - if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) && - vs->boot_jump[0] != 0xe9) - return -1; - - /* heads check */ - if (vs->heads == 0) - return -1; - - /* cluster size check*/ - if (vs->sectors_per_cluster == 0 || - (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))) - return -1; - - /* media check */ - if (vs->media < 0xf8 && vs->media != 0xf0) - return -1; - - /* fat count*/ - if (vs->fats != 2) - return -1; - -valid: - /* 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); - if (fat_length == 0) - fat_length = le32_to_cpu(vs->type.fat32.fat32_length); - dbg("fat_length 0x%x", fat_length); - - fat_size = fat_length * vs->fats; - 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); - - if (cluster_count < FAT12_MAX) { - strcpy(id->type_version, "FAT12"); - } else if (cluster_count < FAT16_MAX) { - strcpy(id->type_version, "FAT16"); - } else { - strcpy(id->type_version, "FAT32"); - 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", 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 = get_buffer(id, off + root_start, buf_size); - if (buf == NULL) - goto found; - - dir = (struct vfat_dir_entry*) buf; - - for (i = 0; i < root_dir_entries; 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"); - label = dir[i].name; - break; - } - - dbg("skip dir entry"); - } - - vs = (struct vfat_super_block *) get_buffer(id, off, 0x200); - if (vs == NULL) - return -1; - - if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { - set_label_raw(id, label, 11); - set_label_string(id, label, 11); - } else if (strncmp(vs->type.fat.label, "NO NAME ", 11) != 0) { - set_label_raw(id, vs->type.fat.label, 11); - set_label_string(id, vs->type.fat.label, 11); - } - set_uuid(id, vs->type.fat.serno, UUID_DOS); - goto found; - -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) { - __u32 next_sect_off; - __u64 next_off; - __u64 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", next_off); - - /* get cluster */ - buf = 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); - - for (i = 0; i < count; i++) { - /* end marker */ - if (dir[i].name[0] == 0x00) { - dbg("end of dir"); - goto fat32_label; - } - - /* 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"); - label = dir[i].name; - goto fat32_label; - } - - dbg("skip dir entry"); - } - - /* get FAT entry */ - fat_entry_off = (reserved * sector_size) + (next * sizeof(__u32)); - buf = get_buffer(id, off + fat_entry_off, buf_size); - if (buf == NULL) - goto found; - - /* set next cluster */ - next = le32_to_cpu(*((__u32 *) buf) & 0x0fffffff); - if (next == 0) - break; - } - if (maxloop == 0) - dbg("reached maximum follow count of root cluster chain, give up"); - -fat32_label: - vs = (struct vfat_super_block *) get_buffer(id, off, 0x200); - if (vs == NULL) - return -1; - - if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { - set_label_raw(id, label, 11); - set_label_string(id, label, 11); - } else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) != 0) { - set_label_raw(id, vs->type.fat32.label, 11); - set_label_string(id, vs->type.fat32.label, 11); - } - set_uuid(id, vs->type.fat32.serno, UUID_DOS); - -found: - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_VFAT; - id->type = "vfat"; - - return 0; -} - -#define UDF_VSD_OFFSET 0x8000 -static int probe_udf(struct volume_id *id, __u64 off) -{ - struct volume_descriptor { - struct descriptor_tag { - __u16 id; - __u16 version; - __u8 checksum; - __u8 reserved; - __u16 serial; - __u16 crc; - __u16 crc_len; - __u32 location; - } __attribute__((__packed__)) tag; - union { - struct anchor_descriptor { - __u32 length; - __u32 location; - } __attribute__((__packed__)) anchor; - struct primary_descriptor { - __u32 seq_num; - __u32 desc_num; - struct dstring { - __u8 clen; - __u8 c[31]; - } __attribute__((__packed__)) ident; - } __attribute__((__packed__)) primary; - } __attribute__((__packed__)) type; - } __attribute__((__packed__)) *vd; - - struct volume_structure_descriptor { - __u8 type; - __u8 id[5]; - __u8 version; - } *vsd; - - unsigned int bs; - unsigned int b; - unsigned int type; - unsigned int count; - unsigned int loc; - unsigned int clen; - - vsd = (struct volume_structure_descriptor *) - get_buffer(id, off + UDF_VSD_OFFSET, 0x200); - if (vsd == NULL) - return -1; - - if (strncmp(vsd->id, "NSR02", 5) == 0) - goto blocksize; - if (strncmp(vsd->id, "NSR03", 5) == 0) - goto blocksize; - if (strncmp(vsd->id, "BEA01", 5) == 0) - goto blocksize; - if (strncmp(vsd->id, "BOOT2", 5) == 0) - goto blocksize; - if (strncmp(vsd->id, "CD001", 5) == 0) - goto blocksize; - if (strncmp(vsd->id, "CDW02", 5) == 0) - goto blocksize; - if (strncmp(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 *) - 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 *) - 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 (strncmp(vsd->id, "NSR02", 5) == 0) - goto anchor; - if (strncmp(vsd->id, "NSR03", 5) == 0) - goto anchor; - } - return -1; - -anchor: - /* read anchor volume descriptor */ - vd = (struct volume_descriptor *) - 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 *) - 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: - 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) - set_label_string(id, vd->type.primary.ident.c, 31); - else if (clen == 16) - set_label_unicode16(id, vd->type.primary.ident.c, BE,31); - -found: - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_UDF; - id->type = "udf"; - - return 0; -} - -#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 -static int probe_iso9660(struct volume_id *id, __u64 off) -{ - union iso_super_block { - struct iso_header { - __u8 type; - __u8 id[5]; - __u8 version; - __u8 unused1; - __u8 system_id[32]; - __u8 volume_id[32]; - } __attribute__((__packed__)) iso; - struct hs_header { - __u8 foo[8]; - __u8 type; - __u8 id[4]; - __u8 version; - } __attribute__((__packed__)) hs; - } __attribute__((__packed__)) *is; - - is = (union iso_super_block *) - get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); - if (is == NULL) - return -1; - - if (strncmp(is->iso.id, "CD001", 5) == 0) { - char root_label[VOLUME_ID_LABEL_SIZE+1]; - int vd_offset; - int i; - int found_svd; - - memset(root_label, 0, sizeof(root_label)); - strncpy(root_label, is->iso.volume_id, sizeof(root_label)-1); - - found_svd = 0; - vd_offset = ISO_VD_OFFSET; - for (i = 0; i < ISO_VD_MAX; i++) { - is = (union iso_super_block *) - get_buffer (id, off + vd_offset, 0x200); - if (is == NULL || is->iso.type == ISO_VD_END) - break; - if (is->iso.type == ISO_VD_SUPPLEMENTARY) { - dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset); - set_label_raw(id, is->iso.volume_id, 32); - set_label_unicode16(id, is->iso.volume_id, BE, 32); - found_svd = 1; - break; - } - vd_offset += ISO_SECTOR_SIZE; - } - - if (!found_svd || - (found_svd && !strncmp(root_label, id->label, 16))) - { - set_label_raw(id, root_label, 32); - set_label_string(id, root_label, 32); - } - goto found; - } - if (strncmp(is->hs.id, "CDROM", 5) == 0) - goto found; - return -1; - -found: - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_ISO9660; - id->type = "iso9660"; - - return 0; -} - -#define UFS_MAGIC 0x00011954 -#define UFS2_MAGIC 0x19540119 -#define UFS_MAGIC_FEA 0x00195612 -#define UFS_MAGIC_LFN 0x00095014 - - -static int probe_ufs(struct volume_id *id, __u64 off) -{ - struct ufs_super_block { - __u32 fs_link; - __u32 fs_rlink; - __u32 fs_sblkno; - __u32 fs_cblkno; - __u32 fs_iblkno; - __u32 fs_dblkno; - __u32 fs_cgoffset; - __u32 fs_cgmask; - __u32 fs_time; - __u32 fs_size; - __u32 fs_dsize; - __u32 fs_ncg; - __u32 fs_bsize; - __u32 fs_fsize; - __u32 fs_frag; - __u32 fs_minfree; - __u32 fs_rotdelay; - __u32 fs_rps; - __u32 fs_bmask; - __u32 fs_fmask; - __u32 fs_bshift; - __u32 fs_fshift; - __u32 fs_maxcontig; - __u32 fs_maxbpg; - __u32 fs_fragshift; - __u32 fs_fsbtodb; - __u32 fs_sbsize; - __u32 fs_csmask; - __u32 fs_csshift; - __u32 fs_nindir; - __u32 fs_inopb; - __u32 fs_nspf; - __u32 fs_optim; - __u32 fs_npsect_state; - __u32 fs_interleave; - __u32 fs_trackskew; - __u32 fs_id[2]; - __u32 fs_csaddr; - __u32 fs_cssize; - __u32 fs_cgsize; - __u32 fs_ntrak; - __u32 fs_nsect; - __u32 fs_spc; - __u32 fs_ncyl; - __u32 fs_cpg; - __u32 fs_ipg; - __u32 fs_fpg; - struct ufs_csum { - __u32 cs_ndir; - __u32 cs_nbfree; - __u32 cs_nifree; - __u32 cs_nffree; - } __attribute__((__packed__)) fs_cstotal; - __s8 fs_fmod; - __s8 fs_clean; - __s8 fs_ronly; - __s8 fs_flags; - union { - struct { - __s8 fs_fsmnt[512]; - __u32 fs_cgrotor; - __u32 fs_csp[31]; - __u32 fs_maxcluster; - __u32 fs_cpc; - __u16 fs_opostbl[16][8]; - } __attribute__((__packed__)) fs_u1; - struct { - __s8 fs_fsmnt[468]; - __u8 fs_volname[32]; - __u64 fs_swuid; - __s32 fs_pad; - __u32 fs_cgrotor; - __u32 fs_ocsp[28]; - __u32 fs_contigdirs; - __u32 fs_csp; - __u32 fs_maxcluster; - __u32 fs_active; - __s32 fs_old_cpc; - __s32 fs_maxbsize; - __s64 fs_sparecon64[17]; - __s64 fs_sblockloc; - struct ufs2_csum_total { - __u64 cs_ndir; - __u64 cs_nbfree; - __u64 cs_nifree; - __u64 cs_nffree; - __u64 cs_numclusters; - __u64 cs_spare[3]; - } __attribute__((__packed__)) fs_cstotal; - struct ufs_timeval { - __s32 tv_sec; - __s32 tv_usec; - } __attribute__((__packed__)) fs_time; - __s64 fs_size; - __s64 fs_dsize; - __u64 fs_csaddr; - __s64 fs_pendingblocks; - __s32 fs_pendinginodes; - } __attribute__((__packed__)) fs_u2; - } fs_u11; - union { - struct { - __s32 fs_sparecon[53]; - __s32 fs_reclaim; - __s32 fs_sparecon2[1]; - __s32 fs_state; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; - } __attribute__((__packed__)) fs_sun; - struct { - __s32 fs_sparecon[53]; - __s32 fs_reclaim; - __s32 fs_sparecon2[1]; - __u32 fs_npsect; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; - } __attribute__((__packed__)) fs_sunx86; - struct { - __s32 fs_sparecon[50]; - __s32 fs_contigsumsize; - __s32 fs_maxsymlinklen; - __s32 fs_inodefmt; - __u32 fs_maxfilesize[2]; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; - __s32 fs_state; - } __attribute__((__packed__)) fs_44; - } fs_u2; - __s32 fs_postblformat; - __s32 fs_nrpos; - __s32 fs_postbloff; - __s32 fs_rotbloff; - __u32 fs_magic; - __u8 fs_space[1]; - } __attribute__((__packed__)) *ufs; - - __u32 magic; - int i; - int offsets[] = {0, 8, 64, 256, -1}; - - for (i = 0; offsets[i] >= 0; i++) { - ufs = (struct ufs_super_block *) - 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: - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_UFS; - id->type = "ufs"; - - return 0; -} - -static int probe_mac_partition_map(struct volume_id *id, __u64 off) -{ - struct mac_driver_desc { - __u8 signature[2]; - __u16 block_size; - __u32 block_count; - } __attribute__((__packed__)) *driver; - - struct mac_partition { - __u8 signature[2]; - __u16 res1; - __u32 map_count; - __u32 start_block; - __u32 block_count; - __u8 name[32]; - __u8 type[32]; - } __attribute__((__packed__)) *part; - - const __u8 *buf; - - buf = get_buffer(id, off, 0x200); - if (buf == NULL) - return -1; - - part = (struct mac_partition *) buf; - if ((strncmp(part->signature, "PM", 2) == 0) && - (strncmp(part->type, "Apple_partition_map", 19) == 0)) { - /* linux creates an own subdevice for the map - * just return the type if the drive header is missing */ - id->usage_id = VOLUME_ID_PARTITIONTABLE; - id->type_id = VOLUME_ID_MACPARTMAP; - id->type = "mac_partition_map"; - return 0; - } - - driver = (struct mac_driver_desc *) buf; - if (strncmp(driver->signature, "ER", 2) == 0) { - /* we are on a main device, like a CD - * just try to probe the first partition from the map */ - unsigned int bsize = be16_to_cpu(driver->block_size); - int part_count; - int i; - - /* get first entry of partition table */ - buf = get_buffer(id, off + bsize, 0x200); - if (buf == NULL) - return -1; - - part = (struct mac_partition *) buf; - if (strncmp(part->signature, "PM", 2) != 0) - return -1; - - part_count = be32_to_cpu(part->map_count); - dbg("expecting %d partition entries", part_count); - - if (id->partitions != NULL) - free(id->partitions); - id->partitions = - malloc(part_count * sizeof(struct volume_id_partition)); - if (id->partitions == NULL) - return -1; - memset(id->partitions, 0x00, sizeof(struct volume_id_partition)); - - id->partition_count = part_count; - - for (i = 0; i < part_count; i++) { - __u64 poff; - __u64 plen; - - buf = get_buffer(id, off + ((i+1) * bsize), 0x200); - if (buf == NULL) - return -1; - - part = (struct mac_partition *) buf; - if (strncmp(part->signature, "PM", 2) != 0) - return -1; - - poff = be32_to_cpu(part->start_block) * bsize; - plen = be32_to_cpu(part->block_count) * bsize; - dbg("found '%s' partition entry at 0x%llx, len 0x%llx", - part->type, poff, plen); - - id->partitions[i].off = poff; - id->partitions[i].len = plen; - - if (strncmp(part->type, "Apple_Free", 10) == 0) { - id->partitions[i].usage_id = VOLUME_ID_UNUSED; - } else if (strncmp(part->type, "Apple_partition_map", 19) == 0) { - id->partitions[i].usage_id = VOLUME_ID_PARTITIONTABLE; - id->partitions[i].type_id = VOLUME_ID_MACPARTMAP; - } else { - id->partitions[i].usage_id = VOLUME_ID_UNPROBED; - } - } - id->usage_id = VOLUME_ID_PARTITIONTABLE; - id->type_id = VOLUME_ID_MACPARTMAP; - id->type = "mac_partition_map"; - return 0; - } - - return -1; -} - -#define HFS_SUPERBLOCK_OFFSET 0x400 -#define HFS_NODE_LEAF 0xff -#define HFSPLUS_POR_CNID 1 -#define HFSPLUS_EXTENT_COUNT 8 -static int probe_hfs_hfsplus(struct volume_id *id, __u64 off) -{ - struct hfs_finder_info{ - __u32 boot_folder; - __u32 start_app; - __u32 open_folder; - __u32 os9_folder; - __u32 reserved; - __u32 osx_folder; - __u8 id[8]; - } __attribute__((__packed__)); - - struct hfs_mdb { - __u8 signature[2]; - __u32 cr_date; - __u32 ls_Mod; - __u16 atrb; - __u16 nm_fls; - __u16 vbm_st; - __u16 alloc_ptr; - __u16 nm_al_blks; - __u32 al_blk_size; - __u32 clp_size; - __u16 al_bl_st; - __u32 nxt_cnid; - __u16 free_bks; - __u8 label_len; - __u8 label[27]; - __u32 vol_bkup; - __u16 vol_seq_num; - __u32 wr_cnt; - __u32 xt_clump_size; - __u32 ct_clump_size; - __u16 num_root_dirs; - __u32 file_count; - __u32 dir_count; - struct hfs_finder_info finder_info; - __u8 embed_sig[2]; - __u16 embed_startblock; - __u16 embed_blockcount; - } __attribute__((__packed__)) *hfs; - - struct hfsplus_bnode_descriptor { - __u32 next; - __u32 prev; - __u8 type; - __u8 height; - __u16 num_recs; - __u16 reserved; - } __attribute__((__packed__)); - - struct hfsplus_bheader_record { - __u16 depth; - __u32 root; - __u32 leaf_count; - __u32 leaf_head; - __u32 leaf_tail; - __u16 node_size; - } __attribute__((__packed__)); - - struct hfsplus_catalog_key { - __u16 key_len; - __u32 parent_id; - __u16 unicode_len; - __u8 unicode[255 * 2]; - } __attribute__((__packed__)); - - struct hfsplus_extent { - __u32 start_block; - __u32 block_count; - } __attribute__((__packed__)); - - struct hfsplus_fork { - __u64 total_size; - __u32 clump_size; - __u32 total_blocks; - struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; - } __attribute__((__packed__)); - - struct hfsplus_vol_header { - __u8 signature[2]; - __u16 version; - __u32 attributes; - __u32 last_mount_vers; - __u32 reserved; - __u32 create_date; - __u32 modify_date; - __u32 backup_date; - __u32 checked_date; - __u32 file_count; - __u32 folder_count; - __u32 blocksize; - __u32 total_blocks; - __u32 free_blocks; - __u32 next_alloc; - __u32 rsrc_clump_sz; - __u32 data_clump_sz; - __u32 next_cnid; - __u32 write_count; - __u64 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; - } __attribute__((__packed__)) *hfsplus; - - 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; - __u64 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 __u8 *buf; - - buf = get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); - if (buf == NULL) - return -1; - - hfs = (struct hfs_mdb *) buf; - if (strncmp(hfs->signature, "BD", 2) != 0) - goto checkplus; - - /* it may be just a hfs wrapper for hfs+ */ - if (strncmp(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", off); - - buf = get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); - if (buf == NULL) - return -1; - goto checkplus; - } - - if (hfs->label_len > 0 && hfs->label_len < 28) { - set_label_raw(id, hfs->label, hfs->label_len); - set_label_string(id, hfs->label, hfs->label_len) ; - } - - set_uuid(id, hfs->finder_info.id, UUID_HFS); - - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_HFS; - id->type = "hfs"; - - return 0; - -checkplus: - hfsplus = (struct hfsplus_vol_header *) buf; - if (strncmp(hfsplus->signature, "H+", 2) == 0) - goto hfsplus; - if (strncmp(hfsplus->signature, "HX", 2) == 0) - goto hfsplus; - return -1; - -hfsplus: - set_uuid(id, hfsplus->finder_info.id, UUID_HFS); - - 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 = 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 = 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); - set_label_raw(id, key->unicode, label_len); - set_label_unicode16(id, key->unicode, BE, label_len); - -found: - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_HFSPLUS; - id->type = "hfsplus"; - - return 0; -} - -#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 -static int probe_ntfs(struct volume_id *id, __u64 off) -{ - struct ntfs_super_block { - __u8 jump[3]; - __u8 oem_id[8]; - __u16 bytes_per_sector; - __u8 sectors_per_cluster; - __u16 reserved_sectors; - __u8 fats; - __u16 root_entries; - __u16 sectors; - __u8 media_type; - __u16 sectors_per_fat; - __u16 sectors_per_track; - __u16 heads; - __u32 hidden_sectors; - __u32 large_sectors; - __u16 unused[2]; - __u64 number_of_sectors; - __u64 mft_cluster_location; - __u64 mft_mirror_cluster_location; - __s8 cluster_per_mft_record; - __u8 reserved1[3]; - __s8 cluster_per_index_record; - __u8 reserved2[3]; - __u8 volume_serial[8]; - __u16 checksum; - } __attribute__((__packed__)) *ns; - - struct master_file_table_record { - __u8 magic[4]; - __u16 usa_ofs; - __u16 usa_count; - __u64 lsn; - __u16 sequence_number; - __u16 link_count; - __u16 attrs_offset; - __u16 flags; - __u32 bytes_in_use; - __u32 bytes_allocated; - } __attribute__((__packed__)) *mftr; - - struct file_attribute { - __u32 type; - __u32 len; - __u8 non_resident; - __u8 name_len; - __u16 name_offset; - __u16 flags; - __u16 instance; - __u32 value_len; - __u16 value_offset; - } __attribute__((__packed__)) *attr; - - struct volume_info { - __u64 reserved; - __u8 major_ver; - __u8 minor_ver; - } __attribute__((__packed__)) *info; - - unsigned int sector_size; - unsigned int cluster_size; - __u64 mft_cluster; - __u64 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 __u8 *buf; - const __u8 *val; - - ns = (struct ntfs_super_block *) get_buffer(id, off, 0x200); - if (ns == NULL) - return -1; - - if (strncmp(ns->oem_id, "NTFS", 4) != 0) - return -1; - - set_uuid(id, ns->volume_serial, UUID_NTFS); - - 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 %lli", mft_cluster); - dbg("mftoffset 0x%llx", mft_off); - dbg("cluster per mft_record %i", ns->cluster_per_mft_record); - dbg("mft record size %i", mft_record_size); - - buf = 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 (strncmp(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*) (((__u8 *) attr) + val_off); - snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-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 = ((__u8 *) attr) + val_off; - set_label_raw(id, val, val_len); - set_label_unicode16(id, val, LE, val_len); - } - } - -found: - id->usage_id = VOLUME_ID_FILESYSTEM; - id->type_id = VOLUME_ID_NTFS; - id->type = "ntfs"; - - return 0; -} - -#define LARGEST_PAGESIZE 0x4000 -static int probe_swap(struct volume_id *id, __u64 off) -{ - struct swap_header_v1_2 { - __u8 bootbits[1024]; - __u32 version; - __u32 last_page; - __u32 nr_badpages; - __u8 uuid[16]; - __u8 volume_name[16]; - } __attribute__((__packed__)) *sw; - - const __u8 *buf; - unsigned int page; - - /* the swap signature is at the end of the PAGE_SIZE */ - for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { - buf = get_buffer(id, off + page-10, 10); - if (buf == NULL) - return -1; - - if (strncmp(buf, "SWAP-SPACE", 10) == 0) { - strcpy(id->type_version, "1"); - goto found; - } - - if (strncmp(buf, "SWAPSPACE2", 10) == 0) { - sw = (struct swap_header_v1_2 *) get_buffer(id, off, sizeof(struct swap_header_v1_2)); - if (sw == NULL) - return -1; - strcpy(id->type_version, "2"); - set_label_raw(id, sw->volume_name, 16); - set_label_string(id, sw->volume_name, 16); - set_uuid(id, sw->uuid, UUID_DCE); - goto found; - } - } - return -1; - -found: - id->usage_id = VOLUME_ID_OTHER; - id->type_id = VOLUME_ID_SWAP; - id->type = "swap"; - - return 0; -} - -/* probe volume for filesystem type and try to read label+uuid */ -int volume_id_probe(struct volume_id *id, - enum volume_id_type type, - unsigned long long off, - unsigned long long size) -{ - int rc; - - dbg("called with size=0x%llx", size); - - if (id == NULL) - return -EINVAL; - - switch (type) { - case VOLUME_ID_MSDOSPARTTABLE: - rc = probe_msdos_part_table(id, off); - break; - case VOLUME_ID_EXT3: - case VOLUME_ID_EXT2: - rc = probe_ext(id, off); - break; - case VOLUME_ID_REISERFS: - rc = probe_reiserfs(id, off); - break; - case VOLUME_ID_XFS: - rc = probe_xfs(id, off); - break; - case VOLUME_ID_JFS: - rc = probe_jfs(id, off); - break; - case VOLUME_ID_VFAT: - rc = probe_vfat(id, off); - break; - case VOLUME_ID_UDF: - rc = probe_udf(id, off); - break; - case VOLUME_ID_ISO9660: - rc = probe_iso9660(id, off); - break; - case VOLUME_ID_MACPARTMAP: - rc = probe_mac_partition_map(id, off); - break; - case VOLUME_ID_HFS: - case VOLUME_ID_HFSPLUS: - rc = probe_hfs_hfsplus(id, off); - break; - case VOLUME_ID_UFS: - rc = probe_ufs(id, off); - break; - case VOLUME_ID_NTFS: - rc = probe_ntfs(id, off); - break; - case VOLUME_ID_SWAP: - rc = probe_swap(id, off); - break; - case VOLUME_ID_LINUX_RAID: - rc = probe_linux_raid(id, off, size); - break; - case VOLUME_ID_LVM1: - rc = probe_lvm1(id, off); - break; - case VOLUME_ID_LVM2: - rc = probe_lvm2(id, off); - break; - case VOLUME_ID_HPTRAID: - rc = probe_highpoint_ataraid(id, off); - break; - case VOLUME_ID_ALL: - default: - /* probe for raid first, cause fs probes may be successful on raid members */ - rc = probe_linux_raid(id, off, size); - if (rc == 0) - break; - rc = probe_lvm1(id, off); - if (rc == 0) - break; - rc = probe_lvm2(id, off); - if (rc == 0) - break; - rc = probe_highpoint_ataraid(id, off); - if (rc == 0) - break; - - /* signature in the first block, only small buffer needed */ - rc = probe_vfat(id, off); - if (rc == 0) - break; - rc = probe_mac_partition_map(id, off); - if (rc == 0) - break; - rc = probe_xfs(id, off); - if (rc == 0) - break; - - /* fill buffer with maximum */ - get_buffer(id, 0, SB_BUFFER_SIZE); - - rc = probe_swap(id, off); - if (rc == 0) - break; - rc = probe_ext(id, off); - if (rc == 0) - break; - rc = probe_reiserfs(id, off); - if (rc == 0) - break; - rc = probe_jfs(id, off); - if (rc == 0) - break; - rc = probe_udf(id, off); - if (rc == 0) - break; - rc = probe_iso9660(id, off); - if (rc == 0) - break; - rc = probe_hfs_hfsplus(id, off); - if (rc == 0) - break; - rc = probe_ufs(id, off); - if (rc == 0) - break; - rc = probe_ntfs(id, off); - if (rc == 0) - break; - - rc = -1; - } - - /* If the filestystem in recognized, we free the allocated buffers, - otherwise they will stay in place for the possible next probe call */ - if (rc == 0) - free_buffer(id); - - return rc; -} - -/* open volume by already open file descriptor */ -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; -} - -/* open volume by device node */ -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; -} - -/* open volume by major/minor */ -struct volume_id *volume_id_open_dev_t(dev_t devt) -{ - struct volume_id *id; - __u8 tmp_node[VOLUME_ID_PATH_MAX]; - - snprintf(tmp_node, VOLUME_ID_PATH_MAX, - "/tmp/volume-%u-%u-%u", getpid(), major(devt), minor(devt)); - tmp_node[VOLUME_ID_PATH_MAX] = '\0'; - - /* create tempory node to open the block device */ - unlink(tmp_node); - if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0) - return NULL; - - id = volume_id_open_node(tmp_node); - - unlink(tmp_node); - - return id; -} - -/* free allocated volume info */ -void volume_id_close(struct volume_id *id) -{ - if (id == NULL) - return; - - if (id->fd_close != 0) - close(id->fd); - - free_buffer(id); - - if (id->partitions != NULL) - free(id->partitions); - - free(id); -} diff --git a/extras/volume_id/dasdlabel.c b/extras/volume_id/volume_id/dasd/dasd.c similarity index 88% rename from extras/volume_id/dasdlabel.c rename to extras/volume_id/volume_id/dasd/dasd.c index cbbe88179d..6f045fe326 100644 --- a/extras/volume_id/dasdlabel.c +++ b/extras/volume_id/volume_id/dasd/dasd.c @@ -18,6 +18,13 @@ * */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif #include #include @@ -25,8 +32,11 @@ #include #include #include +#include -#include "dasdlabel.h" +#include "../volume_id.h" +#include "../util.h" +#include "dasd.h" static unsigned char EBCtoASC[256] = { @@ -100,7 +110,7 @@ static unsigned char EBCtoASC[256] = 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 }; -static void vtoc_ebcdic_dec (unsigned char *source, unsigned char *target, int l) +static void vtoc_ebcdic_dec (const unsigned char *source, unsigned char *target, int l) { int i; @@ -150,29 +160,35 @@ typedef struct dasd_information_t { #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) #define BLKSSZGET _IO(0x12,104) -int probe_ibm_partition(int fd, char *out) +int probe_ibm_partition(struct volume_id *id) { int blocksize; dasd_information_t info; - char name[7] = {0,}; - unsigned char data[16]; + __u8 *data; + __u8 *label_raw; + unsigned char name[7]; - if (ioctl(fd, BIODASDINFO, (unsigned long)&info) != 0) + if (ioctl(id->fd, BIODASDINFO, &info) != 0) return -1; - if (ioctl(fd, BLKSSZGET, (unsigned long)&blocksize)) + if (ioctl(id->fd, BLKSSZGET, &blocksize) != 0) return -1; - lseek(fd, info.label_block * blocksize, SEEK_SET); - if (read(fd, &data, 16) != 16) + data = volume_id_get_buffer(id, info.label_block * blocksize, 16); + if (data == NULL) return -1; if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) - strncpy(name, data + 8, 6); + label_raw = &data[8]; else - strncpy(name, data + 4, 6); + label_raw = &data[4]; - vtoc_ebcdic_dec(name, out, 6); + name[6] = '\0'; + volume_id_set_usage(id, VOLUME_ID_DISKLABEL); + id->type = "dasd"; + volume_id_set_label_raw(id, label_raw, 6); + vtoc_ebcdic_dec(label_raw, name, 6); + volume_id_set_label_string(id, name, 6); return 0; } diff --git a/extras/volume_id/dasdlabel.h b/extras/volume_id/volume_id/dasd/dasd.h similarity index 87% rename from extras/volume_id/dasdlabel.h rename to extras/volume_id/volume_id/dasd/dasd.h index 1501d3ff89..eba73f1af0 100644 --- a/extras/volume_id/dasdlabel.h +++ b/extras/volume_id/volume_id/dasd/dasd.h @@ -18,9 +18,9 @@ * */ -#ifndef _DASDLABEL_H_ -#define _DASDLABEL_H_ +#ifndef _VOLUME_ID_DASDLABEL_ +#define _VOLUME_ID_DASDLABEL_ -extern int probe_ibm_partition(int fd, char *out); +extern int probe_ibm_partition(struct volume_id *id); #endif diff --git a/extras/volume_id/volume_id/ext/ext.c b/extras/volume_id/volume_id/ext/ext.c new file mode 100644 index 0000000000..50ffa85372 --- /dev/null +++ b/extras/volume_id/volume_id/ext/ext.c @@ -0,0 +1,86 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../util.h" +#include "../logging.h" +#include "ext.h" + +#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 +#define EXT_SUPERBLOCK_OFFSET 0x400 + +int volume_id_probe_ext(struct volume_id *id, __u64 off) +{ + struct ext2_super_block { + __u32 inodes_count; + __u32 blocks_count; + __u32 r_blocks_count; + __u32 free_blocks_count; + __u32 free_inodes_count; + __u32 first_data_block; + __u32 log_block_size; + __u32 dummy3[7]; + __u8 magic[2]; + __u16 state; + __u32 dummy5[8]; + __u32 feature_compat; + __u32 feature_incompat; + __u32 feature_ro_compat; + __u8 uuid[16]; + __u8 volume_name[16]; + } __attribute__((__packed__)) *es; + + es = (struct ext2_super_block *) volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); + if (es == NULL) + return -1; + + if (es->magic[0] != 0123 || + es->magic[1] != 0357) + return -1; + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + volume_id_set_label_raw(id, es->volume_name, 16); + volume_id_set_label_string(id, es->volume_name, 16); + volume_id_set_uuid(id, es->uuid, UUID_DCE); + + if ((le32_to_cpu(es->feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) + id->type = "ext3"; + else + id->type = "ext2"; + + return 0; +} diff --git a/extras/volume_id/volume_id/ext/ext.h b/extras/volume_id/volume_id/ext/ext.h new file mode 100644 index 0000000000..6b9b85876b --- /dev/null +++ b/extras/volume_id/volume_id/ext/ext.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_EXT_ +#define _VOLUME_ID_EXT_ + +extern int volume_id_probe_ext(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/fat/fat.c b/extras/volume_id/volume_id/fat/fat.c new file mode 100644 index 0000000000..e6f01076ad --- /dev/null +++ b/extras/volume_id/volume_id/fat/fat.c @@ -0,0 +1,350 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "fat.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 + +struct vfat_super_block { + __u8 boot_jump[3]; + __u8 sysid[8]; + __u16 sector_size; + __u8 sectors_per_cluster; + __u16 reserved; + __u8 fats; + __u16 dir_entries; + __u16 sectors; + __u8 media; + __u16 fat_length; + __u16 secs_track; + __u16 heads; + __u32 hidden; + __u32 total_sect; + union { + struct fat_super_block { + __u8 unknown[3]; + __u8 serno[4]; + __u8 label[11]; + __u8 magic[8]; + __u8 dummy2[192]; + __u8 pmagic[2]; + } __attribute__((__packed__)) fat; + struct fat32_super_block { + __u32 fat32_length; + __u16 flags; + __u8 version[2]; + __u32 root_cluster; + __u16 insfo_sector; + __u16 backup_boot; + __u16 reserved2[6]; + __u8 unknown[3]; + __u8 serno[4]; + __u8 label[11]; + __u8 magic[8]; + __u8 dummy2[164]; + __u8 pmagic[2]; + } __attribute__((__packed__)) fat32; + } __attribute__((__packed__)) type; +} __attribute__((__packed__)); + +struct vfat_dir_entry { + __u8 name[11]; + __u8 attr; + __u16 time_creat; + __u16 date_creat; + __u16 time_acc; + __u16 date_acc; + __u16 cluster_high; + __u16 time_write; + __u16 date_write; + __u16 cluster_low; + __u32 size; +} __attribute__((__packed__)); + +static char *get_attr_volume_id(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 dir[i].name; + } + + dbg("skip dir entry"); + } + + return NULL; +} + +int volume_id_probe_vfat(struct volume_id *id, __u64 off) +{ + struct vfat_super_block *vs; + struct vfat_dir_entry *dir; + __u16 sector_size; + __u16 dir_entries; + __u32 sect_count; + __u16 reserved; + __u32 fat_size; + __u32 root_cluster; + __u32 dir_size; + __u32 cluster_count; + __u32 fat_length; + __u64 root_start; + __u32 start_data_sect; + __u16 root_dir_entries; + __u8 *buf; + __u32 buf_size; + __u8 *label = NULL; + __u32 next; + int maxloop; + + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + + /* believe only that's fat, don't trust the version + * the cluster_count will tell us + */ + if (strncmp(vs->sysid, "NTFS", 4) == 0) + return -1; + + if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0) + goto valid; + + if (strncmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) + goto valid; + + if (strncmp(vs->type.fat.magic, "FAT16 ", 8) == 0) + goto valid; + + if (strncmp(vs->type.fat.magic, "MSDOS", 5) == 0) + goto valid; + + if (strncmp(vs->type.fat.magic, "FAT12 ", 8) == 0) + goto valid; + + /* + * There are old floppies out there without a magic, so we check + * for well known values and guess if it's a fat volume + */ + + /* boot jump address check */ + if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) && + vs->boot_jump[0] != 0xe9) + return -1; + + /* heads check */ + if (vs->heads == 0) + return -1; + + /* cluster size check*/ + if (vs->sectors_per_cluster == 0 || + (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))) + return -1; + + /* media check */ + if (vs->media < 0xf8 && vs->media != 0xf0) + return -1; + + /* fat count*/ + if (vs->fats != 2) + return -1; + +valid: + /* 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); + if (fat_length == 0) + fat_length = le32_to_cpu(vs->type.fat32.fat32_length); + dbg("fat_length 0x%x", fat_length); + + fat_size = fat_length * vs->fats; + 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); + + if (cluster_count < FAT12_MAX) { + strcpy(id->type_version, "FAT12"); + } else if (cluster_count < FAT16_MAX) { + strcpy(id->type_version, "FAT16"); + } else { + strcpy(id->type_version, "FAT32"); + 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", 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; + + label = get_attr_volume_id(dir, root_dir_entries); + + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); + if (vs == NULL) + return -1; + + if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, label, 11); + volume_id_set_label_string(id, label, 11); + } else if (strncmp(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, UUID_DOS); + goto found; + +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) { + __u32 next_sect_off; + __u64 next_off; + __u64 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", 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); + + label = get_attr_volume_id(dir, count); + if (label) + break; + + /* get FAT entry */ + fat_entry_off = (reserved * sector_size) + (next * sizeof(__u32)); + buf = volume_id_get_buffer(id, off + fat_entry_off, buf_size); + if (buf == NULL) + goto found; + + /* set next cluster */ + next = le32_to_cpu(*((__u32 *) buf) & 0x0fffffff); + if (next == 0) + 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 (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { + volume_id_set_label_raw(id, label, 11); + volume_id_set_label_string(id, label, 11); + } else if (strncmp(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, UUID_DOS); + +found: + volume_id_set_usage(id, VOLUME_ID_DISKLABEL); + id->type = "vfat"; + + return 0; +} diff --git a/extras/volume_id/volume_id/fat/fat.h b/extras/volume_id/volume_id/fat/fat.h new file mode 100644 index 0000000000..51ad94df85 --- /dev/null +++ b/extras/volume_id/volume_id/fat/fat.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_FAT_ +#define _VOLUME_ID_FAT_ + +extern int volume_id_probe_vfat(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/hfs/hfs.c b/extras/volume_id/volume_id/hfs/hfs.c new file mode 100644 index 0000000000..638aabadf2 --- /dev/null +++ b/extras/volume_id/volume_id/hfs/hfs.c @@ -0,0 +1,308 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "hfs.h" + +#define HFS_SUPERBLOCK_OFFSET 0x400 +#define HFS_NODE_LEAF 0xff +#define HFSPLUS_POR_CNID 1 +#define HFSPLUS_EXTENT_COUNT 8 + +int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) +{ + struct hfs_finder_info{ + __u32 boot_folder; + __u32 start_app; + __u32 open_folder; + __u32 os9_folder; + __u32 reserved; + __u32 osx_folder; + __u8 id[8]; + } __attribute__((__packed__)); + + struct hfs_mdb { + __u8 signature[2]; + __u32 cr_date; + __u32 ls_Mod; + __u16 atrb; + __u16 nm_fls; + __u16 vbm_st; + __u16 alloc_ptr; + __u16 nm_al_blks; + __u32 al_blk_size; + __u32 clp_size; + __u16 al_bl_st; + __u32 nxt_cnid; + __u16 free_bks; + __u8 label_len; + __u8 label[27]; + __u32 vol_bkup; + __u16 vol_seq_num; + __u32 wr_cnt; + __u32 xt_clump_size; + __u32 ct_clump_size; + __u16 num_root_dirs; + __u32 file_count; + __u32 dir_count; + struct hfs_finder_info finder_info; + __u8 embed_sig[2]; + __u16 embed_startblock; + __u16 embed_blockcount; + } __attribute__((__packed__)) *hfs; + + struct hfsplus_bnode_descriptor { + __u32 next; + __u32 prev; + __u8 type; + __u8 height; + __u16 num_recs; + __u16 reserved; + } __attribute__((__packed__)); + + struct hfsplus_bheader_record { + __u16 depth; + __u32 root; + __u32 leaf_count; + __u32 leaf_head; + __u32 leaf_tail; + __u16 node_size; + } __attribute__((__packed__)); + + struct hfsplus_catalog_key { + __u16 key_len; + __u32 parent_id; + __u16 unicode_len; + __u8 unicode[255 * 2]; + } __attribute__((__packed__)); + + struct hfsplus_extent { + __u32 start_block; + __u32 block_count; + } __attribute__((__packed__)); + + struct hfsplus_fork { + __u64 total_size; + __u32 clump_size; + __u32 total_blocks; + struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; + } __attribute__((__packed__)); + + struct hfsplus_vol_header { + __u8 signature[2]; + __u16 version; + __u32 attributes; + __u32 last_mount_vers; + __u32 reserved; + __u32 create_date; + __u32 modify_date; + __u32 backup_date; + __u32 checked_date; + __u32 file_count; + __u32 folder_count; + __u32 blocksize; + __u32 total_blocks; + __u32 free_blocks; + __u32 next_alloc; + __u32 rsrc_clump_sz; + __u32 data_clump_sz; + __u32 next_cnid; + __u32 write_count; + __u64 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; + } __attribute__((__packed__)) *hfsplus; + + 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; + __u64 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 __u8 *buf; + + buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) + return -1; + + hfs = (struct hfs_mdb *) buf; + if (strncmp(hfs->signature, "BD", 2) != 0) + goto checkplus; + + /* it may be just a hfs wrapper for hfs+ */ + if (strncmp(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", 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) ; + } + + volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "hfs"; + + return 0; + +checkplus: + hfsplus = (struct hfsplus_vol_header *) buf; + if (strncmp(hfsplus->signature, "H+", 2) == 0) + goto hfsplus; + if (strncmp(hfsplus->signature, "HX", 2) == 0) + goto hfsplus; + return -1; + +hfsplus: + volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS); + + 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/extras/volume_id/volume_id/hfs/hfs.h b/extras/volume_id/volume_id/hfs/hfs.h new file mode 100644 index 0000000000..b23ccd30c8 --- /dev/null +++ b/extras/volume_id/volume_id/hfs/hfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_HFS_ +#define _VOLUME_ID_HFS_ + +extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/highpoint/highpoint.c b/extras/volume_id/volume_id/highpoint/highpoint.c new file mode 100644 index 0000000000..3236d6b2fd --- /dev/null +++ b/extras/volume_id/volume_id/highpoint/highpoint.c @@ -0,0 +1,70 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "highpoint.h" + +#define HPT37X_CONFIG_OFF 0x1200 +#define HPT37X_MAGIC_OK 0x5a7816f0 +#define HPT37X_MAGIC_BAD 0x5a7816fd + +int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off) +{ + struct hpt37x { + __u8 filler1[32]; + __u32 magic; + __u32 magic_0; + __u32 magic_1; + } __attribute__((packed)) *hpt; + + const __u8 *buf; + + buf = volume_id_get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); + if (buf == NULL) + return -1; + + hpt = (struct hpt37x *) buf; + + if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD) + return -1; + + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "hpt_ataraid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/highpoint/highpoint.h b/extras/volume_id/volume_id/highpoint/highpoint.h new file mode 100644 index 0000000000..5a5614afef --- /dev/null +++ b/extras/volume_id/volume_id/highpoint/highpoint.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_HIGHPOINT_ +#define _VOLUME_ID_HIGHPOINT_ + +extern int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/iso9660/iso9660.c b/extras/volume_id/volume_id/iso9660/iso9660.c new file mode 100644 index 0000000000..6af9e8befc --- /dev/null +++ b/extras/volume_id/volume_id/iso9660/iso9660.c @@ -0,0 +1,115 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "iso9660.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 + +int volume_id_probe_iso9660(struct volume_id *id, __u64 off) +{ + union iso_super_block { + struct iso_header { + __u8 type; + __u8 id[5]; + __u8 version; + __u8 unused1; + __u8 system_id[32]; + __u8 volume_id[32]; + } __attribute__((__packed__)) iso; + struct hs_header { + __u8 foo[8]; + __u8 type; + __u8 id[4]; + __u8 version; + } __attribute__((__packed__)) hs; + } __attribute__((__packed__)) *is; + + is = (union iso_super_block *) volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); + if (is == NULL) + return -1; + + if (strncmp(is->iso.id, "CD001", 5) == 0) { + char root_label[VOLUME_ID_LABEL_SIZE+1]; + int vd_offset; + int i; + int found_svd; + + memset(root_label, 0, sizeof(root_label)); + strncpy(root_label, is->iso.volume_id, sizeof(root_label)-1); + + found_svd = 0; + vd_offset = ISO_VD_OFFSET; + for (i = 0; i < ISO_VD_MAX; i++) { + is = (union iso_super_block *) volume_id_get_buffer(id, off + vd_offset, 0x200); + if (is == NULL || is->iso.type == ISO_VD_END) + break; + if (is->iso.type == ISO_VD_SUPPLEMENTARY) { + dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset); + volume_id_set_label_raw(id, is->iso.volume_id, 32); + volume_id_set_label_unicode16(id, is->iso.volume_id, BE, 32); + found_svd = 1; + break; + } + vd_offset += ISO_SECTOR_SIZE; + } + + if (!found_svd || + (found_svd && !strncmp(root_label, id->label, 16))) + { + volume_id_set_label_raw(id, root_label, 32); + volume_id_set_label_string(id, root_label, 32); + } + goto found; + } + if (strncmp(is->hs.id, "CDROM", 5) == 0) + goto found; + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "iso9660"; + + return 0; +} diff --git a/extras/volume_id/volume_id/iso9660/iso9660.h b/extras/volume_id/volume_id/iso9660/iso9660.h new file mode 100644 index 0000000000..c187e25f94 --- /dev/null +++ b/extras/volume_id/volume_id/iso9660/iso9660.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_ISO9660_ +#define _VOLUME_ID_ISO9660_ + +extern int volume_id_probe_iso9660(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/jfs/jfs.c b/extras/volume_id/volume_id/jfs/jfs.c new file mode 100644 index 0000000000..3e7e9d6aea --- /dev/null +++ b/extras/volume_id/volume_id/jfs/jfs.c @@ -0,0 +1,74 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "jfs.h" + +#define JFS_SUPERBLOCK_OFFSET 0x8000 + +int volume_id_probe_jfs(struct volume_id *id, __u64 off) +{ + struct jfs_super_block { + __u8 magic[4]; + __u32 version; + __u64 size; + __u32 bsize; + __u32 dummy1; + __u32 pbsize; + __u32 dummy2[27]; + __u8 uuid[16]; + __u8 label[16]; + __u8 loguuid[16]; + } __attribute__((__packed__)) *js; + + js = (struct jfs_super_block *) volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200); + if (js == NULL) + return -1; + + if (strncmp(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, UUID_DCE); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "jfs"; + + return 0; +} diff --git a/extras/volume_id/volume_id/jfs/jfs.h b/extras/volume_id/volume_id/jfs/jfs.h new file mode 100644 index 0000000000..28c48ffe53 --- /dev/null +++ b/extras/volume_id/volume_id/jfs/jfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_JFS_ +#define _VOLUME_ID_JFS_ + +extern int volume_id_probe_jfs(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/linux_raid/linux_raid.c b/extras/volume_id/volume_id/linux_raid/linux_raid.c new file mode 100644 index 0000000000..b55c6ca6e8 --- /dev/null +++ b/extras/volume_id/volume_id/linux_raid/linux_raid.c @@ -0,0 +1,97 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "linux_raid.h" + +#define MD_RESERVED_BYTES 0x10000 +#define MD_MAGIC 0xa92b4efc + +int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) +{ + struct mdp_super_block { + __u32 md_magic; + __u32 major_version; + __u32 minor_version; + __u32 patch_version; + __u32 gvalid_words; + __u32 set_uuid0; + __u32 ctime; + __u32 level; + __u32 size; + __u32 nr_disks; + __u32 raid_disks; + __u32 md_minor; + __u32 not_persistent; + __u32 set_uuid1; + __u32 set_uuid2; + __u32 set_uuid3; + } __attribute__((packed)) *mdp; + + const __u8 *buf; + __u64 sboff; + __u8 uuid[16]; + + if (size < 0x10000) + return -1; + + sboff = (size & ~(MD_RESERVED_BYTES - 1)) - MD_RESERVED_BYTES; + buf = volume_id_get_buffer(id, off + sboff, 0x800); + if (buf == NULL) + return -1; + + mdp = (struct mdp_super_block *) buf; + + if (le32_to_cpu(mdp->md_magic) != MD_MAGIC) + return -1; + + memcpy(uuid, &mdp->set_uuid0, 4); + memcpy(&uuid[4], &mdp->set_uuid1, 12); + volume_id_set_uuid(id, uuid, UUID_DCE); + + snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u", + le32_to_cpu(mdp->major_version), + le32_to_cpu(mdp->minor_version), + le32_to_cpu(mdp->patch_version)); + + dbg("found raid signature"); + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "linux_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/linux_raid/linux_raid.h b/extras/volume_id/volume_id/linux_raid/linux_raid.h new file mode 100644 index 0000000000..0aaaaa6ade --- /dev/null +++ b/extras/volume_id/volume_id/linux_raid/linux_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_LINUX_RAID_ +#define _VOLUME_ID_LINUX_RAID_ + +extern int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/linux_swap/linux_swap.c b/extras/volume_id/volume_id/linux_swap/linux_swap.c new file mode 100644 index 0000000000..7ca4976078 --- /dev/null +++ b/extras/volume_id/volume_id/linux_swap/linux_swap.c @@ -0,0 +1,87 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "linux_swap.h" + +#define LARGEST_PAGESIZE 0x4000 + +int volume_id_probe_linux_swap(struct volume_id *id, __u64 off) +{ + struct swap_header_v1_2 { + __u8 bootbits[1024]; + __u32 version; + __u32 last_page; + __u32 nr_badpages; + __u8 uuid[16]; + __u8 volume_name[16]; + } __attribute__((__packed__)) *sw; + + const __u8 *buf; + unsigned int page; + + /* 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 (strncmp(buf, "SWAP-SPACE", 10) == 0) { + strcpy(id->type_version, "1"); + goto found; + } + + if (strncmp(buf, "SWAPSPACE2", 10) == 0) { + sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); + if (sw == NULL) + return -1; + strcpy(id->type_version, "2"); + 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, UUID_DCE); + goto found; + } + } + return -1; + +found: + volume_id_set_usage(id, VOLUME_ID_OTHER); + id->type = "swap"; + + return 0; +} diff --git a/extras/volume_id/volume_id/linux_swap/linux_swap.h b/extras/volume_id/volume_id/linux_swap/linux_swap.h new file mode 100644 index 0000000000..5de0f93849 --- /dev/null +++ b/extras/volume_id/volume_id/linux_swap/linux_swap.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_LINUX_SWAP_ +#define _VOLUME_ID_LINUX_SWAP_ + +extern int volume_id_probe_linux_swap(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id_logging.h b/extras/volume_id/volume_id/logging.h similarity index 77% rename from extras/volume_id/volume_id_logging.h rename to extras/volume_id/volume_id/logging.h index e978ce197c..c81dc57567 100644 --- a/extras/volume_id/volume_id_logging.h +++ b/extras/volume_id/volume_id/logging.h @@ -1,6 +1,6 @@ /* * volume_id_logging - this file is used to map the dbg() function - * to the host logging facility + * to the user's logging facility * */ @@ -15,7 +15,7 @@ #include #endif -/* just use the udev version*/ +/* just use the udev version */ #include "../../logging.h" #endif /* _VOLUME_ID_LOGGING_H_ */ diff --git a/extras/volume_id/volume_id/lvm/lvm.c b/extras/volume_id/volume_id/lvm/lvm.c new file mode 100644 index 0000000000..d95b6bf2d4 --- /dev/null +++ b/extras/volume_id/volume_id/lvm/lvm.c @@ -0,0 +1,104 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "lvm.h" + +#define LVM1_SB_OFF 0x400 +#define LVM1_MAGIC "HM" + +int volume_id_probe_lvm1(struct volume_id *id, __u64 off) +{ + struct lvm2_super_block { + __u8 id[2]; + } __attribute__((packed)) *lvm; + + const __u8 *buf; + + buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800); + if (buf == NULL) + return -1; + + lvm = (struct lvm2_super_block *) buf; + + if (strncmp(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, __u64 off) +{ + struct lvm2_super_block { + __u8 id[8]; + __u64 sector_xl; + __u32 crc_xl; + __u32 offset_xl; + __u8 type[8]; + } __attribute__((packed)) *lvm; + + const __u8 *buf; + unsigned int soff; + + 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 (strncmp(lvm->id, LVM2_LABEL_ID, 8) == 0) + goto found; + } + + return -1; + +found: + strncpy(id->type_version, lvm->type, 8); + volume_id_set_usage(id, VOLUME_ID_RAID); + id->type = "LVM2_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/lvm/lvm.h b/extras/volume_id/volume_id/lvm/lvm.h new file mode 100644 index 0000000000..2e44cda75b --- /dev/null +++ b/extras/volume_id/volume_id/lvm/lvm.h @@ -0,0 +1,27 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_LVM_ +#define _VOLUME_ID_LVM_ + +extern int volume_id_probe_lvm1(struct volume_id *id, __u64 off); +extern int volume_id_probe_lvm2(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/mac/mac.c b/extras/volume_id/volume_id/mac/mac.c new file mode 100644 index 0000000000..7265b288ab --- /dev/null +++ b/extras/volume_id/volume_id/mac/mac.c @@ -0,0 +1,140 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "mac.h" + +int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) +{ + struct mac_driver_desc { + __u8 signature[2]; + __u16 block_size; + __u32 block_count; + } __attribute__((__packed__)) *driver; + + struct mac_partition { + __u8 signature[2]; + __u16 res1; + __u32 map_count; + __u32 start_block; + __u32 block_count; + __u8 name[32]; + __u8 type[32]; + } __attribute__((__packed__)) *part; + + const __u8 *buf; + + buf = volume_id_get_buffer(id, off, 0x200); + if (buf == NULL) + return -1; + + part = (struct mac_partition *) buf; + if ((strncmp(part->signature, "PM", 2) == 0) && + (strncmp(part->type, "Apple_partition_map", 19) == 0)) { + /* linux creates an own subdevice for the map + * just return the type if the drive header is missing */ + volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE); + id->type = "mac_partition_map"; + return 0; + } + + driver = (struct mac_driver_desc *) buf; + if (strncmp(driver->signature, "ER", 2) == 0) { + /* we are on a main device, like a CD + * just try to probe the first partition from the map */ + unsigned int bsize = be16_to_cpu(driver->block_size); + int part_count; + int i; + + /* get first entry of partition table */ + buf = volume_id_get_buffer(id, off + bsize, 0x200); + if (buf == NULL) + return -1; + + part = (struct mac_partition *) buf; + if (strncmp(part->signature, "PM", 2) != 0) + return -1; + + part_count = be32_to_cpu(part->map_count); + dbg("expecting %d partition entries", part_count); + + if (id->partitions != NULL) + free(id->partitions); + id->partitions = + malloc(part_count * sizeof(struct volume_id_partition)); + if (id->partitions == NULL) + return -1; + memset(id->partitions, 0x00, sizeof(struct volume_id_partition)); + + id->partition_count = part_count; + + for (i = 0; i < part_count; i++) { + __u64 poff; + __u64 plen; + + buf = volume_id_get_buffer(id, off + ((i+1) * bsize), 0x200); + if (buf == NULL) + return -1; + + part = (struct mac_partition *) buf; + if (strncmp(part->signature, "PM", 2) != 0) + return -1; + + poff = be32_to_cpu(part->start_block) * bsize; + plen = be32_to_cpu(part->block_count) * bsize; + dbg("found '%s' partition entry at 0x%llx, len 0x%llx", + part->type, poff, plen); + + id->partitions[i].off = poff; + id->partitions[i].len = plen; + + if (strncmp(part->type, "Apple_Free", 10) == 0) { + volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNUSED); + } else if (strncmp(part->type, "Apple_partition_map", 19) == 0) { + volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_PARTITIONTABLE); + } else { + volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNPROBED); + } + } + volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE); + id->type = "mac_partition_map"; + return 0; + } + + return -1; +} diff --git a/extras/volume_id/volume_id/mac/mac.h b/extras/volume_id/volume_id/mac/mac.h new file mode 100644 index 0000000000..888c1c527d --- /dev/null +++ b/extras/volume_id/volume_id/mac/mac.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_MAC_ +#define _VOLUME_ID_MAC_ + +extern int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/msdos/msdos.c b/extras/volume_id/volume_id/msdos/msdos.c new file mode 100644 index 0000000000..915c1b2917 --- /dev/null +++ b/extras/volume_id/volume_id/msdos/msdos.c @@ -0,0 +1,212 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "msdos.h" + +#define MSDOS_MAGIC "\x55\xaa" +#define MSDOS_PARTTABLE_OFFSET 0x1be +#define MSDOS_SIG_OFF 0x1fe +#define BSIZE 0x200 +#define DOS_EXTENDED_PARTITION 0x05 +#define LINUX_EXTENDED_PARTITION 0x85 +#define WIN98_EXTENDED_PARTITION 0x0f +#define LINUX_RAID_PARTITION 0xfd +#define is_extended(type) \ + (type == DOS_EXTENDED_PARTITION || \ + type == WIN98_EXTENDED_PARTITION || \ + type == LINUX_EXTENDED_PARTITION) +#define is_raid(type) \ + (type == LINUX_RAID_PARTITION) + +int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) +{ + struct msdos_partition_entry { + __u8 boot_ind; + __u8 head; + __u8 sector; + __u8 cyl; + __u8 sys_ind; + __u8 end_head; + __u8 end_sector; + __u8 end_cyl; + __u32 start_sect; + __u32 nr_sects; + } __attribute__((packed)) *part; + + const __u8 *buf; + int i; + __u64 poff; + __u64 plen; + __u64 extended = 0; + __u64 current; + __u64 next; + int limit; + int empty = 1; + struct volume_id_partition *p; + + buf = volume_id_get_buffer(id, off, 0x200); + if (buf == NULL) + return -1; + + if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + return -1; + + /* check flags on all entries for a valid partition table */ + part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; + for (i = 0; i < 4; i++) { + if (part[i].boot_ind != 0 && + part[i].boot_ind != 0x80) + return -1; + + if (le32_to_cpu(part[i].nr_sects) != 0) + empty = 0; + } + if (empty == 1) + return -1; + + if (id->partitions != NULL) + free(id->partitions); + id->partitions = malloc(VOLUME_ID_PARTITIONS_MAX * + sizeof(struct volume_id_partition)); + if (id->partitions == NULL) + return -1; + memset(id->partitions, 0x00, + VOLUME_ID_PARTITIONS_MAX * sizeof(struct volume_id_partition)); + + for (i = 0; i < 4; i++) { + poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; + plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; + + if (plen == 0) + continue; + + p = &id->partitions[i]; + + p->partition_type_raw = part[i].sys_ind; + + if (is_extended(part[i].sys_ind)) { + dbg("found extended partition at 0x%llx", poff); + volume_id_set_usage_part(p, VOLUME_ID_PARTITIONTABLE); + p->type = "msdos_extended_partition"; + if (extended == 0) + extended = off + poff; + } else { + dbg("found 0x%x data partition at 0x%llx, len 0x%llx", + part[i].sys_ind, poff, plen); + + if (is_raid(part[i].sys_ind)) + volume_id_set_usage_part(p, VOLUME_ID_RAID); + else + volume_id_set_usage_part(p, VOLUME_ID_UNPROBED); + } + + p->off = off + poff; + p->len = plen; + id->partition_count = i+1; + } + + next = extended; + current = extended; + limit = 50; + + /* follow extended partition chain and add data partitions */ + while (next != 0) { + if (limit-- == 0) { + dbg("extended chain limit reached"); + break; + } + + buf = volume_id_get_buffer(id, current, 0x200); + if (buf == NULL) + break; + + part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; + + if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + break; + + next = 0; + + for (i = 0; i < 4; i++) { + poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; + plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; + + if (plen == 0) + continue; + + if (is_extended(part[i].sys_ind)) { + dbg("found extended partition at 0x%llx", poff); + if (next == 0) + next = extended + poff; + } else { + dbg("found 0x%x data partition at 0x%llx, len 0x%llx", + part[i].sys_ind, poff, plen); + + /* we always start at the 5th entry */ + while (id->partition_count < 4) + volume_id_set_usage_part(&id->partitions[id->partition_count++], VOLUME_ID_UNUSED); + + p = &id->partitions[id->partition_count]; + + if (is_raid(part[i].sys_ind)) + volume_id_set_usage_part(p, VOLUME_ID_RAID); + else + volume_id_set_usage_part(p, VOLUME_ID_UNPROBED); + + p->off = current + poff; + p->len = plen; + id->partition_count++; + + p->partition_type_raw = part[i].sys_ind; + + if (id->partition_count >= VOLUME_ID_PARTITIONS_MAX) { + dbg("too many partitions"); + next = 0; + } + } + } + + current = next; + } + + volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE); + id->type = "msdos_partition_table"; + + return 0; +} diff --git a/extras/volume_id/volume_id/msdos/msdos.h b/extras/volume_id/volume_id/msdos/msdos.h new file mode 100644 index 0000000000..55185c006b --- /dev/null +++ b/extras/volume_id/volume_id/msdos/msdos.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_MSDOS_ +#define _VOLUME_ID_MSDOS_ + +extern int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/ntfs/ntfs.c b/extras/volume_id/volume_id/ntfs/ntfs.c new file mode 100644 index 0000000000..4e1f508561 --- /dev/null +++ b/extras/volume_id/volume_id/ntfs/ntfs.c @@ -0,0 +1,205 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "ntfs.h" + +#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, __u64 off) +{ + struct ntfs_super_block { + __u8 jump[3]; + __u8 oem_id[8]; + __u16 bytes_per_sector; + __u8 sectors_per_cluster; + __u16 reserved_sectors; + __u8 fats; + __u16 root_entries; + __u16 sectors; + __u8 media_type; + __u16 sectors_per_fat; + __u16 sectors_per_track; + __u16 heads; + __u32 hidden_sectors; + __u32 large_sectors; + __u16 unused[2]; + __u64 number_of_sectors; + __u64 mft_cluster_location; + __u64 mft_mirror_cluster_location; + __s8 cluster_per_mft_record; + __u8 reserved1[3]; + __s8 cluster_per_index_record; + __u8 reserved2[3]; + __u8 volume_serial[8]; + __u16 checksum; + } __attribute__((__packed__)) *ns; + + struct master_file_table_record { + __u8 magic[4]; + __u16 usa_ofs; + __u16 usa_count; + __u64 lsn; + __u16 sequence_number; + __u16 link_count; + __u16 attrs_offset; + __u16 flags; + __u32 bytes_in_use; + __u32 bytes_allocated; + } __attribute__((__packed__)) *mftr; + + struct file_attribute { + __u32 type; + __u32 len; + __u8 non_resident; + __u8 name_len; + __u16 name_offset; + __u16 flags; + __u16 instance; + __u32 value_len; + __u16 value_offset; + } __attribute__((__packed__)) *attr; + + struct volume_info { + __u64 reserved; + __u8 major_ver; + __u8 minor_ver; + } __attribute__((__packed__)) *info; + + unsigned int sector_size; + unsigned int cluster_size; + __u64 mft_cluster; + __u64 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 __u8 *buf; + const __u8 *val; + + ns = (struct ntfs_super_block *) volume_id_get_buffer(id, off, 0x200); + if (ns == NULL) + return -1; + + if (strncmp(ns->oem_id, "NTFS", 4) != 0) + return -1; + + volume_id_set_uuid(id, ns->volume_serial, UUID_NTFS); + + 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 %lli", mft_cluster); + dbg("mftoffset 0x%llx", 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 (strncmp(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*) (((__u8 *) attr) + val_off); + snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-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 = ((__u8 *) 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/extras/volume_id/volume_id/ntfs/ntfs.h b/extras/volume_id/volume_id/ntfs/ntfs.h new file mode 100644 index 0000000000..63b1161d51 --- /dev/null +++ b/extras/volume_id/volume_id/ntfs/ntfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_NTFS_ +#define _VOLUME_ID_NTFS_ + +extern int volume_id_probe_ntfs(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/reiserfs/reiserfs.c b/extras/volume_id/volume_id/reiserfs/reiserfs.c new file mode 100644 index 0000000000..8fd8b51b59 --- /dev/null +++ b/extras/volume_id/volume_id/reiserfs/reiserfs.c @@ -0,0 +1,97 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "reiserfs.h" + +#define REISERFS1_SUPERBLOCK_OFFSET 0x2000 +#define REISERFS_SUPERBLOCK_OFFSET 0x10000 + +int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) +{ + struct reiserfs_super_block { + __u32 blocks_count; + __u32 free_blocks; + __u32 root_block; + __u32 journal_block; + __u32 journal_dev; + __u32 orig_journal_size; + __u32 dummy2[5]; + __u16 blocksize; + __u16 dummy3[3]; + __u8 magic[12]; + __u32 dummy4[5]; + __u8 uuid[16]; + __u8 label[16]; + } __attribute__((__packed__)) *rs; + + rs = (struct reiserfs_super_block *) volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); + if (rs == NULL) + return -1; + + if (strncmp(rs->magic, "ReIsEr2Fs", 9) == 0) { + strcpy(id->type_version, "3.6"); + goto found; + } + + if (strncmp(rs->magic, "ReIsEr3Fs", 9) == 0) { + strcpy(id->type_version, "JR"); + goto found; + } + + rs = (struct reiserfs_super_block *) volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200); + if (rs == NULL) + return -1; + + if (strncmp(rs->magic, "ReIsErFs", 8) == 0) { + strcpy(id->type_version, "3.5"); + goto found; + } + + return -1; + +found: + 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, UUID_DCE); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "reiserfs"; + + return 0; +} diff --git a/extras/volume_id/volume_id/reiserfs/reiserfs.h b/extras/volume_id/volume_id/reiserfs/reiserfs.h new file mode 100644 index 0000000000..14f094578f --- /dev/null +++ b/extras/volume_id/volume_id/reiserfs/reiserfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_REISERFS_ +#define _VOLUME_ID_REISERFS_ + +extern int volume_id_probe_reiserfs(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/udf/udf.c b/extras/volume_id/volume_id/udf/udf.c new file mode 100644 index 0000000000..b91e3cce4e --- /dev/null +++ b/extras/volume_id/volume_id/udf/udf.c @@ -0,0 +1,187 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "udf.h" + +#define UDF_VSD_OFFSET 0x8000 + +int volume_id_probe_udf(struct volume_id *id, __u64 off) +{ + struct volume_descriptor { + struct descriptor_tag { + __u16 id; + __u16 version; + __u8 checksum; + __u8 reserved; + __u16 serial; + __u16 crc; + __u16 crc_len; + __u32 location; + } __attribute__((__packed__)) tag; + union { + struct anchor_descriptor { + __u32 length; + __u32 location; + } __attribute__((__packed__)) anchor; + struct primary_descriptor { + __u32 seq_num; + __u32 desc_num; + struct dstring { + __u8 clen; + __u8 c[31]; + } __attribute__((__packed__)) ident; + } __attribute__((__packed__)) primary; + } __attribute__((__packed__)) type; + } __attribute__((__packed__)) *vd; + + struct volume_structure_descriptor { + __u8 type; + __u8 id[5]; + __u8 version; + } *vsd; + + unsigned int bs; + unsigned int b; + unsigned int type; + unsigned int count; + unsigned int loc; + unsigned int clen; + + vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200); + if (vsd == NULL) + return -1; + + if (strncmp(vsd->id, "NSR02", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "NSR03", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "BEA01", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "BOOT2", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "CD001", 5) == 0) + goto blocksize; + if (strncmp(vsd->id, "CDW02", 5) == 0) + goto blocksize; + if (strncmp(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 (strncmp(vsd->id, "NSR02", 5) == 0) + goto anchor; + if (strncmp(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/extras/volume_id/volume_id/udf/udf.h b/extras/volume_id/volume_id/udf/udf.h new file mode 100644 index 0000000000..b112e46ffc --- /dev/null +++ b/extras/volume_id/volume_id/udf/udf.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_UDF_ +#define _VOLUME_ID_UDF_ + +extern int volume_id_probe_udf(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/ufs/ufs.c b/extras/volume_id/volume_id/ufs/ufs.c new file mode 100644 index 0000000000..bab1d4cfad --- /dev/null +++ b/extras/volume_id/volume_id/ufs/ufs.c @@ -0,0 +1,220 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "ufs.h" + +#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, __u64 off) +{ + struct ufs_super_block { + __u32 fs_link; + __u32 fs_rlink; + __u32 fs_sblkno; + __u32 fs_cblkno; + __u32 fs_iblkno; + __u32 fs_dblkno; + __u32 fs_cgoffset; + __u32 fs_cgmask; + __u32 fs_time; + __u32 fs_size; + __u32 fs_dsize; + __u32 fs_ncg; + __u32 fs_bsize; + __u32 fs_fsize; + __u32 fs_frag; + __u32 fs_minfree; + __u32 fs_rotdelay; + __u32 fs_rps; + __u32 fs_bmask; + __u32 fs_fmask; + __u32 fs_bshift; + __u32 fs_fshift; + __u32 fs_maxcontig; + __u32 fs_maxbpg; + __u32 fs_fragshift; + __u32 fs_fsbtodb; + __u32 fs_sbsize; + __u32 fs_csmask; + __u32 fs_csshift; + __u32 fs_nindir; + __u32 fs_inopb; + __u32 fs_nspf; + __u32 fs_optim; + __u32 fs_npsect_state; + __u32 fs_interleave; + __u32 fs_trackskew; + __u32 fs_id[2]; + __u32 fs_csaddr; + __u32 fs_cssize; + __u32 fs_cgsize; + __u32 fs_ntrak; + __u32 fs_nsect; + __u32 fs_spc; + __u32 fs_ncyl; + __u32 fs_cpg; + __u32 fs_ipg; + __u32 fs_fpg; + struct ufs_csum { + __u32 cs_ndir; + __u32 cs_nbfree; + __u32 cs_nifree; + __u32 cs_nffree; + } __attribute__((__packed__)) fs_cstotal; + __s8 fs_fmod; + __s8 fs_clean; + __s8 fs_ronly; + __s8 fs_flags; + union { + struct { + __s8 fs_fsmnt[512]; + __u32 fs_cgrotor; + __u32 fs_csp[31]; + __u32 fs_maxcluster; + __u32 fs_cpc; + __u16 fs_opostbl[16][8]; + } __attribute__((__packed__)) fs_u1; + struct { + __s8 fs_fsmnt[468]; + __u8 fs_volname[32]; + __u64 fs_swuid; + __s32 fs_pad; + __u32 fs_cgrotor; + __u32 fs_ocsp[28]; + __u32 fs_contigdirs; + __u32 fs_csp; + __u32 fs_maxcluster; + __u32 fs_active; + __s32 fs_old_cpc; + __s32 fs_maxbsize; + __s64 fs_sparecon64[17]; + __s64 fs_sblockloc; + struct ufs2_csum_total { + __u64 cs_ndir; + __u64 cs_nbfree; + __u64 cs_nifree; + __u64 cs_nffree; + __u64 cs_numclusters; + __u64 cs_spare[3]; + } __attribute__((__packed__)) fs_cstotal; + struct ufs_timeval { + __s32 tv_sec; + __s32 tv_usec; + } __attribute__((__packed__)) fs_time; + __s64 fs_size; + __s64 fs_dsize; + __u64 fs_csaddr; + __s64 fs_pendingblocks; + __s32 fs_pendinginodes; + } __attribute__((__packed__)) fs_u2; + } fs_u11; + union { + struct { + __s32 fs_sparecon[53]; + __s32 fs_reclaim; + __s32 fs_sparecon2[1]; + __s32 fs_state; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + } __attribute__((__packed__)) fs_sun; + struct { + __s32 fs_sparecon[53]; + __s32 fs_reclaim; + __s32 fs_sparecon2[1]; + __u32 fs_npsect; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + } __attribute__((__packed__)) fs_sunx86; + struct { + __s32 fs_sparecon[50]; + __s32 fs_contigsumsize; + __s32 fs_maxsymlinklen; + __s32 fs_inodefmt; + __u32 fs_maxfilesize[2]; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + __s32 fs_state; + } __attribute__((__packed__)) fs_44; + } fs_u2; + __s32 fs_postblformat; + __s32 fs_nrpos; + __s32 fs_postbloff; + __s32 fs_rotbloff; + __u32 fs_magic; + __u8 fs_space[1]; + } __attribute__((__packed__)) *ufs; + + __u32 magic; + int i; + int offsets[] = {0, 8, 64, 256, -1}; + + 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"; + + return 0; +} diff --git a/extras/volume_id/volume_id/ufs/ufs.h b/extras/volume_id/volume_id/ufs/ufs.h new file mode 100644 index 0000000000..82b4e1d064 --- /dev/null +++ b/extras/volume_id/volume_id/ufs/ufs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_UFS_ +#define _VOLUME_ID_UFS_ + +extern int volume_id_probe_ufs(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c new file mode 100644 index 0000000000..0cd2eadec1 --- /dev/null +++ b/extras/volume_id/volume_id/util.c @@ -0,0 +1,245 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" + +static char *usage_to_string(enum volume_id_usage usage_id) +{ + switch (usage_id) { + case VOLUME_ID_FILESYSTEM: + return "filesystem"; + case VOLUME_ID_PARTITIONTABLE: + return "partitiontable"; + case VOLUME_ID_OTHER: + return "other"; + case VOLUME_ID_RAID: + return "raid"; + case VOLUME_ID_DISKLABEL: + return "disklabel"; + case VOLUME_ID_UNPROBED: + return "unprobed"; + case VOLUME_ID_UNUSED: + return "unused"; + } + return NULL; +} + +void volume_id_set_usage_part(struct volume_id_partition *part, enum volume_id_usage usage_id) +{ + part->usage_id = usage_id; + part->usage = usage_to_string(usage_id); +} + +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 __u8 *buf, unsigned int count) +{ + memcpy(id->label_raw, buf, count); + id->label_raw_len = count; +} + +void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned int count) +{ + unsigned int i; + + memcpy(id->label, buf, count); + + /* 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 __u8 *buf, enum endian endianess, unsigned int count) +{ + unsigned int i, j; + __u16 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) { + id->label[j] = '\0'; + break; + } else if (c < 0x80) { + id->label[j++] = (__u8) c; + } else if (c < 0x800) { + id->label[j++] = (__u8) (0xc0 | (c >> 6)); + id->label[j++] = (__u8) (0x80 | (c & 0x3f)); + } else { + id->label[j++] = (__u8) (0xe0 | (c >> 12)); + id->label[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); + id->label[j++] = (__u8) (0x80 | (c & 0x3f)); + } + } +} + +void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format) +{ + unsigned int i; + unsigned int count = 0; + + switch(format) { + case UUID_DOS: + count = 4; + break; + case UUID_NTFS: + case UUID_HFS: + count = 8; + break; + case UUID_DCE: + count = 16; + } + memcpy(id->uuid_raw, buf, 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_NTFS: + 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_HFS: + 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; + } +} + +__u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len) +{ + unsigned int buf_len; + + dbg("get buffer off 0x%llx(%llu), len 0x%x", off, 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) + return NULL; + } + + /* check if we need to read */ + if ((off + len) > id->sbbuf_len) { + dbg("read sbbuf len:0x%llx", off + len); + lseek(id->fd, 0, SEEK_SET); + buf_len = read(id->fd, id->sbbuf, off + len); + dbg("got 0x%x (%i) bytes", buf_len, buf_len); + id->sbbuf_len = buf_len; + if (buf_len < off + 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) + return NULL; + } + + /* check if we need to read */ + if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { + dbg("read seekbuf off:0x%llx len:0x%x", off, len); + if (lseek(id->fd, off, SEEK_SET) == -1) + return NULL; + buf_len = read(id->fd, id->seekbuf, len); + dbg("got 0x%x (%i) bytes", buf_len, buf_len); + id->seekbuf_off = off; + id->seekbuf_len = buf_len; + if (buf_len < len) { + dbg("requested 0x%x bytes, got only 0x%x 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/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h new file mode 100644 index 0000000000..e5cd63e1aa --- /dev/null +++ b/extras/volume_id/volume_id/util.h @@ -0,0 +1,91 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_UTIL_ +#define _VOLUME_ID_UTIL_ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#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 + +/* probe volume for all known filesystems in specific order */ +#define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \ + (((__u16)(x) & 0xff00u) >> 8)) + +#define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \ + (((__u32)(x) & 0x00ff0000u) >> 8) | \ + (((__u32)(x) & 0x0000ff00u) << 8) | \ + (((__u32)(x) & 0x000000ffu) << 24)) + +#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000ull) >> 56) | \ + (((__u64)(x) & 0x00ff000000000000ull) >> 40) | \ + (((__u64)(x) & 0x0000ff0000000000ull) >> 24) | \ + (((__u64)(x) & 0x000000ff00000000ull) >> 8) | \ + (((__u64)(x) & 0x00000000ff000000ull) << 8) | \ + (((__u64)(x) & 0x0000000000ff0000ull) << 24) | \ + (((__u64)(x) & 0x000000000000ff00ull) << 40) | \ + (((__u64)(x) & 0x00000000000000ffull) << 56)) + +#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) bswap16(x) +#define be32_to_cpu(x) bswap32(x) +#elif (__BYTE_ORDER == __BIG_ENDIAN) +#define le16_to_cpu(x) bswap16(x) +#define le32_to_cpu(x) bswap32(x) +#define le64_to_cpu(x) bswap64(x) +#define be16_to_cpu(x) (x) +#define be32_to_cpu(x) (x) +#endif + +enum uuid_format { + UUID_DCE, + UUID_DOS, + UUID_NTFS, + UUID_HFS, +}; + +enum endian { + LE = 0, + BE = 1 +}; + +extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id); +extern void volume_id_set_usage_part(struct volume_id_partition *part, enum volume_id_usage usage_id); +extern void volume_id_set_label_raw(struct volume_id *id, const __u8 *buf, unsigned int count); +extern void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned int count); +extern void volume_id_set_label_unicode16(struct volume_id *id, const __u8 *buf, enum endian endianess, unsigned int count); +extern void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format); +extern __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len); +extern void volume_id_free_buffer(struct volume_id *id); + +#endif /* _VOLUME_ID_UTIL_ */ + diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c new file mode 100644 index 0000000000..e1d4b1c922 --- /dev/null +++ b/extras/volume_id/volume_id/volume_id.c @@ -0,0 +1,202 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" + +#include "ext/ext.h" +#include "reiserfs/reiserfs.h" +#include "fat/fat.h" +#include "hfs/hfs.h" +#include "jfs/jfs.h" +#include "xfs/xfs.h" +#include "ufs/ufs.h" +#include "ntfs/ntfs.h" +#include "iso9660/iso9660.h" +#include "udf/udf.h" +#include "highpoint/highpoint.h" +#include "linux_swap/linux_swap.h" +#include "linux_raid/linux_raid.h" +#include "lvm/lvm.h" +#include "mac/mac.h" +#include "msdos/msdos.h" + +int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size) +{ + if (id == NULL) + return -EINVAL; + + /* probe for raid first, cause fs probes may be successful on raid members */ + if (volume_id_probe_linux_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_lvm1(id, off) == 0) + goto exit; + + if (volume_id_probe_lvm2(id, off) == 0) + goto exit; + + if (volume_id_probe_highpoint_ataraid(id, off) == 0) + goto exit; + + /* signature in the first block, only small buffer needed */ + if (volume_id_probe_vfat(id, off) == 0) + goto exit; + + if (volume_id_probe_mac_partition_map(id, off) == 0) + goto exit; + + if (volume_id_probe_xfs(id, off) == 0) + goto exit; + + /* fill buffer with maximum */ + volume_id_get_buffer(id, 0, SB_BUFFER_SIZE); + + if (volume_id_probe_linux_swap(id, off) == 0) + goto exit; + + if (volume_id_probe_ext(id, off) == 0) + goto exit; + + if (volume_id_probe_reiserfs(id, off) == 0) + goto exit; + + if (volume_id_probe_jfs(id, off) == 0) + goto exit; + + if (volume_id_probe_udf(id, off) == 0) + goto exit; + + if (volume_id_probe_iso9660(id, off) == 0) + goto exit; + + if (volume_id_probe_hfs_hfsplus(id, off) == 0) + goto exit; + + if (volume_id_probe_ufs(id, off) == 0) + goto exit; + + if (volume_id_probe_ntfs(id, off) == 0) + goto exit; + + return -1; + +exit: + /* If the filestystem in recognized, we free the allocated buffers, + otherwise they will stay in place for the possible next probe call */ + volume_id_free_buffer(id); + + return 0; +} + +/* open volume by already open file descriptor */ +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; +} + +/* open volume by device node */ +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; +} + +/* open volume by major/minor */ +struct volume_id *volume_id_open_dev_t(dev_t devt) +{ + struct volume_id *id; + __u8 tmp_node[VOLUME_ID_PATH_MAX]; + + snprintf(tmp_node, VOLUME_ID_PATH_MAX, + "/dev/.volume_id-%u-%u-%u", getpid(), major(devt), minor(devt)); + tmp_node[VOLUME_ID_PATH_MAX] = '\0'; + + /* create tempory node to open the block device */ + unlink(tmp_node); + if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0) + return NULL; + + id = volume_id_open_node(tmp_node); + + unlink(tmp_node); + + return id; +} + +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); + + if (id->partitions != NULL) + free(id->partitions); + + free(id); +} diff --git a/extras/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h similarity index 70% rename from extras/volume_id/volume_id.h rename to extras/volume_id/volume_id/volume_id.h index 9d66b196b7..6c25a243c3 100644 --- a/extras/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -1,7 +1,7 @@ /* * volume_id - reads partition label and uuid * - * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2005 Kay Sievers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 28 +#define VOLUME_ID_VERSION 31 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 @@ -37,35 +37,12 @@ enum volume_id_usage { VOLUME_ID_FILESYSTEM, VOLUME_ID_PARTITIONTABLE, VOLUME_ID_RAID, -}; - -enum volume_id_type { - VOLUME_ID_ALL, - VOLUME_ID_MSDOSPARTTABLE, - VOLUME_ID_MSDOSEXTENDED, - VOLUME_ID_SWAP, - VOLUME_ID_EXT2, - VOLUME_ID_EXT3, - VOLUME_ID_REISERFS, - VOLUME_ID_XFS, - VOLUME_ID_JFS, - VOLUME_ID_VFAT, - VOLUME_ID_UDF, - VOLUME_ID_ISO9660, - VOLUME_ID_NTFS, - VOLUME_ID_MACPARTMAP, - VOLUME_ID_HFS, - VOLUME_ID_HFSPLUS, - VOLUME_ID_UFS, - VOLUME_ID_LINUX_RAID, - VOLUME_ID_LVM1, - VOLUME_ID_LVM2, - VOLUME_ID_HPTRAID, + VOLUME_ID_DISKLABEL, }; struct volume_id_partition { enum volume_id_usage usage_id; - enum volume_id_type type_id; + char *usage; char *type; unsigned long long off; unsigned long long len; @@ -79,11 +56,13 @@ struct volume_id { unsigned char uuid_raw[VOLUME_ID_UUID_SIZE]; char uuid[VOLUME_ID_UUID_STRING_SIZE]; enum volume_id_usage usage_id; - enum volume_id_type type_id; + char *usage; char *type; char type_version[VOLUME_ID_FORMAT_SIZE]; + struct volume_id_partition *partitions; unsigned int partition_count; + int fd; unsigned char *sbbuf; unsigned int sbbuf_len; @@ -93,20 +72,10 @@ struct volume_id { int fd_close; }; -/* open volume by already open file descriptor */ extern struct volume_id *volume_id_open_fd(int fd); - -/* open volume by device node */ extern struct volume_id *volume_id_open_node(const char *path); - -/* open volume by major/minor */ extern struct volume_id *volume_id_open_dev_t(dev_t devt); - -/* probe volume for filesystem type and try to read label/uuid */ -extern int volume_id_probe(struct volume_id *id, enum volume_id_type type, - unsigned long long off, unsigned long long size); - -/* free allocated device info */ +extern int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size); extern void volume_id_close(struct volume_id *id); #endif diff --git a/extras/volume_id/volume_id/xfs/xfs.c b/extras/volume_id/volume_id/xfs/xfs.c new file mode 100644 index 0000000000..b73f565eee --- /dev/null +++ b/extras/volume_id/volume_id/xfs/xfs.c @@ -0,0 +1,74 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "xfs.h" + +int volume_id_probe_xfs(struct volume_id *id, __u64 off) +{ + struct xfs_super_block { + __u8 magic[4]; + __u32 blocksize; + __u64 dblocks; + __u64 rblocks; + __u32 dummy1[2]; + __u8 uuid[16]; + __u32 dummy2[15]; + __u8 fname[12]; + __u32 dummy3[2]; + __u64 icount; + __u64 ifree; + __u64 fdblocks; + } __attribute__((__packed__)) *xs; + + xs = (struct xfs_super_block *) volume_id_get_buffer(id, off, 0x200); + if (xs == NULL) + return -1; + + if (strncmp(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, UUID_DCE); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "xfs"; + + return 0; +} diff --git a/extras/volume_id/volume_id/xfs/xfs.h b/extras/volume_id/volume_id/xfs/xfs.h new file mode 100644 index 0000000000..76b1725664 --- /dev/null +++ b/extras/volume_id/volume_id/xfs/xfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID__ +#define _VOLUME_ID__ + +extern int volume_id_probe_xfs(struct volume_id *id, __u64 off); + +#endif From 85a953c0eeb66260f77bd69a255034af18cdbba0 Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Tue, 1 Feb 2005 11:12:32 +0100 Subject: [PATCH 1114/4284] [PATCH] The attached patch fixes the code path if namedev_name_device() fails. --- udev_add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev_add.c b/udev_add.c index acd678ffba..d4cccfc085 100644 --- a/udev_add.c +++ b/udev_add.c @@ -292,7 +292,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) } if (namedev_name_device(udev, class_dev) != 0) - goto exit; + return 0; dbg("adding name='%s'", udev->name); From d25e14ae1ef476fdc1d2b690b9426bd45bafd34e Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 3 Feb 2005 00:22:31 -0800 Subject: [PATCH 1115/4284] [PATCH] gentoo fb permission fix. --- etc/udev/gentoo/udev.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 6f71321fb8..7f708b631f 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -56,7 +56,7 @@ KERNEL="dm-[0-9]*", NAME="" KERNEL="device-mapper", NAME="mapper/control" # fb devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k" +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", MODE="0600" # floppy devices KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy" From 9badc83e4f6d67e7d646c5f438597154f34ad0ab Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 3 Feb 2005 00:24:38 -0800 Subject: [PATCH 1116/4284] [PATCH] 051 release --- ChangeLog | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f34bacdb2..42d84563b2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,63 @@ +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 ============================================ diff --git a/Makefile b/Makefile index d56f22d0df..ece518f53e 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 050 +VERSION = 051 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 46eaf698f8..a0fd5b5426 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 050 +Version: 051 Release: 1 License: GPL Group: Utilities/System From fbda4a34d846946bf8ed63deadfd6e65b2299792 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Feb 2005 21:38:26 +0100 Subject: [PATCH 1117/4284] [PATCH] selinux: cleanup udev integration Move code into a .c-file instead of big inline functions in a header file. Pass the device name down instead of relying that the node name is equal to the kernel name. --- Makefile | 7 ++- selinux.h | 148 ------------------------------------------- udev_add.c | 15 +++-- udev_selinux.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++ udev_selinux.h | 38 +++++++++++ 5 files changed, 217 insertions(+), 157 deletions(-) delete mode 100644 selinux.h create mode 100644 udev_selinux.c create mode 100644 udev_selinux.h diff --git a/Makefile b/Makefile index ece518f53e..47516b3e37 100644 --- a/Makefile +++ b/Makefile @@ -203,7 +203,7 @@ HEADERS = \ udev_db.h \ udev_sysfs.h \ logging.h \ - selinux.h \ + udev_selinux.h \ list.h SYSFS_OBJS = \ @@ -245,6 +245,11 @@ ifeq ($(strip $(USE_KLIBC)),true) OBJS += klibc_fixups/klibc_fixups.a endif +ifeq ($(strip $(USE_SELINUX)),true) + UDEV_OBJS += udev_selinux.o + LIB_OBJS += -lselinux +endif + ifeq ($(strip $(V)),false) QUIET=@$(PWD)/ccdv HOST_PROGS=ccdv diff --git a/selinux.h b/selinux.h deleted file mode 100644 index df5bab69d7..0000000000 --- a/selinux.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef SELINUX_H -#define SELINUX_H - -#ifndef USE_SELINUX - -static inline void selinux_setfilecon(char *file, unsigned int mode) {} -static inline void selinux_setfscreatecon(char *file, unsigned int mode) {} -static inline void selinux_init(void) {} -static inline void selinux_restore(void) {} - -#else - -#include -#include -#include -#include - -static int selinux_enabled=-1; -static security_context_t prev_scontext=NULL; - -static inline int is_selinux_running(void) -{ - if (selinux_enabled == -1) - return selinux_enabled = is_selinux_enabled() > 0; - return selinux_enabled; -} - -static inline int selinux_get_media(char *path, int mode, char **media) -{ - FILE *fp; - char buf[PATH_MAX]; - char mediabuf[PATH_MAX]; - int ret = -1; - - *media = NULL; - if (!(mode && S_IFBLK)) { - return -1; - } - - snprintf(buf, sizeof(buf), "/proc/ide/%s/media", basename(path)); - - fp=fopen(buf,"r"); - if (!fp) - goto out; - - mediabuf[0] = '\0'; - - if (fgets(mediabuf, sizeof(mediabuf), fp) == NULL) - goto close_out; - - int size = strlen(mediabuf); - while (size-- > 0) { - if (isspace(mediabuf[size])) { - mediabuf[size]='\0'; - } else { - break; - } - } - *media = strdup(mediabuf); - info("selinux_get_media(%s)->%s \n", path, *media); - ret = 0; - -close_out: - fclose(fp); -out: - return ret; -} - -static inline void selinux_setfilecon(char *file, unsigned int mode) -{ - if (is_selinux_running()) { - security_context_t scontext=NULL; - char *media; - int ret=selinux_get_media(file, mode, &media); - if (ret == 0) { - ret = matchmediacon(media, &scontext); - free(media); - } - if (ret == -1) - if (matchpathcon(file, mode, &scontext) < 0) { - dbg("matchpathcon(%s) failed\n", file); - return; - } - if (setfilecon(file, scontext) < 0) - dbg("setfiles %s failed with error '%s'", - file, strerror(errno)); - freecon(scontext); - } -} - -static inline void selinux_setfscreatecon(char *file, unsigned int mode) -{ - int retval = 0; - security_context_t scontext=NULL; - - if (is_selinux_running()) { - char *media; - int ret = selinux_get_media(file, mode, &media); - - if (ret == 0) { - ret = matchmediacon(media, &scontext); - free(media); - } - - if (ret == -1) - if (matchpathcon(file, mode, &scontext) < 0) { - dbg("matchpathcon(%s) failed\n", file); - return; - } - - retval = setfscreatecon(scontext); - if (retval < 0) - dbg("setfiles %s failed with error '%s'", - file, strerror(errno)); - freecon(scontext); - } -} - -static inline void selinux_init(void) -{ - /* - * record the present security context, for file-creation - * restoration creation purposes. - */ - if (is_selinux_running()) { - if (getfscreatecon(&prev_scontext) < 0) { - dbg("getfscreatecon failed\n"); - } - prev_scontext = NULL; - } -} - -static inline void selinux_restore(void) -{ - if (is_selinux_running()) { - /* reset the file create context to its former glory */ - if (setfscreatecon(prev_scontext) < 0) - dbg("setfscreatecon failed\n"); - if (prev_scontext) { - freecon(prev_scontext); - prev_scontext = NULL; - } - } -} - -#endif /* USE_SELINUX */ - -#endif /* SELINUX_H */ diff --git a/udev_add.c b/udev_add.c index d4cccfc085..24a20bba9b 100644 --- a/udev_add.c +++ b/udev_add.c @@ -43,8 +43,7 @@ #include "logging.h" #include "namedev.h" #include "udev_db.h" - -#include "selinux.h" +#include "udev_selinux.h" /* * the major/minor of a device is stored in a file called "dev" @@ -68,7 +67,7 @@ error: return -1; } -static int make_node(char *file, int major, int minor, unsigned int mode, uid_t uid, gid_t gid) +static int make_node(struct udevice *udev, char *file, int major, int minor, unsigned int mode, uid_t uid, gid_t gid) { struct stat stats; int retval = 0; @@ -80,7 +79,7 @@ static int make_node(char *file, int major, int minor, unsigned int mode, uid_t if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && (stats.st_rdev == makedev(major, minor))) { dbg("preserve file '%s', cause it has correct dev_t", file); - selinux_setfilecon(file,stats.st_mode); + selinux_setfilecon(file, udev->kernel_name, stats.st_mode); goto perms; } @@ -90,7 +89,7 @@ static int make_node(char *file, int major, int minor, unsigned int mode, uid_t dbg("already present file '%s' unlinked", file); create: - selinux_setfscreatecon(file, mode); + selinux_setfscreatecon(file, udev->kernel_name, mode); retval = mknod(file, mode, makedev(major, minor)); if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", @@ -184,7 +183,7 @@ static int create_node(struct udevice *udev) if (!udev->test_run) { info("creating device node '%s'", filename); - if (make_node(filename, udev->major, udev->minor, udev->mode, uid, gid) != 0) + if (make_node(udev, filename, udev->major, udev->minor, udev->mode, uid, gid) != 0) goto error; } else { info("creating device node '%s', major = '%d', minor = '%d', " @@ -199,7 +198,7 @@ static int create_node(struct udevice *udev) for (i = 1; i <= udev->partitions; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); - make_node(partitionname, udev->major, udev->minor + i, udev->mode, uid, gid); + make_node(udev, partitionname, udev->major, udev->minor + i, udev->mode, uid, gid); } } } @@ -237,7 +236,7 @@ static int create_node(struct udevice *udev) dbg("symlink(%s, %s)", linktarget, filename); if (!udev->test_run) { - selinux_setfscreatecon(filename, S_IFLNK); + selinux_setfscreatecon(filename, udev->kernel_name, S_IFLNK); unlink(filename); if (symlink(linktarget, filename) != 0) dbg("symlink(%s, %s) failed with error '%s'", diff --git a/udev_selinux.c b/udev_selinux.c new file mode 100644 index 0000000000..72381f0d0d --- /dev/null +++ b/udev_selinux.c @@ -0,0 +1,166 @@ +/* + * udev_selinux.h + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev_selinux.h" +#include "logging.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'\n", 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; + + media = get_media(devname, mode); + if (media) { + ret = matchmediacon(media, &scontext); + free(media); + } + + if (ret < 0) + if (matchpathcon(file, mode, &scontext) < 0) { + dbg("matchpathcon(%s) failed\n", file); + return; + } + + if (setfilecon(file, scontext) < 0) + dbg("setfiles %s failed with error '%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; + + media = get_media(devname, mode); + if (media) { + ret = matchmediacon(media, &scontext); + free(media); + } + + if (ret < 0) + if (matchpathcon(file, mode, &scontext) < 0) { + dbg("matchpathcon(%s) failed\n", file); + return; + } + + if (setfscreatecon(scontext) < 0) + dbg("setfiles %s failed with error '%s'", file, strerror(errno)); + + freecon(scontext); + } +} + +void selinux_init(void) +{ + /* + * record the present security context, for file-creation + * restoration creation purposes. + */ + if (is_selinux_running()) { + if (getfscreatecon(&prev_scontext) < 0) + dbg("getfscreatecon failed\n"); + + prev_scontext = NULL; + } +} + +void selinux_restore(void) +{ + if (is_selinux_running()) { + /* reset the file create context to its former glory */ + if (setfscreatecon(prev_scontext) < 0) + dbg("setfscreatecon failed\n"); + + if (prev_scontext) { + freecon(prev_scontext); + prev_scontext = NULL; + } + } +} diff --git a/udev_selinux.h b/udev_selinux.h new file mode 100644 index 0000000000..132a9a6550 --- /dev/null +++ b/udev_selinux.h @@ -0,0 +1,38 @@ +/* + * udev_selinux.h + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, 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_init(void); +extern void selinux_restore(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_init(void) {} +static inline void selinux_restore(void) {} + +#endif /* USE_SELINUX */ +#endif /* _UDEV_USE_SELINUX */ From 61599bdd06b059e7a5792b0417828d0a87541038 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Feb 2005 21:57:39 +0100 Subject: [PATCH 1118/4284] [PATCH] simple_build_check: make it possible to pass KERNEL_DIR --- test/simple-build-check.sh | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 8919fcfcf0..fa80db4c82 100644 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -1,26 +1,29 @@ #/bin/sh -EXTRA="extras/chassis_id extras/scsi_id extras/volume_id" +EXTRAS="extras/chassis_id extras/scsi_id extras/volume_id" -make spotless EXTRAS="$EXTRA" >/dev/null -make all EXTRAS="$EXTRA" || exit +[ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build +echo KERNEL_DIR: "$KERNEL_DIR" + +make spotless EXTRAS="$EXTRAS" >/dev/null +make all EXTRAS="$EXTRAS" || exit echo -e "\n\n" -make spotless EXTRAS="$EXTRA" >/dev/null -make all DEBUG=true EXTRAS="$EXTRA" || exit +make spotless EXTRAS="$EXTRAS" >/dev/null +make all DEBUG=true EXTRAS="$EXTRAS" || exit echo -e "\n\n" -make spotless EXTRAS="$EXTRA" >/dev/null -make all USE_LOG=false EXTRAS="$EXTRA" || exit +make spotless EXTRAS="$EXTRAS" >/dev/null +make all USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" -make spotless EXTRAS="$EXTRA" >/dev/null -make all USE_KLIBC=true DEBUG=true EXTRAS="$EXTRA" || exit +make spotless EXTRAS="$EXTRAS" >/dev/null +make all USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" -make spotless EXTRAS="$EXTRA" >/dev/null -make all USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRA" || exit +make spotless EXTRAS="$EXTRAS" >/dev/null +make all USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" -make spotless EXTRAS="$EXTRA" >/dev/null +make spotless EXTRAS="$EXTRAS" >/dev/null From 9172c95c77e8f1377b6c8becc84995e6e28a61eb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Feb 2005 02:36:54 +0100 Subject: [PATCH 1119/4284] [PATCH] chassis_id: clean compilation and fix bad function parameter passing Adding prototypes for functions resulted in an error, cause: table_find_disk(disk_snum, &chassis_num, &slot_num); is called but the function is defined as: int table_find_disk(char *serialnumber , int *host_num, int *chassis_num, int *slot_num) which can obviously not work correctly. Using popen() is not klibc compatible, so skip the compilation if a klibc compile is requested. --- extras/chassis_id/Makefile | 24 ++++++++++---- extras/chassis_id/chassis_id.c | 58 ++++++++++++++++------------------ extras/chassis_id/chassis_id.h | 6 ++-- extras/chassis_id/table.c | 13 +++++--- 4 files changed, 58 insertions(+), 43 deletions(-) diff --git a/extras/chassis_id/Makefile b/extras/chassis_id/Makefile index 141d23c7b8..ae5c95961c 100644 --- a/extras/chassis_id/Makefile +++ b/extras/chassis_id/Makefile @@ -20,7 +20,7 @@ # * Authors: Atul Sabharwal # * # * -CFLAGS = -g + TARGET = chassis_id exec_prefix = ${prefix} @@ -28,14 +28,24 @@ sbindir = ${exec_prefix}/sbin INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 -all: chassis_id +all: chassis_id +ifneq ($(strip $(USE_KLIBC)),true) chassis_id: chassis_id.c table.c - gcc -o $(TARGET) $(CFLAGS) chassis_id.c table.c - -clean: - rm -rf core a.out $(TARGET) + $(QUIET) $(CC) -o $(TARGET) $(CFLAGS) chassis_id.c table.c install: all $(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(sbindir)/$(TARGET) - +else +chassis_id: + @echo + @echo "!!! chassis_id is incompatible with klibc !!!" + @echo + @exit 0 + +install: all +endif + +clean: + rm -rf core a.out $(TARGET) + diff --git a/extras/chassis_id/chassis_id.c b/extras/chassis_id/chassis_id.c index 3fdfa96018..de86087921 100644 --- a/extras/chassis_id/chassis_id.c +++ b/extras/chassis_id/chassis_id.c @@ -18,7 +18,7 @@ * Boston, MA 021110-1307, USA. * * Authors: Atul Sabharwal - * + * */ #include @@ -29,7 +29,33 @@ //#define DEBUG 1 -int main(int argc, char **argv, char ** envp) +/* Run SCSI id to find serial number of the device */ +static int getserial_number(char * devpath, char * snumber) +{ + FILE *fp; + char vendor[255], model[255], cmd[255]; + int retval; + + sprintf(cmd, "/sbin/scsi_id -s %s -p 0x80", devpath); + + fp = popen(cmd, "r"); + + if (fp == NULL) + return -ERROR_BAD_SNUMBER; + + fscanf(fp, "%s %s %s", vendor, model, snumber); + #ifdef DEBUG + syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", snumber ); + #endif + + retval = pclose(fp); + if (retval == -1) + return -ERROR_BAD_SNUMBER; + else + return NO_ERROR; +} + +int main(int argc, char **argv, char **envp) { int chassis_num, slot_num, retval; char disk_snum[255], devpath[255]; @@ -63,31 +89,3 @@ int main(int argc, char **argv, char ** envp) } return 0; } - - -/* Run SCSI id to find serial number of the device */ -int getserial_number( char * devpath, char * snumber ) -{ - FILE *fp; - char vendor[255], model[255], cmd[255]; - int retval; - - sprintf(cmd, "/sbin/scsi_id -s %s -p 0x80", devpath); - - fp = popen(cmd, "r"); - - if (fp == NULL) - return -ERROR_BAD_SNUMBER; - - fscanf(fp, "%s %s %s", vendor, model, snumber); - #ifdef DEBUG - syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", snumber ); - #endif - - retval = pclose(fp); - if (retval == -1) - return -ERROR_BAD_SNUMBER; - else - return NO_ERROR; -} - diff --git a/extras/chassis_id/chassis_id.h b/extras/chassis_id/chassis_id.h index 9937e3dfac..1463bd22c7 100644 --- a/extras/chassis_id/chassis_id.h +++ b/extras/chassis_id/chassis_id.h @@ -18,7 +18,7 @@ * Boston, MA 021110-1307, USA. * * Authors: Atul Sabharwal - * + * */ #ifndef _CHASSIS_ID_H @@ -35,6 +35,8 @@ #define ERROR_BAD_SCAN 8 #define NO_ERROR 0 -extern int table_init(); +extern int table_init(void); +extern int table_find_disk(const char *serialnumber , int *chassis_num, int *slot_num); +extern int table_select_disk(int diskindex); #endif diff --git a/extras/chassis_id/table.c b/extras/chassis_id/table.c index f4689ae243..8d14cd1b59 100644 --- a/extras/chassis_id/table.c +++ b/extras/chassis_id/table.c @@ -18,10 +18,13 @@ * Boston, MA 021110-1307, USA. * * Authors: Atul Sabharwal - * + * */ #include +#include + +#include "chassis_id.h" #define TABLE_SIZE 100 #define PROVISION_DB "/usr/local/bin/provision.tbl" @@ -40,7 +43,7 @@ int ptable_size; /* Initialize the provisioning table by reading the data from special file provision.tbl * Return error if something does not work appropriately. */ -int table_init() +int table_init(void) { FILE *fp; char ptr[255]; @@ -70,7 +73,7 @@ int table_init() /* return -1 when no disk found. Otherwise return index of disk */ -int table_find_disk( char * serialnumber , int * host_num, int * chassis_num, int *slot_num) +int table_find_disk(const char *serialnumber , int *chassis_num, int *slot_num) { int i; @@ -92,10 +95,12 @@ int table_find_disk( char * serialnumber , int * host_num, int * chassis_num, in * so that it can create descriptive GDN for it. So, for that we need to output * this data to stdout. */ -int table_select_disk( int diskindex ) +int table_select_disk(int diskindex) { printf("%d ", ptable[diskindex].chassis_num); printf("%d ", ptable[diskindex].slot_num); printf("%s ", ptable[diskindex].name); + + return 0; } From 1134a81b98e189a8ec99a1ea4aba8e52b358873b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Feb 2005 02:38:56 +0100 Subject: [PATCH 1120/4284] [PATCH] fix -Wsign-compare warnings --- extras/scsi_id/scsi_serial.c | 5 ++--- namedev_parse.c | 2 +- udev_db.c | 2 +- udev_sysfs.c | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 0db756404c..8b9fbe0681 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -553,7 +553,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int len) { int retval; - int id_ind, j; + unsigned int id_ind, j; unsigned char page_83[SCSI_INQ_BUFF_LEN]; memset(page_83, 0, SCSI_INQ_BUFF_LEN); @@ -584,8 +584,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, * Examine each descriptor returned. There is normally only * one or a small number of descriptors. */ - for (j = 4; j <= page_83[3] + 3; - j += page_83[j + 3] + 4) { + for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) { retval = check_fill_0x83_id(scsi_dev, &page_83[j], &id_search_list[id_ind], serial, len); diff --git a/namedev_parse.c b/namedev_parse.c index 3b14a6a500..5bd59d83f2 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -126,7 +126,7 @@ static int namedev_parse(const char *filename, void *data) cur = 0; lineno = 0; while (cur < bufsize) { - int i, j; + unsigned int i, j; count = buf_get_line(buf, bufsize, cur); bufline = &buf[cur]; diff --git a/udev_db.c b/udev_db.c index 36da264716..df7cfbb259 100644 --- a/udev_db.c +++ b/udev_db.c @@ -195,7 +195,7 @@ int udev_db_get_device_byname(struct udevice *udev, const char *name) memset(&db_udev, 0x00, sizeof(struct udevice)); if (parse_db_file(&db_udev, filename) == 0) { char *pos; - int len; + unsigned int len; if (strncmp(name, db_udev.name, NAME_SIZE) == 0) { goto found; diff --git a/udev_sysfs.c b/udev_sysfs.c index 1b3603df6d..fd7330a161 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -211,7 +211,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { NULL, NULL } }; const struct class_device *classdevice; - int len; + unsigned int len; /* the kernel may tell us what to wait for */ if (kernel_release_satisfactory(2,6,10) > 0) From 045b1f0f7a7af2182e7109f472d873f1cc0c5e4b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Feb 2005 02:43:16 +0100 Subject: [PATCH 1121/4284] [PATCH] Makefile: cleanup conditional config option sections --- Makefile | 159 ++++++++++++++++++++++++++----------------------------- 1 file changed, 76 insertions(+), 83 deletions(-) diff --git a/Makefile b/Makefile index 47516b3e37..052e41acc3 100644 --- a/Makefile +++ b/Makefile @@ -113,88 +113,6 @@ WARNINGS := -Wall CFLAGS := -pipe -ifeq ($(strip $(USE_LOG)),true) - CFLAGS += -DLOG -endif - -# if DEBUG is enabled, then we do not strip or optimize -ifeq ($(strip $(DEBUG)),true) - CFLAGS += -O1 -g -DDEBUG -D_GNU_SOURCE - LDFLAGS += -Wl,-warn-common - STRIPCMD = /bin/true -Since_we_are_debugging -else - CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE - LDFLAGS += -s -Wl,-warn-common - STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment -endif - -# If we are using our version of klibc, then we need to build, link it, and then -# link udev against it statically. -# Otherwise, use glibc and link dynamically. -ifeq ($(strip $(USE_KLIBC)),true) - KLIBC_FIXUPS_DIR= $(PWD)/klibc_fixups - KLIBC_BASE = $(PWD)/klibc - KLIBC_DIR = $(KLIBC_BASE)/klibc - INCLUDE_DIR := $(KLIBC_BASE)/include - LINUX_INCLUDE_DIR := $(KERNEL_DIR)/include - include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG - # arch specific objects - ARCH_LIB_OBJS = $(KLIBC_DIR)/libc.a - - - CRT0 = $(KLIBC_DIR)/crt0.o - LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) - CFLAGS += $(WARNINGS) -nostdinc \ - $(OPTFLAGS) \ - -D__KLIBC__ -fno-builtin-printf \ - -I$(KLIBC_FIXUPS_DIR) \ - -include $(KLIBC_FIXUPS_DIR)/klibc_fixups.h \ - -I$(INCLUDE_DIR) \ - -I$(INCLUDE_DIR)/arch/$(ARCH) \ - -I$(INCLUDE_DIR)/bits$(BITSIZE) \ - -I$(GCCINCDIR) \ - -I$(LINUX_INCLUDE_DIR) - LIB_OBJS = - LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs -else - WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations - CRT0 = - LIBC = - CFLAGS += $(WARNINGS) -I$(GCCINCDIR) - LIB_OBJS = -lc - LDFLAGS = -endif - -ifeq ($(strip $(USE_SELINUX)),true) - CFLAGS += -DUSE_SELINUX - LIB_OBJS += -lselinux -endif - -CFLAGS += -I$(PWD)/libsysfs/sysfs \ - -I$(PWD)/libsysfs - -# config files automatically generated -GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf - -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(GEN_CONFIGS) - @extras="$(EXTRAS)" ; for target in $$extras ; do \ - echo $$target ; \ - $(MAKE) prefix=$(prefix) \ - LD="$(LD)" \ - SYSFS="$(SYSFS)" \ - KERNEL_DIR="$(KERNEL_DIR)" \ - QUIET="$(QUIET)" \ - -C $$target $@ ; \ - done ; \ - -$(ARCH_LIB_OBJS) : $(CRT0) - -$(CRT0): - @if [ ! -r klibc/linux ]; then \ - ln -f -s $(KERNEL_DIR) klibc/linux; \ - fi - $(MAKE) -C klibc SUBDIRS=klibc TESTS= - HEADERS = \ udev.h \ udev_utils.h \ @@ -228,12 +146,57 @@ UDEV_OBJS = \ namedev_parse.o OBJS = \ - udev.a \ + udev.a \ libsysfs/sysfs.a SYSFS = $(PWD)/libsysfs/sysfs.a +CFLAGS += -I$(PWD)/libsysfs/sysfs \ + -I$(PWD)/libsysfs + +ifeq ($(strip $(USE_LOG)),true) + CFLAGS += -DLOG +endif + +# if DEBUG is enabled, then we do not strip or optimize +ifeq ($(strip $(DEBUG)),true) + CFLAGS += -O1 -g -DDEBUG -D_GNU_SOURCE + LDFLAGS += -Wl,-warn-common + STRIPCMD = /bin/true -Since_we_are_debugging +else + CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE + LDFLAGS += -s -Wl,-warn-common + STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment +endif + +# If we are using our version of klibc, then we need to build, link it, and then +# link udev against it statically. Otherwise, use glibc and link dynamically. ifeq ($(strip $(USE_KLIBC)),true) + KLIBC_FIXUPS_DIR= $(PWD)/klibc_fixups + KLIBC_BASE = $(PWD)/klibc + KLIBC_DIR = $(KLIBC_BASE)/klibc + INCLUDE_DIR := $(KLIBC_BASE)/include + LINUX_INCLUDE_DIR := $(KERNEL_DIR)/include + include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG + # arch specific objects + ARCH_LIB_OBJS = $(KLIBC_DIR)/libc.a + + + CRT0 = $(KLIBC_DIR)/crt0.o + LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) + CFLAGS += $(WARNINGS) -nostdinc \ + $(OPTFLAGS) \ + -D__KLIBC__ -fno-builtin-printf \ + -I$(KLIBC_FIXUPS_DIR) \ + -include $(KLIBC_FIXUPS_DIR)/klibc_fixups.h \ + -I$(INCLUDE_DIR) \ + -I$(INCLUDE_DIR)/arch/$(ARCH) \ + -I$(INCLUDE_DIR)/bits$(BITSIZE) \ + -I$(GCCINCDIR) \ + -I$(LINUX_INCLUDE_DIR) + LIB_OBJS = + LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs + HEADERS += \ klibc_fixups/klibc_fixups.h \ klibc_fixups/mntent.h \ @@ -243,11 +206,19 @@ ifeq ($(strip $(USE_KLIBC)),true) klibc_fixups/klibc_fixups.o OBJS += klibc_fixups/klibc_fixups.a +else + WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations + CRT0 = + LIBC = + CFLAGS += $(WARNINGS) -I$(GCCINCDIR) + LIB_OBJS = -lc + LDFLAGS = endif ifeq ($(strip $(USE_SELINUX)),true) UDEV_OBJS += udev_selinux.o LIB_OBJS += -lselinux + CFLAGS += -DUSE_SELINUX endif ifeq ($(strip $(V)),false) @@ -258,6 +229,28 @@ else HOST_PROGS= endif +# config files automatically generated +GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf + +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(GEN_CONFIGS) + @extras="$(EXTRAS)" ; for target in $$extras ; do \ + echo $$target ; \ + $(MAKE) prefix=$(prefix) \ + LD="$(LD)" \ + SYSFS="$(SYSFS)" \ + KERNEL_DIR="$(KERNEL_DIR)" \ + QUIET="$(QUIET)" \ + -C $$target $@ ; \ + done ; \ + +$(ARCH_LIB_OBJS) : $(CRT0) + +$(CRT0): + @if [ ! -r klibc/linux ]; then \ + ln -f -s $(KERNEL_DIR) klibc/linux; \ + fi + $(MAKE) -C klibc SUBDIRS=klibc TESTS= + udev.a: $(UDEV_OBJS) rm -f $@ $(QUIET) $(AR) cq $@ $(UDEV_OBJS) From 51df9ee4965516b17dcd50647546ee970df87b32 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Feb 2005 02:44:37 +0100 Subject: [PATCH 1122/4284] [PATCH] Makefile: add some more warnings and prepare for clean gcc4 compile --- Makefile | 8 ++++++-- extras/volume_id/Makefile | 3 --- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index 052e41acc3..dc907f6a81 100644 --- a/Makefile +++ b/Makefile @@ -108,8 +108,12 @@ GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ then echo "-Os"; else echo "-O2" ; fi} -# add -Wredundant-decls when libsysfs gets cleaned up -WARNINGS := -Wall +# check if compiler option is supported +cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;} + +WARNINGS := -Wall -fno-builtin -Wchar-subscripts -Wpointer-arith -Wstrict-prototypes -Wsign-compare +WARNINGS += $(call cc-supports,-Wno-pointer-sign) +WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) CFLAGS := -pipe diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index f0c15b8fec..d273ed795c 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -28,9 +28,6 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-Wall -fno-builtin -Wchar-subscripts \ - -Wpointer-arith -Wcast-align -Wsign-compare - override CFLAGS+=-D_FILE_OFFSET_BITS=64 VOLUME_ID_OBJS= \ From 7979e3d4b7c56acee2fe0e9a9fefb3fe0d83771e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Feb 2005 04:10:48 +0100 Subject: [PATCH 1123/4284] [PATCH] udev_volume_id: volume_id version 032 --- extras/volume_id/Makefile | 2 + extras/volume_id/volume_id/cramfs/cramfs.c | 75 +++++++++++++++++++ extras/volume_id/volume_id/cramfs/cramfs.h | 26 +++++++ extras/volume_id/volume_id/fat/fat.c | 20 ++--- extras/volume_id/volume_id/hfs/hfs.c | 8 +- extras/volume_id/volume_id/iso9660/iso9660.c | 6 +- extras/volume_id/volume_id/jfs/jfs.c | 2 +- .../volume_id/linux_swap/linux_swap.c | 4 +- extras/volume_id/volume_id/lvm/lvm.c | 4 +- extras/volume_id/volume_id/mac/mac.c | 14 ++-- extras/volume_id/volume_id/msdos/msdos.c | 4 +- extras/volume_id/volume_id/ntfs/ntfs.c | 4 +- .../volume_id/volume_id/reiserfs/reiserfs.c | 6 +- extras/volume_id/volume_id/udf/udf.c | 18 ++--- extras/volume_id/volume_id/volume_id.c | 4 + extras/volume_id/volume_id/volume_id.h | 2 +- extras/volume_id/volume_id/xfs/xfs.c | 2 +- 17 files changed, 154 insertions(+), 47 deletions(-) create mode 100644 extras/volume_id/volume_id/cramfs/cramfs.c create mode 100644 extras/volume_id/volume_id/cramfs/cramfs.h diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index d273ed795c..bfe4cf74af 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -47,6 +47,7 @@ VOLUME_ID_OBJS= \ volume_id/udf/udf.o \ volume_id/ufs/ufs.o \ volume_id/xfs/xfs.o \ + volume_id/cramfs/cramfs.o \ volume_id/dasd/dasd.o \ volume_id/volume_id.o \ volume_id/util.o @@ -68,6 +69,7 @@ VOLUME_ID_HEADERS= \ volume_id/udf/udf.h \ volume_id/ufs/ufs.h \ volume_id/xfs/xfs.h \ + volume_id/cramfs/cramfs.h \ volume_id/dasd/dasd.h \ volume_id/volume_id.h \ volume_id/util.h diff --git a/extras/volume_id/volume_id/cramfs/cramfs.c b/extras/volume_id/volume_id/cramfs/cramfs.c new file mode 100644 index 0000000000..69ab2c7a44 --- /dev/null +++ b/extras/volume_id/volume_id/cramfs/cramfs.c @@ -0,0 +1,75 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "cramfs.h" + +struct cramfs_super { + __u8 magic[4]; + __u32 size; + __u32 flags; + __u32 future; + __u8 signature[16]; + struct cramfs_info { + __u32 crc; + __u32 edition; + __u32 blocks; + __u32 files; + } __attribute__((__packed__)) info; + __u8 name[16]; +} __attribute__((__packed__)); + +int volume_id_probe_cramfs(struct volume_id *id, __u64 off) +{ + struct cramfs_super *cs; + + 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) { + 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/extras/volume_id/volume_id/cramfs/cramfs.h b/extras/volume_id/volume_id/cramfs/cramfs.h new file mode 100644 index 0000000000..b94445b8b7 --- /dev/null +++ b/extras/volume_id/volume_id/cramfs/cramfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_CRAMFS_ +#define _VOLUME_ID_CRAMFS_ + +extern int volume_id_probe_cramfs(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/fat/fat.c b/extras/volume_id/volume_id/fat/fat.c index e6f01076ad..219207e81d 100644 --- a/extras/volume_id/volume_id/fat/fat.c +++ b/extras/volume_id/volume_id/fat/fat.c @@ -166,22 +166,22 @@ int volume_id_probe_vfat(struct volume_id *id, __u64 off) /* believe only that's fat, don't trust the version * the cluster_count will tell us */ - if (strncmp(vs->sysid, "NTFS", 4) == 0) + if (memcmp(vs->sysid, "NTFS", 4) == 0) return -1; - if (strncmp(vs->type.fat32.magic, "MSWIN", 5) == 0) + if (memcmp(vs->type.fat32.magic, "MSWIN", 5) == 0) goto valid; - if (strncmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) + if (memcmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) goto valid; - if (strncmp(vs->type.fat.magic, "FAT16 ", 8) == 0) + if (memcmp(vs->type.fat.magic, "FAT16 ", 8) == 0) goto valid; - if (strncmp(vs->type.fat.magic, "MSDOS", 5) == 0) + if (memcmp(vs->type.fat.magic, "MSDOS", 5) == 0) goto valid; - if (strncmp(vs->type.fat.magic, "FAT12 ", 8) == 0) + if (memcmp(vs->type.fat.magic, "FAT12 ", 8) == 0) goto valid; /* @@ -272,10 +272,10 @@ valid: if (vs == NULL) return -1; - if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { + if (label != NULL && memcmp(label, "NO NAME ", 11) != 0) { volume_id_set_label_raw(id, label, 11); volume_id_set_label_string(id, label, 11); - } else if (strncmp(vs->type.fat.label, "NO NAME ", 11) != 0) { + } 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); } @@ -333,10 +333,10 @@ fat32: if (vs == NULL) return -1; - if (label != NULL && strncmp(label, "NO NAME ", 11) != 0) { + if (label != NULL && memcmp(label, "NO NAME ", 11) != 0) { volume_id_set_label_raw(id, label, 11); volume_id_set_label_string(id, label, 11); - } else if (strncmp(vs->type.fat32.label, "NO NAME ", 11) != 0) { + } 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); } diff --git a/extras/volume_id/volume_id/hfs/hfs.c b/extras/volume_id/volume_id/hfs/hfs.c index 638aabadf2..a4ae86b56a 100644 --- a/extras/volume_id/volume_id/hfs/hfs.c +++ b/extras/volume_id/volume_id/hfs/hfs.c @@ -178,11 +178,11 @@ int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) return -1; hfs = (struct hfs_mdb *) buf; - if (strncmp(hfs->signature, "BD", 2) != 0) + if (memcmp(hfs->signature, "BD", 2) != 0) goto checkplus; /* it may be just a hfs wrapper for hfs+ */ - if (strncmp(hfs->embed_sig, "H+", 2) == 0) { + 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); @@ -216,9 +216,9 @@ int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) checkplus: hfsplus = (struct hfsplus_vol_header *) buf; - if (strncmp(hfsplus->signature, "H+", 2) == 0) + if (memcmp(hfsplus->signature, "H+", 2) == 0) goto hfsplus; - if (strncmp(hfsplus->signature, "HX", 2) == 0) + if (memcmp(hfsplus->signature, "HX", 2) == 0) goto hfsplus; return -1; diff --git a/extras/volume_id/volume_id/iso9660/iso9660.c b/extras/volume_id/volume_id/iso9660/iso9660.c index 6af9e8befc..fa769d3ca3 100644 --- a/extras/volume_id/volume_id/iso9660/iso9660.c +++ b/extras/volume_id/volume_id/iso9660/iso9660.c @@ -70,7 +70,7 @@ int volume_id_probe_iso9660(struct volume_id *id, __u64 off) if (is == NULL) return -1; - if (strncmp(is->iso.id, "CD001", 5) == 0) { + if (memcmp(is->iso.id, "CD001", 5) == 0) { char root_label[VOLUME_ID_LABEL_SIZE+1]; int vd_offset; int i; @@ -96,14 +96,14 @@ int volume_id_probe_iso9660(struct volume_id *id, __u64 off) } if (!found_svd || - (found_svd && !strncmp(root_label, id->label, 16))) + (found_svd && !memcmp(root_label, id->label, 16))) { volume_id_set_label_raw(id, root_label, 32); volume_id_set_label_string(id, root_label, 32); } goto found; } - if (strncmp(is->hs.id, "CDROM", 5) == 0) + if (memcmp(is->hs.id, "CDROM", 5) == 0) goto found; return -1; diff --git a/extras/volume_id/volume_id/jfs/jfs.c b/extras/volume_id/volume_id/jfs/jfs.c index 3e7e9d6aea..c9dce84ecb 100644 --- a/extras/volume_id/volume_id/jfs/jfs.c +++ b/extras/volume_id/volume_id/jfs/jfs.c @@ -60,7 +60,7 @@ int volume_id_probe_jfs(struct volume_id *id, __u64 off) if (js == NULL) return -1; - if (strncmp(js->magic, "JFS1", 4) != 0) + if (memcmp(js->magic, "JFS1", 4) != 0) return -1; volume_id_set_label_raw(id, js->label, 16); diff --git a/extras/volume_id/volume_id/linux_swap/linux_swap.c b/extras/volume_id/volume_id/linux_swap/linux_swap.c index 7ca4976078..d34b22c590 100644 --- a/extras/volume_id/volume_id/linux_swap/linux_swap.c +++ b/extras/volume_id/volume_id/linux_swap/linux_swap.c @@ -61,12 +61,12 @@ int volume_id_probe_linux_swap(struct volume_id *id, __u64 off) if (buf == NULL) return -1; - if (strncmp(buf, "SWAP-SPACE", 10) == 0) { + if (memcmp(buf, "SWAP-SPACE", 10) == 0) { strcpy(id->type_version, "1"); goto found; } - if (strncmp(buf, "SWAPSPACE2", 10) == 0) { + if (memcmp(buf, "SWAPSPACE2", 10) == 0) { sw = (struct swap_header_v1_2 *) volume_id_get_buffer(id, off, sizeof(struct swap_header_v1_2)); if (sw == NULL) return -1; diff --git a/extras/volume_id/volume_id/lvm/lvm.c b/extras/volume_id/volume_id/lvm/lvm.c index d95b6bf2d4..e736f4ed4a 100644 --- a/extras/volume_id/volume_id/lvm/lvm.c +++ b/extras/volume_id/volume_id/lvm/lvm.c @@ -56,7 +56,7 @@ int volume_id_probe_lvm1(struct volume_id *id, __u64 off) lvm = (struct lvm2_super_block *) buf; - if (strncmp(lvm->id, LVM1_MAGIC, 2) != 0) + if (memcmp(lvm->id, LVM1_MAGIC, 2) != 0) return -1; volume_id_set_usage(id, VOLUME_ID_RAID); @@ -89,7 +89,7 @@ int volume_id_probe_lvm2(struct volume_id *id, __u64 off) for (soff = 0; soff < LVM2LABEL_SCAN_SECTORS * 0x200; soff += 0x200) { lvm = (struct lvm2_super_block *) &buf[soff]; - if (strncmp(lvm->id, LVM2_LABEL_ID, 8) == 0) + if (memcmp(lvm->id, LVM2_LABEL_ID, 8) == 0) goto found; } diff --git a/extras/volume_id/volume_id/mac/mac.c b/extras/volume_id/volume_id/mac/mac.c index 7265b288ab..5872b722b4 100644 --- a/extras/volume_id/volume_id/mac/mac.c +++ b/extras/volume_id/volume_id/mac/mac.c @@ -64,8 +64,8 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) return -1; part = (struct mac_partition *) buf; - if ((strncmp(part->signature, "PM", 2) == 0) && - (strncmp(part->type, "Apple_partition_map", 19) == 0)) { + if ((memcmp(part->signature, "PM", 2) == 0) && + (memcmp(part->type, "Apple_partition_map", 19) == 0)) { /* linux creates an own subdevice for the map * just return the type if the drive header is missing */ volume_id_set_usage(id, VOLUME_ID_PARTITIONTABLE); @@ -74,7 +74,7 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) } driver = (struct mac_driver_desc *) buf; - if (strncmp(driver->signature, "ER", 2) == 0) { + if (memcmp(driver->signature, "ER", 2) == 0) { /* we are on a main device, like a CD * just try to probe the first partition from the map */ unsigned int bsize = be16_to_cpu(driver->block_size); @@ -87,7 +87,7 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) return -1; part = (struct mac_partition *) buf; - if (strncmp(part->signature, "PM", 2) != 0) + if (memcmp(part->signature, "PM", 2) != 0) return -1; part_count = be32_to_cpu(part->map_count); @@ -112,7 +112,7 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) return -1; part = (struct mac_partition *) buf; - if (strncmp(part->signature, "PM", 2) != 0) + if (memcmp(part->signature, "PM", 2) != 0) return -1; poff = be32_to_cpu(part->start_block) * bsize; @@ -123,9 +123,9 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) id->partitions[i].off = poff; id->partitions[i].len = plen; - if (strncmp(part->type, "Apple_Free", 10) == 0) { + if (memcmp(part->type, "Apple_Free", 10) == 0) { volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNUSED); - } else if (strncmp(part->type, "Apple_partition_map", 19) == 0) { + } else if (memcmp(part->type, "Apple_partition_map", 19) == 0) { volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_PARTITIONTABLE); } else { volume_id_set_usage_part(&id->partitions[i], VOLUME_ID_UNPROBED); diff --git a/extras/volume_id/volume_id/msdos/msdos.c b/extras/volume_id/volume_id/msdos/msdos.c index 915c1b2917..08124fad2d 100644 --- a/extras/volume_id/volume_id/msdos/msdos.c +++ b/extras/volume_id/volume_id/msdos/msdos.c @@ -84,7 +84,7 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) if (buf == NULL) return -1; - if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) return -1; /* check flags on all entries for a valid partition table */ @@ -158,7 +158,7 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET]; - if (strncmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) + if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) break; next = 0; diff --git a/extras/volume_id/volume_id/ntfs/ntfs.c b/extras/volume_id/volume_id/ntfs/ntfs.c index 4e1f508561..bf87f9d8d0 100644 --- a/extras/volume_id/volume_id/ntfs/ntfs.c +++ b/extras/volume_id/volume_id/ntfs/ntfs.c @@ -122,7 +122,7 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) if (ns == NULL) return -1; - if (strncmp(ns->oem_id, "NTFS", 4) != 0) + if (memcmp(ns->oem_id, "NTFS", 4) != 0) return -1; volume_id_set_uuid(id, ns->volume_serial, UUID_NTFS); @@ -153,7 +153,7 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) 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 (strncmp(mftr->magic, "FILE", 4) != 0) + if (memcmp(mftr->magic, "FILE", 4) != 0) goto found; attr_off = le16_to_cpu(mftr->attrs_offset); diff --git a/extras/volume_id/volume_id/reiserfs/reiserfs.c b/extras/volume_id/volume_id/reiserfs/reiserfs.c index 8fd8b51b59..5653214e9d 100644 --- a/extras/volume_id/volume_id/reiserfs/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs/reiserfs.c @@ -64,12 +64,12 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) if (rs == NULL) return -1; - if (strncmp(rs->magic, "ReIsEr2Fs", 9) == 0) { + if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) { strcpy(id->type_version, "3.6"); goto found; } - if (strncmp(rs->magic, "ReIsEr3Fs", 9) == 0) { + if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) { strcpy(id->type_version, "JR"); goto found; } @@ -78,7 +78,7 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) if (rs == NULL) return -1; - if (strncmp(rs->magic, "ReIsErFs", 8) == 0) { + if (memcmp(rs->magic, "ReIsErFs", 8) == 0) { strcpy(id->type_version, "3.5"); goto found; } diff --git a/extras/volume_id/volume_id/udf/udf.c b/extras/volume_id/volume_id/udf/udf.c index b91e3cce4e..ff23b31039 100644 --- a/extras/volume_id/volume_id/udf/udf.c +++ b/extras/volume_id/volume_id/udf/udf.c @@ -87,19 +87,19 @@ int volume_id_probe_udf(struct volume_id *id, __u64 off) if (vsd == NULL) return -1; - if (strncmp(vsd->id, "NSR02", 5) == 0) + if (memcmp(vsd->id, "NSR02", 5) == 0) goto blocksize; - if (strncmp(vsd->id, "NSR03", 5) == 0) + if (memcmp(vsd->id, "NSR03", 5) == 0) goto blocksize; - if (strncmp(vsd->id, "BEA01", 5) == 0) + if (memcmp(vsd->id, "BEA01", 5) == 0) goto blocksize; - if (strncmp(vsd->id, "BOOT2", 5) == 0) + if (memcmp(vsd->id, "BOOT2", 5) == 0) goto blocksize; - if (strncmp(vsd->id, "CD001", 5) == 0) + if (memcmp(vsd->id, "CD001", 5) == 0) goto blocksize; - if (strncmp(vsd->id, "CDW02", 5) == 0) + if (memcmp(vsd->id, "CDW02", 5) == 0) goto blocksize; - if (strncmp(vsd->id, "TEA03", 5) == 0) + if (memcmp(vsd->id, "TEA03", 5) == 0) goto blocksize; return -1; @@ -127,9 +127,9 @@ nsr: if (vsd->id[0] == '\0') return -1; - if (strncmp(vsd->id, "NSR02", 5) == 0) + if (memcmp(vsd->id, "NSR02", 5) == 0) goto anchor; - if (strncmp(vsd->id, "NSR03", 5) == 0) + if (memcmp(vsd->id, "NSR03", 5) == 0) goto anchor; } return -1; diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index e1d4b1c922..78aae37ba0 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -55,6 +55,7 @@ #include "linux_swap/linux_swap.h" #include "linux_raid/linux_raid.h" #include "lvm/lvm.h" +#include "cramfs/cramfs.h" #include "mac/mac.h" #include "msdos/msdos.h" @@ -116,6 +117,9 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_ntfs(id, off) == 0) goto exit; + if (volume_id_probe_cramfs(id, off) == 0) + goto exit; + return -1; exit: diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 6c25a243c3..a8c47bc616 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 31 +#define VOLUME_ID_VERSION 32 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 diff --git a/extras/volume_id/volume_id/xfs/xfs.c b/extras/volume_id/volume_id/xfs/xfs.c index b73f565eee..67ae2f07d5 100644 --- a/extras/volume_id/volume_id/xfs/xfs.c +++ b/extras/volume_id/volume_id/xfs/xfs.c @@ -60,7 +60,7 @@ int volume_id_probe_xfs(struct volume_id *id, __u64 off) if (xs == NULL) return -1; - if (strncmp(xs->magic, "XFSB", 4) != 0) + if (memcmp(xs->magic, "XFSB", 4) != 0) return -1; volume_id_set_label_raw(id, xs->fname, 12); From d9cf0b0a7c0b3549afe9cdcfc2d1d43a4bafe8a9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Feb 2005 05:23:26 +0100 Subject: [PATCH 1124/4284] [PATCH] udev_volume_id: rename probe_ibm into probe_dasd --- extras/volume_id/udev_volume_id.c | 13 +++++-------- extras/volume_id/volume_id/dasd/dasd.c | 2 +- extras/volume_id/volume_id/dasd/dasd.h | 2 +- extras/volume_id/volume_id/volume_id.h | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 915c1c4117..c2a37e8547 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -89,7 +89,7 @@ int main(int argc, char *argv[]) struct sysfs_class_device *class_dev_parent = NULL; struct volume_id *vid = NULL; char *devpath; - char probe = 'p'; + char probe_main_device = 0; char print = 'a'; static char name[VOLUME_ID_LABEL_SIZE]; int len, i, j; @@ -116,7 +116,7 @@ int main(int argc, char *argv[]) print = 'u'; continue; case 'd': - probe = 'd'; + probe_main_device = 1; continue; case 'h': case '?': @@ -146,8 +146,7 @@ int main(int argc, char *argv[]) goto exit; } - switch(probe) { - case 'p' : + if (probe_main_device == 0) { /* open block device */ vid = open_classdev(class_dev); if (vid == NULL) @@ -158,8 +157,7 @@ int main(int argc, char *argv[]) if (volume_id_probe_all(vid, 0, size) == 0) goto print; - break; - case 'd' : + } else { /* if we are on a partition, open main block device instead */ class_dev_parent = sysfs_get_classdev_parent(class_dev); if (class_dev_parent != NULL) @@ -169,9 +167,8 @@ int main(int argc, char *argv[]) if (vid == NULL) goto exit; - if (probe_ibm_partition(vid) == 0) + if (volume_id_probe_dasd_partition(vid) == 0) goto print; - break; } printf("unknown volume type\n"); diff --git a/extras/volume_id/volume_id/dasd/dasd.c b/extras/volume_id/volume_id/dasd/dasd.c index 6f045fe326..5623f69d36 100644 --- a/extras/volume_id/volume_id/dasd/dasd.c +++ b/extras/volume_id/volume_id/dasd/dasd.c @@ -160,7 +160,7 @@ typedef struct dasd_information_t { #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) #define BLKSSZGET _IO(0x12,104) -int probe_ibm_partition(struct volume_id *id) +int volume_id_probe_dasd_partition(struct volume_id *id) { int blocksize; dasd_information_t info; diff --git a/extras/volume_id/volume_id/dasd/dasd.h b/extras/volume_id/volume_id/dasd/dasd.h index eba73f1af0..e7918948c9 100644 --- a/extras/volume_id/volume_id/dasd/dasd.h +++ b/extras/volume_id/volume_id/dasd/dasd.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_DASDLABEL_ #define _VOLUME_ID_DASDLABEL_ -extern int probe_ibm_partition(struct volume_id *id); +extern int volume_id_probe_dasd_partition(struct volume_id *id); #endif diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index a8c47bc616..5a4b136c32 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 32 +#define VOLUME_ID_VERSION 33 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 From 0786e8e541dcc0a82a57c96569519815c38962f3 Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Sun, 6 Feb 2005 00:09:34 +0100 Subject: [PATCH 1125/4284] [PATCH] udevd: fix valgrind warning ==4304== Syscall param sigaction(act) contains uninitialised or unaddressable byte(s) ==4304== at 0x804A37B: (within /sbin/udevd) ==4304== Address 0x52BFE7FC is on thread 1's stack --- udevd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udevd.c b/udevd.c index 53c7bf3df1..7d7fd63332 100644 --- a/udevd.c +++ b/udevd.c @@ -690,6 +690,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("error fcntl on write pipe: %s", strerror(errno)); /* 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; From 3887557706fed195d85c958d5a07eb744b179e4c Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Sun, 6 Feb 2005 00:13:18 +0100 Subject: [PATCH 1126/4284] [PATCH] namdev: allow symlink-only rules to specify node permissions First case without the patch: KERNEL="hd*", GROUP="disk", MODE="0660" KERNEL="hdc", SYMLINK="cdrecorder", MODE="0666" brw-rw---- 1 root disk 22, 0 Feb 5 14:08 /dev/hdc Second case without the patch: KERNEL="hd*", GROUP="disk", MODE="0660" KERNEL="hdc", MODE="0666" brw-rw-rw- 1 root disk 22, 0 Feb 5 14:08 /dev/hdc --- namedev.c | 61 +++++++++++++++++++++++-------------------------------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/namedev.c b/namedev.c index 26c68fadf6..0c5d0509f9 100644 --- a/namedev.c +++ b/namedev.c @@ -670,7 +670,6 @@ try_parent: dbg("sysfs_device->path='%s'", sysfs_device->path); dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); } - } int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev) @@ -716,32 +715,32 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d list_for_each_entry(dev, &config_device_list, node) { dbg("process rule"); if (match_rule(udev, dev, class_dev, sysfs_device) == 0) { - if (dev->name[0] == '\0' && dev->symlink[0] == '\0') { - /* empty name, symlink, perms will not create any node */ - if (dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0') { - info("configured rule in '%s[%i]' applied, '%s' is ignored", - dev->config_file, dev->config_line, udev->kernel_name); - return -1; - } - /* apply permissions only rule values */ - if (dev->mode != 0000) { - udev->mode = dev->mode; - dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name); - } - if (dev->owner[0] != '\0') { - strfieldcpy(udev->owner, dev->owner); - apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); - dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); - } - if (dev->group[0] != '\0') { - strfieldcpy(udev->group, dev->group); - apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); - dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); - } + /* empty name, symlink and perms will not create any node */ + if (dev->name[0] == '\0' && dev->symlink[0] == '\0' && + dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0') { + info("configured rule in '%s[%i]' applied, '%s' is ignored", + dev->config_file, dev->config_line, udev->kernel_name); + return -1; } - /* collect symlinks for the final matching rule */ + /* apply permissions */ + if (dev->mode != 0000) { + udev->mode = dev->mode; + dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name); + } + if (dev->owner[0] != '\0') { + strfieldcpy(udev->owner, dev->owner); + apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); + dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); + } + if (dev->group[0] != '\0') { + strfieldcpy(udev->group, dev->group); + apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); + dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); + } + + /* collect symlinks for this or the final matching rule */ if (dev->symlink[0] != '\0') { char temp[NAME_SIZE]; @@ -774,19 +773,9 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d goto exit; udev->partitions = dev->partitions; - if (dev->mode != 0000) - udev->mode = dev->mode; - if (dev->owner[0] != '\0') { - strfieldcpy(udev->owner, dev->owner); - apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); - } - if (dev->group[0] != '\0') { - strfieldcpy(udev->group, dev->group); - apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); - } - dbg("name, '%s' is going to have owner='%s', group='%s', mode = %#o", - udev->name, udev->owner, udev->group, udev->mode); + 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); goto exit; } From c7a84d7556531f93c7f47f2bd9c820418cdad5d9 Mon Sep 17 00:00:00 2001 From: "sschweizer@gmail.com" Date: Sun, 6 Feb 2005 00:41:53 +0100 Subject: [PATCH 1127/4284] [PATCH] gentoo/udev.rules: add default permissions for sound devices --- etc/udev/gentoo/udev.rules | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 7f708b631f..b5f23902cb 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -12,6 +12,9 @@ # ########################################################### +# all block devices +SUBSYSTEM="block", GROUP="disk" + # cdrom symlinks and other good cdrom naming BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" @@ -32,6 +35,7 @@ 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" @@ -212,9 +216,6 @@ KERNEL="diskonkey*", NAME="%k", GROUP="disk" # rem_ide devices KERNEL="microdrive*", NAME="%k", GROUP="disk" -# all block devices -SUBSYSTEM="block", NAME="%k", GROUP="disk" - # kbd devices KERNEL="kbd", NAME="%k", MODE="0664" From 0c50db890e838b6fa21708836af93ea736fc047d Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Sun, 6 Feb 2005 01:00:04 +0100 Subject: [PATCH 1128/4284] [PATCH] cdsymlinks.sh: trivial fix, the variable is initialized to '', not 0 --- extras/cdsymlinks.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/cdsymlinks.sh b/extras/cdsymlinks.sh index e99be2e544..b2702e0063 100644 --- a/extras/cdsymlinks.sh +++ b/extras/cdsymlinks.sh @@ -159,7 +159,7 @@ output () { COUNT=$(($COUNT+1)) done # If the target dev ($1) is the current dev ($i), we output its name. - if test $(($NUMBERED_LINKS)) -ne 0 || test "$COUNT" -eq 0; then + if test $(($NUMBERED_LINKS)) -ne 0 || test "$COUNT" = ''; then test "$i" = "$1" && echo -n " $2$COUNT" fi # If the link isn't in our "existing links" list, add it and increment From fd3eeb7502d9ed52569bdb3e01a50ecbc132035e Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Sun, 6 Feb 2005 01:01:29 +0100 Subject: [PATCH 1129/4284] [PATCH] scsi_id: when udevstart is started, /tmp is not writeable. --- extras/scsi_id/scsi_id.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index d2155e6866..f45563d1b3 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -44,8 +44,8 @@ /* * temporary names for mknod. */ -#define TMP_DIR "/tmp" -#define TMP_PREFIX "scsi" +#define TMP_DIR "/dev" +#define TMP_PREFIX "tmp-scsi" /* * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout) From 882b97455b4f8e3859abc6e6357b0e233cf4a0c8 Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Sun, 6 Feb 2005 01:07:13 +0100 Subject: [PATCH 1130/4284] [PATCH] raid-devfs.sh: devfs names for hardware RAID controllers --- extras/raid-devfs.sh | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 extras/raid-devfs.sh diff --git a/extras/raid-devfs.sh b/extras/raid-devfs.sh new file mode 100644 index 0000000000..796232b497 --- /dev/null +++ b/extras/raid-devfs.sh @@ -0,0 +1,50 @@ +#!/bin/sh -e +# +# Copyright (c) 2004 Marco d'Itri +# Copyright (c) 2004 Piotr Roszatycki +# +# Usage: +# KERNEL="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +# KERNEL="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +# KERNEL="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" + +get_dev_number_cciss() { + grep '^cciss/' /proc/driver/cciss/* | cat -n | \ + sed -n "/cciss\/$1:/s/cciss.*//p" +} + +get_dev_number_ida() { + grep '^ida/' /proc/driver/cpqarray/* | cat -n | \ + sed -n "/ida\/$1:/s/ida.*//p" +} + +get_dev_number_rd() { + grep '^ */dev/rd/' /proc/rd/*/initial_status | cat -n | \ + sed -n "/rd\/$1:/s/\/dev\/rd.*//p" +} + +get_dev_number() { + dev=$1 + num=$(eval $(echo get_dev_number_$TYPE $dev)) + [ "$num" ] || exit 1 + echo $(($num - 1)) +} + +TYPE=${1%%/*} +NAME=${1#*/} + +# abort if there was no match +[ "$TYPE" != "$1" ] || exit 1 + +case "$NAME" in + *p*) + LONG_NAME=disc$(get_dev_number ${NAME%%p*})/part${NAME##*p} + ;; + *) + LONG_NAME=disc$(get_dev_number $NAME)/disc + ;; +esac + +echo "$TYPE/$LONG_NAME" +exit 0 + From 36429eef378dd5666eca49a21460e7b61f0b61f3 Mon Sep 17 00:00:00 2001 From: "md@Linux.IT" Date: Sun, 6 Feb 2005 01:08:31 +0100 Subject: [PATCH 1131/4284] [PATCH] debian: update rules files --- etc/udev/debian/devfs.rules | 175 ++++++++++++++++++++++--------- etc/udev/debian/udev.permissions | 121 --------------------- etc/udev/debian/udev.rules | 107 ++++++++++++++----- 3 files changed, 207 insertions(+), 196 deletions(-) delete mode 100644 etc/udev/debian/udev.permissions diff --git a/etc/udev/debian/devfs.rules b/etc/udev/debian/devfs.rules index 8d305cd657..cffef1a2e2 100644 --- a/etc/udev/debian/devfs.rules +++ b/etc/udev/debian/devfs.rules @@ -13,74 +13,152 @@ # %% the '%' char itself. # -# IDE block devices -BUS="ide", KERNEL="hd[a-z]*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +# default permissions for block devices +SUBSYSTEM="block", GROUP="disk" +SUBSYSTEM="block", SYSFS{removable}="1", GROUP="floppy" -# permissions for SCSI CD devices -BUS="scsi", KERNEL="s[grt][0-9]*", SYSFS{type}="5", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}", MODE="0660", GROUP="cdrom" +# workaround for devices which do not report media changes +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/model", RESULT="IOMEGA ZIP *", \ + NAME{all_partitions}="%k%n", GROUP="floppy" -# SCSI block devices -BUS="scsi", KERNEL="sd[a-z]", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="sd[a-z][0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="sd[a-i][a-z]", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="sd[a-i][a-z][0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="s[grt][0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="st[0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="nst[0-9]*", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", NAME="%c{1}", SYMLINK="%k %c{2}" +# IDE devices +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", \ + GROUP="cdrom" +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", \ + GROUP="floppy" +BUS="ide", KERNEL="hd[a-z]*", \ + PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="ide", KERNEL="ht[0-9]*", GROUP="tape" +BUS="ide", KERNEL="nht[0-9]*", GROUP="tape" + +# SCSI devices +BUS="scsi", KERNEL="sd[a-z]", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="sd[a-z][0-9]*", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="sd[a-i][a-z]", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="sd[a-i][a-z][0-9]*", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="s[gr][0-9]*", SYSFS{type}="5", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="cdrom" +BUS="scsi", KERNEL="sr[0-9]*", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="cdrom" +BUS="scsi", KERNEL="sg[0-9]*", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" +BUS="scsi", KERNEL="st[0-9]*", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="tape" +BUS="scsi", KERNEL="nst[0-9]*", \ + PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="tape" + +# RAID controllers +KERNEL="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ + NAME="%c{1}", SYMLINK="%k" +KERNEL="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ + NAME="%c{1}", SYMLINK="%k" +KERNEL="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ + 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 BUS="usb", KERNEL="hiddev*", NAME="usb/%k" -BUS="usb", KERNEL="auer*", NAME="usb/%k" -BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" +BUS="usb", KERNEL="auer[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="legousbtower*", NAME="usb/%k", MODE="0666" BUS="usb", KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="ttyUSB*", SYSFS{product}="Palm Handheld*", SYMLINK="pilot" -# block devices -KERNEL="md[0-9]*", NAME="md/%n", -KERNEL="loop[0-9]*", NAME="loop/%n" - -# tty devices -KERNEL="tty[0-9]*", NAME="vc/%n" +# serial devices +SUBSYSTEM="tty", GROUP="dialout" KERNEL="ttyS[0-9]*", NAME="tts/%n" KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" -KERNEL="rfcomm[0-9]*", NAME="bluetooth/rfcomm/%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="ptmx", MODE="0666" +KERNEL="tty", MODE="0666" +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" -KERNEL="fb[0-9]*", NAME="fb/%n", -# v4l devices -KERNEL="video[0-9]*", NAME="v4l/video%n" -KERNEL="radio[0-9]*", NAME="v4l/radio%n" -KERNEL="vbi[0-9]*", NAME="v4l/vbi%n" -KERNEL="vtx[0-9]*", NAME="v4l/vtx%n" -KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" +# video devices +SUBSYSTEM="video4linux", GROUP="video" +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="/etc/udev/scripts/dvb.sh %k", \ + NAME="%c", GROUP="video" +KERNEL="fb[0-9]*", NAME="fb/%n", GROUP="video" +KERNEL="nvidia*", GROUP="video" +KERNEL="card[0-9]*", NAME="dri/%k", GROUP="video" # misc devices -KERNEL="apm_bios", NAME="misc/apm_bios", -KERNEL="agpgart", NAME="misc/agpgart", -KERNEL="nvram", NAME="misc/nvram" -KERNEL="psaux", NAME="misc/psaux" -KERNEL="rtc", NAME="misc/rtc" +KERNEL="random", MODE="0666" +KERNEL="urandom", MODE="0444" +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="apm_bios", NAME="misc/%k", +KERNEL="agpgart", NAME="misc/%k", GROUP="video" +KERNEL="nvram", NAME="misc/%k", GROUP="nvram" +KERNEL="psaux", NAME="misc/%k" +KERNEL="rtc", NAME="misc/%k", MODE="0644", GROUP="audio" +KERNEL="hw_random", NAME="hwrng" -KERNEL="card[0-9]*", NAME="dri/card%n" -KERNEL="i2c-[0-9]*", NAME="i2c/%n" -KERNEL="ram[0-9]*", NAME="rd/%n" +# printers and parallel devices +SUBSYSTEM="printer", GROUP="lp" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" KERNEL="lp[0-9]*", NAME="printers/%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="pt[0-9]*", GROUP="tape" +KERNEL="pht[0-9]*", GROUP="tape" + +KERNEL="i2c-[0-9]*", NAME="i2c/%n" +KERNEL="fd[0-9]*", NAME="floppy/%n", GROUP="floppy" + +KERNEL="cdemu[0-9]*", NAME="cdemu/%n", GROUP="cdrom" +KERNEL="pktcdvd[0-9]*", NAME="pktcdvd/%n", GROUP="cdrom" +KERNEL="pktcdvd", NAME="pktcdvd/control", MODE="0644" + 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="tap[0-9]*", NAME="net/%k" +KERNEL="tun", NAME="net/%k" + # sound devices +SUBSYSTEM="sound", GROUP="audio" KERNEL="controlC[0-9]*", NAME="snd/%k" KERNEL="hwC[D0-9]*", NAME="snd/%k" KERNEL="pcmC[D0-9cp]*", NAME="snd/%k" @@ -100,19 +178,14 @@ KERNEL="admmidi*", NAME="sound/%k" # input devices KERNEL="mice", NAME="input/%k" KERNEL="mouse[0-9]*", NAME="input/%k" -KERNEL="event[0-9]*", NAME="input/%k", PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", MODE="0664", GROUP="video" +KERNEL="event[0-9]*", NAME="input/%k", \ + PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", \ + MODE="0664", GROUP="video" KERNEL="event[0-9]*", NAME="input/%k" -KERNEL="js[0-9]*", NAME="input/%k" +KERNEL="js[0-9]*", NAME="input/%k", MODE="0664" KERNEL="ts[0-9]*", NAME="input/%k" KERNEL="uinput", NAME="input/%k" -KERNEL="tap[0-9]*", NAME="net/%k" -KERNEL="tun", NAME="net/%k" - -# CAPI devices -KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" -KERNEL="capi[0-9]*", NAME="capi/%n" - # Zaptel KERNEL="zapctl", NAME="zap/ctl" KERNEL="zaptimer", NAME="zap/timer" diff --git a/etc/udev/debian/udev.permissions b/etc/udev/debian/udev.permissions deleted file mode 100644 index 6429519eec..0000000000 --- a/etc/udev/debian/udev.permissions +++ /dev/null @@ -1,121 +0,0 @@ -# name:user:group:mode - -# character devices - -ptmx:root:tty:0666 -random:root:root:0666 -urandom:root:root:0444 -kmem:root:kmem:0640 -mem:root:kmem:0640 -port:root:kmem:0640 -null:root:root:0666 -zero:root:root:0666 -full:root:root:0666 - -misc/nvram:root:nvram:660 -nvram:root:nvram:660 -misc/rtc:root:audio:0664 -rtc:root:audio:0664 - -tts/*:root:dialout:0660 -bluetooth/rfcomm/*:root:dialout:0660 -tty[BCDEFHILMPRSTUVWX][0-9]*:root:dialout:0660 -ttyS[ACIR][0-9]*:root:dialout:0660 -ttyUSB[0-9]*:root:dialout:0660 -ttyACM[0-9]*:root:dialout:0660 -ippp[0-9]*:root:dialout:0660 -isdn[0-9]*:root:dialout:0660 -isdnctrl[0-9]*:root:dialout:0660 -capi[0-9.]*:root:dialout:0660 -dcbri[0-9]*:root:dialout:0660 -ircomm[0-9]*:root:dialout:0660 -rfcomm[0-9]*:root:dialout:0660 -tty:root:tty:0666 - -snd/*:root:audio:0660 -sound/*:root:audio:0660 -admmidi*:root:audio:0660 -adsp*:root:audio:0660 -aload*:root:audio:0660 -amidi*:root:audio:0660 -amixer*:root:audio:0660 -audio*:root:audio:0660 -dmfm*:root:audio:0660 -dsp*:root:audio:0660 -audio*:root:audio:0660 -mixer*:root:audio:0660 -music:root:audio:0660 -sequencer*:root:audio:0660 - -printers/*:root:lp:0660 -usb/lp[0-9]*:root:lp:0660 -usb/legousbtower[0-9]*:root:root:666 -lp[0-9]*:root:lp:0660 -parport[0-9]*:root:lp:0660 -irlpt[0-9]*:root:lp:0660 -usblp[0-9]*:root:lp:0660 - -input/mice:root:root:0600 -input/mouse[0-9]*:root:root:0600 -input/js[0-9]*:root:root:0644 -input/*:root:root:0600 -mouse[0-9]*:root:root:0600 -js[0-9]*:root:root:0644 - -dri/card[0-9]*:root:video:0660 -fb/*:root:video:0660 -fb[0-9]*:root:video:0660 -agpgart:root:video:0660 -nvidia*:root:video:0660 - -v4l/*:root:video:0660 -video[0-9]*:root:video:0660 -radio[0-9]*:root:video:0660 -vbi[0-9]*:root:video:0660 -vtx[0-9]*:root:video:0660 -dvb/*:root:video:0660 - -# block devices - -floppy/*:root:floppy:0660 -fd[0-9]*:root:floppy:0660 -cdemu/*:root:cdrom:0660 -pktcdvd[0-9]*:root:cdrom:0660 - -ram[0-9]*:root:disk:0660 -raw/*:root:disk:0660 - -ide/*/cd:root:cdrom:0660 -ide/*:root:disk:0660 -hd[a-s]:root:disk:0660 -hd[a-s][0-9]*:root:disk:0660 - -scsi/*/cd:root:cdrom:0660 -scsi/*:root:disk:0660 -sd[a-z]:root:disk:0660 -sd[a-z][0-9]*:root:disk:0660 -sd[a-i][a-z]:root:disk:0660 -sd[a-i][a-z][0-9]*:root:disk:0660 -s[gr][0-9]*:root:disk:0660 -scd[0-9]*:root:cdrom:0660 - -dasd[0-9]*:root:disk:0660 -ataraid[0-9]*:root:disk:0660 - -loop/*:root:disk:0660 -loop[0-9]*:root:disk:0660 -md/*:root:disk:0660 -md[0-9]*:root:disk:0660 -dm-*:root:disk:0640 - -ht[0-9]*:root:tape:0660 -nht[0-9]*:root:tape:0660 -pt[0-9]*:root:tape:0660 -npt[0-9]*:root:tape:0660 -st[0-9]*:root:tape:0660 -nst[0-9]*:root:tape:0660 - -sgi_fetchop:root:root:666 -iseries/vcd*:root:disk:660 -iseries/vd*:root:disk:660 - diff --git a/etc/udev/debian/udev.rules b/etc/udev/debian/udev.rules index 65a89ae593..0f7aeb73d4 100644 --- a/etc/udev/debian/udev.rules +++ b/etc/udev/debian/udev.rules @@ -13,36 +13,100 @@ # %% the '%' char itself. # -# permissions for IDE CD devices -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", NAME="%k", MODE="0660", GROUP="cdrom" +# default permissions for block devices +SUBSYSTEM="block", GROUP="disk" +SUBSYSTEM="block", SYSFS{removable}="1", GROUP="floppy" -# permissions for IDE floppy devices -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", NAME="%k", MODE="0660", GROUP="floppy" +# workaround for devices which do not report media changes +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/model", RESULT="IOMEGA ZIP *", \ + NAME{all_partitions}="%k%n", GROUP="floppy" -# permissions for SCSI CD devices -BUS="scsi", KERNEL="sr[0-9]*", SYSFS{type}="5", NAME="scd%n", MODE="0660", GROUP="cdrom", SYMLINK="sr%n" -BUS="scsi", KERNEL="sg[0-9]*", SYSFS{type}="5", NAME="%k", MODE="0660", GROUP="cdrom" +# IDE devices +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", \ + GROUP="cdrom" +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", \ + GROUP="floppy" +BUS="ide", KERNEL="ht[0-9]*", GROUP="tape" +BUS="ide", KERNEL="nht[0-9]*", GROUP="tape" +# SCSI devices +BUS="scsi", KERNEL="sr[0-9]*", SYSFS{type}="5", \ + NAME="scd%n", SYMLINK="sr%n", GROUP="cdrom" +BUS="scsi", KERNEL="sg[0-9]*", SYSFS{type}="5", GROUP="cdrom" +BUS="scsi", KERNEL="st[0-9]*", GROUP="tape" +BUS="scsi", KERNEL="nst[0-9]*", GROUP="tape" +BUS="scsi", KERNEL="osst[0-9]*", GROUP="tape" +BUS="scsi", KERNEL="nosst[0-9]*", GROUP="tape" # USB devices BUS="usb", KERNEL="hiddev*", NAME="usb/%k" -BUS="usb", KERNEL="auer*", NAME="usb/%k" -BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" +BUS="usb", KERNEL="auer[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="legousbtower*", NAME="usb/%k", MODE="0666" BUS="usb", KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="ttyUSB*", SYSFS{product}="Palm Handheld*", SYMLINK="pilot" -KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" +# serial devices +SUBSYSTEM="tty", GROUP="dialout" +KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" +KERNEL="capi[0-9]*", NAME="capi/%n" + +# vc devices +KERNEL="ptmx", MODE="0666" +KERNEL="tty", MODE="0666" + +# video devices +SUBSYSTEM="video4linux", GROUP="video" +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", \ + NAME="%c", GROUP="video" +KERNEL="fb[0-9]*", GROUP="video" +KERNEL="nvidia*", GROUP="video" +KERNEL="card[0-9]*", NAME="dri/%k", GROUP="video" + +# misc devices +KERNEL="random", MODE="0666" +KERNEL="urandom", MODE="0444" +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", MODE="0664", GROUP="audio" +KERNEL="hw_random", NAME="hwrng" + +# printers and parallel devices +SUBSYSTEM="printer", GROUP="lp" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" +KERNEL="pt[0-9]*", GROUP="tape" +KERNEL="pht[0-9]*", GROUP="tape" + +KERNEL="fd[0-9]*", GROUP="floppy" + +KERNEL="cdemu[0-9]*", NAME="cdemu/%n", GROUP="cdrom" +KERNEL="pktcdvd[0-9]*", NAME="pktcdvd/%n", GROUP="cdrom" +KERNEL="pktcdvd", NAME="pktcdvd/control", MODE="0644" -KERNEL="card*", NAME="dri/card%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="tap[0-9]*", NAME="net/%k" +KERNEL="tun", NAME="net/%k" + # ALSA devices +SUBSYSTEM="sound", GROUP="audio" KERNEL="controlC[0-9]*", NAME="snd/%k" KERNEL="hwC[D0-9]*", NAME="snd/%k" KERNEL="pcmC[D0-9cp]*", NAME="snd/%k" @@ -53,19 +117,14 @@ KERNEL="seq", NAME="snd/%k" # input devices KERNEL="mice", NAME="input/%k" KERNEL="mouse[0-9]*", NAME="input/%k" -KERNEL="event[0-9]*", NAME="input/%k", PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", MODE="0664", GROUP="video" +KERNEL="event[0-9]*", NAME="input/%k", \ + PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", \ + MODE="0664", GROUP="video" KERNEL="event[0-9]*", NAME="input/%k" -KERNEL="js[0-9]*", NAME="input/%k" +KERNEL="js[0-9]*", NAME="input/%k", MODE="0664" KERNEL="ts[0-9]*", NAME="input/%k" KERNEL="uinput", NAME="input/%k" -KERNEL="tap[0-9]*", NAME="net/%k" -KERNEL="tun", NAME="net/%k" - -# CAPI devices -KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" -KERNEL="capi[0-9]*", NAME="capi/%n" - # Zaptel KERNEL="zapctl", NAME="zap/ctl" KERNEL="zaptimer", NAME="zap/timer" From 85925517e67b85c94180b1de5e2cbd6a1c67c54c Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Sun, 6 Feb 2005 01:39:25 +0100 Subject: [PATCH 1132/4284] [PATCH] trivial: fix signedness We are already using %u in the sscanf() format string. The patch replaces the int for the kernel release number with unsigned int, as we can never have negative release numbers. --- udev_utils.c | 8 ++++---- udev_utils.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/udev_utils.c b/udev_utils.c index 3c5344a8f9..364037f7a9 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -62,11 +62,11 @@ void udev_init_device(struct udevice *udev, const char* devpath, const char *sub strcpy(udev->group, "root"); } -int kernel_release_satisfactory(int version, int patchlevel, int sublevel) +int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel) { - static int kversion = 0; - static int kpatchlevel; - static int ksublevel; + static unsigned int kversion = 0; + static unsigned int kpatchlevel; + static unsigned int ksublevel; if (kversion == 0) { struct utsname uts; diff --git a/udev_utils.h b/udev_utils.h index cc9dd704de..5d2c9c580c 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -77,7 +77,7 @@ do { \ #endif extern void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); -extern int kernel_release_satisfactory(int version, int patchlevel, int sublevel); +extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); extern int parse_get_pair(char **orig_string, char **left, char **right); extern int file_map(const char *filename, char **buf, size_t *bufsize); From e39515ac1fd303c0263ee4bc91f2d7699617d0bf Mon Sep 17 00:00:00 2001 From: "mbuesch@freenet.de" Date: Sun, 6 Feb 2005 03:23:43 +0100 Subject: [PATCH 1133/4284] [PATCH] trivial: remove _all_ trailing slashes with no_trailing_slash() This changes no_trailing_slash() to remove all trailing slashes and not just the last one. --- udev_utils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/udev_utils.c b/udev_utils.c index 364037f7a9..5b0355d0e9 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -200,11 +200,11 @@ size_t buf_get_line(const char *buf, size_t buflen, size_t cur) void no_trailing_slash(char *path) { - int len; + size_t len; len = strlen(path); - if (len > 0 && path[len-1] == '/') - path[len-1] = '\0'; + while (len > 0 && path[len-1] == '/') + path[--len] = '\0'; } struct files { From 9d4791b66a7756421fc699be51a7be68a5aed329 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 9 Feb 2005 01:02:18 +0100 Subject: [PATCH 1134/4284] [PATCH] udev_volume_id: volume_id version 034 --- extras/volume_id/Makefile | 45 +-- extras/volume_id/volume_id/Makefile.inc | 48 +++ extras/volume_id/volume_id/cramfs/cramfs.c | 2 + extras/volume_id/volume_id/dasd/dasd.c | 5 +- extras/volume_id/volume_id/ext/ext.c | 40 +-- extras/volume_id/volume_id/fat/fat.c | 2 + extras/volume_id/volume_id/hfs/hfs.c | 216 +++++++------- .../volume_id/volume_id/highpoint/highpoint.c | 16 +- extras/volume_id/volume_id/hpfs/hpfs.c | 69 +++++ extras/volume_id/volume_id/hpfs/hpfs.h | 26 ++ extras/volume_id/volume_id/iso9660/iso9660.c | 36 ++- extras/volume_id/volume_id/jfs/jfs.c | 28 +- .../volume_id/linux_raid/linux_raid.c | 40 +-- .../volume_id/linux_swap/linux_swap.c | 20 +- extras/volume_id/volume_id/lvm/lvm.c | 32 +- extras/volume_id/volume_id/mac/mac.c | 36 ++- extras/volume_id/volume_id/msdos/msdos.c | 29 +- extras/volume_id/volume_id/ntfs/ntfs.c | 118 ++++---- .../volume_id/volume_id/reiserfs/reiserfs.c | 34 ++- extras/volume_id/volume_id/romfs/romfs.c | 73 +++++ extras/volume_id/volume_id/romfs/romfs.h | 26 ++ extras/volume_id/volume_id/sysv/sysv.c | 146 +++++++++ extras/volume_id/volume_id/sysv/sysv.h | 26 ++ extras/volume_id/volume_id/udf/udf.c | 70 ++--- extras/volume_id/volume_id/ufs/ufs.c | 277 +++++++++--------- extras/volume_id/volume_id/util.h | 4 + extras/volume_id/volume_id/volume_id.c | 8 + extras/volume_id/volume_id/volume_id.h | 2 +- extras/volume_id/volume_id/xfs/xfs.c | 32 +- 29 files changed, 974 insertions(+), 532 deletions(-) create mode 100644 extras/volume_id/volume_id/Makefile.inc create mode 100644 extras/volume_id/volume_id/hpfs/hpfs.c create mode 100644 extras/volume_id/volume_id/hpfs/hpfs.h create mode 100644 extras/volume_id/volume_id/romfs/romfs.c create mode 100644 extras/volume_id/volume_id/romfs/romfs.h create mode 100644 extras/volume_id/volume_id/sysv/sysv.c create mode 100644 extras/volume_id/volume_id/sysv/sysv.h diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index bfe4cf74af..9c274212a6 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -30,49 +30,8 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} override CFLAGS+=-D_FILE_OFFSET_BITS=64 -VOLUME_ID_OBJS= \ - volume_id/ext/ext.o \ - volume_id/fat/fat.o \ - volume_id/hfs/hfs.o \ - volume_id/highpoint/highpoint.o \ - volume_id/iso9660/iso9660.o \ - volume_id/jfs/jfs.o \ - volume_id/linux_raid/linux_raid.o \ - volume_id/linux_swap/linux_swap.o \ - volume_id/lvm/lvm.o \ - volume_id/mac/mac.o \ - volume_id/msdos/msdos.o \ - volume_id/ntfs/ntfs.o \ - volume_id/reiserfs/reiserfs.o \ - volume_id/udf/udf.o \ - volume_id/ufs/ufs.o \ - volume_id/xfs/xfs.o \ - volume_id/cramfs/cramfs.o \ - volume_id/dasd/dasd.o \ - volume_id/volume_id.o \ - volume_id/util.o - -VOLUME_ID_HEADERS= \ - volume_id/ext/ext.h \ - volume_id/fat/fat.h \ - volume_id/hfs/hfs.h \ - volume_id/highpoint/highpoint.h \ - volume_id/iso9660/iso9660.h \ - volume_id/jfs/jfs.h \ - volume_id/linux_raid/linux_raid.h \ - volume_id/linux_swap/linux_swap.h \ - volume_id/lvm/lvm.h \ - volume_id/mac/mac.h \ - volume_id/msdos/msdos.h \ - volume_id/ntfs/ntfs.h \ - volume_id/reiserfs/reiserfs.h \ - volume_id/udf/udf.h \ - volume_id/ufs/ufs.h \ - volume_id/xfs/xfs.h \ - volume_id/cramfs/cramfs.h \ - volume_id/dasd/dasd.h \ - volume_id/volume_id.h \ - volume_id/util.h +VOLUME_ID_BASE=volume_id +include $(VOLUME_ID_BASE)/Makefile.inc OBJS = udev_volume_id.o $(VOLUME_ID_OBJS) $(SYSFS) HEADERS = $(VOLUME_ID_HEADERS) diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc new file mode 100644 index 0000000000..d010f7778e --- /dev/null +++ b/extras/volume_id/volume_id/Makefile.inc @@ -0,0 +1,48 @@ +VOLUME_ID_OBJS= \ + $(VOLUME_ID_BASE)/ext/ext.o \ + $(VOLUME_ID_BASE)/fat/fat.o \ + $(VOLUME_ID_BASE)/hfs/hfs.o \ + $(VOLUME_ID_BASE)/highpoint/highpoint.o \ + $(VOLUME_ID_BASE)/iso9660/iso9660.o \ + $(VOLUME_ID_BASE)/jfs/jfs.o \ + $(VOLUME_ID_BASE)/linux_raid/linux_raid.o \ + $(VOLUME_ID_BASE)/linux_swap/linux_swap.o \ + $(VOLUME_ID_BASE)/lvm/lvm.o \ + $(VOLUME_ID_BASE)/mac/mac.o \ + $(VOLUME_ID_BASE)/msdos/msdos.o \ + $(VOLUME_ID_BASE)/ntfs/ntfs.o \ + $(VOLUME_ID_BASE)/reiserfs/reiserfs.o \ + $(VOLUME_ID_BASE)/udf/udf.o \ + $(VOLUME_ID_BASE)/ufs/ufs.o \ + $(VOLUME_ID_BASE)/xfs/xfs.o \ + $(VOLUME_ID_BASE)/cramfs/cramfs.o \ + $(VOLUME_ID_BASE)/hpfs/hpfs.o \ + $(VOLUME_ID_BASE)/romfs/romfs.o \ + $(VOLUME_ID_BASE)/sysv/sysv.o \ + $(VOLUME_ID_BASE)/dasd/dasd.o \ + $(VOLUME_ID_BASE)/volume_id.o \ + $(VOLUME_ID_BASE)/util.o + +VOLUME_ID_HEADERS= \ + $(VOLUME_ID_BASE)/ext/ext.h \ + $(VOLUME_ID_BASE)/fat/fat.h \ + $(VOLUME_ID_BASE)/hfs/hfs.h \ + $(VOLUME_ID_BASE)/highpoint/highpoint.h \ + $(VOLUME_ID_BASE)/iso9660/iso9660.h \ + $(VOLUME_ID_BASE)/jfs/jfs.h \ + $(VOLUME_ID_BASE)/linux_raid/linux_raid.h \ + $(VOLUME_ID_BASE)/linux_swap/linux_swap.h \ + $(VOLUME_ID_BASE)/lvm/lvm.h \ + $(VOLUME_ID_BASE)/mac/mac.h \ + $(VOLUME_ID_BASE)/msdos/msdos.h \ + $(VOLUME_ID_BASE)/ntfs/ntfs.h \ + $(VOLUME_ID_BASE)/reiserfs/reiserfs.h \ + $(VOLUME_ID_BASE)/udf/udf.h \ + $(VOLUME_ID_BASE)/ufs/ufs.h \ + $(VOLUME_ID_BASE)/xfs/xfs.h \ + $(VOLUME_ID_BASE)/cramfs/cramfs.h \ + $(VOLUME_ID_BASE)/sysv/sysv.h \ + $(VOLUME_ID_BASE)/romfs/romfs.h \ + $(VOLUME_ID_BASE)/dasd/dasd.h \ + $(VOLUME_ID_BASE)/volume_id.h \ + $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/cramfs/cramfs.c b/extras/volume_id/volume_id/cramfs/cramfs.c index 69ab2c7a44..a1d51f107d 100644 --- a/extras/volume_id/volume_id/cramfs/cramfs.c +++ b/extras/volume_id/volume_id/cramfs/cramfs.c @@ -58,6 +58,8 @@ int volume_id_probe_cramfs(struct volume_id *id, __u64 off) { struct cramfs_super *cs; + dbg("probing at offset %llu", off); + cs = (struct cramfs_super *) volume_id_get_buffer(id, off, 0x200); if (cs == NULL) return -1; diff --git a/extras/volume_id/volume_id/dasd/dasd.c b/extras/volume_id/volume_id/dasd/dasd.c index 5623f69d36..4548190ce2 100644 --- a/extras/volume_id/volume_id/dasd/dasd.c +++ b/extras/volume_id/volume_id/dasd/dasd.c @@ -35,6 +35,7 @@ #include #include "../volume_id.h" +#include "../logging.h" #include "../util.h" #include "dasd.h" @@ -141,7 +142,7 @@ typedef struct dasd_information_t { unsigned int confdata_size; char characteristics[64]; /* from read_device_characteristics */ char configuration_data[256]; /* from read_configuration_data */ -} dasd_information_t; +} __attribute__((__packed__)) dasd_information_t; #define _IOC_NRBITS 8 #define _IOC_TYPEBITS 8 @@ -168,6 +169,8 @@ int volume_id_probe_dasd_partition(struct volume_id *id) __u8 *label_raw; unsigned char name[7]; + dbg("probing"); + if (ioctl(id->fd, BIODASDINFO, &info) != 0) return -1; diff --git a/extras/volume_id/volume_id/ext/ext.c b/extras/volume_id/volume_id/ext/ext.c index 50ffa85372..0940e452fc 100644 --- a/extras/volume_id/volume_id/ext/ext.c +++ b/extras/volume_id/volume_id/ext/ext.c @@ -39,30 +39,34 @@ #include "../logging.h" #include "ext.h" +struct ext2_super_block { + __u32 inodes_count; + __u32 blocks_count; + __u32 r_blocks_count; + __u32 free_blocks_count; + __u32 free_inodes_count; + __u32 first_data_block; + __u32 log_block_size; + __u32 dummy3[7]; + __u8 magic[2]; + __u16 state; + __u32 dummy5[8]; + __u32 feature_compat; + __u32 feature_incompat; + __u32 feature_ro_compat; + __u8 uuid[16]; + __u8 volume_name[16]; +} __attribute__((__packed__)); + #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 #define EXT_SUPERBLOCK_OFFSET 0x400 int volume_id_probe_ext(struct volume_id *id, __u64 off) { - struct ext2_super_block { - __u32 inodes_count; - __u32 blocks_count; - __u32 r_blocks_count; - __u32 free_blocks_count; - __u32 free_inodes_count; - __u32 first_data_block; - __u32 log_block_size; - __u32 dummy3[7]; - __u8 magic[2]; - __u16 state; - __u32 dummy5[8]; - __u32 feature_compat; - __u32 feature_incompat; - __u32 feature_ro_compat; - __u8 uuid[16]; - __u8 volume_name[16]; - } __attribute__((__packed__)) *es; + struct ext2_super_block *es; + + dbg("probing at offset %llu", off); es = (struct ext2_super_block *) volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); if (es == NULL) diff --git a/extras/volume_id/volume_id/fat/fat.c b/extras/volume_id/volume_id/fat/fat.c index 219207e81d..c6bb491f70 100644 --- a/extras/volume_id/volume_id/fat/fat.c +++ b/extras/volume_id/volume_id/fat/fat.c @@ -159,6 +159,8 @@ int volume_id_probe_vfat(struct volume_id *id, __u64 off) __u32 next; int maxloop; + dbg("probing at offset %llu", off); + vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); if (vs == NULL) return -1; diff --git a/extras/volume_id/volume_id/hfs/hfs.c b/extras/volume_id/volume_id/hfs/hfs.c index a4ae86b56a..905471cb35 100644 --- a/extras/volume_id/volume_id/hfs/hfs.c +++ b/extras/volume_id/volume_id/hfs/hfs.c @@ -39,119 +39,119 @@ #include "../util.h" #include "hfs.h" +struct hfs_finder_info{ + __u32 boot_folder; + __u32 start_app; + __u32 open_folder; + __u32 os9_folder; + __u32 reserved; + __u32 osx_folder; + __u8 id[8]; +} __attribute__((__packed__)); + +struct hfs_mdb { + __u8 signature[2]; + __u32 cr_date; + __u32 ls_Mod; + __u16 atrb; + __u16 nm_fls; + __u16 vbm_st; + __u16 alloc_ptr; + __u16 nm_al_blks; + __u32 al_blk_size; + __u32 clp_size; + __u16 al_bl_st; + __u32 nxt_cnid; + __u16 free_bks; + __u8 label_len; + __u8 label[27]; + __u32 vol_bkup; + __u16 vol_seq_num; + __u32 wr_cnt; + __u32 xt_clump_size; + __u32 ct_clump_size; + __u16 num_root_dirs; + __u32 file_count; + __u32 dir_count; + struct hfs_finder_info finder_info; + __u8 embed_sig[2]; + __u16 embed_startblock; + __u16 embed_blockcount; +} __attribute__((__packed__)) *hfs; + +struct hfsplus_bnode_descriptor { + __u32 next; + __u32 prev; + __u8 type; + __u8 height; + __u16 num_recs; + __u16 reserved; +} __attribute__((__packed__)); + +struct hfsplus_bheader_record { + __u16 depth; + __u32 root; + __u32 leaf_count; + __u32 leaf_head; + __u32 leaf_tail; + __u16 node_size; +} __attribute__((__packed__)); + +struct hfsplus_catalog_key { + __u16 key_len; + __u32 parent_id; + __u16 unicode_len; + __u8 unicode[255 * 2]; +} __attribute__((__packed__)); + +struct hfsplus_extent { + __u32 start_block; + __u32 block_count; +} __attribute__((__packed__)); + +#define HFSPLUS_EXTENT_COUNT 8 +struct hfsplus_fork { + __u64 total_size; + __u32 clump_size; + __u32 total_blocks; + struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; +} __attribute__((__packed__)); + +struct hfsplus_vol_header { + __u8 signature[2]; + __u16 version; + __u32 attributes; + __u32 last_mount_vers; + __u32 reserved; + __u32 create_date; + __u32 modify_date; + __u32 backup_date; + __u32 checked_date; + __u32 file_count; + __u32 folder_count; + __u32 blocksize; + __u32 total_blocks; + __u32 free_blocks; + __u32 next_alloc; + __u32 rsrc_clump_sz; + __u32 data_clump_sz; + __u32 next_cnid; + __u32 write_count; + __u64 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; +} __attribute__((__packed__)) *hfsplus; + #define HFS_SUPERBLOCK_OFFSET 0x400 #define HFS_NODE_LEAF 0xff #define HFSPLUS_POR_CNID 1 -#define HFSPLUS_EXTENT_COUNT 8 int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) { - struct hfs_finder_info{ - __u32 boot_folder; - __u32 start_app; - __u32 open_folder; - __u32 os9_folder; - __u32 reserved; - __u32 osx_folder; - __u8 id[8]; - } __attribute__((__packed__)); - - struct hfs_mdb { - __u8 signature[2]; - __u32 cr_date; - __u32 ls_Mod; - __u16 atrb; - __u16 nm_fls; - __u16 vbm_st; - __u16 alloc_ptr; - __u16 nm_al_blks; - __u32 al_blk_size; - __u32 clp_size; - __u16 al_bl_st; - __u32 nxt_cnid; - __u16 free_bks; - __u8 label_len; - __u8 label[27]; - __u32 vol_bkup; - __u16 vol_seq_num; - __u32 wr_cnt; - __u32 xt_clump_size; - __u32 ct_clump_size; - __u16 num_root_dirs; - __u32 file_count; - __u32 dir_count; - struct hfs_finder_info finder_info; - __u8 embed_sig[2]; - __u16 embed_startblock; - __u16 embed_blockcount; - } __attribute__((__packed__)) *hfs; - - struct hfsplus_bnode_descriptor { - __u32 next; - __u32 prev; - __u8 type; - __u8 height; - __u16 num_recs; - __u16 reserved; - } __attribute__((__packed__)); - - struct hfsplus_bheader_record { - __u16 depth; - __u32 root; - __u32 leaf_count; - __u32 leaf_head; - __u32 leaf_tail; - __u16 node_size; - } __attribute__((__packed__)); - - struct hfsplus_catalog_key { - __u16 key_len; - __u32 parent_id; - __u16 unicode_len; - __u8 unicode[255 * 2]; - } __attribute__((__packed__)); - - struct hfsplus_extent { - __u32 start_block; - __u32 block_count; - } __attribute__((__packed__)); - - struct hfsplus_fork { - __u64 total_size; - __u32 clump_size; - __u32 total_blocks; - struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; - } __attribute__((__packed__)); - - struct hfsplus_vol_header { - __u8 signature[2]; - __u16 version; - __u32 attributes; - __u32 last_mount_vers; - __u32 reserved; - __u32 create_date; - __u32 modify_date; - __u32 backup_date; - __u32 checked_date; - __u32 file_count; - __u32 folder_count; - __u32 blocksize; - __u32 total_blocks; - __u32 free_blocks; - __u32 next_alloc; - __u32 rsrc_clump_sz; - __u32 data_clump_sz; - __u32 next_cnid; - __u32 write_count; - __u64 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; - } __attribute__((__packed__)) *hfsplus; - unsigned int blocksize; unsigned int cat_block; unsigned int ext_block_start; @@ -173,6 +173,8 @@ int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; const __u8 *buf; + dbg("probing at offset %llu", off); + buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); if (buf == NULL) return -1; diff --git a/extras/volume_id/volume_id/highpoint/highpoint.c b/extras/volume_id/volume_id/highpoint/highpoint.c index 3236d6b2fd..b301450086 100644 --- a/extras/volume_id/volume_id/highpoint/highpoint.c +++ b/extras/volume_id/volume_id/highpoint/highpoint.c @@ -39,21 +39,23 @@ #include "../util.h" #include "highpoint.h" +struct hpt37x { + __u8 filler1[32]; + __u32 magic; + __u32 magic_0; + __u32 magic_1; +} __attribute__((packed)) *hpt; + #define HPT37X_CONFIG_OFF 0x1200 #define HPT37X_MAGIC_OK 0x5a7816f0 #define HPT37X_MAGIC_BAD 0x5a7816fd int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off) { - struct hpt37x { - __u8 filler1[32]; - __u32 magic; - __u32 magic_0; - __u32 magic_1; - } __attribute__((packed)) *hpt; - const __u8 *buf; + dbg("probing at offset %llu", off); + buf = volume_id_get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); if (buf == NULL) return -1; diff --git a/extras/volume_id/volume_id/hpfs/hpfs.c b/extras/volume_id/volume_id/hpfs/hpfs.c new file mode 100644 index 0000000000..212e74ee41 --- /dev/null +++ b/extras/volume_id/volume_id/hpfs/hpfs.c @@ -0,0 +1,69 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "hpfs.h" + +struct hpfs_super +{ + __u8 magic[4]; + __u8 version; +} __attribute__((__packed__)); + +#define HPFS_SUPERBLOCK_OFFSET 0x2000 + +int volume_id_probe_hpfs(struct volume_id *id, __u64 off) +{ + struct hpfs_super *hs; + + dbg("probing at offset %llu", 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) { + snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u", hs->version); + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "hpfs"; + return 0; + } + + return -1; +} diff --git a/extras/volume_id/volume_id/hpfs/hpfs.h b/extras/volume_id/volume_id/hpfs/hpfs.h new file mode 100644 index 0000000000..bd8d4c90c9 --- /dev/null +++ b/extras/volume_id/volume_id/hpfs/hpfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_HPFS_ +#define _VOLUME_ID_HPFS_ + +extern int volume_id_probe_hpfs(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/iso9660/iso9660.c b/extras/volume_id/volume_id/iso9660/iso9660.c index fa769d3ca3..1d7cfd5037 100644 --- a/extras/volume_id/volume_id/iso9660/iso9660.c +++ b/extras/volume_id/volume_id/iso9660/iso9660.c @@ -47,24 +47,28 @@ #define ISO_VD_END 0xff #define ISO_VD_MAX 16 +union iso_super_block { + struct iso_header { + __u8 type; + __u8 id[5]; + __u8 version; + __u8 unused1; + __u8 system_id[32]; + __u8 volume_id[32]; + } __attribute__((__packed__)) iso; + struct hs_header { + __u8 foo[8]; + __u8 type; + __u8 id[4]; + __u8 version; + } __attribute__((__packed__)) hs; +} __attribute__((__packed__)); + int volume_id_probe_iso9660(struct volume_id *id, __u64 off) { - union iso_super_block { - struct iso_header { - __u8 type; - __u8 id[5]; - __u8 version; - __u8 unused1; - __u8 system_id[32]; - __u8 volume_id[32]; - } __attribute__((__packed__)) iso; - struct hs_header { - __u8 foo[8]; - __u8 type; - __u8 id[4]; - __u8 version; - } __attribute__((__packed__)) hs; - } __attribute__((__packed__)) *is; + union iso_super_block *is; + + dbg("probing at offset %llu", off); is = (union iso_super_block *) volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); if (is == NULL) diff --git a/extras/volume_id/volume_id/jfs/jfs.c b/extras/volume_id/volume_id/jfs/jfs.c index c9dce84ecb..ab0b83081c 100644 --- a/extras/volume_id/volume_id/jfs/jfs.c +++ b/extras/volume_id/volume_id/jfs/jfs.c @@ -39,22 +39,26 @@ #include "../util.h" #include "jfs.h" +struct jfs_super_block { + __u8 magic[4]; + __u32 version; + __u64 size; + __u32 bsize; + __u32 dummy1; + __u32 pbsize; + __u32 dummy2[27]; + __u8 uuid[16]; + __u8 label[16]; + __u8 loguuid[16]; +} __attribute__((__packed__)); + #define JFS_SUPERBLOCK_OFFSET 0x8000 int volume_id_probe_jfs(struct volume_id *id, __u64 off) { - struct jfs_super_block { - __u8 magic[4]; - __u32 version; - __u64 size; - __u32 bsize; - __u32 dummy1; - __u32 pbsize; - __u32 dummy2[27]; - __u8 uuid[16]; - __u8 label[16]; - __u8 loguuid[16]; - } __attribute__((__packed__)) *js; + struct jfs_super_block *js; + + dbg("probing at offset %llu", off); js = (struct jfs_super_block *) volume_id_get_buffer(id, off + JFS_SUPERBLOCK_OFFSET, 0x200); if (js == NULL) diff --git a/extras/volume_id/volume_id/linux_raid/linux_raid.c b/extras/volume_id/volume_id/linux_raid/linux_raid.c index b55c6ca6e8..ca03030ee4 100644 --- a/extras/volume_id/volume_id/linux_raid/linux_raid.c +++ b/extras/volume_id/volume_id/linux_raid/linux_raid.c @@ -39,34 +39,36 @@ #include "../util.h" #include "linux_raid.h" +struct mdp_super_block { + __u32 md_magic; + __u32 major_version; + __u32 minor_version; + __u32 patch_version; + __u32 gvalid_words; + __u32 set_uuid0; + __u32 ctime; + __u32 level; + __u32 size; + __u32 nr_disks; + __u32 raid_disks; + __u32 md_minor; + __u32 not_persistent; + __u32 set_uuid1; + __u32 set_uuid2; + __u32 set_uuid3; +} __attribute__((packed)) *mdp; + #define MD_RESERVED_BYTES 0x10000 #define MD_MAGIC 0xa92b4efc int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) { - struct mdp_super_block { - __u32 md_magic; - __u32 major_version; - __u32 minor_version; - __u32 patch_version; - __u32 gvalid_words; - __u32 set_uuid0; - __u32 ctime; - __u32 level; - __u32 size; - __u32 nr_disks; - __u32 raid_disks; - __u32 md_minor; - __u32 not_persistent; - __u32 set_uuid1; - __u32 set_uuid2; - __u32 set_uuid3; - } __attribute__((packed)) *mdp; - const __u8 *buf; __u64 sboff; __u8 uuid[16]; + dbg("probing at offset %llu", off); + if (size < 0x10000) return -1; diff --git a/extras/volume_id/volume_id/linux_swap/linux_swap.c b/extras/volume_id/volume_id/linux_swap/linux_swap.c index d34b22c590..2fb16377a8 100644 --- a/extras/volume_id/volume_id/linux_swap/linux_swap.c +++ b/extras/volume_id/volume_id/linux_swap/linux_swap.c @@ -39,22 +39,24 @@ #include "../util.h" #include "linux_swap.h" +struct swap_header_v1_2 { + __u8 bootbits[1024]; + __u32 version; + __u32 last_page; + __u32 nr_badpages; + __u8 uuid[16]; + __u8 volume_name[16]; +} __attribute__((__packed__)) *sw; + #define LARGEST_PAGESIZE 0x4000 int volume_id_probe_linux_swap(struct volume_id *id, __u64 off) { - struct swap_header_v1_2 { - __u8 bootbits[1024]; - __u32 version; - __u32 last_page; - __u32 nr_badpages; - __u8 uuid[16]; - __u8 volume_name[16]; - } __attribute__((__packed__)) *sw; - const __u8 *buf; unsigned int page; + dbg("probing at offset %llu", off); + /* 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); diff --git a/extras/volume_id/volume_id/lvm/lvm.c b/extras/volume_id/volume_id/lvm/lvm.c index e736f4ed4a..ed1a83aeb4 100644 --- a/extras/volume_id/volume_id/lvm/lvm.c +++ b/extras/volume_id/volume_id/lvm/lvm.c @@ -39,22 +39,33 @@ #include "../util.h" #include "lvm.h" +struct lvm1_super_block { + __u8 id[2]; +} __attribute__((packed)); + +struct lvm2_super_block { + __u8 id[8]; + __u64 sector_xl; + __u32 crc_xl; + __u32 offset_xl; + __u8 type[8]; +} __attribute__((packed)); + #define LVM1_SB_OFF 0x400 #define LVM1_MAGIC "HM" int volume_id_probe_lvm1(struct volume_id *id, __u64 off) { - struct lvm2_super_block { - __u8 id[2]; - } __attribute__((packed)) *lvm; - const __u8 *buf; + struct lvm1_super_block *lvm; + + dbg("probing at offset %llu", off); buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800); if (buf == NULL) return -1; - lvm = (struct lvm2_super_block *) buf; + lvm = (struct lvm1_super_block *) buf; if (memcmp(lvm->id, LVM1_MAGIC, 2) != 0) return -1; @@ -70,16 +81,11 @@ int volume_id_probe_lvm1(struct volume_id *id, __u64 off) int volume_id_probe_lvm2(struct volume_id *id, __u64 off) { - struct lvm2_super_block { - __u8 id[8]; - __u64 sector_xl; - __u32 crc_xl; - __u32 offset_xl; - __u8 type[8]; - } __attribute__((packed)) *lvm; - const __u8 *buf; unsigned int soff; + struct lvm2_super_block *lvm; + + dbg("probing at offset %llu", off); buf = volume_id_get_buffer(id, off, LVM2LABEL_SCAN_SECTORS * 0x200); if (buf == NULL) diff --git a/extras/volume_id/volume_id/mac/mac.c b/extras/volume_id/volume_id/mac/mac.c index 5872b722b4..895316d26c 100644 --- a/extras/volume_id/volume_id/mac/mac.c +++ b/extras/volume_id/volume_id/mac/mac.c @@ -39,25 +39,29 @@ #include "../util.h" #include "mac.h" +struct mac_driver_desc { + __u8 signature[2]; + __u16 block_size; + __u32 block_count; +} __attribute__((__packed__)); + +struct mac_partition { + __u8 signature[2]; + __u16 res1; + __u32 map_count; + __u32 start_block; + __u32 block_count; + __u8 name[32]; + __u8 type[32]; +} __attribute__((__packed__)); + int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) { - struct mac_driver_desc { - __u8 signature[2]; - __u16 block_size; - __u32 block_count; - } __attribute__((__packed__)) *driver; - - struct mac_partition { - __u8 signature[2]; - __u16 res1; - __u32 map_count; - __u32 start_block; - __u32 block_count; - __u8 name[32]; - __u8 type[32]; - } __attribute__((__packed__)) *part; - const __u8 *buf; + struct mac_driver_desc *driver; + struct mac_partition *part; + + dbg("probing at offset %llu", off); buf = volume_id_get_buffer(id, off, 0x200); if (buf == NULL) diff --git a/extras/volume_id/volume_id/msdos/msdos.c b/extras/volume_id/volume_id/msdos/msdos.c index 08124fad2d..a90b9efc33 100644 --- a/extras/volume_id/volume_id/msdos/msdos.c +++ b/extras/volume_id/volume_id/msdos/msdos.c @@ -39,6 +39,19 @@ #include "../util.h" #include "msdos.h" +struct msdos_partition_entry { + __u8 boot_ind; + __u8 head; + __u8 sector; + __u8 cyl; + __u8 sys_ind; + __u8 end_head; + __u8 end_sector; + __u8 end_cyl; + __u32 start_sect; + __u32 nr_sects; +} __attribute__((packed)); + #define MSDOS_MAGIC "\x55\xaa" #define MSDOS_PARTTABLE_OFFSET 0x1be #define MSDOS_SIG_OFF 0x1fe @@ -56,19 +69,6 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) { - struct msdos_partition_entry { - __u8 boot_ind; - __u8 head; - __u8 sector; - __u8 cyl; - __u8 sys_ind; - __u8 end_head; - __u8 end_sector; - __u8 end_cyl; - __u32 start_sect; - __u32 nr_sects; - } __attribute__((packed)) *part; - const __u8 *buf; int i; __u64 poff; @@ -78,8 +78,11 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) __u64 next; int limit; int empty = 1; + struct msdos_partition_entry *part; struct volume_id_partition *p; + dbg("probing at offset %llu", off); + buf = volume_id_get_buffer(id, off, 0x200); if (buf == NULL) return -1; diff --git a/extras/volume_id/volume_id/ntfs/ntfs.c b/extras/volume_id/volume_id/ntfs/ntfs.c index bf87f9d8d0..e46bc64bb2 100644 --- a/extras/volume_id/volume_id/ntfs/ntfs.c +++ b/extras/volume_id/volume_id/ntfs/ntfs.c @@ -39,6 +39,64 @@ #include "../util.h" #include "ntfs.h" +struct ntfs_super_block { + __u8 jump[3]; + __u8 oem_id[8]; + __u16 bytes_per_sector; + __u8 sectors_per_cluster; + __u16 reserved_sectors; + __u8 fats; + __u16 root_entries; + __u16 sectors; + __u8 media_type; + __u16 sectors_per_fat; + __u16 sectors_per_track; + __u16 heads; + __u32 hidden_sectors; + __u32 large_sectors; + __u16 unused[2]; + __u64 number_of_sectors; + __u64 mft_cluster_location; + __u64 mft_mirror_cluster_location; + __s8 cluster_per_mft_record; + __u8 reserved1[3]; + __s8 cluster_per_index_record; + __u8 reserved2[3]; + __u8 volume_serial[8]; + __u16 checksum; +} __attribute__((__packed__)) *ns; + +struct master_file_table_record { + __u8 magic[4]; + __u16 usa_ofs; + __u16 usa_count; + __u64 lsn; + __u16 sequence_number; + __u16 link_count; + __u16 attrs_offset; + __u16 flags; + __u32 bytes_in_use; + __u32 bytes_allocated; +} __attribute__((__packed__)) *mftr; + +struct file_attribute { + __u32 type; + __u32 len; + __u8 non_resident; + __u8 name_len; + __u16 name_offset; + __u16 flags; + __u16 instance; + __u32 value_len; + __u16 value_offset; +} __attribute__((__packed__)) *attr; + +struct volume_info { + __u64 reserved; + __u8 major_ver; + __u8 minor_ver; +} __attribute__((__packed__)) *info; + #define MFT_RECORD_VOLUME 3 #define MFT_RECORD_ATTR_VOLUME_NAME 0x60 #define MFT_RECORD_ATTR_VOLUME_INFO 0x70 @@ -47,64 +105,6 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) { - struct ntfs_super_block { - __u8 jump[3]; - __u8 oem_id[8]; - __u16 bytes_per_sector; - __u8 sectors_per_cluster; - __u16 reserved_sectors; - __u8 fats; - __u16 root_entries; - __u16 sectors; - __u8 media_type; - __u16 sectors_per_fat; - __u16 sectors_per_track; - __u16 heads; - __u32 hidden_sectors; - __u32 large_sectors; - __u16 unused[2]; - __u64 number_of_sectors; - __u64 mft_cluster_location; - __u64 mft_mirror_cluster_location; - __s8 cluster_per_mft_record; - __u8 reserved1[3]; - __s8 cluster_per_index_record; - __u8 reserved2[3]; - __u8 volume_serial[8]; - __u16 checksum; - } __attribute__((__packed__)) *ns; - - struct master_file_table_record { - __u8 magic[4]; - __u16 usa_ofs; - __u16 usa_count; - __u64 lsn; - __u16 sequence_number; - __u16 link_count; - __u16 attrs_offset; - __u16 flags; - __u32 bytes_in_use; - __u32 bytes_allocated; - } __attribute__((__packed__)) *mftr; - - struct file_attribute { - __u32 type; - __u32 len; - __u8 non_resident; - __u8 name_len; - __u16 name_offset; - __u16 flags; - __u16 instance; - __u32 value_len; - __u16 value_offset; - } __attribute__((__packed__)) *attr; - - struct volume_info { - __u64 reserved; - __u8 major_ver; - __u8 minor_ver; - } __attribute__((__packed__)) *info; - unsigned int sector_size; unsigned int cluster_size; __u64 mft_cluster; @@ -118,6 +118,8 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) const __u8 *buf; const __u8 *val; + dbg("probing at offset %llu", off); + ns = (struct ntfs_super_block *) volume_id_get_buffer(id, off, 0x200); if (ns == NULL) return -1; diff --git a/extras/volume_id/volume_id/reiserfs/reiserfs.c b/extras/volume_id/volume_id/reiserfs/reiserfs.c index 5653214e9d..d54013e4c5 100644 --- a/extras/volume_id/volume_id/reiserfs/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs/reiserfs.c @@ -39,26 +39,30 @@ #include "../util.h" #include "reiserfs.h" +struct reiserfs_super_block { + __u32 blocks_count; + __u32 free_blocks; + __u32 root_block; + __u32 journal_block; + __u32 journal_dev; + __u32 orig_journal_size; + __u32 dummy2[5]; + __u16 blocksize; + __u16 dummy3[3]; + __u8 magic[12]; + __u32 dummy4[5]; + __u8 uuid[16]; + __u8 label[16]; +} __attribute__((__packed__)); + #define REISERFS1_SUPERBLOCK_OFFSET 0x2000 #define REISERFS_SUPERBLOCK_OFFSET 0x10000 int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) { - struct reiserfs_super_block { - __u32 blocks_count; - __u32 free_blocks; - __u32 root_block; - __u32 journal_block; - __u32 journal_dev; - __u32 orig_journal_size; - __u32 dummy2[5]; - __u16 blocksize; - __u16 dummy3[3]; - __u8 magic[12]; - __u32 dummy4[5]; - __u8 uuid[16]; - __u8 label[16]; - } __attribute__((__packed__)) *rs; + struct reiserfs_super_block *rs; + + dbg("probing at offset %llu", off); rs = (struct reiserfs_super_block *) volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); if (rs == NULL) diff --git a/extras/volume_id/volume_id/romfs/romfs.c b/extras/volume_id/volume_id/romfs/romfs.c new file mode 100644 index 0000000000..c04dc98f10 --- /dev/null +++ b/extras/volume_id/volume_id/romfs/romfs.c @@ -0,0 +1,73 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "romfs.h" + +struct romfs_super { + __u8 magic[8]; + __u32 size; + __u32 checksum; + __u8 name[0]; +} __attribute__((__packed__)); + +int volume_id_probe_romfs(struct volume_id *id, __u64 off) +{ + struct romfs_super *rfs; + + dbg("probing at offset %llu", 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(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/extras/volume_id/volume_id/romfs/romfs.h b/extras/volume_id/volume_id/romfs/romfs.h new file mode 100644 index 0000000000..b0108f3dde --- /dev/null +++ b/extras/volume_id/volume_id/romfs/romfs.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_ROMFS_ +#define _VOLUME_ID_ROMFS_ + +extern int volume_id_probe_romfs(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/sysv/sysv.c b/extras/volume_id/volume_id/sysv/sysv.c new file mode 100644 index 0000000000..313ac1732a --- /dev/null +++ b/extras/volume_id/volume_id/sysv/sysv.c @@ -0,0 +1,146 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "../volume_id.h" +#include "../logging.h" +#include "../util.h" +#include "sysv.h" + +#define SYSV_NICINOD 100 +#define SYSV_NICFREE 50 + +struct sysv_super +{ + __u16 s_isize; + __u16 s_pad0; + __u32 s_fsize; + __u16 s_nfree; + __u16 s_pad1; + __u32 s_free[SYSV_NICFREE]; + __u16 s_ninode; + __u16 s_pad2; + __u16 s_inode[SYSV_NICINOD]; + __u8 s_flock; + __u8 s_ilock; + __u8 s_fmod; + __u8 s_ronly; + __u32 s_time; + __u16 s_dinfo[4]; + __u32 s_tfree; + __u16 s_tinode; + __u16 s_pad3; + __u8 s_fname[6]; + __u8 s_fpack[6]; + __u32 s_fill[12]; + __u32 s_state; + __u32 s_magic; + __u32 s_type; +} __attribute__((__packed__)); + +#define XENIX_NICINOD 100 +#define XENIX_NICFREE 100 + +struct xenix_super { + __u16 s_isize; + __u32 s_fsize; + __u16 s_nfree; + __u32 s_free[XENIX_NICFREE]; + __u16 s_ninode; + __u16 s_inode[XENIX_NICINOD]; + __u8 s_flock; + __u8 s_ilock; + __u8 s_fmod; + __u8 s_ronly; + __u32 s_time; + __u32 s_tfree; + __u16 s_tinode; + __u16 s_dinfo[4]; + __u8 s_fname[6]; + __u8 s_fpack[6]; + __u8 s_clean; + __u8 s_fill[371]; + __u32 s_magic; + __u32 s_type; +} __attribute__((__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, __u64 off) +{ + struct sysv_super *vs; + struct xenix_super *xs; + unsigned int boff; + + dbg("probing at offset %llu", 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/extras/volume_id/volume_id/sysv/sysv.h b/extras/volume_id/volume_id/sysv/sysv.h new file mode 100644 index 0000000000..bd5a3500fb --- /dev/null +++ b/extras/volume_id/volume_id/sysv/sysv.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_SYSV_ +#define _VOLUME_ID_SYSV_ + +extern int volume_id_probe_sysv(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/udf/udf.c b/extras/volume_id/volume_id/udf/udf.c index ff23b31039..79d25ad890 100644 --- a/extras/volume_id/volume_id/udf/udf.c +++ b/extras/volume_id/volume_id/udf/udf.c @@ -39,43 +39,45 @@ #include "../util.h" #include "udf.h" +struct volume_descriptor { + struct descriptor_tag { + __u16 id; + __u16 version; + __u8 checksum; + __u8 reserved; + __u16 serial; + __u16 crc; + __u16 crc_len; + __u32 location; + } __attribute__((__packed__)) tag; + union { + struct anchor_descriptor { + __u32 length; + __u32 location; + } __attribute__((__packed__)) anchor; + struct primary_descriptor { + __u32 seq_num; + __u32 desc_num; + struct dstring { + __u8 clen; + __u8 c[31]; + } __attribute__((__packed__)) ident; + } __attribute__((__packed__)) primary; + } __attribute__((__packed__)) type; +} __attribute__((__packed__)); + +struct volume_structure_descriptor { + __u8 type; + __u8 id[5]; + __u8 version; +} __attribute__((__packed__)); + #define UDF_VSD_OFFSET 0x8000 int volume_id_probe_udf(struct volume_id *id, __u64 off) { - struct volume_descriptor { - struct descriptor_tag { - __u16 id; - __u16 version; - __u8 checksum; - __u8 reserved; - __u16 serial; - __u16 crc; - __u16 crc_len; - __u32 location; - } __attribute__((__packed__)) tag; - union { - struct anchor_descriptor { - __u32 length; - __u32 location; - } __attribute__((__packed__)) anchor; - struct primary_descriptor { - __u32 seq_num; - __u32 desc_num; - struct dstring { - __u8 clen; - __u8 c[31]; - } __attribute__((__packed__)) ident; - } __attribute__((__packed__)) primary; - } __attribute__((__packed__)) type; - } __attribute__((__packed__)) *vd; - - struct volume_structure_descriptor { - __u8 type; - __u8 id[5]; - __u8 version; - } *vsd; - + struct volume_descriptor *vd; + struct volume_structure_descriptor *vsd; unsigned int bs; unsigned int b; unsigned int type; @@ -83,6 +85,8 @@ int volume_id_probe_udf(struct volume_id *id, __u64 off) unsigned int loc; unsigned int clen; + dbg("probing at offset %llu", off); + vsd = (struct volume_structure_descriptor *) volume_id_get_buffer(id, off + UDF_VSD_OFFSET, 0x200); if (vsd == NULL) return -1; diff --git a/extras/volume_id/volume_id/ufs/ufs.c b/extras/volume_id/volume_id/ufs/ufs.c index bab1d4cfad..12672ffe01 100644 --- a/extras/volume_id/volume_id/ufs/ufs.c +++ b/extras/volume_id/volume_id/ufs/ufs.c @@ -39,6 +39,143 @@ #include "../util.h" #include "ufs.h" +struct ufs_super_block { + __u32 fs_link; + __u32 fs_rlink; + __u32 fs_sblkno; + __u32 fs_cblkno; + __u32 fs_iblkno; + __u32 fs_dblkno; + __u32 fs_cgoffset; + __u32 fs_cgmask; + __u32 fs_time; + __u32 fs_size; + __u32 fs_dsize; + __u32 fs_ncg; + __u32 fs_bsize; + __u32 fs_fsize; + __u32 fs_frag; + __u32 fs_minfree; + __u32 fs_rotdelay; + __u32 fs_rps; + __u32 fs_bmask; + __u32 fs_fmask; + __u32 fs_bshift; + __u32 fs_fshift; + __u32 fs_maxcontig; + __u32 fs_maxbpg; + __u32 fs_fragshift; + __u32 fs_fsbtodb; + __u32 fs_sbsize; + __u32 fs_csmask; + __u32 fs_csshift; + __u32 fs_nindir; + __u32 fs_inopb; + __u32 fs_nspf; + __u32 fs_optim; + __u32 fs_npsect_state; + __u32 fs_interleave; + __u32 fs_trackskew; + __u32 fs_id[2]; + __u32 fs_csaddr; + __u32 fs_cssize; + __u32 fs_cgsize; + __u32 fs_ntrak; + __u32 fs_nsect; + __u32 fs_spc; + __u32 fs_ncyl; + __u32 fs_cpg; + __u32 fs_ipg; + __u32 fs_fpg; + struct ufs_csum { + __u32 cs_ndir; + __u32 cs_nbfree; + __u32 cs_nifree; + __u32 cs_nffree; + } __attribute__((__packed__)) fs_cstotal; + __s8 fs_fmod; + __s8 fs_clean; + __s8 fs_ronly; + __s8 fs_flags; + union { + struct { + __s8 fs_fsmnt[512]; + __u32 fs_cgrotor; + __u32 fs_csp[31]; + __u32 fs_maxcluster; + __u32 fs_cpc; + __u16 fs_opostbl[16][8]; + } __attribute__((__packed__)) fs_u1; + struct { + __s8 fs_fsmnt[468]; + __u8 fs_volname[32]; + __u64 fs_swuid; + __s32 fs_pad; + __u32 fs_cgrotor; + __u32 fs_ocsp[28]; + __u32 fs_contigdirs; + __u32 fs_csp; + __u32 fs_maxcluster; + __u32 fs_active; + __s32 fs_old_cpc; + __s32 fs_maxbsize; + __s64 fs_sparecon64[17]; + __s64 fs_sblockloc; + struct ufs2_csum_total { + __u64 cs_ndir; + __u64 cs_nbfree; + __u64 cs_nifree; + __u64 cs_nffree; + __u64 cs_numclusters; + __u64 cs_spare[3]; + } __attribute__((__packed__)) fs_cstotal; + struct ufs_timeval { + __s32 tv_sec; + __s32 tv_usec; + } __attribute__((__packed__)) fs_time; + __s64 fs_size; + __s64 fs_dsize; + __u64 fs_csaddr; + __s64 fs_pendingblocks; + __s32 fs_pendinginodes; + } __attribute__((__packed__)) fs_u2; + } fs_u11; + union { + struct { + __s32 fs_sparecon[53]; + __s32 fs_reclaim; + __s32 fs_sparecon2[1]; + __s32 fs_state; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + } __attribute__((__packed__)) fs_sun; + struct { + __s32 fs_sparecon[53]; + __s32 fs_reclaim; + __s32 fs_sparecon2[1]; + __u32 fs_npsect; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + } __attribute__((__packed__)) fs_sunx86; + struct { + __s32 fs_sparecon[50]; + __s32 fs_contigsumsize; + __s32 fs_maxsymlinklen; + __s32 fs_inodefmt; + __u32 fs_maxfilesize[2]; + __u32 fs_qbmask[2]; + __u32 fs_qfmask[2]; + __s32 fs_state; + } __attribute__((__packed__)) fs_44; + } fs_u2; + __s32 fs_postblformat; + __s32 fs_nrpos; + __s32 fs_postbloff; + __s32 fs_rotbloff; + __u32 fs_magic; + __u8 fs_space[1]; +} __attribute__((__packed__)); + #define UFS_MAGIC 0x00011954 #define UFS2_MAGIC 0x19540119 #define UFS_MAGIC_FEA 0x00195612 @@ -46,147 +183,13 @@ int volume_id_probe_ufs(struct volume_id *id, __u64 off) { - struct ufs_super_block { - __u32 fs_link; - __u32 fs_rlink; - __u32 fs_sblkno; - __u32 fs_cblkno; - __u32 fs_iblkno; - __u32 fs_dblkno; - __u32 fs_cgoffset; - __u32 fs_cgmask; - __u32 fs_time; - __u32 fs_size; - __u32 fs_dsize; - __u32 fs_ncg; - __u32 fs_bsize; - __u32 fs_fsize; - __u32 fs_frag; - __u32 fs_minfree; - __u32 fs_rotdelay; - __u32 fs_rps; - __u32 fs_bmask; - __u32 fs_fmask; - __u32 fs_bshift; - __u32 fs_fshift; - __u32 fs_maxcontig; - __u32 fs_maxbpg; - __u32 fs_fragshift; - __u32 fs_fsbtodb; - __u32 fs_sbsize; - __u32 fs_csmask; - __u32 fs_csshift; - __u32 fs_nindir; - __u32 fs_inopb; - __u32 fs_nspf; - __u32 fs_optim; - __u32 fs_npsect_state; - __u32 fs_interleave; - __u32 fs_trackskew; - __u32 fs_id[2]; - __u32 fs_csaddr; - __u32 fs_cssize; - __u32 fs_cgsize; - __u32 fs_ntrak; - __u32 fs_nsect; - __u32 fs_spc; - __u32 fs_ncyl; - __u32 fs_cpg; - __u32 fs_ipg; - __u32 fs_fpg; - struct ufs_csum { - __u32 cs_ndir; - __u32 cs_nbfree; - __u32 cs_nifree; - __u32 cs_nffree; - } __attribute__((__packed__)) fs_cstotal; - __s8 fs_fmod; - __s8 fs_clean; - __s8 fs_ronly; - __s8 fs_flags; - union { - struct { - __s8 fs_fsmnt[512]; - __u32 fs_cgrotor; - __u32 fs_csp[31]; - __u32 fs_maxcluster; - __u32 fs_cpc; - __u16 fs_opostbl[16][8]; - } __attribute__((__packed__)) fs_u1; - struct { - __s8 fs_fsmnt[468]; - __u8 fs_volname[32]; - __u64 fs_swuid; - __s32 fs_pad; - __u32 fs_cgrotor; - __u32 fs_ocsp[28]; - __u32 fs_contigdirs; - __u32 fs_csp; - __u32 fs_maxcluster; - __u32 fs_active; - __s32 fs_old_cpc; - __s32 fs_maxbsize; - __s64 fs_sparecon64[17]; - __s64 fs_sblockloc; - struct ufs2_csum_total { - __u64 cs_ndir; - __u64 cs_nbfree; - __u64 cs_nifree; - __u64 cs_nffree; - __u64 cs_numclusters; - __u64 cs_spare[3]; - } __attribute__((__packed__)) fs_cstotal; - struct ufs_timeval { - __s32 tv_sec; - __s32 tv_usec; - } __attribute__((__packed__)) fs_time; - __s64 fs_size; - __s64 fs_dsize; - __u64 fs_csaddr; - __s64 fs_pendingblocks; - __s32 fs_pendinginodes; - } __attribute__((__packed__)) fs_u2; - } fs_u11; - union { - struct { - __s32 fs_sparecon[53]; - __s32 fs_reclaim; - __s32 fs_sparecon2[1]; - __s32 fs_state; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; - } __attribute__((__packed__)) fs_sun; - struct { - __s32 fs_sparecon[53]; - __s32 fs_reclaim; - __s32 fs_sparecon2[1]; - __u32 fs_npsect; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; - } __attribute__((__packed__)) fs_sunx86; - struct { - __s32 fs_sparecon[50]; - __s32 fs_contigsumsize; - __s32 fs_maxsymlinklen; - __s32 fs_inodefmt; - __u32 fs_maxfilesize[2]; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; - __s32 fs_state; - } __attribute__((__packed__)) fs_44; - } fs_u2; - __s32 fs_postblformat; - __s32 fs_nrpos; - __s32 fs_postbloff; - __s32 fs_rotbloff; - __u32 fs_magic; - __u8 fs_space[1]; - } __attribute__((__packed__)) *ufs; - __u32 magic; int i; + struct ufs_super_block *ufs; int offsets[] = {0, 8, 64, 256, -1}; + dbg("probing at offset %llu", 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) diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h index e5cd63e1aa..22fd1b94e2 100644 --- a/extras/volume_id/volume_id/util.h +++ b/extras/volume_id/volume_id/util.h @@ -58,12 +58,16 @@ #define le64_to_cpu(x) (x) #define be16_to_cpu(x) bswap16(x) #define be32_to_cpu(x) bswap32(x) +#define cpu_to_le32(x) (x) +#define cpu_to_be32(x) bswap32(x) #elif (__BYTE_ORDER == __BIG_ENDIAN) #define le16_to_cpu(x) bswap16(x) #define le32_to_cpu(x) bswap32(x) #define le64_to_cpu(x) bswap64(x) #define be16_to_cpu(x) (x) #define be32_to_cpu(x) (x) +#define cpu_to_le32(x) bswap32(x) +#define cpu_to_be32(x) (x) #endif enum uuid_format { diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 78aae37ba0..95f7f5b127 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -56,6 +56,8 @@ #include "linux_raid/linux_raid.h" #include "lvm/lvm.h" #include "cramfs/cramfs.h" +#include "hpfs/hpfs.h" +#include "romfs/romfs.h" #include "mac/mac.h" #include "msdos/msdos.h" @@ -120,6 +122,12 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_cramfs(id, off) == 0) goto exit; + if (volume_id_probe_romfs(id, off) == 0) + goto exit; + + if (volume_id_probe_hpfs(id, off) == 0) + goto exit; + return -1; exit: diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 5a4b136c32..5b845602c6 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 33 +#define VOLUME_ID_VERSION 34 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 diff --git a/extras/volume_id/volume_id/xfs/xfs.c b/extras/volume_id/volume_id/xfs/xfs.c index 67ae2f07d5..efbe06ec58 100644 --- a/extras/volume_id/volume_id/xfs/xfs.c +++ b/extras/volume_id/volume_id/xfs/xfs.c @@ -39,22 +39,26 @@ #include "../util.h" #include "xfs.h" +struct xfs_super_block { + __u8 magic[4]; + __u32 blocksize; + __u64 dblocks; + __u64 rblocks; + __u32 dummy1[2]; + __u8 uuid[16]; + __u32 dummy2[15]; + __u8 fname[12]; + __u32 dummy3[2]; + __u64 icount; + __u64 ifree; + __u64 fdblocks; +} __attribute__((__packed__)); + int volume_id_probe_xfs(struct volume_id *id, __u64 off) { - struct xfs_super_block { - __u8 magic[4]; - __u32 blocksize; - __u64 dblocks; - __u64 rblocks; - __u32 dummy1[2]; - __u8 uuid[16]; - __u32 dummy2[15]; - __u8 fname[12]; - __u32 dummy3[2]; - __u64 icount; - __u64 ifree; - __u64 fdblocks; - } __attribute__((__packed__)) *xs; + struct xfs_super_block *xs; + + dbg("probing at offset %llu", off); xs = (struct xfs_super_block *) volume_id_get_buffer(id, off, 0x200); if (xs == NULL) From bce52be81ec679bf080bb11f292c899d9fde084e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 9 Feb 2005 01:15:35 +0100 Subject: [PATCH 1135/4284] [PATCH] udev_volume_id: fix dasd disklabel reading with -l option --- extras/volume_id/udev_volume_id.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index c2a37e8547..d3c3fcd505 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -89,7 +89,7 @@ int main(int argc, char *argv[]) struct sysfs_class_device *class_dev_parent = NULL; struct volume_id *vid = NULL; char *devpath; - char probe_main_device = 0; + char probe_disk_label = 0; char print = 'a'; static char name[VOLUME_ID_LABEL_SIZE]; int len, i, j; @@ -116,7 +116,7 @@ int main(int argc, char *argv[]) print = 'u'; continue; case 'd': - probe_main_device = 1; + probe_disk_label = 1; continue; case 'h': case '?': @@ -146,8 +146,7 @@ int main(int argc, char *argv[]) goto exit; } - if (probe_main_device == 0) { - /* open block device */ + if (probe_disk_label == 0) { vid = open_classdev(class_dev); if (vid == NULL) goto exit; @@ -205,7 +204,8 @@ print: printf("%s\n", vid->type); break; case 'l': - if (name[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) { + if (name[0] == '\0' || + (vid->usage_id != VOLUME_ID_FILESYSTEM && vid->usage_id != VOLUME_ID_DISKLABEL)) { rc = 2; goto exit; } From c1ab046124ebef3c82950b91ccfd1678d9f7fe5b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 9 Feb 2005 04:37:32 +0100 Subject: [PATCH 1136/4284] [PATCH] provide temporary device node for callouts to access the device %N will create a temporary node for a callout a be sustituted with the name of the node. --- namedev.c | 21 +++++++++++++++++++++ test/udev-test.pl | 18 ++++++++++++++++++ udev.8.in | 7 +++++++ udev.h | 3 +++ udev_add.c | 6 +++--- udev_remove.c | 39 ++------------------------------------- udev_utils.c | 25 +++++++++++++++++++++++++ udev_utils.h | 1 + 8 files changed, 80 insertions(+), 40 deletions(-) diff --git a/namedev.c b/namedev.c index 0c5d0509f9..332e2d57d8 100644 --- a/namedev.c +++ b/namedev.c @@ -201,6 +201,12 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, switch (c) { + case 'p': + if (strlen(udev->devpath) == 0) + break; + strfieldcatmax(string, udev->devpath, maxsize); + dbg("substitute kernel name '%s'", udev->kernel_name); + break; case 'b': if (strlen(udev->bus_id) == 0) break; @@ -290,6 +296,15 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strfieldcatmax(string, temp2, maxsize); } break; + case 'N': + if (udev->tmp_node[0] == '\0') { + dbg("create temporary device node for callout"); + snprintf(udev->tmp_node, NAME_SIZE-1, "%s/.tmp-%u-%u", udev_root, udev->major, udev->minor); + udev_make_node(udev, udev->tmp_node, udev->major, udev->minor, 0600, 0, 0); + } + strfieldcatmax(string, udev->tmp_node, maxsize); + dbg("substitute temporary device node name '%s'", udev->tmp_node); + break; default: dbg("unknown substitution type '%%%c'", c); break; @@ -787,5 +802,11 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("no rule found, use kernel name '%s'", udev->name); exit: + if (udev->tmp_node[0] != '\0') { + dbg("removing temporary device node"); + unlink_secure(udev->tmp_node); + udev->tmp_node[0] = '\0'; + } + return 0; } diff --git a/test/udev-test.pl b/test/udev-test.pl index 67c0672759..fa1e4affc6 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1066,6 +1066,24 @@ EOF conf => < "temporary node creation test", + subsys => "block", + devpath => "/block/sda", + exp_name => "sda", + conf => < "devpath substitution test", + subsys => "block", + devpath => "/block/sda", + exp_name => "sda", + conf => < #include #include "libsysfs/sysfs/libsysfs.h" @@ -59,6 +60,7 @@ struct udevice { int minor; char devname[NAME_SIZE]; + char tmp_node[NAME_SIZE]; int partitions; int ignore_remove; int config_line; @@ -75,6 +77,7 @@ extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix); +extern int udev_make_node(struct udevice *udev, const char *file, int major, int minor, mode_t mode, uid_t uid, gid_t gid); extern char sysfs_path[SYSFS_PATH_MAX]; extern char udev_root[PATH_MAX]; diff --git a/udev_add.c b/udev_add.c index 24a20bba9b..a495902ab2 100644 --- a/udev_add.c +++ b/udev_add.c @@ -67,7 +67,7 @@ error: return -1; } -static int make_node(struct udevice *udev, char *file, int major, int minor, unsigned int mode, uid_t uid, gid_t gid) +int udev_make_node(struct udevice *udev, const char *file, int major, int minor, mode_t mode, uid_t uid, gid_t gid) { struct stat stats; int retval = 0; @@ -183,7 +183,7 @@ static int create_node(struct udevice *udev) if (!udev->test_run) { info("creating device node '%s'", filename); - if (make_node(udev, filename, udev->major, udev->minor, udev->mode, uid, gid) != 0) + if (udev_make_node(udev, filename, udev->major, udev->minor, udev->mode, uid, gid) != 0) goto error; } else { info("creating device node '%s', major = '%d', minor = '%d', " @@ -198,7 +198,7 @@ static int create_node(struct udevice *udev) for (i = 1; i <= udev->partitions; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); - make_node(udev, partitionname, udev->major, udev->minor + i, udev->mode, uid, gid); + udev_make_node(udev, partitionname, udev->major, udev->minor + i, udev->mode, uid, gid); } } } diff --git a/udev_remove.c b/udev_remove.c index 142503589a..e1af3dbef6 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -67,41 +67,6 @@ static int delete_path(const char *path) return 0; } -/** Remove all permissions on the device node, before - * unlinking it. This fixes a security issue. - * If the user created a hard-link to the device node, - * he can't use it any longer, because he lost permission - * to do so. - */ -static int secure_unlink(const char *filename) -{ - int retval; - - retval = chown(filename, 0, 0); - if (retval) { - dbg("chown(%s, 0, 0) failed with error '%s'", - filename, strerror(errno)); - /* We continue nevertheless. - * I think it's very unlikely for chown - * to fail here, if the file exists. - */ - } - retval = chmod(filename, 0000); - if (retval) { - dbg("chmod(%s, 0000) failed with error '%s'", - filename, strerror(errno)); - /* We continue nevertheless. */ - } - retval = unlink(filename); - if (errno == ENOENT) - retval = 0; - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - } - return retval; -} - static int delete_node(struct udevice *udev) { char filename[NAME_SIZE]; @@ -116,7 +81,7 @@ static int delete_node(struct udevice *udev) filename[NAME_SIZE-1] = '\0'; info("removing device node '%s'", filename); - retval = secure_unlink(filename); + retval = unlink_secure(filename); if (retval) return retval; @@ -131,7 +96,7 @@ static int delete_node(struct udevice *udev) for (i = 1; i <= num; i++) { strfieldcpy(partitionname, filename); strintcat(partitionname, i); - secure_unlink(partitionname); + unlink_secure(partitionname); } } diff --git a/udev_utils.c b/udev_utils.c index 5b0355d0e9..ca46258def 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -112,6 +112,31 @@ int create_path(const char *path) return mkdir(p, 0755); } +/* Reset permissions on the device node, before unlinking it to make sure, + * that permisions of possible hard links will be removed to. + */ +int unlink_secure(const char *filename) +{ + int retval; + + retval = chown(filename, 0, 0); + if (retval) + dbg("chown(%s, 0, 0) failed with error '%s'", filename, strerror(errno)); + + retval = chmod(filename, 0000); + if (retval) + dbg("chmod(%s, 0000) failed with error '%s'", filename, strerror(errno)); + + retval = unlink(filename); + if (errno == ENOENT) + retval = 0; + + if (retval) + dbg("unlink(%s) failed with error '%s'", filename, strerror(errno)); + + return retval; +} + int parse_get_pair(char **orig_string, char **left, char **right) { char *temp; diff --git a/udev_utils.h b/udev_utils.h index 5d2c9c580c..19061f16f6 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -80,6 +80,7 @@ extern void udev_init_device(struct udevice *udev, const char* devpath, const ch extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); extern int parse_get_pair(char **orig_string, char **left, char **right); +extern int unlink_secure(const char *filename); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); From 6d56416665863dc2b4fb107dbdc779e4791bdf9e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 9 Feb 2005 08:43:18 +0100 Subject: [PATCH 1137/4284] [PATCH] create /block/*/range count of partitons for all_partitions --- namedev.h | 2 +- namedev_parse.c | 13 ++++++++++++- udev.h | 2 ++ udev_add.c | 18 +++++++++++++++--- udev_remove.c | 2 +- 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/namedev.h b/namedev.h index 8a3569ec7c..43381bfbd6 100644 --- a/namedev.h +++ b/namedev.h @@ -53,7 +53,6 @@ struct sysfs_class_device; #define ATTR_PARTITIONS "all_partitions" #define ATTR_IGNORE_REMOVE "ignore_remove" -#define PARTITIONS_COUNT 15 #define MAX_SYSFS_PAIRS 5 @@ -91,6 +90,7 @@ extern struct list_head config_device_list; extern int namedev_init(void); extern int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev); +extern void namedev_close(void); extern void dump_config_dev(struct config_device *dev); extern void dump_config_dev_list(void); diff --git a/namedev_parse.c b/namedev_parse.c index 5bd59d83f2..7b5b963020 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -250,7 +250,7 @@ static int namedev_parse(const char *filename, void *data) if (attr != NULL) { if (strstr(attr, ATTR_PARTITIONS) != NULL) { dbg_parse("creation of partition nodes requested"); - dev.partitions = PARTITIONS_COUNT; + dev.partitions = DEFAULT_PARTITIONS_COUNT; } if (strstr(attr, ATTR_IGNORE_REMOVE) != NULL) { dbg_parse("remove event should be ignored"); @@ -338,3 +338,14 @@ int namedev_init(void) return retval; } + +void namedev_close(void) +{ + struct config_device *dev; + + list_for_each_entry(dev, &config_device_list, node) { + list_del(&dev->node); + free(dev); + } +} + diff --git a/udev.h b/udev.h index 5beec64557..c2f9859c5a 100644 --- a/udev.h +++ b/udev.h @@ -46,6 +46,8 @@ #define HOTPLUGD_DIR "/etc/hotplug.d" #define HOTPLUG_SUFFIX ".hotplug" +#define DEFAULT_PARTITIONS_COUNT 15 + struct udevice { char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; diff --git a/udev_add.c b/udev_add.c index a495902ab2..c566571c1c 100644 --- a/udev_add.c +++ b/udev_add.c @@ -117,16 +117,16 @@ exit: return retval; } -static int create_node(struct udevice *udev) +static int create_node(struct udevice *udev, struct sysfs_class_device *class_dev) { char filename[NAME_SIZE]; char partitionname[NAME_SIZE]; uid_t uid = 0; gid_t gid = 0; - int i; int tail; char *pos; int len; + int i; snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); filename[NAME_SIZE-1] = '\0'; @@ -154,6 +154,7 @@ static int create_node(struct udevice *udev) if (udev->owner[0] != '\0') { char *endptr; unsigned long id = strtoul(udev->owner, &endptr, 10); + if (endptr[0] == '\0') uid = (uid_t) id; else { @@ -170,6 +171,7 @@ static int create_node(struct udevice *udev) if (udev->group[0] != '\0') { char *endptr; unsigned long id = strtoul(udev->group, &endptr, 10); + if (endptr[0] == '\0') gid = (gid_t) id; else { @@ -193,6 +195,16 @@ static int create_node(struct udevice *udev) /* create all_partitions if requested */ if (udev->partitions > 0) { + struct sysfs_attribute *attr; + int range; + + /* take the maximum registered minor range */ + attr = sysfs_get_classdev_attr(class_dev, "range"); + if (attr) { + range = atoi(attr->value); + 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++) { @@ -298,7 +310,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) selinux_init(); if (udev->type == 'b' || udev->type == 'c') { - retval = create_node(udev); + retval = create_node(udev, class_dev); if (retval != 0) goto exit; diff --git a/udev_remove.c b/udev_remove.c index e1af3dbef6..172ec12690 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -89,7 +89,7 @@ static int delete_node(struct udevice *udev) num = udev->partitions; if (num > 0) { info("removing all_partitions '%s[1-%i]'", filename, num); - if (num > PARTITIONS_COUNT) { + if (num > 255) { info("garbage from udev database, skip all_partitions removal"); return -1; } From fcbb427e0e54ee29a6d11a7130271de0c4edd9c1 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 8 Feb 2005 21:24:29 -0800 Subject: [PATCH 1138/4284] [PATCH] Fix gentoo bug #81102, device nodes for the pktcdvd device. --- etc/udev/gentoo/udev.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index b5f23902cb..c57e7d8239 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -222,3 +222,6 @@ 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" From d35f580b25c20ccc965b00da2464f25c9a8fe62c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 8 Feb 2005 21:27:02 -0800 Subject: [PATCH 1139/4284] [PATCH] Fix gentoo bug #76056 (fb device group permissions.) --- etc/udev/gentoo/udev.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index c57e7d8239..9c267ebf8e 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -60,7 +60,7 @@ KERNEL="dm-[0-9]*", NAME="" KERNEL="device-mapper", NAME="mapper/control" # fb devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", MODE="0600" +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video", MODE="0600" # floppy devices KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy" From 990f059b1eb8af21b978ec1e3f80a9ca7977571f Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 8 Feb 2005 21:32:55 -0800 Subject: [PATCH 1140/4284] [PATCH] Another gentoo fix, adding dvb support. --- etc/udev/gentoo/udev.rules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 9c267ebf8e..e7e17209d5 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -174,6 +174,9 @@ KERNEL="radio[0-9]*", NAME="v4l/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 +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video", MODE="0660" + # Asterix Zaptel devices KERNEL="zapctl", NAME="zap/ctl" KERNEL="zaptimer", NAME="zap/timer" From ee2427d3daafa746649f361b0b464e40b95b8549 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 8 Feb 2005 21:39:54 -0800 Subject: [PATCH 1141/4284] [PATCH] Add infiniband to gentoo rules. --- etc/udev/gentoo/udev.rules | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index e7e17209d5..52e12541f1 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -228,3 +228,7 @@ 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" From 3a030b511f74348a67c413858713c6fe9c85605c Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 8 Feb 2005 21:40:06 -0800 Subject: [PATCH 1142/4284] [PATCH] fix example comment in ide-devfs.sh --- extras/ide-devfs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/ide-devfs.sh b/extras/ide-devfs.sh index 580a751abe..d4c05b5342 100644 --- a/extras/ide-devfs.sh +++ b/extras/ide-devfs.sh @@ -2,7 +2,7 @@ # udev external PROGRAM script # return devfs-names for ide-devices -# BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" +# BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" HOST="${2%\.[0-9]}" TARGET="${2#[0-9]\.}" From 1d62f6e2decfe9085ea9c054a4d327adc8203e94 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Tue, 8 Feb 2005 22:53:37 -0800 Subject: [PATCH 1143/4284] [PATCH] 052 release --- ChangeLog | 39 +++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 42d84563b2..de7f938f26 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +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 ============================================ diff --git a/Makefile b/Makefile index dc907f6a81..b5698eec73 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 051 +VERSION = 052 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index a0fd5b5426..060ee3310c 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 051 +Version: 052 Release: 1 License: GPL Group: Utilities/System From 866bb54704e9d955318e0dd6089acfb67d36bfd2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Feb 2005 05:51:41 +0100 Subject: [PATCH 1144/4284] [PATCH] udev_volume_id: remove __packed__ from dasd structure as it does not work --- extras/volume_id/udev_volume_id.c | 2 +- extras/volume_id/volume_id/dasd/dasd.c | 4 ++-- extras/volume_id/volume_id/dasd/dasd.h | 2 +- udev_utils.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index d3c3fcd505..f04f374c27 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -166,7 +166,7 @@ int main(int argc, char *argv[]) if (vid == NULL) goto exit; - if (volume_id_probe_dasd_partition(vid) == 0) + if (volume_id_probe_dasd(vid) == 0) goto print; } diff --git a/extras/volume_id/volume_id/dasd/dasd.c b/extras/volume_id/volume_id/dasd/dasd.c index 4548190ce2..2df6a09e81 100644 --- a/extras/volume_id/volume_id/dasd/dasd.c +++ b/extras/volume_id/volume_id/dasd/dasd.c @@ -142,7 +142,7 @@ typedef struct dasd_information_t { unsigned int confdata_size; char characteristics[64]; /* from read_device_characteristics */ char configuration_data[256]; /* from read_configuration_data */ -} __attribute__((__packed__)) dasd_information_t; +} dasd_information_t; #define _IOC_NRBITS 8 #define _IOC_TYPEBITS 8 @@ -161,7 +161,7 @@ typedef struct dasd_information_t { #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) #define BLKSSZGET _IO(0x12,104) -int volume_id_probe_dasd_partition(struct volume_id *id) +int volume_id_probe_dasd(struct volume_id *id) { int blocksize; dasd_information_t info; diff --git a/extras/volume_id/volume_id/dasd/dasd.h b/extras/volume_id/volume_id/dasd/dasd.h index e7918948c9..751b9fda60 100644 --- a/extras/volume_id/volume_id/dasd/dasd.h +++ b/extras/volume_id/volume_id/dasd/dasd.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_DASDLABEL_ #define _VOLUME_ID_DASDLABEL_ -extern int volume_id_probe_dasd_partition(struct volume_id *id); +extern int volume_id_probe_dasd(struct volume_id *id); #endif diff --git a/udev_utils.c b/udev_utils.c index ca46258def..fda1f42f7e 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -113,7 +113,7 @@ int create_path(const char *path) } /* Reset permissions on the device node, before unlinking it to make sure, - * that permisions of possible hard links will be removed to. + * that permisions of possible hard links will be removed too. */ int unlink_secure(const char *filename) { From 69aa6dfb7081de376769cf712d1a8832f4346516 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Feb 2005 09:03:55 +0100 Subject: [PATCH 1145/4284] [PATCH] add %P modifier to query the node name of the parent device Events for partition devies may want to read the main block device name to compose it's own name or read a disklabel from the main device. SUBSYSTEM="block", KERNEL="*[1-9]", NAME="%P-p%n" will append the partition number to the name of the main block device. --- namedev.c | 21 +++++++++++++++++++++ test/udev-test.pl | 32 +++++++++++++++++++++++++++++++- udev.8.in | 3 +++ 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/namedev.c b/namedev.c index 332e2d57d8..90d988311e 100644 --- a/namedev.c +++ b/namedev.c @@ -183,6 +183,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, int slen; struct sysfs_attribute *tmpattr; unsigned int next_free_number; + struct sysfs_class_device *class_dev_parent; pos = string; while (1) { @@ -296,6 +297,22 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strfieldcatmax(string, temp2, maxsize); } break; + case 'P': + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent != NULL) { + struct udevice udev_parent; + + dbg("found parent '%s', get the node name", class_dev_parent->path); + memset(&udev_parent, 0x00, sizeof(struct udevice)); + /* lookup the name in the udev_db with the DEVPATH of the parent */ + strfieldcpy(udev_parent.devpath, &class_dev_parent->path[strlen(sysfs_path)]); + if (udev_db_get_device(&udev_parent) == 0) { + strfieldcatmax(string, udev_parent.name, maxsize); + dbg("substitute parent node name'%s'", udev_parent.name); + } else + dbg("parent not found in database"); + } + break; case 'N': if (udev->tmp_node[0] == '\0') { dbg("create temporary device node for callout"); @@ -305,6 +322,10 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strfieldcatmax(string, udev->tmp_node, maxsize); dbg("substitute temporary device node name '%s'", udev->tmp_node); break; + case 'r': + strfieldcatmax(string, udev_root, maxsize); + dbg("substitute udev_root '%s'", udev_root); + break; default: dbg("unknown substitution type '%%%c'", c); break; diff --git a/test/udev-test.pl b/test/udev-test.pl index fa1e4affc6..5a519ef13b 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -968,7 +968,7 @@ KERNEL="sda", NAME="cdrom%e" EOF }, { - desc => "enumeration char test sequence (1/5 keep)", + desc => "enumeration char test sequence 1/5 (keep)", subsys => "block", devpath => "/block/sda", exp_name => "cdrom", @@ -1084,6 +1084,36 @@ EOF exp_name => "sda", conf => < "parent node name substitution test sequence 1/2 (keep)", + subsys => "block", + devpath => "/block/sda", + exp_name => "main_device", + option => "keep", + conf => < "parent node name substitution test sequence 2/2 (clean)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "main_device-part-1", + option => "clean", + conf => < "udev_root substitution", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "start-udev-root-end", + option => "clean", + conf => < Date: Thu, 10 Feb 2005 09:35:52 +0100 Subject: [PATCH 1146/4284] [PATCH] udev_volume_id: remove temporary node creation and parent handling udev can create the temporary node for us now. (On bootup we don't know where a writable filesystem is mounted). Also the parent handling is not needed anymore, cause udev is able to pass us the node name of the parent device. --- extras/volume_id/README | 18 ++---- extras/volume_id/udev_volume_id.c | 102 ++++++------------------------ 2 files changed, 27 insertions(+), 93 deletions(-) diff --git a/extras/volume_id/README b/extras/volume_id/README index 9d881a1a05..d570615e10 100644 --- a/extras/volume_id/README +++ b/extras/volume_id/README @@ -3,43 +3,37 @@ udev_volume_id - partition, filesystem, disklabel reader This program is normally called from a udev rule, to provide udev with the name, uuid or the filesystem type of a partition to name a device node. -udev_volume_id opens the blockdevice specified by the environment variable -DEVPATH and searches for a filesystem superblock to read the label. The -following commandline switches are supported to specify what udev_volume_id +udev_volume_id opens the blockdevice node specified at the commandline. +The following commandline switches are supported to specify what udev_volume_id should print to stdout: no option prints all values -h prints help text -l prints the label of the partition -u prints the uuid of the partition - -d read disk instead of partition - -If -d is specified udev_volume_id tries to read the label from the main -block device where the partition belongs to. For now this is only useful -for s390 dasd labels. udev_volume_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. The following rule will create a symlink named with the label string: - KERNEL="[hs]d*", PROGRAM="/sbin/udev_volume_id -l", SYMLINK="%c" + KERNEL="[hs]d*", PROGRAM="/sbin/udev_volume_id -l %N", SYMLINK="%c" If no label is found udev_volume_id exits with nonzero and the rule will be ignored. To give it a try, you may call it on the commandline: - [root@pim udev.kay]# DEVPATH=/block/hda/hda3 extras/volume_id/udev_volume_id + [root@pim udev.kay]# extras/volume_id/udev_volume_id /dev/hda3 T:ext3 L:Music Store N:Music_Store U:d2da42b5-bbd9-44eb-a72c-cc4542fcb71e - [root@pim udev.kay]# DEVPATH=/block/hda/hda3 extras/volume_id/udev_volume_id -l + [root@pim udev.kay]# extras/volume_id/udev_volume_id -l /dev/hda3 Music_Store - [root@pim udev.kay]# DEVPATH=/block/hda/hda1 extras/volume_id/udev_volume_id -t + [root@pim udev.kay]# extras/volume_id/udev_volume_id -t /dev/hda3 swap diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index f04f374c27..843b70baf5 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -1,10 +1,10 @@ /* * udev_volume_id - udev callout to read filesystem label and uuid * - * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2005 Kay Sievers * * sample udev rule for creation of a symlink with the filsystem uuid: - * KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -u", SYMLINK="%c" + * KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -u %N", SYMLINK="%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 @@ -28,7 +28,6 @@ #include #include -#include "../../libsysfs/sysfs/libsysfs.h" #include "../../udev_utils.h" #include "../../logging.h" #include "volume_id/volume_id.h" @@ -47,49 +46,18 @@ void log_message(int level, const char *format, ...) } #endif -static struct volume_id *open_classdev(struct sysfs_class_device *class_dev) -{ - struct volume_id *vid; - struct sysfs_attribute *attr; - int major, minor; - - attr = sysfs_get_classdev_attr(class_dev, "dev"); - - if (attr == NULL) { - printf("error reading 'dev' attribute\n"); - return NULL; - } - - if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) { - printf("error getting major/minor number\n"); - return NULL; - } - - vid = volume_id_open_dev_t(makedev(major, minor)); - if (vid == NULL) { - printf("error open volume\n"); - return NULL; - } - - return vid; -} +extern int optind; int main(int argc, char *argv[]) { - const char help[] = "usage: udev_volume_id [-t|-l|-u|-d]\n" + const char help[] = "usage: udev_volume_id [-t|-l|-u] \n" " -t filesystem type\n" " -l filesystem label\n" " -u filesystem uuid\n" - " -d disk label from main device\n" "\n"; - static const char short_options[] = "htlud"; - char sysfs_mnt_path[SYSFS_PATH_MAX]; - char dev_path[SYSFS_PATH_MAX]; - struct sysfs_class_device *class_dev = NULL; - struct sysfs_class_device *class_dev_parent = NULL; + static const char short_options[] = "htlu"; struct volume_id *vid = NULL; - char *devpath; - char probe_disk_label = 0; + const char *device; char print = 'a'; static char name[VOLUME_ID_LABEL_SIZE]; int len, i, j; @@ -115,9 +83,6 @@ int main(int argc, char *argv[]) case 'u': print = 'u'; continue; - case 'd': - probe_disk_label = 1; - continue; case 'h': case '?': default: @@ -126,49 +91,26 @@ int main(int argc, char *argv[]) } } - devpath = getenv("DEVPATH"); - if (devpath == NULL) { - printf("error DEVPATH empty\n"); + device = argv[optind]; + if (device == NULL) { + printf(help); + exit(1); + } + + vid = volume_id_open_node(device); + if (vid == NULL) { + printf("error open volume\n"); goto exit; } - if (sysfs_get_mnt_path(sysfs_mnt_path, SYSFS_PATH_MAX) != 0) { - printf("error getting sysfs mount path\n"); - goto exit; - } + if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) + size = 0; - strfieldcpy(dev_path, sysfs_mnt_path); - strfieldcat(dev_path, devpath); + if (volume_id_probe_all(vid, 0, size) == 0) + goto print; - class_dev = sysfs_open_class_device_path(dev_path); - if (class_dev == NULL) { - printf("error getting class device\n"); - goto exit; - } - - if (probe_disk_label == 0) { - vid = open_classdev(class_dev); - if (vid == NULL) - goto exit; - - if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) - size = 0; - - if (volume_id_probe_all(vid, 0, size) == 0) - goto print; - } else { - /* if we are on a partition, open main block device instead */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) - vid = open_classdev(class_dev_parent); - else - vid = open_classdev(class_dev); - if (vid == NULL) - goto exit; - - if (volume_id_probe_dasd(vid) == 0) - goto print; - } + if (volume_id_probe_dasd(vid) == 0) + goto print; printf("unknown volume type\n"); goto exit; @@ -229,8 +171,6 @@ print: rc = 0; exit: - if (class_dev != NULL) - sysfs_close_class_device(class_dev); if (vid != NULL) volume_id_close(vid); From f22e9686fd4f8e602e8dc11a4b06765206f26edf Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Feb 2005 18:26:09 +0100 Subject: [PATCH 1147/4284] [PATCH] udevstart: simplify "dev" file searching Just stat() the "dev" file in the device directory instead of opening the directory and iterating over all entries. Make udevstart work with the settings in with udev.conf so we can run a test program. Add a test for udevstart. Remove changelog stuff from code. We should never start with this silly thing. --- test/udev-test.pl | 8 +-- test/udevstart-test.pl | 58 +++++++++++++++++ udev_start.c | 141 +++++++++++++++++++---------------------- 3 files changed, 125 insertions(+), 82 deletions(-) create mode 100644 test/udevstart-test.pl diff --git a/test/udev-test.pl b/test/udev-test.pl index 5a519ef13b..992fc0019a 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -14,14 +14,8 @@ # After creation and removal the result is checked against the # expected value and the result is printed. # -# happy testing, # Kay Sievers , 2003 -# -# Modified April 9, 2004 by Leann Ogasawara -# - expanded @tests array to add more symlinks and permissions tests -# - some of the symlinks tests also test lack of node creation -# - added symlink_test() function -# - moved permissions and major_minor tests into their own functions +# Leann Ogasawara , 2004 use warnings; use strict; diff --git a/test/udevstart-test.pl b/test/udevstart-test.pl new file mode 100644 index 0000000000..b6f85bb38c --- /dev/null +++ b/test/udevstart-test.pl @@ -0,0 +1,58 @@ +#!/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 $udev_bin = "../udev"; +my $udev_root = "udev-root/"; # !!! directory will be removed !!! +my $udev_db = ".udevdb"; +my $main_conf = "udev-test.conf"; +my $conf_tmp = "udev-test.rules"; + +# set env +$ENV{UDEV_TEST} = "yes"; +$ENV{SYSFS_PATH} = $sysfs; +$ENV{UDEV_CONFIG_FILE} = $main_conf; +$ENV{UDEV_NO_DEVD} = "yes"; +$ENV{UDEV_NO_HOTPLUGD} = "yes"; + +# 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 initial config file +open CONF, ">$main_conf" || die "unable to create config file: $main_conf"; +print CONF "udev_root=\"$udev_root\"\n"; +print CONF "udev_db=\"$udev_db\"\n"; +print CONF "udev_rules=\"$conf_tmp\"\n"; +close CONF; + +system("$udev_bin udevstart"); +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"; + +# cleanup +system("rm -rf $udev_db"); +system("rm -rf $udev_root"); +unlink($conf_tmp); +unlink($main_conf); + diff --git a/udev_start.c b/udev_start.c index 8c7a06b5af..dcb4293345 100644 --- a/udev_start.c +++ b/udev_start.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -40,22 +41,22 @@ #include "udev.h" -#define MAX_PATHLEN 1024 -#define SYSBLOCK "/sys/block" -#define SYSCLASS "/sys/class" +#define MAX_PATH_SIZE 512 struct device { struct list_head list; - char path[MAX_PATHLEN]; - char subsys[MAX_PATHLEN]; + char path[MAX_PATH_SIZE]; + char subsys[MAX_PATH_SIZE]; }; /* sort files in lexical order */ -static int device_list_insert(char *path, char *subsystem, struct list_head *device_list) +static int device_list_insert(const char *path, char *subsystem, struct list_head *device_list) { struct device *loop_device; struct device *new_device; + dbg("insert: '%s'\n", path); + list_for_each_entry(loop_device, device_list, list) { if (strcmp(loop_device->path, path) > 0) { break; @@ -87,18 +88,20 @@ static char *first_list[] = { NULL, }; -static int add_device(char *devpath, char *subsystem) +static int add_device(const char *path, const char *subsystem) { struct udevice udev; - char path[SYSFS_PATH_MAX]; struct sysfs_class_device *class_dev; + const char *devpath; + + devpath = &path[strlen(sysfs_path)]; /* set environment for callouts and dev.d/ */ setenv("DEVPATH", devpath, 1); setenv("SUBSYSTEM", subsystem, 1); - snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath); - path[SYSFS_PATH_MAX-1] = '\0'; + dbg("exec : '%s' (%s)\n", devpath, path); + class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg ("sysfs_open_class_device_path failed"); @@ -127,7 +130,7 @@ static void exec_list(struct list_head *device_list) /* handle the "first" type devices first */ list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { - for (i=0; first_list[i] != NULL; i++) { + for (i = 0; first_list[i] != NULL; i++) { if (strncmp(loop_device->path, first_list[i], strlen(first_list[i])) == 0) { add_device(loop_device->path, loop_device->subsys); list_del(&loop_device->list); @@ -140,7 +143,7 @@ static void exec_list(struct list_head *device_list) /* handle the devices we are allowed to, excluding the "last" type devices */ list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { int found = 0; - for (i=0; last_list[i] != NULL; i++) { + for (i = 0; last_list[i] != NULL; i++) { if (strncmp(loop_device->path, last_list[i], strlen(last_list[i])) == 0) { found = 1; break; @@ -162,56 +165,61 @@ static void exec_list(struct list_head *device_list) } } +static int has_devt(const char *directory) +{ + char filename[MAX_PATH_SIZE]; + struct stat statbuf; + + snprintf(filename, MAX_PATH_SIZE, "%s/dev", directory); + filename[MAX_PATH_SIZE-1] = '\0'; + + if (stat(filename, &statbuf) == 0) + return 1; + + return 0; +} + static void udev_scan_block(void) { + char base[MAX_PATH_SIZE]; DIR *dir; struct dirent *dent; LIST_HEAD(device_list); - dir = opendir(SYSBLOCK); + snprintf(base, MAX_PATH_SIZE, "%s/block", sysfs_path); + base[MAX_PATH_SIZE-1] = '\0'; + + dir = opendir(base); if (dir != NULL) { for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[MAX_PATHLEN]; + char dirname[MAX_PATH_SIZE]; DIR *dir2; struct dirent *dent2; - if ((strcmp(dent->d_name, ".") == 0) || - (strcmp(dent->d_name, "..") == 0)) + if (dent->d_name[0] == '.') continue; - snprintf(dirname, MAX_PATHLEN, "/block/%s", dent->d_name); - dirname[MAX_PATHLEN-1] = '\0'; - device_list_insert(dirname, "block", &device_list); + snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name); + dirname[MAX_PATH_SIZE-1] = '\0'; + if (has_devt(dirname)) + device_list_insert(dirname, "block", &device_list); + else + continue; - snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSBLOCK, dent->d_name); + snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name); dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN]; - DIR *dir3; - struct dirent *dent3; + char dirname2[MAX_PATH_SIZE]; - if ((strcmp(dent2->d_name, ".") == 0) || - (strcmp(dent2->d_name, "..") == 0)) + if (dent2->d_name[0] == '.') continue; - snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); - dirname2[MAX_PATHLEN-1] = '\0'; + snprintf(dirname2, MAX_PATH_SIZE, "%s/%s", dirname, dent2->d_name); + dirname2[MAX_PATH_SIZE-1] = '\0'; - dir3 = opendir(dirname2); - if (dir3 != NULL) { - for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { - char filename[MAX_PATHLEN]; - - if (strcmp(dent3->d_name, "dev") == 0) { - snprintf(filename, MAX_PATHLEN, "/block/%s/%s", - dent->d_name, dent2->d_name); - filename[MAX_PATHLEN-1] = '\0'; - device_list_insert(filename, "block", &device_list); - } - } - closedir(dir3); - } + if (has_devt(dirname2)) + device_list_insert(dirname2, "block", &device_list); } closedir(dir2); } @@ -224,59 +232,42 @@ static void udev_scan_block(void) static void udev_scan_class(void) { + char base[MAX_PATH_SIZE]; DIR *dir; struct dirent *dent; LIST_HEAD(device_list); - dir = opendir(SYSCLASS); + snprintf(base, MAX_PATH_SIZE, "%s/class", sysfs_path); + base[MAX_PATH_SIZE-1] = '\0'; + + dir = opendir(base); if (dir != NULL) { for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[MAX_PATHLEN]; + char dirname[MAX_PATH_SIZE]; DIR *dir2; struct dirent *dent2; - if ((strcmp(dent->d_name, ".") == 0) || - (strcmp(dent->d_name, "..") == 0)) + if (dent->d_name[0] == '.') continue; - snprintf(dirname, MAX_PATHLEN, "%s/%s", SYSCLASS, dent->d_name); - dirname[MAX_PATHLEN-1] = '\0'; + snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name); + dirname[MAX_PATH_SIZE-1] = '\0'; dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATHLEN]; - DIR *dir3; - struct dirent *dent3; + char dirname2[MAX_PATH_SIZE]; - if ((strcmp(dent2->d_name, ".") == 0) || - (strcmp(dent2->d_name, "..") == 0)) + if (dent2->d_name[0] == '.') continue; + snprintf(dirname2, MAX_PATH_SIZE, "%s/%s", dirname, dent2->d_name); + dirname2[MAX_PATH_SIZE-1] = '\0'; + /* pass the net class as it is */ - if (strcmp(dent->d_name, "net") == 0) { - snprintf(dirname2, MAX_PATHLEN, "/class/net/%s", dent2->d_name); + if (strcmp(dent->d_name, "net") == 0) device_list_insert(dirname2, "net", &device_list); - continue; - } - - snprintf(dirname2, MAX_PATHLEN, "%s/%s", dirname, dent2->d_name); - dirname2[MAX_PATHLEN-1] = '\0'; - dir3 = opendir(dirname2); - if (dir3 != NULL) { - for (dent3 = readdir(dir3); dent3 != NULL; dent3 = readdir(dir3)) { - char filename[MAX_PATHLEN]; - - /* pass devices with a "dev" file */ - if (strcmp(dent3->d_name, "dev") == 0) { - snprintf(filename, MAX_PATHLEN, "/class/%s/%s", - dent->d_name, dent2->d_name); - filename[MAX_PATHLEN-1] = '\0'; - device_list_insert(filename, dent->d_name, &device_list); - break; - } - } - closedir(dir3); - } + else if (has_devt(dirname2)) + device_list_insert(dirname2, dent->d_name, &device_list); } closedir(dir2); } From 6a24dc747788b6049ef35607ff252e3965af2ce5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Feb 2005 19:46:50 +0100 Subject: [PATCH 1148/4284] [PATCH] fix special file mode mask for temporary device node --- test/udev-test.pl | 2 +- udev_add.c | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 992fc0019a..1b1ee90922 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1068,7 +1068,7 @@ EOF devpath => "/block/sda", exp_name => "sda", conf => <type) { + case 'b': + mode |= S_IFBLK; + break; + case 'c': + case 'u': + mode |= S_IFCHR; + break; + case 'p': + mode |= S_IFIFO; + break; + default: + dbg("unknown node type %c\n", udev->type); + return -EINVAL; + } + selinux_setfscreatecon(file, udev->kernel_name, mode); retval = mknod(file, mode, makedev(major, minor)); if (retval != 0) { @@ -131,24 +147,8 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); filename[NAME_SIZE-1] = '\0'; - switch (udev->type) { - case 'b': - udev->mode |= S_IFBLK; - break; - case 'c': - case 'u': - udev->mode |= S_IFCHR; - break; - case 'p': - udev->mode |= S_IFIFO; - break; - default: - dbg("unknown node type %c\n", udev->type); - return -EINVAL; - } - /* create parent directories if needed */ - if (strrchr(udev->name, '/')) + if (strchr(udev->name, '/')) create_path(filename); if (udev->owner[0] != '\0') { From fd42f6a170cc9559d8524a248a3e5ab86535024c Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Fri, 11 Feb 2005 03:28:17 +0100 Subject: [PATCH 1149/4284] [PATCH] fix test for temporary nodes --- test/udev-test.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 1b1ee90922..fc0e89eeb3 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1066,9 +1066,9 @@ EOF desc => "temporary node creation test", subsys => "block", devpath => "/block/sda", - exp_name => "sda", + exp_name => "node", conf => < Date: Fri, 11 Feb 2005 03:30:11 +0100 Subject: [PATCH 1150/4284] [PATCH] udev_volume_id: fix typo --- extras/volume_id/volume_id/fat/fat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/volume_id/fat/fat.c b/extras/volume_id/volume_id/fat/fat.c index c6bb491f70..7c658fe5f4 100644 --- a/extras/volume_id/volume_id/fat/fat.c +++ b/extras/volume_id/volume_id/fat/fat.c @@ -345,7 +345,7 @@ fat32: volume_id_set_uuid(id, vs->type.fat32.serno, UUID_DOS); found: - volume_id_set_usage(id, VOLUME_ID_DISKLABEL); + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); id->type = "vfat"; return 0; From 20da7623c7a2e0571e268c7b169f0b2aa958dbc9 Mon Sep 17 00:00:00 2001 From: "greg@kroah.com" Date: Thu, 10 Feb 2005 18:10:36 -0800 Subject: [PATCH 1151/4284] [PATCH] remove gentoo permission file as it's not valid anymore. --- etc/udev/gentoo/udev.permissions | 205 ------------------------------- 1 file changed, 205 deletions(-) delete mode 100644 etc/udev/gentoo/udev.permissions diff --git a/etc/udev/gentoo/udev.permissions b/etc/udev/gentoo/udev.permissions deleted file mode 100644 index 51dd9f290e..0000000000 --- a/etc/udev/gentoo/udev.permissions +++ /dev/null @@ -1,205 +0,0 @@ -# /etc/udev/udev.permissions: permission/ownership map for udev -# $Header: /home/cvsroot/gentoo-x86/sys-fs/udev/files/udev.permissions,v 1.3 2004/01/01 03:41:24 azarah Exp $ - -# console devices -console:root:tty:0600 -tty:root:tty:0666 -tty[0-9]*:root:tty:0660 -vc/[0-9]*:root:tty:0660 - -# pty devices -# Set this to 0660 if you only want users belonging to tty group -# to be able to allocate PTYs -ptmx:root:tty:0666 -pty[p-za-e][0-9a-f]*:root:tty:0660 -tty[p-za-e][0-9a-f]*:root:tty:0660 -pty/m*:root:tty:0660 -vc/s*:root:tty:0660 - -# serial+dialup devices -ttyS*:root:tty:0660 -ippp*:root:tty:0660 -isdn*:root:tty:0660 -isdnctrl*:root:tty:0660 -capi*:root:tty:0660 -dcbri*:root:tty:0660 -ircomm*:root:tty:0660 -ttyUSB*:root:usb:0660 -tts/[0-9]*:root:tty:0660 -tts/USB[0-9]*:root:usb:0660 - -# vc devices -vcs:root:root:0600 -vcs[0-9]*:root:root:0600 -vcsa:root:root:0600 -vcsa[0-9]*:root:root:0600 -vcc/*:root:root:0600 - -# memory devices -random:root:root:0666 -urandom:root:root:0444 -mem:root:kmem:0640 -kmem:root:kmem:0640 -port:root:kmem:0640 -full:root:root:0666 -null:root:root:0666 -zero:root:root:0666 - -# misc devices -misc/nvram:root:root:0660 -misc/rtc:root:root:0664 -misc/inotify:root:root:0666 - -# floppy devices -fd[01]*:root:floppy:0660 - -# audio devices -dsp*:root:audio:0660 -audio*:root:audio:0660 -midi*:root:audio:0660 -mixer*:root:audio:0660 -sequencer*:root:audio:0660 -sound/*:root:audio:0660 -snd/*:root:audio:0660 -beep:root:audio:0660 -admm*:root:audio:0660 -adsp*:root:audio:0660 -aload*:root:audio:0660 -amidi*:root:audio:0660 -dmfm*:root:audio:0660 -dmmidi*:root:audio:0660 -sndstat:root:audio:0660 - -# optical devices -sr*:root:cdrom:660 -scd*:root:cdrom:660 -pcd*:root:cdrom:0660 -cdrom*:root:cdrom:0660 -dvd:root:cdrom:0660 -rdvd:root:cdrom:0660 -cdroms/*:root:cdrom:0660 - -# pilot/palm devices -pilot:root:uucp:0660 - -# jaz devices -jaz*:root:disk:0660 - -# zip devices -pocketzip*:root:disk:0660 -zip*:root:disk:0660 - -# ls120 devices -ls120:root:disk:0660 -ls120*:root:disk:0660 - -# lp devices -lp*:root:lp:0660 -parport*:root:lp:0660 -irlpt*:root:lp:0660 -usblp*:root:lp:0660 -usb/lp*:root:lp:0660 - -# scanner devices -scanner:root:root:0600 -usb/scanner*:root:root:0600 - -# camera devices -camera*:root:root:0600 -usb/dc2xx*:root:root:0600 -usb/mdc800*:root:root:0600 - -# raw devices -ram*:root:disk:660 -raw/*:root:disk:660 - -# disk devices -hd*:root:disk:660 -sd*:root:disk:660 -dasd*:root:disk:660 -ataraid*:root:disk:660 -loop*:root:disk:660 -md*:root:disk:660 -ide/*/*/*/*/*:root:disk:660 -discs/*/*:root:disk:660 -loop/*:root:disk:660 -md/*:root:disk:660 - -# tape devices -ht*:root:tape:0660 -nht*:root:tape:0660 -pt[0-9]*:root:tape:0660 -npt*:root:tape:0660 -st*:root:tape:0660 -nst*:root:tape:0660 - -# dm devices -dm-*:root:root:0640 - -# memstick devices -memstick*:root:root:0600 - -# flash devices -flash*:root:root:0600 - -# diskonkey devices -diskonkey*:root:disk:0660 - -# rem_ide devices -microdrive*:root:disk:0660 - -# fb devices -fb:root:root:0600 -fb[0-9]*:root:root:0600 -fb/*:root:root:0600 - -# kbd devices -kbd:root:root:0644 - -# joystick devices -js[0-9]*:root:root:0644 -djs[0-9]*:root:root:0644 - -# v4l devices -video*:root:video:0660 -radio*:root:video:0660 -winradio*:root:video:0660 -vtx*:root:video:0660 -vbi*:root:video:0660 -video/*:root:video:0660 -vttuner:root:video:0660 -v4l/*:root:video:0660 - -# input devices -input/event*:root:root:600 -input/ts*:root:root:600 -input/*:root:root:644 - -# Sony Vaio Jogdial sonypi device -sonypi:root:root:0666 - -# gpm devices -gpmctl:root:root:0700 - -# dri devices -nvidia*:root:video:0660 -3dfx*:root:video:0660 -dri/*:root:video:0660 - -# mainboard devices -apm_bios:root:root:0600 - -# scsi devices -sg*:root:disk:0660 -pg*:root:disk:0660 -cdwriter:root:disk:0660 - -# usb devices -usb/dabusb*:root:usb:0660 -usb/mdc800*:root:usb:0660 -usb/rio500:root:usb:0660 -usb/legousbtower*:root:usb:0660 - -sgi_fetchop:root:root:666 -iseries/vcd*:root:disk:660 -iseries/vd*:root:disk:660 From 07544a93d6c75361b4906d90945755e34fd07565 Mon Sep 17 00:00:00 2001 From: "patmans@us.ibm.com" Date: Fri, 11 Feb 2005 18:30:01 -0800 Subject: [PATCH 1152/4284] [PATCH] scsi_id changes for use with udev %N and %p Changes to scsi_id to support the udev %N and %p substitutions: - Update version from .7 to .8 - change TMP_DIR back to /tmp - if DEVPATH is set assume hotplug_mode (use syslog for logging, and does not output some warnings) - Always output a newline after the id is printed - Allow command line options to override settings when hotplug_mode is set - update man page - update generator script to use the %N and %p substitutions. --- extras/scsi_id/Makefile | 2 +- extras/scsi_id/gen_scsi_id_udev_rules.sh | 2 +- extras/scsi_id/scsi_id.8 | 23 +++++++------ extras/scsi_id/scsi_id.c | 41 ++++++++---------------- 4 files changed, 29 insertions(+), 39 deletions(-) diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 610faac4b7..e832102e30 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.7 +SCSI_ID_VERSION=0.8 prefix = etcdir = ${prefix}/etc diff --git a/extras/scsi_id/gen_scsi_id_udev_rules.sh b/extras/scsi_id/gen_scsi_id_udev_rules.sh index 874e94e8bb..92fde5df1b 100644 --- a/extras/scsi_id/gen_scsi_id_udev_rules.sh +++ b/extras/scsi_id/gen_scsi_id_udev_rules.sh @@ -60,7 +60,7 @@ do if [ $first_line = "yes" ] then first_line=no - echo "BUS=\"scsi\", PROGRAM=\"${scsi_id}\", RESULT=\"${id}\", NAME=\"${prefix}${name}%n\"" + echo "BUS=\"scsi\", PROGRAM=\"${scsi_id} -d %N -s %p\", RESULT=\"${id}\", NAME=\"${prefix}${name}%n\"" echo echo "# Further RESULT keys use the result of the last PROGRAM rule." echo "# Be careful not to add any rules containing PROGRAM key between here" diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index 591bb79366..68d4a1c041 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -53,9 +53,10 @@ identifier starts with the NAA value of 6): .SH OPTIONS .TP .BI subsystem -When called with only a single argument without a leading \-, runs in a hotplug -mode, and expects the environment variable DEVPATH to specify the -corresponding sysfs device. See section below on usage with \fBudev\fP. +Deprecated method: when called with only a single argument without a +leading \-, runs in a hotplug mode, and expects the environment variable +DEVPATH to specify the corresponding sysfs device. See section below on +usage with \fBudev\fP. .TP .BI \-b The default behaviour \- treat the device as black listed, and do nothing @@ -66,6 +67,8 @@ 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 \-f "\| config\-file" Read configuration and black/white list entries from @@ -106,15 +109,15 @@ Display version number and exit. .RE .SH USAGE WITH UDEV + If \fBscsi_id\fP is invoked with one argument without a leading \-, it assumes it is called for a hotplug event, and looks for the sysfs device -in the DEVPATH environment variable. +in the DEVPATH environment variable. This mode is deprecated, but +available for backwards compatibility. -This mode is used when run via the \fBudev\fP PROGRAM key. Passing any -arguments or options as part of the PROGRAM rule breaks this assumption, -and the results will likely not be as expected. - -When in this mode, all errors and warnings are sent via syslog. +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. To determine the specific value needed in a RESULT key, use the \-s option, for example: @@ -131,7 +134,7 @@ of 312345: .sp .nf -BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="312345", NAME="disk%n" +BUS="scsi", PROGRAM="/sbin/scsi_id -d %N -s %p", RESULT="312345", NAME="disk%n" .fi .P diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index f45563d1b3..507fa27766 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -44,8 +44,8 @@ /* * temporary names for mknod. */ -#define TMP_DIR "/dev" -#define TMP_PREFIX "tmp-scsi" +#define TMP_DIR "/tmp" +#define TMP_PREFIX "scsi" /* * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout) @@ -736,9 +736,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) format_serial(serial); if (display_bus_id) printf("%s: ", scsi_dev->name); - printf("%s", serial); - if (!hotplug_mode) - printf("\n"); + printf("%s\n", serial); dprintf("%s\n", serial); retval = 0; } @@ -762,11 +760,6 @@ int main(int argc, char **argv) if (getenv("DEBUG")) debug++; - if ((argc == 2) && (argv[1][0] != '-')) { - hotplug_mode = 1; - dprintf("hotplug assumed\n"); - } - dprintf("argc is %d\n", argc); if (sysfs_get_mnt_path(sysfs_mnt_path, MAX_NAME_LEN)) { log_message(LOG_WARNING, "sysfs_get_mnt_path failed: %s\n", @@ -774,27 +767,19 @@ int main(int argc, char **argv) exit(1); } - if (hotplug_mode) { + devpath = getenv("DEVPATH"); + if (devpath) { /* - * There is a kernel race creating attributes, if called - * directly, uncomment the sleep. + * This implies that we were invoked via udev or hotplug. */ - /* sleep(1); */ - - devpath = getenv("DEVPATH"); - if (!devpath) { - log_message(LOG_WARNING, "DEVPATH is not set\n"); - exit(1); - } + hotplug_mode = 1; sys_specified = 1; - strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); strncat(target_path, devpath, MAX_NAME_LEN); } /* - * Override any command line options set via the config file. This - * is the only way to set options when in hotplug mode. + * Get config file options. */ newargv = NULL; retval = get_file_options(NULL, NULL, &newargc, &newargv); @@ -806,11 +791,13 @@ int main(int argc, char **argv) exit(1); free(newargv); } - if (!hotplug_mode) { - if (set_options(argc, argv, short_options, target_path, - maj_min_dev) < 0) + /* + * Get command line options (overriding any config file or DEVPATH + * settings). + */ + if (set_options(argc, argv, short_options, target_path, + maj_min_dev) < 0) exit(1); - } if (!sys_specified) { log_message(LOG_WARNING, "-s must be specified\n"); From 6b3df4310f38683ff24d23688d4941fb395682d1 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Fri, 11 Feb 2005 18:37:58 -0800 Subject: [PATCH 1153/4284] [PATCH] make the release tarballs have writable files in them. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b5698eec73..7684a4030e 100644 --- a/Makefile +++ b/Makefile @@ -358,7 +358,7 @@ release: spotless -rm -rf $(DISTDIR) mkdir $(DISTDIR) chmod 777 $(DISTDIR) - bk export $(DISTDIR) + bk export -w $(DISTDIR) tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz rm -rf $(DISTDIR) @echo "$(RELEASE_NAME).tar.gz created" From 5f2a5816cf6a67f8a39d082f119fe55c782b882b Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Fri, 11 Feb 2005 18:42:03 -0800 Subject: [PATCH 1154/4284] [PATCH] allow simple-build-check.sh to go faster if MAKEOPTS is set This lets my multiprocessor boxes do the testing quicker... --- test/simple-build-check.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index fa80db4c82..1ebe044b98 100644 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -6,24 +6,24 @@ EXTRAS="extras/chassis_id extras/scsi_id extras/volume_id" echo KERNEL_DIR: "$KERNEL_DIR" make spotless EXTRAS="$EXTRAS" >/dev/null -make all EXTRAS="$EXTRAS" || exit +make all $MAKEOPTS EXTRAS="$EXTRAS" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null -make all DEBUG=true EXTRAS="$EXTRAS" || exit +make all $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null -make all USE_LOG=false EXTRAS="$EXTRAS" || exit +make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null -make all USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit +make all $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null -make all USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit +make all $MAKEOPTS USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null - +echo "build test completed successfully" From bc4235d38ea39593169f473267de2d49bf278844 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Fri, 11 Feb 2005 19:48:04 -0800 Subject: [PATCH 1155/4284] [PATCH] fix gentoo fb permission issue. --- etc/udev/gentoo/udev.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 52e12541f1..9d109d0930 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -60,7 +60,7 @@ KERNEL="dm-[0-9]*", NAME="" KERNEL="device-mapper", NAME="mapper/control" # fb devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video", MODE="0600" +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video" # floppy devices KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy" From 5d2d1e7e85de4ae363c96d1ab9de795b0f106e14 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Fri, 11 Feb 2005 19:55:00 -0800 Subject: [PATCH 1156/4284] [PATCH] 053 release --- ChangeLog | 21 +++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index de7f938f26..68fc6ff2e6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 7684a4030e..d696b8ea3b 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 052 +VERSION = 053 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 060ee3310c..f9dc8f3004 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 052 +Version: 053 Release: 1 License: GPL Group: Utilities/System From f51d8ec66139fd907d971c64e951decdc20eeecb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 11 Feb 2005 04:59:28 +0100 Subject: [PATCH 1157/4284] [PATCH] udevinfo: print SUBSYSTEM and DRIVER --- udevinfo.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udevinfo.c b/udevinfo.c index a80ca82e12..a6daf46be6 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -146,6 +146,7 @@ static int print_device_chain(const char *path) /* open sysfs class device directory and print all attributes */ printf(" looking at class device '%s':\n", class_dev->path); + printf(" SUBSYSTEM=\"%s\"\n", class_dev->classname); if (print_all_attributes(class_dev->path) != 0) { printf("couldn't open class device directory\n"); retval = -1; @@ -167,6 +168,7 @@ static int print_device_chain(const char *path) printf(" looking at the device chain at '%s':\n", sysfs_dev->path); printf(" BUS=\"%s\"\n", sysfs_dev->bus); printf(" ID=\"%s\"\n", sysfs_dev->bus_id); + printf(" DRIVER=\"%s\"\n", sysfs_dev->driver_name); /* open sysfs device directory and print all attributes */ print_all_attributes(sysfs_dev->path); From 82b1698314f004b9d69a14c5054e5f7699aa33ad Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 11 Feb 2005 05:21:03 +0100 Subject: [PATCH 1158/4284] [PATCH] namedev: if SUBSYSTEM or KERNEL key doesn't match, give up immediately We don't need to look at the parents in the device chain. There will never be another kernel name or subsystem. --- namedev.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/namedev.c b/namedev.c index 90d988311e..bbc5b40069 100644 --- a/namedev.c +++ b/namedev.c @@ -583,32 +583,15 @@ static int match_rule(struct udevice *udev, struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { while (1) { - /* check for matching bus value */ - if (dev->bus[0] != '\0') { - if (sysfs_device == NULL) { - dbg("device has no bus"); - goto try_parent; - } - dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", - dev->bus, sysfs_device->bus); - if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { - dbg(FIELD_BUS " is not matching"); - goto try_parent; - } else { - dbg(FIELD_BUS " matches"); - } - } - /* check for matching kernel name */ if (dev->kernel[0] != '\0') { dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { dbg(FIELD_KERNEL " is not matching"); - goto try_parent; - } else { - dbg(FIELD_KERNEL " matches"); + goto exit; } + dbg(FIELD_KERNEL " matches"); } /* check for matching subsystem */ @@ -617,10 +600,9 @@ static int match_rule(struct udevice *udev, struct config_device *dev, dev->subsystem, class_dev->name); if (strcmp_pattern(dev->subsystem, udev->subsystem) != 0) { dbg(FIELD_SUBSYSTEM " is not matching"); - goto try_parent; - } else { - dbg(FIELD_SUBSYSTEM " matches"); + goto exit; } + dbg(FIELD_SUBSYSTEM " matches"); } /* check for matching driver */ @@ -635,6 +617,21 @@ static int match_rule(struct udevice *udev, struct config_device *dev, } } + /* check for matching bus value */ + if (dev->bus[0] != '\0') { + if (sysfs_device == NULL) { + dbg("device has no bus"); + goto try_parent; + } + dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", + dev->bus, sysfs_device->bus); + if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { + dbg(FIELD_BUS " is not matching"); + goto try_parent; + } + dbg(FIELD_BUS " matches"); + } + /* check for matching bus id */ if (dev->id[0] != '\0') { dbg("check " FIELD_ID); @@ -695,17 +692,20 @@ static int match_rule(struct udevice *udev, struct config_device *dev, } } - /* Yeah, we matched! */ + /* we matched */ return 0; try_parent: dbg("try parent sysfs device"); sysfs_device = sysfs_get_device_parent(sysfs_device); if (sysfs_device == NULL) - return -ENODEV; + goto exit; dbg("sysfs_device->path='%s'", sysfs_device->path); dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); } + +exit: + return -1; } int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev) From 03a9875bc3ed3c0da226c31e6fe2590a862f6bfe Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 11 Feb 2005 18:33:40 +0100 Subject: [PATCH 1159/4284] [PATCH] namedev: move some matches out of the parent loop --- namedev.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/namedev.c b/namedev.c index bbc5b40069..c8e24db548 100644 --- a/namedev.c +++ b/namedev.c @@ -582,29 +582,29 @@ static int match_place(struct config_device *dev, struct sysfs_class_device *cla static int match_rule(struct udevice *udev, struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { + /* check for matching kernel name */ + if (dev->kernel[0] != '\0') { + dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", + dev->kernel, class_dev->name); + if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { + dbg(FIELD_KERNEL " is not matching"); + goto exit; + } + dbg(FIELD_KERNEL " matches"); + } + + /* check for matching subsystem */ + if (dev->subsystem[0] != '\0') { + dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' class_dev->name='%s'", + dev->subsystem, class_dev->name); + if (strcmp_pattern(dev->subsystem, udev->subsystem) != 0) { + dbg(FIELD_SUBSYSTEM " is not matching"); + goto exit; + } + dbg(FIELD_SUBSYSTEM " matches"); + } + while (1) { - /* check for matching kernel name */ - if (dev->kernel[0] != '\0') { - dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", - dev->kernel, class_dev->name); - if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { - dbg(FIELD_KERNEL " is not matching"); - goto exit; - } - dbg(FIELD_KERNEL " matches"); - } - - /* check for matching subsystem */ - if (dev->subsystem[0] != '\0') { - dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' class_dev->name='%s'", - dev->subsystem, class_dev->name); - if (strcmp_pattern(dev->subsystem, udev->subsystem) != 0) { - dbg(FIELD_SUBSYSTEM " is not matching"); - goto exit; - } - dbg(FIELD_SUBSYSTEM " matches"); - } - /* check for matching driver */ if (dev->driver[0] != '\0') { dbg("check for " FIELD_DRIVER " dev->driver='%s' sysfs_device->driver_name='%s'", From e57e7bc10811fa87e5775012da9e9b2fb67099c3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 14 Feb 2005 01:46:05 +0100 Subject: [PATCH 1160/4284] [PATCH] namedev: execute PROGRAM only once and not possibly for every physical device --- namedev.c | 73 ++++++++++++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/namedev.c b/namedev.c index c8e24db548..42e8032be5 100644 --- a/namedev.c +++ b/namedev.c @@ -604,6 +604,7 @@ static int match_rule(struct udevice *udev, struct config_device *dev, dbg(FIELD_SUBSYSTEM " matches"); } + /* walk up the chain of physical devices and find a match */ while (1) { /* check for matching driver */ if (dev->driver[0] != '\0') { @@ -612,9 +613,8 @@ static int match_rule(struct udevice *udev, struct config_device *dev, if (strcmp_pattern(dev->driver, sysfs_device->driver_name) != 0) { dbg(FIELD_DRIVER " is not matching"); goto try_parent; - } else { - dbg(FIELD_DRIVER " matches"); } + dbg(FIELD_DRIVER " matches"); } /* check for matching bus value */ @@ -638,9 +638,8 @@ static int match_rule(struct udevice *udev, struct config_device *dev, if (match_id(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_ID " is not matching"); goto try_parent; - } else { - dbg(FIELD_ID " matches"); } + dbg(FIELD_ID " matches"); } /* check for matching place of device */ @@ -649,9 +648,8 @@ static int match_rule(struct udevice *udev, struct config_device *dev, if (match_place(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_PLACE " is not matching"); goto try_parent; - } else { - dbg(FIELD_PLACE " matches"); } + dbg(FIELD_PLACE " matches"); } /* check for matching sysfs pairs */ @@ -660,41 +658,12 @@ static int match_rule(struct udevice *udev, struct config_device *dev, if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) { dbg(FIELD_SYSFS " is not matching"); goto try_parent; - } else { - dbg(FIELD_SYSFS " matches"); } + dbg(FIELD_SYSFS " matches"); } - /* execute external program */ - if (dev->program[0] != '\0') { - char program[PROGRAM_SIZE]; - - dbg("check " FIELD_PROGRAM); - strfieldcpy(program, dev->program); - apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - if (execute_program(udev, program, udev->program_result, NAME_SIZE) != 0) { - dbg(FIELD_PROGRAM " returned nonzero"); - goto try_parent; - } else { - dbg(FIELD_PROGRAM " returned successful"); - } - } - - /* check for matching result of external program */ - if (dev->result[0] != '\0') { - dbg("check for " FIELD_RESULT " dev->result='%s', udev->program_result='%s'", - dev->result, udev->program_result); - if (strcmp_pattern(dev->result, udev->program_result) != 0) { - dbg(FIELD_RESULT " is not matching"); - goto try_parent; - } else { - dbg(FIELD_RESULT " matches"); - } - } - - /* we matched */ - return 0; - + /* found matching physical device */ + break; try_parent: dbg("try parent sysfs device"); sysfs_device = sysfs_get_device_parent(sysfs_device); @@ -704,6 +673,34 @@ try_parent: dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); } + /* execute external program */ + if (dev->program[0] != '\0') { + char program[PROGRAM_SIZE]; + + dbg("check " FIELD_PROGRAM); + strfieldcpy(program, dev->program); + apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + if (execute_program(udev, program, udev->program_result, NAME_SIZE) != 0) { + dbg(FIELD_PROGRAM " returned nonzero"); + goto try_parent; + } + dbg(FIELD_PROGRAM " returned successful"); + } + + /* check for matching result of external program */ + if (dev->result[0] != '\0') { + dbg("check for " FIELD_RESULT " dev->result='%s', udev->program_result='%s'", + dev->result, udev->program_result); + if (strcmp_pattern(dev->result, udev->program_result) != 0) { + dbg(FIELD_RESULT " is not matching"); + goto try_parent; + } + dbg(FIELD_RESULT " matches"); + } + + /* rule matches */ + return 0; + exit: return -1; } From fd9efc00a2e477423185c993b8ec4570ef3ee07d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 14 Feb 2005 06:03:06 +0100 Subject: [PATCH 1161/4284] [PATCH] introduce OPTIONS=ignore_device, ignore_remove, all_partitions" key Here we move all possible options into a own key to make it possible to have options-only rules. The options on the NAME key are removed from the man page and will be removed from a future version of udev. For ignore rules, OPTIONS="ignore" should be used. The rule: SUBSYSTEM="block", SYSFS{removable}="1", OPTIONS="all_partitions" will create all partitions for a block device which is known to have removable media (a check for cdrom drives would be needed too). --- namedev.c | 38 +++++++++++++++++++++++--------------- namedev.h | 8 +++++++- namedev_parse.c | 19 +++++++++++++++++++ test/udev-test.pl | 35 +++++++++++++++++++++++++++++++++-- udev.8.in | 29 +++++++++++++++-------------- udev_add.c | 2 +- 6 files changed, 98 insertions(+), 33 deletions(-) diff --git a/namedev.c b/namedev.c index 42e8032be5..5c328594d4 100644 --- a/namedev.c +++ b/namedev.c @@ -4,6 +4,7 @@ * Userspace devfs * * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003-2005 Kay Sievers * * * This program is free software; you can redistribute it and/or modify it @@ -749,14 +750,31 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("process rule"); if (match_rule(udev, dev, class_dev, sysfs_device) == 0) { - /* empty name, symlink and perms will not create any node */ + /* FIXME: remove old style ignore rule and make OPTION="ignore" mandatory */ if (dev->name[0] == '\0' && dev->symlink[0] == '\0' && - dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0') { + dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0' && + !dev->ignore_device && !dev->partitions && !dev->ignore_remove) { info("configured rule in '%s[%i]' applied, '%s' is ignored", dev->config_file, dev->config_line, udev->kernel_name); return -1; } + /* apply options */ + if (dev->ignore_device) { + info("configured rule in '%s[%i]' applied, '%s' is ignored", + dev->config_file, dev->config_line, udev->kernel_name); + return -1; + } + if (dev->ignore_remove) { + udev->ignore_remove = dev->ignore_remove; + dbg_parse("remove event should be ignored"); + } + /* apply all_partitions option only at a main block device */ + if (dev->partitions && udev->type == 'b' && udev->kernel_number[0] == '\0') { + udev->partitions = dev->partitions; + dbg("creation of partition nodes requested"); + } + /* apply permissions */ if (dev->mode != 0000) { udev->mode = dev->mode; @@ -788,11 +806,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d /* rule matches */ if (dev->name[0] != '\0') { - /* apply all_partitions flag only at a main block device */ - if (dev->partitions > 0 && - (udev->type != 'b' || udev->kernel_number[0] != '\0')) - continue; - info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", dev->config_file, dev->config_line, udev->kernel_name, dev->name); @@ -800,15 +813,10 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); strfieldcpy(udev->config_file, dev->config_file); udev->config_line = dev->config_line; - udev->ignore_remove = dev->ignore_remove; - if (udev->type == 'n') - goto exit; - - udev->partitions = dev->partitions; - - 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->type != 'n') + 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); goto exit; } diff --git a/namedev.h b/namedev.h index 43381bfbd6..1e1a9bbc34 100644 --- a/namedev.h +++ b/namedev.h @@ -50,9 +50,11 @@ struct sysfs_class_device; #define FIELD_OWNER "OWNER" #define FIELD_GROUP "GROUP" #define FIELD_MODE "MODE" +#define FIELD_OPTIONS "OPTIONS" -#define ATTR_PARTITIONS "all_partitions" +#define ATTR_IGNORE_DEVICE "ignore_device" #define ATTR_IGNORE_REMOVE "ignore_remove" +#define ATTR_PARTITIONS "all_partitions" #define MAX_SYSFS_PAIRS 5 @@ -77,11 +79,15 @@ struct config_device { char name[NAME_SIZE]; char symlink[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; + char owner[USER_SIZE]; char group[USER_SIZE]; mode_t mode; + int partitions; + int ignore_device; int ignore_remove; + char config_file[NAME_SIZE]; int config_line; }; diff --git a/namedev_parse.c b/namedev_parse.c index 7b5b963020..981daa7b3b 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -4,6 +4,7 @@ * Userspace devfs * * Copyright (C) 2003,2004 Greg Kroah-Hartman + * Copyright (C) 2003-2005 Kay Sievers * * * This program is free software; you can redistribute it and/or modify it @@ -247,6 +248,7 @@ static int namedev_parse(const char *filename, void *data) if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) { attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1); + /* FIXME: remove old style options and make OPTIONS= mandatory */ if (attr != NULL) { if (strstr(attr, ATTR_PARTITIONS) != NULL) { dbg_parse("creation of partition nodes requested"); @@ -286,6 +288,23 @@ static int namedev_parse(const char *filename, void *data) continue; } + if (strcasecmp(temp2, FIELD_OPTIONS) == 0) { + if (strstr(temp3, ATTR_IGNORE_DEVICE) != NULL) { + dbg_parse("device should be ignored"); + dev.ignore_device = 1; + } + if (strstr(temp3, ATTR_IGNORE_REMOVE) != NULL) { + dbg_parse("remove event should be ignored"); + dev.ignore_remove = 1; + } + if (strstr(temp3, ATTR_PARTITIONS) != NULL) { + dbg_parse("creation of partition nodes requested"); + dev.partitions = DEFAULT_PARTITIONS_COUNT; + } + valid = 1; + continue; + } + dbg("unknown type of field '%s'", temp2); goto error; } diff --git a/test/udev-test.pl b/test/udev-test.pl index fc0e89eeb3..5f9c0cb9c5 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1018,6 +1018,37 @@ EOF exp_name => "cdrom", conf => < "ignore rule test", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_error => "yes", + conf => < "all_partitions, option-only rule", + subsys => "block", + devpath => "/block/sda", + exp_name => "node6", + conf => < "all_partitions, option-only rule (fail on partition)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "node6", + exp_error => "yes", + conf => < "node", exp_error => "yes", conf => < "yes", option => "clear", conf => <partitions > 0) { + if (udev->partitions) { struct sysfs_attribute *attr; int range; From 3f930093f9ac79dca6bcc2dcbc8714c143709478 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 16 Feb 2005 23:20:48 +0100 Subject: [PATCH 1162/4284] [PATCH] libsysfs: work around a klibc bug --- libsysfs/sysfs_class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index a132bb64cb..4ea7f41c99 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -111,7 +111,7 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) if (c == NULL) { c = strstr(cdev->path, SYSFS_BLOCK_NAME); } else { - c = strstr(c, "/"); + c = strchr(c, '/'); } if (c == NULL) From 1cec1c241600fc11121f9504bc9e95836c03bd9c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 18 Feb 2005 03:30:03 +0100 Subject: [PATCH 1163/4284] [PATCH] remove the device node only if the major/minor number matches --- test/udev-test.pl | 37 +++++++++++++++---------------------- udev_db.c | 9 +++++++++ udev_remove.c | 10 ++++++++++ 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 5f9c0cb9c5..fe7b932669 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -755,17 +755,6 @@ EOF BUS="scsi", KERNEL="sda", SYMLINK="symlink-only1" BUS="scsi", KERNEL="sda", SYMLINK="symlink-only2" BUS="scsi", KERNEL="sda", NAME="link", SYMLINK="symlink0" -EOF - }, - { - desc => "symlink name empty", - subsys => "block", - devpath => "/block/sda", - exp_name => "", - exp_target => "link", - exp_error => "yes", - conf => < "/block/sda", exp_name => ".", exp_target => "link", - exp_error => "yes", + exp_add_error => "yes", + exp_rem_error => "yes", conf => < "/block/sda", exp_name => "symlink", exp_target => "", - exp_error => "yes", + exp_add_error => "yes", conf => < "/block/sda", exp_name => "", exp_target => "", - exp_error => "yes", + exp_add_error => "yes", + exp_rem_error => "yes", conf => < "/class/tty/tty0", exp_name => "link", exp_target => "link", + exp_rem_error => "yes", + option => "clear", conf => < "block", devpath => "/block/sda", exp_name => "node", - exp_error => "yes", + exp_add_error => "yes", conf => < "block", devpath => "/block/sda/sda1", exp_name => "node6", - exp_error => "yes", + exp_add_error => "yes", conf => < "block", devpath => "/block/sda", exp_name => "node", - exp_error => "yes", + exp_rem_error => "yes", conf => < "block", devpath => "/block/sda", exp_name => "node14", - exp_error => "yes", + exp_rem_error => "yes", option => "clear", conf => <{exp_name}\' to \'$config->{exp_target}\'\n"; print "created symlink from: \'$config->{exp_name}\' to \'$2\'\n"; - if ($config->{exp_error}) { + if ($config->{exp_add_error}) { print "as expected "; } else { $error++; @@ -1234,7 +1227,7 @@ sub symlink_test { } else { print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; print "symlink: not created "; - if ($config->{exp_error}) { + if ($config->{exp_add_error}) { print "as expected "; } else { $error++; @@ -1273,7 +1266,7 @@ sub run_test { print "add: ok "; } else { print "add: error "; - if ($config->{exp_error}) { + if ($config->{exp_add_error}) { print "as expected "; } else { print "\n\n"; @@ -1292,7 +1285,7 @@ sub run_test { if ((-e "$PWD/$udev_root$config->{exp_name}") || (-l "$PWD/$udev_root$config->{exp_name}")) { print "remove: error "; - if ($config->{exp_error}) { + if ($config->{exp_rem_error}) { print "as expected\n\n"; } else { print "\n\n"; diff --git a/udev_db.c b/udev_db.c index df7cfbb259..0be7620ad7 100644 --- a/udev_db.c +++ b/udev_db.c @@ -79,6 +79,7 @@ int udev_db_add_device(struct udevice *udev) fprintf(f, "P:%s\n", udev->devpath); fprintf(f, "N:%s\n", udev->name); fprintf(f, "S:%s\n", udev->symlink); + fprintf(f, "M:%u:%u\n", udev->major, udev->minor); fprintf(f, "A:%u\n", udev->partitions); fprintf(f, "R:%u\n", udev->ignore_remove); @@ -90,6 +91,7 @@ int udev_db_add_device(struct udevice *udev) static int parse_db_file(struct udevice *udev, const char *filename) { char line[NAME_SIZE]; + char temp[NAME_SIZE]; char *bufline; char *buf; size_t bufsize; @@ -120,6 +122,13 @@ static int parse_db_file(struct udevice *udev, const char *filename) strncpy(udev->name, &bufline[2], count-2); udev->name[count-2] = '\0'; break; + case 'M': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(temp, &bufline[2], count-2); + temp[count-2] = '\0'; + sscanf(temp, "%u:%u", &udev->major, &udev->minor); + break; case 'S': if (count > NAME_SIZE) count = NAME_SIZE-1; diff --git a/udev_remove.c b/udev_remove.c index 172ec12690..baafdea51a 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -71,6 +71,7 @@ static int delete_node(struct udevice *udev) { char filename[NAME_SIZE]; char partitionname[NAME_SIZE]; + struct stat stats; int retval; int i; char *pos; @@ -80,6 +81,15 @@ static int delete_node(struct udevice *udev) snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); filename[NAME_SIZE-1] = '\0'; + dbg("checking major/minor of device node '%s'", filename); + if (stat(filename, &stats) != 0) + return -1; + + if (udev->major && stats.st_rdev != makedev(udev->major, udev->minor)) { + info("device node '%s' points to a different device, skip removal", filename); + return -1; + } + info("removing device node '%s'", filename); retval = unlink_secure(filename); if (retval) From 7e720bd4ad8257d81d273d98294ebbcc03ade9ba Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 13:44:39 +0100 Subject: [PATCH 1164/4284] [PATCH] switch major/minor to dev_t --- namedev.c | 13 +++++++------ udev.h | 5 ++--- udev_add.c | 43 +++++++++++++------------------------------ udev_db.c | 6 ++++-- udev_remove.c | 2 +- udev_sysfs.c | 17 +++++++++++++++++ udev_sysfs.h | 1 + 7 files changed, 45 insertions(+), 42 deletions(-) diff --git a/namedev.c b/namedev.c index 5c328594d4..e317cc685b 100644 --- a/namedev.c +++ b/namedev.c @@ -228,12 +228,12 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': - strintcatmax(string, udev->minor, maxsize); - dbg("substitute minor number '%u'", udev->minor); + strintcatmax(string, minor(udev->devt), maxsize); + dbg("substitute minor number '%u'", minor(udev->devt)); break; case 'M': - strintcatmax(string, udev->major, maxsize); - dbg("substitute major number '%u'", udev->major); + strintcatmax(string, major(udev->devt), maxsize); + dbg("substitute major number '%u'", major(udev->devt)); break; case 'c': if (strlen(udev->program_result) == 0) @@ -317,8 +317,9 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, case 'N': if (udev->tmp_node[0] == '\0') { dbg("create temporary device node for callout"); - snprintf(udev->tmp_node, NAME_SIZE-1, "%s/.tmp-%u-%u", udev_root, udev->major, udev->minor); - udev_make_node(udev, udev->tmp_node, udev->major, udev->minor, 0600, 0, 0); + snprintf(udev->tmp_node, NAME_SIZE, "%s/.tmp-%u-%u", udev_root, major(udev->devt), minor(udev->devt)); + udev->tmp_node[NAME_SIZE] = '\0'; + udev_make_node(udev, udev->tmp_node, udev->devt, 0600, 0, 0); } strfieldcatmax(string, udev->tmp_node, maxsize); dbg("substitute temporary device node name '%s'", udev->tmp_node); diff --git a/udev.h b/udev.h index c2f9859c5a..2d2ef364b6 100644 --- a/udev.h +++ b/udev.h @@ -58,8 +58,7 @@ struct udevice { char group[USER_SIZE]; mode_t mode; char type; - int major; - int minor; + dev_t devt; char devname[NAME_SIZE]; char tmp_node[NAME_SIZE]; @@ -79,7 +78,7 @@ extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix); -extern int udev_make_node(struct udevice *udev, const char *file, int major, int minor, mode_t mode, uid_t uid, gid_t gid); +extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); extern char sysfs_path[SYSFS_PATH_MAX]; extern char udev_root[PATH_MAX]; diff --git a/udev_add.c b/udev_add.c index f384ea96e5..66264f06e0 100644 --- a/udev_add.c +++ b/udev_add.c @@ -39,35 +39,15 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "udev_utils.h" +#include "udev_sysfs.h" #include "udev_version.h" #include "logging.h" #include "namedev.h" #include "udev_db.h" #include "udev_selinux.h" -/* - * the major/minor of a device is stored in a file called "dev" - * The number is stored in decimal values in the format: M:m - */ -static int get_major_minor(struct sysfs_class_device *class_dev, struct udevice *udev) -{ - struct sysfs_attribute *attr = NULL; - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr == NULL) - goto error; - dbg("dev='%s'", attr->value); - - if (sscanf(attr->value, "%u:%u", &udev->major, &udev->minor) != 2) - goto error; - dbg("found major=%d, minor=%d", udev->major, udev->minor); - - return 0; -error: - return -1; -} - -int udev_make_node(struct udevice *udev, const char *file, int major, int minor, mode_t mode, uid_t uid, gid_t gid) +int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid) { struct stat stats; int retval = 0; @@ -77,7 +57,7 @@ int udev_make_node(struct udevice *udev, const char *file, int major, int minor, /* preserve node with already correct numbers, to not change the inode number */ if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && - (stats.st_rdev == makedev(major, minor))) { + (stats.st_rdev == devt)) { dbg("preserve file '%s', cause it has correct dev_t", file); selinux_setfilecon(file, udev->kernel_name, stats.st_mode); goto perms; @@ -106,10 +86,10 @@ create: } selinux_setfscreatecon(file, udev->kernel_name, mode); - retval = mknod(file, mode, makedev(major, minor)); + retval = mknod(file, mode, devt); if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", - file, mode, major, minor, strerror(errno)); + file, mode, major(devt), minor(devt), strerror(errno)); goto exit; } @@ -185,12 +165,12 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de if (!udev->test_run) { info("creating device node '%s'", filename); - if (udev_make_node(udev, filename, udev->major, udev->minor, udev->mode, uid, gid) != 0) + if (udev_make_node(udev, filename, udev->devt, udev->mode, uid, gid) != 0) goto error; } else { info("creating device node '%s', major = '%d', minor = '%d', " "mode = '%#o', uid = '%d', gid = '%d'", filename, - udev->major, udev->minor, udev->mode, uid, gid); + major(udev->devt), minor(udev->devt), udev->mode, uid, gid); } /* create all_partitions if requested */ @@ -208,9 +188,12 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de 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; + strfieldcpy(partitionname, filename); strintcat(partitionname, i); - udev_make_node(udev, partitionname, udev->major, udev->minor + i, udev->mode, uid, gid); + part_devt = makedev(major(udev->devt), minor(udev->devt)+1); + udev_make_node(udev, partitionname, part_devt, udev->mode, uid, gid); } } } @@ -295,8 +278,8 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) int retval = 0; if (udev->type == 'b' || udev->type == 'c') { - retval = get_major_minor(class_dev, udev); - if (retval != 0) { + udev->devt = get_devt(class_dev); + if (!udev->devt) { dbg("no dev-file found, do nothing"); return 0; } diff --git a/udev_db.c b/udev_db.c index 0be7620ad7..b9c504430f 100644 --- a/udev_db.c +++ b/udev_db.c @@ -79,7 +79,7 @@ int udev_db_add_device(struct udevice *udev) fprintf(f, "P:%s\n", udev->devpath); fprintf(f, "N:%s\n", udev->name); fprintf(f, "S:%s\n", udev->symlink); - fprintf(f, "M:%u:%u\n", udev->major, udev->minor); + fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt)); fprintf(f, "A:%u\n", udev->partitions); fprintf(f, "R:%u\n", udev->ignore_remove); @@ -92,6 +92,7 @@ static int parse_db_file(struct udevice *udev, const char *filename) { char line[NAME_SIZE]; char temp[NAME_SIZE]; + unsigned int major, minor; char *bufline; char *buf; size_t bufsize; @@ -127,7 +128,8 @@ static int parse_db_file(struct udevice *udev, const char *filename) count = NAME_SIZE-1; strncpy(temp, &bufline[2], count-2); temp[count-2] = '\0'; - sscanf(temp, "%u:%u", &udev->major, &udev->minor); + sscanf(temp, "%u:%u", &major, &minor); + udev->devt = makedev(major, minor); break; case 'S': if (count > NAME_SIZE) diff --git a/udev_remove.c b/udev_remove.c index baafdea51a..3a3db737c1 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -85,7 +85,7 @@ static int delete_node(struct udevice *udev) if (stat(filename, &stats) != 0) return -1; - if (udev->major && stats.st_rdev != makedev(udev->major, udev->minor)) { + if (udev->devt && stats.st_rdev != udev->devt) { info("device node '%s' points to a different device, skip removal", filename); return -1; } diff --git a/udev_sysfs.c b/udev_sysfs.c index fd7330a161..f0666509ea 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -59,6 +59,23 @@ static const struct subsystem_file { { NULL, NULL } }; +dev_t get_devt(struct sysfs_class_device *class_dev) +{ + struct sysfs_attribute *attr = NULL; + unsigned int major, minor; + + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) + return 0; + dbg("dev='%s'", attr->value); + + if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) + return 0; + dbg("found major=%d, minor=%d", major, minor); + + return makedev(major, minor); +} + int subsystem_expect_no_dev(const char *subsystem) { const struct subsystem_file *file; diff --git a/udev_sysfs.h b/udev_sysfs.h index 98ff53e11a..77c0e6a8ef 100644 --- a/udev_sysfs.h +++ b/udev_sysfs.h @@ -27,6 +27,7 @@ #define WAIT_MAX_SECONDS 5 #define WAIT_LOOP_PER_SECOND 20 +extern dev_t get_devt(struct sysfs_class_device *class_dev); extern int subsystem_expect_no_dev(const char *subsystem); /* /sys/class /sys/block devices */ From 5ef42682053f57fc031d420f0a2ae3e204421b8d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 13:45:04 +0100 Subject: [PATCH 1165/4284] [PATCH] switch device type to enum --- namedev.c | 4 ++-- udev.c | 2 +- udev.h | 8 ++++++++ udev_add.c | 14 +++++--------- udev_remove.c | 2 +- udev_utils.c | 10 +++++----- udevtest.c | 2 +- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/namedev.c b/namedev.c index e317cc685b..146dad604b 100644 --- a/namedev.c +++ b/namedev.c @@ -771,7 +771,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg_parse("remove event should be ignored"); } /* apply all_partitions option only at a main block device */ - if (dev->partitions && udev->type == 'b' && udev->kernel_number[0] == '\0') { + if (dev->partitions && udev->type == BLOCK && udev->kernel_number[0] == '\0') { udev->partitions = dev->partitions; dbg("creation of partition nodes requested"); } @@ -815,7 +815,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d strfieldcpy(udev->config_file, dev->config_file); udev->config_line = dev->config_line; - if (udev->type != 'n') + if (udev->type != NET) 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); diff --git a/udev.c b/udev.c index 122d34c1a5..5dbade3c6f 100644 --- a/udev.c +++ b/udev.c @@ -179,7 +179,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("udev add"); /* skip subsystems without "dev", but handle net devices */ - if (udev.type != 'n' && subsystem_expect_no_dev(udev.subsystem)) { + if (udev.type != NET && subsystem_expect_no_dev(udev.subsystem)) { dbg("don't care about '%s' devices", udev.subsystem); goto hotplug; } diff --git a/udev.h b/udev.h index 2d2ef364b6..17ff4031c9 100644 --- a/udev.h +++ b/udev.h @@ -48,6 +48,14 @@ #define DEFAULT_PARTITIONS_COUNT 15 +enum device_type { + UNKNOWN, + CLASS, + BLOCK, + NET, + PHYSDEV, +}; + struct udevice { char devpath[DEVPATH_SIZE]; char subsystem[SUBSYSTEM_SIZE]; diff --git a/udev_add.c b/udev_add.c index 66264f06e0..eeab1ca174 100644 --- a/udev_add.c +++ b/udev_add.c @@ -70,16 +70,12 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo create: switch (udev->type) { - case 'b': + case BLOCK: mode |= S_IFBLK; break; - case 'c': - case 'u': + case CLASS: mode |= S_IFCHR; break; - case 'p': - mode |= S_IFIFO; - break; default: dbg("unknown node type %c\n", udev->type); return -EINVAL; @@ -277,7 +273,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) char *pos; int retval = 0; - if (udev->type == 'b' || udev->type == 'c') { + if (udev->type == BLOCK || udev->type == CLASS) { udev->devt = get_devt(class_dev); if (!udev->devt) { dbg("no dev-file found, do nothing"); @@ -292,7 +288,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) selinux_init(); - if (udev->type == 'b' || udev->type == 'c') { + if (udev->type == BLOCK || udev->type == CLASS) { retval = create_node(udev, class_dev); if (retval != 0) goto exit; @@ -305,7 +301,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) snprintf(udev->devname, NAME_SIZE, "%s/%s", udev_root, udev->name); udev->devname[NAME_SIZE-1] = '\0'; - } else if (udev->type == 'n') { + } else if (udev->type == NET) { /* look if we want to change the name of the netif */ if (strcmp(udev->name, udev->kernel_name) != 0) { retval = rename_net_if(udev); diff --git a/udev_remove.c b/udev_remove.c index 3a3db737c1..0ba6962cad 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -147,7 +147,7 @@ int udev_remove_device(struct udevice *udev) const char *temp; int retval; - if (udev->type != 'b' && udev->type != 'c') + if (udev->type != BLOCK && udev->type != CLASS) return 0; retval = udev_db_get_device(udev); diff --git a/udev_utils.c b/udev_utils.c index fda1f42f7e..e6580d2c0a 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -47,15 +47,15 @@ void udev_init_device(struct udevice *udev, const char* devpath, const char *sub strfieldcpy(udev->subsystem, subsystem); if (strcmp(udev->subsystem, "block") == 0) - udev->type = 'b'; + udev->type = BLOCK; else if (strcmp(udev->subsystem, "net") == 0) - udev->type = 'n'; + udev->type = NET; else if (strncmp(udev->devpath, "/block/", 7) == 0) - udev->type = 'b'; + udev->type = BLOCK; else if (strncmp(udev->devpath, "/class/net/", 11) == 0) - udev->type = 'n'; + udev->type = NET; else if (strncmp(udev->devpath, "/class/", 7) == 0) - udev->type = 'c'; + udev->type = CLASS; udev->mode = 0660; strcpy(udev->owner, "root"); diff --git a/udevtest.c b/udevtest.c index 4b94442608..4e02ac7dbc 100644 --- a/udevtest.c +++ b/udevtest.c @@ -94,7 +94,7 @@ int main(int argc, char *argv[], char *envp[]) udev_init_device(&udev, devpath, subsystem); /* skip subsystems without "dev", but handle net devices */ - if (udev.type != 'n' && subsystem_expect_no_dev(udev.subsystem)) { + if (udev.type != NET && subsystem_expect_no_dev(udev.subsystem)) { info("don't care about '%s' devices", udev.subsystem); return 2; } From 311a2b0a1d65a1bd02bbedda0dda90f10d6b6788 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 13:45:33 +0100 Subject: [PATCH 1166/4284] [PATCH] clean up match_place() --- namedev.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) diff --git a/namedev.c b/namedev.c index 146dad604b..aa45b79b13 100644 --- a/namedev.c +++ b/namedev.c @@ -553,32 +553,27 @@ static int match_id(struct config_device *dev, struct sysfs_class_device *class_ static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { char path[SYSFS_PATH_MAX]; - int found; - char *temp = NULL; + char *temp; /* we have to have a sysfs device for PLACE to work */ if (!sysfs_device) return -ENODEV; - found = 0; strfieldcpy(path, sysfs_device->path); temp = strrchr(path, '/'); dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); - if (strstr(temp, dev->place) != NULL) { - found = 1; - } else { - *temp = 0x00; - temp = strrchr(path, '/'); - dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); - if (strstr(temp, dev->place) != NULL) - found = 1; - } - if (!found) { - dbg("place doesn't match"); - return -ENODEV; - } + if (strstr(temp, dev->place) != NULL) + return 0; - return 0; + /* try the parent */ + temp[0] = '\0'; + temp = strrchr(path, '/'); + dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); + if (strstr(temp, dev->place) == NULL) + return 0; + + dbg("place doesn't match"); + return -ENODEV; } static int match_rule(struct udevice *udev, struct config_device *dev, From 8f2f6e426fc4cc1fa39b864a1792428a4269b751 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 13:48:10 +0100 Subject: [PATCH 1167/4284] [PATCH] cleanup db functions --- namedev.c | 5 +++-- udev_db.c | 36 +++++++++++++++++++----------------- udev_db.h | 2 +- udev_remove.c | 2 +- udevinfo.c | 3 +-- 5 files changed, 25 insertions(+), 23 deletions(-) diff --git a/namedev.c b/namedev.c index aa45b79b13..c1c22a6cfb 100644 --- a/namedev.c +++ b/namedev.c @@ -299,6 +299,8 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } break; case 'P': + if (!class_dev) + break; class_dev_parent = sysfs_get_classdev_parent(class_dev); if (class_dev_parent != NULL) { struct udevice udev_parent; @@ -306,8 +308,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("found parent '%s', get the node name", class_dev_parent->path); memset(&udev_parent, 0x00, sizeof(struct udevice)); /* lookup the name in the udev_db with the DEVPATH of the parent */ - strfieldcpy(udev_parent.devpath, &class_dev_parent->path[strlen(sysfs_path)]); - if (udev_db_get_device(&udev_parent) == 0) { + if (udev_db_get_device_by_devpath(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) { strfieldcatmax(string, udev_parent.name, maxsize); dbg("substitute parent node name'%s'", udev_parent.name); } else diff --git a/udev_db.c b/udev_db.c index b9c504430f..df63bbe2ce 100644 --- a/udev_db.c +++ b/udev_db.c @@ -4,7 +4,7 @@ * Userspace devfs * * Copyright (C) 2003 Greg Kroah-Hartman - * Copyright (C) 2004 Kay Sievers + * 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 @@ -39,19 +39,19 @@ #define PATH_TO_NAME_CHAR '@' -static int get_db_filename(struct udevice *udev, char *filename, int len) +static int get_db_filename(const char *devpath, char *filename, int len) { - char devpath[SYSFS_PATH_MAX]; + char temp[SYSFS_PATH_MAX]; char *pos; /* replace '/' to transform path into a filename */ - strfieldcpy(devpath, udev->devpath); - pos = strchr(&devpath[1], '/'); + strfieldcpy(temp, devpath); + pos = strchr(&temp[1], '/'); while (pos) { pos[0] = PATH_TO_NAME_CHAR; pos = strchr(&pos[1], '/'); } - snprintf(filename, len, "%s%s", udev_db_path, devpath); + snprintf(filename, len, "%s%s", udev_db_path, temp); filename[len-1] = '\0'; return 0; @@ -65,7 +65,7 @@ int udev_db_add_device(struct udevice *udev) if (udev->test_run) return 0; - get_db_filename(udev, filename, SYSFS_PATH_MAX); + get_db_filename(udev->devpath, filename, SYSFS_PATH_MAX); create_path(filename); @@ -160,25 +160,25 @@ static int parse_db_file(struct udevice *udev, const char *filename) return 0; } -int udev_db_get_device(struct udevice *udev) -{ - char filename[SYSFS_PATH_MAX]; - - get_db_filename(udev, filename, SYSFS_PATH_MAX); - - return parse_db_file(udev, filename); -} - int udev_db_delete_device(struct udevice *udev) { char filename[SYSFS_PATH_MAX]; - get_db_filename(udev, filename, SYSFS_PATH_MAX); + get_db_filename(udev->devpath, filename, SYSFS_PATH_MAX); unlink(filename); return 0; } +int udev_db_get_device_by_devpath(struct udevice *udev, const char *devpath) +{ + char filename[SYSFS_PATH_MAX]; + + get_db_filename(devpath, filename, SYSFS_PATH_MAX); + + return parse_db_file(udev, filename); +} + int udev_db_get_device_byname(struct udevice *udev, const char *name) { struct dirent *ent; @@ -234,6 +234,8 @@ found: strfieldcpy(udev->name, db_udev.name); strfieldcpy(udev->symlink, db_udev.symlink); udev->partitions = db_udev.partitions; + udev->ignore_remove = db_udev.ignore_remove; + udev->devt = db_udev.devt; return 0; } diff --git a/udev_db.h b/udev_db.h index 141c586f24..75f1d98296 100644 --- a/udev_db.h +++ b/udev_db.h @@ -26,9 +26,9 @@ extern int udev_db_add_device(struct udevice *dev); -extern int udev_db_get_device(struct udevice *dev); extern int udev_db_delete_device(struct udevice *dev); +extern int udev_db_get_device_by_devpath(struct udevice *dev, const char *devpath); extern int udev_db_get_device_byname(struct udevice *udev, const char *name); #endif /* _UDEV_DB_H_ */ diff --git a/udev_remove.c b/udev_remove.c index 0ba6962cad..22a363ed34 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -150,7 +150,7 @@ int udev_remove_device(struct udevice *udev) if (udev->type != BLOCK && udev->type != CLASS) return 0; - retval = udev_db_get_device(udev); + retval = udev_db_get_device_by_devpath(udev, udev->devpath); if (retval) { /* fall back to kernel name */ temp = strrchr(udev->devpath, '/'); diff --git a/udevinfo.c b/udevinfo.c index a6daf46be6..e9de6e5e09 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -341,8 +341,7 @@ static int process_options(int argc, char *argv[]) } } memset(&udev, 0x00, sizeof(struct udevice)); - strfieldcpy(udev.devpath, pos); - retval = udev_db_get_device(&udev); + retval = udev_db_get_device_by_devpath(&udev, pos); if (retval != 0) { printf("device not found in database\n"); goto exit; From 5e39f90b14ccf242618086a0242000fc11317a75 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 14:01:23 +0100 Subject: [PATCH 1168/4284] [PATCH] trivial namedev cleanup --- namedev.c | 44 +++++++++++++++++++++++--------------------- namedev.h | 6 +++--- namedev_parse.c | 24 ++++++++++++------------ 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/namedev.c b/namedev.c index c1c22a6cfb..0a37ef2fbc 100644 --- a/namedev.c +++ b/namedev.c @@ -264,28 +264,30 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } break; case 's': - if (attr != NULL) { - tmpattr = find_sysfs_attribute(class_dev, sysfs_device, attr); - if (tmpattr == NULL) { - dbg("sysfa attribute '%s' not found", attr); - break; - } - /* strip trailing whitespace of matching value */ - if (isspace(tmpattr->value[strlen(tmpattr->value)-1])) { - i = len = strlen(tmpattr->value); - while (i > 0 && isspace(tmpattr->value[i-1])) - i--; - if (i < len) { - tmpattr->value[i] = '\0'; - dbg("remove %i trailing whitespace chars from '%s'", - len - i, tmpattr->value); - } - } - strfieldcatmax(string, tmpattr->value, maxsize); - dbg("substitute sysfs value '%s'", tmpattr->value); - } else { + if (!class_dev) + break; + if (attr == NULL) { dbg("missing attribute"); + break; } + tmpattr = find_sysfs_attribute(class_dev, sysfs_device, attr); + if (tmpattr == NULL) { + dbg("sysfa attribute '%s' not found", attr); + break; + } + /* strip trailing whitespace of matching value */ + if (isspace(tmpattr->value[strlen(tmpattr->value)-1])) { + i = len = strlen(tmpattr->value); + while (i > 0 && isspace(tmpattr->value[i-1])) + i--; + if (i < len) { + tmpattr->value[i] = '\0'; + dbg("remove %i trailing whitespace chars from '%s'", + len - i, tmpattr->value); + } + } + strfieldcatmax(string, tmpattr->value, maxsize); + dbg("substitute sysfs value '%s'", tmpattr->value); break; case '%': strfieldcatmax(string, "%", maxsize); @@ -535,7 +537,7 @@ static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_devic static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { char path[SYSFS_PATH_MAX]; - char *temp = NULL; + char *temp; /* we have to have a sysfs device for ID to work */ if (!sysfs_device) diff --git a/namedev.h b/namedev.h index 1e1a9bbc34..a929e52756 100644 --- a/namedev.h +++ b/namedev.h @@ -68,17 +68,17 @@ struct sysfs_pair { struct config_device { struct list_head node; + char kernel[NAME_SIZE]; + char subsystem[SUBSYSTEM_SIZE]; char bus[BUS_SIZE]; char id[ID_SIZE]; char place[PLACE_SIZE]; - char kernel[NAME_SIZE]; + struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; char program[PROGRAM_SIZE]; char result[PROGRAM_SIZE]; - char subsystem[SUBSYSTEM_SIZE]; char driver[DRIVER_SIZE]; char name[NAME_SIZE]; char symlink[NAME_SIZE]; - struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; char owner[USER_SIZE]; char group[USER_SIZE]; diff --git a/namedev_parse.c b/namedev_parse.c index 981daa7b3b..eabd9c98bb 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -171,6 +171,18 @@ static int namedev_parse(const char *filename, void *data) if (retval) break; + if (strcasecmp(temp2, FIELD_KERNEL) == 0) { + strfieldcpy(dev.kernel, temp3); + valid = 1; + continue; + } + + if (strcasecmp(temp2, FIELD_SUBSYSTEM) == 0) { + strfieldcpy(dev.subsystem, temp3); + valid = 1; + continue; + } + if (strcasecmp(temp2, FIELD_BUS) == 0) { strfieldcpy(dev.bus, temp3); valid = 1; @@ -215,18 +227,6 @@ static int namedev_parse(const char *filename, void *data) continue; } - if (strcasecmp(temp2, FIELD_KERNEL) == 0) { - strfieldcpy(dev.kernel, temp3); - valid = 1; - continue; - } - - if (strcasecmp(temp2, FIELD_SUBSYSTEM) == 0) { - strfieldcpy(dev.subsystem, temp3); - valid = 1; - continue; - } - if (strcasecmp(temp2, FIELD_DRIVER) == 0) { strfieldcpy(dev.driver, temp3); valid = 1; From 69f57c6a2b94ae3b70a0ca43b46c30f8dce0a295 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 14:05:52 +0100 Subject: [PATCH 1169/4284] [PATCH] detect NAME="" as ignore_device rule --- namedev.c | 9 --------- namedev_parse.c | 5 ++++- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/namedev.c b/namedev.c index 0a37ef2fbc..a5c711bdf6 100644 --- a/namedev.c +++ b/namedev.c @@ -749,15 +749,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("process rule"); if (match_rule(udev, dev, class_dev, sysfs_device) == 0) { - /* FIXME: remove old style ignore rule and make OPTION="ignore" mandatory */ - if (dev->name[0] == '\0' && dev->symlink[0] == '\0' && - dev->mode == 0000 && dev->owner[0] == '\0' && dev->group[0] == '\0' && - !dev->ignore_device && !dev->partitions && !dev->ignore_remove) { - info("configured rule in '%s[%i]' applied, '%s' is ignored", - dev->config_file, dev->config_line, udev->kernel_name); - return -1; - } - /* apply options */ if (dev->ignore_device) { info("configured rule in '%s[%i]' applied, '%s' is ignored", diff --git a/namedev_parse.c b/namedev_parse.c index eabd9c98bb..7cd676c390 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -259,7 +259,10 @@ static int namedev_parse(const char *filename, void *data) dev.ignore_remove = 1; } } - strfieldcpy(dev.name, temp3); + if (temp3[0] != '\0') + strfieldcpy(dev.name, temp3); + else + dev.ignore_device = 1; valid = 1; continue; } From 9ed47a9f2186b67c0127049fdb4886284bc8a33d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 14:48:12 +0100 Subject: [PATCH 1170/4284] [PATCH] move kernel name/number evaluation into udev_init_device() --- namedev.c | 33 +++---------------------- namedev.h | 4 +-- udev.h | 1 + udev_utils.c | 70 ++++++++++++++++++++++++++++++++++++++-------------- udev_utils.h | 2 +- 5 files changed, 59 insertions(+), 51 deletions(-) diff --git a/namedev.c b/namedev.c index a5c711bdf6..0463d4df0b 100644 --- a/namedev.c +++ b/namedev.c @@ -343,19 +343,6 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } } -static void fix_kernel_name(struct udevice *udev) -{ - char *temp = udev->kernel_name; - - while (*temp != 0x00) { - /* Some block devices have a ! in their name, - * we need to change that to / */ - if (*temp == '!') - *temp = '/'; - ++temp; - } -} - static int execute_program(struct udevice *udev, const char *path, char *value, int len) { int retval; @@ -549,8 +536,8 @@ static int match_id(struct config_device *dev, struct sysfs_class_device *class_ dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); if (strcmp_pattern(dev->id, temp) != 0) return -ENODEV; - else - return 0; + + return 0; } static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) @@ -582,7 +569,6 @@ static int match_place(struct config_device *dev, struct sysfs_class_device *cla static int match_rule(struct udevice *udev, struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - /* check for matching kernel name */ if (dev->kernel[0] != '\0') { dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", dev->kernel, class_dev->name); @@ -593,7 +579,6 @@ static int match_rule(struct udevice *udev, struct config_device *dev, dbg(FIELD_KERNEL " matches"); } - /* check for matching subsystem */ if (dev->subsystem[0] != '\0') { dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' class_dev->name='%s'", dev->subsystem, class_dev->name); @@ -710,7 +695,6 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d struct sysfs_class_device *class_dev_parent; struct sysfs_device *sysfs_device = NULL; struct config_device *dev; - char *pos; dbg("class_dev->name='%s'", class_dev->name); @@ -733,16 +717,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d strfieldcpy(udev->bus_id, sysfs_device->bus_id); } - strfieldcpy(udev->kernel_name, class_dev->name); - fix_kernel_name(udev); - dbg("udev->kernel_name = '%s'", udev->kernel_name); - - /* get kernel number */ - pos = class_dev->name + strlen(class_dev->name); - while (isdigit(*(pos-1))) - pos--; - strfieldcpy(udev->kernel_number, pos); - dbg("kernel_number='%s'", udev->kernel_number); + dbg("udev->kernel_name='%s'", udev->kernel_name); /* look for a matching rule to apply */ list_for_each_entry(dev, &config_device_list, node) { @@ -781,7 +756,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); } - /* collect symlinks for this or the final matching rule */ + /* collect symlinks */ if (dev->symlink[0] != '\0') { char temp[NAME_SIZE]; diff --git a/namedev.h b/namedev.h index a929e52756..3a16144169 100644 --- a/namedev.h +++ b/namedev.h @@ -36,14 +36,14 @@ struct sysfs_class_device; #define DRIVER_SIZE 64 #define PROGRAM_SIZE 128 +#define FIELD_KERNEL "KERNEL" +#define FIELD_SUBSYSTEM "SUBSYSTEM" #define FIELD_BUS "BUS" #define FIELD_SYSFS "SYSFS" #define FIELD_ID "ID" #define FIELD_PLACE "PLACE" #define FIELD_PROGRAM "PROGRAM" #define FIELD_RESULT "RESULT" -#define FIELD_KERNEL "KERNEL" -#define FIELD_SUBSYSTEM "SUBSYSTEM" #define FIELD_DRIVER "DRIVER" #define FIELD_NAME "NAME" #define FIELD_SYMLINK "SYMLINK" diff --git a/udev.h b/udev.h index 17ff4031c9..d6dbd7c332 100644 --- a/udev.h +++ b/udev.h @@ -26,6 +26,7 @@ #include #include #include "libsysfs/sysfs/libsysfs.h" +#include "list.h" #define ALARM_TIMEOUT 120 #define COMMENT_CHARACTER '#' diff --git a/udev_utils.c b/udev_utils.c index e6580d2c0a..ea4aa25c90 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -37,12 +37,16 @@ #include "list.h" -void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem) +int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem) { + char *pos; + memset(udev, 0x00, sizeof(struct udevice)); - if (devpath) + if (devpath) { strfieldcpy(udev->devpath, devpath); + no_trailing_slash(udev->devpath); + } if (subsystem) strfieldcpy(udev->subsystem, subsystem); @@ -60,6 +64,30 @@ void udev_init_device(struct udevice *udev, const char* devpath, const char *sub udev->mode = 0660; strcpy(udev->owner, "root"); strcpy(udev->group, "root"); + + /* get kernel name */ + pos = strrchr(udev->devpath, '/'); + if (pos == NULL) + return -1; + strfieldcpy(udev->kernel_name, &pos[1]); + + /* get kernel number */ + pos = &udev->kernel_name[strlen(udev->kernel_name)]; + while (isdigit(pos[-1])) + pos--; + strfieldcpy(udev->kernel_number, pos); + dbg("kernel_number='%s'", udev->kernel_number); + + /* Some block devices have '!' in their name, change that to '/' */ + pos = udev->kernel_name; + while (pos[0] != '\0') { + if (pos[0] == '!') + pos[0] = '/'; + pos++; + } + + dbg("kernel_name='%s'", udev->kernel_name); + return 0; } int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel) @@ -232,31 +260,35 @@ void no_trailing_slash(char *path) path[--len] = '\0'; } -struct files { - struct list_head list; +struct name_entry { + struct list_head node; char name[NAME_SIZE]; }; /* sort files in lexical order */ -static int file_list_insert(char *filename, struct list_head *file_list) +static int name_list_add(struct list_head *name_list, const char *name, int sort) { - struct files *loop_file; - struct files *new_file; + struct name_entry *loop_name; + struct name_entry *new_name; - list_for_each_entry(loop_file, file_list, list) { - if (strcmp(loop_file->name, filename) > 0) { - break; + list_for_each_entry(loop_name, name_list, node) { + /* avoid doubles */ + if (strcmp(loop_name->name, name) == 0) { + dbg("'%s' is already in the list", name); + return 0; } + if (sort && strcmp(loop_name->name, name) > 0) + break; } - new_file = malloc(sizeof(struct files)); - if (new_file == NULL) { + new_name = malloc(sizeof(struct name_entry)); + if (new_name == NULL) { dbg("error malloc"); return -ENOMEM; } - strfieldcpy(new_file->name, filename); - list_add_tail(&new_file->list, &loop_file->list); + strfieldcpy(new_name->name, name); + list_add_tail(&new_name->node, &loop_name->node); return 0; } @@ -267,8 +299,8 @@ int call_foreach_file(file_fnct_t fnct, const char *dirname, struct dirent *ent; DIR *dir; char *ext; - struct files *loop_file; - struct files *tmp_file; + struct name_entry *loop_file; + struct name_entry *tmp_file; LIST_HEAD(file_list); dbg("open directory '%s'", dirname); @@ -295,11 +327,11 @@ int call_foreach_file(file_fnct_t fnct, const char *dirname, continue; dbg("put file '%s/%s' in list", dirname, ent->d_name); - file_list_insert(ent->d_name, &file_list); + name_list_add(&file_list, ent->d_name, 1); } /* call function for every file in the list */ - list_for_each_entry_safe(loop_file, tmp_file, &file_list, list) { + list_for_each_entry_safe(loop_file, tmp_file, &file_list, node) { char filename[NAME_SIZE]; snprintf(filename, NAME_SIZE, "%s/%s", dirname, loop_file->name); @@ -307,7 +339,7 @@ int call_foreach_file(file_fnct_t fnct, const char *dirname, fnct(filename, data); - list_del(&loop_file->list); + list_del(&loop_file->node); free(loop_file); } diff --git a/udev_utils.h b/udev_utils.h index 19061f16f6..268c2075de 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -76,7 +76,7 @@ do { \ # define asmlinkage /* nothing */ #endif -extern void udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); +extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); extern int parse_get_pair(char **orig_string, char **left, char **right); From 2a9a19245bc5ac49e9f1e1f5d073c53f611fa9e2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 21 Feb 2005 15:01:53 +0100 Subject: [PATCH 1171/4284] [PATCH] determine device type in udev_init_device() --- namedev.c | 1 - udev.c | 9 ++++----- udev_utils.c | 5 +++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/namedev.c b/namedev.c index 0463d4df0b..a365574435 100644 --- a/namedev.c +++ b/namedev.c @@ -201,7 +201,6 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("format=%c, string='%s', tail='%s'",c , string, tail); attr = get_format_attribute(&tail); - switch (c) { case 'p': if (strlen(udev->devpath) == 0) diff --git a/udev.c b/udev.c index 5dbade3c6f..7854bc74d0 100644 --- a/udev.c +++ b/udev.c @@ -152,18 +152,15 @@ int main(int argc, char *argv[], char *envp[]) /* older kernels passed the SUBSYSTEM only as argument */ if (!subsystem && argc == 2) subsystem = argv[1]; - udev_init_device(&udev, devpath, subsystem); if (!action) { dbg("no action"); goto hotplug; } - if (!subsystem) { dbg("no subsystem"); goto hotplug; } - if (!devpath) { dbg("no devpath"); goto hotplug; @@ -173,7 +170,9 @@ int main(int argc, char *argv[], char *envp[]) if (udev_log) setenv("UDEV_LOG", "1", 1); - if ((strncmp(devpath, "/block/", 7) == 0) || (strncmp(devpath, "/class/", 7) == 0)) { + udev_init_device(&udev, devpath, subsystem); + + if (udev.type == BLOCK || udev.type == CLASS || udev.type == NET) { if (strcmp(action, "add") == 0) { /* wait for sysfs and possibly add node */ dbg("udev add"); @@ -221,7 +220,7 @@ int main(int argc, char *argv[], char *envp[]) if (udev_dev_d) udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } - } else if ((strncmp(devpath, "/devices/", 9) == 0)) { + } else if (udev.type == PHYSDEV) { if (strcmp(action, "add") == 0) { /* wait for sysfs */ dbg("devices add"); diff --git a/udev_utils.c b/udev_utils.c index ea4aa25c90..c1e497626e 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -60,6 +60,8 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs udev->type = NET; else if (strncmp(udev->devpath, "/class/", 7) == 0) udev->type = CLASS; + else if (strncmp(udev->devpath, "/devices/", 9) == 0) + udev->type = PHYSDEV; udev->mode = 0660; strcpy(udev->owner, "root"); @@ -293,8 +295,7 @@ static int name_list_add(struct list_head *name_list, const char *name, int sort } /* calls function for every file found in specified directory */ -int call_foreach_file(file_fnct_t fnct, const char *dirname, - const char *suffix, void *data) +int call_foreach_file(file_fnct_t fnct, const char *dirname, const char *suffix, void *data) { struct dirent *ent; DIR *dir; From 9f6f8859b0d17b4df2b739b0b0096f62b34de87a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 22 Feb 2005 21:55:46 +0100 Subject: [PATCH 1172/4284] [PATCH] add "serio" to bus list --- udev_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index f0666509ea..94c0164dec 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -307,6 +307,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "bttv-sub", .file = NULL }, { .bus = "pnp", .file = "detach_state" }, { .bus = "eisa", .file = "detach_state" }, + { .bus = "serio", .file = "detach_state" }, { .bus = "pseudo", .file = "detach_state" }, { .bus = "mmc", .file = "detach_state" }, { .bus = "macio", .file = "detach_state" }, From e4d4a557e53c3fbcf14bd1bb29686fd884905b53 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 23 Feb 2005 02:58:31 +0100 Subject: [PATCH 1173/4284] [PATCH] udev_volume_id: volume_id v35 --- extras/volume_id/udev_volume_id.c | 2 +- extras/volume_id/volume_id/Makefile.inc | 92 +++++++-------- .../volume_id/volume_id/{cramfs => }/cramfs.c | 6 +- .../volume_id/volume_id/{cramfs => }/cramfs.h | 0 extras/volume_id/volume_id/{dasd => }/dasd.c | 6 +- extras/volume_id/volume_id/{dasd => }/dasd.h | 0 extras/volume_id/volume_id/{ext => }/ext.c | 6 +- extras/volume_id/volume_id/{ext => }/ext.h | 0 extras/volume_id/volume_id/{fat => }/fat.c | 6 +- extras/volume_id/volume_id/{fat => }/fat.h | 0 extras/volume_id/volume_id/{hfs => }/hfs.c | 6 +- extras/volume_id/volume_id/{hfs => }/hfs.h | 0 .../volume_id/{highpoint => }/highpoint.c | 6 +- .../volume_id/{highpoint => }/highpoint.h | 0 extras/volume_id/volume_id/{hpfs => }/hpfs.c | 6 +- extras/volume_id/volume_id/{hpfs => }/hpfs.h | 0 .../volume_id/{iso9660 => }/iso9660.c | 6 +- .../volume_id/{iso9660 => }/iso9660.h | 0 extras/volume_id/volume_id/{jfs => }/jfs.c | 6 +- extras/volume_id/volume_id/{jfs => }/jfs.h | 0 .../volume_id/{linux_raid => }/linux_raid.c | 6 +- .../volume_id/{linux_raid => }/linux_raid.h | 0 .../volume_id/{linux_swap => }/linux_swap.c | 6 +- .../volume_id/{linux_swap => }/linux_swap.h | 0 extras/volume_id/volume_id/luks.c | 106 ++++++++++++++++++ extras/volume_id/volume_id/luks.h | 26 +++++ extras/volume_id/volume_id/{lvm => }/lvm.c | 6 +- extras/volume_id/volume_id/{lvm => }/lvm.h | 0 extras/volume_id/volume_id/{mac => }/mac.c | 6 +- extras/volume_id/volume_id/{mac => }/mac.h | 0 .../volume_id/volume_id/{msdos => }/msdos.c | 6 +- .../volume_id/volume_id/{msdos => }/msdos.h | 0 extras/volume_id/volume_id/{ntfs => }/ntfs.c | 6 +- extras/volume_id/volume_id/{ntfs => }/ntfs.h | 0 .../volume_id/{reiserfs => }/reiserfs.c | 6 +- .../volume_id/{reiserfs => }/reiserfs.h | 0 .../volume_id/volume_id/{romfs => }/romfs.c | 6 +- .../volume_id/volume_id/{romfs => }/romfs.h | 0 extras/volume_id/volume_id/{sysv => }/sysv.c | 6 +- extras/volume_id/volume_id/{sysv => }/sysv.h | 0 extras/volume_id/volume_id/{udf => }/udf.c | 6 +- extras/volume_id/volume_id/{udf => }/udf.h | 0 extras/volume_id/volume_id/{ufs => }/ufs.c | 6 +- extras/volume_id/volume_id/{ufs => }/ufs.h | 0 extras/volume_id/volume_id/util.c | 2 + extras/volume_id/volume_id/volume_id.c | 47 ++++---- extras/volume_id/volume_id/volume_id.h | 3 +- extras/volume_id/volume_id/{xfs => }/xfs.c | 6 +- extras/volume_id/volume_id/{xfs => }/xfs.h | 0 49 files changed, 275 insertions(+), 129 deletions(-) rename extras/volume_id/volume_id/{cramfs => }/cramfs.c (96%) rename extras/volume_id/volume_id/{cramfs => }/cramfs.h (100%) rename extras/volume_id/volume_id/{dasd => }/dasd.c (99%) rename extras/volume_id/volume_id/{dasd => }/dasd.h (100%) rename extras/volume_id/volume_id/{ext => }/ext.c (97%) rename extras/volume_id/volume_id/{ext => }/ext.h (100%) rename extras/volume_id/volume_id/{fat => }/fat.c (99%) rename extras/volume_id/volume_id/{fat => }/fat.h (100%) rename extras/volume_id/volume_id/{hfs => }/hfs.c (99%) rename extras/volume_id/volume_id/{hfs => }/hfs.h (100%) rename extras/volume_id/volume_id/{highpoint => }/highpoint.c (96%) rename extras/volume_id/volume_id/{highpoint => }/highpoint.h (100%) rename extras/volume_id/volume_id/{hpfs => }/hpfs.c (96%) rename extras/volume_id/volume_id/{hpfs => }/hpfs.h (100%) rename extras/volume_id/volume_id/{iso9660 => }/iso9660.c (97%) rename extras/volume_id/volume_id/{iso9660 => }/iso9660.h (100%) rename extras/volume_id/volume_id/{jfs => }/jfs.c (96%) rename extras/volume_id/volume_id/{jfs => }/jfs.h (100%) rename extras/volume_id/volume_id/{linux_raid => }/linux_raid.c (97%) rename extras/volume_id/volume_id/{linux_raid => }/linux_raid.h (100%) rename extras/volume_id/volume_id/{linux_swap => }/linux_swap.c (96%) rename extras/volume_id/volume_id/{linux_swap => }/linux_swap.h (100%) create mode 100644 extras/volume_id/volume_id/luks.c create mode 100644 extras/volume_id/volume_id/luks.h rename extras/volume_id/volume_id/{lvm => }/lvm.c (97%) rename extras/volume_id/volume_id/{lvm => }/lvm.h (100%) rename extras/volume_id/volume_id/{mac => }/mac.c (98%) rename extras/volume_id/volume_id/{mac => }/mac.h (100%) rename extras/volume_id/volume_id/{msdos => }/msdos.c (98%) rename extras/volume_id/volume_id/{msdos => }/msdos.h (100%) rename extras/volume_id/volume_id/{ntfs => }/ntfs.c (98%) rename extras/volume_id/volume_id/{ntfs => }/ntfs.h (100%) rename extras/volume_id/volume_id/{reiserfs => }/reiserfs.c (97%) rename extras/volume_id/volume_id/{reiserfs => }/reiserfs.h (100%) rename extras/volume_id/volume_id/{romfs => }/romfs.c (96%) rename extras/volume_id/volume_id/{romfs => }/romfs.h (100%) rename extras/volume_id/volume_id/{sysv => }/sysv.c (97%) rename extras/volume_id/volume_id/{sysv => }/sysv.h (100%) rename extras/volume_id/volume_id/{udf => }/udf.c (98%) rename extras/volume_id/volume_id/{udf => }/udf.h (100%) rename extras/volume_id/volume_id/{ufs => }/ufs.c (98%) rename extras/volume_id/volume_id/{ufs => }/ufs.h (100%) rename extras/volume_id/volume_id/{xfs => }/xfs.c (96%) rename extras/volume_id/volume_id/{xfs => }/xfs.h (100%) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 843b70baf5..c36b89f8bd 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -31,7 +31,7 @@ #include "../../udev_utils.h" #include "../../logging.h" #include "volume_id/volume_id.h" -#include "volume_id/dasd/dasd.h" +#include "volume_id/dasd.h" #define BLKGETSIZE64 _IOR(0x12,114,size_t) diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index d010f7778e..9cadec20cc 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -1,48 +1,50 @@ -VOLUME_ID_OBJS= \ - $(VOLUME_ID_BASE)/ext/ext.o \ - $(VOLUME_ID_BASE)/fat/fat.o \ - $(VOLUME_ID_BASE)/hfs/hfs.o \ - $(VOLUME_ID_BASE)/highpoint/highpoint.o \ - $(VOLUME_ID_BASE)/iso9660/iso9660.o \ - $(VOLUME_ID_BASE)/jfs/jfs.o \ - $(VOLUME_ID_BASE)/linux_raid/linux_raid.o \ - $(VOLUME_ID_BASE)/linux_swap/linux_swap.o \ - $(VOLUME_ID_BASE)/lvm/lvm.o \ - $(VOLUME_ID_BASE)/mac/mac.o \ - $(VOLUME_ID_BASE)/msdos/msdos.o \ - $(VOLUME_ID_BASE)/ntfs/ntfs.o \ - $(VOLUME_ID_BASE)/reiserfs/reiserfs.o \ - $(VOLUME_ID_BASE)/udf/udf.o \ - $(VOLUME_ID_BASE)/ufs/ufs.o \ - $(VOLUME_ID_BASE)/xfs/xfs.o \ - $(VOLUME_ID_BASE)/cramfs/cramfs.o \ - $(VOLUME_ID_BASE)/hpfs/hpfs.o \ - $(VOLUME_ID_BASE)/romfs/romfs.o \ - $(VOLUME_ID_BASE)/sysv/sysv.o \ - $(VOLUME_ID_BASE)/dasd/dasd.o \ - $(VOLUME_ID_BASE)/volume_id.o \ +VOLUME_ID_OBJS= \ + $(VOLUME_ID_BASE)/ext.o \ + $(VOLUME_ID_BASE)/fat.o \ + $(VOLUME_ID_BASE)/hfs.o \ + $(VOLUME_ID_BASE)/highpoint.o \ + $(VOLUME_ID_BASE)/iso9660.o \ + $(VOLUME_ID_BASE)/jfs.o \ + $(VOLUME_ID_BASE)/linux_raid.o \ + $(VOLUME_ID_BASE)/linux_swap.o \ + $(VOLUME_ID_BASE)/lvm.o \ + $(VOLUME_ID_BASE)/mac.o \ + $(VOLUME_ID_BASE)/msdos.o \ + $(VOLUME_ID_BASE)/ntfs.o \ + $(VOLUME_ID_BASE)/reiserfs.o \ + $(VOLUME_ID_BASE)/udf.o \ + $(VOLUME_ID_BASE)/ufs.o \ + $(VOLUME_ID_BASE)/xfs.o \ + $(VOLUME_ID_BASE)/cramfs.o \ + $(VOLUME_ID_BASE)/hpfs.o \ + $(VOLUME_ID_BASE)/romfs.o \ + $(VOLUME_ID_BASE)/sysv.o \ + $(VOLUME_ID_BASE)/dasd.o \ + $(VOLUME_ID_BASE)/luks.o \ + $(VOLUME_ID_BASE)/volume_id.o \ $(VOLUME_ID_BASE)/util.o -VOLUME_ID_HEADERS= \ - $(VOLUME_ID_BASE)/ext/ext.h \ - $(VOLUME_ID_BASE)/fat/fat.h \ - $(VOLUME_ID_BASE)/hfs/hfs.h \ - $(VOLUME_ID_BASE)/highpoint/highpoint.h \ - $(VOLUME_ID_BASE)/iso9660/iso9660.h \ - $(VOLUME_ID_BASE)/jfs/jfs.h \ - $(VOLUME_ID_BASE)/linux_raid/linux_raid.h \ - $(VOLUME_ID_BASE)/linux_swap/linux_swap.h \ - $(VOLUME_ID_BASE)/lvm/lvm.h \ - $(VOLUME_ID_BASE)/mac/mac.h \ - $(VOLUME_ID_BASE)/msdos/msdos.h \ - $(VOLUME_ID_BASE)/ntfs/ntfs.h \ - $(VOLUME_ID_BASE)/reiserfs/reiserfs.h \ - $(VOLUME_ID_BASE)/udf/udf.h \ - $(VOLUME_ID_BASE)/ufs/ufs.h \ - $(VOLUME_ID_BASE)/xfs/xfs.h \ - $(VOLUME_ID_BASE)/cramfs/cramfs.h \ - $(VOLUME_ID_BASE)/sysv/sysv.h \ - $(VOLUME_ID_BASE)/romfs/romfs.h \ - $(VOLUME_ID_BASE)/dasd/dasd.h \ - $(VOLUME_ID_BASE)/volume_id.h \ +VOLUME_ID_HEADERS= \ + $(VOLUME_ID_BASE)/ext.h \ + $(VOLUME_ID_BASE)/fat.h \ + $(VOLUME_ID_BASE)/hfs.h \ + $(VOLUME_ID_BASE)/highpoint.h \ + $(VOLUME_ID_BASE)/iso9660.h \ + $(VOLUME_ID_BASE)/jfs.h \ + $(VOLUME_ID_BASE)/linux_raid.h \ + $(VOLUME_ID_BASE)/linux_swap.h \ + $(VOLUME_ID_BASE)/lvm.h \ + $(VOLUME_ID_BASE)/mac.h \ + $(VOLUME_ID_BASE)/msdos.h \ + $(VOLUME_ID_BASE)/ntfs.h \ + $(VOLUME_ID_BASE)/reiserfs.h \ + $(VOLUME_ID_BASE)/udf.h \ + $(VOLUME_ID_BASE)/ufs.h \ + $(VOLUME_ID_BASE)/xfs.h \ + $(VOLUME_ID_BASE)/cramfs.h \ + $(VOLUME_ID_BASE)/sysv.h \ + $(VOLUME_ID_BASE)/romfs.h \ + $(VOLUME_ID_BASE)/dasd.h \ + $(VOLUME_ID_BASE)/luks.h \ + $(VOLUME_ID_BASE)/volume_id.h \ $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/cramfs/cramfs.c b/extras/volume_id/volume_id/cramfs.c similarity index 96% rename from extras/volume_id/volume_id/cramfs/cramfs.c rename to extras/volume_id/volume_id/cramfs.c index a1d51f107d..a8058646d1 100644 --- a/extras/volume_id/volume_id/cramfs/cramfs.c +++ b/extras/volume_id/volume_id/cramfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "cramfs.h" struct cramfs_super { diff --git a/extras/volume_id/volume_id/cramfs/cramfs.h b/extras/volume_id/volume_id/cramfs.h similarity index 100% rename from extras/volume_id/volume_id/cramfs/cramfs.h rename to extras/volume_id/volume_id/cramfs.h diff --git a/extras/volume_id/volume_id/dasd/dasd.c b/extras/volume_id/volume_id/dasd.c similarity index 99% rename from extras/volume_id/volume_id/dasd/dasd.c rename to extras/volume_id/volume_id/dasd.c index 2df6a09e81..6f403cb928 100644 --- a/extras/volume_id/volume_id/dasd/dasd.c +++ b/extras/volume_id/volume_id/dasd.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "dasd.h" static unsigned char EBCtoASC[256] = diff --git a/extras/volume_id/volume_id/dasd/dasd.h b/extras/volume_id/volume_id/dasd.h similarity index 100% rename from extras/volume_id/volume_id/dasd/dasd.h rename to extras/volume_id/volume_id/dasd.h diff --git a/extras/volume_id/volume_id/ext/ext.c b/extras/volume_id/volume_id/ext.c similarity index 97% rename from extras/volume_id/volume_id/ext/ext.c rename to extras/volume_id/volume_id/ext.c index 0940e452fc..b7bdf05d97 100644 --- a/extras/volume_id/volume_id/ext/ext.c +++ b/extras/volume_id/volume_id/ext.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../util.h" -#include "../logging.h" +#include "volume_id.h" +#include "util.h" +#include "logging.h" #include "ext.h" struct ext2_super_block { diff --git a/extras/volume_id/volume_id/ext/ext.h b/extras/volume_id/volume_id/ext.h similarity index 100% rename from extras/volume_id/volume_id/ext/ext.h rename to extras/volume_id/volume_id/ext.h diff --git a/extras/volume_id/volume_id/fat/fat.c b/extras/volume_id/volume_id/fat.c similarity index 99% rename from extras/volume_id/volume_id/fat/fat.c rename to extras/volume_id/volume_id/fat.c index 7c658fe5f4..58aa2aba05 100644 --- a/extras/volume_id/volume_id/fat/fat.c +++ b/extras/volume_id/volume_id/fat.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "fat.h" #define FAT12_MAX 0xff5 diff --git a/extras/volume_id/volume_id/fat/fat.h b/extras/volume_id/volume_id/fat.h similarity index 100% rename from extras/volume_id/volume_id/fat/fat.h rename to extras/volume_id/volume_id/fat.h diff --git a/extras/volume_id/volume_id/hfs/hfs.c b/extras/volume_id/volume_id/hfs.c similarity index 99% rename from extras/volume_id/volume_id/hfs/hfs.c rename to extras/volume_id/volume_id/hfs.c index 905471cb35..327461c676 100644 --- a/extras/volume_id/volume_id/hfs/hfs.c +++ b/extras/volume_id/volume_id/hfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "hfs.h" struct hfs_finder_info{ diff --git a/extras/volume_id/volume_id/hfs/hfs.h b/extras/volume_id/volume_id/hfs.h similarity index 100% rename from extras/volume_id/volume_id/hfs/hfs.h rename to extras/volume_id/volume_id/hfs.h diff --git a/extras/volume_id/volume_id/highpoint/highpoint.c b/extras/volume_id/volume_id/highpoint.c similarity index 96% rename from extras/volume_id/volume_id/highpoint/highpoint.c rename to extras/volume_id/volume_id/highpoint.c index b301450086..e13fd6de61 100644 --- a/extras/volume_id/volume_id/highpoint/highpoint.c +++ b/extras/volume_id/volume_id/highpoint.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "highpoint.h" struct hpt37x { diff --git a/extras/volume_id/volume_id/highpoint/highpoint.h b/extras/volume_id/volume_id/highpoint.h similarity index 100% rename from extras/volume_id/volume_id/highpoint/highpoint.h rename to extras/volume_id/volume_id/highpoint.h diff --git a/extras/volume_id/volume_id/hpfs/hpfs.c b/extras/volume_id/volume_id/hpfs.c similarity index 96% rename from extras/volume_id/volume_id/hpfs/hpfs.c rename to extras/volume_id/volume_id/hpfs.c index 212e74ee41..a8daea7892 100644 --- a/extras/volume_id/volume_id/hpfs/hpfs.c +++ b/extras/volume_id/volume_id/hpfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "hpfs.h" struct hpfs_super diff --git a/extras/volume_id/volume_id/hpfs/hpfs.h b/extras/volume_id/volume_id/hpfs.h similarity index 100% rename from extras/volume_id/volume_id/hpfs/hpfs.h rename to extras/volume_id/volume_id/hpfs.h diff --git a/extras/volume_id/volume_id/iso9660/iso9660.c b/extras/volume_id/volume_id/iso9660.c similarity index 97% rename from extras/volume_id/volume_id/iso9660/iso9660.c rename to extras/volume_id/volume_id/iso9660.c index 1d7cfd5037..ffccf609dc 100644 --- a/extras/volume_id/volume_id/iso9660/iso9660.c +++ b/extras/volume_id/volume_id/iso9660.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "iso9660.h" #define ISO_SUPERBLOCK_OFFSET 0x8000 diff --git a/extras/volume_id/volume_id/iso9660/iso9660.h b/extras/volume_id/volume_id/iso9660.h similarity index 100% rename from extras/volume_id/volume_id/iso9660/iso9660.h rename to extras/volume_id/volume_id/iso9660.h diff --git a/extras/volume_id/volume_id/jfs/jfs.c b/extras/volume_id/volume_id/jfs.c similarity index 96% rename from extras/volume_id/volume_id/jfs/jfs.c rename to extras/volume_id/volume_id/jfs.c index ab0b83081c..ac4eab502d 100644 --- a/extras/volume_id/volume_id/jfs/jfs.c +++ b/extras/volume_id/volume_id/jfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "jfs.h" struct jfs_super_block { diff --git a/extras/volume_id/volume_id/jfs/jfs.h b/extras/volume_id/volume_id/jfs.h similarity index 100% rename from extras/volume_id/volume_id/jfs/jfs.h rename to extras/volume_id/volume_id/jfs.h diff --git a/extras/volume_id/volume_id/linux_raid/linux_raid.c b/extras/volume_id/volume_id/linux_raid.c similarity index 97% rename from extras/volume_id/volume_id/linux_raid/linux_raid.c rename to extras/volume_id/volume_id/linux_raid.c index ca03030ee4..0ea8596ad6 100644 --- a/extras/volume_id/volume_id/linux_raid/linux_raid.c +++ b/extras/volume_id/volume_id/linux_raid.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "linux_raid.h" struct mdp_super_block { diff --git a/extras/volume_id/volume_id/linux_raid/linux_raid.h b/extras/volume_id/volume_id/linux_raid.h similarity index 100% rename from extras/volume_id/volume_id/linux_raid/linux_raid.h rename to extras/volume_id/volume_id/linux_raid.h diff --git a/extras/volume_id/volume_id/linux_swap/linux_swap.c b/extras/volume_id/volume_id/linux_swap.c similarity index 96% rename from extras/volume_id/volume_id/linux_swap/linux_swap.c rename to extras/volume_id/volume_id/linux_swap.c index 2fb16377a8..39a2c4aab3 100644 --- a/extras/volume_id/volume_id/linux_swap/linux_swap.c +++ b/extras/volume_id/volume_id/linux_swap.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "linux_swap.h" struct swap_header_v1_2 { diff --git a/extras/volume_id/volume_id/linux_swap/linux_swap.h b/extras/volume_id/volume_id/linux_swap.h similarity index 100% rename from extras/volume_id/volume_id/linux_swap/linux_swap.h rename to extras/volume_id/volume_id/linux_swap.h diff --git a/extras/volume_id/volume_id/luks.c b/extras/volume_id/volume_id/luks.c new file mode 100644 index 0000000000..2001692731 --- /dev/null +++ b/extras/volume_id/volume_id/luks.c @@ -0,0 +1,106 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 W. Michael Petullo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "util.h" +#include "logging.h" +#include "luks.h" + +/* from cryptsetup-luks internal.h */ +#define SECTOR_SHIFT 9 +#define SECTOR_SIZE (1 << SECTOR_SHIFT) + +/* from cryptsetup-luks luks.h */ +#define LUKS_CIPHERNAME_L 32 +#define LUKS_CIPHERMODE_L 32 +#define LUKS_HASHSPEC_L 32 +#define LUKS_DIGESTSIZE 20 /* since SHA1 */ +#define LUKS_SALTSIZE 32 +#define LUKS_NUMKEYS 8 + +/* from cryptsetup-luks luks.h */ +const unsigned char LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; +#define LUKS_MAGIC_L 6 + +/* from cryptsetup-luks luks.h */ +#define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1) + +/* from cryptsetup-luks luks.h */ +#define UUID_STRING_L 40 + +int volume_id_probe_luks(struct volume_id *id, __u64 off) +{ + /* from cryptsetup-luks luks.h */ + struct luks_phdr { + char magic[LUKS_MAGIC_L]; + uint16_t version; + char cipherName[LUKS_CIPHERNAME_L]; + char cipherMode[LUKS_CIPHERMODE_L]; + char hashSpec[LUKS_HASHSPEC_L]; + uint32_t payloadOffset; + uint32_t keyBytes; + char mkDigest[LUKS_DIGESTSIZE]; + char mkDigestSalt[LUKS_SALTSIZE]; + uint32_t mkDigestIterations; + char uuid[UUID_STRING_L]; + struct { + uint32_t active; + + /* parameters used for password processing */ + uint32_t passwordIterations; + char passwordSalt[LUKS_SALTSIZE]; + + /* parameters used for AF store/load */ + uint32_t keyMaterialOffset; + uint32_t stripes; + } keyblock[LUKS_NUMKEYS]; + } *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, UUID_DCE); + id->type = "crypto_LUKS"; + + return 0; +} diff --git a/extras/volume_id/volume_id/luks.h b/extras/volume_id/volume_id/luks.h new file mode 100644 index 0000000000..180336f573 --- /dev/null +++ b/extras/volume_id/volume_id/luks.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 W. Michael Petullo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_LUKS_ +#define _VOLUME_ID_LUKS_ + +extern int volume_id_probe_luks(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/lvm/lvm.c b/extras/volume_id/volume_id/lvm.c similarity index 97% rename from extras/volume_id/volume_id/lvm/lvm.c rename to extras/volume_id/volume_id/lvm.c index ed1a83aeb4..bfc2ef2343 100644 --- a/extras/volume_id/volume_id/lvm/lvm.c +++ b/extras/volume_id/volume_id/lvm.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "lvm.h" struct lvm1_super_block { diff --git a/extras/volume_id/volume_id/lvm/lvm.h b/extras/volume_id/volume_id/lvm.h similarity index 100% rename from extras/volume_id/volume_id/lvm/lvm.h rename to extras/volume_id/volume_id/lvm.h diff --git a/extras/volume_id/volume_id/mac/mac.c b/extras/volume_id/volume_id/mac.c similarity index 98% rename from extras/volume_id/volume_id/mac/mac.c rename to extras/volume_id/volume_id/mac.c index 895316d26c..2e2db486f2 100644 --- a/extras/volume_id/volume_id/mac/mac.c +++ b/extras/volume_id/volume_id/mac.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "mac.h" struct mac_driver_desc { diff --git a/extras/volume_id/volume_id/mac/mac.h b/extras/volume_id/volume_id/mac.h similarity index 100% rename from extras/volume_id/volume_id/mac/mac.h rename to extras/volume_id/volume_id/mac.h diff --git a/extras/volume_id/volume_id/msdos/msdos.c b/extras/volume_id/volume_id/msdos.c similarity index 98% rename from extras/volume_id/volume_id/msdos/msdos.c rename to extras/volume_id/volume_id/msdos.c index a90b9efc33..fc2f99d4d0 100644 --- a/extras/volume_id/volume_id/msdos/msdos.c +++ b/extras/volume_id/volume_id/msdos.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "msdos.h" struct msdos_partition_entry { diff --git a/extras/volume_id/volume_id/msdos/msdos.h b/extras/volume_id/volume_id/msdos.h similarity index 100% rename from extras/volume_id/volume_id/msdos/msdos.h rename to extras/volume_id/volume_id/msdos.h diff --git a/extras/volume_id/volume_id/ntfs/ntfs.c b/extras/volume_id/volume_id/ntfs.c similarity index 98% rename from extras/volume_id/volume_id/ntfs/ntfs.c rename to extras/volume_id/volume_id/ntfs.c index e46bc64bb2..84d6fbb843 100644 --- a/extras/volume_id/volume_id/ntfs/ntfs.c +++ b/extras/volume_id/volume_id/ntfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "ntfs.h" struct ntfs_super_block { diff --git a/extras/volume_id/volume_id/ntfs/ntfs.h b/extras/volume_id/volume_id/ntfs.h similarity index 100% rename from extras/volume_id/volume_id/ntfs/ntfs.h rename to extras/volume_id/volume_id/ntfs.h diff --git a/extras/volume_id/volume_id/reiserfs/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c similarity index 97% rename from extras/volume_id/volume_id/reiserfs/reiserfs.c rename to extras/volume_id/volume_id/reiserfs.c index d54013e4c5..b74b8ae576 100644 --- a/extras/volume_id/volume_id/reiserfs/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "reiserfs.h" struct reiserfs_super_block { diff --git a/extras/volume_id/volume_id/reiserfs/reiserfs.h b/extras/volume_id/volume_id/reiserfs.h similarity index 100% rename from extras/volume_id/volume_id/reiserfs/reiserfs.h rename to extras/volume_id/volume_id/reiserfs.h diff --git a/extras/volume_id/volume_id/romfs/romfs.c b/extras/volume_id/volume_id/romfs.c similarity index 96% rename from extras/volume_id/volume_id/romfs/romfs.c rename to extras/volume_id/volume_id/romfs.c index c04dc98f10..fe5e5a4827 100644 --- a/extras/volume_id/volume_id/romfs/romfs.c +++ b/extras/volume_id/volume_id/romfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "romfs.h" struct romfs_super { diff --git a/extras/volume_id/volume_id/romfs/romfs.h b/extras/volume_id/volume_id/romfs.h similarity index 100% rename from extras/volume_id/volume_id/romfs/romfs.h rename to extras/volume_id/volume_id/romfs.h diff --git a/extras/volume_id/volume_id/sysv/sysv.c b/extras/volume_id/volume_id/sysv.c similarity index 97% rename from extras/volume_id/volume_id/sysv/sysv.c rename to extras/volume_id/volume_id/sysv.c index 313ac1732a..6c4408d80c 100644 --- a/extras/volume_id/volume_id/sysv/sysv.c +++ b/extras/volume_id/volume_id/sysv.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "sysv.h" #define SYSV_NICINOD 100 diff --git a/extras/volume_id/volume_id/sysv/sysv.h b/extras/volume_id/volume_id/sysv.h similarity index 100% rename from extras/volume_id/volume_id/sysv/sysv.h rename to extras/volume_id/volume_id/sysv.h diff --git a/extras/volume_id/volume_id/udf/udf.c b/extras/volume_id/volume_id/udf.c similarity index 98% rename from extras/volume_id/volume_id/udf/udf.c rename to extras/volume_id/volume_id/udf.c index 79d25ad890..06b521545f 100644 --- a/extras/volume_id/volume_id/udf/udf.c +++ b/extras/volume_id/volume_id/udf.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "udf.h" struct volume_descriptor { diff --git a/extras/volume_id/volume_id/udf/udf.h b/extras/volume_id/volume_id/udf.h similarity index 100% rename from extras/volume_id/volume_id/udf/udf.h rename to extras/volume_id/volume_id/udf.h diff --git a/extras/volume_id/volume_id/ufs/ufs.c b/extras/volume_id/volume_id/ufs.c similarity index 98% rename from extras/volume_id/volume_id/ufs/ufs.c rename to extras/volume_id/volume_id/ufs.c index 12672ffe01..37e74aee6f 100644 --- a/extras/volume_id/volume_id/ufs/ufs.c +++ b/extras/volume_id/volume_id/ufs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "ufs.h" struct ufs_super_block { diff --git a/extras/volume_id/volume_id/ufs/ufs.h b/extras/volume_id/volume_id/ufs.h similarity index 100% rename from extras/volume_id/volume_id/ufs/ufs.h rename to extras/volume_id/volume_id/ufs.h diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index 0cd2eadec1..6159a59928 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -53,6 +53,8 @@ static char *usage_to_string(enum volume_id_usage usage_id) return "raid"; case VOLUME_ID_DISKLABEL: return "disklabel"; + case VOLUME_ID_CRYPTO: + return "crypto"; case VOLUME_ID_UNPROBED: return "unprobed"; case VOLUME_ID_UNUSED: diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 95f7f5b127..f93cc91161 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -41,25 +41,28 @@ #include "logging.h" #include "util.h" -#include "ext/ext.h" -#include "reiserfs/reiserfs.h" -#include "fat/fat.h" -#include "hfs/hfs.h" -#include "jfs/jfs.h" -#include "xfs/xfs.h" -#include "ufs/ufs.h" -#include "ntfs/ntfs.h" -#include "iso9660/iso9660.h" -#include "udf/udf.h" -#include "highpoint/highpoint.h" -#include "linux_swap/linux_swap.h" -#include "linux_raid/linux_raid.h" -#include "lvm/lvm.h" -#include "cramfs/cramfs.h" -#include "hpfs/hpfs.h" -#include "romfs/romfs.h" -#include "mac/mac.h" -#include "msdos/msdos.h" +#include "ext.h" +#include "reiserfs.h" +#include "fat.h" +#include "hfs.h" +#include "jfs.h" +#include "xfs.h" +#include "ufs.h" +#include "ntfs.h" +#include "iso9660.h" +#include "udf.h" +#include "luks.h" +#include "highpoint.h" +#include "linux_swap.h" +#include "linux_raid.h" +#include "lvm.h" +#include "cramfs.h" +#include "hpfs.h" +#include "romfs.h" +#include "sysv.h" +#include "luks.h" +#include "mac.h" +#include "msdos.h" int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size) { @@ -79,6 +82,9 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_highpoint_ataraid(id, off) == 0) goto exit; + if (volume_id_probe_luks(id, off) == 0) + goto exit; + /* signature in the first block, only small buffer needed */ if (volume_id_probe_vfat(id, off) == 0) goto exit; @@ -128,6 +134,9 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_hpfs(id, off) == 0) goto exit; + if (volume_id_probe_sysv(id, off) == 0) + goto exit; + return -1; exit: diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 5b845602c6..c22a5e60ae 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 34 +#define VOLUME_ID_VERSION 35 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 @@ -38,6 +38,7 @@ enum volume_id_usage { VOLUME_ID_PARTITIONTABLE, VOLUME_ID_RAID, VOLUME_ID_DISKLABEL, + VOLUME_ID_CRYPTO, }; struct volume_id_partition { diff --git a/extras/volume_id/volume_id/xfs/xfs.c b/extras/volume_id/volume_id/xfs.c similarity index 96% rename from extras/volume_id/volume_id/xfs/xfs.c rename to extras/volume_id/volume_id/xfs.c index efbe06ec58..12a89aafcb 100644 --- a/extras/volume_id/volume_id/xfs/xfs.c +++ b/extras/volume_id/volume_id/xfs.c @@ -34,9 +34,9 @@ #include #include -#include "../volume_id.h" -#include "../logging.h" -#include "../util.h" +#include "volume_id.h" +#include "logging.h" +#include "util.h" #include "xfs.h" struct xfs_super_block { diff --git a/extras/volume_id/volume_id/xfs/xfs.h b/extras/volume_id/volume_id/xfs.h similarity index 100% rename from extras/volume_id/volume_id/xfs/xfs.h rename to extras/volume_id/volume_id/xfs.h From 8d1b4df2192915dc94442c1ef3327a28a57b3615 Mon Sep 17 00:00:00 2001 From: "tklauser@access.unizh.ch" Date: Wed, 23 Feb 2005 04:35:26 +0100 Subject: [PATCH 1174/4284] [PATCH] udev_volume_id: add Reiser4 support --- extras/volume_id/volume_id/reiserfs.c | 33 +++++++++++++++++++++----- extras/volume_id/volume_id/volume_id.h | 2 +- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index b74b8ae576..094062dba2 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -2,6 +2,7 @@ * volume_id - reads filesystem label and uuid * * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2005 Tobias Klauser * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -55,26 +56,45 @@ struct reiserfs_super_block { __u8 label[16]; } __attribute__((__packed__)); +struct reiser4_super_block { + __u8 magic[16]; + __u16 dummy[2]; + __u8 uuid[16]; + __u8 label[16]; + __u64 dummy2; +} __attribute__((__packed__)); + #define REISERFS1_SUPERBLOCK_OFFSET 0x2000 #define REISERFS_SUPERBLOCK_OFFSET 0x10000 int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) { struct reiserfs_super_block *rs; + struct reiser4_super_block *rs4; + __u8 *buf; dbg("probing at offset %llu", off); - rs = (struct reiserfs_super_block *) volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); - if (rs == NULL) + 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, "ReIsEr2Fs", 9) == 0) { strcpy(id->type_version, "3.6"); - goto found; + goto found_v3; } - if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) { strcpy(id->type_version, "JR"); + goto found_v3; + } + + 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, UUID_DCE); goto found; } @@ -84,16 +104,17 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) if (memcmp(rs->magic, "ReIsErFs", 8) == 0) { strcpy(id->type_version, "3.5"); - goto found; + goto found_v3; } return -1; -found: +found_v3: 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, UUID_DCE); +found: volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); id->type = "reiserfs"; diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index c22a5e60ae..8fe4c3a5e5 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 35 +#define VOLUME_ID_VERSION 36 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 16 From f385ff6512012a75b8381938dd3f55f991b53e9a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 23 Feb 2005 12:21:39 +0100 Subject: [PATCH 1175/4284] [PATCH] big libsysfs diet (pre 2.0 version) --- Makefile | 1 - libsysfs/sysfs.h | 24 +- libsysfs/sysfs/libsysfs.h | 177 ++---- libsysfs/sysfs_class.c | 527 +++--------------- libsysfs/sysfs_device.c | 546 +++++-------------- libsysfs/sysfs_dir.c | 1080 +++++++++---------------------------- libsysfs/sysfs_driver.c | 415 +++++--------- libsysfs/sysfs_utils.c | 260 ++------- udevinfo.8 | 4 - udevinfo.c | 99 +--- 10 files changed, 703 insertions(+), 2430 deletions(-) diff --git a/Makefile b/Makefile index d696b8ea3b..c2d35f7734 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,6 @@ HEADERS = \ list.h SYSFS_OBJS = \ - libsysfs/sysfs_bus.o \ libsysfs/sysfs_class.o \ libsysfs/sysfs_device.o \ libsysfs/sysfs_dir.o \ diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 1e58e8abb4..30bd9b4089 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -27,19 +27,37 @@ #include #include #include +#include #include #include #include #include #include -/* external library functions */ -extern int isascii(int c); +#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) +#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) + +#define safestrcpymax(to, from, max) \ +do { \ + to[max-1] = '\0'; \ + strncpy(to, from, max-1); \ +} while (0) + +#define safestrcatmax(to, from, max) \ +do { \ + to[max-1] = '\0'; \ + strncat(to, from, max - strlen(to)-1); \ +} while (0) + +extern struct sysfs_attribute *get_attribute(void *dev, const char *name); +extern struct dlist *read_dir_subdirs(const char *path); +extern struct dlist *read_dir_links(const char *path); +extern struct dlist *get_attributes_list(void *dev); /* Debugging */ #ifdef DEBUG #include "../logging.h" -#define dprintf(format, arg...) dbg(format, ##arg) +#define dprintf(format, arg...) dbg(format, ## arg) #else #define dprintf(format, arg...) do { } while (0) #endif diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index 29194f61a6..6140c3aecb 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -3,7 +3,7 @@ * * Header Definitions for libsysfs * - * Copyright (C) IBM Corp. 2003 + * Copyright (C) IBM Corp. 2004-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,27 +27,6 @@ #include #include "dlist.h" -/* - * Defines to prevent buffer overruns - */ -#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) -#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) - -#define safestrcpymax(to, from, max) \ -do { \ - to[max-1] = '\0'; \ - strncpy(to, from, max-1); \ -} while (0) - -#define safestrcatmax(to, from, max) \ -do { \ - to[max-1] = '\0'; \ - strncat(to, from, max - strlen(to)-1); \ -} while (0) - -/* - * Generic #defines go here.. - */ #define SYSFS_FSTYPE_NAME "sysfs" #define SYSFS_PROC_MNTS "/proc/mounts" #define SYSFS_BUS_NAME "bus" @@ -55,106 +34,92 @@ do { \ #define SYSFS_BLOCK_NAME "block" #define SYSFS_DEVICES_NAME "devices" #define SYSFS_DRIVERS_NAME "drivers" +#define SYSFS_MODULE_NAME "module" #define SYSFS_NAME_ATTRIBUTE "name" #define SYSFS_UNKNOWN "unknown" #define SYSFS_PATH_ENV "SYSFS_PATH" -#define SYSFS_PATH_MAX 255 -#define SYSFS_NAME_LEN 50 -#define SYSFS_BUS_ID_SIZE 20 +#define SYSFS_PATH_MAX 256 +#define SYSFS_NAME_LEN 64 +#define SYSFS_BUS_ID_SIZE 32 -#define SYSFS_METHOD_SHOW 0x01 /* attr can be read by user */ -#define SYSFS_METHOD_STORE 0x02 /* attr can be changed by user */ +enum sysfs_attribute_method { + SYSFS_METHOD_SHOW = 0x01, /* attr can be read by user */ + SYSFS_METHOD_STORE = 0x02, /* attr can be changed by user */ +}; + +/* NOTE: statically define mnt path for sysfs */ +#define SYSFS_MNT_PATH "/sys" /* - * NOTE: We have the statically allocated "name" as the first element of all + * NOTE: + * 1. We have the statically allocated "name" as the first element of all * the structures. This feature is used in the "sorter" function for dlists + * 2. As is the case with attrlist + * 3. As is the case with path */ - struct sysfs_attribute { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; char *value; - unsigned short len; /* value length */ - unsigned short method; /* show and store */ -}; - -struct sysfs_link { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - char target[SYSFS_PATH_MAX]; -}; - -struct sysfs_directory { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - - /* Private: for internal use only */ - struct dlist *subdirs; - struct dlist *links; - struct dlist *attributes; + unsigned short len; /* value length */ + enum sysfs_attribute_method method; /* show and store */ }; struct sysfs_driver { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; + struct dlist *attrlist; + char bus[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct dlist *devices; - struct sysfs_directory *directory; }; struct sysfs_device { char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + struct dlist *attrlist; char bus_id[SYSFS_NAME_LEN]; char bus[SYSFS_NAME_LEN]; char driver_name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; /* Private: for internal use only */ struct sysfs_device *parent; + /* NOTE - we still don't populate this */ struct dlist *children; - struct sysfs_directory *directory; -}; - -struct sysfs_root_device { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - - /* Private: for internal use only */ - struct dlist *devices; - struct sysfs_directory *directory; }; +/* NOTE: not used as of now */ struct sysfs_bus { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; + struct dlist *attrlist; /* Private: for internal use only */ struct dlist *drivers; struct dlist *devices; - struct sysfs_directory *directory; }; struct sysfs_class_device { char name[SYSFS_NAME_LEN]; - char classname[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; + struct dlist *attrlist; + char classname[SYSFS_NAME_LEN]; /* Private: for internal use only */ struct sysfs_class_device *parent; struct sysfs_device *sysdevice; /* NULL if virtual */ - struct sysfs_driver *driver; /* NULL if not implemented */ - struct sysfs_directory *directory; }; +/* NOTE: not used as of now */ struct sysfs_class { char name[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; + struct dlist *attrlist; /* Private: for internal use only */ struct dlist *devices; - struct sysfs_directory *directory; }; #ifdef __cplusplus @@ -171,43 +136,15 @@ extern int sysfs_path_is_dir(const char *path); extern int sysfs_path_is_link(const char *path); extern int sysfs_path_is_file(const char *path); extern int sysfs_get_link(const char *path, char *target, size_t len); -extern struct dlist *sysfs_open_subsystem_list(char *name); -extern struct dlist *sysfs_open_bus_devices_list(char *name); +extern struct dlist *sysfs_open_directory_list(const char *path); extern void sysfs_close_list(struct dlist *list); /* sysfs directory and file access */ extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); extern struct sysfs_attribute *sysfs_open_attribute(const char *path); extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); -extern int sysfs_read_attribute_value(const char *attrpath, - char *value, size_t vsize); extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, const char *new_value, size_t len); -extern char *sysfs_get_value_from_attributes(struct dlist *attr, - const char *name); -extern int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir); -extern int sysfs_refresh_dir_links(struct sysfs_directory *sysdir); -extern int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir); -extern void sysfs_close_directory(struct sysfs_directory *sysdir); -extern struct sysfs_directory *sysfs_open_directory(const char *path); -extern int sysfs_read_dir_attributes(struct sysfs_directory *sysdir); -extern int sysfs_read_dir_links(struct sysfs_directory *sysdir); -extern int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir); -extern int sysfs_read_directory(struct sysfs_directory *sysdir); -extern int sysfs_read_all_subdirs(struct sysfs_directory *sysdir); -extern struct sysfs_directory *sysfs_get_subdirectory - (struct sysfs_directory *dir, char *subname); -extern void sysfs_close_link(struct sysfs_link *ln); -extern struct sysfs_link *sysfs_open_link(const char *lnpath); -extern struct sysfs_link *sysfs_get_directory_link - (struct sysfs_directory *dir, char *linkname); -extern struct sysfs_link *sysfs_get_subdirectory_link - (struct sysfs_directory *dir, char *linkname); -extern struct sysfs_attribute *sysfs_get_directory_attribute - (struct sysfs_directory *dir, char *attrname); -extern struct dlist *sysfs_get_dir_attributes(struct sysfs_directory *dir); -extern struct dlist *sysfs_get_dir_links(struct sysfs_directory *dir); -extern struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir); /* sysfs driver access */ extern void sysfs_close_driver(struct sysfs_driver *driver); @@ -218,19 +155,8 @@ extern struct sysfs_attribute *sysfs_get_driver_attr (struct sysfs_driver *drv, const char *name); extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); -extern struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver); -extern struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver); -extern struct sysfs_device *sysfs_get_driver_device - (struct sysfs_driver *driver, const char *name); -extern struct dlist *sysfs_refresh_driver_attributes - (struct sysfs_driver *driver); -extern struct sysfs_attribute *sysfs_open_driver_attr - (const char *bus, const char *drv, const char *attrib); /* generic sysfs device access */ -extern void sysfs_close_root_device(struct sysfs_root_device *root); -extern struct sysfs_root_device *sysfs_open_root_device(const char *name); -extern struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root); extern void sysfs_close_device_tree(struct sysfs_device *device); extern struct sysfs_device *sysfs_open_device_tree(const char *path); extern void sysfs_close_device(struct sysfs_device *dev); @@ -241,27 +167,8 @@ extern struct sysfs_device *sysfs_open_device_path(const char *path); extern int sysfs_get_device_bus(struct sysfs_device *dev); extern struct sysfs_attribute *sysfs_get_device_attr (struct sysfs_device *dev, const char *name); -extern struct dlist *sysfs_get_device_attributes(struct sysfs_device *device); -extern struct dlist *sysfs_refresh_device_attributes - (struct sysfs_device *device); -extern struct sysfs_attribute *sysfs_open_device_attr(const char *bus, - const char *bus_id, const char *attrib); - -/* generic sysfs bus access */ -extern void sysfs_close_bus(struct sysfs_bus *bus); -extern struct sysfs_bus *sysfs_open_bus(const char *name); -extern struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, - char *id); -extern struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, - char *drvname); -extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); -extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); -extern struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus); -extern struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus); -extern struct sysfs_attribute *sysfs_get_bus_attribute - (struct sysfs_bus *bus, char *attrname); -extern int sysfs_find_driver_bus(const char *driver, char *busname, - size_t bsize); +extern struct dlist *sysfs_get_device_attributes + (struct sysfs_device *dev); /* generic sysfs class access */ extern void sysfs_close_class_device(struct sysfs_class_device *dev); @@ -269,26 +176,14 @@ extern struct sysfs_class_device *sysfs_open_class_device_path (const char *path); extern struct sysfs_class_device *sysfs_open_class_device (const char *classname, const char *name); -extern struct sysfs_device *sysfs_get_classdev_device - (struct sysfs_class_device *clsdev); -extern struct sysfs_driver *sysfs_get_classdev_driver - (struct sysfs_class_device *clsdev); extern struct sysfs_class_device *sysfs_get_classdev_parent (struct sysfs_class_device *clsdev); -extern void sysfs_close_class(struct sysfs_class *cls); -extern struct sysfs_class *sysfs_open_class(const char *name); -extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); -extern struct sysfs_class_device *sysfs_get_class_device - (struct sysfs_class *cls, char *name); -extern struct dlist *sysfs_get_classdev_attributes - (struct sysfs_class_device *cdev); -extern struct dlist *sysfs_refresh_classdev_attributes - (struct sysfs_class_device *cdev); extern struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const char *name); -extern struct sysfs_attribute *sysfs_open_classdev_attr - (const char *classname, const char *dev, - const char *attrib); +extern struct dlist *sysfs_get_classdev_attributes + (struct sysfs_class_device *clsdev); +extern struct sysfs_device *sysfs_get_classdev_device + (struct sysfs_class_device *clsdev); /** * sort_list: sorter function to keep list elements sorted in alphabetical diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index 4ea7f41c99..a93de573d4 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -3,7 +3,7 @@ * * Generic class utility functions for libsysfs * - * Copyright (C) IBM Corp. 2003 + * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,95 +23,50 @@ #include "libsysfs.h" #include "sysfs.h" -static void sysfs_close_cls_dev(void *dev) -{ - sysfs_close_class_device((struct sysfs_class_device *)dev); -} - -/** - * class_name_equal: compares class_devices' name - * @a: class_name looking for - * @b: sysfs_class_device being compared - */ -static int class_name_equal(void *a, void *b) -{ - if (a == NULL || b == NULL) - return 0; - - if (strcmp(((char *)a), ((struct sysfs_class_device *)b)->name) == 0) - return 1; - - return 0; -} - /** * sysfs_close_class_device: closes a single class device. * @dev: class device to close. */ void sysfs_close_class_device(struct sysfs_class_device *dev) { - if (dev != NULL) { - if (dev->directory != NULL) - sysfs_close_directory(dev->directory); - if (dev->sysdevice != NULL) - sysfs_close_device(dev->sysdevice); - if (dev->driver != NULL) - sysfs_close_driver(dev->driver); - if (dev->parent != NULL) + if (dev) { + if (dev->parent) sysfs_close_class_device(dev->parent); + if (dev->sysdevice) + sysfs_close_device(dev->sysdevice); + if (dev->attrlist) + dlist_destroy(dev->attrlist); free(dev); } } -/** - * sysfs_close_class: close single class - * @cls: class structure - */ -void sysfs_close_class(struct sysfs_class *cls) -{ - if (cls != NULL) { - if (cls->directory != NULL) - sysfs_close_directory(cls->directory); - if (cls->devices != NULL) - dlist_destroy(cls->devices); - free(cls); - } -} - /** * alloc_class_device: mallocs and initializes new class device struct. * returns sysfs_class_device or NULL. */ static struct sysfs_class_device *alloc_class_device(void) { - return (struct sysfs_class_device *) - calloc(1, sizeof(struct sysfs_class_device)); + struct sysfs_class_device *dev; + + dev = calloc(1, sizeof(struct sysfs_class_device)); + return dev; } /** - * alloc_class: mallocs new class structure - * returns sysfs_class struct or NULL - */ -static struct sysfs_class *alloc_class(void) -{ - return (struct sysfs_class *)calloc(1, sizeof(struct sysfs_class)); -} - -/** * set_classdev_classname: Grabs classname from path * @cdev: class device to set * Returns nothing */ static void set_classdev_classname(struct sysfs_class_device *cdev) { - char *c = NULL, *e = NULL; + char *c, *e; int count = 0; c = strstr(cdev->path, SYSFS_CLASS_NAME); if (c == NULL) { c = strstr(cdev->path, SYSFS_BLOCK_NAME); } else { - c = strchr(c, '/'); + c = strstr(c, "/"); } if (c == NULL) @@ -135,9 +90,9 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) */ struct sysfs_class_device *sysfs_open_class_device_path(const char *path) { - struct sysfs_class_device *cdev = NULL; + struct sysfs_class_device *cdev; - if (path == NULL) { + if (!path) { errno = EINVAL; return NULL; } @@ -146,11 +101,11 @@ struct sysfs_class_device *sysfs_open_class_device_path(const char *path) return NULL; } cdev = alloc_class_device(); - if (cdev == NULL) { + if (!cdev) { dprintf("calloc failed\n"); return NULL; } - if ((sysfs_get_name_from_path(path, cdev->name, SYSFS_NAME_LEN)) != 0) { + if (sysfs_get_name_from_path(path, cdev->name, SYSFS_NAME_LEN)) { errno = EINVAL; dprintf("Error getting class device name\n"); sysfs_close_class_device(cdev); @@ -168,245 +123,6 @@ struct sysfs_class_device *sysfs_open_class_device_path(const char *path) return cdev; } -/** - * sysfs_get_class_devices: gets all devices for class - * @cls: class to get devices for - * returns dlist of class_devices with success and NULL with error - */ -struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) -{ - struct sysfs_class_device *dev = NULL; - struct sysfs_directory *cur = NULL; - - if (cls == NULL) { - errno = EINVAL; - return NULL; - } - - if (cls->devices != NULL) - return cls->devices; - - if (cls->directory == NULL) { - cls->directory = sysfs_open_directory(cls->path); - if (cls->directory == NULL) - return NULL; - } - - if ((sysfs_read_dir_subdirs(cls->directory)) != 0) - return NULL; - - if (cls->directory->subdirs != NULL) { - dlist_for_each_data(cls->directory->subdirs, cur, - struct sysfs_directory) { - dev = sysfs_open_class_device_path(cur->path); - if (dev == NULL) { - dprintf("Error opening device at %s\n", - cur->path); - continue; - } - if (cls->devices == NULL) - cls->devices = dlist_new_with_delete - (sizeof(struct sysfs_class_device), - sysfs_close_cls_dev); - dlist_unshift_sorted(cls->devices, dev, sort_list); - } - } - return cls->devices; -} - -/** - * sysfs_open_class: opens specific class and all its devices on system - * returns sysfs_class structure with success or NULL with error. - */ -struct sysfs_class *sysfs_open_class(const char *name) -{ - struct sysfs_class *cls = NULL; - char classpath[SYSFS_PATH_MAX]; - - if (name == NULL) { - errno = EINVAL; - return NULL; - } - - memset(classpath, 0, SYSFS_PATH_MAX); - if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { - dprintf("Sysfs not supported on this system\n"); - return NULL; - } - - /* - * We shall now treat "block" also as a class. Hence, check here - * if "name" is "block" and proceed accordingly - */ - if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { - safestrcat(classpath, "/"); - safestrcat(classpath, SYSFS_BLOCK_NAME); - } else { - safestrcat(classpath, "/"); - safestrcat(classpath, SYSFS_CLASS_NAME); - safestrcat(classpath, "/"); - safestrcat(classpath, name); - } - if ((sysfs_path_is_dir(classpath)) != 0) { - dprintf("Class %s not found on the system\n", name); - return NULL; - } - - cls = alloc_class(); - if (cls == NULL) { - dprintf("calloc failed\n"); - return NULL; - } - safestrcpy(cls->name, name); - safestrcpy(cls->path, classpath); - if ((sysfs_remove_trailing_slash(cls->path)) != 0) { - dprintf("Invalid path to class device %s\n", cls->path); - sysfs_close_class(cls); - return NULL; - } - - return cls; -} - -/** - * sysfs_get_class_device: Get specific class device using the device's id - * @class: class to find device on - * @name: class name of the device - */ -struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, - char *name) -{ - if (cls == NULL || name == NULL) { - errno = EINVAL; - return NULL; - } - - if (cls->devices == NULL) { - cls->devices = sysfs_get_class_devices(cls); - if (cls->devices == NULL) - return NULL; - } - return (struct sysfs_class_device *)dlist_find_custom(cls->devices, - name, class_name_equal); -} - -/** - * sysfs_get_classdev_device: returns the sysfs_device corresponding to - * sysfs_class_device, if present - * @clsdev: class device whose sysfs_device is required - * Returns sysfs_device on success, NULL on error or if device is not - * implemented - */ -struct sysfs_device *sysfs_get_classdev_device - (struct sysfs_class_device *clsdev) -{ - struct sysfs_link *devlink = NULL; - char devpath[SYSFS_PATH_MAX]; - - if (clsdev == NULL) { - errno = EINVAL; - return NULL; - } - safestrcpy(devpath, clsdev->path); - safestrcat(devpath, "/device"); - if ((sysfs_path_is_link(devpath)) != 0) { - if (clsdev->sysdevice != NULL) { - sysfs_close_device(clsdev->sysdevice); - clsdev->sysdevice = NULL; - } - return NULL; - } - - if (clsdev->directory == NULL) { - clsdev->directory = sysfs_open_directory(clsdev->path); - if (clsdev->directory == NULL) - return NULL; - } - devlink = sysfs_get_directory_link(clsdev->directory, "device"); - if (devlink == NULL) { - if (clsdev->sysdevice != NULL) { - dprintf("Device link no longer exists\n"); - sysfs_close_device(clsdev->sysdevice); - clsdev->sysdevice = NULL; - } - return NULL; - } - - if (clsdev->sysdevice != NULL) { - if (!strncmp(devlink->target, clsdev->sysdevice->path, - SYSFS_PATH_MAX)) - /* sysdevice hasn't changed */ - return (clsdev->sysdevice); - else - /* come here only if the device link for has changed */ - sysfs_close_device(clsdev->sysdevice); - } - - clsdev->sysdevice = sysfs_open_device_path(devlink->target); - if (clsdev->sysdevice == NULL) - return NULL; - - return (clsdev->sysdevice); -} - -/** - * sysfs_get_classdev_driver: returns the sysfs_driver corresponding to - * sysfs_class_device, if present - * @clsdev: class device whose sysfs_device is required - * Returns sysfs_driver on success, NULL on error or if driver is not - * implemented - */ -struct sysfs_driver *sysfs_get_classdev_driver - (struct sysfs_class_device *clsdev) -{ - struct sysfs_link *drvlink = NULL; - char drvpath[SYSFS_PATH_MAX]; - - if (clsdev == NULL) { - errno = EINVAL; - return NULL; - } - safestrcpy(drvpath, clsdev->path); - safestrcat(drvpath, "/driver"); - if ((sysfs_path_is_link(drvpath)) != 0) { - if (clsdev->driver != NULL) { - sysfs_close_driver(clsdev->driver); - clsdev->driver = NULL; - } - return NULL; - } - - if (clsdev->directory == NULL) { - clsdev->directory = sysfs_open_directory(clsdev->path); - if (clsdev->directory == NULL) - return NULL; - } - drvlink = sysfs_get_directory_link(clsdev->directory, "driver"); - if (drvlink == NULL) { - if (clsdev->driver != NULL) { - dprintf("Driver link no longer exists\n"); - sysfs_close_driver(clsdev->driver); - clsdev->driver = NULL; - } - return NULL; - } - if (clsdev->driver != NULL) { - if (!strncmp(drvlink->target, clsdev->driver->path, - SYSFS_PATH_MAX)) - /* driver hasn't changed */ - return (clsdev->driver); - else - /* come here only if the device link for has changed */ - sysfs_close_driver(clsdev->driver); - } - - clsdev->driver = sysfs_open_driver_path(drvlink->target); - if (clsdev->driver == NULL) - return NULL; - - return (clsdev->driver); -} - /** * get_blockdev_parent: Get the parent class device for a "block" subsystem * device if present @@ -415,7 +131,8 @@ struct sysfs_driver *sysfs_get_classdev_driver */ static int get_blockdev_parent(struct sysfs_class_device *clsdev) { - char parent_path[SYSFS_PATH_MAX], *c = NULL; + char parent_path[SYSFS_PATH_MAX]; + char *c; safestrcpy(parent_path, clsdev->path); c = strstr(parent_path, SYSFS_BLOCK_NAME); @@ -430,20 +147,20 @@ static int get_blockdev_parent(struct sysfs_class_device *clsdev) else goto errout; - /* validate whether the given class device is a partition or not */ - if ((strncmp(c, clsdev->name, strlen(clsdev->name))) == 0) { - dprintf("%s not a partition\n", clsdev->name); - return 1; - } - - c = strchr(c, '/'); + /* validate whether the given class device is a partition or not */ + if ((strncmp(c, clsdev->name, strlen(clsdev->name))) == 0) { + dprintf("%s not a partition\n", clsdev->name); + return 1; + } + + c = strchr(c, '/'); if (c == NULL) goto errout; *c = '\0'; - + clsdev->parent = sysfs_open_class_device_path(parent_path); - if (clsdev->parent == NULL) { + if (!clsdev->parent) { dprintf("Error opening the parent class device at %s\n", parent_path); return 1; @@ -466,19 +183,19 @@ errout: struct sysfs_class_device *sysfs_get_classdev_parent (struct sysfs_class_device *clsdev) { - if (clsdev == NULL) { + if (!clsdev) { errno = EINVAL; return NULL; } - if (clsdev->parent != NULL) + if (clsdev->parent) return (clsdev->parent); - - /* + + /* * As of now, only block devices have a parent child heirarchy in sysfs * We do not know, if, in the future, more classes will have a similar * structure. Hence, we now call a specialized function for block and * later we can add support functions for other subsystems as required. - */ + */ if (!(strncmp(clsdev->classname, SYSFS_BLOCK_NAME, sizeof(SYSFS_BLOCK_NAME)))) { if ((get_blockdev_parent(clsdev)) == 0) @@ -499,13 +216,13 @@ struct sysfs_class_device *sysfs_get_classdev_parent static int get_classdev_path(const char *classname, const char *clsdev, char *path, size_t len) { - if (classname == NULL || clsdev == NULL || path == NULL) { + if (!classname || !clsdev || !path) { errno = EINVAL; return -1; } - if (sysfs_get_mnt_path(path, len) != 0) { - dprintf("Error getting sysfs mount path\n"); - return -1; + if (sysfs_get_mnt_path(path, len) != 0) { + dprintf("Error getting sysfs mount path\n"); + return -1; } if (strncmp(classname, SYSFS_BLOCK_NAME, sizeof(SYSFS_BLOCK_NAME)) == 0) { @@ -535,9 +252,9 @@ struct sysfs_class_device *sysfs_open_class_device (const char *classname, const char *name) { char devpath[SYSFS_PATH_MAX]; - struct sysfs_class_device *cdev = NULL; + struct sysfs_class_device *cdev; - if (classname == NULL || name == NULL) { + if (!classname || !name) { errno = EINVAL; return NULL; } @@ -549,9 +266,9 @@ struct sysfs_class_device *sysfs_open_class_device name, classname); return NULL; } - + cdev = sysfs_open_class_device_path(devpath); - if (cdev == NULL) { + if (!cdev) { dprintf("Error getting class device %s from class %s\n", name, classname); return NULL; @@ -559,57 +276,6 @@ struct sysfs_class_device *sysfs_open_class_device return cdev; } -/** - * sysfs_get_classdev_attributes: returns a dlist of attributes for - * the requested class_device - * @cdev: sysfs_class_dev for which attributes are needed - * returns a dlist of attributes if exists, NULL otherwise - */ -struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev) -{ - if (cdev == NULL) - return NULL; - - if (cdev->directory == NULL) { - cdev->directory = sysfs_open_directory(cdev->path); - if (cdev->directory == NULL) - return NULL; - } - if (cdev->directory->attributes == NULL) { - if ((sysfs_read_dir_attributes(cdev->directory)) != 0) - return NULL; - } - return (cdev->directory->attributes); -} - -/** - * sysfs_refresh_clsassdev_attributes: refreshes the driver's list of attributes - * @clsdev: sysfs_class_device whose attributes to refresh - * - * NOTE: Upon return, prior references to sysfs_attributes for this classdev - * _may_ not be valid - * - * Returns list of attributes on success and NULL on failure - */ -struct dlist *sysfs_refresh_classdev_attributes - (struct sysfs_class_device *clsdev) -{ - if (clsdev == NULL) { - errno = EINVAL; - return NULL; - } - - if (clsdev->directory == NULL) - return (sysfs_get_classdev_attributes(clsdev)); - - if ((sysfs_refresh_dir_attributes(clsdev->directory)) != 0) { - dprintf("Error refreshing class_device attributes\n"); - return NULL; - } - - return (clsdev->directory->attributes); -} - /** * sysfs_get_classdev_attr: searches class device's attributes by name * @clsdev: class device to look through @@ -619,90 +285,53 @@ struct dlist *sysfs_refresh_classdev_attributes struct sysfs_attribute *sysfs_get_classdev_attr (struct sysfs_class_device *clsdev, const char *name) { - struct sysfs_attribute *cur = NULL; - struct sysfs_directory *sdir = NULL; - struct dlist *attrlist = NULL; - - if (clsdev == NULL || name == NULL) { + if (!clsdev || !name) { errno = EINVAL; return NULL; } - - /* - * First, see if it's in the current directory. Then look at - * subdirs since class devices can have subdirs of attributes. - */ - attrlist = sysfs_get_classdev_attributes(clsdev); - if (attrlist != NULL) { - cur = sysfs_get_directory_attribute(clsdev->directory, - (char *)name); - if (cur != NULL) - return cur; - } - - if (clsdev->directory == NULL) - return NULL; - - if (clsdev->directory->subdirs == NULL) - if ((sysfs_read_dir_subdirs(clsdev->directory)) != 0 || - clsdev->directory->subdirs == NULL) - return NULL; - - if (clsdev->directory->subdirs != NULL) { - dlist_for_each_data(clsdev->directory->subdirs, sdir, - struct sysfs_directory) { - if ((sysfs_path_is_dir(sdir->path)) != 0) - continue; - cur = sysfs_get_directory_attribute(sdir, - (char *)name); - if (cur == NULL) - continue; - } - } - return cur; + return get_attribute(clsdev, (char *)name); } /** - * sysfs_open_classdev_attr: read an attribute for a given class device - * @classname: name of the class on which to look - * @dev: class device name for which the attribute has to be read - * @attrib: attribute to read - * Returns sysfs_attribute * on SUCCESS and NULL on error - * - * NOTE: - * A call to sysfs_close_attribute() is required to close the - * attribute returned and to free memory + * sysfs_get_classdev_attributes: gets list of classdev attributes + * @clsdev: class device whose attributes list is needed + * returns dlist of attributes on success or NULL on error */ -struct sysfs_attribute *sysfs_open_classdev_attr(const char *classname, - const char *dev, const char *attrib) +struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *clsdev) { - struct sysfs_attribute *attribute = NULL; - char path[SYSFS_PATH_MAX]; - - if (classname == NULL || dev == NULL || attrib == NULL) { + if (!clsdev) { errno = EINVAL; return NULL; } - memset(path, 0, SYSFS_PATH_MAX); - if ((get_classdev_path(classname, dev, path, SYSFS_PATH_MAX)) != 0) { - dprintf("Error getting to device %s on class %s\n", - dev, classname); - return NULL; - } - safestrcat(path, "/"); - safestrcat(path, attrib); - attribute = sysfs_open_attribute(path); - if (attribute == NULL) { - dprintf("Error opening attribute %s on class device %s\n", - attrib, dev); - return NULL; - } - if ((sysfs_read_attribute(attribute)) != 0) { - dprintf("Error reading attribute %s for class device %s\n", - attrib, dev); - sysfs_close_attribute(attribute); - return NULL; - } - return attribute; + return get_attributes_list(clsdev); } +/** + * sysfs_get_classdev_device: gets the sysfs_device associated with the + * given sysfs_class_device + * @clsdev: class device whose associated sysfs_device is needed + * returns struct sysfs_device * on success or NULL on error + */ +struct sysfs_device *sysfs_get_classdev_device + (struct sysfs_class_device *clsdev) +{ + char linkpath[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; + + if (!clsdev) { + errno = EINVAL; + return NULL; + } + + if (clsdev->sysdevice) + return clsdev->sysdevice; + + memset(linkpath, 0, SYSFS_PATH_MAX); + safestrcpy(linkpath, clsdev->path); + safestrcat(linkpath, "/device"); + if (!sysfs_path_is_link(linkpath)) { + memset(devpath, 0, SYSFS_PATH_MAX); + if (!sysfs_get_link(linkpath, devpath, SYSFS_PATH_MAX)) + clsdev->sysdevice = sysfs_open_device_path(devpath); + } + return clsdev->sysdevice; +} diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 83c3adc080..7087730d5f 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -3,7 +3,7 @@ * * Generic device utility functions for libsysfs * - * Copyright (C) IBM Corp. 2003 + * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,48 +24,64 @@ #include "sysfs.h" /** - * get_dev_driver: fills in the dev->driver_name field, but searches by - * opening subsystem. Only to be used if no driver link exists in - * device directory. - * - * Returns 0 on SUCCESS and 1 on error + * get_dev_driver: fills in the dev->driver_name field + * Returns 0 on SUCCESS and -1 on error */ static int get_dev_driver(struct sysfs_device *dev) { - struct dlist *drvlist = NULL; - char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; - char *drv = NULL, *c = NULL; - - if (dev == NULL) { + struct dlist *drvlist; + char path[SYSFS_PATH_MAX]; + char devpath[SYSFS_PATH_MAX]; + char *drv = NULL, *c; + + if (!dev) { errno = EINVAL; - return 1; + return -1; } - if (dev->bus[0] == '\0') - return 1; + memset(path, 0, SYSFS_PATH_MAX); memset(devpath, 0, SYSFS_PATH_MAX); - safestrcpy(path, SYSFS_BUS_NAME); + safestrcpymax(path, dev->path, SYSFS_PATH_MAX); + safestrcatmax(path, "/driver", SYSFS_PATH_MAX); + if (!sysfs_path_is_link(path)) { + if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) { + if (sysfs_get_name_from_path(devpath, + dev->driver_name, SYSFS_NAME_LEN)) + return -1; + } + return 0; + } + + /* + * Devices on on earlier kernels do not have the "driver" link. + * Look it up in the bus directory. + */ + if (dev->bus[0] == '\0') + return -1; + memset(path, 0, SYSFS_PATH_MAX); + memset(devpath, 0, SYSFS_PATH_MAX); + safestrcpy(path, dev->path); + c = strstr(path, SYSFS_DEVICES_NAME); + if (c == NULL) { + dprintf("Invalid path to device - %s\n", dev->path); + return -1; + } else + *c = '\0'; + safestrcat(path, SYSFS_BUS_NAME); safestrcat(path, "/"); safestrcat(path, dev->bus); safestrcat(path, "/"); safestrcat(path, SYSFS_DRIVERS_NAME); - safestrcpy(devpath, dev->path); - c = strstr(devpath, SYSFS_DEVICES_NAME); - if (c == NULL) - return 1; - *c = '\0'; - safestrcatmax(c, path, (sizeof(devpath) - strlen(devpath))); - - drvlist = sysfs_open_subsystem_list(path); - if (drvlist != NULL) { + drvlist = sysfs_open_directory_list(path); + if (drvlist) { dlist_for_each_data(drvlist, drv, char) { - safestrcpy(path, devpath); - safestrcat(path, "/"); - safestrcat(path, drv); - safestrcat(path, "/"); - safestrcat(path, dev->bus_id); - if (sysfs_path_is_link(path) == 0) { + safestrcpy(devpath, path); + safestrcat(devpath, "/"); + safestrcat(devpath, drv); + safestrcat(devpath, "/"); + safestrcat(devpath, dev->bus_id); + if (sysfs_path_is_link(devpath) == 0) { safestrcpy(dev->driver_name, drv); sysfs_close_list(drvlist); return 0; @@ -73,35 +89,9 @@ static int get_dev_driver(struct sysfs_device *dev) } sysfs_close_list(drvlist); } - return 1; + return -1; } -/* - * get_device_driver_name: gets device's driver name, searches for driver - * link first before going the brute force route. - * @dev: device to retrieve driver - * returns 0 with success and 1 with error - */ -static int get_device_driver_name(struct sysfs_device *dev) -{ - char devpath[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX]; - - if (dev == NULL) { - errno = EINVAL; - return 1; - } - memset(devpath, 0, SYSFS_PATH_MAX); - memset(drvpath, 0, SYSFS_PATH_MAX); - safestrcpy(devpath, dev->path); - safestrcat(devpath, "/driver"); - - if ((sysfs_get_link(devpath, drvpath, SYSFS_PATH_MAX)) != 0) - return(get_dev_driver(dev)); - - return (sysfs_get_name_from_path(drvpath, dev->driver_name, - SYSFS_NAME_LEN)); -} - /** * sysfs_get_device_bus: retrieves the bus name the device is on, checks path * to bus' link to make sure it has correct device. @@ -110,31 +100,49 @@ static int get_device_driver_name(struct sysfs_device *dev) */ int sysfs_get_device_bus(struct sysfs_device *dev) { - char subsys[SYSFS_NAME_LEN], path[SYSFS_PATH_MAX]; - char target[SYSFS_PATH_MAX], *bus = NULL, *c = NULL; - struct dlist *buslist = NULL; + char devpath[SYSFS_PATH_MAX]; + char subsys[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char target[SYSFS_PATH_MAX]; + char *bus = NULL, *c; + struct dlist *buslist; - if (dev == NULL) { + if (!dev) { errno = EINVAL; return -1; } + memset(path, 0, SYSFS_PATH_MAX); + memset(devpath, 0, SYSFS_PATH_MAX); + safestrcpymax(path, dev->path, SYSFS_PATH_MAX); + safestrcatmax(path, "/bus", SYSFS_PATH_MAX); + if (!sysfs_path_is_link(path)) { + if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) { + if (sysfs_get_name_from_path(devpath, + dev->bus, SYSFS_NAME_LEN)) + return -1; + } + return 0; + } + + /* + * Devices on on earlier kernels do not have the "bus" link. + * Look it up in the bus directory. + */ memset(subsys, 0, SYSFS_NAME_LEN); - safestrcpy(subsys, SYSFS_BUS_NAME); /* subsys = bus */ - buslist = sysfs_open_subsystem_list(subsys); - if (buslist != NULL) { + safestrcpy(subsys, dev->path); + c = strstr(subsys, SYSFS_DEVICES_NAME); + if (c == NULL) { + dprintf("Invalid path to device - %s\n", dev->path); + return -1; + } else + *c = '\0'; + safestrcat(subsys, SYSFS_BUS_NAME); + buslist = sysfs_open_directory_list(subsys); + if (buslist) { dlist_for_each_data(buslist, bus, char) { memset(path, 0, SYSFS_PATH_MAX); - safestrcpy(path, dev->path); - c = strstr(path, "/devices"); - if (c == NULL) { - dprintf("Invalid path to device %s\n", path); - sysfs_close_list(buslist); - return -1; - } - *c = '\0'; - safestrcat(path, "/"); - safestrcat(path, SYSFS_BUS_NAME); + safestrcpy(path, subsys); safestrcat(path, "/"); safestrcat(path, bus); safestrcat(path, "/"); @@ -143,8 +151,8 @@ int sysfs_get_device_bus(struct sysfs_device *dev) safestrcat(path, dev->bus_id); if ((sysfs_path_is_link(path)) == 0) { memset(target, 0, SYSFS_PATH_MAX); - if ((sysfs_get_link(path, target, - SYSFS_PATH_MAX)) != 0) { + if (sysfs_get_link(path, target, + SYSFS_PATH_MAX)) { dprintf("Error getting link target\n"); sysfs_close_list(buslist); return -1; @@ -156,10 +164,10 @@ int sysfs_get_device_bus(struct sysfs_device *dev) return 0; } } - } - sysfs_close_list(buslist); - } - return -1; + } + sysfs_close_list(buslist); + } + return -1; } /** @@ -169,8 +177,8 @@ int sysfs_get_device_bus(struct sysfs_device *dev) */ void sysfs_close_device_tree(struct sysfs_device *devroot) { - if (devroot != NULL) { - if (devroot->children != NULL) { + if (devroot) { + if (devroot->children) { struct sysfs_device *child = NULL; dlist_for_each_data(devroot->children, child, @@ -182,27 +190,19 @@ void sysfs_close_device_tree(struct sysfs_device *devroot) } } -/** - * sysfs_close_dev_tree: routine for dlist integration - */ -static void sysfs_close_dev_tree(void *dev) -{ - sysfs_close_device_tree((struct sysfs_device *)dev); -} - /** * sysfs_close_device: closes and cleans up a device * @dev = device to clean up */ void sysfs_close_device(struct sysfs_device *dev) { - if (dev != NULL) { - if (dev->parent != NULL) + if (dev) { + if (dev->parent) sysfs_close_device(dev->parent); - if (dev->directory != NULL) - sysfs_close_directory(dev->directory); - if (dev->children != NULL && dev->children->count == 0) + if (dev->children && dev->children->count) dlist_destroy(dev->children); + if (dev->attrlist) + dlist_destroy(dev->attrlist); free(dev); } } @@ -213,36 +213,7 @@ void sysfs_close_device(struct sysfs_device *dev) */ static struct sysfs_device *alloc_device(void) { - return (struct sysfs_device *)calloc(1, sizeof(struct sysfs_device)); -} - -/** - * open_device_dir: opens up sysfs_directory for specific root dev - * @name: name of root - * returns struct sysfs_directory with success and NULL with error - */ -static struct sysfs_directory *open_device_dir(const char *path) -{ - struct sysfs_directory *rdir = NULL; - - if (path == NULL) { - errno = EINVAL; - return NULL; - } - - rdir = sysfs_open_directory(path); - if (rdir == NULL) { - errno = EINVAL; - dprintf ("Device %s not supported on this system\n", path); - return NULL; - } - if ((sysfs_read_dir_subdirs(rdir)) != 0) { - dprintf ("Error reading device at dir %s\n", path); - sysfs_close_directory(rdir); - return NULL; - } - - return rdir; + return (struct sysfs_device *) calloc(1, sizeof(struct sysfs_device)); } /** @@ -252,45 +223,44 @@ static struct sysfs_directory *open_device_dir(const char *path) */ struct sysfs_device *sysfs_open_device_path(const char *path) { - struct sysfs_device *dev = NULL; + struct sysfs_device *dev; - if (path == NULL) { + if (!path) { errno = EINVAL; return NULL; } - if ((sysfs_path_is_dir(path)) != 0) { + if (sysfs_path_is_dir(path)) { dprintf("Incorrect path to device: %s\n", path); return NULL; } - dev = alloc_device(); - if (dev == NULL) { + dev = alloc_device(); + if (!dev) { dprintf("Error allocating device at %s\n", path); return NULL; } - if ((sysfs_get_name_from_path(path, dev->bus_id, - SYSFS_NAME_LEN)) != 0) { + if (sysfs_get_name_from_path(path, dev->bus_id, SYSFS_NAME_LEN)) { errno = EINVAL; dprintf("Error getting device bus_id\n"); sysfs_close_device(dev); return NULL; } safestrcpy(dev->path, path); - if ((sysfs_remove_trailing_slash(dev->path)) != 0) { + if (sysfs_remove_trailing_slash(dev->path)) { dprintf("Invalid path to device %s\n", dev->path); sysfs_close_device(dev); return NULL; } - /* + /* * The "name" attribute no longer exists... return the device's * sysfs representation instead, in the "dev->name" field, which * implies that the dev->name and dev->bus_id contain same data. */ safestrcpy(dev->name, dev->bus_id); - - if (sysfs_get_device_bus(dev) != 0) + + if (sysfs_get_device_bus(dev)) dprintf("Could not get device bus\n"); - - if (get_device_driver_name(dev) != 0) { + + if (get_dev_driver(dev)) { dprintf("Could not get device %s's driver\n", dev->bus_id); safestrcpy(dev->driver_name, SYSFS_UNKNOWN); } @@ -298,207 +268,6 @@ struct sysfs_device *sysfs_open_device_path(const char *path) return dev; } -/** - * sysfs_open_device_tree: opens root device and all of its children, - * creating a tree of devices. Only opens children. - * @path: sysfs path to devices - * returns struct sysfs_device and its children with success or NULL with - * error. - */ -struct sysfs_device *sysfs_open_device_tree(const char *path) -{ - struct sysfs_device *rootdev = NULL, *new = NULL; - struct sysfs_directory *cur = NULL; - - if (path == NULL) { - errno = EINVAL; - return NULL; - } - rootdev = sysfs_open_device_path(path); - if (rootdev == NULL) { - dprintf("Error opening root device at %s\n", path); - return NULL; - } - if (rootdev->directory == NULL) { - rootdev->directory = open_device_dir(rootdev->path); - if (rootdev->directory == NULL) - return NULL; - } - if (rootdev->directory->subdirs != NULL) { - dlist_for_each_data(rootdev->directory->subdirs, cur, - struct sysfs_directory) { - new = sysfs_open_device_tree(cur->path); - if (new == NULL) { - dprintf("Error opening device tree at %s\n", - cur->path); - sysfs_close_device_tree(rootdev); - return NULL; - } - if (rootdev->children == NULL) - rootdev->children = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_dev_tree); - dlist_unshift_sorted(rootdev->children, - new, sort_list); - } - } - - return rootdev; -} - -/** - * sysfs_close_root_device: closes root and all devices - * @root: root device to close - */ -void sysfs_close_root_device(struct sysfs_root_device *root) -{ - if (root != NULL) { - if (root->devices != NULL) - dlist_destroy(root->devices); - if (root->directory != NULL) - sysfs_close_directory(root->directory); - free(root); - } -} - -/** - * sysfs_get_root_devices: opens up all the devices under this root device - * @root: root device to open devices for - * returns dlist of devices with success and NULL with error - */ -struct dlist *sysfs_get_root_devices(struct sysfs_root_device *root) -{ - struct sysfs_device *dev = NULL; - struct sysfs_directory *cur = NULL; - - if (root == NULL) { - errno = EINVAL; - return NULL; - } - if (root->directory == NULL) { - root->directory = open_device_dir(root->path); - if (root->directory == NULL) - return NULL; - } - - if (root->directory->subdirs == NULL) - return 0; - - dlist_for_each_data(root->directory->subdirs, cur, - struct sysfs_directory) { - dev = sysfs_open_device_tree(cur->path); - if (dev == NULL) { - dprintf ("Error opening device at %s\n", cur->path); - continue; - } - if (root->devices == NULL) - root->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_dev_tree); - dlist_unshift_sorted(root->devices, dev, sort_list); - } - - return root->devices; -} - -/** - * sysfs_open_root_device: opens sysfs devices root and all of its - * devices. - * @name: name of /sys/devices/root to open - * returns struct sysfs_root_device if success and NULL with error - */ -struct sysfs_root_device *sysfs_open_root_device(const char *name) -{ - struct sysfs_root_device *root = NULL; - char rootpath[SYSFS_PATH_MAX]; - - if (name == NULL) { - errno = EINVAL; - return NULL; - } - - memset(rootpath, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(rootpath, SYSFS_PATH_MAX) != 0) { - dprintf ("Sysfs not supported on this system\n"); - return NULL; - } - - safestrcat(rootpath, "/"); - safestrcat(rootpath, SYSFS_DEVICES_NAME); - safestrcat(rootpath, "/"); - safestrcat(rootpath, name); - if ((sysfs_path_is_dir(rootpath)) != 0) { - errno = EINVAL; - dprintf("Invalid root device: %s\n", name); - return NULL; - } - root = (struct sysfs_root_device *)calloc - (1, sizeof(struct sysfs_root_device)); - if (root == NULL) { - dprintf("calloc failure\n"); - return NULL; - } - safestrcpy(root->name, name); - safestrcpy(root->path, rootpath); - if ((sysfs_remove_trailing_slash(root->path)) != 0) { - dprintf("Invalid path to root device %s\n", root->path); - sysfs_close_root_device(root); - return NULL; - } - return root; -} - -/** - * sysfs_get_device_attributes: returns a dlist of attributes corresponding to - * the specific device - * @device: struct sysfs_device * for which attributes are to be returned - */ -struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) -{ - if (device == NULL) { - errno = EINVAL; - return NULL; - } - - if (device->directory == NULL) { - device->directory = sysfs_open_directory(device->path); - if (device->directory == NULL) - return NULL; - } - if (device->directory->attributes == NULL) { - if ((sysfs_read_dir_attributes(device->directory)) != 0) - return NULL; - } - return (device->directory->attributes); -} - -/** - * sysfs_refresh_device_attributes: refreshes the device's list of attributes - * @device: sysfs_device whose attributes to refresh - * - * NOTE: Upon return, prior references to sysfs_attributes for this device - * _may_ not be valid - * - * Returns list of attributes on success and NULL on failure - */ -struct dlist *sysfs_refresh_device_attributes(struct sysfs_device *device) -{ - if (device == NULL) { - errno = EINVAL; - return NULL; - } - - if (device->directory == NULL) - return (sysfs_get_device_attributes(device)); - - if ((sysfs_refresh_dir_attributes(device->directory)) != 0) { - dprintf("Error refreshing device attributes\n"); - return NULL; - } - - return (device->directory->attributes); -} - /** * sysfs_get_device_attr: searches dev's attributes by name * @dev: device to look through @@ -508,18 +277,25 @@ struct dlist *sysfs_refresh_device_attributes(struct sysfs_device *device) struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, const char *name) { - struct dlist *attrlist = NULL; - - if (dev == NULL || name == NULL) { + if (!dev || !name) { errno = EINVAL; return NULL; } - - attrlist = sysfs_get_device_attributes(dev); - if (attrlist == NULL) - return NULL; + return get_attribute(dev, (char *)name); +} - return sysfs_get_directory_attribute(dev->directory, (char *)name); +/** + * sysfs_get_device_attributes: gets list of device attributes + * @dev: device whose attributes list is needed + * returns dlist of attributes on success or NULL on error + */ +struct dlist *sysfs_get_device_attributes(struct sysfs_device *dev) +{ + if (!dev) { + errno = EINVAL; + return NULL; + } + return get_attributes_list(dev); } /** @@ -535,13 +311,13 @@ static int get_device_absolute_path(const char *device, const char *bus, { char bus_path[SYSFS_PATH_MAX]; - if (device == NULL || path == NULL) { + if (!device || !path) { errno = EINVAL; return -1; } memset(bus_path, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX) != 0) { + if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX)) { dprintf ("Sysfs not supported on this system\n"); return -1; } @@ -557,7 +333,7 @@ static int get_device_absolute_path(const char *device, const char *bus, * We now are at /sys/bus/"bus_name"/devices/"device" which is a link. * Now read this link to reach to the device. */ - if ((sysfs_get_link(bus_path, path, psize)) != 0) { + if (sysfs_get_link(bus_path, path, psize)) { dprintf("Error getting to device %s\n", device); return -1; } @@ -578,21 +354,21 @@ static int get_device_absolute_path(const char *device, const char *bus, struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) { char sysfs_path[SYSFS_PATH_MAX]; - struct sysfs_device *device = NULL; + struct sysfs_device *device; - if (bus_id == NULL || bus == NULL) { + if (!bus_id || !bus) { errno = EINVAL; return NULL; } memset(sysfs_path, 0, SYSFS_PATH_MAX); - if ((get_device_absolute_path(bus_id, bus, sysfs_path, - SYSFS_PATH_MAX)) != 0) { + if (get_device_absolute_path(bus_id, bus, sysfs_path, + SYSFS_PATH_MAX)) { dprintf("Error getting to device %s\n", bus_id); return NULL; } device = sysfs_open_device_path(sysfs_path); - if (device == NULL) { + if (!device) { dprintf("Error opening device %s\n", bus_id); return NULL; } @@ -608,20 +384,20 @@ struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) */ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) { - char ppath[SYSFS_PATH_MAX], *tmp = NULL; + char ppath[SYSFS_PATH_MAX], *tmp; - if (dev == NULL) { + if (!dev) { errno = EINVAL; return NULL; } - if (dev->parent != NULL) + if (dev->parent) return (dev->parent); memset(ppath, 0, SYSFS_PATH_MAX); safestrcpy(ppath, dev->path); tmp = strrchr(ppath, '/'); - if (tmp == NULL) { + if (!tmp) { dprintf("Invalid path to device %s\n", ppath); return NULL; } @@ -634,68 +410,22 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) } } *tmp = '\0'; - + /* * All "devices" have the "detach_state" attribute - validate here */ safestrcat(ppath, "/detach_state"); - if ((sysfs_path_is_file(ppath)) != 0) { + if (sysfs_path_is_file(ppath)) { dprintf("Device at %s does not have a parent\n", dev->path); return NULL; } tmp = strrchr(ppath, '/'); *tmp = '\0'; dev->parent = sysfs_open_device_path(ppath); - if (dev->parent == NULL) { + if (!dev->parent) { dprintf("Error opening device %s's parent at %s\n", dev->bus_id, ppath); return NULL; } return (dev->parent); } - -/* - * sysfs_open_device_attr: open the given device's attribute - * @bus: Bus on which to look - * @dev_id: device for which attribute is required - * @attrname: name of the attribute to look for - * Returns struct sysfs_attribute on success and NULL on failure - * - * NOTE: - * A call to sysfs_close_attribute() is required to close - * the attribute returned and free memory. - */ -struct sysfs_attribute *sysfs_open_device_attr(const char *bus, - const char *bus_id, const char *attrib) -{ - struct sysfs_attribute *attribute = NULL; - char devpath[SYSFS_PATH_MAX]; - - if (bus == NULL || bus_id == NULL || attrib == NULL) { - errno = EINVAL; - return NULL; - } - - memset(devpath, 0, SYSFS_PATH_MAX); - if ((get_device_absolute_path(bus_id, bus, devpath, - SYSFS_PATH_MAX)) != 0) { - dprintf("Error getting to device %s\n", bus_id); - return NULL; - } - safestrcat(devpath, "/"); - safestrcat(devpath, attrib); - attribute = sysfs_open_attribute(devpath); - if (attribute == NULL) { - dprintf("Error opening attribute %s for device %s\n", - attrib, bus_id); - return NULL; - } - if ((sysfs_read_attribute(attribute)) != 0) { - dprintf("Error reading attribute %s for device %s\n", - attrib, bus_id); - sysfs_close_attribute(attribute); - return NULL; - } - return attribute; -} - diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index 52769916cc..c86617934b 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -3,7 +3,7 @@ * * Directory utility functions for libsysfs * - * Copyright (C) IBM Corp. 2003 + * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,39 +23,38 @@ #include "libsysfs.h" #include "sysfs.h" +static int sort_char(void *new, void *old) +{ + return ((strncmp((char *)new, (char *)old, + strlen((char *)new))) < 0 ? 1 : 0); +} + +/** + * sysfs_del_name: free function for sysfs_open_subsystem_list + * @name: memory area to be freed + */ +static void sysfs_del_name(void *name) +{ + free(name); +} + /** * sysfs_del_attribute: routine for dlist integration */ static void sysfs_del_attribute(void *attr) { - sysfs_close_attribute((struct sysfs_attribute *)attr); + sysfs_close_attribute((struct sysfs_attribute *)attr); } /** - * sysfs_del_link: routine for dlist integration - */ -static void sysfs_del_link(void *ln) -{ - sysfs_close_link((struct sysfs_link *)ln); -} - -/** - * sysfs_del_dir: routine for dlist integration - */ -static void sysfs_del_directory(void *dir) -{ - sysfs_close_directory((struct sysfs_directory *)dir); -} - -/** - * dir_attribute_name_equal: compares dir attributes by name + * attr_name_equal: compares attributes by name * @a: attribute name for comparison * @b: sysfs_attribute to be compared. * returns 1 if a==b->name or 0 if not equal */ -static int dir_attribute_name_equal(void *a, void *b) +static int attr_name_equal(void *a, void *b) { - if (a == NULL || b == NULL) + if (!a || !b) return 0; if (strcmp(((char *)a), ((struct sysfs_attribute *)b)->name) == 0) @@ -64,48 +63,14 @@ static int dir_attribute_name_equal(void *a, void *b) return 0; } -/** - * dir_link_name_equal: compares dir links by name - * @a: link name for comparison - * @b: sysfs_link to be compared. - * returns 1 if a==b->name or 0 if not equal - */ -static int dir_link_name_equal(void *a, void *b) -{ - if (a == NULL || b == NULL) - return 0; - - if (strcmp(((char *)a), ((struct sysfs_link *)b)->name) == 0) - return 1; - - return 0; -} - -/** - * dir_subdir_name_equal: compares subdirs by name - * @a: name of subdirectory to compare - * @b: sysfs_directory subdirectory to be compared - * returns 1 if a==b->name or 0 if not equal - */ -static int dir_subdir_name_equal(void *a, void *b) -{ - if (a == NULL || b == NULL) - return 0; - - if (strcmp(((char *)a), ((struct sysfs_directory *)b)->name) == 0) - return 1; - - return 0; -} - /** * sysfs_close_attribute: closes and cleans up attribute * @sysattr: attribute to close. */ void sysfs_close_attribute(struct sysfs_attribute *sysattr) { - if (sysattr != NULL) { - if (sysattr->value != NULL) + if (sysattr) { + if (sysattr->value) free(sysattr->value); free(sysattr); } @@ -130,13 +95,13 @@ struct sysfs_attribute *sysfs_open_attribute(const char *path) { struct sysfs_attribute *sysattr = NULL; struct stat fileinfo; - - if (path == NULL) { + + if (!path) { errno = EINVAL; return NULL; } sysattr = alloc_attribute(); - if (sysattr == NULL) { + if (!sysattr) { dprintf("Error allocating attribute at %s\n", path); return NULL; } @@ -162,94 +127,6 @@ struct sysfs_attribute *sysfs_open_attribute(const char *path) return sysattr; } -/** - * sysfs_write_attribute: write value to the attribute - * @sysattr: attribute to write - * @new_value: value to write - * @len: length of "new_value" - * returns 0 with success and -1 with error. - */ -int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const char *new_value, size_t len) -{ - int fd; - int length; - - if (sysattr == NULL || new_value == NULL || len == 0) { - errno = EINVAL; - return -1; - } - - if (!(sysattr->method & SYSFS_METHOD_STORE)) { - dprintf ("Store method not supported for attribute %s\n", - sysattr->path); - errno = EACCES; - return -1; - } - if (sysattr->method & SYSFS_METHOD_SHOW) { - /* - * read attribute again to see if we can get an updated value - */ - if ((sysfs_read_attribute(sysattr)) != 0) { - dprintf("Error reading attribute\n"); - return -1; - } - if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0) { - dprintf("Attr %s already has the requested value %s\n", - sysattr->name, new_value); - return 0; - } - } - /* - * open O_WRONLY since some attributes have no "read" but only - * "write" permission - */ - if ((fd = open(sysattr->path, O_WRONLY)) < 0) { - dprintf("Error reading attribute %s\n", sysattr->path); - return -1; - } - - length = write(fd, new_value, len); - if (length < 0) { - dprintf("Error writing to the attribute %s - invalid value?\n", - sysattr->name); - close(fd); - return -1; - } else if ((unsigned int)length != len) { - dprintf("Could not write %d bytes to attribute %s\n", - len, sysattr->name); - /* - * since we could not write user supplied number of bytes, - * restore the old value if one available - */ - if (sysattr->method & SYSFS_METHOD_SHOW) { - length = write(fd, sysattr->value, sysattr->len); - close(fd); - return -1; - } - } - - /* - * Validate length that has been copied. Alloc appropriate area - * in sysfs_attribute. Verify first if the attribute supports reading - * (show method). If it does not, do not bother - */ - if (sysattr->method & SYSFS_METHOD_SHOW) { - if (length != sysattr->len) { - sysattr->value = (char *)realloc - (sysattr->value, length); - sysattr->len = length; - safestrcpymax(sysattr->value, new_value, length); - } else { - /*"length" of the new value is same as old one */ - safestrcpymax(sysattr->value, new_value, length); - } - } - - close(fd); - return 0; -} - /** * sysfs_read_attribute: reads value from attribute * @sysattr: attribute to read @@ -263,7 +140,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) long pgsize = 0; int fd; - if (sysattr == NULL) { + if (!sysattr) { errno = EINVAL; return -1; } @@ -275,7 +152,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) } pgsize = sysconf(_SC_PAGESIZE); fbuf = (char *)calloc(1, pgsize+1); - if (fbuf == NULL) { + if (!fbuf) { dprintf("calloc failed\n"); return -1; } @@ -303,7 +180,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) sysattr->len = length; close(fd); vbuf = (char *)realloc(fbuf, length+1); - if (vbuf == NULL) { + if (!vbuf) { dprintf("realloc failed\n"); free(fbuf); return -1; @@ -314,758 +191,301 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) } /** - * sysfs_read_attribute_value: given path to attribute, return its value. - * values can be up to a pagesize, if buffer is smaller the value will - * be truncated. - * @attrpath: sysfs path to attribute - * @value: buffer to put value - * @vsize: size of value buffer + * sysfs_write_attribute: write value to the attribute + * @sysattr: attribute to write + * @new_value: value to write + * @len: length of "new_value" * returns 0 with success and -1 with error. */ -int sysfs_read_attribute_value(const char *attrpath, - char *value, size_t vsize) +int sysfs_write_attribute(struct sysfs_attribute *sysattr, + const char *new_value, size_t len) { - struct sysfs_attribute *attr = NULL; - size_t length = 0; + int fd; + int length; - if (attrpath == NULL || value == NULL || vsize == 0) { + if (!sysattr || !new_value || len == 0) { errno = EINVAL; return -1; } - attr = sysfs_open_attribute(attrpath); - if (attr == NULL) { - dprintf("Invalid attribute path %s\n", attrpath); - errno = EINVAL; + if (!(sysattr->method & SYSFS_METHOD_STORE)) { + dprintf ("Store method not supported for attribute %s\n", + sysattr->path); + errno = EACCES; return -1; } - if((sysfs_read_attribute(attr)) != 0 || attr->value == NULL) { - dprintf("Error reading from attribute %s\n", attrpath); - sysfs_close_attribute(attr); - return -1; - } - length = strlen(attr->value); - if (length > vsize) - dprintf("Value length %d is larger than supplied buffer %d\n", - length, vsize); - safestrcpymax(value, attr->value, vsize); - sysfs_close_attribute(attr); - - return 0; -} - -/** - * sysfs_get_value_from_attrbutes: given a linked list of attributes and an - * attribute name, return its value - * @attr: attribute to search - * @name: name to look for - * returns char * value - could be NULL - */ -char *sysfs_get_value_from_attributes(struct dlist *attr, const char *name) -{ - struct sysfs_attribute *cur = NULL; - - if (attr == NULL || name == NULL) { - errno = EINVAL; - return NULL; - } - dlist_for_each_data(attr, cur, struct sysfs_attribute) { - if (strcmp(cur->name, name) == 0) - return cur->value; - } - return NULL; -} - -/** - * sysfs_close_link: closes and cleans up link. - * @ln: link to close. - */ -void sysfs_close_link(struct sysfs_link *ln) -{ - if (ln != NULL) - free(ln); -} - -/** - * sysfs_close_directory: closes directory, cleans up attributes and links - * @sysdir: sysfs_directory to close - */ -void sysfs_close_directory(struct sysfs_directory *sysdir) -{ - if (sysdir != NULL) { - if (sysdir->subdirs != NULL) - dlist_destroy(sysdir->subdirs); - if (sysdir->links != NULL) - dlist_destroy(sysdir->links); - if (sysdir->attributes != NULL) - dlist_destroy(sysdir->attributes); - free(sysdir); - sysdir = NULL; - } -} - -/** - * alloc_directory: allocates and initializes directory structure - * returns struct sysfs_directory with success or NULL with error. - */ -static struct sysfs_directory *alloc_directory(void) -{ - return (struct sysfs_directory *) - calloc(1, sizeof(struct sysfs_directory)); -} - -/** - * alloc_link: allocates and initializes link structure - * returns struct sysfs_link with success or NULL with error. - */ -static struct sysfs_link *alloc_link(void) -{ - return (struct sysfs_link *)calloc(1, sizeof(struct sysfs_link)); -} - -/** - * sysfs_read_all_subdirs: calls sysfs_read_directory for all subdirs - * @sysdir: directory whose subdirs need reading. - * returns 0 with success and -1 with error. - */ -int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) -{ - struct sysfs_directory *cursub = NULL; - int retval = 0; - - if (sysdir == NULL) { - errno = EINVAL; - return -1; - } - if (sysdir->subdirs == NULL) - if ((sysfs_read_dir_subdirs(sysdir)) != 0) - return 0; - if (sysdir->subdirs != NULL) { - dlist_for_each_data(sysdir->subdirs, cursub, - struct sysfs_directory) { - if ((sysfs_read_dir_subdirs(cursub)) != 0) { - dprintf ("Error reading subdirectory %s\n", - cursub->name); - retval = -1; - } + if (sysattr->method & SYSFS_METHOD_SHOW) { + /* + * read attribute again to see if we can get an updated value + */ + if ((sysfs_read_attribute(sysattr))) { + dprintf("Error reading attribute\n"); + return -1; + } + if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0) { + dprintf("Attr %s already has the requested value %s\n", + sysattr->name, new_value); + return 0; } } - if (!retval) - errno = 0; - return retval; -} - -/** - * sysfs_open_directory: opens a sysfs directory, creates dir struct, and - * returns. - * @path: path of directory to open. - * returns: struct sysfs_directory * with success and NULL on error. - */ -struct sysfs_directory *sysfs_open_directory(const char *path) -{ - struct sysfs_directory *sdir = NULL; - - if (path == NULL) { - errno = EINVAL; - return NULL; + /* + * open O_WRONLY since some attributes have no "read" but only + * "write" permission + */ + if ((fd = open(sysattr->path, O_WRONLY)) < 0) { + dprintf("Error reading attribute %s\n", sysattr->path); + return -1; } - if (sysfs_path_is_dir(path) != 0) { - dprintf("Invalid path to directory %s\n", path); - errno = EINVAL; - return NULL; + length = write(fd, new_value, len); + if (length < 0) { + dprintf("Error writing to the attribute %s - invalid value?\n", + sysattr->name); + close(fd); + return -1; + } else if ((unsigned int)length != len) { + dprintf("Could not write %d bytes to attribute %s\n", + len, sysattr->name); + /* + * since we could not write user supplied number of bytes, + * restore the old value if one available + */ + if (sysattr->method & SYSFS_METHOD_SHOW) { + length = write(fd, sysattr->value, sysattr->len); + close(fd); + return -1; + } } - sdir = alloc_directory(); - if (sdir == NULL) { - dprintf("Error allocating directory %s\n", path); - return NULL; + /* + * Validate length that has been copied. Alloc appropriate area + * in sysfs_attribute. Verify first if the attribute supports reading + * (show method). If it does not, do not bother + */ + if (sysattr->method & SYSFS_METHOD_SHOW) { + if (length != sysattr->len) { + sysattr->value = (char *)realloc + (sysattr->value, length); + sysattr->len = length; + safestrcpymax(sysattr->value, new_value, length); + } else { + /*"length" of the new value is same as old one */ + safestrcpymax(sysattr->value, new_value, length); + } } - if (sysfs_get_name_from_path(path, sdir->name, SYSFS_NAME_LEN) != 0) { - dprintf("Error getting directory name from path: %s\n", path); - sysfs_close_directory(sdir); - return NULL; - } - safestrcpy(sdir->path, path); - - return sdir; -} - -/** - * sysfs_open_link: opens a sysfs link, creates struct, and returns - * @path: path of link to open. - * returns: struct sysfs_link * with success and NULL on error. - */ -struct sysfs_link *sysfs_open_link(const char *linkpath) -{ - struct sysfs_link *ln = NULL; - - if (linkpath == NULL || strlen(linkpath) > SYSFS_PATH_MAX) { - errno = EINVAL; - return NULL; - } - - ln = alloc_link(); - if (ln == NULL) { - dprintf("Error allocating link %s\n", linkpath); - return NULL; - } - safestrcpy(ln->path, linkpath); - if ((sysfs_get_name_from_path(linkpath, ln->name, SYSFS_NAME_LEN)) != 0 - || (sysfs_get_link(linkpath, ln->target, SYSFS_PATH_MAX)) != 0) { - sysfs_close_link(ln); - errno = EINVAL; - dprintf("Invalid link path %s\n", linkpath); - return NULL; - } - - return ln; + + close(fd); + return 0; } /** * add_attribute: open and add attribute at path to given directory - * @sysdir: directory to add attribute to + * @dev: device whose attribute is to be added * @path: path to attribute - * returns 0 with success and -1 with error. + * returns pointer to attr added with success and NULL with error. */ -static int add_attribute(struct sysfs_directory *sysdir, const char *path) +static struct sysfs_attribute *add_attribute(void *dev, const char *path) { - struct sysfs_attribute *attr = NULL; + struct sysfs_attribute *attr; attr = sysfs_open_attribute(path); - if (attr == NULL) { + if (!attr) { dprintf("Error opening attribute %s\n", path); - return -1; - } - if (attr->method & SYSFS_METHOD_SHOW) { - if ((sysfs_read_attribute(attr)) != 0) { - dprintf("Error reading attribute %s\n", path); - sysfs_close_attribute(attr); - return 0; - } - } - - if (sysdir->attributes == NULL) { - sysdir->attributes = dlist_new_with_delete - (sizeof(struct sysfs_attribute), sysfs_del_attribute); - } - dlist_unshift_sorted(sysdir->attributes, attr, sort_list); - - return 0; -} - -/** - * add_subdirectory: open and add subdirectory at path to given directory - * @sysdir: directory to add subdir to - * @path: path to subdirectory - * returns 0 with success and -1 with error. - */ -static int add_subdirectory(struct sysfs_directory *sysdir, const char *path) -{ - struct sysfs_directory *subdir = NULL; - - subdir = sysfs_open_directory(path); - if (subdir == NULL) { - dprintf("Error opening directory %s\n", path); - return -1; - } - if (sysdir->subdirs == NULL) - sysdir->subdirs = dlist_new_with_delete - (sizeof(struct sysfs_directory), sysfs_del_directory); - dlist_unshift_sorted(sysdir->subdirs, subdir, sort_list); - return 0; -} - -/** - * add_link: open and add link at path to given directory - * @sysdir: directory to add link to - * @path: path to link - * returns 0 with success and -1 with error. - */ -static int add_link(struct sysfs_directory *sysdir, const char *path) -{ - struct sysfs_link *ln = NULL; - - ln = sysfs_open_link(path); - if (ln == NULL) { - dprintf("Error opening link %s\n", path); - return -1; - } - if (sysdir->links == NULL) - sysdir->links = dlist_new_with_delete - (sizeof(struct sysfs_link), sysfs_del_link); - dlist_unshift_sorted(sysdir->links, ln, sort_list); - return 0; -} - -/** - * sysfs_read_dir_attributes: grabs attributes for the given directory - * @sysdir: sysfs directory to open - * returns 0 with success and -1 with error. - */ -int sysfs_read_dir_attributes(struct sysfs_directory *sysdir) -{ - DIR *dir = NULL; - struct dirent *dirent = NULL; - char file_path[SYSFS_PATH_MAX]; - int retval = 0; - - if (sysdir == NULL) { - errno = EINVAL; - return -1; - } - dir = opendir(sysdir->path); - if (dir == NULL) { - dprintf("Error opening directory %s\n", sysdir->path); - return -1; - } - while(((dirent = readdir(dir)) != NULL) && retval == 0) { - if (0 == strcmp(dirent->d_name, ".")) - continue; - if (0 == strcmp(dirent->d_name, "..")) - continue; - memset(file_path, 0, SYSFS_PATH_MAX); - safestrcpy(file_path, sysdir->path); - safestrcat(file_path, "/"); - safestrcat(file_path, dirent->d_name); - if ((sysfs_path_is_file(file_path)) == 0) - retval = add_attribute(sysdir, file_path); - } - closedir(dir); - if (!retval) - errno = 0; - return(retval); -} - -/** - * sysfs_read_dir_links: grabs links in a specific directory - * @sysdir: sysfs directory to read links - * returns 0 with success and -1 with error. - */ -int sysfs_read_dir_links(struct sysfs_directory *sysdir) -{ - DIR *dir = NULL; - struct dirent *dirent = NULL; - char file_path[SYSFS_PATH_MAX]; - int retval = 0; - - if (sysdir == NULL) { - errno = EINVAL; - return -1; - } - dir = opendir(sysdir->path); - if (dir == NULL) { - dprintf("Error opening directory %s\n", sysdir->path); - return -1; - } - while(((dirent = readdir(dir)) != NULL) && retval == 0) { - if (0 == strcmp(dirent->d_name, ".")) - continue; - if (0 == strcmp(dirent->d_name, "..")) - continue; - memset(file_path, 0, SYSFS_PATH_MAX); - safestrcpy(file_path, sysdir->path); - safestrcat(file_path, "/"); - safestrcat(file_path, dirent->d_name); - if ((sysfs_path_is_link(file_path)) == 0) { - retval = add_link(sysdir, file_path); - if (retval != 0) - break; - } - } - closedir(dir); - if (!retval) - errno = 0; - return(retval); -} - -/** - * sysfs_read_dir_subdirs: grabs subdirs in a specific directory - * @sysdir: sysfs directory to read links - * returns 0 with success and -1 with error. - */ -int sysfs_read_dir_subdirs(struct sysfs_directory *sysdir) -{ - DIR *dir = NULL; - struct dirent *dirent = NULL; - char file_path[SYSFS_PATH_MAX]; - int retval = 0; - - if (sysdir == NULL) { - errno = EINVAL; - return -1; - } - dir = opendir(sysdir->path); - if (dir == NULL) { - dprintf("Error opening directory %s\n", sysdir->path); - return -1; - } - while(((dirent = readdir(dir)) != NULL) && retval == 0) { - if (0 == strcmp(dirent->d_name, ".")) - continue; - if (0 == strcmp(dirent->d_name, "..")) - continue; - memset(file_path, 0, SYSFS_PATH_MAX); - safestrcpy(file_path, sysdir->path); - safestrcat(file_path, "/"); - safestrcat(file_path, dirent->d_name); - if ((sysfs_path_is_dir(file_path)) == 0) - retval = add_subdirectory(sysdir, file_path); - } - closedir(dir); - if (!retval) - errno = 0; - return(retval); -} - -/** - * sysfs_read_directory: grabs attributes, links, and subdirectories - * @sysdir: sysfs directory to open - * returns 0 with success and -1 with error. - */ -int sysfs_read_directory(struct sysfs_directory *sysdir) -{ - DIR *dir = NULL; - struct dirent *dirent = NULL; - struct stat astats; - char file_path[SYSFS_PATH_MAX]; - int retval = 0; - - if (sysdir == NULL) { - errno = EINVAL; - return -1; - } - dir = opendir(sysdir->path); - if (dir == NULL) { - dprintf("Error opening directory %s\n", sysdir->path); - return -1; - } - while(((dirent = readdir(dir)) != NULL) && retval == 0) { - if (0 == strcmp(dirent->d_name, ".")) - continue; - if (0 == strcmp(dirent->d_name, "..")) - continue; - memset(file_path, 0, SYSFS_PATH_MAX); - safestrcpy(file_path, sysdir->path); - safestrcat(file_path, "/"); - safestrcat(file_path, dirent->d_name); - if ((lstat(file_path, &astats)) != 0) { - dprintf("stat failed\n"); - continue; - } - if (S_ISDIR(astats.st_mode)) - retval = add_subdirectory(sysdir, file_path); - - else if (S_ISLNK(astats.st_mode)) - retval = add_link(sysdir, file_path); - - else if (S_ISREG(astats.st_mode)) - retval = add_attribute(sysdir, file_path); - } - closedir(dir); - if (!retval) - errno = 0; - return(retval); -} - -/** - * sysfs_refresh_dir_attributes: Refresh attributes list - * @sysdir: directory whose list of attributes to refresh - * Returns 0 on success, 1 on failure - */ -int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir) -{ - if (sysdir == NULL) { - errno = EINVAL; - return 1; - } - if ((sysfs_path_is_dir(sysdir->path)) != 0) { - dprintf("Invalid path to directory %s\n", sysdir->path); - errno = EINVAL; - return 1; - } - if (sysdir->attributes != NULL) { - dlist_destroy(sysdir->attributes); - sysdir->attributes = NULL; - } - if ((sysfs_read_dir_attributes(sysdir)) != 0) { - dprintf("Error refreshing attributes for directory %s\n", - sysdir->path); - return 1; - } - errno = 0; - return 0; -} - -/** - * sysfs_refresh_dir_links: Refresh links list - * @sysdir: directory whose list of links to refresh - * Returns 0 on success, 1 on failure - */ -int sysfs_refresh_dir_links(struct sysfs_directory *sysdir) -{ - if (sysdir == NULL) { - errno = EINVAL; - return 1; - } - if ((sysfs_path_is_dir(sysdir->path)) != 0) { - dprintf("Invalid path to directory %s\n", sysdir->path); - errno = EINVAL; - return 1; - } - if (sysdir->links != NULL) { - dlist_destroy(sysdir->links); - sysdir->links = NULL; - } - if ((sysfs_read_dir_links(sysdir)) != 0) { - dprintf("Error refreshing links for directory %s\n", - sysdir->path); - return 1; - } - errno = 0; - return 0; -} - -/** - * sysfs_refresh_dir_subdirs: Refresh subdirs list - * @sysdir: directory whose list of subdirs to refresh - * Returns 0 on success, 1 on failure - */ -int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir) -{ - if (sysdir == NULL) { - errno = EINVAL; - return 1; - } - if ((sysfs_path_is_dir(sysdir->path)) != 0) { - dprintf("Invalid path to directory %s\n", sysdir->path); - errno = EINVAL; - return 1; - } - if (sysdir->subdirs != NULL) { - dlist_destroy(sysdir->subdirs); - sysdir->subdirs = NULL; - } - if ((sysfs_read_dir_subdirs(sysdir)) != 0) { - dprintf("Error refreshing subdirs for directory %s\n", - sysdir->path); - return 1; - } - errno = 0; - return 0; -} - -/** - * sysfs_get_directory_attribute: retrieves attribute attrname from current - * directory only - * @dir: directory to retrieve attribute from - * @attrname: name of attribute to look for - * - * NOTE: Since we know the attribute to look for, this routine looks for the - * attribute if it was created _after_ the attrlist was read initially. - * - * returns sysfs_attribute if found and NULL if not found - */ -struct sysfs_attribute *sysfs_get_directory_attribute - (struct sysfs_directory *dir, char *attrname) -{ - struct sysfs_attribute *attr = NULL; - char new_path[SYSFS_PATH_MAX]; - - if (dir == NULL || attrname == NULL) { - errno = EINVAL; return NULL; } - - if (dir->attributes == NULL) - if ((sysfs_read_dir_attributes(dir) != 0) - || (dir->attributes == NULL)) + if (attr->method & SYSFS_METHOD_SHOW) { + if (sysfs_read_attribute(attr)) { + dprintf("Error reading attribute %s\n", path); + sysfs_close_attribute(attr); return NULL; - - attr = (struct sysfs_attribute *)dlist_find_custom - (dir->attributes, attrname, dir_attribute_name_equal); - if (attr != NULL) { - if ((attr->method & SYSFS_METHOD_SHOW) && - (sysfs_read_attribute(attr)) != 0) { - dprintf("Error reading attribute %s\n", attr->name); - return NULL; - } - } else { - memset(new_path, 0, SYSFS_PATH_MAX); - safestrcpy(new_path, dir->path); - safestrcat(new_path, "/"); - safestrcat(new_path, attrname); - if ((sysfs_path_is_file(new_path)) == 0) { - if ((add_attribute(dir, new_path)) == 0) { - attr = (struct sysfs_attribute *) - dlist_find_custom(dir->attributes, - attrname, dir_attribute_name_equal); - } } } - + + if (!((struct sysfs_device *)dev)->attrlist) { + ((struct sysfs_device *)dev)->attrlist = dlist_new_with_delete + (sizeof(struct sysfs_attribute), sysfs_del_attribute); + } + dlist_unshift_sorted(((struct sysfs_device *)dev)->attrlist, + attr, sort_list); + return attr; } -/** - * sysfs_get_directory_link: retrieves link from one directory list - * @dir: directory to retrieve link from - * @linkname: name of link to look for - * returns reference to sysfs_link if found and NULL if not found +/* + * get_attribute - given a sysfs_* struct and a name, return the + * sysfs_attribute corresponding to "name" + * returns sysfs_attribute on success and NULL on error */ -struct sysfs_link *sysfs_get_directory_link - (struct sysfs_directory *dir, char *linkname) +struct sysfs_attribute *get_attribute(void *dev, const char *name) { - if (dir == NULL || linkname == NULL) { + struct sysfs_attribute *cur = NULL; + char path[SYSFS_PATH_MAX]; + + if (!dev || !name) { errno = EINVAL; return NULL; } - if (dir->links == NULL) { - if ((sysfs_read_dir_links(dir) != 0) || (dir->links == NULL)) - return NULL; - } else { - if ((sysfs_refresh_dir_links(dir)) != 0) - return NULL; - } - return (struct sysfs_link *)dlist_find_custom(dir->links, - linkname, dir_link_name_equal); + if (((struct sysfs_device *)dev)->attrlist) { + /* check if attr is already in the list */ + cur = (struct sysfs_attribute *)dlist_find_custom + ((((struct sysfs_device *)dev)->attrlist), + (void *)name, attr_name_equal); + if (cur) + return cur; + } + safestrcpymax(path, ((struct sysfs_device *)dev)->path, + SYSFS_PATH_MAX); + safestrcatmax(path, "/", SYSFS_PATH_MAX); + safestrcatmax(path, name, SYSFS_PATH_MAX); + if (!(sysfs_path_is_file(path))) + cur = add_attribute((void *)dev, path); + return cur; } /** - * sysfs_get_subdirectory: retrieves subdirectory by name. - * @dir: directory to search for subdirectory. - * @subname: subdirectory name to get. - * returns reference to subdirectory or NULL if not found + * read_dir_links: grabs links in a specific directory + * @sysdir: sysfs directory to read + * returns list of link names with success and NULL with error. */ -struct sysfs_directory *sysfs_get_subdirectory(struct sysfs_directory *dir, - char *subname) +struct dlist *read_dir_links(const char *path) { - struct sysfs_directory *sub = NULL, *cursub = NULL; + DIR *dir = NULL; + struct dirent *dirent = NULL; + char file_path[SYSFS_PATH_MAX], *linkname; + struct dlist *linklist = NULL; - if (dir == NULL || subname == NULL) { + if (!path) { errno = EINVAL; return NULL; } - - if (dir->subdirs == NULL) - if (sysfs_read_dir_subdirs(dir) != 0) - return NULL; - - sub = (struct sysfs_directory *)dlist_find_custom(dir->subdirs, - subname, dir_subdir_name_equal); - if (sub != NULL) - return sub; - - if (dir->subdirs != NULL) { - dlist_for_each_data(dir->subdirs, cursub, - struct sysfs_directory) { - if (cursub->subdirs == NULL) { - if (sysfs_read_dir_subdirs(cursub) != 0) - continue; - if (cursub->subdirs == NULL) - continue; + dir = opendir(path); + if (!dir) { + dprintf("Error opening directory %s\n", path); + return NULL; + } + while ((dirent = readdir(dir)) != NULL) { + if (0 == strcmp(dirent->d_name, ".")) + continue; + if (0 == strcmp(dirent->d_name, "..")) + continue; + memset(file_path, 0, SYSFS_PATH_MAX); + safestrcpy(file_path, path); + safestrcat(file_path, "/"); + safestrcat(file_path, dirent->d_name); + if ((sysfs_path_is_link(file_path)) == 0) { + if (!linklist) { + linklist = dlist_new_with_delete + (SYSFS_NAME_LEN, sysfs_del_name); + if (!linklist) { + dprintf("Error creating list\n"); + return NULL; + } } - sub = sysfs_get_subdirectory(cursub, subname); - if (sub != NULL) - return sub; + linkname = (char *)calloc(1, SYSFS_NAME_LEN); + safestrcpymax(linkname, dirent->d_name, SYSFS_NAME_LEN); + dlist_unshift_sorted(linklist, linkname, sort_char); } } - return NULL; + closedir(dir); + return linklist; } /** - * sysfs_get_subdirectory_link: looks through all subdirs for specific link. - * @dir: directory and subdirectories to search for link. - * @linkname: link name to get. - * returns reference to link or NULL if not found + * read_dir_subdirs: grabs subdirs in a specific directory + * @sysdir: sysfs directory to read + * returns list of directory names with success and NULL with error. */ -struct sysfs_link *sysfs_get_subdirectory_link(struct sysfs_directory *dir, - char *linkname) +struct dlist *read_dir_subdirs(const char *path) { - struct sysfs_directory *cursub = NULL; - struct sysfs_link *ln = NULL; + DIR *dir = NULL; + struct dirent *dirent = NULL; + char file_path[SYSFS_PATH_MAX], *dir_name; + struct dlist *dirlist = NULL; - if (dir == NULL || linkname == NULL) { + if (!path) { errno = EINVAL; return NULL; } - - ln = sysfs_get_directory_link(dir, linkname); - if (ln != NULL) - return ln; - - if (dir->subdirs == NULL) - if (sysfs_read_dir_subdirs(dir) != 0) - return NULL; - - if (dir->subdirs != NULL) { - dlist_for_each_data(dir->subdirs, cursub, - struct sysfs_directory) { - ln = sysfs_get_subdirectory_link(cursub, linkname); - if (ln != NULL) - return ln; + dir = opendir(path); + if (!dir) { + dprintf("Error opening directory %s\n", path); + return NULL; + } + while ((dirent = readdir(dir)) != NULL) { + if (0 == strcmp(dirent->d_name, ".")) + continue; + if (0 == strcmp(dirent->d_name, "..")) + continue; + memset(file_path, 0, SYSFS_PATH_MAX); + safestrcpy(file_path, path); + safestrcat(file_path, "/"); + safestrcat(file_path, dirent->d_name); + if ((sysfs_path_is_dir(file_path)) == 0) { + if (!dirlist) { + dirlist = dlist_new_with_delete + (SYSFS_NAME_LEN, sysfs_del_name); + if (!dirlist) { + dprintf("Error creating list\n"); + return NULL; + } + } + dir_name = (char *)calloc(1, SYSFS_NAME_LEN); + safestrcpymax(dir_name, dirent->d_name, SYSFS_NAME_LEN); + dlist_unshift_sorted(dirlist, dir_name, sort_char); } } - return NULL; + closedir(dir); + return dirlist; } /** - * sysfs_get_dir_attributes: returns dlist of directory attributes - * @dir: directory to retrieve attributes from - * returns dlist of attributes or NULL + * get_attributes_list: build a list of attributes for the given device + * @dev: devices whose attributes list is required + * returns dlist of attributes on success and NULL on failure */ -struct dlist *sysfs_get_dir_attributes(struct sysfs_directory *dir) +struct dlist *get_attributes_list(void *dev) { - if (dir == NULL) { + DIR *dir = NULL; + struct dirent *dirent = NULL; + struct sysfs_attribute *attr = NULL; + char file_path[SYSFS_PATH_MAX], path[SYSFS_PATH_MAX]; + + if (!dev) { errno = EINVAL; return NULL; } - - if (dir->attributes == NULL) { - if (sysfs_read_dir_attributes(dir) != 0) - return NULL; - } - - return (dir->attributes); -} - -/** - * sysfs_get_dir_links: returns dlist of directory links - * @dir: directory to return links for - * returns dlist of links or NULL - */ -struct dlist *sysfs_get_dir_links(struct sysfs_directory *dir) -{ - if (dir == NULL) { - errno = EINVAL; + memset(path, 0, SYSFS_PATH_MAX); + safestrcpy(path, ((struct sysfs_device *)dev)->path); + dir = opendir(path); + if (!dir) { + dprintf("Error opening directory %s\n", path); return NULL; } - - if (dir->links == NULL) { - if (sysfs_read_dir_links(dir) != 0) - return NULL; + while ((dirent = readdir(dir)) != NULL) { + if (0 == strcmp(dirent->d_name, ".")) + continue; + if (0 == strcmp(dirent->d_name, "..")) + continue; + memset(file_path, 0, SYSFS_PATH_MAX); + safestrcpy(file_path, path); + safestrcat(file_path, "/"); + safestrcat(file_path, dirent->d_name); + if ((sysfs_path_is_file(file_path)) == 0) { + if (((struct sysfs_device *)dev)->attrlist) { + /* check if attr is already in the list */ + attr = (struct sysfs_attribute *) + dlist_find_custom + ((((struct sysfs_device *)dev)->attrlist), + (void *)dirent->d_name, attr_name_equal); + if (attr) + continue; + else + add_attribute(dev, file_path); + } else + attr = add_attribute(dev, file_path); + } } - - return (dir->links); -} - -/** - * sysfs_get_dir_subdirs: returns dlist of directory subdirectories - * @dir: directory to return subdirs for - * returns dlist of subdirs or NULL - */ -struct dlist *sysfs_get_dir_subdirs(struct sysfs_directory *dir) -{ - if (dir == NULL) { - errno = EINVAL; - return NULL; - } - - if (dir->subdirs == NULL) { - if (sysfs_read_dir_subdirs(dir) != 0) - return NULL; - } - - return (dir->subdirs); + closedir(dir); + return ((struct sysfs_device *)dev)->attrlist; } diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c index 88d26b56dd..c2464faa9e 100644 --- a/libsysfs/sysfs_driver.c +++ b/libsysfs/sysfs_driver.c @@ -3,7 +3,7 @@ * * Driver utility functions for libsysfs * - * Copyright (C) IBM Corp. 2003 + * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,42 +28,20 @@ static void sysfs_close_driver_device(void *device) sysfs_close_device((struct sysfs_device *)device); } -/** +/** * sysfs_close_driver: closes driver and deletes device lists too * @driver: driver to close - */ + */ void sysfs_close_driver(struct sysfs_driver *driver) { - if (driver != NULL) { - if (driver->devices != NULL) + if (driver) { + if (driver->devices) dlist_destroy(driver->devices); - if (driver->directory != NULL) - sysfs_close_directory(driver->directory); + if (driver->attrlist) + dlist_destroy(driver->attrlist); free(driver); } } - -/** - * open_driver_dir: Open the sysfs_directory for this driver - * @driver: Driver whose directory to be opened - * Returns 0 on success and 1 on failure - */ -static int open_driver_dir(struct sysfs_driver *driver) -{ - if (driver == NULL) { - errno = EINVAL; - return 1; - } - if (driver->directory == NULL) { - driver->directory = sysfs_open_directory(driver->path); - if (driver->directory == NULL) { - dprintf("Error opening driver directory at %s\n", - driver->path); - return 1; - } - } - return 0; -} /** * alloc_driver: allocates and initializes driver @@ -74,6 +52,65 @@ static struct sysfs_driver *alloc_driver(void) return (struct sysfs_driver *)calloc(1, sizeof(struct sysfs_driver)); } +/** + * get_driver_bus: gets bus the driver is on + * Returns 0 on success and 1 on error + */ +static int get_driver_bus(struct sysfs_driver *drv) +{ + char drvpath[SYSFS_PATH_MAX], *c = NULL; + + if (!drv) { + errno = EINVAL; + return 1; + } + + safestrcpy(drvpath, drv->path); + c = strstr(drvpath, SYSFS_DRIVERS_NAME); + if (c == NULL) + return 1; + *--c = '\0'; + c = strstr(drvpath, SYSFS_BUS_NAME); + if (c == NULL) + return 1; + c = strstr(c, "/"); + if (c == NULL) + return 1; + c++; + safestrcpy(drv->bus, c); + return 0; +} + +/** + * sysfs_get_driver_attr: searches drv's attributes by name + * @drv: driver to look through + * @name: attribute name to get + * returns sysfs_attribute reference with success or NULL with error. + */ +struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, + const char *name) +{ + if (!drv || !name) { + errno = EINVAL; + return NULL; + } + return get_attribute(drv, (char *)name); +} + +/** + * sysfs_get_driver_attributes: gets list of driver attributes + * @dev: driver whose attributes list is needed + * returns dlist of attributes on success or NULL on error + */ +struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *drv) +{ + if (!drv) { + errno = EINVAL; + return NULL; + } + return get_attributes_list(drv); +} + /** * sysfs_open_driver_path: opens and initializes driver structure * @path: path to driver directory @@ -83,238 +120,39 @@ struct sysfs_driver *sysfs_open_driver_path(const char *path) { struct sysfs_driver *driver = NULL; - if (path == NULL) { + if (!path) { errno = EINVAL; return NULL; } - if ((sysfs_path_is_dir(path)) != 0) { + if (sysfs_path_is_dir(path)) { dprintf("Invalid path to driver: %s\n", path); return NULL; } driver = alloc_driver(); - if (driver == NULL) { + if (!driver) { dprintf("Error allocating driver at %s\n", path); return NULL; } - if ((sysfs_get_name_from_path(path, driver->name, - SYSFS_NAME_LEN)) != 0) { + if (sysfs_get_name_from_path(path, driver->name, SYSFS_NAME_LEN)) { dprintf("Error getting driver name from path\n"); free(driver); return NULL; } safestrcpy(driver->path, path); - if ((sysfs_remove_trailing_slash(driver->path)) != 0) { + if (sysfs_remove_trailing_slash(driver->path)) { dprintf("Invalid path to driver %s\n", driver->path); sysfs_close_driver(driver); return NULL; } - + if (get_driver_bus(driver)) { + dprintf("Could not get the bus driver is on\n"); + sysfs_close_driver(driver); + return NULL; + } + return driver; } -/** - * sysfs_get_driver_attributes: gets list of attributes for the given driver - * @driver: sysfs_driver for which attributes are required - * returns a dlist of attributes corresponding to the driver if present - * NULL otherwise - */ -struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) -{ - if (driver == NULL) { - errno = EINVAL; - return NULL; - } - - if (driver->directory == NULL) { - if ((open_driver_dir(driver)) == 1) - return NULL; - } - if (driver->directory->attributes == NULL) { - if ((sysfs_read_dir_attributes(driver->directory)) != 0) - return NULL; - } - return(driver->directory->attributes); -} - -/** - * sysfs_refresh_driver_attributes: refreshes the driver's list of attributes - * @driver: sysfs_driver whose attributes to refresh - * - * NOTE: Upon return, prior references to sysfs_attributes for this driver - * _may_ not be valid - * - * Returns list of attributes on success and NULL on failure - */ -struct dlist *sysfs_refresh_driver_attributes(struct sysfs_driver *driver) -{ - if (driver == NULL) { - errno = EINVAL; - return NULL; - } - if (driver->directory == NULL) - return (sysfs_get_driver_attributes(driver)); - - if ((sysfs_refresh_dir_attributes(driver->directory)) != 0) { - dprintf("Error refreshing driver attributes\n"); - return NULL; - } - return (driver->directory->attributes); -} - -/** - * sysfs_get_driver_attr: searches driver's attributes by name - * @drv: driver to look through - * @name: attribute name to get - * returns sysfs_attribute reference on success or NULL with error - */ -struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, - const char *name) -{ - struct dlist *attrlist = NULL; - - if (drv == NULL) { - errno = EINVAL; - return NULL; - } - - attrlist = sysfs_get_driver_attributes(drv); - if (attrlist == NULL) - return NULL; - - return sysfs_get_directory_attribute(drv->directory, (char *)name); -} - -/** - * sysfs_get_driver_links: gets list of links from the given driver - * @driver: sysfs_driver for which links list is required - * returns a dlist of links corresponding to the driver if present - * NULL otherwise - */ -struct dlist *sysfs_get_driver_links(struct sysfs_driver *driver) -{ - if (driver == NULL) { - errno = EINVAL; - return NULL; - } - - if (driver->directory == NULL) - if ((open_driver_dir(driver)) == 1) - return NULL; - - if (driver->directory->links == NULL) - if ((sysfs_read_dir_links(driver->directory)) != 0) - return NULL; - - return(driver->directory->links); -} - -/** - * sysfs_get_driver_devices: open up the list of devices this driver supports - * @driver: sysfs_driver for which devices are needed - * Returns dlist of devices on SUCCESS or NULL with ERROR - */ -struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver) -{ - struct sysfs_link *curlink = NULL; - struct sysfs_device *device = NULL; - - if (driver == NULL) { - errno = EINVAL; - return NULL; - } - - if (driver->devices != NULL) - return (driver->devices); - - if (driver->directory == NULL || driver->directory->links == NULL) { - struct dlist *list = NULL; - list = sysfs_get_driver_links(driver); - } - - if (driver->directory->links != NULL) { - dlist_for_each_data(driver->directory->links, curlink, - struct sysfs_link) { - device = sysfs_open_device_path(curlink->target); - if (device == NULL) { - dprintf("Error opening device at %s\n", - curlink->target); - return NULL; - } - if (driver->devices == NULL) - driver->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_driver_device); - dlist_unshift_sorted(driver->devices, device, - sort_list); - } - } - return (driver->devices); -} - -/** - * sysfs_refresh_driver_devices: Refreshes drivers list of devices - * @driver: sysfs_driver whose devices list needs to be refreshed - * - * NOTE: Upon return from this function, prior sysfs_device references from - * this driver's list of devices _may_ not be valid - * - * Returns dlist of devices on success and NULL on failure - */ -struct dlist *sysfs_refresh_driver_devices(struct sysfs_driver *driver) -{ - if (driver == NULL) { - errno = EINVAL; - return NULL; - } - - if (driver->devices != NULL) { - dlist_destroy(driver->devices); - driver->devices = NULL; - } - - if (driver->directory == NULL) - return (sysfs_get_driver_devices(driver)); - - if ((sysfs_refresh_dir_links(driver->directory)) != 0) { - dprintf("Error refreshing driver links\n"); - return NULL; - } - - return (sysfs_get_driver_devices(driver)); -} - -/** - * sysfs_get_driver_device: looks up a device from a list of driver's devices - * and returns its sysfs_device corresponding to it - * @driver: sysfs_driver on which to search - * @name: name of the device to search - * Returns a sysfs_device if found, NULL otherwise - */ -struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver, - const char *name) -{ - struct sysfs_device *device = NULL; - struct dlist *devlist = NULL; - - if (driver == NULL || name == NULL) { - errno = EINVAL; - return NULL; - } - - if (driver->devices == NULL) { - devlist = sysfs_get_driver_devices(driver); - if (devlist == NULL) { - dprintf("Error getting driver devices\n"); - return NULL; - } - } - dlist_for_each_data(driver->devices, device, struct sysfs_device) { - if (!(strncmp(device->name, name, SYSFS_NAME_LEN))) - return device; - } - return NULL; -} - /** * get_driver_path: looks up the bus the driver is on and builds path to * the driver. @@ -327,11 +165,11 @@ struct sysfs_device *sysfs_get_driver_device(struct sysfs_driver *driver, static int get_driver_path(const char *bus, const char *drv, char *path, size_t psize) { - if (bus == NULL || drv == NULL || path == NULL || psize == 0) { + if (!bus || !drv || !path || psize == 0) { errno = EINVAL; return -1; } - if (sysfs_get_mnt_path(path, psize) != 0) { + if (sysfs_get_mnt_path(path, psize)) { dprintf("Error getting sysfs mount path\n"); return -1; } @@ -346,50 +184,6 @@ static int get_driver_path(const char *bus, const char *drv, return 0; } -/** - * sysfs_open_driver_attr: read the user supplied driver attribute - * @bus: bus on which to look - * @drv: driver whose attribute has to be read - * @attrib: Attribute to be read - * Returns struct sysfs_attribute on success and NULL on failure - * - * NOTE: - * A call to sysfs_close_attribute() is required to close the - * attribute returned and to free memory - */ -struct sysfs_attribute *sysfs_open_driver_attr(const char *bus, - const char *drv, const char *attrib) -{ - struct sysfs_attribute *attribute = NULL; - char path[SYSFS_PATH_MAX]; - - if (bus == NULL || drv == NULL || attrib == NULL) { - errno = EINVAL; - return NULL; - } - - memset(path, 0, SYSFS_PATH_MAX); - if ((get_driver_path(bus, drv, path, SYSFS_PATH_MAX)) != 0) { - dprintf("Error getting to driver %s\n", drv); - return NULL; - } - safestrcat(path, "/"); - safestrcat(path, attrib); - attribute = sysfs_open_attribute(path); - if (attribute == NULL) { - dprintf("Error opening attribute %s for driver %s\n", - attrib, drv); - return NULL; - } - if ((sysfs_read_attribute(attribute)) != 0) { - dprintf("Error reading attribute %s for driver %s\n", - attrib, drv); - sysfs_close_attribute(attribute); - return NULL; - } - return attribute; -} - /** * sysfs_open_driver: open driver by name, given its bus * @bus_name: Name of the bus @@ -402,21 +196,66 @@ struct sysfs_driver *sysfs_open_driver(const char *bus_name, char path[SYSFS_PATH_MAX]; struct sysfs_driver *driver = NULL; - if (drv_name == NULL || bus_name == NULL) { + if (!drv_name || !bus_name) { errno = EINVAL; return NULL; } memset(path, 0, SYSFS_PATH_MAX); - if ((get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) != 0) { + if (get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) { dprintf("Error getting to driver %s\n", drv_name); return NULL; } driver = sysfs_open_driver_path(path); - if (driver == NULL) { + if (!driver) { dprintf("Error opening driver at %s\n", path); return NULL; } return driver; } +/** + * sysfs_get_driver_devices: gets list of devices that use the driver + * @drv: sysfs_driver whose device list is needed + * Returns dlist of struct sysfs_device on success and NULL on failure + */ +struct dlist *sysfs_get_driver_devices(struct sysfs_driver *drv) +{ + char *ln = NULL; + struct dlist *linklist = NULL; + struct sysfs_device *dev = NULL; + + if (!drv) { + errno = EINVAL; + return NULL; + } + + linklist = read_dir_links(drv->path); + if (linklist) { + dlist_for_each_data(linklist, ln, char) { + + if (!strncmp(ln, SYSFS_MODULE_NAME, strlen(ln))) + continue; + + dev = sysfs_open_device(drv->bus, ln); + if (!dev) { + dprintf("Error opening driver's device\n"); + sysfs_close_list(linklist); + return NULL; + } + if (!drv->devices) { + drv->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_driver_device); + if (!drv->devices) { + dprintf("Error creating device list\n"); + sysfs_close_list(linklist); + return NULL; + } + } + dlist_unshift_sorted(drv->devices, dev, sort_list); + } + sysfs_close_list(linklist); + } + return drv->devices; +} diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 8b1f56ed14..9f6e18f665 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -23,12 +23,6 @@ #include "libsysfs.h" #include "sysfs.h" -static int sort_char(void *new, void *old) -{ - return ((strncmp((char *)new, (char *)old, - strlen((char *)new))) < 0 ? 1 : 0); -} - /** * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path * @path: Path to look for the trailing '/' @@ -38,7 +32,7 @@ int sysfs_remove_trailing_slash(char *path) { char *c = NULL; - if (path == NULL) { + if (!path) { errno = EINVAL; return 1; } @@ -53,54 +47,6 @@ int sysfs_remove_trailing_slash(char *path) return 0; } -/** - * sysfs_get_fs_mnt_path: Gets the mount point for specified filesystem. - * @fs_type: filesystem type to retrieve mount point - * @mnt_path: place to put the retrieved mount path - * @len: size of mnt_path - * returns 0 with success and -1 with error. - */ -static int sysfs_get_fs_mnt_path(const char *fs_type, - char *mnt_path, size_t len) -{ - FILE *mnt; - struct mntent *mntent; - int ret = 0; - size_t dirlen = 0; - - /* check arg */ - if (fs_type == NULL || mnt_path == NULL || len == 0) { - errno = EINVAL; - return -1; - } - - if ((mnt = setmntent(SYSFS_PROC_MNTS, "r")) == NULL) { - dprintf("Error getting mount information\n"); - return -1; - } - while (ret == 0 && dirlen == 0 && (mntent = getmntent(mnt)) != NULL) { - if (strcmp(mntent->mnt_type, fs_type) == 0) { - dirlen = strlen(mntent->mnt_dir); - if (dirlen <= (len - 1)) { - safestrcpymax(mnt_path, mntent->mnt_dir, len); - } else { - dprintf("Error - mount path too long\n"); - ret = -1; - } - } - } - endmntent(mnt); - if (dirlen == 0 && ret == 0) { - dprintf("Filesystem %s not found!\n", fs_type); - errno = EINVAL; - ret = -1; - } - if ((sysfs_remove_trailing_slash(mnt_path)) != 0) - ret = -1; - - return ret; -} - /* * sysfs_get_mnt_path: Gets the sysfs mount point. * @mnt_path: place to put "sysfs" mount point @@ -109,22 +55,21 @@ static int sysfs_get_fs_mnt_path(const char *fs_type, */ int sysfs_get_mnt_path(char *mnt_path, size_t len) { - char *sysfs_path = NULL; - int ret = 0; + static char sysfs_path[SYSFS_PATH_MAX] = ""; + const char *sysfs_path_env; - if (mnt_path == NULL || len == 0) { - errno = EINVAL; - return -1; + /* evaluate only at the first call */ + if (sysfs_path[0] == '\0') { + /* possible overrride of real mount path */ + sysfs_path_env = getenv(SYSFS_PATH_ENV); + if (sysfs_path_env != NULL) { + safestrcpymax(mnt_path, sysfs_path_env, len); + return 0; + } + safestrcpymax(mnt_path, SYSFS_MNT_PATH, len); } - sysfs_path = getenv(SYSFS_PATH_ENV); - if (sysfs_path != NULL) { - safestrcpymax(mnt_path, sysfs_path, len); - if ((sysfs_remove_trailing_slash(mnt_path)) != 0) - return 1; - } else - ret = sysfs_get_fs_mnt_path(SYSFS_FSTYPE_NAME, mnt_path, len); - return ret; + return 0; } /** @@ -137,8 +82,8 @@ int sysfs_get_name_from_path(const char *path, char *name, size_t len) { char tmp[SYSFS_PATH_MAX]; char *n = NULL; - - if (path == NULL || name == NULL || len == 0) { + + if (!path || !name || len == 0) { errno = EINVAL; return -1; } @@ -161,7 +106,7 @@ int sysfs_get_name_from_path(const char *path, char *name, size_t len) safestrcpymax(name, n, len); return 0; } - + /** * sysfs_get_link: returns link source * @path: symbolic link's path @@ -176,7 +121,7 @@ int sysfs_get_link(const char *path, char *target, size_t len) char *d = NULL, *s = NULL; int slashes = 0, count = 0; - if (path == NULL || target == NULL || len == 0) { + if (!path || !target || len == 0) { errno = EINVAL; return -1; } @@ -190,15 +135,15 @@ int sysfs_get_link(const char *path, char *target, size_t len) return -1; } d = linkpath; - /* + /* * Three cases here: * 1. relative path => format ../.. * 2. absolute path => format /abcd/efgh * 3. relative path _from_ this dir => format abcd/efgh - */ + */ switch (*d) { case '.': - /* + /* * handle the case where link is of type ./abcd/xxx */ safestrcpy(temp_path, devdir); @@ -215,9 +160,8 @@ int sysfs_get_link(const char *path, char *target, size_t len) } safestrcpymax(target, temp_path, len); break; - /* - * relative path - * getting rid of leading "../.." + /* + * relative path, getting rid of leading "../.." */ parse_path: while (*d == '/' || *d == '.') { @@ -254,16 +198,6 @@ parse_path: return 0; } -/** - * sysfs_del_name: free function for sysfs_open_subsystem_list - * @name: memory area to be freed - */ -static void sysfs_del_name(void *name) -{ - free(name); -} - - /** * sysfs_close_list: generic list free routine * @list: dlist to free @@ -271,142 +205,22 @@ static void sysfs_del_name(void *name) */ void sysfs_close_list(struct dlist *list) { - if (list != NULL) + if (list) dlist_destroy(list); } /** - * sysfs_open_subsystem_list: gets a list of all supported "name" subsystem - * details from the system - * @name: name of the subsystem, eg., "bus", "class", "devices" - * Returns a dlist of supported names or NULL if subsystem not supported - */ -struct dlist *sysfs_open_subsystem_list(char *name) + * sysfs_open_directory_list: gets a list of all directories under "path" + * @path: path to read + * Returns a dlist of supported names or NULL no directories (errno is set + * in case of error + */ +struct dlist *sysfs_open_directory_list(const char *path) { - char sysfs_path[SYSFS_PATH_MAX], *subsys_name = NULL; - char *c = NULL; - struct sysfs_directory *dir = NULL, *cur = NULL; - struct dlist *list = NULL; - - if (name == NULL) + if (!path) return NULL; - if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { - dprintf("Error getting sysfs mount point\n"); - return NULL; - } - - safestrcat(sysfs_path, "/"); - safestrcat(sysfs_path, name); - dir = sysfs_open_directory(sysfs_path); - if (dir == NULL) { - dprintf("Error opening sysfs_directory at %s\n", sysfs_path); - return NULL; - } - - if ((sysfs_read_dir_subdirs(dir)) != 0) { - dprintf("Error reading sysfs_directory at %s\n", sysfs_path); - sysfs_close_directory(dir); - return NULL; - } - - if (dir->subdirs != NULL) { - list = dlist_new_with_delete(SYSFS_NAME_LEN, - sysfs_del_name); - if (list == NULL) { - dprintf("Error creating list\n"); - sysfs_close_directory(dir); - return NULL; - } - - dlist_for_each_data(dir->subdirs, cur, - struct sysfs_directory) { - subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); - safestrcpymax(subsys_name, cur->name, SYSFS_NAME_LEN); - dlist_unshift_sorted(list, subsys_name, sort_char); - } - } - sysfs_close_directory(dir); - /* - * We are now considering "block" as a "class". Hence, if the subsys - * name requested here is "class", verify if "block" is supported on - * this system and return the same. - */ - if (strcmp(name, SYSFS_CLASS_NAME) == 0) { - c = strstr(sysfs_path, SYSFS_CLASS_NAME); - if (c == NULL) - goto out; - *c = '\0'; - safestrcpymax(c, SYSFS_BLOCK_NAME, - sizeof(sysfs_path) - strlen(sysfs_path)); - if ((sysfs_path_is_dir(sysfs_path)) == 0) { - subsys_name = (char *)calloc(1, SYSFS_NAME_LEN); - safestrcpymax(subsys_name, SYSFS_BLOCK_NAME, - SYSFS_NAME_LEN); - dlist_unshift_sorted(list, subsys_name, sort_char); - } - } -out: - return list; -} - - -/** - * sysfs_open_bus_devices_list: gets a list of all devices on "name" bus - * @name: name of the subsystem, eg., "pci", "scsi", "usb" - * Returns a dlist of supported names or NULL if subsystem not supported - */ -struct dlist *sysfs_open_bus_devices_list(char *name) -{ - char sysfs_path[SYSFS_PATH_MAX], *device_name = NULL; - struct sysfs_directory *dir = NULL; - struct sysfs_link *cur = NULL; - struct dlist *list = NULL; - - if (name == NULL) - return NULL; - - if (sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX) != 0) { - dprintf("Error getting sysfs mount point\n"); - return NULL; - } - - safestrcat(sysfs_path, "/"); - safestrcat(sysfs_path, SYSFS_BUS_NAME); - safestrcat(sysfs_path, "/"); - safestrcat(sysfs_path, name); - safestrcat(sysfs_path, "/"); - safestrcat(sysfs_path, SYSFS_DEVICES_NAME); - dir = sysfs_open_directory(sysfs_path); - if (dir == NULL) { - dprintf("Error opening sysfs_directory at %s\n", sysfs_path); - return NULL; - } - - if ((sysfs_read_dir_links(dir)) != 0) { - dprintf("Error reading sysfs_directory at %s\n", sysfs_path); - sysfs_close_directory(dir); - return NULL; - } - - if (dir->links != NULL) { - list = dlist_new_with_delete(SYSFS_NAME_LEN, - sysfs_del_name); - if (list == NULL) { - dprintf("Error creating list\n"); - sysfs_close_directory(dir); - return NULL; - } - - dlist_for_each_data(dir->links, cur, - struct sysfs_link) { - device_name = (char *)calloc(1, SYSFS_NAME_LEN); - safestrcpymax(device_name, cur->name, SYSFS_NAME_LEN); - dlist_unshift_sorted(list, device_name, sort_char); - } - } - sysfs_close_directory(dir); - return list; + return (read_dir_subdirs(path)); } /** @@ -418,7 +232,7 @@ int sysfs_path_is_dir(const char *path) { struct stat astats; - if (path == NULL) { + if (!path) { errno = EINVAL; return 1; } @@ -428,7 +242,7 @@ int sysfs_path_is_dir(const char *path) } if (S_ISDIR(astats.st_mode)) return 0; - + return 1; } @@ -441,7 +255,7 @@ int sysfs_path_is_link(const char *path) { struct stat astats; - if (path == NULL) { + if (!path) { errno = EINVAL; return 1; } @@ -451,7 +265,7 @@ int sysfs_path_is_link(const char *path) } if (S_ISLNK(astats.st_mode)) return 0; - + return 1; } @@ -464,7 +278,7 @@ int sysfs_path_is_file(const char *path) { struct stat astats; - if (path == NULL) { + if (!path) { errno = EINVAL; return 1; } @@ -474,6 +288,6 @@ int sysfs_path_is_file(const char *path) } if (S_ISREG(astats.st_mode)) return 0; - + return 1; } diff --git a/udevinfo.8 b/udevinfo.8 index bbcc3d8f49..963b69aed2 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -47,10 +47,6 @@ attributes along the device chain. Useful for finding unique attributes to compose a rule. .RB Needs " \-p " specified. .TP -.B \-s -Print all sysfs devices with the major/minor number, the physical device and -the bus value. -.TP .B \-h Print help text. .SH "FILES" diff --git a/udevinfo.c b/udevinfo.c index e9de6e5e09..a4c17da3f0 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -49,26 +49,13 @@ void log_message (int level, const char *format, ...) } #endif -static int print_all_attributes(const char *path) +static void print_all_attributes(struct dlist *attr_list) { - struct dlist *attributes; struct sysfs_attribute *attr; - struct sysfs_directory *sysfs_dir; char value[SYSFS_VALUE_SIZE]; int len; - int retval = 0; - sysfs_dir = sysfs_open_directory(path); - if (sysfs_dir == NULL) - return -1; - - attributes = sysfs_get_dir_attributes(sysfs_dir); - if (attributes == NULL) { - retval = -1; - goto exit; - } - - dlist_for_each_data(attributes, attr, struct sysfs_attribute) { + dlist_for_each_data(attr_list, attr, struct sysfs_attribute) { if (attr->value != NULL) { strfieldcpy(value, attr->value); len = strlen(value); @@ -92,11 +79,6 @@ static int print_all_attributes(const char *path) } } printf("\n"); - -exit: - sysfs_close_directory(sysfs_dir); - - return retval; } static int print_record(struct udevice *udev) @@ -123,6 +105,7 @@ static int print_device_chain(const char *path) struct sysfs_attribute *attr; struct sysfs_device *sysfs_dev; struct sysfs_device *sysfs_dev_parent; + struct dlist *attr_list; int retval = 0; /* get the class dev */ @@ -147,11 +130,14 @@ static int print_device_chain(const char *path) /* open sysfs class device directory and print all attributes */ printf(" looking at class device '%s':\n", class_dev->path); printf(" SUBSYSTEM=\"%s\"\n", class_dev->classname); - if (print_all_attributes(class_dev->path) != 0) { + + attr_list = sysfs_get_classdev_attributes(class_dev); + if (attr_list == NULL) { printf("couldn't open class device directory\n"); retval = -1; goto exit; } + print_all_attributes(attr_list); /* get the device link (if parent exists look here) */ class_dev_parent = sysfs_get_classdev_parent(class_dev); @@ -165,13 +151,20 @@ static int print_device_chain(const char *path) /* look the device chain upwards */ while (sysfs_dev != NULL) { + attr_list = sysfs_get_device_attributes(sysfs_dev); + if (attr_list == NULL) { + printf("couldn't open device directory\n"); + retval = -1; + goto exit; + } + printf(" looking at the device chain at '%s':\n", sysfs_dev->path); printf(" BUS=\"%s\"\n", sysfs_dev->bus); printf(" ID=\"%s\"\n", sysfs_dev->bus_id); printf(" DRIVER=\"%s\"\n", sysfs_dev->driver_name); /* open sysfs device directory and print all attributes */ - print_all_attributes(sysfs_dev->path); + print_all_attributes(attr_list); sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev); if (sysfs_dev_parent == NULL) @@ -185,65 +178,9 @@ exit: return retval; } -/* print all class/main block devices with major/minor, physical device, driver and bus */ -static int print_sysfs_devices(void) -{ - struct dlist *subsyslist; - char *class; - - subsyslist = sysfs_open_subsystem_list("class"); - if (!subsyslist) - return -1; - - dlist_for_each_data(subsyslist, class, char) { - struct sysfs_class *cls; - struct dlist *class_devices; - struct sysfs_class_device *class_dev; - struct sysfs_device *phys_dev; - unsigned int major, minor; - - cls = sysfs_open_class(class); - if (!cls) - continue; - - class_devices = sysfs_get_class_devices(cls); - if (!class_devices) - continue; - - dlist_for_each_data(class_devices, class_dev, struct sysfs_class_device) { - struct sysfs_attribute *attr; - - printf("\n"); - printf("DEVPATH '%s'\n", class_dev->path); - printf("SUBSYSTEM '%s'\n", class_dev->classname); - - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr) { - sscanf(attr->value, "%u:%u", &major, &minor); - printf("MAJOR %u\n", major); - printf("MINOR %u\n", minor); - } - - phys_dev = sysfs_get_classdev_device(class_dev); - if (phys_dev) { - printf("PHYSDEVPATH '%s'\n", phys_dev->path); - if (phys_dev->bus[0] != '\0') - printf("PHYSDEVBUS '%s'\n", phys_dev->bus); - - if (phys_dev->driver_name[0] != '\0') - printf("PHYSDEVDRIVER '%s'\n", phys_dev->driver_name); - } - } - sysfs_close_class(cls); - } - sysfs_close_list(subsyslist); - - return 0; -} - static int process_options(int argc, char *argv[]) { - static const char short_options[] = "an:p:q:rsVh"; + static const char short_options[] = "an:p:q:rVh"; int option; int retval = 1; struct udevice udev; @@ -304,10 +241,6 @@ static int process_options(int argc, char *argv[]) root = 1; break; - case 's': - print_sysfs_devices(); - exit(0); - case 'a': attributes = 1; break; From 833aa0fab572536ebb680cc54bf95c50c3b36a0f Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 24 Feb 2005 19:54:47 +0100 Subject: [PATCH 1176/4284] [PATCH] klibc v0.199 --- klibc/MCONFIG | 5 ++ klibc/include/arch/parisc/klibc/archsetjmp.h | 14 +++++ klibc/klibc.spec | 2 +- klibc/klibc/arch/alpha/MCONFIG | 2 +- klibc/klibc/arch/arm/MCONFIG | 2 +- klibc/klibc/arch/ia64/MCONFIG | 2 +- klibc/klibc/arch/ia64/setjmp.S | 2 + klibc/klibc/arch/ia64/vfork.S | 3 +- klibc/klibc/arch/m32r/MCONFIG | 2 +- klibc/klibc/arch/mips/MCONFIG | 2 +- klibc/klibc/arch/mips64/MCONFIG | 2 +- klibc/klibc/arch/parisc/setjmp.S | 2 +- klibc/klibc/arch/parisc/sysstub.ph | 1 - klibc/klibc/arch/ppc/MCONFIG | 2 +- klibc/klibc/arch/ppc64/MCONFIG | 2 +- klibc/klibc/arch/s390/MCONFIG | 2 +- klibc/klibc/arch/s390x/MCONFIG | 2 +- klibc/klibc/arch/sparc/MCONFIG | 2 +- klibc/klibc/arch/sparc64/MCONFIG | 2 +- klibc/klibc/arch/sparc64/crt0.S | 2 +- klibc/klibc/memmem.c | 54 +++++++++++--------- klibc/klibc/strncat.c | 1 - klibc/version | 2 +- 23 files changed, 70 insertions(+), 42 deletions(-) create mode 100644 klibc/include/arch/parisc/klibc/archsetjmp.h diff --git a/klibc/MCONFIG b/klibc/MCONFIG index 7da150d031..3fae2898c6 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -62,5 +62,10 @@ ERRLIST = 1 # include $(KLIBSRC)/arch/$(ARCH)/MCONFIG +ifeq ($(DEBUG),y) +STRIP = /bin/true -Since_we_are_debugging +OPTFLAGS += -O1 -g +endif + # How to tell the linker main() is the entrypoint EMAIN ?= -e main diff --git a/klibc/include/arch/parisc/klibc/archsetjmp.h b/klibc/include/arch/parisc/klibc/archsetjmp.h new file mode 100644 index 0000000000..e7444983ed --- /dev/null +++ b/klibc/include/arch/parisc/klibc/archsetjmp.h @@ -0,0 +1,14 @@ +/* + * arch/parisc/include/klibc/archsetjmp.h + */ + +#ifndef _KLIBC_ARCHSETJMP_H +#define _KLIBC_ARCHSETJMP_H + +struct __jmp_buf { + double regs[21]; +}; + +typedef struct __jmp_buf jmp_buf[1]; + +#endif /* _SETJMP_H */ diff --git a/klibc/klibc.spec b/klibc/klibc.spec index 02131c7f25..de0a14cf63 100644 --- a/klibc/klibc.spec +++ b/klibc/klibc.spec @@ -1,6 +1,6 @@ Summary: A minimal libc subset for use with initramfs. Name: klibc -Version: 0.198 +Version: 0.199 Release: 1 License: BSD/GPL Group: Development/Libraries diff --git a/klibc/klibc/arch/alpha/MCONFIG b/klibc/klibc/arch/alpha/MCONFIG index 5987ed5841..d7ab6c0b82 100644 --- a/klibc/klibc/arch/alpha/MCONFIG +++ b/klibc/klibc/arch/alpha/MCONFIG @@ -5,7 +5,7 @@ # Build configuration for this architecture # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 64 # Extra linkflags when building the shared version of the library diff --git a/klibc/klibc/arch/arm/MCONFIG b/klibc/klibc/arch/arm/MCONFIG index 6fbea32903..fe26b996a7 100644 --- a/klibc/klibc/arch/arm/MCONFIG +++ b/klibc/klibc/arch/arm/MCONFIG @@ -11,7 +11,7 @@ THUMB = n CPU_ARCH := armv4 CPU_TUNE := strongarm -OPTFLAGS = -Os -fomit-frame-pointer -march=$(CPU_ARCH) -mtune=$(CPU_TUNE) +OPTFLAGS = -Os -march=$(CPU_ARCH) -mtune=$(CPU_TUNE) BITSIZE = 32 ifeq ($(THUMB),y) diff --git a/klibc/klibc/arch/ia64/MCONFIG b/klibc/klibc/arch/ia64/MCONFIG index 631a478e4f..36b30ffb81 100644 --- a/klibc/klibc/arch/ia64/MCONFIG +++ b/klibc/klibc/arch/ia64/MCONFIG @@ -7,5 +7,5 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 64 diff --git a/klibc/klibc/arch/ia64/setjmp.S b/klibc/klibc/arch/ia64/setjmp.S index 50f91dc1d6..7859ba4143 100644 --- a/klibc/klibc/arch/ia64/setjmp.S +++ b/klibc/klibc/arch/ia64/setjmp.S @@ -61,6 +61,7 @@ // .align 32 .global setjmp + .proc setjmp setjmp: // // Make sure buffer is aligned at 16byte boundary @@ -190,6 +191,7 @@ setjmp: .align 32 .global longjmp + .proc longjmp longjmp: // // Make sure buffer is aligned at 16byte boundary diff --git a/klibc/klibc/arch/ia64/vfork.S b/klibc/klibc/arch/ia64/vfork.S index efcd03f7f1..f79bdc8234 100644 --- a/klibc/klibc/arch/ia64/vfork.S +++ b/klibc/klibc/arch/ia64/vfork.S @@ -19,6 +19,7 @@ /* pid_t vfork(void) */ /* Implemented as clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */ + .align 32 .proc vfork .global vfork vfork: @@ -38,4 +39,4 @@ vfork: ;; (p7) mov r8=-1 br.ret.sptk.many b0 - .endp + .endp vfork diff --git a/klibc/klibc/arch/m32r/MCONFIG b/klibc/klibc/arch/m32r/MCONFIG index 6706d9ddc1..2673090fce 100644 --- a/klibc/klibc/arch/m32r/MCONFIG +++ b/klibc/klibc/arch/m32r/MCONFIG @@ -7,7 +7,7 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 32 # Extra linkflags when building the shared version of the library diff --git a/klibc/klibc/arch/mips/MCONFIG b/klibc/klibc/arch/mips/MCONFIG index a248973815..0a98918987 100644 --- a/klibc/klibc/arch/mips/MCONFIG +++ b/klibc/klibc/arch/mips/MCONFIG @@ -8,7 +8,7 @@ # ARCHREQFLAGS = -fno-pic -mno-abicalls -G 0 -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 32 # Extra linkflags when building the shared version of the library diff --git a/klibc/klibc/arch/mips64/MCONFIG b/klibc/klibc/arch/mips64/MCONFIG index 6a817e54b6..66405e4373 100644 --- a/klibc/klibc/arch/mips64/MCONFIG +++ b/klibc/klibc/arch/mips64/MCONFIG @@ -7,5 +7,5 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 64 diff --git a/klibc/klibc/arch/parisc/setjmp.S b/klibc/klibc/arch/parisc/setjmp.S index 51b2b1a58b..aebe03a5ed 100644 --- a/klibc/klibc/arch/parisc/setjmp.S +++ b/klibc/klibc/arch/parisc/setjmp.S @@ -27,7 +27,7 @@ setjmp: stw %r17,60(%r26) stw %r18,64(%r26) stw %r19,68(%r26) - stw %dp,72(%r26) + stw %r27,72(%r26) stw %r30,76(%r26) stw %rp,80(%r26) ldo 88(%r26),%r19 diff --git a/klibc/klibc/arch/parisc/sysstub.ph b/klibc/klibc/arch/parisc/sysstub.ph index eb6b5dd92a..63b5e17fcf 100644 --- a/klibc/klibc/arch/parisc/sysstub.ph +++ b/klibc/klibc/arch/parisc/sysstub.ph @@ -16,7 +16,6 @@ sub make_sysstub($$$$@) { print OUT "\t.import __syscall_common, code\n"; print OUT "\t.global ${fname}\n"; print OUT "\t.export ${fname}, code\n"; - print OUT "\t.type ${fname}, @function\n"; print OUT "\t.proc\n"; print OUT "\.callinfo\n"; print OUT "${fname}:\n"; diff --git a/klibc/klibc/arch/ppc/MCONFIG b/klibc/klibc/arch/ppc/MCONFIG index ff7c44db9a..82c7107013 100644 --- a/klibc/klibc/arch/ppc/MCONFIG +++ b/klibc/klibc/arch/ppc/MCONFIG @@ -7,7 +7,7 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 32 # Extra linkflags when building the shared version of the library diff --git a/klibc/klibc/arch/ppc64/MCONFIG b/klibc/klibc/arch/ppc64/MCONFIG index 09881b8d40..9aba2ddbb6 100644 --- a/klibc/klibc/arch/ppc64/MCONFIG +++ b/klibc/klibc/arch/ppc64/MCONFIG @@ -8,7 +8,7 @@ # ARCHREQFLAGS = -m64 -mcall-aixdesc -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 64 LDFLAGS = -m elf64ppc diff --git a/klibc/klibc/arch/s390/MCONFIG b/klibc/klibc/arch/s390/MCONFIG index e32c33faa1..640b395b54 100644 --- a/klibc/klibc/arch/s390/MCONFIG +++ b/klibc/klibc/arch/s390/MCONFIG @@ -7,7 +7,7 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 32 SHAREDFLAGS = -Ttext 0x40000200 diff --git a/klibc/klibc/arch/s390x/MCONFIG b/klibc/klibc/arch/s390x/MCONFIG index 1c8232bed5..081a0bbb52 100644 --- a/klibc/klibc/arch/s390x/MCONFIG +++ b/klibc/klibc/arch/s390x/MCONFIG @@ -7,7 +7,7 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 64 SHAREDFLAGS = -Ttext 0x40000200 diff --git a/klibc/klibc/arch/sparc/MCONFIG b/klibc/klibc/arch/sparc/MCONFIG index cb94f46c00..55f8b198c2 100644 --- a/klibc/klibc/arch/sparc/MCONFIG +++ b/klibc/klibc/arch/sparc/MCONFIG @@ -7,7 +7,7 @@ # accordingly. # -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 32 # Extra linkflags when building the shared version of the library diff --git a/klibc/klibc/arch/sparc64/MCONFIG b/klibc/klibc/arch/sparc64/MCONFIG index d490c63643..a8a742412e 100644 --- a/klibc/klibc/arch/sparc64/MCONFIG +++ b/klibc/klibc/arch/sparc64/MCONFIG @@ -8,7 +8,7 @@ # ARCHREQFLAGS = -m64 -mptr64 -OPTFLAGS = -Os -fomit-frame-pointer +OPTFLAGS = -Os BITSIZE = 64 LDFLAGS = -m elf64_sparc diff --git a/klibc/klibc/arch/sparc64/crt0.S b/klibc/klibc/arch/sparc64/crt0.S index 23af82ecc4..5faee7c6be 100644 --- a/klibc/klibc/arch/sparc64/crt0.S +++ b/klibc/klibc/arch/sparc64/crt0.S @@ -1,2 +1,2 @@ #define TARGET_PTR_SIZE 64 -#include "arch/sparc/crt0i.S" +#include "../sparc/crt0i.S" diff --git a/klibc/klibc/memmem.c b/klibc/klibc/memmem.c index 0f59938ffb..8b5faa0014 100644 --- a/klibc/klibc/memmem.c +++ b/klibc/klibc/memmem.c @@ -13,32 +13,40 @@ void *memmem(const void *haystack, size_t n, const void *needle, size_t m) { - const unsigned char *y = (const unsigned char *)haystack; - const unsigned char *x = (const unsigned char *)needle; + const unsigned char *y = (const unsigned char *)haystack; + const unsigned char *x = (const unsigned char *)needle; - size_t j, k, l; + size_t j, k, l; - if ( m > n ) - return NULL; + if (m > n || !m || !n) + return NULL; - if ( x[0] == x[1] ) { - k = 2; - l = 1; - } else { - k = 1; - l = 2; - } + if (1 != m) { + if (x[0] == x[1]) { + k = 2; + l = 1; + } else { + k = 1; + l = 2; + } - j = 0; - while ( j <= n-m ) { - if (x[1] != y[j+1]) { - j += k; - } else { - if ( !memcmp(x+2, y+j+2, m-2) && x[0] == y[j] ) - return (void *)&y[j]; - j += l; - } - } + j = 0; + while (j <= n - m) { + if (x[1] != y[j + 1]) { + j += k; + } else { + if (!memcmp(x + 2, y + j + 2, m - 2) + && x[0] == y[j]) + return (void *)&y[j]; + j += l; + } + } + } else + do { + if (*y == *x) + return (void *)y; + y++; + } while (--n); - return NULL; + return NULL; } diff --git a/klibc/klibc/strncat.c b/klibc/klibc/strncat.c index 4d8458d5ec..78223152c4 100644 --- a/klibc/klibc/strncat.c +++ b/klibc/klibc/strncat.c @@ -10,7 +10,6 @@ char *strncat(char *dst, const char *src, size_t n) char *q = strchr(dst, '\0'); const char *p = src; char ch; - size_t nn = q-dst; while (n--) { *q++ = ch = *p++; diff --git a/klibc/version b/klibc/version index 129efcc007..b4d2b300cd 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.198 +0.199 From f8a178a35b8dee2ee46a3de298345aa4faa8f41e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 24 Feb 2005 20:13:25 +0100 Subject: [PATCH 1177/4284] [PATCH] trivial rename of some variables --- namedev.c | 2 +- udev_db.c | 2 +- udev_db.h | 2 +- udevd.c | 22 +++++++++++----------- udevd.h | 2 +- udevinfo.c | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/namedev.c b/namedev.c index a365574435..f0a5c34f79 100644 --- a/namedev.c +++ b/namedev.c @@ -152,7 +152,7 @@ static int find_free_number(struct udevice *udev, const char *name) while (1) { dbg("look for existing node '%s'", filename); memset(&db_udev, 0x00, sizeof(struct udevice)); - if (udev_db_get_device_byname(&db_udev, filename) != 0) { + if (udev_db_get_device_by_name(&db_udev, filename) != 0) { dbg("free num=%d", num); return num; } diff --git a/udev_db.c b/udev_db.c index df63bbe2ce..61d4b130d3 100644 --- a/udev_db.c +++ b/udev_db.c @@ -179,7 +179,7 @@ int udev_db_get_device_by_devpath(struct udevice *udev, const char *devpath) return parse_db_file(udev, filename); } -int udev_db_get_device_byname(struct udevice *udev, const char *name) +int udev_db_get_device_by_name(struct udevice *udev, const char *name) { struct dirent *ent; DIR *dir; diff --git a/udev_db.h b/udev_db.h index 75f1d98296..5065eaa6c6 100644 --- a/udev_db.h +++ b/udev_db.h @@ -29,6 +29,6 @@ extern int udev_db_add_device(struct udevice *dev); extern int udev_db_delete_device(struct udevice *dev); extern int udev_db_get_device_by_devpath(struct udevice *dev, const char *devpath); -extern int udev_db_get_device_byname(struct udevice *udev, const char *name); +extern int udev_db_get_device_by_name(struct udevice *udev, const char *name); #endif /* _UDEV_DB_H_ */ diff --git a/udevd.c b/udevd.c index 7d7fd63332..bd21f15614 100644 --- a/udevd.c +++ b/udevd.c @@ -87,14 +87,14 @@ static void msg_dump_queue(void) #ifdef DEBUG struct hotplug_msg *msg; - list_for_each_entry(msg, &msg_list, list) + list_for_each_entry(msg, &msg_list, node) dbg("sequence %llu in queue", msg->seqnum); #endif } static void run_queue_delete(struct hotplug_msg *msg) { - list_del(&msg->list); + list_del(&msg->node); free(msg); } @@ -106,13 +106,13 @@ static void msg_queue_insert(struct hotplug_msg *msg) if (msg->seqnum == 0) { dbg("no SEQNUM, move straight to the exec queue"); - list_add(&msg->list, &exec_list); + list_add(&msg->node, &exec_list); run_exec_q = 1; return; } /* sort message by sequence number into list */ - list_for_each_entry_reverse(loop_msg, &msg_list, list) { + list_for_each_entry_reverse(loop_msg, &msg_list, node) { if (loop_msg->seqnum < msg->seqnum) break; @@ -126,7 +126,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) sysinfo(&info); msg->queue_time = info.uptime; - list_add(&msg->list, &loop_msg->list); + list_add(&msg->node, &loop_msg->node); dbg("queued message seq %llu", msg->seqnum); /* run msg queue manager */ @@ -291,7 +291,7 @@ static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) if (msg->devpath == NULL) return NULL; - list_for_each_entry(loop_msg, &running_list, list) { + list_for_each_entry(loop_msg, &running_list, node) { if (loop_msg->devpath == NULL) continue; @@ -321,7 +321,7 @@ static void exec_queue_manager(void) if (running < 0) running = THROTTLE_MAX_RUNNING_CHILDS; - list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, list) { + list_for_each_entry_safe(loop_msg, tmp_msg, &exec_list, node) { /* check running processes in our session and possibly throttle */ if (running >= THROTTLE_MAX_RUNNING_CHILDS) { running = running_processes_in_session(sid, THROTTLE_MAX_RUNNING_CHILDS+10); @@ -335,7 +335,7 @@ static void exec_queue_manager(void) msg = running_with_devpath(loop_msg); if (!msg) { /* move event to run list */ - list_move_tail(&loop_msg->list, &running_list); + list_move_tail(&loop_msg->node, &running_list); udev_run(loop_msg); running++; dbg("moved seq %llu to running list", loop_msg->seqnum); @@ -348,7 +348,7 @@ static void exec_queue_manager(void) static void msg_move_exec(struct hotplug_msg *msg) { - list_move_tail(&msg->list, &exec_list); + list_move_tail(&msg->node, &exec_list); run_exec_q = 1; expected_seqnum = msg->seqnum+1; dbg("moved seq %llu to exec, next expected is %llu", @@ -367,7 +367,7 @@ static void msg_queue_manager(void) dbg("msg queue manager, next expected is %llu", expected_seqnum); recheck: - list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, list) { + list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, node) { /* move event with expected sequence to the exec list */ if (loop_msg->seqnum == expected_seqnum) { msg_move_exec(loop_msg); @@ -532,7 +532,7 @@ static void udev_done(int pid) /* find msg associated with pid and delete it */ struct hotplug_msg *msg; - list_for_each_entry(msg, &running_list, list) { + list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { dbg("<== exec seq %llu came back", msg->seqnum); run_queue_delete(msg); diff --git a/udevd.h b/udevd.h index ae1d20e5ec..64e1d6ad12 100644 --- a/udevd.h +++ b/udevd.h @@ -52,7 +52,7 @@ struct udevsend_msg { }; struct hotplug_msg { - struct list_head list; + struct list_head node; pid_t pid; long queue_time; char *action; diff --git a/udevinfo.c b/udevinfo.c index a4c17da3f0..e7417697cf 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -293,7 +293,7 @@ static int process_options(int argc, char *argv[]) memset(&udev, 0x00, sizeof(struct udevice)); strfieldcpy(udev.name, pos); - retval = udev_db_get_device_byname(&udev, pos); + retval = udev_db_get_device_by_name(&udev, pos); if (retval != 0) { printf("device not found in database\n"); goto exit; From 9fe1a96d88b304af5f3315197800f6b3d16675e1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 25 Feb 2005 07:40:14 +0100 Subject: [PATCH 1178/4284] [PATCH] udevinfo: print devpath -> node relationship for all devices --- udev_db.c | 35 +++++++++++++++++++++++++++++++++++ udev_db.h | 1 + udevinfo.8 | 4 ++++ udevinfo.c | 14 ++++++++++++-- 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/udev_db.c b/udev_db.c index 61d4b130d3..4515998fcd 100644 --- a/udev_db.c +++ b/udev_db.c @@ -239,3 +239,38 @@ found: return 0; } + +int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)) +{ + struct dirent *ent; + DIR *dir; + char filename[NAME_SIZE]; + struct udevice db_udev; + + dir = opendir(udev_db_path); + if (dir == NULL) { + dbg("unable to udev db '%s'", udev_db_path); + return -1; + } + + while (1) { + ent = readdir(dir); + if (ent == NULL || ent->d_name[0] == '\0') + break; + + if (ent->d_name[0] == '.') + continue; + + snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name); + filename[NAME_SIZE-1] = '\0'; + + memset(&db_udev, 0x00, sizeof(struct udevice)); + if (parse_db_file(&db_udev, filename) == 0) { + if (handler_function(&db_udev) != 0) + break; + } + } + + closedir(dir); + return 0; +} diff --git a/udev_db.h b/udev_db.h index 5065eaa6c6..6a0647f200 100644 --- a/udev_db.h +++ b/udev_db.h @@ -30,5 +30,6 @@ extern int udev_db_delete_device(struct udevice *dev); extern int udev_db_get_device_by_devpath(struct udevice *dev, const char *devpath); extern int udev_db_get_device_by_name(struct udevice *udev, const char *name); +extern int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)); #endif /* _UDEV_DB_H_ */ diff --git a/udevinfo.8 b/udevinfo.8 index 963b69aed2..ac8cc7fda5 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -47,6 +47,10 @@ attributes along the device chain. Useful for finding unique attributes to compose a rule. .RB Needs " \-p " specified. .TP +.B \-d +Print the relationship between the devpath and the node name for all devices +currently available in the database. +.TP .B \-h Print help text. .SH "FILES" diff --git a/udevinfo.c b/udevinfo.c index e7417697cf..045395256d 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -178,9 +178,14 @@ exit: return retval; } +static int print_dump(struct udevice *udev) { + printf("%s:%s/%s\n", udev->devpath, udev_root, udev->name); + return 0; +} + static int process_options(int argc, char *argv[]) { - static const char short_options[] = "an:p:q:rVh"; + static const char short_options[] = "adn:p:q:rVh"; int option; int retval = 1; struct udevice udev; @@ -245,6 +250,10 @@ static int process_options(int argc, char *argv[]) attributes = 1; break; + case 'd': + udev_db_call_foreach(print_dump); + exit(0); + case 'V': printf("udevinfo, version %s\n", UDEV_VERSION); exit(0); @@ -384,7 +393,8 @@ help: "\n" " -r print udev root\n" " -a print all SYSFS_attributes along the device chain\n" - " -s print all sysfs devices with major/minor, physical device and bus\n" + " -d print the relationship of devpath and the node name for all\n" + " devices available in the database\n" " -V print udev version\n" " -h print this help text\n" "\n"); From 9c020c60165997be842948d11f51ce6dd6b9b745 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 26 Feb 2005 01:08:44 +0100 Subject: [PATCH 1179/4284] [PATCH] wait_for_sysfs: add joydev --- udev_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 94c0164dec..8813bd5c47 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -172,6 +172,7 @@ static int class_device_expect_no_device_link(struct sysfs_class_device *class_d { .subsystem = "input", .device = "mice" }, { .subsystem = "input", .device = "mouse" }, { .subsystem = "input", .device = "ts" }, + { .subsystem = "input", .device = "js" }, { .subsystem = "vc", .device = NULL }, { .subsystem = "tty", .device = NULL }, { .subsystem = "cpuid", .device = "cpu" }, From 77313cd0d13ed3682f25c745f71f648292b28215 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 26 Feb 2005 02:52:04 +0100 Subject: [PATCH 1180/4284] [PATCH] namedev: skip backslashes only if followed by newline Fix from: Hannes Reinecke namedev_parse is a bit overzealous when in comes to handling backspaces; it always eats up backspaces regardless of anything beyond that. This means it is impossible to enter '\t' in a rule. Quite a bit of fun when you're trying to write regexps. --- namedev_parse.c | 2 +- test/udev-test.pl | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/namedev_parse.c b/namedev_parse.c index 7cd676c390..02d8a6520c 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -153,7 +153,7 @@ static int namedev_parse(const char *filename, void *data) /* skip backslash and newline from multi line rules */ for (i = j = 0; i < count; i++) { - if (bufline[i] == '\\' || bufline[i] == '\n') + if (bufline[i] == '\\' && bufline[i+1] == '\n') continue; line[j++] = bufline[i]; diff --git a/test/udev-test.pl b/test/udev-test.pl index fe7b932669..f442b162ec 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -192,6 +192,15 @@ EOF KERNEL="ttyUSB0", \\ NAME="visor" +EOF + }, + { + desc => "preserve backslashes, if they are not for a newline", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "aaa", + conf => < Date: Fri, 25 Feb 2005 23:51:17 -0800 Subject: [PATCH 1181/4284] [PATCH] update scsi_id to work with libsysfs changes Update scsi_id to work with the libsysfs changes in udev: use sysfs_get_classdev_attr and sysfs_get_device_attr in place of sysfs_read_attribute_value. --- extras/scsi_id/Makefile | 2 +- extras/scsi_id/scsi_id.c | 51 +++++++++++++++--------------------- extras/scsi_id/scsi_id.h | 2 -- extras/scsi_id/scsi_serial.c | 21 ++++++++------- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index e832102e30..7aa3e83470 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -14,7 +14,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.8 +SCSI_ID_VERSION=0.9 prefix = etcdir = ${prefix}/etc diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 507fa27766..32a96d8adb 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -100,23 +100,13 @@ void log_message (int level, const char *format, ...) return; } -int sysfs_get_attr(const char *devpath, const char *attr, char *value, - size_t bufsize) +static int get_major_minor(struct sysfs_class_device *class_dev, int *maj, + int *min) { - char attr_path[SYSFS_PATH_MAX]; + struct sysfs_attribute *dev_attr; - strncpy(attr_path, devpath, SYSFS_PATH_MAX); - strncat(attr_path, "/", SYSFS_PATH_MAX); - strncat(attr_path, attr, SYSFS_PATH_MAX); - dprintf("%s\n", attr_path); - return sysfs_read_attribute_value(attr_path, value, SYSFS_NAME_LEN); -} - -static int get_major_minor(const char *devpath, int *maj, int *min) -{ - char dev_value[MAX_ATTR_LEN]; - - if (sysfs_get_attr(devpath, "dev", dev_value, MAX_ATTR_LEN)) { + dev_attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (!dev_attr) { /* * XXX This happens a lot, since sg has no dev attr. * And now sysfsutils does not set a meaningful errno @@ -125,27 +115,28 @@ static int get_major_minor(const char *devpath, int *maj, int *min) * it separately. */ log_message(LOG_DEBUG, "%s: could not get dev attribute: %s\n", - devpath, strerror(errno)); + class_dev->name, strerror(errno)); return -1; } - dprintf("dev value %s", dev_value); /* dev_value has a trailing \n */ - if (sscanf(dev_value, "%u:%u", maj, min) != 2) { + dprintf("dev value %s", dev_attr->value); /* value has a trailing \n */ + if (sscanf(dev_attr->value, "%u:%u", maj, min) != 2) { log_message(LOG_WARNING, "%s: invalid dev major/minor\n", - devpath); + class_dev->name); return -1; } return 0; } -static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) +static int create_tmp_dev(struct sysfs_class_device *class_dev, char *tmpdev, + int dev_type) { int maj, min; - dprintf("(%s)\n", devpath); + dprintf("(%s)\n", class_dev->name); - if (get_major_minor(devpath, &maj, &min)) + if (get_major_minor(class_dev, &maj, &min)) return -1; snprintf(tmpdev, MAX_NAME_LEN, "%s/%s-maj%d-min%d-%u", TMP_DIR, TMP_PREFIX, maj, min, getpid()); @@ -500,8 +491,7 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, int retval; int newargc; char **newargv = NULL; - char vendor[MAX_ATTR_LEN]; - char model[MAX_ATTR_LEN]; + struct sysfs_attribute *vendor, *model; int option; *good_bad = all_good; @@ -511,19 +501,22 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, else callout[0] = '\0'; - if (sysfs_get_attr(scsi_dev->path, "vendor", vendor, MAX_ATTR_LEN)) { + vendor = sysfs_get_device_attr(scsi_dev, "vendor"); + if (!vendor) { log_message(LOG_WARNING, "%s: cannot get vendor attribute\n", scsi_dev->name); return -1; } - if (sysfs_get_attr(scsi_dev->path, "model", model, MAX_ATTR_LEN)) { + model = sysfs_get_device_attr(scsi_dev, "model"); + if (!model) { log_message(LOG_WARNING, "%s: cannot get model attribute\n", scsi_dev->name); return -1; } - retval = get_file_options(vendor, model, &newargc, &newargv); + retval = get_file_options(vendor->value, model->value, &newargc, + &newargv); optind = 1; /* reset this global extern */ while (retval == 0) { @@ -694,10 +687,8 @@ static int scsi_id(const char *target_path, char *maj_min_dev) /* * mknod a temp dev to communicate with the device. - * - * XXX pass down class_dev or class_dev_parent. */ - if (!dev_specified && create_tmp_dev(target_path, maj_min_dev, + if (!dev_specified && create_tmp_dev(class_dev, maj_min_dev, dev_type)) { dprintf("create_tmp_dev failed\n"); return 1; diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 0ca7cd4206..74b449e984 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -44,8 +44,6 @@ */ #define MAX_BUFFER_LEN 256 -extern int sysfs_get_attr(const char *devpath, const char *attr, char *value, - size_t bufsize); extern int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, int page_code, char *serial, int len); diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 8b9fbe0681..20a7928553 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -364,7 +364,7 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, char *buffer, int len) { int retval; - char vendor[MAX_ATTR_LEN]; + struct sysfs_attribute *vendor; memset(buffer, 0, len); retval = scsi_inquiry(scsi_dev, fd, 1, 0x0, buffer, len); @@ -394,14 +394,15 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, * If the vendor id appears in the page assume the page is * invalid. */ - if (sysfs_get_attr(scsi_dev->path, "vendor", vendor, - MAX_ATTR_LEN)) { + vendor = sysfs_get_device_attr(scsi_dev, "vendor"); + if (!vendor) { log_message(LOG_WARNING, "%s: cannot get model attribute\n", scsi_dev->name); return 1; } - if (!strncmp(&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) { + if (!strncmp(&buffer[VENDOR_LENGTH], vendor->value, + VENDOR_LENGTH)) { log_message(LOG_WARNING, "%s: invalid page0 data\n", scsi_dev->name); return 1; @@ -416,15 +417,16 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, */ static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial) { - char attr[MAX_ATTR_LEN]; + struct sysfs_attribute *attr; int ind; - if (sysfs_get_attr(scsi_dev->path, "vendor", attr, MAX_ATTR_LEN)) { + attr = sysfs_get_device_attr(scsi_dev, "vendor"); + if (!attr) { log_message(LOG_WARNING, "%s: cannot get vendor attribute\n", scsi_dev->name); return 1; } - strncpy(serial, attr, VENDOR_LENGTH); + strncpy(serial, attr->value, VENDOR_LENGTH); ind = strlen(serial) - 1; /* * Remove sysfs added newlines. @@ -432,12 +434,13 @@ static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial) if (serial[ind] == '\n') serial[ind] = '\0'; - if (sysfs_get_attr(scsi_dev->path, "model", attr, MAX_ATTR_LEN)) { + attr = sysfs_get_device_attr(scsi_dev, "model"); + if (!attr) { log_message(LOG_WARNING, "%s: cannot get model attribute\n", scsi_dev->name); return 1; } - strncat(serial, attr, MODEL_LENGTH); + strncat(serial, attr->value, MODEL_LENGTH); ind = strlen(serial) - 1; if (serial[ind] == '\n') serial[ind] = '\0'; From 6d7a6d08c2386611e4ccb62ce660ceb53b1bf79f Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Sat, 26 Feb 2005 03:14:42 -0800 Subject: [PATCH 1182/4284] [PATCH] 054 release --- ChangeLog | 32 ++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68fc6ff2e6..472df80dbc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +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 ============================================ diff --git a/Makefile b/Makefile index c2d35f7734..99a7618795 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 053 +VERSION = 054 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index f9dc8f3004..32aca6196f 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 053 +Version: 054 Release: 1 License: GPL Group: Utilities/System From e5f053b5312a0f8d62a2bcff8ddb095052d228bc Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Mar 2005 04:26:44 +0100 Subject: [PATCH 1183/4284] [PATCH] klibc: update v0.205 --- klibc/MCONFIG | 24 +- klibc/Makefile | 54 +- klibc/include/arch/x86_64/klibc/archsignal.h | 6 +- klibc/include/bits32/bitsize.h | 3 + klibc/include/bits64/bitsize.h | 3 + klibc/include/signal.h | 11 + klibc/include/sys/select.h | 1 + klibc/include/sys/vfs.h | 7 +- klibc/klcc.1 | 81 + klibc/klcc.in | 207 +++ klibc/klibc.spec | 139 +- klibc/klibc.spec.in | 137 +- klibc/klibc/MCONFIG | 2 + klibc/klibc/Makefile | 21 +- klibc/klibc/SYSCALLS.def | 4 +- klibc/klibc/arch/i386/MCONFIG | 4 +- klibc/klibc/include/sys/times.h | 14 - klibc/klibc/llseek.c | 3 +- klibc/klibc/mmap.c | 14 +- klibc/klibc/tests/rtsig.c | 12 + klibc/klibc/zlib/FAQ | 315 ++++ klibc/klibc/zlib/INDEX | 48 + klibc/klibc/zlib/README | 126 ++ klibc/klibc/zlib/adler32.c | 74 + klibc/klibc/zlib/algorithm.txt | 209 +++ klibc/klibc/zlib/compress.c | 79 + klibc/klibc/zlib/crc32.c | 311 ++++ klibc/klibc/zlib/crc32.h | 441 +++++ klibc/klibc/zlib/deflate.c | 1502 ++++++++++++++++++ klibc/klibc/zlib/deflate.h | 326 ++++ klibc/klibc/zlib/gzio.c | 1008 ++++++++++++ klibc/klibc/zlib/infback.c | 619 ++++++++ klibc/klibc/zlib/inffast.c | 305 ++++ klibc/klibc/zlib/inffast.h | 11 + klibc/klibc/zlib/inffixed.h | 94 ++ klibc/klibc/zlib/inflate.c | 1270 +++++++++++++++ klibc/klibc/zlib/inflate.h | 117 ++ klibc/klibc/zlib/inftrees.c | 321 ++++ klibc/klibc/zlib/inftrees.h | 55 + klibc/klibc/zlib/trees.c | 1215 ++++++++++++++ klibc/klibc/zlib/trees.h | 128 ++ klibc/klibc/zlib/uncompr.c | 61 + klibc/klibc/zlib/zconf.h | 323 ++++ klibc/klibc/zlib/zconf.in.h | 323 ++++ klibc/klibc/zlib/zlib.3 | 159 ++ klibc/klibc/zlib/zlib.h | 1200 ++++++++++++++ klibc/klibc/zlib/zutil.c | 319 ++++ klibc/klibc/zlib/zutil.h | 258 +++ klibc/makeklcc.pl | 36 + klibc/version | 2 +- 50 files changed, 11769 insertions(+), 233 deletions(-) create mode 100644 klibc/include/bits32/bitsize.h create mode 100644 klibc/include/bits64/bitsize.h create mode 100644 klibc/klcc.1 create mode 100644 klibc/klcc.in delete mode 100644 klibc/klibc/include/sys/times.h create mode 100644 klibc/klibc/tests/rtsig.c create mode 100644 klibc/klibc/zlib/FAQ create mode 100644 klibc/klibc/zlib/INDEX create mode 100644 klibc/klibc/zlib/README create mode 100644 klibc/klibc/zlib/adler32.c create mode 100644 klibc/klibc/zlib/algorithm.txt create mode 100644 klibc/klibc/zlib/compress.c create mode 100644 klibc/klibc/zlib/crc32.c create mode 100644 klibc/klibc/zlib/crc32.h create mode 100644 klibc/klibc/zlib/deflate.c create mode 100644 klibc/klibc/zlib/deflate.h create mode 100644 klibc/klibc/zlib/gzio.c create mode 100644 klibc/klibc/zlib/infback.c create mode 100644 klibc/klibc/zlib/inffast.c create mode 100644 klibc/klibc/zlib/inffast.h create mode 100644 klibc/klibc/zlib/inffixed.h create mode 100644 klibc/klibc/zlib/inflate.c create mode 100644 klibc/klibc/zlib/inflate.h create mode 100644 klibc/klibc/zlib/inftrees.c create mode 100644 klibc/klibc/zlib/inftrees.h create mode 100644 klibc/klibc/zlib/trees.c create mode 100644 klibc/klibc/zlib/trees.h create mode 100644 klibc/klibc/zlib/uncompr.c create mode 100644 klibc/klibc/zlib/zconf.h create mode 100644 klibc/klibc/zlib/zconf.in.h create mode 100644 klibc/klibc/zlib/zlib.3 create mode 100644 klibc/klibc/zlib/zlib.h create mode 100644 klibc/klibc/zlib/zutil.c create mode 100644 klibc/klibc/zlib/zutil.h create mode 100644 klibc/makeklcc.pl diff --git a/klibc/MCONFIG b/klibc/MCONFIG index 3fae2898c6..a7b2cb1bf3 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -3,6 +3,17 @@ # Makefile configuration, without explicit rules # +# Location for installation +prefix = /usr +bindir = $(prefix)/bin +libdir = $(prefix)/lib +mandir = $(prefix)/man +INSTALLDIR = $(prefix)/lib/klibc +INSTALLROOT = + +INSTALL_EXEC = install -m 755 +INSTALL_DATA = install -m 644 + # Eventually support separate compilation, but we don't have it yet... OBJROOT = $(SRCROOT) @@ -20,17 +31,19 @@ INCLUDE = -I$(SRCROOT)/include/arch/$(ARCH) \ -I$(SRCROOT)/include/bits$(BITSIZE) \ -I$(SRCROOT)/include \ -I$(KRNLOBJ)/include -I$(KRNLOBJ)/include2 -I$(KRNLSRC)/include -REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include \ - -D__KLIBC__ -DBITSIZE=$(BITSIZE) \ - $(INCLUDE) +REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include -D__KLIBC__ \ + $(INCLUDE) LDFLAGS = AR = $(CROSS)ar RANLIB = $(CROSS)ranlib NM = $(CROSS)nm PERL = perl -STRIP = $(CROSS)strip --strip-all -R .comment -R .note OBJCOPY = $(CROSS)objcopy +STRIP = $(CROSS)strip +STRIPFLAGS = --strip-all -R .comment -R .note +STRIPCMD = $(STRIP) $(STRIPFLAGS) + HOST_CC = gcc HOST_CFLAGS = -g -O HOST_LDFLAGS = @@ -57,6 +70,9 @@ SHLIBDIR = /lib # about 4K bigger. ERRLIST = 1 +# Include zlib in klibc. This roughly triples the size of klibc! +ZLIB = 0 + # # Include arch-specific rule fragments # diff --git a/klibc/Makefile b/klibc/Makefile index 2506417ef5..eb8f55570d 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -1,5 +1,6 @@ VERSION := $(shell cat version) SUBDIRS = klibc ash ipconfig nfsmount utils kinit gzip +SRCROOT = . all: @@ -12,12 +13,55 @@ klibc.spec: klibc.spec.in version rpm: klibc.spec +$(rpmbuild) -bb klibc.spec --target=$(ARCH) -%: +$(CROSS)klibc.config: Makefile + rm -f $@ + echo 'ARCH=$(ARCH)' >> $@ + echo 'CROSS=$(CROSS)' >> $@ + echo "CC=$(shell bash -c 'type -p $(CC)')" >> $@ + echo "LD=$(shell bash -c 'type -p $(LD)')" >> $@ + echo 'REQFLAGS=$(filter-out -I%,$(REQFLAGS))' >> $@ + echo 'OPTFLAGS=$(OPTFLAGS)' >> $@ + echo 'LDFLAGS=$(LDFLAGS)' >> $@ + echo "STRIP=$(shell bash -c 'type -p $(STRIP)')" >> $@ + echo 'STRIPFLAGS=$(STRIPFLAGS)' >> $@ + echo 'EMAIN=$(EMAIN)' >> $@ + echo 'BITSIZE=$(BITSIZE)' >> $@ + echo 'INSTALLDIR=$(INSTALLDIR)' >> $@ + +$(CROSS)klcc: klcc.in $(CROSS)klibc.config makeklcc.pl + $(PERL) makeklcc.pl klcc.in $(CROSS)klibc.config \ + $(shell bash -c 'type -p $(PERL)') > $@ || ( rm -f $@ ; exit 1 ) + chmod a+x $@ + +%: local-% @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done -clean: - @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done +local-all: $(CROSS)klcc -spotless: - @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done +local-clean: + rm -f klibc.config klcc + +local-spotless: rm -f klibc.spec *~ tags + +local-install: $(CROSS)klcc + mkdir -p $(INSTALLROOT)$(bindir) + mkdir -p $(INSTALLROOT)$(mandir)/man1 + mkdir -p $(INSTALLROOT)$(SHLIBDIR) + mkdir -p $(INSTALLROOT)$(INSTALLDIR) + -rm -rf $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)lib + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)bin + set -xe ; for d in linux asm asm-generic ; do \ + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d ; \ + cp -rfL $(KRNLSRC)/include/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d/. ; \ + cp -rfL $(KRNLOBJ)/include/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d/. ; \ + [ ! -d $(KRNLOBJ)/include2/$$d ] || \ + cp -rfL $(KRNLOBJ)/include2/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d/. ; \ + done + cp -rf include/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/. + $(INSTALL_DATA) klcc.1 $(INSTALLROOT)$(mandir)/man1/$(CROSS)klcc.1 + $(INSTALL_EXEC) $(CROSS)klcc $(INSTALLROOT)$(bindir) + +-include MCONFIG diff --git a/klibc/include/arch/x86_64/klibc/archsignal.h b/klibc/include/arch/x86_64/klibc/archsignal.h index 74e82e1dd0..527241454e 100644 --- a/klibc/include/arch/x86_64/klibc/archsignal.h +++ b/klibc/include/arch/x86_64/klibc/archsignal.h @@ -8,6 +8,10 @@ #ifndef _KLIBC_ARCHSIGNAL_H #define _KLIBC_ARCHSIGNAL_H -/* No special stuff for this architecture */ +/* The x86-64 headers defines NSIG 32, but it's actually 64 */ +#undef _NSIG +#undef NSIG +#define _NSIG 64 +#define NSIG _NSIG #endif diff --git a/klibc/include/bits32/bitsize.h b/klibc/include/bits32/bitsize.h new file mode 100644 index 0000000000..06cc885983 --- /dev/null +++ b/klibc/include/bits32/bitsize.h @@ -0,0 +1,3 @@ +#ifndef _BITSIZE +#define _BITSIZE 32 +#endif diff --git a/klibc/include/bits64/bitsize.h b/klibc/include/bits64/bitsize.h new file mode 100644 index 0000000000..54696fd70e --- /dev/null +++ b/klibc/include/bits64/bitsize.h @@ -0,0 +1,3 @@ +#ifndef _BITSIZE +#define _BITSIZE 64 +#endif diff --git a/klibc/include/signal.h b/klibc/include/signal.h index 1b439077f2..e78318f5f7 100644 --- a/klibc/include/signal.h +++ b/klibc/include/signal.h @@ -27,9 +27,20 @@ typedef int sig_atomic_t; #ifndef SA_NODEFER # define SA_NODEFER SA_NOMASK #endif +/* Some architectures define NSIG and not _NSIG or vice versa */ #ifndef NSIG # define NSIG _NSIG #endif +#ifndef _NSIG +# define _NSIG NSIG +#endif + +/* If we don't have any real-time signals available to userspace, + hide them all */ +#if SIGRTMAX <= SIGRTMIN +# undef SIGRTMIN +# undef SIGRTMAX +#endif __extern const char * const sys_siglist[]; diff --git a/klibc/include/sys/select.h b/klibc/include/sys/select.h index 7caf8c931b..361a1a53b0 100644 --- a/klibc/include/sys/select.h +++ b/klibc/include/sys/select.h @@ -5,6 +5,7 @@ #ifndef _SYS_SELECT_H #define _SYS_SELECT_H +#include #include #include diff --git a/klibc/include/sys/vfs.h b/klibc/include/sys/vfs.h index b60d1a572f..cf5aaf9107 100644 --- a/klibc/include/sys/vfs.h +++ b/klibc/include/sys/vfs.h @@ -8,11 +8,12 @@ #include #include #include +#include /* struct statfs64 -- there seems to be two standards - one for 32 and one for 64 bits, and they're incompatible... */ -#if BITSIZE == 32 || defined(__s390__) +#if _BITSIZE == 32 || defined(__s390__) struct statfs { uint32_t f_type; @@ -28,7 +29,7 @@ struct statfs { uint32_t f_spare[5]; }; -#else /* BITSIZE == 64 */ +#else /* _BITSIZE == 64 */ struct statfs { uint64_t f_type; @@ -44,7 +45,7 @@ struct statfs { uint64_t f_spare[5]; }; -#endif /* BITSIZE */ +#endif /* _BITSIZE */ __extern int statfs(const char *, struct statfs *); __extern int fstatfs(int, struct statfs *); diff --git a/klibc/klcc.1 b/klibc/klcc.1 new file mode 100644 index 0000000000..a6f979c6c4 --- /dev/null +++ b/klibc/klcc.1 @@ -0,0 +1,81 @@ +.\" $Id: klcc.1,v 1.2 2005/03/02 02:24:17 hpa Exp $ +.\" ----------------------------------------------------------------------- +.\" +.\" Copyright 2005 H. Peter Anvin - All Rights Reserved +.\" +.\" Permission is hereby granted, free of charge, to any person +.\" obtaining a copy of this software and associated documentation +.\" files (the "Software"), to deal in the Software without +.\" restriction, including without limitation the rights to use, +.\" copy, modify, merge, publish, distribute, sublicense, and/or +.\" sell copies of the Software, and to permit persons to whom +.\" the Software is furnished to do so, subject to the following +.\" conditions: +.\" +.\" The above copyright notice and this permission notice shall +.\" be included in all copies or substantial portions of the Software. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +.\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +.\" OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +.\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +.\" HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +.\" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +.\" OTHER DEALINGS IN THE SOFTWARE. +.\" +.\" ----------------------------------------------------------------------- + +.TH klcc "1" "1 March 2005" "klibc" "H. Peter Anvin" +.SH NAME +klcc \- compile a program against klibc +.SH SYNOPSIS +.B klcc +[\fIgcc options\fP] +[\fB\-o\fP \fIoutfile\fP] +\fIinfile...\fP +.SH DESCRIPTION +.PP +.B klcc +is a wrapper around +.BR gcc (1) +to compile a program against the +.B klibc +tiny C library. It supports most +.B gcc +options. +.PP +Unlike +.BR gcc , +.B klcc +compiles with optimization on by default. Furthermore, the +optimization level used depends on whether or not +.B \-g +is specified, since +.B klcc +frequently uses options in the normal case which makes debugging +impossible. Therefore, compile without +.BR \-g , +.BR \-O , +.B \-f +or +.B \-m +option to use the default optimization level; this will generally +result in the smallest binaries. You may want to use +.B \-s +when linking, however. +.PP +Use the +.B \-shared +or +.B \-static +option to compile for and link against shared or static klibc. Note +that shared klibc only supports running against the exact same klibc +binary as the binary was linked with. +.SH AUTHOR +Written by H. Peter Anvin . +.SH COPYRIGHT +Copyright \(co 2005 H. Peter Anvin. +.SH "SEE ALSO" +.BR gcc (1) + diff --git a/klibc/klcc.in b/klibc/klcc.in new file mode 100644 index 0000000000..713843c37c --- /dev/null +++ b/klibc/klcc.in @@ -0,0 +1,207 @@ +# -*- perl -*- + +# Standard includes +@includes = ("-I${INSTALLDIR}/${CROSS}include/arch/${ARCH}", + "-I${INSTALLDIR}/${CROSS}include/bits${BITSIZE}", + "-I${INSTALLDIR}/${CROSS}include"); + +# Default optimization options (for compiles without -g) +@optopt = @OPTFLAGS; +@goptopt = ('-O'); + +# Options and libraries to pass to ld; shared versus static +@staticopt = ("$INSTALLDIR/${CROSS}lib/crt0.o"); +@staticlib = ("$INSTALLDIR/${CROSS}lib/libc.a"); +@sharedopt = (@EMAIN, "$INSTALLDIR/${CROSS}lib/interp.o"); +@sharedlib = ('-R', "$INSTALLDIR/lib/${CROSS}libc.so"); + +# Returns the language (-x option string) for a specific extension. +sub filename2lang($) { + my ($file) = @_; + + return 'c' if ( $file =~ /\.c$/ ); + return 'c-header' if ( $file =~ /\.h$/ ); + return 'cpp-output' if ( $file =~ /\.i$/ ); + return 'c++-cpp-output' if ( $file =~ /\.ii$/ ); + return 'objective-c' if ( $file =~ /\.m$/ ); + return 'objc-cpp-output' if ( $file =~ /\.mi$/ ); + return 'c++' if ( $file =~/\.(cc|cp|cxx|cpp|CPP|c\+\+|C)$/ ); + return 'c++-header' if ( $file =~ /\.(hh|H)$/ ); + return 'f77' if ( $file =~ /\.(f|for|FOR)$/ ); + return 'f77-cpp-input' if ( $file =~ /\.(F|fpp|FPP)$/ ); + return 'ratfor' if ( $file =~ /\.r$/ ); + + # Is this correct? + return 'ada' if ( $file =~ /\.(ads|adb)$/ ); + + return 'assembler' if ( $file =~ /\.s$/ ); + return 'assembler-with-cpp' if ( $file =~/ \.S$/ ); + + # Linker file; there is no option to gcc to assume something + # is a linker file, so we make up our own... + return 'obj'; +} + +# Produces a series of -x options and files +sub files_with_lang($$) { + my($files, $flang) = @_; + my(@as) = (); + my($xopt) = 'none'; + my($need); + + foreach $f ( @{$files} ) { + $need = ${$flang}{$f}; + $need = 'none' if ( $need eq 'obj' ); + unless ( $xopt eq $need || + ($xopt eq 'none' && filename2lang($f) eq $need) ) { + push(@as, '-x', $need); + $xopt = $need; + } + push(@as, $f); + } + + return @as; +} + +# Convert a return value from system() to an exit() code +sub syserr($) { + my($e) = @_; + + return ($e & 0x7f) | 0x80 if ( $e & 0xff ); + return $e >> 8; +} + +# Run a program; printing out the command line if $verbose is set +sub mysystem(@) { + print STDERR join(' ', @_), "\n" if ( $verbose ); + return system(@_); +} + +# +# Begin parsing options. +# + +@ccopt = (); +@ldopt = (); + +@files = (); # List of files +%flang = (); # Languages for files + +# This is 'c' for compile only, 'E' for preprocess only, +# 'S' for compile to assembly. +$operation = ''; # Compile and link + +# Current -x option. If undefined, it means autodetect. +undef $lang; + +$save_temps = 0; # The -save-temps option +$verbose = 0; # The -v option +$shared = 0; # Are we compiling shared? +$debugging = 0; # -g or -p option present? +$strip = 0; # -s option present? +undef $output; # -o option present? + +while ( defined($a = shift(@ARGV)) ) { + if ( $a !~ /^\-/ ) { + # Not an option. Must be a filename then. + push(@files, $a); + $flang{$a} = $lang || filename2lang($a); + } elsif ( $a =~ /^-Wl,(.*)$/ ) { + # -Wl used to pass options to the linker + push(@ldopt, split(/,/, $1)); + } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic)/ ) { + # Options to gcc + push(@ccopt, $a); + } elsif ( $a =~ /^-([DUI])(.*)$/ ) { + # Options to gcc, which can take either a conjoined argument + # (-DFOO) or a disjoint argument (-D FOO) + push(@ccopt, $a); + push(@ccopt, shift(@ARGV)) if ( $2 eq '' ); + } elsif ( $a eq '-include' ) { + # Options to gcc which always take a disjoint argument + push(@ccopt, $a, shift(@ARGV)); + } elsif ( $a =~ /^-[gp]/ ) { + # Debugging options to gcc *and* ld + push(@ccopt, $a); + push(@ldopt, $a); + $debugging = 1; + } elsif ( $a eq '-v' ) { + push(@ccopt, $a); + $verbose = 1; + } elsif ( $a eq '-save-temps' ) { + push(@ccopt, $a); + $save_temps = 1; + } elsif ( $a =~ '^-([cSE])$' ) { + push(@ccopt, $a); + $operation = $1; + } elsif ( $a eq '-shared' ) { + $shared = 1; + } elsif ( $a eq '-static' ) { + $shared = 0; + } elsif ( $a eq '-s' ) { + $strip = 1; + } elsif ( $a eq '-o' ) { + $output = shift(@ARGV); + } elsif ( $a eq '-nostdinc' ) { + push(@ccopt, $a); + @includes = (); + } elsif ( $a =~ /^(-print|--help)/ ) { + # Pseudo-operations; just pass to gcc and don't do anything else + push(@ccopt, $a); + $operation = 'c' if ( $operation eq '' ); + } else { + die "$0: unknown option: $a\n"; + } +} + +if ( $debugging ) { + @ccopt = (@REQFLAGS, @includes, @goptopt, @ccopt); +} else { + @ccopt = (@REQFLAGS, @includes, @optopt, @ccopt); +} + +if ( $operation ne '' ) { + # Just run gcc with the appropriate options + @outopt = ('-o', $output) if ( defined($output) ); + $rv = mysystem($CC, @ccopt, @outopt, files_with_lang(\@files, \%flang)); +} else { + @outopt = ('-o', $output || 'a.out'); + + @objs = (); + @rmobjs = (); + + foreach $f ( @files ) { + if ( $flang{$f} eq 'obj' ) { + push(@objs, $f); + } else { + $fo = $f; + $fo =~ s/\.[^\/.]+$/\.o/; + + die if ( $f eq $fo ); # safety check + + push(@objs, $fo); + push(@rmobjs, $fo) unless ( $save_temps ); + + $rv = mysystem($CC, @ccopt, '-c', '-o', $fo, '-x', $flang{$f}, $f); + + if ( $rv ) { + unlink(@rmobjs); + exit syserr($rv); + } + } + } + + if ( $shared ) { + $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @sharedlib); + } else { + $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @staticlib); + } + + unlink(@rmobjs); + + if ( $strip && !$rv ) { + $rv = mysystem($STRIP, @STRIPFLAGS, $output); + } +} + +exit syserr($rv); diff --git a/klibc/klibc.spec b/klibc/klibc.spec index de0a14cf63..65b0bf5439 100644 --- a/klibc/klibc.spec +++ b/klibc/klibc.spec @@ -1,50 +1,45 @@ Summary: A minimal libc subset for use with initramfs. Name: klibc -Version: 0.199 +Version: 0.205 Release: 1 License: BSD/GPL Group: Development/Libraries URL: http://www.zytor.com/mailman/listinfo/klibc Source: http://www.kernel.org/pub/linux/libs/klibc-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -BuildRequires: kernel-source >= 2.6.0 +BuildRequires: kernel >= 2.6.0 Packager: H. Peter Anvin Prefix: /usr Vendor: Starving Linux Artists +%define klibcdir %{_prefix}/lib/klibc +%define libdocdir %{_docdir}/%{name}-%{version}-%{release} +%define bindocdir %{_docdir}/%{name}-utils-%{version}-%{release} + %description %{name} is intended to be a minimalistic libc subset for use with initramfs. It is deliberately written for small size, minimal entanglement, and portability, not speed. It is definitely a work in progress, and a lot of things are still missing. -%package kernheaders -Summary: Kernel headers used during the build of klibc. -Group: Development/Libraries - -%description kernheaders -This package contains the set of kernel headers that were required to -build %{name} and the utilities that ship with it. This may or may -not be a complete enough set to build other programs that link against -%{name}. If in doubt, use real kernel headers instead. - %package utils -Summary: Small statically-linked utilities built with klibc. +Summary: Small utilities built with klibc. Group: Utilities/System +Requires: klibc = %{version} %description utils - -This package contains a collection of programs that are statically -linked against klibc. These duplicate some of the functionality of a -regular Linux toolset, but are typically much smaller than their -full-function counterparts. They are intended for inclusion in -initramfs images and embedded systems. +This package contains a collection of programs that are linked against +klibc. These duplicate some of the functionality of a regular Linux +toolset, but are typically much smaller than their full-function +counterparts. They are intended for inclusion in initramfs images and +embedded systems. %prep %setup -q -cp -as /usr/src/linux-`rpm -q kernel-source | tail -1 | cut -d- -f3-` ./linux -make -C linux defconfig ARCH=%{_target_cpu} -make -C linux prepare ARCH=%{_target_cpu} +cp -dRs /lib/modules/`uname -r`/build ./linux +# Shouldn't need this when getting the build tree from /lib/modules +# make -C linux defconfig ARCH=%{_target_cpu} +# make -C linux prepare ARCH=%{_target_cpu} # Deal with braindamage in RedHat's kernel-source RPM rm -f linux/include/linux/config.h cat < linux/include/linux/config.h @@ -58,98 +53,48 @@ EOF mkdir -p %{buildroot} %build -make ARCH=%{_target_cpu} +make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ + INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} %install rm -rf %{buildroot} +make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ + INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} \ + install -dest=%{buildroot}/%{prefix} -lib=$dest/%{_lib}/klibc -inc=$dest/include/klibc -exe=$dest/libexec/klibc -doc=$dest/share/doc/%{name}-%{version} -udoc=$dest/share/doc/%{name}-utils-%{version} +# Install the docs -# First, the library. +mkdir -p %{buildroot}%{bindocdir} %{buildroot}%{libdocdir} +install -m 444 README %{buildroot}%{libdocdir} +install -m 444 klibc/README %{buildroot}%{libdocdir}/README.klibc +install -m 444 klibc/arch/README %{buildroot}%{libdocdir}/README.klibc.arch -install -dD -m 755 $lib $inc/kernel $exe $doc $udoc -install -m 755 klibc/klibc.so $lib -install -m 644 klibc/libc.a $lib -install -m 644 klibc/crt0.o $lib -install -m 644 klibc/libc.so.hash $lib -ln $lib/klibc.so $lib/libc.so -ln $lib/klibc.so $lib/klibc-$(cat $lib/libc.so.hash).so - -# Next, the generated binaries. -# These are currently static binaries, should we go for shared? - -install -m 755 ash/sh $exe -install -m 755 gzip/gzip $exe -ln $exe/gzip $exe/gunzip -ln $exe/gzip $exe/zcat -install -m 755 ipconfig/ipconfig $exe -install -m 755 kinit/kinit $exe -install -m 755 nfsmount/nfsmount $exe -install -m 755 utils/static/* $exe - -# The docs. - -install -m 444 README $doc -install -m 444 klibc/README $doc/README.klibc -install -m 444 klibc/arch/README $doc/README.klibc.arch - -install -m 444 gzip/COPYING $udoc/COPYING.gzip -install -m 444 gzip/README $udoc/README.gzip -install -m 444 ipconfig/README $udoc/README.ipconfig -install -m 444 kinit/README $udoc/README.kinit - -# Finally, the include files. - -bitsize=$(make --no-print-directory -C klibc bitsize ARCH=%{_target_cpu}) -cp --parents $(find klibc/include \( -name CVS -o -name SCCS \) -prune \ - -o -name '*.h' -print) $inc -mv $inc/klibc $inc/klibc.$$ -mv $inc/klibc.$$/include/* $inc -mv $inc/bits$bitsize/bitsize $inc -rm -rf $inc/klibc.$$ $inc/bits[0-9]* -pushd klibc/arch/%{_arch}/include -cp --parents -f $(find . \( -name CVS -o -name SCCS \) -prune \ - -o -name '*.h' -print) $inc -popd - -# Yeugh. Find the transitive closure over all kernel headers included -# by klibc, and copy them into place. - -find . -name '.*.d' | xargs -r sed -e 's,[ \t][ \t]*,\n,g' | sed -n -e 's,^\.\./linux/include/,,p' | sort | uniq | (cd linux/include && xargs -ri cp --parents '{}' $inc/kernel) +install -m 444 gzip/COPYING %{buildroot}%{bindocdir}/COPYING.gzip +install -m 444 gzip/README %{buildroot}%{bindocdir}/README.gzip +install -m 444 ipconfig/README %{buildroot}%{bindocdir}/README.ipconfig +install -m 444 kinit/README %{buildroot}%{bindocdir}/README.kinit %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) -%docdir %{prefix}/share/doc/%{name}-%{version} -%{prefix}/%{_lib}/klibc -%dir %{prefix}/include/klibc -%{prefix}/include/klibc/*.h -%{prefix}/include/klibc/arpa -%{prefix}/include/klibc/bitsize -%{prefix}/include/klibc/klibc -%{prefix}/include/klibc/net -%{prefix}/include/klibc/netinet -%{prefix}/include/klibc/sys -%{prefix}/share/doc/%{name}-%{version} - -%files kernheaders -%defattr(-,root,root,-) -%{prefix}/include/klibc/kernel +%{klibcdir}/lib +%{klibcdir}/include +%{_bindir}/klcc +/lib/klibc-*.so +%doc %{_mandir}/man1/* +%doc %{libdocdir}/* %files utils %defattr(-,root,root,-) -%{prefix}/libexec/klibc -%docdir %{prefix}/share/doc/%{name}-utils-%{version} -%{prefix}/share/doc/%{name}-utils-%{version} +%{klibcdir}/bin +%doc %{bindocdir}/* %changelog +* Tue Mar 1 2005 H. Peter Anvin +- New "make install" scheme, klcc + * Tue Jul 6 2004 H. Peter Anvin - Update to use kernel-source RPM for the kernel symlink. diff --git a/klibc/klibc.spec.in b/klibc/klibc.spec.in index 8f5b2618d0..237771532a 100644 --- a/klibc/klibc.spec.in +++ b/klibc/klibc.spec.in @@ -7,44 +7,39 @@ Group: Development/Libraries URL: http://www.zytor.com/mailman/listinfo/klibc Source: http://www.kernel.org/pub/linux/libs/klibc-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -BuildRequires: kernel-source >= 2.6.0 +BuildRequires: kernel >= 2.6.0 Packager: H. Peter Anvin Prefix: /usr Vendor: Starving Linux Artists +%define klibcdir %{_prefix}/lib/klibc +%define libdocdir %{_docdir}/%{name}-%{version}-%{release} +%define bindocdir %{_docdir}/%{name}-utils-%{version}-%{release} + %description %{name} is intended to be a minimalistic libc subset for use with initramfs. It is deliberately written for small size, minimal entanglement, and portability, not speed. It is definitely a work in progress, and a lot of things are still missing. -%package kernheaders -Summary: Kernel headers used during the build of klibc. -Group: Development/Libraries - -%description kernheaders -This package contains the set of kernel headers that were required to -build %{name} and the utilities that ship with it. This may or may -not be a complete enough set to build other programs that link against -%{name}. If in doubt, use real kernel headers instead. - %package utils -Summary: Small statically-linked utilities built with klibc. +Summary: Small utilities built with klibc. Group: Utilities/System +Requires: klibc = %{version} %description utils - -This package contains a collection of programs that are statically -linked against klibc. These duplicate some of the functionality of a -regular Linux toolset, but are typically much smaller than their -full-function counterparts. They are intended for inclusion in -initramfs images and embedded systems. +This package contains a collection of programs that are linked against +klibc. These duplicate some of the functionality of a regular Linux +toolset, but are typically much smaller than their full-function +counterparts. They are intended for inclusion in initramfs images and +embedded systems. %prep %setup -q -cp -as /usr/src/linux-`rpm -q kernel-source | tail -1 | cut -d- -f3-` ./linux -make -C linux defconfig ARCH=%{_target_cpu} -make -C linux prepare ARCH=%{_target_cpu} +cp -dRs /lib/modules/`uname -r`/build ./linux +# Shouldn't need this when getting the build tree from /lib/modules +# make -C linux defconfig ARCH=%{_target_cpu} +# make -C linux prepare ARCH=%{_target_cpu} # Deal with braindamage in RedHat's kernel-source RPM rm -f linux/include/linux/config.h cat < linux/include/linux/config.h @@ -58,98 +53,48 @@ EOF mkdir -p %{buildroot} %build -make ARCH=%{_target_cpu} +make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ + INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} %install rm -rf %{buildroot} +make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ + INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} \ + install -dest=%{buildroot}/%{prefix} -lib=$dest/%{_lib}/klibc -inc=$dest/include/klibc -exe=$dest/libexec/klibc -doc=$dest/share/doc/%{name}-%{version} -udoc=$dest/share/doc/%{name}-utils-%{version} +# Install the docs -# First, the library. +mkdir -p %{buildroot}%{bindocdir} %{buildroot}%{libdocdir} +install -m 444 README %{buildroot}%{libdocdir} +install -m 444 klibc/README %{buildroot}%{libdocdir}/README.klibc +install -m 444 klibc/arch/README %{buildroot}%{libdocdir}/README.klibc.arch -install -dD -m 755 $lib $inc/kernel $exe $doc $udoc -install -m 755 klibc/klibc.so $lib -install -m 644 klibc/libc.a $lib -install -m 644 klibc/crt0.o $lib -install -m 644 klibc/libc.so.hash $lib -ln $lib/klibc.so $lib/libc.so -ln $lib/klibc.so $lib/klibc-$(cat $lib/libc.so.hash).so - -# Next, the generated binaries. -# These are currently static binaries, should we go for shared? - -install -m 755 ash/sh $exe -install -m 755 gzip/gzip $exe -ln $exe/gzip $exe/gunzip -ln $exe/gzip $exe/zcat -install -m 755 ipconfig/ipconfig $exe -install -m 755 kinit/kinit $exe -install -m 755 nfsmount/nfsmount $exe -install -m 755 utils/static/* $exe - -# The docs. - -install -m 444 README $doc -install -m 444 klibc/README $doc/README.klibc -install -m 444 klibc/arch/README $doc/README.klibc.arch - -install -m 444 gzip/COPYING $udoc/COPYING.gzip -install -m 444 gzip/README $udoc/README.gzip -install -m 444 ipconfig/README $udoc/README.ipconfig -install -m 444 kinit/README $udoc/README.kinit - -# Finally, the include files. - -bitsize=$(make --no-print-directory -C klibc bitsize ARCH=%{_target_cpu}) -cp --parents $(find klibc/include \( -name CVS -o -name SCCS \) -prune \ - -o -name '*.h' -print) $inc -mv $inc/klibc $inc/klibc.$$ -mv $inc/klibc.$$/include/* $inc -mv $inc/bits$bitsize/bitsize $inc -rm -rf $inc/klibc.$$ $inc/bits[0-9]* -pushd klibc/arch/%{_arch}/include -cp --parents -f $(find . \( -name CVS -o -name SCCS \) -prune \ - -o -name '*.h' -print) $inc -popd - -# Yeugh. Find the transitive closure over all kernel headers included -# by klibc, and copy them into place. - -find . -name '.*.d' | xargs -r sed -e 's,[ \t][ \t]*,\n,g' | sed -n -e 's,^\.\./linux/include/,,p' | sort | uniq | (cd linux/include && xargs -ri cp --parents '{}' $inc/kernel) +install -m 444 gzip/COPYING %{buildroot}%{bindocdir}/COPYING.gzip +install -m 444 gzip/README %{buildroot}%{bindocdir}/README.gzip +install -m 444 ipconfig/README %{buildroot}%{bindocdir}/README.ipconfig +install -m 444 kinit/README %{buildroot}%{bindocdir}/README.kinit %clean rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) -%docdir %{prefix}/share/doc/%{name}-%{version} -%{prefix}/%{_lib}/klibc -%dir %{prefix}/include/klibc -%{prefix}/include/klibc/*.h -%{prefix}/include/klibc/arpa -%{prefix}/include/klibc/bitsize -%{prefix}/include/klibc/klibc -%{prefix}/include/klibc/net -%{prefix}/include/klibc/netinet -%{prefix}/include/klibc/sys -%{prefix}/share/doc/%{name}-%{version} - -%files kernheaders -%defattr(-,root,root,-) -%{prefix}/include/klibc/kernel +%{klibcdir}/lib +%{klibcdir}/include +%{_bindir}/klcc +/lib/klibc-*.so +%doc %{_mandir}/man1/* +%doc %{libdocdir}/* %files utils %defattr(-,root,root,-) -%{prefix}/libexec/klibc -%docdir %{prefix}/share/doc/%{name}-utils-%{version} -%{prefix}/share/doc/%{name}-utils-%{version} +%{klibcdir}/bin +%doc %{bindocdir}/* %changelog +* Tue Mar 1 2005 H. Peter Anvin +- New "make install" scheme, klcc + * Tue Jul 6 2004 H. Peter Anvin - Update to use kernel-source RPM for the kernel symlink. diff --git a/klibc/klibc/MCONFIG b/klibc/klibc/MCONFIG index 499b6e8b56..24af09d8e0 100644 --- a/klibc/klibc/MCONFIG +++ b/klibc/klibc/MCONFIG @@ -14,5 +14,7 @@ REQFLAGS += -DWITH_ERRLIST endif CFLAGS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) +INCLUDE += -I./zlib +CFLAGS += -DDYNAMIC_CRC_TABLE SOFLAGS = -fPIC diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 8a9a68bcf7..a9aedc58f0 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -7,6 +7,8 @@ # Include configuration rules include MCONFIG +INCLUDE += -I./zlib + TESTS = $(patsubst %.c,%,$(wildcard tests/*.c)) \ $(patsubst %.c,%.shared,$(wildcard tests/*.c)) LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ @@ -47,10 +49,17 @@ LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \ send.o recv.o + ifeq ($(ERRLIST),1) LIBOBJS += errlist.o endif +ifeq ($(ZLIB),1) +LIBOBJS += zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/gzio.o \ + zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \ + zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/inffast.o +endif + SOLIB = libc.so SOHASH = klibc.so @@ -79,12 +88,12 @@ tests/testvsnp.o : tests/testvsnp.c tests/% : tests/%.o $(LIB) $(CRT0) $(LD) $(LDFLAGS) -o $@ $(CRT0) $< $(LIB) $(LIBGCC) cp $@ $@.stripped - $(STRIP) $@.stripped + $(STRIPCMD) $@.stripped tests/%.shared : tests/%.o interp.o $(SOLIB) $(LD) $(LDFLAGS) -o $@ $(EMAIN) interp.o tests/$*.o -R $(SOLIB) $(LIBGCC) cp $@ $@.stripped - $(STRIP) $@.stripped + $(STRIPCMD) $@.stripped $(LIB): __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj rm -f $(LIB) @@ -168,6 +177,14 @@ spotless: clean bitsize: @echo $(BITSIZE) +install: all + $(INSTALL_DATA) $(LIB) $(SOLIB) $(CRT0) $(INTERP_O) \ + $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)lib + $(INSTALL_EXEC) klibc-`cat $(SOLIB).hash`.so \ + $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)lib + $(INSTALL_EXEC) klibc-`cat $(SOLIB).hash`.so \ + $(INSTALLROOT)/$(SHLIBDIR) + ifneq ($(wildcard $(DIR).*.d),) include $(wildcard $(DIR).*.d) endif diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def index 4591d0b983..3918bcb012 100644 --- a/klibc/klibc/SYSCALLS.def +++ b/klibc/klibc/SYSCALLS.def @@ -11,6 +11,7 @@ ; #include +#include ; ; Process-related syscalls @@ -175,7 +176,8 @@ int munmap(void *, size_t) void * mremap(void *, size_t, size_t, unsigned long) int msync(const void *, size_t, int) int mprotect(const void *, size_t, int) -#if (BITSIZE == 32 && defined(__NR_mmap2)) || (BITSIZE == 64 && !defined(__NR_mmap)) +#if (_BITSIZE == 32 && defined(__NR_mmap2)) || \ + (_BITSIZE == 64 && !defined(__NR_mmap)) void * mmap2::__mmap2(void *, size_t, int, int, int, long) #else void * mmap(void *, size_t, int, int, int, long) diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG index 2421452eea..67d8de4740 100644 --- a/klibc/klibc/arch/i386/MCONFIG +++ b/klibc/klibc/arch/i386/MCONFIG @@ -13,11 +13,13 @@ REGPARM_OPT := -mregparm=3 -DREGPARM=3 gcc_major := $(shell echo __GNUC__ | $(CC) -E -xc - | tail -n 1) -OPTFLAGS = $(REGPARM) -march=i386 -Os -g +OPTFLAGS = -march=i386 -Os -g +LDFLAGS = -m elf_i386 ifeq ($(gcc_major),3) REGPARM := $(REGPARM_OPT) OPTFLAGS += -falign-functions=0 -falign-jumps=0 -falign-loops=0 +ARCHREQFLAGS += -m32 else OPTFLAGS += -malign-functions=0 -malign-jumps=0 -malign-loops=0 endif diff --git a/klibc/klibc/include/sys/times.h b/klibc/klibc/include/sys/times.h deleted file mode 100644 index 657f9c4b1c..0000000000 --- a/klibc/klibc/include/sys/times.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/times.h - */ - -#ifndef _SYS_TIMES_H -#define _SYS_TIMES_H - -#include - -__extern clock_t times(struct tms *); -__extern int gettimeofday(struct timeval *, struct timezone *); -__extern int settimeofday(const struct timeval *, const struct timezone *); - -#endif /* _SYS_TIMES_H */ diff --git a/klibc/klibc/llseek.c b/klibc/klibc/llseek.c index 2102a503e9..857490b378 100644 --- a/klibc/klibc/llseek.c +++ b/klibc/klibc/llseek.c @@ -9,8 +9,9 @@ #include #include +#include -#if BITSIZE == 32 +#if _BITSIZE == 32 extern int __llseek(int fd, unsigned long hi, unsigned long lo, off_t *res, int whence); diff --git a/klibc/klibc/mmap.c b/klibc/klibc/mmap.c index 196f1c088f..11c540aed6 100644 --- a/klibc/klibc/mmap.c +++ b/klibc/klibc/mmap.c @@ -8,20 +8,20 @@ #include #include #include /* For PAGE_SHIFT */ +#include -#if defined(__sparc__) +/* + * MMAP2_SHIFT is definitely *NOT* equal to getpageshift() for + * many 32-bit architectures. Supposedly this is fixed to 12 + * for all 32-bit architectures. CHECK THIS!!! + */ # define MMAP2_SHIFT 12 /* Fixed by syscall definition */ -#elif defined(__mips__) || defined(__powerpc__) -# define MMAP2_SHIFT __getpageshift() /* Variable */ -#else -# define MMAP2_SHIFT PAGE_SHIFT -#endif /* * Set in SYSCALLS whether or not we should use an unadorned mmap() system * call (typical on 64-bit architectures). */ -#if (BITSIZE == 32 && defined(__NR_mmap2)) || (BITSIZE == 64 && !defined(__NR_mmap)) +#if (_BITSIZE == 32 && defined(__NR_mmap2)) || (_BITSIZE == 64 && !defined(__NR_mmap)) /* This architecture uses mmap2(). The Linux mmap2() system call takes a page offset as the offset argument. We need to make sure we have diff --git a/klibc/klibc/tests/rtsig.c b/klibc/klibc/tests/rtsig.c new file mode 100644 index 0000000000..a7f8eed088 --- /dev/null +++ b/klibc/klibc/tests/rtsig.c @@ -0,0 +1,12 @@ +#include +#include + +int main(void) +{ +#ifdef SIGRTMIN + printf("sigrtmin = %d, sigrtmax = %d\n", SIGRTMIN, SIGRTMAX); +#else + printf("No realtime signals\n"); +#endif + return 0; +} diff --git a/klibc/klibc/zlib/FAQ b/klibc/klibc/zlib/FAQ new file mode 100644 index 0000000000..7115ec38d6 --- /dev/null +++ b/klibc/klibc/zlib/FAQ @@ -0,0 +1,315 @@ + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +http://www.zlib.org which may have more recent information. +The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. + See the file win32/DLL_FAQ.txt in the zlib distribution. + Pointers to the precompiled DLL are found in the zlib web site at + http://www.zlib.org. + + 3. Where can I get a Visual Basic interface to zlib? + + See + * http://www.winimage.com/zLibDll/ + * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm + * contrib/visual-basic.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR + + Make sure that before the call of compress, the length of the compressed + buffer is equal to the total size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR + + Before making the call, make sure that avail_in and avail_out are not + zero. When setting the parameter flush equal to Z_FINISH, also make sure + that avail_out is big enough to allow processing all pending input. + Note that a Z_BUF_ERROR is not fatal--another call to deflate() or + inflate() can be made with more input or output space. A Z_BUF_ERROR + may in fact be unavoidable depending on how the functions are used, since + it is not possible to tell whether or not there is more output pending + when strm.avail_out returns with zero. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h for the moment, and Francis S. Lin has converted it to a + web page zlib.html. Volunteers to transform this to Unix-style man pages, + please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage + are in the files example.c and minigzip.c. + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple + package. zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of + zlib. Please try to reproduce the problem with a small program and send + the corresponding source to us at zlib@gzip.org . Do not send + multi-megabyte data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + See the directory contrib/minizip in the zlib distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + make clean + ./configure -s + make + +14. How do I install a shared zlib library on Unix? + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to it. + +15. I have a question about OttoPDF + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site Joel Hainley jhainley@myndkryme.com. + +16. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip + formats use the same compressed data format internally, but have different + headers and trailers around the compressed data. + +17. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about + a single file, such as the name and last modification date. The zlib + format on the other hand was designed for in-memory and communication + channel applications, and has a much more compact header and trailer and + uses a faster integrity check than gzip. + +18. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode + the gzip format using inflateInit2(). Read zlib.h for more details. + + Note that you cannot specify special gzip header contents (e.g. a file + name or modification date), nor will inflate tell you what was in the + gzip header. If you need to customize the header or see what's in it, + you can use the raw deflate and inflate operations and the crc32() + function and roll your own gzip encoding and decoding. Read the gzip + RFC 1952 for details of the header and trailer format. + +19. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's Init functions allow + for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +20. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +21. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +22. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +23. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +24. Will zlib work on a 64-bit machine? + + It should. It has been tested on 64-bit machines, and has no dependence + on any data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +25. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format + than does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +26. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically + use Z_FULL_FLUSH, carefully write all the pending data at those points, + and keep an index of those locations, then you can start decompression + at those points. You have to be careful to not use Z_FULL_FLUSH too + often, since it can significantly degrade compression. + +27. Does zlib work on MVS, OS/390, CICS, etc.? + + We don't know for sure. We have heard occasional reports of success on + these systems. If you do use it on one of these, please provide us with + a report, instructions, and patches that we can reference when we get + these questions. Thanks. + +28. Is there some simpler, easier to read version of inflate I can look at + to understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +29. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + http://www.gzip.org/#faq11 + +30. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit + only if the compiler's "long" type is 32 bits. If the compiler's "long" + type is 64 bits, then the limit is 16 exabytes. + +31. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib + is compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of a 4K string space, other than the caller of + gzprintf() assuring that the output will not exceed 4K. On the other + hand, if zlib is compiled to use snprintf() or vsnprintf(), which should + normally be the case, then there is no vulnerability. The ./configure + script will display warnings if an insecure variation of sprintf() will + be used by gzprintf(). Also the zlibCompileFlags() function will return + information on what variant of sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + http://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability. + +32. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: http://www.zlib.org/ + +33. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pendantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly. So now, we simply make sure that the code always + works. + +34. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +35. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very weak + and can be broken with freely available programs. To get strong encryption, + use gpg ( http://www.gnupg.org/ ) which already includes zlib compression. + For PKZIP compatible "encryption", look at http://www.info-zip.org/ + +36. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion + with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specficiation in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +37. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. + In any case, the compression improvements are so modest compared to other + more modern approaches, that it's not worth the effort to implement. + +38. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/klibc/klibc/zlib/INDEX b/klibc/klibc/zlib/INDEX new file mode 100644 index 0000000000..a9de7844d1 --- /dev/null +++ b/klibc/klibc/zlib/INDEX @@ -0,0 +1,48 @@ +ChangeLog history of changes +FAQ Frequently Asked Questions about zlib +INDEX this file +Makefile makefile for Unix (generated by configure) +Makefile.in makefile for Unix (template for configure) +README guess what +algorithm.txt description of the (de)compression algorithm +configure configure script for Unix +zconf.in.h template for zconf.h (used by configure) + +msdos/ makefiles for MSDOS +old/ makefiles for various architectures and zlib documentation + files that have not yet been updated for zlib 1.2.x +qnx/ makefiles for QNX +win32/ makefiles for Windows + + zlib public header files (must be kept): +zconf.h +zlib.h + + private source files used to build the zlib library: +adler32.c +compress.c +crc32.c +crc32.h +deflate.c +deflate.h +gzio.c +infback.c +inffast.c +inffast.h +inffixed.h +inflate.c +inflate.h +inftrees.c +inftrees.h +trees.c +trees.h +uncompr.c +zutil.c +zutil.h + + source files for sample programs: +example.c +minigzip.c + + unsupported contribution by third parties +See contrib/README.contrib diff --git a/klibc/klibc/zlib/README b/klibc/klibc/zlib/README new file mode 100644 index 0000000000..0f1205481c --- /dev/null +++ b/klibc/klibc/zlib/README @@ -0,0 +1,126 @@ +ZLIB DATA COMPRESSION LIBRARY + +zlib 1.2.1 is a general purpose data compression library. All the code is +thread safe. The data format used by the zlib library is described by RFCs +(Request for Comments) 1950 to 1952 in the files +http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) +and rfc1952.txt (gzip format). These documents are also available in other +formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html + +All functions of the compression library are documented in the file zlib.h +(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example +of the library is given in the file example.c which also tests that the library +is working correctly. Another example is given in the file minigzip.c. The +compression library itself is composed of all source files except example.c and +minigzip.c. + +To compile all files and run the test program, follow the instructions given at +the top of Makefile. In short "make test; make install" should work for most +machines. For Unix: "./configure; make test; make install" For MSDOS, use one +of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or +descrip.mms. + +Questions about zlib should be sent to , or to Gilles Vollant + for the Windows DLL version. The zlib home page is +http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, +please check this site to verify that you have the latest version of zlib; +otherwise get the latest version and check whether the problem still exists or +not. + +PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking +for help. + +Mark Nelson wrote an article about zlib for the Jan. 1997 +issue of Dr. Dobb's Journal; a copy of the article is available in +http://dogma.net/markn/articles/zlibtool/zlibtool.htm + +The changes made in version 1.2.1 are documented in the file ChangeLog. + +Unsupported third party contributions are provided in directory "contrib". + +A Java implementation of zlib is available in the Java Development Kit +http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html +See the zlib home page http://www.zlib.org for details. + +A Perl interface to zlib written by Paul Marquess is in the +CPAN (Comprehensive Perl Archive Network) sites +http://www.cpan.org/modules/by-module/Compress/ + +A Python interface to zlib written by A.M. Kuchling is +available in Python 1.5 and later versions, see +http://www.python.org/doc/lib/module-zlib.html + +A zlib binding for TCL written by Andreas Kupries is +availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html + +An experimental package to read and write files in .zip format, written on top +of zlib by Gilles Vollant , is available in the +contrib/minizip directory of zlib. + + +Notes for some targets: + +- For Windows DLL versions, please see win32/DLL_FAQ.txt + +- For 64-bit Irix, deflate.c must be compiled without any optimization. With + -O, one libpng test fails. The test works in 32 bit mode (with the -n32 + compiler flag). The compiler bug has been reported to SGI. + +- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works + when compiled with cc. + +- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is + necessary to get gzprintf working correctly. This is done by configure. + +- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with + other compilers. Use "make test" to check your compiler. + +- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. + +- For PalmOs, see http://palmzlib.sourceforge.net/ + +- When building a shared, i.e. dynamic library on Mac OS X, the library must be + installed before testing (do "make install" before "make test"), since the + library location is specified in the library. + + +Acknowledgments: + + The deflate format used by zlib was defined by Phil Katz. The deflate + and zlib specifications were written by L. Peter Deutsch. Thanks to all the + people who reported problems and suggested various improvements in zlib; + they are too numerous to cite here. + +Copyright notice: + + (C) 1995-2003 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + +If you use the zlib library in a product, we would appreciate *not* +receiving lengthy legal documents to sign. The sources are provided +for free but without warranty of any kind. The library has been +entirely written by Jean-loup Gailly and Mark Adler; it does not +include third-party code. + +If you redistribute modified sources, we would appreciate that you include +in the file ChangeLog history information documenting your changes. Please +read the FAQ for more information on the distribution of modified source +versions. diff --git a/klibc/klibc/zlib/adler32.c b/klibc/klibc/zlib/adler32.c new file mode 100644 index 0000000000..48c08f094a --- /dev/null +++ b/klibc/klibc/zlib/adler32.c @@ -0,0 +1,74 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: adler32.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +#define BASE 65521UL /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} +#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); +#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); +#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); +#define DO16(buf) DO8(buf,0); DO8(buf,8); + +#ifdef NO_DIVIDE +# define MOD(a) \ + do { \ + if (a >= (BASE << 16)) a -= (BASE << 16); \ + if (a >= (BASE << 15)) a -= (BASE << 15); \ + if (a >= (BASE << 14)) a -= (BASE << 14); \ + if (a >= (BASE << 13)) a -= (BASE << 13); \ + if (a >= (BASE << 12)) a -= (BASE << 12); \ + if (a >= (BASE << 11)) a -= (BASE << 11); \ + if (a >= (BASE << 10)) a -= (BASE << 10); \ + if (a >= (BASE << 9)) a -= (BASE << 9); \ + if (a >= (BASE << 8)) a -= (BASE << 8); \ + if (a >= (BASE << 7)) a -= (BASE << 7); \ + if (a >= (BASE << 6)) a -= (BASE << 6); \ + if (a >= (BASE << 5)) a -= (BASE << 5); \ + if (a >= (BASE << 4)) a -= (BASE << 4); \ + if (a >= (BASE << 3)) a -= (BASE << 3); \ + if (a >= (BASE << 2)) a -= (BASE << 2); \ + if (a >= (BASE << 1)) a -= (BASE << 1); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#else +# define MOD(a) a %= BASE +#endif + +/* ========================================================================= */ +uLong ZEXPORT adler32(adler, buf, len) + uLong adler; + const Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? (int)len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + buf += 16; + k -= 16; + } + if (k != 0) do { + s1 += *buf++; + s2 += s1; + } while (--k); + MOD(s1); + MOD(s2); + } + return (s2 << 16) | s1; +} diff --git a/klibc/klibc/zlib/algorithm.txt b/klibc/klibc/zlib/algorithm.txt new file mode 100644 index 0000000000..b022dde312 --- /dev/null +++ b/klibc/klibc/zlib/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend two much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +http://www.ietf.org/rfc/rfc1951.txt diff --git a/klibc/klibc/zlib/compress.c b/klibc/klibc/zlib/compress.c new file mode 100644 index 0000000000..3f4b44266a --- /dev/null +++ b/klibc/klibc/zlib/compress.c @@ -0,0 +1,79 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2002 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: compress.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; + int level; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; +#ifdef MAXSEG_64K + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; +#endif + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, level); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + +/* =========================================================================== + */ +int ZEXPORT compress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +uLong ZEXPORT compressBound (sourceLen) + uLong sourceLen; +{ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; +} diff --git a/klibc/klibc/zlib/crc32.c b/klibc/klibc/zlib/crc32.c new file mode 100644 index 0000000000..0bb9c49ab1 --- /dev/null +++ b/klibc/klibc/zlib/crc32.c @@ -0,0 +1,311 @@ +/* crc32.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Thanks to Rodney Brown for his contribution of faster + * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing + * tables for updating the shift register in one step with three exclusive-ors + * instead of four steps with four exclusive-ors. This results about a factor + * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. + */ + +/* @(#) $Id: crc32.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#ifdef MAKECRCH +# include +# ifndef DYNAMIC_CRC_TABLE +# define DYNAMIC_CRC_TABLE +# endif /* !DYNAMIC_CRC_TABLE */ +#endif /* MAKECRCH */ + +#include "zutil.h" /* for STDC and FAR definitions */ + +#define local static + +/* Find a four-byte integer type for crc32_little() and crc32_big(). */ +#ifndef NOBYFOUR +# ifdef STDC /* need ANSI C limits.h to determine sizes */ +# include +# define BYFOUR +# if (UINT_MAX == 0xffffffffUL) + typedef unsigned int u4; +# else +# if (ULONG_MAX == 0xffffffffUL) + typedef unsigned long u4; +# else +# if (USHRT_MAX == 0xffffffffUL) + typedef unsigned short u4; +# else +# undef BYFOUR /* can't find a four-byte integer type! */ +# endif +# endif +# endif +# endif /* STDC */ +#endif /* !NOBYFOUR */ + +/* Definitions for doing the crc four data bytes at a time. */ +#ifdef BYFOUR +# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ + (((w)&0xff00)<<8)+(((w)&0xff)<<24)) + local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); + local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +# define TBLS 8 +#else +# define TBLS 1 +#endif /* BYFOUR */ + +#ifdef DYNAMIC_CRC_TABLE + +local int crc_table_empty = 1; +local unsigned long FAR crc_table[TBLS][256]; +local void make_crc_table OF((void)); +#ifdef MAKECRCH + local void write_table OF((FILE *, const unsigned long FAR *)); +#endif /* MAKECRCH */ + +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by + x (which is shifting right by one and adding x^32 mod p if the bit shifted + out is a one). We start with the highest power (least significant bit) of + q and repeat for all eight bits of q. + + The first table is simply the CRC of all possible eight bit values. This is + all the information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. The remaining tables + allow for word-at-a-time CRC calculation for both big-endian and little- + endian machines, where a word is four bytes. +*/ +local void make_crc_table() +{ + unsigned long c; + int n, k; + unsigned long poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0UL; + for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) + poly |= 1UL << (31 - p[n]); + + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) { + c = (unsigned long)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } + +#ifdef BYFOUR + /* generate crc for each value followed by one, two, and three zeros, and + then the byte reversal of those as well as the first table */ + for (n = 0; n < 256; n++) { + c = crc_table[0][n]; + crc_table[4][n] = REV(c); + for (k = 1; k < 4; k++) { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = REV(c); + } + } +#endif /* BYFOUR */ + + crc_table_empty = 0; + +#ifdef MAKECRCH + /* write out CRC tables to crc32.h */ + { + FILE *out; + + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const unsigned long FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +# ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +# endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } +#endif /* MAKECRCH */ +} + +#ifdef MAKECRCH +local void write_table(out, table) + FILE *out; + const unsigned long FAR *table; +{ + int n; + + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); +} +#endif /* MAKECRCH */ + +#else /* !DYNAMIC_CRC_TABLE */ +/* ======================================================================== + * Tables of CRC-32s of all single-byte values, made by make_crc_table(). + */ +#include "crc32.h" +#endif /* DYNAMIC_CRC_TABLE */ + +/* ========================================================================= + * This function can be used by asm versions of crc32() + */ +const unsigned long FAR * ZEXPORT get_crc_table() +{ +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + return (const unsigned long FAR *)crc_table; +} + +/* ========================================================================= */ +#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +unsigned long ZEXPORT crc32(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + if (buf == Z_NULL) return 0UL; + +#ifdef DYNAMIC_CRC_TABLE + if (crc_table_empty) + make_crc_table(); +#endif /* DYNAMIC_CRC_TABLE */ + +#ifdef BYFOUR + if (sizeof(void *) == sizeof(ptrdiff_t)) { + u4 endian; + + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } +#endif /* BYFOUR */ + crc = crc ^ 0xffffffffUL; + while (len >= 8) { + DO8; + len -= 8; + } + if (len) do { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; +} + +#ifdef BYFOUR + +/* ========================================================================= */ +#define DOLIT4 c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 + +/* ========================================================================= */ +local unsigned long crc32_little(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = (u4)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } + + buf4 = (const u4 FAR *)buf; + while (len >= 32) { + DOLIT32; + len -= 32; + } + while (len >= 4) { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; +} + +/* ========================================================================= */ +#define DOBIG4 c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 + +/* ========================================================================= */ +local unsigned long crc32_big(crc, buf, len) + unsigned long crc; + const unsigned char FAR *buf; + unsigned len; +{ + register u4 c; + register const u4 FAR *buf4; + + c = REV((u4)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } + + buf4 = (const u4 FAR *)buf; + buf4--; + while (len >= 32) { + DOBIG32; + len -= 32; + } + while (len >= 4) { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; + + if (len) do { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(REV(c)); +} + +#endif /* BYFOUR */ diff --git a/klibc/klibc/zlib/crc32.h b/klibc/klibc/zlib/crc32.h new file mode 100644 index 0000000000..8053b6117c --- /dev/null +++ b/klibc/klibc/zlib/crc32.h @@ -0,0 +1,441 @@ +/* crc32.h -- tables for rapid CRC calculation + * Generated automatically by crc32.c + */ + +local const unsigned long FAR crc_table[TBLS][256] = +{ + { + 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL +#ifdef BYFOUR + }, + { + 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL + }, + { + 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL + }, + { + 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL + }, + { + 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL + }, + { + 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL + }, + { + 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL + }, + { + 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL +#endif + } +}; diff --git a/klibc/klibc/zlib/deflate.c b/klibc/klibc/zlib/deflate.c new file mode 100644 index 0000000000..fe07dcb673 --- /dev/null +++ b/klibc/klibc/zlib/deflate.c @@ -0,0 +1,1502 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in http://www.ietf.org/rfc/rfc1951.txt + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +/* @(#) $Id: deflate.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#include "deflate.h" + +const char deflate_copyright[] = + " deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Function prototypes. + */ +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +/* Compression function. Returns the block state after the call. */ + +local void fill_window OF((deflate_state *s)); +local block_state deflate_stored OF((deflate_state *s, int flush)); +local block_state deflate_fast OF((deflate_state *s, int flush)); +#ifndef FASTEST +local block_state deflate_slow OF((deflate_state *s, int flush)); +#endif +local void lm_init OF((deflate_state *s)); +local void putShortMSB OF((deflate_state *s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +#ifndef FASTEST +#ifdef ASMV + void match_init OF((void)); /* asm code initialization */ + uInt longest_match OF((deflate_state *s, IPos cur_match)); +#else +local uInt longest_match OF((deflate_state *s, IPos cur_match)); +#endif +#endif +local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); + +#ifdef DEBUG +local void check_match OF((deflate_state *s, IPos start, IPos match, + int length)); +#endif + +/* =========================================================================== + * Local data + */ + +#define NIL 0 +/* Tail of hash chains */ + +#ifndef TOO_FAR +# define TOO_FAR 4096 +#endif +/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; +} config; + +#ifdef FASTEST +local const config configuration_table[2] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ +#else +local const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +/* 3 */ {4, 6, 32, 32, deflate_fast}, + +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ +#endif + +/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +#define EQUAL 0 +/* result of memcmp for equal strings */ + +#ifndef NO_DUMMY_DECL +struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) + + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * If this file is compiled with -DFASTEST, the compression level is forced + * to 1, and no hash chains are maintained. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first MIN_MATCH bytes of str are valid + * (except for the last MIN_MATCH-1 bytes of the input file). + */ +#ifdef FASTEST +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#else +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ + match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) +#endif + +/* =========================================================================== + * Initialize the hash table (avoiding 64K overflow for 16 bit systems). + * prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) \ + s->head[s->hash_size-1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); + +/* ========================================================================= */ +int ZEXPORT deflateInit_(strm, level, version, stream_size) + z_streamp strm; + int level; + const char *version; + int stream_size; +{ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ +} + +/* ========================================================================= */ +int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, + version, stream_size) + z_streamp strm; + int level; + int method; + int windowBits; + int memLevel; + int strategy; + const char *version; + int stream_size; +{ + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; + + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average + * output size for (length,distance) codes is <= 24 bits. + */ + + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; + + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } +#ifdef GZIP + else if (windowBits > 15) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } +#endif + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_RLE) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; + + s->wrap = wrap; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + + s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); + s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); + s->pending_buf = (uchf *) overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) { + s->status = FINISH_STATE; + strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); + deflateEnd (strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize/sizeof(ush); + s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; + + return deflateReset(strm); +} + +/* ========================================================================= */ +int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) + z_streamp strm; + const Bytef *dictionary; + uInt dictLength; +{ + deflate_state *s; + uInt length = dictLength; + uInt n; + IPos hash_head = 0; + + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || + strm->state->wrap == 2 || + (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) + return Z_STREAM_ERROR; + + s = strm->state; + if (s->wrap) + strm->adler = adler32(strm->adler, dictionary, dictLength); + + if (length < MIN_MATCH) return Z_OK; + if (length > MAX_DIST(s)) { + length = MAX_DIST(s); +#ifndef USE_DICT_HEAD + dictionary += dictLength - length; /* use the tail of the dictionary */ +#endif + } + zmemcpy(s->window, dictionary, length); + s->strstart = length; + s->block_start = (long)length; + + /* Insert all strings in the hash table (except for the last two bytes). + * s->lookahead stays null, so s->ins_h will be recomputed at the next + * call of fill_window. + */ + s->ins_h = s->window[0]; + UPDATE_HASH(s, s->ins_h, s->window[1]); + for (n = 0; n <= length - MIN_MATCH; n++) { + INSERT_STRING(s, n, hash_head); + } + if (hash_head) hash_head = 0; /* to make compiler happy */ + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateReset (strm) + z_streamp strm; +{ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { + return Z_STREAM_ERROR; + } + + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = +#ifdef GZIP + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : +#endif + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; + + _tr_init(s); + lm_init(s); + + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflatePrime (strm, bits, value) + z_streamp strm; + int bits; + int value; +{ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + strm->state->bi_valid = bits; + strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); + return Z_OK; +} + +/* ========================================================================= */ +int ZEXPORT deflateParams(strm, level, strategy) + z_streamp strm; + int level; + int strategy; +{ + deflate_state *s; + compress_func func; + int err = Z_OK; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + +#ifdef FASTEST + if (level != 0) level = 1; +#else + if (level == Z_DEFAULT_COMPRESSION) level = 6; +#endif + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; + + if (func != configuration_table[level].func && strm->total_in != 0) { + /* Flush the last buffer: */ + err = deflate(strm, Z_PARTIAL_FLUSH); + } + if (s->level != level) { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds + * for every combination of windowBits and memLevel, as well as wrap. + * But even the conservative upper bound of about 14% expansion does not + * seem onerous for output buffer allocation. + */ +uLong ZEXPORT deflateBound(strm, sourceLen) + z_streamp strm; + uLong sourceLen; +{ + deflate_state *s; + uLong destLen; + + /* conservative upper bound */ + destLen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; + + /* if can't get parameters, return conservative bound */ + if (strm == Z_NULL || strm->state == Z_NULL) + return destLen; + + /* if not default parameters, return conservative bound */ + s = strm->state; + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return destLen; + + /* default settings: return tight bound for that case */ + return compressBound(sourceLen); +} + +/* ========================================================================= + * Put a short in the pending buffer. The 16-bit value is put in MSB order. + * IN assertion: the stream state is correct and there is enough room in + * pending_buf. + */ +local void putShortMSB (s, b) + deflate_state *s; + uInt b; +{ + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output goes + * through this function so some applications may wish to modify it + * to avoid allocating a large strm->next_out buffer and copying into it. + * (See also read_buf()). + */ +local void flush_pending(strm) + z_streamp strm; +{ + unsigned len = strm->state->pending; + + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; + + zmemcpy(strm->next_out, strm->state->pending_out, len); + strm->next_out += len; + strm->state->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + strm->state->pending -= len; + if (strm->state->pending == 0) { + strm->state->pending_out = strm->state->pending_buf; + } +} + +/* ========================================================================= */ +int ZEXPORT deflate (strm, flush) + z_streamp strm; + int flush; +{ + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_FINISH || flush < 0) { + return Z_STREAM_ERROR; + } + s = strm->state; + + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; + + /* Write the header */ + if (s->status == INIT_STATE) { +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? + 4 : 0)); + put_byte(s, 255); + s->status = BUSY_STATE; + strm->adler = crc32(0L, Z_NULL, 0); + } + else +#endif + { + uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + uInt level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); + + s->status = BUSY_STATE; + putShortMSB(s, header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + flush_pending(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && flush <= old_flush && + flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + _tr_align(s); + } else { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + } + } + flush_pending(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); + + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else +#endif + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; +} + +/* ========================================================================= */ +int ZEXPORT deflateEnd (strm) + z_streamp strm; +{ + int status; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + + status = strm->state->status; + if (status != INIT_STATE && status != BUSY_STATE && + status != FINISH_STATE) { + return Z_STREAM_ERROR; + } + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); + + ZFREE(strm, strm->state); + strm->state = Z_NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + * To simplify the source, this is not supported for 16-bit MSDOS (which + * doesn't have enough memory anyway to duplicate compression states). + */ +int ZEXPORT deflateCopy (dest, source) + z_streamp dest; + z_streamp source; +{ +#ifdef MAXSEG_64K + return Z_STREAM_ERROR; +#else + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + + + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { + return Z_STREAM_ERROR; + } + + ss = source->state; + + *dest = *source; + + ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *) ds; + *ds = *ss; + ds->strm = dest; + + ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); + ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); + ds->pending_buf = (uchf *) overlay; + + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) { + deflateEnd (dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); + ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +#endif /* MAXSEG_64K */ +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +local int read_buf(strm, buf, size) + z_streamp strm; + Bytef *buf; + unsigned size; +{ + unsigned len = strm->avail_in; + + if (len > size) len = size; + if (len == 0) return 0; + + strm->avail_in -= len; + + if (strm->state->wrap == 1) { + strm->adler = adler32(strm->adler, strm->next_in, len); + } +#ifdef GZIP + else if (strm->state->wrap == 2) { + strm->adler = crc32(strm->adler, strm->next_in, len); + } +#endif + zmemcpy(buf, strm->next_in, len); + strm->next_in += len; + strm->total_in += len; + + return (int)len; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +local void lm_init (s) + deflate_state *s; +{ + s->window_size = (ulg)2L*s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; + + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH-1; + s->match_available = 0; + s->ins_h = 0; +#ifdef ASMV + match_init(); /* initialize the asm code */ +#endif +} + +#ifndef FASTEST +/* =========================================================================== + * Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is + * garbage. + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 + * OUT assertion: the match length is not greater than s->lookahead. + */ +#ifndef ASMV +/* For 80x86 and 680x0, an optimized version will be provided in match.asm or + * match.S. The code will be functionally equivalent. + */ +local uInt longest_match(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + unsigned chain_length = s->max_chain_length;/* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? + s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0. + */ + Posf *prev = s->prev; + uInt wmask = s->w_mask; + +#ifdef UNALIGNED_OK + /* Compare two bytes at a time. Note: this is not always beneficial. + * Try with and without -DUNALIGNED_OK to check. + */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf*)scan; + register ush scan_end = *(ushf*)(scan+best_len-1); +#else + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len-1]; + register Byte scan_end = scan[best_len]; +#endif + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary + * to make deflate deterministic. + */ + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + do { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; + + /* Skip to next match if the match length cannot increase + * or if the match length is less than 2: + */ +#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) + /* This code assumes sizeof(unsigned short) == 2. Do not use + * UNALIGNED_OK if your compiler uses a different size. + */ + if (*(ushf*)(match+best_len-1) != scan_end || + *(ushf*)match != scan_start) continue; + + /* It is not necessary to compare scan[2] and match[2] since they are + * always equal when the other bytes match, given that the hash keys + * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at + * strstart+3, +5, ... up to strstart+257. We check for insufficient + * lookahead only every 4th comparison; the 128th check will be made + * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is + * necessary to put more guard bytes at the end of the window, or + * to check more often for insufficient lookahead. + */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do { + } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + *(ushf*)(scan+=2) == *(ushf*)(match+=2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ + + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + if (*scan == *match) scan++; + + len = (MAX_MATCH - 1) - (int)(strend-scan); + scan = strend - (MAX_MATCH-1); + +#else /* UNALIGNED_OK */ + + if (match[best_len] != scan_end || + match[best_len-1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; + +#endif /* UNALIGNED_OK */ + + if (len > best_len) { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; +#ifdef UNALIGNED_OK + scan_end = *(ushf*)(scan+best_len-1); +#else + scan_end1 = scan[best_len-1]; + scan_end = scan[best_len]; +#endif + } + } while ((cur_match = prev[cur_match & wmask]) > limit + && --chain_length != 0); + + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; +} +#endif /* ASMV */ +#endif /* FASTEST */ + +/* --------------------------------------------------------------------------- + * Optimized version for level == 1 or strategy == Z_RLE only + */ +local uInt longest_match_fast(s, cur_match) + deflate_state *s; + IPos cur_match; /* current match */ +{ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + * It is easy to get rid of this optimization if necessary. + */ + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + + Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + + Assert(cur_match < s->strstart, "no future"); + + match = s->window + cur_match; + + /* Return failure if the match length is less than 2: + */ + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + + /* The check at best_len-1 can be removed because it will be made + * again later. (This heuristic is not always a win.) + * It is not necessary to compare scan[2] and match[2] since they + * are always equal when the other bytes match, given that + * the hash keys are equal and that HASH_BITS >= 8. + */ + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); + + /* We check for insufficient lookahead only every 8th comparison; + * the 256th check will be made at strstart+258. + */ + do { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); + + Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + + len = MAX_MATCH - (int)(strend - scan); + + if (len < MIN_MATCH) return MIN_MATCH - 1; + + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; +} + +#ifdef DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +local void check_match(s, start, match, length) + deflate_state *s; + IPos start, match; + int length; +{ + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr,"\\[%d,%d]", start-match, length); + do { putc(s->window[start++], stderr); } while (--length != 0); + } +} +#else +# define check_match(s, start, match, length) +#endif /* DEBUG */ + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ +local void fill_window(s) + deflate_state *s; +{ + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; + + do { + more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) { + more = wsize; + + } else if (more == (unsigned)(-1)) { + /* Very unlikely, but possible on 16 bit machine if + * strstart == 0 && lookahead == 1 (input done a byte at time) + */ + more--; + } + } + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + + zmemcpy(s->window, s->window+wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long) wsize; + + /* Slide the hash table (could be avoided with 32 bit values + at the expense of memory usage). We slide even when level == 0 + to keep the hash table consistent if we switch back to level > 0 + later. (Using level 0 permanently is not an optimal usage of + zlib, so we don't care about this pathological case.) + */ + n = s->hash_size; + p = &s->head[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + } while (--n); + + n = wsize; +#ifndef FASTEST + p = &s->prev[n]; + do { + m = *--p; + *p = (Pos)(m >= wsize ? m-wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but + * its value will never be used. + */ + } while (--n); +#endif + more += wsize; + } + if (s->strm->avail_in == 0) return; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead >= MIN_MATCH) { + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, eof) { \ + _tr_flush_block(s, (s->block_start >= 0L ? \ + (charf *)&s->window[(unsigned)s->block_start] : \ + (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (eof)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr,"[FLUSH]")); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, eof) { \ + FLUSH_BLOCK_ONLY(s, eof); \ + if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ +} + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * This function does not insert new strings in the dictionary since + * uncompressible data is probably not useful. This function is used + * only for the level=0 compression option. + * NOTE: this function should be optimized to avoid extra copying from + * window to pending_buf. + */ +local block_state deflate_stored(s, flush) + deflate_state *s; + int flush; +{ + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + * to pending_buf_size, and each stored block has a 5 byte header: + */ + ulg max_block_size = 0xffff; + ulg max_start; + + if (max_block_size > s->pending_buf_size - 5) { + max_block_size = s->pending_buf_size - 5; + } + + /* Copy as much as possible from input to output: */ + for (;;) { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) { + + Assert(s->strstart < s->w_size+MAX_DIST(s) || + s->block_start >= (long)s->w_size, "slide too late"); + + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); + + s->strstart += s->lookahead; + s->lookahead = 0; + + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become + * negative and the data will be gone: + */ + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { + FLUSH_BLOCK(s, 0); + } + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +local block_state deflate_fast(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < MIN_MATCH + */ + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ +#ifdef FASTEST + if ((s->strategy < Z_HUFFMAN_ONLY) || + (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { + s->match_length = longest_match_fast (s, hash_head); + } +#else + if (s->strategy < Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } +#endif + /* longest_match() or longest_match_fast() sets match_start */ + } + if (s->match_length >= MIN_MATCH) { + check_match(s, s->strstart, s->match_start, s->match_length); + + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); + + s->lookahead -= s->match_length; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ +#ifndef FASTEST + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) { + s->match_length--; /* string at strstart already in table */ + do { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are + * always MIN_MATCH bytes ahead. + */ + } while (--s->match_length != 0); + s->strstart++; + } else +#endif + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); +#if MIN_MATCH != 3 + Call UPDATE_HASH() MIN_MATCH-3 more times +#endif + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + } else { + /* No match, output a literal byte */ + Tracevv((stderr,"%c", s->window[s->strstart])); + _tr_tally_lit (s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} + +#ifndef FASTEST +/* =========================================================================== + * Same as above, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +local block_state deflate_slow(s, flush) + deflate_state *s; + int flush; +{ + IPos hash_head = NIL; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need MAX_MATCH bytes + * for the next match, plus MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= MIN_MATCH) { + INSERT_STRING(s, s->strstart, hash_head); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH-1; + + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + if (s->strategy < Z_HUFFMAN_ONLY) { + s->match_length = longest_match (s, hash_head); + } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { + s->match_length = longest_match_fast (s, hash_head); + } + /* longest_match() or longest_match_fast() sets match_start */ + + if (s->match_length <= 5 && (s->strategy == Z_FILTERED +#if TOO_FAR <= 32767 + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) +#endif + )) { + + /* If prev_match is also MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + s->match_length = MIN_MATCH-1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + _tr_tally_dist(s, s->strstart -1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->lookahead -= s->prev_length-1; + s->prev_length -= 2; + do { + if (++s->strstart <= max_insert) { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH-1; + s->strstart++; + + if (bflush) FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + if (bflush) { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert (flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) { + Tracevv((stderr,"%c", s->window[s->strstart-1])); + _tr_tally_lit(s, s->window[s->strstart-1], bflush); + s->match_available = 0; + } + FLUSH_BLOCK(s, flush == Z_FINISH); + return flush == Z_FINISH ? finish_done : block_done; +} +#endif /* FASTEST */ diff --git a/klibc/klibc/zlib/deflate.h b/klibc/klibc/zlib/deflate.h new file mode 100644 index 0000000000..bc79532e59 --- /dev/null +++ b/klibc/klibc/zlib/deflate.h @@ -0,0 +1,326 @@ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2002 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: deflate.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#ifndef DEFLATE_H +#define DEFLATE_H + +#include "zutil.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define MAX_BITS 15 +/* All codes must not exceed MAX_BITS bits */ + +#define INIT_STATE 42 +#define BUSY_STATE 113 +#define FINISH_STATE 666 +/* Stream status */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; +} FAR ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ +} FAR tree_desc; + +typedef ush Pos; +typedef Pos FAR Posf; +typedef unsigned IPos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. IPos is used only for parameter passing. + */ + +typedef struct internal_state { + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + int pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + Byte data_type; /* UNKNOWN, BINARY or ASCII */ + Byte method; /* STORED (for zip only) or DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ + + /* used by deflate.c: */ + + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ + + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + Posf *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Posf *head; /* Heads of the hash chains or NIL. */ + + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ + + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input + * step. It must be such that after MIN_MATCH steps, the oldest + * byte no longer takes part in the hash key, that is: + * hash_shift * MIN_MATCH >= hash_bits + */ + + long block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ + + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this + * length. A higher limit improves compression ratio but degrades the + * speed. + */ + + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly + * smaller than this value. This mechanism is used only for compression + * levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + uInt good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to supress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + uch depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + uchf *l_buf; /* buffer for literals or lengths */ + + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + uInt last_lit; /* running index in l_buf */ + + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have + * the same number of elements. To use different lengths, an extra flag + * array would be necessary. + */ + + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + int last_eob_len; /* bit length of EOB code for last block */ + +#ifdef DEBUG + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ +#endif + + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least + * significant bits). + */ + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit + * are always zero. + */ + +} FAR deflate_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} + + +#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + + /* in trees.c */ +void _tr_init OF((deflate_state *s)); +int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); +void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); +void _tr_align OF((deflate_state *s)); +void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, + int eof)); + +#define d_code(dist) \ + ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. _dist_code[256] and _dist_code[257] are never + * used. + */ + +#ifndef DEBUG +/* Inline versions of _tr_tally for speed: */ + +#if defined(GEN_TREES_H) || !defined(STDC) + extern uch _length_code[]; + extern uch _dist_code[]; +#else + extern const uch _length_code[]; + extern const uch _dist_code[]; +#endif + +# define _tr_tally_lit(s, c, flush) \ + { uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +# define _tr_tally_dist(s, distance, length, flush) \ + { uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize-1); \ + } +#else +# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +# define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) +#endif + +#endif /* DEFLATE_H */ diff --git a/klibc/klibc/zlib/gzio.c b/klibc/klibc/zlib/gzio.c new file mode 100644 index 0000000000..cb56b8d381 --- /dev/null +++ b/klibc/klibc/zlib/gzio.c @@ -0,0 +1,1008 @@ +/* gzio.c -- IO on .gz files + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. + */ + +/* @(#) $Id: gzio.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#include + +#include "zutil.h" + +#ifdef NO_DEFLATE /* for compatiblity with old definition */ +# define NO_GZCOMPRESS +#endif + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef Z_BUFSIZE +# ifdef MAXSEG_64K +# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ +# else +# define Z_BUFSIZE 16384 +# endif +#endif +#ifndef Z_PRINTF_BUFSIZE +# define Z_PRINTF_BUFSIZE 4096 +#endif + +#ifdef __MVS__ +# pragma map (fdopen , "\174\174FDOPEN") + FILE *fdopen(int, const char *); +#endif + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); +#endif + +#define ALLOC(size) malloc(size) +#define TRYFREE(p) {if (p) free(p);} + +static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ + +/* gzip flag byte */ +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ +#define COMMENT 0x10 /* bit 4 set: file comment present */ +#define RESERVED 0xE0 /* bits 5..7: reserved */ + +typedef struct gz_stream { + z_stream stream; + int z_err; /* error code for last stream operation */ + int z_eof; /* set if end of input file */ + FILE *file; /* .gz file */ + Byte *inbuf; /* input buffer */ + Byte *outbuf; /* output buffer */ + uLong crc; /* crc32 of uncompressed data */ + char *msg; /* error message */ + char *path; /* path name for debugging only */ + int transparent; /* 1 if input file is not a .gz file */ + char mode; /* 'w' or 'r' */ + z_off_t start; /* start of compressed data in file (header skipped) */ + z_off_t in; /* bytes into deflate or inflate */ + z_off_t out; /* bytes out of deflate or inflate */ + int back; /* one character push-back */ + int last; /* true if push-back is last character */ +} gz_stream; + + +local gzFile gz_open OF((const char *path, const char *mode, int fd)); +local int do_flush OF((gzFile file, int flush)); +local int get_byte OF((gz_stream *s)); +local void check_header OF((gz_stream *s)); +local int destroy OF((gz_stream *s)); +local void putLong OF((FILE *file, uLong x)); +local uLong getLong OF((gz_stream *s)); + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb"). The file is given either by file descriptor + or path name (if fd == -1). + gz_open returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). +*/ +local gzFile gz_open (path, mode, fd) + const char *path; + const char *mode; + int fd; +{ + int err; + int level = Z_DEFAULT_COMPRESSION; /* compression level */ + int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ + char *p = (char*)mode; + gz_stream *s; + char fmode[80]; /* copy of mode, without the compression level */ + char *m = fmode; + + if (!path || !mode) return Z_NULL; + + s = (gz_stream *)ALLOC(sizeof(gz_stream)); + if (!s) return Z_NULL; + + s->stream.zalloc = (alloc_func)0; + s->stream.zfree = (free_func)0; + s->stream.opaque = (voidpf)0; + s->stream.next_in = s->inbuf = Z_NULL; + s->stream.next_out = s->outbuf = Z_NULL; + s->stream.avail_in = s->stream.avail_out = 0; + s->file = NULL; + s->z_err = Z_OK; + s->z_eof = 0; + s->in = 0; + s->out = 0; + s->back = EOF; + s->crc = crc32(0L, Z_NULL, 0); + s->msg = NULL; + s->transparent = 0; + + s->path = (char*)ALLOC(strlen(path)+1); + if (s->path == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + strcpy(s->path, path); /* do this early for debugging */ + + s->mode = '\0'; + do { + if (*p == 'r') s->mode = 'r'; + if (*p == 'w' || *p == 'a') s->mode = 'w'; + if (*p >= '0' && *p <= '9') { + level = *p - '0'; + } else if (*p == 'f') { + strategy = Z_FILTERED; + } else if (*p == 'h') { + strategy = Z_HUFFMAN_ONLY; + } else if (*p == 'R') { + strategy = Z_RLE; + } else { + *m++ = *p; /* copy the mode */ + } + } while (*p++ && m != fmode + sizeof(fmode)); + if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateInit2(&(s->stream), level, + Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); + /* windowBits is passed < 0 to suppress zlib header */ + + s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); +#endif + if (err != Z_OK || s->outbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } else { + s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); + + err = inflateInit2(&(s->stream), -MAX_WBITS); + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are + * present after the compressed stream. + */ + if (err != Z_OK || s->inbuf == Z_NULL) { + return destroy(s), (gzFile)Z_NULL; + } + } + s->stream.avail_out = Z_BUFSIZE; + + errno = 0; + s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); + + if (s->file == NULL) { + return destroy(s), (gzFile)Z_NULL; + } + if (s->mode == 'w') { + /* Write a very simple .gz header: + */ + fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], + Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); + s->start = 10L; + /* We use 10L instead of ftell(s->file) to because ftell causes an + * fflush on some systems. This version of the library doesn't use + * start anyway in write mode, so this initialization is not + * necessary. + */ + } else { + check_header(s); /* skip the .gz header */ + s->start = ftell(s->file) - s->stream.avail_in; + } + + return (gzFile)s; +} + +/* =========================================================================== + Opens a gzip (.gz) file for reading or writing. +*/ +gzFile ZEXPORT gzopen (path, mode) + const char *path; + const char *mode; +{ + return gz_open (path, mode, -1); +} + +/* =========================================================================== + Associate a gzFile with the file descriptor fd. fd is not dup'ed here + to mimic the behavio(u)r of fdopen. +*/ +gzFile ZEXPORT gzdopen (fd, mode) + int fd; + const char *mode; +{ + char name[20]; + + if (fd < 0) return (gzFile)Z_NULL; + sprintf(name, "", fd); /* for debugging */ + + return gz_open (name, mode, fd); +} + +/* =========================================================================== + * Update the compression level and strategy + */ +int ZEXPORT gzsetparams (file, level, strategy) + gzFile file; + int level; + int strategy; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + /* Make room to allow flushing */ + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + } + s->stream.avail_out = Z_BUFSIZE; + } + + return deflateParams (&(s->stream), level, strategy); +} + +/* =========================================================================== + Read a byte from a gz_stream; update next_in and avail_in. Return EOF + for end of file. + IN assertion: the stream s has been sucessfully opened for reading. +*/ +local int get_byte(s) + gz_stream *s; +{ + if (s->z_eof) return EOF; + if (s->stream.avail_in == 0) { + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + /* klibc hack */ + if (errno) s->z_err = Z_ERRNO; + return EOF; + } + s->stream.next_in = s->inbuf; + } + s->stream.avail_in--; + return *(s->stream.next_in)++; +} + +/* =========================================================================== + Check the gzip header of a gz_stream opened for reading. Set the stream + mode to transparent if the gzip magic header is not present; set s->err + to Z_DATA_ERROR if the magic header is present but the rest of the header + is incorrect. + IN assertion: the stream s has already been created sucessfully; + s->stream.avail_in is zero for the first time, but may be non-zero + for concatenated .gz files. +*/ +local void check_header(s) + gz_stream *s; +{ + int method; /* method byte */ + int flags; /* flags byte */ + uInt len; + int c; + + /* Assure two bytes in the buffer so we can peek ahead -- handle case + where first byte of header is at the end of the buffer after the last + gzip segment */ + len = s->stream.avail_in; + if (len < 2) { + if (len) s->inbuf[0] = s->stream.next_in[0]; + errno = 0; + len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); + /* klibc hack */ + if (len == 0 && errno) s->z_err = Z_ERRNO; + s->stream.avail_in += len; + s->stream.next_in = s->inbuf; + if (s->stream.avail_in < 2) { + s->transparent = s->stream.avail_in; + return; + } + } + + /* Peek ahead to check the gzip magic header */ + if (s->stream.next_in[0] != gz_magic[0] || + s->stream.next_in[1] != gz_magic[1]) { + s->transparent = 1; + return; + } + s->stream.avail_in -= 2; + s->stream.next_in += 2; + + /* Check the rest of the gzip header */ + method = get_byte(s); + flags = get_byte(s); + if (method != Z_DEFLATED || (flags & RESERVED) != 0) { + s->z_err = Z_DATA_ERROR; + return; + } + + /* Discard time, xflags and OS code: */ + for (len = 0; len < 6; len++) (void)get_byte(s); + + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ + len = (uInt)get_byte(s); + len += ((uInt)get_byte(s))<<8; + /* len is garbage if EOF but the loop below will quit anyway */ + while (len-- != 0 && get_byte(s) != EOF) ; + } + if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ + while ((c = get_byte(s)) != 0 && c != EOF) ; + } + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ + for (len = 0; len < 2; len++) (void)get_byte(s); + } + s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; +} + + /* =========================================================================== + * Cleanup then free the given gz_stream. Return a zlib error code. + Try freeing in the reverse order of allocations. + */ +local int destroy (s) + gz_stream *s; +{ + int err = Z_OK; + + if (!s) return Z_STREAM_ERROR; + + TRYFREE(s->msg); + + if (s->stream.state != NULL) { + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + err = Z_STREAM_ERROR; +#else + err = deflateEnd(&(s->stream)); +#endif + } else if (s->mode == 'r') { + err = inflateEnd(&(s->stream)); + } + } + if (s->file != NULL && fclose(s->file)) { +#ifdef ESPIPE + if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ +#endif + err = Z_ERRNO; + } + if (s->z_err < 0) err = s->z_err; + + TRYFREE(s->inbuf); + TRYFREE(s->outbuf); + TRYFREE(s->path); + TRYFREE(s); + return err; +} + +/* =========================================================================== + Reads the given number of uncompressed bytes from the compressed file. + gzread returns the number of bytes actually read (0 for end of file). +*/ +int ZEXPORT gzread (file, buf, len) + gzFile file; + voidp buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + Bytef *start = (Bytef*)buf; /* starting point for crc computation */ + Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ + + if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; + + if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; + if (s->z_err == Z_STREAM_END) return 0; /* EOF */ + + next_out = (Byte*)buf; + s->stream.next_out = (Bytef*)buf; + s->stream.avail_out = len; + + if (s->stream.avail_out && s->back != EOF) { + *next_out++ = s->back; + s->stream.next_out++; + s->stream.avail_out--; + s->back = EOF; + s->out++; + if (s->last) { + s->z_err = Z_STREAM_END; + return 1; + } + } + + while (s->stream.avail_out != 0) { + + if (s->transparent) { + /* Copy first the lookahead bytes: */ + uInt n = s->stream.avail_in; + if (n > s->stream.avail_out) n = s->stream.avail_out; + if (n > 0) { + zmemcpy(s->stream.next_out, s->stream.next_in, n); + next_out += n; + s->stream.next_out = next_out; + s->stream.next_in += n; + s->stream.avail_out -= n; + s->stream.avail_in -= n; + } + if (s->stream.avail_out > 0) { + s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, + s->file); + } + len -= s->stream.avail_out; + s->in += len; + s->out += len; + if (len == 0) s->z_eof = 1; + return (int)len; + } + if (s->stream.avail_in == 0 && !s->z_eof) { + + errno = 0; + s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); + if (s->stream.avail_in == 0) { + s->z_eof = 1; + if (errno) { + s->z_err = Z_ERRNO; + break; + } + } + s->stream.next_in = s->inbuf; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = inflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + + if (s->z_err == Z_STREAM_END) { + /* Check CRC and original size */ + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + start = s->stream.next_out; + + if (getLong(s) != s->crc) { + s->z_err = Z_DATA_ERROR; + } else { + (void)getLong(s); + /* The uncompressed length returned by above getlong() may be + * different from s->out in case of concatenated .gz files. + * Check for such files: + */ + check_header(s); + if (s->z_err == Z_OK) { + inflateReset(&(s->stream)); + s->crc = crc32(0L, Z_NULL, 0); + } + } + } + if (s->z_err != Z_OK || s->z_eof) break; + } + s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); + + return (int)(len - s->stream.avail_out); +} + + +/* =========================================================================== + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ +int ZEXPORT gzgetc(file) + gzFile file; +{ + unsigned char c; + + return gzread(file, &c, 1) == 1 ? c : -1; +} + + +/* =========================================================================== + Push one byte back onto the stream. +*/ +int ZEXPORT gzungetc(c, file) + int c; + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; + s->back = c; + s->out--; + s->last = (s->z_err == Z_STREAM_END); + if (s->last) s->z_err = Z_OK; + s->z_eof = 0; + return c; +} + + +/* =========================================================================== + Reads bytes from the compressed file until len-1 characters are + read, or a newline character is read and transferred to buf, or an + end-of-file condition is encountered. The string is then terminated + with a null character. + gzgets returns buf, or Z_NULL in case of error. + + The current implementation is not optimized at all. +*/ +char * ZEXPORT gzgets(file, buf, len) + gzFile file; + char *buf; + int len; +{ + char *b = buf; + if (buf == Z_NULL || len <= 0) return Z_NULL; + + while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; + *buf = '\0'; + return b == buf && len > 0 ? Z_NULL : b; +} + + +#ifndef NO_GZCOMPRESS +/* =========================================================================== + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of bytes actually written (0 in case of error). +*/ +int ZEXPORT gzwrite (file, buf, len) + gzFile file; + voidpc buf; + unsigned len; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.next_in = (Bytef*)buf; + s->stream.avail_in = len; + + while (s->stream.avail_in != 0) { + + if (s->stream.avail_out == 0) { + + s->stream.next_out = s->outbuf; + if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { + s->z_err = Z_ERRNO; + break; + } + s->stream.avail_out = Z_BUFSIZE; + } + s->in += s->stream.avail_in; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), Z_NO_FLUSH); + s->in -= s->stream.avail_in; + s->out -= s->stream.avail_out; + if (s->z_err != Z_OK) break; + } + s->crc = crc32(s->crc, (const Bytef *)buf, len); + + return (int)(len - s->stream.avail_in); +} + + +/* =========================================================================== + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). +*/ +#ifdef STDC +#include + +int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) +{ + char buf[Z_PRINTF_BUFSIZE]; + va_list va; + int len; + + buf[sizeof(buf) - 1] = 0; + va_start(va, format); +#ifdef NO_vsnprintf +# ifdef HAS_vsprintf_void + (void)vsprintf(buf, format, va); + va_end(va); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = vsprintf(buf, format, va); + va_end(va); +# endif +#else +# ifdef HAS_vsnprintf_void + (void)vsnprintf(buf, sizeof(buf), format, va); + va_end(va); + len = strlen(buf); +# else + len = vsnprintf(buf, sizeof(buf), format, va); + va_end(va); +# endif +#endif + if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, (unsigned)len); +} +#else /* not ANSI C */ + +int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; + const char *format; + int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +{ + char buf[Z_PRINTF_BUFSIZE]; + int len; + + buf[sizeof(buf) - 1] = 0; +#ifdef NO_snprintf +# ifdef HAS_sprintf_void + sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < sizeof(buf); len++) + if (buf[len] == 0) break; +# else + len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#else +# ifdef HAS_snprintf_void + snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen(buf); +# else + len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +# endif +#endif + if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) + return 0; + return gzwrite(file, buf, len); +} +#endif + +/* =========================================================================== + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ +int ZEXPORT gzputc(file, c) + gzFile file; + int c; +{ + unsigned char cc = (unsigned char) c; /* required for big endian systems */ + + return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; +} + + +/* =========================================================================== + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ +int ZEXPORT gzputs(file, s) + gzFile file; + const char *s; +{ + return gzwrite(file, (char*)s, (unsigned)strlen(s)); +} + + +/* =========================================================================== + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. +*/ +local int do_flush (file, flush) + gzFile file; + int flush; +{ + uInt len; + int done = 0; + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; + + s->stream.avail_in = 0; /* should be zero already anyway */ + + for (;;) { + len = Z_BUFSIZE - s->stream.avail_out; + + if (len != 0) { + if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { + s->z_err = Z_ERRNO; + return Z_ERRNO; + } + s->stream.next_out = s->outbuf; + s->stream.avail_out = Z_BUFSIZE; + } + if (done) break; + s->out += s->stream.avail_out; + s->z_err = deflate(&(s->stream), flush); + s->out -= s->stream.avail_out; + + /* Ignore the second of two consecutive flushes: */ + if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); + + if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; + } + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} + +int ZEXPORT gzflush (file, flush) + gzFile file; + int flush; +{ + gz_stream *s = (gz_stream*)file; + int err = do_flush (file, flush); + + if (err) return err; + fflush(s->file); + return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; +} +#endif /* NO_GZCOMPRESS */ + +/* =========================================================================== + Sets the starting position for the next gzread or gzwrite on the given + compressed file. The offset represents a number of bytes in the + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error. + SEEK_END is not implemented, returns error. + In this version of the library, gzseek can be extremely slow. +*/ +z_off_t ZEXPORT gzseek (file, offset, whence) + gzFile file; + z_off_t offset; + int whence; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || whence == SEEK_END || + s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { + return -1L; + } + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return -1L; +#else + if (whence == SEEK_SET) { + offset -= s->in; + } + if (offset < 0) return -1L; + + /* At this point, offset is the number of zero bytes to write. */ + if (s->inbuf == Z_NULL) { + s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ + if (s->inbuf == Z_NULL) return -1L; + zmemzero(s->inbuf, Z_BUFSIZE); + } + while (offset > 0) { + uInt size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (uInt)offset; + + size = gzwrite(file, s->inbuf, size); + if (size == 0) return -1L; + + offset -= size; + } + return s->in; +#endif + } + /* Rest of function is for reading only */ + + /* compute absolute position */ + if (whence == SEEK_CUR) { + offset += s->out; + } + if (offset < 0) return -1L; + + if (s->transparent) { + /* map to fseek */ + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; + + s->in = s->out = offset; + return offset; + } + + /* For a negative seek, rewind and use positive seek */ + if (offset >= s->out) { + offset -= s->out; + } else if (gzrewind(file) < 0) { + return -1L; + } + /* offset is now the number of bytes to skip. */ + + if (offset != 0 && s->outbuf == Z_NULL) { + s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); + if (s->outbuf == Z_NULL) return -1L; + } + if (offset && s->back != EOF) { + s->back = EOF; + s->out++; + offset--; + if (s->last) s->z_err = Z_STREAM_END; + } + while (offset > 0) { + int size = Z_BUFSIZE; + if (offset < Z_BUFSIZE) size = (int)offset; + + size = gzread(file, s->outbuf, (uInt)size); + if (size <= 0) return -1L; + offset -= size; + } + return s->out; +} + +/* =========================================================================== + Rewinds input file. +*/ +int ZEXPORT gzrewind (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL || s->mode != 'r') return -1; + + s->z_err = Z_OK; + s->z_eof = 0; + s->back = EOF; + s->stream.avail_in = 0; + s->stream.next_in = s->inbuf; + s->crc = crc32(0L, Z_NULL, 0); + if (!s->transparent) (void)inflateReset(&s->stream); + s->in = 0; + s->out = 0; + return fseek(s->file, s->start, SEEK_SET); +} + +/* =========================================================================== + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. +*/ +z_off_t ZEXPORT gztell (file) + gzFile file; +{ + return gzseek(file, 0L, SEEK_CUR); +} + +/* =========================================================================== + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ +int ZEXPORT gzeof (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + /* With concatenated compressed files that can have embedded + * crc trailers, z_eof is no longer the only/best indicator of EOF + * on a gz_stream. Handle end-of-stream error explicitly here. + */ + if (s == NULL || s->mode != 'r') return 0; + if (s->z_eof) return 1; + return s->z_err == Z_STREAM_END; +} + +/* =========================================================================== + Outputs a long in LSB order to the given file +*/ +local void putLong (file, x) + FILE *file; + uLong x; +{ + int n; + for (n = 0; n < 4; n++) { + fputc((int)(x & 0xff), file); + x >>= 8; + } +} + +/* =========================================================================== + Reads a long in LSB order from the given gz_stream. Sets z_err in case + of error. +*/ +local uLong getLong (s) + gz_stream *s; +{ + uLong x = (uLong)get_byte(s); + int c; + + x += ((uLong)get_byte(s))<<8; + x += ((uLong)get_byte(s))<<16; + c = get_byte(s); + if (c == EOF) s->z_err = Z_DATA_ERROR; + x += ((uLong)c)<<24; + return x; +} + +/* =========================================================================== + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. +*/ +int ZEXPORT gzclose (file) + gzFile file; +{ + int err; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return Z_STREAM_ERROR; + + if (s->mode == 'w') { +#ifdef NO_GZCOMPRESS + return Z_STREAM_ERROR; +#else + err = do_flush (file, Z_FINISH); + if (err != Z_OK) return destroy((gz_stream*)file); + + putLong (s->file, s->crc); + putLong (s->file, (uLong)(s->in & 0xffffffff)); +#endif + } + return destroy((gz_stream*)file); +} + +/* =========================================================================== + Returns the error message for the last error which occured on the + given compressed file. errnum is set to zlib error number. If an + error occured in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ +const char * ZEXPORT gzerror (file, errnum) + gzFile file; + int *errnum; +{ + char *m; + gz_stream *s = (gz_stream*)file; + + if (s == NULL) { + *errnum = Z_STREAM_ERROR; + return (const char*)ERR_MSG(Z_STREAM_ERROR); + } + *errnum = s->z_err; + if (*errnum == Z_OK) return (const char*)""; + + m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); + + if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); + + TRYFREE(s->msg); + s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); + if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); + strcpy(s->msg, s->path); + strcat(s->msg, ": "); + strcat(s->msg, m); + return (const char*)s->msg; +} + +/* =========================================================================== + Clear the error and end-of-file flags, and do the same for the real file. +*/ +void ZEXPORT gzclearerr (file) + gzFile file; +{ + gz_stream *s = (gz_stream*)file; + + if (s == NULL) return; + if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; + s->z_eof = 0; + /* klibc hack */ + /* clearerr(s->file); */ +} diff --git a/klibc/klibc/zlib/infback.c b/klibc/klibc/zlib/infback.c new file mode 100644 index 0000000000..110b03b857 --- /dev/null +++ b/klibc/klibc/zlib/infback.c @@ -0,0 +1,619 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); + +/* + strm provides memory allocation functions in zalloc and zfree, or + Z_NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + */ +int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) +z_stream FAR *strm; +int windowBits; +unsigned char FAR *window; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (voidpf)state; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->write = 0; + state->whave = 0; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +/* Macros for inflateBack(): */ + +/* Load returned state from inflate_fast() */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Set state from registers for inflate_fast() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflateBack() with + an error. */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is Z_NULL or the state was not initialized. + */ +int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) +z_stream FAR *strm; +in_func in; +void FAR *in_desc; +out_func out; +void FAR *out_desc; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + + /* process literal */ + if (this.op == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + + /* get distance extra bits, if any */ + state->extra = (unsigned)(this.op) & 15; + if (state->extra != 0) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? + left : 0)) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } + else { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Return unused input */ + inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int ZEXPORT inflateBackEnd(strm) +z_stream FAR *strm; +{ + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/klibc/klibc/zlib/inffast.c b/klibc/klibc/zlib/inffast.c new file mode 100644 index 0000000000..c716440a92 --- /dev/null +++ b/klibc/klibc/zlib/inffast.c @@ -0,0 +1,305 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifndef ASMINF + +/* Allow machine dependent optimization for post-increment or pre-increment. + Based on testing to date, + Pre-increment preferred for: + - PowerPC G3 (Adler) + - MIPS R5000 (Randers-Pehrson) + Post-increment preferred for: + - none + No measurable difference: + - Pentium III (Anderson) + - 68060 (Nikl) + */ +#ifdef POSTINC +# define OFF 0 +# define PUP(a) *(a)++ +#else +# define OFF 1 +# define PUP(a) *++(a) +#endif + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= 6 + strm->avail_out >= 258 + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void inflate_fast(strm, start) +z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ +{ + struct inflate_state FAR *state; + unsigned char FAR *in; /* local strm->next_in */ + unsigned char FAR *last; /* while in < last, enough input available */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code this; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ + + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); + wsize = state->wsize; + whave = state->whave; + write = state->write; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = lcode[hold & lmask]; + dolen: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op == 0) { /* literal */ + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + PUP(out) = (unsigned char)(this.val); + } + else if (op & 16) { /* length base */ + len = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (op) { + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + this = dcode[hold & dmask]; + dodist: + op = (unsigned)(this.bits); + hold >>= op; + bits -= op; + op = (unsigned)(this.op); + if (op & 16) { /* distance base */ + dist = (unsigned)(this.val); + op &= 15; /* number of extra bits */ + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + from = window - OFF; + if (write == 0) { /* very common case */ + from += wsize - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (write < op) { /* wrap around window */ + from += wsize + write - op; + op -= write; + if (op < len) { /* some from end of window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (write < len) { /* some from start of window */ + op = write; + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else { /* contiguous in window */ + from += write - op; + if (op < len) { /* some from window */ + len -= op; + do { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else { + from = out - dist; /* copy direct from output */ + do { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) { /* 2nd level distance code */ + this = dcode[this.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) { /* 2nd level length code */ + this = lcode[this.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; + + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? + 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and write == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ + +#endif /* !ASMINF */ diff --git a/klibc/klibc/zlib/inffast.h b/klibc/klibc/zlib/inffast.h new file mode 100644 index 0000000000..1e88d2d97b --- /dev/null +++ b/klibc/klibc/zlib/inffast.h @@ -0,0 +1,11 @@ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/klibc/klibc/zlib/inffixed.h b/klibc/klibc/zlib/inffixed.h new file mode 100644 index 0000000000..75ed4b5978 --- /dev/null +++ b/klibc/klibc/zlib/inffixed.h @@ -0,0 +1,94 @@ + /* inffixed.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + + /* WARNING: this file should *not* be used by applications. It + is part of the implementation of the compression library and + is subject to change. Applications should only use zlib.h. + */ + + static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} + }; + + static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} + }; diff --git a/klibc/klibc/zlib/inflate.c b/klibc/klibc/zlib/inflate.c new file mode 100644 index 0000000000..a53b5c7446 --- /dev/null +++ b/klibc/klibc/zlib/inflate.c @@ -0,0 +1,1270 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * Change history: + * + * 1.2.beta0 24 Nov 2002 + * - First version -- complete rewrite of inflate to simplify code, avoid + * creation of window when not needed, minimize use of window when it is + * needed, make inffast.c even faster, implement gzip decoding, and to + * improve code readability and style over the previous zlib inflate code + * + * 1.2.beta1 25 Nov 2002 + * - Use pointers for available input and output checking in inffast.c + * - Remove input and output counters in inffast.c + * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 + * - Remove unnecessary second byte pull from length extra in inffast.c + * - Unroll direct copy to three copies per loop in inffast.c + * + * 1.2.beta2 4 Dec 2002 + * - Change external routine names to reduce potential conflicts + * - Correct filename to inffixed.h for fixed tables in inflate.c + * - Make hbuf[] unsigned char to match parameter type in inflate.c + * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) + * to avoid negation problem on Alphas (64 bit) in inflate.c + * + * 1.2.beta3 22 Dec 2002 + * - Add comments on state->bits assertion in inffast.c + * - Add comments on op field in inftrees.h + * - Fix bug in reuse of allocated window after inflateReset() + * - Remove bit fields--back to byte structure for speed + * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths + * - Change post-increments to pre-increments in inflate_fast(), PPC biased? + * - Add compile time option, POSTINC, to use post-increments instead (Intel?) + * - Make MATCH copy in inflate() much faster for when inflate_fast() not used + * - Use local copies of stream next and avail values, as well as local bit + * buffer and bit count in inflate()--for speed when inflate_fast() not used + * + * 1.2.beta4 1 Jan 2003 + * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings + * - Move a comment on output buffer sizes from inffast.c to inflate.c + * - Add comments in inffast.c to introduce the inflate_fast() routine + * - Rearrange window copies in inflate_fast() for speed and simplification + * - Unroll last copy for window match in inflate_fast() + * - Use local copies of window variables in inflate_fast() for speed + * - Pull out common write == 0 case for speed in inflate_fast() + * - Make op and len in inflate_fast() unsigned for consistency + * - Add FAR to lcode and dcode declarations in inflate_fast() + * - Simplified bad distance check in inflate_fast() + * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new + * source file infback.c to provide a call-back interface to inflate for + * programs like gzip and unzip -- uses window as output buffer to avoid + * window copying + * + * 1.2.beta5 1 Jan 2003 + * - Improved inflateBack() interface to allow the caller to provide initial + * input in strm. + * - Fixed stored blocks bug in inflateBack() + * + * 1.2.beta6 4 Jan 2003 + * - Added comments in inffast.c on effectiveness of POSTINC + * - Typecasting all around to reduce compiler warnings + * - Changed loops from while (1) or do {} while (1) to for (;;), again to + * make compilers happy + * - Changed type of window in inflateBackInit() to unsigned char * + * + * 1.2.beta7 27 Jan 2003 + * - Changed many types to unsigned or unsigned short to avoid warnings + * - Added inflateCopy() function + * + * 1.2.0 9 Mar 2003 + * - Changed inflateBack() interface to provide separate opaque descriptors + * for the in() and out() functions + * - Changed inflateBack() argument and in_func typedef to swap the length + * and buffer address return values for the input function + * - Check next_in and next_out for Z_NULL on entry to inflate() + * + * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. + */ + +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inffast.h" + +#ifdef MAKEFIXED +# ifndef BUILDFIXED +# define BUILDFIXED +# endif +#endif + +/* function prototypes */ +local void fixedtables OF((struct inflate_state FAR *state)); +local int updatewindow OF((z_streamp strm, unsigned out)); +#ifdef BUILDFIXED + void makefixed OF((void)); +#endif +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, + unsigned len)); + +int ZEXPORT inflateReset(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->wsize = 0; + state->whave = 0; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) +z_streamp strm; +int windowBits; +const char *version; +int stream_size; +{ + struct inflate_state FAR *state; + + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) { + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; + } + if (strm->zfree == (free_func)0) strm->zfree = zcfree; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (voidpf)state; + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { + ZFREE(strm, state); + strm->state = Z_NULL; + return Z_STREAM_ERROR; + } + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); +} + +int ZEXPORT inflateInit_(strm, version, stream_size) +z_streamp strm; +const char *version; +int stream_size; +{ + return inflateInit2_(strm, DEF_WBITS, version, stream_size); +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. Normally this returns fixed tables from inffixed.h. + If BUILDFIXED is defined, then instead this routine builds the tables the + first time it's called, and returns those tables the first time and + thereafter. This reduces the size of the code by about 2K bytes, in + exchange for a little execution time. However, BUILDFIXED should not be + used for threaded applications, since the rewriting of the tables and virgin + may not be thread-safe. + */ +local void fixedtables(state) +struct inflate_state FAR *state; +{ +#ifdef BUILDFIXED + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; + + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) { + unsigned sym, bits; + static code *next; + + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + /* do this just once */ + virgin = 0; + } +#else /* !BUILDFIXED */ +# include "inffixed.h" +#endif /* BUILDFIXED */ + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +#ifdef MAKEFIXED +#include + +/* + Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also + defines BUILDFIXED, so the tables are built on the fly. makefixed() writes + those tables to stdout, which would be piped to inffixed.h. A small program + can simply call makefixed to do this: + + void makefixed(void); + + int main(void) + { + makefixed(); + return 0; + } + + Then that can be linked with zlib built with MAKEFIXED defined and run: + + a.out > inffixed.h + */ +void makefixed() +{ + unsigned low, size; + struct inflate_state state; + + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); +} +#endif /* MAKEFIXED */ + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +local int updatewindow(strm, out) +z_streamp strm; +unsigned out; +{ + struct inflate_state FAR *state; + unsigned copy, dist; + + state = (struct inflate_state FAR *)strm->state; + + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->write = 0; + state->whave = 0; + } + + /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; + if (copy >= state->wsize) { + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); + state->write = 0; + state->whave = state->wsize; + } + else { + dist = state->wsize - state->write; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->write, strm->next_out - copy, dist); + copy -= dist; + if (copy) { + zmemcpy(state->window, strm->next_out - copy, copy); + state->write = copy; + state->whave = state->wsize; + } + else { + state->write += dist; + if (state->write == state->wsize) state->write = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; +} + +/* Macros for inflate(): */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflate() + if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) + +/* Assure that there are at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + ((unsigned)hold & ((1U << (n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int ZEXPORT inflate(strm, flush) +z_streamp strm; +int flush; +{ + struct inflate_state FAR *state; + unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code this; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + if (BITS(4) + 8 > state->wbits) { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) copy = have; + if (copy) { + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + } while (len && copy < have); + if (state->flags & 0x02000) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + } while (len && copy < have); + if (state->flags & 0x02000) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = REVERSE(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK) goto inf_leave; + case TYPEDO: + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) { + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; + } + else { + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); + if (state->have == 0) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else { + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } + + /* build code tables */ + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + break; + } + for (;;) { + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if (this.op && (this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", this.val)); + state->mode = LIT; + break; + } + if (this.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + if (this.op & 64) { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(this.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->mode = DIST; + case DIST: + for (;;) { + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; + PULLBYTE(); + } + if ((this.op & 0xf0) == 0) { + last = this; + for (;;) { + this = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + this.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(this.bits); + if (this.op & 64) { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->write) { + copy -= state->write; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->write - copy); + if (copy > state->length) copy = state->length; + } + else { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( +#ifdef GUNZIP + state->flags ? hold : +#endif + REVERSE(hold)) != state->check) { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int ZEXPORT inflateEnd(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) +z_streamp strm; +const Bytef *dictionary; +uInt dictLength; +{ + struct inflate_state FAR *state; + unsigned long id; + + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->mode != DICT) return Z_STREAM_ERROR; + + /* check for correct dictionary id */ + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) return Z_DATA_ERROR; + + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +local unsigned syncsearch(have, buf, len) +unsigned FAR *have; +unsigned char FAR *buf; +unsigned len; +{ + unsigned got; + unsigned next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int ZEXPORT inflateSync(strm) +z_streamp strm; +{ + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; + + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; out = strm->total_out; + inflateReset(strm); + strm->total_in = in; strm->total_out = out; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int ZEXPORT inflateSyncPoint(strm) +z_streamp strm; +{ + struct inflate_state FAR *state; + + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int ZEXPORT inflateCopy(dest, source) +z_streamp dest; +z_streamp source; +{ + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; + + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + *dest = *source; + *copy = *state; + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) + zmemcpy(window, state->window, 1U << state->wbits); + copy->window = window; + dest->state = (voidpf)copy; + return Z_OK; +} diff --git a/klibc/klibc/zlib/inflate.h b/klibc/klibc/zlib/inflate.h new file mode 100644 index 0000000000..9a12c8fd29 --- /dev/null +++ b/klibc/klibc/zlib/inflate.h @@ -0,0 +1,117 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer decoding by inflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip decoding + should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD, /* i: waiting for magic header */ +#ifdef GUNZIP + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ +#endif + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN, /* i: waiting for length/lit code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ +#ifdef GUNZIP + LENGTH, /* i: waiting for 32-bit length (gzip) */ +#endif + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to the BAD or MEM mode -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME + NAME -> COMMENT -> HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + Read deflate blocks: + TYPE -> STORED or TABLE or LEN or CHECK + STORED -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN + Read deflate codes: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* state maintained between inflate() calls. Approximately 7K bytes. */ +struct inflate_state { + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned write; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ +}; diff --git a/klibc/klibc/zlib/inftrees.c b/klibc/klibc/zlib/inftrees.c new file mode 100644 index 0000000000..3bb56398e1 --- /dev/null +++ b/klibc/klibc/zlib/inftrees.c @@ -0,0 +1,321 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zutil.h" +#include "inftrees.h" + +#define MAXBITS 15 + +const char inflate_copyright[] = + " inflate 1.2.1 Copyright 1995-2003 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int inflate_table(type, lens, codes, table, bits, work) +codetype type; +unsigned short FAR *lens; +unsigned codes; +code FAR * FAR *table; +unsigned FAR *bits; +unsigned short FAR *work; +{ + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code this; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS+1]; /* number of codes of each length */ + unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 76, 66}; + static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) return -1; /* no codes! */ + for (min = 1; min <= MAXBITS; min++) + if (count[min] != 0) break; + if (root < min) root = min; + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || (codes - count[0] != 1))) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked when a LENS table is being made + against the space in *table, ENOUGH, minus the maximum space needed by + the worst case distance code, MAXD. This should never happen, but the + sufficiency of ENOUGH has not been proven exhaustively, hence the check. + This assumes that when type == LENS, bits == 9. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + this.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) { + this.op = (unsigned char)0; + this.val = work[sym]; + } + else if ((int)(work[sym]) > end) { + this.op = (unsigned char)(extra[work[sym]]); + this.val = base[work[sym]]; + } + else { + this.op = (unsigned char)(32 + 64); /* end of block */ + this.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + do { + fill -= incr; + next[(huff >> drop) + fill] = this; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += 1U << curr; + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if (type == LENS && used >= ENOUGH - MAXD) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } + + /* + Fill in rest of table for incomplete codes. This loop is similar to the + loop above in incrementing huff for table indices. It is assumed that + len is equal to curr + drop, so there is no loop needed to increment + through high index bits. When the current sub-table is filled, the loop + drops back to the root table to fill in any remaining entries there. + */ + this.op = (unsigned char)64; /* invalid code marker */ + this.bits = (unsigned char)(len - drop); + this.val = (unsigned short)0; + while (huff != 0) { + /* when done with sub-table, drop back to root table */ + if (drop != 0 && (huff & mask) != low) { + drop = 0; + len = root; + next = *table; + curr = root; + this.bits = (unsigned char)len; + } + + /* put invalid code marker in table */ + next[huff >> drop] = this; + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/klibc/klibc/zlib/inftrees.h b/klibc/klibc/zlib/inftrees.h new file mode 100644 index 0000000000..82d365a7e9 --- /dev/null +++ b/klibc/klibc/zlib/inftrees.h @@ -0,0 +1,55 @@ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2003 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of dynamic tree. The maximum found in a long but non- + exhaustive search was 1004 code structures (850 for length/literals + and 154 for distances, the latter actually the result of an + exhaustive search). The true maximum is not known, but the value + below is more than safe. */ +#define ENOUGH 1440 +#define MAXD 154 + +/* Type of code to build for inftable() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +extern int inflate_table OF((codetype type, unsigned short FAR *lens, + unsigned codes, code FAR * FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/klibc/klibc/zlib/trees.c b/klibc/klibc/zlib/trees.c new file mode 100644 index 0000000000..f7748c4dcc --- /dev/null +++ b/klibc/klibc/zlib/trees.c @@ -0,0 +1,1215 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2003 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +/* @(#) $Id: trees.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +/* #define GEN_TREES_H */ + +#include "deflate.h" + +#ifdef DEBUG +# include +#endif + +/* =========================================================================== + * Constants + */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +local const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +local const uch bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +#define Buf_size (8 * 2*sizeof(char)) +/* Number of bits used within bi_buf. (bi_buf might be implemented on + * more than 16 bits on some systems.) + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ + +#if defined(GEN_TREES_H) || !defined(STDC) +/* non ANSI compilers may not accept trees.h */ + +local ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see _tr_init + * below). + */ + +local ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use + * 5 bits.) + */ + +uch _dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances + * 3 .. 258, the last 256 values correspond to the top 8 bits of + * the 15 bit distances. + */ + +uch _length_code[MAX_MATCH-MIN_MATCH+1]; +/* length code for each normalized match length (0 == MIN_MATCH) */ + +local int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = MIN_MATCH) */ + +local int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + +#else +# include "trees.h" +#endif /* GEN_TREES_H */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ +}; + +local static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +local static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +local static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +local void tr_static_init OF((void)); +local void init_block OF((deflate_state *s)); +local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); +local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state *s, tree_desc *desc)); +local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state *s)); +local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state *s, ct_data *ltree, + ct_data *dtree)); +local void set_data_type OF((deflate_state *s)); +local unsigned bi_reverse OF((unsigned value, int length)); +local void bi_windup OF((deflate_state *s)); +local void bi_flush OF((deflate_state *s)); +local void copy_block OF((deflate_state *s, charf *buf, unsigned len, + int header)); + +#ifdef GEN_TREES_H +local void gen_trees_header OF((void)); +#endif + +#ifndef DEBUG +# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) + /* Send a code of the given tree. c and tree must not have side effects */ + +#else /* DEBUG */ +# define send_code(s, c, tree) \ + { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ + send_bits(s, tree[c].Code, tree[c].Len); } +#endif + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pendingBuf. + */ +#define put_short(s, w) { \ + put_byte(s, (uch)((w) & 0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ +} + +/* =========================================================================== + * Send a value on a given number of bits. + * IN assertion: length <= 16 and value fits in length bits. + */ +#ifdef DEBUG +local void send_bits OF((deflate_state *s, int value, int length)); + +local void send_bits(s, value, length) + deflate_state *s; + int value; /* value to send */ + int length; /* number of bits */ +{ + Tracevv((stderr," l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; + + /* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) + * unused bits in value. + */ + if (s->bi_valid > (int)Buf_size - length) { + s->bi_buf |= (value << s->bi_valid); + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } else { + s->bi_buf |= value << s->bi_valid; + s->bi_valid += length; + } +} +#else /* !DEBUG */ + +#define send_bits(s, value, length) \ +{ int len = length;\ + if (s->bi_valid > (int)Buf_size - len) {\ + int val = value;\ + s->bi_buf |= (val << s->bi_valid);\ + put_short(s, s->bi_buf);\ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ + s->bi_valid += len - Buf_size;\ + } else {\ + s->bi_buf |= (value) << s->bi_valid;\ + s->bi_valid += len;\ + }\ +} +#endif /* DEBUG */ + + +/* the arguments must not have side effects */ + +/* =========================================================================== + * Initialize the various 'constant' tables. + */ +local void tr_static_init() +{ +#if defined(GEN_TREES_H) || !defined(STDC) + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + if (static_init_done) return; + + /* For some embedded targets, global variables are not initialized: */ + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1< dist code (0..29) */ + dist = 0; + for (code = 0 ; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert (dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the + * tree construction to get a canonical Huffman tree (longest code + * all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; + +# ifdef GEN_TREES_H + gen_trees_header(); +# endif +#endif /* defined(GEN_TREES_H) || !defined(STDC) */ +} + +/* =========================================================================== + * Genererate the file trees.h describing the static trees. + */ +#ifdef GEN_TREES_H +# ifndef DEBUG +# include +# endif + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +void gen_trees_header() +{ + FILE *header = fopen("trees.h", "w"); + int i; + + Assert (header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); + + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); + } + + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES-1, 10)); + } + + fclose(header); +} +#endif /* GEN_TREES_H */ + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void _tr_init(s) + deflate_state *s; +{ + tr_static_init(); + + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; + s->last_eob_len = 8; /* enough lookahead for inflate */ +#ifdef DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +local void init_block(s) + deflate_state *s; +{ + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +local void pqdownheap(s, tree, k) + deflate_state *s; + ct_data *tree; /* the tree to restore */ + int k; /* node to move down */ +{ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +local void gen_bitlen(s, desc) + deflate_state *s; + tree_desc *desc; /* the tree descriptor */ +{ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max+1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) continue; /* not a leaf node */ + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; + + Trace((stderr,"\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length-1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) continue; + if (tree[m].Len != (unsigned) bits) { + Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) + *(long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +local void gen_codes (tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ + int max_code; /* largest code with non zero frequency */ + ushf *bl_count; /* number of codes at each bit length */ +{ + ush next_code[MAX_BITS+1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + next_code[bits] = code = (code + bl_count[bits-1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0, s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes ((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +local void scan_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code+1].Len = (ush)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +local void send_tree (s, tree, max_code) + deflate_state *s; + ct_data *tree; /* the tree to be scanned */ + int max_code; /* and its largest code of non zero frequency */ +{ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { send_code(s, curlen, s->bl_tree); } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree); count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); + + } else { + send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); + } + count = 0; prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +local int build_bl_tree(s) + deflate_state *s; +{ + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*(max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +local void send_all_trees(s, lcodes, dcodes, blcodes) + deflate_state *s; + int lcodes, dcodes, blcodes; /* number of codes for each tree */ +{ + int rank; /* index in bl_order */ + + Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5); + send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void _tr_stored_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ +#ifdef DEBUG + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; +#endif + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + * The current inflate code requires 9 bits of lookahead. If the + * last two codes for the previous block (real code plus EOB) were coded + * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode + * the last real code. In this case we send two empty static blocks instead + * of one. (There are no problems if the previous block is stored or fixed.) + * To simplify the code, we assume the worst case of last real code encoded + * on one bit only. + */ +void _tr_align(s) + deflate_state *s; +{ + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ +#endif + bi_flush(s); + /* Of the 10 bits for the empty block, we have already sent + * (10 - bi_valid) bits. The lookahead for the last real code (before + * the EOB of the previous block) was thus at least one plus the length + * of the EOB plus what we have just sent of the empty static block. + */ + if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { + send_bits(s, STATIC_TREES<<1, 3); + send_code(s, END_BLOCK, static_ltree); +#ifdef DEBUG + s->compressed_len += 10L; +#endif + bi_flush(s); + } + s->last_eob_len = 7; +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and output the encoded block to the zip file. + */ +void _tr_flush_block(s, buf, stored_len, eof) + deflate_state *s; + charf *buf; /* input block, or NULL if too old */ + ulg stored_len; /* length of input block */ + int eof; /* true if this is the last block for a file */ +{ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) { + + /* Check if the file is ascii or binary */ + if (s->data_type == Z_UNKNOWN) set_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7)>>3; + static_lenb = (s->static_len+3+7)>>3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); + + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + + } else { + Assert(buf != (char*)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + +#ifdef FORCE_STORED + if (buf != (char*)0) { /* force stored block */ +#else + if (stored_len+4 <= opt_lenb && buf != (char*)0) { + /* 4: two words for the lengths */ +#endif + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + _tr_stored_block(s, buf, stored_len, eof); + +#ifdef FORCE_STATIC + } else if (static_lenb >= 0) { /* force static trees */ +#else + } else if (static_lenb == opt_lenb) { +#endif + send_bits(s, (STATIC_TREES<<1)+eof, 3); + compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->static_len; +#endif + } else { + send_bits(s, (DYN_TREES<<1)+eof, 3); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, + max_blindex+1); + compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +#ifdef DEBUG + s->compressed_len += 3 + s->opt_len; +#endif + } + Assert (s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and uLong implemented on 32 bits. + */ + init_block(s); + + if (eof) { + bi_windup(s); +#ifdef DEBUG + s->compressed_len += 7; /* align on byte boundary */ +#endif + } + Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, + s->compressed_len-7*eof)); +} + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ +int _tr_tally (s, dist, lc) + deflate_state *s; + unsigned dist; /* distance of matched string */ + unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +{ + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } else { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + + s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } + +#ifdef TRUNCATE_BLOCK + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit*8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L+extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length*100L/in_length)); + if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; + } +#endif + return (s->last_lit == s->lit_bufsize-1); + /* We avoid equality with lit_bufsize because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +local void compress_block(s, ltree, dtree) + deflate_state *s; + ct_data *ltree; /* literal tree */ + ct_data *dtree; /* distance tree */ +{ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ + + if (s->last_lit != 0) do { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr," '%c' ", lc)); + } else { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code+LITERALS+1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert (code < D_CODES, "bad d_code"); + + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, + "pendingBuf overflow"); + + } while (lx < s->last_lit); + + send_code(s, END_BLOCK, ltree); + s->last_eob_len = ltree[END_BLOCK].Len; +} + +/* =========================================================================== + * Set the data type to ASCII or BINARY, using a crude approximation: + * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. + * IN assertion: the fields freq of dyn_ltree are set and the total of all + * frequencies does not exceed 64K (to fit in an int on 16 bit machines). + */ +local void set_data_type(s) + deflate_state *s; +{ + int n = 0; + unsigned ascii_freq = 0; + unsigned bin_freq = 0; + while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; + while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; + while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; + s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); +} + +/* =========================================================================== + * Reverse the first len bits of a code, using straightforward code (a faster + * method would use a table) + * IN assertion: 1 <= len <= 15 + */ +local unsigned bi_reverse(code, len) + unsigned code; /* the value to invert */ + int len; /* its bit length */ +{ + register unsigned res = 0; + do { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +local void bi_flush(s) + deflate_state *s; +{ + if (s->bi_valid == 16) { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else if (s->bi_valid >= 8) { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } +} + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +local void bi_windup(s) + deflate_state *s; +{ + if (s->bi_valid > 8) { + put_short(s, s->bi_buf); + } else if (s->bi_valid > 0) { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef DEBUG + s->bits_sent = (s->bits_sent+7) & ~7; +#endif +} + +/* =========================================================================== + * Copy a stored block, storing first the length and its + * one's complement if requested. + */ +local void copy_block(s, buf, len, header) + deflate_state *s; + charf *buf; /* the input data */ + unsigned len; /* its length */ + int header; /* true if block header must be written */ +{ + bi_windup(s); /* align on byte boundary */ + s->last_eob_len = 8; /* enough lookahead for inflate */ + + if (header) { + put_short(s, (ush)len); + put_short(s, (ush)~len); +#ifdef DEBUG + s->bits_sent += 2*16; +#endif + } +#ifdef DEBUG + s->bits_sent += (ulg)len<<3; +#endif + while (len--) { + put_byte(s, *buf++); + } +} diff --git a/klibc/klibc/zlib/trees.h b/klibc/klibc/zlib/trees.h new file mode 100644 index 0000000000..72facf900f --- /dev/null +++ b/klibc/klibc/zlib/trees.h @@ -0,0 +1,128 @@ +/* header created automatically with -DGEN_TREES_H */ + +local const ct_data static_ltree[L_CODES+2] = { +{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, +{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, +{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, +{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, +{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, +{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, +{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, +{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, +{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, +{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, +{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, +{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, +{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, +{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, +{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, +{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, +{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, +{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, +{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, +{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, +{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, +{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, +{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, +{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, +{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, +{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, +{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, +{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, +{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, +{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, +{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, +{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, +{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, +{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, +{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, +{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, +{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, +{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, +{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, +{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, +{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, +{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, +{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, +{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, +{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, +{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, +{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, +{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, +{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, +{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, +{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, +{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, +{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, +{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, +{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, +{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, +{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, +{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} +}; + +local const ct_data static_dtree[D_CODES] = { +{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, +{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, +{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, +{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, +{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, +{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} +}; + +const uch _dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +local const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +local const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + diff --git a/klibc/klibc/zlib/uncompr.c b/klibc/klibc/zlib/uncompr.c new file mode 100644 index 0000000000..debee4385e --- /dev/null +++ b/klibc/klibc/zlib/uncompr.c @@ -0,0 +1,61 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: uncompr.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#define ZLIB_INTERNAL +#include "zlib.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted. +*/ +int ZEXPORT uncompress (dest, destLen, source, sourceLen) + Bytef *dest; + uLongf *destLen; + const Bytef *source; + uLong sourceLen; +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + + err = inflateInit(&stream); + if (err != Z_OK) return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} diff --git a/klibc/klibc/zlib/zconf.h b/klibc/klibc/zlib/zconf.h new file mode 100644 index 0000000000..9b74ce7bd4 --- /dev/null +++ b/klibc/klibc/zlib/zconf.h @@ -0,0 +1,323 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflatePrime z_deflatePrime +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +#define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/klibc/klibc/zlib/zconf.in.h b/klibc/klibc/zlib/zconf.in.h new file mode 100644 index 0000000000..d96c85955c --- /dev/null +++ b/klibc/klibc/zlib/zconf.in.h @@ -0,0 +1,323 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zconf.in.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#ifndef ZCONF_H +#define ZCONF_H + +/* + * If you *really* need a unique prefix for all types and library functions, + * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. + */ +#ifdef Z_PREFIX +# define deflateInit_ z_deflateInit_ +# define deflate z_deflate +# define deflateEnd z_deflateEnd +# define inflateInit_ z_inflateInit_ +# define inflate z_inflate +# define inflateEnd z_inflateEnd +# define deflateInit2_ z_deflateInit2_ +# define deflateSetDictionary z_deflateSetDictionary +# define deflateCopy z_deflateCopy +# define deflateReset z_deflateReset +# define deflatePrime z_deflatePrime +# define deflateParams z_deflateParams +# define deflateBound z_deflateBound +# define inflateInit2_ z_inflateInit2_ +# define inflateSetDictionary z_inflateSetDictionary +# define inflateSync z_inflateSync +# define inflateSyncPoint z_inflateSyncPoint +# define inflateCopy z_inflateCopy +# define inflateReset z_inflateReset +# define compress z_compress +# define compress2 z_compress2 +# define compressBound z_compressBound +# define uncompress z_uncompress +# define adler32 z_adler32 +# define crc32 z_crc32 +# define get_crc_table z_get_crc_table + +# define Byte z_Byte +# define uInt z_uInt +# define uLong z_uLong +# define Bytef z_Bytef +# define charf z_charf +# define intf z_intf +# define uIntf z_uIntf +# define uLongf z_uLongf +# define voidpf z_voidpf +# define voidp z_voidp +#endif + +#if defined(__MSDOS__) && !defined(MSDOS) +# define MSDOS +#endif +#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) +# define OS2 +#endif +#if defined(_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +#endif +#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) +# define WIN32 +#endif +#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) +# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +# ifndef SYS16BIT +# define SYS16BIT +# endif +# endif +#endif + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + */ +#ifdef SYS16BIT +# define MAXSEG_64K +#endif +#ifdef MSDOS +# define UNALIGNED_OK +#endif + +#ifdef __STDC_VERSION__ +# ifndef STDC +# define STDC +# endif +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +#endif +#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) +# define STDC +#endif +#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) +# define STDC +#endif +#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) +# define STDC +#endif +#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) +# define STDC +#endif + +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +# define STDC +#endif + +#ifndef STDC +# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +# define const /* note: need a more gentle solution here */ +# endif +#endif + +/* Some Mac compilers merge all .h files incorrectly: */ +#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) +# define NO_DUMMY_DECL +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +/* The following definitions for FAR are needed only for MSDOS mixed + * model programming (small or medium model with some far allocations). + * This was tested only with MSC; for other MSDOS compilers you may have + * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, + * just define FAR to be empty. + */ +#ifdef SYS16BIT +# if defined(M_I86SM) || defined(M_I86MM) + /* MSC small or medium model */ +# define SMALL_MEDIUM +# ifdef _MSC_VER +# define FAR _far +# else +# define FAR far +# endif +# endif +# if (defined(__SMALL__) || defined(__MEDIUM__)) + /* Turbo C small or medium model */ +# define SMALL_MEDIUM +# ifdef __BORLANDC__ +# define FAR _far +# else +# define FAR far +# endif +# endif +#endif + +#if defined(WINDOWS) || defined(WIN32) + /* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +# ifdef ZLIB_DLL +# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +# ifdef ZLIB_INTERNAL +# define ZEXTERN extern __declspec(dllexport) +# else +# define ZEXTERN extern __declspec(dllimport) +# endif +# endif +# endif /* ZLIB_DLL */ + /* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +# ifdef ZLIB_WINAPI +# ifdef FAR +# undef FAR +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define ZEXPORT WINAPI +# ifdef WIN32 +# define ZEXPORTVA WINAPIV +# else +# define ZEXPORTVA FAR CDECL +# endif +# endif +#endif + +#if defined (__BEOS__) +# ifdef ZLIB_DLL +# ifdef ZLIB_INTERNAL +# define ZEXPORT __declspec(dllexport) +# define ZEXPORTVA __declspec(dllexport) +# else +# define ZEXPORT __declspec(dllimport) +# define ZEXPORTVA __declspec(dllimport) +# endif +# endif +#endif + +#ifndef ZEXTERN +# define ZEXTERN extern +#endif +#ifndef ZEXPORT +# define ZEXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA +#endif + +#ifndef FAR +# define FAR +#endif + +#if !defined(__MACTYPES__) +typedef unsigned char Byte; /* 8 bits */ +#endif +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +#ifdef SMALL_MEDIUM + /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +# define Bytef Byte FAR +#else + typedef Byte FAR Bytef; +#endif +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void const *voidpc; + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte const *voidpc; + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ +# include /* for off_t */ +# include /* for SEEK_* and off_t */ +# ifdef VMS +# include /* for off_t */ +# endif +# define z_off_t off_t +#endif +#ifndef SEEK_SET +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif +#ifndef z_off_t +# define z_off_t long +#endif + +#if defined(__OS400__) +#define NO_vsnprintf +#endif + +#if defined(__MVS__) +# define NO_vsnprintf +# ifdef FAR +# undef FAR +# endif +#endif + +/* MVS linker does not support external names larger than 8 bytes */ +#if defined(__MVS__) +# pragma map(deflateInit_,"DEIN") +# pragma map(deflateInit2_,"DEIN2") +# pragma map(deflateEnd,"DEEND") +# pragma map(deflateBound,"DEBND") +# pragma map(inflateInit_,"ININ") +# pragma map(inflateInit2_,"ININ2") +# pragma map(inflateEnd,"INEND") +# pragma map(inflateSync,"INSY") +# pragma map(inflateSetDictionary,"INSEDI") +# pragma map(compressBound,"CMBND") +# pragma map(inflate_table,"INTABL") +# pragma map(inflate_fast,"INFA") +# pragma map(inflate_copyright,"INCOPY") +#endif + +#endif /* ZCONF_H */ diff --git a/klibc/klibc/zlib/zlib.3 b/klibc/klibc/zlib/zlib.3 new file mode 100644 index 0000000000..890098449d --- /dev/null +++ b/klibc/klibc/zlib/zlib.3 @@ -0,0 +1,159 @@ +.TH ZLIB 3 "17 November 2003" +.SH NAME +zlib \- compression/decompression library +.SH SYNOPSIS +[see +.I zlib.h +for full description] +.SH DESCRIPTION +The +.I zlib +library is a general purpose data compression library. +The code is thread safe. +It provides in-memory compression and decompression functions, +including integrity checks of the uncompressed data. +This version of the library supports only one compression method (deflation) +but other algorithms will be added later +and will have the same stream interface. +.LP +Compression can be done in a single step if the buffers are large enough +(for example if an input file is mmap'ed), +or can be done by repeated calls of the compression function. +In the latter case, +the application must provide more input and/or consume the output +(providing more output space) before each call. +.LP +The library also supports reading and writing files in +.IR gzip (1) +(.gz) format +with an interface similar to that of stdio. +.LP +The library does not install any signal handler. +The decoder checks the consistency of the compressed data, +so the library should never crash even in case of corrupted input. +.LP +All functions of the compression library are documented in the file +.IR zlib.h . +The distribution source includes examples of use of the library +in the files +.I example.c +and +.IR minigzip.c . +.LP +Changes to this version are documented in the file +.I ChangeLog +that accompanies the source, +and are concerned primarily with bug fixes and portability enhancements. +.LP +A Java implementation of +.I zlib +is available in the Java Development Kit 1.1: +.IP +http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html +.LP +A Perl interface to +.IR zlib , +written by Paul Marquess (pmqs@cpan.org), +is available at CPAN (Comprehensive Perl Archive Network) sites, +including: +.IP +http://www.cpan.org/modules/by-module/Compress/ +.LP +A Python interface to +.IR zlib , +written by A.M. Kuchling (amk@magnet.com), +is available in Python 1.5 and later versions: +.IP +http://www.python.org/doc/lib/module-zlib.html +.LP +A +.I zlib +binding for +.IR tcl (1), +written by Andreas Kupries (a.kupries@westend.com), +is availlable at: +.IP +http://www.westend.com/~kupries/doc/trf/man/man.html +.LP +An experimental package to read and write files in .zip format, +written on top of +.I zlib +by Gilles Vollant (info@winimage.com), +is available at: +.IP +http://www.winimage.com/zLibDll/unzip.html +and also in the +.I contrib/minizip +directory of the main +.I zlib +web site. +.SH "SEE ALSO" +The +.I zlib +web site can be found at either of these locations: +.IP +http://www.zlib.org +.br +http://www.gzip.org/zlib/ +.LP +The data format used by the zlib library is described by RFC +(Request for Comments) 1950 to 1952 in the files: +.IP +http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) +.br +http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) +.br +http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) +.LP +These documents are also available in other formats from: +.IP +ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html +.LP +Mark Nelson (markn@ieee.org) wrote an article about +.I zlib +for the Jan. 1997 issue of Dr. Dobb's Journal; +a copy of the article is available at: +.IP +http://dogma.net/markn/articles/zlibtool/zlibtool.htm +.SH "REPORTING PROBLEMS" +Before reporting a problem, +please check the +.I zlib +web site to verify that you have the latest version of +.IR zlib ; +otherwise, +obtain the latest version and see if the problem still exists. +Please read the +.I zlib +FAQ at: +.IP +http://www.gzip.org/zlib/zlib_faq.html +.LP +before asking for help. +Send questions and/or comments to zlib@gzip.org, +or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). +.SH AUTHORS +Version 1.2.1 +Copyright (C) 1995-2003 Jean-loup Gailly (jloup@gzip.org) +and Mark Adler (madler@alumni.caltech.edu). +.LP +This software is provided "as-is," +without any express or implied warranty. +In no event will the authors be held liable for any damages +arising from the use of this software. +See the distribution directory with respect to requirements +governing redistribution. +The deflate format used by +.I zlib +was defined by Phil Katz. +The deflate and +.I zlib +specifications were written by L. Peter Deutsch. +Thanks to all the people who reported problems and suggested various +improvements in +.IR zlib ; +who are too numerous to cite here. +.LP +UNIX manual page by R. P. C. Rodgers, +U.S. National Library of Medicine (rodgers@nlm.nih.gov). +.\" end of man page diff --git a/klibc/klibc/zlib/zlib.h b/klibc/klibc/zlib/zlib.h new file mode 100644 index 0000000000..92edf96ff3 --- /dev/null +++ b/klibc/klibc/zlib/zlib.h @@ -0,0 +1,1200 @@ +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 1.2.1, November 17th, 2003 + + Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt + (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). +*/ + +#ifndef ZLIB_H +#define ZLIB_H + +#include "zconf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIB_VERSION "1.2.1" +#define ZLIB_VERNUM 0x1210 + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms will be added later and will have the same + stream interface. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by the in-memory functions is the zlib + format, which is a zlib wrapper documented in RFC 1950, wrapped around a + deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + This library does not provide any functions to write gzip files in memory. + However such functions could be easily written using zlib's deflate function, + the documentation in the gzip RFC, and the examples in gzio.c. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never + crash even in case of corrupted input. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: ascii or binary */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream FAR *z_streamp; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. + + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative + * values are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Possible values of the data_type field (though see inflate()) */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + /* basic functions */ + +ZEXTERN const char * ZEXPORT zlibVersion OF((void)); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + This check is automatically made by deflateInit and inflateInit. + */ + +/* +ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. + If zalloc and zfree are set to Z_NULL, deflateInit updates them to + use default allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at + all (the input data is simply copied a block at a time). + Z_DEFAULT_COMPRESSION requests a default compromise between speed and + compression (currently equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if level is not a valid compression level, + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). + msg is set to null if there is no error message. deflateInit does not + perform any compression: this will be done by deflate(). +*/ + + +ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce some + output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary (in interactive applications). + Some output may be provided even if flush is not set. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating avail_in or avail_out accordingly; avail_out + should never be zero before the call. The application can consume the + compressed output when it wants, for example when the output buffer is full + (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK + and with zero avail_out, it must be called again after making room in the + output buffer because there might be more output pending. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In particular + avail_in is zero after the call if enough output space has been provided + before the call.) Flushing may degrade compression for some compression + algorithms and so it should be used only when necessary. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + the compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there + was enough output space; if deflate returns with Z_OK, this function must be + called again with Z_FINISH and more output space (updated avail_out) but no + more input data, until it returns with Z_STREAM_END or an error. After + deflate has returned Z_STREAM_END, the only possible operations on the + stream are deflateReset or deflateEnd. + + Z_FINISH can be used immediately after deflateInit if all the compression + is to be done in a single step. In this case, avail_out must be at least + the value returned by deflateBound (see below). If deflate does not return + Z_STREAM_END, then it must be called again as described above. + + deflate() sets strm->adler to the adler32 checksum of all input read + so far (that is, total_in bytes). + + deflate() may update data_type if it can make a good guess about + the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered + binary. This field is only for information purposes and does not affect + the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible + (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not + fatal, and deflate() can be called again with more input and more output + space to continue compressing. +*/ + + +ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, + msg may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. If next_in is not Z_NULL and avail_in is large enough (the exact + value depends on the compression method), inflateInit determines the + compression method from the zlib header and allocates all data structures + accordingly; otherwise the allocation will be deferred to the first call of + inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to + use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller. msg is set to null if there is no error + message. inflateInit does not perform any decompression apart from reading + the zlib header if present: this will be done by inflate(). (So next_in and + avail_in may be modified, but next_out and avail_out are unchanged.) +*/ + + +ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there + is no more input data or no more space in the output buffer (see below + about the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). If inflate returns Z_OK and with zero avail_out, it + must be called again after making room in the output buffer because there + might be more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it get to the next deflate block boundary. When decoding the zlib + or gzip format, this will cause inflate() to return immediately after the + header and before the first block. When doing a raw inflate, inflate() will + go ahead and process the first block, and will return when it gets to the end + of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster approach + may be used for the single inflate() call. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm-adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. +*/ + + +ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy)); + + This is another version of deflateInit with more compression options. The + fields next_in, zalloc, zfree and opaque must be initialized before by + the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute an adler32 check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), + no header crc, and the operating system will be set to 255 (unknown). + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but + is slow and reduces compression ratio; memLevel=9 uses maximum memory + for optimal speed. The default value is 8. See zconf.h for total memory + usage as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as + Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy + parameter only affects the compression ratio but not the correctness of the + compressed output even if it is not set appropriately. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid + method). msg is set to null if there is no error message. deflateInit2 does + not perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. This function must be called + immediately after deflateInit, deflateInit2 or deflateReset, before any + call of deflate. The compressor and decompressor must use exactly the same + dictionary (see inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size in + deflate or deflate2. Thus the strings most likely to be useful should be + put at the end of the dictionary, not at the front. + + Upon return of this function, strm->adler is set to the adler32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The adler32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + adler32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if the compression method is bsort). deflateSetDictionary does not + perform any compression: this will be done by deflate(). +*/ + +ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and + can consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); +/* + This function is equivalent to deflateEnd followed by deflateInit, + but does not free and reallocate all the internal compression state. + The stream will keep the same compression level and any other attributes + that may have been set by deflateInit2. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2. This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different + strategy. If the compression level is changed, the input available so far + is compressed with the old level (and may be flushed); the new level will + take effect only at the next call of deflate(). + + Before the call of deflateParams, the stream state must be set as for + a call of deflate(), since the currently available input may have to + be compressed and flushed. In particular, strm->avail_out must be non-zero. + + deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source + stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR + if strm->avail_out was zero. +*/ + +ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() + or deflateInit2(). This would be used to allocate an output buffer + for deflation in a single pass, and so would be called before deflate(). +*/ + +ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the + bits leftover from a previous deflate stream when appending to it. As such, + this function can only be used for raw deflate, and must be used before the + first deflate() call after a deflateInit2() or deflateReset(). bits must be + less than or equal to 16, and that many of the least significant bits of + value will be inserted in the output. + + deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, + int windowBits)); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative + memLevel). msg is set to null if there is no error message. inflateInit2 + does not perform any decompression apart from reading the zlib header if + present: this will be done by inflate(). (So next_in and avail_in may be + modified, but next_out and avail_out are unchanged.) +*/ + +ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate + if this call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by this call of + inflate. The compressor and decompressor must use exactly the same + dictionary (see deflateSetDictionary). + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (such as NULL dictionary) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect adler32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); +/* + Skips invalid compressed data until a full flush point (see above the + description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR + if no more input was provided, Z_DATA_ERROR if no flush point has been found, + or Z_STREAM_ERROR if the stream structure was inconsistent. In the success + case, the application may save the current current value of total_in which + indicates where valid compressed data was found. In the error case, the + application may repeatedly call inflateSync, providing more input each time, + until success or end of the input data. +*/ + +ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate all the internal decompression state. + The stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +/* +ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits, + unsigned char FAR *window)); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are Z_NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the paramaters are invalid, Z_MEM_ERROR if the internal state could not + be allocated, or Z_VERSION_ERROR if the version of the library does not + match the version of the header file. +*/ + +typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); +typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + +ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is more efficient than inflate() for + file i/o applications in that it avoids copying between the output and the + sliding window by simply making the window itself the output buffer. This + function trusts the application to not change the output buffer passed by + the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free + the allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects + only the raw deflate stream to decompress. This is different from the + normal behavior of inflate(), which expects either a zlib or gzip header and + trailer around the deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero--buf is ignored in that + case--and inflateBack() will return a buffer error. inflateBack() will call + out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() + should return zero on success, or non-zero on failure. If out() returns + non-zero, inflateBack() will return with an error. Neither in() nor out() + are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called + immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format + error in the deflate stream (in which case strm->msg is set to indicate the + nature of the error), or Z_STREAM_ERROR if the stream was not properly + initialized. In the case of Z_BUF_ERROR, an input or output error can be + distinguished using strm->next_in which will be Z_NULL only if in() returned + an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to + out() returning non-zero. (in() will always be called before out(), so + strm->next_in is assured to be defined if out() returns non-zero.) Note + that inflateBack() cannot return Z_OK. +*/ + +ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm)); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of uInt + 3.2: size of uLong + 5.4: size of voidpf (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the + basic stream-oriented functions. To simplify the interface, some + default options are assumed (compression level and memory usage, + standard memory allocation functions). The source code of these + utility functions can easily be modified if you need special options. +*/ + +ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be at least the value returned + by compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + This function can be used to compress a whole file at once if the + input file is mmap'ed. + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before + a compress() or compress2() call to allocate the destination buffer. +*/ + +ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total + size of the destination buffer, which must be large enough to hold the + entire uncompressed data. (The size of the uncompressed data must have + been saved previously by the compressor and transmitted to the decompressor + by some mechanism outside the scope of this compression library.) + Upon exit, destLen is the actual size of the compressed buffer. + This function can be used to decompress a whole file at once if the + input file is mmap'ed. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. +*/ + + +typedef voidp gzFile; + +ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); +/* + Opens a gzip (.gz) file for reading or writing. The mode parameter + is as in fopen ("rb" or "wb") but can also include a compression level + ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for + Huffman only compression as in "wb1h", or 'R' for run-length encoding + as in "wb1R". (See the description of deflateInit2 for more information + about the strategy parameter.) + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. + + gzopen returns NULL if the file could not be opened or if there was + insufficient memory to allocate the (de)compression state; errno + can be checked to distinguish the two cases (if errno is zero, the + zlib error is Z_MEM_ERROR). */ + +ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); +/* + gzdopen() associates a gzFile with the file descriptor fd. File + descriptors are obtained from calls like open, dup, creat, pipe or + fileno (in the file has been previously opened with fopen). + The mode parameter is as in gzopen. + The next call of gzclose on the returned gzFile will also close the + file descriptor fd, just like fclose(fdopen(fd), mode) closes the file + descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). + gzdopen returns NULL if there was insufficient memory to allocate + the (de)compression state. +*/ + +ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); +/* + Dynamically update the compression level or strategy. See the description + of deflateInit2 for the meaning of these parameters. + gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not + opened for writing. +*/ + +ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); +/* + Reads the given number of uncompressed bytes from the compressed file. + If the input file was not in gzip format, gzread copies the given number + of bytes into the buffer. + gzread returns the number of uncompressed bytes actually read (0 for + end of file, -1 for error). */ + +ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); +/* + Writes the given number of uncompressed bytes into the compressed file. + gzwrite returns the number of uncompressed bytes actually written + (0 in case of error). +*/ + +ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); +/* + Converts, formats, and writes the args to the compressed file under + control of the format string, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written (0 in case of error). The number of + uncompressed bytes written is limited to 4095. The caller should assure that + this limit is not exceeded. If it is exceeded, then gzprintf() will return + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf() + because the secure snprintf() or vsnprintf() functions were not available. +*/ + +ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); +/* + Writes the given null-terminated string to the compressed file, excluding + the terminating null character. + gzputs returns the number of characters written, or -1 in case of error. +*/ + +ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); +/* + Reads bytes from the compressed file until len-1 characters are read, or + a newline character is read and transferred to buf, or an end-of-file + condition is encountered. The string is then terminated with a null + character. + gzgets returns buf, or Z_NULL in case of error. +*/ + +ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); +/* + Writes c, converted to an unsigned char, into the compressed file. + gzputc returns the value that was written, or -1 in case of error. +*/ + +ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); +/* + Reads one byte from the compressed file. gzgetc returns this byte + or -1 in case of end of file or error. +*/ + +ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); +/* + Push one character back onto the stream to be read again later. + Only one character of push-back is allowed. gzungetc() returns the + character pushed, or -1 on failure. gzungetc() will fail if a + character has been pushed but not read yet, or if c is -1. The pushed + character will be discarded if the stream is repositioned with gzseek() + or gzrewind(). +*/ + +ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); +/* + Flushes all pending output into the compressed file. The parameter + flush is as in the deflate() function. The return value is the zlib + error number (see function gzerror below). gzflush returns Z_OK if + the flush parameter is Z_FINISH and all output could be flushed. + gzflush should be called only when strictly necessary because it can + degrade compression. +*/ + +ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, + z_off_t offset, int whence)); +/* + Sets the starting position for the next gzread or gzwrite on the + given compressed file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); +/* + Rewinds the given file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) +*/ + +ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); +/* + Returns the starting position for the next gzread or gzwrite on the + given compressed file. This position represents a number of bytes in the + uncompressed data stream. + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +ZEXTERN int ZEXPORT gzeof OF((gzFile file)); +/* + Returns 1 when EOF has previously been detected reading the given + input stream, otherwise zero. +*/ + +ZEXTERN int ZEXPORT gzclose OF((gzFile file)); +/* + Flushes all pending output if necessary, closes the compressed file + and deallocates all the (de)compression state. The return value is the zlib + error number (see function gzerror below). +*/ + +ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); +/* + Returns the error message for the last error which occurred on the + given compressed file. errnum is set to zlib error number. If an + error occurred in the file system and not in the compression library, + errnum is set to Z_ERRNO and the application may consult errno + to get the exact error code. +*/ + +ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); +/* + Clears the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the + compression library. +*/ + +ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. If buf is NULL, this function returns + the required initial value for the checksum. + An Adler-32 checksum is almost as reliable as a CRC32 but can be computed + much faster. Usage example: + + uLong adler = adler32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); +/* + Update a running crc with the bytes buf[0..len-1] and return the updated + crc. If buf is NULL, this function returns the required initial value + for the crc. Pre- and post-conditioning (one's complement) is performed + within this function so it shouldn't be done by the application. + Usage example: + + uLong crc = crc32(0L, Z_NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); +ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); +ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); +#define deflateInit(strm, level) \ + deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit(strm) \ + inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) +#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ + (strategy), ZLIB_VERSION, sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, sizeof(z_stream)) + + +#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) + struct internal_state {int dummy;}; /* hack for buggy compilers */ +#endif + +ZEXTERN const char * ZEXPORT zError OF((int err)); +ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); +ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H */ diff --git a/klibc/klibc/zlib/zutil.c b/klibc/klibc/zlib/zutil.c new file mode 100644 index 0000000000..253a1cc7e1 --- /dev/null +++ b/klibc/klibc/zlib/zutil.c @@ -0,0 +1,319 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* @(#) $Id: zutil.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#include "zutil.h" + +#ifndef NO_DUMMY_DECL +struct internal_state {int dummy;}; /* for buggy compilers */ +#endif + +#ifndef STDC +extern void exit OF((int)); +#endif + +const char * const z_errmsg[10] = { +"need dictionary", /* Z_NEED_DICT 2 */ +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +"incompatible version",/* Z_VERSION_ERROR (-6) */ +""}; + + +const char * ZEXPORT zlibVersion() +{ + return ZLIB_VERSION; +} + +uLong ZEXPORT zlibCompileFlags() +{ + uLong flags; + + flags = 0; + switch (sizeof(uInt)) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch (sizeof(uLong)) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch (sizeof(voidpf)) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch (sizeof(z_off_t)) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef DEBUG + flags += 1 << 8; +#endif +#if defined(ASMV) || defined(ASMINF) + flags += 1 << 9; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif +#ifdef BUILDFIXED + flags += 1 << 12; +#endif +#ifdef DYNAMIC_CRC_TABLE + flags += 1 << 13; +#endif +#ifdef NO_GZCOMPRESS + flags += 1 << 16; +#endif +#ifdef NO_GZIP + flags += 1 << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1 << 20; +#endif +#ifdef FASTEST + flags += 1 << 21; +#endif +#ifdef STDC +# ifdef NO_vsnprintf + flags += 1 << 25; +# ifdef HAS_vsprintf_void + flags += 1 << 26; +# endif +# else +# ifdef HAS_vsnprintf_void + flags += 1 << 26; +# endif +# endif +#else + flags += 1 << 24; +# ifdef NO_snprintf + flags += 1 << 25; +# ifdef HAS_sprintf_void + flags += 1 << 26; +# endif +# else +# ifdef HAS_snprintf_void + flags += 1 << 26; +# endif +# endif +#endif + return flags; +} + +#ifdef DEBUG + +# ifndef verbose +# define verbose 0 +# endif +int z_verbose = verbose; + +void z_error (m) + char *m; +{ + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * ZEXPORT zError(err) + int err; +{ + return ERR_MSG(err); +} + +#if defined(_WIN32_WCE) + /* does not exist on WCE */ + int errno = 0; +#endif + +#ifndef HAVE_MEMCPY + +void zmemcpy(dest, source, len) + Bytef* dest; + const Bytef* source; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); +} + +int zmemcmp(s1, s2, len) + const Bytef* s1; + const Bytef* s2; + uInt len; +{ + uInt j; + + for (j = 0; j < len; j++) { + if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; + } + return 0; +} + +void zmemzero(dest, len) + Bytef* dest; + uInt len; +{ + if (len == 0) return; + do { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); +} +#endif + + +#ifdef SYS16BIT + +#ifdef __TURBOC__ +/* Turbo C in 16-bit mode */ + +# define MY_ZCALLOC + +/* Turbo C malloc() does not allow dynamic allocation of 64K bytes + * and farmalloc(64K) returns a pointer with an offset of 8, so we + * must fix the pointer. Warning: the pointer must be put back to its + * original form in order to free it, use zcfree(). + */ + +#define MAX_PTR 10 +/* 10*64K = 640K */ + +local int next_ptr = 0; + +typedef struct ptr_table_s { + voidpf org_ptr; + voidpf new_ptr; +} ptr_table; + +local ptr_table table[MAX_PTR]; +/* This table is used to remember the original form of pointers + * to large buffers (64K). Such pointers are normalized with a zero offset. + * Since MSDOS is not a preemptive multitasking OS, this table is not + * protected from concurrent access. This hack doesn't work anyway on + * a protected system like OS/2. Use Microsoft C instead. + */ + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items*size; + + /* If we allocate less than 65520 bytes, we assume that farmalloc + * will return a usable pointer which doesn't have to be normalized. + */ + if (bsize < 65520L) { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } else { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; + + /* Normalize the pointer to seg:0 */ + *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + int n; + if (*(ush*)&ptr != 0) { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) { + if (ptr != table[n].new_ptr) continue; + + farfree(table[n].org_ptr); + while (++n < next_ptr) { + table[n-1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); +} + +#endif /* __TURBOC__ */ + + +#ifdef M_I86 +/* Microsoft C in 16-bit mode */ + +# define MY_ZCALLOC + +#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) +# define _halloc halloc +# define _hfree hfree +#endif + +voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); +} + +void zcfree (voidpf opaque, voidpf ptr) +{ + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); +} + +#endif /* M_I86 */ + +#endif /* SYS16BIT */ + + +#ifndef MY_ZCALLOC /* Any system without a special alloc function */ + +#ifndef STDC +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); +#endif + +voidpf zcalloc (opaque, items, size) + voidpf opaque; + unsigned items; + unsigned size; +{ + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : + (voidpf)calloc(items, size); +} + +void zcfree (opaque, ptr) + voidpf opaque; + voidpf ptr; +{ + free(ptr); + if (opaque) return; /* make compiler happy */ +} + +#endif /* MY_ZCALLOC */ diff --git a/klibc/klibc/zlib/zutil.h b/klibc/klibc/zlib/zutil.h new file mode 100644 index 0000000000..129452806b --- /dev/null +++ b/klibc/klibc/zlib/zutil.h @@ -0,0 +1,258 @@ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2003 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* @(#) $Id: zutil.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ + +#ifndef ZUTIL_H +#define ZUTIL_H + +#define ZLIB_INTERNAL +#include "zlib.h" + +#ifdef STDC +# include +# include +# include +#endif +#ifdef NO_ERRNO_H + extern int errno; +#else +# include +#endif + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm,err) \ + return (strm->msg = (char*)ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + + /* target dependencies */ + +#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) +# define OS_CODE 0x00 +# if defined(__TURBOC__) || defined(__BORLANDC__) +# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) + /* Allow compilation with ANSI keywords only enabled */ + void _Cdecl farfree( void *block ); + void *_Cdecl farmalloc( unsigned long nbytes ); +# else +# include +# endif +# else /* MSC or DJGPP */ +# include +# endif +#endif + +#ifdef AMIGA +# define OS_CODE 0x01 +#endif + +#if defined(VAXC) || defined(VMS) +# define OS_CODE 0x02 +# define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 0x05 +#endif + +#ifdef OS2 +# define OS_CODE 0x06 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 0x07 +# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +# include /* for fdopen */ +# else +# ifndef fdopen +# define fdopen(fd,mode) NULL /* No fdopen() */ +# endif +# endif +#endif + +#ifdef TOPS20 +# define OS_CODE 0x0a +#endif + +#ifdef WIN32 +# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +# define OS_CODE 0x0b +# endif +#endif + +#ifdef __50SERIES /* Prime/PRIMOS */ +# define OS_CODE 0x0f +#endif + +#if defined(_BEOS_) || defined(RISCOS) +# define fdopen(fd,mode) NULL /* No fdopen() */ +#endif + +#if (defined(_MSC_VER) && (_MSC_VER > 600)) +# if defined(_WIN32_WCE) +# define fdopen(fd,mode) NULL /* No fdopen() */ +# ifndef _PTRDIFF_T_DEFINED + typedef int ptrdiff_t; +# define _PTRDIFF_T_DEFINED +# endif +# else +# define fdopen(fd,type) _fdopen(fd,type) +# endif +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 0x03 /* assume Unix */ +#endif + +#ifndef F_OPEN +# define F_OPEN(name, mode) fopen((name), (mode)) +#endif + + /* functions */ + +#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#if defined(__CYGWIN__) +# ifndef HAVE_VSNPRINTF +# define HAVE_VSNPRINTF +# endif +#endif +#ifndef HAVE_VSNPRINTF +# ifdef MSDOS + /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), + but for now we just assume it doesn't. */ +# define NO_vsnprintf +# endif +# ifdef __TURBOC__ +# define NO_vsnprintf +# endif +# ifdef WIN32 + /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +# if !defined(vsnprintf) && !defined(NO_vsnprintf) +# define vsnprintf _vsnprintf +# endif +# endif +# ifdef __SASC +# define NO_vsnprintf +# endif +#endif + +#ifdef HAVE_STRERROR + extern char *strerror OF((int)); +# define zstrerror(errnum) strerror(errnum) +#else +# define zstrerror(errnum) "" +#endif + +#if defined(pyr) +# define NO_MEMCPY +#endif +#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) + /* Use our own functions for small and medium model with MSC <= 5.0. + * You may have to use the same strategy for Borland C (untested). + * The __SC__ check is for Symantec. + */ +# define NO_MEMCPY +#endif +#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) +# define HAVE_MEMCPY +#endif +#ifdef HAVE_MEMCPY +# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +# define zmemcpy _fmemcpy +# define zmemcmp _fmemcmp +# define zmemzero(dest, len) _fmemset(dest, 0, len) +# else +# define zmemcpy memcpy +# define zmemcmp memcmp +# define zmemzero(dest, len) memset(dest, 0, len) +# endif +#else + extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); + extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); + extern void zmemzero OF((Bytef* dest, uInt len)); +#endif + +/* Diagnostic functions */ +#ifdef DEBUG +# include + extern int z_verbose; + extern void z_error OF((char *m)); +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose>=0) fprintf x ;} +# define Tracev(x) {if (z_verbose>0) fprintf x ;} +# define Tracevv(x) {if (z_verbose>1) fprintf x ;} +# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} +# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); +void zcfree OF((voidpf opaque, voidpf ptr)); + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H */ diff --git a/klibc/makeklcc.pl b/klibc/makeklcc.pl new file mode 100644 index 0000000000..ea3f8a8256 --- /dev/null +++ b/klibc/makeklcc.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl +# +# Combine klibc.config, klcc.in to produce a klcc script +# +# Usage: makeklcc klcc.in klibc.config perlpath +# + +($klccin, $klibcconf, $perlpath) = @ARGV; + +# This should probably handle quotes and escapes... +sub string2list($) +{ + my($s) = @_; + + $s =~ s/\s+/\',\'/g; + return "(\'".$s."\')"; +} + +print "#!${perlpath}\n"; + +open(KLIBCCONF, '<', $klibcconf) or die "$0: cannot open $klibcconf: $!\n"; +while ( defined($l = ) ) { + chomp $l; + if ( $l =~ /=/ ) { + print "\$$` = \"\Q$'\E\";\n"; + print "\@$` = ", string2list("$'"), ";\n"; + } +} +close(KLIBCCONF); + +open(KLCCIN, '<', $klccin) or die "$0: cannot open $klccin: $!\n"; +while ( defined($l = ) ) { + print $l; +} +close(KLCCIN); + diff --git a/klibc/version b/klibc/version index b4d2b300cd..58be07ab5e 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.199 +0.205 From b55e6540260ac3e38d96a0b6c00514a72d5db218 Mon Sep 17 00:00:00 2001 From: "pebenito@gentoo.org" Date: Tue, 8 Mar 2005 06:57:25 -0800 Subject: [PATCH 1184/4284] [PATCH] udev selinux fix Here is a fix for the SELinux part of udev. Setfscreatecon() overrides the default labeling behavior of SELinux when creating files, so it should only be used for as short of a time as possible, around the mknod or symlink calls. Without this, the files in udev_db get the wrong label because the fscreatecon is reset after the udev_db file creation instead of before. I'm guessing the Redhat people missed this because they modify udev_db to be one big file instead of a directory of small files (at least that's what I'm told). I created selinux_resetfscreatecon() to reset the fscreatecon asap after the file/node is created. Fixed a memory leak in selinux_init. Getfscreatecon() allocates memory for the context, and the udev code was immediately setting the pointer (security_context_t is actually a typedef'ed char*) to NULL after the call regardless of success/failure. If you're wondering about the case where there's effectively a setfscreatecon(NULL), this is ok, as its used to tell SELinux to do the default labeling behavior. Renamed selinux_restore() to selinux_exit() due to the changed behavior. Fixed a couple of dbg() messages. --- udev_add.c | 10 +++++++--- udev_selinux.c | 36 +++++++++++++++++++----------------- udev_selinux.h | 6 ++++-- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/udev_add.c b/udev_add.c index eeab1ca174..e5bd042a5c 100644 --- a/udev_add.c +++ b/udev_add.c @@ -83,6 +83,7 @@ create: selinux_setfscreatecon(file, udev->kernel_name, mode); retval = mknod(file, mode, devt); + selinux_resetfscreatecon(); if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", file, mode, major(devt), minor(devt), strerror(errno)); @@ -196,6 +197,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de /* create symlink(s) if requested */ foreach_strpart(udev->symlink, " ", pos, len) { + int retval; char linkname[NAME_SIZE]; char linktarget[NAME_SIZE]; @@ -227,9 +229,11 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de dbg("symlink(%s, %s)", linktarget, filename); if (!udev->test_run) { - selinux_setfscreatecon(filename, udev->kernel_name, S_IFLNK); unlink(filename); - if (symlink(linktarget, filename) != 0) + selinux_setfscreatecon(filename, udev->kernel_name, S_IFLNK); + retval = symlink(linktarget, filename); + selinux_resetfscreatecon(); + if (retval != 0) dbg("symlink(%s, %s) failed with error '%s'", linktarget, filename, strerror(errno)); } @@ -326,7 +330,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) } exit: - selinux_restore(); + selinux_exit(); return retval; } diff --git a/udev_selinux.c b/udev_selinux.c index 72381f0d0d..cc6f4d7d3f 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -105,7 +105,7 @@ void selinux_setfilecon(const char *file, const char *devname, unsigned int mode } if (setfilecon(file, scontext) < 0) - dbg("setfiles %s failed with error '%s'", file, strerror(errno)); + dbg("setfilecon %s failed with error '%s'", file, strerror(errno)); freecon(scontext); } @@ -131,12 +131,20 @@ void selinux_setfscreatecon(const char *file, const char *devname, unsigned int } if (setfscreatecon(scontext) < 0) - dbg("setfiles %s failed with error '%s'", file, strerror(errno)); + dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); freecon(scontext); } } +void selinux_resetfscreatecon(void) +{ + if (is_selinux_running()) { + if (setfscreatecon(prev_scontext) < 0) + dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); + } +} + void selinux_init(void) { /* @@ -144,23 +152,17 @@ void selinux_init(void) * restoration creation purposes. */ if (is_selinux_running()) { - if (getfscreatecon(&prev_scontext) < 0) + if (getfscreatecon(&prev_scontext) < 0) { dbg("getfscreatecon failed\n"); - - prev_scontext = NULL; - } -} - -void selinux_restore(void) -{ - if (is_selinux_running()) { - /* reset the file create context to its former glory */ - if (setfscreatecon(prev_scontext) < 0) - dbg("setfscreatecon failed\n"); - - if (prev_scontext) { - freecon(prev_scontext); prev_scontext = NULL; } } } + +void selinux_exit(void) +{ + if (is_selinux_running() && prev_scontext) { + freecon(prev_scontext); + prev_scontext = NULL; + } +} diff --git a/udev_selinux.h b/udev_selinux.h index 132a9a6550..d9dfeffad0 100644 --- a/udev_selinux.h +++ b/udev_selinux.h @@ -24,15 +24,17 @@ 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_restore(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_restore(void) {} +static inline void selinux_exit(void) {} #endif /* USE_SELINUX */ #endif /* _UDEV_USE_SELINUX */ From 084420316c7345478028b25fa85b66e39b4f793b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Mar 2005 06:32:03 +0100 Subject: [PATCH 1185/4284] [PATCH] klibc: check for gcc4 --- klibc/klibc/arch/i386/MCONFIG | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG index 67d8de4740..8310e26381 100644 --- a/klibc/klibc/arch/i386/MCONFIG +++ b/klibc/klibc/arch/i386/MCONFIG @@ -16,7 +16,7 @@ gcc_major := $(shell echo __GNUC__ | $(CC) -E -xc - | tail -n 1) OPTFLAGS = -march=i386 -Os -g LDFLAGS = -m elf_i386 -ifeq ($(gcc_major),3) +ifneq ($(shell if [ $(gcc_major) -gt 2 ] ; then echo "new"; fi ;),) REGPARM := $(REGPARM_OPT) OPTFLAGS += -falign-functions=0 -falign-jumps=0 -falign-loops=0 ARCHREQFLAGS += -m32 From b821330f0fce374902a1c8e32064196276006bca Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Mar 2005 20:52:19 +0100 Subject: [PATCH 1186/4284] [PATCH] trivial clenaup of namedev code --- namedev.c | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/namedev.c b/namedev.c index f0a5c34f79..41f0bc0f16 100644 --- a/namedev.c +++ b/namedev.c @@ -168,8 +168,7 @@ static int find_free_number(struct udevice *udev, const char *name) } static void apply_format(struct udevice *udev, char *string, size_t maxsize, - struct sysfs_class_device *class_dev, - struct sysfs_device *sysfs_device) + struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { char temp[NAME_SIZE]; char temp2[NAME_SIZE]; @@ -203,26 +202,18 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, switch (c) { case 'p': - if (strlen(udev->devpath) == 0) - break; strfieldcatmax(string, udev->devpath, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'b': - if (strlen(udev->bus_id) == 0) - break; strfieldcatmax(string, udev->bus_id, maxsize); dbg("substitute bus_id '%s'", udev->bus_id); break; case 'k': - if (strlen(udev->kernel_name) == 0) - break; strfieldcatmax(string, udev->kernel_name, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'n': - if (strlen(udev->kernel_number) == 0) - break; strfieldcatmax(string, udev->kernel_number, maxsize); dbg("substitute kernel number '%s'", udev->kernel_number); break; @@ -235,7 +226,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute major number '%u'", major(udev->devt)); break; case 'c': - if (strlen(udev->program_result) == 0) + if (udev->program_result[0] == '\0') break; /* get part part of the result string */ i = 0; @@ -730,7 +721,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d return -1; } if (dev->ignore_remove) { - udev->ignore_remove = dev->ignore_remove; + udev->ignore_remove = 1; dbg_parse("remove event should be ignored"); } /* apply all_partitions option only at a main block device */ @@ -782,16 +773,17 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d 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); - goto exit; + break; } } } - /* no rule matched, so we use the kernel name */ - strfieldcpy(udev->name, udev->kernel_name); - dbg("no rule found, use kernel name '%s'", udev->name); + if (udev->name[0] == '\0') { + /* no rule matched, so we use the kernel name */ + strfieldcpy(udev->name, udev->kernel_name); + dbg("no rule found, use kernel name '%s'", udev->name); + } -exit: if (udev->tmp_node[0] != '\0') { dbg("removing temporary device node"); unlink_secure(udev->tmp_node); From 75bc9b086fe0f212e52da8425e4a4cb2d8f38090 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Mar 2005 20:56:51 +0100 Subject: [PATCH 1187/4284] [PATCH] kill stupid gcc4 warning --- udev_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index 8813bd5c47..fc7ee885b0 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -330,7 +330,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "iucv", .file = "detach_state" }, { NULL, NULL } }; - const struct device_file *devicefile; + const struct device_file *devicefile = NULL; int loop; /* the kernel may tell us what to wait for */ From c98cb35eb5f24940cf8836be96de42c9e8795f27 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Mar 2005 21:00:43 +0100 Subject: [PATCH 1188/4284] [PATCH] rename attributes to options --- namedev.h | 6 +++--- namedev_parse.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/namedev.h b/namedev.h index 3a16144169..1d6920cc7c 100644 --- a/namedev.h +++ b/namedev.h @@ -52,9 +52,9 @@ struct sysfs_class_device; #define FIELD_MODE "MODE" #define FIELD_OPTIONS "OPTIONS" -#define ATTR_IGNORE_DEVICE "ignore_device" -#define ATTR_IGNORE_REMOVE "ignore_remove" -#define ATTR_PARTITIONS "all_partitions" +#define OPTION_IGNORE_DEVICE "ignore_device" +#define OPTION_IGNORE_REMOVE "ignore_remove" +#define OPTION_PARTITIONS "all_partitions" #define MAX_SYSFS_PAIRS 5 diff --git a/namedev_parse.c b/namedev_parse.c index 02d8a6520c..ed38db4b14 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -250,11 +250,11 @@ static int namedev_parse(const char *filename, void *data) attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1); /* FIXME: remove old style options and make OPTIONS= mandatory */ if (attr != NULL) { - if (strstr(attr, ATTR_PARTITIONS) != NULL) { + if (strstr(attr, OPTION_PARTITIONS) != NULL) { dbg_parse("creation of partition nodes requested"); dev.partitions = DEFAULT_PARTITIONS_COUNT; } - if (strstr(attr, ATTR_IGNORE_REMOVE) != NULL) { + if (strstr(attr, OPTION_IGNORE_REMOVE) != NULL) { dbg_parse("remove event should be ignored"); dev.ignore_remove = 1; } @@ -292,15 +292,15 @@ static int namedev_parse(const char *filename, void *data) } if (strcasecmp(temp2, FIELD_OPTIONS) == 0) { - if (strstr(temp3, ATTR_IGNORE_DEVICE) != NULL) { + if (strstr(temp3, OPTION_IGNORE_DEVICE) != NULL) { dbg_parse("device should be ignored"); dev.ignore_device = 1; } - if (strstr(temp3, ATTR_IGNORE_REMOVE) != NULL) { + if (strstr(temp3, OPTION_IGNORE_REMOVE) != NULL) { dbg_parse("remove event should be ignored"); dev.ignore_remove = 1; } - if (strstr(temp3, ATTR_PARTITIONS) != NULL) { + if (strstr(temp3, OPTION_PARTITIONS) != NULL) { dbg_parse("creation of partition nodes requested"); dev.partitions = DEFAULT_PARTITIONS_COUNT; } From 03cfa1394fcc2c4386f8af22e5a4d9fdd7cecc50 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Mar 2005 21:13:18 +0100 Subject: [PATCH 1189/4284] [PATCH] correct udev_init_device --- udev.c | 18 ++++--------- udev.h | 5 ++-- udev_utils.c | 73 +++++++++++++++++++++++++--------------------------- 3 files changed, 42 insertions(+), 54 deletions(-) diff --git a/udev.c b/udev.c index 7854bc74d0..802e41d147 100644 --- a/udev.c +++ b/udev.c @@ -96,7 +96,6 @@ static void asmlinkage sig_handler(int signum) int main(int argc, char *argv[], char *envp[]) { - struct sigaction act; struct sysfs_class_device *class_dev; struct sysfs_device *devices_dev; struct udevice udev; @@ -106,6 +105,7 @@ int main(int argc, char *argv[], char *envp[]) const char *devpath; const char *subsystem; int managed_event; + struct sigaction act; int retval = -EINVAL; if (argc == 2 && strcmp(argv[1], "-V") == 0) { @@ -153,16 +153,10 @@ int main(int argc, char *argv[], char *envp[]) if (!subsystem && argc == 2) subsystem = argv[1]; - if (!action) { - dbg("no action"); - goto hotplug; - } - if (!subsystem) { - dbg("no subsystem"); - goto hotplug; - } - if (!devpath) { - dbg("no devpath"); + udev_init_device(&udev, devpath, subsystem); + + if (!action || !subsystem || !devpath) { + dbg("action, subsystem or devpath missing"); goto hotplug; } @@ -170,8 +164,6 @@ int main(int argc, char *argv[], char *envp[]) if (udev_log) setenv("UDEV_LOG", "1", 1); - udev_init_device(&udev, devpath, subsystem); - if (udev.type == BLOCK || udev.type == CLASS || udev.type == NET) { if (strcmp(action, "add") == 0) { /* wait for sysfs and possibly add node */ diff --git a/udev.h b/udev.h index d6dbd7c332..ddcfa81c8e 100644 --- a/udev.h +++ b/udev.h @@ -31,6 +31,7 @@ #define ALARM_TIMEOUT 120 #define COMMENT_CHARACTER '#' +#define LINE_SIZE 512 #define NAME_SIZE 256 #define USER_SIZE 32 @@ -39,8 +40,6 @@ #define SUBSYSTEM_SIZE 32 #define SEQNUM_SIZE 32 -#define LINE_SIZE 512 - #define DEVD_DIR "/etc/dev.d" #define DEVD_SUFFIX ".dev" @@ -62,6 +61,7 @@ struct udevice { char subsystem[SUBSYSTEM_SIZE]; char name[NAME_SIZE]; + char devname[NAME_SIZE]; char symlink[NAME_SIZE]; char owner[USER_SIZE]; char group[USER_SIZE]; @@ -69,7 +69,6 @@ struct udevice { char type; dev_t devt; - char devname[NAME_SIZE]; char tmp_node[NAME_SIZE]; int partitions; int ignore_remove; diff --git a/udev_utils.c b/udev_utils.c index c1e497626e..f2534dd331 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -43,52 +43,49 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs memset(udev, 0x00, sizeof(struct udevice)); - if (devpath) { - strfieldcpy(udev->devpath, devpath); - no_trailing_slash(udev->devpath); - } if (subsystem) strfieldcpy(udev->subsystem, subsystem); - if (strcmp(udev->subsystem, "block") == 0) - udev->type = BLOCK; - else if (strcmp(udev->subsystem, "net") == 0) - udev->type = NET; - else if (strncmp(udev->devpath, "/block/", 7) == 0) - udev->type = BLOCK; - else if (strncmp(udev->devpath, "/class/net/", 11) == 0) - udev->type = NET; - else if (strncmp(udev->devpath, "/class/", 7) == 0) - udev->type = CLASS; - else if (strncmp(udev->devpath, "/devices/", 9) == 0) - udev->type = PHYSDEV; + if (devpath) { + strfieldcpy(udev->devpath, devpath); + no_trailing_slash(udev->devpath); + + if (strncmp(udev->devpath, "/block/", 7) == 0) + udev->type = BLOCK; + else if (strncmp(udev->devpath, "/class/net/", 11) == 0) + udev->type = NET; + else if (strncmp(udev->devpath, "/class/", 7) == 0) + udev->type = CLASS; + else if (strncmp(udev->devpath, "/devices/", 9) == 0) + udev->type = PHYSDEV; + + /* get kernel name */ + pos = strrchr(udev->devpath, '/'); + if (pos) { + strfieldcpy(udev->kernel_name, &pos[1]); + dbg("kernel_name='%s'", udev->kernel_name); + + /* Some block devices have '!' in their name, change that to '/' */ + pos = udev->kernel_name; + while (pos[0] != '\0') { + if (pos[0] == '!') + pos[0] = '/'; + pos++; + } + + /* get kernel number */ + pos = &udev->kernel_name[strlen(udev->kernel_name)]; + while (isdigit(pos[-1])) + pos--; + strfieldcpy(udev->kernel_number, pos); + dbg("kernel_number='%s'", udev->kernel_number); + } + } udev->mode = 0660; strcpy(udev->owner, "root"); strcpy(udev->group, "root"); - /* get kernel name */ - pos = strrchr(udev->devpath, '/'); - if (pos == NULL) - return -1; - strfieldcpy(udev->kernel_name, &pos[1]); - - /* get kernel number */ - pos = &udev->kernel_name[strlen(udev->kernel_name)]; - while (isdigit(pos[-1])) - pos--; - strfieldcpy(udev->kernel_number, pos); - dbg("kernel_number='%s'", udev->kernel_number); - - /* Some block devices have '!' in their name, change that to '/' */ - pos = udev->kernel_name; - while (pos[0] != '\0') { - if (pos[0] == '!') - pos[0] = '/'; - pos++; - } - - dbg("kernel_name='%s'", udev->kernel_name); return 0; } From f0308095c78fd68c29be9b3b391bc1c077afa04c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 4 Mar 2005 21:33:57 +0100 Subject: [PATCH 1190/4284] [PATCH] remove typedef for call_foreach_file() handler function --- namedev_parse.c | 9 +++++---- udev.h | 1 + udev_db.h | 2 +- udev_multiplex.c | 11 +++++------ udev_utils.c | 14 +++++--------- udev_utils.h | 12 ++++++++---- 6 files changed, 25 insertions(+), 24 deletions(-) diff --git a/namedev_parse.c b/namedev_parse.c index ed38db4b14..e360565950 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -98,7 +98,7 @@ static char *get_key_attribute(char *str) return NULL; } -static int namedev_parse(const char *filename, void *data) +static int namedev_parse(struct udevice *udev, const char *filename) { char line[LINE_SIZE]; char *bufline; @@ -354,9 +354,9 @@ int namedev_init(void) return -1; if ((stats.st_mode & S_IFMT) != S_IFDIR) - retval = namedev_parse(udev_rules_filename, NULL); + retval = namedev_parse(NULL, udev_rules_filename); else - retval = call_foreach_file(namedev_parse, udev_rules_filename, RULEFILE_SUFFIX, NULL); + retval = call_foreach_file(namedev_parse, NULL, udev_rules_filename, RULEFILE_SUFFIX); return retval; } @@ -364,8 +364,9 @@ int namedev_init(void) void namedev_close(void) { struct config_device *dev; + struct config_device *temp_dev; - list_for_each_entry(dev, &config_device_list, node) { + list_for_each_entry_safe(dev, temp_dev, &config_device_list, node) { list_del(&dev->node); free(dev); } diff --git a/udev.h b/udev.h index ddcfa81c8e..f1236194d6 100644 --- a/udev.h +++ b/udev.h @@ -4,6 +4,7 @@ * Userspace devfs * * Copyright (C) 2003 Greg Kroah-Hartman + * Copyright (C) 2003-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 diff --git a/udev_db.h b/udev_db.h index 6a0647f200..2fce06be72 100644 --- a/udev_db.h +++ b/udev_db.h @@ -28,7 +28,7 @@ extern int udev_db_add_device(struct udevice *dev); extern int udev_db_delete_device(struct udevice *dev); -extern int udev_db_get_device_by_devpath(struct udevice *dev, const char *devpath); +extern int udev_db_get_device_by_devpath(struct udevice *udev, const char *devpath); extern int udev_db_get_device_by_name(struct udevice *udev, const char *name); extern int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)); diff --git a/udev_multiplex.c b/udev_multiplex.c index 3a484068ff..6d7852dbc0 100644 --- a/udev_multiplex.c +++ b/udev_multiplex.c @@ -31,11 +31,10 @@ #include "udev_utils.h" #include "logging.h" -static int run_program(const char *filename, void *data) +static int run_program(struct udevice *udev, const char *filename) { pid_t pid; int fd; - struct udevice *udev = data; dbg("running %s", filename); @@ -89,7 +88,7 @@ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const c if (strcmp(devname, udev->subsystem) != 0) { snprintf(dirname, PATH_MAX, "%s/%s", basedir, devname); dirname[PATH_MAX-1] = '\0'; - call_foreach_file(run_program, dirname, suffix, udev); + call_foreach_file(run_program, udev, dirname, suffix); } temp[0] = '/'; @@ -101,16 +100,16 @@ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const c if (udev->name[0] != '\0') { snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->name); dirname[PATH_MAX-1] = '\0'; - call_foreach_file(run_program, dirname, suffix, udev); + call_foreach_file(run_program, udev, dirname, suffix); } if (udev->subsystem[0] != '\0') { snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->subsystem); dirname[PATH_MAX-1] = '\0'; - call_foreach_file(run_program, dirname, suffix, udev); + call_foreach_file(run_program, udev, dirname, suffix); } snprintf(dirname, PATH_MAX, "%s/default", basedir); dirname[PATH_MAX-1] = '\0'; - call_foreach_file(run_program, dirname, suffix, udev); + call_foreach_file(run_program, udev, dirname, suffix); } diff --git a/udev_utils.c b/udev_utils.c index f2534dd331..cfa4ab51b3 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -259,13 +259,7 @@ void no_trailing_slash(char *path) path[--len] = '\0'; } -struct name_entry { - struct list_head node; - char name[NAME_SIZE]; -}; - -/* sort files in lexical order */ -static int name_list_add(struct list_head *name_list, const char *name, int sort) +int name_list_add(struct list_head *name_list, const char *name, int sort) { struct name_entry *loop_name; struct name_entry *new_name; @@ -288,11 +282,13 @@ static int name_list_add(struct list_head *name_list, const char *name, int sort strfieldcpy(new_name->name, name); list_add_tail(&new_name->node, &loop_name->node); + return 0; } /* calls function for every file found in specified directory */ -int call_foreach_file(file_fnct_t fnct, const char *dirname, const char *suffix, void *data) +int call_foreach_file(int (*handler_function)(struct udevice *udev, const char *string), + struct udevice *udev, const char *dirname, const char *suffix) { struct dirent *ent; DIR *dir; @@ -335,7 +331,7 @@ int call_foreach_file(file_fnct_t fnct, const char *dirname, const char *suffix, snprintf(filename, NAME_SIZE, "%s/%s", dirname, loop_file->name); filename[NAME_SIZE-1] = '\0'; - fnct(filename, data); + handler_function(udev, filename); list_del(&loop_file->node); free(loop_file); diff --git a/udev_utils.h b/udev_utils.h index 268c2075de..1ab4752cd3 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -76,6 +76,11 @@ do { \ # define asmlinkage /* nothing */ #endif +struct name_entry { + struct list_head node; + char name[NAME_SIZE]; +}; + extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); @@ -85,8 +90,7 @@ extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); extern void no_trailing_slash(char *path); -typedef int (*file_fnct_t)(const char *filename, void *data); -extern int call_foreach_file(file_fnct_t fnct, const char *dirname, - const char *suffix, void *data); - +extern int name_list_add(struct list_head *name_list, const char *name, int sort); +extern int call_foreach_file(int (*handler_function)(struct udevice *udev, const char *string), + struct udevice *udev, const char *dirname, const char *suffix); #endif From 237415b141ae2f3915160bc43ed76296588299f0 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 02:33:31 +0100 Subject: [PATCH 1191/4284] [PATCH] unmap db-file after use --- udev_db.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_db.c b/udev_db.c index 4515998fcd..a423247d6b 100644 --- a/udev_db.c +++ b/udev_db.c @@ -153,6 +153,7 @@ static int parse_db_file(struct udevice *udev, const char *filename) break; } } + file_unmap(buf, bufsize); if (udev->name[0] == '\0') return -1; From 7eb92135c61af77fff62eec5f396b9633a54b245 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 26 Apr 2005 23:48:29 -0700 Subject: [PATCH 1192/4284] more merge fixups, looks like i missed a selinux patch somewhere... --- udev_add.c | 10 +++------- udev_selinux.c | 36 +++++++++++++++++------------------- udev_selinux.h | 6 ++---- 3 files changed, 22 insertions(+), 30 deletions(-) diff --git a/udev_add.c b/udev_add.c index e5bd042a5c..eeab1ca174 100644 --- a/udev_add.c +++ b/udev_add.c @@ -83,7 +83,6 @@ create: selinux_setfscreatecon(file, udev->kernel_name, mode); retval = mknod(file, mode, devt); - selinux_resetfscreatecon(); if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", file, mode, major(devt), minor(devt), strerror(errno)); @@ -197,7 +196,6 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de /* create symlink(s) if requested */ foreach_strpart(udev->symlink, " ", pos, len) { - int retval; char linkname[NAME_SIZE]; char linktarget[NAME_SIZE]; @@ -229,11 +227,9 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de dbg("symlink(%s, %s)", linktarget, filename); if (!udev->test_run) { - unlink(filename); selinux_setfscreatecon(filename, udev->kernel_name, S_IFLNK); - retval = symlink(linktarget, filename); - selinux_resetfscreatecon(); - if (retval != 0) + unlink(filename); + if (symlink(linktarget, filename) != 0) dbg("symlink(%s, %s) failed with error '%s'", linktarget, filename, strerror(errno)); } @@ -330,7 +326,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) } exit: - selinux_exit(); + selinux_restore(); return retval; } diff --git a/udev_selinux.c b/udev_selinux.c index cc6f4d7d3f..72381f0d0d 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -105,7 +105,7 @@ void selinux_setfilecon(const char *file, const char *devname, unsigned int mode } if (setfilecon(file, scontext) < 0) - dbg("setfilecon %s failed with error '%s'", file, strerror(errno)); + dbg("setfiles %s failed with error '%s'", file, strerror(errno)); freecon(scontext); } @@ -131,20 +131,12 @@ void selinux_setfscreatecon(const char *file, const char *devname, unsigned int } if (setfscreatecon(scontext) < 0) - dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); + dbg("setfiles %s failed with error '%s'", file, strerror(errno)); freecon(scontext); } } -void selinux_resetfscreatecon(void) -{ - if (is_selinux_running()) { - if (setfscreatecon(prev_scontext) < 0) - dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); - } -} - void selinux_init(void) { /* @@ -152,17 +144,23 @@ void selinux_init(void) * restoration creation purposes. */ if (is_selinux_running()) { - if (getfscreatecon(&prev_scontext) < 0) { + if (getfscreatecon(&prev_scontext) < 0) dbg("getfscreatecon failed\n"); + + prev_scontext = NULL; + } +} + +void selinux_restore(void) +{ + if (is_selinux_running()) { + /* reset the file create context to its former glory */ + if (setfscreatecon(prev_scontext) < 0) + dbg("setfscreatecon failed\n"); + + if (prev_scontext) { + freecon(prev_scontext); prev_scontext = NULL; } } } - -void selinux_exit(void) -{ - if (is_selinux_running() && prev_scontext) { - freecon(prev_scontext); - prev_scontext = NULL; - } -} diff --git a/udev_selinux.h b/udev_selinux.h index d9dfeffad0..132a9a6550 100644 --- a/udev_selinux.h +++ b/udev_selinux.h @@ -24,17 +24,15 @@ 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); +extern void selinux_restore(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) {} +static inline void selinux_restore(void) {} #endif /* USE_SELINUX */ #endif /* _UDEV_USE_SELINUX */ From e48fc108d9731f6f091742fe6588c495d1948fac Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 05:35:31 +0100 Subject: [PATCH 1193/4284] [PATCH] allow unlimitied count of symlinks --- namedev.c | 27 +++++++---- udev.c | 1 + udev.h | 2 +- udev_add.c | 19 ++++---- udev_db.c | 99 ++++++++++++++++++++++++---------------- udev_db.h | 4 +- udev_remove.c | 31 +++++-------- udev_utils.c | 12 +++++ udev_utils.h | 2 + udevinfo.c | 124 ++++++++++++++++++++++---------------------------- 10 files changed, 172 insertions(+), 149 deletions(-) diff --git a/namedev.c b/namedev.c index 41f0bc0f16..91841571c1 100644 --- a/namedev.c +++ b/namedev.c @@ -144,15 +144,14 @@ static int get_format_len(char **str) */ static int find_free_number(struct udevice *udev, const char *name) { + char devpath[NAME_SIZE]; char filename[NAME_SIZE]; int num = 0; - struct udevice db_udev; strfieldcpy(filename, name); while (1) { dbg("look for existing node '%s'", filename); - memset(&db_udev, 0x00, sizeof(struct udevice)); - if (udev_db_get_device_by_name(&db_udev, filename) != 0) { + if (udev_db_search_name(devpath, DEVPATH_SIZE, filename) != 0) { dbg("free num=%d", num); return num; } @@ -298,13 +297,14 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct udevice udev_parent; dbg("found parent '%s', get the node name", class_dev_parent->path); - memset(&udev_parent, 0x00, sizeof(struct udevice)); + udev_init_device(&udev_parent, NULL, NULL); /* lookup the name in the udev_db with the DEVPATH of the parent */ - if (udev_db_get_device_by_devpath(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) { + if (udev_db_get_device(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) { strfieldcatmax(string, udev_parent.name, maxsize); dbg("substitute parent node name'%s'", udev_parent.name); } else dbg("parent not found in database"); + udev_cleanup_device(&udev_parent); } break; case 'N': @@ -749,14 +749,25 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d /* collect symlinks */ if (dev->symlink[0] != '\0') { char temp[NAME_SIZE]; + char *pos, *next; info("configured rule in '%s[%i]' applied, added symlink '%s'", dev->config_file, dev->config_line, dev->symlink); strfieldcpy(temp, dev->symlink); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); - if (udev->symlink[0] != '\0') - strfieldcat(udev->symlink, " "); - strfieldcat(udev->symlink, temp); + + /* add multiple symlinks separated by spaces */ + pos = temp; + next = strchr(temp, ' '); + while (next) { + next[0] = '\0'; + dbg("add symlink '%s'", pos); + name_list_add(&udev->symlink_list, pos, 0); + pos = &next[1]; + next = strchr(pos, ' '); + } + dbg("add symlink '%s'", pos); + name_list_add(&udev->symlink_list, pos, 0); } /* rule matches */ diff --git a/udev.c b/udev.c index 802e41d147..c26ce46b64 100644 --- a/udev.c +++ b/udev.c @@ -236,6 +236,7 @@ int main(int argc, char *argv[], char *envp[]) } hotplug: + udev_cleanup_device(&udev); if (udev_hotplug_d && managed_event) udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); diff --git a/udev.h b/udev.h index f1236194d6..811439faf2 100644 --- a/udev.h +++ b/udev.h @@ -63,7 +63,7 @@ struct udevice { char name[NAME_SIZE]; char devname[NAME_SIZE]; - char symlink[NAME_SIZE]; + struct list_head symlink_list; char owner[USER_SIZE]; char group[USER_SIZE]; mode_t mode; diff --git a/udev_add.c b/udev_add.c index eeab1ca174..7e0c57fc63 100644 --- a/udev_add.c +++ b/udev_add.c @@ -113,12 +113,11 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de { char filename[NAME_SIZE]; char partitionname[NAME_SIZE]; + struct name_entry *name_loop; uid_t uid = 0; gid_t gid = 0; int tail; - char *pos; - int len; - int i; + int i; snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); filename[NAME_SIZE-1] = '\0'; @@ -195,30 +194,28 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de } /* create symlink(s) if requested */ - foreach_strpart(udev->symlink, " ", pos, len) { - char linkname[NAME_SIZE]; + list_for_each_entry(name_loop, &udev->symlink_list, node) { char linktarget[NAME_SIZE]; - strfieldcpymax(linkname, pos, len+1); - snprintf(filename, NAME_SIZE, "%s/%s", udev_root, linkname); + snprintf(filename, NAME_SIZE, "%s/%s", udev_root, name_loop->name); filename[NAME_SIZE-1] = '\0'; dbg("symlink '%s' to node '%s' requested", filename, udev->name); if (!udev->test_run) - if (strrchr(linkname, '/')) + if (strchr(filename, '/')) create_path(filename); /* optimize relative link */ linktarget[0] = '\0'; i = 0; tail = 0; - while ((udev->name[i] == linkname[i]) && udev->name[i]) { + while (udev->name[i] && (udev->name[i] == name_loop->name[i])) { if (udev->name[i] == '/') tail = i+1; i++; } - while (linkname[i] != '\0') { - if (linkname[i] == '/') + while (name_loop->name[i] != '\0') { + if (name_loop->name[i] == '/') strfieldcat(linktarget, "../"); i++; } diff --git a/udev_db.c b/udev_db.c index a423247d6b..1015d21221 100644 --- a/udev_db.c +++ b/udev_db.c @@ -60,6 +60,7 @@ static int get_db_filename(const char *devpath, char *filename, int len) int udev_db_add_device(struct udevice *udev) { char filename[SYSFS_PATH_MAX]; + struct name_entry *name_loop; FILE *f; if (udev->test_run) @@ -78,7 +79,8 @@ int udev_db_add_device(struct udevice *udev) fprintf(f, "P:%s\n", udev->devpath); fprintf(f, "N:%s\n", udev->name); - fprintf(f, "S:%s\n", udev->symlink); + list_for_each_entry(name_loop, &udev->symlink_list, node) + fprintf(f, "S:%s\n", name_loop->name); fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt)); fprintf(f, "A:%u\n", udev->partitions); fprintf(f, "R:%u\n", udev->ignore_remove); @@ -134,8 +136,9 @@ static int parse_db_file(struct udevice *udev, const char *filename) case 'S': if (count > NAME_SIZE) count = NAME_SIZE-1; - strncpy(udev->symlink, &bufline[2], count-2); - udev->symlink[count-2] = '\0'; + strncpy(temp, &bufline[2], count-2); + temp[count-2] = '\0'; + name_list_add(&udev->symlink_list, temp, 0); break; case 'A': if (count > NAME_SIZE) @@ -171,21 +174,23 @@ int udev_db_delete_device(struct udevice *udev) return 0; } -int udev_db_get_device_by_devpath(struct udevice *udev, const char *devpath) +int udev_db_get_device(struct udevice *udev, const char *devpath) { char filename[SYSFS_PATH_MAX]; get_db_filename(devpath, filename, SYSFS_PATH_MAX); - return parse_db_file(udev, filename); + if (parse_db_file(udev, filename) != 0) + return -1; + + return 0; } -int udev_db_get_device_by_name(struct udevice *udev, const char *name) +int udev_db_search_name(char *devpath, size_t len, const char *name) { struct dirent *ent; DIR *dir; char filename[NAME_SIZE]; - struct udevice db_udev; dir = opendir(udev_db_path); if (dir == NULL) { @@ -194,6 +199,14 @@ int udev_db_get_device_by_name(struct udevice *udev, const char *name) } while (1) { + char path[DEVPATH_SIZE]; + char nodename[NAME_SIZE]; + char *bufline; + char *buf; + size_t bufsize; + size_t cur; + size_t count; + ent = readdir(dir); if (ent == NULL || ent->d_name[0] == '\0') break; @@ -203,42 +216,50 @@ int udev_db_get_device_by_name(struct udevice *udev, const char *name) snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name); filename[NAME_SIZE-1] = '\0'; + dbg("looking at '%s'", filename); - memset(&db_udev, 0x00, sizeof(struct udevice)); - if (parse_db_file(&db_udev, filename) == 0) { - char *pos; - unsigned int len; - - if (strncmp(name, db_udev.name, NAME_SIZE) == 0) { - goto found; - } - - foreach_strpart(db_udev.symlink, " ", pos, len) { - if (strncmp(name, pos, len) != 0) - continue; - - if (len == strlen(name)) - goto found; - } - + if (file_map(filename, &buf, &bufsize) != 0) { + dbg("unable to read db file '%s'", filename); + continue; } + + cur = 0; + while (cur < bufsize) { + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + + switch(bufline[0]) { + case 'P': + if (count > DEVPATH_SIZE) + count = DEVPATH_SIZE-1; + strncpy(path, &bufline[2], count-2); + path[count-2] = '\0'; + break; + case 'N': + case 'S': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(nodename, &bufline[2], count-2); + nodename[count-2] = '\0'; + dbg("compare '%s' '%s'", nodename, name); + if (strcmp(nodename, name) == 0) { + strncpy(devpath, path, len); + devpath[len] = '\0'; + file_unmap(buf, bufsize); + closedir(dir); + return 0; + } + break; + default: + continue; + } + } + file_unmap(buf, bufsize); } closedir(dir); - return -1; - -found: - closedir(dir); - - strfieldcpy(udev->devpath, db_udev.devpath); - strfieldcpy(udev->name, db_udev.name); - strfieldcpy(udev->symlink, db_udev.symlink); - udev->partitions = db_udev.partitions; - udev->ignore_remove = db_udev.ignore_remove; - udev->devt = db_udev.devt; - - return 0; } int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)) @@ -265,7 +286,9 @@ int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)) snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name); filename[NAME_SIZE-1] = '\0'; - memset(&db_udev, 0x00, sizeof(struct udevice)); + dbg("found '%s'", filename); + + udev_init_device(&db_udev, NULL, NULL); if (parse_db_file(&db_udev, filename) == 0) { if (handler_function(&db_udev) != 0) break; diff --git a/udev_db.h b/udev_db.h index 2fce06be72..8840142fe3 100644 --- a/udev_db.h +++ b/udev_db.h @@ -28,8 +28,8 @@ extern int udev_db_add_device(struct udevice *dev); extern int udev_db_delete_device(struct udevice *dev); -extern int udev_db_get_device_by_devpath(struct udevice *udev, const char *devpath); -extern int udev_db_get_device_by_name(struct udevice *udev, const char *name); +extern int udev_db_get_device(struct udevice *udev, const char *devpath); +extern int udev_db_search_name(char *devpath, size_t len, const char *name); extern int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)); #endif /* _UDEV_DB_H_ */ diff --git a/udev_remove.c b/udev_remove.c index 22a363ed34..756eef0476 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -71,11 +71,10 @@ static int delete_node(struct udevice *udev) { char filename[NAME_SIZE]; char partitionname[NAME_SIZE]; + struct name_entry *name_loop; struct stat stats; int retval; int i; - char *pos; - int len; int num; snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); @@ -114,11 +113,8 @@ static int delete_node(struct udevice *udev) if (strchr(udev->name, '/')) delete_path(filename); - foreach_strpart(udev->symlink, " ", pos, len) { - char linkname[NAME_SIZE]; - - strfieldcpymax(linkname, pos, len+1); - snprintf(filename, NAME_SIZE, "%s/%s", udev_root, linkname); + list_for_each_entry(name_loop, &udev->symlink_list, node) { + snprintf(filename, NAME_SIZE, "%s/%s", udev_root, name_loop->name); filename[NAME_SIZE-1] = '\0'; dbg("unlinking symlink '%s'", filename); @@ -130,7 +126,7 @@ static int delete_node(struct udevice *udev) filename, strerror(errno)); return retval; } - if (strchr(udev->symlink, '/')) { + if (strchr(filename, '/')) { delete_path(filename); } } @@ -145,13 +141,18 @@ static int delete_node(struct udevice *udev) int udev_remove_device(struct udevice *udev) { const char *temp; - int retval; if (udev->type != BLOCK && udev->type != CLASS) return 0; - retval = udev_db_get_device_by_devpath(udev, udev->devpath); - if (retval) { + if (udev_db_get_device(udev, udev->devpath) == 0) { + if (udev->ignore_remove) { + dbg("remove event for '%s' requested to be ignored by rule", udev->name); + return 0; + } + dbg("remove name='%s'", udev->name); + udev_db_delete_device(udev); + } else { /* fall back to kernel name */ temp = strrchr(udev->devpath, '/'); if (temp == NULL) @@ -160,14 +161,6 @@ int udev_remove_device(struct udevice *udev) dbg("'%s' not found in database, falling back on default name", udev->name); } - if (udev->ignore_remove) { - dbg("remove event for '%s' requested to be ignored by rule", udev->name); - return 0; - } - - dbg("remove name='%s'", udev->name); - udev_db_delete_device(udev); - /* use full path to the environment */ snprintf(udev->devname, NAME_SIZE, "%s/%s", udev_root, udev->name); diff --git a/udev_utils.c b/udev_utils.c index cfa4ab51b3..60f5ad859a 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -42,6 +42,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs char *pos; memset(udev, 0x00, sizeof(struct udevice)); + INIT_LIST_HEAD(&udev->symlink_list); if (subsystem) strfieldcpy(udev->subsystem, subsystem); @@ -89,6 +90,17 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs return 0; } +void udev_cleanup_device(struct udevice *udev) +{ + struct name_entry *name_loop; + struct name_entry *temp_loop; + + list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { + list_del(&name_loop->node); + free(name_loop); + } +} + int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel) { static unsigned int kversion = 0; diff --git a/udev_utils.h b/udev_utils.h index 1ab4752cd3..2f2c2497cb 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -82,6 +82,8 @@ struct name_entry { }; extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); +extern void udev_cleanup_device(struct udevice *udev); + extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); extern int parse_get_pair(char **orig_string, char **left, char **right); diff --git a/udevinfo.c b/udevinfo.c index 045395256d..6dfb918de5 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -83,10 +83,13 @@ static void print_all_attributes(struct dlist *attr_list) static int print_record(struct udevice *udev) { + struct name_entry *name_loop; + printf("P: %s\n", udev->devpath); printf("N: %s\n", udev->name); - printf("S: %s\n", udev->symlink); - printf("\n"); + list_for_each_entry(name_loop, &udev->symlink_list, node) + printf("S: %s\n", name_loop->name); + return 0; } @@ -95,7 +98,7 @@ enum query_type { NAME, PATH, SYMLINK, - ALL + ALL, }; static int print_device_chain(const char *path) @@ -183,20 +186,25 @@ static int print_dump(struct udevice *udev) { return 0; } -static int process_options(int argc, char *argv[]) +int main(int argc, char *argv[], char *envp[]) { static const char short_options[] = "adn:p:q:rVh"; int option; - int retval = 1; struct udevice udev; int root = 0; int attributes = 0; enum query_type query = NONE; - char result[1024] = ""; char path[NAME_SIZE] = ""; char name[NAME_SIZE] = ""; char temp[NAME_SIZE]; + struct name_entry *name_loop; char *pos; + int retval = 0; + + logging_init("udevinfo"); + + udev_init_config(); + udev_init_device(&udev, NULL, NULL); /* get command line options */ while (1) { @@ -240,7 +248,8 @@ static int process_options(int argc, char *argv[]) } printf("unknown query type\n"); - exit(1); + retval = 1; + goto exit; case 'r': root = 1; @@ -252,14 +261,14 @@ static int process_options(int argc, char *argv[]) case 'd': udev_db_call_foreach(print_dump); - exit(0); + goto exit; case 'V': printf("udevinfo, version %s\n", UDEV_VERSION); - exit(0); + goto exit; case 'h': - retval = 0; + retval = 2; case '?': default: goto help; @@ -275,15 +284,14 @@ static int process_options(int argc, char *argv[]) } else { if (path[0] != '/') { /* prepend '/' if missing */ - strfieldcat(temp, "/"); + strcpy(temp, "/"); strfieldcat(temp, path); pos = temp; } else { pos = path; } } - memset(&udev, 0x00, sizeof(struct udevice)); - retval = udev_db_get_device_by_devpath(&udev, pos); + retval = udev_db_get_device(&udev, pos); if (retval != 0) { printf("device not found in database\n"); goto exit; @@ -292,77 +300,64 @@ static int process_options(int argc, char *argv[]) } if (name[0] != '\0') { - /* remove udev_root if given */ - int len = strlen(udev_root); + char devpath[NAME_SIZE]; + int len; + /* remove udev_root if given */ + len = strlen(udev_root); if (strncmp(name, udev_root, len) == 0) { pos = &name[len+1]; } else pos = name; - memset(&udev, 0x00, sizeof(struct udevice)); - strfieldcpy(udev.name, pos); - retval = udev_db_get_device_by_name(&udev, pos); + retval = udev_db_search_name(devpath, DEVPATH_SIZE, pos); if (retval != 0) { printf("device not found in database\n"); goto exit; } - + udev_db_get_device(&udev, devpath); goto print; } printf("query needs device path(-p) or node name(-n) specified\n"); + retval = 3; goto exit; print: switch(query) { case NAME: - if (root) { - snprintf(result, NAME_SIZE-1, "%s/%s", udev_root, udev.name); - result[NAME_SIZE-1] = '\0'; - } else { - strfieldcpy(result, udev.name); - } - break; - + if (root) + printf("%s/%s\n", udev_root, udev.name); + else + printf("%s\n", udev.name); + goto exit; case SYMLINK: - if (root) { - int slen; - char *spos; - char slink[NAME_SIZE]; - - pos = result; - foreach_strpart(udev.symlink, " \n\r", spos, slen) { - strncpy(slink, spos, slen); - slink[slen] = '\0'; - pos += sprintf(pos, "%s/%s ", udev_root, slink); - } - } else { - strfieldcpy(result, udev.symlink); - } - break; - + if (list_empty(&udev.symlink_list)) + break; + 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"); + goto exit; case PATH: - strfieldcpy(result, udev.devpath); - break; - + printf("%s\n", udev.devpath); + goto exit; case ALL: print_record(&udev); goto exit; - default: - goto exit; + goto help; } - printf("%s\n", result); - -exit: - return retval; } if (attributes) { if (path[0] == '\0') { printf("attribute walk on device chain needs path(-p) specified\n"); - return -EINVAL; + retval = 4; + goto exit; } else { if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) { /* prepend sysfs mountpoint if not given */ @@ -371,13 +366,13 @@ exit: strfieldcat(path, temp); } print_device_chain(path); - return 0; + goto exit; } } if (root) { printf("%s\n", udev_root); - return 0; + goto exit; } help: @@ -398,20 +393,9 @@ help: " -V print udev version\n" " -h print this help text\n" "\n"); + +exit: + udev_cleanup_device(&udev); + logging_close(); return retval; } - -int main(int argc, char *argv[], char *envp[]) -{ - int rc = 0; - - logging_init("udevinfo"); - - /* initialize our configuration */ - udev_init_config(); - - rc = process_options(argc, argv); - - logging_close(); - exit(rc); -} From 51015808dae77026ef6aae369be272289547fe72 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 05:39:19 +0100 Subject: [PATCH 1194/4284] [PATCH] udev-test.pl: remove useless tests --- test/udev-test.pl | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index f442b162ec..9699f2e8f5 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -776,29 +776,6 @@ EOF exp_rem_error => "yes", conf => < "symlink to empty name", - subsys => "block", - devpath => "/block/sda", - exp_name => "symlink", - exp_target => "", - exp_add_error => "yes", - conf => < "symlink and name empty", - subsys => "block", - devpath => "/block/sda", - exp_name => "", - exp_target => "", - exp_add_error => "yes", - exp_rem_error => "yes", - conf => < Date: Sat, 5 Mar 2005 06:50:09 +0100 Subject: [PATCH 1195/4284] [PATCH] replace weird defines by real code --- namedev.c | 39 +++++++++++++++++++++------------------ udev_add.c | 4 ++-- udev_remove.c | 4 ++-- udev_utils.h | 20 +------------------- 4 files changed, 26 insertions(+), 41 deletions(-) diff --git a/namedev.c b/namedev.c index 91841571c1..49f9e4b1f4 100644 --- a/namedev.c +++ b/namedev.c @@ -171,15 +171,10 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, { char temp[NAME_SIZE]; char temp2[NAME_SIZE]; - char *tail; - char *pos; - char *attr; + char *tail, *pos, *cpos, *attr, *rest; int len; int i; char c; - char *spos; - char *rest; - int slen; struct sysfs_attribute *tmpattr; unsigned int next_free_number; struct sysfs_class_device *class_dev_parent; @@ -217,12 +212,14 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': - strintcatmax(string, minor(udev->devt), maxsize); - dbg("substitute minor number '%u'", minor(udev->devt)); + sprintf(temp2, "%d", minor(udev->devt)); + strfieldcatmax(string, temp2, maxsize); + dbg("substitute minor number '%s'", temp2); break; case 'M': - strintcatmax(string, major(udev->devt), maxsize); - dbg("substitute major number '%u'", major(udev->devt)); + sprintf(temp2, "%d", major(udev->devt)); + strfieldcatmax(string, temp2, maxsize); + dbg("substitute major number '%s'", temp2); break; case 'c': if (udev->program_result[0] == '\0') @@ -232,19 +229,25 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, if (attr != NULL) i = strtoul(attr, &rest, 10); if (i > 0) { - foreach_strpart(udev->program_result, " \n\r", spos, slen) { - i--; - if (i == 0) - break; + 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) { dbg("requested part of result string not found"); break; } - if (rest[0] == '+') - strfieldcpy(temp2, spos); - else - strfieldcpymax(temp2, spos, slen+1); + strfieldcpy(temp2, cpos); + /* %{2+}c copies the whole string from the second part on */ + if (rest[0] != '+') { + cpos = strchr(temp2, ' '); + if (cpos) + cpos[0] = '\0'; + } strfieldcatmax(string, temp2, maxsize); dbg("substitute part of result string '%s'", temp2); } else { diff --git a/udev_add.c b/udev_add.c index 7e0c57fc63..aa19d874c3 100644 --- a/udev_add.c +++ b/udev_add.c @@ -185,8 +185,8 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de for (i = 1; i <= udev->partitions; i++) { dev_t part_devt; - strfieldcpy(partitionname, filename); - strintcat(partitionname, i); + snprintf(partitionname, NAME_SIZE, "%s%d", filename, i); + partitionname[NAME_SIZE-1] = '\0'; part_devt = makedev(major(udev->devt), minor(udev->devt)+1); udev_make_node(udev, partitionname, part_devt, udev->mode, uid, gid); } diff --git a/udev_remove.c b/udev_remove.c index 756eef0476..7a6c032d01 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -103,8 +103,8 @@ static int delete_node(struct udevice *udev) return -1; } for (i = 1; i <= num; i++) { - strfieldcpy(partitionname, filename); - strintcat(partitionname, i); + snprintf(partitionname, NAME_SIZE, "%s%d", filename, i); + partitionname[NAME_SIZE-1] = '\0'; unlink_secure(partitionname); } } diff --git a/udev_utils.h b/udev_utils.h index 2f2c2497cb..3bb1b25362 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -48,24 +48,6 @@ do { \ strncat(to, from, maxsize - strlen(to)-1); \ } while (0) -#define strintcat(to, i) \ -do { \ - to[sizeof(to)-1] = '\0'; \ - snprintf((to) + strlen(to), sizeof(to) - strlen(to)-1, "%u", i); \ -} while (0) - -#define strintcatmax(to, i, maxsize) \ -do { \ - to[maxsize-1] = '\0'; \ - snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ -} while (0) - -#define foreach_strpart(str, separator, pos, len) \ - for(pos = str, len = 0; \ - (pos) < ((str) + strlen(str)); \ - pos = pos + len + strspn(pos, separator), len = strcspn(pos, separator)) \ - if (len > 0) - #ifdef asmlinkage # undef asmlinkage #endif @@ -73,7 +55,7 @@ do { \ # define asmlinkage __attribute__((regparm(0))) #endif #ifndef asmlinkage -# define asmlinkage /* nothing */ +# define asmlinkage #endif struct name_entry { From 733677e2c21b1ea3789c5296c84c1730d9ce498d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 07:16:21 +0100 Subject: [PATCH 1196/4284] [PATCH] klibc_fixups: remove unneeded stuff --- Makefile | 1 - klibc_fixups/malloc.h | 9 --------- klibc_fixups/mntent.h | 39 --------------------------------------- libsysfs/dlist.c | 1 + libsysfs/dlist.h | 5 +++-- libsysfs/sysfs.h | 1 - 6 files changed, 4 insertions(+), 52 deletions(-) delete mode 100644 klibc_fixups/malloc.h delete mode 100644 klibc_fixups/mntent.h diff --git a/Makefile b/Makefile index 99a7618795..7c159b3d31 100644 --- a/Makefile +++ b/Makefile @@ -202,7 +202,6 @@ ifeq ($(strip $(USE_KLIBC)),true) HEADERS += \ klibc_fixups/klibc_fixups.h \ - klibc_fixups/mntent.h \ klibc_fixups/pwd.h KLIBC_FIXUP_OBJS = \ diff --git a/klibc_fixups/malloc.h b/klibc_fixups/malloc.h deleted file mode 100644 index 439608e3c4..0000000000 --- a/klibc_fixups/malloc.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifdef __KLIBC__ - -#ifndef _MALLOC_H -#define _MALLOC_H - -#include - -#endif /* _MALLOC_H */ -#endif /* __KLIBC__ */ diff --git a/klibc_fixups/mntent.h b/klibc_fixups/mntent.h deleted file mode 100644 index ea79a2dd63..0000000000 --- a/klibc_fixups/mntent.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef __KLIBC__ - -#ifndef _MNTENT_H -#define _MNTENT_H - -#include - -struct mntent -{ - char *mnt_fsname; - char *mnt_dir; - char *mnt_type; - char *mnt_opts; - int mnt_freq; - int mnt_passno; -}; - -static inline FILE *setmntent (const char *file, const char *mode) -{ - return (FILE *) 1; -} - -static inline struct mntent *getmntent (FILE *stream) -{ - static struct mntent mntent = { - .mnt_dir = "/sys", - .mnt_type = "sysfs" - }; - - return &mntent; -} - -static inline int endmntent (FILE *stream) -{ - return 0; -} - -#endif /* _MNTENT_H */ -#endif /* __KLIBC__ */ diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index c4ee324573..c44e9d5ff5 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -27,6 +27,7 @@ * delete function. Otherwise dlist will just use free. */ +#include "stdlib.h" #include "dlist.h" /* diff --git a/libsysfs/dlist.h b/libsysfs/dlist.h index 9e3a6c96de..62eaa9fec4 100644 --- a/libsysfs/dlist.h +++ b/libsysfs/dlist.h @@ -50,9 +50,10 @@ * Just use the dlist_(insert|delete)_(before|after) macros if you do not want * to think about it. - */ -#include + +#include + typedef struct dl_node { struct dl_node *prev; struct dl_node *next; diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 30bd9b4089..838427797d 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include From fa548924d4bf723a310e040feaba3f417757de8a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 07:36:51 +0100 Subject: [PATCH 1197/4284] [PATCH] klibc: version 0.211 --- klibc/MCONFIG | 9 ++++- klibc/Makefile | 26 +++++++------- klibc/include/arch/sparc/klibc/archsignal.h | 27 ++++++++++++++- klibc/include/sys/times.h | 4 +-- klibc/klcc.in | 14 ++++---- klibc/klibc.spec.in | 38 +++++++++++++++++---- klibc/klibc/Makefile | 2 +- klibc/klibc/SYSCALLS.def | 10 +++--- klibc/klibc/arch/i386/MCONFIG | 10 +++--- klibc/klibc/arch/i386/crt0.S | 2 +- klibc/klibc/arch/i386/exits.S | 2 +- klibc/klibc/arch/i386/libgcc/__ashldi3.S | 2 +- klibc/klibc/arch/i386/libgcc/__ashrdi3.S | 2 +- klibc/klibc/arch/i386/libgcc/__lshrdi3.S | 2 +- klibc/klibc/arch/i386/libgcc/__muldi3.S | 2 +- klibc/klibc/arch/i386/libgcc/__negdi2.S | 2 +- klibc/klibc/arch/i386/open.S | 2 +- klibc/klibc/arch/i386/setjmp.S | 4 +-- klibc/klibc/arch/i386/syscall.S | 4 +-- klibc/klibc/arch/i386/sysstub.ph | 2 +- klibc/klibc/arch/x86_64/MCONFIG | 3 ++ klibc/klibc/open.c | 3 +- klibc/klibc/sigaction.c | 2 +- klibc/version | 2 +- 24 files changed, 120 insertions(+), 56 deletions(-) diff --git a/klibc/MCONFIG b/klibc/MCONFIG index a7b2cb1bf3..c833499483 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -3,6 +3,14 @@ # Makefile configuration, without explicit rules # +# CROSS is the prefix used for system tools like gcc, ld etc. +CROSS = + +# KCROSS is the prefix we use for klibc installations. This is usually +# the same as CROSS, but may be different, e.g. to install an i386 +# cross-compilation suite on an x86-64 system, using the same gcc/binutils. +KCROSS ?= $(CROSS) + # Location for installation prefix = /usr bindir = $(prefix)/bin @@ -22,7 +30,6 @@ KRNLSRC = $(SRCROOT)/linux KRNLOBJ = $(SRCROOT)/linux ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) -CROSS = CC = $(CROSS)gcc LD = $(CROSS)ld KLIBSRC = $(SRCROOT)/klibc diff --git a/klibc/Makefile b/klibc/Makefile index eb8f55570d..812ea92f47 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -17,6 +17,7 @@ $(CROSS)klibc.config: Makefile rm -f $@ echo 'ARCH=$(ARCH)' >> $@ echo 'CROSS=$(CROSS)' >> $@ + echo 'KCROSS=$(KCROSS)' >> $@ echo "CC=$(shell bash -c 'type -p $(CC)')" >> $@ echo "LD=$(shell bash -c 'type -p $(LD)')" >> $@ echo 'REQFLAGS=$(filter-out -I%,$(REQFLAGS))' >> $@ @@ -49,19 +50,20 @@ local-install: $(CROSS)klcc mkdir -p $(INSTALLROOT)$(mandir)/man1 mkdir -p $(INSTALLROOT)$(SHLIBDIR) mkdir -p $(INSTALLROOT)$(INSTALLDIR) - -rm -rf $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)lib - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)bin - set -xe ; for d in linux asm asm-generic ; do \ + -rm -rf $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)lib + mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)bin + set -xe ; for d in linux asm-$(ARCH) asm-generic $(ASMARCH); do \ mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d ; \ - cp -rfL $(KRNLSRC)/include/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d/. ; \ - cp -rfL $(KRNLOBJ)/include/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d/. ; \ - [ ! -d $(KRNLOBJ)/include2/$$d ] || \ - cp -rfL $(KRNLOBJ)/include2/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d/. ; \ + for r in $(KRNLSRC)/include $(KRNLOBJ)/include $(KRNLOBJ)/include2 ; do \ + [ ! -d $$r/$$d ] || \ + cp -rfL $$r/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include/$$d/. ; \ + done ; \ done - cp -rf include/. $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/. - $(INSTALL_DATA) klcc.1 $(INSTALLROOT)$(mandir)/man1/$(CROSS)klcc.1 - $(INSTALL_EXEC) $(CROSS)klcc $(INSTALLROOT)$(bindir) + cd $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include && ln -sf asm-$(ARCH) asm + cp -rf include/. $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include/. + $(INSTALL_DATA) klcc.1 $(INSTALLROOT)$(mandir)/man1/$(KCROSS)klcc.1 + $(INSTALL_EXEC) $(KCROSS)klcc $(INSTALLROOT)$(bindir) -include MCONFIG diff --git a/klibc/include/arch/sparc/klibc/archsignal.h b/klibc/include/arch/sparc/klibc/archsignal.h index 6af3709033..3be67a2158 100644 --- a/klibc/include/arch/sparc/klibc/archsignal.h +++ b/klibc/include/arch/sparc/klibc/archsignal.h @@ -8,6 +8,31 @@ #ifndef _KLIBC_ARCHSIGNAL_H #define _KLIBC_ARCHSIGNAL_H -/* No special stuff for this architecture */ +/* Hidden definitions */ + +struct __new_sigaction { + __sighandler_t sa_handler; + unsigned long sa_flags; + void (*sa_restorer)(void); /* Not used by Linux/SPARC */ + __new_sigset_t sa_mask; +}; + +struct k_sigaction { + struct __new_sigaction sa; + void __user *ka_restorer; +}; + +struct __old_sigaction { + __sighandler_t sa_handler; + __old_sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); /* not used by Linux/SPARC */ +}; + +typedef struct sigaltstack { + void __user *ss_sp; + int ss_flags; + size_t ss_size; +} stack_t; #endif diff --git a/klibc/include/sys/times.h b/klibc/include/sys/times.h index 657f9c4b1c..dd86531669 100644 --- a/klibc/include/sys/times.h +++ b/klibc/include/sys/times.h @@ -5,10 +5,10 @@ #ifndef _SYS_TIMES_H #define _SYS_TIMES_H +#include +#include #include __extern clock_t times(struct tms *); -__extern int gettimeofday(struct timeval *, struct timezone *); -__extern int settimeofday(const struct timeval *, const struct timezone *); #endif /* _SYS_TIMES_H */ diff --git a/klibc/klcc.in b/klibc/klcc.in index 713843c37c..bdd03e73b3 100644 --- a/klibc/klcc.in +++ b/klibc/klcc.in @@ -1,19 +1,19 @@ # -*- perl -*- # Standard includes -@includes = ("-I${INSTALLDIR}/${CROSS}include/arch/${ARCH}", - "-I${INSTALLDIR}/${CROSS}include/bits${BITSIZE}", - "-I${INSTALLDIR}/${CROSS}include"); +@includes = ("-I${INSTALLDIR}/${KCROSS}include/arch/${ARCH}", + "-I${INSTALLDIR}/${KCROSS}include/bits${BITSIZE}", + "-I${INSTALLDIR}/${KCROSS}include"); # Default optimization options (for compiles without -g) @optopt = @OPTFLAGS; @goptopt = ('-O'); # Options and libraries to pass to ld; shared versus static -@staticopt = ("$INSTALLDIR/${CROSS}lib/crt0.o"); -@staticlib = ("$INSTALLDIR/${CROSS}lib/libc.a"); -@sharedopt = (@EMAIN, "$INSTALLDIR/${CROSS}lib/interp.o"); -@sharedlib = ('-R', "$INSTALLDIR/lib/${CROSS}libc.so"); +@staticopt = ("$INSTALLDIR/${KCROSS}lib/crt0.o"); +@staticlib = ("$INSTALLDIR/${KCROSS}lib/libc.a"); +@sharedopt = (@EMAIN, "$INSTALLDIR/${KCROSS}lib/interp.o"); +@sharedlib = ('-R', "$INSTALLDIR/${KCROSS}lib/libc.so"); # Returns the language (-x option string) for a specific extension. sub filename2lang($) { diff --git a/klibc/klibc.spec.in b/klibc/klibc.spec.in index 237771532a..cab496b917 100644 --- a/klibc/klibc.spec.in +++ b/klibc/klibc.spec.in @@ -19,13 +19,21 @@ Vendor: Starving Linux Artists %description %{name} is intended to be a minimalistic libc subset for use with initramfs. It is deliberately written for small size, minimal -entanglement, and portability, not speed. It is definitely a work in -progress, and a lot of things are still missing. +entanglement, and portability, not speed. + +%package devel +Summary: Libraries and tools needed to compile applications against klibc. +Group: Development/Libraries +Requires: klibc = %{version}-%{release} + +%description devel +This package contains the link libraries, header files, and gcc +wrapper scripts needed to compile applications against klibc. %package utils Summary: Small utilities built with klibc. Group: Utilities/System -Requires: klibc = %{version} +Requires: klibc = %{version}-%{release} %description utils This package contains a collection of programs that are linked against @@ -62,8 +70,11 @@ make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} \ install -# Install the docs +# Make the .so file in /lib a hardlink (they will be expanded as two +# files automatically if it crosses filesystems when extracted.) +ln -f %{buildroot}%{klibcdir}/lib/klibc-*.so %{buildroot}/lib +# Install the docs mkdir -p %{buildroot}%{bindocdir} %{buildroot}%{libdocdir} install -m 444 README %{buildroot}%{libdocdir} install -m 444 klibc/README %{buildroot}%{libdocdir}/README.klibc @@ -77,12 +88,25 @@ install -m 444 kinit/README %{buildroot}%{bindocdir}/README.kinit %clean rm -rf $RPM_BUILD_ROOT +# +# Note: libc.so and interp.o are technically -devel files, but +# put them in this package until we can make really, really sure +# the dependency system can avoid confusion. (In fact, it would be +# good to eventually get them out of here, so that multiple runtimes +# can be installed should it be necessary.) +# %files %defattr(-,root,root,-) -%{klibcdir}/lib -%{klibcdir}/include -%{_bindir}/klcc /lib/klibc-*.so +%{klibcdir}/lib/*.so +%{klibcdir}/lib/interp.o + +%files devel +%defattr(-,root,root,-) +%{klibcdir}/include +%{klibcdir}/lib/*.a +%{klibcdir}/lib/crt0.o +%{_bindir}/klcc %doc %{_mandir}/man1/* %doc %{libdocdir}/* diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index a9aedc58f0..c412a9ffea 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -116,7 +116,7 @@ $(SOLIB).hash: $(SOLIB) sha1hash $(SOHASH): $(SOLIB) $(SOLIB).hash cp -f $(SOLIB) $@ - $(STRIP) $@ + $(STRIPCMD) $@ rm -f klibc-??????????????????????.so ln -f $@ klibc-`cat $(SOLIB).hash`.so diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def index 3918bcb012..e8b9a7f176 100644 --- a/klibc/klibc/SYSCALLS.def +++ b/klibc/klibc/SYSCALLS.def @@ -146,13 +146,15 @@ ssize_t pwrite64,pwrite::pwrite(int, void *, size_t, off_t) ; Signal operations ; int kill(pid_t, int) +; We really should get rid of the non-rt_* of these, but that takes +; sanitizing for all architectures, sigh... int sigaction(int, const struct sigaction *, struct sigaction *) -int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) int sigsuspend(const sigset_t *) -int rt_sigsuspend(const sigset_t *, size_t) - int sigpending(sigset_t) -int rt_sigpending(sigset_t *, size_t) + int sigpending(sigset_t *) int sigprocmask(int, const sigset_t *, sigset_t *) +int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) +int rt_sigsuspend(const sigset_t *, size_t) +int rt_sigpending(sigset_t *, size_t) int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t) unsigned int alarm(unsigned int) int getitimer(int, struct itimerval *) diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG index 8310e26381..ecd1307d7f 100644 --- a/klibc/klibc/arch/i386/MCONFIG +++ b/klibc/klibc/arch/i386/MCONFIG @@ -8,16 +8,16 @@ # # Enable this to compile with register parameters; only safe for -# gcc > 3 -REGPARM_OPT := -mregparm=3 -DREGPARM=3 +# gcc >= 3 +REGPARM_OPT := -mregparm=3 -D_REGPARM=3 gcc_major := $(shell echo __GNUC__ | $(CC) -E -xc - | tail -n 1) -OPTFLAGS = -march=i386 -Os -g +OPTFLAGS = -march=i386 -Os -g -fomit-frame-pointer LDFLAGS = -m elf_i386 -ifneq ($(shell if [ $(gcc_major) -gt 2 ] ; then echo "new"; fi ;),) -REGPARM := $(REGPARM_OPT) +ifneq ($(gcc_major),2) +REQFLAGS += $(REGPARM_OPT) OPTFLAGS += -falign-functions=0 -falign-jumps=0 -falign-loops=0 ARCHREQFLAGS += -m32 else diff --git a/klibc/klibc/arch/i386/crt0.S b/klibc/klibc/arch/i386/crt0.S index 0f3a7db35e..fb02c694c0 100644 --- a/klibc/klibc/arch/i386/crt0.S +++ b/klibc/klibc/arch/i386/crt0.S @@ -20,7 +20,7 @@ _start: push %ebp # Keep gdb from getting confused push %ebp # Keep gdb from getting confused # Push the arguments and called __libc_init() -#ifndef REGPARM +#ifndef _REGPARM push %edx # atexit() function push %eax # ELF array #endif diff --git a/klibc/klibc/arch/i386/exits.S b/klibc/klibc/arch/i386/exits.S index 59ff563ad8..ed23d98bcb 100644 --- a/klibc/klibc/arch/i386/exits.S +++ b/klibc/klibc/arch/i386/exits.S @@ -28,7 +28,7 @@ exit: .globl _exit .type _exit,@function _exit: -#ifdef REGPARM +#ifdef _REGPARM movl %eax,%ebx #else popl %ebx diff --git a/klibc/klibc/arch/i386/libgcc/__ashldi3.S b/klibc/klibc/arch/i386/libgcc/__ashldi3.S index 80ed4be3cf..61982eb0eb 100644 --- a/klibc/klibc/arch/i386/libgcc/__ashldi3.S +++ b/klibc/klibc/arch/i386/libgcc/__ashldi3.S @@ -8,7 +8,7 @@ .globl __ashldi3 .type __ashldi3,@function __ashldi3: -#ifndef REGPARM +#ifndef _REGPARM movl 4(%esp),%eax movl 8(%esp),%edx movb 12(%esp),%cl diff --git a/klibc/klibc/arch/i386/libgcc/__ashrdi3.S b/klibc/klibc/arch/i386/libgcc/__ashrdi3.S index ba43f9022a..4ac2af69a1 100644 --- a/klibc/klibc/arch/i386/libgcc/__ashrdi3.S +++ b/klibc/klibc/arch/i386/libgcc/__ashrdi3.S @@ -8,7 +8,7 @@ .globl __ashrdi3 .type __ashrdi3,@function __ashrdi3: -#ifndef REGPARM +#ifndef _REGPARM movl 4(%esp),%eax movl 8(%esp),%edx movb 12(%esp),%cl diff --git a/klibc/klibc/arch/i386/libgcc/__lshrdi3.S b/klibc/klibc/arch/i386/libgcc/__lshrdi3.S index 6e521ace2c..730ee43178 100644 --- a/klibc/klibc/arch/i386/libgcc/__lshrdi3.S +++ b/klibc/klibc/arch/i386/libgcc/__lshrdi3.S @@ -8,7 +8,7 @@ .globl __lshrdi3 .type __lshrdi3,@function __lshrdi3: -#ifndef REGPARM +#ifndef _REGPARM movl 4(%esp),%eax movl 8(%esp),%edx movb 12(%esp),%cl diff --git a/klibc/klibc/arch/i386/libgcc/__muldi3.S b/klibc/klibc/arch/i386/libgcc/__muldi3.S index c164588b16..81e23b190e 100644 --- a/klibc/klibc/arch/i386/libgcc/__muldi3.S +++ b/klibc/klibc/arch/i386/libgcc/__muldi3.S @@ -10,7 +10,7 @@ .type __muldi3,@function __muldi3: push %esi -#ifndef REGPARM +#ifndef _REGPARM movl 8(%esp),%eax movl %eax,%esi movl 16(%esp),%ecx diff --git a/klibc/klibc/arch/i386/libgcc/__negdi2.S b/klibc/klibc/arch/i386/libgcc/__negdi2.S index 6c95cb235c..c4f2cd517e 100644 --- a/klibc/klibc/arch/i386/libgcc/__negdi2.S +++ b/klibc/klibc/arch/i386/libgcc/__negdi2.S @@ -9,7 +9,7 @@ .globl __negdi2 .type __negdi2,@function __negdi2: -#ifndef REGPARM +#ifndef _REGPARM movl 4(%esp),%eax movl 8(%esp),%edx #endif diff --git a/klibc/klibc/arch/i386/open.S b/klibc/klibc/arch/i386/open.S index 4f492a1566..54dd6151d1 100644 --- a/klibc/klibc/arch/i386/open.S +++ b/klibc/klibc/arch/i386/open.S @@ -15,7 +15,7 @@ .type open,@function open: -#ifdef REGPARM +#ifdef _REGPARM movl 4(%esp),%eax movl 8(%esp),%edx movl 12(%esp),%ecx diff --git a/klibc/klibc/arch/i386/setjmp.S b/klibc/klibc/arch/i386/setjmp.S index bea900c519..2f3033f5bd 100644 --- a/klibc/klibc/arch/i386/setjmp.S +++ b/klibc/klibc/arch/i386/setjmp.S @@ -19,7 +19,7 @@ .globl setjmp .type setjmp, @function setjmp: -#ifdef REGPARM +#ifdef _REGPARM movl %eax,%edx #else movl 4(%esp),%edx @@ -42,7 +42,7 @@ setjmp: .globl longjmp .type longjmp, @function longjmp: -#ifdef REGPARM +#ifdef _REGPARM xchgl %eax,%edx #else movl 4(%esp),%edx # jmp_ptr address diff --git a/klibc/klibc/arch/i386/syscall.S b/klibc/klibc/arch/i386/syscall.S index f8fa7b4dd3..0634e8208a 100644 --- a/klibc/klibc/arch/i386/syscall.S +++ b/klibc/klibc/arch/i386/syscall.S @@ -14,7 +14,7 @@ .globl __syscall_common .type __syscall_common,@function __syscall_common: -#ifdef REGPARM +#ifdef _REGPARM xchgl %ebx,(%esp) #else popl %eax @@ -24,7 +24,7 @@ __syscall_common: pushl %edi pushl %ebp -#ifdef REGPARM +#ifdef _REGPARM xchgl %eax,%ebx xchgl %ecx,%edx movl ARG(0),%esi diff --git a/klibc/klibc/arch/i386/sysstub.ph b/klibc/klibc/arch/i386/sysstub.ph index eaa8180911..1ba7f36bac 100644 --- a/klibc/klibc/arch/i386/sysstub.ph +++ b/klibc/klibc/arch/i386/sysstub.ph @@ -16,7 +16,7 @@ sub make_sysstub($$$$@) { print OUT "${fname}:\n"; if ( $stype eq 'varadic' ) { - print OUT "#ifdef REGPARM\n"; + print OUT "#ifdef _REGPARM\n"; print OUT "\tmovl 4(%esp),%eax\n"; print OUT "\tmovl 8(%esp),%edx\n"; print OUT "\tmovl 12(%esp),%ecx\n"; diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG index a2a2367633..13b6e391f9 100644 --- a/klibc/klibc/arch/x86_64/MCONFIG +++ b/klibc/klibc/arch/x86_64/MCONFIG @@ -26,3 +26,6 @@ LDFLAGS = -m elf_x86_64 # 2 MB - normal binaries start at 4 MB SHAREDFLAGS = -Ttext 0x00200200 +# Additional asm- directories needed during installation +ASMARCH = asm-i386 + diff --git a/klibc/klibc/open.c b/klibc/klibc/open.c index d52b53a699..cb1f5195db 100644 --- a/klibc/klibc/open.c +++ b/klibc/klibc/open.c @@ -8,8 +8,9 @@ #define _KLIBC_IN_OPEN_C #include #include +#include -#if BITSIZE == 32 && !defined(__i386__) +#if _BITSIZE == 32 && !defined(__i386__) extern int __open(const char *, int, mode_t); diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c index 885bc6a4a4..819ffd4fe8 100644 --- a/klibc/klibc/sigaction.c +++ b/klibc/klibc/sigaction.c @@ -5,7 +5,7 @@ #include #include -#if !defined(__NR_sigaction) +#ifndef __NR_sigaction int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { diff --git a/klibc/version b/klibc/version index 58be07ab5e..1f39702100 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.205 +0.211 From 599e17a3e6678eecfd12874cbd35698591df068d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 11:55:59 +0100 Subject: [PATCH 1198/4284] [PATCH] udevinfo -d: speed-up device dump --- udev_db.c | 62 +++++++++++++++++++++++++++++++++++++++++++----------- udev_db.h | 2 +- udevinfo.c | 6 +++--- 3 files changed, 54 insertions(+), 16 deletions(-) diff --git a/udev_db.c b/udev_db.c index 1015d21221..c12e88c3c4 100644 --- a/udev_db.c +++ b/udev_db.c @@ -188,9 +188,7 @@ int udev_db_get_device(struct udevice *udev, const char *devpath) int udev_db_search_name(char *devpath, size_t len, const char *name) { - struct dirent *ent; DIR *dir; - char filename[NAME_SIZE]; dir = opendir(udev_db_path); if (dir == NULL) { @@ -199,6 +197,8 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) } while (1) { + struct dirent *ent; + char filename[NAME_SIZE]; char path[DEVPATH_SIZE]; char nodename[NAME_SIZE]; char *bufline; @@ -262,12 +262,9 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) return -1; } -int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)) +int udev_db_dump_names(int (*handler_function)(const char *path, const char *name)) { - struct dirent *ent; DIR *dir; - char filename[NAME_SIZE]; - struct udevice db_udev; dir = opendir(udev_db_path); if (dir == NULL) { @@ -276,6 +273,16 @@ int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)) } while (1) { + struct dirent *ent; + char filename[NAME_SIZE]; + char path[DEVPATH_SIZE]; + char nodename[NAME_SIZE]; + char *bufline; + char *buf; + size_t bufsize; + size_t cur; + size_t count; + ent = readdir(dir); if (ent == NULL || ent->d_name[0] == '\0') break; @@ -285,14 +292,45 @@ int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)) snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name); filename[NAME_SIZE-1] = '\0'; + dbg("looking at '%s'", filename); - dbg("found '%s'", filename); - - udev_init_device(&db_udev, NULL, NULL); - if (parse_db_file(&db_udev, filename) == 0) { - if (handler_function(&db_udev) != 0) - break; + if (file_map(filename, &buf, &bufsize) != 0) { + dbg("unable to read db file '%s'", filename); + continue; } + + path[0] = '\0'; + nodename[0] = '\0'; + cur = 0; + while (cur < bufsize) { + count = buf_get_line(buf, bufsize, cur); + bufline = &buf[cur]; + cur += count+1; + + switch(bufline[0]) { + case 'P': + if (count > DEVPATH_SIZE) + count = DEVPATH_SIZE-1; + strncpy(path, &bufline[2], count-2); + path[count-2] = '\0'; + break; + case 'N': + if (count > NAME_SIZE) + count = NAME_SIZE-1; + strncpy(nodename, &bufline[2], count-2); + nodename[count-2] = '\0'; + break; + default: + continue; + } + } + file_unmap(buf, bufsize); + + if (path[0] == '\0' || nodename[0] == '\0') + continue; + + if (handler_function(path, nodename) != 0) + break; } closedir(dir); diff --git a/udev_db.h b/udev_db.h index 8840142fe3..9420981944 100644 --- a/udev_db.h +++ b/udev_db.h @@ -30,6 +30,6 @@ 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_search_name(char *devpath, size_t len, const char *name); -extern int udev_db_call_foreach(int (*handler_function)(struct udevice *udev)); +extern int udev_db_dump_names(int (*handler_function)(const char *path, const char *name)); #endif /* _UDEV_DB_H_ */ diff --git a/udevinfo.c b/udevinfo.c index 6dfb918de5..b2d22e984e 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -181,8 +181,8 @@ exit: return retval; } -static int print_dump(struct udevice *udev) { - printf("%s:%s/%s\n", udev->devpath, udev_root, udev->name); +static int print_dump(const char *devpath, const char *name) { + printf("%s:%s/%s\n", devpath, udev_root, name); return 0; } @@ -260,7 +260,7 @@ int main(int argc, char *argv[], char *envp[]) break; case 'd': - udev_db_call_foreach(print_dump); + udev_db_dump_names(print_dump); goto exit; case 'V': From 9bad6028f738e78b69d18947d586dce7b9267785 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 22:26:15 +0100 Subject: [PATCH 1199/4284] [PATCH] fix up segfaulting binaries with new klibc --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7c159b3d31..ac60ade52a 100644 --- a/Makefile +++ b/Makefile @@ -188,7 +188,7 @@ ifeq ($(strip $(USE_KLIBC)),true) CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) CFLAGS += $(WARNINGS) -nostdinc \ - $(OPTFLAGS) \ + $(OPTFLAGS) $(REQFLAGS) \ -D__KLIBC__ -fno-builtin-printf \ -I$(KLIBC_FIXUPS_DIR) \ -include $(KLIBC_FIXUPS_DIR)/klibc_fixups.h \ From 915a12adc2ea28dc2391788c66b829caefefcfb4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 5 Mar 2005 22:41:00 +0100 Subject: [PATCH 1200/4284] [PATCH] use numeric owner/group as default values to avoid parsing userdb --- udev_utils.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udev_utils.c b/udev_utils.c index 60f5ad859a..145f02b5e1 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -84,8 +84,8 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs } udev->mode = 0660; - strcpy(udev->owner, "root"); - strcpy(udev->group, "root"); + strcpy(udev->owner, "0"); + strcpy(udev->group, "0"); return 0; } From 30c6b4c9a22edc76b2e8335edbdf157dd51241eb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 6 Mar 2005 02:02:45 +0100 Subject: [PATCH 1201/4284] [PATCH] udev_volume_id: volume_id v38 --- extras/volume_id/volume_id/luks.c | 77 +++++++++++--------------- extras/volume_id/volume_id/util.c | 9 +++ extras/volume_id/volume_id/util.h | 1 + extras/volume_id/volume_id/volume_id.c | 3 +- extras/volume_id/volume_id/volume_id.h | 8 +-- 5 files changed, 48 insertions(+), 50 deletions(-) diff --git a/extras/volume_id/volume_id/luks.c b/extras/volume_id/volume_id/luks.c index 2001692731..a00bf4041b 100644 --- a/extras/volume_id/volume_id/luks.c +++ b/extras/volume_id/volume_id/luks.c @@ -26,7 +26,6 @@ # include #endif -#include #include #include #include @@ -40,58 +39,47 @@ #include "logging.h" #include "luks.h" -/* from cryptsetup-luks internal.h */ -#define SECTOR_SHIFT 9 -#define SECTOR_SIZE (1 << SECTOR_SHIFT) +#define SECTOR_SHIFT 9 +#define SECTOR_SIZE (1 << SECTOR_SHIFT) -/* from cryptsetup-luks luks.h */ -#define LUKS_CIPHERNAME_L 32 -#define LUKS_CIPHERMODE_L 32 -#define LUKS_HASHSPEC_L 32 -#define LUKS_DIGESTSIZE 20 /* since SHA1 */ -#define LUKS_SALTSIZE 32 -#define LUKS_NUMKEYS 8 +#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 -/* from cryptsetup-luks luks.h */ -const unsigned char LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; +const __u8 LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; #define LUKS_MAGIC_L 6 - -/* from cryptsetup-luks luks.h */ #define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1) - -/* from cryptsetup-luks luks.h */ #define UUID_STRING_L 40 +struct luks_phdr { + __u8 magic[LUKS_MAGIC_L]; + __u16 version; + __u8 cipherName[LUKS_CIPHERNAME_L]; + __u8 cipherMode[LUKS_CIPHERMODE_L]; + __u8 hashSpec[LUKS_HASHSPEC_L]; + __u32 payloadOffset; + __u32 keyBytes; + __u8 mkDigest[LUKS_DIGESTSIZE]; + __u8 mkDigestSalt[LUKS_SALTSIZE]; + __u32 mkDigestIterations; + __u8 uuid[UUID_STRING_L]; + struct { + __u32 active; + __u32 passwordIterations; + __u8 passwordSalt[LUKS_SALTSIZE]; + __u32 keyMaterialOffset; + __u32 stripes; + } keyblock[LUKS_NUMKEYS]; +}; + int volume_id_probe_luks(struct volume_id *id, __u64 off) { - /* from cryptsetup-luks luks.h */ - struct luks_phdr { - char magic[LUKS_MAGIC_L]; - uint16_t version; - char cipherName[LUKS_CIPHERNAME_L]; - char cipherMode[LUKS_CIPHERMODE_L]; - char hashSpec[LUKS_HASHSPEC_L]; - uint32_t payloadOffset; - uint32_t keyBytes; - char mkDigest[LUKS_DIGESTSIZE]; - char mkDigestSalt[LUKS_SALTSIZE]; - uint32_t mkDigestIterations; - char uuid[UUID_STRING_L]; - struct { - uint32_t active; - - /* parameters used for password processing */ - uint32_t passwordIterations; - char passwordSalt[LUKS_SALTSIZE]; - - /* parameters used for AF store/load */ - uint32_t keyMaterialOffset; - uint32_t stripes; - } keyblock[LUKS_NUMKEYS]; - } *header; + struct luks_phdr *header; header = (struct luks_phdr*) volume_id_get_buffer(id, off, LUKS_PHDR_SIZE); - if (header == NULL) return -1; @@ -99,7 +87,8 @@ int volume_id_probe_luks(struct volume_id *id, __u64 off) return -1; volume_id_set_usage(id, VOLUME_ID_CRYPTO); - volume_id_set_uuid(id, header->uuid, UUID_DCE); + volume_id_set_uuid(id, header->uuid, UUID_DCE_STRING); + id->type = "crypto_LUKS"; return 0; diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index 6159a59928..6ae4d09927 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -138,8 +138,13 @@ void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format break; case UUID_DCE: count = 16; + break; + case UUID_DCE_STRING: + count = 36; + 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++) @@ -172,6 +177,10 @@ set: buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14],buf[15]); break; + case UUID_DCE_STRING: + memcpy(id->uuid, buf, count); + id->uuid[count] = '\0'; + break; } } diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h index 22fd1b94e2..0357b42062 100644 --- a/extras/volume_id/volume_id/util.h +++ b/extras/volume_id/volume_id/util.h @@ -71,6 +71,7 @@ #endif enum uuid_format { + UUID_DCE_STRING, UUID_DCE, UUID_DOS, UUID_NTFS, diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index f93cc91161..7a08be89d9 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -51,8 +51,8 @@ #include "ntfs.h" #include "iso9660.h" #include "udf.h" -#include "luks.h" #include "highpoint.h" +#include "luks.h" #include "linux_swap.h" #include "linux_raid.h" #include "lvm.h" @@ -60,7 +60,6 @@ #include "hpfs.h" #include "romfs.h" #include "sysv.h" -#include "luks.h" #include "mac.h" #include "msdos.h" diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 8fe4c3a5e5..22bb3ea487 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,11 +21,10 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 36 +#define VOLUME_ID_VERSION 38 #define VOLUME_ID_LABEL_SIZE 64 -#define VOLUME_ID_UUID_SIZE 16 -#define VOLUME_ID_UUID_STRING_SIZE 37 +#define VOLUME_ID_UUID_SIZE 36 #define VOLUME_ID_FORMAT_SIZE 32 #define VOLUME_ID_PATH_MAX 256 #define VOLUME_ID_PARTITIONS_MAX 256 @@ -55,7 +54,8 @@ struct volume_id { unsigned int label_raw_len; char label[VOLUME_ID_LABEL_SIZE+1]; unsigned char uuid_raw[VOLUME_ID_UUID_SIZE]; - char uuid[VOLUME_ID_UUID_STRING_SIZE]; + unsigned int uuid_raw_len; + char uuid[VOLUME_ID_UUID_SIZE+1]; enum volume_id_usage usage_id; char *usage; char *type; From 5f335ca4afaa189799225f856f3af8b3d9fd2e1c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 6 Mar 2005 02:09:30 +0100 Subject: [PATCH 1202/4284] [PATCH] klibc_fixups: remove no longer needed stuff --- Makefile | 2 -- klibc_fixups/klibc_fixups.h | 24 ------------------------ libsysfs/sysfs_dir.c | 2 +- 3 files changed, 1 insertion(+), 27 deletions(-) delete mode 100644 klibc_fixups/klibc_fixups.h diff --git a/Makefile b/Makefile index ac60ade52a..8184620a2d 100644 --- a/Makefile +++ b/Makefile @@ -191,7 +191,6 @@ ifeq ($(strip $(USE_KLIBC)),true) $(OPTFLAGS) $(REQFLAGS) \ -D__KLIBC__ -fno-builtin-printf \ -I$(KLIBC_FIXUPS_DIR) \ - -include $(KLIBC_FIXUPS_DIR)/klibc_fixups.h \ -I$(INCLUDE_DIR) \ -I$(INCLUDE_DIR)/arch/$(ARCH) \ -I$(INCLUDE_DIR)/bits$(BITSIZE) \ @@ -201,7 +200,6 @@ ifeq ($(strip $(USE_KLIBC)),true) LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs HEADERS += \ - klibc_fixups/klibc_fixups.h \ klibc_fixups/pwd.h KLIBC_FIXUP_OBJS = \ diff --git a/klibc_fixups/klibc_fixups.h b/klibc_fixups/klibc_fixups.h deleted file mode 100644 index 13011b6888..0000000000 --- a/klibc_fixups/klibc_fixups.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifdef __KLIBC__ - -#ifndef _KLIBC_FIXUPS_H -#define _KLIBC_FIXUPS_H - -#define _KLIBC_HAS_ARCH_SIG_ATOMIC_T -#include - -#define _SC_PAGESIZE 0x66 -static inline long int sysconf(int name) -{ - if (name == _SC_PAGESIZE) - return getpagesize(); - - return -1; -} - -struct exit_status { - short int e_termination; /* process termination status */ - short int e_exit; /* process exit status */ -}; - -#endif /* KLIBC_FIXUPS_H */ -#endif /* __KLIBC__ */ diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index c86617934b..63eec7bb9a 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -150,7 +150,7 @@ int sysfs_read_attribute(struct sysfs_attribute *sysattr) errno = EACCES; return -1; } - pgsize = sysconf(_SC_PAGESIZE); + pgsize = getpagesize(); fbuf = (char *)calloc(1, pgsize+1); if (!fbuf) { dprintf("calloc failed\n"); From 57e1a2770c4d85edd377488906c437f6d1e9b369 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 6 Mar 2005 06:16:52 +0100 Subject: [PATCH 1203/4284] [PATCH] remove Makefile magic for klibc integration The new libsysfs and klibc don't need that anymore. Wrap getpwnam(), so we can use the built-in /etc/passwd parser for statically compiled glibc binaries too. --- Makefile | 38 +++---- klibc_fixups/pwd.h | 27 ----- udev_add.c | 22 +---- .../klibc_fixups.c => udev_libc_wrapper.c | 99 +++++++++++++------ udev_libc_wrapper.h | 28 ++++++ 5 files changed, 112 insertions(+), 102 deletions(-) delete mode 100644 klibc_fixups/pwd.h rename klibc_fixups/klibc_fixups.c => udev_libc_wrapper.c (58%) create mode 100644 udev_libc_wrapper.h diff --git a/Makefile b/Makefile index 8184620a2d..baecda66f3 100644 --- a/Makefile +++ b/Makefile @@ -118,14 +118,15 @@ WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) CFLAGS := -pipe HEADERS = \ - udev.h \ - udev_utils.h \ - namedev.h \ - udev_version.h \ - udev_db.h \ - udev_sysfs.h \ - logging.h \ - udev_selinux.h \ + udev.h \ + udev_utils.h \ + namedev.h \ + udev_version.h \ + udev_db.h \ + udev_sysfs.h \ + logging.h \ + udev_libc_wrapper.h \ + udev_selinux.h \ list.h SYSFS_OBJS = \ @@ -146,7 +147,8 @@ UDEV_OBJS = \ udev_db.o \ udev_multiplex.o \ namedev.o \ - namedev_parse.o + namedev_parse.o \ + udev_libc_wrapper.o OBJS = \ udev.a \ @@ -158,7 +160,7 @@ CFLAGS += -I$(PWD)/libsysfs/sysfs \ -I$(PWD)/libsysfs ifeq ($(strip $(USE_LOG)),true) - CFLAGS += -DLOG + CFLAGS += -DLOG endif # if DEBUG is enabled, then we do not strip or optimize @@ -175,7 +177,6 @@ endif # If we are using our version of klibc, then we need to build, link it, and then # link udev against it statically. Otherwise, use glibc and link dynamically. ifeq ($(strip $(USE_KLIBC)),true) - KLIBC_FIXUPS_DIR= $(PWD)/klibc_fixups KLIBC_BASE = $(PWD)/klibc KLIBC_DIR = $(KLIBC_BASE)/klibc INCLUDE_DIR := $(KLIBC_BASE)/include @@ -190,7 +191,6 @@ ifeq ($(strip $(USE_KLIBC)),true) CFLAGS += $(WARNINGS) -nostdinc \ $(OPTFLAGS) $(REQFLAGS) \ -D__KLIBC__ -fno-builtin-printf \ - -I$(KLIBC_FIXUPS_DIR) \ -I$(INCLUDE_DIR) \ -I$(INCLUDE_DIR)/arch/$(ARCH) \ -I$(INCLUDE_DIR)/bits$(BITSIZE) \ @@ -199,20 +199,12 @@ ifeq ($(strip $(USE_KLIBC)),true) LIB_OBJS = LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs - HEADERS += \ - klibc_fixups/pwd.h - - KLIBC_FIXUP_OBJS = \ - klibc_fixups/klibc_fixups.o - - OBJS += klibc_fixups/klibc_fixups.a else WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations CRT0 = LIBC = CFLAGS += $(WARNINGS) -I$(GCCINCDIR) LIB_OBJS = -lc - LDFLAGS = endif ifeq ($(strip $(USE_SELINUX)),true) @@ -261,11 +253,6 @@ libsysfs/sysfs.a: $(SYSFS_OBJS) $(QUIET) $(AR) cq $@ $(SYSFS_OBJS) $(QUIET) $(RANLIB) $@ -klibc_fixups/klibc_fixups.a: $(KLIBC_FIXUP_OBJS) - rm -f $@ - $(QUIET) $(AR) cq $@ $(KLIBC_FIXUP_OBJS) - $(QUIET) $(RANLIB) $@ - # header files automatically generated GEN_HEADERS = udev_version.h @@ -298,7 +285,6 @@ $(GEN_MANPAGES): $(GEN_MANPAGESIN) $(UDEV_OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(SYSFS_OBJS): $(HOST_PROGS) -$(KLIBC_FIXUP_OBJS): $(HOST_PROGS) $(OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) $(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) diff --git a/klibc_fixups/pwd.h b/klibc_fixups/pwd.h deleted file mode 100644 index f5de6c50b8..0000000000 --- a/klibc_fixups/pwd.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifdef __KLIBC__ - -#ifndef _PWD_H -#define _PWD_H - -struct passwd { - char *pw_name; /* user name */ - char *pw_passwd; /* user password */ - uid_t pw_uid; /* user id */ - gid_t pw_gid; /* group id */ - char *pw_gecos; /* real name */ - char *pw_dir; /* home directory */ - char *pw_shell; /* shell program */ -}; - -struct group { - char *gr_name; /* group name */ - char *gr_passwd; /* group password */ - gid_t gr_gid; /* group id */ - char **gr_mem; /* group members */ -}; - -struct passwd *getpwnam(const char *name); -struct group *getgrnam(const char *name); - -#endif /* _PWD_H */ -#endif /* __KLIBC__ */ diff --git a/udev_add.c b/udev_add.c index aa19d874c3..e05710ce81 100644 --- a/udev_add.c +++ b/udev_add.c @@ -34,9 +34,9 @@ #include #include #include -#include #include "libsysfs/sysfs/libsysfs.h" +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "udev_sysfs.h" @@ -132,15 +132,8 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de if (endptr[0] == '\0') uid = (uid_t) id; - else { - struct passwd *pw; - - pw = getpwnam(udev->owner); - if (pw == NULL) - dbg("specified user unknown '%s'", udev->owner); - else - uid = pw->pw_uid; - } + else + uid = lookup_user(udev->owner); } if (udev->group[0] != '\0') { @@ -149,13 +142,8 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de if (endptr[0] == '\0') gid = (gid_t) id; - else { - struct group *gr = getgrnam(udev->group); - if (gr == NULL) - dbg("specified group unknown '%s'", udev->group); - else - gid = gr->gr_gid; - } + else + gid = lookup_group(udev->group); } if (!udev->test_run) { diff --git a/klibc_fixups/klibc_fixups.c b/udev_libc_wrapper.c similarity index 58% rename from klibc_fixups/klibc_fixups.c rename to udev_libc_wrapper.c index 175cf27fe4..df54515206 100644 --- a/klibc_fixups/klibc_fixups.c +++ b/udev_libc_wrapper.c @@ -1,8 +1,9 @@ /* - * klibc_fixups.c - very simple implementation of stuff missing in klibc + * udev_libc_wrapper - wrapping of functions missing in a specific libc + * or not working in a statically compiled binary * * Copyright (C) 2003 Greg Kroah-Hartman - * Copyright (C) 2004 Kay Sievers + * 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 @@ -19,8 +20,6 @@ * */ -#ifdef __KLIBC__ - #include #include #include @@ -28,18 +27,62 @@ #include #include -#include "pwd.h" +#include "../udev_libc_wrapper.h" #include "../udev.h" #include "../udev_utils.h" #include "../logging.h" -#define PW_FILE "/etc/passwd" -#define GR_FILE "/etc/group" + +#ifdef __KLIBC__ +#define __OWN_USERDB_PARSER__ +#endif +#ifdef USE_STATIC +#define __OWN_USERDB_PARSER__ +#endif + +#ifndef __OWN_USERDB_PARSER__ + +#include +#include +#include + +uid_t lookup_user(const char *user) +{ + struct passwd *pw; + uid_t uid = 0; + + pw = getpwnam(user); + if (pw == NULL) + dbg("specified user unknown '%s'", user); + else + uid = pw->pw_uid; + + return uid; +} + +gid_t lookup_group(const char *group) +{ + struct group *gr; + gid_t gid = 0; + + gr = getgrnam(group); + if (gr == NULL) + dbg("specified group unknown '%s'", group); + else + gid = gr->gr_gid; + + return gid; +} + +#else /* __OWN_USERDB_PARSER__ */ + +#define PASSWD_FILE "/etc/passwd" +#define GROUP_FILE "/etc/group" /* return the id of a passwd style line, selected by the users name */ static unsigned long get_id_by_name(const char *uname, const char *dbfile) { - unsigned long id = -1; + unsigned long id = 0; char line[LINE_SIZE]; char *buf; char *bufline; @@ -51,12 +94,11 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) char *idstr; char *tail; - if (file_map(dbfile, &buf, &bufsize) == 0) { - dbg("reading '%s' as db file", dbfile); - } else { + if (file_map(dbfile, &buf, &bufsize) != 0) { dbg("can't open '%s' as db file", dbfile); - return -1; + return 0; } + dbg("reading '%s' as db file", dbfile); /* loop through the whole file */ cur = 0; @@ -88,9 +130,10 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) if (strcmp(uname, name) == 0) { id = strtoul(idstr, &tail, 10); - if (tail[0] != '\0') - id = -1; - else + if (tail[0] != '\0') { + id = 0; + dbg("no id found for '%s'", name); + } else dbg("id for '%s' is '%li'", name, id); break; } @@ -100,28 +143,20 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) return id; } -struct passwd *getpwnam(const char *name) +uid_t lookup_user(const char *user) { - static struct passwd pw; + unsigned long id; - memset(&pw, 0x00, sizeof(struct passwd)); - pw.pw_uid = (uid_t) get_id_by_name(name, PW_FILE); - if (pw.pw_uid < 0) - return NULL; - else - return &pw; + id = get_id_by_name(user, PASSWD_FILE); + return (uid_t) id; } -struct group *getgrnam(const char *name) +gid_t lookup_group(const char *group) { - static struct group gr; + unsigned long id; - memset(&gr, 0x00, sizeof(struct group)); - gr.gr_gid = (gid_t) get_id_by_name(name, GR_FILE); - if (gr.gr_gid < 0) - return NULL; - else - return &gr; + id = get_id_by_name(group, GROUP_FILE); + return (gid_t) id; } -#endif /* __KLIBC__ */ +#endif /* __OWN_USERDB_PARSER__ */ diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h new file mode 100644 index 0000000000..2df2f4429d --- /dev/null +++ b/udev_libc_wrapper.h @@ -0,0 +1,28 @@ +/* + * udev_libc_wrapper - wrapping of functions missing in a specific libc + * or not working in a statically compiled binary + * + * 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. + * + * 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 _UDEV_LIBC_WRAPPER_H_ +#define _UDEV_LIBC_WRAPPER_H_ + +extern uid_t lookup_user(const char *user); +extern gid_t lookup_group(const char *group); + +#endif /* _UDEV_LIBC_WRAPPER_H_ */ From 6c18b1fb8784606c83adab89e306534d3b943aa3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 6 Mar 2005 10:15:51 +0100 Subject: [PATCH 1204/4284] [PATCH] rename LOG to USE_LOG in all places --- Makefile | 50 +++++++++++++++---------------- extras/volume_id/udev_volume_id.c | 2 +- logging.h | 4 +-- make_gcov.sh | 2 +- udev.c | 2 +- udevd.c | 4 +-- udevinfo.c | 3 +- udevsend.c | 2 +- udevtest.c | 2 +- 9 files changed, 34 insertions(+), 37 deletions(-) diff --git a/Makefile b/Makefile index baecda66f3..f2d445d627 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ # Makefile for udev # # 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 @@ -16,18 +17,28 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# Set the following to control the use of syslog -# Set it to `false' to remove all logging +# Set this to make use of syslog USE_LOG = true -# Set the following to `true' to log the debug -# and make a unstripped, unoptimized binary. -# Leave this set to `false' for production use. +# Set this to ad development debug messages DEBUG = false -# Set this to compile with Security-Enhanced Linux support. +# Set this to include Security-Enhanced Linux support. USE_SELINUX = false +# Set this to comile with the local version of klibc instead of glibc. +USE_KLIBC = false + +# Set this to create statically linked binaries. +USE_STATIC = false + +# To build any of the extras programs, run with: +# make EXTRAS="extras/a extras/b" +EXTRAS= + +# make the build silent. Set this to something else to make it noisy again. +V=false + ROOT = udev DAEMON = udevd SENDER = udevsend @@ -39,9 +50,7 @@ INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev HOTPLUG_EXEC = $(ROOT) - DESTDIR = - KERNEL_DIR = /lib/modules/${shell uname -r}/build # override this to make udev look in a different location for it's config files @@ -62,22 +71,10 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -# To build any of the extras programs, run with: -# make EXTRAS="extras/a extras/b" -EXTRAS= - # place to put our device nodes udevdir = ${prefix}/udev udevdb = ${udevdir}/.udevdb -# Comment out this line to build with something other -# than the local version of klibc -#USE_KLIBC = true - -# make the build silent (well, at least the udev part) Set this -# to something else to make it noisy again. -V=false - # set up PWD so that older versions of make will work with our build. PWD = $(shell pwd) @@ -160,7 +157,7 @@ CFLAGS += -I$(PWD)/libsysfs/sysfs \ -I$(PWD)/libsysfs ifeq ($(strip $(USE_LOG)),true) - CFLAGS += -DLOG + CFLAGS += -DUSE_LOG endif # if DEBUG is enabled, then we do not strip or optimize @@ -182,10 +179,7 @@ ifeq ($(strip $(USE_KLIBC)),true) INCLUDE_DIR := $(KLIBC_BASE)/include LINUX_INCLUDE_DIR := $(KERNEL_DIR)/include include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG - # arch specific objects ARCH_LIB_OBJS = $(KLIBC_DIR)/libc.a - - CRT0 = $(KLIBC_DIR)/crt0.o LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) CFLAGS += $(WARNINGS) -nostdinc \ @@ -197,8 +191,7 @@ ifeq ($(strip $(USE_KLIBC)),true) -I$(GCCINCDIR) \ -I$(LINUX_INCLUDE_DIR) LIB_OBJS = - LDFLAGS = --static --nostdlib -nostartfiles -nodefaultlibs - + LDFLAGS = -static -nostdlib -nostartfiles -nodefaultlibs else WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations CRT0 = @@ -213,6 +206,11 @@ ifeq ($(strip $(USE_SELINUX)),true) CFLAGS += -DUSE_SELINUX endif +ifeq ($(strip $(USE_STATIC)),true) + CFLAGS += -DUSE_STATIC + LDFLAGS += -static +endif + ifeq ($(strip $(V)),false) QUIET=@$(PWD)/ccdv HOST_PROGS=ccdv diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index c36b89f8bd..54d95270d0 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -35,7 +35,7 @@ #define BLKGETSIZE64 _IOR(0x12,114,size_t) -#ifdef LOG +#ifdef USE_LOG void log_message(int level, const char *format, ...) { va_list args; diff --git a/logging.h b/logging.h index 4f51217b9a..3ff54ec974 100644 --- a/logging.h +++ b/logging.h @@ -30,7 +30,7 @@ #define logging_init(foo) do { } while (0) #define logging_close(foo) do { } while (0) -#ifdef LOG +#ifdef USE_LOG #include #include #include @@ -73,6 +73,6 @@ static inline void logging_close(void) closelog(); } -#endif /* LOG */ +#endif /* USE_LOG */ #endif diff --git a/make_gcov.sh b/make_gcov.sh index 4d5f63f1dd..e3ceb96d07 100644 --- a/make_gcov.sh +++ b/make_gcov.sh @@ -28,7 +28,7 @@ GCCINCDIR=`gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"` LIBSYSFS="-I$PWD/libsysfs/sysfs -I$PWD/libsysfs" WARNINGS="-Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations" GCC="-I$GCCINCDIR" -USE_LOG="-DLOG" +USE_LOG="-DUSE_LOG" DEBUG="-D_GNU_SOURCE" GCOV_FLAGS="-pipe -fprofile-arcs -ftest-coverage" diff --git a/udev.c b/udev.c index c26ce46b64..76de8181d1 100644 --- a/udev.c +++ b/udev.c @@ -40,7 +40,7 @@ #include "logging.h" -#ifdef LOG +#ifdef USE_LOG void log_message(int level, const char *format, ...) { va_list args; diff --git a/udevd.c b/udevd.c index bd21f15614..1376cf05c7 100644 --- a/udevd.c +++ b/udevd.c @@ -1,7 +1,7 @@ /* * udevd.c - hotplug event serializer * - * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2004-2005 Kay Sievers * Copyright (C) 2004 Chris Friesen * * @@ -67,7 +67,7 @@ static void user_sighandler(void); static void reap_sigchilds(void); char *udev_bin; -#ifdef LOG +#ifdef USE_LOG void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevinfo.c b/udevinfo.c index b2d22e984e..e30a036ac6 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -3,7 +3,6 @@ * * 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. @@ -38,7 +37,7 @@ #define SYSFS_VALUE_SIZE 256 -#ifdef LOG +#ifdef USE_LOG void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevsend.c b/udevsend.c index 5fe0f456a1..dcd5a2ae93 100644 --- a/udevsend.c +++ b/udevsend.c @@ -43,7 +43,7 @@ /* global variables */ static int sock = -1; -#ifdef LOG +#ifdef USE_LOG void log_message (int level, const char *format, ...) { va_list args; diff --git a/udevtest.c b/udevtest.c index 4e02ac7dbc..084fde0706 100644 --- a/udevtest.c +++ b/udevtest.c @@ -36,7 +36,7 @@ #include "logging.h" -#ifdef LOG +#ifdef USE_LOG void log_message (int level, const char *format, ...) { va_list args; From 845d4751acc26596b827c937b84a9566cd050707 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 6 Mar 2005 12:16:32 +0100 Subject: [PATCH 1205/4284] [PATCH] udev_volume_id: version 39 --- extras/volume_id/volume_id/Makefile.inc | 4 +- extras/volume_id/volume_id/hpfs.c | 2 +- extras/volume_id/volume_id/minix.c | 97 +++++++++++++++++++++++++ extras/volume_id/volume_id/minix.h | 26 +++++++ extras/volume_id/volume_id/volume_id.c | 4 + extras/volume_id/volume_id/volume_id.h | 2 +- udev_db.c | 1 + 7 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 extras/volume_id/volume_id/minix.c create mode 100644 extras/volume_id/volume_id/minix.h diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index 9cadec20cc..68d80d689c 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -19,6 +19,7 @@ VOLUME_ID_OBJS= \ $(VOLUME_ID_BASE)/hpfs.o \ $(VOLUME_ID_BASE)/romfs.o \ $(VOLUME_ID_BASE)/sysv.o \ + $(VOLUME_ID_BASE)/minix.o \ $(VOLUME_ID_BASE)/dasd.o \ $(VOLUME_ID_BASE)/luks.o \ $(VOLUME_ID_BASE)/volume_id.o \ @@ -42,8 +43,9 @@ VOLUME_ID_HEADERS= \ $(VOLUME_ID_BASE)/ufs.h \ $(VOLUME_ID_BASE)/xfs.h \ $(VOLUME_ID_BASE)/cramfs.h \ - $(VOLUME_ID_BASE)/sysv.h \ $(VOLUME_ID_BASE)/romfs.h \ + $(VOLUME_ID_BASE)/sysv.h \ + $(VOLUME_ID_BASE)/minix.h \ $(VOLUME_ID_BASE)/dasd.h \ $(VOLUME_ID_BASE)/luks.h \ $(VOLUME_ID_BASE)/volume_id.h \ diff --git a/extras/volume_id/volume_id/hpfs.c b/extras/volume_id/volume_id/hpfs.c index a8daea7892..3aa95fa839 100644 --- a/extras/volume_id/volume_id/hpfs.c +++ b/extras/volume_id/volume_id/hpfs.c @@ -58,7 +58,7 @@ int volume_id_probe_hpfs(struct volume_id *id, __u64 off) return -1; if (memcmp(hs->magic, "\x49\xe8\x95\xf9", 4) == 0) { - snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u", hs->version); + sprintf(id->type_version, "%u", hs->version); volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); id->type = "hpfs"; diff --git a/extras/volume_id/volume_id/minix.c b/extras/volume_id/volume_id/minix.c new file mode 100644 index 0000000000..d9c9ea8ca9 --- /dev/null +++ b/extras/volume_id/volume_id/minix.c @@ -0,0 +1,97 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "minix.h" + +struct minix_super_block +{ + __u16 s_ninodes; + __u16 s_nzones; + __u16 s_imap_blocks; + __u16 s_zmap_blocks; + __u16 s_firstdatazone; + __u16 s_log_zone_size; + __u32 s_max_size; + __u16 s_magic; + __u16 s_state; + __u32 s_zones; +} __attribute__((__packed__)); + +#define MINIX_SUPERBLOCK_OFFSET 0x400 + +int volume_id_probe_minix(struct volume_id *id, __u64 off) +{ + struct minix_super_block *ms; + + dbg("probing at offset %llu", off); + + ms = (struct minix_super_block *) volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200); + if (ms == NULL) + return -1; + + if (le16_to_cpu(ms->s_magic) == 0x137f) { + strcpy(id->type_version, "1"); + goto found; + } + + if (le16_to_cpu(ms->s_magic) == 0x1387) { + strcpy(id->type_version, "1"); + goto found; + } + + if (le16_to_cpu(ms->s_magic) == 0x2468) { + strcpy(id->type_version, "2"); + goto found; + } + + if (le16_to_cpu(ms->s_magic) == 0x2478) { + strcpy(id->type_version, "2"); + goto found; + } + + goto exit; + +found: + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + id->type = "minix"; + return 0; + +exit: + return -1; +} diff --git a/extras/volume_id/volume_id/minix.h b/extras/volume_id/volume_id/minix.h new file mode 100644 index 0000000000..7a9d97ada2 --- /dev/null +++ b/extras/volume_id/volume_id/minix.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_MINIX_ +#define _VOLUME_ID_MINIX_ + +extern int volume_id_probe_minix(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 7a08be89d9..22d30ee741 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -60,6 +60,7 @@ #include "hpfs.h" #include "romfs.h" #include "sysv.h" +#include "minix.h" #include "mac.h" #include "msdos.h" @@ -136,6 +137,9 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_sysv(id, off) == 0) goto exit; + if (volume_id_probe_minix(id, off) == 0) + goto exit; + return -1; exit: diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 22bb3ea487..6719c1aa31 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 38 +#define VOLUME_ID_VERSION 39 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 diff --git a/udev_db.c b/udev_db.c index c12e88c3c4..653d7d0855 100644 --- a/udev_db.c +++ b/udev_db.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include From 56a8a624eef99f5324b54fad466b144aa4f882c2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 7 Mar 2005 00:01:34 +0100 Subject: [PATCH 1206/4284] [PATCH] split udev and udevstart --- Makefile | 9 ++-- udev.c | 12 ----- udev_start.c => udevstart.c | 100 ++++++++++++++++++++++++------------ 3 files changed, 73 insertions(+), 48 deletions(-) rename udev_start.c => udevstart.c (77%) diff --git a/Makefile b/Makefile index f2d445d627..9b37402fb9 100644 --- a/Makefile +++ b/Makefile @@ -139,7 +139,6 @@ UDEV_OBJS = \ udev_config.o \ udev_add.o \ udev_remove.o \ - udev_start.o \ udev_sysfs.o \ udev_db.o \ udev_multiplex.o \ @@ -222,7 +221,7 @@ endif # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(GEN_CONFIGS) +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -311,6 +310,10 @@ $(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(SENDER).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) $(QUIET) $(STRIPCMD) $@ +$(STARTER): $(LIBC) $(STARTER).o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(STARTER).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + .c.o: $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< @@ -405,7 +408,7 @@ install: install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) - - ln -f -s $(sbindir)/udev $(DESTDIR)$(sbindir)/$(STARTER) + $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug ifndef DESTDIR - killall $(DAEMON) diff --git a/udev.c b/udev.c index 76de8181d1..c9461469e5 100644 --- a/udev.c +++ b/udev.c @@ -130,17 +130,6 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); - if (strstr(argv[0], "udevstart") || (argc == 2 && strstr(argv[1], "udevstart"))) { - dbg("udevstart"); - - /* disable all logging, as it's much too slow on some facilities */ - udev_log = 0; - - namedev_init(); - retval = udev_start(); - goto exit; - } - /* let the executed programs know if we handle the whole hotplug event */ managed_event = manage_hotplug_event(); if (managed_event) @@ -240,7 +229,6 @@ hotplug: if (udev_hotplug_d && managed_event) udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); -exit: logging_close(); return retval; } diff --git a/udev_start.c b/udevstart.c similarity index 77% rename from udev_start.c rename to udevstart.c index dcb4293345..97d38490ae 100644 --- a/udev_start.c +++ b/udevstart.c @@ -26,27 +26,32 @@ #include #include #include +#include #include #include #include +#include #include #include #include -#include #include "libsysfs/sysfs/libsysfs.h" #include "logging.h" +#include "namedev.h" #include "udev_utils.h" #include "list.h" #include "udev.h" - -#define MAX_PATH_SIZE 512 +#ifdef USE_LOG +void log_message(int level, const char *format, ...) +{ +} +#endif struct device { struct list_head list; - char path[MAX_PATH_SIZE]; - char subsys[MAX_PATH_SIZE]; + char path[DEVPATH_SIZE]; + char subsys[SUBSYSTEM_SIZE]; }; /* sort files in lexical order */ @@ -100,7 +105,7 @@ static int add_device(const char *path, const char *subsystem) setenv("DEVPATH", devpath, 1); setenv("SUBSYSTEM", subsystem, 1); - dbg("exec : '%s' (%s)\n", devpath, path); + dbg("exec: '%s' (%s)\n", devpath, path); class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { @@ -118,6 +123,7 @@ static int add_device(const char *path, const char *subsystem) } sysfs_close_class_device(class_dev); + udev_cleanup_device(&udev); return 0; } @@ -167,11 +173,11 @@ static void exec_list(struct list_head *device_list) static int has_devt(const char *directory) { - char filename[MAX_PATH_SIZE]; + char filename[NAME_SIZE]; struct stat statbuf; - snprintf(filename, MAX_PATH_SIZE, "%s/dev", directory); - filename[MAX_PATH_SIZE-1] = '\0'; + snprintf(filename, NAME_SIZE, "%s/dev", directory); + filename[NAME_SIZE-1] = '\0'; if (stat(filename, &statbuf) == 0) return 1; @@ -181,42 +187,42 @@ static int has_devt(const char *directory) static void udev_scan_block(void) { - char base[MAX_PATH_SIZE]; + char base[NAME_SIZE]; DIR *dir; struct dirent *dent; LIST_HEAD(device_list); - snprintf(base, MAX_PATH_SIZE, "%s/block", sysfs_path); - base[MAX_PATH_SIZE-1] = '\0'; + snprintf(base, DEVPATH_SIZE, "%s/block", sysfs_path); + base[DEVPATH_SIZE-1] = '\0'; dir = opendir(base); if (dir != NULL) { for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[MAX_PATH_SIZE]; + char dirname[DEVPATH_SIZE]; DIR *dir2; struct dirent *dent2; if (dent->d_name[0] == '.') continue; - snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name); - dirname[MAX_PATH_SIZE-1] = '\0'; + snprintf(dirname, NAME_SIZE, "%s/%s", base, dent->d_name); + dirname[NAME_SIZE-1] = '\0'; if (has_devt(dirname)) device_list_insert(dirname, "block", &device_list); else continue; - snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name); + /* look for partitions */ dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATH_SIZE]; + char dirname2[DEVPATH_SIZE]; if (dent2->d_name[0] == '.') continue; - snprintf(dirname2, MAX_PATH_SIZE, "%s/%s", dirname, dent2->d_name); - dirname2[MAX_PATH_SIZE-1] = '\0'; + snprintf(dirname2, DEVPATH_SIZE, "%s/%s", dirname, dent2->d_name); + dirname2[DEVPATH_SIZE-1] = '\0'; if (has_devt(dirname2)) device_list_insert(dirname2, "block", &device_list); @@ -226,42 +232,42 @@ static void udev_scan_block(void) } closedir(dir); } - exec_list(&device_list); } static void udev_scan_class(void) { - char base[MAX_PATH_SIZE]; + char base[DEVPATH_SIZE]; DIR *dir; struct dirent *dent; LIST_HEAD(device_list); - snprintf(base, MAX_PATH_SIZE, "%s/class", sysfs_path); - base[MAX_PATH_SIZE-1] = '\0'; + snprintf(base, DEVPATH_SIZE, "%s/class", sysfs_path); + base[DEVPATH_SIZE-1] = '\0'; dir = opendir(base); if (dir != NULL) { for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { - char dirname[MAX_PATH_SIZE]; + char dirname[DEVPATH_SIZE]; DIR *dir2; struct dirent *dent2; if (dent->d_name[0] == '.') continue; - snprintf(dirname, MAX_PATH_SIZE, "%s/%s", base, dent->d_name); - dirname[MAX_PATH_SIZE-1] = '\0'; + snprintf(dirname, DEVPATH_SIZE, "%s/%s", base, dent->d_name); + dirname[DEVPATH_SIZE-1] = '\0'; + dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[MAX_PATH_SIZE]; + char dirname2[DEVPATH_SIZE]; if (dent2->d_name[0] == '.') continue; - snprintf(dirname2, MAX_PATH_SIZE, "%s/%s", dirname, dent2->d_name); - dirname2[MAX_PATH_SIZE-1] = '\0'; + snprintf(dirname2, DEVPATH_SIZE, "%s/%s", dirname, dent2->d_name); + dirname2[DEVPATH_SIZE-1] = '\0'; /* pass the net class as it is */ if (strcmp(dent->d_name, "net") == 0) @@ -274,18 +280,46 @@ static void udev_scan_class(void) } closedir(dir); } - exec_list(&device_list); } -int udev_start(void) +static void asmlinkage sig_handler(int signum) { - /* set environment for callouts and dev.d/ */ + switch (signum) { + case SIGALRM: + exit(1); + case SIGINT: + case SIGTERM: + exit(20 + signum); + } +} + +int main(int argc, char *argv[], char *envp[]) +{ + struct sigaction act; + + udev_init_config(); + + /* 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(ALARM_TIMEOUT); + + /* set environment for executed programs */ setenv("ACTION", "add", 1); setenv("UDEV_START", "1", 1); - udev_scan_class(); + namedev_init(); + udev_scan_block(); + udev_scan_class(); return 0; } From 63f61c5cf639953aa38e025485919b0aa1c49b59 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 7 Mar 2005 04:29:43 +0100 Subject: [PATCH 1207/4284] [PATCH] replace strncpy()/strncat() by strlcpy()/strlcat() --- namedev.c | 92 +++++++++++++++++----------------- namedev.h | 30 +++++------- namedev_parse.c | 33 +++++++------ udev.c | 9 ++-- udev.h | 34 ++++++------- udev_add.c | 34 ++++++------- udev_config.c | 33 ++++++------- udev_db.c | 117 ++++++++++++++++++++------------------------ udev_libc_wrapper.c | 52 +++++++++++++++++--- udev_libc_wrapper.h | 20 ++++++++ udev_multiplex.c | 23 ++++----- udev_remove.c | 22 +++++---- udev_sysfs.c | 10 ++-- udev_utils.c | 27 +++++----- udev_utils.h | 36 +------------- udevd.c | 3 +- udevinfo.c | 29 ++++++----- udevstart.c | 53 ++++++++++---------- udevtest.c | 19 ++++--- 19 files changed, 346 insertions(+), 330 deletions(-) diff --git a/namedev.c b/namedev.c index 49f9e4b1f4..9c73c08149 100644 --- a/namedev.c +++ b/namedev.c @@ -35,6 +35,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "list.h" +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "udev_version.h" @@ -144,14 +145,14 @@ static int get_format_len(char **str) */ static int find_free_number(struct udevice *udev, const char *name) { - char devpath[NAME_SIZE]; - char filename[NAME_SIZE]; + char devpath[PATH_SIZE]; + char filename[PATH_SIZE]; int num = 0; - strfieldcpy(filename, name); + strlcpy(filename, name, sizeof(filename)); while (1) { dbg("look for existing node '%s'", filename); - if (udev_db_search_name(devpath, DEVPATH_SIZE, filename) != 0) { + if (udev_db_search_name(devpath, sizeof(devpath), filename) != 0) { dbg("free num=%d", num); return num; } @@ -161,16 +162,16 @@ static int find_free_number(struct udevice *udev, const char *name) info("find_free_number gone crazy (num=%d), aborted", num); return -1; } - snprintf(filename, NAME_SIZE, "%s%d", name, num); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s%d", name, num); + filename[sizeof(filename)-1] = '\0'; } } static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - char temp[NAME_SIZE]; - char temp2[NAME_SIZE]; + char temp[PATH_SIZE]; + char temp2[PATH_SIZE]; char *tail, *pos, *cpos, *attr, *rest; int len; int i; @@ -189,36 +190,36 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, tail = pos+1; len = get_format_len(&tail); c = tail[0]; - strfieldcpy(temp, tail+1); + strlcpy(temp, tail+1, sizeof(temp)); tail = temp; dbg("format=%c, string='%s', tail='%s'",c , string, tail); attr = get_format_attribute(&tail); switch (c) { case 'p': - strfieldcatmax(string, udev->devpath, maxsize); + strlcat(string, udev->devpath, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'b': - strfieldcatmax(string, udev->bus_id, maxsize); + strlcat(string, udev->bus_id, maxsize); dbg("substitute bus_id '%s'", udev->bus_id); break; case 'k': - strfieldcatmax(string, udev->kernel_name, maxsize); + strlcat(string, udev->kernel_name, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; case 'n': - strfieldcatmax(string, udev->kernel_number, maxsize); + strlcat(string, udev->kernel_number, maxsize); dbg("substitute kernel number '%s'", udev->kernel_number); break; case 'm': sprintf(temp2, "%d", minor(udev->devt)); - strfieldcatmax(string, temp2, maxsize); + strlcat(string, temp2, maxsize); dbg("substitute minor number '%s'", temp2); break; case 'M': sprintf(temp2, "%d", major(udev->devt)); - strfieldcatmax(string, temp2, maxsize); + strlcat(string, temp2, maxsize); dbg("substitute major number '%s'", temp2); break; case 'c': @@ -241,17 +242,17 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("requested part of result string not found"); break; } - strfieldcpy(temp2, cpos); + 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'; } - strfieldcatmax(string, temp2, maxsize); + strlcat(string, temp2, maxsize); dbg("substitute part of result string '%s'", temp2); } else { - strfieldcatmax(string, udev->program_result, maxsize); + strlcat(string, udev->program_result, maxsize); dbg("substitute result string '%s'", udev->program_result); } break; @@ -278,18 +279,18 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, len - i, tmpattr->value); } } - strfieldcatmax(string, tmpattr->value, maxsize); + strlcat(string, tmpattr->value, maxsize); dbg("substitute sysfs value '%s'", tmpattr->value); break; case '%': - strfieldcatmax(string, "%", maxsize); + strlcat(string, "%", maxsize); pos++; break; case 'e': next_free_number = find_free_number(udev, string); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); - strfieldcatmax(string, temp2, maxsize); + strlcat(string, temp2, maxsize); } break; case 'P': @@ -303,7 +304,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, udev_init_device(&udev_parent, NULL, NULL); /* lookup the name in the udev_db with the DEVPATH of the parent */ if (udev_db_get_device(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) { - strfieldcatmax(string, udev_parent.name, maxsize); + strlcat(string, udev_parent.name, maxsize); dbg("substitute parent node name'%s'", udev_parent.name); } else dbg("parent not found in database"); @@ -313,15 +314,16 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, case 'N': if (udev->tmp_node[0] == '\0') { dbg("create temporary device node for callout"); - snprintf(udev->tmp_node, NAME_SIZE, "%s/.tmp-%u-%u", udev_root, major(udev->devt), minor(udev->devt)); - udev->tmp_node[NAME_SIZE] = '\0'; + 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_make_node(udev, udev->tmp_node, udev->devt, 0600, 0, 0); } - strfieldcatmax(string, udev->tmp_node, maxsize); + strlcat(string, udev->tmp_node, maxsize); dbg("substitute temporary device node name '%s'", udev->tmp_node); break; case 'r': - strfieldcatmax(string, udev_root, maxsize); + strlcat(string, udev_root, maxsize); dbg("substitute udev_root '%s'", udev_root); break; default: @@ -332,7 +334,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, if (len > 0) pos[len] = '\0'; - strfieldcatmax(string, tail, maxsize); + strlcat(string, tail, maxsize); } } @@ -344,11 +346,11 @@ static int execute_program(struct udevice *udev, const char *path, char *value, int fds[2]; pid_t pid; char *pos; - char arg[PROGRAM_SIZE]; - char *argv[(PROGRAM_SIZE / 2) + 1]; + char arg[PATH_SIZE]; + char *argv[(sizeof(arg) / 2) + 1]; int i; - strfieldcpy(arg, path); + strlcpy(arg, path, sizeof(arg)); i = 0; if (strchr(path, ' ')) { pos = arg; @@ -516,14 +518,14 @@ static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_devic static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - char path[SYSFS_PATH_MAX]; + char path[PATH_SIZE]; char *temp; /* we have to have a sysfs device for ID to work */ if (!sysfs_device) return -ENODEV; - strfieldcpy(path, sysfs_device->path); + strlcpy(path, sysfs_device->path, sizeof(path)); temp = strrchr(path, '/'); temp++; dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); @@ -535,14 +537,14 @@ static int match_id(struct config_device *dev, struct sysfs_class_device *class_ static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - char path[SYSFS_PATH_MAX]; + char path[PATH_SIZE]; char *temp; /* we have to have a sysfs device for PLACE to work */ if (!sysfs_device) return -ENODEV; - strfieldcpy(path, sysfs_device->path); + strlcpy(path, sysfs_device->path, sizeof(path)); temp = strrchr(path, '/'); dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); if (strstr(temp, dev->place) != NULL) @@ -653,12 +655,12 @@ try_parent: /* execute external program */ if (dev->program[0] != '\0') { - char program[PROGRAM_SIZE]; + char program[PATH_SIZE]; dbg("check " FIELD_PROGRAM); - strfieldcpy(program, dev->program); + strlcpy(program, dev->program, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - if (execute_program(udev, program, udev->program_result, NAME_SIZE) != 0) { + if (execute_program(udev, program, udev->program_result, sizeof(udev->program_result)) != 0) { dbg(FIELD_PROGRAM " returned nonzero"); goto try_parent; } @@ -707,7 +709,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d if (sysfs_device) { dbg("found devices device: path='%s', bus_id='%s', bus='%s'", sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus); - strfieldcpy(udev->bus_id, sysfs_device->bus_id); + strlcpy(udev->bus_id, sysfs_device->bus_id, sizeof(udev->bus_id)); } dbg("udev->kernel_name='%s'", udev->kernel_name); @@ -739,24 +741,24 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name); } if (dev->owner[0] != '\0') { - strfieldcpy(udev->owner, dev->owner); + strlcpy(udev->owner, dev->owner, sizeof(udev->owner)); apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); } if (dev->group[0] != '\0') { - strfieldcpy(udev->group, dev->group); + strlcpy(udev->group, dev->group, sizeof(udev->group)); apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); } /* collect symlinks */ if (dev->symlink[0] != '\0') { - char temp[NAME_SIZE]; + char temp[PATH_SIZE]; char *pos, *next; info("configured rule in '%s[%i]' applied, added symlink '%s'", dev->config_file, dev->config_line, dev->symlink); - strfieldcpy(temp, dev->symlink); + strlcpy(temp, dev->symlink, sizeof(temp)); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); /* add multiple symlinks separated by spaces */ @@ -778,9 +780,9 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", dev->config_file, dev->config_line, udev->kernel_name, dev->name); - strfieldcpy(udev->name, dev->name); + strlcpy(udev->name, dev->name, sizeof(udev->name)); apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - strfieldcpy(udev->config_file, dev->config_file); + strlcpy(udev->config_file, dev->config_file, sizeof(udev->config_file)); udev->config_line = dev->config_line; if (udev->type != NET) @@ -794,7 +796,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d if (udev->name[0] == '\0') { /* no rule matched, so we use the kernel name */ - strfieldcpy(udev->name, udev->kernel_name); + strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); dbg("no rule found, use kernel name '%s'", udev->name); } diff --git a/namedev.h b/namedev.h index 1d6920cc7c..76caaaa9f7 100644 --- a/namedev.h +++ b/namedev.h @@ -28,14 +28,6 @@ struct sysfs_class_device; -#define BUS_SIZE 32 -#define FILE_SIZE 64 -#define VALUE_SIZE 128 -#define ID_SIZE 64 -#define PLACE_SIZE 64 -#define DRIVER_SIZE 64 -#define PROGRAM_SIZE 128 - #define FIELD_KERNEL "KERNEL" #define FIELD_SUBSYSTEM "SUBSYSTEM" #define FIELD_BUS "BUS" @@ -61,7 +53,7 @@ struct sysfs_class_device; #define RULEFILE_SUFFIX ".rules" struct sysfs_pair { - char file[FILE_SIZE]; + char file[PATH_SIZE]; char value[VALUE_SIZE]; }; @@ -69,16 +61,16 @@ struct config_device { struct list_head node; char kernel[NAME_SIZE]; - char subsystem[SUBSYSTEM_SIZE]; - char bus[BUS_SIZE]; - char id[ID_SIZE]; - char place[PLACE_SIZE]; + char subsystem[NAME_SIZE]; + char bus[NAME_SIZE]; + char id[NAME_SIZE]; + char place[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; - char program[PROGRAM_SIZE]; - char result[PROGRAM_SIZE]; - char driver[DRIVER_SIZE]; - char name[NAME_SIZE]; - char symlink[NAME_SIZE]; + char program[PATH_SIZE]; + char result[PATH_SIZE]; + char driver[NAME_SIZE]; + char name[PATH_SIZE]; + char symlink[PATH_SIZE]; char owner[USER_SIZE]; char group[USER_SIZE]; @@ -88,7 +80,7 @@ struct config_device { int ignore_device; int ignore_remove; - char config_file[NAME_SIZE]; + char config_file[PATH_SIZE]; int config_line; }; diff --git a/namedev_parse.c b/namedev_parse.c index e360565950..942596121e 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -36,6 +36,7 @@ #include #include +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "logging.h" @@ -134,7 +135,7 @@ static int namedev_parse(struct udevice *udev, const char *filename) cur += count+1; lineno++; - if (count >= LINE_SIZE) { + if (count >= sizeof(line)) { info("line too long, rule skipped %s, line %d", filename, lineno); continue; } @@ -172,31 +173,31 @@ static int namedev_parse(struct udevice *udev, const char *filename) break; if (strcasecmp(temp2, FIELD_KERNEL) == 0) { - strfieldcpy(dev.kernel, temp3); + strlcpy(dev.kernel, temp3, sizeof(dev.kernel)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_SUBSYSTEM) == 0) { - strfieldcpy(dev.subsystem, temp3); + strlcpy(dev.subsystem, temp3, sizeof(dev.subsystem)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_BUS) == 0) { - strfieldcpy(dev.bus, temp3); + strlcpy(dev.bus, temp3, sizeof(dev.bus)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_ID) == 0) { - strfieldcpy(dev.id, temp3); + strlcpy(dev.id, temp3, sizeof(dev.id)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_PLACE) == 0) { - strfieldcpy(dev.place, temp3); + strlcpy(dev.place, temp3, sizeof(dev.place)); valid = 1; continue; } @@ -220,28 +221,28 @@ static int namedev_parse(struct udevice *udev, const char *filename) dbg("error parsing " FIELD_SYSFS " attribute"); continue; } - strfieldcpy(pair->file, attr); - strfieldcpy(pair->value, temp3); + strlcpy(pair->file, attr, sizeof(pair->file)); + strlcpy(pair->value, temp3, sizeof(pair->value)); valid = 1; } continue; } if (strcasecmp(temp2, FIELD_DRIVER) == 0) { - strfieldcpy(dev.driver, temp3); + strlcpy(dev.driver, temp3, sizeof(dev.driver)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { program_given = 1; - strfieldcpy(dev.program, temp3); + strlcpy(dev.program, temp3, sizeof(dev.program)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_RESULT) == 0) { - strfieldcpy(dev.result, temp3); + strlcpy(dev.result, temp3, sizeof(dev.result)); valid = 1; continue; } @@ -260,7 +261,7 @@ static int namedev_parse(struct udevice *udev, const char *filename) } } if (temp3[0] != '\0') - strfieldcpy(dev.name, temp3); + strlcpy(dev.name, temp3, sizeof(dev.name)); else dev.ignore_device = 1; valid = 1; @@ -268,19 +269,19 @@ static int namedev_parse(struct udevice *udev, const char *filename) } if (strcasecmp(temp2, FIELD_SYMLINK) == 0) { - strfieldcpy(dev.symlink, temp3); + strlcpy(dev.symlink, temp3, sizeof(dev.symlink)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_OWNER) == 0) { - strfieldcpy(dev.owner, temp3); + strlcpy(dev.owner, temp3, sizeof(dev.owner)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_GROUP) == 0) { - strfieldcpy(dev.group, temp3); + strlcpy(dev.group, temp3, sizeof(dev.group)); valid = 1; continue; } @@ -330,7 +331,7 @@ static int namedev_parse(struct udevice *udev, const char *filename) } dev.config_line = lineno; - strfieldcpy(dev.config_file, filename); + strlcpy(dev.config_file, filename, sizeof(dev.config_file)); retval = add_config_dev(&dev); if (retval) { dbg("add_config_dev returned with error %d", retval); diff --git a/udev.c b/udev.c index c9461469e5..bf2eb373f8 100644 --- a/udev.c +++ b/udev.c @@ -32,6 +32,7 @@ #include #include "libsysfs/sysfs/libsysfs.h" +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "udev_sysfs.h" @@ -99,7 +100,7 @@ int main(int argc, char *argv[], char *envp[]) struct sysfs_class_device *class_dev; struct sysfs_device *devices_dev; struct udevice udev; - char path[SYSFS_PATH_MAX]; + char path[PATH_SIZE]; const char *error; const char *action; const char *devpath; @@ -164,7 +165,8 @@ int main(int argc, char *argv[], char *envp[]) goto hotplug; } - snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); + snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath); + path[sizeof(path)-1] = '\0'; class_dev = wait_class_device_open(path); if (class_dev == NULL) { dbg ("open class device failed"); @@ -206,7 +208,8 @@ int main(int argc, char *argv[], char *envp[]) /* wait for sysfs */ dbg("devices add"); - snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, devpath); + snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); + path[sizeof(path)-1] = '\0'; devices_dev = wait_devices_device_open(path); if (!devices_dev) { dbg("devices device unavailable (probably remove has beaten us)"); diff --git a/udev.h b/udev.h index 811439faf2..7eb07bf125 100644 --- a/udev.h +++ b/udev.h @@ -33,13 +33,11 @@ #define COMMENT_CHARACTER '#' #define LINE_SIZE 512 -#define NAME_SIZE 256 +#define NAME_SIZE 128 +#define PATH_SIZE 256 #define USER_SIZE 32 - -#define ACTION_SIZE 32 -#define DEVPATH_SIZE 256 -#define SUBSYSTEM_SIZE 32 #define SEQNUM_SIZE 32 +#define VALUE_SIZE 128 #define DEVD_DIR "/etc/dev.d" #define DEVD_SUFFIX ".dev" @@ -58,11 +56,11 @@ enum device_type { }; struct udevice { - char devpath[DEVPATH_SIZE]; - char subsystem[SUBSYSTEM_SIZE]; + char devpath[PATH_SIZE]; + char subsystem[NAME_SIZE]; - char name[NAME_SIZE]; - char devname[NAME_SIZE]; + char name[PATH_SIZE]; + char devname[PATH_SIZE]; struct list_head symlink_list; char owner[USER_SIZE]; char group[USER_SIZE]; @@ -70,13 +68,13 @@ struct udevice { char type; dev_t devt; - char tmp_node[NAME_SIZE]; + char tmp_node[PATH_SIZE]; int partitions; int ignore_remove; int config_line; - char config_file[NAME_SIZE]; - char bus_id[SYSFS_NAME_LEN]; - char program_result[NAME_SIZE]; + char config_file[PATH_SIZE]; + char bus_id[NAME_SIZE]; + char program_result[PATH_SIZE]; char kernel_number[NAME_SIZE]; char kernel_name[NAME_SIZE]; int test_run; @@ -89,11 +87,11 @@ extern int udev_start(void); extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix); extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); -extern char sysfs_path[SYSFS_PATH_MAX]; -extern char udev_root[PATH_MAX]; -extern char udev_db_path[PATH_MAX+NAME_MAX]; -extern char udev_config_filename[PATH_MAX+NAME_MAX]; -extern char udev_rules_filename[PATH_MAX+NAME_MAX]; +extern char sysfs_path[PATH_SIZE]; +extern char udev_root[PATH_SIZE]; +extern char udev_db_path[PATH_SIZE]; +extern char udev_config_filename[PATH_SIZE]; +extern char udev_rules_filename[PATH_SIZE]; extern int udev_log; extern int udev_dev_d; extern int udev_hotplug_d; diff --git a/udev_add.c b/udev_add.c index e05710ce81..f47ca25f74 100644 --- a/udev_add.c +++ b/udev_add.c @@ -111,16 +111,16 @@ exit: static int create_node(struct udevice *udev, struct sysfs_class_device *class_dev) { - char filename[NAME_SIZE]; - char partitionname[NAME_SIZE]; + char filename[PATH_SIZE]; + char partitionname[PATH_SIZE]; struct name_entry *name_loop; uid_t uid = 0; gid_t gid = 0; int tail; int i; - snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s", udev_root, udev->name); + filename[sizeof(filename)-1] = '\0'; /* create parent directories if needed */ if (strchr(udev->name, '/')) @@ -173,8 +173,8 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de for (i = 1; i <= udev->partitions; i++) { dev_t part_devt; - snprintf(partitionname, NAME_SIZE, "%s%d", filename, i); - partitionname[NAME_SIZE-1] = '\0'; + snprintf(partitionname, sizeof(partitionname), "%s%d", filename, i); + partitionname[sizeof(partitionname)-1] = '\0'; part_devt = makedev(major(udev->devt), minor(udev->devt)+1); udev_make_node(udev, partitionname, part_devt, udev->mode, uid, gid); } @@ -183,10 +183,10 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de /* create symlink(s) if requested */ list_for_each_entry(name_loop, &udev->symlink_list, node) { - char linktarget[NAME_SIZE]; + char linktarget[PATH_SIZE]; - snprintf(filename, NAME_SIZE, "%s/%s", udev_root, name_loop->name); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); + filename[sizeof(filename)-1] = '\0'; dbg("symlink '%s' to node '%s' requested", filename, udev->name); if (!udev->test_run) @@ -204,11 +204,11 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de } while (name_loop->name[i] != '\0') { if (name_loop->name[i] == '/') - strfieldcat(linktarget, "../"); + strlcat(linktarget, "../", sizeof(linktarget)); i++; } - strfieldcat(linktarget, &udev->name[tail]); + strlcat(linktarget, &udev->name[tail], sizeof(linktarget)); dbg("symlink(%s, %s)", linktarget, filename); if (!udev->test_run) { @@ -242,8 +242,8 @@ static int rename_net_if(struct udevice *udev) } memset(&ifr, 0x00, sizeof(struct ifreq)); - strfieldcpy(ifr.ifr_name, udev->kernel_name); - strfieldcpy(ifr.ifr_newname, udev->name); + strlcpy(ifr.ifr_name, udev->kernel_name, IFNAMSIZ); + strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ); retval = ioctl(sk, SIOCSIFNAME, &ifr); if (retval != 0) @@ -283,8 +283,8 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) "remove might not work for custom names"); /* use full path to the environment */ - snprintf(udev->devname, NAME_SIZE, "%s/%s", udev_root, udev->name); - udev->devname[NAME_SIZE-1] = '\0'; + snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); + udev->devname[sizeof(udev->devname)-1] = '\0'; } else if (udev->type == NET) { /* look if we want to change the name of the netif */ @@ -300,13 +300,13 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) pos = strrchr(udev->devpath, '/'); if (pos != NULL) { pos[1] = '\0'; - strfieldcat(udev->devpath, udev->name); + strlcat(udev->devpath, udev->name, sizeof(udev->devpath)); setenv("DEVPATH", udev->devpath, 1); setenv("INTERFACE", udev->name, 1); } /* use netif name for the environment */ - strfieldcpy(udev->devname, udev->name); + strlcpy(udev->devname, udev->name, sizeof(udev->devname)); } } diff --git a/udev_config.c b/udev_config.c index 5e204488d2..26ecf6291c 100644 --- a/udev_config.c +++ b/udev_config.c @@ -33,6 +33,7 @@ #include #include "libsysfs/sysfs/libsysfs.h" +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "udev_version.h" @@ -40,11 +41,11 @@ #include "namedev.h" /* global variables */ -char sysfs_path[SYSFS_PATH_MAX]; -char udev_root[PATH_MAX]; -char udev_db_path[PATH_MAX+NAME_MAX]; -char udev_rules_filename[PATH_MAX+NAME_MAX]; -char udev_config_filename[PATH_MAX+NAME_MAX]; +char sysfs_path[PATH_SIZE]; +char udev_root[PATH_SIZE]; +char udev_db_path[PATH_SIZE]; +char udev_rules_filename[PATH_SIZE]; +char udev_config_filename[PATH_SIZE]; int udev_log; int udev_dev_d; int udev_hotplug_d; @@ -98,12 +99,11 @@ static int parse_config_file(void) int lineno; int retval = 0; - if (file_map(udev_config_filename, &buf, &bufsize) == 0) { - dbg("reading '%s' as config file", udev_config_filename); - } else { + if (file_map(udev_config_filename, &buf, &bufsize) != 0) { dbg("can't open '%s' as config file", udev_config_filename); return -ENODEV; } + dbg("reading '%s' as config file", udev_config_filename); /* loop through the whole file */ lineno = 0; @@ -114,7 +114,7 @@ static int parse_config_file(void) cur += count+1; lineno++; - if (count >= LINE_SIZE) { + if (count >= sizeof(line)) { info("line too long, conf line skipped %s, line %d", udev_config_filename, lineno); continue; @@ -132,8 +132,7 @@ static int parse_config_file(void) if (bufline[0] == COMMENT_CHARACTER) continue; - strncpy(line, bufline, count); - line[count] = '\0'; + strlcpy(line, bufline, count); temp = line; dbg_parse("read '%s'", temp); @@ -145,19 +144,19 @@ static int parse_config_file(void) dbg_parse("variable='%s', value='%s'", variable, value); if (strcasecmp(variable, "udev_root") == 0) { - strfieldcpy(udev_root, value); + strlcpy(udev_root, value, sizeof(udev_root)); no_trailing_slash(udev_root); continue; } if (strcasecmp(variable, "udev_db") == 0) { - strfieldcpy(udev_db_path, value); + strlcpy(udev_db_path, value, sizeof(udev_db_path)); no_trailing_slash(udev_db_path); continue; } if (strcasecmp(variable, "udev_rules") == 0) { - strfieldcpy(udev_rules_filename, value); + strlcpy(udev_rules_filename, value, sizeof(udev_rules_filename)); no_trailing_slash(udev_rules_filename); continue; } @@ -177,7 +176,7 @@ static void get_dirs(void) char *temp; int retval; - retval = sysfs_get_mnt_path(sysfs_path, SYSFS_PATH_MAX); + retval = sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); if (retval) dbg("sysfs_get_mnt_path failed"); @@ -185,13 +184,13 @@ static void get_dirs(void) if (getenv("UDEV_TEST") != NULL) { temp = getenv("SYSFS_PATH"); if (temp != NULL) { - strfieldcpy(sysfs_path, temp); + strlcpy(sysfs_path, temp, sizeof(sysfs_path)); no_trailing_slash(sysfs_path); } temp = getenv("UDEV_CONFIG_FILE"); if (temp != NULL) - strfieldcpy(udev_config_filename, temp); + strlcpy(udev_config_filename, temp, sizeof(udev_config_filename)); } parse_config_file(); diff --git a/udev_db.c b/udev_db.c index 653d7d0855..806fc71bce 100644 --- a/udev_db.c +++ b/udev_db.c @@ -33,6 +33,7 @@ #include #include "libsysfs/sysfs/libsysfs.h" +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "logging.h" @@ -42,11 +43,11 @@ static int get_db_filename(const char *devpath, char *filename, int len) { - char temp[SYSFS_PATH_MAX]; + char temp[PATH_SIZE]; char *pos; /* replace '/' to transform path into a filename */ - strfieldcpy(temp, devpath); + strlcpy(temp, devpath, sizeof(temp)); pos = strchr(&temp[1], '/'); while (pos) { pos[0] = PATH_TO_NAME_CHAR; @@ -60,14 +61,14 @@ static int get_db_filename(const char *devpath, char *filename, int len) int udev_db_add_device(struct udevice *udev) { - char filename[SYSFS_PATH_MAX]; + char filename[PATH_SIZE]; struct name_entry *name_loop; FILE *f; if (udev->test_run) return 0; - get_db_filename(udev->devpath, filename, SYSFS_PATH_MAX); + get_db_filename(udev->devpath, filename, sizeof(filename)); create_path(filename); @@ -93,8 +94,7 @@ int udev_db_add_device(struct udevice *udev) static int parse_db_file(struct udevice *udev, const char *filename) { - char line[NAME_SIZE]; - char temp[NAME_SIZE]; + char line[PATH_SIZE]; unsigned int major, minor; char *bufline; char *buf; @@ -115,44 +115,38 @@ static int parse_db_file(struct udevice *udev, const char *filename) switch(bufline[0]) { case 'P': - if (count > DEVPATH_SIZE) - count = DEVPATH_SIZE-1; - strncpy(udev->devpath, &bufline[2], count-2); - udev->devpath[count-2] = '\0'; + if (count > sizeof(udev->devpath)) + count = sizeof(udev->devpath)-1; + strlcpy(udev->devpath, &bufline[2], count-2); break; case 'N': - if (count > NAME_SIZE) - count = NAME_SIZE-1; - strncpy(udev->name, &bufline[2], count-2); - udev->name[count-2] = '\0'; + if (count > sizeof(udev->name)) + count = sizeof(udev->name)-1; + strlcpy(udev->name, &bufline[2], count-2); break; case 'M': - if (count > NAME_SIZE) - count = NAME_SIZE-1; - strncpy(temp, &bufline[2], count-2); - temp[count-2] = '\0'; - sscanf(temp, "%u:%u", &major, &minor); + if (count > sizeof(line)) + count = sizeof(line)-1; + strlcpy(line, &bufline[2], count-2); + sscanf(line, "%u:%u", &major, &minor); udev->devt = makedev(major, minor); break; case 'S': - if (count > NAME_SIZE) - count = NAME_SIZE-1; - strncpy(temp, &bufline[2], count-2); - temp[count-2] = '\0'; - name_list_add(&udev->symlink_list, temp, 0); + if (count > sizeof(line)) + count = sizeof(line)-1; + strlcpy(line, &bufline[2], count-2); + name_list_add(&udev->symlink_list, line, 0); break; case 'A': - if (count > NAME_SIZE) - count = NAME_SIZE-1; - strncpy(line, &bufline[2], count-2); - line[count-2] = '\0'; + if (count > sizeof(line)) + count = sizeof(line)-1; + strlcpy(line, &bufline[2], count-2); udev->partitions = atoi(line); break; case 'R': - if (count > NAME_SIZE) - count = NAME_SIZE-1; - strncpy(line, &bufline[2], count-2); - line[count-2] = '\0'; + if (count > sizeof(line)) + count = sizeof(line)-1; + strlcpy(line, &bufline[2], count-2); udev->ignore_remove = atoi(line); break; } @@ -167,9 +161,9 @@ static int parse_db_file(struct udevice *udev, const char *filename) int udev_db_delete_device(struct udevice *udev) { - char filename[SYSFS_PATH_MAX]; + char filename[PATH_SIZE]; - get_db_filename(udev->devpath, filename, SYSFS_PATH_MAX); + get_db_filename(udev->devpath, filename, sizeof(filename)); unlink(filename); return 0; @@ -177,9 +171,9 @@ int udev_db_delete_device(struct udevice *udev) int udev_db_get_device(struct udevice *udev, const char *devpath) { - char filename[SYSFS_PATH_MAX]; + char filename[PATH_SIZE]; - get_db_filename(devpath, filename, SYSFS_PATH_MAX); + get_db_filename(devpath, filename, sizeof(filename)); if (parse_db_file(udev, filename) != 0) return -1; @@ -199,9 +193,9 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) while (1) { struct dirent *ent; - char filename[NAME_SIZE]; - char path[DEVPATH_SIZE]; - char nodename[NAME_SIZE]; + char filename[PATH_SIZE]; + char path[PATH_SIZE]; + char nodename[PATH_SIZE]; char *bufline; char *buf; size_t bufsize; @@ -215,8 +209,8 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) if (ent->d_name[0] == '.') continue; - snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s", udev_db_path, ent->d_name); + filename[sizeof(filename)-1] = '\0'; dbg("looking at '%s'", filename); if (file_map(filename, &buf, &bufsize) != 0) { @@ -232,21 +226,18 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) switch(bufline[0]) { case 'P': - if (count > DEVPATH_SIZE) - count = DEVPATH_SIZE-1; - strncpy(path, &bufline[2], count-2); - path[count-2] = '\0'; + if (count > sizeof(path)) + count = sizeof(path)-1; + strlcpy(path, &bufline[2], count-2); break; case 'N': case 'S': - if (count > NAME_SIZE) - count = NAME_SIZE-1; - strncpy(nodename, &bufline[2], count-2); - nodename[count-2] = '\0'; + if (count > sizeof(nodename)) + count = sizeof(nodename)-1; + strlcpy(nodename, &bufline[2], count-2); dbg("compare '%s' '%s'", nodename, name); if (strcmp(nodename, name) == 0) { - strncpy(devpath, path, len); - devpath[len] = '\0'; + strlcpy(devpath, path, len); file_unmap(buf, bufsize); closedir(dir); return 0; @@ -275,9 +266,9 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam while (1) { struct dirent *ent; - char filename[NAME_SIZE]; - char path[DEVPATH_SIZE]; - char nodename[NAME_SIZE]; + char filename[PATH_SIZE]; + char path[PATH_SIZE]; + char nodename[PATH_SIZE]; char *bufline; char *buf; size_t bufsize; @@ -291,8 +282,8 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam if (ent->d_name[0] == '.') continue; - snprintf(filename, NAME_SIZE, "%s/%s", udev_db_path, ent->d_name); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s", udev_db_path, ent->d_name); + filename[sizeof(filename)-1] = '\0'; dbg("looking at '%s'", filename); if (file_map(filename, &buf, &bufsize) != 0) { @@ -310,16 +301,14 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam switch(bufline[0]) { case 'P': - if (count > DEVPATH_SIZE) - count = DEVPATH_SIZE-1; - strncpy(path, &bufline[2], count-2); - path[count-2] = '\0'; + if (count > sizeof(path)) + count = sizeof(path)-1; + strlcpy(path, &bufline[2], count-2); break; case 'N': - if (count > NAME_SIZE) - count = NAME_SIZE-1; - strncpy(nodename, &bufline[2], count-2); - nodename[count-2] = '\0'; + if (count > sizeof(nodename)) + count = sizeof(nodename)-1; + strlcpy(nodename, &bufline[2], count-2); break; default: continue; diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index df54515206..0dafe4d077 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -32,16 +32,58 @@ #include "../udev_utils.h" #include "../logging.h" - #ifdef __KLIBC__ #define __OWN_USERDB_PARSER__ #endif + #ifdef USE_STATIC #define __OWN_USERDB_PARSER__ #endif -#ifndef __OWN_USERDB_PARSER__ +#ifndef strlcpy +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 < size) + *q++ = ch; + bytes++; + } + + *q = '\0'; + return bytes; +} +#endif + +#ifndef strlcat +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++; + } + + while ((ch = *p++)) { + if (bytes < size) + *q++ = ch; + bytes++; + } + + *q = '\0'; + return bytes; +} +#endif + +#ifndef __OWN_USERDB_PARSER__ #include #include #include @@ -107,11 +149,10 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) bufline = &buf[cur]; cur += count+1; - if (count >= LINE_SIZE) + if (count >= sizeof(line)) continue; - strncpy(line, bufline, count); - line[count] = '\0'; + strlcpy(line, bufline, count); pos = line; /* get name */ @@ -158,5 +199,4 @@ gid_t lookup_group(const char *group) id = get_id_by_name(group, GROUP_FILE); return (gid_t) id; } - #endif /* __OWN_USERDB_PARSER__ */ diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 2df2f4429d..65f4e01c23 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -22,7 +22,27 @@ #ifndef _UDEV_LIBC_WRAPPER_H_ #define _UDEV_LIBC_WRAPPER_H_ +#ifdef asmlinkage +# undef asmlinkage +#endif +#ifdef __i386__ +# define asmlinkage __attribute__((regparm(0))) +#endif +#ifndef asmlinkage +# define asmlinkage +#endif + +#include + extern uid_t lookup_user(const char *user); extern gid_t lookup_group(const char *group); +#ifndef strlcat +extern size_t strlcpy(char *dst, const char *src, size_t size); +#endif + +#ifndef strlcat +extern size_t strlcat(char *dst, const char *src, size_t size); +#endif + #endif /* _UDEV_LIBC_WRAPPER_H_ */ diff --git a/udev_multiplex.c b/udev_multiplex.c index 6d7852dbc0..3ef6e1707a 100644 --- a/udev_multiplex.c +++ b/udev_multiplex.c @@ -28,6 +28,7 @@ #include #include "udev.h" +#include "udev_libc_wrapper.h" #include "udev_utils.h" #include "logging.h" @@ -72,22 +73,22 @@ static int run_program(struct udevice *udev, const char *filename) */ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix) { - char dirname[PATH_MAX]; + char dirname[PATH_SIZE]; /* chop the device name up into pieces based on '/' */ if (udev->name[0] != '\0') { - char devname[NAME_SIZE]; + char devname[PATH_SIZE]; char *temp; - strfieldcpy(devname, udev->name); + strlcpy(devname, udev->name, sizeof(devname)); temp = strchr(devname, '/'); while (temp != NULL) { temp[0] = '\0'; /* don't call the subsystem directory here */ if (strcmp(devname, udev->subsystem) != 0) { - snprintf(dirname, PATH_MAX, "%s/%s", basedir, devname); - dirname[PATH_MAX-1] = '\0'; + snprintf(dirname, sizeof(dirname), "%s/%s", basedir, devname); + dirname[sizeof(dirname)-1] = '\0'; call_foreach_file(run_program, udev, dirname, suffix); } @@ -98,18 +99,18 @@ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const c } if (udev->name[0] != '\0') { - snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->name); - dirname[PATH_MAX-1] = '\0'; + snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->name); + dirname[sizeof(dirname)-1] = '\0'; call_foreach_file(run_program, udev, dirname, suffix); } if (udev->subsystem[0] != '\0') { - snprintf(dirname, PATH_MAX, "%s/%s", basedir, udev->subsystem); - dirname[PATH_MAX-1] = '\0'; + snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->subsystem); + dirname[sizeof(dirname)-1] = '\0'; call_foreach_file(run_program, udev, dirname, suffix); } - snprintf(dirname, PATH_MAX, "%s/default", basedir); - dirname[PATH_MAX-1] = '\0'; + snprintf(dirname, sizeof(dirname), "%s/default", basedir); + dirname[sizeof(dirname)-1] = '\0'; call_foreach_file(run_program, udev, dirname, suffix); } diff --git a/udev_remove.c b/udev_remove.c index 7a6c032d01..1fd36d24c5 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -30,6 +30,7 @@ #include #include +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "udev_version.h" @@ -69,16 +70,16 @@ static int delete_path(const char *path) static int delete_node(struct udevice *udev) { - char filename[NAME_SIZE]; - char partitionname[NAME_SIZE]; + char filename[PATH_SIZE]; + char partitionname[PATH_SIZE]; struct name_entry *name_loop; struct stat stats; int retval; int i; int num; - snprintf(filename, NAME_SIZE, "%s/%s", udev_root, udev->name); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s", udev_root, udev->name); + filename[sizeof(filename)-1] = '\0'; dbg("checking major/minor of device node '%s'", filename); if (stat(filename, &stats) != 0) @@ -103,8 +104,8 @@ static int delete_node(struct udevice *udev) return -1; } for (i = 1; i <= num; i++) { - snprintf(partitionname, NAME_SIZE, "%s%d", filename, i); - partitionname[NAME_SIZE-1] = '\0'; + snprintf(partitionname, sizeof(partitionname), "%s%d", filename, i); + partitionname[sizeof(partitionname)-1] = '\0'; unlink_secure(partitionname); } } @@ -114,8 +115,8 @@ static int delete_node(struct udevice *udev) delete_path(filename); list_for_each_entry(name_loop, &udev->symlink_list, node) { - snprintf(filename, NAME_SIZE, "%s/%s", udev_root, name_loop->name); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); + filename[sizeof(filename)-1] = '\0'; dbg("unlinking symlink '%s'", filename); retval = unlink(filename); @@ -157,12 +158,13 @@ int udev_remove_device(struct udevice *udev) temp = strrchr(udev->devpath, '/'); if (temp == NULL) return -ENODEV; - strfieldcpy(udev->name, &temp[1]); + strlcpy(udev->name, &temp[1], sizeof(udev->name)); dbg("'%s' not found in database, falling back on default name", udev->name); } /* use full path to the environment */ - snprintf(udev->devname, NAME_SIZE, "%s/%s", udev_root, udev->name); + snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); + udev->devname[sizeof(udev->devname)-1] = '\0'; return delete_node(udev); } diff --git a/udev_sysfs.c b/udev_sysfs.c index fc7ee885b0..f9ff1ed2f9 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -105,7 +105,7 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev const char **error) { const char *file; - char filename[SYSFS_PATH_MAX]; + char filename[PATH_SIZE]; int loop; file = get_subsystem_specific_file(class_dev->classname); @@ -114,7 +114,8 @@ static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev return 0; } - snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", class_dev->path, file); + snprintf(filename, sizeof(filename), "%s/%s", class_dev->path, file); + filename[sizeof(filename)-1] = '\0'; dbg("looking at class '%s' for specific file '%s'", class_dev->classname, filename); loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; @@ -363,7 +364,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, for (devicefile = device_files; devicefile->bus != NULL; devicefile++) { if (strcmp(devices_dev->bus, devicefile->bus) == 0) { - char filename[SYSFS_PATH_MAX]; + char filename[PATH_SIZE]; struct stat stats; if (devicefile->file == NULL) { @@ -372,7 +373,8 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, } found_bus_type = 1; - snprintf(filename, SYSFS_PATH_MAX-1, "%s/%s", devices_dev->path, devicefile->file); + snprintf(filename, sizeof(filename), "%s/%s", devices_dev->path, devicefile->file); + filename[sizeof(filename)-1] = '\0'; dbg("looking at bus '%s' device for specific file '%s'", devices_dev->bus, filename); if (stat(filename, &stats) == 0) { diff --git a/udev_utils.c b/udev_utils.c index 145f02b5e1..d572581f65 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -31,6 +31,7 @@ #include #include +#include "udev_libc_wrapper.h" #include "udev.h" #include "logging.h" #include "udev_utils.h" @@ -45,10 +46,10 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs INIT_LIST_HEAD(&udev->symlink_list); if (subsystem) - strfieldcpy(udev->subsystem, subsystem); + strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem)); if (devpath) { - strfieldcpy(udev->devpath, devpath); + strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); no_trailing_slash(udev->devpath); if (strncmp(udev->devpath, "/block/", 7) == 0) @@ -63,7 +64,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs /* get kernel name */ pos = strrchr(udev->devpath, '/'); if (pos) { - strfieldcpy(udev->kernel_name, &pos[1]); + strlcpy(udev->kernel_name, &pos[1], sizeof(udev->kernel_name)); dbg("kernel_name='%s'", udev->kernel_name); /* Some block devices have '!' in their name, change that to '/' */ @@ -78,7 +79,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs pos = &udev->kernel_name[strlen(udev->kernel_name)]; while (isdigit(pos[-1])) pos--; - strfieldcpy(udev->kernel_number, pos); + strlcpy(udev->kernel_number, pos, sizeof(udev->kernel_number)); dbg("kernel_number='%s'", udev->kernel_number); } } @@ -126,7 +127,7 @@ int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, u int create_path(const char *path) { - char p[NAME_SIZE]; + char p[PATH_SIZE]; char *pos; struct stat stats; @@ -195,19 +196,19 @@ int parse_get_pair(char **orig_string, char **left, char **right) return -ENODEV; /* take the right side and strip off the '"' */ - while (isspace(*string)) + while (isspace(string[0])) ++string; - if (*string == '"') + if (string[0] == '"') ++string; else return -ENODEV; temp = strsep(&string, "\""); - if (!string || *temp == '\0') + if (!string || temp[0] == '\0') return -ENODEV; *right = temp; *orig_string = string; - + return 0; } @@ -292,7 +293,7 @@ int name_list_add(struct list_head *name_list, const char *name, int sort) return -ENOMEM; } - strfieldcpy(new_name->name, name); + strlcpy(new_name->name, name, sizeof(new_name->name)); list_add_tail(&new_name->node, &loop_name->node); return 0; @@ -338,10 +339,10 @@ int call_foreach_file(int (*handler_function)(struct udevice *udev, const char * /* call function for every file in the list */ list_for_each_entry_safe(loop_file, tmp_file, &file_list, node) { - char filename[NAME_SIZE]; + char filename[PATH_SIZE]; - snprintf(filename, NAME_SIZE, "%s/%s", dirname, loop_file->name); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s", dirname, loop_file->name); + filename[sizeof(filename)-1] = '\0'; handler_function(udev, filename); diff --git a/udev_utils.h b/udev_utils.h index 3bb1b25362..c7a41aaa44 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -24,43 +24,9 @@ #include "udev.h" -#define strfieldcpy(to, from) \ -do { \ - to[sizeof(to)-1] = '\0'; \ - strncpy(to, from, sizeof(to)-1); \ -} while (0) - -#define strfieldcat(to, from) \ -do { \ - to[sizeof(to)-1] = '\0'; \ - strncat(to, from, sizeof(to) - strlen(to)-1); \ -} while (0) - -#define strfieldcpymax(to, from, maxsize) \ -do { \ - to[maxsize-1] = '\0'; \ - strncpy(to, from, maxsize-1); \ -} while (0) - -#define strfieldcatmax(to, from, maxsize) \ -do { \ - to[maxsize-1] = '\0'; \ - strncat(to, from, maxsize - strlen(to)-1); \ -} while (0) - -#ifdef asmlinkage -# undef asmlinkage -#endif -#ifdef __i386__ -# define asmlinkage __attribute__((regparm(0))) -#endif -#ifndef asmlinkage -# define asmlinkage -#endif - struct name_entry { struct list_head node; - char name[NAME_SIZE]; + char name[PATH_SIZE]; }; extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); diff --git a/udevd.c b/udevd.c index 1376cf05c7..c2f2dd048b 100644 --- a/udevd.c +++ b/udevd.c @@ -39,6 +39,7 @@ #include #include "list.h" +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_version.h" #include "udev_utils.h" @@ -262,7 +263,7 @@ static int compare_devpath(const char *running, const char *waiting) { int i; - for (i = 0; i < DEVPATH_SIZE; i++) { + for (i = 0; i < PATH_SIZE; i++) { /* identical device event found */ if (running[i] == '\0' && waiting[i] == '\0') return 1; diff --git a/udevinfo.c b/udevinfo.c index e30a036ac6..4d13a5f6dc 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -28,6 +28,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "libsysfs/dlist.h" +#include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" #include "udev_version.h" @@ -35,8 +36,6 @@ #include "logging.h" -#define SYSFS_VALUE_SIZE 256 - #ifdef USE_LOG void log_message (int level, const char *format, ...) { @@ -51,12 +50,12 @@ void log_message (int level, const char *format, ...) static void print_all_attributes(struct dlist *attr_list) { struct sysfs_attribute *attr; - char value[SYSFS_VALUE_SIZE]; + char value[VALUE_SIZE]; int len; dlist_for_each_data(attr_list, attr, struct sysfs_attribute) { if (attr->value != NULL) { - strfieldcpy(value, attr->value); + strlcpy(value, attr->value, sizeof(value)); len = strlen(value); if (len == 0) continue; @@ -193,9 +192,9 @@ int main(int argc, char *argv[], char *envp[]) int root = 0; int attributes = 0; enum query_type query = NONE; - char path[NAME_SIZE] = ""; - char name[NAME_SIZE] = ""; - char temp[NAME_SIZE]; + char path[PATH_SIZE] = ""; + char name[PATH_SIZE] = ""; + char temp[PATH_SIZE]; struct name_entry *name_loop; char *pos; int retval = 0; @@ -215,12 +214,12 @@ int main(int argc, char *argv[], char *envp[]) switch (option) { case 'n': dbg("udev name: %s\n", optarg); - strfieldcpy(name, optarg); + strlcpy(name, optarg, sizeof(name)); break; case 'p': dbg("udev path: %s\n", optarg); - strfieldcpy(path, optarg); + strlcpy(path, optarg, sizeof(path)); break; case 'q': @@ -284,7 +283,7 @@ int main(int argc, char *argv[], char *envp[]) if (path[0] != '/') { /* prepend '/' if missing */ strcpy(temp, "/"); - strfieldcat(temp, path); + strlcpy(temp, path, sizeof(temp)); pos = temp; } else { pos = path; @@ -299,7 +298,7 @@ int main(int argc, char *argv[], char *envp[]) } if (name[0] != '\0') { - char devpath[NAME_SIZE]; + char devpath[PATH_SIZE]; int len; /* remove udev_root if given */ @@ -309,7 +308,7 @@ int main(int argc, char *argv[], char *envp[]) } else pos = name; - retval = udev_db_search_name(devpath, DEVPATH_SIZE, pos); + retval = udev_db_search_name(devpath, sizeof(devpath), pos); if (retval != 0) { printf("device not found in database\n"); goto exit; @@ -360,9 +359,9 @@ print: } else { if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) { /* prepend sysfs mountpoint if not given */ - strfieldcpy(temp, path); - strfieldcpy(path, sysfs_path); - strfieldcat(path, temp); + snprintf(temp, sizeof(temp), "%s%s", sysfs_path, path); + temp[sizeof(temp)-1] = '\0'; + strlcpy(path, temp, sizeof(temp)); } print_device_chain(path); goto exit; diff --git a/udevstart.c b/udevstart.c index 97d38490ae..6b032a1999 100644 --- a/udevstart.c +++ b/udevstart.c @@ -36,11 +36,12 @@ #include #include "libsysfs/sysfs/libsysfs.h" +#include "udev_libc_wrapper.h" +#include "udev.h" #include "logging.h" #include "namedev.h" #include "udev_utils.h" #include "list.h" -#include "udev.h" #ifdef USE_LOG void log_message(int level, const char *format, ...) @@ -50,8 +51,8 @@ void log_message(int level, const char *format, ...) struct device { struct list_head list; - char path[DEVPATH_SIZE]; - char subsys[SUBSYSTEM_SIZE]; + char path[PATH_SIZE]; + char subsys[NAME_SIZE]; }; /* sort files in lexical order */ @@ -74,8 +75,8 @@ static int device_list_insert(const char *path, char *subsystem, struct list_hea return -ENOMEM; } - strfieldcpy(new_device->path, path); - strfieldcpy(new_device->subsys, subsystem); + strlcpy(new_device->path, path, sizeof(new_device->path)); + strlcpy(new_device->subsys, subsystem, sizeof(new_device->subsys)); list_add_tail(&new_device->list, &loop_device->list); dbg("add '%s' from subsys '%s'", new_device->path, new_device->subsys); return 0; @@ -173,11 +174,11 @@ static void exec_list(struct list_head *device_list) static int has_devt(const char *directory) { - char filename[NAME_SIZE]; + char filename[PATH_SIZE]; struct stat statbuf; - snprintf(filename, NAME_SIZE, "%s/dev", directory); - filename[NAME_SIZE-1] = '\0'; + snprintf(filename, sizeof(filename), "%s/dev", directory); + filename[sizeof(filename)-1] = '\0'; if (stat(filename, &statbuf) == 0) return 1; @@ -187,26 +188,26 @@ static int has_devt(const char *directory) static void udev_scan_block(void) { - char base[NAME_SIZE]; + char base[PATH_SIZE]; DIR *dir; struct dirent *dent; LIST_HEAD(device_list); - snprintf(base, DEVPATH_SIZE, "%s/block", sysfs_path); - base[DEVPATH_SIZE-1] = '\0'; + 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[DEVPATH_SIZE]; + char dirname[PATH_SIZE]; DIR *dir2; struct dirent *dent2; if (dent->d_name[0] == '.') continue; - snprintf(dirname, NAME_SIZE, "%s/%s", base, dent->d_name); - dirname[NAME_SIZE-1] = '\0'; + snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name); + dirname[sizeof(dirname)-1] = '\0'; if (has_devt(dirname)) device_list_insert(dirname, "block", &device_list); else @@ -216,13 +217,13 @@ static void udev_scan_block(void) dir2 = opendir(dirname); if (dir2 != NULL) { for (dent2 = readdir(dir2); dent2 != NULL; dent2 = readdir(dir2)) { - char dirname2[DEVPATH_SIZE]; + char dirname2[PATH_SIZE]; if (dent2->d_name[0] == '.') continue; - snprintf(dirname2, DEVPATH_SIZE, "%s/%s", dirname, dent2->d_name); - dirname2[DEVPATH_SIZE-1] = '\0'; + snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name); + dirname2[sizeof(dirname2)-1] = '\0'; if (has_devt(dirname2)) device_list_insert(dirname2, "block", &device_list); @@ -237,37 +238,37 @@ static void udev_scan_block(void) static void udev_scan_class(void) { - char base[DEVPATH_SIZE]; + char base[PATH_SIZE]; DIR *dir; struct dirent *dent; LIST_HEAD(device_list); - snprintf(base, DEVPATH_SIZE, "%s/class", sysfs_path); - base[DEVPATH_SIZE-1] = '\0'; + 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[DEVPATH_SIZE]; + char dirname[PATH_SIZE]; DIR *dir2; struct dirent *dent2; if (dent->d_name[0] == '.') continue; - snprintf(dirname, DEVPATH_SIZE, "%s/%s", base, dent->d_name); - dirname[DEVPATH_SIZE-1] = '\0'; + 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[DEVPATH_SIZE]; + char dirname2[PATH_SIZE]; if (dent2->d_name[0] == '.') continue; - snprintf(dirname2, DEVPATH_SIZE, "%s/%s", dirname, dent2->d_name); - dirname2[DEVPATH_SIZE-1] = '\0'; + snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name); + dirname2[sizeof(dirname2)-1] = '\0'; /* pass the net class as it is */ if (strcmp(dent->d_name, "net") == 0) diff --git a/udevtest.c b/udevtest.c index 084fde0706..5ce2570058 100644 --- a/udevtest.c +++ b/udevtest.c @@ -1,5 +1,5 @@ /* - * udev.c + * udevtest.c * * Userspace devfs * @@ -53,8 +53,8 @@ int main(int argc, char *argv[], char *envp[]) { struct sysfs_class_device *class_dev; char *devpath; - char path[SYSFS_PATH_MAX]; - char temp[NAME_SIZE]; + char path[PATH_SIZE]; + char temp[PATH_SIZE]; struct udevice udev; char *subsystem = NULL; @@ -69,18 +69,16 @@ int main(int argc, char *argv[], char *envp[]) udev_init_config(); /* remove sysfs_path if given */ - if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) { + if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) devpath = &argv[1][strlen(sysfs_path)] ; - } else if (argv[1][0] != '/') { /* prepend '/' if missing */ - strfieldcpy(temp, "/"); - strfieldcat(temp, argv[1]); + snprintf(temp, sizeof(temp), "/%s", argv[1]); + temp[sizeof(temp)-1] = '\0'; devpath = temp; - } else { + } else devpath = argv[1]; - } info("looking at '%s'", devpath); @@ -100,7 +98,8 @@ int main(int argc, char *argv[], char *envp[]) } /* open the device */ - snprintf(path, SYSFS_PATH_MAX, "%s%s", sysfs_path, udev.devpath); + snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath); + path[sizeof(path)-1] = '\0'; class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { info("sysfs_open_class_device_path failed"); From 472419869c387bb0963d8cfecca997b8154f4d44 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 7 Mar 2005 05:56:40 +0100 Subject: [PATCH 1208/4284] [PATCH] rename device_list->list to device_list->node --- udevstart.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/udevstart.c b/udevstart.c index 6b032a1999..7564c3de03 100644 --- a/udevstart.c +++ b/udevstart.c @@ -50,7 +50,7 @@ void log_message(int level, const char *format, ...) #endif struct device { - struct list_head list; + struct list_head node; char path[PATH_SIZE]; char subsys[NAME_SIZE]; }; @@ -63,7 +63,7 @@ static int device_list_insert(const char *path, char *subsystem, struct list_hea dbg("insert: '%s'\n", path); - list_for_each_entry(loop_device, device_list, list) { + list_for_each_entry(loop_device, device_list, node) { if (strcmp(loop_device->path, path) > 0) { break; } @@ -77,7 +77,7 @@ static int device_list_insert(const char *path, char *subsystem, struct list_hea strlcpy(new_device->path, path, sizeof(new_device->path)); strlcpy(new_device->subsys, subsystem, sizeof(new_device->subsys)); - list_add_tail(&new_device->list, &loop_device->list); + list_add_tail(&new_device->node, &loop_device->node); dbg("add '%s' from subsys '%s'", new_device->path, new_device->subsys); return 0; } @@ -136,11 +136,11 @@ static void exec_list(struct list_head *device_list) int i; /* handle the "first" type devices first */ - list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { + 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, loop_device->subsys); - list_del(&loop_device->list); + list_del(&loop_device->node); free(loop_device); break; } @@ -148,7 +148,7 @@ static void exec_list(struct list_head *device_list) } /* handle the devices we are allowed to, excluding the "last" type devices */ - list_for_each_entry_safe(loop_device, tmp_device, device_list, list) { + 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) { @@ -160,14 +160,14 @@ static void exec_list(struct list_head *device_list) continue; add_device(loop_device->path, loop_device->subsys); - list_del(&loop_device->list); + 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, list) { + list_for_each_entry_safe(loop_device, tmp_device, device_list, node) { add_device(loop_device->path, loop_device->subsys); - list_del(&loop_device->list); + list_del(&loop_device->node); free(loop_device); } } From 4272779706c53c635a3fa5431a4e8791402183b4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 7 Mar 2005 07:04:46 +0100 Subject: [PATCH 1209/4284] [PATCH] klibc: version 0.214 --- klibc/MCONFIG | 2 +- klibc/Makefile | 2 +- klibc/include/klibc/compiler.h | 6 +++--- klibc/klcc.in | 16 ++++++++++++++-- klibc/klibc/arch/sparc/MCONFIG | 2 +- klibc/klibc/arch/sparc/Makefile.inc | 7 ++++++- klibc/klibc/arch/sparc/crt0.S | 2 +- klibc/version | 2 +- 8 files changed, 28 insertions(+), 11 deletions(-) diff --git a/klibc/MCONFIG b/klibc/MCONFIG index c833499483..7a24b821ad 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -59,7 +59,7 @@ HOST_LIBS = # Static library paths CRT0 = $(KLIBOBJ)/crt0.o KLIBC = $(KLIBOBJ)/libc.a -LIBGCC = $(shell $(CC) --print-libgcc) +LIBGCC = $(shell $(CC) $(REQFLAGS) $(OPTFLAGS) --print-libgcc) # Shared library paths CRTSHARED = $(KLIBOBJ)/interp.o diff --git a/klibc/Makefile b/klibc/Makefile index 812ea92f47..a512aa308a 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -54,7 +54,7 @@ local-install: $(CROSS)klcc mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)lib mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)bin - set -xe ; for d in linux asm-$(ARCH) asm-generic $(ASMARCH); do \ + set -xe ; for d in linux scsi asm-$(ARCH) asm-generic $(ASMARCH); do \ mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d ; \ for r in $(KRNLSRC)/include $(KRNLOBJ)/include $(KRNLOBJ)/include2 ; do \ [ ! -d $$r/$$d ] || \ diff --git a/klibc/include/klibc/compiler.h b/klibc/include/klibc/compiler.h index 823996e777..ee697adf08 100644 --- a/klibc/include/klibc/compiler.h +++ b/klibc/include/klibc/compiler.h @@ -22,7 +22,7 @@ /* How to declare a function that *must* be inlined */ #ifdef __GNUC__ -# if __GNUC_MAJOR__ >= 3 +# if __GNUC__ >= 3 # define __must_inline static __inline__ __attribute__((always_inline)) # else # define __must_inline extern __inline__ @@ -84,14 +84,14 @@ #endif /* malloc() function (returns unaliased pointer) */ -#if defined(__GNUC__) && (__GNUC_MAJOR__ >= 3) +#if defined(__GNUC__) && (__GNUC__ >= 3) # define __mallocfunc __attribute__((malloc)) #else # define __mallocfunc #endif /* likely/unlikely */ -#if defined(__GNUC__) && (__GNUC_MAJOR__ > 2 || (__GNUC_MAJOR__ == 2 && __GNUC_MINOR__ >= 95)) +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)) # define __likely(x) __builtin_expect((x), 1) # define __unlikely(x) __builtin_expect((x), 0) #else diff --git a/klibc/klcc.in b/klibc/klcc.in index bdd03e73b3..d8721c9a6b 100644 --- a/klibc/klcc.in +++ b/klibc/klcc.in @@ -77,6 +77,11 @@ sub mysystem(@) { return system(@_); } +# +# Initialization +# +open(NULL, '+<', '/dev/null') or die "$0: cannot open /dev/null\n"; + # # Begin parsing options. # @@ -191,10 +196,17 @@ if ( $operation ne '' ) { } } + # Get the libgcc pathname for the *current* gcc + open(LIBGCC, '-|', $CC, @ccopt, '-print-libgcc-file-name') + or die "$0: cannot get libgcc filename\n"; + $libgcc = ; + chomp $libgcc; + close(LIBGCC); + if ( $shared ) { - $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @sharedlib); + $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @sharedlib, $libgcc); } else { - $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @staticlib); + $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @staticlib, $libgcc); } unlink(@rmobjs); diff --git a/klibc/klibc/arch/sparc/MCONFIG b/klibc/klibc/arch/sparc/MCONFIG index 55f8b198c2..3a5cbaa2e7 100644 --- a/klibc/klibc/arch/sparc/MCONFIG +++ b/klibc/klibc/arch/sparc/MCONFIG @@ -7,7 +7,7 @@ # accordingly. # -OPTFLAGS = -Os +OPTFLAGS = -Os -m32 -mptr32 BITSIZE = 32 # Extra linkflags when building the shared version of the library diff --git a/klibc/klibc/arch/sparc/Makefile.inc b/klibc/klibc/arch/sparc/Makefile.inc index 6ea66114fa..bea1dbc94e 100644 --- a/klibc/klibc/arch/sparc/Makefile.inc +++ b/klibc/klibc/arch/sparc/Makefile.inc @@ -16,7 +16,12 @@ ARCHOBJS = \ arch/$(ARCH)/umul.o \ arch/$(ARCH)/setjmp.o \ arch/$(ARCH)/syscall.o \ - arch/$(ARCH)/sysfork.o + arch/$(ARCH)/sysfork.o \ + libgcc/__divdi3.o \ + libgcc/__moddi3.o \ + libgcc/__udivdi3.o \ + libgcc/__umoddi3.o \ + libgcc/__udivmoddi4.o arch/$(ARCH)/sdiv.S: arch/$(ARCH)/divrem.m4 @echo 'building $@ from $^' diff --git a/klibc/klibc/arch/sparc/crt0.S b/klibc/klibc/arch/sparc/crt0.S index 148cb4b4e9..63db188961 100644 --- a/klibc/klibc/arch/sparc/crt0.S +++ b/klibc/klibc/arch/sparc/crt0.S @@ -1,2 +1,2 @@ #define TARGET_PTR_SIZE 32 -#include "arch/sparc/crt0i.S" +#include "crt0i.S" diff --git a/klibc/version b/klibc/version index 1f39702100..136a629e2d 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.211 +0.214 From 83b069c6e695446688715cc4404bcfaa3288e649 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 8 Mar 2005 01:09:45 +0100 Subject: [PATCH 1210/4284] [PATCH] cleanup list.h --- list.h | 195 ++++++--------------------------------------------------- 1 file changed, 20 insertions(+), 175 deletions(-) diff --git a/list.h b/list.h index 07d474888e..8626630f6b 100644 --- a/list.h +++ b/list.h @@ -1,32 +1,25 @@ -/* +/* * Copied from the Linux kernel source tree, version 2.6.0-test1. * * Licensed under the GPL v2 as per the whole kernel source tree. * - * Ripped out the rcu stuff, as it's not needed. */ -#ifndef _LINUX_LIST_H -#define _LINUX_LIST_H +#ifndef _LIST_H +#define _LIST_H -//#include /** * 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. + * @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) );}) -//#include -static inline void prefetch(const void *x) {;} - -//#include - /* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses @@ -143,8 +136,8 @@ static inline void list_del_init(struct list_head *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_del(list->prev, list->next); + list_add(list, head); } /** @@ -155,8 +148,8 @@ static inline void list_move(struct list_head *list, struct list_head *head) 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_del(list->prev, list->next); + list_add_tail(list, head); } /** @@ -224,8 +217,8 @@ static inline void list_splice_init(struct list_head *list, * @head: the head for your list. */ #define list_for_each(pos, head) \ - for (pos = (head)->next, prefetch(pos->next); pos != (head); \ - pos = pos->next, prefetch(pos->next)) + for (pos = (head)->next; pos != (head); \ + pos = pos->next) /** * __list_for_each - iterate over a list @@ -233,7 +226,7 @@ static inline void list_splice_init(struct list_head *list, * @head: the head for your list. * * This variant differs from list_for_each() in that it's the - * simplest possible list iteration code, no prefetching is done. + * 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. */ @@ -246,9 +239,8 @@ static inline void list_splice_init(struct list_head *list, * @head: the head for your list. */ #define list_for_each_prev(pos, head) \ - for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \ - pos = pos->prev, prefetch(pos->prev)) - + 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. @@ -266,11 +258,9 @@ static inline void list_splice_init(struct list_head *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), \ - prefetch(pos->member.next); \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member), \ - prefetch(pos->member.next)) + pos = list_entry(pos->member.next, typeof(*pos), member)) /** * list_for_each_entry_reverse - iterate backwards over list of given type. @@ -279,12 +269,9 @@ static inline void list_splice_init(struct list_head *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), \ - prefetch(pos->member.prev); \ + for (pos = list_entry((head)->prev, typeof(*pos), member); \ &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member), \ - prefetch(pos->member.prev)) - + 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 @@ -299,146 +286,4 @@ static inline void list_splice_init(struct list_head *list, &pos->member != (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) -/* - * Double linked lists with a single pointer list head. - * Mostly useful for hash tables where the two pointer list head is - * too wasteful. - * You lose the ability to access the tail in O(1). - */ - -struct hlist_head { - struct hlist_node *first; -}; - -struct hlist_node { - struct hlist_node *next, **pprev; -}; - -#define HLIST_HEAD_INIT { .first = NULL } -#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL } -#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL) -#define INIT_HLIST_NODE(ptr) ((ptr)->next = NULL, (ptr)->pprev = NULL) - -static __inline__ int hlist_unhashed(struct hlist_node *h) -{ - return !h->pprev; -} - -static __inline__ int hlist_empty(struct hlist_head *h) -{ - return !h->first; -} - -static __inline__ void __hlist_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - *pprev = next; - if (next) - next->pprev = pprev; -} - -static __inline__ void hlist_del(struct hlist_node *n) -{ - __hlist_del(n); - n->next = LIST_POISON1; - n->pprev = LIST_POISON2; -} - -static __inline__ void hlist_del_init(struct hlist_node *n) -{ - if (n->pprev) { - __hlist_del(n); - INIT_HLIST_NODE(n); - } -} - -static __inline__ void hlist_add_head(struct hlist_node *n, struct hlist_head *h) -{ - struct hlist_node *first = h->first; - n->next = first; - if (first) - first->pprev = &n->next; - h->first = n; - n->pprev = &h->first; -} - -/* next must be != NULL */ -static __inline__ void hlist_add_before(struct hlist_node *n, struct hlist_node *next) -{ - n->pprev = next->pprev; - n->next = next; - next->pprev = &n->next; - *(n->pprev) = n; -} - -static __inline__ void hlist_add_after(struct hlist_node *n, - struct hlist_node *next) -{ - next->next = n->next; - *(next->pprev) = n; - n->next = next; -} - -#define hlist_entry(ptr, type, member) container_of(ptr,type,member) - -/* Cannot easily do prefetch unfortunately */ -#define hlist_for_each(pos, head) \ - for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \ - pos = pos->next) - -#define hlist_for_each_safe(pos, n, head) \ - for (pos = (head)->first; n = pos ? pos->next : 0, pos; \ - pos = n) - -/** - * hlist_for_each_entry - iterate over list of given type - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry(tpos, pos, head, member) \ - for (pos = (head)->first; \ - pos && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_continue - iterate over a hlist continuing after existing point - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_continue(tpos, pos, member) \ - for (pos = (pos)->next; \ - pos && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_from - iterate over a hlist continuing from existing point - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_from(tpos, pos, member) \ - for (; pos && ({ prefetch(pos->next); 1;}) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = pos->next) - -/** - * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @tpos: the type * to use as a loop counter. - * @pos: the &struct hlist_node to use as a loop counter. - * @n: another &struct hlist_node to use as temporary storage - * @head: the head for your list. - * @member: the name of the hlist_node within the struct. - */ -#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \ - for (pos = (head)->first; \ - pos && ({ n = pos->next; 1; }) && \ - ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \ - pos = n) - -#endif +#endif /* _LIST_H */ From 2b40452ab3146322a88ae201a2eb534204c75d63 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 9 Mar 2005 02:12:22 +0100 Subject: [PATCH 1211/4284] [PATCH] fix segfaulting udev while DRIVER matching Don't try to match against values of a nonexistent physical device. Discovered by: Thomas Breitner . --- namedev.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/namedev.c b/namedev.c index 9c73c08149..4b3674935a 100644 --- a/namedev.c +++ b/namedev.c @@ -516,15 +516,11 @@ static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_devic return 0; } -static int match_id(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) +static int match_id(struct config_device *dev, struct sysfs_device *sysfs_device) { char path[PATH_SIZE]; char *temp; - /* we have to have a sysfs device for ID to work */ - if (!sysfs_device) - return -ENODEV; - strlcpy(path, sysfs_device->path, sizeof(path)); temp = strrchr(path, '/'); temp++; @@ -535,15 +531,11 @@ static int match_id(struct config_device *dev, struct sysfs_class_device *class_ return 0; } -static int match_place(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) +static int match_place(struct config_device *dev, struct sysfs_device *sysfs_device) { char path[PATH_SIZE]; char *temp; - /* we have to have a sysfs device for PLACE to work */ - if (!sysfs_device) - return -ENODEV; - strlcpy(path, sysfs_device->path, sizeof(path)); temp = strrchr(path, '/'); dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); @@ -588,6 +580,10 @@ static int match_rule(struct udevice *udev, struct config_device *dev, while (1) { /* check for matching driver */ if (dev->driver[0] != '\0') { + if (sysfs_device == NULL) { + dbg("device has no sysfs_device"); + goto try_parent; + } dbg("check for " FIELD_DRIVER " dev->driver='%s' sysfs_device->driver_name='%s'", dev->driver, sysfs_device->driver_name); if (strcmp_pattern(dev->driver, sysfs_device->driver_name) != 0) { @@ -600,7 +596,7 @@ static int match_rule(struct udevice *udev, struct config_device *dev, /* check for matching bus value */ if (dev->bus[0] != '\0') { if (sysfs_device == NULL) { - dbg("device has no bus"); + dbg("device has no sysfs_device"); goto try_parent; } dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", @@ -614,8 +610,12 @@ static int match_rule(struct udevice *udev, struct config_device *dev, /* check for matching bus id */ if (dev->id[0] != '\0') { + if (sysfs_device == NULL) { + dbg("device has no sysfs_device"); + goto try_parent; + } dbg("check " FIELD_ID); - if (match_id(dev, class_dev, sysfs_device) != 0) { + if (match_id(dev, sysfs_device) != 0) { dbg(FIELD_ID " is not matching"); goto try_parent; } @@ -624,8 +624,12 @@ static int match_rule(struct udevice *udev, struct config_device *dev, /* check for matching place of device */ if (dev->place[0] != '\0') { + if (sysfs_device == NULL) { + dbg("device has no sysfs_device"); + goto try_parent; + } dbg("check " FIELD_PLACE); - if (match_place(dev, class_dev, sysfs_device) != 0) { + if (match_place(dev, sysfs_device) != 0) { dbg(FIELD_PLACE " is not matching"); goto try_parent; } From 138068d690d79e71239d3e776f01560afbabc1cb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Mar 2005 00:58:01 +0100 Subject: [PATCH 1212/4284] [PATCH] fix ia64 compile --- extras/volume_id/volume_id/cramfs.c | 2 +- extras/volume_id/volume_id/ext.c | 2 +- extras/volume_id/volume_id/fat.c | 6 +++--- extras/volume_id/volume_id/hfs.c | 4 ++-- extras/volume_id/volume_id/highpoint.c | 2 +- extras/volume_id/volume_id/hpfs.c | 2 +- extras/volume_id/volume_id/iso9660.c | 4 ++-- extras/volume_id/volume_id/jfs.c | 2 +- extras/volume_id/volume_id/linux_raid.c | 2 +- extras/volume_id/volume_id/linux_swap.c | 2 +- extras/volume_id/volume_id/lvm.c | 4 ++-- extras/volume_id/volume_id/mac.c | 4 ++-- extras/volume_id/volume_id/minix.c | 2 +- extras/volume_id/volume_id/msdos.c | 10 +++++----- extras/volume_id/volume_id/ntfs.c | 6 +++--- extras/volume_id/volume_id/reiserfs.c | 2 +- extras/volume_id/volume_id/romfs.c | 2 +- extras/volume_id/volume_id/sysv.c | 2 +- extras/volume_id/volume_id/udf.c | 2 +- extras/volume_id/volume_id/ufs.c | 2 +- extras/volume_id/volume_id/util.c | 6 +++--- extras/volume_id/volume_id/volume_id.h | 2 +- extras/volume_id/volume_id/xfs.c | 2 +- libsysfs/sysfs_dir.c | 2 +- namedev_parse.c | 2 +- udev_libc_wrapper.h | 22 ++++++++++++++++------ udevd.c | 3 ++- 27 files changed, 57 insertions(+), 46 deletions(-) diff --git a/extras/volume_id/volume_id/cramfs.c b/extras/volume_id/volume_id/cramfs.c index a8058646d1..0c76860013 100644 --- a/extras/volume_id/volume_id/cramfs.c +++ b/extras/volume_id/volume_id/cramfs.c @@ -58,7 +58,7 @@ int volume_id_probe_cramfs(struct volume_id *id, __u64 off) { struct cramfs_super *cs; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); cs = (struct cramfs_super *) volume_id_get_buffer(id, off, 0x200); if (cs == NULL) diff --git a/extras/volume_id/volume_id/ext.c b/extras/volume_id/volume_id/ext.c index b7bdf05d97..4783642114 100644 --- a/extras/volume_id/volume_id/ext.c +++ b/extras/volume_id/volume_id/ext.c @@ -66,7 +66,7 @@ int volume_id_probe_ext(struct volume_id *id, __u64 off) { struct ext2_super_block *es; - dbg("probing at offset %llu", off); + dbg("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) diff --git a/extras/volume_id/volume_id/fat.c b/extras/volume_id/volume_id/fat.c index 58aa2aba05..f6d3699758 100644 --- a/extras/volume_id/volume_id/fat.c +++ b/extras/volume_id/volume_id/fat.c @@ -159,7 +159,7 @@ int volume_id_probe_vfat(struct volume_id *id, __u64 off) __u32 next; int maxloop; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); vs = (struct vfat_super_block *) volume_id_get_buffer(id, off, 0x200); if (vs == NULL) @@ -257,7 +257,7 @@ valid: /* the label may be an attribute in the root directory */ root_start = (reserved + fat_size) * sector_size; - dbg("root dir start 0x%llx", root_start); + 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); @@ -302,7 +302,7 @@ fat32: 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", next_off); + dbg("cluster offset 0x%llx", (unsigned long long) next_off); /* get cluster */ buf = volume_id_get_buffer(id, off + next_off, buf_size); diff --git a/extras/volume_id/volume_id/hfs.c b/extras/volume_id/volume_id/hfs.c index 327461c676..8c40975036 100644 --- a/extras/volume_id/volume_id/hfs.c +++ b/extras/volume_id/volume_id/hfs.c @@ -173,7 +173,7 @@ int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; const __u8 *buf; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); buf = volume_id_get_buffer(id, off + HFS_SUPERBLOCK_OFFSET, 0x200); if (buf == NULL) @@ -196,7 +196,7 @@ int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) off += (alloc_first_block * 512) + (embed_first_block * alloc_block_size); - dbg("hfs wrapped hfs+ found at offset 0x%llx", off); + 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) diff --git a/extras/volume_id/volume_id/highpoint.c b/extras/volume_id/volume_id/highpoint.c index e13fd6de61..72f7d28429 100644 --- a/extras/volume_id/volume_id/highpoint.c +++ b/extras/volume_id/volume_id/highpoint.c @@ -54,7 +54,7 @@ int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off) { const __u8 *buf; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); buf = volume_id_get_buffer(id, off + HPT37X_CONFIG_OFF, 0x200); if (buf == NULL) diff --git a/extras/volume_id/volume_id/hpfs.c b/extras/volume_id/volume_id/hpfs.c index 3aa95fa839..96c63d5e1d 100644 --- a/extras/volume_id/volume_id/hpfs.c +++ b/extras/volume_id/volume_id/hpfs.c @@ -51,7 +51,7 @@ int volume_id_probe_hpfs(struct volume_id *id, __u64 off) { struct hpfs_super *hs; - dbg("probing at offset %llu", off); + dbg("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) diff --git a/extras/volume_id/volume_id/iso9660.c b/extras/volume_id/volume_id/iso9660.c index ffccf609dc..d4ccb9db9c 100644 --- a/extras/volume_id/volume_id/iso9660.c +++ b/extras/volume_id/volume_id/iso9660.c @@ -68,7 +68,7 @@ int volume_id_probe_iso9660(struct volume_id *id, __u64 off) { union iso_super_block *is; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); is = (union iso_super_block *) volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); if (is == NULL) @@ -90,7 +90,7 @@ int volume_id_probe_iso9660(struct volume_id *id, __u64 off) if (is == NULL || is->iso.type == ISO_VD_END) break; if (is->iso.type == ISO_VD_SUPPLEMENTARY) { - dbg("found ISO supplementary VD at offset 0x%llx", off + vd_offset); + dbg("found ISO supplementary VD at offset 0x%llx", (unsigned long long) (off + vd_offset)); volume_id_set_label_raw(id, is->iso.volume_id, 32); volume_id_set_label_unicode16(id, is->iso.volume_id, BE, 32); found_svd = 1; diff --git a/extras/volume_id/volume_id/jfs.c b/extras/volume_id/volume_id/jfs.c index ac4eab502d..77fa095357 100644 --- a/extras/volume_id/volume_id/jfs.c +++ b/extras/volume_id/volume_id/jfs.c @@ -58,7 +58,7 @@ int volume_id_probe_jfs(struct volume_id *id, __u64 off) { struct jfs_super_block *js; - dbg("probing at offset %llu", off); + dbg("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) diff --git a/extras/volume_id/volume_id/linux_raid.c b/extras/volume_id/volume_id/linux_raid.c index 0ea8596ad6..e7db4031de 100644 --- a/extras/volume_id/volume_id/linux_raid.c +++ b/extras/volume_id/volume_id/linux_raid.c @@ -67,7 +67,7 @@ int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) __u64 sboff; __u8 uuid[16]; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); if (size < 0x10000) return -1; diff --git a/extras/volume_id/volume_id/linux_swap.c b/extras/volume_id/volume_id/linux_swap.c index 39a2c4aab3..e37a79be86 100644 --- a/extras/volume_id/volume_id/linux_swap.c +++ b/extras/volume_id/volume_id/linux_swap.c @@ -55,7 +55,7 @@ int volume_id_probe_linux_swap(struct volume_id *id, __u64 off) const __u8 *buf; unsigned int page; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); /* the swap signature is at the end of the PAGE_SIZE */ for (page = 0x1000; page <= LARGEST_PAGESIZE; page <<= 1) { diff --git a/extras/volume_id/volume_id/lvm.c b/extras/volume_id/volume_id/lvm.c index bfc2ef2343..d1e337dc35 100644 --- a/extras/volume_id/volume_id/lvm.c +++ b/extras/volume_id/volume_id/lvm.c @@ -59,7 +59,7 @@ int volume_id_probe_lvm1(struct volume_id *id, __u64 off) const __u8 *buf; struct lvm1_super_block *lvm; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); buf = volume_id_get_buffer(id, off + LVM1_SB_OFF, 0x800); if (buf == NULL) @@ -85,7 +85,7 @@ int volume_id_probe_lvm2(struct volume_id *id, __u64 off) unsigned int soff; struct lvm2_super_block *lvm; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); buf = volume_id_get_buffer(id, off, LVM2LABEL_SCAN_SECTORS * 0x200); if (buf == NULL) diff --git a/extras/volume_id/volume_id/mac.c b/extras/volume_id/volume_id/mac.c index 2e2db486f2..dcfacc2a69 100644 --- a/extras/volume_id/volume_id/mac.c +++ b/extras/volume_id/volume_id/mac.c @@ -61,7 +61,7 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) struct mac_driver_desc *driver; struct mac_partition *part; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); buf = volume_id_get_buffer(id, off, 0x200); if (buf == NULL) @@ -122,7 +122,7 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) poff = be32_to_cpu(part->start_block) * bsize; plen = be32_to_cpu(part->block_count) * bsize; dbg("found '%s' partition entry at 0x%llx, len 0x%llx", - part->type, poff, plen); + part->type, (unsigned long long) poff, (unsigned long long) plen); id->partitions[i].off = poff; id->partitions[i].len = plen; diff --git a/extras/volume_id/volume_id/minix.c b/extras/volume_id/volume_id/minix.c index d9c9ea8ca9..d2f2a336d4 100644 --- a/extras/volume_id/volume_id/minix.c +++ b/extras/volume_id/volume_id/minix.c @@ -59,7 +59,7 @@ int volume_id_probe_minix(struct volume_id *id, __u64 off) { struct minix_super_block *ms; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); ms = (struct minix_super_block *) volume_id_get_buffer(id, off + MINIX_SUPERBLOCK_OFFSET, 0x200); if (ms == NULL) diff --git a/extras/volume_id/volume_id/msdos.c b/extras/volume_id/volume_id/msdos.c index fc2f99d4d0..47c94456e4 100644 --- a/extras/volume_id/volume_id/msdos.c +++ b/extras/volume_id/volume_id/msdos.c @@ -81,7 +81,7 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) struct msdos_partition_entry *part; struct volume_id_partition *p; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); buf = volume_id_get_buffer(id, off, 0x200); if (buf == NULL) @@ -124,14 +124,14 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) p->partition_type_raw = part[i].sys_ind; if (is_extended(part[i].sys_ind)) { - dbg("found extended partition at 0x%llx", poff); + dbg("found extended partition at 0x%llx", (unsigned long long) poff); volume_id_set_usage_part(p, VOLUME_ID_PARTITIONTABLE); p->type = "msdos_extended_partition"; if (extended == 0) extended = off + poff; } else { dbg("found 0x%x data partition at 0x%llx, len 0x%llx", - part[i].sys_ind, poff, plen); + part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen); if (is_raid(part[i].sys_ind)) volume_id_set_usage_part(p, VOLUME_ID_RAID); @@ -174,12 +174,12 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) continue; if (is_extended(part[i].sys_ind)) { - dbg("found extended partition at 0x%llx", poff); + dbg("found extended partition at 0x%llx", (unsigned long long) poff); if (next == 0) next = extended + poff; } else { dbg("found 0x%x data partition at 0x%llx, len 0x%llx", - part[i].sys_ind, poff, plen); + part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen); /* we always start at the 5th entry */ while (id->partition_count < 4) diff --git a/extras/volume_id/volume_id/ntfs.c b/extras/volume_id/volume_id/ntfs.c index 84d6fbb843..8f31735a2d 100644 --- a/extras/volume_id/volume_id/ntfs.c +++ b/extras/volume_id/volume_id/ntfs.c @@ -118,7 +118,7 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) const __u8 *buf; const __u8 *val; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); ns = (struct ntfs_super_block *) volume_id_get_buffer(id, off, 0x200); if (ns == NULL) @@ -142,8 +142,8 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) dbg("sectorsize 0x%x", sector_size); dbg("clustersize 0x%x", cluster_size); - dbg("mftcluster %lli", mft_cluster); - dbg("mftoffset 0x%llx", mft_off); + 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); diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index 094062dba2..34cf167dc4 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -73,7 +73,7 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) struct reiser4_super_block *rs4; __u8 *buf; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); buf = volume_id_get_buffer(id, off + REISERFS_SUPERBLOCK_OFFSET, 0x200); if (buf == NULL) diff --git a/extras/volume_id/volume_id/romfs.c b/extras/volume_id/volume_id/romfs.c index fe5e5a4827..9c2b41bb86 100644 --- a/extras/volume_id/volume_id/romfs.c +++ b/extras/volume_id/volume_id/romfs.c @@ -50,7 +50,7 @@ int volume_id_probe_romfs(struct volume_id *id, __u64 off) { struct romfs_super *rfs; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); rfs = (struct romfs_super *) volume_id_get_buffer(id, off, 0x200); if (rfs == NULL) diff --git a/extras/volume_id/volume_id/sysv.c b/extras/volume_id/volume_id/sysv.c index 6c4408d80c..d4745daa22 100644 --- a/extras/volume_id/volume_id/sysv.c +++ b/extras/volume_id/volume_id/sysv.c @@ -108,7 +108,7 @@ int volume_id_probe_sysv(struct volume_id *id, __u64 off) struct xenix_super *xs; unsigned int boff; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); for (boff = 0x200; boff <= SYSV_MAX_BLOCKSIZE; boff <<= 1) { vs = (struct sysv_super *) diff --git a/extras/volume_id/volume_id/udf.c b/extras/volume_id/volume_id/udf.c index 06b521545f..a378fa9fd1 100644 --- a/extras/volume_id/volume_id/udf.c +++ b/extras/volume_id/volume_id/udf.c @@ -85,7 +85,7 @@ int volume_id_probe_udf(struct volume_id *id, __u64 off) unsigned int loc; unsigned int clen; - dbg("probing at offset %llu", off); + dbg("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) diff --git a/extras/volume_id/volume_id/ufs.c b/extras/volume_id/volume_id/ufs.c index 37e74aee6f..d4f4db3d32 100644 --- a/extras/volume_id/volume_id/ufs.c +++ b/extras/volume_id/volume_id/ufs.c @@ -188,7 +188,7 @@ int volume_id_probe_ufs(struct volume_id *id, __u64 off) struct ufs_super_block *ufs; int offsets[] = {0, 8, 64, 256, -1}; - dbg("probing at offset %llu", off); + dbg("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); diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index 6ae4d09927..22abc9cbf8 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -188,7 +188,7 @@ __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len) { unsigned int buf_len; - dbg("get buffer off 0x%llx(%llu), len 0x%x", off, off, len); + dbg("get buffer off 0x%llx(%llu), len 0x%x", (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) { @@ -199,7 +199,7 @@ __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len) /* check if we need to read */ if ((off + len) > id->sbbuf_len) { - dbg("read sbbuf len:0x%llx", off + len); + dbg("read sbbuf len:0x%llx", (unsigned long long) (off + len)); lseek(id->fd, 0, SEEK_SET); buf_len = read(id->fd, id->sbbuf, off + len); dbg("got 0x%x (%i) bytes", buf_len, buf_len); @@ -224,7 +224,7 @@ __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len) /* check if we need to read */ if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { - dbg("read seekbuf off:0x%llx len:0x%x", off, len); + dbg("read seekbuf off:0x%llx len:0x%x", (unsigned long long) off, len); if (lseek(id->fd, off, SEEK_SET) == -1) return NULL; buf_len = read(id->fd, id->seekbuf, len); diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 6719c1aa31..8287de28f6 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 39 +#define VOLUME_ID_VERSION 40 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 diff --git a/extras/volume_id/volume_id/xfs.c b/extras/volume_id/volume_id/xfs.c index 12a89aafcb..b8702a3fb3 100644 --- a/extras/volume_id/volume_id/xfs.c +++ b/extras/volume_id/volume_id/xfs.c @@ -58,7 +58,7 @@ int volume_id_probe_xfs(struct volume_id *id, __u64 off) { struct xfs_super_block *xs; - dbg("probing at offset %llu", off); + dbg("probing at offset 0x%llx", (unsigned long long) off); xs = (struct xfs_super_block *) volume_id_get_buffer(id, off, 0x200); if (xs == NULL) diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index 63eec7bb9a..ac3936656c 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -244,7 +244,7 @@ int sysfs_write_attribute(struct sysfs_attribute *sysattr, close(fd); return -1; } else if ((unsigned int)length != len) { - dprintf("Could not write %d bytes to attribute %s\n", + dprintf("Could not write %zd bytes to attribute %s\n", len, sysattr->name); /* * since we could not write user supplied number of bytes, diff --git a/namedev_parse.c b/namedev_parse.c index 942596121e..b19a5f26f5 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -338,7 +338,7 @@ static int namedev_parse(struct udevice *udev, const char *filename) continue; error: info("parse error %s, line %d:%d, rule skipped", - filename, lineno, temp - line); + filename, lineno, (int) (temp - line)); } } diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 65f4e01c23..4d6d332c69 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -22,14 +22,24 @@ #ifndef _UDEV_LIBC_WRAPPER_H_ #define _UDEV_LIBC_WRAPPER_H_ -#ifdef asmlinkage -# undef asmlinkage -#endif +#undef asmlinkage #ifdef __i386__ -# define asmlinkage __attribute__((regparm(0))) +#define asmlinkage __attribute__((regparm(0))) +#else +#define asmlinkage #endif -#ifndef asmlinkage -# define asmlinkage + +#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 #include diff --git a/udevd.c b/udevd.c index c2f2dd048b..2cd3622ce0 100644 --- a/udevd.c +++ b/udevd.c @@ -21,7 +21,6 @@ */ #include -#include #include #include #include @@ -31,6 +30,8 @@ #include #include #include +#include +#include #include #include #include From 783272f045faf39325678eef0d55a41d7306e2d3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Mar 2005 02:46:26 +0100 Subject: [PATCH 1213/4284] [PATCH] don't lookup "root" in the userdb --- udev_add.c | 20 +++++++++++++------- udev_utils.c | 4 ++-- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/udev_add.c b/udev_add.c index f47ca25f74..58f4ee1150 100644 --- a/udev_add.c +++ b/udev_add.c @@ -114,8 +114,8 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de char filename[PATH_SIZE]; char partitionname[PATH_SIZE]; struct name_entry *name_loop; - uid_t uid = 0; - gid_t gid = 0; + uid_t uid; + gid_t gid; int tail; int i; @@ -126,24 +126,30 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de if (strchr(udev->name, '/')) create_path(filename); - if (udev->owner[0] != '\0') { + if (strcmp(udev->owner, "root") == 0) + uid = 0; + else { char *endptr; - unsigned long id = strtoul(udev->owner, &endptr, 10); + unsigned long id; + id = strtoul(udev->owner, &endptr, 10); if (endptr[0] == '\0') uid = (uid_t) id; else uid = lookup_user(udev->owner); } - if (udev->group[0] != '\0') { + if (strcmp(udev->group, "root") == 0) + gid = 0; + else { char *endptr; - unsigned long id = strtoul(udev->group, &endptr, 10); + unsigned long id; + id = strtoul(udev->group, &endptr, 10); if (endptr[0] == '\0') gid = (gid_t) id; else - gid = lookup_group(udev->group); + gid = lookup_user(udev->group); } if (!udev->test_run) { diff --git a/udev_utils.c b/udev_utils.c index d572581f65..afa9790fdc 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -85,8 +85,8 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs } udev->mode = 0660; - strcpy(udev->owner, "0"); - strcpy(udev->group, "0"); + strcpy(udev->owner, "root"); + strcpy(udev->group, "root"); return 0; } From 882af735ec18cb4e6ba6f59ca60f8266cc96c330 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Mar 2005 05:15:07 +0100 Subject: [PATCH 1214/4284] [PATCH] remove PLACE key match ID should do the same, cause we walk up the chain of devices on the physical device and can match for the name of every device there with the ID key. --- namedev.c | 36 ------------------------------------ namedev.h | 2 -- namedev_parse.c | 10 ++-------- test/udev-test.pl | 6 +++--- udev.8.in | 5 +---- 5 files changed, 6 insertions(+), 53 deletions(-) diff --git a/namedev.c b/namedev.c index 4b3674935a..cd1f2de989 100644 --- a/namedev.c +++ b/namedev.c @@ -531,28 +531,6 @@ static int match_id(struct config_device *dev, struct sysfs_device *sysfs_device return 0; } -static int match_place(struct config_device *dev, struct sysfs_device *sysfs_device) -{ - char path[PATH_SIZE]; - char *temp; - - strlcpy(path, sysfs_device->path, sizeof(path)); - temp = strrchr(path, '/'); - dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); - if (strstr(temp, dev->place) != NULL) - return 0; - - /* try the parent */ - temp[0] = '\0'; - temp = strrchr(path, '/'); - dbg("search '%s' in '%s', path='%s'", dev->place, temp, path); - if (strstr(temp, dev->place) == NULL) - return 0; - - dbg("place doesn't match"); - return -ENODEV; -} - static int match_rule(struct udevice *udev, struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { @@ -622,20 +600,6 @@ static int match_rule(struct udevice *udev, struct config_device *dev, dbg(FIELD_ID " matches"); } - /* check for matching place of device */ - if (dev->place[0] != '\0') { - if (sysfs_device == NULL) { - dbg("device has no sysfs_device"); - goto try_parent; - } - dbg("check " FIELD_PLACE); - if (match_place(dev, sysfs_device) != 0) { - dbg(FIELD_PLACE " is not matching"); - goto try_parent; - } - dbg(FIELD_PLACE " matches"); - } - /* check for matching sysfs pairs */ if (dev->sysfs_pair[0].file[0] != '\0') { dbg("check " FIELD_SYSFS " pairs"); diff --git a/namedev.h b/namedev.h index 76caaaa9f7..d0235996bc 100644 --- a/namedev.h +++ b/namedev.h @@ -33,7 +33,6 @@ struct sysfs_class_device; #define FIELD_BUS "BUS" #define FIELD_SYSFS "SYSFS" #define FIELD_ID "ID" -#define FIELD_PLACE "PLACE" #define FIELD_PROGRAM "PROGRAM" #define FIELD_RESULT "RESULT" #define FIELD_DRIVER "DRIVER" @@ -64,7 +63,6 @@ struct config_device { char subsystem[NAME_SIZE]; char bus[NAME_SIZE]; char id[NAME_SIZE]; - char place[NAME_SIZE]; struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; char program[PATH_SIZE]; char result[PATH_SIZE]; diff --git a/namedev_parse.c b/namedev_parse.c index b19a5f26f5..3be408932b 100644 --- a/namedev_parse.c +++ b/namedev_parse.c @@ -59,11 +59,11 @@ static int add_config_dev(struct config_device *new_dev) void dump_config_dev(struct config_device *dev) { - dbg_parse("name='%s', symlink='%s', bus='%s', place='%s', id='%s', " + dbg_parse("name='%s', symlink='%s', bus='%s', id='%s', " "sysfs_file[0]='%s', sysfs_value[0]='%s', " "kernel='%s', program='%s', result='%s'" "owner='%s', group='%s', mode=%#o", - dev->name, dev->symlink, dev->bus, dev->place, dev->id, + dev->name, dev->symlink, dev->bus, dev->id, dev->sysfs_pair[0].file, dev->sysfs_pair[0].value, dev->kernel, dev->program, dev->result, dev->owner, dev->group, dev->mode); @@ -196,12 +196,6 @@ static int namedev_parse(struct udevice *udev, const char *filename) continue; } - if (strcasecmp(temp2, FIELD_PLACE) == 0) { - strlcpy(dev.place, temp3, sizeof(dev.place)); - valid = 1; - continue; - } - if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) { struct sysfs_pair *pair = &dev.sysfs_pair[0]; int sysfs_pair_num = 0; diff --git a/test/udev-test.pl b/test/udev-test.pl index 9699f2e8f5..c7e1a9d47e 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -237,7 +237,7 @@ EOF devpath => "/block/sda/sda3", exp_name => "first_disk3" , conf => < "/block/sda/sda3", exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "/block/sda/sda3", exp_name => "M8-m3-n3-b0:0-sIBM" , conf => < Date: Thu, 10 Mar 2005 05:28:41 +0100 Subject: [PATCH 1215/4284] [PATCH] add RELEASE-NOTES file --- RELEASE-NOTES | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 RELEASE-NOTES diff --git a/RELEASE-NOTES b/RELEASE-NOTES new file mode 100644 index 0000000000..870020c430 --- /dev/null +++ b/RELEASE-NOTES @@ -0,0 +1,10 @@ +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, cause +we walk up the chain of physical devices to find a match. + From 08183c4b90505866e806d308213d0a2d293b2659 Mon Sep 17 00:00:00 2001 From: "jkluebs@luebsphoto.com" Date: Thu, 10 Mar 2005 17:34:31 +0100 Subject: [PATCH 1216/4284] [PATCH] This patch causes the remove handler to check that each symlink --- udev_remove.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/udev_remove.c b/udev_remove.c index 1fd36d24c5..c3a7880b49 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -78,13 +78,33 @@ static int delete_node(struct udevice *udev) int i; int num; + list_for_each_entry(name_loop, &udev->symlink_list, node) { + snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); + filename[sizeof(filename)-1] = '\0'; + + if (stat(filename, &stats) != 0) { + dbg("symlink '%s' not found", filename); + continue; + } + if (udev->devt && stats.st_rdev != udev->devt) { + info("symlink '%s' points to a different device, skip removal", filename); + continue;; + } + + dbg("removing symlink '%s'", filename); + unlink(filename); + + if (strchr(filename, '/')) + delete_path(filename); + } + snprintf(filename, sizeof(filename), "%s/%s", udev_root, udev->name); filename[sizeof(filename)-1] = '\0'; - dbg("checking major/minor of device node '%s'", filename); - if (stat(filename, &stats) != 0) + 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; @@ -95,7 +115,6 @@ static int delete_node(struct udevice *udev) if (retval) return retval; - /* remove all_partitions nodes */ num = udev->partitions; if (num > 0) { info("removing all_partitions '%s[1-%i]'", filename, num); @@ -110,28 +129,9 @@ static int delete_node(struct udevice *udev) } } - /* remove subdirectories */ if (strchr(udev->name, '/')) delete_path(filename); - list_for_each_entry(name_loop, &udev->symlink_list, node) { - snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); - filename[sizeof(filename)-1] = '\0'; - - dbg("unlinking symlink '%s'", filename); - retval = unlink(filename); - if (errno == ENOENT) - retval = 0; - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - return retval; - } - if (strchr(filename, '/')) { - delete_path(filename); - } - } - return retval; } From cb948532ff3cb7edf1d2eead7a5cce9e8a1a7a97 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Mar 2005 17:51:43 +0100 Subject: [PATCH 1217/4284] [PATCH] klibc: version 1.0.3 --- klibc/MCONFIG | 6 +++- klibc/Makefile | 5 ++- klibc/include/stddef.h | 2 +- klibc/klcc.in | 76 +++++++++++++++++++++++++++++------------- klibc/makeklcc.pl | 17 +++------- klibc/version | 2 +- 6 files changed, 68 insertions(+), 40 deletions(-) diff --git a/klibc/MCONFIG b/klibc/MCONFIG index 7a24b821ad..1141b78d47 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -29,6 +29,10 @@ OBJROOT = $(SRCROOT) KRNLSRC = $(SRCROOT)/linux KRNLOBJ = $(SRCROOT)/linux +# klibc version information +KLIBCVER = -D__KLIBC__=$(shell cut -d. -f1 < $(SRCROOT)/version) \ + -D__KLIBC_MINOR__=$(shell cut -d. -f2 < $(SRCROOT)/version) + ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) CC = $(CROSS)gcc LD = $(CROSS)ld @@ -38,7 +42,7 @@ INCLUDE = -I$(SRCROOT)/include/arch/$(ARCH) \ -I$(SRCROOT)/include/bits$(BITSIZE) \ -I$(SRCROOT)/include \ -I$(KRNLOBJ)/include -I$(KRNLOBJ)/include2 -I$(KRNLSRC)/include -REQFLAGS = $(ARCHREQFLAGS) -nostdinc -iwithprefix include -D__KLIBC__ \ +REQFLAGS = $(ARCHREQFLAGS) $(KLIBCVER) -nostdinc -iwithprefix include \ $(INCLUDE) LDFLAGS = AR = $(CROSS)ar diff --git a/klibc/Makefile b/klibc/Makefile index a512aa308a..7a9b92e8d6 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -27,7 +27,10 @@ $(CROSS)klibc.config: Makefile echo 'STRIPFLAGS=$(STRIPFLAGS)' >> $@ echo 'EMAIN=$(EMAIN)' >> $@ echo 'BITSIZE=$(BITSIZE)' >> $@ - echo 'INSTALLDIR=$(INSTALLDIR)' >> $@ + echo 'prefix=$(INSTALLDIR)' >> $@ + echo 'bindir=$(INSTALLDIR)/$(KCROSS)bin' >> $@ + echo 'libdir=$(INSTALLDIR)/$(KCROSS)lib' >> $@ + echo 'includedir=$(INSTALLDIR)/$(KCROSS)include' >> $@ $(CROSS)klcc: klcc.in $(CROSS)klibc.config makeklcc.pl $(PERL) makeklcc.pl klcc.in $(CROSS)klibc.config \ diff --git a/klibc/include/stddef.h b/klibc/include/stddef.h index 125d2352ec..e96f28c446 100644 --- a/klibc/include/stddef.h +++ b/klibc/include/stddef.h @@ -6,7 +6,7 @@ #define _STDDEF_H #ifndef __KLIBC__ -# define __KLIBC__ 1 +# error "__KLIBC__ not defined, compiler invocation error!" #endif #include diff --git a/klibc/klcc.in b/klibc/klcc.in index d8721c9a6b..36c4d9b3ee 100644 --- a/klibc/klcc.in +++ b/klibc/klcc.in @@ -1,19 +1,22 @@ # -*- perl -*- # Standard includes -@includes = ("-I${INSTALLDIR}/${KCROSS}include/arch/${ARCH}", - "-I${INSTALLDIR}/${KCROSS}include/bits${BITSIZE}", - "-I${INSTALLDIR}/${KCROSS}include"); +@includes = ("-I${prefix}/${KCROSS}include/arch/${ARCH}", + "-I${prefix}/${KCROSS}include/bits${BITSIZE}", + "-I${prefix}/${KCROSS}include"); # Default optimization options (for compiles without -g) @optopt = @OPTFLAGS; @goptopt = ('-O'); +# Standard library directories +@stdlibpath = ("-L${prefix}/${KCROSS}lib"); + # Options and libraries to pass to ld; shared versus static -@staticopt = ("$INSTALLDIR/${KCROSS}lib/crt0.o"); -@staticlib = ("$INSTALLDIR/${KCROSS}lib/libc.a"); -@sharedopt = (@EMAIN, "$INSTALLDIR/${KCROSS}lib/interp.o"); -@sharedlib = ('-R', "$INSTALLDIR/${KCROSS}lib/libc.so"); +@staticopt = ("${prefix}/${KCROSS}lib/crt0.o"); +@staticlib = ("${prefix}/${KCROSS}lib/libc.a"); +@sharedopt = (@EMAIN, "${prefix}/${KCROSS}lib/interp.o"); +@sharedlib = ('-R', "${prefix}/${KCROSS}lib/libc.so"); # Returns the language (-x option string) for a specific extension. sub filename2lang($) { @@ -51,13 +54,15 @@ sub files_with_lang($$) { foreach $f ( @{$files} ) { $need = ${$flang}{$f}; - $need = 'none' if ( $need eq 'obj' ); - unless ( $xopt eq $need || - ($xopt eq 'none' && filename2lang($f) eq $need) ) { - push(@as, '-x', $need); - $xopt = $need; + + # Skip object files + if ( $need ne 'obj' ) { + unless ( $xopt eq $need ) { + push(@as, '-x', $need); + $xopt = $need; + } + push(@as, $f); } - push(@as, $f); } return @as; @@ -88,6 +93,7 @@ open(NULL, '+<', '/dev/null') or die "$0: cannot open /dev/null\n"; @ccopt = (); @ldopt = (); +@libs = (); @files = (); # List of files %flang = (); # Languages for files @@ -111,13 +117,26 @@ while ( defined($a = shift(@ARGV)) ) { # Not an option. Must be a filename then. push(@files, $a); $flang{$a} = $lang || filename2lang($a); + } elsif ( $a =~ /^-print-klibc-(.*)$/ ) { + # This test must precede -print + if ( defined($conf{$1}) ) { + print ${$conf{$1}}, "\n"; + exit 0; + } else { + die "$0: unknown option: $a\n"; + } + } elsif ( $a =~ /^(-print|-dump|--help|--version)/ ) { + # These share prefixes with some other options, so put this test early! + # Pseudo-operations; just pass to gcc and don't do anything else + push(@ccopt, $a); + $operation = 'c' if ( $operation eq '' ); } elsif ( $a =~ /^-Wl,(.*)$/ ) { # -Wl used to pass options to the linker push(@ldopt, split(/,/, $1)); - } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic)/ ) { + } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic|M[GPD]|MMD)/ ) { # Options to gcc push(@ccopt, $a); - } elsif ( $a =~ /^-([DUI])(.*)$/ ) { + } elsif ( $a =~ /^-([DUI]|M[FQT])(.*)$/ ) { # Options to gcc, which can take either a conjoined argument # (-DFOO) or a disjoint argument (-D FOO) push(@ccopt, $a); @@ -125,10 +144,13 @@ while ( defined($a = shift(@ARGV)) ) { } elsif ( $a eq '-include' ) { # Options to gcc which always take a disjoint argument push(@ccopt, $a, shift(@ARGV)); - } elsif ( $a =~ /^-[gp]/ ) { - # Debugging options to gcc *and* ld + } elsif ( $a eq '-M' || $a eq '-MM' ) { + # gcc options, that force preprocessing mode + push(@ccopt, $a); + $operation = 'E'; + } elsif ( $a =~ /^-[gp]/ || $a eq '-p' ) { + # Debugging options to gcc push(@ccopt, $a); - push(@ldopt, $a); $debugging = 1; } elsif ( $a eq '-v' ) { push(@ccopt, $a); @@ -147,13 +169,15 @@ while ( defined($a = shift(@ARGV)) ) { $strip = 1; } elsif ( $a eq '-o' ) { $output = shift(@ARGV); + } elsif ( $a eq '-x' ) { + $lang = shift(@ARGV); } elsif ( $a eq '-nostdinc' ) { push(@ccopt, $a); @includes = (); - } elsif ( $a =~ /^(-print|--help)/ ) { - # Pseudo-operations; just pass to gcc and don't do anything else - push(@ccopt, $a); - $operation = 'c' if ( $operation eq '' ); + } elsif ( $a =~ /^-([lL])(.*)$/ ) { + # Libraries + push(@libs, $a); + push(@libs, shift(@ARGV)) if ( $2 eq '' ); } else { die "$0: unknown option: $a\n"; } @@ -170,6 +194,10 @@ if ( $operation ne '' ) { @outopt = ('-o', $output) if ( defined($output) ); $rv = mysystem($CC, @ccopt, @outopt, files_with_lang(\@files, \%flang)); } else { + if ( scalar(@files) == 0 ) { + die "$0: No input files!\n"; + } + @outopt = ('-o', $output || 'a.out'); @objs = (); @@ -204,9 +232,9 @@ if ( $operation ne '' ) { close(LIBGCC); if ( $shared ) { - $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @sharedlib, $libgcc); + $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @sharedlib, $libgcc); } else { - $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @staticlib, $libgcc); + $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @staticlib, $libgcc); } unlink(@rmobjs); diff --git a/klibc/makeklcc.pl b/klibc/makeklcc.pl index ea3f8a8256..f8a6294db3 100644 --- a/klibc/makeklcc.pl +++ b/klibc/makeklcc.pl @@ -7,23 +7,16 @@ ($klccin, $klibcconf, $perlpath) = @ARGV; -# This should probably handle quotes and escapes... -sub string2list($) -{ - my($s) = @_; - - $s =~ s/\s+/\',\'/g; - return "(\'".$s."\')"; -} - print "#!${perlpath}\n"; open(KLIBCCONF, '<', $klibcconf) or die "$0: cannot open $klibcconf: $!\n"; while ( defined($l = ) ) { chomp $l; - if ( $l =~ /=/ ) { - print "\$$` = \"\Q$'\E\";\n"; - print "\@$` = ", string2list("$'"), ";\n"; + if ( $l =~ /^([^=]+)\=(.*)$/ ) { + $n = $1; $s = $2; + print "\$$n = \"\Q$s\E\";\n"; + print "\@$n = qw($s);\n"; + print "\$conf{\'\L$n\E\'} = \\\$$n;\n"; } } close(KLIBCCONF); diff --git a/klibc/version b/klibc/version index 136a629e2d..21e8796a09 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -0.214 +1.0.3 From 4d7726399bcaf74105f8f3c27ee37b5dbddc1fee Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 26 Apr 2005 23:52:14 -0700 Subject: [PATCH 1218/4284] selinux merge fixups again... --- udev_add.c | 10 +++++++--- udev_selinux.c | 36 +++++++++++++++++++----------------- udev_selinux.h | 6 ++++-- 3 files changed, 30 insertions(+), 22 deletions(-) diff --git a/udev_add.c b/udev_add.c index 58f4ee1150..42b8d2104c 100644 --- a/udev_add.c +++ b/udev_add.c @@ -83,6 +83,7 @@ create: selinux_setfscreatecon(file, udev->kernel_name, mode); retval = mknod(file, mode, devt); + selinux_resetfscreatecon(); if (retval != 0) { dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", file, mode, major(devt), minor(devt), strerror(errno)); @@ -189,6 +190,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de /* create symlink(s) if requested */ list_for_each_entry(name_loop, &udev->symlink_list, node) { + int retval; char linktarget[PATH_SIZE]; snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); @@ -218,9 +220,11 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de dbg("symlink(%s, %s)", linktarget, filename); if (!udev->test_run) { - selinux_setfscreatecon(filename, udev->kernel_name, S_IFLNK); unlink(filename); - if (symlink(linktarget, filename) != 0) + selinux_setfscreatecon(filename, udev->kernel_name, S_IFLNK); + retval = symlink(linktarget, filename); + selinux_resetfscreatecon(); + if (retval != 0) dbg("symlink(%s, %s) failed with error '%s'", linktarget, filename, strerror(errno)); } @@ -317,7 +321,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) } exit: - selinux_restore(); + selinux_exit(); return retval; } diff --git a/udev_selinux.c b/udev_selinux.c index 72381f0d0d..cc6f4d7d3f 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -105,7 +105,7 @@ void selinux_setfilecon(const char *file, const char *devname, unsigned int mode } if (setfilecon(file, scontext) < 0) - dbg("setfiles %s failed with error '%s'", file, strerror(errno)); + dbg("setfilecon %s failed with error '%s'", file, strerror(errno)); freecon(scontext); } @@ -131,12 +131,20 @@ void selinux_setfscreatecon(const char *file, const char *devname, unsigned int } if (setfscreatecon(scontext) < 0) - dbg("setfiles %s failed with error '%s'", file, strerror(errno)); + dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); freecon(scontext); } } +void selinux_resetfscreatecon(void) +{ + if (is_selinux_running()) { + if (setfscreatecon(prev_scontext) < 0) + dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); + } +} + void selinux_init(void) { /* @@ -144,23 +152,17 @@ void selinux_init(void) * restoration creation purposes. */ if (is_selinux_running()) { - if (getfscreatecon(&prev_scontext) < 0) + if (getfscreatecon(&prev_scontext) < 0) { dbg("getfscreatecon failed\n"); - - prev_scontext = NULL; - } -} - -void selinux_restore(void) -{ - if (is_selinux_running()) { - /* reset the file create context to its former glory */ - if (setfscreatecon(prev_scontext) < 0) - dbg("setfscreatecon failed\n"); - - if (prev_scontext) { - freecon(prev_scontext); prev_scontext = NULL; } } } + +void selinux_exit(void) +{ + if (is_selinux_running() && prev_scontext) { + freecon(prev_scontext); + prev_scontext = NULL; + } +} diff --git a/udev_selinux.h b/udev_selinux.h index 132a9a6550..d9dfeffad0 100644 --- a/udev_selinux.h +++ b/udev_selinux.h @@ -24,15 +24,17 @@ 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_restore(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_restore(void) {} +static inline void selinux_exit(void) {} #endif /* USE_SELINUX */ #endif /* _UDEV_USE_SELINUX */ From 3810823b4410e0bfbaa46e5e63e36a0989ba37f3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 10 Mar 2005 18:35:50 +0100 Subject: [PATCH 1219/4284] [PATCH] udevinfo -d: use '=' as separator, cause ':' may be a part of the devpath --- udevinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevinfo.c b/udevinfo.c index 4d13a5f6dc..930a7be0ae 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -180,7 +180,7 @@ exit: } static int print_dump(const char *devpath, const char *name) { - printf("%s:%s/%s\n", devpath, udev_root, name); + printf("%s=%s/%s\n", devpath, udev_root, name); return 0; } From e296b1476e99150413d92c58e3b5e07e5bda9fd4 Mon Sep 17 00:00:00 2001 From: "tklauser@access.unizh.ch" Date: Fri, 11 Mar 2005 02:19:04 +0100 Subject: [PATCH 1220/4284] [PATCH] The following patch fixes a warning when compiling chassis_id --- extras/chassis_id/table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/chassis_id/table.c b/extras/chassis_id/table.c index 8d14cd1b59..ee64ecc774 100644 --- a/extras/chassis_id/table.c +++ b/extras/chassis_id/table.c @@ -59,7 +59,7 @@ int table_init(void) i = 0; while (!feof(fp)) { fgets(ptr, 80, fp); - sscanf(ptr, "%d %d %d %d %d %s %s", &ptable[i].id, + sscanf(ptr, "%d %d %d %d %s %s", &ptable[i].id, &ptable[i].num_disks, &ptable[i].chassis_num, &ptable[i].slot_num, ptable[i].serial_num, ptable[i].name); From 9066c16adaf90888bc2ffe1a816f3638d58e0bdb Mon Sep 17 00:00:00 2001 From: "tklauser@access.unizh.ch" Date: Fri, 11 Mar 2005 02:31:58 +0100 Subject: [PATCH 1221/4284] [PATCH] The following patch fixes some warnings when compiling volume_id --- extras/volume_id/Makefile | 2 +- extras/volume_id/udev_volume_id.c | 4 ++++ extras/volume_id/volume_id/logging.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 9c274212a6..efec58f80e 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-D_FILE_OFFSET_BITS=64 +override CFLAGS+=-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index 54d95270d0..a00b01a27d 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -21,6 +21,10 @@ * */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + #include #include #include diff --git a/extras/volume_id/volume_id/logging.h b/extras/volume_id/volume_id/logging.h index c81dc57567..ac30264158 100644 --- a/extras/volume_id/volume_id/logging.h +++ b/extras/volume_id/volume_id/logging.h @@ -16,6 +16,6 @@ #endif /* just use the udev version */ -#include "../../logging.h" +#include "../../../logging.h" #endif /* _VOLUME_ID_LOGGING_H_ */ From bc68b28056bfd20c4fcf5030d5c22fd4548dd9fb Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 11 Mar 2005 02:45:26 +0100 Subject: [PATCH 1222/4284] [PATCH] The path to dlist.h is not correct. Pointed out by: Tobias Klauser --- libsysfs/{ => sysfs}/dlist.h | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename libsysfs/{ => sysfs}/dlist.h (100%) diff --git a/libsysfs/dlist.h b/libsysfs/sysfs/dlist.h similarity index 100% rename from libsysfs/dlist.h rename to libsysfs/sysfs/dlist.h From 911847864f1c9183cfca6e7255964d8ee622e943 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 11 Mar 2005 02:49:15 +0100 Subject: [PATCH 1223/4284] [PATCH] remove unneeded include --- udevinfo.c | 1 - 1 file changed, 1 deletion(-) diff --git a/udevinfo.c b/udevinfo.c index 930a7be0ae..ccc3e58e2b 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -27,7 +27,6 @@ #include #include "libsysfs/sysfs/libsysfs.h" -#include "libsysfs/dlist.h" #include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" From 7c492da7f7bb9eb69fdefab0430a0c3ef583d8a3 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 11 Mar 2005 08:02:47 +0100 Subject: [PATCH 1224/4284] [PATCH] volume_id: version 41 --- extras/volume_id/volume_id/iso9660.c | 98 +++++++++++++++----------- extras/volume_id/volume_id/util.c | 58 +++++++++------ extras/volume_id/volume_id/util.h | 1 + extras/volume_id/volume_id/volume_id.h | 2 +- 4 files changed, 95 insertions(+), 64 deletions(-) diff --git a/extras/volume_id/volume_id/iso9660.c b/extras/volume_id/volume_id/iso9660.c index d4ccb9db9c..5d4ab92a79 100644 --- a/extras/volume_id/volume_id/iso9660.c +++ b/extras/volume_id/volume_id/iso9660.c @@ -47,68 +47,86 @@ #define ISO_VD_END 0xff #define ISO_VD_MAX 16 -union iso_super_block { - struct iso_header { - __u8 type; - __u8 id[5]; - __u8 version; - __u8 unused1; - __u8 system_id[32]; - __u8 volume_id[32]; - } __attribute__((__packed__)) iso; - struct hs_header { - __u8 foo[8]; - __u8 type; - __u8 id[4]; - __u8 version; - } __attribute__((__packed__)) hs; +struct iso_volume_descriptor { + __u8 vd_type; + __u8 vd_id[5]; + __u8 vd_version; + __u8 flags; + __u8 system_id[32]; + __u8 volume_id[32]; + __u8 unused[8]; + __u8 space_size[8]; + __u8 escape_sequences[8]; +} __attribute__((__packed__)); + +struct high_sierra_volume_descriptor { + __u8 foo[8]; + __u8 type; + __u8 id[4]; + __u8 version; } __attribute__((__packed__)); int volume_id_probe_iso9660(struct volume_id *id, __u64 off) { - union iso_super_block *is; + __u8 *buf; + struct iso_volume_descriptor *is; + struct high_sierra_volume_descriptor *hs; dbg("probing at offset 0x%llx", (unsigned long long) off); - is = (union iso_super_block *) volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); - if (is == NULL) + buf = volume_id_get_buffer(id, off + ISO_SUPERBLOCK_OFFSET, 0x200); + if (buf == NULL) return -1; - if (memcmp(is->iso.id, "CD001", 5) == 0) { - char root_label[VOLUME_ID_LABEL_SIZE+1]; + is = (struct iso_volume_descriptor *) buf; + + if (memcmp(is->vd_id, "CD001", 5) == 0) { int vd_offset; int i; - int found_svd; - memset(root_label, 0, sizeof(root_label)); - strncpy(root_label, is->iso.volume_id, sizeof(root_label)-1); + 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); - found_svd = 0; + dbg("looking for SVDs"); vd_offset = ISO_VD_OFFSET; for (i = 0; i < ISO_VD_MAX; i++) { - is = (union iso_super_block *) volume_id_get_buffer(id, off + vd_offset, 0x200); - if (is == NULL || is->iso.type == ISO_VD_END) - break; - if (is->iso.type == ISO_VD_SUPPLEMENTARY) { - dbg("found ISO supplementary VD at offset 0x%llx", (unsigned long long) (off + vd_offset)); - volume_id_set_label_raw(id, is->iso.volume_id, 32); - volume_id_set_label_unicode16(id, is->iso.volume_id, BE, 32); - found_svd = 1; + char svd_label[64]; + + is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200); + if (is == NULL || is->vd_type == ISO_VD_END) break; + if (is->vd_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; } - - if (!found_svd || - (found_svd && !memcmp(root_label, id->label, 16))) - { - volume_id_set_label_raw(id, root_label, 32); - volume_id_set_label_string(id, root_label, 32); - } goto found; } - if (memcmp(is->hs.id, "CDROM", 5) == 0) + + 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: diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index 22abc9cbf8..7499fc121e 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -40,6 +40,40 @@ #include "logging.h" #include "util.h" +void volume_id_set_unicode16(char *str, unsigned int len, const __u8 *buf, enum endian endianess, unsigned int count) +{ + unsigned int i, j; + __u16 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++] = (__u8) c; + } else if (c < 0x800) { + if (j+2 >= len) + break; + str[j++] = (__u8) (0xc0 | (c >> 6)); + str[j++] = (__u8) (0x80 | (c & 0x3f)); + } else { + if (j+3 >= len) + break; + str[j++] = (__u8) (0xe0 | (c >> 12)); + str[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); + str[j++] = (__u8) (0x80 | (c & 0x3f)); + } + } + str[j] = '\0'; +} + static char *usage_to_string(enum volume_id_usage usage_id) { switch (usage_id) { @@ -98,29 +132,7 @@ void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned void volume_id_set_label_unicode16(struct volume_id *id, const __u8 *buf, enum endian endianess, unsigned int count) { - unsigned int i, j; - __u16 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) { - id->label[j] = '\0'; - break; - } else if (c < 0x80) { - id->label[j++] = (__u8) c; - } else if (c < 0x800) { - id->label[j++] = (__u8) (0xc0 | (c >> 6)); - id->label[j++] = (__u8) (0x80 | (c & 0x3f)); - } else { - id->label[j++] = (__u8) (0xe0 | (c >> 12)); - id->label[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); - id->label[j++] = (__u8) (0x80 | (c & 0x3f)); - } - } + volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count); } void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format) diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h index 0357b42062..9cea8fc3a0 100644 --- a/extras/volume_id/volume_id/util.h +++ b/extras/volume_id/volume_id/util.h @@ -83,6 +83,7 @@ enum endian { BE = 1 }; +extern void volume_id_set_unicode16(char *str, unsigned int len, const __u8 *buf, enum endian endianess, unsigned int count); extern void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id); extern void volume_id_set_usage_part(struct volume_id_partition *part, enum volume_id_usage usage_id); extern void volume_id_set_label_raw(struct volume_id *id, const __u8 *buf, unsigned int count); diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 8287de28f6..0a273fba55 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 40 +#define VOLUME_ID_VERSION 41 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From afa3c553b1ff0ceb3e038cdf86d9261a8b8aa5d6 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 12 Mar 2005 00:14:38 +0100 Subject: [PATCH 1225/4284] [PATCH] volume_id: version 42 --- extras/volume_id/volume_id/Makefile.inc | 12 +++ extras/volume_id/volume_id/highpoint.c | 55 +++++++++++--- extras/volume_id/volume_id/highpoint.h | 3 +- extras/volume_id/volume_id/isw_raid.c | 79 ++++++++++++++++++++ extras/volume_id/volume_id/isw_raid.h | 26 +++++++ extras/volume_id/volume_id/linux_raid.c | 5 +- extras/volume_id/volume_id/lsi_raid.c | 73 ++++++++++++++++++ extras/volume_id/volume_id/lsi_raid.h | 26 +++++++ extras/volume_id/volume_id/ntfs.c | 2 +- extras/volume_id/volume_id/nvidia_raid.c | 77 +++++++++++++++++++ extras/volume_id/volume_id/nvidia_raid.h | 26 +++++++ extras/volume_id/volume_id/promise_raid.c | 83 +++++++++++++++++++++ extras/volume_id/volume_id/promise_raid.h | 26 +++++++ extras/volume_id/volume_id/silicon_raid.c | 90 +++++++++++++++++++++++ extras/volume_id/volume_id/silicon_raid.h | 26 +++++++ extras/volume_id/volume_id/via_raid.c | 88 ++++++++++++++++++++++ extras/volume_id/volume_id/via_raid.h | 26 +++++++ extras/volume_id/volume_id/volume_id.c | 35 ++++++++- extras/volume_id/volume_id/volume_id.h | 2 +- 19 files changed, 743 insertions(+), 17 deletions(-) create mode 100644 extras/volume_id/volume_id/isw_raid.c create mode 100644 extras/volume_id/volume_id/isw_raid.h create mode 100644 extras/volume_id/volume_id/lsi_raid.c create mode 100644 extras/volume_id/volume_id/lsi_raid.h create mode 100644 extras/volume_id/volume_id/nvidia_raid.c create mode 100644 extras/volume_id/volume_id/nvidia_raid.h create mode 100644 extras/volume_id/volume_id/promise_raid.c create mode 100644 extras/volume_id/volume_id/promise_raid.h create mode 100644 extras/volume_id/volume_id/silicon_raid.c create mode 100644 extras/volume_id/volume_id/silicon_raid.h create mode 100644 extras/volume_id/volume_id/via_raid.c create mode 100644 extras/volume_id/volume_id/via_raid.h diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index 68d80d689c..acd26ff101 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -3,6 +3,12 @@ VOLUME_ID_OBJS= \ $(VOLUME_ID_BASE)/fat.o \ $(VOLUME_ID_BASE)/hfs.o \ $(VOLUME_ID_BASE)/highpoint.o \ + $(VOLUME_ID_BASE)/isw_raid.o \ + $(VOLUME_ID_BASE)/lsi_raid.o \ + $(VOLUME_ID_BASE)/via_raid.o \ + $(VOLUME_ID_BASE)/silicon_raid.o \ + $(VOLUME_ID_BASE)/nvidia_raid.o \ + $(VOLUME_ID_BASE)/promise_raid.o \ $(VOLUME_ID_BASE)/iso9660.o \ $(VOLUME_ID_BASE)/jfs.o \ $(VOLUME_ID_BASE)/linux_raid.o \ @@ -30,6 +36,12 @@ VOLUME_ID_HEADERS= \ $(VOLUME_ID_BASE)/fat.h \ $(VOLUME_ID_BASE)/hfs.h \ $(VOLUME_ID_BASE)/highpoint.h \ + $(VOLUME_ID_BASE)/isw_raid.h \ + $(VOLUME_ID_BASE)/lsi_raid.h \ + $(VOLUME_ID_BASE)/via_raid.h \ + $(VOLUME_ID_BASE)/silicon_raid.h \ + $(VOLUME_ID_BASE)/nvidia_raid.h \ + $(VOLUME_ID_BASE)/promise_raid.h \ $(VOLUME_ID_BASE)/iso9660.h \ $(VOLUME_ID_BASE)/jfs.h \ $(VOLUME_ID_BASE)/linux_raid.h \ diff --git a/extras/volume_id/volume_id/highpoint.c b/extras/volume_id/volume_id/highpoint.c index 72f7d28429..938a8934e5 100644 --- a/extras/volume_id/volume_id/highpoint.c +++ b/extras/volume_id/volume_id/highpoint.c @@ -39,20 +39,28 @@ #include "util.h" #include "highpoint.h" -struct hpt37x { +struct hpt37x_meta { __u8 filler1[32]; __u32 magic; - __u32 magic_0; - __u32 magic_1; -} __attribute__((packed)) *hpt; +} __attribute__((packed)); + +struct hpt45x_meta { + __u32 magic; +} __attribute__((packed)); #define HPT37X_CONFIG_OFF 0x1200 #define HPT37X_MAGIC_OK 0x5a7816f0 #define HPT37X_MAGIC_BAD 0x5a7816fd -int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off) +#define HPT45X_MAGIC_OK 0x5a7816f3 +#define HPT45X_MAGIC_BAD 0x5a7816fd + + +int volume_id_probe_highpoint_37x_raid(struct volume_id *id, __u64 off) { const __u8 *buf; + struct hpt37x_meta *hpt; + __u32 magic; dbg("probing at offset 0x%llx", (unsigned long long) off); @@ -60,13 +68,42 @@ int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off) if (buf == NULL) return -1; - hpt = (struct hpt37x *) buf; - - if (hpt->magic != HPT37X_MAGIC_OK && hpt->magic != HPT37X_MAGIC_BAD) + 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 = "hpt_ataraid_member"; + id->type = "highpoint_raid_member"; + + return 0; +} + +int volume_id_probe_highpoint_45x_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + struct hpt45x_meta *hpt; + __u64 meta_off; + __u32 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/extras/volume_id/volume_id/highpoint.h b/extras/volume_id/volume_id/highpoint.h index 5a5614afef..7cc2ac0cb8 100644 --- a/extras/volume_id/volume_id/highpoint.h +++ b/extras/volume_id/volume_id/highpoint.h @@ -21,6 +21,7 @@ #ifndef _VOLUME_ID_HIGHPOINT_ #define _VOLUME_ID_HIGHPOINT_ -extern int volume_id_probe_highpoint_ataraid(struct volume_id *id, __u64 off); +extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, __u64 off); +extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, __u64 off, __u64 size); #endif diff --git a/extras/volume_id/volume_id/isw_raid.c b/extras/volume_id/volume_id/isw_raid.c new file mode 100644 index 0000000000..c703f3fe27 --- /dev/null +++ b/extras/volume_id/volume_id/isw_raid.c @@ -0,0 +1,79 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "isw_raid.h" + +struct isw_meta { + __u8 sig[32]; + __u32 check_sum; + __u32 mpb_size; + __u32 family_num; + __u32 generation_num; +} __attribute__((packed)); + +#define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " + + +int volume_id_probe_intel_software_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct isw_meta *isw; + + 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)-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); + strncpy(id->type_version, &isw->sig[sizeof(ISW_SIGNATURE)-1], 6); + id->type = "isw_raid_member"; + + return 0; +} diff --git a/extras/volume_id/volume_id/isw_raid.h b/extras/volume_id/volume_id/isw_raid.h new file mode 100644 index 0000000000..4bfd3bb529 --- /dev/null +++ b/extras/volume_id/volume_id/isw_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_ISW_RAID_ +#define _VOLUME_ID_ISW_RAID_ + +extern int volume_id_probe_intel_software_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/linux_raid.c b/extras/volume_id/volume_id/linux_raid.c index e7db4031de..598002ec4f 100644 --- a/extras/volume_id/volume_id/linux_raid.c +++ b/extras/volume_id/volume_id/linux_raid.c @@ -67,7 +67,8 @@ int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) __u64 sboff; __u8 uuid[16]; - dbg("probing at offset 0x%llx", (unsigned long long) off); + dbg("probing at offset 0x%llx, size 0x%llx", + (unsigned long long) off, (unsigned long long) size); if (size < 0x10000) return -1; @@ -86,7 +87,7 @@ int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) memcpy(&uuid[4], &mdp->set_uuid1, 12); volume_id_set_uuid(id, uuid, UUID_DCE); - snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, "%u.%u.%u", + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", le32_to_cpu(mdp->major_version), le32_to_cpu(mdp->minor_version), le32_to_cpu(mdp->patch_version)); diff --git a/extras/volume_id/volume_id/lsi_raid.c b/extras/volume_id/volume_id/lsi_raid.c new file mode 100644 index 0000000000..e411fbc264 --- /dev/null +++ b/extras/volume_id/volume_id/lsi_raid.c @@ -0,0 +1,73 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "lsi_raid.h" + +struct lsi_meta { + __u8 sig[6]; +} __attribute__((packed)); + +#define LSI_SIGNATURE "$XIDE$" + +int volume_id_probe_lsi_mega_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct lsi_meta *lsi; + + 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; + + 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/extras/volume_id/volume_id/lsi_raid.h b/extras/volume_id/volume_id/lsi_raid.h new file mode 100644 index 0000000000..b3ee0bb7fb --- /dev/null +++ b/extras/volume_id/volume_id/lsi_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_LSI_RAID_ +#define _VOLUME_ID_LSI_RAID_ + +extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/ntfs.c b/extras/volume_id/volume_id/ntfs.c index 8f31735a2d..f9df0e9cc3 100644 --- a/extras/volume_id/volume_id/ntfs.c +++ b/extras/volume_id/volume_id/ntfs.c @@ -184,7 +184,7 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { dbg("found info, len %i", val_len); info = (struct volume_info*) (((__u8 *) attr) + val_off); - snprintf(id->type_version, VOLUME_ID_FORMAT_SIZE-1, + snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", info->major_ver, info->minor_ver); } diff --git a/extras/volume_id/volume_id/nvidia_raid.c b/extras/volume_id/volume_id/nvidia_raid.c new file mode 100644 index 0000000000..ad76631799 --- /dev/null +++ b/extras/volume_id/volume_id/nvidia_raid.c @@ -0,0 +1,77 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "nvidia_raid.h" + +struct nvidia_meta { + __u8 vendor[8]; + __u32 size; + __u32 chksum; + __u16 version; +} __attribute__((packed)); + +#define NVIDIA_SIGNATURE "NVIDIA" + +int volume_id_probe_nvidia_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct nvidia_meta *nv; + + 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)-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/extras/volume_id/volume_id/nvidia_raid.h b/extras/volume_id/volume_id/nvidia_raid.h new file mode 100644 index 0000000000..f892be5590 --- /dev/null +++ b/extras/volume_id/volume_id/nvidia_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_NVIDIA_RAID_ +#define _VOLUME_ID_NVIDIA_RAID_ + +extern int volume_id_probe_nvidia_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/promise_raid.c b/extras/volume_id/volume_id/promise_raid.c new file mode 100644 index 0000000000..8fda14945f --- /dev/null +++ b/extras/volume_id/volume_id/promise_raid.c @@ -0,0 +1,83 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "promise_raid.h" + +struct promise_meta { + __u8 sig[24]; +} __attribute__((packed)); + +#define PDC_CONFIG_OFF 0x1200 +#define PDC_SIGNATURE "Promise Technology, Inc." + +int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + struct promise_meta *pdc; + unsigned int i; + static unsigned int sectors[] = { + 63, 255, 256, 16, 399, 0 + }; + + dbg("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++) { + __u64 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/extras/volume_id/volume_id/promise_raid.h b/extras/volume_id/volume_id/promise_raid.h new file mode 100644 index 0000000000..554bcb97d5 --- /dev/null +++ b/extras/volume_id/volume_id/promise_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_PROMISE_RAID_ +#define _VOLUME_ID_PROMISE_RAID_ + +extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/silicon_raid.c b/extras/volume_id/volume_id/silicon_raid.c new file mode 100644 index 0000000000..e528a34ce0 --- /dev/null +++ b/extras/volume_id/volume_id/silicon_raid.c @@ -0,0 +1,90 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "silicon_raid.h" + +struct silicon_meta { + __u8 unknown0[0x2E]; + __u8 ascii_version[0x36 - 0x2E]; + __u8 diskname[0x56 - 0x36]; + __u8 unknown1[0x60 - 0x56]; + __u32 magic; + __u32 unknown1a[0x6C - 0x64]; + __u32 array_sectors_low; + __u32 array_sectors_high; + __u8 unknown2[0x78 - 0x74]; + __u32 thisdisk_sectors; + __u8 unknown3[0x100 - 0x7C]; + __u8 unknown4[0x104 - 0x100]; + __u16 product_id; + __u16 vendor_id; + __u16 minor_ver; + __u16 major_ver; +} __attribute__((packed)); + +#define SILICON_MAGIC 0x2F000000 + +int volume_id_probe_silicon_medley_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 meta_off; + struct silicon_meta *sil; + + 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; + + 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/extras/volume_id/volume_id/silicon_raid.h b/extras/volume_id/volume_id/silicon_raid.h new file mode 100644 index 0000000000..b88e80bb1c --- /dev/null +++ b/extras/volume_id/volume_id/silicon_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_SILICON_RAID_ +#define _VOLUME_ID_SILICON_RAID_ + +extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/via_raid.c b/extras/volume_id/volume_id/via_raid.c new file mode 100644 index 0000000000..393890eb28 --- /dev/null +++ b/extras/volume_id/volume_id/via_raid.c @@ -0,0 +1,88 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "via_raid.h" + +struct via_meta { + __u16 signature; + __u8 version_number; + struct via_array { + __u16 disk_bits; + __u8 disk_array_ex; + __u32 capacity_low; + __u32 capacity_high; + __u32 serial_checksum; + } __attribute((packed)) array; + __u32 serial_checksum[8]; + __u8 checksum; +} __attribute__((packed)); + +#define VIA_SIGNATURE 0xAA55 + +int volume_id_probe_via_raid(struct volume_id *id, __u64 off, __u64 size) +{ + const __u8 *buf; + __u64 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; + + 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/extras/volume_id/volume_id/via_raid.h b/extras/volume_id/volume_id/via_raid.h new file mode 100644 index 0000000000..2d0651c413 --- /dev/null +++ b/extras/volume_id/volume_id/via_raid.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_VIA_RAID_ +#define _VOLUME_ID_VIA_RAID_ + +extern int volume_id_probe_via_raid(struct volume_id *id, __u64 off, __u64 size); + +#endif diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 22d30ee741..3fe8562e33 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -52,6 +52,12 @@ #include "iso9660.h" #include "udf.h" #include "highpoint.h" +#include "isw_raid.h" +#include "lsi_raid.h" +#include "via_raid.h" +#include "silicon_raid.h" +#include "nvidia_raid.h" +#include "promise_raid.h" #include "luks.h" #include "linux_swap.h" #include "linux_raid.h" @@ -70,8 +76,31 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l return -EINVAL; /* probe for raid first, cause fs probes may be successful on raid members */ - if (volume_id_probe_linux_raid(id, off, size) == 0) - goto exit; + if (size) { + if (volume_id_probe_linux_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_intel_software_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_lsi_mega_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_via_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_silicon_medley_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_nvidia_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_promise_fasttrack_raid(id, off, size) == 0) + goto exit; + + if (volume_id_probe_highpoint_45x_raid(id, off, size) == 0) + goto exit; + } if (volume_id_probe_lvm1(id, off) == 0) goto exit; @@ -79,7 +108,7 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_lvm2(id, off) == 0) goto exit; - if (volume_id_probe_highpoint_ataraid(id, off) == 0) + if (volume_id_probe_highpoint_37x_raid(id, off) == 0) goto exit; if (volume_id_probe_luks(id, off) == 0) diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 0a273fba55..63f95132df 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 41 +#define VOLUME_ID_VERSION 42 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 319112e295bbf1ed5d86389190abbe24ce251b14 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 12 Mar 2005 20:55:41 +0100 Subject: [PATCH 1226/4284] [PATCH] remove udevstart on make clean --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9b37402fb9..8e29f24e70 100644 --- a/Makefile +++ b/Makefile @@ -321,7 +321,8 @@ $(STARTER): $(LIBC) $(STARTER).o $(OBJS) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) $(SENDER) $(TESTER) + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) \ + $(SENDER) $(TESTER) $(STARTER) -rm -f ccdv $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ From e6764498e7592f216a1895eacc485448fa4a1660 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 12 Mar 2005 21:41:57 +0100 Subject: [PATCH 1227/4284] [PATCH] correct enum device_type --- namedev.c | 4 ++-- udev.c | 6 +++--- udev.h | 12 ++++++------ udev_add.c | 10 +++++----- udev_remove.c | 2 +- udev_utils.c | 8 ++++---- udevtest.c | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/namedev.c b/namedev.c index cd1f2de989..fd1cf0458a 100644 --- a/namedev.c +++ b/namedev.c @@ -698,7 +698,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg_parse("remove event should be ignored"); } /* apply all_partitions option only at a main block device */ - if (dev->partitions && udev->type == BLOCK && udev->kernel_number[0] == '\0') { + if (dev->partitions && udev->type == DEV_BLOCK && udev->kernel_number[0] == '\0') { udev->partitions = dev->partitions; dbg("creation of partition nodes requested"); } @@ -753,7 +753,7 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d strlcpy(udev->config_file, dev->config_file, sizeof(udev->config_file)); udev->config_line = dev->config_line; - if (udev->type != NET) + if (udev->type != DEV_NET) 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); diff --git a/udev.c b/udev.c index bf2eb373f8..8ce813fbf5 100644 --- a/udev.c +++ b/udev.c @@ -154,13 +154,13 @@ int main(int argc, char *argv[], char *envp[]) if (udev_log) setenv("UDEV_LOG", "1", 1); - if (udev.type == BLOCK || udev.type == CLASS || udev.type == NET) { + if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { if (strcmp(action, "add") == 0) { /* wait for sysfs and possibly add node */ dbg("udev add"); /* skip subsystems without "dev", but handle net devices */ - if (udev.type != NET && subsystem_expect_no_dev(udev.subsystem)) { + if (udev.type != DEV_NET && subsystem_expect_no_dev(udev.subsystem)) { dbg("don't care about '%s' devices", udev.subsystem); goto hotplug; } @@ -203,7 +203,7 @@ int main(int argc, char *argv[], char *envp[]) if (udev_dev_d) udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); } - } else if (udev.type == PHYSDEV) { + } else if (udev.type == DEV_DEVICE) { if (strcmp(action, "add") == 0) { /* wait for sysfs */ dbg("devices add"); diff --git a/udev.h b/udev.h index 7eb07bf125..6e41bb5d26 100644 --- a/udev.h +++ b/udev.h @@ -48,24 +48,24 @@ #define DEFAULT_PARTITIONS_COUNT 15 enum device_type { - UNKNOWN, - CLASS, - BLOCK, - NET, - PHYSDEV, + DEV_UNKNOWN, + DEV_CLASS, + DEV_BLOCK, + DEV_NET, + DEV_DEVICE, }; struct udevice { char devpath[PATH_SIZE]; char subsystem[NAME_SIZE]; + enum device_type type; char name[PATH_SIZE]; char devname[PATH_SIZE]; struct list_head symlink_list; char owner[USER_SIZE]; char group[USER_SIZE]; mode_t mode; - char type; dev_t devt; char tmp_node[PATH_SIZE]; diff --git a/udev_add.c b/udev_add.c index 42b8d2104c..bf5feb1b2d 100644 --- a/udev_add.c +++ b/udev_add.c @@ -70,10 +70,10 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo create: switch (udev->type) { - case BLOCK: + case DEV_BLOCK: mode |= S_IFBLK; break; - case CLASS: + case DEV_CLASS: mode |= S_IFCHR; break; default: @@ -268,7 +268,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) char *pos; int retval = 0; - if (udev->type == BLOCK || udev->type == CLASS) { + if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { udev->devt = get_devt(class_dev); if (!udev->devt) { dbg("no dev-file found, do nothing"); @@ -283,7 +283,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) selinux_init(); - if (udev->type == BLOCK || udev->type == CLASS) { + if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { retval = create_node(udev, class_dev); if (retval != 0) goto exit; @@ -296,7 +296,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); udev->devname[sizeof(udev->devname)-1] = '\0'; - } else if (udev->type == NET) { + } else if (udev->type == DEV_NET) { /* look if we want to change the name of the netif */ if (strcmp(udev->name, udev->kernel_name) != 0) { retval = rename_net_if(udev); diff --git a/udev_remove.c b/udev_remove.c index c3a7880b49..a81d20c98c 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -143,7 +143,7 @@ int udev_remove_device(struct udevice *udev) { const char *temp; - if (udev->type != BLOCK && udev->type != CLASS) + if (udev->type != DEV_BLOCK && udev->type != DEV_CLASS) return 0; if (udev_db_get_device(udev, udev->devpath) == 0) { diff --git a/udev_utils.c b/udev_utils.c index afa9790fdc..b650096593 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -53,13 +53,13 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs no_trailing_slash(udev->devpath); if (strncmp(udev->devpath, "/block/", 7) == 0) - udev->type = BLOCK; + udev->type = DEV_BLOCK; else if (strncmp(udev->devpath, "/class/net/", 11) == 0) - udev->type = NET; + udev->type = DEV_NET; else if (strncmp(udev->devpath, "/class/", 7) == 0) - udev->type = CLASS; + udev->type = DEV_CLASS; else if (strncmp(udev->devpath, "/devices/", 9) == 0) - udev->type = PHYSDEV; + udev->type = DEV_DEVICE; /* get kernel name */ pos = strrchr(udev->devpath, '/'); diff --git a/udevtest.c b/udevtest.c index 5ce2570058..1e0037978b 100644 --- a/udevtest.c +++ b/udevtest.c @@ -92,7 +92,7 @@ int main(int argc, char *argv[], char *envp[]) udev_init_device(&udev, devpath, subsystem); /* skip subsystems without "dev", but handle net devices */ - if (udev.type != NET && subsystem_expect_no_dev(udev.subsystem)) { + if (udev.type != DEV_NET && subsystem_expect_no_dev(udev.subsystem)) { info("don't care about '%s' devices", udev.subsystem); return 2; } From e5e322bc627a07d29a07e08f7c96bd644a3ae057 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 12 Mar 2005 22:36:32 +0100 Subject: [PATCH 1228/4284] [PATCH] rename namedev_dev to udev_rule --- Makefile | 6 +- README | 2 +- logging.h | 10 -- udev.c | 4 +- udev_add.c | 4 +- udev_config.c | 9 +- udev_remove.c | 1 - namedev.c => udev_rules.c | 116 +++++++++++----------- namedev.h => udev_rules.h | 18 ++-- namedev_parse.c => udev_rules_parse.c | 138 +++++++++++++------------- udevstart.c | 4 +- udevtest.c | 4 +- 12 files changed, 149 insertions(+), 167 deletions(-) rename namedev.c => udev_rules.c (85%) rename namedev.h => udev_rules.h (85%) rename namedev_parse.c => udev_rules_parse.c (66%) diff --git a/Makefile b/Makefile index 8e29f24e70..556298a9f1 100644 --- a/Makefile +++ b/Makefile @@ -117,7 +117,7 @@ CFLAGS := -pipe HEADERS = \ udev.h \ udev_utils.h \ - namedev.h \ + udev_rules.h \ udev_version.h \ udev_db.h \ udev_sysfs.h \ @@ -142,8 +142,8 @@ UDEV_OBJS = \ udev_sysfs.o \ udev_db.o \ udev_multiplex.o \ - namedev.o \ - namedev_parse.o \ + udev_rules.o \ + udev_rules_parse.o \ udev_libc_wrapper.o OBJS = \ diff --git a/README b/README index c0475dc904..54cee659a8 100644 --- a/README +++ b/README @@ -65,7 +65,7 @@ To use: This will put the udev binary in /sbin, create the /udev and /etc/udev directories, and place the udev configuration files in /etc/udev. You - will probably want to edit the namedev.* files to create custom naming + will probably want to edit the *.rules files to create custom naming rules. More info on how the config files are set up are contained in comments in the files, and is located in the documentation. diff --git a/logging.h b/logging.h index 3ff54ec974..e7653ee1b8 100644 --- a/logging.h +++ b/logging.h @@ -26,7 +26,6 @@ #define info(format, arg...) do { } while (0) #define dbg(format, arg...) do { } while (0) -#define dbg_parse(format, arg...) do { } while (0) #define logging_init(foo) do { } while (0) #define logging_close(foo) do { } while (0) @@ -49,15 +48,6 @@ } while (0) #endif -/* Parser needs it's own debugging statement, we usually don't care about this at all */ -#ifdef DEBUG_PARSER -#undef dbg_parse -#define dbg_parse(format, arg...) \ - do { \ - log_message(LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ - } while (0) -#endif - extern void log_message(int level, const char *format, ...) __attribute__ ((format (printf, 2, 3))); diff --git a/udev.c b/udev.c index 8ce813fbf5..069cecf973 100644 --- a/udev.c +++ b/udev.c @@ -37,7 +37,7 @@ #include "udev_utils.h" #include "udev_sysfs.h" #include "udev_version.h" -#include "namedev.h" +#include "udev_rules.h" #include "logging.h" @@ -177,7 +177,7 @@ int main(int argc, char *argv[], char *envp[]) wait_for_class_device(class_dev, &error); /* init rules */ - namedev_init(); + udev_rules_init(); /* name, create node, store in db */ retval = udev_add_device(&udev, class_dev); diff --git a/udev_add.c b/udev_add.c index bf5feb1b2d..8443f65e7c 100644 --- a/udev_add.c +++ b/udev_add.c @@ -42,7 +42,7 @@ #include "udev_sysfs.h" #include "udev_version.h" #include "logging.h" -#include "namedev.h" +#include "udev_rules.h" #include "udev_db.h" #include "udev_selinux.h" @@ -276,7 +276,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) } } - if (namedev_name_device(udev, class_dev) != 0) + if (udev_rules_get_name(udev, class_dev) != 0) return 0; dbg("adding name='%s'", udev->name); diff --git a/udev_config.c b/udev_config.c index 26ecf6291c..77ac38a791 100644 --- a/udev_config.c +++ b/udev_config.c @@ -21,9 +21,6 @@ * */ -/* define this to enable parsing debugging */ -/* #define DEBUG_PARSER */ - #include #include #include @@ -38,7 +35,7 @@ #include "udev_utils.h" #include "udev_version.h" #include "logging.h" -#include "namedev.h" +#include "udev_rules.h" /* global variables */ char sysfs_path[PATH_SIZE]; @@ -134,14 +131,14 @@ static int parse_config_file(void) strlcpy(line, bufline, count); temp = line; - dbg_parse("read '%s'", temp); + dbg("read '%s'", temp); retval = parse_get_pair(&temp, &variable, &value); if (retval != 0) info("%s:%d:%Zd: error parsing '%s'", udev_config_filename, lineno, temp-line, temp); - dbg_parse("variable='%s', value='%s'", variable, value); + dbg("variable='%s', value='%s'", variable, value); if (strcasecmp(variable, "udev_root") == 0) { strlcpy(udev_root, value, sizeof(udev_root)); diff --git a/udev_remove.c b/udev_remove.c index a81d20c98c..0a9996dc6a 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -34,7 +34,6 @@ #include "udev.h" #include "udev_utils.h" #include "udev_version.h" -#include "namedev.h" #include "udev_db.h" #include "logging.h" diff --git a/namedev.c b/udev_rules.c similarity index 85% rename from namedev.c rename to udev_rules.c index fd1cf0458a..cbdf7de317 100644 --- a/namedev.c +++ b/udev_rules.c @@ -1,5 +1,5 @@ /* - * namedev.c + * udev_rules.c * * Userspace devfs * @@ -40,7 +40,7 @@ #include "udev_utils.h" #include "udev_version.h" #include "logging.h" -#include "namedev.h" +#include "udev_rules.h" #include "udev_db.h" static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr); @@ -498,13 +498,13 @@ static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct return 0; } -static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) +static int match_sysfs_pairs(struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { struct sysfs_pair *pair; int i; for (i = 0; i < MAX_SYSFS_PAIRS; ++i) { - pair = &dev->sysfs_pair[i]; + pair = &rule->sysfs_pair[i]; if ((pair->file[0] == '\0') || (pair->value[0] == '\0')) break; if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) { @@ -516,7 +516,7 @@ static int match_sysfs_pairs(struct config_device *dev, struct sysfs_class_devic return 0; } -static int match_id(struct config_device *dev, struct sysfs_device *sysfs_device) +static int match_id(struct udev_rule *rule, struct sysfs_device *sysfs_device) { char path[PATH_SIZE]; char *temp; @@ -524,30 +524,30 @@ static int match_id(struct config_device *dev, struct sysfs_device *sysfs_device strlcpy(path, sysfs_device->path, sizeof(path)); temp = strrchr(path, '/'); temp++; - dbg("search '%s' in '%s', path='%s'", dev->id, temp, path); - if (strcmp_pattern(dev->id, temp) != 0) + dbg("search '%s' in '%s', path='%s'", rule->id, temp, path); + if (strcmp_pattern(rule->id, temp) != 0) return -ENODEV; return 0; } -static int match_rule(struct udevice *udev, struct config_device *dev, +static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - if (dev->kernel[0] != '\0') { - dbg("check for " FIELD_KERNEL " dev->kernel='%s' class_dev->name='%s'", - dev->kernel, class_dev->name); - if (strcmp_pattern(dev->kernel, class_dev->name) != 0) { + if (rule->kernel[0] != '\0') { + dbg("check for " FIELD_KERNEL " rule->kernel='%s' class_dev->name='%s'", + rule->kernel, class_dev->name); + if (strcmp_pattern(rule->kernel, class_dev->name) != 0) { dbg(FIELD_KERNEL " is not matching"); goto exit; } dbg(FIELD_KERNEL " matches"); } - if (dev->subsystem[0] != '\0') { - dbg("check for " FIELD_SUBSYSTEM " dev->subsystem='%s' class_dev->name='%s'", - dev->subsystem, class_dev->name); - if (strcmp_pattern(dev->subsystem, udev->subsystem) != 0) { + if (rule->subsystem[0] != '\0') { + dbg("check for " FIELD_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'", + rule->subsystem, class_dev->name); + if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { dbg(FIELD_SUBSYSTEM " is not matching"); goto exit; } @@ -557,14 +557,14 @@ static int match_rule(struct udevice *udev, struct config_device *dev, /* walk up the chain of physical devices and find a match */ while (1) { /* check for matching driver */ - if (dev->driver[0] != '\0') { + if (rule->driver[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no sysfs_device"); goto try_parent; } - dbg("check for " FIELD_DRIVER " dev->driver='%s' sysfs_device->driver_name='%s'", - dev->driver, sysfs_device->driver_name); - if (strcmp_pattern(dev->driver, sysfs_device->driver_name) != 0) { + dbg("check for " FIELD_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'", + rule->driver, sysfs_device->driver_name); + if (strcmp_pattern(rule->driver, sysfs_device->driver_name) != 0) { dbg(FIELD_DRIVER " is not matching"); goto try_parent; } @@ -572,14 +572,14 @@ static int match_rule(struct udevice *udev, struct config_device *dev, } /* check for matching bus value */ - if (dev->bus[0] != '\0') { + if (rule->bus[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no sysfs_device"); goto try_parent; } - dbg("check for " FIELD_BUS " dev->bus='%s' sysfs_device->bus='%s'", - dev->bus, sysfs_device->bus); - if (strcmp_pattern(dev->bus, sysfs_device->bus) != 0) { + dbg("check for " FIELD_BUS " rule->bus='%s' sysfs_device->bus='%s'", + rule->bus, sysfs_device->bus); + if (strcmp_pattern(rule->bus, sysfs_device->bus) != 0) { dbg(FIELD_BUS " is not matching"); goto try_parent; } @@ -587,13 +587,13 @@ static int match_rule(struct udevice *udev, struct config_device *dev, } /* check for matching bus id */ - if (dev->id[0] != '\0') { + if (rule->id[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no sysfs_device"); goto try_parent; } dbg("check " FIELD_ID); - if (match_id(dev, sysfs_device) != 0) { + if (match_id(rule, sysfs_device) != 0) { dbg(FIELD_ID " is not matching"); goto try_parent; } @@ -601,9 +601,9 @@ static int match_rule(struct udevice *udev, struct config_device *dev, } /* check for matching sysfs pairs */ - if (dev->sysfs_pair[0].file[0] != '\0') { + if (rule->sysfs_pair[0].file[0] != '\0') { dbg("check " FIELD_SYSFS " pairs"); - if (match_sysfs_pairs(dev, class_dev, sysfs_device) != 0) { + if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) { dbg(FIELD_SYSFS " is not matching"); goto try_parent; } @@ -622,11 +622,11 @@ try_parent: } /* execute external program */ - if (dev->program[0] != '\0') { + if (rule->program[0] != '\0') { char program[PATH_SIZE]; dbg("check " FIELD_PROGRAM); - strlcpy(program, dev->program, sizeof(program)); + strlcpy(program, rule->program, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); if (execute_program(udev, program, udev->program_result, sizeof(udev->program_result)) != 0) { dbg(FIELD_PROGRAM " returned nonzero"); @@ -636,10 +636,10 @@ try_parent: } /* check for matching result of external program */ - if (dev->result[0] != '\0') { - dbg("check for " FIELD_RESULT " dev->result='%s', udev->program_result='%s'", - dev->result, udev->program_result); - if (strcmp_pattern(dev->result, udev->program_result) != 0) { + if (rule->result[0] != '\0') { + dbg("check for " FIELD_RESULT "rule->result='%s', udev->program_result='%s'", + rule->result, udev->program_result); + if (strcmp_pattern(rule->result, udev->program_result) != 0) { dbg(FIELD_RESULT " is not matching"); goto try_parent; } @@ -653,11 +653,11 @@ exit: return -1; } -int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev) +int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev) { struct sysfs_class_device *class_dev_parent; struct sysfs_device *sysfs_device = NULL; - struct config_device *dev; + struct udev_rule *rule; dbg("class_dev->name='%s'", class_dev->name); @@ -683,50 +683,50 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d dbg("udev->kernel_name='%s'", udev->kernel_name); /* look for a matching rule to apply */ - list_for_each_entry(dev, &config_device_list, node) { + list_for_each_entry(rule, &udev_rule_list, node) { dbg("process rule"); - if (match_rule(udev, dev, class_dev, sysfs_device) == 0) { + if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { /* apply options */ - if (dev->ignore_device) { + if (rule->ignore_device) { info("configured rule in '%s[%i]' applied, '%s' is ignored", - dev->config_file, dev->config_line, udev->kernel_name); + rule->config_file, rule->config_line, udev->kernel_name); return -1; } - if (dev->ignore_remove) { + if (rule->ignore_remove) { udev->ignore_remove = 1; - dbg_parse("remove event should be ignored"); + dbg("remove event should be ignored"); } /* apply all_partitions option only at a main block device */ - if (dev->partitions && udev->type == DEV_BLOCK && udev->kernel_number[0] == '\0') { - udev->partitions = dev->partitions; + if (rule->partitions && udev->type == DEV_BLOCK && udev->kernel_number[0] == '\0') { + udev->partitions = rule->partitions; dbg("creation of partition nodes requested"); } /* apply permissions */ - if (dev->mode != 0000) { - udev->mode = dev->mode; + if (rule->mode != 0000) { + udev->mode = rule->mode; dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name); } - if (dev->owner[0] != '\0') { - strlcpy(udev->owner, dev->owner, sizeof(udev->owner)); + if (rule->owner[0] != '\0') { + strlcpy(udev->owner, rule->owner, sizeof(udev->owner)); apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); } - if (dev->group[0] != '\0') { - strlcpy(udev->group, dev->group, sizeof(udev->group)); + if (rule->group[0] != '\0') { + strlcpy(udev->group, rule->group, sizeof(udev->group)); apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); } /* collect symlinks */ - if (dev->symlink[0] != '\0') { + if (rule->symlink[0] != '\0') { char temp[PATH_SIZE]; char *pos, *next; info("configured rule in '%s[%i]' applied, added symlink '%s'", - dev->config_file, dev->config_line, dev->symlink); - strlcpy(temp, dev->symlink, sizeof(temp)); + rule->config_file, rule->config_line, rule->symlink); + strlcpy(temp, rule->symlink, sizeof(temp)); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); /* add multiple symlinks separated by spaces */ @@ -744,14 +744,14 @@ int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_d } /* rule matches */ - if (dev->name[0] != '\0') { + if (rule->name[0] != '\0') { info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", - dev->config_file, dev->config_line, udev->kernel_name, dev->name); + rule->config_file, rule->config_line, udev->kernel_name, rule->name); - strlcpy(udev->name, dev->name, sizeof(udev->name)); + strlcpy(udev->name, rule->name, sizeof(udev->name)); apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - strlcpy(udev->config_file, dev->config_file, sizeof(udev->config_file)); - udev->config_line = dev->config_line; + strlcpy(udev->config_file, rule->config_file, sizeof(udev->config_file)); + udev->config_line = rule->config_line; if (udev->type != DEV_NET) dbg("name, '%s' is going to have owner='%s', group='%s', mode=%#o partitions=%i", diff --git a/namedev.h b/udev_rules.h similarity index 85% rename from namedev.h rename to udev_rules.h index d0235996bc..71c510bce5 100644 --- a/namedev.h +++ b/udev_rules.h @@ -1,5 +1,5 @@ /* - * namedev.h + * udev_rules.h * * Userspace devfs * @@ -23,10 +23,10 @@ #ifndef NAMEDEV_H #define NAMEDEV_H +#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "list.h" -struct sysfs_class_device; #define FIELD_KERNEL "KERNEL" #define FIELD_SUBSYSTEM "SUBSYSTEM" @@ -56,7 +56,7 @@ struct sysfs_pair { char value[VALUE_SIZE]; }; -struct config_device { +struct udev_rule { struct list_head node; char kernel[NAME_SIZE]; @@ -82,13 +82,13 @@ struct config_device { int config_line; }; -extern struct list_head config_device_list; +extern struct list_head udev_rule_list; -extern int namedev_init(void); -extern int namedev_name_device(struct udevice *udev, struct sysfs_class_device *class_dev); -extern void namedev_close(void); +extern int udev_rules_init(void); +extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev); +extern void udev_rules_close(void); -extern void dump_config_dev(struct config_device *dev); -extern void dump_config_dev_list(void); +extern void udev_rule_dump(struct udev_rule *rule); +extern void udev_rule_list_dump(void); #endif diff --git a/namedev_parse.c b/udev_rules_parse.c similarity index 66% rename from namedev_parse.c rename to udev_rules_parse.c index 3be408932b..4f431decf5 100644 --- a/namedev_parse.c +++ b/udev_rules_parse.c @@ -1,5 +1,5 @@ /* - * namedev_parse.c + * udev_rules_parse.c * * Userspace devfs * @@ -22,11 +22,6 @@ * */ -#ifdef DEBUG -/* define this to enable parsing debugging also */ -/* #define DEBUG_PARSER */ -#endif - #include #include #include @@ -40,41 +35,42 @@ #include "udev.h" #include "udev_utils.h" #include "logging.h" -#include "namedev.h" +#include "udev_rules.h" -LIST_HEAD(config_device_list); +LIST_HEAD(udev_rule_list); -static int add_config_dev(struct config_device *new_dev) +static int add_config_dev(struct udev_rule *new_rule) { - struct config_device *tmp_dev; + struct udev_rule *tmp_rule; - tmp_dev = malloc(sizeof(*tmp_dev)); - if (tmp_dev == NULL) + tmp_rule = malloc(sizeof(*tmp_rule)); + if (tmp_rule == NULL) return -ENOMEM; - memcpy(tmp_dev, new_dev, sizeof(*tmp_dev)); - list_add_tail(&tmp_dev->node, &config_device_list); - //dump_config_dev(tmp_dev); + memcpy(tmp_rule, new_rule, sizeof(*tmp_rule)); + list_add_tail(&tmp_rule->node, &udev_rule_list); + udev_rule_dump(tmp_rule); + return 0; } -void dump_config_dev(struct config_device *dev) +void udev_rule_dump(struct udev_rule *rule) { - dbg_parse("name='%s', symlink='%s', bus='%s', id='%s', " - "sysfs_file[0]='%s', sysfs_value[0]='%s', " - "kernel='%s', program='%s', result='%s'" - "owner='%s', group='%s', mode=%#o", - dev->name, dev->symlink, dev->bus, dev->id, - dev->sysfs_pair[0].file, dev->sysfs_pair[0].value, - dev->kernel, dev->program, dev->result, - dev->owner, dev->group, dev->mode); + dbg("name='%s', symlink='%s', bus='%s', id='%s', " + "sysfs_file[0]='%s', sysfs_value[0]='%s', " + "kernel='%s', program='%s', result='%s'" + "owner='%s', group='%s', mode=%#o", + rule->name, rule->symlink, rule->bus, rule->id, + rule->sysfs_pair[0].file, rule->sysfs_pair[0].value, + rule->kernel, rule->program, rule->result, + rule->owner, rule->group, rule->mode); } -void dump_config_dev_list(void) +void udev_rule_list_dump(void) { - struct config_device *dev; + struct udev_rule *rule; - list_for_each_entry(dev, &config_device_list, node) - dump_config_dev(dev); + list_for_each_entry(rule, &udev_rule_list, node) + udev_rule_dump(rule); } /* extract possible KEY{attr} */ @@ -99,7 +95,7 @@ static char *get_key_attribute(char *str) return NULL; } -static int namedev_parse(struct udevice *udev, const char *filename) +static int rules_parse(struct udevice *udev, const char *filename) { char line[LINE_SIZE]; char *bufline; @@ -115,7 +111,7 @@ static int namedev_parse(struct udevice *udev, const char *filename) int program_given = 0; int valid; int retval = 0; - struct config_device dev; + struct udev_rule rule; if (file_map(filename, &buf, &bufsize) == 0) { dbg("reading '%s' as rules file", filename); @@ -160,10 +156,10 @@ static int namedev_parse(struct udevice *udev, const char *filename) line[j++] = bufline[i]; } line[j] = '\0'; - dbg_parse("read '%s'", line); + dbg("read '%s'", line); /* get all known keys */ - memset(&dev, 0x00, sizeof(struct config_device)); + memset(&rule, 0x00, sizeof(struct udev_rule)); temp = line; valid = 0; @@ -173,31 +169,31 @@ static int namedev_parse(struct udevice *udev, const char *filename) break; if (strcasecmp(temp2, FIELD_KERNEL) == 0) { - strlcpy(dev.kernel, temp3, sizeof(dev.kernel)); + strlcpy(rule.kernel, temp3, sizeof(rule.kernel)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_SUBSYSTEM) == 0) { - strlcpy(dev.subsystem, temp3, sizeof(dev.subsystem)); + strlcpy(rule.subsystem, temp3, sizeof(rule.subsystem)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_BUS) == 0) { - strlcpy(dev.bus, temp3, sizeof(dev.bus)); + strlcpy(rule.bus, temp3, sizeof(rule.bus)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_ID) == 0) { - strlcpy(dev.id, temp3, sizeof(dev.id)); + strlcpy(rule.id, temp3, sizeof(rule.id)); valid = 1; continue; } if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) { - struct sysfs_pair *pair = &dev.sysfs_pair[0]; + struct sysfs_pair *pair = &rule.sysfs_pair[0]; int sysfs_pair_num = 0; /* find first unused pair */ @@ -223,20 +219,20 @@ static int namedev_parse(struct udevice *udev, const char *filename) } if (strcasecmp(temp2, FIELD_DRIVER) == 0) { - strlcpy(dev.driver, temp3, sizeof(dev.driver)); + strlcpy(rule.driver, temp3, sizeof(rule.driver)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { program_given = 1; - strlcpy(dev.program, temp3, sizeof(dev.program)); + strlcpy(rule.program, temp3, sizeof(rule.program)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_RESULT) == 0) { - strlcpy(dev.result, temp3, sizeof(dev.result)); + strlcpy(rule.result, temp3, sizeof(rule.result)); valid = 1; continue; } @@ -246,58 +242,58 @@ static int namedev_parse(struct udevice *udev, const char *filename) /* FIXME: remove old style options and make OPTIONS= mandatory */ if (attr != NULL) { if (strstr(attr, OPTION_PARTITIONS) != NULL) { - dbg_parse("creation of partition nodes requested"); - dev.partitions = DEFAULT_PARTITIONS_COUNT; + dbg("creation of partition nodes requested"); + rule.partitions = DEFAULT_PARTITIONS_COUNT; } if (strstr(attr, OPTION_IGNORE_REMOVE) != NULL) { - dbg_parse("remove event should be ignored"); - dev.ignore_remove = 1; + dbg("remove event should be ignored"); + rule.ignore_remove = 1; } } if (temp3[0] != '\0') - strlcpy(dev.name, temp3, sizeof(dev.name)); + strlcpy(rule.name, temp3, sizeof(rule.name)); else - dev.ignore_device = 1; + rule.ignore_device = 1; valid = 1; continue; } if (strcasecmp(temp2, FIELD_SYMLINK) == 0) { - strlcpy(dev.symlink, temp3, sizeof(dev.symlink)); + strlcpy(rule.symlink, temp3, sizeof(rule.symlink)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_OWNER) == 0) { - strlcpy(dev.owner, temp3, sizeof(dev.owner)); + strlcpy(rule.owner, temp3, sizeof(rule.owner)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_GROUP) == 0) { - strlcpy(dev.group, temp3, sizeof(dev.group)); + strlcpy(rule.group, temp3, sizeof(rule.group)); valid = 1; continue; } if (strcasecmp(temp2, FIELD_MODE) == 0) { - dev.mode = strtol(temp3, NULL, 8); + rule.mode = strtol(temp3, NULL, 8); valid = 1; continue; } if (strcasecmp(temp2, FIELD_OPTIONS) == 0) { if (strstr(temp3, OPTION_IGNORE_DEVICE) != NULL) { - dbg_parse("device should be ignored"); - dev.ignore_device = 1; + dbg("device should be ignored"); + rule.ignore_device = 1; } if (strstr(temp3, OPTION_IGNORE_REMOVE) != NULL) { - dbg_parse("remove event should be ignored"); - dev.ignore_remove = 1; + dbg("remove event should be ignored"); + rule.ignore_remove = 1; } if (strstr(temp3, OPTION_PARTITIONS) != NULL) { - dbg_parse("creation of partition nodes requested"); - dev.partitions = DEFAULT_PARTITIONS_COUNT; + dbg("creation of partition nodes requested"); + rule.partitions = DEFAULT_PARTITIONS_COUNT; } valid = 1; continue; @@ -312,21 +308,21 @@ static int namedev_parse(struct udevice *udev, const char *filename) goto error; /* simple plausibility checks for given keys */ - if ((dev.sysfs_pair[0].file[0] == '\0') ^ - (dev.sysfs_pair[0].value[0] == '\0')) { + if ((rule.sysfs_pair[0].file[0] == '\0') ^ + (rule.sysfs_pair[0].value[0] == '\0')) { info("inconsistency in " FIELD_SYSFS " key"); goto error; } - if ((dev.result[0] != '\0') && (program_given == 0)) { + if ((rule.result[0] != '\0') && (program_given == 0)) { info(FIELD_RESULT " is only useful when " FIELD_PROGRAM " is called in any rule before"); goto error; } - dev.config_line = lineno; - strlcpy(dev.config_file, filename, sizeof(dev.config_file)); - retval = add_config_dev(&dev); + rule.config_line = lineno; + strlcpy(rule.config_file, filename, sizeof(rule.config_file)); + retval = add_config_dev(&rule); if (retval) { dbg("add_config_dev returned with error %d", retval); continue; @@ -340,7 +336,7 @@ error: return retval; } -int namedev_init(void) +int udev_rules_init(void) { struct stat stats; int retval; @@ -349,21 +345,21 @@ int namedev_init(void) return -1; if ((stats.st_mode & S_IFMT) != S_IFDIR) - retval = namedev_parse(NULL, udev_rules_filename); + retval = rules_parse(NULL, udev_rules_filename); else - retval = call_foreach_file(namedev_parse, NULL, udev_rules_filename, RULEFILE_SUFFIX); + retval = call_foreach_file(rules_parse, NULL, udev_rules_filename, RULEFILE_SUFFIX); return retval; } -void namedev_close(void) +void udev_rules_close(void) { - struct config_device *dev; - struct config_device *temp_dev; + struct udev_rule *rule; + struct udev_rule *temp_rule; - list_for_each_entry_safe(dev, temp_dev, &config_device_list, node) { - list_del(&dev->node); - free(dev); + list_for_each_entry_safe(rule, temp_rule, &udev_rule_list, node) { + list_del(&rule->node); + free(rule); } } diff --git a/udevstart.c b/udevstart.c index 7564c3de03..7765661fe4 100644 --- a/udevstart.c +++ b/udevstart.c @@ -39,7 +39,7 @@ #include "udev_libc_wrapper.h" #include "udev.h" #include "logging.h" -#include "namedev.h" +#include "udev_rules.h" #include "udev_utils.h" #include "list.h" @@ -317,7 +317,7 @@ int main(int argc, char *argv[], char *envp[]) setenv("ACTION", "add", 1); setenv("UDEV_START", "1", 1); - namedev_init(); + udev_rules_init(); udev_scan_block(); udev_scan_class(); diff --git a/udevtest.c b/udevtest.c index 1e0037978b..006d55510e 100644 --- a/udevtest.c +++ b/udevtest.c @@ -32,7 +32,7 @@ #include "udev_sysfs.h" #include "udev_utils.h" #include "udev_version.h" -#include "namedev.h" +#include "udev_rules.h" #include "logging.h" @@ -83,7 +83,7 @@ int main(int argc, char *argv[], char *envp[]) info("looking at '%s'", devpath); /* initialize the naming deamon */ - namedev_init(); + udev_rules_init(); if (argc == 3) subsystem = argv[2]; From 3b6ed8bb06d18a2855d530dcb9034e9d37114827 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 12 Mar 2005 22:55:08 +0100 Subject: [PATCH 1229/4284] [PATCH] add OPTION="last_rule" to skip any later rule --- test/udev-test.pl | 11 ++++++++++- udev_rules.c | 6 ++++++ udev_rules.h | 4 +++- udev_rules_parse.c | 4 ++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index c7e1a9d47e..52c5c8d481 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1115,9 +1115,18 @@ EOF subsys => "block", devpath => "/block/sda/sda1", exp_name => "start-udev-root-end", - option => "clean", conf => < "last_rule option", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "last", + conf => <last_rule) { + dbg("last rule to be applied"); + break; + } + } } diff --git a/udev_rules.h b/udev_rules.h index 71c510bce5..42552cfa41 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -43,6 +43,7 @@ #define FIELD_MODE "MODE" #define FIELD_OPTIONS "OPTIONS" +#define OPTION_LAST_RULE "last_rule" #define OPTION_IGNORE_DEVICE "ignore_device" #define OPTION_IGNORE_REMOVE "ignore_remove" #define OPTION_PARTITIONS "all_partitions" @@ -74,9 +75,10 @@ struct udev_rule { char group[USER_SIZE]; mode_t mode; - int partitions; + int last_rule; int ignore_device; int ignore_remove; + int partitions; char config_file[PATH_SIZE]; int config_line; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 4f431decf5..f77f3db915 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -283,6 +283,10 @@ static int rules_parse(struct udevice *udev, const char *filename) } if (strcasecmp(temp2, FIELD_OPTIONS) == 0) { + if (strstr(temp3, OPTION_LAST_RULE) != NULL) { + dbg("last rule to be applied"); + rule.last_rule = 1; + } if (strstr(temp3, OPTION_IGNORE_DEVICE) != NULL) { dbg("device should be ignored"); rule.ignore_device = 1; From 28ce66de1750320d7f09547d8910d42ae580fe5e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 13 Mar 2005 05:46:31 +0100 Subject: [PATCH 1230/4284] [PATCH] support =, ==, !=, += for the key match and assignment --- RELEASE-NOTES | 10 ++ test/udev-test.pl | 354 ++++++++++++++++++++++++--------------------- udev.8.in | 42 +++--- udev_config.c | 80 +++++++--- udev_rules.c | 108 +++++++++----- udev_rules.h | 52 ++++--- udev_rules_parse.c | 197 ++++++++++++++++++------- udev_utils.c | 35 ----- 8 files changed, 541 insertions(+), 337 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 870020c430..ee77d845be 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -8,3 +8,13 @@ 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, cause we walk up the chain of physical devices to find a match. +The KEY="" format supports '=', '==', '!=,' , '+=' now. This makes it +easier to skip certain devices without composing rules with weird character +class negations like: + KERNEL="[!s][!c][!d]*" + +this can be replaced by: + KERNEL!="scd*" + +The simple '=' is still supported, but the rules should be converted if +possible, to be better human-readable. diff --git a/test/udev-test.pl b/test/udev-test.pl index 52c5c8d481..8d66536b94 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -39,8 +39,8 @@ my @tests = ( devpath => "/block/sda", exp_name => "boot_disk" , conf => < "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "/block/sda/sda1", exp_name => "boot_disk1" , conf => < "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "/class/tty/ttyUSB0", exp_name => "visor/0" , conf => < "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "visor" , conf => < "visor" , conf => < "visor" , conf => < "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "/class/tty/ttyUSB0", exp_name => "aaa", conf => < "/class/tty/ttyUSB0", exp_name => "sub/direct/ory/visor" , conf => < "/block/sda/sda3", exp_name => "first_disk3" , conf => < "/block/sda/sda3", exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , conf => < "/block/sda/sda3", exp_name => "M8-m3-n3-b0:0-sIBM" , conf => < "/block/sda", exp_name => "good" , conf => < "/block/sda", exp_name => "disk-IBM-ESXS-sda" , conf => < "/block/sda/sda3", exp_name => "special-device-3" , conf => < "/block/sda/sda3", exp_name => "subsys_block" , conf => < "/block/sda/sda3", exp_name => "newline_removed" , conf => < "/block/sda/sda3", exp_name => "test-0:0:0:0" , conf => < "/block/sda/sda3", exp_name => "escape-3" , conf => < "/block/sda/sda3", exp_name => "foo9" , conf => < "/block/sda/sda3", exp_name => "bar9" , conf => < "/block/sda/sda3", exp_name => "foo7" , conf => < "/block/sda/sda3", exp_name => "my-foo9" , conf => < "/block/sda/sda3", exp_name => "my-foo8" , conf => < "/class/tty/console", exp_name => "TTY" , conf => < "/class/tty/console", exp_name => "foo" , conf => < "/class/tty/console", exp_name => "TTY" , conf => < "/class/tty/console", exp_name => "foo" , conf => < "/block/sda", exp_name => "scsi-0:0:0:0" , conf => < "/block/sda", exp_name => "boot_disk15" , conf => < "/class/tty/ttyUSB0", exp_name => "visor" , conf => < "/block/rd!c0d0", exp_name => "rd/c0d0" , conf => < "/block/rd!c0d0", exp_name => "rd/c0d0" , conf => < "/block/cciss!c0d0/cciss!c0d0p1", exp_name => "cciss/c0d0p1" , conf => < "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "/block/sda", exp_name => "scsi-0:0:0:0", conf => < "/block/sda", exp_name => "ignored", conf => < "/block/sda", exp_name => "matched-with-space", conf => < "tty33", exp_perms => "0:0:0660", conf => < "node", exp_perms => "5000::0660", conf => < "node", exp_perms => ":100:0660", conf => < "node", exp_perms => "::0777", conf => < "node", exp_perms => "5000:100:0777", conf => < "ttyUSB0", exp_perms => "5000::", conf => < "ttyUSB0", exp_perms => ":100:0660", conf => < "ttyUSB0", exp_perms => "::0060", conf => < "ttyUSB0", exp_perms => "5000:100:0777", conf => < "ttyUSB0", exp_perms => "5000:100:0777", conf => < "ttyUSB0", exp_perms => "3000:4000:0777", conf => < "ttyUSB0", exp_perms => "3000:8000:0777", conf => < "node", exp_majorminor => "8:0", conf => < "node", exp_majorminor => "89:300", conf => < "node", exp_majorminor => "4095:1", conf => < "node", exp_majorminor => "4094:89999", conf => < "symlink2-ttyUSB0", exp_target => "ttyUSB0", conf => < "visor0", exp_target => "ttyUSB0", conf => < "1/2/symlink" , exp_target => "a/b/node", conf => < "1/2/c/d/symlink" , exp_target => "../../a/b/node", conf => < "second-0" , exp_target => "visor" , conf => < "symlink-only2", exp_target => "link", conf => < "yes", exp_rem_error => "yes", conf => < "yes", option => "clear", conf => < "symlink0", exp_target => "ttyUSB0", conf => < "symlink-ttyUSB0", exp_target => "ttyUSB0", conf => < "major-188:0", exp_target => "ttyUSB0", conf => < "symlink-0:0:0:0", exp_target => "node", conf => < "test", exp_target => "ttyUSB0", conf => < "test", exp_target => "ttyUSB0", conf => < "this", exp_target => "ttyUSB0", conf => < "test", exp_target => "link", conf => < "188:0", exp_target => "ttyUSB0", conf => < "188", exp_target => "ttyUSB0", conf => < "percent%sign", exp_target => "ttyUSB0", conf => < "%ttyUSB0_name", exp_target => "ttyUSB0", conf => < "link1", exp_target => "node", conf => < "link4", exp_target => "node", conf => < "/block/sda", exp_name => "cdrom", conf => < "cdrom", option => "keep", conf => < "enum", option => "keep", conf => < "cdrom1", option => "keep", conf => < "enum1", option => "keep", conf => < "cdrom2", option => "clear", conf => < "/block/sda", exp_name => "cdrom", conf => < "node", exp_add_error => "yes", conf => < "/block/sda", exp_name => "node6", conf => < "node6", exp_add_error => "yes", conf => < "node", exp_rem_error => "yes", conf => < "yes", option => "clear", conf => < "/block/sda", exp_name => "node", conf => < "/block/sda", exp_name => "node", conf => < "/block/sda", exp_name => "node", conf => < "/block/sda", exp_name => "sda", conf => < "main_device", option => "keep", conf => < "main_device-part-1", option => "clean", conf => < "/block/sda/sda1", exp_name => "start-udev-root-end", conf => < "/block/sda/sda1", exp_name => "last", conf => < "negation KERNEL!=", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "match", + conf => < "negation SUBSYSTEM!=", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "not-anything", + conf => < "negation PROGRAM!= exit code", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "nonzero-program", + conf => <file[0] == '\0') || (pair->value[0] == '\0')) break; if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) { - dbg("sysfs attribute doesn't match"); - return -ENODEV; + dbg("sysfs pair #%u does not match", i); + if (pair->operation != KEY_OP_NOMATCH) + return -1; + } else { + dbg("sysfs pair #%u matches", i); + if (pair->operation == KEY_OP_NOMATCH) + return -1; } } @@ -535,23 +540,33 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { if (rule->kernel[0] != '\0') { - dbg("check for " FIELD_KERNEL " rule->kernel='%s' class_dev->name='%s'", + dbg("check for " KEY_KERNEL " rule->kernel='%s' class_dev->name='%s'", rule->kernel, class_dev->name); if (strcmp_pattern(rule->kernel, class_dev->name) != 0) { - dbg(FIELD_KERNEL " is not matching"); - goto exit; + dbg(KEY_KERNEL " is not matching"); + if (rule->kernel_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_KERNEL " matches"); + if (rule->kernel_operation == KEY_OP_NOMATCH) + goto exit; } - dbg(FIELD_KERNEL " matches"); + dbg(KEY_KERNEL " key is true"); } if (rule->subsystem[0] != '\0') { - dbg("check for " FIELD_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'", + dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'", rule->subsystem, class_dev->name); if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { - dbg(FIELD_SUBSYSTEM " is not matching"); - goto exit; + dbg(KEY_SUBSYSTEM " is not matching"); + if (rule->subsystem_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_SUBSYSTEM " matches"); + if (rule->subsystem_operation == KEY_OP_NOMATCH) + goto exit; } - dbg(FIELD_SUBSYSTEM " matches"); + dbg(KEY_SUBSYSTEM " key is true"); } /* walk up the chain of physical devices and find a match */ @@ -562,13 +577,18 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto try_parent; } - dbg("check for " FIELD_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'", + dbg("check for " KEY_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'", rule->driver, sysfs_device->driver_name); if (strcmp_pattern(rule->driver, sysfs_device->driver_name) != 0) { - dbg(FIELD_DRIVER " is not matching"); - goto try_parent; + dbg(KEY_DRIVER " is not matching"); + if (rule->driver_operation != KEY_OP_NOMATCH) + goto try_parent; + } else { + dbg(KEY_DRIVER " matches"); + if (rule->driver_operation == KEY_OP_NOMATCH) + goto try_parent; } - dbg(FIELD_DRIVER " matches"); + dbg(KEY_DRIVER " key is true"); } /* check for matching bus value */ @@ -577,13 +597,18 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto try_parent; } - dbg("check for " FIELD_BUS " rule->bus='%s' sysfs_device->bus='%s'", + dbg("check for " KEY_BUS " rule->bus='%s' sysfs_device->bus='%s'", rule->bus, sysfs_device->bus); if (strcmp_pattern(rule->bus, sysfs_device->bus) != 0) { - dbg(FIELD_BUS " is not matching"); - goto try_parent; + dbg(KEY_BUS " is not matching"); + if (rule->bus_operation != KEY_OP_NOMATCH) + goto try_parent; + } else { + dbg(KEY_BUS " matches"); + if (rule->bus_operation == KEY_OP_NOMATCH) + goto try_parent; } - dbg(FIELD_BUS " matches"); + dbg(KEY_BUS " key is true"); } /* check for matching bus id */ @@ -592,22 +617,27 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto try_parent; } - dbg("check " FIELD_ID); + dbg("check " KEY_ID); if (match_id(rule, sysfs_device) != 0) { - dbg(FIELD_ID " is not matching"); - goto try_parent; + dbg(KEY_ID " is not matching"); + if (rule->id_operation != KEY_OP_NOMATCH) + goto try_parent; + } else { + dbg(KEY_ID " matches"); + if (rule->id_operation == KEY_OP_NOMATCH) + goto try_parent; } - dbg(FIELD_ID " matches"); + dbg(KEY_ID " key is true"); } /* check for matching sysfs pairs */ if (rule->sysfs_pair[0].file[0] != '\0') { - dbg("check " FIELD_SYSFS " pairs"); + dbg("check " KEY_SYSFS " pairs"); if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) { - dbg(FIELD_SYSFS " is not matching"); + dbg(KEY_SYSFS " is not matching"); goto try_parent; } - dbg(FIELD_SYSFS " matches"); + dbg(KEY_SYSFS " keys are true"); } /* found matching physical device */ @@ -625,25 +655,35 @@ try_parent: if (rule->program[0] != '\0') { char program[PATH_SIZE]; - dbg("check " FIELD_PROGRAM); + dbg("check " KEY_PROGRAM); strlcpy(program, rule->program, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); if (execute_program(udev, program, udev->program_result, sizeof(udev->program_result)) != 0) { - dbg(FIELD_PROGRAM " returned nonzero"); - goto try_parent; + dbg(KEY_PROGRAM " returned nonzero"); + if (rule->program_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_PROGRAM " returned successful"); + if (rule->program_operation == KEY_OP_NOMATCH) + goto exit; } - dbg(FIELD_PROGRAM " returned successful"); + dbg(KEY_PROGRAM " key is true"); } /* check for matching result of external program */ if (rule->result[0] != '\0') { - dbg("check for " FIELD_RESULT "rule->result='%s', udev->program_result='%s'", + dbg("check for " KEY_RESULT " rule->result='%s', udev->program_result='%s'", rule->result, udev->program_result); if (strcmp_pattern(rule->result, udev->program_result) != 0) { - dbg(FIELD_RESULT " is not matching"); - goto try_parent; + dbg(KEY_RESULT " is not matching"); + if (rule->result_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_RESULT " matches"); + if (rule->result_operation == KEY_OP_NOMATCH) + goto exit; } - dbg(FIELD_RESULT " matches"); + dbg(KEY_RESULT " key is true"); } /* rule matches */ diff --git a/udev_rules.h b/udev_rules.h index 42552cfa41..d0142031e7 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -28,20 +28,20 @@ #include "list.h" -#define FIELD_KERNEL "KERNEL" -#define FIELD_SUBSYSTEM "SUBSYSTEM" -#define FIELD_BUS "BUS" -#define FIELD_SYSFS "SYSFS" -#define FIELD_ID "ID" -#define FIELD_PROGRAM "PROGRAM" -#define FIELD_RESULT "RESULT" -#define FIELD_DRIVER "DRIVER" -#define FIELD_NAME "NAME" -#define FIELD_SYMLINK "SYMLINK" -#define FIELD_OWNER "OWNER" -#define FIELD_GROUP "GROUP" -#define FIELD_MODE "MODE" -#define FIELD_OPTIONS "OPTIONS" +#define KEY_KERNEL "KERNEL" +#define KEY_SUBSYSTEM "SUBSYSTEM" +#define KEY_BUS "BUS" +#define KEY_SYSFS "SYSFS" +#define KEY_ID "ID" +#define KEY_PROGRAM "PROGRAM" +#define KEY_RESULT "RESULT" +#define KEY_DRIVER "DRIVER" +#define KEY_NAME "NAME" +#define KEY_SYMLINK "SYMLINK" +#define KEY_OWNER "OWNER" +#define KEY_GROUP "GROUP" +#define KEY_MODE "MODE" +#define KEY_OPTIONS "OPTIONS" #define OPTION_LAST_RULE "last_rule" #define OPTION_IGNORE_DEVICE "ignore_device" @@ -52,25 +52,41 @@ #define RULEFILE_SUFFIX ".rules" +enum key_operation { + KEY_OP_UNKNOWN, + KEY_OP_MATCH, + KEY_OP_NOMATCH, + KEY_OP_ADD, + KEY_OP_ASSIGN, +}; + struct sysfs_pair { char file[PATH_SIZE]; char value[VALUE_SIZE]; + enum key_operation operation; }; struct udev_rule { struct list_head node; char kernel[NAME_SIZE]; + enum key_operation kernel_operation; char subsystem[NAME_SIZE]; + enum key_operation subsystem_operation; char bus[NAME_SIZE]; + enum key_operation bus_operation; char id[NAME_SIZE]; - struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; - char program[PATH_SIZE]; - char result[PATH_SIZE]; + enum key_operation id_operation; char driver[NAME_SIZE]; + enum key_operation driver_operation; + char program[PATH_SIZE]; + enum key_operation program_operation; + char result[PATH_SIZE]; + enum key_operation result_operation; + struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; + char name[PATH_SIZE]; char symlink[PATH_SIZE]; - char owner[USER_SIZE]; char group[USER_SIZE]; mode_t mode; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index f77f3db915..ac4755fd37 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -73,6 +73,90 @@ void udev_rule_list_dump(void) udev_rule_dump(rule); } +static int get_key(char **line, char **key, enum key_operation *operation, char **value) +{ + char *linepos; + char *temp; + + linepos = *line; + if (!linepos) + return -1; + + /* skip whitespace */ + while (isspace(linepos[0]) || 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; + if (linepos[0] == '+') + break; + if (linepos[0] == '!') + break; + } + + /* remember end of key */ + temp = linepos; + + /* skip whitespace after key */ + while (isspace(linepos[0])) + linepos++; + + /* 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 + return -1; + + /* terminate key */ + temp[0] = '\0'; + dbg("key='%s'", *key); + + /* skip whitespace after operator */ + 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'; + 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) { @@ -100,9 +184,7 @@ static int rules_parse(struct udevice *udev, const char *filename) char line[LINE_SIZE]; char *bufline; int lineno; - char *temp; - char *temp2; - char *temp3; + char *linepos; char *attr; char *buf; size_t bufsize; @@ -113,12 +195,11 @@ static int rules_parse(struct udevice *udev, const char *filename) int retval = 0; struct udev_rule rule; - if (file_map(filename, &buf, &bufsize) == 0) { - dbg("reading '%s' as rules file", filename); - } else { + if (file_map(filename, &buf, &bufsize) != 0) { dbg("can't open '%s' as rules file", filename); return -1; } + dbg("reading '%s' as rules file", filename); /* loop through the whole file */ cur = 0; @@ -160,39 +241,47 @@ static int rules_parse(struct udevice *udev, const char *filename) /* get all known keys */ memset(&rule, 0x00, sizeof(struct udev_rule)); - temp = line; + linepos = line; valid = 0; while (1) { - retval = parse_get_pair(&temp, &temp2, &temp3); + char *key; + char *value; + enum key_operation operation = KEY_OP_UNKNOWN; + + retval = get_key(&linepos, &key, &operation, &value); if (retval) break; - if (strcasecmp(temp2, FIELD_KERNEL) == 0) { - strlcpy(rule.kernel, temp3, sizeof(rule.kernel)); + if (strcasecmp(key, KEY_KERNEL) == 0) { + strlcpy(rule.kernel, value, sizeof(rule.kernel)); + rule.kernel_operation = operation; valid = 1; continue; } - if (strcasecmp(temp2, FIELD_SUBSYSTEM) == 0) { - strlcpy(rule.subsystem, temp3, sizeof(rule.subsystem)); + if (strcasecmp(key, KEY_SUBSYSTEM) == 0) { + strlcpy(rule.subsystem, value, sizeof(rule.subsystem)); + rule.subsystem_operation = operation; valid = 1; continue; } - if (strcasecmp(temp2, FIELD_BUS) == 0) { - strlcpy(rule.bus, temp3, sizeof(rule.bus)); + if (strcasecmp(key, KEY_BUS) == 0) { + strlcpy(rule.bus, value, sizeof(rule.bus)); + rule.bus_operation = operation; valid = 1; continue; } - if (strcasecmp(temp2, FIELD_ID) == 0) { - strlcpy(rule.id, temp3, sizeof(rule.id)); + if (strcasecmp(key, KEY_ID) == 0) { + strlcpy(rule.id, value, sizeof(rule.id)); + rule.id_operation = operation; valid = 1; continue; } - if (strncasecmp(temp2, FIELD_SYSFS, sizeof(FIELD_SYSFS)-1) == 0) { + if (strncasecmp(key, KEY_SYSFS, sizeof(KEY_SYSFS)-1) == 0) { struct sysfs_pair *pair = &rule.sysfs_pair[0]; int sysfs_pair_num = 0; @@ -206,39 +295,43 @@ static int rules_parse(struct udevice *udev, const char *filename) ++pair; } if (pair) { - attr = get_key_attribute(temp2 + sizeof(FIELD_SYSFS)-1); + attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1); if (attr == NULL) { - dbg("error parsing " FIELD_SYSFS " attribute"); + dbg("error parsing " KEY_SYSFS " attribute"); continue; } strlcpy(pair->file, attr, sizeof(pair->file)); - strlcpy(pair->value, temp3, sizeof(pair->value)); + strlcpy(pair->value, value, sizeof(pair->value)); + pair->operation = operation; valid = 1; } continue; } - if (strcasecmp(temp2, FIELD_DRIVER) == 0) { - strlcpy(rule.driver, temp3, sizeof(rule.driver)); + if (strcasecmp(key, KEY_DRIVER) == 0) { + strlcpy(rule.driver, value, sizeof(rule.driver)); + rule.driver_operation = operation; valid = 1; continue; } - if (strcasecmp(temp2, FIELD_PROGRAM) == 0) { + if (strcasecmp(key, KEY_RESULT) == 0) { + strlcpy(rule.result, value, sizeof(rule.result)); + rule.result_operation = operation; + valid = 1; + continue; + } + + if (strcasecmp(key, KEY_PROGRAM) == 0) { + strlcpy(rule.program, value, sizeof(rule.program)); + rule.program_operation = operation; program_given = 1; - strlcpy(rule.program, temp3, sizeof(rule.program)); valid = 1; continue; } - if (strcasecmp(temp2, FIELD_RESULT) == 0) { - strlcpy(rule.result, temp3, sizeof(rule.result)); - valid = 1; - continue; - } - - if (strncasecmp(temp2, FIELD_NAME, sizeof(FIELD_NAME)-1) == 0) { - attr = get_key_attribute(temp2 + sizeof(FIELD_NAME)-1); + if (strncasecmp(key, KEY_NAME, sizeof(KEY_NAME)-1) == 0) { + attr = get_key_attribute(key + sizeof(KEY_NAME)-1); /* FIXME: remove old style options and make OPTIONS= mandatory */ if (attr != NULL) { if (strstr(attr, OPTION_PARTITIONS) != NULL) { @@ -250,52 +343,52 @@ static int rules_parse(struct udevice *udev, const char *filename) rule.ignore_remove = 1; } } - if (temp3[0] != '\0') - strlcpy(rule.name, temp3, sizeof(rule.name)); + if (value[0] != '\0') + strlcpy(rule.name, value, sizeof(rule.name)); else rule.ignore_device = 1; valid = 1; continue; } - if (strcasecmp(temp2, FIELD_SYMLINK) == 0) { - strlcpy(rule.symlink, temp3, sizeof(rule.symlink)); + if (strcasecmp(key, KEY_SYMLINK) == 0) { + strlcpy(rule.symlink, value, sizeof(rule.symlink)); valid = 1; continue; } - if (strcasecmp(temp2, FIELD_OWNER) == 0) { - strlcpy(rule.owner, temp3, sizeof(rule.owner)); + if (strcasecmp(key, KEY_OWNER) == 0) { + strlcpy(rule.owner, value, sizeof(rule.owner)); valid = 1; continue; } - if (strcasecmp(temp2, FIELD_GROUP) == 0) { - strlcpy(rule.group, temp3, sizeof(rule.group)); + if (strcasecmp(key, KEY_GROUP) == 0) { + strlcpy(rule.group, value, sizeof(rule.group)); valid = 1; continue; } - if (strcasecmp(temp2, FIELD_MODE) == 0) { - rule.mode = strtol(temp3, NULL, 8); + if (strcasecmp(key, KEY_MODE) == 0) { + rule.mode = strtol(value, NULL, 8); valid = 1; continue; } - if (strcasecmp(temp2, FIELD_OPTIONS) == 0) { - if (strstr(temp3, OPTION_LAST_RULE) != NULL) { + if (strcasecmp(key, KEY_OPTIONS) == 0) { + if (strstr(value, OPTION_LAST_RULE) != NULL) { dbg("last rule to be applied"); rule.last_rule = 1; } - if (strstr(temp3, OPTION_IGNORE_DEVICE) != NULL) { + if (strstr(value, OPTION_IGNORE_DEVICE) != NULL) { dbg("device should be ignored"); rule.ignore_device = 1; } - if (strstr(temp3, OPTION_IGNORE_REMOVE) != NULL) { + if (strstr(value, OPTION_IGNORE_REMOVE) != NULL) { dbg("remove event should be ignored"); rule.ignore_remove = 1; } - if (strstr(temp3, OPTION_PARTITIONS) != NULL) { + if (strstr(value, OPTION_PARTITIONS) != NULL) { dbg("creation of partition nodes requested"); rule.partitions = DEFAULT_PARTITIONS_COUNT; } @@ -303,7 +396,7 @@ static int rules_parse(struct udevice *udev, const char *filename) continue; } - dbg("unknown type of field '%s'", temp2); + dbg("unknown key '%s'", key); goto error; } @@ -314,13 +407,13 @@ static int rules_parse(struct udevice *udev, const char *filename) /* simple plausibility checks for given keys */ if ((rule.sysfs_pair[0].file[0] == '\0') ^ (rule.sysfs_pair[0].value[0] == '\0')) { - info("inconsistency in " FIELD_SYSFS " key"); + info("inconsistency in " KEY_SYSFS " key"); goto error; } if ((rule.result[0] != '\0') && (program_given == 0)) { - info(FIELD_RESULT " is only useful when " - FIELD_PROGRAM " is called in any rule before"); + info(KEY_RESULT " is only useful when " + KEY_PROGRAM " is called in any rule before"); goto error; } @@ -332,7 +425,7 @@ static int rules_parse(struct udevice *udev, const char *filename) continue; error: info("parse error %s, line %d:%d, rule skipped", - filename, lineno, (int) (temp - line)); + filename, lineno, (int) (linepos - line)); } } diff --git a/udev_utils.c b/udev_utils.c index b650096593..c6658e6933 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -177,41 +177,6 @@ int unlink_secure(const char *filename) return retval; } -int parse_get_pair(char **orig_string, char **left, char **right) -{ - char *temp; - char *string = *orig_string; - - if (!string) - return -ENODEV; - - /* eat any whitespace */ - while (isspace(*string) || *string == ',') - ++string; - - /* split based on '=' */ - temp = strsep(&string, "="); - *left = temp; - if (!string) - return -ENODEV; - - /* take the right side and strip off the '"' */ - while (isspace(string[0])) - ++string; - if (string[0] == '"') - ++string; - else - return -ENODEV; - - temp = strsep(&string, "\""); - if (!string || temp[0] == '\0') - return -ENODEV; - *right = temp; - *orig_string = string; - - return 0; -} - int file_map(const char *filename, char **buf, size_t *bufsize) { struct stat stats; From 38285d23d702258d3b219532a9874555e797a292 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 13 Mar 2005 07:14:49 +0100 Subject: [PATCH 1231/4284] [PATCH] add a test and simplify debug statement --- RELEASE-NOTES | 11 ++++++----- test/udev-test.pl | 10 ++++++++++ udev_rules.h | 7 ++----- udev_rules_parse.c | 27 ++++++++------------------- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index ee77d845be..8895f46215 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -9,12 +9,13 @@ THE PLACE= key is gone. It can be replaced by an ID= for a long time, cause we walk up the chain of physical devices to find a match. The KEY="" format supports '=', '==', '!=,' , '+=' now. This makes it -easier to skip certain devices without composing rules with weird character -class negations like: +easy to skip certain attribute matches without composing rules with weird +character class negations like: KERNEL="[!s][!c][!d]*" -this can be replaced by: +this can now be replaced with: KERNEL!="scd*" -The simple '=' is still supported, but the rules should be converted if -possible, to be better human-readable. +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. + diff --git a/test/udev-test.pl b/test/udev-test.pl index 8d66536b94..ebceccecb2 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1159,6 +1159,16 @@ EOF conf => < "test for whitespace between the operator", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + conf => <node, &udev_rule_list); - udev_rule_dump(tmp_rule); - return 0; -} - -void udev_rule_dump(struct udev_rule *rule) -{ dbg("name='%s', symlink='%s', bus='%s', id='%s', " "sysfs_file[0]='%s', sysfs_value[0]='%s', " - "kernel='%s', program='%s', result='%s'" - "owner='%s', group='%s', mode=%#o", + "kernel='%s', program='%s', result='%s', " + "owner='%s', group='%s', mode=%#o, " + "all_partions=%u, ignore_remove=%u, ignore_device=%u, last_rule=%u", rule->name, rule->symlink, rule->bus, rule->id, rule->sysfs_pair[0].file, rule->sysfs_pair[0].value, - rule->kernel, rule->program, rule->result, - rule->owner, rule->group, rule->mode); -} + rule->kernel, rule->program, rule->result, rule->owner, rule->group, rule->mode, + rule->partitions, rule->ignore_remove, rule->ignore_device, rule->last_rule); -void udev_rule_list_dump(void) -{ - struct udev_rule *rule; - - list_for_each_entry(rule, &udev_rule_list, node) - udev_rule_dump(rule); + return 0; } static int get_key(char **line, char **key, enum key_operation *operation, char **value) From 79f651f4bd2fb395a705792eb8ce551a6021bcd6 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 13 Mar 2005 08:15:10 +0100 Subject: [PATCH 1232/4284] [PATCH] simplify sysfs_pair handling --- udev_rules.c | 19 ++++++++++--------- udev_rules.h | 9 +++++---- udev_rules_parse.c | 39 +++++++++++++++++---------------------- 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 3a55270791..d1192614aa 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -463,16 +463,16 @@ attr_found: return tmpattr; } -static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct sysfs_pair *pair) +static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct key_pair *pair) { struct sysfs_attribute *tmpattr; int i; int len; - if ((pair == NULL) || (pair->file[0] == '\0') || (pair->value == '\0')) + if ((pair == NULL) || (pair->name[0] == '\0') || (pair->value == '\0')) return -ENODEV; - tmpattr = find_sysfs_attribute(class_dev, sysfs_device, pair->file); + tmpattr = find_sysfs_attribute(class_dev, sysfs_device, pair->name); if (tmpattr == NULL) return -ENODEV; @@ -489,23 +489,24 @@ static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct } dbg("compare attribute '%s' value '%s' with '%s'", - pair->file, tmpattr->value, pair->value); + pair->name, tmpattr->value, pair->value); if (strcmp_pattern(pair->value, tmpattr->value) != 0) return -ENODEV; dbg("found matching attribute '%s' with value '%s'", - pair->file, pair->value); + pair->name, pair->value); return 0; } static int match_sysfs_pairs(struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { - struct sysfs_pair *pair; int i; - for (i = 0; i < MAX_SYSFS_PAIRS; ++i) { + for (i = 0; i < rule->sysfs_pair_count; i++) { + struct key_pair *pair; + pair = &rule->sysfs_pair[i]; - if ((pair->file[0] == '\0') || (pair->value[0] == '\0')) + if ((pair->name[0] == '\0') || (pair->value[0] == '\0')) break; if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) { dbg("sysfs pair #%u does not match", i); @@ -631,7 +632,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, } /* check for matching sysfs pairs */ - if (rule->sysfs_pair[0].file[0] != '\0') { + if (rule->sysfs_pair[0].name[0] != '\0') { dbg("check " KEY_SYSFS " pairs"); if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) { dbg(KEY_SYSFS " is not matching"); diff --git a/udev_rules.h b/udev_rules.h index 688d4798e1..94a5d9d5fd 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -48,7 +48,7 @@ #define OPTION_IGNORE_REMOVE "ignore_remove" #define OPTION_PARTITIONS "all_partitions" -#define MAX_SYSFS_PAIRS 5 +#define KEY_SYSFS_PAIRS_MAX 5 #define RULEFILE_SUFFIX ".rules" @@ -60,8 +60,8 @@ enum key_operation { KEY_OP_ASSIGN, }; -struct sysfs_pair { - char file[PATH_SIZE]; +struct key_pair { + char name[NAME_SIZE]; char value[VALUE_SIZE]; enum key_operation operation; }; @@ -83,7 +83,8 @@ struct udev_rule { enum key_operation program_operation; char result[PATH_SIZE]; enum key_operation result_operation; - struct sysfs_pair sysfs_pair[MAX_SYSFS_PAIRS]; + struct key_pair sysfs_pair[KEY_SYSFS_PAIRS_MAX]; + int sysfs_pair_count; char name[PATH_SIZE]; char symlink[PATH_SIZE]; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index db83a67953..c4c684d059 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -55,7 +55,7 @@ static int add_config_dev(struct udev_rule *rule) "owner='%s', group='%s', mode=%#o, " "all_partions=%u, ignore_remove=%u, ignore_device=%u, last_rule=%u", rule->name, rule->symlink, rule->bus, rule->id, - rule->sysfs_pair[0].file, rule->sysfs_pair[0].value, + rule->sysfs_pair[0].name, rule->sysfs_pair[0].value, rule->kernel, rule->program, rule->result, rule->owner, rule->group, rule->mode, rule->partitions, rule->ignore_remove, rule->ignore_device, rule->last_rule); @@ -271,29 +271,24 @@ static int rules_parse(struct udevice *udev, const char *filename) } if (strncasecmp(key, KEY_SYSFS, sizeof(KEY_SYSFS)-1) == 0) { - struct sysfs_pair *pair = &rule.sysfs_pair[0]; - int sysfs_pair_num = 0; + struct key_pair *pair; - /* find first unused pair */ - while (pair->file[0] != '\0') { - ++sysfs_pair_num; - if (sysfs_pair_num >= MAX_SYSFS_PAIRS) { - pair = NULL; - break; - } - ++pair; + if (rule.sysfs_pair_count >= KEY_SYSFS_PAIRS_MAX) { + dbg("skip rule, to many " KEY_SYSFS " keys in a single rule"); + goto error; } - if (pair) { - attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1); - if (attr == NULL) { - dbg("error parsing " KEY_SYSFS " attribute"); - continue; - } - strlcpy(pair->file, attr, sizeof(pair->file)); - strlcpy(pair->value, value, sizeof(pair->value)); - pair->operation = operation; - valid = 1; + pair = &rule.sysfs_pair[rule.sysfs_pair_count]; + rule.sysfs_pair_count++; + + attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1); + if (attr == NULL) { + dbg("error parsing " KEY_SYSFS " attribute"); + continue; } + strlcpy(pair->name, attr, sizeof(pair->name)); + strlcpy(pair->value, value, sizeof(pair->value)); + pair->operation = operation; + valid = 1; continue; } @@ -394,7 +389,7 @@ static int rules_parse(struct udevice *udev, const char *filename) goto error; /* simple plausibility checks for given keys */ - if ((rule.sysfs_pair[0].file[0] == '\0') ^ + if ((rule.sysfs_pair[0].name[0] == '\0') ^ (rule.sysfs_pair[0].value[0] == '\0')) { info("inconsistency in " KEY_SYSFS " key"); goto error; From 3e5958dee5f24283eb5c6a2d2d95e1a39428a3b8 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 13 Mar 2005 11:40:32 +0100 Subject: [PATCH 1233/4284] [PATCH] add ENV{} key to match agains environment variables --- test/udev-test.pl | 32 +++++++++++++++------ udev.8.in | 10 +++++-- udev_rules.c | 71 ++++++++++++++++++++++++++++------------------ udev_rules.h | 6 +++- udev_rules_parse.c | 24 ++++++++++++++-- 5 files changed, 100 insertions(+), 43 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index ebceccecb2..2ece431735 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -256,15 +256,6 @@ EOF exp_name => "M8-m3-n3-b0:0-sIBM" , conf => < "old style SYSFS_ attribute", - subsys => "block", - devpath => "/block/sda", - exp_name => "good" , - conf => < < "ENV{} test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + conf => < "ENV{} test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + conf => <sysfs_pair_count; i++) { - struct key_pair *pair; - - pair = &rule->sysfs_pair[i]; - if ((pair->name[0] == '\0') || (pair->value[0] == '\0')) - break; - if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) { - dbg("sysfs pair #%u does not match", i); - if (pair->operation != KEY_OP_NOMATCH) - return -1; - } else { - dbg("sysfs pair #%u matches", i); - if (pair->operation == KEY_OP_NOMATCH) - return -1; - } - } - - return 0; -} - static int match_id(struct udev_rule *rule, struct sysfs_device *sysfs_device) { char path[PATH_SIZE]; @@ -570,6 +546,33 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg(KEY_SUBSYSTEM " key is true"); } + if (rule->env_pair_count) { + int i; + + dbg("check for " KEY_ENV " pairs"); + for (i = 0; i < rule->env_pair_count; i++) { + struct key_pair *pair; + const char *value; + + pair = &rule->env_pair[i]; + value = getenv(pair->name); + if (!value) { + dbg(KEY_ENV "{'%s'} is not found", pair->name); + goto exit; + } + if (strcmp_pattern(pair->value, value) != 0) { + dbg(KEY_ENV "{'%s'} is not matching", pair->name); + if (pair->operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_ENV "{'%s'} matches", pair->name); + if (pair->operation == KEY_OP_NOMATCH) + goto exit; + } + } + dbg(KEY_ENV " key is true"); + } + /* walk up the chain of physical devices and find a match */ while (1) { /* check for matching driver */ @@ -632,11 +635,23 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, } /* check for matching sysfs pairs */ - if (rule->sysfs_pair[0].name[0] != '\0') { + if (rule->sysfs_pair_count) { + int i; + dbg("check " KEY_SYSFS " pairs"); - if (match_sysfs_pairs(rule, class_dev, sysfs_device) != 0) { - dbg(KEY_SYSFS " is not matching"); - goto try_parent; + for (i = 0; i < rule->sysfs_pair_count; i++) { + struct key_pair *pair; + + pair = &rule->sysfs_pair[i]; + if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) { + dbg(KEY_SYSFS "{'%s'} is not matching", pair->name); + if (pair->operation != KEY_OP_NOMATCH) + goto try_parent; + } else { + dbg(KEY_SYSFS "{'%s'} matches", pair->name); + if (pair->operation == KEY_OP_NOMATCH) + goto try_parent; + } } dbg(KEY_SYSFS " keys are true"); } diff --git a/udev_rules.h b/udev_rules.h index 94a5d9d5fd..423a6f641e 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -31,11 +31,12 @@ #define KEY_KERNEL "KERNEL" #define KEY_SUBSYSTEM "SUBSYSTEM" #define KEY_BUS "BUS" -#define KEY_SYSFS "SYSFS" #define KEY_ID "ID" #define KEY_PROGRAM "PROGRAM" #define KEY_RESULT "RESULT" #define KEY_DRIVER "DRIVER" +#define KEY_SYSFS "SYSFS" +#define KEY_ENV "ENV" #define KEY_NAME "NAME" #define KEY_SYMLINK "SYMLINK" #define KEY_OWNER "OWNER" @@ -49,6 +50,7 @@ #define OPTION_PARTITIONS "all_partitions" #define KEY_SYSFS_PAIRS_MAX 5 +#define KEY_ENV_PAIRS_MAX 5 #define RULEFILE_SUFFIX ".rules" @@ -85,6 +87,8 @@ struct udev_rule { enum key_operation result_operation; struct key_pair sysfs_pair[KEY_SYSFS_PAIRS_MAX]; int sysfs_pair_count; + struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; + int env_pair_count; char name[PATH_SIZE]; char symlink[PATH_SIZE]; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index c4c684d059..face496ab3 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -278,16 +278,36 @@ static int rules_parse(struct udevice *udev, const char *filename) goto error; } pair = &rule.sysfs_pair[rule.sysfs_pair_count]; - rule.sysfs_pair_count++; - attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1); if (attr == NULL) { dbg("error parsing " KEY_SYSFS " attribute"); + goto error; + } + strlcpy(pair->name, attr, sizeof(pair->name)); + strlcpy(pair->value, value, sizeof(pair->value)); + pair->operation = operation; + rule.sysfs_pair_count++; + valid = 1; + continue; + } + + if (strncasecmp(key, KEY_ENV, sizeof(KEY_ENV)-1) == 0) { + struct key_pair *pair; + + if (rule.env_pair_count >= KEY_ENV_PAIRS_MAX) { + dbg("skip rule, to many " KEY_ENV " keys in a single rule"); + goto error; + } + pair = &rule.env_pair[rule.env_pair_count]; + attr = get_key_attribute(key + sizeof(KEY_ENV)-1); + if (attr == NULL) { + dbg("error parsing " KEY_ENV " attribute"); continue; } strlcpy(pair->name, attr, sizeof(pair->name)); strlcpy(pair->value, value, sizeof(pair->value)); pair->operation = operation; + rule.env_pair_count++; valid = 1; continue; } From fc90ce812d052b4c766d91769456b42ba0051cb1 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 13 Mar 2005 11:43:50 +0100 Subject: [PATCH 1234/4284] [PATCH] add final release note --- RELEASE-NOTES | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 8895f46215..958ad39b8a 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -5,17 +5,17 @@ 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, cause +The PLACE= key is gone. It can be replaced by an ID= for a long time, cause 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. From d6d1a18d7245b8065df95775c6d45fe2d8f2e66a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 14 Mar 2005 04:01:54 +0100 Subject: [PATCH 1235/4284] [PATCH] remove unneeded code, libsysfs does this for us --- udev_rules.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 551c06131b..f09d6d47bf 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -498,21 +498,6 @@ static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct return 0; } -static int match_id(struct udev_rule *rule, struct sysfs_device *sysfs_device) -{ - char path[PATH_SIZE]; - char *temp; - - strlcpy(path, sysfs_device->path, sizeof(path)); - temp = strrchr(path, '/'); - temp++; - dbg("search '%s' in '%s', path='%s'", rule->id, temp, path); - if (strcmp_pattern(rule->id, temp) != 0) - return -ENODEV; - - return 0; -} - static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { @@ -622,7 +607,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, goto try_parent; } dbg("check " KEY_ID); - if (match_id(rule, sysfs_device) != 0) { + if (strcmp_pattern(rule->id, sysfs_device->bus_id) != 0) { dbg(KEY_ID " is not matching"); if (rule->id_operation != KEY_OP_NOMATCH) goto try_parent; From ca4c984cf5a2ee3e8d61d16bb3391ed6ff5f4cc7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 14 Mar 2005 04:18:20 +0100 Subject: [PATCH 1236/4284] [PATCH] correct rule match for devices without a physical device --- udev_rules.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index f09d6d47bf..3dc77855da 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -564,7 +564,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, if (rule->driver[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no sysfs_device"); - goto try_parent; + goto exit; } dbg("check for " KEY_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'", rule->driver, sysfs_device->driver_name); @@ -584,7 +584,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, if (rule->bus[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no sysfs_device"); - goto try_parent; + goto exit; } dbg("check for " KEY_BUS " rule->bus='%s' sysfs_device->bus='%s'", rule->bus, sysfs_device->bus); @@ -604,7 +604,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, if (rule->id[0] != '\0') { if (sysfs_device == NULL) { dbg("device has no sysfs_device"); - goto try_parent; + goto exit; } dbg("check " KEY_ID); if (strcmp_pattern(rule->id, sysfs_device->bus_id) != 0) { @@ -648,8 +648,8 @@ try_parent: sysfs_device = sysfs_get_device_parent(sysfs_device); if (sysfs_device == NULL) goto exit; - dbg("sysfs_device->path='%s'", sysfs_device->path); - dbg("sysfs_device->bus_id='%s'", sysfs_device->bus_id); + dbg("look at sysfs_device->path='%s'", sysfs_device->path); + dbg("look at sysfs_device->bus_id='%s'", sysfs_device->bus_id); } /* execute external program */ From 29e8ed4c27a311be32cc039f3d284d9836f3021d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 14 Mar 2005 04:40:12 +0100 Subject: [PATCH 1237/4284] [PATCH] clarify the shortcomings of %e --- udev.8.in | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/udev.8.in b/udev.8.in index 84d8a313da..a246efdb45 100644 --- a/udev.8.in +++ b/udev.8.in @@ -238,6 +238,14 @@ decimal integer N is substituted such that the resulting name doesn't match an existing device node. Otherwise nothing is substituted. This can be used to create compatibility symlinks and enumerate devices of the same type originating from different kernel subsystems. +.sp +Note: The use of the enumeration facility is unreliable outside of +udevstart where the node creation is serialized and predictable. +The returned numbers rely on the order devices are probed on the +system. If more than one device requests an enumeration for the same +name at the same time, it may be possible that both requests receive the +same name back from the database. The use of enumerations in todays setups +where device can come and go at any time is not recomended. .TP .B %% The '%' character itself. From cc44094d6353f9af4d8b485e5d7027a190200cb7 Mon Sep 17 00:00:00 2001 From: "hare@suse.de" Date: Wed, 16 Mar 2005 00:46:44 +0100 Subject: [PATCH 1238/4284] [PATCH] volume_id: Fix label/uuid reading for reiserfs Well, I just asked our resident reiserfs guru (thx mason :-). Reiser v3.5 does not support labels nor uuids. --- extras/volume_id/volume_id/reiserfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index 34cf167dc4..091c68aaf4 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -80,6 +80,10 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) return -1; rs = (struct reiserfs_super_block *) buf;; + if (memcmp(rs->magic, "ReIsErFs", 8) == 0) { + strcpy(id->type_version, "3.5"); + goto found; + } if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) { strcpy(id->type_version, "3.6"); goto found_v3; @@ -104,7 +108,7 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) if (memcmp(rs->magic, "ReIsErFs", 8) == 0) { strcpy(id->type_version, "3.5"); - goto found_v3; + goto found; } return -1; From 7d227c5f34d96a560baed6dc1b9d9865db2e678d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 16 Mar 2005 00:52:00 +0100 Subject: [PATCH 1239/4284] [PATCH] volume_id: version 43 --- extras/volume_id/volume_id/reiserfs.c | 6 +++--- extras/volume_id/volume_id/volume_id.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index 091c68aaf4..a53fc4a5a9 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -86,11 +86,11 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) } if (memcmp(rs->magic, "ReIsEr2Fs", 9) == 0) { strcpy(id->type_version, "3.6"); - goto found_v3; + goto found_label; } if (memcmp(rs->magic, "ReIsEr3Fs", 9) == 0) { strcpy(id->type_version, "JR"); - goto found_v3; + goto found_label; } rs4 = (struct reiser4_super_block *) buf; @@ -113,7 +113,7 @@ int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) return -1; -found_v3: +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, UUID_DCE); diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 63f95132df..c7fa0d9bea 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 42 +#define VOLUME_ID_VERSION 43 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 0e33828a76ccf88e9f5e4111df7c02860d307285 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 16 Mar 2005 00:54:28 +0100 Subject: [PATCH 1240/4284] [PATCH] add udevstart to the RELEASE-NOTES --- RELEASE-NOTES | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 958ad39b8a..0bddab4189 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -19,3 +19,6 @@ 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, cause we don't need co carry this araound +with every forked event. From 677a6a84bd16bdae229830a731800efc5de64b0f Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Wed, 16 Mar 2005 22:45:14 -0800 Subject: [PATCH 1241/4284] [PATCH] gentoo rule update for raid devices. From Thierry Vignaud --- etc/udev/gentoo/udev.rules | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 9d109d0930..71e39e1e11 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -29,6 +29,13 @@ KERNEL="sd*", NAME="%k", GROUP="disk" KERNEL="dasd*", NAME="%k", GROUP="disk" KERNEL="ataraid*", NAME="%k", GROUP="disk" +# compaq smart array +KERNEL="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +KERNEL="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" + +# mylex +KERNEL="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" + # dri devices KERNEL="card*", NAME="dri/card%n", GROUP="video" KERNEL="nvidia*", NAME="%k", GROUP="video" From c29125aebb439f906def956c09fb39efd787ca3a Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Wed, 16 Mar 2005 22:51:56 -0800 Subject: [PATCH 1242/4284] [PATCH] added frugalware udev ruleset. --- etc/udev/frugalware/udev.rules | 170 +++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 etc/udev/frugalware/udev.rules diff --git a/etc/udev/frugalware/udev.rules b/etc/udev/frugalware/udev.rules new file mode 100644 index 0000000000..a7c19cb967 --- /dev/null +++ b/etc/udev/frugalware/udev.rules @@ -0,0 +1,170 @@ +# 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 +# + +# if this is a ide cdrom, name it the default name, and create a symlink to cdrom +# BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" + +# 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" + +# USB devices +KERNEL="hiddev*", NAME="usb/%k" +KERNEL="auer*", NAME="usb/%k" +KERNEL="legousbtower*", NAME="usb/%k" +KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" + +# 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="500", GROUP="500", 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="sys", MODE="0666" +KERNEL="beep" NAME="%k", OWNER="root", GROUP="root", MODE="0644" +KERNEL="dsp*" NAME="%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="midi*" NAME="%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="mixer*" NAME="%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="music" NAME="%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="sequencer*" NAME="%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="controlC[0-9]*", NAME="snd/%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="hw[CD0-9]*", NAME="snd/%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="pcm[CD0-9cp]*", NAME="snd/%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="midiC[D0-9]*", NAME="snd/%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="timer", NAME="snd/%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="seq", NAME="snd/%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="sndstat" NAME="%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="speaker" NAME="%k", OWNER="root", GROUP="root", MODE="0644" +KERNEL="sound/*" NAME="%k", OWNER="root", GROUP="root", MODE="0666" +KERNEL="admmidi*" NAME="%k", OWNER="root", GROUP="root", MODE="0666" +KERNEL="adsp*" NAME="%k", OWNER="root", GROUP="root", MODE="0666" +KERNEL="aload*" NAME="%k", OWNER="root", GROUP="sys", MODE="0666" +KERNEL="amidi*" NAME="%k", OWNER="root", GROUP="root", MODE="0666" +KERNEL="amixer*" NAME="%k", OWNER="root", GROUP="root", 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="root", MODE="0660" + +# video devices +KERNEL="card*" NAME="dri/card%n", OWNER="root", GROUP="root", MODE="0666" +KERNEL="fb[0-9]" NAME="%k", OWNER="root", GROUP="tty", MODE="0660" +KERNEL="agpgart" NAME="%k", OWNER="root", GROUP="root", MODE="0660" +KERNEL="nvidia*" NAME="%k", OWNER="root", GROUP="root", MODE="0666" +KERNEL="video*" NAME="%k", OWNER="root", GROUP="sys", 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" + +# 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" From c262aa49840f4821b5769bbfa9930a4bf4981a06 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Wed, 16 Mar 2005 23:23:03 -0800 Subject: [PATCH 1243/4284] [PATCH] fix raid rules. Thanks to Kay for pointing it out. --- etc/udev/gentoo/udev.rules | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 71e39e1e11..db8c5d9263 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -30,11 +30,11 @@ KERNEL="dasd*", NAME="%k", GROUP="disk" KERNEL="ataraid*", NAME="%k", GROUP="disk" # compaq smart array -KERNEL="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" -KERNEL="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +KERNEL="cciss*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +KERNEL="ida*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" # mylex -KERNEL="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +KERNEL="rd*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" # dri devices KERNEL="card*", NAME="dri/card%n", GROUP="video" From 2861655484df31fdeb2a8d04b5abf8fe9bc8a2f8 Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Thu, 17 Mar 2005 00:45:02 -0800 Subject: [PATCH 1244/4284] [PATCH] 055 release --- ChangeLog | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 81 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 472df80dbc..9c1ee1f889 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,82 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 556298a9f1..2be255ef27 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 054 +VERSION = 055 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 32aca6196f..3a03099799 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 054 +Version: 055 Release: 1 License: GPL Group: Utilities/System From 7e3e23925b139075746c015eaffaba509d5eb304 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 17 Mar 2005 00:38:43 +0100 Subject: [PATCH 1245/4284] [PATCH] remove unneeded file from libsysfs --- libsysfs/sysfs_bus.c | 400 ------------------------------------------- 1 file changed, 400 deletions(-) delete mode 100644 libsysfs/sysfs_bus.c diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c deleted file mode 100644 index d47b94ca24..0000000000 --- a/libsysfs/sysfs_bus.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * sysfs_bus.c - * - * Generic bus utility functions for libsysfs - * - * Copyright (C) IBM Corp. 2003 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "libsysfs.h" -#include "sysfs.h" - -static void sysfs_close_dev(void *dev) -{ - sysfs_close_device((struct sysfs_device *)dev); -} - -static void sysfs_close_drv(void *drv) -{ - sysfs_close_driver((struct sysfs_driver *)drv); -} - -/* - * compares devices' bus ids. - * @a: device id looking for - * @b: sysfs_device comparing being compared - * returns 1 if a==b->bus_id or 0 not equal - */ -static int bus_device_id_equal(void *a, void *b) -{ - if (a == NULL || b == NULL) - return 0; - - if (strcmp(((char *)a), ((struct sysfs_device *)b)->bus_id) - == 0) - return 1; - return 0; -} - -/* - * compares drivers' names. - * @a: driver name looking for - * @b: sysfs_driver comparing being compared - * returns 1 if a==b->name or 0 not equal - */ -static int bus_driver_name_equal(void *a, void *b) -{ - if (a == NULL || b == NULL) - return 0; - - if (strcmp(((char *)a), ((struct sysfs_driver *)b)->name) == 0) - return 1; - return 0; -} - -/** - * sysfs_close_bus: close single bus - * @bus: bus structure - */ -void sysfs_close_bus(struct sysfs_bus *bus) -{ - if (bus != NULL) { - if (bus->directory != NULL) - sysfs_close_directory(bus->directory); - if (bus->devices) - dlist_destroy(bus->devices); - if (bus->drivers) - dlist_destroy(bus->drivers); - free(bus); - } -} - -/** - * alloc_bus: mallocs new bus structure - * returns sysfs_bus_bus struct or NULL - */ -static struct sysfs_bus *alloc_bus(void) -{ - return (struct sysfs_bus *)calloc(1, sizeof(struct sysfs_bus)); -} - -/** - * sysfs_get_bus_devices: gets all devices for bus - * @bus: bus to get devices for - * returns dlist of devices with success and NULL with failure - */ -struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) -{ - struct sysfs_device *bdev = NULL; - struct sysfs_directory *devdir = NULL; - struct sysfs_link *curl = NULL; - char path[SYSFS_PATH_MAX]; - - if (bus == NULL) { - errno = EINVAL; - return NULL; - } - memset(path, 0, SYSFS_PATH_MAX); - safestrcpy(path, bus->path); - safestrcat(path, "/"); - safestrcat(path, SYSFS_DEVICES_NAME); - devdir = sysfs_open_directory(path); - if (devdir == NULL) - return NULL; - - if (sysfs_read_dir_links(devdir) != 0) { - sysfs_close_directory(devdir); - return NULL; - } - - if (devdir->links != NULL) { - dlist_for_each_data(devdir->links, curl, struct sysfs_link) { - bdev = sysfs_open_device_path(curl->target); - if (bdev == NULL) { - dprintf("Error opening device at %s\n", - curl->target); - continue; - } - if (bus->devices == NULL) - bus->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_dev); - dlist_unshift_sorted(bus->devices, bdev, sort_list); - } - } - sysfs_close_directory(devdir); - - return (bus->devices); -} - -/** - * sysfs_get_bus_drivers: get all pci drivers - * @bus: pci bus to add drivers to - * returns dlist of drivers with success and NULL with error - */ -struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) -{ - struct sysfs_driver *driver = NULL; - struct sysfs_directory *drvdir = NULL; - struct sysfs_directory *cursub = NULL; - char path[SYSFS_PATH_MAX]; - - if (bus == NULL) { - errno = EINVAL; - return NULL; - } - memset(path, 0, SYSFS_PATH_MAX); - safestrcpy(path, bus->path); - safestrcat(path, "/"); - safestrcat(path, SYSFS_DRIVERS_NAME); - drvdir = sysfs_open_directory(path); - if (drvdir == NULL) - return NULL; - - if (sysfs_read_dir_subdirs(drvdir) != 0) { - sysfs_close_directory(drvdir); - return NULL; - } - if (drvdir->subdirs != NULL) { - dlist_for_each_data(drvdir->subdirs, cursub, - struct sysfs_directory) { - driver = sysfs_open_driver_path(cursub->path); - if (driver == NULL) { - dprintf("Error opening driver at %s\n", - cursub->path); - continue; - } - if (bus->drivers == NULL) - bus->drivers = dlist_new_with_delete - (sizeof(struct sysfs_driver), - sysfs_close_drv); - dlist_unshift_sorted(bus->drivers, driver, sort_list); - } - } - sysfs_close_directory(drvdir); - return (bus->drivers); -} - -/** - * sysfs_open_bus: opens specific bus and all its devices on system - * returns sysfs_bus structure with success or NULL with error. - */ -struct sysfs_bus *sysfs_open_bus(const char *name) -{ - struct sysfs_bus *bus = NULL; - char buspath[SYSFS_PATH_MAX]; - - if (name == NULL) { - errno = EINVAL; - return NULL; - } - - memset(buspath, 0, SYSFS_PATH_MAX); - if ((sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) != 0) { - dprintf("Sysfs not supported on this system\n"); - return NULL; - } - - safestrcat(buspath, "/"); - safestrcat(buspath, SYSFS_BUS_NAME); - safestrcat(buspath, "/"); - safestrcat(buspath, name); - if ((sysfs_path_is_dir(buspath)) != 0) { - dprintf("Invalid path to bus: %s\n", buspath); - return NULL; - } - bus = alloc_bus(); - if (bus == NULL) { - dprintf("calloc failed\n"); - return NULL; - } - safestrcpy(bus->name, name); - safestrcpy(bus->path, buspath); - if ((sysfs_remove_trailing_slash(bus->path)) != 0) { - dprintf("Incorrect path to bus %s\n", bus->path); - sysfs_close_bus(bus); - return NULL; - } - - return bus; -} - -/** - * sysfs_get_bus_device: Get specific device on bus using device's id - * @bus: bus to find device on - * @id: bus_id for device - * returns struct sysfs_device reference or NULL if not found. - */ -struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, char *id) -{ - if (bus == NULL || id == NULL) { - errno = EINVAL; - return NULL; - } - - if (bus->devices == NULL) { - bus->devices = sysfs_get_bus_devices(bus); - if (bus->devices == NULL) - return NULL; - } - - return (struct sysfs_device *)dlist_find_custom(bus->devices, id, - bus_device_id_equal); -} - -/** - * sysfs_get_bus_driver: Get specific driver on bus using driver name - * @bus: bus to find driver on - * @drvname: name of driver - * returns struct sysfs_driver reference or NULL if not found. - */ -struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, - char *drvname) -{ - if (bus == NULL || drvname == NULL) { - errno = EINVAL; - return NULL; - } - - if (bus->drivers == NULL) { - bus->drivers = sysfs_get_bus_drivers(bus); - if (bus->drivers == NULL) - return NULL; - } - - return (struct sysfs_driver *)dlist_find_custom(bus->drivers, drvname, - bus_driver_name_equal); -} - -/** - * sysfs_get_bus_attributes: returns bus' dlist of attributes - * @bus: bus to get attributes for. - * returns dlist of attributes or NULL if there aren't any. - */ -struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) -{ - if (bus == NULL) - return NULL; - - if (bus->directory == NULL) { - bus->directory = sysfs_open_directory(bus->path); - if (bus->directory == NULL) - return NULL; - } - if (bus->directory->attributes == NULL) { - if ((sysfs_read_dir_attributes(bus->directory)) != 0) - return NULL; - } - return bus->directory->attributes; -} - -/** - * sysfs_refresh_bus_attributes: refreshes the bus's list of attributes - * @bus: sysfs_bus whose attributes to refresh - * - * NOTE: Upon return, prior references to sysfs_attributes for this bus - * _may_ not be valid - * - * Returns list of attributes on success and NULL on failure - */ -struct dlist *sysfs_refresh_bus_attributes(struct sysfs_bus *bus) -{ - if (bus == NULL) { - errno = EINVAL; - return NULL; - } - - if (bus->directory == NULL) - return (sysfs_get_bus_attributes(bus)); - - if ((sysfs_refresh_dir_attributes(bus->directory)) != 0) { - dprintf("Error refreshing bus attributes\n"); - return NULL; - } - - return (bus->directory->attributes); -} - -/** - * sysfs_get_bus_attribute: gets a specific bus attribute, if buses had - * attributes. - * @bus: bus to retrieve attribute from - * @attrname: attribute name to retrieve - * returns reference to sysfs_attribute if found or NULL if not found - */ -struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, - char *attrname) -{ - struct dlist *attrlist = NULL; - - if (bus == NULL) { - errno = EINVAL; - return NULL; - } - attrlist = sysfs_get_bus_attributes(bus); - if (attrlist == NULL) - return NULL; - - return sysfs_get_directory_attribute(bus->directory, attrname); -} - -/** - * sysfs_find_driver_bus: locates the bus the driver is on. - * @driver: name of the driver to locate - * @busname: buffer to copy name to - * @bsize: buffer size - * returns 0 with success, -1 with error - */ -int sysfs_find_driver_bus(const char *driver, char *busname, size_t bsize) -{ - char subsys[SYSFS_PATH_MAX], *bus = NULL, *curdrv = NULL; - struct dlist *buslist = NULL, *drivers = NULL; - - if (driver == NULL || busname == NULL) { - errno = EINVAL; - return -1; - } - - memset(subsys, 0, SYSFS_PATH_MAX); - safestrcpy(subsys, SYSFS_BUS_NAME); - buslist = sysfs_open_subsystem_list(subsys); - if (buslist != NULL) { - dlist_for_each_data(buslist, bus, char) { - memset(subsys, 0, SYSFS_PATH_MAX); - safestrcpy(subsys, SYSFS_BUS_NAME); - safestrcat(subsys, "/"); - safestrcat(subsys, bus); - safestrcat(subsys, "/"); - safestrcat(subsys, SYSFS_DRIVERS_NAME); - drivers = sysfs_open_subsystem_list(subsys); - if (drivers != NULL) { - dlist_for_each_data(drivers, curdrv, char) { - if (strcmp(driver, curdrv) == 0) { - safestrcpymax(busname, - bus, bsize); - sysfs_close_list(drivers); - sysfs_close_list(buslist); - return 0; - } - } - sysfs_close_list(drivers); - } - } - sysfs_close_list(buslist); - } - return -1; -} From 67747e1de37158cd58782f432ccba8db55251592 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 17 Mar 2005 09:59:32 +0100 Subject: [PATCH 1246/4284] [PATCH] change call_foreach_file to return a list --- udev_multiplex.c | 16 ++++++++++++---- udev_rules_parse.c | 17 +++++++++++++---- udev_utils.c | 23 +++++------------------ udev_utils.h | 4 ++-- 4 files changed, 32 insertions(+), 28 deletions(-) diff --git a/udev_multiplex.c b/udev_multiplex.c index 3ef6e1707a..9ab11e6bea 100644 --- a/udev_multiplex.c +++ b/udev_multiplex.c @@ -74,6 +74,8 @@ static int run_program(struct udevice *udev, const char *filename) void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix) { char dirname[PATH_SIZE]; + struct name_entry *name_loop, *name_tmp; + LIST_HEAD(name_list); /* chop the device name up into pieces based on '/' */ if (udev->name[0] != '\0') { @@ -89,7 +91,7 @@ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const c if (strcmp(devname, udev->subsystem) != 0) { snprintf(dirname, sizeof(dirname), "%s/%s", basedir, devname); dirname[sizeof(dirname)-1] = '\0'; - call_foreach_file(run_program, udev, dirname, suffix); + add_matching_files(&name_list, dirname, suffix); } temp[0] = '/'; @@ -101,16 +103,22 @@ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const c if (udev->name[0] != '\0') { snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->name); dirname[sizeof(dirname)-1] = '\0'; - call_foreach_file(run_program, udev, dirname, suffix); + add_matching_files(&name_list, dirname, suffix); } if (udev->subsystem[0] != '\0') { snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->subsystem); dirname[sizeof(dirname)-1] = '\0'; - call_foreach_file(run_program, udev, dirname, suffix); + add_matching_files(&name_list, dirname, suffix); } snprintf(dirname, sizeof(dirname), "%s/default", basedir); dirname[sizeof(dirname)-1] = '\0'; - call_foreach_file(run_program, udev, dirname, suffix); + add_matching_files(&name_list, dirname, suffix); + + list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { + run_program(udev, name_loop->name); + list_del(&name_loop->node); + } + } diff --git a/udev_rules_parse.c b/udev_rules_parse.c index face496ab3..55412dba3c 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -168,7 +168,7 @@ static char *get_key_attribute(char *str) return NULL; } -static int rules_parse(struct udevice *udev, const char *filename) +static int rules_parse(const char *filename) { char line[LINE_SIZE]; char *bufline; @@ -446,9 +446,18 @@ int udev_rules_init(void) return -1; if ((stats.st_mode & S_IFMT) != S_IFDIR) - retval = rules_parse(NULL, udev_rules_filename); - else - retval = call_foreach_file(rules_parse, NULL, udev_rules_filename, RULEFILE_SUFFIX); + retval = rules_parse(udev_rules_filename); + else { + struct name_entry *name_loop, *name_tmp; + LIST_HEAD(name_list); + + retval = add_matching_files(&name_list, udev_rules_filename, RULEFILE_SUFFIX); + + list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { + rules_parse(name_loop->name); + list_del(&name_loop->node); + } + } return retval; } diff --git a/udev_utils.c b/udev_utils.c index c6658e6933..2b5683fda6 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -265,15 +265,12 @@ int name_list_add(struct list_head *name_list, const char *name, int sort) } /* calls function for every file found in specified directory */ -int call_foreach_file(int (*handler_function)(struct udevice *udev, const char *string), - struct udevice *udev, const char *dirname, const char *suffix) +int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix) { struct dirent *ent; DIR *dir; char *ext; - struct name_entry *loop_file; - struct name_entry *tmp_file; - LIST_HEAD(file_list); + char filename[PATH_SIZE]; dbg("open directory '%s'", dirname); dir = opendir(dirname); @@ -290,7 +287,7 @@ int call_foreach_file(int (*handler_function)(struct udevice *udev, const char * if ((ent->d_name[0] == '.') || (ent->d_name[0] == COMMENT_CHARACTER)) continue; - /* look for file with specified suffix */ + /* look for file matching with specified suffix */ ext = strrchr(ent->d_name, '.'); if (ext == NULL) continue; @@ -299,20 +296,10 @@ int call_foreach_file(int (*handler_function)(struct udevice *udev, const char * continue; dbg("put file '%s/%s' in list", dirname, ent->d_name); - name_list_add(&file_list, ent->d_name, 1); - } - /* call function for every file in the list */ - list_for_each_entry_safe(loop_file, tmp_file, &file_list, node) { - char filename[PATH_SIZE]; - - snprintf(filename, sizeof(filename), "%s/%s", dirname, loop_file->name); + snprintf(filename, sizeof(filename), "%s/%s", dirname, ent->d_name); filename[sizeof(filename)-1] = '\0'; - - handler_function(udev, filename); - - list_del(&loop_file->node); - free(loop_file); + name_list_add(name_list, filename, 1); } closedir(dir); diff --git a/udev_utils.h b/udev_utils.h index c7a41aaa44..b45500dcff 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -41,6 +41,6 @@ extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); extern void no_trailing_slash(char *path); extern int name_list_add(struct list_head *name_list, const char *name, int sort); -extern int call_foreach_file(int (*handler_function)(struct udevice *udev, const char *string), - struct udevice *udev, const char *dirname, const char *suffix); +extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); + #endif From 92ebb398ed004348d5f92a242f323fb25dc7d6e5 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 17 Mar 2005 11:02:53 +0100 Subject: [PATCH 1247/4284] [PATCH] klibc: use klcc wrapper instead of our own Makefile --- Makefile | 91 ++++++++++++++++----------------------- extras/volume_id/Makefile | 4 +- 2 files changed, 38 insertions(+), 57 deletions(-) diff --git a/Makefile b/Makefile index 2be255ef27..63d33d36ec 100644 --- a/Makefile +++ b/Makefile @@ -89,7 +89,7 @@ STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib HOSTCC = gcc -export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH_LIB_OBJS CRT0 +export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS # code taken from uClibc to determine the current arch ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ @@ -108,11 +108,11 @@ OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2> # check if compiler option is supported cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;} -WARNINGS := -Wall -fno-builtin -Wchar-subscripts -Wpointer-arith -Wstrict-prototypes -Wsign-compare -WARNINGS += $(call cc-supports,-Wno-pointer-sign) -WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) - -CFLAGS := -pipe +CFLAGS += -Wall -fno-builtin -Wchar-subscripts -Wpointer-arith -Wstrict-prototypes -Wsign-compare +CFLAGS += $(call cc-supports,-Wno-pointer-sign) +CFLAGS += $(call cc-supports,-Wdeclaration-after-statement) +CFLAGS += -pipe +CFLAGS += -D_GNU_SOURCE HEADERS = \ udev.h \ @@ -161,42 +161,25 @@ endif # if DEBUG is enabled, then we do not strip or optimize ifeq ($(strip $(DEBUG)),true) - CFLAGS += -O1 -g -DDEBUG -D_GNU_SOURCE - LDFLAGS += -Wl,-warn-common + CFLAGS += -O1 -g -DDEBUG + LDFLAGS += -Wl STRIPCMD = /bin/true -Since_we_are_debugging else - CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer -D_GNU_SOURCE - LDFLAGS += -s -Wl,-warn-common + CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer + LDFLAGS += -s -Wl STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif # If we are using our version of klibc, then we need to build, link it, and then # link udev against it statically. Otherwise, use glibc and link dynamically. ifeq ($(strip $(USE_KLIBC)),true) - KLIBC_BASE = $(PWD)/klibc - KLIBC_DIR = $(KLIBC_BASE)/klibc - INCLUDE_DIR := $(KLIBC_BASE)/include - LINUX_INCLUDE_DIR := $(KERNEL_DIR)/include - include $(KLIBC_DIR)/arch/$(ARCH)/MCONFIG - ARCH_LIB_OBJS = $(KLIBC_DIR)/libc.a - CRT0 = $(KLIBC_DIR)/crt0.o - LIBC = $(ARCH_LIB_OBJS) $(LIB_OBJS) $(CRT0) - CFLAGS += $(WARNINGS) -nostdinc \ - $(OPTFLAGS) $(REQFLAGS) \ - -D__KLIBC__ -fno-builtin-printf \ - -I$(INCLUDE_DIR) \ - -I$(INCLUDE_DIR)/arch/$(ARCH) \ - -I$(INCLUDE_DIR)/bits$(BITSIZE) \ - -I$(GCCINCDIR) \ - -I$(LINUX_INCLUDE_DIR) - LIB_OBJS = - LDFLAGS = -static -nostdlib -nostartfiles -nodefaultlibs + KLIBC_INSTALL = $(PWD)/klibc/.install + KLCC = $(KLIBC_INSTALL)/bin/klcc + CC = $(KLCC) + LD = $(KLCC) + LDFLAGS += -static else - WARNINGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations - CRT0 = - LIBC = - CFLAGS += $(WARNINGS) -I$(GCCINCDIR) - LIB_OBJS = -lc + CFLAGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations endif ifeq ($(strip $(USE_SELINUX)),true) @@ -221,7 +204,7 @@ endif # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) +all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -232,13 +215,12 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) -C $$target $@ ; \ done ; \ -$(ARCH_LIB_OBJS) : $(CRT0) - -$(CRT0): - @if [ ! -r klibc/linux ]; then \ - ln -f -s $(KERNEL_DIR) klibc/linux; \ - fi - $(MAKE) -C klibc SUBDIRS=klibc TESTS= +$(KLCC): + $(MAKE) -C klibc KRNLSRC=$(KERNEL_DIR) SUBDIRS=klibc TESTS= \ + SHLIBDIR=$(KLIBC_INSTALL)/lib \ + INSTALLDIR=$(KLIBC_INSTALL) \ + bindir=$(KLIBC_INSTALL)/bin \ + mandir=$(KLIBC_INSTALL)/man all install udev.a: $(UDEV_OBJS) rm -f $@ @@ -290,34 +272,33 @@ $(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS) $(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) -$(ROOT): $(LIBC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(ROOT).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(ROOT).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -$(TESTER): $(LIBC) $(TESTER).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(TESTER).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(TESTER): $(KLCC) $(TESTER).o $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(TESTER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -$(INFO): $(LIBC) $(INFO).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(INFO).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(INFO): $(KLCC) $(INFO).o $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(INFO).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -$(DAEMON): $(LIBC) $(DAEMON).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(DAEMON).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(DAEMON): $(KLCC) $(DAEMON).o $(OBJS) udevd.h + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(DAEMON).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -$(SENDER): $(LIBC) $(SENDER).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(SENDER).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(SENDER): $(KLCC) $(SENDER).o $(OBJS) udevd.h + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(SENDER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -$(STARTER): $(LIBC) $(STARTER).o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CRT0) $(STARTER).o $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) +$(STARTER): $(KLCC) $(STARTER).o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(STARTER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ .c.o: $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< - clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f @@ -333,7 +314,7 @@ clean: spotless: clean $(MAKE) -C klibc SUBDIRS=klibc spotless - -rm -f klibc/linux + rm -rf klibc/.install DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz" -e "\/\." -e releases -e BitKeeper -e SCCS -e test/sys | sort ) DISTDIR := $(RELEASE_NAME) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index efec58f80e..91527cc9f5 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE +override CFLAGS+=-D_FILE_OFFSET_BITS=64 VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc @@ -42,7 +42,7 @@ $(OBJS): $(HEADERS) $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< $(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) clean: rm -f $(PROG) $(OBJS) From 7f7ae03a6290ccc1e4ca57416fe871dae4b865d2 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Thu, 17 Mar 2005 11:51:37 +0100 Subject: [PATCH 1248/4284] [PATCH] udevd: don't delay events with TIMEOUT in the environment On Tue, 2005-03-15 at 09:25 +0100, Hannes Reinecke wrote: > The current implementation of the firmware class breaks a fundamental > assumption in udevd: that the physical device can be initialised fully > prior to executing the next event for that device. Thanks to Hannes for the patch. --- RELEASE-NOTES | 6 ++++++ udevd.c | 15 +++++++++++++++ udevd.h | 1 + 3 files changed, 22 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 0bddab4189..2defd7117b 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,9 @@ +udev 056 +======== +Possible use of a system-wide klibc: + make USE_KLIB=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. diff --git a/udevd.c b/udevd.c index 2cd3622ce0..6e27c8a0d1 100644 --- a/udevd.c +++ b/udevd.c @@ -113,6 +113,14 @@ static void msg_queue_insert(struct hotplug_msg *msg) return; } + /* don't delay messages with timeout set */ + if (msg->timeout) { + dbg("move seq %llu with timeout %u to exec queue", msg->seqnum, msg->timeout); + list_add(&msg->node, &exec_list); + run_exec_q = 1; + return; + } + /* sort message by sequence number into list */ list_for_each_entry_reverse(loop_msg, &msg_list, node) { if (loop_msg->seqnum < msg->seqnum) @@ -293,6 +301,10 @@ static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) if (msg->devpath == NULL) return NULL; + /* skip any events with a timeout set */ + if (msg->timeout) + return NULL; + list_for_each_entry(loop_msg, &running_list, node) { if (loop_msg->devpath == NULL) continue; @@ -490,6 +502,9 @@ static struct hotplug_msg *get_udevsend_msg(void) if (strncmp(key, "PHYSDEVPATH=", 12) == 0) msg->physdevpath = &key[12]; + + if (strncmp(key, "TIMEOUT=", 8) == 0) + msg->timeout = strtoull(&key[8], NULL, 10); } msg->envp[i++] = "UDEVD_EVENT=1"; msg->envp[i] = NULL; diff --git a/udevd.h b/udevd.h index 64e1d6ad12..b3e998b04c 100644 --- a/udevd.h +++ b/udevd.h @@ -60,6 +60,7 @@ struct hotplug_msg { char *subsystem; unsigned long long seqnum; char *physdevpath; + unsigned int timeout; char *envp[HOTPLUG_NUM_ENVP+1]; char envbuf[]; }; From a5b9e2994a6d34cb169eaa0e2cf16d0a7c4f197a Mon Sep 17 00:00:00 2001 From: "tklauser@access.unizh.ch" Date: Fri, 18 Mar 2005 09:27:31 +0100 Subject: [PATCH 1249/4284] [PATCH] fix header paths in udev_libc_wrapper.c In udev_libc_wrapper.c the paths to the local header files are wrong. The attached patch fixes this. --- udev_libc_wrapper.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index 0dafe4d077..4b39b6f476 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -27,10 +27,10 @@ #include #include -#include "../udev_libc_wrapper.h" -#include "../udev.h" -#include "../udev_utils.h" -#include "../logging.h" +#include "udev_libc_wrapper.h" +#include "udev.h" +#include "udev_utils.h" +#include "logging.h" #ifdef __KLIBC__ #define __OWN_USERDB_PARSER__ From 68c2c0b5b1dedfe0fd3346560999791efdf48c25 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 18 Mar 2005 10:00:25 +0100 Subject: [PATCH 1250/4284] [PATCH] fix bad typo that prevents the GROUP to be applied Thanks to Jim Gifford for catching it. --- udev_add.c | 2 +- udev_libc_wrapper.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/udev_add.c b/udev_add.c index 8443f65e7c..15c6bf9fbc 100644 --- a/udev_add.c +++ b/udev_add.c @@ -150,7 +150,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de if (endptr[0] == '\0') gid = (gid_t) id; else - gid = lookup_user(udev->group); + gid = lookup_group(udev->group); } if (!udev->test_run) { diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index 4b39b6f476..16d90913cf 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -140,7 +140,7 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) dbg("can't open '%s' as db file", dbfile); return 0; } - dbg("reading '%s' as db file", dbfile); + dbg("search '%s' in '%s'", uname, dbfile); /* loop through the whole file */ cur = 0; From 9b434de102c8d4f74842bc6533c92cb3a4887d8d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 18 Mar 2005 23:52:41 +0100 Subject: [PATCH 1251/4284] [PATCH] udev-test.pl: add check for textual uid/gid --- test/udev-test.pl | 87 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 63 insertions(+), 24 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 2ece431735..0f010991ac 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -553,6 +553,26 @@ EOF exp_perms => ":100:0660", conf => < "textual user id", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "adm::0660", + conf => < "textual group id", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => ":daemon:0660", + conf => <{exp_perms} =~ m/^(.*):(.*):(.*)$/; if ($1 ne "") { - if ($uid != $1) { $wrong = 1; }; + if (defined(getpwnam($1))) { + $userid = int(getpwnam($1)); + } else { + $userid = $1; + } + if ($uid != $userid) { $wrong = 1; } } if ($2 ne "") { - if ($gid != $2) { $wrong = 1; }; + 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 "; + print "permissions: ok\n"; } else { - printf "expected permissions are: %i:%i:%#o\n", $1, $2, oct($3); - printf "created permissions are : %i:%i:%#o\n", $uid, $gid, $mode & 07777; + 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++; } } @@ -1249,11 +1283,11 @@ sub major_minor_test { if ($minor != $2) { $wrong = 1; }; } if ($wrong == 0) { - print "major:minor: ok "; + 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 "; + 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++; } } @@ -1265,22 +1299,25 @@ sub symlink_test { if ($output =~ m/(.*)-> (.*)/) { if ($2 eq $config->{exp_target}) { - print "symlink: ok "; + print "symlink: ok\n"; } else { - print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; - print "created symlink from: \'$config->{exp_name}\' to \'$2\'\n"; + print " expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; + print " created symlink from: \'$config->{exp_name}\' to \'$2\'\n"; + print "symlink: error"; if ($config->{exp_add_error}) { - print "as expected "; + print " as expected\n"; } else { + print "\n"; $error++; } } } else { - print "expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; - print "symlink: not created "; + print " expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; + print "symlink: not created"; if ($config->{exp_add_error}) { - print "as expected "; + print " as expected\n"; } else { + print "\n"; $error++; } } @@ -1314,13 +1351,13 @@ sub run_test { if (defined($config->{exp_target})) { symlink_test($config); } - print "add: ok "; + print "add: ok\n"; } else { - print "add: error "; + print "add: error"; if ($config->{exp_add_error}) { - print "as expected "; + print " as expected\n"; } else { - print "\n\n"; + print "\n"; system("tree $udev_root"); print "\n"; $error++; @@ -1335,19 +1372,21 @@ sub run_test { udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf}); if ((-e "$PWD/$udev_root$config->{exp_name}") || (-l "$PWD/$udev_root$config->{exp_name}")) { - print "remove: error "; + print "remove: error"; if ($config->{exp_rem_error}) { - print "as expected\n\n"; + print " as expected\n"; } else { - print "\n\n"; + print "\n"; system("tree $udev_root"); print "\n"; $error++; } } else { - print "remove: ok\n\n"; + print "remove: ok\n"; } + print "\n"; + if (defined($config->{option}) && $config->{option} eq "clear") { system("rm -rf $udev_db"); system("rm -rf $udev_root"); From c827876312bde7809f5f08b89b9223391da0e3b4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 19 Mar 2005 01:45:03 +0100 Subject: [PATCH 1252/4284] [PATCH] udev-test.pl: add a test where the group cannot be found in /etc/passwd --- test/udev-test.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 0f010991ac..11d1d2877b 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -573,6 +573,16 @@ EOF exp_perms => ":daemon:0660", conf => < "textual user/group id", + subsys => "block", + devpath => "/block/sda", + exp_name => "node", + exp_perms => "root:wheel:0660", + conf => < Date: Sat, 19 Mar 2005 02:15:43 +0100 Subject: [PATCH 1253/4284] [PATCH] klibc: remove SCCS directories from the temporary klibc install --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 63d33d36ec..97d20b2146 100644 --- a/Makefile +++ b/Makefile @@ -221,6 +221,7 @@ $(KLCC): INSTALLDIR=$(KLIBC_INSTALL) \ bindir=$(KLIBC_INSTALL)/bin \ mandir=$(KLIBC_INSTALL)/man all install + -find $(KLIBC_INSTALL)/include -name SCCS -print| xargs rm -rf udev.a: $(UDEV_OBJS) rm -f $@ From 0bb438770742815c5839f3fbf1aca967fa6e4a15 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 19 Mar 2005 03:11:48 +0100 Subject: [PATCH 1254/4284] [PATCH] udev-test.pl: use more common user/group names --- test/udev-test.pl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 11d1d2877b..6cde54ffab 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -560,9 +560,9 @@ EOF subsys => "block", devpath => "/block/sda", exp_name => "node", - exp_perms => "adm::0660", + exp_perms => "nobody::0660", conf => < "block", devpath => "/block/sda", exp_name => "node", - exp_perms => "root:wheel:0660", + exp_perms => "root:mail:0660", conf => < Date: Sat, 19 Mar 2005 07:39:19 -0800 Subject: [PATCH 1255/4284] [PATCH] 056 release --- ChangeLog | 17 +++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c1ee1f889..c7d7269400 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 97d20b2146..1424cf0315 100644 --- a/Makefile +++ b/Makefile @@ -45,7 +45,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 055 +VERSION = 056 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index 3a03099799..a9d1c5fb22 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 055 +Version: 056 Release: 1 License: GPL Group: Utilities/System From 93ca11e4be8f4414f09ba60d9d8c77ec8ff2ec3b Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 00:09:05 +0100 Subject: [PATCH 1256/4284] [PATCH] libsysfs: remove trailing slash on SYSFS_PATH override --- libsysfs/sysfs/libsysfs.h | 6 +++--- libsysfs/sysfs_utils.c | 15 ++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index 6140c3aecb..2f122405d7 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -43,14 +43,14 @@ #define SYSFS_NAME_LEN 64 #define SYSFS_BUS_ID_SIZE 32 +/* mount path for sysfs, can be overridden by exporting SYSFS_PATH */ +#define SYSFS_MNT_PATH "/sys" + enum sysfs_attribute_method { SYSFS_METHOD_SHOW = 0x01, /* attr can be read by user */ SYSFS_METHOD_STORE = 0x02, /* attr can be changed by user */ }; -/* NOTE: statically define mnt path for sysfs */ -#define SYSFS_MNT_PATH "/sys" - /* * NOTE: * 1. We have the statically allocated "name" as the first element of all diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 9f6e18f665..210c2a086d 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -30,20 +30,16 @@ */ int sysfs_remove_trailing_slash(char *path) { - char *c = NULL; + size_t len; if (!path) { errno = EINVAL; return 1; } - c = strrchr(path, '/'); - if (c == NULL) { - dprintf("Invalid path %s\n", path); - errno = EINVAL; - return 1; - } - if (*(c+1) == '\0') - *c = '\0'; + + len = strlen(path); + while (len > 0 && path[len-1] == '/') + path[--len] = '\0'; return 0; } @@ -64,6 +60,7 @@ int sysfs_get_mnt_path(char *mnt_path, size_t len) sysfs_path_env = getenv(SYSFS_PATH_ENV); if (sysfs_path_env != NULL) { safestrcpymax(mnt_path, sysfs_path_env, len); + sysfs_remove_trailing_slash(mnt_path); return 0; } safestrcpymax(mnt_path, SYSFS_MNT_PATH, len); From 65005a7f81f86590f7f03bd3d4019c485d0e3c77 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 00:10:03 +0100 Subject: [PATCH 1257/4284] [PATCH] test-suite: remove UDEV_TEST, it's not needed anymore --- test/devd_test | 1 - test/net_test | 1 - test/replace_test | 1 - test/udev-test.pl | 354 ++++++++++++++++++++--------------------- test/udevstart-test.pl | 31 ++-- udev_config.c | 18 +-- 6 files changed, 199 insertions(+), 207 deletions(-) diff --git a/test/devd_test b/test/devd_test index 269c2b11da..534e787f24 100644 --- a/test/devd_test +++ b/test/devd_test @@ -3,7 +3,6 @@ RULES=label_test.rules CONFIG=label_test.conf -export UDEV_TEST=yes export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG diff --git a/test/net_test b/test/net_test index 9686f99258..9daf8da082 100644 --- a/test/net_test +++ b/test/net_test @@ -3,7 +3,6 @@ RULES=label_test.rules CONFIG=label_test.conf -export UDEV_TEST=yes export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG diff --git a/test/replace_test b/test/replace_test index 19260765ba..6e01f28ed5 100644 --- a/test/replace_test +++ b/test/replace_test @@ -3,7 +3,6 @@ RULES=replace_test.rules CONFIG=replace_test.conf -export UDEV_TEST=yes export SYSFS_PATH=$PWD/sys/ export UDEV_CONFIG_FILE=$PWD/$CONFIG diff --git a/test/udev-test.pl b/test/udev-test.pl index 6cde54ffab..50ea5858a4 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -9,7 +9,7 @@ # Every test is driven by its own temporary config file. # This program prepares the environment, creates the config and calls udev. # -# udev reads the config, looks at the provided sysfs and +# 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. @@ -20,13 +20,13 @@ use warnings; use strict; -my $PWD = $ENV{PWD}; -my $sysfs = "sys/"; -my $udev_bin = "../udev"; -my $udev_root = "udev-root/"; # !!! directory will be removed !!! -my $udev_db = ".udevdb"; -my $main_conf = "udev-test.conf"; -my $conf_tmp = "udev-test.rules"; +my $PWD = $ENV{PWD}; +my $sysfs = "sys/"; +my $udev_bin = "../udev"; +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"; # uncomment following line to run udev with valgrind. # Should make this a runtime option to the script someday... @@ -38,7 +38,7 @@ my @tests = ( subsys => "block", devpath => "/block/sda", exp_name => "boot_disk" , - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "boot_disk1" , - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "boot_disk1" , - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "boot_disk1" , - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "boot_disk1" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor/0" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "whitespace" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "aaa", - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "sub/direct/ory/visor" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "first_disk3" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "M8-m3-n3-b0:0-sIBM" , - conf => < < "block", devpath => "/block/sda", exp_name => "disk-IBM-ESXS-sda" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "special-device-3" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "subsys_block" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "newline_removed" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "test-0:0:0:0" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "escape-3" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "foo9" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "bar9" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "foo7" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "my-foo9" , - conf => < < "block", devpath => "/block/sda/sda3", exp_name => "my-foo8" , - conf => < < "tty", devpath => "/class/tty/console", exp_name => "TTY" , - conf => < < "tty", devpath => "/class/tty/console", exp_name => "foo" , - conf => < < "tty", devpath => "/class/tty/console", exp_name => "TTY" , - conf => < < "tty", devpath => "/class/tty/console", exp_name => "foo" , - conf => < < "block", devpath => "/block/sda", exp_name => "scsi-0:0:0:0" , - conf => < < "block", devpath => "/block/sda", exp_name => "boot_disk15" , - conf => < < "tty", devpath => "/class/tty/ttyUSB0", exp_name => "visor" , - conf => < < "block", devpath => "/block/rd!c0d0", exp_name => "rd/c0d0" , - conf => < < "block", devpath => "/block/rd!c0d0", exp_name => "rd/c0d0" , - conf => < < "block", devpath => "/block/cciss!c0d0/cciss!c0d0p1", exp_name => "cciss/c0d0p1" , - conf => < < "block", devpath => "/block/sda", exp_name => "scsi-0:0:0:0", - conf => < < "block", devpath => "/block/sda", exp_name => "scsi-0:0:0:0", - conf => < < "block", devpath => "/block/sda", exp_name => "scsi-0:0:0:0", - conf => < < "block", devpath => "/block/sda", exp_name => "scsi-0:0:0:0", - conf => < < "block", devpath => "/block/sda", exp_name => "ignored", - conf => < < "block", devpath => "/block/sda", exp_name => "matched-with-space", - conf => < < "/class/tty/tty33", exp_name => "tty33", exp_perms => "0:0:0660", - conf => < < "/block/sda", exp_name => "node", exp_perms => "5000::0660", - conf => < < "/block/sda", exp_name => "node", exp_perms => ":100:0660", - conf => < < "/block/sda", exp_name => "node", exp_perms => "nobody::0660", - conf => < < "/block/sda", exp_name => "node", exp_perms => ":daemon:0660", - conf => < < "/block/sda", exp_name => "node", exp_perms => "root:mail:0660", - conf => < < "/block/sda", exp_name => "node", exp_perms => "::0777", - conf => < < "/block/sda", exp_name => "node", exp_perms => "5000:100:0777", - conf => < < "/class/tty/ttyUSB0", exp_name => "ttyUSB0", exp_perms => "5000::", - conf => < < "/class/tty/ttyUSB0", exp_name => "ttyUSB0", exp_perms => ":100:0660", - conf => < < "/class/tty/ttyUSB0", exp_name => "ttyUSB0", exp_perms => "::0060", - conf => < < "/class/tty/ttyUSB0", exp_name => "ttyUSB0", exp_perms => "5000:100:0777", - conf => < < "/class/tty/ttyUSB0", exp_name => "ttyUSB0", exp_perms => "5000:100:0777", - conf => < < "/class/tty/ttyUSB0", exp_name => "ttyUSB0", exp_perms => "3000:4000:0777", - conf => < < "/class/tty/ttyUSB0", exp_name => "ttyUSB0", exp_perms => "3000:8000:0777", - conf => < < "/block/sda", exp_name => "node", exp_majorminor => "8:0", - conf => < < "/class/i2c-dev/i2c-300", exp_name => "node", exp_majorminor => "89:300", - conf => < < "/class/i2c-dev/i2c-fake1", exp_name => "node", exp_majorminor => "4095:1", - conf => < < "/class/i2c-dev/i2c-fake2", exp_name => "node", exp_majorminor => "4094:89999", - conf => < < "/class/tty/ttyUSB0", exp_name => "symlink2-ttyUSB0", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "visor0", exp_target => "ttyUSB0", - conf => < < "/block/sda/sda2", exp_name => "1/2/symlink" , exp_target => "a/b/node", - conf => < < "/block/sda/sda2", exp_name => "1/2/c/d/symlink" , exp_target => "../../a/b/node", - conf => < < "/class/tty/ttyUSB0", exp_name => "second-0" , exp_target => "visor" , - conf => < < "/block/sda", exp_name => "symlink-only2", exp_target => "link", - conf => < < "link", exp_add_error => "yes", exp_rem_error => "yes", - conf => < < "link", exp_rem_error => "yes", option => "clear", - conf => < < "/class/tty/ttyUSB0", exp_name => "symlink0", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "symlink-ttyUSB0", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "major-188:0", exp_target => "ttyUSB0", - conf => < < "/block/sda", exp_name => "symlink-0:0:0:0", exp_target => "node", - conf => < < "/class/tty/ttyUSB0", exp_name => "test", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "test", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "this", exp_target => "ttyUSB0", - conf => < < "/block/sda", exp_name => "test", exp_target => "link", - conf => < < "/class/tty/ttyUSB0", exp_name => "188:0", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "188", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "percent%sign", exp_target => "ttyUSB0", - conf => < < "/class/tty/ttyUSB0", exp_name => "%ttyUSB0_name", exp_target => "ttyUSB0", - conf => < < "/block/sda/sda3", exp_name => "link1", exp_target => "node", - conf => < < "/block/sda/sda3", exp_name => "link4", exp_target => "node", - conf => < < "block", devpath => "/block/sda", exp_name => "cdrom", - conf => < < "/block/sda", exp_name => "cdrom", option => "keep", - conf => < < "/block/sda/sda1", exp_name => "enum", option => "keep", - conf => < < "/block/sda/sda2", exp_name => "cdrom1", option => "keep", - conf => < < "/block/sda/sda3", exp_name => "enum1", option => "keep", - conf => < < "/block/sda/sda4", exp_name => "cdrom2", option => "clear", - conf => < < "block", devpath => "/block/sda", exp_name => "cdrom", - conf => < < "/block/sda", exp_name => "node", exp_add_error => "yes", - conf => < < "block", devpath => "/block/sda", exp_name => "node6", - conf => < < "/block/sda/sda1", exp_name => "node6", exp_add_error => "yes", - conf => < < "/block/sda", exp_name => "node", exp_rem_error => "yes", - conf => < < "node14", exp_rem_error => "yes", option => "clear", - conf => < < "block", devpath => "/block/sda", exp_name => "node", - conf => < < "block", devpath => "/block/sda", exp_name => "node", - conf => < < "block", devpath => "/block/sda", exp_name => "node", - conf => < < "block", devpath => "/block/sda", exp_name => "sda", - conf => < < "/block/sda", exp_name => "main_device", option => "keep", - conf => < < "/block/sda/sda1", exp_name => "main_device-part-1", option => "clean", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "start-udev-root-end", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "last", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "match", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "not-anything", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "nonzero-program", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "true", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "true", - conf => < < "block", devpath => "/block/sda/sda1", exp_name => "true", - conf => < <$conf_tmp" || die "unable to create config file: $conf_tmp"; - print CONF $$config; + # create temporary rules + open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules"; + print CONF $$rules; close CONF; $ENV{ACTION} = $action; @@ -1242,13 +1242,13 @@ sub udev { my $error = 0; sub permissions_test { - my($config, $uid, $gid, $mode) = @_; + my($rules, $uid, $gid, $mode) = @_; my $wrong = 0; my $userid; my $groupid; - $config->{exp_perms} =~ m/^(.*):(.*):(.*)$/; + $rules->{exp_perms} =~ m/^(.*):(.*):(.*)$/; if ($1 ne "") { if (defined(getpwnam($1))) { $userid = int(getpwnam($1)); @@ -1279,13 +1279,13 @@ sub permissions_test { } sub major_minor_test { - my($config, $rdev) = @_; + my($rules, $rdev) = @_; my $major = ($rdev >> 8) & 0xfff; my $minor = ($rdev & 0xff) | (($rdev >> 12) & 0xfff00); my $wrong = 0; - $config->{exp_majorminor} =~ m/^(.*):(.*)$/; + $rules->{exp_majorminor} =~ m/^(.*):(.*)$/; if ($1 ne "") { if ($major != $1) { $wrong = 1; }; } @@ -1303,18 +1303,18 @@ sub major_minor_test { } sub symlink_test { - my ($config) = @_; + my ($rules) = @_; - my $output = `ls -l $PWD/$udev_root$config->{exp_name}`; + my $output = `ls -l $PWD/$udev_root$rules->{exp_name}`; if ($output =~ m/(.*)-> (.*)/) { - if ($2 eq $config->{exp_target}) { + if ($2 eq $rules->{exp_target}) { print "symlink: ok\n"; } else { - print " expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; - print " created symlink from: \'$config->{exp_name}\' to \'$2\'\n"; + 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 ($config->{exp_add_error}) { + if ($rules->{exp_add_error}) { print " as expected\n"; } else { print "\n"; @@ -1322,9 +1322,9 @@ sub symlink_test { } } } else { - print " expected symlink from: \'$config->{exp_name}\' to \'$config->{exp_target}\'\n"; + print " expected symlink from: \'$rules->{exp_name}\' to \'$rules->{exp_target}\'\n"; print "symlink: not created"; - if ($config->{exp_add_error}) { + if ($rules->{exp_add_error}) { print " as expected\n"; } else { print "\n"; @@ -1334,37 +1334,37 @@ sub symlink_test { } sub run_test { - my ($config, $number) = @_; + my ($rules, $number) = @_; - print "TEST $number: $config->{desc}\n"; + print "TEST $number: $rules->{desc}\n"; - if ($config->{exp_target}) { - print "device \'$config->{devpath}\' expecting symlink '$config->{exp_name}' to node \'$config->{exp_target}\'\n"; + if ($rules->{exp_target}) { + print "device \'$rules->{devpath}\' expecting symlink '$rules->{exp_name}' to node \'$rules->{exp_target}\'\n"; } else { - print "device \'$config->{devpath}\' expecting node \'$config->{exp_name}\'\n"; + print "device \'$rules->{devpath}\' expecting node \'$rules->{exp_name}\'\n"; } - udev("add", $config->{subsys}, $config->{devpath}, \$config->{conf}); - if ((-e "$PWD/$udev_root$config->{exp_name}") || - (-l "$PWD/$udev_root$config->{exp_name}")) { + 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$config->{exp_name}"); + $atime, $mtime, $ctime, $blksize, $blocks) = stat("$PWD/$udev_root$rules->{exp_name}"); - if (defined($config->{exp_perms})) { - permissions_test($config, $uid, $gid, $mode); + if (defined($rules->{exp_perms})) { + permissions_test($rules, $uid, $gid, $mode); } - if (defined($config->{exp_majorminor})) { - major_minor_test($config, $rdev); + if (defined($rules->{exp_majorminor})) { + major_minor_test($rules, $rdev); } - if (defined($config->{exp_target})) { - symlink_test($config); + if (defined($rules->{exp_target})) { + symlink_test($rules); } print "add: ok\n"; } else { print "add: error"; - if ($config->{exp_add_error}) { + if ($rules->{exp_add_error}) { print " as expected\n"; } else { print "\n"; @@ -1374,16 +1374,16 @@ sub run_test { } } - if (defined($config->{option}) && $config->{option} eq "keep") { + if (defined($rules->{option}) && $rules->{option} eq "keep") { print "\n\n"; return; } - udev("remove", $config->{subsys}, $config->{devpath}, \$config->{conf}); - if ((-e "$PWD/$udev_root$config->{exp_name}") || - (-l "$PWD/$udev_root$config->{exp_name}")) { + 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 ($config->{exp_rem_error}) { + if ($rules->{exp_rem_error}) { print " as expected\n"; } else { print "\n"; @@ -1397,7 +1397,7 @@ sub run_test { print "\n"; - if (defined($config->{option}) && $config->{option} eq "clear") { + if (defined($rules->{option}) && $rules->{option} eq "clear") { system("rm -rf $udev_db"); system("rm -rf $udev_root"); mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; @@ -1416,11 +1416,11 @@ if (!($<==0)) { system("rm -rf $udev_root"); mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; -# create initial config file -open CONF, ">$main_conf" || die "unable to create config file: $main_conf"; +# 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=\"$conf_tmp\"\n"; +print CONF "udev_rules=\"$udev_rules\"\n"; close CONF; my $test_num = 1; @@ -1439,8 +1439,8 @@ if ($ARGV[0]) { # test all print "\nudev-test will run ".($#tests + 1)." tests:\n\n"; - foreach my $config (@tests) { - run_test($config, $test_num); + foreach my $rules (@tests) { + run_test($rules, $test_num); $test_num++; } } @@ -1450,6 +1450,6 @@ print "$error errors occured\n\n"; # cleanup system("rm -rf $udev_db"); system("rm -rf $udev_root"); -unlink($conf_tmp); -unlink($main_conf); +unlink($udev_rules); +unlink($udev_conf); diff --git a/test/udevstart-test.pl b/test/udevstart-test.pl index b6f85bb38c..1862ffea42 100644 --- a/test/udevstart-test.pl +++ b/test/udevstart-test.pl @@ -13,16 +13,15 @@ use strict; my $PWD = $ENV{PWD}; my $sysfs = "sys/"; -my $udev_bin = "../udev"; +my $udevstart_bin = "../udevstart"; my $udev_root = "udev-root/"; # !!! directory will be removed !!! my $udev_db = ".udevdb"; -my $main_conf = "udev-test.conf"; -my $conf_tmp = "udev-test.rules"; +my $udev_conf = "udev-test.conf"; +my $udev_rules = "udev-test.rules"; # set env -$ENV{UDEV_TEST} = "yes"; $ENV{SYSFS_PATH} = $sysfs; -$ENV{UDEV_CONFIG_FILE} = $main_conf; +$ENV{UDEV_CONFIG_FILE} = $udev_conf; $ENV{UDEV_NO_DEVD} = "yes"; $ENV{UDEV_NO_HOTPLUGD} = "yes"; @@ -36,23 +35,29 @@ if (!($<==0)) { system("rm -rf $udev_root"); mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; -# create initial config file -open CONF, ">$main_conf" || die "unable to create config file: $main_conf"; +# 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=\"$conf_tmp\"\n"; +print CONF "udev_rules=\"$udev_rules\"\n"; close CONF; -system("$udev_bin udevstart"); -my $block = int( `find $udev_root -type b -print | wc -l`); -my $char = int( `find $udev_root -type c -print | wc -l`); +# 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($conf_tmp); -unlink($main_conf); +unlink($udev_rules); +unlink($udev_conf); diff --git a/udev_config.c b/udev_config.c index 45b11de2aa..1b6b614260 100644 --- a/udev_config.c +++ b/udev_config.c @@ -219,24 +219,14 @@ static int parse_config_file(void) void udev_init_config(void) { + const char *config; init_variables(); sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); - /* see if we should try to override any of the default values */ - if (getenv("UDEV_TEST") != NULL) { - char *temp; - - temp = getenv("SYSFS_PATH"); - if (temp != NULL) { - strlcpy(sysfs_path, temp, sizeof(sysfs_path)); - no_trailing_slash(sysfs_path); - } - - temp = getenv("UDEV_CONFIG_FILE"); - if (temp != NULL) - strlcpy(udev_config_filename, temp, sizeof(udev_config_filename)); - } + config = getenv("UDEV_CONFIG_FILE"); + if (config != NULL) + strlcpy(udev_config_filename, config, sizeof(udev_config_filename)); parse_config_file(); dbg("sysfs_path='%s'", sysfs_path); From 6b493a20e1dbf90a4e54d3be37027fa906220c31 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 00:11:03 +0100 Subject: [PATCH 1258/4284] [PATCH] support log-priority levels in udev.conf --- Makefile | 9 ++-- RELEASE-NOTES | 11 +++++ etc/udev/udev.conf.in | 14 +++--- logging.h | 13 ++++-- udev.8.in | 45 +++++++++---------- udev.c | 24 +++++----- udev.h | 2 +- udev_add.c | 6 +-- udev_config.c | 102 +++++++++++++++++++++++------------------- udev_db.c | 12 ++--- udev_remove.c | 2 +- udev_rules.c | 24 +++++----- udev_rules_parse.c | 21 +++++---- udevd.8 | 2 +- udevd.c | 52 ++++++++++----------- udevinfo.c | 7 ++- udevsend.c | 32 +++++++------ udevstart.c | 17 ++++++- udevtest.8 | 2 +- udevtest.c | 12 +++-- 20 files changed, 233 insertions(+), 176 deletions(-) diff --git a/Makefile b/Makefile index 1424cf0315..9d9caec7f7 100644 --- a/Makefile +++ b/Makefile @@ -17,16 +17,18 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# Set this to make use of syslog +# Set this to make use of syslog. USE_LOG = true -# Set this to ad development debug messages +# Set this to compile-in development debug messages. Pass UDEV_LOG="debug" +# to the executed binary or set the value in the udev configuration file to +# let udev print the debug messages to syslog. DEBUG = false # Set this to include Security-Enhanced Linux support. USE_SELINUX = false -# Set this to comile with the local version of klibc instead of glibc. +# Set this to comile with klibc instead of glibc. USE_KLIBC = false # Set this to create statically linked binaries. @@ -249,7 +251,6 @@ udev_version.h: @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ - @echo \#define UDEV_LOG_DEFAULT \"yes\" >> $@ @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 2defd7117b..17d6097abf 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,14 @@ +udev 057 +======== +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: diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 72e25ed482..9d5300a861 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -1,19 +1,15 @@ # udev.conf -# The main config file for udev # -# This file can be used to override some of udev's default values -# for where it looks for files, and where it places device nodes. - -# udev_root - where in the filesystem to place the device nodes +# Where in the filesystem to place the device nodes udev_root="@udevdir@" -# udev_db - The name and location of the udev database. +# The name and location of the udev database. udev_db="@udevdir@/.udevdb" -# udev_rules - The name and location of the udev rules file +# The name and location of the udev rules file(s). udev_rules="@configdir@/rules.d" -# udev_log - set to "yes" if you want logging, else "no" -udev_log="yes" +# The syslog(3) priority: "err", "info", or the numerical value. +udev_log="err" diff --git a/logging.h b/logging.h index e7653ee1b8..904355cb2c 100644 --- a/logging.h +++ b/logging.h @@ -24,6 +24,7 @@ #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) @@ -34,21 +35,27 @@ #include #include +#undef err +#define err(format, arg...) \ + do { \ + log_message(LOG_INFO ,"%s: " format ,__FILE__ ,## arg); \ + } while (0) + #undef info #define info(format, arg...) \ do { \ - log_message(LOG_INFO , format , ## arg); \ + log_message(LOG_INFO ,"%s: " format ,__FILE__ ,## arg); \ } while (0) #ifdef DEBUG #undef dbg #define dbg(format, arg...) \ do { \ - log_message(LOG_DEBUG , "%s: " format , __FUNCTION__ , ## arg); \ + log_message(LOG_DEBUG ,"%s: " format ,__FUNCTION__ ,## arg); \ } while (0) #endif -extern void log_message(int level, const char *format, ...) +extern void log_message(int priority, const char *format, ...) __attribute__ ((format (printf, 2, 3))); #undef logging_init diff --git a/udev.8.in b/udev.8.in index a246efdb45..7b061a8c2b 100644 --- a/udev.8.in +++ b/udev.8.in @@ -2,7 +2,7 @@ .SH NAME udev \- Linux configurable dynamic device naming support .SH SYNOPSIS -.BI udev " hotplug-subsystem" +.BI udev .SH "DESCRIPTION" .B udev provides a dynamic device directory containing only the files for actually @@ -56,25 +56,28 @@ All rule files are read in lexical order. The default value is .IR /etc/udev/rules.d/ . .TP .B udev_log -The switch to enable/disable logging of udev information +The logging priority which can be set to +.IR "err " , "info " +or the corresponding numerical +.BR syslog (3) +value. The default value is -.IR yes . +.IR err . .P .RI "A sample " udev.conf " file might look like this: .sp .nf -# udev_root - where to place the device nodes in the filesystem -udev_root="/udev" +# Where in the filesystem to place the device nodes +udev_root="@udevdir@" -# udev_db - The name and location of the udev database -udev_db="/udev/.udevdb" +# The name and location of the udev database. +udev_db="@udevdir@/.udevdb" -# udev_rules - The name of the udev rules file or directory to look - for files with the suffix .rules -udev_rules="/etc/udev/rules.d/" +# The name and location of the udev rules file(s). +udev_rules="@configdir@/rules.d" -# udev_log - set to "yes" if you want logging, else "no" -udev_log="yes" +# The syslog(3) priority: "err", "info", or the numerical value. +udev_log="err" .fi .P The rules for device naming are read from the files located in the @@ -171,7 +174,6 @@ compiled-in default value. .B last_rule will be the last rule applied. No later rules will have any effect. .sp -.B OPTIONS .B ignore_device will ignore this device. No node will be created. .sp @@ -277,13 +279,6 @@ KERNEL=="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" # multiple USB webcams with symlinks to be called webcam0, webcam1, ... BUS=="usb", SYSFS{model}=="XV3", NAME=="video%n", SYMLINK="webcam%n" - -# grouping of optical drives from multiple kernel subsystems -KERNEL=="sr*", NAME="%k", SYMLINK="cdrom%e" -KERNEL=="scd*", NAME="%k", SYMLINK="cdrom%e" -KERNEL=="pcd*", NAME="%k", SYMLINK="cdrom%e" -KERNEL=="hd[a-z]", PROGRAM=="/bin/cat /proc/ide/%k/media", RESULT=="cdrom", - NAME="%k", SYMLINK="cdrom%e" .fi .P A number of different fields in the above configuration files support a simple @@ -312,8 +307,9 @@ to be recognized. .br In addition to the hotplug environment variables, .B UDEV_LOG -is set if udev is configured to use the syslog facility. Executed programs may -want to follow that setting. +is set and contains the numerical priority value, if udev is configured to use +.BR syslog (3). +Executed programs may want to follow that setting. .B DEVNAME is exported to make the name of the created node, or the name the network device is renamed to, available to the executed program. The programs in every @@ -345,6 +341,9 @@ Overrides the default location of the .B udev config file. .TP +.B UDEV_LOG +Overrides the log priority specified in the config file. +.TP .B UDEV_NO_DEVD The default behavior of .B udev @@ -367,8 +366,8 @@ will skip this step. .PP .B Web resources: .nf -.I http://linux\-hotplug.sourceforge.net/ .I http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html +.I http://linux\-hotplug.sourceforge.net/ .fi .SH AUTHORS .B udev diff --git a/udev.c b/udev.c index 069cecf973..6d1d679d9a 100644 --- a/udev.c +++ b/udev.c @@ -40,17 +40,16 @@ #include "udev_rules.h" #include "logging.h" - #ifdef USE_LOG -void log_message(int level, const char *format, ...) +void log_message(int priority, const char *format, ...) { va_list args; - if (!udev_log) + if (priority > udev_log_priority) return; va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif @@ -115,13 +114,12 @@ int main(int argc, char *argv[], char *envp[]) } logging_init("udev"); - dbg("version %s", UDEV_VERSION); - udev_init_config(); + dbg("version %s", UDEV_VERSION); /* set signal handlers */ memset(&act, 0x00, sizeof(act)); - act.sa_handler = (void (*) (int))sig_handler; + act.sa_handler = (void (*)(int)) sig_handler; sigemptyset (&act.sa_mask); act.sa_flags = 0; sigaction(SIGALRM, &act, NULL); @@ -146,13 +144,17 @@ int main(int argc, char *argv[], char *envp[]) udev_init_device(&udev, devpath, subsystem); if (!action || !subsystem || !devpath) { - dbg("action, subsystem or devpath missing"); + err("action, subsystem or devpath missing"); goto hotplug; } /* export logging flag, as called scripts may want to do the same as udev */ - if (udev_log) - setenv("UDEV_LOG", "1", 1); + if (udev_log_priority) { + char priority[32]; + + sprintf(priority, "%i", udev_log_priority); + setenv("UDEV_LOG", priority, 1); + } if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { if (strcmp(action, "add") == 0) { @@ -169,7 +171,7 @@ int main(int argc, char *argv[], char *envp[]) path[sizeof(path)-1] = '\0'; class_dev = wait_class_device_open(path); if (class_dev == NULL) { - dbg ("open class device failed"); + dbg("open class device failed"); goto hotplug; } dbg("opened class_dev->name='%s'", class_dev->name); diff --git a/udev.h b/udev.h index 6e41bb5d26..c2706f4593 100644 --- a/udev.h +++ b/udev.h @@ -92,7 +92,7 @@ extern char udev_root[PATH_SIZE]; extern char udev_db_path[PATH_SIZE]; extern char udev_config_filename[PATH_SIZE]; extern char udev_rules_filename[PATH_SIZE]; -extern int udev_log; +extern int udev_log_priority; extern int udev_dev_d; extern int udev_hotplug_d; diff --git a/udev_add.c b/udev_add.c index 15c6bf9fbc..d0d9eab913 100644 --- a/udev_add.c +++ b/udev_add.c @@ -58,7 +58,7 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo /* preserve node with already correct numbers, to not change the inode number */ if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && (stats.st_rdev == devt)) { - dbg("preserve file '%s', cause it has correct dev_t", file); + info("preserve file '%s', cause it has correct dev_t", file); selinux_setfilecon(file, udev->kernel_name, stats.st_mode); goto perms; } @@ -85,7 +85,7 @@ create: retval = mknod(file, mode, devt); selinux_resetfscreatecon(); if (retval != 0) { - dbg("mknod(%s, %#o, %u, %u) failed with error '%s'", + err("mknod(%s, %#o, %u, %u) failed with error '%s'", file, mode, major(devt), minor(devt), strerror(errno)); goto exit; } @@ -241,7 +241,7 @@ static int rename_net_if(struct udevice *udev) struct ifreq ifr; int retval; - dbg("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name); + info("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name); if (udev->test_run) return 0; diff --git a/udev_config.c b/udev_config.c index 1b6b614260..54eedb980a 100644 --- a/udev_config.c +++ b/udev_config.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" @@ -35,19 +36,17 @@ #include "udev_utils.h" #include "udev_version.h" #include "logging.h" -#include "udev_rules.h" /* global variables */ char sysfs_path[PATH_SIZE]; char udev_root[PATH_SIZE]; char udev_db_path[PATH_SIZE]; -char udev_rules_filename[PATH_SIZE]; char udev_config_filename[PATH_SIZE]; -int udev_log; +char udev_rules_filename[PATH_SIZE]; +int udev_log_priority; int udev_dev_d; int udev_hotplug_d; - static int string_is_true(const char *str) { if (strcasecmp(str, "true") == 0) @@ -59,6 +58,26 @@ static int string_is_true(const char *str) return 0; } +static 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; +} + static int get_key(char **line, char **key, char **value) { char *linepos; @@ -107,29 +126,6 @@ static int get_key(char **line, char **key, char **value) return 0; } -static void init_variables(void) -{ - const char *env; - - /* If any config values are specified, they will override these values. */ - strcpy(udev_root, UDEV_ROOT); - strcpy(udev_db_path, UDEV_DB); - strcpy(udev_config_filename, UDEV_CONFIG_FILE); - strcpy(udev_rules_filename, UDEV_RULES_FILE); - - udev_log = string_is_true(UDEV_LOG_DEFAULT); - - udev_dev_d = 1; - env = getenv("UDEV_NO_DEVD"); - if (env && string_is_true(env)) - udev_dev_d = 0; - - udev_hotplug_d = 1; - env = getenv("UDEV_NO_HOTPLUGD"); - if (env && string_is_true(env)) - udev_hotplug_d = 0; -} - static int parse_config_file(void) { char line[LINE_SIZE]; @@ -145,10 +141,9 @@ static int parse_config_file(void) int retval = 0; if (file_map(udev_config_filename, &buf, &bufsize) != 0) { - dbg("can't open '%s' as config file", udev_config_filename); + err("can't open '%s' as config file", udev_config_filename); return -ENODEV; } - dbg("reading '%s' as config file", udev_config_filename); /* loop through the whole file */ lineno = 0; @@ -160,8 +155,7 @@ static int parse_config_file(void) lineno++; if (count >= sizeof(line)) { - info("line too long, conf line skipped %s, line %d", - udev_config_filename, lineno); + err("line too long, conf line skipped %s, line %d", udev_config_filename, lineno); continue; } @@ -178,17 +172,14 @@ static int parse_config_file(void) continue; strlcpy(line, bufline, count); - dbg("read '%s'", line); linepos = line; retval = get_key(&linepos, &variable, &value); if (retval != 0) { - info("error parsing %s, line %d:%d", udev_config_filename, lineno, (int) (linepos-line)); + err("error parsing %s, line %d:%d", udev_config_filename, lineno, (int) (linepos-line)); continue; } - dbg("variable='%s', value='%s'", variable, value); - if (strcasecmp(variable, "udev_root") == 0) { strlcpy(udev_root, value, sizeof(udev_root)); no_trailing_slash(udev_root); @@ -208,7 +199,7 @@ static int parse_config_file(void) } if (strcasecmp(variable, "udev_log") == 0) { - udev_log = string_is_true(value); + udev_log_priority = log_priority(value); continue; } } @@ -219,20 +210,41 @@ static int parse_config_file(void) void udev_init_config(void) { - const char *config; + const char *env; - init_variables(); + strcpy(udev_root, UDEV_ROOT); + strcpy(udev_db_path, UDEV_DB); + strcpy(udev_config_filename, UDEV_CONFIG_FILE); + strcpy(udev_rules_filename, UDEV_RULES_FILE); + udev_log_priority = LOG_ERR; + udev_dev_d = 1; + udev_hotplug_d = 1; sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); - config = getenv("UDEV_CONFIG_FILE"); - if (config != NULL) - strlcpy(udev_config_filename, config, sizeof(udev_config_filename)); + env = getenv("UDEV_NO_DEVD"); + if (env && string_is_true(env)) + udev_dev_d = 0; + + env = getenv("UDEV_NO_HOTPLUGD"); + if (env && string_is_true(env)) + udev_hotplug_d = 0; + + env = getenv("UDEV_CONFIG_FILE"); + if (env) { + strlcpy(udev_config_filename, env, sizeof(udev_config_filename)); + no_trailing_slash(udev_config_filename); + } parse_config_file(); + + env = getenv("UDEV_LOG"); + if (env) + udev_log_priority = log_priority(env); + dbg("sysfs_path='%s'", sysfs_path); + dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename); dbg("udev_root='%s'", udev_root); - dbg("udev_config_filename='%s'", udev_config_filename); - dbg("udev_db_path='%s'", udev_db_path); - dbg("udev_rules_filename='%s'", udev_rules_filename); - dbg("udev_log=%d", udev_log); + dbg("udev_db='%s'", udev_db_path); + dbg("udev_rules='%s'", udev_rules_filename); + dbg("udev_log=%d", udev_log_priority); } diff --git a/udev_db.c b/udev_db.c index 806fc71bce..f606b5e05c 100644 --- a/udev_db.c +++ b/udev_db.c @@ -74,7 +74,7 @@ int udev_db_add_device(struct udevice *udev) f = fopen(filename, "w"); if (f == NULL) { - dbg("unable to create db file '%s'", filename); + err("unable to create db file '%s'", filename); return -1; } dbg("storing data for device '%s' in '%s'", udev->devpath, filename); @@ -103,7 +103,7 @@ static int parse_db_file(struct udevice *udev, const char *filename) size_t count; if (file_map(filename, &buf, &bufsize) != 0) { - dbg("unable to read db file '%s'", filename); + err("unable to read db file '%s'", filename); return -1; } @@ -187,7 +187,7 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) dir = opendir(udev_db_path); if (dir == NULL) { - dbg("unable to udev db '%s'", udev_db_path); + err("unable to open udev_db '%s'", udev_db_path); return -1; } @@ -214,7 +214,7 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) dbg("looking at '%s'", filename); if (file_map(filename, &buf, &bufsize) != 0) { - dbg("unable to read db file '%s'", filename); + err("unable to read db file '%s'", filename); continue; } @@ -260,7 +260,7 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam dir = opendir(udev_db_path); if (dir == NULL) { - dbg("unable to udev db '%s'", udev_db_path); + err("unable to open udev_db '%s'", udev_db_path); return -1; } @@ -287,7 +287,7 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam dbg("looking at '%s'", filename); if (file_map(filename, &buf, &bufsize) != 0) { - dbg("unable to read db file '%s'", filename); + err("unable to read db file '%s'", filename); continue; } diff --git a/udev_remove.c b/udev_remove.c index 0a9996dc6a..2df555327b 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -158,7 +158,7 @@ int udev_remove_device(struct udevice *udev) if (temp == NULL) return -ENODEV; strlcpy(udev->name, &temp[1], sizeof(udev->name)); - dbg("'%s' not found in database, falling back on default name", udev->name); + info("'%s' not found in database, falling back on default name", udev->name); } /* use full path to the environment */ diff --git a/udev_rules.c b/udev_rules.c index 3dc77855da..4eb8fd4411 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -107,7 +107,7 @@ static char *get_format_attribute(char **str) if (*str[0] == '{') { pos = strchr(*str, '}'); if (pos == NULL) { - dbg("missing closing brace for format"); + err("missing closing brace for format"); return NULL; } pos[0] = '\0'; @@ -131,7 +131,7 @@ static int get_format_len(char **str) dbg("format length=%i", num); return num; } else { - dbg("format parsing error '%s'", *str); + err("format parsing error '%s'", *str); } } return -1; @@ -239,7 +239,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, cpos++; } if (i > 0) { - dbg("requested part of result string not found"); + err("requested part of result string not found"); break; } strlcpy(temp2, cpos, sizeof(temp2)); @@ -265,7 +265,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } tmpattr = find_sysfs_attribute(class_dev, sysfs_device, attr); if (tmpattr == NULL) { - dbg("sysfa attribute '%s' not found", attr); + dbg("sysfs attribute '%s' not found", attr); break; } /* strip trailing whitespace of matching value */ @@ -327,7 +327,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute udev_root '%s'", udev_root); break; default: - dbg("unknown substitution type '%%%c'", c); + err("unknown substitution type '%%%c'", c); break; } /* truncate to specified length */ @@ -378,7 +378,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value, retval = pipe(fds); if (retval != 0) { - dbg("pipe failed"); + err("pipe failed"); return -1; } @@ -393,7 +393,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value, info(KEY_PROGRAM " execution of '%s' failed", path); exit(1); case -1: - dbg("fork failed"); + err("fork of '%s' failed", path); return -1; default: /* parent reads from fds[0] */ @@ -407,14 +407,14 @@ static int execute_program(struct udevice *udev, const char *path, char *value, i += count; if (i >= len-1) { - dbg("result len %d too short", len); + err("result len %d too short", len); retval = -1; break; } } if (count < 0) { - dbg("read failed with '%s'", strerror(errno)); + err("read failed with '%s'", strerror(errno)); retval = -1; } @@ -775,12 +775,12 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d next = strchr(temp, ' '); while (next) { next[0] = '\0'; - dbg("add symlink '%s'", pos); + info("add symlink '%s'", pos); name_list_add(&udev->symlink_list, pos, 0); pos = &next[1]; next = strchr(pos, ' '); } - dbg("add symlink '%s'", pos); + info("add symlink '%s'", pos); name_list_add(&udev->symlink_list, pos, 0); } @@ -812,7 +812,7 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (udev->name[0] == '\0') { /* no rule matched, so we use the kernel name */ strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); - dbg("no rule found, use kernel name '%s'", udev->name); + info("no rule found, use kernel name '%s'", udev->name); } if (udev->tmp_node[0] != '\0') { diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 55412dba3c..71ca482728 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -157,7 +157,7 @@ static char *get_key_attribute(char *str) attr++; pos = strchr(attr, '}'); if (pos == NULL) { - dbg("missing closing brace for format"); + err("missing closing brace for format"); return NULL; } pos[0] = '\0'; @@ -185,7 +185,7 @@ static int rules_parse(const char *filename) struct udev_rule rule; if (file_map(filename, &buf, &bufsize) != 0) { - dbg("can't open '%s' as rules file", filename); + err("can't open '%s' as rules file", filename); return -1; } dbg("reading '%s' as rules file", filename); @@ -274,13 +274,13 @@ static int rules_parse(const char *filename) struct key_pair *pair; if (rule.sysfs_pair_count >= KEY_SYSFS_PAIRS_MAX) { - dbg("skip rule, to many " KEY_SYSFS " keys in a single rule"); + err("skip rule, to many " KEY_SYSFS " keys in a single rule"); goto error; } pair = &rule.sysfs_pair[rule.sysfs_pair_count]; attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1); if (attr == NULL) { - dbg("error parsing " KEY_SYSFS " attribute"); + err("error parsing " KEY_SYSFS " attribute"); goto error; } strlcpy(pair->name, attr, sizeof(pair->name)); @@ -295,13 +295,13 @@ static int rules_parse(const char *filename) struct key_pair *pair; if (rule.env_pair_count >= KEY_ENV_PAIRS_MAX) { - dbg("skip rule, to many " KEY_ENV " keys in a single rule"); + err("skip rule, to many " KEY_ENV " keys in a single rule"); goto error; } pair = &rule.env_pair[rule.env_pair_count]; attr = get_key_attribute(key + sizeof(KEY_ENV)-1); if (attr == NULL) { - dbg("error parsing " KEY_ENV " attribute"); + err("error parsing " KEY_ENV " attribute"); continue; } strlcpy(pair->name, attr, sizeof(pair->name)); @@ -400,7 +400,7 @@ static int rules_parse(const char *filename) continue; } - dbg("unknown key '%s'", key); + err("unknown key '%s'", key); goto error; } @@ -411,13 +411,12 @@ static int rules_parse(const char *filename) /* simple plausibility checks for given keys */ if ((rule.sysfs_pair[0].name[0] == '\0') ^ (rule.sysfs_pair[0].value[0] == '\0')) { - info("inconsistency in " KEY_SYSFS " key"); + err("inconsistency in " KEY_SYSFS " key"); goto error; } if ((rule.result[0] != '\0') && (program_given == 0)) { - info(KEY_RESULT " is only useful when " - KEY_PROGRAM " is called in any rule before"); + info(KEY_RESULT " is only useful when " KEY_PROGRAM " is called in any rule before"); goto error; } @@ -428,7 +427,7 @@ static int rules_parse(const char *filename) dbg("add_config_dev returned with error %d", retval); continue; error: - info("parse error %s, line %d:%d, rule skipped", + err("parse error %s, line %d:%d, rule skipped", filename, lineno, (int) (linepos - line)); } } diff --git a/udevd.8 b/udevd.8 index b06a2b7af1..02e2e2c5f8 100644 --- a/udevd.8 +++ b/udevd.8 @@ -2,7 +2,7 @@ .SH NAME udevd, udevdsend \- udev event serializer daemon and udev event sender .SH SYNOPSIS -.BI udevsend " hotplug-subsystem" +.BI udevsend .SH "DESCRIPTION" .B udevd allows the serialization of diff --git a/udevd.c b/udevd.c index 6e27c8a0d1..6c4d8b8693 100644 --- a/udevd.c +++ b/udevd.c @@ -70,20 +70,19 @@ static void reap_sigchilds(void); char *udev_bin; #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { - va_list args; + va_list args; + + if (priority > udev_log_priority) + return; va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif -#define msg_dump(msg) \ - dbg("msg_dump: sequence %llu, '%s', '%s', '%s'", \ - msg->seqnum, msg->action, msg->devpath, msg->subsystem); - static void msg_dump_queue(void) { #ifdef DEBUG @@ -127,7 +126,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) break; if (loop_msg->seqnum == msg->seqnum) { - dbg("ignoring duplicate message seq %llu", msg->seqnum); + info("ignoring duplicate message seq %llu", msg->seqnum); return; } } @@ -160,11 +159,11 @@ static void udev_run(struct hotplug_msg *msg) setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); execve(udev_bin, argv, msg->envp); - dbg("exec of child failed"); + err("exec of child failed"); _exit(1); break; case -1: - dbg("fork of child failed"); + err("fork of child failed"); run_queue_delete(msg); break; default: @@ -452,17 +451,17 @@ static struct hotplug_msg *get_udevsend_msg(void) cred = (struct ucred *) CMSG_DATA(cmsg); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { - dbg("no sender credentials received, message ignored"); + info("no sender credentials received, message ignored"); return NULL; } if (cred->uid != 0) { - dbg("sender uid=%i, message ignored", cred->uid); + info("sender uid=%i, message ignored", cred->uid); return NULL; } if (strncmp(usend_msg.magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { - dbg("message magic '%s' doesn't match, ignore it", usend_msg.magic); + info("message magic '%s' doesn't match, ignore it", usend_msg.magic); return NULL; } @@ -605,14 +604,14 @@ static int init_udevsend_socket(void) udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (udevsendsock == -1) { - dbg("error getting socket, %s", strerror(errno)); + err("error getting socket, %s", strerror(errno)); return -1; } /* the bind takes care of ensuring only one copy running */ retval = bind(udevsendsock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { - dbg("bind failed, %s", strerror(errno)); + err("bind failed, %s", strerror(errno)); close(udevsendsock); return -1; } @@ -634,10 +633,11 @@ int main(int argc, char *argv[], char *envp[]) const char *udevd_expected_seqnum; logging_init("udevd"); + udev_init_config(); dbg("version %s", UDEV_VERSION); if (getuid() != 0) { - dbg("need to be root, exit"); + err("need to be root, exit"); goto exit; } @@ -651,7 +651,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("damonized fork running"); break; case -1: - dbg("fork of daemon failed"); + err("fork of daemon failed"); goto exit; default: logging_close(); @@ -679,36 +679,36 @@ int main(int argc, char *argv[], char *envp[]) if (fd > 2) close(fd); } else - dbg("error opening /dev/null %s", strerror(errno)); + err("error opening /dev/null %s", strerror(errno)); /* setup signal handler pipe */ retval = pipe(pipefds); if (retval < 0) { - dbg("error getting pipes: %s", strerror(errno)); + err("error getting pipes: %s", strerror(errno)); goto exit; } retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); if (retval < 0) { - dbg("error fcntl on read pipe: %s", strerror(errno)); + err("error fcntl on read pipe: %s", strerror(errno)); goto exit; } retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); if (retval < 0) - dbg("error fcntl on read pipe: %s", strerror(errno)); + err("error fcntl on read pipe: %s", strerror(errno)); retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); if (retval < 0) { - dbg("error fcntl on write pipe: %s", strerror(errno)); + err("error fcntl on write pipe: %s", strerror(errno)); goto exit; } retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC); if (retval < 0) - dbg("error fcntl on write pipe: %s", strerror(errno)); + err("error fcntl on write pipe: %s", strerror(errno)); /* set signal handlers */ memset(&act, 0x00, sizeof(struct sigaction)); - act.sa_handler = (void (*) (int))sig_handler; + act.sa_handler = (void (*)(int)) sig_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; sigaction(SIGINT, &act, NULL); @@ -728,7 +728,7 @@ int main(int argc, char *argv[], char *envp[]) /* possible override of udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); if (udev_bin != NULL) - dbg("udev binary is set to '%s'", udev_bin); + info("udev binary is set to '%s'", udev_bin); else udev_bin = UDEV_BIN; @@ -736,7 +736,7 @@ int main(int argc, char *argv[], char *envp[]) udevd_expected_seqnum = getenv("UDEVD_EXPECTED_SEQNUM"); if (udevd_expected_seqnum != NULL) { expected_seqnum = strtoull(udevd_expected_seqnum, NULL, 10); - dbg("initialize expected_seqnum to %llu", expected_seqnum); + info("initialize expected_seqnum to %llu", expected_seqnum); } /* get current time to provide shorter timeout on startup */ diff --git a/udevinfo.c b/udevinfo.c index ccc3e58e2b..3fb37b41e9 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -36,12 +36,15 @@ #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { va_list args; + if (priority > udev_log_priority) + return; + va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif diff --git a/udevsend.c b/udevsend.c index dcd5a2ae93..8915edacc8 100644 --- a/udevsend.c +++ b/udevsend.c @@ -44,12 +44,15 @@ static int sock = -1; #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { - va_list args; + va_list args; + + if (priority > udev_log_priority) + return; va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif @@ -71,17 +74,17 @@ static int start_daemon(void) /* daemon with empty environment */ close(sock); execve(UDEVD_BIN, argv, envp); - dbg("exec of daemon failed"); + err("exec of daemon failed"); _exit(1); case -1: - dbg("fork of daemon failed"); + err("fork of daemon failed"); return -1; default: exit(0); } break; case -1: - dbg("fork of helper failed"); + err("fork of helper failed"); return -1; default: waitpid(pid, NULL, 0); @@ -99,11 +102,11 @@ static void run_udev(const char *subsystem) case 0: /* child */ execv(UDEV_BIN, argv); - dbg("exec of child failed"); + err("exec of udev child failed"); _exit(1); break; case -1: - dbg("fork of child failed"); + err("fork of udev child failed"); break; default: waitpid(pid, NULL, 0); @@ -124,11 +127,14 @@ int main(int argc, char *argv[], char *envp[]) const char *subsystem = NULL; logging_init("udevsend"); +#ifdef USE_LOG + udev_init_config(); +#endif dbg("version %s", UDEV_VERSION); sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { - dbg("error getting socket"); + err("error getting socket"); goto fallback; } @@ -156,7 +162,7 @@ int main(int argc, char *argv[], char *envp[]) } if (bufpos + keylen >= HOTPLUG_BUFFER_SIZE-1) { - dbg("environment buffer too small, probably not called by the kernel"); + err("environment buffer too small, probably not called by the kernel"); continue; } @@ -187,12 +193,12 @@ int main(int argc, char *argv[], char *envp[]) } if (errno != ECONNREFUSED) { - dbg("error sending message (%s)", strerror(errno)); + err("error sending message (%s)", strerror(errno)); goto fallback; } if (!started_daemon) { - dbg("try to start udevd daemon"); + info("try to start udevd daemon"); retval = start_daemon(); if (retval) { dbg("error starting daemon"); @@ -207,7 +213,7 @@ int main(int argc, char *argv[], char *envp[]) } fallback: - info("unable to connect to event daemon, try to call udev directly"); + err("unable to connect to event daemon, try to call udev directly"); run_udev(subsystem); exit: diff --git a/udevstart.c b/udevstart.c index 7765661fe4..a862dadf88 100644 --- a/udevstart.c +++ b/udevstart.c @@ -38,14 +38,23 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" #include "udev.h" +#include "udev_version.h" #include "logging.h" #include "udev_rules.h" #include "udev_utils.h" #include "list.h" #ifdef USE_LOG -void log_message(int level, const char *format, ...) +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 @@ -299,7 +308,12 @@ int main(int argc, char *argv[], char *envp[]) { struct sigaction act; + logging_init("udev"); udev_init_config(); + /* disable all logging if not explicitely requested */ + if (getenv("UDEV_LOG") == NULL) + udev_log_priority = 0; + dbg("version %s", UDEV_VERSION); /* set signal handlers */ memset(&act, 0x00, sizeof(act)); @@ -322,5 +336,6 @@ int main(int argc, char *argv[], char *envp[]) udev_scan_block(); udev_scan_class(); + logging_close(); return 0; } diff --git a/udevtest.8 b/udevtest.8 index 13b57f03b6..a595a30d41 100644 --- a/udevtest.8 +++ b/udevtest.8 @@ -3,7 +3,7 @@ udevtest \- simulates a udev run to test the configured rules .SH SYNOPSIS .B udevtest -.IR "sysfs_device_path " [ subsystem ] +.I sysfs_device_path subsystem .SH "DESCRIPTION" .B udevtest simulates a diff --git a/udevtest.c b/udevtest.c index 006d55510e..f0c38b3a51 100644 --- a/udevtest.c +++ b/udevtest.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" @@ -37,10 +38,13 @@ #ifdef USE_LOG -void log_message (int level, const char *format, ...) +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); @@ -60,13 +64,15 @@ int main(int argc, char *argv[], char *envp[]) info("version %s", UDEV_VERSION); - if (argc < 2 || argc > 3) { - info("Usage: udevtest [subsystem]"); + if (argc != 3) { + info("Usage: udevtest "); return 1; } /* initialize our configuration */ udev_init_config(); + if (udev_log_priority < LOG_INFO) + udev_log_priority = LOG_INFO; /* remove sysfs_path if given */ if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) From a6bece643c9e1132052c246eab099e7d9071ab63 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 00:11:52 +0100 Subject: [PATCH 1259/4284] [PATCH] klibc: version 1.0.4 --- klibc/include/signal.h | 2 +- klibc/klibc/tests/environ.c | 24 - klibc/klibc/tests/fcntl.c | 53 - klibc/klibc/tests/getopttest.c | 31 - klibc/klibc/tests/getpagesize.c | 11 - klibc/klibc/tests/hello.c | 7 - klibc/klibc/tests/idtest.c | 14 - klibc/klibc/tests/malloctest.c | 4145 ------------------------------- klibc/klibc/tests/malloctest2.c | 60 - klibc/klibc/tests/memstrtest.c | 29 - klibc/klibc/tests/microhello.c | 9 - klibc/klibc/tests/minihello.c | 7 - klibc/klibc/tests/mmaptest.c | 28 - klibc/klibc/tests/nfs_no_rpc.c | 538 ---- klibc/klibc/tests/opentest.c | 17 - klibc/klibc/tests/rtsig.c | 12 - klibc/klibc/tests/setenvtest.c | 38 - klibc/klibc/tests/setjmptest.c | 36 - klibc/klibc/tests/stat.c | 65 - klibc/klibc/tests/statfs.c | 43 - klibc/klibc/tests/strtoimax.c | 24 - klibc/klibc/tests/strtotime.c | 27 - klibc/klibc/tests/testrand48.c | 19 - klibc/klibc/tests/testvsnp.c | 115 - klibc/version | 2 +- 25 files changed, 2 insertions(+), 5354 deletions(-) delete mode 100644 klibc/klibc/tests/environ.c delete mode 100644 klibc/klibc/tests/fcntl.c delete mode 100644 klibc/klibc/tests/getopttest.c delete mode 100644 klibc/klibc/tests/getpagesize.c delete mode 100644 klibc/klibc/tests/hello.c delete mode 100644 klibc/klibc/tests/idtest.c delete mode 100644 klibc/klibc/tests/malloctest.c delete mode 100644 klibc/klibc/tests/malloctest2.c delete mode 100644 klibc/klibc/tests/memstrtest.c delete mode 100644 klibc/klibc/tests/microhello.c delete mode 100644 klibc/klibc/tests/minihello.c delete mode 100644 klibc/klibc/tests/mmaptest.c delete mode 100644 klibc/klibc/tests/nfs_no_rpc.c delete mode 100644 klibc/klibc/tests/opentest.c delete mode 100644 klibc/klibc/tests/rtsig.c delete mode 100644 klibc/klibc/tests/setenvtest.c delete mode 100644 klibc/klibc/tests/setjmptest.c delete mode 100644 klibc/klibc/tests/stat.c delete mode 100644 klibc/klibc/tests/statfs.c delete mode 100644 klibc/klibc/tests/strtoimax.c delete mode 100644 klibc/klibc/tests/strtotime.c delete mode 100644 klibc/klibc/tests/testrand48.c delete mode 100644 klibc/klibc/tests/testvsnp.c diff --git a/klibc/include/signal.h b/klibc/include/signal.h index e78318f5f7..ab3c98d6e4 100644 --- a/klibc/include/signal.h +++ b/klibc/include/signal.h @@ -16,7 +16,7 @@ /* glibc seems to use sig_atomic_t as "int" pretty much on all architectures. Do the same, but allow the architecture to override. */ -#ifdef _KLIBC_HAS_ARCH_SIG_ATOMIC_T +#ifndef _KLIBC_HAS_ARCH_SIG_ATOMIC_T typedef int sig_atomic_t; #endif diff --git a/klibc/klibc/tests/environ.c b/klibc/klibc/tests/environ.c deleted file mode 100644 index 6eeeb9197e..0000000000 --- a/klibc/klibc/tests/environ.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include - -int main(int argc, char *argv[], char *envp[]) -{ - int i; - - /* Verify envp == environ */ - printf("Verifying envp == environ... %s\n", - (envp == environ) ? "ok" : "ERROR"); - - /* Test argc/argv */ - printf("argc = %d, argv = %p\n", argc, argv); - for ( i = 0 ; i < argc ; i++ ) { - printf("argv[%2d] = %s\n", i, argv[i]); - } - - /* Test environ */ - for ( i = 0 ; envp[i] ; i++ ) - printf("%s\n", envp[i]); - - return 0; -} diff --git a/klibc/klibc/tests/fcntl.c b/klibc/klibc/tests/fcntl.c deleted file mode 100644 index f504ad90f7..0000000000 --- a/klibc/klibc/tests/fcntl.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Simple test of fcntl - */ - -#include -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - int fd = open(argv[0], O_RDONLY); - struct flock l; - long flags; - - (void)argc; - - if ( fd < 0 ) { - perror("open"); - exit(1); - } - - /* Get the flags on this FD */ - - if ( (flags = fcntl(fd, F_GETFL)) == -1 ) { - perror("F_GETFL"); - exit(1); - } - - if ( flags != (O_RDONLY|O_LARGEFILE) ) - fprintf(stderr, "flags = %#lx\n", flags); - - /* Set a lock on this FD */ - memset(&l, 0, sizeof l); - l.l_type = F_RDLCK; - l.l_whence = SEEK_SET; - l.l_start = 123; - l.l_len = 456; - - if ( fcntl(fd, F_SETLK, &l) == -1 ) { - perror("F_SETLK"); - exit(1); - } - - /* Eventually, fork and try to conflict with this lock... */ - - return 0; -} - - - diff --git a/klibc/klibc/tests/getopttest.c b/klibc/klibc/tests/getopttest.c deleted file mode 100644 index 90ceaa2c58..0000000000 --- a/klibc/klibc/tests/getopttest.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * getopttest.c - * - * Simple test for getopt, set the environment variable GETOPTTEST - * to give the argument string to getopt() - */ - -#include -#include -#include - -int main(int argc, char * const *argv) -{ - const char *parser; - char showchar[] = "\'?\'"; - int c; - - parser = getenv("GETOPTTEST"); - if ( !parser ) parser = "abzf:o:"; - - do { - c = getopt(argc, argv, parser); - showchar[1] = c; - printf("c = %s, optind = %d (%s), optarg = \"%s\", optopt = \'%c\'\n", - (c == EOF) ? "EOF" : showchar, - optind, argv[optind], optarg, optopt); - } while ( c != -1 ); - - return 0; -} - diff --git a/klibc/klibc/tests/getpagesize.c b/klibc/klibc/tests/getpagesize.c deleted file mode 100644 index bda37e1f6b..0000000000 --- a/klibc/klibc/tests/getpagesize.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -int main(void) -{ - printf("getpagesize() = %d\n" - "__getpageshift() = %d\n", - getpagesize(), __getpageshift()); - - return 0; -} diff --git a/klibc/klibc/tests/hello.c b/klibc/klibc/tests/hello.c deleted file mode 100644 index 20457af153..0000000000 --- a/klibc/klibc/tests/hello.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int main(void) -{ - printf("Hello, World!\n"); - return 0; -} diff --git a/klibc/klibc/tests/idtest.c b/klibc/klibc/tests/idtest.c deleted file mode 100644 index c3c44479c5..0000000000 --- a/klibc/klibc/tests/idtest.c +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include - -int main(void) -{ - printf("pid = %u\n", getpid()); - printf("ppid = %u\n", getppid()); - printf("uid = %u\n", getuid()); - printf("euid = %u\n", geteuid()); - printf("gid = %u\n", getgid()); - printf("egid = %u\n", getegid()); - sleep(10); - return 0; -} diff --git a/klibc/klibc/tests/malloctest.c b/klibc/klibc/tests/malloctest.c deleted file mode 100644 index 64e8e79851..0000000000 --- a/klibc/klibc/tests/malloctest.c +++ /dev/null @@ -1,4145 +0,0 @@ -#include -#include -#include - -#define NCYCLES 4096 - -int sizes[NCYCLES] = { - 11986, - 277806, - 2659, - 46, - 0, - 775553, - 1991, - 21, - 7638, - 250197, - 155828, - 5777, - 9, - 315006, - 900788, - 0, - 24893, - 119996, - 72299, - 171266, - 357, - 560, - 368, - 22952, - 54058, - 12638, - 39155, - 2738, - 217563, - 26853, - 47, - 75, - 1167, - 16917, - 1899, - 2905, - 9337, - 62243, - 14214, - 270523, - 4024, - 21, - 32, - 14892, - 625144, - 13, - 21700, - 8804, - 254147, - 0, - 6, - 836004, - 1718, - 2289, - 15554, - 412857, - 185097, - 806709, - 64, - 18602, - 17064, - 1779, - 78153, - 170600, - 199100, - 546528, - 0, - 21, - 20609, - 16514, - 548196, - 311446, - 53484, - 0, - 551, - 22225, - 24, - 153989, - 457309, - 526833, - 227979, - 757167, - 429560, - 0, - 835, - 1702, - 475275, - 798416, - 753, - 0, - 11126, - 145779, - 2006, - 0, - 8182, - 0, - 569432, - 9671, - 36, - 5523, - 407325, - 0, - 65, - 9293, - 0, - 6793, - 468701, - 73, - 0, - 186236, - 0, - 328405, - 125616, - 508013, - 380519, - 599518, - 83, - 151973, - 466906, - 9029, - 159725, - 1316, - 1, - 911532, - 1508, - 19050, - 972850, - 126, - 439377, - 29, - 37928, - 149628, - 54, - 130248, - 2, - 143, - 0, - 716873, - 3327, - 5, - 116131, - 5124, - 559621, - 2886, - 534, - 186432, - 441, - 7348, - 10331, - 1, - 260935, - 7, - 4370, - 405415, - 2, - 84518, - 1970, - 1, - 281910, - 46, - 274, - 2273, - 370565, - 4190, - 820641, - 577970, - 32809, - 974893, - 398067, - 380698, - 4, - 25978, - 153, - 882668, - 312365, - 9523, - 156421, - 0, - 268143, - 6, - 2, - 42987, - 212, - 12303, - 6723, - 1179, - 0, - 120924, - 3877, - 330421, - 310445, - 39264, - 8, - 85380, - 464716, - 0, - 33657, - 6285, - 0, - 4491, - 229, - 50, - 373197, - 6029, - 19, - 86884, - 243745, - 335656, - 90945, - 38973, - 572950, - 164129, - 0, - 3, - 17, - 13579, - 4448, - 47, - 3, - 132966, - 726249, - 498503, - 256, - 0, - 25841, - 0, - 7, - 945380, - 11872, - 69, - 3799, - 77223, - 1914, - 73, - 810968, - 10223, - 257918, - 184252, - 350, - 8101, - 725, - 9, - 2, - 2089, - 175, - 247, - 185964, - 36517, - 3723, - 313465, - 209, - 1300, - 128071, - 7425, - 2436, - 62, - 13753, - 9514, - 41, - 409141, - 46643, - 20866, - 15664, - 388548, - 84692, - 9549, - 610, - 7213, - 14, - 14930, - 244719, - 4748, - 41682, - 401098, - 102506, - 176535, - 0, - 5133, - 548, - 5234, - 56, - 11101, - 87638, - 336579, - 291705, - 640250, - 768165, - 370, - 2809, - 3, - 0, - 445122, - 47190, - 24885, - 143556, - 84, - 504726, - 610020, - 40355, - 902230, - 4360, - 1747, - 3496, - 489501, - 19, - 801601, - 62189, - 48, - 2645, - 320601, - 27304, - 17740, - 344, - 10, - 991, - 925503, - 0, - 315, - 251, - 3611, - 1756, - 683, - 165, - 380132, - 181101, - 453041, - 892056, - 67191, - 252592, - 32407, - 56242, - 8, - 297173, - 542903, - 830334, - 585236, - 422555, - 44769, - 0, - 68, - 4143, - 38754, - 73539, - 44579, - 94001, - 428537, - 38554, - 106612, - 0, - 182987, - 831731, - 3605, - 752851, - 52, - 72, - 120872, - 963754, - 31, - 764, - 240592, - 99101, - 328538, - 440325, - 12211, - 151282, - 353436, - 2991, - 40710, - 5212, - 5106, - 139122, - 148915, - 498505, - 1366, - 516, - 29190, - 17, - 224208, - 40, - 89, - 19190, - 8, - 25377, - 10029, - 720, - 97963, - 0, - 614, - 244567, - 2113, - 903675, - 8388, - 6, - 390705, - 325006, - 284272, - 108086, - 17, - 2628, - 952530, - 20474, - 898276, - 138661, - 3883, - 903, - 569993, - 376918, - 5849, - 103404, - 794499, - 35388, - 5, - 0, - 961626, - 27415, - 1927, - 92036, - 46241, - 35978, - 7426, - 399884, - 29490, - 252655, - 675971, - 3509, - 54170, - 170790, - 831341, - 134579, - 0, - 790422, - 35, - 930830, - 97394, - 20265, - 670, - 38497, - 1759, - 71209, - 93, - 736, - 11, - 886, - 1961, - 7, - 210607, - 62226, - 186736, - 1518, - 5, - 5, - 13, - 66989, - 442321, - 0, - 607939, - 11253, - 210875, - 495530, - 2, - 221136, - 377663, - 372, - 200658, - 18591, - 129783, - 803411, - 867506, - 757446, - 48836, - 34, - 200, - 114983, - 7287, - 22849, - 226669, - 13, - 0, - 20164, - 7828, - 39, - 49448, - 26740, - 185566, - 9927, - 36192, - 91068, - 338368, - 926, - 27746, - 534794, - 936132, - 2922, - 5, - 183162, - 256846, - 242551, - 134318, - 212959, - 167162, - 470, - 477045, - 532116, - 483794, - 733, - 5335, - 83074, - 4686, - 9567, - 1, - 195100, - 40354, - 87338, - 369, - 800, - 0, - 194504, - 469051, - 363532, - 850574, - 5085, - 167027, - 794511, - 124320, - 303231, - 132195, - 13225, - 46333, - 4313, - 89, - 799, - 51482, - 0, - 26, - 12659, - 1045, - 23621, - 0, - 74926, - 490979, - 6, - 3188, - 9448, - 174730, - 38982, - 102317, - 189621, - 853, - 29227, - 43374, - 423, - 420951, - 686, - 128, - 31291, - 0, - 402819, - 663143, - 55903, - 142, - 2, - 331584, - 197164, - 7, - 671983, - 53, - 5020, - 9782, - 123, - 743407, - 1276, - 1115, - 1169, - 122752, - 824690, - 292030, - 2094, - 144626, - 0, - 297278, - 440, - 742, - 95879, - 17682, - 10654, - 31, - 22183, - 746, - 0, - 0, - 11185, - 28, - 394987, - 36, - 474, - 243749, - 1431, - 56702, - 76, - 15619, - 33071, - 12181, - 158647, - 261786, - 1, - 119783, - 48816, - 6278, - 4121, - 61122, - 69, - 48790, - 345335, - 275917, - 964393, - 424, - 586433, - 20519, - 18156, - 756400, - 27736, - 458706, - 1, - 3286, - 929624, - 1883, - 2, - 1086, - 439501, - 552, - 157132, - 5565, - 105061, - 8199, - 23, - 178797, - 0, - 130644, - 1, - 6952, - 754, - 500, - 647683, - 0, - 959079, - 622561, - 1131, - 559783, - 6862, - 175420, - 408671, - 463461, - 55908, - 606496, - 169, - 49060, - 247, - 953, - 333030, - 0, - 23399, - 29193, - 9303, - 15, - 515402, - 34961, - 365856, - 633043, - 173, - 556089, - 1809, - 12215, - 14, - 316, - 20642, - 9, - 15, - 190391, - 951463, - 25059, - 13654, - 385040, - 4272, - 929033, - 208813, - 35166, - 42849, - 662648, - 254811, - 4230, - 812459, - 681, - 390168, - 5381, - 4662, - 173257, - 478863, - 103, - 89332, - 0, - 0, - 589484, - 19369, - 94, - 9, - 639917, - 1110, - 393, - 101040, - 911, - 152899, - 0, - 2, - 0, - 0, - 335691, - 43694, - 62273, - 200121, - 2250, - 621004, - 149918, - 41063, - 218229, - 0, - 497924, - 16832, - 587071, - 0, - 0, - 729918, - 2, - 808513, - 9417, - 718, - 0, - 2769, - 28704, - 1335, - 734726, - 219157, - 786230, - 981004, - 350788, - 884529, - 0, - 87872, - 34647, - 85469, - 4524, - 339838, - 38228, - 0, - 4151, - 1145, - 0, - 351, - 167956, - 810075, - 689, - 251212, - 583068, - 2929, - 189456, - 2089, - 48749, - 278952, - 77134, - 0, - 0, - 45595, - 281829, - 969602, - 43999, - 69824, - 856982, - 61732, - 336, - 25488, - 213, - 46683, - 1909, - 174097, - 57930, - 91466, - 828418, - 95740, - 378828, - 128065, - 68068, - 0, - 13312, - 26006, - 6760, - 51, - 276081, - 640068, - 634985, - 7131, - 784882, - 790126, - 628585, - 205824, - 764965, - 17793, - 3159, - 649924, - 0, - 37383, - 9919, - 353, - 0, - 149003, - 620629, - 95928, - 2560, - 504343, - 1000, - 32, - 43836, - 407031, - 207, - 800894, - 3222, - 51028, - 7, - 6, - 22010, - 0, - 21174, - 12893, - 824932, - 7305, - 70, - 624258, - 372139, - 21504, - 387996, - 418931, - 914268, - 576, - 0, - 0, - 618224, - 787516, - 133014, - 422, - 383124, - 656318, - 4420, - 6082, - 244813, - 38585, - 3200, - 1, - 2, - 11882, - 113, - 45581, - 13121, - 95475, - 807219, - 8195, - 995116, - 13, - 2146, - 369925, - 60103, - 25, - 125165, - 51300, - 4894, - 173261, - 74186, - 1044, - 122992, - 1243, - 21703, - 26294, - 197, - 333825, - 426872, - 719580, - 3598, - 106, - 0, - 9932, - 61509, - 146, - 721428, - 964781, - 319850, - 573802, - 7458, - 317889, - 0, - 133086, - 87836, - 60496, - 304249, - 1565, - 27, - 42, - 899324, - 189637, - 8648, - 104570, - 901598, - 447765, - 24, - 108, - 120127, - 828626, - 8, - 899514, - 28, - 13, - 7576, - 163390, - 1625, - 3023, - 155175, - 2, - 391, - 1, - 493073, - 398, - 210771, - 26266, - 287999, - 38255, - 249666, - 598202, - 119601, - 216933, - 91205, - 0, - 7247, - 77077, - 565383, - 29102, - 253641, - 48855, - 19722, - 463536, - 40182, - 65393, - 829444, - 598402, - 1590, - 798, - 467, - 834847, - 3007, - 13711, - 0, - 195, - 101662, - 255749, - 129201, - 11965, - 1781, - 13349, - 3100, - 718066, - 99, - 712450, - 888215, - 42503, - 43171, - 494946, - 0, - 2175, - 12387, - 25662, - 78, - 739030, - 0, - 19, - 427526, - 4275, - 5583, - 0, - 2447, - 132398, - 26437, - 3873, - 440035, - 21, - 6, - 35432, - 41523, - 7179, - 712703, - 428868, - 2793, - 6, - 286277, - 1882, - 95116, - 2959, - 86, - 115425, - 81386, - 59836, - 37, - 247598, - 34732, - 249, - 500110, - 5589, - 40319, - 575, - 12145, - 385829, - 565600, - 582150, - 92, - 223209, - 0, - 910, - 1048, - 47329, - 90944, - 235, - 8739, - 686685, - 1753, - 126, - 434, - 609477, - 25021, - 6610, - 52675, - 4, - 717846, - 150864, - 418583, - 17751, - 513794, - 181362, - 329556, - 10426, - 717019, - 457, - 616, - 388984, - 17, - 8338, - 59531, - 32, - 99565, - 376146, - 134578, - 966, - 0, - 0, - 174, - 2105, - 555, - 8990, - 298, - 169932, - 247281, - 240918, - 298655, - 158743, - 15994, - 95708, - 51, - 2985, - 4294, - 731934, - 185640, - 1483, - 87, - 742033, - 9, - 1345, - 3680, - 133530, - 9355, - 800111, - 28508, - 0, - 369, - 31681, - 24, - 8237, - 313380, - 4732, - 275423, - 951592, - 0, - 41381, - 225515, - 393004, - 526, - 187, - 19515, - 6006, - 28923, - 310151, - 2390, - 374, - 0, - 19142, - 72, - 114, - 193305, - 24035, - 397067, - 18, - 14839, - 3473, - 164, - 104622, - 378958, - 2218, - 0, - 89053, - 105183, - 312265, - 82146, - 147210, - 3419, - 5178, - 34948, - 46836, - 41319, - 842825, - 595972, - 0, - 249625, - 325, - 608, - 372328, - 119634, - 7504, - 920214, - 7302, - 444532, - 359213, - 27265, - 1755, - 48, - 126799, - 651270, - 818220, - 799493, - 724024, - 64047, - 73699, - 206999, - 209, - 1581, - 0, - 42937, - 301144, - 73416, - 0, - 242058, - 29660, - 3, - 34709, - 162719, - 2863, - 3992, - 5212, - 151814, - 3092, - 198001, - 44331, - 36, - 407, - 364771, - 1349, - 502772, - 214726, - 607, - 388583, - 137660, - 337124, - 13279, - 10549, - 943075, - 164068, - 19157, - 38443, - 26351, - 0, - 67167, - 735, - 46486, - 130305, - 232330, - 744, - 882337, - 2, - 69275, - 126354, - 9370, - 2845, - 299, - 38988, - 37834, - 0, - 306433, - 9139, - 237132, - 0, - 500, - 13462, - 373684, - 107453, - 381924, - 347915, - 4329, - 1668, - 3960, - 370661, - 3614, - 636048, - 0, - 487449, - 64925, - 333894, - 11, - 52192, - 531200, - 155554, - 461, - 1547, - 994361, - 11955, - 321056, - 37425, - 14249, - 69151, - 621862, - 174, - 79607, - 34, - 77577, - 13723, - 267550, - 13801, - 698, - 12, - 171556, - 57354, - 676845, - 0, - 24965, - 908955, - 570483, - 0, - 296387, - 983966, - 85012, - 130298, - 151946, - 384474, - 731455, - 150699, - 772, - 216131, - 346, - 130935, - 3472, - 18, - 426045, - 677262, - 808, - 17030, - 5188, - 0, - 491153, - 67299, - 19, - 60342, - 69, - 0, - 76478, - 95763, - 0, - 28778, - 147869, - 335927, - 27846, - 2163, - 22750, - 162, - 23, - 11391, - 469099, - 5852, - 63, - 0, - 0, - 22193, - 165, - 489007, - 9249, - 12477, - 2841, - 223532, - 13877, - 173, - 3570, - 45477, - 233073, - 23296, - 64377, - 4910, - 8, - 76246, - 411147, - 287411, - 10450, - 3667, - 1, - 500933, - 31363, - 257, - 1705, - 6036, - 49934, - 13738, - 13485, - 61608, - 561978, - 76493, - 16377, - 1817, - 0, - 235600, - 0, - 16347, - 680478, - 5115, - 895607, - 138270, - 369912, - 53110, - 0, - 647083, - 85, - 458681, - 163227, - 52767, - 196, - 267719, - 14047, - 147293, - 814457, - 174896, - 0, - 34138, - 36, - 21575, - 3, - 0, - 0, - 38391, - 2597, - 2, - 1433, - 3807, - 36476, - 287, - 141530, - 29389, - 495655, - 30014, - 0, - 550766, - 11958, - 348, - 226760, - 15, - 251353, - 675788, - 518308, - 215, - 81987, - 409862, - 559596, - 114283, - 4925, - 0, - 17, - 14221, - 0, - 162, - 766370, - 4898, - 998, - 493, - 138418, - 265159, - 12152, - 5229, - 1204, - 1814, - 432530, - 2889, - 144, - 1149, - 35886, - 636931, - 6640, - 1508, - 414118, - 858, - 20039, - 17398, - 3, - 5094, - 6, - 13996, - 6754, - 362, - 451487, - 11471, - 7896, - 330009, - 244269, - 99928, - 0, - 14311, - 9949, - 15251, - 283923, - 123754, - 188360, - 93902, - 854384, - 548001, - 531788, - 26298, - 328479, - 941, - 246535, - 106320, - 28769, - 440, - 4, - 61262, - 55615, - 170, - 989327, - 692534, - 8063, - 445842, - 4434, - 255349, - 117781, - 6, - 9249, - 136216, - 38165, - 307012, - 12, - 2341, - 18062, - 371882, - 662154, - 12623, - 176847, - 332220, - 590935, - 33682, - 0, - 121374, - 67, - 46841, - 495890, - 640, - 19, - 14737, - 11032, - 17, - 5993, - 302562, - 827710, - 165346, - 49607, - 87863, - 308513, - 735300, - 1914, - 2900, - 207308, - 9068, - 83494, - 179, - 417, - 41605, - 74681, - 652171, - 4013, - 29811, - 13966, - 8136, - 78, - 61182, - 674187, - 0, - 331121, - 0, - 18559, - 386, - 77, - 348439, - 975358, - 18, - 33700, - 47396, - 204751, - 2350, - 26503, - 0, - 83653, - 446, - 10844, - 485, - 9241, - 88347, - 232419, - 936900, - 43250, - 2, - 26112, - 811955, - 20723, - 102069, - 42255, - 8431, - 119508, - 4080, - 13565, - 12, - 46110, - 62096, - 638777, - 44025, - 152985, - 13362, - 3, - 12331, - 193337, - 56419, - 14593, - 3837, - 282314, - 403454, - 48589, - 135, - 18350, - 2160, - 90, - 918216, - 7083, - 105534, - 742826, - 399028, - 1470, - 23770, - 480, - 677884, - 340472, - 107406, - 0, - 5002, - 445, - 748948, - 534012, - 592464, - 6539, - 819632, - 3138, - 4, - 39397, - 229683, - 12204, - 2439, - 65131, - 817226, - 22596, - 0, - 1046, - 94638, - 0, - 95403, - 1230, - 790056, - 19976, - 43085, - 14251, - 139187, - 20232, - 693, - 3058, - 27654, - 65690, - 40948, - 15001, - 21089, - 14425, - 322459, - 13571, - 228154, - 536814, - 761221, - 28030, - 2322, - 921, - 1, - 1137, - 187815, - 8, - 34911, - 4527, - 15, - 46, - 78801, - 0, - 73605, - 44, - 28233, - 1370, - 73409, - 198159, - 66586, - 3, - 2576, - 15, - 35460, - 263237, - 44997, - 2873, - 240, - 1781, - 269, - 46, - 272778, - 28404, - 8232, - 417073, - 234591, - 9, - 720349, - 1176, - 16195, - 0, - 9705, - 0, - 14, - 947048, - 163, - 76288, - 1115, - 267020, - 3416, - 414217, - 441004, - 95131, - 765002, - 6196, - 9069, - 27017, - 137039, - 65247, - 266489, - 484945, - 187008, - 45405, - 5700, - 9, - 7751, - 12, - 294, - 3093, - 6350, - 103303, - 6045, - 252345, - 140207, - 22390, - 234867, - 443326, - 1, - 0, - 89972, - 8637, - 427150, - 22146, - 0, - 310432, - 390333, - 10461, - 1632, - 31403, - 908653, - 0, - 6543, - 163479, - 67608, - 195543, - 315889, - 822964, - 383536, - 954954, - 1619, - 241, - 96053, - 104556, - 767302, - 2469, - 12, - 164330, - 78, - 141, - 170519, - 268214, - 53338, - 48342, - 721, - 58980, - 4345, - 1, - 856265, - 87289, - 57219, - 775679, - 123992, - 695804, - 113025, - 832, - 117420, - 16634, - 352, - 24729, - 14973, - 25622, - 131290, - 0, - 22, - 87740, - 5917, - 533, - 2934, - 34261, - 9174, - 0, - 1656, - 764587, - 54652, - 35597, - 36389, - 577889, - 63957, - 26808, - 34556, - 56, - 15641, - 137, - 1, - 3, - 11724, - 197397, - 39027, - 87902, - 320, - 791479, - 7, - 487864, - 0, - 433, - 25733, - 6956, - 15407, - 312557, - 526302, - 383019, - 340215, - 96, - 276158, - 6493, - 135613, - 2000, - 1218, - 930, - 276808, - 273249, - 8896, - 397, - 735095, - 20648, - 2079, - 5349, - 205, - 356313, - 841954, - 8255, - 266874, - 0, - 965, - 287993, - 1549, - 207833, - 75, - 178180, - 39072, - 0, - 43254, - 3847, - 227, - 2712, - 161043, - 463264, - 74720, - 795789, - 12, - 6812, - 202804, - 29379, - 64241, - 132121, - 790622, - 493588, - 0, - 48, - 147352, - 925197, - 38149, - 18380, - 0, - 270280, - 633, - 3373, - 31294, - 7830, - 0, - 0, - 11371, - 56143, - 5393, - 74724, - 495109, - 0, - 18993, - 21524, - 0, - 53889, - 400509, - 204563, - 0, - 11625, - 9635, - 0, - 1678, - 12096, - 59, - 817112, - 10002, - 128209, - 11593, - 17313, - 15200, - 106796, - 261401, - 707077, - 0, - 314030, - 798591, - 14175, - 5668, - 2766, - 0, - 566, - 5543, - 24112, - 154482, - 5642, - 0, - 38410, - 3, - 4, - 700724, - 25024, - 5, - 407, - 564150, - 672, - 143, - 2049, - 574708, - 65858, - 213412, - 3797, - 511, - 30907, - 1212, - 765, - 2127, - 481, - 130048, - 113816, - 39861, - 153169, - 503378, - 523944, - 111, - 55083, - 698, - 275, - 3, - 3195, - 1657, - 0, - 317881, - 6672, - 543, - 153011, - 77240, - 9338, - 889850, - 29518, - 872485, - 181927, - 376086, - 266, - 409, - 4, - 14856, - 31943, - 2448, - 8, - 75, - 383097, - 294366, - 0, - 173084, - 753160, - 66457, - 725783, - 51, - 127651, - 1073, - 12598, - 140080, - 0, - 296375, - 581720, - 217346, - 8272, - 2051, - 185390, - 520645, - 1260, - 13873, - 168040, - 19690, - 103347, - 295011, - 548404, - 48, - 4, - 916417, - 1948, - 621365, - 263245, - 2792, - 86803, - 181193, - 558081, - 50907, - 442770, - 51448, - 340276, - 1346, - 607, - 459627, - 0, - 30, - 73298, - 15389, - 12264, - 2719, - 2936, - 143043, - 209970, - 0, - 42, - 6657, - 317419, - 0, - 32622, - 524000, - 0, - 310331, - 303778, - 268710, - 9, - 10410, - 25343, - 949506, - 784353, - 3861, - 46823, - 251292, - 75008, - 269798, - 87731, - 112813, - 571679, - 385, - 3, - 2811, - 36025, - 9243, - 935128, - 906, - 10688, - 25, - 86757, - 307, - 55, - 22, - 2, - 61, - 620426, - 484530, - 633806, - 0, - 1342, - 9293, - 992181, - 503, - 195433, - 46150, - 893091, - 3207, - 2865, - 72894, - 830299, - 355, - 327479, - 0, - 35573, - 3068, - 15699, - 31187, - 55378, - 416067, - 91721, - 159, - 0, - 255139, - 2104, - 19, - 606757, - 323, - 902659, - 365655, - 400, - 903, - 408, - 385, - 21774, - 701290, - 234426, - 17020, - 950, - 0, - 0, - 429, - 1245, - 405871, - 1097, - 280634, - 74, - 158233, - 1583, - 180333, - 42114, - 575973, - 539327, - 59252, - 121928, - 165, - 148501, - 55757, - 7494, - 127728, - 7832, - 68504, - 619770, - 70995, - 312816, - 7307, - 38265, - 46248, - 363304, - 269442, - 77112, - 448331, - 910442, - 474418, - 152752, - 752, - 104912, - 408492, - 691709, - 632381, - 48519, - 20524, - 344294, - 14670, - 0, - 21607, - 81162, - 181458, - 0, - 908322, - 7261, - 10888, - 58054, - 1788, - 970933, - 5925, - 121553, - 36152, - 588267, - 23615, - 1850, - 30728, - 3599, - 1319, - 6027, - 0, - 32141, - 984156, - 436781, - 15003, - 621407, - 9412, - 562911, - 189740, - 377895, - 656800, - 197, - 14413, - 99382, - 384, - 11480, - 0, - 86118, - 881961, - 1905, - 82061, - 4140, - 741153, - 26, - 687, - 12251, - 10945, - 209267, - 220602, - 135881, - 6, - 237945, - 158, - 5, - 76303, - 81344, - 986042, - 956063, - 30282, - 186055, - 357802, - 12492, - 577476, - 838, - 0, - 11, - 117602, - 0, - 187928, - 96860, - 4268, - 3478, - 818264, - 1649, - 17175, - 272, - 158951, - 440987, - 677594, - 14935, - 37953, - 0, - 198, - 160404, - 12, - 287803, - 2386, - 10, - 271663, - 319152, - 361322, - 68370, - 428, - 182707, - 387429, - 1152, - 360065, - 25218, - 2790, - 42228, - 13, - 110942, - 452491, - 1, - 665638, - 2308, - 1196, - 87306, - 66, - 219, - 0, - 130736, - 334, - 605, - 5979, - 2681, - 0, - 123463, - 11219, - 283681, - 19269, - 553, - 6217, - 130965, - 714409, - 242, - 674833, - 237581, - 133284, - 683, - 1758, - 278193, - 518726, - 44, - 420361, - 325228, - 14955, - 10, - 11994, - 64157, - 1937, - 20214, - 848, - 27804, - 151341, - 79236, - 316393, - 158883, - 1196, - 334, - 22797, - 185955, - 13857, - 397357, - 7948, - 6038, - 0, - 2621, - 16, - 155267, - 44809, - 9171, - 21328, - 12212, - 40200, - 2600, - 439, - 804014, - 10938, - 96135, - 43696, - 158715, - 4, - 284558, - 191, - 270254, - 7923, - 880603, - 21032, - 107700, - 172, - 700823, - 5613, - 78816, - 258290, - 214398, - 821856, - 295325, - 0, - 1, - 23559, - 63895, - 21249, - 717490, - 956952, - 944819, - 793, - 356, - 757716, - 111773, - 394826, - 25665, - 4358, - 640216, - 1152, - 37175, - 150192, - 106071, - 28992, - 67, - 1685, - 134242, - 2, - 102045, - 1457, - 419589, - 6789, - 677, - 94675, - 11300, - 2595, - 8, - 926535, - 265194, - 0, - 886048, - 246242, - 1494, - 191, - 169985, - 649765, - 0, - 201, - 1069, - 679163, - 16627, - 274639, - 84438, - 3, - 1301, - 247496, - 5879, - 710904, - 403652, - 958241, - 361, - 139732, - 6042, - 15985, - 2378, - 267031, - 223767, - 9656, - 241717, - 33863, - 14314, - 205697, - 1274, - 168000, - 621777, - 837913, - 89654, - 659829, - 69, - 503884, - 432717, - 70443, - 110891, - 19655, - 132432, - 620401, - 428, - 0, - 425662, - 0, - 0, - 0, - 194489, - 7601, - 26870, - 0, - 63, - 594, - 12278, - 582479, - 213723, - 424489, - 96446, - 990664, - 46966, - 44137, - 829810, - 104, - 19707, - 16, - 0, - 2499, - 167075, - 140972, - 249283, - 6620, - 68368, - 856414, - 9255, - 14315, - 0, - 11432, - 24329, - 216463, - 299556, - 818401, - 246607, - 697733, - 229, - 144, - 389394, - 664634, - 0, - 19393, - 657903, - 52912, - 952177, - 536931, - 187271, - 17687, - 970155, - 232571, - 234016, - 159980, - 13510, - 32952, - 0, - 0, - 24132, - 18806, - 15624, - 28364, - 472126, - 626978, - 599, - 112843, - 502933, - 915660, - 63920, - 0, - 84, - 10899, - 904823, - 126, - 469132, - 590052, - 195831, - 443113, - 294149, - 15944, - 2271, - 282974, - 211, - 0, - 22934, - 82283, - 49973, - 41707, - 87530, - 0, - 910528, - 0, - 36029, - 423337, - 817512, - 223671, - 27800, - 398847, - 198528, - 1, - 560679, - 518270, - 23033, - 501059, - 0, - 3909, - 272062, - 261581, - 187, - 52043, - 334, - 24354, - 3947, - 8549, - 37863, - 328851, - 963771, - 1, - 3930, - 82416, - 6, - 2943, - 122101, - 82577, - 85, - 89540, - 5135, - 109236, - 18297, - 1, - 177371, - 4541, - 769577, - 178, - 417, - 960566, - 33803, - 911651, - 248160, - 153725, - 43981, - 809174, - 116, - 486900, - 4842, - 148490, - 131534, - 4347, - 239949, - 984096, - 749756, - 429499, - 2794, - 78209, - 18812, - 21111, - 490, - 328042, - 12, - 132119, - 505103, - 353148, - 0, - 373656, - 951244, - 491, - 355778, - 30620, - 317, - 60175, - 220, - 214496, - 41249, - 5169, - 78367, - 506804, - 0, - 1368, - 407, - 295126, - 1288, - 86, - 97614, - 61640, - 244723, - 3, - 0, - 869827, - 527246, - 52, - 107036, - 240739, - 780281, - 113084, - 62009, - 740343, - 483201, - 8649, - 16419, - 1, - 801574, - 95524, - 326126, - 26912, - 877040, - 10262, - 5895, - 0, - 132633, - 59171, - 306347, - 702701, - 196245, - 12642, - 32723, - 24608, - 30287, - 45775, - 18281, - 7587, - 144532, - 5, - 35, - 99862, - 215127, - 170875, - 61461, - 77790, - 5, - 0, - 129358, - 0, - 105084, - 21399, - 42233, - 85397, - 480654, - 555988, - 89575, - 42346, - 20004, - 11102, - 21321, - 185, - 379267, - 849147, - 121514, - 3388, - 33662, - 12, - 164898, - 226, - 274, - 385003, - 365052, - 693376, - 41245, - 9010, - 41594, - 89835, - 10490, - 272, - 128437, - 0, - 122648, - 277, - 116505, - 38372, - 4, - 1376, - 0, - 46317, - 139368, - 36398, - 193899, - 30632, - 26371, - 7548, - 367643, - 954849, - 25889, - 36567, - 176, - 140631, - 4690, - 975031, - 80965, - 500471, - 8442, - 43, - 27758, - 301501, - 3797, - 80, - 384440, - 928477, - 4960, - 24566, - 33245, - 14638, - 228354, - 54347, - 861285, - 12841, - 2, - 157402, - 646747, - 53763, - 1, - 214732, - 49471, - 49757, - 998, - 201135, - 566, - 73512, - 194240, - 391773, - 21510, - 13, - 829894, - 783200, - 565329, - 2101, - 12, - 191043, - 1621, - 18443, - 279, - 294135, - 526503, - 729735, - 4639, - 444138, - 5835, - 12372, - 46362, - 1543, - 870907, - 83262, - 0, - 38331, - 95, - 1194, - 909, - 8053, - 453066, - 845561, - 411, - 3229, - 1, - 158, - 1431, - 835137, - 21774, - 7298, - 148388, - 224649, - 379318, - 520138, - 39781, - 172130, - 362634, - 487495, - 51957, - 158, - 1770, - 7, - 18010, - 1063, - 171484, - 19924, - 279867, - 469956, - 189785, - 0, - 814, - 60580, - 944349, - 18743, - 553235, - 0, - 95475, - 99, - 0, - 5, - 42623, - 178418, - 398940, - 5700, - 69023, - 5786, - 0, - 10531, - 551, - 86308, - 63451, - 32704, - 176903, - 0, - 251689, - 11589, - 25711, - 43437, - 1431, - 304, - 52965, - 34816, - 268688, - 47756, - 825323, - 122608, - 81246, - 69974, - 360515, - 99973, - 143015, - 5063, - 4499, - 34459, - 171982, - 677943, - 489082, - 257515, - 3765, - 5, - 7416, - 602206, - 74122, - 3, - 686204, - 5493, - 28901, - 11349, - 549668, - 257082, - 82000, - 17031, - 1517, - 7442, - 937160, - 722, - 0, - 72952, - 377192, - 438266, - 555, - 31436, - 284, - 56390, - 0, - 585856, - 27635, - 519344, - 126131, - 360273, - 845073, - 0, - 191965, - 55652, - 23, - 112773, - 639025, - 84749, - 0, - 330822, - 7173, - 126217, - 871, - 112112, - 0, - 664, - 530474, - 1, - 379564, - 172617, - 647308, - 0, - 356, - 17, - 84345, - 457, - 0, - 8, - 6, - 136602, - 634424, - 0, - 177298, - 100726, - 91661, - 383792, - 1665, - 43583, - 15775, - 4083, - 4277, - 345749, - 969599, - 65804, - 19327, - 0, - 352514, - 4225, - 9, - 103767, - 0, - 0, - 148436, - 850, - 33, - 2146, - 20153, - 50, - 9063, - 50329, - 348379, - 2569, - 83697, - 37073, - 715486, - 629, - 4753, - 442, - 259203, - 287223, - 48625, - 9, - 70184, - 45946, - 144947, - 0, - 60285, - 28640, - 7626, - 134159, - 33, - 12452, - 150566, - 348293, - 124426, - 353952, - 11, - 22, - 776742, - 29072, - 132168, - 254533, - 319957, - 1602, - 1659, - 209341, - 32847, - 92392, - 753005, - 1392, - 10271, - 28557, - 6717, - 941745, - 0, - 0, - 0, - 78645, - 45320, - 11193, - 1448, - 130626, - 377907, - 795535, - 24285, - 26094, - 266691, - 64449, - 77400, - 191410, - 1, - 1346, - 25224, - 489637, - 47052, - 248592, - 76689, - 0, - 7722, - 47285, - 3152, - 285577, - 0, - 149366, - 264346, - 1, - 208602, - 320459, - 131771, - 1421, - 350, - 723283, - 714934, - 0, - 566439, - 11656, - 34189, - 125484, - 943273, - 15, - 7789, - 0, - 7427, - 464278, - 680924, - 651102, - 87794, - 39640, - 838644, - 964500, - 1, - 1765, - 272604, - 10, - 837347, - 44845, - 130, - 163357, - 4150, - 403331, - 839132, - 44876, - 272792, - 592527, - 57225, - 128826, - 2915, - 2, - 3570, - 2410, - 199, - 171358, - 5931, - 53620, - 55299, - 1868, - 24123, - 165, - 346513, - 16527, - 133, - 517412, - 195700, - 730365, - 896209, - 152760, - 24577, - 65, - 8218, - 349642, - 901345, - 5127, - 5102, - 238318, - 955, - 631921, - 12218, - 55101, - 930381, - 219503, - 469237, - 132, - 16701, - 494, - 199729, - 0, - 32139, - 314, - 172, - 2947, - 106997, - 4871, - 236, - 6146, - 1843, - 128, - 0, - 254240, - 2964, - 14825, - 60624, - 2108, - 286953, - 654931, - 0, - 0, - 396587, - 19852, - 70311, - 363561, - 282, - 17966, - 924254, - 104173, - 130816, - 179096, - 105466, - 136, - 618261, - 358433, - 25587, - 49357, - 102, - 133746, - 620776, - 17084, - 406881, - 802675, - 349, - 69, - 8761, - 278482, - 16336, - 128, - 160096, - 25857, - 280, - 39639, - 726299, - 293905, - 4621, - 41, - 649, - 3655, - 269286, - 578026, - 0, - 11156, - 1, - 744858, - 531, - 48155, - 28435, - 7991, - 447, - 10201, - 379341, - 0, - 5773, - 0, - 295, - 228592, - 331155, - 104089, - 628069, - 29693, - 22, - 13, - 0, - 0, - 554349, - 6082, - 238, - 23, - 151873, - 805937, - 0, - 194076, - 6450, - 3, - 128322, - 69149, - 95511, - 86, - 844368, - 415964, - 51985, - 308686, - 553403, - 624943, - 365800, - 4, - 120263, - 91239, - 195248, - 58010, - 19, - 415112, - 136806, - 42, - 571848, - 55306, - 29454, - 3, - 144926, - 189, - 0, - 161943, - 592155, - 10930, - 279297, - 56932, - 957430, - 10244, - 190296, - 807209, - 781, - 1466, - 235055, - 33, - 196, - 58280, - 436, - 408649, - 221, - 711143, - 10495, - 2441, - 275720, - 2, - 15391, - 132107, - 102610, - 688549, - 237142, - 3041, - 14, - 308623, - 0, - 0, - 287, - 295147, - 61443, - 229, - 207, - 2051, - 64, - 13479, - 55656, - 570134, - 50387, - 225869, - 20615, - 258465, - 64932, - 112461, - 164521, - 907269, - 758563, - 22901, - 0, - 7944, - 48, - 154921, - 2784, - 548608, - 0, - 12524, - 142556, - 0, - 13882, - 507227, - 316598, - 987551, - 0, - 894687, - 1964, - 364, - 10316, - 440269, - 9, - 776723, - 72288, - 54604, - 185101, - 142, - 362, - 11679, - 77, - 79, - 529321, - 364, - 42387, - 0, - 570879, - 417503, - 604871, - 578806, - 1102, - 66584, - 615440, - 146744, - 19441, - 170478, - 144069, - 36170, - 145376, - 842283, - 193612, - 3, - 359429, - 368596, - 0, - 11064, - 7726, - 229410, - 63569, - 67402, - 91, - 203201, - 213513, - 0, - 704479, - 1325, - 0, - 385154, - 13, - 806763, - 197132, - 6183, - 45760, - 99377, - 0, - 972077, - 4043, - 195700, - 34229, - 0, - 154027, - 633, - 6, - 32142, - 0, - 29, - 620842, - 14099, - 495465, - 26937, - 0, - 0, - 432, - 227704, - 0, - 63, - 0, - 19, - 863491, - 20, - 1, - 160713, - 24607, - 85800, - 3566, - 37854, - 81913, - 121573, - 816, - 20, - 133253, - 692231, - 4869, - 255175, - 15028, - 9383, - 542877, - 4608, - 369610, - 243635, - 385285, - 391565, - 286009, - 0, - 61685, - 416318, - 208, - 67019, - 788416, - 88, - 165056, - 0, - 439589, - 160, - 105528, - 152, - 160624, - 865, - 390229, - 714086, - 6007, - 30229, - 481306, - 173266, - 1135, - 2266, - 8, - 59, - 104722, - 647885, - 579471, - 21309, - 230834, - 140278, - 31858, - 3288, - 36011, - 151387, - 594217, - 22439, - 418638, - 76859, - 29363, - 154809, - 275533, - 39, - 472996, - 22076, - 7481, - 155705, - 10406, - 214779, - 223, - 1312, - 16391, - 17203, - 55605, - 44579, - 69332, - 303, - 19217, - 26288, - 126212, - 316, - 98, - 114, - 37382, - 137591, - 439749, - 12972, - 54, - 154879, - 0, - 102680, - 7639, - 309119, - 263550, - 766, - 1124, - 56, - 686608, - 123767, - 518054, - 18, - 672385, - 3161, - 53791, - 26769, - 451670, - 61, - 148245, - 2713, - 96725, - 4794, - 33247, - 297946, - 33380, - 0, - 20034, - 5647, - 17227, - 76444, - 0, - 21011, - 675, - 13226, - 1027, - 990842, - 124459, - 34406, - 53, - 69540, - 134, - 0, - 168521, - 6, - 4075, - 1137, - 63740, - 220, - 10434, - 1171, - 28950, - 0, - 79680, - 993269, - 355622, - 15, - 0, - 1452, - 21667, - 22208, - 494484, - 33984, - 691308, - 10, - 693686, - 196, - 9, - 70676, - 157660, - 775, - 165, - 468432, - 1083, - 515154, - 778344, - 70241, - 42, - 40931, - 277125, - 43837, - 301881, - 1332, - 56712, - 9013, - 1299, - 7564, - 31092, - 1975, - 113517, - 833295, - 245021, - 36503, - 23586, - 149327, - 89175, - 10512, - 484348, - 187793, - 954609, - 53199, - 792175, - 126, - 12369, - 405, - 0, - 6614, - 322857, - 166, - 571874, - 60839, - 180975, - 146722, - 411565, - 1536, - 1, - 11, - 116230, - 60514, - 9003, - 2325, - 43763, - 63, - 355553, - 0, - 389876, - 14672, - 11526, - 160209, - 65, - 10283, - 966, - 10, - 58333, - 129920, - 2850, - 83346, - 0, - 14, - 295819, - 679550, - 143928, - 29489, - 82324, - 36558, - 267118, - 143313, - 90107, - 12789, - 951, - 0, - 187619, - 295317, - 82, - 41326, - 309682, - 907327, - 809358, - 324, - 139157, - 12, - 78366, - 671811, - 354, - 131, - 70525, - 35830, - 281018, - 91456, - 92523, - 54874, - 48273, - 2423, - 0, - 81, - 361314, - 374811, - 394758, - 15350, - 795, - 3, - 16779, - 796684, - 477556, - 73927, - 26643, - 119281, - 62692, - 17039, - 454778, - 952, - 48973, - 19529, - 151, - 239121, - 93509, - 254702, - 1307, - 10029, - 7973, - 546706, - 806644, - 680517, - 223, - 0, - 2, - 0, - 402421, - 619193, - 15685, - 2, - 939715, - 519198, - 0, - 444312, - 23204, - 35669, - 32467, - 0, - 799725, - 5883, - 2217, - 32292, - 355557, - 22179, - 1066, - 15704, - 610, - 37819, - 403626, - 83101, - 10989, - 311607, - 43394, - 72576, - 335450, - 85964, - 73734, - 105142, - 38292, - 0, - 181516, - 33959, - 611797, - 221838, - 5931, - 7666, - 1044, - 477173, - 13591, - 405, - 521, - 190653, - 184191, - 0, - 215, - 847195, - 22782, - 11912, - 27345, - 2572, - 0, - 566350, - 7, - 52302, - 26641, - 587826, - 127, - 2, - 44449, - 153198, - 14, - 926, - 285, - 0, - 938196, - 52255, - 9153, - 807, - 12548, - 358324, - 18521, - 104956, - 42738, - 116, - 135772, - 189554, - 38, - 54, - 36, - 89768, - 17170, - 75, - 34502, - 45489, - 172796, - 971810, - 16153, - 499280, - 1, - 879663, - 53830, - 186, - 539, - 242059, - 268, - 402, - 2732, - 68057, - 18463, - 198560, - 10068, - 591753, - 6116, - 699280, - 1, - 0, - 114258, - 277, - 149, - 283821, - 352561, - 88172, - 684476, - 3450, - 87, - 99936, - 3155, - 72983, - 31619, - 8832, - 58666, - 0, - 59023, - 306091, - 352150, - 255063, - 992708, - 23, - 4896, - 18165, - 424401, - 227613, - 5175, - 347, - 139846, - 11962, - 714, - 3501, - 82367, - 11110, - 10, - 12874, - 0, - 0, - 222712, - 169, - 123281, - 0, - 268149, - 101, - 17446, - 4262, - 489, - 0, - 30, - 0, - 277235, - 28, - 71, - 23, - 61219, - 953631, - 477548, - 662491, - 273, - 44787, - 4130, - 14483, - 470571, - 735977, - 406648, - 815898, - 5985, - 462696, - 937510, - 9, - 0, - 111727, - 93, - 331435, - 336402, - 78690, - 49, - 0, - 87422, - 1242, - 0, - 8783, - 8540, - 314, - 33411, - 805718, - 247, - 6870, - 523743, - 8323, - 612593, - 430, - 354048, - 264913, - 83, - 114063, - 202825, - 35202, - 32823, - 185554, - 85760, - 45159, - 5971, - 267733, - 4545, - 116, - 6910, - 24833, - 218, - 922362, - 221735, - 740, - 7112, - 31, - 15739, - 523589, - 4, - 95996, - 936, - 823951, - 0, - 88, - 160, - 375419, - 663627, - 3741, - 22896, - 114326, - 415962, - 880100, - 6222, - 18650, - 35524, - 195076, - 506, - 451640, - 541336, - 70903, - 3946, - 1, - 61765, - 1, - 2696, - 753129, - 289, - 225234, - 378692, - 1703, - 6751, - 1, - 820, - 7677, - 589, - 12412, - 317, - 69, - 226031, - 134523, - 318253, - 66677, - 111025, - 96, - 0, - 96, - 523528, - 1017, - 0, - 258740, - 420947, - 4600, - 400684, - 12174, - 11770, - 52, - 5959, - 82658, - 531787, - 202, - 548430, - 964, - 1054, - 34, - 96897, - 25445, - 47609, - 386052, - 97004, - 1935, - 30074, - 13458, - 494105, - 54, - 65575, - 594698, - 2340, - 20259, - 84, - 2774, - 534, - 972534, - 115057, - 0, - 11379, - 0, - 271, - 266305, - 132595, - 2, - 773561, - 52365, - 3585, - 351, - 148206, - 778964, - 149379, - 596, - 284914, - 2900, - 35596, - 1547, - 212027, - 8100, - 12248, - 3013, - 1814, - 183415, - 273633, - 15812, - 0, - 966680, - 14830, - 134309, - 0, - 416450, - 206611, - 816, - 82258, - 9873, - 3155, - 53485, - 779805, - 107690, - 254475, - 102504, - 72495, - 17301, - 472130, - 6895, - 245420, - 7299, - 110508, - 27776, - 246134, - 0, - 330853, - 0, - 271767, - 61886, - 24123, - 309681, - 58325, - 608865, - 20666, - 87349, - 229228, - 246, - 457768, - 5374, - 69643, - 148, - 618375, - 45236, - 352565, - 133904, - 152, - 10688, - 18, - 0, - 276036, - 493281, - 11156, - 12566, - 5762, - 113, - 24179, - 98, - 327, - 893, - 209180, - 140805, - 0, - 2341, - 66309, - 30305, - 630559, - 3682, - 152767, - 265822, - 142868, - 1535, - 728603, - 69081, - 353151, - 237995, - 1075, - 925071, - 86, - 6748, - 0, - 684186, - 735, - 13793, - 4790, - 73175, - 69677, - 367627, - 238650, - 303543, - 1, - 26059, - 21392, - 10, - 288609, - 0, - 76345, - 158496, - 7000, - 1865, - 20385, - 0, - 54213, - 9948, - 102667, - 6963, - 71, - 555744, - 5626, - 2512, - 1124, - 7171, - 628, - 29225, - 321687, - 61519, - 4, - 8352, - 9156, -}; - -char *pointers[NCYCLES]; - -int main(void) -{ - int r, i, j, sp, sq; - char *p, *q, *ep, *eq; - int ok; - int err = 0; - - for ( r = 0 ; r < 4 ; r++ ) { - for ( i = 0 ; i < NCYCLES ; i++ ) { - pointers[i] = p = malloc(sp = sizes[i]); - ep = p+sp; - ok = 1; - for ( j = 0 ; j < i ; j++ ) { - q = pointers[j]; - sq = sizes[j]; - eq = q+sq; - - if ( (p < q && ep > q) || (p >= q && p < eq) ) { - ok = 0; - err = 1; - break; - } - } - printf("Allocated %6d bytes at %p, ok = %d\n", sp, p, ok); - - if ( p ) - memset(p, 0xee, sp); /* Poison this memory */ - } - - for ( i = 0 ; i < NCYCLES ; i++ ) { - free(pointers[i]); - printf("Freed %6d bytes at %p\n", sizes[i], pointers[i]); - } - } - - return err; -} - diff --git a/klibc/klibc/tests/malloctest2.c b/klibc/klibc/tests/malloctest2.c deleted file mode 100644 index b392046929..0000000000 --- a/klibc/klibc/tests/malloctest2.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include - -#define NCYCLES 32768 -#define NSLOTS 4096 - -struct slot { - char *ptr; - size_t size; -}; - -struct slot s[NSLOTS]; - -int main(void) -{ - size_t sp, sq; - char *p, *ep, *q, *eq; - int r, i, j; - int ok; - int err = 0; - - for ( r = 0 ; r < NCYCLES ; r++ ) { - i = lrand48() % NSLOTS; - - if ( s[i].ptr ) { - free(s[i].ptr); - printf("Freed %8zu bytes at %p\n", s[i].size, s[i].ptr); - s[i].ptr = NULL; - s[i].size = 0; - } else { - sp = lrand48(); /* 32-bit random number */ - sp >>= 12+(lrand48() % 20); - - s[i].size = sp; - s[i].ptr = p = malloc(sp); - ep = p+sp; - ok = 1; - for ( j = 0 ; j < NSLOTS ; j++ ) { - q = s[j].ptr; - if ( i != j && q ) { - sq = s[j].size; - eq = q+sq; - - if ( (p < q && ep > q) || (p >= q && p < eq) ) { - ok = 0; - err = 1; - break; - } - } - } - printf("Allocated %8zu bytes at %p, ok = %d\n", sp, p, ok); - - if ( p ) - memset(p, 0xee, sp); /* Poison this memory */ - } - } - return err; -} - diff --git a/klibc/klibc/tests/memstrtest.c b/klibc/klibc/tests/memstrtest.c deleted file mode 100644 index 70c642c067..0000000000 --- a/klibc/klibc/tests/memstrtest.c +++ /dev/null @@ -1,29 +0,0 @@ -#include -#include -#include - -int main(void) -{ - unsigned char t1[256], t2[256]; - int i; - int r; - - for(i = 0; i < (int)sizeof(t1); i++) - t1[i] = t2[i] = (unsigned char)i; - - r = memcmp(t1, t2, sizeof(t1)); - printf("memcmp r = %d\n", r); - r = memcmp(t1, t2, sizeof(t1)/2); - printf("memcmp r = %d\n", r); - t1[255] = 0; - r = memcmp(t1, t2, sizeof(t1)); - printf("memcmp r = %d\n", r); - - for (i = 0; i < (int)sizeof(t1); i++) - t1[i] = 0xaa; - memset(t2, 0xaa, sizeof(t2)); - r = memcmp(t1, t2, sizeof(t1)); - printf("memcmp r = %d\n", r); - return 0; -} - diff --git a/klibc/klibc/tests/microhello.c b/klibc/klibc/tests/microhello.c deleted file mode 100644 index f0f5a40379..0000000000 --- a/klibc/klibc/tests/microhello.c +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -int main(void) -{ - static const char hello[] = "Hello, World!\n"; - _fwrite(hello, sizeof hello-1, stdout); - return 0; -} diff --git a/klibc/klibc/tests/minihello.c b/klibc/klibc/tests/minihello.c deleted file mode 100644 index 7698e0666b..0000000000 --- a/klibc/klibc/tests/minihello.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int main(void) -{ - fputs("Hello, World!\n", stdout); - return 0; -} diff --git a/klibc/klibc/tests/mmaptest.c b/klibc/klibc/tests/mmaptest.c deleted file mode 100644 index a654affb83..0000000000 --- a/klibc/klibc/tests/mmaptest.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * mmaptest.c - * - * Test some simple cases of mmap() - */ - -#include -#include -#include -#include -#include -#include - -int main(int argc, char *argv[]) -{ - void *foo; - - (void)argc; (void)argv; - - /* Important case, this is how we get memory for malloc() */ - errno = 0; - foo = mmap(0, 65536, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); - - printf("mmap() returned %p, errno = %d\n", foo, errno); - - return 0; -} diff --git a/klibc/klibc/tests/nfs_no_rpc.c b/klibc/klibc/tests/nfs_no_rpc.c deleted file mode 100644 index 5c17706b63..0000000000 --- a/klibc/klibc/tests/nfs_no_rpc.c +++ /dev/null @@ -1,538 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Default path we try to mount. "%s" gets replaced by our IP address */ -#define NFS_ROOT "/tftpboot/%s" -#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096 -#define NFS_MAXPATHLEN 1024 -#define NFS_MNT_PROGRAM 100005 -#define NFS_MNT_PORT 627 -#define NFS_PROGRAM 100003 -#define NFS_PORT 2049 -#define NFS2_VERSION 2 -#define NFS3_VERSION 3 -#define NFS_MNT_PROGRAM 100005 -#define NFS_MNT_VERSION 1 -#define NFS_MNT3_VERSION 3 -#define MNTPROC_MNT 1 -#define MOUNTPROC3_MNT 1 -#define RPC_PMAP_PROGRAM 100000 -#define RPC_PMAP_VERSION 2 -#define RPC_PMAP_PORT 111 - -#define NFS2_FHSIZE 32 -#define NFS3_FHSIZE 64 - -#define RPC_VERSION 2 - -enum rpc_msg_type { - RPC_CALL = 0, - RPC_REPLY = 1 -}; - -enum rpc_auth_flavor { - RPC_AUTH_NULL = 0, - RPC_AUTH_UNIX = 1, - RPC_AUTH_SHORT = 2, - RPC_AUTH_DES = 3, - RPC_AUTH_KRB = 4, -}; - -enum rpc_reply_stat { - RPC_MSG_ACCEPTED = 0, - RPC_MSG_DENIED = 1 -}; - -#define NFS_MAXFHSIZE 64 -struct nfs_fh { - unsigned short size; - unsigned char data[NFS_MAXFHSIZE]; -}; - -struct nfs2_fh { - char data[NFS2_FHSIZE]; -}; - -#define NFS_MOUNT_VERSION 4 - -struct nfs_mount_data { - int version; - int fd; - struct nfs2_fh old_root; - int flags; - int rsize; - int wsize; - int timeo; - int retrans; - int acregmin; - int acregmax; - int acdirmin; - int acdirmax; - struct sockaddr_in addr; - char hostname[256]; - int namlen; - unsigned int bsize; - struct nfs_fh root; -}; - -#define NFS_MOUNT_SOFT 0x0001 /* 1 */ -#define NFS_MOUNT_INTR 0x0002 /* 1 */ -#define NFS_MOUNT_SECURE 0x0004 /* 1 */ -#define NFS_MOUNT_POSIX 0x0008 /* 1 */ -#define NFS_MOUNT_NOCTO 0x0010 /* 1 */ -#define NFS_MOUNT_NOAC 0x0020 /* 1 */ -#define NFS_MOUNT_TCP 0x0040 /* 2 */ -#define NFS_MOUNT_VER3 0x0080 /* 3 */ -#define NFS_MOUNT_KERBEROS 0x0100 /* 3 */ -#define NFS_MOUNT_NONLM 0x0200 /* 3 */ -#define NFS_MOUNT_BROKEN_SUID 0x0400 /* 4 */ -#define NFS_MOUNT_FLAGMASK 0xFFFF - -static char nfs_root_name[256]; -static u_int32_t root_server_addr; -static char root_server_path[256]; - -/* Address of NFS server */ -static u_int32_t servaddr; - -/* Name of directory to mount */ -static char nfs_path[NFS_MAXPATHLEN]; - -/* NFS-related data */ -static struct nfs_mount_data nfs_data = { - .version = NFS_MOUNT_VERSION, - .flags = NFS_MOUNT_NONLM, /* No lockd in nfs root yet */ - .rsize = NFS_DEF_FILE_IO_BUFFER_SIZE, - .wsize = NFS_DEF_FILE_IO_BUFFER_SIZE, - .bsize = 0, - .timeo = 7, - .retrans = 3, - .acregmin = 3, - .acregmax = 60, - .acdirmin = 30, - .acdirmax = 60, -}; -static int nfs_port = -1; -static int mount_port; - -/*************************************************************************** - - Parsing of options - - ***************************************************************************/ - -/* - * The following integer options are recognized - */ -static struct nfs_int_opts { - const char *name; - int *val; -} root_int_opts[] = { - { "port", &nfs_port }, - { "rsize", &nfs_data.rsize }, - { "wsize", &nfs_data.wsize }, - { "timeo", &nfs_data.timeo }, - { "retrans", &nfs_data.retrans }, - { "acregmin", &nfs_data.acregmin }, - { "acregmax", &nfs_data.acregmax }, - { "acdirmin", &nfs_data.acdirmin }, - { "acdirmax", &nfs_data.acdirmax }, - { NULL, NULL } -}; - -/* - * And now the flag options - */ -static struct nfs_bool_opts { - const char *name; - int and_mask; - int or_mask; -} root_bool_opts[] = { - { "soft", ~NFS_MOUNT_SOFT, NFS_MOUNT_SOFT }, - { "hard", ~NFS_MOUNT_SOFT, 0 }, - { "intr", ~NFS_MOUNT_INTR, NFS_MOUNT_INTR }, - { "nointr", ~NFS_MOUNT_INTR, 0 }, - { "posix", ~NFS_MOUNT_POSIX, NFS_MOUNT_POSIX }, - { "noposix", ~NFS_MOUNT_POSIX, 0 }, - { "cto", ~NFS_MOUNT_NOCTO, 0 }, - { "nocto", ~NFS_MOUNT_NOCTO, NFS_MOUNT_NOCTO }, - { "ac", ~NFS_MOUNT_NOAC, 0 }, - { "noac", ~NFS_MOUNT_NOAC, NFS_MOUNT_NOAC }, - { "lock", ~NFS_MOUNT_NONLM, 0 }, - { "nolock", ~NFS_MOUNT_NONLM, NFS_MOUNT_NONLM }, -#ifdef CONFIG_NFS_V3 - { "v2", ~NFS_MOUNT_VER3, 0 }, - { "v3", ~NFS_MOUNT_VER3, NFS_MOUNT_VER3 }, -#endif - { "udp", ~NFS_MOUNT_TCP, 0 }, - { "tcp", ~NFS_MOUNT_TCP, NFS_MOUNT_TCP }, - { "broken_suid",~NFS_MOUNT_BROKEN_SUID, NFS_MOUNT_BROKEN_SUID }, - { NULL, 0, 0 } -}; -/* - * Parse option string. - */ -static void root_nfs_parse(char *name, char *buf) -{ - char *options, *val, *cp; - - if ((options = strchr(name, ','))) { - *options++ = 0; - cp = strtok(options, ","); - while (cp) { - if ((val = strchr(cp, '='))) { - struct nfs_int_opts *opts = root_int_opts; - *val++ = '\0'; - while (opts->name && strcmp(opts->name, cp)) - opts++; - if (opts->name) - *(opts->val) = (int) strtoul(val, NULL, 10); - } else { - struct nfs_bool_opts *opts = root_bool_opts; - while (opts->name && strcmp(opts->name, cp)) - opts++; - if (opts->name) { - nfs_data.flags &= opts->and_mask; - nfs_data.flags |= opts->or_mask; - } - } - cp = strtok(NULL, ","); - } - } - if (name[0] && strcmp(name, "default")) { - strncpy(buf, name, NFS_MAXPATHLEN-1); - buf[NFS_MAXPATHLEN-1] = 0; - } -} - -/* - * Prepare the NFS data structure and parse all options. - */ -static int root_nfs_name(char *name) -{ - char buf[NFS_MAXPATHLEN]; - struct utsname uname_buf; - - /* Set some default values */ - strcpy(buf, NFS_ROOT); - - /* Process options received from the remote server */ - root_nfs_parse(root_server_path, buf); - - /* Override them by options set on kernel command-line */ - root_nfs_parse(name, buf); - - uname(&uname_buf); - if (strlen(buf) + strlen(uname_buf.nodename) > NFS_MAXPATHLEN) { - printf("nfsroot: Pathname for remote directory too long.\n"); - return -1; - } - sprintf(nfs_path, buf, uname_buf.nodename); - - return 1; -} - -/*************************************************************************** - - Routines to actually mount the root directory - - ***************************************************************************/ - -/* - * Construct sockaddr_in from address and port number. - */ -static inline void -set_sockaddr(struct sockaddr_in *sin, u_int32_t addr, u_int16_t port) -{ - memset(sin, 0, sizeof(*sin)); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = addr; - sin->sin_port = port; -} - -/* - * Extremely crude RPC-over-UDP call. We get an already encoded request - * to pass, we do that and put the reply into buffer. That (and callers - * below - getport, getfh2 and getfh3) should be replaced with proper - * librpc use. Now, if we only had one that wasn't bloated as a dead - * gnu that had lied for a while under the sun... - */ - -static u_int32_t XID; -static int flag; -static void timeout(int n) -{ - (void)n; - flag = 1; -} -static int do_call(struct sockaddr_in *sin, u_int32_t msg[], u_int32_t rmsg[], - u_int32_t len, u_int32_t rlen) -{ - struct sockaddr_in from; - int slen = sizeof(struct sockaddr_in); - struct timeval tv = {1, 0}; - int n; - int fd; - - sysv_signal(SIGALRM, timeout); - fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (fd < 0) - goto Esocket; - setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (void*)&tv, sizeof(tv)); - len *= 4; - if (sendto(fd, msg, len, 0, (struct sockaddr *)sin, slen)!=(int)len) - goto Esend; - setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (void*)&tv, sizeof(tv)); - alarm(0); - flag = 0; - alarm(5); - rlen *= 4; - do { - slen = sizeof(from); - n = recvfrom(fd, rmsg, rlen, 0, (struct sockaddr*)&from, &slen); - if (flag || n < 0) - goto Erecv; - } while (memcmp(&from, sin, sizeof(from)) || rmsg[0] != msg[0]); - - if (n < 6*4 || n % 4 || ntohl(rmsg[1]) != 1 || rmsg[2] || - rmsg[3] || rmsg[4] || rmsg[5]) - goto Einval; - alarm(0); - close(fd); - return n / 4 - 6; - -Esend: printf("rpc: write failed\n"); - goto out; -Erecv: printf("rpc: read failed\n"); - goto out; -Einval: printf("rpc: invalid response\n"); - goto out; -Esocket:printf("rpc: can't create socket\n"); - return -1; -out: - alarm(0); - close(fd); - return -1; -} - -enum { - PMAP_GETPORT = 3 -}; - -static void do_header(u_int32_t msg[], u_int32_t prog, u_int32_t vers, u_int32_t proc) -{ - msg[0] = XID++; - msg[1] = htonl(RPC_CALL); - msg[2] = htonl(RPC_VERSION); - msg[3] = htonl(prog); - msg[4] = htonl(vers); - msg[5] = htonl(proc); - msg[6] = htonl(RPC_AUTH_NULL); - msg[7] = htonl(0); - msg[8] = htonl(RPC_AUTH_NULL); - msg[9] = htonl(0); -} - -static int getport(u_int32_t prog, u_int32_t vers, u_int32_t prot) -{ - struct sockaddr_in sin; - unsigned msg[14]; - unsigned rmsg[7]; - int n; - set_sockaddr(&sin, servaddr, htons(RPC_PMAP_PORT)); - do_header(msg, RPC_PMAP_PROGRAM, RPC_PMAP_VERSION, PMAP_GETPORT); - msg[10] = htonl(prog); - msg[11] = htonl(vers); - msg[12] = htonl(prot); - msg[13] = htonl(0); - n = do_call(&sin, msg, rmsg, 14, 7); - if (n <= 0) - return -1; - else - return ntohl(rmsg[6]); -} - -static int getfh2(void) -{ - struct sockaddr_in sin; - unsigned msg[10+1+256/4]; - unsigned rmsg[6 + 1 + NFS2_FHSIZE/4]; - int n; - int len = strlen(nfs_path); - set_sockaddr(&sin, servaddr, mount_port); - - if (len > 255) { - printf("nfsroot: pathname is too long"); - return -1; - } - memset(msg, 0, sizeof(msg)); - do_header(msg, NFS_MNT_PROGRAM, NFS_MNT_VERSION, MNTPROC_MNT); - msg[10] = htonl(len); - strcpy((char*)&msg[11], nfs_path); - n = do_call(&sin, msg, rmsg, 11 + (len + 3)/4, 7 + NFS2_FHSIZE/4); - if (n < 0) - return -1; - if (n != NFS2_FHSIZE/4 + 1) - goto Esize; - if (rmsg[6]) { - printf("nfsroot: mountd returned an error (%d)",htonl(rmsg[6])); - return -1; - } - nfs_data.root.size = NFS2_FHSIZE; - memcpy(nfs_data.root.data, &rmsg[7], NFS2_FHSIZE); - return 0; -Esize: - printf("nfsroot: bad fhandle size"); - return -1; -} - -static int getfh3(void) -{ - struct sockaddr_in sin; - unsigned msg[10+1+256/4]; - unsigned rmsg[6 + 1 + 1 + NFS3_FHSIZE/4]; - int n; - int len = strlen(nfs_path); - int size; - set_sockaddr(&sin, servaddr, mount_port); - - if (len > 255) { - printf("nfsroot: pathname is too long"); - return -1; - } - memset(msg, 0, sizeof(msg)); - do_header(msg, NFS_MNT_PROGRAM, NFS_MNT3_VERSION, MOUNTPROC3_MNT); - msg[10] = htonl(len); - strcpy((char*)&msg[11], nfs_path); - n = do_call(&sin, msg, rmsg, 11 + (len + 3)/4, 8 + NFS3_FHSIZE/4); - if (n < 0) - return -1; - if (n <= 2) - goto Esize; - if (rmsg[6]) { - printf("nfsroot: mountd returned an error (%d)",htonl(rmsg[6])); - return -1; - } - size = ntohl(rmsg[7]); - if (size > NFS3_FHSIZE || n != 2 + size/4) - goto Esize; - nfs_data.root.size = size; - memcpy(nfs_data.root.data, &rmsg[8], size); - return 0; -Esize: - printf("nfsroot: bad fhandle size"); - return -1; -} - -/* - * Use portmapper to find mountd and nfsd port numbers if not overriden - * by the user. Use defaults if portmapper is not available. - * XXX: Is there any nfs server with no portmapper? - */ -static int root_nfs_ports(void) -{ - int port; - int nfsd_ver, mountd_ver; - int proto; - - if (nfs_data.flags & NFS_MOUNT_VER3) { - nfsd_ver = NFS3_VERSION; - mountd_ver = NFS_MNT3_VERSION; - } else { - nfsd_ver = NFS2_VERSION; - mountd_ver = NFS_MNT_VERSION; - } - - proto = (nfs_data.flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP; - - if (nfs_port < 0) { - if ((port = getport(NFS_PROGRAM, nfsd_ver, proto)) < 0) { - printf("nfsroot: Unable to get nfsd port " - "number from server, using default\n"); - port = NFS_PORT; - } - nfs_port = htons(port); - printf("nfsroot: Portmapper on server returned %d " - "as nfsd port\n", port); - } - - if ((port = getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) { - printf("nfsroot: Unable to get mountd port " - "number from server, using default\n"); - port = NFS_MNT_PORT; - } - mount_port = htons(port); - printf("nfsroot: mountd port is %d\n", port); - - return 0; -} - -int main(void) -{ - unsigned char *p; - struct timeval tv; - char *s; - - /* FIX: use getopt() instead of this */ - - s = getenv("root_server_addr"); - if (s) - root_server_addr = strtoul(s, NULL, 10); - s = getenv("root_server_path"); - if (s) - strncpy(root_server_path, s, 255); - s = getenv("nfs_root_name"); - if (s) - strncpy(nfs_root_name, s, 255); - - /* - * Decode the root directory path name and NFS options from - * the kernel command line. This has to go here in order to - * be able to use the client IP address for the remote root - * directory (necessary for pure RARP booting). - */ - if (root_nfs_name(nfs_root_name) < 0) - return 0; - if ((servaddr = root_server_addr) == INADDR_NONE) { - printf("nfsroot: No NFS server available, giving up.\n"); - return 0; - } - - p = (char *) &servaddr; - sprintf(nfs_data.hostname, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); - -#ifdef NFSROOT_DEBUG - printf("nfsroot: Mounting %s on server %s as root\n", - nfs_path, nfs_data.hostname); - printf("nfsroot: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n", - nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans); - printf("nfsroot: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n", - nfs_data.acregmin, nfs_data.acregmax, - nfs_data.acdirmin, nfs_data.acdirmax); - printf("nfsroot: nfsd port = %d, mountd port = %d, flags = %08x\n", - nfs_port, mount_port, nfs_data.flags); -#endif - - gettimeofday(&tv, NULL); - XID = (tv.tv_sec << 15) ^ tv.tv_usec; - - if (root_nfs_ports() < 0) - return 0; - if (nfs_data.flags & NFS_MOUNT_VER3) { - if (getfh3()) - return 0; - } else { - if (getfh2()) - return 0; - } - set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, nfs_port); - return mount("/dev/root", "/mnt", "nfs", 0, &nfs_data) == 0; -} diff --git a/klibc/klibc/tests/opentest.c b/klibc/klibc/tests/opentest.c deleted file mode 100644 index 5a54d2fce2..0000000000 --- a/klibc/klibc/tests/opentest.c +++ /dev/null @@ -1,17 +0,0 @@ -#include - -int main(void) -{ - char buffer[1024]; - FILE *f; - - f = fopen("/etc/passwd", "r"); - fgets(buffer, 1024, f); - fclose(f); - - printf("Line 1 = %s", buffer); - - return 0; -} - - diff --git a/klibc/klibc/tests/rtsig.c b/klibc/klibc/tests/rtsig.c deleted file mode 100644 index a7f8eed088..0000000000 --- a/klibc/klibc/tests/rtsig.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include - -int main(void) -{ -#ifdef SIGRTMIN - printf("sigrtmin = %d, sigrtmax = %d\n", SIGRTMIN, SIGRTMAX); -#else - printf("No realtime signals\n"); -#endif - return 0; -} diff --git a/klibc/klibc/tests/setenvtest.c b/klibc/klibc/tests/setenvtest.c deleted file mode 100644 index 111bef9dfe..0000000000 --- a/klibc/klibc/tests/setenvtest.c +++ /dev/null @@ -1,38 +0,0 @@ -#include -#include -#include - -int main(int argc, char *argv[]) -{ - (void)argc; (void)argv; - - /* Set SETENV */ - setenv("SETENV", "setenv", 1); - - /* Set PUTENV */ - putenv("PUTENV=putenv"); - - /* Print the results... */ - printf("SETENV = %s\n", getenv("SETENV")); - printf("PUTENV = %s\n", getenv("PUTENV")); - - /* Override tests */ - setenv("SETENV", "setenv_good", 1); - putenv("PUTENV=putenv_good"); - printf("SETENV = %s\n", getenv("SETENV")); - printf("PUTENV = %s\n", getenv("PUTENV")); - - /* Non-override test */ - setenv("SETENV", "setenv_bad", 0); - setenv("NEWENV", "newenv_good", 0); - printf("SETENV = %s\n", getenv("SETENV")); - printf("NEWENV = %s\n", getenv("NEWENV")); - - /* Undef test */ - unsetenv("SETENV"); - unsetenv("NEWENV"); - printf("SETENV = %s\n", getenv("SETENV")); - printf("NEWENV = %s\n", getenv("NEWENV")); - - return 0; -} diff --git a/klibc/klibc/tests/setjmptest.c b/klibc/klibc/tests/setjmptest.c deleted file mode 100644 index a199eedab8..0000000000 --- a/klibc/klibc/tests/setjmptest.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * setjmptest.c - */ - -#include -#include - -static jmp_buf buf; - -void do_stuff(int v) -{ - printf("setjmp returned %d\n", v); - longjmp(buf, v+1); -} - -void recurse(int ctr, int v) -{ - if ( ctr-- ) { - recurse(ctr, v); - } else { - do_stuff(v); - } - _fwrite(".", 1, stdout); -} - -int main(void) -{ - int v; - - v = setjmp(buf); - - if ( v < 256 ) - recurse(v,v); - - return 0; -} diff --git a/klibc/klibc/tests/stat.c b/klibc/klibc/tests/stat.c deleted file mode 100644 index 74b0bddf44..0000000000 --- a/klibc/klibc/tests/stat.c +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static void do_stat(const char *path) -{ - struct stat st; - - if ( stat(path, &st) ) { - perror(path); - exit(1); - } - - printf("Path = %s\n" - " st_dev = %#jx (%u,%u)\n" - " st_ino = %ju\n" - " st_mode = %#jo\n" - " st_nlink = %ju\n" - " st_uid = %ju\n" - " st_gid = %ju\n" - " st_rdev = %#jx (%u,%u)\n" - " st_size = %ju\n" - " st_blksize = %ju\n" - " st_blocks = %ju\n", - path, - (uintmax_t)st.st_dev, major(st.st_dev), minor(st.st_dev), - (uintmax_t)st.st_ino, - (uintmax_t)st.st_mode, - (uintmax_t)st.st_nlink, - (uintmax_t)st.st_uid, - (uintmax_t)st.st_gid, - (uintmax_t)st.st_rdev, major(st.st_rdev), minor(st.st_rdev), - (uintmax_t)st.st_size, - (uintmax_t)st.st_blksize, - (uintmax_t)st.st_blocks); - -#ifdef _STATBUF_ST_NSEC - printf(" st_atim = %jd.%09u\n" - " st.mtim = %jd.%09u\n" - " st.ctim = %jd.%09u\n", - (uintmax_t)st.st_atim.tv_sec, (unsigned int)st.st_atim.tv_nsec, - (uintmax_t)st.st_mtim.tv_sec, (unsigned int)st.st_mtim.tv_nsec, - (uintmax_t)st.st_ctim.tv_sec, (unsigned int)st.st_ctim.tv_nsec); -#else - printf(" st_atime = %jd\n" - " st.mtime = %jd\n" - " st.ctime = %jd\n", - (uintmax_t)st.st_atime, - (uintmax_t)st.st_mtime, - (uintmax_t)st.st_ctime); -#endif -} - -int main(int argc, char *argv[]) -{ - int i; - - for ( i = 1 ; i < argc ; i++ ) - do_stat(argv[i]); - - return 0; -} diff --git a/klibc/klibc/tests/statfs.c b/klibc/klibc/tests/statfs.c deleted file mode 100644 index 9b7a26d916..0000000000 --- a/klibc/klibc/tests/statfs.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include -#include - -static void do_statfs(const char *path) -{ - struct statfs sfs; - - if ( statfs(path, &sfs) ) { - perror(path); - exit(1); - } - - printf("Path = %s\n" - " f_type = %#jx\n" - " f_bsize = %jd\n" - " f_blocks = %jd\n" - " f_bfree = %jd\n" - " f_bavail = %jd\n" - " f_files = %jd\n" - " f_ffree = %jd\n" - " f_namelen = %jd\n", - path, - (uintmax_t)sfs.f_type, - (intmax_t)sfs.f_bsize, - (intmax_t)sfs.f_blocks, - (intmax_t)sfs.f_bfree, - (intmax_t)sfs.f_bavail, - (intmax_t)sfs.f_files, - (intmax_t)sfs.f_ffree, - (intmax_t)sfs.f_namelen); -} - -int main(int argc, char *argv[]) -{ - int i; - - for ( i = 1 ; i < argc ; i++ ) - do_statfs(argv[i]); - - return 0; -} diff --git a/klibc/klibc/tests/strtoimax.c b/klibc/klibc/tests/strtoimax.c deleted file mode 100644 index 5af0d7912b..0000000000 --- a/klibc/klibc/tests/strtoimax.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * strtoimaxtest.c - */ - -#include -#include -#include - -int main(int argc, char *argv[]) -{ - int i; - char *ep; - intmax_t iv; - - for ( i = 1 ; i < argc ; i++ ) { - iv = strtoimax(argv[i], &ep, 0); - printf("strtoimax(\"%s\") = %jd\n", argv[i], iv); - if ( *ep ) - printf(" ep = \"%s\"\n", ep); - } - - return 0; -} - diff --git a/klibc/klibc/tests/strtotime.c b/klibc/klibc/tests/strtotime.c deleted file mode 100644 index 815d40da99..0000000000 --- a/klibc/klibc/tests/strtotime.c +++ /dev/null @@ -1,27 +0,0 @@ -#include -#include - -int main(int argc, char *argv[]) -{ - struct timeval tv; - struct timespec ts; - int i; - const char *rv, *rs; - - for ( i = 1 ; i < argc ; i++ ) { - rs = strtotimespec(argv[i], &ts); - rv = strtotimeval(argv[i], &tv); - printf("String: \"%s\"\n" - "Timespec: %ld.%09ld\n" - "Residual: \"%s\"\n" - "Timeval: %ld.%06ld\n" - "Residual: \"%s\"\n", - argv[i], - (long)ts.tv_sec, (long)ts.tv_nsec, rs, - (long)tv.tv_sec, (long)tv.tv_usec, rv); - } - - return 0; -} - - diff --git a/klibc/klibc/tests/testrand48.c b/klibc/klibc/tests/testrand48.c deleted file mode 100644 index bf046b6bda..0000000000 --- a/klibc/klibc/tests/testrand48.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include - -int main(void) -{ - unsigned short seed1[] = { 0x1234, 0x5678, 0x9abc }; - unsigned short *oldseed; - - oldseed = seed48(seed1); - printf("Initial seed: %#06x %#06x %#06x\n", - oldseed[0], oldseed[1], oldseed[2]); - - printf("lrand48() = %ld\n", lrand48()); - - seed48(seed1); - printf("mrand48() = %ld\n", mrand48()); - - return 1; -} diff --git a/klibc/klibc/tests/testvsnp.c b/klibc/klibc/tests/testvsnp.c deleted file mode 100644 index c86e8b30fb..0000000000 --- a/klibc/klibc/tests/testvsnp.c +++ /dev/null @@ -1,115 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int main(void) -{ - int r, i; - char buffer[512]; - - r = snprintf(buffer, 512, "Hello, %d", 37); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'d", 37373737); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'x", 0xdeadbeef); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'#X", 0xdeadbeef); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'#llo", 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - /* Make sure overflow works correctly */ - memset(buffer, '\xff', 512); - r = snprintf(buffer, 16, "Hello, %'#llo", 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - for ( i = 16 ; i < 512 ; i++ ) - assert ( buffer[i] == '\xff' ); - - r = snprintf(buffer, 512, "Hello, %'#40.20llo", 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'#-40.20llo", 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'#*.*llo", 40, 20, 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'#*.*llo", -40, 20, 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'#*.*llo", -40, -20, 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %'#*.*llx", -40, -20, 0123456701234567ULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %p", &buffer); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %P", &buffer); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %20p", &buffer); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %-20p", &buffer); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 512, "Hello, %-20p", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 20, "Hello, %'-20p", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 15, "Hello, %'-20p", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 3, "Hello, %'-20p", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - /* This shouldn't change buffer in any way! */ - r = snprintf(buffer, 0, "Hello, %'-20p", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - for ( i = -30 ; i <= 30 ; i++ ) { - r = snprintf(buffer, 40, "Hello, %'*p", i, NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - } - - r = snprintf(buffer, 40, "Hello, %'-20s", "String"); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'20s", "String"); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'020s", "String"); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'-20s", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'20s", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'020s", NULL); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'-20c", '*'); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'20c", '*'); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - r = snprintf(buffer, 40, "Hello, %'020c", '*'); - printf("buffer = \"%s\" (%d), r = %d\n", buffer, strlen(buffer), r); - - return 0; -} - diff --git a/klibc/version b/klibc/version index 21e8796a09..ee90284c27 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -1.0.3 +1.0.4 From 61b1b7069f7a640e1952dce3c6de97034ef7c4fe Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 00:12:55 +0100 Subject: [PATCH 1260/4284] [PATCH] udevinfo: print errors to stderr instead of stdout On Wed, 2005-03-23 at 13:55 +0100, Dieter Stueken wrote: > I noticed a few funny synlinks within /dev: > lrwxrwxrwx 1 root root 4 2005-03-21 15:33:54.196950896 +0100 device2 -> hda2 > lrwxrwxrwx 1 root root 4 2005-03-21 15:33:54.196950896 +0100 not2 -> hda2 > lrwxrwxrwx 1 root root 4 2005-03-21 15:33:54.196950896 +0100 found2 -> hda2 > lrwxrwxrwx 1 root root 4 2005-03-21 15:33:54.196950896 +0100 in2 -> hda2 > lrwxrwxrwx 1 root root 4 2005-03-21 15:33:54.196950896 +0100 database2 -> hda2 > I don't know exactly, what caused this in depth. But I found udevinfo > prints all error messages to stdout instead of using stderr. --- udevinfo.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index 3fb37b41e9..d1dd663d81 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -75,7 +75,7 @@ static void print_all_attributes(struct dlist *attr_list) len--; } if (len == 0) - printf(" SYSFS{%s}=\"%s\"\n", attr->name, value); + printf(" SYSFS{%s}==\"%s\"\n", attr->name, value); } } printf("\n"); @@ -114,7 +114,7 @@ static int print_device_chain(const char *path) /* get the class dev */ class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { - printf("couldn't get the class device\n"); + fprintf(stderr, "couldn't get the class device\n"); return -1; } @@ -132,11 +132,11 @@ static int print_device_chain(const char *path) /* open sysfs class device directory and print all attributes */ printf(" looking at class device '%s':\n", class_dev->path); - printf(" SUBSYSTEM=\"%s\"\n", class_dev->classname); + printf(" SUBSYSTEM==\"%s\"\n", class_dev->classname); attr_list = sysfs_get_classdev_attributes(class_dev); if (attr_list == NULL) { - printf("couldn't open class device directory\n"); + fprintf(stderr, "couldn't open class device directory\n"); retval = -1; goto exit; } @@ -156,15 +156,15 @@ static int print_device_chain(const char *path) while (sysfs_dev != NULL) { attr_list = sysfs_get_device_attributes(sysfs_dev); if (attr_list == NULL) { - printf("couldn't open device directory\n"); + fprintf(stderr, "couldn't open device directory\n"); retval = -1; goto exit; } printf(" looking at the device chain at '%s':\n", sysfs_dev->path); - printf(" BUS=\"%s\"\n", sysfs_dev->bus); - printf(" ID=\"%s\"\n", sysfs_dev->bus_id); - printf(" DRIVER=\"%s\"\n", sysfs_dev->driver_name); + printf(" BUS==\"%s\"\n", sysfs_dev->bus); + printf(" ID==\"%s\"\n", sysfs_dev->bus_id); + printf(" DRIVER==\"%s\"\n", sysfs_dev->driver_name); /* open sysfs device directory and print all attributes */ print_all_attributes(attr_list); @@ -247,7 +247,7 @@ int main(int argc, char *argv[], char *envp[]) break; } - printf("unknown query type\n"); + fprintf(stderr, "unknown query type\n"); retval = 1; goto exit; @@ -293,7 +293,7 @@ int main(int argc, char *argv[], char *envp[]) } retval = udev_db_get_device(&udev, pos); if (retval != 0) { - printf("device not found in database\n"); + fprintf(stderr, "device not found in database\n"); goto exit; } goto print; @@ -312,14 +312,14 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_db_search_name(devpath, sizeof(devpath), pos); if (retval != 0) { - printf("device not found in database\n"); + fprintf(stderr, "device not found in database\n"); goto exit; } udev_db_get_device(&udev, devpath); goto print; } - printf("query needs device path(-p) or node name(-n) specified\n"); + fprintf(stderr, "query needs device path(-p) or node name(-n) specified\n"); retval = 3; goto exit; @@ -355,7 +355,7 @@ print: if (attributes) { if (path[0] == '\0') { - printf("attribute walk on device chain needs path(-p) specified\n"); + fprintf(stderr, "attribute walk on device chain needs path(-p) specified\n"); retval = 4; goto exit; } else { @@ -376,7 +376,7 @@ print: } help: - printf("Usage: udevinfo [-anpqrVh]\n" + fprintf(stderr, "Usage: udevinfo [-anpqrVh]\n" " -q TYPE query database for the specified value:\n" " 'name' name of device node\n" " 'symlink' pointing to node\n" From 18614ab25d4208749a3d85ced33acc6679c60fce Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 00:15:07 +0100 Subject: [PATCH 1261/4284] [PATCH] remove untrusted chars read from sysfs-values or returned by PROGRAM Better remove characters that are useless in a device node name. It may be a security risk to pass any character read from e.g. a sysfs attribute to a shell script we execute later. Prevent the modification of the libsysfs attribute value cache. Clear PROGRAM result if the execution encountered an error. --- test/udev-test.pl | 9 +++ udev_config.c | 8 +-- udev_rules.c | 145 ++++++++++++++++++++-------------------------- udev_utils.c | 18 +++++- udev_utils.h | 3 +- 5 files changed, 92 insertions(+), 91 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 50ea5858a4..5d7c5e5b81 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1213,6 +1213,15 @@ BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", NAME="wrong" BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sdax1", NAME="no" BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sda1", NAME="true" BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", NAME="bad" +EOF + }, + { + desc => "untrusted string sanitize", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "sane", + rules => <value, len); + remove_trailing_char(value, '\n'); + + dbg("found attribute '%s'", tmpattr->path); + return 0; +} + static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { @@ -176,7 +202,6 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, int len; int i; char c; - struct sysfs_attribute *tmpattr; unsigned int next_free_number; struct sysfs_class_device *class_dev_parent; @@ -257,30 +282,21 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } break; case 's': - if (!class_dev) - break; if (attr == NULL) { dbg("missing attribute"); break; } - tmpattr = find_sysfs_attribute(class_dev, sysfs_device, attr); - if (tmpattr == NULL) { + if (find_sysfs_attribute(class_dev, sysfs_device, attr, temp2, sizeof(temp2)) != 0) { dbg("sysfs attribute '%s' not found", attr); break; } - /* strip trailing whitespace of matching value */ - if (isspace(tmpattr->value[strlen(tmpattr->value)-1])) { - i = len = strlen(tmpattr->value); - while (i > 0 && isspace(tmpattr->value[i-1])) - i--; - if (i < len) { - tmpattr->value[i] = '\0'; - dbg("remove %i trailing whitespace chars from '%s'", - len - i, tmpattr->value); - } - } - strlcat(string, tmpattr->value, maxsize); - dbg("substitute sysfs value '%s'", tmpattr->value); + /* strip trailing whitespace of sysfs value */ + i = strlen(temp2); + while (i > 0 && isspace(temp2[i-1])) + temp2[--i] = '\0'; + replace_untrusted_chars(temp2); + strlcat(string, temp2, maxsize); + dbg("substitute sysfs value '%s'", temp2); break; case '%': strlcat(string, "%", maxsize); @@ -385,8 +401,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value, pid = fork(); switch(pid) { case 0: - /* child */ - /* dup2 write side of pipe to STDOUT */ + /* child dup2 write side of pipe to STDOUT */ dup2(fds[1], STDOUT_FILENO); retval = execv(arg, argv); @@ -402,7 +417,12 @@ static int execute_program(struct udevice *udev, const char *path, char *value, i = 0; while (1) { count = read(fds[0], value + i, len - i-1); - if (count <= 0) + if (count < 0) { + err("read failed with '%s'", strerror(errno)); + retval = -1; + } + + if (count == 0) break; i += count; @@ -412,16 +432,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value, break; } } - - if (count < 0) { - err("read failed with '%s'", strerror(errno)); - retval = -1; - } - - if (i > 0 && value[i-1] == '\n') - i--; value[i] = '\0'; - dbg("result is '%s'", value); close(fds[0]); waitpid(pid, &status, 0); @@ -431,70 +442,38 @@ static int execute_program(struct udevice *udev, const char *path, char *value, retval = -1; } } + + if (!retval) { + remove_trailing_char(value, '\n'); + dbg("result is '%s'", value); + replace_untrusted_chars(value); + } else + value[0] = '\0'; + return retval; } -static struct sysfs_attribute *find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, char *attr) -{ - struct sysfs_attribute *tmpattr = NULL; - char *c; - - dbg("look for device attribute '%s'", attr); - /* try to find the attribute in the class device directory */ - tmpattr = sysfs_get_classdev_attr(class_dev, attr); - if (tmpattr) - goto attr_found; - - /* look in the class device directory if present */ - if (sysfs_device) { - tmpattr = sysfs_get_device_attr(sysfs_device, attr); - if (tmpattr) - goto attr_found; - } - - return NULL; - -attr_found: - c = strchr(tmpattr->value, '\n'); - if (c != NULL) - c[0] = '\0'; - - dbg("found attribute '%s'", tmpattr->path); - return tmpattr; -} - static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct key_pair *pair) { - struct sysfs_attribute *tmpattr; + char value[VALUE_SIZE]; int i; - int len; - if ((pair == NULL) || (pair->name[0] == '\0') || (pair->value == '\0')) - return -ENODEV; - - tmpattr = find_sysfs_attribute(class_dev, sysfs_device, pair->name); - if (tmpattr == NULL) - return -ENODEV; + if (find_sysfs_attribute(class_dev, sysfs_device, pair->name, value, sizeof(value)) != 0) + return -1; /* strip trailing whitespace of value, if not asked to match for it */ - if (! isspace(pair->value[strlen(pair->value)-1])) { - i = len = strlen(tmpattr->value); - while (i > 0 && isspace(tmpattr->value[i-1])) - i--; - if (i < len) { - tmpattr->value[i] = '\0'; - dbg("remove %i trailing whitespace chars from '%s'", - len - i, tmpattr->value); - } + if (!isspace(pair->value[strlen(pair->value)-1])) { + i = strlen(value); + while (i > 0 && isspace(value[i-1])) + value[--i] = '\0'; + dbg("removed %i trailing whitespace chars from '%s'", strlen(value)-i, value); } - dbg("compare attribute '%s' value '%s' with '%s'", - pair->name, tmpattr->value, pair->value); - if (strcmp_pattern(pair->value, tmpattr->value) != 0) - return -ENODEV; + dbg("compare attribute '%s' value '%s' with '%s'", pair->name, value, pair->value); + if (strcmp_pattern(pair->value, value) != 0) + return -1; - dbg("found matching attribute '%s' with value '%s'", - pair->name, pair->value); + dbg("found matching attribute '%s' with value '%s'", pair->name, pair->value); return 0; } diff --git a/udev_utils.c b/udev_utils.c index 2b5683fda6..37607492ac 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -50,7 +50,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs if (devpath) { strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); - no_trailing_slash(udev->devpath); + remove_trailing_char(udev->devpath, '/'); if (strncmp(udev->devpath, "/block/", 7) == 0) udev->type = DEV_BLOCK; @@ -228,12 +228,24 @@ size_t buf_get_line(const char *buf, size_t buflen, size_t cur) return count - cur; } -void no_trailing_slash(char *path) +void replace_untrusted_chars(char *string) +{ + size_t len; + + for (len = 0; string[len] != '\0'; len++) { + if (strchr(";,~\\()\'", string[len])) { + info("replace '%c' in '%s'", string[len], string); + string[len] = '_'; + } + } +} + +void remove_trailing_char(char *path, char c) { size_t len; len = strlen(path); - while (len > 0 && path[len-1] == '/') + while (len > 0 && path[len-1] == c) path[--len] = '\0'; } diff --git a/udev_utils.h b/udev_utils.h index b45500dcff..5ebc9e5bb6 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -39,7 +39,8 @@ extern int unlink_secure(const char *filename); extern int file_map(const char *filename, char **buf, size_t *bufsize); extern void file_unmap(char *buf, size_t bufsize); extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); -extern void no_trailing_slash(char *path); +extern void remove_trailing_char(char *path, char c); +extern void replace_untrusted_chars(char *string); extern int name_list_add(struct list_head *name_list, const char *name, int sort); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); From 6276fdd2ab9c0cbfd0fba3e0261a074e81932156 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 00:29:10 +0100 Subject: [PATCH 1262/4284] [PATCH] udevinfo: print SYSFS attribute the same way we match it --- udevinfo.c | 53 ++++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index d1dd663d81..788dd519a8 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -53,30 +53,29 @@ static void print_all_attributes(struct dlist *attr_list) { struct sysfs_attribute *attr; char value[VALUE_SIZE]; - int len; + size_t len; dlist_for_each_data(attr_list, attr, struct sysfs_attribute) { - if (attr->value != NULL) { - strlcpy(value, attr->value, sizeof(value)); - len = strlen(value); - if (len == 0) - continue; - - /* remove trailing newline */ - if (value[len-1] == '\n') { - value[len-1] = '\0'; - len--; - } - - /* skip nonprintable values */ - while (len) { - if (isprint(value[len-1]) == 0) - break; - len--; - } - if (len == 0) - printf(" SYSFS{%s}==\"%s\"\n", attr->name, value); + if (attr->value == NULL) + continue; + len = strlcpy(value, attr->value, sizeof(value)); + if (len >= sizeof(value)) { + dbg("attribute value of '%s' too long, skip", attr->name); + continue; } + + /* 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", attr->name); + continue; + } + replace_untrusted_chars(value); + printf(" SYSFS{%s}==\"%s\"\n", attr->name, value); } printf("\n"); } @@ -107,7 +106,6 @@ static int print_device_chain(const char *path) struct sysfs_class_device *class_dev_parent; struct sysfs_attribute *attr; struct sysfs_device *sysfs_dev; - struct sysfs_device *sysfs_dev_parent; struct dlist *attr_list; int retval = 0; @@ -144,13 +142,13 @@ static int print_device_chain(const char *path) /* get the device link (if parent exists look here) */ class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) + if (class_dev_parent != NULL) sysfs_dev = sysfs_get_classdev_device(class_dev_parent); else sysfs_dev = sysfs_get_classdev_device(class_dev); if (sysfs_dev != NULL) - printf("follow the class device's \"device\"\n"); + printf("follow the \"device\"-link to the physical device:\n"); /* look the device chain upwards */ while (sysfs_dev != NULL) { @@ -166,14 +164,11 @@ static int print_device_chain(const char *path) printf(" ID==\"%s\"\n", sysfs_dev->bus_id); printf(" DRIVER==\"%s\"\n", sysfs_dev->driver_name); - /* open sysfs device directory and print all attributes */ print_all_attributes(attr_list); - sysfs_dev_parent = sysfs_get_device_parent(sysfs_dev); - if (sysfs_dev_parent == NULL) + sysfs_dev = sysfs_get_device_parent(sysfs_dev); + if (sysfs_dev == NULL) break; - - sysfs_dev = sysfs_dev_parent; } exit: From 8a4c0c32f4252efb0f0adbf5cdc0261d359cd568 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 27 Mar 2005 12:39:12 +0200 Subject: [PATCH 1263/4284] [PATCH] fix klibc's broken strlcpy/strlcat udevinfo segfaults cause klibc's strlcpy writes behind the specified size of the destination string. strlcat truncates the destination string which is also not what you expect from a concatenation function. --- klibc/klibc/strlcat.c | 4 +++- klibc/klibc/strlcpy.c | 2 +- udev_config.c | 2 +- udev_db.c | 46 +++++++++++++++++++++---------------------- udev_libc_wrapper.c | 16 +++++++++------ 5 files changed, 38 insertions(+), 32 deletions(-) diff --git a/klibc/klibc/strlcat.c b/klibc/klibc/strlcat.c index 6111445f06..f397857e76 100644 --- a/klibc/klibc/strlcat.c +++ b/klibc/klibc/strlcat.c @@ -16,9 +16,11 @@ size_t strlcat(char *dst, const char *src, size_t size) q++; bytes++; } + if (bytes == size) + return (bytes + strlen(src)); while ( (ch = *p++) ) { - if ( bytes < size ) + if ( bytes+1 < size ) *q++ = ch; bytes++; diff --git a/klibc/klibc/strlcpy.c b/klibc/klibc/strlcpy.c index eb384c9885..8b36c43c00 100644 --- a/klibc/klibc/strlcpy.c +++ b/klibc/klibc/strlcpy.c @@ -13,7 +13,7 @@ size_t strlcpy(char *dst, const char *src, size_t size) char ch; while ( (ch = *p++) ) { - if ( bytes < size ) + if ( bytes+1 < size ) *q++ = ch; bytes++; diff --git a/udev_config.c b/udev_config.c index 7d6bb77e5b..b6f578b27d 100644 --- a/udev_config.c +++ b/udev_config.c @@ -171,7 +171,7 @@ static int parse_config_file(void) if (bufline[0] == COMMENT_CHARACTER) continue; - strlcpy(line, bufline, count); + strlcpy(line, bufline, count+1); linepos = line; retval = get_key(&linepos, &variable, &value); diff --git a/udev_db.c b/udev_db.c index f606b5e05c..afbd50e50f 100644 --- a/udev_db.c +++ b/udev_db.c @@ -116,37 +116,37 @@ static int parse_db_file(struct udevice *udev, const char *filename) switch(bufline[0]) { case 'P': if (count > sizeof(udev->devpath)) - count = sizeof(udev->devpath)-1; - strlcpy(udev->devpath, &bufline[2], count-2); + count = sizeof(udev->devpath); + strlcpy(udev->devpath, &bufline[2], count-1); break; case 'N': if (count > sizeof(udev->name)) - count = sizeof(udev->name)-1; - strlcpy(udev->name, &bufline[2], count-2); + count = sizeof(udev->name); + strlcpy(udev->name, &bufline[2], count-1); break; case 'M': if (count > sizeof(line)) - count = sizeof(line)-1; - strlcpy(line, &bufline[2], count-2); + count = sizeof(line); + strlcpy(line, &bufline[2], count-1); sscanf(line, "%u:%u", &major, &minor); udev->devt = makedev(major, minor); break; case 'S': - if (count > sizeof(line)) - count = sizeof(line)-1; - strlcpy(line, &bufline[2], count-2); + if (count > sizeof(line)) + count = sizeof(line); + strlcpy(line, &bufline[2], count-1); name_list_add(&udev->symlink_list, line, 0); break; case 'A': - if (count > sizeof(line)) - count = sizeof(line)-1; - strlcpy(line, &bufline[2], count-2); + if (count > sizeof(line)) + count = sizeof(line); + strlcpy(line, &bufline[2], count-1); udev->partitions = atoi(line); break; case 'R': - if (count > sizeof(line)) - count = sizeof(line)-1; - strlcpy(line, &bufline[2], count-2); + if (count > sizeof(line)) + count = sizeof(line); + strlcpy(line, &bufline[2], count-1); udev->ignore_remove = atoi(line); break; } @@ -227,14 +227,14 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) switch(bufline[0]) { case 'P': if (count > sizeof(path)) - count = sizeof(path)-1; - strlcpy(path, &bufline[2], count-2); + count = sizeof(path); + strlcpy(path, &bufline[2], count-1); break; case 'N': case 'S': if (count > sizeof(nodename)) - count = sizeof(nodename)-1; - strlcpy(nodename, &bufline[2], count-2); + count = sizeof(nodename); + strlcpy(nodename, &bufline[2], count-1); dbg("compare '%s' '%s'", nodename, name); if (strcmp(nodename, name) == 0) { strlcpy(devpath, path, len); @@ -302,13 +302,13 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam switch(bufline[0]) { case 'P': if (count > sizeof(path)) - count = sizeof(path)-1; - strlcpy(path, &bufline[2], count-2); + count = sizeof(path); + strlcpy(path, &bufline[2], count-1); break; case 'N': if (count > sizeof(nodename)) - count = sizeof(nodename)-1; - strlcpy(nodename, &bufline[2], count-2); + count = sizeof(nodename); + strlcpy(nodename, &bufline[2], count-1); break; default: continue; diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index 16d90913cf..23cb7b4316 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -36,11 +36,15 @@ #define __OWN_USERDB_PARSER__ #endif +#ifdef __GLIBC__ +#define __OWN_STRLCPYCAT__ +#endif + #ifdef USE_STATIC #define __OWN_USERDB_PARSER__ #endif -#ifndef strlcpy +#ifdef __OWN_STRLCPYCAT__ size_t strlcpy(char *dst, const char *src, size_t size) { size_t bytes = 0; @@ -49,7 +53,7 @@ size_t strlcpy(char *dst, const char *src, size_t size) char ch; while ((ch = *p++)) { - if (bytes < size) + if (bytes+1 < size) *q++ = ch; bytes++; } @@ -57,9 +61,7 @@ size_t strlcpy(char *dst, const char *src, size_t size) *q = '\0'; return bytes; } -#endif -#ifndef strlcat size_t strlcat(char *dst, const char *src, size_t size) { size_t bytes = 0; @@ -71,9 +73,11 @@ size_t strlcat(char *dst, const char *src, size_t size) q++; bytes++; } + if (bytes == size) + return (bytes + strlen(src)); while ((ch = *p++)) { - if (bytes < size) + if (bytes+1 < size) *q++ = ch; bytes++; } @@ -81,7 +85,7 @@ size_t strlcat(char *dst, const char *src, size_t size) *q = '\0'; return bytes; } -#endif +#endif /* __OWN_STRLCPYCAT__ */ #ifndef __OWN_USERDB_PARSER__ #include From 4f8d44c220d811352b63c65b5a66403339005aac Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 28 Mar 2005 00:18:49 +0200 Subject: [PATCH 1264/4284] [PATCH] klibc: strlcpy/strlcat - don't alter destination if size == 0 --- klibc/klibc/strlcat.c | 3 ++- klibc/klibc/strlcpy.c | 3 ++- udev_libc_wrapper.c | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/klibc/klibc/strlcat.c b/klibc/klibc/strlcat.c index f397857e76..fdd72ac392 100644 --- a/klibc/klibc/strlcat.c +++ b/klibc/klibc/strlcat.c @@ -26,7 +26,8 @@ size_t strlcat(char *dst, const char *src, size_t size) bytes++; } - *q = '\0'; + if (size) + *q = '\0'; return bytes; } diff --git a/klibc/klibc/strlcpy.c b/klibc/klibc/strlcpy.c index 8b36c43c00..9e7b6bf91f 100644 --- a/klibc/klibc/strlcpy.c +++ b/klibc/klibc/strlcpy.c @@ -19,7 +19,8 @@ size_t strlcpy(char *dst, const char *src, size_t size) bytes++; } - *q = '\0'; + if (size) + *q = '\0'; return bytes; } diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index 23cb7b4316..d69f2ac48e 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -58,7 +58,8 @@ size_t strlcpy(char *dst, const char *src, size_t size) bytes++; } - *q = '\0'; + if (size) + *q = '\0'; return bytes; } @@ -82,7 +83,8 @@ size_t strlcat(char *dst, const char *src, size_t size) bytes++; } - *q = '\0'; + if (size) + *q = '\0'; return bytes; } #endif /* __OWN_STRLCPYCAT__ */ From aa341f21ebad3cf82fa8ff4f644f80d65ff27a40 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 28 Mar 2005 02:12:39 +0200 Subject: [PATCH 1265/4284] [PATCH] udev_rules.c: don't change sysfs_device while walking up the device chain --- udev_rules.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 2581dc2a78..2fca33d063 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -480,6 +480,8 @@ static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { + struct sysfs_device *parent_device = sysfs_device; + if (rule->kernel[0] != '\0') { dbg("check for " KEY_KERNEL " rule->kernel='%s' class_dev->name='%s'", rule->kernel, class_dev->name); @@ -541,13 +543,13 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, while (1) { /* check for matching driver */ if (rule->driver[0] != '\0') { - if (sysfs_device == NULL) { + if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; } dbg("check for " KEY_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'", - rule->driver, sysfs_device->driver_name); - if (strcmp_pattern(rule->driver, sysfs_device->driver_name) != 0) { + rule->driver, parent_device->driver_name); + if (strcmp_pattern(rule->driver, parent_device->driver_name) != 0) { dbg(KEY_DRIVER " is not matching"); if (rule->driver_operation != KEY_OP_NOMATCH) goto try_parent; @@ -561,13 +563,13 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, /* check for matching bus value */ if (rule->bus[0] != '\0') { - if (sysfs_device == NULL) { + if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; } dbg("check for " KEY_BUS " rule->bus='%s' sysfs_device->bus='%s'", - rule->bus, sysfs_device->bus); - if (strcmp_pattern(rule->bus, sysfs_device->bus) != 0) { + rule->bus, parent_device->bus); + if (strcmp_pattern(rule->bus, parent_device->bus) != 0) { dbg(KEY_BUS " is not matching"); if (rule->bus_operation != KEY_OP_NOMATCH) goto try_parent; @@ -581,12 +583,12 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, /* check for matching bus id */ if (rule->id[0] != '\0') { - if (sysfs_device == NULL) { + if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; } dbg("check " KEY_ID); - if (strcmp_pattern(rule->id, sysfs_device->bus_id) != 0) { + if (strcmp_pattern(rule->id, parent_device->bus_id) != 0) { dbg(KEY_ID " is not matching"); if (rule->id_operation != KEY_OP_NOMATCH) goto try_parent; @@ -607,7 +609,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, struct key_pair *pair; pair = &rule->sysfs_pair[i]; - if (compare_sysfs_attribute(class_dev, sysfs_device, pair) != 0) { + if (compare_sysfs_attribute(class_dev, parent_device, pair) != 0) { dbg(KEY_SYSFS "{'%s'} is not matching", pair->name); if (pair->operation != KEY_OP_NOMATCH) goto try_parent; @@ -624,11 +626,11 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, break; try_parent: dbg("try parent sysfs device"); - sysfs_device = sysfs_get_device_parent(sysfs_device); - if (sysfs_device == NULL) + parent_device = sysfs_get_device_parent(parent_device); + if (parent_device == NULL) goto exit; - dbg("look at sysfs_device->path='%s'", sysfs_device->path); - dbg("look at sysfs_device->bus_id='%s'", sysfs_device->bus_id); + dbg("look at sysfs_device->path='%s'", parent_device->path); + dbg("look at sysfs_device->bus_id='%s'", parent_device->bus_id); } /* execute external program */ From 98bbc835f584ed6792e895519326cc637f64f411 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 28 Mar 2005 11:22:17 +0200 Subject: [PATCH 1266/4284] [PATCH] read %s{}-sysfs values at any device in the chain --- test/udev-test.pl | 9 +++++++++ udev_rules.c | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 5d7c5e5b81..ed94629dd1 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1222,6 +1222,15 @@ EOF exp_name => "sane", rules => < "read sysfs value from device down in the chain", + subsys => "block", + devpath => "/class/tty/ttyUSB0", + exp_name => "serial-0000:00:09.0", + rules => <path); + if (find_sysfs_attribute(NULL, parent_device, attr, temp2, sizeof(temp2)) == 0) + break; + parent_device = sysfs_get_device_parent(parent_device); + } + if (!parent_device) + break; } /* strip trailing whitespace of sysfs value */ i = strlen(temp2); From db949b02489f521e32a052280f913e06b7c87e37 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 28 Mar 2005 12:20:05 +0200 Subject: [PATCH 1267/4284] [PATCH] allow to match against empty key values --- test/udev-test.pl | 20 +++++++++++++---- udev_rules.c | 54 +++++++++++++++++++--------------------------- udev_rules.h | 2 +- udev_rules_parse.c | 9 +------- 4 files changed, 40 insertions(+), 45 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index ed94629dd1..27ca37115c 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -806,7 +806,7 @@ EOF exp_name => "link", exp_target => "link", exp_rem_error => "yes", - option => "clear", + option => "clean", rules => < "block", devpath => "/block/sda/sda4", exp_name => "cdrom2", - option => "clear", + option => "clean", rules => < "/block/sda", exp_name => "node14", exp_rem_error => "yes", - option => "clear", + option => "clean", rules => < "serial-0000:00:09.0", rules => < "match against empty key string", + subsys => "block", + devpath => "/block/sda", + exp_name => "ok", + rules => <{option}) && $rules->{option} eq "clear") { + if (defined($rules->{option}) && $rules->{option} eq "clean") { system("rm -rf $udev_db"); system("rm -rf $udev_root"); mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; diff --git a/udev_rules.c b/udev_rules.c index 00199a062f..b7905477de 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -463,36 +463,12 @@ static int execute_program(struct udevice *udev, const char *path, char *value, return retval; } -static int compare_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, struct key_pair *pair) -{ - char value[VALUE_SIZE]; - int i; - - if (find_sysfs_attribute(class_dev, sysfs_device, pair->name, value, sizeof(value)) != 0) - return -1; - - /* strip trailing whitespace of value, if not asked to match for it */ - if (!isspace(pair->value[strlen(pair->value)-1])) { - i = strlen(value); - while (i > 0 && isspace(value[i-1])) - value[--i] = '\0'; - dbg("removed %i trailing whitespace chars from '%s'", strlen(value)-i, value); - } - - dbg("compare attribute '%s' value '%s' with '%s'", pair->name, value, pair->value); - if (strcmp_pattern(pair->value, value) != 0) - return -1; - - dbg("found matching attribute '%s' with value '%s'", pair->name, pair->value); - return 0; -} - static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { struct sysfs_device *parent_device = sysfs_device; - if (rule->kernel[0] != '\0') { + if (rule->kernel_operation != KEY_OP_UNSET) { dbg("check for " KEY_KERNEL " rule->kernel='%s' class_dev->name='%s'", rule->kernel, class_dev->name); if (strcmp_pattern(rule->kernel, class_dev->name) != 0) { @@ -507,7 +483,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg(KEY_KERNEL " key is true"); } - if (rule->subsystem[0] != '\0') { + if (rule->subsystem_operation != KEY_OP_UNSET) { dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'", rule->subsystem, class_dev->name); if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { @@ -552,7 +528,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, /* walk up the chain of physical devices and find a match */ while (1) { /* check for matching driver */ - if (rule->driver[0] != '\0') { + if (rule->driver_operation != KEY_OP_UNSET) { if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; @@ -572,7 +548,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, } /* check for matching bus value */ - if (rule->bus[0] != '\0') { + if (rule->bus_operation != KEY_OP_UNSET) { if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; @@ -592,7 +568,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, } /* check for matching bus id */ - if (rule->id[0] != '\0') { + if (rule->id_operation != KEY_OP_UNSET) { if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; @@ -617,9 +593,23 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("check " KEY_SYSFS " pairs"); for (i = 0; i < rule->sysfs_pair_count; i++) { struct key_pair *pair; + char value[VALUE_SIZE]; pair = &rule->sysfs_pair[i]; - if (compare_sysfs_attribute(class_dev, parent_device, pair) != 0) { + if (find_sysfs_attribute(class_dev, parent_device, pair->name, value, sizeof(value)) != 0) + goto try_parent; + + /* strip trailing whitespace of value, if not asked to match for it */ + if (!isspace(pair->value[strlen(pair->value)-1])) { + size_t len = strlen(value); + + while (len > 0 && isspace(value[len-1])) + value[--len] = '\0'; + dbg("removed %i trailing whitespace chars from '%s'", strlen(value)-len, value); + } + + dbg("compare attribute '%s' value '%s' with '%s'", pair->name, value, pair->value); + if (strcmp_pattern(pair->value, value) != 0) { dbg(KEY_SYSFS "{'%s'} is not matching", pair->name); if (pair->operation != KEY_OP_NOMATCH) goto try_parent; @@ -644,7 +634,7 @@ try_parent: } /* execute external program */ - if (rule->program[0] != '\0') { + if (rule->program_operation != KEY_OP_UNSET) { char program[PATH_SIZE]; dbg("check " KEY_PROGRAM); @@ -663,7 +653,7 @@ try_parent: } /* check for matching result of external program */ - if (rule->result[0] != '\0') { + if (rule->result_operation != KEY_OP_UNSET) { dbg("check for " KEY_RESULT " rule->result='%s', udev->program_result='%s'", rule->result, udev->program_result); if (strcmp_pattern(rule->result, udev->program_result) != 0) { diff --git a/udev_rules.h b/udev_rules.h index 423a6f641e..561ba1687d 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -55,7 +55,7 @@ #define RULEFILE_SUFFIX ".rules" enum key_operation { - KEY_OP_UNKNOWN, + KEY_OP_UNSET, KEY_OP_MATCH, KEY_OP_NOMATCH, KEY_OP_ADD, diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 71ca482728..3c1631ab49 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -236,7 +236,7 @@ static int rules_parse(const char *filename) while (1) { char *key; char *value; - enum key_operation operation = KEY_OP_UNKNOWN; + enum key_operation operation = KEY_OP_UNSET; retval = get_key(&linepos, &key, &operation, &value); if (retval) @@ -408,13 +408,6 @@ static int rules_parse(const char *filename) if (!valid) goto error; - /* simple plausibility checks for given keys */ - if ((rule.sysfs_pair[0].name[0] == '\0') ^ - (rule.sysfs_pair[0].value[0] == '\0')) { - err("inconsistency in " KEY_SYSFS " key"); - goto error; - } - if ((rule.result[0] != '\0') && (program_given == 0)) { info(KEY_RESULT " is only useful when " KEY_PROGRAM " is called in any rule before"); goto error; From bb1a77d34cd004b44b30a79d7521957c3881e497 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 28 Mar 2005 12:37:54 +0200 Subject: [PATCH 1268/4284] [PATCH] check for strlen()==0 before accessing strlen()-1 --- udev_rules.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index b7905477de..c07abb9be0 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -594,15 +594,16 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, for (i = 0; i < rule->sysfs_pair_count; i++) { struct key_pair *pair; char value[VALUE_SIZE]; + size_t len; pair = &rule->sysfs_pair[i]; if (find_sysfs_attribute(class_dev, parent_device, pair->name, value, sizeof(value)) != 0) goto try_parent; /* strip trailing whitespace of value, if not asked to match for it */ - if (!isspace(pair->value[strlen(pair->value)-1])) { - size_t len = strlen(value); - + len = strlen(pair->value); + if (len && !isspace(pair->value[len-1])) { + len = strlen(value); while (len > 0 && isspace(value[len-1])) value[--len] = '\0'; dbg("removed %i trailing whitespace chars from '%s'", strlen(value)-len, value); From 12340f41085c5ab9f5f049eab640835e39de8286 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 29 Mar 2005 03:53:45 +0200 Subject: [PATCH 1269/4284] [PATCH] klibc: version 1.0.5 --- klibc/klibc/strlcat.c | 3 +-- klibc/klibc/strlcpy.c | 4 +++- klibc/version | 2 +- udev_libc_wrapper.c | 5 +++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/klibc/klibc/strlcat.c b/klibc/klibc/strlcat.c index fdd72ac392..f397857e76 100644 --- a/klibc/klibc/strlcat.c +++ b/klibc/klibc/strlcat.c @@ -26,8 +26,7 @@ size_t strlcat(char *dst, const char *src, size_t size) bytes++; } - if (size) - *q = '\0'; + *q = '\0'; return bytes; } diff --git a/klibc/klibc/strlcpy.c b/klibc/klibc/strlcpy.c index 9e7b6bf91f..e6937445cd 100644 --- a/klibc/klibc/strlcpy.c +++ b/klibc/klibc/strlcpy.c @@ -19,8 +19,10 @@ size_t strlcpy(char *dst, const char *src, size_t size) bytes++; } - if (size) + /* If size == 0 there is no space for a final null... */ + if ( size ) *q = '\0'; + return bytes; } diff --git a/klibc/version b/klibc/version index ee90284c27..90a27f9cea 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -1.0.4 +1.0.5 diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index d69f2ac48e..1852141c93 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -58,8 +58,10 @@ size_t strlcpy(char *dst, const char *src, size_t size) bytes++; } + /* If size == 0 there is no space for a final null... */ if (size) *q = '\0'; + return bytes; } @@ -83,8 +85,7 @@ size_t strlcat(char *dst, const char *src, size_t size) bytes++; } - if (size) - *q = '\0'; + *q = '\0'; return bytes; } #endif /* __OWN_STRLCPYCAT__ */ From 584d412bf0584704dc93a7a7595e273c15b3e457 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 29 Mar 2005 03:56:42 +0200 Subject: [PATCH 1270/4284] [PATCH] correct error path for PROGRAM execution --- udev_rules.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index c07abb9be0..9a0ee833e2 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -415,11 +415,13 @@ static int execute_program(struct udevice *udev, const char *path, char *value, dup2(fds[1], STDOUT_FILENO); retval = execv(arg, argv); - info(KEY_PROGRAM " execution of '%s' failed", path); - exit(1); + err(KEY_PROGRAM " execution of '%s' failed", path); + retval = -1; + break; case -1: err("fork of '%s' failed", path); - return -1; + retval = -1; + break; default: /* parent reads from fds[0] */ close(fds[1]); From 7ff56624f84d1616470ab6cbeab17c1367e775d7 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 29 Mar 2005 04:23:56 +0200 Subject: [PATCH 1271/4284] [PATCH] correct correction for error path for PROGRAM execution --- udev_rules.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 9a0ee833e2..2b5c411d96 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -415,9 +415,8 @@ static int execute_program(struct udevice *udev, const char *path, char *value, dup2(fds[1], STDOUT_FILENO); retval = execv(arg, argv); - err(KEY_PROGRAM " execution of '%s' failed", path); - retval = -1; - break; + err("exec of program failed"); + _exit(1); case -1: err("fork of '%s' failed", path); retval = -1; From fb39f0566e248c09772ed15a3218ef2381700b6a Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 29 Mar 2005 11:25:52 +0200 Subject: [PATCH 1272/4284] [PATCH] move execute_program to utils + add action to init_device --- udev.c | 5 ++-- udev_multiplex.c | 34 +------------------------ udev_rules.c | 48 ++++++++++++++++++++---------------- udev_utils.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++- udev_utils.h | 3 ++- udevinfo.c | 2 +- udevstart.c | 2 +- udevtest.c | 11 +++++---- 8 files changed, 104 insertions(+), 65 deletions(-) diff --git a/udev.c b/udev.c index 6d1d679d9a..23375b7a3e 100644 --- a/udev.c +++ b/udev.c @@ -141,7 +141,7 @@ int main(int argc, char *argv[], char *envp[]) if (!subsystem && argc == 2) subsystem = argv[1]; - udev_init_device(&udev, devpath, subsystem); + udev_init_device(&udev, devpath, subsystem, action); if (!action || !subsystem || !devpath) { err("action, subsystem or devpath missing"); @@ -230,10 +230,11 @@ int main(int argc, char *argv[], char *envp[]) } hotplug: - udev_cleanup_device(&udev); if (udev_hotplug_d && managed_event) udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); + udev_cleanup_device(&udev); + logging_close(); return retval; } diff --git a/udev_multiplex.c b/udev_multiplex.c index 9ab11e6bea..22bbaf7b61 100644 --- a/udev_multiplex.c +++ b/udev_multiplex.c @@ -32,38 +32,6 @@ #include "udev_utils.h" #include "logging.h" -static int run_program(struct udevice *udev, const char *filename) -{ - pid_t pid; - int fd; - - dbg("running %s", filename); - - pid = fork(); - switch (pid) { - case 0: - /* child */ - fd = open("/dev/null", O_RDWR); - if ( fd >= 0) { - dup2(fd, STDOUT_FILENO); - dup2(fd, STDIN_FILENO); - dup2(fd, STDERR_FILENO); - } - close(fd); - - execl(filename, filename, udev->subsystem, NULL); - dbg("exec of child failed"); - _exit(1); - case -1: - dbg("fork of child failed"); - break; - return -1; - default: - waitpid(pid, NULL, 0); - } - - return 0; -} /* * runs files in these directories in order: @@ -117,7 +85,7 @@ void udev_multiplex_directory(struct udevice *udev, const char *basedir, const c add_matching_files(&name_list, dirname, suffix); list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { - run_program(udev, name_loop->name); + execute_command(name_loop->name, udev->subsystem); list_del(&name_loop->node); } diff --git a/udev_rules.c b/udev_rules.c index 2b5c411d96..069dec7d04 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -31,7 +31,6 @@ #include #include #include -#include #include "libsysfs/sysfs/libsysfs.h" #include "list.h" @@ -327,7 +326,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct udevice udev_parent; dbg("found parent '%s', get the node name", class_dev_parent->path); - udev_init_device(&udev_parent, NULL, NULL); + udev_init_device(&udev_parent, NULL, NULL, NULL); /* lookup the name in the udev_db with the DEVPATH of the parent */ if (udev_db_get_device(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) { strlcat(string, udev_parent.name, maxsize); @@ -364,21 +363,22 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, } } -static int execute_program(struct udevice *udev, const char *path, char *value, int len) +static int execute_program_pipe(const char *command, const char *subsystem, char *value, int len) { int retval; int count; int status; - int fds[2]; + int pipefds[2]; pid_t pid; char *pos; char arg[PATH_SIZE]; char *argv[(sizeof(arg) / 2) + 1]; + int devnull; int i; - strlcpy(arg, path, sizeof(arg)); + strlcpy(arg, command, sizeof(arg)); i = 0; - if (strchr(path, ' ')) { + if (strchr(arg, ' ')) { pos = arg; while (pos != NULL) { if (pos[0] == '\'') { @@ -397,12 +397,12 @@ static int execute_program(struct udevice *udev, const char *path, char *value, dbg("execute '%s' with parsed arguments", arg); } else { argv[0] = arg; - argv[1] = udev->subsystem; + argv[1] = (char *) subsystem; argv[2] = NULL; dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); } - retval = pipe(fds); + retval = pipe(pipefds); if (retval != 0) { err("pipe failed"); return -1; @@ -412,22 +412,27 @@ static int execute_program(struct udevice *udev, const char *path, char *value, switch(pid) { case 0: /* child dup2 write side of pipe to STDOUT */ - dup2(fds[1], STDOUT_FILENO); + devnull = open("/dev/null", O_RDWR); + if (devnull >= 0) { + dup2(devnull, STDIN_FILENO); + dup2(devnull, STDERR_FILENO); + close(devnull); + } + dup2(pipefds[1], STDOUT_FILENO); retval = execv(arg, argv); - err("exec of program failed"); _exit(1); case -1: - err("fork of '%s' failed", path); + err("fork of '%s' failed", arg); retval = -1; break; default: - /* parent reads from fds[0] */ - close(fds[1]); + /* parent reads from pipefds[0] */ + close(pipefds[1]); retval = 0; i = 0; while (1) { - count = read(fds[0], value + i, len - i-1); + count = read(pipefds[0], value + i, len - i-1); if (count < 0) { err("read failed with '%s'", strerror(errno)); retval = -1; @@ -445,7 +450,7 @@ static int execute_program(struct udevice *udev, const char *path, char *value, } value[i] = '\0'; - close(fds[0]); + close(pipefds[0]); waitpid(pid, &status, 0); if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { @@ -470,9 +475,9 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_device *parent_device = sysfs_device; if (rule->kernel_operation != KEY_OP_UNSET) { - dbg("check for " KEY_KERNEL " rule->kernel='%s' class_dev->name='%s'", - rule->kernel, class_dev->name); - if (strcmp_pattern(rule->kernel, class_dev->name) != 0) { + dbg("check for " KEY_KERNEL " rule->kernel='%s' udev_kernel_name='%s'", + rule->kernel, udev->kernel_name); + if (strcmp_pattern(rule->kernel, udev->kernel_name) != 0) { dbg(KEY_KERNEL " is not matching"); if (rule->kernel_operation != KEY_OP_NOMATCH) goto exit; @@ -485,8 +490,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, } if (rule->subsystem_operation != KEY_OP_UNSET) { - dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' class_dev->name='%s'", - rule->subsystem, class_dev->name); + dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' udev->subsystem='%s'", + rule->subsystem, udev->subsystem); if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { dbg(KEY_SUBSYSTEM " is not matching"); if (rule->subsystem_operation != KEY_OP_NOMATCH) @@ -642,7 +647,8 @@ try_parent: dbg("check " KEY_PROGRAM); strlcpy(program, rule->program, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - if (execute_program(udev, program, udev->program_result, sizeof(udev->program_result)) != 0) { + if (execute_program_pipe(program, udev->subsystem, + udev->program_result, sizeof(udev->program_result)) != 0) { dbg(KEY_PROGRAM " returned nonzero"); if (rule->program_operation != KEY_OP_NOMATCH) goto exit; diff --git a/udev_utils.c b/udev_utils.c index 37607492ac..4695ef0d72 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,7 @@ #include "list.h" -int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem) +int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action) { char *pos; @@ -317,3 +318,64 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c closedir(dir); return 0; } + +int execute_command(const char *command, const char *subsystem) +{ + int retval; + pid_t pid; + char arg[PATH_SIZE]; + char *argv[(PATH_SIZE / 2) + 1]; + char *pos; + int devnull; + int i; + + strlcpy(arg, command, sizeof(arg)); + i = 0; + if (strchr(arg, ' ')) { + pos = arg; + while (pos != NULL) { + if (pos[0] == '\'') { + /* don't separate if in apostrophes */ + pos++; + argv[i] = strsep(&pos, "\'"); + while (pos && pos[0] == ' ') + pos++; + } else { + argv[i] = strsep(&pos, " "); + } + dbg("arg[%i] '%s'", i, argv[i]); + i++; + } + argv[i] = NULL; + dbg("execute '%s' with parsed arguments", arg); + } else { + argv[0] = arg; + argv[1] = (char *) subsystem; + argv[2] = NULL; + dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); + } + + pid = fork(); + switch (pid) { + case 0: + /* child */ + devnull = open("/dev/null", O_RDWR); + if (devnull >= 0) { + dup2(devnull, STDIN_FILENO); + dup2(devnull, STDOUT_FILENO); + dup2(devnull, STDERR_FILENO); + close(devnull); + } + retval = execv(arg, argv); + err("exec of child failed"); + _exit(1); + case -1: + dbg("fork of child failed"); + break; + return -1; + default: + waitpid(pid, NULL, 0); + } + + return 0; +} diff --git a/udev_utils.h b/udev_utils.h index 5ebc9e5bb6..9cdae6db57 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -29,7 +29,7 @@ struct name_entry { char name[PATH_SIZE]; }; -extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem); +extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action); extern void udev_cleanup_device(struct udevice *udev); extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); @@ -43,5 +43,6 @@ extern void remove_trailing_char(char *path, char c); extern void replace_untrusted_chars(char *string); extern int name_list_add(struct list_head *name_list, const char *name, int sort); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); +extern int execute_command(const char *command, const char *subsystem); #endif diff --git a/udevinfo.c b/udevinfo.c index 788dd519a8..31e719fe35 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -199,7 +199,7 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udevinfo"); udev_init_config(); - udev_init_device(&udev, NULL, NULL); + udev_init_device(&udev, NULL, NULL, NULL); /* get command line options */ while (1) { diff --git a/udevstart.c b/udevstart.c index a862dadf88..4bd4795874 100644 --- a/udevstart.c +++ b/udevstart.c @@ -123,7 +123,7 @@ static int add_device(const char *path, const char *subsystem) return -ENODEV; } - udev_init_device(&udev, devpath, subsystem); + udev_init_device(&udev, devpath, subsystem, "add"); udev_add_device(&udev, class_dev); /* run dev.d/ scripts if we created a node or changed a netif name */ diff --git a/udevtest.c b/udevtest.c index f0c38b3a51..2caa654d4c 100644 --- a/udevtest.c +++ b/udevtest.c @@ -86,16 +86,17 @@ int main(int argc, char *argv[], char *envp[]) } else devpath = argv[1]; - info("looking at '%s'", devpath); + subsystem = argv[2]; + setenv("DEVPATH", devpath, 1); + setenv("SUBSYSTEM", subsystem, 1); + setenv("ACTION", "add", 1); + info("looking at device '%s' from subsystem '%s'", devpath, subsystem); /* initialize the naming deamon */ udev_rules_init(); - if (argc == 3) - subsystem = argv[2]; - /* fill in values and test_run flag*/ - udev_init_device(&udev, devpath, subsystem); + udev_init_device(&udev, devpath, subsystem, "add"); /* skip subsystems without "dev", but handle net devices */ if (udev.type != DEV_NET && subsystem_expect_no_dev(udev.subsystem)) { From e03a196a0d0680868ea230ab8f8d100ee90d0fa4 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 29 Mar 2005 11:30:51 +0200 Subject: [PATCH 1273/4284] [PATCH] fix udevtest to print the error if logging is disabled --- udevtest.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/udevtest.c b/udevtest.c index 2caa654d4c..93387f76d0 100644 --- a/udevtest.c +++ b/udevtest.c @@ -64,16 +64,16 @@ int main(int argc, char *argv[], char *envp[]) info("version %s", UDEV_VERSION); - if (argc != 3) { - info("Usage: udevtest "); - return 1; - } - /* initialize our configuration */ udev_init_config(); if (udev_log_priority < LOG_INFO) udev_log_priority = LOG_INFO; + if (argc != 3) { + info("Usage: udevtest "); + return 1; + } + /* remove sysfs_path if given */ if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) devpath = &argv[1][strlen(sysfs_path)] ; From 821d0ec803a72841f173739f5b713fe847edab75 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 2 Apr 2005 17:45:35 +0200 Subject: [PATCH 1274/4284] [PATCH] add RUN key to be able to run rule based notification SUBSYSTEM=="block", RUN="/sbin/program" will execute the program only for block device events. ACTION="remove", SUBSYSTEM=="block", RUN"/sbin/program" will execute the program, if a block device is removed. --- Makefile | 1 - test/udev-test.pl | 47 ++++++++++++++ udev.8.in | 13 +++- udev.c | 19 +++++- udev.h | 4 ++ udev_add.c | 5 +- udev_config.c | 7 +++ udev_rules.c | 148 +++++++++++++++++++++++++++++++++++++++++++-- udev_rules.h | 6 ++ udev_rules_parse.c | 13 ++++ udev_utils.c | 4 ++ udevd.c | 4 +- udevstart.c | 8 +++ 13 files changed, 266 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 9d9caec7f7..bc3425e278 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,6 @@ VERSION = 056 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev -HOTPLUG_EXEC = $(ROOT) DESTDIR = KERNEL_DIR = /lib/modules/${shell uname -r}/build diff --git a/test/udev-test.pl b/test/udev-test.pl index 27ca37115c..91e91bb2ae 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1243,6 +1243,53 @@ KERNEL=="sda", SYSFS{nothing}!="", NAME="not-1-ok" KERNEL=="sda", SYSFS{nothing}=="", NAME="not-2-ok" KERNEL=="sda", SYSFS{vendor}!="", NAME="ok" KERNEL=="sda", SYSFS{vendor}=="", NAME="not-3-ok" +EOF + }, + { + desc => "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 remove", + subsys => "block", + devpath => "/block/sda", + exp_name => "testsymlink2", + exp_target => "ok2", + rules => <name, udev.subsystem); + } + /* run dev.d/ scripts if we created/deleted a node or changed a netif name */ if (udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); diff --git a/udev.h b/udev.h index c2706f4593..f7a65c60d8 100644 --- a/udev.h +++ b/udev.h @@ -58,6 +58,7 @@ enum device_type { struct udevice { char devpath[PATH_SIZE]; char subsystem[NAME_SIZE]; + char action[NAME_SIZE]; enum device_type type; char name[PATH_SIZE]; @@ -67,9 +68,11 @@ struct udevice { char group[USER_SIZE]; mode_t mode; dev_t devt; + struct list_head run_list; char tmp_node[PATH_SIZE]; int partitions; + int ignore_device; int ignore_remove; int config_line; char config_file[PATH_SIZE]; @@ -93,6 +96,7 @@ extern char udev_db_path[PATH_SIZE]; extern char udev_config_filename[PATH_SIZE]; extern char udev_rules_filename[PATH_SIZE]; extern int udev_log_priority; +extern int udev_run; extern int udev_dev_d; extern int udev_hotplug_d; diff --git a/udev_add.c b/udev_add.c index d0d9eab913..5fff3836e3 100644 --- a/udev_add.c +++ b/udev_add.c @@ -276,8 +276,11 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) } } - if (udev_rules_get_name(udev, class_dev) != 0) + udev_rules_get_name(udev, class_dev); + if (udev->ignore_device) { + dbg("device event will be ignored"); return 0; + } dbg("adding name='%s'", udev->name); diff --git a/udev_config.c b/udev_config.c index b6f578b27d..6bc070d63a 100644 --- a/udev_config.c +++ b/udev_config.c @@ -44,6 +44,7 @@ char udev_db_path[PATH_SIZE]; char udev_config_filename[PATH_SIZE]; char udev_rules_filename[PATH_SIZE]; int udev_log_priority; +int udev_run; int udev_dev_d; int udev_hotplug_d; @@ -217,10 +218,16 @@ void udev_init_config(void) strcpy(udev_config_filename, UDEV_CONFIG_FILE); strcpy(udev_rules_filename, UDEV_RULES_FILE); udev_log_priority = LOG_ERR; + udev_run = 1; udev_dev_d = 1; udev_hotplug_d = 1; sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); + /* disable RUN key execution */ + env = getenv("UDEV_RUN"); + if (env && !string_is_true(env)) + udev_run = 0; + env = getenv("UDEV_NO_DEVD"); if (env && string_is_true(env)) udev_dev_d = 0; diff --git a/udev_rules.c b/udev_rules.c index 069dec7d04..6f82fac841 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -474,6 +474,21 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, { struct sysfs_device *parent_device = sysfs_device; + if (rule->action_operation != KEY_OP_UNSET) { + dbg("check for " KEY_ACTION " rule->action='%s' udev->action='%s'", + rule->action, udev->action); + if (strcmp_pattern(rule->action, udev->action) != 0) { + dbg(KEY_ACTION " is not matching"); + if (rule->action_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_ACTION " matches"); + if (rule->action_operation == KEY_OP_NOMATCH) + goto exit; + } + dbg(KEY_ACTION " key is true"); + } + if (rule->kernel_operation != KEY_OP_UNSET) { dbg("check for " KEY_KERNEL " rule->kernel='%s' udev_kernel_name='%s'", rule->kernel, udev->kernel_name); @@ -716,12 +731,17 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d list_for_each_entry(rule, &udev_rule_list, node) { dbg("process rule"); if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { + if (udev->name[0] != '\0' && rule->name[0] != '\0') { + dbg("node name already set, rule ignored"); + continue; + } /* apply options */ if (rule->ignore_device) { info("configured rule in '%s[%i]' applied, '%s' is ignored", rule->config_file, rule->config_line, udev->kernel_name); - return -1; + udev->ignore_device = 1; + return 0; } if (rule->ignore_remove) { udev->ignore_remove = 1; @@ -773,7 +793,7 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d name_list_add(&udev->symlink_list, pos, 0); } - /* rule matches */ + /* set name, later rules with name set will be ignored */ if (rule->name[0] != '\0') { info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", rule->config_file, rule->config_line, udev->kernel_name, rule->name); @@ -786,20 +806,25 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (udev->type != DEV_NET) 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); + } - break; + if (rule->run[0] != '\0') { + char program[PATH_SIZE]; + + strlcpy(program, rule->run, sizeof(program)); + apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); } if (rule->last_rule) { dbg("last rule to be applied"); break; } - } } if (udev->name[0] == '\0') { - /* no rule matched, so we use the kernel name */ strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); info("no rule found, use kernel name '%s'", udev->name); } @@ -812,3 +837,116 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d return 0; } + +int udev_rules_get_run(struct udevice *udev) +{ + struct udev_rule *rule; + char program[PATH_SIZE]; + + /* look for a matching rule to apply */ + list_for_each_entry(rule, &udev_rule_list, node) { + dbg("process rule"); + + if (rule->run[0] == '\0') + continue; + + if (rule->name[0] != '\0' || rule->symlink[0] != '\0' || + rule->mode != 0000 || rule->owner[0] != '\0' || rule->group[0] != '\0') { + dbg("skip rule that names a device"); + continue; + } + + if (rule->action_operation != KEY_OP_UNSET) { + dbg("check for " KEY_ACTION " rule->action='%s' udev->action='%s'", + rule->action, udev->action); + if (strcmp_pattern(rule->action, udev->action) != 0) { + dbg(KEY_ACTION " is not matching"); + if (rule->action_operation != KEY_OP_NOMATCH) + continue; + } else { + dbg(KEY_ACTION " matches"); + if (rule->action_operation == KEY_OP_NOMATCH) + continue; + } + dbg(KEY_ACTION " key is true"); + } + + if (rule->kernel_operation != KEY_OP_UNSET) { + dbg("check for " KEY_KERNEL " rule->kernel='%s' udev->kernel_name='%s'", + rule->kernel, udev->kernel_name); + if (strcmp_pattern(rule->kernel, udev->kernel_name) != 0) { + dbg(KEY_KERNEL " is not matching"); + if (rule->kernel_operation != KEY_OP_NOMATCH) + continue; + } else { + dbg(KEY_KERNEL " matches"); + if (rule->kernel_operation == KEY_OP_NOMATCH) + continue; + } + dbg(KEY_KERNEL " key is true"); + } + + if (rule->subsystem_operation != KEY_OP_UNSET) { + dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' udev->subsystem='%s'", + rule->subsystem, udev->subsystem); + if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { + dbg(KEY_SUBSYSTEM " is not matching"); + if (rule->subsystem_operation != KEY_OP_NOMATCH) + continue; + } else { + dbg(KEY_SUBSYSTEM " matches"); + if (rule->subsystem_operation == KEY_OP_NOMATCH) + continue; + } + dbg(KEY_SUBSYSTEM " key is true"); + } + + if (rule->env_pair_count) { + int i; + + dbg("check for " KEY_ENV " pairs"); + for (i = 0; i < rule->env_pair_count; i++) { + struct key_pair *pair; + const char *value; + + pair = &rule->env_pair[i]; + value = getenv(pair->name); + if (!value) { + dbg(KEY_ENV "{'%s'} is not found", pair->name); + continue; + } + if (strcmp_pattern(pair->value, value) != 0) { + dbg(KEY_ENV "{'%s'} is not matching", pair->name); + if (pair->operation != KEY_OP_NOMATCH) + continue; + } else { + dbg(KEY_ENV "{'%s'} matches", pair->name); + if (pair->operation == KEY_OP_NOMATCH) + continue; + } + } + dbg(KEY_ENV " key is true"); + } + + /* rule matches */ + + if (rule->ignore_device) { + info("configured rule in '%s[%i]' applied, '%s' is ignored", + rule->config_file, rule->config_line, udev->kernel_name); + udev->ignore_device = 1; + return 0; + } + + strlcpy(program, rule->run, sizeof(program)); + apply_format(udev, program, sizeof(program), NULL, NULL); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); + + if (rule->last_rule) { + dbg("last rule to be applied"); + break; + } + } + + return 0; +} diff --git a/udev_rules.h b/udev_rules.h index 561ba1687d..5fba2d5571 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -30,6 +30,7 @@ #define KEY_KERNEL "KERNEL" #define KEY_SUBSYSTEM "SUBSYSTEM" +#define KEY_ACTION "ACTION" #define KEY_BUS "BUS" #define KEY_ID "ID" #define KEY_PROGRAM "PROGRAM" @@ -42,6 +43,7 @@ #define KEY_OWNER "OWNER" #define KEY_GROUP "GROUP" #define KEY_MODE "MODE" +#define KEY_RUN "RUN" #define KEY_OPTIONS "OPTIONS" #define OPTION_LAST_RULE "last_rule" @@ -75,6 +77,8 @@ struct udev_rule { enum key_operation kernel_operation; char subsystem[NAME_SIZE]; enum key_operation subsystem_operation; + char action[NAME_SIZE]; + enum key_operation action_operation; char bus[NAME_SIZE]; enum key_operation bus_operation; char id[NAME_SIZE]; @@ -95,6 +99,7 @@ struct udev_rule { char owner[USER_SIZE]; char group[USER_SIZE]; mode_t mode; + char run[PATH_SIZE]; int last_rule; int ignore_device; @@ -109,6 +114,7 @@ extern struct list_head udev_rule_list; extern int udev_rules_init(void); extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev); +extern int udev_rules_get_run(struct udevice *udev); extern void udev_rules_close(void); #endif diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 3c1631ab49..e665957b81 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -256,6 +256,13 @@ static int rules_parse(const char *filename) continue; } + if (strcasecmp(key, KEY_ACTION) == 0) { + strlcpy(rule.action, value, sizeof(rule.action)); + rule.action_operation = operation; + valid = 1; + continue; + } + if (strcasecmp(key, KEY_BUS) == 0) { strlcpy(rule.bus, value, sizeof(rule.bus)); rule.bus_operation = operation; @@ -379,6 +386,12 @@ static int rules_parse(const char *filename) continue; } + if (strcasecmp(key, KEY_RUN) == 0) { + strlcpy(rule.run, value, sizeof(rule.run)); + valid = 1; + continue; + } + if (strcasecmp(key, KEY_OPTIONS) == 0) { if (strstr(value, OPTION_LAST_RULE) != NULL) { dbg("last rule to be applied"); diff --git a/udev_utils.c b/udev_utils.c index 4695ef0d72..5cdfb1421d 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -45,10 +45,14 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs memset(udev, 0x00, sizeof(struct udevice)); INIT_LIST_HEAD(&udev->symlink_list); + INIT_LIST_HEAD(&udev->run_list); if (subsystem) strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem)); + if (action) + strlcpy(udev->action, action, sizeof(udev->action)); + if (devpath) { strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); remove_trailing_char(udev->devpath, '/'); diff --git a/udevd.c b/udevd.c index 6c4d8b8693..91033b0688 100644 --- a/udevd.c +++ b/udevd.c @@ -145,7 +145,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) } /* forks event and removes event from run queue when finished */ -static void udev_run(struct hotplug_msg *msg) +static void execute_udev(struct hotplug_msg *msg) { char *const argv[] = { "udev", msg->subsystem, NULL }; pid_t pid; @@ -349,7 +349,7 @@ static void exec_queue_manager(void) if (!msg) { /* move event to run list */ list_move_tail(&loop_msg->node, &running_list); - udev_run(loop_msg); + execute_udev(loop_msg); running++; dbg("moved seq %llu to running list", loop_msg->seqnum); } else { diff --git a/udevstart.c b/udevstart.c index 4bd4795874..d41702efd1 100644 --- a/udevstart.c +++ b/udevstart.c @@ -126,6 +126,14 @@ static int add_device(const char *path, const char *subsystem) udev_init_device(&udev, devpath, subsystem, "add"); udev_add_device(&udev, class_dev); + if (udev_run && !list_empty(&udev.run_list)) { + struct name_entry *name_loop; + + dbg("executing run list"); + list_for_each_entry(name_loop, &udev.run_list, node) + execute_command(name_loop->name, udev.subsystem); + } + /* run dev.d/ scripts if we created a node or changed a netif name */ if (udev_dev_d && udev.devname[0] != '\0') { setenv("DEVNAME", udev.devname, 1); From e4388fb3700146c3bf5cb6ee8b69232101e26f7c Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 2 Apr 2005 18:03:59 +0200 Subject: [PATCH 1275/4284] [PATCH] update RELEASE-NOTES --- RELEASE-NOTES | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 17d6097abf..67b4a6caa1 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,5 +1,23 @@ 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 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 a event (OPTIONS="ignore_device"). +The new ACTION-key may be used to match a rule only at a "remove"-event. + +The new RUN-key supports rule-based execution of programs after device-node +handling. This can replace the dev.d/-rules to make them more efficient. + +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 From 87b60f72b762fddad92c83856ebe05b5aa05fc76 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sat, 2 Apr 2005 18:06:26 +0200 Subject: [PATCH 1276/4284] [PATCH] fix make -j4 and the local klibc-install --- Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index bc3425e278..9c755ba4de 100644 --- a/Makefile +++ b/Makefile @@ -217,7 +217,7 @@ all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(K done ; \ $(KLCC): - $(MAKE) -C klibc KRNLSRC=$(KERNEL_DIR) SUBDIRS=klibc TESTS= \ + $(MAKE) -j1 -C klibc KRNLSRC=$(KERNEL_DIR) SUBDIRS=klibc TESTS= \ SHLIBDIR=$(KLIBC_INSTALL)/lib \ INSTALLDIR=$(KLIBC_INSTALL) \ bindir=$(KLIBC_INSTALL)/bin \ @@ -263,15 +263,15 @@ GEN_MANPAGESIN = udev.8.in $(GEN_MANPAGES): $(GEN_MANPAGESIN) sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ -$(UDEV_OBJS): $(GEN_HEADERS) $(HOST_PROGS) -$(SYSFS_OBJS): $(HOST_PROGS) -$(OBJS): $(GEN_HEADERS) $(HOST_PROGS) -$(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) -$(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) -$(INFO).o: $(GEN_HEADERS) $(HOST_PROGS) -$(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS) -$(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) -$(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) +$(UDEV_OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(SYSFS_OBJS): $(HOST_PROGS) $(KLCC) +$(OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(INFO).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(ROOT).o $(OBJS) $(LIB_OBJS) From 81af4e0519498fdbf75ad1e4250bfa3278262bde Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 3 Apr 2005 00:29:05 +0200 Subject: [PATCH 1277/4284] [PATCH] export DEVNAME to RUN-key executed programs --- udev.8.in | 2 +- udev.c | 11 ++++++----- udevstart.c | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/udev.8.in b/udev.8.in index 4beab0d355..3527d6912f 100644 --- a/udev.8.in +++ b/udev.8.in @@ -314,7 +314,7 @@ The name of a program must have the suffix .I .dev to be recognized. .br -In addition to the hotplug environment variables, +In addition to the kernel provided hotplug environment variables, .B UDEV_LOG is set and contains the numerical priority value, if udev is configured to use .BR syslog (3). diff --git a/udev.c b/udev.c index 5728be59e0..ce9b42f30d 100644 --- a/udev.c +++ b/udev.c @@ -204,6 +204,9 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_remove_device(&udev); } + if (udev.devname[0] != '\0') + setenv("DEVNAME", udev.devname, 1); + if (udev_run && !list_empty(&udev.run_list)) { struct name_entry *name_loop; @@ -213,11 +216,9 @@ int main(int argc, char *argv[], char *envp[]) } /* run dev.d/ scripts if we created/deleted a node or changed a netif name */ - if (udev.devname[0] != '\0') { - setenv("DEVNAME", udev.devname, 1); - if (udev_dev_d) - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); - } + if (udev_dev_d && udev.devname[0] != '\0') + udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); + } else if (udev.type == DEV_DEVICE) { if (strcmp(action, "add") == 0) { /* wait for sysfs */ diff --git a/udevstart.c b/udevstart.c index d41702efd1..60e63c5ad8 100644 --- a/udevstart.c +++ b/udevstart.c @@ -126,6 +126,9 @@ static int add_device(const char *path, const char *subsystem) udev_init_device(&udev, devpath, subsystem, "add"); udev_add_device(&udev, class_dev); + if (udev.devname[0] != '\0') + setenv("DEVNAME", udev.devname, 1); + if (udev_run && !list_empty(&udev.run_list)) { struct name_entry *name_loop; @@ -135,10 +138,8 @@ static int add_device(const char *path, const char *subsystem) } /* run dev.d/ scripts if we created a node or changed a netif name */ - if (udev_dev_d && udev.devname[0] != '\0') { - setenv("DEVNAME", udev.devname, 1); + if (udev_dev_d && udev.devname[0] != '\0') udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); - } sysfs_close_class_device(class_dev); udev_cleanup_device(&udev); From 5165d1dcb71899aca01783e9edc4ad11528acab9 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 3 Apr 2005 01:15:44 +0200 Subject: [PATCH 1278/4284] [PATCH] update the man page to reflect the recent changes --- udev.8.in | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/udev.8.in b/udev.8.in index 3527d6912f..5be9308af4 100644 --- a/udev.8.in +++ b/udev.8.in @@ -15,18 +15,23 @@ As part of the subsystem, .B udev is executed if a kernel device is added or removed from the system. -On device creation, +A list of rules is used to match against specific device attributes. +.br +On device addition, .B udev -reads the sysfs directory of the given device to collect device attributes -like label, serial number or bus device number. -These attributes may be used as keys to determine a -unique name for the device. +matches its configured rules against the available device attributes to +uniquely name the device. .B udev -maintains a database for devices present on the system. +maintains its own database for devices present on the system. This database +can be queried for the relationship of the kernel device path and the +name of the device file. .br On device removal, .B udev queries its database for the name of the device file to be deleted. +.br +After the device node handling, a list of collected programs specific to this +device is executed. .SH "CONFIGURATION" All .B udev @@ -156,18 +161,10 @@ The name of the node to be created, or the name, the network interface should be renamed to. .TP .B SYMLINK -The name of a symlink targeting the node. Multiple symlinks may be -specified by separating the names by the space character. -.br -If both the name and the symlink fields are omitted or its -values are empty, the device will be ignored and no node will be created. -.br -If only the symlink field is given and the name field is omitted, -the rule will not be applied immediately, but the symlink field is added -to the symlink list of the rule which will create the node. -This makes it possible to specify additional symlinks in a possibly -separate rules file, while the device nodes are maintained by the -distribution provided rules file. +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. .TP .B OWNER, GROUP, MODE The permissions for the device node. Every specified value overwrites the @@ -178,10 +175,10 @@ Add a program to the list of programs to be executed for a specific device. .TP .B OPTIONS .B last_rule -will be the last rule applied. No later rules will have any effect. +stops further rules application. No later rules will have any effect. .sp .B ignore_device -will ignore this device. No node will be created. +will ignore this device. No node will be created or program executed. .sp .B ignore_remove will ignore any later remove event for this device. @@ -261,7 +258,7 @@ where device can come and go at any time is not recomended. .B %% The '%' character itself. .P -The count of charcters to insert may be limited by specifying +The count of characters to insert may be limited by specifying the format length value. For example, '%3s{file}' will only insert the first three characters of the sysfs attribute. .P From f040a4a271dd093413303158efb027fe9e891e80 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 4 Apr 2005 15:20:48 +0200 Subject: [PATCH 1279/4284] [PATCH] udev-test.pl: add test for DEVNAME export to RUN environment --- test/udev-test.pl | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/test/udev-test.pl b/test/udev-test.pl index 91e91bb2ae..c1dc8b2f1b 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1278,6 +1278,19 @@ EOF rules => < "test RUN key and DEVNAME", + subsys => "block", + devpath => "/block/sda", + exp_name => "testsymlink", + exp_target => "ok", + exp_rem_error => "yes", + option => "clean", + rules => < Date: Tue, 5 Apr 2005 04:01:08 +0200 Subject: [PATCH 1280/4284] [PATCH] udev_volume_id: fix endianess macros --- extras/volume_id/volume_id/util.h | 4 ++++ extras/volume_id/volume_id/volume_id.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h index 9cea8fc3a0..e18efe2f21 100644 --- a/extras/volume_id/volume_id/util.h +++ b/extras/volume_id/volume_id/util.h @@ -29,6 +29,8 @@ # include #endif +#include + /* size of superblock buffer, reiserfs block is at 64k */ #define SB_BUFFER_SIZE 0x11000 /* size of seek buffer, FAT cluster is 32k max */ @@ -52,6 +54,7 @@ (((__u64)(x) & 0x000000000000ff00ull) << 40) | \ (((__u64)(x) & 0x00000000000000ffull) << 56)) +#ifdef __BYTE_ORDER #if (__BYTE_ORDER == __LITTLE_ENDIAN) #define le16_to_cpu(x) (x) #define le32_to_cpu(x) (x) @@ -69,6 +72,7 @@ #define cpu_to_le32(x) bswap32(x) #define cpu_to_be32(x) (x) #endif +#endif /* __BYTE_ORDER */ enum uuid_format { UUID_DCE_STRING, diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index c7fa0d9bea..2266694f5e 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 43 +#define VOLUME_ID_VERSION 44 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 16eb35d16e4c897f8d0bf7accce5c8ad066e8774 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Wed, 6 Apr 2005 06:47:06 +0200 Subject: [PATCH 1281/4284] [PATCH] adapt RELEASE-NOTES --- RELEASE-NOTES | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 67b4a6caa1..9b7fa31330 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,19 +1,22 @@ 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 ignored. This way system -supplied symlinks or permissions gets applied to user-defined naming rules. +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 a event (OPTIONS="ignore_device"). -The new ACTION-key may be used to match a rule only at a "remove"-event. +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 can replace the dev.d/-rules to make them more efficient. +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. @@ -30,7 +33,7 @@ UDEV_LOG. udev 056 ======== Possible use of a system-wide klibc: - make USE_KLIB=true KLCC=/usr/bin/klcc all + make USE_KLIBC=true KLCC=/usr/bin/klcc all will link against an external klibc and our own version will be ignored. udev 055 From 1bbff4f03584dc0ba830d8cb0fc91d10bd79ac94 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 10 Apr 2005 21:15:12 +0200 Subject: [PATCH 1282/4284] [PATCH] apply default permissions only for devices that will need it --- udev_utils.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/udev_utils.c b/udev_utils.c index 5cdfb1421d..74b55ed406 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -89,9 +89,11 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs } } - udev->mode = 0660; - strcpy(udev->owner, "root"); - strcpy(udev->group, "root"); + if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { + udev->mode = 0660; + strcpy(udev->owner, "root"); + strcpy(udev->group, "root"); + } return 0; } From 7ab16233831bb90b2ee14e7ee98c3dde77276a9e Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Sun, 10 Apr 2005 21:19:51 +0200 Subject: [PATCH 1283/4284] [PATCH] update Debian rules --- etc/udev/debian/devfs.rules | 111 ++++++++---------------------- etc/udev/debian/permissions.rules | 73 ++++++++++++++++++++ etc/udev/debian/udev.rules | 83 +++++----------------- 3 files changed, 118 insertions(+), 149 deletions(-) create mode 100644 etc/udev/debian/permissions.rules diff --git a/etc/udev/debian/devfs.rules b/etc/udev/debian/devfs.rules index cffef1a2e2..0453e66d5f 100644 --- a/etc/udev/debian/devfs.rules +++ b/etc/udev/debian/devfs.rules @@ -13,56 +13,19 @@ # %% the '%' char itself. # -# default permissions for block devices -SUBSYSTEM="block", GROUP="disk" -SUBSYSTEM="block", SYSFS{removable}="1", GROUP="floppy" - # workaround for devices which do not report media changes BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/model", RESULT="IOMEGA ZIP *", \ - NAME{all_partitions}="%k%n", GROUP="floppy" + PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT="IOMEGA ZIP *", \ + OPTIONS="all_partitions", NAME="%k" # IDE devices -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", \ - GROUP="cdrom" -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", \ - GROUP="floppy" BUS="ide", KERNEL="hd[a-z]*", \ - PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="ide", KERNEL="ht[0-9]*", GROUP="tape" -BUS="ide", KERNEL="nht[0-9]*", GROUP="tape" + PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" # SCSI devices -BUS="scsi", KERNEL="sd[a-z]", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="sd[a-z][0-9]*", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="sd[a-i][a-z]", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="sd[a-i][a-z][0-9]*", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="s[gr][0-9]*", SYSFS{type}="5", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="cdrom" -BUS="scsi", KERNEL="sr[0-9]*", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="cdrom" -BUS="scsi", KERNEL="sg[0-9]*", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" -BUS="scsi", KERNEL="st[0-9]*", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="tape" -BUS="scsi", KERNEL="nst[0-9]*", \ - PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}", GROUP="tape" +BUS="scsi", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK="%k %c{2}" # RAID controllers KERNEL="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ @@ -78,15 +41,15 @@ KERNEL="loop[0-9]*", NAME="loop/%n" KERNEL="ram[0-9]*", NAME="rd/%n" # USB devices -BUS="usb", KERNEL="hiddev*", NAME="usb/%k" BUS="usb", KERNEL="auer[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="legousbtower*", NAME="usb/%k", MODE="0666" -BUS="usb", KERNEL="dabusb*", NAME="usb/%k" BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="hiddev*", NAME="usb/%k" +BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" BUS="usb", KERNEL="ttyUSB*", SYSFS{product}="Palm Handheld*", SYMLINK="pilot" # serial devices -SUBSYSTEM="tty", GROUP="dialout" KERNEL="ttyS[0-9]*", NAME="tts/%n" KERNEL="ttyUSB[0-9]*", NAME="tts/USB%n" KERNEL="rfcomm[0-9]*", NAME="bluetooth/rfcomm/%n", @@ -94,8 +57,6 @@ KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" KERNEL="capi[0-9]*", NAME="capi/%n" # vc devices -KERNEL="ptmx", MODE="0666" -KERNEL="tty", MODE="0666" KERNEL="tty[0-9]*", NAME="vc/%n" KERNEL="vcs", NAME="vcc/0" KERNEL="vcs[0-9]*", NAME="vcc/%n" @@ -103,49 +64,32 @@ KERNEL="vcsa", NAME="vcc/a0" KERNEL="vcsa[0-9]*", NAME="vcc/a%n" # video devices -SUBSYSTEM="video4linux", GROUP="video" 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="/etc/udev/scripts/dvb.sh %k", \ - NAME="%c", GROUP="video" -KERNEL="fb[0-9]*", NAME="fb/%n", GROUP="video" -KERNEL="nvidia*", GROUP="video" -KERNEL="card[0-9]*", NAME="dri/%k", GROUP="video" +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" +KERNEL="fb[0-9]*", NAME="fb/%n" +KERNEL="card[0-9]*", NAME="dri/%k" # misc devices -KERNEL="random", MODE="0666" -KERNEL="urandom", MODE="0444" -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="apm_bios", NAME="misc/%k", -KERNEL="agpgart", NAME="misc/%k", GROUP="video" -KERNEL="nvram", NAME="misc/%k", GROUP="nvram" +KERNEL="agpgart", NAME="misc/%k" +KERNEL="nvram", NAME="misc/%k" KERNEL="psaux", NAME="misc/%k" -KERNEL="rtc", NAME="misc/%k", MODE="0644", GROUP="audio" +KERNEL="rtc", NAME="misc/%k" KERNEL="hw_random", NAME="hwrng" # printers and parallel devices -SUBSYSTEM="printer", GROUP="lp" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" KERNEL="lp[0-9]*", NAME="printers/%n" -KERNEL="pt[0-9]*", GROUP="tape" -KERNEL="pht[0-9]*", GROUP="tape" +KERNEL="parport[0-9]*", NAME="parports/%n" KERNEL="i2c-[0-9]*", NAME="i2c/%n" -KERNEL="fd[0-9]*", NAME="floppy/%n", GROUP="floppy" +KERNEL="fd[0-9]*", NAME="floppy/%n" -KERNEL="cdemu[0-9]*", NAME="cdemu/%n", GROUP="cdrom" -KERNEL="pktcdvd[0-9]*", NAME="pktcdvd/%n", GROUP="cdrom" -KERNEL="pktcdvd", NAME="pktcdvd/control", MODE="0644" +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" @@ -158,7 +102,6 @@ KERNEL="tap[0-9]*", NAME="net/%k" KERNEL="tun", NAME="net/%k" # sound devices -SUBSYSTEM="sound", GROUP="audio" KERNEL="controlC[0-9]*", NAME="snd/%k" KERNEL="hwC[D0-9]*", NAME="snd/%k" KERNEL="pcmC[D0-9cp]*", NAME="snd/%k" @@ -178,11 +121,8 @@ KERNEL="admmidi*", NAME="sound/%k" # input devices KERNEL="mice", NAME="input/%k" KERNEL="mouse[0-9]*", NAME="input/%k" -KERNEL="event[0-9]*", NAME="input/%k", \ - PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", \ - MODE="0664", GROUP="video" KERNEL="event[0-9]*", NAME="input/%k" -KERNEL="js[0-9]*", NAME="input/%k", MODE="0664" +KERNEL="js[0-9]*", NAME="input/%k" KERNEL="ts[0-9]*", NAME="input/%k" KERNEL="uinput", NAME="input/%k" @@ -193,7 +133,12 @@ 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" + # device mapper creates its own device nodes, so ignore these -KERNEL="dm-[0-9]*", NAME="" +KERNEL="dm-[0-9]*", OPTIONS="ignore_device" KERNEL="device-mapper", NAME="mapper/control" diff --git a/etc/udev/debian/permissions.rules b/etc/udev/debian/permissions.rules new file mode 100644 index 0000000000..48510e67f6 --- /dev/null +++ b/etc/udev/debian/permissions.rules @@ -0,0 +1,73 @@ +# default permissions for block devices +SUBSYSTEM="block", GROUP="disk" +SUBSYSTEM="block", SYSFS{removable}="1", GROUP="floppy" + +# IDE devices +BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", GROUP="cdrom" +BUS="ide", KERNEL="ht[0-9]*", GROUP="tape" +BUS="ide", KERNEL="nht[0-9]*", GROUP="tape" + +# SCSI devices +BUS="scsi", SYSFS{type}="1", GROUP="tape" +BUS="scsi", SYSFS{type}="5", GROUP="cdrom" +BUS="scsi", SYSFS{type}="6", GROUP="scanner" + +# USB devices +BUS="usb", KERNEL="legousbtower*", MODE="0666" + +# serial devices +SUBSYSTEM="tty", GROUP="dialout" +SUBSYSTEM="capi", 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" + +# video devices +SUBSYSTEM="video4linux", GROUP="video" +SUBSYSTEM="dvb", GROUP="video" +SUBSYSTEM="graphics", GROUP="video" +SUBSYSTEM="nvidia", GROUP="video" +SUBSYSTEM="drm", GROUP="video" + +# misc devices +KERNEL="random", MODE="0666" +KERNEL="urandom", MODE="0444" +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", MODE="0660", GROUP="audio" + +KERNEL="cdemu[0-9]*", GROUP="cdrom" +KERNEL="pktcdvd[0-9]*", GROUP="cdrom" +KERNEL="pktcdvd", MODE="0644" + +# printers and parallel devices +SUBSYSTEM="printer", GROUP="lp" +SUBSYSTEM="ppdev", GROUP="lp" +KERNEL="pt[0-9]*", GROUP="tape" +KERNEL="pht[0-9]*", GROUP="tape" + +# sound devices +SUBSYSTEM="sound", GROUP="audio" + +# input devices +KERNEL="event[0-9]*", PROGRAM="/etc/udev/scripts/inputdev.sh %k", \ + RESULT="inputdev", MODE="0664", GROUP="video" +KERNEL="js[0-9]*", MODE="0664" + +# AOE character devices +SUBSYSTEM="aoe", MODE="0220", GROUP="disk" +SUBSYSTEM="aoe", KERNEL="err", MODE="0440" + diff --git a/etc/udev/debian/udev.rules b/etc/udev/debian/udev.rules index 0f7aeb73d4..a506a02ad3 100644 --- a/etc/udev/debian/udev.rules +++ b/etc/udev/debian/udev.rules @@ -13,87 +13,37 @@ # %% the '%' char itself. # -# default permissions for block devices -SUBSYSTEM="block", GROUP="disk" -SUBSYSTEM="block", SYSFS{removable}="1", GROUP="floppy" - # workaround for devices which do not report media changes BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/model", RESULT="IOMEGA ZIP *", \ - NAME{all_partitions}="%k%n", GROUP="floppy" - -# IDE devices -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", \ - GROUP="cdrom" -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="floppy*", \ - GROUP="floppy" -BUS="ide", KERNEL="ht[0-9]*", GROUP="tape" -BUS="ide", KERNEL="nht[0-9]*", GROUP="tape" + PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT="IOMEGA ZIP *", \ + OPTIONS="all_partitions", NAME="%k" # SCSI devices -BUS="scsi", KERNEL="sr[0-9]*", SYSFS{type}="5", \ - NAME="scd%n", SYMLINK="sr%n", GROUP="cdrom" -BUS="scsi", KERNEL="sg[0-9]*", SYSFS{type}="5", GROUP="cdrom" -BUS="scsi", KERNEL="st[0-9]*", GROUP="tape" -BUS="scsi", KERNEL="nst[0-9]*", GROUP="tape" -BUS="scsi", KERNEL="osst[0-9]*", GROUP="tape" -BUS="scsi", KERNEL="nosst[0-9]*", GROUP="tape" +BUS="scsi", KERNEL="sr[0-9]*", NAME="scd%n", SYMLINK="sr%n" # USB devices BUS="usb", KERNEL="hiddev*", NAME="usb/%k" BUS="usb", KERNEL="auer[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="legousbtower*", NAME="usb/%k", MODE="0666" +BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" BUS="usb", KERNEL="dabusb*", NAME="usb/%k" BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" BUS="usb", KERNEL="ttyUSB*", SYSFS{product}="Palm Handheld*", SYMLINK="pilot" # serial devices -SUBSYSTEM="tty", GROUP="dialout" KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" KERNEL="capi[0-9]*", NAME="capi/%n" -# vc devices -KERNEL="ptmx", MODE="0666" -KERNEL="tty", MODE="0666" - # video devices -SUBSYSTEM="video4linux", GROUP="video" -KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", \ - NAME="%c", GROUP="video" -KERNEL="fb[0-9]*", GROUP="video" -KERNEL="nvidia*", GROUP="video" -KERNEL="card[0-9]*", NAME="dri/%k", GROUP="video" +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" +KERNEL="card[0-9]*", NAME="dri/%k" # misc devices -KERNEL="random", MODE="0666" -KERNEL="urandom", MODE="0444" -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", MODE="0664", GROUP="audio" KERNEL="hw_random", NAME="hwrng" -# printers and parallel devices -SUBSYSTEM="printer", GROUP="lp" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" -KERNEL="pt[0-9]*", GROUP="tape" -KERNEL="pht[0-9]*", GROUP="tape" - -KERNEL="fd[0-9]*", GROUP="floppy" - -KERNEL="cdemu[0-9]*", NAME="cdemu/%n", GROUP="cdrom" -KERNEL="pktcdvd[0-9]*", NAME="pktcdvd/%n", GROUP="cdrom" -KERNEL="pktcdvd", NAME="pktcdvd/control", MODE="0644" +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" @@ -106,7 +56,6 @@ KERNEL="tap[0-9]*", NAME="net/%k" KERNEL="tun", NAME="net/%k" # ALSA devices -SUBSYSTEM="sound", GROUP="audio" KERNEL="controlC[0-9]*", NAME="snd/%k" KERNEL="hwC[D0-9]*", NAME="snd/%k" KERNEL="pcmC[D0-9cp]*", NAME="snd/%k" @@ -117,11 +66,8 @@ KERNEL="seq", NAME="snd/%k" # input devices KERNEL="mice", NAME="input/%k" KERNEL="mouse[0-9]*", NAME="input/%k" -KERNEL="event[0-9]*", NAME="input/%k", \ - PROGRAM="/etc/udev/scripts/inputdev.sh %k", RESULT="inputdev", \ - MODE="0664", GROUP="video" KERNEL="event[0-9]*", NAME="input/%k" -KERNEL="js[0-9]*", NAME="input/%k", MODE="0664" +KERNEL="js[0-9]*", NAME="input/%k" KERNEL="ts[0-9]*", NAME="input/%k" KERNEL="uinput", NAME="input/%k" @@ -132,7 +78,12 @@ 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" + # device mapper creates its own device nodes, so ignore these -KERNEL="dm-[0-9]*", NAME="" +KERNEL="dm-[0-9]*", OPTIONS="ignore_device" KERNEL="device-mapper", NAME="mapper/control" From d3743cfb3bd605a8ccb52d30eeaad6a00e6d2123 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 11 Apr 2005 04:51:03 +0200 Subject: [PATCH 1284/4284] [PATCH] klibc: version 1.0.6 --- klibc/Makefile | 8 ++++---- klibc/klibc/Makefile | 6 ++++-- klibc/klibc/arch/alpha/sysstub.ph | 6 +++--- klibc/klibc/arch/arm/sysstub.ph | 6 +++--- klibc/klibc/arch/cris/sysstub.ph | 6 +++--- klibc/klibc/arch/i386/sysstub.ph | 6 +++--- klibc/klibc/arch/ia64/sysstub.ph | 6 +++--- klibc/klibc/arch/m32r/sysstub.ph | 6 +++--- klibc/klibc/arch/mips/sysstub.ph | 6 +++--- klibc/klibc/arch/parisc/sysstub.ph | 6 +++--- klibc/klibc/arch/ppc/sysstub.ph | 6 +++--- klibc/klibc/arch/ppc64/sysstub.ph | 6 +++--- klibc/klibc/arch/s390/sysstub.ph | 6 +++--- klibc/klibc/arch/s390x/sysstub.ph | 6 +++--- klibc/klibc/arch/sh/sysstub.ph | 6 +++--- klibc/klibc/arch/sparc/sysstub.ph | 6 +++--- klibc/klibc/arch/sparc64/sysstub.ph | 6 +++--- klibc/klibc/arch/x86_64/sysstub.ph | 6 +++--- klibc/klibc/socketcalls.pl | 16 ++++++++++------ klibc/klibc/syscalls.pl | 12 +++++++++--- klibc/makeklcc.pl | 26 ++++++++++++++++++++++++++ klibc/version | 2 +- 22 files changed, 102 insertions(+), 64 deletions(-) diff --git a/klibc/Makefile b/klibc/Makefile index 7a9b92e8d6..5071e60da4 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -18,12 +18,12 @@ $(CROSS)klibc.config: Makefile echo 'ARCH=$(ARCH)' >> $@ echo 'CROSS=$(CROSS)' >> $@ echo 'KCROSS=$(KCROSS)' >> $@ - echo "CC=$(shell bash -c 'type -p $(CC)')" >> $@ - echo "LD=$(shell bash -c 'type -p $(LD)')" >> $@ + echo 'CC=$(CC)' >> $@ + echo 'LD=$(LD)' >> $@ echo 'REQFLAGS=$(filter-out -I%,$(REQFLAGS))' >> $@ echo 'OPTFLAGS=$(OPTFLAGS)' >> $@ echo 'LDFLAGS=$(LDFLAGS)' >> $@ - echo "STRIP=$(shell bash -c 'type -p $(STRIP)')" >> $@ + echo 'STRIP=$(STRIP)' >> $@ echo 'STRIPFLAGS=$(STRIPFLAGS)' >> $@ echo 'EMAIN=$(EMAIN)' >> $@ echo 'BITSIZE=$(BITSIZE)' >> $@ @@ -45,7 +45,7 @@ local-all: $(CROSS)klcc local-clean: rm -f klibc.config klcc -local-spotless: +local-spotless: local-clean rm -f klibc.spec *~ tags local-install: $(CROSS)klcc diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index c412a9ffea..181a226151 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -141,7 +141,9 @@ syscalls.nrs: ../include/sys/syscall.h syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscalls.nrs rm -rf syscalls mkdir syscalls - $(PERL) syscalls.pl SYSCALLS.i $(ARCH) $(BITSIZE) syscalls.nrs ../include/klibc/havesyscall.h + $(PERL) syscalls.pl SYSCALLS.i arch/$(ARCH)/sysstub.ph $(ARCH) \ + $(BITSIZE) syscalls.nrs \ + syscalls ../include/klibc/havesyscall.h touch $@ ../include/klibc/havesyscall.h: syscalls.dir @@ -150,7 +152,7 @@ syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscall socketcalls.dir: SOCKETCALLS.def socketcalls.pl socketcommon.h rm -rf socketcalls mkdir socketcalls - $(PERL) socketcalls.pl SOCKETCALLS.def $(ARCH) + $(PERL) socketcalls.pl SOCKETCALLS.def $(ARCH) socketcalls touch $@ %/static.obj: %.dir diff --git a/klibc/klibc/arch/alpha/sysstub.ph b/klibc/klibc/arch/alpha/sysstub.ph index a24b6c07dc..08b97e807e 100644 --- a/klibc/klibc/arch/alpha/sysstub.ph +++ b/klibc/klibc/arch/alpha/sysstub.ph @@ -12,13 +12,13 @@ # A few system calls are dual-return with the second return value in # r20 (a4). -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; $stype = $stype || 'common'; $stype = 'common' if ( $stype eq 'dual0' ); - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "#include \n"; print OUT "\n"; diff --git a/klibc/klibc/arch/arm/sysstub.ph b/klibc/klibc/arch/arm/sysstub.ph index bf953ccd80..256ea3d534 100644 --- a/klibc/klibc/arch/arm/sysstub.ph +++ b/klibc/klibc/arch/arm/sysstub.ph @@ -6,10 +6,10 @@ # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\t.text\n"; diff --git a/klibc/klibc/arch/cris/sysstub.ph b/klibc/klibc/arch/cris/sysstub.ph index 6c894f62f5..182ad73f8c 100644 --- a/klibc/klibc/arch/cris/sysstub.ph +++ b/klibc/klibc/arch/cris/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.text\n"; diff --git a/klibc/klibc/arch/i386/sysstub.ph b/klibc/klibc/arch/i386/sysstub.ph index 1ba7f36bac..e2649e283e 100644 --- a/klibc/klibc/arch/i386/sysstub.ph +++ b/klibc/klibc/arch/i386/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.type ${fname},\@function\n"; diff --git a/klibc/klibc/arch/ia64/sysstub.ph b/klibc/klibc/arch/ia64/sysstub.ph index 34031a29ae..8e686c68a3 100644 --- a/klibc/klibc/arch/ia64/sysstub.ph +++ b/klibc/klibc/arch/ia64/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.text\n"; diff --git a/klibc/klibc/arch/m32r/sysstub.ph b/klibc/klibc/arch/m32r/sysstub.ph index 3813ea4144..98dfb9d0a8 100644 --- a/klibc/klibc/arch/m32r/sysstub.ph +++ b/klibc/klibc/arch/m32r/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.text\n"; diff --git a/klibc/klibc/arch/mips/sysstub.ph b/klibc/klibc/arch/mips/sysstub.ph index abe599c17d..a71d5d02ef 100644 --- a/klibc/klibc/arch/mips/sysstub.ph +++ b/klibc/klibc/arch/mips/sysstub.ph @@ -9,11 +9,11 @@ # system call number in r0 (v0), return an error value in r19 (a3) as # well as the return value in r0 (v0). -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; $stype = $stype || 'common'; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "#include \n"; print OUT "#include \n"; diff --git a/klibc/klibc/arch/parisc/sysstub.ph b/klibc/klibc/arch/parisc/sysstub.ph index 63b5e17fcf..e2196acaf3 100644 --- a/klibc/klibc/arch/parisc/sysstub.ph +++ b/klibc/klibc/arch/parisc/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.text\n"; diff --git a/klibc/klibc/arch/ppc/sysstub.ph b/klibc/klibc/arch/ppc/sysstub.ph index 542ab5575c..3b3916c726 100644 --- a/klibc/klibc/arch/ppc/sysstub.ph +++ b/klibc/klibc/arch/ppc/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.type ${fname},\@function\n"; diff --git a/klibc/klibc/arch/ppc64/sysstub.ph b/klibc/klibc/arch/ppc64/sysstub.ph index 0a379158e1..9ee93701f6 100644 --- a/klibc/klibc/arch/ppc64/sysstub.ph +++ b/klibc/klibc/arch/ppc64/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.globl ${fname}\n"; diff --git a/klibc/klibc/arch/s390/sysstub.ph b/klibc/klibc/arch/s390/sysstub.ph index 3838a1f1b2..35f40a0865 100644 --- a/klibc/klibc/arch/s390/sysstub.ph +++ b/klibc/klibc/arch/s390/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.type ${fname},\@function\n"; diff --git a/klibc/klibc/arch/s390x/sysstub.ph b/klibc/klibc/arch/s390x/sysstub.ph index 10a47f7b07..55c721b558 100644 --- a/klibc/klibc/arch/s390x/sysstub.ph +++ b/klibc/klibc/arch/s390x/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.type ${fname},\@function\n"; diff --git a/klibc/klibc/arch/sh/sysstub.ph b/klibc/klibc/arch/sh/sysstub.ph index add5d35892..ce04b739e9 100644 --- a/klibc/klibc/arch/sh/sysstub.ph +++ b/klibc/klibc/arch/sh/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.section\t\".text.syscall\",\"ax\"\n"; diff --git a/klibc/klibc/arch/sparc/sysstub.ph b/klibc/klibc/arch/sparc/sysstub.ph index baad9e3d82..d8cedb5ae5 100644 --- a/klibc/klibc/arch/sparc/sysstub.ph +++ b/klibc/klibc/arch/sparc/sysstub.ph @@ -5,12 +5,12 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; $stype = $stype || 'common'; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.type ${fname},\@function\n"; diff --git a/klibc/klibc/arch/sparc64/sysstub.ph b/klibc/klibc/arch/sparc64/sysstub.ph index 2ef2c6b66e..deeb88ce07 100644 --- a/klibc/klibc/arch/sparc64/sysstub.ph +++ b/klibc/klibc/arch/sparc64/sysstub.ph @@ -5,12 +5,12 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; $stype = $stype || 'common'; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.type ${fname},\@function\n"; diff --git a/klibc/klibc/arch/x86_64/sysstub.ph b/klibc/klibc/arch/x86_64/sysstub.ph index 07af1227ca..e2d797b166 100644 --- a/klibc/klibc/arch/x86_64/sysstub.ph +++ b/klibc/klibc/arch/x86_64/sysstub.ph @@ -5,10 +5,10 @@ # Script to generate system call stubs # -sub make_sysstub($$$$@) { - my($fname, $type, $sname, $stype, @args) = @_; +sub make_sysstub($$$$$@) { + my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - open(OUT, '>', "syscalls/${fname}.S"); + open(OUT, '>', "${outputdir}/${fname}.S"); print OUT "#include \n"; print OUT "\n"; print OUT "\t.type ${fname},\@function\n"; diff --git a/klibc/klibc/socketcalls.pl b/klibc/klibc/socketcalls.pl index fd82b2b49f..024483f716 100644 --- a/klibc/klibc/socketcalls.pl +++ b/klibc/klibc/socketcalls.pl @@ -15,12 +15,13 @@ for $arg ( @ARGV ) { push(@args, $arg); } } -($file, $arch) = @args; +($file, $arch, $outputdir) = @args; if (!open(FILE, "< $file")) { die "$file: $!\n"; } +print "socketcall-objs := "; while ( defined($line = ) ) { chomp $line; $line =~ s/\s*[\#\;].*$//; # Strip comments and trailing blanks @@ -39,10 +40,11 @@ while ( defined($line = ) ) { push(@cargs, "$arg a".$i++); } $nargs = $i; + print " \\\n\tsocketcalls/${name}.o"; if ( $arch eq 'i386' ) { - open(OUT, '>', "socketcalls/${name}.S") - or die "$0: Cannot open socketcalls/${name}.S\n"; + open(OUT, '>', "${outputdir}/${name}.S") + or die "$0: Cannot open ${outputdir}/${name}.S\n"; print OUT "#include \n"; print OUT "\n"; @@ -56,10 +58,10 @@ while ( defined($line = ) ) { print OUT "\t.size ${name},.-${name}\n"; close(OUT); } else { - open(OUT, '>', "socketcalls/${name}.c") - or die "$0: Cannot open socketcalls/${name}.c\n"; + open(OUT, '>', "${outputdir}/${name}.c") + or die "$0: Cannot open ${outputdir}/${name}.c\n"; - print OUT "#include \"../socketcommon.h\"\n"; + print OUT "#include \"socketcommon.h\"\n"; print OUT "\n"; print OUT "#ifndef __NR_${name}\n\n"; @@ -82,3 +84,5 @@ while ( defined($line = ) ) { die "$file:$.: Could not parse input\n"; } } + +print "\n"; diff --git a/klibc/klibc/syscalls.pl b/klibc/klibc/syscalls.pl index 1c48ce58ff..9cea63097b 100644 --- a/klibc/klibc/syscalls.pl +++ b/klibc/klibc/syscalls.pl @@ -18,13 +18,14 @@ for $arg ( @ARGV ) { push(@args, $arg); } } -($file, $arch, $bits, $unistd, $havesyscall) = @args; +($file, $sysstub, $arch, $bits, $unistd, $outputdir, $havesyscall) = @args; -require "arch/$arch/sysstub.ph"; +require "$sysstub"; if (!open(UNISTD, '<', $unistd)) { die "$0: $unistd: $!\n"; } + while ( defined($line = ) ) { chomp $line; @@ -46,6 +47,8 @@ if (!open(FILE, '<', $file)) { die "$0: $file: $!\n"; } +print "syscall-objs := "; + while ( defined($line = ) ) { chomp $line; $line =~ s/\s*(|[\#;].*)$//; # Strip comments and trailing blanks @@ -104,11 +107,14 @@ while ( defined($line = ) ) { @args = split(/\s*\,\s*/, $argv); print HAVESYS "#define _KLIBC_HAVE_SYSCALL_${fname} ${sname}\n"; - make_sysstub($fname, $type, $sname, $stype, @args); + print " \\\n\tsyscalls/${fname}.o"; + make_sysstub($outputdir, $fname, $type, $sname, $stype, @args); } else { die "$file:$.: Could not parse input: \"$line\"\n"; } } +print "\n"; + print HAVESYS "\n#endif\n"; close(HAVESYS); diff --git a/klibc/makeklcc.pl b/klibc/makeklcc.pl index f8a6294db3..74045955fd 100644 --- a/klibc/makeklcc.pl +++ b/klibc/makeklcc.pl @@ -5,8 +5,27 @@ # Usage: makeklcc klcc.in klibc.config perlpath # +use File::Spec; + ($klccin, $klibcconf, $perlpath) = @ARGV; +sub pathsearch($) { + my($file) = @_; + my(@path); + my($p,$pp); + + if ( $file =~ /\// ) { + return File::Spec->rel2abs($file); + } + + foreach $p ( split(/\:/, $ENV{'PATH'}) ) { + $pp = File::Spec->rel2abs(File::Spec->catpath(undef, $p, $file)); + return $pp if ( -x $pp ); + } + + return undef; +} + print "#!${perlpath}\n"; open(KLIBCCONF, '<', $klibcconf) or die "$0: cannot open $klibcconf: $!\n"; @@ -14,6 +33,13 @@ while ( defined($l = ) ) { chomp $l; if ( $l =~ /^([^=]+)\=(.*)$/ ) { $n = $1; $s = $2; + + if ( $n eq 'CC' || $n eq 'LD' || $n eq 'STRIP' ) { + $s1 = pathsearch($s); + die "$0: Cannot find $n: $s\n" unless ( defined($s1) ); + $s = $s1; + } + print "\$$n = \"\Q$s\E\";\n"; print "\@$n = qw($s);\n"; print "\$conf{\'\L$n\E\'} = \\\$$n;\n"; diff --git a/klibc/version b/klibc/version index 90a27f9cea..af0b7ddbff 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -1.0.5 +1.0.6 From 05bd6efb41b6a80378cc4f6e7427a302b4953541 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 11 Apr 2005 22:38:41 +0200 Subject: [PATCH 1285/4284] [PATCH] add test for make -j4 to build-check --- Makefile | 1 + test/simple-build-check.sh | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 9c755ba4de..8520b5cc50 100644 --- a/Makefile +++ b/Makefile @@ -427,3 +427,4 @@ uninstall: uninstall-man uninstall-dev.d test: all @ cd test && ./udev-test.pl + @ cd test && ./udevstart-test.pl diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 1ebe044b98..d1e13e69ed 100644 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -10,7 +10,7 @@ make all $MAKEOPTS EXTRAS="$EXTRAS" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null -make all $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit +make all -j4 $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null @@ -18,7 +18,7 @@ make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null -make all $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit +make all -j4 $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null From 15139b8a623748e7d24b18f12e920d94743d8c52 Mon Sep 17 00:00:00 2001 From: "tklauser@access.unizh.ch" Date: Tue, 12 Apr 2005 01:05:03 +0200 Subject: [PATCH 1286/4284] [PATCH] fix stupid all_partitions bug > On Mon, 2005-04-11 at 14:55 +0200, Norbert Preining wrote: > > On Mon, 11 Apr 2005, Kay Sievers wrote: > > > > brw-rw---- 1 root root 8, 0 2005-04-10 14:58 /dev/sdcard > > > > brw-rw---- 1 root root 8, 1 2005-04-10 14:58 /dev/sdcard1 > > > > brw-rw---- 1 root root 8, 1 2005-04-10 14:58 /dev/sdcard2 > > > > brw-rw---- 1 root root 8, 1 2005-04-10 14:58 /dev/sdcard3 > > > > > > This looks broken. > > > > Good to hear. Yeah, I guess it's broken. In create_node() in udev_add.c there is always added 1 to the minor number, thus the error. The attached patch should fix this. --- test/udev-test.pl | 1 + udev_add.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index c1dc8b2f1b..3172d3302f 100644 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -418,6 +418,7 @@ EOF subsys => "block", devpath => "/block/sda", exp_name => "boot_disk15" , + exp_majorminor => "8:15", rules => <devt), minor(udev->devt)+1); + part_devt = makedev(major(udev->devt), minor(udev->devt) + i); udev_make_node(udev, partitionname, part_devt, udev->mode, uid, gid); } } From 9530f1fe19529e1acb31adf5a834fa6cb0a27e6a Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Thu, 14 Apr 2005 22:39:01 -0700 Subject: [PATCH 1287/4284] [PATCH] 057 relelease --- ChangeLog | 39 +++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index c7d7269400..5eb72461ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 8520b5cc50..2e5dd5d9cb 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 056 +VERSION = 057 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev From d4b611430083674ee1d3aa19b87c9894ac3e39d8 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 15 Apr 2005 16:28:21 +0200 Subject: [PATCH 1288/4284] [PATCH] klibc: version 1.0.7 --- klibc/klibc/Makefile | 12 ++++++------ klibc/klibc/socketcalls.pl | 4 ++-- klibc/klibc/syscalls.pl | 2 +- klibc/version | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile index 181a226151..dff813fc59 100644 --- a/klibc/klibc/Makefile +++ b/klibc/klibc/Makefile @@ -139,8 +139,8 @@ syscalls.nrs: ../include/sys/syscall.h $(CC) $(CFLAGS) -Wp,-dM -x c -E -o $@ $< syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscalls.nrs - rm -rf syscalls - mkdir syscalls + rm -f syscalls/*.[Ssco] syscalls/*.obj + mkdir -p syscalls $(PERL) syscalls.pl SYSCALLS.i arch/$(ARCH)/sysstub.ph $(ARCH) \ $(BITSIZE) syscalls.nrs \ syscalls ../include/klibc/havesyscall.h @@ -150,8 +150,8 @@ syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscall : Generated by side effect socketcalls.dir: SOCKETCALLS.def socketcalls.pl socketcommon.h - rm -rf socketcalls - mkdir socketcalls + rm -f socketcalls/*.[Ssco] socketcalls/*.obj + mkdir -p socketcalls $(PERL) socketcalls.pl SOCKETCALLS.def $(ARCH) socketcalls touch $@ @@ -167,8 +167,8 @@ clean: archclean find . -type f -a \( -name \*.[isoa] -o -name \*.l[iso] \) -print0 | xargs -0rt rm -f rm -f *.a *.so *.hash *.syms *.stripped rm -f $(TESTS) tests/*.stripped - rm -rf syscalls syscalls.dir - rm -rf socketcalls socketcalls.dir + rm -f syscalls/*.[Ssco] syscalls/*.obj syscalls.dir + rm -f socketcalls/*.[Ssco] socketcalls/*.obj socketcalls.dir rm -f sha1hash errlist.c spotless: clean diff --git a/klibc/klibc/socketcalls.pl b/klibc/klibc/socketcalls.pl index 024483f716..68f0fa164b 100644 --- a/klibc/klibc/socketcalls.pl +++ b/klibc/klibc/socketcalls.pl @@ -40,7 +40,7 @@ while ( defined($line = ) ) { push(@cargs, "$arg a".$i++); } $nargs = $i; - print " \\\n\tsocketcalls/${name}.o"; + print " \\\n\t${name}.o"; if ( $arch eq 'i386' ) { open(OUT, '>', "${outputdir}/${name}.S") @@ -61,7 +61,7 @@ while ( defined($line = ) ) { open(OUT, '>', "${outputdir}/${name}.c") or die "$0: Cannot open ${outputdir}/${name}.c\n"; - print OUT "#include \"socketcommon.h\"\n"; + print OUT "#include \"../socketcommon.h\"\n"; print OUT "\n"; print OUT "#ifndef __NR_${name}\n\n"; diff --git a/klibc/klibc/syscalls.pl b/klibc/klibc/syscalls.pl index 9cea63097b..0575fa6648 100644 --- a/klibc/klibc/syscalls.pl +++ b/klibc/klibc/syscalls.pl @@ -107,7 +107,7 @@ while ( defined($line = ) ) { @args = split(/\s*\,\s*/, $argv); print HAVESYS "#define _KLIBC_HAVE_SYSCALL_${fname} ${sname}\n"; - print " \\\n\tsyscalls/${fname}.o"; + print " \\\n\t${fname}.o"; make_sysstub($outputdir, $fname, $type, $sname, $stype, @args); } else { die "$file:$.: Could not parse input: \"$line\"\n"; diff --git a/klibc/version b/klibc/version index af0b7ddbff..238d6e882a 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -1.0.6 +1.0.7 From 197178360f5c4253aeb743b32224125e58e2fd5d Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Fri, 15 Apr 2005 16:28:56 +0200 Subject: [PATCH 1289/4284] [PATCH] libsysfs: version 2.0 --- libsysfs/dlist.c | 2 +- libsysfs/sysfs.h | 2 +- libsysfs/sysfs/dlist.h | 1 + libsysfs/sysfs/libsysfs.h | 15 ++ libsysfs/sysfs_bus.c | 317 ++++++++++++++++++++++++++++++++++++++ libsysfs/sysfs_class.c | 188 +++++++++++++++++++++- libsysfs/sysfs_device.c | 9 +- libsysfs/sysfs_dir.c | 8 +- libsysfs/sysfs_utils.c | 2 +- 9 files changed, 530 insertions(+), 14 deletions(-) create mode 100644 libsysfs/sysfs_bus.c diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c index c44e9d5ff5..5579602bbc 100644 --- a/libsysfs/dlist.c +++ b/libsysfs/dlist.c @@ -551,7 +551,7 @@ void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)) struct dlist *templist; unsigned int passcount = 1; unsigned int mergecount = 1; - + dlist_start(list); templist = dlist_new(list->data_size); diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h index 838427797d..2add8227a4 100644 --- a/libsysfs/sysfs.h +++ b/libsysfs/sysfs.h @@ -3,7 +3,7 @@ * * Internal Header Definitions for libsysfs * - * Copyright (C) IBM Corp. 2003 + * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/libsysfs/sysfs/dlist.h b/libsysfs/sysfs/dlist.h index 62eaa9fec4..335a490a0a 100644 --- a/libsysfs/sysfs/dlist.h +++ b/libsysfs/sysfs/dlist.h @@ -50,6 +50,7 @@ * Just use the dlist_(insert|delete)_(before|after) macros if you do not want * to think about it. + */ #include diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h index 2f122405d7..12e7cc5f99 100644 --- a/libsysfs/sysfs/libsysfs.h +++ b/libsysfs/sysfs/libsysfs.h @@ -184,6 +184,21 @@ extern struct dlist *sysfs_get_classdev_attributes (struct sysfs_class_device *clsdev); extern struct sysfs_device *sysfs_get_classdev_device (struct sysfs_class_device *clsdev); +extern void sysfs_close_class(struct sysfs_class *cls); +extern struct sysfs_class *sysfs_open_class(const char *name); +extern struct sysfs_class_device *sysfs_get_class_device + (struct sysfs_class *cls, const char *name); +extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); + +/* generic sysfs bus access */ +extern void sysfs_close_bus(struct sysfs_bus *bus); +extern struct sysfs_bus *sysfs_open_bus(const char *name); +extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); +extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); +extern struct sysfs_device *sysfs_get_bus_device + (struct sysfs_bus *bus, const char *id); +extern struct sysfs_driver *sysfs_get_bus_driver + (struct sysfs_bus *bus, const char *drvname); /** * sort_list: sorter function to keep list elements sorted in alphabetical diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c new file mode 100644 index 0000000000..921ef32094 --- /dev/null +++ b/libsysfs/sysfs_bus.c @@ -0,0 +1,317 @@ +/* + * sysfs_bus.c + * + * Generic bus utility functions for libsysfs + * + * Copyright (C) IBM Corp. 2003-2005 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include "libsysfs.h" +#include "sysfs.h" + +static void sysfs_close_dev(void *dev) +{ + sysfs_close_device((struct sysfs_device *)dev); +} + +static void sysfs_close_drv(void *drv) +{ + sysfs_close_driver((struct sysfs_driver *)drv); +} + +/* + * compares names. + * @a: name looked for + * @b: sysfs_device comparing being compared + * returns 1 if a==b->name or 0 not equal + */ +static int name_equal(void *a, void *b) +{ + if (!a || !b) + return 0; + + if (strcmp(((char *)a), ((struct sysfs_device *)b)->name) == 0) + return 1; + + return 0; +} + +/** + * sysfs_close_bus: close single bus + * @bus: bus structure + */ +void sysfs_close_bus(struct sysfs_bus *bus) +{ + if (bus) { + if (bus->attrlist) + dlist_destroy(bus->attrlist); + if (bus->devices) + dlist_destroy(bus->devices); + if (bus->drivers) + dlist_destroy(bus->drivers); + free(bus); + } +} + +/** + * alloc_bus: mallocs new bus structure + * returns sysfs_bus_bus struct or NULL + */ +static struct sysfs_bus *alloc_bus(void) +{ + return (struct sysfs_bus *)calloc(1, sizeof(struct sysfs_bus)); +} + +/** + * sysfs_get_bus_devices: gets all devices for bus + * @bus: bus to get devices for + * returns dlist of devices with success and NULL with failure + */ +struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) +{ + struct sysfs_device *dev; + struct dlist *linklist; + char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; + char target[SYSFS_PATH_MAX]; + char *curlink; + + if (!bus) { + errno = EINVAL; + return NULL; + } + memset(path, 0, SYSFS_PATH_MAX); + safestrcpy(path, bus->path); + safestrcat(path, "/"); + safestrcat(path, SYSFS_DEVICES_NAME); + + linklist = read_dir_links(path); + if (linklist) { + dlist_for_each_data(linklist, curlink, char) { + if (bus->devices) { + dev = (struct sysfs_device *) + dlist_find_custom(bus->devices, + (void *)curlink, name_equal); + if (dev) + continue; + } + safestrcpy(devpath, path); + safestrcat(devpath, "/"); + safestrcat(devpath, curlink); + if (sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) { + dprintf("Error getting link - %s\n", devpath); + continue; + } + dev = sysfs_open_device_path(target); + if (!dev) { + dprintf("Error opening device at %s\n", + target); + continue; + } + if (!bus->devices) + bus->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_dev); + dlist_unshift_sorted(bus->devices, dev, sort_list); + } + sysfs_close_list(linklist); + } + return (bus->devices); +} + +/** + * sysfs_get_bus_drivers: gets all drivers for bus + * @bus: bus to get devices for + * returns dlist of devices with success and NULL with failure + */ +struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) +{ + struct sysfs_driver *drv; + struct dlist *dirlist; + char path[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX]; + char *curdir; + + if (!bus) { + errno = EINVAL; + return NULL; + } + memset(path, 0, SYSFS_PATH_MAX); + safestrcpy(path, bus->path); + safestrcat(path, "/"); + safestrcat(path, SYSFS_DRIVERS_NAME); + + dirlist = read_dir_subdirs(path); + if (dirlist) { + dlist_for_each_data(dirlist, curdir, char) { + if (bus->drivers) { + drv = (struct sysfs_driver *) + dlist_find_custom(bus->drivers, + (void *)curdir, name_equal); + if (drv) + continue; + } + safestrcpy(drvpath, path); + safestrcat(drvpath, "/"); + safestrcat(drvpath, curdir); + drv = sysfs_open_driver_path(drvpath); + if (!drv) { + dprintf("Error opening driver at %s\n", + drvpath); + continue; + } + if (!bus->drivers) + bus->drivers = dlist_new_with_delete + (sizeof(struct sysfs_driver), + sysfs_close_drv); + dlist_unshift_sorted(bus->drivers, drv, sort_list); + } + sysfs_close_list(dirlist); + } + return (bus->drivers); +} + +/** + * sysfs_open_bus: opens specific bus and all its devices on system + * returns sysfs_bus structure with success or NULL with error. + */ +struct sysfs_bus *sysfs_open_bus(const char *name) +{ + struct sysfs_bus *bus; + char buspath[SYSFS_PATH_MAX]; + + if (!name) { + errno = EINVAL; + return NULL; + } + + memset(buspath, 0, SYSFS_PATH_MAX); + if (sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) { + dprintf("Sysfs not supported on this system\n"); + return NULL; + } + + safestrcat(buspath, "/"); + safestrcat(buspath, SYSFS_BUS_NAME); + safestrcat(buspath, "/"); + safestrcat(buspath, name); + if (sysfs_path_is_dir(buspath)) { + dprintf("Invalid path to bus: %s\n", buspath); + return NULL; + } + bus = alloc_bus(); + if (!bus) { + dprintf("calloc failed\n"); + return NULL; + } + safestrcpy(bus->name, name); + safestrcpy(bus->path, buspath); + if (sysfs_remove_trailing_slash(bus->path)) { + dprintf("Incorrect path to bus %s\n", bus->path); + sysfs_close_bus(bus); + return NULL; + } + + return bus; +} + +/** + * sysfs_get_bus_device: Get specific device on bus using device's id + * @bus: bus to find device on + * @id: bus_id for device + * returns struct sysfs_device reference or NULL if not found. + */ +struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, + const char *id) +{ + struct sysfs_device *dev = NULL; + char devpath[SYSFS_PATH_MAX], target[SYSFS_PATH_MAX]; + + if (!bus || !id) { + errno = EINVAL; + return NULL; + } + + if (bus->devices) { + dev = (struct sysfs_device *)dlist_find_custom + (bus->devices, (void *)id, name_equal); + if (dev) + return dev; + } + safestrcpy(devpath, bus->path); + safestrcat(devpath, "/"); + safestrcat(devpath, SYSFS_DEVICES_NAME); + safestrcat(devpath, "/"); + safestrcat(devpath, id); + if (sysfs_path_is_link(devpath)) { + dprintf("No such device %s on bus %s?\n", id, bus->name); + return NULL; + } + if (!sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) { + dev = sysfs_open_device_path(target); + if (!dev) { + dprintf("Error opening device at %s\n", target); + return NULL; + } + if (!bus->devices) + bus->devices = dlist_new_with_delete + (sizeof(struct sysfs_device), + sysfs_close_dev); + dlist_unshift_sorted(bus->devices, dev, sort_list); + } + return dev; +} + +/** + * sysfs_get_bus_driver: Get specific driver on bus using driver name + * @bus: bus to find driver on + * @drvname: name of driver + * returns struct sysfs_driver reference or NULL if not found. + */ +struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, + const char *drvname) +{ + struct sysfs_driver *drv; + char drvpath[SYSFS_PATH_MAX]; + + if (!bus || !drvname) { + errno = EINVAL; + return NULL; + } + + if (bus->drivers) { + drv = (struct sysfs_driver *)dlist_find_custom + (bus->drivers, (void *)drvname, name_equal); + if (drv) + return drv; + } + safestrcpy(drvpath, bus->path); + safestrcat(drvpath, "/"); + safestrcat(drvpath, SYSFS_DRIVERS_NAME); + safestrcat(drvpath, "/"); + safestrcat(drvpath, drvname); + drv = sysfs_open_driver_path(drvpath); + if (!drv) { + dprintf("Error opening driver at %s\n", drvpath); + return NULL; + } + if (!bus->drivers) + bus->drivers = dlist_new_with_delete + (sizeof(struct sysfs_driver), + sysfs_close_drv); + dlist_unshift_sorted(bus->drivers, drv, sort_list); + return drv; +} + diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index a93de573d4..edf751b124 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -40,6 +40,43 @@ void sysfs_close_class_device(struct sysfs_class_device *dev) } } +static void sysfs_close_cls_dev(void *dev) +{ + sysfs_close_class_device((struct sysfs_class_device *)dev); +} + +/** + * sysfs_close_class: close the given class + * @cls: sysfs_class to close + */ +void sysfs_close_class(struct sysfs_class *cls) +{ + if (cls) { + if (cls->devices) + dlist_destroy(cls->devices); + if (cls->attrlist) + dlist_destroy(cls->attrlist); + free(cls); + } +} + +static int cdev_name_equal(void *a, void *b) +{ + if (!a || !b) + return 0; + + if (strncmp((char *)a, ((struct sysfs_class_device *)b)->name, + strlen((char *)a)) == 0) + return 1; + + return 0; +} + +static struct sysfs_class *alloc_class(void) +{ + return (struct sysfs_class *) calloc(1, sizeof(struct sysfs_class)); +} + /** * alloc_class_device: mallocs and initializes new class device struct. * returns sysfs_class_device or NULL. @@ -96,7 +133,7 @@ struct sysfs_class_device *sysfs_open_class_device_path(const char *path) errno = EINVAL; return NULL; } - if ((sysfs_path_is_dir(path)) != 0) { + if (sysfs_path_is_dir(path)) { dprintf("%s is not a valid path to a class device\n", path); return NULL; } @@ -113,7 +150,7 @@ struct sysfs_class_device *sysfs_open_class_device_path(const char *path) } safestrcpy(cdev->path, path); - if ((sysfs_remove_trailing_slash(cdev->path)) != 0) { + if (sysfs_remove_trailing_slash(cdev->path)) { dprintf("Invalid path to class device %s\n", cdev->path); sysfs_close_class_device(cdev); return NULL; @@ -335,3 +372,150 @@ struct sysfs_device *sysfs_get_classdev_device } return clsdev->sysdevice; } + +/** + * sysfs_open_class: opens specific class and all its devices on system + * returns sysfs_class structure with success or NULL with error. + */ +struct sysfs_class *sysfs_open_class(const char *name) +{ + struct sysfs_class *cls = NULL; + char classpath[SYSFS_PATH_MAX]; + + if (!name) { + errno = EINVAL; + return NULL; + } + + memset(classpath, 0, SYSFS_PATH_MAX); + if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { + dprintf("Sysfs not supported on this system\n"); + return NULL; + } + + /* + * We shall now treat "block" also as a class. Hence, check here + * if "name" is "block" and proceed accordingly + */ + if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { + safestrcat(classpath, "/"); + safestrcat(classpath, SYSFS_BLOCK_NAME); + } else { + safestrcat(classpath, "/"); + safestrcat(classpath, SYSFS_CLASS_NAME); + safestrcat(classpath, "/"); + safestrcat(classpath, name); + } + if (sysfs_path_is_dir(classpath)) { + dprintf("Class %s not found on the system\n", name); + return NULL; + } + + cls = alloc_class(); + if (cls == NULL) { + dprintf("calloc failed\n"); + return NULL; + } + safestrcpy(cls->name, name); + safestrcpy(cls->path, classpath); + if ((sysfs_remove_trailing_slash(cls->path)) != 0) { + dprintf("Invalid path to class device %s\n", cls->path); + sysfs_close_class(cls); + return NULL; + } + + return cls; +} + +/** + * sysfs_get_class_device: get specific class device using the device's id + * @cls: sysfs_class to find the device on + * @name: name of the class device to look for + * + * Returns sysfs_class_device * on success and NULL on failure + */ +struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, + const char *name) +{ + char path[SYSFS_PATH_MAX]; + struct sysfs_class_device *cdev = NULL; + + if (!cls || !name) { + errno = EINVAL; + return NULL; + } + + if (cls->devices) { + cdev = (struct sysfs_class_device *)dlist_find_custom + (cls->devices, (void *)name, cdev_name_equal); + if (cdev) + return cdev; + } + + safestrcpy(path, cls->path); + safestrcat(path, "/"); + safestrcat(path, name); + if (!sysfs_path_is_dir(path)) { + cdev = sysfs_open_class_device_path(path); + if (!cdev) { + dprintf("Error opening class device at %s\n", path); + return NULL; + } + } + if (!cls->devices) + cls->devices = dlist_new_with_delete + (sizeof(struct sysfs_class_device), + sysfs_close_cls_dev); + + dlist_unshift_sorted(cls->devices, cdev, sort_list); + return cdev; +} + +/** + * sysfs_get_class_devices: get all class devices in the given class + * @cls: sysfs_class whose devices list is needed + * + * Returns a dlist of sysfs_class_device * on success and NULL on failure + */ +struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) +{ + char path[SYSFS_PATH_MAX]; + char *cdev_name; + struct sysfs_class_device *cdev = NULL; + struct dlist *dirlist; + + if (!cls) { + errno = EINVAL; + return NULL; + } + + safestrcpy(path, cls->path); + dirlist = read_dir_subdirs(path); + if (dirlist) { + dlist_for_each_data(dirlist, cdev_name, char) { + if (cls->devices) { + cdev = (struct sysfs_class_device *) + dlist_find_custom(cls->devices, + (void *)cdev_name, cdev_name_equal); + if (cdev) + continue; + } + safestrcpy(path, cls->path); + safestrcat(path, "/"); + safestrcat(path, cdev_name); + cdev = sysfs_open_class_device_path(path); + if (cdev) { + if (!cls->devices) + cls->devices = dlist_new_with_delete + (sizeof(struct sysfs_class_device), + sysfs_close_cls_dev); + dlist_unshift_sorted(cls->devices, cdev, + sort_list); + } + } + sysfs_close_list(dirlist); + } + + return cls->devices; +} + diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 7087730d5f..d1c5b321f0 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -38,7 +38,6 @@ static int get_dev_driver(struct sysfs_device *dev) errno = EINVAL; return -1; } - memset(path, 0, SYSFS_PATH_MAX); memset(devpath, 0, SYSFS_PATH_MAX); safestrcpymax(path, dev->path, SYSFS_PATH_MAX); @@ -53,9 +52,9 @@ static int get_dev_driver(struct sysfs_device *dev) } /* - * Devices on on earlier kernels do not have the "driver" link. + * Devices on earlier kernels do not have the "driver" link. * Look it up in the bus directory. - */ + */ if (dev->bus[0] == '\0') return -1; memset(path, 0, SYSFS_PATH_MAX); @@ -81,7 +80,7 @@ static int get_dev_driver(struct sysfs_device *dev) safestrcat(devpath, drv); safestrcat(devpath, "/"); safestrcat(devpath, dev->bus_id); - if (sysfs_path_is_link(devpath) == 0) { + if (!sysfs_path_is_link(devpath)) { safestrcpy(dev->driver_name, drv); sysfs_close_list(drvlist); return 0; @@ -149,7 +148,7 @@ int sysfs_get_device_bus(struct sysfs_device *dev) safestrcat(path, SYSFS_DEVICES_NAME); safestrcat(path, "/"); safestrcat(path, dev->bus_id); - if ((sysfs_path_is_link(path)) == 0) { + if (!sysfs_path_is_link(path)) { memset(target, 0, SYSFS_PATH_MAX); if (sysfs_get_link(path, target, SYSFS_PATH_MAX)) { diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c index ac3936656c..7d98c669c6 100644 --- a/libsysfs/sysfs_dir.c +++ b/libsysfs/sysfs_dir.c @@ -338,7 +338,7 @@ struct sysfs_attribute *get_attribute(void *dev, const char *name) SYSFS_PATH_MAX); safestrcatmax(path, "/", SYSFS_PATH_MAX); safestrcatmax(path, name, SYSFS_PATH_MAX); - if (!(sysfs_path_is_file(path))) + if (!sysfs_path_is_file(path)) cur = add_attribute((void *)dev, path); return cur; } @@ -373,7 +373,7 @@ struct dlist *read_dir_links(const char *path) safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); - if ((sysfs_path_is_link(file_path)) == 0) { + if (!sysfs_path_is_link(file_path)) { if (!linklist) { linklist = dlist_new_with_delete (SYSFS_NAME_LEN, sysfs_del_name); @@ -421,7 +421,7 @@ struct dlist *read_dir_subdirs(const char *path) safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); - if ((sysfs_path_is_dir(file_path)) == 0) { + if (!sysfs_path_is_dir(file_path)) { if (!dirlist) { dirlist = dlist_new_with_delete (SYSFS_NAME_LEN, sysfs_del_name); @@ -471,7 +471,7 @@ struct dlist *get_attributes_list(void *dev) safestrcpy(file_path, path); safestrcat(file_path, "/"); safestrcat(file_path, dirent->d_name); - if ((sysfs_path_is_file(file_path)) == 0) { + if (!sysfs_path_is_file(file_path)) { if (((struct sysfs_device *)dev)->attrlist) { /* check if attr is already in the list */ attr = (struct sysfs_attribute *) diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index 210c2a086d..c5558a43a1 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -3,7 +3,7 @@ * * System utility functions for libsysfs * - * Copyright (C) IBM Corp. 2003 + * Copyright (C) IBM Corp. 2003-2005 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public From 11a598f7ef4c263a6546b512806358970dfe5010 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Mon, 18 Apr 2005 23:59:43 +0200 Subject: [PATCH 1290/4284] [PATCH] Fedora udev.rules update --- etc/udev/redhat/udev.permissions | 202 ----------------------- etc/udev/redhat/udev.rules | 273 +++++++++++++++++++++---------- 2 files changed, 191 insertions(+), 284 deletions(-) delete mode 100644 etc/udev/redhat/udev.permissions diff --git a/etc/udev/redhat/udev.permissions b/etc/udev/redhat/udev.permissions deleted file mode 100644 index 19de177c82..0000000000 --- a/etc/udev/redhat/udev.permissions +++ /dev/null @@ -1,202 +0,0 @@ -# /etc/udev/udev.permissions: permission/ownership map for udev - -# console devices -console:root:root:0600 -tty:root:root:0666 -tty[0-9]:root:tty:0660 -tty[0-9][0-9]*:root:tty:0660 -vc/[0-9]*:root:tty:0660 - -# pty devices -# Set this to 0660 if you only want users belonging to tty group -# to be able to allocate PTYs -ptmx:root:tty:0666 -pty[p-za-e][0-9a-f]*:root:tty:0660 -tty[p-za-e][0-9a-f]*:root:tty:0660 -pty/m*:root:tty:0660 -vc/s*:root:tty:0660 - -# serial+dialup devices -ttyS*:root:uucp:0660 -ippp*:root:root:0660 -isdn*:root:root:0660 -isdnctrl*:root:root:0660 -capi*:root:root:0660 -dcbri*:root:root:0660 -ircomm*:root:uucp:0660 -ttyUSB*:root:uucp:0660 -tts/[0-9]*:root:uucp:0660 -tts/USB[0-9]*:root:uucp:0660 - -# vc devices -vcs:vcsa:tty:0600 -vcs[0-9]*:vcsa:tty:0600 -vcsa:vcsa:tty:0600 -vcsa[0-9]*:vcsa:tty:0600 -vcc/*:vcsa:tty:0600 - -# memory devices -random:root:root:0666 -urandom:root:root:0444 -mem:root:kmem:0640 -kmem:root:kmem:0640 -port:root:kmem:0640 -full:root:root:0666 -null:root:root:0666 -zero:root:root:0666 - -# misc devices -nvram:root:root:0660 -rtc:root:root:0644 - -# floppy devices -fd[01]*:root:floppy:0660 - -# audio devices -dsp*:root:root:0660 -audio*:root:root:0660 -midi*:root:root:0660 -mixer*:root:root:0660 -sequencer*:root:root:0660 -sound/*:root:root:0660 -snd/*:root:root:0660 -beep:root:root:0660 -admm*:root:root:0660 -adsp*:root:root:0660 -aload*:root:root:0660 -amidi*:root:root:0660 -dmfm*:root:root:0660 -dmmidi*:root:root:0660 -sndstat:root:root:0660 - -# optical devices -sr*:root:disk:0640 -scd*:root:disk:0640 -pcd*:root:disk:0640 -disk*:root:disk:0640 -dvd:root:disk:0640 -rdvd:root:disk:0640 -cdroms/*:root:disk:0640 - -# pilot/palm devices -pilot:root:uucp:0660 - -# jaz devices -jaz*:root:disk:0640 - -# zip devices -pocketzip*:root:disk:0640 -zip*:root:disk:0640 - -# ls120 devices -ls120:root:disk:0640 -ls120*:root:disk:0640 - -# lp devices -lp*:root:lp:0660 -parport*:root:lp:0660 -irlpt*:root:lp:0660 -usblp*:root:lp:0660 -usb/lp*:root:lp:0660 - -# scanner devices -scanner:root:root:0600 -usb/scanner*:root:root:0600 - -# camera devices -camera*:root:root:0600 -usb/dc2xx*:root:root:0600 -usb/mdc800*:root:root:0600 - -# raw devices -ram*:root:disk:0640 -raw/*:root:disk:0640 - -# disk devices -hd*:root:disk:0640 -sd*:root:disk:0640 -dasd*:root:disk:0640 -ataraid*:root:disk:0640 -loop*:root:disk:0640 -md*:root:disk:0640 -ide/*/*/*/*/*:root:disk:0640 -discs/*/*:root:disk:0640 -loop/*:root:disk:0640 -md/*:root:disk:0640 - -# tape devices -ht*:root:disk:0640 -nht*:root:disk:0640 -pt[0-9]*:root:disk:0640 -npt*:root:disk:0640 -st*:root:disk:0640 -nst*:root:disk:0640 - -# dm devices -dm-*:root:root:0640 - -# memstick devices -memstick*:root:root:0600 - -# flash devices -flash*:root:root:0600 - -# diskonkey devices -diskonkey*:root:disk:0640 - -# rem_ide devices -microdrive*:root:disk:0640 - -# fb devices -fb:root:root:0600 -fb[0-9]*:root:root:0600 -fb/*:root:root:0600 - -# kbd devices -kbd:root:root:0644 - -# joystick devices -js[0-9]*:root:root:0644 -djs[0-9]*:root:root:0644 - -# v4l devices -video*:root:root:0660 -radio*:root:root:0660 -winradio*:root:root:0660 -vtx*:root:root:0660 -vbi*:root:root:0660 -video/*:root:root:0660 -vttuner:root:root:0660 -v4l/*:root:root:0660 - -# input devices -input/*:root:root:0644 - -# gpm devices -gpmctl:root:root:0700 - -# dri devices -nvidia*:root:root:0660 -3dfx*:root:root:0660 -dri/*:root:root:0660 - -# mainboard devices -apm_bios:root:root:0600 - -# scsi devices -sg*:root:disk:0640 -pg*:root:disk:0640 -cdwriter:root:disk:0640 - -# usb devices -usb/dabusb*:root:usb:0660 -usb/mdc800*:root:usb:0660 -usb/rio500:root:usb:0660 - -# s390 devices -z90crypt:root:root:0666 - -# DVB -dvb/*:root:root:0660 -dvb:root:root:0660 -dvb/adapter*:root:root:0660 diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 9df77b3339..ad60d1a81d 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -1,110 +1,219 @@ # 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 +# default is OWNER="root" GROUP="root", MODE="0600" # +# all block devices +SUBSYSTEM=="block", GROUP="disk", MODE="0640" + +# console devices +KERNEL=="tty", MODE="0666" +KERNEL=="tty[0-9]", GROUP="tty", MODE="0660" +KERNEL=="tty[0-9][0-9]*", GROUP="tty", MODE="0660" +KERNEL=="vc/[0-9]*", 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", GROUP="tty", MODE="0666" +KERNEL=="pty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660" +KERNEL=="tty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660" +KERNEL=="pty/m*", GROUP="tty", MODE="0660" +KERNEL=="vc/s*", GROUP="tty", MODE="0660" + +# serial+dialup devices +KERNEL=="ttyS*", GROUP="uucp", MODE="0660" +KERNEL=="ippp*", MODE="0660" +KERNEL=="isdn*", MODE="0660" +KERNEL=="isdnctrl*", MODE="0660" +KERNEL=="capi*", MODE="0660" +KERNEL=="dcbri*", MODE="0660" +KERNEL=="ircomm*", GROUP="uucp", MODE="0660" +KERNEL=="ttyUSB*", GROUP="uucp", MODE="0660" +KERNEL=="tts/[0-9]*", GROUP="uucp", MODE="0660" +KERNEL=="tts/USB[0-9]*", GROUP="uucp", MODE="0660" + +# vc devices +KERNEL=="vcs", OWNER="vcsa", GROUP="tty" +KERNEL=="vcs[0-9]*", OWNER="vcsa", GROUP="tty" +KERNEL=="vcsa", OWNER="vcsa", GROUP="tty" +KERNEL=="vcsa[0-9]*", OWNER="vcsa", GROUP="tty" +KERNEL=="vcc/*", 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" + +# misc devices +KERNEL=="nvram", MODE="0660" +KERNEL=="rtc", MODE="0644" + +# floppy devices +KERNEL=="fd[01]*", GROUP="floppy", MODE="0660" + +# 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" + +# pilot/palm devices +KERNEL=="pilot", GROUP="uucp", 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 +KERNEL=="ht*", GROUP="disk", MODE="0640" +KERNEL=="nht*", GROUP="disk", MODE="0640" +KERNEL=="pt[0-9]*", GROUP="disk", MODE="0640" +KERNEL=="npt*", GROUP="disk", MODE="0640" +KERNEL=="st*", GROUP="disk", MODE="0640" +KERNEL=="nst*", GROUP="disk", MODE="0640" +KERNEL=="osst*", GROUP="disk", MODE="0640" +KERNEL=="nosst*", GROUP="disk", MODE="0640" + +# 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="0644" + +# gpm devices +KERNEL=="gpmctl", MODE="0700" + +# dri devices +KERNEL=="nvidia*", MODE="0660" +KERNEL=="3dfx*", MODE="0660" +KERNEL=="dri/*", MODE="0666" + +# usb devices +KERNEL=="usb/dabusb*", GROUP="usb", MODE="0660" +KERNEL=="usb/mdc800*", GROUP="usb", MODE="0660" +KERNEL=="usb/rio500", GROUP="usb", MODE="0660" + +# s390 devices +KERNEL=="z90crypt", MODE="0666" + +# DVB +KERNEL=="dvb/*", MODE="0660" +KERNEL=="dvb", MODE="0660" +KERNEL=="dvb/adapter*", MODE="0660" + # 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="console", NAME="%k", GROUP="tty", MODE="0600" -KERNEL="tty", NAME="%k", GROUP="tty", MODE="0666" -KERNEL="tty[0-9]*", NAME="%k", GROUP="tty" - -KERNEL="ptmx", NAME="%k", GROUP="tty", MODE="0666" -KERNEL="pty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="%k", GROUP="tty" - -KERNEL="ttyS[0-9]*", NAME="%k", GROUP="uucp" -KERNEL="ttyUSB[0-9]*", NAME="%k", GROUP="uucp" -KERNEL="ippp0", NAME="%k" -KERNEL="isdn*", NAME="%k" -KERNEL="dcbri*", NAME="%k" -KERNEL="ircomm*", NAME="%k", GROUP="uucp" - -KERNEL="vcs", NAME="%k", OWNER="vcsa", GROUP="tty", MODE="0600" -KERNEL="vcsa[0-9]*", NAME="%k", OWNER="vcsa", GROUP="tty", MODE="0600 - -# 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" +#KERNEL=="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK="%c" # DRI devices always go into a subdirectory (as per the LSB spec) -KERNEL="card*", NAME="dri/card%n" +KERNEL=="card*", NAME="dri/card%n" # 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" +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" -KERNEL="ts*", NAME="input/%k" +KERNEL=="mice", NAME="input/%k" +KERNEL=="mouse*", NAME="input/%k" +KERNEL=="event*", NAME="input/%k" +KERNEL=="js*", NAME="input/%k" +KERNEL=="ts*", NAME="input/%k" -KERNEL="raw[0-9]*", NAME="raw/%k" +KERNEL=="raw[0-9]*", NAME="raw/%k" -KERNEL="lp[0-9]*", SYMLINK="par%n" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" +KERNEL=="lp[0-9]*", SYMLINK="par%n" +BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" -KERNEL="microcode", SYMLINK="cpu/0/%k" -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=="microcode", NAME="cpu/%k" +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" +KERNEL=="tun", NAME="net/%k" -KERNEL="device-mapper", NAME="mapper/control" +KERNEL=="device-mapper", NAME="mapper/control" # old compat symlinks with enumeration -KERNEL="sr[0-9]*", SYMLINK="cdrom%e" -KERNEL="scd[0-9]*", SYMLINK="cdrom%e" -KERNEL="pcd[0-9]*", SYMLINK="cdrom%e" -KERNEL="fd[0-9]*", SYMLINK="floppy%e" -KERNEL="nst[0-9]*", SYMLINK="tape%e" +KERNEL=="sr[0-9]*", SYMLINK="cdrom%e" +KERNEL=="scd[0-9]*", SYMLINK="cdrom%e" +KERNEL=="pcd[0-9]*", SYMLINK="cdrom%e" +KERNEL=="fd[0-9]*", SYMLINK="floppy%e" +KERNEL=="nst[0-9]", SYMLINK="tape%e" +KERNEL=="nosst[0-9]*", SYMLINK="tape%e" -# default permissions for all block devices -SUBSYSTEM="block", GROUP="disk", MODE="0640" +# do not seperate the next 2 lines!! +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/ide-media.sh %k", RESULT=="floppy", SYMLINK="floppy%e", NAME{ignore_remove, all_partitions}="%k" -KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/ide-media.sh %k", RESULT="floppy", SYMLINK="floppy%e, NAME{ignore_remove, all_partitions}="%k", GROUP="floppy" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", RESULT=="cdrom", SYMLINK="cdrom%e" -KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", RESULT="cdrom", SYMLINK="cdrom%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" -KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" -KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" -KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" -KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" - -KERNEL="hd[a-z]", BUS="ide", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" -KERNEL="sr[0-9]*", BUS="scsi", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" # rename sr* to scd* -KERNEL="sr[0-9]*", BUS="scsi", NAME="scd%n" -KERNEL="hd[a-z]*", BUS="ide", SYSFS{removable}="1", NAME{ignore_remove}="%k" +KERNEL=="sr[0-9]*", BUS=="scsi", NAME="scd%n" +KERNEL=="hd[a-z]*", BUS=="ide", SYSFS{removable}=="1", NAME{ignore_remove}="%k" -KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" +KERNEL=="dvb*", PROGRAM=="/etc/udev/scripts/dvb.sh %k", NAME="%c" From 024780c2ed8efacb65cc8597b6cf79d54abbd735 Mon Sep 17 00:00:00 2001 From: "kay.sievers@vrfy.org" Date: Tue, 19 Apr 2005 00:07:01 +0200 Subject: [PATCH 1291/4284] [PATCH] selinux: fix handling during creation of symlinks Patch from: Dan Walsh --- udev_add.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev_add.c b/udev_add.c index b1e7265a3c..9764cb9bcd 100644 --- a/udev_add.c +++ b/udev_add.c @@ -221,7 +221,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de dbg("symlink(%s, %s)", linktarget, filename); if (!udev->test_run) { unlink(filename); - selinux_setfscreatecon(filename, udev->kernel_name, S_IFLNK); + selinux_setfscreatecon(filename, NULL, S_IFLNK); retval = symlink(linktarget, filename); selinux_resetfscreatecon(); if (retval != 0) From 27a71e49c208a10eed83d5b37dc89d20429ea714 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 5 May 2005 21:47:57 -0700 Subject: [PATCH 1292/4284] Added symlinks thanks to Kay's script and git hacking. Now the tests should work again... --- test/sys/block/cciss!c0d0/device | 1 + test/sys/block/rd!c0d0/device | 1 + test/sys/block/sda/device | 1 + test/sys/bus/pci/devices/0000:00:09.0 | 1 + test/sys/bus/pci/devices/0000:00:1e.0 | 1 + test/sys/bus/pci/devices/0000:02:05.0 | 1 + test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 | 1 + test/sys/bus/scsi/devices/0:0:0:0 | 1 + test/sys/bus/scsi/drivers/sd/0:0:0:0 | 1 + test/sys/bus/usb-serial/devices/ttyUSB0 | 1 + test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 | 1 + test/sys/bus/usb/devices/3-0:1.0 | 1 + test/sys/bus/usb/devices/3-1 | 1 + test/sys/bus/usb/devices/3-1:1.0 | 1 + test/sys/bus/usb/devices/usb3 | 1 + test/sys/bus/usb/drivers/hub/3-0:1.0 | 1 + test/sys/bus/usb/drivers/pl2303/3-1:1.0 | 1 + test/sys/bus/usb/drivers/usb/3-1 | 1 + test/sys/bus/usb/drivers/usb/usb3 | 1 + test/sys/class/tty/ttyUSB0/device | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver | 1 + 21 files changed, 21 insertions(+) create mode 120000 test/sys/block/cciss!c0d0/device create mode 120000 test/sys/block/rd!c0d0/device create mode 120000 test/sys/block/sda/device create mode 120000 test/sys/bus/pci/devices/0000:00:09.0 create mode 120000 test/sys/bus/pci/devices/0000:00:1e.0 create mode 120000 test/sys/bus/pci/devices/0000:02:05.0 create mode 120000 test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 create mode 120000 test/sys/bus/scsi/devices/0:0:0:0 create mode 120000 test/sys/bus/scsi/drivers/sd/0:0:0:0 create mode 120000 test/sys/bus/usb-serial/devices/ttyUSB0 create mode 120000 test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 create mode 120000 test/sys/bus/usb/devices/3-0:1.0 create mode 120000 test/sys/bus/usb/devices/3-1 create mode 120000 test/sys/bus/usb/devices/3-1:1.0 create mode 120000 test/sys/bus/usb/devices/usb3 create mode 120000 test/sys/bus/usb/drivers/hub/3-0:1.0 create mode 120000 test/sys/bus/usb/drivers/pl2303/3-1:1.0 create mode 120000 test/sys/bus/usb/drivers/usb/3-1 create mode 120000 test/sys/bus/usb/drivers/usb/usb3 create mode 120000 test/sys/class/tty/ttyUSB0/device create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver diff --git a/test/sys/block/cciss!c0d0/device b/test/sys/block/cciss!c0d0/device new file mode 120000 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/cciss!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/rd!c0d0/device b/test/sys/block/rd!c0d0/device new file mode 120000 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/rd!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/sda/device b/test/sys/block/sda/device new file mode 120000 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/sda/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:00:09.0 b/test/sys/bus/pci/devices/0000:00:09.0 new file mode 120000 index 0000000000..1c776568bd --- /dev/null +++ b/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/test/sys/bus/pci/devices/0000:00:1e.0 b/test/sys/bus/pci/devices/0000:00:1e.0 new file mode 120000 index 0000000000..e000c77614 --- /dev/null +++ b/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/test/sys/bus/pci/devices/0000:02:05.0 b/test/sys/bus/pci/devices/0000:02:05.0 new file mode 120000 index 0000000000..630d35bf61 --- /dev/null +++ b/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/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 b/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 new file mode 120000 index 0000000000..bd644e0e9d --- /dev/null +++ b/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/test/sys/bus/scsi/devices/0:0:0:0 b/test/sys/bus/scsi/devices/0:0:0:0 new file mode 120000 index 0000000000..ebb65b3bac --- /dev/null +++ b/test/sys/bus/scsi/devices/0:0:0:0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/scsi/drivers/sd/0:0:0:0 b/test/sys/bus/scsi/drivers/sd/0:0:0:0 new file mode 120000 index 0000000000..239003f712 --- /dev/null +++ b/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/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/usb-serial/devices/ttyUSB0 b/test/sys/bus/usb-serial/devices/ttyUSB0 new file mode 120000 index 0000000000..b7733a68e0 --- /dev/null +++ b/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/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 b/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 new file mode 120000 index 0000000000..177f109e48 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-0:1.0 b/test/sys/bus/usb/devices/3-0:1.0 new file mode 120000 index 0000000000..9137978832 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-1 b/test/sys/bus/usb/devices/3-1 new file mode 120000 index 0000000000..e47b4d58c4 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-1:1.0 b/test/sys/bus/usb/devices/3-1:1.0 new file mode 120000 index 0000000000..f519185eb3 --- /dev/null +++ b/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/test/sys/bus/usb/devices/usb3 b/test/sys/bus/usb/devices/usb3 new file mode 120000 index 0000000000..fb1919e7c9 --- /dev/null +++ b/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/test/sys/bus/usb/drivers/hub/3-0:1.0 b/test/sys/bus/usb/drivers/hub/3-0:1.0 new file mode 120000 index 0000000000..2bc160c20c --- /dev/null +++ b/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/test/sys/bus/usb/drivers/pl2303/3-1:1.0 b/test/sys/bus/usb/drivers/pl2303/3-1:1.0 new file mode 120000 index 0000000000..49d32d5abd --- /dev/null +++ b/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/test/sys/bus/usb/drivers/usb/3-1 b/test/sys/bus/usb/drivers/usb/3-1 new file mode 120000 index 0000000000..03c76193e9 --- /dev/null +++ b/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/test/sys/bus/usb/drivers/usb/usb3 b/test/sys/bus/usb/drivers/usb/usb3 new file mode 120000 index 0000000000..61dc52a613 --- /dev/null +++ b/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/test/sys/class/tty/ttyUSB0/device b/test/sys/class/tty/ttyUSB0/device new file mode 120000 index 0000000000..b7733a68e0 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver new file mode 120000 index 0000000000..9ff2c81f52 --- /dev/null +++ b/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 From 0ca6adfed9603e63bd42f9af9d1a73bd661a36da Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Mon, 9 May 2005 23:44:27 +0100 Subject: [PATCH 1293/4284] [PATCH] Writing udev rules docs update Here's a long overdue update to the udev rules docs, based on lots of user feedback from the last few months. Mostly updates to keep up with the new udev features, some clarifications and wording improvements. I added a section on rules for palm pilots due to the excessive amount of mail I get about them. I removed the nvidia stuff because it's out of date. Added another section about debugging using logs and udevtest. Removed the thanks list because I haven't been updating it and there are too many people to name now, sorry..! --- docs/writing_udev_rules/index.html | 153 ++++++++++-------- test/sys/block/cciss!c0d0/device | 0 test/sys/block/rd!c0d0/device | 0 test/sys/block/sda/device | 0 test/sys/bus/pci/devices/0000:00:09.0 | 0 test/sys/bus/pci/devices/0000:00:1e.0 | 0 test/sys/bus/pci/devices/0000:02:05.0 | 0 test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 | 0 test/sys/bus/scsi/devices/0:0:0:0 | 0 test/sys/bus/scsi/drivers/sd/0:0:0:0 | 0 test/sys/bus/usb-serial/devices/ttyUSB0 | 0 .../bus/usb-serial/drivers/PL-2303/ttyUSB0 | 0 test/sys/bus/usb/devices/3-0:1.0 | 0 test/sys/bus/usb/devices/3-1 | 0 test/sys/bus/usb/devices/3-1:1.0 | 0 test/sys/bus/usb/devices/usb3 | 0 test/sys/bus/usb/drivers/hub/3-0:1.0 | 0 test/sys/bus/usb/drivers/pl2303/3-1:1.0 | 0 test/sys/bus/usb/drivers/usb/3-1 | 0 test/sys/bus/usb/drivers/usb/usb3 | 0 test/sys/class/tty/ttyUSB0/device | 0 .../0000:00:09.0/usb3/3-1/ttyUSB0/driver | 0 22 files changed, 89 insertions(+), 64 deletions(-) mode change 120000 => 100644 test/sys/block/cciss!c0d0/device mode change 120000 => 100644 test/sys/block/rd!c0d0/device mode change 120000 => 100644 test/sys/block/sda/device mode change 120000 => 100644 test/sys/bus/pci/devices/0000:00:09.0 mode change 120000 => 100644 test/sys/bus/pci/devices/0000:00:1e.0 mode change 120000 => 100644 test/sys/bus/pci/devices/0000:02:05.0 mode change 120000 => 100644 test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 mode change 120000 => 100644 test/sys/bus/scsi/devices/0:0:0:0 mode change 120000 => 100644 test/sys/bus/scsi/drivers/sd/0:0:0:0 mode change 120000 => 100644 test/sys/bus/usb-serial/devices/ttyUSB0 mode change 120000 => 100644 test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 mode change 120000 => 100644 test/sys/bus/usb/devices/3-0:1.0 mode change 120000 => 100644 test/sys/bus/usb/devices/3-1 mode change 120000 => 100644 test/sys/bus/usb/devices/3-1:1.0 mode change 120000 => 100644 test/sys/bus/usb/devices/usb3 mode change 120000 => 100644 test/sys/bus/usb/drivers/hub/3-0:1.0 mode change 120000 => 100644 test/sys/bus/usb/drivers/pl2303/3-1:1.0 mode change 120000 => 100644 test/sys/bus/usb/drivers/usb/3-1 mode change 120000 => 100644 test/sys/bus/usb/drivers/usb/usb3 mode change 120000 => 100644 test/sys/class/tty/ttyUSB0/device mode change 120000 => 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver diff --git a/docs/writing_udev_rules/index.html b/docs/writing_udev_rules/index.html index 9396184366..1ba43678c0 100644 --- a/docs/writing_udev_rules/index.html +++ b/docs/writing_udev_rules/index.html @@ -8,7 +8,7 @@

    Writing udev rules

    by Daniel Drake (dsd)
    -Version 0.55

    +Version 0.6

    The most recent version of this document can always be found at:
    http://www.reactivated.net/udevrules.php @@ -27,6 +27,8 @@ The most recent version of this document can always be found at:
  • Key-writing basics
  • Identifying devices through basic keys
  • Identifying devices through SYSFS files
  • +
  • Using multiple SYMLINK style rules
  • +
  • Controlling ownership and permissions
  • Example: Writing a rule for my USB printer
  • Example: Writing a rule for my USB-Storage digital camera
  • @@ -34,8 +36,7 @@ The most recent version of this document can always be found at:
  • Example: Writing convenience rules for my CD drives
  • Example: Writing a rule to name my network interface
  • Tips for finding the appropriate places in SYSFS
  • -
  • Using multiple SYMLINK style rules
  • -
  • udev vs Nvidia's graphics drivers
  • +
  • Debugging your rules
  • Author and credits
  • @@ -53,6 +54,7 @@ This document assumes that you have udev/hotplug installed and running OK with d

    History

    +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.

    @@ -66,9 +68,8 @@ February 15th 2004 v0.1: Initial publication.

    Software versions used at time of writing

    -Linux Kernel 2.6.7
    -udev 027
    -hotplug 20040401

    +Linux Kernel 2.6.11
    +udev 056

    Terminology: devfs, sysfs, nodes, etc.

    @@ -97,6 +98,8 @@ However, if my HP laser printer got named lp_hp (as well as lpX) and my other pr For external mass-storage devices (e.g. usb hard disks), persistent naming is very helpful in that it allows you to hardcode accurate device paths into your /etc/fstab.

    +It is important to understand that writing rules is simply a means of customizing udev behaviour. Writing rules is not a workaround for the problem where no device nodes for your particular device exist. If no matching rules exist, udev will create the node anyway, using the name that was supplied by the kernel.

    +

    The basics of writing rules

    @@ -104,31 +107,32 @@ When populating /dev, udev decides which nodes to include, and how to nam 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, to reduce hassle while updating your udev installation in the future.

    -Files in /etc/udev/rules.d/ are parsed in lexical order. udev will stop processing rules as soon as it finds a matching rule in a file for the new item of hardware that has been detected. It is important that your own rules get processed before the udev defaults, otherwise your own naming schemes will not take effect! I suggest that you keep your own rules in a file at /etc/udev/rules.d/10-local.rules (this doesn't exist by default - create it). As 10 comes before 50, you know that your rules will be looked at first.

    +Files in /etc/udev/rules.d/ are parsed in lexical order. udev will stop processing rules as soon as it finds a matching rule in a file for the new item of hardware that has been detected. It is important that your own rules get processed before the udev defaults, otherwise your own naming schemes will not take effect! I suggest that you keep your own rules in a file at /etc/udev/rules.d/10-local.rules (this doesn't exist by default - create it). As 10 comes before 50, you know that your rules will be looked at first. It is important that the filenames of your rule files end with the .rules suffix, otherwise they will not be used.

    As your own rules will effectively mask out the udev defaults which create the base /dev layout, it is recommended that you also specify devfs-style names/symlinks for the rules you write, so that you get the sensible defaults plus your own names.

    In rule files, lines starting with a "#" are treated as comments. Every uncommented line in the file corresponds to a rule.

    -The basic form for a rule is: -
    key,[key,...] name [, symlink]
    +Rules are composed of keys. Keys are seperated by commas. Some keys are used for reading and matching information, others are used for assigning information and performing actions.
      -
    1. At least one key must be specified. Keys are used to identify which devices the rule matches.
    2. -
    3. The name parameter is required. It tells udev what that device should be named as in the /dev tree. It is written in the format NAME="X", where X is what the node will be named. You can specify multiple symlinks here, seperate them with a space.
    4. -
    5. The symlink parameter (optional) allows for you to specify additional places where this node will be linked.
    6. +
    7. At least one identification key should be provided, which will match the rule to any number of devices in the system. These are listed in the later section: Identifying devices through basic keys.
    8. +
    9. At least one assignment key should be provided, to control how the resultant device node is created. These include NAME, SYMLINK, OWNER, GROUP and MODE, all of which are described in this document.
    -Remember that udev will only create one node for one device. If you want it to be accessible through multiple nodes, then you have to specify the other nodes in the SYMLINK parameter.

    +Common rules will use basic identification keys to determine the device to name, and then have a NAME assignement key to define the device node name. udev will only create one node for one device, so if you want it to be accessible through multiple nodes, then you have to specify the other nodes in the SYMLINK assignment key.

    I'll take a slightly modified udev example rule to illustrate this:
    BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson", SYMLINK="printers/epson_stylus"
    -The keys here are the BUS and SYSFS{serial} parameters. udev will match this rule against a device that is connected through the USB bus and with a serial number of HXOLL0012202323480. Note that all (as opposed to any) specified keys must be matched for udev to use the rule to name a device.
    +The identification keys here are BUS and SYSFS{serial}. The assignment keys here are NAME and SYMLINK. udev will match this rule against a device that is connected through the USB bus and with a serial number of HXOLL0012202323480. Note that all (as opposed to any) specified keys must be matched for udev to use the rule to name a device.
    udev will name this node lp_epson, and it will be located at /dev/lp_epson.
    udev will also create a symlink to /dev/lp_epson, located at /dev/printers/epson_stylus (the printers directory will be automatically created). You can now print to your Epson printer by sending data to /dev/printers/epson_stylus or /dev/lp_epson.

    +Any rules that you have added or modified will not take effect until you notify udev of this. Make sure you remember to run the following every time you modify any rule files: +
    # udevstart
    +

    Additional automated customisation for NAME and SYMLINK parameters

    @@ -187,6 +191,8 @@ You may be wondering, "How do I find the serial number of my printer? What is th The valid keys are:
    • BUS - match the bus type of the device.
    • KERNEL - match the kernel device name.
    • +
    • DRIVER - match the name of the kernel driver.
    • +
    • SUBSYSTEM - match the kernel subsystem name.
    • ID - match the device number on the bus (e.g. PCI bus ID).
    • PLACE - match the physical position where the device is plugged into (useful for USB).
    • @@ -194,7 +200,7 @@ The valid keys are: The ID and PLACE keys do have their uses, but they are not commonly used in rules. This document focuses on using BUS and KERNEL keys, as well as SYSFS{...} keys (detailed in the next section). I will show how to use these keys by example.

      -For extra flexibility, udev also provides keys to call external scripts and examine their result. This is out of scope of this document. Look at the udev man page for more details. +For extra flexibility, udev also provides keys to call external scripts and examine their result, and to examine environment variables. This is out of scope of this document. Look at the udev man page for more details.

      Identifying devices through SYSFS files

      @@ -220,9 +226,11 @@ You may find that finding the correct place in /sys to run udevinfo on is /block/sda
    -The output of the command (shown above) is telling me that the sysfs path to start at is /sys/block/sda. I would now run "udevinfo -a -p /sys/block/sda". These two commands can be stringed together, like so: +The output of the command (shown above) is telling me that the sysfs path to start at is /sys/block/sda. I would now run "udevinfo -a -p /sys/block/sda". These two commands can be chained together, like so: -
    # udevinfo -a -p `udevinfo -q path -n /dev/sda`
    +
    # udevinfo -a -p $(udevinfo -q path -n /dev/sda)
    + +Sidenote: You may notice that we previously provided full paths (/sys/some/path) to udevinfo beforehand, but now we are providing sysfs-relative paths (/some/path) by chaining these commands. This does not matter - both types of path are accepted.

    Moving on to rule-writing, some snipped output of the results of my "udevinfo -a -p /sys/block/sda" command is shown below, with colour added.
    @@ -280,6 +288,43 @@ The behaviour of your own rules masking the defaults can be overcome if you writ
    + +

    Using multiple SYMLINK style rules

    +Another recent feature is the ability to write rules that do not specify a NAME, but instead they simply specify SYMLINK keys. This allows you to avoid the issue where your own rules effectively mask the udev defaults.

    + +Take the rule:
    +
    KERNEL="hdc", SYMLINK="dvd"
    + +When udev finds this rule, it will take a mental note of it. Upon finding another rule matching the same device which also includes a NAME parameter, udev will create the node as specified by the NAME parameter, plus symbolic links as specified by the SYMLINK parameters of both rules.
    +To put it into practical terms, when udev is naming nodes for my hdc device, it will use the default rules for block devices as usual, with the addition of my personal symlink "dvd".

    + +Similarly to normal rules, rules of this type will only take effect if udev is able to find them before it finds a rule specifying a NAME parameter.

    + + +

    Controlling ownership and permissions

    + +As well as controlling the naming of the device nodes which are created, udev rules also allow you to control ownership and permission attributes on that device node.

    + +The GROUP key allows you to define which unix group should own the device node. Here's an example from the udev defaults, which defines that the video group will own framebuffer (fb) 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 own 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"
    + +You'll notice in the above rule that we didn't specify any NAME or SYMLINK keys. This is similar to the multiple symlink style where udev will take a mental note that we want john to own floppy nodes, and will apply that ownership once it finds a rule which defines a NAME for the floppy device nodes.

    + +Building on the style mentioned above, you can do even more flashy things. The udev defaults use the following rule to define that all the sound device nodes shall be owned by the "audio" group: + +
    SUBSYSTEM="sound", GROUP="audio"
    + +This prevents the need to excessively provide a GROUP="audio" key on every following rule which names sound devices.

    + +udev defaults to creating nodes with unix permissions of 0660 (read/write to owner and group), which is configured by the default_mode setting inside /etc/udev/udev.conf. There may be some situations where you do not want to use the default permissions on your device node. Fortunately, you can easily override the permissions in your rules using the MODE assignment key. 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"
    +

    Example: Writing a rule for my USB printer

    @@ -368,9 +413,18 @@ BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n" You may have noticed that the default 50-udev.rules file contains a rule which runs a script to produces names for block devices. Do not be confused by this - as usual, because your own rules are located in a file which is processed before the default rules, the defaults will not be used when naming the hardware you have written rules for.

    + +

    Example: Writing a rule for your USB Visor Palm Pilot

    + +These devices work as USB-serial devices, so by default, you only get the ttyUSB1 node. The user-space palm utilities rely on /dev/pilot, so you need to use a rule to create this. The following rule will do the job:

    + +
    BUS="usb", SYSFS{product}="Palm Handheld", KERNEL="ttyUSB*", SYMLINK="pilot"
    + +This was adapted from Carsten Clasohm's blog entry, which includes a useful discussion of the situation. You may also wish to add ownership and permission keys to the rule to suit your setup.

    +

    Example: Writing a rule to name my network interface

    -An interesting new feature in recent udev versions is the ability to write rules to name your network interfaces. Network interfaces do not show up in /dev, but they are generally referenced by names (e.g. with ifconfig). Despite the differences, the rule writing process is almost identical.

    +An interesting new feature in recent udev versions is the ability to rename your network interfaces, like the nameif utility does. Network interfaces do not show up in /dev, but they are generally referenced by names (e.g. with ifconfig). Despite the differences, the rule writing process is almost identical.

    As usual, udevinfo comes to our aid in rule-writing. In my example, I wish to rename my "eth0" network device (the following output is snipped): @@ -380,7 +434,9 @@ As usual, udevinfo comes to our aid in rule-writing. In my example, I wish to re SYSFS{address}="00:52:8b:d5:04:48" -Every network adapter has its own unique MAC-address, so I chose to use this when writing my rule. This will not change, unless you change your network card. An example rule is shown below: +Every network adapter has its own unique MAC-address, so I chose to use this when writing my rule. This will not change, unless you change your network card. There is one caveat here: make sure you use the MAC address you obtain from udevinfo (as above), because it is case sensitive. Be careful when using utilities such as ifconfig as they will capitalize the letters.

    + +An example rule is shown below:
    KERNEL="eth*", SYSFS{address}="00:52:8b:d5:04:48", NAME="lan"
    @@ -403,62 +459,31 @@ After that, you should be able to use "lan" instead of "eth0" in any calls to Remember that unfortunately, the kernel does not export information for all devices into sysfs, meaning that you simply can't write rules for some devices yet. On 20/02/04, the udev author stated that there are 162 drivers left to convert to sysfs. - -

    Using multiple SYMLINK style rules

    -Another recent feature is the ability to write rules that do not specify a NAME, but instead they simply specify SYMLINK keys. This allows you to avoid the issue where your own rules effectively mask the udev defaults.

    + +

    Debugging your rules

    -Take the rule:
    -
    KERNEL="hdc", SYMLINK="dvd"
    +If you have written rules and remembered to run udevstart but they do not appear to be taking effect, there are a couple of ways you can debug them.

    -When udev finds this rule, it will take a mental note of it. Upon finding another rule matching the same device which also includes a NAME parameter, udev will create the node as specified by the NAME parameter, plus symbolic links as specified by the SYMLINK parameters of both rules.
    -To put it into practical terms, when udev is naming nodes for my hdc device, it will use the default rules for block devices as usual, with the addition of my personal symlink "dvd".

    +The file /etc/udev/udev.conf contains a udev_log option. Setting this option to yes will cause udev to log some useful information about which rules are being applied to which nodes into the system logger. The logs will be included in /var/log/messages for most users.

    -Similarly to normal rules, rules of this type will only take effect if udev is able to find them before it finds a rule specifying a NAME parameter.

    +Additionally, if you know the path in sysfs for the node you want to create, you can use udevtest to see a rundown on what udev would do with the node. For example: - -

    udev vs Nvidia's graphics drivers

    +
    # udevtest /sys/class/sound/dsp/
    +version 056
    +looking at '/class/sound/dsp/'
    +opened class_dev->name='dsp'
    +configured rule in '/etc/udev/rules.d/50-udev.rules[132]' applied, added symlink '%k'
    +configured rule in '/etc/udev/rules.d/50-udev.rules[132]' applied, 'dsp' becomes 'sound/%k'
    +creating device node '/dev/sound/dsp', major = '14', minor = '3', mode = '0660', uid = '0', gid = '18'
    -This section isn't really relevant to the purpose of this document, but judging from the hits I get from google, this is a hot topic. I will leave it here for now.

    - -Nvidia's graphics drivers (the closed-source ones, not the ones that come with XFree) do not work with a default installation of udev - you are unable to start X. This is because the nvidia module is loaded by X, but the /dev/nvidia* nodes are not created quick enough, so X bails out.

    - -The solution to this problem is to autoload the nvidia module on bootup. Yes - you are *supposed* to do this - the NVidia FAQ confirms this! On devfs-based systems, devfs did this automatically at bootup anyway. Your linux distribution will have created a file which you can list modules to be loaded on bootup (e.g. /etc/modules.autoload.d/kernel-2.6 for Gentoo, /etc/modules for Debian).

    - -This isn't all - you will also need to patch the nvidia kernel interface to export some basic info to SYSFS so that udev will create the devices. Martin Schlemmer has written a patch against the 1.0.5336 version of the nvidia drivers, which can be found here. The Gentoo package nvidia-kernel-1.0.5336-r4 contains this patch.

    - -Another solution is to simply create the nvidia specific nodes on bootup. X will then load the module when required, and as the nodes are already in existance, you will not run into the problem described above. Place these commands in a file that is automatically executed on bootup (e.g. /etc/conf.d/local.start for Gentoo): -
    -mknod /dev/nvidia0 c 195 0
    -mknod /dev/nvidiactl c 195 255
    -
    - -You should now be able to get into X with no problems.

    +udevtest is only a debugging/testing tool - it does not actually create the device node, even though it says it doing so!

    Author and Credits

    This document is written by Daniel Drake <dan@reactivated.net>
    Please do not hesitate to send feedback!

    -Additional thanks to: -
      -
    • The udev developers!
    • -
    • agrippa_cash (usb-storage info)
    • -
    • Carl Streeter (usb-storage info)
    • -
    • David Watson
    • -
    • Decibels
    • -
    • Frank Pieczynski
    • -
    • Feth Arezki
    • -
    • Jim (KDE info)
    • -
    • Johannes Jordens
    • -
    • Kay Sievers
    • -
    • Patrick Dreker
    • -
    • Todd Musall
    • -
    • Tuna
    • -
    • Ueli Schläpfer
    • -
    • ...and anyone else who provided information or feedback
    • -
    - -

    Copyright (C) 2003-2004 Daniel Drake
    +Copyright (C) 2003-2005 Daniel Drake
    This document is licensed under the GNU General Public License, Version 2. diff --git a/test/sys/block/cciss!c0d0/device b/test/sys/block/cciss!c0d0/device deleted file mode 120000 index 2d78258b1a..0000000000 --- a/test/sys/block/cciss!c0d0/device +++ /dev/null @@ -1 +0,0 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/cciss!c0d0/device b/test/sys/block/cciss!c0d0/device new file mode 100644 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/cciss!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/rd!c0d0/device b/test/sys/block/rd!c0d0/device deleted file mode 120000 index 2d78258b1a..0000000000 --- a/test/sys/block/rd!c0d0/device +++ /dev/null @@ -1 +0,0 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/rd!c0d0/device b/test/sys/block/rd!c0d0/device new file mode 100644 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/rd!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/sda/device b/test/sys/block/sda/device deleted file mode 120000 index 2d78258b1a..0000000000 --- a/test/sys/block/sda/device +++ /dev/null @@ -1 +0,0 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/sda/device b/test/sys/block/sda/device new file mode 100644 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/sda/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:00:09.0 b/test/sys/bus/pci/devices/0000:00:09.0 deleted file mode 120000 index 1c776568bd..0000000000 --- a/test/sys/bus/pci/devices/0000:00:09.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:00:09.0 b/test/sys/bus/pci/devices/0000:00:09.0 new file mode 100644 index 0000000000..1c776568bd --- /dev/null +++ b/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/test/sys/bus/pci/devices/0000:00:1e.0 b/test/sys/bus/pci/devices/0000:00:1e.0 deleted file mode 120000 index e000c77614..0000000000 --- a/test/sys/bus/pci/devices/0000:00:1e.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:1e.0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:00:1e.0 b/test/sys/bus/pci/devices/0000:00:1e.0 new file mode 100644 index 0000000000..e000c77614 --- /dev/null +++ b/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/test/sys/bus/pci/devices/0000:02:05.0 b/test/sys/bus/pci/devices/0000:02:05.0 deleted file mode 120000 index 630d35bf61..0000000000 --- a/test/sys/bus/pci/devices/0000:02:05.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:02:05.0 b/test/sys/bus/pci/devices/0000:02:05.0 new file mode 100644 index 0000000000..630d35bf61 --- /dev/null +++ b/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/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 b/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 deleted file mode 120000 index bd644e0e9d..0000000000 --- a/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0 \ No newline at end of file diff --git a/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 b/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 new file mode 100644 index 0000000000..bd644e0e9d --- /dev/null +++ b/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/test/sys/bus/scsi/devices/0:0:0:0 b/test/sys/bus/scsi/devices/0:0:0:0 deleted file mode 120000 index ebb65b3bac..0000000000 --- a/test/sys/bus/scsi/devices/0:0:0:0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/scsi/devices/0:0:0:0 b/test/sys/bus/scsi/devices/0:0:0:0 new file mode 100644 index 0000000000..ebb65b3bac --- /dev/null +++ b/test/sys/bus/scsi/devices/0:0:0:0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/scsi/drivers/sd/0:0:0:0 b/test/sys/bus/scsi/drivers/sd/0:0:0:0 deleted file mode 120000 index 239003f712..0000000000 --- a/test/sys/bus/scsi/drivers/sd/0:0:0:0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/scsi/drivers/sd/0:0:0:0 b/test/sys/bus/scsi/drivers/sd/0:0:0:0 new file mode 100644 index 0000000000..239003f712 --- /dev/null +++ b/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/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/usb-serial/devices/ttyUSB0 b/test/sys/bus/usb-serial/devices/ttyUSB0 deleted file mode 120000 index b7733a68e0..0000000000 --- a/test/sys/bus/usb-serial/devices/ttyUSB0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/test/sys/bus/usb-serial/devices/ttyUSB0 b/test/sys/bus/usb-serial/devices/ttyUSB0 new file mode 100644 index 0000000000..b7733a68e0 --- /dev/null +++ b/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/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 b/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 deleted file mode 120000 index 177f109e48..0000000000 --- a/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 b/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 new file mode 100644 index 0000000000..177f109e48 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-0:1.0 b/test/sys/bus/usb/devices/3-0:1.0 deleted file mode 120000 index 9137978832..0000000000 --- a/test/sys/bus/usb/devices/3-0:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/3-0:1.0 b/test/sys/bus/usb/devices/3-0:1.0 new file mode 100644 index 0000000000..9137978832 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-1 b/test/sys/bus/usb/devices/3-1 deleted file mode 120000 index e47b4d58c4..0000000000 --- a/test/sys/bus/usb/devices/3-1 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/3-1 b/test/sys/bus/usb/devices/3-1 new file mode 100644 index 0000000000..e47b4d58c4 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-1:1.0 b/test/sys/bus/usb/devices/3-1:1.0 deleted file mode 120000 index f519185eb3..0000000000 --- a/test/sys/bus/usb/devices/3-1:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/3-1:1.0 b/test/sys/bus/usb/devices/3-1:1.0 new file mode 100644 index 0000000000..f519185eb3 --- /dev/null +++ b/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/test/sys/bus/usb/devices/usb3 b/test/sys/bus/usb/devices/usb3 deleted file mode 120000 index fb1919e7c9..0000000000 --- a/test/sys/bus/usb/devices/usb3 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/usb3 b/test/sys/bus/usb/devices/usb3 new file mode 100644 index 0000000000..fb1919e7c9 --- /dev/null +++ b/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/test/sys/bus/usb/drivers/hub/3-0:1.0 b/test/sys/bus/usb/drivers/hub/3-0:1.0 deleted file mode 120000 index 2bc160c20c..0000000000 --- a/test/sys/bus/usb/drivers/hub/3-0:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/hub/3-0:1.0 b/test/sys/bus/usb/drivers/hub/3-0:1.0 new file mode 100644 index 0000000000..2bc160c20c --- /dev/null +++ b/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/test/sys/bus/usb/drivers/pl2303/3-1:1.0 b/test/sys/bus/usb/drivers/pl2303/3-1:1.0 deleted file mode 120000 index 49d32d5abd..0000000000 --- a/test/sys/bus/usb/drivers/pl2303/3-1:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/pl2303/3-1:1.0 b/test/sys/bus/usb/drivers/pl2303/3-1:1.0 new file mode 100644 index 0000000000..49d32d5abd --- /dev/null +++ b/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/test/sys/bus/usb/drivers/usb/3-1 b/test/sys/bus/usb/drivers/usb/3-1 deleted file mode 120000 index 03c76193e9..0000000000 --- a/test/sys/bus/usb/drivers/usb/3-1 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/usb/3-1 b/test/sys/bus/usb/drivers/usb/3-1 new file mode 100644 index 0000000000..03c76193e9 --- /dev/null +++ b/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/test/sys/bus/usb/drivers/usb/usb3 b/test/sys/bus/usb/drivers/usb/usb3 deleted file mode 120000 index 61dc52a613..0000000000 --- a/test/sys/bus/usb/drivers/usb/usb3 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/usb/usb3 b/test/sys/bus/usb/drivers/usb/usb3 new file mode 100644 index 0000000000..61dc52a613 --- /dev/null +++ b/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/test/sys/class/tty/ttyUSB0/device b/test/sys/class/tty/ttyUSB0/device deleted file mode 120000 index b7733a68e0..0000000000 --- a/test/sys/class/tty/ttyUSB0/device +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/test/sys/class/tty/ttyUSB0/device b/test/sys/class/tty/ttyUSB0/device new file mode 100644 index 0000000000..b7733a68e0 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver deleted file mode 120000 index 9ff2c81f52..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver +++ /dev/null @@ -1 +0,0 @@ -../../../../../../bus/usb-serial/drivers/PL-2303 \ No newline at end of file diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver new file mode 100644 index 0000000000..9ff2c81f52 --- /dev/null +++ b/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 From 17f2b1a7e0d10334af7f9622848788add125dea8 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 10 May 2005 10:09:29 -0700 Subject: [PATCH 1294/4284] Removed klibc/klibc.spec as it is autogenerated --- klibc/klibc.spec | 102 ----------------------------------------------- 1 file changed, 102 deletions(-) delete mode 100644 klibc/klibc.spec diff --git a/klibc/klibc.spec b/klibc/klibc.spec deleted file mode 100644 index 65b0bf5439..0000000000 --- a/klibc/klibc.spec +++ /dev/null @@ -1,102 +0,0 @@ -Summary: A minimal libc subset for use with initramfs. -Name: klibc -Version: 0.205 -Release: 1 -License: BSD/GPL -Group: Development/Libraries -URL: http://www.zytor.com/mailman/listinfo/klibc -Source: http://www.kernel.org/pub/linux/libs/klibc-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -BuildRequires: kernel >= 2.6.0 -Packager: H. Peter Anvin -Prefix: /usr -Vendor: Starving Linux Artists - -%define klibcdir %{_prefix}/lib/klibc -%define libdocdir %{_docdir}/%{name}-%{version}-%{release} -%define bindocdir %{_docdir}/%{name}-utils-%{version}-%{release} - -%description -%{name} is intended to be a minimalistic libc subset for use with -initramfs. It is deliberately written for small size, minimal -entanglement, and portability, not speed. It is definitely a work in -progress, and a lot of things are still missing. - -%package utils -Summary: Small utilities built with klibc. -Group: Utilities/System -Requires: klibc = %{version} - -%description utils -This package contains a collection of programs that are linked against -klibc. These duplicate some of the functionality of a regular Linux -toolset, but are typically much smaller than their full-function -counterparts. They are intended for inclusion in initramfs images and -embedded systems. - -%prep -%setup -q -cp -dRs /lib/modules/`uname -r`/build ./linux -# Shouldn't need this when getting the build tree from /lib/modules -# make -C linux defconfig ARCH=%{_target_cpu} -# make -C linux prepare ARCH=%{_target_cpu} -# Deal with braindamage in RedHat's kernel-source RPM -rm -f linux/include/linux/config.h -cat < linux/include/linux/config.h -#ifndef _LINUX_CONFIG_H -#define _LINUX_CONFIG_H - -#include - -#endif -EOF -mkdir -p %{buildroot} - -%build -make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ - INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} - -%install -rm -rf %{buildroot} -make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ - INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} \ - install - -# Install the docs - -mkdir -p %{buildroot}%{bindocdir} %{buildroot}%{libdocdir} -install -m 444 README %{buildroot}%{libdocdir} -install -m 444 klibc/README %{buildroot}%{libdocdir}/README.klibc -install -m 444 klibc/arch/README %{buildroot}%{libdocdir}/README.klibc.arch - -install -m 444 gzip/COPYING %{buildroot}%{bindocdir}/COPYING.gzip -install -m 444 gzip/README %{buildroot}%{bindocdir}/README.gzip -install -m 444 ipconfig/README %{buildroot}%{bindocdir}/README.ipconfig -install -m 444 kinit/README %{buildroot}%{bindocdir}/README.kinit - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -%defattr(-,root,root,-) -%{klibcdir}/lib -%{klibcdir}/include -%{_bindir}/klcc -/lib/klibc-*.so -%doc %{_mandir}/man1/* -%doc %{libdocdir}/* - -%files utils -%defattr(-,root,root,-) -%{klibcdir}/bin -%doc %{bindocdir}/* - -%changelog -* Tue Mar 1 2005 H. Peter Anvin -- New "make install" scheme, klcc - -* Tue Jul 6 2004 H. Peter Anvin -- Update to use kernel-source RPM for the kernel symlink. - -* Sat Nov 29 2003 Bryan O'Sullivan - -- Initial build. From 49cedafaf893bfe348eb7598227f1a11ae24bfd6 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 10 May 2005 10:11:15 -0700 Subject: [PATCH 1295/4284] hopefully fix up the symlinks in the test directory Thanks to Kay for pointing this out. Signed-off-by: Greg Kroah-Hartman --- test/sys/block/cciss!c0d0/device | 0 test/sys/block/rd!c0d0/device | 0 test/sys/block/sda/device | 0 test/sys/bus/pci/devices/0000:00:09.0 | 0 test/sys/bus/pci/devices/0000:00:1e.0 | 0 test/sys/bus/pci/devices/0000:02:05.0 | 0 test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 | 0 test/sys/bus/scsi/devices/0:0:0:0 | 0 test/sys/bus/scsi/drivers/sd/0:0:0:0 | 0 test/sys/bus/usb-serial/devices/ttyUSB0 | 0 test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 | 0 test/sys/bus/usb/devices/3-0:1.0 | 0 test/sys/bus/usb/devices/3-1 | 0 test/sys/bus/usb/devices/3-1:1.0 | 0 test/sys/bus/usb/devices/usb3 | 0 test/sys/bus/usb/drivers/hub/3-0:1.0 | 0 test/sys/bus/usb/drivers/pl2303/3-1:1.0 | 0 test/sys/bus/usb/drivers/usb/3-1 | 0 test/sys/bus/usb/drivers/usb/usb3 | 0 test/sys/class/tty/ttyUSB0/device | 0 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver | 0 21 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 120000 test/sys/block/cciss!c0d0/device mode change 100644 => 120000 test/sys/block/rd!c0d0/device mode change 100644 => 120000 test/sys/block/sda/device mode change 100644 => 120000 test/sys/bus/pci/devices/0000:00:09.0 mode change 100644 => 120000 test/sys/bus/pci/devices/0000:00:1e.0 mode change 100644 => 120000 test/sys/bus/pci/devices/0000:02:05.0 mode change 100644 => 120000 test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 mode change 100644 => 120000 test/sys/bus/scsi/devices/0:0:0:0 mode change 100644 => 120000 test/sys/bus/scsi/drivers/sd/0:0:0:0 mode change 100644 => 120000 test/sys/bus/usb-serial/devices/ttyUSB0 mode change 100644 => 120000 test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 mode change 100644 => 120000 test/sys/bus/usb/devices/3-0:1.0 mode change 100644 => 120000 test/sys/bus/usb/devices/3-1 mode change 100644 => 120000 test/sys/bus/usb/devices/3-1:1.0 mode change 100644 => 120000 test/sys/bus/usb/devices/usb3 mode change 100644 => 120000 test/sys/bus/usb/drivers/hub/3-0:1.0 mode change 100644 => 120000 test/sys/bus/usb/drivers/pl2303/3-1:1.0 mode change 100644 => 120000 test/sys/bus/usb/drivers/usb/3-1 mode change 100644 => 120000 test/sys/bus/usb/drivers/usb/usb3 mode change 100644 => 120000 test/sys/class/tty/ttyUSB0/device mode change 100644 => 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver diff --git a/test/sys/block/cciss!c0d0/device b/test/sys/block/cciss!c0d0/device deleted file mode 100644 index 2d78258b1a..0000000000 --- a/test/sys/block/cciss!c0d0/device +++ /dev/null @@ -1 +0,0 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/cciss!c0d0/device b/test/sys/block/cciss!c0d0/device new file mode 120000 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/cciss!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/rd!c0d0/device b/test/sys/block/rd!c0d0/device deleted file mode 100644 index 2d78258b1a..0000000000 --- a/test/sys/block/rd!c0d0/device +++ /dev/null @@ -1 +0,0 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/rd!c0d0/device b/test/sys/block/rd!c0d0/device new file mode 120000 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/rd!c0d0/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/sda/device b/test/sys/block/sda/device deleted file mode 100644 index 2d78258b1a..0000000000 --- a/test/sys/block/sda/device +++ /dev/null @@ -1 +0,0 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/block/sda/device b/test/sys/block/sda/device new file mode 120000 index 0000000000..2d78258b1a --- /dev/null +++ b/test/sys/block/sda/device @@ -0,0 +1 @@ +../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:00:09.0 b/test/sys/bus/pci/devices/0000:00:09.0 deleted file mode 100644 index 1c776568bd..0000000000 --- a/test/sys/bus/pci/devices/0000:00:09.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:00:09.0 b/test/sys/bus/pci/devices/0000:00:09.0 new file mode 120000 index 0000000000..1c776568bd --- /dev/null +++ b/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/test/sys/bus/pci/devices/0000:00:1e.0 b/test/sys/bus/pci/devices/0000:00:1e.0 deleted file mode 100644 index e000c77614..0000000000 --- a/test/sys/bus/pci/devices/0000:00:1e.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:1e.0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:00:1e.0 b/test/sys/bus/pci/devices/0000:00:1e.0 new file mode 120000 index 0000000000..e000c77614 --- /dev/null +++ b/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/test/sys/bus/pci/devices/0000:02:05.0 b/test/sys/bus/pci/devices/0000:02:05.0 deleted file mode 100644 index 630d35bf61..0000000000 --- a/test/sys/bus/pci/devices/0000:02:05.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0 \ No newline at end of file diff --git a/test/sys/bus/pci/devices/0000:02:05.0 b/test/sys/bus/pci/devices/0000:02:05.0 new file mode 120000 index 0000000000..630d35bf61 --- /dev/null +++ b/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/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 b/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 deleted file mode 100644 index bd644e0e9d..0000000000 --- a/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0 \ No newline at end of file diff --git a/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 b/test/sys/bus/pci/drivers/aic7xxx/0000:02:05.0 new file mode 120000 index 0000000000..bd644e0e9d --- /dev/null +++ b/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/test/sys/bus/scsi/devices/0:0:0:0 b/test/sys/bus/scsi/devices/0:0:0:0 deleted file mode 100644 index ebb65b3bac..0000000000 --- a/test/sys/bus/scsi/devices/0:0:0:0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/scsi/devices/0:0:0:0 b/test/sys/bus/scsi/devices/0:0:0:0 new file mode 120000 index 0000000000..ebb65b3bac --- /dev/null +++ b/test/sys/bus/scsi/devices/0:0:0:0 @@ -0,0 +1 @@ +../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/scsi/drivers/sd/0:0:0:0 b/test/sys/bus/scsi/drivers/sd/0:0:0:0 deleted file mode 100644 index 239003f712..0000000000 --- a/test/sys/bus/scsi/drivers/sd/0:0:0:0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/scsi/drivers/sd/0:0:0:0 b/test/sys/bus/scsi/drivers/sd/0:0:0:0 new file mode 120000 index 0000000000..239003f712 --- /dev/null +++ b/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/0:0:0:0 \ No newline at end of file diff --git a/test/sys/bus/usb-serial/devices/ttyUSB0 b/test/sys/bus/usb-serial/devices/ttyUSB0 deleted file mode 100644 index b7733a68e0..0000000000 --- a/test/sys/bus/usb-serial/devices/ttyUSB0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/test/sys/bus/usb-serial/devices/ttyUSB0 b/test/sys/bus/usb-serial/devices/ttyUSB0 new file mode 120000 index 0000000000..b7733a68e0 --- /dev/null +++ b/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/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 b/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 deleted file mode 100644 index 177f109e48..0000000000 --- a/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 b/test/sys/bus/usb-serial/drivers/PL-2303/ttyUSB0 new file mode 120000 index 0000000000..177f109e48 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-0:1.0 b/test/sys/bus/usb/devices/3-0:1.0 deleted file mode 100644 index 9137978832..0000000000 --- a/test/sys/bus/usb/devices/3-0:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/3-0:1.0 b/test/sys/bus/usb/devices/3-0:1.0 new file mode 120000 index 0000000000..9137978832 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-1 b/test/sys/bus/usb/devices/3-1 deleted file mode 100644 index e47b4d58c4..0000000000 --- a/test/sys/bus/usb/devices/3-1 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/3-1 b/test/sys/bus/usb/devices/3-1 new file mode 120000 index 0000000000..e47b4d58c4 --- /dev/null +++ b/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/test/sys/bus/usb/devices/3-1:1.0 b/test/sys/bus/usb/devices/3-1:1.0 deleted file mode 100644 index f519185eb3..0000000000 --- a/test/sys/bus/usb/devices/3-1:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/3-1:1.0 b/test/sys/bus/usb/devices/3-1:1.0 new file mode 120000 index 0000000000..f519185eb3 --- /dev/null +++ b/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/test/sys/bus/usb/devices/usb3 b/test/sys/bus/usb/devices/usb3 deleted file mode 100644 index fb1919e7c9..0000000000 --- a/test/sys/bus/usb/devices/usb3 +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3 \ No newline at end of file diff --git a/test/sys/bus/usb/devices/usb3 b/test/sys/bus/usb/devices/usb3 new file mode 120000 index 0000000000..fb1919e7c9 --- /dev/null +++ b/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/test/sys/bus/usb/drivers/hub/3-0:1.0 b/test/sys/bus/usb/drivers/hub/3-0:1.0 deleted file mode 100644 index 2bc160c20c..0000000000 --- a/test/sys/bus/usb/drivers/hub/3-0:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/hub/3-0:1.0 b/test/sys/bus/usb/drivers/hub/3-0:1.0 new file mode 120000 index 0000000000..2bc160c20c --- /dev/null +++ b/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/test/sys/bus/usb/drivers/pl2303/3-1:1.0 b/test/sys/bus/usb/drivers/pl2303/3-1:1.0 deleted file mode 100644 index 49d32d5abd..0000000000 --- a/test/sys/bus/usb/drivers/pl2303/3-1:1.0 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/pl2303/3-1:1.0 b/test/sys/bus/usb/drivers/pl2303/3-1:1.0 new file mode 120000 index 0000000000..49d32d5abd --- /dev/null +++ b/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/test/sys/bus/usb/drivers/usb/3-1 b/test/sys/bus/usb/drivers/usb/3-1 deleted file mode 100644 index 03c76193e9..0000000000 --- a/test/sys/bus/usb/drivers/usb/3-1 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3/3-1 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/usb/3-1 b/test/sys/bus/usb/drivers/usb/3-1 new file mode 120000 index 0000000000..03c76193e9 --- /dev/null +++ b/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/test/sys/bus/usb/drivers/usb/usb3 b/test/sys/bus/usb/drivers/usb/usb3 deleted file mode 100644 index 61dc52a613..0000000000 --- a/test/sys/bus/usb/drivers/usb/usb3 +++ /dev/null @@ -1 +0,0 @@ -../../../../devices/pci0000:00/0000:00:09.0/usb3 \ No newline at end of file diff --git a/test/sys/bus/usb/drivers/usb/usb3 b/test/sys/bus/usb/drivers/usb/usb3 new file mode 120000 index 0000000000..61dc52a613 --- /dev/null +++ b/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/test/sys/class/tty/ttyUSB0/device b/test/sys/class/tty/ttyUSB0/device deleted file mode 100644 index b7733a68e0..0000000000 --- a/test/sys/class/tty/ttyUSB0/device +++ /dev/null @@ -1 +0,0 @@ -../../../devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0 \ No newline at end of file diff --git a/test/sys/class/tty/ttyUSB0/device b/test/sys/class/tty/ttyUSB0/device new file mode 120000 index 0000000000..b7733a68e0 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver deleted file mode 100644 index 9ff2c81f52..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver +++ /dev/null @@ -1 +0,0 @@ -../../../../../../bus/usb-serial/drivers/PL-2303 \ No newline at end of file diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/driver new file mode 120000 index 0000000000..9ff2c81f52 --- /dev/null +++ b/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 From 1e50c2dee7401055a0e76c116de939f0893e7429 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 10 May 2005 10:22:56 -0700 Subject: [PATCH 1296/4284] Update permissions on test scripts so they will run properly now. Signed-off-by: Greg Kroah-Hartman --- test/udev-test.pl | 0 test/udevstart-test.pl | 0 2 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 test/udev-test.pl mode change 100644 => 100755 test/udevstart-test.pl diff --git a/test/udev-test.pl b/test/udev-test.pl old mode 100644 new mode 100755 diff --git a/test/udevstart-test.pl b/test/udevstart-test.pl old mode 100644 new mode 100755 From 60f44733522cca3a619db598e4c83b8e8d0750b6 Mon Sep 17 00:00:00 2001 From: Date: Mon, 16 May 2005 12:26:41 -0700 Subject: [PATCH 1297/4284] added translated (jp) version of writing udev rules file. From Masanao Igarashi --- docs/writing_udev_rules/index.jp.html | 598 ++++++++++++++++++++++++++ 1 file changed, 598 insertions(+) create mode 100644 docs/writing_udev_rules/index.jp.html diff --git a/docs/writing_udev_rules/index.jp.html b/docs/writing_udev_rules/index.jp.html new file mode 100644 index 0000000000..e94eae8a46 --- /dev/null +++ b/docs/writing_udev_rules/index.jp.html @@ -0,0 +1,598 @@ +udevルールの書き方 + + + + + +

    udevルールの書き方

    +Daniel Drake (dsd) 著
    +バージョン 0.6

    + +この文書の最新バージョンは、常に以下のサイトにあります。
    +http://www.reactivated.net/udevrules.php(英語オリジナルサイト)
    +http://www.gentoo.gr.jp/transdocs/udevrules/udevrules.html(日本語翻訳版)

    + +日本語翻訳版は、著者に許可を得て、五十嵐 正尚(igarashi@gentoo.gr.jp)が翻訳し、GentooJPで公開しているものです。翻訳版に関することは訳者に連絡してください。
    +日本語翻訳版 最終更新日 2005-05-16 + +

    内容

    +
      +
    1. この文書について
    2. +
    3. 更新履歴
    4. +
    5. 執筆時に使用したソフトウェアのバージョン
    6. +
    7. 用語紹介: devfs、sysfs、ノードなど
    8. + +
    9. なぜルールを書く必要がありますか? (この文書の目的)
    10. +
    11. ルールを書く上での基本事項
    12. +
    13. NAMEとSYMLINKパラメータでの設定自動化のための付加機能
    14. +
    15. キーでのシェル形式パターン照合の使い方
    16. +
    17. キーを書く上での基本事項
    18. +
    19. 基本キーによるデバイス識別方法
    20. +
    21. SYSFSファイルによるデバイス識別方法
    22. +
    23. 複数SYMLINK形式の使い方
    24. +
    25. 所有権とパーミッション制御
    26. +
    27. 例: 著者所有のUSBプリンタ向けのルールの書き方
    28. +
    29. 例: USBストレージ方式対応デジカメ向けのルールの書き方
    30. + +
    31. USBストレージ向けルールの書き方に関する追記
    32. +
    33. 例: 著者所有のCDドライブに便利なルールの書き方
    34. +
    35. 例: 著者所有のネットワークインターフェースに名前を付けるルールの書き方
    36. +
    37. SYSFS内におけるudevinfoを実行すべき場所を探し出すコツ
    38. +
    39. ルールのデバッグ方法
    40. +
    41. 著者と謝辞
    42. +
    + + +

    この文書について

    +udevはLinuxカーネル2.6以降を対象とし、デバイス名を固定する機能を備え、動的な/devディレクトリをユーザスペースで実現する方法を提供します。 +これまでの/devの実装であるdevfsは、現在後方互換のためだけに残されており、udevはその後任と考えられています。 +udevとdevfsではどちらが良いかということは、慎重に議論されるべき問題です。 +ご自分で比較する前に、まずこの文書を読むべきです。

    +udevはよく考え抜かれていますが、私は最初、自分のシステムではどのように調整すればよいのかとても戸惑いました。この文書では、ルールを書く手順がもう少し明確になることを目指しています。

    + +いつでも意見や感想をお待ちしております。どんな意見、問題、改善案でも連絡先にお願いします。

    +この文書は、udev/hotplugをインストール済みであり、初期設定で問題なく動作していることを想定しています。まだudevを設定しておらず、動作していないなら、Decibels udev Primer(日本語訳)に従ってその作業を行うことをお勧めします(少しGentoo Linux固有のことが含まれていますが、他のディストリビューションにも有用なはずです)。

    + + + +

    更新履歴

    + +2005年5月9日 v0.6: udevinfo、グループとパーミッション、ログ取り、udevtestに関する情報を含む様々な更新。

    +2004年6月20日 v0.55: 複数シンボリックリンク形式に関する情報を追加。細かい変更/更新。

    +2004年4月26日 v0.54: Debian情報を追加。細かい修正。 +ルールファイルをなんと呼ぶべきかに関しての情報を過去ものに戻した。 +ネットワークインターフェースの名前付けに関する情報を追加。

    +2004年4月15日 v0.53: 細かい修正。NAME{all_partitions}に関する情報を追加。udevinfoを使用する際のコツに関する別の情報を追加。

    +2004年4月14日 v0.52: udevの初期設定が他のファイルを考慮するようになるまで、udev.rulesの使用を推奨するように戻した。細かい作業。

    +2004年4月6日 v0.51: udev.rulesの先頭に追加するより、各自のlocal.rulesファイルの使用を推奨するように書いた。

    +2004年4月3日 v0.5: ちょっとした整理とudev配布物に含まれる可能性があるため、その準備。

    +2004年3月20日 v0.4: 全体的に改良、明確化、および整理。USBストレージ向けのルールの書き方に関する情報をさらに追加。

    +2004年2月23日 v0.3: sysfsの名前付け動作方法とそれにどのように一致させるかを強調するために、いろんな部分を書き直し。 +udev 018の新しいSYSFS{filename}名前付け規則を説明するルールの書き方を更新。 +セクションの体裁を改良と、いろんな箇所をわかりやすくした。KDEに関する情報を追加。

    +2004年2月18日 v0.2: 例の中のちょっとした間違いを修正。 +マスストレージデバイスの識別に関するセクションを更新。nvidiaのセクションを更新

    +2004年2月15日 v0.1: 最初の公開。

    + + +

    執筆時に使用したソフトウェアのバージョン

    +Linuxカーネル 2.6.11
    +udev 056

    + + +

    用語紹介: devfs、sysfs、ノードなど

    +基本的な紹介だけです。完全に正確ではないかもしれません。

    + +標準的なlinuxを基本とするシステムでは、/devディレクトリは、ファイルに似たデバイスノードを保持するために使用されます。 +デバイスノードは、システムに含まれる特定のデバイスに対応します。 +各ノードは、システム構成の一部(デバイス)を指します。デバイスは、実際に存在するかもしれないし、存在しないかもしれません。 +ユーザスペースで動作するアプリケーションは、システムハードウェアとやり取りをするためにこれらのデバイスノードを使用できます。例えば、ユーザが行うマウス動作を、画面上のマウスポインタの動きに結びつけるために、XFree86は/dev/input/miceを監視します。

    + +もともとの/devディレクトリは、システムに組み込まれる可能性のある全てのデバイスが配置されていました。 +そんなわけで/devディレクトリは、一般的にとても大きくなっていました。 +devfsは、もろもろの機能に加え、より扱いやすい手法(特に目を引くのは、システムに接続されたハードウェアだけが/devに配置されたことでした)を提供するために登場しました。 +しかし、devfsには簡単に解決することができない問題があることが判明しました。

    + +udevは、/devディレクトリを管理する新しい手法です。 +過去の/dev実装にある問題を解決するように設計され、将来にわたって破綻しないものを提供します。 +udevは、ユーザが指定するルールとsysfsによって提供される情報を照合して、システムに組み込まれたデバイスに相当する/devデバイスノードを作成し命名します。 +ルールを書く工程は、ユーザが(選択的に)行う必要がある数少ないudevに関係する作業のうちの一つです。 +この文書は、そのルールを書く工程を詳しく説明することが目的です。

    + +sysfsは、2.6カーネル向けの新しいファイルシステムです。 +sysfsはカーネルによって管理され、システムに接続されているデバイスに関する基本情報をユーザスペースに提供します。 +udevは、ハードウェアに相当するデバイスノードを作成するために、この情報を使用します。 +sysfsは/sysにマウントされることで、情報を読み出せる状態になります。 +udevに取り組む前に、まず/sysにあるファイル群を調査したいとお思いになるでしょう。この文書全体に渡って、用語/sysとSYSFSを使用します。どちらにも読み替え可能です。


    + + +

    なぜルールを書く必要がありますか?

    +上で述べたように、udevのルールを書くかどうかは、自由に選択できます。 +初期設定でも、デバイスを接続することができ、過去の/dev実装でのように、そのデバイスに適切なノード(例えば、マスストレージデバイス用である/dev/sdaなど)が作成されるでしょう。

    +しかし、udevはデバイスノードの名前を自由に変えることができます。 +名前を変更したくなる理由には、利便性とデバイス名の固定化の二つが考えられます。

    + +プリンタが接続されたときに、/dev/printerとして命名され、さらにいつもの/dev/lp0も存在するようにする場合のudevの使用例を挙げます。 +この例は、利便性(例えば、lp0ではなくprinterに読み替える)だけではなく、変更になる可能性のある名前への対策であることを意図しています。 +私は二つのプリンタ(HPのレーザプリンタと、EPSONのインクジェット)を持っています。 +それらプリンタの両方が接続され、システムに組み込まれるた場合、/dev/lp0と/dev/lp1になります。
    +どうすれば、どちらのノードがどちらのプリンタを指しているかを知ることができるでしょう。 +簡単な方法はありません。接続された順で、最初のプリンタがlp0を割り当てられ、二番目がlp1に割り当てられます。異なる順番でプリンタが接続されると、この名前は逆になります。そして、それは常にHPのレーザプリンタがlp1であることを想定している私のスクリプトを混乱させるでしょう。

    +しかし、もしHPレーザプリンタに(lpXに加えて)lp_hpの名前が与えられ、一方のプリンタに(lpYに加えて)lp_epsonの名前が与えられるなら、私のスクリプトは、これらの名前を使えるでしょう。udevの魔法は、このようなことを制御でき、このような固定された名前が常に意図するデバイスを指すことを確実にします。

    +この名前の固定化機能は、外部マスストレージデバイス(例えば、USBハードディスク)において、/etc/fstabに正確なデバイスを書き込むことを可能にするのに、とても役に立ちます。

    + +ルールを書くことは、udevの動作を調整する一つの手段でしかないという認識を持つことが大切です。 +ルールを書くことは、既存の特定デバイスに対応するデバイスノードがない場合の問題に対する回避策ではありません。 +該当する既存のルールがない場合、udevはカーネルが提供する名前を使ってとにかくノードを作成します。

    + + +

    ルールを書く上での基本事項

    + +udevは、/devの下を配置するときに、一連のルールファイルを読んで、どのノードを含めるかと、それらのノードにどのような名前を付けるかを決定します。

    + +初期設定のudevルールは、/etc/udev/rules.d/50-udev.rulesにあります。 +このファイルにざっと目を通すとおもしろいことが分かるかもしれません。 +そこには少しの例や、いくつかのdevfs形式の/devレイアウトを提供する初期設定ルールが含まれています。 +しかし、今後udevを更新するときに起こりうる面倒を軽減するために、このファイルにルールを直接書くべきではありません。

    + +/etc/udev/rules.d/にあるファイルは、辞書順で解析されます。 +udevは、ファイル中に新しく検出されたハードウェアに一致するルールを見つけるとすぐに、ルール処理を止めます。 +udevの初期設定と照合される前に、ユーザが用意したルールが処理されることが重要です。そうでないと、ユーザの命名規則は無効になってしまうでしょう。 +/etc/udev/rules.d/10-local.rulesファイル(デフォルトでは存在しないので、作成してください)の中にユーザ指定のルールを保持しておくことを推奨します。 +10は50より前なので、ユーザ指定のルールが最初に評価されることがおわかりでしょう。 +ユーザ指定のルールファイルの名前は、.rulesサフィックスで終わっている必要があります。そうしないと利用されません。

    + +ユーザ指定のルールは、基本の/devレイアウトを作成するudevの初期設定を、事実上無効にしてしまいます。したがって、ユーザが記述するルールには、実用的である初期設定の名前とユーザ指定の名前両方を得るために、devfs形式の名前やシンボリックリンクも指定することをお勧めします。

    + +ルールファイルでは、"#"で始まる行は、コメントとして扱われます。 +ルールファイルの中のコメントされてない全ての行が、ルールに相当します。

    + +ルールは複数のキーで構成されます。複数のキーはコンマによって区切られます。 +一部のキーは情報の読み込みと照合用で、その他のものは、情報の割当てやアクションの実行用です。 +
      +
    1. システムにあるいろいろなデバイスに一致する、少なくとも一つの識別キー(identification key)を指定する必要があります。 +識別キーついては、後にある基本キーによるデバイス識別方法セクションに記載されています。
    2. +
    3. 結果としてデバイスノードがどのようにして作成されるかを制御するための、少なくとも一つの割当てキー(assignment key)を指定する必要があります。 +割当てキーには、NAME、SYMLINK、OWNER、GROUP、MODEがあり、このドキュメントですべて説明しています。
    4. +
    + +一般的なルールは、デバイスに名前を付けることを決定するために、複数の基本識別キーが使われます。そして、デバイスノード名を決めるために一つのNAME割当てキーが指定されます。 +udevは、一つのデバイスに対し一つのノードだけを作成します。 +したがって、一つのデバイスに対し複数のノードを通してアクセスしたい場合は、SYMLINK割当てキーに、別のノードを指定する必要があります。

    + +以下に例を示すためにudevの例にあるルールをちょっと修正したものを取り上げます。 +
    BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson", SYMLINK="printers/epson_stylus"
    + +この場合の識別キーは、BUSとSYSFS{serial}で、割当てキーは、NAMEとSYMLINKです。 +udevは、このルールをUSBバスによって接続されかつHXOLL0012202323480のシリアルナンバーを持つデバイスに対して一致させます。 +udevがデバイスに名前を付けるルールとして採用するには、(どれか一つではなく)すべての指定されたキーが一致する必要があります。
    + +udevは、このノードをlp_epsonと命名し、/dev/lp_epsonに作成するでしょう。
    +udevは、さらに/dev/lp_epsonへのシンボリックリンクを、/dev/printers/epson_stylusに作成します(printersディレクトリは、自動的に作成されます。)。 +これで、/dev/printers/epson_stylusもしくは/dev/lp_epsonにデータを送ることで、EPSONプリンタで印刷することができます。

    + +ユーザが追加または修正したどんなルールも、udevに通知するまで有効にはなりません。 +何かルールファイルを修正した場合は常に以下のコマンドを確実に実行することを忘れないでくささい。 +
    # udevstart
    + + +

    NAMEとSYMLINKパラメータでの設定自動化のための付加機能

    +ルールのNAMEとSYMLINKパラメータに、デバイスの名前づけを支援する基本オペレータを使用することができます。 +プログラム言語が分かる人は、この種のものをprintf形式に似た文字列置換として知っていると思います。 +NAME/SYMLINKパラメータの一部もしくは全てを組み立てることが可能な、いくつかのオペレータがあります。 +これらオペレータは、デバイスに関するカーネルデータを参照します。 +以下の例を見てみましょう。 +
    BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n"
    + +%nオペレータは、camera0、camera1、などのようなNAMEを作成するために、カメラデバイスに対する"カーネル番号"に置き換えられます。

    + +他にはよく使われるオペレータとして、%kがあります。 +これは、例えば"hda1"などのような、カーネルがデバイスに付けると予想される名前を表します。 +ハードウェアのデフォルトの名前を作成するための、NAME="%k"が指定されているルールをよく見るでしょう。 +このようなルールでは、ユーザ指定のものは通常SYMLINKパラメータによって設定されます。

    + +udevのmanページに説明付きでオペレータの全リストがあります。

    + + +

    キーでのシェル形式パターン照合の使い方

    + +キーを書く場合、より柔軟性を高めるためにシェル形式のパターン照合を使用することができます。以下に初期設定のudevルールを取り上げます。 + +
    KERNEL="ts*", NAME="input/%k"
    +ここでは*オペレータが使われています。これは、文字列長が0以上のすべての種類の文字で構成される文字列全体に一致します。 +このルールの書き方は、以下のことを意味します。 + +
    "ts"の文字列で始まり、その後に任意で何かの文字が続くKERNEL名によって識別されるデバイスに一致し、指定ディレクトリの下にKERNEL名(%k)で名前をつけます。
    + +?オペレータはよく似ており、何かの一文字に一致します(0文字には一致しません)。

    + +どれかの一文字に一致する、かぎ括弧[ ]も使用できます。以下にudevのmanページから直接引用します。
    +
    例えば, パターン文字列"tty[SR]"は、"ttyS"か"ttyR"に一致します。
    +一致範囲を指定することもできます。 +例えば、[0-9]はいずれかの一文字の数字に一致します。 +以下にudevインストール直後の初期設定にあるルール例を示します。 +
    KERNEL="fd[0-9]*", NAME="floppy/%n"
    + +このルールは以下のことを意味します。
    + +
    "fd"で始まり、それに一文字の何かの数字が続き、その後に任意で何かの文字が続くKERNEL名によって識別されるデバイスに一致します。フロッピーのディレクトリの下にデバイスのカーネル番号(%n)でデバイスに名前をつけます。
    +これらのワイルドカード/パターン一致は、基本キーとsysfsでの識別情報の両方を含め、どのキータイプででも使用できます(キータイプに関しては後の説明を参照してください)。

    + +ここでは、ルールの書き方に関する基本事項の範囲外である一部の情報(特に[ ]オペレータの柔軟性)をわざと割愛しています。 +これに関する詳しい情報は、udevのmanページにあります。

    + + +

    キーを書く上での基本事項

    +udevは、いくつかの基本キーを照合する仕組みを提供しています。さらにSYSFS内のデバイス情報と照合するための柔軟な方法も提供します。 +標準的なルールは、普通のキー(BUSとKERNELなど)と、 +同一ポートに接続された異なるハードウェア間で区別をするSYSFSキーの両方が一致します。

    +「自分のプリンタのシリアルナンバーをどうやって探せばいいの? 私のカメラのモデルは何だろう?」と疑問に思うかもしれません。 +ルールの書き方は、思うほど難しくありません。 +一番やっかいなのは/sys内で対象のデバイスを探して、どの情報を使うかを決めることです。

    + + +

    基本キーによるデバイス識別方法

    + +基本キーに関するより詳しい情報はudevのmanページを参照してください。

    + +有効なキーは次のとおりです。 +
    • BUS - デバイスのバスの種類と照合されます。
    • +
    • KERNEL - カーネルデバイス名と照合されます。
    • +
    • DRIVER - カーネルドライバの名前と照合されます。
    • +
    • SUBSYSTEM -カーネルサブシステム名と照合されます。
    • +
    • ID - バス上のデバイスナンバー(PCIバスIDなど)と照合されます。
    • +
    • PLACE - デバイスが接続された物理的な位置と照合されます(USBに役に立ちます)。
    • + +
    +IDとPLACEキーは、役に立つこともありますが、一般的にルールでは使用されません。 +この文書は、BUSとKERNELキーやSYSFS{...}キー(次のセクションで説明します)の使い方に重点を置きます。 +例を使ってこれらのキーの使い方を示します。

    + +さらに柔軟な方法として、udevは外部のスクリプトを呼び出してその結果を使うためのキーや、環境変数を使うためのキーも準備しています。 +これは、この文書の範囲外とします。より詳細な説明は、udevのmanページを見てください。 + + +

    SYSFSファイルによるデバイス識別方法

    + +前提となる知識: SYSFSは、ディレクトリツリーの下にハードウェアに関する情報を提供するたくさんの小さなファイルを保持しています。 +一つのファイルは、一般に一つだけ"データ項目"を持ちます。- 例えば、デバイス名や製造者情報やプロダクトIDがあります。

    +SYSFS{...}キーは、前のセクションで説明した基本キーと組み合わせることができます。


    + +特定のSYSFSの情報と照合するために、SYSFS{ファイル名}形式のキーを使えます。ファイル名は、SYSFSツリーの中のファイルに相当します。 +例としては、私のカメラが接続された場合、"USB 2.0M DSC"という内容で/sys/block/sda/device/modelにファイルが存在します。これと照合するために、次のようなキーを使えます。SYSFS{model} = "USB 2.0M DSC"

    + +sysfsにあるすべてのファイルが、この方法で照合することができます。 +ただ、(複数のキーを使って)一つ以上のファイルと照合させる場合、同一ディレクトリにあるファイルとだけに照合させる必要があります。 +一般的には、一つのデバイスに関する情報を提供するディレクトリは、いくつか存在します。 +(後の例で示すとおり、)それらを混合して照合することはできません。

    + +幸いにして、ルールを書く過程において、SYSFSにある無数のファイルを探し回る必要はありません。udevinfoユーティリティがその大変な作業を代わりにやってくれます。このプログラムはudevの配布物の中に含まれています。

    +まず始めにしなければならないことは、対象のハードウェアに対応する、"dev"というファイルを含むディレクトリが/sysのどこにあるかを見つけることです。 +udevinfoは、そのようなディレクトリ上でだけ動作可能です。 +これらのディレクトリは、すべてが/sys/blockか/sys/classのどちらか一方の下で見つかります。 +- その他の場所は、どこも参照する意味がありません! +しかし、udevinfoはこれらのディレクトリを経由してリンクを辿って、sysfsの別のセクションで見つかる情報を読み出します。

    +一度だけこのようなディレクトリを見つければ、udevルールのキーを書く作業を手助けしてくれる以下のコマンドが使えます。 +
    # udevinfo -a -p /sys/path/to/hardware/info
    + +udevinfoを実行するための/sys内の適切な位置を見つけることについては、まだ明確になっていないことが分かるでしょう。 +接続したデバイスに対し既にデバイスノード(例えば、/dev/sda)が作成されている可能性があり、その場合はudevinfoが役に立ちます! +私の/dev/sdaノードの例でいうと、以下のコマンドを実行するとsysfsの適切な位置を示してくれます。 +
    # udevinfo -q path -n /dev/sda
    +
    +/block/sda
    +
    + +(上記で示した)このコマンドの出力は、sysfsパスが/sys/block/sdaで始まることを示しています。 +これで私は"udevinfo -a -p /sys/block/sda"を実行できます。 +これらの二つのコマンドは、以下のように連ねることができます。 + +
    # udevinfo -a -p $(udevinfo -q path -n /dev/sda)
    + +注記: 前に示したものには、udevinfoにあらかじめフルパス(/sys/なんとか/パス)を指定していて、今回はこれらのコマンドを連結することでsysfsに関係するパスを指定していることに気が付くかもしれません。 +どちらでも特に問題はありません。どちらのパス形式も受け付けられます。

    +ここでルールの書き方に移り、私の環境での"udevinfo -a -p /sys/block/sda"の実行結果の抜粋を、色づけをして以下に示します。
    + +
    
    +follow the class device's "device"
    +  looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3/3-3:1.0/host0/0:0:0:0':
    +    BUS="scsi"
    +    ID="0:0:0:0"
    +    SYSFS{detach_state}="0"
    +    SYSFS{type}="0"
    +    SYSFS{max_sectors}="240"
    +    SYSFS{device_blocked}="0"
    +    SYSFS{queue_depth}="1"
    +    SYSFS{scsi_level}="3"
    +    SYSFS{vendor}="        "
    +    SYSFS{model}="USB 2.0M DSC    "
    +    SYSFS{rev}="1.00"
    +    SYSFS{online}="1"
    +
    +  looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3':
    +    BUS="usb"
    +    ID="3-3"
    +    SYSFS{detach_state}="0"
    +    SYSFS{bNumInterfaces}=" 1"
    +    SYSFS{bConfigurationValue}="1"
    +    SYSFS{bmAttributes}="c0"
    +    SYSFS{bMaxPower}="  0mA"
    +    SYSFS{idVendor}="052b"
    +    SYSFS{idProduct}="1514"
    +    SYSFS{bcdDevice}="0100"
    +    SYSFS{bDeviceClass}="00"
    +    SYSFS{bDeviceSubClass}="00"
    +    SYSFS{bDeviceProtocol}="00"
    +    SYSFS{bNumConfigurations}="1"
    +    SYSFS{speed}="12"
    +    SYSFS{manufacturer}="Tekom Technologies, Inc"
    +    SYSFS{product}="USB 2.0M DSC"
    +
    + +udevinfoツールは、udevルールにそのままコピーペーストして使うことができる多くの情報を提供してくれます。 +上記の出力結果に色をつけた理由は、 +通常はudevinfoの出力の異なる箇所からの情報を組み合わせて照合することができないことを示すためです。 +上記の出力結果で、異なる色が付いているセクションの情報を組み合わせることはできません。 - 出力結果の各セクションが、SYSFS内での異なるディレクトリを参照している情報だからです。 +例えば、以下のルールは機能しません。 +
    BUS="scsi", SYSFS{manufacturer}="Tekom Technologies, Inc", NAME="%k"
    このルールは、青いセクションにだけ存在する情報とBUS="scsi"(緑)で始まるセクションにある情報と組み合わさっているので機能しません。 +BUS="usb"と、上記の青いセクションにある情報だけを使用しているならちゃんと機能するでしょう。

    +多くの情報が、基本的なルールの書き方には関係ないことがわかるでしょう(本当にたくさんあります!)。 +一般的には、変更にならないことが分かっている情報(例えばモデル名)を探すべきです。

    + +デバイスを識別するユーザ指定のルールを記述すると、初期設定のdevfs形式のルールが機能しなくなることに注意してください。 +たいていの場合、NAME="%k"を使用するのが賢明で、初期設定の実用的な名前がなくならないように、SYMLINKパラメータに追加の名前を指定してください。

    + +以下にudevinfoの出力を基にしたルールの書き方の手順を三つの例で示します。 +その後、正確な情報を提供するために各デバイス固有の小技やコツをいくつか記述しようと思います。

    + +読者の一人が、KDEのコントロールセンターがルールを書くのに役に立つということを、知らせてきました。 +USBデバイス(やその他)に関する情報が、KDEコントロールセンターの"Info Centre"セクションで見つかるということです。 +このインターフェースは、シリアルナンバー、ベンダIDなどのような情報を表示します。 +GUI的なやり方が好ましいなら、こちらを調査したいと思うでしょう。

    +現在リリースされているGNOMEボリューム管理は、実デバイスとしてシンボリックリンクノードを扱うことができません。 +上記で説明したのとは反対に、NAMEパラメータにユーザ指定の名前を指定して、SYMLINKパラメータに%kを指定しようと思うかもしれません。

    + +複数SYMLINK形式を使えば、ユーザ指定ルールが初期設定を上書きする仕様に対処できます。 + +
    + + +

    複数SYMLINK形式の使い方

    +最近取り入れられた機能の一つに、NAMEを指定せずに、複数のSYMLINKキーを単純に指定するルールが書けるようになったことがあります。 +これで、ユーザ指定ルールがudevの初期設定を実質的に無効にする問題を避けることができます。

    + +そのルールを以下に取り上げます。
    +
    KERNEL="hdc", SYMLINK="dvd"
    +udevはこのルールを見つけると、記憶しておきます。 +そして、NAMEパラメータも含む同一デバイスに一致する別のルールを見つけたときに、そのNAMEパラメータで指定されているノードに加え、両方のルールにあるSYMLINKパラメータで指定されているシンボリックリンクも作成します。
    +実際問題として、udevは私のhdcデバイスのノードを命名する際に、いつものようにブロックデバイス用の初期設定ルールを使い、追加の私個人指定の"dvd"シンボリックリンクを作成します。

    + +普通のルールと同様に、udevがNAMEパラメータを指定しているルールを見つける前にこの形式のルールを見つけたときだけ有効になります。

    + + +

    所有権とパーミッション制御

    +作成されるデバイスノードの名前付け制御と同様に、udevルールは、そのデバイスノードの所有権とパーミッション属性の制御も可能にします。

    + +GROUPキーは、どのunixグループにデバイスノードを所有させるかを定義できます。 +ここにudevの初期設定から例を示します。 +この例は、フレームバッファ(fb)デバイスをvideoグループにするように定義しています。 + +
    KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video"
    + +おそらくあまり使えないOWNERキーは、どのunixユーザにデバイスノードを所有させるかを定義できます。 +フロッピーデバイスを"john"の所有にする場合のちょっと変な状況を仮定すると、次のように使います。 +
    KERNEL="fd[0-9]*", OWNER="john"
    + +上記のルールには、NAMEやSYMLINKが一つも指定されていないことがわかるでしょう。 +これは、udevが、フロッピーノードをjohnの所有にしたいということを記憶しておき、フロッピーデバイスノードに対するNAMEが定義されたルールを見つけると、所有者を適用する点で、複数シンボリック形式に似ています。

    +上で記述した形式を使用すると、もっと華麗なこともできます。 +udevの初期設定では、すべてのサウンドデバイスノードが"audio"グループによって所有されるように定義するのに以下のルールを使用しています。 +
    SUBSYSTEM="sound", GROUP="audio"
    + +これに続くサウンドデバイスに名前を付ける全てのルールにGROUP="audio"キーをやたらと指定する必要をなくします。

    + +udevのデフォルトでは、unixパーミッションに0660(所有者とグループだけが読み書き可能)を持つノードを作成するようになっています。 +これは、/etc/udev/udev.confの中のdefault_mode設定によって設定されています。 +デバイスノードにデフォルトパーミッションを適用したくない場合もあるかもしれません。幸いにして、ルールにMODE割当てキーを使うことで簡単にデフォルト設定より優先させることができます。 +例として、以下のルールはinotifyノードが全てのユーザに読み書き可能になるように定義しています。 + +
    KERNEL="inotify", NAME="misc/%k", SYMLINK="%k", MODE="0666"
    + + +

    例: 著者所有のUSBプリンタ向けのルールの書き方

    +私は、プリンタを接続した後、ルールを書くために/sysディレクトリから関連する位置を探し始めました。 +どこにも見つからなかったのですが、私のプリンタにデバイスノード/dev/lp0が割り当てられていることに気づきました。 +udevinfoは、便利なpathを指定すると以下のように教えてくれます。 +
    # udevinfo -q path -n /dev/lp0
    +/class/usb/lp0
    +
    +"udevinfo -a -p /sys/class/usb/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"
    +
    + +この場合のudevルールは以下のようになります。 +
    BUS="usb", SYSFS{serial}="L72010011070626380", NAME="%k", SYMLINK="epson_680"
    + +そうすると、私のプリンタのノードは/dev/lp0(または、別のプリンタが前もって接続されている場合は/dev/lp1)で存在し、/dev/epson_680は常にそのプリンタのためのデバイスノードを指します。

    + + +

    例: 著者所有のUSBストレージ方式対応デジカメ向けのルールの書き方

    + +簡単な説明: 私のカメラは外付けSCSIハードディスクとして認識されます(USBハードディスクやフラッシュメモリカードリーダのようなデバイスにも使用されるusb-strageドライバを使います)。 +そして、そのディスク上のパーティションをマウントして、画像ファイルをコピーできます。すべてのカメラがこのように動作するわけではありません。ほとんどのカメラは、画像ファイルを扱うために、さらにソフトウェア(gphoto2など)を必要とします。

    + +これにはちょっとしたコツがあります。私のカメラが接続されると、デフォルトでいくつかのノードが作成されます。 +/dev/sdaや/dev/sda1、/dev/sg1さえも作成されるかもしれません。 +この例が示しているものは重要です。もしルールが上手に指定されなければ、上記3つのノードすべてに一致することがありえます。

    + +sda1は、私がマウント用に/dev/cameraとして使用しようと思うノードです。 +udevinfoはsda、sda1、sg1の間に利用できそうな差異は何も提示してくれません。 +これら3つのノードを区別するために信頼できる方法は、KERNEL名を見ることであると私は判断しました。

    + +KERNEL="sd?1"のようなキーは、"sda1"、"sda1"、"sdc1"のようなKERNEL名に一致し、そして同様に重要なことに、それは、sda、sdb、sg1のようなKERNEL名に一致しないであろうということです。 +このようなキー指定には、/dev/sdaや/dev/sg1ノードに一致させないという目的があります。 +対象のデバイスはデジタルカメラです。その上ではfdiskやその類の操作をしようなんて夢にも思わないので、私にとってこれらの2つのノードは、まったく使いものになりません。 +このキーは/dev/sda1ノードを捕捉しようとします。これはマウント可能なので、使いものになります!

    + +このノード(sda1)は、ブロックデバイスとして扱われるので、/sys/blockから探すことは、作業を始めるのに向いています。

    + +私の環境での/sys/blockには、sdaというディレクトリがあります。 +/sys/block/sdaには、sda1というディレクトリがあります。 +これら両方のディレクトリにdevファイルがあるので、そこでudevinfoを実行できます。 +以下を実行すると、私のカメラとそれが接続されているUSBポートに関するたくさんの情報を表示してくれます。 + +
    # udevinfo -a -p /sys/block/sda/sda1
    + +udevinfoの出力に、以下のちょっと役に立つ意味がわかりやすい情報を見つけました。
    SYSFS{product}="USB 2.0M DSC"
    + +よってこれで私のルールを書くことができます。ルールを完全にするために、BUSキーも加えます(これもudevinfoの出力で見つかります)。 +
    BUS="usb", SYSFS{product}="USB 2.0M DSC", KERNEL="sd?1", NAME="%k", SYMLINK="camera"
    + +こうして、私のカメラを接続すると、/dev/sda1(もしくは、sda1が利用できないなら、/dev/sdb1になるかもしれません)という名前で、常に間違いなく/dev/cameraからリンクされます。 +/dev/sda(もしくはsdb)ノードは、いつものようにまだ出現します。 +しかし私が指定する不変の"camera"シンボリックが、マウント可能パーティションを指しているということが重要です。

    + + +

    USBストレージ向けルールの書き方に関する追記

    + +大容量のUSBハードディスクを所持するCarl Streeterが、/dev/sdaノードが役に立たなかった私のデジタルカメラの例とは違った説明をメールしてきました。 +/dev/sdaのようなノード上でfdiskやhdparmなどのツールをちょくちょく使う必要があることを指摘しています。

    + +以下にCarlのルールを示します。 +
    BUS="usb", KERNEL="sd*", SYSFS{product}="USB 2.0 Storage Device", NAME="%k", SYMLINK="usbhd%n"
    + +このルールは、以下のようなシンボリックリンクを作成します。 +
      +
    • /dev/usbhd - fdiskすることができるノード
    • +
    • /dev/usbhd1 - 一つ目のパーティション (マウント可能)
    • +
    • /dev/usbhd2 - 二つ目のパーティション (マウント可能)
    • + +
    +Carlとはマウント不可の/dev/sdaノードが必要かどうかは、状況と対象のデバイスに依存するということで共通認識を持っています。 +どちらの設定方法にしろ都合のよい方を使用してください。

    +これとは別の複雑な状況として、複数のスロットを持つUSBストレージカードリーダを持っている場合があります。 +新しいカードが刺されたり抜かれたりしたときに、一般的にこのような種類のデバイスはその情報を通知しません。 +よって、リーダが接続されている間に未使用スロットにカードを刺しても、マウントする必要がある追加のデバイスノードは、作成されないでしょう!
    +この問題は、他のUSBディスクにも当てはまります。 +例えば、新しいパーティションを作成した場合、デバイスを再接続するまで、新しいパーティションノードは出現しないでしょう。

    +udevは、これに対する一つの解決方法を提供します。 +ブロックデバイスのすべてのパーティション用のノードを作成することができます。 +指定したすべてのルールに対して、ブロックデバイスで16個のパーティションノードを作成します。 +これをするには、以下に示すように単にNAMEキーを修正します。
    + +
    BUS="usb", SYSFS{product}="USB 2.0 Storage Device", NAME{all_partitions}="usbhd"
    + +こうすることで、usbhd、usbhd1、usbhd2、usbhd3、...、usbhd15というノードが作成されるでしょう。

    + + +

    例: 著者所有のCDドライブ向けの有用なルールの書き方

    +私のPCには二つのCDドライブがあります。一つは、DVD読み込み対応で、一つはCD読み書き対応のものです。 +DVDのノードはhdcで、CDRWのノードはhddです。 +あえてシステムの結線を変更する場合を除いて、これを変更するつもりはありません。

    + +でも、利便性のために/dev/dvdや/dev/cdrwのようなノードを好む人が(私自身も含めて)います。 +これらドライバの"hdX"の値がわかっているので、ルールを書くのは簡単です。 +以下の例は、それだけで自明でしょう。 +
    BUS="ide", KERNEL="hdc", NAME="%k", SYMLINK="dvd cdroms/cdrom%n"
    +BUS="ide", KERNEL="hdd", NAME="%k", SYMLINK="cdrw cdroms/cdrom%n"
    +
    + +デフォルトの50-udev.rulesファイルにブロックデバイス用の名前を生成するスクリプトを実行するルールがあることに気が付くかもしれません。 +これに惑わされないでください。やはりユーザ指定のルールは、デフォルトルールの前に処理されるファイルに設定するので、デフォルト設定は、ルールを設定済みのハードウェアに名前をつけるときには使用されません。

    + + +

    例: USB Visor Palm Pilot向けのルールの書き方

    + +これらのデバイスは、USBシリアルデバイスのように動作します。よってデフォルトではttyUSB1ノードだけが得られます。 +ユーザスペースのpalmユーティリティは、/dev/pilotがあることを前提としています。 +よってそのノードを作成するルールを使う必要があります。 +以下のルールはこれを行います。

    + +
    BUS="usb", SYSFS{product}="Palm Handheld", KERNEL="ttyUSB*", SYMLINK="pilot"
    + +この状況に関する有用な議論があるCarsten Clasohm's blog entry(訳注: Carsten Clasohmのブロブ)から応用しました。 +さらに個々の設定に合わせるために、上記ルールに所有権とパーミッションキーを追加したいと思うかもしれません。

    + + +

    例: 著者所有のネットワークインターフェースに名前を付けるルールの書き方

    +最近のバージョンのudevにある興味深い新しい機能に、nameifユーティリティのように、ネットワークインタフェースの名前を付け直す機能があります。 +ネットワークインターフェースは、/devに出現しませんが、一般的にはそれらは名前によって参照されます(例えば、ifconfigで使用される場合)。 +ネットワークデバイスには様々ありますが、ルールを書く工程はほとんど同じです。

    +やはりudevinfoはルールを書く手がかりになります。 +以下は私の"eth0"のネットワークデバイスの名前を変更したい場合の例です(以下の出力結果は省略されています)。 +
    # udevinfo -a -p /sys/class/net/eth0/
    +  looking at class device '/sys/class/net/eth0':
    +    SYSFS{address}="00:52:8b:d5:04:48"
    +
    +すべてのネットワークアダプタには固有のMACアドレスがありますので、ルールを書く場合にはこれを使うことを選択しました。 +この値は、ネットワークカードを変更しない限り変更がありません。 +以下に一つ警告があります。 +大文字小文字を区別しますので、必ず(上記のように)udevinfoから取得したMACアドレスを使ってください。 +ifconfigのようなユーティリティを使う場合は、それらは大文字を使うので、気をつけてください。

    + +ルールの例を以下に示します。 +
    KERNEL="eth*", SYSFS{address}="00:52:8b:d5:04:48", NAME="lan"
    +このルールを有効にするためにネットワークドライバをリロードしなければならないでしょう。 +モジュールをアンロードして再度ロードするか、もしくは単にシステムをリブートすればよいです。 +"eth0"ではなく"lan"を使うようにシステムを構成しなおす必要もあります。 +私の場合、eth0を参照するものすべてを完全に削除しないで、これを進めてしまい、少々苦労をしました。
    +これが完了すれば、ifconfigやそれに似たユーティリティのどれにでも"eth0"の代わりに"lan"を使えるはずです。

    + + +

    SYSFS内におけるudevinfoを実行すべき場所を探すためのコツ

    +ここではより多くのデバイス固有のコツを求めています。 +提供できることならなんでも連絡してください。 + +
      +
    • ルールを書こうとしているデバイスに対し、すでに/devの下にデバイスノードが作成されているなら、運がよいです! +適切な/sysのパスを得るために、次のコマンドを実行してください。udevinfo -q path -n /dev/ノード名
    • +
    • ルールを書く手間を軽くするために、常にudevinfoを使用してください。 +/sys/blockや/sys/classの下を参照するために、常にudevinfoを使用してください(別のところから、チェイン情報を読むことはありません)。
    • +
    • 何も手がかりがなければ、/sysの下のすべて"dev"ファイルを探すために、次のコマンドを使用してくだい(udevinfoは、このファイルがあるディレクトリ上でのみ動作します。)。find /sys -iname dev
    • +
    • 対象のデバイスが、フラッシュカードリーダや、USBフラッシュドライブ、/dev/sdXが作成されるUSBストレージとして振舞うデジタルカメラの場合、/sys/block/sdXを探してみてください。
    • +
    • 上記の状況に該当する場合、必ずsdXとsdX1とを区別して下さい。sdX1に一致するキーKERNEL="sd?1"もしくは、sdXに一致するKERNEL="sd?"で区別できます。
    • +
    • /dev/lpXとして作成されるUSBプリンタについては、/sys/class/usb/lpXから探すべきです。
    • + +
    • USBスキャナドライバは、最近カーネルから削除され、(SANEパッケージの一部として)ユーザスペースで再実装されました。 +特定のカーネルドライバに依存しないように、この種のハードウェア用のルールを書いてはいけません(し、書けないでしょう)。
    • +
    • あいにくカーネルはsysfsですべてのデバイスの情報を開示するわけではありません。 +よって、まだ一部のデバイスに対してはルールを簡単に書くことができません。 +2004年2月20日時点で、udevの作者はsysfsに未対応のドライバが162個残っていると言っています。
    • +
    + + +

    ルールのデバッグ方法

    + +ルールを書き終わって忘れずにudevstartを実行しても、有効にならないなら、それをデバッグするのには二つの方法があります。

    + +/etc/udev/udev.confには、udev_logオプションがあります。 +そのオプションをyesに設定すると、udevはどのノードにどのルールを適用したかに関するいくつかの役に立つ情報をシステムロガーに出力します。 +そのログ情報は、ほとんどの場合/var/log/messagesにあるでしょう。

    + +さらに、ユーザが作成したいノードのsysfsにおけるパスを調べたいなら、ノードに対しudevがするはずであったことを一つずつ追って確認するために、udevtestを使用できます。 +以下に例を示します。 + +
    # udevtest /sys/class/sound/dsp/
    +version 056
    +looking at '/class/sound/dsp/'
    +opened class_dev->name='dsp'
    +configured rule in '/etc/udev/rules.d/50-udev.rules[132]' applied, added symlink '%k'
    +configured rule in '/etc/udev/rules.d/50-udev.rules[132]' applied, 'dsp' becomes 'sound/%k'
    +creating device node '/dev/sound/dsp', major = '14', minor = '3', mode = '0660', uid = '0', gid = '18'
    + +udevtestは、デバッグ/テストだけをするツールです。たとえ作成しているように表示しても、実際にはデバイスノードを作成しません!

    + + +

    著者と謝辞

    +この文書はDaniel Drake <dan@reactivated.net>
    によって書かれました。 +ご意見ご感想などなんなりと送ってください!

    + +Copyright (C) 2003-2005 Daniel Drake
    +この文書はGNU General Public License, Version 2の下に公開されています。 + + \ No newline at end of file From b479b4887f5a0eb69b801645ab1b14636c4b06a2 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 18 May 2005 23:32:28 -0700 Subject: [PATCH 1298/4284] Fix libsysfs issue with relying on the detach_state file to be present in order to traverse the tree properly. Based on a patch from Daniel Stekloff Signed-off-by: Greg Kroah-Hartman --- libsysfs/sysfs_device.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index d1c5b321f0..1c59403edd 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -383,7 +383,7 @@ struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) */ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) { - char ppath[SYSFS_PATH_MAX], *tmp; + char ppath[SYSFS_PATH_MAX], dpath[SYSFS_PATH_MAX], *tmp; if (!dev) { errno = EINVAL; @@ -394,6 +394,7 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) return (dev->parent); memset(ppath, 0, SYSFS_PATH_MAX); + memset(dpath, 0, SYSFS_PATH_MAX); safestrcpy(ppath, dev->path); tmp = strrchr(ppath, '/'); if (!tmp) { @@ -410,16 +411,14 @@ struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) } *tmp = '\0'; - /* - * All "devices" have the "detach_state" attribute - validate here - */ - safestrcat(ppath, "/detach_state"); - if (sysfs_path_is_file(ppath)) { + /* Make sure we're not at the top of the device tree */ + sysfs_get_mnt_path(dpath, SYSFS_PATH_MAX); + safestrcat(dpath, "/" SYSFS_DEVICES_NAME); + if (strcmp(dpath, ppath) == 0) { dprintf("Device at %s does not have a parent\n", dev->path); return NULL; } - tmp = strrchr(ppath, '/'); - *tmp = '\0'; + dev->parent = sysfs_open_device_path(ppath); if (!dev->parent) { dprintf("Error opening device %s's parent at %s\n", From 13ca17798cd69dd384ddade607ae3a9878622965 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 18 May 2005 23:33:12 -0700 Subject: [PATCH 1299/4284] remove detach_state files from the sysfs test tree. Signed-off-by: Greg Kroah-Hartman --- test/sys/devices/pci0000:00/0000:00:09.0/detach_state | 1 - .../devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state | 1 - .../pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state | 1 - test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state | 1 - .../pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state | 1 - test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state | 1 - 6 files changed, 6 deletions(-) delete mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/detach_state delete mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state delete mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state delete mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state delete mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state delete mode 100644 test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/detach_state deleted file mode 100644 index 573541ac97..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/detach_state +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state deleted file mode 100644 index 573541ac97..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/detach_state +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state deleted file mode 100644 index 573541ac97..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/detach_state +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state deleted file mode 100644 index 573541ac97..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/detach_state +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state deleted file mode 100644 index 573541ac97..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/detach_state +++ /dev/null @@ -1 +0,0 @@ -0 diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state deleted file mode 100644 index 573541ac97..0000000000 --- a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/detach_state +++ /dev/null @@ -1 +0,0 @@ -0 From 8d9e468f125ae28d7cd6a0545ecb2a67311cdc1a Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 18 May 2005 23:34:45 -0700 Subject: [PATCH 1300/4284] Update Red Hat default udev rules. Signed-off-by: Greg Kroah-Hartman --- etc/udev/redhat/udev.rules | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index ad60d1a81d..2d4819f8c3 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -119,7 +119,7 @@ KERNEL=="vttuner", MODE="0660" KERNEL=="v4l/*", MODE="0660" # input devices -KERNEL=="input/*", MODE="0644" +KERNEL=="input/*", MODE="0660" # gpm devices KERNEL=="gpmctl", MODE="0700" @@ -195,8 +195,18 @@ KERNEL=="sr[0-9]*", SYMLINK="cdrom%e" KERNEL=="scd[0-9]*", SYMLINK="cdrom%e" KERNEL=="pcd[0-9]*", SYMLINK="cdrom%e" KERNEL=="fd[0-9]*", SYMLINK="floppy%e" -KERNEL=="nst[0-9]", SYMLINK="tape%e" -KERNEL=="nosst[0-9]*", SYMLINK="tape%e" +KERNEL=="nst[0-9]", BUS=="scsi", SYMLINK="tape%e" +KERNEL=="nosst[0-9]", BUS=="scsi", SYMLINK="tape%e" + +KERNEL=="umad*", NAME="infiniband/%k" +KERNEL=="issm*", NAME="infiniband/%k" + +# 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" # do not seperate the next 2 lines!! KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/ide-media.sh %k", RESULT=="floppy", SYMLINK="floppy%e", NAME{ignore_remove, all_partitions}="%k" From 539876083d15cef50f284f54a6b0cd6b7c911afa Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 18 May 2005 23:37:22 -0700 Subject: [PATCH 1301/4284] add Red Hat/Fedora html documenation Signed-off-by: Greg Kroah-Hartman --- docs/fedora_udev.html | 258 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 docs/fedora_udev.html diff --git a/docs/fedora_udev.html b/docs/fedora_udev.html new file mode 100644 index 0000000000..5d5048766d --- /dev/null +++ b/docs/fedora_udev.html @@ -0,0 +1,258 @@ + + + + + Fedora Project, sponsored by Red Hat + + + + + + + + + + + +
    + + +
    + +  Download +  Projects +  FAQ +
    +
    + +
    + + + +
    +
    Site Navigation:
    +
    + + + + +
    +
     
    +
     
    +
    + +

    Udev on Fedora

    +

    by Harald Hoyer

    +

    + This document tries to reveal the secrets of udev and how it works on Fedora. +

    +

    + udev was developed by Greg Kroah-Hartman <greg@kroah.com> with much + help from Dan Stekloff <dsteklof@us.ibm.com>, Kay Sievers <kay.sievers@vrfy.org>, + and many others. +

    +

    + The udev homepage and the + Linux-hotplug-devel mailing list https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel are the main development sources. +

    +

    + +

    What Does Udev Do?

    +

    + udev provides a dynamic device directory containing only the files for + actually present devices. It creates or removes device node files usually + located in the /dev/ directory, or it renames network interfaces. +

    + As part of the hotplug subsystem, udev is executed if a kernel device + is added or removed from the system. On device creation, udev reads + the sysfs directory of the given device to collect device attributes + like label, serial number or bus device number. These attributes may + be used as keys to determine a unique name for the device. udev maintains + a database for devices present on the system. + On device removal, udev queries its database for the name of the device + file to be deleted. +

    + udev gets called by hotplug, if a module is loaded, and a device is added + or removed. udev looks in /sys/, if the driver provides a "dev" file, which + contains the major and minor number for a device node to communicate with + the driver. After looking in the udev rules (in the /etc/udev/rules.d/ directory), which + specify the device node filename and symlinks, a device node is created + in /dev/ with the permissions, which are specified in /etc/udev/permissions.d/. +

    + After device node creation, removal, or network device renaming, udev + executes the programs in the directory tree under /etc/dev.d/. The + name of a program must end with the .dev suffix, to be recognized. + In addition to the hotplug environment variables, DEVNAME is exported + to make the name of the created node or the name the network device is + renamed to, available to the executed program. The programs in every + directory are sorted in lexical order, while the directories are + searched in the following order: +
      +
    • /etc/dev.d/$(DEVNAME)/*.dev
    • +
    • /etc/dev.d/$(SUBSYSTEM)/*.dev
    • +
    • /etc/dev.d/default/*.dev
    • +
    + +

    How is Udev Integrated on Fedora?

    +

    initrd / initfs

    +

    + mkinitrd copies /sbin/udev.static + to the initrd /sbin/udev and symlinks it to + /sbin/udevstart. +

    +After the kernel boots, it executes the nash script of the initrd. This +mounts a tmpfs filesystem on /dev/. Instead of hotplug /sbin/udev is +called in the initrd phase. udevstart creates all device nodes for the +devices, which are compiled in the kernel and for the modules, which +are loaded by nash.

    + +

    Problems

    + +The whole udev and hotplug infrastructure is +not available in initrd. Thus no hotplug scripts, udev rules, and +permissions and no /etc/dev.d/ scripts are executed for any hotplug +event, which is sent from the kernel. + +

    rc.sysinit

    +

    First, if SELinux is loaded and enabled, +the context of /dev/ is set. rc.sysinit calls /sbin/start_udev. +start_udev mounts a tmpfs filesystem on /dev/, if there is none already +mounted. Then it creates some device nodes, which need module +autoloading, or where there is no kernel module. After that +/sbin/udevstart is called again, which simulates the hotplug events in +the initrd phase, to apply the whole udev rules and permissions. After +that rc.sysinit parses the ouput of /sbin/kmodule and loads every +module. This should provide device nodes for all hardware found on your +computer.

    +

    Console User Permissions

    +

    +/etc/dev.d/default/pam_console.dev is called whenever a device node is +created and calls /sbin/pam_console_setowner with the filename (and an +optional symlink) of the device node. This sets the permissions for +console users like specified in /etc/security/console.perms.

    +

    Customizing Udev on Fedora

    +

    + Read the manpage of udev and udevinfo. + Please try not to modify the files of RPM packages. +

    +

    New Rules

    +

    +New rules should be placed in a file, which ends in .rules in +/etc/udev/rules.d/. Please do not use 50-udev.rules. The supported and +preferred way is to create rules without the "NAME" tag and only +create "SYMLINK"s.

    + A nice document describing how to write rules can be found on http://www.reactivated.net/udevrules.php. +

    + +

    Permissions

    +New permissions should be placed in a file, which ends in +.permissions in /etc/udev/permissions.d/. Please do not use +50-udev.permissions. + +

    But I Really Want My Device Node!

    +

    + Put them in /etc/udev/devices/, and they will get copied to /dev/. File a bugzilla entry, if you think that should be done per default. +

    + +

    Updating to udev Without /dev/

    +

    + The steps to upgrade without Anaconda or a rescue CD are (NOT recommended): +

    + +
      +
    • start from a kernel-2.6 +
    • Make sure /sys/ is mounted +
    • Install the latest initscripts package +
    • Install the latest udev package +
    • Execute /sbin/start_udev +
    • Install the latest mkinitrd package +
    • Install the latest kernel package +
    • Or execute mkinitrd for your existing kernel(s) +
    + +

    Udev without initrd

    + +

    Install Fedore Core as usual and reboot. Execute the following commands +

    + +
    +
    +mkdir /tmp/dev
    +mount --move /dev /tmp/dev
    +sbin/MAKEDEV null console zero
    +mount --move /tmp/dev /dev
    +
    + Install your kernel without an initrd. Reboot. +

    + You will get some SELinux errors, and syslogd will not work as expected. +

    +

    Current Problems on Fedora

    +

    + All open bugs for udev +

    +

    Nvidia

    +

    Quick solution: If you do not need rhgb, just load the nvidia module in /etc/rc.local +

    + If you have udev >= 032-5, load the nvidia module: +

    +
    +
    +cp -a /dev/nvidia* /etc/udev/devices
    +chown root.root /etc/udev/devices/nvidia*
    +
    + +

    The Bugzilla for this problem is 133900.

    +

    Palm Pilot

    +

    + If you have udev >= 032-5, execute the command: +

    +
    +
    +ln -s ttyUSB1 /etc/udev/devices/pilot
    +
    + +

    ISDN

    +

    + If you have udev >= 032-5: +

    +
    +
    +/sbin/MAKEDEV -d /etc/udev/devices isdn
    +
    + + + + + +
    +
     
    +
     
    +
    + + + + + + + + From d514329ee2d5614078649a425674d83e0211c1b9 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Thu, 19 May 2005 22:24:38 +0100 Subject: [PATCH 1302/4284] [PATCH] update cdsymlinks to latest version diff -ur udev-057.orig/extras/cdsymlinks.c udev-057/extras/cdsymlinks.c --- extras/cdsymlinks.c | 149 ++++++++++++++++++++++++----------------- extras/cdsymlinks.conf | 11 ++- extras/cdsymlinks.sh | 52 +++++++++----- 3 files changed, 132 insertions(+), 80 deletions(-) diff --git a/extras/cdsymlinks.c b/extras/cdsymlinks.c index 2889ff446c..b6bc96dc6f 100644 --- a/extras/cdsymlinks.c +++ b/extras/cdsymlinks.c @@ -11,7 +11,12 @@ * BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" * (this last one is "just in case") * - * (c) 2004 Darren Salt + * (c) 2004, 2005 Darren Salt + * + * Contributors: + * - J A Magallon (bug fixes) + * + * Last modified: 2005-02-15 */ #define _GNU_SOURCE @@ -56,6 +61,7 @@ struct list_t { /* Configuration variables */ static struct list_t allowed_output = {0}; static int numbered_links = 1; +static int link_zero = 0; /* Available devices */ static struct list_t Devices = {0}; @@ -65,14 +71,40 @@ static struct list_t Devices = {0}; */ static struct list_t cap_DVDRAM = {0}, cap_DVDRW = {0}, cap_DVD = {0}, cap_CDRW = {0}, cap_CDR = {0}, cap_CDWMRW = {0}, - cap_CDMRW = {0}; + cap_CDMRW = {0}, cap_CDRAM = {0}; /* Device capabilities by name */ static struct list_t dev_DVDRAM = {0}, dev_DVDRW = {0}, dev_DVD = {0}, dev_CDRW = {0}, dev_CDR = {0}, dev_CDWMRW = {0}, - dev_CDMRW = {0}; + dev_CDMRW = {0}, dev_CDRAM = {0}; #define dev_CD Devices +typedef struct { + struct list_t *cap, *dev; + const char label[8], symlink[8]; + const char *captext; + int captextlen; +} cap_dev_t; + +#define CAPDEV(X) &cap_##X, &dev_##X + +static const cap_dev_t cap_dev_info[] = { + { NULL, &dev_CD, "CD", "cdrom", NULL, 0 }, + { CAPDEV(CDR), "CDR", "cd-r", "Can write CD-R:", 15 }, + { CAPDEV(CDRW), "CDRW", "cdrw", "Can write CD-RW:", 16 }, + { CAPDEV(DVD), "DVD", "dvd", "Can read DVD:", 13 }, + { CAPDEV(DVDRW), "DVDRW", "dvdrw", "Can write DVD-R:", 16 }, + { CAPDEV(DVDRAM), "DVDRAM", "dvdram", "Can write DVD-RAM:", 18 }, + { CAPDEV(CDMRW), "CDMRW", "cdm", "Can read MRW:", 13 }, /* CDC-MRW R */ + { CAPDEV(CDWMRW), "CDWMRW", "cdmrw", "Can write MRW:", 14 }, /* CDC-MRW W */ + { CAPDEV(CDRAM), "CDRAM", "cdram", "Can write RAM:", 14 }, /* CDC-RAM W */ + { NULL } +}; + +#define foreach_cap_dev(loop) \ + for ((loop) = cap_dev_info; (loop)->label[0]; ++(loop)) +#define foreach_cap_dev_noCD(loop) \ + for ((loop) = cap_dev_info + 1; (loop)->label[0]; ++(loop)) /* * Some library-like bits first... @@ -218,7 +250,7 @@ static void list_assign_split (struct list_t *list, char *text) { char *token = strchr (text, ':'); - token = strtok (token ? token + 1 : text, " \t"); + token = strtok (token ? token + 1 : text, " \t\n"); while (token) { list_prepend (list, token); @@ -267,8 +299,10 @@ read_defaults (void) list_delete (&allowed_output); list_assign_split (&allowed_output, p.we_wordv[0] + 7); } - else if (!strncmp (p.we_wordv[0], "NUMBERED_LINKS=", 14)) - numbered_links = atoi (p.we_wordv[0] + 14); + else if (!strncmp (p.we_wordv[0], "NUMBERED_LINKS=", 15)) + numbered_links = atoi (p.we_wordv[0] + 15); + else if (!strncmp (p.we_wordv[0], "LINK_ZERO=", 15)) + link_zero = atoi (p.we_wordv[0] + 15); break; } /* fall through */ @@ -315,20 +349,16 @@ populate_capability_lists (void) { if (!strncasecmp (text, "drive name", 10)) list_assign_split (&Devices, text); - else if (!strncasecmp (text, "Can write DVD-RAM", 17)) - list_assign_split (&cap_DVDRAM, text); - else if (!strncasecmp (text, "Can write DVD-R", 15)) - list_assign_split (&cap_DVDRW, text); - else if (!strncasecmp (text, "Can read DVD", 12)) - list_assign_split (&cap_DVD, text); - else if (!strncasecmp (text, "Can write CD-RW", 15)) - list_assign_split (&cap_CDRW, text); - else if (!strncasecmp (text, "Can write CD-R", 14)) - list_assign_split (&cap_CDR, text); - else if (!strncasecmp (text, "Can read MRW", 14)) - list_assign_split (&cap_CDMRW, text); - else if (!strncasecmp (text, "Can write MRW", 14)) - list_assign_split (&cap_CDWMRW, text); + else + { + const cap_dev_t *cap; + foreach_cap_dev_noCD (cap) + if (!strncasecmp (text, cap->captext, cap->captextlen)) + { + list_assign_split (cap->cap, text); + break; + } + } } if (!feof (info)) errexit ("error accessing CD/DVD info"); @@ -341,7 +371,8 @@ populate_capability_lists (void) * taking into account existing links and the capability list for type LINK. */ static void -do_output (const char *name, const char *link, const struct list_t *dev) +do_output (const char *name, const char *link, const struct list_t *dev, + int do_link_zero) { const struct list_item_t *i = (const struct list_item_t *)dev; if (!i->next) @@ -406,6 +437,8 @@ do_output (const char *name, const char *link, const struct list_t *dev) /* Existing symlink found - don't output a new one. * If ISDEV, we output the name of the existing symlink. */ + if (do_link_zero) + return; present = 1; if (isdev) printf (" %s", list_nth (&devls, li)->data); @@ -415,14 +448,19 @@ do_output (const char *name, const char *link, const struct list_t *dev) if (!present) { char buf[256]; - snprintf (buf, sizeof (buf), count ? "%s%d" : "%s", link, count); + snprintf (buf, sizeof (buf), count || do_link_zero ? "%s%d" : "%s", + link, count); /* Find the next available (not present) symlink name. * We always need to do this for reasons of output consistency: if a * symlink is created by udev as a result of use of this program, we * DON'T want different output! */ while (list_search (&devls, buf)) + { + if (do_link_zero) + return; snprintf (buf, sizeof (buf), "%s%d", link, ++count); + } /* If ISDEV, output it. */ if (isdev && (numbered_links || count == 0)) printf (" %s", buf); @@ -431,6 +469,8 @@ do_output (const char *name, const char *link, const struct list_t *dev) */ if (!list_search (&devls, buf)) { + if (do_link_zero) + return; list_append (&devls, buf); ++count; } @@ -458,6 +498,8 @@ populate_device_list (struct list_t *out, const struct list_t *caps) int main (int argc, char *argv[]) { + const cap_dev_t *capdev; + progname = argv[0]; debug = argc > 2 && !strcmp (argv[2], "-d"); @@ -470,62 +512,43 @@ main (int argc, char *argv[]) read_defaults (); populate_capability_lists (); - /* Construct the device lists from the capability lists. */ - populate_device_list (&dev_DVDRAM, &cap_DVDRAM); - populate_device_list (&dev_DVDRW, &cap_DVDRW); - populate_device_list (&dev_DVD, &cap_DVD); - populate_device_list (&dev_CDRW, &cap_CDRW); - populate_device_list (&dev_CDR, &cap_CDR); - populate_device_list (&dev_CDWMRW, &cap_CDWMRW); - populate_device_list (&dev_CDMRW, &cap_CDMRW); - /* (All devices can read CDs.) */ + /* Construct the device lists from the capability lists. + * (We assume that all relevant devices can read CDs.) + */ + foreach_cap_dev_noCD (capdev) + populate_device_list (capdev->dev, capdev->cap); if (debug) { -#define printdev(DEV) \ - printf ("%-7s:", #DEV); \ - list_print (&cap_##DEV, stdout); \ - list_print (&dev_##DEV, stdout); \ - puts (""); - printf ("Devices:"); const struct list_item_t *item = (const struct list_item_t *)&Devices; while ((item = item->next) != NULL) printf (" %s", item->data); - puts (""); - printdev (DVDRAM); - printdev (DVDRW); - printdev (DVD); - printdev (CDRW); - printdev (CDR); - printdev (CDWMRW); - printdev (CDMRW); - - printf ("CDROM : (all)"); + printf ("\nCDROM : (all)"); item = (const struct list_item_t *)&dev_CD; while ((item = item->next) != NULL) printf (" %s", item->data); puts (""); + + foreach_cap_dev_noCD (capdev) + { + printf ("%-10s:", capdev->label); + list_print (capdev->cap, stdout); + list_print (capdev->dev, stdout); + puts (""); + } + } /* Write the symlink names. */ - if (list_search (&allowed_output, "CD")) - do_output (argv[1], "cdrom", &dev_CD); - if (list_search (&allowed_output, "CDR")) - do_output (argv[1], "cd-r", &dev_CDR); - if (list_search (&allowed_output, "CDRW")) - do_output (argv[1], "cdrw", &dev_CDRW); - if (list_search (&allowed_output, "DVD")) - do_output (argv[1], "dvd", &dev_DVD); - if (list_search (&allowed_output, "DVDRW")) - do_output (argv[1], "dvdrw", &dev_DVDRW); - if (list_search (&allowed_output, "DVDRAM")) - do_output (argv[1], "dvdram", &dev_DVDRAM); - if (list_search (&allowed_output, "CDMRW")) - do_output (argv[1], "cdmrw", &dev_CDMRW); - if (list_search (&allowed_output, "CDWMRW")) - do_output (argv[1], "cdwmrw", &dev_CDWMRW); + foreach_cap_dev (capdev) + if (list_search (&allowed_output, capdev->label)) + { + do_output (argv[1], capdev->symlink, capdev->dev, 0); + if (link_zero) + do_output (argv[1], capdev->symlink, capdev->dev, 1); + } puts (""); return 0; diff --git a/extras/cdsymlinks.conf b/extras/cdsymlinks.conf index e50a2e6082..e4c5ee2231 100644 --- a/extras/cdsymlinks.conf +++ b/extras/cdsymlinks.conf @@ -1,8 +1,13 @@ # Configuration file for cdsymlinks # Output links for these types of devices. -# Allowed keywords are CD, CDR, CDRW, DVD, DVDRW, DVDRAM, CDMRW, CDWMRW. +# Allowed keywords are: corresponding to device names: +# CD CDR CDRW cdrom cd-r cdrw +# DVD DVDRW DVDRAM dvd dvdrw dvdram +# CDMRW CDWMRW cdm cdmrw +# CDRAM cdram # Other words are accepted but ignored. +# Devices with multiple recognised capabilities WILL get multiple links. #OUTPUT="CD CDRW DVD DVDRW DVDRAM" # Whether to output numbered links. @@ -10,3 +15,7 @@ # 0 = don't output 'cdrom1', 'dvd1' etc. # We always output 'cdrom', 'dvd' etc. for the best-match devices. #NUMBERED_LINKS=1 + +# Whether to output link 0 along with each unnumbered link. +# (No effect if NUMBERED_LINKS=0.) +#LINK_ZERO=0 diff --git a/extras/cdsymlinks.sh b/extras/cdsymlinks.sh index b2702e0063..592de365cb 100644 --- a/extras/cdsymlinks.sh +++ b/extras/cdsymlinks.sh @@ -1,6 +1,7 @@ #! /bin/sh -e # -# Map cdrom, cdm, cdmrw, cd-r, cdrw, dvd, dvdrw, dvdram to suitable devices. +# Map cdrom, cd-r, cdrw, dvd, dvdrw, dvdram, cdm, cdmrw, cdram +# to suitable devices. # Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices. # First parameter is the kernel device name. # Second parameter, if present, must be "-d" => output the full mapping. @@ -11,13 +12,16 @@ # BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" # (this last one is "just in case") # -# (c) 2004 Darren Salt +# (c) 2004, 2005 Darren Salt +# +# Last modified: 2005-02-15 test -e /proc/sys/dev/cdrom/info || exit 0 # Defaults; it's better that you alter them in /etc/udev/cdsymlinks.conf OUTPUT='CD CDRW DVD DVDRW DVDRAM' NUMBERED_LINKS=1 +LINK_ZERO=0 test -e /etc/udev/cdsymlinks.conf && . /etc/udev/cdsymlinks.conf @@ -61,6 +65,7 @@ setArray CDRWs `sed -re '/^Can write CD-RW:/I! d; s/.*://' /proc/sys/dev/cdr setArray CDRs `sed -re '/^Can write CD-R:/I! d; s/.*://' /proc/sys/dev/cdrom/info` setArray CDMRWs `sed -re '/^Can write MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` setArray CDMs `sed -re '/^Can read MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` +setArray CDRAMs `sed -re '/^Can write RAM:/I! d; s/.*://' /proc/sys/dev/cdrom/info` # How many devices do we have? NumDevs=$(($DEVICES-1)) @@ -80,6 +85,7 @@ for i in $Count; do test "`ix CDRs $i`" != '' || ixs CDRs $i 0 test "`ix CDMRWs $i`" != '' || ixs CDMRWs $i 0 test "`ix CDMs $i`" != '' || ixs CDMs $i 0 + test "`ix CDRAMs $i`" != '' || ixs CDRAMs $i 0 done DVDRAM='' @@ -89,6 +95,7 @@ CDRW='' CDR='' CDMRW='' CDM='' +CDRAM='' CD='' # Calculate symlink->device mappings. @@ -116,6 +123,9 @@ done for i in $Count; do test "`ix CDMs $i`" = 1 && CDM="$CDM `ix DEVICES $i`" done +for i in $Count; do + test "`ix CDRAMs $i`" = 1 && CDRAM="$CDRAM `ix DEVICES $i`" +done for i in $Count; do CD="$CD `ix DEVICES $i`" done @@ -123,21 +133,22 @@ done # Debug output if test "$DEBUG" = 1; then echo 'Devices:' `for i in $Count; do ix DEVICES $i; echo -n \ ; done` - echo 'DVDRAM :' `for i in $Count; do ix DVDRAMs $i; echo -n \ ; done` $DVDRAM - echo 'DVDRW :' `for i in $Count; do ix DVDRWs $i; echo -n \ ; done` $DVDRW - echo 'DVD :' `for i in $Count; do ix DVDs $i; echo -n \ ; done` $DVD - echo 'CDRW :' `for i in $Count; do ix CDRWs $i; echo -n \ ; done` $CDRW - echo 'CD-R :' `for i in $Count; do ix CDRs $i; echo -n \ ; done` $CDR - echo 'CDMRW :' `for i in $Count; do ix CDMRWs $i; echo -n \ ; done` $CDMRW - echo 'CDM :' `for i in $Count; do ix CDMs $i; echo -n \ ; done` $CDM echo 'CDROM : (all)' $CD + echo 'CD-R :' `for i in $Count; do ix CDRs $i; echo -n \ ; done` $CDR + echo 'CDRW :' `for i in $Count; do ix CDRWs $i; echo -n \ ; done` $CDRW + echo 'DVD :' `for i in $Count; do ix DVDs $i; echo -n \ ; done` $DVD + echo 'DVDRW :' `for i in $Count; do ix DVDRWs $i; echo -n \ ; done` $DVDRW + echo 'DVDRAM :' `for i in $Count; do ix DVDRAMs $i; echo -n \ ; done` $DVDRAM + echo 'CDMRW :' `for i in $Count; do ix CDMRWs $i; echo -n \ ; done` $CDMRW + echo 'CDWMRW :' `for i in $Count; do ix CDMs $i; echo -n \ ; done` $CDM + echo 'CDRAM :' `for i in $Count; do ix CDRAMs $i; echo -n \ ; done` $CDRAM fi # Prepare symlink names output -output () { +do_output () { test "`eval echo '$'$3`" = '' && return local i - local COUNT='' + local COUNT=$4 local DEVLS="`ls -dl \"/dev/$2\" \"/dev/$2\"[0-9]* 2>/dev/null`" local PRESENT="`echo "$DEVLS" | sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> [^[:space:]]+$!\1!'`" @@ -148,6 +159,7 @@ output () { if test "$DEVPRESENT" != ""; then # Existing symlinks found - don't output a new one. # If the target dev ($1) is the current dev ($i), we output their names. + test -z "$4" || return; test "$1" = "$i" && echo " $DEVPRESENT" | sed -e 'N; $ s/\n/ /' else # If we found no existing symlinks for the target device... @@ -156,15 +168,17 @@ output () { # symlink is created by udev as a result of use of this program, we # DON'T want different output! until notin PRESENT "$2$COUNT"; do + test -z "$4" || return; COUNT=$(($COUNT+1)) done # If the target dev ($1) is the current dev ($i), we output its name. - if test $(($NUMBERED_LINKS)) -ne 0 || test "$COUNT" = ''; then - test "$i" = "$1" && echo -n " $2$COUNT" + if test $(($NUMBERED_LINKS)) -ne 0 || test -z "$COUNT"; then + test "$i" != "$1" || echo -n " $2$COUNT" fi # If the link isn't in our "existing links" list, add it and increment # our counter. - if test ! -e "/dev/$2$COUNT"; then + if notin PRESENT "$2$COUNT"; then + test -z "$4" || return; PRESENT="$PRESENT\n$2$COUNT" COUNT=$(($COUNT+1)) fi @@ -172,13 +186,19 @@ output () { done } +output () { + do_output "$@" + test $(($LINK_ZERO)) -eq 0 || do_output "$@" 0 +} + # And output it notin OUTPUT CD || echo -n "`output "$1" cdrom CD`" -notin OUTPUT CDMRW || echo -n "`output "$1" cdmrw CDM`" -notin OUTPUT CDWMRW || echo -n "`output "$1" cdwmrw CDMRW`" notin OUTPUT CDR || echo -n "`output "$1" cd-r CDR`" notin OUTPUT CDRW || echo -n "`output "$1" cdrw CDRW`" notin OUTPUT DVD || echo -n "`output "$1" dvd DVD`" notin OUTPUT DVDRW || echo -n "`output "$1" dvdrw DVDRW`" notin OUTPUT DVDRAM || echo -n "`output "$1" dvdram DVDRAM`" +notin OUTPUT CDMRW || echo -n "`output "$1" cdmrw CDM`" +notin OUTPUT CDWMRW || echo -n "`output "$1" cdwmrw CDMRW`" +notin OUTPUT CDRAM || echo -n "`output "$1" cdram CDRAM`" echo From db60d377b0c2a6d3d64b9775c581309f04c11b8e Mon Sep 17 00:00:00 2001 From: Greg KH Date: Fri, 20 May 2005 13:18:28 -0700 Subject: [PATCH 1303/4284] 058 release --- ChangeLog | 27 +++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5eb72461ec..3942d319d5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 2e5dd5d9cb..470ab9927f 100644 --- a/Makefile +++ b/Makefile @@ -47,7 +47,7 @@ SENDER = udevsend INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 057 +VERSION = 058 INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev diff --git a/udev.spec b/udev.spec index a9d1c5fb22..28f19565da 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 056 +Version: 058 Release: 1 License: GPL Group: Utilities/System From 5e65ab9a191268fec7cddf6b7d8c0fefd2a6b920 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Fri, 20 May 2005 13:22:05 -0700 Subject: [PATCH 1304/4284] Fix makefile to allow 'make release' to work with git --- Makefile | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 470ab9927f..dc3930b46b 100644 --- a/Makefile +++ b/Makefile @@ -317,35 +317,10 @@ spotless: clean $(MAKE) -C klibc SUBDIRS=klibc spotless rm -rf klibc/.install -DISTFILES = $(shell find . \( -not -name '.' \) -print | grep -v -e CVS -e "\.tar\.gz" -e "\/\." -e releases -e BitKeeper -e SCCS -e test/sys | sort ) -DISTDIR := $(RELEASE_NAME) -srcdir = . release: spotless - -rm -rf $(DISTDIR) - mkdir $(DISTDIR) - chmod 777 $(DISTDIR) - bk export -w $(DISTDIR) - tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz - rm -rf $(DISTDIR) + git-tar-tree HEAD $(RELEASE_NAME) | gzip -9v > $(RELEASE_NAME).tar.gz @echo "$(RELEASE_NAME).tar.gz created" - -small_release: $(DISTFILES) spotless -# @echo $(DISTFILES) - @-rm -rf $(DISTDIR) - @mkdir $(DISTDIR) - @-chmod 777 $(DISTDIR) - @for file in $(DISTFILES); do \ - if test -d $$file; then \ - mkdir $(DISTDIR)/$$file; \ - else \ - cp -p $$file $(DISTDIR)/$$file; \ - fi; \ - done - @tar -c $(DISTDIR) | gzip -9 > $(RELEASE_NAME).tar.gz - @rm -rf $(DISTDIR) - @echo "Built $(RELEASE_NAME).tar.gz" - install-config: $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d @if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \ From 88f4b6485e2a551de55fd9d39aeef89debf3121c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 04:38:10 +0200 Subject: [PATCH 1305/4284] udevd: listen for netlink events After the first valid netlink-event all event with a serial number received on the udevsend socket will be ignored. Signed-off-by: Kay Sievers --- udev.c | 10 ++- udevd.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 160 insertions(+), 36 deletions(-) diff --git a/udev.c b/udev.c index ce9b42f30d..2be4c35740 100644 --- a/udev.c +++ b/udev.c @@ -54,8 +54,10 @@ void log_message(int priority, const char *format, ...) } #endif -/* decide if we should manage the whole hotplug event - * for now look if the kernel calls udevsend instead of /sbin/hotplug +/* Decide if we should manage the whole uevent, including multiplexing + * of the hotplug directories. + * For now look if the kernel calls udevsend instead of /sbin/hotplug, + * or the uevent-helper in /proc/sys/kernel/hotplug is empty. */ static int manage_hotplug_event(void) { char helper[256]; @@ -70,13 +72,15 @@ static int manage_hotplug_event(void) { if (fd < 0) return 0; - len = read(fd, helper, 256); + len = read(fd, helper, sizeof(helper)-1); close(fd); if (len < 0) return 0; helper[len] = '\0'; + if (helper[0] == '\0' || helper[0] == '\n') + return 1; if (strstr(helper, "udevsend")) return 1; diff --git a/udevd.c b/udevd.c index 91033b0688..68e3a75f33 100644 --- a/udevd.c +++ b/udevd.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "list.h" #include "udev_libc_wrapper.h" @@ -49,6 +50,7 @@ /* global variables*/ static int udevsendsock; +static int ueventsock; static pid_t sid; static int pipefds[2]; @@ -126,7 +128,8 @@ static void msg_queue_insert(struct hotplug_msg *msg) break; if (loop_msg->seqnum == msg->seqnum) { - info("ignoring duplicate message seq %llu", msg->seqnum); + dbg("ignoring duplicate message seq %llu", msg->seqnum); + free(msg); return; } } @@ -154,6 +157,8 @@ static void execute_udev(struct hotplug_msg *msg) switch (pid) { case 0: /* child */ + if (ueventsock != -1) + close(ueventsock); close(udevsendsock); logging_close(); @@ -416,13 +421,60 @@ recheck: } } +static struct hotplug_msg *get_msg_from_envbuf(const char *buf, int buf_size) +{ + int bufpos; + int i; + struct hotplug_msg *msg; + + msg = malloc(sizeof(struct hotplug_msg) + buf_size); + if (msg == NULL) + return NULL; + memset(msg, 0x00, sizeof(struct hotplug_msg) + buf_size); + + /* copy environment buffer and reconstruct envp */ + memcpy(msg->envbuf, buf, buf_size); + bufpos = 0; + for (i = 0; (bufpos < buf_size) && (i < HOTPLUG_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]; + + if (strncmp(key, "DEVPATH=", 8) == 0) + msg->devpath = &key[8]; + + if (strncmp(key, "SUBSYSTEM=", 10) == 0) + msg->subsystem = &key[10]; + + if (strncmp(key, "SEQNUM=", 7) == 0) + msg->seqnum = strtoull(&key[7], NULL, 10); + + if (strncmp(key, "PHYSDEVPATH=", 12) == 0) + msg->physdevpath = &key[12]; + + if (strncmp(key, "TIMEOUT=", 8) == 0) + msg->timeout = strtoull(&key[8], NULL, 10); + } + msg->envp[i++] = "UDEVD_EVENT=1"; + msg->envp[i] = NULL; + + return msg; +} + /* receive the udevsend message and do some sanity checks */ static struct hotplug_msg *get_udevsend_msg(void) { static struct udevsend_msg usend_msg; struct hotplug_msg *msg; - int bufpos; - int i; ssize_t size; struct msghdr smsg; struct cmsghdr *cmsg; @@ -467,46 +519,60 @@ static struct hotplug_msg *get_udevsend_msg(void) envbuf_size = size - offsetof(struct udevsend_msg, envbuf); dbg("envbuf_size=%i", envbuf_size); - msg = malloc(sizeof(struct hotplug_msg) + envbuf_size); + msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size); if (msg == NULL) return NULL; - memset(msg, 0x00, sizeof(struct hotplug_msg) + envbuf_size); + return msg; +} - /* copy environment buffer and reconstruct envp */ - memcpy(msg->envbuf, usend_msg.envbuf, envbuf_size); - bufpos = 0; - for (i = 0; (bufpos < envbuf_size) && (i < HOTPLUG_NUM_ENVP-2); i++) { - int keylen; - char *key; +/* receive the kernel user event message and do some sanity checks */ +static struct hotplug_msg *get_uevent_msg(void) +{ + struct hotplug_msg *msg; + int bufpos; + ssize_t size; + static char buffer[HOTPLUG_BUFFER_SIZE + 512]; + char *pos; - 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); + size = recv(ueventsock, &buffer, sizeof(buffer), 0); + if (size < 0) { + if (errno != EINTR) + dbg("unable to receive udevsend message"); + return NULL; + } - /* remember some keys for further processing */ - if (strncmp(key, "ACTION=", 7) == 0) - msg->action = &key[7]; + if ((size_t)size > sizeof(buffer)-1) + size = sizeof(buffer)-1; + buffer[size] = '\0'; + dbg("uevent_size=%i", size); - if (strncmp(key, "DEVPATH=", 8) == 0) - msg->devpath = &key[8]; + /* start of event payload */ + bufpos = strlen(buffer)+1; + msg = get_msg_from_envbuf(&buffer[bufpos], size-bufpos); + if (msg == NULL) + return NULL; - if (strncmp(key, "SUBSYSTEM=", 10) == 0) - msg->subsystem = &key[10]; + /* validate message */ + pos = strchr(buffer, '@'); + if (pos == NULL) { + dbg("invalid uevent '%s'", buffer); + free(msg); + return NULL; + } + pos[0] = '\0'; - if (strncmp(key, "SEQNUM=", 7) == 0) - msg->seqnum = strtoull(&key[7], NULL, 10); + if (msg->action == NULL) { + dbg("no ACTION in payload found, skip event '%s'", buffer); + free(msg); + return NULL; + } - if (strncmp(key, "PHYSDEVPATH=", 12) == 0) - msg->physdevpath = &key[12]; - - if (strncmp(key, "TIMEOUT=", 8) == 0) - msg->timeout = strtoull(&key[8], NULL, 10); + if (strcmp(msg->action, buffer) != 0) { + dbg("ACTION in payload does not match uevent, skip event '%s'", buffer); + free(msg); + return NULL; } - msg->envp[i++] = "UDEVD_EVENT=1"; - msg->envp[i] = NULL; return msg; } @@ -622,6 +688,34 @@ static int init_udevsend_socket(void) return 0; } +static int init_uevent_socket(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 = 0xffffffff; + + ueventsock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); + if (ueventsock == -1) { + dbg("error getting socket, %s", strerror(errno)); + return -1; + } + + retval = bind(ueventsock, (struct sockaddr *) &snl, + sizeof(struct sockaddr_nl)); + if (retval < 0) { + dbg("bind failed, %s", strerror(errno)); + close(ueventsock); + ueventsock = -1; + return -1; + } + + return 0; +} + int main(int argc, char *argv[], char *envp[]) { struct sysinfo info; @@ -631,6 +725,7 @@ int main(int argc, char *argv[], char *envp[]) struct sigaction act; fd_set readfds; const char *udevd_expected_seqnum; + int uevent_active = 0; logging_init("udevd"); udev_init_config(); @@ -716,6 +811,10 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGALRM, &act, NULL); sigaction(SIGCHLD, &act, NULL); + if (init_uevent_socket() < 0) { + dbg("uevent socket not available"); + } + if (init_udevsend_socket() < 0) { if (errno == EADDRINUSE) dbg("another udevd running, exit"); @@ -745,6 +844,8 @@ int main(int argc, char *argv[], char *envp[]) FD_ZERO(&readfds); FD_SET(udevsendsock, &readfds); + if (ueventsock != -1) + FD_SET(ueventsock, &readfds); FD_SET(pipefds[0], &readfds); maxsockplus = udevsendsock+1; while (1) { @@ -761,8 +862,27 @@ int main(int argc, char *argv[], char *envp[]) if (FD_ISSET(udevsendsock, &workreadfds)) { msg = get_udevsend_msg(); - if (msg) + if (msg) { + /* discard kernel messages if netlink is active */ + if (uevent_active && msg->seqnum != 0) { + dbg("skip kernel udevsend message, netlink is active"); + free(msg); + continue; + } msg_queue_insert(msg); + } + } + + if (FD_ISSET(ueventsock, &workreadfds)) { + msg = get_uevent_msg(); + if (msg) { + msg_queue_insert(msg); + /* disable udevsend with first netlink message */ + if (!uevent_active) { + info("netlink message received, disable kernel udevsend messages"); + uevent_active = 1; + } + } } if (FD_ISSET(pipefds[0], &workreadfds)) From 3b47c7394d042b8a3fcf426920a926d4ffedacad Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 04:41:09 +0200 Subject: [PATCH 1306/4284] udevd: add udevcontrol Controls the behavior of the running daemon. Currently only stopping and starting of the execution queue is supported. Signed-off-by: Kay Sievers --- Makefile | 12 +++- udevcontrol.c | 107 ++++++++++++++++++++++++++++++++ udevd.c | 167 +++++++++++++++++++++++++++----------------------- udevd.h | 23 ++++--- udevsend.c | 9 +-- 5 files changed, 230 insertions(+), 88 deletions(-) create mode 100644 udevcontrol.c diff --git a/Makefile b/Makefile index dc3930b46b..896a58a306 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ V=false ROOT = udev DAEMON = udevd SENDER = udevsend +CONTROL = udevcontrol INFO = udevinfo TESTER = udevtest STARTER = udevstart @@ -205,7 +206,7 @@ endif # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) +all: $(ROOT) $(SENDER) $(CONTROL) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -271,6 +272,7 @@ $(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(INFO).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(CONTROL).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) @@ -293,6 +295,10 @@ $(SENDER): $(KLCC) $(SENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(SENDER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ +$(CONTROL): $(KLCC) $(CONTROL).o $(OBJS) udevd.h + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CONTROL).o $(OBJS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + $(STARTER): $(KLCC) $(STARTER).o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(STARTER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ @@ -304,7 +310,7 @@ clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) \ - $(SENDER) $(TESTER) $(STARTER) + $(SENDER) $(CONTROL) $(TESTER) $(STARTER) -rm -f ccdv $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ @@ -364,6 +370,7 @@ install: install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) + $(INSTALL_PROGRAM) -D $(CONTROL) $(DESTDIR)$(sbindir)/$(CONTROL) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) @@ -387,6 +394,7 @@ uninstall: uninstall-man uninstall-dev.d - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) + - rm $(sbindir)/$(CONTROL) - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) - rm $(usrbindir)/$(TESTER) diff --git a/udevcontrol.c b/udevcontrol.c new file mode 100644 index 0000000000..6a278a04c1 --- /dev/null +++ b/udevcontrol.c @@ -0,0 +1,107 @@ +/* + * udevcontrol.c + * + * Userspace devfs + * + * 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "udevd.h" +#include "logging.h" + +/* global variables */ +static int sock = -1; + +#ifdef USE_LOG +void log_message (int level, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif + + +int main(int argc, char *argv[], char *envp[]) +{ + static struct udevd_msg usend_msg; + struct sockaddr_un saddr; + socklen_t addrlen; + int retval = 1; + + logging_init("udevcontrol"); + dbg("version %s", UDEV_VERSION); + + if (argc != 2) { + info("usage: udevcontrol \n"); + goto exit; + } + + memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); + strcpy(usend_msg.magic, UDEV_MAGIC); + + if (strstr(argv[1], "stop_exec_queue")) + usend_msg.type = UDEVD_STOP_EXEC_QUEUE; + else if (strstr(argv[1], "start_exec_queue")) + usend_msg.type = UDEVD_START_EXEC_QUEUE; + else { + info("unknown command\n"); + goto exit; + } + + sock = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (sock == -1) { + info("error getting socket"); + 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_SOCK_PATH); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + + retval = sendto(sock, &usend_msg, sizeof(usend_msg), 0, (struct sockaddr *)&saddr, addrlen); + if (retval == -1) + info("error sending message (%s)", strerror(errno)); + + close(sock); + +exit: + logging_close(); + + return retval; +} diff --git a/udevd.c b/udevd.c index 68e3a75f33..371d715716 100644 --- a/udevd.c +++ b/udevd.c @@ -49,17 +49,18 @@ #include "logging.h" /* global variables*/ -static int udevsendsock; -static int ueventsock; +static int udevd_sock; +static int uevent_nl_sock; static pid_t sid; static int pipefds[2]; static long startup_time; -static unsigned long long expected_seqnum = 0; +static unsigned long long expected_seqnum; static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int sig_flag; static int run_exec_q; +static int stop_exec_q; static LIST_HEAD(msg_list); static LIST_HEAD(exec_list); @@ -88,23 +89,23 @@ void log_message (int priority, const char *format, ...) static void msg_dump_queue(void) { #ifdef DEBUG - struct hotplug_msg *msg; + struct uevent_msg *msg; list_for_each_entry(msg, &msg_list, node) dbg("sequence %llu in queue", msg->seqnum); #endif } -static void run_queue_delete(struct hotplug_msg *msg) +static void run_queue_delete(struct uevent_msg *msg) { list_del(&msg->node); free(msg); } /* orders the message in the queue by sequence number */ -static void msg_queue_insert(struct hotplug_msg *msg) +static void msg_queue_insert(struct uevent_msg *msg) { - struct hotplug_msg *loop_msg; + struct uevent_msg *loop_msg; struct sysinfo info; if (msg->seqnum == 0) { @@ -148,7 +149,7 @@ static void msg_queue_insert(struct hotplug_msg *msg) } /* forks event and removes event from run queue when finished */ -static void execute_udev(struct hotplug_msg *msg) +static void execute_udev(struct uevent_msg *msg) { char *const argv[] = { "udev", msg->subsystem, NULL }; pid_t pid; @@ -157,9 +158,9 @@ static void execute_udev(struct hotplug_msg *msg) switch (pid) { case 0: /* child */ - if (ueventsock != -1) - close(ueventsock); - close(udevsendsock); + if (uevent_nl_sock != -1) + close(uevent_nl_sock); + close(udevd_sock); logging_close(); setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); @@ -298,9 +299,9 @@ static int compare_devpath(const char *running, const char *waiting) } /* returns still running task for the same device, its parent or its physical device */ -static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) +static struct uevent_msg *running_with_devpath(struct uevent_msg *msg) { - struct hotplug_msg *loop_msg; + struct uevent_msg *loop_msg; if (msg->devpath == NULL) return NULL; @@ -329,9 +330,9 @@ static struct hotplug_msg *running_with_devpath(struct hotplug_msg *msg) /* exec queue management routine executes the events and serializes events in the same sequence */ static void exec_queue_manager(void) { - struct hotplug_msg *loop_msg; - struct hotplug_msg *tmp_msg; - struct hotplug_msg *msg; + struct uevent_msg *loop_msg; + struct uevent_msg *tmp_msg; + struct uevent_msg *msg; int running; running = running_processes(); @@ -364,7 +365,7 @@ static void exec_queue_manager(void) } } -static void msg_move_exec(struct hotplug_msg *msg) +static void msg_move_exec(struct uevent_msg *msg) { list_move_tail(&msg->node, &exec_list); run_exec_q = 1; @@ -376,8 +377,8 @@ static void msg_move_exec(struct hotplug_msg *msg) /* msg queue management routine handles the timeouts and dispatches the events */ static void msg_queue_manager(void) { - struct hotplug_msg *loop_msg; - struct hotplug_msg *tmp_msg; + struct uevent_msg *loop_msg; + struct uevent_msg *tmp_msg; struct sysinfo info; long msg_age = 0; static int timeout = EVENT_INIT_TIMEOUT_SEC; @@ -421,21 +422,21 @@ recheck: } } -static struct hotplug_msg *get_msg_from_envbuf(const char *buf, int buf_size) +static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) { int bufpos; int i; - struct hotplug_msg *msg; + struct uevent_msg *msg; - msg = malloc(sizeof(struct hotplug_msg) + buf_size); + msg = malloc(sizeof(struct uevent_msg) + buf_size); if (msg == NULL) return NULL; - memset(msg, 0x00, sizeof(struct hotplug_msg) + buf_size); + memset(msg, 0x00, sizeof(struct 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 < HOTPLUG_NUM_ENVP-2); i++) { + for (i = 0; (bufpos < buf_size) && (i < UEVENT_NUM_ENVP-2); i++) { int keylen; char *key; @@ -470,11 +471,11 @@ static struct hotplug_msg *get_msg_from_envbuf(const char *buf, int buf_size) return msg; } -/* receive the udevsend message and do some sanity checks */ -static struct hotplug_msg *get_udevsend_msg(void) +/* receive the udevd message from userspace */ +static struct uevent_msg *get_udevd_msg(void) { - static struct udevsend_msg usend_msg; - struct hotplug_msg *msg; + static struct udevd_msg usend_msg; + struct uevent_msg *msg; ssize_t size; struct msghdr smsg; struct cmsghdr *cmsg; @@ -483,9 +484,9 @@ static struct hotplug_msg *get_udevsend_msg(void) char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; int envbuf_size; - memset(&usend_msg, 0x00, sizeof(struct udevsend_msg)); + memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); iov.iov_base = &usend_msg; - iov.iov_len = sizeof(struct udevsend_msg); + iov.iov_len = sizeof(struct udevd_msg); memset(&smsg, 0x00, sizeof(struct msghdr)); smsg.msg_iov = &iov; @@ -493,10 +494,10 @@ static struct hotplug_msg *get_udevsend_msg(void) smsg.msg_control = cred_msg; smsg.msg_controllen = sizeof(cred_msg); - size = recvmsg(udevsendsock, &smsg, 0); + size = recvmsg(udevd_sock, &smsg, 0); if (size < 0) { if (errno != EINTR) - dbg("unable to receive udevsend message"); + dbg("unable to receive udevd message"); return NULL; } cmsg = CMSG_FIRSTHDR(&smsg); @@ -517,28 +518,43 @@ static struct hotplug_msg *get_udevsend_msg(void) return NULL; } - envbuf_size = size - offsetof(struct udevsend_msg, envbuf); - dbg("envbuf_size=%i", envbuf_size); - msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size); - if (msg == NULL) - return NULL; - - return msg; +switch (usend_msg.type) { + case UDEVD_UEVENT: + dbg("udevd message (UEVENT) received"); + envbuf_size = size - offsetof(struct udevd_msg, envbuf); + dbg("envbuf_size=%i", envbuf_size); + msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size); + if (msg == NULL) + return NULL; + return msg; + case UDEVD_STOP_EXEC_QUEUE: + dbg("udevd message (STOP_EXEC_QUEUE) received"); + stop_exec_q = 1; + break; + case UDEVD_START_EXEC_QUEUE: + dbg("udevd message (START_EXEC_QUEUE) received"); + stop_exec_q = 0; + exec_queue_manager(); + break; + default: + dbg("unknown message type"); + } + return NULL; } /* receive the kernel user event message and do some sanity checks */ -static struct hotplug_msg *get_uevent_msg(void) +static struct uevent_msg *get_uevent_msg(void) { - struct hotplug_msg *msg; + struct uevent_msg *msg; int bufpos; ssize_t size; - static char buffer[HOTPLUG_BUFFER_SIZE + 512]; + static char buffer[UEVENT_BUFFER_SIZE + 512]; char *pos; - size = recv(ueventsock, &buffer, sizeof(buffer), 0); + size = recv(uevent_nl_sock, &buffer, sizeof(buffer), 0); if (size < 0) { if (errno != EINTR) - dbg("unable to receive udevsend message"); + dbg("unable to receive udevd message"); return NULL; } @@ -612,7 +628,7 @@ do_write: static void udev_done(int pid) { /* find msg associated with pid and delete it */ - struct hotplug_msg *msg; + struct uevent_msg *msg; list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { @@ -655,7 +671,7 @@ static void user_sighandler(void) } } -static int init_udevsend_socket(void) +static int init_udevd_socket(void) { struct sockaddr_un saddr; socklen_t addrlen; @@ -668,27 +684,27 @@ static int init_udevsend_socket(void) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - udevsendsock = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (udevsendsock == -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(udevsendsock, (struct sockaddr *) &saddr, addrlen); + retval = bind(udevd_sock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { err("bind failed, %s", strerror(errno)); - close(udevsendsock); + close(udevd_sock); return -1; } /* enable receiving of the sender credentials */ - setsockopt(udevsendsock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); + setsockopt(udevd_sock, SOL_SOCKET, SO_PASSCRED, &feature_on, sizeof(feature_on)); return 0; } -static int init_uevent_socket(void) +static int init_uevent_nl_sock(void) { struct sockaddr_nl snl; int retval; @@ -698,18 +714,18 @@ static int init_uevent_socket(void) snl.nl_pid = getpid(); snl.nl_groups = 0xffffffff; - ueventsock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); - if (ueventsock == -1) { + uevent_nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); + if (uevent_nl_sock == -1) { dbg("error getting socket, %s", strerror(errno)); return -1; } - retval = bind(ueventsock, (struct sockaddr *) &snl, + retval = bind(uevent_nl_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl)); if (retval < 0) { dbg("bind failed, %s", strerror(errno)); - close(ueventsock); - ueventsock = -1; + close(uevent_nl_sock); + uevent_nl_sock = -1; return -1; } @@ -725,7 +741,7 @@ int main(int argc, char *argv[], char *envp[]) struct sigaction act; fd_set readfds; const char *udevd_expected_seqnum; - int uevent_active = 0; + int uevent_nl_active = 0; logging_init("udevd"); udev_init_config(); @@ -811,15 +827,15 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGALRM, &act, NULL); sigaction(SIGCHLD, &act, NULL); - if (init_uevent_socket() < 0) { + if (init_uevent_nl_sock() < 0) { dbg("uevent socket not available"); } - if (init_udevsend_socket() < 0) { + if (init_udevd_socket() < 0) { if (errno == EADDRINUSE) dbg("another udevd running, exit"); else - dbg("error initialising udevsend socket: %s", strerror(errno)); + dbg("error initialising udevd socket: %s", strerror(errno)); goto exit; } @@ -843,13 +859,13 @@ int main(int argc, char *argv[], char *envp[]) startup_time = info.uptime; FD_ZERO(&readfds); - FD_SET(udevsendsock, &readfds); - if (ueventsock != -1) - FD_SET(ueventsock, &readfds); + FD_SET(udevd_sock, &readfds); + if (uevent_nl_sock != -1) + FD_SET(uevent_nl_sock, &readfds); FD_SET(pipefds[0], &readfds); - maxsockplus = udevsendsock+1; + maxsockplus = udevd_sock+1; while (1) { - struct hotplug_msg *msg; + struct uevent_msg *msg; fd_set workreadfds = readfds; retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); @@ -860,12 +876,12 @@ int main(int argc, char *argv[], char *envp[]) continue; } - if (FD_ISSET(udevsendsock, &workreadfds)) { - msg = get_udevsend_msg(); + if (FD_ISSET(udevd_sock, &workreadfds)) { + msg = get_udevd_msg(); if (msg) { /* discard kernel messages if netlink is active */ - if (uevent_active && msg->seqnum != 0) { - dbg("skip kernel udevsend message, netlink is active"); + if (uevent_nl_active && msg->seqnum != 0) { + dbg("skip uevent_helper message, netlink is active"); free(msg); continue; } @@ -873,14 +889,14 @@ int main(int argc, char *argv[], char *envp[]) } } - if (FD_ISSET(ueventsock, &workreadfds)) { + if (FD_ISSET(uevent_nl_sock, &workreadfds)) { msg = get_uevent_msg(); if (msg) { msg_queue_insert(msg); /* disable udevsend with first netlink message */ - if (!uevent_active) { - info("netlink message received, disable kernel udevsend messages"); - uevent_active = 1; + if (!uevent_nl_active) { + info("uevent_nl message received, disable uevent_helper messages"); + uevent_nl_active = 1; } } } @@ -906,7 +922,8 @@ int main(int argc, char *argv[], char *envp[]) } run_exec_q = 0; - exec_queue_manager(); + if (!stop_exec_q) + exec_queue_manager(); } } diff --git a/udevd.h b/udevd.h index b3e998b04c..b782d7aacd 100644 --- a/udevd.h +++ b/udevd.h @@ -43,15 +43,24 @@ #define THROTTLE_MAX_RUNNING_CHILDS 10 /* environment buffer, should match the kernel's size in lib/kobject_uevent.h */ -#define HOTPLUG_BUFFER_SIZE 1024 -#define HOTPLUG_NUM_ENVP 32 +#define UEVENT_BUFFER_SIZE 1024 +#define UEVENT_NUM_ENVP 32 -struct udevsend_msg { - char magic[20]; - char envbuf[HOTPLUG_BUFFER_SIZE+256]; +enum udevd_msg_type { + UDEVD_UNKNOWN, + UDEVD_UEVENT, + UDEVD_STOP_EXEC_QUEUE, + UDEVD_START_EXEC_QUEUE, }; -struct hotplug_msg { + +struct udevd_msg { + char magic[32]; + enum udevd_msg_type type; + char envbuf[UEVENT_BUFFER_SIZE+512]; +}; + +struct uevent_msg { struct list_head node; pid_t pid; long queue_time; @@ -61,6 +70,6 @@ struct hotplug_msg { unsigned long long seqnum; char *physdevpath; unsigned int timeout; - char *envp[HOTPLUG_NUM_ENVP+1]; + char *envp[UEVENT_NUM_ENVP+1]; char envbuf[]; }; diff --git a/udevsend.c b/udevsend.c index 8915edacc8..2b92e659e2 100644 --- a/udevsend.c +++ b/udevsend.c @@ -115,7 +115,7 @@ static void run_udev(const char *subsystem) int main(int argc, char *argv[], char *envp[]) { - static struct udevsend_msg usend_msg; + static struct udevd_msg usend_msg; int usend_msg_len; int i; int loop; @@ -144,8 +144,9 @@ int main(int argc, char *argv[], char *envp[]) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - memset(&usend_msg, 0x00, sizeof(struct udevsend_msg)); + memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); strcpy(usend_msg.magic, UDEV_MAGIC); + usend_msg.type = UDEVD_UEVENT; /* copy all keys to send buffer */ for (i = 0; envp[i]; i++) { @@ -161,7 +162,7 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - if (bufpos + keylen >= HOTPLUG_BUFFER_SIZE-1) { + if (bufpos + keylen >= UEVENT_BUFFER_SIZE-1) { err("environment buffer too small, probably not called by the kernel"); continue; } @@ -180,7 +181,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("add 'SUBSYSTEM=%s' to env[%i] buffer from argv", argv[1], i); } - usend_msg_len = offsetof(struct udevsend_msg, envbuf) + bufpos; + usend_msg_len = offsetof(struct udevd_msg, envbuf) + bufpos; dbg("usend_msg_len=%i", usend_msg_len); /* If we can't send, try to start daemon and resend message */ From 0590abd720f0ddc8204539feef4df8987d7a1f8c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 04:44:07 +0200 Subject: [PATCH 1307/4284] udevd: add initsend Transfer stored events from initramfs to the running udevd to replay events after userspace is ready. Signed-off-by: Kay Sievers --- Makefile | 32 ++++--- udev.8.in | 3 +- udevinitsend.c | 231 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 13 deletions(-) create mode 100644 udevinitsend.c diff --git a/Makefile b/Makefile index 896a58a306..2a832f7054 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ V=false ROOT = udev DAEMON = udevd SENDER = udevsend +INITSENDER = udevinitsend CONTROL = udevcontrol INFO = udevinfo TESTER = udevtest @@ -206,7 +207,7 @@ endif # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(CONTROL) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) +all: $(ROOT) $(SENDER) $(INITSENDER) $(CONTROL) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -264,16 +265,17 @@ GEN_MANPAGESIN = udev.8.in $(GEN_MANPAGES): $(GEN_MANPAGESIN) sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ -$(UDEV_OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(SYSFS_OBJS): $(HOST_PROGS) $(KLCC) -$(OBJS): $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(ROOT).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(TESTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(INFO).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(DAEMON).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(SENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(CONTROL).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(STARTER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(UDEV_OBJS): $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(SYSFS_OBJS): $(HEADERS) $(HOST_PROGS) $(KLCC) +$(OBJS): $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(ROOT).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(TESTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(INFO).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(DAEMON).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(SENDER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(INITSENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(CONTROL).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(STARTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(ROOT).o $(OBJS) $(LIB_OBJS) @@ -295,6 +297,10 @@ $(SENDER): $(KLCC) $(SENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(SENDER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ +$(INITSENDER): $(KLCC) $(INITSENDER).o $(OBJS) udevd.h + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(INITSENDER).o $(OBJS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + $(CONTROL): $(KLCC) $(CONTROL).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CONTROL).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ @@ -310,7 +316,7 @@ clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) \ - $(SENDER) $(CONTROL) $(TESTER) $(STARTER) + $(SENDER) $(INITSENDER) $(CONTROL) $(TESTER) $(STARTER) -rm -f ccdv $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ @@ -370,6 +376,7 @@ install: install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) + $(INSTALL_PROGRAM) -D $(INITSENDER) $(DESTDIR)$(sbindir)/$(INITSENDER) $(INSTALL_PROGRAM) -D $(CONTROL) $(DESTDIR)$(sbindir)/$(CONTROL) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) @@ -394,6 +401,7 @@ uninstall: uninstall-man uninstall-dev.d - rm $(sbindir)/$(ROOT) - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) + - rm $(sbindir)/$(INITSENDER) - rm $(sbindir)/$(CONTROL) - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) diff --git a/udev.8.in b/udev.8.in index 5be9308af4..79c4a83d16 100644 --- a/udev.8.in +++ b/udev.8.in @@ -158,7 +158,8 @@ The following keys can get values assigned: .TP .B NAME The name of the node to be created, or the name, the network interface -should be renamed to. +should be renamed to. Only one rule can set the a name, all later rules +with a NAME key will be ignored. .TP .B SYMLINK The name of a symlink targeting the node. Every matching rule can add diff --git a/udevinitsend.c b/udevinitsend.c new file mode 100644 index 0000000000..05c39b99b3 --- /dev/null +++ b/udevinitsend.c @@ -0,0 +1,231 @@ +/* + * udevinitsend.c + * + * Userspace devfs + * + * Copyright (C) 2004, 2005 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "udevd.h" +#include "logging.h" + + +#ifdef USE_LOG +void log_message (int level, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vsyslog(level, format, args); + va_end(args); +} +#endif + +/* + * udevsend + * + * Scan a file, write all variables into the msgbuf and + * fires the message to udevd. + */ +static int udevsend(char *filename, int sock, int ignore_loops) +{ + struct stat statbuf; + int fd, bufpos; + char *fdmap, *ls, *le, *ch; + struct udevd_msg usend_msg; + int retval = 0; + int usend_msg_len; + struct sockaddr_un saddr; + socklen_t addrlen; + + if (stat(filename,&statbuf) < 0) { + dbg("cannot stat %s: %s\n", filename, strerror(errno)); + return 1; + } + fd = open(filename,O_RDONLY); + if (fd < 0) + return 1; + + fdmap = mmap(0, statbuf.st_size, + PROT_READ, MAP_PRIVATE, fd, 0); + close(fd); + if (fdmap == MAP_FAILED) { + dbg("mmap failed, errno %d\n", errno); + return 1; + } + + memset(&saddr, 0x00, sizeof(struct sockaddr_un)); + saddr.sun_family = AF_LOCAL; + /* use abstract namespace for socket path */ + strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); + addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; + + memset(usend_msg.envbuf, 0, UEVENT_BUFFER_SIZE+256); + bufpos = 0; + memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); + strcpy(usend_msg.magic, UDEV_MAGIC); + + ls = fdmap; + ch = le = ls; + while (*ch && ch < fdmap + statbuf.st_size) { + le = strchr(ch,'\n'); + if (!le) + break; + ch = strchr(ch,'='); + if (!ch) + break; + + /* prevent loops in the scripts we execute */ + if (strncmp(ls, "UDEVD_EVENT=", 12) == 0) { + if (!ignore_loops) { + dbg("event already handled by udev\n"); + retval = -1; + break; + } + goto loop_end; + } + + /* omit shell-generated keys */ + if (ls[0] == '_' && ls[1] == '=') { + goto loop_end; + } + + if (ch < le) { + + strncpy(&usend_msg.envbuf[bufpos],ls,(ch - ls) + 1); + bufpos += (ch - ls) + 1; + if (ch[1] == '\'' && le[-1] == '\'') { + strncpy(&usend_msg.envbuf[bufpos],ch + 2, (le - ch) -3); + bufpos += (le - ch) - 3; + } else { + strncpy(&usend_msg.envbuf[bufpos],ch, (le - ch)); + bufpos += (le - ch); + } + bufpos++; + } +loop_end: + ch = le + 1; + ls = ch; + } + munmap(fdmap, statbuf.st_size); + + usend_msg_len = offsetof(struct udevd_msg, envbuf) + bufpos; + dbg("usend_msg_len=%i", usend_msg_len); + + if (!retval) { + retval = sendto(sock, &usend_msg, usend_msg_len, 0, (struct sockaddr *)&saddr, addrlen); + if (retval < 0) { + dbg("error sending message (%s)", strerror(errno)); + } + } + + return retval; +} + +int main(int argc, char *argv[], char *envp[]) +{ + static const char short_options[] = "d:f:lVh"; + int option; + char *event_dir = NULL; + char *event_file = NULL; + DIR *dirstream; + struct dirent *direntry; + int retval = 1, ignore_loops = 0; + int sock; + + logging_init("udevinitsend"); + dbg("version %s", UDEV_VERSION); + + /* get command line options */ + while (1) { + option = getopt(argc, argv, short_options); + if (option == -1) + break; + + dbg("option '%c': ", option); + switch (option) { + case 'd': + dbg("scan directory %s\n", optarg); + event_dir = optarg; + break; + + case 'f': + dbg("use event file %s\n", optarg); + event_file = optarg; + break; + + case 'l': + dbg("ignoring loops\n"); + ignore_loops = 1; + break; + + case 'V': + printf("udevinitsend, version 0.1\n"); + return 0; + + case 'h': + retval = 0; + } + } + + sock = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (sock == -1) { + dbg("error getting socket"); + return 1; + } + + if (event_dir) { + dirstream = opendir(event_dir); + if (!dirstream) { + info("error opening directory %s: %s\n", + event_dir, strerror(errno)); + return 1; + } + chdir(event_dir); + while ((direntry = readdir(dirstream)) != NULL) { + if (!strcmp(direntry->d_name,".") || + !strcmp(direntry->d_name,"..")) + continue; + retval = udevsend(direntry->d_name, sock, ignore_loops); + } + closedir(dirstream); + } else if (event_file) { + retval = udevsend(event_file, sock, ignore_loops); + } + + if (sock != -1) + close(sock); + + return retval; +} From 1682c8c4a3909f9d80f17544bcfc6fb73379bc7e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 04:48:09 +0200 Subject: [PATCH 1308/4284] Makefile: fix DESTDIR Patch from: Vassilis Virvilis Signed-off-by: Kay Sievers --- Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 2a832f7054..1cf3e54fb7 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,6 @@ INFO = udevinfo TESTER = udevtest STARTER = udevstart VERSION = 058 -INSTALL_DIR = /usr/local/bin RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev DESTDIR = @@ -180,7 +179,6 @@ ifeq ($(strip $(USE_KLIBC)),true) KLCC = $(KLIBC_INSTALL)/bin/klcc CC = $(KLCC) LD = $(KLCC) - LDFLAGS += -static else CFLAGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations endif @@ -252,8 +250,8 @@ udev_version.h: @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ - @echo \#define UDEV_BIN \"$(DESTDIR)$(sbindir)/udev\" >> $@ - @echo \#define UDEVD_BIN \"$(DESTDIR)$(sbindir)/udevd\" >> $@ + @echo \#define UDEV_BIN \"$(sbindir)/udev\" >> $@ + @echo \#define UDEVD_BIN \"$(sbindir)/udevd\" >> $@ # Rules on how to create the generated config files $(LOCAL_CFG_DIR)/udev.conf: From a15f42c46a7b9ceb5850ea4334c95f099ce74a6f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 04:53:17 +0200 Subject: [PATCH 1309/4284] udevd: improve timeout handling Allow to override some parameters by environment keys. Signed-off-by: Kay Sievers --- udevd.c | 149 ++++++++++++++++++++++++++++++++++------------------- udevd.h | 14 ++--- udevsend.c | 6 +-- 3 files changed, 107 insertions(+), 62 deletions(-) diff --git a/udevd.c b/udevd.c index 371d715716..b5597eab40 100644 --- a/udevd.c +++ b/udevd.c @@ -54,11 +54,10 @@ static int uevent_nl_sock; static pid_t sid; static int pipefds[2]; -static long startup_time; -static unsigned long long expected_seqnum; static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int sig_flag; +static int init_phase = 1; static int run_exec_q; static int stop_exec_q; @@ -70,7 +69,13 @@ static void exec_queue_manager(void); static void msg_queue_manager(void); static void user_sighandler(void); static void reap_sigchilds(void); -char *udev_bin; + +static char *udev_bin; +static unsigned long long expected_seqnum; +static int event_timeout; +static int max_childs; +static int max_childs_running; + #ifdef USE_LOG void log_message (int priority, const char *format, ...) @@ -115,6 +120,20 @@ static void msg_queue_insert(struct uevent_msg *msg) return; } + /* store timestamp of queuing */ + sysinfo(&info); + msg->queue_time = info.uptime; + + /* with the first event we provide a phase of shorter timeout */ + if (init_phase) { + static long init_time; + + if (init_time == 0) + init_time = info.uptime; + if (info.uptime - init_time >= UDEVD_INIT_TIME) + init_phase = 0; + } + /* don't delay messages with timeout set */ if (msg->timeout) { dbg("move seq %llu with timeout %u to exec queue", msg->seqnum, msg->timeout); @@ -134,13 +153,8 @@ static void msg_queue_insert(struct uevent_msg *msg) return; } } - - /* store timestamp of queuing */ - sysinfo(&info); - msg->queue_time = info.uptime; - list_add(&msg->node, &loop_msg->node); - dbg("queued message seq %llu", msg->seqnum); + info("seq %llu queued, devpath '%s'", msg->seqnum, msg->devpath); /* run msg queue manager */ run_msg_q = 1; @@ -153,6 +167,7 @@ static void execute_udev(struct uevent_msg *msg) { char *const argv[] = { "udev", msg->subsystem, NULL }; pid_t pid; + struct sysinfo info; pid = fork(); switch (pid) { @@ -174,7 +189,9 @@ static void execute_udev(struct uevent_msg *msg) break; default: /* get SIGCHLD in main loop */ - dbg("==> exec seq %llu [%d] working at '%s'", msg->seqnum, pid, msg->devpath); + sysinfo(&info); + info("seq %llu forked, pid %d, %ld seconds old", + msg->seqnum, pid, info.uptime - msg->queue_time); msg->pid = pid; } } @@ -299,32 +316,43 @@ static int compare_devpath(const char *running, const char *waiting) } /* returns still running task for the same device, its parent or its physical device */ -static struct uevent_msg *running_with_devpath(struct uevent_msg *msg) +static int running_with_devpath(struct uevent_msg *msg, int limit) { struct uevent_msg *loop_msg; + int childs_count = 0; if (msg->devpath == NULL) - return NULL; + return 0; /* skip any events with a timeout set */ - if (msg->timeout) - return NULL; + if (msg->timeout != 0) + return 0; list_for_each_entry(loop_msg, &running_list, node) { + if (limit && childs_count++ > limit) { + dbg("%llu, maximum number (%i) of child reached", msg->seqnum, childs_count); + return 1; + } if (loop_msg->devpath == NULL) continue; /* return running parent/child device event */ - if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) - return loop_msg; + if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) { + dbg("%llu, child device event still running %llu (%s)", + msg->seqnum, loop_msg->seqnum, loop_msg->devpath); + return 2; + } /* return running physical device event */ if (msg->physdevpath && msg->action && strcmp(msg->action, "add") == 0) - if (compare_devpath(loop_msg->devpath, msg->physdevpath) != 0) - return loop_msg; + 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 NULL; + return 0; } /* exec queue management routine executes the events and serializes events in the same sequence */ @@ -332,36 +360,33 @@ static void exec_queue_manager(void) { struct uevent_msg *loop_msg; struct uevent_msg *tmp_msg; - struct uevent_msg *msg; int running; running = running_processes(); dbg("%d processes runnning on system", running); if (running < 0) - running = THROTTLE_MAX_RUNNING_CHILDS; + 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 >= THROTTLE_MAX_RUNNING_CHILDS) { - running = running_processes_in_session(sid, THROTTLE_MAX_RUNNING_CHILDS+10); - dbg("%d processes running in session", running); - if (running >= THROTTLE_MAX_RUNNING_CHILDS) { - dbg("delay seq %llu, cause too many processes already running", loop_msg->seqnum); + 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, cause too many processes already running", + loop_msg->seqnum); return; } } - msg = running_with_devpath(loop_msg); - if (!msg) { + if (running_with_devpath(loop_msg, max_childs) == 0) { /* move event to run list */ list_move_tail(&loop_msg->node, &running_list); execute_udev(loop_msg); running++; dbg("moved seq %llu to running list", loop_msg->seqnum); - } else { - dbg("delay seq %llu (%s), cause seq %llu (%s) is still running", - loop_msg->seqnum, loop_msg->devpath, msg->seqnum, msg->devpath); - } + } else + dbg("delay seq %llu (%s)", loop_msg->seqnum, loop_msg->devpath); } } @@ -381,11 +406,11 @@ static void msg_queue_manager(void) struct uevent_msg *tmp_msg; struct sysinfo info; long msg_age = 0; - static int timeout = EVENT_INIT_TIMEOUT_SEC; - static int init = 1; + int timeout = event_timeout; dbg("msg queue manager, next expected is %llu", expected_seqnum); recheck: + sysinfo(&info); list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, node) { /* move event with expected sequence to the exec list */ if (loop_msg->seqnum == expected_seqnum) { @@ -393,15 +418,13 @@ recheck: continue; } - /* see if we are in the initialization phase and wait for the very first events */ - if (init && (info.uptime - startup_time >= INIT_TIME_SEC)) { - init = 0; - timeout = EVENT_TIMEOUT_SEC; - dbg("initialization phase passed, set timeout to %i seconds", EVENT_TIMEOUT_SEC); + /* limit timeout during initialization phase */ + if (init_phase) { + timeout = UDEVD_INIT_EVENT_TIMEOUT; + dbg("initialization phase, limit timeout to %i seconds", UDEVD_INIT_EVENT_TIMEOUT); } /* move event with expired timeout to the exec list */ - sysinfo(&info); msg_age = info.uptime - loop_msg->queue_time; dbg("seq %llu is %li seconds old", loop_msg->seqnum, msg_age); if (msg_age >= timeout) { @@ -629,10 +652,12 @@ static void udev_done(int pid) { /* find msg associated with pid and delete it */ struct uevent_msg *msg; + struct sysinfo info; list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { - dbg("<== exec seq %llu came back", msg->seqnum); + sysinfo(&info); + info("seq %llu exit, %ld sec old", msg->seqnum, info.uptime - msg->queue_time); run_queue_delete(msg); /* we want to run the exec queue manager since there may @@ -734,13 +759,12 @@ static int init_uevent_nl_sock(void) int main(int argc, char *argv[], char *envp[]) { - struct sysinfo info; int maxsockplus; int retval; int fd; struct sigaction act; fd_set readfds; - const char *udevd_expected_seqnum; + const char *value; int uevent_nl_active = 0; logging_init("udevd"); @@ -774,7 +798,6 @@ int main(int argc, char *argv[], char *envp[]) sid = setsid(); dbg("our session is %d", sid); - /* make sure we don't lock any path */ chdir("/"); umask(umask(077) | 022); @@ -840,23 +863,43 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - /* possible override of udev binary, used for testing */ + /* override of forked udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); if (udev_bin != NULL) info("udev binary is set to '%s'", udev_bin); else udev_bin = UDEV_BIN; - /* possible init of expected_seqnum value */ - udevd_expected_seqnum = getenv("UDEVD_EXPECTED_SEQNUM"); - if (udevd_expected_seqnum != NULL) { - expected_seqnum = strtoull(udevd_expected_seqnum, NULL, 10); + /* init of expected_seqnum value */ + value = getenv("UDEVD_EXPECTED_SEQNUM"); + if (value) { + expected_seqnum = strtoull(value, NULL, 10); info("initialize expected_seqnum to %llu", expected_seqnum); } - /* get current time to provide shorter timeout on startup */ - sysinfo(&info); - startup_time = info.uptime; + /* timeout to wait for missing events */ + value = getenv("UDEVD_EVENT_TIMEOUT"); + if (value) + event_timeout = strtoul(value, NULL, 10); + else + event_timeout = UDEVD_EVENT_TIMEOUT; + info("initialize event_timeout to %u", event_timeout); + + /* maximum limit of forked childs */ + value = getenv("UDEVD_MAX_CHILDS"); + if (value) + max_childs = strtoul(value, NULL, 10); + 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 + max_childs_running = UDEVD_MAX_CHILDS_RUNNING; + info("initialize max_childs_running to %u", max_childs_running); FD_ZERO(&readfds); FD_SET(udevd_sock, &readfds); @@ -893,7 +936,7 @@ int main(int argc, char *argv[], char *envp[]) msg = get_uevent_msg(); if (msg) { msg_queue_insert(msg); - /* disable udevsend with first netlink message */ + /* disable kernel uevent_helper with first netlink message */ if (!uevent_nl_active) { info("uevent_nl message received, disable uevent_helper messages"); uevent_nl_active = 1; diff --git a/udevd.h b/udevd.h index b782d7aacd..60732fe052 100644 --- a/udevd.h +++ b/udevd.h @@ -26,21 +26,23 @@ #define UDEV_MAGIC "udevd_" UDEV_VERSION #define UDEVD_SOCK_PATH "udevd" -#define SEND_WAIT_MAX_SECONDS 3 -#define SEND_WAIT_LOOP_PER_SECOND 10 +#define UDEVSEND_WAIT_MAX_SECONDS 3 +#define UDEVSEND_WAIT_LOOP_PER_SECOND 10 #define UDEVD_PRIORITY -4 #define UDEV_PRIORITY -2 /* duration of initialization phase with shorter timeout */ -#define INIT_TIME_SEC 5 -#define EVENT_INIT_TIMEOUT_SEC 2 +#define UDEVD_INIT_TIME 5 +#define UDEVD_INIT_EVENT_TIMEOUT 2 /* timeout to wait for missing events */ -#define EVENT_TIMEOUT_SEC 10 +#define UDEVD_EVENT_TIMEOUT 5 +/* maximum limit of runnig childs */ +#define UDEVD_MAX_CHILDS 64 /* start to throttle forking if maximum number of running childs in our session is reached */ -#define THROTTLE_MAX_RUNNING_CHILDS 10 +#define UDEVD_MAX_CHILDS_RUNNING 8 /* environment buffer, should match the kernel's size in lib/kobject_uevent.h */ #define UEVENT_BUFFER_SIZE 1024 diff --git a/udevsend.c b/udevsend.c index 2b92e659e2..888a88daa0 100644 --- a/udevsend.c +++ b/udevsend.c @@ -185,7 +185,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("usend_msg_len=%i", usend_msg_len); /* If we can't send, try to start daemon and resend message */ - loop = SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND; + loop = UDEVSEND_WAIT_MAX_SECONDS * UDEVSEND_WAIT_LOOP_PER_SECOND; while (--loop) { retval = sendto(sock, &usend_msg, usend_msg_len, 0, (struct sockaddr *)&saddr, addrlen); if (retval != -1) { @@ -208,8 +208,8 @@ int main(int argc, char *argv[], char *envp[]) dbg("udevd daemon started"); started_daemon = 1; } else { - dbg("retry to connect %d", SEND_WAIT_MAX_SECONDS * SEND_WAIT_LOOP_PER_SECOND - loop); - usleep(1000 * 1000 / SEND_WAIT_LOOP_PER_SECOND); + dbg("retry to connect %d", UDEVSEND_WAIT_MAX_SECONDS * UDEVSEND_WAIT_LOOP_PER_SECOND - loop); + usleep(1000 * 1000 / UDEVSEND_WAIT_LOOP_PER_SECOND); } } From c974742bf4d6d8fab1e1c90e2e57dae0a2f297a1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 04:57:03 +0200 Subject: [PATCH 1310/4284] udev: allow final assignments := The use of KEY:= will make the key unchangeable by later rules. Signed-off-by: Kay Sievers --- test/udev-test.pl | 23 +++++++++++++++++++++++ udev.h | 5 +++++ udev_rules.c | 20 +++++++++++++++----- udev_rules.h | 6 ++++++ udev_rules_parse.c | 11 +++++++++++ 5 files changed, 60 insertions(+), 5 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 3172d3302f..27fe35456e 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1304,6 +1304,29 @@ EOF KERNEL=="sda", NAME="ok2", RUN+="/bin/ln -s ok2 %r/testsymlink2" KERNEL=="sda", ACTION=="remove", RUN+="/bin/rm -f %r/testsymlink2" KERNEL=="sda", NAME="not-ok2" +EOF + }, + { + desc => "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 => <mode != 0000) { + 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'", udev->mode, udev->kernel_name); } - if (rule->owner[0] != '\0') { + if (!udev->owner_final && rule->owner[0] != '\0') { + if (rule->owner_operation == KEY_OP_ASSIGN_FINAL) + udev->owner_final = 1; strlcpy(udev->owner, rule->owner, sizeof(udev->owner)); apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); } - if (rule->group[0] != '\0') { + if (!udev->group_final && rule->group[0] != '\0') { + if (rule->group_operation == KEY_OP_ASSIGN_FINAL) + udev->group_final = 1; strlcpy(udev->group, rule->group, sizeof(udev->group)); apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); } /* collect symlinks */ - if (rule->symlink[0] != '\0') { + if (!udev->symlink_final && rule->symlink[0] != '\0') { char temp[PATH_SIZE]; char *pos, *next; + if (rule->symlink_operation == KEY_OP_ASSIGN_FINAL) + udev->symlink_final = 1; info("configured rule in '%s[%i]' applied, added symlink '%s'", rule->config_file, rule->config_line, rule->symlink); strlcpy(temp, rule->symlink, sizeof(temp)); @@ -808,9 +816,11 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d udev->name, udev->owner, udev->group, udev->mode, udev->partitions); } - if (rule->run[0] != '\0') { + if (!udev->run_final && rule->run[0] != '\0') { char program[PATH_SIZE]; + if (rule->run_operation == KEY_OP_ASSIGN_FINAL) + udev->run_final = 1; strlcpy(program, rule->run, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); dbg("add run '%s'", program); diff --git a/udev_rules.h b/udev_rules.h index 5fba2d5571..f4a74bba45 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -62,6 +62,7 @@ enum key_operation { KEY_OP_NOMATCH, KEY_OP_ADD, KEY_OP_ASSIGN, + KEY_OP_ASSIGN_FINAL, }; struct key_pair { @@ -96,10 +97,15 @@ struct udev_rule { char name[PATH_SIZE]; char symlink[PATH_SIZE]; + enum key_operation symlink_operation; char owner[USER_SIZE]; + enum key_operation owner_operation; char group[USER_SIZE]; + enum key_operation group_operation; mode_t mode; + enum key_operation mode_operation; char run[PATH_SIZE]; + enum key_operation run_operation; int last_rule; int ignore_device; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index e665957b81..3f07521ccb 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -89,6 +89,8 @@ static int get_key(char **line, char **key, enum key_operation *operation, char break; if (linepos[0] == '!') break; + if (linepos[0] == ':') + break; } /* remember end of key */ @@ -115,6 +117,10 @@ static int get_key(char **line, char **key, enum key_operation *operation, char *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; @@ -364,30 +370,35 @@ static int rules_parse(const char *filename) if (strcasecmp(key, KEY_SYMLINK) == 0) { strlcpy(rule.symlink, value, sizeof(rule.symlink)); + rule.symlink_operation = operation; valid = 1; continue; } if (strcasecmp(key, KEY_OWNER) == 0) { strlcpy(rule.owner, value, sizeof(rule.owner)); + rule.owner_operation = operation; valid = 1; continue; } if (strcasecmp(key, KEY_GROUP) == 0) { strlcpy(rule.group, value, sizeof(rule.group)); + rule.group_operation = operation; valid = 1; continue; } if (strcasecmp(key, KEY_MODE) == 0) { rule.mode = strtol(value, NULL, 8); + rule.mode_operation = operation; valid = 1; continue; } if (strcasecmp(key, KEY_RUN) == 0) { strlcpy(rule.run, value, sizeof(rule.run)); + rule.run_operation = operation; valid = 1; continue; } From 6a522681e1438bbd9c317654cc35d5d206d378ad Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 05:11:29 +0200 Subject: [PATCH 1311/4284] udev: move dev.d/ handling to external helper Modern rules are expected to call notification and postprocessing with the RUN key. For compatibility the current behavior can be emulated with an external helper. Signed-off-by: Kay Sievers --- etc/udev/udev.rules | 51 ++++++++------- etc/udev/udev.rules.examples | 63 ++++++++----------- extras/run_directory/Makefile | 55 +++++++++++++++++ extras/run_directory/run_directory.c | 79 ++++++++++++++++++++++++ extras/run_directory/udev_run_devd.c | 78 +++++++++++++++++++++++ extras/run_directory/udev_run_hotplugd.c | 79 ++++++++++++++++++++++++ test/simple-build-check.sh | 2 +- udev.c | 4 -- udev.h | 1 - udev_config.c | 37 ----------- udev_utils.c | 32 ++++++++++ udev_utils.h | 2 + udevstart.c | 4 -- 13 files changed, 378 insertions(+), 109 deletions(-) create mode 100644 extras/run_directory/Makefile create mode 100644 extras/run_directory/run_directory.c create mode 100644 extras/run_directory/udev_run_devd.c create mode 100644 extras/run_directory/udev_run_hotplugd.c diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules index bc8c8bdd6c..bebf74802f 100644 --- a/etc/udev/udev.rules +++ b/etc/udev/udev.rules @@ -5,43 +5,42 @@ # # if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" - -# 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" +BUS=="ide", KERNEL=="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK+="cdrom" # DRI devices always go into a subdirectory (as per the LSB spec) -KERNEL="card*", NAME="dri/card%n" +KERNEL=="card*", NAME="dri/card%n" # alsa devices -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" +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" # input devices -KERNEL="mice", NAME="input/%k" -KERNEL="mouse*", NAME="input/%k" -KERNEL="event*", NAME="input/%k" -KERNEL="js*", NAME="input/%k" -KERNEL="ts*", NAME="input/%k" +KERNEL=="mice", NAME="input/%k" +KERNEL=="mouse*", NAME="input/%k" +KERNEL=="event*", NAME="input/%k" +KERNEL=="js*", NAME="input/%k" +KERNEL=="ts*", NAME="input/%k" # USB devices -KERNEL="hiddev*", NAME="usb/%k" -KERNEL="auer*", NAME="usb/%k" -KERNEL="legousbtower*", NAME="usb/%k" -KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" +KERNEL=="hiddev*", NAME="usb/%k" +KERNEL=="auer*", NAME="usb/%k" +KERNEL=="legousbtower*", NAME="usb/%k" +KERNEL=="dabusb*", NAME="usb/%k" +BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" # CAPI devices -KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" -KERNEL="capi*", NAME="capi/%n" +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" +KERNEL=="capi*", NAME="capi/%n" # Network devices -KERNEL="tun", NAME="net/%k" +KERNEL=="tun", NAME="net/%k" # raw devices -KERNEL="raw[0-9]*", NAME="raw/%k" +KERNEL=="raw[0-9]*", NAME="raw/%k" + +# emulate dev.d/ +RUN="/sbin/udev_run_devd" diff --git a/etc/udev/udev.rules.examples b/etc/udev/udev.rules.examples index a464b6ba57..1c4527891a 100644 --- a/etc/udev/udev.rules.examples +++ b/etc/udev/udev.rules.examples @@ -9,64 +9,55 @@ # # Looking for scsi bus id 42:0:0:1 -BUS="scsi", PROGRAM="/bin/echo -n test-%b", RESULT="test-42:0:0:1", NAME="%c" +BUS=="scsi", PROGRAM="/bin/echo -n test-%b", RESULT=="test-42:0:0:1", NAME="%c" # A usb camera. -BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n" +BUS=="usb", SYSFS{vendor}=="FUJIFILM", SYSFS{model}=="M100", NAME="camera%n" # USB Epson printer to be called lp_epson -BUS="usb", SYSFS_serial="HXOLL0012202323480", NAME="lp_epson" +BUS=="usb", SYSFS_serial=="HXOLL0012202323480", NAME="lp_epson" # USB HP printer to be called lp_hp -BUS="usb", SYSFS{serial}="W09090207101241330", NAME="lp_hp" +BUS=="usb", SYSFS{serial}=="W09090207101241330", NAME="lp_hp" # sound card with PCI bus id 00:0b.0 to be the first sound card -BUS="pci", ID="00:0b.0", NAME="dsp" +BUS=="pci", ID=="00:0b.0", NAME="dsp" # sound card with PCI bus id 00:07.1 to be the second sound card -BUS="pci", ID="00:07.1", NAME="dsp1" - -# USB mouse plugged into the third port of the first hub to be called mouse0 -BUS="usb", PLACE="1.3", NAME="mouse0" - -# USB tablet plugged into the third port of the second hub to be called mouse1 -BUS="usb", PLACE="2.3", NAME="mouse1" -BUS="usb", PLACE="2.4", NAME="mouse2" +BUS=="pci", ID=="00:07.1", NAME="dsp1" # ttyUSB1 should always be called visor -KERNEL="ttyUSB1", NAME="visor" -KERNEL="ttyUSB0", NAME="pl2303" +KERNEL=="ttyUSB1", NAME="visor" +KERNEL=="ttyUSB0", NAME="pl2303" # a devfs like way to name some tty devices -KERNEL="ttyS*", NAME="tts/%n" -KERNEL="tty*", NAME="vc/%n" +KERNEL=="ttyS*", NAME="tts/%n" +KERNEL=="tty*", NAME="vc/%n" # if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK="cdrom" - -# 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" +BUS=="ide", KERNEL=="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom", NAME="%k", SYMLINK+="cdrom" # DRI devices always go into a subdirectory (as per the LSB spec) -KERNEL="card*", NAME="dri/card%n" +KERNEL=="card*", NAME="dri/card%n" # create all 15 partitions of a USB flash card reader -# note the trailing spaces in the attribute, use udevinfo(8) to examine your device -BUS="scsi", SYSFS{model}="CF/MD ", NAME{all_partitions}="compactflash" +BUS=="scsi", SYSFS{model}=="CF/MD", NAME{all_partitions}="compactflash" # 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" +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" -KERNEL="ts*", NAME="input/%k" +KERNEL=="mice", NAME="input/%k" +KERNEL=="mouse*", NAME="input/%k" +KERNEL=="event*", NAME="input/%k" +KERNEL=="js*", NAME="input/%k" +KERNEL=="ts*", NAME="input/%k" + +# emulate dev.d/ +RUN="/sbin/udev_run_devd" diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile new file mode 100644 index 0000000000..12dccf0749 --- /dev/null +++ b/extras/run_directory/Makefile @@ -0,0 +1,55 @@ +# Makefile for udev_volume_id +# +# 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. +# + +DEVD = udev_run_devd +HOTPLUGD = udev_run_hotplugd + +all: $(DEVD) $(HOTPLUGD) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +override CFLAGS+=-D_FILE_OFFSET_BITS=64 + +OBJS = ../../udev.a ../../libsysfs/sysfs.a + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(DEVD): $(HEADERS) $(DEVD).o run_directory.o + $(QUIET) $(LD) $(LDFLAGS) -o $(DEVD) $(DEVD).o run_directory.o $(OBJS) + +$(HOTPLUGD): $(HEADERS) $(HOTPLUGD).o run_directory.o + $(QUIET) $(LD) $(LDFLAGS) -o $(HOTPLUGD) $(HOTPLUGD).o run_directory.o $(OBJS) + +clean: + rm -f $(DEVD) $(HOTPLUGD) run_directory.o + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(DEVD) $(DESTDIR)$(sbindir)/$(DEVD) + $(INSTALL_PROGRAM) $(HOTPLUGD) $(DESTDIR)$(sbindir)/$(HOTPLUGD) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(DEVD) diff --git a/extras/run_directory/run_directory.c b/extras/run_directory/run_directory.c new file mode 100644 index 0000000000..e6c6173eca --- /dev/null +++ b/extras/run_directory/run_directory.c @@ -0,0 +1,79 @@ +/* + * udev_run_directory.c - directory multiplexer + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev_utils.h" +#include "../../list.h" +#include "../../logging.h" + +int run_directory(const char *dir, const char *suffix, const char *subsystem); + +static int run_program(const char *filename, const char *subsystem) +{ + pid_t pid; + + dbg("running %s", filename); + pid = fork(); + switch (pid) { + case 0: + /* child */ + execl(filename, filename, subsystem, NULL); + dbg("exec of child failed"); + _exit(1); + case -1: + dbg("fork of child failed"); + break; + return -1; + default: + waitpid(pid, NULL, 0); + } + + return 0; +} + +int run_directory(const char *dir, const char *suffix, const char *subsystem) +{ + char dirname[NAME_SIZE]; + struct name_entry *name_loop, *name_tmp; + LIST_HEAD(name_list); + + if (subsystem) { + snprintf(dirname, sizeof(dirname), "%s/%s", dir, subsystem); + dirname[sizeof(dirname)-1] = '\0'; + dbg("looking at '%s'", dirname); + add_matching_files(&name_list, dirname, suffix); + } + + snprintf(dirname, sizeof(dirname), "%s/default", dir); + dirname[sizeof(dirname)-1] = '\0'; + dbg("looking at '%s'", dirname); + add_matching_files(&name_list, dirname, suffix); + + list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { + run_program(name_loop->name, subsystem); + list_del(&name_loop->node); + } + + logging_close(); + return 0; +} diff --git a/extras/run_directory/udev_run_devd.c b/extras/run_directory/udev_run_devd.c new file mode 100644 index 0000000000..02bbc8c353 --- /dev/null +++ b/extras/run_directory/udev_run_devd.c @@ -0,0 +1,78 @@ +/* + * udev_run_devd.c - directory multiplexer + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev_utils.h" +#include "../../list.h" +#include "../../logging.h" + +extern int run_directory(const char *dir, const char *suffix, const char *subsystem); + +#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 *envp[]) +{ + const char *subsystem; + int fd; + + if (getenv("DEVNAME") == NULL) + exit(0); + + subsystem = argv[1]; + logging_init("udev_run_devd"); + + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + dup2(fd, STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + } + dbg("running dev.d directory"); + + run_directory("/etc/dev.d", ".dev", subsystem); + exit(0); +} diff --git a/extras/run_directory/udev_run_hotplugd.c b/extras/run_directory/udev_run_hotplugd.c new file mode 100644 index 0000000000..463473d7c7 --- /dev/null +++ b/extras/run_directory/udev_run_hotplugd.c @@ -0,0 +1,79 @@ +/* + * udev_run_hotplugd.c - directory multiplexer + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev_utils.h" +#include "../../list.h" +#include "../../logging.h" + +extern int run_directory(const char *dir, const char *suffix, const char *subsystem); + +#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 *envp[]) +{ + const char *subsystem; + int fd; + + if (getenv("DEVNAME") == NULL) + exit(0); + + subsystem = argv[1]; + logging_init("udev_run_hotplugd"); + + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + dup2(fd, STDOUT_FILENO); + dup2(fd, STDIN_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); + } + + dbg("running dev.d directory"); + + run_directory("/etc/hotplug.d", ".hotplug", subsystem); + exit(0); +} diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index d1e13e69ed..b653185b26 100644 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -1,6 +1,6 @@ #/bin/sh -EXTRAS="extras/chassis_id extras/scsi_id extras/volume_id" +EXTRAS="extras/chassis_id extras/scsi_id extras/volume_id extras/run_directory" [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build echo KERNEL_DIR: "$KERNEL_DIR" diff --git a/udev.c b/udev.c index 2be4c35740..999d25d4e5 100644 --- a/udev.c +++ b/udev.c @@ -219,10 +219,6 @@ int main(int argc, char *argv[], char *envp[]) execute_command(name_loop->name, udev.subsystem); } - /* run dev.d/ scripts if we created/deleted a node or changed a netif name */ - if (udev_dev_d && udev.devname[0] != '\0') - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); - } else if (udev.type == DEV_DEVICE) { if (strcmp(action, "add") == 0) { /* wait for sysfs */ diff --git a/udev.h b/udev.h index c6f26b3bfb..2c3377ad2e 100644 --- a/udev.h +++ b/udev.h @@ -102,7 +102,6 @@ extern char udev_config_filename[PATH_SIZE]; extern char udev_rules_filename[PATH_SIZE]; extern int udev_log_priority; extern int udev_run; -extern int udev_dev_d; extern int udev_hotplug_d; #endif diff --git a/udev_config.c b/udev_config.c index 6bc070d63a..0701d37e84 100644 --- a/udev_config.c +++ b/udev_config.c @@ -45,40 +45,8 @@ char udev_config_filename[PATH_SIZE]; char udev_rules_filename[PATH_SIZE]; int udev_log_priority; int udev_run; -int udev_dev_d; int udev_hotplug_d; -static 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; -} - -static 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; -} - static int get_key(char **line, char **key, char **value) { char *linepos; @@ -219,7 +187,6 @@ void udev_init_config(void) strcpy(udev_rules_filename, UDEV_RULES_FILE); udev_log_priority = LOG_ERR; udev_run = 1; - udev_dev_d = 1; udev_hotplug_d = 1; sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); @@ -228,10 +195,6 @@ void udev_init_config(void) if (env && !string_is_true(env)) udev_run = 0; - env = getenv("UDEV_NO_DEVD"); - if (env && string_is_true(env)) - udev_dev_d = 0; - env = getenv("UDEV_NO_HOTPLUGD"); if (env && string_is_true(env)) udev_hotplug_d = 0; diff --git a/udev_utils.c b/udev_utils.c index 74b55ed406..70b20e3a28 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +110,37 @@ void udev_cleanup_device(struct udevice *udev) } } +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; +} + +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; +} + int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel) { static unsigned int kversion = 0; diff --git a/udev_utils.h b/udev_utils.h index 9cdae6db57..b3e604fb98 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -34,6 +34,8 @@ extern void udev_cleanup_device(struct udevice *udev); extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); +extern int log_priority(const char *priority); +extern int string_is_true(const char *str); extern int parse_get_pair(char **orig_string, char **left, char **right); extern int unlink_secure(const char *filename); extern int file_map(const char *filename, char **buf, size_t *bufsize); diff --git a/udevstart.c b/udevstart.c index 60e63c5ad8..34f3835d65 100644 --- a/udevstart.c +++ b/udevstart.c @@ -137,10 +137,6 @@ static int add_device(const char *path, const char *subsystem) execute_command(name_loop->name, udev.subsystem); } - /* run dev.d/ scripts if we created a node or changed a netif name */ - if (udev_dev_d && udev.devname[0] != '\0') - udev_multiplex_directory(&udev, DEVD_DIR, DEVD_SUFFIX); - sysfs_close_class_device(class_dev); udev_cleanup_device(&udev); From 995aec875973e29caf42b037736349fc8839ee40 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 05:13:33 +0200 Subject: [PATCH 1312/4284] udev: clear lists if a new value is assigned Former values are cleared if SYMLINK= is used. To add a value SYMLINK+= is now needed. Signed-off-by: Kay Sievers --- test/udev-test.pl | 63 +++++++++++++++++++++++++++++++---------------- udev_rules.c | 18 ++++++++++++++ udev_utils.c | 4 +++ 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 27fe35456e..884abf9e8b 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -783,9 +783,9 @@ EOF exp_name => "symlink-only2", exp_target => "link", rules => < "yes", exp_rem_error => "yes", rules => < "yes", option => "clean", rules => < "symlink0", exp_target => "ttyUSB0", rules => < "symlink-ttyUSB0", exp_target => "ttyUSB0", rules => < "major-188:0", exp_target => "ttyUSB0", rules => < "symlink-0:0:0:0", exp_target => "node", rules => < "test", exp_target => "ttyUSB0", rules => < "test", exp_target => "ttyUSB0", rules => < "this", exp_target => "ttyUSB0", rules => < "test", exp_target => "link", rules => < "188:0", exp_target => "ttyUSB0", rules => < "188", exp_target => "ttyUSB0", rules => < "percent%sign", exp_target => "ttyUSB0", rules => < "%ttyUSB0_name", exp_target => "ttyUSB0", rules => < "link1", exp_target => "node", rules => < "link4", exp_target => "node", rules => < "/block/sda/sda1", exp_name => "last", rules => < "reset list to current value", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "three", + not_exp_name => "two", + exp_target => "node", + 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); } diff --git a/udev_rules.c b/udev_rules.c index 42509f16ce..631cc4270a 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -782,6 +782,15 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (rule->symlink_operation == KEY_OP_ASSIGN_FINAL) udev->symlink_final = 1; + else if (rule->symlink_operation == KEY_OP_ASSIGN) { + struct name_entry *name_loop; + struct name_entry *temp_loop; + + list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { + list_del(&name_loop->node); + free(name_loop); + } + } info("configured rule in '%s[%i]' applied, added symlink '%s'", rule->config_file, rule->config_line, rule->symlink); strlcpy(temp, rule->symlink, sizeof(temp)); @@ -821,6 +830,15 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (rule->run_operation == KEY_OP_ASSIGN_FINAL) udev->run_final = 1; + else if (rule->run_operation == KEY_OP_ASSIGN) { + struct name_entry *name_loop; + struct name_entry *temp_loop; + + list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { + list_del(&name_loop->node); + free(name_loop); + } + } strlcpy(program, rule->run, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); dbg("add run '%s'", program); diff --git a/udev_utils.c b/udev_utils.c index 70b20e3a28..d605631088 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -108,6 +108,10 @@ void udev_cleanup_device(struct udevice *udev) list_del(&name_loop->node); free(name_loop); } + list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { + list_del(&name_loop->node); + free(name_loop); + } } int string_is_true(const char *str) From c2401132bf72cbda6555f1ef4403851c14faeba5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 05:17:21 +0200 Subject: [PATCH 1313/4284] volume_id: use udev-provided log-level Signed-off-by: Kay Sievers --- extras/volume_id/Makefile | 2 +- extras/volume_id/udev_volume_id.c | 18 ++++++++++++++++-- udev.c | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 91527cc9f5..56fdf278b9 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -33,7 +33,7 @@ override CFLAGS+=-D_FILE_OFFSET_BITS=64 VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc -OBJS = udev_volume_id.o $(VOLUME_ID_OBJS) $(SYSFS) +OBJS = udev_volume_id.o $(VOLUME_ID_OBJS) ../../udev.a HEADERS = $(VOLUME_ID_HEADERS) $(OBJS): $(HEADERS) diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/udev_volume_id.c index a00b01a27d..7c6fc4050d 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/udev_volume_id.c @@ -40,12 +40,26 @@ #define BLKGETSIZE64 _IOR(0x12,114,size_t) #ifdef USE_LOG -void log_message(int level, const char *format, ...) +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(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif diff --git a/udev.c b/udev.c index 999d25d4e5..3f76e98b24 100644 --- a/udev.c +++ b/udev.c @@ -152,7 +152,7 @@ int main(int argc, char *argv[], char *envp[]) goto hotplug; } - /* export logging flag, as called scripts may want to do the same as udev */ + /* export logging flag, as called programs may want to do the same as udev */ if (udev_log_priority) { char priority[32]; From c07669bd663d780e4957691e488798aa0178e76b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 15:55:29 +0200 Subject: [PATCH 1314/4284] udev: handle all events - not only class and block devices Handle all events with rules. If udev is expected to handle hotplug.d/ the exernal helper must be called. Signed-off-by: Kay Sievers --- Makefile | 2 +- extras/run_directory/udev_run_hotplugd.c | 3 - udev.8.in | 28 +--- udev.c | 153 ++++++++---------- udev.h | 9 +- udev.spec | 3 - udev_add.c | 16 -- udev_config.c | 6 - udev_multiplex.c | 92 ----------- udev_remove.c | 26 ++- udev_rules.c | 192 +++++++++-------------- udev_rules.h | 3 +- udev_rules_parse.c | 8 +- udevstart.c | 24 ++- 14 files changed, 177 insertions(+), 388 deletions(-) delete mode 100644 udev_multiplex.c diff --git a/Makefile b/Makefile index 1cf3e54fb7..d36bd5866c 100644 --- a/Makefile +++ b/Makefile @@ -143,7 +143,6 @@ UDEV_OBJS = \ udev_remove.o \ udev_sysfs.o \ udev_db.o \ - udev_multiplex.o \ udev_rules.o \ udev_rules_parse.o \ udev_libc_wrapper.o @@ -382,6 +381,7 @@ install: install-config install-man install-dev.d all - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug ifndef DESTDIR - killall $(DAEMON) + - $(sbindir)/$(DAEMON) -d - rm -rf $(udevdb) endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ diff --git a/extras/run_directory/udev_run_hotplugd.c b/extras/run_directory/udev_run_hotplugd.c index 463473d7c7..54b6bf44e3 100644 --- a/extras/run_directory/udev_run_hotplugd.c +++ b/extras/run_directory/udev_run_hotplugd.c @@ -58,9 +58,6 @@ int main(int argc, char *argv[], char *envp[]) const char *subsystem; int fd; - if (getenv("DEVNAME") == NULL) - exit(0); - subsystem = argv[1]; logging_init("udev_run_hotplugd"); diff --git a/udev.8.in b/udev.8.in index 79c4a83d16..e4c1c11af2 100644 --- a/udev.8.in +++ b/udev.8.in @@ -306,11 +306,9 @@ following the '[' is a '!', any characters not enclosed are matched. .P After device node creation, removal, or network device renaming, .B udev -executes the programs located in the directory tree under -.IR /etc/dev.d/ . -The name of a program must have the suffix -.I .dev -to be recognized. +executes the programs specified by the +.B RUN +key. .br In addition to the kernel provided hotplug environment variables, .B UDEV_LOG @@ -319,15 +317,7 @@ is set and contains the numerical priority value, if udev is configured to use Executed programs may want to follow that setting. .B DEVNAME is exported to make the name of the created node, or the name the network -device is renamed to, available to the executed program. The programs in every -directory are sorted in lexical order, while the directories are searched in -the following order: -.sp -.nf -/etc/dev.d/$(DEVNAME)/*.dev -/etc/dev.d/$(SUBSYSTEM)/*.dev -/etc/dev.d/default/*.dev -.fi +device is renamed to, available to the executed programs. .SH "ENVIRONMENT" .P The following variables are read from the environment: @@ -353,20 +343,10 @@ Overrides the log priority specified in the config file. .TP .B UDEV_RUN If set to "0", it disables the execution of programs added by rules. -.TP -.B UDEV_NO_DEVD -The default behavior of -.B udev -is to execute programs in the -.I /etc/dev.d/ -directory after device handling. If set, -.B udev -will skip this step. .SH "FILES" .nf /sbin/udev udev program /etc/udev/* udev config files -/etc/dev.d/* programs invoked by udev .fi .SH "SEE ALSO" .BR udevinfo (8), diff --git a/udev.c b/udev.c index 3f76e98b24..d623cbcc67 100644 --- a/udev.c +++ b/udev.c @@ -54,39 +54,6 @@ void log_message(int priority, const char *format, ...) } #endif -/* Decide if we should manage the whole uevent, including multiplexing - * of the hotplug directories. - * For now look if the kernel calls udevsend instead of /sbin/hotplug, - * or the uevent-helper in /proc/sys/kernel/hotplug is empty. - */ -static int manage_hotplug_event(void) { - char helper[256]; - int fd; - int len; - - /* don't handle hotplug.d if we are called directly */ - if (!getenv("UDEVD_EVENT")) - return 0; - - fd = open("/proc/sys/kernel/hotplug", O_RDONLY); - if (fd < 0) - return 0; - - len = read(fd, helper, sizeof(helper)-1); - close(fd); - - if (len < 0) - return 0; - helper[len] = '\0'; - - if (helper[0] == '\0' || helper[0] == '\n') - return 1; - if (strstr(helper, "udevsend")) - return 1; - - return 0; -} - static void asmlinkage sig_handler(int signum) { switch (signum) { @@ -100,15 +67,12 @@ static void asmlinkage sig_handler(int signum) int main(int argc, char *argv[], char *envp[]) { - struct sysfs_class_device *class_dev; - struct sysfs_device *devices_dev; struct udevice udev; char path[PATH_SIZE]; const char *error; const char *action; const char *devpath; const char *subsystem; - int managed_event; struct sigaction act; int retval = -EINVAL; @@ -133,11 +97,6 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); - /* let the executed programs know if we handle the whole hotplug event */ - managed_event = manage_hotplug_event(); - if (managed_event) - setenv("MANAGED_EVENT", "1", 1); - action = getenv("ACTION"); devpath = getenv("DEVPATH"); subsystem = getenv("SUBSYSTEM"); @@ -145,14 +104,12 @@ int main(int argc, char *argv[], char *envp[]) if (!subsystem && argc == 2) subsystem = argv[1]; - udev_init_device(&udev, devpath, subsystem, action); - if (!action || !subsystem || !devpath) { err("action, subsystem or devpath missing"); - goto hotplug; + goto exit; } - /* export logging flag, as called programs may want to do the same as udev */ + /* export log_level , as called programs may want to do the same as udev */ if (udev_log_priority) { char priority[32]; @@ -160,93 +117,109 @@ int main(int argc, char *argv[], char *envp[]) setenv("UDEV_LOG", priority, 1); } + udev_init_device(&udev, devpath, subsystem, action); + udev_rules_init(); + if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { - udev_rules_init(); - + /* handle device node */ if (strcmp(action, "add") == 0) { - /* wait for sysfs and possibly add node */ - dbg("udev add"); - - /* skip subsystems without "dev", but handle net devices */ - if (udev.type != DEV_NET && subsystem_expect_no_dev(udev.subsystem)) { - dbg("don't care about '%s' devices", udev.subsystem); - goto hotplug; - } + struct sysfs_class_device *class_dev; + /* wait for sysfs of /sys/class /sys/block */ + dbg("node add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath); path[sizeof(path)-1] = '\0'; class_dev = wait_class_device_open(path); if (class_dev == NULL) { dbg("open class device failed"); - goto hotplug; + goto run; } dbg("opened class_dev->name='%s'", class_dev->name); - wait_for_class_device(class_dev, &error); - /* name, create node, store in db */ - retval = udev_add_device(&udev, class_dev); + /* get major/minor */ + if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS) { + udev.devt = get_devt(class_dev); + if (udev.devt) { + /* name device */ + udev_rules_get_name(&udev, class_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } + if (udev.name[0] == '\0') { + info("device node creation supressed"); + goto run; + } + /* create node, store in db */ + retval = udev_add_device(&udev, class_dev); + } else { + dbg("no dev-file found"); + udev_rules_get_run(&udev, NULL); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } + } + } sysfs_close_class_device(class_dev); } else if (strcmp(action, "remove") == 0) { - /* possibly remove a node */ - dbg("udev remove"); - - /* skip subsystems without "dev" */ - if (subsystem_expect_no_dev(udev.subsystem)) { - dbg("don't care about '%s' devices", udev.subsystem); - goto hotplug; - } - - udev_rules_get_run(&udev); + dbg("node remove"); + udev_rules_get_run(&udev, NULL); if (udev.ignore_device) { dbg("device event will be ignored"); - goto hotplug; + goto exit; } - /* get node from db, remove db-entry, delete created node */ + /* get name from db, remove db-entry, delete node */ retval = udev_remove_device(&udev); } + /* export name of device node or netif */ if (udev.devname[0] != '\0') setenv("DEVNAME", udev.devname, 1); - - if (udev_run && !list_empty(&udev.run_list)) { - struct name_entry *name_loop; - - dbg("executing run list"); - list_for_each_entry(name_loop, &udev.run_list, node) - execute_command(name_loop->name, udev.subsystem); - } - } else if (udev.type == DEV_DEVICE) { if (strcmp(action, "add") == 0) { - /* wait for sysfs */ - dbg("devices add"); + struct sysfs_device *devices_dev; + /* wait for sysfs of /sys/devices/ */ + dbg("devices add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); path[sizeof(path)-1] = '\0'; devices_dev = wait_devices_device_open(path); if (!devices_dev) { dbg("devices device unavailable (probably remove has beaten us)"); - goto hotplug; + goto run; } dbg("devices device opened '%s'", path); - wait_for_devices_device(devices_dev, &error); - + udev_rules_get_run(&udev, devices_dev); sysfs_close_device(devices_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } } else if (strcmp(action, "remove") == 0) { dbg("devices remove"); + udev_rules_get_run(&udev, NULL); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } } - } else { - dbg("unhandled"); } -hotplug: - if (udev_hotplug_d && managed_event) - udev_multiplex_directory(&udev, HOTPLUGD_DIR, HOTPLUG_SUFFIX); +run: + if (udev_run && !list_empty(&udev.run_list)) { + struct name_entry *name_loop; + dbg("executing run list"); + list_for_each_entry(name_loop, &udev.run_list, node) + execute_command(name_loop->name, udev.subsystem); + } + +exit: udev_cleanup_device(&udev); logging_close(); diff --git a/udev.h b/udev.h index 2c3377ad2e..11fbe02460 100644 --- a/udev.h +++ b/udev.h @@ -39,12 +39,6 @@ #define SEQNUM_SIZE 32 #define VALUE_SIZE 128 -#define DEVD_DIR "/etc/dev.d" -#define DEVD_SUFFIX ".dev" - -#define HOTPLUGD_DIR "/etc/hotplug.d" -#define HOTPLUG_SUFFIX ".hotplug" - #define DEFAULT_PARTITIONS_COUNT 15 enum device_type { @@ -62,6 +56,7 @@ struct udevice { enum device_type type; char name[PATH_SIZE]; + int name_set; char devname[PATH_SIZE]; struct list_head symlink_list; int symlink_final; @@ -92,7 +87,6 @@ extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *clas extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); extern int udev_start(void); -extern void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix); extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); extern char sysfs_path[PATH_SIZE]; @@ -102,6 +96,5 @@ extern char udev_config_filename[PATH_SIZE]; extern char udev_rules_filename[PATH_SIZE]; extern int udev_log_priority; extern int udev_run; -extern int udev_hotplug_d; #endif diff --git a/udev.spec b/udev.spec index 28f19565da..0430a1259d 100644 --- a/udev.spec +++ b/udev.spec @@ -112,9 +112,6 @@ rm -rf $RPM_BUILD_ROOT %attr(-,root,root) /etc/hotplug.d/default/udev.hotplug %attr(755,root,root) /etc/init.d/udev %attr(0644,root,root) %{_mandir}/man8/udev*.8* -%attr(755,root,root) %dir /etc/dev.d/ -%attr(755,root,root) %dir /etc/dev.d/net/ -%attr(0755,root,root) /etc/dev.d/net/hotplug.dev %if %{scsi_id} %attr(755,root,root) /sbin/scsi_id diff --git a/udev_add.c b/udev_add.c index 9764cb9bcd..2081e503c7 100644 --- a/udev_add.c +++ b/udev_add.c @@ -268,22 +268,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) char *pos; int retval = 0; - if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { - udev->devt = get_devt(class_dev); - if (!udev->devt) { - dbg("no dev-file found, do nothing"); - return 0; - } - } - - udev_rules_get_name(udev, class_dev); - if (udev->ignore_device) { - dbg("device event will be ignored"); - return 0; - } - dbg("adding name='%s'", udev->name); - selinux_init(); if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { @@ -325,6 +310,5 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) exit: selinux_exit(); - return retval; } diff --git a/udev_config.c b/udev_config.c index 0701d37e84..773ee67f9e 100644 --- a/udev_config.c +++ b/udev_config.c @@ -45,7 +45,6 @@ char udev_config_filename[PATH_SIZE]; char udev_rules_filename[PATH_SIZE]; int udev_log_priority; int udev_run; -int udev_hotplug_d; static int get_key(char **line, char **key, char **value) { @@ -187,7 +186,6 @@ void udev_init_config(void) strcpy(udev_rules_filename, UDEV_RULES_FILE); udev_log_priority = LOG_ERR; udev_run = 1; - udev_hotplug_d = 1; sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); /* disable RUN key execution */ @@ -195,10 +193,6 @@ void udev_init_config(void) if (env && !string_is_true(env)) udev_run = 0; - env = getenv("UDEV_NO_HOTPLUGD"); - if (env && string_is_true(env)) - udev_hotplug_d = 0; - env = getenv("UDEV_CONFIG_FILE"); if (env) { strlcpy(udev_config_filename, env, sizeof(udev_config_filename)); diff --git a/udev_multiplex.c b/udev_multiplex.c deleted file mode 100644 index 22bbaf7b61..0000000000 --- a/udev_multiplex.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * udev_multiplex.c directory multiplexer - * - * Copyright (C) 2004 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. - */ - -/* - * This essentially emulates the following shell script logic in C: - * DIR="/etc/dev.d" - * export DEVNAME="whatever_dev_name_udev_just_gave" - * for I in "${DIR}/$DEVNAME/"*.dev "${DIR}/$1/"*.dev "${DIR}/default/"*.dev ; do - * if [ -f $I ]; then $I $1 ; fi - * done - * exit 1; - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "udev.h" -#include "udev_libc_wrapper.h" -#include "udev_utils.h" -#include "logging.h" - - -/* - * runs files in these directories in order: - * / - * subsystem/ - * default/ - */ -void udev_multiplex_directory(struct udevice *udev, const char *basedir, const char *suffix) -{ - char dirname[PATH_SIZE]; - struct name_entry *name_loop, *name_tmp; - LIST_HEAD(name_list); - - /* chop the device name up into pieces based on '/' */ - if (udev->name[0] != '\0') { - char devname[PATH_SIZE]; - char *temp; - - strlcpy(devname, udev->name, sizeof(devname)); - temp = strchr(devname, '/'); - while (temp != NULL) { - temp[0] = '\0'; - - /* don't call the subsystem directory here */ - if (strcmp(devname, udev->subsystem) != 0) { - snprintf(dirname, sizeof(dirname), "%s/%s", basedir, devname); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - } - - temp[0] = '/'; - ++temp; - temp = strchr(temp, '/'); - } - } - - if (udev->name[0] != '\0') { - snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->name); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - } - - if (udev->subsystem[0] != '\0') { - snprintf(dirname, sizeof(dirname), "%s/%s", basedir, udev->subsystem); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - } - - snprintf(dirname, sizeof(dirname), "%s/default", basedir); - dirname[sizeof(dirname)-1] = '\0'; - add_matching_files(&name_list, dirname, suffix); - - list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { - execute_command(name_loop->name, udev->subsystem); - list_del(&name_loop->node); - } - -} diff --git a/udev_remove.c b/udev_remove.c index 2df555327b..cf28ff37a9 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -140,26 +140,20 @@ static int delete_node(struct udevice *udev) */ int udev_remove_device(struct udevice *udev) { - const char *temp; - if (udev->type != DEV_BLOCK && udev->type != DEV_CLASS) return 0; - if (udev_db_get_device(udev, udev->devpath) == 0) { - if (udev->ignore_remove) { - dbg("remove event for '%s' requested to be ignored by rule", udev->name); - return 0; - } - dbg("remove name='%s'", udev->name); - udev_db_delete_device(udev); - } else { - /* fall back to kernel name */ - temp = strrchr(udev->devpath, '/'); - if (temp == NULL) - return -ENODEV; - strlcpy(udev->name, &temp[1], sizeof(udev->name)); - info("'%s' not found in database, falling back on default name", udev->name); + /* remove node only if we can find it in our database */ + if (udev_db_get_device(udev, udev->devpath) != 0) { + dbg("'%s' not found in database, ignore event", udev->name); + return -1; } + if (udev->ignore_remove) { + dbg("remove event for '%s' requested to be ignored by rule", udev->name); + return 0; + } + dbg("remove name='%s'", udev->name); + udev_db_delete_device(udev); /* use full path to the environment */ snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); diff --git a/udev_rules.c b/udev_rules.c index 631cc4270a..cbd76e66eb 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -731,7 +731,7 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d list_for_each_entry(rule, &udev_rule_list, node) { dbg("process rule"); if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { - if (udev->name[0] != '\0' && rule->name[0] != '\0') { + if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { dbg("node name already set, rule ignored"); continue; } @@ -776,73 +776,84 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d } /* collect symlinks */ - if (!udev->symlink_final && rule->symlink[0] != '\0') { + if (!udev->symlink_final && rule->symlink_operation != KEY_OP_UNSET) { char temp[PATH_SIZE]; char *pos, *next; if (rule->symlink_operation == KEY_OP_ASSIGN_FINAL) udev->symlink_final = 1; - else if (rule->symlink_operation == KEY_OP_ASSIGN) { + if (rule->symlink_operation == KEY_OP_ASSIGN || rule->symlink_operation == KEY_OP_ASSIGN_FINAL) { struct name_entry *name_loop; struct name_entry *temp_loop; + info("reset symlink list"); list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { list_del(&name_loop->node); free(name_loop); } } - info("configured rule in '%s[%i]' applied, added symlink '%s'", - rule->config_file, rule->config_line, rule->symlink); - strlcpy(temp, rule->symlink, sizeof(temp)); - apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); + if (rule->symlink[0] != '\0') { + info("configured rule in '%s[%i]' applied, added symlink '%s'", + rule->config_file, rule->config_line, rule->symlink); + strlcpy(temp, rule->symlink, sizeof(temp)); + apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); - /* add multiple symlinks separated by spaces */ - pos = temp; - next = strchr(temp, ' '); - while (next) { - next[0] = '\0'; + /* add multiple symlinks separated by spaces */ + pos = temp; + next = strchr(temp, ' '); + while (next) { + next[0] = '\0'; + info("add symlink '%s'", pos); + name_list_add(&udev->symlink_list, pos, 0); + pos = &next[1]; + next = strchr(pos, ' '); + } info("add symlink '%s'", pos); name_list_add(&udev->symlink_list, pos, 0); - pos = &next[1]; - next = strchr(pos, ' '); } - 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[0] != '\0') { - info("configured rule in '%s[%i]' applied, '%s' becomes '%s'", - rule->config_file, rule->config_line, udev->kernel_name, rule->name); + if (rule->name_operation != KEY_OP_UNSET) { + udev->name_set = 1; + if (rule->name[0] == '\0') { + info("configured rule in '%s[%i]' applied, node handling for '%s' supressed", + rule->config_file, rule->config_line, udev->kernel_name); + } else { + strlcpy(udev->name, rule->name, sizeof(udev->name)); + apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + strlcpy(udev->config_file, rule->config_file, sizeof(udev->config_file)); + udev->config_line = rule->config_line; - strlcpy(udev->name, rule->name, sizeof(udev->name)); - apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - strlcpy(udev->config_file, rule->config_file, sizeof(udev->config_file)); - udev->config_line = rule->config_line; - - if (udev->type != DEV_NET) - 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); + info("configured rule in '%s:%i' applied, '%s' becomes '%s'", + rule->config_file, rule->config_line, udev->kernel_name, rule->name); + if (udev->type != DEV_NET) + 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[0] != '\0') { + if (!udev->run_final && rule->run_operation != KEY_OP_UNSET) { char program[PATH_SIZE]; if (rule->run_operation == KEY_OP_ASSIGN_FINAL) udev->run_final = 1; - else if (rule->run_operation == KEY_OP_ASSIGN) { + if (rule->run_operation == KEY_OP_ASSIGN || rule->run_operation == KEY_OP_ASSIGN_FINAL) { struct name_entry *name_loop; struct name_entry *temp_loop; + info("reset run list"); list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { list_del(&name_loop->node); free(name_loop); } } - strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); + if (rule->run[0] != '\0') { + strlcpy(program, rule->run, sizeof(program)); + apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); + } } if (rule->last_rule) { @@ -866,113 +877,58 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d return 0; } -int udev_rules_get_run(struct udevice *udev) +int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) { struct udev_rule *rule; - char program[PATH_SIZE]; /* look for a matching rule to apply */ list_for_each_entry(rule, &udev_rule_list, node) { dbg("process rule"); - if (rule->run[0] == '\0') + if (rule->run_operation == KEY_OP_UNSET) continue; - if (rule->name[0] != '\0' || rule->symlink[0] != '\0' || + if (rule->name_operation != KEY_OP_UNSET || rule->symlink_operation != KEY_OP_UNSET || rule->mode != 0000 || rule->owner[0] != '\0' || rule->group[0] != '\0') { dbg("skip rule that names a device"); continue; } - if (rule->action_operation != KEY_OP_UNSET) { - dbg("check for " KEY_ACTION " rule->action='%s' udev->action='%s'", - rule->action, udev->action); - if (strcmp_pattern(rule->action, udev->action) != 0) { - dbg(KEY_ACTION " is not matching"); - if (rule->action_operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_ACTION " matches"); - if (rule->action_operation == KEY_OP_NOMATCH) - continue; + if (match_rule(udev, rule, NULL, sysfs_device) == 0) { + if (rule->ignore_device) { + info("configured rule in '%s[%i]' applied, '%s' is ignored", + rule->config_file, rule->config_line, udev->kernel_name); + udev->ignore_device = 1; + return 0; } - dbg(KEY_ACTION " key is true"); - } - if (rule->kernel_operation != KEY_OP_UNSET) { - dbg("check for " KEY_KERNEL " rule->kernel='%s' udev->kernel_name='%s'", - rule->kernel, udev->kernel_name); - if (strcmp_pattern(rule->kernel, udev->kernel_name) != 0) { - dbg(KEY_KERNEL " is not matching"); - if (rule->kernel_operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_KERNEL " matches"); - if (rule->kernel_operation == KEY_OP_NOMATCH) - continue; - } - dbg(KEY_KERNEL " key is true"); - } + if (!udev->run_final && rule->run_operation != KEY_OP_UNSET) { + char program[PATH_SIZE]; - if (rule->subsystem_operation != KEY_OP_UNSET) { - dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' udev->subsystem='%s'", - rule->subsystem, udev->subsystem); - if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { - dbg(KEY_SUBSYSTEM " is not matching"); - if (rule->subsystem_operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_SUBSYSTEM " matches"); - if (rule->subsystem_operation == KEY_OP_NOMATCH) - continue; - } - dbg(KEY_SUBSYSTEM " key is true"); - } + if (rule->run_operation == KEY_OP_ASSIGN || rule->run_operation == KEY_OP_ASSIGN_FINAL) { + struct name_entry *name_loop; + struct name_entry *temp_loop; - if (rule->env_pair_count) { - int i; - - dbg("check for " KEY_ENV " pairs"); - for (i = 0; i < rule->env_pair_count; i++) { - struct key_pair *pair; - const char *value; - - pair = &rule->env_pair[i]; - value = getenv(pair->name); - if (!value) { - dbg(KEY_ENV "{'%s'} is not found", pair->name); - continue; + info("reset run list"); + list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { + list_del(&name_loop->node); + free(name_loop); + } } - if (strcmp_pattern(pair->value, value) != 0) { - dbg(KEY_ENV "{'%s'} is not matching", pair->name); - if (pair->operation != KEY_OP_NOMATCH) - continue; - } else { - dbg(KEY_ENV "{'%s'} matches", pair->name); - if (pair->operation == KEY_OP_NOMATCH) - continue; + if (rule->run[0] != '\0') { + strlcpy(program, rule->run, sizeof(program)); + apply_format(udev, program, sizeof(program), NULL, NULL); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); } + if (rule->run_operation == KEY_OP_ASSIGN_FINAL) + break; } - dbg(KEY_ENV " key is true"); - } - /* rule matches */ - - if (rule->ignore_device) { - info("configured rule in '%s[%i]' applied, '%s' is ignored", - rule->config_file, rule->config_line, udev->kernel_name); - udev->ignore_device = 1; - return 0; - } - - strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), NULL, NULL); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); - - if (rule->last_rule) { - dbg("last rule to be applied"); - break; + if (rule->last_rule) { + dbg("last rule to be applied"); + break; + } } } diff --git a/udev_rules.h b/udev_rules.h index f4a74bba45..75ffd5cb0f 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -96,6 +96,7 @@ struct udev_rule { int env_pair_count; char name[PATH_SIZE]; + enum key_operation name_operation; char symlink[PATH_SIZE]; enum key_operation symlink_operation; char owner[USER_SIZE]; @@ -120,7 +121,7 @@ extern struct list_head udev_rule_list; extern int udev_rules_init(void); extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev); -extern int udev_rules_get_run(struct udevice *udev); +extern int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device); extern void udev_rules_close(void); #endif diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 3f07521ccb..57c797dd31 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -349,21 +349,19 @@ static int rules_parse(const char *filename) if (strncasecmp(key, KEY_NAME, sizeof(KEY_NAME)-1) == 0) { attr = get_key_attribute(key + sizeof(KEY_NAME)-1); - /* FIXME: remove old style options and make OPTIONS= mandatory */ if (attr != NULL) { if (strstr(attr, OPTION_PARTITIONS) != NULL) { dbg("creation of partition nodes requested"); rule.partitions = DEFAULT_PARTITIONS_COUNT; } + /* FIXME: remove old style option and make OPTIONS= mandatory */ if (strstr(attr, OPTION_IGNORE_REMOVE) != NULL) { dbg("remove event should be ignored"); rule.ignore_remove = 1; } } - if (value[0] != '\0') - strlcpy(rule.name, value, sizeof(rule.name)); - else - rule.ignore_device = 1; + rule.name_operation = operation; + strlcpy(rule.name, value, sizeof(rule.name)); valid = 1; continue; } diff --git a/udevstart.c b/udevstart.c index 34f3835d65..d1a0a8379c 100644 --- a/udevstart.c +++ b/udevstart.c @@ -37,6 +37,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" +#include "udev_sysfs.h" #include "udev.h" #include "udev_version.h" #include "logging.h" @@ -110,25 +111,37 @@ static int add_device(const char *path, const char *subsystem) const char *devpath; devpath = &path[strlen(sysfs_path)]; - - /* set environment for callouts and dev.d/ */ setenv("DEVPATH", devpath, 1); setenv("SUBSYSTEM", subsystem, 1); - dbg("exec: '%s' (%s)\n", devpath, path); class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg ("sysfs_open_class_device_path failed"); - return -ENODEV; + return -1; } udev_init_device(&udev, devpath, subsystem, "add"); - udev_add_device(&udev, class_dev); + udev.devt = get_devt(class_dev); + if (!udev.devt) { + dbg ("sysfs_open_class_device_path failed"); + return -1; + } + udev_rules_get_name(&udev, class_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto exit; + } + if (udev.name[0] == '\0') { + info("device node creation supressed"); + goto run; + } + udev_add_device(&udev, class_dev); if (udev.devname[0] != '\0') setenv("DEVNAME", udev.devname, 1); +run: if (udev_run && !list_empty(&udev.run_list)) { struct name_entry *name_loop; @@ -137,6 +150,7 @@ static int add_device(const char *path, const char *subsystem) execute_command(name_loop->name, udev.subsystem); } +exit: sysfs_close_class_device(class_dev); udev_cleanup_device(&udev); From 9607c4222c08c2d3def2faeac62f6cca5d3ce119 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 5 Jun 2005 17:11:09 +0200 Subject: [PATCH 1315/4284] klibc: version 1.0.14 Signed-off-by: Kay Sievers --- klibc/Makefile | 5 +++ klibc/include/{net => netinet}/if_ether.h | 0 klibc/include/netpacket/packet.h | 1 + klibc/include/signal.h | 4 --- klibc/klcc.1 | 43 ++++++++++++++++++++--- klibc/klcc.in | 15 ++++++-- klibc/klibc/SYSCALLS.def | 32 +++++++++++------ klibc/klibc/arch/i386/Makefile.inc | 1 + klibc/klibc/arch/x86_64/MCONFIG | 5 +++ klibc/klibc/arch/x86_64/Makefile.inc | 3 +- klibc/klibc/arch/x86_64/syscall.S | 6 ++-- klibc/klibc/fgets.c | 1 + klibc/klibc/sigaction.c | 35 ++++++++++++++++-- klibc/klibc/sigpending.c | 4 ++- klibc/klibc/sigprocmask.c | 4 ++- klibc/klibc/sigsuspend.c | 4 ++- klibc/klibc/strntoumax.c | 13 +++---- klibc/makeklcc.pl | 0 klibc/version | 2 +- 19 files changed, 141 insertions(+), 37 deletions(-) rename klibc/include/{net => netinet}/if_ether.h (100%) create mode 100644 klibc/include/netpacket/packet.h mode change 100644 => 100755 klibc/makeklcc.pl diff --git a/klibc/Makefile b/klibc/Makefile index 5071e60da4..e634aaccb5 100644 --- a/klibc/Makefile +++ b/klibc/Makefile @@ -69,4 +69,9 @@ local-install: $(CROSS)klcc $(INSTALL_DATA) klcc.1 $(INSTALLROOT)$(mandir)/man1/$(KCROSS)klcc.1 $(INSTALL_EXEC) $(KCROSS)klcc $(INSTALLROOT)$(bindir) +# This does all the prep work needed to turn a freshly exported git repository +# into a release tarball tree +release: klibc.spec + rm -f maketar.sh + -include MCONFIG diff --git a/klibc/include/net/if_ether.h b/klibc/include/netinet/if_ether.h similarity index 100% rename from klibc/include/net/if_ether.h rename to klibc/include/netinet/if_ether.h diff --git a/klibc/include/netpacket/packet.h b/klibc/include/netpacket/packet.h new file mode 100644 index 0000000000..b5e8e0e11f --- /dev/null +++ b/klibc/include/netpacket/packet.h @@ -0,0 +1 @@ +#include diff --git a/klibc/include/signal.h b/klibc/include/signal.h index ab3c98d6e4..05930bdea1 100644 --- a/klibc/include/signal.h +++ b/klibc/include/signal.h @@ -82,10 +82,6 @@ __extern int sigaction(int, const struct sigaction *, struct sigaction *); __extern int sigprocmask(int, const sigset_t *, sigset_t *); __extern int sigpending(sigset_t *); __extern int sigsuspend(const sigset_t *); -__extern int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); -__extern int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); -__extern int rt_sigpending(sigset_t *, size_t); -__extern int rt_sigsuspend(const sigset_t *, size_t); __extern int raise(int); __extern int kill(pid_t, int); diff --git a/klibc/klcc.1 b/klibc/klcc.1 index a6f979c6c4..76334a3a54 100644 --- a/klibc/klcc.1 +++ b/klibc/klcc.1 @@ -1,4 +1,4 @@ -.\" $Id: klcc.1,v 1.2 2005/03/02 02:24:17 hpa Exp $ +.\" $Id: klcc.1,v 1.3 2005/04/19 23:27:46 hpa Exp $ .\" ----------------------------------------------------------------------- .\" .\" Copyright 2005 H. Peter Anvin - All Rights Reserved @@ -39,7 +39,9 @@ klcc \- compile a program against klibc .B klcc is a wrapper around .BR gcc (1) -to compile a program against the +and +.BR ld (1) +which compiles and links a program against the .B klibc tiny C library. It supports most .B gcc @@ -63,7 +65,12 @@ or option to use the default optimization level; this will generally result in the smallest binaries. You may want to use .B \-s -when linking, however. +when linking, however. Use +.B \-O0 +to compile without any optimization whatsoever; this may not work depending +on the version of +.B gcc +used. .PP Use the .B \-shared @@ -72,10 +79,38 @@ or option to compile for and link against shared or static klibc. Note that shared klibc only supports running against the exact same klibc binary as the binary was linked with. +.PP +In addition to standard +.B gcc +options, +.B klcc +supports options of the form \fB\-print-klibc-\fP\fIoption\fP, +which prints the corresponding klibc configuration option. .SH AUTHOR Written by H. Peter Anvin . .SH COPYRIGHT -Copyright \(co 2005 H. Peter Anvin. +Copyright \(co 2005 H. Peter Anvin \- All Rights Reserved +.PP +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following +conditions: +.PP +The above copyright notice and this permission notice shall +be included in all copies or substantial portions of the Software. +.PP +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. .SH "SEE ALSO" .BR gcc (1) diff --git a/klibc/klcc.in b/klibc/klcc.in index 36c4d9b3ee..5629f24f1c 100644 --- a/klibc/klcc.in +++ b/klibc/klcc.in @@ -1,5 +1,7 @@ # -*- perl -*- +use IPC::Open3; + # Standard includes @includes = ("-I${prefix}/${KCROSS}include/arch/${ARCH}", "-I${prefix}/${KCROSS}include/bits${BITSIZE}", @@ -57,7 +59,7 @@ sub files_with_lang($$) { # Skip object files if ( $need ne 'obj' ) { - unless ( $xopt eq $need ) { + unless ( $xopt eq $need || $need eq 'stdin') { push(@as, '-x', $need); $xopt = $need; } @@ -79,7 +81,11 @@ sub syserr($) { # Run a program; printing out the command line if $verbose is set sub mysystem(@) { print STDERR join(' ', @_), "\n" if ( $verbose ); - return system(@_); + my $cmd = shift; + open(INPUT, "<&STDIN"); # dup STDIN filehandle to INPUT + my $childpid = open3("<&INPUT", ">&STDOUT", ">&STDERR", $cmd, @_); + waitpid ($childpid, 0); + return $?; } # @@ -117,6 +123,11 @@ while ( defined($a = shift(@ARGV)) ) { # Not an option. Must be a filename then. push(@files, $a); $flang{$a} = $lang || filename2lang($a); + } elsif ( $a eq '-' ) { + # gcc gets its input from stdin + push(@files, $a); + # prevent setting -x + $flang{$a} = 'stdin' } elsif ( $a =~ /^-print-klibc-(.*)$/ ) { # This test must precede -print if ( defined($conf{$1}) ) { diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def index e8b9a7f176..11d8c9a47e 100644 --- a/klibc/klibc/SYSCALLS.def +++ b/klibc/klibc/SYSCALLS.def @@ -145,17 +145,29 @@ ssize_t pwrite64,pwrite::pwrite(int, void *, size_t, off_t) ; ; Signal operations ; -int kill(pid_t, int) ; We really should get rid of the non-rt_* of these, but that takes -; sanitizing for all architectures, sigh... - int sigaction(int, const struct sigaction *, struct sigaction *) - int sigsuspend(const sigset_t *) - int sigpending(sigset_t *) - int sigprocmask(int, const sigset_t *, sigset_t *) -int rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) -int rt_sigsuspend(const sigset_t *, size_t) -int rt_sigpending(sigset_t *, size_t) -int rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t) +; sanitizing for all architectures, sigh. +#ifdef __NR_sigaction +int sigaction::__sigaction(int, const struct sigaction *, struct sigaction *) +#else +int rt_sigaction::__rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) +#endif +#ifdef __NR_sigsuspend +int sigsuspend(const sigset_t *) +#else +int rt_sigsuspend::__rt_sigsuspend(const sigset_t *, size_t) +#endif +#ifdef __NR_sigpending +int sigpending(sigset_t *) +#else +int rt_sigpending::__rt_sigpending(sigset_t *, size_t) +#endif +#ifdef __NR_sigprocmask +int sigprocmask(int, const sigset_t *, sigset_t *) +#else +int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t) +#endif +int kill(pid_t, int) unsigned int alarm(unsigned int) int getitimer(int, struct itimerval *) int setitimer(int, const struct itimerval *, struct itimerval *) diff --git a/klibc/klibc/arch/i386/Makefile.inc b/klibc/klibc/arch/i386/Makefile.inc index 5c320cb453..80344bd0a5 100644 --- a/klibc/klibc/arch/i386/Makefile.inc +++ b/klibc/klibc/arch/i386/Makefile.inc @@ -13,6 +13,7 @@ ARCHOBJS = \ arch/$(ARCH)/setjmp.o \ arch/$(ARCH)/syscall.o \ arch/$(ARCH)/open.o \ + arch/$(ARCH)/sigreturn.o \ arch/$(ARCH)/libgcc/__ashldi3.o \ arch/$(ARCH)/libgcc/__ashrdi3.o \ arch/$(ARCH)/libgcc/__lshrdi3.o \ diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG index 13b6e391f9..c9b5da8bd6 100644 --- a/klibc/klibc/arch/x86_64/MCONFIG +++ b/klibc/klibc/arch/x86_64/MCONFIG @@ -15,8 +15,13 @@ # debugging using gdb. # ARCHREQFLAGS = -m64 +ifeq ($(DEBUG),y) +OPTFLAGS = -Os -fomit-frame-pointer \ + -falign-functions=0 -falign-jumps=0 -falign-loops=0 +else OPTFLAGS = -Os -fno-asynchronous-unwind-tables -fomit-frame-pointer \ -falign-functions=0 -falign-jumps=0 -falign-loops=0 +endif BITSIZE = 64 LDFLAGS = -m elf_x86_64 diff --git a/klibc/klibc/arch/x86_64/Makefile.inc b/klibc/klibc/arch/x86_64/Makefile.inc index d6cc1204e4..26d880d7c7 100644 --- a/klibc/klibc/arch/x86_64/Makefile.inc +++ b/klibc/klibc/arch/x86_64/Makefile.inc @@ -10,7 +10,8 @@ ARCHOBJS = \ arch/$(ARCH)/exits.o \ arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o + arch/$(ARCH)/syscall.o \ + arch/$(ARCH)/sigreturn.o ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) diff --git a/klibc/klibc/arch/x86_64/syscall.S b/klibc/klibc/arch/x86_64/syscall.S index f2c74ae974..17977978b9 100644 --- a/klibc/klibc/arch/x86_64/syscall.S +++ b/klibc/klibc/arch/x86_64/syscall.S @@ -15,14 +15,14 @@ __syscall_common: syscall cmpq $-4095,%rax - jb 1f + jnb 1f + ret # Error return, must set errno +1: negl %eax movl %eax,errno(%rip) # errno is type int, so 32 bits orq $-1,%rax # orq $-1 smaller than movq $-1 - -1: ret .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/fgets.c b/klibc/klibc/fgets.c index 88a145a63f..72f8a13cf1 100644 --- a/klibc/klibc/fgets.c +++ b/klibc/klibc/fgets.c @@ -20,6 +20,7 @@ char *fgets(char *s, int n, FILE *f) return NULL; } *p++ = ch; + n--; if ( ch == '\n' ) break; } diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c index 819ffd4fe8..85f42a244c 100644 --- a/klibc/klibc/sigaction.c +++ b/klibc/klibc/sigaction.c @@ -5,11 +5,40 @@ #include #include -#ifndef __NR_sigaction +__extern void __sigreturn(void); +__extern int __sigaction(int, const struct sigaction *, struct sigaction *); +__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { - return rt_sigaction(sig, act, oact, sizeof(sigset_t)); -} + int rv; +#if defined(__i386__) || defined(__x86_64__) + /* x86-64, and the Fedora i386 kernel, are broken without SA_RESTORER */ + struct sigaction sa; + + if ( act && !(act->sa_flags & SA_RESTORER) ) { + sa = *act; + act = &sa; + + /* The kernel can't be trusted to have a valid default restorer */ + sa.sa_flags |= SA_RESTORER; + sa.sa_restorer = &__sigreturn; + } #endif + +#ifdef __NR_sigaction + rv = __sigaction(sig, act, oact); +#else + rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t)); +#endif + + +#if defined(__i386__) || defined(__x86_64__) + if ( oact && (oact->sa_restorer == &__sigreturn) ) { + oact->sa_flags &= ~SA_RESTORER; + } +#endif + + return rv; +} diff --git a/klibc/klibc/sigpending.c b/klibc/klibc/sigpending.c index 76d2b1a7f6..decfe32b1b 100644 --- a/klibc/klibc/sigpending.c +++ b/klibc/klibc/sigpending.c @@ -7,9 +7,11 @@ #ifndef __NR_sigpending +__extern __rt_sigpending(sigset_t *, size_t); + int sigpending(sigset_t *set) { - return rt_sigpending(set, sizeof(sigset_t)); + return __rt_sigpending(set, sizeof(sigset_t)); } #endif diff --git a/klibc/klibc/sigprocmask.c b/klibc/klibc/sigprocmask.c index b5e58b28b8..372e0fd90d 100644 --- a/klibc/klibc/sigprocmask.c +++ b/klibc/klibc/sigprocmask.c @@ -7,9 +7,11 @@ #ifndef __NR_sigprocmask +__extern __rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); + int sigprocmask(int how, const sigset_t *set, sigset_t *oset) { - return rt_sigprocmask(how, set, oset, sizeof(sigset_t)); + return __rt_sigprocmask(how, set, oset, sizeof(sigset_t)); } #endif diff --git a/klibc/klibc/sigsuspend.c b/klibc/klibc/sigsuspend.c index a927999ae6..22f9a46681 100644 --- a/klibc/klibc/sigsuspend.c +++ b/klibc/klibc/sigsuspend.c @@ -7,9 +7,11 @@ #ifndef __NR_sigsuspend +__extern int __rt_sigsuspend(const sigset_t *, size_t); + int sigsuspend(const sigset_t *mask) { - return rt_sigsuspend(mask, sizeof *mask); + return __rt_sigsuspend(mask, sizeof *mask); } #endif diff --git a/klibc/klibc/strntoumax.c b/klibc/klibc/strntoumax.c index 4e30637d2c..4c47fe8662 100644 --- a/klibc/klibc/strntoumax.c +++ b/klibc/klibc/strntoumax.c @@ -33,12 +33,13 @@ uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) } /* Single optional + or - */ - if ( n && *nptr == '-' ) { - minus = 1; - nptr++; - n--; - } else if ( n && *nptr == '+' ) { - nptr++; + if ( n ) { + char c = *nptr; + if ( c == '-' || c == '+' ) { + minus = (c == '-'); + nptr++; + n--; + } } if ( base == 0 ) { diff --git a/klibc/makeklcc.pl b/klibc/makeklcc.pl old mode 100644 new mode 100755 diff --git a/klibc/version b/klibc/version index 238d6e882a..5b09c67c20 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -1.0.7 +1.0.14 From e2bd03ff63789e0ffcc1955f15d9927f3ce87465 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Mon, 6 Jun 2005 13:46:19 -0700 Subject: [PATCH 1316/4284] Fix udevinfo for empty sysfs directories udevinfo would die if it ran into a sysfs directory with no attributes. This is valid for a lot of scsi devices, so now we just continue on up the chain. Signed-off-by: Greg Kroah-Hartman --- udevinfo.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index 31e719fe35..69e5335b7c 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -152,19 +152,16 @@ static int print_device_chain(const char *path) /* look the device chain upwards */ while (sysfs_dev != NULL) { - attr_list = sysfs_get_device_attributes(sysfs_dev); - if (attr_list == NULL) { - fprintf(stderr, "couldn't open device directory\n"); - retval = -1; - goto exit; - } - printf(" looking at the device chain at '%s':\n", sysfs_dev->path); printf(" BUS==\"%s\"\n", sysfs_dev->bus); printf(" ID==\"%s\"\n", sysfs_dev->bus_id); printf(" DRIVER==\"%s\"\n", sysfs_dev->driver_name); - print_all_attributes(attr_list); + attr_list = sysfs_get_device_attributes(sysfs_dev); + if (attr_list != NULL) + print_all_attributes(attr_list); + else + printf("\n"); sysfs_dev = sysfs_get_device_parent(sysfs_dev); if (sysfs_dev == NULL) From 561d4c5a3a66830ecfb92fdfd7ccee19cf01c2a7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 8 Jun 2005 11:57:53 +0200 Subject: [PATCH 1317/4284] udevd: allow starting of udevd with stopped exec-queue Signed-off-by: Kay Sievers --- test/simple-build-check.sh | 0 udevd.c | 16 ++++++++++++++-- udevstart.c | 10 ++++------ 3 files changed, 18 insertions(+), 8 deletions(-) mode change 100644 => 100755 test/simple-build-check.sh diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh old mode 100644 new mode 100755 diff --git a/udevd.c b/udevd.c index b5597eab40..6fb0bd9433 100644 --- a/udevd.c +++ b/udevd.c @@ -766,6 +766,8 @@ int main(int argc, char *argv[], char *envp[]) fd_set readfds; const char *value; int uevent_nl_active = 0; + int daemonize = 0; + int i; logging_init("udevd"); udev_init_config(); @@ -776,8 +778,18 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - /* daemonize on request */ - if (argc == 2 && strcmp(argv[1], "-d") == 0) { + for (i = 1 ; i < argc; i++) { + char *arg = argv[i]; + if (strcmp(arg, "--daemon") == 0 || strcmp(arg, "-d") == 0) { + info("will daemonize"); + daemonize = 1; + } + if (strcmp(arg, "--stop-exec-queue") == 0) { + info("will not execute event until START_EXEC_QUEUE is received"); + stop_exec_q = 1; + } + } + if (daemonize) { pid_t pid; pid = fork(); diff --git a/udevstart.c b/udevstart.c index d1a0a8379c..bd91e96f6a 100644 --- a/udevstart.c +++ b/udevstart.c @@ -117,30 +117,29 @@ static int add_device(const char *path, const char *subsystem) class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { - dbg ("sysfs_open_class_device_path failed"); + dbg("sysfs_open_class_device_path failed"); return -1; } udev_init_device(&udev, devpath, subsystem, "add"); udev.devt = get_devt(class_dev); if (!udev.devt) { - dbg ("sysfs_open_class_device_path failed"); + dbg("sysfs_open_class_device_path failed"); return -1; } udev_rules_get_name(&udev, class_dev); if (udev.ignore_device) { - info("device event will be ignored"); + dbg("device event will be ignored"); goto exit; } if (udev.name[0] == '\0') { - info("device node creation supressed"); + dbg("device node creation supressed"); goto run; } udev_add_device(&udev, class_dev); if (udev.devname[0] != '\0') setenv("DEVNAME", udev.devname, 1); - run: if (udev_run && !list_empty(&udev.run_list)) { struct name_entry *name_loop; @@ -149,7 +148,6 @@ run: list_for_each_entry(name_loop, &udev.run_list, node) execute_command(name_loop->name, udev.subsystem); } - exit: sysfs_close_class_device(class_dev); udev_cleanup_device(&udev); From 60d7b201008edb3c6d9226ef336c7ae0daa5742f Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 13 Jun 2005 22:38:42 +0200 Subject: [PATCH 1318/4284] udevcontrol: fix exit code Kay is lazy! :) Signed-off-by: Kay Sievers --- udevcontrol.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/udevcontrol.c b/udevcontrol.c index 6a278a04c1..4a54af805e 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -95,8 +95,13 @@ int main(int argc, char *argv[], char *envp[]) retval = sendto(sock, &usend_msg, sizeof(usend_msg), 0, (struct sockaddr *)&saddr, addrlen); - if (retval == -1) + if (retval == -1) { info("error sending message (%s)", strerror(errno)); + retval = 1; + } else { + dbg("sent message '%x' (%u bytes sent)\n", usend_msg.type, retval); + retval = 0; + } close(sock); From 0fa98832b5be9893e1b26252c20b68d730b77173 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 14 Jun 2005 13:28:24 +0200 Subject: [PATCH 1319/4284] udev man page: add operators Patch from: Hannes Reinecke Signed-off-by: Kay Sievers --- udev.8.in | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/udev.8.in b/udev.8.in index e4c1c11af2..b4edd5aebd 100644 --- a/udev.8.in +++ b/udev.8.in @@ -104,6 +104,36 @@ Every rule consists of a list of comma separated key value fields: .sp .IR "key " ,[ "key " ,...] .P +Each key has the following format: +.sp +.IR "name op value" +.P +There are distinct key operation types, depending on the type of the key, it +does a comparison or an assignment. +.P +Comparison operators are: +.TP +.B == +Compare for equality. +.TP +.B != +Compare for non-equality. +.P +Assignment operators are: +.TP +.B += +Add the value to a key that holds a list of entries. +.TP +.B := +Assign a value to a key finally; disallow any later changes, which +is useful to prevent changes by any later rules. +.TP +.B = +Asign a value to a key. Keys that represent a list, are reset and only this +single value is assigned. While this operator still works inplicitely as +comparison on keys that can't get a value assigned, its usage as an comparison +operator is deprecated. +.P The following key names can be used to match against device properties: .TP .B BUS From d27d8d6a8d63ffce768842324dd53067b9b0e905 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 14 Jun 2005 16:12:31 +0200 Subject: [PATCH 1320/4284] udev: fix netdev RUN handling Signed-off-by: Kay Sievers --- udev.c | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/udev.c b/udev.c index d623cbcc67..3eb788f4c1 100644 --- a/udev.c +++ b/udev.c @@ -138,29 +138,29 @@ int main(int argc, char *argv[], char *envp[]) wait_for_class_device(class_dev, &error); /* get major/minor */ - if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS) { + if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS) udev.devt = get_devt(class_dev); - if (udev.devt) { - /* name device */ - udev_rules_get_name(&udev, class_dev); - if (udev.ignore_device) { - info("device event will be ignored"); - goto exit; - } - if (udev.name[0] == '\0') { - info("device node creation supressed"); - goto run; - } - /* create node, store in db */ - retval = udev_add_device(&udev, class_dev); - } else { - dbg("no dev-file found"); - udev_rules_get_run(&udev, NULL); - if (udev.ignore_device) { - info("device event will be ignored"); - goto exit; - } + if (udev.type == DEV_NET || udev.devt) { + /* name device */ + udev_rules_get_name(&udev, class_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto cleanup; + } + if (udev.name[0] == '\0') { + info("device node creation supressed"); + goto cleanup; + } + + /* create node, store in db */ + retval = udev_add_device(&udev, class_dev); + } else { + dbg("no dev-file found"); + udev_rules_get_run(&udev, NULL); + if (udev.ignore_device) { + info("device event will be ignored"); + goto cleanup; } } sysfs_close_class_device(class_dev); @@ -169,7 +169,7 @@ int main(int argc, char *argv[], char *envp[]) udev_rules_get_run(&udev, NULL); if (udev.ignore_device) { dbg("device event will be ignored"); - goto exit; + goto cleanup; } /* get name from db, remove db-entry, delete node */ @@ -198,14 +198,14 @@ int main(int argc, char *argv[], char *envp[]) sysfs_close_device(devices_dev); if (udev.ignore_device) { info("device event will be ignored"); - goto exit; + goto cleanup; } } else if (strcmp(action, "remove") == 0) { dbg("devices remove"); udev_rules_get_run(&udev, NULL); if (udev.ignore_device) { info("device event will be ignored"); - goto exit; + goto cleanup; } } } @@ -219,9 +219,10 @@ run: execute_command(name_loop->name, udev.subsystem); } -exit: +cleanup: udev_cleanup_device(&udev); +exit: logging_close(); return retval; } From 510de9c9e40c27b1eb224dc49ac439997bfe4db6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 14 Jun 2005 17:02:55 +0200 Subject: [PATCH 1321/4284] udevinitsend: handle replay messages correctly Signed-off-by: Kay Sievers --- udevd.c | 13 ++++++++----- udevd.h | 5 ++++- udevinitsend.c | 39 ++++++++++++++++++--------------------- udevsend.c | 2 +- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/udevd.c b/udevd.c index 6fb0bd9433..873b05d946 100644 --- a/udevd.c +++ b/udevd.c @@ -542,13 +542,15 @@ static struct uevent_msg *get_udevd_msg(void) } switch (usend_msg.type) { - case UDEVD_UEVENT: - dbg("udevd message (UEVENT) received"); + case UDEVD_UDEVSEND: + case UDEVD_INITSEND: + dbg("udevd event message received"); envbuf_size = size - offsetof(struct udevd_msg, envbuf); dbg("envbuf_size=%i", envbuf_size); msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size); if (msg == NULL) return NULL; + msg->type = usend_msg.type; return msg; case UDEVD_STOP_EXEC_QUEUE: dbg("udevd message (STOP_EXEC_QUEUE) received"); @@ -566,7 +568,7 @@ switch (usend_msg.type) { } /* receive the kernel user event message and do some sanity checks */ -static struct uevent_msg *get_uevent_msg(void) +static struct uevent_msg *get_nl_msg(void) { struct uevent_msg *msg; int bufpos; @@ -591,6 +593,7 @@ static struct uevent_msg *get_uevent_msg(void) msg = get_msg_from_envbuf(&buffer[bufpos], size-bufpos); if (msg == NULL) return NULL; + msg->type = UDEVD_NL; /* validate message */ pos = strchr(buffer, '@'); @@ -935,7 +938,7 @@ int main(int argc, char *argv[], char *envp[]) msg = get_udevd_msg(); if (msg) { /* discard kernel messages if netlink is active */ - if (uevent_nl_active && msg->seqnum != 0) { + if (uevent_nl_active && msg->type == UDEVD_UDEVSEND && msg->seqnum != 0) { dbg("skip uevent_helper message, netlink is active"); free(msg); continue; @@ -945,7 +948,7 @@ int main(int argc, char *argv[], char *envp[]) } if (FD_ISSET(uevent_nl_sock, &workreadfds)) { - msg = get_uevent_msg(); + msg = get_nl_msg(); if (msg) { msg_queue_insert(msg); /* disable kernel uevent_helper with first netlink message */ diff --git a/udevd.h b/udevd.h index 60732fe052..b8fb6913c9 100644 --- a/udevd.h +++ b/udevd.h @@ -50,7 +50,9 @@ enum udevd_msg_type { UDEVD_UNKNOWN, - UDEVD_UEVENT, + UDEVD_UDEVSEND, + UDEVD_INITSEND, + UDEVD_NL, UDEVD_STOP_EXEC_QUEUE, UDEVD_START_EXEC_QUEUE, }; @@ -63,6 +65,7 @@ struct udevd_msg { }; struct uevent_msg { + enum udevd_msg_type type; struct list_head node; pid_t pid; long queue_time; diff --git a/udevinitsend.c b/udevinitsend.c index 05c39b99b3..c7d56fc259 100644 --- a/udevinitsend.c +++ b/udevinitsend.c @@ -58,17 +58,18 @@ void log_message (int level, const char *format, ...) * Scan a file, write all variables into the msgbuf and * fires the message to udevd. */ -static int udevsend(char *filename, int sock, int ignore_loops) +static int udevsend(char *filename, int sock, int disable_loop_detection) { - struct stat statbuf; - int fd, bufpos; - char *fdmap, *ls, *le, *ch; - struct udevd_msg usend_msg; - int retval = 0; + static struct udevd_msg usend_msg; int usend_msg_len; + int bufpos = 0; + struct stat statbuf; + int fd; + char *fdmap, *ls, *le, *ch; struct sockaddr_un saddr; socklen_t addrlen; - + int retval = 0; + if (stat(filename,&statbuf) < 0) { dbg("cannot stat %s: %s\n", filename, strerror(errno)); return 1; @@ -91,24 +92,23 @@ static int udevsend(char *filename, int sock, int ignore_loops) strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - memset(usend_msg.envbuf, 0, UEVENT_BUFFER_SIZE+256); - bufpos = 0; memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); strcpy(usend_msg.magic, UDEV_MAGIC); + usend_msg.type = UDEVD_INITSEND; ls = fdmap; ch = le = ls; while (*ch && ch < fdmap + statbuf.st_size) { - le = strchr(ch,'\n'); + le = strchr(ch, '\n'); if (!le) break; - ch = strchr(ch,'='); + ch = strchr(ch, '='); if (!ch) break; /* prevent loops in the scripts we execute */ if (strncmp(ls, "UDEVD_EVENT=", 12) == 0) { - if (!ignore_loops) { + if (!disable_loop_detection) { dbg("event already handled by udev\n"); retval = -1; break; @@ -161,7 +161,8 @@ int main(int argc, char *argv[], char *envp[]) char *event_file = NULL; DIR *dirstream; struct dirent *direntry; - int retval = 1, ignore_loops = 0; + int retval = 1; + int disable_loop_detection = 0; int sock; logging_init("udevinitsend"); @@ -186,14 +187,10 @@ int main(int argc, char *argv[], char *envp[]) break; case 'l': - dbg("ignoring loops\n"); - ignore_loops = 1; + dbg("disable loop detection, ignore UDEVD_EVENT\n"); + disable_loop_detection = 1; break; - case 'V': - printf("udevinitsend, version 0.1\n"); - return 0; - case 'h': retval = 0; } @@ -217,11 +214,11 @@ int main(int argc, char *argv[], char *envp[]) if (!strcmp(direntry->d_name,".") || !strcmp(direntry->d_name,"..")) continue; - retval = udevsend(direntry->d_name, sock, ignore_loops); + retval = udevsend(direntry->d_name, sock, disable_loop_detection); } closedir(dirstream); } else if (event_file) { - retval = udevsend(event_file, sock, ignore_loops); + retval = udevsend(event_file, sock, disable_loop_detection); } if (sock != -1) diff --git a/udevsend.c b/udevsend.c index 888a88daa0..42ef0271dd 100644 --- a/udevsend.c +++ b/udevsend.c @@ -146,7 +146,7 @@ int main(int argc, char *argv[], char *envp[]) memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); strcpy(usend_msg.magic, UDEV_MAGIC); - usend_msg.type = UDEVD_UEVENT; + usend_msg.type = UDEVD_UDEVSEND; /* copy all keys to send buffer */ for (i = 0; envp[i]; i++) { From e5b7f7b83428cb50f165b49408c2f7559dcfefef Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 14 Jun 2005 20:27:08 +0200 Subject: [PATCH 1322/4284] klibc: add missing files Signed-off-by: Kay Sievers --- klibc/include/net/route.h | 1 + klibc/klibc/Kbuild | 149 ++++++++++++++++++++++++++++ klibc/klibc/arch/i386/sigreturn.S | 15 +++ klibc/klibc/arch/x86_64/sigreturn.S | 15 +++ 4 files changed, 180 insertions(+) create mode 100644 klibc/include/net/route.h create mode 100644 klibc/klibc/Kbuild create mode 100644 klibc/klibc/arch/i386/sigreturn.S create mode 100644 klibc/klibc/arch/x86_64/sigreturn.S diff --git a/klibc/include/net/route.h b/klibc/include/net/route.h new file mode 100644 index 0000000000..a60df24c0a --- /dev/null +++ b/klibc/include/net/route.h @@ -0,0 +1 @@ +#include diff --git a/klibc/klibc/Kbuild b/klibc/klibc/Kbuild new file mode 100644 index 0000000000..be239a6647 --- /dev/null +++ b/klibc/klibc/Kbuild @@ -0,0 +1,149 @@ +# +# Kbuild file for klibc +# + +libc-y := vsnprintf.o snprintf.o vsprintf.o sprintf.o \ + asprintf.o vasprintf.o \ + vsscanf.o sscanf.o ctypes.o \ + strntoumax.o strntoimax.o \ + atoi.o atol.o atoll.o \ + strtol.o strtoll.o strtoul.o strtoull.o \ + strtoimax.o strtoumax.o \ + globals.o exitc.o atexit.o onexit.o \ + execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \ + fork.o wait.o wait3.o waitpid.o system.o setpgrp.o getpgrp.o \ + daemon.o \ + printf.o vprintf.o fprintf.o vfprintf.o perror.o \ + statfs.o fstatfs.o umount.o \ + open.o fopen.o fread.o fread2.o fgetc.o fgets.o \ + fwrite.o fwrite2.o fputc.o fputs.o puts.o putchar.o \ + sleep.o usleep.o strtotimespec.o strtotimeval.o \ + raise.o abort.o assert.o alarm.o pause.o \ + __signal.o sysv_signal.o bsd_signal.o siglist.o siglongjmp.o \ + sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ + brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ + memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ + memmove.o memchr.o memrchr.o \ + strcasecmp.o strncasecmp.o strndup.o strerror.o \ + strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o strnlen.o \ + strncat.o strlcpy.o strlcat.o \ + strstr.o strncmp.o strncpy.o strrchr.o \ + strxspn.o strspn.o strcspn.o strpbrk.o strsep.o strtok.o \ + gethostname.o getdomainname.o getcwd.o \ + seteuid.o setegid.o \ + getenv.o setenv.o putenv.o __put_env.o unsetenv.o \ + getopt.o readdir.o \ + syslog.o closelog.o pty.o getpt.o isatty.o reboot.o \ + time.o utime.o llseek.o nice.o getpriority.o \ + qsort.o \ + lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \ + inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ + inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \ + send.o recv.o + +libc-$(CONFIG_KLIBC_ERRLIST) += errlist.o + +libc-$(CONFIG_KLIBC_ZLIB) += \ + zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/gzio.o \ + zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \ + zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/inffast.o + +##### +# Add any architecture-specific rules +include $(obj)/arch/$(ARCH)/Makefile.inc + +##### +# Shared definitions +LIB := libc.a +SOLIB := libc.so +SOHASH := klibc.so +CRT0 := arch/$(ARCH)/crt0.o +INTERP_O := interp.o + +always := $(CRT0) $(LIB) $(SOLIB) $(SOHASH) $(INTERP_O) +LIB := $(call objectify,$(LIB)) +SOLIB := $(call objectify,$(SOLIB)) +SOHASH := $(call objectify,$(SOHASH)) +CRT0 := $(call objectify,$(CRT0)) +INTERP_O := $(call objectify,$(INTERP_O)) + +targets := arch/$(ARCH)/crt0.o +targets += $(libc-y) $(ARCHOBJS) + +# Generate syscall stubs +subdir-y += syscalls +# Generate socket calls stubs +subdir-y += socketcalls + +# Tell make to descend before building libs +$(obj)/syscalls/syscalls.o: $(obj)/syscalls +$(obj)/socketcalls/socketcalls.o: $(obj)/socketcalls + +##### +# Readable errormessages extracted from src.. +targets += errlist.c +quiet_cmd_errlist = GEN $@ + cmd_errlist = $(PERL) $< $(LINUXINCLUDE) -errlist > $@ || rm -f $@ + +$(obj)/errlist.c: $(srctree)/$(src)/makeerrlist.pl + $(call cmd,errlist) + +# full list of dependencies for klibc +libc-deps = $(call objectify, $(libc-y) $(ARCHOBJS)) \ + $(call objectify, syscalls/syscalls.o socketcalls/socketcalls.o) + +###### +# Build static library: libc.a +targets += libc.a __static_init.o +quiet_cmd_libc = USERAR $@ + cmd_libc = rm -f $@; \ + $(USERAR) cq $@ $(filter-out FORCE,$^); \ + $(USERRANLIB) $@ + +$(LIB): $(call objectify,__static_init.o) $(libc-deps) FORCE + $(call if_changed,libc) + +###### +# Build shared library +targets += libc.so __shared_init.o + +quiet_cmd_libcso = LD $@ + cmd_libcso = $(USERLD) $(USERLDFLAGS) $(USERSHAREDFLAGS) \ + -o $@ $(filter-out FORCE,$^) $(USERLIBGCC) + +$(SOLIB): $(CRT0) $(call objectify,__shared_init.o) $(libc-deps) FORCE + $(call if_changed,libcso) + + +##### +# Build sha1 hash values +targets += klibc.so libc.so.hash +hostprogs-y := sha1hash + +quiet_cmd_solibhash = HASH $@ + cmd_solibhash = $(USERNM) $< | egrep '^[0-9a-fA-F]+ [ADRTW] ' | \ + sort | $(obj)/sha1hash > $@ +$(SOLIB).hash: $(SOLIB) $(obj)/sha1hash FORCE + $(call if_changed,solibhash) + +quiet_cmd_sohash = GEN $@ + cmd_sohash = cat $< > $@; \ + $(USERSTRIP) $(USERSTRIPFLAGS) $@; \ + rm -f $(obj)/klibc-??????????????????????.so; \ + ln -f $@ $(obj)/klibc-`cat $(SOLIB).hash`.so +$(SOHASH): $(SOLIB) $(SOLIB).hash + $(call cmd,sohash) + + +##### +# build interp.o +targets += interp.o + +quiet_cmd_interp = BUILD $@ + cmd_interp = $(USERCC) $(usercflags) -D__ASSEMBLY__ \ + -DLIBDIR=\"$(SHLIBDIR)\" \ + -DSOHASH=\"`cat $(SOLIB).hash`\" \ + -c -o $@ $< + +$(INTERP_O): $(obj)/interp.S $(SOLIB).hash + $(call if_changed,interp) diff --git a/klibc/klibc/arch/i386/sigreturn.S b/klibc/klibc/arch/i386/sigreturn.S new file mode 100644 index 0000000000..f2a32419d3 --- /dev/null +++ b/klibc/klibc/arch/i386/sigreturn.S @@ -0,0 +1,15 @@ +# +# arch/i386/sigreturn.S +# + +#include + + .text + .align 4 + .globl __sigreturn + .type __sigreturn,@function +__sigreturn: + pop %eax # Have no idea why this is needed... + movl $__NR_sigreturn,%eax + int $0x80 + .size __sigreturn,.-__sigreturn diff --git a/klibc/klibc/arch/x86_64/sigreturn.S b/klibc/klibc/arch/x86_64/sigreturn.S new file mode 100644 index 0000000000..66e7152344 --- /dev/null +++ b/klibc/klibc/arch/x86_64/sigreturn.S @@ -0,0 +1,15 @@ +/* + * arch/x86_64/sigreturn.S + */ + +#include + + .text + .align 4 + .globl __sigreturn + .type __sigreturn,@function +__sigreturn: + movl $__NR_rt_sigreturn,%eax + syscall + + .size __sigreturn,.-__sigreturn From 3632a3685883d3270145c59d5764de6246547943 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 15 Jun 2005 03:07:14 +0200 Subject: [PATCH 1323/4284] udeveventrecorder: add small program that writes an event to disk Used for debugging and event replay from initramfs. Signed-off-by: Kay Sievers --- Makefile | 12 ++++- udevd.c | 6 +-- udeveventrecorder.c | 127 ++++++++++++++++++++++++++++++++++++++++++++ udevinitsend.c | 15 +++++- 4 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 udeveventrecorder.c diff --git a/Makefile b/Makefile index d36bd5866c..9ad6ee103b 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,7 @@ ROOT = udev DAEMON = udevd SENDER = udevsend INITSENDER = udevinitsend +RECORDER = udeveventrecorder CONTROL = udevcontrol INFO = udevinfo TESTER = udevtest @@ -204,7 +205,7 @@ endif # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(INITSENDER) $(CONTROL) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) +all: $(ROOT) $(SENDER) $(INITSENDER) $(RECORDER) $(CONTROL) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -271,6 +272,7 @@ $(INFO).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(DAEMON).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(SENDER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(INITSENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(RECORDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(CONTROL).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(STARTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) @@ -298,6 +300,10 @@ $(INITSENDER): $(KLCC) $(INITSENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(INITSENDER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ +$(RECORDER): $(KLCC) $(RECORDER).o $(OBJS) udevd.h + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(RECORDER).o $(OBJS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + $(CONTROL): $(KLCC) $(CONTROL).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CONTROL).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ @@ -313,7 +319,7 @@ clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) \ - $(SENDER) $(INITSENDER) $(CONTROL) $(TESTER) $(STARTER) + $(SENDER) $(INITSENDER) $(RECORDER) $(CONTROL) $(TESTER) $(STARTER) -rm -f ccdv $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ @@ -374,6 +380,7 @@ install: install-config install-man install-dev.d all $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(INITSENDER) $(DESTDIR)$(sbindir)/$(INITSENDER) + $(INSTALL_PROGRAM) -D $(RECORDER) $(DESTDIR)$(sbindir)/$(RECORDER) $(INSTALL_PROGRAM) -D $(CONTROL) $(DESTDIR)$(sbindir)/$(CONTROL) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) @@ -400,6 +407,7 @@ uninstall: uninstall-man uninstall-dev.d - rm $(sbindir)/$(DAEMON) - rm $(sbindir)/$(SENDER) - rm $(sbindir)/$(INITSENDER) + - rm $(sbindir)/$(RECORDER) - rm $(sbindir)/$(CONTROL) - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) diff --git a/udevd.c b/udevd.c index 873b05d946..f4c986b870 100644 --- a/udevd.c +++ b/udevd.c @@ -660,7 +660,7 @@ static void udev_done(int pid) list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { sysinfo(&info); - info("seq %llu exit, %ld sec old", msg->seqnum, info.uptime - msg->queue_time); + info("seq %llu exit, %ld seconds old", msg->seqnum, info.uptime - msg->queue_time); run_queue_delete(msg); /* we want to run the exec queue manager since there may @@ -951,9 +951,9 @@ int main(int argc, char *argv[], char *envp[]) msg = get_nl_msg(); if (msg) { msg_queue_insert(msg); - /* disable kernel uevent_helper with first netlink message */ + /* disable udevsend with first netlink message */ if (!uevent_nl_active) { - info("uevent_nl message received, disable uevent_helper messages"); + info("uevent_nl message received, disable udevsend messages"); uevent_nl_active = 1; } } diff --git a/udeveventrecorder.c b/udeveventrecorder.c new file mode 100644 index 0000000000..af7ea7c15c --- /dev/null +++ b/udeveventrecorder.c @@ -0,0 +1,127 @@ +/* + * udeveventrecorder.c + * + * Userspace devfs + * + * Copyright (C) 2004, 2005 Olaf Hering + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udev_version.h" +#include "udev_utils.h" +#include "logging.h" + +#define BUFSIZE 12345 +#define FNSIZE 123 + +static int log = 0; + +#ifdef USE_LOG +void log_message (int priority, const char *format, ...) +{ + va_list args; + + if (priority > log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +int main(int argc, char **argv, char **envp) +{ + int fd, i; + unsigned long seq; + char **ep = envp; + char *buf, *p, *a; + struct stat sb; + const char *env; + + if (stat("/events", &sb) || !(S_ISDIR(sb.st_mode))) + return 1; + + env = getenv("UDEV_LOG"); + if (env) + log = log_priority(env); + + logging_init("udeveventrecorder"); + dbg("version %s", UDEV_VERSION); + + p = getenv("SEQNUM"); + a = getenv("ACTION"); + buf = malloc(FNSIZE); + if (!(buf && a && argv[1])) + goto error; + if (p) + seq = strtoul(p, NULL, 0); + else + seq = 0; + + snprintf(buf, FNSIZE, "/events/debug.%05lu.%s.%s.%u", seq, argv[1], a ? a : "", getpid()); + if ((fd = open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0) { + err("error creating '%s'", buf); + goto error; + } + free(buf); + p = malloc(BUFSIZE); + buf = p; + buf += snprintf(buf, p + BUFSIZE - buf, "set --"); + for (i = 1; i < argc; ++i) { + buf += snprintf(buf, p + BUFSIZE - buf, " %s", argv[i]); + if (buf > p + BUFSIZE) + goto full; + } + buf += snprintf(buf, p + BUFSIZE - buf, "\n"); + if (buf > p + BUFSIZE) + goto full; + while (*ep) { + unsigned char *t; + t = memchr(*ep, '=', strlen(*ep)); + if (t) { + *t = '\0'; + t++; + buf += snprintf(buf, p + BUFSIZE - buf, "%s='%s'\n", *ep, t); + --t; + *t = '='; + } + ep++; + if (buf > p + BUFSIZE) + break; + } + +full: + buf = p; + write(fd, buf, strlen(buf)); + close(fd); + free(buf); + return 0; + +error: + fprintf(stderr, "record enviroment to /events, to be called from udev context\n"); + return 1; +} diff --git a/udevinitsend.c b/udevinitsend.c index c7d56fc259..31a7109d1b 100644 --- a/udevinitsend.c +++ b/udevinitsend.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -38,16 +39,21 @@ #include "udev.h" #include "udev_version.h" #include "udevd.h" +#include "udev_utils.h" #include "logging.h" +static int log = 0; #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { va_list args; + if (priority > log) + return; + va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif @@ -164,6 +170,11 @@ int main(int argc, char *argv[], char *envp[]) int retval = 1; int disable_loop_detection = 0; int sock; + const char *env; + + env = getenv("UDEV_LOG"); + if (env) + log = log_priority(env); logging_init("udevinitsend"); dbg("version %s", UDEV_VERSION); From 8ab44e3fd0b8fd4555db973d4c2c305ca09e787d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 16 Jun 2005 01:58:47 +0200 Subject: [PATCH 1324/4284] udevd: control log-priority of the running daemon with udevcontrol Signed-off-by: Kay Sievers --- Makefile | 2 +- etc/udev/udev.conf.in | 1 - udev.c | 2 +- udev_utils.c | 4 +-- udevcontrol.c | 33 +++++++++++++++----- udevd.c | 70 ++++++++++++++++++++++++++----------------- udevd.h | 8 +++-- udevinitsend.c | 2 +- udevsend.c | 2 +- 9 files changed, 78 insertions(+), 46 deletions(-) diff --git a/Makefile b/Makefile index 9ad6ee103b..bdb87e5651 100644 --- a/Makefile +++ b/Makefile @@ -388,7 +388,7 @@ install: install-config install-man install-dev.d all - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug ifndef DESTDIR - killall $(DAEMON) - - $(sbindir)/$(DAEMON) -d + - $(sbindir)/$(DAEMON) --daemon - rm -rf $(udevdb) endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 9d5300a861..efdb1d1808 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -1,5 +1,4 @@ # udev.conf -# # Where in the filesystem to place the device nodes udev_root="@udevdir@" diff --git a/udev.c b/udev.c index 3eb788f4c1..f7b9bf3573 100644 --- a/udev.c +++ b/udev.c @@ -109,7 +109,7 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } - /* export log_level , as called programs may want to do the same as udev */ + /* export log_priority , as called programs may want to do the same as udev */ if (udev_log_priority) { char priority[32]; diff --git a/udev_utils.c b/udev_utils.c index d605631088..64a7ba9caa 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -409,10 +409,10 @@ int execute_command(const char *command, const char *subsystem) close(devnull); } retval = execv(arg, argv); - err("exec of child failed"); + err("exec of child '%s' failed", command); _exit(1); case -1: - dbg("fork of child failed"); + dbg("fork of child '%s' failed", command); break; return -1; default: diff --git a/udevcontrol.c b/udevcontrol.c index 4a54af805e..98776ccefd 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -37,18 +37,23 @@ #include "udev.h" #include "udev_version.h" #include "udevd.h" +#include "udev_utils.h" #include "logging.h" /* global variables */ static int sock = -1; +static int log = 0; #ifdef USE_LOG -void log_message (int level, const char *format, ...) +void log_message (int priority, const char *format, ...) { va_list args; + if (priority > log) + return; + va_start(args, format); - vsyslog(level, format, args); + vsyslog(priority, format, args); va_end(args); } #endif @@ -59,25 +64,37 @@ int main(int argc, char *argv[], char *envp[]) static struct udevd_msg usend_msg; struct sockaddr_un saddr; socklen_t addrlen; + const char *env; int retval = 1; + env = getenv("UDEV_LOG"); + if (env) + log = log_priority(env); + logging_init("udevcontrol"); dbg("version %s", UDEV_VERSION); if (argc != 2) { - info("usage: udevcontrol \n"); + info("usage: udevcontrol "); goto exit; } memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); strcpy(usend_msg.magic, UDEV_MAGIC); - if (strstr(argv[1], "stop_exec_queue")) + if (!strcmp(argv[1], "stop_exec_queue")) usend_msg.type = UDEVD_STOP_EXEC_QUEUE; - else if (strstr(argv[1], "start_exec_queue")) + else if (!strcmp(argv[1], "start_exec_queue")) usend_msg.type = UDEVD_START_EXEC_QUEUE; - else { - info("unknown command\n"); + else if (!strncmp(argv[1], "log_priority=", strlen("log_priority="))) { + int *level = (int *) usend_msg.envbuf; + char *prio = &argv[1][strlen("log_priority=")]; + + usend_msg.type = UDEVD_SET_LOG_LEVEL; + *level = log_priority(prio); + dbg("send log_priority=%i", *level); + } else { + err("unknown command\n"); goto exit; } @@ -99,7 +116,7 @@ int main(int argc, char *argv[], char *envp[]) info("error sending message (%s)", strerror(errno)); retval = 1; } else { - dbg("sent message '%x' (%u bytes sent)\n", usend_msg.type, retval); + dbg("sent message '%x' (%u bytes sent)", usend_msg.type, retval); retval = 0; } diff --git a/udevd.c b/udevd.c index f4c986b870..209b9fcd87 100644 --- a/udevd.c +++ b/udevd.c @@ -50,7 +50,7 @@ /* global variables*/ static int udevd_sock; -static int uevent_nl_sock; +static int uevent_netlink_sock; static pid_t sid; static int pipefds[2]; @@ -173,8 +173,8 @@ static void execute_udev(struct uevent_msg *msg) switch (pid) { case 0: /* child */ - if (uevent_nl_sock != -1) - close(uevent_nl_sock); + if (uevent_netlink_sock != -1) + close(uevent_netlink_sock); close(udevd_sock); logging_close(); @@ -362,6 +362,9 @@ static void exec_queue_manager(void) struct 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) @@ -506,6 +509,7 @@ static struct uevent_msg *get_udevd_msg(void) struct ucred *cred; char cred_msg[CMSG_SPACE(sizeof(struct ucred))]; int envbuf_size; + int *intval; memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); iov.iov_base = &usend_msg; @@ -541,10 +545,10 @@ static struct uevent_msg *get_udevd_msg(void) return NULL; } -switch (usend_msg.type) { - case UDEVD_UDEVSEND: - case UDEVD_INITSEND: - dbg("udevd event message received"); + switch (usend_msg.type) { + case UDEVD_UEVENT_UDEVSEND: + case UDEVD_UEVENT_INITSEND: + info("udevd event message received"); envbuf_size = size - offsetof(struct udevd_msg, envbuf); dbg("envbuf_size=%i", envbuf_size); msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size); @@ -553,14 +557,24 @@ switch (usend_msg.type) { msg->type = usend_msg.type; return msg; case UDEVD_STOP_EXEC_QUEUE: - dbg("udevd message (STOP_EXEC_QUEUE) received"); + info("udevd message (STOP_EXEC_QUEUE) received"); stop_exec_q = 1; break; case UDEVD_START_EXEC_QUEUE: - dbg("udevd message (START_EXEC_QUEUE) received"); + info("udevd message (START_EXEC_QUEUE) received"); stop_exec_q = 0; exec_queue_manager(); break; + case UDEVD_SET_LOG_LEVEL: + intval = (int *) usend_msg.envbuf; + info("udevd message (SET_LOG_PRIORITY) received, udev_log_priority=%i", *intval); + udev_log_priority = *intval; + break; + case UDEVD_SET_MAX_CHILDS: + intval = (int *) usend_msg.envbuf; + info("udevd message (UDEVD_SET_MAX_CHILDS) received, max_childs=%i", *intval); + max_childs = *intval; + break; default: dbg("unknown message type"); } @@ -568,7 +582,7 @@ switch (usend_msg.type) { } /* receive the kernel user event message and do some sanity checks */ -static struct uevent_msg *get_nl_msg(void) +static struct uevent_msg *get_netlink_msg(void) { struct uevent_msg *msg; int bufpos; @@ -576,7 +590,7 @@ static struct uevent_msg *get_nl_msg(void) static char buffer[UEVENT_BUFFER_SIZE + 512]; char *pos; - size = recv(uevent_nl_sock, &buffer, sizeof(buffer), 0); + size = recv(uevent_netlink_sock, &buffer, sizeof(buffer), 0); if (size < 0) { if (errno != EINTR) dbg("unable to receive udevd message"); @@ -593,7 +607,7 @@ static struct uevent_msg *get_nl_msg(void) msg = get_msg_from_envbuf(&buffer[bufpos], size-bufpos); if (msg == NULL) return NULL; - msg->type = UDEVD_NL; + msg->type = UDEVD_UEVENT_NETLINK; /* validate message */ pos = strchr(buffer, '@'); @@ -732,7 +746,7 @@ static int init_udevd_socket(void) return 0; } -static int init_uevent_nl_sock(void) +static int init_uevent_netlink_sock(void) { struct sockaddr_nl snl; int retval; @@ -742,18 +756,18 @@ static int init_uevent_nl_sock(void) snl.nl_pid = getpid(); snl.nl_groups = 0xffffffff; - uevent_nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); - if (uevent_nl_sock == -1) { + uevent_netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); + if (uevent_netlink_sock == -1) { dbg("error getting socket, %s", strerror(errno)); return -1; } - retval = bind(uevent_nl_sock, (struct sockaddr *) &snl, + retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl)); if (retval < 0) { dbg("bind failed, %s", strerror(errno)); - close(uevent_nl_sock); - uevent_nl_sock = -1; + close(uevent_netlink_sock); + uevent_netlink_sock = -1; return -1; } @@ -768,7 +782,7 @@ int main(int argc, char *argv[], char *envp[]) struct sigaction act; fd_set readfds; const char *value; - int uevent_nl_active = 0; + int uevent_netlink_active = 0; int daemonize = 0; int i; @@ -788,7 +802,7 @@ int main(int argc, char *argv[], char *envp[]) daemonize = 1; } if (strcmp(arg, "--stop-exec-queue") == 0) { - info("will not execute event until START_EXEC_QUEUE is received"); + info("will not execute events until START_EXEC_QUEUE is received"); stop_exec_q = 1; } } @@ -865,7 +879,7 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGALRM, &act, NULL); sigaction(SIGCHLD, &act, NULL); - if (init_uevent_nl_sock() < 0) { + if (init_uevent_netlink_sock() < 0) { dbg("uevent socket not available"); } @@ -918,8 +932,8 @@ int main(int argc, char *argv[], char *envp[]) FD_ZERO(&readfds); FD_SET(udevd_sock, &readfds); - if (uevent_nl_sock != -1) - FD_SET(uevent_nl_sock, &readfds); + if (uevent_netlink_sock != -1) + FD_SET(uevent_netlink_sock, &readfds); FD_SET(pipefds[0], &readfds); maxsockplus = udevd_sock+1; while (1) { @@ -938,7 +952,7 @@ int main(int argc, char *argv[], char *envp[]) msg = get_udevd_msg(); if (msg) { /* discard kernel messages if netlink is active */ - if (uevent_nl_active && msg->type == UDEVD_UDEVSEND && msg->seqnum != 0) { + if (uevent_netlink_active && msg->type == UDEVD_UEVENT_UDEVSEND && msg->seqnum != 0) { dbg("skip uevent_helper message, netlink is active"); free(msg); continue; @@ -947,14 +961,14 @@ int main(int argc, char *argv[], char *envp[]) } } - if (FD_ISSET(uevent_nl_sock, &workreadfds)) { - msg = get_nl_msg(); + if (FD_ISSET(uevent_netlink_sock, &workreadfds)) { + msg = get_netlink_msg(); if (msg) { msg_queue_insert(msg); /* disable udevsend with first netlink message */ - if (!uevent_nl_active) { + if (!uevent_netlink_active) { info("uevent_nl message received, disable udevsend messages"); - uevent_nl_active = 1; + uevent_netlink_active = 1; } } } diff --git a/udevd.h b/udevd.h index b8fb6913c9..34bfe931ba 100644 --- a/udevd.h +++ b/udevd.h @@ -50,11 +50,13 @@ enum udevd_msg_type { UDEVD_UNKNOWN, - UDEVD_UDEVSEND, - UDEVD_INITSEND, - UDEVD_NL, + UDEVD_UEVENT_UDEVSEND, + UDEVD_UEVENT_INITSEND, + UDEVD_UEVENT_NETLINK, UDEVD_STOP_EXEC_QUEUE, UDEVD_START_EXEC_QUEUE, + UDEVD_SET_LOG_LEVEL, + UDEVD_SET_MAX_CHILDS, }; diff --git a/udevinitsend.c b/udevinitsend.c index 31a7109d1b..26ae5c8418 100644 --- a/udevinitsend.c +++ b/udevinitsend.c @@ -100,7 +100,7 @@ static int udevsend(char *filename, int sock, int disable_loop_detection) memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); strcpy(usend_msg.magic, UDEV_MAGIC); - usend_msg.type = UDEVD_INITSEND; + usend_msg.type = UDEVD_UEVENT_INITSEND; ls = fdmap; ch = le = ls; diff --git a/udevsend.c b/udevsend.c index 42ef0271dd..bdc69d0508 100644 --- a/udevsend.c +++ b/udevsend.c @@ -146,7 +146,7 @@ int main(int argc, char *argv[], char *envp[]) memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); strcpy(usend_msg.magic, UDEV_MAGIC); - usend_msg.type = UDEVD_UDEVSEND; + usend_msg.type = UDEVD_UEVENT_UDEVSEND; /* copy all keys to send buffer */ for (i = 0; envp[i]; i++) { From 7628ff6e144a94c48e463d0188022f5661e0ba40 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 16 Jun 2005 03:22:27 +0200 Subject: [PATCH 1325/4284] udevcontrol: add max_childs command Signed-off-by: Kay Sievers --- udevcontrol.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/udevcontrol.c b/udevcontrol.c index 98776ccefd..f19ae98fba 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -65,6 +65,8 @@ int main(int argc, char *argv[], char *envp[]) struct sockaddr_un saddr; socklen_t addrlen; const char *env; + const char *val; + int *intval; int retval = 1; env = getenv("UDEV_LOG"); @@ -75,7 +77,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("version %s", UDEV_VERSION); if (argc != 2) { - info("usage: udevcontrol "); + err("error finding comand"); goto exit; } @@ -87,20 +89,25 @@ int main(int argc, char *argv[], char *envp[]) else if (!strcmp(argv[1], "start_exec_queue")) usend_msg.type = UDEVD_START_EXEC_QUEUE; else if (!strncmp(argv[1], "log_priority=", strlen("log_priority="))) { - int *level = (int *) usend_msg.envbuf; - char *prio = &argv[1][strlen("log_priority=")]; - + intval = (int *) usend_msg.envbuf; + val = &argv[1][strlen("log_priority=")]; usend_msg.type = UDEVD_SET_LOG_LEVEL; - *level = log_priority(prio); - dbg("send log_priority=%i", *level); + *intval = log_priority(val); + info("send log_priority=%i", *intval); + } else if (!strncmp(argv[1], "max_childs=", strlen("max_childs="))) { + intval = (int *) usend_msg.envbuf; + val = &argv[1][strlen("max_childs=")]; + usend_msg.type = UDEVD_SET_MAX_CHILDS; + *intval = atoi(val); + info("send max_childs=%i", *intval); } else { - err("unknown command\n"); + err("error parsing command\n"); goto exit; } sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { - info("error getting socket"); + err("error getting socket"); goto exit; } @@ -116,7 +123,7 @@ int main(int argc, char *argv[], char *envp[]) info("error sending message (%s)", strerror(errno)); retval = 1; } else { - dbg("sent message '%x' (%u bytes sent)", usend_msg.type, retval); + dbg("sent message type=0x%02x, %u bytes sent", usend_msg.type, retval); retval = 0; } From e33d1515e2d22fe8f872556dd649e0db3b601057 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 16 Jun 2005 03:26:16 +0200 Subject: [PATCH 1326/4284] Makefile: remove dev.d/ hotplug.d/ from install target Signed-off-by: Kay Sievers --- Makefile | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index bdb87e5651..8694b917a2 100644 --- a/Makefile +++ b/Makefile @@ -63,10 +63,7 @@ etcdir = ${prefix}/etc sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin mandir = ${prefix}/usr/share/man -hotplugdir = ${etcdir}/hotplug.d/default configdir = ${etcdir}/udev -initdir = ${etcdir}/init.d -dev_ddir = ${etcdir}/dev.d srcdir = . INSTALL = /usr/bin/install -c @@ -347,16 +344,6 @@ install-config: $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir)/rules.d/50-udev.rules; \ fi -install-dev.d: - $(INSTALL) -d $(DESTDIR)$(dev_ddir)/default - $(INSTALL_PROGRAM) -D etc/dev.d/net/hotplug.dev $(DESTDIR)$(dev_ddir)/net/hotplug.dev - -uninstall-dev.d: - - rm $(dev_ddir)/net/hotplug.dev - - rmdir $(dev_ddir)/net - - rmdir $(dev_ddir)/default - - rmdir $(dev_ddir) - install-man: $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 $(INSTALL_DATA) -D udevinfo.8 $(DESTDIR)$(mandir)/man8/udevinfo.8 @@ -373,19 +360,15 @@ uninstall-man: - rm $(mandir)/man8/udevd.8 - rm $(mandir)/man8/udevsend.8 -install: install-config install-man install-dev.d all +install: install-config install-man all $(INSTALL) -d $(DESTDIR)$(udevdir) - $(INSTALL) -d $(DESTDIR)$(hotplugdir) $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) - $(INSTALL_PROGRAM) -D $(INITSENDER) $(DESTDIR)$(sbindir)/$(INITSENDER) - $(INSTALL_PROGRAM) -D $(RECORDER) $(DESTDIR)$(sbindir)/$(RECORDER) $(INSTALL_PROGRAM) -D $(CONTROL) $(DESTDIR)$(sbindir)/$(CONTROL) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) - - ln -f -s $(sbindir)/$(SENDER) $(DESTDIR)$(hotplugdir)/10-udev.hotplug ifndef DESTDIR - killall $(DAEMON) - $(sbindir)/$(DAEMON) --daemon @@ -397,8 +380,7 @@ endif -C $$target $@ ; \ done ; \ -uninstall: uninstall-man uninstall-dev.d - - rm $(hotplugdir)/10-udev.hotplug +uninstall: uninstall-man - rm $(configdir)/rules.d/50-udev.rules - rm $(configdir)/udev.conf - rmdir $(configdir)/rules.d @@ -412,7 +394,6 @@ uninstall: uninstall-man uninstall-dev.d - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) - rm $(usrbindir)/$(TESTER) - - rmdir $(hotplugdir) - rm -rf $(udevdb) - rmdir $(udevdir) - killall $(DAEMON) From ae8d5e161fe916e39f226ce53f2c5f8b31f582a0 Mon Sep 17 00:00:00 2001 From: Stefan Schweizer Date: Sat, 11 Jun 2005 08:09:00 +0200 Subject: [PATCH 1327/4284] [PATCH] Dialout group fix for capi devices in the gentoo rules file currently it is not possible to use the capi devices for users even when the user is in the dialout group. Please apply the attached patch and fix the issue. There is also a gentoo bug about this: http://bugs.gentoo.org/show_bug.cgi?id=92445 diff -ur udev-056.orig/etc/udev/gentoo/udev.rules udev-056/etc/udev/gentoo/udev.rules --- etc/udev/gentoo/udev.rules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index db8c5d9263..65113aebf7 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -51,8 +51,8 @@ KERNEL="timer", NAME="snd/%k" KERNEL="seq", NAME="snd/%k" # capi devices -KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" -KERNEL="capi*", NAME="capi/%n" +KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20", GROUP="dialout" +KERNEL="capi*", NAME="capi/%n", GROUP="dialout" # cpu devices KERNEL="cpu[0-9]*", NAME="cpu/%n/cpuid" From 57663b364beda200ec189c889e7d9c9fede37c9a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 18 Jun 2005 10:57:10 +0200 Subject: [PATCH 1328/4284] remove device node, when type block/char has changed Signed-off-by: Kay Sievers --- README | 3 +-- udev_add.c | 33 ++++++++++++++++----------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/README b/README index 54cee659a8..a2ce9c7d36 100644 --- a/README +++ b/README @@ -10,8 +10,7 @@ To use: - Your 2.6 kernel must have had CONFIG_HOTPLUG enabled when it was built. -- Make sure sysfs is mounted. udev will figure out where sysfs is mounted, but - the traditional place for it is at /sys. You can mount it by hand by running: +- Make sure sysfs is mounted at /sys. You can mount it by running: mount -t sysfs none /sys - Make sure you have the latest version of the linux-hotplug scripts. They are diff --git a/udev_add.c b/udev_add.c index 2081e503c7..89af96570f 100644 --- a/udev_add.c +++ b/udev_add.c @@ -52,23 +52,6 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo struct stat stats; int retval = 0; - if (stat(file, &stats) != 0) - goto create; - - /* preserve node with already correct numbers, to not change the inode number */ - if (((stats.st_mode & S_IFMT) == S_IFBLK || (stats.st_mode & S_IFMT) == S_IFCHR) && - (stats.st_rdev == devt)) { - info("preserve file '%s', cause it has correct dev_t", file); - selinux_setfilecon(file, udev->kernel_name, stats.st_mode); - goto perms; - } - - if (unlink(file) != 0) - dbg("unlink(%s) failed with error '%s'", file, strerror(errno)); - else - dbg("already present file '%s' unlinked", file); - -create: switch (udev->type) { case DEV_BLOCK: mode |= S_IFBLK; @@ -81,6 +64,22 @@ create: return -EINVAL; } + if (stat(file, &stats) != 0) + goto create; + + /* preserve node with already correct numbers, to not change the inode number */ + if ((stats.st_mode & S_IFMT) == (mode & S_IFMT) && (stats.st_rdev == devt)) { + info("preserve file '%s', cause it has correct dev_t", file); + selinux_setfilecon(file, udev->kernel_name, stats.st_mode); + goto perms; + } + + if (unlink(file) != 0) + dbg("unlink(%s) failed with error '%s'", file, strerror(errno)); + else + dbg("already present file '%s' unlinked", file); + +create: selinux_setfscreatecon(file, udev->kernel_name, mode); retval = mknod(file, mode, devt); selinux_resetfscreatecon(); From bf5d2964730e63316861e310d1f24c165b11e961 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 20 Jun 2005 00:29:38 +0200 Subject: [PATCH 1329/4284] prepare for module loading rules and add MODALIAS key Signed-off-by: Kay Sievers --- test/udev-test.pl | 51 ++++++++++- udev_rules.c | 214 +++++++++++++++++++++++++++++++++++---------- udev_rules.h | 6 ++ udev_rules_parse.c | 14 +++ udev_sysfs.c | 54 ++++++------ 5 files changed, 261 insertions(+), 78 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 884abf9e8b..9225352130 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -241,7 +241,7 @@ BUS=="scsi", ID=="0:0:0:0", NAME="first_disk%n" EOF }, { - desc => "test NAME substitution chars", + desc => "test substitution chars", subsys => "block", devpath => "/block/sda/sda3", exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , @@ -250,7 +250,7 @@ BUS=="scsi", ID=="0:0:0:0", NAME="Major:%M:minor:%m:kernelnumber:%n:bus:%b" EOF }, { - desc => "test NAME substitution chars (with length limit)", + desc => "test substitution chars (with length limit)", subsys => "block", devpath => "/block/sda/sda3", exp_name => "M8-m3-n3-b0:0-sIBM" , @@ -360,6 +360,51 @@ EOF exp_name => "my-foo8" , rules => < "test substitution by variable name", + subsys => "block", + devpath => "/block/sda/sda3", + exp_name => "Major:8-minor:3-kernelnumber:3-bus: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-bus: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 => < "yes", option => "clean", rules => <path, name); tmpattr = sysfs_get_classdev_attr(class_dev, name); if (tmpattr) goto attr_found; } if (sysfs_device) { + dbg("look for devices attribute '%s/%s'", sysfs_device->path, name); tmpattr = sysfs_get_device_attr(sysfs_device, name); if (tmpattr) goto attr_found; } - return -1; attr_found: @@ -197,56 +198,133 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, { char temp[PATH_SIZE]; char temp2[PATH_SIZE]; - char *tail, *pos, *cpos, *attr, *rest; + char *head, *tail, *cpos, *attr, *rest; int len; int i; - char c; unsigned int next_free_number; struct sysfs_class_device *class_dev_parent; + enum subst_type { + SUBST_UNKNOWN, + SUBST_DEVPATH, + SUBST_ID, + SUBST_KERNEL_NUMBER, + SUBST_KERNEL_NAME, + SUBST_MAJOR, + SUBST_MINOR, + SUBST_RESULT, + SUBST_SYSFS, + SUBST_ENUM, + SUBST_PARENT, + SUBST_TEMP_NODE, + SUBST_ROOT, + SUBST_MODALIAS, + }; + static const struct subst_map { + char *name; + char fmt; + enum subst_type type; + } map[] = { + { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH }, + { .name = "id", .fmt = 'b', .type = SUBST_ID }, + { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER }, + { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL_NAME }, + { .name = "major", .fmt = 'M', .type = SUBST_MAJOR }, + { .name = "minor", .fmt = 'm', .type = SUBST_MINOR }, + { .name = "result", .fmt = 'c', .type = SUBST_RESULT }, + { .name = "sysfs", .fmt = 's', .type = SUBST_SYSFS }, + { .name = "enum", .fmt = 'e', .type = SUBST_ENUM }, + { .name = "parent", .fmt = 'P', .type = SUBST_PARENT }, + { .name = "tempnode", .fmt = 'N', .type = SUBST_TEMP_NODE }, + { .name = "root", .fmt = 'r', .type = SUBST_ROOT }, + { .name = "modalias", .fmt = 'A', .type = SUBST_MODALIAS }, + {} + }; + enum subst_type type; + const struct subst_map *subst; - pos = string; + head = string; while (1) { - pos = strchr(pos, '%'); - if (pos == NULL) - break; - - pos[0] = '\0'; - tail = pos+1; - len = get_format_len(&tail); - c = tail[0]; - strlcpy(temp, tail+1, sizeof(temp)); - tail = temp; - dbg("format=%c, string='%s', tail='%s'",c , string, tail); + 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; + } + } + } + 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++; + } + break; +found: attr = get_format_attribute(&tail); + strlcpy(temp, tail, sizeof(temp)); + dbg("format=%i, string='%s', tail='%s', class_dev=%p, sysfs_dev=%p", + type ,string, tail, class_dev, sysfs_device); - switch (c) { - case 'p': + switch (type) { + case SUBST_DEVPATH: strlcat(string, udev->devpath, maxsize); - dbg("substitute kernel name '%s'", udev->kernel_name); + dbg("substitute devpath '%s'", udev->devpath); break; - case 'b': + case SUBST_ID: strlcat(string, udev->bus_id, maxsize); dbg("substitute bus_id '%s'", udev->bus_id); break; - case 'k': + case SUBST_KERNEL_NAME: strlcat(string, udev->kernel_name, maxsize); dbg("substitute kernel name '%s'", udev->kernel_name); break; - case 'n': + case SUBST_KERNEL_NUMBER: strlcat(string, udev->kernel_number, maxsize); dbg("substitute kernel number '%s'", udev->kernel_number); - break; - case 'm': - sprintf(temp2, "%d", minor(udev->devt)); - strlcat(string, temp2, maxsize); - dbg("substitute minor number '%s'", temp2); break; - case 'M': + case SUBST_MAJOR: sprintf(temp2, "%d", major(udev->devt)); strlcat(string, temp2, maxsize); dbg("substitute major number '%s'", temp2); break; - case 'c': + 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 */ @@ -280,7 +358,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, dbg("substitute result string '%s'", udev->program_result); } break; - case 's': + case SUBST_SYSFS: if (attr == NULL) { dbg("missing attribute"); break; @@ -307,18 +385,14 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strlcat(string, temp2, maxsize); dbg("substitute sysfs value '%s'", temp2); break; - case '%': - strlcat(string, "%", maxsize); - pos++; - break; - case 'e': + case SUBST_ENUM: next_free_number = find_free_number(udev, string); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); strlcat(string, temp2, maxsize); } break; - case 'P': + case SUBST_PARENT: if (!class_dev) break; class_dev_parent = sysfs_get_classdev_parent(class_dev); @@ -336,7 +410,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, udev_cleanup_device(&udev_parent); } break; - case 'N': + case SUBST_TEMP_NODE: if (udev->tmp_node[0] == '\0') { dbg("create temporary device node for callout"); snprintf(udev->tmp_node, sizeof(udev->tmp_node), "%s/.tmp-%u-%u", @@ -347,19 +421,27 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, strlcat(string, udev->tmp_node, maxsize); dbg("substitute temporary device node name '%s'", udev->tmp_node); break; - case 'r': + case SUBST_ROOT: strlcat(string, udev_root, maxsize); dbg("substitute udev_root '%s'", udev_root); break; + case SUBST_MODALIAS: + if (find_sysfs_attribute(NULL, sysfs_device, "modalias", temp2, sizeof(temp2)) != 0) + break; + strlcat(string, temp2, maxsize); + dbg("substitute MODALIAS '%s'", temp2); + break; default: - err("unknown substitution type '%%%c'", c); + err("unknown substitution type=%i", type); break; } - /* truncate to specified length */ - if (len > 0) - pos[len] = '\0'; + /* possibly truncate to format-char specified length */ + if (len != -1) { + head[len] = '\0'; + dbg("truncate to %i chars, subtitution string becomes '%s'", len, head); + } - strlcat(string, tail, maxsize); + strlcat(string, temp, maxsize); } } @@ -519,6 +601,42 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg(KEY_SUBSYSTEM " key is true"); } + if (rule->devpath_operation != KEY_OP_UNSET) { + dbg("check for " KEY_DEVPATH " rule->devpath='%s' udev->devpath='%s'", + rule->devpath, udev->devpath); + if (strcmp_pattern(rule->devpath, udev->devpath) != 0) { + dbg(KEY_DEVPATH " is not matching"); + if (rule->devpath_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_DEVPATH " matches"); + if (rule->devpath_operation == KEY_OP_NOMATCH) + goto exit; + } + dbg(KEY_DEVPATH " key is true"); + } + + if (rule->modalias_operation != KEY_OP_UNSET) { + char value[NAME_SIZE]; + + if (find_sysfs_attribute(NULL, sysfs_device, "modalias", value, sizeof(value)) != 0) { + dbg(KEY_MODALIAS " value not found"); + goto exit; + } + dbg("check for " KEY_MODALIAS " rule->modalias='%s' modalias='%s'", + rule->modalias, value); + if (strcmp_pattern(rule->modalias, value) != 0) { + dbg(KEY_MODALIAS " is not matching"); + if (rule->modalias_operation != KEY_OP_NOMATCH) + goto exit; + } else { + dbg(KEY_MODALIAS " matches"); + if (rule->modalias_operation == KEY_OP_NOMATCH) + goto exit; + } + dbg(KEY_MODALIAS " key is true"); + } + if (rule->env_pair_count) { int i; @@ -729,13 +847,13 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d /* look for a matching rule to apply */ list_for_each_entry(rule, &udev_rule_list, node) { + if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { + dbg("node name already set, rule ignored"); + continue; + } + dbg("process rule"); if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { - if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { - dbg("node name already set, rule ignored"); - continue; - } - /* apply options */ if (rule->ignore_device) { info("configured rule in '%s[%i]' applied, '%s' is ignored", @@ -917,7 +1035,7 @@ int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) } if (rule->run[0] != '\0') { strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), NULL, NULL); + apply_format(udev, program, sizeof(program), NULL, sysfs_device); dbg("add run '%s'", program); name_list_add(&udev->run_list, program, 0); } diff --git a/udev_rules.h b/udev_rules.h index 75ffd5cb0f..2bf8107543 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -31,6 +31,7 @@ #define KEY_KERNEL "KERNEL" #define KEY_SUBSYSTEM "SUBSYSTEM" #define KEY_ACTION "ACTION" +#define KEY_DEVPATH "DEVPATH" #define KEY_BUS "BUS" #define KEY_ID "ID" #define KEY_PROGRAM "PROGRAM" @@ -38,6 +39,7 @@ #define KEY_DRIVER "DRIVER" #define KEY_SYSFS "SYSFS" #define KEY_ENV "ENV" +#define KEY_MODALIAS "MODALIAS" #define KEY_NAME "NAME" #define KEY_SYMLINK "SYMLINK" #define KEY_OWNER "OWNER" @@ -80,6 +82,8 @@ struct udev_rule { enum key_operation subsystem_operation; char action[NAME_SIZE]; enum key_operation action_operation; + char devpath[PATH_SIZE]; + enum key_operation devpath_operation; char bus[NAME_SIZE]; enum key_operation bus_operation; char id[NAME_SIZE]; @@ -94,6 +98,8 @@ struct udev_rule { int sysfs_pair_count; struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; int env_pair_count; + enum key_operation modalias_operation; + char modalias[PATH_SIZE]; char name[PATH_SIZE]; enum key_operation name_operation; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 57c797dd31..89925a35e4 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -269,6 +269,13 @@ static int rules_parse(const char *filename) continue; } + if (strcasecmp(key, KEY_DEVPATH) == 0) { + strlcpy(rule.devpath, value, sizeof(rule.devpath)); + rule.devpath_operation = operation; + valid = 1; + continue; + } + if (strcasecmp(key, KEY_BUS) == 0) { strlcpy(rule.bus, value, sizeof(rule.bus)); rule.bus_operation = operation; @@ -325,6 +332,13 @@ static int rules_parse(const char *filename) continue; } + if (strcasecmp(key, KEY_MODALIAS) == 0) { + strlcpy(rule.modalias, value, sizeof(rule.modalias)); + rule.modalias_operation = operation; + valid = 1; + continue; + } + if (strcasecmp(key, KEY_DRIVER) == 0) { strlcpy(rule.driver, value, sizeof(rule.driver)); rule.driver_operation = operation; diff --git a/udev_sysfs.c b/udev_sysfs.c index f9ff1ed2f9..5c43190644 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -297,38 +297,38 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "usb", .file = "idVendor" }, { .bus = "usb", .file = "iInterface" }, { .bus = "usb", .file = "bNumEndpoints" }, - { .bus = "usb-serial", .file = "detach_state" }, - { .bus = "ide", .file = "detach_state" }, + { .bus = "usb-serial", .file = "power" }, + { .bus = "ide", .file = "power" }, { .bus = "pci", .file = "vendor" }, - { .bus = "platform", .file = "detach_state" }, - { .bus = "pcmcia", .file = "detach_state" }, - { .bus = "i2c", .file = "detach_state" }, + { .bus = "platform", .file = "power" }, + { .bus = "pcmcia", .file = "power" }, + { .bus = "i2c", .file = "power" }, { .bus = "ieee1394", .file = "node_count" }, { .bus = "ieee1394", .file = "nodeid" }, { .bus = "ieee1394", .file = "address" }, { .bus = "bttv-sub", .file = NULL }, - { .bus = "pnp", .file = "detach_state" }, - { .bus = "eisa", .file = "detach_state" }, - { .bus = "serio", .file = "detach_state" }, - { .bus = "pseudo", .file = "detach_state" }, - { .bus = "mmc", .file = "detach_state" }, - { .bus = "macio", .file = "detach_state" }, - { .bus = "of_platform", .file = "detach_state" }, - { .bus = "vio", .file = "detach_state" }, - { .bus = "ecard", .file = "detach_state" }, - { .bus = "sa1111-rab", .file = "detach_state" }, - { .bus = "amba", .file = "detach_state" }, - { .bus = "locomo-bus", .file = "detach_state" }, - { .bus = "logicmodule", .file = "detach_state" }, - { .bus = "parisc", .file = "detach_state" }, - { .bus = "ocp", .file = "detach_state" }, - { .bus = "dio", .file = "detach_state" }, - { .bus = "MCA", .file = "detach_state" }, - { .bus = "wl", .file = "detach_state" }, - { .bus = "ccwgroup", .file = "detach_state" }, - { .bus = "css", .file = "detach_state" }, - { .bus = "ccw", .file = "detach_state" }, - { .bus = "iucv", .file = "detach_state" }, + { .bus = "pnp", .file = "power" }, + { .bus = "eisa", .file = "power" }, + { .bus = "serio", .file = "power" }, + { .bus = "pseudo", .file = "power" }, + { .bus = "mmc", .file = "power" }, + { .bus = "macio", .file = "power" }, + { .bus = "of_platform", .file = "power" }, + { .bus = "vio", .file = "power" }, + { .bus = "ecard", .file = "power" }, + { .bus = "sa1111-rab", .file = "power" }, + { .bus = "amba", .file = "power" }, + { .bus = "locomo-bus", .file = "power" }, + { .bus = "logicmodule", .file = "power" }, + { .bus = "parisc", .file = "power" }, + { .bus = "ocp", .file = "power" }, + { .bus = "dio", .file = "power" }, + { .bus = "MCA", .file = "power" }, + { .bus = "wl", .file = "power" }, + { .bus = "ccwgroup", .file = "power" }, + { .bus = "css", .file = "power" }, + { .bus = "ccw", .file = "power" }, + { .bus = "iucv", .file = "power" }, { NULL, NULL } }; const struct device_file *devicefile = NULL; From d27d3bb05288fb5e70bc3f3fc7da1dc8ee5413a8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 22 Jun 2005 01:31:24 +0200 Subject: [PATCH 1330/4284] fix udevstart and let all events trvel trough udev Signed-off-by: Kay Sievers --- udev.c | 14 +++++++------- udevtest.c | 17 ++++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/udev.c b/udev.c index f7b9bf3573..67d081d005 100644 --- a/udev.c +++ b/udev.c @@ -200,13 +200,13 @@ int main(int argc, char *argv[], char *envp[]) info("device event will be ignored"); goto cleanup; } - } else if (strcmp(action, "remove") == 0) { - dbg("devices remove"); - udev_rules_get_run(&udev, NULL); - if (udev.ignore_device) { - info("device event will be ignored"); - goto cleanup; - } + } + } else { + dbg("default handling"); + udev_rules_get_run(&udev, NULL); + if (udev.ignore_device) { + info("device event will be ignored"); + goto cleanup; } } diff --git a/udevtest.c b/udevtest.c index 93387f76d0..d3e43593bf 100644 --- a/udevtest.c +++ b/udevtest.c @@ -98,12 +98,6 @@ int main(int argc, char *argv[], char *envp[]) /* fill in values and test_run flag*/ udev_init_device(&udev, devpath, subsystem, "add"); - /* skip subsystems without "dev", but handle net devices */ - if (udev.type != DEV_NET && subsystem_expect_no_dev(udev.subsystem)) { - info("don't care about '%s' devices", udev.subsystem); - return 2; - } - /* open the device */ snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath); path[sizeof(path)-1] = '\0'; @@ -112,13 +106,18 @@ int main(int argc, char *argv[], char *envp[]) info("sysfs_open_class_device_path failed"); return 1; } - info("opened class_dev->name='%s'", class_dev->name); + if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS) + udev.devt = get_devt(class_dev); + /* simulate node creation with test flag */ udev.test_run = 1; - udev_add_device(&udev, class_dev); - + if (udev.type == DEV_NET || udev.devt) { + udev_rules_get_name(&udev, class_dev); + udev_add_device(&udev, class_dev); + } else + info("only char and block devices with a dev-file are supported by this test program"); sysfs_close_class_device(class_dev); return 0; From c9b8dbfb652a10d2f1c1b122a3806c21cab87ab4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 22 Jun 2005 02:11:59 +0200 Subject: [PATCH 1331/4284] fix the fix and change the file to wait for to the "bus" link Signed-off-by: Kay Sievers --- udev.c | 38 ++++++++++++++++++------------------ udev_sysfs.c | 54 ++++++++++++++++++++++++++-------------------------- udev_sysfs.h | 2 +- 3 files changed, 46 insertions(+), 48 deletions(-) diff --git a/udev.c b/udev.c index 67d081d005..36ff21d5b7 100644 --- a/udev.c +++ b/udev.c @@ -179,27 +179,25 @@ int main(int argc, char *argv[], char *envp[]) /* export name of device node or netif */ if (udev.devname[0] != '\0') setenv("DEVNAME", udev.devname, 1); - } else if (udev.type == DEV_DEVICE) { - if (strcmp(action, "add") == 0) { - struct sysfs_device *devices_dev; + } else if (udev.type == DEV_DEVICE && strcmp(action, "add") == 0) { + struct sysfs_device *devices_dev; - /* wait for sysfs of /sys/devices/ */ - dbg("devices add"); - snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); - path[sizeof(path)-1] = '\0'; - devices_dev = wait_devices_device_open(path); - if (!devices_dev) { - dbg("devices device unavailable (probably remove has beaten us)"); - goto run; - } - dbg("devices device opened '%s'", path); - wait_for_devices_device(devices_dev, &error); - udev_rules_get_run(&udev, devices_dev); - sysfs_close_device(devices_dev); - if (udev.ignore_device) { - info("device event will be ignored"); - goto cleanup; - } + /* wait for sysfs of /sys/devices/ */ + dbg("devices add"); + snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); + path[sizeof(path)-1] = '\0'; + devices_dev = wait_devices_device_open(path); + if (!devices_dev) { + dbg("devices device unavailable (probably remove has beaten us)"); + goto run; + } + dbg("devices device opened '%s'", path); + wait_for_devices_device(devices_dev, &error); + udev_rules_get_run(&udev, devices_dev); + sysfs_close_device(devices_dev); + if (udev.ignore_device) { + info("device event will be ignored"); + goto cleanup; } } else { dbg("default handling"); diff --git a/udev_sysfs.c b/udev_sysfs.c index 5c43190644..90ce48caea 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -297,38 +297,38 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "usb", .file = "idVendor" }, { .bus = "usb", .file = "iInterface" }, { .bus = "usb", .file = "bNumEndpoints" }, - { .bus = "usb-serial", .file = "power" }, - { .bus = "ide", .file = "power" }, + { .bus = "usb-serial", .file = "bus" }, + { .bus = "ide", .file = "bus" }, { .bus = "pci", .file = "vendor" }, - { .bus = "platform", .file = "power" }, - { .bus = "pcmcia", .file = "power" }, - { .bus = "i2c", .file = "power" }, + { .bus = "platform", .file = "bus" }, + { .bus = "pcmcia", .file = "bus" }, + { .bus = "i2c", .file = "bus" }, { .bus = "ieee1394", .file = "node_count" }, { .bus = "ieee1394", .file = "nodeid" }, { .bus = "ieee1394", .file = "address" }, { .bus = "bttv-sub", .file = NULL }, - { .bus = "pnp", .file = "power" }, - { .bus = "eisa", .file = "power" }, - { .bus = "serio", .file = "power" }, - { .bus = "pseudo", .file = "power" }, - { .bus = "mmc", .file = "power" }, - { .bus = "macio", .file = "power" }, - { .bus = "of_platform", .file = "power" }, - { .bus = "vio", .file = "power" }, - { .bus = "ecard", .file = "power" }, - { .bus = "sa1111-rab", .file = "power" }, - { .bus = "amba", .file = "power" }, - { .bus = "locomo-bus", .file = "power" }, - { .bus = "logicmodule", .file = "power" }, - { .bus = "parisc", .file = "power" }, - { .bus = "ocp", .file = "power" }, - { .bus = "dio", .file = "power" }, - { .bus = "MCA", .file = "power" }, - { .bus = "wl", .file = "power" }, - { .bus = "ccwgroup", .file = "power" }, - { .bus = "css", .file = "power" }, - { .bus = "ccw", .file = "power" }, - { .bus = "iucv", .file = "power" }, + { .bus = "pnp", .file = "bus" }, + { .bus = "eisa", .file = "bus" }, + { .bus = "serio", .file = "bus" }, + { .bus = "pseudo", .file = "bus" }, + { .bus = "mmc", .file = "bus" }, + { .bus = "macio", .file = "bus" }, + { .bus = "of_platform", .file = "bus" }, + { .bus = "vio", .file = "bus" }, + { .bus = "ecard", .file = "bus" }, + { .bus = "sa1111-rab", .file = "bus" }, + { .bus = "amba", .file = "bus" }, + { .bus = "locomo-bus", .file = "bus" }, + { .bus = "logicmodule", .file = "bus" }, + { .bus = "parisc", .file = "bus" }, + { .bus = "ocp", .file = "bus" }, + { .bus = "dio", .file = "bus" }, + { .bus = "MCA", .file = "bus" }, + { .bus = "wl", .file = "bus" }, + { .bus = "ccwgroup", .file = "bus" }, + { .bus = "css", .file = "bus" }, + { .bus = "ccw", .file = "bus" }, + { .bus = "iucv", .file = "bus" }, { NULL, NULL } }; const struct device_file *devicefile = NULL; diff --git a/udev_sysfs.h b/udev_sysfs.h index 77c0e6a8ef..8078f62d82 100644 --- a/udev_sysfs.h +++ b/udev_sysfs.h @@ -24,7 +24,7 @@ #include "libsysfs/sysfs/libsysfs.h" -#define WAIT_MAX_SECONDS 5 +#define WAIT_MAX_SECONDS 3 #define WAIT_LOOP_PER_SECOND 20 extern dev_t get_devt(struct sysfs_class_device *class_dev); From 6bf0ffe8fd312c1e6549cb1721d7a7efeee77185 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 24 Jun 2005 18:05:32 +0200 Subject: [PATCH 1332/4284] allow rules to be compiled to one binary file All the rule files can be compiled into a single file, which can be mapped into the udev process to avoid parsing the rules with every event. Signed-off-by: Kay Sievers --- Makefile | 11 +++- test/devd_test | 0 test/net_test | 0 test/replace_test | 0 test/show_all_devices.sh | 0 test/test.all | 0 test/test.block | 0 test/test.tty | 0 test/testd.block | 0 udev_rules.c | 15 ++++- udev_rules.h | 10 +-- udev_rules_parse.c | 89 +++++++++++++++++++++++---- udev_utils.c | 2 +- udev_utils.h | 2 +- udevrulescompile.c | 127 +++++++++++++++++++++++++++++++++++++++ 15 files changed, 233 insertions(+), 23 deletions(-) mode change 100644 => 100755 test/devd_test mode change 100644 => 100755 test/net_test mode change 100644 => 100755 test/replace_test mode change 100644 => 100755 test/show_all_devices.sh mode change 100644 => 100755 test/test.all mode change 100644 => 100755 test/test.block mode change 100644 => 100755 test/test.tty mode change 100644 => 100755 test/testd.block create mode 100644 udevrulescompile.c diff --git a/Makefile b/Makefile index 8694b917a2..32e057b1cb 100644 --- a/Makefile +++ b/Makefile @@ -44,6 +44,7 @@ V=false ROOT = udev DAEMON = udevd SENDER = udevsend +COMPILE = udevrulescompile INITSENDER = udevinitsend RECORDER = udeveventrecorder CONTROL = udevcontrol @@ -202,7 +203,8 @@ endif # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(INITSENDER) $(RECORDER) $(CONTROL) $(DAEMON) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) +all: $(ROOT) $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) \ + $(DAEMON) $(COMPILE) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ $(MAKE) prefix=$(prefix) \ @@ -268,6 +270,7 @@ $(TESTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(INFO).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(DAEMON).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(SENDER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(COMPILE).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(INITSENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(RECORDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(CONTROL).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) @@ -293,6 +296,10 @@ $(SENDER): $(KLCC) $(SENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(SENDER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ +$(COMPILE): $(KLCC) $(COMPILE).o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(COMPILE).o $(OBJS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + $(INITSENDER): $(KLCC) $(INITSENDER).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(INITSENDER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ @@ -316,7 +323,7 @@ clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) \ - $(SENDER) $(INITSENDER) $(RECORDER) $(CONTROL) $(TESTER) $(STARTER) + $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) $(TESTER) $(STARTER) -rm -f ccdv $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ diff --git a/test/devd_test b/test/devd_test old mode 100644 new mode 100755 diff --git a/test/net_test b/test/net_test old mode 100644 new mode 100755 diff --git a/test/replace_test b/test/replace_test old mode 100644 new mode 100755 diff --git a/test/show_all_devices.sh b/test/show_all_devices.sh old mode 100644 new mode 100755 diff --git a/test/test.all b/test/test.all old mode 100644 new mode 100755 diff --git a/test/test.block b/test/test.block old mode 100644 new mode 100755 diff --git a/test/test.tty b/test/test.tty old mode 100644 new mode 100755 diff --git a/test/testd.block b/test/testd.block old mode 100644 new mode 100755 diff --git a/udev_rules.c b/udev_rules.c index 52e0712d35..c416128b62 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -846,7 +846,12 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d dbg("udev->kernel_name='%s'", udev->kernel_name); /* look for a matching rule to apply */ - list_for_each_entry(rule, &udev_rule_list, node) { + udev_rules_iter_init(); + while (1) { + rule = udev_rules_iter_next(); + if (rule == NULL) + break; + if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { dbg("node name already set, rule ignored"); continue; @@ -1000,9 +1005,13 @@ int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) struct udev_rule *rule; /* look for a matching rule to apply */ - list_for_each_entry(rule, &udev_rule_list, node) { - dbg("process rule"); + udev_rules_iter_init(); + while (1) { + rule = udev_rules_iter_next(); + if (rule == NULL) + break; + dbg("process rule"); if (rule->run_operation == KEY_OP_UNSET) continue; diff --git a/udev_rules.h b/udev_rules.h index 2bf8107543..cb62839802 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -123,11 +123,13 @@ struct udev_rule { int config_line; }; -extern struct list_head udev_rule_list; - extern int udev_rules_init(void); -extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev); -extern int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device); extern void udev_rules_close(void); +extern int udev_rules_iter_init(void); +extern struct udev_rule *udev_rules_iter_next(void); + +extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev); +extern int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device); + #endif diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 89925a35e4..36bf97177d 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -37,9 +37,45 @@ #include "logging.h" #include "udev_rules.h" -LIST_HEAD(udev_rule_list); +/* rules parsed from .rules files*/ +static LIST_HEAD(rules_list); +static struct list_head *rules_list_current; -static int add_config_dev(struct udev_rule *rule) +/* mapped compiled rules stored on disk */ +static struct udev_rule *rules_array = NULL; +static size_t rules_array_current; +static size_t rules_array_size = 0; + +static size_t rules_count = 0; + +int udev_rules_iter_init(void) +{ + rules_list_current = rules_list.next; + rules_array_current = 0; + + return 0; +} + +struct udev_rule *udev_rules_iter_next(void) +{ + static struct udev_rule *rule; + + if (rules_array) { + if (rules_array_current >= rules_count) + return NULL; + rule = &rules_array[rules_array_current]; + rules_array_current++; + } else { + dbg("head=%p current=%p next=%p", &rules_list, rules_list_current, rules_list_current->next); + if (rules_list_current == &rules_list) + return NULL; + rule = list_entry(rules_list_current, struct udev_rule, node); + rules_list_current = rules_list_current->next; + } + return rule; +} + +static int add_rule_to_list(struct udev_rule *rule) { struct udev_rule *tmp_rule; @@ -47,7 +83,7 @@ static int add_config_dev(struct udev_rule *rule) if (tmp_rule == NULL) return -ENOMEM; memcpy(tmp_rule, rule, sizeof(struct udev_rule)); - list_add_tail(&tmp_rule->node, &udev_rule_list); + list_add_tail(&tmp_rule->node, &rules_list); dbg("name='%s', symlink='%s', bus='%s', id='%s', " "sysfs_file[0]='%s', sysfs_value[0]='%s', " @@ -451,9 +487,9 @@ static int rules_parse(const char *filename) rule.config_line = lineno; strlcpy(rule.config_file, filename, sizeof(rule.config_file)); - retval = add_config_dev(&rule); + retval = add_rule_to_list(&rule); if (retval) { - dbg("add_config_dev returned with error %d", retval); + dbg("add_rule_to_list returned with error %d", retval); continue; error: err("parse error %s, line %d:%d, rule skipped", @@ -465,20 +501,47 @@ error: return retval; } +static int rules_map(const char *filename) +{ + char *buf; + size_t size; + + if (file_map(filename, &buf, &size)) + return -1; + if (size == 0) + return -1; + rules_array = (struct udev_rule *) buf; + rules_array_size = size; + rules_count = size / sizeof(struct udev_rule); + dbg("found %zi compiled rules", rules_count); + + return 0; +} + int udev_rules_init(void) { + char comp[PATH_SIZE]; struct stat stats; int retval; + strlcpy(comp, udev_rules_filename, sizeof(comp)); + strlcat(comp, ".compiled", sizeof(comp)); + if (stat(comp, &stats) == 0) { + dbg("parse compiled rules '%s'", comp); + return rules_map(comp); + } + if (stat(udev_rules_filename, &stats) != 0) return -1; - if ((stats.st_mode & S_IFMT) != S_IFDIR) + if ((stats.st_mode & S_IFMT) != S_IFDIR) { + dbg("parse single rules file '%s'", udev_rules_filename); retval = rules_parse(udev_rules_filename); - else { + } else { struct name_entry *name_loop, *name_tmp; LIST_HEAD(name_list); + dbg("parse rules directory '%s'", udev_rules_filename); retval = add_matching_files(&name_list, udev_rules_filename, RULEFILE_SUFFIX); list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { @@ -495,9 +558,11 @@ void udev_rules_close(void) struct udev_rule *rule; struct udev_rule *temp_rule; - list_for_each_entry_safe(rule, temp_rule, &udev_rule_list, node) { - list_del(&rule->node); - free(rule); - } + if (rules_array) + file_unmap(rules_array, rules_array_size); + else + list_for_each_entry_safe(rule, temp_rule, &rules_list, node) { + list_del(&rule->node); + free(rule); + } } - diff --git a/udev_utils.c b/udev_utils.c index 64a7ba9caa..c35b287881 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -247,7 +247,7 @@ int file_map(const char *filename, char **buf, size_t *bufsize) return 0; } -void file_unmap(char *buf, size_t bufsize) +void file_unmap(void *buf, size_t bufsize) { munmap(buf, bufsize); } diff --git a/udev_utils.h b/udev_utils.h index b3e604fb98..3e372dd948 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -39,7 +39,7 @@ extern int string_is_true(const char *str); extern int parse_get_pair(char **orig_string, char **left, char **right); extern int unlink_secure(const char *filename); extern int file_map(const char *filename, char **buf, size_t *bufsize); -extern void file_unmap(char *buf, size_t bufsize); +extern void file_unmap(void *buf, size_t bufsize); extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); extern void remove_trailing_char(char *path, char c); extern void replace_untrusted_chars(char *string); diff --git a/udevrulescompile.c b/udevrulescompile.c new file mode 100644 index 0000000000..ff9dd79fd4 --- /dev/null +++ b/udevrulescompile.c @@ -0,0 +1,127 @@ +/* + * udevrulescompile.c - store already parsed config on disk + * + * 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. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "udev_libc_wrapper.h" +#include "udev_sysfs.h" +#include "udev.h" +#include "udev_version.h" +#include "logging.h" +#include "udev_rules.h" +#include "udev_utils.h" +#include "list.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 + +int main(int argc, char *argv[], char *envp[]) +{ + struct udev_rule *rule; + FILE *f; + char comp[PATH_SIZE]; + char comp_tmp[PATH_SIZE]; + int retval = 0; + + logging_init("udevrulescompile"); + udev_init_config(); + dbg("version %s", UDEV_VERSION); + + strlcpy(comp, udev_rules_filename, sizeof(comp)); + strlcat(comp, ".compiled", sizeof(comp)); + strlcpy(comp_tmp, comp, sizeof(comp_tmp)); + strlcat(comp_tmp, ".tmp", sizeof(comp_tmp)); + + /* remove old version, otherwise we would read it + * instead of the real rules */ + unlink(comp); + unlink(comp_tmp); + + udev_rules_init(); + + f = fopen(comp_tmp, "w"); + if (f == NULL) { + err("unable to create db file '%s'", comp_tmp); + unlink(comp_tmp); + retval = 1; + goto exit; + } + dbg("storing compiled rules in '%s'", comp_tmp); + + udev_rules_iter_init(); + while (1) { + char *endptr; + unsigned long id; + + rule = udev_rules_iter_next(); + if (rule == NULL) + break; + + id = strtoul(rule->owner, &endptr, 10); + if (endptr[0] != '\0') { + uid_t uid; + + uid = lookup_user(rule->owner); + dbg("replacing username='%s' by id=%i", rule->owner, uid); + sprintf(rule->owner, "%li", uid); + } + + id = strtoul(rule->group, &endptr, 10); + if (endptr[0] != '\0') { + gid_t gid; + + gid = lookup_group(rule->group); + dbg("replacing groupname='%s' by id=%i", rule->group, gid); + sprintf(rule->group, "%li", gid); + } + + dbg("kernel='%s' name='%s'", rule->kernel, rule->name); + fwrite(rule, sizeof(struct udev_rule), 1, f); + } + + fclose(f); + dbg("activating compiled rules in '%s'", comp); + if (rename(comp_tmp, comp) != 0) { + err("unable to write file"); + unlink(comp); + unlink(comp_tmp); + retval = 2; + } + +exit: + logging_close(); + return retval; +} From bd0ed2ffbec325512c3131ce0db896234e36c923 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 25 Jun 2005 13:10:16 +0200 Subject: [PATCH 1333/4284] IMPORT= allow to import a shell-var style config-file This allows to source-in a file into the udev environment to have the defined keys available for later processing by udev itself or the forked helper programs. Signed-off-by: Kay Sievers --- test/udev-test.pl | 19 ++++++ udev_rules.c | 155 ++++++++++++++++++++++++++++++++++++++++++++- udev_rules.h | 3 + udev_rules_parse.c | 7 ++ 4 files changed, 182 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 9225352130..c7a99e517d 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -256,6 +256,16 @@ EOF exp_name => "M8-m3-n3-b0:0-sIBM" , rules => < "import of shellvalue file", + subsys => "block", + devpath => "/block/sda", + exp_name => "subdir/sys/node" , + rules => < "env substitution", + subsys => "block", + devpath => "/block/sda", + exp_name => "node-add-me", + rules => <= 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; + + strlcpy(line, bufline, count+1); + + linepos = line; + if (get_key(&linepos, &variable, &value) == 0) { + dbg("import %s=%s", variable, value); + setenv(variable, value, 0); + } + } + + file_unmap(buf, bufsize); + return retval; +} + /** Finds the lowest positive N such that N isn't present in * $(udevroot) either as a file or a symlink. * @@ -198,7 +321,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, { char temp[PATH_SIZE]; char temp2[PATH_SIZE]; - char *head, *tail, *cpos, *attr, *rest; + char *head, *tail, *pos, *cpos, *attr, *rest; int len; int i; unsigned int next_free_number; @@ -218,6 +341,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, SUBST_TEMP_NODE, SUBST_ROOT, SUBST_MODALIAS, + SUBST_ENV, }; static const struct subst_map { char *name; @@ -237,6 +361,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, { .name = "tempnode", .fmt = 'N', .type = SUBST_TEMP_NODE }, { .name = "root", .fmt = 'r', .type = SUBST_ROOT }, { .name = "modalias", .fmt = 'A', .type = SUBST_MODALIAS }, + { .name = "env", .fmt = 'E', .type = SUBST_ENV }, {} }; enum subst_type type; @@ -431,6 +556,17 @@ found: strlcat(string, temp2, maxsize); dbg("substitute MODALIAS '%s'", temp2); break; + case SUBST_ENV: + if (attr == NULL) { + dbg("missing attribute"); + break; + } + pos = getenv(attr); + if (pos == NULL) + break; + strlcat(string, pos, maxsize); + dbg("substitute env '%s=%s'", attr, pos); + break; default: err("unknown substitution type=%i", type); break; @@ -773,13 +909,28 @@ try_parent: dbg("look at sysfs_device->bus_id='%s'", parent_device->bus_id); } + if (rule->import_operation != KEY_OP_UNSET) { + char import[PATH_SIZE]; + + strlcpy(import, rule->import, sizeof(import)); + apply_format(udev, import, sizeof(import), class_dev, sysfs_device); + dbg("check for " KEY_IMPORT " import='%s", import); + if (import_file_into_env(import) == 0) { + dbg(KEY_IMPORT " file '%s' imported", rule->import); + if (rule->import_operation == KEY_OP_NOMATCH) + goto exit; + } else + goto exit; + dbg(KEY_IMPORT " key is true"); + } + /* execute external program */ if (rule->program_operation != KEY_OP_UNSET) { char program[PATH_SIZE]; - dbg("check " KEY_PROGRAM); strlcpy(program, rule->program, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + dbg("check for " KEY_PROGRAM " program='%s", program); if (execute_program_pipe(program, udev->subsystem, udev->program_result, sizeof(udev->program_result)) != 0) { dbg(KEY_PROGRAM " returned nonzero"); diff --git a/udev_rules.h b/udev_rules.h index cb62839802..f4b0a6f12f 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -40,6 +40,7 @@ #define KEY_SYSFS "SYSFS" #define KEY_ENV "ENV" #define KEY_MODALIAS "MODALIAS" +#define KEY_IMPORT "IMPORT" #define KEY_NAME "NAME" #define KEY_SYMLINK "SYMLINK" #define KEY_OWNER "OWNER" @@ -100,6 +101,8 @@ struct udev_rule { int env_pair_count; enum key_operation modalias_operation; char modalias[PATH_SIZE]; + enum key_operation import_operation; + char import[PATH_SIZE]; char name[PATH_SIZE]; enum key_operation name_operation; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 36bf97177d..121236820b 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -375,6 +375,13 @@ static int rules_parse(const char *filename) continue; } + if (strcasecmp(key, KEY_IMPORT) == 0) { + strlcpy(rule.import, value, sizeof(rule.import)); + rule.import_operation = operation; + valid = 1; + continue; + } + if (strcasecmp(key, KEY_DRIVER) == 0) { strlcpy(rule.driver, value, sizeof(rule.driver)); rule.driver_operation = operation; From be4bedd16b934c8663f8c231f07f23091cde8261 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 25 Jun 2005 15:35:14 +0200 Subject: [PATCH 1334/4284] unify execute_command() and execute_program() Signed-off-by: Kay Sievers --- udev.c | 2 +- udev_rules.c | 155 ++++++++++----------------------------------------- udev_utils.c | 72 +++++++++++++++++++----- udev_utils.h | 3 +- udevstart.c | 2 +- 5 files changed, 93 insertions(+), 141 deletions(-) diff --git a/udev.c b/udev.c index 36ff21d5b7..1c55ec14b8 100644 --- a/udev.c +++ b/udev.c @@ -214,7 +214,7 @@ run: dbg("executing run list"); list_for_each_entry(name_loop, &udev.run_list, node) - execute_command(name_loop->name, udev.subsystem); + execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); } cleanup: diff --git a/udev_rules.c b/udev_rules.c index 6ed67c2672..aa66c7ad30 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -200,24 +200,16 @@ static int get_key(char **line, char **key, char **value) return 0; } -static int import_file_into_env(const char *filename) +static int import_keys_into_env(const char *buf, size_t bufsize) { char line[LINE_SIZE]; - char *bufline; + const 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(filename, &buf, &bufsize) != 0) { - err("can't open '%s'", filename); - return -1; - } /* loop through the whole file */ lineno = 0; @@ -254,8 +246,22 @@ static int import_file_into_env(const char *filename) } } + return 0; +} + +static int import_file_into_env(const char *filename) +{ + char *buf; + size_t bufsize; + + if (file_map(filename, &buf, &bufsize) != 0) { + err("can't open '%s'", filename); + return -1; + } + import_keys_into_env(buf, bufsize); file_unmap(buf, bufsize); - return retval; + + return 0; } /** Finds the lowest positive N such that N isn't present in @@ -576,117 +582,10 @@ found: head[len] = '\0'; dbg("truncate to %i chars, subtitution string becomes '%s'", len, head); } - strlcat(string, temp, maxsize); } } -static int execute_program_pipe(const char *command, const char *subsystem, char *value, int len) -{ - int retval; - int count; - int status; - int pipefds[2]; - pid_t pid; - char *pos; - char arg[PATH_SIZE]; - char *argv[(sizeof(arg) / 2) + 1]; - int devnull; - int i; - - strlcpy(arg, command, sizeof(arg)); - i = 0; - if (strchr(arg, ' ')) { - pos = arg; - while (pos != NULL) { - if (pos[0] == '\'') { - /* don't separate if in apostrophes */ - pos++; - argv[i] = strsep(&pos, "\'"); - while (pos && pos[0] == ' ') - pos++; - } else { - argv[i] = strsep(&pos, " "); - } - dbg("arg[%i] '%s'", i, argv[i]); - i++; - } - argv[i] = NULL; - dbg("execute '%s' with parsed arguments", arg); - } else { - argv[0] = arg; - argv[1] = (char *) subsystem; - argv[2] = NULL; - dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); - } - - retval = pipe(pipefds); - if (retval != 0) { - err("pipe failed"); - return -1; - } - - pid = fork(); - switch(pid) { - case 0: - /* child dup2 write side of pipe to STDOUT */ - devnull = open("/dev/null", O_RDWR); - if (devnull >= 0) { - dup2(devnull, STDIN_FILENO); - dup2(devnull, STDERR_FILENO); - close(devnull); - } - dup2(pipefds[1], STDOUT_FILENO); - retval = execv(arg, argv); - err("exec of program failed"); - _exit(1); - case -1: - err("fork of '%s' failed", arg); - retval = -1; - break; - default: - /* parent reads from pipefds[0] */ - close(pipefds[1]); - retval = 0; - i = 0; - while (1) { - count = read(pipefds[0], value + i, len - i-1); - if (count < 0) { - err("read failed with '%s'", strerror(errno)); - retval = -1; - } - - if (count == 0) - break; - - i += count; - if (i >= len-1) { - err("result len %d too short", len); - retval = -1; - break; - } - } - value[i] = '\0'; - - close(pipefds[0]); - waitpid(pid, &status, 0); - - if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { - dbg("exec program status 0x%x", status); - retval = -1; - } - } - - if (!retval) { - remove_trailing_char(value, '\n'); - dbg("result is '%s'", value); - replace_untrusted_chars(value); - } else - value[0] = '\0'; - - return retval; -} - static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { @@ -909,34 +808,40 @@ try_parent: dbg("look at sysfs_device->bus_id='%s'", parent_device->bus_id); } + /* import variables from file into environment */ if (rule->import_operation != KEY_OP_UNSET) { char import[PATH_SIZE]; strlcpy(import, rule->import, sizeof(import)); apply_format(udev, import, sizeof(import), class_dev, sysfs_device); dbg("check for " KEY_IMPORT " import='%s", import); - if (import_file_into_env(import) == 0) { - dbg(KEY_IMPORT " file '%s' imported", rule->import); - if (rule->import_operation == KEY_OP_NOMATCH) + if (import_file_into_env(import) != 0) { + dbg(KEY_IMPORT " failed"); + if (rule->import_operation != KEY_OP_NOMATCH) goto exit; } else - goto exit; + dbg(KEY_IMPORT " file '%s' imported", rule->import); dbg(KEY_IMPORT " key is true"); } /* execute external program */ if (rule->program_operation != KEY_OP_UNSET) { char program[PATH_SIZE]; + char result[PATH_SIZE]; strlcpy(program, rule->program, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); dbg("check for " KEY_PROGRAM " program='%s", program); - if (execute_program_pipe(program, udev->subsystem, - udev->program_result, sizeof(udev->program_result)) != 0) { - dbg(KEY_PROGRAM " returned nonzero"); + if (execute_program(program, udev->subsystem, result, sizeof(result), NULL) != 0) { + dbg(KEY_PROGRAM " is not matching"); if (rule->program_operation != KEY_OP_NOMATCH) goto exit; } else { + dbg(KEY_PROGRAM " matches"); + remove_trailing_char(result, '\n'); + replace_untrusted_chars(result); + dbg("result is '%s'", result); + strlcpy(udev->program_result, result, sizeof(udev->program_result)); dbg(KEY_PROGRAM " returned successful"); if (rule->program_operation == KEY_OP_NOMATCH) goto exit; diff --git a/udev_utils.c b/udev_utils.c index c35b287881..9e2e152763 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -361,15 +361,20 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c return 0; } -int execute_command(const char *command, const char *subsystem) +int execute_program(const char *command, const char *subsystem, + char *result, size_t ressize, size_t *reslen) { - int retval; + int retval = 0; + int count; + int status; + int pipefds[2]; pid_t pid; - char arg[PATH_SIZE]; - char *argv[(PATH_SIZE / 2) + 1]; char *pos; + char arg[PATH_SIZE]; + char *argv[(sizeof(arg) / 2) + 1]; int devnull; int i; + size_t len; strlcpy(arg, command, sizeof(arg)); i = 0; @@ -397,27 +402,68 @@ int execute_command(const char *command, const char *subsystem) dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); } + if (result) { + if (pipe(pipefds) != 0) { + err("pipe failed"); + return -1; + } + } + pid = fork(); - switch (pid) { + switch(pid) { case 0: - /* child */ + /* child dup2 write side of pipe to STDOUT */ devnull = open("/dev/null", O_RDWR); if (devnull >= 0) { dup2(devnull, STDIN_FILENO); - dup2(devnull, STDOUT_FILENO); + if (!result) + dup2(devnull, STDOUT_FILENO); dup2(devnull, STDERR_FILENO); close(devnull); } - retval = execv(arg, argv); - err("exec of child '%s' failed", command); + if (result) + dup2(pipefds[1], STDOUT_FILENO); + execv(arg, argv); + err("exec of program failed"); _exit(1); case -1: - dbg("fork of child '%s' failed", command); - break; + err("fork of '%s' failed", arg); return -1; default: - waitpid(pid, NULL, 0); + /* parent reads from pipefds[0] */ + if (result) { + close(pipefds[1]); + len = 0; + while (1) { + count = read(pipefds[0], result + len, ressize - len-1); + if (count < 0) { + err("read failed with '%s'", strerror(errno)); + retval = -1; + break; + } + + if (count == 0) + break; + + len += count; + if (len >= ressize-1) { + err("ressize %d too short", ressize); + retval = -1; + break; + } + } + result[len] = '\0'; + close(pipefds[0]); + if (reslen) + *reslen = len; + } + waitpid(pid, &status, 0); + + if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { + dbg("exec program status 0x%x", status); + retval = -1; + } } - return 0; + return retval; } diff --git a/udev_utils.h b/udev_utils.h index 3e372dd948..999a4fcf55 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -45,6 +45,7 @@ extern void remove_trailing_char(char *path, char c); extern void replace_untrusted_chars(char *string); extern int name_list_add(struct list_head *name_list, const char *name, int sort); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); -extern int execute_command(const char *command, const char *subsystem); +extern int execute_program(const char *command, const char *subsystem, + char *result, size_t ressize, size_t *reslen); #endif diff --git a/udevstart.c b/udevstart.c index bd91e96f6a..b65a28aab6 100644 --- a/udevstart.c +++ b/udevstart.c @@ -146,7 +146,7 @@ run: dbg("executing run list"); list_for_each_entry(name_loop, &udev.run_list, node) - execute_command(name_loop->name, udev.subsystem); + execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); } exit: sysfs_close_class_device(class_dev); From 319c6700165dc38d7f813ff646bff0196f2aafe6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 25 Jun 2005 18:58:49 +0200 Subject: [PATCH 1335/4284] IMPORT allow to import program returned keys into the env Signed-off-by: Kay Sievers --- test/udev-test.pl | 12 +++++++++++- udev_rules.c | 35 +++++++++++++++++++++++++---------- udev_rules.h | 5 +++-- udev_rules_parse.c | 8 ++++++-- 4 files changed, 45 insertions(+), 15 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index c7a99e517d..bf6b62f10a 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -259,13 +259,23 @@ BUS=="scsi", ID=="0:0:0:0", NAME="M%M-m%m-n%n-b%3b-s%3s{vendor}" EOF }, { - desc => "import of shellvalue file", + desc => "import of shell-value file", subsys => "block", devpath => "/block/sda", exp_name => "subdir/sys/node" , rules => < "import of shell-value returned from program", + subsys => "block", + devpath => "/block/sda", + exp_name => "node12345678", + rules => <N isn't present in - * $(udevroot) either as a file or a symlink. - * - * @param name Name to check for - * @return 0 if didn't exist and N otherwise. +static int import_program_into_env(struct udevice *udev, const char *program) +{ + char result[1024]; + size_t reslen; + + if (execute_program(program, udev->subsystem, result, sizeof(result), &reslen) != 0) + return -1; + return import_keys_into_env(result, reslen); +} + +/* finds the lowest positive N such that N isn't present in the udevdb + * if doesn't exist, 0 is returned, N otherwise */ static int find_free_number(struct udevice *udev, const char *name) { @@ -811,16 +818,24 @@ try_parent: /* import variables from file into environment */ if (rule->import_operation != KEY_OP_UNSET) { char import[PATH_SIZE]; + int rc = -1; strlcpy(import, rule->import, sizeof(import)); apply_format(udev, import, sizeof(import), class_dev, sysfs_device); - dbg("check for " KEY_IMPORT " import='%s", import); - if (import_file_into_env(import) != 0) { + dbg("check for " KEY_IMPORT " import='%s'", import); + if (rule->import_exec) { + dbg("run executable file import='%s'", import); + rc = import_program_into_env(udev, import); + } else { + dbg("import file import='%s'", import); + rc = import_file_into_env(import); + } + if (rc) { dbg(KEY_IMPORT " failed"); if (rule->import_operation != KEY_OP_NOMATCH) goto exit; } else - dbg(KEY_IMPORT " file '%s' imported", rule->import); + dbg(KEY_IMPORT " '%s' imported", rule->import); dbg(KEY_IMPORT " key is true"); } diff --git a/udev_rules.h b/udev_rules.h index f4b0a6f12f..bad8406cf4 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -99,10 +99,11 @@ struct udev_rule { int sysfs_pair_count; struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; int env_pair_count; + char modalias[NAME_SIZE]; enum key_operation modalias_operation; - char modalias[PATH_SIZE]; - enum key_operation import_operation; char import[PATH_SIZE]; + enum key_operation import_operation; + int import_exec; char name[PATH_SIZE]; enum key_operation name_operation; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 121236820b..4979feddc1 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -375,7 +375,12 @@ static int rules_parse(const char *filename) continue; } - if (strcasecmp(key, KEY_IMPORT) == 0) { + if (strncasecmp(key, KEY_IMPORT, sizeof(KEY_IMPORT)-1) == 0) { + attr = get_key_attribute(key + sizeof(KEY_IMPORT)-1); + if (attr && strstr(attr, "exec")) { + dbg(KEY_IMPORT" will be executed"); + rule.import_exec = 1; + } strlcpy(rule.import, value, sizeof(rule.import)); rule.import_operation = operation; valid = 1; @@ -411,7 +416,6 @@ static int rules_parse(const char *filename) dbg("creation of partition nodes requested"); rule.partitions = DEFAULT_PARTITIONS_COUNT; } - /* FIXME: remove old style option and make OPTIONS= mandatory */ if (strstr(attr, OPTION_IGNORE_REMOVE) != NULL) { dbg("remove event should be ignored"); rule.ignore_remove = 1; From 670e470543e02937979e1c879d97f474d5b6fbd1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 25 Jun 2005 23:54:28 +0200 Subject: [PATCH 1336/4284] add ata_id to read serial numbers from ATA drives Signed-off-by: Kay Sievers --- extras/ata_id/Makefile | 52 +++++++++++++ extras/ata_id/ata_id.c | 150 +++++++++++++++++++++++++++++++++++++ test/simple-build-check.sh | 2 +- 3 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 extras/ata_id/Makefile create mode 100644 extras/ata_id/ata_id.c diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile new file mode 100644 index 0000000000..ad79a0d836 --- /dev/null +++ b/extras/ata_id/Makefile @@ -0,0 +1,52 @@ +# Makefile for udev_volume_id +# +# 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. +# + +PROG = ata_id + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +override CFLAGS+=-D_FILE_OFFSET_BITS=64 + +OBJS = ata_id.o ../../udev.a + +$(OBJS): $(HEADERS) + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(PROG): $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c new file mode 100644 index 0000000000..e26cb6bd2d --- /dev/null +++ b/extras/ata_id/ata_id.c @@ -0,0 +1,150 @@ +/* + * ata_id - reads product/serial number from ATA drives + * + * Copyright (C) 2005 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../logging.h" +#include "../../udev_utils.h" + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + static int udev_log = -1; + + if (udev_log == -1) { + const char *value; + + value = getenv("UDEV_LOG"); + if (value) + udev_log = log_priority(value); + else + udev_log = LOG_ERR; + } + + if (priority > udev_log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +static void set_str(char *to, const unsigned char *from, int count) +{ + int i, j; + int len; + + len = strnlen(from, count); + while (isspace(from[len-1])) + len--; + + i = 0; + while (isspace(from[i]) && (i < len)) + i++; + + j = 0; + while (i < len) { + switch(from[i]) { + case '/': + case ' ': + to[j++] = '_'; + default: + to[j++] = from[i]; + } + 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 i; + int export = 0; + int fd; + int rc = 0; + + for (i = 1 ; i < argc; i++) { + char *arg = argv[i]; + + if (strcmp(arg, "--export") == 0) { + export = 1; + } else + node = arg; + } + if (!node) { + err("no node specified"); + rc = 1; + goto exit; + } + + fd = open(node, O_RDONLY); + if (fd < 0) + if (errno == ENOMEDIUM) + 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)) { + err("HDIO_GET_IDENTITY failed for '%s'", node); + rc = 3; + goto close; + } + + set_str(model, id.model, 40); + set_str(serial, id.serial_no, 20); + set_str(revision, id.fw_rev, 8); + + if (export) { + printf("ID_MODEL=%s\n", model); + printf("ID_SERIAL=%s\n", serial); + printf("ID_REVISION=%s\n", revision); + } else + printf("%s_%s\n", model, serial); + +close: + close(fd); +exit: + logging_close(); + return rc; +} diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index b653185b26..b5a0dcdaa1 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -1,6 +1,6 @@ #/bin/sh -EXTRAS="extras/chassis_id extras/scsi_id extras/volume_id extras/run_directory" +EXTRAS="extras/chassis_id extras/scsi_id extras/ata_id extras/volume_id extras/run_directory" [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build echo KERNEL_DIR: "$KERNEL_DIR" From 208f6aba21199ff4f93002eeb948d564f76843e6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 26 Jun 2005 01:54:47 +0200 Subject: [PATCH 1337/4284] rename udev_volume_id to vol_id and add --export option Signed-off-by: Kay Sievers --- extras/ata_id/ata_id.c | 1 + extras/volume_id/Makefile | 8 +- extras/volume_id/README | 70 +++++--- extras/volume_id/s390-dasd.rules | 7 - .../volume_id/{udev_volume_id.c => vol_id.c} | 154 +++++++++--------- 5 files changed, 132 insertions(+), 108 deletions(-) delete mode 100644 extras/volume_id/s390-dasd.rules rename extras/volume_id/{udev_volume_id.c => vol_id.c} (63%) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index e26cb6bd2d..59e2b3987b 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -81,6 +81,7 @@ static void set_str(char *to, const unsigned char *from, int count) case '/': case ' ': to[j++] = '_'; + break; default: to[j++] = from[i]; } diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 56fdf278b9..eca9cfdbd4 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -1,13 +1,13 @@ -# Makefile for udev_volume_id +# Makefile for volume_id # -# Copyright (C) 2004 Kay Sievers +# 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. # -PROG = udev_volume_id +PROG = vol_id all: $(PROG) @@ -33,7 +33,7 @@ override CFLAGS+=-D_FILE_OFFSET_BITS=64 VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc -OBJS = udev_volume_id.o $(VOLUME_ID_OBJS) ../../udev.a +OBJS = vol_id.o $(VOLUME_ID_OBJS) ../../udev.a HEADERS = $(VOLUME_ID_HEADERS) $(OBJS): $(HEADERS) diff --git a/extras/volume_id/README b/extras/volume_id/README index d570615e10..a7635ff612 100644 --- a/extras/volume_id/README +++ b/extras/volume_id/README @@ -1,43 +1,73 @@ - -udev_volume_id - partition, filesystem, disklabel reader +vol_id - partition, filesystem, disklabel reader This program is normally called from a udev rule, to provide udev with the name, uuid or the filesystem type of a partition to name a device node. -udev_volume_id opens the blockdevice node specified at the commandline. -The following commandline switches are supported to specify what udev_volume_id -should print to stdout: +vol_id opens the blockdevice node specified at the commandline. +The following commandline switches are supported to specify what vol_id +should print: - no option prints all values - -h prints help text - -l prints the label of the partition - -u prints the uuid of the partition + --export prints all values + -h prints help text + -l prints the label of the partition + -u prints the uuid of the partition -udev_volume_id will only return successful if the string asked for, is not +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. -The following rule will create a symlink named with the label string: - KERNEL="[hs]d*", PROGRAM="/sbin/udev_volume_id -l %N", SYMLINK="%c" +fstype probe label uuid fsversion +---------------------------------------------------- +ext * * * * +reiserfs jr/3.5/3.6/4 * * * * +fat (12, 16, 32) * * * * +ntfs * * * * +jfs * * * - +xfs * * * - +hfs (plus, wrapped) * * * - +udf * * - - +iso9660 * * n/a - +ufs * - - - +linux swap * * * * +LVM 1 * - - - +LVM 2 * - - * +linux raid * - * * +cramfs * * - - +sysv * * - * +luks * - * - +hpfs * - - - +romfs * +minix * +dasd * +highpoint * +isw_raid * +lsi_raid * +nvidia_raid * +promise_raid * +silicon_raid * +via_raid * +mac partitons * +msdos partitions * -If no label is found udev_volume_id exits with nonzero and the rule will be + +The following rule will create a symlink named with the label string: + KERNEL=="[hs]d*", PROGRAM=="/sbin/vol_id -l %N", SYMLINK+="%c" + +If no label is found vol_id exits with nonzero and the rule will be ignored. To give it a try, you may call it on the commandline: - - [root@pim udev.kay]# extras/volume_id/udev_volume_id /dev/hda3 + [root@pim udev.kay]# extras/volume_id/vol_id /dev/hda3 T:ext3 L:Music Store N:Music_Store U:d2da42b5-bbd9-44eb-a72c-cc4542fcb71e - [root@pim udev.kay]# extras/volume_id/udev_volume_id -l /dev/hda3 + [root@pim udev.kay]# extras/volume_id/vol_id -l /dev/hda3 Music_Store - [root@pim udev.kay]# extras/volume_id/udev_volume_id -t /dev/hda3 + [root@pim udev.kay]# extras/volume_id/vol_id -t /dev/hda3 swap -Please send any comment/questions/concerns to me or: - linux-hotplug-devel@lists.sourceforge.net - +Any comment/questions/concerns to me: Kay Sievers diff --git a/extras/volume_id/s390-dasd.rules b/extras/volume_id/s390-dasd.rules deleted file mode 100644 index a870d87e04..0000000000 --- a/extras/volume_id/s390-dasd.rules +++ /dev/null @@ -1,7 +0,0 @@ -# s390 block devices named by disk label -KERNEL="dasd*[a-z]", PROGRAM="/sbin/udev_volume_id -d -l" RESULT="[0-9A-Z]*", SYMLINK="dasd/%c/disc dasd/%b/disc" -KERNEL="dasd*[0-9]", PROGRAM="/sbin/udev_volume_id -d -l" RESULT="[0-9A-Z]*", SYMLINK="dasd/%c/part%n dasd/%b/part%n" -KERNEL="dasd*[a-z]", SYMLINK="dasd/%b/disc" -KERNEL="dasd*[0-9]", SYMLINK="dasd/%b/part%n" -KERNEL="dcssblk*", NAME="%k", SYMLINK="dcssblk/%b" - diff --git a/extras/volume_id/udev_volume_id.c b/extras/volume_id/vol_id.c similarity index 63% rename from extras/volume_id/udev_volume_id.c rename to extras/volume_id/vol_id.c index 7c6fc4050d..3048fd8062 100644 --- a/extras/volume_id/udev_volume_id.c +++ b/extras/volume_id/vol_id.c @@ -64,60 +64,83 @@ void log_message(int priority, const char *format, ...) } #endif -extern int optind; +static void set_str(char *to, const unsigned char *from, int count) +{ + int i, j; + int len; + + len = strnlen(from, count); + while (isspace(from[len-1])) + len--; + + i = 0; + while (isspace(from[i]) && (i < len)) + i++; + + j = 0; + while (i < len) { + switch(from[i]) { + case '/': + break; + case ' ': + to[j++] = '_'; + break; + default: + to[j++] = from[i]; + } + i++; + } + to[j] = '\0'; +} int main(int argc, char *argv[]) { - const char help[] = "usage: udev_volume_id [-t|-l|-u] \n" + const char help[] = "usage: udev_volume_id [--export|-t|-l|-u] \n" + " --export\n" " -t filesystem type\n" " -l filesystem label\n" " -u filesystem uuid\n" "\n"; - static const char short_options[] = "htlu"; + enum print_type { + PRINT_EXPORT, + PRINT_TYPE, + PRINT_LABEL, + PRINT_UUID, + } print = PRINT_EXPORT; struct volume_id *vid = NULL; - const char *device; - char print = 'a'; static char name[VOLUME_ID_LABEL_SIZE]; - int len, i, j; + int i; unsigned long long size; - int rc = 1; + const char *node = NULL; + int rc = 0; logging_init("udev_volume_id"); - while (1) { - int option; + for (i = 1 ; i < argc; i++) { + char *arg = argv[i]; - option = getopt(argc, argv, short_options); - if (option == -1) - break; - - switch (option) { - case 't': - print = 't'; - continue; - case 'l': - print = 'l'; - continue; - case 'u': - print = 'u'; - continue; - case 'h': - case '?': - default: - printf(help); - exit(1); - } + if (strcmp(arg, "--export") == 0) { + print = PRINT_EXPORT; + } else if (strcmp(arg, "-t") == 0) { + print = PRINT_TYPE; + } else if (strcmp(arg, "-l") == 0) { + print = PRINT_LABEL; + } else if (strcmp(arg, "-u") == 0) { + print = PRINT_UUID; + } else + node = arg; + } + if (!node) { + err("no node specified"); + fprintf(stderr, help); + rc = 1; + goto exit; } - device = argv[optind]; - if (device == NULL) { - printf(help); - exit(1); - } - - vid = volume_id_open_node(device); + vid = volume_id_open_node(node); if (vid == NULL) { - printf("error open volume\n"); + fprintf(stderr, "error open volume\n"); + rc = 2; goto exit; } @@ -130,69 +153,46 @@ int main(int argc, char *argv[]) if (volume_id_probe_dasd(vid) == 0) goto print; - printf("unknown volume type\n"); + fprintf(stderr, "unknown volume type\n"); + rc = 3; goto exit; - print: - len = strnlen(vid->label, VOLUME_ID_LABEL_SIZE); - - /* remove trailing spaces */ - while (len > 0 && isspace(vid->label[len-1])) - len--; - name[len] = '\0'; - - /* substitute chars */ - i = 0; - j = 0; - while (j < len) { - switch(vid->label[j]) { - case '/' : - break; - case ' ' : - name[i++] = '_'; - break; - default : - name[i++] = vid->label[j]; - } - j++; - } - name[i] = '\0'; + set_str(name, vid->label, sizeof(vid->label)); switch (print) { - case 't': + case PRINT_EXPORT: + printf("ID_FS_USAGE=%s\n", vid->usage); + printf("ID_FS_TYPE=%s\n", vid->type); + printf("ID_FS_VERSION=%s\n", vid->type_version); + printf("ID_FS_UUID=%s\n", vid->uuid); + printf("ID_FS_LABEL=%s\n", vid->label); + printf("ID_FS_LABEL_SAFE=%s\n", name); + break; + case PRINT_TYPE: printf("%s\n", vid->type); break; - case 'l': + case PRINT_LABEL: if (name[0] == '\0' || (vid->usage_id != VOLUME_ID_FILESYSTEM && vid->usage_id != VOLUME_ID_DISKLABEL)) { - rc = 2; + rc = 3; goto exit; } printf("%s\n", name); break; - case 'u': + case PRINT_UUID: if (vid->uuid[0] == '\0' || vid->usage_id != VOLUME_ID_FILESYSTEM) { - rc = 2; + rc = 4; goto exit; } printf("%s\n", vid->uuid); break; - case 'a': - printf("F:%s\n", vid->usage); - printf("T:%s\n", vid->type); - printf("V:%s\n", vid->type_version); - printf("L:%s\n", vid->label); - printf("N:%s\n", name); - printf("U:%s\n", vid->uuid); } - rc = 0; exit: if (vid != NULL) volume_id_close(vid); logging_close(); - - exit(rc); + return rc; } From b8476286d62c82a1a0bd8de318aa3f7d835222a0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 26 Jun 2005 18:55:24 +0200 Subject: [PATCH 1338/4284] store the imported device information in the udevdb Any program can query with udevinfo for persistent device attributes evaluated on device discovery now. Signed-off-by: Kay Sievers --- extras/ata_id/Makefile | 2 +- extras/run_directory/Makefile | 4 ++-- extras/volume_id/vol_id.c | 9 +++---- udev.h | 1 + udev_db.c | 9 ++++++- udev_libc_wrapper.h | 13 ++++++---- udev_rules.c | 28 +++++++++++++--------- udev_utils.c | 42 ++++++++++++++++++++++++++++++-- udev_utils.h | 1 + udevinfo.c | 45 +++++++++++++++++++++-------------- udevstart.c | 26 ++++++++++++++------ 11 files changed, 127 insertions(+), 53 deletions(-) diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index ad79a0d836..a19c4b2289 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -1,4 +1,4 @@ -# Makefile for udev_volume_id +# Makefile for ata_id # # Copyright (C) 2004 Kay Sievers # diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 12dccf0749..0562073c8f 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -1,6 +1,6 @@ -# Makefile for udev_volume_id +# Makefile for run_directory # -# Copyright (C) 2004 Kay Sievers +# 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 diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 3048fd8062..451fd355c1 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -1,11 +1,8 @@ /* - * udev_volume_id - udev callout to read filesystem label and uuid + * vol_id - udev callout to read filesystem label and uuid * * Copyright (C) 2005 Kay Sievers * - * sample udev rule for creation of a symlink with the filsystem uuid: - * KERNEL="sd*", PROGRAM="/sbin/udev_volume_id -u %N", SYMLINK="%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 version 2 of the License. @@ -95,7 +92,7 @@ static void set_str(char *to, const unsigned char *from, int count) int main(int argc, char *argv[]) { - const char help[] = "usage: udev_volume_id [--export|-t|-l|-u] \n" + const char help[] = "usage: vol_id [--export|-t|-l|-u] \n" " --export\n" " -t filesystem type\n" " -l filesystem label\n" @@ -114,7 +111,7 @@ int main(int argc, char *argv[]) const char *node = NULL; int rc = 0; - logging_init("udev_volume_id"); + logging_init("vol_id"); for (i = 1 ; i < argc; i++) { char *arg = argv[i]; diff --git a/udev.h b/udev.h index 11fbe02460..b5287bb53f 100644 --- a/udev.h +++ b/udev.h @@ -69,6 +69,7 @@ struct udevice { dev_t devt; struct list_head run_list; int run_final; + struct list_head env_list; char tmp_node[PATH_SIZE]; int partitions; diff --git a/udev_db.c b/udev_db.c index afbd50e50f..264af79d06 100644 --- a/udev_db.c +++ b/udev_db.c @@ -86,7 +86,8 @@ int udev_db_add_device(struct udevice *udev) fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt)); fprintf(f, "A:%u\n", udev->partitions); 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); return 0; @@ -149,6 +150,12 @@ static int parse_db_file(struct udevice *udev, const char *filename) strlcpy(line, &bufline[2], count-1); udev->ignore_remove = atoi(line); break; + case 'E': + if (count > sizeof(line)) + count = sizeof(line); + strlcpy(line, &bufline[2], count-1); + name_list_add(&udev->env_list, line, 0); + break; } } file_unmap(buf, bufsize); diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 4d6d332c69..4bb68913a9 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -44,15 +44,18 @@ #include +#ifdef __KLIBC__ +static inline int clearenv(void) +{ + environ[0] = NULL; + return 0; +} +#endif + extern uid_t lookup_user(const char *user); extern gid_t lookup_group(const char *group); -#ifndef strlcat extern size_t strlcpy(char *dst, const char *src, size_t size); -#endif - -#ifndef strlcat extern size_t strlcat(char *dst, const char *src, size_t size); -#endif #endif /* _UDEV_LIBC_WRAPPER_H_ */ diff --git a/udev_rules.c b/udev_rules.c index b81943a17c..9b9454e8fb 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -174,21 +174,26 @@ static int get_key(char **line, char **key, char **value) linepos++; /* get the value*/ - if (linepos[0] == '\0') - return -1; - if (linepos[0] == '"') { linepos++; temp = strchr(linepos, '"'); - if (!temp) + if (!temp) { + dbg("missing closing quote"); return -1; + } + dbg("value is quoted"); temp[0] = '\0'; } else if (linepos[0] == '\'') { linepos++; temp = strchr(linepos, '\''); - if (!temp) + if (!temp) { + dbg("missing closing quote"); return -1; + } + dbg("value is quoted"); temp[0] = '\0'; + } else if (linepos[0] == '\0') { + dbg("value is empty"); } else { temp = linepos; while (temp[0] && !isspace(temp[0])) @@ -200,7 +205,7 @@ static int get_key(char **line, char **key, char **value) return 0; } -static int import_keys_into_env(const char *buf, size_t bufsize) +static int import_keys_into_env(struct udevice *udev, const char *buf, size_t bufsize) { char line[LINE_SIZE]; const char *bufline; @@ -211,7 +216,7 @@ static int import_keys_into_env(const char *buf, size_t bufsize) size_t count; int lineno; - /* loop through the whole file */ + /* loop through the whole buffer */ lineno = 0; cur = 0; while (cur < bufsize) { @@ -242,6 +247,7 @@ static int import_keys_into_env(const char *buf, size_t bufsize) linepos = line; if (get_key(&linepos, &variable, &value) == 0) { dbg("import '%s=%s'", variable, value); + name_list_key_add(&udev->env_list, variable, value); setenv(variable, value, 1); } } @@ -249,7 +255,7 @@ static int import_keys_into_env(const char *buf, size_t bufsize) return 0; } -static int import_file_into_env(const char *filename) +static int import_file_into_env(struct udevice *udev, const char *filename) { char *buf; size_t bufsize; @@ -258,7 +264,7 @@ static int import_file_into_env(const char *filename) err("can't open '%s'", filename); return -1; } - import_keys_into_env(buf, bufsize); + import_keys_into_env(udev, buf, bufsize); file_unmap(buf, bufsize); return 0; @@ -271,7 +277,7 @@ static int import_program_into_env(struct udevice *udev, const char *program) if (execute_program(program, udev->subsystem, result, sizeof(result), &reslen) != 0) return -1; - return import_keys_into_env(result, reslen); + return import_keys_into_env(udev, result, reslen); } /* finds the lowest positive N such that N isn't present in the udevdb @@ -828,7 +834,7 @@ try_parent: rc = import_program_into_env(udev, import); } else { dbg("import file import='%s'", import); - rc = import_file_into_env(import); + rc = import_file_into_env(udev, import); } if (rc) { dbg(KEY_IMPORT " failed"); diff --git a/udev_utils.c b/udev_utils.c index 9e2e152763..3ab9e43348 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -47,6 +47,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs memset(udev, 0x00, sizeof(struct udevice)); INIT_LIST_HEAD(&udev->symlink_list); INIT_LIST_HEAD(&udev->run_list); + INIT_LIST_HEAD(&udev->env_list); if (subsystem) strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem)); @@ -112,6 +113,10 @@ void udev_cleanup_device(struct udevice *udev) list_del(&name_loop->node); free(name_loop); } + list_for_each_entry_safe(name_loop, temp_loop, &udev->env_list, node) { + list_del(&name_loop->node); + free(name_loop); + } } int string_is_true(const char *str) @@ -303,10 +308,14 @@ int name_list_add(struct list_head *name_list, const char *name, int sort) dbg("'%s' is already in the list", name); return 0; } - if (sort && strcmp(loop_name->name, name) > 0) - break; } + if (sort) + list_for_each_entry(loop_name, name_list, node) { + if (sort && strcmp(loop_name->name, name) > 0) + break; + } + new_name = malloc(sizeof(struct name_entry)); if (new_name == NULL) { dbg("error malloc"); @@ -314,6 +323,35 @@ int name_list_add(struct list_head *name_list, const char *name, int sort) } strlcpy(new_name->name, name, sizeof(new_name->name)); + dbg("adding '%s'", new_name->name); + list_add_tail(&new_name->node, &loop_name->node); + + return 0; +} + +int name_list_key_add(struct list_head *name_list, const char *key, const char *value) +{ + struct name_entry *loop_name; + struct name_entry *new_name; + + list_for_each_entry(loop_name, name_list, node) { + if (strncmp(loop_name->name, key, strlen(key)) == 0) { + dbg("key already present '%s', replace it", loop_name->name); + snprintf(loop_name->name, sizeof(loop_name->name), "%s=%s", key, value); + loop_name->name[sizeof(loop_name->name)-1] = '\0'; + return 0; + } + } + + new_name = malloc(sizeof(struct name_entry)); + if (new_name == NULL) { + dbg("error malloc"); + return -ENOMEM; + } + + snprintf(new_name->name, sizeof(new_name->name), "%s=%s", key, value); + new_name->name[sizeof(new_name->name)-1] = '\0'; + dbg("adding '%s'", new_name->name); list_add_tail(&new_name->node, &loop_name->node); return 0; diff --git a/udev_utils.h b/udev_utils.h index 999a4fcf55..655c764fc8 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -44,6 +44,7 @@ extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); extern void remove_trailing_char(char *path, char c); extern void replace_untrusted_chars(char *string); extern int name_list_add(struct list_head *name_list, const char *name, int sort); +extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); extern int execute_program(const char *command, const char *subsystem, char *result, size_t ressize, size_t *reslen); diff --git a/udevinfo.c b/udevinfo.c index 69e5335b7c..db562eee49 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -92,14 +92,6 @@ static int print_record(struct udevice *udev) return 0; } -enum query_type { - NONE, - NAME, - PATH, - SYMLINK, - ALL, -}; - static int print_device_chain(const char *path) { struct sysfs_class_device *class_dev; @@ -185,7 +177,14 @@ int main(int argc, char *argv[], char *envp[]) struct udevice udev; int root = 0; int attributes = 0; - enum query_type query = 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] = ""; char temp[PATH_SIZE]; @@ -220,22 +219,27 @@ int main(int argc, char *argv[], char *envp[]) dbg("udev query: %s\n", optarg); if (strcmp(optarg, "name") == 0) { - query = NAME; + query = QUERY_NAME; break; } if (strcmp(optarg, "symlink") == 0) { - query = SYMLINK; + query = QUERY_SYMLINK; break; } if (strcmp(optarg, "path") == 0) { - query = PATH; + query = QUERY_PATH; + break; + } + + if (strcmp(optarg, "env") == 0) { + query = QUERY_ENV; break; } if (strcmp(optarg, "all") == 0) { - query = ALL; + query = QUERY_ALL; break; } @@ -268,7 +272,7 @@ int main(int argc, char *argv[], char *envp[]) } /* process options */ - if (query != NONE) { + if (query != QUERY_NONE) { if (path[0] != '\0') { /* remove sysfs_path if given */ if (strncmp(path, sysfs_path, strlen(sysfs_path)) == 0) { @@ -317,13 +321,13 @@ int main(int argc, char *argv[], char *envp[]) print: switch(query) { - case NAME: + case QUERY_NAME: if (root) printf("%s/%s\n", udev_root, udev.name); else printf("%s\n", udev.name); goto exit; - case SYMLINK: + case QUERY_SYMLINK: if (list_empty(&udev.symlink_list)) break; if (root) @@ -334,10 +338,14 @@ print: printf("%s ", name_loop->name); printf("\n"); goto exit; - case PATH: + case QUERY_PATH: printf("%s\n", udev.devpath); goto exit; - case ALL: + case QUERY_ENV: + list_for_each_entry(name_loop, &udev.env_list, node) + printf("%s\n", name_loop->name); + goto exit; + case QUERY_ALL: print_record(&udev); goto exit; default: @@ -373,6 +381,7 @@ help: " '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" " -p PATH sysfs device path used for query or chain\n" diff --git a/udevstart.c b/udevstart.c index b65a28aab6..4e922bb716 100644 --- a/udevstart.c +++ b/udevstart.c @@ -45,6 +45,9 @@ #include "udev_utils.h" #include "list.h" +static const char *udev_run_str; +static const char *udev_log_str; + #ifdef USE_LOG void log_message(int priority, const char *format, ...) { @@ -111,8 +114,17 @@ static int add_device(const char *path, const char *subsystem) const char *devpath; devpath = &path[strlen(sysfs_path)]; + + /* clear and set environment for next event */ + clearenv(); + setenv("ACTION", "add", 1); setenv("DEVPATH", devpath, 1); setenv("SUBSYSTEM", subsystem, 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); dbg("exec: '%s' (%s)\n", devpath, path); class_dev = sysfs_open_class_device_path(path); @@ -327,11 +339,15 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udev"); udev_init_config(); - /* disable all logging if not explicitely requested */ - if (getenv("UDEV_LOG") == NULL) - udev_log_priority = 0; 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; @@ -344,10 +360,6 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); - /* set environment for executed programs */ - setenv("ACTION", "add", 1); - setenv("UDEV_START", "1", 1); - udev_rules_init(); udev_scan_block(); From 34129109a1f5dca72af2f3f2d3d14a9a0d0c43f6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 27 Jun 2005 02:51:49 +0200 Subject: [PATCH 1339/4284] add -x to scsi_id to export the queried values in env format Signed-off-by: Kay Sievers --- extras/scsi_id/scsi_id.c | 66 ++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 32a96d8adb..86b84bee30 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -52,7 +52,7 @@ * options are not supported, but other code is still left in place for * now. */ -static const char short_options[] = "bd:f:gip:s:uvV"; +static const char short_options[] = "bd:f:gip:s:uvVx"; /* * Just duplicate per dev options. */ @@ -71,6 +71,9 @@ static int use_stderr; static int debug; static int hotplug_mode; static int reformat_serial; +static int export; +static char vendor_str[64]; +static char model_str[64]; void log_message (int level, const char *format, ...) { @@ -84,13 +87,8 @@ void log_message (int level, const char *format, ...) vfprintf(stderr, format, args); } else { static int logging_init = 0; - static unsigned char logname[32]; if (!logging_init) { - /* - * klibc does not have LOG_PID. - */ - snprintf(logname, 32, "scsi_id[%d]", getpid()); - openlog (logname, 0, LOG_DAEMON); + openlog ("scsi_id", LOG_PID, LOG_DAEMON); logging_init = 1; } @@ -100,6 +98,34 @@ void log_message (int level, const char *format, ...) return; } +static void set_str(char *to, const unsigned char *from, int count) +{ + int i, j; + int len; + + len = strnlen(from, count); + while (isspace(from[len-1])) + len--; + + i = 0; + while (isspace(from[i]) && (i < len)) + i++; + + j = 0; + while (i < len) { + switch(from[i]) { + case '/': + case ' ': + to[j++] = '_'; + break; + default: + to[j++] = from[i]; + } + i++; + } + to[j] = '\0'; +} + static int get_major_minor(struct sysfs_class_device *class_dev, int *maj, int *min) { @@ -465,6 +491,10 @@ static int set_options(int argc, char **argv, const char *short_opts, reformat_serial = 1; break; + case 'x': + export = 1; + break; + case 'v': debug++; break; @@ -507,6 +537,7 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, scsi_dev->name); return -1; } + set_str(vendor_str, vendor->value, sizeof(vendor_str)-1); model = sysfs_get_device_attr(scsi_dev, "model"); if (!model) { @@ -514,6 +545,7 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, scsi_dev->name); return -1; } + set_str(model_str, model->value, sizeof(model_str)-1); retval = get_file_options(vendor->value, model->value, &newargc, &newargv); @@ -584,7 +616,7 @@ static void format_serial(char *serial) *p = '_'; p++; } - return; +return; } /* @@ -723,11 +755,19 @@ static int scsi_id(const char *target_path, char *maj_min_dev) retval = 0; } if (!retval) { - if (reformat_serial) - format_serial(serial); - if (display_bus_id) - printf("%s: ", scsi_dev->name); - printf("%s\n", serial); + if (export) { + static char serial_str[64]; + printf("ID_VENDOR=%s\n", vendor_str); + printf("ID_MODEL=%s\n", model_str); + set_str(serial_str, serial, sizeof(serial_str)); + printf("ID_SERIAL=%s\n", serial_str); + } else { + if (reformat_serial) + format_serial(serial); + if (display_bus_id) + printf("%s: ", scsi_dev->name); + printf("%s\n", serial); + } dprintf("%s\n", serial); retval = 0; } From aaff09a30ab849186c0d4ad8bde83876d7a1a63d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 27 Jun 2005 17:04:56 +0200 Subject: [PATCH 1340/4284] add ID_TYPE to the id probers Export the type of device from ata_id and scsi_id, also strip leading and trailing whitespace and substitute consecutive whitespace with a single underline char. From: Hannes Reinecke Signed-off-by: Kay Sievers --- extras/ata_id/ata_id.c | 41 ++++++++++++++++---- extras/scsi_id/scsi_id.c | 80 +++++++++++++++++++++++++++++++++++----- udev_rules.c | 2 +- udev_utils.c | 2 +- udevd.c | 2 +- 5 files changed, 108 insertions(+), 19 deletions(-) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index 59e2b3987b..34b1ccdff1 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -67,25 +67,30 @@ static void set_str(char *to, const unsigned char *from, int count) int i, j; int len; + /* strip trailing whitespace */ len = strnlen(from, count); while (isspace(from[len-1])) len--; + /* strip leading whitespace */ i = 0; while (isspace(from[i]) && (i < len)) i++; j = 0; while (i < len) { - switch(from[i]) { - case '/': - case ' ': + /* substitute multiple whitespace */ + if (isspace(from[i])) { + while (isspace(from[i])) + i++; to[j++] = '_'; - break; - default: - to[j++] = from[i]; } - i++; + /* skip chars */ + if (from[i] == '/') { + i++; + continue; + } + to[j++] = from[i++]; } to[j] = '\0'; } @@ -137,6 +142,28 @@ int main(int argc, char *argv[]) set_str(revision, 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); diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 86b84bee30..4003ee6af5 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -74,6 +74,8 @@ static int reformat_serial; static int export; static char vendor_str[64]; static char model_str[64]; +static char revision_str[16]; +static char type_str[16]; void log_message (int level, const char *format, ...) { @@ -103,29 +105,72 @@ static void set_str(char *to, const unsigned char *from, int count) int i, j; int len; + /* strip trailing whitespace */ len = strnlen(from, count); while (isspace(from[len-1])) len--; + /* strip leading whitespace */ i = 0; while (isspace(from[i]) && (i < len)) i++; j = 0; while (i < len) { - switch(from[i]) { - case '/': - case ' ': + /* substitute multiple whitespace */ + if (isspace(from[i])) { + while (isspace(from[i])) + i++; to[j++] = '_'; - break; - default: - to[j++] = from[i]; } - i++; + /* skip chars */ + if (from[i] == '/') { + i++; + continue; + } + to[j++] = from[i++]; } to[j] = '\0'; } +static void set_type(char *to, const char *from, int count) +{ + int type_num; + char *eptr; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + sprintf(to, "disk"); + break; + case 1: + sprintf(to, "tape"); + break; + case 4: + sprintf(to, "optical"); + break; + case 5: + sprintf(to, "cd"); + break; + case 7: + sprintf(to, "optical"); + break; + case 0xe: + sprintf(to, "disk"); + break; + case 0xf: + sprintf(to, "optical"); + break; + default: + sprintf(to, "generic"); + break; + } + } else { + sprintf(to, "generic"); + } +} + static int get_major_minor(struct sysfs_class_device *class_dev, int *maj, int *min) { @@ -521,7 +566,7 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, int retval; int newargc; char **newargv = NULL; - struct sysfs_attribute *vendor, *model; + struct sysfs_attribute *vendor, *model, *type; int option; *good_bad = all_good; @@ -547,6 +592,22 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, } set_str(model_str, model->value, sizeof(model_str)-1); + type = sysfs_get_device_attr(scsi_dev, "type"); + if (!type) { + log_message(LOG_WARNING, "%s: cannot get type attribute\n", + scsi_dev->name); + return -1; + } + set_type(type_str, type->value, sizeof(type_str)-1); + + type = sysfs_get_device_attr(scsi_dev, "rev"); + if (!type) { + log_message(LOG_WARNING, "%s: cannot get type attribute\n", + scsi_dev->name); + return -1; + } + set_str(revision_str, type->value, sizeof(revision_str)-1); + retval = get_file_options(vendor->value, model->value, &newargc, &newargv); @@ -616,7 +677,6 @@ static void format_serial(char *serial) *p = '_'; p++; } -return; } /* @@ -759,8 +819,10 @@ static int scsi_id(const char *target_path, char *maj_min_dev) static char serial_str[64]; 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); + printf("ID_TYPE=%s\n", type_str); } else { if (reformat_serial) format_serial(serial); diff --git a/udev_rules.c b/udev_rules.c index 9b9454e8fb..9606f04d3d 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -793,7 +793,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, len = strlen(value); while (len > 0 && isspace(value[len-1])) value[--len] = '\0'; - dbg("removed %i trailing whitespace chars from '%s'", strlen(value)-len, value); + dbg("removed %zi trailing whitespace chars from '%s'", strlen(value)-len, value); } dbg("compare attribute '%s' value '%s' with '%s'", pair->name, value, pair->value); diff --git a/udev_utils.c b/udev_utils.c index 3ab9e43348..073cde1074 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -485,7 +485,7 @@ int execute_program(const char *command, const char *subsystem, len += count; if (len >= ressize-1) { - err("ressize %d too short", ressize); + err("ressize %ld too short", (long)ressize); retval = -1; break; } diff --git a/udevd.c b/udevd.c index 209b9fcd87..e3ee1457cb 100644 --- a/udevd.c +++ b/udevd.c @@ -600,7 +600,7 @@ static struct uevent_msg *get_netlink_msg(void) if ((size_t)size > sizeof(buffer)-1) size = sizeof(buffer)-1; buffer[size] = '\0'; - dbg("uevent_size=%i", size); + dbg("uevent_size=%li", (long)size); /* start of event payload */ bufpos = strlen(buffer)+1; From be0856c841e248c491e0fdea013a7af0f61a76b1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 30 Jun 2005 21:50:22 +0200 Subject: [PATCH 1341/4284] prepare RELEASE-NOTES Signed-off-by: Kay Sievers --- RELEASE-NOTES | 99 ++++++++++++++++++++++++++++++++++++++++++++++ test/udev-test.pl | 4 +- udev_rules_parse.c | 19 ++++++++- 3 files changed, 119 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 9b7fa31330..46787704ce 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,102 @@ +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 diff --git a/test/udev-test.pl b/test/udev-test.pl index bf6b62f10a..5210471474 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -264,7 +264,7 @@ EOF devpath => "/block/sda", exp_name => "subdir/sys/node" , rules => < "/block/sda", exp_name => "node12345678", rules => < Date: Thu, 30 Jun 2005 16:26:43 -0700 Subject: [PATCH 1342/4284] Update the gentoo rule file --- etc/udev/gentoo/udev.rules | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 65113aebf7..6698aa6fd9 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -141,7 +141,7 @@ 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="0600" +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" @@ -184,7 +184,7 @@ KERNEL="vtx[0-9]*", NAME="v4l/vtx%n", GROUP="video" # dvb devices KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video", MODE="0660" -# Asterix Zaptel devices +# Asterisk Zaptel devices KERNEL="zapctl", NAME="zap/ctl" KERNEL="zaptimer", NAME="zap/timer" KERNEL="zapchannel", NAME="zap/channel" @@ -238,4 +238,12 @@ KERNEL="pktcdvd[0-9]*", NAME="pktcdvd/pktcdvd%n", GROUP="cdrw", MODE="0660" # infiniband devices KERNEL="umad*", NAME="infiniband/%k" -KERNEL="issm*", NAME="infiniband/%k" +KERNEL="issm*", NAME="infiniband/%k" + +# tpm devices +KERNEL="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" + +# be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems +RUN += "/sbin/udev_run_devd" +RUN += "/sbin/udev_run_hotplugd" + From 4d8c16072a2d529b40bcc392396c0dc215236f01 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 30 Jun 2005 16:27:52 -0700 Subject: [PATCH 1343/4284] 059 release --- Makefile | 2 +- udev.spec | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 32e057b1cb..b04321ff4e 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ CONTROL = udevcontrol INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 058 +VERSION = 059 RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev DESTDIR = diff --git a/udev.spec b/udev.spec index 0430a1259d..d56a43ce7d 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 058 +Version: 059 Release: 1 License: GPL Group: Utilities/System From a105fe495bdc95a24eaf2db557104534f6e1db34 Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Thu, 23 Jun 2005 00:28:54 +0200 Subject: [PATCH 1344/4284] [PATCH] #define NETLINK_KOBJECT_UEVENT On many systems the system kernel headers are not recent enough to compile udev. --- udevd.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/udevd.c b/udevd.c index e3ee1457cb..f69abc4c09 100644 --- a/udevd.c +++ b/udevd.c @@ -48,6 +48,10 @@ #include "udevd.h" #include "logging.h" +#ifndef NETLINK_KOBJECT_UEVENT +#define NETLINK_KOBJECT_UEVENT 15 +#endif + /* global variables*/ static int udevd_sock; static int uevent_netlink_sock; From 3cf745e128ba02fcea33bd13190b713f00119150 Mon Sep 17 00:00:00 2001 From: Gustavo Zacarias Date: Mon, 27 Jun 2005 12:46:53 -0300 Subject: [PATCH 1345/4284] [PATCH] Udev doesn't properly build with $CROSS Patch attached - basically you're always invoking klcc for the udev build itself, but klibc builds $(CROSS)klcc. Thus static cross builds don't work. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b04321ff4e..665f75a29e 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,7 @@ endif # link udev against it statically. Otherwise, use glibc and link dynamically. ifeq ($(strip $(USE_KLIBC)),true) KLIBC_INSTALL = $(PWD)/klibc/.install - KLCC = $(KLIBC_INSTALL)/bin/klcc + KLCC = $(KLIBC_INSTALL)/bin/$(CROSS)klcc CC = $(KLCC) LD = $(KLCC) else From 1fcc2a36fd0de4c268963ae9dc9402c73f3320bd Mon Sep 17 00:00:00 2001 From: Greg KH Date: Sat, 2 Jul 2005 23:47:43 -0700 Subject: [PATCH 1346/4284] Fix the gentoo udev rules to allow the box to boot properly --- etc/udev/gentoo/udev.rules | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 6698aa6fd9..9feed3ea4b 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -244,6 +244,8 @@ KERNEL="issm*", NAME="infiniband/%k" KERNEL="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems -RUN += "/sbin/udev_run_devd" -RUN += "/sbin/udev_run_hotplugd" +# run hotplug.d stuff only if we came from a hotplug event, not for udevstart +ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" +# always run etc.d stuff for now. +RUN += "/sbin/udev_run_devd" From 66f74a2d1411e9761ac90c5a2f81d70b22ec936d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 2 Jul 2005 22:29:46 +0200 Subject: [PATCH 1347/4284] [PATCH] Keep udevstart from skipping devices without a 'dev' file --- udevstart.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevstart.c b/udevstart.c index 4e922bb716..22b781d52a 100644 --- a/udevstart.c +++ b/udevstart.c @@ -135,7 +135,7 @@ static int add_device(const char *path, const char *subsystem) udev_init_device(&udev, devpath, subsystem, "add"); udev.devt = get_devt(class_dev); - if (!udev.devt) { + if (!udev.devt && udev.type != DEV_NET) { dbg("sysfs_open_class_device_path failed"); return -1; } @@ -337,7 +337,7 @@ int main(int argc, char *argv[], char *envp[]) { struct sigaction act; - logging_init("udev"); + logging_init("udevstart"); udev_init_config(); dbg("version %s", UDEV_VERSION); From 281c368b8f00fbe70ea45c3c5f8d152ae7f1e077 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Sat, 2 Jul 2005 23:55:08 -0700 Subject: [PATCH 1348/4284] 060 release --- ChangeLog | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 3942d319d5..4f784bf252 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,69 @@ +Summary of changes from v058 to v059 +============================================ + +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 ============================================ diff --git a/Makefile b/Makefile index 665f75a29e..302bb3da14 100644 --- a/Makefile +++ b/Makefile @@ -51,7 +51,7 @@ CONTROL = udevcontrol INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 059 +VERSION = 060 RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev DESTDIR = From 46763d59dc210e22c611547776363b021c421467 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Sat, 2 Jul 2005 23:55:38 -0700 Subject: [PATCH 1349/4284] Fix ChangeLog titles --- ChangeLog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 4f784bf252..d2e641fc4a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -Summary of changes from v058 to v059 +Summary of changes from v059 to v060 ============================================ Greg Kroah-Hartman: From 7c26d9eb432b173ccd61b998ab5a4a8debf51d68 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 3 Jul 2005 14:01:48 +0200 Subject: [PATCH 1350/4284] switch gentoo rules to new operators Signed-off-by: Kay Sievers --- etc/udev/gentoo/udev.rules | 288 +++++++++++++++++++------------------ 1 file changed, 147 insertions(+), 141 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 9feed3ea4b..7136f6a4bb 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -13,239 +13,245 @@ ########################################################### # all block devices -SUBSYSTEM="block", GROUP="disk" +SUBSYSTEM=="block", GROUP="disk" # cdrom symlinks and other good cdrom naming -BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" +BUS=="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" # disk devices -KERNEL="sd*", NAME="%k", GROUP="disk" -KERNEL="dasd*", NAME="%k", GROUP="disk" -KERNEL="ataraid*", NAME="%k", GROUP="disk" +KERNEL=="sd*", NAME="%k", GROUP="disk" +KERNEL=="dasd*", NAME="%k", GROUP="disk" +KERNEL=="ataraid*", NAME="%k", GROUP="disk" # compaq smart array -KERNEL="cciss*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" -KERNEL="ida*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +KERNEL=="cciss*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" +KERNEL=="ida*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" # mylex -KERNEL="rd*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +KERNEL=="rd*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" # dri devices -KERNEL="card*", NAME="dri/card%n", GROUP="video" -KERNEL="nvidia*", NAME="%k", GROUP="video" -KERNEL="3dfx*", NAME="%k", GROUP="video" +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" +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="dialout" -KERNEL="capi*", NAME="capi/%n", GROUP="dialout" +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20", GROUP="dialout" +KERNEL=="capi*", NAME="capi/%n", GROUP="dialout" # cpu devices -KERNEL="cpu[0-9]*", NAME="cpu/%n/cpuid" -KERNEL="msr[0-9]*", NAME="cpu/%n/msr" -KERNEL="microcode", NAME="cpu/microcode" +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="" +KERNEL=="dm-[0-9]*", OPTIONS="ignore_device" # 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" +#KERNEL=="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK+="%c" +KERNEL=="device-mapper", NAME="mapper/control" # fb devices -KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video" +KERNEL=="fb[0-9]*", NAME="fb/%n", SYMLINK+="%k", GROUP="video" # floppy devices -KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy" +KERNEL=="fd[0-9]*", NAME="floppy/%n", SYMLINK+="%k", GROUP="floppy" # i2c devices -KERNEL="i2c-[0-9]*", NAME="i2c/%n", SYMLINK="%k" +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="664" -KERNEL="ts*", NAME="input/%k", MODE="0600" +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="664" +KERNEL=="ts*", NAME="input/%k", MODE="0600" # loop devices -KERNEL="loop[0-9]*", NAME="loop/%n", SYMLINK="%k", GROUP="disk" +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" +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" +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" +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" +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" +KERNEL=="tun", NAME="net/%k" # ramdisk devices -KERNEL="ram[0-9]*", NAME="rd/%n", SYMLINK="%k" +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" +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" +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" # 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" +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%n", SYMLINK="%k", GROUP="tty" -KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", SYMLINK="%k", GROUP="tty" +KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="0666" +KERNEL=="pty[p-za-e][0-9a-f]*", NAME="pty/m%n", SYMLINK+="%k", GROUP="tty" +KERNEL=="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", 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" +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="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" +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" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k", GROUP="lp" +KERNEL=="hiddev*", NAME="usb/%k" +KERNEL=="auer*", NAME="usb/%k" +KERNEL=="legousbtower*", NAME="usb/%k", GROUP="usb" +KERNEL=="dabusb*", NAME="usb/%k" +BUS=="usb", KERNEL=="lp[0-9]*", 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", 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" +KERNEL=="video[0-9]*", NAME="v4l/video%n", SYMLINK+="video%n", GROUP="video" +KERNEL=="radio[0-9]*", NAME="v4l/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 -KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video", MODE="0660" +KERNEL=="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video", MODE="0660" # 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" +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" +KERNEL=="pilot", NAME="%k", GROUP="uucp" # jaz devices -KERNEL="jaz*", NAME="%k", GROUP="disk" +KERNEL=="jaz*", NAME="%k", GROUP="disk" # zip devices -KERNEL="pocketzip*", NAME="%k", GROUP="disk" -KERNEL="zip*", NAME="%k", GROUP="disk" +KERNEL=="pocketzip*", NAME="%k", GROUP="disk" +KERNEL=="zip*", NAME="%k", GROUP="disk" # ls120 devices -KERNEL="ls120", NAME="%k", GROUP="disk" +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=="lp*", NAME="%k", GROUP="lp" +KERNEL=="irlpt", NAME="%k", GROUP="lp" +KERNEL=="usblp", NAME="%k", GROUP="lp" +KERNEL=="lp*", 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" +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" +KERNEL=="diskonkey*", NAME="%k", GROUP="disk" # rem_ide devices -KERNEL="microdrive*", NAME="%k", GROUP="disk" +KERNEL=="microdrive*", NAME="%k", GROUP="disk" # kbd devices -KERNEL="kbd", NAME="%k", MODE="0664" +KERNEL=="kbd", NAME="%k", MODE="0664" # Sony Vaio Jogdial sonypi device -KERNEL="sonypi", NAME="%k", MODE="0666" +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" +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" +KERNEL=="umad*", NAME="infiniband/%k" +KERNEL=="issm*", NAME="infiniband/%k" # tpm devices -KERNEL="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" +KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" + +# firewire devices +KERNEL="raw1394", NAME="%k" +KERNEL="dv1394*", NAME="dv1394/%n" +KERNEL="video1394*", NAME="video1394/%n" # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems -# run hotplug.d stuff only if we came from a hotplug event, not for udevstart +# run hotplug.d/ stuff only if we came from a hotplug event, not for udevstart ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" -# always run etc.d stuff for now. -RUN += "/sbin/udev_run_devd" +# always run dev.d/ stuff for now. +RUN+="/sbin/udev_run_devd" + From ffd5c6893756af43daf2a9a30bdcff13784a1ec4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 3 Jul 2005 14:31:17 +0200 Subject: [PATCH 1351/4284] allow OPTIONS to be recognized for /sys/modules /sys/devices events Signed-off-by: Kay Sievers --- udev_rules.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 9606f04d3d..cd60c6d1ff 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -1089,9 +1089,6 @@ int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) break; dbg("process rule"); - if (rule->run_operation == KEY_OP_UNSET) - continue; - if (rule->name_operation != KEY_OP_UNSET || rule->symlink_operation != KEY_OP_UNSET || rule->mode != 0000 || rule->owner[0] != '\0' || rule->group[0] != '\0') { dbg("skip rule that names a device"); From c44563817a9eea73a5fac914dd7bd7aa4cbcdbb6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 3 Jul 2005 14:32:22 +0200 Subject: [PATCH 1352/4284] fake also kernel-name if we renamed a netif Signed-off-by: Kay Sievers --- udev_add.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udev_add.c b/udev_add.c index 89af96570f..e9ae150180 100644 --- a/udev_add.c +++ b/udev_add.c @@ -290,6 +290,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) if (retval != 0) goto exit; + info("renamed netif to '%s'", udev->name); /* we've changed the name, now fake the devpath, cause the * original kernel name sleeps with the fishes and we don't * get an event from the kernel with the new name @@ -298,6 +299,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) if (pos != NULL) { pos[1] = '\0'; strlcat(udev->devpath, udev->name, sizeof(udev->devpath)); + strlcpy(udev->kernel_name, udev->name, sizeof(udev->kernel_name)); setenv("DEVPATH", udev->devpath, 1); setenv("INTERFACE", udev->name, 1); } From 8deae6aa342cae01f75a5a269e1a49fdd6de6cc8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 3 Jul 2005 16:11:17 +0200 Subject: [PATCH 1353/4284] add IEEE1394 rules to the gentoo rule file --- etc/udev/gentoo/udev.rules | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 7136f6a4bb..de74c088f0 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -243,10 +243,10 @@ KERNEL=="issm*", NAME="infiniband/%k" # tpm devices KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" -# firewire devices -KERNEL="raw1394", NAME="%k" -KERNEL="dv1394*", NAME="dv1394/%n" -KERNEL="video1394*", NAME="video1394/%n" +# IEEE1394 (firewire) devices +KERNEL=="raw1394", NAME="%k", GROUP="video" +KERNEL=="dv1394*", NAME="dv1394/%n", GROUP="video" +KERNEL=="video1394*", NAME="video1394/%n", GROUP="video" # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems # run hotplug.d/ stuff only if we came from a hotplug event, not for udevstart From 7618e112b44e1ea3b7d0fa790eff9fbab452ae4f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 4 Jul 2005 17:02:25 +0200 Subject: [PATCH 1354/4284] add usb_id program to generate usb-storage device identifiers Signed-off-by: Hannes Reinecke --- extras/usb_id/Makefile | 53 ++++ extras/usb_id/usb_id.c | 480 +++++++++++++++++++++++++++++++++++++ test/simple-build-check.sh | 8 +- 3 files changed, 540 insertions(+), 1 deletion(-) create mode 100644 extras/usb_id/Makefile create mode 100644 extras/usb_id/usb_id.c diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile new file mode 100644 index 0000000000..4324f95c76 --- /dev/null +++ b/extras/usb_id/Makefile @@ -0,0 +1,53 @@ +# Makefile for usb_id +# +# 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. +# + +PROG = usb_id + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +override CFLAGS+=-D_FILE_OFFSET_BITS=64 + +OBJS = $(PROG).o $(VOLUME_ID_OBJS) ../../udev.a ../../libsysfs/sysfs.a +HEADERS = + +$(OBJS): $(HEADERS) + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(PROG): $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c new file mode 100644 index 0000000000..bca80f8de1 --- /dev/null +++ b/extras/usb_id/usb_id.c @@ -0,0 +1,480 @@ +/* + * usb_id.c + * + * Identify an USB (block) device + * + * Copyright (c) 2005 SUSE Linux Products GmbH, Germany + * Author: + * Hannes Reinecke + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include +#include +#include +#include +#include +#include +#include + +#include <../../libsysfs/sysfs/libsysfs.h> +#include "../../udev_utils.h" +#include "../../logging.h" + +#define MAX_NAME_LEN 72 +#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 + +char sysfs_mnt_path[SYSFS_PATH_MAX]; +static char vendor_str[64]; +static char model_str[64]; +static char serial_str[MAX_SERIAL_LEN]; +static char revision_str[16]; +static char type_str[16]; + +static int use_usb_info; +static int export; + +static void set_str(char *to, const unsigned char *from, int count) +{ + int i, j; + int len; + + /* strip trailing whitespace */ + len = strnlen(from, count); + while (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'; +} + +/* + * set_usb_iftype + * + * Set the type based on the USB interface class + */ +static void set_usb_iftype(char *to, const char *from, int count) +{ + int type_num; + char *eptr; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 1: + sprintf(to, "audio"); + break; + case 3: + sprintf(to, "hid"); + break; + case 7: + sprintf(to, "printer"); + break; + case 8: + sprintf(to, "disk"); + 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 */ + default: + sprintf(to, "generic"); + break; + } + } else { + sprintf(to, "generic"); + } +} + +/* + * set_usb_ifsybtype + * + * Set the type base on the interfaceSubClass. + * Valid for Mass-Storage devices (type 8) only. + */ +static int set_usb_ifsubtype(char *to, const char *from, int count) +{ + int type_num = 0; + char *eptr; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 2: + sprintf(to, "cd"); + break; + case 3: + sprintf(to, "tape"); + break; + case 4: /* UFI */ + case 5: /* SFF-8070i */ + sprintf(to, "floppy"); + break; + case 1: /* RBC devices */ + case 6: /* Transparent SPC-2 devices */ + sprintf(to, "disk"); + break; + } + } else { + sprintf(to, "generic"); + } + + return type_num; +} + +static void set_scsi_type(char *to, const char *from, int count) +{ + int type_num; + char *eptr; + + type_num = strtoul(from, &eptr, 0); + if (eptr != from) { + switch (type_num) { + case 0: + sprintf(to, "disk"); + break; + case 1: + sprintf(to, "tape"); + break; + case 4: + sprintf(to, "optical"); + break; + case 5: + sprintf(to, "cd"); + break; + case 7: + sprintf(to, "optical"); + break; + case 0xe: + sprintf(to, "disk"); + break; + case 0xf: + sprintf(to, "optical"); + break; + default: + sprintf(to, "generic"); + break; + } + } else { + sprintf(to, "generic"); + } +} + +/* + * 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 *target_path) +{ + struct sysfs_class_device *class_dev; /* of target_path */ + struct sysfs_class_device *class_dev_parent; /* for partitions */ + struct sysfs_device *scsi_dev; /* the scsi_device */ + struct sysfs_device *target_dev; + struct sysfs_device *host_dev, *interface_dev, *usb_dev; + struct sysfs_attribute *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; + struct sysfs_attribute *usb_model, *usb_vendor, *usb_rev, *usb_serial; + struct sysfs_attribute *if_class, *if_subclass; + int if_class_num; + int protocol = 0; + + class_dev = sysfs_open_class_device_path(target_path); + if (!class_dev) { + info("open class %s failed: %s", target_path, strerror(errno)); + return 1; + } + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent) { + scsi_dev = sysfs_get_classdev_device(class_dev_parent); + } else { + scsi_dev = sysfs_get_classdev_device(class_dev); + } + + /* + * The close of scsi_dev will close class_dev or class_dev_parent. + */ + + /* + * We assume we are called after the device is completely ready, + * so we don't have to loop here like udev. (And we are usually + * called via udev.) + */ + if (!scsi_dev) { + /* + * errno is not set if we can't find the device link, so + * don't print it out here. + */ + info("Cannot find sysfs device associated with %s", target_path); + return 1; + } + + /* + * Allow only scsi devices. + * + * Other block devices can support SG IO, but only ide-cd does, so + * for now, don't bother with anything else. + */ + if (strcmp(scsi_dev->bus, "scsi") != 0) { + info("%s is not a scsi device", target_path); + return 1; + } + + /* target directory */ + target_dev = sysfs_get_device_parent(scsi_dev); + /* host directory */ + host_dev = sysfs_get_device_parent(target_dev); + /* usb interface directory */ + interface_dev = sysfs_get_device_parent(host_dev); + /* usb device directory */ + usb_dev = sysfs_get_device_parent(interface_dev); + + if (!strcmp(interface_dev->bus, "bus") != 0) { + info("%s is not an usb device", target_path); + return 1; + } + + if_class = sysfs_get_device_attr(interface_dev, "bInterfaceClass"); + if (!if_class) { + info("%s: cannot get bInterfaceClass attribute", interface_dev->name); + return -1; + } + if_class_num = strtoul(if_class->value, NULL, 16); + if (if_class_num != 8) { + set_usb_iftype(type_str, if_class->value, sizeof(type_str) - 1); + } else { + if_subclass = sysfs_get_device_attr(interface_dev, + "bInterfaceSubClass"); + protocol = set_usb_ifsubtype(type_str, if_subclass->value, + sizeof(type_str) -1 ); + } + + if (!use_usb_info && protocol == 6) { + /* Generic SPC-2 device */ + scsi_vendor = sysfs_get_device_attr(scsi_dev, "vendor"); + if (!scsi_vendor) { + info("%s: cannot get vendor attribute", scsi_dev->name); + return -1; + } + set_str(vendor_str, scsi_vendor->value, sizeof(vendor_str)-1); + + scsi_model = sysfs_get_device_attr(scsi_dev, "model"); + if (!scsi_model) { + info("%s: cannot get model attribute", scsi_dev->name); + return -1; + } + set_str(model_str, scsi_model->value, sizeof(model_str)-1); + + scsi_type = sysfs_get_device_attr(scsi_dev, "type"); + if (!scsi_type) { + info("%s: cannot get type attribute", scsi_dev->name); + return -1; + } + set_scsi_type(type_str, scsi_type->value, sizeof(type_str)-1); + + scsi_rev = sysfs_get_device_attr(scsi_dev, "rev"); + if (!scsi_rev) { + info("%s: cannot get type attribute", scsi_dev->name); + return -1; + } + set_str(revision_str, scsi_rev->value, sizeof(revision_str)-1); + + } + + /* Fallback to USB vendor & device */ + if (vendor_str[0] == '\0') { + usb_vendor = sysfs_get_device_attr(usb_dev, "manufacturer"); + if (!usb_vendor) { + dbg("No USB vendor string found, using idVendor"); + usb_vendor = sysfs_get_device_attr(usb_dev, "idVendor"); + } + set_str(vendor_str,usb_vendor->value, sizeof(vendor_str) - 1); + } + + if (model_str[0] == '\0') { + usb_model = sysfs_get_device_attr(usb_dev, "product"); + if (!usb_model) { + dbg("No USB model string found, using idProduct"); + usb_model = sysfs_get_device_attr(usb_dev, "idProduct"); + } + set_str(model_str, usb_model->value, sizeof(model_str) - 1); + } + + if (revision_str[0] == '\0') { + usb_rev = sysfs_get_device_attr(usb_dev, "bcdDevice"); + if (usb_rev) { + set_str(revision_str, usb_rev->value, + sizeof(revision_str) - 1); + } + } + + if (serial_str[0] == '\0') { + usb_serial = sysfs_get_device_attr(usb_dev, "serial"); + if (usb_serial) { + set_str(serial_str, usb_serial->value, + sizeof(serial_str) - 1); + } + } + return 0; +} + +int main(int argc, char **argv) +{ + int retval; + char *devpath; + char target_path[MAX_NAME_LEN]; + int option; + + dbg("argc is %d", argc); + if (sysfs_get_mnt_path(sysfs_mnt_path, MAX_NAME_LEN)) { + info("sysfs_get_mnt_path failed: %s", + strerror(errno)); + exit(1); + } + + while ((option = getopt(argc, argv, "ux")) != -1 ) { + if (optarg) + dbg("option '%c' arg '%s'", option, optarg); + else + dbg("option '%c'", option); + + switch (option) { + case 'u': + use_usb_info=1; + break; + case 'x': + export=1; + break; + default: + info("Unknown or bad option '%c' (0x%x)", option, option); + retval = -1; + break; + } + } + + devpath = getenv("DEVPATH"); + if (devpath) { + strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); + strncat(target_path, devpath, MAX_NAME_LEN); + } else { + if (optind == argc) { + fprintf(stderr, "No device specified\n"); + exit(1); + } + devpath = argv[optind]; + strncpy(target_path, devpath, MAX_NAME_LEN); + } + + retval = usb_id(target_path); + + if (export) { + printf("ID_VENDOR=%s\n", vendor_str); + printf("ID_MODEL=%s\n", model_str); + printf("ID_REVISION=%s\n", revision_str); + if (serial_str[0] == '\0') { + printf("ID_SERIAL=%s_%s\n", + vendor_str, model_str); + } else { + printf("ID_SERIAL=%s_%s_%s\n", + vendor_str, model_str, serial_str); + } + printf("ID_TYPE=%s\n", type_str); + } else { + if (serial_str[0] == '\0') { + printf("%s_%s\n", + vendor_str, model_str); + } else { + printf("%s_%s_%s\n", + vendor_str, model_str, serial_str); + } + } + exit(retval); +} + + + diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index b5a0dcdaa1..c5b429d98d 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -1,6 +1,12 @@ #/bin/sh -EXTRAS="extras/chassis_id extras/scsi_id extras/ata_id extras/volume_id extras/run_directory" +EXTRAS="\ + extras/chassis_id \ + extras/scsi_id \ + extras/ata_id \ + extras/volume_id \ + extras/usb_id \ + extras/run_directory" [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build echo KERNEL_DIR: "$KERNEL_DIR" From a0e5382d66567cc91c1a1f571e9fb5288106e876 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 4 Jul 2005 19:44:25 +0200 Subject: [PATCH 1355/4284] move rule matches to function Signed-off-by: Kay Sievers --- udev_rules.c | 186 ++++++++++++--------------------------------- udev_rules.h | 2 +- udev_rules_parse.c | 6 +- udevrulescompile.c | 2 +- 4 files changed, 53 insertions(+), 143 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index cd60c6d1ff..117ffdc2d0 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -599,70 +599,44 @@ found: } } +static int match_key(const char *key, const char *key_val, enum key_operation key_op, const char *val) +{ + int match; + + if (key_op == KEY_OP_UNSET) + return 0; + + dbg("check for %s '%s' <-> '%s'", key, key_val, val); + match = (strcmp_pattern(key_val, val) == 0); + if (match && (key_op != KEY_OP_NOMATCH)) { + dbg("%s key is matching (matching value)", key); + return 0; + } + if (!match && (key_op == KEY_OP_NOMATCH)) { + dbg("%s key is matching, (non matching value)", key); + return 0; + } + + dbg("%s key is not matching", key); + return -1; +} + static int match_rule(struct udevice *udev, struct udev_rule *rule, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { struct sysfs_device *parent_device = sysfs_device; - if (rule->action_operation != KEY_OP_UNSET) { - dbg("check for " KEY_ACTION " rule->action='%s' udev->action='%s'", - rule->action, udev->action); - if (strcmp_pattern(rule->action, udev->action) != 0) { - dbg(KEY_ACTION " is not matching"); - if (rule->action_operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg(KEY_ACTION " matches"); - if (rule->action_operation == KEY_OP_NOMATCH) - goto exit; - } - dbg(KEY_ACTION " key is true"); - } + if (match_key(KEY_ACTION, rule->action, rule->action_operation, udev->action)) + goto exit; - if (rule->kernel_operation != KEY_OP_UNSET) { - dbg("check for " KEY_KERNEL " rule->kernel='%s' udev_kernel_name='%s'", - rule->kernel, udev->kernel_name); - if (strcmp_pattern(rule->kernel, udev->kernel_name) != 0) { - dbg(KEY_KERNEL " is not matching"); - if (rule->kernel_operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg(KEY_KERNEL " matches"); - if (rule->kernel_operation == KEY_OP_NOMATCH) - goto exit; - } - dbg(KEY_KERNEL " key is true"); - } + if (match_key(KEY_KERNEL, rule->kernel_name, rule->kernel_operation, udev->kernel_name)) + goto exit; - if (rule->subsystem_operation != KEY_OP_UNSET) { - dbg("check for " KEY_SUBSYSTEM " rule->subsystem='%s' udev->subsystem='%s'", - rule->subsystem, udev->subsystem); - if (strcmp_pattern(rule->subsystem, udev->subsystem) != 0) { - dbg(KEY_SUBSYSTEM " is not matching"); - if (rule->subsystem_operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg(KEY_SUBSYSTEM " matches"); - if (rule->subsystem_operation == KEY_OP_NOMATCH) - goto exit; - } - dbg(KEY_SUBSYSTEM " key is true"); - } + if (match_key(KEY_SUBSYSTEM, rule->subsystem, rule->subsystem_operation, udev->subsystem)) + goto exit; - if (rule->devpath_operation != KEY_OP_UNSET) { - dbg("check for " KEY_DEVPATH " rule->devpath='%s' udev->devpath='%s'", - rule->devpath, udev->devpath); - if (strcmp_pattern(rule->devpath, udev->devpath) != 0) { - dbg(KEY_DEVPATH " is not matching"); - if (rule->devpath_operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg(KEY_DEVPATH " matches"); - if (rule->devpath_operation == KEY_OP_NOMATCH) - goto exit; - } - dbg(KEY_DEVPATH " key is true"); - } + if (match_key(KEY_DEVPATH, rule->devpath, rule->devpath_operation, udev->devpath)) + goto exit; if (rule->modalias_operation != KEY_OP_UNSET) { char value[NAME_SIZE]; @@ -671,18 +645,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg(KEY_MODALIAS " value not found"); goto exit; } - dbg("check for " KEY_MODALIAS " rule->modalias='%s' modalias='%s'", - rule->modalias, value); - if (strcmp_pattern(rule->modalias, value) != 0) { - dbg(KEY_MODALIAS " is not matching"); - if (rule->modalias_operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg(KEY_MODALIAS " matches"); - if (rule->modalias_operation == KEY_OP_NOMATCH) - goto exit; - } - dbg(KEY_MODALIAS " key is true"); + if (match_key(KEY_MODALIAS, rule->modalias, rule->modalias_operation, value)) + goto exit; } if (rule->env_pair_count) { @@ -699,17 +663,11 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg(KEY_ENV "{'%s'} is not found", pair->name); goto exit; } - if (strcmp_pattern(pair->value, value) != 0) { - dbg(KEY_ENV "{'%s'} is not matching", pair->name); - if (pair->operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg(KEY_ENV "{'%s'} matches", pair->name); - if (pair->operation == KEY_OP_NOMATCH) - goto exit; - } + dbg("check %i " KEY_ENV " keys", rule->env_pair_count); + if (match_key(pair->name, pair->value, pair->operation, value)) + goto exit; } - dbg(KEY_ENV " key is true"); + dbg("all %i " KEY_ENV " keys matched", rule->env_pair_count); } /* walk up the chain of physical devices and find a match */ @@ -720,18 +678,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto exit; } - dbg("check for " KEY_DRIVER " rule->driver='%s' sysfs_device->driver_name='%s'", - rule->driver, parent_device->driver_name); - if (strcmp_pattern(rule->driver, parent_device->driver_name) != 0) { - dbg(KEY_DRIVER " is not matching"); - if (rule->driver_operation != KEY_OP_NOMATCH) - goto try_parent; - } else { - dbg(KEY_DRIVER " matches"); - if (rule->driver_operation == KEY_OP_NOMATCH) - goto try_parent; - } - dbg(KEY_DRIVER " key is true"); + if (match_key(KEY_BUS, rule->driver, rule->driver_operation, parent_device->driver_name)) + goto try_parent; } /* check for matching bus value */ @@ -740,18 +688,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto exit; } - dbg("check for " KEY_BUS " rule->bus='%s' sysfs_device->bus='%s'", - rule->bus, parent_device->bus); - if (strcmp_pattern(rule->bus, parent_device->bus) != 0) { - dbg(KEY_BUS " is not matching"); - if (rule->bus_operation != KEY_OP_NOMATCH) - goto try_parent; - } else { - dbg(KEY_BUS " matches"); - if (rule->bus_operation == KEY_OP_NOMATCH) - goto try_parent; - } - dbg(KEY_BUS " key is true"); + if (match_key(KEY_BUS, rule->bus, rule->bus_operation, parent_device->bus)) + goto try_parent; } /* check for matching bus id */ @@ -760,17 +698,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto exit; } - dbg("check " KEY_ID); - if (strcmp_pattern(rule->id, parent_device->bus_id) != 0) { - dbg(KEY_ID " is not matching"); - if (rule->id_operation != KEY_OP_NOMATCH) - goto try_parent; - } else { - dbg(KEY_ID " matches"); - if (rule->id_operation == KEY_OP_NOMATCH) - goto try_parent; - } - dbg(KEY_ID " key is true"); + if (match_key(KEY_ID, rule->id, rule->id_operation, parent_device->bus_id)) + goto try_parent; } /* check for matching sysfs pairs */ @@ -796,18 +725,11 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("removed %zi trailing whitespace chars from '%s'", strlen(value)-len, value); } - dbg("compare attribute '%s' value '%s' with '%s'", pair->name, value, pair->value); - if (strcmp_pattern(pair->value, value) != 0) { - dbg(KEY_SYSFS "{'%s'} is not matching", pair->name); - if (pair->operation != KEY_OP_NOMATCH) - goto try_parent; - } else { - dbg(KEY_SYSFS "{'%s'} matches", pair->name); - if (pair->operation == KEY_OP_NOMATCH) - goto try_parent; - } + dbg("check %i " KEY_SYSFS " keys", rule->sysfs_pair_count); + if (match_key(pair->name, pair->value, pair->operation, value)) + goto try_parent; } - dbg(KEY_SYSFS " keys are true"); + dbg("all %i " KEY_SYSFS " keys matched", rule->sysfs_pair_count); } /* found matching physical device */ @@ -871,20 +793,8 @@ try_parent: } /* check for matching result of external program */ - if (rule->result_operation != KEY_OP_UNSET) { - dbg("check for " KEY_RESULT " rule->result='%s', udev->program_result='%s'", - rule->result, udev->program_result); - if (strcmp_pattern(rule->result, udev->program_result) != 0) { - dbg(KEY_RESULT " is not matching"); - if (rule->result_operation != KEY_OP_NOMATCH) - goto exit; - } else { - dbg(KEY_RESULT " matches"); - if (rule->result_operation == KEY_OP_NOMATCH) - goto exit; - } - dbg(KEY_RESULT " key is true"); - } + if (match_key(KEY_RESULT, rule->result, rule->result_operation, udev->program_result)) + goto exit; /* rule matches */ return 0; diff --git a/udev_rules.h b/udev_rules.h index bad8406cf4..14e40abc2c 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -77,7 +77,7 @@ struct key_pair { struct udev_rule { struct list_head node; - char kernel[NAME_SIZE]; + char kernel_name[NAME_SIZE]; enum key_operation kernel_operation; char subsystem[NAME_SIZE]; enum key_operation subsystem_operation; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 929a5e6f4c..4bc00dda5a 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -87,12 +87,12 @@ static int add_rule_to_list(struct udev_rule *rule) dbg("name='%s', symlink='%s', bus='%s', id='%s', " "sysfs_file[0]='%s', sysfs_value[0]='%s', " - "kernel='%s', program='%s', result='%s', " + "kernel_name='%s', program='%s', result='%s', " "owner='%s', group='%s', mode=%#o, " "all_partions=%u, ignore_remove=%u, ignore_device=%u, last_rule=%u", rule->name, rule->symlink, rule->bus, rule->id, rule->sysfs_pair[0].name, rule->sysfs_pair[0].value, - rule->kernel, rule->program, rule->result, rule->owner, rule->group, rule->mode, + rule->kernel_name, rule->program, rule->result, rule->owner, rule->group, rule->mode, rule->partitions, rule->ignore_remove, rule->ignore_device, rule->last_rule); return 0; @@ -285,7 +285,7 @@ static int rules_parse(const char *filename) break; if (strcasecmp(key, KEY_KERNEL) == 0) { - strlcpy(rule.kernel, value, sizeof(rule.kernel)); + strlcpy(rule.kernel_name, value, sizeof(rule.kernel_name)); rule.kernel_operation = operation; valid = 1; continue; diff --git a/udevrulescompile.c b/udevrulescompile.c index ff9dd79fd4..9162a16327 100644 --- a/udevrulescompile.c +++ b/udevrulescompile.c @@ -108,7 +108,7 @@ int main(int argc, char *argv[], char *envp[]) sprintf(rule->group, "%li", gid); } - dbg("kernel='%s' name='%s'", rule->kernel, rule->name); + dbg("kernel_name='%s' name='%s'", rule->kernel_name, rule->name); fwrite(rule, sizeof(struct udev_rule), 1, f); } From 6369839195d7572151d986ddc2050162e6879585 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 4 Jul 2005 20:42:04 +0200 Subject: [PATCH 1356/4284] replace useless defines by inline text Signed-off-by: Kay Sievers --- udev_rules.c | 50 ++++++++++++++--------------- udev_rules.h | 27 ---------------- udev_rules_parse.c | 78 +++++++++++++++++++++++----------------------- 3 files changed, 63 insertions(+), 92 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 117ffdc2d0..48e22ad3e8 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -626,33 +626,32 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, { struct sysfs_device *parent_device = sysfs_device; - if (match_key(KEY_ACTION, rule->action, rule->action_operation, udev->action)) + if (match_key("ACTION", rule->action, rule->action_operation, udev->action)) goto exit; - if (match_key(KEY_KERNEL, rule->kernel_name, rule->kernel_operation, udev->kernel_name)) + if (match_key("KERNEL", rule->kernel_name, rule->kernel_operation, udev->kernel_name)) goto exit; - if (match_key(KEY_SUBSYSTEM, rule->subsystem, rule->subsystem_operation, udev->subsystem)) + if (match_key("SUBSYSTEM", rule->subsystem, rule->subsystem_operation, udev->subsystem)) goto exit; - if (match_key(KEY_DEVPATH, rule->devpath, rule->devpath_operation, udev->devpath)) + if (match_key("DEVPATH", rule->devpath, rule->devpath_operation, udev->devpath)) goto exit; if (rule->modalias_operation != KEY_OP_UNSET) { char value[NAME_SIZE]; if (find_sysfs_attribute(NULL, sysfs_device, "modalias", value, sizeof(value)) != 0) { - dbg(KEY_MODALIAS " value not found"); + dbg("MODALIAS value not found"); goto exit; } - if (match_key(KEY_MODALIAS, rule->modalias, rule->modalias_operation, value)) + if (match_key("MODALIAS", rule->modalias, rule->modalias_operation, value)) goto exit; } if (rule->env_pair_count) { int i; - dbg("check for " KEY_ENV " pairs"); for (i = 0; i < rule->env_pair_count; i++) { struct key_pair *pair; const char *value; @@ -660,14 +659,14 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, pair = &rule->env_pair[i]; value = getenv(pair->name); if (!value) { - dbg(KEY_ENV "{'%s'} is not found", pair->name); + dbg("ENV{'%s'} is not found", pair->name); goto exit; } - dbg("check %i " KEY_ENV " keys", rule->env_pair_count); + dbg("check %i ENV keys", rule->env_pair_count); if (match_key(pair->name, pair->value, pair->operation, value)) goto exit; } - dbg("all %i " KEY_ENV " keys matched", rule->env_pair_count); + dbg("all %i ENV keys matched", rule->env_pair_count); } /* walk up the chain of physical devices and find a match */ @@ -678,7 +677,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto exit; } - if (match_key(KEY_BUS, rule->driver, rule->driver_operation, parent_device->driver_name)) + if (match_key("DRIVER", rule->driver, rule->driver_operation, parent_device->driver_name)) goto try_parent; } @@ -688,7 +687,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto exit; } - if (match_key(KEY_BUS, rule->bus, rule->bus_operation, parent_device->bus)) + if (match_key("BUS", rule->bus, rule->bus_operation, parent_device->bus)) goto try_parent; } @@ -698,7 +697,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("device has no sysfs_device"); goto exit; } - if (match_key(KEY_ID, rule->id, rule->id_operation, parent_device->bus_id)) + if (match_key("ID", rule->id, rule->id_operation, parent_device->bus_id)) goto try_parent; } @@ -706,7 +705,6 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, if (rule->sysfs_pair_count) { int i; - dbg("check " KEY_SYSFS " pairs"); for (i = 0; i < rule->sysfs_pair_count; i++) { struct key_pair *pair; char value[VALUE_SIZE]; @@ -725,11 +723,11 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("removed %zi trailing whitespace chars from '%s'", strlen(value)-len, value); } - dbg("check %i " KEY_SYSFS " keys", rule->sysfs_pair_count); + dbg("check %i SYSFS keys", rule->sysfs_pair_count); if (match_key(pair->name, pair->value, pair->operation, value)) goto try_parent; } - dbg("all %i " KEY_SYSFS " keys matched", rule->sysfs_pair_count); + dbg("all %i SYSFS keys matched", rule->sysfs_pair_count); } /* found matching physical device */ @@ -750,7 +748,7 @@ try_parent: strlcpy(import, rule->import, sizeof(import)); apply_format(udev, import, sizeof(import), class_dev, sysfs_device); - dbg("check for " KEY_IMPORT " import='%s'", import); + dbg("check for IMPORT import='%s'", import); if (rule->import_exec) { dbg("run executable file import='%s'", import); rc = import_program_into_env(udev, import); @@ -759,12 +757,12 @@ try_parent: rc = import_file_into_env(udev, import); } if (rc) { - dbg(KEY_IMPORT " failed"); + dbg("IMPORT failed"); if (rule->import_operation != KEY_OP_NOMATCH) goto exit; } else - dbg(KEY_IMPORT " '%s' imported", rule->import); - dbg(KEY_IMPORT " key is true"); + dbg("IMPORT '%s' imported", rule->import); + dbg("IMPORT key is true"); } /* execute external program */ @@ -774,26 +772,26 @@ try_parent: strlcpy(program, rule->program, sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - dbg("check for " KEY_PROGRAM " program='%s", program); + dbg("check for PROGRAM program='%s", program); if (execute_program(program, udev->subsystem, result, sizeof(result), NULL) != 0) { - dbg(KEY_PROGRAM " is not matching"); + dbg("PROGRAM is not matching"); if (rule->program_operation != KEY_OP_NOMATCH) goto exit; } else { - dbg(KEY_PROGRAM " matches"); + dbg("PROGRAM matches"); remove_trailing_char(result, '\n'); replace_untrusted_chars(result); dbg("result is '%s'", result); strlcpy(udev->program_result, result, sizeof(udev->program_result)); - dbg(KEY_PROGRAM " returned successful"); + dbg("PROGRAM returned successful"); if (rule->program_operation == KEY_OP_NOMATCH) goto exit; } - dbg(KEY_PROGRAM " key is true"); + dbg("PROGRAM key is true"); } /* check for matching result of external program */ - if (match_key(KEY_RESULT, rule->result, rule->result_operation, udev->program_result)) + if (match_key("RESULT", rule->result, rule->result_operation, udev->program_result)) goto exit; /* rule matches */ diff --git a/udev_rules.h b/udev_rules.h index 14e40abc2c..fb77509cce 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -27,33 +27,6 @@ #include "udev.h" #include "list.h" - -#define KEY_KERNEL "KERNEL" -#define KEY_SUBSYSTEM "SUBSYSTEM" -#define KEY_ACTION "ACTION" -#define KEY_DEVPATH "DEVPATH" -#define KEY_BUS "BUS" -#define KEY_ID "ID" -#define KEY_PROGRAM "PROGRAM" -#define KEY_RESULT "RESULT" -#define KEY_DRIVER "DRIVER" -#define KEY_SYSFS "SYSFS" -#define KEY_ENV "ENV" -#define KEY_MODALIAS "MODALIAS" -#define KEY_IMPORT "IMPORT" -#define KEY_NAME "NAME" -#define KEY_SYMLINK "SYMLINK" -#define KEY_OWNER "OWNER" -#define KEY_GROUP "GROUP" -#define KEY_MODE "MODE" -#define KEY_RUN "RUN" -#define KEY_OPTIONS "OPTIONS" - -#define OPTION_LAST_RULE "last_rule" -#define OPTION_IGNORE_DEVICE "ignore_device" -#define OPTION_IGNORE_REMOVE "ignore_remove" -#define OPTION_PARTITIONS "all_partitions" - #define KEY_SYSFS_PAIRS_MAX 5 #define KEY_ENV_PAIRS_MAX 5 diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 4bc00dda5a..cf69783c2d 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -284,59 +284,59 @@ static int rules_parse(const char *filename) if (retval) break; - if (strcasecmp(key, KEY_KERNEL) == 0) { + if (strcasecmp(key, "KERNEL") == 0) { strlcpy(rule.kernel_name, value, sizeof(rule.kernel_name)); rule.kernel_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_SUBSYSTEM) == 0) { + if (strcasecmp(key, "SUBSYSTEM") == 0) { strlcpy(rule.subsystem, value, sizeof(rule.subsystem)); rule.subsystem_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_ACTION) == 0) { + if (strcasecmp(key, "ACTION") == 0) { strlcpy(rule.action, value, sizeof(rule.action)); rule.action_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_DEVPATH) == 0) { + if (strcasecmp(key, "DEVPATH") == 0) { strlcpy(rule.devpath, value, sizeof(rule.devpath)); rule.devpath_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_BUS) == 0) { + if (strcasecmp(key, "BUS") == 0) { strlcpy(rule.bus, value, sizeof(rule.bus)); rule.bus_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_ID) == 0) { + if (strcasecmp(key, "ID") == 0) { strlcpy(rule.id, value, sizeof(rule.id)); rule.id_operation = operation; valid = 1; continue; } - if (strncasecmp(key, KEY_SYSFS, sizeof(KEY_SYSFS)-1) == 0) { + if (strncasecmp(key, "SYSFS", sizeof("SYSFS")-1) == 0) { struct key_pair *pair; if (rule.sysfs_pair_count >= KEY_SYSFS_PAIRS_MAX) { - err("skip rule, to many " KEY_SYSFS " keys in a single rule"); + err("skip rule, to many SYSFS keys in a single rule"); goto error; } pair = &rule.sysfs_pair[rule.sysfs_pair_count]; - attr = get_key_attribute(key + sizeof(KEY_SYSFS)-1); + attr = get_key_attribute(key + sizeof("SYSFS")-1); if (attr == NULL) { - err("error parsing " KEY_SYSFS " attribute"); + err("error parsing SYSFS attribute"); goto error; } strlcpy(pair->name, attr, sizeof(pair->name)); @@ -347,17 +347,17 @@ static int rules_parse(const char *filename) continue; } - if (strncasecmp(key, KEY_ENV, sizeof(KEY_ENV)-1) == 0) { + if (strncasecmp(key, "ENV", sizeof("ENV")-1) == 0) { struct key_pair *pair; if (rule.env_pair_count >= KEY_ENV_PAIRS_MAX) { - err("skip rule, to many " KEY_ENV " keys in a single rule"); + err("skip rule, to many ENV keys in a single rule"); goto error; } pair = &rule.env_pair[rule.env_pair_count]; - attr = get_key_attribute(key + sizeof(KEY_ENV)-1); + attr = get_key_attribute(key + sizeof("ENV")-1); if (attr == NULL) { - err("error parsing " KEY_ENV " attribute"); + err("error parsing ENV attribute"); continue; } strlcpy(pair->name, attr, sizeof(pair->name)); @@ -368,20 +368,20 @@ static int rules_parse(const char *filename) continue; } - if (strcasecmp(key, KEY_MODALIAS) == 0) { + if (strcasecmp(key, "MODALIAS") == 0) { strlcpy(rule.modalias, value, sizeof(rule.modalias)); rule.modalias_operation = operation; valid = 1; continue; } - if (strncasecmp(key, KEY_IMPORT, sizeof(KEY_IMPORT)-1) == 0) { - attr = get_key_attribute(key + sizeof(KEY_IMPORT)-1); + if (strncasecmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) { + attr = get_key_attribute(key + sizeof("IMPORT")-1); if (attr && strstr(attr, "program")) { - dbg(KEY_IMPORT" will be executed"); + dbg("IMPORT will be executed"); rule.import_exec = 1; } else if (attr && strstr(attr, "file")) { - dbg(KEY_IMPORT" will be included as file"); + dbg("IMPORT will be included as file"); } else { /* figure it out if it is executable */ char file[PATH_SIZE]; @@ -392,9 +392,9 @@ static int rules_parse(const char *filename) pos = strchr(file, ' '); if (pos) pos[0] = '\0'; - dbg(KEY_IMPORT" auto mode for '%s'", file); + dbg("IMPORT auto mode for '%s'", file); if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) { - dbg(KEY_IMPORT" is executable, will be executed"); + dbg("IMPORT is executable, will be executed"); rule.import_exec = 1; } } @@ -404,21 +404,21 @@ static int rules_parse(const char *filename) continue; } - if (strcasecmp(key, KEY_DRIVER) == 0) { + if (strcasecmp(key, "DRIVER") == 0) { strlcpy(rule.driver, value, sizeof(rule.driver)); rule.driver_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_RESULT) == 0) { + if (strcasecmp(key, "RESULT") == 0) { strlcpy(rule.result, value, sizeof(rule.result)); rule.result_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_PROGRAM) == 0) { + if (strcasecmp(key, "PROGRAM") == 0) { strlcpy(rule.program, value, sizeof(rule.program)); rule.program_operation = operation; program_given = 1; @@ -426,14 +426,14 @@ static int rules_parse(const char *filename) continue; } - if (strncasecmp(key, KEY_NAME, sizeof(KEY_NAME)-1) == 0) { - attr = get_key_attribute(key + sizeof(KEY_NAME)-1); + if (strncasecmp(key, "NAME", sizeof("NAME")-1) == 0) { + attr = get_key_attribute(key + sizeof("NAME")-1); if (attr != NULL) { - if (strstr(attr, OPTION_PARTITIONS) != NULL) { + if (strstr(attr, "all_partitions") != NULL) { dbg("creation of partition nodes requested"); rule.partitions = DEFAULT_PARTITIONS_COUNT; } - if (strstr(attr, OPTION_IGNORE_REMOVE) != NULL) { + if (strstr(attr, "ignore_remove") != NULL) { dbg("remove event should be ignored"); rule.ignore_remove = 1; } @@ -444,55 +444,55 @@ static int rules_parse(const char *filename) continue; } - if (strcasecmp(key, KEY_SYMLINK) == 0) { + if (strcasecmp(key, "SYMLINK") == 0) { strlcpy(rule.symlink, value, sizeof(rule.symlink)); rule.symlink_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_OWNER) == 0) { + if (strcasecmp(key, "OWNER") == 0) { strlcpy(rule.owner, value, sizeof(rule.owner)); rule.owner_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_GROUP) == 0) { + if (strcasecmp(key, "GROUP") == 0) { strlcpy(rule.group, value, sizeof(rule.group)); rule.group_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_MODE) == 0) { + if (strcasecmp(key, "MODE") == 0) { rule.mode = strtol(value, NULL, 8); rule.mode_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_RUN) == 0) { + if (strcasecmp(key, "RUN") == 0) { strlcpy(rule.run, value, sizeof(rule.run)); rule.run_operation = operation; valid = 1; continue; } - if (strcasecmp(key, KEY_OPTIONS) == 0) { - if (strstr(value, OPTION_LAST_RULE) != NULL) { + if (strcasecmp(key, "OPTIONS") == 0) { + if (strstr(value, "last_rule") != NULL) { dbg("last rule to be applied"); rule.last_rule = 1; } - if (strstr(value, OPTION_IGNORE_DEVICE) != NULL) { + if (strstr(value, "ignore_device") != NULL) { dbg("device should be ignored"); rule.ignore_device = 1; } - if (strstr(value, OPTION_IGNORE_REMOVE) != NULL) { + if (strstr(value, "ignore_remove") != NULL) { dbg("remove event should be ignored"); rule.ignore_remove = 1; } - if (strstr(value, OPTION_PARTITIONS) != NULL) { + if (strstr(value, "all_partitions") != NULL) { dbg("creation of partition nodes requested"); rule.partitions = DEFAULT_PARTITIONS_COUNT; } @@ -509,7 +509,7 @@ static int rules_parse(const char *filename) goto error; if ((rule.result[0] != '\0') && (program_given == 0)) { - info(KEY_RESULT " is only useful when " KEY_PROGRAM " is called in any rule before"); + info("RESULT is only useful when PROGRAM is called in any rule before"); goto error; } From 8bd41f36f793f7fc208ef6beb4b2b84e35a5e728 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 5 Jul 2005 15:24:41 +0200 Subject: [PATCH 1357/4284] pack parsed rules list This cuts down our 600 rules file to 98 kb instead of 1.9 Mb memory or file-size with precompiled rules. Signed-off-by: Kay Sievers --- udev.c | 13 +- udev_rules.c | 242 ++++++++-------- udev_rules.h | 111 ++++---- udev_rules_parse.c | 668 ++++++++++++++++++++++----------------------- udevrulescompile.c | 42 +-- udevstart.c | 6 +- udevtest.c | 5 +- 7 files changed, 524 insertions(+), 563 deletions(-) diff --git a/udev.c b/udev.c index 1c55ec14b8..7a0484472a 100644 --- a/udev.c +++ b/udev.c @@ -68,6 +68,7 @@ static void asmlinkage sig_handler(int signum) int main(int argc, char *argv[], char *envp[]) { struct udevice udev; + struct udev_rules rules; char path[PATH_SIZE]; const char *error; const char *action; @@ -118,7 +119,7 @@ int main(int argc, char *argv[], char *envp[]) } udev_init_device(&udev, devpath, subsystem, action); - udev_rules_init(); + udev_rules_init(&rules, 0); if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { /* handle device node */ @@ -143,7 +144,7 @@ int main(int argc, char *argv[], char *envp[]) if (udev.type == DEV_NET || udev.devt) { /* name device */ - udev_rules_get_name(&udev, class_dev); + udev_rules_get_name(&rules, &udev, class_dev); if (udev.ignore_device) { info("device event will be ignored"); goto cleanup; @@ -157,7 +158,7 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_add_device(&udev, class_dev); } else { dbg("no dev-file found"); - udev_rules_get_run(&udev, NULL); + udev_rules_get_run(&rules, &udev, NULL); if (udev.ignore_device) { info("device event will be ignored"); goto cleanup; @@ -166,7 +167,7 @@ int main(int argc, char *argv[], char *envp[]) sysfs_close_class_device(class_dev); } else if (strcmp(action, "remove") == 0) { dbg("node remove"); - udev_rules_get_run(&udev, NULL); + udev_rules_get_run(&rules, &udev, NULL); if (udev.ignore_device) { dbg("device event will be ignored"); goto cleanup; @@ -193,7 +194,7 @@ int main(int argc, char *argv[], char *envp[]) } dbg("devices device opened '%s'", path); wait_for_devices_device(devices_dev, &error); - udev_rules_get_run(&udev, devices_dev); + udev_rules_get_run(&rules, &udev, devices_dev); sysfs_close_device(devices_dev); if (udev.ignore_device) { info("device event will be ignored"); @@ -201,7 +202,7 @@ int main(int argc, char *argv[], char *envp[]) } } else { dbg("default handling"); - udev_rules_get_run(&udev, NULL); + udev_rules_get_run(&rules, &udev, NULL); if (udev.ignore_device) { info("device event will be ignored"); goto cleanup; diff --git a/udev_rules.c b/udev_rules.c index 48e22ad3e8..48397ac1c7 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -599,25 +599,38 @@ found: } } -static int match_key(const char *key, const char *key_val, enum key_operation key_op, const char *val) +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) { int match; + char *key_value; - if (key_op == KEY_OP_UNSET) + if (key->operation == KEY_OP_UNSET) return 0; - dbg("check for %s '%s' <-> '%s'", key, key_val, val); - match = (strcmp_pattern(key_val, val) == 0); - if (match && (key_op != KEY_OP_NOMATCH)) { - dbg("%s key is matching (matching value)", key); + key_value = rule->buf + key->val_off; + + dbg("check for %s '%s' <-> '%s'", key_name, key_value, val); + match = (strcmp_pattern(key_value, val) == 0); + if (match && (key->operation != KEY_OP_NOMATCH)) { + dbg("%s key is matching (matching value)", key_name); return 0; } - if (!match && (key_op == KEY_OP_NOMATCH)) { - dbg("%s key is matching, (non matching value)", key); + if (!match && (key->operation == KEY_OP_NOMATCH)) { + dbg("%s key is matching, (non matching value)", key_name); return 0; } - dbg("%s key is not matching", key); + dbg("%s key is not matching", key_name); return -1; } @@ -626,108 +639,108 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, { struct sysfs_device *parent_device = sysfs_device; - if (match_key("ACTION", rule->action, rule->action_operation, udev->action)) + if (match_key("ACTION", rule, &rule->action, udev->action)) goto exit; - if (match_key("KERNEL", rule->kernel_name, rule->kernel_operation, udev->kernel_name)) + if (match_key("KERNEL", rule, &rule->kernel_name, udev->kernel_name)) goto exit; - if (match_key("SUBSYSTEM", rule->subsystem, rule->subsystem_operation, udev->subsystem)) + if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->subsystem)) goto exit; - if (match_key("DEVPATH", rule->devpath, rule->devpath_operation, udev->devpath)) + if (match_key("DEVPATH", rule, &rule->devpath, udev->devpath)) goto exit; - if (rule->modalias_operation != KEY_OP_UNSET) { + if (rule->modalias.operation != KEY_OP_UNSET) { char value[NAME_SIZE]; if (find_sysfs_attribute(NULL, sysfs_device, "modalias", value, sizeof(value)) != 0) { dbg("MODALIAS value not found"); goto exit; } - if (match_key("MODALIAS", rule->modalias, rule->modalias_operation, value)) + if (match_key("MODALIAS", rule, &rule->modalias, value)) goto exit; } - if (rule->env_pair_count) { + if (rule->env.count) { int i; - for (i = 0; i < rule->env_pair_count; i++) { - struct key_pair *pair; - const char *value; + dbg("check %i ENV keys", rule->env.count); + for (i = 0; i < rule->env.count; i++) { + struct key_pair *pair = &rule->env.keys[i]; + const char *key_name = key_pair_name(rule, pair); + const char *value = getenv(key_name); - pair = &rule->env_pair[i]; - value = getenv(pair->name); if (!value) { - dbg("ENV{'%s'} is not found", pair->name); + dbg("ENV{'%s'} is not found", key_name); goto exit; } - dbg("check %i ENV keys", rule->env_pair_count); - if (match_key(pair->name, pair->value, pair->operation, value)) + if (match_key("ENV", rule, &pair->key, value)) goto exit; } - dbg("all %i ENV keys matched", rule->env_pair_count); + dbg("all %i ENV keys matched", rule->env.count); } /* walk up the chain of physical devices and find a match */ while (1) { /* check for matching driver */ - if (rule->driver_operation != KEY_OP_UNSET) { + if (rule->driver.operation != KEY_OP_UNSET) { if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; } - if (match_key("DRIVER", rule->driver, rule->driver_operation, parent_device->driver_name)) + if (match_key("DRIVER", rule, &rule->driver, parent_device->driver_name)) goto try_parent; } /* check for matching bus value */ - if (rule->bus_operation != KEY_OP_UNSET) { + if (rule->bus.operation != KEY_OP_UNSET) { if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; } - if (match_key("BUS", rule->bus, rule->bus_operation, parent_device->bus)) + if (match_key("BUS", rule, &rule->bus, parent_device->bus)) goto try_parent; } /* check for matching bus id */ - if (rule->id_operation != KEY_OP_UNSET) { + if (rule->id.operation != KEY_OP_UNSET) { if (parent_device == NULL) { dbg("device has no sysfs_device"); goto exit; } - if (match_key("ID", rule->id, rule->id_operation, parent_device->bus_id)) + if (match_key("ID", rule, &rule->id, parent_device->bus_id)) goto try_parent; } /* check for matching sysfs pairs */ - if (rule->sysfs_pair_count) { + if (rule->sysfs.count) { int i; - for (i = 0; i < rule->sysfs_pair_count; i++) { - struct key_pair *pair; + dbg("check %i SYSFS keys", rule->sysfs.count); + for (i = 0; i < rule->sysfs.count; i++) { + struct key_pair *pair = &rule->sysfs.keys[i]; + const char *key_name = key_pair_name(rule, pair); + const char *key_value = key_val(rule, &pair->key); char value[VALUE_SIZE]; size_t len; - pair = &rule->sysfs_pair[i]; - if (find_sysfs_attribute(class_dev, parent_device, pair->name, value, sizeof(value)) != 0) + if (find_sysfs_attribute(class_dev, parent_device, key_name, value, sizeof(value)) != 0) goto try_parent; /* strip trailing whitespace of value, if not asked to match for it */ - len = strlen(pair->value); - if (len && !isspace(pair->value[len-1])) { + len = strlen(key_value); + if (len && !isspace(key_value[len-1])) { len = strlen(value); while (len > 0 && isspace(value[len-1])) value[--len] = '\0'; dbg("removed %zi trailing whitespace chars from '%s'", strlen(value)-len, value); } - dbg("check %i SYSFS keys", rule->sysfs_pair_count); - if (match_key(pair->name, pair->value, pair->operation, value)) + if (match_key("SYSFS", rule, &pair->key, value)) goto try_parent; } - dbg("all %i SYSFS keys matched", rule->sysfs_pair_count); + dbg("all %i SYSFS keys matched", rule->sysfs.count); } /* found matching physical device */ @@ -742,11 +755,11 @@ try_parent: } /* import variables from file into environment */ - if (rule->import_operation != KEY_OP_UNSET) { + if (rule->import.operation != KEY_OP_UNSET) { char import[PATH_SIZE]; int rc = -1; - strlcpy(import, rule->import, sizeof(import)); + strlcpy(import, key_val(rule, &rule->import), sizeof(import)); apply_format(udev, import, sizeof(import), class_dev, sysfs_device); dbg("check for IMPORT import='%s'", import); if (rule->import_exec) { @@ -758,24 +771,24 @@ try_parent: } if (rc) { dbg("IMPORT failed"); - if (rule->import_operation != KEY_OP_NOMATCH) + if (rule->import.operation != KEY_OP_NOMATCH) goto exit; } else - dbg("IMPORT '%s' imported", rule->import); + dbg("IMPORT '%s' imported", key_val(rule, &rule->import)); dbg("IMPORT key is true"); } /* execute external program */ - if (rule->program_operation != KEY_OP_UNSET) { + if (rule->program.operation != KEY_OP_UNSET) { char program[PATH_SIZE]; char result[PATH_SIZE]; - strlcpy(program, rule->program, sizeof(program)); + strlcpy(program, key_val(rule, &rule->program), sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); dbg("check for PROGRAM program='%s", program); if (execute_program(program, udev->subsystem, result, sizeof(result), NULL) != 0) { dbg("PROGRAM is not matching"); - if (rule->program_operation != KEY_OP_NOMATCH) + if (rule->program.operation != KEY_OP_NOMATCH) goto exit; } else { dbg("PROGRAM matches"); @@ -784,14 +797,14 @@ try_parent: 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) + if (rule->program.operation == KEY_OP_NOMATCH) goto exit; } dbg("PROGRAM key is true"); } /* check for matching result of external program */ - if (match_key("RESULT", rule->result, rule->result_operation, udev->program_result)) + if (match_key("RESULT", rule, &rule->result, udev->program_result)) goto exit; /* rule matches */ @@ -801,7 +814,7 @@ exit: return -1; } -int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev) +int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct sysfs_class_device *class_dev) { struct sysfs_class_device *class_dev_parent; struct sysfs_device *sysfs_device = NULL; @@ -831,13 +844,13 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d dbg("udev->kernel_name='%s'", udev->kernel_name); /* look for a matching rule to apply */ - udev_rules_iter_init(); + udev_rules_iter_init(rules); while (1) { - rule = udev_rules_iter_next(); + rule = udev_rules_iter_next(rules); if (rule == NULL) break; - if (udev->name_set && rule->name_operation != KEY_OP_UNSET) { + if (udev->name_set && rule->name.operation != KEY_OP_UNSET) { dbg("node name already set, rule ignored"); continue; } @@ -846,8 +859,7 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { /* apply options */ if (rule->ignore_device) { - info("configured rule in '%s[%i]' applied, '%s' is ignored", - rule->config_file, rule->config_line, udev->kernel_name); + info("rule applied, '%s' is ignored", udev->kernel_name); udev->ignore_device = 1; return 0; } @@ -866,31 +878,31 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (rule->mode_operation == KEY_OP_ASSIGN_FINAL) udev->mode_final = 1; udev->mode = rule->mode; - dbg("applied mode=%#o to '%s'", udev->mode, udev->kernel_name); + dbg("applied mode=%#o to '%s'", rule->mode, udev->kernel_name); } - if (!udev->owner_final && rule->owner[0] != '\0') { - if (rule->owner_operation == KEY_OP_ASSIGN_FINAL) + 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, rule->owner, sizeof(udev->owner)); + strlcpy(udev->owner, key_val(rule, &rule->owner), sizeof(udev->owner)); apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); } - if (!udev->group_final && rule->group[0] != '\0') { - if (rule->group_operation == KEY_OP_ASSIGN_FINAL) + 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, rule->group, sizeof(udev->group)); - apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); + strlcpy(udev->group, key_val(rule, &rule->group), sizeof(udev->group)); + apply_format(udev, key_val(rule, &rule->group), sizeof(udev->group), class_dev, sysfs_device); dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); } /* collect symlinks */ - if (!udev->symlink_final && rule->symlink_operation != KEY_OP_UNSET) { + if (!udev->symlink_final && rule->symlink.operation != KEY_OP_UNSET) { char temp[PATH_SIZE]; char *pos, *next; - if (rule->symlink_operation == KEY_OP_ASSIGN_FINAL) + 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) { + if (rule->symlink.operation == KEY_OP_ASSIGN || rule->symlink.operation == KEY_OP_ASSIGN_FINAL) { struct name_entry *name_loop; struct name_entry *temp_loop; @@ -900,53 +912,42 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d free(name_loop); } } - if (rule->symlink[0] != '\0') { - info("configured rule in '%s[%i]' applied, added symlink '%s'", - rule->config_file, rule->config_line, rule->symlink); - strlcpy(temp, rule->symlink, sizeof(temp)); - apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); + strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); + apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); + info("rule applied, added symlink '%s'", temp); - /* add multiple symlinks separated by spaces */ - pos = temp; - next = strchr(temp, ' '); - while (next) { - next[0] = '\0'; - info("add symlink '%s'", pos); - name_list_add(&udev->symlink_list, pos, 0); - pos = &next[1]; - next = strchr(pos, ' '); - } + /* add multiple symlinks separated by spaces */ + pos = temp; + next = strchr(temp, ' '); + while (next) { + next[0] = '\0'; info("add symlink '%s'", pos); name_list_add(&udev->symlink_list, pos, 0); + pos = &next[1]; + next = strchr(pos, ' '); } + 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_UNSET) { + if (rule->name.operation != KEY_OP_UNSET) { udev->name_set = 1; - if (rule->name[0] == '\0') { - info("configured rule in '%s[%i]' applied, node handling for '%s' supressed", - rule->config_file, rule->config_line, udev->kernel_name); - } else { - strlcpy(udev->name, rule->name, sizeof(udev->name)); - apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - strlcpy(udev->config_file, rule->config_file, sizeof(udev->config_file)); - udev->config_line = rule->config_line; + strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name)); + apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); - info("configured rule in '%s:%i' applied, '%s' becomes '%s'", - rule->config_file, rule->config_line, udev->kernel_name, rule->name); - if (udev->type != DEV_NET) - 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); - } + info("rule applied, '%s' becomes '%s'", udev->kernel_name, udev->name); + if (udev->type != DEV_NET) + 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) { + if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { char program[PATH_SIZE]; - if (rule->run_operation == KEY_OP_ASSIGN_FINAL) + 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) { + if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) { struct name_entry *name_loop; struct name_entry *temp_loop; @@ -956,12 +957,10 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d free(name_loop); } } - if (rule->run[0] != '\0') { - strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); - } + strlcpy(program, key_val(rule, &rule->run), sizeof(program)); + apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); } if (rule->last_rule) { @@ -973,7 +972,7 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d if (udev->name[0] == '\0') { strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); - info("no rule found, use kernel name '%s'", udev->name); + info("no rule found, will use kernel name '%s'", udev->name); } if (udev->tmp_node[0] != '\0') { @@ -985,36 +984,35 @@ int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_d return 0; } -int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) +int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device) { struct udev_rule *rule; /* look for a matching rule to apply */ - udev_rules_iter_init(); + udev_rules_iter_init(rules); while (1) { - rule = udev_rules_iter_next(); + 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 != 0000 || rule->owner[0] != '\0' || rule->group[0] != '\0') { + 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, NULL, sysfs_device) == 0) { if (rule->ignore_device) { - info("configured rule in '%s[%i]' applied, '%s' is ignored", - rule->config_file, rule->config_line, udev->kernel_name); + info("rule applied, '%s' is ignored", udev->kernel_name); udev->ignore_device = 1; return 0; } - if (!udev->run_final && rule->run_operation != KEY_OP_UNSET) { + if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { char program[PATH_SIZE]; - if (rule->run_operation == KEY_OP_ASSIGN || rule->run_operation == KEY_OP_ASSIGN_FINAL) { + if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) { struct name_entry *name_loop; struct name_entry *temp_loop; @@ -1024,13 +1022,11 @@ int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device) free(name_loop); } } - if (rule->run[0] != '\0') { - strlcpy(program, rule->run, sizeof(program)); - apply_format(udev, program, sizeof(program), NULL, sysfs_device); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); - } - if (rule->run_operation == KEY_OP_ASSIGN_FINAL) + strlcpy(program, key_val(rule, &rule->run), sizeof(program)); + apply_format(udev, program, sizeof(program), NULL, sysfs_device); + dbg("add run '%s'", program); + name_list_add(&udev->run_list, program, 0); + if (rule->run.operation == KEY_OP_ASSIGN_FINAL) break; } diff --git a/udev_rules.h b/udev_rules.h index fb77509cce..4ecada1c03 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -27,9 +27,7 @@ #include "udev.h" #include "list.h" -#define KEY_SYSFS_PAIRS_MAX 5 -#define KEY_ENV_PAIRS_MAX 5 - +#define PAIRS_MAX 5 #define RULEFILE_SUFFIX ".rules" enum key_operation { @@ -41,72 +39,69 @@ enum key_operation { KEY_OP_ASSIGN_FINAL, }; -struct key_pair { - char name[NAME_SIZE]; - char value[VALUE_SIZE]; +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]; }; struct udev_rule { - struct list_head node; + struct key kernel_name; + struct key subsystem; + struct key action; + struct key devpath; + struct key bus; + struct key id; + struct key driver; + struct key program; + struct key result; + struct key modalias; + struct key import; + struct key_pairs sysfs; + struct key_pairs env; - char kernel_name[NAME_SIZE]; - enum key_operation kernel_operation; - char subsystem[NAME_SIZE]; - enum key_operation subsystem_operation; - char action[NAME_SIZE]; - enum key_operation action_operation; - char devpath[PATH_SIZE]; - enum key_operation devpath_operation; - char bus[NAME_SIZE]; - enum key_operation bus_operation; - char id[NAME_SIZE]; - enum key_operation id_operation; - char driver[NAME_SIZE]; - enum key_operation driver_operation; - char program[PATH_SIZE]; - enum key_operation program_operation; - char result[PATH_SIZE]; - enum key_operation result_operation; - struct key_pair sysfs_pair[KEY_SYSFS_PAIRS_MAX]; - int sysfs_pair_count; - struct key_pair env_pair[KEY_ENV_PAIRS_MAX]; - int env_pair_count; - char modalias[NAME_SIZE]; - enum key_operation modalias_operation; - char import[PATH_SIZE]; - enum key_operation import_operation; - int import_exec; - - char name[PATH_SIZE]; - enum key_operation name_operation; - char symlink[PATH_SIZE]; - enum key_operation symlink_operation; - char owner[USER_SIZE]; - enum key_operation owner_operation; - char group[USER_SIZE]; - enum key_operation group_operation; - mode_t mode; + struct key name; + struct key symlink; + struct key run; + struct key owner; + struct key group; enum key_operation mode_operation; - char run[PATH_SIZE]; - enum key_operation run_operation; + mode_t mode; - int last_rule; - int ignore_device; - int ignore_remove; - int partitions; + unsigned int partitions; + unsigned int last_rule:1, + ignore_device:1, + ignore_remove:1, + import_exec:1; - char config_file[PATH_SIZE]; - int config_line; + size_t bufsize; + char buf[]; }; -extern int udev_rules_init(void); -extern void udev_rules_close(void); +struct udev_rules { + char *buf; + size_t bufsize; + size_t current; + int mapped; + int resolve_names; +}; -extern int udev_rules_iter_init(void); -extern struct udev_rule *udev_rules_iter_next(void); +extern int udev_rules_init(struct udev_rules *rules, int resolve_names); +extern void udev_rules_close(struct udev_rules *rules); -extern int udev_rules_get_name(struct udevice *udev, struct sysfs_class_device *class_dev); -extern int udev_rules_get_run(struct udevice *udev, struct sysfs_device *sysfs_device); +extern void udev_rules_iter_init(struct udev_rules *rules); +extern struct udev_rule *udev_rules_iter_next(struct udev_rules *rules); + +extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct sysfs_class_device *class_dev); +extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device); #endif diff --git a/udev_rules_parse.c b/udev_rules_parse.c index cf69783c2d..2ec9348b01 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -37,67 +37,31 @@ #include "logging.h" #include "udev_rules.h" -/* rules parsed from .rules files*/ -static LIST_HEAD(rules_list); -static struct list_head *rules_list_current; -/* mapped compiled rules stored on disk */ -static struct udev_rule *rules_array = NULL; -static size_t rules_array_current; -static size_t rules_array_size = 0; - -static size_t rules_count = 0; - -int udev_rules_iter_init(void) +void udev_rules_iter_init(struct udev_rules *rules) { - rules_list_current = rules_list.next; - rules_array_current = 0; - - return 0; + dbg("bufsize=%zi", rules->bufsize); + rules->current = 0; } -struct udev_rule *udev_rules_iter_next(void) +struct udev_rule *udev_rules_iter_next(struct udev_rules *rules) { static struct udev_rule *rule; - if (rules_array) { - if (rules_array_current >= rules_count) - return NULL; - rule = &rules_array[rules_array_current]; - rules_array_current++; - } else { - dbg("head=%p current=%p next=%p", &rules_list, rules_list_current, rules_list_current->next); - if (rules_list_current == &rules_list) - return NULL; - rule = list_entry(rules_list_current, struct udev_rule, node); - rules_list_current = rules_list_current->next; - } + if (!rules) + return NULL; + + dbg("current=%zi", rules->current); + if (rules->current >= rules->bufsize) + return NULL; + + /* get next rule */ + rule = (struct udev_rule *) (rules->buf + rules->current); + rules->current += sizeof(struct udev_rule) + rule->bufsize; + return rule; } -static int add_rule_to_list(struct udev_rule *rule) -{ - struct udev_rule *tmp_rule; - - tmp_rule = malloc(sizeof(*tmp_rule)); - if (tmp_rule == NULL) - return -ENOMEM; - memcpy(tmp_rule, rule, sizeof(struct udev_rule)); - list_add_tail(&tmp_rule->node, &rules_list); - - dbg("name='%s', symlink='%s', bus='%s', id='%s', " - "sysfs_file[0]='%s', sysfs_value[0]='%s', " - "kernel_name='%s', program='%s', result='%s', " - "owner='%s', group='%s', mode=%#o, " - "all_partions=%u, ignore_remove=%u, ignore_device=%u, last_rule=%u", - rule->name, rule->symlink, rule->bus, rule->id, - rule->sysfs_pair[0].name, rule->sysfs_pair[0].value, - rule->kernel_name, rule->program, rule->result, rule->owner, rule->group, rule->mode, - rule->partitions, rule->ignore_remove, rule->ignore_device, rule->last_rule); - - return 0; -} - static int get_key(char **line, char **key, enum key_operation *operation, char **value) { char *linepos; @@ -210,21 +174,306 @@ static char *get_key_attribute(char *str) return NULL; } -static int rules_parse(const char *filename) +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 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) +{ + struct udev_rule *rule; + size_t rule_size; + int valid; + char *linepos; + char *attr; + int retval; + + /* get all the keys */ + rule = calloc(1, sizeof (struct udev_rule) + LINE_SIZE); + if (!rule) { + err("malloc failed"); + return -1; + } + linepos = line; + valid = 0; + + 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, "KERNEL") == 0) { + add_rule_key(rule, &rule->kernel_name, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "SUBSYSTEM") == 0) { + add_rule_key(rule, &rule->subsystem, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "ACTION") == 0) { + add_rule_key(rule, &rule->action, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "DEVPATH") == 0) { + add_rule_key(rule, &rule->devpath, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "BUS") == 0) { + add_rule_key(rule, &rule->bus, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "ID") == 0) { + add_rule_key(rule, &rule->id, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "SYSFS", sizeof("SYSFS")-1) == 0) { + attr = get_key_attribute(key + sizeof("SYSFS")-1); + if (attr == NULL) { + err("error parsing SYSFS attribute in '%s'", line); + continue; + } + add_rule_key_pair(rule, &rule->sysfs, operation, attr, value); + 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"); + continue; + } + add_rule_key_pair(rule, &rule->env, operation, attr, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "MODALIAS") == 0) { + add_rule_key(rule, &rule->modalias, operation, value); + valid = 1; + continue; + } + + if (strncasecmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) { + attr = get_key_attribute(key + sizeof("IMPORT")-1); + if (attr && strstr(attr, "program")) { + dbg("IMPORT will be executed"); + rule->import_exec = 1; + } else if (attr && strstr(attr, "file")) { + dbg("IMPORT will be included as file"); + } else { + /* figure it out if it is executable */ + char file[PATH_SIZE]; + char *pos; + struct stat stats; + + strlcpy(file, value, sizeof(file)); + pos = strchr(file, ' '); + if (pos) + pos[0] = '\0'; + dbg("IMPORT auto mode for '%s'", file); + if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) { + dbg("IMPORT is executable, will be executed"); + rule->import_exec = 1; + } + } + add_rule_key(rule, &rule->import, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "DRIVER") == 0) { + add_rule_key(rule, &rule->driver, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "RESULT") == 0) { + add_rule_key(rule, &rule->result, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "PROGRAM") == 0) { + add_rule_key(rule, &rule->program, 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; + } + } + add_rule_key(rule, &rule->name, operation, value); + continue; + } + + if (strcasecmp(key, "SYMLINK") == 0) { + add_rule_key(rule, &rule->symlink, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "OWNER") == 0) { + valid = 1; + if (rules->resolve_names) { + 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, "%li", 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) { + 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, "%li", gid); + add_rule_key(rule, &rule->owner, 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, "RUN") == 0) { + add_rule_key(rule, &rule->run, operation, value); + valid = 1; + continue; + } + + if (strcasecmp(key, "OPTIONS") == 0) { + 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; + } + 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'", key, line); + } + + /* skip line if not any valid key was found */ + if (!valid) { + err("invalid rule '%s'", line); + goto exit; + } + + /* grow buffer and add rule */ + rule_size = sizeof(struct udev_rule) + rule->bufsize; + rules->buf = realloc(rules->buf, rules->bufsize + rule_size); + if (!rules->buf) { + err("realloc failed"); + goto exit; + } + memcpy(rules->buf + rules->bufsize, rule, rule_size); + rules->bufsize += rule_size; +exit: + free(rule); + return 0; +} + +static int parse_file(struct udev_rules *rules, const char *filename) { char line[LINE_SIZE]; char *bufline; int lineno; - char *linepos; - char *attr; char *buf; size_t bufsize; size_t cur; size_t count; - int program_given = 0; - int valid; int retval = 0; - struct udev_rule rule; if (file_map(filename, &buf, &bufsize) != 0) { err("can't open '%s' as rules file", filename); @@ -268,295 +517,46 @@ static int rules_parse(const char *filename) line[j++] = bufline[i]; } line[j] = '\0'; + dbg("read '%s'", line); - - /* get all known keys */ - memset(&rule, 0x00, sizeof(struct udev_rule)); - linepos = line; - valid = 0; - - 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, "KERNEL") == 0) { - strlcpy(rule.kernel_name, value, sizeof(rule.kernel_name)); - rule.kernel_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "SUBSYSTEM") == 0) { - strlcpy(rule.subsystem, value, sizeof(rule.subsystem)); - rule.subsystem_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "ACTION") == 0) { - strlcpy(rule.action, value, sizeof(rule.action)); - rule.action_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "DEVPATH") == 0) { - strlcpy(rule.devpath, value, sizeof(rule.devpath)); - rule.devpath_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "BUS") == 0) { - strlcpy(rule.bus, value, sizeof(rule.bus)); - rule.bus_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "ID") == 0) { - strlcpy(rule.id, value, sizeof(rule.id)); - rule.id_operation = operation; - valid = 1; - continue; - } - - if (strncasecmp(key, "SYSFS", sizeof("SYSFS")-1) == 0) { - struct key_pair *pair; - - if (rule.sysfs_pair_count >= KEY_SYSFS_PAIRS_MAX) { - err("skip rule, to many SYSFS keys in a single rule"); - goto error; - } - pair = &rule.sysfs_pair[rule.sysfs_pair_count]; - attr = get_key_attribute(key + sizeof("SYSFS")-1); - if (attr == NULL) { - err("error parsing SYSFS attribute"); - goto error; - } - strlcpy(pair->name, attr, sizeof(pair->name)); - strlcpy(pair->value, value, sizeof(pair->value)); - pair->operation = operation; - rule.sysfs_pair_count++; - valid = 1; - continue; - } - - if (strncasecmp(key, "ENV", sizeof("ENV")-1) == 0) { - struct key_pair *pair; - - if (rule.env_pair_count >= KEY_ENV_PAIRS_MAX) { - err("skip rule, to many ENV keys in a single rule"); - goto error; - } - pair = &rule.env_pair[rule.env_pair_count]; - attr = get_key_attribute(key + sizeof("ENV")-1); - if (attr == NULL) { - err("error parsing ENV attribute"); - continue; - } - strlcpy(pair->name, attr, sizeof(pair->name)); - strlcpy(pair->value, value, sizeof(pair->value)); - pair->operation = operation; - rule.env_pair_count++; - valid = 1; - continue; - } - - if (strcasecmp(key, "MODALIAS") == 0) { - strlcpy(rule.modalias, value, sizeof(rule.modalias)); - rule.modalias_operation = operation; - valid = 1; - continue; - } - - if (strncasecmp(key, "IMPORT", sizeof("IMPORT")-1) == 0) { - attr = get_key_attribute(key + sizeof("IMPORT")-1); - if (attr && strstr(attr, "program")) { - dbg("IMPORT will be executed"); - rule.import_exec = 1; - } else if (attr && strstr(attr, "file")) { - dbg("IMPORT will be included as file"); - } else { - /* figure it out if it is executable */ - char file[PATH_SIZE]; - char *pos; - struct stat stats; - - strlcpy(file, value, sizeof(file)); - pos = strchr(file, ' '); - if (pos) - pos[0] = '\0'; - dbg("IMPORT auto mode for '%s'", file); - if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) { - dbg("IMPORT is executable, will be executed"); - rule.import_exec = 1; - } - } - strlcpy(rule.import, value, sizeof(rule.import)); - rule.import_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "DRIVER") == 0) { - strlcpy(rule.driver, value, sizeof(rule.driver)); - rule.driver_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "RESULT") == 0) { - strlcpy(rule.result, value, sizeof(rule.result)); - rule.result_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "PROGRAM") == 0) { - strlcpy(rule.program, value, sizeof(rule.program)); - rule.program_operation = operation; - program_given = 1; - 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; - } - } - rule.name_operation = operation; - strlcpy(rule.name, value, sizeof(rule.name)); - valid = 1; - continue; - } - - if (strcasecmp(key, "SYMLINK") == 0) { - strlcpy(rule.symlink, value, sizeof(rule.symlink)); - rule.symlink_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "OWNER") == 0) { - strlcpy(rule.owner, value, sizeof(rule.owner)); - rule.owner_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "GROUP") == 0) { - strlcpy(rule.group, value, sizeof(rule.group)); - rule.group_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "MODE") == 0) { - rule.mode = strtol(value, NULL, 8); - rule.mode_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "RUN") == 0) { - strlcpy(rule.run, value, sizeof(rule.run)); - rule.run_operation = operation; - valid = 1; - continue; - } - - if (strcasecmp(key, "OPTIONS") == 0) { - 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; - } - if (strstr(value, "all_partitions") != NULL) { - dbg("creation of partition nodes requested"); - rule.partitions = DEFAULT_PARTITIONS_COUNT; - } - valid = 1; - continue; - } - - err("unknown key '%s'", key); - goto error; - } - - /* skip line if not any valid key was found */ - if (!valid) - goto error; - - if ((rule.result[0] != '\0') && (program_given == 0)) { - info("RESULT is only useful when PROGRAM is called in any rule before"); - goto error; - } - - rule.config_line = lineno; - strlcpy(rule.config_file, filename, sizeof(rule.config_file)); - retval = add_rule_to_list(&rule); - if (retval) { - dbg("add_rule_to_list returned with error %d", retval); - continue; -error: - err("parse error %s, line %d:%d, rule skipped", - filename, lineno, (int) (linepos - line)); - } + add_to_rules(rules, line); } file_unmap(buf, bufsize); return retval; } -static int rules_map(const char *filename) +static int rules_map(struct udev_rules *rules, const char *filename) { - char *buf; - size_t size; - - if (file_map(filename, &buf, &size)) + if (file_map(filename, &rules->buf, &rules->bufsize)) { + rules->buf = NULL; return -1; - if (size == 0) + } + if (rules->bufsize == 0) { + file_unmap(rules->buf, rules->bufsize); + rules->buf = NULL; return -1; - rules_array = (struct udev_rule *) buf; - rules_array_size = size; - rules_count = size / sizeof(struct udev_rule); - dbg("found %zi compiled rules", rules_count); + } return 0; } -int udev_rules_init(void) +int udev_rules_init(struct udev_rules *rules, int resolve_names) { char comp[PATH_SIZE]; struct stat stats; int retval; + memset(rules, 0x00, sizeof(struct udev_rules)); + rules->resolve_names = resolve_names; + + /* check for precompiled rules */ strlcpy(comp, udev_rules_filename, sizeof(comp)); strlcat(comp, ".compiled", sizeof(comp)); if (stat(comp, &stats) == 0) { - dbg("parse compiled rules '%s'", comp); - return rules_map(comp); + dbg("map compiled rules '%s'", comp); + if (rules_map(rules, comp) == 0) + return 0; } if (stat(udev_rules_filename, &stats) != 0) @@ -564,7 +564,7 @@ int udev_rules_init(void) if ((stats.st_mode & S_IFMT) != S_IFDIR) { dbg("parse single rules file '%s'", udev_rules_filename); - retval = rules_parse(udev_rules_filename); + retval = parse_file(rules, udev_rules_filename); } else { struct name_entry *name_loop, *name_tmp; LIST_HEAD(name_list); @@ -573,7 +573,7 @@ int udev_rules_init(void) retval = add_matching_files(&name_list, udev_rules_filename, RULEFILE_SUFFIX); list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { - rules_parse(name_loop->name); + parse_file(rules, name_loop->name); list_del(&name_loop->node); } } @@ -581,16 +581,12 @@ int udev_rules_init(void) return retval; } -void udev_rules_close(void) +void udev_rules_close(struct udev_rules *rules) { - struct udev_rule *rule; - struct udev_rule *temp_rule; - - if (rules_array) - file_unmap(rules_array, rules_array_size); + if (rules->mapped) + file_unmap(rules->buf, rules->bufsize); else - list_for_each_entry_safe(rule, temp_rule, &rules_list, node) { - list_del(&rule->node); - free(rule); - } + free(rules->buf); + + rules->buf = NULL; } diff --git a/udevrulescompile.c b/udevrulescompile.c index 9162a16327..a71286abe7 100644 --- a/udevrulescompile.c +++ b/udevrulescompile.c @@ -50,7 +50,7 @@ void log_message(int priority, const char *format, ...) int main(int argc, char *argv[], char *envp[]) { - struct udev_rule *rule; + struct udev_rules rules; FILE *f; char comp[PATH_SIZE]; char comp_tmp[PATH_SIZE]; @@ -65,12 +65,11 @@ int main(int argc, char *argv[], char *envp[]) strlcpy(comp_tmp, comp, sizeof(comp_tmp)); strlcat(comp_tmp, ".tmp", sizeof(comp_tmp)); - /* remove old version, otherwise we would read it - * instead of the real rules */ + /* remove old version, otherwise we would read it instead of the real rules */ unlink(comp); unlink(comp_tmp); - udev_rules_init(); + udev_rules_init(&rules, 1); f = fopen(comp_tmp, "w"); if (f == NULL) { @@ -79,40 +78,11 @@ int main(int argc, char *argv[], char *envp[]) retval = 1; goto exit; } - dbg("storing compiled rules in '%s'", comp_tmp); - - udev_rules_iter_init(); - while (1) { - char *endptr; - unsigned long id; - - rule = udev_rules_iter_next(); - if (rule == NULL) - break; - - id = strtoul(rule->owner, &endptr, 10); - if (endptr[0] != '\0') { - uid_t uid; - - uid = lookup_user(rule->owner); - dbg("replacing username='%s' by id=%i", rule->owner, uid); - sprintf(rule->owner, "%li", uid); - } - - id = strtoul(rule->group, &endptr, 10); - if (endptr[0] != '\0') { - gid_t gid; - - gid = lookup_group(rule->group); - dbg("replacing groupname='%s' by id=%i", rule->group, gid); - sprintf(rule->group, "%li", gid); - } - - dbg("kernel_name='%s' name='%s'", rule->kernel_name, rule->name); - fwrite(rule, sizeof(struct udev_rule), 1, f); - } + dbg("storing compiled rules in '%s' size=%zi", comp_tmp, rules.bufsize); + fwrite(rules.buf, rules.bufsize, 1, f); fclose(f); + dbg("activating compiled rules in '%s'", comp); if (rename(comp_tmp, comp) != 0) { err("unable to write file"); diff --git a/udevstart.c b/udevstart.c index 22b781d52a..4ef92fd537 100644 --- a/udevstart.c +++ b/udevstart.c @@ -47,6 +47,7 @@ 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, ...) @@ -139,7 +140,7 @@ static int add_device(const char *path, const char *subsystem) dbg("sysfs_open_class_device_path failed"); return -1; } - udev_rules_get_name(&udev, class_dev); + udev_rules_get_name(&rules, &udev, class_dev); if (udev.ignore_device) { dbg("device event will be ignored"); goto exit; @@ -360,11 +361,12 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(ALARM_TIMEOUT); - udev_rules_init(); + udev_rules_init(&rules, 1); udev_scan_block(); udev_scan_class(); + udev_rules_close(&rules); logging_close(); return 0; } diff --git a/udevtest.c b/udevtest.c index d3e43593bf..3e17b94715 100644 --- a/udevtest.c +++ b/udevtest.c @@ -55,6 +55,7 @@ void log_message (int priority, const char *format, ...) int main(int argc, char *argv[], char *envp[]) { + struct udev_rules rules; struct sysfs_class_device *class_dev; char *devpath; char path[PATH_SIZE]; @@ -93,7 +94,7 @@ int main(int argc, char *argv[], char *envp[]) info("looking at device '%s' from subsystem '%s'", devpath, subsystem); /* initialize the naming deamon */ - udev_rules_init(); + udev_rules_init(&rules, 0); /* fill in values and test_run flag*/ udev_init_device(&udev, devpath, subsystem, "add"); @@ -114,7 +115,7 @@ int main(int argc, char *argv[], char *envp[]) /* simulate node creation with test flag */ udev.test_run = 1; if (udev.type == DEV_NET || udev.devt) { - udev_rules_get_name(&udev, class_dev); + udev_rules_get_name(&rules, &udev, class_dev); udev_add_device(&udev, class_dev); } else info("only char and block devices with a dev-file are supported by this test program"); From 25103c4849d3bdee38d22e08c65cd60cf5d5bcc4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 5 Jul 2005 22:40:42 +0200 Subject: [PATCH 1358/4284] create udevdb files only if somehting interesting happened Device nodes created with the default rule, without any symlink or option are no longer saved to the udevdb. This saves us ~3 MB RAM for pretty much useless files on tmpfs. Note: HAL needs a fix to handle this correctly. It's already available on the list. Signed-off-by: Kay Sievers --- udev_db.c | 19 +++++++++++++++---- udev_remove.c | 21 ++++++++++----------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/udev_db.c b/udev_db.c index 264af79d06..6f10b1e58d 100644 --- a/udev_db.c +++ b/udev_db.c @@ -68,10 +68,18 @@ int udev_db_add_device(struct udevice *udev) if (udev->test_run) return 0; + /* don't write anything if udev created only the node with the + * kernel name without any interesting data to remember + */ + if (strcmp(udev->name, udev->kernel_name) == 0 && + list_empty(&udev->symlink_list) && list_empty(&udev->env_list) && + !udev->partitions && !udev->ignore_remove) { + dbg("nothing interesting to store in udevdb, skip"); + goto exit; + } + get_db_filename(udev->devpath, filename, sizeof(filename)); - create_path(filename); - f = fopen(filename, "w"); if (f == NULL) { err("unable to create db file '%s'", filename); @@ -84,12 +92,15 @@ int udev_db_add_device(struct udevice *udev) list_for_each_entry(name_loop, &udev->symlink_list, node) fprintf(f, "S:%s\n", name_loop->name); fprintf(f, "M:%u:%u\n", major(udev->devt), minor(udev->devt)); - fprintf(f, "A:%u\n", udev->partitions); - fprintf(f, "R:%u\n", udev->ignore_remove); + if (udev->partitions) + 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); +exit: return 0; } diff --git a/udev_remove.c b/udev_remove.c index cf28ff37a9..b9a4384ee0 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -143,18 +143,17 @@ int udev_remove_device(struct udevice *udev) if (udev->type != DEV_BLOCK && udev->type != DEV_CLASS) return 0; - /* remove node only if we can find it in our database */ - if (udev_db_get_device(udev, udev->devpath) != 0) { - dbg("'%s' not found in database, ignore event", udev->name); - return -1; + if (udev_db_get_device(udev, udev->devpath) == 0) { + if (udev->ignore_remove) { + dbg("remove event for '%s' requested to be ignored by rule", udev->name); + return 0; + } + dbg("remove name='%s'", udev->name); + udev_db_delete_device(udev); + } else { + dbg("'%s' not found in database, using kernel name '%s'", udev->devpath, udev->kernel_name); + strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); } - if (udev->ignore_remove) { - dbg("remove event for '%s' requested to be ignored by rule", udev->name); - return 0; - } - dbg("remove name='%s'", udev->name); - udev_db_delete_device(udev); - /* use full path to the environment */ snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); udev->devname[sizeof(udev->devname)-1] = '\0'; From f41951c8407ab39f4c514e8751457857a7fb5722 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 6 Jul 2005 01:44:34 +0200 Subject: [PATCH 1359/4284] set default device node to /dev Using prefix seems pretty useless and the empty /udev with every "make install" is annoying. Signed-off-by: Kay Sievers --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 302bb3da14..25e0825247 100644 --- a/Makefile +++ b/Makefile @@ -73,7 +73,7 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} # place to put our device nodes -udevdir = ${prefix}/udev +udevdir = /dev udevdb = ${udevdir}/.udevdb # set up PWD so that older versions of make will work with our build. From 2858b86c6a2cabe809088c545e39de76ae906ee7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 6 Jul 2005 02:01:16 +0200 Subject: [PATCH 1360/4284] don't resolve OWNER, GROUP on precompile if string contains %, $ Signed-off-by: Kay Sievers --- udev_rules_parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 2ec9348b01..c36fc8224c 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -371,7 +371,7 @@ static int add_to_rules(struct udev_rules *rules, char *line) if (strcasecmp(key, "OWNER") == 0) { valid = 1; - if (rules->resolve_names) { + if (rules->resolve_names && (!strchr(value, '$') && !strchr(value, '%'))) { char *endptr; strtoul(value, &endptr, 10); if (endptr[0] != '\0') { @@ -390,7 +390,7 @@ static int add_to_rules(struct udev_rules *rules, char *line) if (strcasecmp(key, "GROUP") == 0) { valid = 1; - if (rules->resolve_names) { + if (rules->resolve_names && (!strchr(value, '$') && !strchr(value, '%'))) { char *endptr; strtoul(value, &endptr, 10); if (endptr[0] != '\0') { From ebfc1acd48606d9f2967d92f265010edf010634b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 6 Jul 2005 02:02:05 +0200 Subject: [PATCH 1361/4284] udevd: optimize env-key parsing Signed-off-by: Kay Sievers --- udevd.c | 30 ++++++++++++++++-------------- udevd.h | 1 + 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/udevd.c b/udevd.c index f69abc4c09..8782c615e3 100644 --- a/udevd.c +++ b/udevd.c @@ -105,7 +105,7 @@ static void msg_dump_queue(void) #endif } -static void run_queue_delete(struct uevent_msg *msg) +static void msg_queue_delete(struct uevent_msg *msg) { list_del(&msg->node); free(msg); @@ -189,7 +189,7 @@ static void execute_udev(struct uevent_msg *msg) break; case -1: err("fork of child failed"); - run_queue_delete(msg); + msg_queue_delete(msg); break; default: /* get SIGCHLD in main loop */ @@ -457,6 +457,8 @@ static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) int bufpos; int i; struct uevent_msg *msg; + int major = 0; + int minor = 0; msg = malloc(sizeof(struct uevent_msg) + buf_size); if (msg == NULL) @@ -479,22 +481,22 @@ static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) /* remember some keys for further processing */ if (strncmp(key, "ACTION=", 7) == 0) msg->action = &key[7]; - - if (strncmp(key, "DEVPATH=", 8) == 0) + else if (strncmp(key, "DEVPATH=", 8) == 0) msg->devpath = &key[8]; - - if (strncmp(key, "SUBSYSTEM=", 10) == 0) + else if (strncmp(key, "SUBSYSTEM=", 10) == 0) msg->subsystem = &key[10]; - - if (strncmp(key, "SEQNUM=", 7) == 0) + else if (strncmp(key, "SEQNUM=", 7) == 0) msg->seqnum = strtoull(&key[7], NULL, 10); - - if (strncmp(key, "PHYSDEVPATH=", 12) == 0) + else if (strncmp(key, "PHYSDEVPATH=", 12) == 0) msg->physdevpath = &key[12]; - - if (strncmp(key, "TIMEOUT=", 8) == 0) + else if (strncmp(key, "MAJOR=", 6) == 0) + major = strtoull(&key[6], NULL, 10); + else if (strncmp(key, "MINOR=", 6) == 0) + minor = strtoull(&key[6], NULL, 10); + else if (strncmp(key, "TIMEOUT=", 8) == 0) msg->timeout = strtoull(&key[8], NULL, 10); } + msg->devt = makedev(major, minor); msg->envp[i++] = "UDEVD_EVENT=1"; msg->envp[i] = NULL; @@ -604,7 +606,7 @@ static struct uevent_msg *get_netlink_msg(void) if ((size_t)size > sizeof(buffer)-1) size = sizeof(buffer)-1; buffer[size] = '\0'; - dbg("uevent_size=%li", (long)size); + dbg("uevent_size=%zi", size); /* start of event payload */ bufpos = strlen(buffer)+1; @@ -679,7 +681,7 @@ static void udev_done(int pid) if (msg->pid == pid) { sysinfo(&info); info("seq %llu exit, %ld seconds old", msg->seqnum, info.uptime - msg->queue_time); - run_queue_delete(msg); + msg_queue_delete(msg); /* we want to run the exec queue manager since there may * be events waiting with the devpath of the one that diff --git a/udevd.h b/udevd.h index 34bfe931ba..c60fb139c0 100644 --- a/udevd.h +++ b/udevd.h @@ -74,6 +74,7 @@ struct uevent_msg { char *action; char *devpath; char *subsystem; + dev_t devt; unsigned long long seqnum; char *physdevpath; unsigned int timeout; From 8815afa1df0dbb0b366156d4cebc56468906118c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 6 Jul 2005 14:42:26 +0200 Subject: [PATCH 1362/4284] rename ALARM_TIMEOUT to UDEV_ALARM_TIMEOUT Signed-off-by: Kay Sievers --- udev.c | 2 +- udev.h | 3 +-- udevstart.c | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/udev.c b/udev.c index 7a0484472a..d44f73081d 100644 --- a/udev.c +++ b/udev.c @@ -96,7 +96,7 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGTERM, &act, NULL); /* trigger timeout to prevent hanging processes */ - alarm(ALARM_TIMEOUT); + alarm(UDEV_ALARM_TIMEOUT); action = getenv("ACTION"); devpath = getenv("DEVPATH"); diff --git a/udev.h b/udev.h index b5287bb53f..a8be0ed400 100644 --- a/udev.h +++ b/udev.h @@ -29,9 +29,7 @@ #include "libsysfs/sysfs/libsysfs.h" #include "list.h" -#define ALARM_TIMEOUT 120 #define COMMENT_CHARACTER '#' - #define LINE_SIZE 512 #define NAME_SIZE 128 #define PATH_SIZE 256 @@ -40,6 +38,7 @@ #define VALUE_SIZE 128 #define DEFAULT_PARTITIONS_COUNT 15 +#define UDEV_ALARM_TIMEOUT 120 enum device_type { DEV_UNKNOWN, diff --git a/udevstart.c b/udevstart.c index 4ef92fd537..d9912466ca 100644 --- a/udevstart.c +++ b/udevstart.c @@ -359,7 +359,7 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGTERM, &act, NULL); /* trigger timeout to prevent hanging processes */ - alarm(ALARM_TIMEOUT); + alarm(UDEV_ALARM_TIMEOUT); udev_rules_init(&rules, 1); From 1196e46c339e0df96ee972a5bae5cc8f84bf8990 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 6 Jul 2005 21:36:21 +0200 Subject: [PATCH 1363/4284] we want to provide OPTFLAGS Signed-off-by: Kay Sievers --- Makefile | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 25e0825247..fd2a3f2b4a 100644 --- a/Makefile +++ b/Makefile @@ -41,6 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false +VERSION = 060 ROOT = udev DAEMON = udevd SENDER = udevsend @@ -51,7 +52,6 @@ CONTROL = udevcontrol INFO = udevinfo TESTER = udevtest STARTER = udevstart -VERSION = 060 RELEASE_NAME = $(ROOT)-$(VERSION) LOCAL_CFG_DIR = etc/udev DESTDIR = @@ -102,19 +102,18 @@ GCCINCDIR := ${shell LC_ALL=C $(CC) -print-search-dirs | sed -ne "s/install: \(. # code taken from uClibc to determine the libgcc.a filename GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) -# use '-Os' optimization if available, else use -O2 -OPTIMIZATION := ${shell if $(CC) -Os -S -o /dev/null -xc /dev/null >/dev/null 2>&1; \ - then echo "-Os"; else echo "-O2" ; fi} - # check if compiler option is supported -cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;} +cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi;} CFLAGS += -Wall -fno-builtin -Wchar-subscripts -Wpointer-arith -Wstrict-prototypes -Wsign-compare -CFLAGS += $(call cc-supports,-Wno-pointer-sign) -CFLAGS += $(call cc-supports,-Wdeclaration-after-statement) +CFLAGS += $(call cc-supports, -Wno-pointer-sign, ) +CFLAGS += $(call cc-supports, -Wdeclaration-after-statement, ) CFLAGS += -pipe CFLAGS += -D_GNU_SOURCE +# use '-Os' optimization if available, else use -O2 +OPTFLAGS := $(call cc-supports, -Os, -O2) + HEADERS = \ udev.h \ udev_utils.h \ @@ -165,7 +164,7 @@ ifeq ($(strip $(DEBUG)),true) LDFLAGS += -Wl STRIPCMD = /bin/true -Since_we_are_debugging else - CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer + CFLAGS += $(OPTFLAGS) -fomit-frame-pointer LDFLAGS += -s -Wl STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif From 040e26dc99b84a122ddc4a5bee75f4772766078c Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 6 Jul 2005 13:09:05 -0700 Subject: [PATCH 1364/4284] Sync up the Debian rules files --- etc/udev/debian/cd-aliases.rules | 14 +- etc/udev/debian/compat.rules | 54 +++---- etc/udev/debian/devfs.rules | 196 ++++++++++++------------ etc/udev/debian/hotplugd.rules | 8 + etc/udev/debian/permissions.rules | 104 +++++++------ etc/udev/debian/run.rules | 7 + etc/udev/debian/simple-cd-aliases.rules | 8 +- etc/udev/debian/udev.rules | 108 ++++++------- 8 files changed, 269 insertions(+), 230 deletions(-) create mode 100644 etc/udev/debian/hotplugd.rules create mode 100644 etc/udev/debian/run.rules diff --git a/etc/udev/debian/cd-aliases.rules b/etc/udev/debian/cd-aliases.rules index 7137527628..b96d3a571d 100644 --- a/etc/udev/debian/cd-aliases.rules +++ b/etc/udev/debian/cd-aliases.rules @@ -3,9 +3,15 @@ # # If you would like to statically configure the aliases instead, you can # use rules like: -# BUS="ide", ID="1.0", SYMLINK="cdrom" +# BUS=="ide", ID=="1.0", SYMLINK+="cdrom" -BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS="ide", KERNEL="pcd[0-9]*", SYSFS{removable}="1", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="scsi", KERNEL=="sr[0-9]*", \ + PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", \ + SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ + PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", \ + SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="ide", KERNEL=="pcd[0-9]*", SYSFS{removable}=="1", \ + PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", \ + SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" diff --git a/etc/udev/debian/compat.rules b/etc/udev/debian/compat.rules index ec386ea8c4..09bb07441b 100644 --- a/etc/udev/debian/compat.rules +++ b/etc/udev/debian/compat.rules @@ -1,37 +1,37 @@ # compatibility links for a devfs-style /dev -KERNEL="md[0-9]*", SYMLINK="%k" -#KERNEL="loop[0-9]*", SYMLINK="%k" +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=="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=="vcs", SYMLINK+="%k" +#KERNEL=="vcs[0-9]*", SYMLINK+="%k" +#KERNEL=="vcsa", SYMLINK+="%k" +#KERNEL=="vcsa[0-9]*", SYMLINK+="%k" -KERNEL="video0", SYMLINK="%k" -KERNEL="radio0", SYMLINK="%k" -KERNEL="vbi0", SYMLINK="%k" -KERNEL="vtx0", 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=="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=="i2c-[0-9]*", SYMLINK+="%k" +#KERNEL=="lp[0-9]*", SYMLINK+="%k" -KERNEL="audio" SYMLINK="%k" -KERNEL="dsp" SYMLINK="%k" -KERNEL="mixer" 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" +#KERNEL=="fb[0-9]*", SYMLINK+="%k" +#KERNEL=="fd[0-9]*", SYMLINK+="%k" +#KERNEL=="js[0-9]*", SYMLINK+="%k" diff --git a/etc/udev/debian/devfs.rules b/etc/udev/debian/devfs.rules index 0453e66d5f..89e0db2aac 100644 --- a/etc/udev/debian/devfs.rules +++ b/etc/udev/debian/devfs.rules @@ -4,141 +4,145 @@ # %n the "kernel number" of the device. # For example, 'sda3' has a "kernel number" of '3' # %e the smallest number for that name which does not matches an existing node -# %k the kernel name for the device. +# %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. +# %s{filename} the content of a sysfs attribute +# %% the '%' char itself # # workaround for devices which do not report media changes -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT="IOMEGA ZIP *", \ - OPTIONS="all_partitions", NAME="%k" +BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ + PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT=="IOMEGA ZIP *", \ + NAME="%k", OPTIONS+="all_partitions" # IDE devices -BUS="ide", KERNEL="hd[a-z]*", \ - PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" +BUS=="ide", KERNEL=="hd[a-z]*", \ + PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK+="%k %c{2}" # SCSI devices -BUS="scsi", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK="%k %c{2}" +BUS=="scsi", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK+="%k %c{2}" # RAID controllers -KERNEL="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ - NAME="%c{1}", SYMLINK="%k" -KERNEL="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ - NAME="%c{1}", SYMLINK="%k" -KERNEL="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ - NAME="%c{1}", SYMLINK="%k" +KERNEL=="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ + NAME="%c{1}", SYMLINK+="%k" +KERNEL=="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ + NAME="%c{1}", SYMLINK+="%k" +KERNEL=="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ + 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" +KERNEL=="md[0-9]*", NAME="md/%n", +KERNEL=="loop[0-9]*", NAME="loop/%n" +KERNEL=="ram[0-9]*", NAME="rd/%n" # USB devices -BUS="usb", KERNEL="auer[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="hiddev*", NAME="usb/%k" -BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="ttyUSB*", SYSFS{product}="Palm Handheld*", SYMLINK="pilot" +BUS=="usb", KERNEL=="auer[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="cpad[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="dabusb*", NAME="usb/%k" +BUS=="usb", KERNEL=="hiddev*", NAME="usb/%k" +BUS=="usb", KERNEL=="legousbtower*", NAME="usb/%k" +BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", \ + SYMLINK+="pilot" # 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" +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" +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="/etc/udev/scripts/dvb.sh %k", NAME="%c" -KERNEL="fb[0-9]*", NAME="fb/%n" -KERNEL="card[0-9]*", NAME="dri/%k" +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="/etc/udev/scripts/dvb.sh %k", \ + 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="nvram", NAME="misc/%k" -KERNEL="psaux", NAME="misc/%k" -KERNEL="rtc", NAME="misc/%k" -KERNEL="hw_random", NAME="hwrng" +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" # printers and parallel devices -KERNEL="lp[0-9]*", NAME="printers/%n" -KERNEL="parport[0-9]*", NAME="parports/%n" +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=="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=="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=="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="tap[0-9]*", NAME="net/%k" -KERNEL="tun", NAME="net/%k" +KERNEL=="umad*", NAME="infiniband/%k" +KERNEL=="issm*", 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" +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" +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" +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=="discover", NAME="etherd/%k" +SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k" +SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k" # device mapper creates its own device nodes, so ignore these -KERNEL="dm-[0-9]*", OPTIONS="ignore_device" -KERNEL="device-mapper", NAME="mapper/control" +KERNEL=="dm-[0-9]*", OPTIONS+="ignore_device" +KERNEL=="device-mapper", NAME="mapper/control" diff --git a/etc/udev/debian/hotplugd.rules b/etc/udev/debian/hotplugd.rules new file mode 100644 index 0000000000..cf84682abf --- /dev/null +++ b/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 +ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" +RUN+="/sbin/udev_run_devd" + diff --git a/etc/udev/debian/permissions.rules b/etc/udev/debian/permissions.rules index 48510e67f6..aab6fdbd08 100644 --- a/etc/udev/debian/permissions.rules +++ b/etc/udev/debian/permissions.rules @@ -1,73 +1,81 @@ # default permissions for block devices -SUBSYSTEM="block", GROUP="disk" -SUBSYSTEM="block", SYSFS{removable}="1", GROUP="floppy" +SUBSYSTEM=="block", GROUP="disk" +SUBSYSTEM=="block", SYSFS{removable}=="1", GROUP="floppy" # IDE devices -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", GROUP="cdrom" -BUS="ide", KERNEL="ht[0-9]*", GROUP="tape" -BUS="ide", KERNEL="nht[0-9]*", GROUP="tape" +BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}="1", \ + PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom*", GROUP="cdrom" +BUS=="ide", KERNEL=="ht[0-9]*", GROUP="tape" +BUS=="ide", KERNEL=="nht[0-9]*", GROUP="tape" # SCSI devices -BUS="scsi", SYSFS{type}="1", GROUP="tape" -BUS="scsi", SYSFS{type}="5", GROUP="cdrom" -BUS="scsi", SYSFS{type}="6", GROUP="scanner" +BUS=="scsi", SYSFS{type}=="1", GROUP="tape" +BUS=="scsi", SYSFS{type}=="5", GROUP="cdrom" +BUS=="scsi", SYSFS{type}=="6", GROUP="scanner" # USB devices -BUS="usb", KERNEL="legousbtower*", MODE="0666" +BUS=="usb", KERNEL=="legousbtower*", MODE="0666" +BUS=="usb", KERNEL=="lp[0-9]*", GROUP="lp" # serial devices -SUBSYSTEM="tty", GROUP="dialout" -SUBSYSTEM="capi", GROUP="dialout" +SUBSYSTEM=="tty", GROUP="dialout" +SUBSYSTEM=="capi", GROUP="dialout" +SUBSYSTEM=="slamr", 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=="ptmx", MODE="0666", GROUP="root" +KERNEL=="console", MODE="0600", GROUP="root" +KERNEL=="tty", MODE="0666", GROUP="root" +KERNEL=="tty[0-9]*", GROUP="root" # video devices -SUBSYSTEM="video4linux", GROUP="video" -SUBSYSTEM="dvb", GROUP="video" -SUBSYSTEM="graphics", GROUP="video" -SUBSYSTEM="nvidia", GROUP="video" -SUBSYSTEM="drm", GROUP="video" +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="0444" -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", MODE="0660", GROUP="audio" +KERNEL=="random", MODE="0666" +KERNEL=="urandom", MODE="0444" +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", MODE="0660", GROUP="audio" -KERNEL="cdemu[0-9]*", GROUP="cdrom" -KERNEL="pktcdvd[0-9]*", GROUP="cdrom" -KERNEL="pktcdvd", MODE="0644" +KERNEL=="cdemu[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd[0-9]*", GROUP="cdrom" +KERNEL=="pktcdvd", MODE="0644" # printers and parallel devices -SUBSYSTEM="printer", GROUP="lp" -SUBSYSTEM="ppdev", GROUP="lp" -KERNEL="pt[0-9]*", GROUP="tape" -KERNEL="pht[0-9]*", GROUP="tape" +SUBSYSTEM=="printer", GROUP="lp" +SUBSYSTEM=="ppdev", GROUP="lp" +KERNEL=="pt[0-9]*", GROUP="tape" +KERNEL=="pht[0-9]*", GROUP="tape" # sound devices -SUBSYSTEM="sound", GROUP="audio" +SUBSYSTEM=="sound", GROUP="audio" + +# ieee1394 devices +KERNEL=="raw1394", GROUP="disk" +KERNEL=="dv1394*", GROUP="video" +KERNEL=="video1394*", GROUP="video" # input devices -KERNEL="event[0-9]*", PROGRAM="/etc/udev/scripts/inputdev.sh %k", \ - RESULT="inputdev", MODE="0664", GROUP="video" -KERNEL="js[0-9]*", MODE="0664" +KERNEL=="event[0-9]*", PROGRAM="/etc/udev/scripts/inputdev.sh %k", \ + RESULT=="inputdev", MODE="0664", GROUP="video" +KERNEL=="js[0-9]*", MODE="0664" # AOE character devices -SUBSYSTEM="aoe", MODE="0220", GROUP="disk" -SUBSYSTEM="aoe", KERNEL="err", MODE="0440" +SUBSYSTEM=="aoe", MODE="0220", GROUP="disk" +SUBSYSTEM=="aoe", KERNEL=="err", MODE="0440" diff --git a/etc/udev/debian/run.rules b/etc/udev/debian/run.rules new file mode 100644 index 0000000000..0e28d189be --- /dev/null +++ b/etc/udev/debian/run.rules @@ -0,0 +1,7 @@ +# 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" +SUBSYSTEM=="vc", OPTIONS+="last_rule" + diff --git a/etc/udev/debian/simple-cd-aliases.rules b/etc/udev/debian/simple-cd-aliases.rules index bd700bc29f..45ffeeac6b 100644 --- a/etc/udev/debian/simple-cd-aliases.rules +++ b/etc/udev/debian/simple-cd-aliases.rules @@ -1,5 +1,7 @@ # grouping of optical drives from multiple kernel subsystems -BUS="scsi", KERNEL="sr[0-9]*", SYMLINK="cdrom%e" -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", SYMLINK="cdrom%e", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom" -BUS="ide", KERNEL="pcd[0-9]*", SYSFS{removable}="1", SYMLINK="cdrom%e" +BUS=="scsi", KERNEL=="sr[0-9]*", SYMLINK+="cdrom%e" +BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ + PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom", \ + SYMLINK+="cdrom%e" +BUS=="ide", KERNEL=="pcd[0-9]*", SYSFS{removable}=="1", SYMLINK+="cdrom%e" diff --git a/etc/udev/debian/udev.rules b/etc/udev/debian/udev.rules index a506a02ad3..07087a3a36 100644 --- a/etc/udev/debian/udev.rules +++ b/etc/udev/debian/udev.rules @@ -4,86 +4,90 @@ # %n the "kernel number" of the device. # For example, 'sda3' has a "kernel number" of '3' # %e the smallest number for that name which does not matches an existing node -# %k the kernel name for the device. +# %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. +# %s{filename} the content of a sysfs attribute +# %% the '%' char itself # # workaround for devices which do not report media changes -BUS="ide", KERNEL="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT="IOMEGA ZIP *", \ - OPTIONS="all_partitions", NAME="%k" +BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ + PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT=="IOMEGA ZIP *", \ + NAME="%k", OPTIONS+="all_partitions" # SCSI devices -BUS="scsi", KERNEL="sr[0-9]*", NAME="scd%n", SYMLINK="sr%n" +BUS=="scsi", KERNEL=="sr[0-9]*", NAME="scd%n", SYMLINK+="sr%n" # USB devices -BUS="usb", KERNEL="hiddev*", NAME="usb/%k" -BUS="usb", KERNEL="auer[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="legousbtower*", NAME="usb/%k" -BUS="usb", KERNEL="dabusb*", NAME="usb/%k" -BUS="usb", KERNEL="cpad[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="lp[0-9]*", NAME="usb/%k" -BUS="usb", KERNEL="ttyUSB*", SYSFS{product}="Palm Handheld*", SYMLINK="pilot" +BUS=="usb", KERNEL=="hiddev*", NAME="usb/%k" +BUS=="usb", KERNEL=="auer[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="legousbtower*", NAME="usb/%k" +BUS=="usb", KERNEL=="dabusb*", NAME="usb/%k" +BUS=="usb", KERNEL=="cpad[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", \ + SYMLINK+=="pilot" # serial devices -KERNEL="capi", NAME="capi20", SYMLINK="isdn/capi20" -KERNEL="capi[0-9]*", NAME="capi/%n" +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" +KERNEL=="capi[0-9]*", NAME="capi/%n" # video devices -KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c" -KERNEL="card[0-9]*", NAME="dri/%k" +KERNEL=="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", \ + NAME="%c" +KERNEL=="card[0-9]*", NAME="dri/%k" # misc devices -KERNEL="hw_random", NAME="hwrng" +KERNEL=="hw_random", NAME="hwrng" +KERNEL=="tun", NAME="net/%k" -KERNEL="cdemu[0-9]*", NAME="cdemu/%n" -KERNEL="pktcdvd[0-9]*", NAME="pktcdvd/%n" -KERNEL="pktcdvd", NAME="pktcdvd/control" +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=="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="tap[0-9]*", NAME="net/%k" -KERNEL="tun", NAME="net/%k" +KERNEL=="umad*", NAME="infiniband/%k" +KERNEL=="issm*", 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" +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" +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" +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=="discover", NAME="etherd/%k" +SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k" +SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k" # device mapper creates its own device nodes, so ignore these -KERNEL="dm-[0-9]*", OPTIONS="ignore_device" -KERNEL="device-mapper", NAME="mapper/control" +KERNEL=="dm-[0-9]*", OPTIONS+="ignore_device" +KERNEL=="device-mapper", NAME="mapper/control" From 0cc976eeaf6370490e1f40faf7926180cfeb85fe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 6 Jul 2005 13:15:23 -0700 Subject: [PATCH 1365/4284] fix cdrom symlink problem in gentoo rules --- etc/udev/gentoo/udev.rules | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index de74c088f0..a0e17359ba 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -16,13 +16,13 @@ SUBSYSTEM=="block", GROUP="disk" # cdrom symlinks and other good cdrom naming -BUS=="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS=="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS=="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +BUS=="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" # devfs-names for ide-devices (uncomment only one) # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS=="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" +BUS=="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK+="%c{1} %c{2}", GROUP="%c{3}" # disk devices KERNEL=="sd*", NAME="%k", GROUP="disk" @@ -139,8 +139,8 @@ KERNEL=="sequencer[0-9]*", NAME="sound/%k", SYMLINK+="%k", GROUP="audio" # 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=="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" @@ -249,9 +249,9 @@ KERNEL=="dv1394*", NAME="dv1394/%n", GROUP="video" KERNEL=="video1394*", NAME="video1394/%n", GROUP="video" # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems -# run hotplug.d/ stuff only if we came from a hotplug event, not for udevstart +# run /etc/hotplug.d/ stuff only if we came from a hotplug event, not for udevstart ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" -# always run dev.d/ stuff for now. +# always run /etc/dev.d/ stuff for now. RUN+="/sbin/udev_run_devd" From 133dd3ce3361fdb03b5761d0b980b9e70f7cfca7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 6 Jul 2005 22:17:06 +0200 Subject: [PATCH 1366/4284] update RELEASE-NOTES Signed-off-by: Kay Sievers --- RELEASE-NOTES | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 46787704ce..248944bd51 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,18 @@ +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 From a82f23bf96bf6e05ae7e986678f411dfa2ad65cc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 6 Jul 2005 14:24:08 -0700 Subject: [PATCH 1367/4284] 061 release --- ChangeLog | 26 ++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index d2e641fc4a..4ecd186f90 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +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 ============================================ diff --git a/Makefile b/Makefile index fd2a3f2b4a..1db74b038b 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 060 +VERSION = 061 ROOT = udev DAEMON = udevd SENDER = udevsend diff --git a/udev.spec b/udev.spec index d56a43ce7d..11cc2430f9 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 059 +Version: 061 Release: 1 License: GPL Group: Utilities/System From 5f79d72c436e9433080feff93be965ec79b17ec2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 7 Jul 2005 16:02:03 +0200 Subject: [PATCH 1368/4284] fix unquoted strings in udevinitsend Signed-off-by: Kay Sievers --- udevinitsend.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/udevinitsend.c b/udevinitsend.c index 26ae5c8418..204e9cecd5 100644 --- a/udevinitsend.c +++ b/udevinitsend.c @@ -132,11 +132,11 @@ static int udevsend(char *filename, int sock, int disable_loop_detection) strncpy(&usend_msg.envbuf[bufpos],ls,(ch - ls) + 1); bufpos += (ch - ls) + 1; if (ch[1] == '\'' && le[-1] == '\'') { - strncpy(&usend_msg.envbuf[bufpos],ch + 2, (le - ch) -3); + strncpy(&usend_msg.envbuf[bufpos],ch + 2, (le - ch) - 3); bufpos += (le - ch) - 3; } else { - strncpy(&usend_msg.envbuf[bufpos],ch, (le - ch)); - bufpos += (le - ch); + strncpy(&usend_msg.envbuf[bufpos],ch + 1, (le - ch) - 1); + bufpos += (le - ch) - 1; } bufpos++; } From b2fe4b9ac96c254efa68d747bfb9843c438919a0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 7 Jul 2005 20:05:51 +0200 Subject: [PATCH 1369/4284] add WAIT_FOR_SYSFS key to loop until a file in sysfs arrives Signed-off-by: Kay Sievers --- udev_rules.c | 44 +++++++++++++++++++++++++++++++++++++++++--- udev_rules.h | 1 + udev_rules_parse.c | 6 ++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 48397ac1c7..932a5b9c6f 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -335,6 +335,28 @@ attr_found: return 0; } +#define WAIT_LOOP_PER_SECOND 20 +static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) +{ + char filename[PATH_SIZE]; + struct stat stats; + int loop = timeout * WAIT_LOOP_PER_SECOND; + + snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->devpath, file); + filename[sizeof(filename)-1] = '\0'; + dbg("wait %i sec for '%s'", timeout, filename); + + while (--loop) { + if (stat(filename, &stats) == 0) { + dbg("file appeared after %i loops", (timeout * WAIT_LOOP_PER_SECOND) - loop-1); + return 0; + } + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + dbg("waiting for '%s' failed", filename); + return -1; +} + static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { @@ -622,15 +644,15 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k dbg("check for %s '%s' <-> '%s'", key_name, key_value, val); match = (strcmp_pattern(key_value, val) == 0); if (match && (key->operation != KEY_OP_NOMATCH)) { - dbg("%s key is matching (matching value)", key_name); + dbg("%s is matching (matching value)", key_name); return 0; } if (!match && (key->operation == KEY_OP_NOMATCH)) { - dbg("%s key is matching, (non matching value)", key_name); + dbg("%s is matching, (non matching value)", key_name); return 0; } - dbg("%s key is not matching", key_name); + dbg("%s is not matching", key_name); return -1; } @@ -681,6 +703,22 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, dbg("all %i ENV keys matched", rule->env.count); } + if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) { + int match; + + match = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0); + if (match && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) { + dbg("WAIT_FOR_SYSFS is matching (matching value)"); + return 0; + } + if (!match && (rule->wait_for_sysfs.operation == KEY_OP_NOMATCH)) { + dbg("WAIT_FOR_SYSFS is matching, (non matching value)"); + return 0; + } + dbg("WAIT_FOR_SYSFS is not matching"); + return -1; + } + /* walk up the chain of physical devices and find a match */ while (1) { /* check for matching driver */ diff --git a/udev_rules.h b/udev_rules.h index 4ecada1c03..959524a802 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -66,6 +66,7 @@ struct udev_rule { struct key result; struct key modalias; struct key import; + struct key wait_for_sysfs; struct key_pairs sysfs; struct key_pairs env; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index c36fc8224c..2add91fa9f 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -284,6 +284,12 @@ static int add_to_rules(struct udev_rules *rules, char *line) continue; } + if (strcasecmp(key, "WAIT_FOR_SYSFS") == 0) { + add_rule_key(rule, &rule->wait_for_sysfs, operation, value); + valid = 1; + continue; + } + if (strncasecmp(key, "ENV", sizeof("ENV")-1) == 0) { attr = get_key_attribute(key + sizeof("ENV")-1); if (attr == NULL) { From 613ffbeb15e0507581e5037850c1ea5d56cd0928 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 7 Jul 2005 22:32:48 +0200 Subject: [PATCH 1370/4284] fix default-name handling and NAME="" rules Signed-off-by: Kay Sievers --- udev.h | 1 - udev_rules.c | 7 ++++--- udev_rules_parse.c | 7 ++++++- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/udev.h b/udev.h index a8be0ed400..391dc2c41c 100644 --- a/udev.h +++ b/udev.h @@ -55,7 +55,6 @@ struct udevice { enum device_type type; char name[PATH_SIZE]; - int name_set; char devname[PATH_SIZE]; struct list_head symlink_list; int symlink_final; diff --git a/udev_rules.c b/udev_rules.c index 932a5b9c6f..27fb0a89a6 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -857,6 +857,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s struct sysfs_class_device *class_dev_parent; struct sysfs_device *sysfs_device = NULL; struct udev_rule *rule; + int name_set = 0; dbg("class_dev->name='%s'", class_dev->name); @@ -888,7 +889,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s if (rule == NULL) break; - if (udev->name_set && rule->name.operation != KEY_OP_UNSET) { + if (name_set && rule->name.operation != KEY_OP_UNSET) { dbg("node name already set, rule ignored"); continue; } @@ -970,7 +971,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s /* set name, later rules with name set will be ignored */ if (rule->name.operation != KEY_OP_UNSET) { - udev->name_set = 1; + name_set = 1; strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name)); apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); @@ -1008,7 +1009,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s } } - if (udev->name[0] == '\0') { + if (!name_set) { strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); info("no rule found, will use kernel name '%s'", udev->name); } diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 2add91fa9f..0021ec40be 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -365,7 +365,12 @@ static int add_to_rules(struct udev_rules *rules, char *line) rule->ignore_remove = 1; } } - add_rule_key(rule, &rule->name, operation, value); + if (value[0] == '\0') { + dbg("name empty device should be ignored"); + rule->name.operation = operation; + rule->ignore_device = 1; + } else + add_rule_key(rule, &rule->name, operation, value); continue; } From a72e3f666b897f94a64547ace3af74785d2f6771 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 7 Jul 2005 22:40:09 +0200 Subject: [PATCH 1371/4284] fix typo in group assignment Thanks to: Georgi Georgiev --- test/udev-test.pl | 26 +++++++++++++++++++++++++- udev_rules_parse.c | 2 +- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 5210471474..6fbc23e557 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1090,7 +1090,8 @@ EOF desc => "ignore rule test", subsys => "block", devpath => "/block/sda", - exp_name => "node", + exp_name => "nothing", + not_exp_name => "node", exp_add_error => "yes", 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 => <owner, operation, group); + add_rule_key(rule, &rule->group, operation, group); continue; } } From 97c0448d9a5626a28a60cc3306e9360f45409fd9 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 7 Jul 2005 23:01:04 +0200 Subject: [PATCH 1372/4284] update RELEASE-NOTES Signed-off-by: Kay Sievers --- RELEASE-NOTES | 7 +++++++ udev_rules.c | 1 + 2 files changed, 8 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 248944bd51..db1e6b838f 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,10 @@ +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 diff --git a/udev_rules.c b/udev_rules.c index 27fb0a89a6..41855eb9d7 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "libsysfs/sysfs/libsysfs.h" #include "list.h" From 7b2bdb4b1bd9e273ea67e4538be3f7d3545331fa Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 7 Jul 2005 23:43:13 +0200 Subject: [PATCH 1373/4284] fix symlink values separated by multiple spaces Signed-off-by: Kay Sievers --- test/udev-test.pl | 11 +++++++++++ udev_rules.c | 12 +++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 6fbc23e557..873780d70a 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -799,6 +799,17 @@ EOF 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_list, pos, 0); + while (isspace(next[1])) + next++; pos = &next[1]; next = strchr(pos, ' '); } - info("add symlink '%s'", pos); - name_list_add(&udev->symlink_list, pos, 0); + 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 */ From face198a5f21027fefe796dc01e19e349a2d36ce Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 7 Jul 2005 15:00:50 -0700 Subject: [PATCH 1374/4284] 062 release --- ChangeLog | 11 +++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4ecd186f90..db2f0b0057 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 1db74b038b..48ecbd7428 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 061 +VERSION = 062 ROOT = udev DAEMON = udevd SENDER = udevsend diff --git a/udev.spec b/udev.spec index 11cc2430f9..496065a79b 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 061 +Version: 062 Release: 1 License: GPL Group: Utilities/System From b4a2906bf1921cd6cbc25621a6db0bae906616c8 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Fri, 8 Jul 2005 03:29:19 +0200 Subject: [PATCH 1375/4284] fix usb_id and let scsi_id ignore "illegal request" --- extras/scsi_id/scsi_id.c | 8 ++- extras/scsi_id/scsi_serial.c | 6 +++ extras/usb_id/usb_id.c | 94 ++++++++++++++++++++++-------------- 3 files changed, 70 insertions(+), 38 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 4003ee6af5..cbefb445df 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -52,7 +52,7 @@ * options are not supported, but other code is still left in place for * now. */ -static const char short_options[] = "bd:f:gip:s:uvVx"; +static const char short_options[] = "abd:f:gip:s:uvVx"; /* * Just duplicate per dev options. */ @@ -61,6 +61,7 @@ static const char dev_short_options[] = "bgp:"; char sysfs_mnt_path[SYSFS_PATH_MAX]; static int all_good; +static int always_info; static char *default_callout; static int dev_specified; static int sys_specified; @@ -485,6 +486,9 @@ static int set_options(int argc, char **argv, const char *short_opts, dprintf("option '%c'\n", option); switch (option) { + case 'a': + always_info = 1; + break; case 'b': all_good = 0; break; @@ -810,7 +814,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) retval = 1; } else if (scsi_get_serial(scsi_dev, maj_min_dev, page_code, serial, MAX_SERIAL_LEN)) { - retval = 1; + retval = always_info?0:1; } else { retval = 0; } diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 20a7928553..7bfa9d1812 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -89,6 +89,7 @@ static const char hex_str[]="0123456789abcdef"; #define SG_ERR_CAT_RESET 2 /* interpreted from sense buffer */ #define SG_ERR_CAT_TIMEOUT 3 #define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */ +#define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */ #define SG_ERR_CAT_SENSE 98 /* Something else in the sense buffer */ #define SG_ERR_CAT_OTHER 99 /* Some other error/warning */ @@ -130,6 +131,8 @@ static int sg_err_category_new(int scsi_status, int msg_status, int return SG_ERR_CAT_MEDIA_CHANGED; if (0x29 == asc) return SG_ERR_CAT_RESET; + } else if (sense_key == ILLEGAL_REQUEST) { + return SG_ERR_CAT_NOTSUPPORTED; } } return SG_ERR_CAT_SENSE; @@ -331,6 +334,9 @@ resend: retval = sg_err_category3(&io_hdr); switch (retval) { + case SG_ERR_CAT_NOTSUPPORTED: + buf[1] = 0; + /* Fallthrough */ case SG_ERR_CAT_CLEAN: case SG_ERR_CAT_RECOVERED: retval = 0; diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index bca80f8de1..f4011ee899 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -72,7 +72,9 @@ static char revision_str[16]; static char type_str[16]; static int use_usb_info; +static int use_num_info; static int export; +static int debug; static void set_str(char *to, const unsigned char *from, int count) { @@ -259,7 +261,7 @@ static int usb_id(const char *target_path) struct sysfs_device *target_dev; struct sysfs_device *host_dev, *interface_dev, *usb_dev; struct sysfs_attribute *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; - struct sysfs_attribute *usb_model, *usb_vendor, *usb_rev, *usb_serial; + struct sysfs_attribute *usb_model = NULL, *usb_vendor = NULL, *usb_rev, *usb_serial; struct sysfs_attribute *if_class, *if_subclass; int if_class_num; int protocol = 0; @@ -322,11 +324,12 @@ static int usb_id(const char *target_path) if_class = sysfs_get_device_attr(interface_dev, "bInterfaceClass"); if (!if_class) { info("%s: cannot get bInterfaceClass attribute", interface_dev->name); - return -1; + return 1; } if_class_num = strtoul(if_class->value, NULL, 16); if (if_class_num != 8) { set_usb_iftype(type_str, if_class->value, sizeof(type_str) - 1); + protocol = 0; } else { if_subclass = sysfs_get_device_attr(interface_dev, "bInterfaceSubClass"); @@ -338,29 +341,29 @@ static int usb_id(const char *target_path) /* Generic SPC-2 device */ scsi_vendor = sysfs_get_device_attr(scsi_dev, "vendor"); if (!scsi_vendor) { - info("%s: cannot get vendor attribute", scsi_dev->name); - return -1; + info("%s: cannot get SCSI vendor attribute", scsi_dev->name); + return 1; } set_str(vendor_str, scsi_vendor->value, sizeof(vendor_str)-1); scsi_model = sysfs_get_device_attr(scsi_dev, "model"); if (!scsi_model) { - info("%s: cannot get model attribute", scsi_dev->name); - return -1; + info("%s: cannot get SCSI model attribute", scsi_dev->name); + return 1; } set_str(model_str, scsi_model->value, sizeof(model_str)-1); scsi_type = sysfs_get_device_attr(scsi_dev, "type"); if (!scsi_type) { - info("%s: cannot get type attribute", scsi_dev->name); - return -1; + info("%s: cannot get SCSI type attribute", scsi_dev->name); + return 1; } set_scsi_type(type_str, scsi_type->value, sizeof(type_str)-1); scsi_rev = sysfs_get_device_attr(scsi_dev, "rev"); if (!scsi_rev) { - info("%s: cannot get type attribute", scsi_dev->name); - return -1; + info("%s: cannot get SCSI revision attribute", scsi_dev->name); + return 1; } set_str(revision_str, scsi_rev->value, sizeof(revision_str)-1); @@ -368,19 +371,29 @@ static int usb_id(const char *target_path) /* Fallback to USB vendor & device */ if (vendor_str[0] == '\0') { - usb_vendor = sysfs_get_device_attr(usb_dev, "manufacturer"); + if (!use_num_info) + if (!(usb_vendor = sysfs_get_device_attr(usb_dev, "manufacturer"))) + dbg("No USB vendor string found, using idVendor"); + if (!usb_vendor) { - dbg("No USB vendor string found, using idVendor"); - usb_vendor = sysfs_get_device_attr(usb_dev, "idVendor"); + if (!(usb_vendor = sysfs_get_device_attr(usb_dev, "idVendor"))) { + dbg("No USB vendor information available\n"); + sprintf(vendor_str,"0000"); + } } set_str(vendor_str,usb_vendor->value, sizeof(vendor_str) - 1); } if (model_str[0] == '\0') { - usb_model = sysfs_get_device_attr(usb_dev, "product"); + if (!use_num_info) + if (!(usb_model = sysfs_get_device_attr(usb_dev, "product"))) + dbg("No USB model string found, using idProduct"); + if (!usb_model) { - dbg("No USB model string found, using idProduct"); - usb_model = sysfs_get_device_attr(usb_dev, "idProduct"); + if (!(usb_model = sysfs_get_device_attr(usb_dev, "idProduct"))) { + dbg("No USB model information available\n"); + sprintf(model_str,"0000"); + } } set_str(model_str, usb_model->value, sizeof(model_str) - 1); } @@ -417,13 +430,20 @@ int main(int argc, char **argv) exit(1); } - while ((option = getopt(argc, argv, "ux")) != -1 ) { + while ((option = getopt(argc, argv, "dnux")) != -1 ) { if (optarg) dbg("option '%c' arg '%s'", option, optarg); else dbg("option '%c'", option); switch (option) { + case 'd': + debug = 1; + break; + case 'n': + use_num_info=1; + use_usb_info=1; + break; case 'u': use_usb_info=1; break; @@ -432,7 +452,7 @@ int main(int argc, char **argv) break; default: info("Unknown or bad option '%c' (0x%x)", option, option); - retval = -1; + retval = 1; break; } } @@ -452,25 +472,27 @@ int main(int argc, char **argv) retval = usb_id(target_path); - if (export) { - printf("ID_VENDOR=%s\n", vendor_str); - printf("ID_MODEL=%s\n", model_str); - printf("ID_REVISION=%s\n", revision_str); - if (serial_str[0] == '\0') { - printf("ID_SERIAL=%s_%s\n", - vendor_str, model_str); + if (retval == 0) { + if (export) { + printf("ID_VENDOR=%s\n", vendor_str); + printf("ID_MODEL=%s\n", model_str); + printf("ID_REVISION=%s\n", revision_str); + if (serial_str[0] == '\0') { + printf("ID_SERIAL=%s_%s\n", + vendor_str, model_str); + } else { + printf("ID_SERIAL=%s_%s_%s\n", + vendor_str, model_str, serial_str); + } + printf("ID_TYPE=%s\n", type_str); } else { - printf("ID_SERIAL=%s_%s_%s\n", - vendor_str, model_str, serial_str); - } - printf("ID_TYPE=%s\n", type_str); - } else { - if (serial_str[0] == '\0') { - printf("%s_%s\n", - vendor_str, model_str); - } else { - printf("%s_%s_%s\n", - vendor_str, model_str, serial_str); + if (serial_str[0] == '\0') { + printf("%s_%s\n", + vendor_str, model_str); + } else { + printf("%s_%s_%s\n", + vendor_str, model_str, serial_str); + } } } exit(retval); From 4431072fb8a95005976cd3316fb978ef6fb588ca Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 12 Jul 2005 11:39:56 +0200 Subject: [PATCH 1376/4284] compile dasd only on s390 Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/dasd.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/extras/volume_id/volume_id/dasd.c b/extras/volume_id/volume_id/dasd.c index 6f403cb928..e02b15ce8a 100644 --- a/extras/volume_id/volume_id/dasd.c +++ b/extras/volume_id/volume_id/dasd.c @@ -39,8 +39,8 @@ #include "util.h" #include "dasd.h" -static unsigned char EBCtoASC[256] = -{ +#ifdef __s390__ +static unsigned char EBCtoASC[256] = { /* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, /* 0x08 -GE -SPS -RPT VT FF CR SO SI */ @@ -144,20 +144,7 @@ typedef struct dasd_information_t { char configuration_data[256]; /* from read_configuration_data */ } dasd_information_t; -#define _IOC_NRBITS 8 -#define _IOC_TYPEBITS 8 -#define _IOC_SIZEBITS 14 -#define _IOC_DIRBITS 2 -#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) -#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) -#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) -#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) -#define _IOC_NRSHIFT 0 -#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) -#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) -#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) #define DASD_IOCTL_LETTER 'D' - #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) #define BLKSSZGET _IO(0x12,104) @@ -170,7 +157,6 @@ int volume_id_probe_dasd(struct volume_id *id) unsigned char name[7]; dbg("probing"); - if (ioctl(id->fd, BIODASDINFO, &info) != 0) return -1; @@ -195,3 +181,11 @@ int volume_id_probe_dasd(struct volume_id *id) return 0; } + +#else +int volume_id_probe_dasd(struct volume_id *id) +{ + return -1; +} +#endif /* __s390__ */ + From e03bce632196dea1f6b18885225b46daaba7fa30 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 12 Jul 2005 11:41:09 +0200 Subject: [PATCH 1377/4284] ata_id: check for empty serial number Signed-off-by: Kay Sievers --- extras/ata_id/ata_id.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index 34b1ccdff1..54c3c29feb 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -167,8 +167,12 @@ int main(int argc, char *argv[]) printf("ID_MODEL=%s\n", model); printf("ID_SERIAL=%s\n", serial); printf("ID_REVISION=%s\n", revision); - } else - printf("%s_%s\n", model, serial); + } else { + if (serial[0] != '\0') + printf("%s_%s\n", model, serial); + else + printf("%s\n", model); + } close: close(fd); From ef520ba25f540a3c552e941351f772fbba7be5d9 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 12 Jul 2005 11:42:39 +0200 Subject: [PATCH 1378/4284] remember mapped rules state Signed-off-by: Kay Sievers --- udev_rules.c | 2 +- udev_rules_parse.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/udev_rules.c b/udev_rules.c index a25c2e90a8..77b97d7f99 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -606,8 +606,8 @@ found: pos = getenv(attr); if (pos == NULL) break; - strlcat(string, pos, maxsize); dbg("substitute env '%s=%s'", attr, pos); + strlcat(string, pos, maxsize); break; default: err("unknown substitution type=%i", type); diff --git a/udev_rules_parse.c b/udev_rules_parse.c index a2f2f1804b..9483bcd71f 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -548,6 +548,7 @@ static int rules_map(struct udev_rules *rules, const char *filename) rules->buf = NULL; return -1; } + rules->mapped = 1; return 0; } From cbbde2ba6c19d6515f09a2ed0955eb2808c91198 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 12 Jul 2005 11:44:51 +0200 Subject: [PATCH 1379/4284] udevd: set incoming socket buffer SO_RCVBUF to maximum Signed-off-by: Kay Sievers --- udevd.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/udevd.c b/udevd.c index 8782c615e3..110d8e7c4d 100644 --- a/udevd.c +++ b/udevd.c @@ -167,7 +167,7 @@ static void msg_queue_insert(struct uevent_msg *msg) } /* forks event and removes event from run queue when finished */ -static void execute_udev(struct uevent_msg *msg) +static void udev_event_fork(struct uevent_msg *msg) { char *const argv[] = { "udev", msg->subsystem, NULL }; pid_t pid; @@ -181,12 +181,10 @@ static void execute_udev(struct uevent_msg *msg) close(uevent_netlink_sock); close(udevd_sock); logging_close(); - setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); execve(udev_bin, argv, msg->envp); err("exec of child failed"); _exit(1); - break; case -1: err("fork of child failed"); msg_queue_delete(msg); @@ -389,7 +387,7 @@ static void exec_queue_manager(void) if (running_with_devpath(loop_msg, max_childs) == 0) { /* move event to run list */ list_move_tail(&loop_msg->node, &running_list); - execute_udev(loop_msg); + udev_event_fork(loop_msg); running++; dbg("moved seq %llu to running list", loop_msg->seqnum); } else @@ -722,6 +720,7 @@ static void user_sighandler(void) static int init_udevd_socket(void) { struct sockaddr_un saddr; + const int buffersize = 1024 * 1024; socklen_t addrlen; const int feature_on = 1; int retval; @@ -738,6 +737,9 @@ static int init_udevd_socket(void) return -1; } + /* set receive buffersize */ + setsockopt(udevd_sock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); + /* the bind takes care of ensuring only one copy running */ retval = bind(udevd_sock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { @@ -755,6 +757,7 @@ static int init_udevd_socket(void) static int init_uevent_netlink_sock(void) { struct sockaddr_nl snl; + const int buffersize = 1024 * 1024; int retval; memset(&snl, 0x00, sizeof(struct sockaddr_nl)); @@ -768,6 +771,9 @@ static int init_uevent_netlink_sock(void) return -1; } + /* set receive buffersize */ + setsockopt(uevent_netlink_sock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); + retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl)); if (retval < 0) { From 0cd4ac473a51577e33e700beccb3479e5565d661 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 12 Jul 2005 12:52:56 +0200 Subject: [PATCH 1380/4284] allow multiple values to be matched with KEY=="value1|value2" Signed-off-by: Kay Sievers --- test/udev-test.pl | 21 +++++++++++++++++++++ udev_rules.c | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 873780d70a..e8cb7c48a9 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1450,6 +1450,27 @@ EOF KERNEL=="ttyUSB[0-9]*", NAME="right" KERNEL=="ttyUSB[0-9]*", NAME="" KERNEL=="ttyUSB[0-9]*", NAME="wrong" +EOF + }, + { + desc => "test multi matches", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "right", + rules => < "test multi matches 2", + subsys => "tty", + devpath => "/class/tty/ttyUSB0", + exp_name => "right", + rules => <operation == KEY_OP_UNSET) return 0; - key_value = rule->buf + key->val_off; + strlcpy(value, rule->buf + key->val_off, sizeof(value)); + key_value = value; - dbg("check for %s '%s' <-> '%s'", key_name, key_value, val); - match = (strcmp_pattern(key_value, val) == 0); - if (match && (key->operation != KEY_OP_NOMATCH)) { - dbg("%s is matching (matching value)", key_name); - return 0; + dbg("key %s value='%s'", key_name, key_value); + while (key_value) { + pos = strchr(key_value, '|'); + if (pos) { + pos[0] = '\0'; + pos++; + } + dbg("match %s '%s' <-> '%s'", key_name, key_value, val); + match = (strcmp_pattern(key_value, val) == 0); + if (match && (key->operation != KEY_OP_NOMATCH)) { + dbg("%s is true (matching value)", key_name); + return 0; + } + if (!match && (key->operation == KEY_OP_NOMATCH)) { + dbg("%s is true (non-matching value)", key_name); + return 0; + } + key_value = pos; } - if (!match && (key->operation == KEY_OP_NOMATCH)) { - dbg("%s is matching, (non matching value)", key_name); - return 0; - } - - dbg("%s is not matching", key_name); + dbg("%s is false", key_name); return -1; } @@ -709,14 +720,14 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, match = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0); if (match && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) { - dbg("WAIT_FOR_SYSFS is matching (matching value)"); + dbg("WAIT_FOR_SYSFS is true (matching value)"); return 0; } if (!match && (rule->wait_for_sysfs.operation == KEY_OP_NOMATCH)) { - dbg("WAIT_FOR_SYSFS is matching, (non matching value)"); + dbg("WAIT_FOR_SYSFS is true, (non matching value)"); return 0; } - dbg("WAIT_FOR_SYSFS is not matching"); + dbg("WAIT_FOR_SYSFS is false"); return -1; } @@ -826,7 +837,7 @@ try_parent: apply_format(udev, program, sizeof(program), class_dev, sysfs_device); dbg("check for PROGRAM program='%s", program); if (execute_program(program, udev->subsystem, result, sizeof(result), NULL) != 0) { - dbg("PROGRAM is not matching"); + dbg("PROGRAM is false"); if (rule->program.operation != KEY_OP_NOMATCH) goto exit; } else { From 0bfb84e1edd96b1e82ffd74c43b865e5d6dbf204 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 12 Jul 2005 14:46:36 +0200 Subject: [PATCH 1381/4284] IMPORT: add {parent} to import the persistent data of the parent device Signed-off-by: Kay Sievers --- test/udev-test.pl | 21 +++++++++++++++++++ udev_rules.c | 51 +++++++++++++++++++++++++++++++++++++++++++--- udev_rules.h | 11 ++++++++-- udev_rules_parse.c | 13 +++++++++--- 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index e8cb7c48a9..1bb60bb76e 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1471,6 +1471,27 @@ EOF KERNEL=="dontknow*|*nothing", NAME="nomatch" KERNEL=="dontknow*|ttyUSB*|nothing*", NAME="right" KERNEL=="ttyUSB*", NAME="wrong" +EOF + }, + { + desc => "IMPORT parent test sequence 1/2 (keep)", + subsys => "block", + devpath => "/block/sda", + exp_name => "parent", + option => "keep", + rules => < "IMPORT parent test sequence 2/2 (keep)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "parentenv-parent_right", + option => "clean", + rules => <path); + udev_init_device(&udev_parent, NULL, NULL, NULL); + /* import the udev_db of the parent */ + if (udev_db_get_device(&udev_parent, &parent->path[strlen(sysfs_path)]) == 0) { + dbg("import stored parent env '%s'", udev_parent.name); + list_for_each_entry(name_loop, &udev_parent.env_list, node) { + char name[NAME_SIZE]; + char *pos; + + strlcpy(name, name_loop->name, sizeof(name)); + pos = strchr(name, '='); + if (pos) { + pos[0] = '\0'; + pos++; + if (strcmp_pattern(filter, name) == 0) { + dbg("import key '%s'", name_loop->name); + name_list_add(&udev->env_list, name_loop->name, 0); + setenv(name, pos, 1); + } else + dbg("skip key '%s'", name_loop->name); + } + } + rc = 0; + } else + dbg("parent not found in database"); + udev_cleanup_device(&udev_parent); + } + + return rc; +} + /* finds the lowest positive N such that N isn't present in the udevdb * if doesn't exist, 0 is returned, N otherwise */ @@ -604,8 +644,10 @@ found: break; } pos = getenv(attr); - if (pos == NULL) + if (pos == NULL) { + dbg("env '%s' not avialable", attr); break; + } dbg("substitute env '%s=%s'", attr, pos); strlcat(string, pos, maxsize); break; @@ -812,12 +854,15 @@ try_parent: strlcpy(import, key_val(rule, &rule->import), sizeof(import)); apply_format(udev, import, sizeof(import), class_dev, sysfs_device); dbg("check for IMPORT import='%s'", import); - if (rule->import_exec) { + if (rule->import_type == IMPORT_PROGRAM) { dbg("run executable file import='%s'", import); rc = import_program_into_env(udev, import); - } else { + } else if (rule->import_type == IMPORT_FILE) { dbg("import file import='%s'", import); rc = import_file_into_env(udev, import); + } else if (rule->import_type == IMPORT_PARENT && class_dev) { + dbg("import parent import='%s'", import); + rc = import_parent_into_env(udev, class_dev, import); } if (rc) { dbg("IMPORT failed"); diff --git a/udev_rules.h b/udev_rules.h index 959524a802..3f37d4b0b4 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -54,6 +54,13 @@ struct key_pairs { struct key_pair keys[PAIRS_MAX]; }; +enum import_type { + IMPORT_UNSET, + IMPORT_PROGRAM, + IMPORT_FILE, + IMPORT_PARENT, +}; + struct udev_rule { struct key kernel_name; struct key subsystem; @@ -66,6 +73,7 @@ struct udev_rule { struct key result; struct key modalias; struct key import; + enum import_type import_type; struct key wait_for_sysfs; struct key_pairs sysfs; struct key_pairs env; @@ -81,8 +89,7 @@ struct udev_rule { unsigned int partitions; unsigned int last_rule:1, ignore_device:1, - ignore_remove:1, - import_exec:1; + ignore_remove:1; size_t bufsize; char buf[]; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 9483bcd71f..7c3c2e7fc2 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -311,9 +311,13 @@ static int add_to_rules(struct udev_rules *rules, char *line) attr = get_key_attribute(key + sizeof("IMPORT")-1); if (attr && strstr(attr, "program")) { dbg("IMPORT will be executed"); - rule->import_exec = 1; + rule->import_type = IMPORT_PROGRAM; } else if (attr && strstr(attr, "file")) { dbg("IMPORT will be included as file"); + rule->import_type = IMPORT_FILE; + } else if (attr && strstr(attr, "parent")) { + dbg("IMPORT will include the parent values"); + rule->import_type = IMPORT_PARENT; } else { /* figure it out if it is executable */ char file[PATH_SIZE]; @@ -326,8 +330,11 @@ static int add_to_rules(struct udev_rules *rules, char *line) pos[0] = '\0'; dbg("IMPORT auto mode for '%s'", file); if (!lstat(file, &stats) && (stats.st_mode & S_IXUSR)) { - dbg("IMPORT is executable, will be executed"); - rule->import_exec = 1; + dbg("IMPORT is executable, will be executed (autotype)"); + rule->import_type = IMPORT_PROGRAM; + } else { + dbg("IMPORT is not executable, will be included as file (autotype)"); + rule->import_type = IMPORT_FILE; } } add_rule_key(rule, &rule->import, operation, value); From afd6b4acc8ce76f1187bf852b1404a82047d8f97 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 12 Jul 2005 15:46:54 -0700 Subject: [PATCH 1382/4284] fix position of raw rules in gentoo config file this solve issue of raw1394 device nodes showing up in the proper place. Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index a0e17359ba..572e5c8ce1 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -120,6 +120,11 @@ KERNEL=="tun", NAME="net/%k" # 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 KERNEL=="raw[0-9]*", NAME="raw/%k", GROUP="disk" KERNEL=="ram*", NAME="%k", GROUP="disk" @@ -243,11 +248,6 @@ KERNEL=="issm*", NAME="infiniband/%k" # tpm devices KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" -# IEEE1394 (firewire) devices -KERNEL=="raw1394", NAME="%k", GROUP="video" -KERNEL=="dv1394*", NAME="dv1394/%n", GROUP="video" -KERNEL=="video1394*", NAME="video1394/%n", GROUP="video" - # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems # run /etc/hotplug.d/ stuff only if we came from a hotplug event, not for udevstart ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" From 5f84d7264d752c9eff91e80070fa199286c25b12 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 13 Jul 2005 11:23:21 +0200 Subject: [PATCH 1383/4284] trivial fixes for *_id programs Signed-off-by: Kay Sievers --- extras/ata_id/ata_id.c | 2 ++ extras/volume_id/vol_id.c | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index 54c3c29feb..9df0fdb107 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -107,6 +107,8 @@ int main(int argc, char *argv[]) int fd; int rc = 0; + logging_init("ata_id"); + for (i = 1 ; i < argc; i++) { char *arg = argv[i]; diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 451fd355c1..1b180a7734 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -136,7 +136,7 @@ int main(int argc, char *argv[]) vid = volume_id_open_node(node); if (vid == NULL) { - fprintf(stderr, "error open volume\n"); + fprintf(stderr, "%s: error open volume\n", node); rc = 2; goto exit; } @@ -149,8 +149,9 @@ int main(int argc, char *argv[]) if (volume_id_probe_dasd(vid) == 0) goto print; - - fprintf(stderr, "unknown volume type\n"); + + if (print != PRINT_EXPORT) + fprintf(stderr, "%s: unknown volume type\n", node); rc = 3; goto exit; From 15e5209b8e93eacfcc3440d383d5b05b5e054934 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Wed, 13 Jul 2005 11:35:51 +0200 Subject: [PATCH 1384/4284] dasd_id: add s390 disk-label prober Signed-off-by: Hannes Reinecke --- extras/dasd_id/Makefile | 52 +++++++ extras/dasd_id/dasd_id.c | 273 +++++++++++++++++++++++++++++++++++++ test/simple-build-check.sh | 1 + 3 files changed, 326 insertions(+) create mode 100644 extras/dasd_id/Makefile create mode 100644 extras/dasd_id/dasd_id.c diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile new file mode 100644 index 0000000000..33bb6965cd --- /dev/null +++ b/extras/dasd_id/Makefile @@ -0,0 +1,52 @@ +# Makefile for dasd_id +# +# 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. +# + +PROG = dasd_id + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +CFLAGS+=-D_FILE_OFFSET_BITS=64 + +OBJS = dasd_id.o ../../udev.a + +$(OBJS): $(HEADERS) + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(PROG): $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/dasd_id/dasd_id.c b/extras/dasd_id/dasd_id.c new file mode 100644 index 0000000000..5c2143f45d --- /dev/null +++ b/extras/dasd_id/dasd_id.c @@ -0,0 +1,273 @@ +/* + * dasdlabel - read label from s390 block device + * + * Copyright (C) 2004 Arnd Bergmann + * + * 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../logging.h" +#include "../../udev_utils.h" + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + static int udev_log = -1; + + if (udev_log == -1) { + const char *value; + + value = getenv("UDEV_LOG"); + if (value) + udev_log = log_priority(value); + else + udev_log = LOG_ERR; + } + + if (priority > udev_log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +/* + * Only compile this on S/390. Doesn't make any sense + * for other architectures. + */ + +static unsigned char EBCtoASC[256] = +{ +/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ + 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, +/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ + 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, +/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC + -ENP ->LF */ + 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, +/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB + -IUS */ + 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC + -INP */ + 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, +/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL + -SW */ + 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, +/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ + 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, +/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ + 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, +/* 0x40 SP RSP ä ---- */ + 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, +/* 0x48 . < ( + | */ + 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, +/* 0x50 & ---- */ + 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, +/* 0x58 ß ! $ * ) ; */ + 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, +/* 0x60 - / ---- Ä ---- ---- ---- */ + 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, +/* 0x68 ---- , % _ > ? */ + 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, +/* 0x70 --- ---- ---- ---- ---- ---- ---- */ + 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +/* 0x78 * ` : # @ ' = " */ + 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, +/* 0x80 * a b c d e f g */ + 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, +/* 0x88 h i ---- ---- ---- */ + 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, +/* 0x90 ° j k l m n o p */ + 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, +/* 0x98 q r ---- ---- */ + 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, +/* 0xA0 ~ s t u v w x */ + 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, +/* 0xA8 y z ---- ---- ---- ---- */ + 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, +/* 0xB0 ^ ---- § ---- */ + 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, +/* 0xB8 ---- [ ] ---- ---- ---- ---- */ + 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, +/* 0xC0 { A B C D E F G */ + 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, +/* 0xC8 H I ---- ö ---- */ + 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, +/* 0xD0 } J K L M N O P */ + 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, +/* 0xD8 Q R ---- ü */ + 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, +/* 0xE0 \ S T U V W X */ + 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, +/* 0xE8 Y Z ---- Ö ---- ---- ---- */ + 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, +/* 0xF0 0 1 2 3 4 5 6 7 */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */ + 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 +}; + +static void vtoc_ebcdic_dec (const unsigned char *source, char *target, int l) +{ + int i; + + for (i = 0; i < l; i++) + target[i]=(char)EBCtoASC[(unsigned char)(source[i])]; +} + +/* + * struct dasd_information_t + * represents any data about the data, which is visible to userspace + */ +typedef struct dasd_information_t { + unsigned int devno; /* S/390 devno */ + unsigned int real_devno; /* for aliases */ + unsigned int schid; /* S/390 subchannel identifier */ + unsigned int cu_type : 16; /* from SenseID */ + unsigned int cu_model : 8; /* from SenseID */ + unsigned int dev_type : 16; /* from SenseID */ + unsigned int dev_model : 8; /* from SenseID */ + unsigned int open_count; + unsigned int req_queue_len; + unsigned int chanq_len; /* length of chanq */ + char type[4]; /* from discipline.name, 'none' for unknown */ + unsigned int status; /* current device level */ + unsigned int label_block; /* where to find the VOLSER */ + unsigned int FBA_layout; /* fixed block size (like AIXVOL) */ + unsigned int characteristics_size; + unsigned int confdata_size; + char characteristics[64]; /* from read_device_characteristics */ + char configuration_data[256]; /* from read_configuration_data */ +} dasd_information_t; + +#define DASD_IOCTL_LETTER 'D' +#define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) +#define BLKSSZGET _IO(0x12,104) + +unsigned char serial[8]; + +static int dasd_id(int fd) +{ + int blocksize; + dasd_information_t info; + __u8 *data; + __u8 *label_raw; + + if (ioctl(fd, BIODASDINFO, &info) != 0) { + dbg("not a dasd"); + return -1; + } + + if (ioctl(fd, BLKSSZGET, &blocksize) != 0) { + err("failed to get blocksize"); + return -1; + } + + if (lseek(fd,info.label_block * blocksize, SEEK_SET) == -1) { + err("seek failed on dasd"); + return -1; + } + + data = malloc(blocksize); + if (data == NULL) + return -1; + + if (read(fd, data, blocksize) == -1) { + err("read disklabel failed"); + free(data); + return -1; + } + + if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) + label_raw = &data[8]; + else + label_raw = &data[4]; + serial[6] = '\0'; + + vtoc_ebcdic_dec(label_raw, serial, 6); + free(data); + + return 0; + } + +int main(int argc, char *argv[]) +{ + const char *node = NULL; + int i; + int export = 0; + int fd; + int rc = 0; + + logging_init("dasd_id"); + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (strcmp(arg, "--export") == 0) { + export = 1; + } else + node = arg; + } + if (!node) { + err("no node specified"); + rc = 1; + goto exit; + } + + fd = open(node, O_RDONLY); + if (fd < 0) { + err("unable to open '%s'", node); + rc = 1; + goto exit; + } + + if (dasd_id(fd) < 0) { + err("dasd_id failed: %s", strerror(errno)); + rc = 1; + } + + if (export) { + printf("ID_TYPE=disk\n"); + printf("ID_SERIAL=%s\n",serial); + } else + printf("%s\n", serial); + + close(fd); +exit: + logging_close(); + return rc; +} + diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index c5b429d98d..7e9a940f85 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -6,6 +6,7 @@ EXTRAS="\ extras/ata_id \ extras/volume_id \ extras/usb_id \ + extras/dasd_id \ extras/run_directory" [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build From b0f57eb066cd897dab536ee37daab4239d136d4c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 13 Jul 2005 12:01:53 +0200 Subject: [PATCH 1385/4284] volume_id: remove s390 dasd handling, it is dasd_id now Signed-off-by: Kay Sievers --- extras/volume_id/README | 1 - extras/volume_id/vol_id.c | 4 - extras/volume_id/volume_id/Makefile.inc | 2 - extras/volume_id/volume_id/dasd.c | 191 ------------------------ extras/volume_id/volume_id/dasd.h | 26 ---- extras/volume_id/volume_id/volume_id.h | 2 +- 6 files changed, 1 insertion(+), 225 deletions(-) delete mode 100644 extras/volume_id/volume_id/dasd.c delete mode 100644 extras/volume_id/volume_id/dasd.h diff --git a/extras/volume_id/README b/extras/volume_id/README index a7635ff612..974a5016d9 100644 --- a/extras/volume_id/README +++ b/extras/volume_id/README @@ -37,7 +37,6 @@ luks * - * - hpfs * - - - romfs * minix * -dasd * highpoint * isw_raid * lsi_raid * diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 1b180a7734..a4a866cfcf 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -32,7 +32,6 @@ #include "../../udev_utils.h" #include "../../logging.h" #include "volume_id/volume_id.h" -#include "volume_id/dasd.h" #define BLKGETSIZE64 _IOR(0x12,114,size_t) @@ -147,9 +146,6 @@ int main(int argc, char *argv[]) if (volume_id_probe_all(vid, 0, size) == 0) goto print; - if (volume_id_probe_dasd(vid) == 0) - goto print; - if (print != PRINT_EXPORT) fprintf(stderr, "%s: unknown volume type\n", node); rc = 3; diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index acd26ff101..266d1e4872 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -26,7 +26,6 @@ VOLUME_ID_OBJS= \ $(VOLUME_ID_BASE)/romfs.o \ $(VOLUME_ID_BASE)/sysv.o \ $(VOLUME_ID_BASE)/minix.o \ - $(VOLUME_ID_BASE)/dasd.o \ $(VOLUME_ID_BASE)/luks.o \ $(VOLUME_ID_BASE)/volume_id.o \ $(VOLUME_ID_BASE)/util.o @@ -58,7 +57,6 @@ VOLUME_ID_HEADERS= \ $(VOLUME_ID_BASE)/romfs.h \ $(VOLUME_ID_BASE)/sysv.h \ $(VOLUME_ID_BASE)/minix.h \ - $(VOLUME_ID_BASE)/dasd.h \ $(VOLUME_ID_BASE)/luks.h \ $(VOLUME_ID_BASE)/volume_id.h \ $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/dasd.c b/extras/volume_id/volume_id/dasd.c deleted file mode 100644 index e02b15ce8a..0000000000 --- a/extras/volume_id/volume_id/dasd.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * dasdlabel - read label from s390 block device - * - * Copyright (C) 2004 Arnd Bergmann - * - * 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 - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include "volume_id.h" -#include "logging.h" -#include "util.h" -#include "dasd.h" - -#ifdef __s390__ -static unsigned char EBCtoASC[256] = { -/* 0x00 NUL SOH STX ETX *SEL HT *RNL DEL */ - 0x00, 0x01, 0x02, 0x03, 0x07, 0x09, 0x07, 0x7F, -/* 0x08 -GE -SPS -RPT VT FF CR SO SI */ - 0x07, 0x07, 0x07, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, -/* 0x10 DLE DC1 DC2 DC3 -RES -NL BS -POC - -ENP ->LF */ - 0x10, 0x11, 0x12, 0x13, 0x07, 0x0A, 0x08, 0x07, -/* 0x18 CAN EM -UBS -CU1 -IFS -IGS -IRS -ITB - -IUS */ - 0x18, 0x19, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -/* 0x20 -DS -SOS FS -WUS -BYP LF ETB ESC - -INP */ - 0x07, 0x07, 0x1C, 0x07, 0x07, 0x0A, 0x17, 0x1B, -/* 0x28 -SA -SFE -SM -CSP -MFA ENQ ACK BEL - -SW */ - 0x07, 0x07, 0x07, 0x07, 0x07, 0x05, 0x06, 0x07, -/* 0x30 ---- ---- SYN -IR -PP -TRN -NBS EOT */ - 0x07, 0x07, 0x16, 0x07, 0x07, 0x07, 0x07, 0x04, -/* 0x38 -SBS -IT -RFF -CU3 DC4 NAK ---- SUB */ - 0x07, 0x07, 0x07, 0x07, 0x14, 0x15, 0x07, 0x1A, -/* 0x40 SP RSP ä ---- */ - 0x20, 0xFF, 0x83, 0x84, 0x85, 0xA0, 0x07, 0x86, -/* 0x48 . < ( + | */ - 0x87, 0xA4, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C, -/* 0x50 & ---- */ - 0x26, 0x82, 0x88, 0x89, 0x8A, 0xA1, 0x8C, 0x07, -/* 0x58 ß ! $ * ) ; */ - 0x8D, 0xE1, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0xAA, -/* 0x60 - / ---- Ä ---- ---- ---- */ - 0x2D, 0x2F, 0x07, 0x8E, 0x07, 0x07, 0x07, 0x8F, -/* 0x68 ---- , % _ > ? */ - 0x80, 0xA5, 0x07, 0x2C, 0x25, 0x5F, 0x3E, 0x3F, -/* 0x70 --- ---- ---- ---- ---- ---- ---- */ - 0x07, 0x90, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, -/* 0x78 * ` : # @ ' = " */ - 0x70, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22, -/* 0x80 * a b c d e f g */ - 0x07, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, -/* 0x88 h i ---- ---- ---- */ - 0x68, 0x69, 0xAE, 0xAF, 0x07, 0x07, 0x07, 0xF1, -/* 0x90 ° j k l m n o p */ - 0xF8, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, -/* 0x98 q r ---- ---- */ - 0x71, 0x72, 0xA6, 0xA7, 0x91, 0x07, 0x92, 0x07, -/* 0xA0 ~ s t u v w x */ - 0xE6, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, -/* 0xA8 y z ---- ---- ---- ---- */ - 0x79, 0x7A, 0xAD, 0xAB, 0x07, 0x07, 0x07, 0x07, -/* 0xB0 ^ ---- § ---- */ - 0x5E, 0x9C, 0x9D, 0xFA, 0x07, 0x07, 0x07, 0xAC, -/* 0xB8 ---- [ ] ---- ---- ---- ---- */ - 0xAB, 0x07, 0x5B, 0x5D, 0x07, 0x07, 0x07, 0x07, -/* 0xC0 { A B C D E F G */ - 0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, -/* 0xC8 H I ---- ö ---- */ - 0x48, 0x49, 0x07, 0x93, 0x94, 0x95, 0xA2, 0x07, -/* 0xD0 } J K L M N O P */ - 0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, -/* 0xD8 Q R ---- ü */ - 0x51, 0x52, 0x07, 0x96, 0x81, 0x97, 0xA3, 0x98, -/* 0xE0 \ S T U V W X */ - 0x5C, 0xF6, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, -/* 0xE8 Y Z ---- Ö ---- ---- ---- */ - 0x59, 0x5A, 0xFD, 0x07, 0x99, 0x07, 0x07, 0x07, -/* 0xF0 0 1 2 3 4 5 6 7 */ - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, -/* 0xF8 8 9 ---- ---- Ü ---- ---- ---- */ - 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 -}; - -static void vtoc_ebcdic_dec (const unsigned char *source, unsigned char *target, int l) -{ - int i; - - for (i = 0; i < l; i++) - target[i]=EBCtoASC[(unsigned char)(source[i])]; -} - -/* - * struct dasd_information_t - * represents any data about the data, which is visible to userspace - */ -typedef struct dasd_information_t { - unsigned int devno; /* S/390 devno */ - unsigned int real_devno; /* for aliases */ - unsigned int schid; /* S/390 subchannel identifier */ - unsigned int cu_type : 16; /* from SenseID */ - unsigned int cu_model : 8; /* from SenseID */ - unsigned int dev_type : 16; /* from SenseID */ - unsigned int dev_model : 8; /* from SenseID */ - unsigned int open_count; - unsigned int req_queue_len; - unsigned int chanq_len; /* length of chanq */ - char type[4]; /* from discipline.name, 'none' for unknown */ - unsigned int status; /* current device level */ - unsigned int label_block; /* where to find the VOLSER */ - unsigned int FBA_layout; /* fixed block size (like AIXVOL) */ - unsigned int characteristics_size; - unsigned int confdata_size; - char characteristics[64]; /* from read_device_characteristics */ - char configuration_data[256]; /* from read_configuration_data */ -} dasd_information_t; - -#define DASD_IOCTL_LETTER 'D' -#define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) -#define BLKSSZGET _IO(0x12,104) - -int volume_id_probe_dasd(struct volume_id *id) -{ - int blocksize; - dasd_information_t info; - __u8 *data; - __u8 *label_raw; - unsigned char name[7]; - - dbg("probing"); - if (ioctl(id->fd, BIODASDINFO, &info) != 0) - return -1; - - if (ioctl(id->fd, BLKSSZGET, &blocksize) != 0) - return -1; - - data = volume_id_get_buffer(id, info.label_block * blocksize, 16); - if (data == NULL) - return -1; - - if ((!info.FBA_layout) && (!strcmp(info.type, "ECKD"))) - label_raw = &data[8]; - else - label_raw = &data[4]; - - name[6] = '\0'; - volume_id_set_usage(id, VOLUME_ID_DISKLABEL); - id->type = "dasd"; - volume_id_set_label_raw(id, label_raw, 6); - vtoc_ebcdic_dec(label_raw, name, 6); - volume_id_set_label_string(id, name, 6); - - return 0; -} - -#else -int volume_id_probe_dasd(struct volume_id *id) -{ - return -1; -} -#endif /* __s390__ */ - diff --git a/extras/volume_id/volume_id/dasd.h b/extras/volume_id/volume_id/dasd.h deleted file mode 100644 index 751b9fda60..0000000000 --- a/extras/volume_id/volume_id/dasd.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * dasdlabel - read label from s390 block device - * - * Copyright (C) 2004 Arnd Bergmann - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _VOLUME_ID_DASDLABEL_ -#define _VOLUME_ID_DASDLABEL_ - -extern int volume_id_probe_dasd(struct volume_id *id); - -#endif diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 2266694f5e..c6aef50876 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 44 +#define VOLUME_ID_VERSION 45 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 8cf97fb046ddcfaea48ab6182b0f69996158d280 Mon Sep 17 00:00:00 2001 From: Anton Farygin Date: Thu, 14 Jul 2005 11:39:55 +0200 Subject: [PATCH 1386/4284] fix typo in GROUP value application --- udev_rules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev_rules.c b/udev_rules.c index d08edf7782..5669a8593e 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -987,7 +987,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s if (rule->group.operation == KEY_OP_ASSIGN_FINAL) udev->group_final = 1; strlcpy(udev->group, key_val(rule, &rule->group), sizeof(udev->group)); - apply_format(udev, key_val(rule, &rule->group), sizeof(udev->group), class_dev, sysfs_device); + apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); } From 7fe082a8a42baa45ef45d82edde4f893410ebeea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Thu, 14 Jul 2005 11:43:05 +0200 Subject: [PATCH 1387/4284] correct default mode documentation in udev --- docs/writing_udev_rules/index.html | 2 +- etc/udev/redhat/udev.rules | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/writing_udev_rules/index.html b/docs/writing_udev_rules/index.html index 1ba43678c0..c2ccdc3663 100644 --- a/docs/writing_udev_rules/index.html +++ b/docs/writing_udev_rules/index.html @@ -321,7 +321,7 @@ Building on the style mentioned above, you can do even more flashy things. The u This prevents the need to excessively provide a GROUP="audio" key on every following rule which names sound devices.

    -udev defaults to creating nodes with unix permissions of 0660 (read/write to owner and group), which is configured by the default_mode setting inside /etc/udev/udev.conf. There may be some situations where you do not want to use the default permissions on your device node. Fortunately, you can easily override the permissions in your rules using the MODE assignment key. As an example, the following rule defines that the inotify node shall be readable and writable to everyone: +udev defaults to creating nodes with unix permissions of 0660 (read/write to owner and group). There may be some situations where you do not want to use the default permissions on your device node. Fortunately, you can easily override the permissions in your rules using the MODE assignment key. 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"
    diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 2d4819f8c3..5bed782280 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -1,7 +1,7 @@ # There are a number of modifiers that are allowed to be used in some of the # fields. See the udev man page for a full description of them. # -# default is OWNER="root" GROUP="root", MODE="0600" +# default is OWNER="root" GROUP="root", MODE="0660" # # all block devices From 78e21e3ed4a038a8aa358eb109b6029ca9c3cdd1 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 14 Jul 2005 15:19:37 -0700 Subject: [PATCH 1388/4284] Fixed udev_run_devd to run the /etc/dev.d/DEVNAME/ files too Note, this assumes that you are putting your device nodes in /dev/, the better thing to do is use the RUN= rule and not rely on this program at all. Signed-off-by: Greg Kroah-Hartman --- extras/run_directory/run_directory.h | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 extras/run_directory/run_directory.h diff --git a/extras/run_directory/run_directory.h b/extras/run_directory/run_directory.h new file mode 100644 index 0000000000..edb46ddd73 --- /dev/null +++ b/extras/run_directory/run_directory.h @@ -0,0 +1,3 @@ + +extern int run_directory(const char *dir, const char *suffix, const char *subsystem); + From 04b90b7e256762bb6eecf0567ca33ceec03621f5 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 14 Jul 2005 15:24:59 -0700 Subject: [PATCH 1389/4284] Really commit the udev_run_devd changes... --- extras/run_directory/run_directory.c | 17 +++------------- extras/run_directory/udev_run_devd.c | 25 +++++++++++++++++++++--- extras/run_directory/udev_run_hotplugd.c | 7 +++++-- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/extras/run_directory/run_directory.c b/extras/run_directory/run_directory.c index e6c6173eca..770d8d84a1 100644 --- a/extras/run_directory/run_directory.c +++ b/extras/run_directory/run_directory.c @@ -25,8 +25,7 @@ #include "../../udev_utils.h" #include "../../list.h" #include "../../logging.h" - -int run_directory(const char *dir, const char *suffix, const char *subsystem); +#include "run_directory.h" static int run_program(const char *filename, const char *subsystem) { @@ -53,21 +52,11 @@ static int run_program(const char *filename, const char *subsystem) int run_directory(const char *dir, const char *suffix, const char *subsystem) { - char dirname[NAME_SIZE]; struct name_entry *name_loop, *name_tmp; LIST_HEAD(name_list); - if (subsystem) { - snprintf(dirname, sizeof(dirname), "%s/%s", dir, subsystem); - dirname[sizeof(dirname)-1] = '\0'; - dbg("looking at '%s'", dirname); - add_matching_files(&name_list, dirname, suffix); - } - - snprintf(dirname, sizeof(dirname), "%s/default", dir); - dirname[sizeof(dirname)-1] = '\0'; - dbg("looking at '%s'", dirname); - add_matching_files(&name_list, dirname, suffix); + dbg("looking at '%s'", dir); + add_matching_files(&name_list, dir, suffix); list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { run_program(name_loop->name, subsystem); diff --git a/extras/run_directory/udev_run_devd.c b/extras/run_directory/udev_run_devd.c index 02bbc8c353..e708de8aa4 100644 --- a/extras/run_directory/udev_run_devd.c +++ b/extras/run_directory/udev_run_devd.c @@ -25,8 +25,8 @@ #include "../../udev_utils.h" #include "../../list.h" #include "../../logging.h" +#include "run_directory.h" -extern int run_directory(const char *dir, const char *suffix, const char *subsystem); #ifdef USE_LOG void log_message (int priority, const char *format, ...) @@ -55,11 +55,25 @@ void log_message (int priority, const char *format, ...) int main(int argc, char *argv[], char *envp[]) { + char dirname[NAME_SIZE]; + const char *devname; + const char *my_devname; const char *subsystem; int fd; - if (getenv("DEVNAME") == NULL) + devname = getenv("DEVNAME"); + if (devname == NULL) exit(0); + /* + * Hack, we are assuming that the device nodes are in /dev, + * if not, this will not work, but you should be using the + * RUN= rule anyway... + */ + my_devname = strstr(devname, "/dev/"); + if (my_devname != NULL) + my_devname = &my_devname[5]; + else + my_devname = devname; subsystem = argv[1]; logging_init("udev_run_devd"); @@ -73,6 +87,11 @@ int main(int argc, char *argv[], char *envp[]) } dbg("running dev.d directory"); - run_directory("/etc/dev.d", ".dev", subsystem); + sprintf(dirname, "/etc/dev.d/%s", my_devname); + run_directory(dirname, ".dev", subsystem); + sprintf(dirname, "/etc/dev.d/%s", subsystem); + run_directory(dirname, ".dev", subsystem); + run_directory("/etc/dev.d/default", ".dev", subsystem); + exit(0); } diff --git a/extras/run_directory/udev_run_hotplugd.c b/extras/run_directory/udev_run_hotplugd.c index 54b6bf44e3..a21835ae4e 100644 --- a/extras/run_directory/udev_run_hotplugd.c +++ b/extras/run_directory/udev_run_hotplugd.c @@ -25,8 +25,8 @@ #include "../../udev_utils.h" #include "../../list.h" #include "../../logging.h" +#include "run_directory.h" -extern int run_directory(const char *dir, const char *suffix, const char *subsystem); #ifdef USE_LOG void log_message (int priority, const char *format, ...) @@ -55,6 +55,7 @@ void log_message (int priority, const char *format, ...) int main(int argc, char *argv[], char *envp[]) { + char dirname[NAME_SIZE]; const char *subsystem; int fd; @@ -71,6 +72,8 @@ int main(int argc, char *argv[], char *envp[]) dbg("running dev.d directory"); - run_directory("/etc/hotplug.d", ".hotplug", subsystem); + sprintf(dirname, "/etc/hotplug.d/%s", subsystem); + run_directory(dirname, ".hotplug", subsystem); + run_directory("/etc/hotplug.d/default", ".hotplug", subsystem); exit(0); } From 0de3c3edebeaab08c2697d13c33e0049f6371706 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 14 Jul 2005 15:27:30 -0700 Subject: [PATCH 1390/4284] add 'make tests' as I'm always typing that one wrong... Signed-off-by: Greg Kroah-Hartman --- Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile b/Makefile index 48ecbd7428..c3485c0472 100644 --- a/Makefile +++ b/Makefile @@ -412,3 +412,5 @@ uninstall: uninstall-man test: all @ cd test && ./udev-test.pl @ cd test && ./udevstart-test.pl + +tests: test From 8365854ccda3d0f36333b699454238cff111e169 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 14 Jul 2005 16:09:21 -0700 Subject: [PATCH 1391/4284] 063 release --- ChangeLog | 30 ++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index db2f0b0057..159437240f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +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 ============================================ diff --git a/Makefile b/Makefile index c3485c0472..a8f2851cab 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 062 +VERSION = 063 ROOT = udev DAEMON = udevd SENDER = udevsend diff --git a/udev.spec b/udev.spec index 496065a79b..22d9160529 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace implementation of devfs Name: udev -Version: 062 +Version: 063 Release: 1 License: GPL Group: Utilities/System From c609f627fae97bef5f163eb2eb993d3c8211f768 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 16 Jul 2005 05:50:34 +0200 Subject: [PATCH 1392/4284] thread unknown ENV{key} match as empty value This way we can run a rule if a certain key is not set by: ENV{key}="" or ENV{key}!="?*" Signed-off-by: Kay Sievers --- udev_rules.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 5669a8593e..4bf05cd437 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -748,8 +748,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, const char *value = getenv(key_name); if (!value) { - dbg("ENV{'%s'} is not found", key_name); - goto exit; + dbg("ENV{'%s'} is not set", key_name); + value = ""; } if (match_key("ENV", rule, &pair->key, value)) goto exit; From 594dd610252923591ed0f310695e82d3fb87e581 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 16 Jul 2005 07:46:31 +0200 Subject: [PATCH 1393/4284] allow rules to have labels and skip to next label This will allow us to have whole blocks of rules to skip conditionally. The following section creates the node "yes": GOTO="TEST" NAME="no" NAME="no2", LABEL="NO" NAME="yes", LABEL="TEST" NAME="no3" --- Makefile | 2 +- test/udev-test.pl | 13 +++++++++++++ udev_rules.c | 5 +++++ udev_rules.h | 3 +++ udev_rules_parse.c | 39 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 60 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a8f2851cab..b740838ace 100644 --- a/Makefile +++ b/Makefile @@ -377,8 +377,8 @@ install: install-config install-man all $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) ifndef DESTDIR - killall $(DAEMON) - - $(sbindir)/$(DAEMON) --daemon - rm -rf $(udevdb) + - $(sbindir)/$(DAEMON) --daemon endif @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ diff --git a/test/udev-test.pl b/test/udev-test.pl index 1bb60bb76e..94cffeab07 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1492,6 +1492,19 @@ EOF option => "clean", rules => < "GOTO test", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "right", + rules => <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)); + } } } diff --git a/udev_rules.h b/udev_rules.h index 3f37d4b0b4..d22d31f7e1 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -62,6 +62,8 @@ enum import_type { }; struct udev_rule { + struct key label; + struct key goto_label; struct key kernel_name; struct key subsystem; struct key action; @@ -108,6 +110,7 @@ extern void udev_rules_close(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, struct sysfs_class_device *class_dev); extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device); diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 7c3c2e7fc2..0259268c8f 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -52,8 +52,10 @@ struct udev_rule *udev_rules_iter_next(struct udev_rules *rules) return NULL; dbg("current=%zi", rules->current); - if (rules->current >= rules->bufsize) + if (rules->current >= rules->bufsize) { + dbg("no more rules"); return NULL; + } /* get next rule */ rule = (struct udev_rule *) (rules->buf + rules->current); @@ -62,6 +64,28 @@ struct udev_rule *udev_rules_iter_next(struct udev_rules *rules) 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; @@ -237,6 +261,18 @@ static int add_to_rules(struct udev_rules *rules, char *line) if (retval) break; + 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 (strcasecmp(key, "KERNEL") == 0) { add_rule_key(rule, &rule->kernel_name, operation, value); valid = 1; @@ -475,6 +511,7 @@ static int add_to_rules(struct udev_rules *rules, char *line) 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: From 422d5becc339304805bbe1e359f6389633036a98 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 17 Jul 2005 09:40:29 -0400 Subject: [PATCH 1394/4284] add padding to rules structure Some architectures really want well alingned structures. Thanks to Jim Gifford for help finding it. Signed-off-by: Kay Sievers --- extras/usb_id/usb_id.c | 3 --- udev_rules_parse.c | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index f4011ee899..ab116e9d03 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -497,6 +497,3 @@ int main(int argc, char **argv) } exit(retval); } - - - diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 0259268c8f..e708f35558 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -241,6 +241,7 @@ static int add_to_rules(struct udev_rules *rules, char *line) int valid; char *linepos; char *attr; + size_t padding; int retval; /* get all the keys */ @@ -506,6 +507,11 @@ static int add_to_rules(struct udev_rules *rules, char *line) /* 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"); From 6a5aac78f4d04490fc1d0178b1d7c0cb415c2944 Mon Sep 17 00:00:00 2001 From: Andre Masella Date: Sun, 17 Jul 2005 09:54:40 -0400 Subject: [PATCH 1395/4284] volume_id: add OCFS (Oracle Cluster File System) support --- extras/volume_id/Makefile | 3 +- extras/volume_id/volume_id/Makefile.inc | 2 + extras/volume_id/volume_id/ocfs2.c | 125 ++++++++++++++++++++++++ extras/volume_id/volume_id/ocfs2.h | 26 +++++ extras/volume_id/volume_id/volume_id.c | 4 + extras/volume_id/volume_id/volume_id.h | 2 +- 6 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 extras/volume_id/volume_id/ocfs2.c create mode 100644 extras/volume_id/volume_id/ocfs2.h diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index eca9cfdbd4..014bf8713d 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -33,7 +33,8 @@ override CFLAGS+=-D_FILE_OFFSET_BITS=64 VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc -OBJS = vol_id.o $(VOLUME_ID_OBJS) ../../udev.a +OBJS = vol_id.o $(VOLUME_ID_OBJS) +LIB_OBJS=../../udev.a HEADERS = $(VOLUME_ID_HEADERS) $(OBJS): $(HEADERS) diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index 266d1e4872..71f4ea2862 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -27,6 +27,7 @@ VOLUME_ID_OBJS= \ $(VOLUME_ID_BASE)/sysv.o \ $(VOLUME_ID_BASE)/minix.o \ $(VOLUME_ID_BASE)/luks.o \ + $(VOLUME_ID_BASE)/ocfs2.o \ $(VOLUME_ID_BASE)/volume_id.o \ $(VOLUME_ID_BASE)/util.o @@ -58,5 +59,6 @@ VOLUME_ID_HEADERS= \ $(VOLUME_ID_BASE)/sysv.h \ $(VOLUME_ID_BASE)/minix.h \ $(VOLUME_ID_BASE)/luks.h \ + $(VOLUME_ID_BASE)/ocfs2.h \ $(VOLUME_ID_BASE)/volume_id.h \ $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c new file mode 100644 index 0000000000..1f2819c0cc --- /dev/null +++ b/extras/volume_id/volume_id/ocfs2.c @@ -0,0 +1,125 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) Andre Masella + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "volume_id.h" +#include "logging.h" +#include "util.h" +#include "ocfs2.h" + + +/* All these values are taken from ocfs2-tools's ocfs2_fs.h */ +#define OCFS2_VOL_UUID_LEN 16 +#define OCFS2_MAX_VOL_LABEL_LEN 64 +#define OCFS2_SUPERBLOCK_OFFSET 0x2000 + + +/* This is the superblock. The OCFS2 header files have structs in structs. +This is one has been simplified since we only care about the superblock. +*/ + +struct ocfs2_super_block { + __u8 i_signature[8]; /* Signature for validation */ + __u32 i_generation; /* Generation number */ + __s16 i_suballoc_slot; /* Slot suballocator this inode belongs to */ + __u16 i_suballoc_bit; /* Bit offset in suballocator block group */ + __u32 i_reserved0; + __u32 i_clusters; /* Cluster count */ + __u32 i_uid; /* Owner UID */ + __u32 i_gid; /* Owning GID */ + __u64 i_size; /* Size in bytes */ + __u16 i_mode; /* File mode */ + __u16 i_links_count; /* Links count */ + __u32 i_flags; /* File flags */ + __u64 i_atime; /* Access time */ + __u64 i_ctime; /* Creation time */ + __u64 i_mtime; /* Modification time */ + __u64 i_dtime; /* Deletion time */ + __u64 i_blkno; /* Offset on disk, in blocks */ + __u64 i_last_eb_blk; /* Pointer to last extent block */ + __u32 i_fs_generation; /* Generation per fs-instance */ + __u32 i_atime_nsec; + __u32 i_ctime_nsec; + __u32 i_mtime_nsec; + __u64 i_reserved1[9]; + __u64 i_pad1; /* Generic way to refer to this 64bit union */ + /* Normally there is a union of the different block types, but we only care about the superblock. */ + __u16 s_major_rev_level; + __u16 s_minor_rev_level; + __u16 s_mnt_count; + __s16 s_max_mnt_count; + __u16 s_state; /* File system state */ + __u16 s_errors; /* Behaviour when detecting errors */ + __u32 s_checkinterval; /* Max time between checks */ + __u64 s_lastcheck; /* Time of last check */ + __u32 s_creator_os; /* OS */ + __u32 s_feature_compat; /* Compatible feature set */ + __u32 s_feature_incompat; /* Incompatible feature set */ + __u32 s_feature_ro_compat; /* Readonly-compatible feature set */ + __u64 s_root_blkno; /* Offset, in blocks, of root directory dinode */ + __u64 s_system_dir_blkno; /* Offset, in blocks, of system directory dinode */ + __u32 s_blocksize_bits; /* Blocksize for this fs */ + __u32 s_clustersize_bits; /* Clustersize for this fs */ + __u16 s_max_slots; /* Max number of simultaneous mounts before tunefs required */ + __u16 s_reserved1; + __u32 s_reserved2; + __u64 s_first_cluster_group; /* Block offset of 1st cluster group header */ + __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ + __u8 s_uuid[OCFS2_VOL_UUID_LEN]; /* 128-bit uuid */ +} __attribute__((__packed__)); + +int volume_id_probe_ocfs2(struct volume_id *id, __u64 off) +{ + struct ocfs2_super_block *os; + + dbg("probing at offset 0x%llx", (unsigned long long) off); + + os = (struct ocsf2_super_block *) volume_id_get_buffer(id, off + OCFS2_SUPERBLOCK_OFFSET, 0x200); + if (os == NULL) + return -1; + + if (strcmp(os->i_signature, "OCFSV2") != 0) { + return -1; + } + + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + volume_id_set_label_raw(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ? + OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE); + volume_id_set_label_string(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ? + OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE); + volume_id_set_uuid(id, os->s_uuid, UUID_DCE); + id->type = "ocfs2"; + return 0; +} diff --git a/extras/volume_id/volume_id/ocfs2.h b/extras/volume_id/volume_id/ocfs2.h new file mode 100644 index 0000000000..128348133c --- /dev/null +++ b/extras/volume_id/volume_id/ocfs2.h @@ -0,0 +1,26 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) Andre Masella + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _VOLUME_ID_OCFS2_ +#define _VOLUME_ID_OCFS2_ + +extern int volume_id_probe_ocfs2(struct volume_id *id, __u64 off); + +#endif diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 3fe8562e33..8e944be0b1 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -69,6 +69,7 @@ #include "minix.h" #include "mac.h" #include "msdos.h" +#include "ocfs2.h" int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size) { @@ -169,6 +170,9 @@ int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned l if (volume_id_probe_minix(id, off) == 0) goto exit; + if (volume_id_probe_ocfs2(id, off) == 0) + goto exit; + return -1; exit: diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index c6aef50876..4e0defdadd 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 45 +#define VOLUME_ID_VERSION 46 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From bf375e3af65f0e9728516a3627613fb95288c1d1 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 19 Jul 2005 11:14:12 -0400 Subject: [PATCH 1396/4284] create_floppy_devices: add tool to create floppy nodes based on sysfs info --- extras/floppy/Makefile | 52 ++++++++++ extras/floppy/create_floppy_devices.c | 136 ++++++++++++++++++++++++++ test/simple-build-check.sh | 1 + 3 files changed, 189 insertions(+) create mode 100644 extras/floppy/Makefile create mode 100644 extras/floppy/create_floppy_devices.c diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile new file mode 100644 index 0000000000..2601eeeb55 --- /dev/null +++ b/extras/floppy/Makefile @@ -0,0 +1,52 @@ +# Makefile for create_floppy_devices +# +# 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. +# + +PROG = create_floppy_devices + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +CFLAGS+=-D_FILE_OFFSET_BITS=64 + +OBJS = $(PROG).o ../../udev.a + +$(OBJS): $(HEADERS) + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(PROG): $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/floppy/create_floppy_devices.c b/extras/floppy/create_floppy_devices.c new file mode 100644 index 0000000000..f4003c2ce2 --- /dev/null +++ b/extras/floppy/create_floppy_devices.c @@ -0,0 +1,136 @@ +/* + * 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 + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Hannes Reinecke + * + */ + +#include +#include +#include +#include +#include +#include +#include + +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 }; +static int t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23 }; +static int t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, 17, 21, 22, 30 }; + +static int *table_sup[] = { NULL, t360, t1200, t3in + 5 + 8, t3in + 5, t3in, t3in }; + +int main(int argc, char **argv) +{ + char *dev; + char node[64]; + int type = 0, i, fdnum, c; + int major = 2, minor; + int mode = 0; + int create_nodes = 0; + int print_nodes = 0; + int unlink_nodes = 0; + int is_err = 0; + + while ((c = getopt(argc, argv, "cdm:M:t:u")) != -1) { + switch (c) { + case 'c': + create_nodes = 1; + unlink_nodes = 0; + break; + case 'd': + print_nodes = 1; + break; + case 'M': + mode = strtol(optarg, NULL, 10); + break; + case 'm': + major = strtol(optarg, NULL, 10); + break; + case 't': + type = strtol(optarg, NULL, 10); + break; + case 'u': + unlink_nodes = 1; + create_nodes = 0; + break; + default: + is_err++; + break; + } + } + + if (is_err || optind >= argc) { + fprintf(stderr,"Usage: %s [-d|-c|-u|-m |-t ] \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; + + 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) + mknod(node, S_IFBLK | mode, makedev(major,minor)); + i++; + } + + return 0; +} + diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 7e9a940f85..742b28ec1c 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -7,6 +7,7 @@ EXTRAS="\ extras/volume_id \ extras/usb_id \ extras/dasd_id \ + extras/floppy \ extras/run_directory" [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build From 46f01c6dc44ba516e42d5c8c1ada98a743f916f2 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 19 Jul 2005 11:18:19 -0400 Subject: [PATCH 1397/4284] add ID_BUS to *_id programs --- extras/ata_id/ata_id.c | 1 + extras/dasd_id/dasd_id.c | 1 + extras/scsi_id/scsi_id.c | 1 + extras/usb_id/usb_id.c | 1 + 4 files changed, 4 insertions(+) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index 9df0fdb107..1e99b9df9c 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -169,6 +169,7 @@ int main(int argc, char *argv[]) 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); diff --git a/extras/dasd_id/dasd_id.c b/extras/dasd_id/dasd_id.c index 5c2143f45d..e2df65d6ec 100644 --- a/extras/dasd_id/dasd_id.c +++ b/extras/dasd_id/dasd_id.c @@ -262,6 +262,7 @@ int main(int argc, char *argv[]) if (export) { printf("ID_TYPE=disk\n"); printf("ID_SERIAL=%s\n",serial); + printf("ID_BUS=ccw\n"); } else printf("%s\n", serial); diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index cbefb445df..1b4234a40e 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -827,6 +827,7 @@ static int scsi_id(const char *target_path, char *maj_min_dev) set_str(serial_str, serial, sizeof(serial_str)); printf("ID_SERIAL=%s\n", serial_str); printf("ID_TYPE=%s\n", type_str); + printf("ID_BUS=scsi\n"); } else { if (reformat_serial) format_serial(serial); diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index ab116e9d03..1eb45b9114 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -485,6 +485,7 @@ int main(int argc, char **argv) vendor_str, model_str, serial_str); } printf("ID_TYPE=%s\n", type_str); + printf("ID_BUS=usb\n"); } else { if (serial_str[0] == '\0') { printf("%s_%s\n", From 33aa91b1befa3e4f8da57714ac09b7044cf54451 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 19 Jul 2005 14:36:34 -0400 Subject: [PATCH 1398/4284] usb_id: fix typo --- extras/scsi_id/scsi_id.8 | 4 ++++ extras/usb_id/usb_id.c | 4 ++-- extras/volume_id/volume_id/ocfs2.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index 68d4a1c041..26df0d3e66 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -58,6 +58,10 @@ leading \-, runs in a hotplug mode, and expects the environment variable DEVPATH to specify the corresponding sysfs device. See section below on usage with \fBudev\fP. .TP +.BI \-a +Always print information (model, vendor strings) about the device even +if it does not support VPD pages. +.TP .BI \-b 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. diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index 1eb45b9114..720a0f5df7 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -316,11 +316,11 @@ static int usb_id(const char *target_path) /* usb device directory */ usb_dev = sysfs_get_device_parent(interface_dev); - if (!strcmp(interface_dev->bus, "bus") != 0) { + if (strcmp(interface_dev->bus, "usb") != 0) { info("%s is not an usb device", target_path); return 1; } - + if_class = sysfs_get_device_attr(interface_dev, "bInterfaceClass"); if (!if_class) { info("%s: cannot get bInterfaceClass attribute", interface_dev->name); diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c index 1f2819c0cc..90a6bd531c 100644 --- a/extras/volume_id/volume_id/ocfs2.c +++ b/extras/volume_id/volume_id/ocfs2.c @@ -51,7 +51,7 @@ This is one has been simplified since we only care about the superblock. */ struct ocfs2_super_block { - __u8 i_signature[8]; /* Signature for validation */ + __u8 i_signature[8]; /* Signature for validation */ __u32 i_generation; /* Generation number */ __s16 i_suballoc_slot; /* Slot suballocator this inode belongs to */ __u16 i_suballoc_bit; /* Bit offset in suballocator block group */ From 761e5b476f8e69f41958a62ed787f5d886fa212e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 20 Jul 2005 12:12:56 -0400 Subject: [PATCH 1399/4284] make SYSFS{} usable for all devices Patch from: Hannes Reinecke --- udev.c | 12 +++++++----- udev_rules.c | 22 +++++++++++++++++++--- udev_rules.h | 6 ++++-- udevd.c | 1 + 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/udev.c b/udev.c index d44f73081d..6e0f7f1d0c 100644 --- a/udev.c +++ b/udev.c @@ -147,27 +147,29 @@ int main(int argc, char *argv[], char *envp[]) udev_rules_get_name(&rules, &udev, class_dev); if (udev.ignore_device) { info("device event will be ignored"); + sysfs_close_class_device(class_dev); goto cleanup; } if (udev.name[0] == '\0') { info("device node creation supressed"); + sysfs_close_class_device(class_dev); goto cleanup; } - /* create node, store in db */ retval = udev_add_device(&udev, class_dev); } else { dbg("no dev-file found"); - udev_rules_get_run(&rules, &udev, NULL); + udev_rules_get_run(&rules, &udev, class_dev, NULL); if (udev.ignore_device) { info("device event will be ignored"); + sysfs_close_class_device(class_dev); goto cleanup; } } sysfs_close_class_device(class_dev); } else if (strcmp(action, "remove") == 0) { dbg("node remove"); - udev_rules_get_run(&rules, &udev, NULL); + udev_rules_get_run(&rules, &udev, NULL, NULL); if (udev.ignore_device) { dbg("device event will be ignored"); goto cleanup; @@ -194,7 +196,7 @@ int main(int argc, char *argv[], char *envp[]) } dbg("devices device opened '%s'", path); wait_for_devices_device(devices_dev, &error); - udev_rules_get_run(&rules, &udev, devices_dev); + udev_rules_get_run(&rules, &udev, NULL, devices_dev); sysfs_close_device(devices_dev); if (udev.ignore_device) { info("device event will be ignored"); @@ -202,7 +204,7 @@ int main(int argc, char *argv[], char *envp[]) } } else { dbg("default handling"); - udev_rules_get_run(&rules, &udev, NULL); + udev_rules_get_run(&rules, &udev, NULL, NULL); if (udev.ignore_device) { info("device event will be ignored"); goto cleanup; diff --git a/udev_rules.c b/udev_rules.c index 939febe8f6..6cbaa781f6 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -1091,10 +1091,21 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s return 0; } -int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device) +int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, + struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev) { struct udev_rule *rule; + if (class_dev && !sysfs_dev) + sysfs_dev = sysfs_get_classdev_device(class_dev); + if (sysfs_dev) { + dbg("found devices device: path='%s', bus_id='%s', bus='%s'", + sysfs_dev->path, sysfs_dev->bus_id, sysfs_dev->bus); + strlcpy(udev->bus_id, sysfs_dev->bus_id, sizeof(udev->bus_id)); + } + + dbg("udev->kernel_name='%s'", udev->kernel_name); + /* look for a matching rule to apply */ udev_rules_iter_init(rules); while (1) { @@ -1109,7 +1120,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sy continue; } - if (match_rule(udev, rule, NULL, sysfs_device) == 0) { + if (match_rule(udev, rule, class_dev, sysfs_dev) == 0) { if (rule->ignore_device) { info("rule applied, '%s' is ignored", udev->kernel_name); udev->ignore_device = 1; @@ -1130,7 +1141,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sy } } strlcpy(program, key_val(rule, &rule->run), sizeof(program)); - apply_format(udev, program, sizeof(program), NULL, sysfs_device); + apply_format(udev, program, sizeof(program), class_dev, sysfs_dev); dbg("add run '%s'", program); name_list_add(&udev->run_list, program, 0); if (rule->run.operation == KEY_OP_ASSIGN_FINAL) @@ -1141,6 +1152,11 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sy 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)); + } } } diff --git a/udev_rules.h b/udev_rules.h index d22d31f7e1..bfcb3f23d5 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -112,7 +112,9 @@ 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, struct sysfs_class_device *class_dev); -extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, struct sysfs_device *sysfs_device); +extern int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, + struct sysfs_class_device *class_dev); +extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, + struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev); #endif diff --git a/udevd.c b/udevd.c index 110d8e7c4d..be401bec30 100644 --- a/udevd.c +++ b/udevd.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "list.h" From e8d569b4145a358775e87058829133fa725b32fd Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 22 Jul 2005 12:35:58 -0400 Subject: [PATCH 1400/4284] move code to its own files Signed-off-by: Kay Sievers --- Makefile | 48 +++++++------- extras/usb_id/Makefile | 2 +- udev.c | 102 ++--------------------------- udev.h | 7 +- udev.spec | 7 +- udev_add.c | 4 +- udev_config.c | 4 +- udev_db.c | 2 - udev_db.h | 4 +- udev_device.c | 121 +++++++++++++++++++++++++++++++++++ udev_event.c | 141 +++++++++++++++++++++++++++++++++++++++++ udev_remove.c | 4 +- udev_rules.c | 56 ---------------- udev_rules.h | 8 ++- udev_rules_parse.c | 3 - udev_utils.c | 125 ++++++++++++++---------------------- udev_utils.h | 14 ++-- udevcontrol.c | 3 - udevd.h | 5 +- udeveventrecorder.c | 6 +- udevinfo.c | 2 +- udevinitsend.c | 6 +- udevsend.c | 3 - udevstart.c | 10 +-- udevtest.c | 4 +- 25 files changed, 380 insertions(+), 311 deletions(-) create mode 100644 udev_device.c create mode 100644 udev_event.c diff --git a/Makefile b/Makefile index b740838ace..881ef85ad6 100644 --- a/Makefile +++ b/Makefile @@ -115,34 +115,36 @@ CFLAGS += -D_GNU_SOURCE OPTFLAGS := $(call cc-supports, -Os, -O2) HEADERS = \ - udev.h \ - udev_utils.h \ - udev_rules.h \ - udev_version.h \ - udev_db.h \ - udev_sysfs.h \ - logging.h \ - udev_libc_wrapper.h \ - udev_selinux.h \ + udev.h \ + udev_utils.h \ + udev_rules.h \ + udev_version.h \ + udev_db.h \ + udev_sysfs.h \ + logging.h \ + udev_libc_wrapper.h \ + udev_selinux.h \ list.h SYSFS_OBJS = \ - libsysfs/sysfs_class.o \ - libsysfs/sysfs_device.o \ - libsysfs/sysfs_dir.o \ - libsysfs/sysfs_driver.o \ - libsysfs/sysfs_utils.o \ + libsysfs/sysfs_class.o \ + libsysfs/sysfs_device.o \ + libsysfs/sysfs_dir.o \ + libsysfs/sysfs_driver.o \ + libsysfs/sysfs_utils.o \ libsysfs/dlist.o UDEV_OBJS = \ - udev_utils.o \ - udev_config.o \ - udev_add.o \ - udev_remove.o \ - udev_sysfs.o \ - udev_db.o \ - udev_rules.o \ - udev_rules_parse.o \ + udev_utils.o \ + udev_event.o \ + udev_device.o \ + udev_config.o \ + udev_add.o \ + udev_remove.o \ + udev_sysfs.o \ + udev_db.o \ + udev_rules.o \ + udev_rules_parse.o \ udev_libc_wrapper.o OBJS = \ @@ -151,7 +153,7 @@ OBJS = \ SYSFS = $(PWD)/libsysfs/sysfs.a -CFLAGS += -I$(PWD)/libsysfs/sysfs \ +CFLAGS += -I$(PWD)/libsysfs/sysfs \ -I$(PWD)/libsysfs ifeq ($(strip $(USE_LOG)),true) diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index 4324f95c76..e319a4fee8 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-D_FILE_OFFSET_BITS=64 +CFLAGS+=-D_FILE_OFFSET_BITS=64 OBJS = $(PROG).o $(VOLUME_ID_OBJS) ../../udev.a ../../libsysfs/sysfs.a HEADERS = diff --git a/udev.c b/udev.c index 6e0f7f1d0c..4096b8b348 100644 --- a/udev.c +++ b/udev.c @@ -1,10 +1,8 @@ /* * udev.c * - * Userspace devfs - * - * Copyright (C) 2003,2004 Greg Kroah-Hartman - * Copyright (C) 2004 Kay Sievers + * 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 @@ -69,8 +67,6 @@ int main(int argc, char *argv[], char *envp[]) { struct udevice udev; struct udev_rules rules; - char path[PATH_SIZE]; - const char *error; const char *action; const char *devpath; const char *subsystem; @@ -121,98 +117,9 @@ int main(int argc, char *argv[], char *envp[]) udev_init_device(&udev, devpath, subsystem, action); udev_rules_init(&rules, 0); - if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS || udev.type == DEV_NET) { - /* handle device node */ - if (strcmp(action, "add") == 0) { - struct sysfs_class_device *class_dev; + retval = udev_process_event(&rules, &udev); - /* wait for sysfs of /sys/class /sys/block */ - dbg("node add"); - snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath); - path[sizeof(path)-1] = '\0'; - class_dev = wait_class_device_open(path); - if (class_dev == NULL) { - dbg("open class device failed"); - goto run; - } - dbg("opened class_dev->name='%s'", class_dev->name); - wait_for_class_device(class_dev, &error); - - /* get major/minor */ - if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS) - udev.devt = get_devt(class_dev); - - if (udev.type == DEV_NET || udev.devt) { - /* name device */ - udev_rules_get_name(&rules, &udev, class_dev); - if (udev.ignore_device) { - info("device event will be ignored"); - sysfs_close_class_device(class_dev); - goto cleanup; - } - if (udev.name[0] == '\0') { - info("device node creation supressed"); - sysfs_close_class_device(class_dev); - goto cleanup; - } - /* create node, store in db */ - retval = udev_add_device(&udev, class_dev); - } else { - dbg("no dev-file found"); - udev_rules_get_run(&rules, &udev, class_dev, NULL); - if (udev.ignore_device) { - info("device event will be ignored"); - sysfs_close_class_device(class_dev); - goto cleanup; - } - } - sysfs_close_class_device(class_dev); - } else if (strcmp(action, "remove") == 0) { - dbg("node remove"); - udev_rules_get_run(&rules, &udev, NULL, NULL); - if (udev.ignore_device) { - dbg("device event will be ignored"); - goto cleanup; - } - - /* get name from db, remove db-entry, delete node */ - retval = udev_remove_device(&udev); - } - - /* export name of device node or netif */ - if (udev.devname[0] != '\0') - setenv("DEVNAME", udev.devname, 1); - } else if (udev.type == DEV_DEVICE && strcmp(action, "add") == 0) { - struct sysfs_device *devices_dev; - - /* wait for sysfs of /sys/devices/ */ - dbg("devices add"); - snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); - path[sizeof(path)-1] = '\0'; - devices_dev = wait_devices_device_open(path); - if (!devices_dev) { - dbg("devices device unavailable (probably remove has beaten us)"); - goto run; - } - dbg("devices device opened '%s'", path); - wait_for_devices_device(devices_dev, &error); - udev_rules_get_run(&rules, &udev, NULL, devices_dev); - sysfs_close_device(devices_dev); - if (udev.ignore_device) { - info("device event will be ignored"); - goto cleanup; - } - } else { - dbg("default handling"); - udev_rules_get_run(&rules, &udev, NULL, NULL); - if (udev.ignore_device) { - info("device event will be ignored"); - goto cleanup; - } - } - -run: - if (udev_run && !list_empty(&udev.run_list)) { + if (!retval && udev_run && !list_empty(&udev.run_list)) { struct name_entry *name_loop; dbg("executing run list"); @@ -220,7 +127,6 @@ run: execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); } -cleanup: udev_cleanup_device(&udev); exit: diff --git a/udev.h b/udev.h index 391dc2c41c..66edfd66bf 100644 --- a/udev.h +++ b/udev.h @@ -1,8 +1,6 @@ /* * udev.h * - * Userspace devfs - * * Copyright (C) 2003 Greg Kroah-Hartman * Copyright (C) 2003-2005 Kay Sievers * @@ -40,6 +38,8 @@ #define DEFAULT_PARTITIONS_COUNT 15 #define UDEV_ALARM_TIMEOUT 120 +struct udev_rules; + enum device_type { DEV_UNKNOWN, DEV_CLASS, @@ -82,6 +82,9 @@ struct udevice { int test_run; }; +extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action); +extern void udev_cleanup_device(struct udevice *udev); +extern int udev_process_event(struct udev_rules *rules, struct udevice *udev); extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev); extern int udev_remove_device(struct udevice *udev); extern void udev_init_config(void); diff --git a/udev.spec b/udev.spec index 22d9160529..09f95f1317 100644 --- a/udev.spec +++ b/udev.spec @@ -27,7 +27,7 @@ # 1 - build it %define volume_id 1 -Summary: A userspace implementation of devfs +Summary: A userspace device manager providing devfs functionality Name: udev Version: 063 Release: 1 @@ -41,8 +41,9 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root Prereq: /bin/sh, fileutils, hotplug %description -udev is a implementation of devfs in userspace using sysfs and -/sbin/hotplug. It requires a 2.6 kernel to run properly. +udev is a userspace device manager, using sysfs and uevents +to provide a devfs-like device directory management and uevent +dispatching. %prep %setup -q diff --git a/udev_add.c b/udev_add.c index e9ae150180..9d872bf039 100644 --- a/udev_add.c +++ b/udev_add.c @@ -1,10 +1,8 @@ /* * udev-add.c * - * Userspace devfs - * * Copyright (C) 2003 Greg Kroah-Hartman - * + * 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 diff --git a/udev_config.c b/udev_config.c index 773ee67f9e..c57e36cd8c 100644 --- a/udev_config.c +++ b/udev_config.c @@ -1,10 +1,8 @@ /* * udev_config.c * - * Userspace devfs - * * 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 diff --git a/udev_db.c b/udev_db.c index 6f10b1e58d..ef0e9a71ae 100644 --- a/udev_db.c +++ b/udev_db.c @@ -1,8 +1,6 @@ /* * udev_db.c * - * Userspace devfs - * * Copyright (C) 2003 Greg Kroah-Hartman * Copyright (C) 2004-2005 Kay Sievers * diff --git a/udev_db.h b/udev_db.h index 9420981944..b961c87102 100644 --- a/udev_db.h +++ b/udev_db.h @@ -1,10 +1,8 @@ /* * udev_db.h * - * Userspace devfs - * * Copyright (C) 2003 Greg Kroah-Hartman - * Copyright (C) 2004 Kay Sievers + * 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 diff --git a/udev_device.c b/udev_device.c new file mode 100644 index 0000000000..45bb6a2876 --- /dev/null +++ b/udev_device.c @@ -0,0 +1,121 @@ +/* + * udev_utils.c - generic stuff used by udev + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev_libc_wrapper.h" +#include "udev.h" +#include "logging.h" +#include "udev_utils.h" +#include "udev_sysfs.h" +#include "list.h" + + +int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action) +{ + char *pos; + + memset(udev, 0x00, sizeof(struct udevice)); + INIT_LIST_HEAD(&udev->symlink_list); + INIT_LIST_HEAD(&udev->run_list); + INIT_LIST_HEAD(&udev->env_list); + + if (subsystem) + strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem)); + + if (action) + strlcpy(udev->action, action, sizeof(udev->action)); + + if (devpath) { + strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); + remove_trailing_char(udev->devpath, '/'); + + if (strncmp(udev->devpath, "/block/", 7) == 0) + udev->type = DEV_BLOCK; + else if (strncmp(udev->devpath, "/class/net/", 11) == 0) + udev->type = DEV_NET; + else if (strncmp(udev->devpath, "/class/", 7) == 0) + udev->type = DEV_CLASS; + else if (strncmp(udev->devpath, "/devices/", 9) == 0) + udev->type = DEV_DEVICE; + + /* get kernel name */ + pos = strrchr(udev->devpath, '/'); + if (pos) { + strlcpy(udev->kernel_name, &pos[1], sizeof(udev->kernel_name)); + dbg("kernel_name='%s'", udev->kernel_name); + + /* Some block devices have '!' in their name, change that to '/' */ + pos = udev->kernel_name; + while (pos[0] != '\0') { + if (pos[0] == '!') + pos[0] = '/'; + pos++; + } + + /* get kernel number */ + pos = &udev->kernel_name[strlen(udev->kernel_name)]; + while (isdigit(pos[-1])) + pos--; + strlcpy(udev->kernel_number, pos, sizeof(udev->kernel_number)); + dbg("kernel_number='%s'", udev->kernel_number); + } + } + + if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { + udev->mode = 0660; + strcpy(udev->owner, "root"); + strcpy(udev->group, "root"); + } + + return 0; +} + +void udev_cleanup_device(struct udevice *udev) +{ + struct name_entry *name_loop; + struct name_entry *temp_loop; + + list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { + list_del(&name_loop->node); + free(name_loop); + } + list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { + list_del(&name_loop->node); + free(name_loop); + } + list_for_each_entry_safe(name_loop, temp_loop, &udev->env_list, node) { + list_del(&name_loop->node); + free(name_loop); + } +} diff --git a/udev_event.c b/udev_event.c new file mode 100644 index 0000000000..8a3ed29315 --- /dev/null +++ b/udev_event.c @@ -0,0 +1,141 @@ +/* + * udev_event.c - udev event process + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev_libc_wrapper.h" +#include "udev.h" +#include "logging.h" +#include "udev_rules.h" +#include "udev_utils.h" +#include "udev_sysfs.h" +#include "list.h" + + +int udev_process_event(struct udev_rules *rules, struct udevice *udev) +{ + int retval; + char path[PATH_SIZE]; + const char *error; + + if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS || udev->type == DEV_NET) { + /* handle device node */ + if (strcmp(udev->action, "add") == 0) { + struct sysfs_class_device *class_dev; + + /* wait for sysfs of /sys/class /sys/block */ + dbg("node add"); + snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); + path[sizeof(path)-1] = '\0'; + class_dev = wait_class_device_open(path); + if (class_dev == NULL) { + dbg("open class device failed"); + return 0; + } + dbg("opened class_dev->name='%s'", class_dev->name); + wait_for_class_device(class_dev, &error); + + /* get major/minor */ + if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) + udev->devt = get_devt(class_dev); + + if (udev->type == DEV_NET || udev->devt) { + /* name device */ + udev_rules_get_name(rules, udev, class_dev); + if (udev->ignore_device) { + info("device event will be ignored"); + sysfs_close_class_device(class_dev); + return -1; + } + if (udev->name[0] == '\0') { + info("device node creation supressed"); + sysfs_close_class_device(class_dev); + return -1; + } + /* create node, store in db */ + retval = udev_add_device(udev, class_dev); + } else { + dbg("no dev-file found"); + udev_rules_get_run(rules, udev, class_dev, NULL); + if (udev->ignore_device) { + info("device event will be ignored"); + sysfs_close_class_device(class_dev); + return -1; + } + } + sysfs_close_class_device(class_dev); + } else if (strcmp(udev->action, "remove") == 0) { + dbg("node remove"); + udev_rules_get_run(rules, udev, NULL, NULL); + if (udev->ignore_device) { + dbg("device event will be ignored"); + return -1; + } + + /* get name from db, remove db-entry, delete node */ + retval = udev_remove_device(udev); + } + + /* export name of device node or netif */ + if (udev->devname[0] != '\0') + setenv("DEVNAME", udev->devname, 1); + } else if (udev->type == DEV_DEVICE && strcmp(udev->action, "add") == 0) { + struct sysfs_device *devices_dev; + + /* wait for sysfs of /sys/devices/ */ + dbg("devices add"); + snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); + path[sizeof(path)-1] = '\0'; + devices_dev = wait_devices_device_open(path); + if (!devices_dev) { + dbg("devices device unavailable (probably remove has beaten us)"); + return 0; + } + dbg("devices device opened '%s'", path); + wait_for_devices_device(devices_dev, &error); + udev_rules_get_run(rules, udev, NULL, devices_dev); + sysfs_close_device(devices_dev); + if (udev->ignore_device) { + info("device event will be ignored"); + return -1; + } + } else { + dbg("default handling"); + udev_rules_get_run(rules, udev, NULL, NULL); + if (udev->ignore_device) { + info("device event will be ignored"); + return -1; + } + } + return 0; +} diff --git a/udev_remove.c b/udev_remove.c index b9a4384ee0..28885d4710 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -1,10 +1,8 @@ /* * udev-remove.c * - * Userspace devfs - * * Copyright (C) 2003 Greg Kroah-Hartman - * + * 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 diff --git a/udev_rules.c b/udev_rules.c index 6cbaa781f6..6a485f08af 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -1,12 +1,9 @@ /* * udev_rules.c * - * Userspace devfs - * * Copyright (C) 2003 Greg Kroah-Hartman * Copyright (C) 2003-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. @@ -44,59 +41,6 @@ #include "udev_db.h" -/* compare string with pattern (supports * ? [0-9] [!A-Z]) */ -static int strcmp_pattern(const char *p, const char *s) -{ - if (s[0] == '\0') { - while (p[0] == '*') - p++; - return (p[0] != '\0'); - } - switch (p[0]) { - case '[': - { - int not = 0; - p++; - if (p[0] == '!') { - not = 1; - p++; - } - while ((p[0] != '\0') && (p[0] != ']')) { - int match = 0; - if (p[1] == '-') { - if ((s[0] >= p[0]) && (s[0] <= p[2])) - match = 1; - p += 3; - } else { - match = (p[0] == s[0]); - p++; - } - if (match ^ not) { - while ((p[0] != '\0') && (p[0] != ']')) - p++; - if (p[0] == ']') - return strcmp_pattern(p+1, s+1); - } - } - } - break; - case '*': - if (strcmp_pattern(p, s+1)) - return strcmp_pattern(p+1, s); - return 0; - case '\0': - if (s[0] == '\0') { - return 0; - } - break; - default: - if ((p[0] == s[0]) || (p[0] == '?')) - return strcmp_pattern(p+1, s+1); - break; - } - return 1; -} - /* extract possible {attr} and move str behind it */ static char *get_format_attribute(char **str) { diff --git a/udev_rules.h b/udev_rules.h index bfcb3f23d5..9e3931129f 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -1,9 +1,8 @@ /* * udev_rules.h * - * Userspace devfs - * - * Copyright (C) 2003,2004 Greg Kroah-Hartman + * 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 @@ -108,6 +107,9 @@ struct udev_rules { extern int udev_rules_init(struct udev_rules *rules, int resolve_names); extern void udev_rules_close(struct udev_rules *rules); +extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize, + struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device); + 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); diff --git a/udev_rules_parse.c b/udev_rules_parse.c index e708f35558..be0757374e 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -1,12 +1,9 @@ /* * udev_rules_parse.c * - * Userspace devfs - * * Copyright (C) 2003,2004 Greg Kroah-Hartman * Copyright (C) 2003-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. diff --git a/udev_utils.c b/udev_utils.c index 073cde1074..2524baf592 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -1,7 +1,7 @@ /* - * udev_lib - generic stuff used by udev + * udev_utils.c - generic stuff used by udev * - * Copyright (C) 2004 Kay Sievers + * 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 @@ -39,84 +39,57 @@ #include "udev_utils.h" #include "list.h" - -int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action) +/* compare string with pattern (supports * ? [0-9] [!A-Z]) */ +int strcmp_pattern(const char *p, const char *s) { - char *pos; - - memset(udev, 0x00, sizeof(struct udevice)); - INIT_LIST_HEAD(&udev->symlink_list); - INIT_LIST_HEAD(&udev->run_list); - INIT_LIST_HEAD(&udev->env_list); - - if (subsystem) - strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem)); - - if (action) - strlcpy(udev->action, action, sizeof(udev->action)); - - if (devpath) { - strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); - remove_trailing_char(udev->devpath, '/'); - - if (strncmp(udev->devpath, "/block/", 7) == 0) - udev->type = DEV_BLOCK; - else if (strncmp(udev->devpath, "/class/net/", 11) == 0) - udev->type = DEV_NET; - else if (strncmp(udev->devpath, "/class/", 7) == 0) - udev->type = DEV_CLASS; - else if (strncmp(udev->devpath, "/devices/", 9) == 0) - udev->type = DEV_DEVICE; - - /* get kernel name */ - pos = strrchr(udev->devpath, '/'); - if (pos) { - strlcpy(udev->kernel_name, &pos[1], sizeof(udev->kernel_name)); - dbg("kernel_name='%s'", udev->kernel_name); - - /* Some block devices have '!' in their name, change that to '/' */ - pos = udev->kernel_name; - while (pos[0] != '\0') { - if (pos[0] == '!') - pos[0] = '/'; - pos++; + if (s[0] == '\0') { + while (p[0] == '*') + p++; + return (p[0] != '\0'); + } + switch (p[0]) { + case '[': + { + int not = 0; + p++; + if (p[0] == '!') { + not = 1; + p++; + } + while ((p[0] != '\0') && (p[0] != ']')) { + int match = 0; + if (p[1] == '-') { + if ((s[0] >= p[0]) && (s[0] <= p[2])) + match = 1; + p += 3; + } else { + match = (p[0] == s[0]); + p++; + } + if (match ^ not) { + while ((p[0] != '\0') && (p[0] != ']')) + p++; + if (p[0] == ']') + return strcmp_pattern(p+1, s+1); + } } - - /* get kernel number */ - pos = &udev->kernel_name[strlen(udev->kernel_name)]; - while (isdigit(pos[-1])) - pos--; - strlcpy(udev->kernel_number, pos, sizeof(udev->kernel_number)); - dbg("kernel_number='%s'", udev->kernel_number); } + break; + case '*': + if (strcmp_pattern(p, s+1)) + return strcmp_pattern(p+1, s); + return 0; + case '\0': + if (s[0] == '\0') { + return 0; + } + break; + default: + if ((p[0] == s[0]) || (p[0] == '?')) + return strcmp_pattern(p+1, s+1); + break; } - - if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { - udev->mode = 0660; - strcpy(udev->owner, "root"); - strcpy(udev->group, "root"); - } - - return 0; -} - -void udev_cleanup_device(struct udevice *udev) -{ - struct name_entry *name_loop; - struct name_entry *temp_loop; - - list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { - list_del(&name_loop->node); - free(name_loop); - } - list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { - list_del(&name_loop->node); - free(name_loop); - } - list_for_each_entry_safe(name_loop, temp_loop, &udev->env_list, node) { - list_del(&name_loop->node); - free(name_loop); - } + return 1; } int string_is_true(const char *str) diff --git a/udev_utils.h b/udev_utils.h index 655c764fc8..5f4152df82 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -1,8 +1,7 @@ /* - * udev_lib - generic stuff used by udev - * - * Copyright (C) 2004 Kay Sievers + * udev_utils.c - generic stuff used by udev * + * 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 @@ -19,19 +18,18 @@ * */ -#ifndef _UDEV_LIB_H_ -#define _UDEV_LIB_H_ +#ifndef _UDEV_COMMON_H_ +#define _UDEV_COMMON_H_ #include "udev.h" +#include "list.h" struct name_entry { struct list_head node; char name[PATH_SIZE]; }; -extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action); -extern void udev_cleanup_device(struct udevice *udev); - +extern int strcmp_pattern(const char *p, const char *s); extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int create_path(const char *path); extern int log_priority(const char *priority); diff --git a/udevcontrol.c b/udevcontrol.c index f19ae98fba..5d8fa77683 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -1,11 +1,8 @@ /* * udevcontrol.c * - * Userspace devfs - * * 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. diff --git a/udevd.h b/udevd.h index c60fb139c0..aadae31e57 100644 --- a/udevd.h +++ b/udevd.h @@ -1,11 +1,8 @@ /* * udevd.h * - * Userspace devfs - * * Copyright (C) 2004 Ling, Xiaofeng - * Copyright (C) 2004 Kay Sievers - * + * 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 diff --git a/udeveventrecorder.c b/udeveventrecorder.c index af7ea7c15c..711f467307 100644 --- a/udeveventrecorder.c +++ b/udeveventrecorder.c @@ -1,9 +1,9 @@ /* * udeveventrecorder.c * - * Userspace devfs - * - * Copyright (C) 2004, 2005 Olaf Hering + * Copyright (C) 2004-2005 SuSE Linux Products GmbH + * Author: + * Olaf Hering * * 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 diff --git a/udevinfo.c b/udevinfo.c index db562eee49..d2c3e1ab7f 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -1,5 +1,5 @@ /* - * udevinfo - fetches attributes for a device + * udevinfo.c - fetches attributes for a device * * Copyright (C) 2004 Kay Sievers * diff --git a/udevinitsend.c b/udevinitsend.c index 204e9cecd5..5abf3d4bd3 100644 --- a/udevinitsend.c +++ b/udevinitsend.c @@ -1,9 +1,9 @@ /* * udevinitsend.c * - * Userspace devfs - * - * Copyright (C) 2004, 2005 Hannes Reinecke + * Copyright (C) 2004, 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 diff --git a/udevsend.c b/udevsend.c index bdc69d0508..94ab6ff625 100644 --- a/udevsend.c +++ b/udevsend.c @@ -1,12 +1,9 @@ /* * udevsend.c * - * Userspace devfs - * * Copyright (C) 2004 Ling, Xiaofeng * 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. diff --git a/udevstart.c b/udevstart.c index d9912466ca..0bcbc39737 100644 --- a/udevstart.c +++ b/udevstart.c @@ -2,10 +2,12 @@ * udevstart.c * * Copyright (C) 2004 Greg Kroah-Hartman - * + * Copyright (C) 2004 Kay Sievers + * * Quick and dirty way to populate a /dev with udev if your system - * does not have access to a shell. Based originally on a patch to udev - * from Harald Hoyer + * does not have access to a shell. Based originally on a patch + * from: + * Harald Hoyer * * 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 @@ -41,8 +43,8 @@ #include "udev.h" #include "udev_version.h" #include "logging.h" -#include "udev_rules.h" #include "udev_utils.h" +#include "udev_rules.h" #include "list.h" static const char *udev_run_str; diff --git a/udevtest.c b/udevtest.c index 3e17b94715..4890b6837c 100644 --- a/udevtest.c +++ b/udevtest.c @@ -1,9 +1,7 @@ /* * udevtest.c * - * Userspace devfs - * - * Copyright (C) 2003,2004 Greg Kroah-Hartman + * Copyright (C) 2003-2004 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 From fa5c98ab9c9fa86e7078011c6c95597b74be2103 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 23 Jul 2005 12:26:28 -0400 Subject: [PATCH 1401/4284] 063 release --- ChangeLog | 19 +++++++++++++++++++ Makefile | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 159437240f..0ce54a817d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 881ef85ad6..4b312806eb 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 063 +VERSION = 064 ROOT = udev DAEMON = udevd SENDER = udevsend From 62a22c8d75550d5720019468c7a881a573bff22b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 23 Jul 2005 12:27:02 -0400 Subject: [PATCH 1402/4284] Oops, 064 release, not 063 --- udev.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev.spec b/udev.spec index 09f95f1317..2027725674 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace device manager providing devfs functionality Name: udev -Version: 063 +Version: 064 Release: 1 License: GPL Group: Utilities/System From 70721db6d7ba0d4f3ac5c17f2cedac056065ad8a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 1 Aug 2005 01:33:36 +0200 Subject: [PATCH 1403/4284] fix GGC signed pointer warnings and switch volume_id to stdint Solaris uses volume_id now and they fiddled around with configure scripts to map the linux kernel int types. Adding the types locally to volume_id breaks the klibc build, so just switch to these ugly types and forget it. :) Signed-off-by: Kay Sievers --- Makefile | 6 +- extras/ata_id/Makefile | 2 - extras/ata_id/ata_id.c | 11 +- extras/dasd_id/Makefile | 2 - extras/dasd_id/dasd_id.c | 7 +- extras/floppy/Makefile | 2 - extras/run_directory/Makefile | 2 - extras/scsi_id/Makefile | 3 +- extras/scsi_id/scsi_id.c | 5 +- extras/scsi_id/scsi_serial.c | 15 +- extras/usb_id/Makefile | 2 - extras/usb_id/usb_id.c | 5 +- extras/volume_id/Makefile | 2 - extras/volume_id/vol_id.c | 27 +-- extras/volume_id/volume_id/cramfs.c | 23 +-- extras/volume_id/volume_id/cramfs.h | 2 +- extras/volume_id/volume_id/ext.c | 35 ++-- extras/volume_id/volume_id/ext.h | 2 +- extras/volume_id/volume_id/fat.c | 135 ++++++------ extras/volume_id/volume_id/fat.h | 2 +- extras/volume_id/volume_id/hfs.c | 157 +++++++------- extras/volume_id/volume_id/hfs.h | 2 +- extras/volume_id/volume_id/highpoint.c | 21 +- extras/volume_id/volume_id/highpoint.h | 4 +- extras/volume_id/volume_id/hpfs.c | 7 +- extras/volume_id/volume_id/hpfs.h | 2 +- extras/volume_id/volume_id/iso9660.c | 35 ++-- extras/volume_id/volume_id/iso9660.h | 2 +- extras/volume_id/volume_id/isw_raid.c | 19 +- extras/volume_id/volume_id/isw_raid.h | 2 +- extras/volume_id/volume_id/jfs.c | 23 +-- extras/volume_id/volume_id/jfs.h | 2 +- extras/volume_id/volume_id/linux_raid.c | 41 ++-- extras/volume_id/volume_id/linux_raid.h | 2 +- extras/volume_id/volume_id/linux_swap.c | 17 +- extras/volume_id/volume_id/linux_swap.h | 2 +- extras/volume_id/volume_id/lsi_raid.c | 9 +- extras/volume_id/volume_id/lsi_raid.h | 2 +- extras/volume_id/volume_id/luks.c | 37 ++-- extras/volume_id/volume_id/luks.h | 2 +- extras/volume_id/volume_id/lvm.c | 23 +-- extras/volume_id/volume_id/lvm.h | 4 +- extras/volume_id/volume_id/mac.c | 28 +-- extras/volume_id/volume_id/mac.h | 2 +- extras/volume_id/volume_id/minix.c | 23 +-- extras/volume_id/volume_id/minix.h | 2 +- extras/volume_id/volume_id/msdos.c | 43 ++-- extras/volume_id/volume_id/msdos.h | 2 +- extras/volume_id/volume_id/ntfs.c | 107 +++++----- extras/volume_id/volume_id/ntfs.h | 2 +- extras/volume_id/volume_id/nvidia_raid.c | 15 +- extras/volume_id/volume_id/nvidia_raid.h | 2 +- extras/volume_id/volume_id/ocfs2.c | 98 ++++----- extras/volume_id/volume_id/ocfs2.h | 2 +- extras/volume_id/volume_id/promise_raid.c | 9 +- extras/volume_id/volume_id/promise_raid.h | 2 +- extras/volume_id/volume_id/reiserfs.c | 40 ++-- extras/volume_id/volume_id/reiserfs.h | 2 +- extras/volume_id/volume_id/romfs.c | 13 +- extras/volume_id/volume_id/romfs.h | 2 +- extras/volume_id/volume_id/silicon_raid.c | 39 ++-- extras/volume_id/volume_id/silicon_raid.h | 2 +- extras/volume_id/volume_id/sysv.c | 90 ++++---- extras/volume_id/volume_id/sysv.h | 2 +- extras/volume_id/volume_id/udf.c | 37 ++-- extras/volume_id/volume_id/udf.h | 2 +- extras/volume_id/volume_id/ufs.c | 237 +++++++++++----------- extras/volume_id/volume_id/ufs.h | 2 +- extras/volume_id/volume_id/util.c | 47 +++-- extras/volume_id/volume_id/util.h | 40 ++-- extras/volume_id/volume_id/via_raid.c | 25 ++- extras/volume_id/volume_id/via_raid.h | 2 +- extras/volume_id/volume_id/volume_id.c | 5 +- extras/volume_id/volume_id/volume_id.h | 34 ++-- extras/volume_id/volume_id/xfs.c | 27 ++- extras/volume_id/volume_id/xfs.h | 2 +- 76 files changed, 831 insertions(+), 861 deletions(-) diff --git a/Makefile b/Makefile index 4b312806eb..c9807de4bc 100644 --- a/Makefile +++ b/Makefile @@ -105,11 +105,11 @@ GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) # check if compiler option is supported cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi;} -CFLAGS += -Wall -fno-builtin -Wchar-subscripts -Wpointer-arith -Wstrict-prototypes -Wsign-compare -CFLAGS += $(call cc-supports, -Wno-pointer-sign, ) +CFLAGS += -Wall -fno-builtin -Wchar-subscripts -Wpointer-arith \ + -Wstrict-prototypes -Wsign-compare CFLAGS += $(call cc-supports, -Wdeclaration-after-statement, ) CFLAGS += -pipe -CFLAGS += -D_GNU_SOURCE +CFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 # use '-Os' optimization if available, else use -O2 OPTFLAGS := $(call cc-supports, -Os, -O2) diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index a19c4b2289..fb45bcca64 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -28,8 +28,6 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-D_FILE_OFFSET_BITS=64 - OBJS = ata_id.o ../../udev.a $(OBJS): $(HEADERS) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index 1e99b9df9c..2840e91457 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -62,10 +62,9 @@ void log_message(int priority, const char *format, ...) } #endif -static void set_str(char *to, const unsigned char *from, int count) +static void set_str(char *to, const char *from, size_t count) { - int i, j; - int len; + size_t i, j, len; /* strip trailing whitespace */ len = strnlen(from, count); @@ -139,9 +138,9 @@ int main(int argc, char *argv[]) goto close; } - set_str(model, id.model, 40); - set_str(serial, id.serial_no, 20); - set_str(revision, id.fw_rev, 8); + 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) { diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index 33bb6965cd..3b0a35f75f 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -28,8 +28,6 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -CFLAGS+=-D_FILE_OFFSET_BITS=64 - OBJS = dasd_id.o ../../udev.a $(OBJS): $(HEADERS) diff --git a/extras/dasd_id/dasd_id.c b/extras/dasd_id/dasd_id.c index e2df65d6ec..a6f2de0db7 100644 --- a/extras/dasd_id/dasd_id.c +++ b/extras/dasd_id/dasd_id.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "../../logging.h" #include "../../udev_utils.h" @@ -140,7 +139,7 @@ static unsigned char EBCtoASC[256] = 0x38, 0x39, 0x07, 0x07, 0x9A, 0x07, 0x07, 0x07 }; -static void vtoc_ebcdic_dec (const unsigned char *source, char *target, int l) +static void vtoc_ebcdic_dec (const unsigned char *source, unsigned char *target, int l) { int i; @@ -183,8 +182,8 @@ static int dasd_id(int fd) { int blocksize; dasd_information_t info; - __u8 *data; - __u8 *label_raw; + unsigned char *data; + unsigned char *label_raw; if (ioctl(fd, BIODASDINFO, &info) != 0) { dbg("not a dasd"); diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index 2601eeeb55..ab0cd17e58 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -28,8 +28,6 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -CFLAGS+=-D_FILE_OFFSET_BITS=64 - OBJS = $(PROG).o ../../udev.a $(OBJS): $(HEADERS) diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 0562073c8f..14b4725dae 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -29,8 +29,6 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-D_FILE_OFFSET_BITS=64 - OBJS = ../../udev.a ../../libsysfs/sysfs.a .c.o: diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 7aa3e83470..24c1b32128 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -28,7 +28,7 @@ INSTALL_DATA = ${INSTALL} -m 644 # Note some of the variables used here are set when built under udev, and # otherwise might not be set. -override CFLAGS+=-Wall -fno-builtin +CFLAGS+=-Wall -fno-builtin PROG=scsi_id SYSFS=-lsysfs @@ -77,3 +77,4 @@ spotless: clean $(PROG): $(OBJS) $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 1b4234a40e..8e5172f93c 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -101,10 +101,9 @@ void log_message (int level, const char *format, ...) return; } -static void set_str(char *to, const unsigned char *from, int count) +static void set_str(char *to, const char *from, size_t count) { - int i, j; - int len; + size_t i, j, len; /* strip trailing whitespace */ len = strnlen(from, count); diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 7bfa9d1812..73d66ee615 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -294,9 +294,9 @@ static int scsi_dump(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) return -1; } -static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned - char evpd, unsigned char page, unsigned char *buf, - unsigned int buflen) +static int scsi_inquiry(struct sysfs_device *scsi_dev, 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 }; @@ -367,7 +367,7 @@ error: /* Get list of supported EVPD pages */ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, - char *buffer, int len) + unsigned char *buffer, unsigned int len) { int retval; struct sysfs_attribute *vendor; @@ -407,7 +407,7 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, scsi_dev->name); return 1; } - if (!strncmp(&buffer[VENDOR_LENGTH], vendor->value, + if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor->value, VENDOR_LENGTH)) { log_message(LOG_WARNING, "%s: invalid page0 data\n", scsi_dev->name); @@ -470,8 +470,9 @@ static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial) * 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 *scsi_dev, char - *page_83, const struct scsi_id_search_values +static int check_fill_0x83_id(struct sysfs_device *scsi_dev, + unsigned char *page_83, + const struct scsi_id_search_values *id_search, char *serial, int max_len) { int i, j, len; diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index e319a4fee8..0635e91cc5 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -28,8 +28,6 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -CFLAGS+=-D_FILE_OFFSET_BITS=64 - OBJS = $(PROG).o $(VOLUME_ID_OBJS) ../../udev.a ../../libsysfs/sysfs.a HEADERS = diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index 720a0f5df7..37db6d14db 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -76,10 +76,9 @@ static int use_num_info; static int export; static int debug; -static void set_str(char *to, const unsigned char *from, int count) +static void set_str(char *to, const char *from, size_t count) { - int i, j; - int len; + size_t i, j, len; /* strip trailing whitespace */ len = strnlen(from, count); diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 014bf8713d..0fadbf5b0e 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -28,8 +28,6 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -override CFLAGS+=-D_FILE_OFFSET_BITS=64 - VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index a4a866cfcf..6a9d1120e0 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -60,31 +60,34 @@ void log_message(int priority, const char *format, ...) } #endif -static void set_str(char *to, const unsigned char *from, int count) +static void set_str(char *to, const char *from, size_t count) { - int i, j; - int len; + size_t i, j, len; + /* strip trailing whitespace */ len = strnlen(from, count); while (isspace(from[len-1])) len--; + /* strip leading whitespace */ i = 0; while (isspace(from[i]) && (i < len)) i++; j = 0; while (i < len) { - switch(from[i]) { - case '/': - break; - case ' ': + /* substitute multiple whitespace */ + if (isspace(from[i])) { + while (isspace(from[i])) + i++; to[j++] = '_'; - break; - default: - to[j++] = from[i]; } - i++; + /* skip chars */ + if (from[i] == '/') { + i++; + continue; + } + to[j++] = from[i++]; } to[j] = '\0'; } @@ -106,7 +109,7 @@ int main(int argc, char *argv[]) struct volume_id *vid = NULL; static char name[VOLUME_ID_LABEL_SIZE]; int i; - unsigned long long size; + uint64_t size; const char *node = NULL; int rc = 0; diff --git a/extras/volume_id/volume_id/cramfs.c b/extras/volume_id/volume_id/cramfs.c index 0c76860013..9a71b0265c 100644 --- a/extras/volume_id/volume_id/cramfs.c +++ b/extras/volume_id/volume_id/cramfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,21 +39,21 @@ #include "cramfs.h" struct cramfs_super { - __u8 magic[4]; - __u32 size; - __u32 flags; - __u32 future; - __u8 signature[16]; + uint8_t magic[4]; + uint32_t size; + uint32_t flags; + uint32_t future; + uint8_t signature[16]; struct cramfs_info { - __u32 crc; - __u32 edition; - __u32 blocks; - __u32 files; + uint32_t crc; + uint32_t edition; + uint32_t blocks; + uint32_t files; } __attribute__((__packed__)) info; - __u8 name[16]; + uint8_t name[16]; } __attribute__((__packed__)); -int volume_id_probe_cramfs(struct volume_id *id, __u64 off) +int volume_id_probe_cramfs(struct volume_id *id, uint64_t off) { struct cramfs_super *cs; diff --git a/extras/volume_id/volume_id/cramfs.h b/extras/volume_id/volume_id/cramfs.h index b94445b8b7..a40cec199d 100644 --- a/extras/volume_id/volume_id/cramfs.h +++ b/extras/volume_id/volume_id/cramfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_CRAMFS_ #define _VOLUME_ID_CRAMFS_ -extern int volume_id_probe_cramfs(struct volume_id *id, __u64 off); +extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/ext.c b/extras/volume_id/volume_id/ext.c index 4783642114..64e5ff7cbf 100644 --- a/extras/volume_id/volume_id/ext.c +++ b/extras/volume_id/volume_id/ext.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "util.h" @@ -40,29 +39,29 @@ #include "ext.h" struct ext2_super_block { - __u32 inodes_count; - __u32 blocks_count; - __u32 r_blocks_count; - __u32 free_blocks_count; - __u32 free_inodes_count; - __u32 first_data_block; - __u32 log_block_size; - __u32 dummy3[7]; - __u8 magic[2]; - __u16 state; - __u32 dummy5[8]; - __u32 feature_compat; - __u32 feature_incompat; - __u32 feature_ro_compat; - __u8 uuid[16]; - __u8 volume_name[16]; + uint32_t inodes_count; + uint32_t blocks_count; + uint32_t r_blocks_count; + uint32_t free_blocks_count; + uint32_t free_inodes_count; + uint32_t first_data_block; + uint32_t log_block_size; + uint32_t dummy3[7]; + uint8_t magic[2]; + uint16_t state; + uint32_t dummy5[8]; + uint32_t feature_compat; + uint32_t feature_incompat; + uint32_t feature_ro_compat; + uint8_t uuid[16]; + uint8_t volume_name[16]; } __attribute__((__packed__)); #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 #define EXT_SUPERBLOCK_OFFSET 0x400 -int volume_id_probe_ext(struct volume_id *id, __u64 off) +int volume_id_probe_ext(struct volume_id *id, uint64_t off) { struct ext2_super_block *es; diff --git a/extras/volume_id/volume_id/ext.h b/extras/volume_id/volume_id/ext.h index 6b9b85876b..aa931a02a8 100644 --- a/extras/volume_id/volume_id/ext.h +++ b/extras/volume_id/volume_id/ext.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_EXT_ #define _VOLUME_ID_EXT_ -extern int volume_id_probe_ext(struct volume_id *id, __u64 off); +extern int volume_id_probe_ext(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/fat.c b/extras/volume_id/volume_id/fat.c index f6d3699758..9fa0387afe 100644 --- a/extras/volume_id/volume_id/fat.c +++ b/extras/volume_id/volume_id/fat.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -48,62 +47,62 @@ #define FAT_ENTRY_FREE 0xe5 struct vfat_super_block { - __u8 boot_jump[3]; - __u8 sysid[8]; - __u16 sector_size; - __u8 sectors_per_cluster; - __u16 reserved; - __u8 fats; - __u16 dir_entries; - __u16 sectors; - __u8 media; - __u16 fat_length; - __u16 secs_track; - __u16 heads; - __u32 hidden; - __u32 total_sect; + 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 { - __u8 unknown[3]; - __u8 serno[4]; - __u8 label[11]; - __u8 magic[8]; - __u8 dummy2[192]; - __u8 pmagic[2]; + uint8_t unknown[3]; + uint8_t serno[4]; + uint8_t label[11]; + uint8_t magic[8]; + uint8_t dummy2[192]; + uint8_t pmagic[2]; } __attribute__((__packed__)) fat; struct fat32_super_block { - __u32 fat32_length; - __u16 flags; - __u8 version[2]; - __u32 root_cluster; - __u16 insfo_sector; - __u16 backup_boot; - __u16 reserved2[6]; - __u8 unknown[3]; - __u8 serno[4]; - __u8 label[11]; - __u8 magic[8]; - __u8 dummy2[164]; - __u8 pmagic[2]; + uint32_t fat32_length; + uint16_t flags; + uint8_t version[2]; + uint32_t root_cluster; + uint16_t insfo_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]; } __attribute__((__packed__)) fat32; } __attribute__((__packed__)) type; } __attribute__((__packed__)); struct vfat_dir_entry { - __u8 name[11]; - __u8 attr; - __u16 time_creat; - __u16 date_creat; - __u16 time_acc; - __u16 date_acc; - __u16 cluster_high; - __u16 time_write; - __u16 date_write; - __u16 cluster_low; - __u32 size; + uint8_t name[11]; + uint8_t attr; + uint16_t time_creat; + uint16_t date_creat; + uint16_t time_acc; + uint16_t date_acc; + uint16_t cluster_high; + uint16_t time_write; + uint16_t date_write; + uint16_t cluster_low; + uint32_t size; } __attribute__((__packed__)); -static char *get_attr_volume_id(struct vfat_dir_entry *dir, unsigned int count) +static uint8_t *get_attr_volume_id(struct vfat_dir_entry *dir, unsigned int count) { unsigned int i; @@ -137,26 +136,26 @@ static char *get_attr_volume_id(struct vfat_dir_entry *dir, unsigned int count) return NULL; } -int volume_id_probe_vfat(struct volume_id *id, __u64 off) +int volume_id_probe_vfat(struct volume_id *id, uint64_t off) { struct vfat_super_block *vs; struct vfat_dir_entry *dir; - __u16 sector_size; - __u16 dir_entries; - __u32 sect_count; - __u16 reserved; - __u32 fat_size; - __u32 root_cluster; - __u32 dir_size; - __u32 cluster_count; - __u32 fat_length; - __u64 root_start; - __u32 start_data_sect; - __u16 root_dir_entries; - __u8 *buf; - __u32 buf_size; - __u8 *label = NULL; - __u32 next; + 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; + uint32_t fat_length; + uint64_t root_start; + uint32_t start_data_sect; + uint16_t root_dir_entries; + uint8_t *buf; + uint32_t buf_size; + uint8_t *label = NULL; + uint32_t next; int maxloop; dbg("probing at offset 0x%llx", (unsigned long long) off); @@ -294,9 +293,9 @@ fat32: next = root_cluster; maxloop = 100; while (--maxloop) { - __u32 next_sect_off; - __u64 next_off; - __u64 fat_entry_off; + uint32_t next_sect_off; + uint64_t next_off; + uint64_t fat_entry_off; int count; dbg("next cluster %u", next); @@ -318,13 +317,13 @@ fat32: break; /* get FAT entry */ - fat_entry_off = (reserved * sector_size) + (next * sizeof(__u32)); + 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(*((__u32 *) buf) & 0x0fffffff); + next = le32_to_cpu(*((uint32_t *) buf) & 0x0fffffff); if (next == 0) break; } diff --git a/extras/volume_id/volume_id/fat.h b/extras/volume_id/volume_id/fat.h index 51ad94df85..0043210d5a 100644 --- a/extras/volume_id/volume_id/fat.h +++ b/extras/volume_id/volume_id/fat.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_FAT_ #define _VOLUME_ID_FAT_ -extern int volume_id_probe_vfat(struct volume_id *id, __u64 off); +extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/hfs.c b/extras/volume_id/volume_id/hfs.c index 8c40975036..ab1bc2ec39 100644 --- a/extras/volume_id/volume_id/hfs.c +++ b/extras/volume_id/volume_id/hfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,104 +39,104 @@ #include "hfs.h" struct hfs_finder_info{ - __u32 boot_folder; - __u32 start_app; - __u32 open_folder; - __u32 os9_folder; - __u32 reserved; - __u32 osx_folder; - __u8 id[8]; + 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]; } __attribute__((__packed__)); struct hfs_mdb { - __u8 signature[2]; - __u32 cr_date; - __u32 ls_Mod; - __u16 atrb; - __u16 nm_fls; - __u16 vbm_st; - __u16 alloc_ptr; - __u16 nm_al_blks; - __u32 al_blk_size; - __u32 clp_size; - __u16 al_bl_st; - __u32 nxt_cnid; - __u16 free_bks; - __u8 label_len; - __u8 label[27]; - __u32 vol_bkup; - __u16 vol_seq_num; - __u32 wr_cnt; - __u32 xt_clump_size; - __u32 ct_clump_size; - __u16 num_root_dirs; - __u32 file_count; - __u32 dir_count; + 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; - __u8 embed_sig[2]; - __u16 embed_startblock; - __u16 embed_blockcount; + uint8_t embed_sig[2]; + uint16_t embed_startblock; + uint16_t embed_blockcount; } __attribute__((__packed__)) *hfs; struct hfsplus_bnode_descriptor { - __u32 next; - __u32 prev; - __u8 type; - __u8 height; - __u16 num_recs; - __u16 reserved; + uint32_t next; + uint32_t prev; + uint8_t type; + uint8_t height; + uint16_t num_recs; + uint16_t reserved; } __attribute__((__packed__)); struct hfsplus_bheader_record { - __u16 depth; - __u32 root; - __u32 leaf_count; - __u32 leaf_head; - __u32 leaf_tail; - __u16 node_size; + uint16_t depth; + uint32_t root; + uint32_t leaf_count; + uint32_t leaf_head; + uint32_t leaf_tail; + uint16_t node_size; } __attribute__((__packed__)); struct hfsplus_catalog_key { - __u16 key_len; - __u32 parent_id; - __u16 unicode_len; - __u8 unicode[255 * 2]; + uint16_t key_len; + uint32_t parent_id; + uint16_t unicode_len; + uint8_t unicode[255 * 2]; } __attribute__((__packed__)); struct hfsplus_extent { - __u32 start_block; - __u32 block_count; + uint32_t start_block; + uint32_t block_count; } __attribute__((__packed__)); #define HFSPLUS_EXTENT_COUNT 8 struct hfsplus_fork { - __u64 total_size; - __u32 clump_size; - __u32 total_blocks; + uint64_t total_size; + uint32_t clump_size; + uint32_t total_blocks; struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; } __attribute__((__packed__)); struct hfsplus_vol_header { - __u8 signature[2]; - __u16 version; - __u32 attributes; - __u32 last_mount_vers; - __u32 reserved; - __u32 create_date; - __u32 modify_date; - __u32 backup_date; - __u32 checked_date; - __u32 file_count; - __u32 folder_count; - __u32 blocksize; - __u32 total_blocks; - __u32 free_blocks; - __u32 next_alloc; - __u32 rsrc_clump_sz; - __u32 data_clump_sz; - __u32 next_cnid; - __u32 write_count; - __u64 encodings_bmp; + 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; @@ -150,7 +149,7 @@ struct hfsplus_vol_header { #define HFS_NODE_LEAF 0xff #define HFSPLUS_POR_CNID 1 -int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) +int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off) { unsigned int blocksize; unsigned int cat_block; @@ -161,7 +160,7 @@ int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) unsigned int leaf_node_count; unsigned int leaf_node_size; unsigned int leaf_block; - __u64 leaf_off; + uint64_t leaf_off; unsigned int alloc_block_size; unsigned int alloc_first_block; unsigned int embed_first_block; @@ -169,9 +168,9 @@ int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off) struct hfsplus_bnode_descriptor *descr; struct hfsplus_bheader_record *bnode; struct hfsplus_catalog_key *key; - unsigned int label_len; + unsigned int label_len; struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; - const __u8 *buf; + const uint8_t *buf; dbg("probing at offset 0x%llx", (unsigned long long) off); diff --git a/extras/volume_id/volume_id/hfs.h b/extras/volume_id/volume_id/hfs.h index b23ccd30c8..42dc449e29 100644 --- a/extras/volume_id/volume_id/hfs.h +++ b/extras/volume_id/volume_id/hfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_HFS_ #define _VOLUME_ID_HFS_ -extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, __u64 off); +extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/highpoint.c b/extras/volume_id/volume_id/highpoint.c index 938a8934e5..baa278ba80 100644 --- a/extras/volume_id/volume_id/highpoint.c +++ b/extras/volume_id/volume_id/highpoint.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,12 +39,12 @@ #include "highpoint.h" struct hpt37x_meta { - __u8 filler1[32]; - __u32 magic; + uint8_t filler1[32]; + uint32_t magic; } __attribute__((packed)); struct hpt45x_meta { - __u32 magic; + uint32_t magic; } __attribute__((packed)); #define HPT37X_CONFIG_OFF 0x1200 @@ -56,11 +55,11 @@ struct hpt45x_meta { #define HPT45X_MAGIC_BAD 0x5a7816fd -int volume_id_probe_highpoint_37x_raid(struct volume_id *id, __u64 off) +int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off) { - const __u8 *buf; + const uint8_t *buf; struct hpt37x_meta *hpt; - __u32 magic; + uint32_t magic; dbg("probing at offset 0x%llx", (unsigned long long) off); @@ -79,12 +78,12 @@ int volume_id_probe_highpoint_37x_raid(struct volume_id *id, __u64 off) return 0; } -int volume_id_probe_highpoint_45x_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; + const uint8_t *buf; struct hpt45x_meta *hpt; - __u64 meta_off; - __u32 magic; + uint64_t meta_off; + uint32_t magic; dbg("probing at offset 0x%llx, size 0x%llx", (unsigned long long) off, (unsigned long long) size); diff --git a/extras/volume_id/volume_id/highpoint.h b/extras/volume_id/volume_id/highpoint.h index 7cc2ac0cb8..b0462f0525 100644 --- a/extras/volume_id/volume_id/highpoint.h +++ b/extras/volume_id/volume_id/highpoint.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_HIGHPOINT_ #define _VOLUME_ID_HIGHPOINT_ -extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, __u64 off); -extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off); +extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/hpfs.c b/extras/volume_id/volume_id/hpfs.c index 96c63d5e1d..8cd65cd6e9 100644 --- a/extras/volume_id/volume_id/hpfs.c +++ b/extras/volume_id/volume_id/hpfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -41,13 +40,13 @@ struct hpfs_super { - __u8 magic[4]; - __u8 version; + uint8_t magic[4]; + uint8_t version; } __attribute__((__packed__)); #define HPFS_SUPERBLOCK_OFFSET 0x2000 -int volume_id_probe_hpfs(struct volume_id *id, __u64 off) +int volume_id_probe_hpfs(struct volume_id *id, uint64_t off) { struct hpfs_super *hs; diff --git a/extras/volume_id/volume_id/hpfs.h b/extras/volume_id/volume_id/hpfs.h index bd8d4c90c9..d496829033 100644 --- a/extras/volume_id/volume_id/hpfs.h +++ b/extras/volume_id/volume_id/hpfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_HPFS_ #define _VOLUME_ID_HPFS_ -extern int volume_id_probe_hpfs(struct volume_id *id, __u64 off); +extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/iso9660.c b/extras/volume_id/volume_id/iso9660.c index 5d4ab92a79..8811ffbc03 100644 --- a/extras/volume_id/volume_id/iso9660.c +++ b/extras/volume_id/volume_id/iso9660.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -48,27 +47,27 @@ #define ISO_VD_MAX 16 struct iso_volume_descriptor { - __u8 vd_type; - __u8 vd_id[5]; - __u8 vd_version; - __u8 flags; - __u8 system_id[32]; - __u8 volume_id[32]; - __u8 unused[8]; - __u8 space_size[8]; - __u8 escape_sequences[8]; + uint8_t vd_type; + uint8_t vd_id[5]; + uint8_t vd_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]; } __attribute__((__packed__)); struct high_sierra_volume_descriptor { - __u8 foo[8]; - __u8 type; - __u8 id[4]; - __u8 version; + uint8_t foo[8]; + uint8_t type; + uint8_t id[4]; + uint8_t version; } __attribute__((__packed__)); -int volume_id_probe_iso9660(struct volume_id *id, __u64 off) +int volume_id_probe_iso9660(struct volume_id *id, uint64_t off) { - __u8 *buf; + uint8_t *buf; struct iso_volume_descriptor *is; struct high_sierra_volume_descriptor *hs; @@ -91,7 +90,7 @@ int volume_id_probe_iso9660(struct volume_id *id, __u64 off) dbg("looking for SVDs"); vd_offset = ISO_VD_OFFSET; for (i = 0; i < ISO_VD_MAX; i++) { - char svd_label[64]; + uint8_t svd_label[64]; is = (struct iso_volume_descriptor *) volume_id_get_buffer(id, off + vd_offset, 0x200); if (is == NULL || is->vd_type == ISO_VD_END) @@ -104,7 +103,7 @@ int volume_id_probe_iso9660(struct volume_id *id, __u64 off) 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); + volume_id_set_unicode16((char *)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; diff --git a/extras/volume_id/volume_id/iso9660.h b/extras/volume_id/volume_id/iso9660.h index c187e25f94..0119acac6c 100644 --- a/extras/volume_id/volume_id/iso9660.h +++ b/extras/volume_id/volume_id/iso9660.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_ISO9660_ #define _VOLUME_ID_ISO9660_ -extern int volume_id_probe_iso9660(struct volume_id *id, __u64 off); +extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/isw_raid.c b/extras/volume_id/volume_id/isw_raid.c index c703f3fe27..9c3082dbbf 100644 --- a/extras/volume_id/volume_id/isw_raid.c +++ b/extras/volume_id/volume_id/isw_raid.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,20 +39,20 @@ #include "isw_raid.h" struct isw_meta { - __u8 sig[32]; - __u32 check_sum; - __u32 mpb_size; - __u32 family_num; - __u32 generation_num; + uint8_t sig[32]; + uint32_t check_sum; + uint32_t mpb_size; + uint32_t family_num; + uint32_t generation_num; } __attribute__((packed)); #define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " -int volume_id_probe_intel_software_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; - __u64 meta_off; + const uint8_t *buf; + uint64_t meta_off; struct isw_meta *isw; dbg("probing at offset 0x%llx, size 0x%llx", @@ -72,7 +71,7 @@ int volume_id_probe_intel_software_raid(struct volume_id *id, __u64 off, __u64 s return -1; volume_id_set_usage(id, VOLUME_ID_RAID); - strncpy(id->type_version, &isw->sig[sizeof(ISW_SIGNATURE)-1], 6); + memcpy(id->type_version, &isw->sig[sizeof(ISW_SIGNATURE)-1], 6); id->type = "isw_raid_member"; return 0; diff --git a/extras/volume_id/volume_id/isw_raid.h b/extras/volume_id/volume_id/isw_raid.h index 4bfd3bb529..7f48b0196f 100644 --- a/extras/volume_id/volume_id/isw_raid.h +++ b/extras/volume_id/volume_id/isw_raid.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_ISW_RAID_ #define _VOLUME_ID_ISW_RAID_ -extern int volume_id_probe_intel_software_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/jfs.c b/extras/volume_id/volume_id/jfs.c index 77fa095357..6899e939ac 100644 --- a/extras/volume_id/volume_id/jfs.c +++ b/extras/volume_id/volume_id/jfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,21 +39,21 @@ #include "jfs.h" struct jfs_super_block { - __u8 magic[4]; - __u32 version; - __u64 size; - __u32 bsize; - __u32 dummy1; - __u32 pbsize; - __u32 dummy2[27]; - __u8 uuid[16]; - __u8 label[16]; - __u8 loguuid[16]; + 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]; } __attribute__((__packed__)); #define JFS_SUPERBLOCK_OFFSET 0x8000 -int volume_id_probe_jfs(struct volume_id *id, __u64 off) +int volume_id_probe_jfs(struct volume_id *id, uint64_t off) { struct jfs_super_block *js; diff --git a/extras/volume_id/volume_id/jfs.h b/extras/volume_id/volume_id/jfs.h index 28c48ffe53..e979eb740c 100644 --- a/extras/volume_id/volume_id/jfs.h +++ b/extras/volume_id/volume_id/jfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_JFS_ #define _VOLUME_ID_JFS_ -extern int volume_id_probe_jfs(struct volume_id *id, __u64 off); +extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/linux_raid.c b/extras/volume_id/volume_id/linux_raid.c index 598002ec4f..ece3e46f6d 100644 --- a/extras/volume_id/volume_id/linux_raid.c +++ b/extras/volume_id/volume_id/linux_raid.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,32 +39,32 @@ #include "linux_raid.h" struct mdp_super_block { - __u32 md_magic; - __u32 major_version; - __u32 minor_version; - __u32 patch_version; - __u32 gvalid_words; - __u32 set_uuid0; - __u32 ctime; - __u32 level; - __u32 size; - __u32 nr_disks; - __u32 raid_disks; - __u32 md_minor; - __u32 not_persistent; - __u32 set_uuid1; - __u32 set_uuid2; - __u32 set_uuid3; + 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; } __attribute__((packed)) *mdp; #define MD_RESERVED_BYTES 0x10000 #define MD_MAGIC 0xa92b4efc -int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; - __u64 sboff; - __u8 uuid[16]; + const uint8_t *buf; + uint64_t sboff; + uint8_t uuid[16]; dbg("probing at offset 0x%llx, size 0x%llx", (unsigned long long) off, (unsigned long long) size); diff --git a/extras/volume_id/volume_id/linux_raid.h b/extras/volume_id/volume_id/linux_raid.h index 0aaaaa6ade..adf6ebaacd 100644 --- a/extras/volume_id/volume_id/linux_raid.h +++ b/extras/volume_id/volume_id/linux_raid.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_LINUX_RAID_ #define _VOLUME_ID_LINUX_RAID_ -extern int volume_id_probe_linux_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/linux_swap.c b/extras/volume_id/volume_id/linux_swap.c index e37a79be86..1ffc2a8cb5 100644 --- a/extras/volume_id/volume_id/linux_swap.c +++ b/extras/volume_id/volume_id/linux_swap.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,19 +39,19 @@ #include "linux_swap.h" struct swap_header_v1_2 { - __u8 bootbits[1024]; - __u32 version; - __u32 last_page; - __u32 nr_badpages; - __u8 uuid[16]; - __u8 volume_name[16]; + uint8_t bootbits[1024]; + uint32_t version; + uint32_t last_page; + uint32_t nr_badpages; + uint8_t uuid[16]; + uint8_t volume_name[16]; } __attribute__((__packed__)) *sw; #define LARGEST_PAGESIZE 0x4000 -int volume_id_probe_linux_swap(struct volume_id *id, __u64 off) +int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off) { - const __u8 *buf; + const uint8_t *buf; unsigned int page; dbg("probing at offset 0x%llx", (unsigned long long) off); diff --git a/extras/volume_id/volume_id/linux_swap.h b/extras/volume_id/volume_id/linux_swap.h index 5de0f93849..c8fa90d5c5 100644 --- a/extras/volume_id/volume_id/linux_swap.h +++ b/extras/volume_id/volume_id/linux_swap.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_LINUX_SWAP_ #define _VOLUME_ID_LINUX_SWAP_ -extern int volume_id_probe_linux_swap(struct volume_id *id, __u64 off); +extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/lsi_raid.c b/extras/volume_id/volume_id/lsi_raid.c index e411fbc264..bb2ac7f9c5 100644 --- a/extras/volume_id/volume_id/lsi_raid.c +++ b/extras/volume_id/volume_id/lsi_raid.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,15 +39,15 @@ #include "lsi_raid.h" struct lsi_meta { - __u8 sig[6]; + uint8_t sig[6]; } __attribute__((packed)); #define LSI_SIGNATURE "$XIDE$" -int volume_id_probe_lsi_mega_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; - __u64 meta_off; + const uint8_t *buf; + uint64_t meta_off; struct lsi_meta *lsi; dbg("probing at offset 0x%llx, size 0x%llx", diff --git a/extras/volume_id/volume_id/lsi_raid.h b/extras/volume_id/volume_id/lsi_raid.h index b3ee0bb7fb..2c2758bdb4 100644 --- a/extras/volume_id/volume_id/lsi_raid.h +++ b/extras/volume_id/volume_id/lsi_raid.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_LSI_RAID_ #define _VOLUME_ID_LSI_RAID_ -extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/luks.c b/extras/volume_id/volume_id/luks.c index a00bf4041b..22d2a94ac7 100644 --- a/extras/volume_id/volume_id/luks.c +++ b/extras/volume_id/volume_id/luks.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "util.h" @@ -49,33 +48,33 @@ #define LUKS_SALTSIZE 32 #define LUKS_NUMKEYS 8 -const __u8 LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; +const uint8_t LUKS_MAGIC[] = {'L','U','K','S', 0xba, 0xbe}; #define LUKS_MAGIC_L 6 #define LUKS_PHDR_SIZE (sizeof(struct luks_phdr)/SECTOR_SIZE+1) #define UUID_STRING_L 40 struct luks_phdr { - __u8 magic[LUKS_MAGIC_L]; - __u16 version; - __u8 cipherName[LUKS_CIPHERNAME_L]; - __u8 cipherMode[LUKS_CIPHERMODE_L]; - __u8 hashSpec[LUKS_HASHSPEC_L]; - __u32 payloadOffset; - __u32 keyBytes; - __u8 mkDigest[LUKS_DIGESTSIZE]; - __u8 mkDigestSalt[LUKS_SALTSIZE]; - __u32 mkDigestIterations; - __u8 uuid[UUID_STRING_L]; + 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 { - __u32 active; - __u32 passwordIterations; - __u8 passwordSalt[LUKS_SALTSIZE]; - __u32 keyMaterialOffset; - __u32 stripes; + 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, __u64 off) +int volume_id_probe_luks(struct volume_id *id, uint64_t off) { struct luks_phdr *header; diff --git a/extras/volume_id/volume_id/luks.h b/extras/volume_id/volume_id/luks.h index 180336f573..f53a1558ec 100644 --- a/extras/volume_id/volume_id/luks.h +++ b/extras/volume_id/volume_id/luks.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_LUKS_ #define _VOLUME_ID_LUKS_ -extern int volume_id_probe_luks(struct volume_id *id, __u64 off); +extern int volume_id_probe_luks(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/lvm.c b/extras/volume_id/volume_id/lvm.c index d1e337dc35..b2e2e421d0 100644 --- a/extras/volume_id/volume_id/lvm.c +++ b/extras/volume_id/volume_id/lvm.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,23 +39,23 @@ #include "lvm.h" struct lvm1_super_block { - __u8 id[2]; + uint8_t id[2]; } __attribute__((packed)); struct lvm2_super_block { - __u8 id[8]; - __u64 sector_xl; - __u32 crc_xl; - __u32 offset_xl; - __u8 type[8]; + uint8_t id[8]; + uint64_t sector_xl; + uint32_t crc_xl; + uint32_t offset_xl; + uint8_t type[8]; } __attribute__((packed)); #define LVM1_SB_OFF 0x400 #define LVM1_MAGIC "HM" -int volume_id_probe_lvm1(struct volume_id *id, __u64 off) +int volume_id_probe_lvm1(struct volume_id *id, uint64_t off) { - const __u8 *buf; + const uint8_t *buf; struct lvm1_super_block *lvm; dbg("probing at offset 0x%llx", (unsigned long long) off); @@ -79,9 +78,9 @@ int volume_id_probe_lvm1(struct volume_id *id, __u64 off) #define LVM2_LABEL_ID "LABELONE" #define LVM2LABEL_SCAN_SECTORS 4 -int volume_id_probe_lvm2(struct volume_id *id, __u64 off) +int volume_id_probe_lvm2(struct volume_id *id, uint64_t off) { - const __u8 *buf; + const uint8_t *buf; unsigned int soff; struct lvm2_super_block *lvm; @@ -102,7 +101,7 @@ int volume_id_probe_lvm2(struct volume_id *id, __u64 off) return -1; found: - strncpy(id->type_version, lvm->type, 8); + memcpy(id->type_version, lvm->type, 8); volume_id_set_usage(id, VOLUME_ID_RAID); id->type = "LVM2_member"; diff --git a/extras/volume_id/volume_id/lvm.h b/extras/volume_id/volume_id/lvm.h index 2e44cda75b..555f18d904 100644 --- a/extras/volume_id/volume_id/lvm.h +++ b/extras/volume_id/volume_id/lvm.h @@ -21,7 +21,7 @@ #ifndef _VOLUME_ID_LVM_ #define _VOLUME_ID_LVM_ -extern int volume_id_probe_lvm1(struct volume_id *id, __u64 off); -extern int volume_id_probe_lvm2(struct volume_id *id, __u64 off); +extern int volume_id_probe_lvm1(struct volume_id *id, uint64_t off); +extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/mac.c b/extras/volume_id/volume_id/mac.c index dcfacc2a69..7ebd749e4f 100644 --- a/extras/volume_id/volume_id/mac.c +++ b/extras/volume_id/volume_id/mac.c @@ -40,24 +40,24 @@ #include "mac.h" struct mac_driver_desc { - __u8 signature[2]; - __u16 block_size; - __u32 block_count; + uint8_t signature[2]; + uint16_t block_size; + uint32_t block_count; } __attribute__((__packed__)); struct mac_partition { - __u8 signature[2]; - __u16 res1; - __u32 map_count; - __u32 start_block; - __u32 block_count; - __u8 name[32]; - __u8 type[32]; + uint8_t signature[2]; + uint16_t res1; + uint32_t map_count; + uint32_t start_block; + uint32_t block_count; + uint8_t name[32]; + uint8_t type[32]; } __attribute__((__packed__)); -int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) +int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off) { - const __u8 *buf; + const uint8_t *buf; struct mac_driver_desc *driver; struct mac_partition *part; @@ -108,8 +108,8 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off) id->partition_count = part_count; for (i = 0; i < part_count; i++) { - __u64 poff; - __u64 plen; + uint64_t poff; + uint64_t plen; buf = volume_id_get_buffer(id, off + ((i+1) * bsize), 0x200); if (buf == NULL) diff --git a/extras/volume_id/volume_id/mac.h b/extras/volume_id/volume_id/mac.h index 888c1c527d..0ab0d4489d 100644 --- a/extras/volume_id/volume_id/mac.h +++ b/extras/volume_id/volume_id/mac.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_MAC_ #define _VOLUME_ID_MAC_ -extern int volume_id_probe_mac_partition_map(struct volume_id *id, __u64 off); +extern int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/minix.c b/extras/volume_id/volume_id/minix.c index d2f2a336d4..97aa83a3dc 100644 --- a/extras/volume_id/volume_id/minix.c +++ b/extras/volume_id/volume_id/minix.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -41,21 +40,21 @@ struct minix_super_block { - __u16 s_ninodes; - __u16 s_nzones; - __u16 s_imap_blocks; - __u16 s_zmap_blocks; - __u16 s_firstdatazone; - __u16 s_log_zone_size; - __u32 s_max_size; - __u16 s_magic; - __u16 s_state; - __u32 s_zones; + 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; } __attribute__((__packed__)); #define MINIX_SUPERBLOCK_OFFSET 0x400 -int volume_id_probe_minix(struct volume_id *id, __u64 off) +int volume_id_probe_minix(struct volume_id *id, uint64_t off) { struct minix_super_block *ms; diff --git a/extras/volume_id/volume_id/minix.h b/extras/volume_id/volume_id/minix.h index 7a9d97ada2..2a3fd7292b 100644 --- a/extras/volume_id/volume_id/minix.h +++ b/extras/volume_id/volume_id/minix.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_MINIX_ #define _VOLUME_ID_MINIX_ -extern int volume_id_probe_minix(struct volume_id *id, __u64 off); +extern int volume_id_probe_minix(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/msdos.c b/extras/volume_id/volume_id/msdos.c index 47c94456e4..0b8dbbeaec 100644 --- a/extras/volume_id/volume_id/msdos.c +++ b/extras/volume_id/volume_id/msdos.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,16 +39,16 @@ #include "msdos.h" struct msdos_partition_entry { - __u8 boot_ind; - __u8 head; - __u8 sector; - __u8 cyl; - __u8 sys_ind; - __u8 end_head; - __u8 end_sector; - __u8 end_cyl; - __u32 start_sect; - __u32 nr_sects; + uint8_t boot_ind; + uint8_t head; + uint8_t sector; + uint8_t cyl; + uint8_t sys_ind; + uint8_t end_head; + uint8_t end_sector; + uint8_t end_cyl; + uint32_t start_sect; + uint32_t nr_sects; } __attribute__((packed)); #define MSDOS_MAGIC "\x55\xaa" @@ -67,15 +66,15 @@ struct msdos_partition_entry { #define is_raid(type) \ (type == LINUX_RAID_PARTITION) -int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) +int volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t off) { - const __u8 *buf; + const uint8_t *buf; int i; - __u64 poff; - __u64 plen; - __u64 extended = 0; - __u64 current; - __u64 next; + uint64_t poff; + uint64_t plen; + uint64_t extended = 0; + uint64_t current; + uint64_t next; int limit; int empty = 1; struct msdos_partition_entry *part; @@ -113,8 +112,8 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) VOLUME_ID_PARTITIONS_MAX * sizeof(struct volume_id_partition)); for (i = 0; i < 4; i++) { - poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; - plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; + poff = (uint64_t) le32_to_cpu(part[i].start_sect) * BSIZE; + plen = (uint64_t) le32_to_cpu(part[i].nr_sects) * BSIZE; if (plen == 0) continue; @@ -167,8 +166,8 @@ int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off) next = 0; for (i = 0; i < 4; i++) { - poff = (__u64) le32_to_cpu(part[i].start_sect) * BSIZE; - plen = (__u64) le32_to_cpu(part[i].nr_sects) * BSIZE; + poff = (uint64_t) le32_to_cpu(part[i].start_sect) * BSIZE; + plen = (uint64_t) le32_to_cpu(part[i].nr_sects) * BSIZE; if (plen == 0) continue; diff --git a/extras/volume_id/volume_id/msdos.h b/extras/volume_id/volume_id/msdos.h index 55185c006b..29be629845 100644 --- a/extras/volume_id/volume_id/msdos.h +++ b/extras/volume_id/volume_id/msdos.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_MSDOS_ #define _VOLUME_ID_MSDOS_ -extern int volume_id_probe_msdos_part_table(struct volume_id *id, __u64 off); +extern int volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/ntfs.c b/extras/volume_id/volume_id/ntfs.c index f9df0e9cc3..f59da48165 100644 --- a/extras/volume_id/volume_id/ntfs.c +++ b/extras/volume_id/volume_id/ntfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,61 +39,61 @@ #include "ntfs.h" struct ntfs_super_block { - __u8 jump[3]; - __u8 oem_id[8]; - __u16 bytes_per_sector; - __u8 sectors_per_cluster; - __u16 reserved_sectors; - __u8 fats; - __u16 root_entries; - __u16 sectors; - __u8 media_type; - __u16 sectors_per_fat; - __u16 sectors_per_track; - __u16 heads; - __u32 hidden_sectors; - __u32 large_sectors; - __u16 unused[2]; - __u64 number_of_sectors; - __u64 mft_cluster_location; - __u64 mft_mirror_cluster_location; - __s8 cluster_per_mft_record; - __u8 reserved1[3]; - __s8 cluster_per_index_record; - __u8 reserved2[3]; - __u8 volume_serial[8]; - __u16 checksum; + 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; } __attribute__((__packed__)) *ns; struct master_file_table_record { - __u8 magic[4]; - __u16 usa_ofs; - __u16 usa_count; - __u64 lsn; - __u16 sequence_number; - __u16 link_count; - __u16 attrs_offset; - __u16 flags; - __u32 bytes_in_use; - __u32 bytes_allocated; + 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; } __attribute__((__packed__)) *mftr; struct file_attribute { - __u32 type; - __u32 len; - __u8 non_resident; - __u8 name_len; - __u16 name_offset; - __u16 flags; - __u16 instance; - __u32 value_len; - __u16 value_offset; + 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; } __attribute__((__packed__)) *attr; struct volume_info { - __u64 reserved; - __u8 major_ver; - __u8 minor_ver; + uint64_t reserved; + uint8_t major_ver; + uint8_t minor_ver; } __attribute__((__packed__)) *info; #define MFT_RECORD_VOLUME 3 @@ -103,20 +102,20 @@ struct volume_info { #define MFT_RECORD_ATTR_OBJECT_ID 0x40 #define MFT_RECORD_ATTR_END 0xffffffffu -int volume_id_probe_ntfs(struct volume_id *id, __u64 off) +int volume_id_probe_ntfs(struct volume_id *id, uint64_t off) { unsigned int sector_size; unsigned int cluster_size; - __u64 mft_cluster; - __u64 mft_off; + 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 __u8 *buf; - const __u8 *val; + const uint8_t *buf; + const uint8_t *val; dbg("probing at offset 0x%llx", (unsigned long long) off); @@ -183,7 +182,7 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { dbg("found info, len %i", val_len); - info = (struct volume_info*) (((__u8 *) attr) + val_off); + 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); } @@ -193,7 +192,7 @@ int volume_id_probe_ntfs(struct volume_id *id, __u64 off) if (val_len > VOLUME_ID_LABEL_SIZE) val_len = VOLUME_ID_LABEL_SIZE; - val = ((__u8 *) attr) + val_off; + 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); } diff --git a/extras/volume_id/volume_id/ntfs.h b/extras/volume_id/volume_id/ntfs.h index 63b1161d51..2a84db3653 100644 --- a/extras/volume_id/volume_id/ntfs.h +++ b/extras/volume_id/volume_id/ntfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_NTFS_ #define _VOLUME_ID_NTFS_ -extern int volume_id_probe_ntfs(struct volume_id *id, __u64 off); +extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/nvidia_raid.c b/extras/volume_id/volume_id/nvidia_raid.c index ad76631799..d49ffe3010 100644 --- a/extras/volume_id/volume_id/nvidia_raid.c +++ b/extras/volume_id/volume_id/nvidia_raid.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,18 +39,18 @@ #include "nvidia_raid.h" struct nvidia_meta { - __u8 vendor[8]; - __u32 size; - __u32 chksum; - __u16 version; + uint8_t vendor[8]; + uint32_t size; + uint32_t chksum; + uint16_t version; } __attribute__((packed)); #define NVIDIA_SIGNATURE "NVIDIA" -int volume_id_probe_nvidia_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; - __u64 meta_off; + const uint8_t *buf; + uint64_t meta_off; struct nvidia_meta *nv; dbg("probing at offset 0x%llx, size 0x%llx", diff --git a/extras/volume_id/volume_id/nvidia_raid.h b/extras/volume_id/volume_id/nvidia_raid.h index f892be5590..250c1f8214 100644 --- a/extras/volume_id/volume_id/nvidia_raid.h +++ b/extras/volume_id/volume_id/nvidia_raid.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_NVIDIA_RAID_ #define _VOLUME_ID_NVIDIA_RAID_ -extern int volume_id_probe_nvidia_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c index 90a6bd531c..08138472ce 100644 --- a/extras/volume_id/volume_id/ocfs2.c +++ b/extras/volume_id/volume_id/ocfs2.c @@ -51,66 +51,66 @@ This is one has been simplified since we only care about the superblock. */ struct ocfs2_super_block { - __u8 i_signature[8]; /* Signature for validation */ - __u32 i_generation; /* Generation number */ - __s16 i_suballoc_slot; /* Slot suballocator this inode belongs to */ - __u16 i_suballoc_bit; /* Bit offset in suballocator block group */ - __u32 i_reserved0; - __u32 i_clusters; /* Cluster count */ - __u32 i_uid; /* Owner UID */ - __u32 i_gid; /* Owning GID */ - __u64 i_size; /* Size in bytes */ - __u16 i_mode; /* File mode */ - __u16 i_links_count; /* Links count */ - __u32 i_flags; /* File flags */ - __u64 i_atime; /* Access time */ - __u64 i_ctime; /* Creation time */ - __u64 i_mtime; /* Modification time */ - __u64 i_dtime; /* Deletion time */ - __u64 i_blkno; /* Offset on disk, in blocks */ - __u64 i_last_eb_blk; /* Pointer to last extent block */ - __u32 i_fs_generation; /* Generation per fs-instance */ - __u32 i_atime_nsec; - __u32 i_ctime_nsec; - __u32 i_mtime_nsec; - __u64 i_reserved1[9]; - __u64 i_pad1; /* Generic way to refer to this 64bit union */ + uint8_t i_signature[8]; /* Signature for validation */ + uint32_t i_generation; /* Generation number */ + int16_t i_suballoc_slot; /* Slot suballocator this inode belongs to */ + uint16_t i_suballoc_bit; /* Bit offset in suballocator block group */ + uint32_t i_reserved0; + uint32_t i_clusters; /* Cluster count */ + uint32_t i_uid; /* Owner UID */ + uint32_t i_gid; /* Owning GID */ + uint64_t i_size; /* Size in bytes */ + uint16_t i_mode; /* File mode */ + uint16_t i_links_count; /* Links count */ + uint32_t i_flags; /* File flags */ + uint64_t i_atime; /* Access time */ + uint64_t i_ctime; /* Creation time */ + uint64_t i_mtime; /* Modification time */ + uint64_t i_dtime; /* Deletion time */ + uint64_t i_blkno; /* Offset on disk, in blocks */ + uint64_t i_last_eb_blk; /* Pointer to last extent block */ + uint32_t i_fs_generation; /* Generation per fs-instance */ + uint32_t i_atime_nsec; + uint32_t i_ctime_nsec; + uint32_t i_mtime_nsec; + uint64_t i_reserved1[9]; + uint64_t i_pad1; /* Generic way to refer to this 64bit union */ /* Normally there is a union of the different block types, but we only care about the superblock. */ - __u16 s_major_rev_level; - __u16 s_minor_rev_level; - __u16 s_mnt_count; - __s16 s_max_mnt_count; - __u16 s_state; /* File system state */ - __u16 s_errors; /* Behaviour when detecting errors */ - __u32 s_checkinterval; /* Max time between checks */ - __u64 s_lastcheck; /* Time of last check */ - __u32 s_creator_os; /* OS */ - __u32 s_feature_compat; /* Compatible feature set */ - __u32 s_feature_incompat; /* Incompatible feature set */ - __u32 s_feature_ro_compat; /* Readonly-compatible feature set */ - __u64 s_root_blkno; /* Offset, in blocks, of root directory dinode */ - __u64 s_system_dir_blkno; /* Offset, in blocks, of system directory dinode */ - __u32 s_blocksize_bits; /* Blocksize for this fs */ - __u32 s_clustersize_bits; /* Clustersize for this fs */ - __u16 s_max_slots; /* Max number of simultaneous mounts before tunefs required */ - __u16 s_reserved1; - __u32 s_reserved2; - __u64 s_first_cluster_group; /* Block offset of 1st cluster group header */ - __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ - __u8 s_uuid[OCFS2_VOL_UUID_LEN]; /* 128-bit uuid */ + 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; /* File system state */ + uint16_t s_errors; /* Behaviour when detecting errors */ + uint32_t s_checkinterval; /* Max time between checks */ + uint64_t s_lastcheck; /* Time of last check */ + uint32_t s_creator_os; /* OS */ + uint32_t s_feature_compat; /* Compatible feature set */ + uint32_t s_feature_incompat; /* Incompatible feature set */ + uint32_t s_feature_ro_compat; /* Readonly-compatible feature set */ + uint64_t s_root_blkno; /* Offset, in blocks, of root directory dinode */ + uint64_t s_system_dir_blkno; /* Offset, in blocks, of system directory dinode */ + uint32_t s_blocksize_bits; /* Blocksize for this fs */ + uint32_t s_clustersize_bits; /* Clustersize for this fs */ + uint16_t s_max_slots; /* Max number of simultaneous mounts before tunefs required */ + uint16_t s_reserved1; + uint32_t s_reserved2; + uint64_t s_first_cluster_group; /* Block offset of 1st cluster group header */ + uint8_t s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ + uint8_t s_uuid[OCFS2_VOL_UUID_LEN]; /* 128-bit uuid */ } __attribute__((__packed__)); -int volume_id_probe_ocfs2(struct volume_id *id, __u64 off) +int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off) { struct ocfs2_super_block *os; dbg("probing at offset 0x%llx", (unsigned long long) off); - os = (struct ocsf2_super_block *) volume_id_get_buffer(id, off + OCFS2_SUPERBLOCK_OFFSET, 0x200); + os = (struct ocfs2_super_block *) volume_id_get_buffer(id, off + OCFS2_SUPERBLOCK_OFFSET, 0x200); if (os == NULL) return -1; - if (strcmp(os->i_signature, "OCFSV2") != 0) { + if (memcmp(os->i_signature, "OCFSV2", 6) != 0) { return -1; } diff --git a/extras/volume_id/volume_id/ocfs2.h b/extras/volume_id/volume_id/ocfs2.h index 128348133c..b4b7cc4469 100644 --- a/extras/volume_id/volume_id/ocfs2.h +++ b/extras/volume_id/volume_id/ocfs2.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_OCFS2_ #define _VOLUME_ID_OCFS2_ -extern int volume_id_probe_ocfs2(struct volume_id *id, __u64 off); +extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/promise_raid.c b/extras/volume_id/volume_id/promise_raid.c index 8fda14945f..ed72809acb 100644 --- a/extras/volume_id/volume_id/promise_raid.c +++ b/extras/volume_id/volume_id/promise_raid.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,15 +39,15 @@ #include "promise_raid.h" struct promise_meta { - __u8 sig[24]; + uint8_t sig[24]; } __attribute__((packed)); #define PDC_CONFIG_OFF 0x1200 #define PDC_SIGNATURE "Promise Technology, Inc." -int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; + const uint8_t *buf; struct promise_meta *pdc; unsigned int i; static unsigned int sectors[] = { @@ -62,7 +61,7 @@ int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, __u64 off, __u6 return -1; for (i = 0; sectors[i] != 0; i++) { - __u64 meta_off; + uint64_t meta_off; meta_off = ((size / 0x200) - sectors[i]) * 0x200; buf = volume_id_get_buffer(id, off + meta_off, 0x200); diff --git a/extras/volume_id/volume_id/promise_raid.h b/extras/volume_id/volume_id/promise_raid.h index 554bcb97d5..f1a9925d72 100644 --- a/extras/volume_id/volume_id/promise_raid.h +++ b/extras/volume_id/volume_id/promise_raid.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_PROMISE_RAID_ #define _VOLUME_ID_PROMISE_RAID_ -extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index a53fc4a5a9..75d1be05dc 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -41,37 +41,37 @@ #include "reiserfs.h" struct reiserfs_super_block { - __u32 blocks_count; - __u32 free_blocks; - __u32 root_block; - __u32 journal_block; - __u32 journal_dev; - __u32 orig_journal_size; - __u32 dummy2[5]; - __u16 blocksize; - __u16 dummy3[3]; - __u8 magic[12]; - __u32 dummy4[5]; - __u8 uuid[16]; - __u8 label[16]; + 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]; } __attribute__((__packed__)); struct reiser4_super_block { - __u8 magic[16]; - __u16 dummy[2]; - __u8 uuid[16]; - __u8 label[16]; - __u64 dummy2; + uint8_t magic[16]; + uint16_t dummy[2]; + uint8_t uuid[16]; + uint8_t label[16]; + uint64_t dummy2; } __attribute__((__packed__)); #define REISERFS1_SUPERBLOCK_OFFSET 0x2000 #define REISERFS_SUPERBLOCK_OFFSET 0x10000 -int volume_id_probe_reiserfs(struct volume_id *id, __u64 off) +int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off) { struct reiserfs_super_block *rs; struct reiser4_super_block *rs4; - __u8 *buf; + uint8_t *buf; dbg("probing at offset 0x%llx", (unsigned long long) off); diff --git a/extras/volume_id/volume_id/reiserfs.h b/extras/volume_id/volume_id/reiserfs.h index 14f094578f..2ef1d255b7 100644 --- a/extras/volume_id/volume_id/reiserfs.h +++ b/extras/volume_id/volume_id/reiserfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_REISERFS_ #define _VOLUME_ID_REISERFS_ -extern int volume_id_probe_reiserfs(struct volume_id *id, __u64 off); +extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/romfs.c b/extras/volume_id/volume_id/romfs.c index 9c2b41bb86..3d7df2443f 100644 --- a/extras/volume_id/volume_id/romfs.c +++ b/extras/volume_id/volume_id/romfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,13 +39,13 @@ #include "romfs.h" struct romfs_super { - __u8 magic[8]; - __u32 size; - __u32 checksum; - __u8 name[0]; + uint8_t magic[8]; + uint32_t size; + uint32_t checksum; + uint8_t name[0]; } __attribute__((__packed__)); -int volume_id_probe_romfs(struct volume_id *id, __u64 off) +int volume_id_probe_romfs(struct volume_id *id, uint64_t off) { struct romfs_super *rfs; @@ -57,7 +56,7 @@ int volume_id_probe_romfs(struct volume_id *id, __u64 off) return -1; if (memcmp(rfs->magic, "-rom1fs-", 4) == 0) { - size_t len = strlen(rfs->name); + size_t len = strlen((char *)rfs->name); if (len) { volume_id_set_label_raw(id, rfs->name, len); diff --git a/extras/volume_id/volume_id/romfs.h b/extras/volume_id/volume_id/romfs.h index b0108f3dde..5a8e900b08 100644 --- a/extras/volume_id/volume_id/romfs.h +++ b/extras/volume_id/volume_id/romfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_ROMFS_ #define _VOLUME_ID_ROMFS_ -extern int volume_id_probe_romfs(struct volume_id *id, __u64 off); +extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/silicon_raid.c b/extras/volume_id/volume_id/silicon_raid.c index e528a34ce0..0d5ce043da 100644 --- a/extras/volume_id/volume_id/silicon_raid.c +++ b/extras/volume_id/volume_id/silicon_raid.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,30 +39,30 @@ #include "silicon_raid.h" struct silicon_meta { - __u8 unknown0[0x2E]; - __u8 ascii_version[0x36 - 0x2E]; - __u8 diskname[0x56 - 0x36]; - __u8 unknown1[0x60 - 0x56]; - __u32 magic; - __u32 unknown1a[0x6C - 0x64]; - __u32 array_sectors_low; - __u32 array_sectors_high; - __u8 unknown2[0x78 - 0x74]; - __u32 thisdisk_sectors; - __u8 unknown3[0x100 - 0x7C]; - __u8 unknown4[0x104 - 0x100]; - __u16 product_id; - __u16 vendor_id; - __u16 minor_ver; - __u16 major_ver; + 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; } __attribute__((packed)); #define SILICON_MAGIC 0x2F000000 -int volume_id_probe_silicon_medley_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; - __u64 meta_off; + const uint8_t *buf; + uint64_t meta_off; struct silicon_meta *sil; dbg("probing at offset 0x%llx, size 0x%llx", diff --git a/extras/volume_id/volume_id/silicon_raid.h b/extras/volume_id/volume_id/silicon_raid.h index b88e80bb1c..0816125d7f 100644 --- a/extras/volume_id/volume_id/silicon_raid.h +++ b/extras/volume_id/volume_id/silicon_raid.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_SILICON_RAID_ #define _VOLUME_ID_SILICON_RAID_ -extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/sysv.c b/extras/volume_id/volume_id/sysv.c index d4745daa22..9645ef8004 100644 --- a/extras/volume_id/volume_id/sysv.c +++ b/extras/volume_id/volume_id/sysv.c @@ -44,56 +44,56 @@ struct sysv_super { - __u16 s_isize; - __u16 s_pad0; - __u32 s_fsize; - __u16 s_nfree; - __u16 s_pad1; - __u32 s_free[SYSV_NICFREE]; - __u16 s_ninode; - __u16 s_pad2; - __u16 s_inode[SYSV_NICINOD]; - __u8 s_flock; - __u8 s_ilock; - __u8 s_fmod; - __u8 s_ronly; - __u32 s_time; - __u16 s_dinfo[4]; - __u32 s_tfree; - __u16 s_tinode; - __u16 s_pad3; - __u8 s_fname[6]; - __u8 s_fpack[6]; - __u32 s_fill[12]; - __u32 s_state; - __u32 s_magic; - __u32 s_type; + 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; } __attribute__((__packed__)); #define XENIX_NICINOD 100 #define XENIX_NICFREE 100 struct xenix_super { - __u16 s_isize; - __u32 s_fsize; - __u16 s_nfree; - __u32 s_free[XENIX_NICFREE]; - __u16 s_ninode; - __u16 s_inode[XENIX_NICINOD]; - __u8 s_flock; - __u8 s_ilock; - __u8 s_fmod; - __u8 s_ronly; - __u32 s_time; - __u32 s_tfree; - __u16 s_tinode; - __u16 s_dinfo[4]; - __u8 s_fname[6]; - __u8 s_fpack[6]; - __u8 s_clean; - __u8 s_fill[371]; - __u32 s_magic; - __u32 s_type; + 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; } __attribute__((__packed__)); #define SYSV_SUPERBLOCK_BLOCK 0x01 @@ -102,7 +102,7 @@ struct xenix_super { #define XENIX_MAGIC 0x2b5544 #define SYSV_MAX_BLOCKSIZE 0x800 -int volume_id_probe_sysv(struct volume_id *id, __u64 off) +int volume_id_probe_sysv(struct volume_id *id, uint64_t off) { struct sysv_super *vs; struct xenix_super *xs; diff --git a/extras/volume_id/volume_id/sysv.h b/extras/volume_id/volume_id/sysv.h index bd5a3500fb..1cb2bf9f43 100644 --- a/extras/volume_id/volume_id/sysv.h +++ b/extras/volume_id/volume_id/sysv.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_SYSV_ #define _VOLUME_ID_SYSV_ -extern int volume_id_probe_sysv(struct volume_id *id, __u64 off); +extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/udf.c b/extras/volume_id/volume_id/udf.c index a378fa9fd1..ecb6b9743d 100644 --- a/extras/volume_id/volume_id/udf.c +++ b/extras/volume_id/volume_id/udf.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -41,40 +40,40 @@ struct volume_descriptor { struct descriptor_tag { - __u16 id; - __u16 version; - __u8 checksum; - __u8 reserved; - __u16 serial; - __u16 crc; - __u16 crc_len; - __u32 location; + 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; } __attribute__((__packed__)) tag; union { struct anchor_descriptor { - __u32 length; - __u32 location; + uint32_t length; + uint32_t location; } __attribute__((__packed__)) anchor; struct primary_descriptor { - __u32 seq_num; - __u32 desc_num; + uint32_t seq_num; + uint32_t desc_num; struct dstring { - __u8 clen; - __u8 c[31]; + uint8_t clen; + uint8_t c[31]; } __attribute__((__packed__)) ident; } __attribute__((__packed__)) primary; } __attribute__((__packed__)) type; } __attribute__((__packed__)); struct volume_structure_descriptor { - __u8 type; - __u8 id[5]; - __u8 version; + uint8_t type; + uint8_t id[5]; + uint8_t version; } __attribute__((__packed__)); #define UDF_VSD_OFFSET 0x8000 -int volume_id_probe_udf(struct volume_id *id, __u64 off) +int volume_id_probe_udf(struct volume_id *id, uint64_t off) { struct volume_descriptor *vd; struct volume_structure_descriptor *vsd; diff --git a/extras/volume_id/volume_id/udf.h b/extras/volume_id/volume_id/udf.h index b112e46ffc..5a784ad068 100644 --- a/extras/volume_id/volume_id/udf.h +++ b/extras/volume_id/volume_id/udf.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_UDF_ #define _VOLUME_ID_UDF_ -extern int volume_id_probe_udf(struct volume_id *id, __u64 off); +extern int volume_id_probe_udf(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/ufs.c b/extras/volume_id/volume_id/ufs.c index d4f4db3d32..763b79cb0b 100644 --- a/extras/volume_id/volume_id/ufs.c +++ b/extras/volume_id/volume_id/ufs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,140 +39,140 @@ #include "ufs.h" struct ufs_super_block { - __u32 fs_link; - __u32 fs_rlink; - __u32 fs_sblkno; - __u32 fs_cblkno; - __u32 fs_iblkno; - __u32 fs_dblkno; - __u32 fs_cgoffset; - __u32 fs_cgmask; - __u32 fs_time; - __u32 fs_size; - __u32 fs_dsize; - __u32 fs_ncg; - __u32 fs_bsize; - __u32 fs_fsize; - __u32 fs_frag; - __u32 fs_minfree; - __u32 fs_rotdelay; - __u32 fs_rps; - __u32 fs_bmask; - __u32 fs_fmask; - __u32 fs_bshift; - __u32 fs_fshift; - __u32 fs_maxcontig; - __u32 fs_maxbpg; - __u32 fs_fragshift; - __u32 fs_fsbtodb; - __u32 fs_sbsize; - __u32 fs_csmask; - __u32 fs_csshift; - __u32 fs_nindir; - __u32 fs_inopb; - __u32 fs_nspf; - __u32 fs_optim; - __u32 fs_npsect_state; - __u32 fs_interleave; - __u32 fs_trackskew; - __u32 fs_id[2]; - __u32 fs_csaddr; - __u32 fs_cssize; - __u32 fs_cgsize; - __u32 fs_ntrak; - __u32 fs_nsect; - __u32 fs_spc; - __u32 fs_ncyl; - __u32 fs_cpg; - __u32 fs_ipg; - __u32 fs_fpg; + 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 { - __u32 cs_ndir; - __u32 cs_nbfree; - __u32 cs_nifree; - __u32 cs_nffree; + uint32_t cs_ndir; + uint32_t cs_nbfree; + uint32_t cs_nifree; + uint32_t cs_nffree; } __attribute__((__packed__)) fs_cstotal; - __s8 fs_fmod; - __s8 fs_clean; - __s8 fs_ronly; - __s8 fs_flags; + int8_t fs_fmod; + int8_t fs_clean; + int8_t fs_ronly; + int8_t fs_flags; union { struct { - __s8 fs_fsmnt[512]; - __u32 fs_cgrotor; - __u32 fs_csp[31]; - __u32 fs_maxcluster; - __u32 fs_cpc; - __u16 fs_opostbl[16][8]; + 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]; } __attribute__((__packed__)) fs_u1; struct { - __s8 fs_fsmnt[468]; - __u8 fs_volname[32]; - __u64 fs_swuid; - __s32 fs_pad; - __u32 fs_cgrotor; - __u32 fs_ocsp[28]; - __u32 fs_contigdirs; - __u32 fs_csp; - __u32 fs_maxcluster; - __u32 fs_active; - __s32 fs_old_cpc; - __s32 fs_maxbsize; - __s64 fs_sparecon64[17]; - __s64 fs_sblockloc; + 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 { - __u64 cs_ndir; - __u64 cs_nbfree; - __u64 cs_nifree; - __u64 cs_nffree; - __u64 cs_numclusters; - __u64 cs_spare[3]; + 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]; } __attribute__((__packed__)) fs_cstotal; struct ufs_timeval { - __s32 tv_sec; - __s32 tv_usec; + int32_t tv_sec; + int32_t tv_usec; } __attribute__((__packed__)) fs_time; - __s64 fs_size; - __s64 fs_dsize; - __u64 fs_csaddr; - __s64 fs_pendingblocks; - __s32 fs_pendinginodes; + int64_t fs_size; + int64_t fs_dsize; + uint64_t fs_csaddr; + int64_t fs_pendingblocks; + int32_t fs_pendinginodes; } __attribute__((__packed__)) fs_u2; } fs_u11; union { struct { - __s32 fs_sparecon[53]; - __s32 fs_reclaim; - __s32 fs_sparecon2[1]; - __s32 fs_state; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; + 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]; } __attribute__((__packed__)) fs_sun; struct { - __s32 fs_sparecon[53]; - __s32 fs_reclaim; - __s32 fs_sparecon2[1]; - __u32 fs_npsect; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; + 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]; } __attribute__((__packed__)) fs_sunx86; struct { - __s32 fs_sparecon[50]; - __s32 fs_contigsumsize; - __s32 fs_maxsymlinklen; - __s32 fs_inodefmt; - __u32 fs_maxfilesize[2]; - __u32 fs_qbmask[2]; - __u32 fs_qfmask[2]; - __s32 fs_state; + 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; } __attribute__((__packed__)) fs_44; } fs_u2; - __s32 fs_postblformat; - __s32 fs_nrpos; - __s32 fs_postbloff; - __s32 fs_rotbloff; - __u32 fs_magic; - __u8 fs_space[1]; + 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]; } __attribute__((__packed__)); #define UFS_MAGIC 0x00011954 @@ -181,12 +180,12 @@ struct ufs_super_block { #define UFS_MAGIC_FEA 0x00195612 #define UFS_MAGIC_LFN 0x00095014 -int volume_id_probe_ufs(struct volume_id *id, __u64 off) +int volume_id_probe_ufs(struct volume_id *id, uint64_t off) { - __u32 magic; - int i; + uint32_t magic; + int i; struct ufs_super_block *ufs; - int offsets[] = {0, 8, 64, 256, -1}; + int offsets[] = {0, 8, 64, 256, -1}; dbg("probing at offset 0x%llx", (unsigned long long) off); diff --git a/extras/volume_id/volume_id/ufs.h b/extras/volume_id/volume_id/ufs.h index 82b4e1d064..8f0af18897 100644 --- a/extras/volume_id/volume_id/ufs.h +++ b/extras/volume_id/volume_id/ufs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_UFS_ #define _VOLUME_ID_UFS_ -extern int volume_id_probe_ufs(struct volume_id *id, __u64 off); +extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index 7499fc121e..a145a8aa2f 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -34,16 +34,15 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" #include "util.h" -void volume_id_set_unicode16(char *str, unsigned int len, const __u8 *buf, enum endian endianess, unsigned int count) +void volume_id_set_unicode16(char *str, size_t len, const uint8_t *buf, enum endian endianess, size_t count) { unsigned int i, j; - __u16 c; + uint16_t c; j = 0; for (i = 0; i + 2 <= count; i += 2) { @@ -57,18 +56,18 @@ void volume_id_set_unicode16(char *str, unsigned int len, const __u8 *buf, enum } else if (c < 0x80) { if (j+1 >= len) break; - str[j++] = (__u8) c; + str[j++] = (uint8_t) c; } else if (c < 0x800) { if (j+2 >= len) break; - str[j++] = (__u8) (0xc0 | (c >> 6)); - str[j++] = (__u8) (0x80 | (c & 0x3f)); + str[j++] = (uint8_t) (0xc0 | (c >> 6)); + str[j++] = (uint8_t) (0x80 | (c & 0x3f)); } else { if (j+3 >= len) break; - str[j++] = (__u8) (0xe0 | (c >> 12)); - str[j++] = (__u8) (0x80 | ((c >> 6) & 0x3f)); - str[j++] = (__u8) (0x80 | (c & 0x3f)); + 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'; @@ -109,20 +108,26 @@ void volume_id_set_usage(struct volume_id *id, enum volume_id_usage usage_id) id->usage = usage_to_string(usage_id); } -void volume_id_set_label_raw(struct volume_id *id, const __u8 *buf, unsigned int count) +void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t count) { memcpy(id->label_raw, buf, count); id->label_raw_len = count; } -void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned int count) +static size_t my_strnlen(const char *s, size_t max) { + const char *p = s; + for (; *p && max--; ++p); + return(p - s); +} + +void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count) { unsigned int i; memcpy(id->label, buf, count); /* remove trailing whitespace */ - i = strnlen(id->label, count); + i = my_strnlen(id->label, count); while (i--) { if (!isspace(id->label[i])) break; @@ -130,12 +135,12 @@ void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned id->label[i+1] = '\0'; } -void volume_id_set_label_unicode16(struct volume_id *id, const __u8 *buf, enum endian endianess, unsigned int count) +void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count) { volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count); } -void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format) +void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format) { unsigned int i; unsigned int count = 0; @@ -196,11 +201,11 @@ set: } } -__u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len) +uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) { - unsigned int buf_len; + size_t buf_len; - dbg("get buffer off 0x%llx(%llu), len 0x%x", (unsigned long long) off, (unsigned long long) off, len); + dbg("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) { @@ -214,7 +219,7 @@ __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len) dbg("read sbbuf len:0x%llx", (unsigned long long) (off + len)); lseek(id->fd, 0, SEEK_SET); buf_len = read(id->fd, id->sbbuf, off + len); - dbg("got 0x%x (%i) bytes", buf_len, buf_len); + dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); id->sbbuf_len = buf_len; if (buf_len < off + len) return NULL; @@ -236,15 +241,15 @@ __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len) /* check if we need to read */ if ((off < id->seekbuf_off) || ((off + len) > (id->seekbuf_off + id->seekbuf_len))) { - dbg("read seekbuf off:0x%llx len:0x%x", (unsigned long long) off, len); + dbg("read seekbuf off:0x%llx len:0x%zx", (unsigned long long) off, len); if (lseek(id->fd, off, SEEK_SET) == -1) return NULL; buf_len = read(id->fd, id->seekbuf, len); - dbg("got 0x%x (%i) bytes", buf_len, buf_len); + dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); id->seekbuf_off = off; id->seekbuf_len = buf_len; if (buf_len < len) { - dbg("requested 0x%x bytes, got only 0x%x bytes", len, buf_len); + dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); return NULL; } } diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h index e18efe2f21..0c94fea051 100644 --- a/extras/volume_id/volume_id/util.h +++ b/extras/volume_id/volume_id/util.h @@ -37,22 +37,22 @@ #define SEEK_BUFFER_SIZE 0x10000 /* probe volume for all known filesystems in specific order */ -#define bswap16(x) (__u16)((((__u16)(x) & 0x00ffu) << 8) | \ - (((__u16)(x) & 0xff00u) >> 8)) +#define bswap16(x) (uint16_t) ((((uint16_t)(x) & 0x00ffu) << 8) | \ + (((uint16_t)(x) & 0xff00u) >> 8)) -#define bswap32(x) (__u32)((((__u32)(x) & 0xff000000u) >> 24) | \ - (((__u32)(x) & 0x00ff0000u) >> 8) | \ - (((__u32)(x) & 0x0000ff00u) << 8) | \ - (((__u32)(x) & 0x000000ffu) << 24)) +#define bswap32(x) (uint32_t) ((((uint32_t)(x) & 0xff000000u) >> 24) | \ + (((uint32_t)(x) & 0x00ff0000u) >> 8) | \ + (((uint32_t)(x) & 0x0000ff00u) << 8) | \ + (((uint32_t)(x) & 0x000000ffu) << 24)) -#define bswap64(x) (__u64)((((__u64)(x) & 0xff00000000000000ull) >> 56) | \ - (((__u64)(x) & 0x00ff000000000000ull) >> 40) | \ - (((__u64)(x) & 0x0000ff0000000000ull) >> 24) | \ - (((__u64)(x) & 0x000000ff00000000ull) >> 8) | \ - (((__u64)(x) & 0x00000000ff000000ull) << 8) | \ - (((__u64)(x) & 0x0000000000ff0000ull) << 24) | \ - (((__u64)(x) & 0x000000000000ff00ull) << 40) | \ - (((__u64)(x) & 0x00000000000000ffull) << 56)) +#define bswap64(x) (uint64_t) ((((uint64_t)(x) & 0xff00000000000000ull) >> 56) | \ + (((uint64_t)(x) & 0x00ff000000000000ull) >> 40) | \ + (((uint64_t)(x) & 0x0000ff0000000000ull) >> 24) | \ + (((uint64_t)(x) & 0x000000ff00000000ull) >> 8) | \ + (((uint64_t)(x) & 0x00000000ff000000ull) << 8) | \ + (((uint64_t)(x) & 0x0000000000ff0000ull) << 24) | \ + (((uint64_t)(x) & 0x000000000000ff00ull) << 40) | \ + (((uint64_t)(x) & 0x00000000000000ffull) << 56)) #ifdef __BYTE_ORDER #if (__BYTE_ORDER == __LITTLE_ENDIAN) @@ -87,14 +87,14 @@ enum endian { BE = 1 }; -extern void volume_id_set_unicode16(char *str, unsigned int len, const __u8 *buf, enum endian endianess, unsigned int count); +extern void volume_id_set_unicode16(char *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_usage_part(struct volume_id_partition *part, enum volume_id_usage usage_id); -extern void volume_id_set_label_raw(struct volume_id *id, const __u8 *buf, unsigned int count); -extern void volume_id_set_label_string(struct volume_id *id, const __u8 *buf, unsigned int count); -extern void volume_id_set_label_unicode16(struct volume_id *id, const __u8 *buf, enum endian endianess, unsigned int count); -extern void volume_id_set_uuid(struct volume_id *id, const __u8 *buf, enum uuid_format format); -extern __u8 *volume_id_get_buffer(struct volume_id *id, __u64 off, unsigned int len); +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, 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/extras/volume_id/volume_id/via_raid.c b/extras/volume_id/volume_id/via_raid.c index 393890eb28..2f167dcbcc 100644 --- a/extras/volume_id/volume_id/via_raid.c +++ b/extras/volume_id/volume_id/via_raid.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,25 +39,25 @@ #include "via_raid.h" struct via_meta { - __u16 signature; - __u8 version_number; + uint16_t signature; + uint8_t version_number; struct via_array { - __u16 disk_bits; - __u8 disk_array_ex; - __u32 capacity_low; - __u32 capacity_high; - __u32 serial_checksum; + uint16_t disk_bits; + uint8_t disk_array_ex; + uint32_t capacity_low; + uint32_t capacity_high; + uint32_t serial_checksum; } __attribute((packed)) array; - __u32 serial_checksum[8]; - __u8 checksum; + uint32_t serial_checksum[8]; + uint8_t checksum; } __attribute__((packed)); #define VIA_SIGNATURE 0xAA55 -int volume_id_probe_via_raid(struct volume_id *id, __u64 off, __u64 size) +int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size) { - const __u8 *buf; - __u64 meta_off; + const uint8_t *buf; + uint64_t meta_off; struct via_meta *via; dbg("probing at offset 0x%llx, size 0x%llx", diff --git a/extras/volume_id/volume_id/via_raid.h b/extras/volume_id/volume_id/via_raid.h index 2d0651c413..429375dcc9 100644 --- a/extras/volume_id/volume_id/via_raid.h +++ b/extras/volume_id/volume_id/via_raid.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID_VIA_RAID_ #define _VOLUME_ID_VIA_RAID_ -extern int volume_id_probe_via_raid(struct volume_id *id, __u64 off, __u64 size); +extern int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size); #endif diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 8e944be0b1..4c4a42a00d 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -35,7 +35,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -71,7 +70,7 @@ #include "msdos.h" #include "ocfs2.h" -int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size) +int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) { if (id == NULL) return -EINVAL; @@ -224,7 +223,7 @@ struct volume_id *volume_id_open_node(const char *path) struct volume_id *volume_id_open_dev_t(dev_t devt) { struct volume_id *id; - __u8 tmp_node[VOLUME_ID_PATH_MAX]; + char tmp_node[VOLUME_ID_PATH_MAX]; snprintf(tmp_node, VOLUME_ID_PATH_MAX, "/dev/.volume_id-%u-%u-%u", getpid(), major(devt), minor(devt)); diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 4e0defdadd..a82b221028 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -21,7 +21,9 @@ #ifndef _VOLUME_ID_H_ #define _VOLUME_ID_H_ -#define VOLUME_ID_VERSION 46 +#include + +#define VOLUME_ID_VERSION 47 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 @@ -44,17 +46,17 @@ struct volume_id_partition { enum volume_id_usage usage_id; char *usage; char *type; - unsigned long long off; - unsigned long long len; - unsigned int partition_type_raw; + uint64_t off; + uint64_t len; + uint8_t partition_type_raw; }; struct volume_id { - unsigned char label_raw[VOLUME_ID_LABEL_SIZE]; - unsigned int label_raw_len; + uint8_t label_raw[VOLUME_ID_LABEL_SIZE]; + size_t label_raw_len; char label[VOLUME_ID_LABEL_SIZE+1]; - unsigned char uuid_raw[VOLUME_ID_UUID_SIZE]; - unsigned int uuid_raw_len; + 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; @@ -62,21 +64,21 @@ struct volume_id { char type_version[VOLUME_ID_FORMAT_SIZE]; struct volume_id_partition *partitions; - unsigned int partition_count; + size_t partition_count; int fd; - unsigned char *sbbuf; - unsigned int sbbuf_len; - unsigned char *seekbuf; - unsigned long long seekbuf_off; - unsigned int seekbuf_len; - int fd_close; + uint8_t *sbbuf; + size_t sbbuf_len; + uint8_t *seekbuf; + uint64_t seekbuf_off; + size_t seekbuf_len; + int fd_close:1; }; extern struct volume_id *volume_id_open_fd(int fd); extern struct volume_id *volume_id_open_node(const char *path); extern struct volume_id *volume_id_open_dev_t(dev_t devt); -extern int volume_id_probe_all(struct volume_id *id, unsigned long long off, unsigned long long size); +extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); extern void volume_id_close(struct volume_id *id); #endif diff --git a/extras/volume_id/volume_id/xfs.c b/extras/volume_id/volume_id/xfs.c index b8702a3fb3..e631e23ead 100644 --- a/extras/volume_id/volume_id/xfs.c +++ b/extras/volume_id/volume_id/xfs.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" @@ -40,21 +39,21 @@ #include "xfs.h" struct xfs_super_block { - __u8 magic[4]; - __u32 blocksize; - __u64 dblocks; - __u64 rblocks; - __u32 dummy1[2]; - __u8 uuid[16]; - __u32 dummy2[15]; - __u8 fname[12]; - __u32 dummy3[2]; - __u64 icount; - __u64 ifree; - __u64 fdblocks; + 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; } __attribute__((__packed__)); -int volume_id_probe_xfs(struct volume_id *id, __u64 off) +int volume_id_probe_xfs(struct volume_id *id, uint64_t off) { struct xfs_super_block *xs; diff --git a/extras/volume_id/volume_id/xfs.h b/extras/volume_id/volume_id/xfs.h index 76b1725664..537617f7e5 100644 --- a/extras/volume_id/volume_id/xfs.h +++ b/extras/volume_id/volume_id/xfs.h @@ -21,6 +21,6 @@ #ifndef _VOLUME_ID__ #define _VOLUME_ID__ -extern int volume_id_probe_xfs(struct volume_id *id, __u64 off); +extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off); #endif From d455b0085d65cd25915a34d84f894a4950d313a2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 1 Aug 2005 05:07:19 +0200 Subject: [PATCH 1404/4284] allow RUN to send the environment to a local socket RUN="socket:" will send the environment in the kernel uevent format to the named destination. Using the socket instead of the program to pass the hotplug events to the HAL daemon, cuts down the running time of udevstart from 0.8 to 0.4 seconds on my box. env -i ACTION=add DEVPATH=/block/hda/hda1 strace -s10000 ./udev block sendto(3, "add@/block/hda/hda1\0 ACTION=add\0DEVPATH=/block/hda/hda1\0UDEV_LOG=3\0 ID_TYPE=disk\0ID_MODEL=HTS726060M9AT00\0ID_SERIAL=MRH401M4G6UM9B\0 ID_REVISION=MH4OA6BA\0ID_BUS=ata\0ID_PATH=pci-0000:00:1f.1-ide-0:0\0 ID_FS_USAGE=other\0ID_FS_TYPE=swap\0ID_FS_VERSION=2\0 ID_FS_UUID=9352cfef-7687-47bc-a2a3-34cf136f72e1\0 ID_FS_LABEL=ThisIsSwap\0ID_FS_LABEL_SAFE=ThisIsSwap\0 DEVNAME=/dev/hda1\0" Signed-off-by: Kay Sievers --- udev.c | 8 ++++++-- udev_utils.c | 34 ++++++++++++++++++++++++++++++++++ udev_utils.h | 1 + udevsend.c | 14 +++++++------- udevstart.c | 8 ++++++-- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/udev.c b/udev.c index 4096b8b348..2a6e1efc99 100644 --- a/udev.c +++ b/udev.c @@ -123,8 +123,12 @@ int main(int argc, char *argv[], char *envp[]) struct name_entry *name_loop; dbg("executing run list"); - list_for_each_entry(name_loop, &udev.run_list, node) - execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); + 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:")], devpath, action); + else + execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); + } } udev_cleanup_device(&udev); diff --git a/udev_utils.c b/udev_utils.c index 2524baf592..fd4cd13e5d 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include #include #include @@ -372,6 +374,38 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c return 0; } +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; + int retval; + + 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; + /* only abstract namespace is supported */ + 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++; + } + + retval = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, addrlen); + if (retval != -1) + retval = 0; + + return retval; +} + int execute_program(const char *command, const char *subsystem, char *result, size_t ressize, size_t *reslen) { diff --git a/udev_utils.h b/udev_utils.h index 5f4152df82..5b223855b6 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -44,6 +44,7 @@ extern void replace_untrusted_chars(char *string); extern int name_list_add(struct list_head *name_list, const char *name, int sort); extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); +extern int pass_env_to_socket(const char *name, const char *devpath, const char *action); extern int execute_program(const char *command, const char *subsystem, char *result, size_t ressize, size_t *reslen); diff --git a/udevsend.c b/udevsend.c index 94ab6ff625..0ba1b58a4b 100644 --- a/udevsend.c +++ b/udevsend.c @@ -19,17 +19,17 @@ * */ +#include +#include +#include +#include +#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include #include #include "udev.h" diff --git a/udevstart.c b/udevstart.c index 0bcbc39737..5f3ba711f0 100644 --- a/udevstart.c +++ b/udevstart.c @@ -160,8 +160,12 @@ run: struct name_entry *name_loop; dbg("executing run list"); - list_for_each_entry(name_loop, &udev.run_list, node) - execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); + 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:")], devpath, "add"); + else + execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); + } } exit: sysfs_close_class_device(class_dev); From 1bc33626787f089523192c270790f9f878a4edd7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 1 Aug 2005 20:22:46 +0200 Subject: [PATCH 1405/4284] add udevmonitor, to debug netlink+udev events at the same time This rule: RUN+="socket:/org/kernel/udev/monitor" send the event to the running monitor. Running udevstart give a nice monitor output. Also the delay between the kernel uevent and the udev udev event can be investigated: pim:/home/kay/src/udev-kay # ./udevmonitor UEVENT[1122920113] add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1 UEVENT[1122920113] add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0 UEVENT[1122920113] add@/class/scsi_host/host12 UEVENT[1122920113] add@/class/usb_device/usbdev2.99 UEVENT[1122920113] add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host12/target12:0:0/12:0:0:0 UDEV [1122920113] add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1 UEVENT[1122920113] add@/block/sda UEVENT[1122920113] add@/class/scsi_generic/sg0 UEVENT[1122920113] add@/class/scsi_device/12:0:0:0 UDEV [1122920113] add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0 UDEV [1122920113] add@/class/scsi_host/host12 UDEV [1122920113] add@/class/usb_device/usbdev2.99 UDEV [1122920113] add@/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host12/target12:0:0/12:0:0:0 UDEV [1122920113] add@/block/sda UDEV [1122920113] add@/class/scsi_generic/sg0 UDEV [1122920113] add@/class/scsi_device/12:0:0:0 UEVENT[1122920115] add@/block/sda/sda1 UDEV [1122920115] add@/block/sda/sda1 pim:/home/kay/src/udev-kay # ./udevmonitor --env UDEV [1122920185] add@/block/sda/sda1 ACTION=add DEVPATH=/block/sda/sda1 SUBSYSTEM=block SEQNUM=2159 MINOR=1 MAJOR=8 PHYSDEVPATH=/devices/pci0000:00/0000:00:1d.1/usb2/2-1/2-1:1.0/host13/target13:0:0/13:0:0:0 PHYSDEVBUS=scsi PHYSDEVDRIVER=sd UDEVD_EVENT=1 UDEV_LOG=3 ID_VENDOR=IBM ID_MODEL=Memory_Key ID_REVISION=3.04 ID_SERIAL=IBM_Memory_Key_0218B301030027E8 ID_TYPE=disk ID_BUS=usb ID_PATH=usb-0218B301030027E8:0:0:0 ID_FS_USAGE=filesystem ID_FS_TYPE=vfat ID_FS_VERSION=FAT16 ID_FS_UUID=42D8-9E02 ID_FS_LABEL_SAFE=s_p_c DEVNAME=/dev/sda1 Signed-off-by: Kay Sievers --- Makefile | 12 +++- udevd.h | 2 +- udevmonitor.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 udevmonitor.c diff --git a/Makefile b/Makefile index c9807de4bc..5eb93bd500 100644 --- a/Makefile +++ b/Makefile @@ -49,6 +49,7 @@ COMPILE = udevrulescompile INITSENDER = udevinitsend RECORDER = udeveventrecorder CONTROL = udevcontrol +MONITOR = udevmonitor INFO = udevinfo TESTER = udevtest STARTER = udevstart @@ -204,7 +205,7 @@ endif # config files automatically generated GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf -all: $(ROOT) $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) \ +all: $(ROOT) $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) $(MONITOR)\ $(DAEMON) $(COMPILE) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) @extras="$(EXTRAS)" ; for target in $$extras ; do \ echo $$target ; \ @@ -275,6 +276,7 @@ $(COMPILE).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(INITSENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(RECORDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(CONTROL).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) +$(MONITOR).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(STARTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) @@ -313,6 +315,10 @@ $(CONTROL): $(KLCC) $(CONTROL).o $(OBJS) udevd.h $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CONTROL).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ +$(MONITOR): $(KLCC) $(MONITOR).o $(OBJS) udevd.h + $(QUIET) $(LD) $(LDFLAGS) -o $@ $(MONITOR).o $(OBJS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + $(STARTER): $(KLCC) $(STARTER).o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(STARTER).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ @@ -324,7 +330,7 @@ clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) \ - $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) $(TESTER) $(STARTER) + $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) $(MONITOR) $(TESTER) $(STARTER) -rm -f ccdv $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)" ; for target in $$extras ; do \ @@ -374,6 +380,7 @@ install: install-config install-man all $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(CONTROL) $(DESTDIR)$(sbindir)/$(CONTROL) + $(INSTALL_PROGRAM) -D $(MONITOR) $(DESTDIR)$(sbindir)/$(MONITOR) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) @@ -399,6 +406,7 @@ uninstall: uninstall-man - rm $(sbindir)/$(INITSENDER) - rm $(sbindir)/$(RECORDER) - rm $(sbindir)/$(CONTROL) + - rm $(sbindir)/$(MONITOR) - rm $(sbindir)/$(STARTER) - rm $(usrbindir)/$(INFO) - rm $(usrbindir)/$(TESTER) diff --git a/udevd.h b/udevd.h index aadae31e57..da5f6b94f9 100644 --- a/udevd.h +++ b/udevd.h @@ -22,7 +22,7 @@ #include "list.h" #define UDEV_MAGIC "udevd_" UDEV_VERSION -#define UDEVD_SOCK_PATH "udevd" +#define UDEVD_SOCK_PATH "/org/kernel/udev/udevd" #define UDEVSEND_WAIT_MAX_SECONDS 3 #define UDEVSEND_WAIT_LOOP_PER_SECOND 10 diff --git a/udevmonitor.c b/udevmonitor.c new file mode 100644 index 0000000000..f4f28b1659 --- /dev/null +++ b/udevmonitor.c @@ -0,0 +1,185 @@ +/* + * udevmonitor.c + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev.h" +#include "udevd.h" + +static int uevent_netlink_sock; +static int udev_monitor_sock; + +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); + 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 = 0xffffffff; + + 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; +} + +int main(int argc, char *argv[]) +{ + int env = 0; + int maxsockplus; + fd_set readfds; + int retval; + + if (getuid() != 0) { + printf("need to be root, exit\n"); + exit(1); + } + + if (argc == 2 && strstr(argv[1], "--env")) + env = 1; + + init_uevent_netlink_sock(); + init_udev_monitor_socket(); + + FD_ZERO(&readfds); + FD_SET(uevent_netlink_sock, &readfds); + FD_SET(udev_monitor_sock, &readfds); + maxsockplus = udev_monitor_sock+1; + + while (1) { + static char buf[UEVENT_BUFFER_SIZE*2]; + ssize_t buflen; + fd_set workreadfds; + + buflen = 0; + workreadfds = readfds; + + retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); + if (retval < 0) { + if (errno != EINTR) + fprintf(stderr, "error receiving uevent message\n"); + continue; + } + + if (FD_ISSET(uevent_netlink_sock, &workreadfds)) { + buflen = recv(uevent_netlink_sock, &buf, sizeof(buf), 0); + if (buflen <= 0) { + fprintf(stderr, "error receiving uevent message\n"); + continue; + } + printf("UEVENT[%i] %s\n", time(NULL), buf); + } + + if (FD_ISSET(udev_monitor_sock, &workreadfds)) { + buflen = recv(udev_monitor_sock, &buf, sizeof(buf), 0); + if (buflen <= 0) { + fprintf(stderr, "error receiving udev message\n"); + continue; + } + printf("UDEV [%i] %s\n", time(NULL), buf); + } + + if (buflen == 0) + continue; + + /* print environment */ + if (env) { + size_t bufpos; + + /* start of payload */ + bufpos = strlen(buf) + 1; + + while (bufpos < (size_t)buflen) { + int keylen; + char *key; + + key = &buf[bufpos]; + keylen = strlen(key); + if (keylen == 0) + break; + printf("%s\n", key); + bufpos += keylen + 1; + } + printf("\n"); + } + } + + close(uevent_netlink_sock); + close(udev_monitor_sock); + exit(1); +} From be962ec9a8fa6e7bd5328b29894e7b6186496cc6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Aug 2005 15:44:02 -0700 Subject: [PATCH 1406/4284] Update gentoo rules file. Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 53 +++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 572e5c8ce1..75c192ffaa 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -1,16 +1,33 @@ -# /etc/udev/udev.rules: device naming rules for udev +# /etc/udev/rules/50-udev.rules: device naming rules for udev # -# Gentoo specific rules, based a bit on devfs rules, but much simpler. +# 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. +# -########################################################### -# -# For devfs similar /dev layout (neater) -# -########################################################### +# 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="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" # all block devices SUBSYSTEM=="block", GROUP="disk" @@ -141,28 +158,6 @@ 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" -# 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%n", SYMLINK+="%k", GROUP="tty" -KERNEL=="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", 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="0666" KERNEL=="urandom", NAME="%k", MODE="0444" From 97b7aa1f7813cbe26f5fb928d44956ddb7bc70a9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 1 Aug 2005 16:37:41 -0700 Subject: [PATCH 1407/4284] Added horrible (but fun) path_id script to extras. Signed-off-by: Greg Kroah-Hartman --- extras/path_id | 390 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 390 insertions(+) create mode 100755 extras/path_id diff --git a/extras/path_id b/extras/path_id new file mode 100755 index 0000000000..8391f2e586 --- /dev/null +++ b/extras/path_id @@ -0,0 +1,390 @@ +#!/bin/sh +#set -x + +# this script should provide the shortest possible unique hardware path +# to a block device +# + +# Horrible script. Handle with extreme care. + +# to be called from udev +# DEVPATH=/block/sda/sda3 $0 (or similar) +# $0 /block/sda +# $0 /sys/block/sda + +# example for all: +# for i in `find /sys/block -name dev` ;do DEVPATH="`echo $i | sed -e 's@^/sys\|/dev@@g'`" $0 ; done + +# examples: +# SCSI cdrom +# /block/sr0 -> /devices/pci0002:30/0002:30:0c.0/host0/0:0:1:0 +# result: pci-0002:30:0c.0-scsi-0:0:1:0 +# SCSI disk +# /block/sda -> /devices/pci0002:30/0002:30:0c.0/host0/0:0:4:0 +# result: pci-0002:30:0c.0-scsi-0:0:4:0 +# SATA disk, 4 channels per controller +# /block/sda -> /devices/pci0001:00/0001:00:07.0/0001:05:0c.0/host0/0:0:0:0 +# result: pci-0001:05:0c.0-scsi-0:0:0:0 +# IDE disk +# /block/hda -> /devices/pci0002:02/0002:02:0d.0/ide0/0.0 +# result: pci-0002:02:0d.0-ide-0.0 +# IDE cdrom on a Mac ASIC: +# /block/hdc -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.00020000:ata-3/ide1/1.0 +# result: mac-io_ata-3_master +# IDE cdrom on a Mac ASIC, with ide-scsi: +# /block/sr0 -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.0001f000:ata-4/ide0/0.1/host2/2:0:0:0 +# result: mac-io_ata-4_slave + +# USB CDrom drive without 'serial' number: +# reusing 'product' and 'manufacturer' string, if available +# /block/sr0 -> /devices/pci0001:00/0001:00:04.0/0001:02:0b.0/usb4/4-2/4-2:1.0/host4/4:0:0:0 +# result: usb-storage-odd-Freecom-USIDERev930:0:0:0 + +# devices may have several interfaces on one PCI device, like IDE: +# pci-0001:00:04.0_ide1-master +# pci-0001:00:04.0_ide2-master +# pci-0001:00:04.0_ide2-slave +# they are marked as ports, it is expected that the driver shows +# ide1 even if there is nothing connected to either master or slave +# interface +# +# match order is important. +# first IDE to find ide-scsi devices. +# then SCSI +# first usb-storage +# then firewire sbp2 +# then the rest + +PATH=/lib/klibc/bin #/usr:/usr/sbin:/usr/bin:/sbin:/bin +SYSFS=/sys +export PATH +RESULT=1 +CDROM= +TYPE= +OPWD="`pwd`" +# Check for 'pwd -P' +if $(pwd -P > /dev/null 2>&1); then + pwd_cmd="pwd -P" +else + pwd_cmd="pwd" +fi +full_sysfs_class_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 [ ! -d $SYSFS$DEVPATH ] ; then + exit 1 +fi +if [ ! -f $SYSFS$DEVPATH/dev ] ; then + exit 1 +fi + +case "$DEVPATH" in + /block/*) + TYPE=block + ;; + /class/*) + TYPE="${DEVPATH#/class/}" + TYPE="${TYPE%%/*}" + ;; + *) + exit 1 + ;; +esac + +# +## +# + +get_port () { + 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 + if [ "$port" != "0" ] ; then + echo $(($2 - $offset)) + fi +} + +handle_block_ide () { +: handle_block_ide $* + local DEV=$1 + local port idedev idecontroller + # IDE + : DEV $DEV + d=$DEV + case "$DEV" in + # remove ide-scsi part, leave only channel info + */ide[0-9]*/host[0-9]*) + while [ ! -z "$d" ] ; do + case "$d" in + */host[0-9]*) + d="${d%/*}" + continue + ;; + *) + break + ;; + esac + done + ;; + esac + idedev=$d + while [ ! -z "$d" ] ; do + case "$d" in + */ide[0-9]*) + port="${d##*/}" + d="${d%/*}" + continue + ;; + *) + break + ;; + esac + done + idecontroller=$d + # port info if the controller has more than one interface + port="${port#ide}" + : port $port d $d + : idedev $idedev kernel_port $port + case "${idedev##*.}" in + 0) + channel=0 + ;; + 1) + channel=1 + ;; + *) + echo "Error: $idedev is neither master or slave" >&2 + esac + case "$d" in + *:mac-io/*) + : mac-io: $d + d="`echo $d | sed -e 's@^.*:mac-io[^:]\+:\([^/]\+\).*@mac-io_\1@'`" + ;; + /sys/devices) + # PCMCIA devices + ifname=${full_sysfs_class_path##*/} + set -- `sed -n "/$ifname/p" /var/lib/pcmcia/stab` + d="pcmcia-$1" + ;; + *) + d="pci-${d##*/}" + # d="`echo $d | sed -e 's@^.*/\([^/]\{1,\}\)/.@pci-\1@'`" + ;; + esac + + cd $idecontroller + port="`get_port ide $port`" + cd "$OPWD" + : hardware_port $port + if [ -z "$port" ] ; then + d="${d}-ide-0:$channel" + else + d="${d}-ide-${port}:$channel" + fi + + RESULT=0 +} + +handle_block_scsi () { +: handle_block_scsi $* + local DEV=$1 + local cil controller_port controller_dev + # SCSI device + cil="${DEV##*/}" + cil="${cil#*:}" + controller_dev=$DEV + while [ ! -z "$controller_dev" ] ; do + case "$controller_dev" in + */host[0-9]*) + controller_port=$controller_dev + controller_dev="${controller_dev%/*}" + ;; + *) break ;; + esac + done + : controller_dev $controller_dev + : controller_port $controller_port + # a host controller may have more than one interface/port + controller_port="${controller_port##*/}" + controller_port="${controller_port##host}" + # + case "$controller_dev" in + # grand central, old powermacs + *:gc/*) + adapter="`echo $controller_dev | sed -e 's@/[^/]\{1,\}$@@;s@^.*/@@;s@^.*:@@'`" + bus="gc" + ;; + *) + adapter="${controller_dev##*/}" + bus="pci" + ;; + esac + cd "$controller_dev" + controller_port="`get_port host $controller_port`" + cd "$OPWD" + d="$bus-$adapter" + if [ -z "$controller_port" ] ; then + controller_port=0 + fi + d="${d}-scsi-${controller_port}:${cil}" + RESULT=0 +} + +handle_block_usb_storage () { +: handle_block_usb_storage $* + local DEV=$1 + cil="${DEV##*/}" + cil="${cil#*:}" + controller_dev=$DEV + while [ ! -z "$controller_dev" ] ; do + case "$controller_dev" in + */host[0-9]*) + controller_dev="${controller_dev%/*}" + ;; + *) break ;; + esac + done + : controller_dev $controller_dev + # + # usb-storage devs have a serial number, hopefully unique + serial= + if [ -f $controller_dev/../serial ] ; then + serial="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../serial`" + : serial XXX_${serial}_XXX + d="usb-$serial" + serial="`echo $serial | sed -e 's@[ 0]\{1,\}@@g'`" + fi + if [ -z "$serial" ] ; then + # no serial, broken device + # has eventually binary junk in vpd + identifier= + if [ -f $controller_dev/../product ] ; then + product="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../product`" + fi + if [ -f $controller_dev/../manufacturer ] ; then + manufacturer="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../manufacturer`" + fi + if [ -z "$product" -o -z "$manufacturer" ] ; then + read idvendor < $controller_dev/../idVendor + read idproduct < $controller_dev/../idProduct + identifier="0x${idvendor}-0x${idproduct}" + else + identifier="${manufacturer}-${product}" + fi + d="usb-${identifier}" + fi + d="$d:$cil" + RESULT=0 + + +} + +handle_block () { + full_sysfs_class_path="$SYSFS$DEVPATH" + if [ ! -f $full_sysfs_class_path/dev ] ; then return ; fi + # the main device has (hopefully) a symlink to the real device + # a partition is a subdir of the main (raw) device + if [ ! -L $full_sysfs_class_path/device ] ; then + if [ -f $full_sysfs_class_path/range ] ; then return ; fi + full_sysfs_class_path="${full_sysfs_class_path%/*}" + : full_sysfs_class_path "$full_sysfs_class_path" + if [ ! -L $full_sysfs_class_path/device -o ! -f $full_sysfs_class_path/dev ] ; then + return + fi + fi + cd $full_sysfs_class_path/device + full_sysfs_device_path="`$pwd_cmd`" + cd "$OPWD" + D=$full_sysfs_device_path + case "$D" in + */ide[0-9]/[0-9].[0-9]*|*/ide[0-9][0-9]/[0-9][0-9].[0-9]*) + handle_block_ide "$D" + ;; + */usb[0-9]*/[0-9]*/host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*) + handle_block_usb_storage "$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 + ;; + */host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*) + # check for ieee1394 sbp2 + if test -f $D/ieee1394_id ; then + read ieee1394_id < $D/ieee1394_id + d="`echo ieee1394-${ieee1394_id} | sed -e 's@:@-@g'`" + RESULT=0 + else + handle_block_scsi "$D" + fi + ;; + + *) + : not handled + RESULT=1 + return + + ;; + esac + # look for a partition + if [ "$full_sysfs_class_path" != "$SYSFS$DEVPATH" ] ; then + dp="`echo $SYSFS$DEVPATH | sed -e 's@^/.*/@@;s@^[^0-9]\{1,\}@@;s@.*_@@'`" + case "$d" in + *[0-9]) + d="${d}p${dp}" + ;; + *) + d="${d}${dp}" + ;; + esac + fi + # done + echo "ID_PATH=$d" +} + +case "$TYPE" in + block) + handle_block + ;; + *) + RESULT=1 + ;; +esac +exit $RESULT From 61341fae4f84917d3963fff205e9efc31a4cbd16 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 2 Aug 2005 04:32:19 +0200 Subject: [PATCH 1408/4284] update release notes for next version Signed-off-by: Kay Sievers --- RELEASE-NOTES | 22 ++++++++++++++++++++++ udev_utils.c | 1 + 2 files changed, 23 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index db1e6b838f..09d29c8b0a 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,25 @@ +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}=="?*" +cause "*" 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. diff --git a/udev_utils.c b/udev_utils.c index fd4cd13e5d..500d595c01 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -403,6 +403,7 @@ int pass_env_to_socket(const char *sockname, const char *devpath, const char *ac if (retval != -1) retval = 0; + close(sock); return retval; } From 74f1ce92c462a8df8927a121b3b7a43fdcfdecaa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Aug 2005 12:28:50 -0700 Subject: [PATCH 1409/4284] Added persistent name rules for block devices to gentoo rule file. Copied from Kay's rules from the SuSE package. Let the fun begin... Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 75c192ffaa..0c96969dbc 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -243,6 +243,38 @@ KERNEL=="issm*", NAME="infiniband/%k" # tpm devices KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" +# block device disk id's +SUBSYSTEM=="block", GROUP="disk", MODE="0640" +KERNEL=="hd*[!0-9]", ACTION=="add", IMPORT="/etc/udev/scripts/ata_id --export $tempnode" +KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" +KERNEL=="hd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" + +KERNEL=="sd*[!0-9]", ACTION=="add", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/usb_id -x" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/scsi_id -g -x -s %p" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" +KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + +# Skip id for ram / loop / fd +SUBSYSTEM=="block", KERNEL=="ram*", GOTO="no_volume_id" +SUBSYSTEM=="block", KERNEL=="loop*", GOTO="no_volume_id" +SUBSYSTEM=="block", KERNEL=="fd*", GOTO="no_volume_id" + +SUBSYSTEM=="block", KERNEL=="*[!0-9]", ACTION=="add", ENV{ID_TYPE}=="?*", IMPORT="/etc/udev/scripts/path_id %p", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}" +SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" +SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", ENV{ID_PATH}=="?*", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}-part%n" + +# volume-label/uuid +SUBSYSTEM=="block", KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" +SUBSYSTEM=="block", KERNEL=="sr*", GOTO="no_volume_id" +SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT="/etc/udev/scripts/vol_id --export $tempnode" +SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" +SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" +SUBSYSTEM=="block", LABEL="no_volume_id" + + # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems # run /etc/hotplug.d/ stuff only if we came from a hotplug event, not for udevstart ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" @@ -250,3 +282,5 @@ ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" # always run /etc/dev.d/ stuff for now. RUN+="/sbin/udev_run_devd" +# debugging monitor +RUN+="socket:/org/kernel/udev/monitor" From cfb7ac2b5b3ff38cd9be8a515eaa31696cca7941 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 Aug 2005 13:56:41 -0700 Subject: [PATCH 1410/4284] 065 release --- ChangeLog | 15 +++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ce54a817d..bc62f95c61 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 5eb93bd500..7618d0f7fd 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 064 +VERSION = 065 ROOT = udev DAEMON = udevd SENDER = udevsend diff --git a/udev.spec b/udev.spec index 2027725674..52bfa2ffae 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace device manager providing devfs functionality Name: udev -Version: 064 +Version: 065 Release: 1 License: GPL Group: Utilities/System From 47e353f9b9c1a95d4e7cdf0e9be3d746585851f1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 4 Aug 2005 12:24:41 +0200 Subject: [PATCH 1411/4284] add NETLINK define for the lazy distros Signed-off-by: Kay Sievers --- udev_libc_wrapper.h | 4 ++++ udevd.c | 4 ---- udevmonitor.c | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 4bb68913a9..a12af64c24 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -42,6 +42,10 @@ #define __FD_ZERO(set) ((void) memset ((void*) (set), 0, sizeof (fd_set))) #endif +#ifndef NETLINK_KOBJECT_UEVENT +#define NETLINK_KOBJECT_UEVENT 15 +#endif + #include #ifdef __KLIBC__ diff --git a/udevd.c b/udevd.c index be401bec30..fa14c56073 100644 --- a/udevd.c +++ b/udevd.c @@ -49,10 +49,6 @@ #include "udevd.h" #include "logging.h" -#ifndef NETLINK_KOBJECT_UEVENT -#define NETLINK_KOBJECT_UEVENT 15 -#endif - /* global variables*/ static int udevd_sock; static int uevent_netlink_sock; diff --git a/udevmonitor.c b/udevmonitor.c index f4f28b1659..51e8a2ab0b 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -33,6 +33,7 @@ #include "udev.h" #include "udevd.h" +#include "udev_libc_wrapper.h" static int uevent_netlink_sock; static int udev_monitor_sock; From 52dbd80e783adaa0a66d4cf981f5b34d2af66f60 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 4 Aug 2005 16:33:53 -0700 Subject: [PATCH 1412/4284] updated gentoo rule file to handle removable ide devices. Thanks to Kay for the quick fix. Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 0c96969dbc..d208f5068d 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -245,6 +245,12 @@ KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" # block device disk id's SUBSYSTEM=="block", GROUP="disk", MODE="0640" + +# skip accessing removable ide devices, cause the ide drivers are horrible broken +SUBSYSTEM=="block", BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" +SUBSYSTEM=="block", BUS=="ide", SYSFS{../removable}="1", GOTO="no_volume_id" + +# persistent disk device links /dev/disk/ KERNEL=="hd*[!0-9]", ACTION=="add", IMPORT="/etc/udev/scripts/ata_id --export $tempnode" KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" KERNEL=="hd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" From 738428b4499211247dafa394805ecaa2cb313f03 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 5 Aug 2005 01:52:57 +0200 Subject: [PATCH 1413/4284] read sysfs attribute also from parent class device Signed-off-by: Kay Sievers --- udev_rules.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/udev_rules.c b/udev_rules.c index 6a485f08af..d86b8e8599 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -295,6 +295,7 @@ static int find_free_number(struct udevice *udev, const char *name) static int find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, const char *name, char *value, size_t len) { + struct sysfs_class_device *class_dev_parent; struct sysfs_attribute *tmpattr; dbg("look for device attribute '%s'", name); @@ -303,6 +304,12 @@ static int find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sys tmpattr = sysfs_get_classdev_attr(class_dev, name); if (tmpattr) goto attr_found; + class_dev_parent = sysfs_get_classdev_parent(class_dev); + if (class_dev_parent) { + tmpattr = sysfs_get_classdev_attr(class_dev_parent, name); + if (tmpattr) + goto attr_found; + } } if (sysfs_device) { dbg("look for devices attribute '%s/%s'", sysfs_device->path, name); From 13d11705bf0117365afc3f9210f4d568a2baa69c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 8 Aug 2005 02:21:55 +0200 Subject: [PATCH 1414/4284] switch some strlcpy's to memcpy strlcpy counts the sourec string lengt and is therefore not suitable to copy a defined length of characters from one string to another. Signed-off-by: Kay Sievers --- udev.c | 1 + udev_config.c | 3 ++- udev_db.c | 36 ++++++++++++++++++++++++------------ udev_libc_wrapper.c | 3 ++- udev_rules.c | 3 ++- udev_rules_parse.c | 10 +++++++++- 6 files changed, 40 insertions(+), 16 deletions(-) diff --git a/udev.c b/udev.c index 2a6e1efc99..6a0beda1c2 100644 --- a/udev.c +++ b/udev.c @@ -131,6 +131,7 @@ int main(int argc, char *argv[], char *envp[]) } } + udev_rules_close(&rules); udev_cleanup_device(&udev); exit: diff --git a/udev_config.c b/udev_config.c index c57e36cd8c..f0b409b067 100644 --- a/udev_config.c +++ b/udev_config.c @@ -137,7 +137,8 @@ static int parse_config_file(void) if (bufline[0] == COMMENT_CHARACTER) continue; - strlcpy(line, bufline, count+1); + memcpy(line, bufline, count); + line[count] = '\0'; linepos = line; retval = get_key(&linepos, &variable, &value); diff --git a/udev_db.c b/udev_db.c index ef0e9a71ae..f9adf5c631 100644 --- a/udev_db.c +++ b/udev_db.c @@ -127,42 +127,49 @@ static int parse_db_file(struct udevice *udev, const char *filename) case 'P': if (count > sizeof(udev->devpath)) count = sizeof(udev->devpath); - strlcpy(udev->devpath, &bufline[2], count-1); + memcpy(udev->devpath, &bufline[2], count-2); + udev->devpath[count-2] = '\0'; break; case 'N': if (count > sizeof(udev->name)) count = sizeof(udev->name); - strlcpy(udev->name, &bufline[2], count-1); + memcpy(udev->name, &bufline[2], count-2); + udev->name[count-2] = '\0'; break; case 'M': if (count > sizeof(line)) count = sizeof(line); - strlcpy(line, &bufline[2], count-1); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; sscanf(line, "%u:%u", &major, &minor); udev->devt = makedev(major, minor); break; case 'S': if (count > sizeof(line)) count = sizeof(line); - strlcpy(line, &bufline[2], count-1); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; name_list_add(&udev->symlink_list, line, 0); break; case 'A': if (count > sizeof(line)) count = sizeof(line); - strlcpy(line, &bufline[2], count-1); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; udev->partitions = atoi(line); break; case 'R': if (count > sizeof(line)) count = sizeof(line); - strlcpy(line, &bufline[2], count-1); + 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); - strlcpy(line, &bufline[2], count-1); + memcpy(line, &bufline[2], count-2); + line[count-2] = '\0'; name_list_add(&udev->env_list, line, 0); break; } @@ -244,16 +251,19 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) case 'P': if (count > sizeof(path)) count = sizeof(path); - strlcpy(path, &bufline[2], count-1); + memcpy(path, &bufline[2], count-2); + path[count-2] = '\0'; break; case 'N': case 'S': if (count > sizeof(nodename)) count = sizeof(nodename); - strlcpy(nodename, &bufline[2], count-1); + memcpy(nodename, &bufline[2], count-2); + nodename[count-2] = '\0'; dbg("compare '%s' '%s'", nodename, name); if (strcmp(nodename, name) == 0) { - strlcpy(devpath, path, len); + memcpy(devpath, &bufline[2], count-2); + devpath[count-2] = '\0'; file_unmap(buf, bufsize); closedir(dir); return 0; @@ -319,12 +329,14 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam case 'P': if (count > sizeof(path)) count = sizeof(path); - strlcpy(path, &bufline[2], count-1); + memcpy(path, &bufline[2], count-2); + path[count-2] = '\0'; break; case 'N': if (count > sizeof(nodename)) count = sizeof(nodename); - strlcpy(nodename, &bufline[2], count-1); + memcpy(nodename, &bufline[2], count-2); + nodename[count-2] = '\0'; break; default: continue; diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index 1852141c93..4e9f9f1fe8 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -159,7 +159,8 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) if (count >= sizeof(line)) continue; - strlcpy(line, bufline, count); + memcpy(line, bufline, count-1); + line[count-1] = '\0'; pos = line; /* get name */ diff --git a/udev_rules.c b/udev_rules.c index d86b8e8599..d42b219d7d 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -187,7 +187,8 @@ static int import_keys_into_env(struct udevice *udev, const char *buf, size_t bu if (bufline[0] == COMMENT_CHARACTER) continue; - strlcpy(line, bufline, count+1); + memcpy(line, bufline, count); + line[count] = '\0'; linepos = line; if (get_key(&linepos, &variable, &value) == 0) { diff --git a/udev_rules_parse.c b/udev_rules_parse.c index be0757374e..4580a779c6 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -89,7 +89,7 @@ static int get_key(char **line, char **key, enum key_operation *operation, char char *temp; linepos = *line; - if (!linepos) + if (linepos == NULL && linepos[0] == '\0') return -1; /* skip whitespace */ @@ -97,7 +97,10 @@ static int get_key(char **line, char **key, enum key_operation *operation, char linepos++; /* get the key */ + if (linepos[0] == '\0') + return -1; *key = linepos; + while (1) { linepos++; if (linepos[0] == '\0') @@ -120,6 +123,8 @@ static int get_key(char **line, char **key, enum key_operation *operation, char /* skip whitespace after key */ while (isspace(linepos[0])) linepos++; + if (linepos[0] == '\0') + return -1; /* get operation type */ if (linepos[0] == '=' && linepos[1] == '=') { @@ -152,6 +157,8 @@ static int get_key(char **line, char **key, enum key_operation *operation, char /* skip whitespace after operator */ while (isspace(linepos[0])) linepos++; + if (linepos[0] == '\0') + return -1; /* get the value*/ if (linepos[0] == '"') @@ -634,6 +641,7 @@ int udev_rules_init(struct udev_rules *rules, int resolve_names) list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { parse_file(rules, name_loop->name); list_del(&name_loop->node); + free(name_loop); } } From 63cc8f049100c9b76ca4e37fc5c8976b6e92a207 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 8 Aug 2005 05:07:36 +0200 Subject: [PATCH 1415/4284] allow clean shutdown of udevd Signed-off-by: Kay Sievers --- udev_rules_parse.c | 14 ++++++++------ udevd.c | 30 ++++++++++++++++++++---------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 4580a779c6..cededf002d 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -650,10 +650,12 @@ int udev_rules_init(struct udev_rules *rules, int resolve_names) void udev_rules_close(struct udev_rules *rules) { - if (rules->mapped) - file_unmap(rules->buf, rules->bufsize); - else - free(rules->buf); - - rules->buf = NULL; + if (rules->buf) { + if (rules->mapped) { + rules->mapped = 0; + file_unmap(rules->buf, rules->bufsize); + } else + free(rules->buf); + rules->buf = NULL; + } } diff --git a/udevd.c b/udevd.c index fa14c56073..9242acce31 100644 --- a/udevd.c +++ b/udevd.c @@ -58,6 +58,7 @@ static int pipefds[2]; static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int sig_flag; +static volatile int udev_exit; static int init_phase = 1; static int run_exec_q; static int stop_exec_q; @@ -641,23 +642,20 @@ static void asmlinkage sig_handler(int signum) switch (signum) { case SIGINT: case SIGTERM: - exit(20 + signum); + udev_exit = 1; break; case SIGALRM: /* set flag, then write to pipe if needed */ run_msg_q = 1; - goto do_write; break; case SIGCHLD: /* set flag, then write to pipe if needed */ sigchilds_waiting = 1; - goto do_write; break; } -do_write: - /* if pipe is empty, write to pipe to force select to return - * immediately when it gets called + /* if pipe is empty, write to pipe to force select to return, + * which will wakeup our mainloop */ if (!sig_flag) { rc = write(pipefds[1],&signum,sizeof(signum)); @@ -839,7 +837,7 @@ int main(int argc, char *argv[], char *envp[]) chdir("/"); umask(umask(077) | 022); - /*set a reasonable scheduling priority for the daemon */ + /* set a reasonable scheduling priority for the daemon */ setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); /* Set fds to dev/null */ @@ -887,6 +885,7 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGTERM, &act, NULL); sigaction(SIGALRM, &act, NULL); sigaction(SIGCHLD, &act, NULL); + sigaction(SIGHUP, &act, NULL); if (init_uevent_netlink_sock() < 0) { dbg("uevent socket not available"); @@ -941,11 +940,11 @@ int main(int argc, char *argv[], char *envp[]) FD_ZERO(&readfds); FD_SET(udevd_sock, &readfds); - if (uevent_netlink_sock != -1) + if (uevent_netlink_sock > 0) FD_SET(uevent_netlink_sock, &readfds); FD_SET(pipefds[0], &readfds); maxsockplus = udevd_sock+1; - while (1) { + while (!udev_exit) { struct uevent_msg *msg; fd_set workreadfds = readfds; @@ -957,6 +956,7 @@ int main(int argc, char *argv[], char *envp[]) continue; } + /* get user socket message */ if (FD_ISSET(udevd_sock, &workreadfds)) { msg = get_udevd_msg(); if (msg) { @@ -970,6 +970,7 @@ int main(int argc, char *argv[], char *envp[]) } } + /* get kernel netlink message */ if (FD_ISSET(uevent_netlink_sock, &workreadfds)) { msg = get_netlink_msg(); if (msg) { @@ -982,9 +983,11 @@ int main(int argc, char *argv[], char *envp[]) } } + /* received a signal, clear our notification pipe */ if (FD_ISSET(pipefds[0], &workreadfds)) user_sighandler(); + /* forked child have returned */ if (sigchilds_waiting) { sigchilds_waiting = 0; reap_sigchilds(); @@ -1009,6 +1012,13 @@ int main(int argc, char *argv[], char *envp[]) } exit: + if (udevd_sock > 0) + close(udevd_sock); + + if (uevent_netlink_sock > 0) + close(uevent_netlink_sock); + logging_close(); - return 1; + + return 0; } From bfd12948927b84b3ce990403969c1d10081c1fed Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 8 Aug 2005 17:43:42 +0200 Subject: [PATCH 1416/4284] add flag for reading of precompiled rules Rules can be precompiled and stored on disk for initramfs, to avoid parsing the rules with every event again and again. Also the OWNER and GROUP names are already resolved to numerical values in the compiled rules. This flag is used for the upcoming move of the rules parsing into udevd: If the real root is mounted udevd is started and parses the rules only once. The event processes will inherit the already parsed rules from the daemon, so we want to ignore any precompiled rules and use the real rules files and watch the filesystem for changes to reload the rules automatically. Signed-off-by: Kay Sievers --- udev.c | 2 +- udev_rules.h | 2 +- udev_rules_parse.c | 17 ++++++++++------- udevrulescompile.c | 2 +- udevstart.c | 2 +- udevtest.c | 2 +- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/udev.c b/udev.c index 6a0beda1c2..ecfd5644ec 100644 --- a/udev.c +++ b/udev.c @@ -115,7 +115,7 @@ int main(int argc, char *argv[], char *envp[]) } udev_init_device(&udev, devpath, subsystem, action); - udev_rules_init(&rules, 0); + udev_rules_init(&rules, 1, 0); retval = udev_process_event(&rules, &udev); diff --git a/udev_rules.h b/udev_rules.h index 9e3931129f..be13378e4e 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -104,7 +104,7 @@ struct udev_rules { int resolve_names; }; -extern int udev_rules_init(struct udev_rules *rules, int resolve_names); +extern int udev_rules_init(struct udev_rules *rules, int read_compiled, int resolve_names); extern void udev_rules_close(struct udev_rules *rules); extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize, diff --git a/udev_rules_parse.c b/udev_rules_parse.c index cededf002d..488b7a7ff0 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -607,7 +607,7 @@ static int rules_map(struct udev_rules *rules, const char *filename) return 0; } -int udev_rules_init(struct udev_rules *rules, int resolve_names) +int udev_rules_init(struct udev_rules *rules, int read_compiled, int resolve_names) { char comp[PATH_SIZE]; struct stat stats; @@ -617,14 +617,17 @@ int udev_rules_init(struct udev_rules *rules, int resolve_names) rules->resolve_names = resolve_names; /* check for precompiled rules */ - strlcpy(comp, udev_rules_filename, sizeof(comp)); - strlcat(comp, ".compiled", sizeof(comp)); - if (stat(comp, &stats) == 0) { - dbg("map compiled rules '%s'", comp); - if (rules_map(rules, comp) == 0) - return 0; + if (read_compiled) { + strlcpy(comp, udev_rules_filename, sizeof(comp)); + strlcat(comp, ".compiled", sizeof(comp)); + if (stat(comp, &stats) == 0) { + dbg("map compiled rules '%s'", comp); + if (rules_map(rules, comp) == 0) + return 0; + } } + /* parse rules file or all matching files in directory */ if (stat(udev_rules_filename, &stats) != 0) return -1; diff --git a/udevrulescompile.c b/udevrulescompile.c index a71286abe7..a2c5f2e9fc 100644 --- a/udevrulescompile.c +++ b/udevrulescompile.c @@ -69,7 +69,7 @@ int main(int argc, char *argv[], char *envp[]) unlink(comp); unlink(comp_tmp); - udev_rules_init(&rules, 1); + udev_rules_init(&rules, 0, 1); f = fopen(comp_tmp, "w"); if (f == NULL) { diff --git a/udevstart.c b/udevstart.c index 5f3ba711f0..4288db9d38 100644 --- a/udevstart.c +++ b/udevstart.c @@ -367,7 +367,7 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(UDEV_ALARM_TIMEOUT); - udev_rules_init(&rules, 1); + udev_rules_init(&rules, 0, 1); udev_scan_block(); udev_scan_class(); diff --git a/udevtest.c b/udevtest.c index 4890b6837c..6e973e31e6 100644 --- a/udevtest.c +++ b/udevtest.c @@ -92,7 +92,7 @@ int main(int argc, char *argv[], char *envp[]) info("looking at device '%s' from subsystem '%s'", devpath, subsystem); /* initialize the naming deamon */ - udev_rules_init(&rules, 0); + udev_rules_init(&rules, 0, 0); /* fill in values and test_run flag*/ udev_init_device(&udev, devpath, subsystem, "add"); From b7299fd904d33bc2d6845be535666b528fd18948 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 11:58:11 +0200 Subject: [PATCH 1417/4284] update distro rules files Signed-off-by: Kay Sievers --- etc/udev/debian/compat-full.rules | 37 +++++++++ etc/udev/debian/permissions.rules | 1 + etc/udev/debian/persistent.rules | 49 ++++++++++++ etc/udev/debian/run.rules | 1 + etc/udev/redhat/udev.rules | 120 ++++++++++++++++++++---------- 5 files changed, 168 insertions(+), 40 deletions(-) create mode 100644 etc/udev/debian/compat-full.rules create mode 100644 etc/udev/debian/persistent.rules diff --git a/etc/udev/debian/compat-full.rules b/etc/udev/debian/compat-full.rules new file mode 100644 index 0000000000..50e24bc64a --- /dev/null +++ b/etc/udev/debian/compat-full.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/etc/udev/debian/permissions.rules b/etc/udev/debian/permissions.rules index aab6fdbd08..52d7aa9536 100644 --- a/etc/udev/debian/permissions.rules +++ b/etc/udev/debian/permissions.rules @@ -27,6 +27,7 @@ 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" diff --git a/etc/udev/debian/persistent.rules b/etc/udev/debian/persistent.rules new file mode 100644 index 0000000000..b444a27bf6 --- /dev/null +++ b/etc/udev/debian/persistent.rules @@ -0,0 +1,49 @@ +# This file contains the rules needed to create persistent device names. + +# we are only interested in add actions for block devices +ACTION!="add", GOTO="no_volume_id" +SUBSYSTEM!="block", GOTO="no_volume_id" + +# and we can safely ignore these kinds of devices +KERNEL=="ram*|loop*|fd*|sr*", GOTO="no_volume_id" + +# disk id +KERNEL=="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" +KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", \ + SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" + +KERNEL=="hd*[0-9]", IMPORT{parent}="ID_*" +KERNEL=="hd*[0-9]", ENV{ID_SERIAL}=="?*", \ + SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" + +KERNEL=="sd*[!0-9]", SYSFS{ieee1394_id}=="*", \ + IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", \ + IMPORT="/sbin/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", \ + SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" + +KERNEL=="sd*[0-9]", IMPORT{parent}="ID_*" +KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", \ + SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + +# path +KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", \ + SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}" + +KERNEL=="*[0-9]", IMPORT{parent}="ID_*" +KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", \ + SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}-part%n" + +# volume label and uuid +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" +KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" +KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", \ + SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" +KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", \ + SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" + +# end of processing +SUBSYSTEM=="block", LABEL="no_volume_id" + diff --git a/etc/udev/debian/run.rules b/etc/udev/debian/run.rules index 0e28d189be..23fa43c051 100644 --- a/etc/udev/debian/run.rules +++ b/etc/udev/debian/run.rules @@ -3,5 +3,6 @@ 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/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 5bed782280..0f6e6ffb73 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -1,7 +1,7 @@ # There are a number of modifiers that are allowed to be used in some of the # fields. See the udev man page for a full description of them. # -# default is OWNER="root" GROUP="root", MODE="0660" +# default is OWNER="root" GROUP="root", MODE="0600" # # all block devices @@ -86,14 +86,14 @@ KERNEL=="usblp*", GROUP="lp", MODE="0660" KERNEL=="usb/lp*", GROUP="lp", MODE="0660" # tape devices -KERNEL=="ht*", GROUP="disk", MODE="0640" -KERNEL=="nht*", GROUP="disk", MODE="0640" -KERNEL=="pt[0-9]*", GROUP="disk", MODE="0640" -KERNEL=="npt*", GROUP="disk", MODE="0640" -KERNEL=="st*", GROUP="disk", MODE="0640" -KERNEL=="nst*", GROUP="disk", MODE="0640" -KERNEL=="osst*", GROUP="disk", MODE="0640" -KERNEL=="nosst*", GROUP="disk", MODE="0640" +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" @@ -144,7 +144,7 @@ KERNEL=="dvb/adapter*", MODE="0660" # 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=="dm-[0-9]*", PROGRAM="/sbin/devmap_name %M %m", NAME="%k", SYMLINK+="%c" # DRI devices always go into a subdirectory (as per the LSB spec) KERNEL=="card*", NAME="dri/card%n" @@ -166,37 +166,42 @@ KERNEL=="ts*", NAME="input/%k" KERNEL=="raw[0-9]*", NAME="raw/%k" -KERNEL=="lp[0-9]*", SYMLINK="par%n" +KERNEL=="lp[0-9]*", SYMLINK+="par%n" BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" KERNEL=="microcode", NAME="cpu/%k" -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" +# provide symlinks for backwards compatibility +KERNEL="msr[0-9]*", NAME="cpu/%n/msr", SYMLINK+="cpu/%k" +KERNEL="cpu[0-9]*", NAME="cpu/%n/cpu", SYMLINK+="cpu/%k", SYMLINK+="%k" + +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" KERNEL=="device-mapper", NAME="mapper/control" # old compat symlinks with enumeration -KERNEL=="sr[0-9]*", SYMLINK="cdrom%e" -KERNEL=="scd[0-9]*", SYMLINK="cdrom%e" -KERNEL=="pcd[0-9]*", SYMLINK="cdrom%e" -KERNEL=="fd[0-9]*", SYMLINK="floppy%e" -KERNEL=="nst[0-9]", BUS=="scsi", SYMLINK="tape%e" -KERNEL=="nosst[0-9]", BUS=="scsi", SYMLINK="tape%e" +KERNEL=="sr[0-9]*", SYMLINK+="cdrom%e" +KERNEL=="scd[0-9]*", SYMLINK+="cdrom%e" +KERNEL=="pcd[0-9]*", SYMLINK+="cdrom%e" +KERNEL=="fd[0-9]*", SYMLINK+="floppy%e" +KERNEL=="nst[0-9]", BUS=="scsi", SYMLINK+="tape%e", MODE="0660" +KERNEL=="nosst[0-9]", BUS=="scsi", SYMLINK+="tape%e", MODE="0660" +KERNEL=="sg[0-9]*", BUS="scsi", SYSFS{type}=="6", SYMLINK+="scanner%e", MODE="0660" KERNEL=="umad*", NAME="infiniband/%k" KERNEL=="issm*", NAME="infiniband/%k" @@ -208,22 +213,57 @@ KERNEL=="zapchannel", NAME="zap/channel" KERNEL=="zappseudo", NAME="zap/pseudo" KERNEL=="zap[0-9]*", NAME="zap/%n" +BUS=="scsi", KERNEL=="sg[0-9]*", SYSFS{type}=="6", NAME="%k", SYMLINK="scanner%e", MODE="0660" + # do not seperate the next 2 lines!! -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/ide-media.sh %k", RESULT=="floppy", SYMLINK="floppy%e", NAME{ignore_remove, all_partitions}="%k" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/ide-media.sh %k", RESULT=="floppy", SYMLINK+="floppy%e", NAME{ignore_remove, all_partitions}="%k" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", RESULT=="cdrom", SYMLINK="cdrom%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", RESULT=="cdrom", SYMLINK+="cdrom%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK="dvd%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK="cdwriter%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK="dvdwriter%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" # rename sr* to scd* KERNEL=="sr[0-9]*", BUS=="scsi", NAME="scd%n" KERNEL=="hd[a-z]*", BUS=="ide", SYSFS{removable}=="1", NAME{ignore_remove}="%k" KERNEL=="dvb*", PROGRAM=="/etc/udev/scripts/dvb.sh %k", NAME="%c" + + +# Perhaps this should just be for all subsystems? + +ACTION=="add", SUBSYSTEM=="pci", MODALIAS=="*", \ + RUN+="/sbin/modprobe $modalias" +ACTION=="add", SUBSYSTEM=="usb", MODALIAS=="*", \ + RUN+="/sbin/modprobe $modalias" +ACTION=="add", SUBSYSTEM=="pcmcia", MODALIAS=="*", \ + RUN+="/sbin/modprobe $modalias" +ACTION=="add", SUBSYSTEM=="pcmcia", MODALIAS=="*", \ + RUN+="/bin/sh -c 'echo 1 > /sys/$DEVPATH/allow_func_id_match'" + +ACTION=="add", SUBSYSTEM=="ieee1394", MODALIAS=="*", \ + RUN+="/sbin/modprobe $modalias" + +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[07]", \ + RUN+="/sbin/modprobe sd_mod" +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="14", \ + RUN+="/sbin/modprobe sd_mod" +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[45]", \ + RUN+="/sbin/modprobe sr_mod" +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="Onstream", \ + SYSFS{model}!="ADR*", RUN+="/sbin/modprobe osst" +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="Onstream", \ + SYSFS{model}=="ADR*", RUN+="/sbin/modprobe st" +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}!="Onstream", \ + RUN+="/sbin/modprobe st" +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[23689]", \ + RUN+="/sbin/modprobe sg" + +ACTION=="add", SUBSYSTEM=="firmware", ENV{FIRMWARE}="*", \ + RUN+="/sbin/firmware_helper" From 80489e6395581911c35104f3fc11bfe62a0b785a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 12:29:12 +0200 Subject: [PATCH 1418/4284] add SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/50-udev.rules | 257 ++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 etc/udev/suse/50-udev.rules diff --git a/etc/udev/suse/50-udev.rules b/etc/udev/suse/50-udev.rules new file mode 100644 index 0000000000..63be8812b1 --- /dev/null +++ b/etc/udev/suse/50-udev.rules @@ -0,0 +1,257 @@ +# console +KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" +KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" +KERNEL=="vcs*", NAME="%k", GROUP="tty", MODE="620", OPTIONS="last_rule" +KERNEL=="vcsa*", NAME="%k", GROUP="tty", MODE="620", OPTIONS="last_rule" +KERNEL=="tty", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" +KERNEL=="tty[0-9]*", NAME="%k", GROUP="tty", MODE="620", OPTIONS="last_rule" +KERNEL=="console", NAME="%k", MODE="600" +KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="666" + +# serial devices +KERNEL=="tty[A-Z]*", NAME="%k", GROUP="uucp" +KERNEL=="pppox*", NAME="%k", GROUP="uucp" +KERNEL=="ircomm*", NAME="%k", GROUP="uucp" +KERNEL=="modems/mwave*", NAME="%k", GROUP="uucp" +KERNEL=="hvc*", NAME="%k", GROUP="uucp" +KERNEL=="hvsi*", NAME="%k", GROUP="uucp" +KERNEL=="iseries/vtty*", NAME="%k", GROUP="uucp" + +# video/graphics +SUBSYSTEM=="video4linux", GROUP="video" +SUBSYSTEM=="graphics" GROUP="video" +KERNEL=="video*", NAME="%k", GROUP="video" +KERNEL=="vtx*", NAME="%k", GROUP="video" +KERNEL=="vbi*", NAME="%k", GROUP="video" +KERNEL=="winradio*", NAME="%k", GROUP="video" +KERNEL=="vttuner*", NAME="%k", GROUP="video" +KERNEL=="nvidia*", NAME="%k", GROUP="video" +KERNEL=="nvidiactl*", NAME="%k", GROUP="video" + +# dvb +KERNEL=="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video" + +# ALSA/sound +SUBSYSTEM="sound", GROUP="audio" +SUBSYSTEM="snd", GROUP="audio" +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" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8000/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us428fw.ihx" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8004/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us224fw.ihx" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8006/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us122fw.ihx" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8001/*", RUN+="/sbin/startproc /usr/bin/us428control" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8005/*", RUN+="/sbin/startproc /usr/bin/us428control" +SUBSYSTEM=="sound", KERNEL=="controlC?", RUN+="/usr/sbin/alsactl -F restore %n" +SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVER=="EMU10K1_Audigy", RUN+="/etc/dev.d/snd/hwC0D2/alsa" + +# OpenCT (SmartCard) +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="973/1*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="529/50c*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="529/514*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="73d/5*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="4b9/1200*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="4b9/1300*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="76b/596*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="76b/1784*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="8d4/9*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" +SUBSYSTEM=="usb", ACTION=="add", ENV{INTERFACE}=="11/*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" + +# CAPI devices +SUBSYSTEM="capi", GROUP="dialout" +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" +KERNEL=="capi*", NAME="capi/%n" + +# ISDN +KERNEL=="isdn*", NAME="%k", MODE="600" +KERNEL=="isdnctrl*", NAME="%k", MODE="600" +KERNEL=="ippp*", NAME="%k", MODE="600" +KERNEL=="isdninfo*", NAME="%k", MODE="444" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/c00*", IMPORT="/bin/echo 'DRV=fcusb'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/1000*", IMPORT="/bin/echo -e 'DRV=fcusb2\nFIRMWARE=fus2base.frm'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/1900*", IMPORT="/bin/echo -e 'DRV=fcusb2\nFIRMWARE=fus3base.frm'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2000*", IMPORT="/bin/echo DRV=fxusb", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2200*", IMPORT="/bin/echo DRV=bfusb", RUN+="/etc/sysconfig/isdn/scripts/load-bfusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2300*", IMPORT="/bin/echo -e 'DRV=fcdslusb\nFIRMWARE=fdsubase.frm\nDSL_CONTR=dslisdn'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2800*", IMPORT="/bin/echo DRV=fxusb_CZ", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/3000*", IMPORT="/bin/echo -e 'DRV=fcdslusba\nFIRMWARE=fdsabase.frm\nDSL_CONTR=dslonly\nISDNLOG_START=no'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/3500*", IMPORT="/bin/echo -e 'DRV=fcdslslusb\nFIRMWARE=fdlubase.frm\nDSL_CONTR=dslonly\nISDNLOG_START=no'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/3600*", IMPORT="/bin/echo -e 'DRV=fcdslusb2\nFIRMWARE=fds2base.frm\nDSL_CONTR=dslisdn'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2805*", IMPORT="/bin/echo 'DRV=e2220pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2806*", IMPORT="/bin/echo 'DRV=e5520pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/4401*", IMPORT="/bin/echo 'DRV=e2220pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/4601*", IMPORT="/bin/echo 'DRV=e5520pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="483/4810*", IMPORT="/bin/echo 'DRV=hisax_st5481'", RUN+="/etc/sysconfig/isdn/scripts/load-hisaxusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="959/2bd0*", IMPORT="/bin/echo 'DRV=hfc_usb'", RUN+="/etc/sysconfig/isdn/scripts/load-hisaxusb" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="9bf/*", IMPORT="/bin/echo 'DRV=auerswald'", RUN+="/etc/sysconfig/isdn/scripts/load-auerswald" + +# input devices +KERNEL=="mice", NAME="input/%k", MODE="0640" +KERNEL=="mouse*", NAME="input/%k", MODE="0640" +KERNEL=="event*", NAME="input/%k", MODE="0640" +KERNEL=="js*", NAME="input/%k", MODE="0644" +KERNEL=="ts*", NAME="input/%k", MODE="0600" +KERNEL=="uinput", NAME="input/%k", MODE="0600" +KERNEL=="event*", PROGRAM="/sbin/udev.get_input_lirc.sh %k", RESULT="*IR*", NAME="input/%k", SYMLINK+="input/ir" +KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" +SUBSYSTEM=="input_device", RUN+="/etc/hotplug.d/input_device/50-input_device.hotplug" + +# printer +SUBSYSTEM=="usb", KERNEL=="lp*", ACTION=="add", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" +SUBSYSTEM=="printer", KERNEL=="lp*", ACTION=="add", NAME="%k", GROUP="lp" +KERNEL=="irlpt*", NAME="%k", 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*", NAME="%k", GROUP="video" +KERNEL=="dv1394*", NAME="%k", SYMLINK+="dv1394/%n", GROUP="video" +KERNEL=="video1394*", NAME="%k", SYMLINK+="video1394/%n", GROUP="video" + +# 183 = /dev/hwrng Generic random number generator +KERNEL=="hw_random", NAME="hwrng", SYMLINK+="%k" +# 219 /dev/modems/mwave MWave modem firmware upload +KERNEL=="mwave", NAME="modems/%k" +# 169 /dev/specialix_rioctl Specialix RIO serial control +KERNEL=="rioctl", NAME="specialix_rioctl", SYMLINK+="%k" +# 167 /dev/specialix_sxctl Specialix serial control +KERNEL=="sxctl", NAME="specialix_sxctl", SYMLINK+="%k" + +# misc devices +KERNEL=="mem", NAME="%k", GROUP="kmem", MODE="640" +KERNEL=="kmem", NAME="%k", GROUP="kmem", MODE="640" +KERNEL=="port", NAME="%k", GROUP="kmem", MODE="640" +KERNEL=="nvram", NAME="%k", GROUP="kmem" +KERNEL=="null", NAME="%k", MODE="666" +KERNEL=="zero", NAME="%k", MODE="666" +KERNEL=="full", NAME="%k", MODE="622" +KERNEL=="random", NAME="%k", MODE="666" +KERNEL=="urandom", NAME="%k", MODE="644" +KERNEL=="rtc", GROUP="audio" +KERNEL=="sonypi", MODE="0666" +KERNEL=="agpgart", MODE="0600", GROUP="video" +KERNEL=="djs*", NAME="%k", MODE="644" +KERNEL=="sgi_*", NAME="%k", MODE="666" +KERNEL=="rrom*", NAME="%k", MODE="400" +KERNEL=="rflash*", NAME="%k", MODE="400" +KERNEL=="usbscanner*", NAME="%k", MODE="644" +KERNEL=="3270/ttycons*", NAME="%k", MODE="600" +KERNEL=="3270/tub*", NAME="%k", MODE="666" +KERNEL=="3270/tubcons*", NAME="%k", MODE="600" +KERNEL=="ica", NAME="%k", MODE="666" +KERNEL=="z90crypt", NAME="%k", MODE="666" +KERNEL=="mmtimer", NAME="%k", MODE="444" + +# fix floppy devices +KERNEL=="nvram", ACTION=="add", NAME="%k", MODE="600", RUN="/sbin/load_floppy_module" +KERNEL=="fd*", ACTION=="add", SYSFS{device/cmos}=="*", RUN="/sbin/create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" +KERNEL=="fd*", ACTION=="remove", RUN="/sbin/remove_floppy_devices /dev/%k" + +# block devices +SUBSYSTEM=="block", GROUP="disk", MODE="0640" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0", RUN+="/sbin/modprobe sd_mod" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", RUN+="/sbin/modprobe st" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="[345]", RUN+="/sbin/modprobe sr_mod" + +# misc storage devices (non-block) +KERNEL=="sg*", NAME="%k", GROUP="disk", MODE="640" +KERNEL=="st*", NAME="%k", GROUP="disk" +KERNEL=="nst*", NAME="%k", GROUP="disk" +KERNEL=="initrd", NAME="%k", GROUP="disk" +KERNEL=="qft*", NAME="%k", GROUP="disk" +KERNEL=="nqft*", NAME="%k", GROUP="disk" +KERNEL=="zqft*", NAME="%k", GROUP="disk" +KERNEL=="nzqft*", NAME="%k", GROUP="disk" +KERNEL=="rawqft*", NAME="%k", GROUP="disk" +KERNEL=="nrawqft*", NAME="%k", GROUP="disk" +KERNEL=="pf*", NAME="%k", GROUP="disk" +KERNEL=="sch*", NAME="%k", GROUP="disk" +KERNEL=="pt*", NAME="%k", GROUP="disk" +KERNEL=="npt*", NAME="%k", GROUP="disk" +KERNEL=="pg*", NAME="%k", GROUP="disk" +KERNEL=="evms/block_device*", NAME="%k", GROUP="disk" +KERNEL=="rawctl*", NAME="%k", GROUP="disk" +KERNEL=="osst*", NAME="%k", GROUP="disk" +KERNEL=="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" + +# device mapper targets +KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" +KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/udev.devmap_name.sh %M %m | /bin/sed 's.--._.;s.-./.;s._.-.'", SYMLINK+="%c" +KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/udev.devmap_name.sh %M %m", NAME="mapper/%c" + +# persistent disk device links /dev/disk/ +# skip rules for for ram/loop/fd +SUBSYSTEM=="block", KERNEL=="ram*|loop*|fd*", GOTO="persistent_end" +SUBSYSTEM!="block", GOTO="persistent_end" +ACTION!="add", GOTO="persistent_end" + +# never access removable ide devices, the drivers are causing event loops on open() +SUBSYSTEM=="block", BUS=="ide", SYSFS{removable}="1", GOTO="persistent_end" + +# by-id (hardware serial number) +KERNEL=="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" +KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" +KERNEL=="hd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" + +KERNEL=="sd*[!0-9]", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + +KERNEL=="dasd*[!0-9]", IMPORT="/sbin/dasd_id --export $tempnode" +KERNEL=="dasd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="dasd*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="dasd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + +# by-path (shortest physical path) +KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}" +KERNEL=="*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}-part%n" + +# by-label/by-uuid (filesystem properties) +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_end" +KERNEL=="sr*", GOTO="persistent_end" +KERNEL=="*[0-9]", ACTION=="add", IMPORT="/sbin/vol_id --export $tempnode" +KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" +KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" +LABEL="persistent_end" + +# network devices +KERNEL=="tun", NAME="net/%k", MODE="0600" +SUBSYSTEM=="net", ACTION=="add", RUN+="/sbin/ifup $env{INTERFACE} -o hotplug" +SUBSYSTEM=="net", ACTION=="remove", RUN+="/sbin/ifdown %k -o hotplug" + +# mount usbfs +DEVPATH=="/module/usbcore", ACTION=="add", RUN+="/bin/mount -t usbfs usbfs /proc/bus/usb" + +# firmware loader +SUBSYSTEM=="firmware", ACTION=="add", RUN+="/etc/hotplug.d/firmware/50-firmware.hotplug" + +# SUSE system integration +SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" +SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-/sys%p -o hotplug" +SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-/sys%p -o hotplug" +SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-/sys%p -o hotplug" +SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-/sys%p -o hotplug" +SUBSYSTEM=="scsi", DEVPATH=="/devices/css*", ACTION=="remove", RUN+="/sbin/hwdown scsi-devpath-/sys%p -o hotplug" +SUBSYSTEM=="scsi_host", ACTION=="add", SYSFS{device/cutype}=="*", RUN+="/sbin/hwup scsi__host-devpath-/sys%p -o hotplug" + +# default +RUN+="/usr/sbin/hal.hotplug" +RUN+="socket:/org/kernel/udev/monitor" + +# debug events to /events, but not on default udev_log="err" +ENV{UDEV_LOG}=="[4567]", RUN+="/sbin/hotplugeventrecorder" + From 1bcac4e483ace30b90b79a14b2f4c75d4f7ab3bc Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 15:53:17 +0200 Subject: [PATCH 1419/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/50-udev.rules | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/etc/udev/suse/50-udev.rules b/etc/udev/suse/50-udev.rules index 63be8812b1..be5a2478ba 100644 --- a/etc/udev/suse/50-udev.rules +++ b/etc/udev/suse/50-udev.rules @@ -191,7 +191,6 @@ KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/udev.devmap_name.sh %M %m", N # persistent disk device links /dev/disk/ # skip rules for for ram/loop/fd SUBSYSTEM=="block", KERNEL=="ram*|loop*|fd*", GOTO="persistent_end" -SUBSYSTEM!="block", GOTO="persistent_end" ACTION!="add", GOTO="persistent_end" # never access removable ide devices, the drivers are causing event loops on open() @@ -202,11 +201,13 @@ KERNEL=="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" KERNEL=="hd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" -KERNEL=="sd*[!0-9]", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" + +# for partitions import parent information KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*" KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" @@ -223,7 +224,8 @@ KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PA # by-label/by-uuid (filesystem properties) KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_end" KERNEL=="sr*", GOTO="persistent_end" -KERNEL=="*[0-9]", ACTION=="add", IMPORT="/sbin/vol_id --export $tempnode" +SUBSYSTEM!="block", GOTO="persistent_end" +KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" LABEL="persistent_end" @@ -253,5 +255,5 @@ RUN+="/usr/sbin/hal.hotplug" RUN+="socket:/org/kernel/udev/monitor" # debug events to /events, but not on default udev_log="err" -ENV{UDEV_LOG}=="[4567]", RUN+="/sbin/hotplugeventrecorder" +ENV{UDEV_LOG}=="[4-9]", RUN+="/sbin/hotplugeventrecorder" From bebbc31b90056f5b0eafb52fc965f0cc713f0d4f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 19:00:37 +0200 Subject: [PATCH 1420/4284] add firmware_helper to load firmware From: Bill Nottingham Changed reading of firmware blob to mmap and let firmware_helper follow the setting of the log level with UDEV_LOG. --- extras/firmware/Makefile | 51 +++++++++++ extras/firmware/firmware_helper.c | 147 ++++++++++++++++++++++++++++++ logging.h | 2 +- test/simple-build-check.sh | 3 +- 4 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 extras/firmware/Makefile create mode 100644 extras/firmware/firmware_helper.c diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile new file mode 100644 index 0000000000..6417bbf185 --- /dev/null +++ b/extras/firmware/Makefile @@ -0,0 +1,51 @@ +# Makefile for usb_id +# +# 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. +# + +PROG = firmware_helper + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +OBJS = $(PROG).o $(VOLUME_ID_OBJS) ../../udev.a ../../libsysfs/sysfs.a +HEADERS = + +$(OBJS): $(HEADERS) + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(PROG): $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/firmware/firmware_helper.c b/extras/firmware/firmware_helper.c new file mode 100644 index 0000000000..283ea9f76f --- /dev/null +++ b/extras/firmware/firmware_helper.c @@ -0,0 +1,147 @@ +/* + * A simple firmware helper program. + * + * Copyright 2005 Red Hat, Inc. + * + * This software may be freely redistributed under the terms of the GNU + * public license. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../udev_utils.h" +#include "../../logging.h" + +#define FIRMWARE_PATH "/lib/firmware" +#define PATH_SIZE 256 + +#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 + +/* Set the 'loading' attribute for a firmware device. + * 1 == currently loading + * 0 == done loading + * -1 == error + */ +static int set_loading(const char *device, int value) { + char loading_path[PATH_SIZE]; + int rc; + FILE *f; + + snprintf(loading_path, sizeof(loading_path), "/sys/%s/loading", device); + loading_path[sizeof(loading_path)-1] = '\0'; + f = fopen(loading_path, "w"); + if (!f) + return -1; + rc = fprintf(f, "%d", value); + fclose(f); + if (rc < 0) + return rc; + return 0; +} + +int main(int argc, char **argv) { + char *devpath, *firmware, *action, *driver; + char fw_path[PATH_SIZE]; + char data_path[PATH_SIZE]; + int fw_fd; + char *fw_buffer; + size_t fw_buffer_size; + size_t count; + int rc = 0; + + logging_init("firmware_helper"); + + driver = getenv("PHYSDEVDRIVER"); + if (!driver) + driver = "(unknown)"; + devpath = getenv("DEVPATH"); + firmware = getenv("FIRMWARE"); + action = getenv("ACTION"); + if (!devpath || !firmware || !action || strcmp(action,"add") != 0) { + err("missing devpath, action or firmware"); + exit(1); + } + + dbg("try to load firmware '%s' for '%s'", firmware, devpath); + set_loading(devpath, 1); + + snprintf(fw_path, sizeof(fw_path), "%s/%s", FIRMWARE_PATH, firmware); + fw_path[sizeof(fw_path)-1] = '\0'; + if (file_map(fw_path, &fw_buffer, &fw_buffer_size) != 0 || fw_buffer_size == 0) { + err("could not load firmware '%s' for '%s'", fw_path, devpath); + fw_buffer = NULL; + goto out_err; + } + + snprintf(data_path, sizeof(data_path), "/sys/%s/data", devpath); + fw_path[sizeof(data_path)-1] = '\0'; + fw_fd = open(data_path, O_RDWR); + if (fw_fd < 0) { + rc = errno; + goto out_err; + } + + count = 0; + while (count < fw_buffer_size) { + int c; + + c = write(fw_fd, fw_buffer+count, fw_buffer_size); + if (c <= 0) { + rc = errno; + close(fw_fd); + goto out_err; + } + count += c; + } + + close(fw_fd); + file_unmap(fw_buffer, fw_buffer_size); + set_loading(devpath, 0); + info("loaded '%s' for device '%s'", fw_path, devpath); + logging_close(); + return 0; + +out_err: + if (fw_buffer) + file_unmap(fw_buffer, fw_buffer_size); + set_loading(devpath, -1); + + err("error loading '%s' for device '%s' with driver '%s'", fw_path, devpath, driver); + logging_close(); + return rc; +} diff --git a/logging.h b/logging.h index 904355cb2c..0126de99eb 100644 --- a/logging.h +++ b/logging.h @@ -38,7 +38,7 @@ #undef err #define err(format, arg...) \ do { \ - log_message(LOG_INFO ,"%s: " format ,__FILE__ ,## arg); \ + log_message(LOG_ERR ,"%s: " format ,__FILE__ ,## arg); \ } while (0) #undef info diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 742b28ec1c..521691618a 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -8,7 +8,8 @@ EXTRAS="\ extras/usb_id \ extras/dasd_id \ extras/floppy \ - extras/run_directory" + extras/run_directory \ + extras/firmware" [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build echo KERNEL_DIR: "$KERNEL_DIR" From 6214290df56de85772bdd62f8f646863306b39f0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 19:17:25 +0200 Subject: [PATCH 1421/4284] more distro rules updates Signed-off-by: Kay Sievers --- RELEASE-NOTES | 6 + etc/udev/slackware/udev.permissions | 133 --------------- etc/udev/slackware/udev.rules | 248 ++++++++++++++++++++++++++++ etc/udev/suse/50-udev.rules | 4 +- etc/udev/udev.permissions | 10 -- extras/firmware/Makefile | 2 +- 6 files changed, 257 insertions(+), 146 deletions(-) delete mode 100644 etc/udev/slackware/udev.permissions create mode 100644 etc/udev/slackware/udev.rules delete mode 100644 etc/udev/udev.permissions diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 09d29c8b0a..91cef0ccd4 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,9 @@ +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 diff --git a/etc/udev/slackware/udev.permissions b/etc/udev/slackware/udev.permissions deleted file mode 100644 index 2edc1aaa53..0000000000 --- a/etc/udev/slackware/udev.permissions +++ /dev/null @@ -1,133 +0,0 @@ -#name:user:group:mode -pl2303:500:500:0666 -visor:root:uucp:0666 -camera*:500:500:0666 - -# console devices -console:root:tty:0600 -tty[0-9][0-9]*:root:tty:0666 -vcs*:root:tty:0620 -tty[CIS]*:root:uucp:0660 -ttyUB[0-9]:root:uucp:0660 -ttyUSB0:root:uucp:0660 -ttyUSB1:root:uucp:0666 - -# pty devices -ptmx:root:tty:0666 -pty[p-za-e][0-9a-f]*:root:tty:0666 -tty[p-za-e][0-9a-f]*:root:tty:0666 -cu[abiu]*:root:uucp:0660 - -# sound devices -audio*:root:sys:0662 -beep:root:root:0644 -dsp*:root:sys:0662 -midi*:root:sys:0662 -mixer*:root:sys:0666 -music:root:sys:0662 -sequencer*:root:sys:0662 -snd/*:root:root:0666 -sndstat:root:sys:0662 -speaker:root:root:0644 -sound/*:root:root:0666 -admmidi*:root:root:0666 -adsp*:root:root:0666 -aload*:root:root:0666 -amidi*:root:root:0666 -amixer*:root:root:0666 - -# input devices (mouse, joystick, etc) -input/*:root:root:0644 -input/js*:root:games:0666 -djs[0-3]:root:games:0660 -psaux:root:sys:0660 -crash:roor:root:0660 -logibm:root:sys:0660 -jbm:root:sys:0660 -hwtrap:root:root:0644 -inportbm:root:sys:0660 -sexec:root:root:0660 -jsflash:roo:root:0660 - -# power manager device -apm_bios:root:root:0644 - -# printer device -lp[0-9]:root:lp:0660 -parport*:root:root:0660 - -# video devices -dri/card[0-9]*:root:root:0666 -fb[0-9]:root:tty:0660 -agpgart:root:root:0660 -nvidia*:root:root:0666 -video*:root:sys:0660 - -# DISK devices -ed[ab]*:root:disk:0640 -gscd0:root:disk:0640 -initrd:root:disk:0640 -lmscd:root:disk:0640 -mcd*:root:disk:0640 -md*:root:disk:0660 -mtd*:root:disk:0640 -userdma:root:root:0660 - -# floppy devices -fd[0-3]*:root:floppy:0660 - -# IDE devices (hd, cdrom) -hd*:root:disk:0660 -ht0:root:disk:0640 - -# RAID IDE -ataraid[0-9]*:root:disk:0660 -ataraid/*:root:disk:0660 - -# SCSI devices -scsi/*/cd:root:disk:0660 -scsi/*:root:disk:0660 -sd[a-h]*:root:disk:0640 -s[rt][0-9]*:root:disk:0640 -scd*:root:disk:0660 - -# generic scsi devices -sg*:root:root:0600 - -# old CD-ROM -sbpcd*:root:disk:0640 - -# loop devices -loop[0-9]*:root:disk:0660 - -# network block devices -nb[0-7]:root:disk:0660 -nht0:root:disk:0640 -npt[0-3]:root:disk:0660 -n[qrs]*:root:disk:0640 - -# memory access devices -kmem:root:kmem:0640 -mem:root:kmem:0640 -null:root:sys:0666 -nvram:root:root:0640 -port:root:kmem:0640 -ram[0-9]*:root:disk:0640 -random:root:root:0644 -rtc:root:root:0444 -urandom:root:root:0644 -full:root:sys:0666 -zero:root:root:0664 -raw/*:root:disk:0660 -modreq:root:root:0644 -msr:root:root:0660 -profile*:root:root:0640 - -# ISDN devices -isdn*:root:tty:0660 - -# net devices -ippp*:root:root:0644 -ipstate:root:root:0660 -spx:root:root:0644 -fwmonitor:root:root:0660 diff --git a/etc/udev/slackware/udev.rules b/etc/udev/slackware/udev.rules new file mode 100644 index 0000000000..ac43657cc6 --- /dev/null +++ b/etc/udev/slackware/udev.rules @@ -0,0 +1,248 @@ +# /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. + +# all block devices +SUBSYSTEM="block", GROUP="disk" + +### cdrom symlinks and other good cdrom naming +##BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +##BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +##BUS="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +## +### devfs-names for ide-devices (uncomment only one) +### /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names +##BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}", GROUP="%c{3}" + +# permissions for IDE CD devices +BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom*", NAME="%k", GROUP="cdrom", MODE="0660" + +# permissions for IDE floppy devices +BUS="ide", KERNEL="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="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" + +# disk devices +KERNEL="sd*", NAME="%k", GROUP="disk" +KERNEL="dasd*", NAME="%k", GROUP="disk" +KERNEL="ataraid*", NAME="%k", GROUP="disk" + +# 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", 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" + +# 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" + +# fb devices +KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video" + +# floppy devices +KERNEL="fd[0-9]*", NAME="floppy/%n", SYMLINK="%k", GROUP="floppy", PROGRAM="/etc/udev/scripts/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" +KERNEL="mouse*", NAME="input/%k", MODE="0644" +KERNEL="event*", NAME="input/%k", MODE="0600" +KERNEL="js*", NAME="input/%k", MODE="664" +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" + +# 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="0600" +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%n", SYMLINK="%k", GROUP="tty" +KERNEL="tty[p-za-e][0-9a-f]*", NAME="pty/s%n", 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="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" +KERNEL="dabusb*", NAME="usb/%k" +BUS="usb", KERNEL="lp[0-9]*", 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", 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 +KERNEL="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video", MODE="0660" + +# 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="lp*", NAME="%k", GROUP="lp" +KERNEL="irlpt", NAME="%k", GROUP="lp" +KERNEL="usblp", NAME="%k", GROUP="lp" +KERNEL="lp*", NAME="%k", GROUP="lp" + +# 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" + +## These lines are causing race conditions with the symlink to udevstart in +## /etc/hotplug.d/default/, so they are being commented out for now. Udev +## seems to work better that way... YMMV. +# +## be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/. +## systems run /etc/hotplug.d/ stuff only if we came from a hotplug event, +## not for udevstart +#ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" +# +## always run /etc/dev.d/ stuff for now +#RUN+="/sbin/udev_run_devd" + diff --git a/etc/udev/suse/50-udev.rules b/etc/udev/suse/50-udev.rules index be5a2478ba..515b572e75 100644 --- a/etc/udev/suse/50-udev.rules +++ b/etc/udev/suse/50-udev.rules @@ -185,7 +185,6 @@ KERNEL=="iseries/ibmsis*", NAME="%k", GROUP="disk" # device mapper targets KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" -KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/udev.devmap_name.sh %M %m | /bin/sed 's.--._.;s.-./.;s._.-.'", SYMLINK+="%c" KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/udev.devmap_name.sh %M %m", NAME="mapper/%c" # persistent disk device links /dev/disk/ @@ -235,8 +234,9 @@ KERNEL=="tun", NAME="net/%k", MODE="0600" SUBSYSTEM=="net", ACTION=="add", RUN+="/sbin/ifup $env{INTERFACE} -o hotplug" SUBSYSTEM=="net", ACTION=="remove", RUN+="/sbin/ifdown %k -o hotplug" -# mount usbfs +# libusb device access (mount usbfs or usbdev nodes) DEVPATH=="/module/usbcore", ACTION=="add", RUN+="/bin/mount -t usbfs usbfs /proc/bus/usb" +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+="/etc/hotplug.d/firmware/50-firmware.hotplug" diff --git a/etc/udev/udev.permissions b/etc/udev/udev.permissions deleted file mode 100644 index dd56bbec4c..0000000000 --- a/etc/udev/udev.permissions +++ /dev/null @@ -1,10 +0,0 @@ -#name:user:group:mode -ttyUSB0:root:uucp:0660 -ttyUSB1:root:uucp:0666 -pl2303:500:500:0666 -visor:root:uucp:0666 -dsp1:::0666 -camera*:500:500:0666 -sgi_fetchop:root:root:666 -iseries/vcd*:root:disk:660 -iseries/vd*:root:disk:660 diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index 6417bbf185..913a88db06 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -1,4 +1,4 @@ -# Makefile for usb_id +# Makefile for firmware_helper # # Copyright (C) 2005 Kay Sievers # From 34c00c915c6dd9d063551732169cb3c3126376ad Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 19:45:08 +0200 Subject: [PATCH 1422/4284] update README Signed-off-by: Kay Sievers --- README | 42 ++++++++++++++++++++++++------------------ udev.8.in | 1 - udevd.c | 2 +- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/README b/README index a2ce9c7d36..139c6e1a6f 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ -udev - a userspace implementation of devfs +udev - a userspace device manager For more information on the design, and structure of this project, see the files in the docs/ directory. @@ -10,19 +10,25 @@ To use: - Your 2.6 kernel must have had CONFIG_HOTPLUG enabled when it was built. -- Make sure sysfs is mounted at /sys. You can mount it by running: +- Make sure sysfs is mounted at /sys. No other location is supported. + You can mount it by running: mount -t sysfs none /sys -- Make sure you have the latest version of the linux-hotplug scripts. They are - available at linux-hotplug.sf.net or from your local kernel.org mirror at: - kernel.org/pub/linux/utils/kernel/hotplug/ - They are required in order for udev to work properly. +- Make sure you integrate udev with your hotplug setup. There is a copy of + the rules files for all major distros in the etc/udev folder. You may look + there how others are doing it. - If for some reason you do not install the hotplug scripts, you must tell the - kernel to point the hotplug binary at wherever you install udev at. This can - be done by: +- Make sure you integrate with the kernel hotplug events. Later versions of + udev are able to listen directly to a netlink socket, older versions used + udevsend to feed the udev daemon with the kernel event. The most basic + setup to run udev is to let the kernel for the udev binary directly: echo "/sbin/udev" > /proc/sys/kernel/hotplug + While this may work in some setups, it is not recommended to do. A recent + kernel and udev version is able to operate with the event serializing daemon + udevd, that makes sure, that no "remove" event will beat a "add" event for + the same device. + - Build the project: make @@ -59,31 +65,31 @@ To use: would do: make USE_KLIBC=true DEBUG=true + udev will follow the setting of the debug level in udev.conf. Adapt this + value to see the debug in syslog. + - Install the project: make install - This will put the udev binary in /sbin, create the /udev and /etc/udev - directories, and place the udev configuration files in /etc/udev. You + This will put the udev binaries in /sbin, create the and /etc/udev + directories, and place the udev configuration files in /etc/udev/. You will probably want to edit the *.rules files to create custom naming rules. More info on how the config files are set up are contained in comments in the files, and is located in the documentation. - Add and remove devices from the system and marvel as nodes are created - and removed in /udev/ based on the device types. + and removed in /dev based on the device types. - If you later get sick of it, uninstall it: make uninstall - -Things are still quite rough, but it should work properly. If nothing -seems to happen, make sure your build worked properly by running the -udev-test.pl script as root in the test/ subdirectory of the udev source -tree. +If nothing seems to happen, make sure your build worked properly by +running the udev-test.pl script as root in the test/ subdirectory of the +udev source tree. Development and documentation help is very much appreciated, see the TODO file for a list of things left to be done. - Any comment/questions/concerns please let me and the other udev developers know by sending a message to the linux-hotplug-devel mailing list at: linux-hotplug-devel@lists.sourceforge.net diff --git a/udev.8.in b/udev.8.in index b4edd5aebd..9dae378086 100644 --- a/udev.8.in +++ b/udev.8.in @@ -381,7 +381,6 @@ If set to "0", it disables the execution of programs added by rules. .SH "SEE ALSO" .BR udevinfo (8), .BR udevd (8), -.BR hotplug (8) .PP .B Web resources: .nf diff --git a/udevd.c b/udevd.c index 9242acce31..d51ed2f7b0 100644 --- a/udevd.c +++ b/udevd.c @@ -1,5 +1,5 @@ /* - * udevd.c - hotplug event serializer + * udevd.c - event listener and serializer * * Copyright (C) 2004-2005 Kay Sievers * Copyright (C) 2004 Chris Friesen From a37610d0f885ee301fd99757beb9fd7af729307f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 20:11:26 +0200 Subject: [PATCH 1423/4284] remove example rules and put the dev.d stuff into the run_directory folder The distro rules are the best example you can get and the use of dev.d/ is no longer recommended. Signed-off-by: Kay Sievers --- etc/udev/udev.rules | 46 -------------- etc/udev/udev.rules.devfs | 6 ++ etc/udev/udev.rules.examples | 63 ------------------- extras/run_directory/README | 17 +++++ {docs => extras/run_directory}/RFC-dev.d | 0 .../dev.d/default/pam_console.dev | 0 .../run_directory}/dev.d/net/hotplug.dev | 0 .../dev.d/snd/controlC0/alsa.dev | 0 8 files changed, 23 insertions(+), 109 deletions(-) delete mode 100644 etc/udev/udev.rules delete mode 100644 etc/udev/udev.rules.examples create mode 100644 extras/run_directory/README rename {docs => extras/run_directory}/RFC-dev.d (100%) rename {etc => extras/run_directory}/dev.d/default/pam_console.dev (100%) rename {etc => extras/run_directory}/dev.d/net/hotplug.dev (100%) rename {etc => extras/run_directory}/dev.d/snd/controlC0/alsa.dev (100%) diff --git a/etc/udev/udev.rules b/etc/udev/udev.rules deleted file mode 100644 index bebf74802f..0000000000 --- a/etc/udev/udev.rules +++ /dev/null @@ -1,46 +0,0 @@ -# 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 -# - -# if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS=="ide", KERNEL=="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT="cdrom", NAME="%k", SYMLINK+="cdrom" - -# DRI devices always go into a subdirectory (as per the LSB spec) -KERNEL=="card*", NAME="dri/card%n" - -# alsa devices -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" - -# input devices -KERNEL=="mice", NAME="input/%k" -KERNEL=="mouse*", NAME="input/%k" -KERNEL=="event*", NAME="input/%k" -KERNEL=="js*", NAME="input/%k" -KERNEL=="ts*", NAME="input/%k" - -# USB devices -KERNEL=="hiddev*", NAME="usb/%k" -KERNEL=="auer*", NAME="usb/%k" -KERNEL=="legousbtower*", NAME="usb/%k" -KERNEL=="dabusb*", NAME="usb/%k" -BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" - -# CAPI devices -KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" -KERNEL=="capi*", NAME="capi/%n" - -# Network devices -KERNEL=="tun", NAME="net/%k" - -# raw devices -KERNEL=="raw[0-9]*", NAME="raw/%k" - -# emulate dev.d/ -RUN="/sbin/udev_run_devd" diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev.rules.devfs index 867f95029c..b7b2c4e12d 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev.rules.devfs @@ -1,3 +1,9 @@ +# The use of these rules is not recommended or supported. +# In a world where devices can come and go at any time, the devfs scheme +# of simple device enumeration does not help _anything_. Just forget about +# it. Use custom rules to name your device or look at the persistent device +# naming scheme, which is implemented for disks and add your subsystem. + # 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. diff --git a/etc/udev/udev.rules.examples b/etc/udev/udev.rules.examples deleted file mode 100644 index 1c4527891a..0000000000 --- a/etc/udev/udev.rules.examples +++ /dev/null @@ -1,63 +0,0 @@ -# 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. -# -# -# These are some example rules that you could use to name your devices. -# -# If anyone has any other examples that they think should be in here for others -# to use, please send them to greg@kroah.com -# - -# Looking for scsi bus id 42:0:0:1 -BUS=="scsi", PROGRAM="/bin/echo -n test-%b", RESULT=="test-42:0:0:1", NAME="%c" - -# A usb camera. -BUS=="usb", SYSFS{vendor}=="FUJIFILM", SYSFS{model}=="M100", NAME="camera%n" - -# USB Epson printer to be called lp_epson -BUS=="usb", SYSFS_serial=="HXOLL0012202323480", NAME="lp_epson" - -# USB HP printer to be called lp_hp -BUS=="usb", SYSFS{serial}=="W09090207101241330", NAME="lp_hp" - -# sound card with PCI bus id 00:0b.0 to be the first sound card -BUS=="pci", ID=="00:0b.0", NAME="dsp" - -# sound card with PCI bus id 00:07.1 to be the second sound card -BUS=="pci", ID=="00:07.1", NAME="dsp1" - -# ttyUSB1 should always be called visor -KERNEL=="ttyUSB1", NAME="visor" -KERNEL=="ttyUSB0", NAME="pl2303" - -# a devfs like way to name some tty devices -KERNEL=="ttyS*", NAME="tts/%n" -KERNEL=="tty*", NAME="vc/%n" - -# if this is a ide cdrom, name it the default name, and create a symlink to cdrom -BUS=="ide", KERNEL=="*[!0-9]", PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom", NAME="%k", SYMLINK+="cdrom" - -# DRI devices always go into a subdirectory (as per the LSB spec) -KERNEL=="card*", NAME="dri/card%n" - -# create all 15 partitions of a USB flash card reader -BUS=="scsi", SYSFS{model}=="CF/MD", NAME{all_partitions}="compactflash" - -# 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" -KERNEL=="ts*", NAME="input/%k" - -# emulate dev.d/ -RUN="/sbin/udev_run_devd" - diff --git a/extras/run_directory/README b/extras/run_directory/README new file mode 100644 index 0000000000..022c66451c --- /dev/null +++ b/extras/run_directory/README @@ -0,0 +1,17 @@ +Use these binaries only if you need backward compatibility with +older udev versions. The use of /etc/dev.d/ is no longer recommended +Use explicit udev rules with RUN keys to hook into the processing. + + /etc/dev.d/ + /etc/hotplug.d/ directory multiplexing is completely + removed from udev itself and must be emulated by calling small + helper binaries provided by these helpers: + 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.) + diff --git a/docs/RFC-dev.d b/extras/run_directory/RFC-dev.d similarity index 100% rename from docs/RFC-dev.d rename to extras/run_directory/RFC-dev.d diff --git a/etc/dev.d/default/pam_console.dev b/extras/run_directory/dev.d/default/pam_console.dev similarity index 100% rename from etc/dev.d/default/pam_console.dev rename to extras/run_directory/dev.d/default/pam_console.dev diff --git a/etc/dev.d/net/hotplug.dev b/extras/run_directory/dev.d/net/hotplug.dev similarity index 100% rename from etc/dev.d/net/hotplug.dev rename to extras/run_directory/dev.d/net/hotplug.dev diff --git a/etc/dev.d/snd/controlC0/alsa.dev b/extras/run_directory/dev.d/snd/controlC0/alsa.dev similarity index 100% rename from etc/dev.d/snd/controlC0/alsa.dev rename to extras/run_directory/dev.d/snd/controlC0/alsa.dev From d47fd445bd9ade720776f661a4ad7c4b2202d6f0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 9 Aug 2005 22:11:44 +0200 Subject: [PATCH 1424/4284] trivial text cleanups Signed-off-by: Kay Sievers --- README | 3 ++- etc/udev/{udev.rules.devfs => udev-devfs.rules} | 3 --- extras/run_directory/README | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) rename etc/udev/{udev.rules.devfs => udev-devfs.rules} (95%) diff --git a/README b/README index 139c6e1a6f..5dc1e46c89 100644 --- a/README +++ b/README @@ -85,7 +85,8 @@ To use: If nothing seems to happen, make sure your build worked properly by running the udev-test.pl script as root in the test/ subdirectory of the -udev source tree. +udev source tree. Running udevstart should populate an empty /dev +directory. You may test, if a node is recreated after running udevstart. Development and documentation help is very much appreciated, see the TODO file for a list of things left to be done. diff --git a/etc/udev/udev.rules.devfs b/etc/udev/udev-devfs.rules similarity index 95% rename from etc/udev/udev.rules.devfs rename to etc/udev/udev-devfs.rules index b7b2c4e12d..1e71ae1a17 100644 --- a/etc/udev/udev.rules.devfs +++ b/etc/udev/udev-devfs.rules @@ -4,9 +4,6 @@ # it. Use custom rules to name your device or look at the persistent device # naming scheme, which is implemented for disks and add your subsystem. -# 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. - # ide block devices BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" diff --git a/extras/run_directory/README b/extras/run_directory/README index 022c66451c..feae2f81bf 100644 --- a/extras/run_directory/README +++ b/extras/run_directory/README @@ -1,5 +1,5 @@ Use these binaries only if you need backward compatibility with -older udev versions. The use of /etc/dev.d/ is no longer recommended +older udev versions. The use of /etc/dev.d/ is no longer recommended. Use explicit udev rules with RUN keys to hook into the processing. /etc/dev.d/ + /etc/hotplug.d/ directory multiplexing is completely @@ -12,6 +12,6 @@ Use explicit udev rules with RUN keys to hook into the processing. 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.) + fork and exit 300 tty script instances on bootup you are not interested + in, it is just one rule that matches exactly that single device.) From d33c51c24531b602c9f45a8914c6b1db82c003ec Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 10 Aug 2005 15:27:25 +0200 Subject: [PATCH 1425/4284] update SUSE rules Tape naming is harder than expected, go back to block devices only. Signed-off-by: Kay Sievers --- etc/udev/suse/{50-udev.rules => udev.rules} | 29 +++++++++++---------- udevmonitor.c | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) rename etc/udev/suse/{50-udev.rules => udev.rules} (94%) diff --git a/etc/udev/suse/50-udev.rules b/etc/udev/suse/udev.rules similarity index 94% rename from etc/udev/suse/50-udev.rules rename to etc/udev/suse/udev.rules index 515b572e75..8791e42fc7 100644 --- a/etc/udev/suse/50-udev.rules +++ b/etc/udev/suse/udev.rules @@ -188,9 +188,11 @@ KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/udev.devmap_name.sh %M %m", NAME="mapper/%c" # persistent disk device links /dev/disk/ -# skip rules for for ram/loop/fd -SUBSYSTEM=="block", KERNEL=="ram*|loop*|fd*", GOTO="persistent_end" ACTION!="add", GOTO="persistent_end" +SUBSYSTEM!="block", GOTO="persistent_end" + +# skip rules for for ram/loop/fd +KERNEL=="ram*|loop*|fd*", GOTO="persistent_end" # never access removable ide devices, the drivers are causing event loops on open() SUBSYSTEM=="block", BUS=="ide", SYSFS{removable}="1", GOTO="persistent_end" @@ -204,16 +206,12 @@ KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIA KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" -KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="dasd*[!0-9]", IMPORT="/sbin/dasd_id --export $tempnode" +KERNEL=="sd*[!0-9]|sr*|dasd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" # for partitions import parent information -KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*" -KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" - -KERNEL=="dasd*[!0-9]", IMPORT="/sbin/dasd_id --export $tempnode" -KERNEL=="dasd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" -KERNEL=="dasd*[0-9]", IMPORT{parent}=="ID_*" -KERNEL=="dasd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" +KERNEL=="sd*[0-9]|dasd*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" # by-path (shortest physical path) KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}" @@ -223,10 +221,9 @@ KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PA # by-label/by-uuid (filesystem properties) KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_end" KERNEL=="sr*", GOTO="persistent_end" -SUBSYSTEM!="block", GOTO="persistent_end" -KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" -KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" -KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" +IMPORT="/sbin/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}" LABEL="persistent_end" # network devices @@ -257,3 +254,7 @@ RUN+="socket:/org/kernel/udev/monitor" # debug events to /events, but not on default udev_log="err" ENV{UDEV_LOG}=="[4-9]", RUN+="/sbin/hotplugeventrecorder" +# for backward compatibility with older udev versions and hotplug (no longer supported) +# RUN+="/sbin/udev_run_hotplugd" +# RUN+="/sbin/udev_run_devd" + diff --git a/udevmonitor.c b/udevmonitor.c index 51e8a2ab0b..3a71d002f5 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -28,8 +28,8 @@ #include #include #include +#include #include -#include #include "udev.h" #include "udevd.h" From 59d6bfefceac1a31b0408e60cd251b5035cf3b50 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 10 Aug 2005 16:54:14 +0200 Subject: [PATCH 1426/4284] split udev_util in several files It too big for the small tools to link against for only the log function. Signed-off-by: Kay Sievers --- Makefile | 4 +- udev_event.c | 4 - udev_utils.c | 248 ---------------------------------------------- udev_utils_file.c | 140 ++++++++++++++++++++++++++ udev_utils_run.c | 179 +++++++++++++++++++++++++++++++++ 5 files changed, 322 insertions(+), 253 deletions(-) create mode 100644 udev_utils_file.c create mode 100644 udev_utils_run.c diff --git a/Makefile b/Makefile index 7618d0f7fd..ecc798de89 100644 --- a/Makefile +++ b/Makefile @@ -136,7 +136,6 @@ SYSFS_OBJS = \ libsysfs/dlist.o UDEV_OBJS = \ - udev_utils.o \ udev_event.o \ udev_device.o \ udev_config.o \ @@ -146,6 +145,9 @@ UDEV_OBJS = \ udev_db.o \ udev_rules.o \ udev_rules_parse.o \ + udev_utils.o \ + udev_utils_file.o \ + udev_utils_run.o \ udev_libc_wrapper.o OBJS = \ diff --git a/udev_event.c b/udev_event.c index 8a3ed29315..3580ab937f 100644 --- a/udev_event.c +++ b/udev_event.c @@ -28,10 +28,6 @@ #include #include #include -#include -#include -#include -#include #include "udev_libc_wrapper.h" #include "udev.h" diff --git a/udev_utils.c b/udev_utils.c index 500d595c01..de43dee30d 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -28,11 +28,6 @@ #include #include #include -#include -#include -#include -#include -#include #include #include "udev_libc_wrapper.h" @@ -148,109 +143,6 @@ int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, u return 0; } -int create_path(const char *path) -{ - char p[PATH_SIZE]; - char *pos; - struct stat stats; - - strcpy (p, path); - pos = strrchr(p, '/'); - if (pos == p || pos == NULL) - return 0; - - while (pos[-1] == '/') - pos--; - - pos[0] = '\0'; - - dbg("stat '%s'\n", 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'\n", p); - return mkdir(p, 0755); -} - -/* 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) - dbg("chown(%s, 0, 0) failed with error '%s'", filename, strerror(errno)); - - retval = chmod(filename, 0000); - if (retval) - dbg("chmod(%s, 0000) failed with error '%s'", filename, strerror(errno)); - - retval = unlink(filename); - if (errno == ENOENT) - retval = 0; - - if (retval) - dbg("unlink(%s) failed with error '%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; -} - void replace_untrusted_chars(char *string) { size_t len; @@ -373,143 +265,3 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c closedir(dir); return 0; } - -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; - int retval; - - 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; - /* only abstract namespace is supported */ - 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++; - } - - retval = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, addrlen); - if (retval != -1) - retval = 0; - - close(sock); - return retval; -} - -int execute_program(const char *command, const char *subsystem, - char *result, size_t ressize, size_t *reslen) -{ - int retval = 0; - int count; - int status; - int pipefds[2]; - pid_t pid; - char *pos; - char arg[PATH_SIZE]; - char *argv[(sizeof(arg) / 2) + 1]; - int devnull; - int i; - size_t len; - - strlcpy(arg, command, sizeof(arg)); - i = 0; - if (strchr(arg, ' ')) { - pos = arg; - while (pos != NULL) { - if (pos[0] == '\'') { - /* don't separate if in apostrophes */ - pos++; - argv[i] = strsep(&pos, "\'"); - while (pos && pos[0] == ' ') - pos++; - } else { - argv[i] = strsep(&pos, " "); - } - dbg("arg[%i] '%s'", i, argv[i]); - i++; - } - argv[i] = NULL; - dbg("execute '%s' with parsed arguments", arg); - } else { - argv[0] = arg; - argv[1] = (char *) subsystem; - argv[2] = NULL; - dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); - } - - if (result) { - if (pipe(pipefds) != 0) { - err("pipe failed"); - return -1; - } - } - - pid = fork(); - switch(pid) { - case 0: - /* child dup2 write side of pipe to STDOUT */ - devnull = open("/dev/null", O_RDWR); - if (devnull >= 0) { - dup2(devnull, STDIN_FILENO); - if (!result) - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - close(devnull); - } - if (result) - dup2(pipefds[1], STDOUT_FILENO); - execv(arg, argv); - err("exec of program failed"); - _exit(1); - case -1: - err("fork of '%s' failed", arg); - return -1; - default: - /* parent reads from pipefds[0] */ - if (result) { - close(pipefds[1]); - len = 0; - while (1) { - count = read(pipefds[0], result + len, ressize - len-1); - if (count < 0) { - err("read failed with '%s'", strerror(errno)); - retval = -1; - break; - } - - if (count == 0) - break; - - len += count; - if (len >= ressize-1) { - err("ressize %ld too short", (long)ressize); - retval = -1; - break; - } - } - result[len] = '\0'; - close(pipefds[0]); - if (reslen) - *reslen = len; - } - waitpid(pid, &status, 0); - - if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { - dbg("exec program status 0x%x", status); - retval = -1; - } - } - - return retval; -} diff --git a/udev_utils_file.c b/udev_utils_file.c new file mode 100644 index 0000000000..f8518f64ad --- /dev/null +++ b/udev_utils_file.c @@ -0,0 +1,140 @@ +/* + * udev_utils_file.c - files operations + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev_libc_wrapper.h" +#include "udev.h" +#include "logging.h" +#include "udev_utils.h" +#include "list.h" + +int create_path(const char *path) +{ + char p[PATH_SIZE]; + char *pos; + struct stat stats; + + strcpy (p, path); + pos = strrchr(p, '/'); + if (pos == p || pos == NULL) + return 0; + + while (pos[-1] == '/') + pos--; + + pos[0] = '\0'; + + dbg("stat '%s'\n", 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'\n", p); + return mkdir(p, 0755); +} + +/* 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) + dbg("chown(%s, 0, 0) failed with error '%s'", filename, strerror(errno)); + + retval = chmod(filename, 0000); + if (retval) + dbg("chmod(%s, 0000) failed with error '%s'", filename, strerror(errno)); + + retval = unlink(filename); + if (errno == ENOENT) + retval = 0; + + if (retval) + dbg("unlink(%s) failed with error '%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/udev_utils_run.c b/udev_utils_run.c new file mode 100644 index 0000000000..c2e77cbbcc --- /dev/null +++ b/udev_utils_run.c @@ -0,0 +1,179 @@ +/* + * udev_utils_run.c - execute programs from udev and read its output + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev_libc_wrapper.h" +#include "udev.h" +#include "logging.h" +#include "udev_utils.h" +#include "list.h" + + +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; + int retval; + + 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; + /* only abstract namespace is supported */ + 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++; + } + + retval = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, addrlen); + if (retval != -1) + retval = 0; + + close(sock); + return retval; +} + +int execute_program(const char *command, const char *subsystem, + char *result, size_t ressize, size_t *reslen) +{ + int retval = 0; + int count; + int status; + int pipefds[2]; + pid_t pid; + char *pos; + char arg[PATH_SIZE]; + char *argv[(sizeof(arg) / 2) + 1]; + int devnull; + int i; + size_t len; + + strlcpy(arg, command, sizeof(arg)); + i = 0; + if (strchr(arg, ' ')) { + pos = arg; + while (pos != NULL) { + if (pos[0] == '\'') { + /* don't separate if in apostrophes */ + pos++; + argv[i] = strsep(&pos, "\'"); + while (pos && pos[0] == ' ') + pos++; + } else { + argv[i] = strsep(&pos, " "); + } + dbg("arg[%i] '%s'", i, argv[i]); + i++; + } + argv[i] = NULL; + dbg("execute '%s' with parsed arguments", arg); + } else { + argv[0] = arg; + argv[1] = (char *) subsystem; + argv[2] = NULL; + dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); + } + + if (result) { + if (pipe(pipefds) != 0) { + err("pipe failed"); + return -1; + } + } + + pid = fork(); + switch(pid) { + case 0: + /* child dup2 write side of pipe to STDOUT */ + devnull = open("/dev/null", O_RDWR); + if (devnull >= 0) { + dup2(devnull, STDIN_FILENO); + if (!result) + dup2(devnull, STDOUT_FILENO); + dup2(devnull, STDERR_FILENO); + close(devnull); + } + if (result) + dup2(pipefds[1], STDOUT_FILENO); + execv(arg, argv); + err("exec of program failed"); + _exit(1); + case -1: + err("fork of '%s' failed", arg); + return -1; + default: + /* parent reads from pipefds[0] */ + if (result) { + close(pipefds[1]); + len = 0; + while (1) { + count = read(pipefds[0], result + len, ressize - len-1); + if (count < 0) { + err("read failed with '%s'", strerror(errno)); + retval = -1; + break; + } + + if (count == 0) + break; + + len += count; + if (len >= ressize-1) { + err("ressize %ld too short", (long)ressize); + retval = -1; + break; + } + } + result[len] = '\0'; + close(pipefds[0]); + if (reslen) + *reslen = len; + } + waitpid(pid, &status, 0); + + if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { + dbg("exec program status 0x%x", status); + retval = -1; + } + } + + return retval; +} + From a1ea706a1e3dfa1bb86ebcfcd0b819311526b2e2 Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Wed, 10 Aug 2005 17:06:01 +0200 Subject: [PATCH 1427/4284] fix udevinfo output --- udevinfo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index d2c3e1ab7f..58584d62f8 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -289,7 +289,7 @@ int main(int argc, char *argv[], char *envp[]) } retval = udev_db_get_device(&udev, pos); if (retval != 0) { - fprintf(stderr, "device not found in database\n"); + fprintf(stderr, "no record for '%s' in database\n", pos); goto exit; } goto print; @@ -329,7 +329,7 @@ print: goto exit; case QUERY_SYMLINK: if (list_empty(&udev.symlink_list)) - break; + goto exit; if (root) list_for_each_entry(name_loop, &udev.symlink_list, node) printf("%s/%s ", udev_root, name_loop->name); From 7fd0de4984deac2e51f9b85c156f200beadbc7ef Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 11 Aug 2005 17:19:05 +0200 Subject: [PATCH 1428/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/udev.rules | 5 +++-- udevstart.c | 5 +---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/udev.rules index 8791e42fc7..b0c1f1adcb 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/udev.rules @@ -46,7 +46,7 @@ SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8006/*", RUN+="/sbin/fxload SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8001/*", RUN+="/sbin/startproc /usr/bin/us428control" SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8005/*", RUN+="/sbin/startproc /usr/bin/us428control" SUBSYSTEM=="sound", KERNEL=="controlC?", RUN+="/usr/sbin/alsactl -F restore %n" -SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVER=="EMU10K1_Audigy", RUN+="/etc/dev.d/snd/hwC0D2/alsa" +SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVER=="EMU10K1_Audigy", RUN+="/etc/alsa.d/udev-soundfont" # OpenCT (SmartCard) SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="973/1*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" @@ -221,7 +221,8 @@ KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PA # by-label/by-uuid (filesystem properties) KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_end" KERNEL=="sr*", GOTO="persistent_end" -IMPORT="/sbin/vol_id --export $tempnode" +KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" +KERNEL=="*[!0-9]", SYSFS{range}=="[1-9]*", IMPORT="/sbin/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}" LABEL="persistent_end" diff --git a/udevstart.c b/udevstart.c index 4288db9d38..23a13e08ff 100644 --- a/udevstart.c +++ b/udevstart.c @@ -315,10 +315,7 @@ static void udev_scan_class(void) snprintf(dirname2, sizeof(dirname2), "%s/%s", dirname, dent2->d_name); dirname2[sizeof(dirname2)-1] = '\0'; - /* pass the net class as it is */ - if (strcmp(dent->d_name, "net") == 0) - device_list_insert(dirname2, "net", &device_list); - else if (has_devt(dirname2)) + if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0) device_list_insert(dirname2, dent->d_name, &device_list); } closedir(dir2); From 27f877e60f1c1793d6fafdd888e7e367c44b2eb9 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 11 Aug 2005 17:32:59 +0200 Subject: [PATCH 1429/4284] allow logging of all output from executed tools If USE_DEBUG=true and udev_log="debug", all output of the forked programs to stdout and stderr is send to syslog. Signed-off-by: Kay Sievers --- extras/run_directory/run_directory.c | 4 +- udev.c | 3 +- udev_rules.c | 6 +- udev_utils.h | 6 +- udev_utils_run.c | 156 ++++++++++++++++++++------- udevstart.c | 3 +- 6 files changed, 132 insertions(+), 46 deletions(-) diff --git a/extras/run_directory/run_directory.c b/extras/run_directory/run_directory.c index 770d8d84a1..5107f85aef 100644 --- a/extras/run_directory/run_directory.c +++ b/extras/run_directory/run_directory.c @@ -27,7 +27,7 @@ #include "../../logging.h" #include "run_directory.h" -static int run_program(const char *filename, const char *subsystem) +static int exec_program(const char *filename, const char *subsystem) { pid_t pid; @@ -59,7 +59,7 @@ int run_directory(const char *dir, const char *suffix, const char *subsystem) add_matching_files(&name_list, dir, suffix); list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { - run_program(name_loop->name, subsystem); + exec_program(name_loop->name, subsystem); list_del(&name_loop->node); } diff --git a/udev.c b/udev.c index ecfd5644ec..d50f81ea5e 100644 --- a/udev.c +++ b/udev.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" @@ -127,7 +128,7 @@ int main(int argc, char *argv[], char *envp[]) if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, action); else - execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); + run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_DEBUG)); } } diff --git a/udev_rules.c b/udev_rules.c index d42b219d7d..8587b02549 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -221,7 +222,7 @@ static int import_program_into_env(struct udevice *udev, const char *program) char result[1024]; size_t reslen; - if (execute_program(program, udev->subsystem, result, sizeof(result), &reslen) != 0) + if (run_program(program, udev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_DEBUG)) != 0) return -1; return import_keys_into_env(udev, result, reslen); } @@ -833,8 +834,9 @@ try_parent: strlcpy(program, key_val(rule, &rule->program), sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); dbg("check for PROGRAM program='%s", program); - if (execute_program(program, udev->subsystem, result, sizeof(result), NULL) != 0) { + if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_DEBUG)) != 0) { dbg("PROGRAM is false"); + udev->program_result[0] = '\0'; if (rule->program.operation != KEY_OP_NOMATCH) goto exit; } else { diff --git a/udev_utils.h b/udev_utils.h index 5b223855b6..a3fc283203 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -24,6 +24,8 @@ #include "udev.h" #include "list.h" +#define UDEV_MAX(a,b) ((a) > (b) ? (a) : (b)) + struct name_entry { struct list_head node; char name[PATH_SIZE]; @@ -45,7 +47,7 @@ extern int name_list_add(struct list_head *name_list, const char *name, int sort extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); extern int add_matching_files(struct list_head *name_list, const char *dirname, const char *suffix); extern int pass_env_to_socket(const char *name, const char *devpath, const char *action); -extern int execute_program(const char *command, const char *subsystem, - char *result, size_t ressize, size_t *reslen); +extern int run_program(const char *command, const char *subsystem, + char *result, size_t ressize, size_t *reslen, int log); #endif diff --git a/udev_utils_run.c b/udev_utils_run.c index c2e77cbbcc..50b31781e7 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "udev_libc_wrapper.h" #include "udev.h" @@ -70,20 +71,19 @@ int pass_env_to_socket(const char *sockname, const char *devpath, const char *ac return retval; } -int execute_program(const char *command, const char *subsystem, - char *result, size_t ressize, size_t *reslen) +int run_program(const char *command, const char *subsystem, + char *result, size_t ressize, size_t *reslen, int dbg) { int retval = 0; - int count; int status; - int pipefds[2]; + int outpipe[2] = {-1, -1}; + int errpipe[2] = {-1, -1}; pid_t pid; char *pos; char arg[PATH_SIZE]; char *argv[(sizeof(arg) / 2) + 1]; int devnull; int i; - size_t len; strlcpy(arg, command, sizeof(arg)); i = 0; @@ -102,7 +102,7 @@ int execute_program(const char *command, const char *subsystem, dbg("arg[%i] '%s'", i, argv[i]); i++; } - argv[i] = NULL; + argv[i] = NULL; dbg("execute '%s' with parsed arguments", arg); } else { argv[0] = arg; @@ -111,8 +111,15 @@ int execute_program(const char *command, const char *subsystem, dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); } - if (result) { - if (pipe(pipefds) != 0) { + /* prepare pipes from child to parent */ + if (result || dbg) { + if (pipe(outpipe) != 0) { + err("pipe failed"); + return -1; + } + } + if (dbg) { + if (pipe(errpipe) != 0) { err("pipe failed"); return -1; } @@ -121,53 +128,127 @@ int execute_program(const char *command, const char *subsystem, pid = fork(); switch(pid) { case 0: - /* child dup2 write side of pipe to STDOUT */ + /* child closes parent ends of pipes */ + if (outpipe[0] > 0) + close(outpipe[0]); + if (errpipe[0] > 0) + close(errpipe[0]); + + /* discard child output or connect to pipe */ devnull = open("/dev/null", O_RDWR); - if (devnull >= 0) { - dup2(devnull, STDIN_FILENO); - if (!result) - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - close(devnull); + if (devnull < 0) { + err("open /dev/null failed"); + exit(1); } - if (result) - dup2(pipefds[1], STDOUT_FILENO); + dup2(devnull, STDIN_FILENO); + + if (outpipe[1] > 0) + dup2(outpipe[1], STDOUT_FILENO); + else + dup2(devnull, STDOUT_FILENO); + + if (errpipe[1] > 0) + dup2(errpipe[1], STDERR_FILENO); + else + dup2(devnull, STDERR_FILENO); + + close(devnull); execv(arg, argv); + + /* we should never reach this */ err("exec of program failed"); _exit(1); case -1: err("fork of '%s' failed", arg); return -1; default: - /* parent reads from pipefds[0] */ - if (result) { - close(pipefds[1]); - len = 0; - while (1) { - count = read(pipefds[0], result + len, ressize - len-1); - if (count < 0) { - err("read failed with '%s'", strerror(errno)); + /* read from child if requested */ + if (outpipe[0] > 0 || errpipe[0] > 0) { + size_t count; + size_t respos = 0; + + /* parent closes child ends of pipes */ + if (outpipe[1] > 0) + close(outpipe[1]); + if (errpipe[1] > 0) + close(errpipe[1]); + + /* read child output */ + while (outpipe[0] > 0 || errpipe[0] > 0) { + int fdcount; + fd_set readfds; + + FD_ZERO(&readfds); + if (outpipe[0] > 0) + FD_SET(outpipe[0], &readfds); + if (errpipe[0] > 0) + FD_SET(errpipe[0], &readfds); + fdcount = select(UDEV_MAX(outpipe[0], errpipe[0])+1, &readfds, NULL, NULL, NULL); + if (fdcount < 0) { + if (errno == EINTR) + continue; retval = -1; break; } - if (count == 0) - break; + /* get stdout */ + if (outpipe[0] > 0 && FD_ISSET(outpipe[0], &readfds)) { + char inbuf[1024]; - len += count; - if (len >= ressize-1) { - err("ressize %ld too short", (long)ressize); - retval = -1; - break; + count = read(outpipe[0], inbuf, sizeof(inbuf)-1); + if (count <= 0) { + close(outpipe[0]); + outpipe[0] = -1; + if (count < 0) { + err("stdin read failed with '%s'", strerror(errno)); + retval = -1; + } + continue; + } + inbuf[count] = '\0'; + dbg("stdout: '%s'", inbuf); + + if (result) { + if (respos + count >= ressize) { + err("ressize %ld too short", (long)ressize); + retval = -1; + continue; + } + memcpy(&result[respos], inbuf, count); + respos += count; + } + } + + /* get stderr */ + if (errpipe[0] > 0 && FD_ISSET(errpipe[0], &readfds)) { + char errbuf[1024]; + + count = read(errpipe[0], errbuf, sizeof(errbuf)-1); + if (count <= 0) { + close(errpipe[0]); + errpipe[0] = -1; + if (count < 0) + err("stderr read failed with '%s'", strerror(errno)); + continue; + } + errbuf[count] = '\0'; + dbg("stderr: '%s'", errbuf); } } - result[len] = '\0'; - close(pipefds[0]); - if (reslen) - *reslen = len; + if (outpipe[0] > 0) + close(outpipe[0]); + if (errpipe[0] > 0) + close(errpipe[0]); + + /* 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) || (WEXITSTATUS(status) != 0)) { dbg("exec program status 0x%x", status); retval = -1; @@ -176,4 +257,3 @@ int execute_program(const char *command, const char *subsystem, return retval; } - diff --git a/udevstart.c b/udevstart.c index 23a13e08ff..90b87b8377 100644 --- a/udevstart.c +++ b/udevstart.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -164,7 +165,7 @@ run: if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, "add"); else - execute_program(name_loop->name, udev.subsystem, NULL, 0, NULL); + run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_DEBUG)); } } exit: From 2b996ad19339858ab702c27c9976581ca6784628 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 11 Aug 2005 20:34:24 +0200 Subject: [PATCH 1430/4284] add Usage: to udevmonitor and udevcontrol Signed-off-by: Kay Sievers --- udevcontrol.c | 60 +++++++++++++++++++++++++++++++++------------------ udevd.c | 16 ++++++++------ udevmonitor.c | 48 +++++++++++++++++++++++++++++------------ 3 files changed, 83 insertions(+), 41 deletions(-) diff --git a/udevcontrol.c b/udevcontrol.c index 5d8fa77683..f16f6a125a 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -64,6 +64,7 @@ int main(int argc, char *argv[], char *envp[]) const char *env; const char *val; int *intval; + int i; int retval = 1; env = getenv("UDEV_LOG"); @@ -73,33 +74,50 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udevcontrol"); dbg("version %s", UDEV_VERSION); - if (argc != 2) { - err("error finding comand"); + if (argc < 2) { + fprintf(stderr, "missing command\n\n"); goto exit; } memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); strcpy(usend_msg.magic, UDEV_MAGIC); - if (!strcmp(argv[1], "stop_exec_queue")) - usend_msg.type = UDEVD_STOP_EXEC_QUEUE; - else if (!strcmp(argv[1], "start_exec_queue")) - usend_msg.type = UDEVD_START_EXEC_QUEUE; - else if (!strncmp(argv[1], "log_priority=", strlen("log_priority="))) { - intval = (int *) usend_msg.envbuf; - val = &argv[1][strlen("log_priority=")]; - usend_msg.type = UDEVD_SET_LOG_LEVEL; - *intval = log_priority(val); - info("send log_priority=%i", *intval); - } else if (!strncmp(argv[1], "max_childs=", strlen("max_childs="))) { - intval = (int *) usend_msg.envbuf; - val = &argv[1][strlen("max_childs=")]; - usend_msg.type = UDEVD_SET_MAX_CHILDS; - *intval = atoi(val); - info("send max_childs=%i", *intval); - } else { - err("error parsing command\n"); - goto exit; + for (i = 1 ; i < argc; i++) { + char *arg = argv[i]; + + if (!strcmp(arg, "stop_exec_queue")) + usend_msg.type = UDEVD_STOP_EXEC_QUEUE; + else if (!strcmp(arg, "start_exec_queue")) + usend_msg.type = UDEVD_START_EXEC_QUEUE; + else if (!strncmp(arg, "log_priority=", strlen("log_priority="))) { + intval = (int *) usend_msg.envbuf; + val = &arg[strlen("log_priority=")]; + usend_msg.type = UDEVD_SET_LOG_LEVEL; + *intval = log_priority(val); + info("send log_priority=%i", *intval); + } else if (!strncmp(arg, "max_childs=", strlen("max_childs="))) { + intval = (int *) usend_msg.envbuf; + val = &arg[strlen("max_childs=")]; + usend_msg.type = UDEVD_SET_MAX_CHILDS; + *intval = atoi(val); + info("send max_childs=%i", *intval); + } 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" + " max_childs= maximum number of childs running at the same time\n" + " --help print this help text\n\n"); + exit(0); + } else { + fprintf(stderr, "unknown option\n\n"); + exit(1); + } + } + + if (getuid() != 0) { + fprintf(stderr, "need to be root, exit\n\n"); + exit(1); } sock = socket(AF_LOCAL, SOCK_DGRAM, 0); diff --git a/udevd.c b/udevd.c index d51ed2f7b0..1575da8d5a 100644 --- a/udevd.c +++ b/udevd.c @@ -54,7 +54,7 @@ static int udevd_sock; static int uevent_netlink_sock; static pid_t sid; -static int pipefds[2]; +static int pipefds[2] = {-1, -1}; static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int sig_flag; @@ -843,11 +843,10 @@ int main(int argc, char *argv[], char *envp[]) /* Set fds to dev/null */ fd = open( "/dev/null", O_RDWR ); if (fd >= 0) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) - close(fd); + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + close(fd); } else err("error opening /dev/null %s", strerror(errno)); @@ -1012,6 +1011,11 @@ int main(int argc, char *argv[], char *envp[]) } exit: + if (pipefds[0] > 0) + close(pipefds[0]); + if (pipefds[1] > 0) + close(pipefds[1]); + if (udevd_sock > 0) close(udevd_sock); diff --git a/udevmonitor.c b/udevmonitor.c index 3a71d002f5..2efb705b6d 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -33,6 +33,7 @@ #include "udev.h" #include "udevd.h" +#include "udev_utils.h" #include "udev_libc_wrapper.h" static int uevent_netlink_sock; @@ -102,25 +103,42 @@ static int init_uevent_netlink_sock(void) int main(int argc, char *argv[]) { int env = 0; - int maxsockplus; fd_set readfds; + int i; int retval; - if (getuid() != 0) { - printf("need to be root, exit\n"); - exit(1); + for (i = 1 ; i < argc; i++) { + char *arg = argv[i]; + if (strcmp(arg, "--env") == 0 || strcmp(arg, "-e") == 0) { + env = 1; + } + else if (strcmp(arg, "--help") == 0 || strcmp(arg, "-h") == 0){ + printf("Usage: udevmonitor [--env]\n" + " --env print the whole event environment\n" + " --help print this help text\n\n"); + exit(0); + } else { + fprintf(stderr, "unknown option\n\n"); + exit(1); + } } - if (argc == 2 && strstr(argv[1], "--env")) - env = 1; + if (getuid() != 0) { + fprintf(stderr, "need to be root, exit\n\n"); + exit(1); + } init_uevent_netlink_sock(); init_udev_monitor_socket(); + printf("udevmonitor prints received from the kernel [UEVENT] and after\n" + "the udev processing, the event which udev [UDEV] has generated\n\n"); + FD_ZERO(&readfds); - FD_SET(uevent_netlink_sock, &readfds); - FD_SET(udev_monitor_sock, &readfds); - maxsockplus = udev_monitor_sock+1; + if (uevent_netlink_sock > 0) + FD_SET(uevent_netlink_sock, &readfds); + if (udev_monitor_sock > 0) + FD_SET(udev_monitor_sock, &readfds); while (1) { static char buf[UEVENT_BUFFER_SIZE*2]; @@ -130,14 +148,14 @@ int main(int argc, char *argv[]) buflen = 0; workreadfds = readfds; - retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); + retval = select(UDEV_MAX(uevent_netlink_sock, udev_monitor_sock)+1, &workreadfds, NULL, NULL, NULL); if (retval < 0) { if (errno != EINTR) fprintf(stderr, "error receiving uevent message\n"); continue; } - if (FD_ISSET(uevent_netlink_sock, &workreadfds)) { + if ((uevent_netlink_sock > 0) && FD_ISSET(uevent_netlink_sock, &workreadfds)) { buflen = recv(uevent_netlink_sock, &buf, sizeof(buf), 0); if (buflen <= 0) { fprintf(stderr, "error receiving uevent message\n"); @@ -146,7 +164,7 @@ int main(int argc, char *argv[]) printf("UEVENT[%i] %s\n", time(NULL), buf); } - if (FD_ISSET(udev_monitor_sock, &workreadfds)) { + if ((udev_monitor_sock > 0) && FD_ISSET(udev_monitor_sock, &workreadfds)) { buflen = recv(udev_monitor_sock, &buf, sizeof(buf), 0); if (buflen <= 0) { fprintf(stderr, "error receiving udev message\n"); @@ -180,7 +198,9 @@ int main(int argc, char *argv[]) } } - close(uevent_netlink_sock); - close(udev_monitor_sock); + if (uevent_netlink_sock > 0) + close(uevent_netlink_sock); + if (udev_monitor_sock > 0) + close(udev_monitor_sock); exit(1); } From 4937afa402bf142429f0ac6dfc7e1bf8172faa62 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 11 Aug 2005 21:01:46 +0200 Subject: [PATCH 1431/4284] move some logging to the info level Signed-off-by: Kay Sievers --- etc/udev/suse/udev.rules | 2 +- udev.c | 1 + udev_rules.c | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/udev.rules index b0c1f1adcb..0e3d06817a 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/udev.rules @@ -234,7 +234,7 @@ SUBSYSTEM=="net", ACTION=="remove", RUN+="/sbin/ifdown %k -o hotplug" # libusb device access (mount usbfs or usbdev nodes) DEVPATH=="/module/usbcore", ACTION=="add", RUN+="/bin/mount -t usbfs usbfs /proc/bus/usb" -SUBSYSTEM="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev} B=$${X%%%%.*} D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK="%c" +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+="/etc/hotplug.d/firmware/50-firmware.hotplug" diff --git a/udev.c b/udev.c index d50f81ea5e..f0b2800a91 100644 --- a/udev.c +++ b/udev.c @@ -125,6 +125,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("executing run list"); list_for_each_entry(name_loop, &udev.run_list, node) { + info("RUN key executes '%s'", name_loop->name); if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, action); else diff --git a/udev_rules.c b/udev_rules.c index 8587b02549..40c010c63f 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -808,7 +808,7 @@ try_parent: apply_format(udev, import, sizeof(import), class_dev, sysfs_device); dbg("check for IMPORT import='%s'", import); if (rule->import_type == IMPORT_PROGRAM) { - dbg("run executable file import='%s'", import); + info("IMPORT executes '%s'", import); rc = import_program_into_env(udev, import); } else if (rule->import_type == IMPORT_FILE) { dbg("import file import='%s'", import); @@ -833,7 +833,7 @@ try_parent: strlcpy(program, key_val(rule, &rule->program), sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - dbg("check for PROGRAM program='%s", program); + info("PROGRAM key executes '%s", program); if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_DEBUG)) != 0) { dbg("PROGRAM is false"); udev->program_result[0] = '\0'; @@ -1033,7 +1033,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s if (!name_set) { strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); - info("no rule found, will use kernel name '%s'", udev->name); + info("no node name set, will use kernel name '%s'", udev->name); } if (udev->tmp_node[0] != '\0') { From 02a9a08fb7c37c1142441ba74333b2c7a1084a99 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 13:02:44 -0700 Subject: [PATCH 1432/4284] update gentoo rule file. This fixes the issue of cdroms not showing up in the proper group, and them showing up in /dev/cd/ for the persistant names. Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index d208f5068d..1c1bfed81d 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -37,7 +37,8 @@ BUS=="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYM BUS=="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" BUS=="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -# devfs-names for ide-devices (uncomment only one) +# devfs-names for ide-devices +# Note, this is going away soon... # /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names BUS=="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK+="%c{1} %c{2}", GROUP="%c{3}" @@ -243,8 +244,9 @@ KERNEL=="issm*", NAME="infiniband/%k" # tpm devices KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" -# block device disk id's -SUBSYSTEM=="block", GROUP="disk", MODE="0640" +####################################### +# Persistant block device stuff - begin +####################################### # skip accessing removable ide devices, cause the ide drivers are horrible broken SUBSYSTEM=="block", BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" @@ -252,25 +254,25 @@ SUBSYSTEM=="block", BUS=="ide", SYSFS{../removable}="1", GOTO="no_volume_id" # persistent disk device links /dev/disk/ KERNEL=="hd*[!0-9]", ACTION=="add", IMPORT="/etc/udev/scripts/ata_id --export $tempnode" -KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" -KERNEL=="hd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" +KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" +KERNEL=="hd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" -KERNEL=="sd*[!0-9]", ACTION=="add", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" +KERNEL=="sd*[!0-9]", ACTION=="add", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/usb_id -x" KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/scsi_id -g -x -s %p" KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/scsi_id -g -x -a -s %p" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" KERNEL=="sd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" -KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" +KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" # Skip id for ram / loop / fd SUBSYSTEM=="block", KERNEL=="ram*", GOTO="no_volume_id" SUBSYSTEM=="block", KERNEL=="loop*", GOTO="no_volume_id" SUBSYSTEM=="block", KERNEL=="fd*", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="*[!0-9]", ACTION=="add", ENV{ID_TYPE}=="?*", IMPORT="/etc/udev/scripts/path_id %p", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}" +SUBSYSTEM=="block", KERNEL=="*[!0-9]", ACTION=="add", ENV{ID_TYPE}=="?*", IMPORT="/etc/udev/scripts/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" -SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", ENV{ID_PATH}=="?*", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}-part%n" +SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" # volume-label/uuid SUBSYSTEM=="block", KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" @@ -280,6 +282,9 @@ SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-u SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" SUBSYSTEM=="block", LABEL="no_volume_id" +##################################### +# Persistant block device stuff - end +##################################### # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems # run /etc/hotplug.d/ stuff only if we came from a hotplug event, not for udevstart From 8f6919e6390d79a2765e1dc9b0057412e987dce2 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 13:59:21 -0700 Subject: [PATCH 1433/4284] Created cdrom_id program to make it easier to determine cdrom types Based on the framework from ata_id by Kay. Now we can drop the cdsymlinks.sh and .c files Signed-off-by: Greg Kroah-Hartman --- extras/cdrom_id/Makefile | 51 +++++++++++++++ extras/cdrom_id/cdrom_id.c | 129 +++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 extras/cdrom_id/Makefile create mode 100644 extras/cdrom_id/cdrom_id.c diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile new file mode 100644 index 0000000000..44c9ba2b08 --- /dev/null +++ b/extras/cdrom_id/Makefile @@ -0,0 +1,51 @@ +# Makefile for cdrom_id +# +# Copyright (C) 2004 Kay Sievers +# 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. +# + +PROG = cdrom_id + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +OBJS = cdrom_id.o ../../udev.a + +$(OBJS): $(HEADERS) + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(PROG): $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c new file mode 100644 index 0000000000..7d97d0b07b --- /dev/null +++ b/extras/cdrom_id/cdrom_id.c @@ -0,0 +1,129 @@ +/* + * 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. + * + * Framework based on ata_id which is: + * Copyright (C) 2005 Kay Sievers + * + */ + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE 1 +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../logging.h" +#include "../../udev_utils.h" + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + static int udev_log = -1; + + if (udev_log == -1) { + const char *value; + + value = getenv("UDEV_LOG"); + if (value) + udev_log = log_priority(value); + else + udev_log = LOG_ERR; + } + + if (priority > udev_log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +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) { + err("no node specified"); + rc = 1; + goto exit; + } + + fd = open(node, O_RDONLY); + if (fd < 0) + if (errno == ENOMEDIUM) + fd = open(node, O_RDONLY|O_NONBLOCK); + if (fd < 0) { + err("unable to open '%s'", node); + rc = 1; + goto exit; + } + + result = ioctl(fd, CDROM_GET_CAPABILITY); + if (result < 0) { + err("CDROM_GET_CABILITY failed for '%s'", node); + rc = 3; + goto close; + } + + printf("ID_CDC=true\n"); + + if (result & CDC_CD_R) + printf("ID_CDC_CD_R=true\n"); + if (result & CDC_CD_RW) + printf("ID_CDC_CD_RW=true\n"); + + if (result & CDC_DVD) + printf("ID_CDC_DVD=true\n"); + if (result & CDC_DVD_R) + printf("ID_CDC_DVD_R=true\n"); + if (result & CDC_DVD_RAM) + printf("ID_CDC_DVD_RAM=true\n"); + + if (result & CDC_MRW) + printf("ID_CDC_MRW=true\n"); + if (result & CDC_MRW_W) + printf("ID_CDC_MRW_W=true\n"); + + if (result & CDC_RAM) + printf("ID_CDC_RAM=true\n"); + goto close; + +close: + close(fd); +exit: + logging_close(); + return rc; +} From 8ee99e32799956f23bfd898c48b1276ed47d5c1d Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 14:04:24 -0700 Subject: [PATCH 1434/4284] changed cdrom_id exports to be easier to understand and consistant with other _id programs. Signed-off-by: Greg Kroah-Hartman --- extras/cdrom_id/cdrom_id.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index 7d97d0b07b..f0acedd1cc 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -98,27 +98,27 @@ int main(int argc, char *argv[]) goto close; } - printf("ID_CDC=true\n"); + printf("ID_CDROM=1\n"); if (result & CDC_CD_R) - printf("ID_CDC_CD_R=true\n"); + printf("ID_CDROM_CD_R=1\n"); if (result & CDC_CD_RW) - printf("ID_CDC_CD_RW=true\n"); + printf("ID_CDROM_CD_RW=1\n"); if (result & CDC_DVD) - printf("ID_CDC_DVD=true\n"); + printf("ID_CDROM_DVD=1\n"); if (result & CDC_DVD_R) - printf("ID_CDC_DVD_R=true\n"); + printf("ID_CDROM_DVD_R=1\n"); if (result & CDC_DVD_RAM) - printf("ID_CDC_DVD_RAM=true\n"); + printf("ID_CDROM_DVD_RAM=1\n"); if (result & CDC_MRW) - printf("ID_CDC_MRW=true\n"); + printf("ID_CDROM_MRW=1\n"); if (result & CDC_MRW_W) - printf("ID_CDC_MRW_W=true\n"); + printf("ID_CDROM_MRW_W=1\n"); if (result & CDC_RAM) - printf("ID_CDC_RAM=true\n"); + printf("ID_CDROM_RAM=1\n"); goto close; close: From c1986ea33c26fc285688cfbc0a8473cd10c733ca Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 14:37:54 -0700 Subject: [PATCH 1435/4284] added cdrom_id to the build check --- test/simple-build-check.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 521691618a..0112ef78e2 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -7,6 +7,7 @@ EXTRAS="\ extras/volume_id \ extras/usb_id \ extras/dasd_id \ + extras/cdrom_id \ extras/floppy \ extras/run_directory \ extras/firmware" From 5a64cea1e18dd4e62b6388c8bed86192a1e0c731 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 14:38:33 -0700 Subject: [PATCH 1436/4284] fix klibc build issue in cdrom_id.c Signed-off-by: Greg Kroah-Hartman --- extras/cdrom_id/cdrom_id.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index f0acedd1cc..556499b811 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) goto exit; } - result = ioctl(fd, CDROM_GET_CAPABILITY); + result = ioctl(fd, CDROM_GET_CAPABILITY, NULL); if (result < 0) { err("CDROM_GET_CABILITY failed for '%s'", node); rc = 3; @@ -116,7 +116,7 @@ int main(int argc, char *argv[]) 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"); goto close; From 55ac5dad09ce1b7663e17c6f166e6ef74153f93d Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 15:08:08 -0700 Subject: [PATCH 1437/4284] Change the gentoo rules to use cdrom_id instead of cdsymlink.sh Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 1c1bfed81d..f8f7b45bb0 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -33,14 +33,13 @@ KERNEL=="ircomm*", NAME="%k", GROUP="tty" SUBSYSTEM=="block", GROUP="disk" # cdrom symlinks and other good cdrom naming -BUS=="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS=="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS=="scsi", KERNEL="scd[a-z]", PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - -# devfs-names for ide-devices -# Note, this is going away soon... -# /dev/ide/.../{disc,cd} and /dev/{cdroms,discs}/* type names -BUS=="ide", KERNEL="hd*", PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK+="%c{1} %c{2}", GROUP="%c{3}" +BUS=="ide", KERNEL=="hd[a-z]", ACTION=="add", IMPORT="/etc/udev/scripts/cdrom_id --export $tempnode" +BUS=="scsi", KERNEL="sr[0-9]*", ACTION=="add", IMPORT="/etc/udev/scripts/cdrom_id --export $tempnode" +BUS=="scsi", KERNEL="scd[a-z]", ACTION=="add", IMPORT="/etc/udev/scripts/cdrom_id --export $tempnode" +ENV{ID_CDROM}=="?*", SYMLINK+="cdrom%e", GROUP="cdrom" +ENV{ID_CDROM_CD_RW}=="?*", SYMLINK+="cdrw%e" +ENV{ID_CDROM_DVD}=="?*", SYMLINK+="dvd%e" +ENV{ID_CDROM_DVD_R}=="?*", SYMLINK+="dvdrw%e" # disk devices KERNEL=="sd*", NAME="%k", GROUP="disk" From 91a8b5315930e18e912a7858e2415d77ec7cf4db Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 15:10:10 -0700 Subject: [PATCH 1438/4284] changed location of gentoo helper apps to be /sbin instead of in scripts dir Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index f8f7b45bb0..d3f6c9b63f 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -33,9 +33,9 @@ KERNEL=="ircomm*", NAME="%k", GROUP="tty" SUBSYSTEM=="block", GROUP="disk" # cdrom symlinks and other good cdrom naming -BUS=="ide", KERNEL=="hd[a-z]", ACTION=="add", IMPORT="/etc/udev/scripts/cdrom_id --export $tempnode" -BUS=="scsi", KERNEL="sr[0-9]*", ACTION=="add", IMPORT="/etc/udev/scripts/cdrom_id --export $tempnode" -BUS=="scsi", KERNEL="scd[a-z]", ACTION=="add", IMPORT="/etc/udev/scripts/cdrom_id --export $tempnode" +BUS=="ide", KERNEL=="hd[a-z]", ACTION=="add", IMPORT="/sbin/cdrom_id --export $tempnode" +BUS=="scsi", KERNEL="sr[0-9]*", ACTION=="add", IMPORT="/sbin/cdrom_id --export $tempnode" +BUS=="scsi", KERNEL="scd[a-z]", ACTION=="add", IMPORT="/sbin/cdrom_id --export $tempnode" ENV{ID_CDROM}=="?*", SYMLINK+="cdrom%e", GROUP="cdrom" ENV{ID_CDROM_CD_RW}=="?*", SYMLINK+="cdrw%e" ENV{ID_CDROM_DVD}=="?*", SYMLINK+="dvd%e" @@ -252,14 +252,14 @@ SUBSYSTEM=="block", BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" SUBSYSTEM=="block", BUS=="ide", SYSFS{../removable}="1", GOTO="no_volume_id" # persistent disk device links /dev/disk/ -KERNEL=="hd*[!0-9]", ACTION=="add", IMPORT="/etc/udev/scripts/ata_id --export $tempnode" +KERNEL=="hd*[!0-9]", ACTION=="add", IMPORT="/sbin/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]", ACTION=="add", IMPORT{parent}=="ID_*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" KERNEL=="sd*[!0-9]", ACTION=="add", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/usb_id -x" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/scsi_id -g -x -s %p" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/etc/udev/scripts/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" +KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" KERNEL=="sd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" @@ -269,14 +269,14 @@ SUBSYSTEM=="block", KERNEL=="ram*", GOTO="no_volume_id" SUBSYSTEM=="block", KERNEL=="loop*", GOTO="no_volume_id" SUBSYSTEM=="block", KERNEL=="fd*", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="*[!0-9]", ACTION=="add", ENV{ID_TYPE}=="?*", IMPORT="/etc/udev/scripts/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +SUBSYSTEM=="block", KERNEL=="*[!0-9]", ACTION=="add", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" # volume-label/uuid SUBSYSTEM=="block", KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" SUBSYSTEM=="block", KERNEL=="sr*", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT="/etc/udev/scripts/vol_id --export $tempnode" +SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT="/sbin/vol_id --export $tempnode" SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" SUBSYSTEM=="block", LABEL="no_volume_id" From a3f47f6319188e45604f42280652b9027323e7b3 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 15:32:14 -0700 Subject: [PATCH 1439/4284] tweak the gentoo rules some more. - make the persistant rules smaller - add usbfs-like device node support Signed-off-by: Greg Kroah-Hartman --- etc/udev/gentoo/udev.rules | 54 ++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index d3f6c9b63f..f1e38b8d87 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -247,44 +247,54 @@ KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" # Persistant block device stuff - begin ####################################### +# Skip all of this if we are not adding a block device +ACTION!="add", GOTO="persistent_end" +SUBSYSTEM!="block", GOTO="persistent_end" + # skip accessing removable ide devices, cause the ide drivers are horrible broken -SUBSYSTEM=="block", BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" -SUBSYSTEM=="block", BUS=="ide", SYSFS{../removable}="1", GOTO="no_volume_id" +BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" +BUS=="ide", SYSFS{../removable}="1", GOTO="no_volume_id" # persistent disk device links /dev/disk/ -KERNEL=="hd*[!0-9]", ACTION=="add", IMPORT="/sbin/ata_id --export $tempnode" +KERNEL=="hd*[!0-9]", IMPORT="/sbin/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]", ACTION=="add", IMPORT{parent}=="ID_*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" +KERNEL=="hd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" -KERNEL=="sd*[!0-9]", ACTION=="add", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" -KERNEL=="sd*[!0-9]", ACTION=="add", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" -KERNEL=="sd*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" +KERNEL=="sd*[!0-9]", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*" KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" # Skip id for ram / loop / fd -SUBSYSTEM=="block", KERNEL=="ram*", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="loop*", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="fd*", GOTO="no_volume_id" +KERNEL=="ram*", GOTO="no_volume_id" +KERNEL=="loop*", GOTO="no_volume_id" +KERNEL=="fd*", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="*[!0-9]", ACTION=="add", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" -SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT{parent}=="ID_*" -SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" +KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" # volume-label/uuid -SUBSYSTEM=="block", KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="sr*", GOTO="no_volume_id" -SUBSYSTEM=="block", KERNEL=="*[0-9]", ACTION=="add", IMPORT="/sbin/vol_id --export $tempnode" -SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" -SUBSYSTEM=="block", KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" -SUBSYSTEM=="block", LABEL="no_volume_id" +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" +KERNEL=="sr*", GOTO="no_volume_id" +KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" +KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" +KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" +LABEL="no_volume_id" + +LABEL="persistent_end" ##################################### # Persistant block device stuff - end ##################################### +# usbfs-like device nodes +SUBSYSTEM="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev} B=$${X%%%%.*} D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c" + + # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems # run /etc/hotplug.d/ stuff only if we came from a hotplug event, not for udevstart ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" From f5bed72a53c16e203d5f822167778355530c362a Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 11 Aug 2005 15:44:08 -0700 Subject: [PATCH 1440/4284] 066 release --- ChangeLog | 39 +++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index bc62f95c61..d8c81f67b7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,42 @@ +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 ============================================ diff --git a/Makefile b/Makefile index ecc798de89..53811703d0 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 065 +VERSION = 066 ROOT = udev DAEMON = udevd SENDER = udevsend diff --git a/udev.spec b/udev.spec index 52bfa2ffae..d64d32c535 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace device manager providing devfs functionality Name: udev -Version: 065 +Version: 066 Release: 1 License: GPL Group: Utilities/System From 5590ace308dc57821a5704bdf4a6f586ae2fd698 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 12 Aug 2005 00:50:48 +0200 Subject: [PATCH 1441/4284] update SUSE rules don't use ID_TYPE, so cdroms will be in /dev/disk/ Signed-off-by: Kay Sievers --- etc/udev/suse/udev.rules | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/udev.rules index 0e3d06817a..683a22a2bb 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/udev.rules @@ -195,34 +195,33 @@ SUBSYSTEM!="block", GOTO="persistent_end" KERNEL=="ram*|loop*|fd*", GOTO="persistent_end" # never access removable ide devices, the drivers are causing event loops on open() -SUBSYSTEM=="block", BUS=="ide", SYSFS{removable}="1", GOTO="persistent_end" +SUBSYSTEM=="block", BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}="1", GOTO="persistent_end" # by-id (hardware serial number) KERNEL=="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" -KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" -KERNEL=="hd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" +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}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" +KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\n'" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" KERNEL=="dasd*[!0-9]", IMPORT="/sbin/dasd_id --export $tempnode" -KERNEL=="sd*[!0-9]|sr*|dasd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +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+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" +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]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}" +KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" KERNEL=="*[0-9]", IMPORT{parent}=="ID_*" -KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}-part%n" +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" KERNEL=="sr*", GOTO="persistent_end" -KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" -KERNEL=="*[!0-9]", SYSFS{range}=="[1-9]*", IMPORT="/sbin/vol_id --export $tempnode" +IMPORT="/sbin/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}" LABEL="persistent_end" From d2e8d41b9c7bacd8169c4cb1d15b7bc95445d34b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 12 Aug 2005 02:07:50 +0200 Subject: [PATCH 1442/4284] fix make install, as we don't provide a default rule set anymore Several people complained about the "default" rules and the "default" setup. Here we start to remove things where we can't hava a "default". The best examples for rules are in the distro folders, just pick the one that matches your needs and start from there. Signed-off-by: Kay Sievers --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 53811703d0..e14cb18981 100644 --- a/Makefile +++ b/Makefile @@ -356,8 +356,9 @@ install-config: $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ fi @if [ ! -r $(DESTDIR)$(configdir)/rules.d/50-udev.rules ]; then \ - echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir)/rules.d/50-udev.rules; \ - $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.rules $(DESTDIR)$(configdir)/rules.d/50-udev.rules; \ + echo ; \ + echo "pick a udev rules file from the etc/udev directory that matches your distribution"; \ + echo ; \ fi install-man: From 903a36495f2c796f15464943ad26bfd76f548b6a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 12 Aug 2005 11:37:56 -0700 Subject: [PATCH 1443/4284] added the cdrom.h #defines directly into the cdrom_id.c file This solves the problem with building the file against old kernel header files. Signed-off-by: Greg Kroah-Hartman --- extras/cdrom_id/cdrom_id.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index 556499b811..3d62781186 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -26,11 +26,42 @@ #include #include #include -#include #include "../../logging.h" #include "../../udev_utils.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, ...) { From 853ccc433c4d45c3e1da4336f87b458ed10311ca Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 13 Aug 2005 00:18:44 +0200 Subject: [PATCH 1444/4284] fix more compiler warnings ... Signed-off-by: Kay Sievers --- extras/scsi_id/scsi_id.c | 26 ++++++++++---------- extras/usb_id/usb_id.c | 33 ++++++++++++++------------ extras/volume_id/volume_id/util.c | 8 +------ extras/volume_id/volume_id/volume_id.c | 2 +- udev_db.c | 2 +- udev_rules.c | 6 ++--- udev_utils_run.c | 2 +- 7 files changed, 38 insertions(+), 41 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 8e5172f93c..a46d1b377d 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -133,42 +133,42 @@ static void set_str(char *to, const char *from, size_t count) to[j] = '\0'; } -static void set_type(char *to, const char *from, int count) +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: - sprintf(to, "disk"); + type = "disk"; break; case 1: - sprintf(to, "tape"); + type = "tape"; break; case 4: - sprintf(to, "optical"); + type = "optical"; break; case 5: - sprintf(to, "cd"); + type = "cd"; break; case 7: - sprintf(to, "optical"); + type = "optical"; break; case 0xe: - sprintf(to, "disk"); + type = "disk"; break; case 0xf: - sprintf(to, "optical"); + type = "optical"; break; default: - sprintf(to, "generic"); break; } - } else { - sprintf(to, "generic"); } + strncpy(to, type, len); + to[len-1] = '\0'; } static int get_major_minor(struct sysfs_class_device *class_dev, int *maj, @@ -475,7 +475,7 @@ static int set_options(int argc, char **argv, const char *short_opts, */ optind = 1; while (1) { - option = getopt(argc, argv, short_options); + option = getopt(argc, argv, short_opts); if (option == -1) break; @@ -601,7 +601,7 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, scsi_dev->name); return -1; } - set_type(type_str, type->value, sizeof(type_str)-1); + set_type(type_str, type->value, sizeof(type_str)); type = sysfs_get_device_attr(scsi_dev, "rev"); if (!type) { diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index 37db6d14db..f5ee795924 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -119,25 +119,26 @@ static void set_str(char *to, const char *from, size_t count) * * Set the type based on the USB interface class */ -static void set_usb_iftype(char *to, const char *from, int count) +static void set_usb_iftype(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 1: - sprintf(to, "audio"); + type = "audio"; break; case 3: - sprintf(to, "hid"); + type = "hid"; break; case 7: - sprintf(to, "printer"); + type = "printer"; break; case 8: - sprintf(to, "disk"); + type = "disk"; break; case 2: /* CDC-Control */ case 5: /* Physical */ @@ -152,12 +153,11 @@ static void set_usb_iftype(char *to, const char *from, int count) case 0xf2: /* Application-specific */ case 0xff: /* Vendor-specific */ default: - sprintf(to, "generic"); break; } - } else { - sprintf(to, "generic"); } + strncpy(to, type, len); + to[len-1] = '\0'; } /* @@ -166,32 +166,35 @@ static void set_usb_iftype(char *to, const char *from, int count) * Set the type base on the interfaceSubClass. * Valid for Mass-Storage devices (type 8) only. */ -static int set_usb_ifsubtype(char *to, const char *from, int count) +static int set_usb_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: - sprintf(to, "cd"); + type = "cd"; break; case 3: - sprintf(to, "tape"); + type = "tape"; break; case 4: /* UFI */ case 5: /* SFF-8070i */ - sprintf(to, "floppy"); + type = "floppy"; break; case 1: /* RBC devices */ case 6: /* Transparent SPC-2 devices */ - sprintf(to, "disk"); + type = "disk"; + break; + default: break; } - } else { - sprintf(to, "generic"); } + strncpy(to, type, len); + to[len-1] = '\0'; return type_num; } diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index a145a8aa2f..868d67306c 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -114,12 +114,6 @@ void volume_id_set_label_raw(struct volume_id *id, const uint8_t *buf, size_t co id->label_raw_len = count; } -static size_t my_strnlen(const char *s, size_t max) { - const char *p = s; - for (; *p && max--; ++p); - return(p - s); -} - void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t count) { unsigned int i; @@ -127,7 +121,7 @@ void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t memcpy(id->label, buf, count); /* remove trailing whitespace */ - i = my_strnlen(id->label, count); + i = strnlen(id->label, count); while (i--) { if (!isspace(id->label[i])) break; diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 4c4a42a00d..e7d4d75666 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -227,7 +227,7 @@ struct volume_id *volume_id_open_dev_t(dev_t devt) snprintf(tmp_node, VOLUME_ID_PATH_MAX, "/dev/.volume_id-%u-%u-%u", getpid(), major(devt), minor(devt)); - tmp_node[VOLUME_ID_PATH_MAX] = '\0'; + tmp_node[VOLUME_ID_PATH_MAX-1] = '\0'; /* create tempory node to open the block device */ unlink(tmp_node); diff --git a/udev_db.c b/udev_db.c index f9adf5c631..ac5a7e6d65 100644 --- a/udev_db.c +++ b/udev_db.c @@ -262,7 +262,7 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) nodename[count-2] = '\0'; dbg("compare '%s' '%s'", nodename, name); if (strcmp(nodename, name) == 0) { - memcpy(devpath, &bufline[2], count-2); + strlcpy(devpath, nodename, len); devpath[count-2] = '\0'; file_unmap(buf, bufsize); closedir(dir); diff --git a/udev_rules.c b/udev_rules.c index 40c010c63f..791e98ec07 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -270,7 +270,7 @@ static int import_parent_into_env(struct udevice *udev, struct sysfs_class_devic /* finds the lowest positive N such that N isn't present in the udevdb * if doesn't exist, 0 is returned, N otherwise */ -static int find_free_number(struct udevice *udev, const char *name) +static int find_free_number(const char *name) { char devpath[PATH_SIZE]; char filename[PATH_SIZE]; @@ -397,7 +397,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, { .name = "root", .fmt = 'r', .type = SUBST_ROOT }, { .name = "modalias", .fmt = 'A', .type = SUBST_MODALIAS }, { .name = "env", .fmt = 'E', .type = SUBST_ENV }, - {} + { NULL, '\0', 0 } }; enum subst_type type; const struct subst_map *subst; @@ -546,7 +546,7 @@ found: dbg("substitute sysfs value '%s'", temp2); break; case SUBST_ENUM: - next_free_number = find_free_number(udev, string); + next_free_number = find_free_number(string); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); strlcat(string, temp2, maxsize); diff --git a/udev_utils_run.c b/udev_utils_run.c index 50b31781e7..44fb7f8316 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -164,7 +164,7 @@ int run_program(const char *command, const char *subsystem, default: /* read from child if requested */ if (outpipe[0] > 0 || errpipe[0] > 0) { - size_t count; + ssize_t count; size_t respos = 0; /* parent closes child ends of pipes */ From 7d38d2287c882ffee02b5f285f2ee5bb60de0efa Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 13 Aug 2005 02:19:22 +0200 Subject: [PATCH 1445/4284] fix udevstart event ordering, we want /dev/null very early --- udevstart.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/udevstart.c b/udevstart.c index 90b87b8377..3a715a609f 100644 --- a/udevstart.c +++ b/udevstart.c @@ -77,11 +77,12 @@ static int device_list_insert(const char *path, char *subsystem, struct list_hea { struct device *loop_device; struct device *new_device; + const char *devpath = &path[strlen(sysfs_path)]; - dbg("insert: '%s'\n", path); + dbg("insert: '%s'\n", devpath); list_for_each_entry(loop_device, device_list, node) { - if (strcmp(loop_device->path, path) > 0) { + if (strcmp(loop_device->path, devpath) > 0) { break; } } @@ -92,7 +93,7 @@ static int device_list_insert(const char *path, char *subsystem, struct list_hea return -ENOMEM; } - strlcpy(new_device->path, path, sizeof(new_device->path)); + strlcpy(new_device->path, devpath, sizeof(new_device->path)); strlcpy(new_device->subsys, subsystem, sizeof(new_device->subsys)); list_add_tail(&new_device->node, &loop_device->node); dbg("add '%s' from subsys '%s'", new_device->path, new_device->subsys); @@ -107,17 +108,16 @@ static char *last_list[] = { /* list of devices that we should run first due to any one of a number of reasons */ static char *first_list[] = { - "/class/mem", /* people tend to like their memory devices around first... */ + "/class/mem", + "/class/tty", NULL, }; -static int add_device(const char *path, const char *subsystem) +static int add_device(const char *devpath, const char *subsystem) { struct udevice udev; struct sysfs_class_device *class_dev; - const char *devpath; - - devpath = &path[strlen(sysfs_path)]; + char path[PATH_SIZE]; /* clear and set environment for next event */ clearenv(); @@ -129,8 +129,10 @@ static int add_device(const char *path, const char *subsystem) setenv("UDEV_LOG", udev_log_str, 1); if (udev_run_str) setenv("UDEV_RUN", udev_run_str, 1); - dbg("exec: '%s' (%s)\n", devpath, path); + dbg("add '%s'", devpath); + snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); + path[sizeof(path)-1] = '\0'; class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg("sysfs_open_class_device_path failed"); @@ -218,12 +220,12 @@ static void exec_list(struct list_head *device_list) } } -static int has_devt(const char *directory) +static int has_devt(const char *path) { char filename[PATH_SIZE]; struct stat statbuf; - snprintf(filename, sizeof(filename), "%s/dev", directory); + snprintf(filename, sizeof(filename), "%s/dev", path); filename[sizeof(filename)-1] = '\0'; if (stat(filename, &statbuf) == 0) @@ -232,12 +234,11 @@ static int has_devt(const char *directory) return 0; } -static void udev_scan_block(void) +static void udev_scan_block(struct list_head *device_list) { char base[PATH_SIZE]; DIR *dir; struct dirent *dent; - LIST_HEAD(device_list); snprintf(base, sizeof(base), "%s/block", sysfs_path); base[sizeof(base)-1] = '\0'; @@ -255,7 +256,7 @@ static void udev_scan_block(void) snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name); dirname[sizeof(dirname)-1] = '\0'; if (has_devt(dirname)) - device_list_insert(dirname, "block", &device_list); + device_list_insert(dirname, "block", device_list); else continue; @@ -272,22 +273,20 @@ static void udev_scan_block(void) dirname2[sizeof(dirname2)-1] = '\0'; if (has_devt(dirname2)) - device_list_insert(dirname2, "block", &device_list); + device_list_insert(dirname2, "block", device_list); } closedir(dir2); } } closedir(dir); } - exec_list(&device_list); } -static void udev_scan_class(void) +static void udev_scan_class(struct list_head *device_list) { char base[PATH_SIZE]; DIR *dir; struct dirent *dent; - LIST_HEAD(device_list); snprintf(base, sizeof(base), "%s/class", sysfs_path); base[sizeof(base)-1] = '\0'; @@ -317,14 +316,13 @@ static void udev_scan_class(void) dirname2[sizeof(dirname2)-1] = '\0'; if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0) - device_list_insert(dirname2, dent->d_name, &device_list); + device_list_insert(dirname2, dent->d_name, device_list); } closedir(dir2); } } closedir(dir); } - exec_list(&device_list); } static void asmlinkage sig_handler(int signum) @@ -340,6 +338,7 @@ static void asmlinkage sig_handler(int signum) int main(int argc, char *argv[], char *envp[]) { + LIST_HEAD(device_list); struct sigaction act; logging_init("udevstart"); @@ -367,8 +366,9 @@ int main(int argc, char *argv[], char *envp[]) udev_rules_init(&rules, 0, 1); - udev_scan_block(); - udev_scan_class(); + udev_scan_class(&device_list); + udev_scan_block(&device_list); + exec_list(&device_list); udev_rules_close(&rules); logging_close(); From af5461f72f86bc00fd40a11a8ac2b6979f8cd61a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 13 Aug 2005 02:36:12 +0200 Subject: [PATCH 1446/4284] don't fail too bad, if /dev/null does not exist Signed-off-by: Kay Sievers --- udev_utils_run.c | 20 ++++++++------------ udevd.c | 14 +++++++------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/udev_utils_run.c b/udev_utils_run.c index 44fb7f8316..cf633661e4 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -136,23 +136,19 @@ int run_program(const char *command, const char *subsystem, /* discard child output or connect to pipe */ devnull = open("/dev/null", O_RDWR); - if (devnull < 0) { + if (devnull > 0) { + dup2(devnull, STDIN_FILENO); + if (outpipe[1] < 0) + dup2(devnull, STDOUT_FILENO); + if (errpipe[1] < 0) + dup2(devnull, STDERR_FILENO); + close(devnull); + } else err("open /dev/null failed"); - exit(1); - } - dup2(devnull, STDIN_FILENO); - if (outpipe[1] > 0) dup2(outpipe[1], STDOUT_FILENO); - else - dup2(devnull, STDOUT_FILENO); - if (errpipe[1] > 0) dup2(errpipe[1], STDERR_FILENO); - else - dup2(devnull, STDERR_FILENO); - - close(devnull); execv(arg, argv); /* we should never reach this */ diff --git a/udevd.c b/udevd.c index 1575da8d5a..8423278d6c 100644 --- a/udevd.c +++ b/udevd.c @@ -785,7 +785,7 @@ int main(int argc, char *argv[], char *envp[]) { int maxsockplus; int retval; - int fd; + int devnull; struct sigaction act; fd_set readfds; const char *value; @@ -841,12 +841,12 @@ int main(int argc, char *argv[], char *envp[]) setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); /* Set fds to dev/null */ - fd = open( "/dev/null", O_RDWR ); - if (fd >= 0) { - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - close(fd); + devnull = open( "/dev/null", O_RDWR ); + if (devnull > 0) { + dup2(devnull, STDIN_FILENO); + dup2(devnull, STDOUT_FILENO); + dup2(devnull, STDERR_FILENO); + close(devnull); } else err("error opening /dev/null %s", strerror(errno)); From 8aafc06d943e98dfa4ff8410eb85686e49feccbf Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 13 Aug 2005 10:10:50 -0700 Subject: [PATCH 1447/4284] 067 release --- ChangeLog | 14 ++++++++++++++ Makefile | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index d8c81f67b7..f1cf451c44 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +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 ============================================ diff --git a/Makefile b/Makefile index e14cb18981..dcfac9cf9d 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 066 +VERSION = 067 ROOT = udev DAEMON = udevd SENDER = udevsend From 40caaeec51f5d8f65245932a85396ac85265cbe5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 15 Aug 2005 11:57:04 +0200 Subject: [PATCH 1448/4284] cleanup some debug output and move to info level + unify select() loops Signed-off-by: Kay Sievers --- logging.h | 4 +- udev.c | 3 +- udev_add.c | 2 +- udev_db.c | 2 +- udev_libc_wrapper.h | 9 +++- udev_remove.c | 2 +- udev_rules.c | 8 ++-- udev_rules_parse.c | 8 +++- udev_utils_run.c | 58 +++++++++++++++-------- udevd.c | 113 +++++++++++++++++++++----------------------- udeveventrecorder.c | 2 +- udevmonitor.c | 32 +++++++------ udevstart.c | 2 +- 13 files changed, 132 insertions(+), 113 deletions(-) diff --git a/logging.h b/logging.h index 0126de99eb..e0dcb80305 100644 --- a/logging.h +++ b/logging.h @@ -38,13 +38,13 @@ #undef err #define err(format, arg...) \ do { \ - log_message(LOG_ERR ,"%s: " format ,__FILE__ ,## arg); \ + log_message(LOG_ERR ,"%s: " format ,__FUNCTION__ ,## arg); \ } while (0) #undef info #define info(format, arg...) \ do { \ - log_message(LOG_INFO ,"%s: " format ,__FILE__ ,## arg); \ + log_message(LOG_INFO ,"%s: " format ,__FUNCTION__ ,## arg); \ } while (0) #ifdef DEBUG diff --git a/udev.c b/udev.c index f0b2800a91..beaa191c04 100644 --- a/udev.c +++ b/udev.c @@ -125,11 +125,10 @@ int main(int argc, char *argv[], char *envp[]) dbg("executing run list"); list_for_each_entry(name_loop, &udev.run_list, node) { - info("RUN key executes '%s'", name_loop->name); if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, action); else - run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_DEBUG)); + run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); } } diff --git a/udev_add.c b/udev_add.c index 9d872bf039..9420b4fe14 100644 --- a/udev_add.c +++ b/udev_add.c @@ -215,7 +215,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de strlcat(linktarget, &udev->name[tail], sizeof(linktarget)); - dbg("symlink(%s, %s)", linktarget, filename); + info("creating symlink '%s' to '%s'", filename, linktarget); if (!udev->test_run) { unlink(filename); selinux_setfscreatecon(filename, NULL, S_IFLNK); diff --git a/udev_db.c b/udev_db.c index ac5a7e6d65..632f6f7b2a 100644 --- a/udev_db.c +++ b/udev_db.c @@ -113,7 +113,7 @@ static int parse_db_file(struct udevice *udev, const char *filename) size_t count; if (file_map(filename, &buf, &bufsize) != 0) { - err("unable to read db file '%s'", filename); + dbg("no db file to read '%s'", filename); return -1; } diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index a12af64c24..9dd22175cd 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -22,6 +22,11 @@ #ifndef _UDEV_LIBC_WRAPPER_H_ #define _UDEV_LIBC_WRAPPER_H_ +#include +#include +#include + +/* needed for our signal handlers to work */ #undef asmlinkage #ifdef __i386__ #define asmlinkage __attribute__((regparm(0))) @@ -29,6 +34,7 @@ #define asmlinkage #endif +/* headers are broken on some lazy platforms */ #ifndef __FD_SET #define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d)) #endif @@ -42,12 +48,11 @@ #define __FD_ZERO(set) ((void) memset ((void*) (set), 0, sizeof (fd_set))) #endif +/* missing in some lazy distros */ #ifndef NETLINK_KOBJECT_UEVENT #define NETLINK_KOBJECT_UEVENT 15 #endif -#include - #ifdef __KLIBC__ static inline int clearenv(void) { diff --git a/udev_remove.c b/udev_remove.c index 28885d4710..cff940ccfe 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -88,7 +88,7 @@ static int delete_node(struct udevice *udev) continue;; } - dbg("removing symlink '%s'", filename); + info("removing symlink '%s'", filename); unlink(filename); if (strchr(filename, '/')) diff --git a/udev_rules.c b/udev_rules.c index 791e98ec07..7ecca9468e 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -222,7 +222,7 @@ static int import_program_into_env(struct udevice *udev, const char *program) char result[1024]; size_t reslen; - if (run_program(program, udev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_DEBUG)) != 0) + if (run_program(program, udev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_INFO)) != 0) return -1; return import_keys_into_env(udev, result, reslen); } @@ -808,7 +808,6 @@ try_parent: apply_format(udev, import, sizeof(import), class_dev, sysfs_device); dbg("check for IMPORT import='%s'", import); if (rule->import_type == IMPORT_PROGRAM) { - info("IMPORT executes '%s'", import); rc = import_program_into_env(udev, import); } else if (rule->import_type == IMPORT_FILE) { dbg("import file import='%s'", import); @@ -833,8 +832,7 @@ try_parent: strlcpy(program, key_val(rule, &rule->program), sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - info("PROGRAM key executes '%s", program); - if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_DEBUG)) != 0) { + if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) { dbg("PROGRAM is false"); udev->program_result[0] = '\0'; if (rule->program.operation != KEY_OP_NOMATCH) @@ -964,7 +962,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s } strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); - info("rule applied, added symlink '%s'", temp); + dbg("rule applied, added symlink '%s'", temp); /* add multiple symlinks separated by spaces */ pos = temp; diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 488b7a7ff0..c14164f1cc 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -642,7 +642,13 @@ int udev_rules_init(struct udev_rules *rules, int read_compiled, int resolve_nam retval = add_matching_files(&name_list, udev_rules_filename, RULEFILE_SUFFIX); list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { - parse_file(rules, name_loop->name); + if (stat(name_loop->name, &stats) == 0) { + if (stats.st_size) + parse_file(rules, name_loop->name); + else + dbg("empty rules file '%s'", name_loop->name); + } else + dbg("could not read '%s'", name_loop->name); list_del(&name_loop->node); free(name_loop); } diff --git a/udev_utils_run.c b/udev_utils_run.c index cf633661e4..0ee36d6848 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -46,7 +46,8 @@ int pass_env_to_socket(const char *sockname, const char *devpath, const char *ac char buf[2048]; size_t bufpos = 0; int i; - int retval; + ssize_t count; + int retval = 0; dbg("pass environment to socket '%s'", sockname); sock = socket(AF_LOCAL, SOCK_DGRAM, 0); @@ -63,23 +64,23 @@ int pass_env_to_socket(const char *sockname, const char *devpath, const char *ac bufpos++; } - retval = sendto(sock, &buf, bufpos, 0, (struct sockaddr *)&saddr, addrlen); - if (retval != -1) - retval = 0; + 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 run_program(const char *command, const char *subsystem, - char *result, size_t ressize, size_t *reslen, int dbg) + char *result, size_t ressize, size_t *reslen, int log) { int retval = 0; int status; int outpipe[2] = {-1, -1}; int errpipe[2] = {-1, -1}; pid_t pid; - char *pos; char arg[PATH_SIZE]; char *argv[(sizeof(arg) / 2) + 1]; int devnull; @@ -88,7 +89,7 @@ int run_program(const char *command, const char *subsystem, strlcpy(arg, command, sizeof(arg)); i = 0; if (strchr(arg, ' ')) { - pos = arg; + char *pos = arg; while (pos != NULL) { if (pos[0] == '\'') { /* don't separate if in apostrophes */ @@ -103,22 +104,22 @@ int run_program(const char *command, const char *subsystem, i++; } argv[i] = NULL; - dbg("execute '%s' with parsed arguments", arg); + info("'%s'", command); } else { argv[0] = arg; argv[1] = (char *) subsystem; argv[2] = NULL; - dbg("execute '%s' with subsystem '%s' argument", arg, argv[1]); + info("'%s' '%s'", arg, argv[1]); } /* prepare pipes from child to parent */ - if (result || dbg) { + if (result || log) { if (pipe(outpipe) != 0) { err("pipe failed"); return -1; } } - if (dbg) { + if (log) { if (pipe(errpipe) != 0) { err("pipe failed"); return -1; @@ -149,13 +150,13 @@ int run_program(const char *command, const char *subsystem, dup2(outpipe[1], STDOUT_FILENO); if (errpipe[1] > 0) dup2(errpipe[1], STDERR_FILENO); - execv(arg, argv); + execv(argv[0], argv); /* we should never reach this */ err("exec of program failed"); _exit(1); case -1: - err("fork of '%s' failed", arg); + err("fork of '%s' failed", argv[0]); return -1; default: /* read from child if requested */ @@ -190,6 +191,8 @@ int run_program(const char *command, const char *subsystem, /* get stdout */ if (outpipe[0] > 0 && FD_ISSET(outpipe[0], &readfds)) { char inbuf[1024]; + char *pos; + char *line; count = read(outpipe[0], inbuf, sizeof(inbuf)-1); if (count <= 0) { @@ -202,22 +205,28 @@ int run_program(const char *command, const char *subsystem, continue; } inbuf[count] = '\0'; - dbg("stdout: '%s'", inbuf); + /* store result for rule processing */ if (result) { - if (respos + count >= ressize) { + if (respos + count < ressize) { + memcpy(&result[respos], inbuf, count); + respos += count; + } else { err("ressize %ld too short", (long)ressize); retval = -1; - continue; } - memcpy(&result[respos], inbuf, count); - respos += count; } + pos = inbuf; + while ((line = strsep(&pos, "\n"))) + if (pos || line[0] != '\0') + info("'%s' (stdout) '%s'", argv[0], line); } /* get stderr */ if (errpipe[0] > 0 && FD_ISSET(errpipe[0], &readfds)) { char errbuf[1024]; + char *pos; + char *line; count = read(errpipe[0], errbuf, sizeof(errbuf)-1); if (count <= 0) { @@ -228,7 +237,10 @@ int run_program(const char *command, const char *subsystem, continue; } errbuf[count] = '\0'; - dbg("stderr: '%s'", errbuf); + pos = errbuf; + while ((line = strsep(&pos, "\n"))) + if (pos || line[0] != '\0') + info("'%s' (stderr) '%s'", argv[0], line); } } if (outpipe[0] > 0) @@ -245,8 +257,12 @@ int run_program(const char *command, const char *subsystem, } } waitpid(pid, &status, 0); - if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) { - dbg("exec program status 0x%x", status); + 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; } } diff --git a/udevd.c b/udevd.c index 8423278d6c..79d3e82550 100644 --- a/udevd.c +++ b/udevd.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -62,22 +63,17 @@ static volatile int udev_exit; static int init_phase = 1; static int run_exec_q; static int stop_exec_q; +static char *udev_bin; +static int event_timeout; +static int max_childs; +static int max_childs_running; +static unsigned long long expected_seqnum; +static char log[32]; static LIST_HEAD(msg_list); static LIST_HEAD(exec_list); static LIST_HEAD(running_list); -static void exec_queue_manager(void); -static void msg_queue_manager(void); -static void user_sighandler(void); -static void reap_sigchilds(void); - -static char *udev_bin; -static unsigned long long expected_seqnum; -static int event_timeout; -static int max_childs; -static int max_childs_running; - #ifdef USE_LOG void log_message (int priority, const char *format, ...) @@ -138,7 +134,8 @@ static void msg_queue_insert(struct uevent_msg *msg) /* don't delay messages with timeout set */ if (msg->timeout) { - dbg("move seq %llu with timeout %u to exec queue", msg->seqnum, msg->timeout); + info("seq %llu with timeout %u seconds will be execute without queuing, '%s' '%s'", + msg->seqnum, msg->timeout, msg->action, msg->devpath); list_add(&msg->node, &exec_list); run_exec_q = 1; return; @@ -156,7 +153,7 @@ static void msg_queue_insert(struct uevent_msg *msg) } } list_add(&msg->node, &loop_msg->node); - info("seq %llu queued, devpath '%s'", msg->seqnum, msg->devpath); + info("seq %llu queued, '%s' '%s'", msg->seqnum, msg->action, msg->devpath); /* run msg queue manager */ run_msg_q = 1; @@ -165,7 +162,7 @@ static void msg_queue_insert(struct uevent_msg *msg) } /* forks event and removes event from run queue when finished */ -static void udev_event_fork(struct uevent_msg *msg) +static void udev_event_run(struct uevent_msg *msg) { char *const argv[] = { "udev", msg->subsystem, NULL }; pid_t pid; @@ -190,8 +187,8 @@ static void udev_event_fork(struct uevent_msg *msg) default: /* get SIGCHLD in main loop */ sysinfo(&info); - info("seq %llu forked, pid %d, %ld seconds old", - msg->seqnum, pid, info.uptime - msg->queue_time); + info("seq %llu forked, pid [%d], '%s' '%s', %ld seconds old", + msg->seqnum, pid, msg->action, msg->subsystem, info.uptime - msg->queue_time); msg->pid = pid; } } @@ -385,7 +382,7 @@ static void exec_queue_manager(void) if (running_with_devpath(loop_msg, max_childs) == 0) { /* move event to run list */ list_move_tail(&loop_msg->node, &running_list); - udev_event_fork(loop_msg); + udev_event_run(loop_msg); running++; dbg("moved seq %llu to running list", loop_msg->seqnum); } else @@ -441,7 +438,7 @@ recheck: msg_dump_queue(); /* set timeout for remaining queued events */ - if (list_empty(&msg_list) == 0) { + if (!list_empty(&msg_list)) { struct itimerval itv = {{0, 0}, {timeout - msg_age, 0}}; dbg("next event expires in %li seconds", timeout - msg_age); setitimer(ITIMER_REAL, &itv, NULL); @@ -550,7 +547,7 @@ static struct uevent_msg *get_udevd_msg(void) switch (usend_msg.type) { case UDEVD_UEVENT_UDEVSEND: case UDEVD_UEVENT_INITSEND: - info("udevd event message received"); + dbg("udevd event message received"); envbuf_size = size - offsetof(struct udevd_msg, envbuf); dbg("envbuf_size=%i", envbuf_size); msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size); @@ -571,6 +568,8 @@ static struct uevent_msg *get_udevd_msg(void) intval = (int *) usend_msg.envbuf; info("udevd message (SET_LOG_PRIORITY) received, udev_log_priority=%i", *intval); udev_log_priority = *intval; + sprintf(log, "UDEV_LOG=%i", udev_log_priority); + putenv(log); break; case UDEVD_SET_MAX_CHILDS: intval = (int *) usend_msg.envbuf; @@ -658,7 +657,7 @@ static void asmlinkage sig_handler(int signum) * which will wakeup our mainloop */ if (!sig_flag) { - rc = write(pipefds[1],&signum,sizeof(signum)); + rc = write(pipefds[1], &signum, sizeof(signum)); if (rc >= 0) sig_flag = 1; } @@ -688,30 +687,16 @@ static void udev_done(int pid) static void reap_sigchilds(void) { - while(1) { - int pid = waitpid(-1, NULL, WNOHANG); - if ((pid == -1) || (pid == 0)) + pid_t pid; + + while (1) { + pid = waitpid(-1, NULL, WNOHANG); + if (pid <= 0) break; udev_done(pid); } } -/* just read everything from the pipe and clear the flag, - * the flags was set in the signal handler - */ -static void user_sighandler(void) -{ - int sig; - - while(1) { - int rc = read(pipefds[0], &sig, sizeof(sig)); - if (rc < 0) - break; - - sig_flag = 0; - } -} - static int init_udevd_socket(void) { struct sockaddr_un saddr; @@ -783,7 +768,6 @@ static int init_uevent_netlink_sock(void) int main(int argc, char *argv[], char *envp[]) { - int maxsockplus; int retval; int devnull; struct sigaction act; @@ -813,6 +797,7 @@ int main(int argc, char *argv[], char *envp[]) stop_exec_q = 1; } } + if (daemonize) { pid_t pid; @@ -856,7 +841,6 @@ int main(int argc, char *argv[], char *envp[]) err("error getting pipes: %s", strerror(errno)); goto exit; } - retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); if (retval < 0) { err("error fcntl on read pipe: %s", strerror(errno)); @@ -865,7 +849,6 @@ int main(int argc, char *argv[], char *envp[]) retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); if (retval < 0) err("error fcntl on read pipe: %s", strerror(errno)); - retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); if (retval < 0) { err("error fcntl on write pipe: %s", strerror(errno)); @@ -886,10 +869,6 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGCHLD, &act, NULL); sigaction(SIGHUP, &act, NULL); - if (init_uevent_netlink_sock() < 0) { - dbg("uevent socket not available"); - } - if (init_udevd_socket() < 0) { if (errno == EADDRINUSE) dbg("another udevd running, exit"); @@ -899,6 +878,9 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + if (init_uevent_netlink_sock() < 0) + info("uevent socket not available"); + /* override of forked udev binary, used for testing */ udev_bin = getenv("UDEV_BIN"); if (udev_bin != NULL) @@ -937,26 +919,29 @@ int main(int argc, char *argv[], char *envp[]) max_childs_running = UDEVD_MAX_CHILDS_RUNNING; info("initialize max_childs_running to %u", max_childs_running); - FD_ZERO(&readfds); - FD_SET(udevd_sock, &readfds); - if (uevent_netlink_sock > 0) - FD_SET(uevent_netlink_sock, &readfds); - FD_SET(pipefds[0], &readfds); - maxsockplus = udevd_sock+1; + /* export log_priority , as called programs may want to follow that setting */ + sprintf(log, "UDEV_LOG=%i", udev_log_priority); + putenv(log); + while (!udev_exit) { struct uevent_msg *msg; + int fdcount; - fd_set workreadfds = readfds; - retval = select(maxsockplus, &workreadfds, NULL, NULL, NULL); + FD_ZERO(&readfds); + FD_SET(pipefds[0], &readfds); + FD_SET(udevd_sock, &readfds); + if (uevent_netlink_sock > 0) + FD_SET(uevent_netlink_sock, &readfds); - if (retval < 0) { + fdcount = select(UDEV_MAX(udevd_sock, uevent_netlink_sock)+1, &readfds, NULL, NULL, NULL); + if (fdcount < 0) { if (errno != EINTR) dbg("error in select: %s", strerror(errno)); continue; } /* get user socket message */ - if (FD_ISSET(udevd_sock, &workreadfds)) { + if (FD_ISSET(udevd_sock, &readfds)) { msg = get_udevd_msg(); if (msg) { /* discard kernel messages if netlink is active */ @@ -970,7 +955,7 @@ int main(int argc, char *argv[], char *envp[]) } /* get kernel netlink message */ - if (FD_ISSET(uevent_netlink_sock, &workreadfds)) { + if ((uevent_netlink_sock > 0) && FD_ISSET(uevent_netlink_sock, &readfds)) { msg = get_netlink_msg(); if (msg) { msg_queue_insert(msg); @@ -983,8 +968,17 @@ int main(int argc, char *argv[], char *envp[]) } /* received a signal, clear our notification pipe */ - if (FD_ISSET(pipefds[0], &workreadfds)) - user_sighandler(); + if (FD_ISSET(pipefds[0], &readfds)) { + int sig; + ssize_t rlen; + + while(1) { + rlen = read(pipefds[0], &sig, sizeof(sig)); + if (rlen <= 0) + break; + } + sig_flag = 0; + } /* forked child have returned */ if (sigchilds_waiting) { @@ -1018,7 +1012,6 @@ exit: if (udevd_sock > 0) close(udevd_sock); - if (uevent_netlink_sock > 0) close(uevent_netlink_sock); diff --git a/udeveventrecorder.c b/udeveventrecorder.c index 711f467307..9a3c3e197c 100644 --- a/udeveventrecorder.c +++ b/udeveventrecorder.c @@ -63,7 +63,7 @@ int main(int argc, char **argv, char **envp) const char *env; if (stat("/events", &sb) || !(S_ISDIR(sb.st_mode))) - return 1; + return 0; env = getenv("UDEV_LOG"); if (env) diff --git a/udevmonitor.c b/udevmonitor.c index 2efb705b6d..c1538883c9 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -105,7 +105,7 @@ int main(int argc, char *argv[]) int env = 0; fd_set readfds; int i; - int retval; + int retval = 0; for (i = 1 ; i < argc; i++) { char *arg = argv[i]; @@ -128,34 +128,34 @@ int main(int argc, char *argv[]) exit(1); } + retval = init_udev_monitor_socket(); + if (retval) + goto out; init_uevent_netlink_sock(); - init_udev_monitor_socket(); printf("udevmonitor prints received from the kernel [UEVENT] and after\n" "the udev processing, the event which udev [UDEV] has generated\n\n"); - 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); - while (1) { static char buf[UEVENT_BUFFER_SIZE*2]; ssize_t buflen; - fd_set workreadfds; + int fdcount; buflen = 0; - workreadfds = readfds; + 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); - retval = select(UDEV_MAX(uevent_netlink_sock, udev_monitor_sock)+1, &workreadfds, NULL, NULL, NULL); - if (retval < 0) { + 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\n"); continue; } - if ((uevent_netlink_sock > 0) && FD_ISSET(uevent_netlink_sock, &workreadfds)) { + 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\n"); @@ -164,7 +164,7 @@ int main(int argc, char *argv[]) printf("UEVENT[%i] %s\n", time(NULL), buf); } - if ((udev_monitor_sock > 0) && FD_ISSET(udev_monitor_sock, &workreadfds)) { + 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\n"); @@ -198,9 +198,11 @@ int main(int argc, char *argv[]) } } +out: if (uevent_netlink_sock > 0) close(uevent_netlink_sock); if (udev_monitor_sock > 0) close(udev_monitor_sock); - exit(1); + + return retval; } diff --git a/udevstart.c b/udevstart.c index 3a715a609f..ce96f38879 100644 --- a/udevstart.c +++ b/udevstart.c @@ -167,7 +167,7 @@ run: if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) pass_env_to_socket(&name_loop->name[strlen("socket:")], devpath, "add"); else - run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_DEBUG)); + run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); } } exit: From beb9f9ccb83b2c6f367b34e28ed6841141a42d48 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 15 Aug 2005 12:00:43 +0200 Subject: [PATCH 1449/4284] move udevmonitor to /usr/sbin Signed-off-by: Kay Sievers --- Makefile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index dcfac9cf9d..e9544f4510 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,7 @@ exec_prefix = ${prefix} etcdir = ${prefix}/etc sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev srcdir = . @@ -383,7 +384,7 @@ install: install-config install-man all $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) $(INSTALL_PROGRAM) -D $(CONTROL) $(DESTDIR)$(sbindir)/$(CONTROL) - $(INSTALL_PROGRAM) -D $(MONITOR) $(DESTDIR)$(sbindir)/$(MONITOR) + $(INSTALL_PROGRAM) -D $(MONITOR) $(DESTDIR)$(usrsbindir)/$(MONITOR) $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) @@ -409,8 +410,8 @@ uninstall: uninstall-man - rm $(sbindir)/$(INITSENDER) - rm $(sbindir)/$(RECORDER) - rm $(sbindir)/$(CONTROL) - - rm $(sbindir)/$(MONITOR) - rm $(sbindir)/$(STARTER) + - rm $(usrsbindir)/$(MONITOR) - rm $(usrbindir)/$(INFO) - rm $(usrbindir)/$(TESTER) - rm -rf $(udevdb) From 5618b5611bccf64a1e22f8cbcebe8ecba9713c9c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 16 Aug 2005 04:25:20 +0200 Subject: [PATCH 1450/4284] ENV{TEST}=="1" compares and ENV{TEST}="1" sets the environment This can be uses to export stuff to the event environment or to carry a state from one rule to another, like enabling/disabling later rules conditionally. Signed-off-by: Kay Sievers --- test/udev-test.pl | 25 +++++++++++++++ udev_rules.c | 81 ++++++++++++++++++++++++++--------------------- 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index 94cffeab07..c32cfe7eeb 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1291,6 +1291,31 @@ BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="go", NAME="wrong" BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="yes", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sdax1", NAME="no" BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="test", ENV{ACTION}=="add", ENV{DEVPATH}=="/block/sda/sda1", NAME="true" BUS=="scsi", KERNEL=="sda1", ENV{ENV_KEY_TEST}=="bad", NAME="bad" +EOF + }, + { + desc => "ENV{} test (assign)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "true", + rules => < "ENV{} test (assign2)", + subsys => "block", + devpath => "/block/sda/sda1", + exp_name => "part", + rules => <action, udev->action)) goto exit; @@ -691,23 +692,21 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, goto exit; } - if (rule->env.count) { - int i; + for (i = 0; i < rule->env.count; i++) { + struct key_pair *pair = &rule->env.keys[i]; - dbg("check %i ENV keys", rule->env.count); - 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_ASSIGN) { const char *key_name = key_pair_name(rule, pair); const char *value = getenv(key_name); if (!value) { - dbg("ENV{'%s'} is not set", key_name); + dbg("ENV{'%s'} is not set, treat as empty", key_name); value = ""; } if (match_key("ENV", rule, &pair->key, value)) goto exit; } - dbg("all %i ENV keys matched", rule->env.count); } if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) { @@ -760,8 +759,6 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, /* check for matching sysfs pairs */ if (rule->sysfs.count) { - int i; - dbg("check %i SYSFS keys", rule->sysfs.count); for (i = 0; i < rule->sysfs.count; i++) { struct key_pair *pair = &rule->sysfs.keys[i]; @@ -799,32 +796,6 @@ try_parent: dbg("look at sysfs_device->bus_id='%s'", parent_device->bus_id); } - /* import variables from 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)); - apply_format(udev, import, sizeof(import), class_dev, sysfs_device); - 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 && class_dev) { - dbg("import parent import='%s'", import); - rc = import_parent_into_env(udev, class_dev, import); - } - if (rc) { - dbg("IMPORT failed"); - if (rule->import.operation != KEY_OP_NOMATCH) - goto exit; - } else - dbg("IMPORT '%s' imported", key_val(rule, &rule->import)); - dbg("IMPORT key is true"); - } - /* execute external program */ if (rule->program.operation != KEY_OP_UNSET) { char program[PATH_SIZE]; @@ -854,7 +825,45 @@ try_parent: if (match_key("RESULT", rule, &rule->result, udev->program_result)) goto exit; - /* rule matches */ + /* 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)); + apply_format(udev, import, sizeof(import), class_dev, sysfs_device); + 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 && class_dev) { + dbg("import parent import='%s'", import); + rc = import_parent_into_env(udev, class_dev, import); + } + if (rc) { + dbg("IMPORT failed"); + if (rule->import.operation != KEY_OP_NOMATCH) + goto exit; + } 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) { + const char *key_name = key_pair_name(rule, pair); + const char *value = key_val(rule, &pair->key); + + setenv(key_name, value, 1); + dbg("export ENV '%s=%s'", key_name, value); + } + } + return 0; exit: From f7a144a5be4af01c8bce13632c9a46b2653e3398 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 17 Aug 2005 16:58:19 +0200 Subject: [PATCH 1451/4284] vol_id: fix sloppy error handling vol_id segfaults if read() fails on broken devices reporting the wrong size. Thanks to Erhard Schultchen for the debugging. Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/util.c | 29 +++++++++++++++++++++----- extras/volume_id/volume_id/volume_id.h | 2 +- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index 868d67306c..62b96a3657 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -204,19 +204,30 @@ uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) if (off + len <= SB_BUFFER_SIZE) { if (id->sbbuf == NULL) { id->sbbuf = malloc(SB_BUFFER_SIZE); - if (id->sbbuf == NULL) + if (id->sbbuf == NULL) { + dbg("error malloc"); return NULL; + } } /* check if we need to read */ if ((off + len) > id->sbbuf_len) { dbg("read sbbuf len:0x%llx", (unsigned long long) (off + len)); - lseek(id->fd, 0, SEEK_SET); + 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 (buf_len < off + len) + if (buf_len < off + len) { + dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); return NULL; + } } return &(id->sbbuf[off]); @@ -229,16 +240,24 @@ uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) /* get seek buffer */ if (id->seekbuf == NULL) { id->seekbuf = malloc(SEEK_BUFFER_SIZE); - if (id->seekbuf == NULL) + 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))) { dbg("read seekbuf off:0x%llx len:0x%zx", (unsigned long long) off, len); - if (lseek(id->fd, off, SEEK_SET) == -1) + 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; diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index a82b221028..84f8fb6740 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -23,7 +23,7 @@ #include -#define VOLUME_ID_VERSION 47 +#define VOLUME_ID_VERSION 48 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From fc046d4d08f686bcdb91c015b5b35c35e2c205a0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 17 Aug 2005 16:09:03 -0700 Subject: [PATCH 1452/4284] Always open the cdrom drive in non-blocking mode in cdrom_id Signed-off-by: Greg Kroah-Hartman --- extras/cdrom_id/cdrom_id.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index 3d62781186..c561112d30 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -112,10 +112,7 @@ int main(int argc, char *argv[]) goto exit; } - fd = open(node, O_RDONLY); - if (fd < 0) - if (errno == ENOMEDIUM) - fd = open(node, O_RDONLY|O_NONBLOCK); + fd = open(node, O_RDONLY|O_NONBLOCK); if (fd < 0) { err("unable to open '%s'", node); rc = 1; From a961dcbf0dabc91c0c6f9fde6195fe8209574d48 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 17 Aug 2005 16:10:32 -0700 Subject: [PATCH 1453/4284] cdrom_id: change err() to info() to help with debugging problems Signed-off-by: Greg Kroah-Hartman --- extras/cdrom_id/cdrom_id.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index c561112d30..941a2facfe 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -107,21 +107,21 @@ int main(int argc, char *argv[]) node = arg; } if (!node) { - err("no node specified"); + info("no node specified"); rc = 1; goto exit; } fd = open(node, O_RDONLY|O_NONBLOCK); if (fd < 0) { - err("unable to open '%s'", node); + info("unable to open '%s'", node); rc = 1; goto exit; } result = ioctl(fd, CDROM_GET_CAPABILITY, NULL); if (result < 0) { - err("CDROM_GET_CABILITY failed for '%s'", node); + info("CDROM_GET_CABILITY failed for '%s'", node); rc = 3; goto close; } From e331c54dc58a8228018e1a29e84eff76cd9f8fe1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Aug 2005 04:54:59 +0200 Subject: [PATCH 1454/4284] fix typo in cdrom_id syslog Signed-off-by: Kay Sievers --- extras/cdrom_id/cdrom_id.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index 941a2facfe..091bf91559 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -121,7 +121,7 @@ int main(int argc, char *argv[]) result = ioctl(fd, CDROM_GET_CAPABILITY, NULL); if (result < 0) { - info("CDROM_GET_CABILITY failed for '%s'", node); + info("CDROM_GET_CAPABILITY failed for '%s'", node); rc = 3; goto close; } @@ -147,8 +147,6 @@ int main(int argc, char *argv[]) if (result & CDC_RAM) printf("ID_CDROM_RAM=1\n"); - goto close; - close: close(fd); exit: From 3f9f8de4de49135476644297585bd910b14d0ea7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Aug 2005 13:07:15 +0200 Subject: [PATCH 1455/4284] bring std(in|out|err) fd's in a sane state If the kernel forks us as an usermodhelper, we don't have any of the standard fd's and the first open() will start with fd=0. This is inherited to all forked childs and confuses later forked helpers where we want to read from a pipe connected to the helpers stdout/stderr. # ls -l /proc/$(pidof udevd)/fd total 6 dr-x------ 2 root root 0 2005-08-18 12:44 . dr-xr-xr-x 4 root root 0 2005-08-18 12:44 .. lrwx------ 1 root root 64 2005-08-18 12:44 0 -> /dev/null lrwx------ 1 root root 64 2005-08-18 12:44 1 -> socket:[1274617] lr-x------ 1 root root 64 2005-08-18 12:44 2 -> pipe:[1274618] l-wx------ 1 root root 64 2005-08-18 12:44 3 -> pipe:[1274618] lrwx------ 1 root root 64 2005-08-18 12:44 4 -> socket:[1274619] lrwx------ 1 root root 64 2005-08-18 12:44 5 -> socket:[1274620] Ouch! This will obviously not redirect sterr, it will kill the pipe we established between the parent and the child: devnull = open("/dev/null", O_RDWR); dup2(devnull, STDERR_FILENO); Signed-off-by: Kay Sievers --- udev.c | 16 ++++++++++++++++ udevd.c | 26 ++++++++++++++++---------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/udev.c b/udev.c index beaa191c04..926c4b526a 100644 --- a/udev.c +++ b/udev.c @@ -72,6 +72,7 @@ int main(int argc, char *argv[], char *envp[]) const char *devpath; const char *subsystem; struct sigaction act; + int devnull; int retval = -EINVAL; if (argc == 2 && strcmp(argv[1], "-V") == 0) { @@ -79,7 +80,22 @@ int main(int argc, char *argv[], char *envp[]) exit(0); } + /* set std fd's to /dev/null, if the kernel 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("fatal, could not open /dev/null"); udev_init_config(); dbg("version %s", UDEV_VERSION); diff --git a/udevd.c b/udevd.c index 79d3e82550..ffd2b1ff3b 100644 --- a/udevd.c +++ b/udevd.c @@ -777,7 +777,23 @@ int main(int argc, char *argv[], char *envp[]) int daemonize = 0; int i; + /* set std fd's to /dev/null, if the kernel 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("udevd"); + if (devnull < 0) + err("fatal, could not open /dev/null"); + udev_init_config(); dbg("version %s", UDEV_VERSION); @@ -825,16 +841,6 @@ int main(int argc, char *argv[], char *envp[]) /* set a reasonable scheduling priority for the daemon */ setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); - /* Set fds to dev/null */ - devnull = open( "/dev/null", O_RDWR ); - if (devnull > 0) { - dup2(devnull, STDIN_FILENO); - dup2(devnull, STDOUT_FILENO); - dup2(devnull, STDERR_FILENO); - close(devnull); - } else - err("error opening /dev/null %s", strerror(errno)); - /* setup signal handler pipe */ retval = pipe(pipefds); if (retval < 0) { From 24a12dcbb81e364723cee065d7471b4d03a9db86 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 18 Aug 2005 13:43:27 +0200 Subject: [PATCH 1456/4284] fix printed udevmonitor header Signed-off-by: Kay Sievers --- RELEASE-NOTES | 13 +++++++++++++ udevmonitor.c | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 91cef0ccd4..ee992d1e60 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,16 @@ +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, cause /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 diff --git a/udevmonitor.c b/udevmonitor.c index c1538883c9..2775b295ce 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -133,8 +133,8 @@ int main(int argc, char *argv[]) goto out; init_uevent_netlink_sock(); - printf("udevmonitor prints received from the kernel [UEVENT] and after\n" - "the udev processing, the event which udev [UDEV] has generated\n\n"); + printf("udevmonitor prints the received event from the kernel [UEVENT]\n" + "and the event which udev sends out after rule processing [UDEV]\n\n"); while (1) { static char buf[UEVENT_BUFFER_SIZE*2]; From da4aec2fb4e3c9f1f73a67a5e326c90220fb0c59 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 18 Aug 2005 10:02:27 -0700 Subject: [PATCH 1457/4284] add EXTRAS documentation to the README file. Signed-off-by: Greg Kroah-Hartman --- README | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README b/README index 5dc1e46c89..9891c696d3 100644 --- a/README +++ b/README @@ -60,11 +60,18 @@ To use: This is used if USE_KLIBC=true to find the kernel include directory that klibc needs to build against. This must be set if you are not building udev while running a 2.6 kernel. + EXTRAS + if set, will build the "extra" helper programs as specified + as listed (see below for an example.) So, if you want to build udev using klibc with debugging messages, you would do: make USE_KLIBC=true DEBUG=true + If you want to build the udev helper program cdrom_id and scsi_id you + would do: + make EXTRAS="extras/cdrom_id extras/scsi_id" + udev will follow the setting of the debug level in udev.conf. Adapt this value to see the debug in syslog. From 8c11a2f0ff27264513033691bb818262f009fe4e Mon Sep 17 00:00:00 2001 From: Greg KH Date: Thu, 18 Aug 2005 10:04:49 -0700 Subject: [PATCH 1458/4284] 068 release --- ChangeLog | 18 ++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index f1cf451c44..b18208e245 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +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 ============================================ diff --git a/Makefile b/Makefile index e9544f4510..1c1280a7dc 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 067 +VERSION = 068 ROOT = udev DAEMON = udevd SENDER = udevsend diff --git a/udev.spec b/udev.spec index d64d32c535..25bc2d7f2c 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace device manager providing devfs functionality Name: udev -Version: 066 +Version: 068 Release: 1 License: GPL Group: Utilities/System From c907c823c388dfbdfa7054cfb2f4e9b92eb31e2e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 22 Aug 2005 11:37:12 +0200 Subject: [PATCH 1459/4284] *_id: fix zero length in set_str() Thanks to Olaf Hering Signed-off-by: Kay Sievers --- extras/ata_id/ata_id.c | 2 +- extras/scsi_id/scsi_id.c | 2 +- extras/usb_id/usb_id.c | 2 +- extras/volume_id/vol_id.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index 2840e91457..9579db3105 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -68,7 +68,7 @@ static void set_str(char *to, const char *from, size_t count) /* strip trailing whitespace */ len = strnlen(from, count); - while (isspace(from[len-1])) + while (len && isspace(from[len-1])) len--; /* strip leading whitespace */ diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index a46d1b377d..a86b004709 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -107,7 +107,7 @@ static void set_str(char *to, const char *from, size_t count) /* strip trailing whitespace */ len = strnlen(from, count); - while (isspace(from[len-1])) + while (len && isspace(from[len-1])) len--; /* strip leading whitespace */ diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index f5ee795924..c4ce0c6103 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -82,7 +82,7 @@ static void set_str(char *to, const char *from, size_t count) /* strip trailing whitespace */ len = strnlen(from, count); - while (isspace(from[len-1])) + while (len && isspace(from[len-1])) len--; /* strip leading whitespace */ diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 6a9d1120e0..fe0b3a0ed0 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -66,7 +66,7 @@ static void set_str(char *to, const char *from, size_t count) /* strip trailing whitespace */ len = strnlen(from, count); - while (isspace(from[len-1])) + while (len && isspace(from[len-1])) len--; /* strip leading whitespace */ From 66691c6e6c22820f645e3e1e104a9b5178031d3b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 22 Aug 2005 11:42:58 +0200 Subject: [PATCH 1460/4284] add program name to logged error Signed-off-by: Kay Sievers --- udev_utils_run.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev_utils_run.c b/udev_utils_run.c index 0ee36d6848..fb37a05830 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -153,7 +153,7 @@ int run_program(const char *command, const char *subsystem, execv(argv[0], argv); /* we should never reach this */ - err("exec of program failed"); + err("exec of program '%s' failed", argv[0]); _exit(1); case -1: err("fork of '%s' failed", argv[0]); From 9bbcdb56d8221e2e839a2cf03fc071952fe7bc3c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 22 Aug 2005 12:01:55 +0200 Subject: [PATCH 1461/4284] fix exit code of udevinitsend and udevmonitor Thanks to: Marco d'Itri for the initial patch. Signed-off-by: Kay Sievers --- udevinitsend.c | 12 +++++++----- udevmonitor.c | 11 ++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/udevinitsend.c b/udevinitsend.c index 5abf3d4bd3..ea05734a00 100644 --- a/udevinitsend.c +++ b/udevinitsend.c @@ -128,7 +128,6 @@ static int udevsend(char *filename, int sock, int disable_loop_detection) } if (ch < le) { - strncpy(&usend_msg.envbuf[bufpos],ls,(ch - ls) + 1); bufpos += (ch - ls) + 1; if (ch[1] == '\'' && le[-1] == '\'') { @@ -153,9 +152,10 @@ loop_end: retval = sendto(sock, &usend_msg, usend_msg_len, 0, (struct sockaddr *)&saddr, addrlen); if (retval < 0) { dbg("error sending message (%s)", strerror(errno)); + retval = -1; } } - + return retval; } @@ -167,7 +167,7 @@ int main(int argc, char *argv[], char *envp[]) char *event_file = NULL; DIR *dirstream; struct dirent *direntry; - int retval = 1; + int retval = 0; int disable_loop_detection = 0; int sock; const char *env; @@ -218,7 +218,7 @@ int main(int argc, char *argv[], char *envp[]) if (!dirstream) { info("error opening directory %s: %s\n", event_dir, strerror(errno)); - return 1; + return 2; } chdir(event_dir); while ((direntry = readdir(dirstream)) != NULL) { @@ -235,5 +235,7 @@ int main(int argc, char *argv[], char *envp[]) if (sock != -1) close(sock); - return retval; + if (retval) + return 3; + return 0; } diff --git a/udevmonitor.c b/udevmonitor.c index 2775b295ce..9fe6da906f 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -63,6 +63,7 @@ static int init_udev_monitor_socket(void) if (retval < 0) { fprintf(stderr, "bind failed, %s\n", strerror(errno)); close(udev_monitor_sock); + udev_monitor_sock = -1; return -1; } @@ -125,13 +126,15 @@ int main(int argc, char *argv[]) if (getuid() != 0) { fprintf(stderr, "need to be root, exit\n\n"); - exit(1); + exit(2); } retval = init_udev_monitor_socket(); if (retval) goto out; - init_uevent_netlink_sock(); + retval = init_uevent_netlink_sock(); + if (retval) + goto out; printf("udevmonitor prints the received event from the kernel [UEVENT]\n" "and the event which udev sends out after rule processing [UDEV]\n\n"); @@ -204,5 +207,7 @@ out: if (udev_monitor_sock > 0) close(udev_monitor_sock); - return retval; + if (retval) + return 3; + return 0; } From e7f247503c63764e4ffb255acb3e99faf91f2214 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 23 Aug 2005 00:57:46 +0200 Subject: [PATCH 1462/4284] udevd: keep the right order for messages without SEQNUM Signed-off-by: Kay Sievers --- udevd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevd.c b/udevd.c index ffd2b1ff3b..e4880c9814 100644 --- a/udevd.c +++ b/udevd.c @@ -113,7 +113,7 @@ static void msg_queue_insert(struct uevent_msg *msg) if (msg->seqnum == 0) { dbg("no SEQNUM, move straight to the exec queue"); - list_add(&msg->node, &exec_list); + list_add_tail(&msg->node, &exec_list); run_exec_q = 1; return; } From 8d77c6a383ed1b308ce73e97b9f02f767b012921 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 25 Aug 2005 00:37:46 +0200 Subject: [PATCH 1463/4284] volume_id: don't probe for mac_partition_maps Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/volume_id.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index e7d4d75666..32b91e65ca 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -118,9 +118,6 @@ int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) if (volume_id_probe_vfat(id, off) == 0) goto exit; - if (volume_id_probe_mac_partition_map(id, off) == 0) - goto exit; - if (volume_id_probe_xfs(id, off) == 0) goto exit; From 9ae611be33c29d5d9b51bca281408d407dcf007f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 25 Aug 2005 00:38:25 +0200 Subject: [PATCH 1464/4284] udevmonitor: cleanup on exit We want to write the output buffer before we exit, otherwise redirection to a file does not work correctly. Signed-off-by: Kay Sievers --- udevmonitor.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/udevmonitor.c b/udevmonitor.c index 9fe6da906f..33dff2a13c 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ static int uevent_netlink_sock; static int udev_monitor_sock; +static volatile int udev_exit; static int init_udev_monitor_socket(void) { @@ -101,8 +103,15 @@ static int init_uevent_netlink_sock(void) return 0; } +static void asmlinkage sig_handler(int signum) +{ + if (signum == SIGINT || signum == SIGTERM) + udev_exit = 1; +} + int main(int argc, char *argv[]) { + struct sigaction act; int env = 0; fd_set readfds; int i; @@ -129,6 +138,14 @@ int main(int argc, char *argv[]) exit(2); } + /* 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); + retval = init_udev_monitor_socket(); if (retval) goto out; @@ -139,7 +156,7 @@ int main(int argc, char *argv[]) printf("udevmonitor prints the received event from the kernel [UEVENT]\n" "and the event which udev sends out after rule processing [UDEV]\n\n"); - while (1) { + while (!udev_exit) { static char buf[UEVENT_BUFFER_SIZE*2]; ssize_t buflen; int fdcount; From 440103fcfc99626c4705f879b63ad710de0209de Mon Sep 17 00:00:00 2001 From: Amir Shalem Date: Thu, 25 Aug 2005 00:39:45 +0200 Subject: [PATCH 1465/4284] fix typo in firmware_helper The wrong string is being nullifed. --- extras/firmware/firmware_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/firmware/firmware_helper.c b/extras/firmware/firmware_helper.c index 283ea9f76f..7b7a307298 100644 --- a/extras/firmware/firmware_helper.c +++ b/extras/firmware/firmware_helper.c @@ -109,7 +109,7 @@ int main(int argc, char **argv) { } snprintf(data_path, sizeof(data_path), "/sys/%s/data", devpath); - fw_path[sizeof(data_path)-1] = '\0'; + data_path[sizeof(data_path)-1] = '\0'; fw_fd = open(data_path, O_RDWR); if (fw_fd < 0) { rc = errno; From cf7cad9dc90c15ac13baeae85db5e0e25b59ed0e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 25 Aug 2005 00:40:41 +0200 Subject: [PATCH 1466/4284] path_id: remove SUSE specific PATH Signed-off-by: Kay Sievers --- extras/path_id | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/extras/path_id b/extras/path_id index 8391f2e586..c7f50687fe 100755 --- a/extras/path_id +++ b/extras/path_id @@ -1,13 +1,12 @@ #!/bin/sh -#set -x -# this script should provide the shortest possible unique hardware path -# to a block device +# provide the shortest possible unique hardware path to a block device +# for the udev persistent disk device naming scheme # - -# Horrible script. Handle with extreme care. - -# to be called from udev +# Copyright (C) 2005 SUSE Linux Products GmbH +# Licensed under the GPL v2. +# +# to be called from a udev rule to return the name for a symlink # DEVPATH=/block/sda/sda3 $0 (or similar) # $0 /block/sda # $0 /sys/block/sda @@ -55,9 +54,7 @@ # then firewire sbp2 # then the rest -PATH=/lib/klibc/bin #/usr:/usr/sbin:/usr/bin:/sbin:/bin SYSFS=/sys -export PATH RESULT=1 CDROM= TYPE= From 879d1946735e17c84984de9c090b5a3f4293046e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 25 Aug 2005 02:30:01 +0200 Subject: [PATCH 1467/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/isdn.rules | 54 ++++++++++++++++++++++++++++++++++++++ etc/udev/suse/pcmcia.rules | 5 ++++ etc/udev/suse/udev.rules | 42 +++++++---------------------- 3 files changed, 68 insertions(+), 33 deletions(-) create mode 100644 etc/udev/suse/isdn.rules create mode 100644 etc/udev/suse/pcmcia.rules diff --git a/etc/udev/suse/isdn.rules b/etc/udev/suse/isdn.rules new file mode 100644 index 0000000000..29f993adab --- /dev/null +++ b/etc/udev/suse/isdn.rules @@ -0,0 +1,54 @@ +# +# Very important !!! +# These rules must be processed befor 50-pcmcia and 50-udev +# if not here 'll be a endless loop !!! +# +# CAPI devices +SUBSYSTEM="capi", GROUP="dialout" +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" +KERNEL=="capi*", NAME="capi/%n" + +# ISDN +KERNEL=="isdn*", NAME="%k", MODE="600" +KERNEL=="isdnctrl*", NAME="%k", MODE="600" +KERNEL=="ippp*", NAME="%k", MODE="600" +KERNEL=="isdninfo*", NAME="%k", MODE="444" +# USB +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/c00*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/1000*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/1900*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2000*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2200*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2300*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2800*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3000*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3500*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3600*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2805*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2806*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/4401*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/4601*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="483/4810*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="959/2bd0*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" +SUBSYSTEM=="usb", ENV{PRODUCT}=="9bf/*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" + +# ISDN PCMCIA +# AVM B1 models +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb845DC335pc*pd*", RUN+="/sbin/udev.isdn.sh b1 1", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb81E10430pc*pd*", RUN+="/sbin/udev.isdn.sh b1 2", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb18E8558Apc*pd*", RUN+="/sbin/udev.isdn.sh b1 3", GOTO="after_pcmcia" +# AVM A1 models (aka Fritz!Card PCMCIA) +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pbADC9D4BBpc*pd*", RUN+="/sbin/udev.isdn.sh a1 1", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa8D9761C8pb01C5AA7Bpc*pd*", RUN+="/sbin/udev.isdn.sh a1 2", GOTO="after_pcmcia" +# teles +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa67B50EAEpbE9E70119pc*pd*", RUN+="/sbin/udev.isdn.sh teles 1", GOTO="after_pcmcia" +# sedlbauer +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbF3612E1Dpc6B95C78Apd*", RUN+="/sbin/udev.isdn.sh sedlbauer 1", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc397B7E90pd*", RUN+="/sbin/udev.isdn.sh sedlbauer 2", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc2E5C7FCEpd*", RUN+="/sbin/udev.isdn.sh sedlbauer 3", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc8DB143FEpd*", RUN+="/sbin/udev.isdn.sh sedlbauer 4", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pcB391AB4Cpd*", RUN+="/sbin/udev.isdn.sh sedlbauer 5", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*paD79E0B84pb21D083AEpc*pd*", RUN+="/sbin/udev.isdn.sh sedlbauer 6", GOTO="after_pcmcia" +# elsa +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa983DE2C4pb333BA257pc*pd*", RUN+="/sbin/udev.isdn.sh elsa 1", GOTO="after_pcmcia" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa639E5718pb333BA257pc*pd*", RUN+="/sbin/udev.isdn.sh elsa 2", GOTO="after_pcmcia" diff --git a/etc/udev/suse/pcmcia.rules b/etc/udev/suse/pcmcia.rules new file mode 100644 index 0000000000..11ccde56e7 --- /dev/null +++ b/etc/udev/suse/pcmcia.rules @@ -0,0 +1,5 @@ +SUBSYSTEM=="pcmcia_socket", ACTION=="add", RUN+="/sbin/hwup pcmcia_socket-devpath-%p -o hotplug" +SUBSYSTEM=="pcmcia", ACTION=="add", RUN+="/sbin/hwup pcmcia-devpath-%p -o hotplug" + +LABEL="after_pcmcia" + diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/udev.rules index 683a22a2bb..8ffd645257 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/udev.rules @@ -27,8 +27,11 @@ KERNEL=="winradio*", NAME="%k", GROUP="video" KERNEL=="vttuner*", NAME="%k", GROUP="video" KERNEL=="nvidia*", NAME="%k", GROUP="video" KERNEL=="nvidiactl*", NAME="%k", GROUP="video" +KERNEL=="video0", SYMLINK+="video" +KERNEL=="radi0", SYMLINK+="radio" # dvb +#SUBSYSTEM="dvb", PROGRAM="/bin/sh -c 'X=%k X=$${X#dvb} A=$${X%%%%.*} D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" KERNEL=="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video" # ALSA/sound @@ -60,34 +63,6 @@ SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="76b/1784*", RUN+="/usr/sbin/open SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="8d4/9*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" SUBSYSTEM=="usb", ACTION=="add", ENV{INTERFACE}=="11/*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -# CAPI devices -SUBSYSTEM="capi", GROUP="dialout" -KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" -KERNEL=="capi*", NAME="capi/%n" - -# ISDN -KERNEL=="isdn*", NAME="%k", MODE="600" -KERNEL=="isdnctrl*", NAME="%k", MODE="600" -KERNEL=="ippp*", NAME="%k", MODE="600" -KERNEL=="isdninfo*", NAME="%k", MODE="444" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/c00*", IMPORT="/bin/echo 'DRV=fcusb'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/1000*", IMPORT="/bin/echo -e 'DRV=fcusb2\nFIRMWARE=fus2base.frm'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/1900*", IMPORT="/bin/echo -e 'DRV=fcusb2\nFIRMWARE=fus3base.frm'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2000*", IMPORT="/bin/echo DRV=fxusb", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2200*", IMPORT="/bin/echo DRV=bfusb", RUN+="/etc/sysconfig/isdn/scripts/load-bfusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2300*", IMPORT="/bin/echo -e 'DRV=fcdslusb\nFIRMWARE=fdsubase.frm\nDSL_CONTR=dslisdn'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2800*", IMPORT="/bin/echo DRV=fxusb_CZ", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/3000*", IMPORT="/bin/echo -e 'DRV=fcdslusba\nFIRMWARE=fdsabase.frm\nDSL_CONTR=dslonly\nISDNLOG_START=no'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/3500*", IMPORT="/bin/echo -e 'DRV=fcdslslusb\nFIRMWARE=fdlubase.frm\nDSL_CONTR=dslonly\nISDNLOG_START=no'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/3600*", IMPORT="/bin/echo -e 'DRV=fcdslusb2\nFIRMWARE=fds2base.frm\nDSL_CONTR=dslisdn'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2805*", IMPORT="/bin/echo 'DRV=e2220pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/2806*", IMPORT="/bin/echo 'DRV=e5520pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/4401*", IMPORT="/bin/echo 'DRV=e2220pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="57c/4601*", IMPORT="/bin/echo 'DRV=e5520pc'", RUN+="/etc/sysconfig/isdn/scripts/load-avmusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="483/4810*", IMPORT="/bin/echo 'DRV=hisax_st5481'", RUN+="/etc/sysconfig/isdn/scripts/load-hisaxusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="959/2bd0*", IMPORT="/bin/echo 'DRV=hfc_usb'", RUN+="/etc/sysconfig/isdn/scripts/load-hisaxusb" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="9bf/*", IMPORT="/bin/echo 'DRV=auerswald'", RUN+="/etc/sysconfig/isdn/scripts/load-auerswald" - # input devices KERNEL=="mice", NAME="input/%k", MODE="0640" KERNEL=="mouse*", NAME="input/%k", MODE="0640" @@ -127,7 +102,7 @@ KERNEL=="sxctl", NAME="specialix_sxctl", SYMLINK+="%k" KERNEL=="mem", NAME="%k", GROUP="kmem", MODE="640" KERNEL=="kmem", NAME="%k", GROUP="kmem", MODE="640" KERNEL=="port", NAME="%k", GROUP="kmem", MODE="640" -KERNEL=="nvram", NAME="%k", GROUP="kmem" +KERNEL=="nvram", NAME="%k", GROUP="kmem", MODE="600" KERNEL=="null", NAME="%k", MODE="666" KERNEL=="zero", NAME="%k", MODE="666" KERNEL=="full", NAME="%k", MODE="622" @@ -149,9 +124,9 @@ KERNEL=="z90crypt", NAME="%k", MODE="666" KERNEL=="mmtimer", NAME="%k", MODE="444" # fix floppy devices -KERNEL=="nvram", ACTION=="add", NAME="%k", MODE="600", RUN="/sbin/load_floppy_module" -KERNEL=="fd*", ACTION=="add", SYSFS{device/cmos}=="*", RUN="/sbin/create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" -KERNEL=="fd*", ACTION=="remove", RUN="/sbin/remove_floppy_devices /dev/%k" +KERNEL=="nvram", ACTION=="add", RUN+="/sbin/load_floppy_module" +KERNEL=="fd*", ACTION=="add", SYSFS{device/cmos}=="*", RUN+="/sbin/create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" +KERNEL=="fd*", ACTION=="remove", RUN+="/sbin/remove_floppy_devices %k" # block devices SUBSYSTEM=="block", GROUP="disk", MODE="0640" @@ -236,11 +211,12 @@ DEVPATH=="/module/usbcore", ACTION=="add", RUN+="/bin/mount -t usbfs usbfs /proc 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+="/etc/hotplug.d/firmware/50-firmware.hotplug" +SUBSYSTEM=="firmware", ACTION=="add", RUN+="/sbin/firmware.hotplug.sh" # SUSE system integration SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-/sys%p -o hotplug" +LABEL="after_usb_default" SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-/sys%p -o hotplug" SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-/sys%p -o hotplug" SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-/sys%p -o hotplug" From bcd9fc8f474bbe6ec0bbca139b3356ae5198441e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 25 Aug 2005 03:37:38 +0200 Subject: [PATCH 1468/4284] add pci_express to bus list Hopefully that wait_for_sysfs crap can go away some day... Signed-off-by: Kay Sievers --- udev_sysfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 90ce48caea..75e275d500 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -300,6 +300,7 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, { .bus = "usb-serial", .file = "bus" }, { .bus = "ide", .file = "bus" }, { .bus = "pci", .file = "vendor" }, + { .bus = "pci_express", .file = "bus" }, { .bus = "platform", .file = "bus" }, { .bus = "pcmcia", .file = "bus" }, { .bus = "i2c", .file = "bus" }, From 97dd82b9a7cced2568c99b500b1e31187604dcb7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 26 Aug 2005 14:27:13 +0200 Subject: [PATCH 1469/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/udev.rules | 63 +++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/udev.rules index 8ffd645257..1ed2c6cd50 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/udev.rules @@ -28,11 +28,10 @@ KERNEL=="vttuner*", NAME="%k", GROUP="video" KERNEL=="nvidia*", NAME="%k", GROUP="video" KERNEL=="nvidiactl*", NAME="%k", GROUP="video" KERNEL=="video0", SYMLINK+="video" -KERNEL=="radi0", SYMLINK+="radio" +KERNEL=="radio0", SYMLINK+="radio" # dvb -#SUBSYSTEM="dvb", PROGRAM="/bin/sh -c 'X=%k X=$${X#dvb} A=$${X%%%%.*} D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" -KERNEL=="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video" +SUBSYSTEM="dvb", PROGRAM="/bin/sh -c 'X=%k X=$${X#dvb} A=$${X%%%%.*} D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" # ALSA/sound SUBSYSTEM="sound", GROUP="audio" @@ -51,18 +50,6 @@ SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8005/*", RUN+="/sbin/startp SUBSYSTEM=="sound", KERNEL=="controlC?", RUN+="/usr/sbin/alsactl -F restore %n" SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVER=="EMU10K1_Audigy", RUN+="/etc/alsa.d/udev-soundfont" -# OpenCT (SmartCard) -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="973/1*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="529/50c*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="529/514*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="73d/5*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="4b9/1200*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="4b9/1300*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="76b/596*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="76b/1784*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="8d4/9*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" -SUBSYSTEM=="usb", ACTION=="add", ENV{INTERFACE}=="11/*", RUN+="/usr/sbin/openct-control attach $env{DEVICE} usb:$env{PRODUCT}" - # input devices KERNEL=="mice", NAME="input/%k", MODE="0640" KERNEL=="mouse*", NAME="input/%k", MODE="0640" @@ -130,9 +117,29 @@ KERNEL=="fd*", ACTION=="remove", RUN+="/sbin/remove_floppy_devices %k" # block devices SUBSYSTEM=="block", GROUP="disk", MODE="0640" -SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0", RUN+="/sbin/modprobe sd_mod" + +# SCSI types: +# sd / block values: +# 0 TYPE_DISK +# 7 TYPE_MOD +# 14 TYPE_RBC +# +# st/osst tape: +# 1 TYPE_TAPE +# +# sr cd like ones: +# 4 TYPE_WORM +# 5 TYPE_ROM +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0|7|14", RUN+="/sbin/modprobe sd_mod" +# Treat osst as a unique case, that is, osst will load more often than +# actually required, but the osst and st drivers will do the right thing. +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", SYSFS{device/vendor}=="Onstream", 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}=="[345]", RUN+="/sbin/modprobe sr_mod" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="[45]", RUN+="/sbin/modprobe sr_mod" +SUBSYSTEM=="scsi_device", ACTION=="add", RUN+="/sbin/modprobe sg" + +# IDE/ATAPI handling +SUBSYSTEM=="ide", ACTION=="add", RUN+="/sbin/udev.load_ide_modules.sh" # misc storage devices (non-block) KERNEL=="sg*", NAME="%k", GROUP="disk", MODE="640" @@ -173,15 +180,15 @@ KERNEL=="ram*|loop*|fd*", GOTO="persistent_end" SUBSYSTEM=="block", BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}="1", GOTO="persistent_end" # by-id (hardware serial number) -KERNEL=="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" +KERNEL=="hd*[!0-9]", IMPORT{program}="/sbin/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}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\n'" -KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" -KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" -KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" -KERNEL=="dasd*[!0-9]", IMPORT="/sbin/dasd_id --export $tempnode" +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}="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -s %p" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -a -s %p" +KERNEL=="dasd*[!0-9]", IMPORT{program}="/sbin/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 @@ -189,14 +196,14 @@ 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]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT{program}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" 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" KERNEL=="sr*", GOTO="persistent_end" -IMPORT="/sbin/vol_id --export $tempnode" +IMPORT{program}="/sbin/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}" LABEL="persistent_end" @@ -211,7 +218,7 @@ DEVPATH=="/module/usbcore", ACTION=="add", RUN+="/bin/mount -t usbfs usbfs /proc 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+="/sbin/firmware.hotplug.sh" +SUBSYSTEM=="firmware", ACTION=="add", RUN+="/sbin/udev.firmware.sh" # SUSE system integration SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" @@ -230,7 +237,3 @@ RUN+="socket:/org/kernel/udev/monitor" # debug events to /events, but not on default udev_log="err" ENV{UDEV_LOG}=="[4-9]", RUN+="/sbin/hotplugeventrecorder" -# for backward compatibility with older udev versions and hotplug (no longer supported) -# RUN+="/sbin/udev_run_hotplugd" -# RUN+="/sbin/udev_run_devd" - From c4ef16f92c56d2f4d8990625212fd27c805425cb Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Fri, 26 Aug 2005 14:52:57 +0200 Subject: [PATCH 1470/4284] switch to '==' in raid-devfs.sh --- extras/raid-devfs.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extras/raid-devfs.sh b/extras/raid-devfs.sh index 796232b497..ca279d45c0 100644 --- a/extras/raid-devfs.sh +++ b/extras/raid-devfs.sh @@ -4,9 +4,9 @@ # Copyright (c) 2004 Piotr Roszatycki # # Usage: -# KERNEL="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" -# KERNEL="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" -# KERNEL="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK="%k" +# KERNEL=="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" +# KERNEL=="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" +# KERNEL=="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" get_dev_number_cciss() { grep '^cciss/' /proc/driver/cciss/* | cat -n | \ From 8f847bb8455f7db8f26893b167fbf8a09cf8f41b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 26 Aug 2005 21:38:18 +0200 Subject: [PATCH 1471/4284] store ENV{key}="value" exported keys in the database Just like the IMPORT values are stored in the udev database the exported keys are stored in the udev database. The database is also imported on a remove event before the rules are matched. So it is possible to do: ACTION=="add", KERNEL=="sda", ENV{MY_DEVICE}="1234", RUN+="/bin/logger add $devpath" ACTION=="remove", ENV{MY_DEVICE}=="1234", RUN+="/bin/logger remove $devpath" Signed-off-by: Kay Sievers --- udev_event.c | 12 +++++++++--- udev_rules.c | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/udev_event.c b/udev_event.c index 3580ab937f..fae5a46597 100644 --- a/udev_event.c +++ b/udev_event.c @@ -91,15 +91,21 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) } sysfs_close_class_device(class_dev); } else if (strcmp(udev->action, "remove") == 0) { + struct name_entry *name_loop; + + /* get data from db, remove db-entry, delete node */ dbg("node remove"); + retval = udev_remove_device(udev); + + /* restore stored persistent data */ + list_for_each_entry(name_loop, &udev->env_list, node) + putenv(name_loop->name); + udev_rules_get_run(rules, udev, NULL, NULL); if (udev->ignore_device) { dbg("device event will be ignored"); return -1; } - - /* get name from db, remove db-entry, delete node */ - retval = udev_remove_device(udev); } /* export name of device node or netif */ diff --git a/udev_rules.c b/udev_rules.c index 647875d9a9..6c6aa0f091 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -859,6 +859,7 @@ try_parent: const char *key_name = key_pair_name(rule, pair); const char *value = key_val(rule, &pair->key); + name_list_key_add(&udev->env_list, key_name, value); setenv(key_name, value, 1); dbg("export ENV '%s=%s'", key_name, value); } From 3ad7a5b1a562ba71bea91ae3fba48e5b5947e285 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 26 Aug 2005 22:43:49 +0200 Subject: [PATCH 1472/4284] fix lookup for name in the udevdb, it should return the devpath Signed-off-by: Kay Sievers --- udev_db.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/udev_db.c b/udev_db.c index 632f6f7b2a..9b40a5904e 100644 --- a/udev_db.c +++ b/udev_db.c @@ -207,6 +207,8 @@ int udev_db_get_device(struct udevice *udev, const char *devpath) int udev_db_search_name(char *devpath, size_t len, const char *name) { DIR *dir; + char path[PATH_SIZE]; + int found = 0; dir = opendir(udev_db_path); if (dir == NULL) { @@ -214,10 +216,9 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) return -1; } - while (1) { + while (!found) { struct dirent *ent; char filename[PATH_SIZE]; - char path[PATH_SIZE]; char nodename[PATH_SIZE]; char *bufline; char *buf; @@ -242,7 +243,7 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) } cur = 0; - while (cur < bufsize) { + while (cur < bufsize && !found) { count = buf_get_line(buf, bufsize, cur); bufline = &buf[cur]; cur += count+1; @@ -262,11 +263,8 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) nodename[count-2] = '\0'; dbg("compare '%s' '%s'", nodename, name); if (strcmp(nodename, name) == 0) { - strlcpy(devpath, nodename, len); - devpath[count-2] = '\0'; - file_unmap(buf, bufsize); - closedir(dir); - return 0; + found = 1; + break; } break; default: @@ -277,7 +275,11 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) } closedir(dir); - return -1; + if (found) { + strlcpy(devpath, path, len); + return 0; + } else + return -1; } int udev_db_dump_names(int (*handler_function)(const char *path, const char *name)) From db481105c2cf2092e1499736d6619bf194f91711 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 27 Aug 2005 02:59:20 +0200 Subject: [PATCH 1473/4284] prepare for new HAL udevdb dump HAL soon wants to read the whole content of the udevdatabase while starting up. This makes the whole udev structure available to the udevinfo "dump". Signed-off-by: Kay Sievers --- udev_db.c | 81 +++++++++++++----------------------------------------- udev_db.h | 2 +- udevinfo.c | 21 +++++++++++--- 3 files changed, 37 insertions(+), 67 deletions(-) diff --git a/udev_db.c b/udev_db.c index 9b40a5904e..d958c6173b 100644 --- a/udev_db.c +++ b/udev_db.c @@ -39,20 +39,19 @@ #define PATH_TO_NAME_CHAR '@' -static int get_db_filename(const char *devpath, char *filename, int len) +static int get_db_filename(const char *devpath, char *filename, size_t len) { - char temp[PATH_SIZE]; - char *pos; + size_t start, end, i; + + start = strlcpy(filename, udev_db_path, len); + end = strlcat(filename, devpath, len); + if (end > len) + end = len; /* replace '/' to transform path into a filename */ - strlcpy(temp, devpath, sizeof(temp)); - pos = strchr(&temp[1], '/'); - while (pos) { - pos[0] = PATH_TO_NAME_CHAR; - pos = strchr(&pos[1], '/'); - } - snprintf(filename, len, "%s%s", udev_db_path, temp); - filename[len-1] = '\0'; + for (i = start+1; i < end; i++) + if (filename[i] == '/') + filename[i] = PATH_TO_NAME_CHAR; return 0; } @@ -197,7 +196,6 @@ int udev_db_get_device(struct udevice *udev, const char *devpath) char filename[PATH_SIZE]; get_db_filename(devpath, filename, sizeof(filename)); - if (parse_db_file(udev, filename) != 0) return -1; @@ -282,7 +280,7 @@ int udev_db_search_name(char *devpath, size_t len, const char *name) return -1; } -int udev_db_dump_names(int (*handler_function)(const char *path, const char *name)) +int udev_db_get_all_entries(struct list_head *name_list) { DIR *dir; @@ -294,14 +292,8 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam while (1) { struct dirent *ent; - char filename[PATH_SIZE]; - char path[PATH_SIZE]; - char nodename[PATH_SIZE]; - char *bufline; - char *buf; - size_t bufsize; - size_t cur; - size_t count; + char filename[PATH_SIZE] = "/"; + size_t end, i; ent = readdir(dir); if (ent == NULL || ent->d_name[0] == '\0') @@ -310,47 +302,12 @@ int udev_db_dump_names(int (*handler_function)(const char *path, const char *nam if (ent->d_name[0] == '.') continue; - snprintf(filename, sizeof(filename), "%s/%s", udev_db_path, ent->d_name); - filename[sizeof(filename)-1] = '\0'; - dbg("looking at '%s'", filename); - - if (file_map(filename, &buf, &bufsize) != 0) { - err("unable to read db file '%s'", filename); - continue; - } - - path[0] = '\0'; - nodename[0] = '\0'; - cur = 0; - while (cur < bufsize) { - count = buf_get_line(buf, bufsize, cur); - bufline = &buf[cur]; - cur += count+1; - - switch(bufline[0]) { - case 'P': - if (count > sizeof(path)) - count = sizeof(path); - memcpy(path, &bufline[2], count-2); - path[count-2] = '\0'; - break; - case 'N': - if (count > sizeof(nodename)) - count = sizeof(nodename); - memcpy(nodename, &bufline[2], count-2); - nodename[count-2] = '\0'; - break; - default: - continue; - } - } - file_unmap(buf, bufsize); - - if (path[0] == '\0' || nodename[0] == '\0') - continue; - - if (handler_function(path, nodename) != 0) - break; + end = strlcat(filename, ent->d_name, sizeof(filename)); + for (i = 1; i < end; i++) + if (filename[i] == PATH_TO_NAME_CHAR) + filename[i] = '/'; + name_list_add(name_list, filename, 1); + dbg("added '%s'", filename); } closedir(dir); diff --git a/udev_db.h b/udev_db.h index b961c87102..61ea5b47fc 100644 --- a/udev_db.h +++ b/udev_db.h @@ -28,6 +28,6 @@ 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_search_name(char *devpath, size_t len, const char *name); -extern int udev_db_dump_names(int (*handler_function)(const char *path, const char *name)); +extern int udev_db_get_all_entries(struct list_head *name_list); #endif /* _UDEV_DB_H_ */ diff --git a/udevinfo.c b/udevinfo.c index 58584d62f8..814bd1e90a 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -165,9 +165,22 @@ exit: return retval; } -static int print_dump(const char *devpath, const char *name) { - printf("%s=%s/%s\n", devpath, udev_root, name); - return 0; +static void dump_names(void) { + LIST_HEAD(name_list); + struct name_entry *name_loop; + struct name_entry *tmp_loop; + + udev_db_get_all_entries(&name_list); + list_for_each_entry_safe(name_loop, tmp_loop, &name_list, node) { + struct udevice udev_db; + + udev_init_device(&udev_db, NULL, NULL, NULL); + if (udev_db_get_device(&udev_db, name_loop->name) == 0) { + printf("%s=%s/%s\n", udev_db.devpath, udev_root, udev_db.name); + free(name_loop); + } + udev_cleanup_device(&udev_db); + } } int main(int argc, char *argv[], char *envp[]) @@ -256,7 +269,7 @@ int main(int argc, char *argv[], char *envp[]) break; case 'd': - udev_db_dump_names(print_dump); + dump_names(); goto exit; case 'V': From 64d735e652e949dae5bcaf2bd2004a2d67e627cf Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 27 Aug 2005 15:37:03 +0200 Subject: [PATCH 1474/4284] print persistent data with "udevinfo -q all" Signed-off-by: Kay Sievers --- udevinfo.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/udevinfo.c b/udevinfo.c index 814bd1e90a..11b0104581 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -88,6 +88,8 @@ static int print_record(struct udevice *udev) printf("N: %s\n", udev->name); list_for_each_entry(name_loop, &udev->symlink_list, node) printf("S: %s\n", name_loop->name); + list_for_each_entry(name_loop, &udev->env_list, node) + printf("E: %s\n", name_loop->name); return 0; } @@ -321,7 +323,7 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_db_search_name(devpath, sizeof(devpath), pos); if (retval != 0) { - fprintf(stderr, "device not found in database\n"); + fprintf(stderr, "no record for '%s' in database\n", pos); goto exit; } udev_db_get_device(&udev, devpath); From 314edf3ca44b268fa70a7a87a106322e2dd461af Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 27 Aug 2005 15:46:58 +0200 Subject: [PATCH 1475/4284] change parameter order of udev_db_search_name() Signed-off-by: Kay Sievers --- udev_db.c | 2 +- udev_db.h | 2 +- udev_rules.c | 19 +++++++++++-------- udevinfo.c | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/udev_db.c b/udev_db.c index d958c6173b..5377a3b373 100644 --- a/udev_db.c +++ b/udev_db.c @@ -202,7 +202,7 @@ int udev_db_get_device(struct udevice *udev, const char *devpath) return 0; } -int udev_db_search_name(char *devpath, size_t len, const char *name) +int udev_db_search_name(const char *name, char *devpath, size_t len) { DIR *dir; char path[PATH_SIZE]; diff --git a/udev_db.h b/udev_db.h index 61ea5b47fc..b0bc51a2c7 100644 --- a/udev_db.h +++ b/udev_db.h @@ -27,7 +27,7 @@ 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_search_name(char *devpath, size_t len, const char *name); +extern int udev_db_search_name(const char *name, char *devpath, size_t len); extern int udev_db_get_all_entries(struct list_head *name_list); #endif /* _UDEV_DB_H_ */ diff --git a/udev_rules.c b/udev_rules.c index 6c6aa0f091..8db7fd377a 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -270,28 +270,31 @@ static int import_parent_into_env(struct udevice *udev, struct sysfs_class_devic /* finds the lowest positive N such that N isn't present in the udevdb * if doesn't exist, 0 is returned, N otherwise */ -static int find_free_number(const char *name) +static int find_free_number(const char *name, const char *devpath) { - char devpath[PATH_SIZE]; + char db_devpath[PATH_SIZE]; char filename[PATH_SIZE]; int num = 0; strlcpy(filename, name, sizeof(filename)); while (1) { dbg("look for existing node '%s'", filename); - if (udev_db_search_name(devpath, sizeof(devpath), filename) != 0) { + if (udev_db_search_name(filename, db_devpath, sizeof(db_devpath)) != 0) { dbg("free num=%d", num); - return num; + break; } num++; - if (num > 1000) { - info("find_free_number gone crazy (num=%d), aborted", num); - return -1; + if (num > 100000) { + err("find_free_number aborted at num=%d", num); + num = -1; + break; } snprintf(filename, sizeof(filename), "%s%d", name, num); filename[sizeof(filename)-1] = '\0'; } + + return num; } static int find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, @@ -546,7 +549,7 @@ found: dbg("substitute sysfs value '%s'", temp2); break; case SUBST_ENUM: - next_free_number = find_free_number(string); + next_free_number = find_free_number(string, udev->devpath); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); strlcat(string, temp2, maxsize); diff --git a/udevinfo.c b/udevinfo.c index 11b0104581..b546488c7e 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -321,7 +321,7 @@ int main(int argc, char *argv[], char *envp[]) } else pos = name; - retval = udev_db_search_name(devpath, sizeof(devpath), pos); + retval = udev_db_search_name(pos, devpath, sizeof(devpath)); if (retval != 0) { fprintf(stderr, "no record for '%s' in database\n", pos); goto exit; From fb17920701dcba0d94e3fde566788a868e41d1ad Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 27 Aug 2005 16:15:41 +0200 Subject: [PATCH 1476/4284] add and use name_list_cleanup() for cleaning up the string lists Signed-off-by: Kay Sievers --- udev_device.c | 18 +++--------------- udev_rules.c | 24 +++--------------------- udev_utils.c | 11 +++++++++++ udev_utils.h | 1 + udevinfo.c | 8 +++----- 5 files changed, 21 insertions(+), 41 deletions(-) diff --git a/udev_device.c b/udev_device.c index 45bb6a2876..db72d3007d 100644 --- a/udev_device.c +++ b/udev_device.c @@ -103,19 +103,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs void udev_cleanup_device(struct udevice *udev) { - struct name_entry *name_loop; - struct name_entry *temp_loop; - - list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { - list_del(&name_loop->node); - free(name_loop); - } - list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { - list_del(&name_loop->node); - free(name_loop); - } - list_for_each_entry_safe(name_loop, temp_loop, &udev->env_list, node) { - list_del(&name_loop->node); - free(name_loop); - } + name_list_cleanup(&udev->symlink_list); + name_list_cleanup(&udev->run_list); + name_list_cleanup(&udev->env_list); } diff --git a/udev_rules.c b/udev_rules.c index 8db7fd377a..3cbcad55c1 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -964,14 +964,8 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s 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) { - struct name_entry *name_loop; - struct name_entry *temp_loop; - info("reset symlink list"); - list_for_each_entry_safe(name_loop, temp_loop, &udev->symlink_list, node) { - list_del(&name_loop->node); - free(name_loop); - } + name_list_cleanup(&udev->symlink_list); } strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); @@ -1015,14 +1009,8 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s 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) { - struct name_entry *name_loop; - struct name_entry *temp_loop; - info("reset run list"); - list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { - list_del(&name_loop->node); - free(name_loop); - } + name_list_cleanup(&udev->run_list); } strlcpy(program, key_val(rule, &rule->run), sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_device); @@ -1096,14 +1084,8 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, char program[PATH_SIZE]; if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) { - struct name_entry *name_loop; - struct name_entry *temp_loop; - info("reset run list"); - list_for_each_entry_safe(name_loop, temp_loop, &udev->run_list, node) { - list_del(&name_loop->node); - free(name_loop); - } + name_list_cleanup(&udev->run_list); } strlcpy(program, key_val(rule, &rule->run), sizeof(program)); apply_format(udev, program, sizeof(program), class_dev, sysfs_dev); diff --git a/udev_utils.c b/udev_utils.c index de43dee30d..fc1e2e1f7e 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -224,6 +224,17 @@ int name_list_key_add(struct list_head *name_list, const char *key, const char * return 0; } +void name_list_cleanup(struct list_head *name_list) +{ + struct name_entry *name_loop; + struct name_entry *temp_loop; + + list_for_each_entry_safe(name_loop, temp_loop, 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) { diff --git a/udev_utils.h b/udev_utils.h index a3fc283203..0a307526b7 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -45,6 +45,7 @@ extern void remove_trailing_char(char *path, char c); extern void replace_untrusted_chars(char *string); extern int name_list_add(struct list_head *name_list, const char *name, int sort); extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); +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 int pass_env_to_socket(const char *name, const char *devpath, const char *action); extern int run_program(const char *command, const char *subsystem, diff --git a/udevinfo.c b/udevinfo.c index b546488c7e..fadfaec945 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -170,19 +170,17 @@ exit: static void dump_names(void) { LIST_HEAD(name_list); struct name_entry *name_loop; - struct name_entry *tmp_loop; udev_db_get_all_entries(&name_list); - list_for_each_entry_safe(name_loop, tmp_loop, &name_list, node) { + list_for_each_entry(name_loop, &name_list, node) { struct udevice udev_db; udev_init_device(&udev_db, NULL, NULL, NULL); - if (udev_db_get_device(&udev_db, name_loop->name) == 0) { + if (udev_db_get_device(&udev_db, name_loop->name) == 0) printf("%s=%s/%s\n", udev_db.devpath, udev_root, udev_db.name); - free(name_loop); - } udev_cleanup_device(&udev_db); } + name_list_cleanup(&name_list); } int main(int argc, char *argv[], char *envp[]) From 7104c558dad47ee85860ebb891bdc8820d95154d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 27 Aug 2005 23:27:43 +0200 Subject: [PATCH 1477/4284] don't store devpath in udevdb, we don't need it Signed-off-by: Kay Sievers --- udev_db.c | 63 ++++++++++++++++++++++------------------------------ udev_db.h | 2 +- udev_rules.c | 2 +- udevinfo.c | 2 +- 4 files changed, 30 insertions(+), 39 deletions(-) diff --git a/udev_db.c b/udev_db.c index 5377a3b373..bf369ac2e6 100644 --- a/udev_db.c +++ b/udev_db.c @@ -39,10 +39,11 @@ #define PATH_TO_NAME_CHAR '@' -static int get_db_filename(const char *devpath, char *filename, size_t len) +static int devpath_to_db_path(const char *devpath, char *filename, size_t len) { size_t start, end, i; + /* add location of db files */ start = strlcpy(filename, udev_db_path, len); end = strlcat(filename, devpath, len); if (end > len) @@ -56,6 +57,21 @@ static int get_db_filename(const char *devpath, char *filename, size_t len) return 0; } +static int db_file_to_devpath(const char *filename, char *devpath, size_t len) +{ + size_t end, i; + + strlcpy(devpath, "/", len); + end = strlcat(devpath, filename, len); + + /* replace PATH_TO_NAME_CHAR to transform name into devpath */ + for (i = 1; i < end; i++) + if (devpath[i] == PATH_TO_NAME_CHAR) + devpath[i] = '/'; + + return 0; +} + int udev_db_add_device(struct udevice *udev) { char filename[PATH_SIZE]; @@ -75,7 +91,7 @@ int udev_db_add_device(struct udevice *udev) goto exit; } - get_db_filename(udev->devpath, filename, sizeof(filename)); + devpath_to_db_path(udev->devpath, filename, sizeof(filename)); create_path(filename); f = fopen(filename, "w"); if (f == NULL) { @@ -84,7 +100,6 @@ int udev_db_add_device(struct udevice *udev) } dbg("storing data for device '%s' in '%s'", udev->devpath, filename); - fprintf(f, "P:%s\n", udev->devpath); 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); @@ -101,8 +116,9 @@ exit: return 0; } -static int parse_db_file(struct udevice *udev, const char *filename) +int udev_db_get_device(struct udevice *udev, const char *devpath) { + char filename[PATH_SIZE]; char line[PATH_SIZE]; unsigned int major, minor; char *bufline; @@ -111,11 +127,13 @@ static int parse_db_file(struct udevice *udev, const char *filename) size_t cur; size_t count; + devpath_to_db_path(devpath, filename, sizeof(filename)); if (file_map(filename, &buf, &bufsize) != 0) { dbg("no db file to read '%s'", filename); return -1; } + strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); cur = 0; while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); @@ -123,12 +141,6 @@ static int parse_db_file(struct udevice *udev, const char *filename) cur += count+1; switch(bufline[0]) { - case 'P': - if (count > sizeof(udev->devpath)) - count = sizeof(udev->devpath); - memcpy(udev->devpath, &bufline[2], count-2); - udev->devpath[count-2] = '\0'; - break; case 'N': if (count > sizeof(udev->name)) count = sizeof(udev->name); @@ -185,27 +197,15 @@ int udev_db_delete_device(struct udevice *udev) { char filename[PATH_SIZE]; - get_db_filename(udev->devpath, filename, sizeof(filename)); + devpath_to_db_path(udev->devpath, filename, sizeof(filename)); unlink(filename); return 0; } -int udev_db_get_device(struct udevice *udev, const char *devpath) -{ - char filename[PATH_SIZE]; - - get_db_filename(devpath, filename, sizeof(filename)); - if (parse_db_file(udev, filename) != 0) - return -1; - - return 0; -} - -int udev_db_search_name(const char *name, char *devpath, size_t len) +int udev_db_lookup_name(const char *name, char *devpath, size_t len) { DIR *dir; - char path[PATH_SIZE]; int found = 0; dir = opendir(udev_db_path); @@ -227,7 +227,6 @@ int udev_db_search_name(const char *name, char *devpath, size_t len) ent = readdir(dir); if (ent == NULL || ent->d_name[0] == '\0') break; - if (ent->d_name[0] == '.') continue; @@ -247,12 +246,6 @@ int udev_db_search_name(const char *name, char *devpath, size_t len) cur += count+1; switch(bufline[0]) { - case 'P': - if (count > sizeof(path)) - count = sizeof(path); - memcpy(path, &bufline[2], count-2); - path[count-2] = '\0'; - break; case 'N': case 'S': if (count > sizeof(nodename)) @@ -261,8 +254,8 @@ int udev_db_search_name(const char *name, char *devpath, size_t len) nodename[count-2] = '\0'; dbg("compare '%s' '%s'", nodename, name); if (strcmp(nodename, name) == 0) { + db_file_to_devpath(ent->d_name, devpath, len); found = 1; - break; } break; default: @@ -273,10 +266,9 @@ int udev_db_search_name(const char *name, char *devpath, size_t len) } closedir(dir); - if (found) { - strlcpy(devpath, path, len); + if (found) return 0; - } else + else return -1; } @@ -298,7 +290,6 @@ int udev_db_get_all_entries(struct list_head *name_list) ent = readdir(dir); if (ent == NULL || ent->d_name[0] == '\0') break; - if (ent->d_name[0] == '.') continue; diff --git a/udev_db.h b/udev_db.h index b0bc51a2c7..89513932b3 100644 --- a/udev_db.h +++ b/udev_db.h @@ -27,7 +27,7 @@ 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_search_name(const char *name, char *devpath, size_t len); +extern int udev_db_lookup_name(const char *name, char *devpath, size_t len); extern int udev_db_get_all_entries(struct list_head *name_list); #endif /* _UDEV_DB_H_ */ diff --git a/udev_rules.c b/udev_rules.c index 3cbcad55c1..41a7291d79 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -279,7 +279,7 @@ static int find_free_number(const char *name, const char *devpath) strlcpy(filename, name, sizeof(filename)); while (1) { dbg("look for existing node '%s'", filename); - if (udev_db_search_name(filename, db_devpath, sizeof(db_devpath)) != 0) { + if (udev_db_lookup_name(filename, db_devpath, sizeof(db_devpath)) != 0) { dbg("free num=%d", num); break; } diff --git a/udevinfo.c b/udevinfo.c index fadfaec945..c7d801b87c 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -319,7 +319,7 @@ int main(int argc, char *argv[], char *envp[]) } else pos = name; - retval = udev_db_search_name(pos, devpath, sizeof(devpath)); + retval = udev_db_lookup_name(pos, devpath, sizeof(devpath)); if (retval != 0) { fprintf(stderr, "no record for '%s' in database\n", pos); goto exit; From 5b13ecb830cdec338b514b9ed8c2c559c2f05223 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 13:49:32 +0200 Subject: [PATCH 1478/4284] add uft8 validation for safe volume label exporting We will not support any other character encoding than plain ascii or utf8 for volume labels. All invalid utf8 and non-ascii characters are substituted for security reasons. No options, no fancy heuristics. Signed-off-by: Kay Sievers --- Makefile | 1 + udev_utils.c | 84 --------------- udev_utils.h | 29 ++++-- udev_utils_string.c | 243 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 262 insertions(+), 95 deletions(-) create mode 100644 udev_utils_string.c diff --git a/Makefile b/Makefile index 1c1280a7dc..8f99330967 100644 --- a/Makefile +++ b/Makefile @@ -147,6 +147,7 @@ UDEV_OBJS = \ udev_rules.o \ udev_rules_parse.o \ udev_utils.o \ + udev_utils_string.o \ udev_utils_file.o \ udev_utils_run.o \ udev_libc_wrapper.o diff --git a/udev_utils.c b/udev_utils.c index fc1e2e1f7e..c7292d0f04 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -36,69 +36,6 @@ #include "udev_utils.h" #include "list.h" -/* compare string with pattern (supports * ? [0-9] [!A-Z]) */ -int strcmp_pattern(const char *p, const char *s) -{ - if (s[0] == '\0') { - while (p[0] == '*') - p++; - return (p[0] != '\0'); - } - switch (p[0]) { - case '[': - { - int not = 0; - p++; - if (p[0] == '!') { - not = 1; - p++; - } - while ((p[0] != '\0') && (p[0] != ']')) { - int match = 0; - if (p[1] == '-') { - if ((s[0] >= p[0]) && (s[0] <= p[2])) - match = 1; - p += 3; - } else { - match = (p[0] == s[0]); - p++; - } - if (match ^ not) { - while ((p[0] != '\0') && (p[0] != ']')) - p++; - if (p[0] == ']') - return strcmp_pattern(p+1, s+1); - } - } - } - break; - case '*': - if (strcmp_pattern(p, s+1)) - return strcmp_pattern(p+1, s); - return 0; - case '\0': - if (s[0] == '\0') { - return 0; - } - break; - default: - if ((p[0] == s[0]) || (p[0] == '?')) - return strcmp_pattern(p+1, s+1); - break; - } - return 1; -} - -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; -} int log_priority(const char *priority) { @@ -143,27 +80,6 @@ int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, u return 0; } -void replace_untrusted_chars(char *string) -{ - size_t len; - - for (len = 0; string[len] != '\0'; len++) { - if (strchr(";,~\\()\'", string[len])) { - info("replace '%c' in '%s'", string[len], string); - string[len] = '_'; - } - } -} - -void remove_trailing_char(char *path, char c) -{ - size_t len; - - len = strlen(path); - while (len > 0 && path[len-1] == c) - path[--len] = '\0'; -} - int name_list_add(struct list_head *name_list, const char *name, int sort) { struct name_entry *loop_name; diff --git a/udev_utils.h b/udev_utils.h index 0a307526b7..a07d8d2b7c 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -31,22 +31,29 @@ struct name_entry { char name[PATH_SIZE]; }; -extern int strcmp_pattern(const char *p, const char *s); -extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); -extern int create_path(const char *path); +/* udev_utils.c */ extern int log_priority(const char *priority); -extern int string_is_true(const char *str); -extern int parse_get_pair(char **orig_string, char **left, char **right); -extern int unlink_secure(const char *filename); -extern int file_map(const char *filename, char **buf, size_t *bufsize); -extern void file_unmap(void *buf, size_t bufsize); -extern size_t buf_get_line(const char *buf, size_t buflen, size_t cur); -extern void remove_trailing_char(char *path, char c); -extern void replace_untrusted_chars(char *string); +extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int name_list_add(struct list_head *name_list, const char *name, int sort); extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); 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); + +/* udev_utils_string.c */ +extern int strcmp_pattern(const char *p, const char *s); +extern int string_is_true(const char *str); +extern void replace_untrusted_chars(char *string); +extern void remove_trailing_char(char *path, char c); +extern int utf8_encoded_valid_unichar(const char *str); + +/* udev_utils_file.c */ +extern int create_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); + +/* udev_utils_run.c */ extern int pass_env_to_socket(const char *name, const char *devpath, const char *action); extern int run_program(const char *command, const char *subsystem, char *result, size_t ressize, size_t *reslen, int log); diff --git a/udev_utils_string.c b/udev_utils_string.c new file mode 100644 index 0000000000..a30181e760 --- /dev/null +++ b/udev_utils_string.c @@ -0,0 +1,243 @@ +/* + * udev_utils_string.c - string manipulation + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "udev_libc_wrapper.h" +#include "udev.h" +#include "logging.h" +#include "udev_utils.h" +#include "list.h" + +/* compare string with pattern (like fnmatch(), supports * ? [0-9] [!A-Z]) */ +int strcmp_pattern(const char *p, const char *s) +{ + if (s[0] == '\0') { + while (p[0] == '*') + p++; + return (p[0] != '\0'); + } + switch (p[0]) { + case '[': + { + int not = 0; + p++; + if (p[0] == '!') { + not = 1; + p++; + } + while ((p[0] != '\0') && (p[0] != ']')) { + int match = 0; + if (p[1] == '-') { + if ((s[0] >= p[0]) && (s[0] <= p[2])) + match = 1; + p += 3; + } else { + match = (p[0] == s[0]); + p++; + } + if (match ^ not) { + while ((p[0] != '\0') && (p[0] != ']')) + p++; + if (p[0] == ']') + return strcmp_pattern(p+1, s+1); + } + } + } + break; + case '*': + if (strcmp_pattern(p, s+1)) + return strcmp_pattern(p+1, s); + return 0; + case '\0': + if (s[0] == '\0') { + return 0; + } + break; + default: + if ((p[0] == s[0]) || (p[0] == '?')) + return strcmp_pattern(p+1, s+1); + break; + } + return 1; +} + +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_char(char *path, char c) +{ + size_t len; + + len = strlen(path); + while (len > 0 && path[len-1] == c) + path[--len] = '\0'; +} + +/* 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; +} + +void replace_untrusted_chars(char *string) +{ + size_t len; + + for (len = 0; string[len] != '\0'; len++) { + if (strchr(";,~\\()\'", string[len])) + string[len] = '_'; + } +} From 764ce7f2ab526c084f005186e0dcbabe59070247 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 15:55:58 +0200 Subject: [PATCH 1479/4284] start to enforce plain ascii or valid utf8 No device node or symlink can have other characters as plain readable ascii or valid utf8. The /dev/disk/by-label/* symlinks can no longer contain weird stuff read from untrusted sources. Signed-off-by: Kay Sievers --- test/udev-test.pl | 20 +++++++++++++++++++- udev_rules.c | 21 ++++++++++++++++++--- udev_utils.h | 2 +- udev_utils_string.c | 33 ++++++++++++++++++++++++++++----- 4 files changed, 66 insertions(+), 10 deletions(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index c32cfe7eeb..e7c00e29e6 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1324,7 +1324,25 @@ EOF 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 => < 0 && isspace(temp2[i-1])) temp2[--i] = '\0'; - replace_untrusted_chars(temp2); + count = replace_untrusted_chars(temp2); + if (count) + info("%i untrusted character(s) replaced" , count); strlcat(string, temp2, maxsize); dbg("substitute sysfs value '%s'", temp2); break; @@ -812,9 +815,13 @@ try_parent: if (rule->program.operation != KEY_OP_NOMATCH) goto exit; } else { + int count; + dbg("PROGRAM matches"); remove_trailing_char(result, '\n'); - replace_untrusted_chars(result); + count = replace_untrusted_chars(result); + if (count) + info("%i untrusted character(s) replaced" , count); dbg("result is '%s'", result); strlcpy(udev->program_result, result, sizeof(udev->program_result)); dbg("PROGRAM returned successful"); @@ -960,6 +967,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s if (!udev->symlink_final && rule->symlink.operation != KEY_OP_UNSET) { char temp[PATH_SIZE]; char *pos, *next; + int count; if (rule->symlink.operation == KEY_OP_ASSIGN_FINAL) udev->symlink_final = 1; @@ -969,7 +977,10 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s } strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); - dbg("rule applied, added symlink '%s'", temp); + count = replace_untrusted_chars(temp); + if (count) + info("%i untrusted character(s) replaced" , count); + dbg("rule applied, added symlink(s) '%s'", temp); /* add multiple symlinks separated by spaces */ pos = temp; @@ -993,9 +1004,13 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s /* set name, later rules with name set will be ignored */ if (rule->name.operation != KEY_OP_UNSET) { + int count; name_set = 1; strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name)); apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + count = replace_untrusted_chars(udev->name); + if (count) + info("%i untrusted character(s) replaced", count); info("rule applied, '%s' becomes '%s'", udev->kernel_name, udev->name); if (udev->type != DEV_NET) diff --git a/udev_utils.h b/udev_utils.h index a07d8d2b7c..ad415641d8 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -42,9 +42,9 @@ extern int add_matching_files(struct list_head *name_list, const char *dirname, /* udev_utils_string.c */ extern int strcmp_pattern(const char *p, const char *s); extern int string_is_true(const char *str); -extern void replace_untrusted_chars(char *string); extern void remove_trailing_char(char *path, char c); extern int utf8_encoded_valid_unichar(const char *str); +extern int replace_untrusted_chars(char *str); /* udev_utils_file.c */ extern int create_path(const char *path); diff --git a/udev_utils_string.c b/udev_utils_string.c index a30181e760..bb5677d46e 100644 --- a/udev_utils_string.c +++ b/udev_utils_string.c @@ -232,12 +232,35 @@ int utf8_encoded_valid_unichar(const char *str) return len; } -void replace_untrusted_chars(char *string) +/* replace everything but whitelisted plain ascii and valid utf8 */ +int replace_untrusted_chars(char *str) { - size_t len; + size_t i = 0; + int replaced = 0; - for (len = 0; string[len] != '\0'; len++) { - if (strchr(";,~\\()\'", string[len])) - string[len] = '_'; + while (str[i] != '\0') { + int len; + + /* valid printable ascii char */ + if ((str[i] >= '0' && str[i] <= '9') || + (str[i] >= 'A' && str[i] <= 'Z') || + (str[i] >= 'a' && str[i] <= 'z') || + strchr(" #$%+-./:=?@_", str[i])) { + i++; + continue; + } + /* valid utf8 is accepted */ + len = utf8_encoded_valid_unichar(&str[i]); + if (len > 1) { + i += len; + continue; + } + + /* everything else is garbage */ + str[i] = '_'; + i++; + replaced++; } + + return replaced; } From f1ff8d7b4ad1f95385d42c3fa1b2a997b9e6d5f5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 20:25:37 +0200 Subject: [PATCH 1480/4284] use WRITE_END/READ_END for the pipe index Signed-off-by: Kay Sievers --- udev_utils.h | 4 +++ udev_utils_run.c | 66 ++++++++++++++++++++++++------------------------ udevd.c | 28 ++++++++++---------- 3 files changed, 51 insertions(+), 47 deletions(-) diff --git a/udev_utils.h b/udev_utils.h index ad415641d8..9ff79113b1 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -26,6 +26,10 @@ #define UDEV_MAX(a,b) ((a) > (b) ? (a) : (b)) +/* pipes */ +#define READ_END 0 +#define WRITE_END 1 + struct name_entry { struct list_head node; char name[PATH_SIZE]; diff --git a/udev_utils_run.c b/udev_utils_run.c index fb37a05830..1315154c26 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -130,26 +130,26 @@ int run_program(const char *command, const char *subsystem, switch(pid) { case 0: /* child closes parent ends of pipes */ - if (outpipe[0] > 0) - close(outpipe[0]); - if (errpipe[0] > 0) - close(errpipe[0]); + 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[1] < 0) + if (outpipe[WRITE_END] < 0) dup2(devnull, STDOUT_FILENO); - if (errpipe[1] < 0) + if (errpipe[WRITE_END] < 0) dup2(devnull, STDERR_FILENO); close(devnull); } else err("open /dev/null failed"); - if (outpipe[1] > 0) - dup2(outpipe[1], STDOUT_FILENO); - if (errpipe[1] > 0) - dup2(errpipe[1], STDERR_FILENO); + if (outpipe[WRITE_END] > 0) + dup2(outpipe[WRITE_END], STDOUT_FILENO); + if (errpipe[WRITE_END] > 0) + dup2(errpipe[WRITE_END], STDERR_FILENO); execv(argv[0], argv); /* we should never reach this */ @@ -160,27 +160,27 @@ int run_program(const char *command, const char *subsystem, return -1; default: /* read from child if requested */ - if (outpipe[0] > 0 || errpipe[0] > 0) { + if (outpipe[READ_END] > 0 || errpipe[READ_END] > 0) { ssize_t count; size_t respos = 0; /* parent closes child ends of pipes */ - if (outpipe[1] > 0) - close(outpipe[1]); - if (errpipe[1] > 0) - close(errpipe[1]); + if (outpipe[WRITE_END] > 0) + close(outpipe[WRITE_END]); + if (errpipe[WRITE_END] > 0) + close(errpipe[WRITE_END]); /* read child output */ - while (outpipe[0] > 0 || errpipe[0] > 0) { + while (outpipe[READ_END] > 0 || errpipe[READ_END] > 0) { int fdcount; fd_set readfds; FD_ZERO(&readfds); - if (outpipe[0] > 0) - FD_SET(outpipe[0], &readfds); - if (errpipe[0] > 0) - FD_SET(errpipe[0], &readfds); - fdcount = select(UDEV_MAX(outpipe[0], errpipe[0])+1, &readfds, NULL, NULL, NULL); + 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; @@ -189,15 +189,15 @@ int run_program(const char *command, const char *subsystem, } /* get stdout */ - if (outpipe[0] > 0 && FD_ISSET(outpipe[0], &readfds)) { + if (outpipe[READ_END] > 0 && FD_ISSET(outpipe[READ_END], &readfds)) { char inbuf[1024]; char *pos; char *line; - count = read(outpipe[0], inbuf, sizeof(inbuf)-1); + count = read(outpipe[READ_END], inbuf, sizeof(inbuf)-1); if (count <= 0) { - close(outpipe[0]); - outpipe[0] = -1; + close(outpipe[READ_END]); + outpipe[READ_END] = -1; if (count < 0) { err("stdin read failed with '%s'", strerror(errno)); retval = -1; @@ -223,15 +223,15 @@ int run_program(const char *command, const char *subsystem, } /* get stderr */ - if (errpipe[0] > 0 && FD_ISSET(errpipe[0], &readfds)) { + if (errpipe[READ_END] > 0 && FD_ISSET(errpipe[READ_END], &readfds)) { char errbuf[1024]; char *pos; char *line; - count = read(errpipe[0], errbuf, sizeof(errbuf)-1); + count = read(errpipe[READ_END], errbuf, sizeof(errbuf)-1); if (count <= 0) { - close(errpipe[0]); - errpipe[0] = -1; + close(errpipe[READ_END]); + errpipe[READ_END] = -1; if (count < 0) err("stderr read failed with '%s'", strerror(errno)); continue; @@ -243,10 +243,10 @@ int run_program(const char *command, const char *subsystem, info("'%s' (stderr) '%s'", argv[0], line); } } - if (outpipe[0] > 0) - close(outpipe[0]); - if (errpipe[0] > 0) - close(errpipe[0]); + 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) { diff --git a/udevd.c b/udevd.c index e4880c9814..d26d53fe0b 100644 --- a/udevd.c +++ b/udevd.c @@ -55,7 +55,7 @@ static int udevd_sock; static int uevent_netlink_sock; static pid_t sid; -static int pipefds[2] = {-1, -1}; +static int signal_pipe[2] = {-1, -1}; static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int sig_flag; @@ -657,7 +657,7 @@ static void asmlinkage sig_handler(int signum) * which will wakeup our mainloop */ if (!sig_flag) { - rc = write(pipefds[1], &signum, sizeof(signum)); + rc = write(signal_pipe[1], &signum, sizeof(signum)); if (rc >= 0) sig_flag = 1; } @@ -842,25 +842,25 @@ int main(int argc, char *argv[], char *envp[]) setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); /* setup signal handler pipe */ - retval = pipe(pipefds); + retval = pipe(signal_pipe); if (retval < 0) { err("error getting pipes: %s", strerror(errno)); goto exit; } - retval = fcntl(pipefds[0], F_SETFL, O_NONBLOCK); + retval = fcntl(signal_pipe[READ_END], F_SETFL, O_NONBLOCK); if (retval < 0) { err("error fcntl on read pipe: %s", strerror(errno)); goto exit; } - retval = fcntl(pipefds[0], F_SETFD, FD_CLOEXEC); + retval = fcntl(signal_pipe[READ_END], F_SETFD, FD_CLOEXEC); if (retval < 0) err("error fcntl on read pipe: %s", strerror(errno)); - retval = fcntl(pipefds[1], F_SETFL, O_NONBLOCK); + retval = fcntl(signal_pipe[WRITE_END], F_SETFL, O_NONBLOCK); if (retval < 0) { err("error fcntl on write pipe: %s", strerror(errno)); goto exit; } - retval = fcntl(pipefds[1], F_SETFD, FD_CLOEXEC); + retval = fcntl(signal_pipe[WRITE_END], F_SETFD, FD_CLOEXEC); if (retval < 0) err("error fcntl on write pipe: %s", strerror(errno)); @@ -934,7 +934,7 @@ int main(int argc, char *argv[], char *envp[]) int fdcount; FD_ZERO(&readfds); - FD_SET(pipefds[0], &readfds); + FD_SET(signal_pipe[READ_END], &readfds); FD_SET(udevd_sock, &readfds); if (uevent_netlink_sock > 0) FD_SET(uevent_netlink_sock, &readfds); @@ -974,12 +974,12 @@ int main(int argc, char *argv[], char *envp[]) } /* received a signal, clear our notification pipe */ - if (FD_ISSET(pipefds[0], &readfds)) { + if (FD_ISSET(signal_pipe[0], &readfds)) { int sig; ssize_t rlen; while(1) { - rlen = read(pipefds[0], &sig, sizeof(sig)); + rlen = read(signal_pipe[0], &sig, sizeof(sig)); if (rlen <= 0) break; } @@ -1011,10 +1011,10 @@ int main(int argc, char *argv[], char *envp[]) } exit: - if (pipefds[0] > 0) - close(pipefds[0]); - if (pipefds[1] > 0) - close(pipefds[1]); + 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); From c6303c1316e967ae2c52792b0560ee055ce4276e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 23:13:14 +0200 Subject: [PATCH 1481/4284] remove not needed sig_flag for state of signal_pipe Less internal state is better. And, we don't need to call read() twice with every signal handling. Signed-off-by: Kay Sievers --- udevd.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/udevd.c b/udevd.c index d26d53fe0b..3392eea1a1 100644 --- a/udevd.c +++ b/udevd.c @@ -636,8 +636,6 @@ static struct uevent_msg *get_netlink_msg(void) static void asmlinkage sig_handler(int signum) { - int rc; - switch (signum) { case SIGINT: case SIGTERM: @@ -653,14 +651,8 @@ static void asmlinkage sig_handler(int signum) break; } - /* if pipe is empty, write to pipe to force select to return, - * which will wakeup our mainloop - */ - if (!sig_flag) { - rc = write(signal_pipe[1], &signum, sizeof(signum)); - if (rc >= 0) - sig_flag = 1; - } + /* write to pipe, which will wakeup select() in our mainloop */ + write(signal_pipe[WRITE_END], "", 1); } static void udev_done(int pid) @@ -974,16 +966,10 @@ int main(int argc, char *argv[], char *envp[]) } /* received a signal, clear our notification pipe */ - if (FD_ISSET(signal_pipe[0], &readfds)) { - int sig; - ssize_t rlen; + if (FD_ISSET(signal_pipe[READ_END], &readfds)) { + char buf[256]; - while(1) { - rlen = read(signal_pipe[0], &sig, sizeof(sig)); - if (rlen <= 0) - break; - } - sig_flag = 0; + read(signal_pipe[READ_END], &buf, sizeof(buf)); } /* forked child have returned */ From d2ecd6a19d147ede317995cce1b21042291a6b19 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 23:14:59 +0200 Subject: [PATCH 1482/4284] don't reenter get_udevd_msg() if message is ignored Check all event sources with every iteration. Signed-off-by: Kay Sievers --- udevd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/udevd.c b/udevd.c index 3392eea1a1..c75141f9fa 100644 --- a/udevd.c +++ b/udevd.c @@ -946,9 +946,8 @@ int main(int argc, char *argv[], char *envp[]) if (uevent_netlink_active && msg->type == UDEVD_UEVENT_UDEVSEND && msg->seqnum != 0) { dbg("skip uevent_helper message, netlink is active"); free(msg); - continue; - } - msg_queue_insert(msg); + } else + msg_queue_insert(msg); } } From b2c6818dc35f7b149bba7bf963d1a3afb8daa867 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 23:15:51 +0200 Subject: [PATCH 1483/4284] rename ...trailing_char() to ...trailing_chars() Signed-off-by: Kay Sievers --- udev_config.c | 8 ++++---- udev_device.c | 2 +- udev_rules.c | 4 ++-- udev_utils.h | 2 +- udev_utils_string.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/udev_config.c b/udev_config.c index f0b409b067..b8c4ffc8ed 100644 --- a/udev_config.c +++ b/udev_config.c @@ -149,19 +149,19 @@ static int parse_config_file(void) if (strcasecmp(variable, "udev_root") == 0) { strlcpy(udev_root, value, sizeof(udev_root)); - remove_trailing_char(udev_root, '/'); + remove_trailing_chars(udev_root, '/'); continue; } if (strcasecmp(variable, "udev_db") == 0) { strlcpy(udev_db_path, value, sizeof(udev_db_path)); - remove_trailing_char(udev_db_path, '/'); + remove_trailing_chars(udev_db_path, '/'); continue; } if (strcasecmp(variable, "udev_rules") == 0) { strlcpy(udev_rules_filename, value, sizeof(udev_rules_filename)); - remove_trailing_char(udev_rules_filename, '/'); + remove_trailing_chars(udev_rules_filename, '/'); continue; } @@ -195,7 +195,7 @@ void udev_init_config(void) env = getenv("UDEV_CONFIG_FILE"); if (env) { strlcpy(udev_config_filename, env, sizeof(udev_config_filename)); - remove_trailing_char(udev_config_filename, '/'); + remove_trailing_chars(udev_config_filename, '/'); } parse_config_file(); diff --git a/udev_device.c b/udev_device.c index db72d3007d..ad6f706366 100644 --- a/udev_device.c +++ b/udev_device.c @@ -58,7 +58,7 @@ int udev_init_device(struct udevice *udev, const char* devpath, const char *subs if (devpath) { strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); - remove_trailing_char(udev->devpath, '/'); + remove_trailing_chars(udev->devpath, '/'); if (strncmp(udev->devpath, "/block/", 7) == 0) udev->type = DEV_BLOCK; diff --git a/udev_rules.c b/udev_rules.c index c1482c34b5..459c27b4d5 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -326,7 +326,7 @@ static int find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sys attr_found: strlcpy(value, tmpattr->value, len); - remove_trailing_char(value, '\n'); + remove_trailing_chars(value, '\n'); dbg("found attribute '%s'", tmpattr->path); return 0; @@ -818,7 +818,7 @@ try_parent: int count; dbg("PROGRAM matches"); - remove_trailing_char(result, '\n'); + remove_trailing_chars(result, '\n'); count = replace_untrusted_chars(result); if (count) info("%i untrusted character(s) replaced" , count); diff --git a/udev_utils.h b/udev_utils.h index 9ff79113b1..ea39a028f5 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -46,7 +46,7 @@ extern int add_matching_files(struct list_head *name_list, const char *dirname, /* udev_utils_string.c */ extern int strcmp_pattern(const char *p, const char *s); extern int string_is_true(const char *str); -extern void remove_trailing_char(char *path, char c); +extern void remove_trailing_chars(char *path, char c); extern int utf8_encoded_valid_unichar(const char *str); extern int replace_untrusted_chars(char *str); diff --git a/udev_utils_string.c b/udev_utils_string.c index bb5677d46e..37db8dbc85 100644 --- a/udev_utils_string.c +++ b/udev_utils_string.c @@ -100,7 +100,7 @@ int string_is_true(const char *str) return 0; } -void remove_trailing_char(char *path, char c) +void remove_trailing_chars(char *path, char c) { size_t len; From e79952c59854e6d5fab638262498d8395acd33ff Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 23:16:56 +0200 Subject: [PATCH 1484/4284] vol_id: ID_LABEL_SAFE will no longer contain fancy characters Signed-off-by: Kay Sievers --- extras/volume_id/vol_id.c | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index fe0b3a0ed0..3c75bdaa2f 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -156,6 +156,7 @@ int main(int argc, char *argv[]) print: set_str(name, vid->label, sizeof(vid->label)); + replace_untrusted_chars(name); switch (print) { case PRINT_EXPORT: From 199cdd8675379768c69bf789e2159c360ae0332e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 28 Aug 2005 23:19:45 +0200 Subject: [PATCH 1485/4284] udevd: move some logging to "info" and "err" Signed-off-by: Kay Sievers --- udevd.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/udevd.c b/udevd.c index c75141f9fa..3a8ac639bd 100644 --- a/udevd.c +++ b/udevd.c @@ -58,7 +58,6 @@ static pid_t sid; static int signal_pipe[2] = {-1, -1}; static volatile int sigchilds_waiting; static volatile int run_msg_q; -static volatile int sig_flag; static volatile int udev_exit; static int init_phase = 1; static int run_exec_q; @@ -440,7 +439,7 @@ recheck: /* set timeout for remaining queued events */ if (!list_empty(&msg_list)) { struct itimerval itv = {{0, 0}, {timeout - msg_age, 0}}; - dbg("next event expires in %li seconds", timeout - msg_age); + info("next event expires in %li seconds", timeout - msg_age); setitimer(ITIMER_REAL, &itv, NULL); } } @@ -523,31 +522,31 @@ static struct uevent_msg *get_udevd_msg(void) size = recvmsg(udevd_sock, &smsg, 0); if (size < 0) { if (errno != EINTR) - dbg("unable to receive udevd message"); + err("unable to receive udevd message"); return NULL; } cmsg = CMSG_FIRSTHDR(&smsg); cred = (struct ucred *) CMSG_DATA(cmsg); if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { - info("no sender credentials received, message ignored"); + err("no sender credentials received, message ignored"); return NULL; } if (cred->uid != 0) { - info("sender uid=%i, message ignored", cred->uid); + err("sender uid=%i, message ignored", cred->uid); return NULL; } if (strncmp(usend_msg.magic, UDEV_MAGIC, sizeof(UDEV_MAGIC)) != 0 ) { - info("message magic '%s' doesn't match, ignore it", usend_msg.magic); + err("message magic '%s' doesn't match, ignore it", usend_msg.magic); return NULL; } switch (usend_msg.type) { case UDEVD_UEVENT_UDEVSEND: case UDEVD_UEVENT_INITSEND: - dbg("udevd event message received"); + info("udevd event message received"); envbuf_size = size - offsetof(struct udevd_msg, envbuf); dbg("envbuf_size=%i", envbuf_size); msg = get_msg_from_envbuf(usend_msg.envbuf, envbuf_size); @@ -594,7 +593,7 @@ static struct uevent_msg *get_netlink_msg(void) size = recv(uevent_netlink_sock, &buffer, sizeof(buffer), 0); if (size < 0) { if (errno != EINTR) - dbg("unable to receive udevd message"); + err("unable to receive udevd message"); return NULL; } @@ -613,20 +612,20 @@ static struct uevent_msg *get_netlink_msg(void) /* validate message */ pos = strchr(buffer, '@'); if (pos == NULL) { - dbg("invalid uevent '%s'", buffer); + err("invalid uevent '%s'", buffer); free(msg); return NULL; } pos[0] = '\0'; if (msg->action == NULL) { - dbg("no ACTION in payload found, skip event '%s'", buffer); + err("no ACTION in payload found, skip event '%s'", buffer); free(msg); return NULL; } if (strcmp(msg->action, buffer) != 0) { - dbg("ACTION in payload does not match uevent, skip event '%s'", buffer); + err("ACTION in payload does not match uevent, skip event '%s'", buffer); free(msg); return NULL; } @@ -664,7 +663,10 @@ static void udev_done(int pid) list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { sysinfo(&info); - info("seq %llu exit, %ld seconds old", msg->seqnum, info.uptime - msg->queue_time); + if (msg->queue_time) + info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, info.uptime - msg->queue_time); + else + info("seq 0, pid [%d] exit", msg->pid); msg_queue_delete(msg); /* we want to run the exec queue manager since there may @@ -739,7 +741,7 @@ static int init_uevent_netlink_sock(void) uevent_netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (uevent_netlink_sock == -1) { - dbg("error getting socket, %s", strerror(errno)); + err("error getting socket, %s", strerror(errno)); return -1; } @@ -749,7 +751,7 @@ static int init_uevent_netlink_sock(void) retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl)); if (retval < 0) { - dbg("bind failed, %s", strerror(errno)); + err("bind failed, %s", strerror(errno)); close(uevent_netlink_sock); uevent_netlink_sock = -1; return -1; @@ -944,7 +946,7 @@ int main(int argc, char *argv[], char *envp[]) if (msg) { /* discard kernel messages if netlink is active */ if (uevent_netlink_active && msg->type == UDEVD_UEVENT_UDEVSEND && msg->seqnum != 0) { - dbg("skip uevent_helper message, netlink is active"); + info("skip uevent_helper message with SEQNUM, netlink is active"); free(msg); } else msg_queue_insert(msg); From 69348b66ff4163a2fbf974bde649e5bc963462b4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 29 Aug 2005 01:19:02 +0200 Subject: [PATCH 1486/4284] remove special TIMEOUT handling from incoming queue Moving events directly to the exec queue instead of the reordering incoming queue, leaves holes in the sequence, that lead to timeouts for all other events. Remove that part of the special handling. (With netlink, events can't get out-of-order and the maximum timeout is 5 seconds and should not cause any trouble with the 10 sec timout for the firmware class anyway. Events with timeouts are still prioritized for execution, but don't bypass the incoming queue anymore.) Many thanks to: Uberto Barbini for his endless debugging and sending all the traces, that showed this failure with his DVB device: UEVENT[1124474094] add@/module/stv0299 UEVENT[1124474094] add@/module/ves1x93 UEVENT[1124474094] add@/module/ttpci_eeprom UEVENT[1124474094] add@/module/saa7146 UEVENT[1124474094] add@/module/video_buf UEVENT[1124474094] add@/module/saa7146_vv UEVENT[1124474094] add@/module/dvb_core UEVENT[1124474094] add@/module/dvb_ttpci UEVENT[1124474094] add@/bus/pci/drivers/dvb UEVENT[1124474094] add@/class/firmware/0000:00:14.0 UDEV [1124474094] add@/module/dvb_core UDEV [1124474094] add@/module/saa7146_vv UDEV [1124474094] add@/module/dvb_ttpci UDEV [1124474094] add@/module/ves1x93 UDEV [1124474094] add@/module/ttpci_eeprom UDEV [1124474094] add@/module/saa7146 UDEV [1124474094] add@/module/stv0299 UDEV [1124474094] add@/module/video_buf UDEV [1124474094] add@/bus/pci/drivers/dvb UEVENT[1124474094] remove@/class/firmware/0000:00:14.0 <- event with TIMEOUT will leave a hole in the incoming UDEV [1124474094] add@/class/firmware/0000:00:14.0 sequence, which will cause a wait for the alarm() UEVENT[1124474094] add@/class/i2c-adapter/i2c-1 that flushes the queue UEVENT[1124474094] add@/class/i2c-dev/i2c-1 UDEV [1124474094] remove@/class/firmware/0000:00:14.0 <- event also has TIMEOUT and is executed immediately UEVENT[1124474095] add@/class/dvb/dvb0.demux0 UEVENT[1124474095] add@/class/dvb/dvb0.dvr0 UEVENT[1124474095] add@/class/dvb/dvb0.video0 UEVENT[1124474095] add@/class/dvb/dvb0.audio0 UEVENT[1124474095] add@/class/dvb/dvb0.ca0 UEVENT[1124474095] add@/class/dvb/dvb0.osd0 UEVENT[1124474095] add@/class/dvb/dvb0.net0 UEVENT[1124474095] add@/class/video4linux/video1 UEVENT[1124474095] add@/class/dvb/dvb0.frontend0 UDEV [1124474099] add@/class/i2c-adapter/i2c-1 <- all others have 5 seconds delay cause of the missing event UDEV [1124474099] add@/class/dvb/dvb0.ca0 missing events UDEV [1124474099] add@/class/dvb/dvb0.osd0 UDEV [1124474099] add@/class/video4linux/video1 UDEV [1124474099] add@/class/dvb/dvb0.frontend0 UDEV [1124474099] add@/class/dvb/dvb0.video0 UDEV [1124474099] add@/class/dvb/dvb0.audio0 UDEV [1124474099] add@/class/i2c-dev/i2c-1 UDEV [1124474099] add@/class/dvb/dv My test program that simulates a similar sequence, runs without any delay now. (With one of the next versions we will make netlink mandatory, then we can remove the whole input queue crap with the reordering anyway.) Signed-off-by: Kay Sievers --- udevd.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/udevd.c b/udevd.c index 3a8ac639bd..96d4fbb3be 100644 --- a/udevd.c +++ b/udevd.c @@ -131,15 +131,6 @@ static void msg_queue_insert(struct uevent_msg *msg) init_phase = 0; } - /* don't delay messages with timeout set */ - if (msg->timeout) { - info("seq %llu with timeout %u seconds will be execute without queuing, '%s' '%s'", - msg->seqnum, msg->timeout, msg->action, msg->devpath); - list_add(&msg->node, &exec_list); - run_exec_q = 1; - return; - } - /* sort message by sequence number into list */ list_for_each_entry_reverse(loop_msg, &msg_list, node) { if (loop_msg->seqnum < msg->seqnum) From a8586078fc768e930624f29347fedcbb5c5f41cf Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 29 Aug 2005 02:19:36 +0200 Subject: [PATCH 1487/4284] udev_test.pl: we replace untrusted chars with '_' Signed-off-by: Kay Sievers --- test/udev-test.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/udev-test.pl b/test/udev-test.pl index e7c00e29e6..44bc483cf1 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -1342,7 +1342,7 @@ EOF devpath => "/block/sda/sda1", exp_name => "replaced", rules => < Date: Mon, 29 Aug 2005 03:48:17 +0200 Subject: [PATCH 1488/4284] check the udevdb before assigning a new %e A second "add" event created a new enumeration with %e. Check the udevdb first and if a matching name is already used. Signed-off-by: Kay Sievers --- udev_rules.c | 61 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 459c27b4d5..7c73356831 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -267,16 +267,58 @@ static int import_parent_into_env(struct udevice *udev, struct sysfs_class_devic return rc; } -/* finds the lowest positive N such that N isn't present in the udevdb - * if doesn't exist, 0 is returned, N otherwise - */ -static int find_free_number(const char *name, const char *devpath) +static int match_name_and_get_number(const char *base, const char *devname) +{ + size_t baselen; + char *endptr; + int num; + + baselen = strlen(base); + if (strncmp(base, devname, baselen) != 0) + return -1; + if (devname[baselen] == '\0') + return 0; + if (!isdigit(devname[baselen])) + return -1; + num = strtoul(&devname[baselen], &endptr, 10); + if (endptr[0] != '\0') + return -1; + return num; +} + +/* finds the lowest positive device number such that N isn't present in the udevdb + * if doesn't exist, 0 is returned, N otherwise */ +static int find_free_number(const char *base, const char *devpath) { char db_devpath[PATH_SIZE]; char filename[PATH_SIZE]; + struct udevice udev_db; int num = 0; - strlcpy(filename, name, sizeof(filename)); + /* check if the device already owns a matching name */ + udev_init_device(&udev_db, NULL, NULL, NULL); + if (udev_db_get_device(&udev_db, devpath) == 0) { + struct name_entry *name_loop; + int devnum; + + devnum = match_name_and_get_number(base, udev_db.name); + if (devnum >= 0) { + num = devnum; + dbg("device '%s', already has the node '%s' with num %u, use it", devpath, base, num); + goto out; + } + list_for_each_entry(name_loop, &udev_db.symlink_list, node) { + devnum = match_name_and_get_number(base, name_loop->name); + if (devnum >= 0) { + num = devnum; + dbg("device '%s', already has a symlink '%s' with num %u, use it", devpath, base, num); + goto out; + } + } + } + + /* just search the database again and again until a free name is found */ + strlcpy(filename, base, sizeof(filename)); while (1) { dbg("look for existing node '%s'", filename); if (udev_db_lookup_name(filename, db_devpath, sizeof(db_devpath)) != 0) { @@ -290,10 +332,12 @@ static int find_free_number(const char *name, const char *devpath) num = -1; break; } - snprintf(filename, sizeof(filename), "%s%d", name, num); + snprintf(filename, sizeof(filename), "%s%d", base, num); filename[sizeof(filename)-1] = '\0'; } +out: + udev_cleanup_device(&udev_db); return num; } @@ -345,12 +389,12 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) while (--loop) { if (stat(filename, &stats) == 0) { - dbg("file appeared after %i loops", (timeout * WAIT_LOOP_PER_SECOND) - loop-1); + info("file appeared after %i loops", (timeout * WAIT_LOOP_PER_SECOND) - loop-1); return 0; } usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } - dbg("waiting for '%s' failed", filename); + info("waiting for '%s' failed", filename); return -1; } @@ -669,6 +713,7 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k 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, struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) { From b581515ce8ab4760ba9a4095a7eb98fa352e02a7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 29 Aug 2005 03:49:40 +0200 Subject: [PATCH 1489/4284] update RELEASE-NOTES Signed-off-by: Kay Sievers --- RELEASE-NOTES | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index ee992d1e60..76d945e2e0 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,11 @@ +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, cause we import untrusted data and +export it to the filesystem. + udev 068 ======== More bugfixes. If udevd was started from the kernel, we don't From 24ca5c3398eb61380e0add8b9ffac1651a008bb3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 29 Aug 2005 15:01:08 +0200 Subject: [PATCH 1490/4284] udevinfo: add database export Signed-off-by: Kay Sievers --- udevinfo.8 | 3 ++ udevinfo.c | 156 ++++++++++++++++++++++++++++------------------------- 2 files changed, 87 insertions(+), 72 deletions(-) diff --git a/udevinfo.8 b/udevinfo.8 index ac8cc7fda5..28904fef47 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -51,6 +51,9 @@ unique attributes to compose a rule. Print the relationship between the devpath and the node name for all devices currently available in the database. .TP +.B \-e +Print all attributes for all devices curently available in the database. +.TP .B \-h Print help text. .SH "FILES" diff --git a/udevinfo.c b/udevinfo.c index c7d801b87c..0089df46b6 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -1,7 +1,7 @@ /* - * udevinfo.c - fetches attributes for a device + * udevinfo.c - fetches stored device information or sysfs attributes * - * Copyright (C) 2004 Kay Sievers + * 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 @@ -80,7 +80,7 @@ static void print_all_attributes(struct dlist *attr_list) printf("\n"); } -static int print_record(struct udevice *udev) +static void print_record(struct udevice *udev) { struct name_entry *name_loop; @@ -90,8 +90,6 @@ static int print_record(struct udevice *udev) printf("S: %s\n", name_loop->name); list_for_each_entry(name_loop, &udev->env_list, node) printf("E: %s\n", name_loop->name); - - return 0; } static int print_device_chain(const char *path) @@ -124,6 +122,7 @@ static int print_device_chain(const char *path) /* open sysfs class device directory and print all attributes */ printf(" looking at class device '%s':\n", class_dev->path); + printf(" KERNEL==\"%s\"\n", class_dev->name); printf(" SUBSYSTEM==\"%s\"\n", class_dev->classname); attr_list = sysfs_get_classdev_attributes(class_dev); @@ -167,7 +166,16 @@ exit: return retval; } -static void dump_names(void) { +static void dump_name_devpath(struct udevice *udev) { + printf("%s=%s/%s\n", udev->devpath, udev_root, udev->name); +} + +static void dump_record(struct udevice *udev) { + print_record(udev); + printf("\n"); +} + +static void dump_db(void fnct(struct udevice *udev)) { LIST_HEAD(name_list); struct name_entry *name_loop; @@ -177,19 +185,48 @@ static void dump_names(void) { udev_init_device(&udev_db, NULL, NULL, NULL); if (udev_db_get_device(&udev_db, name_loop->name) == 0) - printf("%s=%s/%s\n", udev_db.devpath, udev_root, udev_db.name); + fnct(&udev_db); udev_cleanup_device(&udev_db); } name_list_cleanup(&name_list); } +static void print_help(void) +{ + fprintf(stderr, "Usage: udevinfo [-anpqrVh]\n" + " -q TYPE 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" + " -p PATH sysfs device path used for query or chain\n" + " -n NAME node/symlink name used for query\n" + "\n" + " -r print udev root\n" + " -a print all SYSFS_attributes along the device chain\n" + " -d print the relationship of devpath and the node name for all\n" + " -e print the content of the udev database\n" + " -V print udev version\n" + " -h print this help text\n" + "\n"); +} + int main(int argc, char *argv[], char *envp[]) { - static const char short_options[] = "adn:p:q:rVh"; + static const char short_options[] = "aden:p:q:rVh"; int option; struct udevice udev; int root = 0; - int attributes = 0; + + enum action_type { + ACTION_NONE, + ACTION_QUERY, + ACTION_ATTRIBUTE_WALK, + ACTION_ROOT, + } action = ACTION_NONE; + enum query_type { QUERY_NONE, QUERY_NAME, @@ -198,6 +235,7 @@ int main(int argc, char *argv[], char *envp[]) QUERY_ENV, QUERY_ALL, } query = QUERY_NONE; + char path[PATH_SIZE] = ""; char name[PATH_SIZE] = ""; char temp[PATH_SIZE]; @@ -222,70 +260,65 @@ int main(int argc, char *argv[], char *envp[]) dbg("udev name: %s\n", optarg); strlcpy(name, optarg, sizeof(name)); break; - case 'p': dbg("udev path: %s\n", optarg); strlcpy(path, optarg, sizeof(path)); break; - case 'q': dbg("udev query: %s\n", optarg); - + 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"); - retval = 1; + retval = 2; goto exit; - case 'r': + if (action == ACTION_NONE) + action = ACTION_ROOT; root = 1; break; - case 'a': - attributes = 1; + action = ACTION_ATTRIBUTE_WALK; break; - case 'd': - dump_names(); + dump_db(dump_name_devpath); + goto exit; + case 'e': + dump_db(dump_record); goto exit; - case 'V': printf("udevinfo, version %s\n", UDEV_VERSION); goto exit; - case 'h': - retval = 2; case '?': default: - goto help; + print_help(); + goto exit; } } - /* process options */ - if (query != QUERY_NONE) { + /* run action */ + switch (action) { + case ACTION_QUERY: + /* need devpath or node/symlink name for query */ if (path[0] != '\0') { /* remove sysfs_path if given */ if (strncmp(path, sysfs_path, strlen(sysfs_path)) == 0) { @@ -303,12 +336,10 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_db_get_device(&udev, pos); if (retval != 0) { fprintf(stderr, "no record for '%s' in database\n", pos); + retval = 3; goto exit; } - goto print; - } - - if (name[0] != '\0') { + } else if (name[0] != '\0') { char devpath[PATH_SIZE]; int len; @@ -322,24 +353,23 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_db_lookup_name(pos, devpath, sizeof(devpath)); if (retval != 0) { fprintf(stderr, "no record for '%s' in database\n", pos); + retval = 3; goto exit; } udev_db_get_device(&udev, devpath); - goto print; + } else { + fprintf(stderr, "query needs device path(-p) or node name(-n) specified\n"); + retval = 4; + goto exit; } - fprintf(stderr, "query needs device path(-p) or node name(-n) specified\n"); - retval = 3; - goto exit; - -print: switch(query) { case QUERY_NAME: if (root) printf("%s/%s\n", udev_root, udev.name); else printf("%s\n", udev.name); - goto exit; + break; case QUERY_SYMLINK: if (list_empty(&udev.symlink_list)) goto exit; @@ -350,23 +380,23 @@ print: list_for_each_entry(name_loop, &udev.symlink_list, node) printf("%s ", name_loop->name); printf("\n"); - goto exit; + break; case QUERY_PATH: printf("%s\n", udev.devpath); goto exit; case QUERY_ENV: list_for_each_entry(name_loop, &udev.env_list, node) printf("%s\n", name_loop->name); - goto exit; + break; case QUERY_ALL: print_record(&udev); - goto exit; + break; default: - goto help; + print_help(); + break; } - } - - if (attributes) { + break; + case ACTION_ATTRIBUTE_WALK: if (path[0] == '\0') { fprintf(stderr, "attribute walk on device chain needs path(-p) specified\n"); retval = 4; @@ -379,35 +409,17 @@ print: strlcpy(path, temp, sizeof(temp)); } print_device_chain(path); - goto exit; } - } - - if (root) { + break; + case ACTION_ROOT: printf("%s\n", udev_root); - goto exit; + break; + default: + print_help(); + retval = 1; + break; } -help: - fprintf(stderr, "Usage: udevinfo [-anpqrVh]\n" - " -q TYPE 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" - " -p PATH sysfs device path used for query or chain\n" - " -n NAME node/symlink name used for query\n" - "\n" - " -r print udev root\n" - " -a print all SYSFS_attributes along the device chain\n" - " -d print the relationship of devpath and the node name for all\n" - " devices available in the database\n" - " -V print udev version\n" - " -h print this help text\n" - "\n"); - exit: udev_cleanup_device(&udev); logging_close(); From 420a506ef00b011ddb50249c0c53c07cbc37e04c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 30 Aug 2005 04:41:42 +0200 Subject: [PATCH 1491/4284] write man page masters in DocBook XML The troff man pages will still be checked into the tree but the source is DocBook XML format living in the docs/ directory now. Start with the easy ones, the main udev page is still left to rewrite. Signed-off-by: Kay Sievers --- Makefile | 23 +++++--- docs/udevd.xml | 99 ++++++++++++++++++++++++++++++++ docs/udevinfo.xml | 131 +++++++++++++++++++++++++++++++++++++++++++ docs/udevmonitor.xml | 76 +++++++++++++++++++++++++ docs/udevstart.xml | 62 ++++++++++++++++++++ docs/udevtest.xml | 62 ++++++++++++++++++++ udev.8.in => udev.8 | 0 udevd.8 | 80 +++++++++++++------------- udevinfo.8 | 107 ++++++++++++++++------------------- udevstart.8 | 36 +++++++----- udevtest.8 | 39 +++++++------ 11 files changed, 577 insertions(+), 138 deletions(-) create mode 100644 docs/udevd.xml create mode 100644 docs/udevinfo.xml create mode 100644 docs/udevmonitor.xml create mode 100644 docs/udevstart.xml create mode 100644 docs/udevtest.xml rename udev.8.in => udev.8 (100%) diff --git a/Makefile b/Makefile index 8f99330967..1e6dd55ee9 100644 --- a/Makefile +++ b/Makefile @@ -158,6 +158,13 @@ OBJS = \ SYSFS = $(PWD)/libsysfs/sysfs.a +MAN_PAGES = \ + udevmonitor.8 \ + udevd.8 \ + udevtest.8 \ + udevinfo.8 \ + udevstart.8 + CFLAGS += -I$(PWD)/libsysfs/sysfs \ -I$(PWD)/libsysfs @@ -262,11 +269,9 @@ udev_version.h: $(LOCAL_CFG_DIR)/udev.conf: sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ -GEN_MANPAGES = udev.8 -GEN_MANPAGESIN = udev.8.in -# Rules on how to create the man pages -$(GEN_MANPAGES): $(GEN_MANPAGESIN) - sed -e "s:@udevdir@:$(udevdir):" < $@.in > $@ +# man pages +%.8: docs/%.xml + xmlto man $? $(UDEV_OBJS): $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(SYSFS_OBJS): $(HEADERS) $(HOST_PROGS) $(KLCC) @@ -283,7 +288,7 @@ $(CONTROL).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(MONITOR).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) $(STARTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(GEN_MANPAGES) +$(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(MAN_PAGES) $(QUIET) $(LD) $(LDFLAGS) -o $@ $(ROOT).o $(OBJS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ @@ -333,7 +338,7 @@ $(STARTER): $(KLCC) $(STARTER).o $(OBJS) clean: -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(GEN_MANPAGES) $(INFO) $(DAEMON) \ + -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(INFO) $(DAEMON) \ $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) $(MONITOR) $(TESTER) $(STARTER) -rm -f ccdv $(MAKE) -C klibc SUBDIRS=klibc clean @@ -369,7 +374,9 @@ install-man: $(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8 $(INSTALL_DATA) -D udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 + $(INSTALL_DATA) -D udevmonitor.8 $(DESTDIR)$(mandir)/man8/udevmonitor.8 - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 + - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8 uninstall-man: - rm $(mandir)/man8/udev.8 @@ -377,7 +384,9 @@ uninstall-man: - rm $(mandir)/man8/udevtest.8 - rm $(mandir)/man8/udevstart.8 - rm $(mandir)/man8/udevd.8 + - rm $(mandir)/man8/udevmonitor.8 - rm $(mandir)/man8/udevsend.8 + - rm $(mandir)/man8/udevcontrol.8 install: install-config install-man all $(INSTALL) -d $(DESTDIR)$(udevdir) diff --git a/docs/udevd.xml b/docs/udevd.xml new file mode 100644 index 0000000000..eeaec4402f --- /dev/null +++ b/docs/udevd.xml @@ -0,0 +1,99 @@ + + + +
    + + xmlto + + Kay + Sievers + kay.sievers@vrfy.org + + + 2005 + Kay Sievers + + + +
    + udevd, udevsend, udevcontrol + + + udevd + August 2005 + udev + + + + udevd + 8 + + + + udevdevent managing daemon + + + + + udevd + + + + udevcontrol command + + + udevsend subsystem + + + + 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. + + + + + + udevcontrol can dynamically set the log level of udevd. + Valid values are the numerical syslog priorities or their textual + representations: err, info and debug. + + + + + + udevcontrol stops the execution of events from udevd. + + + + + + udevcontrol starts the execution of events from udevd. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev8 + + + +
    +
    diff --git a/docs/udevinfo.xml b/docs/udevinfo.xml new file mode 100644 index 0000000000..b8ced7f174 --- /dev/null +++ b/docs/udevinfo.xml @@ -0,0 +1,131 @@ + + + +
    + + xmlto + + Kay + Sievers + kay.sievers@vrfy.org + + + 2005 + Kay Sievers + + + +
    + udevinfo + + + udevinfo + August 2005 + udev + + + + udevinfo + 8 + + + + udevinfoquery device information from the udev database + + + + + udevinfo + + + + + + + + + + + + DESCRIPTION + udevinfo queries the udev database for device information + stored in the udev database. udevinfo also queries the properties + of a device from its sysfs representation to help creating udev + rules to 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. + + + + + + + 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. + + + + + + + The sysfs path 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. + + + + + + + Export the content of the udev database. + + + + + + + Print help text. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev8 + + + +
    +
    diff --git a/docs/udevmonitor.xml b/docs/udevmonitor.xml new file mode 100644 index 0000000000..6f1e347f84 --- /dev/null +++ b/docs/udevmonitor.xml @@ -0,0 +1,76 @@ + + + +
    + + xmlto + + Kay + Sievers + kay.sievers@vrfy.org + + + 2005 + Kay Sievers + + + +
    + 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 send out by a udev rule + and prints the devpath of the event to the console. It can be used analyze to the + event timing by comparing the timestamps of the kernel uevent with 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. + + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev8 + + + +
    +
    diff --git a/docs/udevstart.xml b/docs/udevstart.xml new file mode 100644 index 0000000000..f917287086 --- /dev/null +++ b/docs/udevstart.xml @@ -0,0 +1,62 @@ + + + +
    + + xmlto + + Kay + Sievers + kay.sievers@vrfy.org + + + 2005 + Kay Sievers + + + +
    + 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 + + udev8 + + + +
    +
    diff --git a/docs/udevtest.xml b/docs/udevtest.xml new file mode 100644 index 0000000000..ceea0413c5 --- /dev/null +++ b/docs/udevtest.xml @@ -0,0 +1,62 @@ + + + +
    + + xmlto + + Kay + Sievers + kay.sievers@vrfy.org + + + 2005 + Kay Sievers + + + +
    + udevtest + + + udevtest + August 2005 + udev + + + + udevtest + 8 + + + + udevtest + simulate a udev run and print the action to the console + + + + + udevtest device-path subsystem + + + + 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 renamend. + + + AUTHOR + Written by Greg Kroah-Hartman greg@kroah.com. + + + + SEE ALSO + + udev8 + + + +
    +
    diff --git a/udev.8.in b/udev.8 similarity index 100% rename from udev.8.in rename to udev.8 diff --git a/udevd.8 b/udevd.8 index 02e2e2c5f8..01b90ccfb3 100644 --- a/udevd.8 +++ b/udevd.8 @@ -1,43 +1,41 @@ -.TH UDEVD 8 "February 2004" "" "Linux Administrator's Manual" -.SH NAME -udevd, udevdsend \- udev event serializer daemon and udev event sender -.SH SYNOPSIS -.BI udevsend +.\" ** You probably do not want to edit this file directly ** +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" Instead of manually editing it, you probably should edit the DocBook XML +.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. +.TH "UDEVD" "8" "August 2005" "udev" "udevd, udevsend, 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] +.HP 20 +\fBudevcontrol \fR\fB\fIcommand\fR\fR +.HP 19 +\fBudevsend \fR\fB\fIsubsystem\fR\fR .SH "DESCRIPTION" -.B udevd -allows the serialization of -.BR hotplug (8) -events. The events generated by the kernel may arrive in random order -in userspace, that makes it neccessary to reorder them. -.br -.B udevd -takes care of the kernel supplied -.B SEQNUM -sequence number and arranges the events for execution in the correct order. -Missing sequences delay the execution of the following events until a timeout -is reached. Events without any sequence number are bypassing the queue and -will be executed immediately. -.br -For each event a -.BR udev (8) -instance is executed in the background with the complete environment received -by the hotplug event. All further events for the same device are delayed until -the execution is finished. This way there will never be more than one instance -running for a single device at the same time. -.br -.B udevd -receives the events from -.B udevsend -If -.B udevd -isn't already running, -.B udevsend -will start it. +.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" +.TP +\fB\-\-daemon\fR +Detach and run in the background. +.TP +\fBlog_priority=\fR\fB\fIvalue\fR\fR +udevcontrol can dynamically set the log level of udevd. Valid values are the numerical syslog priorities or their textual representations: err, info and debug. +.TP +\fBstop_exec_queue\fR +udevcontrol stops the execution of events from udevd. +.TP +\fBstart_exec_queue\fR +udevcontrol starts the execution of events from udevd. +.SH "AUTHOR" +.PP +Written by Kay Sievers +. .SH "SEE ALSO" -.BR udev (8), -.BR udevinfo (8), -.BR hotplug (8) -.SH AUTHORS -.B udevd -was developed primarily by Kay Sievers , with much help -from others. +.PP +\fBudev\fR(8) diff --git a/udevinfo.8 b/udevinfo.8 index 28904fef47..d8f7bbe629 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -1,69 +1,60 @@ -.TH UDEVINFO 8 "January 2004" "" "Linux Administrator's Manual" -.SH NAME -udevinfo \- retrieve information from udev -.SH SYNOPSIS -.B udevinfo -.RI "[\-q " query_type " \-p " sysfs_path "] [\-drVh]" +.\" ** You probably do not want to edit this file directly ** +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" Instead of manually editing it, you probably should edit the DocBook XML +.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. +.TH "UDEVINFO" "8" "August 2005" "udev" "udevinfo" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevinfo \- query device information from the udev database +.SH "SYNOPSIS" +.HP 9 +\fBudevinfo\fR [\fB\-q\ \fR\fB\fIquery\-type\fR\fR] [\fB\-a\ \fR] [\fB\-p\ \fR\fB\fIdevice\-path\fR\fR] [\fB\-n\ \fR\fB\fInode\-name\fR\fR] [\fB\-r\fR] [\fB\-e\fR] [\fB\-V\fR] [\fB\-h\fR] .SH "DESCRIPTION" -.B udevinfo -allows users to query the udev database for information on any device -currently present on the system. It also provides a way to query any device -in the sysfs tree to help creating -.B udev -rules. +.PP +udevinfo queries the udev database for device information stored in the udev database. udevinfo also queries the properties of a device from its sysfs representation to help creating udev rules to match this device. .SH "OPTIONS" .TP -.B \-V -Print the version information. +\fB\-q\fR +Query the database for specified type of device data. It needs the +\fB\-p\fR +or +\fB\-n\fR +to identify the specified device. Valid queries are: +\fBname\fR, +\fBsymlink\fR, +\fBpath\fR, +\fBenv\fR, +\fBall\fR. .TP -.B \-r -Print the -.B udev_root -directory. When used in conjunction with a query for the node name or the -symlink names, the -.B udev_root -will be prepended to query result. +\fB\-a\fR +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. .TP -.BI \-q " query_type" -Query the database for specified value of a created device node or network -interface. -.RB Needs " \-p " or " \-n " specified. -.br -Valid types are: -.BR name ", " symlink ", " path " or " all. +\fB\-p \fR\fB\fIdevice\-path\fR\fR +The sysfs path of the device to query. .TP -.BI \-p " sysfs_path" -Specify the sysfs path of the device to query. +\fB\-n \fR\fB\fInode\-name\fR\fR +The name of the device node or a symlink to query .TP -.BI \-n " name" -Specify the name of the node, the symlink or the network interface for the -device to query. Partition names generated with the NAME{all_partitons} option -can not be queried, the main device must be used instead. +\fB\-r\fR +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. .TP -.B \-a -Print all -.BI SYSFS{ filename } -attributes along the device chain. Useful for finding -unique attributes to compose a rule. -.RB Needs " \-p " specified. +\fB\-e\fR +Export the content of the udev database. .TP -.B \-d -Print the relationship between the devpath and the node name for all devices -currently available in the database. -.TP -.B \-e -Print all attributes for all devices curently available in the database. -.TP -.B \-h +\fB\-h\fR Print help text. -.SH "FILES" -.nf -/etc/udev/* udev config files -.fi -.LP +.SH "AUTHOR" +.PP +Written by Kay Sievers +. .SH "SEE ALSO" -.BR udev (8) -.SH AUTHORS -.B udevinfo -was developed primarily by Kay Sievers , with help -from others. +.PP +\fBudev\fR(8) diff --git a/udevstart.8 b/udevstart.8 index c64400cc4f..ea7a59ea8b 100644 --- a/udevstart.8 +++ b/udevstart.8 @@ -1,18 +1,24 @@ -.TH UDEVSTART 8 "March 2004" "" "Linux Administrator's Manual" -.SH NAME +.\" ** You probably do not want to edit this file directly ** +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" Instead of manually editing it, you probably should edit the DocBook XML +.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. +.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 -.B udevstart +.SH "SYNOPSIS" +.HP 10 +\fBudevstart\fR .SH "DESCRIPTION" -.B udevstart -walks trough the sysfs device tree and calls -.B udev -to create the nodes for every valid device found. It can be used to fill a -empty device directory with nodes for all devices currently available on -the system. +.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" -.BR udev (8) -.SH AUTHORS -.B udevstart -was developed primarily by Harald Hoyer , with much help -from others. +.PP +\fBudev\fR(8) diff --git a/udevtest.8 b/udevtest.8 index a595a30d41..e547811a8b 100644 --- a/udevtest.8 +++ b/udevtest.8 @@ -1,19 +1,24 @@ -.TH UDEVTEST 8 "March 2004" "" "Linux Administrator's Manual" -.SH NAME -udevtest \- simulates a udev run to test the configured rules -.SH SYNOPSIS -.B udevtest -.I sysfs_device_path subsystem +.\" ** You probably do not want to edit this file directly ** +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" Instead of manually editing it, you probably should edit the DocBook XML +.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. +.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 31 +\fBudevtest \fR\fB\fIdevice\-path\fR\fR\fB \fR\fB\fIsubsystem\fR\fR .SH "DESCRIPTION" -.B udevtest -simulates a -.B udev -run for the given device, and prints out the name of the node -the real udev would have created, or the name of the renamed network -interface. +.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 renamend. +.SH "AUTHOR" +.PP +Written by Greg Kroah\-Hartman +. .SH "SEE ALSO" -.BR udev (8) -.SH AUTHORS -.B udevtest -was developed by Greg Kroah-Hartman with much help -from others. +.PP +\fBudev\fR(8) From ae8cc07b2a954dc55f6cc90eea64f281e3421e76 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 30 Aug 2005 04:56:24 +0200 Subject: [PATCH 1492/4284] udevinfo: rename dump() to export() Signed-off-by: Kay Sievers --- udevinfo.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/udevinfo.c b/udevinfo.c index 0089df46b6..6b368fcfe8 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -166,16 +166,16 @@ exit: return retval; } -static void dump_name_devpath(struct udevice *udev) { +static void export_name_devpath(struct udevice *udev) { printf("%s=%s/%s\n", udev->devpath, udev_root, udev->name); } -static void dump_record(struct udevice *udev) { +static void export_record(struct udevice *udev) { print_record(udev); printf("\n"); } -static void dump_db(void fnct(struct udevice *udev)) { +static void export_db(void fnct(struct udevice *udev)) { LIST_HEAD(name_list); struct name_entry *name_loop; @@ -204,10 +204,9 @@ static void print_help(void) " -p PATH sysfs device path used for query or chain\n" " -n NAME node/symlink name used for query\n" "\n" - " -r print udev root\n" + " -r prepend to query result or print udev_root\n" " -a print all SYSFS_attributes along the device chain\n" - " -d print the relationship of devpath and the node name for all\n" - " -e print the content of the udev database\n" + " -e export the content of the udev database\n" " -V print udev version\n" " -h print this help text\n" "\n"); @@ -215,7 +214,7 @@ static void print_help(void) int main(int argc, char *argv[], char *envp[]) { - static const char short_options[] = "aden:p:q:rVh"; + static const char short_options[] = "aen:p:q:rVh"; int option; struct udevice udev; int root = 0; @@ -299,10 +298,10 @@ int main(int argc, char *argv[], char *envp[]) action = ACTION_ATTRIBUTE_WALK; break; case 'd': - dump_db(dump_name_devpath); + export_db(export_name_devpath); goto exit; case 'e': - dump_db(dump_record); + export_db(export_record); goto exit; case 'V': printf("udevinfo, version %s\n", UDEV_VERSION); From 264ccb68ee070adcb7b38b3a139adf018ba9089e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 30 Aug 2005 05:02:11 +0200 Subject: [PATCH 1493/4284] test the automatic man page rebuild and checkin Signed-off-by: Kay Sievers --- docs/udevinfo.xml | 4 ++-- udevinfo.8 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/udevinfo.xml b/docs/udevinfo.xml index b8ced7f174..d6eecfb70d 100644 --- a/docs/udevinfo.xml +++ b/docs/udevinfo.xml @@ -50,9 +50,9 @@ DESCRIPTION udevinfo queries the udev database for device information - stored in the udev database. udevinfo also queries the properties + stored in the udev database. It can also query the properties of a device from its sysfs representation to help creating udev - rules to match this device. + rules that match this device. OPTIONS diff --git a/udevinfo.8 b/udevinfo.8 index d8f7bbe629..fc7001dc21 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -14,7 +14,7 @@ udevinfo \- query device information from the udev database \fBudevinfo\fR [\fB\-q\ \fR\fB\fIquery\-type\fR\fR] [\fB\-a\ \fR] [\fB\-p\ \fR\fB\fIdevice\-path\fR\fR] [\fB\-n\ \fR\fB\fInode\-name\fR\fR] [\fB\-r\fR] [\fB\-e\fR] [\fB\-V\fR] [\fB\-h\fR] .SH "DESCRIPTION" .PP -udevinfo queries the udev database for device information stored in the udev database. udevinfo also queries the properties of a device from its sysfs representation to help creating udev rules to match this device. +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" .TP \fB\-q\fR From 0e47c219fc5c509f277c9a44f2d29362fff88193 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 30 Aug 2005 17:03:25 +0200 Subject: [PATCH 1494/4284] Makefile: remove all the duplicated rules Signed-off-by: Kay Sievers --- Makefile | 376 +++++++++++++++------------------- extras/ata_id/Makefile | 2 +- extras/cdrom_id/Makefile | 2 +- extras/dasd_id/Makefile | 2 +- extras/firmware/Makefile | 2 +- extras/floppy/Makefile | 2 +- extras/run_directory/Makefile | 2 +- extras/usb_id/Makefile | 2 +- extras/volume_id/Makefile | 5 +- test/simple-build-check.sh | 1 - 10 files changed, 171 insertions(+), 225 deletions(-) diff --git a/Makefile b/Makefile index 1e6dd55ee9..f34befd999 100644 --- a/Makefile +++ b/Makefile @@ -17,46 +17,96 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# Set this to make use of syslog. +VERSION = 068 + +# set this to make use of syslog USE_LOG = true -# Set this to compile-in development debug messages. Pass UDEV_LOG="debug" -# to the executed binary or set the value in the udev configuration file to -# let udev print the debug messages to syslog. +# 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 -# Set this to include Security-Enhanced Linux support. +# include Security-Enhanced Linux support USE_SELINUX = false -# Set this to comile with klibc instead of glibc. +# comile with klibc instead of glibc USE_KLIBC = false -# Set this to create statically linked binaries. +# set this to create statically linked binaries USE_STATIC = false -# To build any of the extras programs, run with: -# make EXTRAS="extras/a extras/b" +# to build any of the extras programs pass: +# make EXTRAS="extras/ extras/" EXTRAS= # make the build silent. Set this to something else to make it noisy again. V=false -VERSION = 068 -ROOT = udev -DAEMON = udevd -SENDER = udevsend -COMPILE = udevrulescompile -INITSENDER = udevinitsend -RECORDER = udeveventrecorder -CONTROL = udevcontrol -MONITOR = udevmonitor -INFO = udevinfo -TESTER = udevtest -STARTER = udevstart -RELEASE_NAME = $(ROOT)-$(VERSION) -LOCAL_CFG_DIR = etc/udev -DESTDIR = -KERNEL_DIR = /lib/modules/${shell uname -r}/build +PROGRAMS = \ + udev \ + udevd \ + udevsend \ + udevrulescompile \ + udevinitsend \ + udeveventrecorder \ + udevcontrol \ + udevmonitor \ + udevinfo \ + udevtest \ + udevstart + +HEADERS = \ + udev.h \ + udev_utils.h \ + udev_rules.h \ + udev_version.h \ + udev_db.h \ + udev_sysfs.h \ + logging.h \ + udev_libc_wrapper.h \ + udev_selinux.h \ + list.h + +UDEV_OBJS = \ + udev_event.o \ + udev_device.o \ + udev_config.o \ + udev_add.o \ + udev_remove.o \ + udev_sysfs.o \ + udev_db.o \ + udev_rules.o \ + udev_rules_parse.o \ + udev_utils.o \ + udev_utils_string.o \ + udev_utils_file.o \ + udev_utils_run.o \ + udev_libc_wrapper.o +LIBUDEV = libudev.a + +MAN_PAGES = \ + udevmonitor.8 \ + udevd.8 \ + udevtest.8 \ + udevinfo.8 \ + udevstart.8 + +SYSFS_OBJS = \ + libsysfs/sysfs_class.o \ + libsysfs/sysfs_device.o \ + libsysfs/sysfs_dir.o \ + libsysfs/sysfs_driver.o \ + libsysfs/sysfs_utils.o \ + libsysfs/dlist.o +LIBSYSFS = libsysfs/libsysfs.a + +# config files automatically generated +GEN_CONFIGS = \ + $(LOCAL_CFG_DIR)/udev.conf + +GEN_HEADERS = \ + udev_version.h # override this to make udev look in a different location for it's config files prefix = @@ -67,18 +117,18 @@ usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev +udevdir = /dev +udevdb = ${udevdir}/.udevdb +LOCAL_CFG_DIR = etc/udev +KERNEL_DIR = /lib/modules/${shell uname -r}/build srcdir = . +DESTDIR = +RELEASE_NAME = udev-$(VERSION) INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} - -# place to put our device nodes -udevdir = /dev -udevdb = ${udevdir}/.udevdb - -# set up PWD so that older versions of make will work with our build. PWD = $(shell pwd) # If you are running a cross compiler, you may want to set this @@ -98,10 +148,10 @@ export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/powerpc/ppc/g'} -# code taken from uClibc to determine the gcc include dir +# determine the gcc include dir GCCINCDIR := ${shell LC_ALL=C $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} -# code taken from uClibc to determine the libgcc.a filename +# determine the libgcc.a filename GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) # check if compiler option is supported @@ -116,55 +166,7 @@ CFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 # use '-Os' optimization if available, else use -O2 OPTFLAGS := $(call cc-supports, -Os, -O2) -HEADERS = \ - udev.h \ - udev_utils.h \ - udev_rules.h \ - udev_version.h \ - udev_db.h \ - udev_sysfs.h \ - logging.h \ - udev_libc_wrapper.h \ - udev_selinux.h \ - list.h - -SYSFS_OBJS = \ - libsysfs/sysfs_class.o \ - libsysfs/sysfs_device.o \ - libsysfs/sysfs_dir.o \ - libsysfs/sysfs_driver.o \ - libsysfs/sysfs_utils.o \ - libsysfs/dlist.o - -UDEV_OBJS = \ - udev_event.o \ - udev_device.o \ - udev_config.o \ - udev_add.o \ - udev_remove.o \ - udev_sysfs.o \ - udev_db.o \ - udev_rules.o \ - udev_rules_parse.o \ - udev_utils.o \ - udev_utils_string.o \ - udev_utils_file.o \ - udev_utils_run.o \ - udev_libc_wrapper.o - -OBJS = \ - udev.a \ - libsysfs/sysfs.a - -SYSFS = $(PWD)/libsysfs/sysfs.a - -MAN_PAGES = \ - udevmonitor.8 \ - udevd.8 \ - udevtest.8 \ - udevinfo.8 \ - udevstart.8 - +# include our local copy of libsysfs CFLAGS += -I$(PWD)/libsysfs/sysfs \ -I$(PWD)/libsysfs @@ -183,8 +185,7 @@ else STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif -# If we are using our version of klibc, then we need to build, link it, and then -# link udev against it statically. Otherwise, use glibc and link dynamically. +# if our own version of klibc is used, we need to build it ifeq ($(strip $(USE_KLIBC)),true) KLIBC_INSTALL = $(PWD)/klibc/.install KLCC = $(KLIBC_INSTALL)/bin/$(CROSS)klcc @@ -213,21 +214,25 @@ else HOST_PROGS= endif -# config files automatically generated -GEN_CONFIGS = $(LOCAL_CFG_DIR)/udev.conf - -all: $(ROOT) $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) $(MONITOR)\ - $(DAEMON) $(COMPILE) $(INFO) $(TESTER) $(STARTER) $(GEN_CONFIGS) $(KLCC) - @extras="$(EXTRAS)" ; for target in $$extras ; do \ - echo $$target ; \ +all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) + @extras="$(EXTRAS)"; for target in $$extras; do \ + echo $$target; \ $(MAKE) prefix=$(prefix) \ LD="$(LD)" \ - SYSFS="$(SYSFS)" \ + LIBUDEV="$(PWD)/$(LIBUDEV)" \ + LIBSYSFS="$(PWD)/$(LIBSYSFS)" \ KERNEL_DIR="$(KERNEL_DIR)" \ QUIET="$(QUIET)" \ - -C $$target $@ ; \ - done ; \ + -C $$target $@; \ + done; +.PHONY: all +$(PROGRAMS): $(HOST_PROGS) $(KLCC) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) + $(QUIET) $(CC) $(CFLAGS) -c -o $@.o $@.c + $(QUIET) $(LD) $(LDFLAGS) -o $@ $@.o $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ + +# our own copy of klibc if KLCC is specified it will not be used $(KLCC): $(MAKE) -j1 -C klibc KRNLSRC=$(KERNEL_DIR) SUBDIRS=klibc TESTS= \ SHLIBDIR=$(KLIBC_INSTALL)/lib \ @@ -236,24 +241,23 @@ $(KLCC): mandir=$(KLIBC_INSTALL)/man all install -find $(KLIBC_INSTALL)/include -name SCCS -print| xargs rm -rf -udev.a: $(UDEV_OBJS) - rm -f $@ +$(UDEV_OBJS): $(KLCC) +$(LIBUDEV): $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS) + @rm -f $@ $(QUIET) $(AR) cq $@ $(UDEV_OBJS) $(QUIET) $(RANLIB) $@ -libsysfs/sysfs.a: $(SYSFS_OBJS) - rm -f $@ +$(SYSFS_OBJS): $(KLCC) +$(LIBSYSFS): $(HOST_PROGS) $(SYSFS_OBJS) + @rm -f $@ $(QUIET) $(AR) cq $@ $(SYSFS_OBJS) $(QUIET) $(RANLIB) $@ -# header files automatically generated -GEN_HEADERS = udev_version.h +# generate config files +$(GEN_CONFIGS): + sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $@.in > $@ -ccdv: - @echo "Building ccdv" - @$(HOSTCC) -O1 ccdv.c -o ccdv - -# Rules on how to create the generated header files +# generate config header file udev_version.h: @echo "Creating udev_version.h" @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ @@ -265,108 +269,50 @@ udev_version.h: @echo \#define UDEV_BIN \"$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(sbindir)/udevd\" >> $@ -# Rules on how to create the generated config files -$(LOCAL_CFG_DIR)/udev.conf: - sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $(LOCAL_CFG_DIR)/udev.conf.in > $@ - # man pages %.8: docs/%.xml xmlto man $? - -$(UDEV_OBJS): $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(SYSFS_OBJS): $(HEADERS) $(HOST_PROGS) $(KLCC) -$(OBJS): $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(ROOT).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(TESTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(INFO).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(DAEMON).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(SENDER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(COMPILE).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(INITSENDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(RECORDER).o: $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(CONTROL).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(MONITOR).o: $(HEADERS) $( $(HEADERS)GEN_HEADERS) $(HOST_PROGS) $(KLCC) -$(STARTER).o: $(HEADERS) $(GEN_HEADERS) $(HOST_PROGS) $(KLCC) - -$(ROOT): $(KLCC) $(ROOT).o $(OBJS) $(HEADERS) $(MAN_PAGES) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(ROOT).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(TESTER): $(KLCC) $(TESTER).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(TESTER).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(INFO): $(KLCC) $(INFO).o $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(INFO).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(DAEMON): $(KLCC) $(DAEMON).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(DAEMON).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(SENDER): $(KLCC) $(SENDER).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(SENDER).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(COMPILE): $(KLCC) $(COMPILE).o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(COMPILE).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(INITSENDER): $(KLCC) $(INITSENDER).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(INITSENDER).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(RECORDER): $(KLCC) $(RECORDER).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(RECORDER).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(CONTROL): $(KLCC) $(CONTROL).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(CONTROL).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(MONITOR): $(KLCC) $(MONITOR).o $(OBJS) udevd.h - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(MONITOR).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ - -$(STARTER): $(KLCC) $(STARTER).o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) -o $@ $(STARTER).o $(OBJS) $(LIB_OBJS) - $(QUIET) $(STRIPCMD) $@ +.PRECIOUS: %.8 .c.o: $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +ccdv: ccdv.c + @$(HOSTCC) -O1 ccdv.c -o ccdv +.SILENT: ccdv + clean: - -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ - | xargs rm -f - -rm -f core $(ROOT) $(GEN_HEADERS) $(GEN_CONFIGS) $(INFO) $(DAEMON) \ - $(SENDER) $(COMPILE) $(INITSENDER) $(RECORDER) $(CONTROL) $(MONITOR) $(TESTER) $(STARTER) - -rm -f ccdv + -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print | xargs rm -f + -rm -f core $(PROGRAMS) $(GEN_HEADERS) $(GEN_CONFIGS) $(MAKE) -C klibc SUBDIRS=klibc clean - @extras="$(EXTRAS)" ; for target in $$extras ; do \ - echo $$target ; \ - $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ - -C $$target $@ ; \ - done ; \ + @extras="$(EXTRAS)"; for target in $$extras; do \ + echo $$target; \ + $(MAKE) prefix=$(prefix) -C $$target $@; \ + done; +.PHONY: clean spotless: clean $(MAKE) -C klibc SUBDIRS=klibc spotless rm -rf klibc/.install +.PHONY: spotless release: spotless git-tar-tree HEAD $(RELEASE_NAME) | gzip -9v > $(RELEASE_NAME).tar.gz @echo "$(RELEASE_NAME).tar.gz created" +.PHONY: release -install-config: +install-config: $(GEN_CONFIGS) $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d @if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \ echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ fi @if [ ! -r $(DESTDIR)$(configdir)/rules.d/50-udev.rules ]; then \ - echo ; \ + echo; \ echo "pick a udev rules file from the etc/udev directory that matches your distribution"; \ - echo ; \ + echo; \ fi +.PHONY: install-config install-man: $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 @@ -377,6 +323,7 @@ install-man: $(INSTALL_DATA) -D udevmonitor.8 $(DESTDIR)$(mandir)/man8/udevmonitor.8 - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8 +.PHONY: install-man uninstall-man: - rm $(mandir)/man8/udev.8 @@ -387,54 +334,55 @@ uninstall-man: - rm $(mandir)/man8/udevmonitor.8 - rm $(mandir)/man8/udevsend.8 - rm $(mandir)/man8/udevcontrol.8 +.PHONY: uninstall-man install: install-config install-man all $(INSTALL) -d $(DESTDIR)$(udevdir) - $(INSTALL_PROGRAM) -D $(ROOT) $(DESTDIR)$(sbindir)/$(ROOT) - $(INSTALL_PROGRAM) -D $(DAEMON) $(DESTDIR)$(sbindir)/$(DAEMON) - $(INSTALL_PROGRAM) -D $(SENDER) $(DESTDIR)$(sbindir)/$(SENDER) - $(INSTALL_PROGRAM) -D $(CONTROL) $(DESTDIR)$(sbindir)/$(CONTROL) - $(INSTALL_PROGRAM) -D $(MONITOR) $(DESTDIR)$(usrsbindir)/$(MONITOR) - $(INSTALL_PROGRAM) -D $(INFO) $(DESTDIR)$(usrbindir)/$(INFO) - $(INSTALL_PROGRAM) -D $(TESTER) $(DESTDIR)$(usrbindir)/$(TESTER) - $(INSTALL_PROGRAM) -D $(STARTER) $(DESTDIR)$(sbindir)/$(STARTER) + $(INSTALL_PROGRAM) -D udev $(DESTDIR)$(sbindir)/udev + $(INSTALL_PROGRAM) -D udevd $(DESTDIR)$(sbindir)/udevd + $(INSTALL_PROGRAM) -D udevsend $(DESTDIR)$(sbindir)/udevsend + $(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 + $(INSTALL_PROGRAM) -D udevstart $(DESTDIR)$(sbindir)/udevstart ifndef DESTDIR - - killall $(DAEMON) + - killall udevd - rm -rf $(udevdb) - - $(sbindir)/$(DAEMON) --daemon + - $(sbindir)/udevd --daemon endif - @extras="$(EXTRAS)" ; for target in $$extras ; do \ - echo $$target ; \ - $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ - -C $$target $@ ; \ - done ; \ + @extras="$(EXTRAS)"; for target in $$extras; do \ + echo $$target; \ + $(MAKE) prefix=$(prefix) -C $$target $@; \ + done; +.PHONY: install uninstall: uninstall-man - rm $(configdir)/rules.d/50-udev.rules - rm $(configdir)/udev.conf - rmdir $(configdir)/rules.d - rmdir $(configdir) - - rm $(sbindir)/$(ROOT) - - rm $(sbindir)/$(DAEMON) - - rm $(sbindir)/$(SENDER) - - rm $(sbindir)/$(INITSENDER) - - rm $(sbindir)/$(RECORDER) - - rm $(sbindir)/$(CONTROL) - - rm $(sbindir)/$(STARTER) - - rm $(usrsbindir)/$(MONITOR) - - rm $(usrbindir)/$(INFO) - - rm $(usrbindir)/$(TESTER) + - rm $(sbindir)/udev + - rm $(sbindir)/udevd + - rm $(sbindir)/udevsend + - rm $(sbindir)/udevinitsend + - rm $(sbindir)/udeveventrecoreder + - rm $(sbindir)/udevcontrol + - rm $(sbindir)/udevstart + - rm $(usrsbindir)/udevmonitor + - rm $(usrbindir)/udevinfo + - rm $(usrbindir)/udevtest - rm -rf $(udevdb) - rmdir $(udevdir) - - killall $(DAEMON) - @extras="$(EXTRAS)" ; for target in $$extras ; do \ - echo $$target ; \ - $(MAKE) prefix=$(prefix) LD="$(LD)" SYSFS="$(SYSFS)" \ - -C $$target $@ ; \ - done ; \ + - killall udevd + @extras="$(EXTRAS)"; for target in $$extras; do \ + echo $$target; \ + $(MAKE) prefix=$(prefix) -C $$target $@; \ + done; +.PHONY: uninstall-man -test: all +test tests: all @ cd test && ./udev-test.pl @ cd test && ./udevstart-test.pl +.PHONY: test tests -tests: test diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index fb45bcca64..eab01ad9ab 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = ata_id.o ../../udev.a +OBJS = ata_id.o $(LIBUDEV) $(OBJS): $(HEADERS) diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index 44c9ba2b08..6ea5f14ec1 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -29,7 +29,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = cdrom_id.o ../../udev.a +OBJS = cdrom_id.o $(LIBUDEV) $(OBJS): $(HEADERS) diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index 3b0a35f75f..f2c0595de0 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = dasd_id.o ../../udev.a +OBJS = dasd_id.o $(LIBUDEV) $(OBJS): $(HEADERS) diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index 913a88db06..343d5295f1 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(PROG).o $(VOLUME_ID_OBJS) ../../udev.a ../../libsysfs/sysfs.a +OBJS = $(PROG).o $(LIBUDEV) $(LIBSYSFS) HEADERS = $(OBJS): $(HEADERS) diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index ab0cd17e58..5380590c9b 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(PROG).o ../../udev.a +OBJS = $(PROG).o $(LIBUDEV) $(OBJS): $(HEADERS) diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 14b4725dae..c1a83e3c0b 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -29,7 +29,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = ../../udev.a ../../libsysfs/sysfs.a +OBJS = $(LIBUDEV) .c.o: $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index 0635e91cc5..4347fba407 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -28,7 +28,7 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(PROG).o $(VOLUME_ID_OBJS) ../../udev.a ../../libsysfs/sysfs.a +OBJS = $(PROG).o $(VOLUME_ID_OBJS) $(LIBUDEV) $(LIBSYSFS) HEADERS = $(OBJS): $(HEADERS) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 0fadbf5b0e..8ca3bd1333 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -31,8 +31,7 @@ INSTALL_SCRIPT = ${INSTALL_PROGRAM} VOLUME_ID_BASE=volume_id include $(VOLUME_ID_BASE)/Makefile.inc -OBJS = vol_id.o $(VOLUME_ID_OBJS) -LIB_OBJS=../../udev.a +OBJS = vol_id.o $(VOLUME_ID_OBJS) $(LIBUDEV) HEADERS = $(VOLUME_ID_HEADERS) $(OBJS): $(HEADERS) @@ -41,7 +40,7 @@ $(OBJS): $(HEADERS) $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< $(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) clean: rm -f $(PROG) $(OBJS) diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 0112ef78e2..ec18e51a0c 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -36,4 +36,3 @@ make all $MAKEOPTS USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRAS" KERNEL_DIR="$KE echo -e "\n\n" make spotless EXTRAS="$EXTRAS" >/dev/null -echo "build test completed successfully" From 7b86ada7d4a6b2597299912964d1b8da3d059691 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 30 Aug 2005 23:30:52 +0200 Subject: [PATCH 1495/4284] all man pages rewritten to use DocBook XML Signed-off-by: Kay Sievers --- Makefile | 4 +- docs/udev.xml | 545 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/udevd.xml | 19 +- udev.8 | 543 ++++++++++++++++++------------------------------ udevd.8 | 14 +- 5 files changed, 773 insertions(+), 352 deletions(-) create mode 100644 docs/udev.xml diff --git a/Makefile b/Makefile index f34befd999..80364c2a7a 100644 --- a/Makefile +++ b/Makefile @@ -86,8 +86,10 @@ UDEV_OBJS = \ LIBUDEV = libudev.a MAN_PAGES = \ + udev.8 \ udevmonitor.8 \ udevd.8 \ + udevsend.8 \ udevtest.8 \ udevinfo.8 \ udevstart.8 @@ -320,8 +322,8 @@ install-man: $(INSTALL_DATA) -D udevtest.8 $(DESTDIR)$(mandir)/man8/udevtest.8 $(INSTALL_DATA) -D udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 + $(INSTALL_DATA) -D udevsend.8 $(DESTDIR)$(mandir)/man8/udevsend.8 $(INSTALL_DATA) -D udevmonitor.8 $(DESTDIR)$(mandir)/man8/udevmonitor.8 - - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevsend.8 - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8 .PHONY: install-man diff --git a/docs/udev.xml b/docs/udev.xml new file mode 100644 index 0000000000..02dcd2586a --- /dev/null +++ b/docs/udev.xml @@ -0,0 +1,545 @@ + + + +
    + + xmlto + + Kay + Sievers + kay.sievers@vrfy.org + + + 2005 + Kay Sievers + + + +
    + udev + + + udev + August 2005 + udev + + + + udev + 8 + + + + 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 form the system. The program + udev itself may be used as an event handler in situations, + where running the daemon is not appropriate, like in initramfs. + + 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 consist 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 and location of the udev database. The default value is + /dev/.udevdb. + + + + + + + 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 configuraton file. Every line in the rules file contains at least + one key value pair. There are two kind of keys, match and assignement 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 consists 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. + + + + + + + Asign 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: + + + + + Match the kernel action name. + + + + + + + Match the kernel device name + + + + + + + Match the kernel devpath. + + + + + + + Match the kernel subsystem name + + + + + + + Match the typ of bus the device is connected to. + + + + + + + Match the kernel driver name. + + + + + + + Match the device number on the bus. + + + + + + + Match against the value of an environment key. Depending on + the specified operation, this key is also used as a assignment. + + + + + + + Match the sysfs attribute value. Up to five values can be specified. + Trailing whitespace is ignored, if the specified match value does not contain + trailing whitespace itself. + + + + + + + Execute external program. The key is true, if the program returns + without exit code zero. The whole event environment is available to the + executed program. The program's output printed to stdout is available for + 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. + 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 a 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 over writes + the compiled-in default value. + + + + + + + Export the key to the environment. Depending on the specified + operation, this key is also used as a match. + + + + + + + Add a program to the list of programs to be executed for a specific + device. + + + + + + + Named label where a GOTO can jump to. + + + + + + + Jumps to the next LABEL with a matching gname + + + + + + + Import the printed result or the content of a file in environment key + format into the event environment. will execute an + external program and read its output. will inport a + text file. If no option is given, udev will determine it from the executable + bit of of the file permissions. + + + + + + + Wait for the specified sysfs file of the device to be created. May be used + to fight agains timing issues wth the kernel. + + + + + + + stops further rules application. No later rules + will have any effect. + will ignore this event completely. + will ignore any later remove event for this + device. This may be useful as a workaround for broken device drivers. + will create device nodes for all available partitions of + a block device. This may be useful for removable media. + + + + + The , , , + and fields support simple + printf-like string substitutions: + + + , + + The kernel name for this device. + + + + + , + + The kernel bus id for this device. + + + + + , + + The kernel number for this device. For example, 'sda3' has + kernel number of '3' + + + + + , + + The devpath of the device. + + + + + , + + The content of a sysfs attribute. + + + + + , + + 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: + + + + + , + + If a device node already exists with the name, the smallest next free + number is used. This can be used to create compatibility symlinks and enumerate + devices of the same type originating from different kernel subsystems. + Note: The use of the enumeration facility is unreliable for events that + request a number at the same time. The use of enumerations in todays setups + where devices can come and go at any time is not recomended. + + + + + , + + The node name of the parent device. + + + + + , + + The udev_root value. + + + + + , + + 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 + + + + ENVIRONMENT + + + + + add or remove signifies + the addition or the removal of a device. + + + + + + + The sysfs devpath without the mountpoint but a leading slash. + + + + + + + The kernel subsystem the device belongs to. + + + + + + + Overrides the syslog priority specified in the config file. + + + + + + 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 + + udev8 + , + + udevinfo8 + , + + udevd8 + , + + udevmonitor8 + + + +
    +
    diff --git a/docs/udevd.xml b/docs/udevd.xml index eeaec4402f..76df707519 100644 --- a/docs/udevd.xml +++ b/docs/udevd.xml @@ -17,7 +17,7 @@
    - udevd, udevsend, udevcontrol + udevd, udevcontrol udevd @@ -42,9 +42,6 @@ udevcontrol command - - udevsend subsystem - DESCRIPTION @@ -66,7 +63,8 @@ udevcontrol can dynamically set the log level of udevd. Valid values are the numerical syslog priorities or their textual - representations: err, info and debug. + representations: , + and . @@ -84,6 +82,17 @@ + ENVIRONMENT + + + + + Overrides the syslog priority specified in the config file. + + + + + AUTHOR Written by Kay Sievers kay.sievers@vrfy.org. diff --git a/udev.8 b/udev.8 index 9dae378086..9b74ae23bf 100644 --- a/udev.8 +++ b/udev.8 @@ -1,394 +1,253 @@ -.TH UDEV 8 "October 2003" "" "Linux Administrator's Manual" -.SH NAME -udev \- Linux configurable dynamic device naming support -.SH SYNOPSIS -.BI udev +.\" ** You probably do not want to edit this file directly ** +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" Instead of manually editing it, you probably should edit the DocBook XML +.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. +.TH "UDEV" "8" "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" -.B udev -provides a dynamic device directory containing only the files for actually -present devices. It creates or removes device node files usually located in -the /dev directory, or it renames network interfaces. -.br -.P -As part of the -.B hotplug -subsystem, -.B udev -is executed if a kernel device is added or removed from the system. -A list of rules is used to match against specific device attributes. -.br -On device addition, -.B udev -matches its configured rules against the available device attributes to -uniquely name the device. -.B udev -maintains its own database for devices present on the system. This database -can be queried for the relationship of the kernel device path and the -name of the device file. -.br -On device removal, -.B udev -queries its database for the name of the device file to be deleted. -.br -After the device node handling, a list of collected programs specific to this -device is executed. +.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 form the system. The program +\fBudev\fR +itself may be used as an event handler in situations, where running the daemon is not appropriate, like in initramfs. +.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" -All -.B udev -configuration files consist of a set of lines of text. All empty -lines or lines beginning with '#' will be ignored. -.P -.B udev -expects its main configuration file at -.IR /etc/udev/udev.conf . -The file consists of a set of variables and values allowing the user to -override default udev values. The following variables can be overridden -in this file: +.PP +All udev configuration files are placed in +\fI/etc/udev/*\fR. Every file consist 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: .TP -.B udev_root -Indicates where to place the device nodes in the filesystem. The default -value is -.IR @udevdir@/ . +\fBudev_root\fR +Specifies where to place the device nodes in the filesystem. The default value is +\fI/dev\fR. .TP -.B udev_db -The name and location of the udev database. The default value is -.IR @udevdir@/.udevdb . +\fBudev_db\fR +The name and location of the udev database. The default value is +\fI/dev/.udevdb\fR. .TP -.B udev_rules -The name of the udev rules file or directory to look for files with the suffix -.IR .rules . -All rule files are read in lexical order. The default value is -.IR /etc/udev/rules.d/ . +\fBudev_rules\fR +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. .TP -.B udev_log -The logging priority which can be set to -.IR "err " , "info " -or the corresponding numerical -.BR syslog (3) -value. -The default value is -.IR err . -.P -.RI "A sample " udev.conf " file might look like this: -.sp -.nf -# Where in the filesystem to place the device nodes -udev_root="@udevdir@" - -# The name and location of the udev database. -udev_db="@udevdir@/.udevdb" - -# The name and location of the udev rules file(s). -udev_rules="@configdir@/rules.d" - -# The syslog(3) priority: "err", "info", or the numerical value. -udev_log="err" -.fi -.P -The rules for device naming are read from the files located in the -.I /etc/udev/rules.d/ -directory, or at the location specified by the -.I udev_rules -value in the -.I /etc/udev/udev.conf -file. -.br -Every line in the rules file defines the mapping between device attributes -and the device name. One or more keys are specified to match a rule with -the current device. If all keys are matching, the rule will be applied and -the name is used to name the device file or the network interface. -.br -If no matching rule is found, the default kernel device name is used. -.P -Every rule consists of a list of comma separated key value fields: -.sp -.IR "key " ,[ "key " ,...] -.P -Each key has the following format: -.sp -.IR "name op value" -.P -There are distinct key operation types, depending on the type of the key, it -does a comparison or an assignment. -.P -Comparison operators are: +\fBudev_log\fR +The logging priority. Valid values are the numerical syslog priorities or their textual representations: +\fBerr\fR, +\fBinfo\fR +and +\fBdebug\fR. +.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 configuraton file. Every line in the rules file contains at least one key value pair. There are two kind of keys, match and assignement 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. +.PP +A rule may consists 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: .TP -.B == +\fB==\fR Compare for equality. .TP -.B != -Compare for non-equality. -.P -Assignment operators are: +\fB!=\fR +Compare for non\-equality. .TP -.B += +\fB=\fR +Asign a value to a key. Keys that represent a list, are reset and only this single value is assigned. +.TP +\fB+=\fR Add the value to a key that holds a list of entries. .TP -.B := -Assign a value to a key finally; disallow any later changes, which -is useful to prevent changes by any later rules. -.TP -.B = -Asign a value to a key. Keys that represent a list, are reset and only this -single value is assigned. While this operator still works inplicitely as -comparison on keys that can't get a value assigned, its usage as an comparison -operator is deprecated. -.P +\fB:=\fR +Assign a value to a key finally; disallow any later changes, which may be used to prevent changes by any later rules. +.PP The following key names can be used to match against device properties: .TP -.B BUS -Match the bus type of the device. -(The sysfs device bus must be able to be determined by a "device" symlink.) -.TP -.B KERNEL -Match the kernel device name. -.TP -.B SUBSYSTEM -Match the kernel subsystem name. -.TP -.B ACTION +\fBACTION\fR Match the kernel action name. .TP -.B DRIVER +\fBKERNEL\fR +Match the kernel device name +.TP +\fBDEVPATH\fR +Match the kernel devpath. +.TP +\fBSUBSYSTEM\fR +Match the kernel subsystem name +.TP +\fBBUS\fR +Match the typ of bus the device is connected to. +.TP +\fBDRIVER\fR Match the kernel driver name. .TP -.B ID -Match the device number on the bus, like PCI bus id. +\fBID\fR +Match the device number on the bus. .TP -.BI SYSFS{ filename } -Match sysfs device attribute like vendor and product id's, USB serial number -or the SCSI disk model number. Up to 5 different sysfs files can be checked, -with all of the values being required to match the rule. -.br -Trailing whitespace characters in the sysfs attribute value are ignored, if -the key doesn't have any trailing whitespace characters by itself. +\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR +Match against the value of an environment key. Depending on the specified operation, this key is also used as a assignment. .TP -.BI ENV{ variable } -Match an environment variable. Up to 5 different environment variables can be -checked, with all of the values being required to match the rule. +\fBSYSFS{\fR\fB\fIfilename\fR\fR\fB}\fR +Match the sysfs attribute value. Up to five values can be specified. Trailing whitespace is ignored, if the specified match value does not contain trailing whitespace itself. .TP -.B PROGRAM -Call external program. This key is valid if the program returns successful. -The environment variables of -.B udev -are also available to the program. -.br -The string returned by the program may be additionally matched with the -.B RESULT -key in the same or any later rule. +\fBPROGRAM\fR +Execute external program. The key is true, if the program returns without exit code zero. The whole event environment is available to the executed program. The program's output printed to stdout is available for the RESULT key. .TP -.B RESULT -Match the returned string of the last -.B PROGRAM -call. This key can be used in the same or in any later rule after a -.B PROGRAM -call. -.P +\fBRESULT\fR +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. +.PP +Most of the fields support a shell style pattern matching. The following pattern characters are supported: +.TP +\fB*\fR +Matches zero, or any number of characters. +.TP +\fB?\fR +Matches any single character. +.TP +\fB[]\fR +Matches any single character specified within the brackets. 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. +.PP The following keys can get values assigned: .TP -.B NAME -The name of the node to be created, or the name, the network interface -should be renamed to. Only one rule can set the a name, all later rules -with a NAME key will be ignored. +\fBNAME\fR +The name of the node to be created, or the name, the network interface should be renamed to. Only one rule can set the a name, all later rules with a NAME key will be ignored. .TP -.B SYMLINK -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. +\fBSYMLINK\fR +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. .TP -.B OWNER, GROUP, MODE -The permissions for the device node. Every specified value overwrites the -compiled-in default value. +\fBOWNER, GROUP, MODE\fR +The permissions for the device node. Every specified value over writes the compiled\-in default value. .TP -.B RUN +\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR +Export the key to the environment. Depending on the specified operation, this key is also used as a match. +.TP +\fBRUN\fR Add a program to the list of programs to be executed for a specific device. .TP -.B OPTIONS -.B last_rule -stops further rules application. No later rules will have any effect. -.sp -.B ignore_device -will ignore this device. No node will be created or program executed. -.sp -.B ignore_remove -will ignore any later remove event for this device. -This may be useful as a workaround for broken device drivers. -.sp -.B all_partitions -will create device nodes for all available partitions of a blockdevice. -This may be useful for removable media devices which do not detect a media -change. -.sp -Multiple attributes may be separated by comma. -.P -.RB "The " NAME ", " SYMLINK ", " PROGRAM ", " OWNER " and " GROUP -fields support simple printf-like string substitutions: +\fBLABEL\fR +Named label where a GOTO can jump to. .TP -.B %n -The "kernel number" of the device. -For example, 'sda3' has a "kernel number" of '3'. +\fBGOTO\fR +Jumps to the next LABEL with a matching gname .TP -.B %k -The "kernel name" for the device. +\fBIMPORT{\fR\fB\fItype\fR\fR\fB}\fR +Import the printed result or the content of a file in environment key format into the event environment. +\fBprogram\fR +will execute an external program and read its output. +\fBfile\fR +will inport a text file. If no option is given, udev will determine it from the executable bit of of the file permissions. .TP -.B %p -The devpath for the device. +\fBWAIT_FOR_SYSFS\fR +Wait for the specified sysfs file of the device to be created. May be used to fight agains timing issues wth the kernel. .TP -.B %M -The kernel major number for the device. +\fBOPTIONS\fR +\fBlast_rule\fR +stops further rules application. No later rules will have any effect. +\fBignore_device\fR +will ignore this event completely. +\fBignore_remove\fR +will ignore any later remove event for this device. This may be useful as a workaround for broken device drivers. +\fBall_partitions\fR +will create device nodes for all available partitions of a block device. This may be useful for removable media. +.PP +The +\fBNAME\fR, +\fBSYMLINK\fR, +\fBPROGRAM\fR, +\fBOWNER\fR +and +\fBGROUP\fR +fields support simple printf\-like string substitutions: .TP -.B %m -The kernel minor number for the device. +\fB%k\fR, \fB$kernel\fR +The kernel name for this device. .TP -.B %b -The bus id for the device. +\fB%b\fR, \fB$id\fR +The kernel bus id for this device. .TP -.B %c -The string returned by the external program, specified in -.B PROGRAM -(This does not work within the -.B PROGRAM -field for the obvious reason.) -.br -A single part of the string, separated by a space character -may be selected by specifying the part number as an attribute: -.BI %c{ N } -If the number is followed by the + char this part plus -all remaining parts of the result string are substituted: -.BI %c{ N+ } +\fB%n\fR, \fB$number\fR +The kernel number for this device. For example, 'sda3' has kernel number of '3' .TP -.B %N -The name of a created temporary device node to provide access to the -device from a external program. +\fB%p\fR, \fB$devpath\fR +The devpath of the device. .TP -.B %P -The node name of the parent device. -.TP -.BI %s{ filename } +\fB%s{\fR\fB\fIfile\fR\fR\fB}\fR, \fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR The content of a sysfs attribute. .TP -.B %r +\fB%e{\fR\fB\fIkey\fR\fR\fB}\fR, \fB$env{\fR\fB\fIkey\fR\fR\fB}\fR +The value of an environment variable. +.TP +\fB%m\fR, \fB$major\fR +The kernel major number for the device. +.TP +\fB%M\fR \fB$minor\fR +The kernel minor number for the device. +.TP +\fB%c\fR, \fB$result\fR +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 +.TP +\fB%e\fR, \fB$enum\fR +If a device node already exists with the name, the smallest next free number is used. This can be used to create compatibility symlinks and enumerate devices of the same type originating from different kernel subsystems. + +Note: The use of the enumeration facility is unreliable for events that request a number at the same time. The use of enumerations in todays setups where devices can come and go at any time is not recomended. +.TP +\fB%P\fR, \fB$parent\fR +The node name of the parent device. +.TP +\fB%r\fR, \fB$root\fR The udev_root value. .TP -.B %e -If a device node already exists with the name, the smallest positive -decimal integer N is substituted such that the resulting name doesn't -match an existing device node. Otherwise nothing is substituted. This -can be used to create compatibility symlinks and enumerate devices of -the same type originating from different kernel subsystems. -.sp -Note: The use of the enumeration facility is unreliable outside of -udevstart where the node creation is serialized and predictable. -The returned numbers rely on the order devices are probed on the -system. If more than one device requests an enumeration for the same -name at the same time, it may be possible that both requests receive the -same name back from the database. The use of enumerations in todays setups -where device can come and go at any time is not recomended. +\fB%N\fR, \fB$tempnode\fR +The name of a created temporary device node to provide access to the device from a external program before the real node is created. .TP -.B %% +\fB%%\fR The '%' character itself. -.P -The count of characters to insert may be limited by specifying -the format length value. For example, '%3s{file}' will only insert -the first three characters of the sysfs attribute. -.P -.RI "A sample " udev.rules " file might look like this:" -.sp -.nf -# if /sbin/scsi_id returns "OEM 0815", the device will be called disk1 -BUS=="scsi", PROGRAM=="/sbin/scsi_id", RESULT=="OEM 0815", NAME="disk1" - -# USB printer to be called lp_color -BUS=="usb", SYSFS{serial}=="W09090207101241330", NAME="lp_color" - -# SCSI disk with a specific vendor and model number will be called boot -BUS=="scsi", SYSFS{vendor}=="IBM", SYSFS{model}=="ST336", NAME="boot%n" - -# sound card with PCI bus id 00:0b.0 to be called dsp -BUS=="pci", ID=="00:0b.0", NAME="dsp" - -# USB mouse at third port of the second hub to be called mouse1 -BUS=="usb", ID=="2.3", NAME="mouse1" - -# ttyUSB1 should always be called pda with two additional symlinks -KERNEL=="ttyUSB1", NAME="pda", SYMLINK="palmtop handheld" - -# multiple USB webcams with symlinks to be called webcam0, webcam1, ... -BUS=="usb", SYSFS{model}=="XV3", NAME=="video%n", SYMLINK="webcam%n" -.fi -.P -A number of different fields in the above configuration files support a simple -form of shell style pattern matching. It supports the following pattern characters: .TP -.B * -Matches zero, one, or more characters. -.TP -.B ? -Matches any single character, but does not match zero characters. -.TP -.B [ ] -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. -.P -After device node creation, removal, or network device renaming, -.B udev -executes the programs specified by the -.B RUN -key. -.br -In addition to the kernel provided hotplug environment variables, -.B UDEV_LOG -is set and contains the numerical priority value, if udev is configured to use -.BR syslog (3). -Executed programs may want to follow that setting. -.B DEVNAME -is exported to make the name of the created node, or the name the network -device is renamed to, available to the executed programs. +\fB$$\fR +The '$' character itself. +.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 "ENVIRONMENT" -.P -The following variables are read from the environment: .TP -.B ACTION -.IR add " or " remove +\fBACTION\fR +\fIadd\fR +or +\fIremove\fR signifies the addition or the removal of a device. .TP -.B DEVPATH -The sysfs devpath of the device without the mountpoint but a leading slash. +\fBDEVPATH\fR +The sysfs devpath without the mountpoint but a leading slash. .TP -.B SUBSYSTEM -The subsystem the device belongs to. Alternatively the subsystem may -be passed as the first argument. +\fBSUBSYSTEM\fR +The kernel subsystem the device belongs to. .TP -.B UDEV_CONFIG_FILE -Overrides the default location of the -.B udev -config file. -.TP -.B UDEV_LOG -Overrides the log priority specified in the config file. -.TP -.B UDEV_RUN -If set to "0", it disables the execution of programs added by rules. -.SH "FILES" -.nf -/sbin/udev udev program -/etc/udev/* udev config files -.fi -.SH "SEE ALSO" -.BR udevinfo (8), -.BR udevd (8), +\fBUDEV_LOG\fR +Overrides the syslog priority specified in the config file. +.SH "AUTHOR" .PP -.B Web resources: -.nf -.I http://www.kernel.org/pub/linux/utils/kernel/hotplug/udev.html -.I http://linux\-hotplug.sourceforge.net/ -.fi -.SH AUTHORS -.B udev -was developed by Greg Kroah-Hartman with much help from -Dan Stekloff , Kay Sievers , and -many others. +Written by Greg Kroah\-Hartman + +and Kay Sievers +. With much help from Dan Stekloff + +and many others. +.SH "SEE ALSO" +.PP +\fBudev\fR(8), +\fBudevinfo\fR(8), +\fBudevd\fR(8), +\fBudevmonitor\fR(8) diff --git a/udevd.8 b/udevd.8 index 01b90ccfb3..c6efe9a03a 100644 --- a/udevd.8 +++ b/udevd.8 @@ -2,7 +2,7 @@ .\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. -.TH "UDEVD" "8" "August 2005" "udev" "udevd, udevsend, udevcontrol" +.TH "UDEVD" "8" "August 2005" "udev" "udevd, udevcontrol" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -14,8 +14,6 @@ udevd \- event managing daemon \fBudevd\fR [\fB\-\-daemon\fR] .HP 20 \fBudevcontrol \fR\fB\fIcommand\fR\fR -.HP 19 -\fBudevsend \fR\fB\fIsubsystem\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. @@ -25,13 +23,21 @@ udevd listens to kernel uevents and passes the incoming events to udev. It ensur Detach and run in the background. .TP \fBlog_priority=\fR\fB\fIvalue\fR\fR -udevcontrol can dynamically set the log level of udevd. Valid values are the numerical syslog priorities or their textual representations: err, info and debug. +udevcontrol can dynamically set the log level of udevd. Valid values are the numerical syslog priorities or their textual representations: +\fBerr\fR, +\fBinfo\fR +and +\fBdebug\fR. .TP \fBstop_exec_queue\fR udevcontrol stops the execution of events from udevd. .TP \fBstart_exec_queue\fR udevcontrol starts the execution of events from udevd. +.SH "ENVIRONMENT" +.TP +\fBUDEV_LOG\fR +Overrides the syslog priority specified in the config file. .SH "AUTHOR" .PP Written by Kay Sievers From 0599b4a25fdeffd7eb3acbd4c9783f40fa70f759 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 31 Aug 2005 00:00:22 +0200 Subject: [PATCH 1496/4284] add missing udevsend man page Signed-off-by: Kay Sievers --- docs/udevsend.xml | 90 +++++++++++++++++++++++++++++++++++++++++++++++ udevsend.8 | 38 ++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 docs/udevsend.xml create mode 100644 udevsend.8 diff --git a/docs/udevsend.xml b/docs/udevsend.xml new file mode 100644 index 0000000000..aa76eea845 --- /dev/null +++ b/docs/udevsend.xml @@ -0,0 +1,90 @@ + + + +
    + + xmlto + + Kay + Sievers + kay.sievers@vrfy.org + + + 2005 + Kay Sievers + + + +
    + udevsend + + + udevsend + August 2005 + udev + + + + udevsend + 8 + + + + udevsend + send the current environment to the udev daemon + + + + + udevsend + + + + DESCRIPTION + Usually the udev daemon listens directly to the kernel uevents. + udevsend may be used to pass events for already existing devices from + a userspace application to the daemon. + + + ENVIRONMENT + + + + + add or remove signifies + the addition or the removal of a device. + + + + + + + The sysfs devpath without the mountpoint but a leading slash. + + + + + + + The kernel subsystem the device belongs to. + + + + + AUTHOR + Written by Kay Sievers kay.sievers@vrfy.org. + + + + SEE ALSO + + udev8 + , + + udevd8 + + + +
    +
    diff --git a/udevsend.8 b/udevsend.8 new file mode 100644 index 0000000000..d483f22133 --- /dev/null +++ b/udevsend.8 @@ -0,0 +1,38 @@ +.\" ** You probably do not want to edit this file directly ** +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" Instead of manually editing it, you probably should edit the DocBook XML +.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. +.TH "UDEVSEND" "8" "August 2005" "udev" "udevsend" +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.SH "NAME" +udevsend \- send the current environment to the udev daemon +.SH "SYNOPSIS" +.HP 9 +\fBudevsend\fR +.SH "DESCRIPTION" +.PP +Usually the udev daemon listens directly to the kernel uevents. udevsend may be used to pass events for already existing devices from a userspace application to the daemon. +.SH "ENVIRONMENT" +.TP +\fBACTION\fR +\fIadd\fR +or +\fIremove\fR +signifies the addition or the removal of a device. +.TP +\fBDEVPATH\fR +The sysfs devpath without the mountpoint but a leading slash. +.TP +\fBSUBSYSTEM\fR +The kernel subsystem the device belongs to. +.SH "AUTHOR" +.PP +Written by Kay Sievers +. +.SH "SEE ALSO" +.PP +\fBudev\fR(8), +\fBudevd\fR(8) From f336ff8003a547f162bfc27ad6fe6417a9035fed Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 31 Aug 2005 00:03:20 +0200 Subject: [PATCH 1497/4284] also forgot udevmonitor.8 Signed-off-by: Kay Sievers --- udevmonitor.8 | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 udevmonitor.8 diff --git a/udevmonitor.8 b/udevmonitor.8 new file mode 100644 index 0000000000..6f60130cc7 --- /dev/null +++ b/udevmonitor.8 @@ -0,0 +1,28 @@ +.\" ** You probably do not want to edit this file directly ** +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" Instead of manually editing it, you probably should edit the DocBook XML +.\" source for it and then use the DocBook XSL Stylesheets to regenerate it. +.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\-\-env\fR] +.SH "DESCRIPTION" +.PP +udevmonitor listens to the kernel uevents and events send out by a udev rule and prints the devpath of the event to the console. It can be used analyze to the event timing by comparing the timestamps of the kernel uevent with the udev event. +.SH "OPTIONS" +.TP +\fB\-\-env\fR +Print the complete environment for all events. Can be used to compare the kernel supplied and the udev added environment values. +.SH "AUTHOR" +.PP +Written by Kay Sievers +. +.SH "SEE ALSO" +.PP +\fBudev\fR(8) From 7b4f33ce60246ad1ba518cf054ec3322ea6f9954 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 31 Aug 2005 02:35:35 +0200 Subject: [PATCH 1498/4284] udevinfo: restore -d option Signed-off-by: Kay Sievers --- udevinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevinfo.c b/udevinfo.c index 6b368fcfe8..b668655f29 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -214,7 +214,7 @@ static void print_help(void) int main(int argc, char *argv[], char *envp[]) { - static const char short_options[] = "aen:p:q:rVh"; + static const char short_options[] = "aden:p:q:rVh"; int option; struct udevice udev; int root = 0; From 7596a562988b45b62dcac6daac3663524cc8f930 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 31 Aug 2005 23:36:25 +0200 Subject: [PATCH 1499/4284] scsi_id: rename SYSFS to LIBSYSFS Signed-off-by: Kay Sievers --- extras/scsi_id/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 24c1b32128..3c38d6171e 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -31,7 +31,7 @@ INSTALL_DATA = ${INSTALL} -m 644 CFLAGS+=-Wall -fno-builtin PROG=scsi_id -SYSFS=-lsysfs +LIBSYSFS=-lsysfs # # Built static and stripped when built with udev. @@ -76,5 +76,5 @@ spotless: clean $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< $(PROG): $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(SYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(LIBSYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) From 077ed27c55a9ea661262d7b3ec8be184445ab82e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 6 Sep 2005 12:18:04 +0200 Subject: [PATCH 1500/4284] add edd_id tool to match BIOS EDD disk information Thanks to: John Hull Matt Domsch Signed-off-by: Kay Sievers --- extras/edd_id/Makefile | 50 ++++++++++ extras/edd_id/edd_id.c | 184 +++++++++++++++++++++++++++++++++++++ test/simple-build-check.sh | 1 + 3 files changed, 235 insertions(+) create mode 100644 extras/edd_id/Makefile create mode 100644 extras/edd_id/edd_id.c diff --git a/extras/edd_id/Makefile b/extras/edd_id/Makefile new file mode 100644 index 0000000000..627884a329 --- /dev/null +++ b/extras/edd_id/Makefile @@ -0,0 +1,50 @@ +# Makefile for edd_id +# +# 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. +# + +PROG = edd_id + +all: $(PROG) + +prefix = +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin +mandir = ${prefix}/usr/share/man +devddir = ${etcdir}/dev.d/default +configdir = ${etcdir}/udev/ +initdir = ${etcdir}/init.d/ +srcdir = . + +INSTALL = /usr/bin/install -c +INSTALL_PROGRAM = ${INSTALL} +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} + +OBJS = $(PROG).o $(LIBUDEV) + +$(OBJS): $(HEADERS) + +.c.o: + $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< + +$(PROG): $(OBJS) $(HEADERS) + $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) + +clean: + rm -f $(PROG) $(OBJS) + +spotless: clean + +install: all + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +uninstall: + - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/edd_id/edd_id.c b/extras/edd_id/edd_id.c new file mode 100644 index 0000000000..504aac36e6 --- /dev/null +++ b/extras/edd_id/edd_id.c @@ -0,0 +1,184 @@ +/* + * 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 "../../logging.h" +#include "../../udev_utils.h" + +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) +{ + va_list args; + static int udev_log = -1; + + if (udev_log == -1) { + const char *value; + + value = getenv("UDEV_LOG"); + if (value) + udev_log = log_priority(value); + else + udev_log = LOG_ERR; + } + + if (priority > udev_log) + return; + + va_start(args, format); + vsyslog(priority, format, args); + va_end(args); +} +#endif + +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; + + 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) { + err("no node specified"); + fprintf(stderr, "no node specified\n"); + goto exit; + } + + /* check for kernel support */ + dir = opendir("/sys/firmware/edd"); + if (!dir) { + 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); + if (disk_id == sysfs_id) { + if (export) + printf("ID_EDD=%s\n", dent->d_name); + else + printf("%s\n", dent->d_name); + rc = 0; + break; + } + } + +close: + close(disk_fd); +closedir: + closedir(dir); +exit: + logging_close(); + return rc; +} diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index ec18e51a0c..27e5c93d90 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -8,6 +8,7 @@ EXTRAS="\ extras/usb_id \ extras/dasd_id \ extras/cdrom_id \ + extras/edd_id \ extras/floppy \ extras/run_directory \ extras/firmware" From 3ce0d7b202ecb6896fe2ee5dd7b0c090ca675760 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 6 Sep 2005 20:33:59 +0200 Subject: [PATCH 1501/4284] move and update libsysfs.txt Signed-off-by: Kay Sievers --- etc/udev/suse/udev.rules | 10 +- {docs => libsysfs}/libsysfs.txt | 713 ++++++++++++++++++++++---------- 2 files changed, 498 insertions(+), 225 deletions(-) rename {docs => libsysfs}/libsysfs.txt (73%) diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/udev.rules index 1ed2c6cd50..51d182a307 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/udev.rules @@ -50,6 +50,10 @@ SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8005/*", RUN+="/sbin/startp SUBSYSTEM=="sound", KERNEL=="controlC?", RUN+="/usr/sbin/alsactl -F restore %n" SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVER=="EMU10K1_Audigy", RUN+="/etc/alsa.d/udev-soundfont" +# Kino jogshuttle support +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="b33/10/*", RUN+="/usr/bin/killall --quiet -USR2 kino" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="5f3/240/*", RUN+="/usr/bin/killall --quiet -USR2 kino" + # input devices KERNEL=="mice", NAME="input/%k", MODE="0640" KERNEL=="mouse*", NAME="input/%k", MODE="0640" @@ -57,9 +61,8 @@ KERNEL=="event*", NAME="input/%k", MODE="0640" KERNEL=="js*", NAME="input/%k", MODE="0644" KERNEL=="ts*", NAME="input/%k", MODE="0600" KERNEL=="uinput", NAME="input/%k", MODE="0600" -KERNEL=="event*", PROGRAM="/sbin/udev.get_input_lirc.sh %k", RESULT="*IR*", NAME="input/%k", SYMLINK+="input/ir" KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" -SUBSYSTEM=="input_device", RUN+="/etc/hotplug.d/input_device/50-input_device.hotplug" +SUBSYSTEM=="input_device", RUN+="/sbin/udev.input_device.sh" # printer SUBSYSTEM=="usb", KERNEL=="lp*", ACTION=="add", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" @@ -208,6 +211,8 @@ 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}" LABEL="persistent_end" +SUBSYSTEM=="block", KERNEL=="sd*[0-9]|hd*[0-9]", ACTION=="add", RUN+="/sbin/udev.mount.sh" + # network devices KERNEL=="tun", NAME="net/%k", MODE="0600" SUBSYSTEM=="net", ACTION=="add", RUN+="/sbin/ifup $env{INTERFACE} -o hotplug" @@ -222,6 +227,7 @@ SUBSYSTEM=="firmware", ACTION=="add", RUN+="/sbin/udev.firmware.sh" # SUSE system integration SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" +SUBSYSTEM=="macio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-/sys%p -o hotplug" LABEL="after_usb_default" SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-/sys%p -o hotplug" diff --git a/docs/libsysfs.txt b/libsysfs/libsysfs.txt similarity index 73% rename from docs/libsysfs.txt rename to libsysfs/libsysfs.txt index 2d68ee4648..b877cb8030 100644 --- a/docs/libsysfs.txt +++ b/libsysfs/libsysfs.txt @@ -2,8 +2,8 @@ System Utilities sysfs Library - libsysfs ========================================= -Version: 0.4.0 -December 16, 2003 +Version: 1.2.0 +September 13, 2004 Contents -------- @@ -22,18 +22,22 @@ Contents 5.5 Device Data Structure 5.6 Driver Data Structure 6. Functions - 6.1 Utility Functions - 6.2 Filesystem Functions - 6.2.1 Attribute Functions - 6.2.2 Directory Link Functions - 6.2.3 Directory Functions - 6.3 Bus Functions - 6.4 Class Functions - 6.5 Device Functions - 6.6 Driver Functions -7. Navigating a dlist + 6.1 Calling Conventions in Libsysfs + 6.2 Utility Functions + 6.3 Filesystem Functions + 6.3.1 Attribute Functions + 6.3.2 Directory Link Functions + 6.3.3 Directory Functions + 6.4 Bus Functions + 6.5 Class Functions + 6.6 Device Functions + 6.7 Driver Functions +7. Dlists + 7.1 Navigating a dlist + 7.2 Custom sorting using dlist_sort_custom() 8. Usage -9. Conclusion +9. Testsuite +10. Conclusion 1. Introduction @@ -87,6 +91,13 @@ The library must satisfy the following requirements: http://www.kernel.org/pub/linux/utils/kernel/hotplug/ + Udev provides persistent device naming based on a set of user specified + rules. The rules a device name is based on could one or a combination of a + number of parameters such as the bus the device is on, the serial number + of the device (in case of USB), the vendor name (in case of SCSI) and so + on. Udev uses Libsysfs to retrieve relevent information to appropriately + name devices. + 4. Overview ----------- @@ -113,6 +124,11 @@ and files that lie underneath it. To query a device on a PCI bus, one would completed. Besides supplying functions to retrieve devices, the library will also provide some utility functions like getting sysfs mount point. +A paper on Libsysfs was presented at Linux.Conf.Au 2004 (Adelaide, January +2004). The paper is available online at: + +http://oss.software.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf + 5. Data Structures ------------------ @@ -128,15 +144,10 @@ and devices, here's some examples: #define SYSFS_FSTYPE_NAME "sysfs" #define SYSFS_PROC_MNTS "/proc/mounts" -#define SYSFS_BUS_DIR "/bus" #define SYSFS_BUS_NAME "bus" -#define SYSFS_CLASS_DIR "/class" #define SYSFS_CLASS_NAME "class" -#define SYSFS_BLOCK_DIR "/block" #define SYSFS_BLOCK_NAME "block" -#define SYSFS_DEVICES_DIR "/devices" #define SYSFS_DEVICES_NAME "devices" -#define SYSFS_DRIVERS_DIR "/drivers" #define SYSFS_DRIVERS_NAME "drivers" #define SYSFS_NAME_ATTRIBUTE "name" @@ -149,11 +160,16 @@ path length: NOTE: - As of release 0.4.0 of libsysfs, a number of changes have been made - so that the dlists and "directory" references in all libsysfs's + a. As of release 0.4.0 of sysfsutils, a number of changes have been + made so that the dlists and "directory" references in all libsysfs's structures are not populated until such time that it is absolutely necessary. Hence, these elements may not contain valid data at all times (as was the case before). + b. As of release 1.0.0 of sysfsutils, all dlists in the library are + sorted in alphabetical order. It is now a requirement that the + "name" and "path" be the first two elements of all libsysfs + structures. + 5.1 Directory and Attribute Data Structures ------------------------------------------- @@ -170,11 +186,11 @@ read only, write only, or read and write. File data can be ASCII and binary. The library has the following structure to represent files: struct sysfs_attribute { - unsigned char *value; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char *value; unsigned short len; /* value length */ unsigned short method; /* show and store */ - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; }; Path represents the file/attribute's full path. Value is used when reading @@ -190,9 +206,9 @@ Symbolic links are used in sysfs to link bus or class views with particular devices. struct sysfs_link { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; - unsigned char target[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char target[SYSFS_PATH_MAX]; }; Link's name is stored in "name' and it's target stored in "target". Absolute @@ -205,11 +221,13 @@ path to the link is stored in "path". The directory structure represents a sysfs directory: struct sysfs_directory { + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + + /* Private: for internal use only */ struct dlist *subdirs; struct dlist *links; struct dlist *attributes; - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; }; The sysfs_directory structure includes the list of subdirectories, links and @@ -226,10 +244,10 @@ All buses look similar in sysfs including lists of devices and drivers, therefore we use the following structure to represent all sysfs buses: struct sysfs_bus { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; - /* internal use only */ + /* Private: for internal use only */ struct dlist *drivers; struct dlist *devices; struct sysfs_directory *directory; @@ -245,7 +263,7 @@ applications to retrieve data from the sysfs_directory structure: struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, - unsigned char *attrname) + char *attrname) 5.3 Class Data Structures @@ -256,10 +274,10 @@ classes contains a class directory like "net" or "scsi_host" and then class devices like "eth0", "lo", or "eth1" for the "net" class. struct sysfs_class { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct dlist *devices; struct sysfs_directory *directory; }; @@ -269,11 +287,11 @@ the class "name", "path" to the class, a list of class devices and the directory representation (for internal use only). struct sysfs_class_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char classname[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char classname[SYSFS_NAME_LEN]; - /* for internal use only */ + /* Private: for internal use only */ struct sysfs_class_device *parent; struct sysfs_device *sysdevice; /* NULL if virtual */ struct sysfs_driver *driver; /* NULL if not implemented */ @@ -300,10 +318,10 @@ structure. Sysfs devices typically spawn off from base devices which are represented by a sysfs_root_device. struct sysfs_root_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct dlist *devices; struct sysfs_directory *directory; }; @@ -321,13 +339,13 @@ The sysfs_device structure represents a system device that's exposed in sysfs under the /sys/devices directory structure. struct sysfs_device { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char bus_id[SYSFS_NAME_LEN]; - unsigned char bus[SYSFS_NAME_LEN]; - unsigned char driver_name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; + char bus_id[SYSFS_NAME_LEN]; + char bus[SYSFS_NAME_LEN]; + char driver_name[SYSFS_NAME_LEN]; - /* for internal use only */ + /* Private: for internal use only */ struct sysfs_device *parent; struct dlist *children; struct sysfs_directory *directory; @@ -342,7 +360,7 @@ device's attributes (for internal use only). The following functions may be used to obtain information from sysfs_directory structure: struct sysfs_attribute *sysfs_get_device_attribute(struct sysfs_device *dev, - const unsigned char *name) + const char *name) struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) @@ -352,10 +370,10 @@ struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) The sysfs_driver structure represents a device driver. struct sysfs_driver { - unsigned char name[SYSFS_NAME_LEN]; - unsigned char path[SYSFS_PATH_MAX]; + char name[SYSFS_NAME_LEN]; + char path[SYSFS_PATH_MAX]; - /* for internal use only */ + /* Private: for internal use only */ struct dlist *devices; struct sysfs_directory *directory; }; @@ -378,7 +396,21 @@ using "open" and "close". Open returns a structure and close is used to clean that structure up. -6.1 Utility Functions +6.1 Calling Conventions in Libsysfs +----------------------------------- + +Libsysfs uses a simple API calling convention. APIs are classified to be +one of "open", "get", "close" types. The convention is as follows: + + a. All "open" APIs have a corresponding "close" API. + b. References obtained using "get" calls should not be closed + explicitly. + c. All "opened" references have to be closed with a call to + their corresponding "close" call. This takes care of + freeing structure references obtained with "get" calls. + + +6.2 Utility Functions --------------------- The library will provide a few utility functions for working with sysfs. @@ -388,14 +420,15 @@ Name: sysfs_get_mnt_path Description: Function finds the mount path for filesystem type "sysfs". -Arguments: unsigned char *mnt_path Mount path buffer - size_t len Size of mount path buffer +Arguments: char *mnt_path Mount path buffer + size_t len Size of mount path buffer Returns: Zero with success. -1 with error. Errno will be set with error: - - EINVAL for invalid argument, if buffer is NULL. + - EINVAL for invalid argument, if buffer is NULL or + if len is zero -Prototype: sysfs_get_mnt_path(unsigned char *mnt_path, size_t len); +Prototype: sysfs_get_mnt_path(char *mnt_path, size_t len); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -404,16 +437,16 @@ Name: sysfs_get_name_from_path Description: Function returns the last directory or file name from the included path. -Arguments: const unsigned char *path Path to parse name from - unsigned char *name Buffer to put parsed name into - size_t *len Size of name buffer +Arguments: const char *path Path to parse name from + char *name Buffer to put parsed name into + size_t *len Size of name buffer Returns: 0 with success. -1 on Error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: int sysfs_get_name_from_path(const unsigned char *path, - unsigned char *name, size_t *len) +Prototype: int sysfs_get_name_from_path(const char *path, + char *name, size_t *len) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -422,16 +455,15 @@ Name: sysfs_get_link Description: Sysfs readlink function, reads the link at supplied path and returns its target path. -Arguments: const unsigned char *path Link's path - unsigned char *target Buffer to place link's target path - size_t len Size of target buffer +Arguments: const char *path Link's path + char *target Buffer to place link's target + size_t len Size of target buffer Returns: 0 with success -1 with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: int sysfs_get_link(const unsigned char *path, - unsigned char *target, size_t len) +Prototype: int sysfs_get_link(const char *path, char *target, size_t len) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -444,12 +476,12 @@ Description: Function returns the list of entries for the given subsystem. If sysfs_close_list() has to be called to free the list obtained from this call. -Arguments: unsigned char *name Subsystem to open, like "bus".. +Arguments: char *name Subsystem to open, like "bus".. Returns: dlist of entries for the subsystem on success NULL with error indicating the "name" subsystem is invalid. -Prototype: struct dlist *sysfs_open_subsystem_list(unsigned char *name) +Prototype: struct dlist *sysfs_open_subsystem_list(char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -460,12 +492,12 @@ Description: Function returns the list of devices on the given bus. sysfs_close_list() has to be called to free the list obtained from this call. -Arguments: unsigned char *name Bus name to open "pci"/"scsi"/"usb".. +Arguments: char *name Bus name to open "pci"/"scsi"/"usb".. Returns: dlist of device names for the given bus on success NULL with error indicating the bus is not supported. -Prototype: struct dlist *sysfs_open_bus_devices_list(unsigned char *name) +Prototype: struct dlist *sysfs_open_bus_devices_list(char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -474,7 +506,7 @@ Name: sysfs_close_list Description: Closes a given dlist. This can be used as a generic list close routine. -Arguments: struct dlist *list List to be closed +Arguments: struct dlist *list List to be closed Prototype: void sysfs_close_list(struct dlist *list) ------------------------------------------------------------------------------- @@ -484,12 +516,12 @@ Name: sysfs_path_is_dir Description: Utility function to verify if a given path is to a directory. -Arguments: unsigned char *path Path to verify +Arguments: const char *path Path to verify Returns: 0 on success, 1 on error - EINVAL for invalid arguments -Prototype: int sysfs_path_is_dir(unsigned char *path) +Prototype: int sysfs_path_is_dir(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -497,12 +529,12 @@ Name: sysfs_path_is_file Description: Utility function to verify if a given path is to a file. -Arguments: unsigned char *path Path to verify +Arguments: const char *path Path to verify Returns: 0 on success, 1 on error - EINVAL for invalid arguments -Prototype: int sysfs_path_is_file(unsigned char *path) +Prototype: int sysfs_path_is_file(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -510,22 +542,24 @@ Name: sysfs_path_is_link Description: Utility function to verify if a given path is to a link. -Arguments: unsigned char *path Path to verify +Arguments: const char *path Path to verify Returns: 0 on success, 1 on error - EINVAL for invalid arguments -Prototype: int sysfs_path_is_link(unsigned char *path) +Prototype: int sysfs_path_is_link(const char *path) ------------------------------------------------------------------------------- -6.2 Filesystem Functions + +6.3 Filesystem Functions ------------------------ Libsysfs provides a set of functions to open, read, and close directories and attributes/files in sysfs. These functions mirror their filesystem function counterparts. -6.2.1 Attribute Functions + +6.3.1 Attribute Functions ------------------------- Along with the usual open, read, and close functions, libsysfs provides @@ -537,14 +571,13 @@ Name: sysfs_open_attribute Description: Opens up a file in sysfs and creates a sysfs_attribute structure. File isn't read with this function. -Arguments: const unsigned char *path File/Attribute's path +Arguments: const char *path File/Attribute's path Returns: struct sysfs_attribute * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_attribute *sysfs_open_attribute - (const unsigned char *path) +Prototype: struct sysfs_attribute *sysfs_open_attribute(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -574,18 +607,35 @@ Prototype: struct dlist *sysfs_read_dir_attributes ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -Name: sysfs_refresh_attributes +Name: sysfs_refresh_dir_attributes -Description: Given a list of attributes, this function refreshes the values - of attributes in the list. +Description: Given a list sysfs_directory, this function refreshes the list + of attributes for the given directory. -Arguments: struct dlist *attrlist list of attributes to refresh +Arguments: struct sysfs_directory *sysdir sysfs_ directory whose + attributes list to refresh Returns: 0 with success. 1 with error. Errno will be set on error, returning EINVAL for invalid arguments -Prototype: int sysfs_refresh_attributes(struct dlist *attrlist) +Prototype: int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_dir_attributes + +Description: Returns a list of attributes for the given sysfs_directory. + +Arguments: struct sysfs_directory *sysdir sysfs_directory whose + attributes list to return + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: struct dlist *sysfs_read_dir_attributes + (struct sysfs_directory *sysdir) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -596,7 +646,7 @@ Description: Reads the supplied attribute. Since the maximum transfer up to a page from the file and stores it in the "value" field in the attribute. -Arguments: struct sysfs_attribute *sysattr Attribute to read +Arguments: struct sysfs_attribute *sysattr Attribute to read Returns: 0 with success. -1 with error. Errno will be set with error, returning @@ -608,14 +658,15 @@ Prototype: int sysfs_read_attribute(struct sysfs_attribute *sysattr) ------------------------------------------------------------------------------- Name: sysfs_write_attribute -Description: Writes to the supplied attribute. Function validates if attribute - is writable, and writes the new value to the attribute. Value to - write as well as its length is user supplied. In case the length - written is not equal to the length requested to be written, the - original value is restored and an error is returned. +Description: Writes to the supplied attribute. Function validates if the + given attribute is writable, and writes the new value to the + attribute. Value to write as well as its length is user + supplied. In case the length written is not equal to the + length requested to be written, the original value is + restored and an error is returned. Arguments: struct sysfs_attribute *sysattr Attribute to write to - const unsigned char *new_value New value for the attribute + const char *new_value sysattr's new value size_t len Length of "new_value" Returns: 0 with success. @@ -623,7 +674,7 @@ Returns: 0 with success. - EINVAL for invalid arguments Prototype: int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const unsigned char *new_value, size_t len) + const char *new_value, size_t len) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -632,16 +683,16 @@ Name: sysfs_read_attribute_value Description: Given a path to a specific attribute, function reads and returns its value to the supplied value buffer. -Arguments: const unsigned char *attrpath Attribute path to read - unsigned char *value Buffer to place attribute's value - size_t vsize Size of buffer +Arguments: const char *attrpath Attribute path to read + char *value Buffer to read in attribute's value + size_t vsize Size of buffer Returns: 0 with success. -1 with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: int sysfs_read_attribute_value(const unsigned char *attrpath, - unsigned char *value, size_t vsize) +Prototype: int sysfs_read_attribute_value(const char *attrpath, + char *value, size_t vsize) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -651,16 +702,16 @@ Description: Function takes a single or linked list of sysfs attribute structures and returns the value of the specified attribute name. -Arguments: struct sysfs_attribute *attr - Attribute list to search through - const unsigned char *name Name of attribute to return value +Arguments: struct dlist *attr Attribute list to search through + const char *name Name of attribute whose value + to retrieve -Returns: unsigned char * attribute value with success. +Returns: char * attribute value with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: unsigned char *sysfs_get_value_from_attributes - (struct sysfs_attribute *attr, const unsigned char * name) +Prototype: char *sysfs_get_value_from_attributes + (struct sysfs_attribute *attr, const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -671,18 +722,18 @@ Description: Function walks the list of attributes for the given sysfs the specified attribute name. Arguments: struct sysfs_directory *dir Directory in which to search - unsigned char *attrname Attribute name to look for + char *attrname Attribute name to look for Returns: struct sysfs_attribute on success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_directory_attribute - (struct sysfs_directory *dir, unsigned char *attrname) + (struct sysfs_directory *dir, char *attrname) ------------------------------------------------------------------------------- -6.2.2 Link Functions +6.3.2 Link Functions -------------------- Sysfs contains many symbolic links, like bus links to bus devices. Libsysfs @@ -696,14 +747,13 @@ Name: sysfs_open_link Description: Opens a directory link. -Arguments: const unsigned char *linkpath Path to link +Arguments: const char *linkpath Path to link Returns: struct sysfs_link * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_link *sysfs_open_link - (const unsigned char *linkpath) +Prototype: struct sysfs_link *sysfs_open_link(const char *linkpath) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -711,7 +761,7 @@ Name: sysfs_close_link Description: Closes a directory link structure. -Arguments: struct sysfs_link *ln Link to close +Arguments: struct sysfs_link *ln Link to close Prototype: void sysfs_close_link(struct sysfs_link *ln) ------------------------------------------------------------------------------- @@ -732,6 +782,22 @@ Prototype: struct dlist *sysfs_read_dir_links (struct sysfs_directory *sysdir) ------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +Name: sysfs_get_dir_links + +Description: Returns a list of links for the given sysfs_directory. + +Arguments: struct sysfs_directory *sysdir sysfs_directory whose + list of links to return + +Returns: struct dlist * of links with success + NULL with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: struct dlist *sysfs_read_dir_links + (struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + ------------------------------------------------------------------------------- Name: sysfs_get_directory_link @@ -740,14 +806,14 @@ Description: Function walks the list of links for the given sysfs directory name. Arguments: struct sysfs_directory *dir Directory in which to search - unsigned char *linkname Link name to look for + char *linkname Link name to look for Returns: struct sysfs_link * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_link *sysfs_get_directory_link - (struct sysfs_directory *dir, unsigned char *linkname) + (struct sysfs_directory *dir, char *linkname) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -758,18 +824,34 @@ Description: Function walks the list of links for the given sysfs directory the specified link name. Arguments: struct sysfs_directory *dir Directory in which to search - unsigned char *linkname Link name to look for + char *linkname Link name to look for Returns: struct sysfs_link * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_link *sysfs_get_subdirectory_link - (struct sysfs_directory *dir, unsigned char *linkname) + (struct sysfs_directory *dir, char *linkname) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_refresh_dir_links + +Description: Given a list sysfs_directory, this function refreshes the list + of links under the given directory. + +Arguments: struct sysfs_directory *sysdir sysfs_ directory whose + links list to refresh + +Returns: 0 with success. + 1 with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: int sysfs_refresh_dir_links(struct sysfs_directory *sysdir) ------------------------------------------------------------------------------- -6.2.3 Directory Functions +6.3.3 Directory Functions ------------------------- Sysfs directories can represent every directory under sysfs. The structures @@ -784,14 +866,13 @@ Name: sysfs_open_directory Description: Opens a sysfs directory at a specific path -Arguments: const unsigned char *path Directory path to open +Arguments: const char *path Directory path to open Returns: struct sysfs_directory * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_directory *sysfs_open_directory - (const unsigned char *path) +Prototype: struct sysfs_directory *sysfs_open_directory(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -858,15 +939,50 @@ Description: Function walks the directory tree for the given directory and name. Arguments: struct sysfs_directory *dir Directory in which to search - unsigned char *subname Name of directory to look for + char *subname Name of directory to look for Returns: struct sysfs_directory with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments + +Prototype: struct sysfs_directory *sysfs_get_subdirectory + (struct sysfs_directory *dir, char *subname) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_dir_subdirs + +Description: Returns a list of subdirs for the given sysfs_directory. + +Arguments: struct sysfs_directory *sysdir sysfs_directory whose + subdirectories list to return + +Returns: struct dlist * of directories with success + NULL with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: struct dlist *sysfs_read_dir_subdirs + (struct sysfs_directory *sysdir) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_refresh_dir_subdirs + +Description: Given a list sysfs_directory, this function refreshes the list + of subdirectories under the given directory. + +Arguments: struct sysfs_directory *sysdir sysfs_ directory whose + subdirs list to refresh + +Returns: 0 with success. + 1 with error. Errno will be set on error, returning EINVAL + for invalid arguments + +Prototype: int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir) ------------------------------------------------------------------------------- -6.3 Bus Functions +6.4 Bus Functions ----------------- The library provides a functions for viewing buses represented in sysfs. @@ -883,13 +999,13 @@ Description: Function opens up one of the buses represented in sysfs in the /sys/bus directory. It returns a sysfs_bus structure that includes a list of bus devices and drivers. -Arguments: const unsigned char *name Bus name to open, like "pci"... +Arguments: const char *name Bus name to open, like "pci"... Returns: struct sysfs_bus * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_bus *sysfs_open_bus(const unsigned char *name) +Prototype: struct sysfs_bus *sysfs_open_bus(const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -942,14 +1058,14 @@ Description: Function takes a sysfs_bus structure(obtained on a successful structure corresponding to the device. Arguments: struct sysfs_bus *bus Bus structure on which to search - unsigned char *id Device to look for + char *id Device to look for Returns: struct sysfs_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_get_bus_device - (struct sysfs_bus *bus, unsigned char *id) + (struct sysfs_bus *bus, char *id) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -961,14 +1077,14 @@ Description: Function takes a sysfs_bus structure (obtained on a successful structure corresponding to the driver. Arguments: struct sysfs_bus *bus Bus structure on which to search - unsigned char *drvname Driver to look for + char *drvname Driver to look for Returns: struct sysfs_driver * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_get_bus_driver - (struct sysfs_bus *bus, unsigned char *drvname) + (struct sysfs_bus *bus, char *drvname) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -994,37 +1110,28 @@ Description: Function takes a sysfs_bus structure and looks for the required structure corresponding to the given attribute. Arguments: struct sysfs_bus *bus Bus structure on which to search - unsigned char *attrname Attribute to look for + char *attrname Attribute to look for Returns: struct sysfs_attribute * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_bus_attribute - (struct sysfs_bus *bus, unsigned char *attrname) + (struct sysfs_bus *bus, char *attrname) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- -Name: sysfs_open_bus_device +Name: sysfs_refresh_bus_attributes -Description: Given the name of the bus on which to look for, this function - locates a given device on the bus and returns a sysfs_device - structure corresponding to the requested device. +Description: Function refreshes the list of attributes for a given sysfs_bus - NOTE: - 1. The sysfs_device structure obtained upon successful return - from this function has to be closed by calling - sysfs_close_device(). +Arguments: struct sysfs_bus *bus Bus whose attributes list to refresh -Arguments: unsigned char *busname Bus on which to search - unsigned char *dev_id Name of the device to look for - -Returns: struct sysfs_device * on success +Returns: struct dlist * of attributes with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_open_bus_device - (unsigned char *busname, unsigned char *dev_id) + +Prototype: struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1033,20 +1140,20 @@ Name: sysfs_find_driver_bus Description: Given the name of a driver, this function finds the name of the bus the driver is on -Arguments: const unsigned char *driver Name of the driver to look for - unsigned char *busname Buffer to return the bus name - size_t bsize Size of the "busname" buffer +Arguments: const char *driver Name of the driver to look for + char *busname Buffer to return the bus name + size_t bsize Size of the "busname" buffer Returns: 0 with success. -1 with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: int sysfs_find_driver_bus(const unsigned char *driver, - unsigned char *busname, size_t bsize) +Prototype: int sysfs_find_driver_bus(const char *driver, + char *busname, size_t bsize) ------------------------------------------------------------------------------- -6.4 Class Functions +6.5 Class Functions ------------------- Libsysfs provides functions to open sysfs classes and their class devices. @@ -1064,13 +1171,13 @@ Description: Function opens up one of the classes represented in sysfs in the /sys/class directory. It returns a sysfs_class structure that includes a list of class devices. -Arguments: const unsigned char *name Class name to open, like "net".. +Arguments: const char *name Class name to open, like "net".. Returns: struct sysfs_class * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_class *sysfs_open_class(const unsigned char *name) +Prototype: struct sysfs_class *sysfs_open_class(const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1079,9 +1186,9 @@ Name: sysfs_close_class Description: Function closes up the sysfs_class structure including its class devices. -Arguments: sysfs_class *class Class structure to close +Arguments: sysfs_class *cls Class structure to close -Prototype: void sysfs_close_class(struct sysfs_class *class); +Prototype: void sysfs_close_class(struct sysfs_class *cls); ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1091,14 +1198,14 @@ Description: Function opens up one of the class devices represented in sysfs in sysfs/class/"class"/ directory. It returns a sysfs_class_device structure. -Arguments: const unsigned char *path Path to class device +Arguments: const char *path Path to class device Returns: struct sysfs_class_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class_device *sysfs_open_class_device_path - (const unsigned char *path) + (const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1119,15 +1226,15 @@ Description: Function takes a sysfs_class structure(obtained on a successful device in this class. On success, it returns a sysfs_class_device structure corresponding to the class device. -Arguments: struct sysfs_class *class Class on which to search - unsigned_char *name Class device "name" to look for +Arguments: struct sysfs_class *cls Class on which to search + char *name Class device "name" to look for Returns: struct sysfs_class_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class_device *sysfs_get_class_device - (struct sysfs_class *class, unsigned char *name) + (struct sysfs_class *cls, char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1159,15 +1266,15 @@ Description: Given the name of the class on which to look for, this function 2. Class this device belongs to must be known prior to calling this function. -Arguments: const unsigned char *classname Class on which to search - unsigned char *name Class device "name" to open +Arguments: const char *classname Class on which to search + char *name Class device "name" to open Returns: struct sysfs_class_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_class_device *sysfs_open_class_device - (const unsigned char *classname, unsigned char *class) + (const char *classname, char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1191,8 +1298,8 @@ Prototype: struct sysfs_device *sysfs_get_classdev_device ------------------------------------------------------------------------------- Name: sysfs_get_classdev_driver -Description: Function returns the sysfs_driver reference (if present) for the - given class device. +Description: Function returns the sysfs_driver reference (if present) for + the given class device. Arguments: struct sysfs_class_device *clsdev Class device whose sysfs_driver reference @@ -1209,8 +1316,8 @@ Prototype: struct sysfs_driver *sysfs_get_classdev_driver ------------------------------------------------------------------------------- Name: sysfs_get_classdev_parent -Description: Function returns the sysfs_class_device reference for the parent - (if present) of the given class device. +Description: Function returns the sysfs_class_device reference for the + parent (if present) of the given class device. Arguments: struct sysfs_class_device *clsdev Class device whose parent reference @@ -1227,8 +1334,8 @@ Prototype: struct sysfs_class_device *sysfs_get_classdev_parent ------------------------------------------------------------------------------- Name: sysfs_get_classdev_attributes -Description: Function takes a sysfs_class_device structure and returns a list - of attributes for the class device. +Description: Function takes a sysfs_class_device structure and returns a + list of attributes for the class device. Arguments: struct sysfs_class_device *cdev Class device for which attributes are required @@ -1248,14 +1355,31 @@ Description: Searches supplied class device's attributes by name and returns the attribute. Arguments: struct sysfs_class_device *clsdev Device to search - const unsigned char *name Attribute name to find + const char *name Attribute name to find Returns: struct sysfs_attribute * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_classdev_attr - (struct sysfs_class_device *clsdev, const unsigned char *name) + (struct sysfs_class_device *clsdev, const char *name) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_refresh_classdev_attributes + +Description: Function refreshes the list of attributes for a given + sysfs_class_device. + +Arguments: struct sysfs_class_device *cdev Class device whose attributes + list to refresh + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_get_classdev_attributes + (struct sysfs_class_device *cdev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1269,21 +1393,21 @@ Description: Function takes as arguments, a the name of the class, the class return from this function has to be closed by making a call to sysfs_close_attribute() -Arguments: unsigned char *classname Class name on which to search - unsigned char *dev Name of the class device - unsigned char *attrib Attribute to open +Arguments: char *classname Class name on which to search + char *dev Name of the class device + char *attrib Attribute to open Returns: struct sysfs_attribute * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_write_classdev_attr - (const unsigned char *classname, const unsigned char *dev, - const unsigned char *attrib) + (const char *classname, const char *dev, + const char *attrib) ------------------------------------------------------------------------------- -6.5 Device Functions +6.6 Device Functions -------------------- Devices represent everything in sysfs under /sys/devices, which is a @@ -1299,14 +1423,13 @@ Description: Opens up a device at a specific path. It opens the device's directory, reads the directory, and returns a sysfs_device structure. -Arguments: const unsigned char *path Path to device +Arguments: const char *path Path to device Returns: struct sysfs_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_device *sysfs_open_device_path - (const unsigned char *path) +Prototype: struct sysfs_device *sysfs_open_device_path(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1326,14 +1449,13 @@ Description: Function opens up one of the root devices represented in sysfs in the /sys/devices directory. It returns a sysfs_root_device structure that includes a list of devices in the tree. -Arguments: const unsigned char *name Name of the root device to open +Arguments: const char *name Name of the root device to open Returns: struct sysfs_root_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_device *sysfs_open_root_device - (const unsigned char *name) +Prototype: struct sysfs_device *sysfs_open_root_device(const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1347,6 +1469,32 @@ Arguments: sysfs_device *root Root device structure to close Prototype: void sysfs_close_root_device(struct sysfs_root_device *root) ------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +Name: sysfs_open_device_tree + +Description: Function opens up the device tree at the specified path. + +Arguments: const char *path Path at which to open the device tree + +Returns: struct sysfs_device * with success + NULL with error, Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct sysfs_device *sysfs_open_device_tree(const char *path) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_close_device_tree + +Description: Function closes the device tree originating at the given + sysfs_device. + +Arguments: struct sysfs_device *devroot Device from which the device + tree has to be closed + +Prototype: void sysfs_close_device_tree(struct sysfs_device *devroot) +------------------------------------------------------------------------------- + ------------------------------------------------------------------------------- Name: sysfs_get_device_parent @@ -1361,7 +1509,7 @@ Returns: struct sysfs_device * on success - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_get_device_parent - (struct sysfs_device *dev) + (struct sysfs_device *dev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1387,14 +1535,14 @@ Description: Searches supplied device's attributes by name and returns the attribute. Arguments: struct sysfs_device *dev Device to search - const unsigned char *name Attribute name to find + const char *name Attribute name to find Returns: struct sysfs_attribute * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_device_attr - (struct sysfs_device *dev, const unsigned char *name) + (struct sysfs_device *dev, const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1403,8 +1551,8 @@ Name: sysfs_get_device_attributes Description: Function takes a sysfs_device structure and returns a list of attributes for the device. -Arguments: struct sysfs_device *device Device for which - attributes are required +Arguments: struct sysfs_device *device Device for which + attributes are required Returns: struct dlist * of attributes with success NULL with error. Errno will be set with error, returning @@ -1414,6 +1562,23 @@ Prototype: struct dlist *sysfs_get_device_attributes (struct sysfs_device *device) ------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +Name: sysfs_refresh_device_attributes + +Description: Function refreshes the list of attributes for a given + sysfs_device. + +Arguments: struct sysfs_device *device Device whose attributes list + to refresh + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_refresh_device_attributes + (struct sysfs_device *device) +------------------------------------------------------------------------------- + ------------------------------------------------------------------------------- Name: sysfs_open_device @@ -1421,15 +1586,30 @@ Description: Given the name of the bus on which to look for, this function locates a given device and returns a sysfs_device structure corresponding to the requested device. -Arguments: const unsigned char *bus_id Device to look for - const unsigned char *bus Bus on which to search +Arguments: const char *bus Bus on which to search + const char *bus_id Device to look for Returns: struct sysfs_device * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_device *sysfs_open_device - (const unsigned char *bus_id, const unsigned char *bus) + (const char *bus, const char *bus_id) +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +Name: sysfs_get_device_bus + +Description: Given a sysfs_device, this function fills in the bus this + device is on in the sysfs_device->bus field. + +Arguments: struct sysfs_device *dev Device whose bus name to find + +Returns: 0 with success. + -1 with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: int sysfs_get_device_bus(struct sysfs_device *dev) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1443,21 +1623,20 @@ Description: Function takes as arguments, the bus on which to search for a return from this function has to be closed by making a call to sysfs_close_attribute() -Arguments: unsigned char *bus Bus on which to search - unsigned char *bus_id Device to look for - unsigned char *attrib Name of the attribute to open +Arguments: char *bus Bus on which to search + char *bus_id Device to look for + char *attrib Name of the attribute to open Returns: struct sysfs_attribute * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_open_device_attr - (const unsigned char *bus, const unsigned char *bus_id, - const unsigned char *attrib) + (const char *bus, const char *bus_id, const char *attrib) ------------------------------------------------------------------------------- -6.6 Driver Functions +6.7 Driver Functions -------------------- Drivers are represented in sysfs under the /sys/bus/xxx/drivers (xxx being @@ -1469,14 +1648,13 @@ Name: sysfs_open_driver_path Description: Opens driver at specific path. -Arguments: const unsigned char *path Path to driver +Arguments: const char *path Path to driver Returns: struct sysfs_driver * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_driver *sysfs_open_driver_path - (const unsigned char *path) +Prototype: struct sysfs_driver *sysfs_open_driver_path(const char *path) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1505,6 +1683,22 @@ Prototype: struct dlist *sysfs_get_driver_devices (struct sysfs_driver *driver) ------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +Name: sysfs_refresh_driver_devices + +Description: Function refreshes the list of devices that use this driver. + +Arguments: struct sysfs_driver *driver Driver whose devices list is + required to be refreshed + +Returns: struct dlist * of sysfs_devices on success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_refresh_driver_devices + (struct sysfs_driver *driver) +------------------------------------------------------------------------------- + ------------------------------------------------------------------------------- Name: sysfs_get_driver_device @@ -1512,14 +1706,14 @@ Description: Function returns a sysfs_device reference for the device with "name" that uses this driver Arguments: struct sysfs_driver *driver Driver on which to search - const unsigned char *name Name of the device to look for + const char *name Name of the device to look for Returns: struct sysfs_device * corresponding to "name" on success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct dlist *sysfs_get_driver_device - (struct sysfs_driver *driver, const unsigned char *name) + (struct sysfs_driver *driver, const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1529,14 +1723,14 @@ Description: Searches supplied driver's attributes by name and returns the attribute. Arguments: struct sysfs_driver *drv Driver to search - const unsigned char *name Attribute name to find + const char *name Attribute name to find Returns: struct sysfs_attribute * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_get_driver_attr - (struct sysfs_driver *drv, const unsigned char *name) + (struct sysfs_driver *drv, const char *name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1545,8 +1739,8 @@ Name: sysfs_get_driver_attributes Description: Function takes a sysfs_driver structure and returns a list of attributes for the driver. -Arguments: struct sysfs_driver *driver Driver for which - attributes are required +Arguments: struct sysfs_driver *driver Driver for which attributes + are required Returns: struct dlist * of attributes with success NULL with error. Errno will be set with error, returning @@ -1556,6 +1750,23 @@ Prototype: struct dlist *sysfs_get_driver_attributes (struct sysfs_driver *driver) ------------------------------------------------------------------------------- +------------------------------------------------------------------------------- +Name: sysfs_refresh_driver_attributes + +Description: Function refreshes the list of attributes for a given + sysfs_driver. + +Arguments: struct sysfs_driver *driver Driver whose attributes list + to refresh + +Returns: struct dlist * of attributes with success + NULL with error. Errno will be set with error, returning + - EINVAL for invalid arguments + +Prototype: struct dlist *sysfs_refresh_driver_attributes + (struct sysfs_driver *driver) +------------------------------------------------------------------------------- + ------------------------------------------------------------------------------- Name: sysfs_open_driver @@ -1571,17 +1782,15 @@ Description: Given the name of the bus on which to look for, this function to calling this function. Use sysfs_find_driver_bus() to determine this. -Arguments: const unsigned char *drv_name Driver to look for - const unsigned char *bus Bus on which to search - size_t bsize Size of "bus" +Arguments: const char *bus_name Bus on which to search + const char *drv_name Driver name to look for Returns: struct sysfs_driver * with success NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments -Prototype: struct sysfs_driver *sysfs_open_driver - (const unsigned char *drv_name, - const unsigned char *bus, size_t bsize) +Prototype: struct sysfs_driver *sysfs_open_driver(const char *bus_name, + const char *drv_name) ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- @@ -1609,25 +1818,28 @@ Description: Function takes as arguments, the bus the driver is registered return from this function has to be closed by making a call to sysfs_close_attribute() -Arguments: unsigned char *bus Bus on which driver is present - unsigned char *drv Driver to look for - unsigned char *attrib Name of the attribute to open +Arguments: char *bus Bus on which driver is present + char *drv Driver to look for + char *attrib Name of the attribute to open Returns: struct sysfs_attribute * with success. NULL with error. Errno will be set with error, returning - EINVAL for invalid arguments Prototype: struct sysfs_attribute *sysfs_open_driver_attr - (const unsigned char *bus, const unsigned char *drv, - const unsigned char *attrib) + (const char *bus, const char *drv, const char *attrib) ------------------------------------------------------------------------------- -7. Navigating a dlist ---------------------- +7 Dlists +-------- Libsysfs uses (yet another) list implementation thanks to Eric J Bohm. + +7.1 Navigating a dlist +---------------------- + Some library functions return a dlist of devices/drivers/attributes, etc. To navigate the list returned the macro "dlist_for_each_data" is to be used. @@ -1667,6 +1879,24 @@ Usage example: The function sysfs_get_classdev_attributes() returns a ------------------------------------------------------------------------------- +7.2 Custom sorting using dlist_sort_custom() +-------------------------------------------- + +As of release 1.2.0, libsysfs provides a new interface for custom sorting +of dlists. The API dlist_sort_custom() has been added for this purpose. +Applications that would like to define their own sorter function can now +make use of this API. + +The sorter function must conform to the following prototype: + + int compare(void *a, void*b) + +dlist_sort_custom() expects that the compare function will: + return >0 for a before b + return <0 for b before a + return 0 for a == b + + 8. Usage -------- @@ -1679,8 +1909,45 @@ in the filesystem it represents. Here's a typical order of operation: - "close" sysfs category -9. Conclusion -------------- +9. Testsuite +------------ + +Version 1.0.0 of sysfsutils ships with a comprehensive testsuite. The testsuite +shipped as part of the "test" directory of the sysfsutils source package, +results in an executable "testlibsysfs" which will be installed in the +/usr/local/bin directory. Some of the salient features of the testsuite are: + +a. Tests _every_ API exported by the library. +b. Tests are performed for all possible combinations of input parameters. +c. Detailed output is provided for the correct case. +d. Facility to redirect output of the tests to a normal file. +e. Number of iterations of tests can be specified. + +The testsuite comes with its own configuration file "libsysfs.conf" in the +"test" directory. This file is used to generate a header file at the time +the tests are built. + +To use the testsuite: + +a. Modify the variables libsysfs.conf file to appropriate values for your + system. (The libsysfs.conf file contains comments describing what each + variable stands for and, in some cases, how to determine an appropriate + value for the system under test). + +b. Build and install the testsuite. + +c. Run the testsuite: + + testlibsysfs + +The default logfile is stdout. + +NOTE: If the libsysfs.conf file is changed, make sure to run "make clean" in +the test directory and then a "make" for the changes to take effect. + + +10. Conclusion +-------------- Libsysfs is meant to provide a stable application programming interface to sysfs. Applications can depend upon the library to access system devices From b2652e6b29c3d29766e1133c81612113084ee44a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 6 Sep 2005 22:57:07 +0200 Subject: [PATCH 1502/4284] klibc: update to version 1.1.1 Signed-off-by: Kay Sievers --- klibc/MCONFIG | 4 ++-- klibc/include/klibc/compiler.h | 4 ++++ klibc/include/klibc/extern.h | 2 ++ klibc/include/malloc.h | 21 +++++++++++++++++++++ klibc/include/stdlib.h | 6 ++---- klibc/include/string.h | 2 ++ klibc/include/sys/inotify.h | 16 ++++++++++++++++ klibc/klibc.spec.in | 4 ++-- klibc/klibc/SYSCALLS.def | 3 +++ klibc/klibc/execvpe.c | 4 +++- klibc/klibc/strchr.c | 3 +++ klibc/klibc/strrchr.c | 3 +++ klibc/version | 2 +- 13 files changed, 64 insertions(+), 10 deletions(-) create mode 100644 klibc/include/malloc.h create mode 100644 klibc/include/sys/inotify.h diff --git a/klibc/MCONFIG b/klibc/MCONFIG index 1141b78d47..450e5c7f5c 100644 --- a/klibc/MCONFIG +++ b/klibc/MCONFIG @@ -33,7 +33,7 @@ KRNLOBJ = $(SRCROOT)/linux KLIBCVER = -D__KLIBC__=$(shell cut -d. -f1 < $(SRCROOT)/version) \ -D__KLIBC_MINOR__=$(shell cut -d. -f2 < $(SRCROOT)/version) -ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) +ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/parisc.*/parisc/) CC = $(CROSS)gcc LD = $(CROSS)ld KLIBSRC = $(SRCROOT)/klibc @@ -42,7 +42,7 @@ INCLUDE = -I$(SRCROOT)/include/arch/$(ARCH) \ -I$(SRCROOT)/include/bits$(BITSIZE) \ -I$(SRCROOT)/include \ -I$(KRNLOBJ)/include -I$(KRNLOBJ)/include2 -I$(KRNLSRC)/include -REQFLAGS = $(ARCHREQFLAGS) $(KLIBCVER) -nostdinc -iwithprefix include \ +REQFLAGS = $(ARCHREQFLAGS) $(KLIBCVER) -nostdlib -nostdinc -iwithprefix include \ $(INCLUDE) LDFLAGS = AR = $(CROSS)ar diff --git a/klibc/include/klibc/compiler.h b/klibc/include/klibc/compiler.h index ee697adf08..7ff6ff7d51 100644 --- a/klibc/include/klibc/compiler.h +++ b/klibc/include/klibc/compiler.h @@ -116,4 +116,8 @@ # define __bitwise #endif +/* Compiler pragma to make an alias symbol */ +#define __ALIAS(__t, __f, __p, __a) \ + __t __f __p __attribute__((weak, alias(#__a))); + #endif diff --git a/klibc/include/klibc/extern.h b/klibc/include/klibc/extern.h index f9c3467211..8a73d19358 100644 --- a/klibc/include/klibc/extern.h +++ b/klibc/include/klibc/extern.h @@ -11,4 +11,6 @@ #define __extern extern #endif +#define __alias(x) __attribute__((weak, alias(x))) + #endif /* _KLIBC_EXTERN_H */ diff --git a/klibc/include/malloc.h b/klibc/include/malloc.h new file mode 100644 index 0000000000..5beca8d068 --- /dev/null +++ b/klibc/include/malloc.h @@ -0,0 +1,21 @@ +/* + * malloc.h + * + * Apparently people haven't caught on to use , which is the + * standard place for this crap since the 1980's... + */ + +#ifndef _MALLOC_H +#define _MALLOC_H + +#include +#include +#include + +__extern void free(void *); + +__extern __mallocfunc void *malloc(size_t); +__extern __mallocfunc void *calloc(size_t, size_t); +__extern __mallocfunc void *realloc(void *, size_t); + +#endif /* _MALLOC_H */ diff --git a/klibc/include/stdlib.h b/klibc/include/stdlib.h index 54d45043f7..17efc30e5a 100644 --- a/klibc/include/stdlib.h +++ b/klibc/include/stdlib.h @@ -9,6 +9,8 @@ #include #include +#include + #define EXIT_FAILURE 1 #define EXIT_SUCCESS 0 @@ -28,7 +30,6 @@ __extern int atoi(const char *); __extern long atol(const char *); __extern long long atoll(const char *); __extern __noreturn exit(int); -__extern void free(void *); static __inline__ long labs(long __n) { return (__n < 0L) ? -__n : __n; } @@ -37,9 +38,6 @@ static __inline__ long long llabs(long long __n) { return (__n < 0LL) ? -__n : __n; } -__extern __mallocfunc void *malloc(size_t); -__extern __mallocfunc void *calloc(size_t, size_t); -__extern __mallocfunc void *realloc(void *, size_t); __extern long strtol(const char *, char **, int); __extern long long strtoll(const char *, char **, int); __extern unsigned long strtoul(const char *, char **, int); diff --git a/klibc/include/string.h b/klibc/include/string.h index 5608a3c963..319be4eb85 100644 --- a/klibc/include/string.h +++ b/klibc/include/string.h @@ -21,7 +21,9 @@ __extern int strcasecmp(const char *, const char *); __extern int strncasecmp(const char *, const char *, size_t); __extern char *strcat(char *, const char *); __extern char *strchr(const char *, int); +__extern char *index(const char *, int); __extern char *strrchr(const char *, int); +__extern char *rindex(const char *, int); __extern int strcmp(const char *, const char *); __extern char *strcpy(char *, const char *); __extern size_t strcspn(const char *, const char *); diff --git a/klibc/include/sys/inotify.h b/klibc/include/sys/inotify.h new file mode 100644 index 0000000000..74fc714190 --- /dev/null +++ b/klibc/include/sys/inotify.h @@ -0,0 +1,16 @@ +/* + * sys/inotify.h + */ + +#ifndef _SYS_INOTIFY_H +#define _SYS_INOTIFY_H + +#include +#include +#include + +__extern int inotify_init(void); +__extern int inotify_add_watch(int, const char *, __u32); +__extern int inotify_rm_watch(int, __u32); + +#endif /* _SYS_INOTIFY_H */ diff --git a/klibc/klibc.spec.in b/klibc/klibc.spec.in index cab496b917..eef5dbf9d3 100644 --- a/klibc/klibc.spec.in +++ b/klibc/klibc.spec.in @@ -7,7 +7,7 @@ Group: Development/Libraries URL: http://www.zytor.com/mailman/listinfo/klibc Source: http://www.kernel.org/pub/linux/libs/klibc-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -BuildRequires: kernel >= 2.6.0 +BuildRequires: kernel >= 2.6.0, kernel-devel Packager: H. Peter Anvin Prefix: /usr Vendor: Starving Linux Artists @@ -44,7 +44,7 @@ embedded systems. %prep %setup -q -cp -dRs /lib/modules/`uname -r`/build ./linux +cp -dRs /lib/modules/`uname -r`/build/ ./linux # Shouldn't need this when getting the build tree from /lib/modules # make -C linux defconfig ARCH=%{_target_cpu} # make -C linux prepare ARCH=%{_target_cpu} diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def index 11d8c9a47e..b78919b134 100644 --- a/klibc/klibc/SYSCALLS.def +++ b/klibc/klibc/SYSCALLS.def @@ -114,6 +114,9 @@ int lchown32,lchown::lchown(const char *, uid_t, gid_t) int getcwd::__getcwd(char *, size_t) int utime(const char *, const struct utimbuf *) int utimes(const char *, const struct timeval *) + int inotify_init(void) + int inotify_add_watch(int, const char *, __u32) + int inotify_rm_watch(int, __u32) ; ; I/O operations diff --git a/klibc/klibc/execvpe.c b/klibc/klibc/execvpe.c index afd791ab43..fcd5b6fd4a 100644 --- a/klibc/klibc/execvpe.c +++ b/klibc/klibc/execvpe.c @@ -9,7 +9,9 @@ * Since execlpe() and execvpe() aren't in POSIX, nor in glibc, * I have followed QNX precedent in the implementation of the PATH: * the PATH that is used is the one in the current environment, not - * in the new environment. + * in the new environment. Otherwise it would be impossible to pass + * a different PATH to the new process than the one one would want to + * use to search. */ #include diff --git a/klibc/klibc/strchr.c b/klibc/klibc/strchr.c index 192f83600c..f657095c6b 100644 --- a/klibc/klibc/strchr.c +++ b/klibc/klibc/strchr.c @@ -3,6 +3,7 @@ */ #include +#include char *strchr(const char *s, int c) { @@ -14,3 +15,5 @@ char *strchr(const char *s, int c) return (char *)s; } + +__ALIAS(char *, index, (const char *, int), strchr) diff --git a/klibc/klibc/strrchr.c b/klibc/klibc/strrchr.c index 3b42464059..5a0cbe386e 100644 --- a/klibc/klibc/strrchr.c +++ b/klibc/klibc/strrchr.c @@ -3,6 +3,7 @@ */ #include +#include char *strrchr(const char *s, int c) { @@ -16,3 +17,5 @@ char *strrchr(const char *s, int c) return (char *)found; } + +__ALIAS(char *, rindex, (const char *, int), strrchr) diff --git a/klibc/version b/klibc/version index 5b09c67c20..45a1b3f445 100644 --- a/klibc/version +++ b/klibc/version @@ -1 +1 @@ -1.0.14 +1.1.2 From fc049858394318dab8ec729cb49cd6cfd49f350d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Sep 2005 03:34:34 +0200 Subject: [PATCH 1503/4284] delete cdromsymlinks* - obsoleted by cdrom_id and IMPORT rules Signed-off-by: Kay Sievers --- extras/cdsymlinks.c | 555 ----------------------------------------- extras/cdsymlinks.conf | 21 -- extras/cdsymlinks.sh | 204 --------------- 3 files changed, 780 deletions(-) delete mode 100644 extras/cdsymlinks.c delete mode 100644 extras/cdsymlinks.conf delete mode 100644 extras/cdsymlinks.sh diff --git a/extras/cdsymlinks.c b/extras/cdsymlinks.c deleted file mode 100644 index b6bc96dc6f..0000000000 --- a/extras/cdsymlinks.c +++ /dev/null @@ -1,555 +0,0 @@ -/* cdsymlinks.c - * - * Map cdrom, cd-r, cdrw, dvd, dvdrw, dvdram to suitable devices. - * Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices. - * First parameter is the kernel device name. - * Second parameter, if present, must be "-d" => output the full mapping. - * - * Usage: - * BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - * BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - * BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - * (this last one is "just in case") - * - * (c) 2004, 2005 Darren Salt - * - * Contributors: - * - J A Magallon (bug fixes) - * - * Last modified: 2005-02-15 - */ - -#define _GNU_SOURCE - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -static const char *progname; - -/* This file provides us with our devices and capabilities information. */ -#define CDROM_INFO "/proc/sys/dev/cdrom/info" - -/* This file contains our default settings. */ -#define CONFIGURATION "/etc/udev/cdsymlinks.conf" -/* Default output types configuration, in the presence of an empty list */ -#define OUTPUT_DEFAULT "CD CDRW DVD DVDRW DVDRAM" - -static int debug = 0; - -/* List item */ -struct list_item_t { - struct list_item_t *next; - char *data; -}; - -/* List root. Note offset of list_t->head and list_item_t->next */ -struct list_t { - struct list_item_t *head, *tail; -}; - -/* Configuration variables */ -static struct list_t allowed_output = {0}; -static int numbered_links = 1; -static int link_zero = 0; - -/* Available devices */ -static struct list_t Devices = {0}; - -/* Devices' capabilities in full (same order as available devices list). - * There's no cap_CD; all are assumed able to read CDs. - */ -static struct list_t cap_DVDRAM = {0}, cap_DVDRW = {0}, cap_DVD = {0}, - cap_CDRW = {0}, cap_CDR = {0}, cap_CDWMRW = {0}, - cap_CDMRW = {0}, cap_CDRAM = {0}; - -/* Device capabilities by name */ -static struct list_t dev_DVDRAM = {0}, dev_DVDRW = {0}, dev_DVD = {0}, - dev_CDRW = {0}, dev_CDR = {0}, dev_CDWMRW = {0}, - dev_CDMRW = {0}, dev_CDRAM = {0}; -#define dev_CD Devices - -typedef struct { - struct list_t *cap, *dev; - const char label[8], symlink[8]; - const char *captext; - int captextlen; -} cap_dev_t; - -#define CAPDEV(X) &cap_##X, &dev_##X - -static const cap_dev_t cap_dev_info[] = { - { NULL, &dev_CD, "CD", "cdrom", NULL, 0 }, - { CAPDEV(CDR), "CDR", "cd-r", "Can write CD-R:", 15 }, - { CAPDEV(CDRW), "CDRW", "cdrw", "Can write CD-RW:", 16 }, - { CAPDEV(DVD), "DVD", "dvd", "Can read DVD:", 13 }, - { CAPDEV(DVDRW), "DVDRW", "dvdrw", "Can write DVD-R:", 16 }, - { CAPDEV(DVDRAM), "DVDRAM", "dvdram", "Can write DVD-RAM:", 18 }, - { CAPDEV(CDMRW), "CDMRW", "cdm", "Can read MRW:", 13 }, /* CDC-MRW R */ - { CAPDEV(CDWMRW), "CDWMRW", "cdmrw", "Can write MRW:", 14 }, /* CDC-MRW W */ - { CAPDEV(CDRAM), "CDRAM", "cdram", "Can write RAM:", 14 }, /* CDC-RAM W */ - { NULL } -}; - -#define foreach_cap_dev(loop) \ - for ((loop) = cap_dev_info; (loop)->label[0]; ++(loop)) -#define foreach_cap_dev_noCD(loop) \ - for ((loop) = cap_dev_info + 1; (loop)->label[0]; ++(loop)) - -/* - * Some library-like bits first... - */ - -static void -errexit (const char *reason) -{ - fprintf (stderr, "%s: %s: %s\n", progname, reason, strerror (errno)); - exit (2); -} - - -static void -msgexit (const char *reason) -{ - fprintf (stderr, "%s: %s\n", progname, reason); - exit (2); -} - - -static void -errwarn (const char *reason) -{ - fprintf (stderr, "%s: warning: %s: %s\n", progname, reason, strerror (errno)); -} - - -static void -msgwarn (const char *reason) -{ - fprintf (stderr, "%s: warning: %s\n", progname, reason); -} - - -static void * -xmalloc (size_t size) -{ - void *mem = malloc (size); - if (size && !mem) - msgexit ("malloc failed"); - return mem; -} - - -static char * -xstrdup (const char *text) -{ - char *mem = xmalloc (strlen (text) + 1); - return strcpy (mem, text); -} - - -/* Append a string to a list. The string is duplicated. */ -static void -list_append (struct list_t *list, const char *data) -{ - struct list_item_t *node = xmalloc (sizeof (struct list_item_t)); - node->next = NULL; - if (list->tail) - list->tail->next = node; - list->tail = node; - if (!list->head) - list->head = node; - node->data = xstrdup (data); -} - - -/* Prepend a string to a list. The string is duplicated. */ -static void -list_prepend (struct list_t *list, const char *data) -{ - struct list_item_t *node = xmalloc (sizeof (struct list_item_t)); - node->next = list->head; - list->head = node; - if (!list->tail) - list->tail = node; - node->data = xstrdup (data); -} - - -/* Delete a lists's contents, freeing claimed memory */ -static void -list_delete (struct list_t *list) -{ - struct list_item_t *node = list->head; - while (node) - { - struct list_item_t *n = node; - node = node->next; - free (n->data); - free (n); - } - list->tail = list->head = NULL; -} - - -/* Print out a list on one line, each item space-prefixed, no LF */ -static void -list_print (const struct list_t *list, FILE *stream) -{ - const struct list_item_t *node = (const struct list_item_t *)list; - while ((node = node->next) != NULL) - fprintf (stream, " %s", node->data); -} - - -/* Return the nth item in a list (count from 0) - * If there aren't enough items in the list, return the requested default - */ -static const struct list_item_t * -list_nth (const struct list_t *list, size_t nth) -{ - const struct list_item_t *node = list->head; - while (nth && node) - { - node = node->next; - --nth; - } - return node; -} - - -/* Return the first matching item in a list, or NULL */ -static const struct list_item_t * -list_search (const struct list_t *list, const char *data) -{ - const struct list_item_t *node = list->head; - while (node) - { - if (!strcmp (node->data, data)) - return node; - node = node->next; - } - return NULL; -} - - -/* Split up a string on whitespace & assign the resulting tokens to a list. - * Ignore everything up until the first colon (if present). - */ -static void -list_assign_split (struct list_t *list, char *text) -{ - char *token = strchr (text, ':'); - token = strtok (token ? token + 1 : text, " \t\n"); - while (token) - { - list_prepend (list, token); - token = strtok (0, " \t\n"); - } -} - - - -/* Gather the default settings. */ -static void -read_defaults (void) -{ - FILE *conf = fopen (CONFIGURATION, "r"); - if (!conf) - { - if (errno != ENOENT) - errwarn ("error accessing configuration"); - } - else - { - char *text = NULL; - size_t textlen; - while (getline (&text, &textlen, conf) != -1) - { - wordexp_t p = {0}; - int len = strlen (text); - if (len && text[len - 1] == '\n') - text[--len] = '\0'; - if (len && text[len - 1] == '\r') - text[--len] = '\0'; - if (!len) - continue; - char *token = text + strspn (text, " \t"); - if (!*token || *token == '#') - continue; - switch (len = wordexp (text, &p, 0)) - { - case WRDE_NOSPACE: - msgexit ("malloc failed"); - case 0: - if (p.we_wordc == 1) - { - if (!strncmp (p.we_wordv[0], "OUTPUT=", 7)) - { - list_delete (&allowed_output); - list_assign_split (&allowed_output, p.we_wordv[0] + 7); - } - else if (!strncmp (p.we_wordv[0], "NUMBERED_LINKS=", 15)) - numbered_links = atoi (p.we_wordv[0] + 15); - else if (!strncmp (p.we_wordv[0], "LINK_ZERO=", 15)) - link_zero = atoi (p.we_wordv[0] + 15); - break; - } - /* fall through */ - default: - msgwarn ("syntax error in configuration file"); - } - wordfree (&p); - } - if (!feof (conf)) - errwarn ("error accessing configuration"); - if (fclose (conf)) - errwarn ("error accessing configuration"); - free (text); - } - if (!allowed_output.head) - { - char *dflt = strdup (OUTPUT_DEFAULT); - list_assign_split (&allowed_output, dflt); - free (dflt); - } -} - - -/* From information supplied by the kernel: - * + get the names of the available devices - * + populate our capability lists - * Order is significant: device item N maps to each capability item N. - */ -static void -populate_capability_lists (void) -{ - FILE *info = fopen (CDROM_INFO, "r"); - if (!info) - { - if (errno == ENOENT) - exit (0); - errexit ("error accessing CD/DVD info"); - } - - char *text = 0; - size_t textlen = 0; - - while (getline (&text, &textlen, info) != -1) - { - if (!strncasecmp (text, "drive name", 10)) - list_assign_split (&Devices, text); - else - { - const cap_dev_t *cap; - foreach_cap_dev_noCD (cap) - if (!strncasecmp (text, cap->captext, cap->captextlen)) - { - list_assign_split (cap->cap, text); - break; - } - } - } - if (!feof (info)) - errexit ("error accessing CD/DVD info"); - fclose (info); - free (text); -} - - -/* Write out the links of type LINK which should be created for device NAME, - * taking into account existing links and the capability list for type LINK. - */ -static void -do_output (const char *name, const char *link, const struct list_t *dev, - int do_link_zero) -{ - const struct list_item_t *i = (const struct list_item_t *)dev; - if (!i->next) - return; - - errno = 0; - - size_t link_len = strlen (link); - DIR *dir = opendir ("/dev"); - if (!dir) - errexit ("error reading /dev"); - - struct list_t devls = {0}; /* symlinks whose name matches LINK */ - struct list_t devlinks = {0}; /* those symlinks' targets */ - struct dirent *entry; - while ((entry = readdir (dir)) != NULL) - { - if (strncmp (entry->d_name, link, link_len)) - continue; /* wrong name: ignore it */ - - /* The rest of the name must be null or consist entirely of digits. */ - const char *p = entry->d_name + link_len - 1; - while (*++p) - if (!isdigit (*p)) - break; - if (*p) - continue; /* wrong format - ignore */ - - /* Assume that it's a symlink and try to read its target. */ - char buf[sizeof (entry->d_name)]; - int r = readlink (entry->d_name, buf, sizeof (buf) - 1); - if (r < 0) - { - if (errno == EINVAL) - continue; /* not a symlink - ignore */ - errexit ("error reading link in /dev"); - } - /* We have the name and the target, so update our lists. */ - buf[r] = 0; - list_append (&devls, entry->d_name); - list_append (&devlinks, buf); - } - if (errno) - errexit ("error reading /dev"); - if (closedir (dir)) - errexit ("error closing /dev"); - - /* Now we write our output... */ - size_t count = 0; - while ((i = i->next) != NULL) - { - int isdev = !strcmp (name, i->data); /* current dev == target dev? */ - int present = 0; - size_t li = -1; - const struct list_item_t *l = (const struct list_item_t *)&devlinks; - - /* First, we look for existing symlinks to the target device. */ - while (++li, (l = l->next) != NULL) - { - if (strcmp (l->data, i->data)) - continue; - /* Existing symlink found - don't output a new one. - * If ISDEV, we output the name of the existing symlink. - */ - if (do_link_zero) - return; - present = 1; - if (isdev) - printf (" %s", list_nth (&devls, li)->data); - } - - /* If we found no existing symlinks for the target device... */ - if (!present) - { - char buf[256]; - snprintf (buf, sizeof (buf), count || do_link_zero ? "%s%d" : "%s", - link, count); - /* Find the next available (not present) symlink name. - * We always need to do this for reasons of output consistency: if a - * symlink is created by udev as a result of use of this program, we - * DON'T want different output! - */ - while (list_search (&devls, buf)) - { - if (do_link_zero) - return; - snprintf (buf, sizeof (buf), "%s%d", link, ++count); - } - /* If ISDEV, output it. */ - if (isdev && (numbered_links || count == 0)) - printf (" %s", buf); - /* If the link isn't in our "existing links" list, add it and increment - * our counter. - */ - if (!list_search (&devls, buf)) - { - if (do_link_zero) - return; - list_append (&devls, buf); - ++count; - } - } - } - - list_delete (&devls); - list_delete (&devlinks); -} - - -/* Populate a device list from a capabilities list. */ -static void -populate_device_list (struct list_t *out, const struct list_t *caps) -{ - const struct list_item_t *cap, *dev; - cap = (const struct list_item_t *)caps; - dev = (const struct list_item_t *)&Devices; - while ((cap = cap->next) != NULL && (dev = dev->next) != NULL) - if (cap->data[0] != '0') - list_append (out, dev->data); -} - - -int -main (int argc, char *argv[]) -{ - const cap_dev_t *capdev; - - progname = argv[0]; - debug = argc > 2 && !strcmp (argv[2], "-d"); - - if (argc < 2 || argc > 2 + debug) - msgexit ("usage: cdsymlinks DEVICE [-d]"); - - if (chdir ("/dev")) - errexit ("can't chdir /dev"); - - read_defaults (); - populate_capability_lists (); - - /* Construct the device lists from the capability lists. - * (We assume that all relevant devices can read CDs.) - */ - foreach_cap_dev_noCD (capdev) - populate_device_list (capdev->dev, capdev->cap); - - if (debug) - { - printf ("Devices:"); - const struct list_item_t *item = (const struct list_item_t *)&Devices; - while ((item = item->next) != NULL) - printf (" %s", item->data); - - printf ("\nCDROM : (all)"); - item = (const struct list_item_t *)&dev_CD; - while ((item = item->next) != NULL) - printf (" %s", item->data); - puts (""); - - foreach_cap_dev_noCD (capdev) - { - printf ("%-10s:", capdev->label); - list_print (capdev->cap, stdout); - list_print (capdev->dev, stdout); - puts (""); - } - - } - - /* Write the symlink names. */ - foreach_cap_dev (capdev) - if (list_search (&allowed_output, capdev->label)) - { - do_output (argv[1], capdev->symlink, capdev->dev, 0); - if (link_zero) - do_output (argv[1], capdev->symlink, capdev->dev, 1); - } - puts (""); - - return 0; -} diff --git a/extras/cdsymlinks.conf b/extras/cdsymlinks.conf deleted file mode 100644 index e4c5ee2231..0000000000 --- a/extras/cdsymlinks.conf +++ /dev/null @@ -1,21 +0,0 @@ -# Configuration file for cdsymlinks - -# Output links for these types of devices. -# Allowed keywords are: corresponding to device names: -# CD CDR CDRW cdrom cd-r cdrw -# DVD DVDRW DVDRAM dvd dvdrw dvdram -# CDMRW CDWMRW cdm cdmrw -# CDRAM cdram -# Other words are accepted but ignored. -# Devices with multiple recognised capabilities WILL get multiple links. -#OUTPUT="CD CDRW DVD DVDRW DVDRAM" - -# Whether to output numbered links. -# 1 = output 'cdrom1', 'dvd1' etc. for other devices -# 0 = don't output 'cdrom1', 'dvd1' etc. -# We always output 'cdrom', 'dvd' etc. for the best-match devices. -#NUMBERED_LINKS=1 - -# Whether to output link 0 along with each unnumbered link. -# (No effect if NUMBERED_LINKS=0.) -#LINK_ZERO=0 diff --git a/extras/cdsymlinks.sh b/extras/cdsymlinks.sh deleted file mode 100644 index 592de365cb..0000000000 --- a/extras/cdsymlinks.sh +++ /dev/null @@ -1,204 +0,0 @@ -#! /bin/sh -e -# -# Map cdrom, cd-r, cdrw, dvd, dvdrw, dvdram, cdm, cdmrw, cdram -# to suitable devices. -# Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices. -# First parameter is the kernel device name. -# Second parameter, if present, must be "-d" => output the full mapping. -# -# Usage: -# BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -# BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -# BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -# (this last one is "just in case") -# -# (c) 2004, 2005 Darren Salt -# -# Last modified: 2005-02-15 - -test -e /proc/sys/dev/cdrom/info || exit 0 - -# Defaults; it's better that you alter them in /etc/udev/cdsymlinks.conf -OUTPUT='CD CDRW DVD DVDRW DVDRAM' -NUMBERED_LINKS=1 -LINK_ZERO=0 - -test -e /etc/udev/cdsymlinks.conf && . /etc/udev/cdsymlinks.conf - -DEBUG='' -test "$2" = '-d' && DEBUG=1 - - -# Array emulation. 'setArray FOO a b c' gives FOO=3 FOO_1=a FOO_2=b FOO_3=c -setArray () { - local _ARRAY=$1 - local _INDEX=0 - shift - while test $# -ne 0; do - eval ${_ARRAY}_$_INDEX="$1" - _INDEX=$(($_INDEX+1)) - shift - done - eval $_ARRAY=$_INDEX -} - -ix () { eval echo -n \$$1_$2; } -ixs () { eval $1_$2="$3"; } - -# Args: variable, value -# Returns true if value is not in variable (a whitespace-separated list) -notin () { - test "$2" = '' && return 0 - local i - for i in `eval echo '$'$1`; do - test "$i" != "$2" || return 1 - done -} - - -# Scan /proc/sys/dev/cdrom/info for details on the present devices -setArray DEVICES `sed -re '/^drive name:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray DVDRAMs `sed -re '/^Can write DVD-RAM:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray DVDRWs `sed -re '/^Can write DVD-R:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray DVDs `sed -re '/^Can read DVD:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDRWs `sed -re '/^Can write CD-RW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDRs `sed -re '/^Can write CD-R:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDMRWs `sed -re '/^Can write MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDMs `sed -re '/^Can read MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDRAMs `sed -re '/^Can write RAM:/I! d; s/.*://' /proc/sys/dev/cdrom/info` - -# How many devices do we have? -NumDevs=$(($DEVICES-1)) -Count='' -i=-1 -while test $i -ne $NumDevs; do - i=$(($i+1)); - Count="$i${Count:+ }$Count"; -done - -# Fill in any missing capabilities information (assume not capable) -for i in $Count; do - test "`ix DVDRAMs $i`" != '' || ixs DVDRAMs $i 0 - test "`ix DVDRWs $i`" != '' || ixs DVDRWs $i 0 - test "`ix DVDs $i`" != '' || ixs DVDs $i 0 - test "`ix CDRWs $i`" != '' || ixs CDRWs $i 0 - test "`ix CDRs $i`" != '' || ixs CDRs $i 0 - test "`ix CDMRWs $i`" != '' || ixs CDMRWs $i 0 - test "`ix CDMs $i`" != '' || ixs CDMs $i 0 - test "`ix CDRAMs $i`" != '' || ixs CDRAMs $i 0 -done - -DVDRAM='' -DVDRW='' -DVD='' -CDRW='' -CDR='' -CDMRW='' -CDM='' -CDRAM='' -CD='' - -# Calculate symlink->device mappings. -# We need to be careful about how we assign mappings because we want -# read-only devices to have /dev/cdrom and /dev/dvd. -# Hot-plugged CD/DVD devices may well cause this scheme some problems. -for i in $Count; do - test "`ix DVDRAMs $i`" = 1 && DVDRAM="$DVDRAM `ix DEVICES $i`" -done -for i in $Count; do - test "`ix DVDRWs $i`" = 1 && DVDRW="$DVDRW `ix DEVICES $i`" -done -for i in $Count; do - test "`ix DVDs $i`" = 1 && DVD="$DVD `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDRWs $i`" = 1 && CDRW="$CDRW `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDRs $i`" = 1 && CDR="$CDR `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDMRWs $i`" = 1 && CDMRW="$CDMRW `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDMs $i`" = 1 && CDM="$CDM `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDRAMs $i`" = 1 && CDRAM="$CDRAM `ix DEVICES $i`" -done -for i in $Count; do - CD="$CD `ix DEVICES $i`" -done - -# Debug output -if test "$DEBUG" = 1; then - echo 'Devices:' `for i in $Count; do ix DEVICES $i; echo -n \ ; done` - echo 'CDROM : (all)' $CD - echo 'CD-R :' `for i in $Count; do ix CDRs $i; echo -n \ ; done` $CDR - echo 'CDRW :' `for i in $Count; do ix CDRWs $i; echo -n \ ; done` $CDRW - echo 'DVD :' `for i in $Count; do ix DVDs $i; echo -n \ ; done` $DVD - echo 'DVDRW :' `for i in $Count; do ix DVDRWs $i; echo -n \ ; done` $DVDRW - echo 'DVDRAM :' `for i in $Count; do ix DVDRAMs $i; echo -n \ ; done` $DVDRAM - echo 'CDMRW :' `for i in $Count; do ix CDMRWs $i; echo -n \ ; done` $CDMRW - echo 'CDWMRW :' `for i in $Count; do ix CDMs $i; echo -n \ ; done` $CDM - echo 'CDRAM :' `for i in $Count; do ix CDRAMs $i; echo -n \ ; done` $CDRAM -fi - -# Prepare symlink names output -do_output () { - test "`eval echo '$'$3`" = '' && return - local i - local COUNT=$4 - local DEVLS="`ls -dl \"/dev/$2\" \"/dev/$2\"[0-9]* 2>/dev/null`" - local PRESENT="`echo "$DEVLS" | - sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> [^[:space:]]+$!\1!'`" - for i in `eval echo '$'$3`; do - # First, we look for existing symlinks to the target device. - local DEVPRESENT="`echo "$DEVLS" | - sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> '$i'$!\1!; t X; d; :X'`" - if test "$DEVPRESENT" != ""; then - # Existing symlinks found - don't output a new one. - # If the target dev ($1) is the current dev ($i), we output their names. - test -z "$4" || return; - test "$1" = "$i" && echo " $DEVPRESENT" | sed -e 'N; $ s/\n/ /' - else - # If we found no existing symlinks for the target device... - # Find the next available (not present) symlink name. - # We always need to do this for reasons of output consistency: if a - # symlink is created by udev as a result of use of this program, we - # DON'T want different output! - until notin PRESENT "$2$COUNT"; do - test -z "$4" || return; - COUNT=$(($COUNT+1)) - done - # If the target dev ($1) is the current dev ($i), we output its name. - if test $(($NUMBERED_LINKS)) -ne 0 || test -z "$COUNT"; then - test "$i" != "$1" || echo -n " $2$COUNT" - fi - # If the link isn't in our "existing links" list, add it and increment - # our counter. - if notin PRESENT "$2$COUNT"; then - test -z "$4" || return; - PRESENT="$PRESENT\n$2$COUNT" - COUNT=$(($COUNT+1)) - fi - fi - done -} - -output () { - do_output "$@" - test $(($LINK_ZERO)) -eq 0 || do_output "$@" 0 -} - -# And output it -notin OUTPUT CD || echo -n "`output "$1" cdrom CD`" -notin OUTPUT CDR || echo -n "`output "$1" cd-r CDR`" -notin OUTPUT CDRW || echo -n "`output "$1" cdrw CDRW`" -notin OUTPUT DVD || echo -n "`output "$1" dvd DVD`" -notin OUTPUT DVDRW || echo -n "`output "$1" dvdrw DVDRW`" -notin OUTPUT DVDRAM || echo -n "`output "$1" dvdram DVDRAM`" -notin OUTPUT CDMRW || echo -n "`output "$1" cdmrw CDM`" -notin OUTPUT CDWMRW || echo -n "`output "$1" cdwmrw CDMRW`" -notin OUTPUT CDRAM || echo -n "`output "$1" cdram CDRAM`" -echo From 619d548faaad20fbbe4f38a862b1b3e92d1c0f27 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Sep 2005 03:36:45 +0200 Subject: [PATCH 1504/4284] delete docs/persistent_naming - obsoleted by persistent disk names Signed-off-by: Kay Sievers --- docs/persistent_naming/testing_scsi_notes.txt | 201 ---- .../udev.rules_1000_scsi_debug | 1014 ----------------- 2 files changed, 1215 deletions(-) delete mode 100644 docs/persistent_naming/testing_scsi_notes.txt delete mode 100644 docs/persistent_naming/udev.rules_1000_scsi_debug diff --git a/docs/persistent_naming/testing_scsi_notes.txt b/docs/persistent_naming/testing_scsi_notes.txt deleted file mode 100644 index 728b40b0fe..0000000000 --- a/docs/persistent_naming/testing_scsi_notes.txt +++ /dev/null @@ -1,201 +0,0 @@ -Using UDEV to do Persistent storage device naming -for large numbers of storage devices -3/16/2004 - -Here are some lessons we learned at OSDL recently on how to use UDEV -(version 021) to do persistent device naming for lots of storage devices. -We used what was available in udev for scsi devices. Here is an outline of -this report: - -Background information - a list of resources we needed to get started. -Setup - what we needed to create the right enviroment (kernel, patches, - drivers) -How udev works to assign persistent storage device names - what the documentation didn't tell us. -Performance - A sanity test we ran to compare with and without persistent naming. - - -BACKGROUND INFORMATION -To get started, here are some references. Review the overview articles so -that the rest of the information makes sense. - -Download the latest udev stuff from: - http://www.kernel.org/pub/linux/utils/kernel/hotplug/ - -mailing list: - linux-hotplug-devel@lists.sourceforge.net - -Here is a nice overview article to get started (warning, this is from -summer 2003 so many items indicated as "todo" have been done and -configuration file name references have sometime changed): -http://www.kroah.com/linux/talks/ols_2003_udev_paper/Reprint-Kroah-Hartman-OLS2003.pdf -(also included when you download udev) - -More general info (also included in the udev package): - http://kernel.org/pub/linux/utils/kernel/hotplug/udev-FAQ -UDEV version 021 Announcement: - http://marc.theaimsgroup.com/?l=linux-hotplug-devel&m=107827264803336&w=2 - -"Managing Dynamic Naming": - http://lwn.net/Articles/28897/ - -If you are a fan of devfs, whatever you do, don't complain until you read -everything you possibly can about udev. This for example: - http://kernel.org/pub/linux/utils/kernel/hotplug/udev_vs_devfs - -You will need to create udev.rules to supply consistent names. (See -etc/udev/udev.rules in the download). This article gives you some -background about udev.rules, but avoids describing the "PROGRAM" key which -is needed for our work. Read it for background: writing udev rules -(current as of udev 018) - http://www.reactivated.net/udevrules.php - -bitkeeper tree: - bk://kernel.bkbits.net/gregkh/udev - -Libsysfs used to get sysfs information): - http://www-124.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf - -UDEV works using the way hotplug events are handled by the kernel. -Several overview articles about hotplug include: -Hotplug events -http://lwn.net/Articles/52621/ -Overview of Hotplug -http://linux-hotplug.sourceforge.net/ - -Gentoo centric install info: -http://webpages.charter.net/decibelshelp/LinuxHelp_UDEVPrimer.html - -rpms built against Red Hat FC2-test1 may be available at: -http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.i386.rpm - -with the source rpm at: -http://kernel.org/pub/linux/utils/kernel/hotplug/udev-021-1.src.rpm - - - -SETUP - -Here is a brief checklist of what you need on your system for this to -work: - -Kernel must be a 2.6 kernel - -Must use CONFIG_HOTPLUG kernel config option, since the solution is based -on hotplug capabilities. - -To test more than 256 scsi devices you need a patch to the scsi driver to -support that many (available from IBM or SuSE). To see the patch we used, -see this link: -http://developer.osdl.org/maryedie/DCL/PSDN/lotsofdisks.patch - -Your storage device must support (via the driver) a unique identifier for -persistent device naming. (Adaptec RAID device does not, for example.) - -Your device driver must support sysfs (new in 2.6 kernel). This is already -done for scsi devices and most if not all block devices. - -A program (scsi_id) exists in the udev download (extras/scsi_id/scsi_id.c) -for scsi devices. It can read the identifier and is needed for persistent -naming. - - -HOW UDEV WORKS TO ASSIGN PERSISTENT NAMES: - -There are three places where device information is stored that udev -uses: -(1) /sys maintained by sysfs -(2) /etc/udev/udev.rules - where you can store the identifier to NAME - mapping information. -(3) The udevdb, that keeps track the valid system configuration. - It is constructed at boot time and updated with configuration changes. - -The persistent names are kept (at least this is one way to do it) in -udev.rules (uuid and NAME), one entry per device. If you want to initially -give your 1000 disk devices a default name and then make sure those names -are preserved, here is how : - -Start with no special entry in udev.rules when do you an initial boot of -your system with disks in place. Udev will assign default names (there -are ways to control what you want for default too). - -Once the names are assigned, use a script supplied for scsi devices - -udev-021/extras/scsi_id/gen_scsi_id_udev_rules.sh to generate the lines -needed for udev.rules, one per device. Each line indicates the identifier -and the NAME it was assigned. You could optionally create this manually if -you prefer other names . - -[example entries in udev.rules for scsi disks] -BUS="scsi", PROGRAM="scsi_id", RESULT="",NAME="" -BUS="scsi", RESULT="",NAME="" -... -BUS="scsi", RESULT="",NAME="" - -(The actual file we used is the file udev.rules_1000_scsi_debug in this -directory ) - -Upon reboot, for each device a hotplug event occurs. The udev.rules file -is scanned looking for the device type (BUS) in this case for "scsi". The -first entry generated by the above program references a PROGRAM in the key -field (scsi_id) which is called to probe the device and determine the -unique identifier. sysfs is used to determine the major/minor number for -the device. The result of the program execution (the uuid) is compared -with the RESULT entry in the same udev.rules line. - -- If it matches, then the NAME entered on this line is used. The uuid and - major/minor number is saved in the udevdb (newly recreated upon boot). - That device is created in /udev (the target directory name is configurable) - with the assigned NAME. - -- If it doesn't match, the RESULT (uuid) is preserved for use on the next - udev.rules line as long as the bus type (scsi) is the same. So the - result (the uuid) is compared on the next line, and the next until a - match occurs. - -- If no match occurs, the device will be assigned a default name. - -- The udevdb is updated with the resulting name assignment. - - -Thus if the uuid and names are enumerated, they will be found, assigned, -and are therefore permanent. - -If the device is removed from a live system, a hotplug event occurs, and it -is removed from udevdb and the /udev entry disappears. - -If it is re-inserted at a new location, the udev.rules file is scanned as -above. The rule matches again against the uuid, the name in udev.rules -is applied again and the /udev name re-appears. - - - -PERFORMANCE - -Now the question becomes, how much longer does it take to scan the -udev.rules table once there are 1000 entries? - -To test this, we created 1000 "scsi " devices using the scsi debug device -driver supplied in the kernel. When this device driver is loaded you can -specify how many fake scsi devices to create. There is no real I/O -involved but it does respond to some scsi commands. It simulates the uuid -by using the device number assigned when the device is created. - -Then we auto-generated entries into udev.rules with -gen_scsi_id_udev_rules.sh. We then removed the devices and reassigned them -to simulate a reboot. The delta between assigning defaults and assigning -the names enumerated in the udev.rules file was 7 seconds (that's for 1000 -drives). - -Scripts utilized the feature (described above) that saves the "RESULT" key -after one scsi-id program call for later reference with other udev.rules -entries (so only have one PROGRAM key is the moral of the story). If you -repeated the PROGRAM key, you would unnecessarily call the program up to -999 times! - -The script that creates udev.rules did not work for 1000 drives (the input -line is too long). We determined that a patch for this already existed but -had not yet been checked in. - diff --git a/docs/persistent_naming/udev.rules_1000_scsi_debug b/docs/persistent_naming/udev.rules_1000_scsi_debug deleted file mode 100644 index e1598cb829..0000000000 --- a/docs/persistent_naming/udev.rules_1000_scsi_debug +++ /dev/null @@ -1,1014 +0,0 @@ -# -# Start of autogenerated scsi_id rules. Edit the NAME portions of these -# rules to your liking. -# -BUS="scsi", PROGRAM="/sbin/scsi_id", RESULT="SSEAGATE ST336704LC 3CD1HVVA00007128JK12", NAME="disk-sda%n" - -# Further RESULT keys use the result of the last PROGRAM rule. -# Be careful not to add any rules containing PROGRAM key between here -# and the end of this section - -BUS="scsi", RESULT="3512345600000afc8", NAME="disk-sdaa%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaaa%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaab%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaac%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdaad%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaae%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaaf%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaag%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaah%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaai%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaaj%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaak%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaal%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaam%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdaan%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaao%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaap%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaaq%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaar%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaas%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdaat%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaau%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaav%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaaw%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaax%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaay%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaaz%n" -BUS="scsi", RESULT="3512345600000b3b0", NAME="disk-sdab%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaba%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdabb%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdabc%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdabd%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdabe%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdabf%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdabg%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdabh%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdabi%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdabj%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdabk%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdabl%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdabm%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdabn%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdabo%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdabp%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdabq%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdabr%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdabs%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdabt%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdabu%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdabv%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdabw%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdabx%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaby%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdabz%n" -BUS="scsi", RESULT="3512345600000b798", NAME="disk-sdac%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaca%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdacb%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdacc%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdacd%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdace%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdacf%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdacg%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdach%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaci%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdacj%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdack%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdacl%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdacm%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdacn%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaco%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdacp%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdacq%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdacr%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdacs%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdact%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdacu%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdacv%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdacw%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdacx%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdacy%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdacz%n" -BUS="scsi", RESULT="3512345600000bb80", NAME="disk-sdad%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdada%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdadb%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdadc%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdadd%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdade%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdadf%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdadg%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdadh%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdadi%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdadj%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdadk%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdadl%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdadm%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdadn%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdado%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdadp%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdadq%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdadr%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdads%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdadt%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdadu%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdadv%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdadw%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdadx%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdady%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdadz%n" -BUS="scsi", RESULT="3512345600000bf68", NAME="disk-sdae%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaea%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaeb%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaec%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaed%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaee%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdaef%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaeg%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaeh%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaei%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaej%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaek%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdael%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaem%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaen%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaeo%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaep%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaeq%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaer%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaes%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaet%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaeu%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdaev%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaew%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaex%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaey%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaez%n" -BUS="scsi", RESULT="3512345600000c350", NAME="disk-sdaf%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdafa%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdafb%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdafc%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdafd%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdafe%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaff%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdafg%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdafh%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdafi%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdafj%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdafk%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdafl%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdafm%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdafn%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdafo%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdafp%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdafq%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdafr%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdafs%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaft%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdafu%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdafv%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdafw%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdafx%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdafy%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdafz%n" -BUS="scsi", RESULT="3512345600000c738", NAME="disk-sdag%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaga%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdagb%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdagc%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdagd%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdage%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdagf%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdagg%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdagh%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdagi%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdagj%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdagk%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdagl%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdagm%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdagn%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdago%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdagp%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdagq%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdagr%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdags%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdagt%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdagu%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdagv%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdagw%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdagx%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdagy%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdagz%n" -BUS="scsi", RESULT="3512345600000cb20", NAME="disk-sdah%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaha%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdahb%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdahc%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdahd%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdahe%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdahf%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdahg%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdahh%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdahi%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdahj%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdahk%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdahl%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdahm%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdahn%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaho%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdahp%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdahq%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdahr%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdahs%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaht%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdahu%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdahv%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdahw%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdahx%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdahy%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdahz%n" -BUS="scsi", RESULT="3512345600000cf08", NAME="disk-sdai%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaia%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdaib%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaic%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdaid%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaie%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaif%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaig%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaih%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaii%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaij%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaik%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdail%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaim%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdain%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaio%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdaip%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdaiq%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdair%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdais%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdait%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaiu%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdaiv%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaiw%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdaix%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaiy%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdaiz%n" -BUS="scsi", RESULT="3512345600000d2f0", NAME="disk-sdaj%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdaja%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdajb%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdajc%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdajd%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaje%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdajf%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdajg%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdajh%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdaji%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdajj%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdajk%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdajl%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdajm%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdajn%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdajo%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdajp%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdajq%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdajr%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdajs%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdajt%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdaju%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdajv%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdajw%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdajx%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdajy%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdajz%n" -BUS="scsi", RESULT="3512345600000d6d8", NAME="disk-sdak%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdaka%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdakb%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdakc%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdakd%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdake%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdakf%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdakg%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdakh%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaki%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdakj%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdakk%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdakl%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdakm%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdakn%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdako%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdakp%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdakq%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdakr%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdaks%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdakt%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdaku%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdakv%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdakw%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdakx%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdaky%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdakz%n" -BUS="scsi", RESULT="3512345600000dac0", NAME="disk-sdal%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdala%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdalb%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdalc%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdald%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdale%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdalf%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdalg%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdalh%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdali%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdalj%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdalk%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdall%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdalm%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdaln%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdalo%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdalp%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdalq%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdalr%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdals%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdalt%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdalu%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdalv%n" -BUS="scsi", RESULT="3512345600000dea8", NAME="disk-sdam%n" -BUS="scsi", RESULT="3512345600000e290", NAME="disk-sdan%n" -BUS="scsi", RESULT="3512345600000e678", NAME="disk-sdao%n" -BUS="scsi", RESULT="3512345600000ea60", NAME="disk-sdap%n" -BUS="scsi", RESULT="3512345600000ee48", NAME="disk-sdaq%n" -BUS="scsi", RESULT="3512345600000f230", NAME="disk-sdar%n" -BUS="scsi", RESULT="3512345600000f618", NAME="disk-sdas%n" -BUS="scsi", RESULT="3512345600000fa00", NAME="disk-sdat%n" -BUS="scsi", RESULT="3512345600000fde8", NAME="disk-sdau%n" -BUS="scsi", RESULT="351234560000101d0", NAME="disk-sdav%n" -BUS="scsi", RESULT="351234560000105b8", NAME="disk-sdaw%n" -BUS="scsi", RESULT="351234560000109a0", NAME="disk-sdax%n" -BUS="scsi", RESULT="35123456000010d88", NAME="disk-sday%n" -BUS="scsi", RESULT="35123456000011170", NAME="disk-sdaz%n" -BUS="scsi", RESULT="SSEAGATE ST336704LC 3CD1HVBC000071283KA0", NAME="disk-sdb%n" -BUS="scsi", RESULT="35123456000011558", NAME="disk-sdba%n" -BUS="scsi", RESULT="35123456000011940", NAME="disk-sdbb%n" -BUS="scsi", RESULT="35123456000011d28", NAME="disk-sdbc%n" -BUS="scsi", RESULT="35123456000012110", NAME="disk-sdbd%n" -BUS="scsi", RESULT="351234560000124f8", NAME="disk-sdbe%n" -BUS="scsi", RESULT="351234560000128e0", NAME="disk-sdbf%n" -BUS="scsi", RESULT="35123456000012cc8", NAME="disk-sdbg%n" -BUS="scsi", RESULT="351234560000130b0", NAME="disk-sdbh%n" -BUS="scsi", RESULT="35123456000013498", NAME="disk-sdbi%n" -BUS="scsi", RESULT="35123456000013880", NAME="disk-sdbj%n" -BUS="scsi", RESULT="35123456000013c68", NAME="disk-sdbk%n" -BUS="scsi", RESULT="35123456000014050", NAME="disk-sdbl%n" -BUS="scsi", RESULT="35123456000014438", NAME="disk-sdbm%n" -BUS="scsi", RESULT="35123456000014820", NAME="disk-sdbn%n" -BUS="scsi", RESULT="35123456000014c08", NAME="disk-sdbo%n" -BUS="scsi", RESULT="35123456000014ff0", NAME="disk-sdbp%n" -BUS="scsi", RESULT="351234560000153d8", NAME="disk-sdbq%n" -BUS="scsi", RESULT="351234560000157c0", NAME="disk-sdbr%n" -BUS="scsi", RESULT="35123456000015ba8", NAME="disk-sdbs%n" -BUS="scsi", RESULT="35123456000015f90", NAME="disk-sdbt%n" -BUS="scsi", RESULT="35123456000016378", NAME="disk-sdbu%n" -BUS="scsi", RESULT="35123456000016760", NAME="disk-sdbv%n" -BUS="scsi", RESULT="35123456000016b48", NAME="disk-sdbw%n" -BUS="scsi", RESULT="35123456000016f30", NAME="disk-sdbx%n" -BUS="scsi", RESULT="35123456000017318", NAME="disk-sdby%n" -BUS="scsi", RESULT="35123456000017700", NAME="disk-sdbz%n" -BUS="scsi", RESULT="35123456000017ae8", NAME="disk-sdca%n" -BUS="scsi", RESULT="35123456000017ed0", NAME="disk-sdcb%n" -BUS="scsi", RESULT="351234560000182b8", NAME="disk-sdcc%n" -BUS="scsi", RESULT="351234560000186a0", NAME="disk-sdcd%n" -BUS="scsi", RESULT="35123456000018a88", NAME="disk-sdce%n" -BUS="scsi", RESULT="35123456000018e70", NAME="disk-sdcf%n" -BUS="scsi", RESULT="35123456000019258", NAME="disk-sdcg%n" -BUS="scsi", RESULT="35123456000019640", NAME="disk-sdch%n" -BUS="scsi", RESULT="35123456000019a28", NAME="disk-sdci%n" -BUS="scsi", RESULT="35123456000019e10", NAME="disk-sdcj%n" -BUS="scsi", RESULT="3512345600001a1f8", NAME="disk-sdck%n" -BUS="scsi", RESULT="3512345600001a5e0", NAME="disk-sdcl%n" -BUS="scsi", RESULT="3512345600001a9c8", NAME="disk-sdcm%n" -BUS="scsi", RESULT="3512345600001adb0", NAME="disk-sdcn%n" -BUS="scsi", RESULT="3512345600001b198", NAME="disk-sdco%n" -BUS="scsi", RESULT="3512345600001b580", NAME="disk-sdcp%n" -BUS="scsi", RESULT="3512345600001b968", NAME="disk-sdcq%n" -BUS="scsi", RESULT="3512345600001bd50", NAME="disk-sdcr%n" -BUS="scsi", RESULT="3512345600001c138", NAME="disk-sdcs%n" -BUS="scsi", RESULT="3512345600001c520", NAME="disk-sdct%n" -BUS="scsi", RESULT="3512345600001c908", NAME="disk-sdcu%n" -BUS="scsi", RESULT="3512345600001ccf0", NAME="disk-sdcv%n" -BUS="scsi", RESULT="3512345600001d0d8", NAME="disk-sdcw%n" -BUS="scsi", RESULT="3512345600001d4c0", NAME="disk-sdcx%n" -BUS="scsi", RESULT="3512345600001d8a8", NAME="disk-sdcy%n" -BUS="scsi", RESULT="3512345600001dc90", NAME="disk-sdcz%n" -BUS="scsi", RESULT="3512345600001e078", NAME="disk-sdda%n" -BUS="scsi", RESULT="3512345600001e460", NAME="disk-sddb%n" -BUS="scsi", RESULT="3512345600001e848", NAME="disk-sddc%n" -BUS="scsi", RESULT="3512345600001ec30", NAME="disk-sddd%n" -BUS="scsi", RESULT="3512345600001f018", NAME="disk-sdde%n" -BUS="scsi", RESULT="3512345600001f400", NAME="disk-sddf%n" -BUS="scsi", RESULT="35123456000007530", NAME="disk-sddg%n" -BUS="scsi", RESULT="35123456000007918", NAME="disk-sddh%n" -BUS="scsi", RESULT="35123456000007d00", NAME="disk-sddi%n" -BUS="scsi", RESULT="351234560000080e8", NAME="disk-sddj%n" -BUS="scsi", RESULT="351234560000084d0", NAME="disk-sddk%n" -BUS="scsi", RESULT="351234560000088b8", NAME="disk-sddl%n" -BUS="scsi", RESULT="35123456000008ca0", NAME="disk-sddm%n" -BUS="scsi", RESULT="35123456000009470", NAME="disk-sddn%n" -BUS="scsi", RESULT="35123456000009858", NAME="disk-sddo%n" -BUS="scsi", RESULT="35123456000009c40", NAME="disk-sddp%n" -BUS="scsi", RESULT="3512345600000a028", NAME="disk-sddq%n" -BUS="scsi", RESULT="3512345600000a410", NAME="disk-sddr%n" -BUS="scsi", RESULT="3512345600000a7f8", NAME="disk-sdds%n" -BUS="scsi", RESULT="3512345600000abe0", NAME="disk-sddt%n" -BUS="scsi", RESULT="3512345600000afc8", NAME="disk-sddu%n" -BUS="scsi", RESULT="3512345600000b3b0", NAME="disk-sddv%n" -BUS="scsi", RESULT="3512345600000b798", NAME="disk-sddw%n" -BUS="scsi", RESULT="3512345600000bb80", NAME="disk-sddx%n" -BUS="scsi", RESULT="3512345600000bf68", NAME="disk-sddy%n" -BUS="scsi", RESULT="3512345600000c350", NAME="disk-sddz%n" -BUS="scsi", RESULT="3512345600000c738", NAME="disk-sdea%n" -BUS="scsi", RESULT="3512345600000cb20", NAME="disk-sdeb%n" -BUS="scsi", RESULT="3512345600000cf08", NAME="disk-sdec%n" -BUS="scsi", RESULT="3512345600000d2f0", NAME="disk-sded%n" -BUS="scsi", RESULT="3512345600000d6d8", NAME="disk-sdee%n" -BUS="scsi", RESULT="3512345600000dac0", NAME="disk-sdef%n" -BUS="scsi", RESULT="3512345600000dea8", NAME="disk-sdeg%n" -BUS="scsi", RESULT="3512345600000e290", NAME="disk-sdeh%n" -BUS="scsi", RESULT="3512345600000e678", NAME="disk-sdei%n" -BUS="scsi", RESULT="3512345600000ea60", NAME="disk-sdej%n" -BUS="scsi", RESULT="3512345600000ee48", NAME="disk-sdek%n" -BUS="scsi", RESULT="3512345600000f230", NAME="disk-sdel%n" -BUS="scsi", RESULT="3512345600000f618", NAME="disk-sdem%n" -BUS="scsi", RESULT="3512345600000fa00", NAME="disk-sden%n" -BUS="scsi", RESULT="3512345600000fde8", NAME="disk-sdeo%n" -BUS="scsi", RESULT="351234560000101d0", NAME="disk-sdep%n" -BUS="scsi", RESULT="351234560000105b8", NAME="disk-sdeq%n" -BUS="scsi", RESULT="351234560000109a0", NAME="disk-sder%n" -BUS="scsi", RESULT="35123456000010d88", NAME="disk-sdes%n" -BUS="scsi", RESULT="35123456000011170", NAME="disk-sdet%n" -BUS="scsi", RESULT="35123456000011558", NAME="disk-sdeu%n" -BUS="scsi", RESULT="35123456000011940", NAME="disk-sdev%n" -BUS="scsi", RESULT="35123456000011d28", NAME="disk-sdew%n" -BUS="scsi", RESULT="35123456000012110", NAME="disk-sdex%n" -BUS="scsi", RESULT="351234560000124f8", NAME="disk-sdey%n" -BUS="scsi", RESULT="351234560000128e0", NAME="disk-sdez%n" -BUS="scsi", RESULT="35123456000012cc8", NAME="disk-sdfa%n" -BUS="scsi", RESULT="351234560000130b0", NAME="disk-sdfb%n" -BUS="scsi", RESULT="35123456000013498", NAME="disk-sdfc%n" -BUS="scsi", RESULT="35123456000013880", NAME="disk-sdfd%n" -BUS="scsi", RESULT="35123456000013c68", NAME="disk-sdfe%n" -BUS="scsi", RESULT="35123456000014050", NAME="disk-sdff%n" -BUS="scsi", RESULT="35123456000014438", NAME="disk-sdfg%n" -BUS="scsi", RESULT="35123456000014820", NAME="disk-sdfh%n" -BUS="scsi", RESULT="35123456000014c08", NAME="disk-sdfi%n" -BUS="scsi", RESULT="35123456000014ff0", NAME="disk-sdfj%n" -BUS="scsi", RESULT="351234560000153d8", NAME="disk-sdfk%n" -BUS="scsi", RESULT="351234560000157c0", NAME="disk-sdfl%n" -BUS="scsi", RESULT="35123456000015ba8", NAME="disk-sdfm%n" -BUS="scsi", RESULT="35123456000015f90", NAME="disk-sdfn%n" -BUS="scsi", RESULT="35123456000016378", NAME="disk-sdfo%n" -BUS="scsi", RESULT="35123456000016760", NAME="disk-sdfp%n" -BUS="scsi", RESULT="35123456000016b48", NAME="disk-sdfq%n" -BUS="scsi", RESULT="35123456000016f30", NAME="disk-sdfr%n" -BUS="scsi", RESULT="35123456000017318", NAME="disk-sdfs%n" -BUS="scsi", RESULT="35123456000017700", NAME="disk-sdft%n" -BUS="scsi", RESULT="35123456000017ae8", NAME="disk-sdfu%n" -BUS="scsi", RESULT="35123456000017ed0", NAME="disk-sdfv%n" -BUS="scsi", RESULT="351234560000182b8", NAME="disk-sdfw%n" -BUS="scsi", RESULT="351234560000186a0", NAME="disk-sdfx%n" -BUS="scsi", RESULT="35123456000018a88", NAME="disk-sdfy%n" -BUS="scsi", RESULT="35123456000018e70", NAME="disk-sdfz%n" -BUS="scsi", RESULT="35123456000019258", NAME="disk-sdga%n" -BUS="scsi", RESULT="35123456000019640", NAME="disk-sdgb%n" -BUS="scsi", RESULT="35123456000019a28", NAME="disk-sdgc%n" -BUS="scsi", RESULT="35123456000019e10", NAME="disk-sdgd%n" -BUS="scsi", RESULT="3512345600001a1f8", NAME="disk-sdge%n" -BUS="scsi", RESULT="3512345600001a5e0", NAME="disk-sdgf%n" -BUS="scsi", RESULT="3512345600001a9c8", NAME="disk-sdgg%n" -BUS="scsi", RESULT="3512345600001adb0", NAME="disk-sdgh%n" -BUS="scsi", RESULT="3512345600001b198", NAME="disk-sdgi%n" -BUS="scsi", RESULT="3512345600001b580", NAME="disk-sdgj%n" -BUS="scsi", RESULT="3512345600001b968", NAME="disk-sdgk%n" -BUS="scsi", RESULT="3512345600001bd50", NAME="disk-sdgl%n" -BUS="scsi", RESULT="3512345600001c138", NAME="disk-sdgm%n" -BUS="scsi", RESULT="3512345600001c520", NAME="disk-sdgn%n" -BUS="scsi", RESULT="3512345600001c908", NAME="disk-sdgo%n" -BUS="scsi", RESULT="3512345600001ccf0", NAME="disk-sdgp%n" -BUS="scsi", RESULT="3512345600001d0d8", NAME="disk-sdgq%n" -BUS="scsi", RESULT="3512345600001d4c0", NAME="disk-sdgr%n" -BUS="scsi", RESULT="3512345600001d8a8", NAME="disk-sdgs%n" -BUS="scsi", RESULT="3512345600001dc90", NAME="disk-sdgt%n" -BUS="scsi", RESULT="3512345600001e078", NAME="disk-sdgu%n" -BUS="scsi", RESULT="3512345600001e460", NAME="disk-sdgv%n" -BUS="scsi", RESULT="3512345600001e848", NAME="disk-sdgw%n" -BUS="scsi", RESULT="3512345600001ec30", NAME="disk-sdgx%n" -BUS="scsi", RESULT="3512345600001f018", NAME="disk-sdgy%n" -BUS="scsi", RESULT="3512345600001f400", NAME="disk-sdgz%n" -BUS="scsi", RESULT="3512345600001f7e8", NAME="disk-sdha%n" -BUS="scsi", RESULT="3512345600001fbd0", NAME="disk-sdhb%n" -BUS="scsi", RESULT="35123456000007d00", NAME="disk-sdhc%n" -BUS="scsi", RESULT="351234560000080e8", NAME="disk-sdhd%n" -BUS="scsi", RESULT="351234560000084d0", NAME="disk-sdhe%n" -BUS="scsi", RESULT="351234560000088b8", NAME="disk-sdhf%n" -BUS="scsi", RESULT="35123456000008ca0", NAME="disk-sdhg%n" -BUS="scsi", RESULT="35123456000009088", NAME="disk-sdhh%n" -BUS="scsi", RESULT="35123456000009470", NAME="disk-sdhi%n" -BUS="scsi", RESULT="35123456000009c40", NAME="disk-sdhj%n" -BUS="scsi", RESULT="3512345600000a028", NAME="disk-sdhk%n" -BUS="scsi", RESULT="3512345600000a410", NAME="disk-sdhl%n" -BUS="scsi", RESULT="3512345600000a7f8", NAME="disk-sdhm%n" -BUS="scsi", RESULT="3512345600000abe0", NAME="disk-sdhn%n" -BUS="scsi", RESULT="3512345600000afc8", NAME="disk-sdho%n" -BUS="scsi", RESULT="3512345600000b3b0", NAME="disk-sdhp%n" -BUS="scsi", RESULT="3512345600000b798", NAME="disk-sdhq%n" -BUS="scsi", RESULT="3512345600000bb80", NAME="disk-sdhr%n" -BUS="scsi", RESULT="3512345600000bf68", NAME="disk-sdhs%n" -BUS="scsi", RESULT="3512345600000c350", NAME="disk-sdht%n" -BUS="scsi", RESULT="3512345600000c738", NAME="disk-sdhu%n" -BUS="scsi", RESULT="3512345600000cb20", NAME="disk-sdhv%n" -BUS="scsi", RESULT="3512345600000cf08", NAME="disk-sdhw%n" -BUS="scsi", RESULT="3512345600000d2f0", NAME="disk-sdhx%n" -BUS="scsi", RESULT="3512345600000d6d8", NAME="disk-sdhy%n" -BUS="scsi", RESULT="3512345600000dac0", NAME="disk-sdhz%n" -BUS="scsi", RESULT="3512345600000dea8", NAME="disk-sdia%n" -BUS="scsi", RESULT="3512345600000e290", NAME="disk-sdib%n" -BUS="scsi", RESULT="3512345600000e678", NAME="disk-sdic%n" -BUS="scsi", RESULT="3512345600000ea60", NAME="disk-sdid%n" -BUS="scsi", RESULT="3512345600000ee48", NAME="disk-sdie%n" -BUS="scsi", RESULT="3512345600000f230", NAME="disk-sdif%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdig%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdih%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdii%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdij%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdik%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdil%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdim%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdin%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdio%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdip%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdiq%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdir%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdis%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdit%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdiu%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdiv%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdiw%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdix%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdiy%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdiz%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdja%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdjb%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdjc%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdjd%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdje%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdjf%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdjg%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdjh%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdji%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdjj%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdjk%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdjl%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdjm%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdjn%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdjo%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdjp%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdjq%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdjr%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdjs%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdjt%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdju%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdjv%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdjw%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdjx%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdjy%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdjz%n" -BUS="scsi", RESULT="35123456000006d60", NAME="disk-sdk%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdka%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdkb%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdkc%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdkd%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdke%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdkf%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdkg%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdkh%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdki%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdkj%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdkk%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdkl%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdkm%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdkn%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdko%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdkp%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdkq%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdkr%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdks%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdkt%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdku%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdkv%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdkw%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdkx%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdky%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdkz%n" -BUS="scsi", RESULT="35123456000007148", NAME="disk-sdl%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdla%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdlb%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdlc%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdld%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdle%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdlf%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdlg%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdlh%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdli%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdlj%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdlk%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdll%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdlm%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdln%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdlo%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdlp%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdlq%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdlr%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdls%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdlt%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdlu%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdlv%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdlw%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdlx%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdly%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdlz%n" -BUS="scsi", RESULT="35123456000007530", NAME="disk-sdm%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdma%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdmb%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdmc%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdmd%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdme%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdmf%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdmg%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdmh%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdmi%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdmj%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdmk%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdml%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdmm%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdmn%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdmo%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdmp%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdmq%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdmr%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdms%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdmt%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdmu%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdmv%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdmw%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdmx%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdmy%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdmz%n" -BUS="scsi", RESULT="35123456000007918", NAME="disk-sdn%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdna%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdnb%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdnc%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdnd%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdne%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdnf%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdng%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdnh%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdni%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdnj%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdnk%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdnl%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdnm%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdnn%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdno%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdnp%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdnq%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdnr%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdns%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdnt%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdnu%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdnv%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdnw%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdnx%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdny%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdnz%n" -BUS="scsi", RESULT="35123456000007d00", NAME="disk-sdo%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdoa%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdob%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdoc%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdod%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdoe%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdof%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdog%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdoh%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdoi%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdoj%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdok%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdol%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdom%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdon%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdoo%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdop%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdoq%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdor%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdos%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdot%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdou%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdov%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdow%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdox%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdoy%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdoz%n" -BUS="scsi", RESULT="351234560000080e8", NAME="disk-sdp%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdpa%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdpb%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdpc%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdpd%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdpe%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdpf%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdpg%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdph%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdpi%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdpj%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdpk%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdpl%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdpm%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdpn%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdpo%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdpp%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdpq%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdpr%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdps%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdpt%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdpu%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdpv%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdpw%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdpx%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdpy%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdpz%n" -BUS="scsi", RESULT="351234560000084d0", NAME="disk-sdq%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdqa%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdqb%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdqc%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdqd%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdqe%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdqf%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdqg%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdqh%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdqi%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdqj%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdqk%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdql%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdqm%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdqn%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdqo%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdqp%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdqq%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdqr%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdqs%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdqt%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdqu%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdqv%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdqw%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdqx%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdqy%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdqz%n" -BUS="scsi", RESULT="35123456000008ca0", NAME="disk-sdr%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdra%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdrb%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdrc%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdrd%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdre%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdrf%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdrg%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdrh%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdri%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdrj%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdrk%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdrl%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdrm%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdrn%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdro%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdrp%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdrq%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdrr%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdrs%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdrt%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdru%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdrv%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdrw%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdrx%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdry%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdrz%n" -BUS="scsi", RESULT="35123456000009088", NAME="disk-sds%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdsa%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdsb%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdsc%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdsd%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdse%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdsf%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdsg%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdsh%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdsi%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdsj%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdsk%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdsl%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdsm%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdsn%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdso%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdsp%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdsq%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdsr%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdss%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdst%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdsu%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdsv%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdsw%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdsx%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdsy%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdsz%n" -BUS="scsi", RESULT="35123456000009470", NAME="disk-sdt%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdta%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdtb%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdtc%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdtd%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdte%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdtf%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdtg%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdth%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdti%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdtj%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdtk%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdtl%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdtm%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdtn%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdto%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdtp%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdtq%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdtr%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdts%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdtt%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdtu%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdtv%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdtw%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdtx%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdty%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdtz%n" -BUS="scsi", RESULT="35123456000009858", NAME="disk-sdu%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdua%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdub%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sduc%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdud%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdue%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sduf%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdug%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sduh%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdui%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sduj%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sduk%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdul%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdum%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdun%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sduo%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdup%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sduq%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdur%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdus%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdut%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sduu%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sduv%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sduw%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdux%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sduy%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sduz%n" -BUS="scsi", RESULT="35123456000009c40", NAME="disk-sdv%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdva%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdvb%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdvc%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdvd%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdve%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdvf%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdvg%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdvh%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdvi%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdvj%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdvk%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdvl%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdvm%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdvn%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdvo%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdvp%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdvq%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdvr%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdvs%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdvt%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdvu%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdvv%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdvw%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdvx%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdvy%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdvz%n" -BUS="scsi", RESULT="3512345600000a028", NAME="disk-sdw%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdwa%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdwb%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdwc%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdwd%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdwe%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdwf%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdwg%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdwh%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdwi%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdwj%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdwk%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdwl%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdwm%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdwn%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdwo%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdwp%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdwq%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdwr%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdws%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdwt%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdwu%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdwv%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdww%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdwx%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdwy%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdwz%n" -BUS="scsi", RESULT="3512345600000a410", NAME="disk-sdx%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdxa%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdxb%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdxc%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdxd%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdxe%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdxf%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdxg%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdxh%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdxi%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdxj%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdxk%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdxl%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdxm%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdxn%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdxo%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdxp%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdxq%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdxr%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdxs%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdxt%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdxu%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdxv%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdxw%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdxx%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdxy%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdxz%n" -BUS="scsi", RESULT="3512345600000a7f8", NAME="disk-sdy%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdya%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdyb%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdyc%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdyd%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdye%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdyf%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdyg%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdyh%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdyi%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdyj%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdyk%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdyl%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdym%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdyn%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdyo%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdyp%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdyq%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdyr%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdys%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdyt%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdyu%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdyv%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdyw%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdyx%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdyy%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdyz%n" -BUS="scsi", RESULT="3512345600000abe0", NAME="disk-sdz%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdza%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdzb%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdzc%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdzd%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdze%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdzf%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdzg%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdzh%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdzi%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdzj%n" -BUS="scsi", RESULT="35123456000022e98", NAME="disk-sdzk%n" -BUS="scsi", RESULT="35123456000023280", NAME="disk-sdzl%n" -BUS="scsi", RESULT="35123456000023668", NAME="disk-sdzm%n" -BUS="scsi", RESULT="35123456000023a50", NAME="disk-sdzn%n" -BUS="scsi", RESULT="3512345600001ffb8", NAME="disk-sdzo%n" -BUS="scsi", RESULT="351234560000203a0", NAME="disk-sdzp%n" -BUS="scsi", RESULT="35123456000020788", NAME="disk-sdzq%n" -BUS="scsi", RESULT="35123456000020b70", NAME="disk-sdzr%n" -BUS="scsi", RESULT="35123456000020f58", NAME="disk-sdzs%n" -BUS="scsi", RESULT="35123456000021340", NAME="disk-sdzt%n" -BUS="scsi", RESULT="35123456000021728", NAME="disk-sdzu%n" -BUS="scsi", RESULT="35123456000021b10", NAME="disk-sdzv%n" -BUS="scsi", RESULT="35123456000021ef8", NAME="disk-sdzw%n" -BUS="scsi", RESULT="351234560000222e0", NAME="disk-sdzx%n" -BUS="scsi", RESULT="351234560000226c8", NAME="disk-sdzy%n" -BUS="scsi", RESULT="35123456000022ab0", NAME="disk-sdzz%n" -# -# End of autogenerated scsi_id rules -# From b90f1b81895bc4f161794e1aed5784fd98f06571 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Sep 2005 03:38:06 +0200 Subject: [PATCH 1505/4284] delete old Fedora html page Signed-off-by: Kay Sievers --- docs/fedora_udev.html | 258 ------------------------------------------ 1 file changed, 258 deletions(-) delete mode 100644 docs/fedora_udev.html diff --git a/docs/fedora_udev.html b/docs/fedora_udev.html deleted file mode 100644 index 5d5048766d..0000000000 --- a/docs/fedora_udev.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - - Fedora Project, sponsored by Red Hat - - - - - - - - - - - -
    - - -
    - -  Download -  Projects -  FAQ -
    -
    - -
    - - - -
    -
    Site Navigation:
    -
    - - - - -
    -
     
    -
     
    -
    - -

    Udev on Fedora

    -

    by Harald Hoyer

    -

    - This document tries to reveal the secrets of udev and how it works on Fedora. -

    -

    - udev was developed by Greg Kroah-Hartman <greg@kroah.com> with much - help from Dan Stekloff <dsteklof@us.ibm.com>, Kay Sievers <kay.sievers@vrfy.org>, - and many others. -

    -

    - The udev homepage and the - Linux-hotplug-devel mailing list https://lists.sourceforge.net/lists/listinfo/linux-hotplug-devel are the main development sources. -

    -

    - -

    What Does Udev Do?

    -

    - udev provides a dynamic device directory containing only the files for - actually present devices. It creates or removes device node files usually - located in the /dev/ directory, or it renames network interfaces. -

    - As part of the hotplug subsystem, udev is executed if a kernel device - is added or removed from the system. On device creation, udev reads - the sysfs directory of the given device to collect device attributes - like label, serial number or bus device number. These attributes may - be used as keys to determine a unique name for the device. udev maintains - a database for devices present on the system. - On device removal, udev queries its database for the name of the device - file to be deleted. -

    - udev gets called by hotplug, if a module is loaded, and a device is added - or removed. udev looks in /sys/, if the driver provides a "dev" file, which - contains the major and minor number for a device node to communicate with - the driver. After looking in the udev rules (in the /etc/udev/rules.d/ directory), which - specify the device node filename and symlinks, a device node is created - in /dev/ with the permissions, which are specified in /etc/udev/permissions.d/. -

    - After device node creation, removal, or network device renaming, udev - executes the programs in the directory tree under /etc/dev.d/. The - name of a program must end with the .dev suffix, to be recognized. - In addition to the hotplug environment variables, DEVNAME is exported - to make the name of the created node or the name the network device is - renamed to, available to the executed program. The programs in every - directory are sorted in lexical order, while the directories are - searched in the following order: -
      -
    • /etc/dev.d/$(DEVNAME)/*.dev
    • -
    • /etc/dev.d/$(SUBSYSTEM)/*.dev
    • -
    • /etc/dev.d/default/*.dev
    • -
    - -

    How is Udev Integrated on Fedora?

    -

    initrd / initfs

    -

    - mkinitrd copies /sbin/udev.static - to the initrd /sbin/udev and symlinks it to - /sbin/udevstart. -

    -After the kernel boots, it executes the nash script of the initrd. This -mounts a tmpfs filesystem on /dev/. Instead of hotplug /sbin/udev is -called in the initrd phase. udevstart creates all device nodes for the -devices, which are compiled in the kernel and for the modules, which -are loaded by nash.

    - -

    Problems

    - -The whole udev and hotplug infrastructure is -not available in initrd. Thus no hotplug scripts, udev rules, and -permissions and no /etc/dev.d/ scripts are executed for any hotplug -event, which is sent from the kernel. - -

    rc.sysinit

    -

    First, if SELinux is loaded and enabled, -the context of /dev/ is set. rc.sysinit calls /sbin/start_udev. -start_udev mounts a tmpfs filesystem on /dev/, if there is none already -mounted. Then it creates some device nodes, which need module -autoloading, or where there is no kernel module. After that -/sbin/udevstart is called again, which simulates the hotplug events in -the initrd phase, to apply the whole udev rules and permissions. After -that rc.sysinit parses the ouput of /sbin/kmodule and loads every -module. This should provide device nodes for all hardware found on your -computer.

    -

    Console User Permissions

    -

    -/etc/dev.d/default/pam_console.dev is called whenever a device node is -created and calls /sbin/pam_console_setowner with the filename (and an -optional symlink) of the device node. This sets the permissions for -console users like specified in /etc/security/console.perms.

    -

    Customizing Udev on Fedora

    -

    - Read the manpage of udev and udevinfo. - Please try not to modify the files of RPM packages. -

    -

    New Rules

    -

    -New rules should be placed in a file, which ends in .rules in -/etc/udev/rules.d/. Please do not use 50-udev.rules. The supported and -preferred way is to create rules without the "NAME" tag and only -create "SYMLINK"s.

    - A nice document describing how to write rules can be found on http://www.reactivated.net/udevrules.php. -

    - -

    Permissions

    -New permissions should be placed in a file, which ends in -.permissions in /etc/udev/permissions.d/. Please do not use -50-udev.permissions. - -

    But I Really Want My Device Node!

    -

    - Put them in /etc/udev/devices/, and they will get copied to /dev/. File a bugzilla entry, if you think that should be done per default. -

    - -

    Updating to udev Without /dev/

    -

    - The steps to upgrade without Anaconda or a rescue CD are (NOT recommended): -

    - -
      -
    • start from a kernel-2.6 -
    • Make sure /sys/ is mounted -
    • Install the latest initscripts package -
    • Install the latest udev package -
    • Execute /sbin/start_udev -
    • Install the latest mkinitrd package -
    • Install the latest kernel package -
    • Or execute mkinitrd for your existing kernel(s) -
    - -

    Udev without initrd

    - -

    Install Fedore Core as usual and reboot. Execute the following commands -

    - -
    -
    -mkdir /tmp/dev
    -mount --move /dev /tmp/dev
    -sbin/MAKEDEV null console zero
    -mount --move /tmp/dev /dev
    -
    - Install your kernel without an initrd. Reboot. -

    - You will get some SELinux errors, and syslogd will not work as expected. -

    -

    Current Problems on Fedora

    -

    - All open bugs for udev -

    -

    Nvidia

    -

    Quick solution: If you do not need rhgb, just load the nvidia module in /etc/rc.local -

    - If you have udev >= 032-5, load the nvidia module: -

    -
    -
    -cp -a /dev/nvidia* /etc/udev/devices
    -chown root.root /etc/udev/devices/nvidia*
    -
    - -

    The Bugzilla for this problem is 133900.

    -

    Palm Pilot

    -

    - If you have udev >= 032-5, execute the command: -

    -
    -
    -ln -s ttyUSB1 /etc/udev/devices/pilot
    -
    - -

    ISDN

    -

    - If you have udev >= 032-5: -

    -
    -
    -/sbin/MAKEDEV -d /etc/udev/devices isdn
    -
    - - - - - -
    -
     
    -
     
    -
    - - - - - - - - From 14e31b3502b5748068e9367cf4a0d42d9e6cfbf2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Sep 2005 03:49:23 +0200 Subject: [PATCH 1506/4284] add "totally outdated" header to docs/overview :) Signed-off-by: Kay Sievers --- docs/overview | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/overview b/docs/overview index 350d53ee70..87c1d1df10 100644 --- a/docs/overview +++ b/docs/overview @@ -1,5 +1,11 @@ +------------------------------------------------------------------------- + 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 goals for udev: +We've got a couple of goals for udev: 1) dynamic replacement for /dev 2) device naming From 86eeb30e0c349ea7aab1713b0ede29029043ca54 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Sep 2005 03:53:54 +0200 Subject: [PATCH 1507/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/udev.rules | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/udev.rules index 51d182a307..a674f9b510 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/udev.rules @@ -20,7 +20,6 @@ KERNEL=="iseries/vtty*", NAME="%k", GROUP="uucp" # video/graphics SUBSYSTEM=="video4linux", GROUP="video" SUBSYSTEM=="graphics" GROUP="video" -KERNEL=="video*", NAME="%k", GROUP="video" KERNEL=="vtx*", NAME="%k", GROUP="video" KERNEL=="vbi*", NAME="%k", GROUP="video" KERNEL=="winradio*", NAME="%k", GROUP="video" @@ -29,6 +28,8 @@ KERNEL=="nvidia*", NAME="%k", GROUP="video" KERNEL=="nvidiactl*", NAME="%k", 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 'X=%k X=$${X#dvb} A=$${X%%%%.*} D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" @@ -63,6 +64,7 @@ KERNEL=="ts*", NAME="input/%k", MODE="0600" KERNEL=="uinput", NAME="input/%k", MODE="0600" KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" SUBSYSTEM=="input_device", RUN+="/sbin/udev.input_device.sh" +SUBSYSTEM=="input_device", ACTION=="add", ENV{ABS}=="[1-9]*", RUN+="/sbin/modprobe joydev" # printer SUBSYSTEM=="usb", KERNEL=="lp*", ACTION=="add", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" @@ -199,13 +201,13 @@ 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]", ENV{ID_TYPE}=="?*", IMPORT{program}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", IMPORT{program}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="sr*", 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" -KERNEL=="sr*", GOTO="persistent_end" IMPORT{program}="/sbin/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}" From aab571f3621de595dfb2b014040520804c71796c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Sep 2005 12:24:18 +0200 Subject: [PATCH 1508/4284] fix useless but funny name_cdrom.pl script to work again Signed-off-by: Kay Sievers --- extras/name_cdrom.pl | 46 +++++++++++++++----------------------------- 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/extras/name_cdrom.pl b/extras/name_cdrom.pl index 766f6f366a..5e696f33ae 100644 --- a/extras/name_cdrom.pl +++ b/extras/name_cdrom.pl @@ -2,45 +2,31 @@ # a horribly funny script that shows how flexible udev can really be # This is to be executed by udev with the following rules: -# KERNEL="[hs]d[a-z]", PROGRAM="name_cdrom.pl %M %m", NAME="%c{1}", SYMLINK="cdrom" +# +# KERNEL="hd*[!0-9]|sr*", PROGRAM="name_cdrom.pl $tempnode", SYMLINK+="%c" use strict; use warnings; -use CDDB_get qw( get_cddb ); - -my $dev_node = "/tmp/cd_foo"; +use CDDB_get qw(get_cddb); # following variables just need to be declared if different from defaults my %config; -$config{CDDB_HOST}="freedb.freedb.org"; # set cddb host -$config{CDDB_PORT}=8880; # set cddb port -$config{CDDB_MODE}="cddb"; # set cddb mode: cddb or http -$config{CD_DEVICE}="$dev_node"; # set cd device +$config{'CDDB_HOST'} = "freedb.freedb.org"; # set cddb host +$config{'CDDB_PORT'} = 8880; # set cddb port +$config{'CDDB_MODE'} = "cddb"; # set cddb mode: cddb or http +$config{'CD_DEVICE'} = $ARGV[0]; # set cd device +$config{'input'} = 0; # no user interaction -# No user interaction, this is a automated script! -$config{input}=0; +my %cd = get_cddb(\%config); -my $major = $ARGV[0]; -my $minor = $ARGV[1]; - -# create our temp device node to read the cd info from -unlink($dev_node); -if (system("mknod $dev_node b $major $minor")) { - die "bad mknod failed"; +if (!defined $cd{title}) { + exit 1; } -# get it on -my %cd=get_cddb(\%config); +# print out our cd name +$cd{artist} =~ s/ /_/g; +$cd{title} =~ s/ /_/g; +print "$cd{artist}-$cd{title}\n"; -# remove the dev node we just created -unlink($dev_node); - -# print out our cd name if we have found it or skip rule by nonzero exit -if (defined $cd{title}) { - $cd{artist} =~ s/ /_/g; - $cd{title} =~ s/ /_/g; - print "$cd{artist}-$cd{title}\n"; -} else { - exit -1; -} +exit 0; From f432183eb8cfdd21a4445c77273d6aa4f2d1c5dd Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 8 Sep 2005 12:45:09 +0200 Subject: [PATCH 1509/4284] update TODO Signed-off-by: Kay Sievers --- TODO | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/TODO b/TODO index 63e518feeb..a992547377 100644 --- a/TODO +++ b/TODO @@ -1,14 +1,19 @@ This is a short list of things that needs to be done. They are in no specific -order. I will gladly accept patches for any of these items, or any other stuff -people offer up. +order. We will gladly accept patches for any of these items: -greg k-h -greg@kroah.com +- More documentation: + Allmost all extras/*_id/ programs don't have a man page + some details are missing in the udev man pages. +- Completely replace the built-in wait_for_sysfs stuff in udev_sysfs.c + by rules using the WAIT_FOR_SYSFS key. + +- Log the relationship of the kernel name and the persistent disk name + to syslog, so any error logged from the kernel can be associated with + any of the links. + +- Do generic early boot logic: + initramfs, pivot-root, cover coldplug or event replay, etc... + +- Keep the distro rules in etc/ up-to-date. -- more documentation (can never have too much.) -- persuade the distro packagers to submit their changes (or just steal them - if we can find them...) -- do early boot logic (putting udev into initramfs, handle pivot-root, - etc.) -- solve world hunger From 609435bad66d5b33db367c341ab528239044d346 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 9 Sep 2005 12:38:58 +0200 Subject: [PATCH 1510/4284] firmware_helper: fix write count --- extras/firmware/firmware_helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/firmware/firmware_helper.c b/extras/firmware/firmware_helper.c index 7b7a307298..45815137ac 100644 --- a/extras/firmware/firmware_helper.c +++ b/extras/firmware/firmware_helper.c @@ -118,9 +118,9 @@ int main(int argc, char **argv) { count = 0; while (count < fw_buffer_size) { - int c; + ssize_t c; - c = write(fw_fd, fw_buffer+count, fw_buffer_size); + c = write(fw_fd, fw_buffer+count, fw_buffer_size-count); if (c <= 0) { rc = errno; close(fw_fd); From 7a526da67da5be9522af02c2c10511a088402356 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 10 Sep 2005 23:35:30 +0200 Subject: [PATCH 1511/4284] Makefile: fix prerequisits for $(PROGRAMS) Signed-off-by: Kay Sievers --- Makefile | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 80364c2a7a..07f57519ab 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,6 @@ HEADERS = \ udev.h \ udev_utils.h \ udev_rules.h \ - udev_version.h \ udev_db.h \ udev_sysfs.h \ logging.h \ @@ -229,19 +228,27 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) done; .PHONY: all -$(PROGRAMS): $(HOST_PROGS) $(KLCC) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) - $(QUIET) $(CC) $(CFLAGS) -c -o $@.o $@.c - $(QUIET) $(LD) $(LDFLAGS) -o $@ $@.o $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +# clear implicit rules +.SUFFIXES: + +# build the objects +%.o: %.c + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + +# "Static Pattern Rule" to build all programs +$(PROGRAMS): %: $(HOST_PROGS) $(KLCC) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) %.o + $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) $(QUIET) $(STRIPCMD) $@ -# our own copy of klibc if KLCC is specified it will not be used +# our own copy of klibc, it is not used if KLCC is given $(KLCC): - $(MAKE) -j1 -C klibc KRNLSRC=$(KERNEL_DIR) SUBDIRS=klibc TESTS= \ + $(MAKE) -C klibc KRNLSRC=$(KERNEL_DIR) SUBDIRS=klibc TESTS= \ SHLIBDIR=$(KLIBC_INSTALL)/lib \ INSTALLDIR=$(KLIBC_INSTALL) \ bindir=$(KLIBC_INSTALL)/bin \ mandir=$(KLIBC_INSTALL)/man all install -find $(KLIBC_INSTALL)/include -name SCCS -print| xargs rm -rf +.NOTPARALLEL: $(KLCC) $(UDEV_OBJS): $(KLCC) $(LIBUDEV): $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS) @@ -276,9 +283,6 @@ udev_version.h: xmlto man $? .PRECIOUS: %.8 -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< - ccdv: ccdv.c @$(HOSTCC) -O1 ccdv.c -o ccdv .SILENT: ccdv From 17d3cb12882f71f19a78beb26054054628423703 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 12 Sep 2005 14:21:14 +0200 Subject: [PATCH 1512/4284] Makefile: cleanup install targets Split into individual target and never remove any config file. Signed-off-by: Kay Sievers --- Makefile | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 07f57519ab..773041b02f 100644 --- a/Makefile +++ b/Makefile @@ -194,6 +194,7 @@ ifeq ($(strip $(USE_KLIBC)),true) LD = $(KLCC) else CFLAGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations + LDFLAGS += -Wl,-warn-common endif ifeq ($(strip $(USE_SELINUX)),true) @@ -227,6 +228,7 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) -C $$target $@; \ done; .PHONY: all +.DEFAULT: all # clear implicit rules .SUFFIXES: @@ -288,8 +290,8 @@ ccdv: ccdv.c .SILENT: ccdv clean: - -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print | xargs rm -f - -rm -f core $(PROGRAMS) $(GEN_HEADERS) $(GEN_CONFIGS) + - find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print0 | xargs -0rt rm -f + - rm -f core $(PROGRAMS) $(GEN_HEADERS) $(GEN_CONFIGS) $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ @@ -342,7 +344,7 @@ uninstall-man: - rm $(mandir)/man8/udevcontrol.8 .PHONY: uninstall-man -install: install-config install-man all +install-bin: $(INSTALL) -d $(DESTDIR)$(udevdir) $(INSTALL_PROGRAM) -D udev $(DESTDIR)$(sbindir)/udev $(INSTALL_PROGRAM) -D udevd $(DESTDIR)$(sbindir)/udevd @@ -361,13 +363,9 @@ endif echo $$target; \ $(MAKE) prefix=$(prefix) -C $$target $@; \ done; -.PHONY: install +.PHONY: install-bin -uninstall: uninstall-man - - rm $(configdir)/rules.d/50-udev.rules - - rm $(configdir)/udev.conf - - rmdir $(configdir)/rules.d - - rmdir $(configdir) +uninstall-bin: - rm $(sbindir)/udev - rm $(sbindir)/udevd - rm $(sbindir)/udevsend @@ -379,16 +377,24 @@ uninstall: uninstall-man - rm $(usrbindir)/udevinfo - rm $(usrbindir)/udevtest - rm -rf $(udevdb) - - rmdir $(udevdir) - killall udevd @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ $(MAKE) prefix=$(prefix) -C $$target $@; \ done; -.PHONY: uninstall-man +.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 + From 852cc0f58dba9d101abf86880aaea4880222de47 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 12 Sep 2005 14:28:59 +0200 Subject: [PATCH 1513/4284] remove chassis_id program Broken and unmaintained! Signed-off-by: Kay Sievers --- extras/chassis_id/Makefile | 51 --------------- extras/chassis_id/README | 28 --------- extras/chassis_id/chassis_id.c | 91 --------------------------- extras/chassis_id/chassis_id.h | 42 ------------- extras/chassis_id/install.txt | 49 --------------- extras/chassis_id/provision.tbl | 5 -- extras/chassis_id/table.c | 106 -------------------------------- extras/chassis_id/udev.rules | 7 --- 8 files changed, 379 deletions(-) delete mode 100644 extras/chassis_id/Makefile delete mode 100644 extras/chassis_id/README delete mode 100644 extras/chassis_id/chassis_id.c delete mode 100644 extras/chassis_id/chassis_id.h delete mode 100644 extras/chassis_id/install.txt delete mode 100644 extras/chassis_id/provision.tbl delete mode 100644 extras/chassis_id/table.c delete mode 100644 extras/chassis_id/udev.rules diff --git a/extras/chassis_id/Makefile b/extras/chassis_id/Makefile deleted file mode 100644 index ae5c95961c..0000000000 --- a/extras/chassis_id/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# * -# * Makefile -# * -# * Copyright (C) 2004 Intel Corporation. All rights reserved. -# * -# * This program is free software; you can redistribute it and/or -# * modify it under the terms of the GNU General Public -# * License v2.0 as published by the Free Software Foundation; -# * -# * 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., 59 Temple Place - Suite 330, -# * Boston, MA 021110-1307, USA. -# * -# * Authors: Atul Sabharwal -# * -# * - -TARGET = chassis_id - -exec_prefix = ${prefix} -sbindir = ${exec_prefix}/sbin -INSTALL = /usr/bin/install -c -INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 -all: chassis_id - -ifneq ($(strip $(USE_KLIBC)),true) -chassis_id: chassis_id.c table.c - $(QUIET) $(CC) -o $(TARGET) $(CFLAGS) chassis_id.c table.c - -install: all - $(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(sbindir)/$(TARGET) -else -chassis_id: - @echo - @echo "!!! chassis_id is incompatible with klibc !!!" - @echo - @exit 0 - -install: all -endif - -clean: - rm -rf core a.out $(TARGET) - diff --git a/extras/chassis_id/README b/extras/chassis_id/README deleted file mode 100644 index 51add4945e..0000000000 --- a/extras/chassis_id/README +++ /dev/null @@ -1,28 +0,0 @@ - README.txt - ~~~~~~~~~~ -Chassis_id is a callout program which is used to give geographic names to devices. It uses -another callout program scsi_id to determine the serial number of a device and then looks up -the provisioning table based on this key. It retrieves geographic information -( chassis#, slot# and host# ) about the device and prints it to stdout. These fields are -used by udev to create the device entry. - -Using Udev: -~~~~~~~~~~ -Chassis_id gets invoked by udev using the udev as below: - -BUS="scsi", PROGRAM="/usr/local/bin/chassis_id", NAME="/chassis%c{1}/slot%c{2}/host%c{3}/disk-%c{4} - -The provisioning table ( file provision.tbl ) has to be put in /usr/local/bin and as of now has -to be populated manually. This is the only place where the geographic map of devices is kept -in the system. - - -Usage Model: -~~~~~~~~~~~~ -On ATCA based blade architecture systems, blade insertion/removal is common. We create names -in a 3 level deep tree which represent the geographic map of the devices. - - -CONTACT: -~~~~~~~~ -Please feel free to contact atul.sabharwal@intel.com with questions, comments, suggestions. diff --git a/extras/chassis_id/chassis_id.c b/extras/chassis_id/chassis_id.c deleted file mode 100644 index de86087921..0000000000 --- a/extras/chassis_id/chassis_id.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * chassis_id.c - * - * Copyright (C) 2004 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v 2.0 as published by the Free Software Foundation; - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - * Authors: Atul Sabharwal - * - */ - -#include -#include -#include - -#include "chassis_id.h" - -//#define DEBUG 1 - -/* Run SCSI id to find serial number of the device */ -static int getserial_number(char * devpath, char * snumber) -{ - FILE *fp; - char vendor[255], model[255], cmd[255]; - int retval; - - sprintf(cmd, "/sbin/scsi_id -s %s -p 0x80", devpath); - - fp = popen(cmd, "r"); - - if (fp == NULL) - return -ERROR_BAD_SNUMBER; - - fscanf(fp, "%s %s %s", vendor, model, snumber); - #ifdef DEBUG - syslog(LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", snumber ); - #endif - - retval = pclose(fp); - if (retval == -1) - return -ERROR_BAD_SNUMBER; - else - return NO_ERROR; -} - -int main(int argc, char **argv, char **envp) -{ - int chassis_num, slot_num, retval; - char disk_snum[255], devpath[255]; - char *ptr; - int disk_index; - - syslog( LOG_PID| LOG_DAEMON| LOG_ERR, "\n%s", "starting chassis_id" ); - - ptr = getenv("DEVPATH"); - if (ptr == NULL) - return -ERROR_NO_DEVPATH; - - sscanf(ptr, "%s", &devpath[0]); - #ifdef DEBUG - syslog(LOG_PID|LOG_DAEMON| LOG_ERR, "Devpath %s", devpath); - #endif - - retval = table_init(); - if (retval < 0) - return -ERROR_BAD_TABLE; - - getserial_number(devpath, disk_snum); - - /* Now we open the provisioning table t find actual entry for the serial number*/ - disk_index = table_find_disk(disk_snum, &chassis_num, &slot_num); - if ( disk_index == -1 ) { - // typical provisioning error - return -ERROR_NO_DISK; - } else { - table_select_disk( disk_index ); - } - return 0; -} diff --git a/extras/chassis_id/chassis_id.h b/extras/chassis_id/chassis_id.h deleted file mode 100644 index 1463bd22c7..0000000000 --- a/extras/chassis_id/chassis_id.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * chassis_id.h - * - * Copyright (C) 2004 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v 2.0 as published by the Free Software Foundation; - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - * Authors: Atul Sabharwal - * - */ - -#ifndef _CHASSIS_ID_H -#define _CHASSIS_ID_H - -//#define DEBUG 1 -#define ERROR 1 -#define ERROR_NO_SLOT 2 -#define ERROR_NO_CHASSIS 3 -#define ERROR_NO_DEVPATH 4 -#define ERROR_BAD_SNUMBER 5 -#define ERROR_NO_DISK 6 -#define ERROR_BAD_TABLE 7 -#define ERROR_BAD_SCAN 8 -#define NO_ERROR 0 - -extern int table_init(void); -extern int table_find_disk(const char *serialnumber , int *chassis_num, int *slot_num); -extern int table_select_disk(int diskindex); - -#endif diff --git a/extras/chassis_id/install.txt b/extras/chassis_id/install.txt deleted file mode 100644 index a567afedcf..0000000000 --- a/extras/chassis_id/install.txt +++ /dev/null @@ -1,49 +0,0 @@ - -Udev does not come pre-installed on a Linux system. Hence, we need to do the following before -a Linux system is ready :: - -Steps: -~~~~~ -1. Install libsysfs shared libraries by installing sysfsutils-0.4.0. - -2. Download latest version of udev from www.kernel.org site. It is - under repository->utils->kernel path chain. - - Do make and make install so as to install udev. To install scsi_id, - go into extras/scsi_id folder to compile scsi_id. Typically, this - would be in /sbin folder. Now, change scsi_id.cfg and set the - global option to work with all devices ( -g) and comment out the - black list option ( -b ). - -3. Download chassis_id callout code and compile. Install chassis_id and - provision.tbl file in /usr/local/bin. - -4. In /etc/rc.sysinit, add mount command to mount the sys memory file - system. ( mount -t sysfs sys /sys ). The /sys is necessary as - lot of the software components expect it to be in /sys. - -5. Now, in /etc/udev/udev.rules, install the udev rules file. This - is the GDN config file which is used by udev to create folders - in the form chasis/slot/port/disk

    . - -6. Now, you are almost there. Refer to PROVISIONING file. - - -PROVISIONING: -1. For GDN, the provisioning file is in the format : - - - SCSI host on which the device is connected - how many disks on this blade ? - chassis Number - Physical slot number - Serial Number for the disk - Name of the disk device. - -2. To fill the provisioning table, the user needs to collect this information and - fill provision.tbl. - - The serial number is found from the command scsi_id -p 0x80 -s . - - The host number is availble from the sys file system. The chassis & slot - are visual data and should be enetered into provision.tbl. diff --git a/extras/chassis_id/provision.tbl b/extras/chassis_id/provision.tbl deleted file mode 100644 index c137fd537f..0000000000 --- a/extras/chassis_id/provision.tbl +++ /dev/null @@ -1,5 +0,0 @@ -id host number_of_disks chassis# slot# serial# name -1 1 2 1 2 3BM07NKA000070456Z6B disk1 -2 1 2 1 2 3BM07R68000070456ZCK disk2 -3 2 2 1 3 3EV08ANK00007219JAVA disk3 -4 2 2 1 4 3EV00NZB000072190Y90 disk4 diff --git a/extras/chassis_id/table.c b/extras/chassis_id/table.c deleted file mode 100644 index ee64ecc774..0000000000 --- a/extras/chassis_id/table.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * table.c - * - * Copyright (C) 2004 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License v2.0 as published by the Free Software Foundation; - * - * 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., 59 Temple Place - Suite 330, - * Boston, MA 021110-1307, USA. - * - * Authors: Atul Sabharwal - * - */ - -#include -#include - -#include "chassis_id.h" - -#define TABLE_SIZE 100 -#define PROVISION_DB "/usr/local/bin/provision.tbl" - -struct provision_record -{ - int id; - int num_disks; - int chassis_num; - int slot_num; - char serial_num[32]; - char name[32]; -} ptable[TABLE_SIZE]; - -int ptable_size; - -/* Initialize the provisioning table by reading the data from special file provision.tbl * - Return error if something does not work appropriately. */ -int table_init(void) -{ - FILE *fp; - char ptr[255]; - int i; - - fp = fopen( PROVISION_DB, "r"); - - if ((fp== NULL) || feof(fp)) - return -1; - - // skip the first line of text which contains descriptive details. - fgets(ptr, 80, fp); - i = 0; - while (!feof(fp)) { - fgets(ptr, 80, fp); - sscanf(ptr, "%d %d %d %d %s %s", &ptable[i].id, - &ptable[i].num_disks, - &ptable[i].chassis_num, &ptable[i].slot_num, - ptable[i].serial_num, ptable[i].name); - i++; - } - - ptable_size = i; - fclose(fp); - return 0; -} - - -/* return -1 when no disk found. Otherwise return index of disk */ -int table_find_disk(const char *serialnumber , int *chassis_num, int *slot_num) -{ - int i; - - for (i = 0; i < ptable_size; i++) { - if (strcmp(ptable[i].serial_num, serialnumber) == 0) { - *chassis_num = ptable[i].chassis_num; - *slot_num = ptable[i].slot_num; - break; - } - } - - if (i == ptable_size) - return -1; - else - return i; -} - -/* This function is primarily there for passing the selected disk entry to udev - * so that it can create descriptive GDN for it. So, for that we need to output - * this data to stdout. - */ -int table_select_disk(int diskindex) -{ - printf("%d ", ptable[diskindex].chassis_num); - printf("%d ", ptable[diskindex].slot_num); - printf("%s ", ptable[diskindex].name); - - return 0; -} - diff --git a/extras/chassis_id/udev.rules b/extras/chassis_id/udev.rules deleted file mode 100644 index b1618c1b0b..0000000000 --- a/extras/chassis_id/udev.rules +++ /dev/null @@ -1,7 +0,0 @@ -# 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 -# - -BUS="scsi", PROGRAM="/usr/local/bin/chassis_id", NAME="/chassis%c{1}/slot%c{2}/%c{3}" From a8b38f1c44c8a925bef467c7fbca7812dfbf86f8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 12 Sep 2005 15:26:33 +0200 Subject: [PATCH 1514/4284] fic gcov use and move it into the Makefile Signed-off-by: Kay Sievers --- Makefile | 37 +++++++++++++ .../README-gcov_for_udev | 42 +++++---------- make_gcov.sh | 53 ------------------- run_gcov.sh | 40 -------------- 4 files changed, 49 insertions(+), 123 deletions(-) rename README-gcov_for_udev => docs/README-gcov_for_udev (70%) delete mode 100644 make_gcov.sh delete mode 100644 run_gcov.sh diff --git a/Makefile b/Makefile index 773041b02f..2017e7be3b 100644 --- a/Makefile +++ b/Makefile @@ -27,6 +27,10 @@ USE_LOG = true # to print the debug messages to syslog) DEBUG = false +# compile with gcc's code coverage option +# (use it with DEBUG, works only with glibc) +USE_GCOV = false + # include Security-Enhanced Linux support USE_SELINUX = false @@ -186,6 +190,11 @@ else STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment endif +ifeq ($(strip $(USE_GCOV)),true) + CFLAGS += -fprofile-arcs -ftest-coverage + LDFLAGS = -fprofile-arcs +endif + # if our own version of klibc is used, we need to build it ifeq ($(strip $(USE_KLIBC)),true) KLIBC_INSTALL = $(PWD)/klibc/.install @@ -291,6 +300,10 @@ ccdv: ccdv.c clean: - find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print0 | xargs -0rt rm -f + - find -name "*.gcno" -print0 | xargs -0rt rm -f + - find -name "*.gcda" -print0 | xargs -0rt rm -f + - find -name "*.gcov" -print0 | xargs -0rt rm -f + - rm -f udev_gcov.txt - rm -f core $(PROGRAMS) $(GEN_HEADERS) $(GEN_CONFIGS) $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)"; for target in $$extras; do \ @@ -397,4 +410,28 @@ test tests: all buildtest: ./test/simple-build-check.sh +.PHONY: buildtest + +gcov-all: + $(MAKE) clean all DEBUG=true 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/README-gcov_for_udev b/docs/README-gcov_for_udev similarity index 70% rename from README-gcov_for_udev rename to docs/README-gcov_for_udev index ca832803a2..c223dc38e8 100644 --- a/README-gcov_for_udev +++ b/docs/README-gcov_for_udev @@ -2,6 +2,8 @@ Using GCC's code coverage tool, gcov, with udev +Leann Ogasawara , April 2004 + ################################################ For more information on using gcov please see: @@ -13,14 +15,11 @@ 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. I've also compiled a udev_for_dev - toubleshooting document for Red Hat which can be found in: - - docs/rh_udev_for_dev.txt + documents in udev tarball. - execute make_gcov.sh from udev top level directory - ./make_gcov.sh + 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 @@ -28,21 +27,9 @@ Note that this was developed with udev version 024. also add the -fprofile-arcs and -ftest-coverage options which are the necessary flags needed to use gcov. - make_gcov.sh will assume the same default parameters as the regular - make but also accepts the same parameters. For example if you want - to get code coverage analysis for udev with the DEBUG flag turned - on, you would just execute: - - ./make_gcov.sh DEBUG=true - - There is one exception, gcov will not work with klibc as it does not - compile cleanly with the -fprofile-arcs and -ftest-coverage flags. - With this said it is pretty much useless to set the KERNEL_DIR flag - when using make_gcov.sh as well. - - Don't be alarmed if you look into your udev directory and see that it - has been polluted with a bunch of *.bb, *.bbg, *.da, and *.gcov files. - gcov creates and uses these files to extract the code coverage info. + 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, @@ -58,7 +45,7 @@ Note that this was developed with udev version 024. level directory. You need to be root to do this. su to root - ./run_gcov.sh + 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 @@ -95,14 +82,9 @@ Note that this was developed with udev version 024. was never hit during execution. - Once you are done with using gcov for udev and want to return to your - normal use of udev. Simply, + 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_gcov.sh clean - - This will clean out all the *.bb, *.bbg, *.da, *.gcov files produced by gcov. - It will also 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 + make clean all su to root - make isntall + make install diff --git a/make_gcov.sh b/make_gcov.sh deleted file mode 100644 index e3ceb96d07..0000000000 --- a/make_gcov.sh +++ /dev/null @@ -1,53 +0,0 @@ -#!/bin/sh -# -# gcov capability for udev -# -# Provides code coverage analysis for udev. -# -# make_gcov.sh assumes the same same default parameters as make, but also -# accepts the same parameters as make (see README file in udev/ for -# parameter info). There is one exception, klibc can not be used with -# gcov as it will not compile cleanly. -# -# make_gcov.sh then overrides CFLAGS to strip out optimization in order -# for gcov to get correct code coverage analysis. -# -# Leann Ogasawara , April 2004 - -# clean up udev dir -clean_udev () { - find -name "*.gcno" -exec rm -f "{}" \; - find -name "*.gcda" -exec rm -f "{}" \; - find -name "*.gcov" -exec rm -f "{}" \; - rm -f udev_gcov.txt - make clean -} - -PWD=`pwd` -GCCINCDIR=`gcc -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"` -LIBSYSFS="-I$PWD/libsysfs/sysfs -I$PWD/libsysfs" -WARNINGS="-Wall -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations" -GCC="-I$GCCINCDIR" -USE_LOG="-DUSE_LOG" -DEBUG="-D_GNU_SOURCE" -GCOV_FLAGS="-pipe -fprofile-arcs -ftest-coverage" - -for i in $*; do - pre=`echo $i | sed 's/=.*//g'` - post=`echo $i | sed 's/.*=//g'` - if [ $pre = "USE_KLIBC" ] && [ $post = "true" ]; then - echo "cannot use gcov with klibc, will not compile" - exit - elif [ $pre = "USE_LOG" ] && [ $post = "false" ]; then - USE_LOG="" - elif [ $pre = "DEBUG" ] && [ $post = "true" ]; then - DEBUG="-g -DDEBUG -D_GNU_SOURCE" - elif [ $pre = "clean" ]; then - clean_udev - exit - fi -done - -clean_udev - -make $* CFLAGS="$WARNINGS $GCOV_FLAGS $USE_LOG $DEBUG $GCC $LIBSYSFS" LDFLAGS="-Wl,-warn-common -fprofile-arcs" diff --git a/run_gcov.sh b/run_gcov.sh deleted file mode 100644 index ad6a62b130..0000000000 --- a/run_gcov.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -# -# run gcov on udev -# -# Generate code coverage analysis for udev files -# -# This requires that you compiled udev with gcov flags i.e. -# you should have compiled udev with the make_gcov.sh script. -# -# Leann Ogasawara , April 2004 - -PWD=`pwd` - -# check if root else may not have access to *.da files -# and gcov analysis will fail. -if [ $(id -u) -ne 0 ]; then - echo "please become root before executing run_gcov.sh" - exit 1 -fi - -echo > udev_gcov.txt -echo "CODE COVERAGE ANALYSIS FOR UDEV" >> udev_gcov.txt -echo >> udev_gcov.txt - -for file in `find -maxdepth 1 -name "*.gcno"`; do - name=`basename $file .gcno` - echo "################" >> udev_gcov.txt - echo "$name.c" >> udev_gcov.txt - echo "################" >> udev_gcov.txt - if [ -e "$name.gcda" ]; then - gcov -l "$name.c" >> udev_gcov.txt 2>&1 - else - echo "code for $name.c was never executed" >> udev_gcov.txt 2>&1 - echo "no code coverage analysis to be done" >> udev_gcov.txt 2>&1 - fi - echo >> udev_gcov.txt -done - -echo "udev gcov analysis done. View udev_gcov.txt for results." From 9d97f3bb7974103efb9602e2066b95e4cb529e53 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 12 Sep 2005 16:00:09 +0200 Subject: [PATCH 1515/4284] FAQ: update things that have changed Signed-off-by: Kay Sievers --- FAQ | 92 ++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 43 deletions(-) diff --git a/FAQ b/FAQ index bd9d63a4d5..1b9e56d8c5 100644 --- a/FAQ +++ b/FAQ @@ -1,40 +1,40 @@ 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 /sbin/hotplug calls that the - kernel makes whenever a device is added or removed from the kernel. All - naming policy, and permission control is done in userspace. devfs - operated from within the kernel. +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 marked OBSOLETE if udev is not finished yet? +Q: Why was devfs marked OBSOLETE/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. + - 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: If you really require this functionality, then use devfs. It is still - present in the kernel. +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: But wait, I really want udev to automatically load drivers when they are not present but the device node is opened. It's the only reason I like using devfs. Please make udev do this. -A: No. udev is for managing /dev, not loading kernel drivers. +A: No. udev is for managing /dev, not loading kernel drivers. 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 @@ -53,9 +53,14 @@ A: The devfs approach caused a lot of spurious modprobe attempts as Q: I really like the devfs naming scheme, will udev do that? A: Yes, udev can create /dev nodes using the devfs naming policy. A configuration file needs to be created to map the kernel default names - to the devfs names. See the initial udev.rules.devfs file in the udev - release. It is the start of such a configuration file. If there are - any things missing, please let the udev authors know. + to the devfs names. See the udev.rules.devfs file in the udev + release. + Note that the devfs scheme is not recommended or officially supported + cause it is a really 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 disk rules for an example how to do it correctly in userspace + without any stupid device enumeration. Q: What kinds of devices does udev create nodes for? A: All devices that are shown in sysfs will work with udev. If more @@ -70,29 +75,30 @@ A: udev is entirely in userspace. If the kernel supports a greater number of anonymous devices, udev will support it. Q: Will udev support symlinks? -A: Yes, It now does. Multiple symlinks per device node too. +A: Yes, It now does. Multiple symlinks per device node are supported. Q: How will udev handle the /dev filesystem? -A: /dev can be a ramfs, or a backing filesystem. udev does not care what - kind of filesystem it runs on. +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 will be placed in initramfs and run for every device that is found. - Work to get this implemented is still underway. +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. Projects that do - automount hotplugged storage devices are: - * Usb-mount http://users.actrix.co.nz/michael/usbmount.html - * devlabel http://linux.dell.com/projects.shtml#devlabel - - Alternatively, it is easy to add the following to fstab: - /udev/pendrive /pendrive vfat user,noauto 0 0 +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 into the desktop software. + + 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 /pendrive - And don't have to be root but will get full permissions on /pendrive. - This works even without udev if /udev/pendrive is replaced by /dev/sda1 + $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 @@ -103,15 +109,15 @@ A: When using dynamic device numbers, a given pair of major/minor numbers may 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 in a separate filesystem (tmpfs, ramfs, ...). - + /dev in 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 - + Archives of the mailing list can be found at: - + From a2c7b2173ab1c365157d07795a58a5e37a083c04 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 13 Sep 2005 10:24:51 -0700 Subject: [PATCH 1516/4284] 069 release --- ChangeLog | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index b18208e245..1e39f722c4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,72 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 2017e7be3b..95b657c47c 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 068 +VERSION = 069 # set this to make use of syslog USE_LOG = true diff --git a/udev.spec b/udev.spec index 25bc2d7f2c..4997528257 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace device manager providing devfs functionality Name: udev -Version: 068 +Version: 069 Release: 1 License: GPL Group: Utilities/System From 23fd5f886c6847fd1917cefd7cb6d3eba0b9df1d Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 13 Sep 2005 10:39:07 -0700 Subject: [PATCH 1517/4284] fix scsi_id rule in gentoo config file --- etc/udev/gentoo/udev.rules | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index f1e38b8d87..cba8e677c2 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -262,8 +262,8 @@ KERNEL=="hd*[0-9]", IMPORT{parent}=="ID_*", SYMLINK+="disk/by-id/ata-$env{ID_MOD KERNEL=="sd*[!0-9]", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p -d %N" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p -d %N" KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*" KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" From 8c65c6a1be91dd3a3da2b5c3b304ec02ad3c67f9 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Tue, 13 Sep 2005 14:10:27 -0700 Subject: [PATCH 1518/4284] fix nbd error messages with a gentoo rule hack --- etc/udev/gentoo/udev.rules | 1 + 1 file changed, 1 insertion(+) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index cba8e677c2..0c705f778d 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -250,6 +250,7 @@ KERNEL=="tpm*", NAME="%k", OWNER="tss", GROUP="tss", MODE="0600" # Skip all of this if we are not adding a block device ACTION!="add", GOTO="persistent_end" SUBSYSTEM!="block", GOTO="persistent_end" +KERNEL=="ram*|loop*|fd*|nbd*", GOTO="persistent_end" # skip accessing removable ide devices, cause the ide drivers are horrible broken BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" From 1ac216b198e559163b1c81eca2f1c9a635d8e326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrg=20Billeter?= Date: Wed, 14 Sep 2005 14:27:28 +0200 Subject: [PATCH 1519/4284] EXTRAS/Makefile: fix install targets to match main Makefile --- Makefile | 12 ++++++++++++ extras/ata_id/Makefile | 4 ++-- extras/cdrom_id/Makefile | 4 ++-- extras/dasd_id/Makefile | 4 ++-- extras/edd_id/Makefile | 4 ++-- extras/firmware/Makefile | 4 ++-- extras/floppy/Makefile | 4 ++-- extras/run_directory/Makefile | 4 ++-- extras/scsi_id/Makefile | 11 ++++++++--- extras/usb_id/Makefile | 4 ++-- extras/volume_id/Makefile | 4 ++-- 11 files changed, 38 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index 95b657c47c..7e3adb975b 100644 --- a/Makefile +++ b/Makefile @@ -333,6 +333,10 @@ install-config: $(GEN_CONFIGS) echo "pick a udev rules file from the etc/udev directory that matches your distribution"; \ echo; \ fi + @extras="$(EXTRAS)"; for target in $$extras; do \ + echo $$target; \ + $(MAKE) prefix=$(prefix) -C $$target $@; \ + done; .PHONY: install-config install-man: @@ -344,6 +348,10 @@ install-man: $(INSTALL_DATA) -D udevsend.8 $(DESTDIR)$(mandir)/man8/udevsend.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 \ + echo $$target; \ + $(MAKE) prefix=$(prefix) -C $$target $@; \ + done; .PHONY: install-man uninstall-man: @@ -355,6 +363,10 @@ uninstall-man: - rm $(mandir)/man8/udevmonitor.8 - rm $(mandir)/man8/udevsend.8 - rm $(mandir)/man8/udevcontrol.8 + @extras="$(EXTRAS)"; for target in $$extras; do \ + echo $$target; \ + $(MAKE) prefix=$(prefix) -C $$target $@; \ + done; .PHONY: uninstall-man install-bin: diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index eab01ad9ab..769b7e3c2d 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -43,8 +43,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index 6ea5f14ec1..c6dfc4e1a8 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -44,8 +44,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index f2c0595de0..23331ce14c 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -43,8 +43,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/edd_id/Makefile b/extras/edd_id/Makefile index 627884a329..aa3db4f209 100644 --- a/extras/edd_id/Makefile +++ b/extras/edd_id/Makefile @@ -43,8 +43,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index 343d5295f1..5632e0dee5 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -44,8 +44,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index 5380590c9b..b7915fc484 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -43,8 +43,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index c1a83e3c0b..38ef7b128e 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -45,9 +45,9 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(DEVD) $(DESTDIR)$(sbindir)/$(DEVD) $(INSTALL_PROGRAM) $(HOTPLUGD) $(DESTDIR)$(sbindir)/$(HOTPLUGD) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(DEVD) diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 3c38d6171e..3b75e165fb 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -46,18 +46,23 @@ all: $(PROG) # XXX use a compressed man page? -install: all +install-bin: all $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + +install-man: $(INSTALL_DATA) -D scsi_id.8 $(DESTDIR)$(mandir)/man8/scsi_id.8 + +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 -uninstall: +uninstall-bin: -rm $(DESTDIR)$(sbindir)/$(PROG) + +uninstall-man: -rm $(DESTDIR)$(mandir)/man8/scsi_id.8 - -rm $(DESTDIR)$(etcdir)/scsi_id.config GEN_HEADER=scsi_id_version.h diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index 4347fba407..10dd09da21 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -44,8 +44,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 8ca3bd1333..c1dd74f0f7 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -47,8 +47,8 @@ clean: spotless: clean -install: all +install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) -uninstall: +uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) From b4f192f054410bf9ddd04b770f0b46f0fd25abce Mon Sep 17 00:00:00 2001 From: Amir Shalem Date: Wed, 14 Sep 2005 14:28:13 +0200 Subject: [PATCH 1520/4284] udevd: fix udevd read() calls to leave room for null byte --- udevd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevd.c b/udevd.c index 96d4fbb3be..e227a64d71 100644 --- a/udevd.c +++ b/udevd.c @@ -195,7 +195,7 @@ static int running_processes(void) if (f == -1) return -1; - len = read(f, buf, sizeof(buf)); + len = read(f, buf, sizeof(buf)-1); close(f); if (len <= 0) @@ -244,7 +244,7 @@ static int running_processes_in_session(pid_t session, int limit) if (f == -1) continue; - len = read(f, line, sizeof(line)); + len = read(f, line, sizeof(line)-1); close(f); if (len <= 0) From 129979643f5ae0363cef23978bce5d546be2f77d Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Wed, 14 Sep 2005 14:28:59 +0200 Subject: [PATCH 1521/4284] fix a debug text typo in udev_rules.c --- udev_rules.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev_rules.c b/udev_rules.c index 7c73356831..ad3629d39d 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -648,7 +648,7 @@ found: } pos = getenv(attr); if (pos == NULL) { - dbg("env '%s' not avialable", attr); + dbg("env '%s' not available", attr); break; } dbg("substitute env '%s=%s'", attr, pos); From 726b21604aa5132090a6be1068da7f58069849ab Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Sep 2005 14:29:59 +0200 Subject: [PATCH 1522/4284] volume_id: fix error handling with failing read() Signed-off-by: Kay Sievers --- extras/volume_id/vol_id.c | 1 + extras/volume_id/volume_id/util.c | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 3c75bdaa2f..2b53085c72 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -145,6 +145,7 @@ int main(int argc, char *argv[]) if (ioctl(vid->fd, BLKGETSIZE64, &size) != 0) size = 0; + dbg("BLKGETSIZE64=%llu", size); if (volume_id_probe_all(vid, 0, size) == 0) goto print; diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index 62b96a3657..d1271a86be 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -197,7 +197,7 @@ set: uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) { - size_t buf_len; + ssize_t buf_len; dbg("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 */ @@ -224,7 +224,7 @@ uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) } dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); id->sbbuf_len = buf_len; - if (buf_len < off + len) { + if ((size_t)buf_len < off + len) { dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); return NULL; } @@ -261,7 +261,7 @@ uint8_t *volume_id_get_buffer(struct volume_id *id, uint64_t off, size_t len) dbg("got 0x%zx (%zi) bytes", buf_len, buf_len); id->seekbuf_off = off; id->seekbuf_len = buf_len; - if (buf_len < len) { + if ((size_t)buf_len < len) { dbg("requested 0x%zx bytes, got only 0x%zx bytes", len, buf_len); return NULL; } From db28d2ea4f95aee82ec3619546546eb1506be46a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Sep 2005 17:00:02 +0200 Subject: [PATCH 1523/4284] EXTRAS: cleanup and sync all Makefiles Signed-off-by: Kay Sievers --- Makefile | 17 +++-- extras/ata_id/Makefile | 54 ++++++++++------ extras/cdrom_id/Makefile | 61 ++++++++++++------ extras/dasd_id/Makefile | 54 ++++++++++------ extras/edd_id/Makefile | 54 ++++++++++------ extras/firmware/Makefile | 54 ++++++++++------ extras/floppy/Makefile | 53 ++++++++++------ extras/run_directory/Makefile | 65 +++++++++++-------- extras/scsi_id/Makefile | 116 ++++++++++++++++++---------------- extras/usb_id/Makefile | 54 ++++++++++------ extras/volume_id/Makefile | 60 +++++++++++------- test/simple-build-check.sh | 1 - 12 files changed, 405 insertions(+), 238 deletions(-) diff --git a/Makefile b/Makefile index 7e3adb975b..46d5365694 100644 --- a/Makefile +++ b/Makefile @@ -147,8 +147,6 @@ STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib HOSTCC = gcc -export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS - # code taken from uClibc to determine the current arch ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/powerpc/ppc/g'} @@ -229,7 +227,12 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ $(MAKE) prefix=$(prefix) \ + CC="$(CC)" \ + CFLAGS="$(CFLAGS)" \ LD="$(LD)" \ + LDFLAGS="$(LDFLAGS)" \ + STRIPCMD="$(STRIPCMD)" \ + LIB_OBJS="$(LIB_OBJS)" \ LIBUDEV="$(PWD)/$(LIBUDEV)" \ LIBSYSFS="$(PWD)/$(LIBSYSFS)" \ KERNEL_DIR="$(KERNEL_DIR)" \ @@ -243,7 +246,7 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) .SUFFIXES: # build the objects -%.o: %.c +%.o: %.c $(GEN_HEADERS) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ # "Static Pattern Rule" to build all programs @@ -379,15 +382,15 @@ install-bin: $(INSTALL_PROGRAM) -D udevinfo $(DESTDIR)$(usrbindir)/udevinfo $(INSTALL_PROGRAM) -D udevtest $(DESTDIR)$(usrbindir)/udevtest $(INSTALL_PROGRAM) -D udevstart $(DESTDIR)$(sbindir)/udevstart + @extras="$(EXTRAS)"; for target in $$extras; do \ + echo $$target; \ + $(MAKE) prefix=$(prefix) -C $$target $@; \ + done; ifndef DESTDIR - killall udevd - rm -rf $(udevdb) - $(sbindir)/udevd --daemon endif - @extras="$(EXTRAS)"; for target in $$extras; do \ - echo $$target; \ - $(MAKE) prefix=$(prefix) -C $$target $@; \ - done; .PHONY: install-bin uninstall-bin: diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index 769b7e3c2d..d93e694778 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -1,15 +1,15 @@ -# Makefile for ata_id +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2004 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # PROG = ata_id - -all: $(PROG) +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -18,9 +18,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -28,23 +26,43 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = ata_id.o $(LIBUDEV) +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -$(OBJS): $(HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index c6dfc4e1a8..3e91d4fc47 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -1,16 +1,15 @@ -# Makefile for cdrom_id +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2004 Kay Sievers -# Copyright (C) 2005 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. +# Released under the GNU General Public License, version 2. # PROG = cdrom_id - -all: $(PROG) +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -19,9 +18,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -29,23 +26,49 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = cdrom_id.o $(LIBUDEV) +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -$(OBJS): $(HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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 + +install: all install-bin install-config install-man +.PHONY: install + +uninstall: uninstall-bin uninstall-man +.PHONY: uninstall + diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index 23331ce14c..2a14050d66 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -1,15 +1,15 @@ -# Makefile for dasd_id +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2004 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # PROG = dasd_id - -all: $(PROG) +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -18,9 +18,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -28,23 +26,43 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = dasd_id.o $(LIBUDEV) +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -$(OBJS): $(HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/extras/edd_id/Makefile b/extras/edd_id/Makefile index aa3db4f209..70244ea468 100644 --- a/extras/edd_id/Makefile +++ b/extras/edd_id/Makefile @@ -1,15 +1,15 @@ -# Makefile for edd_id +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2004 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # PROG = edd_id - -all: $(PROG) +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -18,9 +18,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -28,23 +26,43 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(PROG).o $(LIBUDEV) +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -$(OBJS): $(HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/extras/firmware/Makefile b/extras/firmware/Makefile index 5632e0dee5..7de94c40a7 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -1,15 +1,15 @@ -# Makefile for firmware_helper +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2005 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # PROG = firmware_helper - -all: $(PROG) +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -18,9 +18,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -28,24 +26,42 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(PROG).o $(LIBUDEV) $(LIBSYSFS) -HEADERS = +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -$(OBJS): $(HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/extras/floppy/Makefile b/extras/floppy/Makefile index b7915fc484..8568e28edf 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -1,15 +1,15 @@ -# Makefile for create_floppy_devices +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2004 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # PROG = create_floppy_devices - -all: $(PROG) +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -18,9 +18,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -28,23 +26,42 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(PROG).o $(LIBUDEV) +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -$(OBJS): $(HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/extras/run_directory/Makefile b/extras/run_directory/Makefile index 38ef7b128e..8444c3ba63 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -1,16 +1,14 @@ -# Makefile for run_directory +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2005 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # - -DEVD = udev_run_devd -HOTPLUGD = udev_run_hotplugd - -all: $(DEVD) $(HOTPLUGD) +PROG = udev_run_devd udev_run_hotplugd +OBJS = run_directory.o +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -19,9 +17,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -29,25 +25,44 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(LIBUDEV) +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -$(DEVD): $(HEADERS) $(DEVD).o run_directory.o - $(QUIET) $(LD) $(LDFLAGS) -o $(DEVD) $(DEVD).o run_directory.o $(OBJS) +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(HOTPLUGD): $(HEADERS) $(HOTPLUGD).o run_directory.o - $(QUIET) $(LD) $(LDFLAGS) -o $(HOTPLUGD) $(HOTPLUGD).o run_directory.o $(OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(DEVD) $(HOTPLUGD) run_directory.o - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all - $(INSTALL_PROGRAM) $(DEVD) $(DESTDIR)$(sbindir)/$(DEVD) - $(INSTALL_PROGRAM) $(HOTPLUGD) $(DESTDIR)$(sbindir)/$(HOTPLUGD) + $(INSTALL_PROGRAM) udev_run_devd $(DESTDIR)$(sbindir)/udev_run_devd + $(INSTALL_PROGRAM) udev_run_devd $(DESTDIR)$(sbindir)/udev_run_hotplugd +.PHONY: install-bin uninstall-bin: - - rm $(DESTDIR)$(sbindir)/$(DEVD) + - rm $(DESTDIR)$(sbindir)/udev_run_devd + - rm $(DESTDIR)$(sbindir)/udev_run_hotplugd +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 3b75e165fb..bb3422a9c4 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -1,85 +1,93 @@ +# Makefile for udev extra invoked from the udev main Makefile # # Copyright (C) 2003 IBM +# 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. +# Released under the GNU General Public License, version 2. # -# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -SCSI_ID_VERSION=0.9 +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 +exec_prefix = ${prefix} +etcdir = ${prefix}/etc +sbindir = ${exec_prefix}/sbin +usrbindir = ${exec_prefix}/usr/bin +usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man +configdir = ${etcdir}/udev/ +srcdir = . -INSTALL = /usr/bin/install -c +INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_SCRIPT = ${INSTALL_PROGRAM} -# Note some of the variables used here are set when built under udev, and -# otherwise might not be set. +# be able to run without udev +LIBSYSFS = -lsysfs +CROSS = +QUIET = +CC = $(CROSS)gcc +LD = $(CROSS)gcc +AR = $(CROSS)ar +STRIPCMD = $(CROSS)strip +RANLIB = $(CROSS)ranlib +HOSTCC = gcc +CFLAGS += -Wall -pipe -fno-builtin -Wstrict-prototypes -Wsign-compare -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 +LDFLAGS += -Wl -CFLAGS+=-Wall -fno-builtin +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -PROG=scsi_id -LIBSYSFS=-lsysfs +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -# -# Built static and stripped when built with udev. -# -# STRIP=-s -# LDFLAGS=$(STRIP) -LD=$(CC) +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -OBJS= scsi_id.o scsi_serial.o +scsi_id_version.h: + @echo "/* This file is auto-generated by the Makefile */" > $@ + @echo \#define SCSI_ID_VERSION \"$(SCSI_ID_VERSION)\" >> $@ + @echo \#define SCSI_ID_CONFIG_FILE \"$(etcdir)/scsi_id.config\" >> $@ -all: $(PROG) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 -# XXX use a compressed man page? +clean: + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all - $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin + +uninstall-bin: + - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin install-man: $(INSTALL_DATA) -D scsi_id.8 $(DESTDIR)$(mandir)/man8/scsi_id.8 +.PHONY: uninstall-man + +uninstall-man: + -rm -f $(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 - -uninstall-bin: - -rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-config -uninstall-man: - -rm $(DESTDIR)$(mandir)/man8/scsi_id.8 - -GEN_HEADER=scsi_id_version.h - -scsi_id_version.h: - @echo "/* This file is auto-generated by the Makefile */" > $@ - @echo \#define SCSI_ID_VERSION \"$(SCSI_ID_VERSION)\" >> $@ - @echo \#define SCSI_ID_CONFIG_FILE \"$(etcdir)/scsi_id.config\" >> $@ -$(OBJS): scsi_id.h scsi.h scsi_id_version.h - -clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADER) - -spotless: clean - -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< - -$(PROG): $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(CRT0) $(OBJS) $(LIBSYSFS) $(LIB_OBJS) $(ARCH_LIB_OBJS) diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index 10dd09da21..1796aaea09 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -1,15 +1,15 @@ -# Makefile for usb_id +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2005 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # PROG = usb_id - -all: $(PROG) +OBJ = +HEADERS = +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -18,9 +18,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -28,24 +26,42 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -OBJS = $(PROG).o $(VOLUME_ID_OBJS) $(LIBUDEV) $(LIBSYSFS) -HEADERS = +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -$(OBJS): $(HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) $(LIB_OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/extras/volume_id/Makefile b/extras/volume_id/Makefile index c1dd74f0f7..56cab10e23 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -1,15 +1,18 @@ -# Makefile for volume_id +# Makefile for udev extra invoked from the udev main Makefile # -# Copyright (C) 2004, 2005 Kay Sievers +# 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. +# Released under the GNU General Public License, version 2. # +VOLUME_ID_BASE=volume_id +include $(VOLUME_ID_BASE)/Makefile.inc + PROG = vol_id - -all: $(PROG) +OBJS = $(VOLUME_ID_OBJS) +HEADERS = $(VOLUME_ID_HEADERS) +GEN_HEADERS = +MAN_PAGES = prefix = exec_prefix = ${prefix} @@ -18,9 +21,7 @@ sbindir = ${exec_prefix}/sbin usrbindir = ${exec_prefix}/usr/bin usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man -devddir = ${etcdir}/dev.d/default configdir = ${etcdir}/udev/ -initdir = ${etcdir}/init.d/ srcdir = . INSTALL = /usr/bin/install -c @@ -28,27 +29,42 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -VOLUME_ID_BASE=volume_id -include $(VOLUME_ID_BASE)/Makefile.inc +all: $(PROG) $(MAN_PAGES) +.PHONY: all +.DEFAULT: all -OBJS = vol_id.o $(VOLUME_ID_OBJS) $(LIBUDEV) -HEADERS = $(VOLUME_ID_HEADERS) +%.o: %.c $(GEN_HEADERS) + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -$(OBJS): $(HEADERS) +$(PROG): %: $(HEADERS) %.o $(OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(STRIPCMD) $@ -.c.o: - $(QUIET) $(CC) $(CFLAGS) -c -o $@ $< - -$(PROG): $(OBJS) $(HEADERS) - $(QUIET) $(LD) $(LDFLAGS) -o $(PROG) $(OBJS) +# man pages +%.8: %.xml + xmlto man $? +.PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) - -spotless: clean + rm -f $(PROG) $(OBJS) $(GEN_HEADERS) +.PHONY: clean install-bin: all $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: install-bin uninstall-bin: - rm $(DESTDIR)$(sbindir)/$(PROG) +.PHONY: uninstall-bin + +install-man: + @echo "Please create a man page for this tool." +.PHONY: uninstall-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/test/simple-build-check.sh b/test/simple-build-check.sh index 27e5c93d90..8becb0b057 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -1,7 +1,6 @@ #/bin/sh EXTRAS="\ - extras/chassis_id \ extras/scsi_id \ extras/ata_id \ extras/volume_id \ From 85701baede56edd4fba042f98550b8dec1a73127 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Sep 2005 17:29:27 +0200 Subject: [PATCH 1524/4284] add install test to 'make buildtest' Signed-off-by: Kay Sievers --- Makefile | 36 ++++++++++++++++++------------------ extras/cdrom_id/Makefile | 7 ------- extras/scsi_id/Makefile | 6 ++++-- test/simple-build-check.sh | 19 +++++++++++++++---- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index 46d5365694..c0e1e46ad7 100644 --- a/Makefile +++ b/Makefile @@ -358,14 +358,14 @@ install-man: .PHONY: install-man uninstall-man: - - rm $(mandir)/man8/udev.8 - - rm $(mandir)/man8/udevinfo.8 - - rm $(mandir)/man8/udevtest.8 - - rm $(mandir)/man8/udevstart.8 - - rm $(mandir)/man8/udevd.8 - - rm $(mandir)/man8/udevmonitor.8 - - rm $(mandir)/man8/udevsend.8 - - rm $(mandir)/man8/udevcontrol.8 + - rm -f $(mandir)/man8/udev.8 + - rm -f $(mandir)/man8/udevinfo.8 + - rm -f $(mandir)/man8/udevtest.8 + - rm -f $(mandir)/man8/udevstart.8 + - rm -f $(mandir)/man8/udevd.8 + - rm -f $(mandir)/man8/udevmonitor.8 + - rm -f $(mandir)/man8/udevsend.8 + - rm -f $(mandir)/man8/udevcontrol.8 @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ $(MAKE) prefix=$(prefix) -C $$target $@; \ @@ -394,16 +394,16 @@ endif .PHONY: install-bin uninstall-bin: - - rm $(sbindir)/udev - - rm $(sbindir)/udevd - - rm $(sbindir)/udevsend - - rm $(sbindir)/udevinitsend - - rm $(sbindir)/udeveventrecoreder - - rm $(sbindir)/udevcontrol - - rm $(sbindir)/udevstart - - rm $(usrsbindir)/udevmonitor - - rm $(usrbindir)/udevinfo - - rm $(usrbindir)/udevtest + - rm -f $(sbindir)/udev + - rm -f $(sbindir)/udevd + - rm -f $(sbindir)/udevsend + - rm -f $(sbindir)/udevinitsend + - rm -f $(sbindir)/udeveventrecoreder + - rm -f $(sbindir)/udevcontrol + - rm -f $(sbindir)/udevstart + - rm -f $(usrsbindir)/udevmonitor + - rm -f $(usrbindir)/udevinfo + - rm -f $(usrbindir)/udevtest - rm -rf $(udevdb) - killall udevd @extras="$(EXTRAS)"; for target in $$extras; do \ diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index 3e91d4fc47..c3ee6e3295 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -65,10 +65,3 @@ uninstall-man: install-config: @echo "no config file to install" .PHONY: install-config - -install: all install-bin install-config install-man -.PHONY: install - -uninstall: uninstall-bin uninstall-man -.PHONY: uninstall - diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index bb3422a9c4..85f6ff6ca8 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -37,8 +37,6 @@ CC = $(CROSS)gcc LD = $(CROSS)gcc AR = $(CROSS)ar STRIPCMD = $(CROSS)strip -RANLIB = $(CROSS)ranlib -HOSTCC = gcc CFLAGS += -Wall -pipe -fno-builtin -Wstrict-prototypes -Wsign-compare -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 LDFLAGS += -Wl @@ -90,4 +88,8 @@ install-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/test/simple-build-check.sh b/test/simple-build-check.sh index 8becb0b057..e69c6451ab 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -15,24 +15,35 @@ EXTRAS="\ [ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build echo KERNEL_DIR: "$KERNEL_DIR" -make spotless EXTRAS="$EXTRAS" >/dev/null -make all $MAKEOPTS EXTRAS="$EXTRAS" || exit -echo -e "\n\n" - +# with debug make spotless EXTRAS="$EXTRAS" >/dev/null make all -j4 $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit echo -e "\n\n" +# without any logging make spotless EXTRAS="$EXTRAS" >/dev/null make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" +# klibc and debug make spotless EXTRAS="$EXTRAS" >/dev/null make all -j4 $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" +# klibc without logging make spotless EXTRAS="$EXTRAS" >/dev/null make all $MAKEOPTS USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" +# install in temporary dir and show it +TEMPDIR="`pwd`/.tmp" +rm -rf $TEMPDIR +mkdir $TEMPDIR +make spotless 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 spotless EXTRAS="$EXTRAS" >/dev/null From 50be1401743704419ba52174302b4c1d06b3898b Mon Sep 17 00:00:00 2001 From: Edward Goggin Date: Wed, 14 Sep 2005 20:23:48 +0200 Subject: [PATCH 1525/4284] scsi_id: derive a UID for a SCSI-2 not compliant with the page 83 This patch is to enable the use of scsi_id to derive a UID for a SCSI-2 device which is not compliant with the page 83 inquiry reply format for either SPC-2 or SPC-3. In this case, the page 83 reply does not contain a list of Identification descriptors but a single binary encoded hexa-decimal Vendor Specified Identifier. The update is being driven by the need for scsi_id to support older model EMC Symmetrix hardware, that is, models 4, 5, and 6. --- extras/scsi_id/scsi_id.8 | 16 +++-- extras/scsi_id/scsi_id.c | 14 +++-- extras/scsi_id/scsi_id.config | 5 ++ extras/scsi_id/scsi_id.h | 10 ++++ extras/scsi_id/scsi_serial.c | 109 +++++++++++++++++++++++++++++++--- 5 files changed, 137 insertions(+), 17 deletions(-) diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index 26df0d3e66..4213468ae4 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -91,10 +91,18 @@ to generate any output. Prefix the identification string with the driver model (sysfs) bus id of the SCSI device. .TP -.BI \-p "\| 0x80 | 0x83" -Use SCSI INQUIRY VPD page code 0x80 or 0x83. The default behaviour is to -query the available VPD pages, and use page 0x83 if found, else page 0x80 -if found, else nothing. +.BI \-p "\| 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 availabe 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 \-s "\| sysfs\-device" Generate an id for the diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index a86b004709..e997be9956 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -67,7 +67,7 @@ static int dev_specified; static int sys_specified; static char config_file[MAX_NAME_LEN] = SCSI_ID_CONFIG_FILE; static int display_bus_id; -static int default_page_code; +static enum page_code default_page_code; static int use_stderr; static int debug; static int hotplug_mode; @@ -519,9 +519,11 @@ static int set_options(int argc, char **argv, const char *short_opts, case 'p': if (strcmp(optarg, "0x80") == 0) { - default_page_code = 0x80; + default_page_code = PAGE_80; } else if (strcmp(optarg, "0x83") == 0) { - default_page_code = 0x83; + default_page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + default_page_code = PAGE_83_PRE_SPC3; } else { log_message(LOG_WARNING, "Unknown page code '%s'\n", optarg); @@ -640,9 +642,11 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, case 'p': if (strcmp(optarg, "0x80") == 0) { - *page_code = 0x80; + *page_code = PAGE_80; } else if (strcmp(optarg, "0x83") == 0) { - *page_code = 0x83; + *page_code = PAGE_83; + } else if (strcmp(optarg, "pre-spc3-83") == 0) { + *page_code = PAGE_83_PRE_SPC3; } else { log_message(LOG_WARNING, "Unknown page code '%s'\n", optarg); diff --git a/extras/scsi_id/scsi_id.config b/extras/scsi_id/scsi_id.config index 0567ecb7d6..4f31b1c498 100644 --- a/extras/scsi_id/scsi_id.config +++ b/extras/scsi_id/scsi_id.config @@ -41,3 +41,8 @@ vendor=someone, model=nicedrive, options=-g # if you rely on the id for persistent naming or multi-path configuration. ## vendor=ELBONIA, model=borken, options=-b + +# EMC SYMMETRIX models 4 and 5, and some model 6 systems return the VSI +# field of the page 83 reply according to SCSI-2 format. This format is +# binary encoded hexa-decimal as opposed to the Identifiscation descriptor +# utilized by both SPC-2 and SPC-3 compliant systems. diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 74b449e984..1c9ed969a7 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -53,3 +53,13 @@ extern void log_message (int level, const char *format, ...) #ifndef u8 typedef unsigned char u8; #endif + +/* + * Page code values. + */ +enum page_code { + PAGE_83_PRE_SPC3 = -0x83, + PAGE_UNSPECIFIED = 0x00, + PAGE_80 = 0x80, + PAGE_83 = 0x83, +}; diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 73d66ee615..d1b1d94f53 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -567,12 +567,12 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned char page_83[SCSI_INQ_BUFF_LEN]; memset(page_83, 0, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(scsi_dev, fd, 1, 0x83, page_83, + retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN); if (retval < 0) return 1; - if (page_83[1] != 0x83) { + if (page_83[1] != PAGE_83) { log_message(LOG_WARNING, "%s: Invalid page 0x83\n", scsi_dev->name); return 1; @@ -616,6 +616,74 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, 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 *scsi_dev, int fd, + char *serial, 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(scsi_dev, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN); + if (retval < 0) + return 1; + + if (page_83[1] != PAGE_83) { + log_message(LOG_WARNING, "%s: Invalid page 0x83\n", scsi_dev->name); + 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++; + } + dprintf("using pre-spc3-83 for %s.\n", scsi_dev->name); + return 0; +} + /* Get unit serial number VPD page */ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int max_len) @@ -627,11 +695,11 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned char buf[SCSI_INQ_BUFF_LEN]; memset(buf, 0, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(scsi_dev, fd, 1, 0x80, buf, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN); if (retval < 0) return retval; - if (buf[1] != 0x80) { + if (buf[1] != PAGE_80) { log_message(LOG_WARNING, "%s: Invalid page 0x80\n", scsi_dev->name); return 1; @@ -674,7 +742,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, return 1; } - if (page_code == 0x80) { + if (page_code == PAGE_80) { if (do_scsi_page80_inquiry(scsi_dev, fd, serial, len)) { retval = 1; goto completed; @@ -682,7 +750,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, retval = 0; goto completed; } - } else if (page_code == 0x83) { + } else if (page_code == PAGE_83) { if (do_scsi_page83_inquiry(scsi_dev, fd, serial, len)) { retval = 1; goto completed; @@ -690,6 +758,31 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, retval = 0; goto completed; } + } else if (page_code == PAGE_83_PRE_SPC3) { + retval = do_scsi_page83_prespc3_inquiry(scsi_dev, fd, serial, 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(scsi_dev, fd, serial, 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) { log_message(LOG_WARNING, "%s: unsupported page code 0x%d\n", scsi_dev->name, page_code); @@ -713,7 +806,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, dprintf("%s: Checking page0\n", scsi_dev->name); for (ind = 4; ind <= page0[3] + 3; ind++) - if (page0[ind] == 0x83) + if (page0[ind] == PAGE_83) if (!do_scsi_page83_inquiry(scsi_dev, fd, serial, len)) { /* @@ -724,7 +817,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, } for (ind = 4; ind <= page0[3] + 3; ind++) - if (page0[ind] == 0x80) + if (page0[ind] == PAGE_80) if (!do_scsi_page80_inquiry(scsi_dev, fd, serial, len)) { /* From b0f6529556e71186b186cbc295ad7e21e2288887 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 14 Sep 2005 21:12:08 +0200 Subject: [PATCH 1526/4284] update RELEASE-NOTES Signed-off-by: Kay Sievers --- RELEASE-NOTES | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 76d945e2e0..31c97ce1b2 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,8 @@ +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 From 8355c61b485dd93683d724469bf88b56fd32a463 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 14 Sep 2005 16:19:07 -0700 Subject: [PATCH 1527/4284] 070 release --- ChangeLog | 26 ++++++++++++++++++++++++++ Makefile | 2 +- udev.spec | 2 +- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1e39f722c4..8f25c0c5b8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +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 ============================================ diff --git a/Makefile b/Makefile index c0e1e46ad7..ed5a87c427 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 069 +VERSION = 070 # set this to make use of syslog USE_LOG = true diff --git a/udev.spec b/udev.spec index 4997528257..2b8eb054c0 100644 --- a/udev.spec +++ b/udev.spec @@ -29,7 +29,7 @@ Summary: A userspace device manager providing devfs functionality Name: udev -Version: 069 +Version: 070 Release: 1 License: GPL Group: Utilities/System From 77914dfeda9caae155f7dcdbeb06dc8574a6f4ad Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Fri, 16 Sep 2005 21:05:15 +0200 Subject: [PATCH 1528/4284] run_directory: fix typo in "make install" --- extras/run_directory/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 8444c3ba63..20b3af340c 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -47,7 +47,7 @@ clean: install-bin: all $(INSTALL_PROGRAM) udev_run_devd $(DESTDIR)$(sbindir)/udev_run_devd - $(INSTALL_PROGRAM) udev_run_devd $(DESTDIR)$(sbindir)/udev_run_hotplugd + $(INSTALL_PROGRAM) udev_run_hotplugd $(DESTDIR)$(sbindir)/udev_run_hotplugd .PHONY: install-bin uninstall-bin: From 4b12433517bfb1a4cdf4eecc5102f2cc5e1e6288 Mon Sep 17 00:00:00 2001 From: John Hull Date: Fri, 16 Sep 2005 21:10:12 +0200 Subject: [PATCH 1529/4284] edd_id: check that EDD id is unique The attached patch adds a check to edd_id.c to verify that the MBR signature on the device node passed to the program is unique to only that disk. Signed-off-by: John Hull --- extras/edd_id/edd_id.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/extras/edd_id/edd_id.c b/extras/edd_id/edd_id.c index 504aac36e6..8ac50e9812 100644 --- a/extras/edd_id/edd_id.c +++ b/extras/edd_id/edd_id.c @@ -63,6 +63,7 @@ int main(int argc, char *argv[]) int sysfs_fd; DIR *dir = NULL; int rc = 1; + char *match = NULL; logging_init("edd_id"); @@ -165,15 +166,24 @@ int main(int argc, char *argv[]) sysfs_id = strtoul(sysfs_id_buf, NULL, 16); if (disk_id == sysfs_id) { - if (export) - printf("ID_EDD=%s\n", dent->d_name); - else - printf("%s\n", dent->d_name); - rc = 0; - break; + if (!match) { + match = dent->d_name; + } else { + 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 (export) + printf("ID_EDD=%s\n", match); + else + printf("%s\n", match); + rc = 0; + close: close(disk_fd); closedir: From 3515c0ad001731edd9a1cbf6e3d9a3161d37eb4b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 16 Sep 2005 21:23:36 +0200 Subject: [PATCH 1530/4284] ata_id: open volume O_NONBLOCK Opticals like that and should be ok for disks too, as long as we don't read(). Signed-off-by: Kay Sievers --- extras/ata_id/ata_id.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index 9579db3105..ba40555a0b 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -122,10 +122,7 @@ int main(int argc, char *argv[]) goto exit; } - fd = open(node, O_RDONLY); - if (fd < 0) - if (errno == ENOMEDIUM) - fd = open(node, O_RDONLY|O_NONBLOCK); + fd = open(node, O_RDONLY|O_NONBLOCK); if (fd < 0) { err("unable to open '%s'", node); rc = 1; From a3f129d054395019d4b2385dede233eb12425c78 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 18 Sep 2005 04:41:09 +0200 Subject: [PATCH 1531/4284] add "Persistent Device Naming" rules file for disks Based on: "Linux Persistent Device Naming", 2004, Hannes Reinecke --- etc/udev/persistent.rules | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 etc/udev/persistent.rules diff --git a/etc/udev/persistent.rules b/etc/udev/persistent.rules new file mode 100644 index 0000000000..0ca0c56545 --- /dev/null +++ b/etc/udev/persistent.rules @@ -0,0 +1,46 @@ +# persistent disk links: /dev/disk/{by-id,by-uuid,by-label,by-path} +# scheme based on "Linux persistent device names", 2004, Hannes Reinecke + +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() +SUBSYSTEM=="block", BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}="1", GOTO="persistent_end" + +# by-id (hardware serial number) +KERNEL=="hd*[!0-9]", IMPORT{program}="/sbin/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}="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -s %p -d $tempnode" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -a -s %p -d $tempnode" +KERNEL=="dasd*[!0-9]", IMPORT{program}="/sbin/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}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="sr*", 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}="/sbin/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}="/sbin/edd_id --export $tempnode" +ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}" + +LABEL="persistent_end" + From 0e5f8a1fcc4b2bb020d865075bb8e543f5b0c230 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 18 Sep 2005 04:49:23 +0200 Subject: [PATCH 1532/4284] scsi_id: switch temporary node creation to /dev /tmp is not writable on most systems, so just use /dev to create a temporary node. If called from a udev rule, "-d $tempnode" should be used and udev will create a temporary node and pass the name before calling scsi_id. Also remove gen_scsi_id_udev_rules.sh per Patrick's request, as it's no longer needed with the persistent disk links. Signed-off-by: Kay Sievers --- extras/scsi_id/gen_scsi_id_udev_rules.sh | 80 ------------------------ extras/scsi_id/scsi_id.8 | 16 +++-- extras/scsi_id/scsi_id.c | 4 +- 3 files changed, 14 insertions(+), 86 deletions(-) delete mode 100644 extras/scsi_id/gen_scsi_id_udev_rules.sh diff --git a/extras/scsi_id/gen_scsi_id_udev_rules.sh b/extras/scsi_id/gen_scsi_id_udev_rules.sh deleted file mode 100644 index 92fde5df1b..0000000000 --- a/extras/scsi_id/gen_scsi_id_udev_rules.sh +++ /dev/null @@ -1,80 +0,0 @@ -#! /bin/sh - -# This script generates and sends to stdout a set of udev.rules for use -# with all scsi block devices on your system. It creates a udev key NAME -# with prefix defaulting to "disk-", and appends the current kernel name -# and the udev kernel number (the partition number, empty for the entire -# disk). -# -# Managing these is probably better done via a gui interface. -# -# You can edit and append the output to your /etc/udev/udev.rules file. -# You probably want to to change names to be non-kernel defaults, so as to -# avoid confusion if a configuration change modifies /sys/block/sd* -# naming. -# -# /etc/scsi_id.config must be properly configured. If you are using this -# script, you probably want a single line enabling scsi_id for all -# devices as follows: -# -# options=-g -# -# The above assumes you will not attach block devices that do not -# properly support the page codes used by scsi_id, this is especially true -# of many USB mass storage devices (mainly flash card readers). -# - -prefix=disk- -scsi_id=/sbin/scsi_id - -sysfs_dir=$(mount | awk '$5 == "sysfs" {print $3}') -if [ "$sysfs_dir" = "" ] -then - sysfs_dir="/sys" - echo "Using sysfs mount point \"$sysfs_dir\"" >&2 -fi - -c=$(ls /${sysfs_dir}/block/sd* 2>/dev/null | wc -l) -if [ $c = 0 ] -then - echo $0 no block devices present >&2 - exit 1 -fi - -echo "#" -echo "# Start of autogenerated scsi_id rules. Edit the NAME portions of these" -echo "# rules to your liking." -echo "#" -first_line=yes - -# -cd ${sysfs_dir}/block -for name in sd* -do - id=$($scsi_id -s /block/$name) - if [ $? != 0 ] - then - echo $0 failed for device $name exiting >&2 - exit 1 - fi - if [ $first_line = "yes" ] - then - first_line=no - echo "BUS=\"scsi\", PROGRAM=\"${scsi_id} -d %N -s %p\", RESULT=\"${id}\", NAME=\"${prefix}${name}%n\"" - echo - echo "# Further RESULT keys use the result of the last PROGRAM rule." - echo "# Be careful not to add any rules containing PROGRAM key between here" - echo "# and the end of this section" - echo - else - # No PROGRAM, so just use the last result of PROGRAM. The - # following is the same as the above without the PROGRAM - # key. - echo "BUS=\"scsi\", RESULT=\"${id}\", NAME=\"${prefix}${name}%n\"" - fi - -done - -echo "#" -echo "# End of autogenerated scsi_id rules" -echo "#" diff --git a/extras/scsi_id/scsi_id.8 b/extras/scsi_id/scsi_id.8 index 4213468ae4..691d5b8b05 100644 --- a/extras/scsi_id/scsi_id.8 +++ b/extras/scsi_id/scsi_id.8 @@ -111,7 +111,10 @@ The sysfs mount point must not be included. For example, use /block/sd, not /sys/block/sd. .TP .BI \-u -Reformat the output : replace all whitespaces by underscores +Reformat the output : replace all whitespaces by underscores. +.TP +.BI \-x +Export all data in KEY= format used to import in other programs. .TP .BI \-v Generate verbose debugging output. @@ -140,13 +143,18 @@ for example: .fi .P -An example \fBudev\fP rule using \fBscsi_id\fP, that will name a block +\fBscsi_id\fP is one of the tools used in the "Linux Persistent Device Names" +scheme that creates persistent device links in /dev/disk. It is called with +the -x option which will print all values in a defined format to let udev +import it into its own environment for later event processing. +.sp +An example custom \fBudev\fP rule using \fBscsi_id\fP, that will name a block device and any partitions for the device matching the \fBscsi_id\fP output of 312345: .sp .nf -BUS="scsi", PROGRAM="/sbin/scsi_id -d %N -s %p", RESULT="312345", NAME="disk%n" +BUS=="scsi", PROGRAM=="/sbin/scsi_id -d %N -s %p", RESULT=="312345", NAME="disk%n" .fi .P @@ -158,7 +166,7 @@ BUS="scsi", PROGRAM="/sbin/scsi_id -d %N -s %p", RESULT="312345", NAME="disk%n" .fi .LP .SH "SEE ALSO" -.BR udev (8), hotplug (8) +.BR udev (8) .SH AUTHORS Developed by Patrick Mansfield based on SCSI ID source included in earlier linux 2.5 kernels, sg_utils source, and SCSI diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index e997be9956..39391f6e2e 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -44,8 +44,8 @@ /* * temporary names for mknod. */ -#define TMP_DIR "/tmp" -#define TMP_PREFIX "scsi" +#define TMP_DIR "/dev" +#define TMP_PREFIX "tmp-scsi" /* * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout) From 3a9fc6416770a617023dade2ffb8952703686b42 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 18 Sep 2005 05:06:10 +0200 Subject: [PATCH 1533/4284] volume_id: set reiser instead of reiserfs for filesystem type Thanks to Theodore Ts'o for the hint and a test image. Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/reiserfs.c | 11 ++++++++--- extras/volume_id/volume_id/volume_id.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index 75d1be05dc..6cffdce8d8 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -82,14 +82,17 @@ int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off) 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; } @@ -99,15 +102,18 @@ int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off) 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, UUID_DCE); + id->type = "reiser4"; goto found; } - rs = (struct reiserfs_super_block *) volume_id_get_buffer(id, off + REISERFS1_SUPERBLOCK_OFFSET, 0x200); - if (rs == NULL) + 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; } @@ -120,7 +126,6 @@ found_label: found: volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - id->type = "reiserfs"; return 0; } diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 84f8fb6740..0f5716b893 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -23,7 +23,7 @@ #include -#define VOLUME_ID_VERSION 48 +#define VOLUME_ID_VERSION 49 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 800c36cd642a38a8d775e3e434cbc984b562032d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 18 Sep 2005 05:08:52 +0200 Subject: [PATCH 1534/4284] update devfs rules header Signed-off-by: Kay Sievers --- etc/udev/udev-devfs.rules | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/etc/udev/udev-devfs.rules b/etc/udev/udev-devfs.rules index 1e71ae1a17..380bbee85b 100644 --- a/etc/udev/udev-devfs.rules +++ b/etc/udev/udev-devfs.rules @@ -1,8 +1,12 @@ -# The use of these rules is not recommended or supported. -# In a world where devices can come and go at any time, the devfs scheme -# of simple device enumeration does not help _anything_. Just forget about -# it. Use custom rules to name your device or look at the persistent device -# naming scheme, which is implemented for disks and add your subsystem. +# The use of these rules is not recommended or supported. This file +# is just kept around to proof that udev is able to emulate the devfs scheme. +# +# In a world where devices can come and go at any time, the devfs device +# naming scheme of simple grouping and enumeration does not help _anything_. +# +# Use custom rules to name your device or look at the persistent device +# naming scheme, which is implemented for disks and extend it in a +# similar way for the subsystem you want a sane node layout for. # ide block devices BUS="ide", KERNEL="hd*", PROGRAM="/etc/udev/ide-devfs.sh %k %b %n", NAME="%k", SYMLINK="%c{1} %c{2}" From 449ac79193438b233508adf6bd7310f875be4d01 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 18 Sep 2005 05:34:05 +0200 Subject: [PATCH 1535/4284] update Debian rules Signed-off-by: Kay Sievers --- etc/udev/debian/cd-aliases.rules | 20 +++---- etc/udev/debian/devfs.rules | 32 ++++++----- etc/udev/debian/hotplugd.rules | 7 +++ etc/udev/debian/permissions.rules | 11 ++-- etc/udev/debian/persistent.rules | 73 ++++++++++++++----------- etc/udev/debian/simple-cd-aliases.rules | 7 --- etc/udev/debian/udev.rules | 18 ++++-- 7 files changed, 93 insertions(+), 75 deletions(-) delete mode 100644 etc/udev/debian/simple-cd-aliases.rules diff --git a/etc/udev/debian/cd-aliases.rules b/etc/udev/debian/cd-aliases.rules index b96d3a571d..22f710032b 100644 --- a/etc/udev/debian/cd-aliases.rules +++ b/etc/udev/debian/cd-aliases.rules @@ -1,17 +1,15 @@ -# These rules create the /dev/{cdrom,dvd,...} symlinks. Also see the -# /etc/udev/cdsymlinks.conf config file. +# These rules create the /dev/{cdrom,dvd,...} symlinks. # # If you would like to statically configure the aliases instead, you can # use rules like: # BUS=="ide", ID=="1.0", SYMLINK+="cdrom" -BUS=="scsi", KERNEL=="sr[0-9]*", \ - PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", \ - SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ - PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", \ - SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -BUS=="ide", KERNEL=="pcd[0-9]*", SYSFS{removable}=="1", \ - PROGRAM="/etc/udev/scripts/cdsymlinks.sh %k", \ - SYMLINK+="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" +# The variables for IDE devices are imported in permissions.rules. +BUS=="scsi", KERNEL=="sr[0-9]*", ACTION=="add", \ + IMPORT{program}="/sbin/cdrom_id --export $tempnode" + +ENV{ID_CDROM}=="?*", SYMLINK+="cdrom%e" +ENV{ID_CDROM_CD_RW}=="?*", SYMLINK+="cdrw%e" +ENV{ID_CDROM_DVD}=="?*", SYMLINK+="dvd%e" +ENV{ID_CDROM_DVD_R}=="?*", SYMLINK+="dvdrw%e" diff --git a/etc/udev/debian/devfs.rules b/etc/udev/debian/devfs.rules index 89e0db2aac..b1696c7d24 100644 --- a/etc/udev/debian/devfs.rules +++ b/etc/udev/debian/devfs.rules @@ -15,30 +15,26 @@ # workaround for devices which do not report media changes BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ - PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT=="IOMEGA ZIP *", \ - NAME="%k", OPTIONS+="all_partitions" + PROGRAM="/sbin/ata_id --export $tempnode", ENV{ID_MODEL}=="IOMEGA_ZIP*", \ + NAME="%k", OPTIONS+="all_partitions" # IDE devices BUS=="ide", KERNEL=="hd[a-z]*", \ PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK+="%k %c{2}" + NAME="%c{1}", SYMLINK+="%k %c{2}" # SCSI devices -BUS=="scsi", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ - NAME="%c{1}", SYMLINK+="%k %c{2}" +BUS=="scsi", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ + NAME="%c{1}", SYMLINK+="%k %c{2}" # RAID controllers -KERNEL=="cciss!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ - NAME="%c{1}", SYMLINK+="%k" -KERNEL=="ida!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ - NAME="%c{1}", SYMLINK+="%k" -KERNEL=="rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ - NAME="%c{1}", SYMLINK+="%k" +KERNEL=="cciss!*|ida!*|rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ + 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" +KERNEL=="md[0-9]*", NAME="md/%n", +KERNEL=="loop[0-9]*", NAME="loop/%n" +KERNEL=="ram[0-9]*", NAME="rd/%n" # USB devices BUS=="usb", KERNEL=="auer[0-9]*", NAME="usb/%k" @@ -50,6 +46,10 @@ BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" BUS=="usb", KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", \ SYMLINK+="pilot" +# usbfs-like devices +SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k K=$${K#usbdev} B=$${K%%%%.*} D=$${K#*.}; echo bus/usb/$$B/$$D'", \ + SYMLINK+="%c" + # serial devices KERNEL=="ttyS[0-9]*", NAME="tts/%n" KERNEL=="ttyUSB[0-9]*", NAME="tts/USB%n" @@ -69,7 +69,7 @@ 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="/etc/udev/scripts/dvb.sh %k", \ +KERNEL=="dvb*", PROGRAM="/bin/sh -c 'KNAME=%k KNAME=$${KNAME#dvb} A=$${KNAME%%%%.*} D=$${KNAME#*.}; echo dvb/adapter$$A/$$D'", \ NAME="%c" KERNEL=="fb[0-9]*", NAME="fb/%n" KERNEL=="card[0-9]*", NAME="dri/%k" @@ -100,6 +100,8 @@ 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" diff --git a/etc/udev/debian/hotplugd.rules b/etc/udev/debian/hotplugd.rules index cf84682abf..e311d22678 100644 --- a/etc/udev/debian/hotplugd.rules +++ b/etc/udev/debian/hotplugd.rules @@ -3,6 +3,13 @@ SUBSYSTEM=="drivers", OPTIONS="last_rule" SUBSYSTEM=="module", OPTIONS="last_rule" # compatibility support for the obsolete hotplug.d and dev.d directories +# do not run the hotplug.d scripts when started from udevstart ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" RUN+="/sbin/udev_run_devd" +# run a command on remove events +ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}" + +# debugging monitor +RUN+="socket:/org/kernel/udev/monitor" + diff --git a/etc/udev/debian/permissions.rules b/etc/udev/debian/permissions.rules index 52d7aa9536..02bfefdd27 100644 --- a/etc/udev/debian/permissions.rules +++ b/etc/udev/debian/permissions.rules @@ -1,12 +1,14 @@ # default permissions for block devices SUBSYSTEM=="block", GROUP="disk" SUBSYSTEM=="block", SYSFS{removable}=="1", GROUP="floppy" +SUBSYSTEM=="block", SYSFS{../removable}=="1", GROUP="floppy" # IDE devices -BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}="1", \ - PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom*", GROUP="cdrom" -BUS=="ide", KERNEL=="ht[0-9]*", GROUP="tape" -BUS=="ide", KERNEL=="nht[0-9]*", GROUP="tape" +BUS=="ide", KERNEL=="hd[a-z]|pcd[0-9]*", ACTION=="add", \ + IMPORT{program}="/sbin/cdrom_id --export $tempnode" +ENV{ID_CDROM}=="?*", GROUP="cdrom" +BUS=="ide", KERNEL=="ht[0-9]*", GROUP="tape" +BUS=="ide", KERNEL=="nht[0-9]*", GROUP="tape" # SCSI devices BUS=="scsi", SYSFS{type}=="1", GROUP="tape" @@ -52,6 +54,7 @@ KERNEL=="sonypi", MODE="0666" KERNEL=="agpgart", GROUP="video" KERNEL=="nvram", GROUP="nvram" KERNEL=="rtc", MODE="0660", GROUP="audio" +KERNEL=="tpm*", MODE="0600", OWNER="tss", GROUP="tss" KERNEL=="cdemu[0-9]*", GROUP="cdrom" KERNEL=="pktcdvd[0-9]*", GROUP="cdrom" diff --git a/etc/udev/debian/persistent.rules b/etc/udev/debian/persistent.rules index b444a27bf6..a6467fa319 100644 --- a/etc/udev/debian/persistent.rules +++ b/etc/udev/debian/persistent.rules @@ -1,49 +1,58 @@ # This file contains the rules needed to create persistent device names. # we are only interested in add actions for block devices -ACTION!="add", GOTO="no_volume_id" -SUBSYSTEM!="block", GOTO="no_volume_id" +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*|sr*", GOTO="no_volume_id" +KERNEL=="ram*|loop*|fd*|nbd*", GOTO="no_volume_id" + +# skip removable ide devices, because open(2) on them causes an events loop +BUS=="ide", SYSFS{removable}=="1", GOTO="no_volume_id" +BUS=="ide", SYSFS{../removable}=="1", GOTO="no_volume_id" # disk id -KERNEL=="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" -KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", \ - SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" +KERNEL=="hd*[!0-9]", \ + IMPORT{program}="/sbin/ata_id --export $tempnode" -KERNEL=="hd*[0-9]", IMPORT{parent}="ID_*" -KERNEL=="hd*[0-9]", ENV{ID_SERIAL}=="?*", \ - SYMLINK+="$env{ID_TYPE}/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}-part%n" +KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="*", \ + IMPORT{program}="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", \ + IMPORT{program}="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", \ + IMPORT{program}="/sbin/scsi_id -g -x -s %p -d %N" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", \ + IMPORT{program}="/sbin/scsi_id -g -x -a -s %p -d %N" -KERNEL=="sd*[!0-9]", SYSFS{ieee1394_id}=="*", \ - IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394\nID_TYPE=disk'" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", \ - IMPORT="/sbin/scsi_id -g -x -a -s %p" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", \ - SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="dasd*[!0-9]", \ + IMPORT{program}="/sbin/dasd_id --export $tempnode" -KERNEL=="sd*[0-9]", IMPORT{parent}="ID_*" -KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", \ - SYMLINK+="$env{ID_TYPE}/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" +KERNEL=="hd*[0-9]|sd*[0-9]|dasd*[0-9]", IMPORT{parent}="ID_*" +KERNEL=="hd*[!0-9]", ENV{ID_SERIAL}=="?*", \ + SYMLINK+="disk/by-id/ata-$env{ID_MODEL}_$env{ID_SERIAL}" +KERNEL=="sd*[!0-9]|sr*|dasd[!0-9]*", ENV{ID_SERIAL}=="?*", \ + SYMLINK+="disk/by-id/$env{ID_BUS}-$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]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", \ + SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" # path -KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", \ - SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}" +KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", \ + IMPORT{program}="/sbin/path_id %p", -KERNEL=="*[0-9]", IMPORT{parent}="ID_*" -KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", \ - SYMLINK+="$env{ID_TYPE}/by-path/$env{ID_PATH}-part%n" +KERNEL=="*[0-9]", IMPORT{parent}="ID_*" +KERNEL=="*[!0-9]|sr*", ENV{ID_PATH}=="?*", \ + SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", \ + SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" -# volume label and uuid -KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" -KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" -KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", \ - SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" -KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", \ - SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" +# UUID and volume label +KERNEL=="*[!0-9]|sr*", SYSFS{removable}=="1", GOTO="no_volume_id" +IMPORT{program}="/sbin/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}" # end of processing -SUBSYSTEM=="block", LABEL="no_volume_id" +LABEL="no_volume_id" diff --git a/etc/udev/debian/simple-cd-aliases.rules b/etc/udev/debian/simple-cd-aliases.rules deleted file mode 100644 index 45ffeeac6b..0000000000 --- a/etc/udev/debian/simple-cd-aliases.rules +++ /dev/null @@ -1,7 +0,0 @@ -# grouping of optical drives from multiple kernel subsystems -BUS=="scsi", KERNEL=="sr[0-9]*", SYMLINK+="cdrom%e" -BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ - PROGRAM="/bin/cat /proc/ide/%k/media", RESULT=="cdrom", \ - SYMLINK+="cdrom%e" -BUS=="ide", KERNEL=="pcd[0-9]*", SYSFS{removable}=="1", SYMLINK+="cdrom%e" - diff --git a/etc/udev/debian/udev.rules b/etc/udev/debian/udev.rules index 07087a3a36..27eb43e54c 100644 --- a/etc/udev/debian/udev.rules +++ b/etc/udev/debian/udev.rules @@ -15,28 +15,32 @@ # workaround for devices which do not report media changes BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ - PROGRAM="/etc/udev/scripts/ide-model.sh %k", RESULT=="IOMEGA ZIP *", \ + PROGRAM="/sbin/ata_id --export $tempnode", ENV{ID_MODEL}=="IOMEGA_ZIP*", \ NAME="%k", OPTIONS+="all_partitions" # SCSI devices BUS=="scsi", KERNEL=="sr[0-9]*", NAME="scd%n", SYMLINK+="sr%n" # USB devices -BUS=="usb", KERNEL=="hiddev*", NAME="usb/%k" BUS=="usb", KERNEL=="auer[0-9]*", NAME="usb/%k" -BUS=="usb", KERNEL=="legousbtower*", NAME="usb/%k" -BUS=="usb", KERNEL=="dabusb*", NAME="usb/%k" BUS=="usb", KERNEL=="cpad[0-9]*", NAME="usb/%k" +BUS=="usb", KERNEL=="dabusb*", NAME="usb/%k" +BUS=="usb", KERNEL=="hiddev*", NAME="usb/%k" +BUS=="usb", KERNEL=="legousbtower*", NAME="usb/%k" BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" BUS=="usb", KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", \ - SYMLINK+=="pilot" + SYMLINK+="pilot" + +# usbfs-like devices +SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k K=$${K#usbdev} B=$${K%%%%.*} D=$${K#*.}; echo bus/usb/$$B/$$D'", \ + SYMLINK+="%c" # serial devices KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" KERNEL=="capi[0-9]*", NAME="capi/%n" # video devices -KERNEL=="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", \ +KERNEL=="dvb*", PROGRAM="/bin/sh -c 'K=%k K=$${K#dvb} A=$${K%%%%.*} D=$${K#*.}; echo dvb/adapter$$A/$$D'", \ NAME="%c" KERNEL=="card[0-9]*", NAME="dri/%k" @@ -54,6 +58,8 @@ 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" From 5bd4c5d72aa69c8d0b722630fd88e29c4a42662a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 18 Sep 2005 05:37:33 +0200 Subject: [PATCH 1536/4284] update Fedora rules Signed-off-by: Kay Sievers --- etc/udev/redhat/udev.rules | 81 +++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 0f6e6ffb73..115abc3ae4 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -3,34 +3,37 @@ # # 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", MODE="0666" -KERNEL=="tty[0-9]", GROUP="tty", MODE="0660" -KERNEL=="tty[0-9][0-9]*", GROUP="tty", MODE="0660" -KERNEL=="vc/[0-9]*", GROUP="tty", MODE="0660" +KERNEL=="tty", MODE="0666", OPTIONS="last_rule" +KERNEL=="tty[0-9]", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="tty[0-9][0-9]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="vc/[0-9]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" # pty devices # Set this to 0660 if you only want users belonging to tty group # to be able to allocate PTYs -KERNEL=="ptmx", GROUP="tty", MODE="0666" -KERNEL=="pty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660" -KERNEL=="tty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660" -KERNEL=="pty/m*", GROUP="tty", MODE="0660" -KERNEL=="vc/s*", GROUP="tty", MODE="0660" +KERNEL=="ptmx", GROUP="tty", MODE="0666", OPTIONS="last_rule" +KERNEL=="pty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="tty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="pty/m*", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="vc/s*", GROUP="tty", MODE="0660", OPTIONS="last_rule" # serial+dialup devices -KERNEL=="ttyS*", GROUP="uucp", MODE="0660" +KERNEL=="ttyS*", GROUP="uucp", MODE="0660", OPTIONS="last_rule" +KERNEL=="ttyACM*", GROUP="uucp", MODE="0660", OPTIONS="last_rule" +KERNEL=="ttyUSB*", GROUP="uucp", MODE="0660", OPTIONS="last_rule" KERNEL=="ippp*", MODE="0660" KERNEL=="isdn*", MODE="0660" KERNEL=="isdnctrl*", MODE="0660" KERNEL=="capi*", MODE="0660" KERNEL=="dcbri*", MODE="0660" KERNEL=="ircomm*", GROUP="uucp", MODE="0660" -KERNEL=="ttyUSB*", GROUP="uucp", MODE="0660" KERNEL=="tts/[0-9]*", GROUP="uucp", MODE="0660" KERNEL=="tts/USB[0-9]*", GROUP="uucp", MODE="0660" @@ -170,9 +173,8 @@ KERNEL=="lp[0-9]*", SYMLINK+="par%n" BUS=="usb", KERNEL=="lp[0-9]*", NAME="usb/%k" KERNEL=="microcode", NAME="cpu/%k" -# provide symlinks for backwards compatibility -KERNEL="msr[0-9]*", NAME="cpu/%n/msr", SYMLINK+="cpu/%k" -KERNEL="cpu[0-9]*", NAME="cpu/%n/cpu", SYMLINK+="cpu/%k", SYMLINK+="%k" +KERNEL="msr[0-9]*", NAME="cpu/%n/msr" +KERNEL="cpu[0-9]*", NAME="cpu/%n/cpu" KERNEL=="ram1", SYMLINK+="ram" KERNEL=="video0", SYMLINK+="video" @@ -235,6 +237,55 @@ KERNEL=="hd[a-z]*", BUS=="ide", SYSFS{removable}=="1", NAME{ignore_remove}="%k" KERNEL=="dvb*", PROGRAM=="/etc/udev/scripts/dvb.sh %k", NAME="%c" +####################################### +# Persistant block device stuff - begin +####################################### + +# Skip all of this if we are not adding a block device +ACTION!="add", GOTO="persistent_end" +SUBSYSTEM!="block", GOTO="persistent_end" + +# skip accessing removable ide devices, cause the ide drivers are horrible broken +BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" +BUS=="ide", SYSFS{../removable}="1", GOTO="no_volume_id" + +# persistent disk device links /dev/disk/ +KERNEL=="hd*[!0-9]", IMPORT="/sbin/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]", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" +KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" +KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}-part%n" + +# Skip id for ram / loop / fd +KERNEL=="ram*", GOTO="no_volume_id" +KERNEL=="loop*", GOTO="no_volume_id" +KERNEL=="fd*", GOTO="no_volume_id" + +KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="*[0-9]", IMPORT{parent}=="ID_*" +KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" + +# volume-label/uuid +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" +KERNEL=="sr*", GOTO="no_volume_id" +KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" +KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" +KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" +LABEL="no_volume_id" + +LABEL="persistent_end" + +##################################### +# Persistant block device stuff - end +##################################### + + # Perhaps this should just be for all subsystems? @@ -265,5 +316,5 @@ ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}!="Onstream", \ ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[23689]", \ RUN+="/sbin/modprobe sg" -ACTION=="add", SUBSYSTEM=="firmware", ENV{FIRMWARE}="*", \ +ACTION=="add", SUBSYSTEM=="firmware", ENV{FIRMWARE}=="*", \ RUN+="/sbin/firmware_helper" From 6e01a73fc31c220bfed43540ecd15a4daa8cc428 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 23 Sep 2005 09:51:49 +0200 Subject: [PATCH 1537/4284] update Debian rules --- etc/udev/debian/compat-full.rules | 37 ------------------------- etc/udev/debian/hotplug.rules | 46 +++++++++++++++++++++++++++++++ etc/udev/debian/hotplugd.rules | 6 ---- etc/udev/debian/persistent.rules | 8 +++--- etc/udev/debian/run.rules | 6 ++++ 5 files changed, 56 insertions(+), 47 deletions(-) delete mode 100644 etc/udev/debian/compat-full.rules create mode 100644 etc/udev/debian/hotplug.rules diff --git a/etc/udev/debian/compat-full.rules b/etc/udev/debian/compat-full.rules deleted file mode 100644 index 50e24bc64a..0000000000 --- a/etc/udev/debian/compat-full.rules +++ /dev/null @@ -1,37 +0,0 @@ -# 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/etc/udev/debian/hotplug.rules b/etc/udev/debian/hotplug.rules new file mode 100644 index 0000000000..84f8c32156 --- /dev/null +++ b/etc/udev/debian/hotplug.rules @@ -0,0 +1,46 @@ +ACTION!="add", GOTO="hotplug_not_add_event" + +# check if the device has already been claimed by a driver +PROGRAM="/bin/sh -c 'test -e /sys$devpath/driver'", \ + GOTO="hotplug_driver_loaded" + +# workarounds for kernels which lack $MODALIAS support +SUBSYSTEM=="input", BUS=="serio", ENV{MODALIAS}!="?*", \ + IMPORT{program}="/lib/hotplug/modalias_serio" +SUBSYSTEM=="ieee1394", ENV{MODALIAS}!="?*", \ + IMPORT{program}="/lib/hotplug/modalias_ieee1394" + +# load the drivers +ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $modalias" +SUBSYSTEM=="pnp", ENV{MODALIAS}!="?*", RUN+="/bin/sh -c 'while read id; do /sbin/modprobe pnp:d$$id; done < /sys$devpath/id'" + +SUBSYSTEM=="scsi_device", SYSFS{type}=="0|7|14", RUN+="/sbin/modprobe sd_mod" +SUBSYSTEM=="scsi_device", SYSFS{type}=="1", RUN+="/sbin/modprobe osst", \ + SYSFS{vendor}=="Onstream", SYSFS{model}!="ADR*" +SUBSYSTEM=="scsi_device", SYSFS{type}=="1", RUN+="/sbin/modprobe st", \ + SYSFS{vendor}=="Onstream", SYSFS{model}=="ADR*" +SUBSYSTEM=="scsi_device", SYSFS{type}=="1", RUN+="/sbin/modprobe st", \ + SYSFS{vendor}!="Onstream" +SUBSYSTEM=="scsi_device", SYSFS{type}=="[345]", RUN+="/sbin/modprobe sr_mod" +SUBSYSTEM=="scsi_device", SYSFS{type}=="[235689]", RUN+="/sbin/modprobe sg" + +SUBSYSTEM=="input_device", ENV{ABS}=="?*", RUN+="/sbin/modprobe joydev" + +SUBSYSTEM=="ide", RUN+="/lib/hotplug/ide.agent" + +# 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", SYSFS{idVendor}=="...", \ +# RUN+="/lib/hotplug/scsi-re-add" + +SUBSYSTEM=="firmware", RUN+="/lib/hotplug/firmware.agent" + +LABEL="hotplug_not_add_event" + +SUBSYSTEM=="net", RUN+="/lib/hotplug/net.agent" + +# for debugging +#RUN+="/lib/hotplug/logger.agent" + diff --git a/etc/udev/debian/hotplugd.rules b/etc/udev/debian/hotplugd.rules index e311d22678..7b85e179e8 100644 --- a/etc/udev/debian/hotplugd.rules +++ b/etc/udev/debian/hotplugd.rules @@ -7,9 +7,3 @@ SUBSYSTEM=="module", OPTIONS="last_rule" ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" RUN+="/sbin/udev_run_devd" -# run a command on remove events -ACTION=="remove", ENV{REMOVE_CMD}!="", RUN+="$env{REMOVE_CMD}" - -# debugging monitor -RUN+="socket:/org/kernel/udev/monitor" - diff --git a/etc/udev/debian/persistent.rules b/etc/udev/debian/persistent.rules index a6467fa319..7bd44da36c 100644 --- a/etc/udev/debian/persistent.rules +++ b/etc/udev/debian/persistent.rules @@ -8,14 +8,14 @@ ACTION!="add", GOTO="no_volume_id" KERNEL=="ram*|loop*|fd*|nbd*", GOTO="no_volume_id" # skip removable ide devices, because open(2) on them causes an events loop -BUS=="ide", SYSFS{removable}=="1", GOTO="no_volume_id" -BUS=="ide", SYSFS{../removable}=="1", GOTO="no_volume_id" +BUS=="ide", SYSFS{removable}=="1", DRIVER!="ide-cdrom", GOTO="no_volume_id" +BUS=="ide", SYSFS{../removable}=="1", GOTO="no_volume_id" # disk id KERNEL=="hd*[!0-9]", \ IMPORT{program}="/sbin/ata_id --export $tempnode" -KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="*", \ +KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="?*", \ IMPORT{program}="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", \ IMPORT{program}="/sbin/usb_id -x" @@ -39,7 +39,7 @@ KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", \ # path KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", \ - IMPORT{program}="/sbin/path_id %p", + IMPORT{program}="/sbin/path_id %p" KERNEL=="*[0-9]", IMPORT{parent}="ID_*" KERNEL=="*[!0-9]|sr*", ENV{ID_PATH}=="?*", \ diff --git a/etc/udev/debian/run.rules b/etc/udev/debian/run.rules index 23fa43c051..75d71375bb 100644 --- a/etc/udev/debian/run.rules +++ b/etc/udev/debian/run.rules @@ -1,3 +1,9 @@ +# 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" From 2d8af104e0262554be2bf2cbbaa752bee6f1a65a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 27 Sep 2005 15:05:34 +0200 Subject: [PATCH 1538/4284] remove no longer needed includes Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/mac.c | 1 - extras/volume_id/volume_id/ocfs2.c | 1 - extras/volume_id/volume_id/reiserfs.c | 1 - extras/volume_id/volume_id/sysv.c | 1 - extras/volume_id/volume_id/volume_id.h | 2 +- 5 files changed, 1 insertion(+), 5 deletions(-) diff --git a/extras/volume_id/volume_id/mac.c b/extras/volume_id/volume_id/mac.c index 7ebd749e4f..f394ca45f8 100644 --- a/extras/volume_id/volume_id/mac.c +++ b/extras/volume_id/volume_id/mac.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c index 08138472ce..7ccdd066a7 100644 --- a/extras/volume_id/volume_id/ocfs2.c +++ b/extras/volume_id/volume_id/ocfs2.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index 6cffdce8d8..e6677015de 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -33,7 +33,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" diff --git a/extras/volume_id/volume_id/sysv.c b/extras/volume_id/volume_id/sysv.c index 9645ef8004..a72d5025a9 100644 --- a/extras/volume_id/volume_id/sysv.c +++ b/extras/volume_id/volume_id/sysv.c @@ -32,7 +32,6 @@ #include #include #include -#include #include "volume_id.h" #include "logging.h" diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 0f5716b893..6537f7c67e 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -23,7 +23,7 @@ #include -#define VOLUME_ID_VERSION 49 +#define VOLUME_ID_VERSION 50 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 2321ba6fd89635f321ec08fa3803aa7e20aa76bf Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 27 Sep 2005 16:27:35 +0200 Subject: [PATCH 1539/4284] switch tools and volume_id from LGPL to GPLv2 After beeing hit by proprietary applications which statically link the LGPL'd libusb, which needs a patch to reflect the recent kernel changes, I decided not to provide LGPL code anymore. Signed-off-by: Kay Sievers --- extras/ata_id/ata_id.c | 16 +++------------- extras/cdrom_id/cdrom_id.c | 3 --- extras/dasd_id/dasd_id.c | 10 ---------- extras/edd_id/edd_id.c | 1 - extras/firmware/firmware_helper.c | 10 +++------- extras/floppy/create_floppy_devices.c | 20 +++++--------------- extras/path_id | 16 ++++++++++------ extras/usb_id/usb_id.c | 18 ++++-------------- extras/volume_id/volume_id/cramfs.c | 16 +++------------- extras/volume_id/volume_id/cramfs.h | 16 +++------------- extras/volume_id/volume_id/ext.c | 16 +++------------- extras/volume_id/volume_id/ext.h | 16 +++------------- extras/volume_id/volume_id/fat.c | 16 +++------------- extras/volume_id/volume_id/fat.h | 16 +++------------- extras/volume_id/volume_id/hfs.c | 16 +++------------- extras/volume_id/volume_id/hfs.h | 16 +++------------- extras/volume_id/volume_id/highpoint.c | 16 +++------------- extras/volume_id/volume_id/highpoint.h | 16 +++------------- extras/volume_id/volume_id/hpfs.c | 16 +++------------- extras/volume_id/volume_id/hpfs.h | 16 +++------------- extras/volume_id/volume_id/iso9660.c | 16 +++------------- extras/volume_id/volume_id/iso9660.h | 16 +++------------- extras/volume_id/volume_id/isw_raid.c | 16 +++------------- extras/volume_id/volume_id/isw_raid.h | 16 +++------------- extras/volume_id/volume_id/jfs.c | 16 +++------------- extras/volume_id/volume_id/jfs.h | 16 +++------------- extras/volume_id/volume_id/linux_raid.c | 16 +++------------- extras/volume_id/volume_id/linux_raid.h | 16 +++------------- extras/volume_id/volume_id/linux_swap.c | 16 +++------------- extras/volume_id/volume_id/linux_swap.h | 16 +++------------- extras/volume_id/volume_id/logging.h | 3 +++ extras/volume_id/volume_id/lsi_raid.c | 16 +++------------- extras/volume_id/volume_id/lsi_raid.h | 16 +++------------- extras/volume_id/volume_id/luks.c | 16 +++------------- extras/volume_id/volume_id/luks.h | 16 +++------------- extras/volume_id/volume_id/lvm.c | 16 +++------------- extras/volume_id/volume_id/lvm.h | 16 +++------------- extras/volume_id/volume_id/mac.c | 16 +++------------- extras/volume_id/volume_id/mac.h | 16 +++------------- extras/volume_id/volume_id/minix.c | 16 +++------------- extras/volume_id/volume_id/minix.h | 16 +++------------- extras/volume_id/volume_id/msdos.c | 16 +++------------- extras/volume_id/volume_id/msdos.h | 16 +++------------- extras/volume_id/volume_id/ntfs.c | 16 +++------------- extras/volume_id/volume_id/ntfs.h | 16 +++------------- extras/volume_id/volume_id/nvidia_raid.c | 16 +++------------- extras/volume_id/volume_id/nvidia_raid.h | 16 +++------------- extras/volume_id/volume_id/ocfs2.c | 16 +++------------- extras/volume_id/volume_id/ocfs2.h | 16 +++------------- extras/volume_id/volume_id/promise_raid.c | 16 +++------------- extras/volume_id/volume_id/promise_raid.h | 16 +++------------- extras/volume_id/volume_id/reiserfs.c | 16 +++------------- extras/volume_id/volume_id/reiserfs.h | 16 +++------------- extras/volume_id/volume_id/romfs.c | 16 +++------------- extras/volume_id/volume_id/romfs.h | 16 +++------------- extras/volume_id/volume_id/silicon_raid.c | 16 +++------------- extras/volume_id/volume_id/silicon_raid.h | 16 +++------------- extras/volume_id/volume_id/sysv.c | 16 +++------------- extras/volume_id/volume_id/sysv.h | 16 +++------------- extras/volume_id/volume_id/udf.c | 16 +++------------- extras/volume_id/volume_id/udf.h | 16 +++------------- extras/volume_id/volume_id/ufs.c | 16 +++------------- extras/volume_id/volume_id/ufs.h | 16 +++------------- extras/volume_id/volume_id/util.c | 16 +++------------- extras/volume_id/volume_id/util.h | 16 +++------------- extras/volume_id/volume_id/via_raid.c | 16 +++------------- extras/volume_id/volume_id/via_raid.h | 16 +++------------- extras/volume_id/volume_id/volume_id.c | 16 +++------------- extras/volume_id/volume_id/volume_id.h | 16 +++------------- extras/volume_id/volume_id/xfs.c | 16 +++------------- extras/volume_id/volume_id/xfs.h | 16 +++------------- 71 files changed, 214 insertions(+), 875 deletions(-) diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index ba40555a0b..a97cc284cc 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index 091bf91559..ff6f89e163 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -7,9 +7,6 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation version 2 of the License. * - * Framework based on ata_id which is: - * Copyright (C) 2005 Kay Sievers - * */ #ifndef _GNU_SOURCE diff --git a/extras/dasd_id/dasd_id.c b/extras/dasd_id/dasd_id.c index a6f2de0db7..ca2582cde6 100644 --- a/extras/dasd_id/dasd_id.c +++ b/extras/dasd_id/dasd_id.c @@ -6,16 +6,6 @@ * 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 diff --git a/extras/edd_id/edd_id.c b/extras/edd_id/edd_id.c index 8ac50e9812..f21362b902 100644 --- a/extras/edd_id/edd_id.c +++ b/extras/edd_id/edd_id.c @@ -7,7 +7,6 @@ * 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 diff --git a/extras/firmware/firmware_helper.c b/extras/firmware/firmware_helper.c index 45815137ac..2bc6b50f06 100644 --- a/extras/firmware/firmware_helper.c +++ b/extras/firmware/firmware_helper.c @@ -3,13 +3,9 @@ * * Copyright 2005 Red Hat, Inc. * - * This software may be freely redistributed under the terms of the GNU - * public license. - * - * 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. - * + * 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 diff --git a/extras/floppy/create_floppy_devices.c b/extras/floppy/create_floppy_devices.c index f4003c2ce2..b2906106d4 100644 --- a/extras/floppy/create_floppy_devices.c +++ b/extras/floppy/create_floppy_devices.c @@ -6,22 +6,12 @@ * * Copyright(C) 2005, SUSE Linux Products GmbH * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Author: Hannes Reinecke + * 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 diff --git a/extras/path_id b/extras/path_id index c7f50687fe..4ac718717a 100755 --- a/extras/path_id +++ b/extras/path_id @@ -4,15 +4,19 @@ # for the udev persistent disk device naming scheme # # Copyright (C) 2005 SUSE Linux Products GmbH -# Licensed under the GPL v2. +# 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. # # to be called from a udev rule to return the name for a symlink -# DEVPATH=/block/sda/sda3 $0 (or similar) -# $0 /block/sda -# $0 /sys/block/sda +# DEVPATH=/block/sda/sda3 path_id +# path_id -# example for all: -# for i in `find /sys/block -name dev` ;do DEVPATH="`echo $i | sed -e 's@^/sys\|/dev@@g'`" $0 ; done +# example for all block devices on a system: +# for i in `find /sys/block -name dev` ;do DEVPATH="`echo $i | sed -e 's@^/sys\|/dev@@g'`" path_id ; done # examples: # SCSI cdrom diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index c4ce0c6103..b7d67958c9 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -4,23 +4,13 @@ * Identify an USB (block) device * * Copyright (c) 2005 SUSE Linux Products GmbH, Germany + * * Author: * Hannes Reinecke * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * 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 diff --git a/extras/volume_id/volume_id/cramfs.c b/extras/volume_id/volume_id/cramfs.c index 9a71b0265c..85a1bc8c55 100644 --- a/extras/volume_id/volume_id/cramfs.c +++ b/extras/volume_id/volume_id/cramfs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/cramfs.h b/extras/volume_id/volume_id/cramfs.h index a40cec199d..0ff19c342e 100644 --- a/extras/volume_id/volume_id/cramfs.h +++ b/extras/volume_id/volume_id/cramfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_CRAMFS_ diff --git a/extras/volume_id/volume_id/ext.c b/extras/volume_id/volume_id/ext.c index 64e5ff7cbf..df2ebb696b 100644 --- a/extras/volume_id/volume_id/ext.c +++ b/extras/volume_id/volume_id/ext.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/ext.h b/extras/volume_id/volume_id/ext.h index aa931a02a8..dfda2074b8 100644 --- a/extras/volume_id/volume_id/ext.h +++ b/extras/volume_id/volume_id/ext.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_EXT_ diff --git a/extras/volume_id/volume_id/fat.c b/extras/volume_id/volume_id/fat.c index 9fa0387afe..d5f84ece4c 100644 --- a/extras/volume_id/volume_id/fat.c +++ b/extras/volume_id/volume_id/fat.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/fat.h b/extras/volume_id/volume_id/fat.h index 0043210d5a..92fa953b11 100644 --- a/extras/volume_id/volume_id/fat.h +++ b/extras/volume_id/volume_id/fat.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_FAT_ diff --git a/extras/volume_id/volume_id/hfs.c b/extras/volume_id/volume_id/hfs.c index ab1bc2ec39..8de8b9aaac 100644 --- a/extras/volume_id/volume_id/hfs.c +++ b/extras/volume_id/volume_id/hfs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/hfs.h b/extras/volume_id/volume_id/hfs.h index 42dc449e29..4f732b6726 100644 --- a/extras/volume_id/volume_id/hfs.h +++ b/extras/volume_id/volume_id/hfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_HFS_ diff --git a/extras/volume_id/volume_id/highpoint.c b/extras/volume_id/volume_id/highpoint.c index baa278ba80..33c4a8c9c0 100644 --- a/extras/volume_id/volume_id/highpoint.c +++ b/extras/volume_id/volume_id/highpoint.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/highpoint.h b/extras/volume_id/volume_id/highpoint.h index b0462f0525..f04d5f1685 100644 --- a/extras/volume_id/volume_id/highpoint.h +++ b/extras/volume_id/volume_id/highpoint.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_HIGHPOINT_ diff --git a/extras/volume_id/volume_id/hpfs.c b/extras/volume_id/volume_id/hpfs.c index 8cd65cd6e9..3b97d9339d 100644 --- a/extras/volume_id/volume_id/hpfs.c +++ b/extras/volume_id/volume_id/hpfs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/hpfs.h b/extras/volume_id/volume_id/hpfs.h index d496829033..d33e43a114 100644 --- a/extras/volume_id/volume_id/hpfs.h +++ b/extras/volume_id/volume_id/hpfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_HPFS_ diff --git a/extras/volume_id/volume_id/iso9660.c b/extras/volume_id/volume_id/iso9660.c index 8811ffbc03..3999a1e7bf 100644 --- a/extras/volume_id/volume_id/iso9660.c +++ b/extras/volume_id/volume_id/iso9660.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/iso9660.h b/extras/volume_id/volume_id/iso9660.h index 0119acac6c..c407d416a2 100644 --- a/extras/volume_id/volume_id/iso9660.h +++ b/extras/volume_id/volume_id/iso9660.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_ISO9660_ diff --git a/extras/volume_id/volume_id/isw_raid.c b/extras/volume_id/volume_id/isw_raid.c index 9c3082dbbf..745b42f2d1 100644 --- a/extras/volume_id/volume_id/isw_raid.c +++ b/extras/volume_id/volume_id/isw_raid.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/isw_raid.h b/extras/volume_id/volume_id/isw_raid.h index 7f48b0196f..55d8c49268 100644 --- a/extras/volume_id/volume_id/isw_raid.h +++ b/extras/volume_id/volume_id/isw_raid.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_ISW_RAID_ diff --git a/extras/volume_id/volume_id/jfs.c b/extras/volume_id/volume_id/jfs.c index 6899e939ac..1b2bfdf0e9 100644 --- a/extras/volume_id/volume_id/jfs.c +++ b/extras/volume_id/volume_id/jfs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/jfs.h b/extras/volume_id/volume_id/jfs.h index e979eb740c..4ef0d8763c 100644 --- a/extras/volume_id/volume_id/jfs.h +++ b/extras/volume_id/volume_id/jfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_JFS_ diff --git a/extras/volume_id/volume_id/linux_raid.c b/extras/volume_id/volume_id/linux_raid.c index ece3e46f6d..eb37dba367 100644 --- a/extras/volume_id/volume_id/linux_raid.c +++ b/extras/volume_id/volume_id/linux_raid.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/linux_raid.h b/extras/volume_id/volume_id/linux_raid.h index adf6ebaacd..8fdeebf5cd 100644 --- a/extras/volume_id/volume_id/linux_raid.h +++ b/extras/volume_id/volume_id/linux_raid.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_LINUX_RAID_ diff --git a/extras/volume_id/volume_id/linux_swap.c b/extras/volume_id/volume_id/linux_swap.c index 1ffc2a8cb5..b3e22f6db2 100644 --- a/extras/volume_id/volume_id/linux_swap.c +++ b/extras/volume_id/volume_id/linux_swap.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/linux_swap.h b/extras/volume_id/volume_id/linux_swap.h index c8fa90d5c5..e31ee6eb90 100644 --- a/extras/volume_id/volume_id/linux_swap.h +++ b/extras/volume_id/volume_id/linux_swap.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_LINUX_SWAP_ diff --git a/extras/volume_id/volume_id/logging.h b/extras/volume_id/volume_id/logging.h index ac30264158..4a8aa50d4c 100644 --- a/extras/volume_id/volume_id/logging.h +++ b/extras/volume_id/volume_id/logging.h @@ -2,6 +2,9 @@ * volume_id_logging - this file is used to map the dbg() function * to the user's logging facility * + * 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_LOGGING_H_ diff --git a/extras/volume_id/volume_id/lsi_raid.c b/extras/volume_id/volume_id/lsi_raid.c index bb2ac7f9c5..e5da281203 100644 --- a/extras/volume_id/volume_id/lsi_raid.c +++ b/extras/volume_id/volume_id/lsi_raid.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/lsi_raid.h b/extras/volume_id/volume_id/lsi_raid.h index 2c2758bdb4..51a0bfbcc6 100644 --- a/extras/volume_id/volume_id/lsi_raid.h +++ b/extras/volume_id/volume_id/lsi_raid.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_LSI_RAID_ diff --git a/extras/volume_id/volume_id/luks.c b/extras/volume_id/volume_id/luks.c index 22d2a94ac7..ff90f5d3d1 100644 --- a/extras/volume_id/volume_id/luks.c +++ b/extras/volume_id/volume_id/luks.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 W. Michael Petullo * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/luks.h b/extras/volume_id/volume_id/luks.h index f53a1558ec..fbf3fcd846 100644 --- a/extras/volume_id/volume_id/luks.h +++ b/extras/volume_id/volume_id/luks.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 W. Michael Petullo * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_LUKS_ diff --git a/extras/volume_id/volume_id/lvm.c b/extras/volume_id/volume_id/lvm.c index b2e2e421d0..a188402da8 100644 --- a/extras/volume_id/volume_id/lvm.c +++ b/extras/volume_id/volume_id/lvm.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/lvm.h b/extras/volume_id/volume_id/lvm.h index 555f18d904..d07cb53af6 100644 --- a/extras/volume_id/volume_id/lvm.h +++ b/extras/volume_id/volume_id/lvm.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_LVM_ diff --git a/extras/volume_id/volume_id/mac.c b/extras/volume_id/volume_id/mac.c index f394ca45f8..1587f48823 100644 --- a/extras/volume_id/volume_id/mac.c +++ b/extras/volume_id/volume_id/mac.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/mac.h b/extras/volume_id/volume_id/mac.h index 0ab0d4489d..77b8ccda6f 100644 --- a/extras/volume_id/volume_id/mac.h +++ b/extras/volume_id/volume_id/mac.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_MAC_ diff --git a/extras/volume_id/volume_id/minix.c b/extras/volume_id/volume_id/minix.c index 97aa83a3dc..b081afab49 100644 --- a/extras/volume_id/volume_id/minix.c +++ b/extras/volume_id/volume_id/minix.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/minix.h b/extras/volume_id/volume_id/minix.h index 2a3fd7292b..3020cc0464 100644 --- a/extras/volume_id/volume_id/minix.h +++ b/extras/volume_id/volume_id/minix.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_MINIX_ diff --git a/extras/volume_id/volume_id/msdos.c b/extras/volume_id/volume_id/msdos.c index 0b8dbbeaec..ab18fc3585 100644 --- a/extras/volume_id/volume_id/msdos.c +++ b/extras/volume_id/volume_id/msdos.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/msdos.h b/extras/volume_id/volume_id/msdos.h index 29be629845..b319f05d63 100644 --- a/extras/volume_id/volume_id/msdos.h +++ b/extras/volume_id/volume_id/msdos.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_MSDOS_ diff --git a/extras/volume_id/volume_id/ntfs.c b/extras/volume_id/volume_id/ntfs.c index f59da48165..39aa2d73c6 100644 --- a/extras/volume_id/volume_id/ntfs.c +++ b/extras/volume_id/volume_id/ntfs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/ntfs.h b/extras/volume_id/volume_id/ntfs.h index 2a84db3653..8d59159685 100644 --- a/extras/volume_id/volume_id/ntfs.h +++ b/extras/volume_id/volume_id/ntfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_NTFS_ diff --git a/extras/volume_id/volume_id/nvidia_raid.c b/extras/volume_id/volume_id/nvidia_raid.c index d49ffe3010..9198f1e067 100644 --- a/extras/volume_id/volume_id/nvidia_raid.c +++ b/extras/volume_id/volume_id/nvidia_raid.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/nvidia_raid.h b/extras/volume_id/volume_id/nvidia_raid.h index 250c1f8214..80c51692aa 100644 --- a/extras/volume_id/volume_id/nvidia_raid.h +++ b/extras/volume_id/volume_id/nvidia_raid.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_NVIDIA_RAID_ diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c index 7ccdd066a7..3a771123f1 100644 --- a/extras/volume_id/volume_id/ocfs2.c +++ b/extras/volume_id/volume_id/ocfs2.c @@ -3,19 +3,9 @@ * * Copyright (C) Andre Masella * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/ocfs2.h b/extras/volume_id/volume_id/ocfs2.h index b4b7cc4469..24b43b1875 100644 --- a/extras/volume_id/volume_id/ocfs2.h +++ b/extras/volume_id/volume_id/ocfs2.h @@ -3,19 +3,9 @@ * * Copyright (C) Andre Masella * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_OCFS2_ diff --git a/extras/volume_id/volume_id/promise_raid.c b/extras/volume_id/volume_id/promise_raid.c index ed72809acb..54832a888a 100644 --- a/extras/volume_id/volume_id/promise_raid.c +++ b/extras/volume_id/volume_id/promise_raid.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/promise_raid.h b/extras/volume_id/volume_id/promise_raid.h index f1a9925d72..a46b062015 100644 --- a/extras/volume_id/volume_id/promise_raid.h +++ b/extras/volume_id/volume_id/promise_raid.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_PROMISE_RAID_ diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/volume_id/reiserfs.c index e6677015de..e64b08acdd 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/volume_id/reiserfs.c @@ -4,19 +4,9 @@ * Copyright (C) 2004 Kay Sievers * Copyright (C) 2005 Tobias Klauser * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/reiserfs.h b/extras/volume_id/volume_id/reiserfs.h index 2ef1d255b7..57ee05ea2e 100644 --- a/extras/volume_id/volume_id/reiserfs.h +++ b/extras/volume_id/volume_id/reiserfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_REISERFS_ diff --git a/extras/volume_id/volume_id/romfs.c b/extras/volume_id/volume_id/romfs.c index 3d7df2443f..3373f36497 100644 --- a/extras/volume_id/volume_id/romfs.c +++ b/extras/volume_id/volume_id/romfs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/romfs.h b/extras/volume_id/volume_id/romfs.h index 5a8e900b08..5fe56dcdfe 100644 --- a/extras/volume_id/volume_id/romfs.h +++ b/extras/volume_id/volume_id/romfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_ROMFS_ diff --git a/extras/volume_id/volume_id/silicon_raid.c b/extras/volume_id/volume_id/silicon_raid.c index 0d5ce043da..5f68127c4f 100644 --- a/extras/volume_id/volume_id/silicon_raid.c +++ b/extras/volume_id/volume_id/silicon_raid.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/silicon_raid.h b/extras/volume_id/volume_id/silicon_raid.h index 0816125d7f..f80c1a4a3f 100644 --- a/extras/volume_id/volume_id/silicon_raid.h +++ b/extras/volume_id/volume_id/silicon_raid.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_SILICON_RAID_ diff --git a/extras/volume_id/volume_id/sysv.c b/extras/volume_id/volume_id/sysv.c index a72d5025a9..610edb8876 100644 --- a/extras/volume_id/volume_id/sysv.c +++ b/extras/volume_id/volume_id/sysv.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/sysv.h b/extras/volume_id/volume_id/sysv.h index 1cb2bf9f43..b8c369ec08 100644 --- a/extras/volume_id/volume_id/sysv.h +++ b/extras/volume_id/volume_id/sysv.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_SYSV_ diff --git a/extras/volume_id/volume_id/udf.c b/extras/volume_id/volume_id/udf.c index ecb6b9743d..f54ca87c8f 100644 --- a/extras/volume_id/volume_id/udf.c +++ b/extras/volume_id/volume_id/udf.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/udf.h b/extras/volume_id/volume_id/udf.h index 5a784ad068..ff95cc1058 100644 --- a/extras/volume_id/volume_id/udf.h +++ b/extras/volume_id/volume_id/udf.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_UDF_ diff --git a/extras/volume_id/volume_id/ufs.c b/extras/volume_id/volume_id/ufs.c index 763b79cb0b..a7bd091c5e 100644 --- a/extras/volume_id/volume_id/ufs.c +++ b/extras/volume_id/volume_id/ufs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/ufs.h b/extras/volume_id/volume_id/ufs.h index 8f0af18897..ae46a924b4 100644 --- a/extras/volume_id/volume_id/ufs.h +++ b/extras/volume_id/volume_id/ufs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_UFS_ diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/volume_id/util.c index d1271a86be..361d7058d0 100644 --- a/extras/volume_id/volume_id/util.c +++ b/extras/volume_id/volume_id/util.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h index 0c94fea051..afaa0b7d8d 100644 --- a/extras/volume_id/volume_id/util.h +++ b/extras/volume_id/volume_id/util.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_ diff --git a/extras/volume_id/volume_id/via_raid.c b/extras/volume_id/volume_id/via_raid.c index 2f167dcbcc..2b74123016 100644 --- a/extras/volume_id/volume_id/via_raid.c +++ b/extras/volume_id/volume_id/via_raid.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/via_raid.h b/extras/volume_id/volume_id/via_raid.h index 429375dcc9..3eeaa2cee3 100644 --- a/extras/volume_id/volume_id/via_raid.h +++ b/extras/volume_id/volume_id/via_raid.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_VIA_RAID_ diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 32b91e65ca..d1a6a5f0f5 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 6537f7c67e..2ee974ff42 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -3,19 +3,9 @@ * * Copyright (C) 2005 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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_H_ diff --git a/extras/volume_id/volume_id/xfs.c b/extras/volume_id/volume_id/xfs.c index e631e23ead..7fd629099d 100644 --- a/extras/volume_id/volume_id/xfs.c +++ b/extras/volume_id/volume_id/xfs.c @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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 diff --git a/extras/volume_id/volume_id/xfs.h b/extras/volume_id/volume_id/xfs.h index 537617f7e5..f21cc5f929 100644 --- a/extras/volume_id/volume_id/xfs.h +++ b/extras/volume_id/volume_id/xfs.h @@ -3,19 +3,9 @@ * * Copyright (C) 2004 Kay Sievers * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * 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__ From 144d1c9707f80f24014db49eaa6929732727fe87 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 27 Sep 2005 16:38:43 +0200 Subject: [PATCH 1540/4284] add edd-*-part%n to the persistent.rules Thanks to: Marco d'Itri Signed-off-by: Kay Sievers --- etc/udev/persistent.rules | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/etc/udev/persistent.rules b/etc/udev/persistent.rules index 0ca0c56545..0b231aacd5 100644 --- a/etc/udev/persistent.rules +++ b/etc/udev/persistent.rules @@ -8,7 +8,7 @@ SUBSYSTEM!="block", GOTO="persistent_end" KERNEL=="ram*|loop*|fd*|nbd*", GOTO="persistent_end" # never access removable ide devices, the drivers are causing event loops on open() -SUBSYSTEM=="block", BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}="1", GOTO="persistent_end" +BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}="1", GOTO="persistent_end" # by-id (hardware serial number) KERNEL=="hd*[!0-9]", IMPORT{program}="/sbin/ata_id --export $tempnode" @@ -40,7 +40,8 @@ ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" # BIOS Enhanced Disk Device KERNEL=="*[!0-9]", IMPORT{program}="/sbin/edd_id --export $tempnode" -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}" +KERNEL=="*[0-9]", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part%n" LABEL="persistent_end" From af2703d39aaf924cbfdce5a41b498a0a025c34d1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 27 Sep 2005 16:43:27 +0200 Subject: [PATCH 1541/4284] update Debian persistent rules --- etc/udev/debian/persistent.rules | 36 +++++++++++++++++++------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/etc/udev/debian/persistent.rules b/etc/udev/debian/persistent.rules index 7bd44da36c..4b591b02fa 100644 --- a/etc/udev/debian/persistent.rules +++ b/etc/udev/debian/persistent.rules @@ -9,46 +9,54 @@ KERNEL=="ram*|loop*|fd*|nbd*", GOTO="no_volume_id" # skip removable ide devices, because open(2) on them causes an events loop BUS=="ide", SYSFS{removable}=="1", DRIVER!="ide-cdrom", GOTO="no_volume_id" -BUS=="ide", SYSFS{../removable}=="1", GOTO="no_volume_id" -# disk id +# look for different kinds of unique identificators KERNEL=="hd*[!0-9]", \ IMPORT{program}="/sbin/ata_id --export $tempnode" KERNEL=="sd*[!0-9]|sr*", SYSFS{ieee1394_id}=="?*", \ - IMPORT{program}="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" + ENV{ID_BUS}="ieee1394", ENV{ID_SERIAL}="$sysfs{ieee1394_id}" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", \ IMPORT{program}="/sbin/usb_id -x" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", \ - IMPORT{program}="/sbin/scsi_id -g -x -s %p -d %N" + IMPORT{program}="/sbin/scsi_id -g -x -s $devpath -d $tempnode" KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", \ - IMPORT{program}="/sbin/scsi_id -g -x -a -s %p -d %N" + IMPORT{program}="/sbin/scsi_id -g -x -a -s $devpath -d $tempnode" KERNEL=="dasd*[!0-9]", \ IMPORT{program}="/sbin/dasd_id --export $tempnode" -KERNEL=="hd*[0-9]|sd*[0-9]|dasd*[0-9]", IMPORT{parent}="ID_*" +KERNEL=="*[!0-9]", SYSFS{removable}!="1", \ + IMPORT{program}="/sbin/edd_id --export $tempnode" + +# find the physical path of the device +KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", \ + IMPORT{program}="/sbin/path_id $devpath" + +# 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=="sd*[!0-9]|sr*|dasd[!0-9]*", ENV{ID_SERIAL}=="?*", \ - SYMLINK+="disk/by-id/$env{ID_BUS}-$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]|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=="*[!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" -# path -KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", \ - IMPORT{program}="/sbin/path_id %p" - -KERNEL=="*[0-9]", IMPORT{parent}="ID_*" KERNEL=="*[!0-9]|sr*", ENV{ID_PATH}=="?*", \ SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="sr*", 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]|sr*", SYSFS{removable}=="1", GOTO="no_volume_id" +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" IMPORT{program}="/sbin/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}" From 3162a25fd3d6fe95026dc754ef5d5859b62a6b7c Mon Sep 17 00:00:00 2001 From: Date: Tue, 27 Sep 2005 08:11:31 -0700 Subject: [PATCH 1542/4284] Remove the udev.spec file as no one uses it anymore Signed-off-by: Greg Kroah-Hartman --- udev.spec | 179 ------------------------------------------------------ 1 file changed, 179 deletions(-) delete mode 100644 udev.spec diff --git a/udev.spec b/udev.spec deleted file mode 100644 index 2b8eb054c0..0000000000 --- a/udev.spec +++ /dev/null @@ -1,179 +0,0 @@ -# if we want to build against the included version of klibc or not. -# 0 - do not use klibc -# 1 - use klibc -# Watch out for where the linux symlink is in the klibc part of the tarball, -# it probably is not where you want it to be. -%define klibc 1 - -# if we want to have logging support in or not. -# 0 - no logging support -# 1 - logging support -# Note, it is not recommend if you use klibc to enable logging. -%define log 0 - -# if we want to enable debugging support in udev. If it is enabled, lots of -# stuff will get sent to the debug syslog. -# 0 - debugging disabled -# 1 - debugging enabled -%define debug 0 - -# if we want to build the scsi_id "extra" package or not -# 0 - do not build the package -# 1 - build it -%define scsi_id 1 - -# if we want to build the volume_id "extra" package or not -# 0 - do not build the package -# 1 - build it -%define volume_id 1 - -Summary: A userspace device manager providing devfs functionality -Name: udev -Version: 070 -Release: 1 -License: GPL -Group: Utilities/System -Source: ftp://ftp.kernel.org/pub/linux/utils/kernel/hotplug/%{name}-%{version}.tar.gz -ExclusiveOS: Linux -Vendor: Greg Kroah-Hartman -URL : kernel.org/pub/linux/utils/kernel/hotplug/ -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root -Prereq: /bin/sh, fileutils, hotplug - -%description -udev is a userspace device manager, using sysfs and uevents -to provide a devfs-like device directory management and uevent -dispatching. - -%prep -%setup -q - -%build -make CC="gcc $RPM_OPT_FLAGS" \ -%if %{klibc} - USE_KLIBC=true \ -%endif -%if %{log} - USE_LOG=true \ -%else - USE_LOG=false \ -%endif -%if %{debug} - DEBUG=true \ -%else - DEBUG=false \ -%endif - EXTRAS=" \ -%if %{scsi_id} - extras/scsi_id \ -%endif -%if %{volume_id} - extras/volume_id \ -%endif -" - -%install -rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT install \ - EXTRAS=" \ -%if %{scsi_id} - extras/scsi_id \ -%endif -%if %{volume_id} - extras/volume_id \ -%endif -" - -%post -/sbin/chkconfig --add udev - -%postun -if [ $1 = 0 ]; then - /sbin/chkconfig --del udev -fi - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -%defattr(-,root,root) -%doc COPYING README TODO ChangeLog HOWTO* docs/* -%doc etc/udev/udev.rules.{examples,gentoo,redhat} -%attr(755,root,root) /sbin/udev -%attr(755,root,root) /usr/bin/udevinfo -%attr(755,root,root) /sbin/udevsend -%attr(755,root,root) /sbin/udevd -%attr(755,root,root) /usr/bin/udevtest -%attr(755,root,root) /sbin/udevstart -%attr(755,root,root) %dir /udev/ -%attr(755,root,root) %dir /etc/udev/ -%config(noreplace) %attr(0644,root,root) /etc/udev/udev.conf -%attr(755,root,root) %dir /etc/udev/rules.d/ -%config(noreplace) %attr(0644,root,root) /etc/udev/rules.d/50-udev.rules -%attr(-,root,root) /etc/hotplug.d/default/udev.hotplug -%attr(755,root,root) /etc/init.d/udev -%attr(0644,root,root) %{_mandir}/man8/udev*.8* - -%if %{scsi_id} - %attr(755,root,root) /sbin/scsi_id - %config(noreplace) %attr(0644,root,root) /etc/scsi_id.config - %attr(0644,root,root) %{_mandir}/man8/scsi_id*.8* -%endif -%if %{volume_id} - %attr(755,root,root) /sbin/udev_volume_id -%endif - -%changelog -* Fri May 14 2004 Greg Kroah-Hartman -- remove dbus and selinux stuff from here -- added volume_id option - -* Wed Mar 24 2004 Greg Kroah-Hartman -- change the way dbus and selinux support is built (now an extra) - -* Tue Mar 2 2004 Greg Kroah-Hartman -- added udevstart to the list of files installed -- udevinfo is now in /usr/bin not /sbin - -* Fri Feb 27 2004 Greg Kroah-Hartman -- added ability to build with SELinux support - -* Thu Feb 19 2004 Greg Kroah-Hartman -- add some more files to the documentation directory -- add ability to build scsi_id and make it the default - -* Mon Feb 16 2004 Greg Kroah-Hartman -- fix up udevd build, as it's no longer needed to be build seperatly -- add udevtest to list of files -- more Red Hat sync ups. - -* Thu Feb 12 2004 Greg Kroah-Hartman -- add some changes from the latest Fedora udev release. - -* Mon Feb 2 2004 Greg Kroah-Hartman -- add udevsend, and udevd to the files -- add ability to build udevd with glibc after the rest is build with klibc - -* Mon Jan 26 2004 Greg Kroah-Hartman -- added udevinfo to rpm -- added URL to spec file -- added udevinfo's man page - -* Mon Jan 05 2004 Rolf Eike Beer -- add defines to choose the init script (Redhat or LSB) - -* Tue Dec 16 2003 Robert Love -- install the initscript and run chkconfig on it - -* Tue Nov 2 2003 Greg Kroah-Hartman -- changes due to config file name changes - -* Fri Oct 17 2003 Robert Love -- Make work without a build root -- Correctly install the right files -- Pass the RPM_OPT_FLAGS to gcc so we can build per the build policy -- Put some prereqs in -- Install the hotplug symlink to udev - -* Mon Jul 28 2003 Paul Mundt -- Initial spec file for udev-0.2. From c2df8b5f517216ab7763c1b25655c170cfcee097 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 3 Oct 2005 16:28:11 +0200 Subject: [PATCH 1543/4284] clarify README Signed-off-by: Kay Sievers --- README | 150 ++++++++++++++++++++------------------------------ docs/udev.xml | 2 +- udev.8 | 2 +- 3 files changed, 62 insertions(+), 92 deletions(-) diff --git a/README b/README index 9891c696d3..19ed4468ea 100644 --- a/README +++ b/README @@ -1,107 +1,77 @@ +udev - userspace device management -udev - a userspace device manager +For more information see the files in the docs/ directory. -For more information on the design, and structure of this project, 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 reasonable distros use udev these + days, the major ones make it mandatory and the system will not work without it. -To use: + The upstream udev project does not support or recomend to replace a distro's udev + installation with the upstream version. The installation of a unmodified upstream + version may render your system unusable! There is no "default" setup or a set + of "default" rules provided by the upstream udev version. -- You must be running a 2.6 version of the Linux kernel. +udev requires: + - 2.6 version of the Linux kernel -- Your 2.6 kernel must have had CONFIG_HOTPLUG enabled when it was built. + - the kernel must have sysfs, netlink, and hotplug enabled -- Make sure sysfs is mounted at /sys. No other location is supported. - You can mount it by running: - mount -t sysfs none /sys + - proc must be mounted on /proc -- Make sure you integrate udev with your hotplug setup. There is a copy of - the rules files for all major distros in the etc/udev folder. You may look - there how others are doing it. + - sysfs must be mounted at /sys, no other location is supported -- Make sure you integrate with the kernel hotplug events. Later versions of - udev are able to listen directly to a netlink socket, older versions used - udevsend to feed the udev daemon with the kernel event. The most basic - setup to run udev is to let the kernel for the udev binary directly: - echo "/sbin/udev" > /proc/sys/kernel/hotplug + - udev creates and removes device nodes in /dev based on events + the kernel sends out on device discovery or removal - While this may work in some setups, it is not recommended to do. A recent - kernel and udev version is able to operate with the event serializing daemon - udevd, that makes sure, that no "remove" event will beat a "add" event for - the same device. + - during bootup /dev usually gets a tmpfs mounted which is populated scratch + by udev (created nodes don't survive a reboot, it always starts from scratch) -- Build the project: - make + - udev replaces the hotplug event management invoked from /sbin/hotplug + by the udevd daemon, which receives the kernel events over netlink - Note: - There are a number of different flags that you can use when building - udev. They are as follows: - prefix - set this to the default root that you want udev to be - installed into. This works just like the 'configure --prefix' - script does. Default value is ''. Only override this if you - really know what you are doing. - USE_KLIBC - if set to 'true', udev is built and linked against the - included version of klibc. Default value is 'false'. - USE_LOG - if set to 'true', udev will emit messages to the syslog when - it creates or removes device nodes. This is helpful to see - what udev is doing. This is enabled by default. Note, if you - are building udev against klibc it is recommended that you - disable this option (due to klibc's syslog implementation.) - USE_SELINUX - if set to 'true', udev will be built with SELinux support - enabled. This is disabled by default. - DEBUG - if set to 'true', debugging messages will be sent to the syslog - as udev is run. Default value is 'false'. - KERNEL_DIR - If this is not set it will default to /lib/modules/`uname -r`/build - This is used if USE_KLIBC=true to find the kernel include - directory that klibc needs to build against. This must be set - if you are not building udev while running a 2.6 kernel. - EXTRAS - if set, will build the "extra" helper programs as specified - as listed (see below for an example.) + - all kernel events are matched against a set of specified rules which + make it posible to hook into the event processing - So, if you want to build udev using klibc with debugging messages, you - would do: - make USE_KLIBC=true DEBUG=true + - there is a copy of the rules files for all major distros in the etc/udev + directory (you may look there how others distros are doing it) - If you want to build the udev helper program cdrom_id and scsi_id you - would do: - make EXTRAS="extras/cdrom_id extras/scsi_id" +Setting which are used for building udev: + prefix + set this to the default root that you want to use + Only override this if you really know what you are doing + DESTDIR + prefix for install target for package building + USE_LOG + if set to 'true', udev will emit messages to the syslog when + it creates or removes device nodes. This is helpful to see + what udev is doing. This is enabled by default. Note, if you + are building udev against klibc it is recommended that you + disable this option (due to klibc's syslog implementation.) + DEBUG + if set to 'true', verbose debugging messages will be compiled into + the udev binaries. Default value is 'false'. + USE_SELINUX + if set to 'true', udev will be built with SELinux support + enabled. This is disabled by default. + USE_KLIBC + if set to 'true', udev is built and linked against the + included version of klibc. Default value is 'false'. + KERNEL_DIR + If this is not set it will default to /lib/modules/`uname -r`/build + This is used if USE_KLIBC=true to find the kernel include + directory that klibc needs to build against. This must be set + if you are not building udev while running a 2.6 kernel. + EXTRAS + if set, will build the "extra" helper programs as specified + as listed (see below for an example.) - udev will follow the setting of the debug level in udev.conf. Adapt this - value to see the debug in syslog. +if you want to build udev using klibc with debugging messages: + make USE_KLIBC=true DEBUG=true -- Install the project: - make install +if you want to build the udev helper program cdrom_id and scsi_id: + make EXTRAS="extras/cdrom_id extras/scsi_id" - This will put the udev binaries in /sbin, create the and /etc/udev - directories, and place the udev configuration files in /etc/udev/. You - will probably want to edit the *.rules files to create custom naming - rules. More info on how the config files are set up are contained in - comments in the files, and is located in the documentation. - -- Add and remove devices from the system and marvel as nodes are created - and removed in /dev based on the device types. - -- If you later get sick of it, uninstall it: - make uninstall - -If nothing seems to happen, make sure your build worked properly by -running the udev-test.pl script as root in the test/ subdirectory of the -udev source tree. Running udevstart should populate an empty /dev -directory. You may test, if a node is recreated after running udevstart. - -Development and documentation help is very much appreciated, see the TODO -file for a list of things left to be done. - -Any comment/questions/concerns please let me and the other udev developers -know by sending a message to the linux-hotplug-devel mailing list at: - linux-hotplug-devel@lists.sourceforge.net - -greg k-h -greg@kroah.com +Please direct any comment/question/concern to the linux-hotplug-devel mailing list at: + linux-hotplug-devel@lists.sourceforge.net diff --git a/docs/udev.xml b/docs/udev.xml index 02dcd2586a..c98054f8ce 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -440,7 +440,7 @@ devices of the same type originating from different kernel subsystems. Note: The use of the enumeration facility is unreliable for events that request a number at the same time. The use of enumerations in todays setups - where devices can come and go at any time is not recomended. + where devices can come and go at any time is not recommended. diff --git a/udev.8 b/udev.8 index 9b74ae23bf..a591a1398e 100644 --- a/udev.8 +++ b/udev.8 @@ -203,7 +203,7 @@ The string returned by the external program requested with PROGRAM. A single par \fB%e\fR, \fB$enum\fR If a device node already exists with the name, the smallest next free number is used. This can be used to create compatibility symlinks and enumerate devices of the same type originating from different kernel subsystems. -Note: The use of the enumeration facility is unreliable for events that request a number at the same time. The use of enumerations in todays setups where devices can come and go at any time is not recomended. +Note: The use of the enumeration facility is unreliable for events that request a number at the same time. The use of enumerations in todays setups where devices can come and go at any time is not recommended. .TP \fB%P\fR, \fB$parent\fR The node name of the parent device. From 133326dc74d9f02686d480b2f4c8a1d9732ba1d6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 3 Oct 2005 16:36:52 +0200 Subject: [PATCH 1544/4284] udevd: fix initial timeout handling UDEVD_EVENT_TIMEOUT=0 didn't work directly after udevd startup. The whole event timeout handling is not needed since we use netlink. Signed-off-by: Kay Sievers --- udevd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/udevd.c b/udevd.c index e227a64d71..5974d14e8e 100644 --- a/udevd.c +++ b/udevd.c @@ -410,8 +410,9 @@ recheck: /* limit timeout during initialization phase */ if (init_phase) { - timeout = UDEVD_INIT_EVENT_TIMEOUT; - dbg("initialization phase, limit timeout to %i seconds", UDEVD_INIT_EVENT_TIMEOUT); + if (timeout > UDEVD_INIT_EVENT_TIMEOUT) + timeout = UDEVD_INIT_EVENT_TIMEOUT; + dbg("initialization phase, timeout %i seconds", timeout); } /* move event with expired timeout to the exec list */ From a5c606f6c3c736bdd3a38b03aa8e1aa144bb3c98 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 11 Oct 2005 21:06:50 +0200 Subject: [PATCH 1545/4284] force event socket buffer size to 16MB Netlink events get lost when the kernel creates thousends of events faster than udevd reads it. The default is 128 KB, which can carry app. 500 events. Set it to 16 MB now. I have 4000 fibrechannel LUNs connected to my system. There are two paths to the devices and two ports on the host connected via a switch. This gives 16000 when probed. I have had problems getting all of the entries in /dev created. -- Mark Haverkamp Signed-off-by: Kay Sievers --- udev_libc_wrapper.h | 4 ++++ udevd.c | 8 ++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 9dd22175cd..6f8c8f24c7 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -53,6 +53,10 @@ #define NETLINK_KOBJECT_UEVENT 15 #endif +#ifndef SO_RCVBUFFORCE +#define SO_RCVBUFFORCE 33 +#endif + #ifdef __KLIBC__ static inline int clearenv(void) { diff --git a/udevd.c b/udevd.c index 5974d14e8e..aaf80a2314 100644 --- a/udevd.c +++ b/udevd.c @@ -686,7 +686,7 @@ static void reap_sigchilds(void) static int init_udevd_socket(void) { struct sockaddr_un saddr; - const int buffersize = 1024 * 1024; + const int buffersize = 16 * 1024 * 1024; socklen_t addrlen; const int feature_on = 1; int retval; @@ -704,7 +704,7 @@ static int init_udevd_socket(void) } /* set receive buffersize */ - setsockopt(udevd_sock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); + setsockopt(udevd_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize)); /* the bind takes care of ensuring only one copy running */ retval = bind(udevd_sock, (struct sockaddr *) &saddr, addrlen); @@ -723,7 +723,7 @@ static int init_udevd_socket(void) static int init_uevent_netlink_sock(void) { struct sockaddr_nl snl; - const int buffersize = 1024 * 1024; + const int buffersize = 16 * 1024 * 1024; int retval; memset(&snl, 0x00, sizeof(struct sockaddr_nl)); @@ -738,7 +738,7 @@ static int init_uevent_netlink_sock(void) } /* set receive buffersize */ - setsockopt(uevent_netlink_sock, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); + setsockopt(uevent_netlink_sock, SOL_SOCKET, SO_RCVBUFFORCE, &buffersize, sizeof(buffersize)); retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl)); From dfedc446db906952ef32fe95f637cc51f9b2d129 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 12 Oct 2005 11:55:49 +0200 Subject: [PATCH 1546/4284] udevd: move logging from err to info for non-hotplug uevent Signed-off-by: Kay Sievers --- udevd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevd.c b/udevd.c index aaf80a2314..a926715908 100644 --- a/udevd.c +++ b/udevd.c @@ -611,7 +611,7 @@ static struct uevent_msg *get_netlink_msg(void) pos[0] = '\0'; if (msg->action == NULL) { - err("no ACTION in payload found, skip event '%s'", buffer); + info("no ACTION in payload found, skip event '%s'", buffer); free(msg); return NULL; } @@ -865,7 +865,7 @@ int main(int argc, char *argv[], char *envp[]) if (errno == EADDRINUSE) dbg("another udevd running, exit"); else - dbg("error initialising udevd socket: %s", strerror(errno)); + dbg("error initializing udevd socket: %s", strerror(errno)); goto exit; } From 586e1a37eff1ec9b69c0d2953014e7291fb875b5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 16 Oct 2005 14:16:43 +0200 Subject: [PATCH 1547/4284] fix selinux compilation Taken from Red Hat CVS. Signed-off-by: Kay Sievers --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ed5a87c427..16f4c244eb 100644 --- a/Makefile +++ b/Makefile @@ -206,7 +206,7 @@ endif ifeq ($(strip $(USE_SELINUX)),true) UDEV_OBJS += udev_selinux.o - LIB_OBJS += -lselinux + LIB_OBJS += -lselinux -lsepol CFLAGS += -DUSE_SELINUX endif From daff48063eb2cb547d24a547684543ee991f0815 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 19 Oct 2005 23:59:54 +0200 Subject: [PATCH 1548/4284] libsysfs: accept sysmlinks to directories instead of real directories Recent changes to the sysfs layout introduced class-devices pointed to by a symlink, instead of the real object at that location. Signed-off-by: Kay Sievers --- libsysfs/sysfs_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index c5558a43a1..bd7f99ae15 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -233,7 +233,7 @@ int sysfs_path_is_dir(const char *path) errno = EINVAL; return 1; } - if ((lstat(path, &astats)) != 0) { + if ((stat(path, &astats)) != 0) { dprintf("stat() failed\n"); return 1; } From a743be9a785e1223ce628a4225b63546281d9e66 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 20 Oct 2005 00:28:34 +0200 Subject: [PATCH 1549/4284] 071 release --- ChangeLog | 33 +++++++++++++++++++++++++++++++++ Makefile | 2 +- RELEASE-NOTES | 15 +++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8f25c0c5b8..cc20111553 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,36 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 16f4c244eb..0f5ab8fe82 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 070 +VERSION = 071 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 31c97ce1b2..815d4083c5 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,18 @@ +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 From 0ecc6c1b1957e367852bf2dbf3fbc406762d272d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 16:08:56 +0200 Subject: [PATCH 1550/4284] volume_id: add OVFS Version 1 Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/Makefile.inc | 4 +- extras/volume_id/volume_id/ocfs.c | 194 ++++++++++++++++++ .../volume_id/volume_id/{ocfs2.h => ocfs.h} | 8 +- extras/volume_id/volume_id/ocfs2.c | 114 ---------- extras/volume_id/volume_id/volume_id.c | 5 +- 5 files changed, 205 insertions(+), 120 deletions(-) create mode 100644 extras/volume_id/volume_id/ocfs.c rename extras/volume_id/volume_id/{ocfs2.h => ocfs.h} (58%) delete mode 100644 extras/volume_id/volume_id/ocfs2.c diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index 71f4ea2862..80f451d583 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -27,7 +27,7 @@ VOLUME_ID_OBJS= \ $(VOLUME_ID_BASE)/sysv.o \ $(VOLUME_ID_BASE)/minix.o \ $(VOLUME_ID_BASE)/luks.o \ - $(VOLUME_ID_BASE)/ocfs2.o \ + $(VOLUME_ID_BASE)/ocfs.o \ $(VOLUME_ID_BASE)/volume_id.o \ $(VOLUME_ID_BASE)/util.o @@ -59,6 +59,6 @@ VOLUME_ID_HEADERS= \ $(VOLUME_ID_BASE)/sysv.h \ $(VOLUME_ID_BASE)/minix.h \ $(VOLUME_ID_BASE)/luks.h \ - $(VOLUME_ID_BASE)/ocfs2.h \ + $(VOLUME_ID_BASE)/ocfs.h \ $(VOLUME_ID_BASE)/volume_id.h \ $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/ocfs.c b/extras/volume_id/volume_id/ocfs.c new file mode 100644 index 0000000000..81b4e2d048 --- /dev/null +++ b/extras/volume_id/volume_id/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 "volume_id.h" +#include "logging.h" +#include "util.h" +#include "ocfs.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; +} __attribute__((__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; + } disk_lock __attribute__((__packed__)); + 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; +} __attribute__((__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]; +} __attribute__((__packed__)); + +int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off) +{ + const uint8_t *buf; + struct ocfs1_super_block_header *osh; + struct ocfs1_super_block_label *osl; + + 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, 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) +{ + const uint8_t *buf; + struct ocfs2_super_block *os; + size_t blksize; + + dbg("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, 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/extras/volume_id/volume_id/ocfs2.h b/extras/volume_id/volume_id/ocfs.h similarity index 58% rename from extras/volume_id/volume_id/ocfs2.h rename to extras/volume_id/volume_id/ocfs.h index 24b43b1875..9d46b28dcd 100644 --- a/extras/volume_id/volume_id/ocfs2.h +++ b/extras/volume_id/volume_id/ocfs.h @@ -1,16 +1,18 @@ /* * volume_id - reads filesystem label and uuid * - * Copyright (C) Andre Masella + * 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 _VOLUME_ID_OCFS2_ -#define _VOLUME_ID_OCFS2_ +#ifndef _VOLUME_ID_OCFS1_ +#define _VOLUME_ID_OCFS1_ +extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off); extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off); #endif diff --git a/extras/volume_id/volume_id/ocfs2.c b/extras/volume_id/volume_id/ocfs2.c deleted file mode 100644 index 3a771123f1..0000000000 --- a/extras/volume_id/volume_id/ocfs2.c +++ /dev/null @@ -1,114 +0,0 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) Andre Masella - * - * 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 "volume_id.h" -#include "logging.h" -#include "util.h" -#include "ocfs2.h" - - -/* All these values are taken from ocfs2-tools's ocfs2_fs.h */ -#define OCFS2_VOL_UUID_LEN 16 -#define OCFS2_MAX_VOL_LABEL_LEN 64 -#define OCFS2_SUPERBLOCK_OFFSET 0x2000 - - -/* This is the superblock. The OCFS2 header files have structs in structs. -This is one has been simplified since we only care about the superblock. -*/ - -struct ocfs2_super_block { - uint8_t i_signature[8]; /* Signature for validation */ - uint32_t i_generation; /* Generation number */ - int16_t i_suballoc_slot; /* Slot suballocator this inode belongs to */ - uint16_t i_suballoc_bit; /* Bit offset in suballocator block group */ - uint32_t i_reserved0; - uint32_t i_clusters; /* Cluster count */ - uint32_t i_uid; /* Owner UID */ - uint32_t i_gid; /* Owning GID */ - uint64_t i_size; /* Size in bytes */ - uint16_t i_mode; /* File mode */ - uint16_t i_links_count; /* Links count */ - uint32_t i_flags; /* File flags */ - uint64_t i_atime; /* Access time */ - uint64_t i_ctime; /* Creation time */ - uint64_t i_mtime; /* Modification time */ - uint64_t i_dtime; /* Deletion time */ - uint64_t i_blkno; /* Offset on disk, in blocks */ - uint64_t i_last_eb_blk; /* Pointer to last extent block */ - uint32_t i_fs_generation; /* Generation per fs-instance */ - uint32_t i_atime_nsec; - uint32_t i_ctime_nsec; - uint32_t i_mtime_nsec; - uint64_t i_reserved1[9]; - uint64_t i_pad1; /* Generic way to refer to this 64bit union */ - /* Normally there is a union of the different block types, but we only care about the superblock. */ - 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; /* File system state */ - uint16_t s_errors; /* Behaviour when detecting errors */ - uint32_t s_checkinterval; /* Max time between checks */ - uint64_t s_lastcheck; /* Time of last check */ - uint32_t s_creator_os; /* OS */ - uint32_t s_feature_compat; /* Compatible feature set */ - uint32_t s_feature_incompat; /* Incompatible feature set */ - uint32_t s_feature_ro_compat; /* Readonly-compatible feature set */ - uint64_t s_root_blkno; /* Offset, in blocks, of root directory dinode */ - uint64_t s_system_dir_blkno; /* Offset, in blocks, of system directory dinode */ - uint32_t s_blocksize_bits; /* Blocksize for this fs */ - uint32_t s_clustersize_bits; /* Clustersize for this fs */ - uint16_t s_max_slots; /* Max number of simultaneous mounts before tunefs required */ - uint16_t s_reserved1; - uint32_t s_reserved2; - uint64_t s_first_cluster_group; /* Block offset of 1st cluster group header */ - uint8_t s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */ - uint8_t s_uuid[OCFS2_VOL_UUID_LEN]; /* 128-bit uuid */ -} __attribute__((__packed__)); - -int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off) -{ - struct ocfs2_super_block *os; - - dbg("probing at offset 0x%llx", (unsigned long long) off); - - os = (struct ocfs2_super_block *) volume_id_get_buffer(id, off + OCFS2_SUPERBLOCK_OFFSET, 0x200); - if (os == NULL) - return -1; - - if (memcmp(os->i_signature, "OCFSV2", 6) != 0) { - return -1; - } - - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - volume_id_set_label_raw(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ? - OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE); - volume_id_set_label_string(id, os->s_label, OCFS2_MAX_VOL_LABEL_LEN < VOLUME_ID_LABEL_SIZE ? - OCFS2_MAX_VOL_LABEL_LEN : VOLUME_ID_LABEL_SIZE); - volume_id_set_uuid(id, os->s_uuid, UUID_DCE); - id->type = "ocfs2"; - return 0; -} diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index d1a6a5f0f5..25bcd95358 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -58,7 +58,7 @@ #include "minix.h" #include "mac.h" #include "msdos.h" -#include "ocfs2.h" +#include "ocfs.h" int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) { @@ -156,6 +156,9 @@ int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) if (volume_id_probe_minix(id, off) == 0) goto exit; + if (volume_id_probe_ocfs1(id, off) == 0) + goto exit; + if (volume_id_probe_ocfs2(id, off) == 0) goto exit; From 79bd4f222954a331aafcd7d0164742a60b570294 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 16:31:13 +0200 Subject: [PATCH 1551/4284] volume_id: add Veritas fs Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/Makefile.inc | 2 + extras/volume_id/volume_id/volume_id.c | 3 ++ extras/volume_id/volume_id/vxfs.c | 56 +++++++++++++++++++++++++ extras/volume_id/volume_id/vxfs.h | 16 +++++++ 4 files changed, 77 insertions(+) create mode 100644 extras/volume_id/volume_id/vxfs.c create mode 100644 extras/volume_id/volume_id/vxfs.h diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc index 80f451d583..6f8dceea4a 100644 --- a/extras/volume_id/volume_id/Makefile.inc +++ b/extras/volume_id/volume_id/Makefile.inc @@ -28,6 +28,7 @@ VOLUME_ID_OBJS= \ $(VOLUME_ID_BASE)/minix.o \ $(VOLUME_ID_BASE)/luks.o \ $(VOLUME_ID_BASE)/ocfs.o \ + $(VOLUME_ID_BASE)/vxfs.o \ $(VOLUME_ID_BASE)/volume_id.o \ $(VOLUME_ID_BASE)/util.o @@ -60,5 +61,6 @@ VOLUME_ID_HEADERS= \ $(VOLUME_ID_BASE)/minix.h \ $(VOLUME_ID_BASE)/luks.h \ $(VOLUME_ID_BASE)/ocfs.h \ + $(VOLUME_ID_BASE)/vxfs.h \ $(VOLUME_ID_BASE)/volume_id.h \ $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 25bcd95358..06496e7130 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -162,6 +162,9 @@ int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) if (volume_id_probe_ocfs2(id, off) == 0) goto exit; + if (volume_id_probe_vxfs(id, off) == 0) + goto exit; + return -1; exit: diff --git a/extras/volume_id/volume_id/vxfs.c b/extras/volume_id/volume_id/vxfs.c new file mode 100644 index 0000000000..c4a9ace98f --- /dev/null +++ b/extras/volume_id/volume_id/vxfs.c @@ -0,0 +1,56 @@ +/* + * 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 "volume_id.h" +#include "logging.h" +#include "util.h" +#include "vxfs.h" + +#define VXFS_SUPER_MAGIC 0xa501FCF5 + +struct vxfs_super { + uint32_t vs_magic; + int32_t vs_version; +} __attribute__((__packed__)); + +int volume_id_probe_vxfs(struct volume_id *id, uint64_t off) +{ + struct vxfs_super *vxs; + + dbg("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/extras/volume_id/volume_id/vxfs.h b/extras/volume_id/volume_id/vxfs.h new file mode 100644 index 0000000000..8ca45c3fdc --- /dev/null +++ b/extras/volume_id/volume_id/vxfs.h @@ -0,0 +1,16 @@ +/* + * 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 _VOLUME_ID_VXFS_ +#define _VOLUME_ID_VXFS_ + +extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off); + +#endif From c929358e0292e7f0650b543f4085cd10d2624534 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 17:41:55 +0200 Subject: [PATCH 1552/4284] volume_id: check ext fs for valid blocksize, cause magic is only 2 bytes Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/ext.c | 84 ++++++++++++++++++++++--------- extras/volume_id/volume_id/util.h | 2 + 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/extras/volume_id/volume_id/ext.c b/extras/volume_id/volume_id/ext.c index df2ebb696b..7080f1dd35 100644 --- a/extras/volume_id/volume_id/ext.c +++ b/extras/volume_id/volume_id/ext.c @@ -29,31 +29,53 @@ #include "ext.h" struct ext2_super_block { - uint32_t inodes_count; - uint32_t blocks_count; - uint32_t r_blocks_count; - uint32_t free_blocks_count; - uint32_t free_inodes_count; - uint32_t first_data_block; - uint32_t log_block_size; - uint32_t dummy3[7]; - uint8_t magic[2]; - uint16_t state; - uint32_t dummy5[8]; - uint32_t feature_compat; - uint32_t feature_incompat; - uint32_t feature_ro_compat; - uint8_t uuid[16]; - uint8_t volume_name[16]; + 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]; } __attribute__((__packed__)); +#define EXT_SUPER_MAGIC 0xEF53 #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x00000008 #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) { struct ext2_super_block *es; + size_t bsize; dbg("probing at offset 0x%llx", (unsigned long long) off); @@ -61,16 +83,32 @@ int volume_id_probe_ext(struct volume_id *id, uint64_t off) if (es == NULL) return -1; - if (es->magic[0] != 0123 || - es->magic[1] != 0357) + if (es->s_magic != cpu_to_le16(EXT_SUPER_MAGIC)) return -1; - volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); - volume_id_set_label_raw(id, es->volume_name, 16); - volume_id_set_label_string(id, es->volume_name, 16); - volume_id_set_uuid(id, es->uuid, UUID_DCE); + bsize = 0x200 << 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; + } - if ((le32_to_cpu(es->feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) + 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, UUID_DCE); + snprintf(id->type_version, sizeof(id->type_version)-1, + "%u.%u", es->s_rev_level, es->s_minor_rev_level); + + /* check for external journal device */ + if ((le32_to_cpu(es->s_feature_incompat) & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) != 0) { + volume_id_set_usage(id, VOLUME_ID_OTHER); + id->type = "jbd"; + return 0; + } + + /* check for ext2 / ext3 */ + volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); + if ((le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) id->type = "ext3"; else id->type = "ext2"; diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/volume_id/util.h index afaa0b7d8d..6e16491c80 100644 --- a/extras/volume_id/volume_id/util.h +++ b/extras/volume_id/volume_id/util.h @@ -51,6 +51,7 @@ #define le64_to_cpu(x) (x) #define be16_to_cpu(x) bswap16(x) #define be32_to_cpu(x) bswap32(x) +#define cpu_to_le16(x) (x) #define cpu_to_le32(x) (x) #define cpu_to_be32(x) bswap32(x) #elif (__BYTE_ORDER == __BIG_ENDIAN) @@ -59,6 +60,7 @@ #define le64_to_cpu(x) bswap64(x) #define be16_to_cpu(x) (x) #define be32_to_cpu(x) (x) +#define cpu_to_le16(x) bswap16(x) #define cpu_to_le32(x) bswap32(x) #define cpu_to_be32(x) (x) #endif From f3c14c68499d318b2beb56cee7c5f88f2c04dc62 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 18:54:34 +0200 Subject: [PATCH 1553/4284] volume_id: move blocksize validation to fix jbd recognition Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/ext.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/extras/volume_id/volume_id/ext.c b/extras/volume_id/volume_id/ext.c index 7080f1dd35..e80ac90ad6 100644 --- a/extras/volume_id/volume_id/ext.c +++ b/extras/volume_id/volume_id/ext.c @@ -86,13 +86,6 @@ int volume_id_probe_ext(struct volume_id *id, uint64_t off) if (es->s_magic != cpu_to_le16(EXT_SUPER_MAGIC)) return -1; - bsize = 0x200 << 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, UUID_DCE); @@ -106,6 +99,13 @@ int volume_id_probe_ext(struct volume_id *id, uint64_t off) return 0; } + bsize = 0x200 << 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; + } + /* check for ext2 / ext3 */ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); if ((le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) From b5866871385be4e4ad170dca40f5e2b1c6666694 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 18:55:22 +0200 Subject: [PATCH 1554/4284] volume_id: fix typo in ocfs Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/ocfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/volume_id/ocfs.c b/extras/volume_id/volume_id/ocfs.c index 81b4e2d048..88064ed193 100644 --- a/extras/volume_id/volume_id/ocfs.c +++ b/extras/volume_id/volume_id/ocfs.c @@ -172,7 +172,7 @@ int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off) dbg("probing at offset 0x%llx", (unsigned long long) off); - for (blksize = 0x200; blksize <= OCFS2_MAX_BLOCKSIZE; blksize >>= 1) { + 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; From 1305b47167388297b33b073989ae3b70a26ca71a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 18:56:30 +0200 Subject: [PATCH 1555/4284] volume_id: add vxfs include Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/volume_id.c | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/volume_id/volume_id.c index 06496e7130..b92269863f 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/volume_id/volume_id.c @@ -59,6 +59,7 @@ #include "mac.h" #include "msdos.h" #include "ocfs.h" +#include "vxfs.h" int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) { From 04b222b4b0369f3f0861f3911bacc928d18c0b00 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 19:15:07 +0200 Subject: [PATCH 1556/4284] volume_id: make FAT32 recognition more robust FAT32 volumes should never have a cluster count, that fits into a 16 bit value, but mkdosfs can create such volumes. No sane formatter or Windows will ever do this, but the Linux kernel as Windows can read/write it. Thanks to Ted Ts'o for convincing me. Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/fat.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/extras/volume_id/volume_id/fat.c b/extras/volume_id/volume_id/fat.c index d5f84ece4c..74f2bb9194 100644 --- a/extras/volume_id/volume_id/fat.c +++ b/extras/volume_id/volume_id/fat.c @@ -138,7 +138,8 @@ int volume_id_probe_vfat(struct volume_id *id, uint64_t off) uint32_t root_cluster; uint32_t dir_size; uint32_t cluster_count; - uint32_t fat_length; + uint16_t fat_length; + uint32_t fat32_length; uint64_t root_start; uint32_t start_data_sect; uint16_t root_dir_entries; @@ -222,11 +223,18 @@ valid: dbg("sect_count 0x%x", sect_count); fat_length = le16_to_cpu(vs->fat_length); - if (fat_length == 0) - fat_length = le32_to_cpu(vs->type.fat32.fat32_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); - fat_size = fat_length * vs->fats; dir_size = ((dir_entries * sizeof(struct vfat_dir_entry)) + (sector_size-1)) / sector_size; dbg("dir_size 0x%x", dir_size); @@ -235,14 +243,17 @@ valid: cluster_count /= vs->sectors_per_cluster; dbg("cluster_count 0x%x", cluster_count); - if (cluster_count < FAT12_MAX) { + /* 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) { + else if (cluster_count < FAT16_MAX) strcpy(id->type_version, "FAT16"); - } else { - strcpy(id->type_version, "FAT32"); + else goto fat32; - } /* the label may be an attribute in the root directory */ root_start = (reserved + fat_size) * sector_size; @@ -274,6 +285,8 @@ valid: goto found; fat32: + 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); From eba25b20ce19cb273785f72f169c60406edacc3a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 19:16:01 +0200 Subject: [PATCH 1557/4284] volume_id: Version 051 Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/volume_id.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 2ee974ff42..16770dd6ab 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -13,7 +13,7 @@ #include -#define VOLUME_ID_VERSION 50 +#define VOLUME_ID_VERSION 51 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 7f0a5b80957844148d05ba5218c40b70910a6b49 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 21:12:51 +0200 Subject: [PATCH 1558/4284] volume_id: fix typo in ext blocksize check Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/ext.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/extras/volume_id/volume_id/ext.c b/extras/volume_id/volume_id/ext.c index e80ac90ad6..a3e20d3151 100644 --- a/extras/volume_id/volume_id/ext.c +++ b/extras/volume_id/volume_id/ext.c @@ -86,6 +86,13 @@ int volume_id_probe_ext(struct volume_id *id, uint64_t off) 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, UUID_DCE); @@ -99,13 +106,6 @@ int volume_id_probe_ext(struct volume_id *id, uint64_t off) return 0; } - bsize = 0x200 << 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; - } - /* check for ext2 / ext3 */ volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); if ((le32_to_cpu(es->s_feature_compat) & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0) From 81d719a1d48f31f169487d043982aeabd3b2dd51 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 23 Oct 2005 21:13:10 +0200 Subject: [PATCH 1559/4284] volume_id: Version 052 Signed-off-by: Kay Sievers --- extras/volume_id/volume_id/volume_id.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h index 16770dd6ab..9994615c69 100644 --- a/extras/volume_id/volume_id/volume_id.h +++ b/extras/volume_id/volume_id/volume_id.h @@ -13,7 +13,7 @@ #include -#define VOLUME_ID_VERSION 51 +#define VOLUME_ID_VERSION 52 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From e4b1a0f608c2d00e458b5cb47a6fba4da9aafe7e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 13:13:25 +0200 Subject: [PATCH 1560/4284] FAQ: remove confusing statement about module loading Signed-off-by: Kay Sievers --- FAQ | 5 ----- 1 file changed, 5 deletions(-) diff --git a/FAQ b/FAQ index 1b9e56d8c5..abe88638b2 100644 --- a/FAQ +++ b/FAQ @@ -31,11 +31,6 @@ Q: But udev will not automatically load a driver if a /dev node is opened 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: But wait, I really want udev to automatically load drivers when they - are not present but the device node is opened. It's the only reason I - like using devfs. Please make udev do this. -A: No. udev is for managing /dev, not loading kernel drivers. - 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 From 638b983b4d20f3c8f184084b672da8e8e93eb91e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 18:20:58 +0200 Subject: [PATCH 1561/4284] cleanup compiler/linker flags Signed-off-by: Kay Sievers --- Makefile | 39 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 0f5ab8fe82..5fd5f29182 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 071 +VERSION = 071 # set this to make use of syslog USE_LOG = true @@ -42,10 +42,10 @@ USE_STATIC = false # to build any of the extras programs pass: # make EXTRAS="extras/ extras/" -EXTRAS= +EXTRAS = # make the build silent. Set this to something else to make it noisy again. -V=false +V = false PROGRAMS = \ udev \ @@ -136,10 +136,7 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} PWD = $(shell pwd) -# If you are running a cross compiler, you may want to set this -# to something more interesting, like "arm-linux-". If you want -# to compile vs uClibc, that can be done here as well. -CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- +CROSS = CC = $(CROSS)gcc LD = $(CROSS)gcc AR = $(CROSS)ar @@ -147,25 +144,18 @@ STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib HOSTCC = gcc -# code taken from uClibc to determine the current arch -ARCH := ${shell $(CC) -dumpmachine | sed -e s'/-.*//' -e 's/i.86/i386/' -e 's/sparc.*/sparc/' \ - -e 's/arm.*/arm/g' -e 's/m68k.*/m68k/' -e 's/powerpc/ppc/g'} - -# determine the gcc include dir -GCCINCDIR := ${shell LC_ALL=C $(CC) -print-search-dirs | sed -ne "s/install: \(.*\)/\1include/gp"} - -# determine the libgcc.a filename -GCC_LIB := $(shell $(CC) -print-libgcc-file-name ) - # check if compiler option is supported cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi;} -CFLAGS += -Wall -fno-builtin -Wchar-subscripts -Wpointer-arith \ - -Wstrict-prototypes -Wsign-compare +CFLAGS += -g -Wall -pipe -fno-builtin -Wstrict-prototypes -Wsign-compare \ + -Wchar-subscripts -Wmissing-declarations -Wnested-externs \ + -Wpointer-arith -Wcast-align -Wsign-compare -Wmissing-prototypes \ + -Wshadow CFLAGS += $(call cc-supports, -Wdeclaration-after-statement, ) -CFLAGS += -pipe CFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 +LDFLAGS = -Wl,-warn-common + # use '-Os' optimization if available, else use -O2 OPTFLAGS := $(call cc-supports, -Os, -O2) @@ -179,8 +169,7 @@ endif # if DEBUG is enabled, then we do not strip or optimize ifeq ($(strip $(DEBUG)),true) - CFLAGS += -O1 -g -DDEBUG - LDFLAGS += -Wl + CFLAGS += -DDEBUG STRIPCMD = /bin/true -Since_we_are_debugging else CFLAGS += $(OPTFLAGS) -fomit-frame-pointer @@ -190,7 +179,7 @@ endif ifeq ($(strip $(USE_GCOV)),true) CFLAGS += -fprofile-arcs -ftest-coverage - LDFLAGS = -fprofile-arcs + LDFLAGS += -fprofile-arcs endif # if our own version of klibc is used, we need to build it @@ -199,9 +188,6 @@ ifeq ($(strip $(USE_KLIBC)),true) KLCC = $(KLIBC_INSTALL)/bin/$(CROSS)klcc CC = $(KLCC) LD = $(KLCC) -else - CFLAGS += -Wshadow -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations - LDFLAGS += -Wl,-warn-common endif ifeq ($(strip $(USE_SELINUX)),true) @@ -261,7 +247,6 @@ $(KLCC): INSTALLDIR=$(KLIBC_INSTALL) \ bindir=$(KLIBC_INSTALL)/bin \ mandir=$(KLIBC_INSTALL)/man all install - -find $(KLIBC_INSTALL)/include -name SCCS -print| xargs rm -rf .NOTPARALLEL: $(KLCC) $(UDEV_OBJS): $(KLCC) From 49fb51c6159db916f93c9439ef9b37ce6be90d02 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 18:42:52 +0200 Subject: [PATCH 1562/4284] use DESTDIR on uninstall, no need to pass prefix to submake Signed-off-by: Kay Sievers --- Makefile | 61 +++++++++++++++++++------------------- extras/scsi_id/Makefile | 2 +- test/simple-build-check.sh | 15 ++++------ 3 files changed, 36 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index 5fd5f29182..f3698329ef 100644 --- a/Makefile +++ b/Makefile @@ -188,6 +188,7 @@ ifeq ($(strip $(USE_KLIBC)),true) KLCC = $(KLIBC_INSTALL)/bin/$(CROSS)klcc CC = $(KLCC) LD = $(KLCC) + V = true endif ifeq ($(strip $(USE_SELINUX)),true) @@ -212,8 +213,7 @@ endif all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) prefix=$(prefix) \ - CC="$(CC)" \ + $(MAKE) CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LD="$(LD)" \ LDFLAGS="$(LDFLAGS)" \ @@ -296,16 +296,13 @@ clean: $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) prefix=$(prefix) -C $$target $@; \ + $(MAKE) -C $$target $@; \ done; -.PHONY: clean - -spotless: clean $(MAKE) -C klibc SUBDIRS=klibc spotless rm -rf klibc/.install -.PHONY: spotless +.PHONY: clean -release: spotless +release: git-tar-tree HEAD $(RELEASE_NAME) | gzip -9v > $(RELEASE_NAME).tar.gz @echo "$(RELEASE_NAME).tar.gz created" .PHONY: release @@ -323,7 +320,7 @@ install-config: $(GEN_CONFIGS) fi @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) prefix=$(prefix) -C $$target $@; \ + $(MAKE) -C $$target $@; \ done; .PHONY: install-config @@ -338,22 +335,22 @@ install-man: - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8 @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) prefix=$(prefix) -C $$target $@; \ + $(MAKE) -C $$target $@; \ done; .PHONY: install-man uninstall-man: - - rm -f $(mandir)/man8/udev.8 - - rm -f $(mandir)/man8/udevinfo.8 - - rm -f $(mandir)/man8/udevtest.8 - - rm -f $(mandir)/man8/udevstart.8 - - rm -f $(mandir)/man8/udevd.8 - - rm -f $(mandir)/man8/udevmonitor.8 - - rm -f $(mandir)/man8/udevsend.8 - - rm -f $(mandir)/man8/udevcontrol.8 + - rm -f $(DESTDIR)$(mandir)/man8/udev.8 + - rm -f $(DESTDIR)$(mandir)/man8/udevinfo.8 + - rm -f $(DESTDIR)$(mandir)/man8/udevtest.8 + - rm -f $(DESTDIR)$(mandir)/man8/udevstart.8 + - rm -f $(DESTDIR)$(mandir)/man8/udevd.8 + - rm -f $(DESTDIR)$(mandir)/man8/udevmonitor.8 + - rm -f $(DESTDIR)$(mandir)/man8/udevsend.8 + - rm -f $(DESTDIR)$(mandir)/man8/udevcontrol.8 @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) prefix=$(prefix) -C $$target $@; \ + $(MAKE) -C $$target $@; \ done; .PHONY: uninstall-man @@ -369,7 +366,7 @@ install-bin: $(INSTALL_PROGRAM) -D udevstart $(DESTDIR)$(sbindir)/udevstart @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) prefix=$(prefix) -C $$target $@; \ + $(MAKE) -C $$target $@; \ done; ifndef DESTDIR - killall udevd @@ -379,21 +376,23 @@ endif .PHONY: install-bin uninstall-bin: - - rm -f $(sbindir)/udev - - rm -f $(sbindir)/udevd - - rm -f $(sbindir)/udevsend - - rm -f $(sbindir)/udevinitsend - - rm -f $(sbindir)/udeveventrecoreder - - rm -f $(sbindir)/udevcontrol - - rm -f $(sbindir)/udevstart - - rm -f $(usrsbindir)/udevmonitor + - rm -f $(DESTDIR)$(sbindir)/udev + - rm -f $(DESTDIR)$(sbindir)/udevd + - rm -f $(DESTDIR)$(sbindir)/udevsend + - rm -f $(DESTDIR)$(sbindir)/udevinitsend + - rm -f $(DESTDIR)$(sbindir)/udeveventrecoreder + - rm -f $(DESTDIR)$(sbindir)/udevcontrol + - rm -f $(DESTDIR)$(sbindir)/udevstart + - rm -f $(DESTDIR)$(usrsbindir)/udevmonitor - rm -f $(usrbindir)/udevinfo - - rm -f $(usrbindir)/udevtest - - rm -rf $(udevdb) + - rm -f $(DESTDIR)$(DESTDIR)$(usrbindir)/udevtest +ifndef DESTDIR - killall udevd + - rm -rf $(udevdb) +endif @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) prefix=$(prefix) -C $$target $@; \ + $(MAKE) -C $$target $@; \ done; .PHONY: uninstall-bin diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 85f6ff6ca8..8a8c714a87 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -78,7 +78,7 @@ install-man: .PHONY: uninstall-man uninstall-man: - -rm -f $(mandir)/man8/scsi_id.8 + -rm -f $(DESTDIR)$(mandir)/man8/scsi_id.8 .PHONY: uninstall-man install-config: diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index e69c6451ab..6572a39625 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -16,34 +16,29 @@ EXTRAS="\ echo KERNEL_DIR: "$KERNEL_DIR" # with debug -make spotless EXTRAS="$EXTRAS" >/dev/null +make clean EXTRAS="$EXTRAS" >/dev/null make all -j4 $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit echo -e "\n\n" # without any logging -make spotless EXTRAS="$EXTRAS" >/dev/null +make clean EXTRAS="$EXTRAS" >/dev/null make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" # klibc and debug -make spotless EXTRAS="$EXTRAS" >/dev/null +make clean EXTRAS="$EXTRAS" >/dev/null make all -j4 $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit echo -e "\n\n" -# klibc without logging -make spotless EXTRAS="$EXTRAS" >/dev/null -make all $MAKEOPTS USE_KLIBC=true USE_LOG=false EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit -echo -e "\n\n" - # install in temporary dir and show it TEMPDIR="`pwd`/.tmp" rm -rf $TEMPDIR mkdir $TEMPDIR -make spotless EXTRAS="$EXTRAS" >/dev/null +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 spotless EXTRAS="$EXTRAS" >/dev/null +make clean EXTRAS="$EXTRAS" >/dev/null From f032e0ed6b4bd7a9112711687b5012a0285357f7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 19:14:21 +0200 Subject: [PATCH 1563/4284] allow to pass STRIPCMD, to skip stripping of binaries Signed-off-by: Kay Sievers --- Makefile | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index f3698329ef..e10967017c 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,6 @@ USE_LOG = true DEBUG = false # compile with gcc's code coverage option -# (use it with DEBUG, works only with glibc) USE_GCOV = false # include Security-Enhanced Linux support @@ -140,24 +139,26 @@ CROSS = CC = $(CROSS)gcc LD = $(CROSS)gcc AR = $(CROSS)ar -STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib HOSTCC = gcc +STRIP = $(CROSS)strip +STRIPCMD = $(STRIP) -s # check if compiler option is supported cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi;} -CFLAGS += -g -Wall -pipe -fno-builtin -Wstrict-prototypes -Wsign-compare \ - -Wchar-subscripts -Wmissing-declarations -Wnested-externs \ - -Wpointer-arith -Wcast-align -Wsign-compare -Wmissing-prototypes \ - -Wshadow -CFLAGS += $(call cc-supports, -Wdeclaration-after-statement, ) -CFLAGS += -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 +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 +WARNINGS += $(call cc-supports, -Wdeclaration-after-statement, ) +CFLAGS += $(WARNINGS) LDFLAGS = -Wl,-warn-common -# use '-Os' optimization if available, else use -O2 +# use -Os optimization if available, else use -O2 OPTFLAGS := $(call cc-supports, -Os, -O2) +CFLAGS += $(OPTFLAGS) # include our local copy of libsysfs CFLAGS += -I$(PWD)/libsysfs/sysfs \ @@ -167,14 +168,10 @@ ifeq ($(strip $(USE_LOG)),true) CFLAGS += -DUSE_LOG endif -# if DEBUG is enabled, then we do not strip or optimize +# if DEBUG is enabled, then we do not strip ifeq ($(strip $(DEBUG)),true) CFLAGS += -DDEBUG - STRIPCMD = /bin/true -Since_we_are_debugging -else - CFLAGS += $(OPTFLAGS) -fomit-frame-pointer - LDFLAGS += -s -Wl - STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment + STRIPCMD = /bin/true unstripped binary endif ifeq ($(strip $(USE_GCOV)),true) @@ -412,7 +409,7 @@ buildtest: .PHONY: buildtest gcov-all: - $(MAKE) clean all DEBUG=true USE_GCOV=true + $(MAKE) clean all STRIPCMD= USE_GCOV=true @echo @echo "binaries built with gcov support." @echo "run the tests and analyze with 'make udev_gcov.txt'" From cf686d37b42ed49df9209d6630fd3292c54c6bde Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 19:38:36 +0200 Subject: [PATCH 1564/4284] cleanup make release Signed-off-by: Kay Sievers --- Makefile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index e10967017c..f69ac96e9d 100644 --- a/Makefile +++ b/Makefile @@ -125,9 +125,7 @@ udevdir = /dev udevdb = ${udevdir}/.udevdb LOCAL_CFG_DIR = etc/udev KERNEL_DIR = /lib/modules/${shell uname -r}/build -srcdir = . DESTDIR = -RELEASE_NAME = udev-$(VERSION) INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} @@ -290,6 +288,7 @@ clean: - find -name "*.gcov" -print0 | xargs -0rt rm -f - rm -f udev_gcov.txt - rm -f core $(PROGRAMS) $(GEN_HEADERS) $(GEN_CONFIGS) + - rm -f udev-$(VERSION).tar.gz $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ @@ -300,8 +299,8 @@ clean: .PHONY: clean release: - git-tar-tree HEAD $(RELEASE_NAME) | gzip -9v > $(RELEASE_NAME).tar.gz - @echo "$(RELEASE_NAME).tar.gz created" + git-tar-tree HEAD udev-$(VERSION) | gzip -9v > udev-$(VERSION).tar.gz + @echo "udev-$(VERSION).tar.gz created" .PHONY: release install-config: $(GEN_CONFIGS) From 916c5e4725ef4558b752c6464deef6492c8ac31a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 20:32:07 +0200 Subject: [PATCH 1565/4284] fix the new warnings I asked for Signed-off-by: Kay Sievers --- test/simple-build-check.sh | 4 ++-- udev_rules_parse.c | 4 ++-- udevcontrol.c | 6 +++--- udevd.c | 10 +++++----- udeveventrecorder.c | 6 +++--- udevinitsend.c | 6 +++--- udevmonitor.c | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index 6572a39625..daf0b75269 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -17,12 +17,12 @@ echo KERNEL_DIR: "$KERNEL_DIR" # with debug make clean EXTRAS="$EXTRAS" >/dev/null -make all -j4 $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit +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 +make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" # klibc and debug diff --git a/udev_rules_parse.c b/udev_rules_parse.c index c14164f1cc..7d1853acbe 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -437,7 +437,7 @@ static int add_to_rules(struct udev_rules *rules, char *line) char owner[32]; uid_t uid = lookup_user(value); dbg("replacing username='%s' by id=%i", value, uid); - sprintf(owner, "%li", uid); + sprintf(owner, "%u", (unsigned int) uid); add_rule_key(rule, &rule->owner, operation, owner); continue; } @@ -456,7 +456,7 @@ static int add_to_rules(struct udev_rules *rules, char *line) char group[32]; gid_t gid = lookup_group(value); dbg("replacing groupname='%s' by id=%i", value, gid); - sprintf(group, "%li", gid); + sprintf(group, "%u", (unsigned int) gid); add_rule_key(rule, &rule->group, operation, group); continue; } diff --git a/udevcontrol.c b/udevcontrol.c index f16f6a125a..6651e9761e 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -39,14 +39,14 @@ /* global variables */ static int sock = -1; -static int log = 0; +static int udev_log = 0; #ifdef USE_LOG void log_message (int priority, const char *format, ...) { va_list args; - if (priority > log) + if (priority > udev_log) return; va_start(args, format); @@ -69,7 +69,7 @@ int main(int argc, char *argv[], char *envp[]) env = getenv("UDEV_LOG"); if (env) - log = log_priority(env); + udev_log = log_priority(env); logging_init("udevcontrol"); dbg("version %s", UDEV_VERSION); diff --git a/udevd.c b/udevd.c index a926715908..bd1324e4a3 100644 --- a/udevd.c +++ b/udevd.c @@ -67,7 +67,7 @@ static int event_timeout; static int max_childs; static int max_childs_running; static unsigned long long expected_seqnum; -static char log[32]; +static char udev_log[32]; static LIST_HEAD(msg_list); static LIST_HEAD(exec_list); @@ -559,8 +559,8 @@ static struct uevent_msg *get_udevd_msg(void) intval = (int *) usend_msg.envbuf; info("udevd message (SET_LOG_PRIORITY) received, udev_log_priority=%i", *intval); udev_log_priority = *intval; - sprintf(log, "UDEV_LOG=%i", udev_log_priority); - putenv(log); + sprintf(udev_log, "UDEV_LOG=%i", udev_log_priority); + putenv(udev_log); break; case UDEVD_SET_MAX_CHILDS: intval = (int *) usend_msg.envbuf; @@ -912,8 +912,8 @@ int main(int argc, char *argv[], char *envp[]) info("initialize max_childs_running to %u", max_childs_running); /* export log_priority , as called programs may want to follow that setting */ - sprintf(log, "UDEV_LOG=%i", udev_log_priority); - putenv(log); + sprintf(udev_log, "UDEV_LOG=%i", udev_log_priority); + putenv(udev_log); while (!udev_exit) { struct uevent_msg *msg; diff --git a/udeveventrecorder.c b/udeveventrecorder.c index 9a3c3e197c..8ac344a47e 100644 --- a/udeveventrecorder.c +++ b/udeveventrecorder.c @@ -37,14 +37,14 @@ #define BUFSIZE 12345 #define FNSIZE 123 -static int log = 0; +static int udev_log = 0; #ifdef USE_LOG void log_message (int priority, const char *format, ...) { va_list args; - if (priority > log) + if (priority > udev_log) return; va_start(args, format); @@ -67,7 +67,7 @@ int main(int argc, char **argv, char **envp) env = getenv("UDEV_LOG"); if (env) - log = log_priority(env); + udev_log = log_priority(env); logging_init("udeveventrecorder"); dbg("version %s", UDEV_VERSION); diff --git a/udevinitsend.c b/udevinitsend.c index ea05734a00..4f50da8f68 100644 --- a/udevinitsend.c +++ b/udevinitsend.c @@ -42,14 +42,14 @@ #include "udev_utils.h" #include "logging.h" -static int log = 0; +static int udev_log = 0; #ifdef USE_LOG void log_message (int priority, const char *format, ...) { va_list args; - if (priority > log) + if (priority > udev_log) return; va_start(args, format); @@ -174,7 +174,7 @@ int main(int argc, char *argv[], char *envp[]) env = getenv("UDEV_LOG"); if (env) - log = log_priority(env); + udev_log = log_priority(env); logging_init("udevinitsend"); dbg("version %s", UDEV_VERSION); diff --git a/udevmonitor.c b/udevmonitor.c index 33dff2a13c..382cbb1905 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -181,7 +181,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "error receiving uevent message\n"); continue; } - printf("UEVENT[%i] %s\n", time(NULL), buf); + printf("UEVENT[%llu] %s\n", (unsigned long long) time(NULL), buf); } if ((udev_monitor_sock > 0) && FD_ISSET(udev_monitor_sock, &readfds)) { @@ -190,7 +190,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "error receiving udev message\n"); continue; } - printf("UDEV [%i] %s\n", time(NULL), buf); + printf("UDEV [%llu] %s\n", (unsigned long long) time(NULL), buf); } if (buflen == 0) From c895fd002763d6ae808e820020dc54e74c347fc2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 21:04:38 +0200 Subject: [PATCH 1566/4284] move rules parsing into daemon The rules files are parsed only once at daemon startup. Every udev event process will be fork()'d from udevd without exec()'ing the udev binary. The in-memory rules will be inherited from the daemon itself. If inotify is available, udevd will reload all rules if any change in /etc/udev/rules.d/ happens. Otherwise -HUP or "udevcontrol reload_rules" can be used. Signed-off-by: Kay Sievers --- etc/udev/udev.conf.in | 4 +- udev_libc_wrapper.h | 69 +++++++++++++++++++- udevcontrol.c | 3 + udevd.c | 142 +++++++++++++++++++++++++++++++++++------- udevd.h | 1 + 5 files changed, 192 insertions(+), 27 deletions(-) diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index efdb1d1808..c44ed3092c 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -9,6 +9,8 @@ udev_db="@udevdir@/.udevdb" # The name and location of the udev rules file(s). udev_rules="@configdir@/rules.d" -# The syslog(3) priority: "err", "info", or the numerical value. +# The initial syslog(3) priority: "err", "info", "debug" or its +# numerical equivalent. For runtime debugging, change the daemons +# internal state with: "udevcontrol log_priority=". udev_log="err" diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 6f8c8f24c7..9a8b26a2b3 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -24,7 +24,72 @@ #include #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 316 +# define __NR_inotify_add_watch 317 +# define __NR_inotify_rm_watch 318 +#elif defined (__sh__) +# define __NR_inotify_init 290 +# define __NR_inotify_add_watch 291 +# define __NR_inotify_rm_watch 292 +#else +# error "Unsupported architecture!" +#endif +#endif /* __NR_inotify_init */ + +/* needed until /usr/include/sys/inotify.h is working */ +#ifdef __KLIBC__ +#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); +} +#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 /* __KLIBC__ */ /* needed for our signal handlers to work */ #undef asmlinkage @@ -32,7 +97,7 @@ #define asmlinkage __attribute__((regparm(0))) #else #define asmlinkage -#endif +#endif /* __i386__ */ /* headers are broken on some lazy platforms */ #ifndef __FD_SET diff --git a/udevcontrol.c b/udevcontrol.c index 6651e9761e..00b435edc4 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -89,6 +89,8 @@ int main(int argc, char *argv[], char *envp[]) usend_msg.type = UDEVD_STOP_EXEC_QUEUE; else if (!strcmp(arg, "start_exec_queue")) usend_msg.type = UDEVD_START_EXEC_QUEUE; + else if (!strcmp(arg, "reload_rules")) + usend_msg.type = UDEVD_RELOAD_RULES; else if (!strncmp(arg, "log_priority=", strlen("log_priority="))) { intval = (int *) usend_msg.envbuf; val = &arg[strlen("log_priority=")]; @@ -106,6 +108,7 @@ int main(int argc, char *argv[], char *envp[]) " 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" " max_childs= maximum number of childs running at the same time\n" " --help print this help text\n\n"); exit(0); diff --git a/udevd.c b/udevd.c index bd1324e4a3..1f769fbce0 100644 --- a/udevd.c +++ b/udevd.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -46,23 +47,26 @@ #include "udev_libc_wrapper.h" #include "udev.h" #include "udev_version.h" +#include "udev_rules.h" #include "udev_utils.h" #include "udevd.h" #include "logging.h" /* global variables*/ +struct udev_rules rules; static int udevd_sock; static int uevent_netlink_sock; +static int inotify_fd; static pid_t sid; static int signal_pipe[2] = {-1, -1}; static volatile int sigchilds_waiting; static volatile int run_msg_q; static volatile int udev_exit; +static volatile int reload_config; static int init_phase = 1; static int run_exec_q; static int stop_exec_q; -static char *udev_bin; static int event_timeout; static int max_childs; static int max_childs_running; @@ -75,7 +79,7 @@ static LIST_HEAD(running_list); #ifdef USE_LOG -void log_message (int priority, const char *format, ...) +void log_message(int priority, const char *format, ...) { va_list args; @@ -151,10 +155,55 @@ static void msg_queue_insert(struct uevent_msg *msg) return; } -/* forks event and removes event from run queue when finished */ +static void asmlinkage udev_event_sig_handler(int signum) +{ + if (signum == SIGALRM) + exit(1); +} + +static int udev_event_process(struct uevent_msg *msg) +{ + struct sigaction act; + struct udevice udev; + struct name_entry *name_loop; + 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); + + /* trigger timeout to prevent hanging processes */ + alarm(UDEV_ALARM_TIMEOUT); + + /* reconstruct env from message */ + for (i = 0; msg->envp[i]; i++) + putenv(msg->envp[i]); + + udev_init_device(&udev, msg->devpath, msg->subsystem, msg->action); + retval = udev_process_event(&rules, &udev); + + /* run programs collected by RUN-key*/ + if (!retval) { + 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:")], msg->devpath, msg->action); + else + run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + } + } + + udev_cleanup_device(&udev); + + return 0; +} + +/* runs event and removes event from run queue when finished */ static void udev_event_run(struct uevent_msg *msg) { - char *const argv[] = { "udev", msg->subsystem, NULL }; pid_t pid; struct sysinfo info; @@ -162,14 +211,22 @@ static void udev_event_run(struct uevent_msg *msg) switch (pid) { case 0: /* child */ - if (uevent_netlink_sock != -1) + if (uevent_netlink_sock > 0) close(uevent_netlink_sock); + if (inotify_fd > 0) + close(inotify_fd); close(udevd_sock); + close(signal_pipe[READ_END]); + close(signal_pipe[WRITE_END]); logging_close(); + + logging_init("udevd-event"); setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); - execve(udev_bin, argv, msg->envp); - err("exec of child failed"); - _exit(1); + udev_event_process(msg); + info("seq %llu finished", msg->seqnum); + + logging_close(); + exit(0); case -1: err("fork of child failed"); msg_queue_delete(msg); @@ -421,9 +478,8 @@ recheck: if (msg_age >= timeout) { msg_move_exec(loop_msg); goto recheck; - } else { + } else break; - } } msg_dump_queue(); @@ -567,6 +623,10 @@ static struct uevent_msg *get_udevd_msg(void) info("udevd message (UDEVD_SET_MAX_CHILDS) received, max_childs=%i", *intval); max_childs = *intval; break; + case UDEVD_RELOAD_RULES: + info("udevd message (RELOAD_RULES) received"); + reload_config = 1; + break; default: dbg("unknown message type"); } @@ -640,6 +700,9 @@ static void asmlinkage sig_handler(int signum) /* 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 */ @@ -838,17 +901,11 @@ int main(int argc, char *argv[], char *envp[]) err("error fcntl on read pipe: %s", strerror(errno)); goto exit; } - retval = fcntl(signal_pipe[READ_END], F_SETFD, FD_CLOEXEC); - if (retval < 0) - err("error fcntl on read pipe: %s", strerror(errno)); retval = fcntl(signal_pipe[WRITE_END], F_SETFL, O_NONBLOCK); if (retval < 0) { err("error fcntl on write pipe: %s", strerror(errno)); goto exit; } - retval = fcntl(signal_pipe[WRITE_END], F_SETFD, FD_CLOEXEC); - if (retval < 0) - err("error fcntl on write pipe: %s", strerror(errno)); /* set signal handlers */ memset(&act, 0x00, sizeof(struct sigaction)); @@ -861,6 +918,9 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGCHLD, &act, NULL); sigaction(SIGHUP, &act, NULL); + /* parse the rules and keep it in memory */ + udev_rules_init(&rules, 0, 1); + if (init_udevd_socket() < 0) { if (errno == EADDRINUSE) dbg("another udevd running, exit"); @@ -871,14 +931,12 @@ int main(int argc, char *argv[], char *envp[]) } if (init_uevent_netlink_sock() < 0) - info("uevent socket not available"); + err("uevent socket not available"); - /* override of forked udev binary, used for testing */ - udev_bin = getenv("UDEV_BIN"); - if (udev_bin != NULL) - info("udev binary is set to '%s'", udev_bin); - else - udev_bin = UDEV_BIN; + /* watch rules directory */ + inotify_fd = inotify_init(); + if (inotify_fd > 0) + inotify_add_watch(inotify_fd, udev_rules_filename, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); /* init of expected_seqnum value */ value = getenv("UDEVD_EXPECTED_SEQNUM"); @@ -911,6 +969,9 @@ int main(int argc, char *argv[], char *envp[]) 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); @@ -924,8 +985,10 @@ int main(int argc, char *argv[], char *envp[]) FD_SET(udevd_sock, &readfds); if (uevent_netlink_sock > 0) FD_SET(uevent_netlink_sock, &readfds); + if (inotify_fd > 0) + FD_SET(inotify_fd, &readfds); - fdcount = select(UDEV_MAX(udevd_sock, uevent_netlink_sock)+1, &readfds, NULL, NULL, NULL); + fdcount = select(UDEV_MAX(uevent_netlink_sock, inotify_fd)+1, &readfds, NULL, NULL, NULL); if (fdcount < 0) { if (errno != EINTR) dbg("error in select: %s", strerror(errno)); @@ -965,6 +1028,33 @@ int main(int argc, char *argv[], char *envp[]) 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) { + char *buf; + + reload_config = 1; + buf = malloc(nbytes); + if (!buf) { + 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 signal*/ + if (reload_config) { + reload_config = 0; + udev_rules_close(&rules); + udev_rules_init(&rules, 0, 1); + } + /* forked child have returned */ if (sigchilds_waiting) { sigchilds_waiting = 0; @@ -990,6 +1080,8 @@ int main(int argc, char *argv[], char *envp[]) } exit: + udev_rules_close(&rules); + if (signal_pipe[READ_END] > 0) close(signal_pipe[READ_END]); if (signal_pipe[WRITE_END] > 0) @@ -997,6 +1089,8 @@ exit: if (udevd_sock > 0) close(udevd_sock); + if (inotify_fd > 0) + close(inotify_fd); if (uevent_netlink_sock > 0) close(uevent_netlink_sock); diff --git a/udevd.h b/udevd.h index da5f6b94f9..db510ab24a 100644 --- a/udevd.h +++ b/udevd.h @@ -54,6 +54,7 @@ enum udevd_msg_type { UDEVD_START_EXEC_QUEUE, UDEVD_SET_LOG_LEVEL, UDEVD_SET_MAX_CHILDS, + UDEVD_RELOAD_RULES, }; From 6cb1bbe471ea4e5098a47e4515765e6cae96b9a0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 27 Oct 2005 21:49:13 +0200 Subject: [PATCH 1567/4284] "make STRIPCMD=" will disable the stripping of binaries Almost all packagers have always patched the stripping out, cause the buildsystems takes care of it. Signed-off-by: Kay Sievers --- Makefile | 4 +++- RELEASE-NOTES | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f69ac96e9d..d309cf6c90 100644 --- a/Makefile +++ b/Makefile @@ -169,7 +169,7 @@ endif # if DEBUG is enabled, then we do not strip ifeq ($(strip $(DEBUG)),true) CFLAGS += -DDEBUG - STRIPCMD = /bin/true unstripped binary + STRIPCMD = endif ifeq ($(strip $(USE_GCOV)),true) @@ -233,7 +233,9 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) # "Static Pattern Rule" to build all programs $(PROGRAMS): %: $(HOST_PROGS) $(KLCC) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) %.o $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # our own copy of klibc, it is not used if KLCC is given $(KLCC): diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 815d4083c5..39e72d474d 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,15 @@ +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. + +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". From 90e037dbe29fc55e72d0c7e31ed78a71b8dca2c9 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 28 Oct 2005 00:29:50 +0200 Subject: [PATCH 1568/4284] remove no longer working udevd-test program Signed-off-by: Kay Sievers --- test/udevd-test/udev-log-amplify.pl | 63 --- test/udevd-test/udev-log-script.pl | 58 --- test/udevd-test/udevd-test.pl | 602 ---------------------------- 3 files changed, 723 deletions(-) delete mode 100644 test/udevd-test/udev-log-amplify.pl delete mode 100644 test/udevd-test/udev-log-script.pl delete mode 100644 test/udevd-test/udevd-test.pl diff --git a/test/udevd-test/udev-log-amplify.pl b/test/udevd-test/udev-log-amplify.pl deleted file mode 100644 index 9e2692ac0c..0000000000 --- a/test/udevd-test/udev-log-amplify.pl +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/perl -w -# -# udev-log-amplify -# -# Copyright (C) Intel Corp, 2004 -# -# Author: Yin Hu -# -# This is a script for replacing udev binary during udevsend/udevd testing. -# It first amplifies the execution time ( sleep 5 ) and then logs the event -# information sent by udved in order that test script udevd-test.pl can -# analyze whether udved execute as we expected. -# You should not execute this script directly because it will be invoked by -# udevd automatically. -# -# Before you run your test please modify $log_file to designate where the udev -# log file should be placed, in fact, the default value is ok. -# -# -# 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. -# - -use warnings; -use strict; - -# modifiable settings -my $udev_exe_time = 5; -my $log_file = "/tmp/udev_log.txt"; - -if ($ARGV[0]) { - my $subsystem = $ARGV[0]; - my $devpath = $ENV{DEVPATH}; - my $action = $ENV{ACTION}; - my $time = time(); - - # Logging - if (open(LOGF, ">>$log_file")) { - print LOGF "$devpath,$action,$subsystem,$time\n"; - } else { - print "File open failed. \n"; - exit 1; - } - close(LOGF); - - # Amplify the execution time of udev - sleep 5; - - exit 0; -} else { - print "Too less argument count.\n"; - exit 1; -} diff --git a/test/udevd-test/udev-log-script.pl b/test/udevd-test/udev-log-script.pl deleted file mode 100644 index 5d7ca71181..0000000000 --- a/test/udevd-test/udev-log-script.pl +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/perl -w -# -# udev-log-script -# -# Copyright (C) Intel Corp, 2004 -# -# Author: Yin Hu -# -# This is a script for replacing udev binary during udevsend/udevd testing. -# It just simply logs the event information sent by udved in order to -# test script udevd-test.pl can analyze whether udved execute as we expected. -# You should not execute this script directly because it will be invoked by -# udevd automatically. -# -# Before you run your test please modify $log_file to designate where the udev -# log file should be placed, in fact, the default value is ok. -# -# -# 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. -# - -use warnings; -use strict; - -# modifiable settings -my $log_file = "/tmp/udev_log.txt"; - -if ($ARGV[0]) { - my $subsystem = $ARGV[0]; - my $devpath = $ENV{DEVPATH}; - my $action = $ENV{ACTION}; - my $time = time(); - - # Logging - if (open(LOGF, ">>$log_file")) { - print LOGF "$devpath,$action,$subsystem,$time\n"; - } else { - print "File open failed. \n"; - exit 1; - } - close(LOGF); - - exit 0; -} else { - print "Too less argument count.\n"; - exit 1; -} diff --git a/test/udevd-test/udevd-test.pl b/test/udevd-test/udevd-test.pl deleted file mode 100644 index 2328de814f..0000000000 --- a/test/udevd-test/udevd-test.pl +++ /dev/null @@ -1,602 +0,0 @@ -#!/usr/bin/perl -w -# -# udevd-test -# -# Copyright (C) Intel Corp, 2004 -# -# Author: Yin Hu -# -# Provides automated testing of the udevd binary.This test script is self-contained. -# Before you run this script please modify $sysfs to locate your sysfs filesystem, -# modify $udevsend_bin to locate your udevsend binary, -# modify $udev_bin to locate dummy udev script, -# modify $udev_bin2 to locate another dummy udev script ( amplify the execution time for test), -# modify $log_file to locate where udev script have placed the log file, -# modify $time_out to decide the time out for events, -# modify $udev_exe_time to decide the execution time for dummy udev script. -# -# Detail information of each test case please refer to the header of corresponding -# test case function. -# -# -# 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. -# - -use warnings; -use strict; - -# modifiable settings -my $sysfs = "../sys"; -my $udevd_bin = "../../udevd"; -my $udevsend_bin = "../../udevsend"; -my $udev_bin = "$ENV{'PWD'}/udev-log-script.pl"; -my $udev_bin2 = "$ENV{'PWD'}/udev-log-amplify.pl"; -my $log_file = "/tmp/udev_log.txt"; -my $time_out = 10; -my $udev_exe_time = 5; - -# global variables -my $test_case = 0; - -# common functions - -sub restart_daemon { - my ($udev_binary) = @_; - - system("killall udevd"); - system("rm -f $log_file"); - sleep 1; - - if (!defined($udev_binary)) { - $udev_binary = $udev_bin; - } - - $ENV{'UDEV_BIN'} = $udev_binary; - system("/bin/sh -c $udevd_bin&"); - sleep(1); -} - -sub udevsend { - # This function prepares corresponding environment variables - # and then call $udevsend_bin to send event. - - my ($seqnum, $devpath, $action, $subsystem, $script) = @_; - - %ENV = (); - $ENV{'DEVPATH'} = $devpath; - $ENV{'ACTION'} = $action; - $ENV{'SUBSYSTEM'} = $subsystem; - - if ( $seqnum != -1) { - $ENV{SEQNUM} = $seqnum; - } - - return system("$udevsend_bin $subsystem"); -} - -sub check_count_and_time { - my $event_recv_time; - my $udev_fork_time; - my $log_ln_count = 0; - my $line; - my @content; - my @line_items; - my $diff; - - ($event_recv_time) = @_; - - print " event receiving time: $event_recv_time\n\n"; - - open(LOGF, $log_file) || die "Opening file $log_file: $!"; - @content = ; - foreach $line ( @content ) { - @line_items = split(/,/,$line); - print " device: $line_items[0], action: $line_items[1] \n"; - print " forking udev time: $line_items[-1]"; - $diff = $line_items[-1] - $event_recv_time; - print " the delay time is: $diff s \n\n"; - if ( $diff > $time_out+10 ) { - print " the delay time is: $diff \n"; - print " udevd doesn't act properly. \n"; - exit 1; - } - $log_ln_count++; - } - close(LOGF); - - return $log_ln_count; -} - -sub check_sysfs_device_exist { - # check if the designated devices exist - my @dev_list = @_; - my $dev; - - foreach $dev (@dev_list) { - if (! -e $dev) { - print "the designated device $dev doesn't exist. please change a device!\n"; - exit 1; - } - } -} - -sub show_result { - my $event_recv_time; - my $udev_fork_time; - my $line; - my @content; - my @line_items; - my $diff; - - ($event_recv_time) = @_; - - print " event receiving time: $event_recv_time\n\n"; - - open(LOGF, $log_file) || die "Opening file $log_file: $!"; - @content = ; - foreach $line ( @content ) { - @line_items = split(/,/,$line); - print " device: $line_items[0], action: $line_items[1] \n"; - print " forking udev time: $line_items[-1]"; - $diff = $line_items[-1] - $event_recv_time; - print " the delay time is: $diff s \n\n"; - } - close(LOGF); -} - -sub show_result_tm_out { - my $event_recv_time; - my $udev_fork_time; - my $line; - my @content; - my @line_items; - my $diff; - - ($event_recv_time) = @_; - - print " event receiving time: $event_recv_time\n\n"; - - open(LOGF, $log_file) || die "Opening file $log_file: $!"; - @content = ; - foreach $line ( @content ) { - @line_items = split(/,/,$line); - print " device: $line_items[0], action: $line_items[1] \n"; - print " forking udev time: $line_items[-1]"; - $diff = $line_items[-1] - $event_recv_time; - print " the delay time is: $diff s \n\n"; - if ( $diff < $time_out ) { - print " the delay time is: $diff \n"; - print " udevd doesn't act properly. \n"; - exit 1; - } - } - close(LOGF); -} - -sub show_result_immediate { - my $event_recv_time; - my $udev_fork_time; - my $line; - my @content; - my @line_items; - my $diff; - - ($event_recv_time) = @_; - - print " event receiving time: $event_recv_time\n\n"; - - open(LOGF, $log_file) || die "Opening file $log_file: $!"; - @content = ; - foreach $line ( @content ) { - @line_items = split(/,/,$line); - print " device: $line_items[0], action: $line_items[1] \n"; - print " forking udev time: $line_items[-1]"; - $diff = $line_items[-1] - $event_recv_time; - print " the delay time is: $diff s \n\n"; - if ( $diff > $time_out ) { - print " the delay time is: $diff \n"; - print " udevd doesn't act properly. \n"; - exit 1; - } - } - close(LOGF); -} - -sub check_exe_time { - my @exe_time; - my $i = 0; - my $line; - my @content; - my @line_items; - my $diff; - - open(LOGF, $log_file) || die "Opening file $log_file: $!"; - @content = ; - close(LOGF); - foreach $line ( @content ) { - @line_items = split(/,/,$line); - $exe_time[$i] = $line_items[-1]; - $i++; - } - $diff = $exe_time[1] - $exe_time[0]; - if ( $diff < $udev_exe_time ) { - print " there are more than one udev instance for a single device at the same time. \n"; - exit 1; - } else { - print " there is just one udev instance for a single device at the same time. \n"; - } -} - -# test case functions -sub run_no_seq_test { - print "Test case name: no sequence number test\n"; - print "Test case purpose: check whether udevd forks udev immediately when environment variable SEQNUM is null.\n"; - print "Test expected visible results: \n"; - print " the delay time between event receiving and forking udev for udevd should be negligible, \n"; - print " that is, udev should be forked at once. please notice the following time...\n\n"; - - my $time; - - # - # add devices event test - # - restart_daemon(); - - # check if devices /block/sda exist - check_sysfs_device_exist("$sysfs/block/sda"); - - # log current system date/time - $time = time(); - - udevsend(-1, "/block/sda", "add", "block"); - - # check if execution is successful in time - sleep 1; - show_result_immediate($time); - print " fork udev (add device) at once successfully.\n\n"; - - # - # remove devices event test - # - system("rm -f $log_file"); - - # log current system date/time - $time = time(); - - udevsend(-1, "/block/sda", "remove", "block"); - - # check if execution is successful in time - sleep 1; - show_result_immediate($time); - print " fork udev (remove device) at once successfully.\n\n"; - print "this case is ok\n\n"; -} - -sub run_normal_seq_test { - print "Test case name: normal sequence number stress test\n"; - print "Test case purpose: check whether udevd can fork massive udev instances for \n"; - print " massive sequential events successfully. \n"; - print "Test expected visible results: \n"; - print " Populate all the devices in directory $sysfs/class/tty, fork udved to send add/remove \n"; - print " event to udev for each device. \n"; - print " We can see the delay time for each device should be negligible. \n\n"; - - my @file_list; - my $file; - my $seq = 0; - my $time; - my $ret_seq; - - restart_daemon(); - @file_list = glob "$sysfs/class/tty/*"; - - # log current system date/time for device add events - $time = time(); - - # - # add devices event test - # - print "add device events test: \n"; - foreach $file (@file_list) { - udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "add", "tty"); - # check if execution is successful - if ($? == 0) { - $seq++; - } else { - print "add event: error\n\n"; - exit 1; - } - } - - # we'd better wait the udev to create all the device for a few seconds - print " wait for udevd processing about $time_out s... \n\n"; - sleep $time_out + 5; - - $ret_seq = check_count_and_time($time); - if ( $ret_seq != $seq ) { - print " add event: failed. some device-adding events fail to execute.\n\n"; - exit 1; - } else { - print " $seq pieces of device-adding events have executed successfully.\n\n"; - } - - # log current system date/time for device remove events - $time = time(); - - # - # remove devices event test - # - print "remove device events test: \n"; - restart_daemon(); - @file_list = glob "$sysfs/class/tty/*"; - $seq = 0; - foreach $file (@file_list) { - udevsend($seq, substr($file, length($sysfs), length($file)-length($sysfs)), "remove", "tty"); - # check if execution is successful - if ($? == 0) { - $seq++; - } else { - print "remove event: error\n\n"; - exit 1; - } - } - - # we'd better wait the udev to create all the device for a few seconds - print " waiting for udev removing devices (about $time_out s)...\n"; - sleep $time_out + 5; - - # show results - $ret_seq = check_count_and_time($time); - if ( $ret_seq != $seq ) { - print " remove event: failed. some device-removing events fail to execute.\n\n"; - exit 1; - } else { - print " $seq pieces of device-removing events have executed successfully.\n\n"; - print "this case is ok.\n\n"; - } -} - -sub run_random_seq_test { - print "Test case name: random sequence number test case,\n"; - print "Test case purpose: check whether udevd can order the events with random sequence number \n"; - print " and fork udev correctly. \n"; - print "Test expected visible results: \n"; - print " We have disordered the events sent to udevd, if udevd can order them correctly, the devices' \n"; - print " add/remove sequence should be tty0, tty1, tty2. \n\n"; - - my $time; - - # check if devices /class/tty/tty0, tty1, tty2 exist - check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2"); - - # - # add device events test - # - print "add device events test: \n"; - restart_daemon(); - - # log current system date/time for device remove events - $time = time(); - - # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem - udevsend(3, "/class/tty/tty2", "add", "tty"); - udevsend(1, "/class/tty/tty0", "add", "tty"); - udevsend(2, "/class/tty/tty1", "add", "tty"); - print " wait for udevd processing about $time_out s... \n\n"; - sleep $time_out+1; - show_result_tm_out($time); - - # - # remove device events test - # - print "\nremove device events test: \n"; - restart_daemon(); - - # log current system date/time for device remove events - $time = time(); - - udevsend(3, "/class/tty/tty2", "remove", "tty"); - udevsend(2, "/class/tty/tty1", "remove", "tty"); - udevsend(1, "/class/tty/tty0", "remove", "tty"); - - # show results - print " wait for udevd processing about $time_out s... \n\n"; - sleep $time_out+1; - show_result_tm_out($time); - print "this case is ok.\n\n"; -} - -sub run_expected_seq_test { - print "Test case name: expected sequence number test \n"; - print "Test case purpose: check whether udevd fork udev immediately when the incoming event\n"; - print " is exactly the expected event sequence number.\n"; - print "Test expected visible results:\n"; - print " first, udevd disposes disorder events(sequence number is 3,1,2,5,4,6),\n"; - print " thus after disposed the expected event number for udevd is 7, when incoming event is 7, udevd\n"; - print " should fork udev immediately, the delay time should be negligible. \n"; - print " where: event 7 is (add device /class/tty/tty2) \n\n"; - - my $time; - - # check if devices /class/tty0, tty1, tty2 exist - check_sysfs_device_exist("$sysfs/class/tty/tty0", "$sysfs/class/tty/tty1", "$sysfs/class/tty/tty2"); - - restart_daemon(); - - # parameters: 1 sequence number, 2 device, 3 action, 4 subsystem - udevsend(3, "/class/tty/tty2", "add", "tty"); - udevsend(1, "/class/tty/tty0", "add", "tty"); - udevsend(2, "/class/tty/tty1", "add", "tty"); - udevsend(5, "/class/tty/tty1", "remove", "tty"); - udevsend(4, "/class/tty/tty0", "remove", "tty"); - udevsend(6, "/class/tty/tty2", "remove", "tty"); - - print " wait for udevd timing out for disorder events (about $time_out s) \n\n"; - sleep $udev_exe_time + $time_out+1; - system("rm -f $log_file"); - - # log current system date/time for device remove events - $time = time(); - - # show results - udevsend(7, "/class/tty/tty2", "add", "tty"); - sleep 1; - print " event sequence number: 7 \n"; - show_result_immediate($time); - - print "this case is ok.\n\n"; -} - -sub run_single_instance_test { - print "Test case name: single instance running for a single device test \n"; - print "Test case purpose: check whether udevd only fork one udev instance for a single\n"; - print " device at the same time. For each event a udev instance is \n"; - print " executed in the background. All further events for the same \n"; - print " device are delayed until the execution is finished. This way \n"; - print " there will never be more than one instance running for a single \n"; - print " device at the same time.\n"; - print "Test expected visible results:\n"; - print " In this test we amplify the execution time of udev (about 5 seconds), first, \n"; - print " we send a add event for device /block/sda, and then we send a remove event, so the \n"; - print " execution of remove event should be delayed until add is finished. \n\n"; - - my $time; - - restart_daemon($udev_bin2); - - # check if device exists - check_sysfs_device_exist("$sysfs/block/sda"); - - # log current system date/time - $time = time(); - - udevsend(-1, "/block/sda", "add", "block"); - udevsend(-1, "/block/sda", "remove", "block"); - - # show results - print " wait for udevd processing about $udev_exe_time s... \n\n"; - sleep $udev_exe_time+1; - show_result_immediate($time); - check_exe_time(); - print "this case is ok\n\n"; -} - -sub run_same_events_test { - print "Test case name: event sequence number overlap test \n"; - print "Test case purpose: check whether udevd doesn't fork udev untill time out\n"; - print " when encountering a event with sequence number same as the pevious event. \n"; - print "Test expected visible results:\n"; - print " event ( remove device /block/sda ) should be no delay, \n"; - print " event ( add device /class/tty/tty1 ) should be delayed for $time_out s than its previous \n"; - print " event ( remove device /block/sda ) \n\n"; - - my $time; - - restart_daemon(); - - # check if device exist - check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1"); - - udevsend(0, "/block/sda", "add", "block"); - - # log current system date/time - sleep 1; - $time = time(); - system("rm -f $log_file"); - - udevsend(1, "/block/sda", "remove", "block"); - udevsend(1, "/class/tty/tty1", "add", "tty"); - - # show results - print " wait for udevd processing about $time_out s... \n\n"; - sleep $time_out+1; - show_result($time); - print "this case is ok\n\n"; -} - -sub run_missing_seq_test { - print "Test case name: missing sequence number test \n"; - print "Test case purpose: check whether udevd doesn't fork udev untill time out\n"; - print " when certain event sequence number is missing.\n"; - print "Test expected visible results:\n"; - print " the delay time for event(add device /block/sda) should be about $time_out s.\n\n"; - - my $time; - - restart_daemon(); - - # check if device exist - check_sysfs_device_exist("$sysfs/block/sda", "$sysfs/class/tty/tty1"); - - udevsend(0, "/class/tty/tty1", "add", "tty"); - udevsend(1, "/class/tty/tty1", "remove", "tty"); - sleep 1; - - # log current system date/time - $time = time(); - system("rm -f $log_file"); - - udevsend(3, "/block/sda", "add", "block"); - - # show results - print " wait for udevd processing about $time_out s... \n\n"; - sleep $time_out+1; - show_result($time); - print "this case is ok\n\n"; -} - -sub run_all_cases_test { - run_no_seq_test(); - run_normal_seq_test(); - run_random_seq_test(); - run_missing_seq_test(); - run_expected_seq_test(); - run_same_events_test(); - run_single_instance_test(); -} - -# main program -if ($ARGV[0]) { - $test_case = $ARGV[0]; - - if ($test_case == 1) { - run_no_seq_test(); - } elsif ($test_case == 2) { - run_normal_seq_test(); - } elsif ($test_case == 3) { - run_random_seq_test(); - } elsif ($test_case == 4) { - run_missing_seq_test(); - } elsif ($test_case == 5) { - run_expected_seq_test(); - } elsif ($test_case == 6) { - run_single_instance_test(); - } elsif ($test_case == 7) { - run_same_events_test(); - } else { - run_all_cases_test(); - } -} else { - # echo usage - print "command format: perl udevd-test.pl \n"; - print " test case:\n"; - print " 1: no event sequence number\n"; - print " 2: sequential event sequence number\n"; - print " 3: random event sequence number\n"; - print " 4: missing event sequence number\n"; - print " 5: the incoming event sequence number is right the expected sequence number\n"; - print " 6: single udev instance on a single device at the same time\n"; - print " 7: test event sequence number overlap\n"; - print " 9: all the cases\n\n"; -} From c1bf1edeb726dc2cdedca5358f9b9cd88db72697 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 28 Oct 2005 01:49:22 +0200 Subject: [PATCH 1569/4284] "STRIPCMD=" for the EXTRAS Signed-off-by: Kay Sievers --- Makefile | 2 +- extras/ata_id/Makefile | 2 ++ extras/cdrom_id/Makefile | 2 ++ extras/dasd_id/Makefile | 2 ++ extras/edd_id/Makefile | 2 ++ extras/firmware/Makefile | 2 ++ extras/floppy/Makefile | 2 ++ extras/run_directory/Makefile | 2 ++ extras/scsi_id/Makefile | 2 ++ extras/usb_id/Makefile | 2 ++ extras/volume_id/Makefile | 2 ++ 11 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d309cf6c90..8446eee924 100644 --- a/Makefile +++ b/Makefile @@ -233,7 +233,7 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) # "Static Pattern Rule" to build all programs $(PROGRAMS): %: $(HOST_PROGS) $(KLCC) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) %.o $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) -ifneq ($(strip $(STRIPCMD)),) +ifneq ($(STRIPCMD),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index d93e694778..fba0d0b719 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -35,7 +35,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(STRIPCMD),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index c3ee6e3295..f06d2c65bf 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -35,7 +35,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index 2a14050d66..698253a9ee 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -35,7 +35,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/edd_id/Makefile b/extras/edd_id/Makefile index 70244ea468..65e023f542 100644 --- a/extras/edd_id/Makefile +++ b/extras/edd_id/Makefile @@ -35,7 +35,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index 7de94c40a7..48dacb4764 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -35,7 +35,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index 8568e28edf..344f48828d 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -35,7 +35,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 20b3af340c..1b48719c61 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -34,7 +34,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 8a8c714a87..fadd4a1dd4 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -49,7 +49,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif scsi_id_version.h: @echo "/* This file is auto-generated by the Makefile */" > $@ diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index 1796aaea09..9f82fd5b2c 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -35,7 +35,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 56cab10e23..a936e43bb2 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -38,7 +38,9 @@ all: $(PROG) $(MAN_PAGES) $(PROG): %: $(HEADERS) %.o $(OBJS) $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ +endif # man pages %.8: %.xml From 29ed5bf414c9eebdc78c68540f8a19af7691ef1f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 28 Oct 2005 02:29:38 +0200 Subject: [PATCH 1570/4284] add dummy inotify syscalls on unsupported architecture Signed-off-by: Kay Sievers --- udev_libc_wrapper.h | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 9a8b26a2b3..824603b74c 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -66,10 +66,22 @@ # define __NR_inotify_add_watch 291 # define __NR_inotify_rm_watch 292 #else -# error "Unsupported architecture!" +#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 */ #ifdef __KLIBC__ #include @@ -83,13 +95,17 @@ static inline int inotify_add_watch(int fd, const char *name, uint32_t mask) { return syscall(__NR_inotify_add_watch, fd, name, mask); } +#endif /* __KLIBC__ */ +#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 /* __KLIBC__ */ +#endif /* IN_CREATE */ /* needed for our signal handlers to work */ #undef asmlinkage From 2a4ce7092546039063fcf5aaa36760a89d8c9047 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 29 Oct 2005 21:13:43 +0200 Subject: [PATCH 1571/4284] remove no longer needed waiting for "dev" file Signed-off-by: Kay Sievers --- udev_sysfs.c | 310 ++++++++++----------------------------------------- udev_sysfs.h | 3 +- udev_utils.c | 23 ---- udev_utils.h | 1 - 4 files changed, 61 insertions(+), 276 deletions(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index 75e275d500..71aa827d38 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -35,30 +35,6 @@ #include "logging.h" /* list of subsystem specific files, NULL if there is no file to wait for */ -static const struct subsystem_file { - const char *subsystem; - const char *file; -} subsystem_files[] = { - { .subsystem = "class", .file = NULL }, - { .subsystem = "net", .file = "ifindex" }, - { .subsystem = "scsi_host", .file = "unique_id" }, - { .subsystem = "scsi_device", .file = NULL }, - { .subsystem = "pcmcia_socket", .file = "card_type" }, - { .subsystem = "usb_host", .file = NULL }, - { .subsystem = "bluetooth", .file = "address" }, - { .subsystem = "firmware", .file = "data" }, - { .subsystem = "i2c-adapter", .file = NULL }, - { .subsystem = "pci_bus", .file = NULL }, - { .subsystem = "ieee1394", .file = NULL }, - { .subsystem = "ieee1394_host", .file = NULL }, - { .subsystem = "ieee1394_node", .file = NULL }, - { .subsystem = "fc_transport", .file = "port_id" }, - { .subsystem = "fc_host", .file = "port_id" }, - { .subsystem = "spi_transport", .file = "width" }, - { .subsystem = "spi_host", .file = "width" }, - { NULL, NULL } -}; - dev_t get_devt(struct sysfs_class_device *class_dev) { struct sysfs_attribute *attr = NULL; @@ -76,215 +52,6 @@ dev_t get_devt(struct sysfs_class_device *class_dev) return makedev(major, minor); } -int subsystem_expect_no_dev(const char *subsystem) -{ - const struct subsystem_file *file; - - for (file = subsystem_files; file->subsystem != NULL; file++) - if (strcmp(subsystem, file->subsystem) == 0) - return 1; - - return 0; -} - -/* get subsystem specific files, returns "dev" if no other found */ -static const char *get_subsystem_specific_file(const char *subsystem) -{ - const struct subsystem_file *file; - - /* look if we want to look for another file instead of "dev" */ - for (file = subsystem_files; file->subsystem != NULL; file++) - if (strcmp(subsystem, file->subsystem) == 0) - return file->file; - - return "dev"; -} - -/* wait for class pecific file to show up */ -static int wait_for_class_device_attributes(struct sysfs_class_device *class_dev, - const char **error) -{ - const char *file; - char filename[PATH_SIZE]; - int loop; - - file = get_subsystem_specific_file(class_dev->classname); - if (file == NULL) { - dbg("class '%s' has no file to wait for", class_dev->classname); - return 0; - } - - snprintf(filename, sizeof(filename), "%s/%s", class_dev->path, file); - filename[sizeof(filename)-1] = '\0'; - dbg("looking at class '%s' for specific file '%s'", class_dev->classname, filename); - - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - struct stat stats; - - if (stat(class_dev->path, &stats) == -1) { - dbg("'%s' now disappeared (probably remove has beaten us)", class_dev->path); - return -ENODEV; - } - - if (stat(filename, &stats) == 0) { - dbg("class '%s' specific file '%s' found", class_dev->classname, file); - return 0; - } - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - dbg("error: getting class '%s' specific file '%s'", class_dev->classname, file); - if (error) - *error = "class specific file unavailable"; - return -ENOENT; -} - -/* check if we need to wait for a physical device */ -static int class_device_expect_no_device_link(struct sysfs_class_device *class_dev) -{ - /* list of devices without a "device" symlink to the physical device - * if device is set to NULL, no devices in that subsystem has a link */ - static const struct class_device { - const char *subsystem; - const char *device; - } class_device[] = { - { .subsystem = "block", .device = "double" }, - { .subsystem = "block", .device = "nb" }, - { .subsystem = "block", .device = "ram" }, - { .subsystem = "block", .device = "loop" }, - { .subsystem = "block", .device = "fd" }, - { .subsystem = "block", .device = "md" }, - { .subsystem = "block", .device = "dos_cd" }, - { .subsystem = "block", .device = "rflash" }, - { .subsystem = "block", .device = "rom" }, - { .subsystem = "block", .device = "rrom" }, - { .subsystem = "block", .device = "flash" }, - { .subsystem = "block", .device = "msd" }, - { .subsystem = "block", .device = "sbpcd" }, - { .subsystem = "block", .device = "pcd" }, - { .subsystem = "block", .device = "pf" }, - { .subsystem = "block", .device = "scd" }, - { .subsystem = "block", .device = "ubd" }, - { .subsystem = "block", .device = "dm-" }, - { .subsystem = "block", .device = "bcrypt" }, - { .subsystem = "input", .device = "event" }, - { .subsystem = "input", .device = "mice" }, - { .subsystem = "input", .device = "mouse" }, - { .subsystem = "input", .device = "ts" }, - { .subsystem = "input", .device = "js" }, - { .subsystem = "vc", .device = NULL }, - { .subsystem = "tty", .device = NULL }, - { .subsystem = "cpuid", .device = "cpu" }, - { .subsystem = "graphics", .device = "fb" }, - { .subsystem = "mem", .device = NULL }, - { .subsystem = "misc", .device = NULL }, - { .subsystem = "msr", .device = NULL }, - { .subsystem = "netlink", .device = NULL }, - { .subsystem = "net", .device = "sit" }, - { .subsystem = "net", .device = "lo" }, - { .subsystem = "net", .device = "tap" }, - { .subsystem = "net", .device = "ipsec" }, - { .subsystem = "net", .device = "dummy" }, - { .subsystem = "net", .device = "irda" }, - { .subsystem = "net", .device = "ppp" }, - { .subsystem = "net", .device = "tun" }, - { .subsystem = "net", .device = "pan" }, - { .subsystem = "net", .device = "bnep" }, - { .subsystem = "net", .device = "vmnet" }, - { .subsystem = "net", .device = "ippp" }, - { .subsystem = "net", .device = "nlv" }, - { .subsystem = "net", .device = "atml" }, - { .subsystem = "ppp", .device = NULL }, - { .subsystem = "sound", .device = NULL }, - { .subsystem = "printer", .device = "lp" }, - { .subsystem = "ppdev", .device = NULL }, - { .subsystem = "nvidia", .device = NULL }, - { .subsystem = "video4linux", .device = "vbi" }, - { .subsystem = "dvb", .device = NULL }, - { .subsystem = "lirc", .device = NULL }, - { .subsystem = "firmware", .device = NULL }, - { .subsystem = "drm", .device = NULL }, - { .subsystem = "pci_bus", .device = NULL }, - { .subsystem = "ieee1394", .device = NULL }, - { .subsystem = "ieee1394_host", .device = NULL }, - { .subsystem = "ieee1394_node", .device = NULL }, - { .subsystem = "raw", .device = NULL }, - { .subsystem = "zaptel", .device = NULL }, - { .subsystem = "tiglusb", .device = NULL }, - { .subsystem = "ppdev", .device = NULL }, - { .subsystem = "ticables", .device = NULL }, - { .subsystem = "snsc", .device = NULL }, - { .subsystem = "staliomem", .device = NULL }, - { .subsystem = "tape", .device = NULL }, - { .subsystem = "ip2", .device = NULL }, - { .subsystem = "tpqic02", .device = NULL }, - { .subsystem = "dsp56k", .device = NULL }, - { .subsystem = "zft", .device = NULL }, - { .subsystem = "adb", .device = NULL }, - { .subsystem = "cosa", .device = NULL }, - { .subsystem = "pg", .device = NULL }, - { .subsystem = "pt", .device = NULL }, - { .subsystem = "capi", .device = NULL }, - { NULL, NULL } - }; - const struct class_device *classdevice; - unsigned int len; - - /* the kernel may tell us what to wait for */ - if (kernel_release_satisfactory(2,6,10) > 0) - if (getenv("PHYSDEVPATH") == NULL) { - dbg("the kernel says, that there is no physical device for '%s'", class_dev->path); - return 1; - } - - for (classdevice = class_device; classdevice->subsystem != NULL; classdevice++) { - if (strcmp(class_dev->classname, classdevice->subsystem) == 0) { - /* see if no device in this class is expected to have a device-link */ - if (classdevice->device == NULL) - return 1; - - len = strlen(classdevice->device); - - /* see if device name matches */ - if (strncmp(class_dev->name, classdevice->device, len) != 0) - continue; - - /* exact name match */ - if (strlen(class_dev->name) == len) - return 1; - - /* name match with instance number */ - if (isdigit(class_dev->name[len])) - return 1; - } - } - - return 0; -} - -/* skip waiting for the bus of the devices device */ -static int class_device_expect_no_bus(struct sysfs_class_device *class_dev) -{ - static const char *devices_without_bus[] = { - "scsi_host", - "i2c-adapter", - "i2c-dev", - NULL - }; - const char **device; - - for (device = devices_without_bus; *device != NULL; device++) { - int len = strlen(*device); - - if (strncmp(class_dev->classname, *device, len) == 0) - return 1; - } - - return 0; -} - /* wait for a devices device specific file to show up */ int wait_for_devices_device(struct sysfs_device *devices_dev, const char **error) @@ -335,12 +102,10 @@ int wait_for_devices_device(struct sysfs_device *devices_dev, const struct device_file *devicefile = NULL; int loop; - /* the kernel may tell us what to wait for */ - if (kernel_release_satisfactory(2,6,10) > 0) - if (getenv("PHYSDEVBUS") == NULL) { - dbg("the kernel says, that there is no bus for '%s'", devices_dev->path); - return 0; - } + if (getenv("PHYSDEVBUS") == NULL) { + dbg("the kernel says, that there is no bus for '%s'", devices_dev->path); + return 0; + } /* wait for the bus device link to the devices device */ loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; @@ -421,17 +186,68 @@ struct sysfs_class_device *wait_class_device_open(const char *path) int wait_for_class_device(struct sysfs_class_device *class_dev, const char **error) { + const struct subsystem_file { + const char *subsystem; + const char *file; + } subsystem_files[] = { + { .subsystem = "net", .file = "ifindex" }, + { .subsystem = "scsi_host", .file = "unique_id" }, + { .subsystem = "pcmcia_socket", .file = "card_type" }, + { .subsystem = "bluetooth", .file = "address" }, + { .subsystem = "firmware", .file = "data" }, + { .subsystem = "fc_transport", .file = "port_id" }, + { .subsystem = "fc_host", .file = "port_id" }, + { .subsystem = "spi_transport", .file = "width" }, + { .subsystem = "spi_host", .file = "width" }, + { NULL, NULL } + }; + + const struct subsystem_file *subsys_file; struct sysfs_class_device *class_dev_parent; struct sysfs_device *devices_dev = NULL; + char filename[PATH_SIZE]; int loop; - if (wait_for_class_device_attributes(class_dev, error) != 0) - return -ENOENT; + /* look if we want to wait for a file */ + for (subsys_file = subsystem_files; subsys_file->subsystem != NULL; subsys_file++) + if (strcmp(class_dev->classname, subsys_file->subsystem) == 0) + break; + + if (subsys_file->file == NULL) { + dbg("class '%s' has no file to wait for", class_dev->classname); + return 0; + } + + snprintf(filename, sizeof(filename), "%s/%s", class_dev->path, subsys_file->file); + filename[sizeof(filename)-1] = '\0'; + dbg("looking at class '%s' for specific file '%s'", class_dev->classname, filename); + + loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; + while (--loop) { + struct stat stats; + + if (stat(class_dev->path, &stats) == -1) { + dbg("'%s' now disappeared (probably remove has beaten us)", class_dev->path); + return -ENODEV; + } + + if (stat(filename, &stats) == 0) { + dbg("class '%s' specific file '%s' found", class_dev->classname, subsys_file->file); + return 0; + } + + usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); + } + + dbg("error: getting class '%s' specific file '%s'", class_dev->classname, subsys_file->file); + if (error) + *error = "class specific file unavailable"; + return -1; /* skip devices without devices-link */ - if (class_device_expect_no_device_link(class_dev)) { - dbg("no device symlink expected for '%s', ", class_dev->name); - return 0; + if (getenv("PHYSDEVPATH") == NULL) { + dbg("the kernel says, that there is no physical device for '%s'", class_dev->path); + return 1; } /* the symlink may be on the parent device */ @@ -461,12 +277,6 @@ int wait_for_class_device(struct sysfs_class_device *class_dev, } dbg("device symlink found pointing to '%s'", devices_dev->path); - /* wait for the devices device */ - if (class_device_expect_no_bus(class_dev)) { - dbg("no bus device expected for '%s', ", class_dev->classname); - return 0; - } - return wait_for_devices_device(devices_dev, error); } diff --git a/udev_sysfs.h b/udev_sysfs.h index 8078f62d82..5b87d6bf95 100644 --- a/udev_sysfs.h +++ b/udev_sysfs.h @@ -28,9 +28,8 @@ #define WAIT_LOOP_PER_SECOND 20 extern dev_t get_devt(struct sysfs_class_device *class_dev); -extern int subsystem_expect_no_dev(const char *subsystem); -/* /sys/class /sys/block devices */ +/* /sys/class, /sys/block devices */ extern struct sysfs_class_device *wait_class_device_open(const char *path); extern int wait_for_class_device(struct sysfs_class_device *class_dev, const char **error); diff --git a/udev_utils.c b/udev_utils.c index c7292d0f04..683378aadf 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -57,29 +57,6 @@ int log_priority(const char *priority) return 0; } -int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel) -{ - static unsigned int kversion = 0; - static unsigned int kpatchlevel; - static unsigned int ksublevel; - - if (kversion == 0) { - struct utsname uts; - if (uname(&uts) != 0) - return -1; - - if (sscanf (uts.release, "%u.%u.%u", &kversion, &kpatchlevel, &ksublevel) != 3) { - kversion = 0; - return -1; - } - } - - if (kversion >= version && kpatchlevel >= patchlevel && ksublevel >= sublevel) - return 1; - else - return 0; -} - int name_list_add(struct list_head *name_list, const char *name, int sort) { struct name_entry *loop_name; diff --git a/udev_utils.h b/udev_utils.h index ea39a028f5..ffdaf0469f 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -37,7 +37,6 @@ struct name_entry { /* udev_utils.c */ extern int log_priority(const char *priority); -extern int kernel_release_satisfactory(unsigned int version, unsigned int patchlevel, unsigned int sublevel); extern int name_list_add(struct list_head *name_list, const char *name, int sort); extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); extern void name_list_cleanup(struct list_head *name_list); From 0c25d156b06259f4d0ba4cfafffc8c64c27a0baf Mon Sep 17 00:00:00 2001 From: Jan Luebbe Date: Mon, 31 Oct 2005 02:10:56 +0100 Subject: [PATCH 1572/4284] add man pages for *_id programs I've written manpages for the *_id binaries, which are attached to this mail. --- extras/ata_id/Makefile | 4 ++-- extras/ata_id/ata_id.8 | 28 ++++++++++++++++++++++++++ extras/cdrom_id/Makefile | 4 ++-- extras/cdrom_id/cdrom_id.8 | 27 +++++++++++++++++++++++++ extras/dasd_id/Makefile | 4 ++-- extras/dasd_id/dasd_id.8 | 28 ++++++++++++++++++++++++++ extras/edd_id/Makefile | 4 ++-- extras/edd_id/edd_id.8 | 27 +++++++++++++++++++++++++ extras/volume_id/Makefile | 4 ++-- extras/volume_id/vol_id.8 | 41 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 161 insertions(+), 10 deletions(-) create mode 100644 extras/ata_id/ata_id.8 create mode 100644 extras/cdrom_id/cdrom_id.8 create mode 100644 extras/dasd_id/dasd_id.8 create mode 100644 extras/edd_id/edd_id.8 create mode 100644 extras/volume_id/vol_id.8 diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index fba0d0b719..4080df1b42 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -57,11 +57,11 @@ uninstall-bin: .PHONY: uninstall-bin install-man: - @echo "Please create a man page for this tool." + $(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man uninstall-man: - @echo "Please create a man page for this tool." + -rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man install-config: diff --git a/extras/ata_id/ata_id.8 b/extras/ata_id/ata_id.8 new file mode 100644 index 0000000000..0ef9e3ed84 --- /dev/null +++ b/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 (8) +.SH AUTHORS +Developed by Kay Sievers . + diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index f06d2c65bf..f1120673e1 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -57,11 +57,11 @@ uninstall-bin: .PHONY: uninstall-bin install-man: - @echo "Please create a man page for this tool." + $(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man uninstall-man: - @echo "Please create a man page for this tool." + -rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man install-config: diff --git a/extras/cdrom_id/cdrom_id.8 b/extras/cdrom_id/cdrom_id.8 new file mode 100644 index 0000000000..8c95e938cf --- /dev/null +++ b/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 (8) +.SH AUTHORS +Developed by Greg Kroah\-Hartman . + diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index 698253a9ee..a995c7892d 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -57,11 +57,11 @@ uninstall-bin: .PHONY: uninstall-bin install-man: - @echo "Please create a man page for this tool." + $(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man uninstall-man: - @echo "Please create a man page for this tool." + -rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man install-config: diff --git a/extras/dasd_id/dasd_id.8 b/extras/dasd_id/dasd_id.8 new file mode 100644 index 0000000000..c3d4075326 --- /dev/null +++ b/extras/dasd_id/dasd_id.8 @@ -0,0 +1,28 @@ +.TH DASD_ID 8 "November 2005" "" "Linux Administrator's Manual" +.SH NAME +dasd_id \- udev callout to read label from s390 block device +.SH SYNOPSIS +.BI dasd_id +[\fI--export\fP] \fIblockdevice\fP +.SH "DESCRIPTION" +.B dasd_id +is normally called from a udev rule, to provide udev with a unique string and +additional information (type, serial) for an S390 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 dasd_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 dasd_id +should print: +.TP +.BI --export +print all values (instead of only the serial) +.RE +.SH SEE ALSO +.BR udev (8) +.SH AUTHORS +Developed by Arnd Bergmann and Kay Sievers . + diff --git a/extras/edd_id/Makefile b/extras/edd_id/Makefile index 65e023f542..469d6d4d03 100644 --- a/extras/edd_id/Makefile +++ b/extras/edd_id/Makefile @@ -57,11 +57,11 @@ uninstall-bin: .PHONY: uninstall-bin install-man: - @echo "Please create a man page for this tool." + $(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man uninstall-man: - @echo "Please create a man page for this tool." + -rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man install-config: diff --git a/extras/edd_id/edd_id.8 b/extras/edd_id/edd_id.8 new file mode 100644 index 0000000000..8d5fd4f1aa --- /dev/null +++ b/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 (8) +.SH AUTHORS +Developed by John Hull and Kay Sievers . + diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index a936e43bb2..23de2ba091 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -60,11 +60,11 @@ uninstall-bin: .PHONY: uninstall-bin install-man: - @echo "Please create a man page for this tool." + $(INSTALL_DATA) -D $(PROG).8 $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man uninstall-man: - @echo "Please create a man page for this tool." + -rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8 .PHONY: uninstall-man install-config: diff --git a/extras/volume_id/vol_id.8 b/extras/volume_id/vol_id.8 new file mode 100644 index 0000000000..6ffe7ce220 --- /dev/null +++ b/extras/volume_id/vol_id.8 @@ -0,0 +1,41 @@ +.TH VOL_ID 8 "November 2005" "" "Linux Administrator's Manual" +.SH NAME +vol_id \- probe filesystem type and read label and uuid +.SH SYNOPSIS +.BI vol_id +[\fI--export\fP|\fI-t\fP|\fI-l\fP|\fI-u\fP] \fIblockdevice\fP +.SH "DESCRIPTION" +.B vol_id +is normally called from a udev rule, to provide udev with the +label and uuid of a filesystem. vol_id supports all common +filesystem formats and detects various raid setups to prevent +the recognition of raid members as a filesystem. +.SH USAGE +.B vol_id +opens the device node specified at the commandline. +.SH OPTIONS +The following commandline switches are supported to specify what vol_id +should print: +.TP +.BI --export +print all values in key/value format to import them into the environment. +.TP +.BI -l +print the label of the partition +.TP +.BI -t +print the type of the partition +.TP +.BI -u +print the uuid of the partition +.RE +.SH EXIT STATUS +.B 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. +.SH SEE ALSO +.BR udev (8) +.SH AUTHORS +Developed by Kay Sievers . + From 7a551dc35580988d13ff8e6e3e37398ac779181a Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Wed, 2 Nov 2005 04:02:33 +0100 Subject: [PATCH 1573/4284] libsysfs: translate devpath of the symlinked class devices to its real path --- libsysfs/sysfs_class.c | 110 +++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 37 deletions(-) diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c index edf751b124..102f09f17a 100644 --- a/libsysfs/sysfs_class.c +++ b/libsysfs/sysfs_class.c @@ -128,28 +128,45 @@ static void set_classdev_classname(struct sysfs_class_device *cdev) struct sysfs_class_device *sysfs_open_class_device_path(const char *path) { struct sysfs_class_device *cdev; + char temp_path[SYSFS_PATH_MAX]; if (!path) { errno = EINVAL; return NULL; } + + /* + * Post linux-2.6.14 driver model supports nested classes with + * links to the nested hierarchy at /sys/class/xxx/. Check for + * a link to the actual class device if a directory isn't found + */ if (sysfs_path_is_dir(path)) { - dprintf("%s is not a valid path to a class device\n", path); - return NULL; - } + dprintf("%s: Directory not found, checking for a link\n", path); + if (!sysfs_path_is_link(path)) { + if (sysfs_get_link(path, temp_path, SYSFS_PATH_MAX)) { + dprintf("Error retrieving link at %s\n", path); + return NULL; + } + } else { + dprintf("%s is not a valid class device path\n", path); + return NULL; + } + } else + safestrcpy(temp_path, path); + cdev = alloc_class_device(); if (!cdev) { dprintf("calloc failed\n"); return NULL; } - if (sysfs_get_name_from_path(path, cdev->name, SYSFS_NAME_LEN)) { + if (sysfs_get_name_from_path(temp_path, cdev->name, SYSFS_NAME_LEN)) { errno = EINVAL; dprintf("Error getting class device name\n"); sysfs_close_class_device(cdev); return NULL; } - safestrcpy(cdev->path, path); + safestrcpy(cdev->path, temp_path); if (sysfs_remove_trailing_slash(cdev->path)) { dprintf("Invalid path to class device %s\n", cdev->path); sysfs_close_class_device(cdev); @@ -455,12 +472,10 @@ struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, safestrcpy(path, cls->path); safestrcat(path, "/"); safestrcat(path, name); - if (!sysfs_path_is_dir(path)) { - cdev = sysfs_open_class_device_path(path); - if (!cdev) { - dprintf("Error opening class device at %s\n", path); - return NULL; - } + cdev = sysfs_open_class_device_path(path); + if (!cdev) { + dprintf("Error opening class device at %s\n", path); + return NULL; } if (!cls->devices) cls->devices = dlist_new_with_delete @@ -471,6 +486,40 @@ struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, return cdev; } +/** + * Add class devices to list + */ +static void add_cdevs_to_classlist(struct sysfs_class *cls, struct dlist *list) +{ + char path[SYSFS_PATH_MAX], *cdev_name; + struct sysfs_class_device *cdev = NULL; + + if (cls == NULL || list == NULL) + return; + + dlist_for_each_data(list, cdev_name, char) { + if (cls->devices) { + cdev = (struct sysfs_class_device *) + dlist_find_custom(cls->devices, + (void *)cdev_name, cdev_name_equal); + if (cdev) + continue; + } + safestrcpy(path, cls->path); + safestrcat(path, "/"); + safestrcat(path, cdev_name); + cdev = sysfs_open_class_device_path(path); + if (cdev) { + if (!cls->devices) + cls->devices = dlist_new_with_delete + (sizeof(struct sysfs_class_device), + sysfs_close_cls_dev); + dlist_unshift_sorted(cls->devices, cdev, + sort_list); + } + } +} + /** * sysfs_get_class_devices: get all class devices in the given class * @cls: sysfs_class whose devices list is needed @@ -480,42 +529,29 @@ struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) { char path[SYSFS_PATH_MAX]; - char *cdev_name; - struct sysfs_class_device *cdev = NULL; - struct dlist *dirlist; + struct dlist *dirlist, *linklist; if (!cls) { errno = EINVAL; return NULL; } + /* + * Post linux-2.6.14, we have nested classes and links under + * /sys/class/xxx/. are also valid class devices + */ safestrcpy(path, cls->path); dirlist = read_dir_subdirs(path); if (dirlist) { - dlist_for_each_data(dirlist, cdev_name, char) { - if (cls->devices) { - cdev = (struct sysfs_class_device *) - dlist_find_custom(cls->devices, - (void *)cdev_name, cdev_name_equal); - if (cdev) - continue; - } - safestrcpy(path, cls->path); - safestrcat(path, "/"); - safestrcat(path, cdev_name); - cdev = sysfs_open_class_device_path(path); - if (cdev) { - if (!cls->devices) - cls->devices = dlist_new_with_delete - (sizeof(struct sysfs_class_device), - sysfs_close_cls_dev); - dlist_unshift_sorted(cls->devices, cdev, - sort_list); - } - } + add_cdevs_to_classlist(cls, dirlist); sysfs_close_list(dirlist); } - + + linklist = read_dir_links(path); + if (linklist) { + add_cdevs_to_classlist(cls, linklist); + sysfs_close_list(linklist); + } + return cls->devices; } - From 8ebe9547a81408061ecf3571d31117a18c1810b8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 2 Nov 2005 04:04:19 +0100 Subject: [PATCH 1574/4284] revert the "read symlink as device patch" It's covered by libsysfs now. Signed-off-by: Kay Sievers --- libsysfs/sysfs_utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c index bd7f99ae15..c5558a43a1 100644 --- a/libsysfs/sysfs_utils.c +++ b/libsysfs/sysfs_utils.c @@ -233,7 +233,7 @@ int sysfs_path_is_dir(const char *path) errno = EINVAL; return 1; } - if ((stat(path, &astats)) != 0) { + if ((lstat(path, &astats)) != 0) { dprintf("stat() failed\n"); return 1; } From 0747dd884adfdf2bcd617655c44a87cb7a6eda5f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 2 Nov 2005 04:05:06 +0100 Subject: [PATCH 1575/4284] use libsysfs to translate the class linke to the device path Signed-off-by: Kay Sievers --- udevstart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevstart.c b/udevstart.c index ce96f38879..057d59fcaa 100644 --- a/udevstart.c +++ b/udevstart.c @@ -139,7 +139,7 @@ static int add_device(const char *devpath, const char *subsystem) return -1; } - udev_init_device(&udev, devpath, subsystem, "add"); + udev_init_device(&udev, &class_dev->path[strlen(sysfs_path)], subsystem, "add"); udev.devt = get_devt(class_dev); if (!udev.devt && udev.type != DEV_NET) { dbg("sysfs_open_class_device_path failed"); From 8687cbfffb3d0c380bd02409dd71e0e8ffe3a3b4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 2 Nov 2005 04:58:59 +0100 Subject: [PATCH 1576/4284] libsysfs: remove brute-force "bus", "driver" searching for old kernels Signed-off-by: Kay Sievers --- libsysfs/sysfs_device.c | 88 ----------------------------------------- 1 file changed, 88 deletions(-) diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c index 1c59403edd..e3d70143f9 100644 --- a/libsysfs/sysfs_device.c +++ b/libsysfs/sysfs_device.c @@ -29,10 +29,8 @@ */ static int get_dev_driver(struct sysfs_device *dev) { - struct dlist *drvlist; char path[SYSFS_PATH_MAX]; char devpath[SYSFS_PATH_MAX]; - char *drv = NULL, *c; if (!dev) { errno = EINVAL; @@ -50,44 +48,6 @@ static int get_dev_driver(struct sysfs_device *dev) } return 0; } - - /* - * Devices on earlier kernels do not have the "driver" link. - * Look it up in the bus directory. - */ - if (dev->bus[0] == '\0') - return -1; - memset(path, 0, SYSFS_PATH_MAX); - memset(devpath, 0, SYSFS_PATH_MAX); - safestrcpy(path, dev->path); - c = strstr(path, SYSFS_DEVICES_NAME); - if (c == NULL) { - dprintf("Invalid path to device - %s\n", dev->path); - return -1; - } else - *c = '\0'; - safestrcat(path, SYSFS_BUS_NAME); - safestrcat(path, "/"); - safestrcat(path, dev->bus); - safestrcat(path, "/"); - safestrcat(path, SYSFS_DRIVERS_NAME); - - drvlist = sysfs_open_directory_list(path); - if (drvlist) { - dlist_for_each_data(drvlist, drv, char) { - safestrcpy(devpath, path); - safestrcat(devpath, "/"); - safestrcat(devpath, drv); - safestrcat(devpath, "/"); - safestrcat(devpath, dev->bus_id); - if (!sysfs_path_is_link(devpath)) { - safestrcpy(dev->driver_name, drv); - sysfs_close_list(drvlist); - return 0; - } - } - sysfs_close_list(drvlist); - } return -1; } @@ -100,11 +60,7 @@ static int get_dev_driver(struct sysfs_device *dev) int sysfs_get_device_bus(struct sysfs_device *dev) { char devpath[SYSFS_PATH_MAX]; - char subsys[SYSFS_NAME_LEN]; char path[SYSFS_PATH_MAX]; - char target[SYSFS_PATH_MAX]; - char *bus = NULL, *c; - struct dlist *buslist; if (!dev) { errno = EINVAL; @@ -123,49 +79,6 @@ int sysfs_get_device_bus(struct sysfs_device *dev) } return 0; } - - /* - * Devices on on earlier kernels do not have the "bus" link. - * Look it up in the bus directory. - */ - memset(subsys, 0, SYSFS_NAME_LEN); - safestrcpy(subsys, dev->path); - c = strstr(subsys, SYSFS_DEVICES_NAME); - if (c == NULL) { - dprintf("Invalid path to device - %s\n", dev->path); - return -1; - } else - *c = '\0'; - safestrcat(subsys, SYSFS_BUS_NAME); - buslist = sysfs_open_directory_list(subsys); - if (buslist) { - dlist_for_each_data(buslist, bus, char) { - memset(path, 0, SYSFS_PATH_MAX); - safestrcpy(path, subsys); - safestrcat(path, "/"); - safestrcat(path, bus); - safestrcat(path, "/"); - safestrcat(path, SYSFS_DEVICES_NAME); - safestrcat(path, "/"); - safestrcat(path, dev->bus_id); - if (!sysfs_path_is_link(path)) { - memset(target, 0, SYSFS_PATH_MAX); - if (sysfs_get_link(path, target, - SYSFS_PATH_MAX)) { - dprintf("Error getting link target\n"); - sysfs_close_list(buslist); - return -1; - } - if (!(strncmp(target, dev->path, - SYSFS_PATH_MAX))) { - safestrcpy(dev->bus, bus); - sysfs_close_list(buslist); - return 0; - } - } - } - sysfs_close_list(buslist); - } return -1; } @@ -371,7 +284,6 @@ struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) dprintf("Error opening device %s\n", bus_id); return NULL; } - return device; } From 6d33ed73741ad4108dc1a540defb851418a04013 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 2 Nov 2005 05:08:22 +0100 Subject: [PATCH 1577/4284] test: add "driver" and "bus" links to test sysfs tree Signed-off-by: Kay Sievers --- test/sys/block/cciss!c0d0/device | 2 +- test/sys/block/rd!c0d0/device | 2 +- test/sys/block/sda/device | 2 +- test/sys/bus/scsi/devices/0:0:0:0 | 2 +- test/sys/bus/scsi/drivers/sd/0:0:0:0 | 2 +- test/sys/devices/pci0000:00/0000:00:09.0/bus | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bus | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/driver | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bus | 1 + .../sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/driver | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bus | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/driver | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/bus | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/bus | 1 + test/sys/devices/pci0000:00/0000:00:09.0/usb3/driver | 1 + test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/bus | 1 + test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/driver | 1 + .../0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/bus | 1 + .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/device_blocked | 0 .../0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/driver | 1 + .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/model | 0 .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/online | 0 .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/queue_depth | 0 .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/rev | 0 .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/scsi_level | 0 .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/type | 0 .../0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/vendor | 0 .../host0/{ => target0:0:0}/0:0:0:0/whitespace_test | 0 test/sys/devices/pci0000:00/0000:00:1e.0/bus | 1 + 29 files changed, 20 insertions(+), 5 deletions(-) create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/bus create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bus create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/driver create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bus create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/driver create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bus create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/driver create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/bus create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/bus create mode 120000 test/sys/devices/pci0000:00/0000:00:09.0/usb3/driver create mode 120000 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/bus create mode 120000 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/driver create mode 120000 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/bus rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/device_blocked (100%) create mode 120000 test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/driver rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/model (100%) rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/online (100%) rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/queue_depth (100%) rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/rev (100%) rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/scsi_level (100%) rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/type (100%) rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/vendor (100%) rename test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/{ => target0:0:0}/0:0:0:0/whitespace_test (100%) create mode 120000 test/sys/devices/pci0000:00/0000:00:1e.0/bus diff --git a/test/sys/block/cciss!c0d0/device b/test/sys/block/cciss!c0d0/device index 2d78258b1a..485bf09f61 120000 --- a/test/sys/block/cciss!c0d0/device +++ b/test/sys/block/cciss!c0d0/device @@ -1 +1 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file +../../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/test/sys/block/rd!c0d0/device b/test/sys/block/rd!c0d0/device index 2d78258b1a..485bf09f61 120000 --- a/test/sys/block/rd!c0d0/device +++ b/test/sys/block/rd!c0d0/device @@ -1 +1 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file +../../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/test/sys/block/sda/device b/test/sys/block/sda/device index 2d78258b1a..485bf09f61 120000 --- a/test/sys/block/sda/device +++ b/test/sys/block/sda/device @@ -1 +1 @@ -../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file +../../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/test/sys/bus/scsi/devices/0:0:0:0 b/test/sys/bus/scsi/devices/0:0:0:0 index ebb65b3bac..6d8555dce1 120000 --- a/test/sys/bus/scsi/devices/0:0:0:0 +++ b/test/sys/bus/scsi/devices/0:0:0:0 @@ -1 +1 @@ -../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file +../../../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/test/sys/bus/scsi/drivers/sd/0:0:0:0 b/test/sys/bus/scsi/drivers/sd/0:0:0:0 index 239003f712..97ae02167d 120000 --- a/test/sys/bus/scsi/drivers/sd/0:0:0:0 +++ b/test/sys/bus/scsi/drivers/sd/0:0:0:0 @@ -1 +1 @@ -../../../../devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0 \ No newline at end of file +../../../../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/test/sys/devices/pci0000:00/0000:00:09.0/bus b/test/sys/devices/pci0000:00/0000:00:09.0/bus new file mode 120000 index 0000000000..4b20ef9984 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:09.0/bus @@ -0,0 +1 @@ +../../../bus/pci \ No newline at end of file diff --git a/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bus b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/bus new file mode 120000 index 0000000000..af968de921 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-0:1.0/driver new file mode 120000 index 0000000000..5cf493442c --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bus b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/bus new file mode 120000 index 0000000000..29689de588 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/3-1:1.0/driver new file mode 120000 index 0000000000..27eb850ee4 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bus b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/bus new file mode 120000 index 0000000000..af968de921 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/driver new file mode 120000 index 0000000000..092d2282f3 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/bus b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/3-1/ttyUSB0/bus new file mode 120000 index 0000000000..dd0c04b01d --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bus b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/bus new file mode 120000 index 0000000000..77682faf80 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:09.0/usb3/driver b/test/sys/devices/pci0000:00/0000:00:09.0/usb3/driver new file mode 120000 index 0000000000..0b3eba3d91 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/bus b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/bus new file mode 120000 index 0000000000..d6210992bb --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/driver b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/driver new file mode 120000 index 0000000000..f6536ff545 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/bus b/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 0000000000..2edcea4660 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/device_blocked b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/device_blocked similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/device_blocked rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/device_blocked diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/driver b/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 0000000000..5fbbc0f385 --- /dev/null +++ b/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/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/model b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/model similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/model rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/model diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/online b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/online similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/online rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/online diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/queue_depth b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/queue_depth similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/queue_depth rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/queue_depth diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/rev b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/rev similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/rev rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/rev diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/scsi_level b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/scsi_level similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/scsi_level rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/scsi_level diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/type b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/type similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/type rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/type diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/vendor b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/vendor similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/vendor rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/vendor diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/whitespace_test b/test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/whitespace_test similarity index 100% rename from test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/0:0:0:0/whitespace_test rename to test/sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/host0/target0:0:0/0:0:0:0/whitespace_test diff --git a/test/sys/devices/pci0000:00/0000:00:1e.0/bus b/test/sys/devices/pci0000:00/0000:00:1e.0/bus new file mode 120000 index 0000000000..4b20ef9984 --- /dev/null +++ b/test/sys/devices/pci0000:00/0000:00:1e.0/bus @@ -0,0 +1 @@ +../../../bus/pci \ No newline at end of file From ce364175b275834077b97fa79e1969e736b6e551 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 2 Nov 2005 05:47:18 +0100 Subject: [PATCH 1578/4284] update RELEASE-NOTES Signed-off-by: Kay Sievers --- RELEASE-NOTES | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 39e72d474d..0cd11d6bb6 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -5,7 +5,12 @@ event processes inherit the already parsed rules from the daemon. It is shipped with SUSE10.0 and reduces heavily the system load at startup. -using 'make STRIPCMD=' will leave the binaries unstripped for debugging +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. From 833b3c680b23dab87ba4918f25fbd5775dfd9ba8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 4 Nov 2005 05:25:15 +0100 Subject: [PATCH 1579/4284] udevd: don't daemonize before initialization Move socket init and rule parsing before forking, so we can start emitting event immediately after udevd has started. Signed-off-by: Kay Sievers --- udevd.c | 80 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/udevd.c b/udevd.c index 1f769fbce0..c49cf292cf 100644 --- a/udevd.c +++ b/udevd.c @@ -211,11 +211,10 @@ static void udev_event_run(struct uevent_msg *msg) switch (pid) { case 0: /* child */ - if (uevent_netlink_sock > 0) - close(uevent_netlink_sock); + close(uevent_netlink_sock); + close(udevd_sock); if (inotify_fd > 0) close(inotify_fd); - close(udevd_sock); close(signal_pipe[READ_END]); close(signal_pipe[WRITE_END]); logging_close(); @@ -773,7 +772,6 @@ static int init_udevd_socket(void) retval = bind(udevd_sock, (struct sockaddr *) &saddr, addrlen); if (retval < 0) { err("bind failed, %s", strerror(errno)); - close(udevd_sock); return -1; } @@ -803,15 +801,13 @@ static int init_uevent_netlink_sock(void) /* 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)); + 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; } @@ -825,10 +821,11 @@ int main(int argc, char *argv[], char *envp[]) int uevent_netlink_active = 0; int daemonize = 0; int i; + int rc = 0; - /* set std fd's to /dev/null, if the kernel forks us, we don't have them at all */ + /* redirect std fd's, if the kernel forks us, we don't have them at all */ devnull = open("/dev/null", O_RDWR); - if (devnull >= 0) { + if (devnull >= 0) { if (devnull != STDIN_FILENO) dup2(devnull, STDIN_FILENO); if (devnull != STDOUT_FILENO) @@ -851,6 +848,7 @@ int main(int argc, char *argv[], char *envp[]) goto exit; } + /* parse commandline options */ for (i = 1 ; i < argc; i++) { char *arg = argv[i]; if (strcmp(arg, "--daemon") == 0 || strcmp(arg, "-d") == 0) { @@ -863,30 +861,52 @@ int main(int argc, char *argv[], char *envp[]) } } + /* init sockets to receive events */ + if (init_udevd_socket() < 0) { + if (errno == EADDRINUSE) { + dbg("another udevd running, exit"); + rc = 1; + } else { + dbg("error initializing udevd socket: %s", strerror(errno)); + rc = 2; + } + goto exit; + } + + if (init_uevent_netlink_sock() < 0) { + err("uevent socket not available"); + rc = 3; + goto exit; + } + + /* parse the rules and keep it in memory */ + udev_rules_init(&rules, 0, 1); + if (daemonize) { pid_t pid; pid = fork(); switch (pid) { case 0: - dbg("damonized fork running"); + dbg("daemonized fork running"); + + /* become session leader */ + sid = setsid(); + dbg("our session is %d", sid); + + chdir("/"); + umask(umask(077) | 022); break; case -1: err("fork of daemon failed"); + rc = 4; goto exit; default: - logging_close(); - exit(0); + dbg("child [%u] running, parent exits", pid); + goto exit; } } - /* become session leader */ - sid = setsid(); - dbg("our session is %d", sid); - - chdir("/"); - umask(umask(077) | 022); - /* set a reasonable scheduling priority for the daemon */ setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); @@ -918,21 +938,6 @@ int main(int argc, char *argv[], char *envp[]) sigaction(SIGCHLD, &act, NULL); sigaction(SIGHUP, &act, NULL); - /* parse the rules and keep it in memory */ - udev_rules_init(&rules, 0, 1); - - if (init_udevd_socket() < 0) { - if (errno == EADDRINUSE) - dbg("another udevd running, exit"); - else - dbg("error initializing udevd socket: %s", strerror(errno)); - - goto exit; - } - - if (init_uevent_netlink_sock() < 0) - err("uevent socket not available"); - /* watch rules directory */ inotify_fd = inotify_init(); if (inotify_fd > 0) @@ -983,8 +988,7 @@ int main(int argc, char *argv[], char *envp[]) FD_ZERO(&readfds); FD_SET(signal_pipe[READ_END], &readfds); FD_SET(udevd_sock, &readfds); - if (uevent_netlink_sock > 0) - FD_SET(uevent_netlink_sock, &readfds); + FD_SET(uevent_netlink_sock, &readfds); if (inotify_fd > 0) FD_SET(inotify_fd, &readfds); @@ -1009,7 +1013,7 @@ int main(int argc, char *argv[], char *envp[]) } /* get kernel netlink message */ - if ((uevent_netlink_sock > 0) && FD_ISSET(uevent_netlink_sock, &readfds)) { + if (FD_ISSET(uevent_netlink_sock, &readfds)) { msg = get_netlink_msg(); if (msg) { msg_queue_insert(msg); @@ -1096,5 +1100,5 @@ exit: logging_close(); - return 0; + return rc; } From 57d782bf1e8313e65579a8faa9671a8e5ffecb2f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 5 Nov 2005 16:22:14 +0100 Subject: [PATCH 1580/4284] log to console if syslog is not available Signed-off-by: Kay Sievers --- logging.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging.h b/logging.h index e0dcb80305..dd520dd874 100644 --- a/logging.h +++ b/logging.h @@ -61,7 +61,7 @@ extern void log_message(int priority, const char *format, ...) #undef logging_init static inline void logging_init(const char *program_name) { - openlog(program_name, LOG_PID, LOG_DAEMON); + openlog(program_name, LOG_PID | LOG_CONS, LOG_DAEMON); } #undef logging_close From 3904a7581776cffc7ddaf4adbfbea8a57ab1adaa Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 5 Nov 2005 19:41:00 +0100 Subject: [PATCH 1581/4284] udevd: disable OOM Signed-off-by: Kay Sievers --- udevd.c | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/udevd.c b/udevd.c index c49cf292cf..e2514e5947 100644 --- a/udevd.c +++ b/udevd.c @@ -814,7 +814,7 @@ static int init_uevent_netlink_sock(void) int main(int argc, char *argv[], char *envp[]) { int retval; - int devnull; + int fd; struct sigaction act; fd_set readfds; const char *value; @@ -824,20 +824,20 @@ int main(int argc, char *argv[], char *envp[]) int rc = 0; /* redirect std fd's, if the kernel 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); + fd = open("/dev/null", O_RDWR); + if (fd >= 0) { + if (fd != STDIN_FILENO) + dup2(fd, STDIN_FILENO); + if (fd != STDOUT_FILENO) + dup2(fd, STDOUT_FILENO); + if (fd != STDERR_FILENO) + dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + close(fd); } logging_init("udevd"); - if (devnull < 0) + if (fd < 0) err("fatal, could not open /dev/null"); udev_init_config(); @@ -889,13 +889,6 @@ int main(int argc, char *argv[], char *envp[]) switch (pid) { case 0: dbg("daemonized fork running"); - - /* become session leader */ - sid = setsid(); - dbg("our session is %d", sid); - - chdir("/"); - umask(umask(077) | 022); break; case -1: err("fork of daemon failed"); @@ -907,9 +900,25 @@ int main(int argc, char *argv[], char *envp[]) } } - /* set a reasonable scheduling priority for the daemon */ + /* set scheduling priority for the daemon */ setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); + chdir("/"); + umask(077); + + /* 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"); + else { + write(fd, "-17", 3); + close(fd); + } + /* setup signal handler pipe */ retval = pipe(signal_pipe); if (retval < 0) { From 287814b23cd564043391ce449f27e6ccd9d244e4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 5 Nov 2005 20:00:31 +0100 Subject: [PATCH 1582/4284] remove precompiled rules option It was a workaround for speed up udev "coldplug", where ~800 events happened a second time during bootup. No need for it with the rules aleady parsed in the daemon. Signed-off-by: Kay Sievers --- Makefile | 1 - udev.c | 2 +- udev_rules.h | 3 +- udev_rules_parse.c | 36 +---------------- udevd.c | 4 +- udevrulescompile.c | 97 ---------------------------------------------- udevstart.c | 2 +- udevtest.c | 2 +- 8 files changed, 8 insertions(+), 139 deletions(-) delete mode 100644 udevrulescompile.c diff --git a/Makefile b/Makefile index 8446eee924..4f6d3da983 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,6 @@ PROGRAMS = \ udev \ udevd \ udevsend \ - udevrulescompile \ udevinitsend \ udeveventrecorder \ udevcontrol \ diff --git a/udev.c b/udev.c index 926c4b526a..aab9f015fb 100644 --- a/udev.c +++ b/udev.c @@ -132,7 +132,7 @@ int main(int argc, char *argv[], char *envp[]) } udev_init_device(&udev, devpath, subsystem, action); - udev_rules_init(&rules, 1, 0); + udev_rules_init(&rules, 0); retval = udev_process_event(&rules, &udev); diff --git a/udev_rules.h b/udev_rules.h index be13378e4e..6d9d306ded 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -100,11 +100,10 @@ struct udev_rules { char *buf; size_t bufsize; size_t current; - int mapped; int resolve_names; }; -extern int udev_rules_init(struct udev_rules *rules, int read_compiled, int resolve_names); +extern int udev_rules_init(struct udev_rules *rules, int resolve_names); extern void udev_rules_close(struct udev_rules *rules); extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize, diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 7d1853acbe..6e978d74b4 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -591,42 +591,14 @@ static int parse_file(struct udev_rules *rules, const char *filename) return retval; } -static int rules_map(struct udev_rules *rules, const char *filename) +int udev_rules_init(struct udev_rules *rules, int resolve_names) { - if (file_map(filename, &rules->buf, &rules->bufsize)) { - rules->buf = NULL; - return -1; - } - if (rules->bufsize == 0) { - file_unmap(rules->buf, rules->bufsize); - rules->buf = NULL; - return -1; - } - rules->mapped = 1; - - return 0; -} - -int udev_rules_init(struct udev_rules *rules, int read_compiled, int resolve_names) -{ - char comp[PATH_SIZE]; struct stat stats; int retval; memset(rules, 0x00, sizeof(struct udev_rules)); rules->resolve_names = resolve_names; - /* check for precompiled rules */ - if (read_compiled) { - strlcpy(comp, udev_rules_filename, sizeof(comp)); - strlcat(comp, ".compiled", sizeof(comp)); - if (stat(comp, &stats) == 0) { - dbg("map compiled rules '%s'", comp); - if (rules_map(rules, comp) == 0) - return 0; - } - } - /* parse rules file or all matching files in directory */ if (stat(udev_rules_filename, &stats) != 0) return -1; @@ -660,11 +632,7 @@ int udev_rules_init(struct udev_rules *rules, int read_compiled, int resolve_nam void udev_rules_close(struct udev_rules *rules) { if (rules->buf) { - if (rules->mapped) { - rules->mapped = 0; - file_unmap(rules->buf, rules->bufsize); - } else - free(rules->buf); + free(rules->buf); rules->buf = NULL; } } diff --git a/udevd.c b/udevd.c index e2514e5947..154c370589 100644 --- a/udevd.c +++ b/udevd.c @@ -880,7 +880,7 @@ int main(int argc, char *argv[], char *envp[]) } /* parse the rules and keep it in memory */ - udev_rules_init(&rules, 0, 1); + udev_rules_init(&rules, 1); if (daemonize) { pid_t pid; @@ -1065,7 +1065,7 @@ int main(int argc, char *argv[], char *envp[]) if (reload_config) { reload_config = 0; udev_rules_close(&rules); - udev_rules_init(&rules, 0, 1); + udev_rules_init(&rules, 1); } /* forked child have returned */ diff --git a/udevrulescompile.c b/udevrulescompile.c deleted file mode 100644 index a2c5f2e9fc..0000000000 --- a/udevrulescompile.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * udevrulescompile.c - store already parsed config on disk - * - * 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. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "udev_libc_wrapper.h" -#include "udev_sysfs.h" -#include "udev.h" -#include "udev_version.h" -#include "logging.h" -#include "udev_rules.h" -#include "udev_utils.h" -#include "list.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 - -int main(int argc, char *argv[], char *envp[]) -{ - struct udev_rules rules; - FILE *f; - char comp[PATH_SIZE]; - char comp_tmp[PATH_SIZE]; - int retval = 0; - - logging_init("udevrulescompile"); - udev_init_config(); - dbg("version %s", UDEV_VERSION); - - strlcpy(comp, udev_rules_filename, sizeof(comp)); - strlcat(comp, ".compiled", sizeof(comp)); - strlcpy(comp_tmp, comp, sizeof(comp_tmp)); - strlcat(comp_tmp, ".tmp", sizeof(comp_tmp)); - - /* remove old version, otherwise we would read it instead of the real rules */ - unlink(comp); - unlink(comp_tmp); - - udev_rules_init(&rules, 0, 1); - - f = fopen(comp_tmp, "w"); - if (f == NULL) { - err("unable to create db file '%s'", comp_tmp); - unlink(comp_tmp); - retval = 1; - goto exit; - } - - dbg("storing compiled rules in '%s' size=%zi", comp_tmp, rules.bufsize); - fwrite(rules.buf, rules.bufsize, 1, f); - fclose(f); - - dbg("activating compiled rules in '%s'", comp); - if (rename(comp_tmp, comp) != 0) { - err("unable to write file"); - unlink(comp); - unlink(comp_tmp); - retval = 2; - } - -exit: - logging_close(); - return retval; -} diff --git a/udevstart.c b/udevstart.c index 057d59fcaa..8ee079dbe5 100644 --- a/udevstart.c +++ b/udevstart.c @@ -364,7 +364,7 @@ int main(int argc, char *argv[], char *envp[]) /* trigger timeout to prevent hanging processes */ alarm(UDEV_ALARM_TIMEOUT); - udev_rules_init(&rules, 0, 1); + udev_rules_init(&rules, 1); udev_scan_class(&device_list); udev_scan_block(&device_list); diff --git a/udevtest.c b/udevtest.c index 6e973e31e6..4890b6837c 100644 --- a/udevtest.c +++ b/udevtest.c @@ -92,7 +92,7 @@ int main(int argc, char *argv[], char *envp[]) info("looking at device '%s' from subsystem '%s'", devpath, subsystem); /* initialize the naming deamon */ - udev_rules_init(&rules, 0, 0); + udev_rules_init(&rules, 0); /* fill in values and test_run flag*/ udev_init_device(&udev, devpath, subsystem, "add"); From 31819a1e32fbd249264fbe089270d832b4987d39 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 5 Nov 2005 20:32:20 +0100 Subject: [PATCH 1583/4284] export DEVNAME on "remove" only if we really got a node to remove Signed-off-by: Kay Sievers --- udev_remove.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/udev_remove.c b/udev_remove.c index cff940ccfe..0d536bc8ff 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -112,6 +112,10 @@ static int delete_node(struct udevice *udev) if (retval) return retval; + /* export DEVNAME to the environment */ + snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); + udev->devname[sizeof(udev->devname)-1] = '\0'; + num = udev->partitions; if (num > 0) { info("removing all_partitions '%s[1-%i]'", filename, num); @@ -152,9 +156,6 @@ int udev_remove_device(struct udevice *udev) dbg("'%s' not found in database, using kernel name '%s'", udev->devpath, udev->kernel_name); strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); } - /* use full path to the environment */ - snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); - udev->devname[sizeof(udev->devname)-1] = '\0'; return delete_node(udev); } From 74adec7d97f463bfe441996b8997cdea213a087d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 5 Nov 2005 22:02:21 +0100 Subject: [PATCH 1584/4284] fix typo in umask() Signed-off-by: Kay Sievers --- udevd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevd.c b/udevd.c index 154c370589..64a6f4d002 100644 --- a/udevd.c +++ b/udevd.c @@ -904,7 +904,7 @@ int main(int argc, char *argv[], char *envp[]) setpriority(PRIO_PROCESS, 0, UDEVD_PRIORITY); chdir("/"); - umask(077); + umask(022); /* become session leader */ sid = setsid(); From 1ad45a47cae79a80bb9c9ff287dc46c18b2ddc71 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 5 Nov 2005 22:05:35 +0100 Subject: [PATCH 1585/4284] 072 release --- ChangeLog | 45 +++++++++++++++++++++++++++++++++++++++++++++ Makefile | 2 +- RELEASE-NOTES | 3 ++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index cc20111553..4964d782fd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,48 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 4f6d3da983..8d280acd48 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 071 +VERSION = 072 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 0cd11d6bb6..087403d56f 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -3,7 +3,8 @@ 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. +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 From 0b3dfb3d72e1df5f38ecb9669e37e5e77d958343 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 02:22:44 +0100 Subject: [PATCH 1586/4284] udevd: depend on netlink and remove all sequence reorder logic Netlink will never get out-of-order and we just depend on it from now on. Udevsend messages will have no effect if they contain a sequence number (SEQNUM). Thanks to Bastian Blank , for the debugging session which identified a bug where the timeouts are not working if inotify was not available. All the timeout handling is removed now and this issue should be solved. Signed-off-by: Kay Sievers --- Makefile | 1 - udev.h | 2 +- udevd.c | 185 ++++++----------------------------------------------- udevd.h | 9 +-- udevsend.c | 31 +-------- 5 files changed, 23 insertions(+), 205 deletions(-) diff --git a/Makefile b/Makefile index 8d280acd48..afa649e522 100644 --- a/Makefile +++ b/Makefile @@ -270,7 +270,6 @@ udev_version.h: @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ - @echo \#define UDEV_BIN \"$(sbindir)/udev\" >> $@ @echo \#define UDEVD_BIN \"$(sbindir)/udevd\" >> $@ # man pages diff --git a/udev.h b/udev.h index 66edfd66bf..ecc0a44f91 100644 --- a/udev.h +++ b/udev.h @@ -36,7 +36,7 @@ #define VALUE_SIZE 128 #define DEFAULT_PARTITIONS_COUNT 15 -#define UDEV_ALARM_TIMEOUT 120 +#define UDEV_ALARM_TIMEOUT 180 struct udev_rules; diff --git a/udevd.c b/udevd.c index 64a6f4d002..dcf5781812 100644 --- a/udevd.c +++ b/udevd.c @@ -31,16 +31,14 @@ #include #include #include +#include #include #include -#include #include #include #include -#include #include #include -#include #include #include "list.h" @@ -61,19 +59,14 @@ static pid_t sid; static int signal_pipe[2] = {-1, -1}; static volatile int sigchilds_waiting; -static volatile int run_msg_q; static volatile int udev_exit; static volatile int reload_config; -static int init_phase = 1; static int run_exec_q; static int stop_exec_q; -static int event_timeout; static int max_childs; static int max_childs_running; -static unsigned long long expected_seqnum; static char udev_log[32]; -static LIST_HEAD(msg_list); static LIST_HEAD(exec_list); static LIST_HEAD(running_list); @@ -92,14 +85,11 @@ void log_message(int priority, const char *format, ...) } #endif -static void msg_dump_queue(void) +static void msg_queue_insert(struct uevent_msg *msg) { -#ifdef DEBUG - struct uevent_msg *msg; - - list_for_each_entry(msg, &msg_list, node) - dbg("sequence %llu in queue", msg->seqnum); -#endif + list_add(&msg->node, &exec_list); + msg->queue_time = time(NULL); + run_exec_q = 1; } static void msg_queue_delete(struct uevent_msg *msg) @@ -108,53 +98,6 @@ static void msg_queue_delete(struct uevent_msg *msg) free(msg); } -/* orders the message in the queue by sequence number */ -static void msg_queue_insert(struct uevent_msg *msg) -{ - struct uevent_msg *loop_msg; - struct sysinfo info; - - if (msg->seqnum == 0) { - dbg("no SEQNUM, move straight to the exec queue"); - list_add_tail(&msg->node, &exec_list); - run_exec_q = 1; - return; - } - - /* store timestamp of queuing */ - sysinfo(&info); - msg->queue_time = info.uptime; - - /* with the first event we provide a phase of shorter timeout */ - if (init_phase) { - static long init_time; - - if (init_time == 0) - init_time = info.uptime; - if (info.uptime - init_time >= UDEVD_INIT_TIME) - init_phase = 0; - } - - /* sort message by sequence number into list */ - list_for_each_entry_reverse(loop_msg, &msg_list, node) { - if (loop_msg->seqnum < msg->seqnum) - break; - - if (loop_msg->seqnum == msg->seqnum) { - dbg("ignoring duplicate message seq %llu", msg->seqnum); - free(msg); - return; - } - } - list_add(&msg->node, &loop_msg->node); - info("seq %llu queued, '%s' '%s'", msg->seqnum, msg->action, msg->devpath); - - /* run msg queue manager */ - run_msg_q = 1; - - return; -} - static void asmlinkage udev_event_sig_handler(int signum) { if (signum == SIGALRM) @@ -205,7 +148,6 @@ static int udev_event_process(struct uevent_msg *msg) static void udev_event_run(struct uevent_msg *msg) { pid_t pid; - struct sysinfo info; pid = fork(); switch (pid) { @@ -232,9 +174,8 @@ static void udev_event_run(struct uevent_msg *msg) break; default: /* get SIGCHLD in main loop */ - sysinfo(&info); info("seq %llu forked, pid [%d], '%s' '%s', %ld seconds old", - msg->seqnum, pid, msg->action, msg->subsystem, info.uptime - msg->queue_time); + msg->seqnum, pid, msg->action, msg->subsystem, time(NULL) - msg->queue_time); msg->pid = pid; } } @@ -436,61 +377,6 @@ static void exec_queue_manager(void) } } -static void msg_move_exec(struct uevent_msg *msg) -{ - list_move_tail(&msg->node, &exec_list); - run_exec_q = 1; - expected_seqnum = msg->seqnum+1; - dbg("moved seq %llu to exec, next expected is %llu", - msg->seqnum, expected_seqnum); -} - -/* msg queue management routine handles the timeouts and dispatches the events */ -static void msg_queue_manager(void) -{ - struct uevent_msg *loop_msg; - struct uevent_msg *tmp_msg; - struct sysinfo info; - long msg_age = 0; - int timeout = event_timeout; - - dbg("msg queue manager, next expected is %llu", expected_seqnum); -recheck: - sysinfo(&info); - list_for_each_entry_safe(loop_msg, tmp_msg, &msg_list, node) { - /* move event with expected sequence to the exec list */ - if (loop_msg->seqnum == expected_seqnum) { - msg_move_exec(loop_msg); - continue; - } - - /* limit timeout during initialization phase */ - if (init_phase) { - if (timeout > UDEVD_INIT_EVENT_TIMEOUT) - timeout = UDEVD_INIT_EVENT_TIMEOUT; - dbg("initialization phase, timeout %i seconds", timeout); - } - - /* move event with expired timeout to the exec list */ - msg_age = info.uptime - loop_msg->queue_time; - dbg("seq %llu is %li seconds old", loop_msg->seqnum, msg_age); - if (msg_age >= timeout) { - msg_move_exec(loop_msg); - goto recheck; - } else - break; - } - - msg_dump_queue(); - - /* set timeout for remaining queued events */ - if (!list_empty(&msg_list)) { - struct itimerval itv = {{0, 0}, {timeout - msg_age, 0}}; - info("next event expires in %li seconds", timeout - msg_age); - setitimer(ITIMER_REAL, &itv, NULL); - } -} - static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) { int bufpos; @@ -691,10 +577,6 @@ static void asmlinkage sig_handler(int signum) case SIGTERM: udev_exit = 1; break; - case SIGALRM: - /* set flag, then write to pipe if needed */ - run_msg_q = 1; - break; case SIGCHLD: /* set flag, then write to pipe if needed */ sigchilds_waiting = 1; @@ -712,13 +594,11 @@ static void udev_done(int pid) { /* find msg associated with pid and delete it */ struct uevent_msg *msg; - struct sysinfo info; list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { - sysinfo(&info); if (msg->queue_time) - info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, info.uptime - msg->queue_time); + info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, time(NULL) - msg->queue_time); else info("seq 0, pid [%d] exit", msg->pid); msg_queue_delete(msg); @@ -818,10 +698,10 @@ int main(int argc, char *argv[], char *envp[]) struct sigaction act; fd_set readfds; const char *value; - int uevent_netlink_active = 0; int daemonize = 0; int i; int rc = 0; + int maxfd; /* redirect std fd's, if the kernel forks us, we don't have them at all */ fd = open("/dev/null", O_RDWR); @@ -943,7 +823,6 @@ int main(int argc, char *argv[], char *envp[]) act.sa_flags = SA_RESTART; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); - sigaction(SIGALRM, &act, NULL); sigaction(SIGCHLD, &act, NULL); sigaction(SIGHUP, &act, NULL); @@ -952,21 +831,6 @@ int main(int argc, char *argv[], char *envp[]) if (inotify_fd > 0) inotify_add_watch(inotify_fd, udev_rules_filename, IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE); - /* init of expected_seqnum value */ - value = getenv("UDEVD_EXPECTED_SEQNUM"); - if (value) { - expected_seqnum = strtoull(value, NULL, 10); - info("initialize expected_seqnum to %llu", expected_seqnum); - } - - /* timeout to wait for missing events */ - value = getenv("UDEVD_EVENT_TIMEOUT"); - if (value) - event_timeout = strtoul(value, NULL, 10); - else - event_timeout = UDEVD_EVENT_TIMEOUT; - info("initialize event_timeout to %u", event_timeout); - /* maximum limit of forked childs */ value = getenv("UDEVD_MAX_CHILDS"); if (value) @@ -990,6 +854,11 @@ int main(int argc, char *argv[], char *envp[]) sprintf(udev_log, "UDEV_LOG=%i", udev_log_priority); putenv(udev_log); + 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 uevent_msg *msg; int fdcount; @@ -1001,7 +870,7 @@ int main(int argc, char *argv[], char *envp[]) if (inotify_fd > 0) FD_SET(inotify_fd, &readfds); - fdcount = select(UDEV_MAX(uevent_netlink_sock, inotify_fd)+1, &readfds, NULL, NULL, NULL); + fdcount = select(maxfd+1, &readfds, NULL, NULL, NULL); if (fdcount < 0) { if (errno != EINTR) dbg("error in select: %s", strerror(errno)); @@ -1012,9 +881,8 @@ int main(int argc, char *argv[], char *envp[]) if (FD_ISSET(udevd_sock, &readfds)) { msg = get_udevd_msg(); if (msg) { - /* discard kernel messages if netlink is active */ - if (uevent_netlink_active && msg->type == UDEVD_UEVENT_UDEVSEND && msg->seqnum != 0) { - info("skip uevent_helper message with SEQNUM, netlink is active"); + if (msg->type == UDEVD_UEVENT_UDEVSEND && msg->seqnum != 0) { + info("skip non-kernel message with SEQNUM"); free(msg); } else msg_queue_insert(msg); @@ -1024,14 +892,8 @@ int main(int argc, char *argv[], char *envp[]) /* get kernel netlink message */ if (FD_ISSET(uevent_netlink_sock, &readfds)) { msg = get_netlink_msg(); - if (msg) { + if (msg) msg_queue_insert(msg); - /* disable udevsend with first netlink message */ - if (!uevent_netlink_active) { - info("uevent_nl message received, disable udevsend messages"); - uevent_netlink_active = 1; - } - } } /* received a signal, clear our notification pipe */ @@ -1068,24 +930,13 @@ int main(int argc, char *argv[], char *envp[]) udev_rules_init(&rules, 1); } - /* forked child have returned */ + /* forked child has returned */ if (sigchilds_waiting) { sigchilds_waiting = 0; reap_sigchilds(); } - if (run_msg_q) { - run_msg_q = 0; - msg_queue_manager(); - } - if (run_exec_q) { - /* clean up running_list before calling exec_queue_manager() */ - if (sigchilds_waiting) { - sigchilds_waiting = 0; - reap_sigchilds(); - } - run_exec_q = 0; if (!stop_exec_q) exec_queue_manager(); diff --git a/udevd.h b/udevd.h index db510ab24a..884c4b0074 100644 --- a/udevd.h +++ b/udevd.h @@ -29,13 +29,6 @@ #define UDEVD_PRIORITY -4 #define UDEV_PRIORITY -2 -/* duration of initialization phase with shorter timeout */ -#define UDEVD_INIT_TIME 5 -#define UDEVD_INIT_EVENT_TIMEOUT 2 - -/* timeout to wait for missing events */ -#define UDEVD_EVENT_TIMEOUT 5 - /* maximum limit of runnig childs */ #define UDEVD_MAX_CHILDS 64 /* start to throttle forking if maximum number of running childs in our session is reached */ @@ -68,7 +61,7 @@ struct uevent_msg { enum udevd_msg_type type; struct list_head node; pid_t pid; - long queue_time; + time_t queue_time; char *action; char *devpath; char *subsystem; diff --git a/udevsend.c b/udevsend.c index 0ba1b58a4b..29d5bc155e 100644 --- a/udevsend.c +++ b/udevsend.c @@ -89,27 +89,6 @@ static int start_daemon(void) return 0; } -static void run_udev(const char *subsystem) -{ - char *const argv[] = { "udev", (char *)subsystem, NULL }; - pid_t pid; - - pid = fork(); - switch (pid) { - case 0: - /* child */ - execv(UDEV_BIN, argv); - err("exec of udev child failed"); - _exit(1); - break; - case -1: - err("fork of udev child failed"); - break; - default: - waitpid(pid, NULL, 0); - } -} - int main(int argc, char *argv[], char *envp[]) { static struct udevd_msg usend_msg; @@ -132,7 +111,7 @@ int main(int argc, char *argv[], char *envp[]) sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { err("error getting socket"); - goto fallback; + goto exit; } memset(&saddr, 0x00, sizeof(struct sockaddr_un)); @@ -192,7 +171,7 @@ int main(int argc, char *argv[], char *envp[]) if (errno != ECONNREFUSED) { err("error sending message (%s)", strerror(errno)); - goto fallback; + goto exit; } if (!started_daemon) { @@ -200,7 +179,7 @@ int main(int argc, char *argv[], char *envp[]) retval = start_daemon(); if (retval) { dbg("error starting daemon"); - goto fallback; + goto exit; } dbg("udevd daemon started"); started_daemon = 1; @@ -210,10 +189,6 @@ int main(int argc, char *argv[], char *envp[]) } } -fallback: - err("unable to connect to event daemon, try to call udev directly"); - run_udev(subsystem); - exit: if (sock != -1) close(sock); From 38ff77b80ba400ab059b6a215092bf25a3085b2e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 02:23:06 +0100 Subject: [PATCH 1587/4284] print useconds in udevmonitor Signed-off-by: Kay Sievers --- udevmonitor.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/udevmonitor.c b/udevmonitor.c index 382cbb1905..dc04649745 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -23,13 +23,12 @@ #include #include #include -#include #include #include +#include #include #include #include -#include #include #include "udev.h" @@ -160,6 +159,9 @@ int main(int argc, char *argv[]) static char buf[UEVENT_BUFFER_SIZE*2]; ssize_t buflen; int fdcount; + struct timeval tv; + struct timezone tz; + char timestr[64]; buflen = 0; FD_ZERO(&readfds); @@ -175,13 +177,19 @@ int main(int argc, char *argv[]) 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\n"); continue; } - printf("UEVENT[%llu] %s\n", (unsigned long long) time(NULL), buf); + printf("UEVENT[%s] %s\n", timestr, buf); } if ((udev_monitor_sock > 0) && FD_ISSET(udev_monitor_sock, &readfds)) { @@ -190,7 +198,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "error receiving udev message\n"); continue; } - printf("UDEV [%llu] %s\n", (unsigned long long) time(NULL), buf); + printf("UDEV [%s] %s\n", timestr, buf); } if (buflen == 0) From 9092f7edcf12f7b2dc77e56a6a5f688ef81ef000 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 02:40:09 +0100 Subject: [PATCH 1588/4284] add .gitignore Signed-off-by: Kay Sievers --- .gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..c37b70c524 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.o +*.a +ccdv +udev +udevd +udevcontrol +udevsend +udevinfo +udevmonitor +udevstart +udevtest +udev_version.h + From 8f528042ca780a6f772dd8f9b4a1427f2407a264 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 02:44:34 +0100 Subject: [PATCH 1589/4284] 073 release --- ChangeLog | 9 +++++++++ Makefile | 2 +- RELEASE-NOTES | 6 ++++++ TODO | 11 ++--------- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4964d782fd..2a81a68166 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +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 ============================================ diff --git a/Makefile b/Makefile index afa649e522..9050933214 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 072 +VERSION = 073 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 087403d56f..8e9416d921 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,9 @@ +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 diff --git a/TODO b/TODO index a992547377..0bf22dd580 100644 --- a/TODO +++ b/TODO @@ -1,19 +1,12 @@ This is a short list of things that needs to be done. They are in no specific order. We will gladly accept patches for any of these items: -- More documentation: - Allmost all extras/*_id/ programs don't have a man page - some details are missing in the udev man pages. - - Completely replace the built-in wait_for_sysfs stuff in udev_sysfs.c by rules using the WAIT_FOR_SYSFS key. - Log the relationship of the kernel name and the persistent disk name to syslog, so any error logged from the kernel can be associated with - any of the links. + any of the links at that time. -- Do generic early boot logic: - initramfs, pivot-root, cover coldplug or event replay, etc... - -- Keep the distro rules in etc/ up-to-date. +- remove klibc tree and make it an external dependency From fc465079caefbbfb838019e3c2b86ffa3e889efa Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 14:10:09 +0100 Subject: [PATCH 1590/4284] never queue events with TIMEOUT set With removing the event reorder queue, we can fix the TIMEOUT events like firmware loading proper, and never delay any of these events. Signed-off-by: Kay Sievers --- udevd.c | 77 ++++++++++++++++++++++++++++----------------------------- udevd.h | 2 +- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/udevd.c b/udevd.c index dcf5781812..ddf72738c3 100644 --- a/udevd.c +++ b/udevd.c @@ -50,7 +50,6 @@ #include "udevd.h" #include "logging.h" -/* global variables*/ struct udev_rules rules; static int udevd_sock; static int uevent_netlink_sock; @@ -85,19 +84,6 @@ void log_message(int priority, const char *format, ...) } #endif -static void msg_queue_insert(struct uevent_msg *msg) -{ - list_add(&msg->node, &exec_list); - msg->queue_time = time(NULL); - run_exec_q = 1; -} - -static void msg_queue_delete(struct uevent_msg *msg) -{ - list_del(&msg->node); - free(msg); -} - static void asmlinkage udev_event_sig_handler(int signum) { if (signum == SIGALRM) @@ -144,7 +130,12 @@ static int udev_event_process(struct uevent_msg *msg) return 0; } -/* runs event and removes event from run queue when finished */ +static void msg_queue_delete(struct uevent_msg *msg) +{ + list_del(&msg->node); + free(msg); +} + static void udev_event_run(struct uevent_msg *msg) { pid_t pid; @@ -180,6 +171,22 @@ static void udev_event_run(struct uevent_msg *msg) } } +static void msg_queue_insert(struct uevent_msg *msg) +{ + msg->queue_time = time(NULL); + + /* 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; +} + +/* runs event and removes event from run queue when finished */ static int running_processes(void) { int f; @@ -308,10 +315,6 @@ static int running_with_devpath(struct uevent_msg *msg, int limit) if (msg->devpath == NULL) return 0; - /* skip any events with a timeout set */ - if (msg->timeout != 0) - return 0; - list_for_each_entry(loop_msg, &running_list, node) { if (limit && childs_count++ > limit) { dbg("%llu, maximum number (%i) of child reached", msg->seqnum, childs_count); @@ -340,7 +343,7 @@ static int running_with_devpath(struct uevent_msg *msg, int limit) } /* exec queue management routine executes the events and serializes events in the same sequence */ -static void exec_queue_manager(void) +static void msg_queue_manager(void) { struct uevent_msg *loop_msg; struct uevent_msg *tmp_msg; @@ -360,20 +363,22 @@ static void exec_queue_manager(void) 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, cause too many processes already running", - loop_msg->seqnum); + dbg("delay seq %llu, too many processes already running", loop_msg->seqnum); return; } } - if (running_with_devpath(loop_msg, max_childs) == 0) { - /* 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); - } else + /* don't run two processes for the same devpath and wait for the parent*/ + if (running_with_devpath(loop_msg, max_childs)) { 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); } } @@ -494,7 +499,7 @@ static struct uevent_msg *get_udevd_msg(void) case UDEVD_START_EXEC_QUEUE: info("udevd message (START_EXEC_QUEUE) received"); stop_exec_q = 0; - exec_queue_manager(); + msg_queue_manager(); break; case UDEVD_SET_LOG_LEVEL: intval = (int *) usend_msg.envbuf; @@ -597,16 +602,10 @@ static void udev_done(int pid) list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { - if (msg->queue_time) - info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, time(NULL) - msg->queue_time); - else - info("seq 0, pid [%d] exit", msg->pid); + info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, time(NULL) - msg->queue_time); msg_queue_delete(msg); - /* we want to run the exec queue manager since there may - * be events waiting with the devpath of the one that - * just finished - */ + /* there may be events waiting with the same devpath */ run_exec_q = 1; return; } @@ -939,7 +938,7 @@ int main(int argc, char *argv[], char *envp[]) if (run_exec_q) { run_exec_q = 0; if (!stop_exec_q) - exec_queue_manager(); + msg_queue_manager(); } } diff --git a/udevd.h b/udevd.h index 884c4b0074..91c8e6503d 100644 --- a/udevd.h +++ b/udevd.h @@ -32,7 +32,7 @@ /* maximum limit of runnig childs */ #define UDEVD_MAX_CHILDS 64 /* start to throttle forking if maximum number of running childs in our session is reached */ -#define UDEVD_MAX_CHILDS_RUNNING 8 +#define UDEVD_MAX_CHILDS_RUNNING 16 /* environment buffer, should match the kernel's size in lib/kobject_uevent.h */ #define UEVENT_BUFFER_SIZE 1024 From 271c2d7d26132858a3302208dfe1572aa9cbbd12 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 16:00:41 +0100 Subject: [PATCH 1591/4284] let NAME="" supress node creation, but do RUN keys Signed-off-by: Kay Sievers --- udev_event.c | 9 ++++----- udev_rules_parse.c | 9 +++------ 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/udev_event.c b/udev_event.c index fae5a46597..b50fbf4c1d 100644 --- a/udev_event.c +++ b/udev_event.c @@ -73,13 +73,12 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) sysfs_close_class_device(class_dev); return -1; } - if (udev->name[0] == '\0') { + if (udev->name[0] != '\0') { + /* create node, store in db */ + retval = udev_add_device(udev, class_dev); + } else { info("device node creation supressed"); - sysfs_close_class_device(class_dev); - return -1; } - /* create node, store in db */ - retval = udev_add_device(udev, class_dev); } else { dbg("no dev-file found"); udev_rules_get_run(rules, udev, class_dev, NULL); diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 6e978d74b4..9041c383e0 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -413,12 +413,9 @@ static int add_to_rules(struct udev_rules *rules, char *line) rule->ignore_remove = 1; } } - if (value[0] == '\0') { - dbg("name empty device should be ignored"); - rule->name.operation = operation; - rule->ignore_device = 1; - } else - add_rule_key(rule, &rule->name, operation, value); + if (value[0] == '\0') + dbg("name empty, not creation supressed"); + add_rule_key(rule, &rule->name, operation, value); continue; } From e07a3d79bad70ea132435c8a44737ac270b0f9e3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 17:14:38 +0100 Subject: [PATCH 1592/4284] remove udevinitsend Signed-off-by: Kay Sievers --- Makefile | 2 - udevinitsend.c | 241 ------------------------------------------------- 2 files changed, 243 deletions(-) delete mode 100644 udevinitsend.c diff --git a/Makefile b/Makefile index 9050933214..bcaf30b706 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,6 @@ PROGRAMS = \ udev \ udevd \ udevsend \ - udevinitsend \ udeveventrecorder \ udevcontrol \ udevmonitor \ @@ -375,7 +374,6 @@ uninstall-bin: - rm -f $(DESTDIR)$(sbindir)/udev - rm -f $(DESTDIR)$(sbindir)/udevd - rm -f $(DESTDIR)$(sbindir)/udevsend - - rm -f $(DESTDIR)$(sbindir)/udevinitsend - rm -f $(DESTDIR)$(sbindir)/udeveventrecoreder - rm -f $(DESTDIR)$(sbindir)/udevcontrol - rm -f $(DESTDIR)$(sbindir)/udevstart diff --git a/udevinitsend.c b/udevinitsend.c deleted file mode 100644 index 4f50da8f68..0000000000 --- a/udevinitsend.c +++ /dev/null @@ -1,241 +0,0 @@ -/* - * udevinitsend.c - * - * Copyright (C) 2004, 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. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "udev.h" -#include "udev_version.h" -#include "udevd.h" -#include "udev_utils.h" -#include "logging.h" - -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 - -/* - * udevsend - * - * Scan a file, write all variables into the msgbuf and - * fires the message to udevd. - */ -static int udevsend(char *filename, int sock, int disable_loop_detection) -{ - static struct udevd_msg usend_msg; - int usend_msg_len; - int bufpos = 0; - struct stat statbuf; - int fd; - char *fdmap, *ls, *le, *ch; - struct sockaddr_un saddr; - socklen_t addrlen; - int retval = 0; - - if (stat(filename,&statbuf) < 0) { - dbg("cannot stat %s: %s\n", filename, strerror(errno)); - return 1; - } - fd = open(filename,O_RDONLY); - if (fd < 0) - return 1; - - fdmap = mmap(0, statbuf.st_size, - PROT_READ, MAP_PRIVATE, fd, 0); - close(fd); - if (fdmap == MAP_FAILED) { - dbg("mmap failed, errno %d\n", errno); - return 1; - } - - memset(&saddr, 0x00, sizeof(struct sockaddr_un)); - saddr.sun_family = AF_LOCAL; - /* use abstract namespace for socket path */ - strcpy(&saddr.sun_path[1], UDEVD_SOCK_PATH); - addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; - - memset(&usend_msg, 0x00, sizeof(struct udevd_msg)); - strcpy(usend_msg.magic, UDEV_MAGIC); - usend_msg.type = UDEVD_UEVENT_INITSEND; - - ls = fdmap; - ch = le = ls; - while (*ch && ch < fdmap + statbuf.st_size) { - le = strchr(ch, '\n'); - if (!le) - break; - ch = strchr(ch, '='); - if (!ch) - break; - - /* prevent loops in the scripts we execute */ - if (strncmp(ls, "UDEVD_EVENT=", 12) == 0) { - if (!disable_loop_detection) { - dbg("event already handled by udev\n"); - retval = -1; - break; - } - goto loop_end; - } - - /* omit shell-generated keys */ - if (ls[0] == '_' && ls[1] == '=') { - goto loop_end; - } - - if (ch < le) { - strncpy(&usend_msg.envbuf[bufpos],ls,(ch - ls) + 1); - bufpos += (ch - ls) + 1; - if (ch[1] == '\'' && le[-1] == '\'') { - strncpy(&usend_msg.envbuf[bufpos],ch + 2, (le - ch) - 3); - bufpos += (le - ch) - 3; - } else { - strncpy(&usend_msg.envbuf[bufpos],ch + 1, (le - ch) - 1); - bufpos += (le - ch) - 1; - } - bufpos++; - } -loop_end: - ch = le + 1; - ls = ch; - } - munmap(fdmap, statbuf.st_size); - - usend_msg_len = offsetof(struct udevd_msg, envbuf) + bufpos; - dbg("usend_msg_len=%i", usend_msg_len); - - if (!retval) { - retval = sendto(sock, &usend_msg, usend_msg_len, 0, (struct sockaddr *)&saddr, addrlen); - if (retval < 0) { - dbg("error sending message (%s)", strerror(errno)); - retval = -1; - } - } - - return retval; -} - -int main(int argc, char *argv[], char *envp[]) -{ - static const char short_options[] = "d:f:lVh"; - int option; - char *event_dir = NULL; - char *event_file = NULL; - DIR *dirstream; - struct dirent *direntry; - int retval = 0; - int disable_loop_detection = 0; - int sock; - const char *env; - - env = getenv("UDEV_LOG"); - if (env) - udev_log = log_priority(env); - - logging_init("udevinitsend"); - dbg("version %s", UDEV_VERSION); - - /* get command line options */ - while (1) { - option = getopt(argc, argv, short_options); - if (option == -1) - break; - - dbg("option '%c': ", option); - switch (option) { - case 'd': - dbg("scan directory %s\n", optarg); - event_dir = optarg; - break; - - case 'f': - dbg("use event file %s\n", optarg); - event_file = optarg; - break; - - case 'l': - dbg("disable loop detection, ignore UDEVD_EVENT\n"); - disable_loop_detection = 1; - break; - - case 'h': - retval = 0; - } - } - - sock = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (sock == -1) { - dbg("error getting socket"); - return 1; - } - - if (event_dir) { - dirstream = opendir(event_dir); - if (!dirstream) { - info("error opening directory %s: %s\n", - event_dir, strerror(errno)); - return 2; - } - chdir(event_dir); - while ((direntry = readdir(dirstream)) != NULL) { - if (!strcmp(direntry->d_name,".") || - !strcmp(direntry->d_name,"..")) - continue; - retval = udevsend(direntry->d_name, sock, disable_loop_detection); - } - closedir(dirstream); - } else if (event_file) { - retval = udevsend(event_file, sock, disable_loop_detection); - } - - if (sock != -1) - close(sock); - - if (retval) - return 3; - return 0; -} From b6d474506f8935084e423f78035ea7206d4c3da0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 17:16:33 +0100 Subject: [PATCH 1593/4284] update .gitignore Signed-off-by: Kay Sievers --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c37b70c524..a83700c930 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,6 @@ udevinfo udevmonitor udevstart udevtest +udeveventrecorder udev_version.h From ff3e4bed21aaff673284f2e024da26c1e39cfda6 Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Mon, 7 Nov 2005 18:44:18 +0100 Subject: [PATCH 1594/4284] add strerror() to error logs --- udev.c | 2 +- udev_add.c | 14 +++++++------- udev_config.c | 2 +- udev_db.c | 10 +++++----- udev_libc_wrapper.c | 2 +- udev_remove.c | 7 +++---- udev_rules.c | 2 +- udev_rules_parse.c | 2 +- udev_selinux.c | 6 +++--- udev_utils.c | 2 +- udev_utils_file.c | 6 +++--- udev_utils_run.c | 12 ++++++------ udevcontrol.c | 4 ++-- udevd.c | 20 ++++++++++---------- udeveventrecorder.c | 2 +- udevmonitor.c | 14 +++++++------- udevsend.c | 10 +++++----- 17 files changed, 58 insertions(+), 59 deletions(-) diff --git a/udev.c b/udev.c index aab9f015fb..17867180c7 100644 --- a/udev.c +++ b/udev.c @@ -95,7 +95,7 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udev"); if (devnull < 0) - err("fatal, could not open /dev/null"); + err("fatal, could not open /dev/null: %s", strerror(errno)); udev_init_config(); dbg("version %s", UDEV_VERSION); diff --git a/udev_add.c b/udev_add.c index 9420b4fe14..a811b5a17c 100644 --- a/udev_add.c +++ b/udev_add.c @@ -73,7 +73,7 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo } if (unlink(file) != 0) - dbg("unlink(%s) failed with error '%s'", file, strerror(errno)); + dbg("unlink(%s) failed: %s", file, strerror(errno)); else dbg("already present file '%s' unlinked", file); @@ -82,7 +82,7 @@ create: retval = mknod(file, mode, devt); selinux_resetfscreatecon(); if (retval != 0) { - err("mknod(%s, %#o, %u, %u) failed with error '%s'", + err("mknod(%s, %#o, %u, %u) failed: %s", file, mode, major(devt), minor(devt), strerror(errno)); goto exit; } @@ -90,14 +90,14 @@ create: perms: dbg("chmod(%s, %#o)", file, mode); if (chmod(file, mode) != 0) { - dbg("chmod(%s, %#o) failed with error '%s'", file, mode, strerror(errno)); + dbg("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) { - dbg("chown(%s, %u, %u) failed with error '%s'", + dbg("chown(%s, %u, %u) failed: %s", file, uid, gid, strerror(errno)); goto exit; } @@ -222,7 +222,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de retval = symlink(linktarget, filename); selinux_resetfscreatecon(); if (retval != 0) - dbg("symlink(%s, %s) failed with error '%s'", + dbg("symlink(%s, %s) failed: %s", linktarget, filename, strerror(errno)); } } @@ -244,7 +244,7 @@ static int rename_net_if(struct udevice *udev) sk = socket(PF_INET, SOCK_DGRAM, 0); if (sk < 0) { - dbg("error opening socket"); + dbg("error opening socket: %s", strerror(errno)); return -1; } @@ -254,7 +254,7 @@ static int rename_net_if(struct udevice *udev) retval = ioctl(sk, SIOCSIFNAME, &ifr); if (retval != 0) - dbg("error changing net interface name"); + dbg("error changing net interface name: %s", strerror(errno)); close(sk); return retval; diff --git a/udev_config.c b/udev_config.c index b8c4ffc8ed..192a0b80d2 100644 --- a/udev_config.c +++ b/udev_config.c @@ -107,7 +107,7 @@ static int parse_config_file(void) int retval = 0; if (file_map(udev_config_filename, &buf, &bufsize) != 0) { - err("can't open '%s' as config file", udev_config_filename); + err("can't open '%s' as config file: %s", udev_config_filename, strerror(errno)); return -ENODEV; } diff --git a/udev_db.c b/udev_db.c index bf369ac2e6..f00308bd2f 100644 --- a/udev_db.c +++ b/udev_db.c @@ -95,7 +95,7 @@ int udev_db_add_device(struct udevice *udev) create_path(filename); f = fopen(filename, "w"); if (f == NULL) { - err("unable to create db file '%s'", filename); + err("unable to create db file '%s': %s", filename, strerror(errno)); return -1; } dbg("storing data for device '%s' in '%s'", udev->devpath, filename); @@ -129,7 +129,7 @@ int udev_db_get_device(struct udevice *udev, const char *devpath) devpath_to_db_path(devpath, filename, sizeof(filename)); if (file_map(filename, &buf, &bufsize) != 0) { - dbg("no db file to read '%s'", filename); + dbg("no db file to read %s: %s", filename, strerror(errno)); return -1; } @@ -210,7 +210,7 @@ int udev_db_lookup_name(const char *name, char *devpath, size_t len) dir = opendir(udev_db_path); if (dir == NULL) { - err("unable to open udev_db '%s'", udev_db_path); + err("unable to open udev_db '%s': %s", udev_db_path, strerror(errno)); return -1; } @@ -235,7 +235,7 @@ int udev_db_lookup_name(const char *name, char *devpath, size_t len) dbg("looking at '%s'", filename); if (file_map(filename, &buf, &bufsize) != 0) { - err("unable to read db file '%s'", filename); + err("unable to read db file '%s': %s", filename, strerror(errno)); continue; } @@ -278,7 +278,7 @@ int udev_db_get_all_entries(struct list_head *name_list) dir = opendir(udev_db_path); if (dir == NULL) { - err("unable to open udev_db '%s'", udev_db_path); + err("unable to open udev_db '%s': %s", udev_db_path, strerror(errno)); return -1; } diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index 4e9f9f1fe8..a7a8c5342d 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -144,7 +144,7 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) char *tail; if (file_map(dbfile, &buf, &bufsize) != 0) { - dbg("can't open '%s' as db file", dbfile); + dbg("can't open '%s' as db file: %s", dbfile, strerror(errno)); return 0; } dbg("search '%s' in '%s'", uname, dbfile); diff --git a/udev_remove.c b/udev_remove.c index 0d536bc8ff..621fcc1960 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -56,8 +56,7 @@ static int delete_path(const char *path) if (retval) { if (errno == ENOTEMPTY) return 0; - dbg("rmdir(%s) failed with error '%s'", - path, strerror(errno)); + dbg("rmdir(%s) failed: %s", path, strerror(errno)); break; } dbg("removed '%s'", path); @@ -153,8 +152,8 @@ int udev_remove_device(struct udevice *udev) dbg("remove name='%s'", udev->name); udev_db_delete_device(udev); } else { - dbg("'%s' not found in database, using kernel name '%s'", udev->devpath, udev->kernel_name); - strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); + dbg("'%s' not found in database, don't remove anything", udev->devpath); + return -1; } return delete_node(udev); diff --git a/udev_rules.c b/udev_rules.c index ad3629d39d..137ad27dba 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -208,7 +208,7 @@ static int import_file_into_env(struct udevice *udev, const char *filename) size_t bufsize; if (file_map(filename, &buf, &bufsize) != 0) { - err("can't open '%s'", filename); + err("can't open '%s': %s", filename, strerror(errno)); return -1; } import_keys_into_env(udev, buf, bufsize); diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 9041c383e0..b664b983fb 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -538,7 +538,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) int retval = 0; if (file_map(filename, &buf, &bufsize) != 0) { - err("can't open '%s' as rules file", filename); + err("can't open '%s' as rules file: %s", filename, strerror(errno)); return -1; } dbg("reading '%s' as rules file", filename); diff --git a/udev_selinux.c b/udev_selinux.c index cc6f4d7d3f..719ff6403e 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -105,7 +105,7 @@ void selinux_setfilecon(const char *file, const char *devname, unsigned int mode } if (setfilecon(file, scontext) < 0) - dbg("setfilecon %s failed with error '%s'", file, strerror(errno)); + dbg("setfilecon %s failed: %s", file, strerror(errno)); freecon(scontext); } @@ -131,7 +131,7 @@ void selinux_setfscreatecon(const char *file, const char *devname, unsigned int } if (setfscreatecon(scontext) < 0) - dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); + dbg("setfscreatecon %s failed: %s", file, strerror(errno)); freecon(scontext); } @@ -141,7 +141,7 @@ void selinux_resetfscreatecon(void) { if (is_selinux_running()) { if (setfscreatecon(prev_scontext) < 0) - dbg("setfscreatecon %s failed with error '%s'", file, strerror(errno)); + dbg("setfscreatecon failed: %s", strerror(errno)); } } diff --git a/udev_utils.c b/udev_utils.c index 683378aadf..04258a39c2 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -139,7 +139,7 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c dbg("open directory '%s'", dirname); dir = opendir(dirname); if (dir == NULL) { - dbg("unable to open '%s'", dirname); + dbg("unable to open '%s': %s", dirname, strerror(errno)); return -1; } diff --git a/udev_utils_file.c b/udev_utils_file.c index f8518f64ad..23f61196b7 100644 --- a/udev_utils_file.c +++ b/udev_utils_file.c @@ -72,18 +72,18 @@ int unlink_secure(const char *filename) retval = chown(filename, 0, 0); if (retval) - dbg("chown(%s, 0, 0) failed with error '%s'", filename, strerror(errno)); + dbg("chown(%s, 0, 0) failed: %s", filename, strerror(errno)); retval = chmod(filename, 0000); if (retval) - dbg("chmod(%s, 0000) failed with error '%s'", filename, strerror(errno)); + dbg("chmod(%s, 0000) failed: %s", filename, strerror(errno)); retval = unlink(filename); if (errno == ENOENT) retval = 0; if (retval) - dbg("unlink(%s) failed with error '%s'", filename, strerror(errno)); + dbg("unlink(%s) failed: %s", filename, strerror(errno)); return retval; } diff --git a/udev_utils_run.c b/udev_utils_run.c index 1315154c26..20aaa4ab05 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -115,13 +115,13 @@ int run_program(const char *command, const char *subsystem, /* prepare pipes from child to parent */ if (result || log) { if (pipe(outpipe) != 0) { - err("pipe failed"); + err("pipe failed: %s", strerror(errno)); return -1; } } if (log) { if (pipe(errpipe) != 0) { - err("pipe failed"); + err("pipe failed: %s", strerror(errno)); return -1; } } @@ -145,7 +145,7 @@ int run_program(const char *command, const char *subsystem, dup2(devnull, STDERR_FILENO); close(devnull); } else - err("open /dev/null failed"); + err("open /dev/null failed: %s", strerror(errno)); if (outpipe[WRITE_END] > 0) dup2(outpipe[WRITE_END], STDOUT_FILENO); if (errpipe[WRITE_END] > 0) @@ -156,7 +156,7 @@ int run_program(const char *command, const char *subsystem, err("exec of program '%s' failed", argv[0]); _exit(1); case -1: - err("fork of '%s' failed", argv[0]); + err("fork of '%s' failed: %s", argv[0], strerror(errno)); return -1; default: /* read from child if requested */ @@ -199,7 +199,7 @@ int run_program(const char *command, const char *subsystem, close(outpipe[READ_END]); outpipe[READ_END] = -1; if (count < 0) { - err("stdin read failed with '%s'", strerror(errno)); + err("stdin read failed: %s", strerror(errno)); retval = -1; } continue; @@ -233,7 +233,7 @@ int run_program(const char *command, const char *subsystem, close(errpipe[READ_END]); errpipe[READ_END] = -1; if (count < 0) - err("stderr read failed with '%s'", strerror(errno)); + err("stderr read failed: %s", strerror(errno)); continue; } errbuf[count] = '\0'; diff --git a/udevcontrol.c b/udevcontrol.c index 00b435edc4..bd6563531d 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -125,7 +125,7 @@ int main(int argc, char *argv[], char *envp[]) sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { - err("error getting socket"); + err("error getting socket: %s", strerror(errno)); goto exit; } @@ -138,7 +138,7 @@ int main(int argc, char *argv[], char *envp[]) retval = sendto(sock, &usend_msg, sizeof(usend_msg), 0, (struct sockaddr *)&saddr, addrlen); if (retval == -1) { - info("error sending message (%s)", strerror(errno)); + err("error sending message: %s", strerror(errno)); retval = 1; } else { dbg("sent message type=0x%02x, %u bytes sent", usend_msg.type, retval); diff --git a/udevd.c b/udevd.c index ddf72738c3..86905923be 100644 --- a/udevd.c +++ b/udevd.c @@ -160,7 +160,7 @@ static void udev_event_run(struct uevent_msg *msg) logging_close(); exit(0); case -1: - err("fork of child failed"); + err("fork of child failed: %s", strerror(errno)); msg_queue_delete(msg); break; default: @@ -460,7 +460,7 @@ static struct uevent_msg *get_udevd_msg(void) size = recvmsg(udevd_sock, &smsg, 0); if (size < 0) { if (errno != EINTR) - err("unable to receive udevd message"); + err("unable to receive udevd message: %s", strerror(errno)); return NULL; } cmsg = CMSG_FIRSTHDR(&smsg); @@ -535,7 +535,7 @@ static struct uevent_msg *get_netlink_msg(void) size = recv(uevent_netlink_sock, &buffer, sizeof(buffer), 0); if (size < 0) { if (errno != EINTR) - err("unable to receive udevd message"); + err("unable to receive udevd message: %s", strerror(errno)); return NULL; } @@ -640,7 +640,7 @@ static int init_udevd_socket(void) udevd_sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (udevd_sock == -1) { - err("error getting socket, %s", strerror(errno)); + err("error getting socket: %s", strerror(errno)); return -1; } @@ -650,7 +650,7 @@ static int init_udevd_socket(void) /* 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)); + err("bind failed: %s", strerror(errno)); return -1; } @@ -673,7 +673,7 @@ static int init_uevent_netlink_sock(void) uevent_netlink_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (uevent_netlink_sock == -1) { - err("error getting socket, %s", strerror(errno)); + err("error getting socket: %s", strerror(errno)); return -1; } @@ -682,7 +682,7 @@ static int init_uevent_netlink_sock(void) retval = bind(uevent_netlink_sock, (struct sockaddr *) &snl, sizeof(struct sockaddr_nl)); if (retval < 0) { - err("bind failed, %s", strerror(errno)); + err("bind failed: %s", strerror(errno)); close(uevent_netlink_sock); uevent_netlink_sock = -1; return -1; @@ -717,7 +717,7 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udevd"); if (fd < 0) - err("fatal, could not open /dev/null"); + err("fatal, could not open /dev/null: %s", strerror(errno)); udev_init_config(); dbg("version %s", UDEV_VERSION); @@ -770,7 +770,7 @@ int main(int argc, char *argv[], char *envp[]) dbg("daemonized fork running"); break; case -1: - err("fork of daemon failed"); + err("fork of daemon failed: %s", strerror(errno)); rc = 4; goto exit; default: @@ -792,7 +792,7 @@ int main(int argc, char *argv[], char *envp[]) /* OOM_DISABLE == -17 */ fd = open("/proc/self/oom_adj", O_RDWR); if (fd < 0) - err("error disabling OOM"); + err("error disabling OOM: %s", strerror(errno)); else { write(fd, "-17", 3); close(fd); diff --git a/udeveventrecorder.c b/udeveventrecorder.c index 8ac344a47e..422cf88ff0 100644 --- a/udeveventrecorder.c +++ b/udeveventrecorder.c @@ -84,7 +84,7 @@ int main(int argc, char **argv, char **envp) snprintf(buf, FNSIZE, "/events/debug.%05lu.%s.%s.%u", seq, argv[1], a ? a : "", getpid()); if ((fd = open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0) { - err("error creating '%s'", buf); + err("error creating '%s': %s", buf, strerror(errno)); goto error; } free(buf); diff --git a/udevmonitor.c b/udevmonitor.c index dc04649745..805790233f 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -55,14 +55,14 @@ static int init_udev_monitor_socket(void) udev_monitor_sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (udev_monitor_sock == -1) { - fprintf(stderr, "error getting socket, %s\n", strerror(errno)); + 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)); + fprintf(stderr, "bind failed: %s\n", strerror(errno)); close(udev_monitor_sock); udev_monitor_sock = -1; return -1; @@ -86,14 +86,14 @@ static int init_uevent_netlink_sock(void) 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)); + 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)); + fprintf(stderr, "bind failed: %s\n", strerror(errno)); close(uevent_netlink_sock); uevent_netlink_sock = -1; return -1; @@ -173,7 +173,7 @@ int main(int argc, char *argv[]) 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\n"); + fprintf(stderr, "error receiving uevent message: %s\n", strerror(errno)); continue; } @@ -186,7 +186,7 @@ int main(int argc, char *argv[]) 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\n"); + fprintf(stderr, "error receiving uevent message: %s\n", strerror(errno)); continue; } printf("UEVENT[%s] %s\n", timestr, buf); @@ -195,7 +195,7 @@ int main(int argc, char *argv[]) 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\n"); + fprintf(stderr, "error receiving udev message: %s\n", strerror(errno)); continue; } printf("UDEV [%s] %s\n", timestr, buf); diff --git a/udevsend.c b/udevsend.c index 29d5bc155e..d0cfc2af53 100644 --- a/udevsend.c +++ b/udevsend.c @@ -71,17 +71,17 @@ static int start_daemon(void) /* daemon with empty environment */ close(sock); execve(UDEVD_BIN, argv, envp); - err("exec of daemon failed"); + err("exec of daemon failed: %s", strerror(errno)); _exit(1); case -1: - err("fork of daemon failed"); + err("fork of daemon failed: %s", strerror(errno)); return -1; default: exit(0); } break; case -1: - err("fork of helper failed"); + err("fork of helper failed: %s", strerror(errno)); return -1; default: waitpid(pid, NULL, 0); @@ -110,7 +110,7 @@ int main(int argc, char *argv[], char *envp[]) sock = socket(AF_LOCAL, SOCK_DGRAM, 0); if (sock == -1) { - err("error getting socket"); + err("error getting socket: %s", strerror(errno)); goto exit; } @@ -170,7 +170,7 @@ int main(int argc, char *argv[], char *envp[]) } if (errno != ECONNREFUSED) { - err("error sending message (%s)", strerror(errno)); + err("error sending message: %s", strerror(errno)); goto exit; } From df4e89bfa61b6aaea41619842aa9032dd1af072e Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Mon, 7 Nov 2005 18:52:03 +0100 Subject: [PATCH 1595/4284] move some logging from dbg() to info() --- udev_add.c | 12 ++++++------ udev_db.c | 2 +- udev_libc_wrapper.c | 6 +++--- udev_remove.c | 2 +- udev_rules_parse.c | 2 +- udev_selinux.c | 12 ++++++------ udev_utils.c | 2 +- udev_utils_file.c | 6 +++--- udevd.c | 6 +++--- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/udev_add.c b/udev_add.c index a811b5a17c..f4ad55a893 100644 --- a/udev_add.c +++ b/udev_add.c @@ -73,7 +73,7 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo } if (unlink(file) != 0) - dbg("unlink(%s) failed: %s", file, strerror(errno)); + err("unlink(%s) failed: %s", file, strerror(errno)); else dbg("already present file '%s' unlinked", file); @@ -90,14 +90,14 @@ create: perms: dbg("chmod(%s, %#o)", file, mode); if (chmod(file, mode) != 0) { - dbg("chmod(%s, %#o) failed: %s", file, mode, strerror(errno)); + 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) { - dbg("chown(%s, %u, %u) failed: %s", + err("chown(%s, %u, %u) failed: %s", file, uid, gid, strerror(errno)); goto exit; } @@ -222,7 +222,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de retval = symlink(linktarget, filename); selinux_resetfscreatecon(); if (retval != 0) - dbg("symlink(%s, %s) failed: %s", + err("symlink(%s, %s) failed: %s", linktarget, filename, strerror(errno)); } } @@ -244,7 +244,7 @@ static int rename_net_if(struct udevice *udev) sk = socket(PF_INET, SOCK_DGRAM, 0); if (sk < 0) { - dbg("error opening socket: %s", strerror(errno)); + err("error opening socket: %s", strerror(errno)); return -1; } @@ -254,7 +254,7 @@ static int rename_net_if(struct udevice *udev) retval = ioctl(sk, SIOCSIFNAME, &ifr); if (retval != 0) - dbg("error changing net interface name: %s", strerror(errno)); + err("error changing net interface name: %s", strerror(errno)); close(sk); return retval; diff --git a/udev_db.c b/udev_db.c index f00308bd2f..5caf3fda80 100644 --- a/udev_db.c +++ b/udev_db.c @@ -129,7 +129,7 @@ int udev_db_get_device(struct udevice *udev, const char *devpath) devpath_to_db_path(devpath, filename, sizeof(filename)); if (file_map(filename, &buf, &bufsize) != 0) { - dbg("no db file to read %s: %s", filename, strerror(errno)); + info("no db file to read %s: %s", filename, strerror(errno)); return -1; } diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index a7a8c5342d..fe38993cd7 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -102,7 +102,7 @@ uid_t lookup_user(const char *user) pw = getpwnam(user); if (pw == NULL) - dbg("specified user unknown '%s'", user); + info("specified user unknown '%s'", user); else uid = pw->pw_uid; @@ -116,7 +116,7 @@ gid_t lookup_group(const char *group) gr = getgrnam(group); if (gr == NULL) - dbg("specified group unknown '%s'", group); + info("specified group unknown '%s'", group); else gid = gr->gr_gid; @@ -144,7 +144,7 @@ static unsigned long get_id_by_name(const char *uname, const char *dbfile) char *tail; if (file_map(dbfile, &buf, &bufsize) != 0) { - dbg("can't open '%s' as db file: %s", dbfile, strerror(errno)); + err("can't open '%s' as db file: %s", dbfile, strerror(errno)); return 0; } dbg("search '%s' in '%s'", uname, dbfile); diff --git a/udev_remove.c b/udev_remove.c index 621fcc1960..cb5523af92 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -56,7 +56,7 @@ static int delete_path(const char *path) if (retval) { if (errno == ENOTEMPTY) return 0; - dbg("rmdir(%s) failed: %s", path, strerror(errno)); + err("rmdir(%s) failed: %s", path, strerror(errno)); break; } dbg("removed '%s'", path); diff --git a/udev_rules_parse.c b/udev_rules_parse.c index b664b983fb..7fa21afa8c 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -617,7 +617,7 @@ int udev_rules_init(struct udev_rules *rules, int resolve_names) else dbg("empty rules file '%s'", name_loop->name); } else - dbg("could not read '%s'", name_loop->name); + err("could not read '%s': %s", name_loop->name, strerror(errno)); list_del(&name_loop->node); free(name_loop); } diff --git a/udev_selinux.c b/udev_selinux.c index 719ff6403e..6ec359edd4 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -100,12 +100,12 @@ void selinux_setfilecon(const char *file, const char *devname, unsigned int mode if (ret < 0) if (matchpathcon(file, mode, &scontext) < 0) { - dbg("matchpathcon(%s) failed\n", file); + err("matchpathcon(%s) failed\n", file); return; } if (setfilecon(file, scontext) < 0) - dbg("setfilecon %s failed: %s", file, strerror(errno)); + err("setfilecon %s failed: %s", file, strerror(errno)); freecon(scontext); } @@ -126,12 +126,12 @@ void selinux_setfscreatecon(const char *file, const char *devname, unsigned int if (ret < 0) if (matchpathcon(file, mode, &scontext) < 0) { - dbg("matchpathcon(%s) failed\n", file); + err("matchpathcon(%s) failed\n", file); return; } if (setfscreatecon(scontext) < 0) - dbg("setfscreatecon %s failed: %s", file, strerror(errno)); + err("setfscreatecon %s failed: %s", file, strerror(errno)); freecon(scontext); } @@ -141,7 +141,7 @@ void selinux_resetfscreatecon(void) { if (is_selinux_running()) { if (setfscreatecon(prev_scontext) < 0) - dbg("setfscreatecon failed: %s", strerror(errno)); + err("setfscreatecon failed: %s", strerror(errno)); } } @@ -153,7 +153,7 @@ void selinux_init(void) */ if (is_selinux_running()) { if (getfscreatecon(&prev_scontext) < 0) { - dbg("getfscreatecon failed\n"); + err("getfscreatecon failed\n"); prev_scontext = NULL; } } diff --git a/udev_utils.c b/udev_utils.c index 04258a39c2..581ba9e80a 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -139,7 +139,7 @@ int add_matching_files(struct list_head *name_list, const char *dirname, const c dbg("open directory '%s'", dirname); dir = opendir(dirname); if (dir == NULL) { - dbg("unable to open '%s': %s", dirname, strerror(errno)); + err("unable to open '%s': %s", dirname, strerror(errno)); return -1; } diff --git a/udev_utils_file.c b/udev_utils_file.c index 23f61196b7..a3dab58b36 100644 --- a/udev_utils_file.c +++ b/udev_utils_file.c @@ -72,18 +72,18 @@ int unlink_secure(const char *filename) retval = chown(filename, 0, 0); if (retval) - dbg("chown(%s, 0, 0) failed: %s", filename, strerror(errno)); + err("chown(%s, 0, 0) failed: %s", filename, strerror(errno)); retval = chmod(filename, 0000); if (retval) - dbg("chmod(%s, 0000) failed: %s", filename, strerror(errno)); + err("chmod(%s, 0000) failed: %s", filename, strerror(errno)); retval = unlink(filename); if (errno == ENOENT) retval = 0; if (retval) - dbg("unlink(%s) failed: %s", filename, strerror(errno)); + err("unlink(%s) failed: %s", filename, strerror(errno)); return retval; } diff --git a/udevd.c b/udevd.c index 86905923be..333ad4143a 100644 --- a/udevd.c +++ b/udevd.c @@ -743,10 +743,10 @@ int main(int argc, char *argv[], char *envp[]) /* init sockets to receive events */ if (init_udevd_socket() < 0) { if (errno == EADDRINUSE) { - dbg("another udevd running, exit"); + err("another udevd running, exit"); rc = 1; } else { - dbg("error initializing udevd socket: %s", strerror(errno)); + err("error initializing udevd socket: %s", strerror(errno)); rc = 2; } goto exit; @@ -872,7 +872,7 @@ int main(int argc, char *argv[], char *envp[]) fdcount = select(maxfd+1, &readfds, NULL, NULL, NULL); if (fdcount < 0) { if (errno != EINTR) - dbg("error in select: %s", strerror(errno)); + err("error in select: %s", strerror(errno)); continue; } From bc48bbd9cd994470ce9b77adbb40464968853b00 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 7 Nov 2005 18:52:26 +0100 Subject: [PATCH 1596/4284] 074 release --- Makefile | 2 +- RELEASE-NOTES | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index bcaf30b706..bc97388a12 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 073 +VERSION = 074 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 8e9416d921..8a1bde8a3b 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,11 @@ +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 From 09c2bab517c58d9447660a9584822c8de6b641f0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 8 Nov 2005 03:07:04 +0100 Subject: [PATCH 1597/4284] forgot the ChangeLog for 074 --- ChangeLog | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index 2a81a68166..e6fd84f582 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +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 ============================================ From accff726856a0b3258a413d823a534f4f437e6b2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 9 Nov 2005 15:08:45 +0100 Subject: [PATCH 1598/4284] volume_id: provide libvolume_id.a file Signed-off-by: Kay Sievers --- extras/volume_id/Makefile | 14 +-- extras/volume_id/libvolume_id/Makefile | 66 ++++++++++ .../{volume_id => libvolume_id}/cramfs.c | 1 - .../{volume_id => libvolume_id}/ext.c | 1 - .../{volume_id => libvolume_id}/fat.c | 1 - .../{volume_id => libvolume_id}/hfs.c | 1 - .../{volume_id => libvolume_id}/highpoint.c | 1 - .../{volume_id => libvolume_id}/hpfs.c | 1 - .../{volume_id => libvolume_id}/iso9660.c | 1 - .../{volume_id => libvolume_id}/isw_raid.c | 1 - .../{volume_id => libvolume_id}/jfs.c | 1 - .../{volume_id => libvolume_id}/linux_raid.c | 1 - .../{volume_id => libvolume_id}/linux_swap.c | 1 - .../{volume_id => libvolume_id}/logging.h | 0 .../{volume_id => libvolume_id}/lsi_raid.c | 1 - .../{volume_id => libvolume_id}/luks.c | 1 - .../{volume_id => libvolume_id}/lvm.c | 1 - .../{volume_id => libvolume_id}/mac.c | 1 - .../{volume_id => libvolume_id}/minix.c | 1 - .../{volume_id => libvolume_id}/msdos.c | 1 - .../{volume_id => libvolume_id}/ntfs.c | 1 - .../{volume_id => libvolume_id}/nvidia_raid.c | 1 - .../{volume_id => libvolume_id}/ocfs.c | 1 - .../promise_raid.c | 1 - .../{volume_id => libvolume_id}/reiserfs.c | 1 - .../{volume_id => libvolume_id}/romfs.c | 1 - .../silicon_raid.c | 1 - .../{volume_id => libvolume_id}/sysv.c | 1 - .../{volume_id => libvolume_id}/udf.c | 1 - .../{volume_id => libvolume_id}/ufs.c | 1 - .../{volume_id => libvolume_id}/util.c | 0 .../{volume_id => libvolume_id}/util.h | 0 .../{volume_id => libvolume_id}/via_raid.c | 1 - .../{volume_id => libvolume_id}/volume_id.c | 52 -------- extras/volume_id/libvolume_id/volume_id.h | 116 ++++++++++++++++++ .../{volume_id => libvolume_id}/vxfs.c | 1 - .../{volume_id => libvolume_id}/xfs.c | 1 - extras/volume_id/vol_id.c | 2 +- extras/volume_id/volume_id/Makefile.inc | 66 ---------- extras/volume_id/volume_id/cramfs.h | 16 --- extras/volume_id/volume_id/ext.h | 16 --- extras/volume_id/volume_id/fat.h | 16 --- extras/volume_id/volume_id/hfs.h | 16 --- extras/volume_id/volume_id/highpoint.h | 17 --- extras/volume_id/volume_id/hpfs.h | 16 --- extras/volume_id/volume_id/iso9660.h | 16 --- extras/volume_id/volume_id/isw_raid.h | 16 --- extras/volume_id/volume_id/jfs.h | 16 --- extras/volume_id/volume_id/linux_raid.h | 16 --- extras/volume_id/volume_id/linux_swap.h | 16 --- extras/volume_id/volume_id/lsi_raid.h | 16 --- extras/volume_id/volume_id/luks.h | 16 --- extras/volume_id/volume_id/lvm.h | 17 --- extras/volume_id/volume_id/mac.h | 16 --- extras/volume_id/volume_id/minix.h | 16 --- extras/volume_id/volume_id/msdos.h | 16 --- extras/volume_id/volume_id/ntfs.h | 16 --- extras/volume_id/volume_id/nvidia_raid.h | 16 --- extras/volume_id/volume_id/ocfs.h | 18 --- extras/volume_id/volume_id/promise_raid.h | 16 --- extras/volume_id/volume_id/reiserfs.h | 16 --- extras/volume_id/volume_id/romfs.h | 16 --- extras/volume_id/volume_id/silicon_raid.h | 16 --- extras/volume_id/volume_id/sysv.h | 16 --- extras/volume_id/volume_id/udf.h | 16 --- extras/volume_id/volume_id/ufs.h | 16 --- extras/volume_id/volume_id/via_raid.h | 16 --- extras/volume_id/volume_id/volume_id.h | 74 ----------- extras/volume_id/volume_id/vxfs.h | 16 --- extras/volume_id/volume_id/xfs.h | 16 --- 70 files changed, 190 insertions(+), 714 deletions(-) create mode 100644 extras/volume_id/libvolume_id/Makefile rename extras/volume_id/{volume_id => libvolume_id}/cramfs.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/ext.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/fat.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/hfs.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/highpoint.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/hpfs.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/iso9660.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/isw_raid.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/jfs.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/linux_raid.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/linux_swap.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/logging.h (100%) rename extras/volume_id/{volume_id => libvolume_id}/lsi_raid.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/luks.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/lvm.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/mac.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/minix.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/msdos.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/ntfs.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/nvidia_raid.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/ocfs.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/promise_raid.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/reiserfs.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/romfs.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/silicon_raid.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/sysv.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/udf.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/ufs.c (99%) rename extras/volume_id/{volume_id => libvolume_id}/util.c (100%) rename extras/volume_id/{volume_id => libvolume_id}/util.h (100%) rename extras/volume_id/{volume_id => libvolume_id}/via_raid.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/volume_id.c (78%) create mode 100644 extras/volume_id/libvolume_id/volume_id.h rename extras/volume_id/{volume_id => libvolume_id}/vxfs.c (98%) rename extras/volume_id/{volume_id => libvolume_id}/xfs.c (98%) delete mode 100644 extras/volume_id/volume_id/Makefile.inc delete mode 100644 extras/volume_id/volume_id/cramfs.h delete mode 100644 extras/volume_id/volume_id/ext.h delete mode 100644 extras/volume_id/volume_id/fat.h delete mode 100644 extras/volume_id/volume_id/hfs.h delete mode 100644 extras/volume_id/volume_id/highpoint.h delete mode 100644 extras/volume_id/volume_id/hpfs.h delete mode 100644 extras/volume_id/volume_id/iso9660.h delete mode 100644 extras/volume_id/volume_id/isw_raid.h delete mode 100644 extras/volume_id/volume_id/jfs.h delete mode 100644 extras/volume_id/volume_id/linux_raid.h delete mode 100644 extras/volume_id/volume_id/linux_swap.h delete mode 100644 extras/volume_id/volume_id/lsi_raid.h delete mode 100644 extras/volume_id/volume_id/luks.h delete mode 100644 extras/volume_id/volume_id/lvm.h delete mode 100644 extras/volume_id/volume_id/mac.h delete mode 100644 extras/volume_id/volume_id/minix.h delete mode 100644 extras/volume_id/volume_id/msdos.h delete mode 100644 extras/volume_id/volume_id/ntfs.h delete mode 100644 extras/volume_id/volume_id/nvidia_raid.h delete mode 100644 extras/volume_id/volume_id/ocfs.h delete mode 100644 extras/volume_id/volume_id/promise_raid.h delete mode 100644 extras/volume_id/volume_id/reiserfs.h delete mode 100644 extras/volume_id/volume_id/romfs.h delete mode 100644 extras/volume_id/volume_id/silicon_raid.h delete mode 100644 extras/volume_id/volume_id/sysv.h delete mode 100644 extras/volume_id/volume_id/udf.h delete mode 100644 extras/volume_id/volume_id/ufs.h delete mode 100644 extras/volume_id/volume_id/via_raid.h delete mode 100644 extras/volume_id/volume_id/volume_id.h delete mode 100644 extras/volume_id/volume_id/vxfs.h delete mode 100644 extras/volume_id/volume_id/xfs.h diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 23de2ba091..30c0abb9a4 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -5,12 +5,8 @@ # Released under the GNU General Public License, version 2. # -VOLUME_ID_BASE=volume_id -include $(VOLUME_ID_BASE)/Makefile.inc - PROG = vol_id -OBJS = $(VOLUME_ID_OBJS) -HEADERS = $(VOLUME_ID_HEADERS) +LIBVOLUME_ID = libvolume_id/libvolume_id.a GEN_HEADERS = MAN_PAGES = @@ -36,8 +32,11 @@ all: $(PROG) $(MAN_PAGES) %.o: %.c $(GEN_HEADERS) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -$(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +$(LIBVOLUME_ID): + $(MAKE) -C libvolume_id + +$(PROG): %: $(HEADERS) %.o $(LIBVOLUME_ID) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(LIBVOLUME_ID) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif @@ -49,6 +48,7 @@ endif clean: rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(MAKE) -C libvolume_id clean .PHONY: clean install-bin: all diff --git a/extras/volume_id/libvolume_id/Makefile b/extras/volume_id/libvolume_id/Makefile new file mode 100644 index 0000000000..02c24eae05 --- /dev/null +++ b/extras/volume_id/libvolume_id/Makefile @@ -0,0 +1,66 @@ +# 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. +# + +LIBVOLUME_ID = libvolume_id.a + +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 \ + iso9660.o \ + jfs.o \ + linux_raid.o \ + linux_swap.o \ + lvm.o \ + mac.o \ + msdos.o \ + ntfs.o \ + reiserfs.o \ + udf.o \ + ufs.o \ + xfs.o \ + cramfs.o \ + hpfs.o \ + romfs.o \ + sysv.o \ + minix.o \ + luks.o \ + ocfs.o \ + vxfs.o \ + volume_id.o \ + util.o + +HEADERS= \ + volume_id.h \ + util.h + +AR = $(CROSS)ar +RANLIB = $(CROSS)ranlib + +all: $(LIBVOLUME_ID) +.PHONY: all +.DEFAULT: all + +%.o: %.c + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + +$(LIBVOLUME_ID): $(HEADERS) $(OBJS) + @rm -f $@ + $(QUIET) $(AR) cq $@ $(OBJS) + $(QUIET) $(RANLIB) $@ + +clean: + rm -f $(LIBVOLUME_ID) $(OBJS) +.PHONY: clean + diff --git a/extras/volume_id/volume_id/cramfs.c b/extras/volume_id/libvolume_id/cramfs.c similarity index 98% rename from extras/volume_id/volume_id/cramfs.c rename to extras/volume_id/libvolume_id/cramfs.c index 85a1bc8c55..0ad5886b32 100644 --- a/extras/volume_id/volume_id/cramfs.c +++ b/extras/volume_id/libvolume_id/cramfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "cramfs.h" struct cramfs_super { uint8_t magic[4]; diff --git a/extras/volume_id/volume_id/ext.c b/extras/volume_id/libvolume_id/ext.c similarity index 99% rename from extras/volume_id/volume_id/ext.c rename to extras/volume_id/libvolume_id/ext.c index a3e20d3151..d1f62dfb6f 100644 --- a/extras/volume_id/volume_id/ext.c +++ b/extras/volume_id/libvolume_id/ext.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "util.h" #include "logging.h" -#include "ext.h" struct ext2_super_block { uint32_t s_inodes_count; diff --git a/extras/volume_id/volume_id/fat.c b/extras/volume_id/libvolume_id/fat.c similarity index 99% rename from extras/volume_id/volume_id/fat.c rename to extras/volume_id/libvolume_id/fat.c index 74f2bb9194..26d0fe74ab 100644 --- a/extras/volume_id/volume_id/fat.c +++ b/extras/volume_id/libvolume_id/fat.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "fat.h" #define FAT12_MAX 0xff5 #define FAT16_MAX 0xfff5 diff --git a/extras/volume_id/volume_id/hfs.c b/extras/volume_id/libvolume_id/hfs.c similarity index 99% rename from extras/volume_id/volume_id/hfs.c rename to extras/volume_id/libvolume_id/hfs.c index 8de8b9aaac..27a8ac9999 100644 --- a/extras/volume_id/volume_id/hfs.c +++ b/extras/volume_id/libvolume_id/hfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "hfs.h" struct hfs_finder_info{ uint32_t boot_folder; diff --git a/extras/volume_id/volume_id/highpoint.c b/extras/volume_id/libvolume_id/highpoint.c similarity index 98% rename from extras/volume_id/volume_id/highpoint.c rename to extras/volume_id/libvolume_id/highpoint.c index 33c4a8c9c0..721b7ab26f 100644 --- a/extras/volume_id/volume_id/highpoint.c +++ b/extras/volume_id/libvolume_id/highpoint.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "highpoint.h" struct hpt37x_meta { uint8_t filler1[32]; diff --git a/extras/volume_id/volume_id/hpfs.c b/extras/volume_id/libvolume_id/hpfs.c similarity index 98% rename from extras/volume_id/volume_id/hpfs.c rename to extras/volume_id/libvolume_id/hpfs.c index 3b97d9339d..52cb47be39 100644 --- a/extras/volume_id/volume_id/hpfs.c +++ b/extras/volume_id/libvolume_id/hpfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "hpfs.h" struct hpfs_super { diff --git a/extras/volume_id/volume_id/iso9660.c b/extras/volume_id/libvolume_id/iso9660.c similarity index 99% rename from extras/volume_id/volume_id/iso9660.c rename to extras/volume_id/libvolume_id/iso9660.c index 3999a1e7bf..b6654cecf2 100644 --- a/extras/volume_id/volume_id/iso9660.c +++ b/extras/volume_id/libvolume_id/iso9660.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "iso9660.h" #define ISO_SUPERBLOCK_OFFSET 0x8000 #define ISO_SECTOR_SIZE 0x800 diff --git a/extras/volume_id/volume_id/isw_raid.c b/extras/volume_id/libvolume_id/isw_raid.c similarity index 98% rename from extras/volume_id/volume_id/isw_raid.c rename to extras/volume_id/libvolume_id/isw_raid.c index 745b42f2d1..1f49959ff9 100644 --- a/extras/volume_id/volume_id/isw_raid.c +++ b/extras/volume_id/libvolume_id/isw_raid.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "isw_raid.h" struct isw_meta { uint8_t sig[32]; diff --git a/extras/volume_id/volume_id/jfs.c b/extras/volume_id/libvolume_id/jfs.c similarity index 98% rename from extras/volume_id/volume_id/jfs.c rename to extras/volume_id/libvolume_id/jfs.c index 1b2bfdf0e9..b6ae9624d6 100644 --- a/extras/volume_id/volume_id/jfs.c +++ b/extras/volume_id/libvolume_id/jfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "jfs.h" struct jfs_super_block { uint8_t magic[4]; diff --git a/extras/volume_id/volume_id/linux_raid.c b/extras/volume_id/libvolume_id/linux_raid.c similarity index 98% rename from extras/volume_id/volume_id/linux_raid.c rename to extras/volume_id/libvolume_id/linux_raid.c index eb37dba367..d90510a817 100644 --- a/extras/volume_id/volume_id/linux_raid.c +++ b/extras/volume_id/libvolume_id/linux_raid.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "linux_raid.h" struct mdp_super_block { uint32_t md_magic; diff --git a/extras/volume_id/volume_id/linux_swap.c b/extras/volume_id/libvolume_id/linux_swap.c similarity index 98% rename from extras/volume_id/volume_id/linux_swap.c rename to extras/volume_id/libvolume_id/linux_swap.c index b3e22f6db2..18928b8351 100644 --- a/extras/volume_id/volume_id/linux_swap.c +++ b/extras/volume_id/libvolume_id/linux_swap.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "linux_swap.h" struct swap_header_v1_2 { uint8_t bootbits[1024]; diff --git a/extras/volume_id/volume_id/logging.h b/extras/volume_id/libvolume_id/logging.h similarity index 100% rename from extras/volume_id/volume_id/logging.h rename to extras/volume_id/libvolume_id/logging.h diff --git a/extras/volume_id/volume_id/lsi_raid.c b/extras/volume_id/libvolume_id/lsi_raid.c similarity index 98% rename from extras/volume_id/volume_id/lsi_raid.c rename to extras/volume_id/libvolume_id/lsi_raid.c index e5da281203..2720de763d 100644 --- a/extras/volume_id/volume_id/lsi_raid.c +++ b/extras/volume_id/libvolume_id/lsi_raid.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "lsi_raid.h" struct lsi_meta { uint8_t sig[6]; diff --git a/extras/volume_id/volume_id/luks.c b/extras/volume_id/libvolume_id/luks.c similarity index 99% rename from extras/volume_id/volume_id/luks.c rename to extras/volume_id/libvolume_id/luks.c index ff90f5d3d1..43f326e176 100644 --- a/extras/volume_id/volume_id/luks.c +++ b/extras/volume_id/libvolume_id/luks.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "util.h" #include "logging.h" -#include "luks.h" #define SECTOR_SHIFT 9 #define SECTOR_SIZE (1 << SECTOR_SHIFT) diff --git a/extras/volume_id/volume_id/lvm.c b/extras/volume_id/libvolume_id/lvm.c similarity index 99% rename from extras/volume_id/volume_id/lvm.c rename to extras/volume_id/libvolume_id/lvm.c index a188402da8..650986256d 100644 --- a/extras/volume_id/volume_id/lvm.c +++ b/extras/volume_id/libvolume_id/lvm.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "lvm.h" struct lvm1_super_block { uint8_t id[2]; diff --git a/extras/volume_id/volume_id/mac.c b/extras/volume_id/libvolume_id/mac.c similarity index 99% rename from extras/volume_id/volume_id/mac.c rename to extras/volume_id/libvolume_id/mac.c index 1587f48823..99bcbde6be 100644 --- a/extras/volume_id/volume_id/mac.c +++ b/extras/volume_id/libvolume_id/mac.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "mac.h" struct mac_driver_desc { uint8_t signature[2]; diff --git a/extras/volume_id/volume_id/minix.c b/extras/volume_id/libvolume_id/minix.c similarity index 98% rename from extras/volume_id/volume_id/minix.c rename to extras/volume_id/libvolume_id/minix.c index b081afab49..ca57745f78 100644 --- a/extras/volume_id/volume_id/minix.c +++ b/extras/volume_id/libvolume_id/minix.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "minix.h" struct minix_super_block { diff --git a/extras/volume_id/volume_id/msdos.c b/extras/volume_id/libvolume_id/msdos.c similarity index 99% rename from extras/volume_id/volume_id/msdos.c rename to extras/volume_id/libvolume_id/msdos.c index ab18fc3585..a66046052a 100644 --- a/extras/volume_id/volume_id/msdos.c +++ b/extras/volume_id/libvolume_id/msdos.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "msdos.h" struct msdos_partition_entry { uint8_t boot_ind; diff --git a/extras/volume_id/volume_id/ntfs.c b/extras/volume_id/libvolume_id/ntfs.c similarity index 99% rename from extras/volume_id/volume_id/ntfs.c rename to extras/volume_id/libvolume_id/ntfs.c index 39aa2d73c6..de9ad6d654 100644 --- a/extras/volume_id/volume_id/ntfs.c +++ b/extras/volume_id/libvolume_id/ntfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "ntfs.h" struct ntfs_super_block { uint8_t jump[3]; diff --git a/extras/volume_id/volume_id/nvidia_raid.c b/extras/volume_id/libvolume_id/nvidia_raid.c similarity index 98% rename from extras/volume_id/volume_id/nvidia_raid.c rename to extras/volume_id/libvolume_id/nvidia_raid.c index 9198f1e067..3b967e6979 100644 --- a/extras/volume_id/volume_id/nvidia_raid.c +++ b/extras/volume_id/libvolume_id/nvidia_raid.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "nvidia_raid.h" struct nvidia_meta { uint8_t vendor[8]; diff --git a/extras/volume_id/volume_id/ocfs.c b/extras/volume_id/libvolume_id/ocfs.c similarity index 99% rename from extras/volume_id/volume_id/ocfs.c rename to extras/volume_id/libvolume_id/ocfs.c index 88064ed193..faf89bd3e0 100644 --- a/extras/volume_id/volume_id/ocfs.c +++ b/extras/volume_id/libvolume_id/ocfs.c @@ -27,7 +27,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "ocfs.h" struct ocfs1_super_block_header { diff --git a/extras/volume_id/volume_id/promise_raid.c b/extras/volume_id/libvolume_id/promise_raid.c similarity index 98% rename from extras/volume_id/volume_id/promise_raid.c rename to extras/volume_id/libvolume_id/promise_raid.c index 54832a888a..6611aeab32 100644 --- a/extras/volume_id/volume_id/promise_raid.c +++ b/extras/volume_id/libvolume_id/promise_raid.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "promise_raid.h" struct promise_meta { uint8_t sig[24]; diff --git a/extras/volume_id/volume_id/reiserfs.c b/extras/volume_id/libvolume_id/reiserfs.c similarity index 99% rename from extras/volume_id/volume_id/reiserfs.c rename to extras/volume_id/libvolume_id/reiserfs.c index e64b08acdd..0eecbda5cb 100644 --- a/extras/volume_id/volume_id/reiserfs.c +++ b/extras/volume_id/libvolume_id/reiserfs.c @@ -27,7 +27,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "reiserfs.h" struct reiserfs_super_block { uint32_t blocks_count; diff --git a/extras/volume_id/volume_id/romfs.c b/extras/volume_id/libvolume_id/romfs.c similarity index 98% rename from extras/volume_id/volume_id/romfs.c rename to extras/volume_id/libvolume_id/romfs.c index 3373f36497..51ef3739b3 100644 --- a/extras/volume_id/volume_id/romfs.c +++ b/extras/volume_id/libvolume_id/romfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "romfs.h" struct romfs_super { uint8_t magic[8]; diff --git a/extras/volume_id/volume_id/silicon_raid.c b/extras/volume_id/libvolume_id/silicon_raid.c similarity index 98% rename from extras/volume_id/volume_id/silicon_raid.c rename to extras/volume_id/libvolume_id/silicon_raid.c index 5f68127c4f..a307764730 100644 --- a/extras/volume_id/volume_id/silicon_raid.c +++ b/extras/volume_id/libvolume_id/silicon_raid.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "silicon_raid.h" struct silicon_meta { uint8_t unknown0[0x2E]; diff --git a/extras/volume_id/volume_id/sysv.c b/extras/volume_id/libvolume_id/sysv.c similarity index 99% rename from extras/volume_id/volume_id/sysv.c rename to extras/volume_id/libvolume_id/sysv.c index 610edb8876..fc874d5bea 100644 --- a/extras/volume_id/volume_id/sysv.c +++ b/extras/volume_id/libvolume_id/sysv.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "sysv.h" #define SYSV_NICINOD 100 #define SYSV_NICFREE 50 diff --git a/extras/volume_id/volume_id/udf.c b/extras/volume_id/libvolume_id/udf.c similarity index 99% rename from extras/volume_id/volume_id/udf.c rename to extras/volume_id/libvolume_id/udf.c index f54ca87c8f..fede1ce68a 100644 --- a/extras/volume_id/volume_id/udf.c +++ b/extras/volume_id/libvolume_id/udf.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "udf.h" struct volume_descriptor { struct descriptor_tag { diff --git a/extras/volume_id/volume_id/ufs.c b/extras/volume_id/libvolume_id/ufs.c similarity index 99% rename from extras/volume_id/volume_id/ufs.c rename to extras/volume_id/libvolume_id/ufs.c index a7bd091c5e..ace61db657 100644 --- a/extras/volume_id/volume_id/ufs.c +++ b/extras/volume_id/libvolume_id/ufs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "ufs.h" struct ufs_super_block { uint32_t fs_link; diff --git a/extras/volume_id/volume_id/util.c b/extras/volume_id/libvolume_id/util.c similarity index 100% rename from extras/volume_id/volume_id/util.c rename to extras/volume_id/libvolume_id/util.c diff --git a/extras/volume_id/volume_id/util.h b/extras/volume_id/libvolume_id/util.h similarity index 100% rename from extras/volume_id/volume_id/util.h rename to extras/volume_id/libvolume_id/util.h diff --git a/extras/volume_id/volume_id/via_raid.c b/extras/volume_id/libvolume_id/via_raid.c similarity index 98% rename from extras/volume_id/volume_id/via_raid.c rename to extras/volume_id/libvolume_id/via_raid.c index 2b74123016..66962cd7f0 100644 --- a/extras/volume_id/volume_id/via_raid.c +++ b/extras/volume_id/libvolume_id/via_raid.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "via_raid.h" struct via_meta { uint16_t signature; diff --git a/extras/volume_id/volume_id/volume_id.c b/extras/volume_id/libvolume_id/volume_id.c similarity index 78% rename from extras/volume_id/volume_id/volume_id.c rename to extras/volume_id/libvolume_id/volume_id.c index b92269863f..09d1e31725 100644 --- a/extras/volume_id/volume_id/volume_id.c +++ b/extras/volume_id/libvolume_id/volume_id.c @@ -30,36 +30,6 @@ #include "logging.h" #include "util.h" -#include "ext.h" -#include "reiserfs.h" -#include "fat.h" -#include "hfs.h" -#include "jfs.h" -#include "xfs.h" -#include "ufs.h" -#include "ntfs.h" -#include "iso9660.h" -#include "udf.h" -#include "highpoint.h" -#include "isw_raid.h" -#include "lsi_raid.h" -#include "via_raid.h" -#include "silicon_raid.h" -#include "nvidia_raid.h" -#include "promise_raid.h" -#include "luks.h" -#include "linux_swap.h" -#include "linux_raid.h" -#include "lvm.h" -#include "cramfs.h" -#include "hpfs.h" -#include "romfs.h" -#include "sysv.h" -#include "minix.h" -#include "mac.h" -#include "msdos.h" -#include "ocfs.h" -#include "vxfs.h" int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) { @@ -213,28 +183,6 @@ struct volume_id *volume_id_open_node(const char *path) return id; } -/* open volume by major/minor */ -struct volume_id *volume_id_open_dev_t(dev_t devt) -{ - struct volume_id *id; - char tmp_node[VOLUME_ID_PATH_MAX]; - - snprintf(tmp_node, VOLUME_ID_PATH_MAX, - "/dev/.volume_id-%u-%u-%u", getpid(), major(devt), minor(devt)); - tmp_node[VOLUME_ID_PATH_MAX-1] = '\0'; - - /* create tempory node to open the block device */ - unlink(tmp_node); - if (mknod(tmp_node, (S_IFBLK | 0600), devt) != 0) - return NULL; - - id = volume_id_open_node(tmp_node); - - unlink(tmp_node); - - return id; -} - void volume_id_close(struct volume_id *id) { if (id == NULL) diff --git a/extras/volume_id/libvolume_id/volume_id.h b/extras/volume_id/libvolume_id/volume_id.h new file mode 100644 index 0000000000..f2f3a0d006 --- /dev/null +++ b/extras/volume_id/libvolume_id/volume_id.h @@ -0,0 +1,116 @@ +/* + * volume_id - reads partition 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 _VOLUME_ID_H_ +#define _VOLUME_ID_H_ + +#include + +#define VOLUME_ID_VERSION 53 + +#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_PARTITIONTABLE, + VOLUME_ID_RAID, + VOLUME_ID_DISKLABEL, + VOLUME_ID_CRYPTO, +}; + +struct volume_id_partition { + enum volume_id_usage usage_id; + char *usage; + char *type; + uint64_t off; + uint64_t len; + uint8_t partition_type_raw; +}; + +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]; + + struct volume_id_partition *partitions; + size_t partition_count; + + int fd; + uint8_t *sbbuf; + size_t sbbuf_len; + uint8_t *seekbuf; + uint64_t seekbuf_off; + size_t seekbuf_len; + int fd_close:1; +}; + +extern struct volume_id *volume_id_open_fd(int fd); +extern struct volume_id *volume_id_open_node(const char *path); +extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); +extern void volume_id_close(struct volume_id *id); + +/* filesystems */ +extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ext(struct volume_id *id, uint64_t off); +extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off); +extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off); +extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off); +extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_minix(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off); +extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off); +extern int volume_id_probe_udf(struct volume_id *id, uint64_t off); +extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off); +extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off); + +/* special formats */ +extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off); +extern int volume_id_probe_luks(struct volume_id *id, uint64_t off); + +/* 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); +extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off); + +/* 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); +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); + +/* partition tables */ +extern int volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t off); +extern int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off); + +#endif diff --git a/extras/volume_id/volume_id/vxfs.c b/extras/volume_id/libvolume_id/vxfs.c similarity index 98% rename from extras/volume_id/volume_id/vxfs.c rename to extras/volume_id/libvolume_id/vxfs.c index c4a9ace98f..0aef369899 100644 --- a/extras/volume_id/volume_id/vxfs.c +++ b/extras/volume_id/libvolume_id/vxfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "vxfs.h" #define VXFS_SUPER_MAGIC 0xa501FCF5 diff --git a/extras/volume_id/volume_id/xfs.c b/extras/volume_id/libvolume_id/xfs.c similarity index 98% rename from extras/volume_id/volume_id/xfs.c rename to extras/volume_id/libvolume_id/xfs.c index 7fd629099d..a5f5d8432c 100644 --- a/extras/volume_id/volume_id/xfs.c +++ b/extras/volume_id/libvolume_id/xfs.c @@ -26,7 +26,6 @@ #include "volume_id.h" #include "logging.h" #include "util.h" -#include "xfs.h" struct xfs_super_block { uint8_t magic[4]; diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 2b53085c72..6f99c52728 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -31,7 +31,7 @@ #include "../../udev_utils.h" #include "../../logging.h" -#include "volume_id/volume_id.h" +#include "libvolume_id/volume_id.h" #define BLKGETSIZE64 _IOR(0x12,114,size_t) diff --git a/extras/volume_id/volume_id/Makefile.inc b/extras/volume_id/volume_id/Makefile.inc deleted file mode 100644 index 6f8dceea4a..0000000000 --- a/extras/volume_id/volume_id/Makefile.inc +++ /dev/null @@ -1,66 +0,0 @@ -VOLUME_ID_OBJS= \ - $(VOLUME_ID_BASE)/ext.o \ - $(VOLUME_ID_BASE)/fat.o \ - $(VOLUME_ID_BASE)/hfs.o \ - $(VOLUME_ID_BASE)/highpoint.o \ - $(VOLUME_ID_BASE)/isw_raid.o \ - $(VOLUME_ID_BASE)/lsi_raid.o \ - $(VOLUME_ID_BASE)/via_raid.o \ - $(VOLUME_ID_BASE)/silicon_raid.o \ - $(VOLUME_ID_BASE)/nvidia_raid.o \ - $(VOLUME_ID_BASE)/promise_raid.o \ - $(VOLUME_ID_BASE)/iso9660.o \ - $(VOLUME_ID_BASE)/jfs.o \ - $(VOLUME_ID_BASE)/linux_raid.o \ - $(VOLUME_ID_BASE)/linux_swap.o \ - $(VOLUME_ID_BASE)/lvm.o \ - $(VOLUME_ID_BASE)/mac.o \ - $(VOLUME_ID_BASE)/msdos.o \ - $(VOLUME_ID_BASE)/ntfs.o \ - $(VOLUME_ID_BASE)/reiserfs.o \ - $(VOLUME_ID_BASE)/udf.o \ - $(VOLUME_ID_BASE)/ufs.o \ - $(VOLUME_ID_BASE)/xfs.o \ - $(VOLUME_ID_BASE)/cramfs.o \ - $(VOLUME_ID_BASE)/hpfs.o \ - $(VOLUME_ID_BASE)/romfs.o \ - $(VOLUME_ID_BASE)/sysv.o \ - $(VOLUME_ID_BASE)/minix.o \ - $(VOLUME_ID_BASE)/luks.o \ - $(VOLUME_ID_BASE)/ocfs.o \ - $(VOLUME_ID_BASE)/vxfs.o \ - $(VOLUME_ID_BASE)/volume_id.o \ - $(VOLUME_ID_BASE)/util.o - -VOLUME_ID_HEADERS= \ - $(VOLUME_ID_BASE)/ext.h \ - $(VOLUME_ID_BASE)/fat.h \ - $(VOLUME_ID_BASE)/hfs.h \ - $(VOLUME_ID_BASE)/highpoint.h \ - $(VOLUME_ID_BASE)/isw_raid.h \ - $(VOLUME_ID_BASE)/lsi_raid.h \ - $(VOLUME_ID_BASE)/via_raid.h \ - $(VOLUME_ID_BASE)/silicon_raid.h \ - $(VOLUME_ID_BASE)/nvidia_raid.h \ - $(VOLUME_ID_BASE)/promise_raid.h \ - $(VOLUME_ID_BASE)/iso9660.h \ - $(VOLUME_ID_BASE)/jfs.h \ - $(VOLUME_ID_BASE)/linux_raid.h \ - $(VOLUME_ID_BASE)/linux_swap.h \ - $(VOLUME_ID_BASE)/lvm.h \ - $(VOLUME_ID_BASE)/mac.h \ - $(VOLUME_ID_BASE)/msdos.h \ - $(VOLUME_ID_BASE)/ntfs.h \ - $(VOLUME_ID_BASE)/reiserfs.h \ - $(VOLUME_ID_BASE)/udf.h \ - $(VOLUME_ID_BASE)/ufs.h \ - $(VOLUME_ID_BASE)/xfs.h \ - $(VOLUME_ID_BASE)/cramfs.h \ - $(VOLUME_ID_BASE)/romfs.h \ - $(VOLUME_ID_BASE)/sysv.h \ - $(VOLUME_ID_BASE)/minix.h \ - $(VOLUME_ID_BASE)/luks.h \ - $(VOLUME_ID_BASE)/ocfs.h \ - $(VOLUME_ID_BASE)/vxfs.h \ - $(VOLUME_ID_BASE)/volume_id.h \ - $(VOLUME_ID_BASE)/util.h diff --git a/extras/volume_id/volume_id/cramfs.h b/extras/volume_id/volume_id/cramfs.h deleted file mode 100644 index 0ff19c342e..0000000000 --- a/extras/volume_id/volume_id/cramfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_CRAMFS_ -#define _VOLUME_ID_CRAMFS_ - -extern int volume_id_probe_cramfs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/ext.h b/extras/volume_id/volume_id/ext.h deleted file mode 100644 index dfda2074b8..0000000000 --- a/extras/volume_id/volume_id/ext.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_EXT_ -#define _VOLUME_ID_EXT_ - -extern int volume_id_probe_ext(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/fat.h b/extras/volume_id/volume_id/fat.h deleted file mode 100644 index 92fa953b11..0000000000 --- a/extras/volume_id/volume_id/fat.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_FAT_ -#define _VOLUME_ID_FAT_ - -extern int volume_id_probe_vfat(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/hfs.h b/extras/volume_id/volume_id/hfs.h deleted file mode 100644 index 4f732b6726..0000000000 --- a/extras/volume_id/volume_id/hfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_HFS_ -#define _VOLUME_ID_HFS_ - -extern int volume_id_probe_hfs_hfsplus(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/highpoint.h b/extras/volume_id/volume_id/highpoint.h deleted file mode 100644 index f04d5f1685..0000000000 --- a/extras/volume_id/volume_id/highpoint.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 _VOLUME_ID_HIGHPOINT_ -#define _VOLUME_ID_HIGHPOINT_ - -extern int volume_id_probe_highpoint_37x_raid(struct volume_id *id, uint64_t off); -extern int volume_id_probe_highpoint_45x_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/hpfs.h b/extras/volume_id/volume_id/hpfs.h deleted file mode 100644 index d33e43a114..0000000000 --- a/extras/volume_id/volume_id/hpfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_HPFS_ -#define _VOLUME_ID_HPFS_ - -extern int volume_id_probe_hpfs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/iso9660.h b/extras/volume_id/volume_id/iso9660.h deleted file mode 100644 index c407d416a2..0000000000 --- a/extras/volume_id/volume_id/iso9660.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_ISO9660_ -#define _VOLUME_ID_ISO9660_ - -extern int volume_id_probe_iso9660(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/isw_raid.h b/extras/volume_id/volume_id/isw_raid.h deleted file mode 100644 index 55d8c49268..0000000000 --- a/extras/volume_id/volume_id/isw_raid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_ISW_RAID_ -#define _VOLUME_ID_ISW_RAID_ - -extern int volume_id_probe_intel_software_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/jfs.h b/extras/volume_id/volume_id/jfs.h deleted file mode 100644 index 4ef0d8763c..0000000000 --- a/extras/volume_id/volume_id/jfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_JFS_ -#define _VOLUME_ID_JFS_ - -extern int volume_id_probe_jfs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/linux_raid.h b/extras/volume_id/volume_id/linux_raid.h deleted file mode 100644 index 8fdeebf5cd..0000000000 --- a/extras/volume_id/volume_id/linux_raid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_LINUX_RAID_ -#define _VOLUME_ID_LINUX_RAID_ - -extern int volume_id_probe_linux_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/linux_swap.h b/extras/volume_id/volume_id/linux_swap.h deleted file mode 100644 index e31ee6eb90..0000000000 --- a/extras/volume_id/volume_id/linux_swap.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_LINUX_SWAP_ -#define _VOLUME_ID_LINUX_SWAP_ - -extern int volume_id_probe_linux_swap(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/lsi_raid.h b/extras/volume_id/volume_id/lsi_raid.h deleted file mode 100644 index 51a0bfbcc6..0000000000 --- a/extras/volume_id/volume_id/lsi_raid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_LSI_RAID_ -#define _VOLUME_ID_LSI_RAID_ - -extern int volume_id_probe_lsi_mega_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/luks.h b/extras/volume_id/volume_id/luks.h deleted file mode 100644 index fbf3fcd846..0000000000 --- a/extras/volume_id/volume_id/luks.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_LUKS_ -#define _VOLUME_ID_LUKS_ - -extern int volume_id_probe_luks(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/lvm.h b/extras/volume_id/volume_id/lvm.h deleted file mode 100644 index d07cb53af6..0000000000 --- a/extras/volume_id/volume_id/lvm.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 _VOLUME_ID_LVM_ -#define _VOLUME_ID_LVM_ - -extern int volume_id_probe_lvm1(struct volume_id *id, uint64_t off); -extern int volume_id_probe_lvm2(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/mac.h b/extras/volume_id/volume_id/mac.h deleted file mode 100644 index 77b8ccda6f..0000000000 --- a/extras/volume_id/volume_id/mac.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_MAC_ -#define _VOLUME_ID_MAC_ - -extern int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/minix.h b/extras/volume_id/volume_id/minix.h deleted file mode 100644 index 3020cc0464..0000000000 --- a/extras/volume_id/volume_id/minix.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_MINIX_ -#define _VOLUME_ID_MINIX_ - -extern int volume_id_probe_minix(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/msdos.h b/extras/volume_id/volume_id/msdos.h deleted file mode 100644 index b319f05d63..0000000000 --- a/extras/volume_id/volume_id/msdos.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_MSDOS_ -#define _VOLUME_ID_MSDOS_ - -extern int volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/ntfs.h b/extras/volume_id/volume_id/ntfs.h deleted file mode 100644 index 8d59159685..0000000000 --- a/extras/volume_id/volume_id/ntfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_NTFS_ -#define _VOLUME_ID_NTFS_ - -extern int volume_id_probe_ntfs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/nvidia_raid.h b/extras/volume_id/volume_id/nvidia_raid.h deleted file mode 100644 index 80c51692aa..0000000000 --- a/extras/volume_id/volume_id/nvidia_raid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_NVIDIA_RAID_ -#define _VOLUME_ID_NVIDIA_RAID_ - -extern int volume_id_probe_nvidia_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/ocfs.h b/extras/volume_id/volume_id/ocfs.h deleted file mode 100644 index 9d46b28dcd..0000000000 --- a/extras/volume_id/volume_id/ocfs.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * 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 _VOLUME_ID_OCFS1_ -#define _VOLUME_ID_OCFS1_ - -extern int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off); -extern int volume_id_probe_ocfs2(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/promise_raid.h b/extras/volume_id/volume_id/promise_raid.h deleted file mode 100644 index a46b062015..0000000000 --- a/extras/volume_id/volume_id/promise_raid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_PROMISE_RAID_ -#define _VOLUME_ID_PROMISE_RAID_ - -extern int volume_id_probe_promise_fasttrack_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/reiserfs.h b/extras/volume_id/volume_id/reiserfs.h deleted file mode 100644 index 57ee05ea2e..0000000000 --- a/extras/volume_id/volume_id/reiserfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_REISERFS_ -#define _VOLUME_ID_REISERFS_ - -extern int volume_id_probe_reiserfs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/romfs.h b/extras/volume_id/volume_id/romfs.h deleted file mode 100644 index 5fe56dcdfe..0000000000 --- a/extras/volume_id/volume_id/romfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_ROMFS_ -#define _VOLUME_ID_ROMFS_ - -extern int volume_id_probe_romfs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/silicon_raid.h b/extras/volume_id/volume_id/silicon_raid.h deleted file mode 100644 index f80c1a4a3f..0000000000 --- a/extras/volume_id/volume_id/silicon_raid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_SILICON_RAID_ -#define _VOLUME_ID_SILICON_RAID_ - -extern int volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/sysv.h b/extras/volume_id/volume_id/sysv.h deleted file mode 100644 index b8c369ec08..0000000000 --- a/extras/volume_id/volume_id/sysv.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_SYSV_ -#define _VOLUME_ID_SYSV_ - -extern int volume_id_probe_sysv(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/udf.h b/extras/volume_id/volume_id/udf.h deleted file mode 100644 index ff95cc1058..0000000000 --- a/extras/volume_id/volume_id/udf.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_UDF_ -#define _VOLUME_ID_UDF_ - -extern int volume_id_probe_udf(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/ufs.h b/extras/volume_id/volume_id/ufs.h deleted file mode 100644 index ae46a924b4..0000000000 --- a/extras/volume_id/volume_id/ufs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_UFS_ -#define _VOLUME_ID_UFS_ - -extern int volume_id_probe_ufs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/via_raid.h b/extras/volume_id/volume_id/via_raid.h deleted file mode 100644 index 3eeaa2cee3..0000000000 --- a/extras/volume_id/volume_id/via_raid.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_VIA_RAID_ -#define _VOLUME_ID_VIA_RAID_ - -extern int volume_id_probe_via_raid(struct volume_id *id, uint64_t off, uint64_t size); - -#endif diff --git a/extras/volume_id/volume_id/volume_id.h b/extras/volume_id/volume_id/volume_id.h deleted file mode 100644 index 9994615c69..0000000000 --- a/extras/volume_id/volume_id/volume_id.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * volume_id - reads partition 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 _VOLUME_ID_H_ -#define _VOLUME_ID_H_ - -#include - -#define VOLUME_ID_VERSION 52 - -#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_PARTITIONTABLE, - VOLUME_ID_RAID, - VOLUME_ID_DISKLABEL, - VOLUME_ID_CRYPTO, -}; - -struct volume_id_partition { - enum volume_id_usage usage_id; - char *usage; - char *type; - uint64_t off; - uint64_t len; - uint8_t partition_type_raw; -}; - -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]; - - struct volume_id_partition *partitions; - size_t partition_count; - - int fd; - uint8_t *sbbuf; - size_t sbbuf_len; - uint8_t *seekbuf; - uint64_t seekbuf_off; - size_t seekbuf_len; - int fd_close:1; -}; - -extern struct volume_id *volume_id_open_fd(int fd); -extern struct volume_id *volume_id_open_node(const char *path); -extern struct volume_id *volume_id_open_dev_t(dev_t devt); -extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); -extern void volume_id_close(struct volume_id *id); - -#endif diff --git a/extras/volume_id/volume_id/vxfs.h b/extras/volume_id/volume_id/vxfs.h deleted file mode 100644 index 8ca45c3fdc..0000000000 --- a/extras/volume_id/volume_id/vxfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID_VXFS_ -#define _VOLUME_ID_VXFS_ - -extern int volume_id_probe_vxfs(struct volume_id *id, uint64_t off); - -#endif diff --git a/extras/volume_id/volume_id/xfs.h b/extras/volume_id/volume_id/xfs.h deleted file mode 100644 index f21cc5f929..0000000000 --- a/extras/volume_id/volume_id/xfs.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * 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 _VOLUME_ID__ -#define _VOLUME_ID__ - -extern int volume_id_probe_xfs(struct volume_id *id, uint64_t off); - -#endif From a8349b33e564f7faa83341cb1fa58466b0589ae9 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 9 Nov 2005 15:42:07 +0100 Subject: [PATCH 1599/4284] remove our own copy of klibc Signed-off-by: Kay Sievers --- ChangeLog | 3 + Makefile | 25 +- README | 17 +- RELEASE-NOTES | 5 + klibc/MCONFIG | 98 -- klibc/MRULES | 45 - klibc/Makefile | 77 - klibc/README | 21 - klibc/include/alloca.h | 13 - klibc/include/arch/alpha/klibc/archsetjmp.h | 33 - klibc/include/arch/alpha/klibc/archsignal.h | 13 - klibc/include/arch/alpha/klibc/archstat.h | 26 - klibc/include/arch/alpha/klibc/archsys.h | 53 - klibc/include/arch/alpha/machine/asm.h | 44 - klibc/include/arch/arm/klibc/archsetjmp.h | 14 - klibc/include/arch/arm/klibc/archsignal.h | 13 - klibc/include/arch/arm/klibc/archstat.h | 45 - klibc/include/arch/arm/klibc/archsys.h | 12 - klibc/include/arch/cris/klibc/archsetjmp.h | 24 - klibc/include/arch/cris/klibc/archsignal.h | 13 - klibc/include/arch/cris/klibc/archstat.h | 37 - klibc/include/arch/cris/klibc/archsys.h | 12 - klibc/include/arch/i386/klibc/archsetjmp.h | 19 - klibc/include/arch/i386/klibc/archsignal.h | 13 - klibc/include/arch/i386/klibc/archstat.h | 37 - klibc/include/arch/i386/klibc/archsys.h | 12 - klibc/include/arch/i386/klibc/diverr.h | 16 - klibc/include/arch/i386/sys/io.h | 126 -- klibc/include/arch/i386/sys/vm86.h | 41 - klibc/include/arch/ia64/klibc/archsetjmp.h | 17 - klibc/include/arch/ia64/klibc/archsignal.h | 31 - klibc/include/arch/ia64/klibc/archstat.h | 24 - klibc/include/arch/ia64/klibc/archsys.h | 218 --- klibc/include/arch/m32r/klibc/archsetjmp.h | 21 - klibc/include/arch/m32r/klibc/archsignal.h | 13 - klibc/include/arch/m32r/klibc/archstat.h | 37 - klibc/include/arch/m32r/klibc/archsys.h | 12 - klibc/include/arch/m68k/klibc/archsignal.h | 13 - klibc/include/arch/m68k/klibc/archstat.h | 37 - klibc/include/arch/m68k/klibc/archsys.h | 12 - klibc/include/arch/mips/klibc/archfcntl.h | 87 - klibc/include/arch/mips/klibc/archsetjmp.h | 39 - klibc/include/arch/mips/klibc/archsignal.h | 13 - klibc/include/arch/mips/klibc/archstat.h | 39 - klibc/include/arch/mips/klibc/archsys.h | 12 - klibc/include/arch/mips/machine/asm.h | 11 - klibc/include/arch/mips/sgidefs.h | 20 - klibc/include/arch/mips/spaces.h | 1 - klibc/include/arch/mips64/klibc/archsignal.h | 13 - klibc/include/arch/mips64/klibc/archstat.h | 33 - klibc/include/arch/mips64/klibc/archsys.h | 12 - klibc/include/arch/parisc/klibc/archsetjmp.h | 14 - klibc/include/arch/parisc/klibc/archsignal.h | 24 - klibc/include/arch/parisc/klibc/archstat.h | 27 - klibc/include/arch/parisc/klibc/archsys.h | 12 - klibc/include/arch/ppc/klibc/archsetjmp.h | 36 - klibc/include/arch/ppc/klibc/archsignal.h | 13 - klibc/include/arch/ppc/klibc/archstat.h | 28 - klibc/include/arch/ppc/klibc/archsys.h | 61 - klibc/include/arch/ppc64/klibc/archsetjmp.h | 36 - klibc/include/arch/ppc64/klibc/archsignal.h | 13 - klibc/include/arch/ppc64/klibc/archstat.h | 25 - klibc/include/arch/ppc64/klibc/archsys.h | 52 - klibc/include/arch/s390/klibc/archsetjmp.h | 15 - klibc/include/arch/s390/klibc/archsignal.h | 13 - klibc/include/arch/s390/klibc/archstat.h | 31 - klibc/include/arch/s390/klibc/archsys.h | 41 - klibc/include/arch/s390x/klibc/archsetjmp.h | 15 - klibc/include/arch/s390x/klibc/archsignal.h | 13 - klibc/include/arch/s390x/klibc/archstat.h | 24 - klibc/include/arch/s390x/klibc/archsys.h | 41 - klibc/include/arch/sh/klibc/archsetjmp.h | 22 - klibc/include/arch/sh/klibc/archsignal.h | 13 - klibc/include/arch/sh/klibc/archstat.h | 45 - klibc/include/arch/sh/klibc/archsys.h | 12 - klibc/include/arch/sparc/klibc/archsetjmp.h | 16 - klibc/include/arch/sparc/klibc/archsignal.h | 38 - klibc/include/arch/sparc/klibc/archstat.h | 35 - klibc/include/arch/sparc/klibc/archsys.h | 10 - klibc/include/arch/sparc/machine/asm.h | 192 --- klibc/include/arch/sparc/machine/frame.h | 138 -- klibc/include/arch/sparc/machine/trap.h | 141 -- klibc/include/arch/sparc64/klibc/archsetjmp.h | 16 - klibc/include/arch/sparc64/klibc/archsignal.h | 13 - klibc/include/arch/sparc64/klibc/archstat.h | 22 - klibc/include/arch/sparc64/klibc/archsys.h | 10 - klibc/include/arch/x86_64/klibc/archsetjmp.h | 21 - klibc/include/arch/x86_64/klibc/archsignal.h | 17 - klibc/include/arch/x86_64/klibc/archstat.h | 26 - klibc/include/arch/x86_64/klibc/archsys.h | 109 -- klibc/include/arch/x86_64/sys/io.h | 126 -- klibc/include/arpa/inet.h | 24 - klibc/include/assert.h | 22 - klibc/include/bits32/bitsize.h | 3 - klibc/include/bits32/bitsize/limits.h | 14 - klibc/include/bits32/bitsize/stddef.h | 18 - klibc/include/bits32/bitsize/stdint.h | 34 - klibc/include/bits32/bitsize/stdintconst.h | 18 - klibc/include/bits32/bitsize/stdintlimits.h | 22 - klibc/include/bits64/bitsize.h | 3 - klibc/include/bits64/bitsize/limits.h | 14 - klibc/include/bits64/bitsize/stddef.h | 13 - klibc/include/bits64/bitsize/stdint.h | 36 - klibc/include/bits64/bitsize/stdintconst.h | 18 - klibc/include/bits64/bitsize/stdintlimits.h | 22 - klibc/include/ctype.h | 119 -- klibc/include/dirent.h | 32 - klibc/include/elf.h | 12 - klibc/include/endian.h | 42 - klibc/include/errno.h | 8 - klibc/include/fcntl.h | 46 - klibc/include/grp.h | 13 - klibc/include/inttypes.h | 226 --- klibc/include/klibc/compiler.h | 123 -- klibc/include/klibc/diverr.h | 16 - klibc/include/klibc/extern.h | 16 - klibc/include/klibc/sysconfig.h | 34 - klibc/include/limits.h | 40 - klibc/include/malloc.h | 21 - klibc/include/net/if.h | 1 - klibc/include/net/if_arp.h | 1 - klibc/include/net/if_packet.h | 1 - klibc/include/net/route.h | 1 - klibc/include/netinet/if_ether.h | 1 - klibc/include/netinet/in.h | 39 - klibc/include/netinet/in6.h | 10 - klibc/include/netinet/ip.h | 13 - klibc/include/netinet/tcp.h | 11 - klibc/include/netinet/udp.h | 19 - klibc/include/netpacket/packet.h | 1 - klibc/include/paths.h | 74 - klibc/include/poll.h | 16 - klibc/include/sched.h | 36 - klibc/include/setjmp.h | 43 - klibc/include/signal.h | 88 - klibc/include/stdarg.h | 14 - klibc/include/stddef.h | 24 - klibc/include/stdint.h | 116 -- klibc/include/stdio.h | 125 -- klibc/include/stdlib.h | 89 - klibc/include/string.h | 46 - klibc/include/sys/dirent.h | 21 - klibc/include/sys/elf32.h | 115 -- klibc/include/sys/elf64.h | 115 -- klibc/include/sys/elfcommon.h | 188 --- klibc/include/sys/fsuid.h | 14 - klibc/include/sys/inotify.h | 16 - klibc/include/sys/ioctl.h | 14 - klibc/include/sys/klog.h | 24 - klibc/include/sys/mman.h | 25 - klibc/include/sys/mount.h | 72 - klibc/include/sys/param.h | 11 - klibc/include/sys/reboot.h | 25 - klibc/include/sys/resource.h | 15 - klibc/include/sys/select.h | 14 - klibc/include/sys/socket.h | 50 - klibc/include/sys/socketcalls.h | 28 - klibc/include/sys/stat.h | 31 - klibc/include/sys/statfs.h | 1 - klibc/include/sys/syscall.h | 17 - klibc/include/sys/sysinfo.h | 12 - klibc/include/sys/sysmacros.h | 31 - klibc/include/sys/time.h | 18 - klibc/include/sys/times.h | 14 - klibc/include/sys/types.h | 104 -- klibc/include/sys/uio.h | 15 - klibc/include/sys/un.h | 10 - klibc/include/sys/utime.h | 10 - klibc/include/sys/utsname.h | 23 - klibc/include/sys/vfs.h | 112 -- klibc/include/sys/wait.h | 28 - klibc/include/syslog.h | 64 - klibc/include/termios.h | 86 - klibc/include/time.h | 18 - klibc/include/unistd.h | 140 -- klibc/include/utime.h | 15 - klibc/klcc.1 | 116 -- klibc/klcc.in | 258 --- klibc/klibc.spec.in | 126 -- klibc/klibc/CAVEATS | 61 - klibc/klibc/Kbuild | 149 -- klibc/klibc/LICENSE | 73 - klibc/klibc/MCONFIG | 20 - klibc/klibc/Makefile | 192 --- klibc/klibc/README | 81 - klibc/klibc/SOCKETCALLS.def | 21 - klibc/klibc/SYSCALLS.def | 231 --- klibc/klibc/__put_env.c | 60 - klibc/klibc/__shared_init.c | 2 - klibc/klibc/__signal.c | 22 - klibc/klibc/__static_init.c | 2 - klibc/klibc/abort.c | 19 - klibc/klibc/alarm.c | 25 - klibc/klibc/arch/README | 67 - klibc/klibc/arch/alpha/MCONFIG | 17 - klibc/klibc/arch/alpha/Makefile.inc | 95 -- klibc/klibc/arch/alpha/README-gcc | 23 - klibc/klibc/arch/alpha/crt0.S | 22 - klibc/klibc/arch/alpha/divide.c | 57 - klibc/klibc/arch/alpha/pipe.c | 28 - klibc/klibc/arch/alpha/setjmp.S | 77 - klibc/klibc/arch/alpha/syscall.S | 26 - klibc/klibc/arch/alpha/sysdual.S | 33 - klibc/klibc/arch/alpha/sysstub.ph | 37 - klibc/klibc/arch/arm/MCONFIG | 26 - klibc/klibc/arch/arm/Makefile.inc | 43 - klibc/klibc/arch/arm/crt0.S | 23 - klibc/klibc/arch/arm/setjmp-arm.S | 39 - klibc/klibc/arch/arm/setjmp-thumb.S | 58 - klibc/klibc/arch/arm/syscall.S | 50 - klibc/klibc/arch/arm/sysstub.ph | 44 - klibc/klibc/arch/cris/MCONFIG | 26 - klibc/klibc/arch/cris/Makefile.inc | 33 - klibc/klibc/arch/cris/__negdi2.S | 25 - klibc/klibc/arch/cris/crt0.S | 28 - klibc/klibc/arch/cris/divide.c | 92 - klibc/klibc/arch/cris/setjmp.S | 37 - klibc/klibc/arch/cris/syscall.S | 30 - klibc/klibc/arch/cris/sysstub.ph | 29 - klibc/klibc/arch/i386/MCONFIG | 33 - klibc/klibc/arch/i386/Makefile.inc | 28 - klibc/klibc/arch/i386/crt0.S | 32 - klibc/klibc/arch/i386/exits.S | 45 - klibc/klibc/arch/i386/libgcc/__ashldi3.S | 29 - klibc/klibc/arch/i386/libgcc/__ashrdi3.S | 29 - klibc/klibc/arch/i386/libgcc/__lshrdi3.S | 29 - klibc/klibc/arch/i386/libgcc/__muldi3.S | 34 - klibc/klibc/arch/i386/libgcc/__negdi2.S | 21 - klibc/klibc/arch/i386/open.S | 29 - klibc/klibc/arch/i386/setjmp.S | 58 - klibc/klibc/arch/i386/sigreturn.S | 15 - klibc/klibc/arch/i386/socketcall.S | 42 - klibc/klibc/arch/i386/syscall.S | 60 - klibc/klibc/arch/i386/sysstub.ph | 32 - klibc/klibc/arch/ia64/MCONFIG | 11 - klibc/klibc/arch/ia64/Makefile.inc | 26 - klibc/klibc/arch/ia64/crt0.S | 27 - klibc/klibc/arch/ia64/pipe.c | 42 - klibc/klibc/arch/ia64/setjmp.S | 343 ---- klibc/klibc/arch/ia64/syscall.S | 20 - klibc/klibc/arch/ia64/sysstub.ph | 29 - klibc/klibc/arch/ia64/vfork.S | 42 - klibc/klibc/arch/m32r/MCONFIG | 18 - klibc/klibc/arch/m32r/Makefile.inc | 19 - klibc/klibc/arch/m32r/crt0.S | 25 - klibc/klibc/arch/m32r/setjmp.S | 47 - klibc/klibc/arch/m32r/syscall.S | 29 - klibc/klibc/arch/m32r/sysstub.ph | 25 - klibc/klibc/arch/m68k/MCONFIG | 11 - klibc/klibc/arch/m68k/Makefile.inc | 10 - klibc/klibc/arch/mips/MCONFIG | 15 - klibc/klibc/arch/mips/Makefile.inc | 25 - klibc/klibc/arch/mips/crt0.S | 25 - klibc/klibc/arch/mips/klibc.ld | 217 --- klibc/klibc/arch/mips/pipe.S | 16 - klibc/klibc/arch/mips/setjmp.S | 82 - klibc/klibc/arch/mips/syscall.S | 15 - klibc/klibc/arch/mips/sysstub.ph | 30 - klibc/klibc/arch/mips/vfork.S | 16 - klibc/klibc/arch/mips64/MCONFIG | 11 - klibc/klibc/arch/mips64/Makefile.inc | 10 - klibc/klibc/arch/parisc/MCONFIG | 11 - klibc/klibc/arch/parisc/Makefile.inc | 19 - klibc/klibc/arch/parisc/crt0.S | 34 - klibc/klibc/arch/parisc/setjmp.S | 88 - klibc/klibc/arch/parisc/syscall.c | 29 - klibc/klibc/arch/parisc/sysstub.ph | 28 - klibc/klibc/arch/ppc/MCONFIG | 18 - klibc/klibc/arch/ppc/Makefile.inc | 22 - klibc/klibc/arch/ppc/crt0.S | 20 - klibc/klibc/arch/ppc/setjmp.S | 35 - klibc/klibc/arch/ppc/syscall.S | 16 - klibc/klibc/arch/ppc/sysstub.ph | 25 - klibc/klibc/arch/ppc64/MCONFIG | 20 - klibc/klibc/arch/ppc64/Makefile.inc | 25 - klibc/klibc/arch/ppc64/crt0.S | 32 - klibc/klibc/arch/ppc64/setjmp.S | 85 - klibc/klibc/arch/ppc64/syscall.c | 14 - klibc/klibc/arch/ppc64/sysstub.ph | 31 - klibc/klibc/arch/s390/MCONFIG | 13 - klibc/klibc/arch/s390/Makefile.inc | 23 - klibc/klibc/arch/s390/crt0.S | 25 - klibc/klibc/arch/s390/mmap.c | 41 - klibc/klibc/arch/s390/setjmp.S | 32 - klibc/klibc/arch/s390/syscall.c | 16 - klibc/klibc/arch/s390/sysstub.ph | 31 - klibc/klibc/arch/s390x/MCONFIG | 13 - klibc/klibc/arch/s390x/Makefile.inc | 18 - klibc/klibc/arch/s390x/crt0.S | 21 - klibc/klibc/arch/s390x/mmap.c | 41 - klibc/klibc/arch/s390x/setjmp.S | 36 - klibc/klibc/arch/s390x/syscall.c | 16 - klibc/klibc/arch/s390x/sysstub.ph | 28 - klibc/klibc/arch/sh/MCONFIG | 19 - klibc/klibc/arch/sh/Makefile.inc | 15 - klibc/klibc/arch/sh/crt0.S | 27 - klibc/klibc/arch/sh/setjmp.S | 65 - klibc/klibc/arch/sh/syscall.S | 35 - klibc/klibc/arch/sh/sysstub.ph | 34 - klibc/klibc/arch/sparc/MCONFIG | 18 - klibc/klibc/arch/sparc/Makefile.inc | 51 - klibc/klibc/arch/sparc/crt0.S | 2 - klibc/klibc/arch/sparc/crt0i.S | 100 -- klibc/klibc/arch/sparc/divrem.m4 | 276 --- klibc/klibc/arch/sparc/setjmp.S | 38 - klibc/klibc/arch/sparc/smul.S | 160 -- klibc/klibc/arch/sparc/syscall.S | 19 - klibc/klibc/arch/sparc/sysfork.S | 25 - klibc/klibc/arch/sparc/sysstub.ph | 25 - klibc/klibc/arch/sparc/umul.S | 193 --- klibc/klibc/arch/sparc64/MCONFIG | 21 - klibc/klibc/arch/sparc64/Makefile.inc | 15 - klibc/klibc/arch/sparc64/crt0.S | 2 - klibc/klibc/arch/sparc64/setjmp.S | 55 - klibc/klibc/arch/sparc64/syscall.S | 18 - klibc/klibc/arch/sparc64/sysfork.S | 26 - klibc/klibc/arch/sparc64/sysstub.ph | 25 - klibc/klibc/arch/x86_64/MCONFIG | 36 - klibc/klibc/arch/x86_64/Makefile.inc | 18 - klibc/klibc/arch/x86_64/crt0.S | 22 - klibc/klibc/arch/x86_64/exits.S | 35 - klibc/klibc/arch/x86_64/setjmp.S | 54 - klibc/klibc/arch/x86_64/sigreturn.S | 15 - klibc/klibc/arch/x86_64/syscall.S | 28 - klibc/klibc/arch/x86_64/sysstub.ph | 23 - klibc/klibc/asprintf.c | 30 - klibc/klibc/assert.c | 13 - klibc/klibc/atexit.c | 10 - klibc/klibc/atexit.h | 17 - klibc/klibc/atoi.c | 3 - klibc/klibc/atol.c | 3 - klibc/klibc/atoll.c | 3 - klibc/klibc/atox.c | 14 - klibc/klibc/brk.c | 24 - klibc/klibc/bsd_signal.c | 11 - klibc/klibc/calloc.c | 21 - klibc/klibc/closelog.c | 18 - klibc/klibc/creat.c | 12 - klibc/klibc/ctypes.c | 284 ---- klibc/klibc/daemon.c | 38 - klibc/klibc/exec_l.c | 57 - klibc/klibc/execl.c | 8 - klibc/klibc/execle.c | 8 - klibc/klibc/execlp.c | 8 - klibc/klibc/execlpe.c | 8 - klibc/klibc/execv.c | 13 - klibc/klibc/execvp.c | 13 - klibc/klibc/execvpe.c | 75 - klibc/klibc/exitc.c | 23 - klibc/klibc/fgetc.c | 20 - klibc/klibc/fgets.c | 34 - klibc/klibc/fopen.c | 40 - klibc/klibc/fork.c | 20 - klibc/klibc/fprintf.c | 19 - klibc/klibc/fputc.c | 14 - klibc/klibc/fputs.c | 15 - klibc/klibc/fread.c | 36 - klibc/klibc/fread2.c | 13 - klibc/klibc/fstatfs.c | 19 - klibc/klibc/fwrite.c | 36 - klibc/klibc/fwrite2.c | 13 - klibc/klibc/getcwd.c | 16 - klibc/klibc/getdomainname.c | 25 - klibc/klibc/getenv.c | 22 - klibc/klibc/gethostname.c | 25 - klibc/klibc/getopt.c | 75 - klibc/klibc/getpgrp.c | 9 - klibc/klibc/getpriority.c | 23 - klibc/klibc/getpt.c | 17 - klibc/klibc/globals.c | 10 - klibc/klibc/inet/bindresvport.c | 45 - klibc/klibc/inet/inet_addr.c | 14 - klibc/klibc/inet/inet_aton.c | 23 - klibc/klibc/inet/inet_ntoa.c | 19 - klibc/klibc/inet/inet_ntop.c | 52 - klibc/klibc/inet/inet_pton.c | 74 - klibc/klibc/interp.S | 13 - klibc/klibc/isatty.c | 21 - klibc/klibc/jrand48.c | 24 - klibc/klibc/libc_init.c | 86 - klibc/klibc/libgcc/__divdi3.c | 29 - klibc/klibc/libgcc/__divsi3.c | 29 - klibc/klibc/libgcc/__moddi3.c | 29 - klibc/klibc/libgcc/__modsi3.c | 29 - klibc/klibc/libgcc/__udivdi3.c | 13 - klibc/klibc/libgcc/__udivmoddi4.c | 32 - klibc/klibc/libgcc/__udivmodsi4.c | 32 - klibc/klibc/libgcc/__udivsi3.c | 13 - klibc/klibc/libgcc/__umoddi3.c | 16 - klibc/klibc/libgcc/__umodsi3.c | 16 - klibc/klibc/llseek.c | 30 - klibc/klibc/lrand48.c | 14 - klibc/klibc/makeerrlist.pl | 100 -- klibc/klibc/malloc.c | 197 --- klibc/klibc/malloc.h | 45 - klibc/klibc/memccpy.c | 23 - klibc/klibc/memchr.c | 19 - klibc/klibc/memcmp.c | 19 - klibc/klibc/memcpy.c | 29 - klibc/klibc/memmem.c | 52 - klibc/klibc/memmove.c | 34 - klibc/klibc/memrchr.c | 20 - klibc/klibc/memset.c | 30 - klibc/klibc/memswap.c | 23 - klibc/klibc/mmap.c | 49 - klibc/klibc/mrand48.c | 13 - klibc/klibc/nice.c | 18 - klibc/klibc/nrand48.c | 11 - klibc/klibc/onexit.c | 39 - klibc/klibc/open.c | 22 - klibc/klibc/pause.c | 17 - klibc/klibc/perror.c | 13 - klibc/klibc/printf.c | 19 - klibc/klibc/pty.c | 31 - klibc/klibc/putchar.c | 15 - klibc/klibc/putenv.c | 40 - klibc/klibc/puts.c | 13 - klibc/klibc/qsort.c | 42 - klibc/klibc/raise.c | 11 - klibc/klibc/readdir.c | 57 - klibc/klibc/realloc.c | 49 - klibc/klibc/reboot.c | 15 - klibc/klibc/recv.c | 11 - klibc/klibc/sbrk.c | 41 - klibc/klibc/seed48.c | 19 - klibc/klibc/send.c | 11 - klibc/klibc/setegid.c | 10 - klibc/klibc/setenv.c | 45 - klibc/klibc/seteuid.c | 10 - klibc/klibc/setpgrp.c | 10 - klibc/klibc/sha1hash.c | 317 ---- klibc/klibc/sigaction.c | 44 - klibc/klibc/siglist.c | 115 -- klibc/klibc/siglongjmp.c | 16 - klibc/klibc/sigpending.c | 17 - klibc/klibc/sigprocmask.c | 17 - klibc/klibc/sigsuspend.c | 17 - klibc/klibc/sleep.c | 20 - klibc/klibc/snprintf.c | 16 - klibc/klibc/socketcalls.pl | 88 - klibc/klibc/socketcommon.h | 16 - klibc/klibc/sprintf.c | 18 - klibc/klibc/srand48.c | 15 - klibc/klibc/sscanf.c | 17 - klibc/klibc/statfs.c | 19 - klibc/klibc/strcasecmp.c | 23 - klibc/klibc/strcat.c | 11 - klibc/klibc/strchr.c | 19 - klibc/klibc/strcmp.c | 20 - klibc/klibc/strcpy.c | 20 - klibc/klibc/strcspn.c | 11 - klibc/klibc/strdup.c | 17 - klibc/klibc/strerror.c | 34 - klibc/klibc/strlcat.c | 33 - klibc/klibc/strlcpy.c | 29 - klibc/klibc/strlen.c | 14 - klibc/klibc/strncasecmp.c | 23 - klibc/klibc/strncat.c | 22 - klibc/klibc/strncmp.c | 20 - klibc/klibc/strncpy.c | 24 - klibc/klibc/strndup.c | 17 - klibc/klibc/strnlen.c | 19 - klibc/klibc/strntoimax.c | 13 - klibc/klibc/strntoumax.c | 76 - klibc/klibc/strpbrk.c | 14 - klibc/klibc/strrchr.c | 21 - klibc/klibc/strsep.c | 21 - klibc/klibc/strspn.c | 11 - klibc/klibc/strstr.c | 10 - klibc/klibc/strtoimax.c | 3 - klibc/klibc/strtok.c | 16 - klibc/klibc/strtol.c | 3 - klibc/klibc/strtoll.c | 3 - klibc/klibc/strtotimespec.c | 5 - klibc/klibc/strtotimeval.c | 5 - klibc/klibc/strtotimex.c | 39 - klibc/klibc/strtoul.c | 3 - klibc/klibc/strtoull.c | 3 - klibc/klibc/strtoumax.c | 3 - klibc/klibc/strtox.c | 13 - klibc/klibc/strxspn.c | 30 - klibc/klibc/strxspn.h | 13 - klibc/klibc/syscalls.pl | 120 -- klibc/klibc/syscommon.h | 32 - klibc/klibc/syslog.c | 87 - klibc/klibc/system.c | 61 - klibc/klibc/sysv_signal.c | 11 - klibc/klibc/time.c | 23 - klibc/klibc/umount.c | 12 - klibc/klibc/unsetenv.c | 40 - klibc/klibc/usleep.c | 15 - klibc/klibc/utime.c | 24 - klibc/klibc/vasprintf.c | 25 - klibc/klibc/vfprintf.c | 26 - klibc/klibc/vprintf.c | 11 - klibc/klibc/vsnprintf.c | 433 ----- klibc/klibc/vsprintf.c | 11 - klibc/klibc/vsscanf.c | 365 ---- klibc/klibc/wait.c | 12 - klibc/klibc/wait3.c | 12 - klibc/klibc/waitpid.c | 12 - klibc/klibc/zlib/FAQ | 315 ---- klibc/klibc/zlib/INDEX | 48 - klibc/klibc/zlib/README | 126 -- klibc/klibc/zlib/adler32.c | 74 - klibc/klibc/zlib/algorithm.txt | 209 --- klibc/klibc/zlib/compress.c | 79 - klibc/klibc/zlib/crc32.c | 311 ---- klibc/klibc/zlib/crc32.h | 441 ----- klibc/klibc/zlib/deflate.c | 1502 ----------------- klibc/klibc/zlib/deflate.h | 326 ---- klibc/klibc/zlib/gzio.c | 1008 ----------- klibc/klibc/zlib/infback.c | 619 ------- klibc/klibc/zlib/inffast.c | 305 ---- klibc/klibc/zlib/inffast.h | 11 - klibc/klibc/zlib/inffixed.h | 94 -- klibc/klibc/zlib/inflate.c | 1270 -------------- klibc/klibc/zlib/inflate.h | 117 -- klibc/klibc/zlib/inftrees.c | 321 ---- klibc/klibc/zlib/inftrees.h | 55 - klibc/klibc/zlib/trees.c | 1215 ------------- klibc/klibc/zlib/trees.h | 128 -- klibc/klibc/zlib/uncompr.c | 61 - klibc/klibc/zlib/zconf.h | 323 ---- klibc/klibc/zlib/zconf.in.h | 323 ---- klibc/klibc/zlib/zlib.3 | 159 -- klibc/klibc/zlib/zlib.h | 1200 ------------- klibc/klibc/zlib/zutil.c | 319 ---- klibc/klibc/zlib/zutil.h | 258 --- klibc/makeklcc.pl | 55 - klibc/version | 1 - test/simple-build-check.sh | 15 +- 532 files changed, 25 insertions(+), 30176 deletions(-) delete mode 100644 klibc/MCONFIG delete mode 100644 klibc/MRULES delete mode 100644 klibc/Makefile delete mode 100644 klibc/README delete mode 100644 klibc/include/alloca.h delete mode 100644 klibc/include/arch/alpha/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/alpha/klibc/archsignal.h delete mode 100644 klibc/include/arch/alpha/klibc/archstat.h delete mode 100644 klibc/include/arch/alpha/klibc/archsys.h delete mode 100644 klibc/include/arch/alpha/machine/asm.h delete mode 100644 klibc/include/arch/arm/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/arm/klibc/archsignal.h delete mode 100644 klibc/include/arch/arm/klibc/archstat.h delete mode 100644 klibc/include/arch/arm/klibc/archsys.h delete mode 100644 klibc/include/arch/cris/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/cris/klibc/archsignal.h delete mode 100644 klibc/include/arch/cris/klibc/archstat.h delete mode 100644 klibc/include/arch/cris/klibc/archsys.h delete mode 100644 klibc/include/arch/i386/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/i386/klibc/archsignal.h delete mode 100644 klibc/include/arch/i386/klibc/archstat.h delete mode 100644 klibc/include/arch/i386/klibc/archsys.h delete mode 100644 klibc/include/arch/i386/klibc/diverr.h delete mode 100644 klibc/include/arch/i386/sys/io.h delete mode 100644 klibc/include/arch/i386/sys/vm86.h delete mode 100644 klibc/include/arch/ia64/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/ia64/klibc/archsignal.h delete mode 100644 klibc/include/arch/ia64/klibc/archstat.h delete mode 100644 klibc/include/arch/ia64/klibc/archsys.h delete mode 100644 klibc/include/arch/m32r/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/m32r/klibc/archsignal.h delete mode 100644 klibc/include/arch/m32r/klibc/archstat.h delete mode 100644 klibc/include/arch/m32r/klibc/archsys.h delete mode 100644 klibc/include/arch/m68k/klibc/archsignal.h delete mode 100644 klibc/include/arch/m68k/klibc/archstat.h delete mode 100644 klibc/include/arch/m68k/klibc/archsys.h delete mode 100644 klibc/include/arch/mips/klibc/archfcntl.h delete mode 100644 klibc/include/arch/mips/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/mips/klibc/archsignal.h delete mode 100644 klibc/include/arch/mips/klibc/archstat.h delete mode 100644 klibc/include/arch/mips/klibc/archsys.h delete mode 100644 klibc/include/arch/mips/machine/asm.h delete mode 100644 klibc/include/arch/mips/sgidefs.h delete mode 100644 klibc/include/arch/mips/spaces.h delete mode 100644 klibc/include/arch/mips64/klibc/archsignal.h delete mode 100644 klibc/include/arch/mips64/klibc/archstat.h delete mode 100644 klibc/include/arch/mips64/klibc/archsys.h delete mode 100644 klibc/include/arch/parisc/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/parisc/klibc/archsignal.h delete mode 100644 klibc/include/arch/parisc/klibc/archstat.h delete mode 100644 klibc/include/arch/parisc/klibc/archsys.h delete mode 100644 klibc/include/arch/ppc/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/ppc/klibc/archsignal.h delete mode 100644 klibc/include/arch/ppc/klibc/archstat.h delete mode 100644 klibc/include/arch/ppc/klibc/archsys.h delete mode 100644 klibc/include/arch/ppc64/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/ppc64/klibc/archsignal.h delete mode 100644 klibc/include/arch/ppc64/klibc/archstat.h delete mode 100644 klibc/include/arch/ppc64/klibc/archsys.h delete mode 100644 klibc/include/arch/s390/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/s390/klibc/archsignal.h delete mode 100644 klibc/include/arch/s390/klibc/archstat.h delete mode 100644 klibc/include/arch/s390/klibc/archsys.h delete mode 100644 klibc/include/arch/s390x/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/s390x/klibc/archsignal.h delete mode 100644 klibc/include/arch/s390x/klibc/archstat.h delete mode 100644 klibc/include/arch/s390x/klibc/archsys.h delete mode 100644 klibc/include/arch/sh/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/sh/klibc/archsignal.h delete mode 100644 klibc/include/arch/sh/klibc/archstat.h delete mode 100644 klibc/include/arch/sh/klibc/archsys.h delete mode 100644 klibc/include/arch/sparc/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/sparc/klibc/archsignal.h delete mode 100644 klibc/include/arch/sparc/klibc/archstat.h delete mode 100644 klibc/include/arch/sparc/klibc/archsys.h delete mode 100644 klibc/include/arch/sparc/machine/asm.h delete mode 100644 klibc/include/arch/sparc/machine/frame.h delete mode 100644 klibc/include/arch/sparc/machine/trap.h delete mode 100644 klibc/include/arch/sparc64/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/sparc64/klibc/archsignal.h delete mode 100644 klibc/include/arch/sparc64/klibc/archstat.h delete mode 100644 klibc/include/arch/sparc64/klibc/archsys.h delete mode 100644 klibc/include/arch/x86_64/klibc/archsetjmp.h delete mode 100644 klibc/include/arch/x86_64/klibc/archsignal.h delete mode 100644 klibc/include/arch/x86_64/klibc/archstat.h delete mode 100644 klibc/include/arch/x86_64/klibc/archsys.h delete mode 100644 klibc/include/arch/x86_64/sys/io.h delete mode 100644 klibc/include/arpa/inet.h delete mode 100644 klibc/include/assert.h delete mode 100644 klibc/include/bits32/bitsize.h delete mode 100644 klibc/include/bits32/bitsize/limits.h delete mode 100644 klibc/include/bits32/bitsize/stddef.h delete mode 100644 klibc/include/bits32/bitsize/stdint.h delete mode 100644 klibc/include/bits32/bitsize/stdintconst.h delete mode 100644 klibc/include/bits32/bitsize/stdintlimits.h delete mode 100644 klibc/include/bits64/bitsize.h delete mode 100644 klibc/include/bits64/bitsize/limits.h delete mode 100644 klibc/include/bits64/bitsize/stddef.h delete mode 100644 klibc/include/bits64/bitsize/stdint.h delete mode 100644 klibc/include/bits64/bitsize/stdintconst.h delete mode 100644 klibc/include/bits64/bitsize/stdintlimits.h delete mode 100644 klibc/include/ctype.h delete mode 100644 klibc/include/dirent.h delete mode 100644 klibc/include/elf.h delete mode 100644 klibc/include/endian.h delete mode 100644 klibc/include/errno.h delete mode 100644 klibc/include/fcntl.h delete mode 100644 klibc/include/grp.h delete mode 100644 klibc/include/inttypes.h delete mode 100644 klibc/include/klibc/compiler.h delete mode 100644 klibc/include/klibc/diverr.h delete mode 100644 klibc/include/klibc/extern.h delete mode 100644 klibc/include/klibc/sysconfig.h delete mode 100644 klibc/include/limits.h delete mode 100644 klibc/include/malloc.h delete mode 100644 klibc/include/net/if.h delete mode 100644 klibc/include/net/if_arp.h delete mode 100644 klibc/include/net/if_packet.h delete mode 100644 klibc/include/net/route.h delete mode 100644 klibc/include/netinet/if_ether.h delete mode 100644 klibc/include/netinet/in.h delete mode 100644 klibc/include/netinet/in6.h delete mode 100644 klibc/include/netinet/ip.h delete mode 100644 klibc/include/netinet/tcp.h delete mode 100644 klibc/include/netinet/udp.h delete mode 100644 klibc/include/netpacket/packet.h delete mode 100644 klibc/include/paths.h delete mode 100644 klibc/include/poll.h delete mode 100644 klibc/include/sched.h delete mode 100644 klibc/include/setjmp.h delete mode 100644 klibc/include/signal.h delete mode 100644 klibc/include/stdarg.h delete mode 100644 klibc/include/stddef.h delete mode 100644 klibc/include/stdint.h delete mode 100644 klibc/include/stdio.h delete mode 100644 klibc/include/stdlib.h delete mode 100644 klibc/include/string.h delete mode 100644 klibc/include/sys/dirent.h delete mode 100644 klibc/include/sys/elf32.h delete mode 100644 klibc/include/sys/elf64.h delete mode 100644 klibc/include/sys/elfcommon.h delete mode 100644 klibc/include/sys/fsuid.h delete mode 100644 klibc/include/sys/inotify.h delete mode 100644 klibc/include/sys/ioctl.h delete mode 100644 klibc/include/sys/klog.h delete mode 100644 klibc/include/sys/mman.h delete mode 100644 klibc/include/sys/mount.h delete mode 100644 klibc/include/sys/param.h delete mode 100644 klibc/include/sys/reboot.h delete mode 100644 klibc/include/sys/resource.h delete mode 100644 klibc/include/sys/select.h delete mode 100644 klibc/include/sys/socket.h delete mode 100644 klibc/include/sys/socketcalls.h delete mode 100644 klibc/include/sys/stat.h delete mode 100644 klibc/include/sys/statfs.h delete mode 100644 klibc/include/sys/syscall.h delete mode 100644 klibc/include/sys/sysinfo.h delete mode 100644 klibc/include/sys/sysmacros.h delete mode 100644 klibc/include/sys/time.h delete mode 100644 klibc/include/sys/times.h delete mode 100644 klibc/include/sys/types.h delete mode 100644 klibc/include/sys/uio.h delete mode 100644 klibc/include/sys/un.h delete mode 100644 klibc/include/sys/utime.h delete mode 100644 klibc/include/sys/utsname.h delete mode 100644 klibc/include/sys/vfs.h delete mode 100644 klibc/include/sys/wait.h delete mode 100644 klibc/include/syslog.h delete mode 100644 klibc/include/termios.h delete mode 100644 klibc/include/time.h delete mode 100644 klibc/include/unistd.h delete mode 100644 klibc/include/utime.h delete mode 100644 klibc/klcc.1 delete mode 100644 klibc/klcc.in delete mode 100644 klibc/klibc.spec.in delete mode 100644 klibc/klibc/CAVEATS delete mode 100644 klibc/klibc/Kbuild delete mode 100644 klibc/klibc/LICENSE delete mode 100644 klibc/klibc/MCONFIG delete mode 100644 klibc/klibc/Makefile delete mode 100644 klibc/klibc/README delete mode 100644 klibc/klibc/SOCKETCALLS.def delete mode 100644 klibc/klibc/SYSCALLS.def delete mode 100644 klibc/klibc/__put_env.c delete mode 100644 klibc/klibc/__shared_init.c delete mode 100644 klibc/klibc/__signal.c delete mode 100644 klibc/klibc/__static_init.c delete mode 100644 klibc/klibc/abort.c delete mode 100644 klibc/klibc/alarm.c delete mode 100644 klibc/klibc/arch/README delete mode 100644 klibc/klibc/arch/alpha/MCONFIG delete mode 100644 klibc/klibc/arch/alpha/Makefile.inc delete mode 100644 klibc/klibc/arch/alpha/README-gcc delete mode 100644 klibc/klibc/arch/alpha/crt0.S delete mode 100644 klibc/klibc/arch/alpha/divide.c delete mode 100644 klibc/klibc/arch/alpha/pipe.c delete mode 100644 klibc/klibc/arch/alpha/setjmp.S delete mode 100644 klibc/klibc/arch/alpha/syscall.S delete mode 100644 klibc/klibc/arch/alpha/sysdual.S delete mode 100644 klibc/klibc/arch/alpha/sysstub.ph delete mode 100644 klibc/klibc/arch/arm/MCONFIG delete mode 100644 klibc/klibc/arch/arm/Makefile.inc delete mode 100644 klibc/klibc/arch/arm/crt0.S delete mode 100644 klibc/klibc/arch/arm/setjmp-arm.S delete mode 100644 klibc/klibc/arch/arm/setjmp-thumb.S delete mode 100644 klibc/klibc/arch/arm/syscall.S delete mode 100644 klibc/klibc/arch/arm/sysstub.ph delete mode 100644 klibc/klibc/arch/cris/MCONFIG delete mode 100644 klibc/klibc/arch/cris/Makefile.inc delete mode 100644 klibc/klibc/arch/cris/__negdi2.S delete mode 100644 klibc/klibc/arch/cris/crt0.S delete mode 100644 klibc/klibc/arch/cris/divide.c delete mode 100644 klibc/klibc/arch/cris/setjmp.S delete mode 100644 klibc/klibc/arch/cris/syscall.S delete mode 100644 klibc/klibc/arch/cris/sysstub.ph delete mode 100644 klibc/klibc/arch/i386/MCONFIG delete mode 100644 klibc/klibc/arch/i386/Makefile.inc delete mode 100644 klibc/klibc/arch/i386/crt0.S delete mode 100644 klibc/klibc/arch/i386/exits.S delete mode 100644 klibc/klibc/arch/i386/libgcc/__ashldi3.S delete mode 100644 klibc/klibc/arch/i386/libgcc/__ashrdi3.S delete mode 100644 klibc/klibc/arch/i386/libgcc/__lshrdi3.S delete mode 100644 klibc/klibc/arch/i386/libgcc/__muldi3.S delete mode 100644 klibc/klibc/arch/i386/libgcc/__negdi2.S delete mode 100644 klibc/klibc/arch/i386/open.S delete mode 100644 klibc/klibc/arch/i386/setjmp.S delete mode 100644 klibc/klibc/arch/i386/sigreturn.S delete mode 100644 klibc/klibc/arch/i386/socketcall.S delete mode 100644 klibc/klibc/arch/i386/syscall.S delete mode 100644 klibc/klibc/arch/i386/sysstub.ph delete mode 100644 klibc/klibc/arch/ia64/MCONFIG delete mode 100644 klibc/klibc/arch/ia64/Makefile.inc delete mode 100644 klibc/klibc/arch/ia64/crt0.S delete mode 100644 klibc/klibc/arch/ia64/pipe.c delete mode 100644 klibc/klibc/arch/ia64/setjmp.S delete mode 100644 klibc/klibc/arch/ia64/syscall.S delete mode 100644 klibc/klibc/arch/ia64/sysstub.ph delete mode 100644 klibc/klibc/arch/ia64/vfork.S delete mode 100644 klibc/klibc/arch/m32r/MCONFIG delete mode 100644 klibc/klibc/arch/m32r/Makefile.inc delete mode 100644 klibc/klibc/arch/m32r/crt0.S delete mode 100644 klibc/klibc/arch/m32r/setjmp.S delete mode 100644 klibc/klibc/arch/m32r/syscall.S delete mode 100644 klibc/klibc/arch/m32r/sysstub.ph delete mode 100644 klibc/klibc/arch/m68k/MCONFIG delete mode 100644 klibc/klibc/arch/m68k/Makefile.inc delete mode 100644 klibc/klibc/arch/mips/MCONFIG delete mode 100644 klibc/klibc/arch/mips/Makefile.inc delete mode 100644 klibc/klibc/arch/mips/crt0.S delete mode 100644 klibc/klibc/arch/mips/klibc.ld delete mode 100644 klibc/klibc/arch/mips/pipe.S delete mode 100644 klibc/klibc/arch/mips/setjmp.S delete mode 100644 klibc/klibc/arch/mips/syscall.S delete mode 100644 klibc/klibc/arch/mips/sysstub.ph delete mode 100644 klibc/klibc/arch/mips/vfork.S delete mode 100644 klibc/klibc/arch/mips64/MCONFIG delete mode 100644 klibc/klibc/arch/mips64/Makefile.inc delete mode 100644 klibc/klibc/arch/parisc/MCONFIG delete mode 100644 klibc/klibc/arch/parisc/Makefile.inc delete mode 100644 klibc/klibc/arch/parisc/crt0.S delete mode 100644 klibc/klibc/arch/parisc/setjmp.S delete mode 100644 klibc/klibc/arch/parisc/syscall.c delete mode 100644 klibc/klibc/arch/parisc/sysstub.ph delete mode 100644 klibc/klibc/arch/ppc/MCONFIG delete mode 100644 klibc/klibc/arch/ppc/Makefile.inc delete mode 100644 klibc/klibc/arch/ppc/crt0.S delete mode 100644 klibc/klibc/arch/ppc/setjmp.S delete mode 100644 klibc/klibc/arch/ppc/syscall.S delete mode 100644 klibc/klibc/arch/ppc/sysstub.ph delete mode 100644 klibc/klibc/arch/ppc64/MCONFIG delete mode 100644 klibc/klibc/arch/ppc64/Makefile.inc delete mode 100644 klibc/klibc/arch/ppc64/crt0.S delete mode 100644 klibc/klibc/arch/ppc64/setjmp.S delete mode 100644 klibc/klibc/arch/ppc64/syscall.c delete mode 100644 klibc/klibc/arch/ppc64/sysstub.ph delete mode 100644 klibc/klibc/arch/s390/MCONFIG delete mode 100644 klibc/klibc/arch/s390/Makefile.inc delete mode 100644 klibc/klibc/arch/s390/crt0.S delete mode 100644 klibc/klibc/arch/s390/mmap.c delete mode 100644 klibc/klibc/arch/s390/setjmp.S delete mode 100644 klibc/klibc/arch/s390/syscall.c delete mode 100644 klibc/klibc/arch/s390/sysstub.ph delete mode 100644 klibc/klibc/arch/s390x/MCONFIG delete mode 100644 klibc/klibc/arch/s390x/Makefile.inc delete mode 100644 klibc/klibc/arch/s390x/crt0.S delete mode 100644 klibc/klibc/arch/s390x/mmap.c delete mode 100644 klibc/klibc/arch/s390x/setjmp.S delete mode 100644 klibc/klibc/arch/s390x/syscall.c delete mode 100644 klibc/klibc/arch/s390x/sysstub.ph delete mode 100644 klibc/klibc/arch/sh/MCONFIG delete mode 100644 klibc/klibc/arch/sh/Makefile.inc delete mode 100644 klibc/klibc/arch/sh/crt0.S delete mode 100644 klibc/klibc/arch/sh/setjmp.S delete mode 100644 klibc/klibc/arch/sh/syscall.S delete mode 100644 klibc/klibc/arch/sh/sysstub.ph delete mode 100644 klibc/klibc/arch/sparc/MCONFIG delete mode 100644 klibc/klibc/arch/sparc/Makefile.inc delete mode 100644 klibc/klibc/arch/sparc/crt0.S delete mode 100644 klibc/klibc/arch/sparc/crt0i.S delete mode 100644 klibc/klibc/arch/sparc/divrem.m4 delete mode 100644 klibc/klibc/arch/sparc/setjmp.S delete mode 100644 klibc/klibc/arch/sparc/smul.S delete mode 100644 klibc/klibc/arch/sparc/syscall.S delete mode 100644 klibc/klibc/arch/sparc/sysfork.S delete mode 100644 klibc/klibc/arch/sparc/sysstub.ph delete mode 100644 klibc/klibc/arch/sparc/umul.S delete mode 100644 klibc/klibc/arch/sparc64/MCONFIG delete mode 100644 klibc/klibc/arch/sparc64/Makefile.inc delete mode 100644 klibc/klibc/arch/sparc64/crt0.S delete mode 100644 klibc/klibc/arch/sparc64/setjmp.S delete mode 100644 klibc/klibc/arch/sparc64/syscall.S delete mode 100644 klibc/klibc/arch/sparc64/sysfork.S delete mode 100644 klibc/klibc/arch/sparc64/sysstub.ph delete mode 100644 klibc/klibc/arch/x86_64/MCONFIG delete mode 100644 klibc/klibc/arch/x86_64/Makefile.inc delete mode 100644 klibc/klibc/arch/x86_64/crt0.S delete mode 100644 klibc/klibc/arch/x86_64/exits.S delete mode 100644 klibc/klibc/arch/x86_64/setjmp.S delete mode 100644 klibc/klibc/arch/x86_64/sigreturn.S delete mode 100644 klibc/klibc/arch/x86_64/syscall.S delete mode 100644 klibc/klibc/arch/x86_64/sysstub.ph delete mode 100644 klibc/klibc/asprintf.c delete mode 100644 klibc/klibc/assert.c delete mode 100644 klibc/klibc/atexit.c delete mode 100644 klibc/klibc/atexit.h delete mode 100644 klibc/klibc/atoi.c delete mode 100644 klibc/klibc/atol.c delete mode 100644 klibc/klibc/atoll.c delete mode 100644 klibc/klibc/atox.c delete mode 100644 klibc/klibc/brk.c delete mode 100644 klibc/klibc/bsd_signal.c delete mode 100644 klibc/klibc/calloc.c delete mode 100644 klibc/klibc/closelog.c delete mode 100644 klibc/klibc/creat.c delete mode 100644 klibc/klibc/ctypes.c delete mode 100644 klibc/klibc/daemon.c delete mode 100644 klibc/klibc/exec_l.c delete mode 100644 klibc/klibc/execl.c delete mode 100644 klibc/klibc/execle.c delete mode 100644 klibc/klibc/execlp.c delete mode 100644 klibc/klibc/execlpe.c delete mode 100644 klibc/klibc/execv.c delete mode 100644 klibc/klibc/execvp.c delete mode 100644 klibc/klibc/execvpe.c delete mode 100644 klibc/klibc/exitc.c delete mode 100644 klibc/klibc/fgetc.c delete mode 100644 klibc/klibc/fgets.c delete mode 100644 klibc/klibc/fopen.c delete mode 100644 klibc/klibc/fork.c delete mode 100644 klibc/klibc/fprintf.c delete mode 100644 klibc/klibc/fputc.c delete mode 100644 klibc/klibc/fputs.c delete mode 100644 klibc/klibc/fread.c delete mode 100644 klibc/klibc/fread2.c delete mode 100644 klibc/klibc/fstatfs.c delete mode 100644 klibc/klibc/fwrite.c delete mode 100644 klibc/klibc/fwrite2.c delete mode 100644 klibc/klibc/getcwd.c delete mode 100644 klibc/klibc/getdomainname.c delete mode 100644 klibc/klibc/getenv.c delete mode 100644 klibc/klibc/gethostname.c delete mode 100644 klibc/klibc/getopt.c delete mode 100644 klibc/klibc/getpgrp.c delete mode 100644 klibc/klibc/getpriority.c delete mode 100644 klibc/klibc/getpt.c delete mode 100644 klibc/klibc/globals.c delete mode 100644 klibc/klibc/inet/bindresvport.c delete mode 100644 klibc/klibc/inet/inet_addr.c delete mode 100644 klibc/klibc/inet/inet_aton.c delete mode 100644 klibc/klibc/inet/inet_ntoa.c delete mode 100644 klibc/klibc/inet/inet_ntop.c delete mode 100644 klibc/klibc/inet/inet_pton.c delete mode 100644 klibc/klibc/interp.S delete mode 100644 klibc/klibc/isatty.c delete mode 100644 klibc/klibc/jrand48.c delete mode 100644 klibc/klibc/libc_init.c delete mode 100644 klibc/klibc/libgcc/__divdi3.c delete mode 100644 klibc/klibc/libgcc/__divsi3.c delete mode 100644 klibc/klibc/libgcc/__moddi3.c delete mode 100644 klibc/klibc/libgcc/__modsi3.c delete mode 100644 klibc/klibc/libgcc/__udivdi3.c delete mode 100644 klibc/klibc/libgcc/__udivmoddi4.c delete mode 100644 klibc/klibc/libgcc/__udivmodsi4.c delete mode 100644 klibc/klibc/libgcc/__udivsi3.c delete mode 100644 klibc/klibc/libgcc/__umoddi3.c delete mode 100644 klibc/klibc/libgcc/__umodsi3.c delete mode 100644 klibc/klibc/llseek.c delete mode 100644 klibc/klibc/lrand48.c delete mode 100644 klibc/klibc/makeerrlist.pl delete mode 100644 klibc/klibc/malloc.c delete mode 100644 klibc/klibc/malloc.h delete mode 100644 klibc/klibc/memccpy.c delete mode 100644 klibc/klibc/memchr.c delete mode 100644 klibc/klibc/memcmp.c delete mode 100644 klibc/klibc/memcpy.c delete mode 100644 klibc/klibc/memmem.c delete mode 100644 klibc/klibc/memmove.c delete mode 100644 klibc/klibc/memrchr.c delete mode 100644 klibc/klibc/memset.c delete mode 100644 klibc/klibc/memswap.c delete mode 100644 klibc/klibc/mmap.c delete mode 100644 klibc/klibc/mrand48.c delete mode 100644 klibc/klibc/nice.c delete mode 100644 klibc/klibc/nrand48.c delete mode 100644 klibc/klibc/onexit.c delete mode 100644 klibc/klibc/open.c delete mode 100644 klibc/klibc/pause.c delete mode 100644 klibc/klibc/perror.c delete mode 100644 klibc/klibc/printf.c delete mode 100644 klibc/klibc/pty.c delete mode 100644 klibc/klibc/putchar.c delete mode 100644 klibc/klibc/putenv.c delete mode 100644 klibc/klibc/puts.c delete mode 100644 klibc/klibc/qsort.c delete mode 100644 klibc/klibc/raise.c delete mode 100644 klibc/klibc/readdir.c delete mode 100644 klibc/klibc/realloc.c delete mode 100644 klibc/klibc/reboot.c delete mode 100644 klibc/klibc/recv.c delete mode 100644 klibc/klibc/sbrk.c delete mode 100644 klibc/klibc/seed48.c delete mode 100644 klibc/klibc/send.c delete mode 100644 klibc/klibc/setegid.c delete mode 100644 klibc/klibc/setenv.c delete mode 100644 klibc/klibc/seteuid.c delete mode 100644 klibc/klibc/setpgrp.c delete mode 100644 klibc/klibc/sha1hash.c delete mode 100644 klibc/klibc/sigaction.c delete mode 100644 klibc/klibc/siglist.c delete mode 100644 klibc/klibc/siglongjmp.c delete mode 100644 klibc/klibc/sigpending.c delete mode 100644 klibc/klibc/sigprocmask.c delete mode 100644 klibc/klibc/sigsuspend.c delete mode 100644 klibc/klibc/sleep.c delete mode 100644 klibc/klibc/snprintf.c delete mode 100644 klibc/klibc/socketcalls.pl delete mode 100644 klibc/klibc/socketcommon.h delete mode 100644 klibc/klibc/sprintf.c delete mode 100644 klibc/klibc/srand48.c delete mode 100644 klibc/klibc/sscanf.c delete mode 100644 klibc/klibc/statfs.c delete mode 100644 klibc/klibc/strcasecmp.c delete mode 100644 klibc/klibc/strcat.c delete mode 100644 klibc/klibc/strchr.c delete mode 100644 klibc/klibc/strcmp.c delete mode 100644 klibc/klibc/strcpy.c delete mode 100644 klibc/klibc/strcspn.c delete mode 100644 klibc/klibc/strdup.c delete mode 100644 klibc/klibc/strerror.c delete mode 100644 klibc/klibc/strlcat.c delete mode 100644 klibc/klibc/strlcpy.c delete mode 100644 klibc/klibc/strlen.c delete mode 100644 klibc/klibc/strncasecmp.c delete mode 100644 klibc/klibc/strncat.c delete mode 100644 klibc/klibc/strncmp.c delete mode 100644 klibc/klibc/strncpy.c delete mode 100644 klibc/klibc/strndup.c delete mode 100644 klibc/klibc/strnlen.c delete mode 100644 klibc/klibc/strntoimax.c delete mode 100644 klibc/klibc/strntoumax.c delete mode 100644 klibc/klibc/strpbrk.c delete mode 100644 klibc/klibc/strrchr.c delete mode 100644 klibc/klibc/strsep.c delete mode 100644 klibc/klibc/strspn.c delete mode 100644 klibc/klibc/strstr.c delete mode 100644 klibc/klibc/strtoimax.c delete mode 100644 klibc/klibc/strtok.c delete mode 100644 klibc/klibc/strtol.c delete mode 100644 klibc/klibc/strtoll.c delete mode 100644 klibc/klibc/strtotimespec.c delete mode 100644 klibc/klibc/strtotimeval.c delete mode 100644 klibc/klibc/strtotimex.c delete mode 100644 klibc/klibc/strtoul.c delete mode 100644 klibc/klibc/strtoull.c delete mode 100644 klibc/klibc/strtoumax.c delete mode 100644 klibc/klibc/strtox.c delete mode 100644 klibc/klibc/strxspn.c delete mode 100644 klibc/klibc/strxspn.h delete mode 100644 klibc/klibc/syscalls.pl delete mode 100644 klibc/klibc/syscommon.h delete mode 100644 klibc/klibc/syslog.c delete mode 100644 klibc/klibc/system.c delete mode 100644 klibc/klibc/sysv_signal.c delete mode 100644 klibc/klibc/time.c delete mode 100644 klibc/klibc/umount.c delete mode 100644 klibc/klibc/unsetenv.c delete mode 100644 klibc/klibc/usleep.c delete mode 100644 klibc/klibc/utime.c delete mode 100644 klibc/klibc/vasprintf.c delete mode 100644 klibc/klibc/vfprintf.c delete mode 100644 klibc/klibc/vprintf.c delete mode 100644 klibc/klibc/vsnprintf.c delete mode 100644 klibc/klibc/vsprintf.c delete mode 100644 klibc/klibc/vsscanf.c delete mode 100644 klibc/klibc/wait.c delete mode 100644 klibc/klibc/wait3.c delete mode 100644 klibc/klibc/waitpid.c delete mode 100644 klibc/klibc/zlib/FAQ delete mode 100644 klibc/klibc/zlib/INDEX delete mode 100644 klibc/klibc/zlib/README delete mode 100644 klibc/klibc/zlib/adler32.c delete mode 100644 klibc/klibc/zlib/algorithm.txt delete mode 100644 klibc/klibc/zlib/compress.c delete mode 100644 klibc/klibc/zlib/crc32.c delete mode 100644 klibc/klibc/zlib/crc32.h delete mode 100644 klibc/klibc/zlib/deflate.c delete mode 100644 klibc/klibc/zlib/deflate.h delete mode 100644 klibc/klibc/zlib/gzio.c delete mode 100644 klibc/klibc/zlib/infback.c delete mode 100644 klibc/klibc/zlib/inffast.c delete mode 100644 klibc/klibc/zlib/inffast.h delete mode 100644 klibc/klibc/zlib/inffixed.h delete mode 100644 klibc/klibc/zlib/inflate.c delete mode 100644 klibc/klibc/zlib/inflate.h delete mode 100644 klibc/klibc/zlib/inftrees.c delete mode 100644 klibc/klibc/zlib/inftrees.h delete mode 100644 klibc/klibc/zlib/trees.c delete mode 100644 klibc/klibc/zlib/trees.h delete mode 100644 klibc/klibc/zlib/uncompr.c delete mode 100644 klibc/klibc/zlib/zconf.h delete mode 100644 klibc/klibc/zlib/zconf.in.h delete mode 100644 klibc/klibc/zlib/zlib.3 delete mode 100644 klibc/klibc/zlib/zlib.h delete mode 100644 klibc/klibc/zlib/zutil.c delete mode 100644 klibc/klibc/zlib/zutil.h delete mode 100755 klibc/makeklcc.pl delete mode 100644 klibc/version diff --git a/ChangeLog b/ChangeLog index e6fd84f582..3ef3c4b838 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +Summary of changes from v74 to v075 +============================================ + Summary of changes from v73 to v074 ============================================ diff --git a/Makefile b/Makefile index bc97388a12..c105dab2e2 100644 --- a/Makefile +++ b/Makefile @@ -122,7 +122,6 @@ configdir = ${etcdir}/udev udevdir = /dev udevdb = ${udevdir}/.udevdb LOCAL_CFG_DIR = etc/udev -KERNEL_DIR = /lib/modules/${shell uname -r}/build DESTDIR = INSTALL = /usr/bin/install -c @@ -177,8 +176,7 @@ endif # if our own version of klibc is used, we need to build it ifeq ($(strip $(USE_KLIBC)),true) - KLIBC_INSTALL = $(PWD)/klibc/.install - KLCC = $(KLIBC_INSTALL)/bin/$(CROSS)klcc + KLCC = /usr/bin/$(CROSS)klcc CC = $(KLCC) LD = $(KLCC) V = true @@ -203,7 +201,7 @@ else HOST_PROGS= endif -all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) +all: $(PROGRAMS) $(MAN_PAGES) @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ $(MAKE) CC="$(CC)" \ @@ -214,7 +212,6 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) LIB_OBJS="$(LIB_OBJS)" \ LIBUDEV="$(PWD)/$(LIBUDEV)" \ LIBSYSFS="$(PWD)/$(LIBSYSFS)" \ - KERNEL_DIR="$(KERNEL_DIR)" \ QUIET="$(QUIET)" \ -C $$target $@; \ done; @@ -229,28 +226,19 @@ all: $(KLCC) $(PROGRAMS) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ # "Static Pattern Rule" to build all programs -$(PROGRAMS): %: $(HOST_PROGS) $(KLCC) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) %.o +$(PROGRAMS): %: $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) %.o $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) ifneq ($(STRIPCMD),) $(QUIET) $(STRIPCMD) $@ endif -# our own copy of klibc, it is not used if KLCC is given -$(KLCC): - $(MAKE) -C klibc KRNLSRC=$(KERNEL_DIR) SUBDIRS=klibc TESTS= \ - SHLIBDIR=$(KLIBC_INSTALL)/lib \ - INSTALLDIR=$(KLIBC_INSTALL) \ - bindir=$(KLIBC_INSTALL)/bin \ - mandir=$(KLIBC_INSTALL)/man all install -.NOTPARALLEL: $(KLCC) - -$(UDEV_OBJS): $(KLCC) +$(UDEV_OBJS): $(LIBUDEV): $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS) @rm -f $@ $(QUIET) $(AR) cq $@ $(UDEV_OBJS) $(QUIET) $(RANLIB) $@ -$(SYSFS_OBJS): $(KLCC) +$(SYSFS_OBJS): $(LIBSYSFS): $(HOST_PROGS) $(SYSFS_OBJS) @rm -f $@ $(QUIET) $(AR) cq $@ $(SYSFS_OBJS) @@ -288,13 +276,10 @@ clean: - rm -f udev_gcov.txt - rm -f core $(PROGRAMS) $(GEN_HEADERS) $(GEN_CONFIGS) - rm -f udev-$(VERSION).tar.gz - $(MAKE) -C klibc SUBDIRS=klibc clean @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ $(MAKE) -C $$target $@; \ done; - $(MAKE) -C klibc SUBDIRS=klibc spotless - rm -rf klibc/.install .PHONY: clean release: diff --git a/README b/README index 19ed4468ea..3f4f947f79 100644 --- a/README +++ b/README @@ -45,9 +45,7 @@ Setting which are used for building udev: USE_LOG if set to 'true', udev will emit messages to the syslog when it creates or removes device nodes. This is helpful to see - what udev is doing. This is enabled by default. Note, if you - are building udev against klibc it is recommended that you - disable this option (due to klibc's syslog implementation.) + what udev is doing. This is enabled by default. DEBUG if set to 'true', verbose debugging messages will be compiled into the udev binaries. Default value is 'false'. @@ -55,20 +53,13 @@ Setting which are used for building udev: if set to 'true', udev will be built with SELinux support enabled. This is disabled by default. USE_KLIBC - if set to 'true', udev is built and linked against the - included version of klibc. Default value is 'false'. - KERNEL_DIR - If this is not set it will default to /lib/modules/`uname -r`/build - This is used if USE_KLIBC=true to find the kernel include - directory that klibc needs to build against. This must be set - if you are not building udev while running a 2.6 kernel. + if set to 'true', udev is built and linked against klibc. + Default value is 'false'. KLCC specifies the klibc compiler + wrapper, usually in /usr/bin/klcc EXTRAS if set, will build the "extra" helper programs as specified as listed (see below for an example.) -if you want to build udev using klibc with debugging messages: - make USE_KLIBC=true DEBUG=true - if you want to build the udev helper program cdrom_id and scsi_id: make EXTRAS="extras/cdrom_id extras/scsi_id" diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 8a1bde8a3b..d89aeaa69f 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,8 @@ +udev 075 +======== +The copy of klibc is removed. A systemwide installed version of klibc +can be used to buil a klibc udev. + udev 074 ======== NAME="" will not create any nodes, but execute RUN keys. To completely diff --git a/klibc/MCONFIG b/klibc/MCONFIG deleted file mode 100644 index 450e5c7f5c..0000000000 --- a/klibc/MCONFIG +++ /dev/null @@ -1,98 +0,0 @@ -# -*- makefile -*- -# -# Makefile configuration, without explicit rules -# - -# CROSS is the prefix used for system tools like gcc, ld etc. -CROSS = - -# KCROSS is the prefix we use for klibc installations. This is usually -# the same as CROSS, but may be different, e.g. to install an i386 -# cross-compilation suite on an x86-64 system, using the same gcc/binutils. -KCROSS ?= $(CROSS) - -# Location for installation -prefix = /usr -bindir = $(prefix)/bin -libdir = $(prefix)/lib -mandir = $(prefix)/man -INSTALLDIR = $(prefix)/lib/klibc -INSTALLROOT = - -INSTALL_EXEC = install -m 755 -INSTALL_DATA = install -m 644 - -# Eventually support separate compilation, but we don't have it yet... -OBJROOT = $(SRCROOT) - -# Kernel trees (source and obj) - can potentially be different -KRNLSRC = $(SRCROOT)/linux -KRNLOBJ = $(SRCROOT)/linux - -# klibc version information -KLIBCVER = -D__KLIBC__=$(shell cut -d. -f1 < $(SRCROOT)/version) \ - -D__KLIBC_MINOR__=$(shell cut -d. -f2 < $(SRCROOT)/version) - -ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/ -e s/parisc.*/parisc/) -CC = $(CROSS)gcc -LD = $(CROSS)ld -KLIBSRC = $(SRCROOT)/klibc -KLIBOBJ = $(OBJROOT)/klibc -INCLUDE = -I$(SRCROOT)/include/arch/$(ARCH) \ - -I$(SRCROOT)/include/bits$(BITSIZE) \ - -I$(SRCROOT)/include \ - -I$(KRNLOBJ)/include -I$(KRNLOBJ)/include2 -I$(KRNLSRC)/include -REQFLAGS = $(ARCHREQFLAGS) $(KLIBCVER) -nostdlib -nostdinc -iwithprefix include \ - $(INCLUDE) -LDFLAGS = -AR = $(CROSS)ar -RANLIB = $(CROSS)ranlib -NM = $(CROSS)nm -PERL = perl -OBJCOPY = $(CROSS)objcopy - -STRIP = $(CROSS)strip -STRIPFLAGS = --strip-all -R .comment -R .note -STRIPCMD = $(STRIP) $(STRIPFLAGS) - -HOST_CC = gcc -HOST_CFLAGS = -g -O -HOST_LDFLAGS = -HOST_LIBS = - -# Static library paths -CRT0 = $(KLIBOBJ)/crt0.o -KLIBC = $(KLIBOBJ)/libc.a -LIBGCC = $(shell $(CC) $(REQFLAGS) $(OPTFLAGS) --print-libgcc) - -# Shared library paths -CRTSHARED = $(KLIBOBJ)/interp.o -LIBSHARED = $(KLIBOBJ)/libc.so - -# -# This indicates the location of the final version of the shared library. -# THIS MUST BE AN ABSOLUTE PATH WITH NO FINAL SLASH. -# Leave this empty to make it the root. -# -SHLIBDIR = /lib - -# Enable this to make perror/strerror return real error messages -# This makes klibc.so and any static binary which uses these functions -# about 4K bigger. -ERRLIST = 1 - -# Include zlib in klibc. This roughly triples the size of klibc! -ZLIB = 0 - -# -# Include arch-specific rule fragments -# -include $(KLIBSRC)/arch/$(ARCH)/MCONFIG - -ifeq ($(DEBUG),y) -STRIP = /bin/true -Since_we_are_debugging -OPTFLAGS += -O1 -g -endif - -# How to tell the linker main() is the entrypoint -EMAIN ?= -e main diff --git a/klibc/MRULES b/klibc/MRULES deleted file mode 100644 index 41fdd07af8..0000000000 --- a/klibc/MRULES +++ /dev/null @@ -1,45 +0,0 @@ -# -*- makefile -*- -# -# Standard pattern rules -# - -.SUFFIXES: .c .o .a .so .lo .i .S .s .ls .ss .lss - -% : %.c # Cancel default rule - -% : %.S - -.c.o: - $(CC) $(CFLAGS) -c -o $@ $< - -.c.i: - $(CC) $(CFLAGS) -E -o $@ $< - -.c.s: - $(CC) $(CFLAGS) -S -o $@ $< - -.S.o: - $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $< - -.S.s: - $(CC) $(CFLAGS) -D__ASSEMBLY__ -E -o $@ $< - -.S.lo: - $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -c -o $@ $< - -.S.ls: - $(CC) $(CFLAGS) $(SOFLAGS) -D__ASSEMBLY__ -E -o $@ $< - -.s.o: - $(CC) $(CFLAGS) -x assembler -c -o $@ $< - -.ls.lo: - $(CC) $(CFLAGS) $(SOFLAGS) -x assembler -c -o $@ $< - -.c.lo: - $(CC) $(CFLAGS) $(SOFLAGS) -c -o $@ $< - -.c.ls: - $(CC) $(CFLAGS) $(SOFLAGS) -S -o $@ $< - - diff --git a/klibc/Makefile b/klibc/Makefile deleted file mode 100644 index e634aaccb5..0000000000 --- a/klibc/Makefile +++ /dev/null @@ -1,77 +0,0 @@ -VERSION := $(shell cat version) -SUBDIRS = klibc ash ipconfig nfsmount utils kinit gzip -SRCROOT = . - -all: - -rpmbuild = $(shell which rpmbuild 2>/dev/null || which rpm) - -klibc.spec: klibc.spec.in version - sed -e 's/@@VERSION@@/$(VERSION)/g' < $< > $@ - -.PHONY: rpm -rpm: klibc.spec - +$(rpmbuild) -bb klibc.spec --target=$(ARCH) - -$(CROSS)klibc.config: Makefile - rm -f $@ - echo 'ARCH=$(ARCH)' >> $@ - echo 'CROSS=$(CROSS)' >> $@ - echo 'KCROSS=$(KCROSS)' >> $@ - echo 'CC=$(CC)' >> $@ - echo 'LD=$(LD)' >> $@ - echo 'REQFLAGS=$(filter-out -I%,$(REQFLAGS))' >> $@ - echo 'OPTFLAGS=$(OPTFLAGS)' >> $@ - echo 'LDFLAGS=$(LDFLAGS)' >> $@ - echo 'STRIP=$(STRIP)' >> $@ - echo 'STRIPFLAGS=$(STRIPFLAGS)' >> $@ - echo 'EMAIN=$(EMAIN)' >> $@ - echo 'BITSIZE=$(BITSIZE)' >> $@ - echo 'prefix=$(INSTALLDIR)' >> $@ - echo 'bindir=$(INSTALLDIR)/$(KCROSS)bin' >> $@ - echo 'libdir=$(INSTALLDIR)/$(KCROSS)lib' >> $@ - echo 'includedir=$(INSTALLDIR)/$(KCROSS)include' >> $@ - -$(CROSS)klcc: klcc.in $(CROSS)klibc.config makeklcc.pl - $(PERL) makeklcc.pl klcc.in $(CROSS)klibc.config \ - $(shell bash -c 'type -p $(PERL)') > $@ || ( rm -f $@ ; exit 1 ) - chmod a+x $@ - -%: local-% - @set -e; for d in $(SUBDIRS); do $(MAKE) -C $$d $@; done - -local-all: $(CROSS)klcc - -local-clean: - rm -f klibc.config klcc - -local-spotless: local-clean - rm -f klibc.spec *~ tags - -local-install: $(CROSS)klcc - mkdir -p $(INSTALLROOT)$(bindir) - mkdir -p $(INSTALLROOT)$(mandir)/man1 - mkdir -p $(INSTALLROOT)$(SHLIBDIR) - mkdir -p $(INSTALLROOT)$(INSTALLDIR) - -rm -rf $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)lib - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)bin - set -xe ; for d in linux scsi asm-$(ARCH) asm-generic $(ASMARCH); do \ - mkdir -p $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)include/$$d ; \ - for r in $(KRNLSRC)/include $(KRNLOBJ)/include $(KRNLOBJ)/include2 ; do \ - [ ! -d $$r/$$d ] || \ - cp -rfL $$r/$$d/. $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include/$$d/. ; \ - done ; \ - done - cd $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include && ln -sf asm-$(ARCH) asm - cp -rf include/. $(INSTALLROOT)$(INSTALLDIR)/$(KCROSS)include/. - $(INSTALL_DATA) klcc.1 $(INSTALLROOT)$(mandir)/man1/$(KCROSS)klcc.1 - $(INSTALL_EXEC) $(KCROSS)klcc $(INSTALLROOT)$(bindir) - -# This does all the prep work needed to turn a freshly exported git repository -# into a release tarball tree -release: klibc.spec - rm -f maketar.sh - --include MCONFIG diff --git a/klibc/README b/klibc/README deleted file mode 100644 index eb72e1c239..0000000000 --- a/klibc/README +++ /dev/null @@ -1,21 +0,0 @@ -Please see klibc/README for build instructions and for the status of -various platforms. - - - -klibc is archived at: - - ftp://ftp.kernel.org/pub/linux/libs/klibc/ - -There is a mailing list for klibc and early-userspace issues at: - - http://www.zytor.com/mailman/listinfo/klibc/ - -There is also a cvsweb repository at: - - http://www.zytor.com/cvsweb.cgi/klibc/ - -There is no direct public CVS access yet, however, the CVS repository -is available for rsync from: - - rsync://rsync.kernel.org/pub/linux/libs/klibc/cvsroot/ diff --git a/klibc/include/alloca.h b/klibc/include/alloca.h deleted file mode 100644 index 41a4d94d44..0000000000 --- a/klibc/include/alloca.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * alloca.h - * - * Just call the builtin alloca() function - */ - -#ifndef _ALLOCA_H -#define _ALLOCA_H - -#define alloca(size) __builtin_alloca(size) - -#endif /* _ALLOCA_H */ - diff --git a/klibc/include/arch/alpha/klibc/archsetjmp.h b/klibc/include/arch/alpha/klibc/archsetjmp.h deleted file mode 100644 index 9dc570a6f5..0000000000 --- a/klibc/include/arch/alpha/klibc/archsetjmp.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * arch/alpha/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __s0; - unsigned long __s1; - unsigned long __s2; - unsigned long __s3; - unsigned long __s4; - unsigned long __s5; - unsigned long __fp; - unsigned long __ra; - unsigned long __gp; - unsigned long __sp; - - unsigned long __f2; - unsigned long __f3; - unsigned long __f4; - unsigned long __f5; - unsigned long __f6; - unsigned long __f7; - unsigned long __f8; - unsigned long __f9; -}; - -/* Must be an array so it will decay to a pointer when a function is called */ -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/alpha/klibc/archsignal.h b/klibc/include/arch/alpha/klibc/archsignal.h deleted file mode 100644 index b870a05131..0000000000 --- a/klibc/include/arch/alpha/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/alpha/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/alpha/klibc/archstat.h b/klibc/include/arch/alpha/klibc/archstat.h deleted file mode 100644 index 23302d737d..0000000000 --- a/klibc/include/arch/alpha/klibc/archstat.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned long st_dev; - unsigned long st_ino; - unsigned long st_rdev; - long st_size; - unsigned long st_blocks; - - unsigned int st_mode; - unsigned int st_uid; - unsigned int st_gid; - unsigned int st_blksize; - unsigned int st_nlink; - unsigned int __pad0; - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - long __unused[3]; -}; - -#endif diff --git a/klibc/include/arch/alpha/klibc/archsys.h b/klibc/include/arch/alpha/klibc/archsys.h deleted file mode 100644 index 16ed658987..0000000000 --- a/klibc/include/arch/alpha/klibc/archsys.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * arch/alpha/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* Alpha has some bizarre Tru64-derived system calls which return two - different values in $0 and $20(!), respectively. The standard - macros can't deal with these; even the ones that give the right - return value have the wrong clobbers. */ - -#define _syscall0_dual0(type, name) \ -type name(void) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_19 __asm__("$19"); \ - register long _sc_20 __asm__("$20"); \ - \ - _sc_0 = __NR_##name; \ - __asm__("callsys" \ - : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ - : "0"(_sc_0) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; (void)(_sc_20); \ - } \ - _syscall_return(type); \ -} - -#define _syscall0_dual1(type, name) \ -type name(void) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_19 __asm__("$19"); \ - register long _sc_20 __asm__("$20"); \ - \ - _sc_0 = __NR_##name; \ - __asm__("callsys" \ - : "=r"(_sc_0), "=r"(_sc_19), "=r" (_sc_20) \ - : "0"(_sc_0) \ - : _syscall_clobbers); \ - _sc_ret = _sc_20, _sc_err = _sc_19; (void)(_sc_0); \ - } \ - _syscall_return(type); \ -} - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/alpha/machine/asm.h b/klibc/include/arch/alpha/machine/asm.h deleted file mode 100644 index e22db90412..0000000000 --- a/klibc/include/arch/alpha/machine/asm.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * machine/asm.h - */ - -#ifndef _MACHINE_ASM_H -#define _MACHINE_ASM_H - -/* Standard aliases for Alpha register names */ - -#define v0 $0 -#define t0 $1 -#define t1 $2 -#define t2 $3 -#define t3 $4 -#define t4 $5 -#define t5 $6 -#define t6 $7 -#define t7 $8 -#define s0 $9 -#define s1 $10 -#define s2 $11 -#define s3 $12 -#define s4 $13 -#define s5 $14 -#define fp $15 -#define a0 $16 -#define a1 $17 -#define a2 $18 -#define a3 $19 -#define a4 $20 -#define a5 $21 -#define t8 $22 -#define t9 $23 -#define t10 $24 -#define t11 $25 -#define ra $26 -#define t12 $27 /* t12 and pv are both used for $27 */ -#define pv $27 /* t12 and pv are both used for $27 */ -#define at $28 -#define gp $29 -#define sp $30 -#define zero $31 - -#endif /* _MACHINE_ASM_H */ diff --git a/klibc/include/arch/arm/klibc/archsetjmp.h b/klibc/include/arch/arm/klibc/archsetjmp.h deleted file mode 100644 index c956b50a90..0000000000 --- a/klibc/include/arch/arm/klibc/archsetjmp.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * arch/i386/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned int regs[10]; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/arm/klibc/archsignal.h b/klibc/include/arch/arm/klibc/archsignal.h deleted file mode 100644 index 77685e62f0..0000000000 --- a/klibc/include/arch/arm/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/arm/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/arm/klibc/archstat.h b/klibc/include/arch/arm/klibc/archstat.h deleted file mode 100644 index 42b1409f67..0000000000 --- a/klibc/include/arch/arm/klibc/archstat.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#include - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - * Note: The kernel zero's the padded region because glibc might read them - * in the hope that the kernel has stretched to using larger sizes. - */ -struct stat { - unsigned long long st_dev; - unsigned char __pad0[4]; - - unsigned long __st_ino; - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[4]; - - long long st_size; - unsigned long st_blksize; - -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned long __pad4; /* Future possible st_blocks hi bits */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ -#else /* Must be little */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long __pad4; /* Future possible st_blocks hi bits */ -#endif - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned long long st_ino; -}; - -#endif diff --git a/klibc/include/arch/arm/klibc/archsys.h b/klibc/include/arch/arm/klibc/archsys.h deleted file mode 100644 index dfdc70a6de..0000000000 --- a/klibc/include/arch/arm/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/cris/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/cris/klibc/archsetjmp.h b/klibc/include/arch/cris/klibc/archsetjmp.h deleted file mode 100644 index 8d20800609..0000000000 --- a/klibc/include/arch/cris/klibc/archsetjmp.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/cris/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __r0; - unsigned long __r1; - unsigned long __r2; - unsigned long __r3; - unsigned long __r4; - unsigned long __r5; - unsigned long __r6; - unsigned long __r7; - unsigned long __r8; - unsigned long __sp; - unsigned long __srp; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/cris/klibc/archsignal.h b/klibc/include/arch/cris/klibc/archsignal.h deleted file mode 100644 index 73b2e196c9..0000000000 --- a/klibc/include/arch/cris/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/cris/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/cris/klibc/archstat.h b/klibc/include/arch/cris/klibc/archstat.h deleted file mode 100644 index 154820755f..0000000000 --- a/klibc/include/arch/cris/klibc/archstat.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat { - unsigned long long st_dev; - unsigned char __pad0[4]; - - unsigned long __st_ino; - - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[4]; - - long long st_size; - unsigned long st_blksize; - - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long __pad4; /* future possible st_blocks high bits */ - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned long long st_ino; -}; - -#endif diff --git a/klibc/include/arch/cris/klibc/archsys.h b/klibc/include/arch/cris/klibc/archsys.h deleted file mode 100644 index dfdc70a6de..0000000000 --- a/klibc/include/arch/cris/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/cris/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/i386/klibc/archsetjmp.h b/klibc/include/arch/i386/klibc/archsetjmp.h deleted file mode 100644 index db04314b8c..0000000000 --- a/klibc/include/arch/i386/klibc/archsetjmp.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/i386/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned int __ebx; - unsigned int __esp; - unsigned int __ebp; - unsigned int __esi; - unsigned int __edi; - unsigned int __eip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/i386/klibc/archsignal.h b/klibc/include/arch/i386/klibc/archsignal.h deleted file mode 100644 index b092ba6d3a..0000000000 --- a/klibc/include/arch/i386/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/i386/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/i386/klibc/archstat.h b/klibc/include/arch/i386/klibc/archstat.h deleted file mode 100644 index 154820755f..0000000000 --- a/klibc/include/arch/i386/klibc/archstat.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat { - unsigned long long st_dev; - unsigned char __pad0[4]; - - unsigned long __st_ino; - - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[4]; - - long long st_size; - unsigned long st_blksize; - - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long __pad4; /* future possible st_blocks high bits */ - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned long long st_ino; -}; - -#endif diff --git a/klibc/include/arch/i386/klibc/archsys.h b/klibc/include/arch/i386/klibc/archsys.h deleted file mode 100644 index dfdc70a6de..0000000000 --- a/klibc/include/arch/i386/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/cris/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/i386/klibc/diverr.h b/klibc/include/arch/i386/klibc/diverr.h deleted file mode 100644 index 410aba06d3..0000000000 --- a/klibc/include/arch/i386/klibc/diverr.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/i386/include/klibc/diverr.h - */ - -#ifndef _KLIBC_DIVERR_H -#define _KLIBC_DIVERR_H - -#include - -static __inline__ void -__divide_error(void) -{ - asm volatile("divl %0" :: "rm" (0) : "eax", "edx"); -} - -#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/include/arch/i386/sys/io.h b/klibc/include/arch/i386/sys/io.h deleted file mode 100644 index b051464dfc..0000000000 --- a/klibc/include/arch/i386/sys/io.h +++ /dev/null @@ -1,126 +0,0 @@ -#ident "$Id: io.h,v 1.2 2004/01/25 07:49:39 hpa Exp $" -/* ----------------------------------------------------------------------- * - * - * Copyright 2004 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * sys/io.h for the i386 architecture - * - * Basic I/O macros - */ - -#ifndef _SYS_IO_H -#define _SYS_IO_H 1 - -/* I/O-related system calls */ - -int iopl(int); -int ioperm(unsigned long, unsigned long, int); - -/* Basic I/O macros */ - -static __inline__ void -outb(unsigned char __v, unsigned short __p) -{ - asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outw(unsigned short __v, unsigned short __p) -{ - asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outl(unsigned int __v, unsigned short __p) -{ - asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ unsigned char -inb(unsigned short __p) -{ - unsigned char __v; - asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); - return __v; -} - -static __inline__ unsigned short -inw(unsigned short __p) -{ - unsigned short __v; - asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); - return __v; -} - -static __inline__ unsigned int -inl(unsigned short __p) -{ - unsigned int __v; - asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); - return __v; -} - -/* String I/O macros */ - -static __inline__ void -outsb (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsw (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsl (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - - -static __inline__ void -insb (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insw (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insl (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -#endif /* _SYS_IO_H */ diff --git a/klibc/include/arch/i386/sys/vm86.h b/klibc/include/arch/i386/sys/vm86.h deleted file mode 100644 index d3272393dc..0000000000 --- a/klibc/include/arch/i386/sys/vm86.h +++ /dev/null @@ -1,41 +0,0 @@ -#ident "$Id: vm86.h,v 1.1 2004/01/25 01:34:28 hpa Exp $" -/* ----------------------------------------------------------------------- * - * - * Copyright 2004 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * sys/vm86.h for i386 - */ - -#ifndef _SYS_VM86_H -#define _SYS_VM86_H 1 - -#include - -/* Actual system call */ -int vm86(struct vm86_struct *); - -#endif diff --git a/klibc/include/arch/ia64/klibc/archsetjmp.h b/klibc/include/arch/ia64/klibc/archsetjmp.h deleted file mode 100644 index bd639c0b00..0000000000 --- a/klibc/include/arch/ia64/klibc/archsetjmp.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/ia64/include/klibc/archsetjmp.h - * - * Code borrowed from the FreeBSD kernel. - * - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -/* User code must not depend on the internal representation of jmp_buf. */ -#define _JBLEN 0x200 - -/* guaranteed 128-bit alignment! */ -typedef char jmp_buf[_JBLEN] __attribute__ ((aligned (16))); - -#endif diff --git a/klibc/include/arch/ia64/klibc/archsignal.h b/klibc/include/arch/ia64/klibc/archsignal.h deleted file mode 100644 index 5b01f19bc2..0000000000 --- a/klibc/include/arch/ia64/klibc/archsignal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * arch/ia64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions. - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -#define _NSIG 64 -#define _NSIG_BPW 64 -#define _NSIG_WORDS (_NSIG / _NSIG_BPW) - -typedef struct { - unsigned long sig[_NSIG_WORDS]; -} sigset_t; - -struct sigaction { - union { - __sighandler_t _sa_handler; - void (*_sa_sigaction)(int, struct siginfo *, void *); - } _u; - sigset_t sa_mask; - int sa_flags; -}; - -#define sa_handler _u._sa_handler -#define sa_sigaction _u._sa_sigaction - -#endif diff --git a/klibc/include/arch/ia64/klibc/archstat.h b/klibc/include/arch/ia64/klibc/archstat.h deleted file mode 100644 index 9475c0b797..0000000000 --- a/klibc/include/arch/ia64/klibc/archstat.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned long st_dev; - unsigned long st_ino; - unsigned long st_nlink; - unsigned int st_mode; - unsigned int st_uid; - unsigned int st_gid; - unsigned int __pad0; - unsigned long st_rdev; - unsigned long st_size; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - unsigned long st_blksize; - long st_blocks; - unsigned long __unused[3]; -}; - -#endif diff --git a/klibc/include/arch/ia64/klibc/archsys.h b/klibc/include/arch/ia64/klibc/archsys.h deleted file mode 100644 index 4c795a43ca..0000000000 --- a/klibc/include/arch/ia64/klibc/archsys.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * arch/ia64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -#define __IA64_BREAK "break 0x100000;;\n\t" - -#define _syscall0(type,name) \ -type \ -name (void) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15) \ - : "2" (_r15) ASM_ARGS_0 \ - : "memory" ASM_CLOBBERS_0); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return (type)_retval; \ -} - -#define _syscall1(type,name,type1,arg1) \ -type \ -name (type1 arg1) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_1(arg1); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_1 \ - : "2" (_r15) ASM_ARGS_1 \ - : "memory" ASM_CLOBBERS_1); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return (type)_retval; \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type \ -name (type1 arg1, type2 arg2) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_2(arg1, arg2); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_2 \ - : "2" (_r15) ASM_ARGS_2 \ - : "memory" ASM_CLOBBERS_2); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return (type)_retval; \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_3(arg1, arg2, arg3); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_3 \ - : "2" (_r15) ASM_ARGS_3 \ - : "memory" ASM_CLOBBERS_3); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return (type)_retval; \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_4(arg1, arg2, arg3, arg4); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_4 \ - : "2" (_r15) ASM_ARGS_4 \ - : "memory" ASM_CLOBBERS_4); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return (type)_retval; \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_5(arg1, arg2, arg3, arg4, arg5); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_5 \ - : "2" (_r15) ASM_ARGS_5 \ - : "memory" ASM_CLOBBERS_5); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return (type)_retval; \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type \ -name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ - register long _r8 asm ("r8"); \ - register long _r10 asm ("r10"); \ - register long _r15 asm ("r15") = __NR_##name; \ - long _retval; \ - LOAD_ARGS_6(arg1, arg2, arg3, arg4, arg5, arg6); \ - __asm __volatile (__IA64_BREAK \ - : "=r" (_r8), "=r" (_r10), "=r" (_r15), \ - ASM_OUTARGS_6 \ - : "2" (_r15) ASM_ARGS_6 \ - : "memory" ASM_CLOBBERS_6); \ - _retval = _r8; \ - if (_r10 == -1) { \ - errno = (_retval); \ - _retval = -1; \ - } \ - return (type)_retval; \ -} - - -#define LOAD_ARGS_0() do { } while (0) -#define LOAD_ARGS_1(out0) \ - register long _out0 asm ("out0") = (long) (out0); \ - LOAD_ARGS_0 () -#define LOAD_ARGS_2(out0, out1) \ - register long _out1 asm ("out1") = (long) (out1); \ - LOAD_ARGS_1 (out0) -#define LOAD_ARGS_3(out0, out1, out2) \ - register long _out2 asm ("out2") = (long) (out2); \ - LOAD_ARGS_2 (out0, out1) -#define LOAD_ARGS_4(out0, out1, out2, out3) \ - register long _out3 asm ("out3") = (long) (out3); \ - LOAD_ARGS_3 (out0, out1, out2) -#define LOAD_ARGS_5(out0, out1, out2, out3, out4) \ - register long _out4 asm ("out4") = (long) (out4); \ - LOAD_ARGS_4 (out0, out1, out2, out3) -#define LOAD_ARGS_6(out0, out1, out2, out3, out4, out5) \ - register long _out5 asm ("out5") = (long) (out5); \ - LOAD_ARGS_5 (out0, out1, out2, out3, out4) - -#define ASM_OUTARGS_1 "=r" (_out0) -#define ASM_OUTARGS_2 ASM_OUTARGS_1, "=r" (_out1) -#define ASM_OUTARGS_3 ASM_OUTARGS_2, "=r" (_out2) -#define ASM_OUTARGS_4 ASM_OUTARGS_3, "=r" (_out3) -#define ASM_OUTARGS_5 ASM_OUTARGS_4, "=r" (_out4) -#define ASM_OUTARGS_6 ASM_OUTARGS_5, "=r" (_out5) - -#define ASM_ARGS_0 -#define ASM_ARGS_1 ASM_ARGS_0, "3" (_out0) -#define ASM_ARGS_2 ASM_ARGS_1, "4" (_out1) -#define ASM_ARGS_3 ASM_ARGS_2, "5" (_out2) -#define ASM_ARGS_4 ASM_ARGS_3, "6" (_out3) -#define ASM_ARGS_5 ASM_ARGS_4, "7" (_out4) -#define ASM_ARGS_6 ASM_ARGS_5, "8" (_out5) - -#define ASM_CLOBBERS_0 ASM_CLOBBERS_1, "out0" -#define ASM_CLOBBERS_1 ASM_CLOBBERS_2, "out1" -#define ASM_CLOBBERS_2 ASM_CLOBBERS_3, "out2" -#define ASM_CLOBBERS_3 ASM_CLOBBERS_4, "out3" -#define ASM_CLOBBERS_4 ASM_CLOBBERS_5, "out4" -#define ASM_CLOBBERS_5 ASM_CLOBBERS_6, "out5" -#define ASM_CLOBBERS_6 , "out6", "out7", \ - /* Non-stacked integer registers, minus r8, r10, r15. */ \ - "r2", "r3", "r9", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \ - "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \ - "r28", "r29", "r30", "r31", \ - /* Predicate registers. */ \ - "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \ - /* Non-rotating fp registers. */ \ - "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ - /* Branch registers. */ \ - "b6", "b7" - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/m32r/klibc/archsetjmp.h b/klibc/include/arch/m32r/klibc/archsetjmp.h deleted file mode 100644 index e16a83517a..0000000000 --- a/klibc/include/arch/m32r/klibc/archsetjmp.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/m32r/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __r8; - unsigned long __r9; - unsigned long __r10; - unsigned long __r11; - unsigned long __r12; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/m32r/klibc/archsignal.h b/klibc/include/arch/m32r/klibc/archsignal.h deleted file mode 100644 index 02596e9a1c..0000000000 --- a/klibc/include/arch/m32r/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/m32r/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/m32r/klibc/archstat.h b/klibc/include/arch/m32r/klibc/archstat.h deleted file mode 100644 index 154820755f..0000000000 --- a/klibc/include/arch/m32r/klibc/archstat.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat { - unsigned long long st_dev; - unsigned char __pad0[4]; - - unsigned long __st_ino; - - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[4]; - - long long st_size; - unsigned long st_blksize; - - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long __pad4; /* future possible st_blocks high bits */ - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned long long st_ino; -}; - -#endif diff --git a/klibc/include/arch/m32r/klibc/archsys.h b/klibc/include/arch/m32r/klibc/archsys.h deleted file mode 100644 index 386db8b505..0000000000 --- a/klibc/include/arch/m32r/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/m32r/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/m68k/klibc/archsignal.h b/klibc/include/arch/m68k/klibc/archsignal.h deleted file mode 100644 index 714527f6b0..0000000000 --- a/klibc/include/arch/m68k/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/m68k/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/m68k/klibc/archstat.h b/klibc/include/arch/m68k/klibc/archstat.h deleted file mode 100644 index 9c0a05da09..0000000000 --- a/klibc/include/arch/m68k/klibc/archstat.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat { - unsigned long long st_dev; - unsigned char __pad1[2]; - - unsigned long __st_ino; - - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[2]; - - long long st_size; - unsigned long st_blksize; - - unsigned long __pad4; /* future possible st_blocks high bits */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned long long st_ino; -}; - -#endif diff --git a/klibc/include/arch/m68k/klibc/archsys.h b/klibc/include/arch/m68k/klibc/archsys.h deleted file mode 100644 index 8f6bed8e94..0000000000 --- a/klibc/include/arch/m68k/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/m68k/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/mips/klibc/archfcntl.h b/klibc/include/arch/mips/klibc/archfcntl.h deleted file mode 100644 index 54462ea69f..0000000000 --- a/klibc/include/arch/mips/klibc/archfcntl.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * arch/mips/include/klibc/archfcntl.h - * - * On MIPS, isn't usable (compiling struct stat with - * the correct definitions doesn't "just work"), so we need to provide - * our own definitions. - */ - -#ifndef _KLIBC_ARCHFCNTL_H -#define _KLIBC_ARCHFCNTL_H - -#ifdef _ASM_FCNTL_H /* We were too late! */ -# error " included before " -#endif -#define _ASM_FCNTL_H /* Keep from getting included */ - -#define O_ACCMODE 0x0003 -#define O_RDONLY 0x0000 -#define O_WRONLY 0x0001 -#define O_RDWR 0x0002 -#define O_APPEND 0x0008 -#define O_SYNC 0x0010 -#define O_NONBLOCK 0x0080 -#define O_CREAT 0x0100 -#define O_TRUNC 0x0200 -#define O_EXCL 0x0400 -#define O_NOCTTY 0x0800 -#define FASYNC 0x1000 -#define O_LARGEFILE 0x2000 -#define O_DIRECT 0x8000 -#define O_DIRECTORY 0x10000 -#define O_NOFOLLOW 0x20000 -#define O_NOATIME 0x40000 - -#define O_NDELAY O_NONBLOCK - -#define F_DUPFD 0 -#define F_GETFD 1 -#define F_SETFD 2 -#define F_GETFL 3 -#define F_SETFL 4 -#define F_GETLK 14 -#define F_SETLK 6 -#define F_SETLKW 7 - -#define F_SETOWN 24 -#define F_GETOWN 23 -#define F_SETSIG 10 -#define F_GETSIG 11 - -#define F_GETLK64 33 -#define F_SETLK64 34 -#define F_SETLKW64 35 - -#define FD_CLOEXEC 1 - -#define F_RDLCK 0 -#define F_WRLCK 1 -#define F_UNLCK 2 - -#define F_EXLCK 4 -#define F_SHLCK 8 - -#define F_INPROGRESS 16 - -#define LOCK_SH 1 -#define LOCK_EX 2 -#define LOCK_NB 4 -#define LOCK_UN 8 - -#define LOCK_MAND 32 -#define LOCK_READ 64 -#define LOCK_WRITE 128 -#define LOCK_RW 192 - -typedef struct flock { - short l_type; - short l_whence; - loff_t l_start; - loff_t l_len; - pid_t l_pid; -} flock_t; - -#define F_LINUX_SPECIFIC_BASE 1024 - -#endif /* _KLIBC_ARCHFCNTL_H */ - diff --git a/klibc/include/arch/mips/klibc/archsetjmp.h b/klibc/include/arch/mips/klibc/archsetjmp.h deleted file mode 100644 index 40e5be2736..0000000000 --- a/klibc/include/arch/mips/klibc/archsetjmp.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * arch/mips/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __s0; - unsigned long __s1; - unsigned long __s2; - unsigned long __s3; - unsigned long __s4; - unsigned long __s5; - unsigned long __s6; - unsigned long __s7; - unsigned long __gp; - unsigned long __sp; - unsigned long __s8; - unsigned long __ra; - unsigned long __f20; - unsigned long __f21; - unsigned long __f22; - unsigned long __f23; - unsigned long __f24; - unsigned long __f25; - unsigned long __f26; - unsigned long __f27; - unsigned long __f28; - unsigned long __f29; - unsigned long __f30; - unsigned long __f31; - unsigned long __fcr31; - unsigned long __unused; -} __attribute__((aligned(8))); - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/mips/klibc/archsignal.h b/klibc/include/arch/mips/klibc/archsignal.h deleted file mode 100644 index 3b72908636..0000000000 --- a/klibc/include/arch/mips/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/mips/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/mips/klibc/archstat.h b/klibc/include/arch/mips/klibc/archstat.h deleted file mode 100644 index 612bbfa85b..0000000000 --- a/klibc/include/arch/mips/klibc/archstat.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -/* - * This matches struct stat64 in glibc2.1, hence the absolutely insane - * amounts of padding around dev_t's. The memory layout is the same as of - * struct stat of the 64-bit kernel. - */ - -struct stat { - unsigned long st_dev; - unsigned long st_pad0[3]; /* Reserved for st_dev expansion */ - - unsigned long long st_ino; - - mode_t st_mode; - nlink_t st_nlink; - - uid_t st_uid; - gid_t st_gid; - - unsigned long st_rdev; - unsigned long st_pad1[3]; /* Reserved for st_rdev expansion */ - - long long st_size; - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned long st_blksize; - unsigned long st_pad2; - - long long st_blocks; -}; - -#endif diff --git a/klibc/include/arch/mips/klibc/archsys.h b/klibc/include/arch/mips/klibc/archsys.h deleted file mode 100644 index f696cdfaa7..0000000000 --- a/klibc/include/arch/mips/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/mips/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/mips/machine/asm.h b/klibc/include/arch/mips/machine/asm.h deleted file mode 100644 index e5239a6cef..0000000000 --- a/klibc/include/arch/mips/machine/asm.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * arch/mips/include/machine/asm.h - */ - -#ifndef _MACHINE_ASM_H -#define _MACHINE_ASM_H - -#include -#include - -#endif /* _MACHINE_ASM_H */ diff --git a/klibc/include/arch/mips/sgidefs.h b/klibc/include/arch/mips/sgidefs.h deleted file mode 100644 index eb103ace2c..0000000000 --- a/klibc/include/arch/mips/sgidefs.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/mips/include/sgidefs.h - */ - -/* Some ABI constants */ - -#ifndef _SGIDEFS_H -#define _SGIDEFS_H - -#define _MIPS_ISA_MIPS1 1 -#define _MIPS_ISA_MIPS2 2 -#define _MIPS_ISA_MIPS3 3 -#define _MIPS_ISA_MIPS4 4 -#define _MIPS_ISA_MIPS5 5 - -#define _MIPS_SIM_ABI32 1 -#define _MIPS_SIM_NABI32 2 -#define _MIPS_SIM_ABI64 3 - -#endif /* _SGIDEFS_H */ diff --git a/klibc/include/arch/mips/spaces.h b/klibc/include/arch/mips/spaces.h deleted file mode 100644 index b5f530b753..0000000000 --- a/klibc/include/arch/mips/spaces.h +++ /dev/null @@ -1 +0,0 @@ -/* Included by but not actually needed */ diff --git a/klibc/include/arch/mips64/klibc/archsignal.h b/klibc/include/arch/mips64/klibc/archsignal.h deleted file mode 100644 index 56b0fd323e..0000000000 --- a/klibc/include/arch/mips64/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/mips64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/mips64/klibc/archstat.h b/klibc/include/arch/mips64/klibc/archstat.h deleted file mode 100644 index d237e3a3e8..0000000000 --- a/klibc/include/arch/mips64/klibc/archstat.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned int st_dev; - unsigned int st_pad0[3]; /* Reserved for st_dev expansion */ - - unsigned long st_ino; - - mode_t st_mode; - nlink_t st_nlink; - - uid_t st_uid; - gid_t st_gid; - - unsigned int st_rdev; - unsigned int st_pad1[3]; /* Reserved for st_rdev expansion */ - - off_t st_size; - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned int st_blksize; - unsigned int st_pad2; - - unsigned long st_blocks; -}; - -#endif diff --git a/klibc/include/arch/mips64/klibc/archsys.h b/klibc/include/arch/mips64/klibc/archsys.h deleted file mode 100644 index 81e5106e16..0000000000 --- a/klibc/include/arch/mips64/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/mips64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/parisc/klibc/archsetjmp.h b/klibc/include/arch/parisc/klibc/archsetjmp.h deleted file mode 100644 index e7444983ed..0000000000 --- a/klibc/include/arch/parisc/klibc/archsetjmp.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * arch/parisc/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - double regs[21]; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/parisc/klibc/archsignal.h b/klibc/include/arch/parisc/klibc/archsignal.h deleted file mode 100644 index 3190e8528e..0000000000 --- a/klibc/include/arch/parisc/klibc/archsignal.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arch/parisc/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -#define _NSIG 64 -#define _NSIG_SZ (_NSIG / LONG_BIT) - -typedef struct { - unsigned long sig[_NSIG_SZ]; -} sigset_t; - -struct sigaction { - __sighandler_t sa_handler; - unsigned long sa_flags; - sigset_t sa_mask; -}; - -#endif diff --git a/klibc/include/arch/parisc/klibc/archstat.h b/klibc/include/arch/parisc/klibc/archstat.h deleted file mode 100644 index 7d28f459ee..0000000000 --- a/klibc/include/arch/parisc/klibc/archstat.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned long long st_dev; - unsigned int __pad1; - - unsigned int __st_ino; /* Not actually filled in */ - unsigned int st_mode; - unsigned int st_nlink; - unsigned int st_uid; - unsigned int st_gid; - unsigned long long st_rdev; - unsigned int __pad2; - signed long long st_size; - signed int st_blksize; - - signed long long st_blocks; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - unsigned long long st_ino; -}; - -#endif diff --git a/klibc/include/arch/parisc/klibc/archsys.h b/klibc/include/arch/parisc/klibc/archsys.h deleted file mode 100644 index 5013ba8794..0000000000 --- a/klibc/include/arch/parisc/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/parisc/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/ppc/klibc/archsetjmp.h b/klibc/include/arch/ppc/klibc/archsetjmp.h deleted file mode 100644 index 53e2fccc3b..0000000000 --- a/klibc/include/arch/ppc/klibc/archsetjmp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/ppc/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __r2; - unsigned long __sp; - unsigned long __lr; - unsigned long __cr; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __r16; - unsigned long __r17; - unsigned long __r18; - unsigned long __r19; - unsigned long __r20; - unsigned long __r21; - unsigned long __r22; - unsigned long __r23; - unsigned long __r24; - unsigned long __r25; - unsigned long __r26; - unsigned long __r27; - unsigned long __r28; - unsigned long __r29; - unsigned long __r30; - unsigned long __r31; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/ppc/klibc/archsignal.h b/klibc/include/arch/ppc/klibc/archsignal.h deleted file mode 100644 index 567a547ef9..0000000000 --- a/klibc/include/arch/ppc/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/ppc/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/ppc/klibc/archstat.h b/klibc/include/arch/ppc/klibc/archstat.h deleted file mode 100644 index 1d0487b47f..0000000000 --- a/klibc/include/arch/ppc/klibc/archstat.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1. - */ -struct stat { - unsigned long long st_dev; /* Device. */ - unsigned long long st_ino; /* File serial number. */ - unsigned int st_mode; /* File mode. */ - unsigned int st_nlink; /* Link count. */ - unsigned int st_uid; /* User ID of the file's owner. */ - unsigned int st_gid; /* Group ID of the file's group. */ - unsigned long long st_rdev; /* Device number, if device. */ - unsigned short int __pad2; - long long st_size; /* Size of file, in bytes. */ - long st_blksize; /* Optimal block size for I/O. */ - - long long st_blocks; /* Number 512-byte blocks allocated. */ - struct timespec st_atim; /* Time of last access. */ - struct timespec st_mtim; /* Time of last modification. */ - struct timespec st_ctim; /* Time of last status change. */ - unsigned long int __unused4; - unsigned long int __unused5; -}; - -#endif diff --git a/klibc/include/arch/ppc/klibc/archsys.h b/klibc/include/arch/ppc/klibc/archsys.h deleted file mode 100644 index 17a28859e5..0000000000 --- a/klibc/include/arch/ppc/klibc/archsys.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * arch/ppc/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* PowerPC seems to lack _syscall6() in its headers */ -/* This seems to work on both 32- and 64-bit ppc */ - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_7 = (unsigned long) (arg5); \ - __sc_8 = (unsigned long) (arg6); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "+r" (__sc_3), \ - "+r" (__sc_0), \ - "+r" (__sc_4), \ - "+r" (__sc_5), \ - "+r" (__sc_6), \ - "+r" (__sc_7), \ - "+r" (__sc_8) \ - : : "cr0", "ctr", "memory", \ - "r9", "r10", "r11", "r12"); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - if (__sc_err & 0x10000000) \ - { \ - errno = (int)__sc_ret; \ - __sc_ret = -1; \ - } \ - return (type)__sc_ret; \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/ppc64/klibc/archsetjmp.h b/klibc/include/arch/ppc64/klibc/archsetjmp.h deleted file mode 100644 index 006a2e27be..0000000000 --- a/klibc/include/arch/ppc64/klibc/archsetjmp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/ppc64/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __r2; - unsigned long __sp; - unsigned long __lr; - unsigned long __cr; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __r16; - unsigned long __r17; - unsigned long __r18; - unsigned long __r19; - unsigned long __r20; - unsigned long __r21; - unsigned long __r22; - unsigned long __r23; - unsigned long __r24; - unsigned long __r25; - unsigned long __r26; - unsigned long __r27; - unsigned long __r28; - unsigned long __r29; - unsigned long __r30; - unsigned long __r31; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/ppc64/klibc/archsignal.h b/klibc/include/arch/ppc64/klibc/archsignal.h deleted file mode 100644 index 8452f6e4bc..0000000000 --- a/klibc/include/arch/ppc64/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/ppc64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/ppc64/klibc/archstat.h b/klibc/include/arch/ppc64/klibc/archstat.h deleted file mode 100644 index 71f4748690..0000000000 --- a/klibc/include/arch/ppc64/klibc/archstat.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned long st_dev; - ino_t st_ino; - nlink_t st_nlink; - mode_t st_mode; - uid_t st_uid; - gid_t st_gid; - unsigned long st_rdev; - off_t st_size; - unsigned long st_blksize; - unsigned long st_blocks; - struct timespec st_atim; /* Time of last access. */ - struct timespec st_mtim; /* Time of last modification. */ - struct timespec st_ctim; /* Time of last status change. */ - unsigned long __unused4; - unsigned long __unused5; - unsigned long __unused6; -}; - -#endif diff --git a/klibc/include/arch/ppc64/klibc/archsys.h b/klibc/include/arch/ppc64/klibc/archsys.h deleted file mode 100644 index 4f81fee00d..0000000000 --- a/klibc/include/arch/ppc64/klibc/archsys.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * arch/ppc64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - __sc_3 = (unsigned long) (arg1); \ - __sc_4 = (unsigned long) (arg2); \ - __sc_5 = (unsigned long) (arg3); \ - __sc_6 = (unsigned long) (arg4); \ - __sc_7 = (unsigned long) (arg5); \ - __sc_8 = (unsigned long) (arg6); \ - __sc_0 = __NR_##name; \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %1 " \ - : "=&r" (__sc_3), "=&r" (__sc_0) \ - : "0" (__sc_3), "1" (__sc_0), \ - "r" (__sc_4), \ - "r" (__sc_5), \ - "r" (__sc_6), \ - "r" (__sc_7), \ - "r" (__sc_8) \ - : __syscall_clobbers); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - __syscall_return (type); \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/s390/klibc/archsetjmp.h b/klibc/include/arch/s390/klibc/archsetjmp.h deleted file mode 100644 index 11a641ed5a..0000000000 --- a/klibc/include/arch/s390/klibc/archsetjmp.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/s390/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - uint32_t __gregs[10]; /* general registers r6-r15 */ - uint64_t __fpregs[2]; /* fp registers f4 and f6 */ -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/s390/klibc/archsignal.h b/klibc/include/arch/s390/klibc/archsignal.h deleted file mode 100644 index 1f8de28b4b..0000000000 --- a/klibc/include/arch/s390/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/s390/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/s390/klibc/archstat.h b/klibc/include/arch/s390/klibc/archstat.h deleted file mode 100644 index 866c3d4f4c..0000000000 --- a/klibc/include/arch/s390/klibc/archstat.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat { - unsigned long long st_dev; - unsigned int __pad1; -#define STAT64_HAS_BROKEN_ST_INO 1 - unsigned long __st_ino; - unsigned int st_mode; - unsigned int st_nlink; - unsigned long st_uid; - unsigned long st_gid; - unsigned long long st_rdev; - unsigned int __pad3; - long long st_size; - unsigned long st_blksize; - unsigned char __pad4[4]; - unsigned long __pad5; /* future possible st_blocks high bits */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - unsigned long long st_ino; -}; - -#endif diff --git a/klibc/include/arch/s390/klibc/archsys.h b/klibc/include/arch/s390/klibc/archsys.h deleted file mode 100644 index 1cd0948f3c..0000000000 --- a/klibc/include/arch/s390/klibc/archsys.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/s390/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* S/390 only has five syscall parameters, and uses a structure for - 6-argument syscalls. */ - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ - type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - unsigned long __arg[6] = { \ - (unsigned long) arg1, \ - (unsigned long) arg2, \ - (unsigned long) arg3, \ - (unsigned long) arg4, \ - (unsigned long) arg5, \ - (unsigned long) arg6 \ - }; \ - register void *__argp asm("2") = &__arg; \ - long __res; \ - __asm__ __volatile__ ( \ - " svc %b1\n" \ - " lr %0,2" \ - : "=d" (__res) \ - : "i" (__NR_##name), \ - "d" (__argp) \ - : _svc_clobber); \ - __syscall_return(type, __res); \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/s390x/klibc/archsetjmp.h b/klibc/include/arch/s390x/klibc/archsetjmp.h deleted file mode 100644 index dd3ed0d47c..0000000000 --- a/klibc/include/arch/s390x/klibc/archsetjmp.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/s390x/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - uint64_t __gregs[10]; /* general registers r6-r15 */ - uint64_t __fpregs[4]; /* fp registers f1, f3, f5, f7 */ -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/s390x/klibc/archsignal.h b/klibc/include/arch/s390x/klibc/archsignal.h deleted file mode 100644 index 08c9a0073a..0000000000 --- a/klibc/include/arch/s390x/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/s390x/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/s390x/klibc/archstat.h b/klibc/include/arch/s390x/klibc/archstat.h deleted file mode 100644 index 0de73cb2b6..0000000000 --- a/klibc/include/arch/s390x/klibc/archstat.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned long st_dev; - unsigned long st_ino; - unsigned long st_nlink; - unsigned int st_mode; - unsigned int st_uid; - unsigned int st_gid; - unsigned int __pad1; - unsigned long st_rdev; - unsigned long st_size; - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - unsigned long st_blksize; - long st_blocks; - unsigned long __unused[3]; -}; - -#endif diff --git a/klibc/include/arch/s390x/klibc/archsys.h b/klibc/include/arch/s390x/klibc/archsys.h deleted file mode 100644 index 15f7113bb4..0000000000 --- a/klibc/include/arch/s390x/klibc/archsys.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * arch/s390x/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* S/390X only has five syscall parameters, and uses a structure for - 6-argument syscalls. */ - -#ifndef _syscall6 - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,\ - type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5, type6 arg6) { \ - unsigned long __arg[6] = { \ - (unsigned long) arg1, \ - (unsigned long) arg2, \ - (unsigned long) arg3, \ - (unsigned long) arg4, \ - (unsigned long) arg5, \ - (unsigned long) arg6 \ - }; \ - register void *__argp asm("2") = &__arg; \ - long __res; \ - __asm__ __volatile__ ( \ - " svc %b1\n" \ - " lgr %0,2" \ - : "=d" (__res) \ - : "i" (__NR_##name), \ - "d" (__argp) \ - : _svc_clobber); \ - __syscall_return(type, __res); \ -} - -#endif /* _syscall6() missing */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/sh/klibc/archsetjmp.h b/klibc/include/arch/sh/klibc/archsetjmp.h deleted file mode 100644 index 28dd932fbc..0000000000 --- a/klibc/include/arch/sh/klibc/archsetjmp.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * arch/sh/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long r8; - unsigned long r9; - unsigned long r10; - unsigned long r11; - unsigned long r12; - unsigned long r13; - unsigned long r14; - unsigned long r15; - unsigned long pr; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _KLIBC_ARCHSETJMP_H */ diff --git a/klibc/include/arch/sh/klibc/archsignal.h b/klibc/include/arch/sh/klibc/archsignal.h deleted file mode 100644 index 6c4e5976ad..0000000000 --- a/klibc/include/arch/sh/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/sh/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/sh/klibc/archstat.h b/klibc/include/arch/sh/klibc/archstat.h deleted file mode 100644 index 73caceb593..0000000000 --- a/klibc/include/arch/sh/klibc/archstat.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#include - -#define _STATBUF_ST_NSEC - -/* This matches struct stat64 in glibc2.1, hence the absolutely - * insane amounts of padding around dev_t's. - */ -struct stat64 { - unsigned long long st_dev; - unsigned char __pad0[4]; - - unsigned long st_ino; - unsigned int st_mode; - unsigned int st_nlink; - - unsigned long st_uid; - unsigned long st_gid; - - unsigned long long st_rdev; - unsigned char __pad3[4]; - - long long st_size; - unsigned long st_blksize; - -#if __BYTE_ORDER == __BIG_ENDIAN - unsigned long __pad4; /* Future possible st_blocks hi bits */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ -#else /* Must be little */ - unsigned long st_blocks; /* Number 512-byte blocks allocated. */ - unsigned long __pad4; /* Future possible st_blocks hi bits */ -#endif - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned long __unused1; - unsigned long __unused2; -}; - -#endif - diff --git a/klibc/include/arch/sh/klibc/archsys.h b/klibc/include/arch/sh/klibc/archsys.h deleted file mode 100644 index 5f8050a536..0000000000 --- a/klibc/include/arch/sh/klibc/archsys.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * arch/sh/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* No special syscall definitions for this architecture */ - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/sparc/klibc/archsetjmp.h b/klibc/include/arch/sparc/klibc/archsetjmp.h deleted file mode 100644 index 92c1c74c9d..0000000000 --- a/klibc/include/arch/sparc/klibc/archsetjmp.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/sparc/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __sp; - unsigned long __fp; - unsigned long __pc; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/sparc/klibc/archsignal.h b/klibc/include/arch/sparc/klibc/archsignal.h deleted file mode 100644 index 3be67a2158..0000000000 --- a/klibc/include/arch/sparc/klibc/archsignal.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * arch/sparc/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* Hidden definitions */ - -struct __new_sigaction { - __sighandler_t sa_handler; - unsigned long sa_flags; - void (*sa_restorer)(void); /* Not used by Linux/SPARC */ - __new_sigset_t sa_mask; -}; - -struct k_sigaction { - struct __new_sigaction sa; - void __user *ka_restorer; -}; - -struct __old_sigaction { - __sighandler_t sa_handler; - __old_sigset_t sa_mask; - unsigned long sa_flags; - void (*sa_restorer) (void); /* not used by Linux/SPARC */ -}; - -typedef struct sigaltstack { - void __user *ss_sp; - int ss_flags; - size_t ss_size; -} stack_t; - -#endif diff --git a/klibc/include/arch/sparc/klibc/archstat.h b/klibc/include/arch/sparc/klibc/archstat.h deleted file mode 100644 index 0ff68785e5..0000000000 --- a/klibc/include/arch/sparc/klibc/archstat.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned long long st_dev; - - unsigned long long st_ino; - - unsigned int st_mode; - unsigned int st_nlink; - - unsigned int st_uid; - unsigned int st_gid; - - unsigned long long st_rdev; - - unsigned char __pad3[8]; - - long long st_size; - unsigned int st_blksize; - - unsigned char __pad4[8]; - unsigned int st_blocks; - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - - unsigned int __unused4; - unsigned int __unused5; -}; - -#endif diff --git a/klibc/include/arch/sparc/klibc/archsys.h b/klibc/include/arch/sparc/klibc/archsys.h deleted file mode 100644 index 20de8a8b44..0000000000 --- a/klibc/include/arch/sparc/klibc/archsys.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/sparc/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/sparc/machine/asm.h b/klibc/include/arch/sparc/machine/asm.h deleted file mode 100644 index b622bd8cf1..0000000000 --- a/klibc/include/arch/sparc/machine/asm.h +++ /dev/null @@ -1,192 +0,0 @@ -/* $NetBSD: asm.h,v 1.14 2002/07/20 08:37:30 mrg Exp $ */ - -/* - * Copyright (c) 1994 Allen Briggs - * All rights reserved. - * - * Gleaned from locore.s and sun3 asm.h which had the following copyrights: - * locore.s: - * Copyright (c) 1988 University of Utah. - * Copyright (c) 1982, 1990 The Regents of the University of California. - * sun3/include/asm.h: - * Copyright (c) 1993 Adam Glass - * Copyright (c) 1990 The Regents of the University of California. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef _ASM_H_ -#define _ASM_H_ - -/* Pull in CCFSZ, CC64FSZ, and BIAS from frame.h */ -#ifndef _LOCORE -#define _LOCORE -#endif -#include - -#ifdef __ELF__ -#define _C_LABEL(name) name -#else -#ifdef __STDC__ -#define _C_LABEL(name) _ ## name -#else -#define _C_LABEL(name) _/**/name -#endif -#endif -#define _ASM_LABEL(name) name - -#ifdef PIC -/* - * PIC_PROLOGUE() is akin to the compiler generated function prologue for - * PIC code. It leaves the address of the Global Offset Table in DEST, - * clobbering register TMP in the process. - * - * We can use two code sequences. We can read the %pc or use the call - * instruction that saves the pc in %o7. Call requires the branch unit and - * IEU1, and clobbers %o7 which needs to be restored. This instruction - * sequence takes about 4 cycles due to instruction interdependence. Reading - * the pc takes 4 cycles to dispatch and is always dispatched alone. That - * sequence takes 7 cycles. - */ -#ifdef __arch64__ -#define PIC_PROLOGUE(dest,tmp) \ - mov %o7, tmp; \ - sethi %hi(_GLOBAL_OFFSET_TABLE_-4),dest; \ - call 0f; \ - or dest,%lo(_GLOBAL_OFFSET_TABLE_+4),dest; \ -0: \ - add dest,%o7,dest; \ - mov tmp, %o7 -#else -#define PIC_PROLOGUE(dest,tmp) \ - mov %o7,tmp; 3: call 4f; nop; 4: \ - sethi %hi(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ - or dest,%lo(_C_LABEL(_GLOBAL_OFFSET_TABLE_)-(3b-.)),dest; \ - add dest,%o7,dest; mov tmp,%o7 -#endif - -/* - * PICCY_SET() does the equivalent of a `set var, %dest' instruction in - * a PIC-like way, but without involving the Global Offset Table. This - * only works for VARs defined in the same file *and* in the text segment. - */ -#ifdef __arch64__ -#define PICCY_SET(var,dest,tmp) \ - 3: rd %pc, tmp; add tmp,(var-3b),dest -#else -#define PICCY_SET(var,dest,tmp) \ - mov %o7,tmp; 3: call 4f; nop; 4: \ - add %o7,(var-3b),dest; mov tmp,%o7 -#endif -#else -#define PIC_PROLOGUE(dest,tmp) -#define PICCY_OFFSET(var,dest,tmp) -#endif - -#define FTYPE(x) .type x,@function -#define OTYPE(x) .type x,@object - -#define _ENTRY(name) \ - .align 4; .globl name; .proc 1; FTYPE(name); name: - -#ifdef GPROF -/* see _MCOUNT_ENTRY in profile.h */ -#ifdef __ELF__ -#ifdef __arch64__ -#define _PROF_PROLOGUE \ - .data; .align 8; 1: .uaword 0; .uaword 0; \ - .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call _mcount; \ - or %o0,%lo(1b),%o0; restore -#else -#define _PROF_PROLOGUE \ - .data; .align 4; 1: .long 0; \ - .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call _mcount; \ - or %o0,%lo(1b),%o0; restore -#endif -#else -#ifdef __arch64__ -#define _PROF_PROLOGUE \ - .data; .align 8; 1: .uaword 0; .uaword 0; \ - .text; save %sp,-CC64FSZ,%sp; sethi %hi(1b),%o0; call mcount; \ - or %o0,%lo(1b),%o0; restore -#else -#define _PROF_PROLOGUE \ - .data; .align 4; 1: .long 0; \ - .text; save %sp,-96,%sp; sethi %hi(1b),%o0; call mcount; \ - or %o0,%lo(1b),%o0; restore -#endif -#endif -#else -#define _PROF_PROLOGUE -#endif - -#define ENTRY(name) _ENTRY(_C_LABEL(name)); _PROF_PROLOGUE -#define ENTRY_NOPROFILE(name) _ENTRY(_C_LABEL(name)) -#define ASENTRY(name) _ENTRY(_ASM_LABEL(name)); _PROF_PROLOGUE -#define FUNC(name) ASENTRY(name) -#define RODATA(name) .align 4; .text; .globl _C_LABEL(name); \ - OTYPE(_C_LABEL(name)); _C_LABEL(name): - - -#define ASMSTR .asciz - -#define RCSID(name) .asciz name - -#ifdef __ELF__ -#define WEAK_ALIAS(alias,sym) \ - .weak alias; \ - alias = sym -#endif - -/* - * WARN_REFERENCES: create a warning if the specified symbol is referenced. - */ -#ifdef __ELF__ -#ifdef __STDC__ -#define WARN_REFERENCES(_sym,_msg) \ - .section .gnu.warning. ## _sym ; .ascii _msg ; .text -#else -#define WARN_REFERENCES(_sym,_msg) \ - .section .gnu.warning./**/_sym ; .ascii _msg ; .text -#endif /* __STDC__ */ -#else -#ifdef __STDC__ -#define __STRING(x) #x -#define WARN_REFERENCES(sym,msg) \ - .stabs msg ## ,30,0,0,0 ; \ - .stabs __STRING(_ ## sym) ## ,1,0,0,0 -#else -#define __STRING(x) "x" -#define WARN_REFERENCES(sym,msg) \ - .stabs msg,30,0,0,0 ; \ - .stabs __STRING(_/**/sym),1,0,0,0 -#endif /* __STDC__ */ -#endif /* __ELF__ */ - -#endif /* _ASM_H_ */ diff --git a/klibc/include/arch/sparc/machine/frame.h b/klibc/include/arch/sparc/machine/frame.h deleted file mode 100644 index b09175c7f4..0000000000 --- a/klibc/include/arch/sparc/machine/frame.h +++ /dev/null @@ -1,138 +0,0 @@ -/* $NetBSD: frame.h,v 1.4 2001/12/04 00:05:05 darrenr Exp $ */ - -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)frame.h 8.1 (Berkeley) 6/11/93 - */ - -#if defined(_KERNEL_OPT) -#include "opt_sparc_arch.h" -#endif - -/* - * Sparc stack frame format. - * - * Note that the contents of each stack frame may be held only in - * machine register windows. In order to get an accurate picture - * of the frame, you must first force the kernel to write any such - * windows to the stack. - */ -#ifndef _LOCORE -#ifndef SUN4U -struct frame { - int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ - int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ - struct frame *fr_fp; /* space to save frame pointer (%i6) */ - int32_t fr_pc; /* space to save return pc (%i7) */ - /* - * SunOS reserves another 8 words here; this is pointless - * but we do it for compatibility. - */ - int32_t fr_xxx; /* `structure return pointer' (unused) */ - int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ - int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ -}; -#else -struct frame32 { - int32_t fr_local[8]; /* space to save locals (%l0..%l7) */ - int32_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ - u_int32_t fr_fp; /* space to save frame pointer (%i6) */ - u_int32_t fr_pc; /* space to save return pc (%i7) */ - /* - * SunOS reserves another 8 words here; this is pointless - * but we do it for compatibility. - */ - int32_t fr_xxx; /* `structure return pointer' (unused) */ - int32_t fr_argd[6]; /* `arg dump area' (lunacy) */ - int32_t fr_argx[1]; /* arg extension (args 7..n; variable size) */ -}; -#endif -#endif - -/* - * CCFSZ (C Compiler Frame SiZe) is the size of a stack frame required if - * a function is to call C code. It should be just 64, but Sun defined - * their frame with space to hold arguments 0 through 5 (plus some junk), - * and varargs routines (such as kprintf) demand this, and gcc uses this - * area at times anyway. - */ -#define CCFSZ 96 - -/* - * Sparc v9 stack frame format. - * - * Note that the contents of each stack frame may be held only in - * machine register windows. In order to get an accurate picture - * of the frame, you must first force the kernel to write any such - * windows to the stack. - * - * V9 frames have an odd bias, so you can tall a v9 frame from - * a v8 frame by testing the stack pointer's lsb. - */ -#if !defined(_LOCORE) && !defined(_LIBC) -struct frame64 { - int64_t fr_local[8]; /* space to save locals (%l0..%l7) */ - int64_t fr_arg[6]; /* space to save arguments (%i0..%i5) */ - u_int64_t fr_fp; /* space to save frame pointer (%i6) */ - u_int64_t fr_pc; /* space to save return pc (%i7) */ - /* - * SVR4 reserves a bunch of extra stuff. - */ - int64_t fr_argd[6]; /* `register save area' (lunacy) */ - int64_t fr_argx[0]; /* arg extension (args 7..n; variable size) */ -}; - -#define v9next_frame(f) ((struct frame64*)(f->fr_fp+BIAS)) -#endif - -/* - * CC64FSZ (C Compiler 64-bit Frame SiZe) is the size of a stack frame used - * by the compiler in 64-bit mode. It is (16)*8; space for 8 ins, 8 outs. - */ -#define CC64FSZ 176 - -/* - * v9 stacks all have a bias of 2047 added to the %sp and %fp, so you can easily - * detect it by testing the register for an odd value. Why 2K-1 I don't know. - */ -#define BIAS (2048-1) - diff --git a/klibc/include/arch/sparc/machine/trap.h b/klibc/include/arch/sparc/machine/trap.h deleted file mode 100644 index 42c3ef6ae2..0000000000 --- a/klibc/include/arch/sparc/machine/trap.h +++ /dev/null @@ -1,141 +0,0 @@ -/* $NetBSD: trap.h,v 1.11 1999/01/20 00:15:08 pk Exp $ */ - -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Lawrence Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)trap.h 8.1 (Berkeley) 6/11/93 - */ -/* - * Sun4m support by Aaron Brown, Harvard University. - * Changes Copyright (c) 1995 The President and Fellows of Harvard College. - * All rights reserved. - */ - -#ifndef _MACHINE_TRAP_H -#define _MACHINE_TRAP_H - -/* trap vec (pri) description */ -#define T_RESET 0x00 /* (1) not actually vectored; jumps to 0 */ -#define T_TEXTFAULT 0x01 /* (2) address fault during instr fetch */ -#define T_ILLINST 0x02 /* (3) illegal instruction */ -#define T_PRIVINST 0x03 /* (4) privileged instruction */ -#define T_FPDISABLED 0x04 /* (5) fp instr while fp disabled */ -#define T_WINOF 0x05 /* (6) register window overflow */ -#define T_WINUF 0x06 /* (7) register window underflow */ -#define T_ALIGN 0x07 /* (8) address not properly aligned */ -#define T_FPE 0x08 /* (9) floating point exception */ -#define T_DATAFAULT 0x09 /* (10) address fault during data fetch */ -#define T_TAGOF 0x0a /* (11) tag overflow */ -/* 0x0b unused */ -/* 0x0c unused */ -/* 0x0d unused */ -/* 0x0e unused */ -/* 0x0f unused */ -/* 0x10 unused */ -#define T_L1INT 0x11 /* (27) level 1 interrupt */ -#define T_L2INT 0x12 /* (26) level 2 interrupt */ -#define T_L3INT 0x13 /* (25) level 3 interrupt */ -#define T_L4INT 0x14 /* (24) level 4 interrupt */ -#define T_L5INT 0x15 /* (23) level 5 interrupt */ -#define T_L6INT 0x16 /* (22) level 6 interrupt */ -#define T_L7INT 0x17 /* (21) level 7 interrupt */ -#define T_L8INT 0x18 /* (20) level 8 interrupt */ -#define T_L9INT 0x19 /* (19) level 9 interrupt */ -#define T_L10INT 0x1a /* (18) level 10 interrupt */ -#define T_L11INT 0x1b /* (17) level 11 interrupt */ -#define T_L12INT 0x1c /* (16) level 12 interrupt */ -#define T_L13INT 0x1d /* (15) level 13 interrupt */ -#define T_L14INT 0x1e /* (14) level 14 interrupt */ -#define T_L15INT 0x1f /* (13) level 15 interrupt */ -/* 0x20 unused */ -/* through 0x23 unused */ -#define T_CPDISABLED 0x24 /* (5) coprocessor instr while disabled */ -#define T_UNIMPLFLUSH 0x25 /* Unimplemented FLUSH */ -/* through 0x27 unused */ -#define T_CPEXCEPTION 0x28 /* (9) coprocessor exception */ -/* 0x29 unused */ -#define T_IDIV0 0x2a /* divide by zero (from hw [su]div instr) */ -#define T_STOREBUFFAULT 0x2b /* SuperSPARC: Store buffer copy-back fault */ -/* 0x2c unused */ -/* through 0x7f unused */ - -/* beginning of `user' vectors (from trap instructions) - all priority 12 */ -#define T_SUN_SYSCALL 0x80 /* system call */ -#define T_BREAKPOINT 0x81 /* breakpoint `instruction' */ -#define T_DIV0 0x82 /* division routine was handed 0 */ -#define T_FLUSHWIN 0x83 /* flush windows */ -#define T_CLEANWIN 0x84 /* provide clean windows */ -#define T_RANGECHECK 0x85 /* ? */ -#define T_FIXALIGN 0x86 /* fix up unaligned accesses */ -#define T_INTOF 0x87 /* integer overflow ? */ -#define T_SVR4_SYSCALL 0x88 /* SVR4 system call */ -#define T_BSD_SYSCALL 0x89 /* BSD system call */ -#define T_KGDB_EXEC 0x8a /* for kernel gdb */ - -/* 0x8b..0xff are currently unallocated, except the following */ -#define T_SVR4_GETCC 0xa0 -#define T_SVR4_SETCC 0xa1 -#define T_SVR4_GETPSR 0xa2 -#define T_SVR4_SETPSR 0xa3 -#define T_SVR4_GETHRTIME 0xa4 -#define T_SVR4_GETHRVTIME 0xa5 -#define T_SVR4_GETHRESTIME 0xa7 - - -#ifdef _KERNEL /* pseudo traps for locore.s */ -#define T_RWRET -1 /* need first user window for trap return */ -#define T_AST -2 /* no-op, just needed reschedule or profile */ -#endif - -/* flags to system call (flags in %g1 along with syscall number) */ -#define SYSCALL_G2RFLAG 0x400 /* on success, return to %g2 rather than npc */ -#define SYSCALL_G7RFLAG 0x800 /* use %g7 as above (deprecated) */ - -/* - * `software trap' macros to keep people happy (sparc v8 manual says not - * to set the upper bits). - */ -#define ST_BREAKPOINT (T_BREAKPOINT & 0x7f) -#define ST_DIV0 (T_DIV0 & 0x7f) -#define ST_FLUSHWIN (T_FLUSHWIN & 0x7f) -#define ST_SYSCALL (T_SUN_SYSCALL & 0x7f) - -#endif /* _MACHINE_TRAP_H_ */ diff --git a/klibc/include/arch/sparc64/klibc/archsetjmp.h b/klibc/include/arch/sparc64/klibc/archsetjmp.h deleted file mode 100644 index 022a31e542..0000000000 --- a/klibc/include/arch/sparc64/klibc/archsetjmp.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/sparc64/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __sp; - unsigned long __fp; - unsigned long __pc; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/sparc64/klibc/archsignal.h b/klibc/include/arch/sparc64/klibc/archsignal.h deleted file mode 100644 index f81bd668bb..0000000000 --- a/klibc/include/arch/sparc64/klibc/archsignal.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/sparc64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* No special stuff for this architecture */ - -#endif diff --git a/klibc/include/arch/sparc64/klibc/archstat.h b/klibc/include/arch/sparc64/klibc/archstat.h deleted file mode 100644 index c22905d30c..0000000000 --- a/klibc/include/arch/sparc64/klibc/archstat.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -/* No nsec fields?! */ -struct stat { - unsigned st_dev; - ino_t st_ino; - mode_t st_mode; - short st_nlink; - uid_t st_uid; - gid_t st_gid; - unsigned st_rdev; - off_t st_size; - time_t st_atime; - time_t st_mtime; - time_t st_ctime; - off_t st_blksize; - off_t st_blocks; - unsigned long __unused4[2]; -}; - -#endif diff --git a/klibc/include/arch/sparc64/klibc/archsys.h b/klibc/include/arch/sparc64/klibc/archsys.h deleted file mode 100644 index 6a3a7b25bc..0000000000 --- a/klibc/include/arch/sparc64/klibc/archsys.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * arch/sparc64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/x86_64/klibc/archsetjmp.h b/klibc/include/arch/x86_64/klibc/archsetjmp.h deleted file mode 100644 index 90d0a0d263..0000000000 --- a/klibc/include/arch/x86_64/klibc/archsetjmp.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/x86_64/include/klibc/archsetjmp.h - */ - -#ifndef _KLIBC_ARCHSETJMP_H -#define _KLIBC_ARCHSETJMP_H - -struct __jmp_buf { - unsigned long __rbx; - unsigned long __rsp; - unsigned long __rbp; - unsigned long __r12; - unsigned long __r13; - unsigned long __r14; - unsigned long __r15; - unsigned long __rip; -}; - -typedef struct __jmp_buf jmp_buf[1]; - -#endif /* _SETJMP_H */ diff --git a/klibc/include/arch/x86_64/klibc/archsignal.h b/klibc/include/arch/x86_64/klibc/archsignal.h deleted file mode 100644 index 527241454e..0000000000 --- a/klibc/include/arch/x86_64/klibc/archsignal.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * arch/x86_64/include/klibc/archsignal.h - * - * Architecture-specific signal definitions - * - */ - -#ifndef _KLIBC_ARCHSIGNAL_H -#define _KLIBC_ARCHSIGNAL_H - -/* The x86-64 headers defines NSIG 32, but it's actually 64 */ -#undef _NSIG -#undef NSIG -#define _NSIG 64 -#define NSIG _NSIG - -#endif diff --git a/klibc/include/arch/x86_64/klibc/archstat.h b/klibc/include/arch/x86_64/klibc/archstat.h deleted file mode 100644 index 53e141daea..0000000000 --- a/klibc/include/arch/x86_64/klibc/archstat.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef _KLIBC_ARCHSTAT_H -#define _KLIBC_ARCHSTAT_H - -#define _STATBUF_ST_NSEC - -struct stat { - unsigned long st_dev; - unsigned long st_ino; - unsigned long st_nlink; - - unsigned int st_mode; - unsigned int st_uid; - unsigned int st_gid; - unsigned int __pad0; - unsigned long st_rdev; - long st_size; - long st_blksize; - long st_blocks; /* Number 512-byte blocks allocated. */ - - struct timespec st_atim; - struct timespec st_mtim; - struct timespec st_ctim; - long __unused[3]; -}; - -#endif diff --git a/klibc/include/arch/x86_64/klibc/archsys.h b/klibc/include/arch/x86_64/klibc/archsys.h deleted file mode 100644 index 2ec72cd397..0000000000 --- a/klibc/include/arch/x86_64/klibc/archsys.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * arch/x86_64/include/klibc/archsys.h - * - * Architecture-specific syscall definitions - */ - -#ifndef _KLIBC_ARCHSYS_H -#define _KLIBC_ARCHSYS_H - -/* The x86-64 syscall headers are needlessly inefficient */ - -#undef _syscall0 -#undef _syscall1 -#undef _syscall2 -#undef _syscall3 -#undef _syscall4 -#undef _syscall5 -#undef _syscall6 - -#define _syscall0(type,name) \ -type name (void) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name (type1 arg1) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name (type1 arg1,type2 arg2) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name (type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ -{ \ -long __res; \ -register type4 __r10 asm("%r10") = arg4; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3),"r" (__r10) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -register type4 __r10 asm("%r10") = arg4; \ -register type5 __r8 asm("%r8") = arg5; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3),"r" (__r10),"r" (__r8) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ -long __res; \ -register type4 __r10 asm("%r10") = arg4; \ -register type5 __r8 asm("%r8") = arg5; \ -register type6 __r9 asm("%r9") = arg6; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" (arg1),"S" (arg2), \ - "d" (arg3),"r" (__r10),"r" (__r8), "r" (__r9) \ - : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#endif /* _KLIBC_ARCHSYS_H */ diff --git a/klibc/include/arch/x86_64/sys/io.h b/klibc/include/arch/x86_64/sys/io.h deleted file mode 100644 index 4a0ae44985..0000000000 --- a/klibc/include/arch/x86_64/sys/io.h +++ /dev/null @@ -1,126 +0,0 @@ -#ident "$Id: io.h,v 1.1 2004/01/25 01:34:29 hpa Exp $" -/* ----------------------------------------------------------------------- * - * - * Copyright 2004 H. Peter Anvin - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * sys/io.h for the i386 architecture - * - * Basic I/O macros - */ - -#ifndef _SYS_IO_H -#define _SYS_IO_H 1 - -/* I/O-related system calls */ - -int iopl(int); -int ioperm(unsigned long, unsigned long, int); - -/* Basic I/O macros */ - -static __inline__ void -outb(unsigned char __v, unsigned short __p) -{ - asm volatile("outb %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outw(unsigned short __v, unsigned short __p) -{ - asm volatile("outw %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ void -outl(unsigned int __v, unsigned short __p) -{ - asm volatile("outl %0,%1" : : "a" (__v), "dN" (__p)); -} - -static __inline__ unsigned char -inb(unsigned short __p) -{ - unsigned char __v; - asm volatile("inb %1,%0" : "=a" (__v) : "dN" (__p)); - return v; -} - -static __inline__ unsigned short -inw(unsigned short __p) -{ - unsigned short __v; - asm volatile("inw %1,%0" : "=a" (__v) : "dN" (__p)); - return v; -} - -static __inline__ unsigned int -inl(unsigned short __p) -{ - unsigned int __v; - asm volatile("inl %1,%0" : "=a" (__v) : "dN" (__p)); - return v; -} - -/* String I/O macros */ - -static __inline__ void -outsb (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsb" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsw (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsw" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -outsl (unsigned short __p, const void *__d, unsigned long __n) -{ - asm volatile("cld; rep; outsl" : "+S" (__d), "+c" (__n) : "d" (__p)); -} - - -static __inline__ void -insb (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insb" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insw (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insw" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -static __inline__ void -insl (unsigned short __p, void *__d, unsigned long __n) -{ - asm volatile("cld; rep; insl" : "+D" (__d), "+c" (__n) : "d" (__p)); -} - -#endif /* _SYS_IO_H */ diff --git a/klibc/include/arpa/inet.h b/klibc/include/arpa/inet.h deleted file mode 100644 index 043b148e17..0000000000 --- a/klibc/include/arpa/inet.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * arpa/inet.h - */ - -#ifndef _ARPA_INET_H -#define _ARPA_INET_H - -#include -#include -#include -#include -#include - -__extern uint32_t inet_addr(const char *); -__extern int inet_aton(const char *, struct in_addr *); -__extern char *inet_ntoa(struct in_addr); -__extern int inet_pton(int, const char *, void *); -__extern const char *inet_ntop(int, const void *, char *, size_t); -__extern unsigned int inet_nsap_addr(const char *, unsigned char *, int); -__extern char *inet_nsap_ntoa(int, const unsigned char *, char *); - -#endif /* _ARPA_INET_H */ - - diff --git a/klibc/include/assert.h b/klibc/include/assert.h deleted file mode 100644 index 58cc37c487..0000000000 --- a/klibc/include/assert.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * assert.h - */ - -#ifndef _ASSERT_H -#define _ASSERT_H - -#ifdef NDEBUG - -#define assert(x) ((void)(x)) - -#else - -extern void __assert_fail(const char *, const char *, - unsigned int); - -#define assert(x) ((x) ? (void)0 : __assert_fail(#x, __FILE__, __LINE__)) - -#endif - -#endif /* _ASSERT_H */ - diff --git a/klibc/include/bits32/bitsize.h b/klibc/include/bits32/bitsize.h deleted file mode 100644 index 06cc885983..0000000000 --- a/klibc/include/bits32/bitsize.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef _BITSIZE -#define _BITSIZE 32 -#endif diff --git a/klibc/include/bits32/bitsize/limits.h b/klibc/include/bits32/bitsize/limits.h deleted file mode 100644 index f90e524b2b..0000000000 --- a/klibc/include/bits32/bitsize/limits.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * bits32/limits.h - */ - -#ifndef _BITSIZE_LIMITS_H -#define _BITSIZE_LIMITS_H - -#define LONG_BIT 32 - -#define LONG_MIN (-2147483647L-1) -#define LONG_MAX 2147483647L -#define ULONG_MAX 4294967295UL - -#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/include/bits32/bitsize/stddef.h b/klibc/include/bits32/bitsize/stddef.h deleted file mode 100644 index c486041fe0..0000000000 --- a/klibc/include/bits32/bitsize/stddef.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bits32/stddef.h - */ - -#ifndef _BITSIZE_STDDEF_H -#define _BITSIZE_STDDEF_H - -#define _SIZE_T -#if defined(__s390__) || defined(__hppa__) || defined(__cris__) -typedef unsigned long size_t; -#else -typedef unsigned int size_t; -#endif - -#define _PTRDIFF_T -typedef signed int ptrdiff_t; - -#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/include/bits32/bitsize/stdint.h b/klibc/include/bits32/bitsize/stdint.h deleted file mode 100644 index 40b464961c..0000000000 --- a/klibc/include/bits32/bitsize/stdint.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * bits32/stdint.h - */ - -#ifndef _BITSIZE_STDINT_H -#define _BITSIZE_STDINT_H - -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long int uint64_t; - -typedef int int_fast16_t; -typedef int int_fast32_t; - -typedef unsigned int uint_fast16_t; -typedef unsigned int uint_fast32_t; - -typedef int intptr_t; -typedef unsigned int uintptr_t; - -#define __INT64_C(c) c ## LL -#define __UINT64_C(c) c ## ULL - -#define __PRI64_RANK "ll" -#define __PRIFAST_RANK "" -#define __PRIPTR_RANK "" - -#endif /* _BITSIZE_STDINT_H */ diff --git a/klibc/include/bits32/bitsize/stdintconst.h b/klibc/include/bits32/bitsize/stdintconst.h deleted file mode 100644 index 8157dd06e0..0000000000 --- a/klibc/include/bits32/bitsize/stdintconst.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bits32/stdintconst.h - */ - -#ifndef _BITSIZE_STDINTCONST_H -#define _BITSIZE_STDINTCONST_H - -#define INT_FAST16_C(c) INT32_C(c) -#define INT_FAST32_C(c) INT32_C(c) - -#define UINT_FAST16_C(c) UINT32_C(c) -#define UINT_FAST32_C(c) UINT32_C(c) - -#define INTPTR_C(c) INT32_C(c) -#define UINTPTR_C(c) UINT32_C(c) -#define PTRDIFF_C(c) INT32_C(c) - -#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/include/bits32/bitsize/stdintlimits.h b/klibc/include/bits32/bitsize/stdintlimits.h deleted file mode 100644 index b44fe01186..0000000000 --- a/klibc/include/bits32/bitsize/stdintlimits.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * bits32/stdintlimits.h - */ - -#ifndef _BITSIZE_STDINTLIMITS_H -#define _BITSIZE_STDINTLIMITS_H - -#define INT_FAST16_MIN INT32_MIN -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST16_MAX INT32_MAX -#define INT_FAST32_MAX INT32_MAX -#define UINT_FAST16_MAX UINT32_MAX -#define UINT_FAST32_MAX UINT32_MAX - -#define INTPTR_MIN INT32_MIN -#define INTPTR_MAX INT32_MAX -#define UINTPTR_MAX UINT32_MAX - -#define PTRDIFF_MIN INT32_MIN -#define PTRDIFF_MAX INT32_MAX - -#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/include/bits64/bitsize.h b/klibc/include/bits64/bitsize.h deleted file mode 100644 index 54696fd70e..0000000000 --- a/klibc/include/bits64/bitsize.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef _BITSIZE -#define _BITSIZE 64 -#endif diff --git a/klibc/include/bits64/bitsize/limits.h b/klibc/include/bits64/bitsize/limits.h deleted file mode 100644 index 7b20da085b..0000000000 --- a/klibc/include/bits64/bitsize/limits.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * bits64/limits.h - */ - -#ifndef _BITSIZE_LIMITS_H -#define _BITSIZE_LIMITS_H - -#define LONG_BIT 64 - -#define LONG_MIN (-9223372036854775807L-1) -#define LONG_MAX 9223372036854775807L -#define ULONG_MAX 18446744073709551615UL - -#endif /* _BITSIZE_LIMITS_H */ diff --git a/klibc/include/bits64/bitsize/stddef.h b/klibc/include/bits64/bitsize/stddef.h deleted file mode 100644 index 3e72621862..0000000000 --- a/klibc/include/bits64/bitsize/stddef.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * bits64/stddef.h - */ - -#ifndef _BITSIZE_STDDEF_H -#define _BITSIZE_STDDEF_H - -#define _SIZE_T -typedef unsigned long size_t; -#define _PTRDIFF_T -typedef signed long ptrdiff_t; - -#endif /* _BITSIZE_STDDEF_H */ diff --git a/klibc/include/bits64/bitsize/stdint.h b/klibc/include/bits64/bitsize/stdint.h deleted file mode 100644 index 8e16cf0909..0000000000 --- a/klibc/include/bits64/bitsize/stdint.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * bits64/stdint.h - */ - -#ifndef _BITSIZE_STDINT_H -#define _BITSIZE_STDINT_H - -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long int int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long int uint64_t; - -typedef long int int_fast16_t; -typedef long int int_fast32_t; - -typedef unsigned long int uint_fast16_t; -typedef unsigned long int uint_fast32_t; - -typedef long int intptr_t; -typedef unsigned long int uintptr_t; - -#define __INT64_C(c) c ## L -#define __UINT64_C(c) c ## UL - -#define __PRI64_RANK "l" -#define __PRIFAST_RANK "l" -#define __PRIPTR_RANK "l" - -#endif /* _BITSIZE_STDINT_H */ - - diff --git a/klibc/include/bits64/bitsize/stdintconst.h b/klibc/include/bits64/bitsize/stdintconst.h deleted file mode 100644 index 65f2db0501..0000000000 --- a/klibc/include/bits64/bitsize/stdintconst.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * bits64/stdintconst.h - */ - -#ifndef _BITSIZE_STDINTCONST_H -#define _BITSIZE_STDINTCONST_H - -#define INT_FAST16_C(c) INT64_C(c) -#define INT_FAST32_C(c) INT64_C(c) - -#define UINT_FAST16_C(c) UINT64_C(c) -#define UINT_FAST32_C(c) UINT64_C(c) - -#define INTPTR_C(c) INT64_C(c) -#define UINTPTR_C(c) UINT64_C(c) -#define PTRDIFF_C(c) INT64_C(c) - -#endif /* _BITSIZE_STDINTCONST_H */ diff --git a/klibc/include/bits64/bitsize/stdintlimits.h b/klibc/include/bits64/bitsize/stdintlimits.h deleted file mode 100644 index d110d17d2d..0000000000 --- a/klibc/include/bits64/bitsize/stdintlimits.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * bits64/stdintlimits.h - */ - -#ifndef _BITSIZE_STDINTLIMITS_H -#define _BITSIZE_STDINTLIMITS_H - -#define INT_FAST16_MIN INT64_MIN -#define INT_FAST32_MIN INT64_MIN -#define INT_FAST16_MAX INT64_MAX -#define INT_FAST32_MAX INT64_MAX -#define UINT_FAST16_MAX UINT64_MAX -#define UINT_FAST32_MAX UINT64_MAX - -#define INTPTR_MIN INT64_MIN -#define INTPTR_MAX INT64_MAX -#define UINTPTR_MAX UINT64_MAX - -#define PTRDIFF_MIN INT64_MIN -#define PTRDIFF_MAX INT64_MAX - -#endif /* _BITSIZE_STDINTLIMITS_H */ diff --git a/klibc/include/ctype.h b/klibc/include/ctype.h deleted file mode 100644 index daa6a8eff4..0000000000 --- a/klibc/include/ctype.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * ctype.h - * - * This assumes ISO 8859-1, being a reasonable superset of ASCII. - */ - -#ifndef _CTYPE_H -#define _CTYPE_H - -#ifndef __CTYPE_NO_INLINE -# define __ctype_inline extern __inline__ -#else -# define __ctype_inline -#endif - -/* - * This relies on the following definitions: - * - * cntrl = !print - * alpha = upper|lower - * graph = punct|alpha|digit - * blank = '\t' || ' ' (per POSIX requirement) - */ -enum { - __ctype_upper = (1 << 0), - __ctype_lower = (1 << 1), - __ctype_digit = (1 << 2), - __ctype_xdigit = (1 << 3), - __ctype_space = (1 << 4), - __ctype_print = (1 << 5), - __ctype_punct = (1 << 6), - __ctype_cntrl = (1 << 7), -}; - -extern const unsigned char __ctypes[]; - -__ctype_inline int isalnum(int __c) -{ - return __ctypes[__c+1] & - (__ctype_upper|__ctype_lower|__ctype_digit); -} - -__ctype_inline int isalpha(int __c) -{ - return __ctypes[__c+1] & - (__ctype_upper|__ctype_lower); -} - -__ctype_inline int isascii(int __c) -{ - return !(__c & ~0x7f); -} - -__ctype_inline int isblank(int __c) -{ - return (__c == '\t') || (__c == ' '); -} - -__ctype_inline int iscntrl(int __c) -{ - return __ctypes[__c+1] & __ctype_cntrl; -} - -__ctype_inline int isdigit(int __c) -{ - return ((unsigned)__c - '0') <= 9; -} - -__ctype_inline int isgraph(int __c) -{ - return __ctypes[__c+1] & - (__ctype_upper|__ctype_lower|__ctype_digit|__ctype_punct); -} - -__ctype_inline int islower(int __c) -{ - return __ctypes[__c+1] & __ctype_lower; -} - -__ctype_inline int isprint(int __c) -{ - return __ctypes[__c+1] & __ctype_print; -} - -__ctype_inline int ispunct(int __c) -{ - return __ctypes[__c+1] & __ctype_punct; -} - -__ctype_inline int isspace(int __c) -{ - return __ctypes[__c+1] & __ctype_space; -} - -__ctype_inline int isupper(int __c) -{ - return __ctypes[__c+1] & __ctype_upper; -} - -__ctype_inline int isxdigit(int __c) -{ - return __ctypes[__c+1] & __ctype_xdigit; -} - -/* Note: this is decimal, not hex, to avoid accidental promotion to unsigned */ -#define _toupper(__c) ((__c) & ~32) -#define _tolower(__c) ((__c) | 32) - -__ctype_inline int toupper(int __c) -{ - return islower(__c) ? _toupper(__c) : __c; -} - -__ctype_inline int tolower(int __c) -{ - return isupper(__c) ? _tolower(__c) : __c; -} - -#endif /* _CTYPE_H */ diff --git a/klibc/include/dirent.h b/klibc/include/dirent.h deleted file mode 100644 index 4db479592b..0000000000 --- a/klibc/include/dirent.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * dirent.h - */ - -#ifndef _DIRENT_H -#define _DIRENT_H - -#include -#include - -struct _IO_dir { - int __fd; - -#ifdef __KLIBC_DIRENT_INTERNALS - /* These fields for internal use only */ - - size_t bytes_left; - struct dirent *next; - /* Declaring this as an array of struct enforces correct alignment */ - struct dirent buffer[15]; /* 15 times max dirent size =~ 4K */ -#endif -}; -typedef struct _IO_dir DIR; - -__extern DIR *opendir(const char *); -__extern struct dirent *readdir(DIR *); -__extern int closedir(DIR *); -static __inline__ int dirfd (DIR *__d) { - return __d->__fd; -} - -#endif /* _DIRENT_H */ diff --git a/klibc/include/elf.h b/klibc/include/elf.h deleted file mode 100644 index 52f47d042e..0000000000 --- a/klibc/include/elf.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * elf.h - */ - -#ifndef _ELF_H -#define _ELF_H - -#include -#include - -#endif /* _ELF_H */ - diff --git a/klibc/include/endian.h b/klibc/include/endian.h deleted file mode 100644 index 44f89ccbbc..0000000000 --- a/klibc/include/endian.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * endian.h - */ - -#ifndef _ENDIAN_H -#define _ENDIAN_H - -#include -#include - -/* Linux' asm/byteorder.h defines either __LITTLE_ENDIAN or - __BIG_ENDIAN, but the glibc/BSD-ish macros expect both to be - defined with __BYTE_ORDER defining which is actually used... */ - -#if defined(__LITTLE_ENDIAN) -# undef __LITTLE_ENDIAN -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# define __PDP_ENDIAN 3412 -# define __BYTE_ORDER __LITTLE_ENDIAN -#elif defined(__BIG_ENDIAN) -# undef __BIG_ENDIAN -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# define __PDP_ENDIAN 3412 -# define __BYTE_ORDER __BIG_ENDIAN -#elif defined(__PDP_ENDIAN) -# undef __PDP_ENDIAN -# define __LITTLE_ENDIAN 1234 -# define __BIG_ENDIAN 4321 -# define __PDP_ENDIAN 3412 -# define __BYTE_ORDER __PDP_ENDIAN -#else -# error "Unknown byte order!" -#endif - -#define LITTLE_ENDIAN __LITTLE_ENDIAN -#define BIG_ENDIAN __BIG_ENDIAN -#define PDP_ENDIAN __PDP_ENDIAN -#define BYTE_ORDER __BYTE_ORDER - -#endif /* _ENDIAN_H */ diff --git a/klibc/include/errno.h b/klibc/include/errno.h deleted file mode 100644 index b2e666504d..0000000000 --- a/klibc/include/errno.h +++ /dev/null @@ -1,8 +0,0 @@ -/* - * errno.h - */ - -#include -#include - -__extern int errno; diff --git a/klibc/include/fcntl.h b/klibc/include/fcntl.h deleted file mode 100644 index c9650f76b5..0000000000 --- a/klibc/include/fcntl.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * fcntl.h - */ - -#ifndef _FCNTL_H -#define _FCNTL_H - -#include -#include -#include -#if defined(__mips__) && !defined(__mips64__) -# include -#endif -#include - -/* This is ugly, but "struct flock" has actually been defined with - a long off_t, so it's really "struct flock64". It just happens - to work. Gag. Barf. - - This happens to work on all 32-bit architectures except MIPS. */ - -#ifdef F_GETLK64 -# undef F_GETLK -# define F_GETLK F_GETLK64 -#endif - -#ifdef F_SETLK64 -# undef F_SETLK -# define F_SETLK F_SETLK64 -#endif - -#ifdef F_SETLKW64 -# undef F_SETLKW -# define F_SETLKW F_SETLKW64 -#endif - -/* This is defined here as well as in since old-style code - would still include when using open(), and open() being - a varadic function changes its calling convention on some architectures. */ -#ifndef _KLIBC_IN_OPEN_C -__extern int open(const char *, int, ...); -#endif - -__extern int fcntl(int, int, ...); - -#endif /* _FCNTL_H */ diff --git a/klibc/include/grp.h b/klibc/include/grp.h deleted file mode 100644 index 03ceb31560..0000000000 --- a/klibc/include/grp.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * grp.h - */ - -#ifndef _GRP_H -#define _GRP_H - -#include -#include - -__extern int setgroups(size_t, const gid_t *); - -#endif /* _GRP_H */ diff --git a/klibc/include/inttypes.h b/klibc/include/inttypes.h deleted file mode 100644 index e00fa63160..0000000000 --- a/klibc/include/inttypes.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * inttypes.h - */ - -#ifndef _INTTYPES_H -#define _INTTYPES_H - -#include -#include -#include - -static __inline__ intmax_t imaxabs(intmax_t __n) -{ - return (__n < (intmax_t)0) ? -__n : __n; -} - -__extern intmax_t strtoimax(const char *, char **, int); -__extern uintmax_t strtoumax(const char *, char **, int); - -/* extensions */ -__extern intmax_t strntoimax(const char *, char **, int, size_t); -__extern uintmax_t strntoumax(const char *, char **, int, size_t); - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) - -#define PRId8 "d" -#define PRId16 "d" -#define PRId32 "d" -#define PRId64 __PRI64_RANK "d" - -#define PRIdLEAST8 "d" -#define PRIdLEAST16 "d" -#define PRIdLEAST32 "d" -#define PRIdLEAST64 __PRI64_RANK "d" - -#define PRIdFAST8 "d" -#define PRIdFAST16 __PRIFAST_RANK "d" -#define PRIdFAST32 __PRIFAST_RANK "d" -#define PRIdFAST64 __PRI64_RANK "d" - -#define PRIdMAX __PRI64_RANK "d" -#define PRIdPTR __PRIPTR_RANK "d" - -#define PRIi8 "i" -#define PRIi16 "i" -#define PRIi32 "i" -#define PRIi64 __PRI64_RANK "i" - -#define PRIiLEAST8 "i" -#define PRIiLEAST16 "i" -#define PRIiLEAST32 "i" -#define PRIiLEAST64 __PRI64_RANK "i" - -#define PRIiFAST8 "i" -#define PRIiFAST16 __PRIFAST_RANK "i" -#define PRIiFAST32 __PRIFAST_RANK "i" -#define PRIiFAST64 __PRI64_RANK "i" - -#define PRIiMAX __PRI64_RANK "i" -#define PRIiPTR __PRIPTR_RANK "i" - -#define PRIo8 "o" -#define PRIo16 "o" -#define PRIo32 "o" -#define PRIo64 __PRI64_RANK "o" - -#define PRIoLEAST8 "o" -#define PRIoLEAST16 "o" -#define PRIoLEAST32 "o" -#define PRIoLEAST64 __PRI64_RANK "o" - -#define PRIoFAST8 "o" -#define PRIoFAST16 __PRIFAST_RANK "o" -#define PRIoFAST32 __PRIFAST_RANK "o" -#define PRIoFAST64 __PRI64_RANK "o" - -#define PRIoMAX __PRI64_RANK "o" -#define PRIoPTR __PRIPTR_RANK "o" - -#define PRIu8 "u" -#define PRIu16 "u" -#define PRIu32 "u" -#define PRIu64 __PRI64_RANK "u" - -#define PRIuLEAST8 "u" -#define PRIuLEAST16 "u" -#define PRIuLEAST32 "u" -#define PRIuLEAST64 __PRI64_RANK "u" - -#define PRIuFAST8 "u" -#define PRIuFAST16 __PRIFAST_RANK "u" -#define PRIuFAST32 __PRIFAST_RANK "u" -#define PRIuFAST64 __PRI64_RANK "u" - -#define PRIuMAX __PRI64_RANK "u" -#define PRIuPTR __PRIPTR_RANK "u" - -#define PRIx8 "x" -#define PRIx16 "x" -#define PRIx32 "x" -#define PRIx64 __PRI64_RANK "x" - -#define PRIxLEAST8 "x" -#define PRIxLEAST16 "x" -#define PRIxLEAST32 "x" -#define PRIxLEAST64 __PRI64_RANK "x" - -#define PRIxFAST8 "x" -#define PRIxFAST16 __PRIFAST_RANK "x" -#define PRIxFAST32 __PRIFAST_RANK "x" -#define PRIxFAST64 __PRI64_RANK "x" - -#define PRIxMAX __PRI64_RANK "x" -#define PRIxPTR __PRIPTR_RANK "x" - -#define PRIX8 "X" -#define PRIX16 "X" -#define PRIX32 "X" -#define PRIX64 __PRI64_RANK "X" - -#define PRIXLEAST8 "X" -#define PRIXLEAST16 "X" -#define PRIXLEAST32 "X" -#define PRIXLEAST64 __PRI64_RANK "X" - -#define PRIXFAST8 "X" -#define PRIXFAST16 __PRIFAST_RANK "X" -#define PRIXFAST32 __PRIFAST_RANK "X" -#define PRIXFAST64 __PRI64_RANK "X" - -#define PRIXMAX __PRI64_RANK "X" -#define PRIXPTR __PRIPTR_RANK "X" - -#define SCNd8 "hhd" -#define SCNd16 "hd" -#define SCNd32 "d" -#define SCNd64 __PRI64_RANK "d" - -#define SCNdLEAST8 "hhd" -#define SCNdLEAST16 "hd" -#define SCNdLEAST32 "d" -#define SCNdLEAST64 __PRI64_RANK "d" - -#define SCNdFAST8 "hhd" -#define SCNdFAST16 __PRIFAST_RANK "d" -#define SCNdFAST32 __PRIFAST_RANK "d" -#define SCNdFAST64 __PRI64_RANK "d" - -#define SCNdMAX __PRI64_RANK "d" -#define SCNdPTR __PRIPTR_RANK "d" - -#define SCNi8 "hhi" -#define SCNi16 "hi" -#define SCNi32 "i" -#define SCNi64 __PRI64_RANK "i" - -#define SCNiLEAST8 "hhi" -#define SCNiLEAST16 "hi" -#define SCNiLEAST32 "i" -#define SCNiLEAST64 __PRI64_RANK "i" - -#define SCNiFAST8 "hhi" -#define SCNiFAST16 __PRIFAST_RANK "i" -#define SCNiFAST32 __PRIFAST_RANK "i" -#define SCNiFAST64 __PRI64_RANK "i" - -#define SCNiMAX __PRI64_RANK "i" -#define SCNiPTR __PRIPTR_RANK "i" - -#define SCNo8 "hho" -#define SCNo16 "ho" -#define SCNo32 "o" -#define SCNo64 __PRI64_RANK "o" - -#define SCNoLEAST8 "hho" -#define SCNoLEAST16 "ho" -#define SCNoLEAST32 "o" -#define SCNoLEAST64 __PRI64_RANK "o" - -#define SCNoFAST8 "hho" -#define SCNoFAST16 __PRIFAST_RANK "o" -#define SCNoFAST32 __PRIFAST_RANK "o" -#define SCNoFAST64 __PRI64_RANK "o" - -#define SCNoMAX __PRI64_RANK "o" -#define SCNoPTR __PRIPTR_RANK "o" - -#define SCNu8 "hhu" -#define SCNu16 "hu" -#define SCNu32 "u" -#define SCNu64 __PRI64_RANK "u" - -#define SCNuLEAST8 "hhu" -#define SCNuLEAST16 "hu" -#define SCNuLEAST32 "u" -#define SCNuLEAST64 __PRI64_RANK "u" - -#define SCNuFAST8 "hhu" -#define SCNuFAST16 __PRIFAST_RANK "u" -#define SCNuFAST32 __PRIFAST_RANK "u" -#define SCNuFAST64 __PRI64_RANK "u" - -#define SCNuMAX __PRI64_RANK "u" -#define SCNuPTR __PRIPTR_RANK "u" - -#define SCNx8 "hhx" -#define SCNx16 "hx" -#define SCNx32 "x" -#define SCNx64 __PRI64_RANK "x" - -#define SCNxLEAST8 "hhx" -#define SCNxLEAST16 "hx" -#define SCNxLEAST32 "x" -#define SCNxLEAST64 __PRI64_RANK "x" - -#define SCNxFAST8 "hhx" -#define SCNxFAST16 __PRIFAST_RANK "x" -#define SCNxFAST32 __PRIFAST_RANK "x" -#define SCNxFAST64 __PRI64_RANK "x" - -#define SCNxMAX __PRI64_RANK "x" -#define SCNxPTR __PRIPTR_RANK "x" - -#endif - -#endif /* _INTTYPES_H */ diff --git a/klibc/include/klibc/compiler.h b/klibc/include/klibc/compiler.h deleted file mode 100644 index 7ff6ff7d51..0000000000 --- a/klibc/include/klibc/compiler.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * klibc/compiler.h - * - * Various compiler features - */ - -#ifndef _KLIBC_COMPILER_H -#define _KLIBC_COMPILER_H - -/* Specific calling conventions */ -/* __cdecl is used when we want varadic and non-varadic functions to have - the same binary calling convention. */ -#ifdef __i386__ -# ifdef __GNUC__ -# define __cdecl __attribute__((cdecl,regparm(0))) -# else - /* Most other C compilers have __cdecl as a keyword */ -# endif -#else -# define __cdecl /* Meaningless on non-i386 */ -#endif - -/* How to declare a function that *must* be inlined */ -#ifdef __GNUC__ -# if __GNUC__ >= 3 -# define __must_inline static __inline__ __attribute__((always_inline)) -# else -# define __must_inline extern __inline__ -# endif -#else -# define __must_inline inline /* Just hope this works... */ -#endif - -/* How to declare a function that does not return */ -#ifdef __GNUC__ -# define __noreturn void __attribute__((noreturn)) -#else -# define __noreturn void -#endif - -/* "const" function: - - Many functions do not examine any values except their arguments, - and have no effects except the return value. Basically this is - just slightly more strict class than the `pure' attribute above, - since function is not allowed to read global memory. - - Note that a function that has pointer arguments and examines the - data pointed to must _not_ be declared `const'. Likewise, a - function that calls a non-`const' function usually must not be - `const'. It does not make sense for a `const' function to return - `void'. -*/ -#ifdef __GNUC__ -# define __constfunc __attribute__((const)) -#else -# define __constfunc -#endif -#undef __attribute_const__ -#define __attribute_const__ __constfunc - -/* "pure" function: - - Many functions have no effects except the return value and their - return value depends only on the parameters and/or global - variables. Such a function can be subject to common subexpression - elimination and loop optimization just as an arithmetic operator - would be. These functions should be declared with the attribute - `pure'. -*/ -#ifdef __GNUC__ -# define __purefunc __attribute__((pure)) -#else -# define __purefunc -#endif -#undef __attribute_pure__ -#define __attribute_pure__ __purefunc - -/* Format attribute */ -#ifdef __GNUC__ -# define __formatfunc(t,f,a) __attribute__((format(t,f,a))) -#else -# define __formatfunc(t,f,a) -#endif - -/* malloc() function (returns unaliased pointer) */ -#if defined(__GNUC__) && (__GNUC__ >= 3) -# define __mallocfunc __attribute__((malloc)) -#else -# define __mallocfunc -#endif - -/* likely/unlikely */ -#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)) -# define __likely(x) __builtin_expect((x), 1) -# define __unlikely(x) __builtin_expect((x), 0) -#else -# define __likely(x) (x) -# define __unlikely(x) (x) -#endif - -/* Possibly unused function */ -#ifdef __GNUC__ -# define __unusedfunc __attribute__((unused)) -#else -# define __unusedfunc -#endif - -/* It's all user space... */ -#define __user - -/* The bitwise attribute: disallow arithmetric operations */ -#ifdef __CHECKER__ /* sparse only */ -# define __bitwise __attribute__((bitwise)) -#else -# define __bitwise -#endif - -/* Compiler pragma to make an alias symbol */ -#define __ALIAS(__t, __f, __p, __a) \ - __t __f __p __attribute__((weak, alias(#__a))); - -#endif diff --git a/klibc/include/klibc/diverr.h b/klibc/include/klibc/diverr.h deleted file mode 100644 index 4d8c8d36c2..0000000000 --- a/klibc/include/klibc/diverr.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * klibc/diverr.h - */ - -#ifndef _KLIBC_DIVERR_H -#define _KLIBC_DIVERR_H - -#include - -static __inline__ void -__divide_error(void) -{ - raise(SIGFPE); -} - -#endif /* _KLIBC_DIVERR_H */ diff --git a/klibc/include/klibc/extern.h b/klibc/include/klibc/extern.h deleted file mode 100644 index 8a73d19358..0000000000 --- a/klibc/include/klibc/extern.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * klibc/extern.h - */ - -#ifndef _KLIBC_EXTERN_H -#define _KLIBC_EXTERN_H - -#ifdef __cplusplus -#define __extern extern "C" -#else -#define __extern extern -#endif - -#define __alias(x) __attribute__((weak, alias(x))) - -#endif /* _KLIBC_EXTERN_H */ diff --git a/klibc/include/klibc/sysconfig.h b/klibc/include/klibc/sysconfig.h deleted file mode 100644 index ce01c23593..0000000000 --- a/klibc/include/klibc/sysconfig.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * klibc/sysconfig.h - * - * Allows for definitions of some things which may be system-dependent - */ - -#ifndef _KLIBC_SYSCONFIG_H -#define _KLIBC_SYSCONFIG_H - -/* - * Define this to obtain memory using sbrk() instead - * of mmap(). This should make it friendlier on - * non-MMU architectures. This should become a - * per-architecture configurable. - */ -#undef MALLOC_USING_SBRK - -/* - * This is the minimum chunk size we will ask the kernel for using - * malloc(); this should be a multiple of the page size on all - * architectures. - */ -#define MALLOC_CHUNK_SIZE 65536 -#define MALLOC_CHUNK_MASK (MALLOC_CHUNK_SIZE-1) - -/* - * This is the minimum alignment for the memory returned by sbrk(). - * It must be a power of 2. If MALLOC_USING_SBRK is defined it should - * be no smaller than the size of struct arena_header in malloc.h (4 - * pointers.) - */ -#define SBRK_ALIGNMENT 32 - -#endif /* _KLIBC_SYSCONFIG_H */ diff --git a/klibc/include/limits.h b/klibc/include/limits.h deleted file mode 100644 index f1532e5323..0000000000 --- a/klibc/include/limits.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * limits.h - */ - -#ifndef _LIMITS_H -#define _LIMITS_H - -#define CHAR_BIT 8 -#define SHRT_BIT 16 -#define INT_BIT 32 -#define LONGLONG_BIT 64 - -#define SCHAR_MIN (-128) -#define SCHAR_MAX 127 -#define UCHAR_MAX 255 - -#ifdef __CHAR_UNSIGNED__ -# define CHAR_MIN 0 -# define CHAR_MAX UCHAR_MAX -#else -# define CHAR_MIN SCHAR_MIN -# define CHAR_MAX SCHAR_MAX -#endif - -#define SHRT_MIN (-32768) -#define SHRT_MAX 32767 -#define USHRT_MAX 65535 - -#define INT_MIN (-2147483647-1) -#define INT_MAX 2147483647 -#define UINT_MAX 4294967295U - -#define LONGLONG_MIN (-9223372036854775807LL-1) -#define LONGLONG_MAX 9223372036854775807LL -#define ULONGLONG_MAX 18446744073709551615ULL - -#include -#include - -#endif /* _LIMITS_H */ diff --git a/klibc/include/malloc.h b/klibc/include/malloc.h deleted file mode 100644 index 5beca8d068..0000000000 --- a/klibc/include/malloc.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * malloc.h - * - * Apparently people haven't caught on to use , which is the - * standard place for this crap since the 1980's... - */ - -#ifndef _MALLOC_H -#define _MALLOC_H - -#include -#include -#include - -__extern void free(void *); - -__extern __mallocfunc void *malloc(size_t); -__extern __mallocfunc void *calloc(size_t, size_t); -__extern __mallocfunc void *realloc(void *, size_t); - -#endif /* _MALLOC_H */ diff --git a/klibc/include/net/if.h b/klibc/include/net/if.h deleted file mode 100644 index 1aa8e7b90c..0000000000 --- a/klibc/include/net/if.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/include/net/if_arp.h b/klibc/include/net/if_arp.h deleted file mode 100644 index a25f1b4759..0000000000 --- a/klibc/include/net/if_arp.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/include/net/if_packet.h b/klibc/include/net/if_packet.h deleted file mode 100644 index b5e8e0e11f..0000000000 --- a/klibc/include/net/if_packet.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/include/net/route.h b/klibc/include/net/route.h deleted file mode 100644 index a60df24c0a..0000000000 --- a/klibc/include/net/route.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/include/netinet/if_ether.h b/klibc/include/netinet/if_ether.h deleted file mode 100644 index 060ef22070..0000000000 --- a/klibc/include/netinet/if_ether.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/include/netinet/in.h b/klibc/include/netinet/in.h deleted file mode 100644 index 27b778700e..0000000000 --- a/klibc/include/netinet/in.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * netinet/in.h - */ - -#ifndef _NETINET_IN_H -#define _NETINET_IN_H - -/* added this include by Mats Petersson */ -#include - -#include -#include -#include /* Must be included *before* */ -#include - -#ifndef htons -# define htons(x) __cpu_to_be16(x) -#endif -#ifndef ntohs -# define ntohs(x) __be16_to_cpu(x) -#endif -#ifndef htonl -# define htonl(x) __cpu_to_be32(x) -#endif -#ifndef ntohl -# define ntohl(x) __be32_to_cpu(x) -#endif -#ifndef htonq -# define htonq(x) __cpu_to_be64(x) -#endif -#ifndef ntohq -# define ntohq(x) __be64_to_cpu(x) -#endif - -#define IPPORT_RESERVED 1024 - -__extern int bindresvport (int sd, struct sockaddr_in *sin); - -#endif /* _NETINET_IN_H */ diff --git a/klibc/include/netinet/in6.h b/klibc/include/netinet/in6.h deleted file mode 100644 index 46584ca627..0000000000 --- a/klibc/include/netinet/in6.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * netinet/in6.h - */ - -#ifndef _NETINET_IN6_H -#define _NETINET_IN6_H - -#include - -#endif /* _NETINET_IN6_H */ diff --git a/klibc/include/netinet/ip.h b/klibc/include/netinet/ip.h deleted file mode 100644 index 8aecbe66a3..0000000000 --- a/klibc/include/netinet/ip.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * netinet/ip.h - */ - -#ifndef _NETINET_IP_H -#define _NETINET_IP_H - -#include -#include - -#define IP_DF 0x4000 /* Flag: "Don't Fragment" */ - -#endif /* _NETINET_IP_H */ diff --git a/klibc/include/netinet/tcp.h b/klibc/include/netinet/tcp.h deleted file mode 100644 index bb5d307e98..0000000000 --- a/klibc/include/netinet/tcp.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * netinet/tcp.h - */ - -#ifndef _NETINET_TCP_H -#define _NETINET_TCP_H - -#include /* Include *before* linux/tcp.h */ -#include - -#endif /* _NETINET_TCP_H */ diff --git a/klibc/include/netinet/udp.h b/klibc/include/netinet/udp.h deleted file mode 100644 index b809b4ee6e..0000000000 --- a/klibc/include/netinet/udp.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * netinet/udp.h - */ - -#ifndef _NETINET_UDP_H -#define _NETINET_UDP_H - -/* - * We would include linux/udp.h, but it brings in too much other stuff - */ - -struct udphdr { - __u16 source; - __u16 dest; - __u16 len; - __u16 check; -}; - -#endif /* _NETINET_UDP_H */ diff --git a/klibc/include/netpacket/packet.h b/klibc/include/netpacket/packet.h deleted file mode 100644 index b5e8e0e11f..0000000000 --- a/klibc/include/netpacket/packet.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/include/paths.h b/klibc/include/paths.h deleted file mode 100644 index a87831e74a..0000000000 --- a/klibc/include/paths.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)paths.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _PATHS_H_ -#define _PATHS_H_ - -/* Default search path. */ -#define _PATH_DEFPATH "/usr/bin:/bin" -/* All standard utilities path. */ -#define _PATH_STDPATH \ - "/usr/bin:/bin:/usr/sbin:/sbin" - -#define _PATH_BSHELL "/bin/sh" -#define _PATH_CONSOLE "/dev/console" -#define _PATH_CSHELL "/bin/csh" -#define _PATH_DEVDB "/var/run/dev.db" -#define _PATH_DEVNULL "/dev/null" -#define _PATH_DRUM "/dev/drum" -#define _PATH_KLOG "/proc/kmsg" -#define _PATH_KMEM "/dev/kmem" -#define _PATH_LASTLOG "/var/log/lastlog" -#define _PATH_MAILDIR "/var/mail" -#define _PATH_MAN "/usr/share/man" -#define _PATH_MEM "/dev/mem" -#define _PATH_MNTTAB "/etc/fstab" -#define _PATH_MOUNTED "/etc/mtab" -#define _PATH_NOLOGIN "/etc/nologin" -#define _PATH_PRESERVE "/var/lib" -#define _PATH_RWHODIR "/var/spool/rwho" -#define _PATH_SENDMAIL "/usr/sbin/sendmail" -#define _PATH_SHADOW "/etc/shadow" -#define _PATH_SHELLS "/etc/shells" -#define _PATH_TTY "/dev/tty" -#define _PATH_UNIX "/boot/vmlinux" -#define _PATH_UTMP "/var/run/utmp" -#define _PATH_VI "/bin/vi" -#define _PATH_WTMP "/var/log/wtmp" - -/* Provide trailing slash, since mostly used for building pathnames. */ -#define _PATH_DEV "/dev/" -#define _PATH_TMP "/tmp/" -#define _PATH_VARDB "/var/db/" -#define _PATH_VARRUN "/var/run/" -#define _PATH_VARTMP "/var/tmp/" - -#endif /* !_PATHS_H_ */ diff --git a/klibc/include/poll.h b/klibc/include/poll.h deleted file mode 100644 index 8710d92ebd..0000000000 --- a/klibc/include/poll.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * poll.h - */ - -#ifndef _POLL_H -#define _POLL_H - -#include -#include - -/* POSIX specifies "int" for the timeout, Linux seems to use long... */ - -typedef unsigned int nfds_t; -__extern int poll(struct pollfd *, nfds_t, long); - -#endif /* _POLL_H */ diff --git a/klibc/include/sched.h b/klibc/include/sched.h deleted file mode 100644 index 3465b5705c..0000000000 --- a/klibc/include/sched.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * sched.h - */ - -#ifndef _SCHED_H -#define _SCHED_H - -#include - -/* linux/sched.h is unusable; put the declarations we need here... */ - -#define SCHED_NORMAL 0 -#define SCHED_FIFO 1 -#define SCHED_RR 2 - -struct sched_param { - int sched_priority; -}; - -__extern int sched_setscheduler(pid_t, int, const struct sched_param *); -__extern int sched_yield(void); - -/* Raw interfaces to clone(2); only actually usable for non-VM-cloning */ -#ifdef __ia64__ -__extern pid_t __clone2(int, void *, void *); -static __inline__ pid_t __clone(int _f, void *_sp) -{ - /* If this is used with _sp != 0 it will have the effect of the sp - and rsp growing away from a single point in opposite directions. */ - return __clone2(_f, _sp, _sp); -} -#else -__extern pid_t __clone(int, void *); -#endif - -#endif /* _SCHED_H */ diff --git a/klibc/include/setjmp.h b/klibc/include/setjmp.h deleted file mode 100644 index b504eb6d08..0000000000 --- a/klibc/include/setjmp.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * setjmp.h - */ - -#ifndef _SETJMP_H -#define _SETJMP_H - -#include -#include -#include -#include - -#include - -__extern int setjmp(jmp_buf); -__extern __noreturn longjmp(jmp_buf, int); - -/* - Whose bright idea was it to add unrelated functionality to just about - the only function in the standard C library (setjmp) which cannot be - wrapped by an ordinary function wrapper? Anyway, the damage is done, - and therefore, this wrapper *must* be inline. However, gcc will - complain if this is an inline function for unknown reason, and - therefore sigsetjmp() needs to be a macro. -*/ - -struct __sigjmp_buf { - jmp_buf __jmpbuf; - sigset_t __sigs; -}; - -typedef struct __sigjmp_buf sigjmp_buf[1]; - -#define sigsetjmp(__env, __save) \ -({ \ - struct __sigjmp_buf *__e = (__env); \ - sigprocmask(0, NULL, &__e->__sigs); \ - setjmp(__e->__jmpbuf); \ -}) - -__extern __noreturn siglongjmp(sigjmp_buf, int); - -#endif /* _SETJMP_H */ diff --git a/klibc/include/signal.h b/klibc/include/signal.h deleted file mode 100644 index 05930bdea1..0000000000 --- a/klibc/include/signal.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * signal.h - */ - -#ifndef _SIGNAL_H -#define _SIGNAL_H - -#include -#include -#include /* For memset() */ -#include /* For LONG_BIT */ -#include -#include - -#include - -/* glibc seems to use sig_atomic_t as "int" pretty much on all architectures. - Do the same, but allow the architecture to override. */ -#ifndef _KLIBC_HAS_ARCH_SIG_ATOMIC_T -typedef int sig_atomic_t; -#endif - -/* Some architectures don't define these */ -#ifndef SA_RESETHAND -# define SA_RESETHAND SA_ONESHOT -#endif -#ifndef SA_NODEFER -# define SA_NODEFER SA_NOMASK -#endif -/* Some architectures define NSIG and not _NSIG or vice versa */ -#ifndef NSIG -# define NSIG _NSIG -#endif -#ifndef _NSIG -# define _NSIG NSIG -#endif - -/* If we don't have any real-time signals available to userspace, - hide them all */ -#if SIGRTMAX <= SIGRTMIN -# undef SIGRTMIN -# undef SIGRTMAX -#endif - -__extern const char * const sys_siglist[]; - -/* This assumes sigset_t is either an unsigned long or an array of such, - and that _NSIG_BPW in the kernel is always LONG_BIT */ - -static __inline__ int sigemptyset(sigset_t *__set) -{ - memset(__set, 0, sizeof *__set); - return 0; -} -static __inline__ int sigfillset(sigset_t *__set) -{ - memset(__set, ~0, sizeof *__set); - return 0; -} -static __inline__ int sigaddset(sigset_t *__set, int __signum) -{ - unsigned long *__lset = (unsigned long *)__set; - __lset[__signum/LONG_BIT] |= 1UL << (__signum%LONG_BIT); - return 0; -} -static __inline__ int sigdelset(sigset_t *__set, int __signum) -{ - unsigned long *__lset = (unsigned long *)__set; - __lset[__signum/LONG_BIT] &= ~(1UL << (__signum%LONG_BIT)); - return 0; -} -static __inline__ int sigismember(sigset_t *__set, int __signum) -{ - unsigned long *__lset = (unsigned long *)__set; - return (int)((__lset[__signum/LONG_BIT] >> (__signum%LONG_BIT)) & 1); -} - -__extern __sighandler_t __signal(int, __sighandler_t, int); -__extern __sighandler_t sysv_signal(int, __sighandler_t); -__extern __sighandler_t bsd_signal(int, __sighandler_t); -__extern int sigaction(int, const struct sigaction *, struct sigaction *); -__extern int sigprocmask(int, const sigset_t *, sigset_t *); -__extern int sigpending(sigset_t *); -__extern int sigsuspend(const sigset_t *); -__extern int raise(int); -__extern int kill(pid_t, int); - -#endif /* _SIGNAL_H */ diff --git a/klibc/include/stdarg.h b/klibc/include/stdarg.h deleted file mode 100644 index cc324b825d..0000000000 --- a/klibc/include/stdarg.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * stdarg.h - * - * This is just a wrapper for the gcc one, but defines va_copy() - * even if gcc doesn't. - */ - -/* Note: the _STDARG_H macro belongs to the gcc header... */ -#include_next - -/* Older gcc considers this an extension, so it's double underbar only */ -#ifndef va_copy -#define va_copy(d,s) __va_copy(d,s) -#endif diff --git a/klibc/include/stddef.h b/klibc/include/stddef.h deleted file mode 100644 index e96f28c446..0000000000 --- a/klibc/include/stddef.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * stddef.h - */ - -#ifndef _STDDEF_H -#define _STDDEF_H - -#ifndef __KLIBC__ -# error "__KLIBC__ not defined, compiler invocation error!" -#endif - -#include - -#undef NULL -#ifdef __cplusplus -# define NULL 0 -#else -# define NULL ((void *)0) -#endif - -#undef offsetof -#define offsetof(t,m) ((size_t)&((t *)0)->m) - -#endif /* _STDDEF_H */ diff --git a/klibc/include/stdint.h b/klibc/include/stdint.h deleted file mode 100644 index 47fec18594..0000000000 --- a/klibc/include/stdint.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * stdint.h - */ - -#ifndef _STDINT_H -#define _STDINT_H - -#include - -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; - -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -typedef int8_t int_fast8_t; -typedef int64_t int_fast64_t; - -typedef uint8_t uint_fast8_t; -typedef uint64_t uint_fast64_t; - -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) - -#define INT8_MIN (-128) -#define INT16_MIN (-32768) -#define INT32_MIN (-2147483647-1) -#define INT64_MIN (__INT64_C(-9223372036854775807)-1) - -#define INT8_MAX (127) -#define INT16_MAX (32767) -#define INT32_MAX (2147483647) -#define INT64_MAX (__INT64_C(9223372036854775807)) - -#define UINT8_MAX (255U) -#define UINT16_MAX (65535U) -#define UINT32_MAX (4294967295U) -#define UINT64_MAX (__UINT64_C(18446744073709551615)) - -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST64_MIN INT64_MIN - -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MAX INT64_MAX - -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST64_MIN INT64_MIN - -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST64_MAX INT64_MAX - -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST64_MAX UINT64_MAX - -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -#include - -#endif - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) - -#define INT8_C(c) c -#define INT16_C(c) c -#define INT32_C(c) c -#define INT64_C(c) __INT64_C(c) - -#define UINT8_C(c) c ## U -#define UINT16_C(c) c ## U -#define UINT32_C(c) c ## U -#define UINT64_C(c) __UINT64_C(c) - -#define INT_LEAST8_C(c) INT8_C(c) -#define INT_LEAST16_C(c) INT16_C(c) -#define INT_LEAST32_C(c) INT32_C(c) -#define INT_LEAST64_C(c) INT64_C(c) - -#define UINT_LEAST8_C(c) UINT8_C(c) -#define UINT_LEAST16_C(c) UINT16_C(c) -#define UINT_LEAST32_C(c) UINT32_C(c) -#define UINT_LEAST64_C(c) UINT64_C(c) - -#define INT_FAST8_C(c) INT8_C(c) -#define INT_FAST64_C(c) INT64_C(c) - -#define UINT_FAST8_C(c) UINT8_C(c) -#define UINT_FAST64_C(c) UINT64_C(c) - -#define INTMAX_C(c) INT64_C(c) -#define UINTMAX_C(c) UINT64_C(c) - -#include - -#endif - -/* Keep the kernel from trying to define these types... */ -#define __BIT_TYPES_DEFINED__ - -#endif /* _STDINT_H */ diff --git a/klibc/include/stdio.h b/klibc/include/stdio.h deleted file mode 100644 index d30622cfb2..0000000000 --- a/klibc/include/stdio.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * stdio.h - */ - -#ifndef _STDIO_H -#define _STDIO_H - -#include -#include -#include -#include - -/* This structure doesn't really exist, but it gives us something - to define FILE * with */ -struct _IO_file; -typedef struct _IO_file FILE; - -#ifndef EOF -# define EOF (-1) -#endif - -#ifndef BUFSIZ -# define BUFSIZ 4096 -#endif - -#define SEEK_SET 0 -#define SEEK_CUR 1 -#define SEEK_END 2 - -/* - * Convert between a FILE * and a file descriptor. We don't actually - * have any in-memory data, so we just abuse the pointer itself to - * hold the data. Note, however, that for file descriptors, -1 is - * error and 0 is a valid value; for FILE *, NULL (0) is error and - * non-NULL are valid. - */ -static __inline__ int fileno(FILE *__f) -{ - /* This should really be intptr_t, but size_t should be the same size */ - return (int)(size_t)__f - 1; -} - -/* This is a macro so it can be used as initializer */ -#define __create_file(__fd) ((FILE *)(size_t)((__fd) + 1)) - -#define stdin __create_file(0) -#define stdout __create_file(1) -#define stderr __create_file(2) - -__extern FILE *fopen(const char *, const char *); - -static __inline__ FILE *fdopen(int __fd, const char *__m) -{ - (void)__m; return __create_file(__fd); -} -static __inline__ int fclose(FILE *__f) -{ - extern int close(int); - return close(fileno(__f)); -} -static __inline__ int fseek(FILE *__f, off_t __o, int __w) -{ - extern off_t lseek(int, off_t, int); - return (lseek(fileno(__f), __o, __w) == (off_t)-1) ? -1 : 0; -} -static __inline__ off_t ftell(FILE *__f) -{ - extern off_t lseek(int, off_t, int); - return lseek(fileno(__f), 0, SEEK_CUR); -} - -__extern int fputs(const char *, FILE *); -__extern int puts(const char *); -__extern int fputc(int, FILE *); -#define putc(c,f) fputc((c),(f)) -#define putchar(c) fputc((c),stdout) - -__extern int fgetc(FILE *); -__extern char * fgets(char *, int, FILE *); -#define getc(f) fgetc(f) - -__extern size_t _fread(void *, size_t, FILE *); -__extern size_t _fwrite(const void *, size_t, FILE *); - -#ifndef __NO_FREAD_FWRITE_INLINES -extern __inline__ size_t -fread(void *__p, size_t __s, size_t __n, FILE *__f) -{ - return _fread(__p, __s*__n, __f)/__s; -} - -extern __inline__ size_t -fwrite(const void *__p, size_t __s, size_t __n, FILE *__f) -{ - return _fwrite(__p, __s*__n, __f)/__s; -} -#endif - -__extern int printf(const char *, ...); -__extern int vprintf(const char *, va_list); -__extern int fprintf(FILE *, const char *, ...); -__extern int vfprintf(FILE *, const char *, va_list); -__extern int sprintf(char *, const char *, ...); -__extern int vsprintf(char *, const char *, va_list); -__extern int snprintf(char *, size_t n, const char *, ...); -__extern int vsnprintf(char *, size_t n, const char *, va_list); -__extern int asprintf(char **, const char *, ...); -__extern int vasprintf(char **, const char *, va_list); - -/* No buffering, so no flushing needed */ -extern __inline__ int -fflush(FILE *__f) -{ - (void)__f; - return 0; -} - -__extern int sscanf(const char *, const char *, ...); -__extern int vsscanf(const char *, const char *, va_list); - -__extern void perror(const char *); - -__extern int rename(const char *, const char *); - -#endif /* _STDIO_H */ diff --git a/klibc/include/stdlib.h b/klibc/include/stdlib.h deleted file mode 100644 index 17efc30e5a..0000000000 --- a/klibc/include/stdlib.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * stdlib.h - */ - -#ifndef _STDLIB_H -#define _STDLIB_H - -#include -#include -#include - -#include - -#define EXIT_FAILURE 1 -#define EXIT_SUCCESS 0 - -static __inline__ __noreturn _Exit(int __n) { - __extern __noreturn _exit(int); - _exit(__n); - for(;;); /* Some gcc versions are stupid */ -} -__extern __noreturn abort(void); -static __inline__ int abs(int __n) { - return (__n < 0) ? -__n : __n; -} -__extern int system(const char * string); -__extern int atexit(void (*)(void)); -__extern int on_exit(void (*)(int, void *), void *); -__extern int atoi(const char *); -__extern long atol(const char *); -__extern long long atoll(const char *); -__extern __noreturn exit(int); -static __inline__ long labs(long __n) { - return (__n < 0L) ? -__n : __n; -} - -static __inline__ long long llabs(long long __n) { - return (__n < 0LL) ? -__n : __n; -} - -__extern long strtol(const char *, char **, int); -__extern long long strtoll(const char *, char **, int); -__extern unsigned long strtoul(const char *, char **, int); -__extern unsigned long long strtoull(const char *, char **, int); - -__extern char *getenv(const char *); -__extern int putenv(const char *); -__extern int setenv(const char *, const char *, int); -__extern int unsetenv(const char *); - -__extern void qsort(void *, size_t, size_t, int (*)(const void *, const void *)); - - -__extern long jrand48(unsigned short *); -__extern long mrand48(void); -__extern long nrand48(unsigned short *); -__extern long lrand48(void); -__extern unsigned short *seed48(const unsigned short *); -__extern void srand48(long); - -#define RAND_MAX 0x7fffffff -static __inline__ int rand(void) { - return (int)lrand48(); -} -static __inline__ void srand(unsigned int __s) { - srand48(__s); -} -static __inline__ long random(void) -{ - return lrand48(); -} -static __inline__ void srandom(unsigned int __s) -{ - srand48(__s); -} - -/* Basic PTY functions. These only work if devpts is mounted! */ - -__extern int unlockpt(int); -__extern char *ptsname(int); -__extern int getpt(void); - -static __inline__ int grantpt(int __fd) -{ - (void)__fd; - return 0; /* devpts does this all for us! */ -} - -#endif /* _STDLIB_H */ diff --git a/klibc/include/string.h b/klibc/include/string.h deleted file mode 100644 index 319be4eb85..0000000000 --- a/klibc/include/string.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * string.h - */ - -#ifndef _STRING_H -#define _STRING_H - -#include -#include - -__extern void *memccpy(void *, const void *, int, size_t); -__extern void *memchr(const void *, int, size_t); -__extern void *memrchr(const void *, int, size_t); -__extern int memcmp(const void *, const void *, size_t); -__extern void *memcpy(void *, const void *, size_t); -__extern void *memmove(void *, const void *, size_t); -__extern void *memset(void *, int, size_t); -__extern void *memmem(const void *, size_t, const void *, size_t); -__extern void memswap(void *, void *, size_t); -__extern int strcasecmp(const char *, const char *); -__extern int strncasecmp(const char *, const char *, size_t); -__extern char *strcat(char *, const char *); -__extern char *strchr(const char *, int); -__extern char *index(const char *, int); -__extern char *strrchr(const char *, int); -__extern char *rindex(const char *, int); -__extern int strcmp(const char *, const char *); -__extern char *strcpy(char *, const char *); -__extern size_t strcspn(const char *, const char *); -__extern char *strdup(const char *); -__extern char *strndup(const char *, size_t); -__extern char *strerror(int); -__extern size_t strlen(const char *); -__extern size_t strnlen(const char *, size_t); -__extern char *strncat(char *, const char *, size_t); -__extern size_t strlcat(char *, const char *, size_t); -__extern int strncmp(const char *, const char *, size_t); -__extern char *strncpy(char *, const char *, size_t); -__extern size_t strlcpy(char *, const char *, size_t); -__extern char *strpbrk(const char *, const char *); -__extern char *strsep(char **, const char *); -__extern size_t strspn(const char *, const char *); -__extern char *strstr(const char *, const char *); -__extern char *strtok(char *, const char *); - -#endif /* _STRING_H */ diff --git a/klibc/include/sys/dirent.h b/klibc/include/sys/dirent.h deleted file mode 100644 index eec470ce1a..0000000000 --- a/klibc/include/sys/dirent.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * sys/dirent.h - */ - -#ifndef _SYS_DIRENT_H -#define _SYS_DIRENT_H - -#include - -/* The kernel calls this struct dirent64 */ -struct dirent { - uint64_t d_ino; - int64_t d_off; - unsigned short d_reclen; - unsigned char d_type; - char d_name[256]; -}; - -__extern int getdents(unsigned int, struct dirent *, unsigned int); - -#endif /* _SYS_DIRENT_H */ diff --git a/klibc/include/sys/elf32.h b/klibc/include/sys/elf32.h deleted file mode 100644 index 652de5bc5f..0000000000 --- a/klibc/include/sys/elf32.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * sys/elf32.h - */ - -#ifndef _SYS_ELF32_H -#define _SYS_ELF32_H - -#include - -/* ELF standard typedefs (yet more proof that was way overdue) */ -typedef uint16_t Elf32_Half; -typedef int16_t Elf32_SHalf; -typedef uint32_t Elf32_Word; -typedef int32_t Elf32_Sword; -typedef uint64_t Elf32_Xword; -typedef int64_t Elf32_Sxword; - -typedef uint32_t Elf32_Off; -typedef uint32_t Elf32_Addr; -typedef uint16_t Elf32_Section; - -/* Dynamic header */ - -typedef struct elf32_dyn { - Elf32_Sword d_tag; - union{ - Elf32_Sword d_val; - Elf32_Addr d_ptr; - } d_un; -} Elf32_Dyn; - -/* Relocations */ - -#define ELF32_R_SYM(x) ((x) >> 8) -#define ELF32_R_TYPE(x) ((x) & 0xff) - -typedef struct elf32_rel { - Elf32_Addr r_offset; - Elf32_Word r_info; -} Elf32_Rel; - -typedef struct elf32_rela { - Elf32_Addr r_offset; - Elf32_Word r_info; - Elf32_Sword r_addend; -} Elf32_Rela; - -/* Symbol */ - -typedef struct elf32_sym { - Elf32_Word st_name; - Elf32_Addr st_value; - Elf32_Word st_size; - unsigned char st_info; - unsigned char st_other; - Elf32_Half st_shndx; -} Elf32_Sym; - -/* Main file header */ - -typedef struct elf32_hdr { - unsigned char e_ident[EI_NIDENT]; - Elf32_Half e_type; - Elf32_Half e_machine; - Elf32_Word e_version; - Elf32_Addr e_entry; - Elf32_Off e_phoff; - Elf32_Off e_shoff; - Elf32_Word e_flags; - Elf32_Half e_ehsize; - Elf32_Half e_phentsize; - Elf32_Half e_phnum; - Elf32_Half e_shentsize; - Elf32_Half e_shnum; - Elf32_Half e_shstrndx; -} Elf32_Ehdr; - -/* Program header */ - -typedef struct elf32_phdr { - Elf32_Word p_type; - Elf32_Off p_offset; - Elf32_Addr p_vaddr; - Elf32_Addr p_paddr; - Elf32_Word p_filesz; - Elf32_Word p_memsz; - Elf32_Word p_flags; - Elf32_Word p_align; -} Elf32_Phdr; - - -/* Section header */ - -typedef struct elf32_shdr { - Elf32_Word sh_name; - Elf32_Word sh_type; - Elf32_Word sh_flags; - Elf32_Addr sh_addr; - Elf32_Off sh_offset; - Elf32_Word sh_size; - Elf32_Word sh_link; - Elf32_Word sh_info; - Elf32_Word sh_addralign; - Elf32_Word sh_entsize; -} Elf32_Shdr; - -/* Note header */ -typedef struct elf32_note { - Elf32_Word n_namesz; /* Name size */ - Elf32_Word n_descsz; /* Content size */ - Elf32_Word n_type; /* Content type */ -} Elf32_Nhdr; - -#endif /* _SYS_ELF32_H */ - diff --git a/klibc/include/sys/elf64.h b/klibc/include/sys/elf64.h deleted file mode 100644 index 750ddac4d9..0000000000 --- a/klibc/include/sys/elf64.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * sys/elf64.h - */ - -#ifndef _SYS_ELF64_H -#define _SYS_ELF64_H - -#include - -/* ELF standard typedefs (yet more proof that was way overdue) */ -typedef uint16_t Elf64_Half; -typedef int16_t Elf64_SHalf; -typedef uint32_t Elf64_Word; -typedef int32_t Elf64_Sword; -typedef uint64_t Elf64_Xword; -typedef int64_t Elf64_Sxword; - -typedef uint64_t Elf64_Off; -typedef uint64_t Elf64_Addr; -typedef uint16_t Elf64_Section; - -/* Dynamic header */ - -typedef struct elf64_dyn { - Elf64_Sxword d_tag; - union{ - Elf64_Xword d_val; - Elf64_Addr d_ptr; - } d_un; -} Elf64_Dyn; - -/* Relocations */ - -#define ELF64_R_SYM(x) ((x) >> 32) -#define ELF64_R_TYPE(x) ((x) & 0xffffffff) - -typedef struct elf64_rel { - Elf64_Addr r_offset; - Elf64_Xword r_info; -} Elf64_Rel; - -typedef struct elf64_rela { - Elf64_Addr r_offset; - Elf64_Xword r_info; - Elf64_Sxword r_addend; -} Elf64_Rela; - -/* Symbol */ - -typedef struct elf64_sym { - Elf64_Word st_name; - unsigned char st_info; - unsigned char st_other; - Elf64_Half st_shndx; - Elf64_Addr st_value; - Elf64_Xword st_size; -} Elf64_Sym; - -/* Main file header */ - -typedef struct elf64_hdr { - unsigned char e_ident[EI_NIDENT]; - Elf64_Half e_type; - Elf64_Half e_machine; - Elf64_Word e_version; - Elf64_Addr e_entry; - Elf64_Off e_phoff; - Elf64_Off e_shoff; - Elf64_Word e_flags; - Elf64_Half e_ehsize; - Elf64_Half e_phentsize; - Elf64_Half e_phnum; - Elf64_Half e_shentsize; - Elf64_Half e_shnum; - Elf64_Half e_shstrndx; -} Elf64_Ehdr; - -/* Program header */ - -typedef struct elf64_phdr { - Elf64_Word p_type; - Elf64_Word p_flags; - Elf64_Off p_offset; - Elf64_Addr p_vaddr; - Elf64_Addr p_paddr; - Elf64_Xword p_filesz; - Elf64_Xword p_memsz; - Elf64_Xword p_align; -} Elf64_Phdr; - - -/* Section header */ - -typedef struct elf64_shdr { - Elf64_Word sh_name; - Elf64_Word sh_type; - Elf64_Xword sh_flags; - Elf64_Addr sh_addr; - Elf64_Off sh_offset; - Elf64_Xword sh_size; - Elf64_Word sh_link; - Elf64_Word sh_info; - Elf64_Xword sh_addralign; - Elf64_Xword sh_entsize; -} Elf64_Shdr; - -/* Note header */ -typedef struct elf64_note { - Elf64_Word n_namesz; /* Name size */ - Elf64_Word n_descsz; /* Content size */ - Elf64_Word n_type; /* Content type */ -} Elf64_Nhdr; - -#endif /* _SYS_ELF64_H */ - diff --git a/klibc/include/sys/elfcommon.h b/klibc/include/sys/elfcommon.h deleted file mode 100644 index d25804e483..0000000000 --- a/klibc/include/sys/elfcommon.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * sys/elfcommon.h - */ - -#ifndef _SYS_ELFCOMMON_H -#define _SYS_ELFCOMMON_H - -#include - -/* Segment types */ -#define PT_NULL 0 -#define PT_LOAD 1 -#define PT_DYNAMIC 2 -#define PT_INTERP 3 -#define PT_NOTE 4 -#define PT_SHLIB 5 -#define PT_PHDR 6 -#define PT_LOOS 0x60000000 -#define PT_HIOS 0x6fffffff -#define PT_LOPROC 0x70000000 -#define PT_HIPROC 0x7fffffff -#define PT_GNU_EH_FRAME 0x6474e550 /* Extension, eh? */ - -/* ELF file types */ -#define ET_NONE 0 -#define ET_REL 1 -#define ET_EXEC 2 -#define ET_DYN 3 -#define ET_CORE 4 -#define ET_LOPROC 0xff00 -#define ET_HIPROC 0xffff - -/* ELF machine types */ -#define EM_NONE 0 -#define EM_M32 1 -#define EM_SPARC 2 -#define EM_386 3 -#define EM_68K 4 -#define EM_88K 5 -#define EM_486 6 /* Not used in Linux at least */ -#define EM_860 7 -#define EM_MIPS 8 /* R3k, bigendian(?) */ -#define EM_MIPS_RS4_BE 10 /* R4k BE */ -#define EM_PARISC 15 -#define EM_SPARC32PLUS 18 -#define EM_PPC 20 -#define EM_PPC64 21 -#define EM_S390 22 -#define EM_SH 42 -#define EM_SPARCV9 43 /* v9 = SPARC64 */ -#define EM_H8_300H 47 -#define EM_H8S 48 -#define EM_IA_64 50 /* Itanic */ -#define EM_X86_64 62 -#define EM_CRIS 76 -#define EM_V850 87 -#define EM_ALPHA 0x9026 /* Interrim Alpha that stuck around */ -#define EM_CYGNUS_V850 0x9080 /* Old v850 ID used by Cygnus */ -#define EM_S390_OLD 0xA390 /* Obsolete interrim value for S/390 */ - -/* Dynamic type values */ -#define DT_NULL 0 -#define DT_NEEDED 1 -#define DT_PLTRELSZ 2 -#define DT_PLTGOT 3 -#define DT_HASH 4 -#define DT_STRTAB 5 -#define DT_SYMTAB 6 -#define DT_RELA 7 -#define DT_RELASZ 8 -#define DT_RELAENT 9 -#define DT_STRSZ 10 -#define DT_SYMENT 11 -#define DT_INIT 12 -#define DT_FINI 13 -#define DT_SONAME 14 -#define DT_RPATH 15 -#define DT_SYMBOLIC 16 -#define DT_REL 17 -#define DT_RELSZ 18 -#define DT_RELENT 19 -#define DT_PLTREL 20 -#define DT_DEBUG 21 -#define DT_TEXTREL 22 -#define DT_JMPREL 23 -#define DT_LOPROC 0x70000000 -#define DT_HIPROC 0x7fffffff - -/* Auxilliary table entries */ -#define AT_NULL 0 /* end of vector */ -#define AT_IGNORE 1 /* entry should be ignored */ -#define AT_EXECFD 2 /* file descriptor of program */ -#define AT_PHDR 3 /* program headers for program */ -#define AT_PHENT 4 /* size of program header entry */ -#define AT_PHNUM 5 /* number of program headers */ -#define AT_PAGESZ 6 /* system page size */ -#define AT_BASE 7 /* base address of interpreter */ -#define AT_FLAGS 8 /* flags */ -#define AT_ENTRY 9 /* entry point of program */ -#define AT_NOTELF 10 /* program is not ELF */ -#define AT_UID 11 /* real uid */ -#define AT_EUID 12 /* effective uid */ -#define AT_GID 13 /* real gid */ -#define AT_EGID 14 /* effective gid */ -#define AT_PLATFORM 15 /* string identifying CPU for optimizations */ -#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ -#define AT_CLKTCK 17 /* frequency at which times() increments */ -/* 18..22 = ? */ -#define AT_SECURE 23 /* secure mode boolean */ - -/* Program header permission flags */ -#define PF_X 0x1 -#define PF_W 0x2 -#define PF_R 0x4 - -/* Section header types */ -#define SHT_NULL 0 -#define SHT_PROGBITS 1 -#define SHT_SYMTAB 2 -#define SHT_STRTAB 3 -#define SHT_RELA 4 -#define SHT_HASH 5 -#define SHT_DYNAMIC 6 -#define SHT_NOTE 7 -#define SHT_NOBITS 8 -#define SHT_REL 9 -#define SHT_SHLIB 10 -#define SHT_DYNSYM 11 -#define SHT_NUM 12 -#define SHT_LOPROC 0x70000000 -#define SHT_HIPROC 0x7fffffff -#define SHT_LOUSER 0x80000000 -#define SHT_HIUSER 0xffffffff - -/* Section header flags */ -#define SHF_WRITE 0x1 -#define SHF_ALLOC 0x2 -#define SHF_EXECINSTR 0x4 -#define SHF_MASKPROC 0xf0000000 - -/* Special section numbers */ -#define SHN_UNDEF 0 -#define SHN_LORESERVE 0xff00 -#define SHN_LOPROC 0xff00 -#define SHN_HIPROC 0xff1f -#define SHN_ABS 0xfff1 -#define SHN_COMMON 0xfff2 -#define SHN_HIRESERVE 0xffff - -/* Lenght of magic at the start of a file */ -#define EI_NIDENT 16 - -/* Magic number constants... */ -#define EI_MAG0 0 /* e_ident[] indexes */ -#define EI_MAG1 1 -#define EI_MAG2 2 -#define EI_MAG3 3 -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_OSABI 7 -#define EI_PAD 8 - -#define ELFMAG0 0x7f /* EI_MAG */ -#define ELFMAG1 'E' -#define ELFMAG2 'L' -#define ELFMAG3 'F' -#define ELFMAG "\177ELF" -#define SELFMAG 4 - -#define ELFCLASSNONE 0 /* EI_CLASS */ -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFCLASSNUM 3 - -#define ELFDATANONE 0 /* e_ident[EI_DATA] */ -#define ELFDATA2LSB 1 -#define ELFDATA2MSB 2 - -#define EV_NONE 0 /* e_version, EI_VERSION */ -#define EV_CURRENT 1 -#define EV_NUM 2 - -#define ELFOSABI_NONE 0 -#define ELFOSABI_LINUX 3 - -#endif /* _SYS_ELFCOMMON_H */ - diff --git a/klibc/include/sys/fsuid.h b/klibc/include/sys/fsuid.h deleted file mode 100644 index 823486b776..0000000000 --- a/klibc/include/sys/fsuid.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/fsuid.h - */ - -#ifndef _SYS_FSUID_H -#define _SYS_FSUID_H - -#include -#include - -__extern int setfsuid(uid_t); -__extern int setfsgid(gid_t); - -#endif /* _SYS_FSUID_H */ diff --git a/klibc/include/sys/inotify.h b/klibc/include/sys/inotify.h deleted file mode 100644 index 74fc714190..0000000000 --- a/klibc/include/sys/inotify.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * sys/inotify.h - */ - -#ifndef _SYS_INOTIFY_H -#define _SYS_INOTIFY_H - -#include -#include -#include - -__extern int inotify_init(void); -__extern int inotify_add_watch(int, const char *, __u32); -__extern int inotify_rm_watch(int, __u32); - -#endif /* _SYS_INOTIFY_H */ diff --git a/klibc/include/sys/ioctl.h b/klibc/include/sys/ioctl.h deleted file mode 100644 index b0cee4c02c..0000000000 --- a/klibc/include/sys/ioctl.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/ioctl.h - */ - -#ifndef _SYS_IOCTL_H -#define _SYS_IOCTL_H - -#include -#include -#include - -__extern int ioctl(int, int, void *); - -#endif /* _SYS_IOCTL_H */ diff --git a/klibc/include/sys/klog.h b/klibc/include/sys/klog.h deleted file mode 100644 index 0fc5f5d945..0000000000 --- a/klibc/include/sys/klog.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * sys/klog.h - */ - -#ifndef _SYS_KLOG_H -#define _SYS_KLOG_H - -#include - -#define KLOG_CLOSE 0 -#define KLOG_OPEN 1 -#define KLOG_READ 2 -#define KLOG_READ_ALL 3 -#define KLOG_READ_CLEAR 4 -#define KLOG_CLEAR 5 -#define KLOG_DISABLE 6 -#define KLOG_ENABLE 7 -#define KLOG_SETLEVEL 8 -#define KLOG_UNREADSIZE 9 -#define KLOG_WRITE 10 - -__extern int klogctl(int, char *, int); - -#endif /* _SYS_KLOG_H */ diff --git a/klibc/include/sys/mman.h b/klibc/include/sys/mman.h deleted file mode 100644 index 7f8f3e2f96..0000000000 --- a/klibc/include/sys/mman.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * sys/mman.h - */ - -#ifndef _SYS_MMAN_H -#define _SYS_MMAN_H - -#include -#include -#include -#include /* For PAGE_SIZE */ - -#define MAP_FAILED ((void *)-1) - -__extern void *mmap(void *, size_t, int, int, int, off_t); -__extern int munmap(void *, size_t); -__extern void *mremap(void *, size_t, size_t, unsigned long); -__extern int msync(const void *, size_t, int); -__extern int mprotect(const void *, size_t, int); -__extern int mlockall(int); -__extern int munlockall(void); -__extern int mlock(const void *, size_t); -__extern int munlock(const void *, size_t); - -#endif /* _SYS_MMAN_H */ diff --git a/klibc/include/sys/mount.h b/klibc/include/sys/mount.h deleted file mode 100644 index 0e1bce49bf..0000000000 --- a/klibc/include/sys/mount.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * sys/mount.h - */ - -#ifndef _SYS_MOUNT_H -#define _SYS_MOUNT_H - -#include -#include - -/* - * These are the fs-independent mount-flags: up to 32 flags are supported - */ -#define MS_RDONLY 1 /* Mount read-only */ -#define MS_NOSUID 2 /* Ignore suid and sgid bits */ -#define MS_NODEV 4 /* Disallow access to device special files */ -#define MS_NOEXEC 8 /* Disallow program execution */ -#define MS_SYNCHRONOUS 16 /* Writes are synced at once */ -#define MS_REMOUNT 32 /* Alter flags of a mounted FS */ -#define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ -#define MS_DIRSYNC 128 /* Directory modifications are synchronous */ -#define MS_NOATIME 1024 /* Do not update access times. */ -#define MS_NODIRATIME 2048 /* Do not update directory access times */ -#define MS_BIND 4096 -#define MS_MOVE 8192 -#define MS_REC 16384 -#define MS_VERBOSE 32768 -#define MS_POSIXACL (1<<16) /* VFS does not apply the umask */ -#define MS_ONE_SECOND (1<<17) /* fs has 1 sec a/m/ctime resolution */ -#define MS_ACTIVE (1<<30) -#define MS_NOUSER (1<<31) - -/* - * Superblock flags that can be altered by MS_REMOUNT - */ -#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|MS_NODIRATIME) - -/* - * Old magic mount flag and mask - */ -#define MS_MGC_VAL 0xC0ED0000 -#define MS_MGC_MSK 0xffff0000 - -/* - * umount2() flags - */ -#define MNT_FORCE 1 /* Forcibly unmount */ -#define MNT_DETACH 2 /* Detach from tree only */ -#define MNT_EXPIRE 4 /* Mark for expiry */ - -/* - * Block device ioctls - */ -#define BLKROSET _IO(0x12, 93) /* Set device read-only (0 = read-write). */ -#define BLKROGET _IO(0x12, 94) /* Get read-only status (0 = read_write). */ -#define BLKRRPART _IO(0x12, 95) /* Re-read partition table. */ -#define BLKGETSIZE _IO(0x12, 96) /* Return device size. */ -#define BLKFLSBUF _IO(0x12, 97) /* Flush buffer cache. */ -#define BLKRASET _IO(0x12, 98) /* Set read ahead for block device. */ -#define BLKRAGET _IO(0x12, 99) /* Get current read ahead setting. */ - -/* - * Prototypes - */ -__extern int mount(const char *, const char *, - const char *, unsigned long, - const void *); -__extern int umount(const char *); -__extern int umount2(const char *, int); -__extern int pivot_root(const char *, const char *); - -#endif /* _SYS_MOUNT_H */ diff --git a/klibc/include/sys/param.h b/klibc/include/sys/param.h deleted file mode 100644 index 63a0661f43..0000000000 --- a/klibc/include/sys/param.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - * sys/param.h - */ - -#ifndef _SYS_PARAM_H -#define _SYS_PARAM_H - -#include -#include - -#endif /* _SYS_PARAM_H */ diff --git a/klibc/include/sys/reboot.h b/klibc/include/sys/reboot.h deleted file mode 100644 index eaf56610d7..0000000000 --- a/klibc/include/sys/reboot.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * sys/reboot.h - */ - -#ifndef _SYS_REBOOT_H -#define _SYS_REBOOT_H - -#include -#include - -/* glibc names these constants differently; allow both versions */ - -#define RB_AUTOBOOT LINUX_REBOOT_CMD_RESTART -#define RB_HALT_SYSTEM LINUX_REBOOT_CMD_HALT -#define RB_ENABLE_CAD LINUX_REBOOT_CMD_CAD_ON -#define RB_DISABLE_CAD LINUX_REBOOT_CMD_CAD_OFF -#define RB_POWER_OFF LINUX_REBOOT_CMD_POWER_OFF - -/* glibc-ish one-argument version */ -__extern int reboot(int); - -/* Native four-argument system call */ -__extern int __reboot(int, int, int, void *); - -#endif /* _SYS_REBOOT_H */ diff --git a/klibc/include/sys/resource.h b/klibc/include/sys/resource.h deleted file mode 100644 index ef14bde9f6..0000000000 --- a/klibc/include/sys/resource.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * sys/resource.h - */ - -#ifndef _SYS_RESOURCE_H -#define _SYS_RESOURCE_H - -#include -#include /* MUST be included before linux/resource.h */ -#include - -__extern int getpriority(int, int); -__extern int setpriority(int, int, int); - -#endif /* _SYS_RESOURCE_H */ diff --git a/klibc/include/sys/select.h b/klibc/include/sys/select.h deleted file mode 100644 index 361a1a53b0..0000000000 --- a/klibc/include/sys/select.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/select.h - */ - -#ifndef _SYS_SELECT_H -#define _SYS_SELECT_H - -#include -#include -#include - -__extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); - -#endif /* _SYS_SELECT_H */ diff --git a/klibc/include/sys/socket.h b/klibc/include/sys/socket.h deleted file mode 100644 index cbc2b89591..0000000000 --- a/klibc/include/sys/socket.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * sys/socket.h - */ - -#ifndef _SYS_SOCKET_H -#define _SYS_SOCKET_H - -#include -#include -#include - -/* For some reason these may be protected by __KERNEL__ in asm/socket.h */ -#ifndef SOCK_STREAM -# define SOCK_STREAM 1 -# define SOCK_DGRAM 2 -# define SOCK_RAW 3 -# define SOCK_RDM 4 -# define SOCK_SEQPACKET 5 -# define SOCK_PACKET 10 -#endif - -#ifdef __i386__ -# define __socketcall __extern __cdecl -#else -# define __socketcall __extern -#endif - -typedef int socklen_t; - -__socketcall int socket(int, int, int); -__socketcall int bind(int, struct sockaddr *, int); -__socketcall int connect(int, struct sockaddr *, socklen_t); -__socketcall int listen(int, int); -__socketcall int accept(int, struct sockaddr *, socklen_t *); -__socketcall int getsockname(int, struct sockaddr *, socklen_t *); -__socketcall int getpeername(int, struct sockaddr *, socklen_t *); -__socketcall int socketpair(int, int, int, int *); -__extern int send(int, const void *, size_t, unsigned int); -__socketcall int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); -__extern int recv(int, void *, size_t, unsigned int); -__socketcall int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *); -__socketcall int shutdown(int, int); -__socketcall int setsockopt(int, int, int, const void *, socklen_t); -__socketcall int getsockopt(int, int, int, void *, socklen_t *); -__socketcall int sendmsg(int, const struct msghdr *, unsigned int); -__socketcall int recvmsg(int, struct msghdr *, unsigned int); - -#undef __socketcall - -#endif /* _SYS_SOCKET_H */ diff --git a/klibc/include/sys/socketcalls.h b/klibc/include/sys/socketcalls.h deleted file mode 100644 index dac9f9aab6..0000000000 --- a/klibc/include/sys/socketcalls.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * sys/socketcalls.h - */ - -#ifndef _SYS_SOCKETCALLS_H -#define _SYS_SOCKETCALLS_H - -/* socketcalls by number, since isn't usable for assembly */ - -#define SYS_SOCKET 1 /* sys_socket(2) */ -#define SYS_BIND 2 /* sys_bind(2) */ -#define SYS_CONNECT 3 /* sys_connect(2) */ -#define SYS_LISTEN 4 /* sys_listen(2) */ -#define SYS_ACCEPT 5 /* sys_accept(2) */ -#define SYS_GETSOCKNAME 6 /* sys_getsockname(2) */ -#define SYS_GETPEERNAME 7 /* sys_getpeername(2) */ -#define SYS_SOCKETPAIR 8 /* sys_socketpair(2) */ -#define SYS_SEND 9 /* sys_send(2) */ -#define SYS_RECV 10 /* sys_recv(2) */ -#define SYS_SENDTO 11 /* sys_sendto(2) */ -#define SYS_RECVFROM 12 /* sys_recvfrom(2) */ -#define SYS_SHUTDOWN 13 /* sys_shutdown(2) */ -#define SYS_SETSOCKOPT 14 /* sys_setsockopt(2) */ -#define SYS_GETSOCKOPT 15 /* sys_getsockopt(2) */ -#define SYS_SENDMSG 16 /* sys_sendmsg(2) */ -#define SYS_RECVMSG 17 /* sys_recvmsg(2) */ - -#endif /* _SYS_SOCKETCALLS_H */ diff --git a/klibc/include/sys/stat.h b/klibc/include/sys/stat.h deleted file mode 100644 index 1bf6a75f79..0000000000 --- a/klibc/include/sys/stat.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * sys/stat.h - */ - -#ifndef _SYS_STAT_H -#define _SYS_STAT_H - -#include -#include -#include /* For struct timespec */ -#include -#include - -#ifdef _STATBUF_ST_NSEC - /* struct stat has struct timespec instead of time_t */ -# define st_atime st_atim.tv_sec -# define st_mtime st_mtim.tv_sec -# define st_ctime st_ctim.tv_sec -#endif - -__extern int stat(const char *, struct stat *); -__extern int fstat(int, struct stat *); -__extern int lstat(const char *, struct stat *); -__extern mode_t umask(mode_t); -__extern int mknod(const char *, mode_t, dev_t); -static __inline__ int mkfifo(const char *__p, mode_t __m) -{ - return mknod(__p, (__m & ~S_IFMT) | S_IFIFO, (dev_t)0); -} - -#endif /* _SYS_STAT_H */ diff --git a/klibc/include/sys/statfs.h b/klibc/include/sys/statfs.h deleted file mode 100644 index 53b3b5e4da..0000000000 --- a/klibc/include/sys/statfs.h +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/klibc/include/sys/syscall.h b/klibc/include/sys/syscall.h deleted file mode 100644 index c2c7684c4a..0000000000 --- a/klibc/include/sys/syscall.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * sys/syscall.h - * - * Generic system call interface macros - */ -#ifndef _SYS_SYSCALL_H -#define _SYS_SYSCALL_H - -#include -#include -#include - -/* Many architectures have incomplete, defective or non-applicable - syscall macros */ -#include - -#endif /* _SYS_SYSCALL_H */ diff --git a/klibc/include/sys/sysinfo.h b/klibc/include/sys/sysinfo.h deleted file mode 100644 index 4051c6897a..0000000000 --- a/klibc/include/sys/sysinfo.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * sys/sysinfo.h - */ - -#ifndef _SYS_SYSINFO_H -#define _SYS_SYSINFO_H - -#include - -extern int sysinfo (struct sysinfo *info); - -#endif /* _SYS_SYSINFO_H */ diff --git a/klibc/include/sys/sysmacros.h b/klibc/include/sys/sysmacros.h deleted file mode 100644 index 7f1e0822b3..0000000000 --- a/klibc/include/sys/sysmacros.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * sys/sysmacros.h - * - * Constructs to create and pick apart dev_t. This applies to the Linux 2.6 - * 32-bit dev_t format. - */ - -#ifndef _SYS_SYSMACROS_H -#define _SYS_SYSMACROS_H - -#ifndef _SYS_TYPES_H -# include -#endif - -static __inline__ int major(dev_t __d) -{ - return (__d >> 8) & 0xfff; -} - -static __inline__ int minor(dev_t __d) -{ - return (__d & 0xff) | ((__d >> 12) & 0xfff00); -} - -static __inline__ dev_t makedev(int __ma, int __mi) -{ - return ((__ma & 0xfff) << 8) | (__mi & 0xff) | ((__mi & 0xfff00) << 12); -} - -#endif /* _SYS_SYSMACROS_H */ - diff --git a/klibc/include/sys/time.h b/klibc/include/sys/time.h deleted file mode 100644 index 2767a1bce3..0000000000 --- a/klibc/include/sys/time.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * sys/time.h - */ - -#ifndef _SYS_TIME_H -#define _SYS_TIME_H - -#include -#include -#include - -__extern int gettimeofday(struct timeval *, struct timezone *); -__extern int settimeofday(const struct timeval *, const struct timezone *); -__extern int getitimer(int, struct itimerval *); -__extern int setitimer(int, const struct itimerval *, struct itimerval *); -__extern int utimes(const char *, const struct timeval *); - -#endif /* _SYS_TIME_H */ diff --git a/klibc/include/sys/times.h b/klibc/include/sys/times.h deleted file mode 100644 index dd86531669..0000000000 --- a/klibc/include/sys/times.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * sys/times.h - */ - -#ifndef _SYS_TIMES_H -#define _SYS_TIMES_H - -#include -#include -#include - -__extern clock_t times(struct tms *); - -#endif /* _SYS_TIMES_H */ diff --git a/klibc/include/sys/types.h b/klibc/include/sys/types.h deleted file mode 100644 index ddec242922..0000000000 --- a/klibc/include/sys/types.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * sys/types.h - */ - -#ifndef _SYS_TYPES_H -#define _SYS_TYPES_H - -#include -#include -#include - -#define _SSIZE_T -typedef ptrdiff_t ssize_t; - -#include -#include - -/* Keeps linux/types.h from getting included elsewhere */ -#define _LINUX_TYPES_H - -typedef __kernel_fd_set fd_set; -typedef uint32_t dev_t; -typedef __kernel_ino_t ino_t; -typedef __kernel_mode_t mode_t; -typedef __kernel_nlink_t nlink_t; -typedef __kernel_loff_t off_t; -typedef __kernel_loff_t loff_t; -typedef __kernel_pid_t pid_t; -typedef __kernel_daddr_t daddr_t; -typedef __kernel_key_t key_t; -typedef __kernel_suseconds_t suseconds_t; -/* typedef __kernel_timer_t timer_t; */ -typedef int timer_t; - -typedef __kernel_uid32_t uid_t; -typedef __kernel_gid32_t gid_t; - -typedef __kernel_fsid_t fsid_t; - -/* - * The following typedefs are also protected by individual ifdefs for - * historical reasons: - */ -#ifndef _SIZE_T -#define _SIZE_T -typedef __kernel_size_t size_t; -#endif - -#ifndef _SSIZE_T -#define _SSIZE_T -typedef __kernel_ssize_t ssize_t; -#endif - -#ifndef _PTRDIFF_T -#define _PTRDIFF_T -typedef __kernel_ptrdiff_t ptrdiff_t; -#endif - -#ifndef _TIME_T -#define _TIME_T -typedef __kernel_time_t time_t; -#endif - -#ifndef _CLOCK_T -#define _CLOCK_T -typedef __kernel_clock_t clock_t; -#endif - -#ifndef _CADDR_T -#define _CADDR_T -typedef __kernel_caddr_t caddr_t; -#endif - -/* bsd */ -typedef unsigned char u_char; -typedef unsigned short u_short; -typedef unsigned int u_int; -typedef unsigned long u_long; - -/* sysv */ -typedef unsigned char unchar; -typedef unsigned short ushort; -typedef unsigned int uint; -typedef unsigned long ulong; - -/* Linux-specific? */ -typedef uint8_t u_int8_t; -typedef uint16_t u_int16_t; -typedef uint32_t u_int32_t; -typedef uint64_t u_int64_t; - -typedef uint16_t __bitwise __le16; -typedef uint16_t __bitwise __be16; -typedef uint32_t __bitwise __le32; -typedef uint32_t __bitwise __be32; -typedef uint64_t __bitwise __le64; -typedef uint64_t __bitwise __be64; - -/* - * Some apps want this in - */ -#include - -#endif diff --git a/klibc/include/sys/uio.h b/klibc/include/sys/uio.h deleted file mode 100644 index fc2525d11a..0000000000 --- a/klibc/include/sys/uio.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * sys/uio.h - */ - -#ifndef _SYS_UIO_H -#define _SYS_UIO_H - -#include -#include -#include - -__extern int readv(int, const struct iovec *, int); -__extern int writev(int, const struct iovec *, int); - -#endif /* _SYS_UIO_H */ diff --git a/klibc/include/sys/un.h b/klibc/include/sys/un.h deleted file mode 100644 index df42d719f7..0000000000 --- a/klibc/include/sys/un.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * - */ - -#ifndef _SYS_UN_H -#define _SYS_UN_H - -#include - -#endif /* _SYS_UN_H */ diff --git a/klibc/include/sys/utime.h b/klibc/include/sys/utime.h deleted file mode 100644 index d1d635d242..0000000000 --- a/klibc/include/sys/utime.h +++ /dev/null @@ -1,10 +0,0 @@ -/* - * sys/utime.h - */ - -#ifndef _SYS_UTIME_H -#define _SYS_UTIME_H - -#include - -#endif /* _SYS_UTIME_H */ diff --git a/klibc/include/sys/utsname.h b/klibc/include/sys/utsname.h deleted file mode 100644 index f2990f5711..0000000000 --- a/klibc/include/sys/utsname.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * sys/utsname.h - */ - -#ifndef _SYS_UTSNAME_H -#define _SYS_UTSNAME_H - -#include - -#define SYS_NMLN 65 - -struct utsname { - char sysname[SYS_NMLN]; - char nodename[SYS_NMLN]; - char release[SYS_NMLN]; - char version[SYS_NMLN]; - char machine[SYS_NMLN]; - char domainname[SYS_NMLN]; -}; - -__extern int uname(struct utsname *); - -#endif /* _SYS_UTSNAME_H */ diff --git a/klibc/include/sys/vfs.h b/klibc/include/sys/vfs.h deleted file mode 100644 index cf5aaf9107..0000000000 --- a/klibc/include/sys/vfs.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * sys/vfs.h - */ - -#ifndef _SYS_VFS_H -#define _SYS_VFS_H - -#include -#include -#include -#include - -/* struct statfs64 -- there seems to be two standards - - one for 32 and one for 64 bits, and they're incompatible... */ - -#if _BITSIZE == 32 || defined(__s390__) - -struct statfs { - uint32_t f_type; - uint32_t f_bsize; - uint64_t f_blocks; - uint64_t f_bfree; - uint64_t f_bavail; - uint64_t f_files; - uint64_t f_ffree; - __kernel_fsid_t f_fsid; - uint32_t f_namelen; - uint32_t f_frsize; - uint32_t f_spare[5]; -}; - -#else /* _BITSIZE == 64 */ - -struct statfs { - uint64_t f_type; - uint64_t f_bsize; - uint64_t f_blocks; - uint64_t f_bfree; - uint64_t f_bavail; - uint64_t f_files; - uint64_t f_ffree; - __kernel_fsid_t f_fsid; - uint64_t f_namelen; - uint64_t f_frsize; - uint64_t f_spare[5]; -}; - -#endif /* _BITSIZE */ - -__extern int statfs(const char *, struct statfs *); -__extern int fstatfs(int, struct statfs *); - -/* Various filesystem types */ -#define ADFS_SUPER_MAGIC 0xadf5 -#define AFFS_SUPER_MAGIC 0xadff -#define AFS_FS_MAGIC 0x6B414653 /* 'kAFS' */ -#define AUTOFS_SUPER_MAGIC 0x0187 -#define BFS_MAGIC 0x1BADFACE -#define CAPIFS_SUPER_MAGIC 0x434e -#define CIFS_MAGIC_NUMBER 0xFF534D42 -#define CODA_SUPER_MAGIC 0x73757245 -#define CRAMFS_MAGIC 0x28cd3d45 -#define DEVFS_SUPER_MAGIC 0x1373 -#define DEVPTS_SUPER_MAGIC 0x1cd1 -#define EFS_SUPER_MAGIC 0x414A53 -#define EVENTPOLLFS_MAGIC 0x03111965 -#define EXT2_SUPER_MAGIC 0xEF53 -#define EXT3_SUPER_MAGIC 0xEF53 -#define GADGETFS_MAGIC 0xaee71ee7 -#define HFSPLUS_SUPER_MAGIC 0x482b -#define HFS_MFS_SUPER_MAGIC 0xD2D7 /* MFS MDB (super block) */ -#define HFS_SUPER_MAGIC 0x4244 /* "BD": HFS MDB (super block) */ -#define HPFS_SUPER_MAGIC 0xf995e849 -#define HUGETLBFS_MAGIC 0x958458f6 -#define HWGFS_MAGIC 0x12061983 -#define IBMASMFS_MAGIC 0x66726f67 -#define ISOFS_SUPER_MAGIC 0x9660 -#define JFFS2_SUPER_MAGIC 0x72b6 -#define JFFS_MAGIC_BITMASK 0x34383931 /* "1984" */ -#define JFFS_MAGIC_SB_BITMASK 0x07c0 /* 1984 */ -#define JFS_SUPER_MAGIC 0x3153464a /* "JFS1" */ -#define MINIX2_SUPER_MAGIC 0x2468 /* minix V2 fs */ -#define MINIX2_SUPER_MAGIC2 0x2478 /* minix V2 fs, 30 char names */ -#define MINIX_SUPER_MAGIC 0x137F /* original minix fs */ -#define MINIX_SUPER_MAGIC2 0x138F /* minix fs, 30 char names */ -#define MSDOS_SUPER_MAGIC 0x4d44 /* MD */ -#define NCP_SUPER_MAGIC 0x564c -#define NFS_SUPER_MAGIC 0x6969 -#define NFS_SUPER_MAGIC 0x6969 -#define OPENPROM_SUPER_MAGIC 0x9fa1 -#define OPROFILEFS_MAGIC 0x6f70726f -#define PFMFS_MAGIC 0xa0b4d889 -#define PIPEFS_MAGIC 0x50495045 -#define PROC_SUPER_MAGIC 0x9fa0 -#define QNX4_SUPER_MAGIC 0x002f /* qnx4 fs detection */ -#define RAMFS_MAGIC 0x858458f6 -#define REISERFS_SUPER_MAGIC 0x52654973 -#define ROMFS_MAGIC 0x7275 -#define SMB_SUPER_MAGIC 0x517B -#define SOCKFS_MAGIC 0x534F434B -#define SYSFS_MAGIC 0x62656572 -#define TMPFS_MAGIC 0x01021994 -#define UDF_SUPER_MAGIC 0x15013346 -#define UFS_MAGIC 0x00011954 -#define UFS_MAGIC_4GB 0x05231994 /* fs > 4 GB && fs_featurebits */ -#define UFS_MAGIC_FEA 0x00195612 /* fs_featurebits supported */ -#define UFS_MAGIC_LFN 0x00095014 /* fs supports filenames > 14 chars */ -#define UFS_MAGIC_SEC 0x00612195 /* B1 security fs */ -#define USBDEVICE_SUPER_MAGIC 0x9fa2 -#define VXFS_SUPER_MAGIC 0xa501FCF5 - -#endif /* _SYS_VFS_H */ diff --git a/klibc/include/sys/wait.h b/klibc/include/sys/wait.h deleted file mode 100644 index 4cfafc9408..0000000000 --- a/klibc/include/sys/wait.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * sys/wait.h - */ - -#ifndef _SYS_WAIT_H -#define _SYS_WAIT_H - -#include -#include -#include - -#include - -#define WEXITSTATUS(s) (((s) & 0xff00) >> 8) -#define WTERMSIG(s) ((s) & 0x7f) -#define WIFEXITED(s) (WTERMSIG(s) == 0) -#define WIFSTOPPED(s) (WTERMSIG(s) == 0x7f) -/* Ugly hack to avoid multiple evaluation of "s" */ -#define WIFSIGNALED(s) (WTERMSIG((s)+1) >= 2) -#define WCOREDUMP(s) ((s) & 0x80) -#define WSTOPSIG(s) WEXITSTATUS(s) - -__extern pid_t wait(int *); -__extern pid_t waitpid(pid_t, int *, int); -__extern pid_t wait3(int *, int, struct rusage *); -__extern pid_t wait4(pid_t, int *, int, struct rusage *); - -#endif /* _SYS_WAIT_H */ diff --git a/klibc/include/syslog.h b/klibc/include/syslog.h deleted file mode 100644 index 061dbcd5a7..0000000000 --- a/klibc/include/syslog.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * syslog.h - */ - -#ifndef _SYSLOG_H -#define _SYSLOG_H - -#include -#include - -/* Alert levels */ -#define LOG_EMERG 0 -#define LOG_ALERT 1 -#define LOG_CRIT 2 -#define LOG_ERR 3 -#define LOG_WARNING 4 -#define LOG_NOTICE 5 -#define LOG_INFO 6 -#define LOG_DEBUG 7 - -#define LOG_PRIMASK 7 -#define LOG_PRI(x) ((x) & LOG_PRIMASK) - - -/* Facilities; not actually used */ -#define LOG_KERN 0000 -#define LOG_USER 0010 -#define LOG_MAIL 0020 -#define LOG_DAEMON 0030 -#define LOG_AUTH 0040 -#define LOG_SYSLOG 0050 -#define LOG_LPR 0060 -#define LOG_NEWS 0070 -#define LOG_UUCP 0100 -#define LOG_CRON 0110 -#define LOG_AUTHPRIV 0120 -#define LOG_FTP 0130 -#define LOG_LOCAL0 0200 -#define LOG_LOCAL1 0210 -#define LOG_LOCAL2 0220 -#define LOG_LOCAL3 0230 -#define LOG_LOCAL4 0240 -#define LOG_LOCAL5 0250 -#define LOG_LOCAL6 0260 -#define LOG_LOCAL7 0270 - -#define LOG_FACMASK 01770 -#define LOG_FAC(x) (((x) >> 3) & (LOG_FACMASK >> 3)) - -/* openlog() flags; only LOG_PID and LOG_PERROR supported */ -#define LOG_PID 0x01 /* include pid with message */ -#define LOG_CONS 0x02 /* write to console on logger error */ -#define LOG_ODELAY 0x04 /* delay connection until syslog() */ -#define LOG_NDELAY 0x08 /* open connection immediately */ -#define LOG_NOWAIT 0x10 /* wait for child processes (unused on linux) */ -#define LOG_PERROR 0x20 /* additional logging to stderr */ - - -__extern void openlog(const char *, int, int); -__extern void syslog(int, const char *, ...); -__extern void vsyslog(int, const char *, va_list); -__extern void closelog(void); - -#endif /* _SYSLOG_H */ diff --git a/klibc/include/termios.h b/klibc/include/termios.h deleted file mode 100644 index 08a5e56855..0000000000 --- a/klibc/include/termios.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * termios.h - */ - -#ifndef _TERMIOS_H -#define _TERMIOS_H - -#include -#include -#include -#include -#include - -/* Redefine these so the magic constants == the ioctl number to use. */ -#undef TCSANOW -#undef TCSADRAIN -#undef TCSAFLUSH -#define TCSANOW TCSETS -#define TCSADRAIN TCSETSW -#define TCSAFLUSH TCSETSF - -static __inline__ int tcgetattr(int __fd, struct termios *__s) -{ - return ioctl(__fd, TCGETS, __s); -} - -static __inline__ int tcsetattr(int __fd, int __opt, const struct termios *__s) -{ - return ioctl(__fd, __opt, (void *)__s); -} - -static __inline__ int tcflow(int __fd, int __action) -{ - return ioctl(__fd, TCXONC, (void *)(intptr_t)__action); -} - -static __inline__ int tcflush(int __fd, int __queue) -{ - return ioctl(__fd, TCFLSH, (void *)(intptr_t)__queue); -} - -static __inline__ pid_t tcgetpgrp(int __fd) -{ - pid_t __p; - return ioctl(__fd, TIOCGPGRP, &__p) ? (pid_t)-1 : __p; -} - -static __inline__ pid_t tcgetsid(int __fd) -{ - pid_t __p; - return ioctl(__fd, TIOCGSID, &__p) ? (pid_t)-1 : __p; -} - -static __inline__ int tcsendbreak(int __fd, int __duration) -{ - return ioctl(__fd, TCSBRKP, (void *)(uintptr_t)__duration); -} - -static __inline__ int tcsetpgrp(int __fd, pid_t __p) -{ - return ioctl(__fd, TIOCSPGRP, &__p); -} - -static __inline__ speed_t cfgetospeed(const struct termios *__s) -{ - return (speed_t)(__s->c_cflag & CBAUD); -} - -static __inline__ speed_t cfgetispeed(const struct termios *__s) -{ - return (speed_t)(__s->c_cflag & CBAUD); -} - -static __inline__ int cfsetospeed(struct termios *__s, speed_t __v) -{ - __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); - return 0; -} - -static __inline__ int cfsetispeed(struct termios *__s, speed_t __v) -{ - __s->c_cflag = (__s->c_cflag & ~CBAUD) | (__v & CBAUD); - return 0; -} - -#endif /* _TERMIOS_H */ diff --git a/klibc/include/time.h b/klibc/include/time.h deleted file mode 100644 index 0f094c2806..0000000000 --- a/klibc/include/time.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * time.h - */ - -#ifndef _TIME_H -#define _TIME_H - -#include -#include - -__extern time_t time(time_t *); -__extern int nanosleep(const struct timespec *, struct timespec *); - -/* klibc-specific but useful since we don't have floating point */ -__extern char *strtotimeval(const char *str, struct timeval *tv); -__extern char *strtotimespec(const char *str, struct timespec *tv); - -#endif /* _TIME_H */ diff --git a/klibc/include/unistd.h b/klibc/include/unistd.h deleted file mode 100644 index 51fd7b769e..0000000000 --- a/klibc/include/unistd.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * unistd.h - */ - -#ifndef _UNISTD_H -#define _UNISTD_H - -#include -#include -#include -#include -#include - -__extern char **environ; -__extern __noreturn _exit(int); - -__extern pid_t fork(void); -__extern pid_t vfork(void); -__extern pid_t getpid(void); -__extern pid_t getpgid(pid_t); -__extern int setpgid(pid_t, pid_t); -__extern pid_t getppid(void); -__extern pid_t getpgrp(void); -__extern int setpgrp(void); -__extern pid_t setsid(void); -__extern pid_t getsid(pid_t); -__extern int execv(const char *, char * const *); -__extern int execvp(const char *, char * const *); -__extern int execve(const char *, char * const *, char * const *); -__extern int execvpe(const char *, char * const *, char * const *); -__extern int execl(const char *, const char *, ...); -__extern int execlp(const char *, const char *, ...); -__extern int execle(const char *, const char *, ...); -__extern int execlpe(const char *, const char *, ...); - -__extern int setuid(uid_t); -__extern uid_t getuid(void); -__extern int seteuid(uid_t); -__extern uid_t geteuid(void); -__extern int setgid(gid_t); -__extern gid_t getgid(void); -__extern int setegid(gid_t); -__extern gid_t getegid(void); -__extern int getgroups(int, gid_t *); -__extern int setgroups(size_t, const gid_t *); -__extern int setreuid(uid_t, uid_t); -__extern int setregid(gid_t, gid_t); -__extern int setresuid(uid_t, uid_t, uid_t); -__extern int setresgid(gid_t, gid_t, gid_t); -__extern int getfsuid(uid_t); -__extern int setfsuid(uid_t); - -/* Macros for access() */ -#define R_OK 4 /* Read */ -#define W_OK 2 /* Write */ -#define X_OK 1 /* Execute */ -#define F_OK 0 /* Existence */ - -__extern int access(const char *, int); -__extern int link(const char *, const char *); -__extern int unlink(const char *); -__extern int chdir(const char *); -__extern int fchdir(int); -__extern int chmod(const char *, mode_t); -__extern int fchmod(int, mode_t); -__extern int mkdir(const char *, mode_t); -__extern int rmdir(const char *); -__extern int pipe(int *); -__extern int chroot(const char *); -__extern int symlink(const char *, const char *); -__extern int readlink(const char *, char *, size_t); -__extern int chown(const char *, uid_t, gid_t); -__extern int fchown(int, uid_t, gid_t); -__extern int lchown(const char *, uid_t, gid_t); -__extern char *getcwd(char *, size_t); - -__extern int sync(void); - -/* Also in */ -#ifndef _KLIBC_IN_OPEN_C -__extern int open(const char *, int, ...); -#endif -__extern int close(int); -__extern off_t lseek(int, off_t, int); -/* off_t is 64 bits now even on 32-bit platforms; see llseek.c */ -static __inline__ off_t llseek(int __f, off_t __o, int __w) { - return lseek(__f, __o, __w); -} - -__extern ssize_t read(int, void *, size_t); -__extern ssize_t write(int, const void *, size_t); -__extern ssize_t pread(int, void *, size_t, off_t); -__extern ssize_t pwrite(int, void *, size_t, off_t); - -__extern int dup(int); -__extern int dup2(int, int); -__extern int fcntl(int, int, ...); -__extern int ioctl(int, int, void *); -__extern int flock(int, int); -__extern int fsync(int); -__extern int fdatasync(int); -__extern int ftruncate(int, off_t); - -__extern int pause(void); -__extern unsigned int alarm(unsigned int); -__extern unsigned int sleep(unsigned int); -__extern void usleep(unsigned long); - -__extern int gethostname(char *, size_t); -__extern int sethostname(const char *, size_t); -__extern int getdomainname(char *, size_t); -__extern int setdomainname(const char *, size_t); - -__extern void *__brk(void *); -__extern int brk(void *); -__extern void *sbrk(ptrdiff_t); - -__extern int getopt(int, char * const *, const char *); -__extern char *optarg; -__extern int optind, opterr, optopt; - -__extern int isatty(int); - -static __inline__ int getpagesize(void) { - extern unsigned int __page_size; - return __page_size; -} -static __inline__ int __getpageshift(void) { - extern unsigned int __page_shift; - return __page_shift; -} - -__extern int daemon(int, int); - -/* Standard file descriptor numbers. */ -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 - -#endif /* _UNISTD_H */ diff --git a/klibc/include/utime.h b/klibc/include/utime.h deleted file mode 100644 index 3dfa03a14a..0000000000 --- a/klibc/include/utime.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * utime.h - */ - -#ifndef _UTIME_H -#define _UTIME_H - -#include -#include -#include - -__extern int utime(const char *, const struct utimbuf *); - -#endif /* _UTIME_H */ - diff --git a/klibc/klcc.1 b/klibc/klcc.1 deleted file mode 100644 index 76334a3a54..0000000000 --- a/klibc/klcc.1 +++ /dev/null @@ -1,116 +0,0 @@ -.\" $Id: klcc.1,v 1.3 2005/04/19 23:27:46 hpa Exp $ -.\" ----------------------------------------------------------------------- -.\" -.\" Copyright 2005 H. Peter Anvin - All Rights Reserved -.\" -.\" Permission is hereby granted, free of charge, to any person -.\" obtaining a copy of this software and associated documentation -.\" files (the "Software"), to deal in the Software without -.\" restriction, including without limitation the rights to use, -.\" copy, modify, merge, publish, distribute, sublicense, and/or -.\" sell copies of the Software, and to permit persons to whom -.\" the Software is furnished to do so, subject to the following -.\" conditions: -.\" -.\" The above copyright notice and this permission notice shall -.\" be included in all copies or substantial portions of the Software. -.\" -.\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -.\" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -.\" OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -.\" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -.\" HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -.\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -.\" FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -.\" OTHER DEALINGS IN THE SOFTWARE. -.\" -.\" ----------------------------------------------------------------------- - -.TH klcc "1" "1 March 2005" "klibc" "H. Peter Anvin" -.SH NAME -klcc \- compile a program against klibc -.SH SYNOPSIS -.B klcc -[\fIgcc options\fP] -[\fB\-o\fP \fIoutfile\fP] -\fIinfile...\fP -.SH DESCRIPTION -.PP -.B klcc -is a wrapper around -.BR gcc (1) -and -.BR ld (1) -which compiles and links a program against the -.B klibc -tiny C library. It supports most -.B gcc -options. -.PP -Unlike -.BR gcc , -.B klcc -compiles with optimization on by default. Furthermore, the -optimization level used depends on whether or not -.B \-g -is specified, since -.B klcc -frequently uses options in the normal case which makes debugging -impossible. Therefore, compile without -.BR \-g , -.BR \-O , -.B \-f -or -.B \-m -option to use the default optimization level; this will generally -result in the smallest binaries. You may want to use -.B \-s -when linking, however. Use -.B \-O0 -to compile without any optimization whatsoever; this may not work depending -on the version of -.B gcc -used. -.PP -Use the -.B \-shared -or -.B \-static -option to compile for and link against shared or static klibc. Note -that shared klibc only supports running against the exact same klibc -binary as the binary was linked with. -.PP -In addition to standard -.B gcc -options, -.B klcc -supports options of the form \fB\-print-klibc-\fP\fIoption\fP, -which prints the corresponding klibc configuration option. -.SH AUTHOR -Written by H. Peter Anvin . -.SH COPYRIGHT -Copyright \(co 2005 H. Peter Anvin \- All Rights Reserved -.PP -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom -the Software is furnished to do so, subject to the following -conditions: -.PP -The above copyright notice and this permission notice shall -be included in all copies or substantial portions of the Software. -.PP -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. -.SH "SEE ALSO" -.BR gcc (1) - diff --git a/klibc/klcc.in b/klibc/klcc.in deleted file mode 100644 index 5629f24f1c..0000000000 --- a/klibc/klcc.in +++ /dev/null @@ -1,258 +0,0 @@ -# -*- perl -*- - -use IPC::Open3; - -# Standard includes -@includes = ("-I${prefix}/${KCROSS}include/arch/${ARCH}", - "-I${prefix}/${KCROSS}include/bits${BITSIZE}", - "-I${prefix}/${KCROSS}include"); - -# Default optimization options (for compiles without -g) -@optopt = @OPTFLAGS; -@goptopt = ('-O'); - -# Standard library directories -@stdlibpath = ("-L${prefix}/${KCROSS}lib"); - -# Options and libraries to pass to ld; shared versus static -@staticopt = ("${prefix}/${KCROSS}lib/crt0.o"); -@staticlib = ("${prefix}/${KCROSS}lib/libc.a"); -@sharedopt = (@EMAIN, "${prefix}/${KCROSS}lib/interp.o"); -@sharedlib = ('-R', "${prefix}/${KCROSS}lib/libc.so"); - -# Returns the language (-x option string) for a specific extension. -sub filename2lang($) { - my ($file) = @_; - - return 'c' if ( $file =~ /\.c$/ ); - return 'c-header' if ( $file =~ /\.h$/ ); - return 'cpp-output' if ( $file =~ /\.i$/ ); - return 'c++-cpp-output' if ( $file =~ /\.ii$/ ); - return 'objective-c' if ( $file =~ /\.m$/ ); - return 'objc-cpp-output' if ( $file =~ /\.mi$/ ); - return 'c++' if ( $file =~/\.(cc|cp|cxx|cpp|CPP|c\+\+|C)$/ ); - return 'c++-header' if ( $file =~ /\.(hh|H)$/ ); - return 'f77' if ( $file =~ /\.(f|for|FOR)$/ ); - return 'f77-cpp-input' if ( $file =~ /\.(F|fpp|FPP)$/ ); - return 'ratfor' if ( $file =~ /\.r$/ ); - - # Is this correct? - return 'ada' if ( $file =~ /\.(ads|adb)$/ ); - - return 'assembler' if ( $file =~ /\.s$/ ); - return 'assembler-with-cpp' if ( $file =~/ \.S$/ ); - - # Linker file; there is no option to gcc to assume something - # is a linker file, so we make up our own... - return 'obj'; -} - -# Produces a series of -x options and files -sub files_with_lang($$) { - my($files, $flang) = @_; - my(@as) = (); - my($xopt) = 'none'; - my($need); - - foreach $f ( @{$files} ) { - $need = ${$flang}{$f}; - - # Skip object files - if ( $need ne 'obj' ) { - unless ( $xopt eq $need || $need eq 'stdin') { - push(@as, '-x', $need); - $xopt = $need; - } - push(@as, $f); - } - } - - return @as; -} - -# Convert a return value from system() to an exit() code -sub syserr($) { - my($e) = @_; - - return ($e & 0x7f) | 0x80 if ( $e & 0xff ); - return $e >> 8; -} - -# Run a program; printing out the command line if $verbose is set -sub mysystem(@) { - print STDERR join(' ', @_), "\n" if ( $verbose ); - my $cmd = shift; - open(INPUT, "<&STDIN"); # dup STDIN filehandle to INPUT - my $childpid = open3("<&INPUT", ">&STDOUT", ">&STDERR", $cmd, @_); - waitpid ($childpid, 0); - return $?; -} - -# -# Initialization -# -open(NULL, '+<', '/dev/null') or die "$0: cannot open /dev/null\n"; - -# -# Begin parsing options. -# - -@ccopt = (); -@ldopt = (); -@libs = (); - -@files = (); # List of files -%flang = (); # Languages for files - -# This is 'c' for compile only, 'E' for preprocess only, -# 'S' for compile to assembly. -$operation = ''; # Compile and link - -# Current -x option. If undefined, it means autodetect. -undef $lang; - -$save_temps = 0; # The -save-temps option -$verbose = 0; # The -v option -$shared = 0; # Are we compiling shared? -$debugging = 0; # -g or -p option present? -$strip = 0; # -s option present? -undef $output; # -o option present? - -while ( defined($a = shift(@ARGV)) ) { - if ( $a !~ /^\-/ ) { - # Not an option. Must be a filename then. - push(@files, $a); - $flang{$a} = $lang || filename2lang($a); - } elsif ( $a eq '-' ) { - # gcc gets its input from stdin - push(@files, $a); - # prevent setting -x - $flang{$a} = 'stdin' - } elsif ( $a =~ /^-print-klibc-(.*)$/ ) { - # This test must precede -print - if ( defined($conf{$1}) ) { - print ${$conf{$1}}, "\n"; - exit 0; - } else { - die "$0: unknown option: $a\n"; - } - } elsif ( $a =~ /^(-print|-dump|--help|--version)/ ) { - # These share prefixes with some other options, so put this test early! - # Pseudo-operations; just pass to gcc and don't do anything else - push(@ccopt, $a); - $operation = 'c' if ( $operation eq '' ); - } elsif ( $a =~ /^-Wl,(.*)$/ ) { - # -Wl used to pass options to the linker - push(@ldopt, split(/,/, $1)); - } elsif ( $a =~ /^-([fmwWQdO]|std=|ansi|pedantic|M[GPD]|MMD)/ ) { - # Options to gcc - push(@ccopt, $a); - } elsif ( $a =~ /^-([DUI]|M[FQT])(.*)$/ ) { - # Options to gcc, which can take either a conjoined argument - # (-DFOO) or a disjoint argument (-D FOO) - push(@ccopt, $a); - push(@ccopt, shift(@ARGV)) if ( $2 eq '' ); - } elsif ( $a eq '-include' ) { - # Options to gcc which always take a disjoint argument - push(@ccopt, $a, shift(@ARGV)); - } elsif ( $a eq '-M' || $a eq '-MM' ) { - # gcc options, that force preprocessing mode - push(@ccopt, $a); - $operation = 'E'; - } elsif ( $a =~ /^-[gp]/ || $a eq '-p' ) { - # Debugging options to gcc - push(@ccopt, $a); - $debugging = 1; - } elsif ( $a eq '-v' ) { - push(@ccopt, $a); - $verbose = 1; - } elsif ( $a eq '-save-temps' ) { - push(@ccopt, $a); - $save_temps = 1; - } elsif ( $a =~ '^-([cSE])$' ) { - push(@ccopt, $a); - $operation = $1; - } elsif ( $a eq '-shared' ) { - $shared = 1; - } elsif ( $a eq '-static' ) { - $shared = 0; - } elsif ( $a eq '-s' ) { - $strip = 1; - } elsif ( $a eq '-o' ) { - $output = shift(@ARGV); - } elsif ( $a eq '-x' ) { - $lang = shift(@ARGV); - } elsif ( $a eq '-nostdinc' ) { - push(@ccopt, $a); - @includes = (); - } elsif ( $a =~ /^-([lL])(.*)$/ ) { - # Libraries - push(@libs, $a); - push(@libs, shift(@ARGV)) if ( $2 eq '' ); - } else { - die "$0: unknown option: $a\n"; - } -} - -if ( $debugging ) { - @ccopt = (@REQFLAGS, @includes, @goptopt, @ccopt); -} else { - @ccopt = (@REQFLAGS, @includes, @optopt, @ccopt); -} - -if ( $operation ne '' ) { - # Just run gcc with the appropriate options - @outopt = ('-o', $output) if ( defined($output) ); - $rv = mysystem($CC, @ccopt, @outopt, files_with_lang(\@files, \%flang)); -} else { - if ( scalar(@files) == 0 ) { - die "$0: No input files!\n"; - } - - @outopt = ('-o', $output || 'a.out'); - - @objs = (); - @rmobjs = (); - - foreach $f ( @files ) { - if ( $flang{$f} eq 'obj' ) { - push(@objs, $f); - } else { - $fo = $f; - $fo =~ s/\.[^\/.]+$/\.o/; - - die if ( $f eq $fo ); # safety check - - push(@objs, $fo); - push(@rmobjs, $fo) unless ( $save_temps ); - - $rv = mysystem($CC, @ccopt, '-c', '-o', $fo, '-x', $flang{$f}, $f); - - if ( $rv ) { - unlink(@rmobjs); - exit syserr($rv); - } - } - } - - # Get the libgcc pathname for the *current* gcc - open(LIBGCC, '-|', $CC, @ccopt, '-print-libgcc-file-name') - or die "$0: cannot get libgcc filename\n"; - $libgcc = ; - chomp $libgcc; - close(LIBGCC); - - if ( $shared ) { - $rv = mysystem($LD, @LDFLAGS, @sharedopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @sharedlib, $libgcc); - } else { - $rv = mysystem($LD, @LDFLAGS, @staticopt, @ldopt, @outopt, @objs, @libs, @stdlibpath, @staticlib, $libgcc); - } - - unlink(@rmobjs); - - if ( $strip && !$rv ) { - $rv = mysystem($STRIP, @STRIPFLAGS, $output); - } -} - -exit syserr($rv); diff --git a/klibc/klibc.spec.in b/klibc/klibc.spec.in deleted file mode 100644 index eef5dbf9d3..0000000000 --- a/klibc/klibc.spec.in +++ /dev/null @@ -1,126 +0,0 @@ -Summary: A minimal libc subset for use with initramfs. -Name: klibc -Version: @@VERSION@@ -Release: 1 -License: BSD/GPL -Group: Development/Libraries -URL: http://www.zytor.com/mailman/listinfo/klibc -Source: http://www.kernel.org/pub/linux/libs/klibc-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -BuildRequires: kernel >= 2.6.0, kernel-devel -Packager: H. Peter Anvin -Prefix: /usr -Vendor: Starving Linux Artists - -%define klibcdir %{_prefix}/lib/klibc -%define libdocdir %{_docdir}/%{name}-%{version}-%{release} -%define bindocdir %{_docdir}/%{name}-utils-%{version}-%{release} - -%description -%{name} is intended to be a minimalistic libc subset for use with -initramfs. It is deliberately written for small size, minimal -entanglement, and portability, not speed. - -%package devel -Summary: Libraries and tools needed to compile applications against klibc. -Group: Development/Libraries -Requires: klibc = %{version}-%{release} - -%description devel -This package contains the link libraries, header files, and gcc -wrapper scripts needed to compile applications against klibc. - -%package utils -Summary: Small utilities built with klibc. -Group: Utilities/System -Requires: klibc = %{version}-%{release} - -%description utils -This package contains a collection of programs that are linked against -klibc. These duplicate some of the functionality of a regular Linux -toolset, but are typically much smaller than their full-function -counterparts. They are intended for inclusion in initramfs images and -embedded systems. - -%prep -%setup -q -cp -dRs /lib/modules/`uname -r`/build/ ./linux -# Shouldn't need this when getting the build tree from /lib/modules -# make -C linux defconfig ARCH=%{_target_cpu} -# make -C linux prepare ARCH=%{_target_cpu} -# Deal with braindamage in RedHat's kernel-source RPM -rm -f linux/include/linux/config.h -cat < linux/include/linux/config.h -#ifndef _LINUX_CONFIG_H -#define _LINUX_CONFIG_H - -#include - -#endif -EOF -mkdir -p %{buildroot} - -%build -make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ - INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} - -%install -rm -rf %{buildroot} -make ARCH=%{_target_cpu} prefix=%{_prefix} bindir=%{_bindir} \ - INSTALLDIR=%{klibcdir} mandir=%{_mandir} INSTALLROOT=%{buildroot} \ - install - -# Make the .so file in /lib a hardlink (they will be expanded as two -# files automatically if it crosses filesystems when extracted.) -ln -f %{buildroot}%{klibcdir}/lib/klibc-*.so %{buildroot}/lib - -# Install the docs -mkdir -p %{buildroot}%{bindocdir} %{buildroot}%{libdocdir} -install -m 444 README %{buildroot}%{libdocdir} -install -m 444 klibc/README %{buildroot}%{libdocdir}/README.klibc -install -m 444 klibc/arch/README %{buildroot}%{libdocdir}/README.klibc.arch - -install -m 444 gzip/COPYING %{buildroot}%{bindocdir}/COPYING.gzip -install -m 444 gzip/README %{buildroot}%{bindocdir}/README.gzip -install -m 444 ipconfig/README %{buildroot}%{bindocdir}/README.ipconfig -install -m 444 kinit/README %{buildroot}%{bindocdir}/README.kinit - -%clean -rm -rf $RPM_BUILD_ROOT - -# -# Note: libc.so and interp.o are technically -devel files, but -# put them in this package until we can make really, really sure -# the dependency system can avoid confusion. (In fact, it would be -# good to eventually get them out of here, so that multiple runtimes -# can be installed should it be necessary.) -# -%files -%defattr(-,root,root,-) -/lib/klibc-*.so -%{klibcdir}/lib/*.so -%{klibcdir}/lib/interp.o - -%files devel -%defattr(-,root,root,-) -%{klibcdir}/include -%{klibcdir}/lib/*.a -%{klibcdir}/lib/crt0.o -%{_bindir}/klcc -%doc %{_mandir}/man1/* -%doc %{libdocdir}/* - -%files utils -%defattr(-,root,root,-) -%{klibcdir}/bin -%doc %{bindocdir}/* - -%changelog -* Tue Mar 1 2005 H. Peter Anvin -- New "make install" scheme, klcc - -* Tue Jul 6 2004 H. Peter Anvin -- Update to use kernel-source RPM for the kernel symlink. - -* Sat Nov 29 2003 Bryan O'Sullivan - -- Initial build. diff --git a/klibc/klibc/CAVEATS b/klibc/klibc/CAVEATS deleted file mode 100644 index 5bc11e4179..0000000000 --- a/klibc/klibc/CAVEATS +++ /dev/null @@ -1,61 +0,0 @@ - ------------------------------------------------- - Please note the following caveats to using klibc: - ------------------------------------------------- - -optimization: -------------- - -Compiling with -O0 is not supported. It may or may not work; please -use -O1 if you want to do maximize debuggability. - -Compiling with -O0 is more likely to work on gcc 3. - - -setjmp()/longjmp(): -------------------- - -setjmp() and longjmp() *do not* save signal state. sigsetjmp() and -siglongjmp() *do* save the signal mask -- regardless of the value of -the extra argument. - -The standards actually state that if you pass longjmp() a final value -of zero the library should change that to a 1! Presumably the reason -is so people who write broken code can get away with writing -longjmp(buf); or something equally bad. If you pass longjmp() a final -value of 0 you get what you deserve -- setjmp() will happily return 0. - - -stdio: ------- - -Only a small subset of the stdio functions are implemented. Those -that are implemented do not buffer, although they *do* trap EINTR or -short read/writes and iterate. - -_fread() and _fwrite(), which take only one size argument (like -read/write), but do handle EINTR/short return are also available. - - -namespaces: ------------ - -klibc frequently includes headers in other headers in a way that -exposes more symbols than POSIX says they should. "Live with it." - - -theading: ---------- - -klibc is not thread-safe. Consequently, clone() or any of the -pthreads functions are not included. - - -bsd_signal vs sysv_signal: --------------------------- - -There is no signal() call, because you never know if you want -Linux/SysV semantics (SA_RESETHAND) or GNU/BSD semantics (SA_RESTART). -The best, in *any* circumstances, is to never use signal() and instead -use sigaction(), but in order to simplify porting you can use either -sysv_signal() or bsd_signal(), depending on what you actually want. - diff --git a/klibc/klibc/Kbuild b/klibc/klibc/Kbuild deleted file mode 100644 index be239a6647..0000000000 --- a/klibc/klibc/Kbuild +++ /dev/null @@ -1,149 +0,0 @@ -# -# Kbuild file for klibc -# - -libc-y := vsnprintf.o snprintf.o vsprintf.o sprintf.o \ - asprintf.o vasprintf.o \ - vsscanf.o sscanf.o ctypes.o \ - strntoumax.o strntoimax.o \ - atoi.o atol.o atoll.o \ - strtol.o strtoll.o strtoul.o strtoull.o \ - strtoimax.o strtoumax.o \ - globals.o exitc.o atexit.o onexit.o \ - execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \ - fork.o wait.o wait3.o waitpid.o system.o setpgrp.o getpgrp.o \ - daemon.o \ - printf.o vprintf.o fprintf.o vfprintf.o perror.o \ - statfs.o fstatfs.o umount.o \ - open.o fopen.o fread.o fread2.o fgetc.o fgets.o \ - fwrite.o fwrite2.o fputc.o fputs.o puts.o putchar.o \ - sleep.o usleep.o strtotimespec.o strtotimeval.o \ - raise.o abort.o assert.o alarm.o pause.o \ - __signal.o sysv_signal.o bsd_signal.o siglist.o siglongjmp.o \ - sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ - brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ - memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ - memmove.o memchr.o memrchr.o \ - strcasecmp.o strncasecmp.o strndup.o strerror.o \ - strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o strnlen.o \ - strncat.o strlcpy.o strlcat.o \ - strstr.o strncmp.o strncpy.o strrchr.o \ - strxspn.o strspn.o strcspn.o strpbrk.o strsep.o strtok.o \ - gethostname.o getdomainname.o getcwd.o \ - seteuid.o setegid.o \ - getenv.o setenv.o putenv.o __put_env.o unsetenv.o \ - getopt.o readdir.o \ - syslog.o closelog.o pty.o getpt.o isatty.o reboot.o \ - time.o utime.o llseek.o nice.o getpriority.o \ - qsort.o \ - lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \ - inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ - inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \ - send.o recv.o - -libc-$(CONFIG_KLIBC_ERRLIST) += errlist.o - -libc-$(CONFIG_KLIBC_ZLIB) += \ - zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/gzio.o \ - zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \ - zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/inffast.o - -##### -# Add any architecture-specific rules -include $(obj)/arch/$(ARCH)/Makefile.inc - -##### -# Shared definitions -LIB := libc.a -SOLIB := libc.so -SOHASH := klibc.so -CRT0 := arch/$(ARCH)/crt0.o -INTERP_O := interp.o - -always := $(CRT0) $(LIB) $(SOLIB) $(SOHASH) $(INTERP_O) -LIB := $(call objectify,$(LIB)) -SOLIB := $(call objectify,$(SOLIB)) -SOHASH := $(call objectify,$(SOHASH)) -CRT0 := $(call objectify,$(CRT0)) -INTERP_O := $(call objectify,$(INTERP_O)) - -targets := arch/$(ARCH)/crt0.o -targets += $(libc-y) $(ARCHOBJS) - -# Generate syscall stubs -subdir-y += syscalls -# Generate socket calls stubs -subdir-y += socketcalls - -# Tell make to descend before building libs -$(obj)/syscalls/syscalls.o: $(obj)/syscalls -$(obj)/socketcalls/socketcalls.o: $(obj)/socketcalls - -##### -# Readable errormessages extracted from src.. -targets += errlist.c -quiet_cmd_errlist = GEN $@ - cmd_errlist = $(PERL) $< $(LINUXINCLUDE) -errlist > $@ || rm -f $@ - -$(obj)/errlist.c: $(srctree)/$(src)/makeerrlist.pl - $(call cmd,errlist) - -# full list of dependencies for klibc -libc-deps = $(call objectify, $(libc-y) $(ARCHOBJS)) \ - $(call objectify, syscalls/syscalls.o socketcalls/socketcalls.o) - -###### -# Build static library: libc.a -targets += libc.a __static_init.o -quiet_cmd_libc = USERAR $@ - cmd_libc = rm -f $@; \ - $(USERAR) cq $@ $(filter-out FORCE,$^); \ - $(USERRANLIB) $@ - -$(LIB): $(call objectify,__static_init.o) $(libc-deps) FORCE - $(call if_changed,libc) - -###### -# Build shared library -targets += libc.so __shared_init.o - -quiet_cmd_libcso = LD $@ - cmd_libcso = $(USERLD) $(USERLDFLAGS) $(USERSHAREDFLAGS) \ - -o $@ $(filter-out FORCE,$^) $(USERLIBGCC) - -$(SOLIB): $(CRT0) $(call objectify,__shared_init.o) $(libc-deps) FORCE - $(call if_changed,libcso) - - -##### -# Build sha1 hash values -targets += klibc.so libc.so.hash -hostprogs-y := sha1hash - -quiet_cmd_solibhash = HASH $@ - cmd_solibhash = $(USERNM) $< | egrep '^[0-9a-fA-F]+ [ADRTW] ' | \ - sort | $(obj)/sha1hash > $@ -$(SOLIB).hash: $(SOLIB) $(obj)/sha1hash FORCE - $(call if_changed,solibhash) - -quiet_cmd_sohash = GEN $@ - cmd_sohash = cat $< > $@; \ - $(USERSTRIP) $(USERSTRIPFLAGS) $@; \ - rm -f $(obj)/klibc-??????????????????????.so; \ - ln -f $@ $(obj)/klibc-`cat $(SOLIB).hash`.so -$(SOHASH): $(SOLIB) $(SOLIB).hash - $(call cmd,sohash) - - -##### -# build interp.o -targets += interp.o - -quiet_cmd_interp = BUILD $@ - cmd_interp = $(USERCC) $(usercflags) -D__ASSEMBLY__ \ - -DLIBDIR=\"$(SHLIBDIR)\" \ - -DSOHASH=\"`cat $(SOLIB).hash`\" \ - -c -o $@ $< - -$(INTERP_O): $(obj)/interp.S $(SOLIB).hash - $(call if_changed,interp) diff --git a/klibc/klibc/LICENSE b/klibc/klibc/LICENSE deleted file mode 100644 index b512ff96bc..0000000000 --- a/klibc/klibc/LICENSE +++ /dev/null @@ -1,73 +0,0 @@ -This license applies to all files in directory and its subdirectories, -unless otherwise noted in individual files. - - -Some files are derived from files derived from the include/ directory -of the Linux kernel, and are licensed under the terms of the GNU -General Public License, version 2, as released by the Free Software -Foundation, Inc.; incorporated herein by reference. - - ----- - -Some files are derived from files copyrighted by the Regents of The -University of California, and are available under the following -license: - -Note: The advertising clause in the license appearing on BSD Unix -files was officially rescinded by the Director of the Office of -Technology Licensing of the University of California on July 22 -1999. He states that clause 3 is "hereby deleted in its entirety." - - * Copyright (c) - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - - ----- - -For all remaining files, the following license applies: - - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * Any copyright notice(s) and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/klibc/klibc/MCONFIG b/klibc/klibc/MCONFIG deleted file mode 100644 index 24af09d8e0..0000000000 --- a/klibc/klibc/MCONFIG +++ /dev/null @@ -1,20 +0,0 @@ -# -*- makefile -*- -# -# Makefile configuration, without explicit rules -# - -SRCROOT = .. -include ../MCONFIG -include ../MRULES - -WARNFLAGS = -W -Wall -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Winline - -ifeq ($(ERRLIST),1) -REQFLAGS += -DWITH_ERRLIST -endif - -CFLAGS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d $(OPTFLAGS) $(REQFLAGS) $(WARNFLAGS) -INCLUDE += -I./zlib -CFLAGS += -DDYNAMIC_CRC_TABLE - -SOFLAGS = -fPIC diff --git a/klibc/klibc/Makefile b/klibc/klibc/Makefile deleted file mode 100644 index dff813fc59..0000000000 --- a/klibc/klibc/Makefile +++ /dev/null @@ -1,192 +0,0 @@ -# -# Makefile -# -# Main makefile -# - -# Include configuration rules -include MCONFIG - -INCLUDE += -I./zlib - -TESTS = $(patsubst %.c,%,$(wildcard tests/*.c)) \ - $(patsubst %.c,%.shared,$(wildcard tests/*.c)) -LIBOBJS = vsnprintf.o snprintf.o vsprintf.o sprintf.o \ - asprintf.o vasprintf.o \ - vsscanf.o sscanf.o ctypes.o \ - strntoumax.o strntoimax.o \ - atoi.o atol.o atoll.o \ - strtol.o strtoll.o strtoul.o strtoull.o \ - strtoimax.o strtoumax.o \ - globals.o exitc.o atexit.o onexit.o \ - execl.o execle.o execv.o execvpe.o execvp.o execlp.o execlpe.o \ - fork.o wait.o wait3.o waitpid.o system.o setpgrp.o getpgrp.o \ - daemon.o \ - printf.o vprintf.o fprintf.o vfprintf.o perror.o \ - statfs.o fstatfs.o umount.o \ - open.o fopen.o fread.o fread2.o fgetc.o fgets.o \ - fwrite.o fwrite2.o fputc.o fputs.o puts.o putchar.o \ - sleep.o usleep.o strtotimespec.o strtotimeval.o \ - raise.o abort.o assert.o alarm.o pause.o \ - __signal.o sysv_signal.o bsd_signal.o siglist.o siglongjmp.o \ - sigaction.o sigpending.o sigprocmask.o sigsuspend.o \ - brk.o sbrk.o malloc.o realloc.o calloc.o mmap.o \ - memcpy.o memcmp.o memset.o memccpy.o memmem.o memswap.o \ - memmove.o memchr.o memrchr.o \ - strcasecmp.o strncasecmp.o strndup.o strerror.o \ - strcat.o strchr.o strcmp.o strcpy.o strdup.o strlen.o strnlen.o \ - strncat.o strlcpy.o strlcat.o \ - strstr.o strncmp.o strncpy.o strrchr.o \ - strxspn.o strspn.o strcspn.o strpbrk.o strsep.o strtok.o \ - gethostname.o getdomainname.o getcwd.o \ - seteuid.o setegid.o \ - getenv.o setenv.o putenv.o __put_env.o unsetenv.o \ - getopt.o readdir.o \ - syslog.o closelog.o pty.o getpt.o isatty.o reboot.o \ - time.o utime.o llseek.o nice.o getpriority.o \ - qsort.o \ - lrand48.o jrand48.o mrand48.o nrand48.o srand48.o seed48.o \ - inet/inet_ntoa.o inet/inet_aton.o inet/inet_addr.o \ - inet/inet_ntop.o inet/inet_pton.o inet/bindresvport.o \ - send.o recv.o - -ifeq ($(ERRLIST),1) -LIBOBJS += errlist.o -endif - -ifeq ($(ZLIB),1) -LIBOBJS += zlib/adler32.o zlib/compress.o zlib/crc32.o zlib/gzio.o \ - zlib/uncompr.o zlib/deflate.o zlib/trees.o zlib/zutil.o \ - zlib/inflate.o zlib/infback.o zlib/inftrees.o zlib/inffast.o -endif - -SOLIB = libc.so -SOHASH = klibc.so - -CRT0 = crt0.o -LIB = libc.a - -INTERP_O = interp.o - -all: tests $(CRT0) $(LIB) $(SOLIB) $(SOHASH) $(INTERP_O) - -# Add any architecture-specific rules -include arch/$(ARCH)/Makefile.inc -EMAIN ?= -e main - -tests: $(TESTS) - -tests/%.o : tests/%.c - $(CC) $(CFLAGS) -c -o $@ $< - -# This particular file uses a bunch of formats gcc don't know of, in order -# to test the full range of our vsnprintf() function. This outputs a bunch -# of useless warnings unless we tell it not to. -tests/testvsnp.o : tests/testvsnp.c - $(CC) $(CFLAGS) -Wno-format -c -o $@ $< - -tests/% : tests/%.o $(LIB) $(CRT0) - $(LD) $(LDFLAGS) -o $@ $(CRT0) $< $(LIB) $(LIBGCC) - cp $@ $@.stripped - $(STRIPCMD) $@.stripped - -tests/%.shared : tests/%.o interp.o $(SOLIB) - $(LD) $(LDFLAGS) -o $@ $(EMAIN) interp.o tests/$*.o -R $(SOLIB) $(LIBGCC) - cp $@ $@.stripped - $(STRIPCMD) $@.stripped - -$(LIB): __static_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj - rm -f $(LIB) - $(AR) cq $(LIB) __static_init.o $(LIBOBJS) $(ARCHOBJS) \ - $(wildcard syscalls/*.o) $(wildcard socketcalls/*.o) - $(RANLIB) $(LIB) - -$(SOLIB): $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) syscalls/static.obj socketcalls/static.obj - $(LD) $(LDFLAGS) $(SHAREDFLAGS) -o $@ \ - $(CRT0) __shared_init.o $(LIBOBJS) $(ARCHOBJS) \ - $(wildcard syscalls/*.o) $(wildcard socketcalls/*.o) \ - $(LIBGCC) - -sha1hash: sha1hash.c - $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ $< - -$(SOLIB).hash: $(SOLIB) sha1hash - $(NM) $(SOLIB) | \ - egrep '^[0-9a-fA-F]+ [ADRTW] ' | sort | ./sha1hash > $@ - -$(SOHASH): $(SOLIB) $(SOLIB).hash - cp -f $(SOLIB) $@ - $(STRIPCMD) $@ - rm -f klibc-??????????????????????.so - ln -f $@ klibc-`cat $(SOLIB).hash`.so - -$(INTERP_O): interp.S $(SOLIB).hash - $(CC) $(CFLAGS) -D__ASSEMBLY__ -DLIBDIR=\"$(SHLIBDIR)\" \ - -DSOHASH=\"`cat $(SOLIB).hash`\" \ - -c -o $@ $< - -crt0.o: arch/$(ARCH)/crt0.o - cp arch/$(ARCH)/crt0.o . - -errlist.c: - $(PERL) makeerrlist.pl -q $(INCLUDE) -errlist > $@ || rm -f $@ - -# We pass -ansi to keep cpp from define e.g. "i386" as well as "__i386__" -SYSCALLS.i: SYSCALLS.def - $(CC) $(CFLAGS) -D__ASSEMBLY__ -ansi -x assembler-with-cpp -E -o $@ $< - -syscalls.nrs: ../include/sys/syscall.h - $(CC) $(CFLAGS) -Wp,-dM -x c -E -o $@ $< - -syscalls.dir: SYSCALLS.i syscalls.pl arch/$(ARCH)/sysstub.ph syscommon.h syscalls.nrs - rm -f syscalls/*.[Ssco] syscalls/*.obj - mkdir -p syscalls - $(PERL) syscalls.pl SYSCALLS.i arch/$(ARCH)/sysstub.ph $(ARCH) \ - $(BITSIZE) syscalls.nrs \ - syscalls ../include/klibc/havesyscall.h - touch $@ - -../include/klibc/havesyscall.h: syscalls.dir - : Generated by side effect - -socketcalls.dir: SOCKETCALLS.def socketcalls.pl socketcommon.h - rm -f socketcalls/*.[Ssco] socketcalls/*.obj - mkdir -p socketcalls - $(PERL) socketcalls.pl SOCKETCALLS.def $(ARCH) socketcalls - touch $@ - -%/static.obj: %.dir - $(MAKE) objects-$(basename $(notdir $@)) DIR=$*/ - -STATIC = $(addsuffix .o,$(basename $(wildcard $(DIR)*.[cS]))) - -objects-static: $(STATIC) - touch $(DIR)static.obj - -clean: archclean - find . -type f -a \( -name \*.[isoa] -o -name \*.l[iso] \) -print0 | xargs -0rt rm -f - rm -f *.a *.so *.hash *.syms *.stripped - rm -f $(TESTS) tests/*.stripped - rm -f syscalls/*.[Ssco] syscalls/*.obj syscalls.dir - rm -f socketcalls/*.[Ssco] socketcalls/*.obj socketcalls.dir - rm -f sha1hash errlist.c - -spotless: clean - rm -f ../include/klibc/havesyscall.h syscalls.nrs - find . \( -name \*~ -o -name '.*.d' \) -not -type d -print0 | \ - xargs -0rt rm -f - -bitsize: - @echo $(BITSIZE) - -install: all - $(INSTALL_DATA) $(LIB) $(SOLIB) $(CRT0) $(INTERP_O) \ - $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)lib - $(INSTALL_EXEC) klibc-`cat $(SOLIB).hash`.so \ - $(INSTALLROOT)$(INSTALLDIR)/$(CROSS)lib - $(INSTALL_EXEC) klibc-`cat $(SOLIB).hash`.so \ - $(INSTALLROOT)/$(SHLIBDIR) - -ifneq ($(wildcard $(DIR).*.d),) -include $(wildcard $(DIR).*.d) -endif diff --git a/klibc/klibc/README b/klibc/klibc/README deleted file mode 100644 index 3a53a8809f..0000000000 --- a/klibc/klibc/README +++ /dev/null @@ -1,81 +0,0 @@ -This is klibc, what is intended to be a minimalistic libc subset for -use with initramfs. It is deliberately written for small size, -minimal entaglement, and portability, not speed. It is definitely a -work in progress, and a lot of things are still missing. - - -The build procedure is not very polished yet, but it should work like -this: - -a) In the source root directory (the directory above the one in which - this file is found) create a symlink called "linux" pointing to a - reasonably recent Linux kernel tree (2.4 or 2.6 should be OK.) - This tree must have the include/asm symlink set up for the - architecture you're compiling for, and include/linux/autoconf.h - must exist. The easiest way to make sure of all of these is to do - a "make config" or any of its variants on the kernel tree is - question, followed by a "make dep" (2.4) or "make prepare" (2.6). - -b) If you're cross-compiling, change ARCH in the main MCONFIG file to - the appropriate architecture, and set CROSS to your toolchain - prefix. - - IMPORTANT: if you're on a 64-bit machine with a 32-bit userland - (ia64, mips64, ppc64 sparc64, s390x or x86_64), and you want to - build the 32-bit version: you need to set ARCH to the 32-bit - architecture as well as set up the linux/include/asm symlink to - point to the 32-bit architecture. Building the 32-bit architecture - usually (but not always) produces smaller binaries, and is likely - to be better tested. - - If you are on ARM, and want to build a thumb version of the library - (this is supported), change OPTFLAGS in arch/arm/MCONFIG to build - thumb code. - - The following is the last known status of various architectures: - - alpha: Working static, shared untested - arm-thumb: Untested - arm26: Not yet ported - arm: Working - cris: Working - h8300: Not yet ported - i386: Working - ia64: Working - m32r: Untested - m68k: Not yet ported - mips64: Not yet ported - mips: Working - parisc: Untested - ppc64: Working - ppc: Working - s390: Working static, shared untested - s390x: Working - sh: Untested - sparc64: Untested - sparc: Working - v850: Not yet ported - x86-64: Working - - Shared library support requires recent binutils on many - architectures. - - "Need sysstub.ph" means the architectural changes first implemented - in klibc-0.117 has not yet been implemented; klibc-0.116 did, - however, work. "Not yet ported" means no porting work has been - done on this architecture. - - Note that even the "working" ones likely have bugs. Please report - them if you run into them. - -c) Type "make" and pray... - -d) Try the test programs in the tests/ directory. They should run... - -Contact the klibc mailing list: - - http://www.zytor.com/mailman/listinfo/klibc - -... for more info. - - -hpa diff --git a/klibc/klibc/SOCKETCALLS.def b/klibc/klibc/SOCKETCALLS.def deleted file mode 100644 index e70b3fc16e..0000000000 --- a/klibc/klibc/SOCKETCALLS.def +++ /dev/null @@ -1,21 +0,0 @@ -; -*- fundamental -*- -; -; These are calls that are invoked via the socketcall mechanism -; Note that on most architectures this is simply #included into -; SYSCALLS.def. -; - int socket(int, int, int) - int bind(int, struct sockaddr *, int) - int connect(int, struct sockaddr *, socklen_t) - int listen(int, int) - int accept(int, struct sockaddr *, socklen_t *) - int getsockname(int, struct sockaddr *, socklen_t *) - int getpeername(int, struct sockaddr *, socklen_t *) - int socketpair(int, int, int, int *) - int sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t) - int recvfrom(int, void *, size_t, unsigned int, struct sockaddr *, socklen_t *) - int shutdown(int, int) - int setsockopt(int, int, int, const void *, socklen_t) - int getsockopt(int, int, int, void *, socklen_t *) - int sendmsg(int, const struct msghdr *, unsigned int) - int recvmsg(int, struct msghdr *, unsigned int) diff --git a/klibc/klibc/SYSCALLS.def b/klibc/klibc/SYSCALLS.def deleted file mode 100644 index b78919b134..0000000000 --- a/klibc/klibc/SYSCALLS.def +++ /dev/null @@ -1,231 +0,0 @@ -; -*- fundamental -*- -; -; This is a list of system calls we invoke "directly". These -; are generated into syscall stubs in their own files, so the -; linker can do its job properly. -; -; The full description of a line is: -; [<[?][!]arch,...>] type [sysname,...][@systype][::funcname](args) -; -; ? means only instantiate this system call if present in asm/unistd.h -; - -#include -#include - -; -; Process-related syscalls -; - void _exit,exit::_exit(int) - pid_t clone::__clone(unsigned long, void *) - pid_t clone::__clone2(unsigned long, void *, void *) - pid_t fork() - pid_t fork@forkish() - pid_t vfork() - pid_t vfork@forkish() - pid_t getpid() - pid_t getxpid@dual0::getpid() -int setpgid(pid_t, pid_t) -pid_t getpgid(pid_t) - pid_t getppid() - pid_t getxpid@dual1::getppid() -pid_t setsid() -pid_t getsid(pid_t) -pid_t wait4(pid_t, int *, int, struct rusage *) -int execve(const char *, char * const *, char * const *) - int nice(int) - int getpriority(int, int) - int getpriority::__getpriority(int, int) -int setpriority(int, int, int) -int sched_setscheduler(pid_t, int, const struct sched_param *) -int sched_yield() - -; -; User and group IDs -; -int setuid32,setuid::setuid(uid_t) -int setgid32,setgid::setgid(gid_t) - uid_t getuid32,getuid::getuid() - uid_t getxuid@dual0::getuid() - gid_t getgid32,getgid::getgid() - gid_t getxgid@dual0::getgid() - uid_t geteuid32,geteuid::geteuid() - uid_t getxuid@dual1::geteuid() - gid_t getegid32,getegid::getegid() - gid_t getxgid@dual1::getegid() -int getgroups32,getgroups::getgroups(int, gid_t *) -int setgroups32,setgroups::setgroups(size_t, const gid_t *) -int setreuid32,setreuid::setreuid(uid_t, uid_t) -int setregid32,setregid::setregid(gid_t, gid_t) -int setfsuid32,setfsuid::setfsuid(uid_t) -int setfsgid32,setfsgid::setfsgid(gid_t) -int setresuid32,setresuid::setresuid(int, uid_t, uid, uid_t) - -; -; Filesystem-related system calls -; -int mount(const char *, const char *, const char *, unsigned long, const void *) - int umount2(const char *, int) - int umount::umount2(const char *, int) - int pivot_root(const char *, const char *) -int sync() -#ifdef __NR_statfs64 -int statfs64::__statfs64(const char *, size_t, struct statfs *) -#else -int statfs(const char *, struct statfs *) -#endif -#ifdef __NR_fstatfs64 -int fstatfs64::__fstatfs64(int, size_t, struct statfs *) -#else -int fstatfs(int, struct statfs *) -#endif -int swapon(const char *, int) -int swapoff(const char *) - -; -; Inode-related system calls -; -int access(const char *, int) -int link(const char *, const char *) -int unlink(const char *) -int chdir(const char *) -int fchdir(int) -int rename(const char *, const char *) -int mknod(const char *, mode_t, dev_t) -int chmod(const char *, mode_t) -int fchmod(int, mode_t) -int mkdir(const char *, mode_t) -int rmdir(const char *) - int pipe(int *) -mode_t umask(mode_t) -int chroot(const char *) -int symlink(const char *, const char *) -int readlink(const char *, char *, size_t) - int stat64,stat::stat(const char *, struct stat *) - int lstat64,lstat::lstat(const char *, struct stat *) - int fstat64,fstat::fstat(int, struct stat *) - int stat::stat(const char *, struct stat *) - int lstat::lstat(const char *, struct stat *) - int fstat::fstat(int, struct stat *) -int getdents64,getdents::getdents(unsigned int, struct dirent *, unsigned int) -int chown32,chown::chown(const char *, uid_t, gid_t) -int fchown32,fchown::fchown(int, uid_t, gid_t) -int lchown32,lchown::lchown(const char *, uid_t, gid_t) -int getcwd::__getcwd(char *, size_t) - int utime(const char *, const struct utimbuf *) - int utimes(const char *, const struct timeval *) - int inotify_init(void) - int inotify_add_watch(int, const char *, __u32) - int inotify_rm_watch(int, __u32) - -; -; I/O operations -; - int open::__open(const char *, int, mode_t) -<64> int open(const char *, int, mode_t) -ssize_t read(int, void *, size_t) -ssize_t write(int, const void *, size_t) -int close(int) -<64> off_t lseek(int, off_t, int) -<32> int _llseek::__llseek(int, unsigned long, unsigned long, off_t *, int) -int dup(int) -int dup2(int, int) - int fcntl64@varadic::fcntl(int, int, unsigned long) - int fcntl(int, int, unsigned long) - int fcntl64,fcntl::fcntl(int, int, unsigned long) -int ioctl(int, int, void *) -int flock(int, int) -int _newselect,select::select(int, fd_set *, fd_set *, fd_set *, struct timeval *) -int poll(struct pollfd *, nfds_t, long) -int fsync(int) -int fdatasync,fsync::fdatasync(int) -int readv(int, const struct iovec *, int) -int writev(int, const struct iovec *, int) -int ftruncate64,ftruncate::ftruncate(int, off_t) -ssize_t pread64,pread::pread(int, void *, size_t, off_t) -ssize_t pwrite64,pwrite::pwrite(int, void *, size_t, off_t) - -; -; Signal operations -; -; We really should get rid of the non-rt_* of these, but that takes -; sanitizing for all architectures, sigh. -#ifdef __NR_sigaction -int sigaction::__sigaction(int, const struct sigaction *, struct sigaction *) -#else -int rt_sigaction::__rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t) -#endif -#ifdef __NR_sigsuspend -int sigsuspend(const sigset_t *) -#else -int rt_sigsuspend::__rt_sigsuspend(const sigset_t *, size_t) -#endif -#ifdef __NR_sigpending -int sigpending(sigset_t *) -#else -int rt_sigpending::__rt_sigpending(sigset_t *, size_t) -#endif -#ifdef __NR_sigprocmask -int sigprocmask(int, const sigset_t *, sigset_t *) -#else -int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t) -#endif -int kill(pid_t, int) - unsigned int alarm(unsigned int) -int getitimer(int, struct itimerval *) -int setitimer(int, const struct itimerval *, struct itimerval *) - -; -; Time-related system calls -; - time_t time(time_t *) -clock_t times(struct tms *) -int gettimeofday(struct timeval *, struct timezone *) -int settimeofday(const struct timeval *, const struct timezone *) -int nanosleep(const struct timespec *, struct timespec *) - int pause() - -; -; Memory -; -void * brk::__brk(void *) -int munmap(void *, size_t) -void * mremap(void *, size_t, size_t, unsigned long) -int msync(const void *, size_t, int) -int mprotect(const void *, size_t, int) -#if (_BITSIZE == 32 && defined(__NR_mmap2)) || \ - (_BITSIZE == 64 && !defined(__NR_mmap)) - void * mmap2::__mmap2(void *, size_t, int, int, int, long) -#else - void * mmap(void *, size_t, int, int, int, long) -#endif -int mlockall(int) -int munlockall() -int mlock(const void *, size_t) -int munlock(const void *, size_t) - -; -; System stuff -; -int uname(struct utsname *) -int setdomainname(const char *, size_t) -int sethostname(const char *, size_t) -long init_module(void *, unsigned long, const char *) -long delete_module(const char *, unsigned int) -int reboot::__reboot(int, int, int, void *) -int syslog::klogctl(int, char *, int) -int sysinfo(struct sysinfo *) - -; -; Low-level I/O (generally architecture-specific) -; - int iopl(int) - int ioperm(unsigned long, unsigned long, int) - int vm86(struct vm86_struct *) - -; -; Most architectures have the socket interfaces using regular -; system calls. -; - long socketcall::__socketcall(int, const unsigned long *) -#include "SOCKETCALLS.def" diff --git a/klibc/klibc/__put_env.c b/klibc/klibc/__put_env.c deleted file mode 100644 index 7e55f2c43b..0000000000 --- a/klibc/klibc/__put_env.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * __put_env.c - common code for putenv() and setenv() - */ - -#include -#include -#include -#include - -/* Initialized to zero, meaning "not malloc'd" */ -static size_t __environ_size; - -/* str should be a duplicated version of the input string; - len is the length of the key including the = sign */ -int __put_env(char *str, size_t len, int overwrite) -{ - char **p, *q; - char **newenv; - size_t n; - - n = 1; /* Include space for final NULL */ - for ( p = environ ; (q = *p) ; p++ ) { - n++; - if ( !strncmp(q,str,len) ) { - if ( !overwrite ) - free(str); - else - *p = str; /* Possible memory leak... */ - return 0; - } - } - - /* Need to extend the environment */ - if ( n < __environ_size ) { - p[1] = NULL; - *p = str; - return 0; - } else { - if ( __environ_size ) { - newenv = realloc(environ, (__environ_size << 1)*sizeof(char *)); - if ( !newenv ) - return -1; - - __environ_size <<= 1; - } else { - /* Make a reasonable guess how much more space we need */ - size_t newsize = n+32; - newenv = malloc(newsize*sizeof(char *)); - if ( !newenv ) - return -1; - - memcpy(newenv, environ, n*sizeof(char *)); - __environ_size = newsize; - } - newenv[n-1] = str; /* Old NULL position */ - newenv[n] = NULL; - environ = newenv; - } - return 0; -} diff --git a/klibc/klibc/__shared_init.c b/klibc/klibc/__shared_init.c deleted file mode 100644 index 592a3db6f5..0000000000 --- a/klibc/klibc/__shared_init.c +++ /dev/null @@ -1,2 +0,0 @@ -#define SHARED 1 -#include "libc_init.c" diff --git a/klibc/klibc/__signal.c b/klibc/klibc/__signal.c deleted file mode 100644 index b5081d386b..0000000000 --- a/klibc/klibc/__signal.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * __signal.c - */ - -#include - -__sighandler_t __signal(int signum, __sighandler_t handler, int flags) -{ - struct sigaction sa; - - sa.sa_handler = handler; - sa.sa_flags = flags; - sigemptyset(&sa.sa_mask); - - if ( sigaction(signum, &sa, &sa) ) { - return (__sighandler_t)SIG_ERR; - } else { - return (__sighandler_t)sa.sa_handler; - } -} - - diff --git a/klibc/klibc/__static_init.c b/klibc/klibc/__static_init.c deleted file mode 100644 index 0b59eedaa7..0000000000 --- a/klibc/klibc/__static_init.c +++ /dev/null @@ -1,2 +0,0 @@ -#define SHARED 0 -#include "libc_init.c" diff --git a/klibc/klibc/abort.c b/klibc/klibc/abort.c deleted file mode 100644 index 9280d9861b..0000000000 --- a/klibc/klibc/abort.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * abort.c - */ - -#include -#include -#include - -void abort(void) -{ - sigset_t set; - - sigemptyset(&set); - sigaddset(&set, SIGABRT); - sigprocmask(SIG_UNBLOCK, &set, NULL); - raise(SIGABRT); - _exit(255); /* raise() should have killed us */ -} - diff --git a/klibc/klibc/alarm.c b/klibc/klibc/alarm.c deleted file mode 100644 index 40c0969432..0000000000 --- a/klibc/klibc/alarm.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * alarm.c - */ - -#include -#include - -#ifndef __NR_alarm - -/* Emulate alarm() via setitimer() */ - -unsigned int alarm(unsigned int seconds) -{ - struct itimerval iv; - - iv.it_interval.tv_sec = iv.it_interval.tv_usec = 0; - iv.it_value.tv_sec = seconds; - iv.it_value.tv_usec = 0; - - setitimer(ITIMER_REAL, &iv, &iv); - - return iv.it_value.tv_sec + (iv.it_value.tv_usec ? 1 : 0); -} - -#endif diff --git a/klibc/klibc/arch/README b/klibc/klibc/arch/README deleted file mode 100644 index eceb23de4b..0000000000 --- a/klibc/klibc/arch/README +++ /dev/null @@ -1,67 +0,0 @@ -To port klibc to a new architecture, you need: - -a) A directory structure - -Each archtecture has an arch/ directory, which should include an -MCONFIG and a Makefile.inc file. - -b) Startup code (arch/*/crt0.S) - -The crt0.S assembly routine typically corresponds to the following -pseudo-C code. In addition, each architecture needs any support -routines that gcc-generated code expects to find in the system library --- Alpha, for example, needs divide subroutines. - -The "getenvtest" test program is a very good test for proper crt0.S -functionality. - - -extern __noreturn __libc_init(void *, void *); - -__noreturn _start(void) -{ - void *elf_data = get_elf_data_address(); /* Usually the stack address */ - void *atexit_ptr = get_atexit_ptr(); /* Usually in a register */ - - /* Some architectures need this for debugging to work */ - setup_null_stack_frame_if_necessary(); - - __libc_init(elf_data, atexit_ptr); -} - - -c) A setenv implementation (arch/*/setjmp.S, arch/*/include/klibc/archsetjmp.h) - -On most (but not all!) architectures, this entails creating a setjmp -buffer big enough to hold all callee-saved registers, plus the stack -pointer and the return address. In setjmp.S you have: - -* A "setjmp" function that writes out the callee-saved registers, the - stack pointer and the return address to the buffer pointed to by the - first argument, and then returns zero normally. - - On some architectures you need to take some kind of action to make - sure the contents of the stack is actually manifest in memory and - not cached in the CPU. In some cases (e.g. on SPARC) this will - automatically spill the registers onto the stack; then they don't - need to be spilled into the jmp_buf. - -* A "longjmp" function that read back these same registers from the - jmp_buf pointed to by the first argument, and returns the second - argument *to the address specified in the jmp_buf*. - - On some architectures you need to take some kind of action to flush - any cached stack data or return stack. - - -d) Any support functions needed by gcc, *unless* they are in libgcc - *and* libgcc is usable for klibc on your particular platform. If - libgcc isn't usable for klibc (on MIPS, for example, libgcc is - compiled in a way that is not compatible with klibc) there are - reasonably good clones of most of the libgcc functions in the libgcc - directory. To use them, add them to ARCHOBJS in - arch/*/Makefile.inc. - - -e) A link location for the shared klibc. This should be specified in - SHAREDFLAGS in arch/*/MCONFIG. diff --git a/klibc/klibc/arch/alpha/MCONFIG b/klibc/klibc/arch/alpha/MCONFIG deleted file mode 100644 index d7ab6c0b82..0000000000 --- a/klibc/klibc/arch/alpha/MCONFIG +++ /dev/null @@ -1,17 +0,0 @@ -# -*- makefile -*- -# -# arch/alpha/MCONFIG -# -# Build configuration for this architecture -# - -OPTFLAGS = -Os -BITSIZE = 64 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 7 GB - normal binaries start at 4.5 GB, and the stack is below -# the binary. -SHAREDFLAGS = -Ttext 0x1c0000200 - diff --git a/klibc/klibc/arch/alpha/Makefile.inc b/klibc/klibc/arch/alpha/Makefile.inc deleted file mode 100644 index 62fce9dc28..0000000000 --- a/klibc/klibc/arch/alpha/Makefile.inc +++ /dev/null @@ -1,95 +0,0 @@ -# -*- makefile -*- -# -# arch/alpha/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -# Special CFLAGS for the divide code -DIVCFLAGS = $(REQFLAGS) \ - -O3 -fomit-frame-pointer -fcall-saved-1 -fcall-saved-2 \ - -fcall-saved-3 -fcall-saved-4 -fcall-saved-5 -fcall-saved-6 \ - -fcall-saved-7 -fcall-saved-8 -ffixed-15 -fcall-saved-16 \ - -fcall-saved-17 -fcall-saved-18 -fcall-saved-19 -fcall-saved-20 \ - -fcall-saved-21 -fcall-saved-22 -ffixed-23 -fcall-saved-24 \ - -ffixed-25 -ffixed-27 - -ARCHOBJS = \ - arch/$(ARCH)/__divqu.o \ - arch/$(ARCH)/__remqu.o \ - arch/$(ARCH)/__divq.o \ - arch/$(ARCH)/__remq.o \ - arch/$(ARCH)/__divlu.o \ - arch/$(ARCH)/__remlu.o \ - arch/$(ARCH)/__divl.o \ - arch/$(ARCH)/__reml.o \ - arch/$(ARCH)/pipe.o \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - arch/$(ARCH)/sysdual.o - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - -arch/$(ARCH)/%.s: arch/$(ARCH)/%.ss - sed -e 's/\$$0\b/$$27/g' -e 's/\$$24\b/$$99/g' \ - -e 's/\$$16\b/$$24/g' -e 's/\$$17\b/$$25/g' \ - -e 's/\$$26\b/$$23/g' -e 's/\$$99\b/$$16/g' < $< > $@ - -arch/$(ARCH)/%.ls: arch/$(ARCH)/%.lss - sed -e 's/\$$0\b/$$27/g' -e 's/\$$24\b/$$99/g' \ - -e 's/\$$16\b/$$24/g' -e 's/\$$17\b/$$25/g' \ - -e 's/\$$26\b/$$23/g' -e 's/\$$99\b/$$16/g' < $< > $@ - -arch/$(ARCH)/__divqu.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=0 -DBITS=64 -DNAME=__divqu -S -o $@ $< - -arch/$(ARCH)/__remqu.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=1 -DBITS=64 -DNAME=__remqu -S -o $@ $< - -arch/$(ARCH)/__divq.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=0 -DBITS=64 -DNAME=__divq -S -o $@ $< - -arch/$(ARCH)/__remq.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=1 -DBITS=64 -DNAME=__remq -S -o $@ $< - -arch/$(ARCH)/__divlu.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__divlu -S -o $@ $< - -arch/$(ARCH)/__remlu.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__remlu -S -o $@ $< - -arch/$(ARCH)/__divl.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__divl -S -o $@ $< - -arch/$(ARCH)/__reml.ss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__reml -S -o $@ $< - -arch/$(ARCH)/__divqu.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=0 -DBITS=64 -DNAME=__divqu -S -o $@ $< - -arch/$(ARCH)/__remqu.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=1 -DBITS=64 -DNAME=__remqu -S -o $@ $< - -arch/$(ARCH)/__divq.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=0 -DBITS=64 -DNAME=__divq -S -o $@ $< - -arch/$(ARCH)/__remq.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=1 -DBITS=64 -DNAME=__remq -S -o $@ $< - -arch/$(ARCH)/__divlu.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__divlu -S -o $@ $< - -arch/$(ARCH)/__remlu.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__remlu -S -o $@ $< - -arch/$(ARCH)/__divl.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__divl -S -o $@ $< - -arch/$(ARCH)/__reml.lss: arch/$(ARCH)/divide.c - $(CC) $(DIVCFLAGS) -fPIC -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__reml -S -o $@ $< - -archclean: - rm -f arch/$(ARCH)/*.ss arch/$(ARCH)/*.lss - diff --git a/klibc/klibc/arch/alpha/README-gcc b/klibc/klibc/arch/alpha/README-gcc deleted file mode 100644 index 9aaba72837..0000000000 --- a/klibc/klibc/arch/alpha/README-gcc +++ /dev/null @@ -1,23 +0,0 @@ - The current Alpha chips don't provide hardware for integer - division. The C compiler expects the functions - - __divqu: 64-bit unsigned long divide - __remqu: 64-bit unsigned long remainder - __divq/__remq: signed 64-bit - __divlu/__remlu: unsigned 32-bit - __divl/__reml: signed 32-bit - - These are not normal C functions: instead of the normal calling - sequence, these expect their arguments in registers t10 and t11, and - return the result in t12 (aka pv). Register AT may be clobbered - (assembly temporary), anything else must be saved. - - Furthermore, the return address is in t9 instead of ra. - - Normal function Divide functions - --------------- ---------------- - v0 ($0) t12/pv ($27) - a0 ($16) t10 ($24) - a1 ($17) t11 ($25) - ra ($26) t9 ($23) - diff --git a/klibc/klibc/arch/alpha/crt0.S b/klibc/klibc/arch/alpha/crt0.S deleted file mode 100644 index 904b539741..0000000000 --- a/klibc/klibc/arch/alpha/crt0.S +++ /dev/null @@ -1,22 +0,0 @@ -# -# arch/alpha/crt0.S -# - - .text - .type _start,@function - .ent _start, 0 - .globl _start -_start: - .frame $30, 0, $26, 0 - mov $31, $15 - br $29, 1f -1: ldgp $29, 0($29) - .prologue 0 - - lda $16, 0($30) # ELF data structure - lda $17, 0($0) # atexit pointer - - jsr $26, __libc_init - - .size _start,.-_start - .end _start diff --git a/klibc/klibc/arch/alpha/divide.c b/klibc/klibc/arch/alpha/divide.c deleted file mode 100644 index 49d77cd5dc..0000000000 --- a/klibc/klibc/arch/alpha/divide.c +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include - -#if BITS == 64 -typedef uint64_t uint; -typedef int64_t sint; -#else -typedef uint32_t uint; -typedef int32_t sint; -#endif - -#ifdef SIGNED -typedef sint xint; -#else -typedef uint xint; -#endif - -xint NAME (uint num, uint den) -{ - uint quot = 0, qbit = 1; - int minus = 0; - xint v; - - if ( den == 0 ) { - /* This is really $16, but $16 and $24 are exchanged by a script */ - register unsigned long cause asm("$24") = GEN_INTDIV; - asm volatile("call_pal %0" :: "i" (PAL_gentrap), "r" (cause)); - return 0; /* If trap returns... */ - } - -#if SIGNED - if ( (sint)(num^den) < 0 ) - minus = 1; - if ( (sint)num < 0 ) num = -num; - if ( (sint)den < 0 ) den = -den; -#endif - - /* Left-justify denominator and count shift */ - while ( (sint)den >= 0 ) { - den <<= 1; - qbit <<= 1; - } - - while ( qbit ) { - if ( den <= num ) { - num -= den; - quot += qbit; - } - den >>= 1; - qbit >>= 1; - } - - v = (xint)(REM ? num : quot); - if ( minus ) v = -v; - return v; -} diff --git a/klibc/klibc/arch/alpha/pipe.c b/klibc/klibc/arch/alpha/pipe.c deleted file mode 100644 index 5aee9edbab..0000000000 --- a/klibc/klibc/arch/alpha/pipe.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -/* pipe() on alpha returns both file descriptors in registers -- - $0 and $20 respectively. This is unlike any other system call, - as far as I can tell. */ - -int pipe(int *fds) -{ - register long sc_0 __asm__("$0"); - register long sc_19 __asm__("$19"); - register long sc_20 __asm__("$20"); - - sc_0 = __NR_pipe; - asm volatile("callsys" : "=r" (sc_0), "=r" (sc_19), "=r" (sc_20) - : "0" (sc_0) - : _syscall_clobbers); - - if ( sc_19 ) { - errno = sc_19; - return -1; - } - - fds[0] = sc_0; - fds[1] = sc_20; - - return 0; -} diff --git a/klibc/klibc/arch/alpha/setjmp.S b/klibc/klibc/arch/alpha/setjmp.S deleted file mode 100644 index 5d915f2dbe..0000000000 --- a/klibc/klibc/arch/alpha/setjmp.S +++ /dev/null @@ -1,77 +0,0 @@ -# -# setjmp.S -# - -# -# The jmp_buf looks like: -# -# s0..5 -# fp -# ra -# gp -# sp -# - -#include - - .text - .align 3 - .type setjmp,@function - .ent setjmp, 0 - .globl setjmp -setjmp: - lda v0, 0(zero) - stq s0, 0(a0) - stq s1, 8(a0) - stq s2, 16(a0) - stq s3, 24(a0) - stq s4, 32(a0) - stq s5, 40(a0) - stq fp, 48(a0) - stq ra, 56(a0) - stq gp, 64(a0) - stq sp, 72(a0) - stt $f2, 80(a0) - stt $f3, 88(a0) - stt $f4, 96(a0) - stt $f5, 104(a0) - stt $f6, 112(a0) - stt $f7, 120(a0) - stt $f8, 128(a0) - stt $f9, 136(a0) - ret zero,(ra),1 - - .size setjmp,.-setjmp - .end setjmp - - .type longjmp,@function - .ent longjmp, 0 - .globl longjmp -longjmp: - mov a1, v0 - ldq s0, 0(a0) - ldq s1, 8(a0) - ldq s2, 16(a0) - ldq s3, 24(a0) - ldq s4, 32(a0) - ldq s5, 40(a0) - ldq fp, 48(a0) - ldq ra, 56(a0) - ldq gp, 64(a0) - ldq sp, 72(a0) - ldt $f2, 80(a0) - ldt $f3, 88(a0) - ldt $f4, 96(a0) - ldt $f5, 104(a0) - ldt $f6, 112(a0) - ldt $f7, 120(a0) - ldt $f8, 128(a0) - ldt $f9, 136(a0) - /* We're bound to get a mispredict here, but at least give us - a chance to get the return stack back in sync... */ - ret zero,(ra),1 - - .size longjmp,.-longjmp - .end longjmp - - diff --git a/klibc/klibc/arch/alpha/syscall.S b/klibc/klibc/arch/alpha/syscall.S deleted file mode 100644 index 0c87414b1a..0000000000 --- a/klibc/klibc/arch/alpha/syscall.S +++ /dev/null @@ -1,26 +0,0 @@ -# -# arch/alpha/syscall.S -# - -#include - - .text - .align 3 - .type __syscall_common,@function - .ent __syscall_common, 0 - .globl __syscall_common -__syscall_common: - .frame sp,0,ra,0 - callsys - beq a3, 1f - br pv, 2f # pv <- pc -2: - ldgp gp, 0(pv) - lda a1, errno - lda v0, -1(zero) - stl a3, 0(a1) -1: - ret zero,(ra),1 - - .size __syscall_common,.-__syscall_common - .end __syscall_common diff --git a/klibc/klibc/arch/alpha/sysdual.S b/klibc/klibc/arch/alpha/sysdual.S deleted file mode 100644 index c00db88960..0000000000 --- a/klibc/klibc/arch/alpha/sysdual.S +++ /dev/null @@ -1,33 +0,0 @@ -# -# arch/alpha/sysdual.S -# - -# -# Some system calls have an alternate return value in r20 (a4). -# This system call stub is for system calls where that is -# the "real" return value. -# - -#include - - .text - .align 3 - .type __syscall_dual1,@function - .ent __syscall_dual1, 0 - .globl __syscall_dual1 -__syscall_dual1: - .frame sp,0,ra,0 - callsys - mov v0, a4 - beq a3, 1f - br pv, 2f # pv <- pc -2: - ldgp gp, 0(pv) - lda a1, errno - lda v0, -1(zero) - stl a3, 0(a1) -1: - ret zero,(ra),1 - - .size __syscall_dual1,.-__syscall_dual1 - .end __syscall_dual1 diff --git a/klibc/klibc/arch/alpha/sysstub.ph b/klibc/klibc/arch/alpha/sysstub.ph deleted file mode 100644 index 08b97e807e..0000000000 --- a/klibc/klibc/arch/alpha/sysstub.ph +++ /dev/null @@ -1,37 +0,0 @@ -# -*- perl -*- -# -# arch/alpha/sysstub.ph -# -# Script to generate system call stubs -# - -# On Alpha, most system calls follow the standard convention, with the -# system call number in r0 (v0), return an error value in r19 (a3) as -# well as the return value in r0 (v0). -# -# A few system calls are dual-return with the second return value in -# r20 (a4). - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - $stype = $stype || 'common'; - $stype = 'common' if ( $stype eq 'dual0' ); - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.text\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.ent\t${fname}, 0\n"; # What is this? - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT "\tlda\tv0, __NR_${sname}(zero)\n"; - print OUT "\tbr __syscall_${stype}\n"; - print OUT "\t.size\t${fname},.-${fname}\n"; - print OUT "\t.end\t${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/arm/MCONFIG b/klibc/klibc/arch/arm/MCONFIG deleted file mode 100644 index fe26b996a7..0000000000 --- a/klibc/klibc/arch/arm/MCONFIG +++ /dev/null @@ -1,26 +0,0 @@ -# -*- makefile -*- -# -# arch/arm/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -THUMB = n -CPU_ARCH := armv4 -CPU_TUNE := strongarm - -OPTFLAGS = -Os -march=$(CPU_ARCH) -mtune=$(CPU_TUNE) -BITSIZE = 32 - -ifeq ($(THUMB),y) -CPU_ARCH := $(CPU_ARCH)t -OPTFLAGS += -mthumb -LDFLAGS += --thumb-entry _start -endif - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -SHAREDFLAGS = -Ttext 0x01000200 diff --git a/klibc/klibc/arch/arm/Makefile.inc b/klibc/klibc/arch/arm/Makefile.inc deleted file mode 100644 index 0603d850bd..0000000000 --- a/klibc/klibc/arch/arm/Makefile.inc +++ /dev/null @@ -1,43 +0,0 @@ -# -*- makefile -*- -# -# arch/arm/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - libgcc/__divsi3.o \ - libgcc/__modsi3.o \ - libgcc/__udivsi3.o \ - libgcc/__umodsi3.o \ - libgcc/__udivmodsi4.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o \ - arch/arm/syscall.o - -ifeq ($(THUMB),y) -ARCHOBJS += arch/arm/setjmp-thumb.o -LIBGCC = -else -ARCHOBJS += arch/arm/setjmp-arm.o -endif - -arch/arm/sysstubs.a: arch/arm/sysstubs.pl - mkdir -p arch/arm/sysstubs - $(PERL) $< arch/arm/sysstubs - $(MAKE) $(patsubst %.S,%.o,$(wildcard arch/arm/sysstubs/*.S)) - -rm -f $@ - $(AR) cq $@ arch/arm/sysstubs/*.o - $(RANLIB) $@ - - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - -archclean: - -rm -rf arch/arm/sysstubs - -rm -f arch/arm/sysstubs.a diff --git a/klibc/klibc/arch/arm/crt0.S b/klibc/klibc/arch/arm/crt0.S deleted file mode 100644 index fc1104ef0e..0000000000 --- a/klibc/klibc/arch/arm/crt0.S +++ /dev/null @@ -1,23 +0,0 @@ -# -# arch/arm/crt0.S -# -# void _start(void) -# { -# __libc_init(elf_structure, atexit_ptr); -# } -# - - .text - .align 4 - .type _start,#function - .globl _start - -#ifdef __thumb__ - .thumb_func -#endif - -_start: mov r0, sp - mov r1, #0 - bl __libc_init - - .size _start,.-_start diff --git a/klibc/klibc/arch/arm/setjmp-arm.S b/klibc/klibc/arch/arm/setjmp-arm.S deleted file mode 100644 index 1a29ee7f71..0000000000 --- a/klibc/klibc/arch/arm/setjmp-arm.S +++ /dev/null @@ -1,39 +0,0 @@ -# -# arch/arm/setjmp.S -# -# setjmp/longjmp for the ARM architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# r4 -# r5 -# r6 -# r7 -# r8 -# r9 -# r10 -# fp -# sp -# lr -# - - .text - .align 4 - .globl setjmp - .type setjmp, #function -setjmp: - stmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr} - mov r0, #0 - mov pc, lr - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, #function -longjmp: - ldmia r0, {r4, r5, r6, r7, r8, r9, r10, fp, sp, lr} - mov r0, r1 - mov pc, lr - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/arm/setjmp-thumb.S b/klibc/klibc/arch/arm/setjmp-thumb.S deleted file mode 100644 index b581c5f7ad..0000000000 --- a/klibc/klibc/arch/arm/setjmp-thumb.S +++ /dev/null @@ -1,58 +0,0 @@ -# -# arch/arm/setjmp-thumb.S -# -# setjmp/longjmp for the ARM/thumb architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# lr -# r4 -# r5 -# r6 -# r7 -# r8 -# r9 -# r10 -# fp -# sp -# - - .text - .align 4 - .globl setjmp - .type setjmp, #function - .thumb_func -setjmp: - mov r3, lr - stmia r0!, {r3, r4, r5, r6, r7} - mov r3, r8 - mov r4, r9 - mov r5, r10 - mov r6, fp - mov r7, sp - stmia r0!, {r3, r4, r5, r6, r7} - mov r0, #0 - mov pc, lr - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, #function - .thumb_func -longjmp: - mov r2, r0 - add r0, #5*4 - ldmia r0!, {r3, r4, r5, r6, r7} - mov r8, r3 - mov r9, r4 - mov r10, r5 - mov fp, r6 - mov sp, r7 - ldmia r2!, {r3, r4, r5, r6, r7} - mov r0, r1 - bne 1f - mov r0, #1 -1: mov pc, r3 - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/arm/syscall.S b/klibc/klibc/arch/arm/syscall.S deleted file mode 100644 index 0e73f68ed0..0000000000 --- a/klibc/klibc/arch/arm/syscall.S +++ /dev/null @@ -1,50 +0,0 @@ -/* - * arch/arm/syscall.S - * - * System call common handling - */ - - .type __syscall_common,#function - .globl __syscall_common -#ifndef __thumb__ - /* ARM version - this is executed after the swi */ - - .align 4 -__syscall_common: - cmn r0, #4096 - rsbcs r2, r0, #0 - ldrcs r3, 1f - mvncs r0, #0 - strcs r2, [r3] - ldmfd sp!,{r4,r5,pc} - - .align 4 -1: - .word errno - -#else - /* Thumb version - must still load r4 and r5 and run swi */ - - .thumb_func - .align 2 -__syscall_common: - ldr r4, [sp #12] - ldr r5, [sp #16] - swi 0 - ldr r1, 2f - cmp r0, r1 - bcc 1f - ldr r1, 3f - neg r2, r0 - mvn r0, #0 - str r2, [r1] -1: - pop {r4,r5,r7,pc} - - .align 4 -2: - .word #-4095 -3: - .word errno - -#endif diff --git a/klibc/klibc/arch/arm/sysstub.ph b/klibc/klibc/arch/arm/sysstub.ph deleted file mode 100644 index 256ea3d534..0000000000 --- a/klibc/klibc/arch/arm/sysstub.ph +++ /dev/null @@ -1,44 +0,0 @@ -# -*- perl -*- -# -# arch/arm/sysstub.ph -# -# Script to generate system call stubs -# - - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - - print OUT "\t.text\n"; - print OUT "\t.type\t${fname}, #function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "\t.align\t4\n"; - - print OUT "#ifndef __thumb__\n"; - - # ARM version first - print OUT "${fname}:\n"; - print OUT "\tstmfd\tsp!,{r4,r5,lr}\n"; - print OUT "\tldr\tr4,[sp,#12]\n"; - print OUT "\tldr\tr5,[sp,#16]\n"; - print OUT "\tswi\t# __NR_${sname}\n"; - print OUT "\tb\t__syscall_common\n"; - - print OUT "#else\n"; - - # Thumb version - print OUT "\t.thumb_func\n"; - print OUT "${fname}:\n"; - print OUT "\tpush\t{r4,r5,r7,pc}\n"; - print OUT "\tmov\tr7, # __NR_${sname}\n"; - print OUT "\tb\t__syscall_common\n"; - - print OUT "#endif\n"; - - print OUT "\t.size\t__syscall${i},.-__syscall${i}\n"; -} - -1; diff --git a/klibc/klibc/arch/cris/MCONFIG b/klibc/klibc/arch/cris/MCONFIG deleted file mode 100644 index 2762494a30..0000000000 --- a/klibc/klibc/arch/cris/MCONFIG +++ /dev/null @@ -1,26 +0,0 @@ -# -*- makefile -*- -# -# arch/cris/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -fomit-frame-pointer -BITSIZE = 32 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 224 MB - normal binaries start at 0 -# (lib?)gcc on cris seems to insist on producing .init and .fini sections -SHAREDFLAGS = --section-start .init=0x0e000100 - -# The CRIS compiler needs an -iprefix to find libgcc includes when -# nostdinc is used. It also needs -mlinux to compile linux applications. -INCLUDE_PREFIX = $(shell $(CC) -print-libgcc-file-name | sed -e s/libgcc.a//) -ARCHREQFLAGS = -iprefix $(INCLUDE_PREFIX) -mlinux - -# Special flags needed for linking -LDFLAGS += -mcrislinux diff --git a/klibc/klibc/arch/cris/Makefile.inc b/klibc/klibc/arch/cris/Makefile.inc deleted file mode 100644 index 75fa17ba99..0000000000 --- a/klibc/klibc/arch/cris/Makefile.inc +++ /dev/null @@ -1,33 +0,0 @@ -# -*- makefile -*- -# -# arch/cris/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/__Umod.o \ - arch/$(ARCH)/__Udiv.o \ - arch/$(ARCH)/__Mod.o \ - arch/$(ARCH)/__Div.o \ - arch/$(ARCH)/__negdi2.o \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o - -arch/$(ARCH)/__Umod.o: arch/$(ARCH)/divide.c - $(CC) $(CFLAGS) -DSIGNED=0 -DREM=1 -DBITS=32 -DNAME=__Umod -c -o $@ $< -arch/$(ARCH)/__Udiv.o: arch/$(ARCH)/divide.c - $(CC) $(CFLAGS) -DSIGNED=0 -DREM=0 -DBITS=32 -DNAME=__Udiv -c -o $@ $< -arch/$(ARCH)/__Mod.o: arch/$(ARCH)/divide.c - $(CC) $(CFLAGS) -DSIGNED=1 -DREM=1 -DBITS=32 -DNAME=__Mod -c -o $@ $< -arch/$(ARCH)/__Div.o: arch/$(ARCH)/divide.c - $(CC) $(CFLAGS) -DSIGNED=1 -DREM=0 -DBITS=32 -DNAME=__Div -c -o $@ $< - -archclean: diff --git a/klibc/klibc/arch/cris/__negdi2.S b/klibc/klibc/arch/cris/__negdi2.S deleted file mode 100644 index 3cca9edfa8..0000000000 --- a/klibc/klibc/arch/cris/__negdi2.S +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/cris/__negdi2.c - */ - -/* - * In 2's complement arithmetric, -x == (~x + 1), so - * -{h,l} = (~{h,l} + {0,1) - * -{h,l} = {~h,~l} + {0,1} - * -{h,l} = {~h + cy, ~l + 1} - * ... where cy = (l == 0) - * -{h,l} = {~h + cy, -l} - */ - - .text - .balign 4 - .type __negdi2,@function - .globl __negdi2 -__negdi2: - neg.d $r10,$r10 - seq $r12 - not $r11 - ret - add.d $r12,$r11 - - .size __negdi2, .-__negdi2 diff --git a/klibc/klibc/arch/cris/crt0.S b/klibc/klibc/arch/cris/crt0.S deleted file mode 100644 index 989c82b2ba..0000000000 --- a/klibc/klibc/arch/cris/crt0.S +++ /dev/null @@ -1,28 +0,0 @@ -# -# arch/cris/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - - .text - .balign 4 - .type _start,@function - .globl _start -_start: - /* Save the address of the ELF argument array */ - move.d $sp,$r10 /* Address of ELF arguments */ - - /* atexit() function (assume null) */ - moveq 0,$r11 - - /* Set up a dummy stack frame to keep gcc from getting confused */ - push $r11 - push $r11 - jump __libc_init - - .size _start, .-_start - diff --git a/klibc/klibc/arch/cris/divide.c b/klibc/klibc/arch/cris/divide.c deleted file mode 100644 index 29081dc953..0000000000 --- a/klibc/klibc/arch/cris/divide.c +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include - -#if BITS == 64 -typedef uint64_t unum; -typedef int64_t snum; -#else -typedef uint32_t unum; -typedef int32_t snum; -#endif - -#ifdef SIGNED -typedef snum xnum; -#else -typedef unum xnum; -#endif - -#ifdef __cris__ -static inline unum __attribute__((const)) dstep(unum rs, unum rd) { - asm("dstep %1,%0" : "+r" (rd) : "r" (rs)); - return rd; -} - -static inline unum __attribute__((const)) lz(unum rs) { - unum rd; - asm("lz %1,%0" : "=r" (rd) : "r" (rs)); - return rd; -} - -#else -/* For testing */ -static inline unum __attribute__ ((const)) dstep(unum rs, unum rd) { - rd <<= 1; - if ( rd >= rs ) - rd -= rs; - - return rd; -} - -static inline unum __attribute__((const)) lz(unum rs) { - unum rd = 0; - while ( rs >= 0x7fffffff ) { - rd++; - rs <<= 1; - } - return rd; -} - -#endif - -xnum NAME (unum num, unum den) -{ - unum quot = 0, qbit = 1; - int minus = 0; - xnum v; - - if ( den == 0 ) { - raise(SIGFPE); - return 0; /* If signal ignored... */ - } - - if (den == 1) return (xnum)(REM ? 0 : num); - -#if SIGNED - if ( (snum)(num^den) < 0 ) - minus = 1; - if ( (snum)num < 0 ) num = -num; - if ( (snum)den < 0 ) den = -den; -#endif - - den--; - - - /* Left-justify denominator and count shift */ - while ( (snum)den >= 0 ) { - den <<= 1; - qbit <<= 1; - } - - while ( qbit ) { - if ( den <= num ) { - num -= den; - quot += qbit; - } - den >>= 1; - qbit >>= 1; - } - - v = (xnum)(REM ? num : quot); - if ( minus ) v = -v; - return v; -} diff --git a/klibc/klibc/arch/cris/setjmp.S b/klibc/klibc/arch/cris/setjmp.S deleted file mode 100644 index 43162418af..0000000000 --- a/klibc/klibc/arch/cris/setjmp.S +++ /dev/null @@ -1,37 +0,0 @@ -# -# arch/cris/setjmp.S -# -# setjmp/longjmp for the cris architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# $r8..$r0 (in that order) -# $sp ($r14) -# return address -# - - .text - .balign 4 - .globl setjmp - .type setjmp, @function -setjmp: - movem $r8,[$r10+] /* Save $r8..$r0 at $r10... */ - move.d $sp,[$r10+] - move $srp,[$r10] - ret - moveq 0,$r10 - - .size setjmp,.-setjmp - - .text - .balign 4 - .globl longjmp - .type longjmp, @function -longjmp: - movem [$r10+],$r8 /* Load $r8..$r0 from $r10... */ - move.d [$r10+],$sp - jump [$r10] - move.d $r11,$r10 - - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/cris/syscall.S b/klibc/klibc/arch/cris/syscall.S deleted file mode 100644 index d71495aba2..0000000000 --- a/klibc/klibc/arch/cris/syscall.S +++ /dev/null @@ -1,30 +0,0 @@ -/* - * arch/cris/syscall.S - * - * On cris, r9 contains the syscall number (set by generated stub); - * r10..r13 contain arguments 0-3 per the standard calling convention, - * and arguments 4-5 are passed in $mof and $srp; however, we have - * to save $srp around the system call. - */ - - .section ".text","ax" - .balign 4 - .globl __syscall_common - .type __syscall_common,@function -__syscall_common: - push $srp - move [$sp+4],$mof - move [$sp+8],$srp - break 13 - - cmps.w -4096,$r10 - blo 1f - neg.d $r10,$r11 - move.d $r11,[errno] - moveq -1,$r10 -1: - pop $srp - ret - nop - - .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/cris/sysstub.ph b/klibc/klibc/arch/cris/sysstub.ph deleted file mode 100644 index 182ad73f8c..0000000000 --- a/klibc/klibc/arch/cris/sysstub.ph +++ /dev/null @@ -1,29 +0,0 @@ -# -*- perl -*- -# -# arch/cris/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.text\n"; - print OUT "\t.type\t${fname},\@function\n"; - print OUT "\t.globl\t${fname}\n"; - print OUT "\t.balign\t4\n"; - print OUT "${fname}:\n"; - print OUT "#if __NR_${sname} <= 31\n"; - print OUT "\t moveq\t__NR_${sname}, \$r9\n"; - print OUT "#else\n"; - print OUT "\t move.d\t__NR_${sname}, \$r9\n"; - print OUT "#endif\n"; - print OUT "\tjump\t__syscall_common\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/i386/MCONFIG b/klibc/klibc/arch/i386/MCONFIG deleted file mode 100644 index ecd1307d7f..0000000000 --- a/klibc/klibc/arch/i386/MCONFIG +++ /dev/null @@ -1,33 +0,0 @@ -# -*- makefile -*- -# -# arch/i386/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -# Enable this to compile with register parameters; only safe for -# gcc >= 3 -REGPARM_OPT := -mregparm=3 -D_REGPARM=3 - -gcc_major := $(shell echo __GNUC__ | $(CC) -E -xc - | tail -n 1) - -OPTFLAGS = -march=i386 -Os -g -fomit-frame-pointer -LDFLAGS = -m elf_i386 - -ifneq ($(gcc_major),2) -REQFLAGS += $(REGPARM_OPT) -OPTFLAGS += -falign-functions=0 -falign-jumps=0 -falign-loops=0 -ARCHREQFLAGS += -m32 -else -OPTFLAGS += -malign-functions=0 -malign-jumps=0 -malign-loops=0 -endif - -BITSIZE = 32 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 96 MB - normal binaries start at 128 MB -SHAREDFLAGS = -Ttext 0x06000200 diff --git a/klibc/klibc/arch/i386/Makefile.inc b/klibc/klibc/arch/i386/Makefile.inc deleted file mode 100644 index 80344bd0a5..0000000000 --- a/klibc/klibc/arch/i386/Makefile.inc +++ /dev/null @@ -1,28 +0,0 @@ -# -*- makefile -*- -# -# arch/i386/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/exits.o \ - arch/$(ARCH)/socketcall.o \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - arch/$(ARCH)/open.o \ - arch/$(ARCH)/sigreturn.o \ - arch/$(ARCH)/libgcc/__ashldi3.o \ - arch/$(ARCH)/libgcc/__ashrdi3.o \ - arch/$(ARCH)/libgcc/__lshrdi3.o \ - arch/$(ARCH)/libgcc/__muldi3.o \ - arch/$(ARCH)/libgcc/__negdi2.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o - -archclean: diff --git a/klibc/klibc/arch/i386/crt0.S b/klibc/klibc/arch/i386/crt0.S deleted file mode 100644 index fb02c694c0..0000000000 --- a/klibc/klibc/arch/i386/crt0.S +++ /dev/null @@ -1,32 +0,0 @@ -# -# arch/i386/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - - .text - .align 4 - .type _start,@function - .globl _start -_start: - # Save the address of the ELF argument array - movl %esp,%eax # Address of ELF arguments - # Set up a faux stack frame for the benefit of gdb - xorl %ebp,%ebp - push %ebp # Keep gdb from getting confused - push %ebp # Keep gdb from getting confused - # Push the arguments and called __libc_init() -#ifndef _REGPARM - push %edx # atexit() function - push %eax # ELF array -#endif - call __libc_init - # If __libc_init returns, problem... - hlt - - .size _start, .-_start - diff --git a/klibc/klibc/arch/i386/exits.S b/klibc/klibc/arch/i386/exits.S deleted file mode 100644 index ed23d98bcb..0000000000 --- a/klibc/klibc/arch/i386/exits.S +++ /dev/null @@ -1,45 +0,0 @@ -# -# exit and _exit get included in *every* program, and gcc generates -# horrible code for them. Yes, this only saves a few bytes, but -# it does it in every program. -# - -#include - - .data - .align 4 - .globl __exit_handler - .type __exit_handler,@object -__exit_handler: - .long _exit - .size __exit_handler,4 - - .text - .align 4 - .globl exit - .type exit,@function -exit: - jmp *(__exit_handler) - .size exit,.-exit - - /* No need to save any registers... we're exiting! */ - .text - .align 4 - .globl _exit - .type _exit,@function -_exit: -#ifdef _REGPARM - movl %eax,%ebx -#else - popl %ebx - popl %ebx -#endif -#if __NR_exit == 1 - xorl %eax,%eax - incl %eax -#else - movl $__NR_exit,%eax -#endif - int $0x80 - hlt - .size _exit,.-exit diff --git a/klibc/klibc/arch/i386/libgcc/__ashldi3.S b/klibc/klibc/arch/i386/libgcc/__ashldi3.S deleted file mode 100644 index 61982eb0eb..0000000000 --- a/klibc/klibc/arch/i386/libgcc/__ashldi3.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/i386/libgcc/__ashldi3.S - * - * 64-bit shl - */ - .text - .align 4 - .globl __ashldi3 - .type __ashldi3,@function -__ashldi3: -#ifndef _REGPARM - movl 4(%esp),%eax - movl 8(%esp),%edx - movb 12(%esp),%cl -#endif - cmpb $32,%cl - jae 1f - - shldl %cl,%eax,%edx - shl %cl,%eax - ret - -1: - xorl %edx,%edx - shl %cl,%eax - xchgl %edx,%eax - ret - - .size __ashldi3,.-__ashldi3 diff --git a/klibc/klibc/arch/i386/libgcc/__ashrdi3.S b/klibc/klibc/arch/i386/libgcc/__ashrdi3.S deleted file mode 100644 index 4ac2af69a1..0000000000 --- a/klibc/klibc/arch/i386/libgcc/__ashrdi3.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/i386/libgcc/__ashrdi3.S - * - * 64-bit sar - */ - .text - .align 4 - .globl __ashrdi3 - .type __ashrdi3,@function -__ashrdi3: -#ifndef _REGPARM - movl 4(%esp),%eax - movl 8(%esp),%edx - movb 12(%esp),%cl -#endif - cmpb $32,%cl - jae 1f - - shrdl %cl,%edx,%eax - sarl %cl,%edx - ret - -1: - sarl %cl,%edx - movl %edx,%eax - cdq - ret - - .size __ashrdi3,.-__ashrdi3 diff --git a/klibc/klibc/arch/i386/libgcc/__lshrdi3.S b/klibc/klibc/arch/i386/libgcc/__lshrdi3.S deleted file mode 100644 index 730ee43178..0000000000 --- a/klibc/klibc/arch/i386/libgcc/__lshrdi3.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/i386/libgcc/__lshrdi3.S - * - * 64-bit shr - */ - .text - .align 4 - .globl __lshrdi3 - .type __lshrdi3,@function -__lshrdi3: -#ifndef _REGPARM - movl 4(%esp),%eax - movl 8(%esp),%edx - movb 12(%esp),%cl -#endif - cmpb $32,%cl - jae 1f - - shrdl %cl,%edx,%eax - shrl %cl,%edx - ret - -1: - shrl %cl,%edx - xorl %eax,%eax - xchgl %edx,%eax - ret - - .size __lshrdi3,.-__lshrdi3 diff --git a/klibc/klibc/arch/i386/libgcc/__muldi3.S b/klibc/klibc/arch/i386/libgcc/__muldi3.S deleted file mode 100644 index 81e23b190e..0000000000 --- a/klibc/klibc/arch/i386/libgcc/__muldi3.S +++ /dev/null @@ -1,34 +0,0 @@ -/* - * arch/i386/libgcc/__muldi3.S - * - * 64*64 = 64 bit unsigned multiplication - */ - - .text - .align 4 - .globl __muldi3 - .type __muldi3,@function -__muldi3: - push %esi -#ifndef _REGPARM - movl 8(%esp),%eax - movl %eax,%esi - movl 16(%esp),%ecx - mull %ecx - imull 12(%esp),%ecx - imull 20(%esp),%esi - addl %ecx,%edx - addl %esi,%edx -#else - movl %eax,%esi - push %edx - mull %ecx - imull 8(%esp),%esi - addl %esi,%edx - pop %esi - imull %esi,%ecx - addl %ecx,%edx -#endif - pop %esi - ret - .size __muldi3,.-__muldi3 diff --git a/klibc/klibc/arch/i386/libgcc/__negdi2.S b/klibc/klibc/arch/i386/libgcc/__negdi2.S deleted file mode 100644 index c4f2cd517e..0000000000 --- a/klibc/klibc/arch/i386/libgcc/__negdi2.S +++ /dev/null @@ -1,21 +0,0 @@ -/* - * arch/i386/libgcc/__negdi2.S - * - * 64-bit negation - */ - - .text - .align 4 - .globl __negdi2 - .type __negdi2,@function -__negdi2: -#ifndef _REGPARM - movl 4(%esp),%eax - movl 8(%esp),%edx -#endif - negl %edx - negl %eax - sbbl $0,%edx - ret - - .size __negdi2,.-__negdi2 diff --git a/klibc/klibc/arch/i386/open.S b/klibc/klibc/arch/i386/open.S deleted file mode 100644 index 54dd6151d1..0000000000 --- a/klibc/klibc/arch/i386/open.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/i386/open.S - * - * Handle the open() system call - oddball due to the varadic - * prototype, which forces the use of the cdecl calling convention, - * and the need for O_LARGEFILE. - */ - -#include - -/* , despite the name, isn't assembly-safe */ -#define O_LARGEFILE 0100000 - - .globl open - .type open,@function - -open: -#ifdef _REGPARM - movl 4(%esp),%eax - movl 8(%esp),%edx - movl 12(%esp),%ecx - orl $O_LARGEFILE,%edx -#else - orl $O_LARGEFILE,8(%esp) -#endif - pushl $__NR_open - jmp __syscall_common - - .size open,.-open diff --git a/klibc/klibc/arch/i386/setjmp.S b/klibc/klibc/arch/i386/setjmp.S deleted file mode 100644 index 2f3033f5bd..0000000000 --- a/klibc/klibc/arch/i386/setjmp.S +++ /dev/null @@ -1,58 +0,0 @@ -# -# arch/i386/setjmp.S -# -# setjmp/longjmp for the i386 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %ebx -# %esp -# %ebp -# %esi -# %edi -# -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: -#ifdef _REGPARM - movl %eax,%edx -#else - movl 4(%esp),%edx -#endif - popl %ecx # Return address, and adjust the stack - xorl %eax,%eax # Return value - movl %ebx,(%edx) - movl %esp,4(%edx) # Post-return %esp! - pushl %ecx # Make the call/return stack happy - movl %ebp,8(%edx) - movl %esi,12(%edx) - movl %edi,16(%edx) - movl %ecx,20(%edx) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: -#ifdef _REGPARM - xchgl %eax,%edx -#else - movl 4(%esp),%edx # jmp_ptr address - movl 8(%esp),%eax # Return value -#endif - movl (%edx),%ebx - movl 4(%edx),%esp - movl 8(%edx),%ebp - movl 12(%edx),%esi - movl 16(%edx),%edi - jmp *20(%edx) - - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/i386/sigreturn.S b/klibc/klibc/arch/i386/sigreturn.S deleted file mode 100644 index f2a32419d3..0000000000 --- a/klibc/klibc/arch/i386/sigreturn.S +++ /dev/null @@ -1,15 +0,0 @@ -# -# arch/i386/sigreturn.S -# - -#include - - .text - .align 4 - .globl __sigreturn - .type __sigreturn,@function -__sigreturn: - pop %eax # Have no idea why this is needed... - movl $__NR_sigreturn,%eax - int $0x80 - .size __sigreturn,.-__sigreturn diff --git a/klibc/klibc/arch/i386/socketcall.S b/klibc/klibc/arch/i386/socketcall.S deleted file mode 100644 index b13d204c32..0000000000 --- a/klibc/klibc/arch/i386/socketcall.S +++ /dev/null @@ -1,42 +0,0 @@ -# -# socketcall.S -# -# On i386, the main (only?) user of socketcall(2), the memory array -# socketcall(2) needs is conveniently already assembled for us on -# the stack. Capitalize on that to make a common socketcall stub. -# - -#include - -#ifdef __i386__ - - .text - .align 4 - .globl __socketcall_common - .type __socketcall_common, @function - -__socketcall_common: - pushl %ebx - - movzbl %al,%ebx # The socketcall number is passed in in %al - leal 8(%esp),%ecx # Argument pointer - movl $__NR_socketcall,%eax - int $0x80 - - cmpl $-4096,%eax # Error return? - - popl %ebx - - jb 1f - - negl %eax - movl %eax,errno - orl $-1,%eax # Return -1 -1: - ret - - .size __socketcall_common,.-__socketcall_common - -#endif - - diff --git a/klibc/klibc/arch/i386/syscall.S b/klibc/klibc/arch/i386/syscall.S deleted file mode 100644 index 0634e8208a..0000000000 --- a/klibc/klibc/arch/i386/syscall.S +++ /dev/null @@ -1,60 +0,0 @@ -/* - * arch/i386/syscall.S - * - * Common tail-handling code for system calls. Because of __syscalldecl - * we are using the stack even on if we are compiling with regparm. - * - * The arguments are on the stack; the system call number in %eax. - */ - -#define ARG(n) (4*n+20)(%esp) - - .text - .align 4 - .globl __syscall_common - .type __syscall_common,@function -__syscall_common: -#ifdef _REGPARM - xchgl %ebx,(%esp) -#else - popl %eax - pushl %ebx -#endif - pushl %esi - pushl %edi - pushl %ebp - -#ifdef _REGPARM - xchgl %eax,%ebx - xchgl %ecx,%edx - movl ARG(0),%esi - movl ARG(1),%edi - movl ARG(2),%ebp -#else - movl ARG(0),%ebx # Syscall arguments - movl ARG(1),%ecx - movl ARG(2),%edx - movl ARG(3),%esi - movl ARG(4),%edi - movl ARG(5),%ebp -#endif - int $0x80 - - cmpl $-4096,%eax - - popl %ebp - popl %edi - popl %esi - popl %ebx - - jb 1f - - # Error return, must set errno - negl %eax - movl %eax,errno - orl $-1,%eax # Return -1 - -1: - ret - - .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/i386/sysstub.ph b/klibc/klibc/arch/i386/sysstub.ph deleted file mode 100644 index e2649e283e..0000000000 --- a/klibc/klibc/arch/i386/sysstub.ph +++ /dev/null @@ -1,32 +0,0 @@ -# -*- perl -*- -# -# arch/i386/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - - if ( $stype eq 'varadic' ) { - print OUT "#ifdef _REGPARM\n"; - print OUT "\tmovl 4(%esp),%eax\n"; - print OUT "\tmovl 8(%esp),%edx\n"; - print OUT "\tmovl 12(%esp),%ecx\n"; - print OUT "#endif\n"; - } - - print OUT "\tpushl \$__NR_${sname}\n"; - print OUT "\tjmp __syscall_common\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/ia64/MCONFIG b/klibc/klibc/arch/ia64/MCONFIG deleted file mode 100644 index 36b30ffb81..0000000000 --- a/klibc/klibc/arch/ia64/MCONFIG +++ /dev/null @@ -1,11 +0,0 @@ -# -*- makefile -*- -# -# arch/ia64/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -BITSIZE = 64 diff --git a/klibc/klibc/arch/ia64/Makefile.inc b/klibc/klibc/arch/ia64/Makefile.inc deleted file mode 100644 index 6363c1f948..0000000000 --- a/klibc/klibc/arch/ia64/Makefile.inc +++ /dev/null @@ -1,26 +0,0 @@ -# -*- makefile -*- -# -# arch/ia64/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/vfork.o \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/pipe.o \ - arch/$(ARCH)/syscall.o \ - libgcc/__divdi3.o \ - libgcc/__divsi3.o \ - libgcc/__udivdi3.o \ - libgcc/__udivsi3.o \ - libgcc/__umodsi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmodsi4.o \ - libgcc/__udivmoddi4.o - -ARCHSOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS)) - -archclean: diff --git a/klibc/klibc/arch/ia64/crt0.S b/klibc/klibc/arch/ia64/crt0.S deleted file mode 100644 index 4b128154e8..0000000000 --- a/klibc/klibc/arch/ia64/crt0.S +++ /dev/null @@ -1,27 +0,0 @@ - -#include - - .align 32 - .global _start - - .proc _start - .type _start,@function -_start: - .prologue - .save rp, r0 - - alloc r2 = ar.pfs,0,0,2,0 - movl r3 = FPSR_DEFAULT - ;; - adds out0= 16,sp /* argc pointer */ - movl gp = @gprel(0f) -0: mov r9 = ip - ;; - sub gp = r9, gp /* back-compute gp value */ - - .body - br.call.sptk.few rp = __libc_init - ;; - break 0 /* break miserably if we ever return */ - - .endp _start diff --git a/klibc/klibc/arch/ia64/pipe.c b/klibc/klibc/arch/ia64/pipe.c deleted file mode 100644 index 87a6981e55..0000000000 --- a/klibc/klibc/arch/ia64/pipe.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * pipe.c - */ - -#include -#include - -#define ASM_CLOBBERS ,"out2", "out3", "out4", "out5", "out6", "out7", \ - /* Non-stacked integer registers, minus r8, r9, r10, r15. */ \ - "r2", "r3", "r11", "r12", "r13", "r14", "r16", "r17", "r18", \ - "r19", "r20", "r21", "r22", "r23", "r24", "r25", "r26", "r27", \ - "r28", "r29", "r30", "r31", \ - /* Predicate registers. */ \ - "p6", "p7", "p8", "p9", "p10", "p11", "p12", "p13", "p14", "p15", \ - /* Non-rotating fp registers. */ \ - "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \ - /* Branch registers. */ \ - "b6", "b7" - -int pipe(int *filedes) -{ - register long _r8 asm("r8"); - register long _r9 asm("r9"); - register long _r10 asm("r10"); - register long _r15 asm("r15") = __NR_pipe; - register long _out0 asm ("out0") = (long)filedes; - long _retval; - __asm __volatile (__IA64_BREAK - : "=r" (_r8), "=r" (_r10), "=r" (_r15), - "=r" (_out0), "=r" (_r9) - : "2" (_r15), "3" (_out0) - : "memory" ASM_CLOBBERS); - if (_r10 == -1) { - errno = _r8; - _retval = -1; - } else { - filedes[0] = _r8; - filedes[1] = _r9; - _retval = 0; - } - return _retval; -} diff --git a/klibc/klibc/arch/ia64/setjmp.S b/klibc/klibc/arch/ia64/setjmp.S deleted file mode 100644 index 7859ba4143..0000000000 --- a/klibc/klibc/arch/ia64/setjmp.S +++ /dev/null @@ -1,343 +0,0 @@ -/* - * IA-64 specific setjmp/longjmp routines - * - * Inspired by setjmp.s from the FreeBSD kernel. - */ - -#define J_UNAT 0 -#define J_NATS 0x8 -#define J_PFS 0x10 -#define J_BSP 0x18 -#define J_RNAT 0x20 -#define J_PREDS 0x28 -#define J_LC 0x30 -#define J_R4 0x38 -#define J_R5 0x40 -#define J_R6 0x48 -#define J_R7 0x50 -#define J_SP 0x58 -#define J_F2 0x60 -#define J_F3 0x70 -#define J_F4 0x80 -#define J_F5 0x90 -#define J_F16 0xa0 -#define J_F17 0xb0 -#define J_F18 0xc0 -#define J_F19 0xd0 -#define J_F20 0xe0 -#define J_F21 0xf0 -#define J_F22 0x100 -#define J_F23 0x110 -#define J_F24 0x120 -#define J_F25 0x130 -#define J_F26 0x140 -#define J_F27 0x150 -#define J_F28 0x160 -#define J_F29 0x170 -#define J_F30 0x180 -#define J_F31 0x190 -#define J_FPSR 0x1a0 -#define J_B0 0x1a8 -#define J_B1 0x1b0 -#define J_B2 0x1b8 -#define J_B3 0x1c0 -#define J_B4 0x1c8 -#define J_B5 0x1d0 -#define J_SIGMASK 0x1d8 -#define J_SIGSET 0x1e0 -#define J_GP 0x1f0 - -// int setjmp(struct jmp_buffer *) -// -// Setup a non-local goto. -// -// Description: -// -// SetJump stores the current register set in the area pointed to -// by "save". It returns zero. Subsequent calls to "LongJump" will -// restore the registers and return non-zero to the same location. -// -// On entry, r32 contains the pointer to the jmp_buffer -// - .align 32 - .global setjmp - .proc setjmp -setjmp: - // - // Make sure buffer is aligned at 16byte boundary - // - add r10 = -0x10,r0 ;; // mask the lower 4 bits - and r32 = r32, r10;; - add r32 = 0x10, r32;; // move to next 16 byte boundary - - add r10 = J_PREDS, r32 // skip Unats & pfs save area - add r11 = J_BSP, r32 - // - // save immediate context - // - mov r2 = ar.bsp // save backing store pointer - mov r3 = pr // save predicates - flushrs - ;; - // - // save user Unat register - // - mov r16 = ar.lc // save loop count register - mov r14 = ar.unat // save user Unat register - - st8 [r10] = r3, J_LC-J_PREDS - st8 [r11] = r2, J_R4-J_BSP - ;; - st8 [r10] = r16, J_R5-J_LC - st8 [r32] = r14, J_NATS // Note: Unat at the - // beginning of the save area - mov r15 = ar.pfs - ;; - // - // save preserved general registers & NaT's - // - st8.spill [r11] = r4, J_R6-J_R4 - ;; - st8.spill [r10] = r5, J_R7-J_R5 - ;; - st8.spill [r11] = r6, J_SP-J_R6 - ;; - st8.spill [r10] = r7, J_F3-J_R7 - ;; - st8.spill [r11] = sp, J_F2-J_SP - ;; - // - // save spilled Unat and pfs registers - // - mov r2 = ar.unat // save Unat register after spill - ;; - st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs - ;; - st8 [r32] = r15 // save pfs - // - // save floating registers - // - stf.spill [r11] = f2, J_F4-J_F2 - stf.spill [r10] = f3, J_F5-J_F3 - ;; - stf.spill [r11] = f4, J_F16-J_F4 - stf.spill [r10] = f5, J_F17-J_F5 - ;; - stf.spill [r11] = f16, J_F18-J_F16 - stf.spill [r10] = f17, J_F19-J_F17 - ;; - stf.spill [r11] = f18, J_F20-J_F18 - stf.spill [r10] = f19, J_F21-J_F19 - ;; - stf.spill [r11] = f20, J_F22-J_F20 - stf.spill [r10] = f21, J_F23-J_F21 - ;; - stf.spill [r11] = f22, J_F24-J_F22 - stf.spill [r10] = f23, J_F25-J_F23 - ;; - stf.spill [r11] = f24, J_F26-J_F24 - stf.spill [r10] = f25, J_F27-J_F25 - ;; - stf.spill [r11] = f26, J_F28-J_F26 - stf.spill [r10] = f27, J_F29-J_F27 - ;; - stf.spill [r11] = f28, J_F30-J_F28 - stf.spill [r10] = f29, J_F31-J_F29 - ;; - stf.spill [r11] = f30, J_FPSR-J_F30 - stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr - // - // save FPSR register & branch registers - // - mov r2 = ar.fpsr // save fpsr register - mov r3 = b0 - ;; - st8 [r11] = r2, J_B1-J_FPSR - st8 [r10] = r3, J_B2-J_B0 - mov r2 = b1 - mov r3 = b2 - ;; - st8 [r11] = r2, J_B3-J_B1 - st8 [r10] = r3, J_B4-J_B2 - mov r2 = b3 - mov r3 = b4 - ;; - st8 [r11] = r2, J_B5-J_B3 - st8 [r10] = r3 - mov r2 = b5 - ;; - st8 [r11] = r2 - ;; - // - // return - // - mov r8 = r0 // return 0 from setjmp - mov ar.unat = r14 // restore unat - br.ret.sptk b0 - .endp setjmp - -// -// void longjmp(struct jmp_buffer *, int val) -// -// Perform a non-local goto. -// -// Description: -// -// LongJump initializes the register set to the values saved by a -// previous 'SetJump' and jumps to the return location saved by that -// 'SetJump'. This has the effect of unwinding the stack and returning -// for a second time to the 'SetJump'. -// - - .align 32 - .global longjmp - .proc longjmp -longjmp: - // - // Make sure buffer is aligned at 16byte boundary - // - add r10 = -0x10,r0 ;; // mask the lower 4 bits - and r32 = r32, r10;; - add r32 = 0x10, r32;; // move to next 16 byte boundary - - // - // caching the return value as we do invala in the end - // - mov r8 = r33 // return value - - // - // get immediate context - // - mov r14 = ar.rsc // get user RSC conf - add r10 = J_PFS, r32 // get address of pfs - add r11 = J_NATS, r32 - ;; - ld8 r15 = [r10], J_BSP-J_PFS // get pfs - ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs - ;; - mov ar.unat = r2 - ;; - ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer - mov ar.rsc = r0 // put RSE in enforced lazy - mov ar.pfs = r15 - ;; - - // - // while returning from longjmp the BSPSTORE and BSP needs to be - // same and discard all the registers allocated after we did - // setjmp. Also, we need to generate the RNAT register since we - // did not flushed the RSE on setjmp. - // - mov r17 = ar.bspstore // get current BSPSTORE - ;; - cmp.ltu p6,p7 = r17, r16 // is it less than BSP of -(p6) br.spnt.few .flush_rse - mov r19 = ar.rnat // get current RNAT - ;; - loadrs // invalidate dirty regs - br.sptk.many .restore_rnat // restore RNAT - -.flush_rse: - flushrs - ;; - mov r19 = ar.rnat // get current RNAT - mov r17 = r16 // current BSPSTORE - ;; -.restore_rnat: - // - // check if RNAT is saved between saved BSP and curr BSPSTORE - // - mov r18 = 0x3f - ;; - dep r18 = r18,r16,3,6 // get RNAT address - ;; - cmp.ltu p8,p9 = r18, r17 // RNAT saved on RSE - ;; -(p8) ld8 r19 = [r18] // get RNAT from RSE - ;; - mov ar.bspstore = r16 // set new BSPSTORE - ;; - mov ar.rnat = r19 // restore RNAT - mov ar.rsc = r14 // restore RSC conf - - - ld8 r3 = [r11], J_R4-J_LC // get lc register - ld8 r2 = [r10], J_R5-J_PREDS // get predicates - ;; - mov pr = r2, -1 - mov ar.lc = r3 - // - // restore preserved general registers & NaT's - // - ld8.fill r4 = [r11], J_R6-J_R4 - ;; - ld8.fill r5 = [r10], J_R7-J_R5 - ld8.fill r6 = [r11], J_SP-J_R6 - ;; - ld8.fill r7 = [r10], J_F2-J_R7 - ld8.fill sp = [r11], J_F3-J_SP - ;; - // - // restore floating registers - // - ldf.fill f2 = [r10], J_F4-J_F2 - ldf.fill f3 = [r11], J_F5-J_F3 - ;; - ldf.fill f4 = [r10], J_F16-J_F4 - ldf.fill f5 = [r11], J_F17-J_F5 - ;; - ldf.fill f16 = [r10], J_F18-J_F16 - ldf.fill f17 = [r11], J_F19-J_F17 - ;; - ldf.fill f18 = [r10], J_F20-J_F18 - ldf.fill f19 = [r11], J_F21-J_F19 - ;; - ldf.fill f20 = [r10], J_F22-J_F20 - ldf.fill f21 = [r11], J_F23-J_F21 - ;; - ldf.fill f22 = [r10], J_F24-J_F22 - ldf.fill f23 = [r11], J_F25-J_F23 - ;; - ldf.fill f24 = [r10], J_F26-J_F24 - ldf.fill f25 = [r11], J_F27-J_F25 - ;; - ldf.fill f26 = [r10], J_F28-J_F26 - ldf.fill f27 = [r11], J_F29-J_F27 - ;; - ldf.fill f28 = [r10], J_F30-J_F28 - ldf.fill f29 = [r11], J_F31-J_F29 - ;; - ldf.fill f30 = [r10], J_FPSR-J_F30 - ldf.fill f31 = [r11], J_B0-J_F31 ;; - - // - // restore branch registers and fpsr - // - ld8 r16 = [r10], J_B1-J_FPSR // get fpsr - ld8 r17 = [r11], J_B2-J_B0 // get return pointer - ;; - mov ar.fpsr = r16 - mov b0 = r17 - ld8 r2 = [r10], J_B3-J_B1 - ld8 r3 = [r11], J_B4-J_B2 - ;; - mov b1 = r2 - mov b2 = r3 - ld8 r2 = [r10], J_B5-J_B3 - ld8 r3 = [r11] - ;; - mov b3 = r2 - mov b4 = r3 - ld8 r2 = [r10] - ld8 r21 = [r32] // get user unat - ;; - mov b5 = r2 - mov ar.unat = r21 - - // - // invalidate ALAT - // - invala ;; - - br.ret.sptk b0 - .endp longjmp diff --git a/klibc/klibc/arch/ia64/syscall.S b/klibc/klibc/arch/ia64/syscall.S deleted file mode 100644 index e3f264c0e4..0000000000 --- a/klibc/klibc/arch/ia64/syscall.S +++ /dev/null @@ -1,20 +0,0 @@ -# -# arch/ia64/syscall.S -# - -#include - - .text - .align 32 - .proc __syscall_error - .globl __syscall_error -__syscall_error: - addl r2 = @ltoffx(errno),gp - ;; - ld8.mov r3 = [r2],errno - ;; - st4 [r3] = r8 - mov r8 = -1 - br.ret.sptk.many b0 - .size __syscall_error, .-__syscall_error - .endp __syscall_error diff --git a/klibc/klibc/arch/ia64/sysstub.ph b/klibc/klibc/arch/ia64/sysstub.ph deleted file mode 100644 index 8e686c68a3..0000000000 --- a/klibc/klibc/arch/ia64/sysstub.ph +++ /dev/null @@ -1,29 +0,0 @@ -# -*- perl -*- -# -# arch/ia64/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.text\n"; - print OUT "\t.align 32\n"; - print OUT "\t.proc ${fname}\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT "\tmov\tr15 = __NR_${sname}\n"; - print OUT "\tbreak __BREAK_SYSCALL\n"; - print OUT "\tcmp.eq p6,p0 = -1,r10\n"; - print OUT "(p6)\tbr.few __syscall_error\n"; - print OUT "\tbr.ret.sptk.many b0\n"; - print OUT "\t.size\t${fname},.-${fname}\n"; - print OUT "\t.endp\t${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/ia64/vfork.S b/klibc/klibc/arch/ia64/vfork.S deleted file mode 100644 index f79bdc8234..0000000000 --- a/klibc/klibc/arch/ia64/vfork.S +++ /dev/null @@ -1,42 +0,0 @@ -/* - * ia64 specific vfork syscall - * - * Written By: Martin Hicks - * - */ - -/* This syscall is a special case of the clone syscall */ -#include -#include -#include - -/* These are redefined here because linux/sched.h isn't safe for - * inclusion in asm. - */ -#define CLONE_VM 0x00000100 /* set if VM shared between processes */ -#define CLONE_VFORK 0x00004000 /* set if parent wants the child to wake it up on exit */ - -/* pid_t vfork(void) */ -/* Implemented as clone(CLONE_VFORK | CLONE_VM | SIGCHLD, 0) */ - - .align 32 - .proc vfork - .global vfork -vfork: - alloc r2=ar.pfs,0,0,2,0 - mov r15=__NR_clone - mov out0=CLONE_VM|CLONE_VFORK|SIGCHLD - mov out1=0 - ;; - break 0x100000 // Do the syscall - ;; - addl r15=0,r1 - cmp.eq p7,p6 = -1,r10 - ;; - ld8 r14=[r15] - ;; -(p7) st4 [r14]=r8 - ;; -(p7) mov r8=-1 - br.ret.sptk.many b0 - .endp vfork diff --git a/klibc/klibc/arch/m32r/MCONFIG b/klibc/klibc/arch/m32r/MCONFIG deleted file mode 100644 index 2673090fce..0000000000 --- a/klibc/klibc/arch/m32r/MCONFIG +++ /dev/null @@ -1,18 +0,0 @@ -# -*- makefile -*- -# -# arch/m32r/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -BITSIZE = 32 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 224 MB - normal binaries start at 0 (?) -# (lib?)gcc on cris seems to insist on producing .init and .fini sections -SHAREDFLAGS = --section-start .init=0x0e000100 diff --git a/klibc/klibc/arch/m32r/Makefile.inc b/klibc/klibc/arch/m32r/Makefile.inc deleted file mode 100644 index 43cb44ef8f..0000000000 --- a/klibc/klibc/arch/m32r/Makefile.inc +++ /dev/null @@ -1,19 +0,0 @@ -# -*- makefile -*- -# -# arch/m32r/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o - -archclean: diff --git a/klibc/klibc/arch/m32r/crt0.S b/klibc/klibc/arch/m32r/crt0.S deleted file mode 100644 index 1589a774a2..0000000000 --- a/klibc/klibc/arch/m32r/crt0.S +++ /dev/null @@ -1,25 +0,0 @@ -# -# arch/m32r/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - - .text - .balign 4 - .type _start,@function - .globl _start -_start: - /* Save the address of the ELF argument array */ - mv r0, sp - - /* atexit() function (assume null) */ - xor r1, r1 - - bl __libc_init - - .size _start, .-_start - diff --git a/klibc/klibc/arch/m32r/setjmp.S b/klibc/klibc/arch/m32r/setjmp.S deleted file mode 100644 index 14ef7e3577..0000000000 --- a/klibc/klibc/arch/m32r/setjmp.S +++ /dev/null @@ -1,47 +0,0 @@ -# -# arch/m32r/setjmp.S -# -# setjmp/longjmp for the M32R architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# r8-r15 -# -# Note that r14 is the return address register and -# r15 is the stack pointer. -# - - .text - .balign 4 - .globl setjmp - .type setjmp, @function -setjmp: - st r8, @r0 - st r9, @+r0 - st r10, @+r0 - st r11, @+r0 - st r12, @+r0 - st r13, @+r0 - st r14, @+r0 - st r15, @+r0 - xor r0, r0 - jmp r14 - .size setjmp,.-setjmp - - .text - .balign 4 - .globl longjmp - .type longjmp, @function -longjmp: - ld r8, @r0+ - ld r9, @r0+ - ld r10, @r0+ - ld r11, @r0+ - ld r12, @r0+ - ld r13, @r0+ - ld r14, @r0+ - ld r15, @r0 - mv r0, r1 - jmp r14 - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/m32r/syscall.S b/klibc/klibc/arch/m32r/syscall.S deleted file mode 100644 index a20a33667f..0000000000 --- a/klibc/klibc/arch/m32r/syscall.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/m32r/syscall.S - * - * r7 contains the syscall number (set by stub); - * r0..r3 contains arguments 0-3 per standard calling convention; - * r4..r5 contains arguments 4-5, but we have to get those from - * the stack. - */ - - .section ".text","ax" - .balign 4 - .globl __syscall_common - .type __syscall_common,@function -__syscall_common: - ld r4,@sp - ld r5,@(4,sp) - trap #2 - cmpi r0, #-4096 - bnc 1f - jmp r14 -1: - seth r2,#high(errno) - or3 r2,r2,#low(errno) - neg r1,r0 - st r1,@r7 - ldi r0,#-1 - jmp r14 - - .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/m32r/sysstub.ph b/klibc/klibc/arch/m32r/sysstub.ph deleted file mode 100644 index 98dfb9d0a8..0000000000 --- a/klibc/klibc/arch/m32r/sysstub.ph +++ /dev/null @@ -1,25 +0,0 @@ -# -*- perl -*- -# -# arch/m32r/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.text\n"; - print OUT "\t.type\t${fname},\@function\n"; - print OUT "\t.globl\t${fname}\n"; - print OUT "\t.balign\t4\n"; - print OUT "${fname}:\n"; - print OUT "\tldi\tr7,#__NR_${sname}\n"; - print OUT "\tbra\t__syscall_common\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/m68k/MCONFIG b/klibc/klibc/arch/m68k/MCONFIG deleted file mode 100644 index 2ba69b3178..0000000000 --- a/klibc/klibc/arch/m68k/MCONFIG +++ /dev/null @@ -1,11 +0,0 @@ -# -*- makefile -*- -# -# arch/m68k/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -fomit-frame-pointer -BITSIZE = 32 diff --git a/klibc/klibc/arch/m68k/Makefile.inc b/klibc/klibc/arch/m68k/Makefile.inc deleted file mode 100644 index 9abec14db1..0000000000 --- a/klibc/klibc/arch/m68k/Makefile.inc +++ /dev/null @@ -1,10 +0,0 @@ -# -*- makefile -*- -# -# arch/m68k/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -archclean: diff --git a/klibc/klibc/arch/mips/MCONFIG b/klibc/klibc/arch/mips/MCONFIG deleted file mode 100644 index 0a98918987..0000000000 --- a/klibc/klibc/arch/mips/MCONFIG +++ /dev/null @@ -1,15 +0,0 @@ -# -*- makefile -*- -# -# arch/mips/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHREQFLAGS = -fno-pic -mno-abicalls -G 0 -OPTFLAGS = -Os -BITSIZE = 32 - -# Extra linkflags when building the shared version of the library -SHAREDFLAGS = -T arch/$(ARCH)/klibc.ld diff --git a/klibc/klibc/arch/mips/Makefile.inc b/klibc/klibc/arch/mips/Makefile.inc deleted file mode 100644 index e257023f34..0000000000 --- a/klibc/klibc/arch/mips/Makefile.inc +++ /dev/null @@ -1,25 +0,0 @@ -# -*- makefile -*- -# -# arch/mips/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/pipe.o \ - arch/$(ARCH)/vfork.o \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o - - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - - -archclean: diff --git a/klibc/klibc/arch/mips/crt0.S b/klibc/klibc/arch/mips/crt0.S deleted file mode 100644 index 42d9dd5e38..0000000000 --- a/klibc/klibc/arch/mips/crt0.S +++ /dev/null @@ -1,25 +0,0 @@ -# -# arch/mips/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - -#include - -NESTED(__start, 32, sp) - subu sp, 32 - sw zero, 16(sp) - - lui gp, %hi(_gp) # Initialize gp - addiu gp, gp, _gp - - addiu a0, sp, 32 # Pointer to ELF entry structure - move a1, v0 # Kernel-provided atexit() pointer - - jal __libc_init - - END(__start) diff --git a/klibc/klibc/arch/mips/klibc.ld b/klibc/klibc/arch/mips/klibc.ld deleted file mode 100644 index d75c9de70c..0000000000 --- a/klibc/klibc/arch/mips/klibc.ld +++ /dev/null @@ -1,217 +0,0 @@ -/* Linker script for klibc.so, needed because of the the damned - GNU ld script headers problem */ - -OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", - "elf32-tradlittlemips") -OUTPUT_ARCH(mips) -ENTRY(__start) -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - /* This address needs to be reachable using normal inter-module - calls, and work on the memory models for this architecture */ - /* 2 MB -- the normal starting point for text is 4 MB */ - . = 0x00200400; - .interp : { *(.interp) } - .reginfo : { *(.reginfo) } - .dynamic : { *(.dynamic) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .gnu.version : { *(.gnu.version) } - .gnu.version_d : { *(.gnu.version_d) } - .gnu.version_r : { *(.gnu.version_r) } - .rel.dyn : - { - *(.rel.init) - *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) - *(.rel.fini) - *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) - *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) - *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) - *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) - *(.rel.ctors) - *(.rel.dtors) - *(.rel.got) - *(.rel.sdata .rel.sdata.* .rel.gnu.linkonce.s.*) - *(.rel.sbss .rel.sbss.* .rel.gnu.linkonce.sb.*) - *(.rel.sdata2 .rel.sdata2.* .rel.gnu.linkonce.s2.*) - *(.rel.sbss2 .rel.sbss2.* .rel.gnu.linkonce.sb2.*) - *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) - } - .rela.dyn : - { - *(.rela.init) - *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) - *(.rela.fini) - *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) - *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) - *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) - *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) - *(.rela.ctors) - *(.rela.dtors) - *(.rela.got) - *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) - *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) - *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) - *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) - *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) - } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : - { - KEEP (*(.init)) - } =0 - .plt : { *(.plt) } - .text : - { - _ftext = . ; - *(.text .stub .text.* .gnu.linkonce.t.*) - /* .gnu.warning sections are handled specially by elf32.em. */ - *(.gnu.warning) - *(.mips16.fn.*) *(.mips16.call.*) - } =0 - .fini : - { - KEEP (*(.fini)) - } =0 - PROVIDE (__etext = .); - PROVIDE (_etext = .); - PROVIDE (etext = .); - .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } - .rodata1 : { *(.rodata1) } - .sdata2 : { *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) } - .sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) } - .eh_frame_hdr : { *(.eh_frame_hdr) } - /* Adjust the address for the data segment. We want to adjust up to - the same address within the page on the next page up. */ - . = ALIGN(8192); - /* Ensure the __preinit_array_start label is properly aligned. We - could instead move the label definition inside the section, but - the linker would then create the section even if it turns out to - be empty, which isn't pretty. */ - . = ALIGN(32 / 8); - PROVIDE (__preinit_array_start = .); - .preinit_array : { *(.preinit_array) } - PROVIDE (__preinit_array_end = .); - PROVIDE (__init_array_start = .); - .init_array : { *(.init_array) } - PROVIDE (__init_array_end = .); - PROVIDE (__fini_array_start = .); - .fini_array : { *(.fini_array) } - PROVIDE (__fini_array_end = .); - .data : - { - _fdata = . ; - *(.data .data.* .gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } - .data1 : { *(.data1) } - .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } - .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } - .eh_frame : { KEEP (*(.eh_frame)) } - .gcc_except_table : { *(.gcc_except_table) } - .ctors : - { - /* gcc uses crtbegin.o to find the start of - the constructors, so we make sure it is - first. Because this is a wildcard, it - doesn't matter if the user does not - actually link against crtbegin.o; the - linker won't look for a file to match a - wildcard. The wildcard also means that it - doesn't matter which directory crtbegin.o - is in. */ - KEEP (*crtbegin*.o(.ctors)) - /* We don't want to include the .ctor section from - from the crtend.o file until after the sorted ctors. - The .ctor section from the crtend file contains the - end of ctors marker and it must be last */ - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } - .dtors : - { - KEEP (*crtbegin*.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } - .jcr : { KEEP (*(.jcr)) } - _gp = ALIGN(16) + 0x7ff0; - .got : { *(.got.plt) *(.got) } - /* We want the small data sections together, so single-instruction offsets - can access them all, and initialized data all before uninitialized, so - we can shorten the on-disk segment size. */ - .sdata : - { - *(.sdata .sdata.* .gnu.linkonce.s.*) - } - .lit8 : { *(.lit8) } - .lit4 : { *(.lit4) } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - _fbss = .; - .sbss : - { - PROVIDE (__sbss_start = .); - PROVIDE (___sbss_start = .); - *(.dynsbss) - *(.sbss .sbss.* .gnu.linkonce.sb.*) - *(.scommon) - PROVIDE (__sbss_end = .); - PROVIDE (___sbss_end = .); - } - .bss : - { - *(.dynbss) - *(.bss .bss.* .gnu.linkonce.b.*) - *(COMMON) - /* Align here to ensure that the .bss section occupies space up to - _end. Align after .bss to ensure correct alignment even if the - .bss section disappears because there are no input sections. */ - . = ALIGN(32 / 8); - } - . = ALIGN(32 / 8); - _end = .; - PROVIDE (end = .); - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - Symbols in the DWARF debugging sections are relative to the beginning - of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } - .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } - .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } - /DISCARD/ : { *(.note.GNU-stack) } -} diff --git a/klibc/klibc/arch/mips/pipe.S b/klibc/klibc/arch/mips/pipe.S deleted file mode 100644 index d79f614025..0000000000 --- a/klibc/klibc/arch/mips/pipe.S +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include - -LEAF(pipe) - li v0, __NR_pipe - syscall - bnez a3, 1f - sw v0, (a0) - sw v1, (a1) - li v0, 0 - b 2f -1: sw v0, errno - li v0, -1 -2: jr ra - END(pipe) diff --git a/klibc/klibc/arch/mips/setjmp.S b/klibc/klibc/arch/mips/setjmp.S deleted file mode 100644 index 4d293757ec..0000000000 --- a/klibc/klibc/arch/mips/setjmp.S +++ /dev/null @@ -1,82 +0,0 @@ -# -# arch/mips/setjmp.S -# -# setjmp/longjmp for the MIPS architecture -# -# The jmp_buf is assumed to contain the following, in order: -# s0..s7 -# gp -# sp -# s8 -# ra -# f20..f31 -# fcr31 -# - -#include - -LEAF(setjmp) - sw s0, 0(a0) - sw s1, 4(a0) - sw s2, 8(a0) - sw s3, 12(a0) - sw s4, 16(a0) - sw s5, 20(a0) - sw s6, 24(a0) - sw s7, 28(a0) - sw gp, 32(a0) - sw sp, 36(a0) - sw s8, 40(a0) - sw ra, 44(a0) - cfc1 t0,$31 - swc1 $f20,48(a0) - swc1 $f21,52(a0) - swc1 $f22,56(a0) - swc1 $f23,60(a0) - swc1 $f24,64(a0) - swc1 $f25,68(a0) - swc1 $f26,72(a0) - swc1 $f27,76(a0) - swc1 $f28,80(a0) - swc1 $f29,84(a0) - swc1 $f30,88(a0) - swc1 $f31,92(a0) - sw t0,96(a0) - move v0,zero - jr ra - - END(setjmp) - -LEAF(longjmp) - lw s0, 0(a0) - lw s1, 4(a0) - lw s2, 8(a0) - lw s3, 12(a0) - lw s4, 16(a0) - lw s5, 20(a0) - lw s6, 24(a0) - lw s7, 28(a0) - lw gp, 32(a0) - lw sp, 36(a0) - lw s8, 40(a0) - lw ra, 44(a0) - lw t0, 96(a0) - lwc1 $f20,48(a0) - lwc1 $f21,52(a0) - lwc1 $f22,56(a0) - lwc1 $f23,60(a0) - lwc1 $f24,64(a0) - lwc1 $f25,68(a0) - lwc1 $f26,72(a0) - lwc1 $f27,76(a0) - lwc1 $f28,80(a0) - lwc1 $f29,84(a0) - lwc1 $f30,88(a0) - lwc1 $f31,92(a0) - ctc1 t0,$31 - move v0,a1 - jr ra - - END(longjmp) - - \ No newline at end of file diff --git a/klibc/klibc/arch/mips/syscall.S b/klibc/klibc/arch/mips/syscall.S deleted file mode 100644 index d5c1fe1c7d..0000000000 --- a/klibc/klibc/arch/mips/syscall.S +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include -#include - - .set noreorder - -LEAF(__syscall_common) - syscall - beqz a3, 1f - # sw is actually two instructions; the first one goes - # in the branch delay slot - sw v0, errno - li v0, -1 -1: jr ra - END(__syscall_common) diff --git a/klibc/klibc/arch/mips/sysstub.ph b/klibc/klibc/arch/mips/sysstub.ph deleted file mode 100644 index a71d5d02ef..0000000000 --- a/klibc/klibc/arch/mips/sysstub.ph +++ /dev/null @@ -1,30 +0,0 @@ -# -*- perl -*- -# -# arch/mips/sysstub.ph -# -# Script to generate system call stubs -# - -# On MIPS, most system calls follow the standard convention, with the -# system call number in r0 (v0), return an error value in r19 (a3) as -# well as the return value in r0 (v0). - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - $stype = $stype || 'common'; - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "#include \n"; - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.set noreorder\n"; - print OUT "\n"; - print OUT "LEAF(${fname})\n"; - print OUT "\tj\t__syscall_${stype}\n"; - print OUT "\t li\tv0, __NR_${sname}\n"; - print OUT "\tEND(${fname})\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/mips/vfork.S b/klibc/klibc/arch/mips/vfork.S deleted file mode 100644 index 9829867fab..0000000000 --- a/klibc/klibc/arch/mips/vfork.S +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include -#include - -#define CLONE_VM 0x00000100 -#define CLONE_VFORK 0x00004000 -#define SIGCHLD 18 - - .set noreorder - -LEAF(vfork) - li a0, CLONE_VFORK | CLONE_VM | SIGCHLD - li a1, 0 - j __syscall_common - li v0, __NR_clone - END(vfork) diff --git a/klibc/klibc/arch/mips64/MCONFIG b/klibc/klibc/arch/mips64/MCONFIG deleted file mode 100644 index 66405e4373..0000000000 --- a/klibc/klibc/arch/mips64/MCONFIG +++ /dev/null @@ -1,11 +0,0 @@ -# -*- makefile -*- -# -# arch/mips64/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -BITSIZE = 64 diff --git a/klibc/klibc/arch/mips64/Makefile.inc b/klibc/klibc/arch/mips64/Makefile.inc deleted file mode 100644 index 4a9529adca..0000000000 --- a/klibc/klibc/arch/mips64/Makefile.inc +++ /dev/null @@ -1,10 +0,0 @@ -# -*- makefile -*- -# -# arch/mips64/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -archclean: diff --git a/klibc/klibc/arch/parisc/MCONFIG b/klibc/klibc/arch/parisc/MCONFIG deleted file mode 100644 index 93a31707c6..0000000000 --- a/klibc/klibc/arch/parisc/MCONFIG +++ /dev/null @@ -1,11 +0,0 @@ -# -*- makefile -*- -# -# arch/parisc/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -fomit-frame-pointer -BITSIZE = 32 diff --git a/klibc/klibc/arch/parisc/Makefile.inc b/klibc/klibc/arch/parisc/Makefile.inc deleted file mode 100644 index 980a543ed2..0000000000 --- a/klibc/klibc/arch/parisc/Makefile.inc +++ /dev/null @@ -1,19 +0,0 @@ -# -*- makefile -*- -# -# arch/parisc/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o - -ARCHOOBJS = $(patsubst %o,%.lo,%(ARCHOBJS)) - -archclean: - -arch/$(ARCH)/syscall.o: arch/$(ARCH)/syscall.c - $(CC) $(CFLAGS) -ffixed-r20 -c -o $@ $< diff --git a/klibc/klibc/arch/parisc/crt0.S b/klibc/klibc/arch/parisc/crt0.S deleted file mode 100644 index fb0bd373ee..0000000000 --- a/klibc/klibc/arch/parisc/crt0.S +++ /dev/null @@ -1,34 +0,0 @@ - .align 4 - - .import $global$, data - .import __libc_init, code - - .global _start - .export _start, ENTRY - .type _start,@function - - .proc - .callinfo - -_start: -/* extend the stack by 64-bytes */ - ldo 64(%sp), %sp - -/* %r25 = argc - * %r24 = argv - * envp = argv + (argc + 1) - * elfdata = (argv - 4) - */ - ldo -4(%r24), %r26 - -/* load global data */ - ldil L%$global$, %dp - ldo R%$global$(%dp), %dp - -/* branch to __libc_init */ - bl __libc_init,%r2 - nop -/* break miserably if we ever return */ - iitlbp %r0,(%r0) /* illegal instruction */ - nop - .procend diff --git a/klibc/klibc/arch/parisc/setjmp.S b/klibc/klibc/arch/parisc/setjmp.S deleted file mode 100644 index aebe03a5ed..0000000000 --- a/klibc/klibc/arch/parisc/setjmp.S +++ /dev/null @@ -1,88 +0,0 @@ -/* - * parisc specific setjmp/longjmp routines - * - */ - - .text - .align 4 - .global setjmp - .export setjmp, code - .proc - .callinfo -setjmp: - stw %r3,0(%r26) - stw %r4,8(%r26) - stw %r5,12(%r26) - stw %r6,16(%r26) - stw %r7,20(%r26) - stw %r8,24(%r26) - stw %r9,28(%r26) - stw %r10,32(%r26) - stw %r11,36(%r26) - stw %r12,40(%r26) - stw %r13,44(%r26) - stw %r14,48(%r26) - stw %r15,52(%r26) - stw %r16,56(%r26) - stw %r17,60(%r26) - stw %r18,64(%r26) - stw %r19,68(%r26) - stw %r27,72(%r26) - stw %r30,76(%r26) - stw %rp,80(%r26) - ldo 88(%r26),%r19 - fstd,ma %fr12,8(%r19) - fstd,ma %fr13,8(%r19) - fstd,ma %fr14,8(%r19) - fstd,ma %fr15,8(%r19) - fstd,ma %fr16,8(%r19) - fstd,ma %fr17,8(%r19) - fstd,ma %fr18,8(%r19) - fstd,ma %fr19,8(%r19) - fstd,ma %fr20,8(%r19) - fstd %fr21,0(%r19) - bv %r0(%rp) - copy %r0,%r28 - .procend - - .text - .align 4 - .global longjmp - .export longjmp, code - .proc - .callinfo -longjmp: - ldw 0(%r26),%r3 - ldw 8(%r26),%r4 - ldw 12(%r26),%r5 - ldw 16(%r26),%r6 - ldw 20(%r26),%r7 - ldw 24(%r26),%r8 - ldw 28(%r26),%r9 - ldw 32(%r26),%r10 - ldw 36(%r26),%r11 - ldw 40(%r26),%r12 - ldw 44(%r26),%r13 - ldw 48(%r26),%r14 - ldw 52(%r26),%r15 - ldw 56(%r26),%r16 - ldw 60(%r26),%r17 - ldw 64(%r26),%r18 - ldw 68(%r26),%r19 - ldw 72(%r26),%r27 - ldw 76(%r26),%r30 - ldw 80(%r26),%rp - ldo 88(%r26),%r20 - fldd,ma 8(%r20),%fr12 - fldd,ma 8(%r20),%fr13 - fldd,ma 8(%r20),%fr14 - fldd,ma 8(%r20),%fr15 - fldd,ma 8(%r20),%fr16 - fldd,ma 8(%r20),%fr17 - fldd,ma 8(%r20),%fr18 - fldd,ma 8(%r20),%fr19 - fldd,ma 8(%r20),%fr20 - fldd 0(%r20),%fr21 - bv %r0(%rp) - copy %r25,%r28 - .procend diff --git a/klibc/klibc/arch/parisc/syscall.c b/klibc/klibc/arch/parisc/syscall.c deleted file mode 100644 index 99ef5fe103..0000000000 --- a/klibc/klibc/arch/parisc/syscall.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/parisc/syscall.c - * - * This function is called from a stub with %r20 already set up. - * Compile this function with -ffixed-r20 so that it doesn't clobber - * this register by mistake. - */ - -#include -#include - -long __syscall_common(long a0, long a1, long a2, long a3, long a4, long a5) -{ - register unsigned long rv asm ("r28"); - - asm volatile("\tble 0x100(%%sr2, %%r0)\n" - : "=r" (rv) - : "r" (a0), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5) - : "%r1", "%r2", "%r29", "%r31"); - - if ( __unlikely(rv >= -4095UL) ) { - errno = -rv; - return -1L; - } else { - return (long)rv; - } -} - - diff --git a/klibc/klibc/arch/parisc/sysstub.ph b/klibc/klibc/arch/parisc/sysstub.ph deleted file mode 100644 index e2196acaf3..0000000000 --- a/klibc/klibc/arch/parisc/sysstub.ph +++ /dev/null @@ -1,28 +0,0 @@ -# -*- perl -*- -# -# arch/parisc/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.text\n"; - print OUT "\t.align 4\n"; - print OUT "\t.import __syscall_common, code\n"; - print OUT "\t.global ${fname}\n"; - print OUT "\t.export ${fname}, code\n"; - print OUT "\t.proc\n"; - print OUT "\.callinfo\n"; - print OUT "${fname}:\n"; - print OUT "\tb\t__syscall_common\n"; - print OUT "\t ldo\t__NR_${sname}(%r0),%r20\n"; - print OUT "\t.procend\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/ppc/MCONFIG b/klibc/klibc/arch/ppc/MCONFIG deleted file mode 100644 index 82c7107013..0000000000 --- a/klibc/klibc/arch/ppc/MCONFIG +++ /dev/null @@ -1,18 +0,0 @@ -# -*- makefile -*- -# -# arch/ppc/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -BITSIZE = 32 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 256-16 MB - normal binaries start at 256 MB, and jumps are limited -# to +/- 16 MB -SHAREDFLAGS = -Ttext 0x0f000200 diff --git a/klibc/klibc/arch/ppc/Makefile.inc b/klibc/klibc/arch/ppc/Makefile.inc deleted file mode 100644 index c6bb975f0f..0000000000 --- a/klibc/klibc/arch/ppc/Makefile.inc +++ /dev/null @@ -1,22 +0,0 @@ -# -*- makefile -*- -# -# arch/ppc/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o - - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - -archclean: diff --git a/klibc/klibc/arch/ppc/crt0.S b/klibc/klibc/arch/ppc/crt0.S deleted file mode 100644 index 282f8411e4..0000000000 --- a/klibc/klibc/arch/ppc/crt0.S +++ /dev/null @@ -1,20 +0,0 @@ -# -# arch/ppc/crt0.S -# - - .text - .align 4 - .type _start,@function - .globl _start -_start: - stwu 1,-16(1) - addi 3,1,16 - /* - * the SVR4abippc.pdf specifies r7 as a pointer to - * a termination function pointer. - * It is unused on Linux. - */ - mr 4,7 - bl __libc_init - - .size _start,.-_start diff --git a/klibc/klibc/arch/ppc/setjmp.S b/klibc/klibc/arch/ppc/setjmp.S deleted file mode 100644 index 3012de3ea6..0000000000 --- a/klibc/klibc/arch/ppc/setjmp.S +++ /dev/null @@ -1,35 +0,0 @@ -# -# arch/ppc/setjmp.S -# -# Basic setjmp/longjmp implementation -# This file was derived from the equivalent file in NetBSD -# - - .text - .align 4 - .type setjmp,@function - .globl setjmp -setjmp: - mflr %r11 /* save return address */ - mfcr %r12 /* save condition register */ - mr %r10,%r1 /* save stack pointer */ - mr %r9,%r2 /* save GPR2 (not needed) */ - stmw %r9,0(%r3) /* save r9..r31 */ - li %r3,0 /* indicate success */ - blr /* return */ - - .size setjmp,.-setjmp - - .type longjmp,@function - .globl longjmp -longjmp: - lmw %r9,0(%r3) /* save r9..r31 */ - mtlr %r11 /* restore LR */ - mtcr %r12 /* restore CR */ - mr %r2,%r9 /* restore GPR2 (not needed) */ - mr %r1,%r10 /* restore stack */ - mr %r3,%r4 /* get return value */ - blr /* return */ - - .size longjmp,.-longjmp - diff --git a/klibc/klibc/arch/ppc/syscall.S b/klibc/klibc/arch/ppc/syscall.S deleted file mode 100644 index 0a7c37c903..0000000000 --- a/klibc/klibc/arch/ppc/syscall.S +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/ppc/syscall.S - * - * Common error-handling path for system calls. - */ - - .text - .align 2 - .globl __syscall_error - .type __syscall_error,@function -__syscall_error: - lis 9,errno@ha - stw 3,errno@l(9) - li 3,-1 - blr - .size __syscall_error,.-__syscall_error diff --git a/klibc/klibc/arch/ppc/sysstub.ph b/klibc/klibc/arch/ppc/sysstub.ph deleted file mode 100644 index 3b3916c726..0000000000 --- a/klibc/klibc/arch/ppc/sysstub.ph +++ /dev/null @@ -1,25 +0,0 @@ -# -*- perl -*- -# -# arch/ppc/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT "\tli 0,__NR_${sname}\n"; - print OUT "\tsc\n"; - print OUT "\tbnslr\n"; - print OUT "\tb __syscall_error\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/ppc64/MCONFIG b/klibc/klibc/arch/ppc64/MCONFIG deleted file mode 100644 index 9aba2ddbb6..0000000000 --- a/klibc/klibc/arch/ppc64/MCONFIG +++ /dev/null @@ -1,20 +0,0 @@ -# -*- makefile -*- -# -# arch/ppc64/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHREQFLAGS = -m64 -mcall-aixdesc -OPTFLAGS = -Os -BITSIZE = 64 -LDFLAGS = -m elf64ppc - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 256-16 MB - normal binaries start at 256 MB, and jumps are limited -# to +/- 16 MB -SHAREDFLAGS = -Ttext 0x0f000200 diff --git a/klibc/klibc/arch/ppc64/Makefile.inc b/klibc/klibc/arch/ppc64/Makefile.inc deleted file mode 100644 index d1e128fdce..0000000000 --- a/klibc/klibc/arch/ppc64/Makefile.inc +++ /dev/null @@ -1,25 +0,0 @@ -# -*- makefile -*- -# -# arch/ppc64/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - -INTERP_O = interp1.o - -interp.o: interp1.o klibc.got - $(LD) $(LDFLAGS) -r -o $@ interp1.o klibc.got - -klibc.got: $(SOHASH) - $(OBJCOPY) -j .got $< $@ - -archclean: - rm -f klibc.got diff --git a/klibc/klibc/arch/ppc64/crt0.S b/klibc/klibc/arch/ppc64/crt0.S deleted file mode 100644 index 872d2a0791..0000000000 --- a/klibc/klibc/arch/ppc64/crt0.S +++ /dev/null @@ -1,32 +0,0 @@ -# -# arch/ppc64/crt0.S -# -# void _start(void) -# { -# /* Divine up argc, argv, and envp */ -# environ = envp; -# exit(main(argc, argv, envp)); -# } -# - - .section ".toc","aw" -.LC0: .tc environ[TC],environ - - .section ".opd","aw" - .align 3 - .globl _start -_start: - .quad ._start - .quad .TOC.@tocbase, 0 - - .text - .globl ._start - .type ._start,@function -._start: - stdu %r1,-32(%r1) - addi %r3,%r1,32 - mr %r4,%r7 /* fini */ - b .__libc_init - nop - - .size _start,.-_start diff --git a/klibc/klibc/arch/ppc64/setjmp.S b/klibc/klibc/arch/ppc64/setjmp.S deleted file mode 100644 index 30db419140..0000000000 --- a/klibc/klibc/arch/ppc64/setjmp.S +++ /dev/null @@ -1,85 +0,0 @@ -# -# arch/ppc64/setjmp.S -# -# Basic setjmp/longjmp implementation -# - - .text - .align 4 - - .section ".opd","aw" -setjmp: - .quad .setjmp,.TOC.@tocbase,0 - .previous - .size setjmp,24 - .type .setjmp,@function - .globl setjmp - .globl .setjmp -.setjmp: - mflr %r11 /* save return address */ - mfcr %r12 /* save condition register */ - std %r2,0(%r3) /* save TOC pointer (not needed) */ - stdu %r1,8(%r3) /* save stack pointer */ - stdu %r11,8(%r3) - stdu %r12,8(%r3) - stdu %r13,8(%r3) /* save caller saved regs */ - stdu %r14,8(%r3) - stdu %r15,8(%r3) - stdu %r16,8(%r3) - stdu %r17,8(%r3) - stdu %r18,8(%r3) - stdu %r19,8(%r3) - stdu %r20,8(%r3) - stdu %r21,8(%r3) - stdu %r22,8(%r3) - stdu %r23,8(%r3) - stdu %r24,8(%r3) - stdu %r25,8(%r3) - stdu %r26,8(%r3) - stdu %r27,8(%r3) - stdu %r28,8(%r3) - stdu %r29,8(%r3) - stdu %r30,8(%r3) - std %r31,8(%r3) - li %r3,0 /* indicate success */ - blr /* return */ - - .size .setjmp,.-.setjmp - .section ".opd","aw" -longjmp: - .quad .longjmp,.TOC.@tocbase,0 - .previous - .size longjmp,24 - .type .longjmp,@function - .globl longjmp - .globl .longjmp -.longjmp: - ld %r2,0(%r3) /* restore TOC pointer (not needed) */ - ldu %r1,8(%r3) /* restore stack */ - ldu %r11,8(%r3) - ldu %r12,8(%r3) - ldu %r13,8(%r3) /* restore caller saved regs */ - ldu %r14,8(%r3) - ldu %r15,8(%r3) - ldu %r16,8(%r3) - ldu %r17,8(%r3) - ldu %r18,8(%r3) - ldu %r19,8(%r3) - ldu %r20,8(%r3) - ldu %r21,8(%r3) - ldu %r22,8(%r3) - ldu %r23,8(%r3) - ldu %r24,8(%r3) - ldu %r25,8(%r3) - ldu %r26,8(%r3) - ldu %r27,8(%r3) - ldu %r28,8(%r3) - ldu %r29,8(%r3) - ldu %r30,8(%r3) - ld %r31,8(%r3) - mtlr %r11 /* restore LR */ - mtcr %r12 /* restore CR */ - mr %r3,%r4 /* get return value */ - blr /* return */ - - .size .longjmp,.-.longjmp diff --git a/klibc/klibc/arch/ppc64/syscall.c b/klibc/klibc/arch/ppc64/syscall.c deleted file mode 100644 index a5895fe88e..0000000000 --- a/klibc/klibc/arch/ppc64/syscall.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * arch/ppc64/syscall.c - * - * Common error-handling path for system calls. - * The return value from __syscall_error becomes the - * return value from the system call. - */ -#include - -long int __syscall_error(long int err) -{ - errno = err; - return -1; -} diff --git a/klibc/klibc/arch/ppc64/sysstub.ph b/klibc/klibc/arch/ppc64/sysstub.ph deleted file mode 100644 index 9ee93701f6..0000000000 --- a/klibc/klibc/arch/ppc64/sysstub.ph +++ /dev/null @@ -1,31 +0,0 @@ -# -*- perl -*- -# -# arch/ppc64/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "\t.section \".opd\",\"aw\"\n"; - print OUT "\t.align 3\n"; - print OUT "${fname}:\n"; - print OUT "\t.quad .${fname},.TOC.\@tocbase,0\n"; - print OUT "\t.text\n"; - print OUT "\t.type .${fname},\@function\n"; - print OUT "\t.globl .${fname}\n"; - print OUT ".${fname}:\n"; - print OUT "\tli 0,__NR_${sname}\n"; - print OUT "\tsc\n"; - print OUT "\tbnslr\n"; - print OUT "\tb .__syscall_error\n"; - print OUT "\t.size .${fname},.-.${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/s390/MCONFIG b/klibc/klibc/arch/s390/MCONFIG deleted file mode 100644 index 640b395b54..0000000000 --- a/klibc/klibc/arch/s390/MCONFIG +++ /dev/null @@ -1,13 +0,0 @@ -# -*- makefile -*- -# -# arch/s390/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -BITSIZE = 32 - -SHAREDFLAGS = -Ttext 0x40000200 diff --git a/klibc/klibc/arch/s390/Makefile.inc b/klibc/klibc/arch/s390/Makefile.inc deleted file mode 100644 index 49b64ddbc6..0000000000 --- a/klibc/klibc/arch/s390/Makefile.inc +++ /dev/null @@ -1,23 +0,0 @@ -# -*- makefile -*- -# -# arch/s390/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/mmap.o \ - arch/$(ARCH)/syscall.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - - -archclean: diff --git a/klibc/klibc/arch/s390/crt0.S b/klibc/klibc/arch/s390/crt0.S deleted file mode 100644 index 49c3e7ebc7..0000000000 --- a/klibc/klibc/arch/s390/crt0.S +++ /dev/null @@ -1,25 +0,0 @@ -# -# arch/s390/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - .text - .align 4 - .type _start,@function - .globl _start -_start: - lr %r2,%r15 - lhi %r3,0 - ahi %r15,-96 - bras %r1,.L0 -.L0: - l %r1,.L1-.L0(%r1) - br %r1 -.L1: - .long __libc_init - - .size _start,.-_start diff --git a/klibc/klibc/arch/s390/mmap.c b/klibc/klibc/arch/s390/mmap.c deleted file mode 100644 index 51ff07f44c..0000000000 --- a/klibc/klibc/arch/s390/mmap.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -struct mmap_arg_struct { - unsigned long addr; - unsigned long len; - unsigned long prot; - unsigned long flags; - unsigned long fd; - unsigned long offset; -}; - -void * __mmap2(void * addr, size_t len, int prot, int flags, - int fd, long offset) -{ - struct mmap_arg_struct args = { - (unsigned long) addr, - (unsigned long) len, - (unsigned long) prot, - (unsigned long) flags, - (unsigned long) fd, - (unsigned long) offset, - }; - - register struct mmap_arg_struct *__arg1 asm("2") = &args; - register long __svcres asm("2"); - unsigned long __res; - - __asm__ __volatile__ ( - " svc %b1\n" - : "=d" (__svcres) - : "i" (__NR_mmap2), - "0" (__arg1) - : "1", "cc", "memory"); - __res = __svcres; - if (__res >= (unsigned long)-125) { - errno = -__res; - __res = -1; - } - return (void *)__res; -} diff --git a/klibc/klibc/arch/s390/setjmp.S b/klibc/klibc/arch/s390/setjmp.S deleted file mode 100644 index 97132680ae..0000000000 --- a/klibc/klibc/arch/s390/setjmp.S +++ /dev/null @@ -1,32 +0,0 @@ -# -# arch/s390/setjmp.S -# -# setjmp/longjmp for the s390 architecture -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: - stm %r6,%r15,0(%r2) # save all general registers - std %f4,40(%r2) # save fp registers f4 and f6 - std %f6,48(%r2) - lhi %r2,0 # return 0 - br %r14 - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: - lr %r1,%r2 # jmp_buf - lr %r2,%r3 # return value - ld %f6,48(%r1) # restore all saved registers - ld %f4,40(%r1) - lm %r6,%r15,0(%r1) - br %r14 # return to restored address - - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/s390/syscall.c b/klibc/klibc/arch/s390/syscall.c deleted file mode 100644 index c0f17c453c..0000000000 --- a/klibc/klibc/arch/s390/syscall.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/s390/syscall.c - * - * Common error-handling path for system calls. - * The return value from __syscall_common becomes the - * return value from the system call. - */ -#include - -long int __syscall_common(long int err) -{ - if ((unsigned long)(err) < (unsigned long)(-125)) - return err; - errno = err; - return -1; -} diff --git a/klibc/klibc/arch/s390/sysstub.ph b/klibc/klibc/arch/s390/sysstub.ph deleted file mode 100644 index 35f40a0865..0000000000 --- a/klibc/klibc/arch/s390/sysstub.ph +++ /dev/null @@ -1,31 +0,0 @@ -# -*- perl -*- -# -# arch/s390/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT ".if __NR_${sname} < 256\n"; - print OUT "\tsvc __NR_${sname}\n"; - print OUT ".else\n"; - print OUT "\tlhi %r1,__NR_${sname}\n"; - print OUT "\tsvc 0\n"; - print OUT ".endif\n"; - print OUT "\tbras %r3,1f\n"; - print OUT "\t.long __syscall_common\n"; - print OUT "1:\tl %r3,0(%r3)\n"; - print OUT "\tbr %r3\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/s390x/MCONFIG b/klibc/klibc/arch/s390x/MCONFIG deleted file mode 100644 index 081a0bbb52..0000000000 --- a/klibc/klibc/arch/s390x/MCONFIG +++ /dev/null @@ -1,13 +0,0 @@ -# -*- makefile -*- -# -# arch/s390x/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -BITSIZE = 64 - -SHAREDFLAGS = -Ttext 0x40000200 diff --git a/klibc/klibc/arch/s390x/Makefile.inc b/klibc/klibc/arch/s390x/Makefile.inc deleted file mode 100644 index 9d614e07b2..0000000000 --- a/klibc/klibc/arch/s390x/Makefile.inc +++ /dev/null @@ -1,18 +0,0 @@ -# -*- makefile -*- -# -# arch/s390x/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/mmap.o \ - arch/$(ARCH)/syscall.o - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - - -archclean: diff --git a/klibc/klibc/arch/s390x/crt0.S b/klibc/klibc/arch/s390x/crt0.S deleted file mode 100644 index de35664904..0000000000 --- a/klibc/klibc/arch/s390x/crt0.S +++ /dev/null @@ -1,21 +0,0 @@ -# -# arch/s390/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - - .text - .align 4 - .type _start,@function - .globl _start -_start: - lgr %r2,%r15 - lghi %r3,0 - aghi %r15,-160 - jg __libc_init - - .size _start,.-_start diff --git a/klibc/klibc/arch/s390x/mmap.c b/klibc/klibc/arch/s390x/mmap.c deleted file mode 100644 index 158f0933a4..0000000000 --- a/klibc/klibc/arch/s390x/mmap.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -struct mmap_arg_struct { - unsigned long addr; - unsigned long len; - unsigned long prot; - unsigned long flags; - unsigned long fd; - unsigned long offset; -}; - -void * mmap(void * addr, size_t len, int prot, int flags, - int fd, off_t offset) -{ - struct mmap_arg_struct args = { - (unsigned long) addr, - (unsigned long) len, - (unsigned long) prot, - (unsigned long) flags, - (unsigned long) fd, - (unsigned long) offset, - }; - - register struct mmap_arg_struct *__arg1 asm("2") = &args; - register long __svcres asm("2"); - unsigned long __res; - - __asm__ __volatile__ ( - " svc %b1\n" - : "=d" (__svcres) - : "i" (__NR_mmap), - "0" (__arg1) - : "1", "cc", "memory"); - __res = __svcres; - if (__res >= (unsigned long)-125) { - errno = -__res; - __res = -1; - } - return (void *)__res; -} diff --git a/klibc/klibc/arch/s390x/setjmp.S b/klibc/klibc/arch/s390x/setjmp.S deleted file mode 100644 index 251c57d43a..0000000000 --- a/klibc/klibc/arch/s390x/setjmp.S +++ /dev/null @@ -1,36 +0,0 @@ -# -# arch/s390x/setjmp.S -# -# setjmp/longjmp for the s390x architecture -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: - stmg %r6,%r15,0(%r2) # save all general registers - std %f1,80(%r2) # save fp registers f4 and f6 - std %f3,88(%r2) - std %f5,96(%r2) - std %f7,104(%r2) - lghi %r2,0 # return 0 - br %r14 - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: - lgr %r1,%r2 # jmp_buf - lgr %r2,%r3 # return value - ld %f7,104(%r1) # restore all saved registers - ld %f5,96(%r1) - ld %f3,88(%r1) - ld %f1,80(%r1) - lmg %r6,%r15,0(%r1) - br %r14 # return to restored address - - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/s390x/syscall.c b/klibc/klibc/arch/s390x/syscall.c deleted file mode 100644 index c0f17c453c..0000000000 --- a/klibc/klibc/arch/s390x/syscall.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/s390/syscall.c - * - * Common error-handling path for system calls. - * The return value from __syscall_common becomes the - * return value from the system call. - */ -#include - -long int __syscall_common(long int err) -{ - if ((unsigned long)(err) < (unsigned long)(-125)) - return err; - errno = err; - return -1; -} diff --git a/klibc/klibc/arch/s390x/sysstub.ph b/klibc/klibc/arch/s390x/sysstub.ph deleted file mode 100644 index 55c721b558..0000000000 --- a/klibc/klibc/arch/s390x/sysstub.ph +++ /dev/null @@ -1,28 +0,0 @@ -# -*- perl -*- -# -# arch/s390x/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT ".if __NR_${sname} < 256\n"; - print OUT "\tsvc __NR_${sname}\n"; - print OUT ".else\n"; - print OUT "\tlghi %r1,__NR_${sname}\n"; - print OUT "\tsvc 0\n"; - print OUT ".endif\n"; - print OUT "\tbrasl %r3,__syscall_common\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/sh/MCONFIG b/klibc/klibc/arch/sh/MCONFIG deleted file mode 100644 index 6cd4e5c839..0000000000 --- a/klibc/klibc/arch/sh/MCONFIG +++ /dev/null @@ -1,19 +0,0 @@ -# -*- makefile -*- -# -# arch/sh/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHREGFLAGS = -m4 -mno-implicit-fp -OPTFLAGS = -Os -fomit-frame-pointer -BITSIZE = 32 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 2 MB -- the normal starting point for text is 4 MB. -SHAREDFLAGS = -Ttext 0x00200200 - diff --git a/klibc/klibc/arch/sh/Makefile.inc b/klibc/klibc/arch/sh/Makefile.inc deleted file mode 100644 index ccabfa496b..0000000000 --- a/klibc/klibc/arch/sh/Makefile.inc +++ /dev/null @@ -1,15 +0,0 @@ -# -*- makefile -*- -# -# arch/sh/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = arch/sh/setjmp.o \ - arch/sh/syscall.o - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - -archclean: diff --git a/klibc/klibc/arch/sh/crt0.S b/klibc/klibc/arch/sh/crt0.S deleted file mode 100644 index 21a37655f2..0000000000 --- a/klibc/klibc/arch/sh/crt0.S +++ /dev/null @@ -1,27 +0,0 @@ -# -# arch/sh/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - - .text - .align 2 - .type _start,#function - .globl _start - -_start: - mov r15, r4 - mov #0, r5 - mov.l 1f, r0 - - jsr @r0 - nop - - .align 2 -1: .long __libc_init - - .size _start,.-_start diff --git a/klibc/klibc/arch/sh/setjmp.S b/klibc/klibc/arch/sh/setjmp.S deleted file mode 100644 index 63f760283f..0000000000 --- a/klibc/klibc/arch/sh/setjmp.S +++ /dev/null @@ -1,65 +0,0 @@ -# -# arch/sh/setjmp.S -# -# setjmp/longjmp for the SuperH architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# -# r8 -# r9 -# r10 -# r11 -# r12 -# r13 -# r14 -# r15 -# pr -# - - .text - .align 2 - - .globl setjmp - .type setjmp, #function - -setjmp: - add #(9*4), r4 - sts.l pr, @-r4 - mov.l r15, @-r4 - mov.l r14, @-r4 - mov.l r13, @-r4 - mov.l r12, @-r4 - mov.l r11, @-r4 - mov.l r10, @-r4 - mov.l r9, @-r4 - mov.l r8, @-r4 - rts - mov #0, r0 - - .size setjmp,.-setjmp - - .align 2 - .globl longjmp - .type setjmp, #function - -longjmp: - mov.l @r4+, r8 - mov.l @r4+, r9 - mov.l @r4+, r10 - mov.l @r4+, r11 - mov.l @r4+, r12 - mov.l @r4+, r13 - mov.l @r4+, r14 - mov.l @r4+, r15 - lds.l @r4+, pr - mov r5, r0 - tst r0, r0 - bf 1f - mov #1, r0 ! in case val==0 -1: rts - nop - - .size longjmp,.-longjmp - diff --git a/klibc/klibc/arch/sh/syscall.S b/klibc/klibc/arch/sh/syscall.S deleted file mode 100644 index 41a0486679..0000000000 --- a/klibc/klibc/arch/sh/syscall.S +++ /dev/null @@ -1,35 +0,0 @@ -/* - * arch/sh/syscall.S - * - * On sh, r3 contains the syscall number (set by generated stub); - * r4..r7 contain arguments 0-3 per the standard calling convention, - * and arguments 4-5 are passed in r0 and r1. - * - * The return value is in r3 rather than standard r0. - */ - - .section ".text.syscall","ax" - .align 2 - .globl ___syscall_common - .type ___syscall_common,@function -___syscall_common: - mov.l @(sp),r0 - mov.l @(4,sp),r1 - trapa #0x15 - mov.l 1f,r0 - cmp/hs r0,r3 - bt/s 3f - neg r3,r4 - mov.l 2f,r5 - mov.l r4,@r5 - rts - mov #-1,r0 -3: - rts - mov r3,r0 - - .align 2 -1: .long -4096 /* Errno limit */ -2: .long errno - - .size ___syscall_common,.-___syscall_common diff --git a/klibc/klibc/arch/sh/sysstub.ph b/klibc/klibc/arch/sh/sysstub.ph deleted file mode 100644 index ce04b739e9..0000000000 --- a/klibc/klibc/arch/sh/sysstub.ph +++ /dev/null @@ -1,34 +0,0 @@ -# -*- perl -*- -# -# arch/sh/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.section\t\".text.syscall\",\"ax\"\n"; - print OUT "\t.type\t${fname},\#function\n"; - print OUT "\t.globl\t${fname}\n"; - print OUT "\t.align\t2\n"; - print OUT "${fname}:\n"; - print OUT "\tbra\t__syscall_common\n"; - print OUT "#if __NR_${sname} >= 128\n"; - print OUT "\t mov.l\t1f, r3\n"; - print OUT "#else\n"; - print OUT "\t mov\t# __NR_${sname}, r3\n"; - print OUT "#endif\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - print OUT "\n"; - print OUT "#if __NR_${sname} >= 128\n"; - print OUT "\t.align\t2\n"; - print OUT "1:\t.long\t__NR_${sname}\n"; - print OUT "#endif\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/sparc/MCONFIG b/klibc/klibc/arch/sparc/MCONFIG deleted file mode 100644 index 3a5cbaa2e7..0000000000 --- a/klibc/klibc/arch/sparc/MCONFIG +++ /dev/null @@ -1,18 +0,0 @@ -# -*- makefile -*- -# -# arch/sparc/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -OPTFLAGS = -Os -m32 -mptr32 -BITSIZE = 32 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# Normal binaries start at 64K; the linker wants 64K alignment, -# and call instructions have a 30-bit signed offset, << 2. -SHAREDFLAGS = -Ttext 0x40000100 diff --git a/klibc/klibc/arch/sparc/Makefile.inc b/klibc/klibc/arch/sparc/Makefile.inc deleted file mode 100644 index bea1dbc94e..0000000000 --- a/klibc/klibc/arch/sparc/Makefile.inc +++ /dev/null @@ -1,51 +0,0 @@ -# -*- makefile -*- -# -# arch/sparc/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/sdiv.o \ - arch/$(ARCH)/udiv.o \ - arch/$(ARCH)/srem.o \ - arch/$(ARCH)/urem.o \ - arch/$(ARCH)/smul.o \ - arch/$(ARCH)/umul.o \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - arch/$(ARCH)/sysfork.o \ - libgcc/__divdi3.o \ - libgcc/__moddi3.o \ - libgcc/__udivdi3.o \ - libgcc/__umoddi3.o \ - libgcc/__udivmoddi4.o - -arch/$(ARCH)/sdiv.S: arch/$(ARCH)/divrem.m4 - @echo 'building $@ from $^' - @(echo "define(NAME,\`.div')define(OP,\`div')define(S,\`true')"; \ - cat $^) | m4 > $@ - @chmod 444 $@ - -arch/$(ARCH)/udiv.S: arch/$(ARCH)/divrem.m4 - @echo 'building $@ from $^' - @(echo "define(NAME,\`.udiv')define(OP,\`div')define(S,\`false')"; \ - cat $^) | m4 > $@ - @chmod 444 $@ - -arch/$(ARCH)/srem.S: arch/$(ARCH)/divrem.m4 - @echo 'building $@ from $^' - @(echo "define(NAME,\`.rem')define(OP,\`rem')define(S,\`true')"; \ - cat $^) | m4 > $@ - @chmod 444 $@ - -arch/$(ARCH)/urem.S: arch/$(ARCH)/divrem.m4 - @echo 'building $@ from $^' - @(echo "define(NAME,\`.urem')define(OP,\`rem')define(S,\`false')"; \ - cat $^) | m4 > $@ - @chmod 444 $@ - -archclean: - rm -f arch/$(ARCH)/?div.S arch/$(ARCH)/?rem.S diff --git a/klibc/klibc/arch/sparc/crt0.S b/klibc/klibc/arch/sparc/crt0.S deleted file mode 100644 index 63db188961..0000000000 --- a/klibc/klibc/arch/sparc/crt0.S +++ /dev/null @@ -1,2 +0,0 @@ -#define TARGET_PTR_SIZE 32 -#include "crt0i.S" diff --git a/klibc/klibc/arch/sparc/crt0i.S b/klibc/klibc/arch/sparc/crt0i.S deleted file mode 100644 index 97652a3090..0000000000 --- a/klibc/klibc/arch/sparc/crt0i.S +++ /dev/null @@ -1,100 +0,0 @@ -! This file derived from the equivalent in newlib -! -! C run time start off - -! This file supports: -! -! - both 32bit pointer and 64bit pointer environments (at compile time) -! - an imposed stack bias (of 2047) (at run time) -! - medium/low and medium/anywhere code models (at run time) - -! Initial stack setup: -! -! bottom of stack (higher memory address) -! ... -! text of environment strings -! text of argument strings -! envp[envc] = 0 (4/8 bytes) -! ... -! env[0] (4/8 bytes) -! argv[argc] = 0 (4/8 bytes) -! ... -! argv[0] (4/8 bytes) -! argc (4/8 bytes) -! register save area (64 bits by 16 registers = 128 bytes) -! top of stack (%sp) - -! Stack Bias: -! -! It is the responsibility of the o/s to set this up. -! We handle both a 0 and 2047 value for the stack bias. - -! Medium/Anywhere code model support: -! -! In this model %g4 points to the start of the data segment. -! The text segment can go anywhere, but %g4 points to the *data* segment. -! It is up to the compiler/linker to get this right. -! -! Since this model is statically linked the start of the data segment -! is known at link time. Eg: -! -! sethi %hh(data_start), %g1 -! sethi %lm(data_start), %g4 -! or %g1, %hm(data_start), %g1 -! or %g4, %lo(data_start), %g4 -! sllx %g1, 32, %g1 -! or %g4, %g1, %g4 -! -! FIXME: For now we just assume 0. - -! FIXME: if %g1 contains a non-zero value, atexit() should be invoked -! with this value. - - - .text - .align 4 - .globl _start - .type _start, @function -_start: - clr %fp - -! We use %g4 even if the code model is Medium/Low (simplifies the code). - - clr %g4 ! Medium/Anywhere base reg - -! If there is a stack bias in effect, account for it in %g5. Then always -! add %g5 to stack references below. This way the code can be used with -! or without an imposed bias. - - andcc %sp, 1, %g5 - bz,a .LNoBias - nop - mov 2047, %g5 -.LNoBias: - add %sp, %g5, %g5 - -! On entry, the kernel leaves room for one register frame, but -! the C API wants more free space. Thus, we need to drop the stack -! pointer additionally. - -#if TARGET_PTR_SIZE == 32 - sub %sp, 32, %sp ! make room for incoming arguments -#else /* TARGET_PTR_SIZE == 64 */ - sub %sp, 64, %sp ! make room for incoming arguments -#endif - -! Set up pointers to the ELF data structure (argc, argv, ...) -! Pass as the first argument to __libc_init -#if TARGET_PTR_SIZE == 32 - add %g5, 0x40, %o0 -#else /* TARGET_PTR_SIZE == 64 */ - add %g5, 0x80, %o0 -#endif - - call __libc_init - mov %g1, %o1 ! This is the "atexit" pointer; - ! pass as the second argument to __libc_init - -! If __libc_init returns, something is hosed. Try an illegal insn. -! If that does not work, the o/s is hosed more than we are. - .long 0 diff --git a/klibc/klibc/arch/sparc/divrem.m4 b/klibc/klibc/arch/sparc/divrem.m4 deleted file mode 100644 index aa4171dd88..0000000000 --- a/klibc/klibc/arch/sparc/divrem.m4 +++ /dev/null @@ -1,276 +0,0 @@ -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: Header: divrem.m4,v 1.4 92/06/25 13:23:57 torek Exp - * $NetBSD: divrem.m4,v 1.4 1997/10/09 10:07:54 lukem Exp $ - */ - -/* - * Division and remainder, from Appendix E of the Sparc Version 8 - * Architecture Manual, with fixes from Gordon Irlam. - */ - -#if defined(LIBC_SCCS) && !defined(lint) - .asciz "@(#)divrem.m4 8.1 (Berkeley) 6/4/93" -#endif /* LIBC_SCCS and not lint */ - -/* - * Input: dividend and divisor in %o0 and %o1 respectively. - * - * m4 parameters: - * NAME name of function to generate - * OP OP=div => %o0 / %o1; OP=rem => %o0 % %o1 - * S S=true => signed; S=false => unsigned - * - * Algorithm parameters: - * N how many bits per iteration we try to get (4) - * WORDSIZE total number of bits (32) - * - * Derived constants: - * TWOSUPN 2^N, for label generation (m4 exponentiation currently broken) - * TOPBITS number of bits in the top `decade' of a number - * - * Important variables: - * Q the partial quotient under development (initially 0) - * R the remainder so far, initially the dividend - * ITER number of main division loop iterations required; - * equal to ceil(log2(quotient) / N). Note that this - * is the log base (2^N) of the quotient. - * V the current comparand, initially divisor*2^(ITER*N-1) - * - * Cost: - * Current estimate for non-large dividend is - * ceil(log2(quotient) / N) * (10 + 7N/2) + C - * A large dividend is one greater than 2^(31-TOPBITS) and takes a - * different path, as the upper bits of the quotient must be developed - * one bit at a time. - */ - -define(N, `4') -define(TWOSUPN, `16') -define(WORDSIZE, `32') -define(TOPBITS, eval(WORDSIZE - N*((WORDSIZE-1)/N))) - -define(dividend, `%o0') -define(divisor, `%o1') -define(Q, `%o2') -define(R, `%o3') -define(ITER, `%o4') -define(V, `%o5') - -/* m4 reminder: ifelse(a,b,c,d) => if a is b, then c, else d */ -define(T, `%g1') -define(SC, `%g7') -ifelse(S, `true', `define(SIGN, `%g6')') - -/* - * This is the recursive definition for developing quotient digits. - * - * Parameters: - * $1 the current depth, 1 <= $1 <= N - * $2 the current accumulation of quotient bits - * N max depth - * - * We add a new bit to $2 and either recurse or insert the bits in - * the quotient. R, Q, and V are inputs and outputs as defined above; - * the condition codes are expected to reflect the input R, and are - * modified to reflect the output R. - */ -define(DEVELOP_QUOTIENT_BITS, -` ! depth $1, accumulated bits $2 - bl L.$1.eval(TWOSUPN+$2) - srl V,1,V - ! remainder is positive - subcc R,V,R - ifelse($1, N, - ` b 9f - add Q, ($2*2+1), Q - ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2+1)')') -L.$1.eval(TWOSUPN+$2): - ! remainder is negative - addcc R,V,R - ifelse($1, N, - ` b 9f - add Q, ($2*2-1), Q - ', ` DEVELOP_QUOTIENT_BITS(incr($1), `eval(2*$2-1)')') - ifelse($1, 1, `9:')') - -#include -#include - -FUNC(NAME) -ifelse(S, `true', -` ! compute sign of result; if neither is negative, no problem - orcc divisor, dividend, %g0 ! either negative? - bge 2f ! no, go do the divide - ifelse(OP, `div', - `xor divisor, dividend, SIGN', - `mov dividend, SIGN') ! compute sign in any case - tst divisor - bge 1f - tst dividend - ! divisor is definitely negative; dividend might also be negative - bge 2f ! if dividend not negative... - neg divisor ! in any case, make divisor nonneg -1: ! dividend is negative, divisor is nonnegative - neg dividend ! make dividend nonnegative -2: -') - ! Ready to divide. Compute size of quotient; scale comparand. - orcc divisor, %g0, V - bnz 1f - mov dividend, R - - ! Divide by zero trap. If it returns, return 0 (about as - ! wrong as possible, but that is what SunOS does...). - t ST_DIV0 - retl - clr %o0 - -1: - cmp R, V ! if divisor exceeds dividend, done - blu Lgot_result ! (and algorithm fails otherwise) - clr Q - sethi %hi(1 << (WORDSIZE - TOPBITS - 1)), T - cmp R, T - blu Lnot_really_big - clr ITER - - ! `Here the dividend is >= 2^(31-N) or so. We must be careful here, - ! as our usual N-at-a-shot divide step will cause overflow and havoc. - ! The number of bits in the result here is N*ITER+SC, where SC <= N. - ! Compute ITER in an unorthodox manner: know we need to shift V into - ! the top decade: so do not even bother to compare to R.' - 1: - cmp V, T - bgeu 3f - mov 1, SC - sll V, N, V - b 1b - inc ITER - - ! Now compute SC. - 2: addcc V, V, V - bcc Lnot_too_big - inc SC - - ! We get here if the divisor overflowed while shifting. - ! This means that R has the high-order bit set. - ! Restore V and subtract from R. - sll T, TOPBITS, T ! high order bit - srl V, 1, V ! rest of V - add V, T, V - b Ldo_single_div - dec SC - - Lnot_too_big: - 3: cmp V, R - blu 2b - nop - be Ldo_single_div - nop - /* NB: these are commented out in the V8-Sparc manual as well */ - /* (I do not understand this) */ - ! V > R: went too far: back up 1 step - ! srl V, 1, V - ! dec SC - ! do single-bit divide steps - ! - ! We have to be careful here. We know that R >= V, so we can do the - ! first divide step without thinking. BUT, the others are conditional, - ! and are only done if R >= 0. Because both R and V may have the high- - ! order bit set in the first step, just falling into the regular - ! division loop will mess up the first time around. - ! So we unroll slightly... - Ldo_single_div: - deccc SC - bl Lend_regular_divide - nop - sub R, V, R - mov 1, Q - b Lend_single_divloop - nop - Lsingle_divloop: - sll Q, 1, Q - bl 1f - srl V, 1, V - ! R >= 0 - sub R, V, R - b 2f - inc Q - 1: ! R < 0 - add R, V, R - dec Q - 2: - Lend_single_divloop: - deccc SC - bge Lsingle_divloop - tst R - b,a Lend_regular_divide - -Lnot_really_big: -1: - sll V, N, V - cmp V, R - bleu 1b - inccc ITER - be Lgot_result - dec ITER - - tst R ! set up for initial iteration -Ldivloop: - sll Q, N, Q - DEVELOP_QUOTIENT_BITS(1, 0) -Lend_regular_divide: - deccc ITER - bge Ldivloop - tst R - bl,a Lgot_result - ! non-restoring fixup here (one instruction only!) -ifelse(OP, `div', -` dec Q -', ` add R, divisor, R -') - -Lgot_result: -ifelse(S, `true', -` ! check to see if answer should be < 0 - tst SIGN - bl,a 1f - ifelse(OP, `div', `neg Q', `neg R') -1:') - retl - ifelse(OP, `div', `mov Q, %o0', `mov R, %o0') diff --git a/klibc/klibc/arch/sparc/setjmp.S b/klibc/klibc/arch/sparc/setjmp.S deleted file mode 100644 index f41ee2bf12..0000000000 --- a/klibc/klibc/arch/sparc/setjmp.S +++ /dev/null @@ -1,38 +0,0 @@ -! -! setjmp.S -! -! Basic setjmp/longjmp -! -! This code was based on the equivalent code in NetBSD -! - -#include -#include - -! -! The jmp_buf contains the following entries: -! sp -! fp -! pc -! -ENTRY(setjmp) - st %sp,[%o0+0] ! Callers stack pointer - st %o7,[%o0+4] ! Return pc - st %fp,[%o0+8] ! Frame pointer - retl ! Return - clr %o0 ! ...0 - -ENTRY(longjmp) - sub %sp, 64, %sp ! set up a local stack frame -0: - t ST_FLUSHWIN ! flush register windows out to memory - ! - ! We restore the saved stack pointer to %fp, then issue - ! a restore instruction which will reload the register - ! window from the stack. - ! - ld [%o0+4], %o7 /* restore return pc */ - ld [%o0+0], %fp /* and stack pointer */ - - retl ! success, return %g6 - restore %o1, 0, %o0 diff --git a/klibc/klibc/arch/sparc/smul.S b/klibc/klibc/arch/sparc/smul.S deleted file mode 100644 index 0eb218bbe8..0000000000 --- a/klibc/klibc/arch/sparc/smul.S +++ /dev/null @@ -1,160 +0,0 @@ -/* $NetBSD: mul.S,v 1.3 1997/07/16 14:37:42 christos Exp $ */ - -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: Header: mul.s,v 1.5 92/06/25 13:24:03 torek Exp - */ - -#include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 - .asciz "@(#)mul.s 8.1 (Berkeley) 6/4/93" -#else - RCSID("$NetBSD: mul.S,v 1.3 1997/07/16 14:37:42 christos Exp $") -#endif -#endif /* LIBC_SCCS and not lint */ - -/* - * Signed multiply, from Appendix E of the Sparc Version 8 - * Architecture Manual. - * - * Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the upper 32 bits of - * the 64-bit product). - * - * This code optimizes short (less than 13-bit) multiplies. - */ - -FUNC(.mul) - mov %o0, %y ! multiplier -> Y - andncc %o0, 0xfff, %g0 ! test bits 12..31 - be Lmul_shortway ! if zero, can do it the short way - andcc %g0, %g0, %o4 ! zero the partial product and clear N and V - - /* - * Long multiply. 32 steps, followed by a final shift step. - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %o1, %o4 ! 13 - mulscc %o4, %o1, %o4 ! 14 - mulscc %o4, %o1, %o4 ! 15 - mulscc %o4, %o1, %o4 ! 16 - mulscc %o4, %o1, %o4 ! 17 - mulscc %o4, %o1, %o4 ! 18 - mulscc %o4, %o1, %o4 ! 19 - mulscc %o4, %o1, %o4 ! 20 - mulscc %o4, %o1, %o4 ! 21 - mulscc %o4, %o1, %o4 ! 22 - mulscc %o4, %o1, %o4 ! 23 - mulscc %o4, %o1, %o4 ! 24 - mulscc %o4, %o1, %o4 ! 25 - mulscc %o4, %o1, %o4 ! 26 - mulscc %o4, %o1, %o4 ! 27 - mulscc %o4, %o1, %o4 ! 28 - mulscc %o4, %o1, %o4 ! 29 - mulscc %o4, %o1, %o4 ! 30 - mulscc %o4, %o1, %o4 ! 31 - mulscc %o4, %o1, %o4 ! 32 - mulscc %o4, %g0, %o4 ! final shift - - ! If %o0 was negative, the result is - ! (%o0 * %o1) + (%o1 << 32)) - ! We fix that here. - - tst %o0 - bge 1f - rd %y, %o0 - - ! %o0 was indeed negative; fix upper 32 bits of result by subtracting - ! %o1 (i.e., return %o4 - %o1 in %o1). - retl - sub %o4, %o1, %o1 - -1: - retl - mov %o4, %o1 - -Lmul_shortway: - /* - * Short multiply. 12 steps, followed by a final shift step. - * The resulting bits are off by 12 and (32-12) = 20 bit positions, - * but there is no problem with %o0 being negative (unlike above). - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %g0, %o4 ! final shift - - /* - * %o4 has 20 of the bits that should be in the low part of the - * result; %y has the bottom 12 (as %y's top 12). That is: - * - * %o4 %y - * +----------------+----------------+ - * | -12- | -20- | -12- | -20- | - * +------(---------+------)---------+ - * --hi-- ----low-part---- - * - * The upper 12 bits of %o4 should be sign-extended to form the - * high part of the product (i.e., highpart = %o4 >> 20). - */ - - rd %y, %o5 - sll %o4, 12, %o0 ! shift middle bits left 12 - srl %o5, 20, %o5 ! shift low bits right 20, zero fill at left - or %o5, %o0, %o0 ! construct low part of result - retl - sra %o4, 20, %o1 ! ... and extract high part of result diff --git a/klibc/klibc/arch/sparc/syscall.S b/klibc/klibc/arch/sparc/syscall.S deleted file mode 100644 index c0273f77ca..0000000000 --- a/klibc/klibc/arch/sparc/syscall.S +++ /dev/null @@ -1,19 +0,0 @@ -/* - * arch/sparc/syscall.S - * - * Common system-call stub; %g1 already set to syscall number - */ - - .globl __syscall_common - .type __syscall_common,#function - .align 4 -__syscall_common: - t 0x10 - bcc 1f - sethi %hi(errno), %g4 - or %g4, %lo(errno), %g4 - st %o0,[%g4] - mov -1, %o0 -1: - retl - nop diff --git a/klibc/klibc/arch/sparc/sysfork.S b/klibc/klibc/arch/sparc/sysfork.S deleted file mode 100644 index a66c76e9db..0000000000 --- a/klibc/klibc/arch/sparc/sysfork.S +++ /dev/null @@ -1,25 +0,0 @@ -/* - * arch/sparc/sysfork.S - * - * The fork and vfork system calls are special on sparc[64]: - * they return the "other process" pid in %o0 and the - * "is child" flag in %o1 - * - * Common system-call stub; %g1 already set to syscall number - */ - - .globl __syscall_forkish - .type __syscall_forkish,#function - .align 4 -__syscall_forkish: - t 0x10 - sub %o1, 1, %o1 - bcc,a 1f - and %o0, %o1, %o0 - sethi %hi(errno), %g4 - or %g4, %lo(errno), %g4 - st %o0,[%g4] - mov -1, %o0 -1: - retl - nop diff --git a/klibc/klibc/arch/sparc/sysstub.ph b/klibc/klibc/arch/sparc/sysstub.ph deleted file mode 100644 index d8cedb5ae5..0000000000 --- a/klibc/klibc/arch/sparc/sysstub.ph +++ /dev/null @@ -1,25 +0,0 @@ -# -*- perl -*- -# -# arch/sparc32/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - $stype = $stype || 'common'; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT "\tb __syscall_${stype}\n"; - print OUT "\t mov\t__NR_${sname}, %g1\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/sparc/umul.S b/klibc/klibc/arch/sparc/umul.S deleted file mode 100644 index 6a7193d217..0000000000 --- a/klibc/klibc/arch/sparc/umul.S +++ /dev/null @@ -1,193 +0,0 @@ -/* $NetBSD: umul.S,v 1.3 1997/07/16 14:37:44 christos Exp $ */ - -/* - * Copyright (c) 1992, 1993 - * The Regents of the University of California. All rights reserved. - * - * This software was developed by the Computer Systems Engineering group - * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and - * contributed to Berkeley. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: Header: umul.s,v 1.4 92/06/25 13:24:05 torek Exp - */ - -#include -#if defined(LIBC_SCCS) && !defined(lint) -#if 0 - .asciz "@(#)umul.s 8.1 (Berkeley) 6/4/93" -#else - RCSID("$NetBSD: umul.S,v 1.3 1997/07/16 14:37:44 christos Exp $") -#endif -#endif /* LIBC_SCCS and not lint */ - -/* - * Unsigned multiply. Returns %o0 * %o1 in %o1%o0 (i.e., %o1 holds the - * upper 32 bits of the 64-bit product). - * - * This code optimizes short (less than 13-bit) multiplies. Short - * multiplies require 25 instruction cycles, and long ones require - * 45 instruction cycles. - * - * On return, overflow has occurred (%o1 is not zero) if and only if - * the Z condition code is clear, allowing, e.g., the following: - * - * call .umul - * nop - * bnz overflow (or tnz) - */ - -FUNC(.umul) - or %o0, %o1, %o4 - mov %o0, %y ! multiplier -> Y - andncc %o4, 0xfff, %g0 ! test bits 12..31 of *both* args - be Lmul_shortway ! if zero, can do it the short way - andcc %g0, %g0, %o4 ! zero the partial product and clear N and V - - /* - * Long multiply. 32 steps, followed by a final shift step. - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %o1, %o4 ! 13 - mulscc %o4, %o1, %o4 ! 14 - mulscc %o4, %o1, %o4 ! 15 - mulscc %o4, %o1, %o4 ! 16 - mulscc %o4, %o1, %o4 ! 17 - mulscc %o4, %o1, %o4 ! 18 - mulscc %o4, %o1, %o4 ! 19 - mulscc %o4, %o1, %o4 ! 20 - mulscc %o4, %o1, %o4 ! 21 - mulscc %o4, %o1, %o4 ! 22 - mulscc %o4, %o1, %o4 ! 23 - mulscc %o4, %o1, %o4 ! 24 - mulscc %o4, %o1, %o4 ! 25 - mulscc %o4, %o1, %o4 ! 26 - mulscc %o4, %o1, %o4 ! 27 - mulscc %o4, %o1, %o4 ! 28 - mulscc %o4, %o1, %o4 ! 29 - mulscc %o4, %o1, %o4 ! 30 - mulscc %o4, %o1, %o4 ! 31 - mulscc %o4, %o1, %o4 ! 32 - mulscc %o4, %g0, %o4 ! final shift - - - /* - * Normally, with the shift-and-add approach, if both numbers are - * positive you get the correct result. WIth 32-bit two's-complement - * numbers, -x is represented as - * - * x 32 - * ( 2 - ------ ) mod 2 * 2 - * 32 - * 2 - * - * (the `mod 2' subtracts 1 from 1.bbbb). To avoid lots of 2^32s, - * we can treat this as if the radix point were just to the left - * of the sign bit (multiply by 2^32), and get - * - * -x = (2 - x) mod 2 - * - * Then, ignoring the `mod 2's for convenience: - * - * x * y = xy - * -x * y = 2y - xy - * x * -y = 2x - xy - * -x * -y = 4 - 2x - 2y + xy - * - * For signed multiplies, we subtract (x << 32) from the partial - * product to fix this problem for negative multipliers (see mul.s). - * Because of the way the shift into the partial product is calculated - * (N xor V), this term is automatically removed for the multiplicand, - * so we don't have to adjust. - * - * But for unsigned multiplies, the high order bit wasn't a sign bit, - * and the correction is wrong. So for unsigned multiplies where the - * high order bit is one, we end up with xy - (y << 32). To fix it - * we add y << 32. - */ - tst %o1 - bl,a 1f ! if %o1 < 0 (high order bit = 1), - add %o4, %o0, %o4 ! %o4 += %o0 (add y to upper half) -1: rd %y, %o0 ! get lower half of product - retl - addcc %o4, %g0, %o1 ! put upper half in place and set Z for %o1==0 - -Lmul_shortway: - /* - * Short multiply. 12 steps, followed by a final shift step. - * The resulting bits are off by 12 and (32-12) = 20 bit positions, - * but there is no problem with %o0 being negative (unlike above), - * and overflow is impossible (the answer is at most 24 bits long). - */ - mulscc %o4, %o1, %o4 ! 1 - mulscc %o4, %o1, %o4 ! 2 - mulscc %o4, %o1, %o4 ! 3 - mulscc %o4, %o1, %o4 ! 4 - mulscc %o4, %o1, %o4 ! 5 - mulscc %o4, %o1, %o4 ! 6 - mulscc %o4, %o1, %o4 ! 7 - mulscc %o4, %o1, %o4 ! 8 - mulscc %o4, %o1, %o4 ! 9 - mulscc %o4, %o1, %o4 ! 10 - mulscc %o4, %o1, %o4 ! 11 - mulscc %o4, %o1, %o4 ! 12 - mulscc %o4, %g0, %o4 ! final shift - - /* - * %o4 has 20 of the bits that should be in the result; %y has - * the bottom 12 (as %y's top 12). That is: - * - * %o4 %y - * +----------------+----------------+ - * | -12- | -20- | -12- | -20- | - * +------(---------+------)---------+ - * -----result----- - * - * The 12 bits of %o4 left of the `result' area are all zero; - * in fact, all top 20 bits of %o4 are zero. - */ - - rd %y, %o5 - sll %o4, 12, %o0 ! shift middle bits left 12 - srl %o5, 20, %o5 ! shift low bits right 20 - or %o5, %o0, %o0 - retl - addcc %g0, %g0, %o1 ! %o1 = zero, and set Z diff --git a/klibc/klibc/arch/sparc64/MCONFIG b/klibc/klibc/arch/sparc64/MCONFIG deleted file mode 100644 index a8a742412e..0000000000 --- a/klibc/klibc/arch/sparc64/MCONFIG +++ /dev/null @@ -1,21 +0,0 @@ -# -*- makefile -*- -# -# arch/sparc64/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHREQFLAGS = -m64 -mptr64 -OPTFLAGS = -Os -BITSIZE = 64 - -LDFLAGS = -m elf64_sparc - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# Normal binaries start at 1 MB; the linker wants 1 MB alignment, -# and call instructions have a 30-bit signed offset, << 2. -SHAREDFLAGS = -Ttext 0x80000200 diff --git a/klibc/klibc/arch/sparc64/Makefile.inc b/klibc/klibc/arch/sparc64/Makefile.inc deleted file mode 100644 index 06b79537a3..0000000000 --- a/klibc/klibc/arch/sparc64/Makefile.inc +++ /dev/null @@ -1,15 +0,0 @@ -# -*- makefile -*- -# -# arch/sparc64/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - arch/$(ARCH)/sysfork.o - -archclean: diff --git a/klibc/klibc/arch/sparc64/crt0.S b/klibc/klibc/arch/sparc64/crt0.S deleted file mode 100644 index 5faee7c6be..0000000000 --- a/klibc/klibc/arch/sparc64/crt0.S +++ /dev/null @@ -1,2 +0,0 @@ -#define TARGET_PTR_SIZE 64 -#include "../sparc/crt0i.S" diff --git a/klibc/klibc/arch/sparc64/setjmp.S b/klibc/klibc/arch/sparc64/setjmp.S deleted file mode 100644 index b04d47faab..0000000000 --- a/klibc/klibc/arch/sparc64/setjmp.S +++ /dev/null @@ -1,55 +0,0 @@ -! -! setjmp.S -! -! Basic setjmp/longjmp -! -! This code was based on the equivalent code in NetBSD -! - -! -! The jmp_buf contains the following entries: -! sp -! fp -! pc -! - .text - .align 4 - .global setjmp - .type setjmp, @function -setjmp: - stx %sp,[%o0+0] ! Callers stack pointer - stx %o7,[%o0+8] ! Return pc - stx %fp,[%o0+16] ! Frame pointer - retl ! Return - clr %o0 ! ...0 - - .size setjmp,.-setjmp - - - .globl longjmp - .type longjmp, @function -longjmp: - mov %o1, %g4 ! save return value - mov %o0, %g1 ! save target - ldx [%g1+16],%g5 ! get callers frame -1: - cmp %fp, %g5 ! compare against desired frame - bl,a 1b ! if below... - restore ! pop frame and loop - be,a 2f ! if there... - ldx [%g1+0],%o2 ! fetch return %sp - -.Lbotch: - unimp 0 ! ... error ... - -2: - cmp %o2, %sp ! %sp must not decrease - bl .Lbotch - nop - mov %o2, %sp ! it is OK, put it in place - - ldx [%g1+8],%o3 ! fetch %pc - jmp %o3 + 8 ! if sucess... - mov %g4,%o0 ! return %g4 - - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/sparc64/syscall.S b/klibc/klibc/arch/sparc64/syscall.S deleted file mode 100644 index 7ab9d95f11..0000000000 --- a/klibc/klibc/arch/sparc64/syscall.S +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/sparc64/syscall.S - * - * Common system-call stub; %g1 already set to syscall number - */ - - .globl __syscall_common - .type __syscall_common,#function - .align 4 -__syscall_common: - t 0x6d - bcc %xcc, 1f - sethi %hi(errno), %g4 - or %g4, %lo(errno), %g4 - st %o0,[%g4] -1: - retl - movcs %xcc, -1, %o0 diff --git a/klibc/klibc/arch/sparc64/sysfork.S b/klibc/klibc/arch/sparc64/sysfork.S deleted file mode 100644 index 739c35ede3..0000000000 --- a/klibc/klibc/arch/sparc64/sysfork.S +++ /dev/null @@ -1,26 +0,0 @@ -/* - * arch/sparc64/sysfork.S - * - * The fork and vfork system calls are special on sparc[64]: - * they return the "other process" pid in %o0 and the - * "is child" flag in %o1 - * - * Common system-call stub; %g1 already set to syscall number - * - * IS THIS CORRECT FOR SPARC64? - */ - - .globl __syscall_forkish - .type __syscall_forkish,#function - .align 4 -__syscall_forkish: - t 0x6d - sub %o1, 1, %o1 - bcc,a %xcc, 1f - and %o0, %o1, %o0 - sethi %hi(errno), %g4 - or %g4, %lo(errno), %g4 - st %o0,[%g4] -1: - retl - movcs %xcc, -1, %o0 diff --git a/klibc/klibc/arch/sparc64/sysstub.ph b/klibc/klibc/arch/sparc64/sysstub.ph deleted file mode 100644 index deeb88ce07..0000000000 --- a/klibc/klibc/arch/sparc64/sysstub.ph +++ /dev/null @@ -1,25 +0,0 @@ -# -*- perl -*- -# -# arch/sparc64/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - $stype = $stype || 'common'; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT "\tb __syscall_${stype}\n"; - print OUT "\t mov\t__NR_${sname}, %g1\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/arch/x86_64/MCONFIG b/klibc/klibc/arch/x86_64/MCONFIG deleted file mode 100644 index c9b5da8bd6..0000000000 --- a/klibc/klibc/arch/x86_64/MCONFIG +++ /dev/null @@ -1,36 +0,0 @@ -# -*- makefile -*- -# -# arch/x86-64/MCONFIG -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# -# Blatantly copied and modified from i386 version by Mats Petersson, AMD. -# - -# -# NOTE: -fno-asynchronous-unwind-tables produce significantly smaller -# binaries (20% smaller), but makes the code completely useless for -# debugging using gdb. -# -ARCHREQFLAGS = -m64 -ifeq ($(DEBUG),y) -OPTFLAGS = -Os -fomit-frame-pointer \ - -falign-functions=0 -falign-jumps=0 -falign-loops=0 -else -OPTFLAGS = -Os -fno-asynchronous-unwind-tables -fomit-frame-pointer \ - -falign-functions=0 -falign-jumps=0 -falign-loops=0 -endif -BITSIZE = 64 -LDFLAGS = -m elf_x86_64 - -# Extra linkflags when building the shared version of the library -# This address needs to be reachable using normal inter-module -# calls, and work on the memory models for this architecture -# 2 MB - normal binaries start at 4 MB -SHAREDFLAGS = -Ttext 0x00200200 - -# Additional asm- directories needed during installation -ASMARCH = asm-i386 - diff --git a/klibc/klibc/arch/x86_64/Makefile.inc b/klibc/klibc/arch/x86_64/Makefile.inc deleted file mode 100644 index 26d880d7c7..0000000000 --- a/klibc/klibc/arch/x86_64/Makefile.inc +++ /dev/null @@ -1,18 +0,0 @@ -# -*- makefile -*- -# -# arch/x86_64/Makefile.inc -# -# Special rules for this architecture. Note that this is actually -# included from the main Makefile, and that pathnames should be -# accordingly. -# - -ARCHOBJS = \ - arch/$(ARCH)/exits.o \ - arch/$(ARCH)/setjmp.o \ - arch/$(ARCH)/syscall.o \ - arch/$(ARCH)/sigreturn.o - -ARCHSOOBJS = $(patsubst %.o,%.lo,$(ARCHOBJS)) - -archclean: diff --git a/klibc/klibc/arch/x86_64/crt0.S b/klibc/klibc/arch/x86_64/crt0.S deleted file mode 100644 index c562708d0f..0000000000 --- a/klibc/klibc/arch/x86_64/crt0.S +++ /dev/null @@ -1,22 +0,0 @@ -# -# arch/x86_64/crt0.S -# -# Does arch-specific initialization and invokes __libc_init -# with the appropriate arguments. -# -# See __static_init.c or __shared_init.c for the expected -# arguments. -# - - .text - .align 4 - .type _start,@function - .globl _start -_start: - movq %rsp,%rdi # Offset of the ELF data structure - movq %rdx,%rsi # The atexit() pointer (if any) - call __libc_init - # We should never get here... - hlt - - .size _start,.-_start diff --git a/klibc/klibc/arch/x86_64/exits.S b/klibc/klibc/arch/x86_64/exits.S deleted file mode 100644 index 618f4fb585..0000000000 --- a/klibc/klibc/arch/x86_64/exits.S +++ /dev/null @@ -1,35 +0,0 @@ -# -# exit and _exit get included in *every* program, and gcc generates -# horrible code for them. Yes, this only saves a few bytes, but -# it does it in every program. -# - -#include - - .data - .align 8 - .globl __exit_handler - .type __exit_handler,@object -__exit_handler: - .quad _exit - .size __exit_handler,8 - - .text - .align 8 - .globl exit - .type exit,@function -exit: - jmp *(__exit_handler) - .size exit,.-exit - - /* No need to save any registers... we're exiting! */ - .text - .align 4 - .globl _exit - .type _exit,@function -_exit: - movl $__NR_exit,%eax - /* The argument is already in %rdi */ - syscall - .size _exit,.-exit - diff --git a/klibc/klibc/arch/x86_64/setjmp.S b/klibc/klibc/arch/x86_64/setjmp.S deleted file mode 100644 index 45f547b404..0000000000 --- a/klibc/klibc/arch/x86_64/setjmp.S +++ /dev/null @@ -1,54 +0,0 @@ -# -# arch/x86_64/setjmp.S -# -# setjmp/longjmp for the x86-64 architecture -# - -# -# The jmp_buf is assumed to contain the following, in order: -# %rbx -# %rsp (post-return) -# %rbp -# %r12 -# %r13 -# %r14 -# %r15 -# -# - - .text - .align 4 - .globl setjmp - .type setjmp, @function -setjmp: - pop %rsi # Return address, and adjust the stack - xorl %eax,%eax # Return value - movq %rbx,(%rdi) - movq %rsp,8(%rdi) # Post-return %rsp! - push %rsi # Make the call/return stack happy - movq %rbp,16(%rdi) - movq %r12,24(%rdi) - movq %r13,32(%rdi) - movq %r14,40(%rdi) - movq %r15,48(%rdi) - movq %rsi,56(%rdi) # Return address - ret - - .size setjmp,.-setjmp - - .text - .align 4 - .globl longjmp - .type longjmp, @function -longjmp: - movl %esi,%eax # Return value (int) - movq (%rdi),%rbx - movq 8(%rdi),%rsp - movq 16(%rdi),%rbp - movq 24(%rdi),%r12 - movq 32(%rdi),%r13 - movq 40(%rdi),%r14 - movq 48(%rdi),%r15 - jmp *56(%rdi) - - .size longjmp,.-longjmp diff --git a/klibc/klibc/arch/x86_64/sigreturn.S b/klibc/klibc/arch/x86_64/sigreturn.S deleted file mode 100644 index 66e7152344..0000000000 --- a/klibc/klibc/arch/x86_64/sigreturn.S +++ /dev/null @@ -1,15 +0,0 @@ -/* - * arch/x86_64/sigreturn.S - */ - -#include - - .text - .align 4 - .globl __sigreturn - .type __sigreturn,@function -__sigreturn: - movl $__NR_rt_sigreturn,%eax - syscall - - .size __sigreturn,.-__sigreturn diff --git a/klibc/klibc/arch/x86_64/syscall.S b/klibc/klibc/arch/x86_64/syscall.S deleted file mode 100644 index 17977978b9..0000000000 --- a/klibc/klibc/arch/x86_64/syscall.S +++ /dev/null @@ -1,28 +0,0 @@ -/* - * arch/x86-64/syscall.S - * - * Common tail-handling code for system calls. - * - * The arguments are in the standard argument registers; the system - * call number in %eax. - */ - .text - .align 4 - .globl __syscall_common - .type __syscall_common,@function -__syscall_common: - movq %rcx,%r10 # The kernel uses %r10 istf %rcx - syscall - - cmpq $-4095,%rax - jnb 1f - ret - - # Error return, must set errno -1: - negl %eax - movl %eax,errno(%rip) # errno is type int, so 32 bits - orq $-1,%rax # orq $-1 smaller than movq $-1 - ret - - .size __syscall_common,.-__syscall_common diff --git a/klibc/klibc/arch/x86_64/sysstub.ph b/klibc/klibc/arch/x86_64/sysstub.ph deleted file mode 100644 index e2d797b166..0000000000 --- a/klibc/klibc/arch/x86_64/sysstub.ph +++ /dev/null @@ -1,23 +0,0 @@ -# -*- perl -*- -# -# arch/x86_64/sysstub.ph -# -# Script to generate system call stubs -# - -sub make_sysstub($$$$$@) { - my($outputdir, $fname, $type, $sname, $stype, @args) = @_; - - open(OUT, '>', "${outputdir}/${fname}.S"); - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.type ${fname},\@function\n"; - print OUT "\t.globl ${fname}\n"; - print OUT "${fname}:\n"; - print OUT "\tmovl \$__NR_${sname},%eax\n"; # Zero-extends to 64 bits - print OUT "\tjmp __syscall_common\n"; - print OUT "\t.size ${fname},.-${fname}\n"; - close(OUT); -} - -1; diff --git a/klibc/klibc/asprintf.c b/klibc/klibc/asprintf.c deleted file mode 100644 index 6002b576e1..0000000000 --- a/klibc/klibc/asprintf.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * asprintf.c - */ - -#include -#include -#include - -int asprintf(char **bufp, const char *format, ...) -{ - va_list ap, ap1; - int rv; - int bytes; - char *p; - - va_start(ap, format); - va_copy(ap1, ap); - - bytes = vsnprintf(NULL, 0, format, ap1) + 1; - va_end(ap1); - - *bufp = p = malloc(bytes); - if ( !p ) - return -1; - - rv = vsnprintf(p, bytes, format, ap); - va_end(ap); - - return rv; -} diff --git a/klibc/klibc/assert.c b/klibc/klibc/assert.c deleted file mode 100644 index 6d3ff238c9..0000000000 --- a/klibc/klibc/assert.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * assert.c - */ - -#include -#include -#include - -void __assert_fail(const char *expr, const char *file, unsigned int line) -{ - printf("Assertion %s failed, file %s, line %u\n", expr, file, line); - abort(); -} diff --git a/klibc/klibc/atexit.c b/klibc/klibc/atexit.c deleted file mode 100644 index 078dd8b211..0000000000 --- a/klibc/klibc/atexit.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * atexit.c - */ - -#include - -int atexit(void (*fctn)(void)) -{ - return on_exit((void (*)(int, void *))fctn, NULL); -} diff --git a/klibc/klibc/atexit.h b/klibc/klibc/atexit.h deleted file mode 100644 index 792141def5..0000000000 --- a/klibc/klibc/atexit.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * atexit.h - * - * atexit()/on_exit() internal definitions - */ - -#ifndef ATEXIT_H -#define ATEXIT_H - -struct atexit { - void (*fctn)(int, void *); - void *arg; /* on_exit() parameter */ - struct atexit *next; -}; - -#endif /* ATEXIT_H */ - diff --git a/klibc/klibc/atoi.c b/klibc/klibc/atoi.c deleted file mode 100644 index a6ec0bf778..0000000000 --- a/klibc/klibc/atoi.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE int -#define NAME atoi -#include "atox.c" diff --git a/klibc/klibc/atol.c b/klibc/klibc/atol.c deleted file mode 100644 index e65484e7f1..0000000000 --- a/klibc/klibc/atol.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE long -#define NAME atol -#include "atox.c" diff --git a/klibc/klibc/atoll.c b/klibc/klibc/atoll.c deleted file mode 100644 index 25df79e1bf..0000000000 --- a/klibc/klibc/atoll.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE long long -#define NAME atoll -#include "atox.c" diff --git a/klibc/klibc/atox.c b/klibc/klibc/atox.c deleted file mode 100644 index 56f8d93b40..0000000000 --- a/klibc/klibc/atox.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * atox.c - * - * atoi(), atol(), atoll() - */ - -#include -#include -#include - -TYPE NAME (const char *nptr) -{ - return (TYPE) strntoumax(nptr, (char **)NULL, 10, ~(size_t)0); -} diff --git a/klibc/klibc/brk.c b/klibc/klibc/brk.c deleted file mode 100644 index 0a08c4e1c5..0000000000 --- a/klibc/klibc/brk.c +++ /dev/null @@ -1,24 +0,0 @@ -/* brk.c - Change data segment size */ - -/* Written 2000 by Werner Almesberger */ - - -#include -#include -#include - -char *__current_brk; /* Common with sbrk.c */ - -/* - * The Linux brk() isn't what most people expect, so we call the - * system call __brk() and provide a wrapper. - */ -int brk(void *end_data_segment) -{ - char *new_brk; - - new_brk = __brk(end_data_segment); - if (new_brk != end_data_segment) return -1; - __current_brk = new_brk; - return 0; -} diff --git a/klibc/klibc/bsd_signal.c b/klibc/klibc/bsd_signal.c deleted file mode 100644 index 9acc867a36..0000000000 --- a/klibc/klibc/bsd_signal.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * bsd_signal.c - */ - -#include - -__sighandler_t bsd_signal(int signum, __sighandler_t handler) -{ - /* BSD signal() semantics */ - return __signal(signum, handler, SA_RESTART); -} diff --git a/klibc/klibc/calloc.c b/klibc/klibc/calloc.c deleted file mode 100644 index 228a1b70e4..0000000000 --- a/klibc/klibc/calloc.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * calloc.c - */ - -#include -#include - -/* FIXME: This should look for multiplication overflow */ - -void *calloc(size_t nmemb, size_t size) -{ - void *ptr; - - size *= nmemb; - ptr = malloc(size); - if ( ptr ) - memset(ptr, 0, size); - - return ptr; -} - diff --git a/klibc/klibc/closelog.c b/klibc/klibc/closelog.c deleted file mode 100644 index 2359d4f92b..0000000000 --- a/klibc/klibc/closelog.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * closelog.c - */ - -#include -#include - -extern int __syslog_fd; - -void closelog(void) -{ - int logfd = __syslog_fd; - - if ( logfd != -1 ) { - close(logfd); - __syslog_fd = -1; - } -} diff --git a/klibc/klibc/creat.c b/klibc/klibc/creat.c deleted file mode 100644 index 9bd22172d4..0000000000 --- a/klibc/klibc/creat.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * creat.c - */ - -#include -#include -#include - -int creat(const char *pathname, mode_t mode) -{ - return open(pathname, O_CREAT|O_WRONLY|O_TRUNC, mode); -} diff --git a/klibc/klibc/ctypes.c b/klibc/klibc/ctypes.c deleted file mode 100644 index acfa05ab65..0000000000 --- a/klibc/klibc/ctypes.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * ctypes.c - * - * This is the array that defines classes. - * This assumes ISO 8859-1. - */ - -#include - -const unsigned char __ctypes[257] = { - 0, /* EOF */ - - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl|__ctype_space, /* BS */ - __ctype_cntrl|__ctype_space, /* TAB */ - __ctype_cntrl|__ctype_space, /* LF */ - __ctype_cntrl|__ctype_space, /* VT */ - __ctype_cntrl|__ctype_space, /* FF */ - __ctype_cntrl|__ctype_space, /* CR */ - __ctype_cntrl, /* control character */ - - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - - __ctype_print|__ctype_space, /* space */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_digit|__ctype_xdigit, /* digit */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ - __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ - __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ - __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ - __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ - __ctype_print|__ctype_upper|__ctype_xdigit, /* A-F */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_upper, /* G-Z */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ - __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ - __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ - __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ - __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ - __ctype_print|__ctype_lower|__ctype_xdigit, /* a-f */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_lower, /* g-z */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_cntrl, /* control character */ - - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - __ctype_cntrl, /* control character */ - - __ctype_print|__ctype_space, /* NBSP */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_punct, /* punctuation */ - - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_upper, /* upper accented */ - __ctype_print|__ctype_lower, /* lower accented */ - - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_punct, /* punctuation */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ - __ctype_print|__ctype_lower, /* lower accented */ -}; diff --git a/klibc/klibc/daemon.c b/klibc/klibc/daemon.c deleted file mode 100644 index 75d7146205..0000000000 --- a/klibc/klibc/daemon.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * daemon.c - "daemonize" a process - */ - -#include -#include -#include - -int daemon(int nochdir, int noclose) -{ - int nullfd; - pid_t f; - - if ( !nochdir ) { - if ( chdir("/") ) - return -1; - } - - if ( !noclose ) { - if ( (nullfd = open("/dev/null", O_RDWR)) < 0 || - dup2(nullfd, 0) < 0 || - dup2(nullfd, 1) < 0 || - dup2(nullfd, 2) < 0 ) - return -1; - close(nullfd); - } - - f = fork(); - if ( f < 0 ) - return -1; - else if ( f > 0 ) - _exit(0); - - - return setsid(); -} - - diff --git a/klibc/klibc/exec_l.c b/klibc/klibc/exec_l.c deleted file mode 100644 index cdae11e981..0000000000 --- a/klibc/klibc/exec_l.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * exec_l.c - * - * Common implementation of execl() execle() execlp() - */ - -#include -#include -#include - -int NAME (const char *path, const char *arg0, ...) -{ - va_list ap, cap; - int argc = 1, rv; - const char **argv, **argp; - const char *arg; -#if EXEC_E - char * const * envp; -#else -#define envp environ -#endif - - va_start(ap, arg0); - va_copy(cap, ap); - - /* Count the number of arguments */ - do { - arg = va_arg(cap, const char *); - argc++; - } while ( arg ); - - va_end(cap); - - /* Allocate memory for the pointer array */ - argp = argv = alloca(argc*sizeof(const char *)); - if ( !argv ) { - va_end(ap); - return -1; - } - - /* Copy the list into an array */ - *argp++ = arg0; - do { - *argp++ = arg = va_arg(ap, const char *); - } while ( arg ); - -#if EXEC_E - /* execle() takes one more argument for the environment pointer */ - envp = va_arg(ap, char * const *); -#endif - - rv = (EXEC_P ? execvpe : execve)(path, (char * const *)argv, envp); - - va_end(ap); - - return rv; -} diff --git a/klibc/klibc/execl.c b/klibc/klibc/execl.c deleted file mode 100644 index 4581113ba5..0000000000 --- a/klibc/klibc/execl.c +++ /dev/null @@ -1,8 +0,0 @@ -/* - * execl.c - */ - -#define NAME execl -#define EXEC_P 0 -#define EXEC_E 0 -#include "exec_l.c" diff --git a/klibc/klibc/execle.c b/klibc/klibc/execle.c deleted file mode 100644 index b073988835..0000000000 --- a/klibc/klibc/execle.c +++ /dev/null @@ -1,8 +0,0 @@ -/* - * execle.c - */ - -#define NAME execle -#define EXEC_P 0 -#define EXEC_E 1 -#include "exec_l.c" diff --git a/klibc/klibc/execlp.c b/klibc/klibc/execlp.c deleted file mode 100644 index 65c9aa4a7a..0000000000 --- a/klibc/klibc/execlp.c +++ /dev/null @@ -1,8 +0,0 @@ -/* - * execlp.c - */ - -#define NAME execlp -#define EXEC_P 1 -#define EXEC_E 0 -#include "exec_l.c" diff --git a/klibc/klibc/execlpe.c b/klibc/klibc/execlpe.c deleted file mode 100644 index fef972fcb3..0000000000 --- a/klibc/klibc/execlpe.c +++ /dev/null @@ -1,8 +0,0 @@ -/* - * execlpe.c - */ - -#define NAME execlpe -#define EXEC_P 1 -#define EXEC_E 1 -#include "exec_l.c" diff --git a/klibc/klibc/execv.c b/klibc/klibc/execv.c deleted file mode 100644 index 9856b76d87..0000000000 --- a/klibc/klibc/execv.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * execv.c - */ - -#include -#include - -int execv(const char *path, char * const * argv) -{ - return execve(path, argv, environ); -} - - diff --git a/klibc/klibc/execvp.c b/klibc/klibc/execvp.c deleted file mode 100644 index b1065ee47e..0000000000 --- a/klibc/klibc/execvp.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * execvp.c - */ - -#include -#include - -int execvp(const char *path, char * const * argv) -{ - return execvpe(path, argv, environ); -} - - diff --git a/klibc/klibc/execvpe.c b/klibc/klibc/execvpe.c deleted file mode 100644 index fcd5b6fd4a..0000000000 --- a/klibc/klibc/execvpe.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * execvpe.c - * - * execvpe() function (from which we build execlp, execlpe, execvp). - * - * This version of execvpe() will *not* spawn /bin/sh if the command - * return ENOEXEC. That's what #! is for, folks! - * - * Since execlpe() and execvpe() aren't in POSIX, nor in glibc, - * I have followed QNX precedent in the implementation of the PATH: - * the PATH that is used is the one in the current environment, not - * in the new environment. Otherwise it would be impossible to pass - * a different PATH to the new process than the one one would want to - * use to search. - */ - -#include -#include -#include -#include -#include - -#define DEFAULT_PATH "/bin:/usr/bin:." - -int execvpe(const char *file, char * const *argv, char * const *envp) -{ - char path[PATH_MAX]; - const char *searchpath, *esp; - size_t prefixlen, filelen, totallen; - - if ( strchr(file, '/') ) /* Specific path */ - return execve(file, argv, envp); - - filelen = strlen(file); - - searchpath = getenv("PATH"); - if ( !searchpath ) - searchpath = DEFAULT_PATH; - - errno = ENOENT; /* Default errno, if execve() doesn't change it */ - - do { - esp = strchr(searchpath, ':'); - if ( esp ) - prefixlen = esp-searchpath; - else - prefixlen = strlen(searchpath); - - if ( prefixlen == 0 || searchpath[prefixlen-1] == '/' ) { - totallen = prefixlen+filelen; - if ( totallen >= PATH_MAX ) - continue; - memcpy(path, searchpath, prefixlen); - memcpy(path+prefixlen, file, filelen); - } else { - totallen = prefixlen+filelen+1; - if ( totallen >= PATH_MAX ) - continue; - memcpy(path, searchpath, prefixlen); - path[prefixlen] = '/'; - memcpy(path+prefixlen+1, file, filelen); - } - path[totallen] = '\0'; - - execve(path, argv, envp); - if ( errno == E2BIG || errno == ENOEXEC || - errno == ENOMEM || errno == ETXTBSY ) - break; /* Report this as an error, no more search */ - - searchpath = esp+1; - } while ( esp ); - - return -1; -} - diff --git a/klibc/klibc/exitc.c b/klibc/klibc/exitc.c deleted file mode 100644 index 8819737fb7..0000000000 --- a/klibc/klibc/exitc.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * exit.c - * - * Implement exit() - */ - -#include -#include -#include - -/* We have an assembly version for i386 and x86-64 */ - -#if !defined(__i386__) && !defined(__x86_64__) - -/* This allows atexit/on_exit to install a hook */ -__noreturn (*__exit_handler)(int) = _exit; - -__noreturn exit(int rv) -{ - __exit_handler(rv); -} - -#endif diff --git a/klibc/klibc/fgetc.c b/klibc/klibc/fgetc.c deleted file mode 100644 index 83eee16f61..0000000000 --- a/klibc/klibc/fgetc.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * fgetc.c - * - * Extremely slow fgetc implementation, using _fread(). If people - * actually need character-oriented input to be fast, we may actually - * have to implement buffering. Sigh. - */ - -#include -#include -#include -#include - -int fgetc(FILE *f) -{ - unsigned char ch; - - return (_fread(&ch, 1, f) == 1) ? (int)ch : EOF; -} - diff --git a/klibc/klibc/fgets.c b/klibc/klibc/fgets.c deleted file mode 100644 index 72f8a13cf1..0000000000 --- a/klibc/klibc/fgets.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * fgets.c - * - * This will be very slow due to the implementation of getc(), - * but we can't afford to drain characters we don't need from - * the input. - */ - -#include - -char *fgets(char *s, int n, FILE *f) -{ - int ch; - char *p = s; - - while ( n > 1 ) { - ch = getc(f); - if ( ch == EOF ) { - *p = '\0'; - return NULL; - } - *p++ = ch; - n--; - if ( ch == '\n' ) - break; - } - if ( n ) - *p = '\0'; - - return s; -} - - - diff --git a/klibc/klibc/fopen.c b/klibc/klibc/fopen.c deleted file mode 100644 index ee62c68bd7..0000000000 --- a/klibc/klibc/fopen.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * fopen.c - */ - -#include -#include -#include - -/* This depends on O_RDONLY == 0, O_WRONLY == 1, O_RDWR == 2 */ - - -FILE *fopen(const char *file, const char *mode) -{ - int flags = O_RDONLY; - int plus = 0; - - while ( *mode ) { - switch ( *mode++ ) { - case 'r': - flags = O_RDONLY; - break; - case 'w': - flags = O_WRONLY|O_CREAT|O_TRUNC; - break; - case 'a': - flags = O_WRONLY|O_CREAT|O_APPEND; - break; - case '+': - plus = 1; - break; - } - } - - if ( plus ) { - flags = (flags & ~(O_RDONLY|O_WRONLY)) | O_RDWR; - } - - /* Note: __create_file(-1) == NULL, so this is safe */ - return __create_file(open(file, flags, 0666)); -} diff --git a/klibc/klibc/fork.c b/klibc/klibc/fork.c deleted file mode 100644 index fcd73bd60b..0000000000 --- a/klibc/klibc/fork.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * fork.c - * - * This is normally just a syscall stub, but at least one system - * doesn't have sys_fork, only sys_clone... - */ - -#include -#include -#include -#include - -#ifndef __NR_fork - -pid_t fork(void) -{ - return __clone(SIGCHLD, 0); -} - -#endif /* __NR_fork */ diff --git a/klibc/klibc/fprintf.c b/klibc/klibc/fprintf.c deleted file mode 100644 index df3823eac3..0000000000 --- a/klibc/klibc/fprintf.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * fprintf.c - */ - -#include -#include - -#define BUFFER_SIZE 16384 - -int fprintf(FILE *file, const char *format, ...) -{ - va_list ap; - int rv; - - va_start(ap, format); - rv = vfprintf(file, format, ap); - va_end(ap); - return rv; -} diff --git a/klibc/klibc/fputc.c b/klibc/klibc/fputc.c deleted file mode 100644 index 61aff1644b..0000000000 --- a/klibc/klibc/fputc.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * fputc.c - * - * gcc "printf decompilation" expects this to exist... - */ - -#include - -int fputc(int c, FILE *f) -{ - unsigned char ch = c; - - return _fwrite(&ch, 1, f) == 1 ? ch : EOF; -} diff --git a/klibc/klibc/fputs.c b/klibc/klibc/fputs.c deleted file mode 100644 index 4b68f96886..0000000000 --- a/klibc/klibc/fputs.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * fputs.c - * - * This isn't quite fputs() in the stdio sense, since we don't - * have stdio, but it takes a file descriptor argument instead - * of the FILE *. - */ - -#include -#include - -int fputs(const char *s, FILE *file) -{ - return _fwrite(s, strlen(s), file); -} diff --git a/klibc/klibc/fread.c b/klibc/klibc/fread.c deleted file mode 100644 index a49f0d8210..0000000000 --- a/klibc/klibc/fread.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * fread.c - */ - -#include -#include -#include - -size_t _fread(void *buf, size_t count, FILE *f) -{ - size_t bytes = 0; - ssize_t rv; - char *p = buf; - - while ( count ) { - rv = read(fileno(f), p, count); - if ( rv == -1 ) { - if ( errno == EINTR ) { - errno = 0; - continue; - } else - break; - } else if ( rv == 0 ) { - break; - } - - p += rv; - bytes += rv; - count -= rv; - } - - return bytes; -} - - - diff --git a/klibc/klibc/fread2.c b/klibc/klibc/fread2.c deleted file mode 100644 index 9e5ac81fc2..0000000000 --- a/klibc/klibc/fread2.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * fread2.c - * - * The actual fread() function as a non-inline - */ - -#define __NO_FREAD_FWRITE_INLINES -#include - -size_t fread(void *ptr, size_t size, size_t nmemb, FILE *f) -{ - return _fread(ptr, size*nmemb, f)/size; -} diff --git a/klibc/klibc/fstatfs.c b/klibc/klibc/fstatfs.c deleted file mode 100644 index 09e4674947..0000000000 --- a/klibc/klibc/fstatfs.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * fstatfs.c - * - * On architectures which do fstatfs64, wrap the system call - */ - -#include -#include - -#ifdef __NR_fstatfs64 - -extern int __fstatfs64(int, size_t, struct statfs *); - -int fstatfs(int fd, struct statfs *buf) -{ - return __fstatfs64(fd, sizeof *buf, buf); -} - -#endif diff --git a/klibc/klibc/fwrite.c b/klibc/klibc/fwrite.c deleted file mode 100644 index ad61c86b88..0000000000 --- a/klibc/klibc/fwrite.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * fwrite.c - */ - -#include -#include -#include - -size_t _fwrite(const void *buf, size_t count, FILE *f) -{ - size_t bytes = 0; - ssize_t rv; - const char *p = buf; - - while ( count ) { - rv = write(fileno(f), p, count); - if ( rv == -1 ) { - if ( errno == EINTR ) { - errno = 0; - continue; - } else - break; - } else if ( rv == 0 ) { - break; - } - - p += rv; - bytes += rv; - count -= rv; - } - - return bytes; -} - - - diff --git a/klibc/klibc/fwrite2.c b/klibc/klibc/fwrite2.c deleted file mode 100644 index 82ec832be4..0000000000 --- a/klibc/klibc/fwrite2.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * fwrite2.c - * - * The actual fwrite() function as a non-inline - */ - -#define __NO_FREAD_FWRITE_INLINES -#include - -size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *f) -{ - return _fwrite(ptr, size*nmemb, f)/size; -} diff --git a/klibc/klibc/getcwd.c b/klibc/klibc/getcwd.c deleted file mode 100644 index 613ca0529c..0000000000 --- a/klibc/klibc/getcwd.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * getcwd.c - * - * The system call behaves differently than the library function. - */ - -#include -#include - -extern int __getcwd(char * buf, size_t size); - -char *getcwd(char *buf, size_t size) -{ - return ( __getcwd(buf, size) < 0 ) ? NULL : buf; -} - diff --git a/klibc/klibc/getdomainname.c b/klibc/klibc/getdomainname.c deleted file mode 100644 index 4cd68a3cb5..0000000000 --- a/klibc/klibc/getdomainname.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * getdomainname.c - */ - -#include -#include -#include -#include - -int getdomainname(char *name, size_t len) -{ - struct utsname un; - - if ( !uname(&un) ) - return -1; - - if ( len < strlen(un.domainname)+1 ) { - errno = EINVAL; - return -1; - } - - strcpy(name, un.domainname); - - return 0; -} diff --git a/klibc/klibc/getenv.c b/klibc/klibc/getenv.c deleted file mode 100644 index 84fc94c00e..0000000000 --- a/klibc/klibc/getenv.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * getenv.c - */ - -#include -#include -#include - -char *getenv(const char *name) -{ - char **p, *q; - int len = strlen(name); - - for ( p = environ ; (q = *p) ; p++ ) { - if ( !strncmp(name, q, len) && q[len] == '=' ) { - return q+(len+1); - } - } - - return NULL; -} - diff --git a/klibc/klibc/gethostname.c b/klibc/klibc/gethostname.c deleted file mode 100644 index 6c5062e816..0000000000 --- a/klibc/klibc/gethostname.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * gethostname.c - */ - -#include -#include -#include -#include - -int gethostname(char *name, size_t len) -{ - struct utsname un; - - if ( !uname(&un) ) - return -1; - - if ( len < strlen(un.nodename)+1 ) { - errno = EINVAL; - return -1; - } - - strcpy(name, un.nodename); - - return 0; -} diff --git a/klibc/klibc/getopt.c b/klibc/klibc/getopt.c deleted file mode 100644 index cd534bf304..0000000000 --- a/klibc/klibc/getopt.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * getopt.c - * - * Simple POSIX getopt(), no GNU extensions... - */ - -#include -#include -#include - -char *optarg; -int optind = 1; -int opterr, optopt; -static const char *__optptr; - -int getopt(int argc, char * const *argv, const char *optstring) -{ - const char *carg = argv[optind]; - const char *osptr; - int opt; - - /* We don't actually need argc */ - (void)argc; - - /* First, eliminate all non-option cases */ - - if ( !carg || carg[0] != '-' || !carg[1] ) { - return -1; - } - - if ( carg[1] == '-' && !carg[2] ) { - optind++; - return -1; - } - - if ( (uintptr_t)(__optptr-carg) > (uintptr_t)strlen(carg) ) - __optptr = carg+1; /* Someone frobbed optind, change to new opt. */ - - opt = *__optptr++; - - if ( opt != ':' && (osptr = strchr(optstring, opt)) ) { - if ( osptr[1] == ':' ) { - if ( *__optptr ) { - /* Argument-taking option with attached argument */ - optarg = (char *)__optptr; - optind++; - } else { - /* Argument-taking option with non-attached argument */ - if ( argv[optind+1] ) { - optarg = (char *)argv[optind+1]; - optind += 2; - } else { - /* Missing argument */ - optind++; - return (optstring[0] == ':') ? ':' : '?'; - } - } - return opt; - } else { - /* Non-argument-taking option */ - /* __optptr will remember the exact position to resume at */ - if ( ! *__optptr ) - optind++; - return opt; - } - } else { - /* Unknown option */ - optopt = opt; - if ( ! *__optptr ) - optind++; - return '?'; - } -} - - diff --git a/klibc/klibc/getpgrp.c b/klibc/klibc/getpgrp.c deleted file mode 100644 index c92369807b..0000000000 --- a/klibc/klibc/getpgrp.c +++ /dev/null @@ -1,9 +0,0 @@ -/* - * getpgrp.c - */ - -#include - -pid_t getpgrp(void) { - return getpgid(0); -} diff --git a/klibc/klibc/getpriority.c b/klibc/klibc/getpriority.c deleted file mode 100644 index 4ea630487d..0000000000 --- a/klibc/klibc/getpriority.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * getpriority.c - * - * Needs to do some post-syscall mangling to distinguish error returns... - * but only on some platforms. Sigh. - */ - -#include -#include -#include -#include - -#if !defined(__alpha__) && !defined(__ia64__) - -extern int __getpriority(int, int); - -int getpriority(int which, int who) -{ - int rv = __getpriority(which, who); - return ( rv < 0 ) ? rv : 20-rv; -} - -#endif diff --git a/klibc/klibc/getpt.c b/klibc/klibc/getpt.c deleted file mode 100644 index a05903062c..0000000000 --- a/klibc/klibc/getpt.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * getpt.c - * - * GNU extension to the standard Unix98 pty suite - */ - -#include -#include -#include -#include -#include -#include - -int getpt(void) -{ - return open("/dev/ptmx", O_RDWR|O_NOCTTY); -} diff --git a/klibc/klibc/globals.c b/klibc/klibc/globals.c deleted file mode 100644 index 72ae91fbad..0000000000 --- a/klibc/klibc/globals.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * globals.c - * - * These have to be defined somewhere... - */ -#include -#include - -int errno; -char **environ; diff --git a/klibc/klibc/inet/bindresvport.c b/klibc/klibc/inet/bindresvport.c deleted file mode 100644 index 750bd709c4..0000000000 --- a/klibc/klibc/inet/bindresvport.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * inet/bindresvport.c - */ - -#include -#include -#include -#include -#include -#include - -#define START_PORT 768 -#define END_PORT IPPORT_RESERVED -#define NUM_PORTS (END_PORT - START_PORT) - -int bindresvport(int sd, struct sockaddr_in *sin) -{ - struct sockaddr_in me; - static short port; - int ret = 0; - int i; - - if (sin == NULL) { - memset(&me, 0, sizeof(me)); - sin = &me; - sin->sin_family = AF_INET; - } else if (sin->sin_family != AF_INET) { - errno = EPFNOSUPPORT; - return -1; - } - - if (port == 0) { - port = START_PORT + (getpid() % NUM_PORTS); - } - - for (i = 0; i < NUM_PORTS; i++, port++) { - if (port == END_PORT) - port = START_PORT; - sin->sin_port = htons(port); - if ((ret = bind(sd, (struct sockaddr *)sin, sizeof(*sin))) != -1) - break; - } - - return ret; -} diff --git a/klibc/klibc/inet/inet_addr.c b/klibc/klibc/inet/inet_addr.c deleted file mode 100644 index e04a4d0214..0000000000 --- a/klibc/klibc/inet/inet_addr.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * inet/inet_addr.c - */ - -#include -#include - -uint32_t inet_addr(const char *str) -{ - struct in_addr a; - int rv = inet_aton(str, &a); - - return rv ? INADDR_NONE : a.s_addr; -} diff --git a/klibc/klibc/inet/inet_aton.c b/klibc/klibc/inet/inet_aton.c deleted file mode 100644 index e581b492ad..0000000000 --- a/klibc/klibc/inet/inet_aton.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * inet/inet_aton.c - */ - -#include -#include - -int inet_aton(const char *str, struct in_addr *addr) -{ - union { - uint8_t b[4]; - uint32_t l; - } a; - - if ( sscanf(str, "%hhu.%hhu.%hhu.%hhu", &a.b[0], &a.b[1], &a.b[2], &a.b[3]) == 4 ) { - addr->s_addr = a.l; /* Always in network byte order */ - return 1; - } else { - return 0; - } -} - - diff --git a/klibc/klibc/inet/inet_ntoa.c b/klibc/klibc/inet/inet_ntoa.c deleted file mode 100644 index 5340aa622a..0000000000 --- a/klibc/klibc/inet/inet_ntoa.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * inet/inet_ntoa.c - */ - -#include -#include - -char *inet_ntoa(struct in_addr addr) -{ - static char name[16]; - union { - uint8_t b[4]; - uint32_t l; - } a; - a.l = addr.s_addr; - - sprintf(name, "%u.%u.%u.%u", a.b[0], a.b[1], a.b[2], a.b[3]); - return name; -} diff --git a/klibc/klibc/inet/inet_ntop.c b/klibc/klibc/inet/inet_ntop.c deleted file mode 100644 index 377bab7bf2..0000000000 --- a/klibc/klibc/inet/inet_ntop.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * inet/inet_ntop.c - */ - -#include -#include -#include -#include -#include - -const char *inet_ntop(int af, const void *cp, char *buf, size_t len) -{ - size_t xlen; - - switch ( af ) { - case AF_INET: - { - union { - uint8_t b[4]; - uint32_t l; - } a; - a.l = ((const struct in_addr *)cp)->s_addr; - - xlen = snprintf(buf, len, "%u.%u.%u.%u", a.b[0], a.b[1], a.b[2], a.b[3]); - } - break; - - case AF_INET6: - { - const struct in6_addr *s = (const struct in6_addr *)cp; - - xlen = snprintf(buf, len, "%x:%x:%x:%x:%x:%x:%x:%x", - ntohs(s->s6_addr16[0]), ntohs(s->s6_addr16[1]), - ntohs(s->s6_addr16[2]), ntohs(s->s6_addr16[3]), - ntohs(s->s6_addr16[4]), ntohs(s->s6_addr16[5]), - ntohs(s->s6_addr16[6]), ntohs(s->s6_addr16[7])); - } - break; - - default: - errno = EAFNOSUPPORT; - return NULL; - } - - if ( xlen > len ) { - errno = ENOSPC; - return NULL; - } - - return buf; -} - diff --git a/klibc/klibc/inet/inet_pton.c b/klibc/klibc/inet/inet_pton.c deleted file mode 100644 index 6c14b3cfb6..0000000000 --- a/klibc/klibc/inet/inet_pton.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * inet/inet_pton.c - */ - -#include -#include -#include -#include -#include -#include -#include - -static inline int hexval(int ch) -{ - if ( ch >= '0' && ch <= '9' ) { - return ch-'0'; - } else if ( ch >= 'A' && ch <= 'F' ) { - return ch-'A'+10; - } else if ( ch >= 'a' && ch <= 'f' ) { - return ch-'a'+10; - } else { - return -1; - } -} - -int inet_pton(int af, const char *src, void *dst) -{ - switch ( af ) { - case AF_INET: - return inet_aton(src, (struct in_addr *)dst); - - case AF_INET6: - { - struct in6_addr *d = (struct in6_addr *)dst; - int colons = 0, dcolons = 0; - int i; - const char *p; - - /* A double colon will increment colons by 2, dcolons by 1 */ - for ( p = dst ; *p ; p++ ) { - if ( p[0] == ':' ) { - colons++; - if ( p[1] == ':' ) - dcolons++; - } else if ( !isxdigit(*p) ) - return 0; /* Not a valid address */ - } - - if ( colons > 7 || dcolons > 1 || (!dcolons && colons != 7) ) - return 0; /* Not a valid address */ - - memset(d, 0, sizeof(struct in6_addr)); - - i = 0; - for ( p = dst ; *p ; p++ ) { - if ( *p == ':' ) { - if ( p[1] == ':' ) { - i += (8-colons); - } else { - i++; - } - } else { - d->s6_addr16[i] = htons((ntohs(d->s6_addr16[i]) << 4) + hexval(*p)); - } - } - - return 1; - } - - default: - errno = EAFNOSUPPORT; - return -1; - } -} diff --git a/klibc/klibc/interp.S b/klibc/klibc/interp.S deleted file mode 100644 index b1a2701999..0000000000 --- a/klibc/klibc/interp.S +++ /dev/null @@ -1,13 +0,0 @@ -# -# This is a hack to generate the .intrp section, which then -# ld turns into an PT_INTERP header. -# -# NOTE: The .interp section needs to be "a", or it doesnt work... -# - - .section ".interp","a" - .ascii LIBDIR - .ascii "/klibc-" - .ascii SOHASH - .ascii ".so" - .byte 0 diff --git a/klibc/klibc/isatty.c b/klibc/klibc/isatty.c deleted file mode 100644 index ff5e1ff748..0000000000 --- a/klibc/klibc/isatty.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * isatty.c - */ - -#include -#include -#include - -int isatty(int fd) -{ - int old_errno = errno; - int istty; - pid_t dummy; - - /* All ttys support TIOCGPGRP */ - istty = !ioctl(fd, TIOCGPGRP, &dummy); - errno = old_errno; - - return istty; -} - diff --git a/klibc/klibc/jrand48.c b/klibc/klibc/jrand48.c deleted file mode 100644 index 660a6e5a71..0000000000 --- a/klibc/klibc/jrand48.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * jrand48.c - */ - -#include -#include - -long jrand48(unsigned short xsubi[3]) -{ - uint64_t x; - - /* The xsubi[] array is littleendian by spec */ - x = (uint64_t)(uint16_t)xsubi[0] + - ((uint64_t)(uint16_t)xsubi[1] << 16) + - ((uint64_t)(uint16_t)xsubi[2] << 32); - - x = (0x5deece66dULL * x) + 0xb; - - xsubi[0] = (unsigned short)(uint16_t)x; - xsubi[1] = (unsigned short)(uint16_t)(x >> 16); - xsubi[2] = (unsigned short)(uint16_t)(x >> 32); - - return (long)(int32_t)(x >> 16); -} diff --git a/klibc/klibc/libc_init.c b/klibc/klibc/libc_init.c deleted file mode 100644 index e91edc44a3..0000000000 --- a/klibc/klibc/libc_init.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * libc_init.c - * - * This function takes the raw data block set up by the ELF loader - * in the kernel and parses it. It is invoked by crt0.S which makes - * any necessary adjustments and passes calls this function using - * the standard C calling convention. - * - * The arguments are: - * uintptr_t *elfdata -- The ELF loader data block; usually from the stack. - * Basically a pointer to argc. - * void (*onexit)(void) -- Function to install into onexit - */ - -#include -#include -#include -#include -#include - -/* This file is included from __static_init.c or __shared_init.c */ -#ifndef SHARED -# error "SHARED should be defined to 0 or 1" -#endif - -char **environ; -unsigned int __page_size, __page_shift; - -struct auxentry { - uintptr_t type; - uintptr_t v; -}; - -__noreturn __libc_init(uintptr_t *elfdata, void (*onexit)(void)) -{ - int argc; - char **argv, **envp, **envend; - struct auxentry *auxentry; -#if SHARED - typedef int (*main_t)(int, char **, char **); - main_t MAIN = NULL; -#else - extern int main(int, char **, char **); -#define MAIN main -#endif - unsigned int page_size = 0, page_shift = 0; - - (void)onexit; /* For now, we ignore this... */ - - argc = (int)*elfdata++; - argv = (char **)elfdata; - envp = argv+(argc+1); - - /* The auxillary entry vector is after all the environment vars */ - for ( envend = envp ; *envend ; envend++ ); - auxentry = (struct auxentry *)(envend+1); - - while ( auxentry->type ) { - switch ( auxentry->type ) { -#if SHARED - case AT_ENTRY: - MAIN = (main_t)(auxentry->v); - break; -#endif - case AT_PAGESZ: - page_size = (int)(auxentry->v); - break; - } - auxentry++; - } - - __page_size = page_size; - -#if defined(__i386__) || defined(__x86_64__) - asm("bsrl %1,%0" : "=r" (page_shift) : "rm" (page_size)); -#else - while ( page_size > 1 ) { - page_shift++; - page_size >>= 1; - } -#endif - __page_shift = page_shift; - - environ = envp; - exit(MAIN(argc, argv, envp)); -} diff --git a/klibc/klibc/libgcc/__divdi3.c b/klibc/klibc/libgcc/__divdi3.c deleted file mode 100644 index be13caed7e..0000000000 --- a/klibc/klibc/libgcc/__divdi3.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/i386/libgcc/__divdi3.c - */ - -#include -#include - -extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); - -int64_t __divdi3(int64_t num, int64_t den) -{ - int minus = 0; - int64_t v; - - if ( num < 0 ) { - num = -num; - minus = 1; - } - if ( den < 0 ) { - den = -den; - minus ^= 1; - } - - v = __udivmoddi4(num, den, NULL); - if ( minus ) - v = -v; - - return v; -} diff --git a/klibc/klibc/libgcc/__divsi3.c b/klibc/klibc/libgcc/__divsi3.c deleted file mode 100644 index 24a7e044c8..0000000000 --- a/klibc/klibc/libgcc/__divsi3.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * libgcc/__divsi3.c - */ - -#include -#include - -extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); - -int32_t __divsi3(int32_t num, int32_t den) -{ - int minus = 0; - int32_t v; - - if ( num < 0 ) { - num = -num; - minus = 1; - } - if ( den < 0 ) { - den = -den; - minus ^= 1; - } - - v = __udivmodsi4(num, den, NULL); - if ( minus ) - v = -v; - - return v; -} diff --git a/klibc/klibc/libgcc/__moddi3.c b/klibc/klibc/libgcc/__moddi3.c deleted file mode 100644 index 3e613654e4..0000000000 --- a/klibc/klibc/libgcc/__moddi3.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * arch/i386/libgcc/__moddi3.c - */ - -#include -#include - -extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); - -int64_t __moddi3(int64_t num, int64_t den) -{ - int minus = 0; - int64_t v; - - if ( num < 0 ) { - num = -num; - minus = 1; - } - if ( den < 0 ) { - den = -den; - minus ^= 1; - } - - (void) __udivmoddi4(num, den, &v); - if ( minus ) - v = -v; - - return v; -} diff --git a/klibc/klibc/libgcc/__modsi3.c b/klibc/klibc/libgcc/__modsi3.c deleted file mode 100644 index cf62b8b556..0000000000 --- a/klibc/klibc/libgcc/__modsi3.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * libgcc/__modsi3.c - */ - -#include -#include - -extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); - -int32_t __modsi3(int32_t num, int32_t den) -{ - int minus = 0; - int32_t v; - - if ( num < 0 ) { - num = -num; - minus = 1; - } - if ( den < 0 ) { - den = -den; - minus ^= 1; - } - - (void) __udivmodsi4(num, den, &v); - if ( minus ) - v = -v; - - return v; -} diff --git a/klibc/klibc/libgcc/__udivdi3.c b/klibc/klibc/libgcc/__udivdi3.c deleted file mode 100644 index 901ce2aea6..0000000000 --- a/klibc/klibc/libgcc/__udivdi3.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * arch/i386/libgcc/__divdi3.c - */ - -#include -#include - -extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); - -uint64_t __udivdi3(uint64_t num, uint64_t den) -{ - return __udivmoddi4(num, den, NULL); -} diff --git a/klibc/klibc/libgcc/__udivmoddi4.c b/klibc/klibc/libgcc/__udivmoddi4.c deleted file mode 100644 index 1c456543be..0000000000 --- a/klibc/klibc/libgcc/__udivmoddi4.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem_p) -{ - uint64_t quot = 0, qbit = 1; - - if ( den == 0 ) { - __divide_error(); - return 0; /* If trap returns... */ - } - - /* Left-justify denominator and count shift */ - while ( (int64_t)den >= 0 ) { - den <<= 1; - qbit <<= 1; - } - - while ( qbit ) { - if ( den <= num ) { - num -= den; - quot += qbit; - } - den >>= 1; - qbit >>= 1; - } - - if ( rem_p ) - *rem_p = num; - - return quot; -} diff --git a/klibc/klibc/libgcc/__udivmodsi4.c b/klibc/klibc/libgcc/__udivmodsi4.c deleted file mode 100644 index 61f6bef0a4..0000000000 --- a/klibc/klibc/libgcc/__udivmodsi4.c +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include - -uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem_p) -{ - uint32_t quot = 0, qbit = 1; - - if ( den == 0 ) { - __divide_error(); - return 0; /* If trap returns... */ - } - - /* Left-justify denominator and count shift */ - while ( (int32_t)den >= 0 ) { - den <<= 1; - qbit <<= 1; - } - - while ( qbit ) { - if ( den <= num ) { - num -= den; - quot += qbit; - } - den >>= 1; - qbit >>= 1; - } - - if ( rem_p ) - *rem_p = num; - - return quot; -} diff --git a/klibc/klibc/libgcc/__udivsi3.c b/klibc/klibc/libgcc/__udivsi3.c deleted file mode 100644 index cba6f8f03d..0000000000 --- a/klibc/klibc/libgcc/__udivsi3.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * libgcc/__divsi3.c - */ - -#include -#include - -extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); - -uint32_t __udivsi3(uint32_t num, uint32_t den) -{ - return __udivmodsi4(num, den, NULL); -} diff --git a/klibc/klibc/libgcc/__umoddi3.c b/klibc/klibc/libgcc/__umoddi3.c deleted file mode 100644 index c007d4859f..0000000000 --- a/klibc/klibc/libgcc/__umoddi3.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * arch/i386/libgcc/__umoddi3.c - */ - -#include -#include - -extern uint64_t __udivmoddi4(uint64_t num, uint64_t den, uint64_t *rem); - -uint64_t __umoddi3(uint64_t num, uint64_t den) -{ - uint64_t v; - - (void) __udivmoddi4(num, den, &v); - return v; -} diff --git a/klibc/klibc/libgcc/__umodsi3.c b/klibc/klibc/libgcc/__umodsi3.c deleted file mode 100644 index e3db972c4e..0000000000 --- a/klibc/klibc/libgcc/__umodsi3.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * libgcc/__umodsi3.c - */ - -#include -#include - -extern uint32_t __udivmodsi4(uint32_t num, uint32_t den, uint32_t *rem); - -uint32_t __umodsi3(uint32_t num, uint32_t den) -{ - uint32_t v; - - (void) __udivmodsi4(num, den, &v); - return v; -} diff --git a/klibc/klibc/llseek.c b/klibc/klibc/llseek.c deleted file mode 100644 index 857490b378..0000000000 --- a/klibc/klibc/llseek.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * llseek.c - * - * On 32-bit platforms, we need to use the _llseek() system call - * rather than lseek(), to be able to handle large disks. _llseek() - * isn't just a normal syscall which takes a 64-bit argument; it needs - * to return a 64-bit value and so takes an extra pointer. - */ - -#include -#include -#include - -#if _BITSIZE == 32 - -extern int __llseek(int fd, unsigned long hi, unsigned long lo, off_t *res, int whence); - -off_t lseek(int fd, off_t offset, int whence) -{ - off_t result; - int rv; - - rv = __llseek(fd, (unsigned long)(offset >> 32), (unsigned long)offset, - &result, whence); - - return rv ? (off_t)-1 : result; -} - -#endif - diff --git a/klibc/klibc/lrand48.c b/klibc/klibc/lrand48.c deleted file mode 100644 index 8c0a3de176..0000000000 --- a/klibc/klibc/lrand48.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * lrand48.c - */ - -#include -#include - -unsigned short __rand48_seed[3]; /* Common with mrand48.c, srand48.c */ - -long lrand48(void) -{ - return (uint32_t)jrand48(__rand48_seed) >> 1; -} - diff --git a/klibc/klibc/makeerrlist.pl b/klibc/klibc/makeerrlist.pl deleted file mode 100644 index 14498d880a..0000000000 --- a/klibc/klibc/makeerrlist.pl +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/perl -# -# This creates sys_errlist from through somewhat -# heuristic matching. It presumes the relevant entries are of the form -# #define Exxxx /* comment */ -# - -use FileHandle; - -%errors = (); -%errmsg = (); -$maxerr = -1; -@includelist = (); # Include directories - -sub parse_file($) { - my($file) = @_; - my($fh) = new FileHandle; - my($line, $error, $msg); - my($kernelonly) = 0; - my($root); - - print STDERR "opening $file\n" unless ( $quiet ); - - $ok = 0; - foreach $root ( @includelist ) { - if ( $fh->open($root.'//'.$file, '<') ) { - $ok = 1; - last; - } - } - - if ( ! $ok ) { - die "$0: Cannot find file $file\n"; - } - - while ( defined($line = <$fh>) ) { - if ( $kernelonly ) { - if ( $line =~ /^\#\s*endif/ ) { - $kernelonly--; - } elsif ( $line =~ /^\#\sif/ ) { - $kernelonly++; - } - } else { - if ( $line =~ /^\#\s*define\s+([A-Z0-9_]+)\s+([0-9]+)\s*\/\*\s*(.*\S)\s*\*\// ) { - $error = $1; - $errno = $2+0; - $msg = $3; - print STDERR "$error ($errno) => \"$msg\"\n" unless ( $quiet ); - $errors{$errno} = $error; - $errmsg{$errno} = $msg; - $maxerr = $errno if ( $errno > $maxerr ); - } elsif ( $line =~ /^\#\s*include\s+[\<\"](.*)[\>\"]/ ) { - parse_file($1); - } elsif ( $line =~ /^\#\s*ifdef\s+__KERNEL__/ ) { - $kernelonly++; - } - } - } - close($fh); - print STDERR "closing $file\n" unless ( $quiet ); -} - -$v = $ENV{'KBUILD_VERBOSE'}; -$quiet = defined($v) ? !$v : 0; - -foreach $arg ( @ARGV ) { - if ( $arg eq '-q' ) { - $quiet = 1; - } elsif ( $arg =~ /^-(errlist|errnos|maxerr)$/ ) { - $type = $arg; - } elsif ( $arg =~ '^\-I' ) { - push(@includelist, "$'"); - } else { - die "$0: Unknown option: $arg\n"; - } -} - -parse_file('linux/errno.h'); - -if ( $type eq '-errlist' ) { - print "#include \n"; - printf "const int sys_nerr = %d;\n", $maxerr+1; - printf "const char * const sys_errlist[%d] = {\n", $maxerr+1; - foreach $e ( sort(keys(%errors)) ) { - printf " [%s] = \"%s\",\n", $errors{$e}, $errmsg{$e}; - } - print "};\n"; -} elsif ( $type eq '-errnos' ) { - print "#include \n"; - printf "const int sys_nerr = %d;\n", $maxerr+1; - printf "const char * const sys_errlist[%d] = {\n", $maxerr+1; - foreach $e ( sort(keys(%errors)) ) { - printf " [%s] = \"%s\",\n", $errors{$e}, $errors{$e}; - } - print "};\n"; -} elsif ( $type eq '-maxerr' ) { - print $maxerr, "\n"; -} - - diff --git a/klibc/klibc/malloc.c b/klibc/klibc/malloc.c deleted file mode 100644 index 976353c201..0000000000 --- a/klibc/klibc/malloc.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * malloc.c - * - * Very simple linked-list based malloc()/free(). - */ - -#include -#include -#include "malloc.h" - -struct free_arena_header __malloc_head = -{ - { - ARENA_TYPE_HEAD, - 0, - &__malloc_head, - &__malloc_head, - }, - &__malloc_head, - &__malloc_head -}; - -static void *__malloc_from_block(struct free_arena_header *fp, size_t size) -{ - size_t fsize; - struct free_arena_header *nfp, *na; - - fsize = fp->a.size; - - /* We need the 2* to account for the larger requirements of a free block */ - if ( fsize >= size+2*sizeof(struct arena_header) ) { - /* Bigger block than required -- split block */ - nfp = (struct free_arena_header *)((char *)fp + size); - na = fp->a.next; - - nfp->a.type = ARENA_TYPE_FREE; - nfp->a.size = fsize-size; - fp->a.type = ARENA_TYPE_USED; - fp->a.size = size; - - /* Insert into all-block chain */ - nfp->a.prev = fp; - nfp->a.next = na; - na->a.prev = nfp; - fp->a.next = nfp; - - /* Replace current block on free chain */ - nfp->next_free = fp->next_free; - nfp->prev_free = fp->prev_free; - fp->next_free->prev_free = nfp; - fp->prev_free->next_free = nfp; - } else { - /* Allocate the whole block */ - fp->a.type = ARENA_TYPE_USED; - - /* Remove from free chain */ - fp->next_free->prev_free = fp->prev_free; - fp->prev_free->next_free = fp->next_free; - } - - return (void *)(&fp->a + 1); -} - -static struct free_arena_header * -__free_block(struct free_arena_header *ah) -{ - struct free_arena_header *pah, *nah; - - pah = ah->a.prev; - nah = ah->a.next; - if ( pah->a.type == ARENA_TYPE_FREE && - (char *)pah+pah->a.size == (char *)ah ) { - /* Coalesce into the previous block */ - pah->a.size += ah->a.size; - pah->a.next = nah; - nah->a.prev = pah; - -#ifdef DEBUG_MALLOC - ah->a.type = ARENA_TYPE_DEAD; -#endif - - ah = pah; - pah = ah->a.prev; - } else { - /* Need to add this block to the free chain */ - ah->a.type = ARENA_TYPE_FREE; - - ah->next_free = __malloc_head.next_free; - ah->prev_free = &__malloc_head; - __malloc_head.next_free = ah; - ah->next_free->prev_free = ah; - } - - /* In either of the previous cases, we might be able to merge - with the subsequent block... */ - if ( nah->a.type == ARENA_TYPE_FREE && - (char *)ah+ah->a.size == (char *)nah ) { - ah->a.size += nah->a.size; - - /* Remove the old block from the chains */ - nah->next_free->prev_free = nah->prev_free; - nah->prev_free->next_free = nah->next_free; - ah->a.next = nah->a.next; - nah->a.next->a.prev = ah; - -#ifdef DEBUG_MALLOC - nah->a.type = ARENA_TYPE_DEAD; -#endif - } - - /* Return the block that contains the called block */ - return ah; -} - -void *malloc(size_t size) -{ - struct free_arena_header *fp; - struct free_arena_header *pah; - size_t fsize; - - if ( size == 0 ) - return NULL; - - /* Add the obligatory arena header, and round up */ - size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK; - - for ( fp = __malloc_head.next_free ; fp->a.type != ARENA_TYPE_HEAD ; - fp = fp->next_free ) { - if ( fp->a.size >= size ) { - /* Found fit -- allocate out of this block */ - return __malloc_from_block(fp, size); - } - } - - /* Nothing found... need to request a block from the kernel */ - fsize = (size+MALLOC_CHUNK_MASK) & ~MALLOC_CHUNK_MASK; - -#ifdef MALLOC_USING_SBRK - fp = (struct free_arena_header *) sbrk(fsize); -#else - fp = (struct free_arena_header *) - mmap(NULL, fsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); -#endif - - if ( fp == (struct free_arena_header *)MAP_FAILED ) { - return NULL; /* Failed to get a block */ - } - - /* Insert the block into the management chains. We need to set - up the size and the main block list pointer, the rest of - the work is logically identical to free(). */ - fp->a.type = ARENA_TYPE_FREE; - fp->a.size = fsize; - - /* We need to insert this into the main block list in the proper - place -- this list is required to be sorted. Since we most likely - get memory assignments in ascending order, search backwards for - the proper place. */ - for ( pah = __malloc_head.a.prev ; pah->a.type != ARENA_TYPE_HEAD ; - pah = pah->a.prev ) { - if ( pah < fp ) - break; - } - - /* Now pah points to the node that should be the predecessor of - the new node */ - fp->a.next = pah->a.next; - fp->a.prev = pah; - pah->a.next = fp; - fp->a.next->a.prev = fp; - - - /* Insert into the free chain and coalesce with adjacent blocks */ - fp = __free_block(fp); - - /* Now we can allocate from this block */ - return __malloc_from_block(fp, size); -} - -void free(void *ptr) -{ - struct free_arena_header *ah; - - if ( !ptr ) - return; - - ah = (struct free_arena_header *) - ((struct arena_header *)ptr - 1); - -#ifdef DEBUG_MALLOC - assert( ah->a.type == ARENA_TYPE_USED ); -#endif - - __free_block(ah); - - /* Here we could insert code to return memory to the system. */ -} diff --git a/klibc/klibc/malloc.h b/klibc/klibc/malloc.h deleted file mode 100644 index 456295069a..0000000000 --- a/klibc/klibc/malloc.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * malloc.h - * - * Internals for the memory allocator - */ - -#include -#include -#include - -/* - * This structure should be a power of two. This becomes the - * alignment unit. - */ -struct free_arena_header; - -struct arena_header { - size_t type; - size_t size; /* Also gives the location of the next entry */ - struct free_arena_header *next, *prev; -}; - -#ifdef DEBUG_MALLOC -#define ARENA_TYPE_USED 0x64e69c70 -#define ARENA_TYPE_FREE 0x012d610a -#define ARENA_TYPE_HEAD 0x971676b5 -#define ARENA_TYPE_DEAD 0xeeeeeeee -#else -#define ARENA_TYPE_USED 0 -#define ARENA_TYPE_FREE 1 -#define ARENA_TYPE_HEAD 2 -#endif - -#define ARENA_SIZE_MASK (~(sizeof(struct arena_header)-1)) - -/* - * This structure should be no more than twice the size of the - * previous structure. - */ -struct free_arena_header { - struct arena_header a; - struct free_arena_header *next_free, *prev_free; -}; - -extern struct free_arena_header __malloc_head; diff --git a/klibc/klibc/memccpy.c b/klibc/klibc/memccpy.c deleted file mode 100644 index 22f68deaad..0000000000 --- a/klibc/klibc/memccpy.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * memccpy.c - * - * memccpy() - */ - -#include -#include - -void *memccpy(void *dst, const void *src, int c, size_t n) -{ - char *q = dst; - const char *p = src; - char ch; - - while ( n-- ) { - *q++ = ch = *p++; - if ( ch == (char)c ) - return q; - } - - return NULL; /* No instance of "c" found */ -} diff --git a/klibc/klibc/memchr.c b/klibc/klibc/memchr.c deleted file mode 100644 index 2e5e4cc7f2..0000000000 --- a/klibc/klibc/memchr.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * memchr.c - */ - -#include -#include - -void *memchr(const void *s, int c, size_t n) -{ - const unsigned char *sp = s; - - while ( n-- ) { - if ( *sp == (unsigned char)c ) - return (void *)sp; - sp++; - } - - return NULL; -} diff --git a/klibc/klibc/memcmp.c b/klibc/klibc/memcmp.c deleted file mode 100644 index f6bc17286f..0000000000 --- a/klibc/klibc/memcmp.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * memcmp.c - */ - -#include - -int memcmp(const void *s1, const void *s2, size_t n) -{ - const unsigned char *c1 = s1, *c2 = s2; - int d = 0; - - while ( n-- ) { - d = (int)*c1++ - (int)*c2++; - if ( d ) - break; - } - - return d; -} diff --git a/klibc/klibc/memcpy.c b/klibc/klibc/memcpy.c deleted file mode 100644 index b9171c300d..0000000000 --- a/klibc/klibc/memcpy.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * memcpy.c - */ - -#include -#include - -void *memcpy(void *dst, const void *src, size_t n) -{ - const char *p = src; - char *q = dst; -#if defined(__i386__) - size_t nl = n >> 2; - asm volatile("cld ; rep ; movsl ; movl %3,%0 ; rep ; movsb" - : "+c" (nl), "+S" (p), "+D" (q) - : "r" (n & 3)); -#elif defined(__x86_64__) - size_t nq = n >> 3; - asm volatile("cld ; rep ; movsq ; movl %3,%%ecx ; rep ; movsb" - : "+c" (nq), "+S" (p), "+D" (q) - : "r" ((uint32_t)(n & 7))); -#else - while ( n-- ) { - *q++ = *p++; - } -#endif - - return dst; -} diff --git a/klibc/klibc/memmem.c b/klibc/klibc/memmem.c deleted file mode 100644 index 8b5faa0014..0000000000 --- a/klibc/klibc/memmem.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * memmem.c - * - * Find a byte string inside a longer byte string - * - * This uses the "Not So Naive" algorithm, a very simple but - * usually effective algorithm, see: - * - * http://www-igm.univ-mlv.fr/~lecroq/string/ - */ - -#include - -void *memmem(const void *haystack, size_t n, const void *needle, size_t m) -{ - const unsigned char *y = (const unsigned char *)haystack; - const unsigned char *x = (const unsigned char *)needle; - - size_t j, k, l; - - if (m > n || !m || !n) - return NULL; - - if (1 != m) { - if (x[0] == x[1]) { - k = 2; - l = 1; - } else { - k = 1; - l = 2; - } - - j = 0; - while (j <= n - m) { - if (x[1] != y[j + 1]) { - j += k; - } else { - if (!memcmp(x + 2, y + j + 2, m - 2) - && x[0] == y[j]) - return (void *)&y[j]; - j += l; - } - } - } else - do { - if (*y == *x) - return (void *)y; - y++; - } while (--n); - - return NULL; -} diff --git a/klibc/klibc/memmove.c b/klibc/klibc/memmove.c deleted file mode 100644 index c1f042af39..0000000000 --- a/klibc/klibc/memmove.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * memmove.c - */ - -#include - -void *memmove(void *dst, const void *src, size_t n) -{ - const char *p = src; - char *q = dst; -#if defined(__i386__) || defined(__x86_64__) - if ( q < p ) { - asm volatile("cld ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q)); - } else { - p += (n-1); - q += (n-1); - asm volatile("std ; rep ; movsb" : "+c" (n), "+S" (p), "+D" (q)); - } -#else - if ( q < p ) { - while ( n-- ) { - *q++ = *p++; - } - } else { - p += n; - q += n; - while ( n-- ) { - *--q = *--p; - } - } -#endif - - return dst; -} diff --git a/klibc/klibc/memrchr.c b/klibc/klibc/memrchr.c deleted file mode 100644 index 10d9c29851..0000000000 --- a/klibc/klibc/memrchr.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * memrchr.c - */ - -#include -#include - -void *memrchr(const void *s, int c, size_t n) -{ - const unsigned char *sp = - (const unsigned char *)s + n - 1; - - while ( n-- ) { - if ( *sp == (unsigned char)c ) - return (void *)sp; - sp--; - } - - return NULL; -} diff --git a/klibc/klibc/memset.c b/klibc/klibc/memset.c deleted file mode 100644 index 522cc59a1e..0000000000 --- a/klibc/klibc/memset.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * memset.c - */ - -#include -#include - -void *memset(void *dst, int c, size_t n) -{ - char *q = dst; - -#if defined(__i386__) - size_t nl = n >> 2; - asm volatile("cld ; rep ; stosl ; movl %3,%0 ; rep ; stosb" - : "+c" (nl), "+D" (q) - : "a" ((unsigned char)c * 0x01010101U), "r" (n & 3)); -#elif defined(__x86_64__) - size_t nq = n >> 3; - asm volatile("cld ; rep ; stosq ; movl %3,%%ecx ; rep ; stosb" - : "+c" (nq), "+D" (q) - : "a" ((unsigned char)c * 0x0101010101010101U), - "r" ((uint32_t)n & 7)); -#else - while ( n-- ) { - *q++ = c; - } -#endif - - return dst; -} diff --git a/klibc/klibc/memswap.c b/klibc/klibc/memswap.c deleted file mode 100644 index 10440e3499..0000000000 --- a/klibc/klibc/memswap.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * memswap() - * - * Swaps the contents of two nonoverlapping memory areas. - * This really could be done faster... - */ - -#include - -void memswap(void *m1, void *m2, size_t n) -{ - char *p = m1; - char *q = m2; - char tmp; - - while ( n-- ) { - tmp = *p; - *p = *q; - *q = tmp; - - p++; q++; - } -} diff --git a/klibc/klibc/mmap.c b/klibc/klibc/mmap.c deleted file mode 100644 index 11c540aed6..0000000000 --- a/klibc/klibc/mmap.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * mmap.c - */ - -#include -#include -#include -#include -#include -#include /* For PAGE_SHIFT */ -#include - -/* - * MMAP2_SHIFT is definitely *NOT* equal to getpageshift() for - * many 32-bit architectures. Supposedly this is fixed to 12 - * for all 32-bit architectures. CHECK THIS!!! - */ -# define MMAP2_SHIFT 12 /* Fixed by syscall definition */ - -/* - * Set in SYSCALLS whether or not we should use an unadorned mmap() system - * call (typical on 64-bit architectures). - */ -#if (_BITSIZE == 32 && defined(__NR_mmap2)) || (_BITSIZE == 64 && !defined(__NR_mmap)) - -/* This architecture uses mmap2(). The Linux mmap2() system call takes - a page offset as the offset argument. We need to make sure we have - the proper conversion in place. */ - -extern void *__mmap2(void *, size_t, int, int, int, size_t); - -void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) -{ - const int mmap2_shift = MMAP2_SHIFT; - const unsigned long mmap2_mask = (1UL << mmap2_shift) - 1; - - if ( offset & mmap2_mask ) { - errno = EINVAL; - return MAP_FAILED; - } - - return __mmap2(start, length, prot, flags, fd, (size_t)offset >> mmap2_shift); -} - -#endif - - - - diff --git a/klibc/klibc/mrand48.c b/klibc/klibc/mrand48.c deleted file mode 100644 index 886ae9f03c..0000000000 --- a/klibc/klibc/mrand48.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * mrand48.c - */ - -#include -#include - -unsigned short __rand48_seed[3]; /* Common with lrand48.c, srand48.c */ - -long mrand48(void) -{ - return jrand48(__rand48_seed); -} diff --git a/klibc/klibc/nice.c b/klibc/klibc/nice.c deleted file mode 100644 index 5a18de9091..0000000000 --- a/klibc/klibc/nice.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * nice.c - */ - -#include -#include -#include -#include - -#ifndef __NR_nice - -int nice(int inc) -{ - pid_t me = getpid(); - return setpriority(me, PRIO_PROCESS, getpriority(me, PRIO_PROCESS)+inc); -} - -#endif diff --git a/klibc/klibc/nrand48.c b/klibc/klibc/nrand48.c deleted file mode 100644 index fb7c5772fd..0000000000 --- a/klibc/klibc/nrand48.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * nrand48.c - */ - -#include -#include - -long nrand48(unsigned short xsubi[3]) -{ - return (long)((uint32_t)jrand48(xsubi) >> 1); -} diff --git a/klibc/klibc/onexit.c b/klibc/klibc/onexit.c deleted file mode 100644 index 70a9c01f61..0000000000 --- a/klibc/klibc/onexit.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * onexit.c - */ - -#include -#include -#include "atexit.h" - -extern __noreturn (*__exit_handler)(int); -static struct atexit *__atexit_list; - -static __noreturn on_exit_exit(int rv) -{ - struct atexit *ap; - - for ( ap = __atexit_list ; ap ; ap = ap->next ) { - ap->fctn(rv, ap->arg); /* This assumes extra args are harmless */ - } - - _exit(rv); -} - -int on_exit(void (*fctn)(int, void *), void *arg) -{ - struct atexit *as = malloc(sizeof(struct atexit)); - - if ( !as ) - return -1; - - as->fctn = fctn; - as->arg = arg; - - as->next = __atexit_list; - __atexit_list = as; - - __exit_handler = on_exit_exit; - - return 0; -} diff --git a/klibc/klibc/open.c b/klibc/klibc/open.c deleted file mode 100644 index cb1f5195db..0000000000 --- a/klibc/klibc/open.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * open.c - * - * On 32-bit platforms we need to pass O_LARGEFILE to the open() - * system call, to indicate that we're 64-bit safe. - */ - -#define _KLIBC_IN_OPEN_C -#include -#include -#include - -#if _BITSIZE == 32 && !defined(__i386__) - -extern int __open(const char *, int, mode_t); - -int open(const char *pathname, int flags, mode_t mode) -{ - return __open(pathname, flags|O_LARGEFILE, mode); -} - -#endif diff --git a/klibc/klibc/pause.c b/klibc/klibc/pause.c deleted file mode 100644 index 1f7b9342de..0000000000 --- a/klibc/klibc/pause.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * pause.c - */ - -#include -#include -#include -#include - -#ifndef __NR_pause - -int pause(void) -{ - return select(0,NULL,NULL,NULL,NULL); -} - -#endif diff --git a/klibc/klibc/perror.c b/klibc/klibc/perror.c deleted file mode 100644 index 26f8ce8f6d..0000000000 --- a/klibc/klibc/perror.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * perror.c - */ - -#include -#include -#include - -void perror(const char *s) -{ - int e = errno; - fprintf(stderr, "%s: %s\n", s, strerror(e)); -} diff --git a/klibc/klibc/printf.c b/klibc/klibc/printf.c deleted file mode 100644 index 34237592d6..0000000000 --- a/klibc/klibc/printf.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * printf.c - */ - -#include -#include - -#define BUFFER_SIZE 16384 - -int printf(const char *format, ...) -{ - va_list ap; - int rv; - - va_start(ap, format); - rv = vfprintf(stdout, format, ap); - va_end(ap); - return rv; -} diff --git a/klibc/klibc/pty.c b/klibc/klibc/pty.c deleted file mode 100644 index 2fe01ab204..0000000000 --- a/klibc/klibc/pty.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * pty.c - * - * Basic Unix98 PTY functionality; assumes devpts mounted on /dev/pts - */ - -#include -#include -#include -#include -#include - -char *ptsname(int fd) -{ - static char buffer[32]; /* Big enough to hold even a 64-bit pts no */ - unsigned int ptyno; - - if ( ioctl(fd, TIOCGPTN, &ptyno) ) - return NULL; - - snprintf(buffer, sizeof buffer, "/dev/pts/%u", ptyno); - - return buffer; -} - -int unlockpt(int fd) -{ - int unlock = 0; - - return ioctl(fd, TIOCSPTLCK, &unlock); -} diff --git a/klibc/klibc/putchar.c b/klibc/klibc/putchar.c deleted file mode 100644 index 0e35adda17..0000000000 --- a/klibc/klibc/putchar.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * putchar.c - * - * - gcc wants this - */ - -#include - -#undef putchar /* Defined as a macro */ -int putchar(int); - -int putchar(int c) -{ - return fputc(c, stdout); -} diff --git a/klibc/klibc/putenv.c b/klibc/klibc/putenv.c deleted file mode 100644 index 8138c653b4..0000000000 --- a/klibc/klibc/putenv.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * putenv.c - */ - -#include -#include -#include -#include - -/* str should be a duplicated version of the input string; - len is the length of the key including the = sign */ -int __put_env(char *str, size_t len, int overwrite); - -int putenv(const char *str) -{ - char *s; - const char *e, *z; - - if ( !str ) { - errno = EINVAL; - return -1; - } - - e = NULL; - for ( z = str ; *z ; z++ ) { - if ( *z == '=' ) - e = z; - } - - if ( !e ) { - errno = EINVAL; - return -1; - } - - s = strdup(str); - if ( !s ) - return -1; - - return __put_env(s, e-str, 1); -} diff --git a/klibc/klibc/puts.c b/klibc/klibc/puts.c deleted file mode 100644 index ecebf275da..0000000000 --- a/klibc/klibc/puts.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * puts.c - */ - -#include - -int puts(const char *s) -{ - if ( fputs(s, stdout) < 0 ) - return -1; - - return _fwrite("\n", 1, stdout); -} diff --git a/klibc/klibc/qsort.c b/klibc/klibc/qsort.c deleted file mode 100644 index 185f4dac69..0000000000 --- a/klibc/klibc/qsort.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * qsort.c - * - * This is actually combsort. It's an O(n log n) algorithm with - * simplicity/small code size being its main virtue. - */ - -#include -#include - -static inline size_t newgap(size_t gap) -{ - gap = (gap*10)/13; - if ( gap == 9 || gap == 10 ) - gap = 11; - - if ( gap < 1 ) - gap = 1; - return gap; -} - -void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) -{ - size_t gap = nmemb; - size_t i, j; - char *p1, *p2; - int swapped; - - do { - gap = newgap(gap); - swapped = 0; - - for ( i = 0, p1 = base ; i < nmemb-gap ; i++, p1 += size ) { - j = i+gap; - if ( compar(p1, p2 = (char *)base+j*size) > 0 ) { - memswap(p1, p2, size); - swapped = 1; - } - } - } while ( gap > 1 || swapped ); -} - diff --git a/klibc/klibc/raise.c b/klibc/klibc/raise.c deleted file mode 100644 index dcbb9c9c6c..0000000000 --- a/klibc/klibc/raise.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * raise.c - */ - -#include -#include - -int raise(int signal) -{ - return kill(getpid(), signal); -} diff --git a/klibc/klibc/readdir.c b/klibc/klibc/readdir.c deleted file mode 100644 index acfe588713..0000000000 --- a/klibc/klibc/readdir.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * readdir.c: opendir/readdir/closedir - */ - -#include -#include -#include - -#define __KLIBC_DIRENT_INTERNALS -#include - -DIR *opendir(const char *name) -{ - DIR *dp = malloc(sizeof(DIR)); - - if ( !dp ) - return NULL; - - dp->__fd = open(name, O_DIRECTORY|O_RDONLY); - - if ( dp->__fd < 0 ) { - free(dp); - return NULL; - } - - dp->bytes_left = 0; - - return dp; -} - -struct dirent *readdir(DIR *dir) -{ - struct dirent *dent; - int rv; - - if ( !dir->bytes_left ) { - rv = getdents(dir->__fd, dir->buffer, sizeof(dir->buffer)); - if ( rv <= 0 ) - return NULL; - dir->bytes_left = rv; - dir->next = dir->buffer; - } - - dent = dir->next; - dir->next = (struct dirent *)((char *)dir->next + dent->d_reclen); - dir->bytes_left -= dent->d_reclen; - - return dent; -} - -int closedir(DIR *dir) -{ - int rv; - rv = close(dir->__fd); - free(dir); - return rv; -} diff --git a/klibc/klibc/realloc.c b/klibc/klibc/realloc.c deleted file mode 100644 index 577c2001a5..0000000000 --- a/klibc/klibc/realloc.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * realloc.c - */ - -#include -#include - -#include "malloc.h" - -/* FIXME: This is cheesy, it should be fixed later */ - -void *realloc(void *ptr, size_t size) -{ - struct free_arena_header *ah; - void *newptr; - size_t oldsize; - - if ( !ptr ) - return malloc(size); - - if ( size == 0 ) { - free(ptr); - return NULL; - } - - /* Add the obligatory arena header, and round up */ - size = (size+2*sizeof(struct arena_header)-1) & ARENA_SIZE_MASK; - - ah = (struct free_arena_header *) - ((struct arena_header *)ptr - 1); - - if ( ah->a.size >= size && size >= (ah->a.size >> 2) ) { - /* This field is a good size already. */ - return ptr; - } else { - /* Make me a new block. This is kind of bogus; we should - be checking the adjacent blocks to see if we can do an - in-place adjustment... fix that later. */ - - oldsize = ah->a.size - sizeof(struct arena_header); - - newptr = malloc(size); - memcpy(newptr, ptr, (size < oldsize) ? size : oldsize); - free(ptr); - - return newptr; - } -} - diff --git a/klibc/klibc/reboot.c b/klibc/klibc/reboot.c deleted file mode 100644 index 772c85910e..0000000000 --- a/klibc/klibc/reboot.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * reboot.c - */ - -#include -#include -#include - -/* This provides the one-argument glibc-ish version of reboot. - The full four-argument system call is available as __reboot(). */ - -int reboot(int flag) -{ - return __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, flag, NULL); -} diff --git a/klibc/klibc/recv.c b/klibc/klibc/recv.c deleted file mode 100644 index 4d30610cee..0000000000 --- a/klibc/klibc/recv.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * recv.c - */ - -#include -#include - -int recv(int s, void *buf, size_t len, unsigned int flags) -{ - return recvfrom(s, buf, len, flags, NULL, 0); -} diff --git a/klibc/klibc/sbrk.c b/klibc/klibc/sbrk.c deleted file mode 100644 index cb0efb21b9..0000000000 --- a/klibc/klibc/sbrk.c +++ /dev/null @@ -1,41 +0,0 @@ -/* sbrk.c - Change data segment size */ - -/* Written 2000 by Werner Almesberger */ -/* Modified 2003-2004 for klibc by H. Peter Anvin */ - -#include -#include -#include -#include -#include "malloc.h" - -char *__current_brk; /* Common with brk.c */ - -/* p is an address, a is alignment; must be a power of 2 */ -static inline void *align_up(void *p, uintptr_t a) -{ - return (void *) (((uintptr_t)p + a-1) & ~(a-1)); -} - -void *sbrk(ptrdiff_t increment) -{ - char *start, *end, *new_brk; - - if (!__current_brk) - __current_brk = __brk(NULL); - - start = align_up(__current_brk, SBRK_ALIGNMENT); - end = start + increment; - - new_brk = __brk(end); - - if (new_brk == (void *)-1) - return (void *)-1; - else if (new_brk < end) { - errno = ENOMEM; - return (void *) -1; - } - - __current_brk = new_brk; - return start; -} diff --git a/klibc/klibc/seed48.c b/klibc/klibc/seed48.c deleted file mode 100644 index ac916d6165..0000000000 --- a/klibc/klibc/seed48.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * seed48.c - */ - -#include -#include -#include - -unsigned short __rand48_seed[3]; - -unsigned short *seed48(const unsigned short xsubi[3]) -{ - static unsigned short oldseed[3]; - memcpy(oldseed, __rand48_seed, sizeof __rand48_seed); - memcpy(__rand48_seed, xsubi, sizeof __rand48_seed); - - return oldseed; -} - diff --git a/klibc/klibc/send.c b/klibc/klibc/send.c deleted file mode 100644 index 8c53d0f764..0000000000 --- a/klibc/klibc/send.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * send.c - */ - -#include -#include - -int send(int s, const void *buf, size_t len, unsigned int flags) -{ - return sendto(s, buf, len, flags, NULL, 0); -} diff --git a/klibc/klibc/setegid.c b/klibc/klibc/setegid.c deleted file mode 100644 index 09f2416e43..0000000000 --- a/klibc/klibc/setegid.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * setegid.c - */ - -#include - -int setegid(gid_t egid) -{ - return setregid(-1, egid); -} diff --git a/klibc/klibc/setenv.c b/klibc/klibc/setenv.c deleted file mode 100644 index d4ada53d74..0000000000 --- a/klibc/klibc/setenv.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * setenv.c - */ - -#include -#include -#include -#include - -/* str should be a duplicated version of the input string; - len is the length of the key including the = sign */ -int __put_env(char *str, size_t len, int overwrite); - -int setenv(const char *name, const char *val, int overwrite) -{ - const char *z; - char *s; - size_t l1, l2; - - if ( !name || !name[0] ) { - errno = EINVAL; - return -1; - } - - l1 = 0; - for ( z = name ; *z ; z++ ) { - l1++; - if ( *z == '=' ) { - errno = EINVAL; - return -1; - } - } - - l2 = strlen(val); - - s = malloc(l1+l2+2); - if ( !s ) - return -1; - - memcpy(s, name, l1); - s[l1] = '='; - memcpy(s+l1+1, val, l2+1); - - return __put_env(s, l1+1, overwrite); -} diff --git a/klibc/klibc/seteuid.c b/klibc/klibc/seteuid.c deleted file mode 100644 index 6d1ac3922a..0000000000 --- a/klibc/klibc/seteuid.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * seteuid.c - */ - -#include - -int seteuid(uid_t euid) -{ - return setreuid(-1, euid); -} diff --git a/klibc/klibc/setpgrp.c b/klibc/klibc/setpgrp.c deleted file mode 100644 index 001dd0435d..0000000000 --- a/klibc/klibc/setpgrp.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * setpgrp.c - */ - -#include - -int setpgrp(void) -{ - return setpgid(0,0); -} diff --git a/klibc/klibc/sha1hash.c b/klibc/klibc/sha1hash.c deleted file mode 100644 index 28e3399967..0000000000 --- a/klibc/klibc/sha1hash.c +++ /dev/null @@ -1,317 +0,0 @@ -/* -SHA-1 in C -By Steve Reid -100% Public Domain - ------------------ -Modified 7/98 -By James H. Brown -Still 100% Public Domain - -Corrected a problem which generated improper hash values on 16 bit machines -Routine SHA1Update changed from - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int -len) -to - void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned -long len) - -The 'len' parameter was declared an int which works fine on 32 bit machines. -However, on 16 bit machines an int is too small for the shifts being done -against -it. This caused the hash function to generate incorrect values if len was -greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). - -Since the file IO in main() reads 16K at a time, any file 8K or larger would -be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million -"a"s). - -I also changed the declaration of variables i & j in SHA1Update to -unsigned long from unsigned int for the same reason. - -These changes should make no difference to any 32 bit implementations since -an -int and a long are the same size in those environments. - --- -I also corrected a few compiler warnings generated by Borland C. -1. Added #include for exit() prototype -2. Removed unused variable 'j' in SHA1Final -3. Changed exit(0) to return(0) at end of main. - -ALL changes I made can be located by searching for comments containing 'JHB' ------------------ -Modified 8/98 -By Steve Reid -Still 100% public domain - -1- Removed #include and used return() instead of exit() -2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) -3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net - ------------------ -Modified 4/01 -By Saul Kravitz -Still 100% PD -Modified to run on Compaq Alpha hardware. - ------------------ -Modified 2/03 -By H. Peter Anvin -Still 100% PD -Modified to run on any hardware with and -Changed the driver program - -*/ - -/* -Test Vectors (from FIPS PUB 180-1) -"abc" - A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D -"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" - 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 -A million repetitions of "a" - 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F -*/ - -/* #define SHA1HANDSOFF */ - -#include -#include -#include -#include /* For htonl/ntohl/htons/ntohs */ - -/* #include */ /* prototype for exit() - JHB */ -/* Using return() instead of exit() - SWR */ - -typedef struct { - uint32_t state[5]; - uint32_t count[2]; - unsigned char buffer[64]; -} SHA1_CTX; - -void SHA1Transform(uint32_t state[5], unsigned char buffer[64]); -void SHA1Init(SHA1_CTX* context); -void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len); /* -JHB */ -void SHA1Final(unsigned char digest[20], SHA1_CTX* context); - -#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -/* blk0() and blk() perform the initial expand. */ -/* I got the idea of expanding during the round function from SSLeay */ -#define blk0(i) (block->l[i] = ntohl(block->l[i])) -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) - -/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); - - -#ifdef VERBOSE /* SAK */ -void SHAPrintContext(SHA1_CTX *context, char *msg){ - printf("%s (%d,%d) %x %x %x %x %x\n", - msg, - context->count[0], context->count[1], - context->state[0], - context->state[1], - context->state[2], - context->state[3], - context->state[4]); -} -#endif - -/* Hash a single 512-bit block. This is the core of the algorithm. */ - -void SHA1Transform(uint32_t state[5], unsigned char buffer[64]) -{ -uint32_t a, b, c, d, e; -typedef union { - unsigned char c[64]; - uint32_t l[16]; -} CHAR64LONG16; -CHAR64LONG16* block; -#ifdef SHA1HANDSOFF -static unsigned char workspace[64]; - block = (CHAR64LONG16*)workspace; - memcpy(block, buffer, 64); -#else - block = (CHAR64LONG16*)buffer; -#endif - /* Copy context->state[] to working vars */ - a = state[0]; - b = state[1]; - c = state[2]; - d = state[3]; - e = state[4]; - /* 4 rounds of 20 operations each. Loop unrolled. */ - R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); - R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); - R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); - R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); - R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); - R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); - R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); - R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); - R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); - R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); - R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); - R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); - R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); - R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); - R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); - R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); - R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); - R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); - R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); - R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); - /* Add the working vars back into context.state[] */ - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - state[4] += e; - /* Wipe variables */ - a = b = c = d = e = 0; -} - - -/* SHA1Init - Initialize new context */ - -void SHA1Init(SHA1_CTX* context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - - -/* Run your data through this. */ - -void SHA1Update(SHA1_CTX* context, unsigned char* data, uint32_t len) /* -JHB */ -{ -uint32_t i, j; /* JHB */ - -#ifdef VERBOSE - SHAPrintContext(context, "before"); -#endif - j = (context->count[0] >> 3) & 63; - if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; - context->count[1] += (len >> 29); - if ((j + len) > 63) { - memcpy(&context->buffer[j], data, (i = 64-j)); - SHA1Transform(context->state, context->buffer); - for ( ; i + 63 < len; i += 64) { - SHA1Transform(context->state, &data[i]); - } - j = 0; - } - else i = 0; - memcpy(&context->buffer[j], &data[i], len - i); -#ifdef VERBOSE - SHAPrintContext(context, "after "); -#endif -} - - -/* Add padding and return the message digest. */ - -void SHA1Final(unsigned char digest[20], SHA1_CTX* context) -{ -uint32_t i; /* JHB */ -unsigned char finalcount[8]; - - for (i = 0; i < 8; i++) { - finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] - >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ - } - SHA1Update(context, (unsigned char *)"\200", 1); - while ((context->count[0] & 504) != 448) { - SHA1Update(context, (unsigned char *)"\0", 1); - } - SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() -*/ - for (i = 0; i < 20; i++) { - digest[i] = (unsigned char) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); - } - /* Wipe variables */ - i = 0; /* JHB */ - memset(context->buffer, 0, 64); - memset(context->state, 0, 20); - memset(context->count, 0, 8); - memset(finalcount, 0, 8); /* SWR */ -#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ - SHA1Transform(context->state, context->buffer); -#endif -} - -/*************************************************************/ - -/* This is not quite the MIME base64 algorithm: it uses _ instead of /, - and instead of padding the output with = characters we just make the - output shorter. */ -char *mybase64(uint8_t digest[20]) -{ - static const char charz[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - uint8_t input[21]; - static char output[28]; - int i, j; - uint8_t *p; - char *q; - uint32_t bv; - - memcpy(input, digest, 20); - input[20] = 0; /* Pad to multiple of 3 bytes */ - - p = input; q = output; - for ( i = 0 ; i < 7 ; i++ ) { - bv = (p[0] << 16) | (p[1] << 8) | p[2]; - p += 3; - for ( j = 0 ; j < 4 ; j++ ) { - *q++ = charz[(bv >> 18) & 0x3f]; - bv <<= 6; - } - } - *--q = '\0'; /* The last character is not significant */ - return output; -} - -int main(int argc, char** argv) -{ - int i; - SHA1_CTX context; - uint8_t digest[20], buffer[16384]; - FILE* file; - - if (argc < 2) { - file = stdin; - } - else { - if (!(file = fopen(argv[1], "rb"))) { - fputs("Unable to open file.", stderr); - return(-1); - } - } - SHA1Init(&context); - while (!feof(file)) { /* note: what if ferror(file) */ - i = fread(buffer, 1, 16384, file); - SHA1Update(&context, buffer, i); - } - SHA1Final(digest, &context); - fclose(file); - - puts(mybase64(digest)); - - return 0; -} diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c deleted file mode 100644 index 85f42a244c..0000000000 --- a/klibc/klibc/sigaction.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * sigaction.c - */ - -#include -#include - -__extern void __sigreturn(void); -__extern int __sigaction(int, const struct sigaction *, struct sigaction *); -__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); - -int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) -{ - int rv; - -#if defined(__i386__) || defined(__x86_64__) - /* x86-64, and the Fedora i386 kernel, are broken without SA_RESTORER */ - struct sigaction sa; - - if ( act && !(act->sa_flags & SA_RESTORER) ) { - sa = *act; - act = &sa; - - /* The kernel can't be trusted to have a valid default restorer */ - sa.sa_flags |= SA_RESTORER; - sa.sa_restorer = &__sigreturn; - } -#endif - -#ifdef __NR_sigaction - rv = __sigaction(sig, act, oact); -#else - rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t)); -#endif - - -#if defined(__i386__) || defined(__x86_64__) - if ( oact && (oact->sa_restorer == &__sigreturn) ) { - oact->sa_flags &= ~SA_RESTORER; - } -#endif - - return rv; -} diff --git a/klibc/klibc/siglist.c b/klibc/klibc/siglist.c deleted file mode 100644 index dce7355079..0000000000 --- a/klibc/klibc/siglist.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * siglist.h - * - * Construct the signal list - */ - -#include -#include - -const char * const sys_siglist[NSIG] = { -#ifdef SIGABRT - [SIGABRT] = "Aborted", -#endif -#ifdef SIGALRM - [SIGALRM] = "Alarm clock", -#endif -#ifdef SIGBUS - [SIGBUS] = "Bus error", -#endif -#ifdef SIGCHLD - [SIGCHLD] = "Child exited", -#endif -#if defined(SIGCLD) && (SIGCHLD != SIGCLD) - [SIGCLD] = "Child exited", -#endif -#ifdef SIGEMT - [SIGEMT] = "Emulation trap", -#endif -#ifdef SIGFPE - [SIGFPE] = "Floating point exception", -#endif -#ifdef SIGHUP - [SIGHUP] = "Hangup", -#endif -#ifdef SIGILL - [SIGILL] = "Illegal instruction", -#endif - /* SIGINFO == SIGPWR */ -#ifdef SIGINT - [SIGINT] = "Interrupt", -#endif -#ifdef SIGIO - [SIGIO] = "I/O possible", -#endif -#if defined(SIGIOT) && (SIGIOT != SIGABRT) - [SIGIOT] = "I/O trap", -#endif -#ifdef SIGKILL - [SIGKILL] = "Killed", -#endif -#if defined(SIGLOST) && (SIGLOST != SIGIO) && (SIGLOST != SIGPWR) - [SIGLOST] = "Lock lost", -#endif -#ifdef SIGPIPE - [SIGPIPE] = "Broken pipe", -#endif -#if defined(SIGPOLL) && (SIGPOLL != SIGIO) - [SIGPOLL] = "Pollable event", -#endif -#ifdef SIGPROF - [SIGPROF] = "Profiling timer expired", -#endif -#ifdef SIGPWR - [SIGPWR] = "Power failure", -#endif -#ifdef SIGQUIT - [SIGQUIT] = "Quit", -#endif - /* SIGRESERVE == SIGUNUSED */ -#ifdef SIGSEGV - [SIGSEGV] = "Segment violation", -#endif -#ifdef SIGSTKFLT - [SIGSTKFLT] = "Stack fault", -#endif -#ifdef SIGSTOP - [SIGSTOP] = "Stopped (signal)", -#endif -#ifdef SIGSYS - [SIGSYS] = "Bad system call", -#endif -#ifdef SIGTERM - [SIGTERM] = "Terminated", -#endif -#ifdef SIGTSTP - [SIGTSTP] = "Stopped", -#endif -#ifdef SIGTTIN - [SIGTTIN] = "Stopped (tty input)", -#endif -#ifdef SIGTTOU - [SIGTTOU] = "Stopped (tty output)", -#endif -#ifdef SIGURG - [SIGURG] = "Urgent I/O condition", -#endif -#ifdef SIGUSR1 - [SIGUSR1] = "User signal 1", -#endif -#ifdef SIGUSR2 - [SIGUSR2] = "User signal 2", -#endif -#ifdef SIGVTALRM - [SIGVTALRM] = "Virtual timer expired", -#endif -#ifdef SIGWINCH - [SIGWINCH] = "Window size changed", -#endif -#ifdef SIGXCPU - [SIGXCPU] = "CPU time limit exceeded", -#endif -#ifdef SIGXFSZ - [SIGXFSZ] = "File size limit exceeded", -#endif -}; diff --git a/klibc/klibc/siglongjmp.c b/klibc/klibc/siglongjmp.c deleted file mode 100644 index 2ba1239b6b..0000000000 --- a/klibc/klibc/siglongjmp.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * siglongjmp.c - * - * sigsetjmp() is a macro, by necessity (it's either that or write - * it in assembly), but siglongjmp() is a normal function. - */ - -#include -#include - -__noreturn siglongjmp(sigjmp_buf buf, int retval) -{ - sigprocmask(SIG_SETMASK, &buf->__sigs, NULL); - longjmp(buf->__jmpbuf, retval); -} - diff --git a/klibc/klibc/sigpending.c b/klibc/klibc/sigpending.c deleted file mode 100644 index decfe32b1b..0000000000 --- a/klibc/klibc/sigpending.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * sigpending.c - */ - -#include -#include - -#ifndef __NR_sigpending - -__extern __rt_sigpending(sigset_t *, size_t); - -int sigpending(sigset_t *set) -{ - return __rt_sigpending(set, sizeof(sigset_t)); -} - -#endif diff --git a/klibc/klibc/sigprocmask.c b/klibc/klibc/sigprocmask.c deleted file mode 100644 index 372e0fd90d..0000000000 --- a/klibc/klibc/sigprocmask.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * sigprocmask.c - */ - -#include -#include - -#ifndef __NR_sigprocmask - -__extern __rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); - -int sigprocmask(int how, const sigset_t *set, sigset_t *oset) -{ - return __rt_sigprocmask(how, set, oset, sizeof(sigset_t)); -} - -#endif diff --git a/klibc/klibc/sigsuspend.c b/klibc/klibc/sigsuspend.c deleted file mode 100644 index 22f9a46681..0000000000 --- a/klibc/klibc/sigsuspend.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * sigsuspend.c - */ - -#include -#include - -#ifndef __NR_sigsuspend - -__extern int __rt_sigsuspend(const sigset_t *, size_t); - -int sigsuspend(const sigset_t *mask) -{ - return __rt_sigsuspend(mask, sizeof *mask); -} - -#endif diff --git a/klibc/klibc/sleep.c b/klibc/klibc/sleep.c deleted file mode 100644 index eb3777e8a6..0000000000 --- a/klibc/klibc/sleep.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * sleep.c - */ - -#include -#include - -unsigned int sleep(unsigned int seconds) -{ - struct timespec ts; - - ts.tv_sec = seconds; - ts.tv_nsec = 0; - if ( !nanosleep(&ts,&ts) ) - return 0; - else if ( errno == EINTR ) - return ts.tv_sec; - else - return -1; -} diff --git a/klibc/klibc/snprintf.c b/klibc/klibc/snprintf.c deleted file mode 100644 index c642851b2f..0000000000 --- a/klibc/klibc/snprintf.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * snprintf.c - */ - -#include - -int snprintf(char *buffer, size_t n, const char *format, ...) -{ - va_list ap; - int rv; - - va_start(ap, format); - rv = vsnprintf(buffer, n, format, ap); - va_end(ap); - return rv; -} diff --git a/klibc/klibc/socketcalls.pl b/klibc/klibc/socketcalls.pl deleted file mode 100644 index 68f0fa164b..0000000000 --- a/klibc/klibc/socketcalls.pl +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/perl - -$v = $ENV{'KBUILD_VERBOSE'}; -$quiet = defined($v) ? !$v : 0; - -@args = (); -for $arg ( @ARGV ) { - if ( $arg =~ /^-/ ) { - if ( $arg eq '-q' ) { - $quiet = 1; - } else { - die "$0: Unknown option: $arg\n"; - } - } else { - push(@args, $arg); - } -} -($file, $arch, $outputdir) = @args; - -if (!open(FILE, "< $file")) { - die "$file: $!\n"; -} - -print "socketcall-objs := "; -while ( defined($line = ) ) { - chomp $line; - $line =~ s/\s*[\#\;].*$//; # Strip comments and trailing blanks - next unless $line; - - if ( $line =~ /^\s*\<\?\>\s*(.*)\s+([_a-zA-Z][_a-zA-Z0-9]+)\s*\((.*)\)$/ ) { - $type = $1; - $name = $2; - $argv = $3; - - @args = split(/\s*\,\s*/, $argv); - @cargs = (); - - $i = 0; - for $arg ( @args ) { - push(@cargs, "$arg a".$i++); - } - $nargs = $i; - print " \\\n\t${name}.o"; - - if ( $arch eq 'i386' ) { - open(OUT, '>', "${outputdir}/${name}.S") - or die "$0: Cannot open ${outputdir}/${name}.S\n"; - - print OUT "#include \n"; - print OUT "\n"; - print OUT "\t.text\n"; - print OUT "\t.align 4\n"; - print OUT "\t.globl ${name}\n"; - print OUT "\t.type ${name},\@function\n"; - print OUT "${name}:\n"; - print OUT "\tmovb \$SYS_\U${name}\E,%al\n"; - print OUT "\tjmp __socketcall_common\n"; - print OUT "\t.size ${name},.-${name}\n"; - close(OUT); - } else { - open(OUT, '>', "${outputdir}/${name}.c") - or die "$0: Cannot open ${outputdir}/${name}.c\n"; - - print OUT "#include \"../socketcommon.h\"\n"; - print OUT "\n"; - print OUT "#ifndef __NR_${name}\n\n"; - - print OUT "extern long __socketcall(int, const unsigned long *);\n\n"; - - print OUT "$type $name (", join(', ', @cargs), ")\n"; - print OUT "{\n"; - print OUT " unsigned long args[$nargs];\n"; - for ( $i = 0 ; $i < $nargs ; $i++ ) { - print OUT " args[$i] = (unsigned long)a$i;\n"; - } - print OUT " return ($type) __socketcall(SYS_\U${name}\E, args);\n"; - print OUT "}\n\n"; - - print OUT "#endif\n"; - - close(OUT); - } - } else { - die "$file:$.: Could not parse input\n"; - } -} - -print "\n"; diff --git a/klibc/klibc/socketcommon.h b/klibc/klibc/socketcommon.h deleted file mode 100644 index 9c4b11fab8..0000000000 --- a/klibc/klibc/socketcommon.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * socketcommon.h - * - * Common header file for socketcall stubs - */ - -#define __IN_SYS_COMMON -#include -#include -#include -#include -#include -#include -#include -#include -#include diff --git a/klibc/klibc/sprintf.c b/klibc/klibc/sprintf.c deleted file mode 100644 index 31f28af005..0000000000 --- a/klibc/klibc/sprintf.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * sprintf.c - */ - -#include -#include - -int sprintf(char *buffer, const char *format, ...) -{ - va_list ap; - int rv; - - va_start(ap, format); - rv = vsnprintf(buffer, ~(size_t)0, format, ap); - va_end(ap); - - return rv; -} diff --git a/klibc/klibc/srand48.c b/klibc/klibc/srand48.c deleted file mode 100644 index 5f201d2047..0000000000 --- a/klibc/klibc/srand48.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * srand48.c - */ - -#include -#include - -unsigned short __rand48_seed[3]; /* Common with mrand48.c, lrand48.c */ - -void srand48(long seedval) -{ - __rand48_seed[0] = 0x330e; - __rand48_seed[1] = (unsigned short)seedval; - __rand48_seed[2] = (unsigned short)((uint32_t)seedval >> 16); -} diff --git a/klibc/klibc/sscanf.c b/klibc/klibc/sscanf.c deleted file mode 100644 index 81aab9e05b..0000000000 --- a/klibc/klibc/sscanf.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * sscanf() - */ - -#include - -int sscanf(const char *str, const char *format, ...) -{ - va_list ap; - int rv; - - va_start(ap, format); - rv = vsscanf(str, format, ap); - va_end(ap); - - return rv; -} diff --git a/klibc/klibc/statfs.c b/klibc/klibc/statfs.c deleted file mode 100644 index 60e9188a09..0000000000 --- a/klibc/klibc/statfs.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * statfs.c - * - * On architectures which do statfs64, wrap the system call - */ - -#include -#include - -#ifdef __NR_statfs64 - -extern int __statfs64(const char *, size_t, struct statfs *); - -int statfs(const char *path, struct statfs *buf) -{ - return __statfs64(path, sizeof *buf, buf); -} - -#endif diff --git a/klibc/klibc/strcasecmp.c b/klibc/klibc/strcasecmp.c deleted file mode 100644 index 12aef40d93..0000000000 --- a/klibc/klibc/strcasecmp.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * strcasecmp.c - */ - -#include -#include - -int strcasecmp(const char *s1, const char *s2) -{ - const unsigned char *c1 = s1, *c2 = s2; - unsigned char ch; - int d = 0; - - while ( 1 ) { - /* toupper() expects an unsigned char (implicitly cast to int) - as input, and returns an int, which is exactly what we want. */ - d = toupper(ch = *c1++) - toupper(*c2++); - if ( d || !ch ) - break; - } - - return d; -} diff --git a/klibc/klibc/strcat.c b/klibc/klibc/strcat.c deleted file mode 100644 index a5f9477866..0000000000 --- a/klibc/klibc/strcat.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * strcat.c - */ - -#include - -char *strcat(char *dst, const char *src) -{ - strcpy(strchr(dst, '\0'), src); - return dst; -} diff --git a/klibc/klibc/strchr.c b/klibc/klibc/strchr.c deleted file mode 100644 index f657095c6b..0000000000 --- a/klibc/klibc/strchr.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * strchr.c - */ - -#include -#include - -char *strchr(const char *s, int c) -{ - while ( *s != (char)c ) { - if ( ! *s ) - return NULL; - s++; - } - - return (char *)s; -} - -__ALIAS(char *, index, (const char *, int), strchr) diff --git a/klibc/klibc/strcmp.c b/klibc/klibc/strcmp.c deleted file mode 100644 index f44774f443..0000000000 --- a/klibc/klibc/strcmp.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * strcmp.c - */ - -#include - -int strcmp(const char *s1, const char *s2) -{ - const unsigned char *c1 = s1, *c2 = s2; - unsigned char ch; - int d = 0; - - while ( 1 ) { - d = (int)(ch = *c1++) - (int)*c2++; - if ( d || !ch ) - break; - } - - return d; -} diff --git a/klibc/klibc/strcpy.c b/klibc/klibc/strcpy.c deleted file mode 100644 index 8372eba50b..0000000000 --- a/klibc/klibc/strcpy.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * strcpy.c - * - * strcpy() - */ - -#include - -char *strcpy(char *dst, const char *src) -{ - char *q = dst; - const char *p = src; - char ch; - - do { - *q++ = ch = *p++; - } while ( ch ); - - return dst; -} diff --git a/klibc/klibc/strcspn.c b/klibc/klibc/strcspn.c deleted file mode 100644 index 87d644551e..0000000000 --- a/klibc/klibc/strcspn.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * strcspn - */ - -#include "strxspn.h" - -size_t -strcspn(const char *s, const char *reject) -{ - return __strxspn(s, reject, 1); -} diff --git a/klibc/klibc/strdup.c b/klibc/klibc/strdup.c deleted file mode 100644 index eb170c2645..0000000000 --- a/klibc/klibc/strdup.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * strdup.c - */ - -#include -#include - -char *strdup(const char *s) -{ - int l = strlen(s)+1; - char *d = malloc(l); - - if ( d ) - memcpy(d, s, l); - - return d; -} diff --git a/klibc/klibc/strerror.c b/klibc/klibc/strerror.c deleted file mode 100644 index c8e3eac793..0000000000 --- a/klibc/klibc/strerror.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * strerror.c - */ - -#include - -char *strerror(int errnum) -{ - static char message[32] = "error "; /* enough for error 2^63-1 */ - char numbuf[32]; - char *p; - unsigned int e = (unsigned int)errnum; - -#ifdef WITH_ERRLIST - extern const int sys_nerr; - extern const char * const sys_errlist[]; - - if ( e < (unsigned int)sys_nerr && sys_errlist[e] ) - return (char *)sys_errlist[e]; -#endif - - p = numbuf+sizeof numbuf; - *--p = '\0'; - - do { - *--p = (e % 10) + '0'; - e /= 10; - } while ( e ); - - memcpy(message+6, p, (numbuf+sizeof numbuf)-p); - - return message; -} - diff --git a/klibc/klibc/strlcat.c b/klibc/klibc/strlcat.c deleted file mode 100644 index f397857e76..0000000000 --- a/klibc/klibc/strlcat.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * strlcat.c - */ - -#include -#include - -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; -} - - diff --git a/klibc/klibc/strlcpy.c b/klibc/klibc/strlcpy.c deleted file mode 100644 index e6937445cd..0000000000 --- a/klibc/klibc/strlcpy.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * strlcpy.c - */ - -#include -#include - -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; -} - - diff --git a/klibc/klibc/strlen.c b/klibc/klibc/strlen.c deleted file mode 100644 index 4d773f9a05..0000000000 --- a/klibc/klibc/strlen.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * strlen() - */ - -#include - -size_t strlen(const char *s) -{ - const char *ss = s; - while ( *ss ) - ss++; - return ss-s; -} - diff --git a/klibc/klibc/strncasecmp.c b/klibc/klibc/strncasecmp.c deleted file mode 100644 index 3309d1a7fe..0000000000 --- a/klibc/klibc/strncasecmp.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * strncasecmp.c - */ - -#include -#include - -int strncasecmp(const char *s1, const char *s2, size_t n) -{ - const unsigned char *c1 = s1, *c2 = s2; - unsigned char ch; - int d = 0; - - while ( n-- ) { - /* toupper() expects an unsigned char (implicitly cast to int) - as input, and returns an int, which is exactly what we want. */ - d = toupper(ch = *c1++) - toupper(*c2++); - if ( d || !ch ) - break; - } - - return d; -} diff --git a/klibc/klibc/strncat.c b/klibc/klibc/strncat.c deleted file mode 100644 index 78223152c4..0000000000 --- a/klibc/klibc/strncat.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * strncat.c - */ - -#include -#include - -char *strncat(char *dst, const char *src, size_t n) -{ - char *q = strchr(dst, '\0'); - const char *p = src; - char ch; - - while (n--) { - *q++ = ch = *p++; - if ( !ch ) - return dst; - } - *q = '\0'; - - return dst; -} diff --git a/klibc/klibc/strncmp.c b/klibc/klibc/strncmp.c deleted file mode 100644 index 4dbde1389f..0000000000 --- a/klibc/klibc/strncmp.c +++ /dev/null @@ -1,20 +0,0 @@ -/* - * strncmp.c - */ - -#include - -int strncmp(const char *s1, const char *s2, size_t n) -{ - const unsigned char *c1 = s1, *c2 = s2; - unsigned char ch; - int d = 0; - - while ( n-- ) { - d = (int)(ch = *c1++) - (int)*c2++; - if ( d || !ch ) - break; - } - - return d; -} diff --git a/klibc/klibc/strncpy.c b/klibc/klibc/strncpy.c deleted file mode 100644 index 06964f31d6..0000000000 --- a/klibc/klibc/strncpy.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * strncpy.c - */ - -#include - -char *strncpy(char *dst, const char *src, size_t n) -{ - char *q = dst; - const char *p = src; - char ch; - - while (n) { - n--; - *q++ = ch = *p++; - if ( !ch ) - break; - } - - /* The specs say strncpy() fills the entire buffer with NUL. Sigh. */ - memset(q, 0, n); - - return dst; -} diff --git a/klibc/klibc/strndup.c b/klibc/klibc/strndup.c deleted file mode 100644 index 1b44e6f99a..0000000000 --- a/klibc/klibc/strndup.c +++ /dev/null @@ -1,17 +0,0 @@ -/* - * strndup.c - */ - -#include -#include - -char *strndup(const char *s, size_t n) -{ - int l = n > strlen(s) ? strlen(s)+1 : n+1; - char *d = malloc(l); - - if (d) - memcpy(d, s, l); - d[n] = '\0'; - return d; -} diff --git a/klibc/klibc/strnlen.c b/klibc/klibc/strnlen.c deleted file mode 100644 index 06b54c3189..0000000000 --- a/klibc/klibc/strnlen.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * strnlen() - */ - -#include - -size_t strnlen(const char *s, size_t maxlen) -{ - const char *ss = s; - - /* Important: the maxlen test must precede the reference through ss; - since the byte beyond the maximum may segfault */ - while ((maxlen > 0) && *ss) { - ss++; - maxlen--; - } - return ss-s; -} - diff --git a/klibc/klibc/strntoimax.c b/klibc/klibc/strntoimax.c deleted file mode 100644 index f53a266dba..0000000000 --- a/klibc/klibc/strntoimax.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * strntoimax.c - * - * strntoimax() - */ - -#include -#include - -intmax_t strntoimax(const char *nptr, char **endptr, int base, size_t n) -{ - return (intmax_t) strntoumax(nptr, endptr, base, n); -} diff --git a/klibc/klibc/strntoumax.c b/klibc/klibc/strntoumax.c deleted file mode 100644 index 4c47fe8662..0000000000 --- a/klibc/klibc/strntoumax.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * strntoumax.c - * - * The strntoumax() function and associated - */ - -#include -#include -#include - -static inline int digitval(int ch) -{ - if ( ch >= '0' && ch <= '9' ) { - return ch-'0'; - } else if ( ch >= 'A' && ch <= 'Z' ) { - return ch-'A'+10; - } else if ( ch >= 'a' && ch <= 'z' ) { - return ch-'a'+10; - } else { - return -1; - } -} - -uintmax_t strntoumax(const char *nptr, char **endptr, int base, size_t n) -{ - int minus = 0; - uintmax_t v = 0; - int d; - - while ( n && isspace((unsigned char)*nptr) ) { - nptr++; - n--; - } - - /* Single optional + or - */ - if ( n ) { - char c = *nptr; - if ( c == '-' || c == '+' ) { - minus = (c == '-'); - nptr++; - n--; - } - } - - if ( base == 0 ) { - if ( n >= 2 && nptr[0] == '0' && - (nptr[1] == 'x' || nptr[1] == 'X') ) { - n -= 2; - nptr += 2; - base = 16; - } else if ( n >= 1 && nptr[0] == '0' ) { - n--; - nptr++; - base = 8; - } else { - base = 10; - } - } else if ( base == 16 ) { - if ( n >= 2 && nptr[0] == '0' && - (nptr[1] == 'x' || nptr[1] == 'X') ) { - n -= 2; - nptr += 2; - } - } - - while ( n && (d = digitval(*nptr)) >= 0 && d < base ) { - v = v*base + d; - n--; - nptr++; - } - - if ( endptr ) - *endptr = (char *)nptr; - - return minus ? -v : v; -} diff --git a/klibc/klibc/strpbrk.c b/klibc/klibc/strpbrk.c deleted file mode 100644 index 86ea236308..0000000000 --- a/klibc/klibc/strpbrk.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * strpbrk - */ - -#include "strxspn.h" - -char * -strpbrk(const char *s, const char *accept) -{ - const char *ss = s+__strxspn(s, accept, 1); - - return *ss ? (char *)ss : NULL; -} - diff --git a/klibc/klibc/strrchr.c b/klibc/klibc/strrchr.c deleted file mode 100644 index 5a0cbe386e..0000000000 --- a/klibc/klibc/strrchr.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * strrchr.c - */ - -#include -#include - -char *strrchr(const char *s, int c) -{ - const char *found = NULL; - - while ( *s ) { - if ( *s == (char) c ) - found = s; - s++; - } - - return (char *)found; -} - -__ALIAS(char *, rindex, (const char *, int), strrchr) diff --git a/klibc/klibc/strsep.c b/klibc/klibc/strsep.c deleted file mode 100644 index 58a7a07773..0000000000 --- a/klibc/klibc/strsep.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * strsep.c - */ - -#include - -char *strsep(char **stringp, const char *delim) -{ - char *s = *stringp; - char *e; - - if ( !s ) - return NULL; - - e = strpbrk(s, delim); - if (e) - *e++ = '\0'; - - *stringp = e; - return s; -} diff --git a/klibc/klibc/strspn.c b/klibc/klibc/strspn.c deleted file mode 100644 index 10b1dfc5fa..0000000000 --- a/klibc/klibc/strspn.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * strspn - */ - -#include "strxspn.h" - -size_t -strspn(const char *s, const char *accept) -{ - return __strxspn(s, accept, 0); -} diff --git a/klibc/klibc/strstr.c b/klibc/klibc/strstr.c deleted file mode 100644 index 10222dfd30..0000000000 --- a/klibc/klibc/strstr.c +++ /dev/null @@ -1,10 +0,0 @@ -/* - * strstr.c - */ - -#include - -char *strstr(const char *haystack, const char *needle) -{ - return (char *)memmem(haystack, strlen(haystack), needle, strlen(needle)); -} diff --git a/klibc/klibc/strtoimax.c b/klibc/klibc/strtoimax.c deleted file mode 100644 index 0cdd088e51..0000000000 --- a/klibc/klibc/strtoimax.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE intmax_t -#define NAME strtoimax -#include "strtox.c" diff --git a/klibc/klibc/strtok.c b/klibc/klibc/strtok.c deleted file mode 100644 index 6e84f1dff3..0000000000 --- a/klibc/klibc/strtok.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * strtok.c - */ - -#include - -char *strtok(char *s, const char *delim) -{ - static char *holder; - - if ( s ) - holder = s; - - return strsep(&holder, delim); -} - diff --git a/klibc/klibc/strtol.c b/klibc/klibc/strtol.c deleted file mode 100644 index 9efc8b9e4a..0000000000 --- a/klibc/klibc/strtol.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE signed long -#define NAME strtol -#include "strtox.c" diff --git a/klibc/klibc/strtoll.c b/klibc/klibc/strtoll.c deleted file mode 100644 index a9428c7f14..0000000000 --- a/klibc/klibc/strtoll.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE signed long long -#define NAME strtoll -#include "strtox.c" diff --git a/klibc/klibc/strtotimespec.c b/klibc/klibc/strtotimespec.c deleted file mode 100644 index b426bf8d0f..0000000000 --- a/klibc/klibc/strtotimespec.c +++ /dev/null @@ -1,5 +0,0 @@ -#define NAME strtotimespec -#define TIMEX struct timespec -#define FSEC tv_nsec -#define DECIMALS 9 -#include "strtotimex.c" diff --git a/klibc/klibc/strtotimeval.c b/klibc/klibc/strtotimeval.c deleted file mode 100644 index 280d4bcd3a..0000000000 --- a/klibc/klibc/strtotimeval.c +++ /dev/null @@ -1,5 +0,0 @@ -#define NAME strtotimeval -#define TIMEX struct timeval -#define FSEC tv_usec -#define DECIMALS 6 -#include "strtotimex.c" diff --git a/klibc/klibc/strtotimex.c b/klibc/klibc/strtotimex.c deleted file mode 100644 index 0f6c2f9181..0000000000 --- a/klibc/klibc/strtotimex.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * strtotimex.c - * - * Nonstandard function which takes a string and converts it to a - * struct timespec/timeval. Returns a pointer to the first non-numeric - * character in the string. - * - */ - -#include -#include -#include -#include - -char * NAME (const char *str, TIMEX *ts) -{ - int n; - char *s, *s0; - __typeof__(ts->FSEC) fs; /* Fractional seconds */ - - ts->tv_sec = strntoumax(str, &s, 10, ~(size_t)0); - fs = 0; - - if ( *s == '.' ) { - s0 = s+1; - - fs = strntoumax(s0, &s, 10, DECIMALS); - n = s-s0; - - while ( isdigit(*s) ) - s++; - - for ( ; n < DECIMALS ; n++ ) - fs *= 10; - } - - ts->FSEC = fs; - return s; -} diff --git a/klibc/klibc/strtoul.c b/klibc/klibc/strtoul.c deleted file mode 100644 index 3189aaa7ce..0000000000 --- a/klibc/klibc/strtoul.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE unsigned long -#define NAME strtoul -#include "strtox.c" diff --git a/klibc/klibc/strtoull.c b/klibc/klibc/strtoull.c deleted file mode 100644 index 83c14e9128..0000000000 --- a/klibc/klibc/strtoull.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE unsigned long long -#define NAME strtoull -#include "strtox.c" diff --git a/klibc/klibc/strtoumax.c b/klibc/klibc/strtoumax.c deleted file mode 100644 index a3797105e8..0000000000 --- a/klibc/klibc/strtoumax.c +++ /dev/null @@ -1,3 +0,0 @@ -#define TYPE uintmax_t -#define NAME strtoumax -#include "strtox.c" diff --git a/klibc/klibc/strtox.c b/klibc/klibc/strtox.c deleted file mode 100644 index 7c228b6fa4..0000000000 --- a/klibc/klibc/strtox.c +++ /dev/null @@ -1,13 +0,0 @@ -/* - * strtox.c - * - * strto...() functions, by macro definition - */ - -#include -#include - -TYPE NAME (const char *nptr, char **endptr, int base) -{ - return (TYPE) strntoumax(nptr, endptr, base, ~(size_t)0); -} diff --git a/klibc/klibc/strxspn.c b/klibc/klibc/strxspn.c deleted file mode 100644 index 618c0bcdb5..0000000000 --- a/klibc/klibc/strxspn.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * strpbrk - */ - -#include -#include -#include -#include -#include "strxspn.h" - -size_t -__strxspn(const char *s, const char *map, int parity) -{ - char matchmap[UCHAR_MAX+1]; - size_t n = 0; - - /* Create bitmap */ - memset(matchmap, 0, sizeof matchmap); - while ( *map ) - matchmap[(unsigned char) *map++] = 1; - - /* Make sure the null character never matches */ - matchmap[0] = parity; - - /* Calculate span length */ - while ( matchmap[(unsigned char) *s++] ^ parity ) - n++; - - return n; -} diff --git a/klibc/klibc/strxspn.h b/klibc/klibc/strxspn.h deleted file mode 100644 index 5e1a21922f..0000000000 --- a/klibc/klibc/strxspn.h +++ /dev/null @@ -1,13 +0,0 @@ -/* - * strxspn.h - */ - -#ifndef STRXSPN_H -#define STRXSPN_H - -#include - -extern size_t -__strxspn(const char *s, const char *map, int parity); - -#endif diff --git a/klibc/klibc/syscalls.pl b/klibc/klibc/syscalls.pl deleted file mode 100644 index 0575fa6648..0000000000 --- a/klibc/klibc/syscalls.pl +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/perl -# -# Script to parse the SYSCALLS file and generate appropriate -# stubs. - -$v = $ENV{'KBUILD_VERBOSE'}; -$quiet = defined($v) ? !$v : 0; - -@args = (); -for $arg ( @ARGV ) { - if ( $arg =~ /^-/ ) { - if ( $arg eq '-q' ) { - $quiet = 1; - } else { - die "$0: Unknown option: $arg\n"; - } - } else { - push(@args, $arg); - } -} -($file, $sysstub, $arch, $bits, $unistd, $outputdir, $havesyscall) = @args; - -require "$sysstub"; - -if (!open(UNISTD, '<', $unistd)) { - die "$0: $unistd: $!\n"; -} - -while ( defined($line = ) ) { - chomp $line; - - if ( $line =~ /^\#\s*define\s+__NR_([A-Za-z0-9_]+)\s+(.*\S)\s*$/ ) { - $syscalls{$1} = $2; - print STDERR "SYSCALL FOUND: $1\n" unless ( $quiet ); - } -} -close(UNISTD); - -if (!open(HAVESYS, '>', $havesyscall)) { - die "$0: $havesyscall: $!\n"; -} - -print HAVESYS "#ifndef _KLIBC_HAVESYSCALL_H\n"; -print HAVESYS "#define _KLIBC_HAVESYSCALL_H 1\n\n"; - -if (!open(FILE, '<', $file)) { - die "$0: $file: $!\n"; -} - -print "syscall-objs := "; - -while ( defined($line = ) ) { - chomp $line; - $line =~ s/\s*(|[\#;].*)$//; # Strip comments and trailing blanks - next unless $line; - - if ( $line =~ /^\s*(\<[^\>]+\>\s+|)([A-Za-z0-9_\*\s]+)\s+([A-Za-z0-9_,]+)(|\@[A-Za-z0-9_]+)(|\:\:[A-Za-z0-9_]+)\s*\(([^\:\)]*)\)\s*$/ ) { - $archs = $1; - $type = $2; - $snames = $3; - $stype = $4; - $fname = $5; - $argv = $6; - - $doit = 1; - $maybe = 0; - if ( $archs ne '' ) { - die "$file:$.: Invalid architecture spec: <$archs>\n" - unless ( $archs =~ /^\<(|\?)(|\!)([^\>\!\?]*)\>/ ); - $maybe = $1 ne ''; - $not = $2 ne ''; - $list = $3; - - $doit = $not || ($list eq ''); - - @list = split(/,/, $list); - foreach $a ( @list ) { - if ( $a eq $arch || $a eq $bits ) { - $doit = !$not; - last; - } - } - } - next if ( ! $doit ); - - undef $sname; - foreach $sn ( split(/,/, $snames) ) { - if ( defined $syscalls{$sn} ) { - $sname = $sn; - last; - } - } - if ( !defined($sname) ) { - next if ( $maybe ); - die "$file:$.: Undefined system call: $snames\n"; - } - - $type =~ s/\s*$//; - $stype =~ s/^\@//; - - if ( $fname eq '' ) { - $fname = $sname; - } else { - $fname =~ s/^\:\://; - } - - @args = split(/\s*\,\s*/, $argv); - - print HAVESYS "#define _KLIBC_HAVE_SYSCALL_${fname} ${sname}\n"; - print " \\\n\t${fname}.o"; - make_sysstub($outputdir, $fname, $type, $sname, $stype, @args); - } else { - die "$file:$.: Could not parse input: \"$line\"\n"; - } -} - -print "\n"; - -print HAVESYS "\n#endif\n"; -close(HAVESYS); diff --git a/klibc/klibc/syscommon.h b/klibc/klibc/syscommon.h deleted file mode 100644 index 429025279e..0000000000 --- a/klibc/klibc/syscommon.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * syscommon.h - * - * Common header file for system call stubs - */ - -#define __IN_SYS_COMMON -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __i386__ -# include -#endif diff --git a/klibc/klibc/syslog.c b/klibc/klibc/syslog.c deleted file mode 100644 index 0cd296ab85..0000000000 --- a/klibc/klibc/syslog.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * syslog.c - * - * Issue syslog messages via the kernel printk queue. - */ - -#include -#include -#include -#include -#include -#include - -/* Maximum size for a kernel message */ -#define BUFLEN 1024 - -/* Logging node */ -#define LOGDEV "/dev/kmsg" - -/* Max length of ID string */ -#define MAXID 31 /* MAXID+5 must be < BUFLEN */ - -int __syslog_fd = -1; -static char id[MAXID+1]; -static int syslog_flags = 0; - -void openlog(const char *ident, int option, int facility) -{ - int fd; - - (void)option; (void)facility; /* Unused */ - - if ( __syslog_fd == -1 ) { - __syslog_fd = fd = open(LOGDEV, O_WRONLY); - if ( fd == -1 ) - return; - fcntl(fd, F_SETFD, (long)FD_CLOEXEC); - } - - syslog_flags = option; - - strncpy(id, ident?ident:"", MAXID); -} - -void vsyslog(int prio, const char *format, va_list ap) -{ - char buf[BUFLEN]; - int len; - int fd; - - if ( __syslog_fd == -1 ) - openlog(NULL, 0, 0); - - buf[0] = '<'; - buf[1] = LOG_PRI(prio)+'0'; - buf[2] = '>'; - len = 3; - - if ( syslog_flags & LOG_PID ) - len += sprintf(buf+3, "%s[%u]: ", id, getpid()); - else if ( *id ) - len += sprintf(buf+3, "%s: ", id); - - len += vsnprintf(buf+len, BUFLEN-len, format, ap); - - if ( len > BUFLEN-1 ) len = BUFLEN-1; - if (buf[len-1] != '\n') - buf[len++] = '\n'; - - fd = __syslog_fd; - if ( fd == -1 ) - fd = 2; /* Failed to open log, write to stderr */ - - write(fd, buf, len); - - if ( syslog_flags & LOG_PERROR ) - _fwrite(buf+3, len-3, stderr); -} - -void syslog(int prio, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vsyslog(prio, format, ap); - va_end(ap); -} diff --git a/klibc/klibc/system.c b/klibc/klibc/system.c deleted file mode 100644 index 643bf5e1cc..0000000000 --- a/klibc/klibc/system.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * system.c - * - * The system() function. If this turns out to actually be *used*, - * we may want to try to detect the very simple cases (no shell magic) - * and handle them internally, instead of requiring that /bin/sh be - * present. - */ - -#include -#include -#include -#include -#include - -int system(const char *string) -{ - pid_t pid; - struct sigaction ignore, old_int, old_quit; - sigset_t masked, oldmask; - static const char *argv[] = { "/bin/sh", "-c", NULL, NULL }; - int status; - - /* Block SIGCHLD and ignore SIGINT and SIGQUIT */ - /* Do this before the fork() to avoid races */ - - ignore.sa_handler = SIG_IGN; - sigemptyset(&ignore.sa_mask); - ignore.sa_flags = 0; - sigaction(SIGINT, &ignore, &old_int); - sigaction(SIGQUIT, &ignore, &old_quit); - - sigemptyset(&masked); - sigaddset(&masked, SIGCHLD); - sigprocmask(SIG_BLOCK, &masked, &oldmask); - - pid = fork(); - - if ( pid < 0 ) - return -1; - else if ( pid == 0 ) { - sigaction(SIGINT, &old_int, NULL); - sigaction(SIGQUIT, &old_quit, NULL); - sigprocmask(SIG_SETMASK, &oldmask, NULL); - - argv[2] = string; - - execve(argv[0], (char * const *)argv, (char * const *)environ); - _exit(127); - } - - /* else... */ - - waitpid(pid, &status, 0); - - sigaction(SIGINT, &old_int, NULL); - sigaction(SIGQUIT, &old_quit, NULL); - sigprocmask(SIG_SETMASK, &oldmask, NULL); - - return status; -} diff --git a/klibc/klibc/sysv_signal.c b/klibc/klibc/sysv_signal.c deleted file mode 100644 index 3e55a02bb5..0000000000 --- a/klibc/klibc/sysv_signal.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * sysv_signal.c - */ - -#include - -__sighandler_t sysv_signal(int signum, __sighandler_t handler) -{ - /* Linux/SysV signal() semantics */ - return __signal(signum, handler, SA_RESETHAND); -} diff --git a/klibc/klibc/time.c b/klibc/klibc/time.c deleted file mode 100644 index 92f82ccee0..0000000000 --- a/klibc/klibc/time.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * time.c - */ - -#include -#include -#include - -#ifndef __NR_time - -time_t time(time_t *t) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - - if ( t ) - *t = (time_t)tv.tv_sec; - - return (time_t)tv.tv_sec; -} - -#endif diff --git a/klibc/klibc/umount.c b/klibc/klibc/umount.c deleted file mode 100644 index 9a8e62a779..0000000000 --- a/klibc/klibc/umount.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * umount.c - * - * Single-argument form of umount - */ - -#include - -int umount(const char *dir) -{ - return umount2(dir, 0); -} diff --git a/klibc/klibc/unsetenv.c b/klibc/klibc/unsetenv.c deleted file mode 100644 index 5f39f3d8f9..0000000000 --- a/klibc/klibc/unsetenv.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * unsetenv.c - */ - -#include -#include -#include -#include - -int unsetenv(const char *name) -{ - size_t len; - char **p, *q; - const char *z; - - if ( !name || !name[0] ) { - errno = EINVAL; - return -1; - } - - len = 0; - for ( z = name ; *z ; z++ ) { - len++; - if ( *z == '=' ) { - errno = EINVAL; - return -1; - } - } - - for ( p = environ ; (q = *p) ; p++ ) { - if ( !strncmp(name,q,len) && q[len] == '=' ) - break; - } - - for ( ; (q = *p) ; p++ ) { - p[0] = p[1]; - } - - return 0; -} diff --git a/klibc/klibc/usleep.c b/klibc/klibc/usleep.c deleted file mode 100644 index b63352eebf..0000000000 --- a/klibc/klibc/usleep.c +++ /dev/null @@ -1,15 +0,0 @@ -/* - * usleep.c - */ - -#include -#include - -void usleep(unsigned long usec) -{ - struct timespec ts; - - ts.tv_sec = usec/1000000UL; - ts.tv_nsec = (usec%1000000UL) * 1000; - while ( nanosleep(&ts,&ts) == -1 && errno == EINTR ); -} diff --git a/klibc/klibc/utime.c b/klibc/klibc/utime.c deleted file mode 100644 index 2c8607756a..0000000000 --- a/klibc/klibc/utime.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * utime.c - */ - -#include -#include -#include -#include - -#ifndef __NR_utime - -int utime(const char *filename, const struct utimbuf *buf) -{ - struct timeval tvp[2]; - - tvp[0].tv_sec = buf->actime; - tvp[0].tv_usec = 0; - tvp[1].tv_sec = buf->modtime; - tvp[1].tv_usec = 0; - - return utimes(filename, tvp); -} - -#endif diff --git a/klibc/klibc/vasprintf.c b/klibc/klibc/vasprintf.c deleted file mode 100644 index 657bfdc3ef..0000000000 --- a/klibc/klibc/vasprintf.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * vasprintf.c - */ - -#include -#include -#include - -int vasprintf(char **bufp, const char *format, va_list ap) -{ - va_list ap1; - int bytes; - char *p; - - va_copy(ap1, ap); - - bytes = vsnprintf(NULL, 0, format, ap1) + 1; - va_end(ap1); - - *bufp = p = malloc(bytes); - if ( !p ) - return -1; - - return vsnprintf(p, bytes, format, ap); -} diff --git a/klibc/klibc/vfprintf.c b/klibc/klibc/vfprintf.c deleted file mode 100644 index 39cf9838f6..0000000000 --- a/klibc/klibc/vfprintf.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * vfprintf.c - */ - -#include -#include -#include -#include - -#define BUFFER_SIZE 32768 - -int vfprintf(FILE *file, const char *format, va_list ap) -{ - int rv; - char buffer[BUFFER_SIZE]; - - rv = vsnprintf(buffer, BUFFER_SIZE, format, ap); - - if ( rv < 0 ) - return rv; - - if ( rv > BUFFER_SIZE-1 ) - rv = BUFFER_SIZE-1; - - return _fwrite(buffer, rv, file); -} diff --git a/klibc/klibc/vprintf.c b/klibc/klibc/vprintf.c deleted file mode 100644 index 7d6066586f..0000000000 --- a/klibc/klibc/vprintf.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * vprintf.c - */ - -#include -#include - -int vprintf(const char *format, va_list ap) -{ - return vfprintf(stdout, format, ap); -} diff --git a/klibc/klibc/vsnprintf.c b/klibc/klibc/vsnprintf.c deleted file mode 100644 index 5cb9331954..0000000000 --- a/klibc/klibc/vsnprintf.c +++ /dev/null @@ -1,433 +0,0 @@ -/* - * vsnprintf.c - * - * vsnprintf(), from which the rest of the printf() - * family is built - */ - -#include -#include -#include -#include -#include -#include - -enum flags { - FL_ZERO = 0x01, /* Zero modifier */ - FL_MINUS = 0x02, /* Minus modifier */ - FL_PLUS = 0x04, /* Plus modifier */ - FL_TICK = 0x08, /* ' modifier */ - FL_SPACE = 0x10, /* Space modifier */ - FL_HASH = 0x20, /* # modifier */ - FL_SIGNED = 0x40, /* Number is signed */ - FL_UPPER = 0x80 /* Upper case digits */ -}; - -/* These may have to be adjusted on certain implementations */ -enum ranks { - rank_char = -2, - rank_short = -1, - rank_int = 0, - rank_long = 1, - rank_longlong = 2 -}; - -#define MIN_RANK rank_char -#define MAX_RANK rank_longlong - -#define INTMAX_RANK rank_longlong -#define SIZE_T_RANK rank_long -#define PTRDIFF_T_RANK rank_long - -#define EMIT(x) ({ if (o nchars ) { - while ( width > nchars ) { - EMIT(' '); - width--; - } - } - - /* Emit nondigits */ - if ( minus ) - EMIT('-'); - else if ( flags & FL_PLUS ) - EMIT('+'); - else if ( flags & FL_SPACE ) - EMIT(' '); - - if ( (flags & FL_HASH) && base == 16 ) { - EMIT('0'); - EMIT((flags & FL_UPPER) ? 'X' : 'x'); - } - - /* Emit zero padding */ - if ( (flags & (FL_MINUS|FL_ZERO)) == FL_ZERO && width > ndigits ) { - while ( width > nchars ) { - EMIT('0'); - width--; - } - } - - /* Generate the number. This is done from right to left. */ - q += ndigits; /* Advance the pointer to end of number */ - o += ndigits; - qq = q; oo = o; /* Temporary values */ - - b4tick = tickskip; - while ( ndigits > 0 ) { - if ( !b4tick-- ) { - qq--; oo--; ndigits--; - if ( oo < n ) *qq = '_'; - b4tick = tickskip-1; - } - qq--; oo--; ndigits--; - if ( oo < n ) *qq = digits[val%base]; - val /= base; - } - - /* Emit late space padding */ - while ( (flags & FL_MINUS) && width > nchars ) { - EMIT(' '); - width--; - } - - return o; -} - - -int vsnprintf(char *buffer, size_t n, const char *format, va_list ap) -{ - const char *p = format; - char ch; - char *q = buffer; - size_t o = 0; /* Number of characters output */ - uintmax_t val = 0; - int rank = rank_int; /* Default rank */ - int width = 0; - int prec = -1; - int base; - size_t sz; - enum flags flags = 0; - enum { - st_normal, /* Ground state */ - st_flags, /* Special flags */ - st_width, /* Field width */ - st_prec, /* Field precision */ - st_modifiers /* Length or conversion modifiers */ - } state = st_normal; - const char *sarg; /* %s string argument */ - char carg; /* %c char argument */ - int slen; /* String length */ - - while ( (ch = *p++) ) { - switch ( state ) { - case st_normal: - if ( ch == '%' ) { - state = st_flags; - flags = 0; rank = rank_int; width = 0; prec = -1; - } else { - EMIT(ch); - } - break; - - case st_flags: - switch ( ch ) { - case '-': - flags |= FL_MINUS; - break; - case '+': - flags |= FL_PLUS; - break; - case '\'': - flags |= FL_TICK; - break; - case ' ': - flags |= FL_SPACE; - break; - case '#': - flags |= FL_HASH; - break; - case '0': - flags |= FL_ZERO; - break; - default: - state = st_width; - p--; /* Process this character again */ - break; - } - break; - - case st_width: - if ( ch >= '0' && ch <= '9' ) { - width = width*10+(ch-'0'); - } else if ( ch == '*' ) { - width = va_arg(ap, int); - if ( width < 0 ) { - width = -width; - flags |= FL_MINUS; - } - } else if ( ch == '.' ) { - prec = 0; /* Precision given */ - state = st_prec; - } else { - state = st_modifiers; - p--; /* Process this character again */ - } - break; - - case st_prec: - if ( ch >= '0' && ch <= '9' ) { - prec = prec*10+(ch-'0'); - } else if ( ch == '*' ) { - prec = va_arg(ap, int); - if ( prec < 0 ) - prec = -1; - } else { - state = st_modifiers; - p--; /* Process this character again */ - } - break; - - case st_modifiers: - switch ( ch ) { - /* Length modifiers - nonterminal sequences */ - case 'h': - rank--; /* Shorter rank */ - break; - case 'l': - rank++; /* Longer rank */ - break; - case 'j': - rank = INTMAX_RANK; - break; - case 'z': - rank = SIZE_T_RANK; - break; - case 't': - rank = PTRDIFF_T_RANK; - break; - case 'L': - case 'q': - rank += 2; - break; - default: - /* Output modifiers - terminal sequences */ - state = st_normal; /* Next state will be normal */ - if ( rank < MIN_RANK ) /* Canonicalize rank */ - rank = MIN_RANK; - else if ( rank > MAX_RANK ) - rank = MAX_RANK; - - switch ( ch ) { - case 'P': /* Upper case pointer */ - flags |= FL_UPPER; - /* fall through */ - case 'p': /* Pointer */ - base = 16; - prec = (CHAR_BIT*sizeof(void *)+3)/4; - flags |= FL_HASH; - val = (uintmax_t)(uintptr_t)va_arg(ap, void *); - goto is_integer; - - case 'd': /* Signed decimal output */ - case 'i': - base = 10; - flags |= FL_SIGNED; - switch (rank) { - case rank_char: - /* Yes, all these casts are needed... */ - val = (uintmax_t)(intmax_t)(signed char)va_arg(ap, signed int); - break; - case rank_short: - val = (uintmax_t)(intmax_t)(signed short)va_arg(ap, signed int); - break; - case rank_int: - val = (uintmax_t)(intmax_t)va_arg(ap, signed int); - break; - case rank_long: - val = (uintmax_t)(intmax_t)va_arg(ap, signed long); - break; - case rank_longlong: - val = (uintmax_t)(intmax_t)va_arg(ap, signed long long); - break; - } - goto is_integer; - case 'o': /* Octal */ - base = 8; - goto is_unsigned; - case 'u': /* Unsigned decimal */ - base = 10; - goto is_unsigned; - case 'X': /* Upper case hexadecimal */ - flags |= FL_UPPER; - /* fall through */ - case 'x': /* Hexadecimal */ - base = 16; - goto is_unsigned; - - is_unsigned: - switch (rank) { - case rank_char: - val = (uintmax_t)(unsigned char)va_arg(ap, unsigned int); - break; - case rank_short: - val = (uintmax_t)(unsigned short)va_arg(ap, unsigned int); - break; - case rank_int: - val = (uintmax_t)va_arg(ap, unsigned int); - break; - case rank_long: - val = (uintmax_t)va_arg(ap, unsigned long); - break; - case rank_longlong: - val = (uintmax_t)va_arg(ap, unsigned long long); - break; - } - /* fall through */ - - is_integer: - sz = format_int(q, (o prec ) - slen = prec; - - if ( width > slen && !(flags & FL_MINUS) ) { - char pad = (flags & FL_ZERO) ? '0' : ' '; - while ( width > slen ) { - EMIT(pad); - width--; - } - } - for ( i = slen ; i ; i-- ) { - sch = *sarg++; - EMIT(sch); - } - if ( width > slen && (flags & FL_MINUS) ) { - while ( width > slen ) { - EMIT(' '); - width--; - } - } - } - break; - - case 'n': /* Output the number of characters written */ - { - switch (rank) { - case rank_char: - *va_arg(ap, signed char *) = o; - break; - case rank_short: - *va_arg(ap, signed short *) = o; - break; - case rank_int: - *va_arg(ap, signed int *) = o; - break; - case rank_long: - *va_arg(ap, signed long *) = o; - break; - case rank_longlong: - *va_arg(ap, signed long long *) = o; - break; - } - } - break; - - default: /* Anything else, including % */ - EMIT(ch); - break; - } - } - } - } - - /* Null-terminate the string */ - if ( o0 ) - buffer[n-1] = '\0'; /* Overflow - terminate at end of buffer */ - - return o; -} diff --git a/klibc/klibc/vsprintf.c b/klibc/klibc/vsprintf.c deleted file mode 100644 index 4a6100e70c..0000000000 --- a/klibc/klibc/vsprintf.c +++ /dev/null @@ -1,11 +0,0 @@ -/* - * vsprintf.c - */ - -#include -#include - -int vsprintf(char *buffer, const char *format, va_list ap) -{ - return vsnprintf(buffer, ~(size_t)0, format, ap); -} diff --git a/klibc/klibc/vsscanf.c b/klibc/klibc/vsscanf.c deleted file mode 100644 index 12a82b2747..0000000000 --- a/klibc/klibc/vsscanf.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * vsscanf.c - * - * vsscanf(), from which the rest of the scanf() - * family is built - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifndef LONG_BIT -#define LONG_BIT (CHAR_BIT*sizeof(long)) -#endif - -enum flags { - FL_SPLAT = 0x01, /* Drop the value, do not assign */ - FL_INV = 0x02, /* Character-set with inverse */ - FL_WIDTH = 0x04, /* Field width specified */ - FL_MINUS = 0x08, /* Negative number */ -}; - -enum ranks { - rank_char = -2, - rank_short = -1, - rank_int = 0, - rank_long = 1, - rank_longlong = 2, - rank_ptr = INT_MAX /* Special value used for pointers */ -}; - -#define MIN_RANK rank_char -#define MAX_RANK rank_longlong - -#define INTMAX_RANK rank_longlong -#define SIZE_T_RANK rank_long -#define PTRDIFF_T_RANK rank_long - -enum bail { - bail_none = 0, /* No error condition */ - bail_eof, /* Hit EOF */ - bail_err /* Conversion mismatch */ -}; - -static inline const char * -skipspace(const char *p) -{ - while ( isspace((unsigned char)*p) ) p++; - return p; -} - -#undef set_bit -static inline void -set_bit(unsigned long *bitmap, unsigned int bit) -{ - bitmap[bit/LONG_BIT] |= 1UL << (bit%LONG_BIT); -} - -#undef test_bit -static inline int -test_bit(unsigned long *bitmap, unsigned int bit) -{ - return (int)(bitmap[bit/LONG_BIT] >> (bit%LONG_BIT)) & 1; -} - -int vsscanf(const char *buffer, const char *format, va_list ap) -{ - const char *p = format; - char ch; - const char *q = buffer; - const char *qq; - uintmax_t val = 0; - int rank = rank_int; /* Default rank */ - unsigned int width = UINT_MAX; - int base; - enum flags flags = 0; - enum { - st_normal, /* Ground state */ - st_flags, /* Special flags */ - st_width, /* Field width */ - st_modifiers, /* Length or conversion modifiers */ - st_match_init, /* Initial state of %[ sequence */ - st_match, /* Main state of %[ sequence */ - st_match_range, /* After - in a %[ sequence */ - } state = st_normal; - char *sarg = NULL; /* %s %c or %[ string argument */ - enum bail bail = bail_none; - int sign; - int converted = 0; /* Successful conversions */ - unsigned long matchmap[((1 << CHAR_BIT)+(LONG_BIT-1))/LONG_BIT]; - int matchinv = 0; /* Is match map inverted? */ - unsigned char range_start = 0; - - while ( (ch = *p++) && !bail ) { - switch ( state ) { - case st_normal: - if ( ch == '%' ) { - state = st_flags; - flags = 0; rank = rank_int; width = UINT_MAX; - } else if ( isspace((unsigned char)ch) ) { - q = skipspace(q); - } else { - if ( *q == ch ) - q++; - else - bail = bail_err; /* Match failure */ - } - break; - - case st_flags: - switch ( ch ) { - case '*': - flags |= FL_SPLAT; - break; - case '0' ... '9': - width = (ch-'0'); - state = st_width; - flags |= FL_WIDTH; - break; - default: - state = st_modifiers; - p--; /* Process this character again */ - break; - } - break; - - case st_width: - if ( ch >= '0' && ch <= '9' ) { - width = width*10+(ch-'0'); - } else { - state = st_modifiers; - p--; /* Process this character again */ - } - break; - - case st_modifiers: - switch ( ch ) { - /* Length modifiers - nonterminal sequences */ - case 'h': - rank--; /* Shorter rank */ - break; - case 'l': - rank++; /* Longer rank */ - break; - case 'j': - rank = INTMAX_RANK; - break; - case 'z': - rank = SIZE_T_RANK; - break; - case 't': - rank = PTRDIFF_T_RANK; - break; - case 'L': - case 'q': - rank = rank_longlong; /* long double/long long */ - break; - - default: - /* Output modifiers - terminal sequences */ - state = st_normal; /* Next state will be normal */ - if ( rank < MIN_RANK ) /* Canonicalize rank */ - rank = MIN_RANK; - else if ( rank > MAX_RANK ) - rank = MAX_RANK; - - switch ( ch ) { - case 'P': /* Upper case pointer */ - case 'p': /* Pointer */ -#if 0 /* Enable this to allow null pointers by name */ - q = skipspace(q); - if ( !isdigit((unsigned char)*q) ) { - static const char * const nullnames[] = - { "null", "nul", "nil", "(null)", "(nul)", "(nil)", 0 }; - const char * const *np; - - /* Check to see if it's a null pointer by name */ - for ( np = nullnames ; *np ; np++ ) { - if ( !strncasecmp(q, *np, strlen(*np)) ) { - val = (uintmax_t)((void *)NULL); - goto set_integer; - } - } - /* Failure */ - bail = bail_err; - break; - } - /* else */ -#endif - rank = rank_ptr; - base = 0; sign = 0; - goto scan_int; - - case 'i': /* Base-independent integer */ - base = 0; sign = 1; - goto scan_int; - - case 'd': /* Decimal integer */ - base = 10; sign = 1; - goto scan_int; - - case 'o': /* Octal integer */ - base = 8; sign = 0; - goto scan_int; - - case 'u': /* Unsigned decimal integer */ - base = 10; sign = 0; - goto scan_int; - - case 'x': /* Hexadecimal integer */ - case 'X': - base = 16; sign = 0; - goto scan_int; - - case 'n': /* Number of characters consumed */ - val = (q-buffer); - goto set_integer; - - scan_int: - q = skipspace(q); - if ( !*q ) { - bail = bail_eof; - break; - } - val = strntoumax(q, (char **)&qq, base, width); - if ( qq == q ) { - bail = bail_err; - break; - } - q = qq; - converted++; - /* fall through */ - - set_integer: - if ( !(flags & FL_SPLAT) ) { - switch(rank) { - case rank_char: - *va_arg(ap, unsigned char *) = (unsigned char)val; - break; - case rank_short: - *va_arg(ap, unsigned short *) = (unsigned short)val; - break; - case rank_int: - *va_arg(ap, unsigned int *) = (unsigned int)val; - break; - case rank_long: - *va_arg(ap, unsigned long *) = (unsigned long)val; - break; - case rank_longlong: - *va_arg(ap, unsigned long long *) = (unsigned long long)val; - break; - case rank_ptr: - *va_arg(ap, void **) = (void *)(uintptr_t)val; - break; - } - } - break; - - case 'c': /* Character */ - width = (flags & FL_WIDTH) ? width : 1; /* Default width == 1 */ - sarg = va_arg(ap, char *); - while ( width-- ) { - if ( !*q ) { - bail = bail_eof; - break; - } - *sarg++ = *q++; - } - if ( !bail ) - converted++; - break; - - case 's': /* String */ - { - char *sp; - sp = sarg = va_arg(ap, char *); - while ( width-- && *q && !isspace((unsigned char)*q) ) { - *sp++ = *q++; - } - if ( sarg != sp ) { - *sp = '\0'; /* Terminate output */ - converted++; - } else { - bail = bail_eof; - } - } - break; - - case '[': /* Character range */ - sarg = va_arg(ap, char *); - state = st_match_init; - matchinv = 0; - memset(matchmap, 0, sizeof matchmap); - break; - - case '%': /* %% sequence */ - if ( *q == '%' ) - q++; - else - bail = bail_err; - break; - - default: /* Anything else */ - bail = bail_err; /* Unknown sequence */ - break; - } - } - break; - - case st_match_init: /* Initial state for %[ match */ - if ( ch == '^' && !(flags & FL_INV) ) { - matchinv = 1; - } else { - set_bit(matchmap, (unsigned char)ch); - state = st_match; - } - break; - - case st_match: /* Main state for %[ match */ - if ( ch == ']' ) { - goto match_run; - } else if ( ch == '-' ) { - range_start = (unsigned char)ch; - state = st_match_range; - } else { - set_bit(matchmap, (unsigned char)ch); - } - break; - - case st_match_range: /* %[ match after - */ - if ( ch == ']' ) { - set_bit(matchmap, (unsigned char)'-'); /* - was last character */ - goto match_run; - } else { - int i; - for ( i = range_start ; i < (unsigned char)ch ; i++ ) - set_bit(matchmap, i); - state = st_match; - } - break; - - match_run: /* Match expression finished */ - qq = q; - while ( width && *q && test_bit(matchmap, (unsigned char)*q)^matchinv ) { - *sarg++ = *q++; - } - if ( q != qq ) { - *sarg = '\0'; - converted++; - } else { - bail = *q ? bail_err : bail_eof; - } - break; - } - } - - if ( bail == bail_eof && !converted ) - converted = -1; /* Return EOF (-1) */ - - return converted; -} diff --git a/klibc/klibc/wait.c b/klibc/klibc/wait.c deleted file mode 100644 index 5e0bbe29c5..0000000000 --- a/klibc/klibc/wait.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * wait.c - */ - -#include -#include -#include - -pid_t wait(int *status) -{ - return wait4((pid_t)-1, status, 0, NULL); -} diff --git a/klibc/klibc/wait3.c b/klibc/klibc/wait3.c deleted file mode 100644 index 48840ad155..0000000000 --- a/klibc/klibc/wait3.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * wait3.c - */ - -#include -#include -#include - -pid_t wait3(int *status, int options, struct rusage *rusage) -{ - return wait4((pid_t)-1, status, options, rusage); -} diff --git a/klibc/klibc/waitpid.c b/klibc/klibc/waitpid.c deleted file mode 100644 index f7c5cbfbc0..0000000000 --- a/klibc/klibc/waitpid.c +++ /dev/null @@ -1,12 +0,0 @@ -/* - * waitpid.c - */ - -#include -#include -#include - -pid_t waitpid(pid_t pid, int *status, int options) -{ - return wait4(pid, status, options, NULL); -} diff --git a/klibc/klibc/zlib/FAQ b/klibc/klibc/zlib/FAQ deleted file mode 100644 index 7115ec38d6..0000000000 --- a/klibc/klibc/zlib/FAQ +++ /dev/null @@ -1,315 +0,0 @@ - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://www.zlib.org which may have more recent information. -The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. - See the file win32/DLL_FAQ.txt in the zlib distribution. - Pointers to the precompiled DLL are found in the zlib web site at - http://www.zlib.org. - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://www.winimage.com/zLibDll/ - * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm - * contrib/visual-basic.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR - - Make sure that before the call of compress, the length of the compressed - buffer is equal to the total size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR - - Before making the call, make sure that avail_in and avail_out are not - zero. When setting the parameter flush equal to Z_FINISH, also make sure - that avail_out is big enough to allow processing all pending input. - Note that a Z_BUF_ERROR is not fatal--another call to deflate() or - inflate() can be made with more input or output space. A Z_BUF_ERROR - may in fact be unavoidable depending on how the functions are used, since - it is not possible to tell whether or not there is more output pending - when strm.avail_out returns with zero. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h for the moment, and Francis S. Lin has converted it to a - web page zlib.html. Volunteers to transform this to Unix-style man pages, - please contact Jean-loup Gailly (jloup@gzip.org). Examples of zlib usage - are in the files example.c and minigzip.c. - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple - package. zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of - zlib. Please try to reproduce the problem with a small program and send - the corresponding source to us at zlib@gzip.org . Do not send - multi-megabyte data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - See the directory contrib/minizip in the zlib distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - make clean - ./configure -s - make - -14. How do I install a shared zlib library on Unix? - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include , it's there. The -lz option will probably link to it. - -15. I have a question about OttoPDF - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site Joel Hainley jhainley@myndkryme.com. - -16. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip - formats use the same compressed data format internally, but have different - headers and trailers around the compressed data. - -17. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about - a single file, such as the name and last modification date. The zlib - format on the other hand was designed for in-memory and communication - channel applications, and has a much more compact header and trailer and - uses a faster integrity check than gzip. - -18. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode - the gzip format using inflateInit2(). Read zlib.h for more details. - - Note that you cannot specify special gzip header contents (e.g. a file - name or modification date), nor will inflate tell you what was in the - gzip header. If you need to customize the header or see what's in it, - you can use the raw deflate and inflate operations and the crc32() - function and roll your own gzip encoding and decoding. Read the gzip - RFC 1952 for details of the header and trailer format. - -19. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's Init functions allow - for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -20. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -21. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -22. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -23. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -24. Will zlib work on a 64-bit machine? - - It should. It has been tested on 64-bit machines, and has no dependence - on any data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to zlib@gzip.org - -25. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format - than does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -26. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically - use Z_FULL_FLUSH, carefully write all the pending data at those points, - and keep an index of those locations, then you can start decompression - at those points. You have to be careful to not use Z_FULL_FLUSH too - often, since it can significantly degrade compression. - -27. Does zlib work on MVS, OS/390, CICS, etc.? - - We don't know for sure. We have heard occasional reports of success on - these systems. If you do use it on one of these, please provide us with - a report, instructions, and patches that we can reference when we get - these questions. Thanks. - -28. Is there some simpler, easier to read version of inflate I can look at - to understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -29. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -30. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit - only if the compiler's "long" type is 32 bits. If the compiler's "long" - type is 64 bits, then the limit is 16 exabytes. - -31. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib - is compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of a 4K string space, other than the caller of - gzprintf() assuring that the output will not exceed 4K. On the other - hand, if zlib is compiled to use snprintf() or vsnprintf(), which should - normally be the case, then there is no vulnerability. The ./configure - script will display warnings if an insecure variation of sprintf() will - be used by gzprintf(). Also the zlibCompileFlags() function will return - information on what variant of sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability. - -32. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://www.zlib.org/ - -33. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pendantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly. So now, we simply make sure that the code always - works. - -34. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -35. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very weak - and can be broken with freely available programs. To get strong encryption, - use gpg ( http://www.gnupg.org/ ) which already includes zlib compression. - For PKZIP compatible "encryption", look at http://www.info-zip.org/ - -36. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion - with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specficiation in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -37. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. - In any case, the compression improvements are so modest compared to other - more modern approaches, that it's not worth the effort to implement. - -38. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/klibc/klibc/zlib/INDEX b/klibc/klibc/zlib/INDEX deleted file mode 100644 index a9de7844d1..0000000000 --- a/klibc/klibc/zlib/INDEX +++ /dev/null @@ -1,48 +0,0 @@ -ChangeLog history of changes -FAQ Frequently Asked Questions about zlib -INDEX this file -Makefile makefile for Unix (generated by configure) -Makefile.in makefile for Unix (template for configure) -README guess what -algorithm.txt description of the (de)compression algorithm -configure configure script for Unix -zconf.in.h template for zconf.h (used by configure) - -msdos/ makefiles for MSDOS -old/ makefiles for various architectures and zlib documentation - files that have not yet been updated for zlib 1.2.x -qnx/ makefiles for QNX -win32/ makefiles for Windows - - zlib public header files (must be kept): -zconf.h -zlib.h - - private source files used to build the zlib library: -adler32.c -compress.c -crc32.c -crc32.h -deflate.c -deflate.h -gzio.c -infback.c -inffast.c -inffast.h -inffixed.h -inflate.c -inflate.h -inftrees.c -inftrees.h -trees.c -trees.h -uncompr.c -zutil.c -zutil.h - - source files for sample programs: -example.c -minigzip.c - - unsupported contribution by third parties -See contrib/README.contrib diff --git a/klibc/klibc/zlib/README b/klibc/klibc/zlib/README deleted file mode 100644 index 0f1205481c..0000000000 --- a/klibc/klibc/zlib/README +++ /dev/null @@ -1,126 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.1 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). These documents are also available in other -formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example -of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The -compression library itself is composed of all source files except example.c and -minigzip.c. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile. In short "make test; make install" should work for most -machines. For Unix: "./configure; make test; make install" For MSDOS, use one -of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or -descrip.mms. - -Questions about zlib should be sent to , or to Gilles Vollant - for the Windows DLL version. The zlib home page is -http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, -please check this site to verify that you have the latest version of zlib; -otherwise get the latest version and check whether the problem still exists or -not. - -PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking -for help. - -Mark Nelson wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available in -http://dogma.net/markn/articles/zlibtool/zlibtool.htm - -The changes made in version 1.2.1 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory "contrib". - -A Java implementation of zlib is available in the Java Development Kit -http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html -See the zlib home page http://www.zlib.org for details. - -A Perl interface to zlib written by Paul Marquess is in the -CPAN (Comprehensive Perl Archive Network) sites -http://www.cpan.org/modules/by-module/Compress/ - -A Python interface to zlib written by A.M. Kuchling is -available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html - -A zlib binding for TCL written by Andreas Kupries is -availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant , is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - -- When building a shared, i.e. dynamic library on Mac OS X, the library must be - installed before testing (do "make install" before "make test"), since the - library location is specified in the library. - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate - and zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; - they are too numerous to cite here. - -Copyright notice: - - (C) 1995-2003 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - -If you use the zlib library in a product, we would appreciate *not* -receiving lengthy legal documents to sign. The sources are provided -for free but without warranty of any kind. The library has been -entirely written by Jean-loup Gailly and Mark Adler; it does not -include third-party code. - -If you redistribute modified sources, we would appreciate that you include -in the file ChangeLog history information documenting your changes. Please -read the FAQ for more information on the distribution of modified source -versions. diff --git a/klibc/klibc/zlib/adler32.c b/klibc/klibc/zlib/adler32.c deleted file mode 100644 index 48c08f094a..0000000000 --- a/klibc/klibc/zlib/adler32.c +++ /dev/null @@ -1,74 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: adler32.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {s1 += buf[i]; s2 += s1;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? (int)len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - buf += 16; - k -= 16; - } - if (k != 0) do { - s1 += *buf++; - s2 += s1; - } while (--k); - MOD(s1); - MOD(s2); - } - return (s2 << 16) | s1; -} diff --git a/klibc/klibc/zlib/algorithm.txt b/klibc/klibc/zlib/algorithm.txt deleted file mode 100644 index b022dde312..0000000000 --- a/klibc/klibc/zlib/algorithm.txt +++ /dev/null @@ -1,209 +0,0 @@ -1. Compression algorithm (deflate) - -The deflation algorithm used by gzip (also zip and zlib) is a variation of -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in -the input data. The second occurrence of a string is replaced by a -pointer to the previous string, in the form of a pair (distance, -length). Distances are limited to 32K bytes, and lengths are limited -to 258 bytes. When a string does not occur anywhere in the previous -32K bytes, it is emitted as a sequence of literal bytes. (In this -description, `string' must be taken as an arbitrary sequence of bytes, -and is not restricted to printable characters.) - -Literals or match lengths are compressed with one Huffman tree, and -match distances are compressed with another tree. The trees are stored -in a compact form at the start of each block. The blocks can have any -size (except that the compressed data for one block must fit in -available memory). A block is terminated when deflate() determines that -it would be useful to start another block with fresh trees. (This is -somewhat similar to the behavior of LZW-based _compress_.) - -Duplicated strings are found using a hash table. All input strings of -length 3 are inserted in the hash table. A hash index is computed for -the next 3 bytes. If the hash chain for this index is not empty, all -strings in the chain are compared with the current input string, and -the longest match is selected. - -The hash chains are searched starting with the most recent strings, to -favor small distances and thus take advantage of the Huffman encoding. -The hash chains are singly linked. There are no deletions from the -hash chains, the algorithm simply discards matches that are too old. - -To avoid a worst-case situation, very long hash chains are arbitrarily -truncated at a certain length, determined by a runtime option (level -parameter of deflateInit). So deflate() does not always find the longest -possible match but generally finds a match which is long enough. - -deflate() also defers the selection of matches with a lazy evaluation -mechanism. After a match of length N has been found, deflate() searches for -a longer match at the next input byte. If a longer match is found, the -previous match is truncated to a length of one (thus producing a single -literal byte) and the process of lazy evaluation begins again. Otherwise, -the original match is kept, and the next match search is attempted only N -steps later. - -The lazy match evaluation is also subject to a runtime parameter. If -the current match is long enough, deflate() reduces the search for a longer -match, thus speeding up the whole process. If compression ratio is more -important than speed, deflate() attempts a complete second search even if -the first match is already long enough. - -The lazy match evaluation is not performed for the fastest compression -modes (level parameter 1 to 3). For these fast modes, new strings -are inserted in the hash table only when no match was found, or -when the match is not too long. This degrades the compression ratio -but saves time since there are both fewer insertions and fewer searches. - - -2. Decompression algorithm (inflate) - -2.1 Introduction - -The key question is how to represent a Huffman code (or any prefix code) so -that you can decode fast. The most important characteristic is that shorter -codes are much more common than longer codes, so pay attention to decoding the -short codes fast, and let the long codes take longer to decode. - -inflate() sets up a first level table that covers some number of bits of -input less than the length of longest code. It gets that many bits from the -stream, and looks it up in the table. The table will tell if the next -code is that many bits or less and how many, and if it is, it will tell -the value, else it will point to the next level table for which inflate() -grabs more bits and tries to decode a longer code. - -How many bits to make the first lookup is a tradeoff between the time it -takes to decode and the time it takes to build the table. If building the -table took no time (and if you had infinite memory), then there would only -be a first level table to cover all the way to the longest code. However, -building the table ends up taking a lot longer for more bits since short -codes are replicated many times in such a table. What inflate() does is -simply to make the number of bits in the first table a variable, and then -to set that variable for the maximum speed. - -For inflate, which has 286 possible codes for the literal/length tree, the size -of the first table is nine bits. Also the distance trees have 30 possible -values, and the size of the first table is six bits. Note that for each of -those cases, the table ended up one bit longer than the ``average'' code -length, i.e. the code length of an approximately flat code which would be a -little more than eight bits for 286 symbols and a little less than five bits -for 30 symbols. - - -2.2 More details on the inflate table lookup - -Ok, you want to know what this cleverly obfuscated inflate tree actually -looks like. You are correct that it's not a Huffman tree. It is simply a -lookup table for the first, let's say, nine bits of a Huffman symbol. The -symbol could be as short as one bit or as long as 15 bits. If a particular -symbol is shorter than nine bits, then that symbol's translation is duplicated -in all those entries that start with that symbol's bits. For example, if the -symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a -symbol is nine bits long, it appears in the table once. - -If the symbol is longer than nine bits, then that entry in the table points -to another similar table for the remaining bits. Again, there are duplicated -entries as needed. The idea is that most of the time the symbol will be short -and there will only be one table look up. (That's whole idea behind data -compression in the first place.) For the less frequent long symbols, there -will be two lookups. If you had a compression method with really long -symbols, you could have as many levels of lookups as is efficient. For -inflate, two is enough. - -So a table entry either points to another table (in which case nine bits in -the above example are gobbled), or it contains the translation for the symbol -and the number of bits to gobble. Then you start again with the next -ungobbled bit. - -You may wonder: why not just have one lookup table for how ever many bits the -longest symbol is? The reason is that if you do that, you end up spending -more time filling in duplicate symbol entries than you do actually decoding. -At least for deflate's output that generates new trees every several 10's of -kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code -would take too long if you're only decoding several thousand symbols. At the -other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend two much time -traversing the tree while decoding, even for short symbols. - -So the number of bits for the first lookup table is a trade of the time to -fill out the table vs. the time spent looking at the second level and above of -the table. - -Here is an example, scaled down: - -The code being decoded, with 10 symbols, from 1 to 6 bits long: - -A: 0 -B: 10 -C: 1100 -D: 11010 -E: 11011 -F: 11100 -G: 11101 -H: 11110 -I: 111110 -J: 111111 - -Let's make the first table three bits long (eight entries): - -000: A,1 -001: A,1 -010: A,1 -011: A,1 -100: B,2 -101: B,2 -110: -> table X (gobble 3 bits) -111: -> table Y (gobble 3 bits) - -Each entry is what the bits decode as and how many bits that is, i.e. how -many bits to gobble. Or the entry points to another table, with the number of -bits to gobble implicit in the size of the table. - -Table X is two bits long since the longest code starting with 110 is five bits -long: - -00: C,1 -01: C,1 -10: D,2 -11: E,2 - -Table Y is three bits long since the longest code starting with 111 is six -bits long: - -000: F,2 -001: F,2 -010: G,2 -011: G,2 -100: H,2 -101: H,2 -110: I,3 -111: J,3 - -So what we have here are three tables with a total of 20 entries that had to -be constructed. That's compared to 64 entries for a single table. Or -compared to 16 entries for a Huffman tree (six two entry tables and one four -entry table). Assuming that the code ideally represents the probability of -the symbols, it takes on the average 1.25 lookups per symbol. That's compared -to one lookup for the single table, or 1.66 lookups per symbol for the -Huffman tree. - -There, I think that gives you a picture of what's going on. For inflate, the -meaning of a particular symbol is often more than just a letter. It can be a -byte (a "literal"), or it can be either a length or a distance which -indicates a base value and a number of bits to fetch after the code that is -added to the base value. Or it might be the special end-of-block code. The -data structures created in inftrees.c try to encode all that information -compactly in the tables. - - -Jean-loup Gailly Mark Adler -jloup@gzip.org madler@alumni.caltech.edu - - -References: - -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, -pp. 337-343. - -``DEFLATE Compressed Data Format Specification'' available in -http://www.ietf.org/rfc/rfc1951.txt diff --git a/klibc/klibc/zlib/compress.c b/klibc/klibc/zlib/compress.c deleted file mode 100644 index 3f4b44266a..0000000000 --- a/klibc/klibc/zlib/compress.c +++ /dev/null @@ -1,79 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2002 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: compress.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; -} diff --git a/klibc/klibc/zlib/crc32.c b/klibc/klibc/zlib/crc32.c deleted file mode 100644 index 0bb9c49ab1..0000000000 --- a/klibc/klibc/zlib/crc32.c +++ /dev/null @@ -1,311 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results about a factor - * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id: crc32.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -#ifdef DYNAMIC_CRC_TABLE - -local int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); -#endif /* MAKECRCH */ - -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - unsigned long c; - int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, and - then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const unsigned long FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const u4 FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const u4 FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ diff --git a/klibc/klibc/zlib/crc32.h b/klibc/klibc/zlib/crc32.h deleted file mode 100644 index 8053b6117c..0000000000 --- a/klibc/klibc/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const unsigned long FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/klibc/klibc/zlib/deflate.c b/klibc/klibc/zlib/deflate.c deleted file mode 100644 index fe07dcb673..0000000000 --- a/klibc/klibc/zlib/deflate.c +++ /dev/null @@ -1,1502 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id: deflate.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.1 Copyright 1995-2003 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifndef FASTEST -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif -#endif -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_RLE) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); -#ifndef USE_DICT_HEAD - dictionary += dictLength - length; /* use the tail of the dictionary */ -#endif - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds - * for every combination of windowBits and memLevel, as well as wrap. - * But even the conservative upper bound of about 14% expansion does not - * seem onerous for output buffer allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong destLen; - - /* conservative upper bound */ - destLen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; - - /* if can't get parameters, return conservative bound */ - if (strm == Z_NULL || strm->state == Z_NULL) - return destLen; - - /* if not default parameters, return conservative bound */ - s = strm->state; - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return destLen; - - /* default settings: return tight bound for that case */ - return compressBound(sourceLen); -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, 255); - s->status = BUSY_STATE; - strm->adler = crc32(0L, Z_NULL, 0); - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - *dest = *source; - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - *ds = *ss; - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2: - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ -#endif /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for level == 1 or strategy == Z_RLE only - */ -local uInt longest_match_fast(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ -#ifdef FASTEST - if ((s->strategy < Z_HUFFMAN_ONLY) || - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { - s->match_length = longest_match_fast (s, hash_head); - } -#else - if (s->strategy < Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } -#endif - /* longest_match() or longest_match_fast() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy < Z_HUFFMAN_ONLY) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } - /* longest_match() or longest_match_fast() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ diff --git a/klibc/klibc/zlib/deflate.h b/klibc/klibc/zlib/deflate.h deleted file mode 100644 index bc79532e59..0000000000 --- a/klibc/klibc/zlib/deflate.h +++ /dev/null @@ -1,326 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2002 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id: deflate.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - int pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - Byte data_type; /* UNKNOWN, BINARY or ASCII */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch _length_code[]; - extern uch _dist_code[]; -#else - extern const uch _length_code[]; - extern const uch _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/klibc/klibc/zlib/gzio.c b/klibc/klibc/zlib/gzio.c deleted file mode 100644 index cb56b8d381..0000000000 --- a/klibc/klibc/zlib/gzio.c +++ /dev/null @@ -1,1008 +0,0 @@ -/* gzio.c -- IO on .gz files - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. - */ - -/* @(#) $Id: gzio.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#include - -#include "zutil.h" - -#ifdef NO_DEFLATE /* for compatiblity with old definition */ -# define NO_GZCOMPRESS -#endif - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef Z_BUFSIZE -# ifdef MAXSEG_64K -# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ -# else -# define Z_BUFSIZE 16384 -# endif -#endif -#ifndef Z_PRINTF_BUFSIZE -# define Z_PRINTF_BUFSIZE 4096 -#endif - -#ifdef __MVS__ -# pragma map (fdopen , "\174\174FDOPEN") - FILE *fdopen(int, const char *); -#endif - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern void free OF((voidpf ptr)); -#endif - -#define ALLOC(size) malloc(size) -#define TRYFREE(p) {if (p) free(p);} - -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -typedef struct gz_stream { - z_stream stream; - int z_err; /* error code for last stream operation */ - int z_eof; /* set if end of input file */ - FILE *file; /* .gz file */ - Byte *inbuf; /* input buffer */ - Byte *outbuf; /* output buffer */ - uLong crc; /* crc32 of uncompressed data */ - char *msg; /* error message */ - char *path; /* path name for debugging only */ - int transparent; /* 1 if input file is not a .gz file */ - char mode; /* 'w' or 'r' */ - z_off_t start; /* start of compressed data in file (header skipped) */ - z_off_t in; /* bytes into deflate or inflate */ - z_off_t out; /* bytes out of deflate or inflate */ - int back; /* one character push-back */ - int last; /* true if push-back is last character */ -} gz_stream; - - -local gzFile gz_open OF((const char *path, const char *mode, int fd)); -local int do_flush OF((gzFile file, int flush)); -local int get_byte OF((gz_stream *s)); -local void check_header OF((gz_stream *s)); -local int destroy OF((gz_stream *s)); -local void putLong OF((FILE *file, uLong x)); -local uLong getLong OF((gz_stream *s)); - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb"). The file is given either by file descriptor - or path name (if fd == -1). - gz_open returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). -*/ -local gzFile gz_open (path, mode, fd) - const char *path; - const char *mode; - int fd; -{ - int err; - int level = Z_DEFAULT_COMPRESSION; /* compression level */ - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ - char *p = (char*)mode; - gz_stream *s; - char fmode[80]; /* copy of mode, without the compression level */ - char *m = fmode; - - if (!path || !mode) return Z_NULL; - - s = (gz_stream *)ALLOC(sizeof(gz_stream)); - if (!s) return Z_NULL; - - s->stream.zalloc = (alloc_func)0; - s->stream.zfree = (free_func)0; - s->stream.opaque = (voidpf)0; - s->stream.next_in = s->inbuf = Z_NULL; - s->stream.next_out = s->outbuf = Z_NULL; - s->stream.avail_in = s->stream.avail_out = 0; - s->file = NULL; - s->z_err = Z_OK; - s->z_eof = 0; - s->in = 0; - s->out = 0; - s->back = EOF; - s->crc = crc32(0L, Z_NULL, 0); - s->msg = NULL; - s->transparent = 0; - - s->path = (char*)ALLOC(strlen(path)+1); - if (s->path == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - strcpy(s->path, path); /* do this early for debugging */ - - s->mode = '\0'; - do { - if (*p == 'r') s->mode = 'r'; - if (*p == 'w' || *p == 'a') s->mode = 'w'; - if (*p >= '0' && *p <= '9') { - level = *p - '0'; - } else if (*p == 'f') { - strategy = Z_FILTERED; - } else if (*p == 'h') { - strategy = Z_HUFFMAN_ONLY; - } else if (*p == 'R') { - strategy = Z_RLE; - } else { - *m++ = *p; /* copy the mode */ - } - } while (*p++ && m != fmode + sizeof(fmode)); - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateInit2(&(s->stream), level, - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); - /* windowBits is passed < 0 to suppress zlib header */ - - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); -#endif - if (err != Z_OK || s->outbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } else { - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); - - err = inflateInit2(&(s->stream), -MAX_WBITS); - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are - * present after the compressed stream. - */ - if (err != Z_OK || s->inbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } - s->stream.avail_out = Z_BUFSIZE; - - errno = 0; - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); - - if (s->file == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - if (s->mode == 'w') { - /* Write a very simple .gz header: - */ - fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); - s->start = 10L; - /* We use 10L instead of ftell(s->file) to because ftell causes an - * fflush on some systems. This version of the library doesn't use - * start anyway in write mode, so this initialization is not - * necessary. - */ - } else { - check_header(s); /* skip the .gz header */ - s->start = ftell(s->file) - s->stream.avail_in; - } - - return (gzFile)s; -} - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. -*/ -gzFile ZEXPORT gzopen (path, mode) - const char *path; - const char *mode; -{ - return gz_open (path, mode, -1); -} - -/* =========================================================================== - Associate a gzFile with the file descriptor fd. fd is not dup'ed here - to mimic the behavio(u)r of fdopen. -*/ -gzFile ZEXPORT gzdopen (fd, mode) - int fd; - const char *mode; -{ - char name[20]; - - if (fd < 0) return (gzFile)Z_NULL; - sprintf(name, "", fd); /* for debugging */ - - return gz_open (name, mode, fd); -} - -/* =========================================================================== - * Update the compression level and strategy - */ -int ZEXPORT gzsetparams (file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - /* Make room to allow flushing */ - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - } - s->stream.avail_out = Z_BUFSIZE; - } - - return deflateParams (&(s->stream), level, strategy); -} - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ -local int get_byte(s) - gz_stream *s; -{ - if (s->z_eof) return EOF; - if (s->stream.avail_in == 0) { - errno = 0; - s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - /* klibc hack */ - if (errno) s->z_err = Z_ERRNO; - return EOF; - } - s->stream.next_in = s->inbuf; - } - s->stream.avail_in--; - return *(s->stream.next_in)++; -} - -/* =========================================================================== - Check the gzip header of a gz_stream opened for reading. Set the stream - mode to transparent if the gzip magic header is not present; set s->err - to Z_DATA_ERROR if the magic header is present but the rest of the header - is incorrect. - IN assertion: the stream s has already been created sucessfully; - s->stream.avail_in is zero for the first time, but may be non-zero - for concatenated .gz files. -*/ -local void check_header(s) - gz_stream *s; -{ - int method; /* method byte */ - int flags; /* flags byte */ - uInt len; - int c; - - /* Assure two bytes in the buffer so we can peek ahead -- handle case - where first byte of header is at the end of the buffer after the last - gzip segment */ - len = s->stream.avail_in; - if (len < 2) { - if (len) s->inbuf[0] = s->stream.next_in[0]; - errno = 0; - len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); - /* klibc hack */ - if (len == 0 && errno) s->z_err = Z_ERRNO; - s->stream.avail_in += len; - s->stream.next_in = s->inbuf; - if (s->stream.avail_in < 2) { - s->transparent = s->stream.avail_in; - return; - } - } - - /* Peek ahead to check the gzip magic header */ - if (s->stream.next_in[0] != gz_magic[0] || - s->stream.next_in[1] != gz_magic[1]) { - s->transparent = 1; - return; - } - s->stream.avail_in -= 2; - s->stream.next_in += 2; - - /* Check the rest of the gzip header */ - method = get_byte(s); - flags = get_byte(s); - if (method != Z_DEFLATED || (flags & RESERVED) != 0) { - s->z_err = Z_DATA_ERROR; - return; - } - - /* Discard time, xflags and OS code: */ - for (len = 0; len < 6; len++) (void)get_byte(s); - - if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ - len = (uInt)get_byte(s); - len += ((uInt)get_byte(s))<<8; - /* len is garbage if EOF but the loop below will quit anyway */ - while (len-- != 0 && get_byte(s) != EOF) ; - } - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ - for (len = 0; len < 2; len++) (void)get_byte(s); - } - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; -} - - /* =========================================================================== - * Cleanup then free the given gz_stream. Return a zlib error code. - Try freeing in the reverse order of allocations. - */ -local int destroy (s) - gz_stream *s; -{ - int err = Z_OK; - - if (!s) return Z_STREAM_ERROR; - - TRYFREE(s->msg); - - if (s->stream.state != NULL) { - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateEnd(&(s->stream)); -#endif - } else if (s->mode == 'r') { - err = inflateEnd(&(s->stream)); - } - } - if (s->file != NULL && fclose(s->file)) { -#ifdef ESPIPE - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ -#endif - err = Z_ERRNO; - } - if (s->z_err < 0) err = s->z_err; - - TRYFREE(s->inbuf); - TRYFREE(s->outbuf); - TRYFREE(s->path); - TRYFREE(s); - return err; -} - -/* =========================================================================== - Reads the given number of uncompressed bytes from the compressed file. - gzread returns the number of bytes actually read (0 for end of file). -*/ -int ZEXPORT gzread (file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - Bytef *start = (Bytef*)buf; /* starting point for crc computation */ - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ - - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; - - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; - if (s->z_err == Z_STREAM_END) return 0; /* EOF */ - - next_out = (Byte*)buf; - s->stream.next_out = (Bytef*)buf; - s->stream.avail_out = len; - - if (s->stream.avail_out && s->back != EOF) { - *next_out++ = s->back; - s->stream.next_out++; - s->stream.avail_out--; - s->back = EOF; - s->out++; - if (s->last) { - s->z_err = Z_STREAM_END; - return 1; - } - } - - while (s->stream.avail_out != 0) { - - if (s->transparent) { - /* Copy first the lookahead bytes: */ - uInt n = s->stream.avail_in; - if (n > s->stream.avail_out) n = s->stream.avail_out; - if (n > 0) { - zmemcpy(s->stream.next_out, s->stream.next_in, n); - next_out += n; - s->stream.next_out = next_out; - s->stream.next_in += n; - s->stream.avail_out -= n; - s->stream.avail_in -= n; - } - if (s->stream.avail_out > 0) { - s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out, - s->file); - } - len -= s->stream.avail_out; - s->in += len; - s->out += len; - if (len == 0) s->z_eof = 1; - return (int)len; - } - if (s->stream.avail_in == 0 && !s->z_eof) { - - errno = 0; - s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (errno) { - s->z_err = Z_ERRNO; - break; - } - } - s->stream.next_in = s->inbuf; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = inflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - - if (s->z_err == Z_STREAM_END) { - /* Check CRC and original size */ - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - start = s->stream.next_out; - - if (getLong(s) != s->crc) { - s->z_err = Z_DATA_ERROR; - } else { - (void)getLong(s); - /* The uncompressed length returned by above getlong() may be - * different from s->out in case of concatenated .gz files. - * Check for such files: - */ - check_header(s); - if (s->z_err == Z_OK) { - inflateReset(&(s->stream)); - s->crc = crc32(0L, Z_NULL, 0); - } - } - } - if (s->z_err != Z_OK || s->z_eof) break; - } - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - - return (int)(len - s->stream.avail_out); -} - - -/* =========================================================================== - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ -int ZEXPORT gzgetc(file) - gzFile file; -{ - unsigned char c; - - return gzread(file, &c, 1) == 1 ? c : -1; -} - - -/* =========================================================================== - Push one byte back onto the stream. -*/ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; - s->back = c; - s->out--; - s->last = (s->z_err == Z_STREAM_END); - if (s->last) s->z_err = Z_OK; - s->z_eof = 0; - return c; -} - - -/* =========================================================================== - Reads bytes from the compressed file until len-1 characters are - read, or a newline character is read and transferred to buf, or an - end-of-file condition is encountered. The string is then terminated - with a null character. - gzgets returns buf, or Z_NULL in case of error. - - The current implementation is not optimized at all. -*/ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - char *b = buf; - if (buf == Z_NULL || len <= 0) return Z_NULL; - - while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; - *buf = '\0'; - return b == buf && len > 0 ? Z_NULL : b; -} - - -#ifndef NO_GZCOMPRESS -/* =========================================================================== - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of bytes actually written (0 in case of error). -*/ -int ZEXPORT gzwrite (file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.next_in = (Bytef*)buf; - s->stream.avail_in = len; - - while (s->stream.avail_in != 0) { - - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - break; - } - s->stream.avail_out = Z_BUFSIZE; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - if (s->z_err != Z_OK) break; - } - s->crc = crc32(s->crc, (const Bytef *)buf, len); - - return (int)(len - s->stream.avail_in); -} - - -/* =========================================================================== - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). -*/ -#ifdef STDC -#include - -int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) -{ - char buf[Z_PRINTF_BUFSIZE]; - va_list va; - int len; - - buf[sizeof(buf) - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(buf, format, va); - va_end(va); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = vsprintf(buf, format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(buf, sizeof(buf), format, va); - va_end(va); - len = strlen(buf); -# else - len = vsnprintf(buf, sizeof(buf), format, va); - va_end(va); -# endif -#endif - if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, (unsigned)len); -} -#else /* not ANSI C */ - -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - char buf[Z_PRINTF_BUFSIZE]; - int len; - - buf[sizeof(buf) - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(buf); -# else - len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, len); -} -#endif - -/* =========================================================================== - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char cc = (unsigned char) c; /* required for big endian systems */ - - return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; -} - - -/* =========================================================================== - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ -int ZEXPORT gzputs(file, s) - gzFile file; - const char *s; -{ - return gzwrite(file, (char*)s, (unsigned)strlen(s)); -} - - -/* =========================================================================== - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. -*/ -local int do_flush (file, flush) - gzFile file; - int flush; -{ - uInt len; - int done = 0; - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.avail_in = 0; /* should be zero already anyway */ - - for (;;) { - len = Z_BUFSIZE - s->stream.avail_out; - - if (len != 0) { - if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { - s->z_err = Z_ERRNO; - return Z_ERRNO; - } - s->stream.next_out = s->outbuf; - s->stream.avail_out = Z_BUFSIZE; - } - if (done) break; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), flush); - s->out -= s->stream.avail_out; - - /* Ignore the second of two consecutive flushes: */ - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; - - /* deflate has finished flushing only when it hasn't used up - * all the available space in the output buffer: - */ - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); - - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; - } - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} - -int ZEXPORT gzflush (file, flush) - gzFile file; - int flush; -{ - gz_stream *s = (gz_stream*)file; - int err = do_flush (file, flush); - - if (err) return err; - fflush(s->file); - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} -#endif /* NO_GZCOMPRESS */ - -/* =========================================================================== - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error. - SEEK_END is not implemented, returns error. - In this version of the library, gzseek can be extremely slow. -*/ -z_off_t ZEXPORT gzseek (file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || whence == SEEK_END || - s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { - return -1L; - } - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return -1L; -#else - if (whence == SEEK_SET) { - offset -= s->in; - } - if (offset < 0) return -1L; - - /* At this point, offset is the number of zero bytes to write. */ - if (s->inbuf == Z_NULL) { - s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ - if (s->inbuf == Z_NULL) return -1L; - zmemzero(s->inbuf, Z_BUFSIZE); - } - while (offset > 0) { - uInt size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (uInt)offset; - - size = gzwrite(file, s->inbuf, size); - if (size == 0) return -1L; - - offset -= size; - } - return s->in; -#endif - } - /* Rest of function is for reading only */ - - /* compute absolute position */ - if (whence == SEEK_CUR) { - offset += s->out; - } - if (offset < 0) return -1L; - - if (s->transparent) { - /* map to fseek */ - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; - - s->in = s->out = offset; - return offset; - } - - /* For a negative seek, rewind and use positive seek */ - if (offset >= s->out) { - offset -= s->out; - } else if (gzrewind(file) < 0) { - return -1L; - } - /* offset is now the number of bytes to skip. */ - - if (offset != 0 && s->outbuf == Z_NULL) { - s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); - if (s->outbuf == Z_NULL) return -1L; - } - if (offset && s->back != EOF) { - s->back = EOF; - s->out++; - offset--; - if (s->last) s->z_err = Z_STREAM_END; - } - while (offset > 0) { - int size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (int)offset; - - size = gzread(file, s->outbuf, (uInt)size); - if (size <= 0) return -1L; - offset -= size; - } - return s->out; -} - -/* =========================================================================== - Rewinds input file. -*/ -int ZEXPORT gzrewind (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return -1; - - s->z_err = Z_OK; - s->z_eof = 0; - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - s->crc = crc32(0L, Z_NULL, 0); - if (!s->transparent) (void)inflateReset(&s->stream); - s->in = 0; - s->out = 0; - return fseek(s->file, s->start, SEEK_SET); -} - -/* =========================================================================== - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. -*/ -z_off_t ZEXPORT gztell (file) - gzFile file; -{ - return gzseek(file, 0L, SEEK_CUR); -} - -/* =========================================================================== - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ -int ZEXPORT gzeof (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - /* With concatenated compressed files that can have embedded - * crc trailers, z_eof is no longer the only/best indicator of EOF - * on a gz_stream. Handle end-of-stream error explicitly here. - */ - if (s == NULL || s->mode != 'r') return 0; - if (s->z_eof) return 1; - return s->z_err == Z_STREAM_END; -} - -/* =========================================================================== - Outputs a long in LSB order to the given file -*/ -local void putLong (file, x) - FILE *file; - uLong x; -{ - int n; - for (n = 0; n < 4; n++) { - fputc((int)(x & 0xff), file); - x >>= 8; - } -} - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets z_err in case - of error. -*/ -local uLong getLong (s) - gz_stream *s; -{ - uLong x = (uLong)get_byte(s); - int c; - - x += ((uLong)get_byte(s))<<8; - x += ((uLong)get_byte(s))<<16; - c = get_byte(s); - if (c == EOF) s->z_err = Z_DATA_ERROR; - x += ((uLong)c)<<24; - return x; -} - -/* =========================================================================== - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. -*/ -int ZEXPORT gzclose (file) - gzFile file; -{ - int err; - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return Z_STREAM_ERROR; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return Z_STREAM_ERROR; -#else - err = do_flush (file, Z_FINISH); - if (err != Z_OK) return destroy((gz_stream*)file); - - putLong (s->file, s->crc); - putLong (s->file, (uLong)(s->in & 0xffffffff)); -#endif - } - return destroy((gz_stream*)file); -} - -/* =========================================================================== - Returns the error message for the last error which occured on the - given compressed file. errnum is set to zlib error number. If an - error occured in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ -const char * ZEXPORT gzerror (file, errnum) - gzFile file; - int *errnum; -{ - char *m; - gz_stream *s = (gz_stream*)file; - - if (s == NULL) { - *errnum = Z_STREAM_ERROR; - return (const char*)ERR_MSG(Z_STREAM_ERROR); - } - *errnum = s->z_err; - if (*errnum == Z_OK) return (const char*)""; - - m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); - - if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); - - TRYFREE(s->msg); - s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); - if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); - strcpy(s->msg, s->path); - strcat(s->msg, ": "); - strcat(s->msg, m); - return (const char*)s->msg; -} - -/* =========================================================================== - Clear the error and end-of-file flags, and do the same for the real file. -*/ -void ZEXPORT gzclearerr (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return; - if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; - s->z_eof = 0; - /* klibc hack */ - /* clearerr(s->file); */ -} diff --git a/klibc/klibc/zlib/infback.c b/klibc/klibc/zlib/infback.c deleted file mode 100644 index 110b03b857..0000000000 --- a/klibc/klibc/zlib/infback.c +++ /dev/null @@ -1,619 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_stream FAR *strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (voidpf)state; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->write = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_stream FAR *strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; - } - else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.op && (this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - - /* process literal */ - if (this.op == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (this.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (this.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if ((this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - if (this.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)this.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_stream FAR *strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/klibc/klibc/zlib/inffast.c b/klibc/klibc/zlib/inffast.c deleted file mode 100644 index c716440a92..0000000000 --- a/klibc/klibc/zlib/inffast.c +++ /dev/null @@ -1,305 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - 68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code this; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); - wsize = state->wsize; - whave = state->whave; - write = state->write; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = lcode[hold & lmask]; - dolen: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op == 0) { /* literal */ - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - PUP(out) = (unsigned char)(this.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = dcode[hold & dmask]; - dodist: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - from = window - OFF; - if (write == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (write < op) { /* wrap around window */ - from += wsize + write - op; - op -= write; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (write < len) { /* some from start of window */ - op = write; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += write - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - this = dcode[this.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - this = lcode[this.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and write == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/klibc/klibc/zlib/inffast.h b/klibc/klibc/zlib/inffast.h deleted file mode 100644 index 1e88d2d97b..0000000000 --- a/klibc/klibc/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/klibc/klibc/zlib/inffixed.h b/klibc/klibc/zlib/inffixed.h deleted file mode 100644 index 75ed4b5978..0000000000 --- a/klibc/klibc/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/klibc/klibc/zlib/inflate.c b/klibc/klibc/zlib/inflate.c deleted file mode 100644 index a53b5c7446..0000000000 --- a/klibc/klibc/zlib/inflate.c +++ /dev/null @@ -1,1270 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common write == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->wsize = 0; - state->whave = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (voidpf)state; - if (windowBits < 0) { - state->wrap = 0; - windowBits = -windowBits; - } - else { - state->wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) windowBits &= 15; -#endif - } - if (windowBits < 8 || windowBits > 15) { - ZFREE(strm, state); - strm->state = Z_NULL; - return Z_STREAM_ERROR; - } - state->wbits = (unsigned)windowBits; - state->window = Z_NULL; - return inflateReset(strm); -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->write = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->write = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->write; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->write, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->write = copy; - state->whave = state->wsize; - } - else { - state->write += dist; - if (state->write == state->wsize) state->write = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - if (BITS(4) + 8 > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - } while (len && copy < have); - if (state->flags & 0x02000) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - } while (len && copy < have); - if (state->flags & 0x02000) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; - } - else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - break; - } - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.op && (this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - if ((int)(this.op) == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - state->mode = LIT; - break; - } - if (this.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - if (this.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(this.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->mode = DIST; - case DIST: - for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if ((this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - if (this.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)this.val; - state->extra = (unsigned)(this.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->whave + out - left) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->write) { - copy -= state->write; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->write - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->mode != DICT) return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) return Z_DATA_ERROR; - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - *dest = *source; - *copy = *state; - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) - zmemcpy(window, state->window, 1U << state->wbits); - copy->window = window; - dest->state = (voidpf)copy; - return Z_OK; -} diff --git a/klibc/klibc/zlib/inflate.h b/klibc/klibc/zlib/inflate.h deleted file mode 100644 index 9a12c8fd29..0000000000 --- a/klibc/klibc/zlib/inflate.h +++ /dev/null @@ -1,117 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ -#ifdef GUNZIP - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ -#endif - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN, /* i: waiting for length/lit code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ -#ifdef GUNZIP - LENGTH, /* i: waiting for 32-bit length (gzip) */ -#endif - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to the BAD or MEM mode -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME - NAME -> COMMENT -> HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - Read deflate blocks: - TYPE -> STORED or TABLE or LEN or CHECK - STORED -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN - Read deflate codes: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 7K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ -}; diff --git a/klibc/klibc/zlib/inftrees.c b/klibc/klibc/zlib/inftrees.c deleted file mode 100644 index 3bb56398e1..0000000000 --- a/klibc/klibc/zlib/inftrees.c +++ /dev/null @@ -1,321 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.1 Copyright 1995-2003 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code this; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 76, 66}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) return -1; /* no codes! */ - for (min = 1; min <= MAXBITS; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || (codes - count[0] != 1))) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked when a LENS table is being made - against the space in *table, ENOUGH, minus the maximum space needed by - the worst case distance code, MAXD. This should never happen, but the - sufficiency of ENOUGH has not been proven exhaustively, hence the check. - This assumes that when type == LENS, bits == 9. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - this.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - this.op = (unsigned char)0; - this.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - this.op = (unsigned char)(extra[work[sym]]); - this.val = base[work[sym]]; - } - else { - this.op = (unsigned char)(32 + 64); /* end of block */ - this.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - do { - fill -= incr; - next[(huff >> drop) + fill] = this; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += 1U << curr; - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)(len - drop); - this.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - curr = root; - this.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = this; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/klibc/klibc/zlib/inftrees.h b/klibc/klibc/zlib/inftrees.h deleted file mode 100644 index 82d365a7e9..0000000000 --- a/klibc/klibc/zlib/inftrees.h +++ /dev/null @@ -1,55 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1004 code structures (850 for length/literals - and 154 for distances, the latter actually the result of an - exhaustive search). The true maximum is not known, but the value - below is more than safe. */ -#define ENOUGH 1440 -#define MAXD 154 - -/* Type of code to build for inftable() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -extern int inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/klibc/klibc/zlib/trees.c b/klibc/klibc/zlib/trees.c deleted file mode 100644 index f7748c4dcc..0000000000 --- a/klibc/klibc/zlib/trees.c +++ /dev/null @@ -1,1215 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2003 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id: trees.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if (tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void _tr_flush_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is ascii or binary */ - if (s->data_type == Z_UNKNOWN) set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (eof) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to ASCII or BINARY, using a crude approximation: - * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise. - * IN assertion: the fields freq of dyn_ltree are set and the total of all - * frequencies does not exceed 64K (to fit in an int on 16 bit machines). - */ -local void set_data_type(s) - deflate_state *s; -{ - int n = 0; - unsigned ascii_freq = 0; - unsigned bin_freq = 0; - while (n < 7) bin_freq += s->dyn_ltree[n++].Freq; - while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq; - while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq; - s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII); -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/klibc/klibc/zlib/trees.h b/klibc/klibc/zlib/trees.h deleted file mode 100644 index 72facf900f..0000000000 --- a/klibc/klibc/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/klibc/klibc/zlib/uncompr.c b/klibc/klibc/zlib/uncompr.c deleted file mode 100644 index debee4385e..0000000000 --- a/klibc/klibc/zlib/uncompr.c +++ /dev/null @@ -1,61 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: uncompr.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#define ZLIB_INTERNAL -#include "zlib.h" - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} diff --git a/klibc/klibc/zlib/zconf.h b/klibc/klibc/zlib/zconf.h deleted file mode 100644 index 9b74ce7bd4..0000000000 --- a/klibc/klibc/zlib/zconf.h +++ /dev/null @@ -1,323 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: zconf.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflatePrime z_deflatePrime -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table - -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -#define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/klibc/klibc/zlib/zconf.in.h b/klibc/klibc/zlib/zconf.in.h deleted file mode 100644 index d96c85955c..0000000000 --- a/klibc/klibc/zlib/zconf.in.h +++ /dev/null @@ -1,323 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: zconf.in.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#ifndef ZCONF_H -#define ZCONF_H - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflatePrime z_deflatePrime -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table - -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) -# define WIN32 -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include /* for off_t */ -# include /* for SEEK_* and off_t */ -# ifdef VMS -# include /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -#define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/klibc/klibc/zlib/zlib.3 b/klibc/klibc/zlib/zlib.3 deleted file mode 100644 index 890098449d..0000000000 --- a/klibc/klibc/zlib/zlib.3 +++ /dev/null @@ -1,159 +0,0 @@ -.TH ZLIB 3 "17 November 2003" -.SH NAME -zlib \- compression/decompression library -.SH SYNOPSIS -[see -.I zlib.h -for full description] -.SH DESCRIPTION -The -.I zlib -library is a general purpose data compression library. -The code is thread safe. -It provides in-memory compression and decompression functions, -including integrity checks of the uncompressed data. -This version of the library supports only one compression method (deflation) -but other algorithms will be added later -and will have the same stream interface. -.LP -Compression can be done in a single step if the buffers are large enough -(for example if an input file is mmap'ed), -or can be done by repeated calls of the compression function. -In the latter case, -the application must provide more input and/or consume the output -(providing more output space) before each call. -.LP -The library also supports reading and writing files in -.IR gzip (1) -(.gz) format -with an interface similar to that of stdio. -.LP -The library does not install any signal handler. -The decoder checks the consistency of the compressed data, -so the library should never crash even in case of corrupted input. -.LP -All functions of the compression library are documented in the file -.IR zlib.h . -The distribution source includes examples of use of the library -in the files -.I example.c -and -.IR minigzip.c . -.LP -Changes to this version are documented in the file -.I ChangeLog -that accompanies the source, -and are concerned primarily with bug fixes and portability enhancements. -.LP -A Java implementation of -.I zlib -is available in the Java Development Kit 1.1: -.IP -http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html -.LP -A Perl interface to -.IR zlib , -written by Paul Marquess (pmqs@cpan.org), -is available at CPAN (Comprehensive Perl Archive Network) sites, -including: -.IP -http://www.cpan.org/modules/by-module/Compress/ -.LP -A Python interface to -.IR zlib , -written by A.M. Kuchling (amk@magnet.com), -is available in Python 1.5 and later versions: -.IP -http://www.python.org/doc/lib/module-zlib.html -.LP -A -.I zlib -binding for -.IR tcl (1), -written by Andreas Kupries (a.kupries@westend.com), -is availlable at: -.IP -http://www.westend.com/~kupries/doc/trf/man/man.html -.LP -An experimental package to read and write files in .zip format, -written on top of -.I zlib -by Gilles Vollant (info@winimage.com), -is available at: -.IP -http://www.winimage.com/zLibDll/unzip.html -and also in the -.I contrib/minizip -directory of the main -.I zlib -web site. -.SH "SEE ALSO" -The -.I zlib -web site can be found at either of these locations: -.IP -http://www.zlib.org -.br -http://www.gzip.org/zlib/ -.LP -The data format used by the zlib library is described by RFC -(Request for Comments) 1950 to 1952 in the files: -.IP -http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) -.br -http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) -.br -http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) -.LP -These documents are also available in other formats from: -.IP -ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html -.LP -Mark Nelson (markn@ieee.org) wrote an article about -.I zlib -for the Jan. 1997 issue of Dr. Dobb's Journal; -a copy of the article is available at: -.IP -http://dogma.net/markn/articles/zlibtool/zlibtool.htm -.SH "REPORTING PROBLEMS" -Before reporting a problem, -please check the -.I zlib -web site to verify that you have the latest version of -.IR zlib ; -otherwise, -obtain the latest version and see if the problem still exists. -Please read the -.I zlib -FAQ at: -.IP -http://www.gzip.org/zlib/zlib_faq.html -.LP -before asking for help. -Send questions and/or comments to zlib@gzip.org, -or (for the Windows DLL version) to Gilles Vollant (info@winimage.com). -.SH AUTHORS -Version 1.2.1 -Copyright (C) 1995-2003 Jean-loup Gailly (jloup@gzip.org) -and Mark Adler (madler@alumni.caltech.edu). -.LP -This software is provided "as-is," -without any express or implied warranty. -In no event will the authors be held liable for any damages -arising from the use of this software. -See the distribution directory with respect to requirements -governing redistribution. -The deflate format used by -.I zlib -was defined by Phil Katz. -The deflate and -.I zlib -specifications were written by L. Peter Deutsch. -Thanks to all the people who reported problems and suggested various -improvements in -.IR zlib ; -who are too numerous to cite here. -.LP -UNIX manual page by R. P. C. Rodgers, -U.S. National Library of Medicine (rodgers@nlm.nih.gov). -.\" end of man page diff --git a/klibc/klibc/zlib/zlib.h b/klibc/klibc/zlib/zlib.h deleted file mode 100644 index 92edf96ff3..0000000000 --- a/klibc/klibc/zlib/zlib.h +++ /dev/null @@ -1,1200 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.1, November 17th, 2003 - - Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.1" -#define ZLIB_VERNUM 0x1210 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by the in-memory functions is the zlib - format, which is a zlib wrapper documented in RFC 1950, wrapped around a - deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - This library does not provide any functions to write gzip files in memory. - However such functions could be easily written using zlib's deflate function, - the documentation in the gzip RFC, and the examples in gzio.c. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: ascii or binary */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - the compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update data_type if it can make a good guess about - the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it get to the next deflate block boundary. When decoding the zlib - or gzip format, this will cause inflate() to return immediately after the - header and before the first block. When doing a raw inflate, inflate() will - go ahead and process the first block, and will return when it gets to the end - of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm-adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative - memLevel). msg is set to null if there is no error message. inflateInit2 - does not perform any decompression apart from reading the zlib header if - present: this will be done by inflate(). (So next_in and avail_in may be - modified, but next_out and avail_out are unchanged.) -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate - if this call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by this call of - inflate. The compressor and decompressor must use exactly the same - dictionary (see deflateSetDictionary). - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - -typedef voidp gzFile; - -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); - -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running crc with the bytes buf[0..len-1] and return the updated - crc. If buf is NULL, this function returns the required initial value - for the crc. Pre- and post-conditioning (one's complement) is performed - within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN const char * ZEXPORT zError OF((int err)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/klibc/klibc/zlib/zutil.c b/klibc/klibc/zlib/zutil.c deleted file mode 100644 index 253a1cc7e1..0000000000 --- a/klibc/klibc/zlib/zutil.c +++ /dev/null @@ -1,319 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id: zutil.c,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef STDC -extern void exit OF((int)); -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch (sizeof(uInt)) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch (sizeof(uLong)) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch (sizeof(voidpf)) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch (sizeof(z_off_t)) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1 << 16; -#endif -#ifdef NO_GZIP - flags += 1 << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1 << 20; -#endif -#ifdef FASTEST - flags += 1 << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1 << 25; -# ifdef HAS_vsprintf_void - flags += 1 << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1 << 26; -# endif -# endif -#else - flags += 1 << 24; -# ifdef NO_snprintf - flags += 1 << 25; -# ifdef HAS_sprintf_void - flags += 1 << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1 << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int z_verbose = verbose; - -void z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* does not exist on WCE */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ diff --git a/klibc/klibc/zlib/zutil.h b/klibc/klibc/zlib/zutil.h deleted file mode 100644 index 129452806b..0000000000 --- a/klibc/klibc/zlib/zutil.h +++ /dev/null @@ -1,258 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id: zutil.h,v 1.1 2005/02/27 23:15:39 hpa Exp $ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#define ZLIB_INTERNAL -#include "zlib.h" - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# define vsnprintf _vsnprintf -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif - -#ifdef HAVE_STRERROR - extern char *strerror OF((int)); -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include - extern int z_verbose; - extern void z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ diff --git a/klibc/makeklcc.pl b/klibc/makeklcc.pl deleted file mode 100755 index 74045955fd..0000000000 --- a/klibc/makeklcc.pl +++ /dev/null @@ -1,55 +0,0 @@ -#!/usr/bin/perl -# -# Combine klibc.config, klcc.in to produce a klcc script -# -# Usage: makeklcc klcc.in klibc.config perlpath -# - -use File::Spec; - -($klccin, $klibcconf, $perlpath) = @ARGV; - -sub pathsearch($) { - my($file) = @_; - my(@path); - my($p,$pp); - - if ( $file =~ /\// ) { - return File::Spec->rel2abs($file); - } - - foreach $p ( split(/\:/, $ENV{'PATH'}) ) { - $pp = File::Spec->rel2abs(File::Spec->catpath(undef, $p, $file)); - return $pp if ( -x $pp ); - } - - return undef; -} - -print "#!${perlpath}\n"; - -open(KLIBCCONF, '<', $klibcconf) or die "$0: cannot open $klibcconf: $!\n"; -while ( defined($l = ) ) { - chomp $l; - if ( $l =~ /^([^=]+)\=(.*)$/ ) { - $n = $1; $s = $2; - - if ( $n eq 'CC' || $n eq 'LD' || $n eq 'STRIP' ) { - $s1 = pathsearch($s); - die "$0: Cannot find $n: $s\n" unless ( defined($s1) ); - $s = $s1; - } - - print "\$$n = \"\Q$s\E\";\n"; - print "\@$n = qw($s);\n"; - print "\$conf{\'\L$n\E\'} = \\\$$n;\n"; - } -} -close(KLIBCCONF); - -open(KLCCIN, '<', $klccin) or die "$0: cannot open $klccin: $!\n"; -while ( defined($l = ) ) { - print $l; -} -close(KLCCIN); - diff --git a/klibc/version b/klibc/version deleted file mode 100644 index 45a1b3f445..0000000000 --- a/klibc/version +++ /dev/null @@ -1 +0,0 @@ -1.1.2 diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index daf0b75269..d1c28749fb 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -12,9 +12,6 @@ EXTRAS="\ extras/run_directory \ extras/firmware" -[ -z "$KERNEL_DIR" ] && KERNEL_DIR=/lib/modules/`uname -r`/build -echo KERNEL_DIR: "$KERNEL_DIR" - # with debug make clean EXTRAS="$EXTRAS" >/dev/null make all -j4 $MAKEOPTS DEBUG=true EXTRAS="$EXTRAS" || exit @@ -25,10 +22,14 @@ make clean EXTRAS="$EXTRAS" >/dev/null make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" -# klibc and debug -make clean EXTRAS="$EXTRAS" >/dev/null -make all -j4 $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KERNEL_DIR="$KERNEL_DIR" || exit -echo -e "\n\n" +# klibc build +[ -z "$KLCC" ] && KLCC=/usr/bin/klcc +if [ -e "$KLCC" ]; then + echo KLCC: "$KLCC" + make clean EXTRAS="$EXTRAS" >/dev/null + make all -j4 $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KLCC="$KLCC" || exit + echo -e "\n\n" +fi # install in temporary dir and show it TEMPDIR="`pwd`/.tmp" From fd15e02dbbaa60cf2aff37e1e2a86b244564fe4a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 9 Nov 2005 15:46:25 +0100 Subject: [PATCH 1600/4284] remove outdated HOWTO Signed-off-by: Kay Sievers --- HOWTO-udev_for_dev | 79 ---------------------------------------------- 1 file changed, 79 deletions(-) delete mode 100644 HOWTO-udev_for_dev diff --git a/HOWTO-udev_for_dev b/HOWTO-udev_for_dev deleted file mode 100644 index 9833dd1411..0000000000 --- a/HOWTO-udev_for_dev +++ /dev/null @@ -1,79 +0,0 @@ -HOWTO use udev to manage /dev - - This document describes one way to get udev working on a Fedora-development - machine to manage /dev. This procedure may be used to get udev to manage - /dev on other distros, if you modify some of the steps. - - This will only work if you use a 2.6 based kernel, preferably the most - recent one. This does not prevent your machine from using a 2.4 - kernel, if you boot into one, udev will not run and your old /dev will - be present with no changes needed. - - -NOTE NOTE NOTE NOTE NOTE NOTE NOTE - This is completely unsupported. Attempting to do this may cause your - machine to be unable to boot properly. USE AT YOUR OWN RISK. Always - have a rescue disk or CD handy to allow you to fix up any errors that - may occur. -NOTE NOTE NOTE NOTE NOTE NOTE NOTE - - - - Build and install udev as specified in the README that comes with - udev. I recommend using the following build options to get the - smallest possible binaries: - make USE_KLIBC=true USE_LOG=false DEBUG=false - - - disable udev from the boot process by running: - chkconfig udev off - or - chkconfig --del udev - as root. - - - place the start_udev script somewhere that is accessible by your - initscripts. I placed it into /etc/rc.d with the following command: - copy extras/start_udev /etc/rc.d/ - - - modify the rc.sysinit script to call the start_udev script as one of - the first things that it does, but after /proc and /sys are mounted. - I did this with the latest Fedora startup scripts with the patch at - the end of this file. - - - make sure the /etc/udev/udev.conf file lists the udev_root as "/dev/" - and the udev_db as "/dev/.udevdb". It should contain the - following lines in order to work properly. - udev_root="/dev/" - udev_db="/dev/.udevdb" - - - reboot into a 2.6 kernel and watch udev create all of the initial - device nodes in /dev - - -If anyone has any problems with this, please let me, and the -linux-hotplug-devel@lists.sourceforge.net mailing list know. - -A big thanks go out to the Gentoo developers for showing me that this is -possible to do. - -Greg Kroah-Hartman - - - ----------------------------------- -Patch to modify rc.sysinit to call udev at the beginning of the boot -process: - - ---- /etc/rc.sysinit.orig 2004-02-17 11:45:17.000000000 -0800 -+++ /etc/rc.sysinit 2004-02-17 13:28:33.000000000 -0800 -@@ -32,6 +32,9 @@ - - . /etc/init.d/functions - -+# start udev to populate /dev -+/etc/rc.d/start_udev -+ - if [ "$HOSTTYPE" != "s390" -a "$HOSTTYPE" != "s390x" ]; then - last=0 - for i in `LC_ALL=C grep '^[0-9].*respawn:/sbin/mingetty' /etc/inittab | sed 's/^.* tty\([0-9][0-9]*\).*/\1/g'`; do - - From e5bdb75a109c446ff0ca2e27268cdd274ee61a9c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 9 Nov 2005 15:47:47 +0100 Subject: [PATCH 1601/4284] update TODO Signed-off-by: Kay Sievers --- TODO | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/TODO b/TODO index 0bf22dd580..41ea98ff02 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,4 @@ -This is a short list of things that needs to be done. They are in no specific +This is a list of things that needs to be done. They are in no specific order. We will gladly accept patches for any of these items: - Completely replace the built-in wait_for_sysfs stuff in udev_sysfs.c @@ -8,5 +8,3 @@ order. We will gladly accept patches for any of these items: to syslog, so any error logged from the kernel can be associated with any of the links at that time. -- remove klibc tree and make it an external dependency - From 54eb6a122fc6d2d765b9f71f9b47d529c1acf30f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Nov 2005 09:53:32 -0800 Subject: [PATCH 1602/4284] Make run_directory.c stat the place it is going to try to run. This should remove a lot of error messages that people are seeing. Signed-off-by: Greg Kroah-Hartman --- extras/run_directory/run_directory.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/extras/run_directory/run_directory.c b/extras/run_directory/run_directory.c index 5107f85aef..69faecc15e 100644 --- a/extras/run_directory/run_directory.c +++ b/extras/run_directory/run_directory.c @@ -53,9 +53,16 @@ static int exec_program(const char *filename, const char *subsystem) int run_directory(const char *dir, const char *suffix, const char *subsystem) { struct name_entry *name_loop, *name_tmp; + struct stat buf; LIST_HEAD(name_list); dbg("looking at '%s'", dir); + + if (stat(dir, &buf) != 0) { + dbg("directory '%s' not found", dir); + return 0; + } + add_matching_files(&name_list, dir, suffix); list_for_each_entry_safe(name_loop, name_tmp, &name_list, node) { From efbd13e83863d834db1eb8b6f6301dede32f54fe Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 10 Nov 2005 01:07:51 +0100 Subject: [PATCH 1603/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/45-isdn.rules | 50 ++++++++++ etc/udev/suse/{udev.rules => 50-udev.rules} | 99 ++++--------------- etc/udev/suse/60-persistent.rules | 46 +++++++++ .../suse/{pcmcia.rules => 80-pcmcia.rules} | 4 +- etc/udev/suse/80-sysconfig.rules | 20 ++++ etc/udev/suse/90-hal.rules | 3 + etc/udev/suse/95-debug.rules | 6 ++ etc/udev/suse/isdn.rules | 54 ---------- 8 files changed, 149 insertions(+), 133 deletions(-) create mode 100644 etc/udev/suse/45-isdn.rules rename etc/udev/suse/{udev.rules => 50-udev.rules} (65%) create mode 100644 etc/udev/suse/60-persistent.rules rename etc/udev/suse/{pcmcia.rules => 80-pcmcia.rules} (73%) create mode 100644 etc/udev/suse/80-sysconfig.rules create mode 100644 etc/udev/suse/90-hal.rules create mode 100644 etc/udev/suse/95-debug.rules delete mode 100644 etc/udev/suse/isdn.rules diff --git a/etc/udev/suse/45-isdn.rules b/etc/udev/suse/45-isdn.rules new file mode 100644 index 0000000000..ef2912d160 --- /dev/null +++ b/etc/udev/suse/45-isdn.rules @@ -0,0 +1,50 @@ +# CAPI devices +SUBSYSTEM="capi", GROUP="dialout" +KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" +KERNEL=="capi*", NAME="capi/%n" + +# ISDN devices +KERNEL=="isdn*", NAME="%k", MODE="600" +KERNEL=="isdnctrl*", NAME="%k", MODE="600" +KERNEL=="ippp*", NAME="%k", MODE="600" +KERNEL=="isdninfo*", NAME="%k", MODE="444" + +# ISDN USB +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/c00*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/1000*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/1900*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2000*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2200*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2300*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2800*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3000*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3500*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3600*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2805*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2806*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/4401*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/4601*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="483/4810*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="959/2bd0*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" +SUBSYSTEM=="usb", ENV{PRODUCT}=="9bf/*", RUN+="/lib/udev/isdn.sh", ENV{SYSCONFIG}="no" + +# ISDN PCMCIA +# AVM B1 models +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb845DC335pc*pd*", RUN+="/lib/udev/isdn.sh b1 1", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb81E10430pc*pd*", RUN+="/lib/udev/isdn.sh b1 2", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb18E8558Apc*pd*", RUN+="/lib/udev/isdn.sh b1 3", ENV{SYSCONFIG}="no" +# AVM A1 models (aka Fritz!Card PCMCIA) +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pbADC9D4BBpc*pd*", RUN+="/lib/udev/isdn.sh a1 1", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa8D9761C8pb01C5AA7Bpc*pd*", RUN+="/lib/udev/isdn.sh a1 2", ENV{SYSCONFIG}="no" +# teles +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa67B50EAEpbE9E70119pc*pd*", RUN+="/lib/udev/isdn.sh teles 1", ENV{SYSCONFIG}="no" +# sedlbauer +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbF3612E1Dpc6B95C78Apd*", RUN+="/lib/udev/isdn.sh sedlbauer 1", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc397B7E90pd*", RUN+="/lib/udev/isdn.sh sedlbauer 2", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc2E5C7FCEpd*", RUN+="/lib/udev/isdn.sh sedlbauer 3", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc8DB143FEpd*", RUN+="/lib/udev/isdn.sh sedlbauer 4", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pcB391AB4Cpd*", RUN+="/lib/udev/isdn.sh sedlbauer 5", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*paD79E0B84pb21D083AEpc*pd*", RUN+="/lib/udev/isdn.sh sedlbauer 6", ENV{SYSCONFIG}="no" +# elsa +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa983DE2C4pb333BA257pc*pd*", RUN+="/lib/udev/isdn.sh elsa 1", ENV{SYSCONFIG}="no" +SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa639E5718pb333BA257pc*pd*", RUN+="/lib/udev/isdn.sh elsa 2", ENV{SYSCONFIG}="no" diff --git a/etc/udev/suse/udev.rules b/etc/udev/suse/50-udev.rules similarity index 65% rename from etc/udev/suse/udev.rules rename to etc/udev/suse/50-udev.rules index a674f9b510..f24d77d197 100644 --- a/etc/udev/suse/udev.rules +++ b/etc/udev/suse/50-udev.rules @@ -16,6 +16,7 @@ KERNEL=="modems/mwave*", NAME="%k", GROUP="uucp" KERNEL=="hvc*", NAME="%k", GROUP="uucp" KERNEL=="hvsi*", NAME="%k", GROUP="uucp" KERNEL=="iseries/vtty*", NAME="%k", GROUP="uucp" +KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", SYMLINK+="pilot" # video/graphics SUBSYSTEM=="video4linux", GROUP="video" @@ -32,7 +33,7 @@ KERNEL=="vbi0", SYMLINK+="vbi" KERNEL=="pmu", GROUP="video" # dvb -SUBSYSTEM="dvb", PROGRAM="/bin/sh -c 'X=%k X=$${X#dvb} A=$${X%%%%.*} D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" +SUBSYSTEM="dvb", PROGRAM="/bin/sh -c 'X=%k; X=$${X#dvb}; A=$${X%%%%.*}; D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" # ALSA/sound SUBSYSTEM="sound", GROUP="audio" @@ -63,8 +64,8 @@ KERNEL=="js*", NAME="input/%k", MODE="0644" KERNEL=="ts*", NAME="input/%k", MODE="0600" KERNEL=="uinput", NAME="input/%k", MODE="0600" KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" -SUBSYSTEM=="input_device", RUN+="/sbin/udev.input_device.sh" -SUBSYSTEM=="input_device", ACTION=="add", ENV{ABS}=="[1-9]*", RUN+="/sbin/modprobe joydev" +SUBSYSTEM=="input[0-9]*", RUN+="/lib/udev/input_device.sh" +KERNEL=="input[0-9]*", ACTION=="add", ENV{ABS}=="[1-9]*", RUN+="/sbin/modprobe joydev" # printer SUBSYSTEM=="usb", KERNEL=="lp*", ACTION=="add", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" @@ -114,11 +115,15 @@ KERNEL=="3270/tubcons*", NAME="%k", MODE="600" KERNEL=="ica", NAME="%k", MODE="666" KERNEL=="z90crypt", NAME="%k", MODE="666" KERNEL=="mmtimer", NAME="%k", MODE="444" +KERNEL=="auer[0-9]*" NAME="usb/%k" + +KERNEL=="pktcdvd", NAME="pktcdvd/control" +KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%k" # fix floppy devices -KERNEL=="nvram", ACTION=="add", RUN+="/sbin/load_floppy_module" +KERNEL=="nvram", ACTION=="add", RUN+="/sbin/load_floppy_module.sh" KERNEL=="fd*", ACTION=="add", SYSFS{device/cmos}=="*", RUN+="/sbin/create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" -KERNEL=="fd*", ACTION=="remove", RUN+="/sbin/remove_floppy_devices %k" +KERNEL=="fd*", ACTION=="remove", RUN+="/sbin/remove_floppy_devices.sh %k" # block devices SUBSYSTEM=="block", GROUP="disk", MODE="0640" @@ -137,14 +142,20 @@ SUBSYSTEM=="block", GROUP="disk", MODE="0640" # 5 TYPE_ROM SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0|7|14", RUN+="/sbin/modprobe sd_mod" # Treat osst as a unique case, that is, osst will load more often than -# actually required, but the osst and st drivers will do the right thing. SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", SYSFS{device/vendor}=="Onstream", 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" # IDE/ATAPI handling -SUBSYSTEM=="ide", ACTION=="add", RUN+="/sbin/udev.load_ide_modules.sh" +SUBSYSTEM=="ide", ACTION=="add", RUN+="/lib/udev/load_ide_modules.sh" + +# device mapper targets +KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" +KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/dmsetup info -c --noheadings -o name -j %M -m %m", SYMLINK="disk/by-name/%c" + +# check fstab and possibly mount +SUBSYSTEM=="block", KERNEL=="sd*[0-9]|hd*[0-9]", ACTION=="add", RUN+="/lib/udev/mount.sh" # misc storage devices (non-block) KERNEL=="sg*", NAME="%k", GROUP="disk", MODE="640" @@ -170,78 +181,10 @@ KERNEL=="iseries/vt*", NAME="%k", GROUP="disk" KERNEL=="iseries/nvt*", NAME="%k", GROUP="disk" KERNEL=="iseries/ibmsis*", NAME="%k", GROUP="disk" -# device mapper targets -KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" -KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/udev.devmap_name.sh %M %m", NAME="mapper/%c" - -# persistent disk device links /dev/disk/ -ACTION!="add", GOTO="persistent_end" -SUBSYSTEM!="block", GOTO="persistent_end" - -# skip rules for for ram/loop/fd -KERNEL=="ram*|loop*|fd*", GOTO="persistent_end" - -# never access removable ide devices, the drivers are causing event loops on open() -SUBSYSTEM=="block", BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}="1", GOTO="persistent_end" - -# by-id (hardware serial number) -KERNEL=="hd*[!0-9]", IMPORT{program}="/sbin/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}="/sbin/usb_id -x" -KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -s %p" -KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -a -s %p" -KERNEL=="dasd*[!0-9]", IMPORT{program}="/sbin/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}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" -KERNEL=="sr*", 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}="/sbin/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}" -LABEL="persistent_end" - -SUBSYSTEM=="block", KERNEL=="sd*[0-9]|hd*[0-9]", ACTION=="add", RUN+="/sbin/udev.mount.sh" - -# network devices -KERNEL=="tun", NAME="net/%k", MODE="0600" -SUBSYSTEM=="net", ACTION=="add", RUN+="/sbin/ifup $env{INTERFACE} -o hotplug" -SUBSYSTEM=="net", ACTION=="remove", RUN+="/sbin/ifdown %k -o hotplug" - -# libusb device access (mount usbfs or usbdev nodes) +# libusb device access (mount usbfs or create usbdev nodes) DEVPATH=="/module/usbcore", ACTION=="add", RUN+="/bin/mount -t usbfs usbfs /proc/bus/usb" -SUBSYSTEM="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev} B=$${X%%%%.*} D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c" +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+="/sbin/udev.firmware.sh" - -# SUSE system integration -SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" -SUBSYSTEM=="macio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" -SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-/sys%p -o hotplug" -LABEL="after_usb_default" -SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-/sys%p -o hotplug" -SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-/sys%p -o hotplug" -SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-/sys%p -o hotplug" -SUBSYSTEM=="scsi", DEVPATH=="/devices/css*", ACTION=="remove", RUN+="/sbin/hwdown scsi-devpath-/sys%p -o hotplug" -SUBSYSTEM=="scsi_host", ACTION=="add", SYSFS{device/cutype}=="*", RUN+="/sbin/hwup scsi__host-devpath-/sys%p -o hotplug" - -# default -RUN+="/usr/sbin/hal.hotplug" -RUN+="socket:/org/kernel/udev/monitor" - -# debug events to /events, but not on default udev_log="err" -ENV{UDEV_LOG}=="[4-9]", RUN+="/sbin/hotplugeventrecorder" +SUBSYSTEM=="firmware", ACTION=="add", RUN+="/lib/udev/firmware.sh" diff --git a/etc/udev/suse/60-persistent.rules b/etc/udev/suse/60-persistent.rules new file mode 100644 index 0000000000..589fb0f88a --- /dev/null +++ b/etc/udev/suse/60-persistent.rules @@ -0,0 +1,46 @@ +# persistent disk links: /dev/disk/{by-id,by-uuid,by-label,by-path} +# scheme based on "Linux persistent device names", 2004, Hannes Reinecke + +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}="/sbin/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}="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -s %p -d $tempnode" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -a -s %p -d $tempnode" +KERNEL=="dasd*[!0-9]", IMPORT{program}="/sbin/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}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="sr*", 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}="/sbin/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}="/sbin/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" + +LABEL="persistent_end" diff --git a/etc/udev/suse/pcmcia.rules b/etc/udev/suse/80-pcmcia.rules similarity index 73% rename from etc/udev/suse/pcmcia.rules rename to etc/udev/suse/80-pcmcia.rules index 11ccde56e7..cae7a7606c 100644 --- a/etc/udev/suse/pcmcia.rules +++ b/etc/udev/suse/80-pcmcia.rules @@ -1,5 +1,7 @@ +ENV{SYSCONFIG}=="no|off|0", GOTO="pcmcia_end" + SUBSYSTEM=="pcmcia_socket", ACTION=="add", RUN+="/sbin/hwup pcmcia_socket-devpath-%p -o hotplug" SUBSYSTEM=="pcmcia", ACTION=="add", RUN+="/sbin/hwup pcmcia-devpath-%p -o hotplug" -LABEL="after_pcmcia" +LABEL="pcmcia_end" diff --git a/etc/udev/suse/80-sysconfig.rules b/etc/udev/suse/80-sysconfig.rules new file mode 100644 index 0000000000..630c0eedfb --- /dev/null +++ b/etc/udev/suse/80-sysconfig.rules @@ -0,0 +1,20 @@ +ENV{SYSCONFIG}=="no|off|0", GOTO="sysconfig_end" + +# network devices +KERNEL=="tun", NAME="net/%k", MODE="0600" +SUBSYSTEM=="net", ACTION=="add", RUN+="/sbin/ifup $env{INTERFACE} -o hotplug" +SUBSYSTEM=="net", ACTION=="remove", RUN+="/sbin/ifdown %k -o hotplug" + +# SUSE system integration +SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" +SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-/sys%p -o hotplug" +SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-/sys%p -o hotplug" +SUBSYSTEM=="scsi", DEVPATH=="/devices/css*", ACTION=="remove", RUN+="/sbin/hwdown scsi-devpath-/sys%p -o hotplug" +SUBSYSTEM=="scsi_host", ACTION=="add", SYSFS{device/cutype}=="*", RUN+="/sbin/hwup scsi__host-devpath-/sys%p -o hotplug" +SUBSYSTEM=="vio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" +SUBSYSTEM=="macio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" +SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-/sys%p -o hotplug" +SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-/sys%p -o hotplug" +SUBSYSTEM=="pnp", RUN+="/bin/sh -c 'while read id; do /sbin/modprobe pnp:d$$id; done < /sys$devpath/id'" + +LABEL="sysconfig_end" diff --git a/etc/udev/suse/90-hal.rules b/etc/udev/suse/90-hal.rules new file mode 100644 index 0000000000..35b81ea046 --- /dev/null +++ b/etc/udev/suse/90-hal.rules @@ -0,0 +1,3 @@ +# send all events to HAL +RUN+="/usr/sbin/hal.hotplug" + diff --git a/etc/udev/suse/95-debug.rules b/etc/udev/suse/95-debug.rules new file mode 100644 index 0000000000..fad54b9632 --- /dev/null +++ b/etc/udev/suse/95-debug.rules @@ -0,0 +1,6 @@ +# debug events to /events, but not on default udev_log="err" +ENV{UDEV_LOG}=="[4-9]", RUN+="/sbin/udeventrecorder" + +# event to be catched by udevmonitor +RUN+="socket:/org/kernel/udev/monitor" + diff --git a/etc/udev/suse/isdn.rules b/etc/udev/suse/isdn.rules deleted file mode 100644 index 29f993adab..0000000000 --- a/etc/udev/suse/isdn.rules +++ /dev/null @@ -1,54 +0,0 @@ -# -# Very important !!! -# These rules must be processed befor 50-pcmcia and 50-udev -# if not here 'll be a endless loop !!! -# -# CAPI devices -SUBSYSTEM="capi", GROUP="dialout" -KERNEL=="capi", NAME="capi20", SYMLINK+="isdn/capi20" -KERNEL=="capi*", NAME="capi/%n" - -# ISDN -KERNEL=="isdn*", NAME="%k", MODE="600" -KERNEL=="isdnctrl*", NAME="%k", MODE="600" -KERNEL=="ippp*", NAME="%k", MODE="600" -KERNEL=="isdninfo*", NAME="%k", MODE="444" -# USB -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/c00*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/1000*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/1900*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2000*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2200*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2300*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2800*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3000*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3500*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/3600*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2805*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/2806*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/4401*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="57c/4601*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="483/4810*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="959/2bd0*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" -SUBSYSTEM=="usb", ENV{PRODUCT}=="9bf/*", RUN+="/sbin/udev.isdn.sh", GOTO="after_usb_default" - -# ISDN PCMCIA -# AVM B1 models -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb845DC335pc*pd*", RUN+="/sbin/udev.isdn.sh b1 1", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb81E10430pc*pd*", RUN+="/sbin/udev.isdn.sh b1 2", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pb18E8558Apc*pd*", RUN+="/sbin/udev.isdn.sh b1 3", GOTO="after_pcmcia" -# AVM A1 models (aka Fritz!Card PCMCIA) -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa95D42008pbADC9D4BBpc*pd*", RUN+="/sbin/udev.isdn.sh a1 1", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa8D9761C8pb01C5AA7Bpc*pd*", RUN+="/sbin/udev.isdn.sh a1 2", GOTO="after_pcmcia" -# teles -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa67B50EAEpbE9E70119pc*pd*", RUN+="/sbin/udev.isdn.sh teles 1", GOTO="after_pcmcia" -# sedlbauer -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbF3612E1Dpc6B95C78Apd*", RUN+="/sbin/udev.isdn.sh sedlbauer 1", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc397B7E90pd*", RUN+="/sbin/udev.isdn.sh sedlbauer 2", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc2E5C7FCEpd*", RUN+="/sbin/udev.isdn.sh sedlbauer 3", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pc8DB143FEpd*", RUN+="/sbin/udev.isdn.sh sedlbauer 4", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa81FB79F5pbE4E9BC12pcB391AB4Cpd*", RUN+="/sbin/udev.isdn.sh sedlbauer 5", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*paD79E0B84pb21D083AEpc*pd*", RUN+="/sbin/udev.isdn.sh sedlbauer 6", GOTO="after_pcmcia" -# elsa -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa983DE2C4pb333BA257pc*pd*", RUN+="/sbin/udev.isdn.sh elsa 1", GOTO="after_pcmcia" -SUBSYSTEM=="pcmcia", ENV{MODALIAS}=="pcmcia:m*c*f*fn*pfn*pa639E5718pb333BA257pc*pd*", RUN+="/sbin/udev.isdn.sh elsa 2", GOTO="after_pcmcia" From f5f8f316aa66251d0ccf71b940182a9d00dbd040 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 10 Nov 2005 01:11:03 +0100 Subject: [PATCH 1604/4284] remove completely useless start script Signed-off-by: Kay Sievers --- etc/init.d/udev.init.LSB | 101 --------------------------------------- 1 file changed, 101 deletions(-) delete mode 100644 etc/init.d/udev.init.LSB diff --git a/etc/init.d/udev.init.LSB b/etc/init.d/udev.init.LSB deleted file mode 100644 index 0fb0f0c205..0000000000 --- a/etc/init.d/udev.init.LSB +++ /dev/null @@ -1,101 +0,0 @@ -#! /bin/sh -# -# Author: Rolf Eike Beer -# derived from original RedHat udev init script -# based on the SuSE 9.0 template (c) 1995-2002 SuSE Linux AG -# -# /etc/init.d/udev -# and its symbolic link -# /(usr/)sbin/rcudev -# -# System startup script for udev -# -# LSB compatible service control script; see http://www.linuxbase.org/spec/ -# -### BEGIN INIT INFO -# Provides: udev -# Required-Start: -# Required-Stop: -# Default-Start: 1 2 3 5 -# Default-Stop: 0 6 -# Short-Description: manage user-space device nodes in /udev -# Description: Start udev to create the device files for all -# devices already present in system when script is -# called. All other devices files will be automatically -# created when udev is called via /sbin/hotplug. -# Requires at least a kernel 2.6 to work properly. -### END INIT INFO -# -# Note on script names: -# http://www.linuxbase.org/spec/refspecs/LSB_1.2.0/gLSB/scrptnames.html -# A registry has been set up to manage the init script namespace. -# http://www.lanana.org/ -# Please use the names already registered or register one or use a -# vendor prefix. - - -# Check for missing binaries (stale symlinks should not happen) -UDEV_BIN=/sbin/udev -test -x $UDEV_BIN || exit 5 - -# Check for existence of needed config file and read it -UDEV_CONFIG=/etc/udev/udev.conf -test -r $UDEV_CONFIG || exit 6 -. $UDEV_CONFIG - -# Directory where sysfs is mounted -SYSFS_DIR=/sys - -# Source LSB init functions -. /lib/lsb/init-functions - -case "$1" in - start) - if [ ! -d $SYSFS_DIR ]; then - log_failure_msg "${0}: SYSFS_DIR \"$SYSFS_DIR\" not found" - exit 1 - fi - if [ ! -d $udev_root ]; then - mkdir $udev_root || exit 4 - fi - # propogate /udev from /sys - we only need this while we do not - # have initramfs and an early user-space with which to do early - # device bring up - echo -n "Creating initial udev device nodes: " - export ACTION=add - udevstart - log_success_msg - ;; - stop) - # nothing to do here - echo -n "Stopping udev: " - log_success_msg - ;; - restart) - $0 stop - $0 start - - exit $? - ;; - force-reload) - echo -n "Reload udev " - $0 stop && $0 start - exit $? - ;; - reload) - exit 3 - ;; - status) - echo -n "Checking for udev root directory: " - if [ -d $udev_root ]; then - log_success_msg found - else - log_warning_msg "not found" - exit 3 - fi - ;; - *) - echo "Usage: $0 {start|stop|status|restart|force-reload|reload}" - exit 1 - ;; -esac From 53899a171ea862124b49c75b7511b7eb30742ef9 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 10 Nov 2005 01:50:06 +0100 Subject: [PATCH 1605/4284] fix tests and remove no longer useful stuff Signed-off-by: Kay Sievers --- test/devd_test | 37 ------------------------------------ test/net_test | 35 ---------------------------------- test/replace_test | 33 -------------------------------- test/show_all_devices.sh | 27 -------------------------- test/test.all | 41 ---------------------------------------- test/test.block | 29 ---------------------------- test/test.tty | 20 -------------------- test/testd.block | 36 ----------------------------------- test/udev-test.pl | 5 +++-- udev_remove.c | 4 ++-- 10 files changed, 5 insertions(+), 262 deletions(-) delete mode 100755 test/devd_test delete mode 100755 test/net_test delete mode 100755 test/replace_test delete mode 100755 test/show_all_devices.sh delete mode 100755 test/test.all delete mode 100755 test/test.block delete mode 100755 test/test.tty delete mode 100755 test/testd.block diff --git a/test/devd_test b/test/devd_test deleted file mode 100755 index 534e787f24..0000000000 --- a/test/devd_test +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -RULES=label_test.rules -CONFIG=label_test.conf - -export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_FILE=$PWD/$CONFIG - -cat > $RULES << EOF -BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="boot_diskX%n" -BUS="scsi", SYSFS{vendor}="IBM-ESXS", SYSFS{model}="ST336605LW !#", NAME="a/nice/place/to/put/a/boot_disk%n" -EOF - -cat > $CONFIG << EOF -udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udevdb" -udev_rules="$PWD/$RULES" -EOF - -mkdir udev - -export ACTION=add -export DEVPATH=block/sda - -../udev block -ls -l udev - -export ACTION=remove -export DEVPATH=block/sda - -../udev block -ls -l udev - - -rm $RULES -rm $CONFIG -rm -rf udev diff --git a/test/net_test b/test/net_test deleted file mode 100755 index 9daf8da082..0000000000 --- a/test/net_test +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/bash - -RULES=label_test.rules -CONFIG=label_test.conf - -export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_FILE=$PWD/$CONFIG - -cat > $RULES << EOF -SYSFS{address}="00:e0:00:8d:9f:25", NAME="wireless" -EOF - -cat > $CONFIG << EOF -udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udevdb" -udev_rules="$PWD/$RULES" -EOF - -mkdir udev - -export ACTION=add -export DEVPATH=class/net/eth1 - -../udevtest class/net/eth1 net -ls -l udev - -export ACTION=remove -export DEVPATH=class/net/eth1 - -../udevtest class/net/eth1 net -ls -l udev - -rm $RULES -rm $CONFIG -rm -rf udev diff --git a/test/replace_test b/test/replace_test deleted file mode 100755 index 6e01f28ed5..0000000000 --- a/test/replace_test +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash - -RULES=replace_test.rules -CONFIG=replace_test.conf - -export SYSFS_PATH=$PWD/sys/ -export UDEV_CONFIG_FILE=$PWD/$CONFIG - -cat > $RULES << EOF -KERNEL="ttyUSB0", NAME="visor" -EOF - -cat > $CONFIG << EOF -udev_root="$PWD/udev/" -udev_db="$PWD/udev/.udevdb" -udev_rules="$PWD/$RULES" -EOF - -mkdir udev - -export DEVPATH=class/tty/ttyUSB0 -export ACTION=add - -../udev tty -ls -l udev - -export ACTION=remove -../udev tty -ls -l udev - -rm $RULES -rm $CONFIG -rm -rf udev diff --git a/test/show_all_devices.sh b/test/show_all_devices.sh deleted file mode 100755 index 921b8e6163..0000000000 --- a/test/show_all_devices.sh +++ /dev/null @@ -1,27 +0,0 @@ -#! /bin/bash -# -# Directory where sysfs is mounted -SYSFS_DIR=/sys - -# handle block devices and their partitions -for i in ${SYSFS_DIR}/block/*; do - # each drive - echo ${i#${SYSFS_DIR}/block/} - - # each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - echo ${j#${SYSFS_DIR}} | cut --delimiter='/' --fields=4- - fi - done -done - -# all other device classes -for i in ${SYSFS_DIR}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - echo ${j#${SYSFS_DIR}} | cut --delimiter='/' --fields=4- - fi - done -done - diff --git a/test/test.all b/test/test.all deleted file mode 100755 index 527569bd43..0000000000 --- a/test/test.all +++ /dev/null @@ -1,41 +0,0 @@ -#! /bin/sh -# -# test.block - run udev(8) on each block device in /sys/block - -if [ $# = "0" ] ; then - echo - echo "usage: $0 " - echo "where is \"add\" or \"remove\"" - echo - exit 1 -fi - -SYSFSDIR=/sys # change this for a nonstand sysfs mount point -BIN=../udev # location of your udev binary -export ACTION=$1 # 'add' or 'remove' - -# do the block devices first -for i in ${SYSFSDIR}/block/*; do - # add each drive - export DEVPATH=${i#${SYSFSDIR}} - $BIN block - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFSDIR}} - $BIN block - fi - done -done - -# now all the devices in the class directories -for i in ${SYSFSDIR}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFSDIR}} - CLASS=`echo ${i#${SYSFSDIR}} | cut --delimiter='/' --fields=3-` - $BIN $CLASS - fi - done -done diff --git a/test/test.block b/test/test.block deleted file mode 100755 index 294c47c0be..0000000000 --- a/test/test.block +++ /dev/null @@ -1,29 +0,0 @@ -#! /bin/sh -# -# test.block - run udev(8) on each block device in /sys/block - -if [ $# = "0" ] ; then - echo - echo "usage: $0 " - echo "where is \"add\" or \"remove\"" - echo - exit 1 -fi - -SYSFSDIR=/sys # change this for a nonstand sysfs mount point -BIN=../udev # location of your udev binary -export ACTION=$1 # 'add' or 'remove' - -for i in ${SYSFSDIR}/block/*; do - # add each drive - export DEVPATH=${i#${SYSFSDIR}} - $BIN block - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFSDIR}} - $BIN block - fi - done -done diff --git a/test/test.tty b/test/test.tty deleted file mode 100755 index b89ad5a6d8..0000000000 --- a/test/test.tty +++ /dev/null @@ -1,20 +0,0 @@ -#! /bin/sh -# -# test.tty - run udev(8) on each tty device in /sys/class/tty - -if [ $# = "0" ] ; then - echo - echo "usage: $0 " - echo "where is \"add\" or \"remove\"" - echo - exit 1 -fi - -SYSFSDIR=/sys # change this for a nonstand sysfs mount point -BIN=../udev # location of your udev binary -export ACTION=$1 # 'add' or 'remove' - -for i in ${SYSFSDIR}/class/tty/*; do - export DEVPATH=${i#${SYSFSDIR}} - $BIN tty -done diff --git a/test/testd.block b/test/testd.block deleted file mode 100755 index ca9ac8c1ac..0000000000 --- a/test/testd.block +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# -# test.block - run udev(8) on each block device in /sys/block - -if [ $# = "0" ] ; then - echo - echo "usage: $0 " - echo "where is \"add\" or \"remove\"" - echo - exit 1 -fi - -killall udevd - -SYSFSDIR=/sys # change this for a nonstand sysfs mount point -BIN=./udevsend # location of your udev binary -export ACTION=$1 # 'add' or 'remove' -seq=1 - -for i in ${SYSFSDIR}/block/*; do - # add each drive - export DEVPATH=${i#${SYSFSDIR}} - export SEQNUM=$seq - $BIN block - x=$((seq++)) - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${SYSFSDIR}} - export SEQNUM=$seq - $BIN block - x=$((seq++)) - fi - done -done diff --git a/test/udev-test.pl b/test/udev-test.pl index 44bc483cf1..2549c7ee69 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -262,9 +262,9 @@ EOF desc => "import of shell-value file", subsys => "block", devpath => "/block/sda", - exp_name => "subdir/sys/node" , + exp_name => "subdir/info/node" , rules => <$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"; +print CONF "udev_log=\"info\"\n"; close CONF; my $test_num = 1; diff --git a/udev_remove.c b/udev_remove.c index cb5523af92..4d1b9286a0 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -152,8 +152,8 @@ int udev_remove_device(struct udevice *udev) dbg("remove name='%s'", udev->name); udev_db_delete_device(udev); } else { - dbg("'%s' not found in database, don't remove anything", udev->devpath); - return -1; + dbg("'%s' not found in database, using kernel name '%s'", udev->devpath, udev->kernel_name); + strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); } return delete_node(udev); From a8d141a3c165dafcf21d081e88f3cc0b7f1e65c5 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 10 Nov 2005 02:06:43 +0100 Subject: [PATCH 1606/4284] replace udeveventrecorder by a shell script Signed-off-by: Kay Sievers --- .gitignore | 1 - Makefile | 2 - etc/udev/suse/95-debug.rules | 2 +- extras/eventrecorder.sh | 4 ++ udeveventrecorder.c | 127 ----------------------------------- 5 files changed, 5 insertions(+), 131 deletions(-) create mode 100755 extras/eventrecorder.sh delete mode 100644 udeveventrecorder.c diff --git a/.gitignore b/.gitignore index a83700c930..c37b70c524 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,5 @@ udevinfo udevmonitor udevstart udevtest -udeveventrecorder udev_version.h diff --git a/Makefile b/Makefile index c105dab2e2..ab75bb3d9a 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,6 @@ PROGRAMS = \ udev \ udevd \ udevsend \ - udeveventrecorder \ udevcontrol \ udevmonitor \ udevinfo \ @@ -359,7 +358,6 @@ uninstall-bin: - rm -f $(DESTDIR)$(sbindir)/udev - rm -f $(DESTDIR)$(sbindir)/udevd - rm -f $(DESTDIR)$(sbindir)/udevsend - - rm -f $(DESTDIR)$(sbindir)/udeveventrecoreder - rm -f $(DESTDIR)$(sbindir)/udevcontrol - rm -f $(DESTDIR)$(sbindir)/udevstart - rm -f $(DESTDIR)$(usrsbindir)/udevmonitor diff --git a/etc/udev/suse/95-debug.rules b/etc/udev/suse/95-debug.rules index fad54b9632..280287c1a7 100644 --- a/etc/udev/suse/95-debug.rules +++ b/etc/udev/suse/95-debug.rules @@ -1,5 +1,5 @@ # debug events to /events, but not on default udev_log="err" -ENV{UDEV_LOG}=="[4-9]", RUN+="/sbin/udeventrecorder" +ENV{UDEV_LOG}=="[4-9]", RUN+="/lib/udev/eventrecorder.sh" # event to be catched by udevmonitor RUN+="socket:/org/kernel/udev/monitor" diff --git a/extras/eventrecorder.sh b/extras/eventrecorder.sh new file mode 100755 index 0000000000..90cfe68ebb --- /dev/null +++ b/extras/eventrecorder.sh @@ -0,0 +1,4 @@ +#/bin/sh + +[ -d /events ] || exit 0 +set > /events/debug.$SEQNUM.$1.$ACTION.$$ diff --git a/udeveventrecorder.c b/udeveventrecorder.c deleted file mode 100644 index 422cf88ff0..0000000000 --- a/udeveventrecorder.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * udeveventrecorder.c - * - * Copyright (C) 2004-2005 SuSE Linux Products GmbH - * Author: - * Olaf Hering - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "udev.h" -#include "udev_version.h" -#include "udev_utils.h" -#include "logging.h" - -#define BUFSIZE 12345 -#define FNSIZE 123 - -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) -{ - int fd, i; - unsigned long seq; - char **ep = envp; - char *buf, *p, *a; - struct stat sb; - const char *env; - - if (stat("/events", &sb) || !(S_ISDIR(sb.st_mode))) - return 0; - - env = getenv("UDEV_LOG"); - if (env) - udev_log = log_priority(env); - - logging_init("udeveventrecorder"); - dbg("version %s", UDEV_VERSION); - - p = getenv("SEQNUM"); - a = getenv("ACTION"); - buf = malloc(FNSIZE); - if (!(buf && a && argv[1])) - goto error; - if (p) - seq = strtoul(p, NULL, 0); - else - seq = 0; - - snprintf(buf, FNSIZE, "/events/debug.%05lu.%s.%s.%u", seq, argv[1], a ? a : "", getpid()); - if ((fd = open(buf, O_CREAT | O_WRONLY | O_TRUNC, 0644)) < 0) { - err("error creating '%s': %s", buf, strerror(errno)); - goto error; - } - free(buf); - p = malloc(BUFSIZE); - buf = p; - buf += snprintf(buf, p + BUFSIZE - buf, "set --"); - for (i = 1; i < argc; ++i) { - buf += snprintf(buf, p + BUFSIZE - buf, " %s", argv[i]); - if (buf > p + BUFSIZE) - goto full; - } - buf += snprintf(buf, p + BUFSIZE - buf, "\n"); - if (buf > p + BUFSIZE) - goto full; - while (*ep) { - unsigned char *t; - t = memchr(*ep, '=', strlen(*ep)); - if (t) { - *t = '\0'; - t++; - buf += snprintf(buf, p + BUFSIZE - buf, "%s='%s'\n", *ep, t); - --t; - *t = '='; - } - ep++; - if (buf > p + BUFSIZE) - break; - } - -full: - buf = p; - write(fd, buf, strlen(buf)); - close(fd); - free(buf); - return 0; - -error: - fprintf(stderr, "record enviroment to /events, to be called from udev context\n"); - return 1; -} From ef0cd1ac934f10037766d1000e9a6065653688ac Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 10 Nov 2005 02:20:25 +0100 Subject: [PATCH 1607/4284] 075 release --- ChangeLog | 15 +++++++++++++++ Makefile | 2 +- RELEASE-NOTES | 5 ++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ef3c4b838..bde6b4f05e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,21 @@ 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 ============================================ diff --git a/Makefile b/Makefile index ab75bb3d9a..c68db3b93a 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 074 +VERSION = 075 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index d89aeaa69f..8062703889 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,7 +1,10 @@ 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 -can be used to buil a klibc udev. +should be used to build a klibc udev now. udev 074 ======== From 08f403cc3759c406a67c5477c3a14a0d82f4c8a1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 10 Nov 2005 04:35:35 +0100 Subject: [PATCH 1608/4284] fix typo in eventrecorder Signed-off-by: Kay Sievers --- extras/eventrecorder.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/eventrecorder.sh b/extras/eventrecorder.sh index 90cfe68ebb..95ec95a24e 100755 --- a/extras/eventrecorder.sh +++ b/extras/eventrecorder.sh @@ -1,4 +1,4 @@ -#/bin/sh +#!/bin/sh [ -d /events ] || exit 0 set > /events/debug.$SEQNUM.$1.$ACTION.$$ From 009364eef93ab3e757ece02a17b2cd217fd71dac Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 12 Nov 2005 04:11:08 +0100 Subject: [PATCH 1609/4284] volume_id: include stddef.h header Signed-off-by: Kay Sievers --- extras/volume_id/libvolume_id/volume_id.h | 1 + 1 file changed, 1 insertion(+) diff --git a/extras/volume_id/libvolume_id/volume_id.h b/extras/volume_id/libvolume_id/volume_id.h index f2f3a0d006..517d382540 100644 --- a/extras/volume_id/libvolume_id/volume_id.h +++ b/extras/volume_id/libvolume_id/volume_id.h @@ -12,6 +12,7 @@ #define _VOLUME_ID_H_ #include +#include #define VOLUME_ID_VERSION 53 From e24b218ad7ab05f92c6ca93ddc7e62f918094a46 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 12 Nov 2005 04:11:48 +0100 Subject: [PATCH 1610/4284] remove misleading install instructions Signed-off-by: Kay Sievers --- docs/rh_udev_for_dev.txt | 62 ---------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 docs/rh_udev_for_dev.txt diff --git a/docs/rh_udev_for_dev.txt b/docs/rh_udev_for_dev.txt deleted file mode 100644 index 0b66868d79..0000000000 --- a/docs/rh_udev_for_dev.txt +++ /dev/null @@ -1,62 +0,0 @@ -Troubleshooting udev for dev on Red Hat distro - -1) Make sure you have a rescue disk/cd in case you hose your machine. You've - been forewarned. -2) Grab latest udev tarball or clone udev bitkeeper tree - (bk://linuxusb.bkbits.net.udev) -3) Follow README and HOWTO-udev_for_dev documents - -The following is some additional help to get udev for dev up and running on RH. - -Q. I login as my normal self from the login screen and RH just hangs on an - empty blue screen. What's wrong? - -A. You have some wrong permissions. I'm guessing you can probably log in as root - but not as your normal user. Basically you need to set the right - permissions with a rule. Setting the correct permissions to null and urandom - allowed me to login as myself and not at root. - - While you are there you might want to set the permissions to ptmx as well - or you may have trouble getting a bash prompt in an xterm. Also refer to the - next question. - -Q. I'm having trouble getting a bash prompt from my xterm. i.e. I bring up a - terminal and all I have is a blank screen with a blinking cursor. - -A. First make sure you have the correct permissions set for ptmx. See above - Q&A for help on this. But I'm guessing that something is wrong with your - /dev/pts, thanks Captain Obvious, heh:) You probably have devpts mounted - to /dev/pts from /etc/fstab. I'm also guessing that you have sysfs mounted - to /sys from /etc/fstab as well. If this is the case then the line in - /etc/rc.sysinit - - action $"Mounting local filesystems:" mount -a -t nonfs,smbfs,ncpfs -O no_netdev - - will have mounted these for you. As a result you placed your call to - start_udev directly after this because the HOWTO-udev_for_dev document - told you to insert start_udev after /proc and /sys have been mounted. - Well start_udev actually overwrites /dev thus anything you had mounted in - /dev prior to start_udev being called will be blown away. So basically, - you mounted devpts to /dev/pts because everything in /etc/fstab was mounted - and then it was blown away by calling start_udev. A simple fix is to remove - the mount devpts line from /etc/fstab and mount it after calling start_udev. - I did the following: - - action $"Mounting local filesystems:" mount -a -t nonfs,smbfs,ncpfs -O no_netdev - /etc/rc.d/start_udev - action $"Mounting devpts: " mount -t devpts none /dev/pts - - After doing so I rebooted and was able to get my prompt from my xterm. - -Q. I'm getting some error messages during boot. How do I get rid of them? - -A. For me it was a matter of setting up Symlinks. Basically, some /dev entries - were being looked for and not being found so an error was thrown. For example, - /dev/cdrom was needed but udev had named it /dev/hdc by default. Basically I - edited my /etc/udev/udev.rules file to create a symlink from /dev/cdrom to - /dev/hdc and my error went away. - -These are some of the things I ran into. NOTE: I hosed my machine more than once -trying to figure this out and a rescue disk was my best friend. If you have any -other experiences and would like to add to this Q&A list feel free to send me a -patch (ogasawara@osdl.org). Hopefully this helped someone. Thanks. From c86be870ce6bb6361ca2ca6c3c05b6d89cf70a2c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 12 Nov 2005 04:17:48 +0100 Subject: [PATCH 1611/4284] remove all built-in wait_for_sysfs logic Most of the issues are fixed with the kernel we depend on, for the remaing ones see the RELEASE-NOTES for a special rule to add. Signed-off-by: Kay Sievers --- Makefile | 2 - RELEASE-NOTES | 9 ++ udev.c | 1 - udev.h | 1 + udev_add.c | 1 - udev_device.c | 1 - udev_event.c | 39 +++++-- udev_rules.c | 5 +- udev_sysfs.c | 298 -------------------------------------------------- udev_sysfs.h | 40 ------- udevstart.c | 1 - udevtest.c | 1 - 12 files changed, 44 insertions(+), 355 deletions(-) delete mode 100644 udev_sysfs.c delete mode 100644 udev_sysfs.h diff --git a/Makefile b/Makefile index c68db3b93a..de305cb9bf 100644 --- a/Makefile +++ b/Makefile @@ -61,7 +61,6 @@ HEADERS = \ udev_utils.h \ udev_rules.h \ udev_db.h \ - udev_sysfs.h \ logging.h \ udev_libc_wrapper.h \ udev_selinux.h \ @@ -73,7 +72,6 @@ UDEV_OBJS = \ udev_config.o \ udev_add.o \ udev_remove.o \ - udev_sysfs.o \ udev_db.o \ udev_rules.o \ udev_rules_parse.o \ diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 8062703889..18e2829bbb 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,12 @@ +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" + udev 075 ======== Silent a too verbose error logging for the old hotplug.d/ dev.d/ diff --git a/udev.c b/udev.c index 17867180c7..f2d6f6653c 100644 --- a/udev.c +++ b/udev.c @@ -34,7 +34,6 @@ #include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" -#include "udev_sysfs.h" #include "udev_version.h" #include "udev_rules.h" #include "logging.h" diff --git a/udev.h b/udev.h index ecc0a44f91..e61b692df7 100644 --- a/udev.h +++ b/udev.h @@ -84,6 +84,7 @@ struct udevice { extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action); extern void udev_cleanup_device(struct udevice *udev); +extern dev_t get_devt(struct sysfs_class_device *class_dev); extern int udev_process_event(struct udev_rules *rules, struct udevice *udev); extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev); extern int udev_remove_device(struct udevice *udev); diff --git a/udev_add.c b/udev_add.c index f4ad55a893..1a224a1792 100644 --- a/udev_add.c +++ b/udev_add.c @@ -37,7 +37,6 @@ #include "udev_libc_wrapper.h" #include "udev.h" #include "udev_utils.h" -#include "udev_sysfs.h" #include "udev_version.h" #include "logging.h" #include "udev_rules.h" diff --git a/udev_device.c b/udev_device.c index ad6f706366..7821c91cb4 100644 --- a/udev_device.c +++ b/udev_device.c @@ -37,7 +37,6 @@ #include "udev.h" #include "logging.h" #include "udev_utils.h" -#include "udev_sysfs.h" #include "list.h" diff --git a/udev_event.c b/udev_event.c index b50fbf4c1d..353aff09b7 100644 --- a/udev_event.c +++ b/udev_event.c @@ -28,38 +28,62 @@ #include #include #include +#include +#include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" #include "udev.h" #include "logging.h" #include "udev_rules.h" #include "udev_utils.h" -#include "udev_sysfs.h" #include "list.h" +dev_t get_devt(struct sysfs_class_device *class_dev) +{ + struct sysfs_attribute *attr = NULL; + unsigned int major, minor; + char *maj, *min; + + maj = getenv("MAJOR"); + min = getenv("MINOR"); + + if (maj && min) { + major = atoi(maj); + minor = atoi(min); + } else { + attr = sysfs_get_classdev_attr(class_dev, "dev"); + if (attr == NULL) + return 0; + dbg("dev='%s'", attr->value); + + if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) + return 0; + } + + dbg("found major=%d, minor=%d", major, minor); + return makedev(major, minor); +} + int udev_process_event(struct udev_rules *rules, struct udevice *udev) { int retval; char path[PATH_SIZE]; - const char *error; if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS || udev->type == DEV_NET) { /* handle device node */ if (strcmp(udev->action, "add") == 0) { struct sysfs_class_device *class_dev; - /* wait for sysfs of /sys/class /sys/block */ dbg("node add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); path[sizeof(path)-1] = '\0'; - class_dev = wait_class_device_open(path); + class_dev = sysfs_open_class_device_path(path); if (class_dev == NULL) { dbg("open class device failed"); return 0; } dbg("opened class_dev->name='%s'", class_dev->name); - wait_for_class_device(class_dev, &error); /* get major/minor */ if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) @@ -113,17 +137,16 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) } else if (udev->type == DEV_DEVICE && strcmp(udev->action, "add") == 0) { struct sysfs_device *devices_dev; - /* wait for sysfs of /sys/devices/ */ dbg("devices add"); snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); path[sizeof(path)-1] = '\0'; - devices_dev = wait_devices_device_open(path); + devices_dev = sysfs_open_device_path(path); if (!devices_dev) { dbg("devices device unavailable (probably remove has beaten us)"); return 0; } + dbg("devices device opened '%s'", path); - wait_for_devices_device(devices_dev, &error); udev_rules_get_run(rules, udev, NULL, devices_dev); sysfs_close_device(devices_dev); if (udev->ignore_device) { diff --git a/udev_rules.c b/udev_rules.c index 137ad27dba..a3100f8e14 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -376,7 +376,7 @@ attr_found: return 0; } -#define WAIT_LOOP_PER_SECOND 20 +#define WAIT_LOOP_PER_SECOND 50 static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) { char filename[PATH_SIZE]; @@ -392,9 +392,10 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) info("file appeared after %i loops", (timeout * WAIT_LOOP_PER_SECOND) - loop-1); return 0; } + info("wait for %i mseconds", 1000 / WAIT_LOOP_PER_SECOND); usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } - info("waiting for '%s' failed", filename); + err("waiting for '%s' failed", filename); return -1; } diff --git a/udev_sysfs.c b/udev_sysfs.c deleted file mode 100644 index 71aa827d38..0000000000 --- a/udev_sysfs.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * udev_sysfs.c - sysfs linux kernel specific knowledge - * - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2004 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. - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_version.h" -#include "udev_sysfs.h" -#include "udev_utils.h" -#include "logging.h" - -/* list of subsystem specific files, NULL if there is no file to wait for */ -dev_t get_devt(struct sysfs_class_device *class_dev) -{ - struct sysfs_attribute *attr = NULL; - unsigned int major, minor; - - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr == NULL) - return 0; - dbg("dev='%s'", attr->value); - - if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) - return 0; - dbg("found major=%d, minor=%d", major, minor); - - return makedev(major, minor); -} - -/* wait for a devices device specific file to show up */ -int wait_for_devices_device(struct sysfs_device *devices_dev, - const char **error) -{ - static const struct device_file { - const char *bus; - const char *file; - } device_files[] = { - { .bus = "scsi", .file = "vendor" }, - { .bus = "usb", .file = "idVendor" }, - { .bus = "usb", .file = "iInterface" }, - { .bus = "usb", .file = "bNumEndpoints" }, - { .bus = "usb-serial", .file = "bus" }, - { .bus = "ide", .file = "bus" }, - { .bus = "pci", .file = "vendor" }, - { .bus = "pci_express", .file = "bus" }, - { .bus = "platform", .file = "bus" }, - { .bus = "pcmcia", .file = "bus" }, - { .bus = "i2c", .file = "bus" }, - { .bus = "ieee1394", .file = "node_count" }, - { .bus = "ieee1394", .file = "nodeid" }, - { .bus = "ieee1394", .file = "address" }, - { .bus = "bttv-sub", .file = NULL }, - { .bus = "pnp", .file = "bus" }, - { .bus = "eisa", .file = "bus" }, - { .bus = "serio", .file = "bus" }, - { .bus = "pseudo", .file = "bus" }, - { .bus = "mmc", .file = "bus" }, - { .bus = "macio", .file = "bus" }, - { .bus = "of_platform", .file = "bus" }, - { .bus = "vio", .file = "bus" }, - { .bus = "ecard", .file = "bus" }, - { .bus = "sa1111-rab", .file = "bus" }, - { .bus = "amba", .file = "bus" }, - { .bus = "locomo-bus", .file = "bus" }, - { .bus = "logicmodule", .file = "bus" }, - { .bus = "parisc", .file = "bus" }, - { .bus = "ocp", .file = "bus" }, - { .bus = "dio", .file = "bus" }, - { .bus = "MCA", .file = "bus" }, - { .bus = "wl", .file = "bus" }, - { .bus = "ccwgroup", .file = "bus" }, - { .bus = "css", .file = "bus" }, - { .bus = "ccw", .file = "bus" }, - { .bus = "iucv", .file = "bus" }, - { NULL, NULL } - }; - const struct device_file *devicefile = NULL; - int loop; - - if (getenv("PHYSDEVBUS") == NULL) { - dbg("the kernel says, that there is no bus for '%s'", devices_dev->path); - return 0; - } - - /* wait for the bus device link to the devices device */ - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - if (sysfs_get_device_bus(devices_dev) == 0) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - if (loop == 0) { - dbg("error: getting bus device link"); - if (error) - *error = "no bus device link"; - return -1; - } - dbg("bus device link found for bus '%s'", devices_dev->bus); - - /* wait for a bus device specific file to show up */ - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - int found_bus_type = 0; - - for (devicefile = device_files; devicefile->bus != NULL; devicefile++) { - if (strcmp(devices_dev->bus, devicefile->bus) == 0) { - char filename[PATH_SIZE]; - struct stat stats; - - if (devicefile->file == NULL) { - dbg("bus '%s' has no file to wait for", devices_dev->bus); - return 0; - } - - found_bus_type = 1; - snprintf(filename, sizeof(filename), "%s/%s", devices_dev->path, devicefile->file); - filename[sizeof(filename)-1] = '\0'; - dbg("looking at bus '%s' device for specific file '%s'", devices_dev->bus, filename); - - if (stat(filename, &stats) == 0) { - dbg("bus '%s' device specific file '%s' found", devices_dev->bus, devicefile->file); - return 0; - } - } - } - if (found_bus_type == 0) { - if (error) - *error = "unknown bus"; - info("error: unknown bus, please report to " - " '%s'", devices_dev->bus); - return -1; - } - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - dbg("error: getting '%s' device specific file '%s'", devices_dev->bus, devicefile->file); - if (error) - *error = "bus device specific file unavailable"; - return -1; -} - - -struct sysfs_class_device *wait_class_device_open(const char *path) -{ - struct sysfs_class_device *class_dev = NULL; - int loop; - - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - class_dev = sysfs_open_class_device_path(path); - if (class_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - return class_dev; -} - -int wait_for_class_device(struct sysfs_class_device *class_dev, - const char **error) -{ - const struct subsystem_file { - const char *subsystem; - const char *file; - } subsystem_files[] = { - { .subsystem = "net", .file = "ifindex" }, - { .subsystem = "scsi_host", .file = "unique_id" }, - { .subsystem = "pcmcia_socket", .file = "card_type" }, - { .subsystem = "bluetooth", .file = "address" }, - { .subsystem = "firmware", .file = "data" }, - { .subsystem = "fc_transport", .file = "port_id" }, - { .subsystem = "fc_host", .file = "port_id" }, - { .subsystem = "spi_transport", .file = "width" }, - { .subsystem = "spi_host", .file = "width" }, - { NULL, NULL } - }; - - const struct subsystem_file *subsys_file; - struct sysfs_class_device *class_dev_parent; - struct sysfs_device *devices_dev = NULL; - char filename[PATH_SIZE]; - int loop; - - /* look if we want to wait for a file */ - for (subsys_file = subsystem_files; subsys_file->subsystem != NULL; subsys_file++) - if (strcmp(class_dev->classname, subsys_file->subsystem) == 0) - break; - - if (subsys_file->file == NULL) { - dbg("class '%s' has no file to wait for", class_dev->classname); - return 0; - } - - snprintf(filename, sizeof(filename), "%s/%s", class_dev->path, subsys_file->file); - filename[sizeof(filename)-1] = '\0'; - dbg("looking at class '%s' for specific file '%s'", class_dev->classname, filename); - - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - struct stat stats; - - if (stat(class_dev->path, &stats) == -1) { - dbg("'%s' now disappeared (probably remove has beaten us)", class_dev->path); - return -ENODEV; - } - - if (stat(filename, &stats) == 0) { - dbg("class '%s' specific file '%s' found", class_dev->classname, subsys_file->file); - return 0; - } - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - dbg("error: getting class '%s' specific file '%s'", class_dev->classname, subsys_file->file); - if (error) - *error = "class specific file unavailable"; - return -1; - - /* skip devices without devices-link */ - if (getenv("PHYSDEVPATH") == NULL) { - dbg("the kernel says, that there is no physical device for '%s'", class_dev->path); - return 1; - } - - /* the symlink may be on the parent device */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent) - dbg("looking at parent device for device link '%s'", class_dev_parent->path); - - /* wait for the symlink to the devices device */ - dbg("waiting for symlink to devices device"); - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - if (class_dev_parent) - devices_dev = sysfs_get_classdev_device(class_dev_parent); - else - devices_dev = sysfs_get_classdev_device(class_dev); - - if (devices_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - if (!devices_dev) { - dbg(" error: no devices device symlink found"); - if (error) - *error = "no device symlink"; - return -ENODEV; - } - dbg("device symlink found pointing to '%s'", devices_dev->path); - - return wait_for_devices_device(devices_dev, error); -} - -struct sysfs_device *wait_devices_device_open(const char *path) -{ - struct sysfs_device *devices_dev = NULL; - int loop; - - loop = WAIT_MAX_SECONDS * WAIT_LOOP_PER_SECOND; - while (--loop) { - devices_dev = sysfs_open_device_path(path); - if (devices_dev) - break; - - usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); - } - - return devices_dev; -} diff --git a/udev_sysfs.h b/udev_sysfs.h deleted file mode 100644 index 5b87d6bf95..0000000000 --- a/udev_sysfs.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * udev_sysfs.h - * - * Copyright (C) 2004 Kay Sievers - * Copyright (C) 2004 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. - * - * 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 _UDEV_SYSFS_H_ -#define _UDEV_SYSFS_H_ - -#include "libsysfs/sysfs/libsysfs.h" - -#define WAIT_MAX_SECONDS 3 -#define WAIT_LOOP_PER_SECOND 20 - -extern dev_t get_devt(struct sysfs_class_device *class_dev); - -/* /sys/class, /sys/block devices */ -extern struct sysfs_class_device *wait_class_device_open(const char *path); -extern int wait_for_class_device(struct sysfs_class_device *class_dev, const char **error); - -/* /sys/devices devices */ -extern struct sysfs_device *wait_devices_device_open(const char *path); -extern int wait_for_devices_device(struct sysfs_device *devices_dev, const char **error); - -#endif /* _UDEV_SYSFS_H_ */ diff --git a/udevstart.c b/udevstart.c index 8ee079dbe5..11063f6799 100644 --- a/udevstart.c +++ b/udevstart.c @@ -40,7 +40,6 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev_libc_wrapper.h" -#include "udev_sysfs.h" #include "udev.h" #include "udev_version.h" #include "logging.h" diff --git a/udevtest.c b/udevtest.c index 4890b6837c..1be3fa9515 100644 --- a/udevtest.c +++ b/udevtest.c @@ -28,7 +28,6 @@ #include "libsysfs/sysfs/libsysfs.h" #include "udev.h" -#include "udev_sysfs.h" #include "udev_utils.h" #include "udev_version.h" #include "udev_rules.h" From 62821d0de11e5af5b0cf066781228489408ef29b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 12 Nov 2005 05:09:34 +0100 Subject: [PATCH 1612/4284] add linux/types.h back, old glibc-kernel-headers want it Signed-off-by: Kay Sievers --- udevd.c | 1 + udevmonitor.c | 1 + 2 files changed, 2 insertions(+) diff --git a/udevd.c b/udevd.c index 333ad4143a..58371ba592 100644 --- a/udevd.c +++ b/udevd.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "list.h" diff --git a/udevmonitor.c b/udevmonitor.c index 805790233f..7d3f0aa538 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "udev.h" From 88be7e8887e9284666b7844bb0faa84fbb699fb2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 12 Nov 2005 14:28:22 +0100 Subject: [PATCH 1613/4284] volume_id: use glibc's byteswap Signed-off-by: Kay Sievers --- extras/volume_id/libvolume_id/util.h | 35 ++++++----------------- extras/volume_id/libvolume_id/volume_id.h | 2 +- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/extras/volume_id/libvolume_id/util.h b/extras/volume_id/libvolume_id/util.h index 6e16491c80..f6c57fb66d 100644 --- a/extras/volume_id/libvolume_id/util.h +++ b/extras/volume_id/libvolume_id/util.h @@ -20,48 +20,31 @@ #endif #include +#include /* 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 -/* probe volume for all known filesystems in specific order */ -#define bswap16(x) (uint16_t) ((((uint16_t)(x) & 0x00ffu) << 8) | \ - (((uint16_t)(x) & 0xff00u) >> 8)) - -#define bswap32(x) (uint32_t) ((((uint32_t)(x) & 0xff000000u) >> 24) | \ - (((uint32_t)(x) & 0x00ff0000u) >> 8) | \ - (((uint32_t)(x) & 0x0000ff00u) << 8) | \ - (((uint32_t)(x) & 0x000000ffu) << 24)) - -#define bswap64(x) (uint64_t) ((((uint64_t)(x) & 0xff00000000000000ull) >> 56) | \ - (((uint64_t)(x) & 0x00ff000000000000ull) >> 40) | \ - (((uint64_t)(x) & 0x0000ff0000000000ull) >> 24) | \ - (((uint64_t)(x) & 0x000000ff00000000ull) >> 8) | \ - (((uint64_t)(x) & 0x00000000ff000000ull) << 8) | \ - (((uint64_t)(x) & 0x0000000000ff0000ull) << 24) | \ - (((uint64_t)(x) & 0x000000000000ff00ull) << 40) | \ - (((uint64_t)(x) & 0x00000000000000ffull) << 56)) - #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) bswap16(x) -#define be32_to_cpu(x) bswap32(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) bswap32(x) +#define cpu_to_be32(x) bswap_32(x) #elif (__BYTE_ORDER == __BIG_ENDIAN) -#define le16_to_cpu(x) bswap16(x) -#define le32_to_cpu(x) bswap32(x) -#define le64_to_cpu(x) bswap64(x) +#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) bswap16(x) -#define cpu_to_le32(x) bswap32(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 */ diff --git a/extras/volume_id/libvolume_id/volume_id.h b/extras/volume_id/libvolume_id/volume_id.h index 517d382540..3e3acbde9f 100644 --- a/extras/volume_id/libvolume_id/volume_id.h +++ b/extras/volume_id/libvolume_id/volume_id.h @@ -14,7 +14,7 @@ #include #include -#define VOLUME_ID_VERSION 53 +#define VOLUME_ID_VERSION 54 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From e825b59b0763ae82d12ef832df33e434aa066875 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 16 Nov 2005 00:13:28 +0100 Subject: [PATCH 1614/4284] udevd: ignore all messages without DEVPATH Signed-off-by: Kay Sievers --- udevd.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/udevd.c b/udevd.c index 58371ba592..3fd3bfe6ad 100644 --- a/udevd.c +++ b/udevd.c @@ -313,16 +313,11 @@ static int running_with_devpath(struct uevent_msg *msg, int limit) struct uevent_msg *loop_msg; int childs_count = 0; - if (msg->devpath == NULL) - return 0; - list_for_each_entry(loop_msg, &running_list, node) { if (limit && childs_count++ > limit) { dbg("%llu, maximum number (%i) of child reached", msg->seqnum, childs_count); return 1; } - if (loop_msg->devpath == NULL) - continue; /* return running parent/child device event */ if (compare_devpath(loop_msg->devpath, msg->devpath) != 0) { @@ -431,6 +426,12 @@ static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) msg->envp[i++] = "UDEVD_EVENT=1"; msg->envp[i] = NULL; + if (!msg->devpath) { + info("DEVPATH missing, ingnore message"); + free(msg); + return NULL; + } + return msg; } From f4fc0136523afdc3ace865312f816c53694a6b87 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 16 Nov 2005 02:06:46 +0100 Subject: [PATCH 1615/4284] udevd: track exit status of event process Signed-off-by: Kay Sievers --- udevd.c | 28 ++++++++++++++++++++-------- udevd.h | 1 + 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/udevd.c b/udevd.c index 3fd3bfe6ad..b7b306131e 100644 --- a/udevd.c +++ b/udevd.c @@ -122,13 +122,15 @@ static int udev_event_process(struct uevent_msg *msg) if (strncmp(name_loop->name, "socket:", strlen("socket:")) == 0) pass_env_to_socket(&name_loop->name[strlen("socket:")], msg->devpath, msg->action); else - run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + if (run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, + (udev_log_priority >= LOG_INFO))) + retval = -1; } } udev_cleanup_device(&udev); - return 0; + return retval; } static void msg_queue_delete(struct uevent_msg *msg) @@ -140,6 +142,7 @@ static void msg_queue_delete(struct uevent_msg *msg) static void udev_event_run(struct uevent_msg *msg) { pid_t pid; + int retval; pid = fork(); switch (pid) { @@ -155,10 +158,12 @@ static void udev_event_run(struct uevent_msg *msg) logging_init("udevd-event"); setpriority(PRIO_PROCESS, 0, UDEV_PRIORITY); - udev_event_process(msg); + retval = udev_event_process(msg); info("seq %llu finished", msg->seqnum); logging_close(); + if (retval) + exit(1); exit(0); case -1: err("fork of child failed: %s", strerror(errno)); @@ -427,7 +432,7 @@ static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) msg->envp[i] = NULL; if (!msg->devpath) { - info("DEVPATH missing, ingnore message"); + info("DEVPATH missing, ignore message"); free(msg); return NULL; } @@ -597,14 +602,16 @@ static void asmlinkage sig_handler(int signum) write(signal_pipe[WRITE_END], "", 1); } -static void udev_done(int pid) +static void udev_done(int pid, int exitstatus) { /* find msg associated with pid and delete it */ struct uevent_msg *msg; list_for_each_entry(msg, &running_list, node) { if (msg->pid == pid) { - info("seq %llu, pid [%d] exit, %ld seconds old", msg->seqnum, msg->pid, time(NULL) - msg->queue_time); + 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 */ @@ -617,12 +624,17 @@ static void udev_done(int pid) static void reap_sigchilds(void) { pid_t pid; + int status; while (1) { - pid = waitpid(-1, NULL, WNOHANG); + pid = waitpid(-1, &status, WNOHANG); if (pid <= 0) break; - udev_done(pid); + if (WIFEXITED(status)) + status = WEXITSTATUS(status); + else + status = 0; + udev_done(pid, status); } } diff --git a/udevd.h b/udevd.h index 91c8e6503d..4040942ac9 100644 --- a/udevd.h +++ b/udevd.h @@ -61,6 +61,7 @@ struct uevent_msg { enum udevd_msg_type type; struct list_head node; pid_t pid; + int exitstatus; time_t queue_time; char *action; char *devpath; From 7a7702509259f811d4f8321e64e28dc72037c88b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 16 Nov 2005 04:12:53 +0100 Subject: [PATCH 1616/4284] udevd: export event queue and event state All pending and running events can be found as symlinks to the actual device in /dev/.udev/queue/ now. This way we can lookup if specific events are still in the queue, before doing actions which require events to have finished. All failed event processes can be found in /dev/.udev/failed/. This makes it possible to retry a failed event process at a later time in the boot process. Signed-off-by: Kay Sievers --- udevd.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/udevd.c b/udevd.c index b7b306131e..93f02c5395 100644 --- a/udevd.c +++ b/udevd.c @@ -133,9 +133,83 @@ static int udev_event_process(struct uevent_msg *msg) return retval; } +enum event_state { + EVENT_QUEUED, + EVENT_FINISHED, + EVENT_FAILED, +}; + +#define PATH_TO_NAME_CHAR '@' +#define EVENT_QUEUE_DIR ".udev/queue" +#define EVENT_FAILED_DIR ".udev/failed" +static void export_event_state(struct uevent_msg *msg, enum event_state state) +{ + char filename[PATH_SIZE]; + char filename_failed[PATH_SIZE]; + char target[PATH_SIZE]; + size_t start, end, i; + struct uevent_msg *loop_msg; + + /* add location of queue files */ + strlcpy(filename, udev_root, sizeof(filename)); + strlcat(filename, "/", sizeof(filename)); + start = strlcat(filename, EVENT_QUEUE_DIR, sizeof(filename)); + end = strlcat(filename, msg->devpath, sizeof(filename)); + if (end > sizeof(filename)) + end = sizeof(filename); + + /* replace '/' to transform path into a filename */ + for (i = start+1; i < end; i++) + if (filename[i] == '/') + filename[i] = PATH_TO_NAME_CHAR; + + /* 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)); + end = strlcat(filename_failed, msg->devpath, sizeof(filename_failed)); + if (end > sizeof(filename_failed)) + end = sizeof(filename_failed); + + /* replace '/' to transform path into a filename */ + for (i = start+1; i < end; i++) + if (filename_failed[i] == '/') + filename_failed[i] = PATH_TO_NAME_CHAR; + + switch (state) { + case EVENT_QUEUED: + unlink(filename_failed); + + strlcpy(target, sysfs_path, sizeof(target)); + strlcat(target, msg->devpath, sizeof(target)); + create_path(filename); + symlink(target, filename); + return; + case EVENT_FINISHED: + unlink(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; + unlink(filename); + case EVENT_FAILED: + create_path(filename_failed); + rename(filename, filename_failed); + return; + } +} + static void msg_queue_delete(struct 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); } @@ -181,6 +255,8 @@ static void msg_queue_insert(struct uevent_msg *msg) { msg->queue_time = time(NULL); + export_event_state(msg, EVENT_QUEUED); + /* run all events with a timeout set immediately */ if (msg->timeout != 0) { list_add_tail(&msg->node, &running_list); From fc55cf68ca0c0db5172a9de7e827c6c3f7c2a308 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 16 Nov 2005 04:14:15 +0100 Subject: [PATCH 1617/4284] remove "udev_db" option from config file All udev state is kept in /$udev_root/.udev/ now. No option to configure that anymore, it will always be there. Signed-off-by: Kay Sievers --- Makefile | 7 ++----- RELEASE-NOTES | 4 ++++ docs/udev.xml | 8 -------- etc/udev/udev.conf.in | 3 --- test/udev-test.pl | 4 ---- udev.8 | 4 ---- udev.h | 10 +++++++++- udev_add.c | 1 - udev_config.c | 9 --------- udev_db.c | 24 ++++++++++++++++-------- udev_db.h | 33 --------------------------------- udev_remove.c | 1 - udev_rules.c | 1 - udevd.c | 3 --- udevd.h | 3 +++ udevinfo.c | 1 - 16 files changed, 34 insertions(+), 82 deletions(-) delete mode 100644 udev_db.h diff --git a/Makefile b/Makefile index de305cb9bf..4968df4261 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,6 @@ HEADERS = \ udev.h \ udev_utils.h \ udev_rules.h \ - udev_db.h \ logging.h \ udev_libc_wrapper.h \ udev_selinux.h \ @@ -117,7 +116,6 @@ usrsbindir = ${exec_prefix}/usr/sbin mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev udevdir = /dev -udevdb = ${udevdir}/.udevdb LOCAL_CFG_DIR = etc/udev DESTDIR = @@ -250,7 +248,6 @@ udev_version.h: @echo "Creating udev_version.h" @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ - @echo \#define UDEV_DB \"$(udevdb)\" >> $@ @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ @@ -347,7 +344,7 @@ install-bin: done; ifndef DESTDIR - killall udevd - - rm -rf $(udevdb) + - rm -rf /dev/.udev - $(sbindir)/udevd --daemon endif .PHONY: install-bin @@ -363,7 +360,7 @@ uninstall-bin: - rm -f $(DESTDIR)$(DESTDIR)$(usrbindir)/udevtest ifndef DESTDIR - killall udevd - - rm -rf $(udevdb) + - rm -rf /dev/.udev endif @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 18e2829bbb..69166cfef1 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -7,6 +7,10 @@ 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 always +be in /$udev_root/.udev/ now, there is no longer an option to set this +to anything else. + udev 075 ======== Silent a too verbose error logging for the old hotplug.d/ dev.d/ diff --git a/docs/udev.xml b/docs/udev.xml index c98054f8ce..3db66f8001 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -71,14 +71,6 @@ - - - - The name and location of the udev database. The default value is - /dev/.udevdb. - - - diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index c44ed3092c..90c1f99ba6 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -3,9 +3,6 @@ # Where in the filesystem to place the device nodes udev_root="@udevdir@" -# The name and location of the udev database. -udev_db="@udevdir@/.udevdb" - # The name and location of the udev rules file(s). udev_rules="@configdir@/rules.d" diff --git a/test/udev-test.pl b/test/udev-test.pl index 2549c7ee69..c33c79b1c0 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -24,7 +24,6 @@ my $PWD = $ENV{PWD}; my $sysfs = "sys/"; my $udev_bin = "../udev"; 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"; @@ -1740,7 +1739,6 @@ sub run_test { print "\n"; if (defined($rules->{option}) && $rules->{option} eq "clean") { - system("rm -rf $udev_db"); system("rm -rf $udev_root"); mkdir($udev_root) || die "unable to create udev_root: $udev_root\n"; } @@ -1761,7 +1759,6 @@ 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"; print CONF "udev_log=\"info\"\n"; close CONF; @@ -1791,7 +1788,6 @@ if ($ARGV[0]) { print "$error errors occured\n\n"; # cleanup -system("rm -rf $udev_db"); system("rm -rf $udev_root"); unlink($udev_rules); unlink($udev_conf); diff --git a/udev.8 b/udev.8 index a591a1398e..2ea5812092 100644 --- a/udev.8 +++ b/udev.8 @@ -35,10 +35,6 @@ udev expects its main configuration file at Specifies where to place the device nodes in the filesystem. The default value is \fI/dev\fR. .TP -\fBudev_db\fR -The name and location of the udev database. The default value is -\fI/dev/.udevdb\fR. -.TP \fBudev_rules\fR 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 diff --git a/udev.h b/udev.h index e61b692df7..faa12a31ee 100644 --- a/udev.h +++ b/udev.h @@ -28,6 +28,7 @@ #include "list.h" #define COMMENT_CHARACTER '#' +#define PATH_TO_NAME_CHAR '@' #define LINE_SIZE 512 #define NAME_SIZE 128 #define PATH_SIZE 256 @@ -38,6 +39,8 @@ #define DEFAULT_PARTITIONS_COUNT 15 #define UDEV_ALARM_TIMEOUT 180 +#define DB_DIR ".udev/db" + struct udev_rules; enum device_type { @@ -92,9 +95,14 @@ extern void udev_init_config(void); extern int udev_start(void); extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); +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_lookup_name(const char *name, char *devpath, size_t len); +extern int udev_db_get_all_entries(struct list_head *name_list); + extern char sysfs_path[PATH_SIZE]; extern char udev_root[PATH_SIZE]; -extern char udev_db_path[PATH_SIZE]; extern char udev_config_filename[PATH_SIZE]; extern char udev_rules_filename[PATH_SIZE]; extern int udev_log_priority; diff --git a/udev_add.c b/udev_add.c index 1a224a1792..128917e519 100644 --- a/udev_add.c +++ b/udev_add.c @@ -40,7 +40,6 @@ #include "udev_version.h" #include "logging.h" #include "udev_rules.h" -#include "udev_db.h" #include "udev_selinux.h" diff --git a/udev_config.c b/udev_config.c index 192a0b80d2..7037a17081 100644 --- a/udev_config.c +++ b/udev_config.c @@ -38,7 +38,6 @@ /* global variables */ char sysfs_path[PATH_SIZE]; char udev_root[PATH_SIZE]; -char udev_db_path[PATH_SIZE]; char udev_config_filename[PATH_SIZE]; char udev_rules_filename[PATH_SIZE]; int udev_log_priority; @@ -153,12 +152,6 @@ static int parse_config_file(void) continue; } - if (strcasecmp(variable, "udev_db") == 0) { - strlcpy(udev_db_path, value, sizeof(udev_db_path)); - remove_trailing_chars(udev_db_path, '/'); - continue; - } - if (strcasecmp(variable, "udev_rules") == 0) { strlcpy(udev_rules_filename, value, sizeof(udev_rules_filename)); remove_trailing_chars(udev_rules_filename, '/'); @@ -180,7 +173,6 @@ void udev_init_config(void) const char *env; strcpy(udev_root, UDEV_ROOT); - strcpy(udev_db_path, UDEV_DB); strcpy(udev_config_filename, UDEV_CONFIG_FILE); strcpy(udev_rules_filename, UDEV_RULES_FILE); udev_log_priority = LOG_ERR; @@ -207,7 +199,6 @@ void udev_init_config(void) dbg("sysfs_path='%s'", sysfs_path); dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename); dbg("udev_root='%s'", udev_root); - dbg("udev_db='%s'", udev_db_path); dbg("udev_rules='%s'", udev_rules_filename); dbg("udev_log=%d", udev_log_priority); } diff --git a/udev_db.c b/udev_db.c index 5caf3fda80..e2b7b4d921 100644 --- a/udev_db.c +++ b/udev_db.c @@ -35,16 +35,16 @@ #include "udev.h" #include "udev_utils.h" #include "logging.h" -#include "udev_db.h" -#define PATH_TO_NAME_CHAR '@' static int devpath_to_db_path(const char *devpath, char *filename, size_t len) { size_t start, end, i; /* add location of db files */ - start = strlcpy(filename, udev_db_path, len); + strlcpy(filename, udev_root, len); + strlcat(filename, "/", len); + start = strlcat(filename, DB_DIR, len); end = strlcat(filename, devpath, len); if (end > len) end = len; @@ -205,12 +205,16 @@ int udev_db_delete_device(struct udevice *udev) int udev_db_lookup_name(const char *name, char *devpath, size_t len) { + char dbpath[PATH_MAX]; DIR *dir; int found = 0; - dir = opendir(udev_db_path); + strlcpy(dbpath, udev_root, sizeof(dbpath)); + strlcat(dbpath, "/", sizeof(dbpath)); + strlcat(dbpath, DB_DIR, sizeof(dbpath)); + dir = opendir(dbpath); if (dir == NULL) { - err("unable to open udev_db '%s': %s", udev_db_path, strerror(errno)); + err("unable to open udev_db '%s': %s", dbpath, strerror(errno)); return -1; } @@ -230,7 +234,7 @@ int udev_db_lookup_name(const char *name, char *devpath, size_t len) if (ent->d_name[0] == '.') continue; - snprintf(filename, sizeof(filename), "%s/%s", udev_db_path, ent->d_name); + snprintf(filename, sizeof(filename), "%s/%s", dbpath, ent->d_name); filename[sizeof(filename)-1] = '\0'; dbg("looking at '%s'", filename); @@ -274,11 +278,15 @@ int udev_db_lookup_name(const char *name, char *devpath, size_t len) int udev_db_get_all_entries(struct list_head *name_list) { + char dbpath[PATH_MAX]; DIR *dir; - dir = opendir(udev_db_path); + strlcpy(dbpath, udev_root, sizeof(dbpath)); + strlcat(dbpath, "/", sizeof(dbpath)); + strlcat(dbpath, DB_DIR, sizeof(dbpath)); + dir = opendir(dbpath); if (dir == NULL) { - err("unable to open udev_db '%s': %s", udev_db_path, strerror(errno)); + err("unable to open udev_db '%s': %s", dbpath, strerror(errno)); return -1; } diff --git a/udev_db.h b/udev_db.h deleted file mode 100644 index 89513932b3..0000000000 --- a/udev_db.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * udev_db.h - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _UDEV_DB_H_ -#define _UDEV_DB_H_ - - -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_lookup_name(const char *name, char *devpath, size_t len); -extern int udev_db_get_all_entries(struct list_head *name_list); - -#endif /* _UDEV_DB_H_ */ diff --git a/udev_remove.c b/udev_remove.c index 4d1b9286a0..8351860472 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -32,7 +32,6 @@ #include "udev.h" #include "udev_utils.h" #include "udev_version.h" -#include "udev_db.h" #include "logging.h" static int delete_path(const char *path) diff --git a/udev_rules.c b/udev_rules.c index a3100f8e14..492a9b0dfc 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -39,7 +39,6 @@ #include "udev_version.h" #include "logging.h" #include "udev_rules.h" -#include "udev_db.h" /* extract possible {attr} and move str behind it */ diff --git a/udevd.c b/udevd.c index 93f02c5395..e1afb7622b 100644 --- a/udevd.c +++ b/udevd.c @@ -139,9 +139,6 @@ enum event_state { EVENT_FAILED, }; -#define PATH_TO_NAME_CHAR '@' -#define EVENT_QUEUE_DIR ".udev/queue" -#define EVENT_FAILED_DIR ".udev/failed" static void export_event_state(struct uevent_msg *msg, enum event_state state) { char filename[PATH_SIZE]; diff --git a/udevd.h b/udevd.h index 4040942ac9..afbc3a31b1 100644 --- a/udevd.h +++ b/udevd.h @@ -29,6 +29,9 @@ #define UDEVD_PRIORITY -4 #define UDEV_PRIORITY -2 +#define EVENT_QUEUE_DIR ".udev/queue" +#define EVENT_FAILED_DIR ".udev/failed" + /* maximum limit of runnig childs */ #define UDEVD_MAX_CHILDS 64 /* start to throttle forking if maximum number of running childs in our session is reached */ diff --git a/udevinfo.c b/udevinfo.c index b668655f29..8ff09da3d1 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -31,7 +31,6 @@ #include "udev.h" #include "udev_utils.h" #include "udev_version.h" -#include "udev_db.h" #include "logging.h" From d7363ee14c3ea46611d3e706a3e198e07869afc3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 16 Nov 2005 04:35:37 +0100 Subject: [PATCH 1618/4284] Makefile: remove exec_prefix and srcdir Signed-off-by: Kay Sievers --- Makefile | 9 ++++----- extras/ata_id/Makefile | 9 ++++----- extras/cdrom_id/Makefile | 9 ++++----- extras/dasd_id/Makefile | 9 ++++----- extras/edd_id/Makefile | 9 ++++----- extras/firmware/Makefile | 9 ++++----- extras/floppy/Makefile | 9 ++++----- extras/run_directory/Makefile | 9 ++++----- extras/scsi_id/Makefile | 9 ++++----- extras/usb_id/Makefile | 9 ++++----- extras/volume_id/Makefile | 9 ++++----- 11 files changed, 44 insertions(+), 55 deletions(-) diff --git a/Makefile b/Makefile index 4968df4261..6cc51eea0a 100644 --- a/Makefile +++ b/Makefile @@ -108,11 +108,11 @@ GEN_HEADERS = \ # override this to make udev look in a different location for it's config files prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +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 @@ -248,7 +248,6 @@ udev_version.h: @echo "Creating udev_version.h" @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ - @echo \#define UDEV_CONFIG_DIR \"$(configdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ @echo \#define UDEVD_BIN \"$(sbindir)/udevd\" >> $@ diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index 4080df1b42..ebf0f4e9b4 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -12,14 +12,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index f1120673e1..985eb805a5 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -12,14 +12,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index a995c7892d..80680f22fe 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -12,14 +12,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/edd_id/Makefile b/extras/edd_id/Makefile index 469d6d4d03..5a6cdb65c3 100644 --- a/extras/edd_id/Makefile +++ b/extras/edd_id/Makefile @@ -12,14 +12,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index 48dacb4764..78a7935d66 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -12,14 +12,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index 344f48828d..d894a4a3e1 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -12,14 +12,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 1b48719c61..7d5bccbcca 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -11,14 +11,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index fadd4a1dd4..399de76911 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -15,14 +15,13 @@ GEN_HEADERS = scsi_id_version.h MAN_PAGES = scsi_id.8 prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index 9f82fd5b2c..f6d26e1c4c 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -12,14 +12,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 30c0abb9a4..6201044941 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -11,14 +11,13 @@ GEN_HEADERS = MAN_PAGES = prefix = -exec_prefix = ${prefix} etcdir = ${prefix}/etc -sbindir = ${exec_prefix}/sbin -usrbindir = ${exec_prefix}/usr/bin -usrsbindir = ${exec_prefix}/usr/sbin +sbindir = ${prefix}/sbin +usrbindir = ${prefix}/usr/bin +usrsbindir = ${prefix}/usr/sbin +libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev/ -srcdir = . INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} From c249f66a70f9ea623205f27f7931727acbafba9e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 16 Nov 2005 05:22:31 +0100 Subject: [PATCH 1619/4284] update README and RELEASE-NOTES Signed-off-by: Kay Sievers --- README | 89 ++++++++++++++++++++++++++++--------------- RELEASE-NOTES | 7 ++++ etc/udev/udev.conf.in | 6 +-- 3 files changed, 68 insertions(+), 34 deletions(-) diff --git a/README b/README index 3f4f947f79..fee078898c 100644 --- a/README +++ b/README @@ -4,65 +4,92 @@ 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 reasonable distros use udev these - days, the major ones make it mandatory and the system will not work without it. + and differs a lot from distro to distro. All reasonable distros depend on udev + these days and the system will not work without it. The upstream udev project does not support or recomend to replace a distro's udev installation with the upstream version. The installation of a unmodified upstream version may render your system unusable! There is no "default" setup or a set of "default" rules provided by the upstream udev version. -udev requires: - - 2.6 version of the Linux kernel +Requirements: + - 2.6 version of the Linux kernel. - - the kernel must have sysfs, netlink, and hotplug enabled + - The kernel must have sysfs, netlink, and hotplug enabled. - - proc must be mounted on /proc + - The proc filesystem must be mounted on /proc. - - sysfs must be mounted at /sys, no other location is supported + - The sysfs filesystem must be mounted at /sys. No other location + is supported. - - udev creates and removes device nodes in /dev based on events + +Operation: + - Udev creates and removes device nodes in /dev based on events the kernel sends out on device discovery or removal - - during bootup /dev usually gets a tmpfs mounted which is populated scratch - by udev (created nodes don't survive a reboot, it always starts from scratch) + - Directly after mounting the root filesystem, the udevd daemon must be + started by an init script. - - udev replaces the hotplug event management invoked from /sbin/hotplug - by the udevd daemon, which receives the kernel events over netlink + - From kernel version 2.6.15 on, the hotplug helper /sbin/hotplug should + be disabled with an init script before kernel modules are loaded. - - all kernel events are matched against a set of specified rules which - make it posible to hook into the event processing + - During bootup, /dev usually gets a tmpfs filesystem mounted which is + populated from scratch by udev (created nodes don't survive a reboot, + the /lib/udev/devices directory should be used for "static nodes"). - - there is a copy of the rules files for all major distros in the etc/udev - directory (you may look there how others distros are doing it) + - Udev replaces the hotplug event management invoked from /sbin/hotplug + by the udevd daemon, which receives the kernel events over netlink. -Setting which are used for building udev: + - All kernel events are matched against a set of specified rules which + make it possible to hook into the event processing. + + - Copies of the rules files for all major distros are in the etc/udev + directory (you may look there how others distros are doing it). + +Compile Options: prefix - set this to the default root that you want to use - Only override this if you really know what you are doing + Set this to the default root that you want to use only override + this if you really know what you are doing even then, you probably + don't do the right thing. DESTDIR - prefix for install target for package building + Prefix for install target, used for package building. USE_LOG - if set to 'true', udev will emit messages to the syslog when - it creates or removes device nodes. This is helpful to see - what udev is doing. This is enabled by default. + 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. DEBUG - if set to 'true', verbose debugging messages will be compiled into - the udev binaries. Default value is 'false'. + 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. + STRIPCMD + If udev is compiled for packaging an empty string can be passed + to disable the stripping of the binaries. USE_SELINUX - if set to 'true', udev will be built with SELinux support + If set to 'true', udev will be built with SELinux support enabled. This is disabled by default. USE_KLIBC - if set to 'true', udev is built and linked against klibc. + If set to 'true', udev is built and linked against klibc. Default value is 'false'. KLCC specifies the klibc compiler - wrapper, usually in /usr/bin/klcc + wrapper, usually located at /usr/bin/klcc. EXTRAS - if set, will build the "extra" helper programs as specified - as listed (see below for an example.) + If set, will build the "extra" helper programs as specified + as listed (see below for an example). -if you want to build the udev helper program cdrom_id and scsi_id: +If you want to build the udev helper program cdrom_id and scsi_id: make EXTRAS="extras/cdrom_id extras/scsi_id" +Installation: + - The install target intall the udev binaries in the default locations, + all at boot time reqired binaries will be installed in /sbin. + + - The default location for scripts and binaries that are called from + rules is /lib/udev. + + - 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. + Please direct any comment/question/concern to the linux-hotplug-devel mailing list at: linux-hotplug-devel@lists.sourceforge.net diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 69166cfef1..0d7951f75b 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -11,6 +11,13 @@ The option "udev_db" does no longer exist. All udev state will always be in /$udev_root/.udev/ now, there is no longer an option to set this to anything else. +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. 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. + udev 075 ======== Silent a too verbose error logging for the old hotplug.d/ dev.d/ diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index 90c1f99ba6..a92f688c3a 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -1,13 +1,13 @@ # udev.conf -# Where in the filesystem to place the device nodes +# Where in the filesystem to place the device nodes. udev_root="@udevdir@" # The name and location of the udev rules file(s). udev_rules="@configdir@/rules.d" # The initial syslog(3) priority: "err", "info", "debug" or its -# numerical equivalent. For runtime debugging, change the daemons -# internal state with: "udevcontrol log_priority=". +# numerical equivalent. For runtime debugging, the daemons internal +# state can be changed with: "udevcontrol log_priority=". udev_log="err" From 82de5983ab395df7f59ed53a51517a6066be3a57 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 17 Nov 2005 16:34:37 +0100 Subject: [PATCH 1620/4284] udevd: track killed event processes as failed Thanks to Marco for catching this. Signed-off-by: Kay Sievers --- udevd.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/udevd.c b/udevd.c index e1afb7622b..7978bdb08a 100644 --- a/udevd.c +++ b/udevd.c @@ -705,6 +705,8 @@ static void reap_sigchilds(void) break; if (WIFEXITED(status)) status = WEXITSTATUS(status); + else if (WIFSIGNALED(status)) + status = WTERMSIG(status) + 128; else status = 0; udev_done(pid, status); From dfc9761d8846a5f6f437fb599bc6817d14efbec2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 17 Nov 2005 18:05:29 +0100 Subject: [PATCH 1621/4284] update README Signed-off-by: Kay Sievers --- README | 77 +++++++++++++++++++++++++++++++++++----------------------- TODO | 3 --- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/README b/README index fee078898c..fe56095686 100644 --- a/README +++ b/README @@ -13,50 +13,58 @@ Important Note: of "default" rules provided by the upstream udev version. Requirements: - - 2.6 version of the Linux kernel. + - 2.6.x version of the Linux kernel. See the RELEASE-NOTES file in the + udev tree and the Documentation/Changes in the kernel source tree for + the actual dependency. - - The kernel must have sysfs, netlink, and hotplug enabled. + - The kernel must have sysfs and unix domain socket 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 - is supported. + 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 + Udev creates and removes device nodes in /dev, based on events the kernel + sends out on device discovery or removal. - - Directly after mounting the root filesystem, the udevd daemon must be - started by an init script. + - Directly after mouting the real root filesystem, wherever that + happens, in initramfs or with a directly mounted root, /dev should get + a tmpfs filesystem mounted, which is populated from scratch by udev. + Created nodes or changed permissions don't survive a reboot. + + - The content of /lib/udev/devices directory should be copied over to the + tmpfs mounted /dev, to provide the required nodes to initialize udev. + + - The udevd daemon must be started to receive netlink events from the kernel + driver core. - From kernel version 2.6.15 on, the hotplug helper /sbin/hotplug should - be disabled with an init script before kernel modules are loaded. + be disabled with an init script before the boot scripts are run and + kernel modules are loaded. - - During bootup, /dev usually gets a tmpfs filesystem mounted which is - populated from scratch by udev (created nodes don't survive a reboot, - the /lib/udev/devices directory should be used for "static nodes"). + - 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 requests a device node, udev will create one with + the default name or the one specified by a matching udev rules. - - Udev replaces the hotplug event management invoked from /sbin/hotplug - by the udevd daemon, which receives the kernel events over netlink. - - - All kernel events are matched against a set of specified rules which - make it possible to hook into the event processing. - - - Copies of the rules files for all major distros are in the etc/udev - directory (you may look there how others distros are doing it). Compile Options: prefix - Set this to the default root that you want to use only override - this if you really know what you are doing even then, you probably + Set this to the default root that you want to use. Only override + this if you really know what you are doing, even then, you probably don't do the right thing. DESTDIR Prefix for 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. + 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 @@ -75,20 +83,29 @@ Compile Options: If set, will build the "extra" helper programs as specified as listed (see below for an example). -If you want to build the udev helper program cdrom_id and scsi_id: - make EXTRAS="extras/cdrom_id extras/scsi_id" +If you want to build the udev helper programs: + make EXTRAS="extras/cdrom_id extras/scsi_id extras/volume_id" + Installation: - - The install target intall the udev binaries in the default locations, - all at boot time reqired binaries will be installed in /sbin. + - The install target intalls the udev binaries in the default locations, + All at boot time reqired binaries will be installed in /sbin. - The default location for scripts and binaries that are called from - rules is /lib/udev. + rules is /lib/udev. Other packages who install udev rules, should use + that diretory 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. + detected automatically by the kernel, will always be available. + + - Copies of the rules files for all major distros are in the etc/udev + directory (you may look there how others distros are doing it). + + - The persistent disk links in /dev/disk are the de facto standard + on Linux and should be installed with every default udev installation. + The devfs naming scheme rules are not recommended and not supported. Please direct any comment/question/concern to the linux-hotplug-devel mailing list at: linux-hotplug-devel@lists.sourceforge.net diff --git a/TODO b/TODO index 41ea98ff02..7e123d8b14 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,6 @@ This is a list of things that needs to be done. They are in no specific order. We will gladly accept patches for any of these items: -- Completely replace the built-in wait_for_sysfs stuff in udev_sysfs.c - by rules using the WAIT_FOR_SYSFS key. - - Log the relationship of the kernel name and the persistent disk name to syslog, so any error logged from the kernel can be associated with any of the links at that time. From 4389ec08fb177f62fc02eb2217fed126aef3a7a3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 17 Nov 2005 18:50:47 +0100 Subject: [PATCH 1622/4284] don't start udevd from udevsend Doesn't make any sense these days to let the kernel start the daemon. Signed-off-by: Kay Sievers --- Makefile | 1 - RELEASE-NOTES | 4 +++ udevsend.c | 81 +++++---------------------------------------------- 3 files changed, 12 insertions(+), 74 deletions(-) diff --git a/Makefile b/Makefile index 6cc51eea0a..718cf4347d 100644 --- a/Makefile +++ b/Makefile @@ -250,7 +250,6 @@ udev_version.h: @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ - @echo \#define UDEVD_BIN \"$(sbindir)/udevd\" >> $@ # man pages %.8: docs/%.xml diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 0d7951f75b..cbec3d31ab 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -18,6 +18,10 @@ 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/ diff --git a/udevsend.c b/udevsend.c index d0cfc2af53..8cabe9039b 100644 --- a/udevsend.c +++ b/udevsend.c @@ -54,52 +54,15 @@ void log_message (int priority, const char *format, ...) } #endif -static int start_daemon(void) -{ - pid_t pid; - pid_t child_pid; - char *const argv[] = { "udevd", NULL }; - char *const envp[] = { NULL }; - - pid = fork(); - switch (pid) { - case 0: - /* helper child */ - child_pid = fork(); - switch (child_pid) { - case 0: - /* daemon with empty environment */ - close(sock); - execve(UDEVD_BIN, argv, envp); - err("exec of daemon failed: %s", strerror(errno)); - _exit(1); - case -1: - err("fork of daemon failed: %s", strerror(errno)); - return -1; - default: - exit(0); - } - break; - case -1: - err("fork of helper failed: %s", strerror(errno)); - return -1; - default: - waitpid(pid, NULL, 0); - } - return 0; -} - int main(int argc, char *argv[], char *envp[]) { static struct udevd_msg usend_msg; int usend_msg_len; int i; - int loop; struct sockaddr_un saddr; socklen_t addrlen; int bufpos = 0; - int retval = 1; - int started_daemon = 0; + int retval = 0; const char *subsystem = NULL; logging_init("udevsend"); @@ -109,8 +72,9 @@ int main(int argc, char *argv[], char *envp[]) dbg("version %s", UDEV_VERSION); sock = socket(AF_LOCAL, SOCK_DGRAM, 0); - if (sock == -1) { + if (sock < 0) { err("error getting socket: %s", strerror(errno)); + retval = 1; goto exit; } @@ -134,7 +98,8 @@ int main(int argc, char *argv[], char *envp[]) /* prevent loops in the scripts we execute */ if (strncmp(key, "UDEVD_EVENT=", 12) == 0) { - dbg("seems that the event source is not the kernel, just exit"); + err("event loop, already passed through the daemon, exit"); + retval = 2; goto exit; } @@ -151,42 +116,13 @@ int main(int argc, char *argv[], char *envp[]) strcpy(&usend_msg.envbuf[bufpos], key); bufpos += keylen + 1; } - /* older kernels passed the SUBSYSTEM only as the first argument */ - if (!subsystem && argc == 2) { - bufpos += sprintf(&usend_msg.envbuf[bufpos], "SUBSYSTEM=%s", argv[1]) + 1; - dbg("add 'SUBSYSTEM=%s' to env[%i] buffer from argv", argv[1], i); - } usend_msg_len = offsetof(struct udevd_msg, envbuf) + bufpos; dbg("usend_msg_len=%i", usend_msg_len); - /* If we can't send, try to start daemon and resend message */ - loop = UDEVSEND_WAIT_MAX_SECONDS * UDEVSEND_WAIT_LOOP_PER_SECOND; - while (--loop) { - retval = sendto(sock, &usend_msg, usend_msg_len, 0, (struct sockaddr *)&saddr, addrlen); - if (retval != -1) { - retval = 0; - goto exit; - } - - if (errno != ECONNREFUSED) { - err("error sending message: %s", strerror(errno)); - goto exit; - } - - if (!started_daemon) { - info("try to start udevd daemon"); - retval = start_daemon(); - if (retval) { - dbg("error starting daemon"); - goto exit; - } - dbg("udevd daemon started"); - started_daemon = 1; - } else { - dbg("retry to connect %d", UDEVSEND_WAIT_MAX_SECONDS * UDEVSEND_WAIT_LOOP_PER_SECOND - loop); - usleep(1000 * 1000 / UDEVSEND_WAIT_LOOP_PER_SECOND); - } + if (sendto(sock, &usend_msg, usend_msg_len, 0, (struct sockaddr *)&saddr, addrlen) < 0) { + retval = 3; + err("error sending message: %s", strerror(errno)); } exit: @@ -194,6 +130,5 @@ exit: close(sock); logging_close(); - return retval; } From 8813e55c74d8224a361f62fc8c9f01591dfb58d3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 17 Nov 2005 18:53:53 +0100 Subject: [PATCH 1623/4284] udevd: add a missing return Signed-off-by: Kay Sievers --- udevd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udevd.c b/udevd.c index 7978bdb08a..446db8fd33 100644 --- a/udevd.c +++ b/udevd.c @@ -190,6 +190,7 @@ static void export_event_state(struct uevent_msg *msg, enum event_state state) if (loop_msg->devpath && strcmp(loop_msg->devpath, msg->devpath) == 0) return; unlink(filename); + return; case EVENT_FAILED: create_path(filename_failed); rename(filename, filename_failed); From cfd0fc66054cb7eab4989d214e4f8552dc2bf0b8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 21 Nov 2005 18:28:56 +0100 Subject: [PATCH 1624/4284] libvolume_id: fix weird fat volume recognition Signed-off-by: Kay Sievers --- extras/volume_id/libvolume_id/fat.c | 37 +++++++++++------------ extras/volume_id/libvolume_id/volume_id.h | 2 +- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/extras/volume_id/libvolume_id/fat.c b/extras/volume_id/libvolume_id/fat.c index 26d0fe74ab..cea5b8cff2 100644 --- a/extras/volume_id/libvolume_id/fat.c +++ b/extras/volume_id/libvolume_id/fat.c @@ -161,32 +161,38 @@ int volume_id_probe_vfat(struct volume_id *id, uint64_t off) return -1; if (memcmp(vs->type.fat32.magic, "MSWIN", 5) == 0) - goto valid; + goto magic; if (memcmp(vs->type.fat32.magic, "FAT32 ", 8) == 0) - goto valid; + goto magic; if (memcmp(vs->type.fat.magic, "FAT16 ", 8) == 0) - goto valid; + goto magic; if (memcmp(vs->type.fat.magic, "MSDOS", 5) == 0) - goto valid; + goto magic; if (memcmp(vs->type.fat.magic, "FAT12 ", 8) == 0) - goto valid; + goto magic; - /* - * There are old floppies out there without a magic, so we check - * for well known values and guess if it's a fat volume - */ + /* some old floppies don't have a magic, so we expect the boot code to match */ /* boot jump address check */ if ((vs->boot_jump[0] != 0xeb || vs->boot_jump[2] != 0x90) && vs->boot_jump[0] != 0xe9) return -1; - /* heads check */ - if (vs->heads == 0) +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*/ @@ -194,15 +200,6 @@ int volume_id_probe_vfat(struct volume_id *id, uint64_t off) (vs->sectors_per_cluster & (vs->sectors_per_cluster-1))) return -1; - /* media check */ - if (vs->media < 0xf8 && vs->media != 0xf0) - return -1; - - /* fat count*/ - if (vs->fats != 2) - return -1; - -valid: /* sector size check */ sector_size = le16_to_cpu(vs->sector_size); if (sector_size != 0x200 && sector_size != 0x400 && diff --git a/extras/volume_id/libvolume_id/volume_id.h b/extras/volume_id/libvolume_id/volume_id.h index 3e3acbde9f..ad65fe5438 100644 --- a/extras/volume_id/libvolume_id/volume_id.h +++ b/extras/volume_id/libvolume_id/volume_id.h @@ -14,7 +14,7 @@ #include #include -#define VOLUME_ID_VERSION 54 +#define VOLUME_ID_VERSION 55 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 From 0da0efb2b622435209d183b49e2d16d426142b2c Mon Sep 17 00:00:00 2001 From: Scott James Remnant Date: Tue, 22 Nov 2005 15:44:02 +0100 Subject: [PATCH 1625/4284] move delete_path() to utils --- udev_remove.c | 29 ----------------------------- udev_utils.h | 1 + udev_utils_file.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/udev_remove.c b/udev_remove.c index 8351860472..6efa17eb7c 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -34,35 +34,6 @@ #include "udev_version.h" #include "logging.h" -static int delete_path(const char *path) -{ - char *pos; - int retval; - - pos = strrchr(path, '/'); - while (1) { - *pos = '\0'; - pos = strrchr(path, '/'); - - /* don't remove the last one */ - if ((pos == path) || (pos == NULL)) - break; - - /* remove if empty */ - retval = rmdir(path); - if (errno == ENOENT) - retval = 0; - if (retval) { - if (errno == ENOTEMPTY) - return 0; - err("rmdir(%s) failed: %s", path, strerror(errno)); - break; - } - dbg("removed '%s'", path); - } - return 0; -} - static int delete_node(struct udevice *udev) { char filename[PATH_SIZE]; diff --git a/udev_utils.h b/udev_utils.h index ffdaf0469f..a28ba005ca 100644 --- a/udev_utils.h +++ b/udev_utils.h @@ -51,6 +51,7 @@ extern int replace_untrusted_chars(char *str); /* 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); diff --git a/udev_utils_file.c b/udev_utils_file.c index a3dab58b36..cd9c244f0f 100644 --- a/udev_utils_file.c +++ b/udev_utils_file.c @@ -63,6 +63,37 @@ int create_path(const char *path) return mkdir(p, 0755); } +int delete_path(const char *path) +{ + char p[PATH_SIZE]; + char *pos; + int retval; + + strcpy (p, path); + pos = strrchr(p, '/'); + 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. */ From 1b75f1096e8fdf2ec5ab4ec112f20b69fbd084c3 Mon Sep 17 00:00:00 2001 From: Scott James Remnant Date: Tue, 22 Nov 2005 15:49:49 +0100 Subject: [PATCH 1626/4284] clean-up empty queue directories This allows scripts to do: while test -d /dev/.udev/queue; do sleep 0.1; done And don't create a failed symlink if there is another event for the same devpath in the queue. --- udevd.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/udevd.c b/udevd.c index 446db8fd33..25ef857a8c 100644 --- a/udevd.c +++ b/udevd.c @@ -176,6 +176,7 @@ static void export_event_state(struct uevent_msg *msg, enum event_state state) switch (state) { case EVENT_QUEUED: unlink(filename_failed); + delete_path(filename_failed); strlcpy(target, sysfs_path, sizeof(target)); strlcat(target, msg->devpath, sizeof(target)); @@ -183,17 +184,26 @@ static void export_event_state(struct uevent_msg *msg, enum event_state state) symlink(target, filename); 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 */ + /* 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; - unlink(filename); - return; - case EVENT_FAILED: - create_path(filename_failed); - rename(filename, filename_failed); + + /* 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; } } From c699bc48e1432bc1b283907a52e461b97f2e45b1 Mon Sep 17 00:00:00 2001 From: Scott James Remnant Date: Tue, 22 Nov 2005 16:33:25 +0100 Subject: [PATCH 1627/4284] Makefile: fail, if submake fails --- Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 718cf4347d..54bfb31cd3 100644 --- a/Makefile +++ b/Makefile @@ -208,7 +208,7 @@ all: $(PROGRAMS) $(MAN_PAGES) LIBUDEV="$(PWD)/$(LIBUDEV)" \ LIBSYSFS="$(PWD)/$(LIBSYSFS)" \ QUIET="$(QUIET)" \ - -C $$target $@; \ + -C $$target $@ || exit 1; \ done; .PHONY: all .DEFAULT: all @@ -270,7 +270,7 @@ clean: - rm -f udev-$(VERSION).tar.gz @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) -C $$target $@; \ + $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: clean @@ -292,7 +292,7 @@ install-config: $(GEN_CONFIGS) fi @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) -C $$target $@; \ + $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: install-config @@ -307,7 +307,7 @@ install-man: - ln -f -s udevd.8 $(DESTDIR)$(mandir)/man8/udevcontrol.8 @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) -C $$target $@; \ + $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: install-man @@ -322,7 +322,7 @@ uninstall-man: - rm -f $(DESTDIR)$(mandir)/man8/udevcontrol.8 @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) -C $$target $@; \ + $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: uninstall-man @@ -338,7 +338,7 @@ install-bin: $(INSTALL_PROGRAM) -D udevstart $(DESTDIR)$(sbindir)/udevstart @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) -C $$target $@; \ + $(MAKE) -C $$target $@ || exit 1; \ done; ifndef DESTDIR - killall udevd @@ -362,7 +362,7 @@ ifndef DESTDIR endif @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ - $(MAKE) -C $$target $@; \ + $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: uninstall-bin From e0dc4f00baaa4ad328aa13362fcf25e7ec2ae2f6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 22 Nov 2005 17:31:38 +0100 Subject: [PATCH 1628/4284] move some helpers from extras to /lib/udev Signed-off-by: Kay Sievers --- RELEASE-NOTES | 18 ++++++++++++------ extras/firmware/Makefile | 4 ++-- extras/floppy/Makefile | 4 ++-- extras/run_directory/Makefile | 8 ++++---- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index cbec3d31ab..86a7fa8bde 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -7,16 +7,22 @@ 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 always -be in /$udev_root/.udev/ now, there is no longer an option to set this +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. 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. +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, diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index 78a7935d66..16918867fc 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -48,11 +48,11 @@ clean: .PHONY: clean install-bin: all - $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG) .PHONY: install-bin uninstall-bin: - - rm $(DESTDIR)$(sbindir)/$(PROG) + - rm $(DESTDIR)$(libudevdir)/$(PROG) .PHONY: uninstall-bin install-man: diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index d894a4a3e1..240af4ce05 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -48,11 +48,11 @@ clean: .PHONY: clean install-bin: all - $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) + $(INSTALL_PROGRAM) -D $(PROG) $(DESTDIR)$(libudevdir)/$(PROG) .PHONY: install-bin uninstall-bin: - - rm $(DESTDIR)$(sbindir)/$(PROG) + - rm $(DESTDIR)$(libudevdir)/$(PROG) .PHONY: uninstall-bin install-man: diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 7d5bccbcca..d138f62c03 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -47,13 +47,13 @@ clean: .PHONY: clean install-bin: all - $(INSTALL_PROGRAM) udev_run_devd $(DESTDIR)$(sbindir)/udev_run_devd - $(INSTALL_PROGRAM) udev_run_hotplugd $(DESTDIR)$(sbindir)/udev_run_hotplugd + $(INSTALL_PROGRAM) -D udev_run_devd $(DESTDIR)$(libudevdir)/udev_run_devd + $(INSTALL_PROGRAM) -D udev_run_hotplugd $(DESTDIR)$(libudevdir)/udev_run_hotplugd .PHONY: install-bin uninstall-bin: - - rm $(DESTDIR)$(sbindir)/udev_run_devd - - rm $(DESTDIR)$(sbindir)/udev_run_hotplugd + - rm $(DESTDIR)$(libudevdir)/udev_run_devd + - rm $(DESTDIR)$(libudevdir)/udev_run_hotplugd .PHONY: uninstall-bin install-man: From 4a924f0a58024258098e03e3a8827acbc26c591e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 22 Nov 2005 17:34:55 +0100 Subject: [PATCH 1629/4284] 076 release --- ChangeLog | 29 +++++++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index bde6b4f05e..795de89707 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 54bfb31cd3..48a130491e 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 075 +VERSION = 076 # set this to make use of syslog USE_LOG = true From 30473427e8c958158750a0ee412315282c25f3ae Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 24 Nov 2005 20:06:22 +0100 Subject: [PATCH 1630/4284] merge two consecutive static strlcat's Thanks for Marco, who noticed it. Signed-off-by: Kay Sievers --- udev_db.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/udev_db.c b/udev_db.c index e2b7b4d921..6e9a1187d0 100644 --- a/udev_db.c +++ b/udev_db.c @@ -43,8 +43,7 @@ static int devpath_to_db_path(const char *devpath, char *filename, size_t len) /* add location of db files */ strlcpy(filename, udev_root, len); - strlcat(filename, "/", len); - start = strlcat(filename, DB_DIR, len); + start = strlcat(filename, "/"DB_DIR, len); end = strlcat(filename, devpath, len); if (end > len) end = len; @@ -210,8 +209,7 @@ int udev_db_lookup_name(const char *name, char *devpath, size_t len) int found = 0; strlcpy(dbpath, udev_root, sizeof(dbpath)); - strlcat(dbpath, "/", sizeof(dbpath)); - strlcat(dbpath, DB_DIR, sizeof(dbpath)); + strlcat(dbpath, "/"DB_DIR, sizeof(dbpath)); dir = opendir(dbpath); if (dir == NULL) { err("unable to open udev_db '%s': %s", dbpath, strerror(errno)); @@ -282,8 +280,7 @@ int udev_db_get_all_entries(struct list_head *name_list) DIR *dir; strlcpy(dbpath, udev_root, sizeof(dbpath)); - strlcat(dbpath, "/", sizeof(dbpath)); - strlcat(dbpath, DB_DIR, sizeof(dbpath)); + strlcat(dbpath, "/"DB_DIR, sizeof(dbpath)); dir = opendir(dbpath); if (dir == NULL) { err("unable to open udev_db '%s': %s", dbpath, strerror(errno)); From 8d1425d54717b9b9ec06efdd1dd25559445e2571 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 24 Nov 2005 20:06:51 +0100 Subject: [PATCH 1631/4284] don't return an error, if "ignore_device" is used Signed-off-by: Kay Sievers --- udev_event.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/udev_event.c b/udev_event.c index 353aff09b7..0b4b9dc495 100644 --- a/udev_event.c +++ b/udev_event.c @@ -95,7 +95,7 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) if (udev->ignore_device) { info("device event will be ignored"); sysfs_close_class_device(class_dev); - return -1; + return 0; } if (udev->name[0] != '\0') { /* create node, store in db */ @@ -109,7 +109,7 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) if (udev->ignore_device) { info("device event will be ignored"); sysfs_close_class_device(class_dev); - return -1; + return 0; } } sysfs_close_class_device(class_dev); @@ -127,7 +127,7 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) udev_rules_get_run(rules, udev, NULL, NULL); if (udev->ignore_device) { dbg("device event will be ignored"); - return -1; + return 0; } } @@ -151,14 +151,14 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) sysfs_close_device(devices_dev); if (udev->ignore_device) { info("device event will be ignored"); - return -1; + return 0; } } else { dbg("default handling"); udev_rules_get_run(rules, udev, NULL, NULL); if (udev->ignore_device) { info("device event will be ignored"); - return -1; + return 0; } } return 0; From a8a614a7018918e987585c2d07189024c640cb3a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 25 Nov 2005 18:50:42 +0100 Subject: [PATCH 1632/4284] remove outdated and misleading stuff Packagers who still need this, should carry it in their own package. It just causes too much trouble to users to have it in the tree and expect that it's needed or the way to do it. Signed-off-by: Kay Sievers --- README | 10 ++-- etc/udev/udev-devfs.rules | 2 +- extras/dvb.sh | 3 -- extras/inputdev.sh | 30 ----------- extras/name_cdrom.pl | 7 ++- extras/start_udev | 102 -------------------------------------- 6 files changed, 10 insertions(+), 144 deletions(-) delete mode 100644 extras/dvb.sh delete mode 100644 extras/inputdev.sh delete mode 100644 extras/start_udev diff --git a/README b/README index fe56095686..9e1aae3452 100644 --- a/README +++ b/README @@ -36,11 +36,13 @@ Operation: a tmpfs filesystem mounted, which is populated from scratch by udev. Created nodes or changed permissions don't survive a reboot. - - The content of /lib/udev/devices directory should be copied over to the - tmpfs mounted /dev, to provide the required nodes to initialize udev. + - 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 udevd daemon must be started to receive netlink events from the kernel - driver core. + - The udevd daemon must be started by an init script to receive netlink + events from the kernel driver core. - From kernel version 2.6.15 on, the hotplug helper /sbin/hotplug should be disabled with an init script before the boot scripts are run and diff --git a/etc/udev/udev-devfs.rules b/etc/udev/udev-devfs.rules index 380bbee85b..ec44692d68 100644 --- a/etc/udev/udev-devfs.rules +++ b/etc/udev/udev-devfs.rules @@ -2,7 +2,7 @@ # is just kept around to proof that udev is able to emulate the devfs scheme. # # In a world where devices can come and go at any time, the devfs device -# naming scheme of simple grouping and enumeration does not help _anything_. +# naming scheme of simple grouping and enumeration DOES NOT HELP ANYTHING. # # Use custom rules to name your device or look at the persistent device # naming scheme, which is implemented for disks and extend it in a diff --git a/extras/dvb.sh b/extras/dvb.sh deleted file mode 100644 index b14a6d0d7b..0000000000 --- a/extras/dvb.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e -echo $1 | sed -e 's#^dvb\([0-9]\)\.\([^0-9]*\)\([0-9]\)#dvb/adapter\1/\2\3#' -exit 0 diff --git a/extras/inputdev.sh b/extras/inputdev.sh deleted file mode 100644 index 82e4fdc374..0000000000 --- a/extras/inputdev.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh -e -# -# Scans /proc/bus/input/devices for the given device. -# -# (c) 2004 Darren Salt -# GPL v2 or later applies. - -[ "$1" ] || exit 0 - -# input device name, less leading "input/" -DEVICE=${1#input/} - -# "|"-separated list. -# The first found in the given device's "N:" line will be output. -DEFAULT_KEYWORDS='dvb|saa7134' -KEYWORDS=${2:-$DEFAULT_KEYWORDS} - -exec sed -nre ' - /^I:/ { - : gather - N - /\nH:/! b gather - /'"$DEVICE"'/ { - s/^.*\nN:[^\n]*("|\b)('"$KEYWORDS"')("|\b)[^\n]*\n.*$/inputdev/ - T - p - } - } -' < /proc/bus/input/devices - diff --git a/extras/name_cdrom.pl b/extras/name_cdrom.pl index 5e696f33ae..28d2d29a3d 100644 --- a/extras/name_cdrom.pl +++ b/extras/name_cdrom.pl @@ -1,9 +1,8 @@ #!/usr/bin/perl -# a horribly funny script that shows how flexible udev can really be -# This is to be executed by udev with the following rules: -# -# KERNEL="hd*[!0-9]|sr*", PROGRAM="name_cdrom.pl $tempnode", SYMLINK+="%c" +# Horrible but funny script that shows how flexible udev can really be +# This is to be executed by udev with the following rule: +# KERNEL="hd*[!0-9]|sr*", PROGRAM="name_cdrom.pl $tempnode", SYMLINK+="%c" use strict; use warnings; diff --git a/extras/start_udev b/extras/start_udev deleted file mode 100644 index c2518761e3..0000000000 --- a/extras/start_udev +++ /dev/null @@ -1,102 +0,0 @@ -#! /bin/sh -# -# start_udev -# -# script to initialize /dev by using udev. -# -# Copyright (C) 2004 Greg Kroah-Hartman -# -# Released under the GPL v2 only. -# -# This needs to be run at the earliest possible point in the boot -# process. -# -# Based on the udev init.d script -# -# Thanks go out to the Gentoo developers for proving -# that this is possible to do. -# -# Yes, it's very verbose, feel free to turn off all of the echo calls, -# they were there to make me feel better that everything was working -# properly during development... -# - -. /etc/udev/udev.conf - -prog=udev -sysfs_dir=/sys -bin=/sbin/udev -udevd=/sbin/udevd - -run_udev () { - export ACTION=add - - # handle block devices and their partitions - for i in ${sysfs_dir}/block/*; do - # add each drive - export DEVPATH=${i#${sysfs_dir}} - echo "$DEVPATH" - $bin block - - # add each partition, on each device - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - echo "$DEVPATH" - $bin block - fi - done - done - # all other device classes - for i in ${sysfs_dir}/class/*; do - for j in $i/*; do - if [ -f $j/dev ]; then - export DEVPATH=${j#${sysfs_dir}} - CLASS=`echo ${i#${sysfs_dir}} | \ - cut --delimiter='/' --fields=3-` - echo "$DEVPATH" - $bin $CLASS - fi - done - done - return 0 -} - -make_extra_nodes () { - # there are a few things that sysfs does not export for us. - # these things go here (and remember to remove them in - # remove_extra_nodes() - # - # Thanks to Gentoo for the initial list of these. - ln -snf /proc/self/fd $udev_root/fd - ln -snf /proc/self/fd/0 $udev_root/stdin - ln -snf /proc/self/fd/1 $udev_root/stdout - ln -snf /proc/self/fd/2 $udev_root/stderr - ln -snf /proc/kcore $udev_root/core - - mkdir $udev_root/pts - mkdir $udev_root/shm -} - -# don't use udev if sysfs is not mounted. -if [ ! -d $sysfs_dir/block ]; then - exit 1 -fi - -echo "mounting... ramfs at $udev_root" -mount -n -t ramfs none $udev_root - -# propogate /udev from /sys -echo "Creating initial udev device nodes:" - -# You can use the shell scripts above by calling run_udev or execute udevstart -# which does the same thing, but much faster by not using shell. -# only comment out one of the following lines. -#run_udev -/sbin/udevstart - -echo "making extra nodes" -make_extra_nodes - -echo "udev startup is finished!" -exit 0 From 2796c47b5c88f2775247fd0cddc1385d6bbb10bd Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Fri, 25 Nov 2005 18:56:06 +0100 Subject: [PATCH 1633/4284] allow to overwrite the configured udev_root by exporting UDEV_ROOT --- udev_config.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/udev_config.c b/udev_config.c index 7037a17081..c1af7c12ca 100644 --- a/udev_config.c +++ b/udev_config.c @@ -192,6 +192,12 @@ void udev_init_config(void) 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); From 13141b9a6a046e2aca812b2442f12f116856addf Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Fri, 25 Nov 2005 19:02:25 +0100 Subject: [PATCH 1634/4284] let udevsend ignore events with SEQNUM set Using syslog from udevsend for error logging when the daemon is not running, causes vc events and an udev event loop. --- udevsend.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/udevsend.c b/udevsend.c index 8cabe9039b..b67df9720b 100644 --- a/udevsend.c +++ b/udevsend.c @@ -96,6 +96,13 @@ int main(int argc, char *argv[], char *envp[]) key = envp[i]; keylen = strlen(key); + /* ignore events which are already sent on the netlink socket */ + if (strncmp(key, "SEQNUM=", 7) == 0) { + dbg("ignoring event with SEQNUM set"); + retval = 0; + goto exit; + } + /* prevent loops in the scripts we execute */ if (strncmp(key, "UDEVD_EVENT=", 12) == 0) { err("event loop, already passed through the daemon, exit"); From 997b164d56257244411aea4d709e47e6ca2da299 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 25 Nov 2005 19:03:16 +0100 Subject: [PATCH 1635/4284] move SEQNUM event skipping to udevsend Signed-off-by: Kay Sievers --- udevd.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/udevd.c b/udevd.c index 25ef857a8c..b87fe56413 100644 --- a/udevd.c +++ b/udevd.c @@ -979,13 +979,8 @@ int main(int argc, char *argv[], char *envp[]) /* get user socket message */ if (FD_ISSET(udevd_sock, &readfds)) { msg = get_udevd_msg(); - if (msg) { - if (msg->type == UDEVD_UEVENT_UDEVSEND && msg->seqnum != 0) { - info("skip non-kernel message with SEQNUM"); - free(msg); - } else - msg_queue_insert(msg); - } + if (msg) + msg_queue_insert(msg); } /* get kernel netlink message */ From 7403f98b53b115738299d7ed7a0b4d23d727ce92 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 25 Nov 2005 19:13:28 +0100 Subject: [PATCH 1636/4284] update RELEASE-NOTES Signed-off-by: Kay Sievers --- ChangeLog | 14 ++++++++++++++ RELEASE-NOTES | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index 795de89707..52a88a976a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Summary of changes from v76 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 + +Marco d'Itri: + allow to overwrite the configured udev_root by exporting UDEV_ROOT + let udevsend ignore events with SEQNUM set + + Summary of changes from v75 to v076 ============================================ diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 86a7fa8bde..4006e510d7 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,9 @@ +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 From de34dc2b06f941a7d3aa12e4cdc62b48677a0c3b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 25 Nov 2005 19:30:33 +0100 Subject: [PATCH 1637/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/10-wait-for-sysfs.rules | 1 + etc/udev/suse/40-alsa.rules | 16 ++++ etc/udev/suse/40-bluetooth.rules | 82 +++++++++++++++++++ .../suse/{80-pcmcia.rules => 50-pcmcia.rules} | 4 +- etc/udev/suse/50-udev.rules | 68 ++++++--------- etc/udev/suse/60-persistent.rules | 2 + etc/udev/suse/80-sysconfig.rules | 14 ++-- etc/udev/suse/90-hal.rules | 2 +- 8 files changed, 133 insertions(+), 56 deletions(-) create mode 100644 etc/udev/suse/10-wait-for-sysfs.rules create mode 100644 etc/udev/suse/40-alsa.rules create mode 100644 etc/udev/suse/40-bluetooth.rules rename etc/udev/suse/{80-pcmcia.rules => 50-pcmcia.rules} (73%) diff --git a/etc/udev/suse/10-wait-for-sysfs.rules b/etc/udev/suse/10-wait-for-sysfs.rules new file mode 100644 index 0000000000..80c1781530 --- /dev/null +++ b/etc/udev/suse/10-wait-for-sysfs.rules @@ -0,0 +1 @@ +ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus" diff --git a/etc/udev/suse/40-alsa.rules b/etc/udev/suse/40-alsa.rules new file mode 100644 index 0000000000..79888dd3be --- /dev/null +++ b/etc/udev/suse/40-alsa.rules @@ -0,0 +1,16 @@ +SUBSYSTEM="sound", GROUP="audio" +SUBSYSTEM="snd", GROUP="audio" +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" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8000/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us428fw.ihx" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8004/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us224fw.ihx" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8006/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us122fw.ihx" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8001/*", RUN+="/sbin/startproc /usr/bin/us428control" +SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8005/*", RUN+="/sbin/startproc /usr/bin/us428control" +SUBSYSTEM=="sound", KERNEL=="controlC?", RUN+="/usr/sbin/alsactl -F restore %n" +SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVER=="EMU10K1_Audigy", RUN+="/etc/alsa.d/udev-soundfont" + diff --git a/etc/udev/suse/40-bluetooth.rules b/etc/udev/suse/40-bluetooth.rules new file mode 100644 index 0000000000..7405d15b21 --- /dev/null +++ b/etc/udev/suse/40-bluetooth.rules @@ -0,0 +1,82 @@ +# bluetooth subsystem +SUBSYSTEM=="bluetooth", RUN+="/sbin/udev.bluetooth.sh" + +# uncomment this if you have configured an automatic rfcomm-bind in +# /etc/bluetooth/rfcomm.conf +# KERNEL=="rfcomm*", NAME="%k" GROUP="uucp" MODE="0660" OPTIONS="resmgr" + +## PCMCIA-Cards +# "Brain Boxes BL-620 Bluetooth Adapter" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Brain Boxes", SYSFS{prod_id2}=="Bluetooth PC Card", RUN+="/etc/pcmcia/bluetooth.sh" +# "Xircom CreditCard Bluetooth Adapter" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Xircom", SYSFS{prod_id3}=="CBT", RUN+="/etc/pcmcia/bluetooth.sh" +# "Xircom RealPort2 Bluetooth Adapter" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Xircom", SYSFS{prod_id3}=="CBT", RUN+="/etc/pcmcia/bluetooth.sh" +# "IBM Bluetooth PC Card II" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="IBM", SYSFS{prod_id2}=="Bluetooth PC Card II", RUN+="/etc/pcmcia/bluetooth.sh" +# "TDK Bluetooth PC Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="TDK", SYSFS{prod_id2}=="Bluetooth PC Card II", RUN+="/etc/pcmcia/bluetooth.sh" +# "AmbiCom BT2000C Bluetooth PC/CF Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="AmbiCom BT2000C", SYSFS{prod_id2}=="Bluetooth PC/CF Card", RUN+="/etc/pcmcia/bluetooth.sh" +# "COM One Platinium Bluetooth PC Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="COM1 SA", SYSFS{prod_id2}=="MC310 CARD", RUN+="/etc/pcmcia/bluetooth.sh" +# "Sphinx PICO Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="SPHINX", SYSFS{prod_id2}=="BT-CARD", RUN+="/etc/pcmcia/bluetooth.sh" +# "H-Soft blue+Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="H-Soft", SYSFS{prod_id2}=="Blue+CARD", RUN+="/etc/pcmcia/bluetooth.sh" +# "Compaq iPAQ Bluetooth Sleeve" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="CF CARD", SYSFS{prod_id2}=="GENERIC", RUN+="/etc/pcmcia/bluetooth.sh" +# "Zoom Bluetooth Card" +# "Sitecom CN-504 Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="PCMCIA", SYSFS{prod_id2}=="Bluetooth Card", RUN+="/etc/pcmcia/bluetooth.sh" + + +# +# dtl1_cs +# +# card "Nokia Bluetooth Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Nokia Mobile Phones", SYSFS{prod_id2}=="DTL-1", RUN+="/etc/pcmcia/bluetooth.sh" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Nokia Mobile Phones", SYSFS{prod_id2}=="DTL-4", RUN+="/etc/pcmcia/bluetooth.sh" +# "Socket Bluetooth Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Socket", SYSFS{prod_id2}=="CF+ Personal Network Card", RUN+="/etc/pcmcia/bluetooth.sh" + + +# +# bt3c_cs +# + +# "3Com Bluetooth PC Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="3COM", SYSFS{prod_id3}=="Bluetooth PC Card", RUN+="/etc/pcmcia/bluetooth.sh" + +# +# bluecard_cs +# + +# "LSE041 Bluetooth PC Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="BlueCard", SYSFS{prod_id2}=="LSE041", RUN+="/etc/pcmcia/bluetooth.sh" +# "LSE039 Bluetooth Compact Flash Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="WSS", SYSFS{prod_id2}=="LSE039", RUN+="/etc/pcmcia/bluetooth.sh" +# "LSE139 Bluetooth Compact Flash Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="BTCFCARD", SYSFS{prod_id2}=="LSE139", RUN+="/etc/pcmcia/bluetooth.sh" + + +# +# bt950_cs +# + +# "AmbiCom BT2000E Bluetooth Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="AmbiCom,Inc", SYSFS{prod_id2}=="BT2000E", RUN+="/etc/pcmcia/bluetooth.sh" +# "Pretec BT2000E Bluetooth Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Pretec", SYSFS{prod_id2}=="BT2000E", RUN+="/etc/pcmcia/bluetooth.sh" +# "Billionton Bluetooth Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="Compact Flash", SYSFS{prod_id2}=="Bluetooth Card", RUN+="/etc/pcmcia/bluetooth.sh" + + +# +# btuart_cs +# + +# "Cyber-blue Compact Flash Card" +SUBSYSTEM=="tty", ENV{PHYSDEVBUS}=="pcmcia", SYSFS{prod_id1}=="BT", SYSFS{prod_id2}=="", SYSFS{prod_id3}=="", SYSFS{prod_id4}=="", RUN+="/etc/pcmcia/bluetooth.sh" + + diff --git a/etc/udev/suse/80-pcmcia.rules b/etc/udev/suse/50-pcmcia.rules similarity index 73% rename from etc/udev/suse/80-pcmcia.rules rename to etc/udev/suse/50-pcmcia.rules index cae7a7606c..11ccde56e7 100644 --- a/etc/udev/suse/80-pcmcia.rules +++ b/etc/udev/suse/50-pcmcia.rules @@ -1,7 +1,5 @@ -ENV{SYSCONFIG}=="no|off|0", GOTO="pcmcia_end" - SUBSYSTEM=="pcmcia_socket", ACTION=="add", RUN+="/sbin/hwup pcmcia_socket-devpath-%p -o hotplug" SUBSYSTEM=="pcmcia", ACTION=="add", RUN+="/sbin/hwup pcmcia-devpath-%p -o hotplug" -LABEL="pcmcia_end" +LABEL="after_pcmcia" diff --git a/etc/udev/suse/50-udev.rules b/etc/udev/suse/50-udev.rules index f24d77d197..768fdf0acb 100644 --- a/etc/udev/suse/50-udev.rules +++ b/etc/udev/suse/50-udev.rules @@ -1,3 +1,7 @@ +# ignore these events until someone needs them +SUBSYSTEM=="drivers", OPTIONS="last_rule" +SUBSYSTEM=="module", OPTIONS="last_rule" + # console KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" @@ -5,8 +9,8 @@ KERNEL=="vcs*", NAME="%k", GROUP="tty", MODE="620", OPTIONS="last_rule" KERNEL=="vcsa*", NAME="%k", GROUP="tty", MODE="620", OPTIONS="last_rule" KERNEL=="tty", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" KERNEL=="tty[0-9]*", NAME="%k", GROUP="tty", MODE="620", OPTIONS="last_rule" -KERNEL=="console", NAME="%k", MODE="600" -KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="666" +KERNEL=="console", NAME="%k", MODE="600", OPTIONS="last_rule" +KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" # serial devices KERNEL=="tty[A-Z]*", NAME="%k", GROUP="uucp" @@ -35,23 +39,6 @@ KERNEL=="pmu", GROUP="video" # dvb SUBSYSTEM="dvb", PROGRAM="/bin/sh -c 'X=%k; X=$${X#dvb}; A=$${X%%%%.*}; D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" -# ALSA/sound -SUBSYSTEM="sound", GROUP="audio" -SUBSYSTEM="snd", GROUP="audio" -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" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8000/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us428fw.ihx" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8004/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us224fw.ihx" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8006/*", RUN+="/sbin/fxload -s /usr/share/alsa/firmware/usx2yloader/tascam_loader.ihx -I /usr/share/alsa/firmware/usx2yloader/us122fw.ihx" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8001/*", RUN+="/sbin/startproc /usr/bin/us428control" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="1604/8005/*", RUN+="/sbin/startproc /usr/bin/us428control" -SUBSYSTEM=="sound", KERNEL=="controlC?", RUN+="/usr/sbin/alsactl -F restore %n" -SUBSYSTEM=="sound", KERNEL=="hwC?D2", DRIVER=="EMU10K1_Audigy", RUN+="/etc/alsa.d/udev-soundfont" - # Kino jogshuttle support SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="b33/10/*", RUN+="/usr/bin/killall --quiet -USR2 kino" SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="5f3/240/*", RUN+="/usr/bin/killall --quiet -USR2 kino" @@ -64,12 +51,12 @@ KERNEL=="js*", NAME="input/%k", MODE="0644" KERNEL=="ts*", NAME="input/%k", MODE="0600" KERNEL=="uinput", NAME="input/%k", MODE="0600" KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" -SUBSYSTEM=="input[0-9]*", RUN+="/lib/udev/input_device.sh" -KERNEL=="input[0-9]*", ACTION=="add", ENV{ABS}=="[1-9]*", RUN+="/sbin/modprobe joydev" +KERNEL=="input[0-9]*", RUN+="/lib/udev/input_device.sh" +KERNEL=="input[0-9]*", ACTION=="add", ENV{ABS}=="[1-9]*", RUN+="/sbin/modprobe joydev" # printer -SUBSYSTEM=="usb", KERNEL=="lp*", ACTION=="add", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" -SUBSYSTEM=="printer", KERNEL=="lp*", ACTION=="add", NAME="%k", GROUP="lp" +SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" +SUBSYSTEM=="printer", KERNEL=="lp*", NAME="%k", GROUP="lp" KERNEL=="irlpt*", NAME="%k", GROUP="lp" # cpu devices @@ -117,32 +104,25 @@ KERNEL=="z90crypt", NAME="%k", MODE="666" KERNEL=="mmtimer", NAME="%k", MODE="444" KERNEL=="auer[0-9]*" NAME="usb/%k" -KERNEL=="pktcdvd", NAME="pktcdvd/control" -KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%k" +KERNEL=="pktcdvd", NAME="pktcdvd/control" +KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%k" # fix floppy devices -KERNEL=="nvram", ACTION=="add", RUN+="/sbin/load_floppy_module.sh" -KERNEL=="fd*", ACTION=="add", SYSFS{device/cmos}=="*", RUN+="/sbin/create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" -KERNEL=="fd*", ACTION=="remove", RUN+="/sbin/remove_floppy_devices.sh %k" +KERNEL=="nvram", ACTION=="add", RUN+="/lib/udev/load_floppy_module.sh" +KERNEL=="fd*", ACTION=="add", SYSFS{device/cmos}=="*", RUN+="/lib/udev/create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" +KERNEL=="fd*", ACTION=="remove", RUN+="/lib/udev/remove_floppy_devices.sh %k" # block devices SUBSYSTEM=="block", GROUP="disk", MODE="0640" -# SCSI types: -# sd / block values: -# 0 TYPE_DISK -# 7 TYPE_MOD -# 14 TYPE_RBC -# -# st/osst tape: -# 1 TYPE_TAPE -# -# sr cd like ones: -# 4 TYPE_WORM -# 5 TYPE_ROM +# sd: 0 TYPE_DISK, 7 TYPE_MOD, 14 TYPE_RBC +# sr: 4 TYPE_WORM, 5 TYPE_ROM +# st/osst: 1 TYPE_TAPE +ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="0|7|14", RUN+="/bin/sh -c 'echo 60 > /sys/$DEVPATH/timeout'" +ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="1", RUN+="/bin/sh -c 'echo 900 > /sys/$DEVPATH/timeout'" SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0|7|14", RUN+="/sbin/modprobe sd_mod" # Treat osst as a unique case, that is, osst will load more often than -SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", SYSFS{device/vendor}=="Onstream", RUN+="/sbin/modprobe osst" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", SYSFS{device/vendor}=="OnStream", 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" @@ -150,9 +130,8 @@ SUBSYSTEM=="scsi_device", ACTION=="add", RUN+="/sbin/modprobe sg" # IDE/ATAPI handling SUBSYSTEM=="ide", ACTION=="add", RUN+="/lib/udev/load_ide_modules.sh" -# device mapper targets +# device mapper KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" -KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/dmsetup info -c --noheadings -o name -j %M -m %m", SYMLINK="disk/by-name/%c" # check fstab and possibly mount SUBSYSTEM=="block", KERNEL=="sd*[0-9]|hd*[0-9]", ACTION=="add", RUN+="/lib/udev/mount.sh" @@ -181,8 +160,7 @@ KERNEL=="iseries/vt*", NAME="%k", GROUP="disk" KERNEL=="iseries/nvt*", NAME="%k", GROUP="disk" KERNEL=="iseries/ibmsis*", NAME="%k", GROUP="disk" -# libusb device access (mount usbfs or create usbdev nodes) -DEVPATH=="/module/usbcore", ACTION=="add", RUN+="/bin/mount -t usbfs usbfs /proc/bus/usb" +# libusb device access 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 diff --git a/etc/udev/suse/60-persistent.rules b/etc/udev/suse/60-persistent.rules index 589fb0f88a..0d24a29338 100644 --- a/etc/udev/suse/60-persistent.rules +++ b/etc/udev/suse/60-persistent.rules @@ -43,4 +43,6 @@ KERNEL=="*[!0-9]", IMPORT{program}="/sbin/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" +KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/dmsetup info -c --noheadings -o name -j %M -m %m", SYMLINK="disk/by-name/%c" + LABEL="persistent_end" diff --git a/etc/udev/suse/80-sysconfig.rules b/etc/udev/suse/80-sysconfig.rules index 630c0eedfb..d33d975b36 100644 --- a/etc/udev/suse/80-sysconfig.rules +++ b/etc/udev/suse/80-sysconfig.rules @@ -7,14 +7,14 @@ SUBSYSTEM=="net", ACTION=="remove", RUN+="/sbin/ifdown %k -o hotplug" # SUSE system integration SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" -SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-/sys%p -o hotplug" -SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-/sys%p -o hotplug" -SUBSYSTEM=="scsi", DEVPATH=="/devices/css*", ACTION=="remove", RUN+="/sbin/hwdown scsi-devpath-/sys%p -o hotplug" -SUBSYSTEM=="scsi_host", ACTION=="add", SYSFS{device/cutype}=="*", RUN+="/sbin/hwup scsi__host-devpath-/sys%p -o hotplug" +SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-%p -o hotplug" +SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-%p -o hotplug" +SUBSYSTEM=="scsi", DEVPATH=="/devices/css*", ACTION=="remove", RUN+="/sbin/hwdown scsi-devpath-%p -o hotplug" +SUBSYSTEM=="scsi_host", ACTION=="add", SYSFS{device/cutype}=="?*", RUN+="/sbin/hwup scsi__host-devpath-%p -o hotplug" SUBSYSTEM=="vio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" SUBSYSTEM=="macio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" -SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-/sys%p -o hotplug" -SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-/sys%p -o hotplug" -SUBSYSTEM=="pnp", RUN+="/bin/sh -c 'while read id; do /sbin/modprobe pnp:d$$id; done < /sys$devpath/id'" +SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-%p -o hotplug" +SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-%p -o hotplug" +SUBSYSTEM=="pnp", ACTION=="add", RUN+="/sbin/hwup pnp-devpath-%p -o hotplug" LABEL="sysconfig_end" diff --git a/etc/udev/suse/90-hal.rules b/etc/udev/suse/90-hal.rules index 35b81ea046..9b2fe79ea5 100644 --- a/etc/udev/suse/90-hal.rules +++ b/etc/udev/suse/90-hal.rules @@ -1,3 +1,3 @@ # send all events to HAL -RUN+="/usr/sbin/hal.hotplug" +RUN+="socket:/org/freedesktop/hal/udev_event" From 6acd81c8981a5f0ea80e3cdef2a10e5d595bbae3 Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Fri, 25 Nov 2005 19:35:26 +0100 Subject: [PATCH 1638/4284] update Debian rules --- etc/udev/debian/devfs.rules | 20 ++++++++---------- etc/udev/debian/hotplug.rules | 35 ++++++++++++++++--------------- etc/udev/debian/hotplugd.rules | 4 ++-- etc/udev/debian/permissions.rules | 18 ++++++++++++---- etc/udev/debian/udev.rules | 13 ++++++------ 5 files changed, 49 insertions(+), 41 deletions(-) diff --git a/etc/udev/debian/devfs.rules b/etc/udev/debian/devfs.rules index b1696c7d24..c4a44e3e7f 100644 --- a/etc/udev/debian/devfs.rules +++ b/etc/udev/debian/devfs.rules @@ -15,20 +15,18 @@ # workaround for devices which do not report media changes BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ - PROGRAM="/sbin/ata_id --export $tempnode", ENV{ID_MODEL}=="IOMEGA_ZIP*", \ - NAME="%k", OPTIONS+="all_partitions" + ENV{ID_MODEL}=="IOMEGA_ZIP*", NAME="%k", OPTIONS+="all_partitions" # IDE devices -BUS=="ide", KERNEL=="hd[a-z]*", \ - PROGRAM="/etc/udev/scripts/ide-devfs.sh %k %b %n", \ +BUS=="ide", KERNEL=="hd[a-z]*", PROGRAM="/lib/udev/ide-devfs.sh %k %b %n", \ NAME="%c{1}", SYMLINK+="%k %c{2}" # SCSI devices -BUS=="scsi", PROGRAM="/etc/udev/scripts/scsi-devfs.sh %k %b %n", \ +BUS=="scsi", PROGRAM="/lib/udev/scsi-devfs.sh %k %b %n", \ NAME="%c{1}", SYMLINK+="%k %c{2}" # RAID controllers -KERNEL=="cciss!*|ida!*|rd!*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", \ +KERNEL=="cciss!*|ida!*|rd!*", PROGRAM="/lib/udev/raid-devfs.sh %k", \ NAME="%c{1}", SYMLINK+="%k" # other block devices @@ -47,8 +45,8 @@ BUS=="usb", KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", \ SYMLINK+="pilot" # usbfs-like devices -SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k K=$${K#usbdev} B=$${K%%%%.*} D=$${K#*.}; echo bus/usb/$$B/$$D'", \ - SYMLINK+="%c" +SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; B=$${K%%%%.*}; D=$${K#*.}; echo bus/usb/$$B/$$D'", \ + NAME="%c" # serial devices KERNEL=="ttyS[0-9]*", NAME="tts/%n" @@ -69,7 +67,7 @@ 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 'KNAME=%k KNAME=$${KNAME#dvb} A=$${KNAME%%%%.*} D=$${KNAME#*.}; echo dvb/adapter$$A/$$D'", \ +KERNEL=="dvb*", PROGRAM="/bin/sh -c 'KNAME=%k; KNAME=$${KNAME#dvb}; A=$${KNAME%%%%.*}; D=$${KNAME#*.}; echo dvb/adapter$$A/$$D'", \ NAME="%c" KERNEL=="fb[0-9]*", NAME="fb/%n" KERNEL=="card[0-9]*", NAME="dri/%k" @@ -101,7 +99,7 @@ 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" +KERNEL=="ucm*", NAME="infiniband/%k" # sound devices KERNEL=="controlC[0-9]*", NAME="snd/%k" @@ -145,6 +143,6 @@ SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k" SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k" # device mapper creates its own device nodes, so ignore these -KERNEL=="dm-[0-9]*", OPTIONS+="ignore_device" +KERNEL=="dm-[0-9]*", NAME="" KERNEL=="device-mapper", NAME="mapper/control" diff --git a/etc/udev/debian/hotplug.rules b/etc/udev/debian/hotplug.rules index 84f8c32156..f4c99ec8eb 100644 --- a/etc/udev/debian/hotplug.rules +++ b/etc/udev/debian/hotplug.rules @@ -1,18 +1,23 @@ ACTION!="add", GOTO="hotplug_not_add_event" # check if the device has already been claimed by a driver -PROGRAM="/bin/sh -c 'test -e /sys$devpath/driver'", \ - GOTO="hotplug_driver_loaded" +ENV{PHYSDEVDRIVER}=="?*", GOTO="hotplug_driver_loaded" # workarounds for kernels which lack $MODALIAS support -SUBSYSTEM=="input", BUS=="serio", ENV{MODALIAS}!="?*", \ - IMPORT{program}="/lib/hotplug/modalias_serio" -SUBSYSTEM=="ieee1394", ENV{MODALIAS}!="?*", \ - IMPORT{program}="/lib/hotplug/modalias_ieee1394" +SUBSYSTEM=="ieee1394", ENV{MODALIAS}!="?*", \ + IMPORT{program}="/lib/udev/modalias_ieee1394" +SUBSYSTEM=="serio", ENV{MODALIAS}!="?*", \ + IMPORT{program}="/lib/udev/modalias_serio" # load the drivers -ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $modalias" -SUBSYSTEM=="pnp", ENV{MODALIAS}!="?*", RUN+="/bin/sh -c 'while read id; do /sbin/modprobe pnp:d$$id; done < /sys$devpath/id'" +ENV{MODALIAS}=="?*", RUN+="/sbin/modprobe $env{MODALIAS}" +SUBSYSTEM=="ide", ENV{MODALIAS}!="?*", RUN+="/lib/udev/ide.agent" +#SUBSYSTEM=="input", ENV{MODALIAS}!="?*", RUN+="/lib/udev/input.agent" +SUBSYSTEM=="vio", ENV{MODALIAS}!="?*", RUN+="/lib/udev/vio.agent" + +SUBSYSTEM=="pnp", ENV{MODALIAS}!="?*", RUN+="/bin/sh -c 'while read id; do /sbin/modprobe pnp:d$$id; done < /sys$devpath/id'" + +SUBSYSTEM=="pcmcia_socket", RUN+="/sbin/modprobe pcmcia" SUBSYSTEM=="scsi_device", SYSFS{type}=="0|7|14", RUN+="/sbin/modprobe sd_mod" SUBSYSTEM=="scsi_device", SYSFS{type}=="1", RUN+="/sbin/modprobe osst", \ @@ -24,23 +29,19 @@ SUBSYSTEM=="scsi_device", SYSFS{type}=="1", RUN+="/sbin/modprobe st", \ SUBSYSTEM=="scsi_device", SYSFS{type}=="[345]", RUN+="/sbin/modprobe sr_mod" SUBSYSTEM=="scsi_device", SYSFS{type}=="[235689]", RUN+="/sbin/modprobe sg" -SUBSYSTEM=="input_device", ENV{ABS}=="?*", RUN+="/sbin/modprobe joydev" - -SUBSYSTEM=="ide", RUN+="/lib/hotplug/ide.agent" - # 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", SYSFS{idVendor}=="...", \ -# RUN+="/lib/hotplug/scsi-re-add" +# RUN+="/lib/udev/scsi-re-add" -SUBSYSTEM=="firmware", RUN+="/lib/hotplug/firmware.agent" +SUBSYSTEM=="firmware", RUN+="/lib/udev/firmware.agent" LABEL="hotplug_not_add_event" -SUBSYSTEM=="net", RUN+="/lib/hotplug/net.agent" +SUBSYSTEM=="net", RUN+="/bin/sh -c '/lib/udev/net.agent &'" -# for debugging -#RUN+="/lib/hotplug/logger.agent" +# Log every event to /dev/hotplug.log (for debugging). +#RUN+="/lib/udev/logger.agent" diff --git a/etc/udev/debian/hotplugd.rules b/etc/udev/debian/hotplugd.rules index 7b85e179e8..d79ce85e52 100644 --- a/etc/udev/debian/hotplugd.rules +++ b/etc/udev/debian/hotplugd.rules @@ -4,6 +4,6 @@ SUBSYSTEM=="module", OPTIONS="last_rule" # compatibility support for the obsolete hotplug.d and dev.d directories # do not run the hotplug.d scripts when started from udevstart -ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" -RUN+="/sbin/udev_run_devd" +ENV{UDEVD_EVENT}=="1", RUN+="/lib/udev/udev_run_hotplugd" +RUN+="/lib/udev/udev_run_devd" diff --git a/etc/udev/debian/permissions.rules b/etc/udev/debian/permissions.rules index 02bfefdd27..bc97566b57 100644 --- a/etc/udev/debian/permissions.rules +++ b/etc/udev/debian/permissions.rules @@ -1,7 +1,10 @@ +# workaround needed to make udevd wait for the "bus" link +ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", \ + WAIT_FOR_SYSFS="bus" + # default permissions for block devices SUBSYSTEM=="block", GROUP="disk" SUBSYSTEM=="block", SYSFS{removable}=="1", GROUP="floppy" -SUBSYSTEM=="block", SYSFS{../removable}=="1", GROUP="floppy" # IDE devices BUS=="ide", KERNEL=="hd[a-z]|pcd[0-9]*", ACTION=="add", \ @@ -19,6 +22,9 @@ BUS=="scsi", SYSFS{type}=="6", GROUP="scanner" BUS=="usb", KERNEL=="legousbtower*", MODE="0666" BUS=="usb", KERNEL=="lp[0-9]*", GROUP="lp" +# usbfs-like devices +SUBSYSTEM=="usb_device", MODE="0664" + # serial devices SUBSYSTEM=="tty", GROUP="dialout" SUBSYSTEM=="capi", GROUP="dialout" @@ -41,7 +47,7 @@ SUBSYSTEM=="nvidia", GROUP="video" # misc devices KERNEL=="random", MODE="0666" -KERNEL=="urandom", MODE="0444" +KERNEL=="urandom", MODE="0666" KERNEL=="mem", MODE="0640", GROUP="kmem" KERNEL=="kmem", MODE="0640", GROUP="kmem" KERNEL=="port", MODE="0640", GROUP="kmem" @@ -53,13 +59,17 @@ KERNEL=="sgi_fetchop", MODE="0666" KERNEL=="sonypi", MODE="0666" KERNEL=="agpgart", GROUP="video" KERNEL=="nvram", GROUP="nvram" -KERNEL=="rtc", MODE="0660", GROUP="audio" +KERNEL=="rtc", GROUP="audio" KERNEL=="tpm*", MODE="0600", OWNER="tss", GROUP="tss" +KERNEL=="fuse", GROUP="fuse" 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" @@ -75,7 +85,7 @@ KERNEL=="dv1394*", GROUP="video" KERNEL=="video1394*", GROUP="video" # input devices -KERNEL=="event[0-9]*", PROGRAM="/etc/udev/scripts/inputdev.sh %k", \ +KERNEL=="event[0-9]*", PROGRAM="/lib/udev/inputdev.sh %k", \ RESULT=="inputdev", MODE="0664", GROUP="video" KERNEL=="js[0-9]*", MODE="0664" diff --git a/etc/udev/debian/udev.rules b/etc/udev/debian/udev.rules index 27eb43e54c..b5dfd00572 100644 --- a/etc/udev/debian/udev.rules +++ b/etc/udev/debian/udev.rules @@ -15,8 +15,7 @@ # workaround for devices which do not report media changes BUS=="ide", KERNEL=="hd[a-z]", SYSFS{removable}=="1", \ - PROGRAM="/sbin/ata_id --export $tempnode", ENV{ID_MODEL}=="IOMEGA_ZIP*", \ - NAME="%k", OPTIONS+="all_partitions" + ENV{ID_MODEL}=="IOMEGA_ZIP*", NAME="%k", OPTIONS+="all_partitions" # SCSI devices BUS=="scsi", KERNEL=="sr[0-9]*", NAME="scd%n", SYMLINK+="sr%n" @@ -32,15 +31,15 @@ BUS=="usb", KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", \ SYMLINK+="pilot" # usbfs-like devices -SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k K=$${K#usbdev} B=$${K%%%%.*} D=$${K#*.}; echo bus/usb/$$B/$$D'", \ - SYMLINK+="%c" +SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; B=$${K%%%%.*}; D=$${K#*.}; echo bus/usb/$$B/$$D'", \ + 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} A=$${K%%%%.*} D=$${K#*.}; echo dvb/adapter$$A/$$D'", \ +KERNEL=="dvb*", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; A=$${K%%%%.*}; D=$${K#*.}; echo dvb/adapter$$A/$$D'", \ NAME="%c" KERNEL=="card[0-9]*", NAME="dri/%k" @@ -59,7 +58,7 @@ 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" +KERNEL=="ucm*", NAME="infiniband/%k" # ALSA devices KERNEL=="controlC[0-9]*", NAME="snd/%k" @@ -94,6 +93,6 @@ SUBSYSTEM=="aoe", KERNEL=="err", NAME="etherd/%k" SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k" # device mapper creates its own device nodes, so ignore these -KERNEL=="dm-[0-9]*", OPTIONS+="ignore_device" +KERNEL=="dm-[0-9]*", NAME="" KERNEL=="device-mapper", NAME="mapper/control" From aab4c0eebef44c5b67d4c9537f1c5149de3ca9c2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 3 Dec 2005 18:55:51 +0100 Subject: [PATCH 1639/4284] allow programs in /lib/udev called without the path RUN="firmware.sh" should work like RUN="/lib/udev/firmware.sh" Signed-off-by: Kay Sievers --- udev_utils_run.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/udev_utils_run.c b/udev_utils_run.c index 20aaa4ab05..e1e775ebe6 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -82,6 +82,7 @@ int run_program(const char *command, const char *subsystem, 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; @@ -126,6 +127,13 @@ int run_program(const char *command, const char *subsystem, } } + /* 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: From a2f87fddbfcb81f6f8f254b1a986a18f444212cf Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 4 Dec 2005 01:48:53 +0100 Subject: [PATCH 1640/4284] update SUSE rules Signed-off-by: Kay Sievers --- Makefile | 1 - etc/udev/suse/50-udev.rules | 14 ++++++-------- etc/udev/suse/90-hal.rules | 2 -- udevd.c | 4 ++-- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/Makefile b/Makefile index 48a130491e..5995b57697 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,6 @@ GEN_CONFIGS = \ GEN_HEADERS = \ udev_version.h -# override this to make udev look in a different location for it's config files prefix = etcdir = ${prefix}/etc sbindir = ${prefix}/sbin diff --git a/etc/udev/suse/50-udev.rules b/etc/udev/suse/50-udev.rules index 768fdf0acb..51561ffd0f 100644 --- a/etc/udev/suse/50-udev.rules +++ b/etc/udev/suse/50-udev.rules @@ -37,7 +37,7 @@ KERNEL=="vbi0", SYMLINK+="vbi" KERNEL=="pmu", GROUP="video" # dvb -SUBSYSTEM="dvb", PROGRAM="/bin/sh -c 'X=%k; X=$${X#dvb}; A=$${X%%%%.*}; D=$${X#*.}; echo dvb/adapter$$A/$$D'", NAME="%c", GROUP="video" +SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%i $${K%%%%.*} $${K#*.}'", NAME="%c", GROUP="video" # Kino jogshuttle support SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="b33/10/*", RUN+="/usr/bin/killall --quiet -USR2 kino" @@ -51,8 +51,7 @@ KERNEL=="js*", NAME="input/%k", MODE="0644" KERNEL=="ts*", NAME="input/%k", MODE="0600" KERNEL=="uinput", NAME="input/%k", MODE="0600" KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" -KERNEL=="input[0-9]*", RUN+="/lib/udev/input_device.sh" -KERNEL=="input[0-9]*", ACTION=="add", ENV{ABS}=="[1-9]*", RUN+="/sbin/modprobe joydev" +KERNEL=="input[0-9]*", ACTION=="add", RUN+="/lib/udev/input.sh" # printer SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" @@ -121,14 +120,13 @@ SUBSYSTEM=="block", GROUP="disk", MODE="0640" ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="0|7|14", RUN+="/bin/sh -c 'echo 60 > /sys/$DEVPATH/timeout'" ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="1", RUN+="/bin/sh -c 'echo 900 > /sys/$DEVPATH/timeout'" SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="0|7|14", RUN+="/sbin/modprobe sd_mod" -# Treat osst as a unique case, that is, osst will load more often than -SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", SYSFS{device/vendor}=="OnStream", RUN+="/sbin/modprobe osst" +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" -# IDE/ATAPI handling -SUBSYSTEM=="ide", ACTION=="add", RUN+="/lib/udev/load_ide_modules.sh" +# IDE modules +SUBSYSTEM=="ide", ACTION=="add", RUN+="/lib/udev/ide.sh" # device mapper KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" @@ -161,7 +159,7 @@ KERNEL=="iseries/nvt*", NAME="%k", GROUP="disk" KERNEL=="iseries/ibmsis*", NAME="%k", GROUP="disk" # libusb device access -SUBSYSTEM="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev}; B=$${X%%%%.*}; D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c" +SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", NAME="%c", MODE="0644" # firmware loader SUBSYSTEM=="firmware", ACTION=="add", RUN+="/lib/udev/firmware.sh" diff --git a/etc/udev/suse/90-hal.rules b/etc/udev/suse/90-hal.rules index 9b2fe79ea5..b0b36330df 100644 --- a/etc/udev/suse/90-hal.rules +++ b/etc/udev/suse/90-hal.rules @@ -1,3 +1 @@ -# send all events to HAL - RUN+="socket:/org/freedesktop/hal/udev_event" diff --git a/udevd.c b/udevd.c index b87fe56413..ff61c656c8 100644 --- a/udevd.c +++ b/udevd.c @@ -551,7 +551,7 @@ static struct uevent_msg *get_udevd_msg(void) size = recvmsg(udevd_sock, &smsg, 0); if (size < 0) { if (errno != EINTR) - err("unable to receive udevd message: %s", strerror(errno)); + err("unable to receive user udevd message: %s", strerror(errno)); return NULL; } cmsg = CMSG_FIRSTHDR(&smsg); @@ -626,7 +626,7 @@ static struct uevent_msg *get_netlink_msg(void) size = recv(uevent_netlink_sock, &buffer, sizeof(buffer), 0); if (size < 0) { if (errno != EINTR) - err("unable to receive udevd message: %s", strerror(errno)); + err("unable to receive kernel netlink message: %s", strerror(errno)); return NULL; } From ed0e3cbd6dfe49c2cceb26eb65466dd5905b1c5b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 4 Dec 2005 02:31:38 +0100 Subject: [PATCH 1641/4284] add target to to generate ChangeLog section I can't remember that magic sequence... Signed-off-by: Kay Sievers --- ChangeLog | 14 -------------- Makefile | 12 +++++++++++- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 52a88a976a..795de89707 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,17 +1,3 @@ -Summary of changes from v76 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 - -Marco d'Itri: - allow to overwrite the configured udev_root by exporting UDEV_ROOT - let udevsend ignore events with SEQNUM set - - Summary of changes from v75 to v076 ============================================ diff --git a/Makefile b/Makefile index 5995b57697..d4ee3eb6be 100644 --- a/Makefile +++ b/Makefile @@ -377,9 +377,19 @@ test tests: all .PHONY: test tests buildtest: - ./test/simple-build-check.sh + test/simple-build-check.sh .PHONY: buildtest +ChangeLog: Makefile + @ mv $@ $@.tmp + @ echo "Summary of changes from v$(VERSION) to v$(shell printf '%03i' $$(expr $(VERSION) + 1))" >> $@ + @ echo "============================================" >> $@ + @ git log --pretty=short $(VERSION)..HEAD | git shortlog >> $@ + @ echo >> $@ + @ cat $@ + @ cat $@.tmp >> $@ + @ rm $@.tmp + gcov-all: $(MAKE) clean all STRIPCMD= USE_GCOV=true @echo From 4d1f4aa957277808a79d04216cf6e3db00035204 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 4 Dec 2005 02:52:57 +0100 Subject: [PATCH 1642/4284] update Red Hat rules --- etc/udev/redhat/hotplug.rules | 8 +++ etc/udev/redhat/udev.rules | 129 +++++++++++++++++++--------------- 2 files changed, 79 insertions(+), 58 deletions(-) create mode 100644 etc/udev/redhat/hotplug.rules diff --git a/etc/udev/redhat/hotplug.rules b/etc/udev/redhat/hotplug.rules new file mode 100644 index 0000000000..1f4369c36b --- /dev/null +++ b/etc/udev/redhat/hotplug.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 +ENV{UDEVD_EVENT}=="1", RUN+="/lib/udev/udev_run_hotplugd" +RUN+="/lib/udev/udev_run_devd" + diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index 115abc3ae4..ba10fd5501 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -11,6 +11,7 @@ KERNEL=="root", GROUP="disk", MODE="0640" # console devices KERNEL=="tty", MODE="0666", OPTIONS="last_rule" +KERNEL=="console", MODE="0600", OPTIONS="last_rule" KERNEL=="tty[0-9]", GROUP="tty", MODE="0660", OPTIONS="last_rule" KERNEL=="tty[0-9][0-9]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" KERNEL=="vc/[0-9]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" @@ -38,21 +39,21 @@ KERNEL=="tts/[0-9]*", GROUP="uucp", MODE="0660" KERNEL=="tts/USB[0-9]*", GROUP="uucp", MODE="0660" # vc devices -KERNEL=="vcs", OWNER="vcsa", GROUP="tty" -KERNEL=="vcs[0-9]*", OWNER="vcsa", GROUP="tty" -KERNEL=="vcsa", OWNER="vcsa", GROUP="tty" -KERNEL=="vcsa[0-9]*", OWNER="vcsa", GROUP="tty" -KERNEL=="vcc/*", OWNER="vcsa", GROUP="tty" +KERNEL=="vcs", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcs[0-9]*", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcsa", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcsa[0-9]*", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcc/*", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" # 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" +KERNEL=="random", MODE="0666", OPTIONS="last_rule" +KERNEL=="urandom", MODE="0444", OPTIONS="last_rule" +KERNEL=="mem", GROUP="kmem", MODE="0640", OPTIONS="last_rule" +KERNEL=="kmem", GROUP="kmem", MODE="0640", OPTIONS="last_rule" +KERNEL=="port", GROUP="kmem", MODE="0640", OPTIONS="last_rule" +KERNEL=="full", MODE="0666", OPTIONS="last_rule" +KERNEL=="null", MODE="0666", OPTIONS="last_rule" +KERNEL=="zero", MODE="0666", OPTIONS="last_rule" # misc devices KERNEL=="nvram", MODE="0660" @@ -133,9 +134,9 @@ KERNEL=="3dfx*", MODE="0660" KERNEL=="dri/*", MODE="0666" # usb devices -KERNEL=="usb/dabusb*", GROUP="usb", MODE="0660" -KERNEL=="usb/mdc800*", GROUP="usb", MODE="0660" -KERNEL=="usb/rio500", GROUP="usb", MODE="0660" +KERNEL=="usb/dabusb*", MODE="0660" +KERNEL=="usb/mdc800*", MODE="0660" +KERNEL=="usb/rio500", MODE="0660" # s390 devices KERNEL=="z90crypt", MODE="0666" @@ -164,9 +165,14 @@ KERNEL=="seq", NAME="snd/%k" KERNEL=="mice", NAME="input/%k" KERNEL=="mouse*", NAME="input/%k" KERNEL=="event*", NAME="input/%k" -KERNEL=="js*", NAME="input/%k" +KERNEL=="js*", NAME="input/%k", SYMLINK+="%k" KERNEL=="ts*", 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=="raw[0-9]*", NAME="raw/%k" KERNEL=="lp[0-9]*", SYMLINK+="par%n" @@ -174,7 +180,7 @@ 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/cpu" +KERNEL="cpu[0-9]*", NAME="cpu/%n/cpuid" KERNEL=="ram1", SYMLINK+="ram" KERNEL=="video0", SYMLINK+="video" @@ -218,73 +224,80 @@ KERNEL=="zap[0-9]*", NAME="zap/%n" BUS=="scsi", KERNEL=="sg[0-9]*", SYSFS{type}=="6", NAME="%k", SYMLINK="scanner%e", MODE="0660" # do not seperate the next 2 lines!! -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/ide-media.sh %k", RESULT=="floppy", SYMLINK+="floppy%e", NAME{ignore_remove, all_partitions}="%k" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/lib/udev/ide-media.sh %k", RESULT=="floppy", SYMLINK+="floppy%e", NAME{ignore_remove, all_partitions}="%k" KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", RESULT=="cdrom", SYMLINK+="cdrom%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/lib/udev/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/lib/udev/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/lib/udev/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/lib/udev/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/etc/udev/scripts/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="/lib/udev/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/lib/udev/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" # rename sr* to scd* KERNEL=="sr[0-9]*", BUS=="scsi", NAME="scd%n" KERNEL=="hd[a-z]*", BUS=="ide", SYSFS{removable}=="1", NAME{ignore_remove}="%k" -KERNEL=="dvb*", PROGRAM=="/etc/udev/scripts/dvb.sh %k", NAME="%c" +KERNEL=="dvb*", PROGRAM=="/lib/udev/dvb.sh %k", NAME="%c" ####################################### -# Persistant block device stuff - begin +# Persistent block device stuff - begin ####################################### +# persistent disk links: /dev/disk/{by-id,by-uuid,by-label,by-path} +# scheme based on "Linux persistent device names", 2004, Hannes Reinecke -# Skip all of this if we are not adding a block device -ACTION!="add", GOTO="persistent_end" -SUBSYSTEM!="block", GOTO="persistent_end" +ACTION!="add", GOTO="persistent_end" +SUBSYSTEM!="block", GOTO="persistent_end" -# skip accessing removable ide devices, cause the ide drivers are horrible broken -BUS=="ide", SYSFS{removable}="1", GOTO="no_volume_id" -BUS=="ide", SYSFS{../removable}="1", GOTO="no_volume_id" +# skip rules for inappropriate block devices +KERNEL=="ram*|loop*|fd*|nbd*", GOTO="persistent_end" -# persistent disk device links /dev/disk/ -KERNEL=="hd*[!0-9]", IMPORT="/sbin/ata_id --export $tempnode" +# 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}="/sbin/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]", SYSFS{ieee1394_id}=="*", IMPORT="/bin/echo -e 'ID_SERIAL=$sysfs{ieee1394_id}\nID_BUS=ieee1394'" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/usb_id -x" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -s %p" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="", IMPORT="/sbin/scsi_id -g -x -a -s %p" -KERNEL=="sd*[!0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$env{ID_SERIAL}" -KERNEL=="sd*[0-9]", IMPORT{parent}=="ID_*" -KERNEL=="sd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{ID_BUS}-$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}="/sbin/usb_id -x" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -s %p -d $tempnode" +KERNEL=="sd*[!0-9]|sr*", ENV{ID_SERIAL}=="", IMPORT{program}="/sbin/scsi_id -g -x -a -s %p -d $tempnode" +KERNEL=="dasd*[!0-9]", IMPORT{program}="/sbin/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}" -# Skip id for ram / loop / fd -KERNEL=="ram*", GOTO="no_volume_id" -KERNEL=="loop*", GOTO="no_volume_id" -KERNEL=="fd*", GOTO="no_volume_id" +# 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" -KERNEL=="*[!0-9]", ENV{ID_TYPE}=="?*", IMPORT="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +# by-path (shortest physical path) +KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", IMPORT{program}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" +KERNEL=="sr*", GOTO="persistent_end" KERNEL=="*[0-9]", IMPORT{parent}=="ID_*" KERNEL=="*[0-9]", ENV{ID_PATH}=="?*", SYMLINK+="disk/by-path/$env{ID_PATH}-part%n" -# volume-label/uuid -KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="no_volume_id" -KERNEL=="sr*", GOTO="no_volume_id" -KERNEL=="*[0-9]", IMPORT="/sbin/vol_id --export $tempnode" -KERNEL=="*[0-9]", ENV{ID_FS_UUID}=="?*", SYMLINK+="disk/by-uuid/$env{ID_FS_UUID}" -KERNEL=="*[0-9]", ENV{ID_FS_LABEL_SAFE}=="?*", SYMLINK+="disk/by-label/$env{ID_FS_LABEL_SAFE}" -LABEL="no_volume_id" +# by-label/by-uuid (filesystem properties) +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_end" +IMPORT{program}="/sbin/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}="/sbin/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" LABEL="persistent_end" ##################################### -# Persistant block device stuff - end +# Persistent block device stuff - end ##################################### +ACTION=="add", SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev} B=$${X%%%%.*} D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c" # Perhaps this should just be for all subsystems? @@ -307,11 +320,11 @@ ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="14", \ RUN+="/sbin/modprobe sd_mod" ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[45]", \ RUN+="/sbin/modprobe sr_mod" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="Onstream", \ +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="On[sS]tream", \ SYSFS{model}!="ADR*", RUN+="/sbin/modprobe osst" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="Onstream", \ +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="On[sS]tream", \ SYSFS{model}=="ADR*", RUN+="/sbin/modprobe st" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}!="Onstream", \ +ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}!="On[sS]tream", \ RUN+="/sbin/modprobe st" ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[23689]", \ RUN+="/sbin/modprobe sg" From 731a7d6d75fa412d676fd536ea282f33296f64cb Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 4 Dec 2005 03:01:48 +0100 Subject: [PATCH 1643/4284] 077 release --- ChangeLog | 21 +++++++++++++++++++++ Makefile | 7 ++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 795de89707..e80def7759 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +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 ============================================ diff --git a/Makefile b/Makefile index d4ee3eb6be..cd789f82fd 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 076 +VERSION = 077 # set this to make use of syslog USE_LOG = true @@ -382,9 +382,10 @@ buildtest: ChangeLog: Makefile @ mv $@ $@.tmp - @ echo "Summary of changes from v$(VERSION) to v$(shell printf '%03i' $$(expr $(VERSION) + 1))" >> $@ + @ echo "Summary of changes from v$(shell printf '%03i' $$(expr $(VERSION) - 1)) to v$(VERSION)" >> $@ @ echo "============================================" >> $@ - @ git log --pretty=short $(VERSION)..HEAD | git shortlog >> $@ + @ echo >> $@ + @ git log --pretty=short $(shell printf '%03i' $$(expr $(VERSION) - 1))..HEAD | git shortlog >> $@ @ echo >> $@ @ cat $@ @ cat $@.tmp >> $@ From 65e63a710e0369781c3632dd3fc95e4c72f9ab40 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 6 Dec 2005 19:00:40 +0100 Subject: [PATCH 1644/4284] optimize SELinux path match --- udev_selinux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_selinux.c b/udev_selinux.c index 6ec359edd4..f014ea5535 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -152,6 +152,7 @@ void selinux_init(void) * restoration creation purposes. */ if (is_selinux_running()) { + matchpathcon_init_prefix(NULL, "/dev"); if (getfscreatecon(&prev_scontext) < 0) { err("getfscreatecon failed\n"); prev_scontext = NULL; From d992629180a4bbce84c28456057bf4e9c6bfce6e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 7 Dec 2005 20:40:38 +0100 Subject: [PATCH 1645/4284] update README Signed-off-by: Kay Sievers --- README | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/README b/README index 9e1aae3452..21a6c186dc 100644 --- a/README +++ b/README @@ -31,22 +31,21 @@ Operation: Udev creates and removes device nodes in /dev, based on events the kernel sends out on device discovery or removal. - - Directly after mouting the real root filesystem, wherever that - happens, in initramfs or with a directly mounted root, /dev should get - a tmpfs filesystem mounted, which is populated from scratch by udev. - Created nodes or changed permissions don't survive a reboot. + - Early in the boot process, /dev 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 + 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 udevd daemon must be started by an init script to receive netlink - events from the kernel driver core. + uevents from the kernel driver core. - From kernel version 2.6.15 on, the hotplug helper /sbin/hotplug should - be disabled with an init script before the boot scripts are run and - kernel modules are loaded. + be disabled with an init script before actions like loading kernel + modules are taken, which may cause a lot of events. - 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 @@ -56,12 +55,8 @@ Operation: Compile Options: - prefix - Set this to the default root that you want to use. Only override - this if you really know what you are doing, even then, you probably - don't do the right thing. DESTDIR - Prefix for install target, used for package building. + 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. @@ -95,7 +90,7 @@ Installation: - The default location for scripts and binaries that are called from rules is /lib/udev. Other packages who install udev rules, should use - that diretory too. + 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. From ca93c2c6c4daee82c45c15dd321a38357d26586e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 7 Dec 2005 13:59:32 -0800 Subject: [PATCH 1646/4284] Update Gentoo udev main rule file. --- etc/udev/gentoo/udev.rules | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 0c705f778d..6614c76394 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -36,6 +36,7 @@ SUBSYSTEM=="block", GROUP="disk" BUS=="ide", KERNEL=="hd[a-z]", ACTION=="add", IMPORT="/sbin/cdrom_id --export $tempnode" BUS=="scsi", KERNEL="sr[0-9]*", ACTION=="add", IMPORT="/sbin/cdrom_id --export $tempnode" BUS=="scsi", KERNEL="scd[a-z]", ACTION=="add", IMPORT="/sbin/cdrom_id --export $tempnode" +BUS=="scsi", KERNEL="sg[0-9]*", ACTION=="add", DRIVER=="sr", GROUP="cdrom" ENV{ID_CDROM}=="?*", SYMLINK+="cdrom%e", GROUP="cdrom" ENV{ID_CDROM_CD_RW}=="?*", SYMLINK+="cdrw%e" ENV{ID_CDROM_DVD}=="?*", SYMLINK+="dvd%e" @@ -47,11 +48,11 @@ KERNEL=="dasd*", NAME="%k", GROUP="disk" KERNEL=="ataraid*", NAME="%k", GROUP="disk" # compaq smart array -KERNEL=="cciss*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" -KERNEL=="ida*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" +KERNEL=="cciss*", PROGRAM="raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" +KERNEL=="ida*", PROGRAM="raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" # mylex -KERNEL=="rd*", PROGRAM="/etc/udev/scripts/raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" +KERNEL=="rd*", PROGRAM="raid-devfs.sh %k", NAME="%c{1}", SYMLINK+="%k" # dri devices KERNEL=="card*", NAME="dri/card%n", GROUP="video" @@ -177,12 +178,12 @@ BUS=="usb", KERNEL=="lp[0-9]*", 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", 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 -KERNEL=="dvb*", PROGRAM="/etc/udev/scripts/dvb.sh %k", NAME="%c", GROUP="video", MODE="0660" +SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%i $${K%%%%.*} $${K#*.}'", NAME="%c" # Asterisk Zaptel devices KERNEL=="zapctl", NAME="zap/ctl" @@ -293,7 +294,7 @@ LABEL="persistent_end" ##################################### # usbfs-like device nodes -SUBSYSTEM="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev} B=$${X%%%%.*} D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c" +SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", NAME="%c", MODE="0644" # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems From f3aef1a78eeb80f9234eb39d22965ad1f6e94b5d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 7 Dec 2005 14:00:05 -0800 Subject: [PATCH 1647/4284] add parisc support to path_id As reported at http://bugs.gentoo.org/show_bug.cgi?id=113379 path_id doesn't work too well for parisc boxes. This patch from Jeroen Roovers fixes that. Signed-off-by: Greg Kroah-Hartman --- extras/path_id | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/extras/path_id b/extras/path_id index 4ac718717a..dfb997b340 100755 --- a/extras/path_id +++ b/extras/path_id @@ -235,6 +235,11 @@ handle_block_scsi () { adapter="`echo $controller_dev | sed -e 's@/[^/]\{1,\}$@@;s@^.*/@@;s@^.*:@@'`" bus="gc" ;; + # PARISC devices + *parisc*) + adapter="${controler_dev##*/}" + bus=parisc; + ;; *) adapter="${controller_dev##*/}" bus="pci" From d313632b04e2277306af74738df0b4444bcad695 Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Thu, 15 Dec 2005 12:22:42 +0100 Subject: [PATCH 1648/4284] fold multiple consecutive whitespace chars into single '_' --- extras/scsi_id/scsi_id.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 39391f6e2e..aa1b16009e 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -677,13 +677,22 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, */ static void format_serial(char *serial) { - char *p = serial; + char *p = serial, *q; + q = p; while (*p != '\0') { - if (isspace(*p)) - *p = '_'; + if (isspace(*p)) { + if (q > serial && q[-1] != '_') { + *q = '_'; + q++; + } + } else { + *q = *p; + q++; + } p++; } + *q = '\0'; } /* From c756114f8e78f2b7d17ac9f5c3e6cd76e3648601 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Dec 2005 12:30:25 +0100 Subject: [PATCH 1649/4284] allow C99 statements Signed-off-by: Kay Sievers --- Makefile | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Makefile b/Makefile index cd789f82fd..774d5e154a 100644 --- a/Makefile +++ b/Makefile @@ -133,20 +133,15 @@ HOSTCC = gcc STRIP = $(CROSS)strip STRIPCMD = $(STRIP) -s -# check if compiler option is supported -cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi;} - 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 -WARNINGS += $(call cc-supports, -Wdeclaration-after-statement, ) CFLAGS += $(WARNINGS) LDFLAGS = -Wl,-warn-common -# use -Os optimization if available, else use -O2 -OPTFLAGS := $(call cc-supports, -Os, -O2) +OPTFLAGS = -Os CFLAGS += $(OPTFLAGS) # include our local copy of libsysfs From cbba4a544628b2f5d78cb15dadbc4e0f73f75eb3 Mon Sep 17 00:00:00 2001 From: Kurt Garloff Date: Thu, 15 Dec 2005 13:01:01 +0100 Subject: [PATCH 1650/4284] support pre-SPC3 page 83 format --- extras/scsi_id/scsi_serial.c | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index d1b1d94f53..14955e676c 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -558,6 +558,27 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev, return 0; } +/* Extract the raw binary from VPD 0x83 pre-SPC devices */ +static int check_fill_0x83_prespc3(struct sysfs_device *scsi_dev, + unsigned char *page_83, + const struct scsi_id_search_values + *id_search, char *serial, int max_len) +{ + int i, j; + + 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]; + } + dprintf("using pre-spc3-83 for %s.\n", scsi_dev->name); + return 0; +} + + /* Get device identification VPD page */ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, char *serial, int len) @@ -584,6 +605,33 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, * 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(scsi_dev, page_83, + id_search_list, serial, len); + /* * Search for a match in the prioritized id_search_list. */ From 89a8f4e75e68aea378163a3c56b16f76cee407e0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Dec 2005 15:56:50 +0100 Subject: [PATCH 1651/4284] fix segfaulting create_floppy_devices Signed-off-by: Kay Sievers --- extras/floppy/create_floppy_devices.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extras/floppy/create_floppy_devices.c b/extras/floppy/create_floppy_devices.c index b2906106d4..91d3a58195 100644 --- a/extras/floppy/create_floppy_devices.c +++ b/extras/floppy/create_floppy_devices.c @@ -31,9 +31,9 @@ static char *table[] = { NULL }; -static int t360[] = { 1 }; -static int t1200[] = { 2, 5, 6, 10, 12, 14, 16, 18, 20, 23 }; -static int t3in[] = { 8, 9, 26, 27, 28, 7, 11, 15, 19, 24, 25, 29, 31, 3, 4, 13, 17, 21, 22, 30 }; +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 }; @@ -112,7 +112,7 @@ int main(int argc, char **argv) i = 0; while (table_sup[type][i]) { - sprintf(node,"%s%s",dev,table[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); From 6317c213d0cffdf66faf644361877bf259aff756 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 15 Dec 2005 16:05:37 +0100 Subject: [PATCH 1652/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/05-udev-early.rules | 7 ++++ etc/udev/suse/10-wait-for-sysfs.rules | 1 - etc/udev/suse/40-bluetooth.rules | 2 +- .../{50-udev.rules => 50-udev-default.rules} | 32 ++++++++----------- ...sistent.rules => 60-persistent-disk.rules} | 2 +- etc/udev/suse/80-sysconfig.rules | 5 +-- .../{95-debug.rules => 95-udev-late.rules} | 2 +- 7 files changed, 27 insertions(+), 24 deletions(-) create mode 100644 etc/udev/suse/05-udev-early.rules delete mode 100644 etc/udev/suse/10-wait-for-sysfs.rules rename etc/udev/suse/{50-udev.rules => 50-udev-default.rules} (85%) rename etc/udev/suse/{60-persistent.rules => 60-persistent-disk.rules} (97%) rename etc/udev/suse/{95-debug.rules => 95-udev-late.rules} (70%) diff --git a/etc/udev/suse/05-udev-early.rules b/etc/udev/suse/05-udev-early.rules new file mode 100644 index 0000000000..ce159d56d3 --- /dev/null +++ b/etc/udev/suse/05-udev-early.rules @@ -0,0 +1,7 @@ +# sysfs is populated after the event is sent +ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus" + +# ignore these events until someone needs them +SUBSYSTEM=="drivers", OPTIONS="ignore_device" +SUBSYSTEM=="module", OPTIONS="ignore_device" + diff --git a/etc/udev/suse/10-wait-for-sysfs.rules b/etc/udev/suse/10-wait-for-sysfs.rules deleted file mode 100644 index 80c1781530..0000000000 --- a/etc/udev/suse/10-wait-for-sysfs.rules +++ /dev/null @@ -1 +0,0 @@ -ACTION=="add", DEVPATH=="/devices/*", ENV{PHYSDEVBUS}=="?*", WAIT_FOR_SYSFS="bus" diff --git a/etc/udev/suse/40-bluetooth.rules b/etc/udev/suse/40-bluetooth.rules index 7405d15b21..b6d706cabf 100644 --- a/etc/udev/suse/40-bluetooth.rules +++ b/etc/udev/suse/40-bluetooth.rules @@ -1,5 +1,5 @@ # bluetooth subsystem -SUBSYSTEM=="bluetooth", RUN+="/sbin/udev.bluetooth.sh" +SUBSYSTEM=="bluetooth", RUN+="/lib/udev/bluetooth.sh" # uncomment this if you have configured an automatic rfcomm-bind in # /etc/bluetooth/rfcomm.conf diff --git a/etc/udev/suse/50-udev.rules b/etc/udev/suse/50-udev-default.rules similarity index 85% rename from etc/udev/suse/50-udev.rules rename to etc/udev/suse/50-udev-default.rules index 51561ffd0f..09f197da23 100644 --- a/etc/udev/suse/50-udev.rules +++ b/etc/udev/suse/50-udev-default.rules @@ -1,7 +1,3 @@ -# ignore these events until someone needs them -SUBSYSTEM=="drivers", OPTIONS="last_rule" -SUBSYSTEM=="module", OPTIONS="last_rule" - # console KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" @@ -39,10 +35,6 @@ KERNEL=="pmu", GROUP="video" # dvb SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%i $${K%%%%.*} $${K#*.}'", NAME="%c", GROUP="video" -# Kino jogshuttle support -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="b33/10/*", RUN+="/usr/bin/killall --quiet -USR2 kino" -SUBSYSTEM=="usb", ACTION=="add", ENV{PRODUCT}=="5f3/240/*", RUN+="/usr/bin/killall --quiet -USR2 kino" - # input devices KERNEL=="mice", NAME="input/%k", MODE="0640" KERNEL=="mouse*", NAME="input/%k", MODE="0640" @@ -51,7 +43,7 @@ KERNEL=="js*", NAME="input/%k", MODE="0644" KERNEL=="ts*", NAME="input/%k", MODE="0600" KERNEL=="uinput", NAME="input/%k", MODE="0600" KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" -KERNEL=="input[0-9]*", ACTION=="add", RUN+="/lib/udev/input.sh" +KERNEL=="input[0-9]*", ACTION=="add", RUN+="input.sh" # printer SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" @@ -77,6 +69,9 @@ KERNEL=="rioctl", NAME="specialix_rioctl", SYMLINK+="%k" # 167 /dev/specialix_sxctl Specialix serial control KERNEL=="sxctl", NAME="specialix_sxctl", SYMLINK+="%k" +# network +KERNEL=="tun", NAME="net/%k", MODE="0600" + # misc devices KERNEL=="mem", NAME="%k", GROUP="kmem", MODE="640" KERNEL=="kmem", NAME="%k", GROUP="kmem", MODE="640" @@ -103,13 +98,14 @@ KERNEL=="z90crypt", NAME="%k", MODE="666" KERNEL=="mmtimer", NAME="%k", MODE="444" KERNEL=="auer[0-9]*" NAME="usb/%k" +# packet writing interface KERNEL=="pktcdvd", NAME="pktcdvd/control" KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%k" # fix floppy devices -KERNEL=="nvram", ACTION=="add", RUN+="/lib/udev/load_floppy_module.sh" -KERNEL=="fd*", ACTION=="add", SYSFS{device/cmos}=="*", RUN+="/lib/udev/create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" -KERNEL=="fd*", ACTION=="remove", RUN+="/lib/udev/remove_floppy_devices.sh %k" +KERNEL=="nvram", ACTION=="add", RUN+="load_floppy_module.sh" +KERNEL=="fd[0-9]*", ACTION=="add", SYSFS{device/cmos}=="*", RUN+="create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" +KERNEL=="fd[0-9]*", ACTION=="remove", RUN+="/bin/rm -f $root/%k*" # block devices SUBSYSTEM=="block", GROUP="disk", MODE="0640" @@ -125,14 +121,14 @@ SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", RUN+="/sbin/mo SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="[45]", RUN+="/sbin/modprobe sr_mod" SUBSYSTEM=="scsi_device", ACTION=="add", RUN+="/sbin/modprobe sg" -# IDE modules -SUBSYSTEM=="ide", ACTION=="add", RUN+="/lib/udev/ide.sh" +# load IDE modules +SUBSYSTEM=="ide", ACTION=="add", RUN+="ide.sh" # device mapper -KERNEL=="device-mapper", ACTION=="add", NAME="%k", SYMLINK+="mapper/control" +KERNEL=="device-mapper", NAME="%k", SYMLINK+="mapper/control" # check fstab and possibly mount -SUBSYSTEM=="block", KERNEL=="sd*[0-9]|hd*[0-9]", ACTION=="add", RUN+="/lib/udev/mount.sh" +SUBSYSTEM=="block", ACTION=="add", KERNEL=="sd*[0-9]|hd*[0-9]", RUN+="mount.sh" # misc storage devices (non-block) KERNEL=="sg*", NAME="%k", GROUP="disk", MODE="640" @@ -161,6 +157,6 @@ KERNEL=="iseries/ibmsis*", NAME="%k", GROUP="disk" # libusb device access SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/usb/%%03i/%%03i $${K%%%%.*} $${K#*.}'", NAME="%c", MODE="0644" -# firmware loader -SUBSYSTEM=="firmware", ACTION=="add", RUN+="/lib/udev/firmware.sh" +# kernel firmware loader +SUBSYSTEM=="firmware", ACTION=="add", RUN+="firmware.sh" diff --git a/etc/udev/suse/60-persistent.rules b/etc/udev/suse/60-persistent-disk.rules similarity index 97% rename from etc/udev/suse/60-persistent.rules rename to etc/udev/suse/60-persistent-disk.rules index 0d24a29338..3515bb189d 100644 --- a/etc/udev/suse/60-persistent.rules +++ b/etc/udev/suse/60-persistent-disk.rules @@ -43,6 +43,6 @@ KERNEL=="*[!0-9]", IMPORT{program}="/sbin/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" -KERNEL=="dm-[0-9]*", ACTION=="add", PROGRAM="/sbin/dmsetup info -c --noheadings -o name -j %M -m %m", SYMLINK="disk/by-name/%c" +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" diff --git a/etc/udev/suse/80-sysconfig.rules b/etc/udev/suse/80-sysconfig.rules index d33d975b36..7073813c61 100644 --- a/etc/udev/suse/80-sysconfig.rules +++ b/etc/udev/suse/80-sysconfig.rules @@ -1,7 +1,6 @@ ENV{SYSCONFIG}=="no|off|0", GOTO="sysconfig_end" -# network devices -KERNEL=="tun", NAME="net/%k", MODE="0600" +# SUSE network device handling SUBSYSTEM=="net", ACTION=="add", RUN+="/sbin/ifup $env{INTERFACE} -o hotplug" SUBSYSTEM=="net", ACTION=="remove", RUN+="/sbin/ifdown %k -o hotplug" @@ -16,5 +15,7 @@ SUBSYSTEM=="macio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-%p -o hotplug" SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-%p -o hotplug" SUBSYSTEM=="pnp", ACTION=="add", RUN+="/sbin/hwup pnp-devpath-%p -o hotplug" +#SUBSYSTEM=="ide", ACTION=="add", RUN+="/sbin/hwup ide-devpath-%p -o hotplug" +#SUBSYSTEM=="input", KERNEL=="input[0-9]*", ACTION=="add", RUN+="/sbin/hwup input-devpath-%p -o hotplug" LABEL="sysconfig_end" diff --git a/etc/udev/suse/95-debug.rules b/etc/udev/suse/95-udev-late.rules similarity index 70% rename from etc/udev/suse/95-debug.rules rename to etc/udev/suse/95-udev-late.rules index 280287c1a7..81331ad6b7 100644 --- a/etc/udev/suse/95-debug.rules +++ b/etc/udev/suse/95-udev-late.rules @@ -1,5 +1,5 @@ # debug events to /events, but not on default udev_log="err" -ENV{UDEV_LOG}=="[4-9]", RUN+="/lib/udev/eventrecorder.sh" +ENV{UDEV_LOG}=="[4-9]", RUN+="eventrecorder.sh" # event to be catched by udevmonitor RUN+="socket:/org/kernel/udev/monitor" From 632b682b2a1b4b71500a633369668b0cc7379bcd Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 16 Dec 2005 21:00:14 +0100 Subject: [PATCH 1653/4284] remove unused variables Signed-off-by: Kay Sievers --- udev.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/udev.h b/udev.h index faa12a31ee..474f3f5e25 100644 --- a/udev.h +++ b/udev.h @@ -76,8 +76,6 @@ struct udevice { int partitions; int ignore_device; int ignore_remove; - int config_line; - char config_file[PATH_SIZE]; char bus_id[NAME_SIZE]; char program_result[PATH_SIZE]; char kernel_number[NAME_SIZE]; From c602535043cbe74dfdcc5f2926e8518237602694 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 16 Dec 2005 21:16:32 +0100 Subject: [PATCH 1654/4284] remove default settings in udev.conf Changing the default values in udev.conf will render allmost all current systems unusable. So just remove the settings that can't be changed anyway. Signed-off-by: Kay Sievers --- etc/udev/udev.conf.in | 6 ------ udev_add.c | 3 +-- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf.in index a92f688c3a..41902c4f06 100644 --- a/etc/udev/udev.conf.in +++ b/etc/udev/udev.conf.in @@ -1,11 +1,5 @@ # udev.conf -# Where in the filesystem to place the device nodes. -udev_root="@udevdir@" - -# The name and location of the udev rules file(s). -udev_rules="@configdir@/rules.d" - # 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=". diff --git a/udev_add.c b/udev_add.c index 128917e519..174474bdc7 100644 --- a/udev_add.c +++ b/udev_add.c @@ -272,8 +272,7 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) goto exit; if (udev_db_add_device(udev) != 0) - dbg("udev_db_add_dev failed, but we create the node anyway, " - "remove might not work for custom names"); + dbg("udev_db_add_dev failed, remove might not work for custom names"); /* use full path to the environment */ snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); From d2e7c6bf67b1b0d1f5d12ac533131c73bc046454 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 17 Dec 2005 00:27:19 +0100 Subject: [PATCH 1655/4284] clearenv() is now part of klibc Signed-off-by: Kay Sievers --- udev_libc_wrapper.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index 824603b74c..a4d320fef2 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -138,14 +138,6 @@ static inline int inotify_add_watch(int fd, const char *name, uint32_t mask) #define SO_RCVBUFFORCE 33 #endif -#ifdef __KLIBC__ -static inline int clearenv(void) -{ - environ[0] = NULL; - return 0; -} -#endif - extern uid_t lookup_user(const char *user); extern gid_t lookup_group(const char *group); From fb6e4c28248cdeed30a1d3eb42aba477f0429472 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 17 Dec 2005 16:20:51 +0100 Subject: [PATCH 1656/4284] add DEVLINKS to the event environment Multiple symlinks are separated by a space character. Signed-off-by: Kay Sievers --- RELEASE-NOTES | 10 ++++++ udev.h | 1 - udev_add.c | 89 ++++++++++++++++++++++++++------------------------- udev_event.c | 4 --- udev_remove.c | 7 ++-- udevstart.c | 2 -- 6 files changed, 60 insertions(+), 53 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 4006e510d7..19af28fb66 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,13 @@ +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 diff --git a/udev.h b/udev.h index 474f3f5e25..ca99da512d 100644 --- a/udev.h +++ b/udev.h @@ -58,7 +58,6 @@ struct udevice { enum device_type type; char name[PATH_SIZE]; - char devname[PATH_SIZE]; struct list_head symlink_list; int symlink_final; char owner[USER_SIZE]; diff --git a/udev_add.c b/udev_add.c index 174474bdc7..bf2d59d198 100644 --- a/udev_add.c +++ b/udev_add.c @@ -108,7 +108,6 @@ exit: static int create_node(struct udevice *udev, struct sysfs_class_device *class_dev) { char filename[PATH_SIZE]; - char partitionname[PATH_SIZE]; struct name_entry *name_loop; uid_t uid; gid_t gid; @@ -152,6 +151,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de info("creating device node '%s'", filename); if (udev_make_node(udev, filename, udev->devt, udev->mode, uid, gid) != 0) goto error; + setenv("DEVNAME", filename, 1); } else { info("creating device node '%s', major = '%d', minor = '%d', " "mode = '%#o', uid = '%d', gid = '%d'", filename, @@ -160,6 +160,7 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de /* create all_partitions if requested */ if (udev->partitions) { + char partitionname[PATH_SIZE]; struct sysfs_attribute *attr; int range; @@ -184,45 +185,55 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de } /* create symlink(s) if requested */ - list_for_each_entry(name_loop, &udev->symlink_list, node) { - int retval; - char linktarget[PATH_SIZE]; + if (!list_empty(&udev->symlink_list)) { + char symlinks[512] = ""; - snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); - filename[sizeof(filename)-1] = '\0'; + list_for_each_entry(name_loop, &udev->symlink_list, node) { + int retval; + char linktarget[PATH_SIZE]; - dbg("symlink '%s' to node '%s' requested", filename, udev->name); - if (!udev->test_run) - if (strchr(filename, '/')) - create_path(filename); + snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); + filename[sizeof(filename)-1] = '\0'; - /* optimize relative link */ - linktarget[0] = '\0'; - i = 0; - tail = 0; - while (udev->name[i] && (udev->name[i] == name_loop->name[i])) { - if (udev->name[i] == '/') - tail = i+1; - i++; - } - while (name_loop->name[i] != '\0') { - if (name_loop->name[i] == '/') - strlcat(linktarget, "../", sizeof(linktarget)); - i++; + dbg("symlink '%s' to node '%s' requested", filename, udev->name); + if (!udev->test_run) + if (strchr(filename, '/')) + create_path(filename); + + /* optimize relative link */ + linktarget[0] = '\0'; + i = 0; + tail = 0; + while (udev->name[i] && (udev->name[i] == name_loop->name[i])) { + if (udev->name[i] == '/') + tail = i+1; + i++; + } + while (name_loop->name[i] != '\0') { + if (name_loop->name[i] == '/') + strlcat(linktarget, "../", sizeof(linktarget)); + i++; + } + + strlcat(linktarget, &udev->name[tail], sizeof(linktarget)); + + info("creating symlink '%s' to '%s'", filename, linktarget); + if (!udev->test_run) { + unlink(filename); + selinux_setfscreatecon(filename, NULL, S_IFLNK); + retval = symlink(linktarget, filename); + selinux_resetfscreatecon(); + if (retval != 0) + err("symlink(%s, %s) failed: %s", + linktarget, filename, strerror(errno)); + } + + strlcat(symlinks, filename, sizeof(symlinks)); + strlcat(symlinks, " ", sizeof(symlinks)); } - strlcat(linktarget, &udev->name[tail], sizeof(linktarget)); - - info("creating symlink '%s' to '%s'", filename, linktarget); - if (!udev->test_run) { - unlink(filename); - selinux_setfscreatecon(filename, NULL, S_IFLNK); - retval = symlink(linktarget, filename); - selinux_resetfscreatecon(); - if (retval != 0) - err("symlink(%s, %s) failed: %s", - linktarget, filename, strerror(errno)); - } + remove_trailing_chars(symlinks, ' '); + setenv("DEVLINKS", symlinks, 1); } return 0; @@ -273,11 +284,6 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) if (udev_db_add_device(udev) != 0) dbg("udev_db_add_dev failed, remove might not work for custom names"); - - /* use full path to the environment */ - snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); - udev->devname[sizeof(udev->devname)-1] = '\0'; - } else if (udev->type == DEV_NET) { /* look if we want to change the name of the netif */ if (strcmp(udev->name, udev->kernel_name) != 0) { @@ -298,9 +304,6 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) setenv("DEVPATH", udev->devpath, 1); setenv("INTERFACE", udev->name, 1); } - - /* use netif name for the environment */ - strlcpy(udev->devname, udev->name, sizeof(udev->devname)); } } diff --git a/udev_event.c b/udev_event.c index 0b4b9dc495..887537e0e9 100644 --- a/udev_event.c +++ b/udev_event.c @@ -130,10 +130,6 @@ int udev_process_event(struct udev_rules *rules, struct udevice *udev) return 0; } } - - /* export name of device node or netif */ - if (udev->devname[0] != '\0') - setenv("DEVNAME", udev->devname, 1); } else if (udev->type == DEV_DEVICE && strcmp(udev->action, "add") == 0) { struct sysfs_device *devices_dev; diff --git a/udev_remove.c b/udev_remove.c index 6efa17eb7c..f9592b4c70 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -37,6 +37,7 @@ static int delete_node(struct udevice *udev) { char filename[PATH_SIZE]; + char devname[PATH_SIZE]; char partitionname[PATH_SIZE]; struct name_entry *name_loop; struct stat stats; @@ -81,9 +82,9 @@ static int delete_node(struct udevice *udev) if (retval) return retval; - /* export DEVNAME to the environment */ - snprintf(udev->devname, sizeof(udev->devname), "%s/%s", udev_root, udev->name); - udev->devname[sizeof(udev->devname)-1] = '\0'; + snprintf(devname, sizeof(devname), "%s/%s", udev_root, udev->name); + devname[sizeof(devname)-1] = '\0'; + setenv("DEVNAME", devname, 1); num = udev->partitions; if (num > 0) { diff --git a/udevstart.c b/udevstart.c index 11063f6799..a9959c5d6b 100644 --- a/udevstart.c +++ b/udevstart.c @@ -155,8 +155,6 @@ static int add_device(const char *devpath, const char *subsystem) } udev_add_device(&udev, class_dev); - if (udev.devname[0] != '\0') - setenv("DEVNAME", udev.devname, 1); run: if (udev_run && !list_empty(&udev.run_list)) { struct name_entry *name_loop; From ba65db20cfa6754ed7e0d0c5ecc82a58f481e070 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 17 Dec 2005 16:40:29 +0100 Subject: [PATCH 1657/4284] 078 release --- ChangeLog | 27 +++++++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e80def7759..71df29fc20 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 774d5e154a..8d80ce5dc7 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 077 +VERSION = 078 # set this to make use of syslog USE_LOG = true From caa4fd85aeff9c40897d34fba09b4fb7c18d2198 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 20 Dec 2005 11:23:08 +0100 Subject: [PATCH 1658/4284] don't log error if database does not exist Signed-off-by: Kay Sievers --- udev_db.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udev_db.c b/udev_db.c index 6e9a1187d0..6b9d5e8426 100644 --- a/udev_db.c +++ b/udev_db.c @@ -212,7 +212,7 @@ int udev_db_lookup_name(const char *name, char *devpath, size_t len) strlcat(dbpath, "/"DB_DIR, sizeof(dbpath)); dir = opendir(dbpath); if (dir == NULL) { - err("unable to open udev_db '%s': %s", dbpath, strerror(errno)); + info("no udev_db available '%s': %s", dbpath, strerror(errno)); return -1; } @@ -283,7 +283,7 @@ int udev_db_get_all_entries(struct list_head *name_list) strlcat(dbpath, "/"DB_DIR, sizeof(dbpath)); dir = opendir(dbpath); if (dir == NULL) { - err("unable to open udev_db '%s': %s", dbpath, strerror(errno)); + info("no udev_db available '%s': %s", dbpath, strerror(errno)); return -1; } From 1698d39857e105876011b95e82d44c5e1e0846f2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 22 Dec 2005 17:29:20 +0100 Subject: [PATCH 1659/4284] use udev_root instead of "/dev"in selinux matchpathcon_init_prefix() Taken from Red Hat CVS: udev-075-selinux.patch --- udev_selinux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udev_selinux.c b/udev_selinux.c index f014ea5535..1e1fdb9617 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -152,7 +152,7 @@ void selinux_init(void) * restoration creation purposes. */ if (is_selinux_running()) { - matchpathcon_init_prefix(NULL, "/dev"); + matchpathcon_init_prefix(NULL, udev_root); if (getfscreatecon(&prev_scontext) < 0) { err("getfscreatecon failed\n"); prev_scontext = NULL; From 892532a9395d6b2c9cbaddde8b658fefa13bf7dc Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 23 Dec 2005 00:06:54 +0100 Subject: [PATCH 1660/4284] scsi_id: read page 0x80 with libata drives Signed-off-by: Kay Sievers --- extras/scsi_id/scsi_id.config | 39 ++++------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/extras/scsi_id/scsi_id.config b/extras/scsi_id/scsi_id.config index 4f31b1c498..d1768509ad 100644 --- a/extras/scsi_id/scsi_id.config +++ b/extras/scsi_id/scsi_id.config @@ -1,11 +1,8 @@ # -# Informational and example scsi_id.config file for use with scsi_id. -# - -# General syntax is: +# scsi_id configuration # # lower or upper case has no affect on the left side. Quotes (") are -# required if you need spaces in values. Model is the same as the SCSI +# 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. # @@ -13,36 +10,8 @@ # if you do not want such a match space fill the extra bytes. If no model # is specified, only the vendor string need match. # -# The "options" line is searched for when scsi_id starts up, and is -# primarily for use with hotplug. -# # options= -# # vendor=string[,model=string],options= -# -# If you normally don't need scsi id's, or might be attaching devices of -# an unknown functionality, black list everyone. This is the default -# behaviour (if no -b or -g is specified). -# -options=-b - -# -# Then white list devices on your system that have correct and useful id's: -# -vendor=someone, model=nicedrive, options=-g - -# If you know all the scsi devices on your system support valid id's, -# remove the options=-b line, and mark all devices as good: - -## options=-g - -# Then black list any offenders. Missing entries here could be dangerous -# if you rely on the id for persistent naming or multi-path configuration. - -## vendor=ELBONIA, model=borken, options=-b - -# EMC SYMMETRIX models 4 and 5, and some model 6 systems return the VSI -# field of the page 83 reply according to SCSI-2 format. This format is -# binary encoded hexa-decimal as opposed to the Identifiscation descriptor -# utilized by both SPC-2 and SPC-3 compliant systems. +# some libata drives require vpd page 0x80 +vendor="ATA",options=-p 0x80 From d69b2203c37d32bbfbd81153a1fc99b55b7b6cbb Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 23 Dec 2005 00:13:34 +0100 Subject: [PATCH 1661/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/{persistent.rules => persistent-disk.rules} | 3 ++- etc/udev/suse/05-udev-early.rules | 1 + etc/udev/suse/50-udev-default.rules | 5 +---- etc/udev/suse/80-sysconfig.rules | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) rename etc/udev/{persistent.rules => persistent-disk.rules} (94%) diff --git a/etc/udev/persistent.rules b/etc/udev/persistent-disk.rules similarity index 94% rename from etc/udev/persistent.rules rename to etc/udev/persistent-disk.rules index 0b231aacd5..3515bb189d 100644 --- a/etc/udev/persistent.rules +++ b/etc/udev/persistent-disk.rules @@ -43,5 +43,6 @@ KERNEL=="*[!0-9]", IMPORT{program}="/sbin/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" -LABEL="persistent_end" +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" diff --git a/etc/udev/suse/05-udev-early.rules b/etc/udev/suse/05-udev-early.rules index ce159d56d3..dfdbdff0c9 100644 --- a/etc/udev/suse/05-udev-early.rules +++ b/etc/udev/suse/05-udev-early.rules @@ -1,5 +1,6 @@ # 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" # ignore these events until someone needs them SUBSYSTEM=="drivers", OPTIONS="ignore_device" diff --git a/etc/udev/suse/50-udev-default.rules b/etc/udev/suse/50-udev-default.rules index 09f197da23..fe861ae972 100644 --- a/etc/udev/suse/50-udev-default.rules +++ b/etc/udev/suse/50-udev-default.rules @@ -33,7 +33,7 @@ KERNEL=="vbi0", SYMLINK+="vbi" KERNEL=="pmu", GROUP="video" # dvb -SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%i $${K%%%%.*} $${K#*.}'", NAME="%c", GROUP="video" +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=="mice", NAME="input/%k", MODE="0640" @@ -127,9 +127,6 @@ SUBSYSTEM=="ide", ACTION=="add", RUN+="ide.sh" # device mapper KERNEL=="device-mapper", NAME="%k", SYMLINK+="mapper/control" -# check fstab and possibly mount -SUBSYSTEM=="block", ACTION=="add", KERNEL=="sd*[0-9]|hd*[0-9]", RUN+="mount.sh" - # misc storage devices (non-block) KERNEL=="sg*", NAME="%k", GROUP="disk", MODE="640" KERNEL=="st*", NAME="%k", GROUP="disk" diff --git a/etc/udev/suse/80-sysconfig.rules b/etc/udev/suse/80-sysconfig.rules index 7073813c61..d6778647ba 100644 --- a/etc/udev/suse/80-sysconfig.rules +++ b/etc/udev/suse/80-sysconfig.rules @@ -9,7 +9,7 @@ SUBSYSTEM=="pci", ACTION=="add", RUN+="/sbin/hwup bus-pci-%k -o hotplug" SUBSYSTEM=="usb", ACTION=="add", RUN+="/sbin/hwup usb-devpath-%p -o hotplug" SUBSYSTEM=="ieee1394", ACTION=="add", RUN+="/sbin/hwup ieee1394-devpath-%p -o hotplug" SUBSYSTEM=="scsi", DEVPATH=="/devices/css*", ACTION=="remove", RUN+="/sbin/hwdown scsi-devpath-%p -o hotplug" -SUBSYSTEM=="scsi_host", ACTION=="add", SYSFS{device/cutype}=="?*", RUN+="/sbin/hwup scsi__host-devpath-%p -o hotplug" +SUBSYSTEM=="scsi_host", ACTION=="add", SYSFS{proc_name}=="zfcp", RUN+="/sbin/hwup scsi_host-devpath-%p -o hotplug" SUBSYSTEM=="vio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" SUBSYSTEM=="macio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-%p -o hotplug" From c082b99acbc4b25fd133a88bfabf68eee23d7b0b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 23 Dec 2005 00:49:02 +0100 Subject: [PATCH 1662/4284] remove %e from man page Simple %e enumerations never worked reliably outside of udevstart and udevstart is no longer recommended to use. Signed-off-by: Kay Sievers --- docs/udev.xml | 18 ++---------------- udev.8 | 11 ++--------- 2 files changed, 4 insertions(+), 25 deletions(-) diff --git a/docs/udev.xml b/docs/udev.xml index 3db66f8001..8c07f0e687 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -42,9 +42,7 @@ Usually udev runs as udevd 8 and receives uevents directly from the - kernel if a device is added or removed form the system. The program - udev itself may be used as an event handler in situations, - where running the daemon is not appropriate, like in initramfs. + kernel if a device is added or removed form 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. @@ -393,7 +391,7 @@ - , + , The value of an environment variable. @@ -424,18 +422,6 @@ - - , - - If a device node already exists with the name, the smallest next free - number is used. This can be used to create compatibility symlinks and enumerate - devices of the same type originating from different kernel subsystems. - Note: The use of the enumeration facility is unreliable for events that - request a number at the same time. The use of enumerations in todays setups - where devices can come and go at any time is not recommended. - - - , diff --git a/udev.8 b/udev.8 index 2ea5812092..c6ab83e805 100644 --- a/udev.8 +++ b/udev.8 @@ -17,9 +17,7 @@ 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 form the system. The program -\fBudev\fR -itself may be used as an event handler in situations, where running the daemon is not appropriate, like in initramfs. +and receives uevents directly from the kernel if a device is added or removed form 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" @@ -182,7 +180,7 @@ The devpath of the device. \fB%s{\fR\fB\fIfile\fR\fR\fB}\fR, \fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR The content of a sysfs attribute. .TP -\fB%e{\fR\fB\fIkey\fR\fR\fB}\fR, \fB$env{\fR\fB\fIkey\fR\fR\fB}\fR +\fB%E{\fR\fB\fIkey\fR\fR\fB}\fR, \fB$env{\fR\fB\fIkey\fR\fR\fB}\fR The value of an environment variable. .TP \fB%m\fR, \fB$major\fR @@ -196,11 +194,6 @@ The string returned by the external program requested with PROGRAM. A single par \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 .TP -\fB%e\fR, \fB$enum\fR -If a device node already exists with the name, the smallest next free number is used. This can be used to create compatibility symlinks and enumerate devices of the same type originating from different kernel subsystems. - -Note: The use of the enumeration facility is unreliable for events that request a number at the same time. The use of enumerations in todays setups where devices can come and go at any time is not recommended. -.TP \fB%P\fR, \fB$parent\fR The node name of the parent device. .TP From e2e8e5ce960ad79d8e5380303e770302570534af Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 23 Dec 2005 00:51:30 +0100 Subject: [PATCH 1663/4284] 079 release --- ChangeLog | 10 ++++++++++ Makefile | 2 +- RELEASE-NOTES | 10 ++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 71df29fc20..cba96f91a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 8d80ce5dc7..f5c71a6f80 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 078 +VERSION = 079 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 19af28fb66..f7839b6893 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,13 @@ +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 From 68cfe3b5c851eb4c21e73720049f00ad87fcd5b8 Mon Sep 17 00:00:00 2001 From: Marco d'Itri Date: Mon, 26 Dec 2005 17:21:25 +0100 Subject: [PATCH 1664/4284] udev_selinux.c: include udev.h --- udev_selinux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_selinux.c b/udev_selinux.c index 1e1fdb9617..298c75566c 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -30,6 +30,7 @@ #include #include +#include "udev.h" #include "udev_selinux.h" #include "logging.h" From a5e551b996f81709d9f53b2c7434b48ee7f85605 Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Thu, 29 Dec 2005 03:42:38 +0100 Subject: [PATCH 1665/4284] fix dependency for make -j2 --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f5c71a6f80..5edc76f81a 100644 --- a/Makefile +++ b/Makefile @@ -211,7 +211,7 @@ all: $(PROGRAMS) $(MAN_PAGES) .SUFFIXES: # build the objects -%.o: %.c $(GEN_HEADERS) +%.o: %.c $(HOST_PROGS) $(GEN_HEADERS) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ # "Static Pattern Rule" to build all programs @@ -255,6 +255,7 @@ ccdv: ccdv.c .SILENT: ccdv clean: + - rm -f $(HOST_PROGS) - find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print0 | xargs -0rt rm -f - find -name "*.gcno" -print0 | xargs -0rt rm -f - find -name "*.gcda" -print0 | xargs -0rt rm -f From 3e0f8812f8c824648db7cc6886265ed186685488 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 29 Dec 2005 03:51:24 +0100 Subject: [PATCH 1666/4284] update RELEASE-NOTES + TODO Signed-off-by: Kay Sievers --- RELEASE-NOTES | 12 ++++++++++++ TODO | 24 +++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index f7839b6893..4e3570205e 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,15 @@ +udev 080 +======== +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. + udev 079 ======== Let scsi_id request libata drive serial numbers from page 0x80. diff --git a/TODO b/TODO index 7e123d8b14..2afa1783ee 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,21 @@ -This is a list of things that needs to be done. They are in no specific -order. We will gladly accept patches for any of these items: +These things need to be done, or would be nice to have: -- Log the relationship of the kernel name and the persistent disk name - to syslog, so any error logged from the kernel can be associated with - any of the links at that time. + o Log the relationship of the kernel name and the persistent disk name + to syslog, so any error logged from the kernel can be associated with + any of the links at that time. + + +These things are scheduled for removal sometimes: + + o remove broken %e enumeration + (simple enumerations can't work and should go) + + o remove devfs naming scheme rules and scripts + + o remove MODALIAS + $modalias + (ENV{MODALIAS}, $env{MODALIAS}, $sysfs{modalias} will do it) + + o remove udevstart, udevsend + (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) From fabd8709fb2202daa30168401f3ed8af5e6dadab Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 29 Dec 2005 04:02:24 +0100 Subject: [PATCH 1667/4284] fix typo in man page Thanks to Frans Pop for the "patch". --- docs/udev.xml | 8 ++++---- udev.8 | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/udev.xml b/docs/udev.xml index 8c07f0e687..b2e2df0aa3 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -176,7 +176,7 @@ - Match the typ of bus the device is connected to. + Match the type of bus the device is connected to. @@ -263,8 +263,8 @@ - The name of the node to be created, or the name, the network interface - should be renamed to. Only one rule can set the a name, all later rules with + 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. @@ -282,7 +282,7 @@ - The permissions for the device node. Every specified value over writes + The permissions for the device node. Every specified value overwrites the compiled-in default value. diff --git a/udev.8 b/udev.8 index c6ab83e805..4ca8107265 100644 --- a/udev.8 +++ b/udev.8 @@ -82,7 +82,7 @@ Match the kernel devpath. Match the kernel subsystem name .TP \fBBUS\fR -Match the typ of bus the device is connected to. +Match the type of bus the device is connected to. .TP \fBDRIVER\fR Match the kernel driver name. @@ -116,13 +116,13 @@ Matches any single character specified within the brackets. example, the pattern The following keys can get values assigned: .TP \fBNAME\fR -The name of the node to be created, or the name, the network interface should be renamed to. Only one rule can set the a name, all later rules with a NAME key will be ignored. +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. .TP \fBSYMLINK\fR 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. .TP \fBOWNER, GROUP, MODE\fR -The permissions for the device node. Every specified value over writes the compiled\-in default value. +The permissions for the device node. Every specified value overwrites the compiled\-in default value. .TP \fBENV{\fR\fB\fIkey\fR\fR\fB}\fR Export the key to the environment. Depending on the specified operation, this key is also used as a match. From 22f29307ff0df84de0c3bebc9bf523d19d673b32 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 29 Dec 2005 04:24:15 +0100 Subject: [PATCH 1668/4284] update TODO Signed-off-by: Kay Sievers --- TODO | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 2afa1783ee..19aae9edf0 100644 --- a/TODO +++ b/TODO @@ -4,8 +4,14 @@ These things need to be done, or would be nice to have: to syslog, so any error logged from the kernel can be associated with any of the links at that time. + o Fix inconsistency with KERNEL and ID. ID will walk up the device chain + but it matches on "KERNEL names" too. And ID and SYSFS can only match + on the same device in the chain. That's pretty hard to explain and to + understand. Same for SUBSYSTEM and BUS. -These things are scheduled for removal sometimes: + +These things are deprecated and scheduled for removal in a future +udev version: o remove broken %e enumeration (simple enumerations can't work and should go) From 33d062d74661c5d1f5d9686365ee95254e32332a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 29 Dec 2005 04:25:49 +0100 Subject: [PATCH 1669/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/50-udev-default.rules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/udev/suse/50-udev-default.rules b/etc/udev/suse/50-udev-default.rules index fe861ae972..667b0ae9b1 100644 --- a/etc/udev/suse/50-udev-default.rules +++ b/etc/udev/suse/50-udev-default.rules @@ -16,7 +16,7 @@ KERNEL=="modems/mwave*", NAME="%k", GROUP="uucp" KERNEL=="hvc*", NAME="%k", GROUP="uucp" KERNEL=="hvsi*", NAME="%k", GROUP="uucp" KERNEL=="iseries/vtty*", NAME="%k", GROUP="uucp" -KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", SYMLINK+="pilot" +KERNEL=="ttyUSB*", SYSFS{product}=="[Pp]alm*Handheld*", SYMLINK+="pilot" # video/graphics SUBSYSTEM=="video4linux", GROUP="video" From 309d6fd302921489a93dca07f1675c9fc1f74a5a Mon Sep 17 00:00:00 2001 From: coly Date: Mon, 9 Jan 2006 20:58:20 +0100 Subject: [PATCH 1670/4284] fix man page typos --- docs/udev.xml | 4 ++-- udev.8 | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/udev.xml b/docs/udev.xml index b2e2df0aa3..e87dbab880 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -53,7 +53,7 @@ CONFIGURATION All udev configuration files are placed in /etc/udev/*. - Every file consist of a set of lines of text. All empty lines or lines beginning + Every file consists of a set of lines of text. All empty lines or lines beginning with '#' will be ignored. Configuration file @@ -198,7 +198,7 @@ Match against the value of an environment key. Depending on - the specified operation, this key is also used as a assignment. + the specified operation, this key is also used as an assignment. diff --git a/udev.8 b/udev.8 index 4ca8107265..6d2f5e679e 100644 --- a/udev.8 +++ b/udev.8 @@ -23,7 +23,7 @@ If udev receives a device event, it matches its configured rules against the ava .SH "CONFIGURATION" .PP All udev configuration files are placed in -\fI/etc/udev/*\fR. Every file consist of a set of lines of text. All empty lines or lines beginning with '#' will be ignored. +\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 @@ -91,7 +91,7 @@ Match the kernel driver name. Match the device number on the bus. .TP \fBENV{\fR\fB\fIkey\fR\fR\fB}\fR -Match against the value of an environment key. Depending on the specified operation, this key is also used as a assignment. +Match against the value of an environment key. Depending on the specified operation, this key is also used as an assignment. .TP \fBSYSFS{\fR\fB\fIfilename\fR\fR\fB}\fR Match the sysfs attribute value. Up to five values can be specified. Trailing whitespace is ignored, if the specified match value does not contain trailing whitespace itself. From 47fbf3c58260e3fed1078061f8d45e01b0e120f0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 9 Jan 2006 21:17:24 +0100 Subject: [PATCH 1671/4284] path_id: fix invalid character class Thanks to Marco for the _right_ fix. Signed-off-by: Kay Sievers --- extras/path_id | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extras/path_id b/extras/path_id index dfb997b340..44fc4820b5 100755 --- a/extras/path_id +++ b/extras/path_id @@ -275,7 +275,7 @@ handle_block_usb_storage () { # usb-storage devs have a serial number, hopefully unique serial= if [ -f $controller_dev/../serial ] ; then - serial="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../serial`" + serial="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789-]@@g' < $controller_dev/../serial`" : serial XXX_${serial}_XXX d="usb-$serial" serial="`echo $serial | sed -e 's@[ 0]\{1,\}@@g'`" @@ -285,10 +285,10 @@ handle_block_usb_storage () { # has eventually binary junk in vpd identifier= if [ -f $controller_dev/../product ] ; then - product="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../product`" + product="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789-]@@g' < $controller_dev/../product`" fi if [ -f $controller_dev/../manufacturer ] ; then - manufacturer="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_0123456789]@@g' < $controller_dev/../manufacturer`" + manufacturer="`sed -e 's@^[ -]\{1,\}\|[ -]\{1,\}$@@g;s@[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789-]@@g' < $controller_dev/../manufacturer`" fi if [ -z "$product" -o -z "$manufacturer" ] ; then read idvendor < $controller_dev/../idVendor From 1aa1e24848903d11780db1ade355be73ad61a937 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 9 Jan 2006 21:18:00 +0100 Subject: [PATCH 1672/4284] replace libsysfs We never used any of the libsysfs convenience features. Here we replace it completely with 300 lines of code, which are much simpler and a bit faster cause udev(d) does not open any syfs file for a simple event which does not need any parent device information. Signed-off-by: Kay Sievers --- Makefile | 30 +- RELEASE-NOTES | 8 + docs/udev.xml | 7 - docs/udevtest.xml | 2 +- extras/ata_id/Makefile | 2 +- extras/ata_id/ata_id.c | 4 +- extras/cdrom_id/Makefile | 2 +- extras/cdrom_id/cdrom_id.c | 4 +- extras/dasd_id/Makefile | 2 +- extras/dasd_id/dasd_id.c | 3 +- extras/edd_id/Makefile | 2 +- extras/edd_id/edd_id.c | 4 +- extras/firmware/Makefile | 2 +- extras/firmware/firmware_helper.c | 3 +- extras/floppy/Makefile | 2 +- extras/run_directory/Makefile | 2 +- extras/run_directory/run_directory.c | 4 +- extras/run_directory/udev_run_devd.c | 4 +- extras/run_directory/udev_run_hotplugd.c | 4 +- extras/scsi_id/Makefile | 3 +- extras/scsi_id/scsi_id.c | 438 ++--- extras/scsi_id/scsi_id.h | 14 +- extras/scsi_id/scsi_serial.c | 258 ++- extras/usb_id/Makefile | 2 +- extras/usb_id/usb_id.c | 228 ++- extras/volume_id/Makefile | 2 +- extras/volume_id/vol_id.c | 3 +- libsysfs/LGPL | 441 ----- libsysfs/dlist.c | 621 ------- libsysfs/libsysfs.txt | 1954 ---------------------- libsysfs/sysfs.h | 64 - libsysfs/sysfs/dlist.h | 207 --- libsysfs/sysfs/libsysfs.h | 225 --- libsysfs/sysfs_bus.c | 317 ---- libsysfs/sysfs_class.c | 557 ------ libsysfs/sysfs_device.c | 341 ---- libsysfs/sysfs_dir.c | 491 ------ libsysfs/sysfs_driver.c | 261 --- libsysfs/sysfs_utils.c | 290 ---- test/simple-build-check.sh | 3 +- test/udev-test.pl | 51 +- udev.c | 53 +- udev.h | 110 +- udev_add.c | 54 +- udev_config.c | 10 +- udev_db.c | 14 +- udev_device.c | 136 +- udev_event.c | 161 -- udev_libc_wrapper.c | 3 - udev_remove.c | 12 +- udev_rules.c | 349 ++-- udev_rules.h | 12 +- udev_rules_parse.c | 5 +- udev_selinux.c | 1 - udev_sysfs.c | 345 ++++ udev_utils.c | 4 - udev_utils.h | 65 - udev_utils_file.c | 4 - udev_utils_run.c | 4 - udev_utils_string.c | 4 - udevcontrol.c | 3 - udevd.c | 41 +- udevd.h | 2 +- udevinfo.c | 260 ++- udevmonitor.c | 2 - udevsend.c | 4 +- udevstart.c | 90 +- udevtest.8 | 4 +- udevtest.c | 85 +- 69 files changed, 1380 insertions(+), 7319 deletions(-) delete mode 100644 libsysfs/LGPL delete mode 100644 libsysfs/dlist.c delete mode 100644 libsysfs/libsysfs.txt delete mode 100644 libsysfs/sysfs.h delete mode 100644 libsysfs/sysfs/dlist.h delete mode 100644 libsysfs/sysfs/libsysfs.h delete mode 100644 libsysfs/sysfs_bus.c delete mode 100644 libsysfs/sysfs_class.c delete mode 100644 libsysfs/sysfs_device.c delete mode 100644 libsysfs/sysfs_dir.c delete mode 100644 libsysfs/sysfs_driver.c delete mode 100644 libsysfs/sysfs_utils.c delete mode 100644 udev_event.c create mode 100644 udev_sysfs.c delete mode 100644 udev_utils.h diff --git a/Makefile b/Makefile index 5edc76f81a..461f5ac012 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,6 @@ PROGRAMS = \ HEADERS = \ udev.h \ - udev_utils.h \ udev_rules.h \ logging.h \ udev_libc_wrapper.h \ @@ -66,12 +65,12 @@ HEADERS = \ list.h UDEV_OBJS = \ - udev_event.o \ udev_device.o \ udev_config.o \ udev_add.o \ udev_remove.o \ udev_db.o \ + udev_sysfs.o \ udev_rules.o \ udev_rules_parse.o \ udev_utils.o \ @@ -90,15 +89,6 @@ MAN_PAGES = \ udevinfo.8 \ udevstart.8 -SYSFS_OBJS = \ - libsysfs/sysfs_class.o \ - libsysfs/sysfs_device.o \ - libsysfs/sysfs_dir.o \ - libsysfs/sysfs_driver.o \ - libsysfs/sysfs_utils.o \ - libsysfs/dlist.o -LIBSYSFS = libsysfs/libsysfs.a - # config files automatically generated GEN_CONFIGS = \ $(LOCAL_CFG_DIR)/udev.conf @@ -144,10 +134,6 @@ LDFLAGS = -Wl,-warn-common OPTFLAGS = -Os CFLAGS += $(OPTFLAGS) -# include our local copy of libsysfs -CFLAGS += -I$(PWD)/libsysfs/sysfs \ - -I$(PWD)/libsysfs - ifeq ($(strip $(USE_LOG)),true) CFLAGS += -DUSE_LOG endif @@ -200,7 +186,6 @@ all: $(PROGRAMS) $(MAN_PAGES) STRIPCMD="$(STRIPCMD)" \ LIB_OBJS="$(LIB_OBJS)" \ LIBUDEV="$(PWD)/$(LIBUDEV)" \ - LIBSYSFS="$(PWD)/$(LIBSYSFS)" \ QUIET="$(QUIET)" \ -C $$target $@ || exit 1; \ done; @@ -211,28 +196,21 @@ all: $(PROGRAMS) $(MAN_PAGES) .SUFFIXES: # build the objects -%.o: %.c $(HOST_PROGS) $(GEN_HEADERS) +%.o: %.c $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ # "Static Pattern Rule" to build all programs -$(PROGRAMS): %: $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(LIBSYSFS) $(LIBUDEV) %.o - $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) +$(PROGRAMS): %: $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(LIBUDEV) %.o + $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(STRIPCMD),) $(QUIET) $(STRIPCMD) $@ endif -$(UDEV_OBJS): $(LIBUDEV): $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS) @rm -f $@ $(QUIET) $(AR) cq $@ $(UDEV_OBJS) $(QUIET) $(RANLIB) $@ -$(SYSFS_OBJS): -$(LIBSYSFS): $(HOST_PROGS) $(SYSFS_OBJS) - @rm -f $@ - $(QUIET) $(AR) cq $@ $(SYSFS_OBJS) - $(QUIET) $(RANLIB) $@ - # generate config files $(GEN_CONFIGS): sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $@.in > $@ diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 4e3570205e..623ea0ed60 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,5 +1,11 @@ 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 @@ -10,6 +16,8 @@ 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. diff --git a/docs/udev.xml b/docs/udev.xml index e87dbab880..7f6a30df52 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -361,13 +361,6 @@ - - , - - The kernel bus id for this device. - - - , diff --git a/docs/udevtest.xml b/docs/udevtest.xml index ceea0413c5..2b39eebab0 100644 --- a/docs/udevtest.xml +++ b/docs/udevtest.xml @@ -37,7 +37,7 @@ - udevtest device-path subsystem + udevtest device-path diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index ebf0f4e9b4..0a881fb194 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(STRIPCMD),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/ata_id/ata_id.c b/extras/ata_id/ata_id.c index a97cc284cc..aedebff711 100644 --- a/extras/ata_id/ata_id.c +++ b/extras/ata_id/ata_id.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -24,8 +25,7 @@ #include #include -#include "../../logging.h" -#include "../../udev_utils.h" +#include "../../udev.h" #ifdef USE_LOG void log_message(int priority, const char *format, ...) diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index 985eb805a5..9a722d52f9 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index ff6f89e163..0d4a8c10f0 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -18,14 +18,14 @@ #include #include #include +#include #include #include #include #include #include -#include "../../logging.h" -#include "../../udev_utils.h" +#include "../../udev.h" /* * Taken from the cdrom.h kernel include file. diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index 80680f22fe..79f14a49ba 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/dasd_id/dasd_id.c b/extras/dasd_id/dasd_id.c index ca2582cde6..b2496e99f8 100644 --- a/extras/dasd_id/dasd_id.c +++ b/extras/dasd_id/dasd_id.c @@ -24,8 +24,7 @@ #include #include -#include "../../logging.h" -#include "../../udev_utils.h" +#include "../../udev.h" #ifdef USE_LOG void log_message(int priority, const char *format, ...) diff --git a/extras/edd_id/Makefile b/extras/edd_id/Makefile index 5a6cdb65c3..db6afae18c 100644 --- a/extras/edd_id/Makefile +++ b/extras/edd_id/Makefile @@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/edd_id/edd_id.c b/extras/edd_id/edd_id.c index f21362b902..8fc690a49c 100644 --- a/extras/edd_id/edd_id.c +++ b/extras/edd_id/edd_id.c @@ -18,12 +18,12 @@ #include #include #include +#include #include #include #include -#include "../../logging.h" -#include "../../udev_utils.h" +#include "../../udev.h" #ifdef USE_LOG void log_message(int priority, const char *format, ...) diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index 16918867fc..da7fe9d1a8 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/firmware/firmware_helper.c b/extras/firmware/firmware_helper.c index 2bc6b50f06..ca1c43814f 100644 --- a/extras/firmware/firmware_helper.c +++ b/extras/firmware/firmware_helper.c @@ -17,8 +17,7 @@ #include #include -#include "../../udev_utils.h" -#include "../../logging.h" +#include "../../udev.h" #define FIRMWARE_PATH "/lib/firmware" #define PATH_SIZE 256 diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index 240af4ce05..e23191a533 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index d138f62c03..37a59597b9 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -32,7 +32,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/run_directory/run_directory.c b/extras/run_directory/run_directory.c index 69faecc15e..c715ca6bd3 100644 --- a/extras/run_directory/run_directory.c +++ b/extras/run_directory/run_directory.c @@ -22,9 +22,7 @@ #include #include -#include "../../udev_utils.h" -#include "../../list.h" -#include "../../logging.h" +#include "../../udev.h" #include "run_directory.h" static int exec_program(const char *filename, const char *subsystem) diff --git a/extras/run_directory/udev_run_devd.c b/extras/run_directory/udev_run_devd.c index e708de8aa4..59ea766ac2 100644 --- a/extras/run_directory/udev_run_devd.c +++ b/extras/run_directory/udev_run_devd.c @@ -22,9 +22,7 @@ #include #include -#include "../../udev_utils.h" -#include "../../list.h" -#include "../../logging.h" +#include "../../udev.h" #include "run_directory.h" diff --git a/extras/run_directory/udev_run_hotplugd.c b/extras/run_directory/udev_run_hotplugd.c index a21835ae4e..bfa82ab917 100644 --- a/extras/run_directory/udev_run_hotplugd.c +++ b/extras/run_directory/udev_run_hotplugd.c @@ -22,9 +22,7 @@ #include #include -#include "../../udev_utils.h" -#include "../../list.h" -#include "../../logging.h" +#include "../../udev.h" #include "run_directory.h" diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 399de76911..057594d5bf 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -29,7 +29,6 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} # be able to run without udev -LIBSYSFS = -lsysfs CROSS = QUIET = CC = $(CROSS)gcc @@ -47,7 +46,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index aa1b16009e..3a4a374d3e 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -32,37 +32,20 @@ #include #include #include -#include -#include "scsi_id_version.h" + +#include "../../udev.h" #include "scsi_id.h" +#include "scsi_id_version.h" -#ifndef SCSI_ID_VERSION -#warning No version -#define SCSI_ID_VERSION "unknown" -#endif +/* temporary names for mknod */ +#define TMP_DIR "/dev" +#define TMP_PREFIX "tmp-scsi" -/* - * temporary names for mknod. - */ -#define TMP_DIR "/dev" -#define TMP_PREFIX "tmp-scsi" - -/* - * XXX Note the 'e' (send output to stderr in all cases), and 'c' (callout) - * options are not supported, but other code is still left in place for - * now. - */ static const char short_options[] = "abd:f:gip:s:uvVx"; -/* - * Just duplicate per dev options. - */ static const char dev_short_options[] = "bgp:"; -char sysfs_mnt_path[SYSFS_PATH_MAX]; - static int all_good; static int always_info; -static char *default_callout; static int dev_specified; static int sys_specified; static char config_file[MAX_NAME_LEN] = SCSI_ID_CONFIG_FILE; @@ -78,28 +61,30 @@ static char model_str[64]; static char revision_str[16]; static char type_str[16]; -void log_message (int level, const char *format, ...) +#ifdef USE_LOG +void log_message(int priority, const char *format, ...) { - va_list args; + va_list args; + static int udev_log = -1; - if (!debug && level == LOG_DEBUG) + 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); - if (!hotplug_mode || use_stderr) { - vfprintf(stderr, format, args); - } else { - static int logging_init = 0; - if (!logging_init) { - openlog ("scsi_id", LOG_PID, LOG_DAEMON); - logging_init = 1; - } - - vsyslog(level, format, args); - } - va_end (args); - 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) { @@ -171,68 +156,35 @@ static void set_type(char *to, const char *from, size_t len) to[len-1] = '\0'; } -static int get_major_minor(struct sysfs_class_device *class_dev, int *maj, - int *min) +static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) { - struct sysfs_attribute *dev_attr; + unsigned int maj, min; + const char *attr; - dev_attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (!dev_attr) { - /* - * XXX This happens a lot, since sg has no dev attr. - * And now sysfsutils does not set a meaningful errno - * value. Someday change this back to a LOG_WARNING. - * And if sysfsutils changes, check for ENOENT and handle - * it separately. - */ - log_message(LOG_DEBUG, "%s: could not get dev attribute: %s\n", - class_dev->name, strerror(errno)); + 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; } - dprintf("dev value %s", dev_attr->value); /* value has a trailing \n */ - if (sscanf(dev_attr->value, "%u:%u", maj, min) != 2) { - log_message(LOG_WARNING, "%s: invalid dev major/minor\n", - class_dev->name); + dbg("dev value %s", attr); + if (sscanf(attr, "%u:%u", &maj, &min) != 2) { + err("%s: invalid dev major/minor", devpath); return -1; } - return 0; -} - -static int create_tmp_dev(struct sysfs_class_device *class_dev, char *tmpdev, - int dev_type) -{ - int maj, min; - - dprintf("(%s)\n", class_dev->name); - - if (get_major_minor(class_dev, &maj, &min)) - return -1; snprintf(tmpdev, MAX_NAME_LEN, "%s/%s-maj%d-min%d-%u", TMP_DIR, TMP_PREFIX, maj, min, getpid()); - dprintf("tmpdev '%s'\n", tmpdev); - + dbg("tmpdev '%s'", tmpdev); if (mknod(tmpdev, 0600 | dev_type, makedev(maj, min))) { - log_message(LOG_WARNING, "mknod failed: %s\n", strerror(errno)); + err("mknod failed: %s", strerror(errno)); return -1; } return 0; } -static int has_sysfs_prefix(const char *path, const char *prefix) -{ - char match[MAX_NAME_LEN]; - - strncpy(match, sysfs_mnt_path, MAX_NAME_LEN); - strncat(match, prefix, MAX_NAME_LEN); - if (strncmp(path, match, strlen(match)) == 0) - return 1; - else - return 0; -} - /* * get_value: * @@ -289,8 +241,8 @@ static int argc_count(char *opts) * * vendor and model can end in '\n'. */ -static int get_file_options(char *vendor, char *model, int *argc, - char ***newargv) +static int get_file_options(const char *vendor, const char *model, + int *argc, char ***newargv) { char *buffer; FILE *fd; @@ -301,15 +253,14 @@ static int get_file_options(char *vendor, char *model, int *argc, int c; int retval = 0; - dprintf("vendor='%s'; model='%s'\n", vendor, model); + dbg("vendor='%s'; model='%s'\n", vendor, model); fd = fopen(config_file, "r"); if (fd == NULL) { - dprintf("can't open %s\n", config_file); + dbg("can't open %s\n", config_file); if (errno == ENOENT) { return 1; } else { - log_message(LOG_WARNING, "can't open %s: %s\n", - config_file, strerror(errno)); + err("can't open %s: %s", config_file, strerror(errno)); return -1; } } @@ -321,7 +272,7 @@ static int get_file_options(char *vendor, char *model, int *argc, */ buffer = malloc(MAX_BUFFER_LEN); if (!buffer) { - log_message(LOG_WARNING, "Can't allocate memory.\n"); + err("Can't allocate memory."); return -1; } @@ -335,29 +286,22 @@ static int get_file_options(char *vendor, char *model, int *argc, break; lineno++; if (buf[strlen(buffer) - 1] != '\n') { - log_message(LOG_WARNING, - "Config file line %d too long.\n", lineno); + info("Config file line %d too long.\n", lineno); break; } while (isspace(*buf)) buf++; + /* blank or all whitespace line */ if (*buf == '\0') - /* - * blank or all whitespace line - */ continue; + /* comment line */ if (*buf == '#') - /* - * comment line - */ continue; -#ifdef LOTS - dprintf("lineno %d: '%s'\n", lineno, buf); -#endif + dbg("lineno %d: '%s'\n", lineno, buf); str1 = strsep(&buf, "="); if (str1 && strcasecmp(str1, "VENDOR") == 0) { str1 = get_value(&buf); @@ -387,22 +331,20 @@ static int get_file_options(char *vendor, char *model, int *argc, } options_in = str1; } - dprintf("config file line %d:" + 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)) { - log_message(LOG_WARNING, - "Error parsing config file line %d '%s'\n", - lineno, buffer); + info("Error parsing config file line %d '%s'", lineno, buffer); retval = -1; break; } if (vendor == NULL) { if (vendor_in == NULL) { - dprintf("matched global option\n"); + dbg("matched global option\n"); break; } } else if ((vendor_in && strncmp(vendor, vendor_in, @@ -416,10 +358,10 @@ static int get_file_options(char *vendor, char *model, int *argc, * give a partial match (that is FOO * matches FOOBAR). */ - dprintf("matched vendor/model\n"); + dbg("matched vendor/model\n"); break; } else { - dprintf("no match\n"); + dbg("no match\n"); } } @@ -434,8 +376,7 @@ static int get_file_options(char *vendor, char *model, int *argc, c = argc_count(buffer) + 2; *newargv = calloc(c, sizeof(**newargv)); if (!*newargv) { - log_message(LOG_WARNING, - "Can't allocate memory.\n"); + err("Can't allocate memory."); retval = -1; } else { *argc = c; @@ -450,9 +391,7 @@ static int get_file_options(char *vendor, char *model, int *argc, (*newargv)[c] = strsep(&buffer, " "); } } else { - /* - * No matches. - */ + /* No matches */ retval = 1; } } @@ -480,9 +419,9 @@ static int set_options(int argc, char **argv, const char *short_opts, break; if (optarg) - dprintf("option '%c' arg '%s'\n", option, optarg); + dbg("option '%c' arg '%s'\n", option, optarg); else - dprintf("option '%c'\n", option); + dbg("option '%c'\n", option); switch (option) { case 'a': @@ -492,10 +431,6 @@ static int set_options(int argc, char **argv, const char *short_opts, all_good = 0; break; - case 'c': - default_callout = optarg; - break; - case 'd': dev_specified = 1; strncpy(maj_min_dev, optarg, MAX_NAME_LEN); @@ -525,16 +460,15 @@ static int set_options(int argc, char **argv, const char *short_opts, } else if (strcmp(optarg, "pre-spc3-83") == 0) { default_page_code = PAGE_83_PRE_SPC3; } else { - log_message(LOG_WARNING, - "Unknown page code '%s'\n", optarg); + info("Unknown page code '%s'", optarg); return -1; } break; case 's': sys_specified = 1; - strncpy(target, sysfs_mnt_path, MAX_NAME_LEN); - strncat(target, optarg, MAX_NAME_LEN); + strncpy(target, optarg, MAX_NAME_LEN); + target[MAX_NAME_LEN-1] = '\0'; break; case 'u': @@ -550,71 +484,58 @@ static int set_options(int argc, char **argv, const char *short_opts, break; case 'V': - log_message(LOG_WARNING, "scsi_id version: %s\n", - SCSI_ID_VERSION); + info("scsi_id version: %s\n", SCSI_ID_VERSION); exit(0); break; default: - log_message(LOG_WARNING, - "Unknown or bad option '%c' (0x%x)\n", - option, option); + info("Unknown or bad option '%c' (0x%x)", option, option); return -1; } } return 0; } -static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, - int *page_code, char *callout) +static int per_dev_options(struct sysfs_device *dev_scsi, int *good_bad, int *page_code) { int retval; int newargc; char **newargv = NULL; - struct sysfs_attribute *vendor, *model, *type; + const char *vendor, *model, *type; int option; *good_bad = all_good; *page_code = default_page_code; - if (default_callout && (callout != default_callout)) - strncpy(callout, default_callout, MAX_NAME_LEN); - else - callout[0] = '\0'; - vendor = sysfs_get_device_attr(scsi_dev, "vendor"); + vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); if (!vendor) { - log_message(LOG_WARNING, "%s: cannot get vendor attribute\n", - scsi_dev->name); + info("%s: cannot get vendor attribute", dev_scsi->devpath); return -1; } - set_str(vendor_str, vendor->value, sizeof(vendor_str)-1); + set_str(vendor_str, vendor, sizeof(vendor_str)-1); - model = sysfs_get_device_attr(scsi_dev, "model"); + model = sysfs_attr_get_value(dev_scsi->devpath, "model"); if (!model) { - log_message(LOG_WARNING, "%s: cannot get model attribute\n", - scsi_dev->name); + info("%s: cannot get model attribute\n", dev_scsi->devpath); return -1; } - set_str(model_str, model->value, sizeof(model_str)-1); + set_str(model_str, model, sizeof(model_str)-1); - type = sysfs_get_device_attr(scsi_dev, "type"); + type = sysfs_attr_get_value(dev_scsi->devpath, "type"); if (!type) { - log_message(LOG_WARNING, "%s: cannot get type attribute\n", - scsi_dev->name); + info("%s: cannot get type attribute", dev_scsi->devpath); return -1; } - set_type(type_str, type->value, sizeof(type_str)); + set_type(type_str, type, sizeof(type_str)); - type = sysfs_get_device_attr(scsi_dev, "rev"); + type = sysfs_attr_get_value(dev_scsi->devpath, "rev"); if (!type) { - log_message(LOG_WARNING, "%s: cannot get type attribute\n", - scsi_dev->name); + info("%s: cannot get type attribute\n", dev_scsi->devpath); return -1; } - set_str(revision_str, type->value, sizeof(revision_str)-1); + set_str(revision_str, type, sizeof(revision_str)-1); - retval = get_file_options(vendor->value, model->value, &newargc, - &newargv); + retval = get_file_options(vendor, model, &newargc, &newargv); optind = 1; /* reset this global extern */ while (retval == 0) { @@ -623,19 +544,15 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, break; if (optarg) - dprintf("option '%c' arg '%s'\n", option, optarg); + dbg("option '%c' arg '%s'\n", option, optarg); else - dprintf("option '%c'\n", option); + dbg("option '%c'\n", option); switch (option) { case 'b': *good_bad = 0; break; - case 'c': - strncpy(callout, default_callout, MAX_NAME_LEN); - break; - case 'g': *good_bad = 1; break; @@ -648,16 +565,13 @@ static int per_dev_options(struct sysfs_device *scsi_dev, int *good_bad, } else if (strcmp(optarg, "pre-spc3-83") == 0) { *page_code = PAGE_83_PRE_SPC3; } else { - log_message(LOG_WARNING, - "Unknown page code '%s'\n", optarg); + info("Unknown page code '%s'", optarg); retval = -1; } break; default: - log_message(LOG_WARNING, - "Unknown or bad option '%c' (0x%x)\n", - option, option); + info("Unknown or bad option '%c' (0x%x)", option, option); retval = -1; break; } @@ -702,129 +616,62 @@ static void format_serial(char *serial) * 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 *target_path, char *maj_min_dev) +static int scsi_id(const char *devpath, char *maj_min_dev) { int retval; int dev_type = 0; char *serial, *unaligned_buf; - struct sysfs_class_device *class_dev; /* of target_path */ - struct sysfs_class_device *class_dev_parent; /* for partitions */ - struct sysfs_device *scsi_dev; /* the scsi_device */ + struct sysfs_device *dev; + struct sysfs_device *dev_scsi; int good_dev; int page_code; - char callout[MAX_NAME_LEN]; - dprintf("target_path %s\n", target_path); + dbg("devpath %s\n", devpath); - /* - * Ugly: depend on the sysfs path to tell us whether this is a - * block or char device. This should probably be encoded in the - * "dev" along with the major/minor. - */ - if (has_sysfs_prefix(target_path, "/block")) { + 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 if (has_sysfs_prefix(target_path, "/class")) { + else dev_type = S_IFCHR; - } else { - if (!hotplug_mode) { - log_message(LOG_WARNING, - "Non block or class device '%s'\n", - target_path); - return 1; - } else { - /* - * Expected in some cases. - */ - dprintf("Non block or class device\n"); - return 0; - } - } - class_dev = sysfs_open_class_device_path(target_path); - if (!class_dev) { - log_message(LOG_WARNING, "open class %s failed: %s\n", - target_path, strerror(errno)); - return 1; - } - class_dev_parent = sysfs_get_classdev_parent(class_dev); - dprintf("class_dev 0x%p; class_dev_parent 0x%p\n", class_dev, - class_dev_parent); - if (class_dev_parent) { - scsi_dev = sysfs_get_classdev_device(class_dev_parent); - } else { - scsi_dev = sysfs_get_classdev_device(class_dev); - } - - /* - * The close of scsi_dev will close class_dev or class_dev_parent. - */ - - /* - * We assume we are called after the device is completely ready, - * so we don't have to loop here like udev. (And we are usually - * called via udev.) - */ - if (!scsi_dev) { - /* - * errno is not set if we can't find the device link, so - * don't print it out here. - */ - log_message(LOG_WARNING, "Cannot find sysfs device associated with %s\n", - target_path); + /* get scsi parent device */ + dev_scsi = sysfs_device_get_parent(dev); + if (dev_scsi == NULL) { + err("unable to access parent device of '%s'", devpath); return 1; } - - /* - * Allow only scsi devices. - * - * Other block devices can support SG IO, but only ide-cd does, so - * for now, don't bother with anything else. - */ - if (strcmp(scsi_dev->bus, "scsi") != 0) { - if (hotplug_mode) - /* - * Expected in some cases. - */ - dprintf("%s is not a scsi device\n", target_path); - else - log_message(LOG_WARNING, "%s is not a scsi device\n", - target_path); + /* allow only scsi devices */ + if (strcmp(dev_scsi->subsystem, "scsi") != 0) { + info("%s is not a scsi device", devpath); return 1; } - /* - * mknod a temp dev to communicate with the device. - */ - if (!dev_specified && create_tmp_dev(class_dev, maj_min_dev, - dev_type)) { - dprintf("create_tmp_dev failed\n"); + /* 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; } - /* - * Get any per device (vendor + model) options from the config - * file. - */ - retval = per_dev_options(scsi_dev, &good_dev, &page_code, callout); - dprintf("per dev options: good %d; page code 0x%x; callout '%s'\n", - good_dev, page_code, callout); + /* 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); #define ALIGN 512 unaligned_buf = malloc(MAX_SERIAL_LEN + ALIGN); serial = (char*) (((unsigned long) unaligned_buf + (ALIGN - 1)) & ~(ALIGN - 1)); - dprintf("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial); + dbg("buffer unaligned 0x%p; aligned 0x%p\n", unaligned_buf, serial); #undef ALIGN if (!good_dev) { retval = 1; - } else if (callout[0] != '\0') { - /* - * XXX Disabled for now ('c' is not in any options[]). - */ - retval = 1; - } else if (scsi_get_serial(scsi_dev, maj_min_dev, page_code, + } else if (scsi_get_serial(dev_scsi, maj_min_dev, page_code, serial, MAX_SERIAL_LEN)) { retval = always_info?0:1; } else { @@ -844,13 +691,12 @@ static int scsi_id(const char *target_path, char *maj_min_dev) if (reformat_serial) format_serial(serial); if (display_bus_id) - printf("%s: ", scsi_dev->name); + printf("%s: ", dev_scsi->kernel_name); printf("%s\n", serial); } - dprintf("%s\n", serial); + dbg("%s\n", serial); retval = 0; } - sysfs_close_device(scsi_dev); if (!dev_specified) unlink(maj_min_dev); @@ -860,32 +706,31 @@ static int scsi_id(const char *target_path, char *maj_min_dev) int main(int argc, char **argv) { - int retval; - char *devpath; - char target_path[MAX_NAME_LEN]; + int retval = 0; + char devpath[MAX_NAME_LEN]; char maj_min_dev[MAX_NAME_LEN]; int newargc; + const char *env; char **newargv; - if (getenv("DEBUG")) - debug++; + logging_init("scsi_id"); + sysfs_init(); + dbg("argc is %d\n", argc); - dprintf("argc is %d\n", argc); - if (sysfs_get_mnt_path(sysfs_mnt_path, MAX_NAME_LEN)) { - log_message(LOG_WARNING, "sysfs_get_mnt_path failed: %s\n", - strerror(errno)); - exit(1); - } + /* 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"); - devpath = getenv("DEVPATH"); - if (devpath) { - /* - * This implies that we were invoked via udev or hotplug. - */ + env = getenv("DEVPATH"); + if (env) { hotplug_mode = 1; sys_specified = 1; - strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); - strncat(target_path, devpath, MAX_NAME_LEN); + strncpy(devpath, env, MAX_NAME_LEN); + devpath[sizeof(devpath)-1] = '\0'; } /* @@ -894,26 +739,35 @@ int main(int argc, char **argv) newargv = NULL; retval = get_file_options(NULL, NULL, &newargc, &newargv); if (retval < 0) { - exit(1); - } else if (newargv && (retval == 0)) { - if (set_options(newargc, newargv, short_options, target_path, - maj_min_dev) < 0) - exit(1); + 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, target_path, - maj_min_dev) < 0) + if (set_options(argc, argv, short_options, devpath, maj_min_dev) < 0) exit(1); if (!sys_specified) { - log_message(LOG_WARNING, "-s must be specified\n"); - exit(1); + info("-s must be specified\n"); + retval = 1; + goto exit; } - retval = scsi_id(target_path, maj_min_dev); - exit(retval); + retval = scsi_id(devpath, maj_min_dev); + +exit: + sysfs_cleanup(); + logging_close(); + return retval; } diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 1c9ed969a7..b5312b8988 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -21,9 +21,6 @@ * USA */ -#define dprintf(format, arg...) \ - log_message(LOG_DEBUG, "%s: " format, __FUNCTION__ , ## arg) - #define MAX_NAME_LEN 72 /* @@ -44,15 +41,8 @@ */ #define MAX_BUFFER_LEN 256 -extern int scsi_get_serial (struct sysfs_device *scsi_dev, const char - *devname, int page_code, char *serial, int - len); -extern void log_message (int level, const char *format, ...) - __attribute__ ((format (printf, 2, 3))); - -#ifndef u8 -typedef unsigned char u8; -#endif +extern int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, + int page_code, char *serial, int len); /* * Page code values. diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index 14955e676c..bdebe94eb3 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -30,11 +30,12 @@ #include #include #include -#include /* need __user when built via klibc */ #include -#include -#include "scsi_id.h" + +#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 @@ -75,23 +76,21 @@ static const char hex_str[]="0123456789abcdef"; * 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 */ +#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 */ +#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 @@ -157,7 +156,7 @@ static int sg_err_category3(struct sg_io_hdr *hp) hp->sbp, hp->sb_len_wr); } -static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) +static int scsi_dump_sense(struct sysfs_device *dev_scsi, struct sg_io_hdr *io) { unsigned char *sense_buffer; int s; @@ -184,12 +183,11 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) * we'll retry the command. */ - dprintf("got check condition\n"); + dbg("got check condition\n"); sb_len = io->sb_len_wr; if (sb_len < 1) { - log_message(LOG_WARNING, "%s: sense buffer empty\n", - scsi_dev->name); + info("%s: sense buffer empty", dev_scsi->kernel_name); return -1; } @@ -203,10 +201,8 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) */ s = sense_buffer[7] + 8; if (sb_len < s) { - log_message(LOG_WARNING, - "%s: sense buffer too small %d bytes," - " %d bytes too short\n", scsi_dev->name, - sb_len, s - sb_len); + info("%s: sense buffer too small %d bytes, %d bytes too short", + dev_scsi->kernel_name, sb_len, s - sb_len); return -1; } if ((code == 0x0) || (code == 0x1)) { @@ -216,9 +212,8 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) /* * Possible? */ - log_message(LOG_WARNING, "%s: sense result too" - " small %d bytes\n", - scsi_dev->name, s); + info("%s: sense result too" " small %d bytes", + dev_scsi->kernel_name, s); return -1; } asc = sense_buffer[12]; @@ -229,72 +224,64 @@ static int scsi_dump_sense(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) asc = sense_buffer[2]; ascq = sense_buffer[3]; } else { - log_message(LOG_WARNING, - "%s: invalid sense code 0x%x\n", - scsi_dev->name, code); + info("%s: invalid sense code 0x%x", + dev_scsi->kernel_name, code); return -1; } - log_message(LOG_WARNING, - "%s: sense key 0x%x ASC 0x%x ASCQ 0x%x\n", - scsi_dev->name, sense_key, asc, ascq); + info("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x", + dev_scsi->kernel_name, sense_key, asc, ascq); } else { if (sb_len < 4) { - log_message(LOG_WARNING, - "%s: sense buffer too small %d bytes, %d bytes too short\n", - scsi_dev->name, sb_len, 4 - sb_len); + info("%s: sense buffer too small %d bytes, %d bytes too short", + dev_scsi->kernel_name, sb_len, 4 - sb_len); return -1; } if (sense_buffer[0] < 15) - log_message(LOG_WARNING, "%s: old sense key: 0x%x\n", - scsi_dev->name, sense_buffer[0] & 0x0f); + info("%s: old sense key: 0x%x", dev_scsi->kernel_name, sense_buffer[0] & 0x0f); else - log_message(LOG_WARNING, "%s: sense = %2x %2x\n", - scsi_dev->name, sense_buffer[0], - sense_buffer[2]); - log_message(LOG_WARNING, - "%s: non-extended sense class %d code 0x%0x\n", - scsi_dev->name, sense_class, code); + info("%s: sense = %2x %2x", + dev_scsi->kernel_name, sense_buffer[0], sense_buffer[2]); + info("%s: non-extended sense class %d code 0x%0x", + dev_scsi->kernel_name, sense_class, code); } #ifdef DUMP_SENSE for (i = 0, j = 0; (i < s) && (j < 254); i++) { - dprintf("i %d, j %d\n", i, j); + 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'; - log_message(LOG_WARNING, "%s: sense dump:\n", scsi_dev->name); - log_message(LOG_WARNING, "%s: %s\n", scsi_dev->name, out_buffer); + info("%s: sense dump:", dev_scsi->kernel_name); + info("%s: %s", dev_scsi->kernel_name, out_buffer); #endif return -1; } -static int scsi_dump(struct sysfs_device *scsi_dev, struct sg_io_hdr *io) +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. */ - log_message(LOG_WARNING, "%s: called with no error\n", - __FUNCTION__); + info("%s: called with no error", __FUNCTION__); return -1; } - log_message(LOG_WARNING, "%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x\n", - scsi_dev->name, io->driver_status, io->host_status, - io->msg_status, io->status); + info("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x", + dev_scsi->kernel_name, io->driver_status, io->host_status, io->msg_status, io->status); if (io->status == SCSI_CHECK_CONDITION) - return scsi_dump_sense(scsi_dev, io); + return scsi_dump_sense(dev_scsi, io); else return -1; } -static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd, +static int scsi_inquiry(struct sysfs_device *dev_scsi, int fd, unsigned char evpd, unsigned char page, unsigned char *buf, unsigned int buflen) { @@ -306,12 +293,12 @@ static int scsi_inquiry(struct sysfs_device *scsi_dev, int fd, int retry = 3; /* rather random */ if (buflen > SCSI_INQ_BUFF_LEN) { - log_message(LOG_WARNING, "buflen %d too long\n", buflen); + info("buflen %d too long", buflen); return -1; } resend: - dprintf("%s evpd %d, page 0x%x\n", scsi_dev->name, evpd, page); + dbg("%s evpd %d, page 0x%x\n", dev_scsi->kernel_name, evpd, page); memset(&io_hdr, 0, sizeof(struct sg_io_hdr)); io_hdr.interface_id = 'S'; @@ -325,8 +312,7 @@ resend: io_hdr.timeout = DEF_TIMEOUT; if (ioctl(fd, SG_IO, &io_hdr) < 0) { - log_message(LOG_WARNING, "%s: ioctl failed: %s\n", - scsi_dev->name, strerror(errno)); + info("%s: ioctl failed: %s", dev_scsi->kernel_name, strerror(errno)); retval = -1; goto error; } @@ -343,14 +329,14 @@ resend: break; default: - retval = scsi_dump(scsi_dev, &io_hdr); + retval = scsi_dump(dev_scsi, &io_hdr); } if (!retval) { retval = buflen; } else if (retval > 0) { if (--retry > 0) { - dprintf("%s: Retrying ...\n", scsi_dev->name); + dbg("%s: Retrying ...\n", dev_scsi->kernel_name); goto resend; } retval = -1; @@ -358,33 +344,30 @@ resend: error: if (retval < 0) - log_message(LOG_WARNING, - "%s: Unable to get INQUIRY vpd %d page 0x%x.\n", - scsi_dev->name, evpd, page); + info("%s: Unable to get INQUIRY vpd %d page 0x%x.", + dev_scsi->kernel_name, evpd, page); return retval; } /* Get list of supported EVPD pages */ -static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, +static int do_scsi_page0_inquiry(struct sysfs_device *dev_scsi, int fd, unsigned char *buffer, unsigned int len) { int retval; - struct sysfs_attribute *vendor; + const char *vendor; memset(buffer, 0, len); - retval = scsi_inquiry(scsi_dev, fd, 1, 0x0, buffer, len); + retval = scsi_inquiry(dev_scsi, fd, 1, 0x0, buffer, len); if (retval < 0) return 1; if (buffer[1] != 0) { - log_message(LOG_WARNING, "%s: page 0 not available.\n", - scsi_dev->name); + info("%s: page 0 not available.", dev_scsi->kernel_name); return 1; } if (buffer[3] > len) { - log_message(LOG_WARNING, "%s: page 0 buffer too long %d\n", - scsi_dev->name, buffer[3]); + info("%s: page 0 buffer too long %d", dev_scsi->kernel_name, buffer[3]); return 1; } @@ -400,17 +383,13 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, * If the vendor id appears in the page assume the page is * invalid. */ - vendor = sysfs_get_device_attr(scsi_dev, "vendor"); + vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); if (!vendor) { - log_message(LOG_WARNING, - "%s: cannot get model attribute\n", - scsi_dev->name); + info("%s: cannot get model attribute", dev_scsi->kernel_name); return 1; } - if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor->value, - VENDOR_LENGTH)) { - log_message(LOG_WARNING, "%s: invalid page0 data\n", - scsi_dev->name); + if (!strncmp((char *)&buffer[VENDOR_LENGTH], vendor, VENDOR_LENGTH)) { + info("%s: invalid page0 data", dev_scsi->kernel_name); return 1; } } @@ -421,46 +400,35 @@ static int do_scsi_page0_inquiry(struct sysfs_device *scsi_dev, int fd, * The caller checks that serial is long enough to include the vendor + * model. */ -static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial) +static int prepend_vendor_model(struct sysfs_device *dev_scsi, char *serial) { - struct sysfs_attribute *attr; + const char *attr; int ind; - attr = sysfs_get_device_attr(scsi_dev, "vendor"); + attr = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); if (!attr) { - log_message(LOG_WARNING, "%s: cannot get vendor attribute\n", - scsi_dev->name); + info("%s: cannot get vendor attribute", dev_scsi->kernel_name); return 1; } - strncpy(serial, attr->value, VENDOR_LENGTH); + strncpy(serial, attr, VENDOR_LENGTH); ind = strlen(serial) - 1; - /* - * Remove sysfs added newlines. - */ - if (serial[ind] == '\n') - serial[ind] = '\0'; - attr = sysfs_get_device_attr(scsi_dev, "model"); + attr = sysfs_attr_get_value(dev_scsi->devpath, "model"); if (!attr) { - log_message(LOG_WARNING, "%s: cannot get model attribute\n", - scsi_dev->name); + info("%s: cannot get model attribute", dev_scsi->kernel_name); return 1; } - strncat(serial, attr->value, MODEL_LENGTH); + strncat(serial, attr, MODEL_LENGTH); ind = strlen(serial) - 1; - if (serial[ind] == '\n') - serial[ind] = '\0'; - else - ind++; + 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)) { - log_message(LOG_WARNING, "%s: expected length %d, got length %d\n", - scsi_dev->name, (VENDOR_LENGTH + MODEL_LENGTH), - ind); + info("%s: expected length %d, got length %d", + dev_scsi->kernel_name, (VENDOR_LENGTH + MODEL_LENGTH), ind); return 1; } return ind; @@ -470,7 +438,7 @@ static int prepend_vendor_model(struct sysfs_device *scsi_dev, char *serial) * 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 *scsi_dev, +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, int max_len) @@ -517,8 +485,8 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev, len += VENDOR_LENGTH + MODEL_LENGTH; if (max_len < len) { - log_message(LOG_WARNING, "%s: length %d too short - need %d\n", - scsi_dev->name, max_len, len); + info("%s: length %d too short - need %d", + dev_scsi->kernel_name, max_len, len); return 1; } @@ -531,8 +499,8 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev, * included in the identifier. */ if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC) - if (prepend_vendor_model(scsi_dev, &serial[1]) < 0) { - dprintf("prepend failed\n"); + if (prepend_vendor_model(dev_scsi, &serial[1]) < 0) { + dbg("prepend failed\n"); return 1; } @@ -559,7 +527,7 @@ static int check_fill_0x83_id(struct sysfs_device *scsi_dev, } /* Extract the raw binary from VPD 0x83 pre-SPC devices */ -static int check_fill_0x83_prespc3(struct sysfs_device *scsi_dev, +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, int max_len) @@ -574,13 +542,13 @@ static int check_fill_0x83_prespc3(struct sysfs_device *scsi_dev, serial[j++] = hex_str[(page_83[4+i] & 0xf0) >> 4]; serial[j++] = hex_str[ page_83[4+i] & 0x0f]; } - dprintf("using pre-spc3-83 for %s.\n", scsi_dev->name); + dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name); return 0; } /* Get device identification VPD page */ -static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, +static int do_scsi_page83_inquiry(struct sysfs_device *dev_scsi, int fd, char *serial, int len) { int retval; @@ -588,14 +556,13 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned char page_83[SCSI_INQ_BUFF_LEN]; memset(page_83, 0, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_83, page_83, + 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) { - log_message(LOG_WARNING, "%s: Invalid page 0x83\n", - scsi_dev->name); + info("%s: Invalid page 0x83", dev_scsi->kernel_name); return 1; } @@ -629,7 +596,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, */ if (page_83[6] != 0) - return check_fill_0x83_prespc3(scsi_dev, page_83, + return check_fill_0x83_prespc3(dev_scsi, page_83, id_search_list, serial, len); /* @@ -643,21 +610,21 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, * 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(scsi_dev, &page_83[j], + retval = check_fill_0x83_id(dev_scsi, &page_83[j], &id_search_list[id_ind], serial, len); - dprintf("%s id desc %d/%d/%d\n", scsi_dev->name, + dbg("%s id desc %d/%d/%d\n", dev_scsi->kernel_name, id_search_list[id_ind].id_type, id_search_list[id_ind].naa_type, id_search_list[id_ind].code_set); if (!retval) { - dprintf(" used\n"); + dbg(" used\n"); return retval; } else if (retval < 0) { - dprintf(" failed\n"); + dbg(" failed\n"); return retval; } else { - dprintf(" not used\n"); + dbg(" not used\n"); } } } @@ -671,7 +638,7 @@ static int do_scsi_page83_inquiry(struct sysfs_device *scsi_dev, int fd, * 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 *scsi_dev, int fd, +static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *dev_scsi, int fd, char *serial, int len) { int retval; @@ -679,12 +646,12 @@ static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned char page_83[SCSI_INQ_BUFF_LEN]; memset(page_83, 0, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_83, page_83, 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) { - log_message(LOG_WARNING, "%s: Invalid page 0x83\n", scsi_dev->name); + info("%s: Invalid page 0x83", dev_scsi->kernel_name); return 1; } /* @@ -728,12 +695,12 @@ static int do_scsi_page83_prespc3_inquiry(struct sysfs_device *scsi_dev, int fd, serial[j++] = hex_str[page_83[i] & 0x0f]; i++; } - dprintf("using pre-spc3-83 for %s.\n", scsi_dev->name); + dbg("using pre-spc3-83 for %s.\n", dev_scsi->kernel_name); return 0; } /* Get unit serial number VPD page */ -static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, +static int do_scsi_page80_inquiry(struct sysfs_device *dev_scsi, int fd, char *serial, int max_len) { int retval; @@ -743,20 +710,19 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, unsigned char buf[SCSI_INQ_BUFF_LEN]; memset(buf, 0, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(scsi_dev, fd, 1, PAGE_80, buf, 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) { - log_message(LOG_WARNING, "%s: Invalid page 0x80\n", - scsi_dev->name); + info("%s: Invalid page 0x80", dev_scsi->kernel_name); return 1; } len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3]; if (max_len < len) { - log_message(LOG_WARNING, "%s: length %d too short - need %d\n", - scsi_dev->name, max_len, len); + info("%s: length %d too short - need %d", + dev_scsi->kernel_name, max_len, len); return 1; } /* @@ -764,7 +730,7 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, * specific type where we prepend '0' + vendor + model. */ serial[0] = 'S'; - ser_ind = prepend_vendor_model(scsi_dev, &serial[1]); + ser_ind = prepend_vendor_model(dev_scsi, &serial[1]); if (ser_ind < 0) return 1; len = buf[3]; @@ -773,7 +739,7 @@ static int do_scsi_page80_inquiry(struct sysfs_device *scsi_dev, int fd, return 0; } -int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, +int scsi_get_serial (struct sysfs_device *dev_scsi, const char *devname, int page_code, char *serial, int len) { unsigned char page0[SCSI_INQ_BUFF_LEN]; @@ -782,16 +748,16 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, int retval; memset(serial, 0, len); - dprintf("opening %s\n", devname); + dbg("opening %s\n", devname); fd = open(devname, O_RDONLY | O_NONBLOCK); if (fd < 0) { - log_message(LOG_WARNING, "%s: cannot open %s: %s\n", - scsi_dev->name, devname, strerror(errno)); + info("%s: cannot open %s: %s", + dev_scsi->kernel_name, devname, strerror(errno)); return 1; } if (page_code == PAGE_80) { - if (do_scsi_page80_inquiry(scsi_dev, fd, serial, len)) { + if (do_scsi_page80_inquiry(dev_scsi, fd, serial, len)) { retval = 1; goto completed; } else { @@ -799,7 +765,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, goto completed; } } else if (page_code == PAGE_83) { - if (do_scsi_page83_inquiry(scsi_dev, fd, serial, len)) { + if (do_scsi_page83_inquiry(dev_scsi, fd, serial, len)) { retval = 1; goto completed; } else { @@ -807,7 +773,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, goto completed; } } else if (page_code == PAGE_83_PRE_SPC3) { - retval = do_scsi_page83_prespc3_inquiry(scsi_dev, fd, serial, len); + retval = do_scsi_page83_prespc3_inquiry(dev_scsi, fd, serial, len); if (retval) { /* * Fallback to servicing a SPC-2/3 compliant page 83 @@ -815,7 +781,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, * conform to pre-SPC3 expectations. */ if (retval == 2) { - if (do_scsi_page83_inquiry(scsi_dev, fd, serial, len)) { + if (do_scsi_page83_inquiry(dev_scsi, fd, serial, len)) { retval = 1; goto completed; } else { @@ -832,8 +798,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, goto completed; } } else if (page_code != 0x00) { - log_message(LOG_WARNING, "%s: unsupported page code 0x%d\n", - scsi_dev->name, page_code); + info("%s: unsupported page code 0x%d", dev_scsi->kernel_name, page_code); return 1; } @@ -841,7 +806,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, * 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(scsi_dev, fd, page0, SCSI_INQ_BUFF_LEN)) { + 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 @@ -851,11 +816,11 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, goto completed; } - dprintf("%s: Checking page0\n", scsi_dev->name); + dbg("%s: Checking page0\n", dev_scsi->kernel_name); for (ind = 4; ind <= page0[3] + 3; ind++) if (page0[ind] == PAGE_83) - if (!do_scsi_page83_inquiry(scsi_dev, fd, serial, + if (!do_scsi_page83_inquiry(dev_scsi, fd, serial, len)) { /* * Success @@ -866,7 +831,7 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, for (ind = 4; ind <= page0[3] + 3; ind++) if (page0[ind] == PAGE_80) - if (!do_scsi_page80_inquiry(scsi_dev, fd, serial, + if (!do_scsi_page80_inquiry(dev_scsi, fd, serial, len)) { /* * Success @@ -877,7 +842,6 @@ int scsi_get_serial (struct sysfs_device *scsi_dev, const char *devname, retval = 1; completed: if (close(fd) < 0) - log_message(LOG_WARNING, "%s: close failed: %s\n", - scsi_dev->name, strerror(errno)); + info("%s: close failed: %s", dev_scsi->kernel_name, strerror(errno)); return retval; } diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index f6d26e1c4c..91b4d57d76 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -33,7 +33,7 @@ all: $(PROG) $(MAN_PAGES) $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index b7d67958c9..0bcd267f67 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -21,12 +21,10 @@ #include #include -#include <../../libsysfs/sysfs/libsysfs.h> -#include "../../udev_utils.h" -#include "../../logging.h" +#include "../../udev.h" -#define MAX_NAME_LEN 72 -#define MAX_SERIAL_LEN 256 +#define MAX_NAME_LEN 72 +#define MAX_SERIAL_LEN 256 #define BLKGETSIZE64 _IOR(0x12,114,size_t) #ifdef USE_LOG @@ -54,7 +52,6 @@ void log_message(int priority, const char *format, ...) } #endif -char sysfs_mnt_path[SYSFS_PATH_MAX]; static char vendor_str[64]; static char model_str[64]; static char serial_str[MAX_SERIAL_LEN]; @@ -245,182 +242,176 @@ static void set_scsi_type(char *to, const char *from, int count) * 6.) If the device supplies a serial number, this number * is concatenated with the identification with an underscore '_'. */ -static int usb_id(const char *target_path) +static int usb_id(const char *devpath) { - struct sysfs_class_device *class_dev; /* of target_path */ - struct sysfs_class_device *class_dev_parent; /* for partitions */ - struct sysfs_device *scsi_dev; /* the scsi_device */ - struct sysfs_device *target_dev; - struct sysfs_device *host_dev, *interface_dev, *usb_dev; - struct sysfs_attribute *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; - struct sysfs_attribute *usb_model = NULL, *usb_vendor = NULL, *usb_rev, *usb_serial; - struct sysfs_attribute *if_class, *if_subclass; + struct sysfs_device *dev; + struct sysfs_device *dev_scsi; + struct sysfs_device *dev_target; + struct sysfs_device *dev_host, *dev_interface, *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; - class_dev = sysfs_open_class_device_path(target_path); - if (!class_dev) { - info("open class %s failed: %s", target_path, strerror(errno)); - return 1; - } - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent) { - scsi_dev = sysfs_get_classdev_device(class_dev_parent); - } else { - scsi_dev = sysfs_get_classdev_device(class_dev); - } + dbg("devpath %s\n", devpath); - /* - * The close of scsi_dev will close class_dev or class_dev_parent. - */ - - /* - * We assume we are called after the device is completely ready, - * so we don't have to loop here like udev. (And we are usually - * called via udev.) - */ - if (!scsi_dev) { - /* - * errno is not set if we can't find the device link, so - * don't print it out here. - */ - info("Cannot find sysfs device associated with %s", target_path); + dev = sysfs_device_get(devpath); + if (dev == NULL) { + err("unable to access '%s'", devpath); return 1; } - /* - * Allow only scsi devices. - * - * Other block devices can support SG IO, but only ide-cd does, so - * for now, don't bother with anything else. - */ - if (strcmp(scsi_dev->bus, "scsi") != 0) { - info("%s is not a scsi device", target_path); + /* get scsi parent device */ + dev_scsi = sysfs_device_get_parent(dev); + if (dev_scsi == NULL) { + err("unable to access parent device of '%s'", devpath); + return 1; + } + /* allow only scsi devices */ + if (strcmp(dev_scsi->subsystem, "scsi") != 0) { + info("%s is not a scsi device", devpath); return 1; } /* target directory */ - target_dev = sysfs_get_device_parent(scsi_dev); + dev_target = sysfs_device_get_parent(dev_scsi); + if (dev_target == NULL) { + err("unable to access parent device of '%s'", devpath); + return 1; + } + /* host directory */ - host_dev = sysfs_get_device_parent(target_dev); + dev_host = sysfs_device_get_parent(dev_target); + if (dev_host == NULL) { + err("unable to access parent device of '%s'", devpath); + return 1; + } + /* usb interface directory */ - interface_dev = sysfs_get_device_parent(host_dev); + dev_interface = sysfs_device_get_parent(dev_host); + if (dev_interface == NULL) { + err("unable to access parent device of '%s'", devpath); + return 1; + } + /* usb device directory */ - usb_dev = sysfs_get_device_parent(interface_dev); - - if (strcmp(interface_dev->bus, "usb") != 0) { - info("%s is not an usb device", target_path); + dev_usb = sysfs_device_get_parent(dev_interface); + if (dev_usb == NULL) { + err("unable to access parent device of '%s'", devpath); + return 1; + } + if (strcmp(dev_interface->subsystem, "usb") != 0) { + info("%s is not an usb device", devpath); return 1; } - if_class = sysfs_get_device_attr(interface_dev, "bInterfaceClass"); + if_class = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceClass"); if (!if_class) { - info("%s: cannot get bInterfaceClass attribute", interface_dev->name); + info("%s: cannot get bInterfaceClass attribute", dev_interface->kernel_name); return 1; } - if_class_num = strtoul(if_class->value, NULL, 16); + if_class_num = strtoul(if_class, NULL, 16); if (if_class_num != 8) { - set_usb_iftype(type_str, if_class->value, sizeof(type_str) - 1); + set_usb_iftype(type_str, if_class, sizeof(type_str)-1); protocol = 0; } else { - if_subclass = sysfs_get_device_attr(interface_dev, - "bInterfaceSubClass"); - protocol = set_usb_ifsubtype(type_str, if_subclass->value, - sizeof(type_str) -1 ); + if_subclass = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceSubClass"); + protocol = set_usb_ifsubtype(type_str, if_subclass, sizeof(type_str)-1); } if (!use_usb_info && protocol == 6) { /* Generic SPC-2 device */ - scsi_vendor = sysfs_get_device_attr(scsi_dev, "vendor"); + scsi_vendor = sysfs_attr_get_value(dev_scsi->devpath, "vendor"); if (!scsi_vendor) { - info("%s: cannot get SCSI vendor attribute", scsi_dev->name); + info("%s: cannot get SCSI vendor attribute", dev_scsi->kernel_name); return 1; } - set_str(vendor_str, scsi_vendor->value, sizeof(vendor_str)-1); + set_str(vendor_str, scsi_vendor, sizeof(vendor_str)-1); - scsi_model = sysfs_get_device_attr(scsi_dev, "model"); + scsi_model = sysfs_attr_get_value(dev_scsi->devpath, "model"); if (!scsi_model) { - info("%s: cannot get SCSI model attribute", scsi_dev->name); + info("%s: cannot get SCSI model attribute", dev_scsi->kernel_name); return 1; } - set_str(model_str, scsi_model->value, sizeof(model_str)-1); + set_str(model_str, scsi_model, sizeof(model_str)-1); - scsi_type = sysfs_get_device_attr(scsi_dev, "type"); + scsi_type = sysfs_attr_get_value(dev_scsi->devpath, "type"); if (!scsi_type) { - info("%s: cannot get SCSI type attribute", scsi_dev->name); + info("%s: cannot get SCSI type attribute", dev_scsi->kernel_name); return 1; } - set_scsi_type(type_str, scsi_type->value, sizeof(type_str)-1); + set_scsi_type(type_str, scsi_type, sizeof(type_str)-1); - scsi_rev = sysfs_get_device_attr(scsi_dev, "rev"); + scsi_rev = sysfs_attr_get_value(dev_scsi->devpath, "rev"); if (!scsi_rev) { - info("%s: cannot get SCSI revision attribute", scsi_dev->name); + info("%s: cannot get SCSI revision attribute", dev_scsi->kernel_name); return 1; } - set_str(revision_str, scsi_rev->value, sizeof(revision_str)-1); + set_str(revision_str, scsi_rev, sizeof(revision_str)-1); } /* Fallback to USB vendor & device */ if (vendor_str[0] == '\0') { if (!use_num_info) - if (!(usb_vendor = sysfs_get_device_attr(usb_dev, "manufacturer"))) + 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_get_device_attr(usb_dev, "idVendor"))) { + 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->value, sizeof(vendor_str) - 1); + set_str(vendor_str,usb_vendor, sizeof(vendor_str) - 1); } if (model_str[0] == '\0') { if (!use_num_info) - if (!(usb_model = sysfs_get_device_attr(usb_dev, "product"))) + 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_get_device_attr(usb_dev, "idProduct"))) { - dbg("No USB model information available\n"); - sprintf(model_str,"0000"); - } + 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->value, sizeof(model_str) - 1); + set_str(model_str, usb_model, sizeof(model_str) - 1); } if (revision_str[0] == '\0') { - usb_rev = sysfs_get_device_attr(usb_dev, "bcdDevice"); - if (usb_rev) { - set_str(revision_str, usb_rev->value, - sizeof(revision_str) - 1); - } + 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_get_device_attr(usb_dev, "serial"); - if (usb_serial) { - set_str(serial_str, usb_serial->value, - sizeof(serial_str) - 1); - } + 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; - char *devpath; - char target_path[MAX_NAME_LEN]; + int retval = 0; + const char *env; + char devpath[MAX_NAME_LEN]; int option; + logging_init("usb_id"); + sysfs_init(); + dbg("argc is %d", argc); - if (sysfs_get_mnt_path(sysfs_mnt_path, MAX_NAME_LEN)) { - info("sysfs_get_mnt_path failed: %s", - strerror(errno)); - exit(1); - } + + /* sysfs path can be overridden for testing */ + env = getenv("SYSFS_PATH"); + if (env) { + strlcpy(sysfs_path, env, sizeof(sysfs_path)); + remove_trailing_chars(sysfs_path, '/'); + } else + strcpy(sysfs_path, "/sys"); while ((option = getopt(argc, argv, "dnux")) != -1 ) { if (optarg) @@ -433,14 +424,14 @@ int main(int argc, char **argv) debug = 1; break; case 'n': - use_num_info=1; - use_usb_info=1; + use_num_info = 1; + use_usb_info = 1; break; case 'u': - use_usb_info=1; + use_usb_info = 1; break; case 'x': - export=1; + export = 1; break; default: info("Unknown or bad option '%c' (0x%x)", option, option); @@ -449,20 +440,19 @@ int main(int argc, char **argv) } } - devpath = getenv("DEVPATH"); - if (devpath) { - strncpy(target_path, sysfs_mnt_path, MAX_NAME_LEN); - strncat(target_path, devpath, MAX_NAME_LEN); - } else { + env = getenv("DEVPATH"); + if (env != NULL) + strlcpy(devpath, env, sizeof(devpath)); + else { if (optind == argc) { fprintf(stderr, "No device specified\n"); - exit(1); + retval = 1; + goto exit; } - devpath = argv[optind]; - strncpy(target_path, devpath, MAX_NAME_LEN); + strlcpy(devpath, argv[optind], sizeof(devpath)); } - retval = usb_id(target_path); + retval = usb_id(devpath); if (retval == 0) { if (export) { @@ -488,5 +478,9 @@ int main(int argc, char **argv) } } } - exit(retval); + +exit: + sysfs_cleanup(); + logging_close(); + return retval; } diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index 6201044941..edb5d3ac68 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -35,7 +35,7 @@ $(LIBVOLUME_ID): $(MAKE) -C libvolume_id $(PROG): %: $(HEADERS) %.o $(LIBVOLUME_ID) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(LIBVOLUME_ID) -o $@ $(LIBUDEV) $(LIBSYSFS) $(LIB_OBJS) + $(QUIET) $(LD) $(LDFLAGS) $@.o $(LIBVOLUME_ID) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) $(QUIET) $(STRIPCMD) $@ endif diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index 6f99c52728..a291eda51d 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -29,8 +29,7 @@ #include #include -#include "../../udev_utils.h" -#include "../../logging.h" +#include "../../udev.h" #include "libvolume_id/volume_id.h" #define BLKGETSIZE64 _IOR(0x12,114,size_t) diff --git a/libsysfs/LGPL b/libsysfs/LGPL deleted file mode 100644 index e00a829bb6..0000000000 --- a/libsysfs/LGPL +++ /dev/null @@ -1,441 +0,0 @@ - - GNU Lesser Public License - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - [This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your freedom to - share and change it. By contrast, the GNU General Public Licenses are - intended to guarantee your freedom to share and change free software--to - make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some specially - designated software packages--typically libraries--of the Free Software - Foundation and other authors who decide to use it. You can use it too, but - we suggest you first think carefully about whether this license or the - ordinary General Public License is the better strategy to use in any - particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, 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 and use pieces of it in new free - programs; and that you are informed that you can do these things. - - To protect your rights, we need to make restrictions that forbid - distributors to deny you these rights or to ask you to surrender these - rights. These restrictions translate to certain responsibilities for you - if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis or - for a fee, you must give the recipients all the rights that we gave you. - You must make sure that they, too, receive or can get the source code. If - you link other code with the library, you must provide complete object - files to the recipients, so that they can relink them with the library - after making changes to the library and recompiling it. And you must show - them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the - library, and (2) we offer you this license, which gives you legal - permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that there is - no warranty for the free library. Also, if the library is modified by - someone else and passed on, the recipients should know that what they have - is not the original version, so that the original author's reputation will - not be affected by problems that might be introduced by others. - - Finally, software patents pose a constant threat to the existence of any - free program. We wish to make sure that a company cannot effectively - restrict the users of a free program by obtaining a restrictive license - from a patent holder. Therefore, we insist that any patent license - obtained for a version of the library must be consistent with the full - freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the ordinary - GNU General Public License. This license, the GNU Lesser General Public - License, applies to certain designated libraries, and is quite different - from the ordinary General Public License. We use this license for certain - libraries in order to permit linking those libraries into non-free - programs. - - When a program is linked with a library, whether statically or using a - shared library, the combination of the two is legally speaking a combined - work, a derivative of the original library. The ordinary General Public - License therefore permits such linking only if the entire combination fits - its criteria of freedom. The Lesser General Public License permits more - lax criteria for linking other code with the library. - - We call this license the "Lesser" General Public License because it does - Less to protect the user's freedom than the ordinary General Public - License. It also provides other free software developers Less of an - advantage over competing non-free programs. These disadvantages are the - reason we use the ordinary General Public License for many libraries. - However, the Lesser license provides advantages in certain special - circumstances. - - For example, on rare occasions, there may be a special need to encourage - the widest possible use of a certain library, so that it becomes a - de-facto standard. To achieve this, non-free programs must be allowed to - use the library. A more frequent case is that a free library does the same - job as widely used non-free libraries. In this case, there is little to - gain by limiting the free library to free software only, so we use the - Lesser General Public License. - - In other cases, permission to use a particular library in non-free - programs enables a greater number of people to use a large body of free - software. For example, permission to use the GNU C Library in non-free - programs enables many more people to use the whole GNU operating system, - as well as its variant, the GNU/Linux operating system. - - Although the Lesser General Public License is Less protective of the - users' freedom, it does ensure that the user of a program that is linked - with the Library has the freedom and the wherewithal to run that program - using a modified version of the Library. - - The precise terms and conditions for copying, distribution and - modification follow. Pay close attention to the difference between a "work - based on the library" and a "work that uses the library". The former - contains code derived from the library, whereas the latter must be - combined with the library in order to run. - - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other program - which contains a notice placed by the copyright holder or other authorized - party saying it may be distributed under the terms of this Lesser General - Public License (also called "this License"). Each licensee is addressed as - "you". - - A "library" means a collection of software functions and/or data prepared - so as to be conveniently linked with application programs (which use some - of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work which - has been distributed under these terms. A "work based on the Library" - means either the Library or any derivative work under copyright law: that - is to say, a work containing the Library or a portion of it, either - verbatim or with modifications and/or translated straightforwardly into - another language. (Hereinafter, translation is included without limitation - in the term "modification".) - - "Source code" for a work means the preferred form of the work for making - modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not - covered by this License; they are outside its scope. The act of running a - program using the Library is not restricted, and output from such a - program is covered only if its contents constitute a work based on the - Library (independent of the use of the Library in a tool for writing it). - Whether that is true depends on what the Library does and what the program - that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's complete - 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 - distribute a copy of this License along with the Library. - - 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 Library or any portion of it, - thus forming a work based on the Library, 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) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices stating - that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no charge to - all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a table - of data to be supplied by an application program that uses the facility, - other than as an argument passed when the facility is invoked, then you - must make a good faith effort to ensure that, in the event an - application does not supply such function or table, the facility still - operates, and performs whatever part of its purpose remains meaningful. - - (For example, a function in a library to compute square roots has a - purpose that is entirely well-defined independent of the application. - Therefore, Subsection 2d requires that any application-supplied function - or table used by this function must be optional: if the application does - not supply it, the square root function must still compute square - roots.) - - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. - - In addition, mere aggregation of another work not based on the Library - with the Library (or with a work based on the Library) on a volume of a - storage or distribution medium does not bring the other work under the - scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public - License instead of this License to a given copy of the Library. To do - this, you must alter all the notices that refer to this License, so that - they refer to the ordinary GNU General Public License, version 2, instead - of to this License. (If a newer version than version 2 of the ordinary GNU - General Public License has appeared, then you can specify that version - instead if you wish.) Do not make any other change in these notices. - - Once this change is made in a given copy, it is irreversible for that - copy, so the ordinary GNU General Public License applies to all subsequent - copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of the - Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or derivative of - it, under Section 2) in object code or executable form under the terms of - Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to distribute the source - code, even though third parties are not compelled to copy the source along - with the object code. - - 5. A program that contains no derivative of any portion of the Library, - but is designed to work with the Library by being compiled or linked with - it, is called a "work that uses the Library". Such a work, in isolation, - is not a derivative work of the Library, and therefore falls outside the - scope of this License. - - However, linking a "work that uses the Library" with the Library creates - an executable that is a derivative of the Library (because it contains - portions of the Library), rather than a "work that uses the library". The - executable is therefore covered by this License. Section 6 states terms - for distribution of such executables. - - When a "work that uses the Library" uses material from a header file that - is part of the Library, the object code for the work may be a derivative - work of the Library even though the source code is not. Whether this is - true is especially significant if the work can be linked without the - Library, or if the work is itself a library. The threshold for this to be - true is not precisely defined by law. - - If such an object file uses only numerical parameters, data structure - layouts and accessors, and small macros and small inline functions (ten - lines or less in length), then the use of the object file is unrestricted, - regardless of whether it is legally a derivative work. (Executables - containing this object code plus portions of the Library will still fall - under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may distribute - the object code for the work under the terms of Section 6. Any executables - containing that work also fall under Section 6, whether or not they are - linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or link a - "work that uses the Library" with the Library to produce a work containing - portions of the Library, and distribute that work under terms of your - choice, provided that the terms permit modification of the work for the - customer's own use and reverse engineering for debugging such - modifications. - - You must give prominent notice with each copy of the work that the Library - is used in it and that the Library and its use are covered by this - License. You must supply a copy of this License. If the work during - execution displays copyright notices, you must include the copyright - notice for the Library among them, as well as a reference directing the - user to the copy of this License. Also, you must do one of these things: - - a) Accompany the work with the complete corresponding machine-readable - source code for the Library including whatever changes were used in the - work (which must be distributed under Sections 1 and 2 above); and, if - the work is an executable linked with the Library, with the complete - machine-readable "work that uses the Library", as object code and/or - source code, so that the user can modify the Library and then relink to - produce a modified executable containing the modified Library. (It is - understood that the user who changes the contents of definitions files - in the Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the Library. - A suitable mechanism is one that (1) uses at run time a copy of the - library already present on the user's computer system, rather than - copying library functions into the executable, and (2) will operate - properly with a modified version of the library, if the user installs - one, as long as the modified version is interface-compatible with the - version that the work was made with. - - c) Accompany the work with a written offer, valid for at least three - years, to give the same user the materials specified in Subsection 6a, - above, for a charge no more than the cost of performing this - distribution. - - d) If distribution of the work is made by offering access to copy from a - designated place, offer equivalent access to copy the above specified - materials from the same place. - - e) Verify that the user has already received a copy of these materials - or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the Library" - must include any data and utility programs needed for reproducing the - executable from it. However, as a special exception, the materials to be - 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. - - It may happen that this requirement contradicts the license restrictions - of other proprietary libraries that do not normally accompany the - operating system. Such a contradiction means you cannot use both them and - the Library together in an executable that you distribute. - - 7. You may place library facilities that are a work based on the Library - side-by-side in a single library together with other library facilities - not covered by this License, and distribute such a combined library, - provided that the separate distribution of the work based on the Library - and of the other library facilities is otherwise permitted, and provided - that you do these two things: - - a) Accompany the combined library with a copy of the same work based on - the Library, uncombined with any other library facilities. This must be - distributed under the terms of the Sections above. - - b) Give prominent notice with the combined library of the fact that part - of it is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute the - Library except as expressly provided under this License. Any attempt - otherwise to copy, modify, sublicense, link with, or distribute the - Library 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. - - 9. 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 Library or its derivative works. These actions are prohibited by law - if you do not accept this License. Therefore, by modifying or distributing - the Library (or any work based on the Library), you indicate your - acceptance of this License to do so, and all its terms and conditions for - copying, distributing or modifying the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the - Library), the recipient automatically receives a license from the original - licensor to copy, distribute, link with or modify the Library 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 with this License. - - 11. 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 Library at all. For example, if a patent license would not - permit royalty-free redistribution of the Library 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 Library. - - 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. - - 12. If the distribution and/or use of the Library is restricted in certain - countries either by patents or by copyrighted interfaces, the original - copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new versions - of the Lesser 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 Library - 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 Library does not specify a license version - number, you may choose any version ever published by the Free Software - Foundation. - - 14. If you wish to incorporate parts of the Library into other free - programs whose distribution conditions are incompatible with these, 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 - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY - FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN - OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES - PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE - LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, - REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE - WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - diff --git a/libsysfs/dlist.c b/libsysfs/dlist.c deleted file mode 100644 index 5579602bbc..0000000000 --- a/libsysfs/dlist.c +++ /dev/null @@ -1,621 +0,0 @@ -/* - * dlist.c - * - * Copyright (C) 2003 Eric J Bohm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 021110307 USA - * - */ - - -/* Double linked list implementation. - - * You allocate the data and give dlist the pointer. - * If your data is complex set the dlist->del_func to a an appropriate - * delete function. Otherwise dlist will just use free. - -*/ -#include "stdlib.h" -#include "dlist.h" - -/* - * Return pointer to node at marker. - * else null if no nodes. - */ - -inline void *dlist_mark(Dlist *list) -{ - if(list->marker!=NULL) - return(list->marker->data); - else - return(NULL); -} - -/* - * Set marker to start. - */ - -inline void dlist_start(Dlist *list) -{ - list->marker=list->head; -} - -/* - * Set marker to end. - */ - -inline void dlist_end(Dlist *list) -{ - list->marker=list->head; -} - -/* internal use function - * quickie inline to consolidate the marker movement logic - * in one place - * - * when direction true it moves marker after - * when direction false it moves marker before. - * return pointer to data at new marker - * if nowhere to move the marker in desired direction return null - */ -inline void *_dlist_mark_move(Dlist *list,int direction) -{ - if(direction) - { - if( list->marker && list->marker->next!=NULL) - list->marker=list->marker->next; - else - return(NULL); - } - else - { - if( list->marker && list->marker->prev!=NULL) - list->marker=list->marker->prev; - else - return(NULL); - } - if(list->marker!=list->head) - return(list->marker->data); - else - return(NULL); -} - -/* - * Create new linked list to store nodes of datasize. - * return null if list cannot be created. - */ -Dlist *dlist_new(size_t datasize) -{ - Dlist *list=NULL; - if((list=malloc(sizeof(Dlist)))) - { - list->marker=NULL; - list->count=0L; - list->data_size=datasize; - list->del_func=free; - list->head=&(list->headnode); - list->head->prev=NULL; - list->head->next=NULL; - list->head->data=NULL; - } - return(list); -} - -/* - * Create new linked list to store nodes of datasize set list - * data node delete function to the passed in del_func - * return null if list cannot be created. - */ -Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)) -{ - Dlist *list=NULL; - list=dlist_new(datasize); - if(list!=NULL) - list->del_func=del_func; - return(list); -} - - -/* - * remove marker node from list - * call data_delete function on data if registered. - * otherwise call free. - * when direction true it moves marker after - * when direction false it moves marker before. - * free marker node - * return nothing. - */ -void dlist_delete(Dlist *list,int direction) -{ - if((list->marker != list->head)&&(list->marker!=NULL)) - { - DL_node *corpse; - corpse=list->marker; - _dlist_mark_move(list,direction); - if(list->head->next==corpse) - list->head->next=corpse->next; - if(list->head->prev==corpse) - list->head->prev=corpse->prev; - if(corpse->prev!=NULL) //should be impossible - corpse->prev->next=corpse->next; - if(corpse->next!=NULL) //should be impossible - corpse->next->prev=corpse->prev; - list->del_func(corpse->data); - list->count--; - free(corpse); - } -} - -/* - * Insert node containing data at marker. - * If direction true it inserts after. - * If direction false it inserts before. - * move marker to inserted node - * return pointer to inserted node - */ -void *dlist_insert(Dlist *list,void *data,int direction) -{ - DL_node *new_node=NULL; - if(list==NULL || data==NULL) - return(NULL); - if(list->marker==NULL) //in case the marker ends up unset - list->marker=list->head; - if((new_node=malloc(sizeof(DL_node)))) - { - new_node->data=data; - new_node->prev=NULL; - new_node->next=NULL; - list->count++; - if(list->head->next==NULL) //no l - { - list->head->next=list->head->prev=new_node; - new_node->prev=list->head; - new_node->next=list->head; - } - else if(direction) - { - new_node->next=list->marker->next; - new_node->prev=list->marker; - list->marker->next->prev=new_node; - list->marker->next=new_node; - } - else - { - new_node->prev=list->marker->prev; - new_node->next=list->marker; - list->marker->prev->next=new_node; - list->marker->prev=new_node; - } - list->marker=new_node; - } - else - { - return(NULL); - } - return(list->marker->data); -} - -/* internal use only - * Insert dl_node at marker. - * If direction true it inserts after. - * If direction false it inserts before. - * move marker to inserted node - * return pointer to inserted node - */ -void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction) -{ - if(list==NULL || new_node==NULL) - return(NULL); - if(list->marker==NULL) //in case the marker ends up unset - list->marker=list->head; - list->count++; - if(list->head->next==NULL) - { - list->head->next=list->head->prev=new_node; - new_node->prev=list->head; - new_node->next=list->head; - } - else if(direction) - { - new_node->next=list->marker->next; - new_node->prev=list->marker; - list->marker->next->prev=new_node; - list->marker->next=new_node; - } - else - { - new_node->prev=list->marker->prev; - new_node->next=list->marker; - list->marker->prev->next=new_node; - list->marker->prev=new_node; - } - list->marker=new_node; - return(list->marker); -} - - - -/* - * Remove DL_node from list without deallocating data. - * if marker == killme . - * when direction true it moves marker after - * when direction false it moves marker before. - * to previous if there is no next. - */ -void *_dlist_remove(Dlist *list,DL_node *killme,int direction) -{ - if(killme!=NULL) - { - void *killer_data=killme->data; - // take care of head and marker pointers. - if(list->marker==killme) - _dlist_mark_move(list,direction); - if(killme ==list->head->next) - list->head->next=killme->next; - if(killme==list->head->prev) - list->head->prev=killme->prev; - // remove from list - if(killme->prev !=NULL) - killme->prev->next=killme->next; - if(killme->next !=NULL) - killme->next->prev=killme->prev; - list->count--; - free(killme); - return(killer_data); - } - else - return (NULL); -} - -/* - * move dl_node from source to dest - * if marker == target . - * when direction true it moves marker after - * when direction false it moves marker before. - * to previous if there is no next. - */ -void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction) -{ - - if(target!=NULL) - { - if(target==source->head) - { - //not even going to try - } - else - { - // take care of head and marker pointers. - if(source->marker==target) - _dlist_mark_move(source,direction); - if(target ==source->head->next) - source->head->next=target->next; - if(target==source->head->prev) - source->head->prev=target->prev; - // remove from list - if(source->count==1) - { - target->prev=NULL; - target->next=NULL; - source->head->next=NULL; - source->head->prev=NULL; - } - else - { - if(target->prev !=NULL) - target->prev->next=target->next; - if(target->next !=NULL) - target->next->prev=target->prev; - target->prev=NULL; - target->next=NULL; - } - source->count--; - _dlist_insert_dlnode(dest,target,direction); - } - } -} - - -/* - * Insert node containing data after end. - */ -void dlist_push(Dlist *list,void *data) -{ - list->marker=list->head->prev; - dlist_insert(list,data,1); -} - -/* - * Insert node containing data at start. - */ - -void dlist_unshift(Dlist *list,void *data) - -{ - list->marker=list->head->next; - dlist_insert(list,data,0); -} - -void dlist_unshift_sorted(Dlist *list, void *data, - int (*sorter)(void *new_elem, void *old_elem)) -{ - if (list->count == 0) - dlist_unshift(list, data); - else { - list->marker=list->head->next; - dlist_insert_sorted(list, data, sorter); - } -} - -/* - * Remove end node from list. - * Return pointer to data in removed node. - * Null if no nodes. - */ - -void *dlist_pop(Dlist *list) -{ - return(_dlist_remove(list,list->head->prev,0)); -} - -/* - * Remove start node from list. - * Return pointer to data in removed node. - * Null if no nodes. - */ - -void *dlist_shift(Dlist *list) -{ - return(_dlist_remove(list,list->head->next,1)); -} - - -/* - * destroy the list freeing all memory - */ - - -void dlist_destroy(Dlist *list) -{ - if(list !=NULL) - { - dlist_start(list); - dlist_next(list); - while (dlist_mark(list)) { - dlist_delete(list,1); - } - free(list); - } -} - -/** - * Return void pointer to list_data element matching comp function criteria - * else null - * Does not move the marker. - */ - -void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)) -{ - /* test the comp function on each node */ - struct dl_node *nodepointer; - dlist_for_each_nomark(list,nodepointer) - if(comp(target,nodepointer->data)) - return(nodepointer->data); - return(NULL); -} - -/** - * Apply the node_operation function to each data node in the list - */ -void dlist_transform(struct dlist *list, void (*node_operation)(void *)) -{ - struct dl_node *nodepointer; - dlist_for_each_nomark(list,nodepointer) - node_operation(nodepointer->data); -} - -/** - * insert new into list in sorted order - * sorter function in form int sorter(new,ith) - * must return 1 for when new should go before ith - * else 0 - * return pointer to inserted node - * NOTE: assumes list is already sorted - */ -void *dlist_insert_sorted(struct dlist *list, void *new, int (*sorter)(void *, void *)) -{ - for(dlist_start(list),dlist_next(list); \ - list->marker!=list->head && !sorter(new,list->marker->data);dlist_next(list)); - return(dlist_insert_before(list,new)); -} - -/* - * NOTE: internal use only - */ -int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)) -{ - - struct dl_node *l1head; - struct dl_node *l2head; - struct dl_node *target; - unsigned int l1count=0; - unsigned int l2count=0; - unsigned int mergecount=0; - while(listsource->count>0) - { - l1head=listsource->head->next; - l2head=l1head; - while((l1counthead)) - { - l2head=l2head->next; - l1count++; - } - // so now we have two lists to merge - - if(l2head==listsource->head) - {// l2count - l2count=0; - } - else - { - l2count=passcount; - } - while(l1count>0 || l2count>0) - { - mergecount++; - if((l2count>0)&&(l1count>0)) - { - // we have things to merge - int result=compare(l1head->data,l2head->data); - if(result>0) - { - // move from l2 - target=l2head; - l2head=l2head->next; - dlist_move(listsource,listdest,target,1); - l2count--; - if(l2head==listsource->head) - l2count=0; - } - else - { - // move from l1 - target=l1head; - l1head=l1head->next; - dlist_move(listsource,listdest,target,1); - l1count--; - } - } - else if(l1count>0) - { - // only have l1 to work with - while(l1count>0) - { - target=l1head; - l1head=l1head->next; - dlist_move(listsource,listdest,target,1); - l1count--; - } - } - else if(l2count>0) - { - // only have l2 to work with - while(l2count>0) - { - if(l2head==listsource->head) - { - l2count=0; - } - else - { - target=l2head; - l2head=l2head->next; - dlist_move(listsource,listdest,target,1); - l2count--; - } - } - } - else - { //nothing left and this should be unreachable - } - } - } - return(mergecount); -} - -/** - * mergesort the list based on compare - * compare function in form int sorter(void * a,void * b) - * must return >0 for a after b - * must return <0 for a before b - * else 0 - - * NOTE: mergesort changes the mark pointer - */ -void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)) -{ - - struct dlist *listsource, *listdest, *swap; - struct dlist *templist; - unsigned int passcount = 1; - unsigned int mergecount = 1; - - dlist_start(list); - templist = dlist_new(list->data_size); - - // do nothing if there isn't anything to sort - listsource = list; - listdest = templist; - if(listsource->count<2) - { //nothing to do - return; - } - else - { - while(mergecount>0) - { - mergecount=_dlist_merge(listsource, listdest, passcount, compare); - if(mergecount>1) - { - passcount=passcount*2; - //start new pass - swap=listsource; - listsource=listdest; - listdest=swap; - } - } - } - // now put the input list pointers right - // list pointers = newlist pointers - // including the forward and next nodes prev and back pointers - if(list->count==0) - {//copy - list->marker = listdest->marker; - list->count = listdest->count; - list->data_size = listdest->data_size; - list->del_func = listdest->del_func; - list->head->prev = listdest->head->prev; - list->head->next = listdest->head->next; - list->head->data = listdest->head->data; - list->head->next->prev=list->head; - list->head->prev->next=list->head; - templist->head->next=NULL; - templist->head->prev=NULL; - templist->count=0; - } - else - {// no need to copy - - } - - dlist_destroy(templist); -} - - - -/* internal use function - swaps elements a and b - No sense in juggling node pointers when we can just swap the data pointers -*/ - -void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b) -{ - - void *swap=a->data; - a->data=b->data; - b->data=swap; - -} - diff --git a/libsysfs/libsysfs.txt b/libsysfs/libsysfs.txt deleted file mode 100644 index b877cb8030..0000000000 --- a/libsysfs/libsysfs.txt +++ /dev/null @@ -1,1954 +0,0 @@ - - System Utilities sysfs Library - libsysfs - ========================================= - -Version: 1.2.0 -September 13, 2004 - -Contents --------- -1. Introduction -2. Requirements -3. Definitions -4. Overview -5. Data Structures - 5.1 Directory and Attribute Data Structures - 5.1.1 Attribute Structure - 5.1.2 Link Structure - 5.1.3 Directory Structure - 5.2 Bus Data Structure - 5.3 Class Data Structures - 5.4 Root Device Data Structure - 5.5 Device Data Structure - 5.6 Driver Data Structure -6. Functions - 6.1 Calling Conventions in Libsysfs - 6.2 Utility Functions - 6.3 Filesystem Functions - 6.3.1 Attribute Functions - 6.3.2 Directory Link Functions - 6.3.3 Directory Functions - 6.4 Bus Functions - 6.5 Class Functions - 6.6 Device Functions - 6.7 Driver Functions -7. Dlists - 7.1 Navigating a dlist - 7.2 Custom sorting using dlist_sort_custom() -8. Usage -9. Testsuite -10. Conclusion - - -1. Introduction ---------------- - -Libsysfs' purpose is to provide a consistent and stable interface for -querying system device information exposed through the sysfs filesystem. -The library implements functions for querying filesystem information, -such as reading directories and files. It also contains routines for -working with buses, classes, and the device tree. - - -2. Requirements ---------------- - -The library must satisfy the following requirements: - -- It must provide a stable programming interfaces that applications can - be built upon. - -- It must provide functions to retrieve device Vital Product Data (VPD) - information for Error Log Analysis (ELA) support. ELA will provide - device driver and device bus address information. - -- It must provide access to all system devices and information exposed - by sysfs. - -- It must provide a function to find sysfs' current mount point. - -- It must provide a function for udev to retrieve a device's major and - minor numbers. - - -3. Definitions --------------- - -- sysfs: Sysfs is a virtual filesystem in 2.5+ Linux kernels that - presents a hierarchical representation of all system physical and - virtual devices. It presents system devices by bus, by class, and - by topology. Callbacks to device drivers are exposed as files in - device directories. Sysfs, for all purposes, is our tree of system - devices. For more information, please see: - - http://www.kernel.org/pub/linux/kernel/people/mochel/doc/ - -- udev: Udev is Greg Kroah-Hartman's User Space implementation of devfs. - Udev creates /dev nodes for devices upon Hotplug events. The Hotplug - event provides udev with a sysfs directory location of the device. Udev - must use that directory to grab device's major and minor number, which it - will use to create the /dev node. For more information, please see: - - http://www.kernel.org/pub/linux/utils/kernel/hotplug/ - - Udev provides persistent device naming based on a set of user specified - rules. The rules a device name is based on could one or a combination of a - number of parameters such as the bus the device is on, the serial number - of the device (in case of USB), the vendor name (in case of SCSI) and so - on. Udev uses Libsysfs to retrieve relevent information to appropriately - name devices. - - -4. Overview ------------ - -Libsysfs grew from a common need. There are several applications under -development that need access to sysfs and system devices. Udev, on a -hotplug event, must take a sysfs device path and create a /dev node. Our -diagnostic client needs to list all system devices. Finally, our Error -Log Analysis piece is required to retrieve VPD information for a -failing device. We divided to create a single library interface rather -than having these separate applications create their own accesses to -sysfs involving reading directories and files. - -Libsysfs will also provide stability for applications to be built upon. Sysfs -currently doesn't enforce any standards for callback or file names. File -names change depending on bus or class. Sysfs is also changing, it is -currently being developed. Libsysfs will provide a stable interface to -applications while allowing sysfs to change underneath it. - -Like sysfs, the library will provide devices to applications by bus, by -class, and by topology. The library will function similar to directories -and files that lie underneath it. To query a device on a PCI bus, one would -"open" the bus to scan or read devices and "close" the bus when -completed. Besides supplying functions to retrieve devices, the library -will also provide some utility functions like getting sysfs mount point. - -A paper on Libsysfs was presented at Linux.Conf.Au 2004 (Adelaide, January -2004). The paper is available online at: - -http://oss.software.ibm.com/linux/papers/libsysfs/libsysfs-linuxconfau2004.pdf - - -5. Data Structures ------------------- - -Libsysfs will classify system devices following sysfs' example, dividing -them by bus, class, and devices. The library presents this information -generically. It doesn't, for example, differentiate between PCI and USB -buses. Device attributes are presented with values as they are exposed -by sysfs, the values are not formatted. - -The library will provide standard definitions for working with sysfs -and devices, here's some examples: - -#define SYSFS_FSTYPE_NAME "sysfs" -#define SYSFS_PROC_MNTS "/proc/mounts" -#define SYSFS_BUS_NAME "bus" -#define SYSFS_CLASS_NAME "class" -#define SYSFS_BLOCK_NAME "block" -#define SYSFS_DEVICES_NAME "devices" -#define SYSFS_DRIVERS_NAME "drivers" -#define SYSFS_NAME_ATTRIBUTE "name" - -The library uses some definitions to mark maximum size of a sysfs name or -path length: - -#define SYSFS_PATH_MAX 255 -#define SYSFS_NAME_LEN 50 -#define SYSFS_BUS_ID_SIZE 20 - - -NOTE: - a. As of release 0.4.0 of sysfsutils, a number of changes have been - made so that the dlists and "directory" references in all libsysfs's - structures are not populated until such time that it is absolutely - necessary. Hence, these elements may not contain valid data at all - times (as was the case before). - b. As of release 1.0.0 of sysfsutils, all dlists in the library are - sorted in alphabetical order. It is now a requirement that the - "name" and "path" be the first two elements of all libsysfs - structures. - - -5.1 Directory and Attribute Data Structures -------------------------------------------- - -The library implements structures to represent sysfs directories, links, -and files. - - -5.1.1 Attribute Structure -------------------------- - -A file in sysfs represents a device or driver attribute. Attributes can be -read only, write only, or read and write. File data can be ASCII and -binary. The library has the following structure to represent files: - -struct sysfs_attribute { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - char *value; - unsigned short len; /* value length */ - unsigned short method; /* show and store */ -}; - -Path represents the file/attribute's full path. Value is used when reading -from or writing to an attribute. "len" is the length of data in "value". -Method is a bitmask for defining if the attribute supports show(read) -and/or store(write). - - -5.1.2 Link Structure --------------------- - -Symbolic links are used in sysfs to link bus or class views with -particular devices. - -struct sysfs_link { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - char target[SYSFS_PATH_MAX]; -}; - -Link's name is stored in "name' and it's target stored in "target". Absolute -path to the link is stored in "path". - - -5.1.3 Directory Structure -------------------------- - -The directory structure represents a sysfs directory: - -struct sysfs_directory { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - - /* Private: for internal use only */ - struct dlist *subdirs; - struct dlist *links; - struct dlist *attributes; -}; - -The sysfs_directory structure includes the list of subdirectories, links and -attributes. The "name" and absolute "path" are also stored in the structure. -The sysfs_directory structure is intended for use internal to the library. -Applications needing access to attributes and links from the directory -will need to make appropriate calls (described below) to get the same. - - -5.2 Bus Data Structure ----------------------- - -All buses look similar in sysfs including lists of devices and drivers, -therefore we use the following structure to represent all sysfs buses: - -struct sysfs_bus { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - - /* Private: for internal use only */ - struct dlist *drivers; - struct dlist *devices; - struct sysfs_directory *directory; -}; - -The sysfs_bus structure contains the bus "name", while the "path" to bus -directory is also stored. It also contains lists of devices on the bus -and drivers that are registered on it. The bus' directory is represented -by the sysfs_directory structure and it contains references to all the -subdirectories, links, and attributes. The sysfs_directory structure -is for internal use only. The following functions may be used by -applications to retrieve data from the sysfs_directory structure: - -struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) -struct sysfs_attribute *sysfs_get_bus_attribute(struct sysfs_bus *bus, - char *attrname) - - -5.3 Class Data Structures -------------------------- - -The library uses two data structures to represent classes in sysfs. Sysfs -classes contains a class directory like "net" or "scsi_host" and then -class devices like "eth0", "lo", or "eth1" for the "net" class. - -struct sysfs_class { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - - /* Private: for internal use only */ - struct dlist *devices; - struct sysfs_directory *directory; -}; - -The sysfs_class represents device classes in sysfs like "net". It contains -the class "name", "path" to the class, a list of class devices and the -directory representation (for internal use only). - -struct sysfs_class_device { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - char classname[SYSFS_NAME_LEN]; - - /* Private: for internal use only */ - struct sysfs_class_device *parent; - struct sysfs_device *sysdevice; /* NULL if virtual */ - struct sysfs_driver *driver; /* NULL if not implemented */ - struct sysfs_directory *directory; -}; - -A class device isn't the same as a sysfs_device, it's specific to the class in -which it belongs. The class device structure contains the name of the class -the class device belongs to, its sysfs_device reference and that device's -driver reference (if any). It also contains the name of the class device -- like "eth0", its parent point (if present) and its sysfs directory -information including links and attributes (for internal use only). -The following function may be used by applications to retrieve data -from the sysfs_directory structure: - -struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *cdev); - - -5.4 Root Device Data Structure ------------------------------- - -Device hierarchies in sysfs are represented under the /sys/devices directory -structure. Sysfs devices typically spawn off from base devices which are -represented by a sysfs_root_device. - -struct sysfs_root_device { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - - /* Private: for internal use only */ - struct dlist *devices; - struct sysfs_directory *directory; -}; - -The sysfs_root_device structure contains a list of "devices" that spawn off it. -The name of the root device as represented under /sys/devices is read into -"name" and the absolute path into "path" and its sysfs_directory information -intended to be used internal to the library. - - -5.5 Device Data Structure -------------------------- - -The sysfs_device structure represents a system device that's exposed -in sysfs under the /sys/devices directory structure. - -struct sysfs_device { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - char bus_id[SYSFS_NAME_LEN]; - char bus[SYSFS_NAME_LEN]; - char driver_name[SYSFS_NAME_LEN]; - - /* Private: for internal use only */ - struct sysfs_device *parent; - struct dlist *children; - struct sysfs_directory *directory; -}; - -The sysfs_device structure contains a "parent" pointer, a list of child -devices, if any, device's directory, its bus id - which is the name of -device's directory, the bus name on which this device is registered and -its driver name. The device structure also contains the absolute path -to the device and a directory structure, which contains a list of the -device's attributes (for internal use only). The following functions -may be used to obtain information from sysfs_directory structure: - -struct sysfs_attribute *sysfs_get_device_attribute(struct sysfs_device *dev, - const char *name) -struct dlist *sysfs_get_device_attributes(struct sysfs_device *device) - - -5.6 Driver Data Structure -------------------------- - -The sysfs_driver structure represents a device driver. - -struct sysfs_driver { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - - /* Private: for internal use only */ - struct dlist *devices; - struct sysfs_directory *directory; -}; - -The sysfs_driver structure contains a list of devices that use this driver, -the name of the driver, its path, and its directory information, which -includes the driver's attributes (for internal use only). The following -function may be used to retrieve driver attribute information from the -sysfs_directory structure: - -struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver) - - -6. Functions ------------- - -Libsysfs will provide functions to access system devices by bus, by class, -and by device. Functions will act like accessing directories and files, -using "open" and "close". Open returns a structure and close is used -to clean that structure up. - - -6.1 Calling Conventions in Libsysfs ------------------------------------ - -Libsysfs uses a simple API calling convention. APIs are classified to be -one of "open", "get", "close" types. The convention is as follows: - - a. All "open" APIs have a corresponding "close" API. - b. References obtained using "get" calls should not be closed - explicitly. - c. All "opened" references have to be closed with a call to - their corresponding "close" call. This takes care of - freeing structure references obtained with "get" calls. - - -6.2 Utility Functions ---------------------- - -The library will provide a few utility functions for working with sysfs. - -------------------------------------------------------------------------------- -Name: sysfs_get_mnt_path - -Description: Function finds the mount path for filesystem type "sysfs". - -Arguments: char *mnt_path Mount path buffer - size_t len Size of mount path buffer - -Returns: Zero with success. - -1 with error. Errno will be set with error: - - EINVAL for invalid argument, if buffer is NULL or - if len is zero - -Prototype: sysfs_get_mnt_path(char *mnt_path, size_t len); -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_name_from_path - -Description: Function returns the last directory or file name from the - included path. - -Arguments: const char *path Path to parse name from - char *name Buffer to put parsed name into - size_t *len Size of name buffer - -Returns: 0 with success. - -1 on Error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_get_name_from_path(const char *path, - char *name, size_t *len) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_link - -Description: Sysfs readlink function, reads the link at supplied path - and returns its target path. - -Arguments: const char *path Link's path - char *target Buffer to place link's target - size_t len Size of target buffer - -Returns: 0 with success - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_get_link(const char *path, char *target, size_t len) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_subsystem_list - -Description: Function returns the list of entries for the given subsystem. If - the argument is "bus", this function will return a list of buses - ("pci", "scsi", etc) supported on the system. - - sysfs_close_list() has to be called to free the list obtained - from this call. - -Arguments: char *name Subsystem to open, like "bus".. - -Returns: dlist of entries for the subsystem on success - NULL with error indicating the "name" subsystem is invalid. - -Prototype: struct dlist *sysfs_open_subsystem_list(char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_bus_devices_list - -Description: Function returns the list of devices on the given bus. - - sysfs_close_list() has to be called to free the list obtained - from this call. - -Arguments: char *name Bus name to open "pci"/"scsi"/"usb".. - -Returns: dlist of device names for the given bus on success - NULL with error indicating the bus is not supported. - -Prototype: struct dlist *sysfs_open_bus_devices_list(char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_list - -Description: Closes a given dlist. This can be used as a generic list close - routine. - -Arguments: struct dlist *list List to be closed - -Prototype: void sysfs_close_list(struct dlist *list) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_path_is_dir - -Description: Utility function to verify if a given path is to a directory. - -Arguments: const char *path Path to verify - -Returns: 0 on success, 1 on error - - EINVAL for invalid arguments - -Prototype: int sysfs_path_is_dir(const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_path_is_file - -Description: Utility function to verify if a given path is to a file. - -Arguments: const char *path Path to verify - -Returns: 0 on success, 1 on error - - EINVAL for invalid arguments - -Prototype: int sysfs_path_is_file(const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_path_is_link - -Description: Utility function to verify if a given path is to a link. - -Arguments: const char *path Path to verify - -Returns: 0 on success, 1 on error - - EINVAL for invalid arguments - -Prototype: int sysfs_path_is_link(const char *path) -------------------------------------------------------------------------------- - - -6.3 Filesystem Functions ------------------------- - -Libsysfs provides a set of functions to open, read, and close directories -and attributes/files in sysfs. These functions mirror their filesystem -function counterparts. - - -6.3.1 Attribute Functions -------------------------- - -Along with the usual open, read, and close functions, libsysfs provides -a couple other functions for accessing attribute values. - -------------------------------------------------------------------------------- -Name: sysfs_open_attribute - -Description: Opens up a file in sysfs and creates a sysfs_attribute - structure. File isn't read with this function. - -Arguments: const char *path File/Attribute's path - -Returns: struct sysfs_attribute * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_open_attribute(const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_attribute - -Description: Cleans up and closes sysfs_attribute structure. - -Arguments: struct sysfs_attribute *sysattr Attribute to close - -Prototype: void sysfs_close_attribute(struct sysfs_attribute *sysattr) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_read_dir_attributes - -Description: Reads the given sysfs_directory to create a list of attributes. - -Arguments: struct sysfs_directory *sysdir sysfs_directory whose - attributes to read - -Returns: struct dlist * of attributes on success - NULL with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: struct dlist *sysfs_read_dir_attributes - (struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_dir_attributes - -Description: Given a list sysfs_directory, this function refreshes the list - of attributes for the given directory. - -Arguments: struct sysfs_directory *sysdir sysfs_ directory whose - attributes list to refresh - -Returns: 0 with success. - 1 with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: int sysfs_refresh_dir_attributes(struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_dir_attributes - -Description: Returns a list of attributes for the given sysfs_directory. - -Arguments: struct sysfs_directory *sysdir sysfs_directory whose - attributes list to return - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: struct dlist *sysfs_read_dir_attributes - (struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_read_attribute - -Description: Reads the supplied attribute. Since the maximum transfer - from a sysfs attribute is a pagesize, function reads in - up to a page from the file and stores it in the "value" - field in the attribute. - -Arguments: struct sysfs_attribute *sysattr Attribute to read - -Returns: 0 with success. - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_read_attribute(struct sysfs_attribute *sysattr) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_write_attribute - -Description: Writes to the supplied attribute. Function validates if the - given attribute is writable, and writes the new value to the - attribute. Value to write as well as its length is user - supplied. In case the length written is not equal to the - length requested to be written, the original value is - restored and an error is returned. - -Arguments: struct sysfs_attribute *sysattr Attribute to write to - const char *new_value sysattr's new value - size_t len Length of "new_value" - -Returns: 0 with success. - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const char *new_value, size_t len) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_read_attribute_value - -Description: Given a path to a specific attribute, function reads and - returns its value to the supplied value buffer. - -Arguments: const char *attrpath Attribute path to read - char *value Buffer to read in attribute's value - size_t vsize Size of buffer - -Returns: 0 with success. - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_read_attribute_value(const char *attrpath, - char *value, size_t vsize) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_value_from_attributes - -Description: Function takes a single or linked list of sysfs attribute - structures and returns the value of the specified attribute - name. - -Arguments: struct dlist *attr Attribute list to search through - const char *name Name of attribute whose value - to retrieve - -Returns: char * attribute value with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: char *sysfs_get_value_from_attributes - (struct sysfs_attribute *attr, const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_directory_attribute - -Description: Function walks the list of attributes for the given sysfs - directory and returns the sysfs_attribute structure for - the specified attribute name. - -Arguments: struct sysfs_directory *dir Directory in which to search - char *attrname Attribute name to look for - -Returns: struct sysfs_attribute on success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_get_directory_attribute - (struct sysfs_directory *dir, char *attrname) -------------------------------------------------------------------------------- - - -6.3.2 Link Functions --------------------- - -Sysfs contains many symbolic links, like bus links to bus devices. Libsysfs -treats links differently than directories due to processing differences. A -link in the /sys/bus/"busname"/devices/ directory indicates a device in the -/sys/devices directory. Through links we give the functionality to know -what is and what isn't a link and the ability to query the links target. - -------------------------------------------------------------------------------- -Name: sysfs_open_link - -Description: Opens a directory link. - -Arguments: const char *linkpath Path to link - -Returns: struct sysfs_link * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_link *sysfs_open_link(const char *linkpath) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_link - -Description: Closes a directory link structure. - -Arguments: struct sysfs_link *ln Link to close - -Prototype: void sysfs_close_link(struct sysfs_link *ln) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_read_dir_links - -Description: Reads the given sysfs_directory to create a list of links. - -Arguments: struct sysfs_directory *sysdir sysfs_directory whose - links to read - -Returns: struct dlist * of links with success - NULL with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: struct dlist *sysfs_read_dir_links - (struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_dir_links - -Description: Returns a list of links for the given sysfs_directory. - -Arguments: struct sysfs_directory *sysdir sysfs_directory whose - list of links to return - -Returns: struct dlist * of links with success - NULL with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: struct dlist *sysfs_read_dir_links - (struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_directory_link - -Description: Function walks the list of links for the given sysfs directory - and returns the sysfs_link structure for the specified link - name. - -Arguments: struct sysfs_directory *dir Directory in which to search - char *linkname Link name to look for - -Returns: struct sysfs_link * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_link *sysfs_get_directory_link - (struct sysfs_directory *dir, char *linkname) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_subdirectory_link - -Description: Function walks the list of links for the given sysfs directory - and its subdirectories returns the sysfs_link structure for - the specified link name. - -Arguments: struct sysfs_directory *dir Directory in which to search - char *linkname Link name to look for - -Returns: struct sysfs_link * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_link *sysfs_get_subdirectory_link - (struct sysfs_directory *dir, char *linkname) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_dir_links - -Description: Given a list sysfs_directory, this function refreshes the list - of links under the given directory. - -Arguments: struct sysfs_directory *sysdir sysfs_ directory whose - links list to refresh - -Returns: 0 with success. - 1 with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: int sysfs_refresh_dir_links(struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - - -6.3.3 Directory Functions -------------------------- - -Sysfs directories can represent every directory under sysfs. The structures -keep track of subdirectories, links, and files. Like opendir, readdir, and -closedir, libsysfs provides open, read, and close functions for working with -sysfs directories. Open creates the sysfs_directory structure. Read reads in -its contents - like subdirectories, links, and files. Close cleans it all -up. - -------------------------------------------------------------------------------- -Name: sysfs_open_directory - -Description: Opens a sysfs directory at a specific path - -Arguments: const char *path Directory path to open - -Returns: struct sysfs_directory * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_directory *sysfs_open_directory(const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_directory - -Description: Closes specific directory, its subdirectories, links, and - files. - -Arguments: struct sysfs_directory *sysdir Directory to close - -Prototype: void sysfs_close_directory(struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_read_dir_subdirs - -Description: Reads the given sysfs_directory to create a list of subdirs. - -Arguments: struct sysfs_directory *sysdir sysfs_directory whose - subdirs have to be read - -Returns: struct dlist * of links with success - NULL with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: struct dlist *sysfs_read_dir_subdirs - (struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_read_directory - -Description: Read the supplied directory. Reading fills in the directory's - contents like subdirectories, links, and attributes. - -Arguments: struct sysfs_directory *sysdir Directory to read - -Returns: 0 with success. - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_read_directory(struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_read_all_subdirs - -Description: Reads all subdirs under a given supplied directory. - -Arguments: struct sysfs_directory *sysdir Directory to read - -Returns: 0 with success. - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_read_all_subdirs(struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_subdirectory - -Description: Function walks the directory tree for the given directory and - returns a sysfs_directory structure for the specified directory - name. - -Arguments: struct sysfs_directory *dir Directory in which to search - char *subname Name of directory to look for - -Returns: struct sysfs_directory with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_directory *sysfs_get_subdirectory - (struct sysfs_directory *dir, char *subname) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_dir_subdirs - -Description: Returns a list of subdirs for the given sysfs_directory. - -Arguments: struct sysfs_directory *sysdir sysfs_directory whose - subdirectories list to return - -Returns: struct dlist * of directories with success - NULL with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: struct dlist *sysfs_read_dir_subdirs - (struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_dir_subdirs - -Description: Given a list sysfs_directory, this function refreshes the list - of subdirectories under the given directory. - -Arguments: struct sysfs_directory *sysdir sysfs_ directory whose - subdirs list to refresh - -Returns: 0 with success. - 1 with error. Errno will be set on error, returning EINVAL - for invalid arguments - -Prototype: int sysfs_refresh_dir_subdirs(struct sysfs_directory *sysdir) -------------------------------------------------------------------------------- - - -6.4 Bus Functions ------------------ - -The library provides a functions for viewing buses represented in sysfs. -The sysfs_open_bus opens a bus in the /sys/bus directory, such as "pci", -"usb", or "scsi". The open command returns a sysfs_bus structure that -contains a list of the bus' devices. The sysfs_close_bus function is -used to clean up the bus structure. Given a device or a driver, -functions are provided to determine what bus they are on. - -------------------------------------------------------------------------------- -Name: sysfs_open_bus - -Description: Function opens up one of the buses represented in sysfs in - the /sys/bus directory. It returns a sysfs_bus structure - that includes a list of bus devices and drivers. - -Arguments: const char *name Bus name to open, like "pci"... - -Returns: struct sysfs_bus * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_bus *sysfs_open_bus(const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_bus - -Description: Function closes up the sysfs_bus structure including its - devices, drivers, and directory. - -Arguments: sysfs_bus *bus Bus structure to close - -Prototype: void sysfs_close_bus(struct sysfs_bus *bus) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_bus_devices - -Description: Function returns a list of devices that are registered with - this bus. - -Arguments: struct sysfs_bus *bus Bus whose devices list to return - -Returns: struct dlist * of sysfs_devices on success - NULL with error. Errno will be sent with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_bus_drivers - -Description: Function returns a list of drivers that are registered with - this bus. - -Arguments: struct sysfs_bus *bus Bus whose drivers list to return - -Returns: struct dlist * of sysfs_drivers on success - NULL with error. Errno will be sent with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_bus_device - -Description: Function takes a sysfs_bus structure(obtained on a successful - return from a sysfs_open_bus() call) and looks for the given - device on this bus. On success, it returns a sysfs_device - structure corresponding to the device. - -Arguments: struct sysfs_bus *bus Bus structure on which to search - char *id Device to look for - -Returns: struct sysfs_device * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_get_bus_device - (struct sysfs_bus *bus, char *id) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_bus_driver - -Description: Function takes a sysfs_bus structure (obtained on a successful - return from a sysfs_open_bus() call) and looks for the given - driver on this bus. On success, it returns a sysfs_driver - structure corresponding to the driver. - -Arguments: struct sysfs_bus *bus Bus structure on which to search - char *drvname Driver to look for - -Returns: struct sysfs_driver * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_get_bus_driver - (struct sysfs_bus *bus, char *drvname) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_bus_attributes - -Description: Function takes a sysfs_bus structure and returns a list of - attributes for the bus. - -Arguments: struct sysfs_bus *bus Bus for which attributes are required - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_bus_attribute - -Description: Function takes a sysfs_bus structure and looks for the required - attribute on the bus. On success, it returns a sysfs_attribute - structure corresponding to the given attribute. - -Arguments: struct sysfs_bus *bus Bus structure on which to search - char *attrname Attribute to look for - -Returns: struct sysfs_attribute * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_get_bus_attribute - (struct sysfs_bus *bus, char *attrname) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_bus_attributes - -Description: Function refreshes the list of attributes for a given sysfs_bus - -Arguments: struct sysfs_bus *bus Bus whose attributes list to refresh - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_bus_attributes(struct sysfs_bus *bus) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_find_driver_bus - -Description: Given the name of a driver, this function finds the name of the - bus the driver is on - -Arguments: const char *driver Name of the driver to look for - char *busname Buffer to return the bus name - size_t bsize Size of the "busname" buffer - -Returns: 0 with success. - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_find_driver_bus(const char *driver, - char *busname, size_t bsize) -------------------------------------------------------------------------------- - - -6.5 Class Functions -------------------- - -Libsysfs provides functions to open sysfs classes and their class devices. -These functions too operate with open and close, close must be called to -clean up the class structures. Given a class device name, functions are -provided to determine what class they belong to. Once a class device -name and the class it belongs to is known, a function to open the -class device is provided. This method can be used when details of -a single class device is required. - -------------------------------------------------------------------------------- -Name: sysfs_open_class - -Description: Function opens up one of the classes represented in sysfs in - the /sys/class directory. It returns a sysfs_class structure - that includes a list of class devices. - -Arguments: const char *name Class name to open, like "net".. - -Returns: struct sysfs_class * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_class *sysfs_open_class(const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_class - -Description: Function closes up the sysfs_class structure including its - class devices. - -Arguments: sysfs_class *cls Class structure to close - -Prototype: void sysfs_close_class(struct sysfs_class *cls); -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_class_device_path - -Description: Function opens up one of the class devices represented in - sysfs in sysfs/class/"class"/ directory. It returns a - sysfs_class_device structure. - -Arguments: const char *path Path to class device - -Returns: struct sysfs_class_device * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_class_device *sysfs_open_class_device_path - (const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_class_device - -Description: Function closes up the sysfs_class_device structure. - -Arguments: sysfs_class_device *dev Class device structure to close - -Prototype: void sysfs_close_class_device(struct sysfs_class_device *dev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_class_device - -Description: Function takes a sysfs_class structure(obtained on a successful - return from a sysfs_open_class() call) and looks for the given - device in this class. On success, it returns a sysfs_class_device - structure corresponding to the class device. - -Arguments: struct sysfs_class *cls Class on which to search - char *name Class device "name" to look for - -Returns: struct sysfs_class_device * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_class_device *sysfs_get_class_device - (struct sysfs_class *cls, char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_class_devices - -Description: Function returns a list of class devices for the given class. - -Arguments: struct sysfs_class *cls Class whose class device list - is required - -Returns: struct dlist * of sysfs_class_devices on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_class_device - -Description: Given the name of the class on which to look for, this function - locates a given class device and returns a sysfs_class_device - structure corresponding to the requested class device. - - NOTE: - 1. The sysfs_class_device structure obtained upon successful - return from this function has to be closed by calling - sysfs_close_class_device(). - 2. Class this device belongs to must be known prior to calling - this function. - -Arguments: const char *classname Class on which to search - char *name Class device "name" to open - -Returns: struct sysfs_class_device * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_class_device *sysfs_open_class_device - (const char *classname, char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_classdev_device - -Description: Function returns the sysfs_device reference (if present) for the - given class device. - -Arguments: struct sysfs_class_device *clsdev Class device whose - sysfs_device reference - is required - -Returns: struct sysfs_device * on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_get_classdev_device - (struct sysfs_class_device *clsdev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_classdev_driver - -Description: Function returns the sysfs_driver reference (if present) for - the given class device. - -Arguments: struct sysfs_class_device *clsdev Class device whose - sysfs_driver reference - is required - -Returns: struct sysfs_driver * on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_driver *sysfs_get_classdev_driver - (struct sysfs_class_device *clsdev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_classdev_parent - -Description: Function returns the sysfs_class_device reference for the - parent (if present) of the given class device. - -Arguments: struct sysfs_class_device *clsdev Class device whose - parent reference - is required - -Returns: struct sysfs_class_device * on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_class_device *sysfs_get_classdev_parent - (struct sysfs_class_device *clsdev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_classdev_attributes - -Description: Function takes a sysfs_class_device structure and returns a - list of attributes for the class device. - -Arguments: struct sysfs_class_device *cdev Class device for which - attributes are required - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_classdev_attributes - (struct sysfs_class_device *cdev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_classdev_attr - -Description: Searches supplied class device's attributes by name and returns - the attribute. - -Arguments: struct sysfs_class_device *clsdev Device to search - const char *name Attribute name to find - -Returns: struct sysfs_attribute * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_get_classdev_attr - (struct sysfs_class_device *clsdev, const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_classdev_attributes - -Description: Function refreshes the list of attributes for a given - sysfs_class_device. - -Arguments: struct sysfs_class_device *cdev Class device whose attributes - list to refresh - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_classdev_attributes - (struct sysfs_class_device *cdev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_classdev_attr - -Description: Function takes as arguments, a the name of the class, the class - device name and the name of the required attribute. - - NOTE: - 1. The struct sysfs_attribute * obtained upon successful - return from this function has to be closed by making - a call to sysfs_close_attribute() - -Arguments: char *classname Class name on which to search - char *dev Name of the class device - char *attrib Attribute to open - -Returns: struct sysfs_attribute * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_write_classdev_attr - (const char *classname, const char *dev, - const char *attrib) -------------------------------------------------------------------------------- - - -6.6 Device Functions --------------------- - -Devices represent everything in sysfs under /sys/devices, which is a -hierarchical view of system devices. Besides the expected open and -close functions, libsysfs provides open and close functions for -root devices. These functions recursively open or close a device -and all of its children. - -------------------------------------------------------------------------------- -Name: sysfs_open_device_path - -Description: Opens up a device at a specific path. It opens the device's - directory, reads the directory, and returns a sysfs_device - structure. - -Arguments: const char *path Path to device - -Returns: struct sysfs_device * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_open_device_path(const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_device - -Description: Function closes up the sysfs_device structure. - -Arguments: sysfs_device *dev Device structure to close - -Prototype: void sysfs_close_device(struct sysfs_device *dev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_root_device - -Description: Function opens up one of the root devices represented in sysfs - in the /sys/devices directory. It returns a sysfs_root_device - structure that includes a list of devices in the tree. - -Arguments: const char *name Name of the root device to open - -Returns: struct sysfs_root_device * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_open_root_device(const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_root_device - -Description: Function closes up the sysfs_root_device structure including the - devices in the root device tree. - -Arguments: sysfs_device *root Root device structure to close - -Prototype: void sysfs_close_root_device(struct sysfs_root_device *root) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_device_tree - -Description: Function opens up the device tree at the specified path. - -Arguments: const char *path Path at which to open the device tree - -Returns: struct sysfs_device * with success - NULL with error, Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_open_device_tree(const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_device_tree - -Description: Function closes the device tree originating at the given - sysfs_device. - -Arguments: struct sysfs_device *devroot Device from which the device - tree has to be closed - -Prototype: void sysfs_close_device_tree(struct sysfs_device *devroot) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_device_parent - -Description: Function returns the sysfs_device reference for the parent - (if present) of the given sysfs_device. - -Arguments: struct sysfs_device *dev sysfs_device whose parent - reference is required - -Returns: struct sysfs_device * on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_get_device_parent - (struct sysfs_device *dev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_root_devices - -Description: Function returns a list of devices under the given root device. - -Arguments: struct sysfs_root_device *root sysfs_root_device whose devices - list is required - -Returns: struct dlist * of sysfs_devices on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_root_devices - (struct sysfs_root_device *root) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_device_attr - -Description: Searches supplied device's attributes by name and returns - the attribute. - -Arguments: struct sysfs_device *dev Device to search - const char *name Attribute name to find - -Returns: struct sysfs_attribute * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_get_device_attr - (struct sysfs_device *dev, const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_device_attributes - -Description: Function takes a sysfs_device structure and returns a list - of attributes for the device. - -Arguments: struct sysfs_device *device Device for which - attributes are required - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_device_attributes - (struct sysfs_device *device) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_device_attributes - -Description: Function refreshes the list of attributes for a given - sysfs_device. - -Arguments: struct sysfs_device *device Device whose attributes list - to refresh - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_refresh_device_attributes - (struct sysfs_device *device) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_device - -Description: Given the name of the bus on which to look for, this function - locates a given device and returns a sysfs_device structure - corresponding to the requested device. - -Arguments: const char *bus Bus on which to search - const char *bus_id Device to look for - -Returns: struct sysfs_device * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_device *sysfs_open_device - (const char *bus, const char *bus_id) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_device_bus - -Description: Given a sysfs_device, this function fills in the bus this - device is on in the sysfs_device->bus field. - -Arguments: struct sysfs_device *dev Device whose bus name to find - -Returns: 0 with success. - -1 with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: int sysfs_get_device_bus(struct sysfs_device *dev) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_device_attr - -Description: Function takes as arguments, the bus on which to search for a - device, and an attribute of the device to open. - - NOTE: - 1. The struct sysfs_attribute * obtained upon successful - return from this function has to be closed by making - a call to sysfs_close_attribute() - -Arguments: char *bus Bus on which to search - char *bus_id Device to look for - char *attrib Name of the attribute to open - -Returns: struct sysfs_attribute * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_open_device_attr - (const char *bus, const char *bus_id, const char *attrib) -------------------------------------------------------------------------------- - - -6.7 Driver Functions --------------------- - -Drivers are represented in sysfs under the /sys/bus/xxx/drivers (xxx being -the bus type, such as "pci", "usb, and so on). Functions are provided to -open and close drivers. - -------------------------------------------------------------------------------- -Name: sysfs_open_driver_path - -Description: Opens driver at specific path. - -Arguments: const char *path Path to driver - -Returns: struct sysfs_driver * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_driver *sysfs_open_driver_path(const char *path) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_close_driver - -Description: Closes and cleans up sysfs_driver structure. - -Arguments: sysfs_driver *driver Driver structure to close - -Prototype: void sysfs_close_driver(struct sysfs_driver *driver) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_driver_devices - -Description: Function returns a list of devices that use this driver. - -Arguments: struct sysfs_driver *driver Driver whose devices list is - required - -Returns: struct dlist * of sysfs_devices on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_driver_devices - (struct sysfs_driver *driver) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_driver_devices - -Description: Function refreshes the list of devices that use this driver. - -Arguments: struct sysfs_driver *driver Driver whose devices list is - required to be refreshed - -Returns: struct dlist * of sysfs_devices on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_refresh_driver_devices - (struct sysfs_driver *driver) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_driver_device - -Description: Function returns a sysfs_device reference for the device with - "name" that uses this driver - -Arguments: struct sysfs_driver *driver Driver on which to search - const char *name Name of the device to look for - -Returns: struct sysfs_device * corresponding to "name" on success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_driver_device - (struct sysfs_driver *driver, const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_driver_attr - -Description: Searches supplied driver's attributes by name and returns - the attribute. - -Arguments: struct sysfs_driver *drv Driver to search - const char *name Attribute name to find - -Returns: struct sysfs_attribute * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_get_driver_attr - (struct sysfs_driver *drv, const char *name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_driver_attributes - -Description: Function takes a sysfs_driver structure and returns a list - of attributes for the driver. - -Arguments: struct sysfs_driver *driver Driver for which attributes - are required - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_get_driver_attributes - (struct sysfs_driver *driver) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_refresh_driver_attributes - -Description: Function refreshes the list of attributes for a given - sysfs_driver. - -Arguments: struct sysfs_driver *driver Driver whose attributes list - to refresh - -Returns: struct dlist * of attributes with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct dlist *sysfs_refresh_driver_attributes - (struct sysfs_driver *driver) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_driver - -Description: Given the name of the bus on which to look for, this function - locates a given driver and returns a sysfs_driver structure - corresponding to the requested device. - - NOTE: - 1. The sysfs_driver structure obtained upon successful return - from this function has to be closed by calling - sysfs_close_driver_by_name(). - 2. Bus on which to look for this driver should be known prior - to calling this function. Use sysfs_find_driver_bus() - to determine this. - -Arguments: const char *bus_name Bus on which to search - const char *drv_name Driver name to look for - -Returns: struct sysfs_driver * with success - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_driver *sysfs_open_driver(const char *bus_name, - const char *drv_name) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_get_driver_links - -Description: Function returns a list of links for a given driver - -Arguments: struct sysfs_driver *driver Driver to get links from - -Returns: struct dlist * of links on success - NULL with error - -Prototype: struct dlist *sysfs_get_driver_links - (struct sysfs_driver *driver) -------------------------------------------------------------------------------- - -------------------------------------------------------------------------------- -Name: sysfs_open_driver_attr - -Description: Function takes as arguments, the bus the driver is registered - on, the driver name and the name of the attribute to open. - - NOTE: - 1. The struct sysfs_attribute * obtained upon successful - return from this function has to be closed by making - a call to sysfs_close_attribute() - -Arguments: char *bus Bus on which driver is present - char *drv Driver to look for - char *attrib Name of the attribute to open - -Returns: struct sysfs_attribute * with success. - NULL with error. Errno will be set with error, returning - - EINVAL for invalid arguments - -Prototype: struct sysfs_attribute *sysfs_open_driver_attr - (const char *bus, const char *drv, const char *attrib) -------------------------------------------------------------------------------- - - -7 Dlists --------- - -Libsysfs uses (yet another) list implementation thanks to Eric J Bohm. - - -7.1 Navigating a dlist ----------------------- - -Some library functions return a dlist of devices/drivers/attributes, etc. -To navigate the list returned the macro "dlist_for_each_data" is to be used. - ------------------------------------------------------------------------------- -Function/Macro name: dlist_for_each_data - -Description: Walk the given list, returning a known data type/ - structure in each iteration. - -Arguments: struct dlist *list List pointer - data_iterator Data type/structure variable - contained in the list - datatype Data type/structure contained - in the list - -Returns: On each iteration, "data_iterator" will contain a list - element of "datatype" - -Usage example: The function sysfs_get_classdev_attributes() returns a - dlist of attributes. To navigate the list: - - struct sysfs_attribute *attr = NULL; - struct dlist *attrlist = NULL; - . - . - . - attrlist = sysfs_get_classdev_attributes - (struct sysfs_class_device *cdev) - if (attrlist != NULL) { - dlist_for_each_data(attrlist, attr, - struct sysfs_attribute) { - . - . - . - } - } -------------------------------------------------------------------------------- - - -7.2 Custom sorting using dlist_sort_custom() --------------------------------------------- - -As of release 1.2.0, libsysfs provides a new interface for custom sorting -of dlists. The API dlist_sort_custom() has been added for this purpose. -Applications that would like to define their own sorter function can now -make use of this API. - -The sorter function must conform to the following prototype: - - int compare(void *a, void*b) - -dlist_sort_custom() expects that the compare function will: - return >0 for a before b - return <0 for b before a - return 0 for a == b - - -8. Usage --------- - -Accessing devices through libsysfs is supposed to mirror accessing devices -in the filesystem it represents. Here's a typical order of operation: - - - get sysfs mount point - - "open" sysfs category, ie. bus, class, or device - - work with category - - "close" sysfs category - - -9. Testsuite ------------- - -Version 1.0.0 of sysfsutils ships with a comprehensive testsuite. The testsuite -shipped as part of the "test" directory of the sysfsutils source package, -results in an executable "testlibsysfs" which will be installed in the -/usr/local/bin directory. Some of the salient features of the testsuite are: - -a. Tests _every_ API exported by the library. -b. Tests are performed for all possible combinations of input parameters. -c. Detailed output is provided for the correct case. -d. Facility to redirect output of the tests to a normal file. -e. Number of iterations of tests can be specified. - -The testsuite comes with its own configuration file "libsysfs.conf" in the -"test" directory. This file is used to generate a header file at the time -the tests are built. - -To use the testsuite: - -a. Modify the variables libsysfs.conf file to appropriate values for your - system. (The libsysfs.conf file contains comments describing what each - variable stands for and, in some cases, how to determine an appropriate - value for the system under test). - -b. Build and install the testsuite. - -c. Run the testsuite: - - testlibsysfs - -The default logfile is stdout. - -NOTE: If the libsysfs.conf file is changed, make sure to run "make clean" in -the test directory and then a "make" for the changes to take effect. - - -10. Conclusion --------------- - -Libsysfs is meant to provide a stable application programming interface to -sysfs. Applications can depend upon the library to access system devices -and functions exposed through sysfs. diff --git a/libsysfs/sysfs.h b/libsysfs/sysfs.h deleted file mode 100644 index 2add8227a4..0000000000 --- a/libsysfs/sysfs.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * sysfs.h - * - * Internal Header Definitions for libsysfs - * - * Copyright (C) IBM Corp. 2003-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _SYSFS_H_ -#define _SYSFS_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define safestrcpy(to, from) strncpy(to, from, sizeof(to)-1) -#define safestrcat(to, from) strncat(to, from, sizeof(to) - strlen(to)-1) - -#define safestrcpymax(to, from, max) \ -do { \ - to[max-1] = '\0'; \ - strncpy(to, from, max-1); \ -} while (0) - -#define safestrcatmax(to, from, max) \ -do { \ - to[max-1] = '\0'; \ - strncat(to, from, max - strlen(to)-1); \ -} while (0) - -extern struct sysfs_attribute *get_attribute(void *dev, const char *name); -extern struct dlist *read_dir_subdirs(const char *path); -extern struct dlist *read_dir_links(const char *path); -extern struct dlist *get_attributes_list(void *dev); - -/* Debugging */ -#ifdef DEBUG -#include "../logging.h" -#define dprintf(format, arg...) dbg(format, ## arg) -#else -#define dprintf(format, arg...) do { } while (0) -#endif - -#endif /* _SYSFS_H_ */ diff --git a/libsysfs/sysfs/dlist.h b/libsysfs/sysfs/dlist.h deleted file mode 100644 index 335a490a0a..0000000000 --- a/libsysfs/sysfs/dlist.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * dlist.h - * - * Copyright (C) 2003 Eric J Bohm - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _DLIST_H_ -#define _DLIST_H_ - -/* Double linked list header. - -* navigate your list with DLIST_PREV and DLIST_NEXT. These are macros -* so function call overhead is minimized. - -* Supports perl style push, pop, shift, unshift list semantics. - -* You allocate the data and give dlist the pointer. If your data is -* complex set the dlist->del_func to a an appropriate delete using -* dlist_new_with_delete. Your delete function must match -(void * )(del(void *) -*Otherwise dlist will just use free. - -* NOTE: The small amount of pain involved in doing that allows us to -* avoid copy in copy out semantics. - -* Dlist uses an internal mark pointer to keep track of where you are -* in the list. - -* insert and delete take a directional parameter. Where direction -* corresponds to the direction in which you want the list to go. -* true direction corresponded to progressing forward in the last -* false to regressing in the list. -* so a dlist_insert(yourlist,item,1) will insert it after the mark -* so a dlist_insert(yourlist,item,0) will insert it before the mark -* any insert will move the mark to the new node regardless of the direction. - -* Just use the dlist_(insert|delete)_(before|after) macros if you do not want -* to think about it. - -*/ - -#include - -typedef struct dl_node { - struct dl_node *prev; - struct dl_node *next; - void *data; -} DL_node; - -typedef struct dlist { - DL_node *marker; - unsigned long count; - size_t data_size; - void (*del_func)(void *); - DL_node headnode; - DL_node *head; -} Dlist; - -Dlist *dlist_new(size_t datasize); -Dlist *dlist_new_with_delete(size_t datasize,void (*del_func)(void*)); -void *_dlist_mark_move(Dlist *list,int direction); -void *dlist_mark(Dlist *); -void dlist_start(Dlist *); -void dlist_end(Dlist *); -void dlist_move(struct dlist *source, struct dlist *dest, struct dl_node *target,int direction); -void *dlist_insert(Dlist *,void *,int) ; - -void *dlist_insert_sorted(struct dlist *list, void *new_elem, int (*sorter)(void *, void *)); - -void dlist_delete(Dlist *,int); - -void dlist_push(Dlist *,void *); - -void dlist_unshift(Dlist *,void *); -void dlist_unshift_sorted(Dlist *,void *,int (*sorter)(void *, void *)); - -void *dlist_pop(Dlist *); - -void *dlist_shift(Dlist *); - -void dlist_destroy(Dlist *); - -int _dlist_merge(struct dlist *listsource, struct dlist *listdest, unsigned int passcount, int (*compare)(void *, void *)); - -void *dlist_find_custom(struct dlist *list, void *target, int (*comp)(void *, void *)); - -void dlist_sort_custom(struct dlist *list, int (*compare)(void *, void *)); - - -void _dlist_swap(struct dlist *list, struct dl_node *a, struct dl_node *b); - -void dlist_transform(struct dlist *list, void (*node_operation)(void *)); - - -/* - * _dlist_remove is for internal use only - * _dlist_mark_move is for internal use only - */ -void *_dlist_remove(struct dlist *,struct dl_node *,int ); -void *_dlist_insert_dlnode(struct dlist *list,struct dl_node *new_node,int direction); - -#define dlist_prev(A) _dlist_mark_move((A),0) -#define dlist_next(A) _dlist_mark_move((A),1) - -#define dlist_insert_before(A,B) dlist_insert((A),(B),0) -#define dlist_insert_after(A,B) dlist_insert((A),(B),1) - -#define dlist_delete_before(A) dlist_delete((A),0) -#define dlist_delete_after(A) dlist_delete((A),1) - -/** - * provide for loop header which iterates the mark from start to end - * list: the dlist pointer, use dlist_mark(list) to get iterator - */ -#define dlist_for_each(list) \ - for(dlist_start(list),dlist_next(list); \ - (list)->marker!=(list)->head;dlist_next(list)) - -/** - * provide for loop header which iterates the mark from end to start - * list: the dlist pointer, use dlist_mark(list) to get iterator - */ -#define dlist_for_each_rev(list) \ - for(dlist_end(list),dlist_prev(list); \ - (list)->marker!=(list)->head;dlist_prev(list)) - -/** - * provide for loop header which iterates through the list without moving mark - * list: the dlist_pointer - * iterator: dl_node pointer to iterate - */ -#define dlist_for_each_nomark(list,iterator) \ - for((iterator)=(list)->head->next; (iterator)!=(list)->head; \ - (iterator)=(iterator)->next) - -/** - * provide for loop header which iterates through the list without moving mark - * in reverse - * list: the dlist_pointer - * iterator: dl_node pointer to iterate - */ -#define dlist_for_each_nomark_rev(list,iterator) \ - for((iterator)=(list)->head->prev; (iterator)!=(list)->head; \ - (iterator)=(iterator)->prev) -/** - * provide for loop header which iterates through the list providing a - * data iterator - * list: the dlist pointer - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ - -#define dlist_for_each_data(list,data_iterator,datatype) \ - for(dlist_start(list), (data_iterator)=(datatype *) dlist_next(list); \ - (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_next(list)) - -/** - * provide for loop header which iterates through the list providing a - * data iterator in reverse - * list: the dlist pointer - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ -#define dlist_for_each_data_rev(list,data_iterator,datatype) \ - for(dlist_end(list), (data_iterator)=(datatype *) dlist_prev(list); \ - (list)->marker!=(list)->head;(data_iterator)=(datatype *) dlist_prev(list)) - -/** - * provide for loop header which iterates through the list providing a - * data iterator without moving the mark - * list: the dlist pointer - * iterator: the dl_node pointer to iterate - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ - -#define dlist_for_each_data_nomark(list,iterator,data_iterator,datatype) \ - for((iterator)=(list)->head->next, (data_iterator)=(datatype *) (iterator)->data; \ - (iterator)!=(list)->head;(iterator)=(iterator)->next,(data_iterator)=(datatype *) (iterator)) - -/** - * provide for loop header which iterates through the list providing a - * data iterator in reverse without moving the mark - * list: the dlist pointer - * iterator: the dl_node pointer to iterate - * data_iterator: the pointer of type datatype to iterate - * datatype: actual type of the contents in the dl_node->data - */ -#define dlist_for_each_data_nomark_rev(list,iterator, data_iterator,datatype) \ - for((iterator)=(list)->head->prev, (data_iterator)=(datatype *) (iterator)->data; \ - (iterator)!=(list)->head;(iterator)=(iterator)->prev,(data_iterator)=(datatype *) (iterator)) - -#endif /* _DLIST_H_ */ diff --git a/libsysfs/sysfs/libsysfs.h b/libsysfs/sysfs/libsysfs.h deleted file mode 100644 index 12e7cc5f99..0000000000 --- a/libsysfs/sysfs/libsysfs.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * libsysfs.h - * - * Header Definitions for libsysfs - * - * Copyright (C) IBM Corp. 2004-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#ifndef _LIBSYSFS_H_ -#define _LIBSYSFS_H_ - -#include -#include -#include "dlist.h" - -#define SYSFS_FSTYPE_NAME "sysfs" -#define SYSFS_PROC_MNTS "/proc/mounts" -#define SYSFS_BUS_NAME "bus" -#define SYSFS_CLASS_NAME "class" -#define SYSFS_BLOCK_NAME "block" -#define SYSFS_DEVICES_NAME "devices" -#define SYSFS_DRIVERS_NAME "drivers" -#define SYSFS_MODULE_NAME "module" -#define SYSFS_NAME_ATTRIBUTE "name" -#define SYSFS_UNKNOWN "unknown" -#define SYSFS_PATH_ENV "SYSFS_PATH" - -#define SYSFS_PATH_MAX 256 -#define SYSFS_NAME_LEN 64 -#define SYSFS_BUS_ID_SIZE 32 - -/* mount path for sysfs, can be overridden by exporting SYSFS_PATH */ -#define SYSFS_MNT_PATH "/sys" - -enum sysfs_attribute_method { - SYSFS_METHOD_SHOW = 0x01, /* attr can be read by user */ - SYSFS_METHOD_STORE = 0x02, /* attr can be changed by user */ -}; - -/* - * NOTE: - * 1. We have the statically allocated "name" as the first element of all - * the structures. This feature is used in the "sorter" function for dlists - * 2. As is the case with attrlist - * 3. As is the case with path - */ -struct sysfs_attribute { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - char *value; - unsigned short len; /* value length */ - enum sysfs_attribute_method method; /* show and store */ -}; - -struct sysfs_driver { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - struct dlist *attrlist; - char bus[SYSFS_NAME_LEN]; - - /* Private: for internal use only */ - struct dlist *devices; -}; - -struct sysfs_device { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - struct dlist *attrlist; - char bus_id[SYSFS_NAME_LEN]; - char bus[SYSFS_NAME_LEN]; - char driver_name[SYSFS_NAME_LEN]; - - /* Private: for internal use only */ - struct sysfs_device *parent; - /* NOTE - we still don't populate this */ - struct dlist *children; -}; - -/* NOTE: not used as of now */ -struct sysfs_bus { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - struct dlist *attrlist; - - /* Private: for internal use only */ - struct dlist *drivers; - struct dlist *devices; -}; - -struct sysfs_class_device { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - struct dlist *attrlist; - char classname[SYSFS_NAME_LEN]; - - /* Private: for internal use only */ - struct sysfs_class_device *parent; - struct sysfs_device *sysdevice; /* NULL if virtual */ -}; - -/* NOTE: not used as of now */ -struct sysfs_class { - char name[SYSFS_NAME_LEN]; - char path[SYSFS_PATH_MAX]; - struct dlist *attrlist; - - /* Private: for internal use only */ - struct dlist *devices; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Function Prototypes - */ -extern int sysfs_get_mnt_path(char *mnt_path, size_t len); -extern int sysfs_remove_trailing_slash(char *path); -extern int sysfs_get_name_from_path(const char *path, char *name, size_t len); -extern int sysfs_path_is_dir(const char *path); -extern int sysfs_path_is_link(const char *path); -extern int sysfs_path_is_file(const char *path); -extern int sysfs_get_link(const char *path, char *target, size_t len); -extern struct dlist *sysfs_open_directory_list(const char *path); -extern void sysfs_close_list(struct dlist *list); - -/* sysfs directory and file access */ -extern void sysfs_close_attribute(struct sysfs_attribute *sysattr); -extern struct sysfs_attribute *sysfs_open_attribute(const char *path); -extern int sysfs_read_attribute(struct sysfs_attribute *sysattr); -extern int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const char *new_value, size_t len); - -/* sysfs driver access */ -extern void sysfs_close_driver(struct sysfs_driver *driver); -extern struct sysfs_driver *sysfs_open_driver - (const char *bus_name, const char *drv_name); -extern struct sysfs_driver *sysfs_open_driver_path(const char *path); -extern struct sysfs_attribute *sysfs_get_driver_attr - (struct sysfs_driver *drv, const char *name); -extern struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *driver); -extern struct dlist *sysfs_get_driver_devices(struct sysfs_driver *driver); - -/* generic sysfs device access */ -extern void sysfs_close_device_tree(struct sysfs_device *device); -extern struct sysfs_device *sysfs_open_device_tree(const char *path); -extern void sysfs_close_device(struct sysfs_device *dev); -extern struct sysfs_device *sysfs_open_device - (const char *bus, const char *bus_id); -extern struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev); -extern struct sysfs_device *sysfs_open_device_path(const char *path); -extern int sysfs_get_device_bus(struct sysfs_device *dev); -extern struct sysfs_attribute *sysfs_get_device_attr - (struct sysfs_device *dev, const char *name); -extern struct dlist *sysfs_get_device_attributes - (struct sysfs_device *dev); - -/* generic sysfs class access */ -extern void sysfs_close_class_device(struct sysfs_class_device *dev); -extern struct sysfs_class_device *sysfs_open_class_device_path - (const char *path); -extern struct sysfs_class_device *sysfs_open_class_device - (const char *classname, const char *name); -extern struct sysfs_class_device *sysfs_get_classdev_parent - (struct sysfs_class_device *clsdev); -extern struct sysfs_attribute *sysfs_get_classdev_attr - (struct sysfs_class_device *clsdev, const char *name); -extern struct dlist *sysfs_get_classdev_attributes - (struct sysfs_class_device *clsdev); -extern struct sysfs_device *sysfs_get_classdev_device - (struct sysfs_class_device *clsdev); -extern void sysfs_close_class(struct sysfs_class *cls); -extern struct sysfs_class *sysfs_open_class(const char *name); -extern struct sysfs_class_device *sysfs_get_class_device - (struct sysfs_class *cls, const char *name); -extern struct dlist *sysfs_get_class_devices(struct sysfs_class *cls); - -/* generic sysfs bus access */ -extern void sysfs_close_bus(struct sysfs_bus *bus); -extern struct sysfs_bus *sysfs_open_bus(const char *name); -extern struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus); -extern struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus); -extern struct sysfs_device *sysfs_get_bus_device - (struct sysfs_bus *bus, const char *id); -extern struct sysfs_driver *sysfs_get_bus_driver - (struct sysfs_bus *bus, const char *drvname); - -/** - * sort_list: sorter function to keep list elements sorted in alphabetical - * order. Just does a strncmp as you can see :) - * - * Returns 1 if less than 0 otherwise - * - * NOTE: We take care to have a statically allocated "name" as the first - * lement of all libsysfs structures. Hence, this function will work - * AS IS for _ALL_ the lists that have to be sorted. - */ -static inline int sort_list(void *new_elem, void *old_elem) -{ - return ((strncmp(((struct sysfs_attribute *)new_elem)->name, - ((struct sysfs_attribute *)old_elem)->name, - strlen(((struct sysfs_attribute *)new_elem)->name))) < 0 ? 1 : 0); -} - - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBSYSFS_H_ */ diff --git a/libsysfs/sysfs_bus.c b/libsysfs/sysfs_bus.c deleted file mode 100644 index 921ef32094..0000000000 --- a/libsysfs/sysfs_bus.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * sysfs_bus.c - * - * Generic bus utility functions for libsysfs - * - * Copyright (C) IBM Corp. 2003-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "libsysfs.h" -#include "sysfs.h" - -static void sysfs_close_dev(void *dev) -{ - sysfs_close_device((struct sysfs_device *)dev); -} - -static void sysfs_close_drv(void *drv) -{ - sysfs_close_driver((struct sysfs_driver *)drv); -} - -/* - * compares names. - * @a: name looked for - * @b: sysfs_device comparing being compared - * returns 1 if a==b->name or 0 not equal - */ -static int name_equal(void *a, void *b) -{ - if (!a || !b) - return 0; - - if (strcmp(((char *)a), ((struct sysfs_device *)b)->name) == 0) - return 1; - - return 0; -} - -/** - * sysfs_close_bus: close single bus - * @bus: bus structure - */ -void sysfs_close_bus(struct sysfs_bus *bus) -{ - if (bus) { - if (bus->attrlist) - dlist_destroy(bus->attrlist); - if (bus->devices) - dlist_destroy(bus->devices); - if (bus->drivers) - dlist_destroy(bus->drivers); - free(bus); - } -} - -/** - * alloc_bus: mallocs new bus structure - * returns sysfs_bus_bus struct or NULL - */ -static struct sysfs_bus *alloc_bus(void) -{ - return (struct sysfs_bus *)calloc(1, sizeof(struct sysfs_bus)); -} - -/** - * sysfs_get_bus_devices: gets all devices for bus - * @bus: bus to get devices for - * returns dlist of devices with success and NULL with failure - */ -struct dlist *sysfs_get_bus_devices(struct sysfs_bus *bus) -{ - struct sysfs_device *dev; - struct dlist *linklist; - char path[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; - char target[SYSFS_PATH_MAX]; - char *curlink; - - if (!bus) { - errno = EINVAL; - return NULL; - } - memset(path, 0, SYSFS_PATH_MAX); - safestrcpy(path, bus->path); - safestrcat(path, "/"); - safestrcat(path, SYSFS_DEVICES_NAME); - - linklist = read_dir_links(path); - if (linklist) { - dlist_for_each_data(linklist, curlink, char) { - if (bus->devices) { - dev = (struct sysfs_device *) - dlist_find_custom(bus->devices, - (void *)curlink, name_equal); - if (dev) - continue; - } - safestrcpy(devpath, path); - safestrcat(devpath, "/"); - safestrcat(devpath, curlink); - if (sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) { - dprintf("Error getting link - %s\n", devpath); - continue; - } - dev = sysfs_open_device_path(target); - if (!dev) { - dprintf("Error opening device at %s\n", - target); - continue; - } - if (!bus->devices) - bus->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_dev); - dlist_unshift_sorted(bus->devices, dev, sort_list); - } - sysfs_close_list(linklist); - } - return (bus->devices); -} - -/** - * sysfs_get_bus_drivers: gets all drivers for bus - * @bus: bus to get devices for - * returns dlist of devices with success and NULL with failure - */ -struct dlist *sysfs_get_bus_drivers(struct sysfs_bus *bus) -{ - struct sysfs_driver *drv; - struct dlist *dirlist; - char path[SYSFS_PATH_MAX], drvpath[SYSFS_PATH_MAX]; - char *curdir; - - if (!bus) { - errno = EINVAL; - return NULL; - } - memset(path, 0, SYSFS_PATH_MAX); - safestrcpy(path, bus->path); - safestrcat(path, "/"); - safestrcat(path, SYSFS_DRIVERS_NAME); - - dirlist = read_dir_subdirs(path); - if (dirlist) { - dlist_for_each_data(dirlist, curdir, char) { - if (bus->drivers) { - drv = (struct sysfs_driver *) - dlist_find_custom(bus->drivers, - (void *)curdir, name_equal); - if (drv) - continue; - } - safestrcpy(drvpath, path); - safestrcat(drvpath, "/"); - safestrcat(drvpath, curdir); - drv = sysfs_open_driver_path(drvpath); - if (!drv) { - dprintf("Error opening driver at %s\n", - drvpath); - continue; - } - if (!bus->drivers) - bus->drivers = dlist_new_with_delete - (sizeof(struct sysfs_driver), - sysfs_close_drv); - dlist_unshift_sorted(bus->drivers, drv, sort_list); - } - sysfs_close_list(dirlist); - } - return (bus->drivers); -} - -/** - * sysfs_open_bus: opens specific bus and all its devices on system - * returns sysfs_bus structure with success or NULL with error. - */ -struct sysfs_bus *sysfs_open_bus(const char *name) -{ - struct sysfs_bus *bus; - char buspath[SYSFS_PATH_MAX]; - - if (!name) { - errno = EINVAL; - return NULL; - } - - memset(buspath, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(buspath, SYSFS_PATH_MAX)) { - dprintf("Sysfs not supported on this system\n"); - return NULL; - } - - safestrcat(buspath, "/"); - safestrcat(buspath, SYSFS_BUS_NAME); - safestrcat(buspath, "/"); - safestrcat(buspath, name); - if (sysfs_path_is_dir(buspath)) { - dprintf("Invalid path to bus: %s\n", buspath); - return NULL; - } - bus = alloc_bus(); - if (!bus) { - dprintf("calloc failed\n"); - return NULL; - } - safestrcpy(bus->name, name); - safestrcpy(bus->path, buspath); - if (sysfs_remove_trailing_slash(bus->path)) { - dprintf("Incorrect path to bus %s\n", bus->path); - sysfs_close_bus(bus); - return NULL; - } - - return bus; -} - -/** - * sysfs_get_bus_device: Get specific device on bus using device's id - * @bus: bus to find device on - * @id: bus_id for device - * returns struct sysfs_device reference or NULL if not found. - */ -struct sysfs_device *sysfs_get_bus_device(struct sysfs_bus *bus, - const char *id) -{ - struct sysfs_device *dev = NULL; - char devpath[SYSFS_PATH_MAX], target[SYSFS_PATH_MAX]; - - if (!bus || !id) { - errno = EINVAL; - return NULL; - } - - if (bus->devices) { - dev = (struct sysfs_device *)dlist_find_custom - (bus->devices, (void *)id, name_equal); - if (dev) - return dev; - } - safestrcpy(devpath, bus->path); - safestrcat(devpath, "/"); - safestrcat(devpath, SYSFS_DEVICES_NAME); - safestrcat(devpath, "/"); - safestrcat(devpath, id); - if (sysfs_path_is_link(devpath)) { - dprintf("No such device %s on bus %s?\n", id, bus->name); - return NULL; - } - if (!sysfs_get_link(devpath, target, SYSFS_PATH_MAX)) { - dev = sysfs_open_device_path(target); - if (!dev) { - dprintf("Error opening device at %s\n", target); - return NULL; - } - if (!bus->devices) - bus->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_dev); - dlist_unshift_sorted(bus->devices, dev, sort_list); - } - return dev; -} - -/** - * sysfs_get_bus_driver: Get specific driver on bus using driver name - * @bus: bus to find driver on - * @drvname: name of driver - * returns struct sysfs_driver reference or NULL if not found. - */ -struct sysfs_driver *sysfs_get_bus_driver(struct sysfs_bus *bus, - const char *drvname) -{ - struct sysfs_driver *drv; - char drvpath[SYSFS_PATH_MAX]; - - if (!bus || !drvname) { - errno = EINVAL; - return NULL; - } - - if (bus->drivers) { - drv = (struct sysfs_driver *)dlist_find_custom - (bus->drivers, (void *)drvname, name_equal); - if (drv) - return drv; - } - safestrcpy(drvpath, bus->path); - safestrcat(drvpath, "/"); - safestrcat(drvpath, SYSFS_DRIVERS_NAME); - safestrcat(drvpath, "/"); - safestrcat(drvpath, drvname); - drv = sysfs_open_driver_path(drvpath); - if (!drv) { - dprintf("Error opening driver at %s\n", drvpath); - return NULL; - } - if (!bus->drivers) - bus->drivers = dlist_new_with_delete - (sizeof(struct sysfs_driver), - sysfs_close_drv); - dlist_unshift_sorted(bus->drivers, drv, sort_list); - return drv; -} - diff --git a/libsysfs/sysfs_class.c b/libsysfs/sysfs_class.c deleted file mode 100644 index 102f09f17a..0000000000 --- a/libsysfs/sysfs_class.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * sysfs_class.c - * - * Generic class utility functions for libsysfs - * - * Copyright (C) IBM Corp. 2003-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "libsysfs.h" -#include "sysfs.h" - -/** - * sysfs_close_class_device: closes a single class device. - * @dev: class device to close. - */ -void sysfs_close_class_device(struct sysfs_class_device *dev) -{ - if (dev) { - if (dev->parent) - sysfs_close_class_device(dev->parent); - if (dev->sysdevice) - sysfs_close_device(dev->sysdevice); - if (dev->attrlist) - dlist_destroy(dev->attrlist); - free(dev); - } -} - -static void sysfs_close_cls_dev(void *dev) -{ - sysfs_close_class_device((struct sysfs_class_device *)dev); -} - -/** - * sysfs_close_class: close the given class - * @cls: sysfs_class to close - */ -void sysfs_close_class(struct sysfs_class *cls) -{ - if (cls) { - if (cls->devices) - dlist_destroy(cls->devices); - if (cls->attrlist) - dlist_destroy(cls->attrlist); - free(cls); - } -} - -static int cdev_name_equal(void *a, void *b) -{ - if (!a || !b) - return 0; - - if (strncmp((char *)a, ((struct sysfs_class_device *)b)->name, - strlen((char *)a)) == 0) - return 1; - - return 0; -} - -static struct sysfs_class *alloc_class(void) -{ - return (struct sysfs_class *) calloc(1, sizeof(struct sysfs_class)); -} - -/** - * alloc_class_device: mallocs and initializes new class device struct. - * returns sysfs_class_device or NULL. - */ -static struct sysfs_class_device *alloc_class_device(void) -{ - struct sysfs_class_device *dev; - - dev = calloc(1, sizeof(struct sysfs_class_device)); - return dev; -} - -/** - * set_classdev_classname: Grabs classname from path - * @cdev: class device to set - * Returns nothing - */ -static void set_classdev_classname(struct sysfs_class_device *cdev) -{ - char *c, *e; - int count = 0; - - c = strstr(cdev->path, SYSFS_CLASS_NAME); - if (c == NULL) { - c = strstr(cdev->path, SYSFS_BLOCK_NAME); - } else { - c = strstr(c, "/"); - } - - if (c == NULL) - safestrcpy(cdev->classname, SYSFS_UNKNOWN); - else { - if (*c == '/') - c++; - e = c; - while (e != NULL && *e != '/' && *e != '\0') { - e++; - count++; - } - strncpy(cdev->classname, c, count); - } -} - -/** - * sysfs_open_class_device_path: Opens and populates class device - * @path: path to class device. - * returns struct sysfs_class_device with success and NULL with error. - */ -struct sysfs_class_device *sysfs_open_class_device_path(const char *path) -{ - struct sysfs_class_device *cdev; - char temp_path[SYSFS_PATH_MAX]; - - if (!path) { - errno = EINVAL; - return NULL; - } - - /* - * Post linux-2.6.14 driver model supports nested classes with - * links to the nested hierarchy at /sys/class/xxx/. Check for - * a link to the actual class device if a directory isn't found - */ - if (sysfs_path_is_dir(path)) { - dprintf("%s: Directory not found, checking for a link\n", path); - if (!sysfs_path_is_link(path)) { - if (sysfs_get_link(path, temp_path, SYSFS_PATH_MAX)) { - dprintf("Error retrieving link at %s\n", path); - return NULL; - } - } else { - dprintf("%s is not a valid class device path\n", path); - return NULL; - } - } else - safestrcpy(temp_path, path); - - cdev = alloc_class_device(); - if (!cdev) { - dprintf("calloc failed\n"); - return NULL; - } - if (sysfs_get_name_from_path(temp_path, cdev->name, SYSFS_NAME_LEN)) { - errno = EINVAL; - dprintf("Error getting class device name\n"); - sysfs_close_class_device(cdev); - return NULL; - } - - safestrcpy(cdev->path, temp_path); - if (sysfs_remove_trailing_slash(cdev->path)) { - dprintf("Invalid path to class device %s\n", cdev->path); - sysfs_close_class_device(cdev); - return NULL; - } - set_classdev_classname(cdev); - - return cdev; -} - -/** - * get_blockdev_parent: Get the parent class device for a "block" subsystem - * device if present - * @clsdev: block subsystem class device whose parent needs to be found - * Returns 0 on success and 1 on error - */ -static int get_blockdev_parent(struct sysfs_class_device *clsdev) -{ - char parent_path[SYSFS_PATH_MAX]; - char *c; - - safestrcpy(parent_path, clsdev->path); - c = strstr(parent_path, SYSFS_BLOCK_NAME); - if (c == NULL) { - dprintf("Class device %s does not belong to BLOCK subsystem\n", - clsdev->name); - return 1; - } - c += strlen(SYSFS_BLOCK_NAME); - if (*c == '/') - c++; - else - goto errout; - - /* validate whether the given class device is a partition or not */ - if ((strncmp(c, clsdev->name, strlen(clsdev->name))) == 0) { - dprintf("%s not a partition\n", clsdev->name); - return 1; - } - - c = strchr(c, '/'); - if (c == NULL) - goto errout; - - *c = '\0'; - - clsdev->parent = sysfs_open_class_device_path(parent_path); - if (!clsdev->parent) { - dprintf("Error opening the parent class device at %s\n", - parent_path); - return 1; - } - return 0; - -errout: - dprintf("Invalid path %s\n", clsdev->path); - return 1; -} - -/** - * sysfs_get_classdev_parent: Retrieves the parent of a class device. - * eg., when working with hda1, this function can be used to retrieve the - * sysfs_class_device for hda - * - * @clsdev: class device whose parent details are required. - * Returns sysfs_class_device of the parent on success, NULL on failure - */ -struct sysfs_class_device *sysfs_get_classdev_parent - (struct sysfs_class_device *clsdev) -{ - if (!clsdev) { - errno = EINVAL; - return NULL; - } - if (clsdev->parent) - return (clsdev->parent); - - /* - * As of now, only block devices have a parent child heirarchy in sysfs - * We do not know, if, in the future, more classes will have a similar - * structure. Hence, we now call a specialized function for block and - * later we can add support functions for other subsystems as required. - */ - if (!(strncmp(clsdev->classname, SYSFS_BLOCK_NAME, - sizeof(SYSFS_BLOCK_NAME)))) { - if ((get_blockdev_parent(clsdev)) == 0) - return (clsdev->parent); - } - return NULL; -} - -/** - * get_classdev_path: given the class and a device in the class, return the - * absolute path to the device - * @classname: name of the class - * @clsdev: the class device - * @path: buffer to return path - * @psize: size of "path" - * Returns 0 on SUCCESS or -1 on error - */ -static int get_classdev_path(const char *classname, const char *clsdev, - char *path, size_t len) -{ - if (!classname || !clsdev || !path) { - errno = EINVAL; - return -1; - } - if (sysfs_get_mnt_path(path, len) != 0) { - dprintf("Error getting sysfs mount path\n"); - return -1; - } - if (strncmp(classname, SYSFS_BLOCK_NAME, - sizeof(SYSFS_BLOCK_NAME)) == 0) { - safestrcatmax(path, "/", len); - safestrcatmax(path, SYSFS_BLOCK_NAME, len); - } else { - safestrcatmax(path, "/", len); - safestrcatmax(path, SYSFS_CLASS_NAME, len); - safestrcatmax(path, "/", len); - safestrcatmax(path, classname, len); - } - safestrcatmax(path, "/", len); - safestrcatmax(path, clsdev, len); - return 0; -} - -/** - * sysfs_open_class_device: Locates a specific class_device and returns it. - * Class_device must be closed using sysfs_close_class_device - * @classname: Class to search - * @name: name of the class_device - * - * NOTE: - * Call sysfs_close_class_device() to close the class device - */ -struct sysfs_class_device *sysfs_open_class_device - (const char *classname, const char *name) -{ - char devpath[SYSFS_PATH_MAX]; - struct sysfs_class_device *cdev; - - if (!classname || !name) { - errno = EINVAL; - return NULL; - } - - memset(devpath, 0, SYSFS_PATH_MAX); - if ((get_classdev_path(classname, name, devpath, - SYSFS_PATH_MAX)) != 0) { - dprintf("Error getting to device %s on class %s\n", - name, classname); - return NULL; - } - - cdev = sysfs_open_class_device_path(devpath); - if (!cdev) { - dprintf("Error getting class device %s from class %s\n", - name, classname); - return NULL; - } - return cdev; -} - -/** - * sysfs_get_classdev_attr: searches class device's attributes by name - * @clsdev: class device to look through - * @name: attribute name to get - * returns sysfs_attribute reference with success or NULL with error - */ -struct sysfs_attribute *sysfs_get_classdev_attr - (struct sysfs_class_device *clsdev, const char *name) -{ - if (!clsdev || !name) { - errno = EINVAL; - return NULL; - } - return get_attribute(clsdev, (char *)name); -} - -/** - * sysfs_get_classdev_attributes: gets list of classdev attributes - * @clsdev: class device whose attributes list is needed - * returns dlist of attributes on success or NULL on error - */ -struct dlist *sysfs_get_classdev_attributes(struct sysfs_class_device *clsdev) -{ - if (!clsdev) { - errno = EINVAL; - return NULL; - } - return get_attributes_list(clsdev); -} - -/** - * sysfs_get_classdev_device: gets the sysfs_device associated with the - * given sysfs_class_device - * @clsdev: class device whose associated sysfs_device is needed - * returns struct sysfs_device * on success or NULL on error - */ -struct sysfs_device *sysfs_get_classdev_device - (struct sysfs_class_device *clsdev) -{ - char linkpath[SYSFS_PATH_MAX], devpath[SYSFS_PATH_MAX]; - - if (!clsdev) { - errno = EINVAL; - return NULL; - } - - if (clsdev->sysdevice) - return clsdev->sysdevice; - - memset(linkpath, 0, SYSFS_PATH_MAX); - safestrcpy(linkpath, clsdev->path); - safestrcat(linkpath, "/device"); - if (!sysfs_path_is_link(linkpath)) { - memset(devpath, 0, SYSFS_PATH_MAX); - if (!sysfs_get_link(linkpath, devpath, SYSFS_PATH_MAX)) - clsdev->sysdevice = sysfs_open_device_path(devpath); - } - return clsdev->sysdevice; -} - -/** - * sysfs_open_class: opens specific class and all its devices on system - * returns sysfs_class structure with success or NULL with error. - */ -struct sysfs_class *sysfs_open_class(const char *name) -{ - struct sysfs_class *cls = NULL; - char classpath[SYSFS_PATH_MAX]; - - if (!name) { - errno = EINVAL; - return NULL; - } - - memset(classpath, 0, SYSFS_PATH_MAX); - if ((sysfs_get_mnt_path(classpath, SYSFS_PATH_MAX)) != 0) { - dprintf("Sysfs not supported on this system\n"); - return NULL; - } - - /* - * We shall now treat "block" also as a class. Hence, check here - * if "name" is "block" and proceed accordingly - */ - if (strcmp(name, SYSFS_BLOCK_NAME) == 0) { - safestrcat(classpath, "/"); - safestrcat(classpath, SYSFS_BLOCK_NAME); - } else { - safestrcat(classpath, "/"); - safestrcat(classpath, SYSFS_CLASS_NAME); - safestrcat(classpath, "/"); - safestrcat(classpath, name); - } - if (sysfs_path_is_dir(classpath)) { - dprintf("Class %s not found on the system\n", name); - return NULL; - } - - cls = alloc_class(); - if (cls == NULL) { - dprintf("calloc failed\n"); - return NULL; - } - safestrcpy(cls->name, name); - safestrcpy(cls->path, classpath); - if ((sysfs_remove_trailing_slash(cls->path)) != 0) { - dprintf("Invalid path to class device %s\n", cls->path); - sysfs_close_class(cls); - return NULL; - } - - return cls; -} - -/** - * sysfs_get_class_device: get specific class device using the device's id - * @cls: sysfs_class to find the device on - * @name: name of the class device to look for - * - * Returns sysfs_class_device * on success and NULL on failure - */ -struct sysfs_class_device *sysfs_get_class_device(struct sysfs_class *cls, - const char *name) -{ - char path[SYSFS_PATH_MAX]; - struct sysfs_class_device *cdev = NULL; - - if (!cls || !name) { - errno = EINVAL; - return NULL; - } - - if (cls->devices) { - cdev = (struct sysfs_class_device *)dlist_find_custom - (cls->devices, (void *)name, cdev_name_equal); - if (cdev) - return cdev; - } - - safestrcpy(path, cls->path); - safestrcat(path, "/"); - safestrcat(path, name); - cdev = sysfs_open_class_device_path(path); - if (!cdev) { - dprintf("Error opening class device at %s\n", path); - return NULL; - } - if (!cls->devices) - cls->devices = dlist_new_with_delete - (sizeof(struct sysfs_class_device), - sysfs_close_cls_dev); - - dlist_unshift_sorted(cls->devices, cdev, sort_list); - return cdev; -} - -/** - * Add class devices to list - */ -static void add_cdevs_to_classlist(struct sysfs_class *cls, struct dlist *list) -{ - char path[SYSFS_PATH_MAX], *cdev_name; - struct sysfs_class_device *cdev = NULL; - - if (cls == NULL || list == NULL) - return; - - dlist_for_each_data(list, cdev_name, char) { - if (cls->devices) { - cdev = (struct sysfs_class_device *) - dlist_find_custom(cls->devices, - (void *)cdev_name, cdev_name_equal); - if (cdev) - continue; - } - safestrcpy(path, cls->path); - safestrcat(path, "/"); - safestrcat(path, cdev_name); - cdev = sysfs_open_class_device_path(path); - if (cdev) { - if (!cls->devices) - cls->devices = dlist_new_with_delete - (sizeof(struct sysfs_class_device), - sysfs_close_cls_dev); - dlist_unshift_sorted(cls->devices, cdev, - sort_list); - } - } -} - -/** - * sysfs_get_class_devices: get all class devices in the given class - * @cls: sysfs_class whose devices list is needed - * - * Returns a dlist of sysfs_class_device * on success and NULL on failure - */ -struct dlist *sysfs_get_class_devices(struct sysfs_class *cls) -{ - char path[SYSFS_PATH_MAX]; - struct dlist *dirlist, *linklist; - - if (!cls) { - errno = EINVAL; - return NULL; - } - - /* - * Post linux-2.6.14, we have nested classes and links under - * /sys/class/xxx/. are also valid class devices - */ - safestrcpy(path, cls->path); - dirlist = read_dir_subdirs(path); - if (dirlist) { - add_cdevs_to_classlist(cls, dirlist); - sysfs_close_list(dirlist); - } - - linklist = read_dir_links(path); - if (linklist) { - add_cdevs_to_classlist(cls, linklist); - sysfs_close_list(linklist); - } - - return cls->devices; -} diff --git a/libsysfs/sysfs_device.c b/libsysfs/sysfs_device.c deleted file mode 100644 index e3d70143f9..0000000000 --- a/libsysfs/sysfs_device.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * sysfs_device.c - * - * Generic device utility functions for libsysfs - * - * Copyright (C) IBM Corp. 2003-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "libsysfs.h" -#include "sysfs.h" - -/** - * get_dev_driver: fills in the dev->driver_name field - * Returns 0 on SUCCESS and -1 on error - */ -static int get_dev_driver(struct sysfs_device *dev) -{ - char path[SYSFS_PATH_MAX]; - char devpath[SYSFS_PATH_MAX]; - - if (!dev) { - errno = EINVAL; - return -1; - } - memset(path, 0, SYSFS_PATH_MAX); - memset(devpath, 0, SYSFS_PATH_MAX); - safestrcpymax(path, dev->path, SYSFS_PATH_MAX); - safestrcatmax(path, "/driver", SYSFS_PATH_MAX); - if (!sysfs_path_is_link(path)) { - if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) { - if (sysfs_get_name_from_path(devpath, - dev->driver_name, SYSFS_NAME_LEN)) - return -1; - } - return 0; - } - return -1; -} - -/** - * sysfs_get_device_bus: retrieves the bus name the device is on, checks path - * to bus' link to make sure it has correct device. - * @dev: device to get busname. - * returns 0 with success and -1 with error. - */ -int sysfs_get_device_bus(struct sysfs_device *dev) -{ - char devpath[SYSFS_PATH_MAX]; - char path[SYSFS_PATH_MAX]; - - if (!dev) { - errno = EINVAL; - return -1; - } - - memset(path, 0, SYSFS_PATH_MAX); - memset(devpath, 0, SYSFS_PATH_MAX); - safestrcpymax(path, dev->path, SYSFS_PATH_MAX); - safestrcatmax(path, "/bus", SYSFS_PATH_MAX); - if (!sysfs_path_is_link(path)) { - if (!sysfs_get_link(path, devpath, SYSFS_PATH_MAX)) { - if (sysfs_get_name_from_path(devpath, - dev->bus, SYSFS_NAME_LEN)) - return -1; - } - return 0; - } - return -1; -} - -/** - * sysfs_close_device_tree: closes every device in the supplied tree, - * closing children only. - * @devroot: device root of tree. - */ -void sysfs_close_device_tree(struct sysfs_device *devroot) -{ - if (devroot) { - if (devroot->children) { - struct sysfs_device *child = NULL; - - dlist_for_each_data(devroot->children, child, - struct sysfs_device) { - sysfs_close_device_tree(child); - } - } - sysfs_close_device(devroot); - } -} - -/** - * sysfs_close_device: closes and cleans up a device - * @dev = device to clean up - */ -void sysfs_close_device(struct sysfs_device *dev) -{ - if (dev) { - if (dev->parent) - sysfs_close_device(dev->parent); - if (dev->children && dev->children->count) - dlist_destroy(dev->children); - if (dev->attrlist) - dlist_destroy(dev->attrlist); - free(dev); - } -} - -/** - * alloc_device: allocates and initializes device structure - * returns struct sysfs_device - */ -static struct sysfs_device *alloc_device(void) -{ - return (struct sysfs_device *) calloc(1, sizeof(struct sysfs_device)); -} - -/** - * sysfs_open_device_path: opens and populates device structure - * @path: path to device, this is the /sys/devices/ path - * returns sysfs_device structure with success or NULL with error - */ -struct sysfs_device *sysfs_open_device_path(const char *path) -{ - struct sysfs_device *dev; - - if (!path) { - errno = EINVAL; - return NULL; - } - if (sysfs_path_is_dir(path)) { - dprintf("Incorrect path to device: %s\n", path); - return NULL; - } - dev = alloc_device(); - if (!dev) { - dprintf("Error allocating device at %s\n", path); - return NULL; - } - if (sysfs_get_name_from_path(path, dev->bus_id, SYSFS_NAME_LEN)) { - errno = EINVAL; - dprintf("Error getting device bus_id\n"); - sysfs_close_device(dev); - return NULL; - } - safestrcpy(dev->path, path); - if (sysfs_remove_trailing_slash(dev->path)) { - dprintf("Invalid path to device %s\n", dev->path); - sysfs_close_device(dev); - return NULL; - } - /* - * The "name" attribute no longer exists... return the device's - * sysfs representation instead, in the "dev->name" field, which - * implies that the dev->name and dev->bus_id contain same data. - */ - safestrcpy(dev->name, dev->bus_id); - - if (sysfs_get_device_bus(dev)) - dprintf("Could not get device bus\n"); - - if (get_dev_driver(dev)) { - dprintf("Could not get device %s's driver\n", dev->bus_id); - safestrcpy(dev->driver_name, SYSFS_UNKNOWN); - } - - return dev; -} - -/** - * sysfs_get_device_attr: searches dev's attributes by name - * @dev: device to look through - * @name: attribute name to get - * returns sysfs_attribute reference with success or NULL with error. - */ -struct sysfs_attribute *sysfs_get_device_attr(struct sysfs_device *dev, - const char *name) -{ - if (!dev || !name) { - errno = EINVAL; - return NULL; - } - return get_attribute(dev, (char *)name); -} - -/** - * sysfs_get_device_attributes: gets list of device attributes - * @dev: device whose attributes list is needed - * returns dlist of attributes on success or NULL on error - */ -struct dlist *sysfs_get_device_attributes(struct sysfs_device *dev) -{ - if (!dev) { - errno = EINVAL; - return NULL; - } - return get_attributes_list(dev); -} - -/** - * get_device_absolute_path: looks up the bus the device is on, gets - * absolute path to the device - * @device: device for which path is needed - * @path: buffer to store absolute path - * @psize: size of "path" - * Returns 0 on success -1 on failure - */ -static int get_device_absolute_path(const char *device, const char *bus, - char *path, size_t psize) -{ - char bus_path[SYSFS_PATH_MAX]; - - if (!device || !path) { - errno = EINVAL; - return -1; - } - - memset(bus_path, 0, SYSFS_PATH_MAX); - if (sysfs_get_mnt_path(bus_path, SYSFS_PATH_MAX)) { - dprintf ("Sysfs not supported on this system\n"); - return -1; - } - safestrcat(bus_path, "/"); - safestrcat(bus_path, SYSFS_BUS_NAME); - safestrcat(bus_path, "/"); - safestrcat(bus_path, bus); - safestrcat(bus_path, "/"); - safestrcat(bus_path, SYSFS_DEVICES_NAME); - safestrcat(bus_path, "/"); - safestrcat(bus_path, device); - /* - * We now are at /sys/bus/"bus_name"/devices/"device" which is a link. - * Now read this link to reach to the device. - */ - if (sysfs_get_link(bus_path, path, psize)) { - dprintf("Error getting to device %s\n", device); - return -1; - } - return 0; -} - -/** - * sysfs_open_device: open a device by id (use the "bus" subsystem) - * @bus: bus the device belongs to - * @bus_id: bus_id of the device to open - has to be the "bus_id" in - * /sys/bus/xxx/devices - * returns struct sysfs_device if found, NULL otherwise - * NOTE: - * 1. Use sysfs_close_device to close the device - * 2. Bus the device is on must be supplied - * Use sysfs_find_device_bus to get the bus name - */ -struct sysfs_device *sysfs_open_device(const char *bus, const char *bus_id) -{ - char sysfs_path[SYSFS_PATH_MAX]; - struct sysfs_device *device; - - if (!bus_id || !bus) { - errno = EINVAL; - return NULL; - } - memset(sysfs_path, 0, SYSFS_PATH_MAX); - if (get_device_absolute_path(bus_id, bus, sysfs_path, - SYSFS_PATH_MAX)) { - dprintf("Error getting to device %s\n", bus_id); - return NULL; - } - - device = sysfs_open_device_path(sysfs_path); - if (!device) { - dprintf("Error opening device %s\n", bus_id); - return NULL; - } - return device; -} - -/** - * sysfs_get_device_parent: opens up given device's parent and returns a - * reference to its sysfs_device - * @dev: sysfs_device whose parent is requested - * Returns sysfs_device of the parent on success and NULL on failure - */ -struct sysfs_device *sysfs_get_device_parent(struct sysfs_device *dev) -{ - char ppath[SYSFS_PATH_MAX], dpath[SYSFS_PATH_MAX], *tmp; - - if (!dev) { - errno = EINVAL; - return NULL; - } - - if (dev->parent) - return (dev->parent); - - memset(ppath, 0, SYSFS_PATH_MAX); - memset(dpath, 0, SYSFS_PATH_MAX); - safestrcpy(ppath, dev->path); - tmp = strrchr(ppath, '/'); - if (!tmp) { - dprintf("Invalid path to device %s\n", ppath); - return NULL; - } - if (*(tmp + 1) == '\0') { - *tmp = '\0'; - tmp = strrchr(tmp, '/'); - if (tmp == NULL) { - dprintf("Invalid path to device %s\n", ppath); - return NULL; - } - } - *tmp = '\0'; - - /* Make sure we're not at the top of the device tree */ - sysfs_get_mnt_path(dpath, SYSFS_PATH_MAX); - safestrcat(dpath, "/" SYSFS_DEVICES_NAME); - if (strcmp(dpath, ppath) == 0) { - dprintf("Device at %s does not have a parent\n", dev->path); - return NULL; - } - - dev->parent = sysfs_open_device_path(ppath); - if (!dev->parent) { - dprintf("Error opening device %s's parent at %s\n", - dev->bus_id, ppath); - return NULL; - } - return (dev->parent); -} diff --git a/libsysfs/sysfs_dir.c b/libsysfs/sysfs_dir.c deleted file mode 100644 index 7d98c669c6..0000000000 --- a/libsysfs/sysfs_dir.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * sysfs_dir.c - * - * Directory utility functions for libsysfs - * - * Copyright (C) IBM Corp. 2003-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "libsysfs.h" -#include "sysfs.h" - -static int sort_char(void *new, void *old) -{ - return ((strncmp((char *)new, (char *)old, - strlen((char *)new))) < 0 ? 1 : 0); -} - -/** - * sysfs_del_name: free function for sysfs_open_subsystem_list - * @name: memory area to be freed - */ -static void sysfs_del_name(void *name) -{ - free(name); -} - -/** - * sysfs_del_attribute: routine for dlist integration - */ -static void sysfs_del_attribute(void *attr) -{ - sysfs_close_attribute((struct sysfs_attribute *)attr); -} - -/** - * attr_name_equal: compares attributes by name - * @a: attribute name for comparison - * @b: sysfs_attribute to be compared. - * returns 1 if a==b->name or 0 if not equal - */ -static int attr_name_equal(void *a, void *b) -{ - if (!a || !b) - return 0; - - if (strcmp(((char *)a), ((struct sysfs_attribute *)b)->name) == 0) - return 1; - - return 0; -} - -/** - * sysfs_close_attribute: closes and cleans up attribute - * @sysattr: attribute to close. - */ -void sysfs_close_attribute(struct sysfs_attribute *sysattr) -{ - if (sysattr) { - if (sysattr->value) - free(sysattr->value); - free(sysattr); - } -} - -/** - * alloc_attribute: allocates and initializes attribute structure - * returns struct sysfs_attribute with success and NULL with error. - */ -static struct sysfs_attribute *alloc_attribute(void) -{ - return (struct sysfs_attribute *) - calloc(1, sizeof(struct sysfs_attribute)); -} - -/** - * sysfs_open_attribute: creates sysfs_attribute structure - * @path: path to attribute. - * returns sysfs_attribute struct with success and NULL with error. - */ -struct sysfs_attribute *sysfs_open_attribute(const char *path) -{ - struct sysfs_attribute *sysattr = NULL; - struct stat fileinfo; - - if (!path) { - errno = EINVAL; - return NULL; - } - sysattr = alloc_attribute(); - if (!sysattr) { - dprintf("Error allocating attribute at %s\n", path); - return NULL; - } - if (sysfs_get_name_from_path(path, sysattr->name, - SYSFS_NAME_LEN) != 0) { - dprintf("Error retrieving attrib name from path: %s\n", path); - sysfs_close_attribute(sysattr); - return NULL; - } - safestrcpy(sysattr->path, path); - if ((stat(sysattr->path, &fileinfo)) != 0) { - dprintf("Stat failed: No such attribute?\n"); - sysattr->method = 0; - free(sysattr); - sysattr = NULL; - } else { - if (fileinfo.st_mode & S_IRUSR) - sysattr->method |= SYSFS_METHOD_SHOW; - if (fileinfo.st_mode & S_IWUSR) - sysattr->method |= SYSFS_METHOD_STORE; - } - - return sysattr; -} - -/** - * sysfs_read_attribute: reads value from attribute - * @sysattr: attribute to read - * returns 0 with success and -1 with error. - */ -int sysfs_read_attribute(struct sysfs_attribute *sysattr) -{ - char *fbuf = NULL; - char *vbuf = NULL; - ssize_t length = 0; - long pgsize = 0; - int fd; - - if (!sysattr) { - errno = EINVAL; - return -1; - } - if (!(sysattr->method & SYSFS_METHOD_SHOW)) { - dprintf("Show method not supported for attribute %s\n", - sysattr->path); - errno = EACCES; - return -1; - } - pgsize = getpagesize(); - fbuf = (char *)calloc(1, pgsize+1); - if (!fbuf) { - dprintf("calloc failed\n"); - return -1; - } - if ((fd = open(sysattr->path, O_RDONLY)) < 0) { - dprintf("Error reading attribute %s\n", sysattr->path); - free(fbuf); - return -1; - } - length = read(fd, fbuf, pgsize); - if (length < 0) { - dprintf("Error reading from attribute %s\n", sysattr->path); - close(fd); - free(fbuf); - return -1; - } - if (sysattr->len > 0) { - if ((sysattr->len == length) && - (!(strncmp(sysattr->value, fbuf, length)))) { - close(fd); - free(fbuf); - return 0; - } - free(sysattr->value); - } - sysattr->len = length; - close(fd); - vbuf = (char *)realloc(fbuf, length+1); - if (!vbuf) { - dprintf("realloc failed\n"); - free(fbuf); - return -1; - } - sysattr->value = vbuf; - - return 0; -} - -/** - * sysfs_write_attribute: write value to the attribute - * @sysattr: attribute to write - * @new_value: value to write - * @len: length of "new_value" - * returns 0 with success and -1 with error. - */ -int sysfs_write_attribute(struct sysfs_attribute *sysattr, - const char *new_value, size_t len) -{ - int fd; - int length; - - if (!sysattr || !new_value || len == 0) { - errno = EINVAL; - return -1; - } - - if (!(sysattr->method & SYSFS_METHOD_STORE)) { - dprintf ("Store method not supported for attribute %s\n", - sysattr->path); - errno = EACCES; - return -1; - } - if (sysattr->method & SYSFS_METHOD_SHOW) { - /* - * read attribute again to see if we can get an updated value - */ - if ((sysfs_read_attribute(sysattr))) { - dprintf("Error reading attribute\n"); - return -1; - } - if ((strncmp(sysattr->value, new_value, sysattr->len)) == 0) { - dprintf("Attr %s already has the requested value %s\n", - sysattr->name, new_value); - return 0; - } - } - /* - * open O_WRONLY since some attributes have no "read" but only - * "write" permission - */ - if ((fd = open(sysattr->path, O_WRONLY)) < 0) { - dprintf("Error reading attribute %s\n", sysattr->path); - return -1; - } - - length = write(fd, new_value, len); - if (length < 0) { - dprintf("Error writing to the attribute %s - invalid value?\n", - sysattr->name); - close(fd); - return -1; - } else if ((unsigned int)length != len) { - dprintf("Could not write %zd bytes to attribute %s\n", - len, sysattr->name); - /* - * since we could not write user supplied number of bytes, - * restore the old value if one available - */ - if (sysattr->method & SYSFS_METHOD_SHOW) { - length = write(fd, sysattr->value, sysattr->len); - close(fd); - return -1; - } - } - - /* - * Validate length that has been copied. Alloc appropriate area - * in sysfs_attribute. Verify first if the attribute supports reading - * (show method). If it does not, do not bother - */ - if (sysattr->method & SYSFS_METHOD_SHOW) { - if (length != sysattr->len) { - sysattr->value = (char *)realloc - (sysattr->value, length); - sysattr->len = length; - safestrcpymax(sysattr->value, new_value, length); - } else { - /*"length" of the new value is same as old one */ - safestrcpymax(sysattr->value, new_value, length); - } - } - - close(fd); - return 0; -} - -/** - * add_attribute: open and add attribute at path to given directory - * @dev: device whose attribute is to be added - * @path: path to attribute - * returns pointer to attr added with success and NULL with error. - */ -static struct sysfs_attribute *add_attribute(void *dev, const char *path) -{ - struct sysfs_attribute *attr; - - attr = sysfs_open_attribute(path); - if (!attr) { - dprintf("Error opening attribute %s\n", path); - return NULL; - } - if (attr->method & SYSFS_METHOD_SHOW) { - if (sysfs_read_attribute(attr)) { - dprintf("Error reading attribute %s\n", path); - sysfs_close_attribute(attr); - return NULL; - } - } - - if (!((struct sysfs_device *)dev)->attrlist) { - ((struct sysfs_device *)dev)->attrlist = dlist_new_with_delete - (sizeof(struct sysfs_attribute), sysfs_del_attribute); - } - dlist_unshift_sorted(((struct sysfs_device *)dev)->attrlist, - attr, sort_list); - - return attr; -} - -/* - * get_attribute - given a sysfs_* struct and a name, return the - * sysfs_attribute corresponding to "name" - * returns sysfs_attribute on success and NULL on error - */ -struct sysfs_attribute *get_attribute(void *dev, const char *name) -{ - struct sysfs_attribute *cur = NULL; - char path[SYSFS_PATH_MAX]; - - if (!dev || !name) { - errno = EINVAL; - return NULL; - } - - if (((struct sysfs_device *)dev)->attrlist) { - /* check if attr is already in the list */ - cur = (struct sysfs_attribute *)dlist_find_custom - ((((struct sysfs_device *)dev)->attrlist), - (void *)name, attr_name_equal); - if (cur) - return cur; - } - safestrcpymax(path, ((struct sysfs_device *)dev)->path, - SYSFS_PATH_MAX); - safestrcatmax(path, "/", SYSFS_PATH_MAX); - safestrcatmax(path, name, SYSFS_PATH_MAX); - if (!sysfs_path_is_file(path)) - cur = add_attribute((void *)dev, path); - return cur; -} - -/** - * read_dir_links: grabs links in a specific directory - * @sysdir: sysfs directory to read - * returns list of link names with success and NULL with error. - */ -struct dlist *read_dir_links(const char *path) -{ - DIR *dir = NULL; - struct dirent *dirent = NULL; - char file_path[SYSFS_PATH_MAX], *linkname; - struct dlist *linklist = NULL; - - if (!path) { - errno = EINVAL; - return NULL; - } - dir = opendir(path); - if (!dir) { - dprintf("Error opening directory %s\n", path); - return NULL; - } - while ((dirent = readdir(dir)) != NULL) { - if (0 == strcmp(dirent->d_name, ".")) - continue; - if (0 == strcmp(dirent->d_name, "..")) - continue; - memset(file_path, 0, SYSFS_PATH_MAX); - safestrcpy(file_path, path); - safestrcat(file_path, "/"); - safestrcat(file_path, dirent->d_name); - if (!sysfs_path_is_link(file_path)) { - if (!linklist) { - linklist = dlist_new_with_delete - (SYSFS_NAME_LEN, sysfs_del_name); - if (!linklist) { - dprintf("Error creating list\n"); - return NULL; - } - } - linkname = (char *)calloc(1, SYSFS_NAME_LEN); - safestrcpymax(linkname, dirent->d_name, SYSFS_NAME_LEN); - dlist_unshift_sorted(linklist, linkname, sort_char); - } - } - closedir(dir); - return linklist; -} - -/** - * read_dir_subdirs: grabs subdirs in a specific directory - * @sysdir: sysfs directory to read - * returns list of directory names with success and NULL with error. - */ -struct dlist *read_dir_subdirs(const char *path) -{ - DIR *dir = NULL; - struct dirent *dirent = NULL; - char file_path[SYSFS_PATH_MAX], *dir_name; - struct dlist *dirlist = NULL; - - if (!path) { - errno = EINVAL; - return NULL; - } - dir = opendir(path); - if (!dir) { - dprintf("Error opening directory %s\n", path); - return NULL; - } - while ((dirent = readdir(dir)) != NULL) { - if (0 == strcmp(dirent->d_name, ".")) - continue; - if (0 == strcmp(dirent->d_name, "..")) - continue; - memset(file_path, 0, SYSFS_PATH_MAX); - safestrcpy(file_path, path); - safestrcat(file_path, "/"); - safestrcat(file_path, dirent->d_name); - if (!sysfs_path_is_dir(file_path)) { - if (!dirlist) { - dirlist = dlist_new_with_delete - (SYSFS_NAME_LEN, sysfs_del_name); - if (!dirlist) { - dprintf("Error creating list\n"); - return NULL; - } - } - dir_name = (char *)calloc(1, SYSFS_NAME_LEN); - safestrcpymax(dir_name, dirent->d_name, SYSFS_NAME_LEN); - dlist_unshift_sorted(dirlist, dir_name, sort_char); - } - } - closedir(dir); - return dirlist; -} - -/** - * get_attributes_list: build a list of attributes for the given device - * @dev: devices whose attributes list is required - * returns dlist of attributes on success and NULL on failure - */ -struct dlist *get_attributes_list(void *dev) -{ - DIR *dir = NULL; - struct dirent *dirent = NULL; - struct sysfs_attribute *attr = NULL; - char file_path[SYSFS_PATH_MAX], path[SYSFS_PATH_MAX]; - - if (!dev) { - errno = EINVAL; - return NULL; - } - memset(path, 0, SYSFS_PATH_MAX); - safestrcpy(path, ((struct sysfs_device *)dev)->path); - dir = opendir(path); - if (!dir) { - dprintf("Error opening directory %s\n", path); - return NULL; - } - while ((dirent = readdir(dir)) != NULL) { - if (0 == strcmp(dirent->d_name, ".")) - continue; - if (0 == strcmp(dirent->d_name, "..")) - continue; - memset(file_path, 0, SYSFS_PATH_MAX); - safestrcpy(file_path, path); - safestrcat(file_path, "/"); - safestrcat(file_path, dirent->d_name); - if (!sysfs_path_is_file(file_path)) { - if (((struct sysfs_device *)dev)->attrlist) { - /* check if attr is already in the list */ - attr = (struct sysfs_attribute *) - dlist_find_custom - ((((struct sysfs_device *)dev)->attrlist), - (void *)dirent->d_name, attr_name_equal); - if (attr) - continue; - else - add_attribute(dev, file_path); - } else - attr = add_attribute(dev, file_path); - } - } - closedir(dir); - return ((struct sysfs_device *)dev)->attrlist; -} diff --git a/libsysfs/sysfs_driver.c b/libsysfs/sysfs_driver.c deleted file mode 100644 index c2464faa9e..0000000000 --- a/libsysfs/sysfs_driver.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * sysfs_driver.c - * - * Driver utility functions for libsysfs - * - * Copyright (C) IBM Corp. 2003-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "libsysfs.h" -#include "sysfs.h" - -static void sysfs_close_driver_device(void *device) -{ - sysfs_close_device((struct sysfs_device *)device); -} - -/** - * sysfs_close_driver: closes driver and deletes device lists too - * @driver: driver to close - */ -void sysfs_close_driver(struct sysfs_driver *driver) -{ - if (driver) { - if (driver->devices) - dlist_destroy(driver->devices); - if (driver->attrlist) - dlist_destroy(driver->attrlist); - free(driver); - } -} - -/** - * alloc_driver: allocates and initializes driver - * returns struct sysfs_driver with success and NULL with error. - */ -static struct sysfs_driver *alloc_driver(void) -{ - return (struct sysfs_driver *)calloc(1, sizeof(struct sysfs_driver)); -} - -/** - * get_driver_bus: gets bus the driver is on - * Returns 0 on success and 1 on error - */ -static int get_driver_bus(struct sysfs_driver *drv) -{ - char drvpath[SYSFS_PATH_MAX], *c = NULL; - - if (!drv) { - errno = EINVAL; - return 1; - } - - safestrcpy(drvpath, drv->path); - c = strstr(drvpath, SYSFS_DRIVERS_NAME); - if (c == NULL) - return 1; - *--c = '\0'; - c = strstr(drvpath, SYSFS_BUS_NAME); - if (c == NULL) - return 1; - c = strstr(c, "/"); - if (c == NULL) - return 1; - c++; - safestrcpy(drv->bus, c); - return 0; -} - -/** - * sysfs_get_driver_attr: searches drv's attributes by name - * @drv: driver to look through - * @name: attribute name to get - * returns sysfs_attribute reference with success or NULL with error. - */ -struct sysfs_attribute *sysfs_get_driver_attr(struct sysfs_driver *drv, - const char *name) -{ - if (!drv || !name) { - errno = EINVAL; - return NULL; - } - return get_attribute(drv, (char *)name); -} - -/** - * sysfs_get_driver_attributes: gets list of driver attributes - * @dev: driver whose attributes list is needed - * returns dlist of attributes on success or NULL on error - */ -struct dlist *sysfs_get_driver_attributes(struct sysfs_driver *drv) -{ - if (!drv) { - errno = EINVAL; - return NULL; - } - return get_attributes_list(drv); -} - -/** - * sysfs_open_driver_path: opens and initializes driver structure - * @path: path to driver directory - * returns struct sysfs_driver with success and NULL with error - */ -struct sysfs_driver *sysfs_open_driver_path(const char *path) -{ - struct sysfs_driver *driver = NULL; - - if (!path) { - errno = EINVAL; - return NULL; - } - if (sysfs_path_is_dir(path)) { - dprintf("Invalid path to driver: %s\n", path); - return NULL; - } - driver = alloc_driver(); - if (!driver) { - dprintf("Error allocating driver at %s\n", path); - return NULL; - } - if (sysfs_get_name_from_path(path, driver->name, SYSFS_NAME_LEN)) { - dprintf("Error getting driver name from path\n"); - free(driver); - return NULL; - } - safestrcpy(driver->path, path); - if (sysfs_remove_trailing_slash(driver->path)) { - dprintf("Invalid path to driver %s\n", driver->path); - sysfs_close_driver(driver); - return NULL; - } - if (get_driver_bus(driver)) { - dprintf("Could not get the bus driver is on\n"); - sysfs_close_driver(driver); - return NULL; - } - - return driver; -} - -/** - * get_driver_path: looks up the bus the driver is on and builds path to - * the driver. - * @bus: bus on which to search - * @drv: driver to look for - * @path: buffer to return path to driver - * @psize: size of "path" - * Returns 0 on success and -1 on error - */ -static int get_driver_path(const char *bus, const char *drv, - char *path, size_t psize) -{ - if (!bus || !drv || !path || psize == 0) { - errno = EINVAL; - return -1; - } - if (sysfs_get_mnt_path(path, psize)) { - dprintf("Error getting sysfs mount path\n"); - return -1; - } - safestrcatmax(path, "/", psize); - safestrcatmax(path, SYSFS_BUS_NAME, psize); - safestrcatmax(path, "/", psize); - safestrcatmax(path, bus, psize); - safestrcatmax(path, "/", psize); - safestrcatmax(path, SYSFS_DRIVERS_NAME, psize); - safestrcatmax(path, "/", psize); - safestrcatmax(path, drv, psize); - return 0; -} - -/** - * sysfs_open_driver: open driver by name, given its bus - * @bus_name: Name of the bus - * @drv_name: Name of the driver - * Returns the sysfs_driver reference on success and NULL on failure - */ -struct sysfs_driver *sysfs_open_driver(const char *bus_name, - const char *drv_name) -{ - char path[SYSFS_PATH_MAX]; - struct sysfs_driver *driver = NULL; - - if (!drv_name || !bus_name) { - errno = EINVAL; - return NULL; - } - - memset(path, 0, SYSFS_PATH_MAX); - if (get_driver_path(bus_name, drv_name, path, SYSFS_PATH_MAX)) { - dprintf("Error getting to driver %s\n", drv_name); - return NULL; - } - driver = sysfs_open_driver_path(path); - if (!driver) { - dprintf("Error opening driver at %s\n", path); - return NULL; - } - return driver; -} - -/** - * sysfs_get_driver_devices: gets list of devices that use the driver - * @drv: sysfs_driver whose device list is needed - * Returns dlist of struct sysfs_device on success and NULL on failure - */ -struct dlist *sysfs_get_driver_devices(struct sysfs_driver *drv) -{ - char *ln = NULL; - struct dlist *linklist = NULL; - struct sysfs_device *dev = NULL; - - if (!drv) { - errno = EINVAL; - return NULL; - } - - linklist = read_dir_links(drv->path); - if (linklist) { - dlist_for_each_data(linklist, ln, char) { - - if (!strncmp(ln, SYSFS_MODULE_NAME, strlen(ln))) - continue; - - dev = sysfs_open_device(drv->bus, ln); - if (!dev) { - dprintf("Error opening driver's device\n"); - sysfs_close_list(linklist); - return NULL; - } - if (!drv->devices) { - drv->devices = dlist_new_with_delete - (sizeof(struct sysfs_device), - sysfs_close_driver_device); - if (!drv->devices) { - dprintf("Error creating device list\n"); - sysfs_close_list(linklist); - return NULL; - } - } - dlist_unshift_sorted(drv->devices, dev, sort_list); - } - sysfs_close_list(linklist); - } - return drv->devices; -} diff --git a/libsysfs/sysfs_utils.c b/libsysfs/sysfs_utils.c deleted file mode 100644 index c5558a43a1..0000000000 --- a/libsysfs/sysfs_utils.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * sysfs_utils.c - * - * System utility functions for libsysfs - * - * Copyright (C) IBM Corp. 2003-2005 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ -#include "libsysfs.h" -#include "sysfs.h" - -/** - * sysfs_remove_trailing_slash: Removes any trailing '/' in the given path - * @path: Path to look for the trailing '/' - * Returns 0 on success 1 on error - */ -int sysfs_remove_trailing_slash(char *path) -{ - size_t len; - - if (!path) { - errno = EINVAL; - return 1; - } - - len = strlen(path); - while (len > 0 && path[len-1] == '/') - path[--len] = '\0'; - return 0; -} - -/* - * sysfs_get_mnt_path: Gets the sysfs mount point. - * @mnt_path: place to put "sysfs" mount point - * @len: size of mnt_path - * returns 0 with success and -1 with error. - */ -int sysfs_get_mnt_path(char *mnt_path, size_t len) -{ - static char sysfs_path[SYSFS_PATH_MAX] = ""; - const char *sysfs_path_env; - - /* evaluate only at the first call */ - if (sysfs_path[0] == '\0') { - /* possible overrride of real mount path */ - sysfs_path_env = getenv(SYSFS_PATH_ENV); - if (sysfs_path_env != NULL) { - safestrcpymax(mnt_path, sysfs_path_env, len); - sysfs_remove_trailing_slash(mnt_path); - return 0; - } - safestrcpymax(mnt_path, SYSFS_MNT_PATH, len); - } - - return 0; -} - -/** - * sysfs_get_name_from_path: returns last name from a "/" delimited path - * @path: path to get name from - * @name: where to put name - * @len: size of name - */ -int sysfs_get_name_from_path(const char *path, char *name, size_t len) -{ - char tmp[SYSFS_PATH_MAX]; - char *n = NULL; - - if (!path || !name || len == 0) { - errno = EINVAL; - return -1; - } - memset(tmp, 0, SYSFS_PATH_MAX); - safestrcpy(tmp, path); - n = strrchr(tmp, '/'); - if (n == NULL) { - errno = EINVAL; - return -1; - } - if (*(n+1) == '\0') { - *n = '\0'; - n = strrchr(tmp, '/'); - if (n == NULL) { - errno = EINVAL; - return -1; - } - } - n++; - safestrcpymax(name, n, len); - return 0; -} - -/** - * sysfs_get_link: returns link source - * @path: symbolic link's path - * @target: where to put name - * @len: size of name - */ -int sysfs_get_link(const char *path, char *target, size_t len) -{ - char devdir[SYSFS_PATH_MAX]; - char linkpath[SYSFS_PATH_MAX]; - char temp_path[SYSFS_PATH_MAX]; - char *d = NULL, *s = NULL; - int slashes = 0, count = 0; - - if (!path || !target || len == 0) { - errno = EINVAL; - return -1; - } - - memset(devdir, 0, SYSFS_PATH_MAX); - memset(linkpath, 0, SYSFS_PATH_MAX); - memset(temp_path, 0, SYSFS_PATH_MAX); - safestrcpy(devdir, path); - - if ((readlink(path, linkpath, SYSFS_PATH_MAX)) < 0) { - return -1; - } - d = linkpath; - /* - * Three cases here: - * 1. relative path => format ../.. - * 2. absolute path => format /abcd/efgh - * 3. relative path _from_ this dir => format abcd/efgh - */ - switch (*d) { - case '.': - /* - * handle the case where link is of type ./abcd/xxx - */ - safestrcpy(temp_path, devdir); - if (*(d+1) == '/') - d += 2; - else if (*(d+1) == '.') - goto parse_path; - s = strrchr(temp_path, '/'); - if (s != NULL) { - *(s+1) = '\0'; - safestrcat(temp_path, d); - } else { - safestrcpy(temp_path, d); - } - safestrcpymax(target, temp_path, len); - break; - /* - * relative path, getting rid of leading "../.." - */ -parse_path: - while (*d == '/' || *d == '.') { - if (*d == '/') - slashes++; - d++; - } - d--; - s = &devdir[strlen(devdir)-1]; - while (s != NULL && count != (slashes+1)) { - s--; - if (*s == '/') - count++; - } - safestrcpymax(s, d, (SYSFS_PATH_MAX-strlen(devdir))); - safestrcpymax(target, devdir, len); - break; - case '/': - /* absolute path - copy as is */ - safestrcpymax(target, linkpath, len); - break; - default: - /* relative path from this directory */ - safestrcpy(temp_path, devdir); - s = strrchr(temp_path, '/'); - if (s != NULL) { - *(s+1) = '\0'; - safestrcat(temp_path, linkpath); - } else { - safestrcpy(temp_path, linkpath); - } - safestrcpymax(target, temp_path, len); - } - return 0; -} - -/** - * sysfs_close_list: generic list free routine - * @list: dlist to free - * Returns nothing - */ -void sysfs_close_list(struct dlist *list) -{ - if (list) - dlist_destroy(list); -} - -/** - * sysfs_open_directory_list: gets a list of all directories under "path" - * @path: path to read - * Returns a dlist of supported names or NULL no directories (errno is set - * in case of error - */ -struct dlist *sysfs_open_directory_list(const char *path) -{ - if (!path) - return NULL; - - return (read_dir_subdirs(path)); -} - -/** - * sysfs_path_is_dir: Check if the path supplied points to a directory - * @path: path to validate - * Returns 0 if path points to dir, 1 otherwise - */ -int sysfs_path_is_dir(const char *path) -{ - struct stat astats; - - if (!path) { - errno = EINVAL; - return 1; - } - if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed\n"); - return 1; - } - if (S_ISDIR(astats.st_mode)) - return 0; - - return 1; -} - -/** - * sysfs_path_is_link: Check if the path supplied points to a link - * @path: path to validate - * Returns 0 if path points to link, 1 otherwise - */ -int sysfs_path_is_link(const char *path) -{ - struct stat astats; - - if (!path) { - errno = EINVAL; - return 1; - } - if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed\n"); - return 1; - } - if (S_ISLNK(astats.st_mode)) - return 0; - - return 1; -} - -/** - * sysfs_path_is_file: Check if the path supplied points to a file - * @path: path to validate - * Returns 0 if path points to file, 1 otherwise - */ -int sysfs_path_is_file(const char *path) -{ - struct stat astats; - - if (!path) { - errno = EINVAL; - return 1; - } - if ((lstat(path, &astats)) != 0) { - dprintf("stat() failed\n"); - return 1; - } - if (S_ISREG(astats.st_mode)) - return 0; - - return 1; -} diff --git a/test/simple-build-check.sh b/test/simple-build-check.sh index d1c28749fb..faa7c46432 100755 --- a/test/simple-build-check.sh +++ b/test/simple-build-check.sh @@ -23,8 +23,7 @@ make all $MAKEOPTS USE_LOG=false EXTRAS="$EXTRAS" || exit echo -e "\n\n" # klibc build -[ -z "$KLCC" ] && KLCC=/usr/bin/klcc -if [ -e "$KLCC" ]; then +if [ -n "$KLCC" -a -e "$KLCC" ]; then echo KLCC: "$KLCC" make clean EXTRAS="$EXTRAS" >/dev/null make all -j4 $MAKEOPTS USE_KLIBC=true DEBUG=true EXTRAS="$EXTRAS" KLCC="$KLCC" || exit diff --git a/test/udev-test.pl b/test/udev-test.pl index c33c79b1c0..7ce920092f 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -243,18 +243,18 @@ EOF desc => "test substitution chars", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "Major:8:minor:3:kernelnumber:3:bus:0:0:0:0" , + exp_name => "Major:8:minor:3:kernelnumber:3" , rules => < "test substitution chars (with length limit)", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "M8-m3-n3-b0:0-sIBM" , + exp_name => "M8-m3-n3-bsd-sIBM" , rules => < "program result substitution", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "test-0:0:0:0" , + exp_name => "test-3" , rules => < "test substitution by variable name", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "Major:8-minor:3-kernelnumber:3-bus:0:0:0:0" , + exp_name => "Major:8-minor:3-kernelnumber:3" , rules => < "test substitution by variable name 2", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "Major:8-minor:3-kernelnumber:3-bus:0:0:0:0" , + exp_name => "Major:8-minor:3-kernelnumber:3-name:sda3" , rules => < "test substitution by variable name 3", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "830:0:0:03" , + exp_name => "83sda33" , rules => < "test substitution by variable name 5", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "8330:0:0:0" , + exp_name => "833sda3" , rules => < "program and bus type match", subsys => "block", devpath => "/block/sda", - exp_name => "scsi-0:0:0:0" , + exp_name => "scsi-sda" , rules => < "symlink2-ttyUSB0", exp_target => "ttyUSB0", rules => < "symlink %b substitution", + desc => "symlink %k substitution", subsys => "block", devpath => "/block/sda", - exp_name => "symlink-0:0:0:0", + exp_name => "symlink-sda", exp_target => "node", rules => <; + close $fd; + $dev =~ m/^(.+):(.+)$/; + $ENV{MAJOR} = $1; + $ENV{MINOR} = $2; + # create temporary rules open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules"; print CONF $$rules; diff --git a/udev.c b/udev.c index f2d6f6653c..4762ab1cef 100644 --- a/udev.c +++ b/udev.c @@ -30,13 +30,8 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "udev_version.h" #include "udev_rules.h" -#include "logging.h" #ifdef USE_LOG void log_message(int priority, const char *format, ...) @@ -65,7 +60,9 @@ static void asmlinkage sig_handler(int signum) int main(int argc, char *argv[], char *envp[]) { - struct udevice udev; + struct sysfs_device *dev; + struct udevice *udev; + const char *maj, *min; struct udev_rules rules; const char *action; const char *devpath; @@ -95,7 +92,7 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udev"); if (devnull < 0) err("fatal, could not open /dev/null: %s", strerror(errno)); - udev_init_config(); + udev_config_init(); dbg("version %s", UDEV_VERSION); /* set signal handlers */ @@ -114,10 +111,10 @@ int main(int argc, char *argv[], char *envp[]) devpath = getenv("DEVPATH"); subsystem = getenv("SUBSYSTEM"); /* older kernels passed the SUBSYSTEM only as argument */ - if (!subsystem && argc == 2) + if (subsystem == NULL && argc == 2) subsystem = argv[1]; - if (!action || !subsystem || !devpath) { + if (action == NULL || subsystem == NULL || devpath == NULL) { err("action, subsystem or devpath missing"); goto exit; } @@ -130,25 +127,49 @@ int main(int argc, char *argv[], char *envp[]) setenv("UDEV_LOG", priority, 1); } - udev_init_device(&udev, devpath, subsystem, action); + sysfs_init(); udev_rules_init(&rules, 0); - retval = udev_process_event(&rules, &udev); + dev = sysfs_device_get(devpath); + if (dev == NULL) { + info("unable to open '%s'", devpath); + goto fail; + } - if (!retval && udev_run && !list_empty(&udev.run_list)) { + udev = udev_device_init(); + 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 && udev_run && !list_empty(&udev->run_list)) { struct name_entry *name_loop; dbg("executing run list"); - list_for_each_entry(name_loop, &udev.run_list, node) { + 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:")], devpath, action); else - run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); } } - udev_rules_close(&rules); - udev_cleanup_device(&udev); + udev_device_cleanup(udev); +fail: + udev_rules_cleanup(&rules); + sysfs_cleanup(); exit: logging_close(); diff --git a/udev.h b/udev.h index ca99da512d..c060b8d6ff 100644 --- a/udev.h +++ b/udev.h @@ -24,8 +24,11 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" + #include "list.h" +#include "logging.h" +#include "udev_libc_wrapper.h" +#include "udev_version.h" #define COMMENT_CHARACTER '#' #define PATH_TO_NAME_CHAR '@' @@ -39,24 +42,32 @@ #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" struct udev_rules; -enum device_type { - DEV_UNKNOWN, - DEV_CLASS, - DEV_BLOCK, - DEV_NET, - DEV_DEVICE, +struct sysfs_device { + struct list_head node; /* for device cache */ + char devpath[PATH_SIZE]; + char subsystem[NAME_SIZE]; /* $class/$bus/"drivers */ + char kernel_name[NAME_SIZE]; /* device instance name */ + char kernel_number[NAME_SIZE]; + char driver[NAME_SIZE]; /* device driver name */ }; struct udevice { - char devpath[PATH_SIZE]; - char subsystem[NAME_SIZE]; + /* device event */ + struct sysfs_device *dev; + struct sysfs_device dev_local; char action[NAME_SIZE]; - enum device_type type; + /* node */ char name[PATH_SIZE]; struct list_head symlink_list; int symlink_final; @@ -67,42 +78,83 @@ struct udevice { 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 bus_id[NAME_SIZE]; char program_result[PATH_SIZE]; - char kernel_number[NAME_SIZE]; - char kernel_name[NAME_SIZE]; int test_run; }; -extern int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action); -extern void udev_cleanup_device(struct udevice *udev); -extern dev_t get_devt(struct sysfs_class_device *class_dev); -extern int udev_process_event(struct udev_rules *rules, struct udevice *udev); -extern int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev); -extern int udev_remove_device(struct udevice *udev); -extern void udev_init_config(void); -extern int udev_start(void); -extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); +/* udev_config.c */ +extern char udev_root[PATH_SIZE]; +extern char udev_config_filename[PATH_SIZE]; +extern char udev_rules_filename[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(void); +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); +extern struct sysfs_device *sysfs_device_get(const char *devpath); +extern struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev); +extern char *sysfs_attr_get_value(const char *devpath, const char *attr_name); + +/* udev_add.c / udev_remove.c */ +extern int udev_add_device(struct udevice *udev); +extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); +extern int udev_remove_device(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_lookup_name(const char *name, char *devpath, size_t len); extern int udev_db_get_all_entries(struct list_head *name_list); -extern char sysfs_path[PATH_SIZE]; -extern char udev_root[PATH_SIZE]; -extern char udev_config_filename[PATH_SIZE]; -extern char udev_rules_filename[PATH_SIZE]; -extern int udev_log_priority; -extern int udev_run; +/* udev_utils.c */ +struct name_entry { + struct list_head node; + char name[PATH_SIZE]; +}; +extern int log_priority(const char *priority); +extern int name_list_add(struct list_head *name_list, const char *name, int sort); +extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); +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); + +/* udev_utils_string.c */ +extern int strcmp_pattern(const char *p, const char *s); +extern int string_is_true(const char *str); +extern void remove_trailing_chars(char *path, char c); +extern int utf8_encoded_valid_unichar(const char *str); +extern int replace_untrusted_chars(char *str); + +/* 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); + +/* udev_utils_run.c */ +extern int pass_env_to_socket(const char *name, const char *devpath, const char *action); +extern int run_program(const char *command, const char *subsystem, + char *result, size_t ressize, size_t *reslen, int log); #endif diff --git a/udev_add.c b/udev_add.c index bf2d59d198..2c66a0ba8d 100644 --- a/udev_add.c +++ b/udev_add.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,16 +30,10 @@ #include #include #include -#include #include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "udev_version.h" -#include "logging.h" #include "udev_rules.h" #include "udev_selinux.h" @@ -48,25 +43,18 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo struct stat stats; int retval = 0; - switch (udev->type) { - case DEV_BLOCK: + if (major(devt) != 0 && strcmp(udev->dev->subsystem, "block") == 0) mode |= S_IFBLK; - break; - case DEV_CLASS: + else mode |= S_IFCHR; - break; - default: - dbg("unknown node type %c\n", udev->type); - return -EINVAL; - } if (stat(file, &stats) != 0) goto create; - /* preserve node with already correct numbers, to not change the inode number */ + /* preserve node with already correct numbers, to prevent changing the inode number */ if ((stats.st_mode & S_IFMT) == (mode & S_IFMT) && (stats.st_rdev == devt)) { info("preserve file '%s', cause it has correct dev_t", file); - selinux_setfilecon(file, udev->kernel_name, stats.st_mode); + selinux_setfilecon(file, udev->dev->kernel_name, stats.st_mode); goto perms; } @@ -76,7 +64,7 @@ int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mo dbg("already present file '%s' unlinked", file); create: - selinux_setfscreatecon(file, udev->kernel_name, mode); + selinux_setfscreatecon(file, udev->dev->kernel_name, mode); retval = mknod(file, mode, devt); selinux_resetfscreatecon(); if (retval != 0) { @@ -105,7 +93,7 @@ exit: return retval; } -static int create_node(struct udevice *udev, struct sysfs_class_device *class_dev) +static int create_node(struct udevice *udev) { char filename[PATH_SIZE]; struct name_entry *name_loop; @@ -161,13 +149,13 @@ static int create_node(struct udevice *udev, struct sysfs_class_device *class_de /* create all_partitions if requested */ if (udev->partitions) { char partitionname[PATH_SIZE]; - struct sysfs_attribute *attr; + char *attr; int range; /* take the maximum registered minor range */ - attr = sysfs_get_classdev_attr(class_dev, "range"); + attr = sysfs_attr_get_value(udev->dev->devpath, "range"); if (attr) { - range = atoi(attr->value); + range = atoi(attr); if (range > 1) udev->partitions = range-1; } @@ -247,7 +235,7 @@ static int rename_net_if(struct udevice *udev) struct ifreq ifr; int retval; - info("changing net interface name from '%s' to '%s'", udev->kernel_name, udev->name); + info("changing net interface name from '%s' to '%s'", udev->dev->kernel_name, udev->name); if (udev->test_run) return 0; @@ -258,7 +246,7 @@ static int rename_net_if(struct udevice *udev) } memset(&ifr, 0x00, sizeof(struct ifreq)); - strlcpy(ifr.ifr_name, udev->kernel_name, IFNAMSIZ); + strlcpy(ifr.ifr_name, udev->dev->kernel_name, IFNAMSIZ); strlcpy(ifr.ifr_newname, udev->name, IFNAMSIZ); retval = ioctl(sk, SIOCSIFNAME, &ifr); @@ -269,7 +257,7 @@ static int rename_net_if(struct udevice *udev) return retval; } -int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) +int udev_add_device(struct udevice *udev) { char *pos; int retval = 0; @@ -277,16 +265,16 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) dbg("adding name='%s'", udev->name); selinux_init(); - if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { - retval = create_node(udev, class_dev); + if (major(udev->devt)) { + retval = create_node(udev); if (retval != 0) goto exit; if (udev_db_add_device(udev) != 0) dbg("udev_db_add_dev failed, remove might not work for custom names"); - } else if (udev->type == DEV_NET) { + } else if (strcmp(udev->dev->subsystem, "net") == 0) { /* look if we want to change the name of the netif */ - if (strcmp(udev->name, udev->kernel_name) != 0) { + if (strcmp(udev->name, udev->dev->kernel_name) != 0) { retval = rename_net_if(udev); if (retval != 0) goto exit; @@ -296,12 +284,12 @@ int udev_add_device(struct udevice *udev, struct sysfs_class_device *class_dev) * original kernel name sleeps with the fishes and we don't * get an event from the kernel with the new name */ - pos = strrchr(udev->devpath, '/'); + pos = strrchr(udev->dev->devpath, '/'); if (pos != NULL) { pos[1] = '\0'; - strlcat(udev->devpath, udev->name, sizeof(udev->devpath)); - strlcpy(udev->kernel_name, udev->name, sizeof(udev->kernel_name)); - setenv("DEVPATH", udev->devpath, 1); + strlcat(udev->dev->devpath, udev->name, sizeof(udev->dev->devpath)); + strlcpy(udev->dev->kernel_name, udev->name, sizeof(udev->dev->kernel_name)); + setenv("DEVPATH", udev->dev->devpath, 1); setenv("INTERFACE", udev->name, 1); } } diff --git a/udev_config.c b/udev_config.c index c1af7c12ca..a7e19fe864 100644 --- a/udev_config.c +++ b/udev_config.c @@ -28,15 +28,9 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "udev_version.h" -#include "logging.h" /* global variables */ -char sysfs_path[PATH_SIZE]; char udev_root[PATH_SIZE]; char udev_config_filename[PATH_SIZE]; char udev_rules_filename[PATH_SIZE]; @@ -168,7 +162,7 @@ static int parse_config_file(void) return retval; } -void udev_init_config(void) +void udev_config_init(void) { const char *env; @@ -177,7 +171,6 @@ void udev_init_config(void) strcpy(udev_rules_filename, UDEV_RULES_FILE); udev_log_priority = LOG_ERR; udev_run = 1; - sysfs_get_mnt_path(sysfs_path, sizeof(sysfs_path)); /* disable RUN key execution */ env = getenv("UDEV_RUN"); @@ -202,7 +195,6 @@ void udev_init_config(void) if (env) udev_log_priority = log_priority(env); - dbg("sysfs_path='%s'", sysfs_path); dbg("UDEV_CONFIG_FILE='%s'", udev_config_filename); dbg("udev_root='%s'", udev_root); dbg("udev_rules='%s'", udev_rules_filename); diff --git a/udev_db.c b/udev_db.c index 6b9d5e8426..e9ae799132 100644 --- a/udev_db.c +++ b/udev_db.c @@ -30,11 +30,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "logging.h" static int devpath_to_db_path(const char *devpath, char *filename, size_t len) @@ -83,21 +79,21 @@ int udev_db_add_device(struct udevice *udev) /* don't write anything if udev created only the node with the * kernel name without any interesting data to remember */ - if (strcmp(udev->name, udev->kernel_name) == 0 && + if (strcmp(udev->name, udev->dev->kernel_name) == 0 && list_empty(&udev->symlink_list) && list_empty(&udev->env_list) && !udev->partitions && !udev->ignore_remove) { dbg("nothing interesting to store in udevdb, skip"); goto exit; } - devpath_to_db_path(udev->devpath, filename, sizeof(filename)); + devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename)); create_path(filename); 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->devpath, filename); + 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) @@ -132,7 +128,7 @@ int udev_db_get_device(struct udevice *udev, const char *devpath) return -1; } - strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); + strlcpy(udev->dev->devpath, devpath, sizeof(udev->dev->devpath)); cur = 0; while (cur < bufsize) { count = buf_get_line(buf, bufsize, cur); @@ -196,7 +192,7 @@ int udev_db_delete_device(struct udevice *udev) { char filename[PATH_SIZE]; - devpath_to_db_path(udev->devpath, filename, sizeof(filename)); + devpath_to_db_path(udev->dev->devpath, filename, sizeof(filename)); unlink(filename); return 0; diff --git a/udev_device.c b/udev_device.c index 7821c91cb4..0325001428 100644 --- a/udev_device.c +++ b/udev_device.c @@ -26,83 +26,99 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "logging.h" -#include "udev_utils.h" -#include "list.h" +#include "udev_rules.h" -int udev_init_device(struct udevice *udev, const char* devpath, const char *subsystem, const char *action) +struct udevice *udev_device_init(void) { - char *pos; + struct udevice *udev; + 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); - if (subsystem) - strlcpy(udev->subsystem, subsystem, sizeof(udev->subsystem)); + /* set sysfs device to local storage, can be overridden if needed */ + udev->dev = &udev->dev_local; - if (action) - strlcpy(udev->action, action, sizeof(udev->action)); + /* default node permissions */ + udev->mode = 0660; + strcpy(udev->owner, "root"); + strcpy(udev->group, "root"); - if (devpath) { - strlcpy(udev->devpath, devpath, sizeof(udev->devpath)); - remove_trailing_chars(udev->devpath, '/'); - - if (strncmp(udev->devpath, "/block/", 7) == 0) - udev->type = DEV_BLOCK; - else if (strncmp(udev->devpath, "/class/net/", 11) == 0) - udev->type = DEV_NET; - else if (strncmp(udev->devpath, "/class/", 7) == 0) - udev->type = DEV_CLASS; - else if (strncmp(udev->devpath, "/devices/", 9) == 0) - udev->type = DEV_DEVICE; - - /* get kernel name */ - pos = strrchr(udev->devpath, '/'); - if (pos) { - strlcpy(udev->kernel_name, &pos[1], sizeof(udev->kernel_name)); - dbg("kernel_name='%s'", udev->kernel_name); - - /* Some block devices have '!' in their name, change that to '/' */ - pos = udev->kernel_name; - while (pos[0] != '\0') { - if (pos[0] == '!') - pos[0] = '/'; - pos++; - } - - /* get kernel number */ - pos = &udev->kernel_name[strlen(udev->kernel_name)]; - while (isdigit(pos[-1])) - pos--; - strlcpy(udev->kernel_number, pos, sizeof(udev->kernel_number)); - dbg("kernel_number='%s'", udev->kernel_number); - } - } - - if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) { - udev->mode = 0660; - strcpy(udev->owner, "root"); - strcpy(udev->group, "root"); - } - - return 0; + return udev; } -void udev_cleanup_device(struct udevice *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 major, minor; + + /* read it from sysfs */ + attr = sysfs_attr_get_value(udev->dev->devpath, "dev"); + if (attr != NULL) { + if (sscanf(attr, "%u:%u", &major, &minor) == 2) + return makedev(major, minor); + } + return makedev(0, 0); +} + +int udev_device_event(struct udev_rules *rules, struct udevice *udev) +{ + int retval = 0; + + /* device node or netif */ + if ((major(udev->devt) != 0 || strcmp(udev->dev->subsystem, "net") == 0) && + strcmp(udev->action, "add") == 0) { + dbg("device node or netif add '%s'", udev->dev->devpath); + udev_rules_get_name(rules, udev); + if (udev->ignore_device) { + info("device event will be ignored"); + return 0; + } + /* create node, store in db */ + if (udev->name[0] != '\0') + retval = udev_add_device(udev); + else + info("device node creation supressed"); + return 0; + } + + if (major(udev->devt) != 0 && strcmp(udev->action, "remove") == 0) { + struct name_entry *name_loop; + + udev_rules_get_run(rules, udev); + if (udev->ignore_device) { + info("device event will be ignored"); + return 0; + } + /* get data from db, remove db-entry, delete node */ + retval = udev_remove_device(udev); + + /* restore stored persistent data */ + list_for_each_entry(name_loop, &udev->env_list, node) + putenv(name_loop->name); + return 0; + } + + /* default devices */ + udev_rules_get_run(rules, udev); + if (udev->ignore_device) + info("device event will be ignored"); + + return retval; } diff --git a/udev_event.c b/udev_event.c deleted file mode 100644 index 887537e0e9..0000000000 --- a/udev_event.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * udev_event.c - udev event process - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_libc_wrapper.h" -#include "udev.h" -#include "logging.h" -#include "udev_rules.h" -#include "udev_utils.h" -#include "list.h" - - -dev_t get_devt(struct sysfs_class_device *class_dev) -{ - struct sysfs_attribute *attr = NULL; - unsigned int major, minor; - char *maj, *min; - - maj = getenv("MAJOR"); - min = getenv("MINOR"); - - if (maj && min) { - major = atoi(maj); - minor = atoi(min); - } else { - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr == NULL) - return 0; - dbg("dev='%s'", attr->value); - - if (sscanf(attr->value, "%u:%u", &major, &minor) != 2) - return 0; - } - - dbg("found major=%d, minor=%d", major, minor); - return makedev(major, minor); -} - -int udev_process_event(struct udev_rules *rules, struct udevice *udev) -{ - int retval; - char path[PATH_SIZE]; - - if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS || udev->type == DEV_NET) { - /* handle device node */ - if (strcmp(udev->action, "add") == 0) { - struct sysfs_class_device *class_dev; - - dbg("node add"); - snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); - path[sizeof(path)-1] = '\0'; - class_dev = sysfs_open_class_device_path(path); - if (class_dev == NULL) { - dbg("open class device failed"); - return 0; - } - dbg("opened class_dev->name='%s'", class_dev->name); - - /* get major/minor */ - if (udev->type == DEV_BLOCK || udev->type == DEV_CLASS) - udev->devt = get_devt(class_dev); - - if (udev->type == DEV_NET || udev->devt) { - /* name device */ - udev_rules_get_name(rules, udev, class_dev); - if (udev->ignore_device) { - info("device event will be ignored"); - sysfs_close_class_device(class_dev); - return 0; - } - if (udev->name[0] != '\0') { - /* create node, store in db */ - retval = udev_add_device(udev, class_dev); - } else { - info("device node creation supressed"); - } - } else { - dbg("no dev-file found"); - udev_rules_get_run(rules, udev, class_dev, NULL); - if (udev->ignore_device) { - info("device event will be ignored"); - sysfs_close_class_device(class_dev); - return 0; - } - } - sysfs_close_class_device(class_dev); - } else if (strcmp(udev->action, "remove") == 0) { - struct name_entry *name_loop; - - /* get data from db, remove db-entry, delete node */ - dbg("node remove"); - retval = udev_remove_device(udev); - - /* restore stored persistent data */ - list_for_each_entry(name_loop, &udev->env_list, node) - putenv(name_loop->name); - - udev_rules_get_run(rules, udev, NULL, NULL); - if (udev->ignore_device) { - dbg("device event will be ignored"); - return 0; - } - } - } else if (udev->type == DEV_DEVICE && strcmp(udev->action, "add") == 0) { - struct sysfs_device *devices_dev; - - dbg("devices add"); - snprintf(path, sizeof(path), "%s%s", sysfs_path, udev->devpath); - path[sizeof(path)-1] = '\0'; - devices_dev = sysfs_open_device_path(path); - if (!devices_dev) { - dbg("devices device unavailable (probably remove has beaten us)"); - return 0; - } - - dbg("devices device opened '%s'", path); - udev_rules_get_run(rules, udev, NULL, devices_dev); - sysfs_close_device(devices_dev); - if (udev->ignore_device) { - info("device event will be ignored"); - return 0; - } - } else { - dbg("default handling"); - udev_rules_get_run(rules, udev, NULL, NULL); - if (udev->ignore_device) { - info("device event will be ignored"); - return 0; - } - } - return 0; -} diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index fe38993cd7..02a1f8d016 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -27,10 +27,7 @@ #include #include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "logging.h" #ifdef __KLIBC__ #define __OWN_USERDB_PARSER__ diff --git a/udev_remove.c b/udev_remove.c index f9592b4c70..945618ce5a 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -28,11 +28,7 @@ #include #include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "udev_version.h" -#include "logging.h" static int delete_node(struct udevice *udev) { @@ -112,10 +108,10 @@ static int delete_node(struct udevice *udev) */ int udev_remove_device(struct udevice *udev) { - if (udev->type != DEV_BLOCK && udev->type != DEV_CLASS) + if (major(udev->devt) == 0) return 0; - if (udev_db_get_device(udev, udev->devpath) == 0) { + if (udev_db_get_device(udev, udev->dev->devpath) == 0) { if (udev->ignore_remove) { dbg("remove event for '%s' requested to be ignored by rule", udev->name); return 0; @@ -123,8 +119,8 @@ int udev_remove_device(struct udevice *udev) dbg("remove name='%s'", udev->name); udev_db_delete_device(udev); } else { - dbg("'%s' not found in database, using kernel name '%s'", udev->devpath, udev->kernel_name); - strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); + dbg("'%s' not found in database, using kernel name '%s'", udev->dev->devpath, udev->dev->kernel_name); + strlcpy(udev->name, udev->dev->kernel_name, sizeof(udev->name)); } return delete_node(udev); diff --git a/udev_rules.c b/udev_rules.c index 492a9b0dfc..8693b71c08 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -31,13 +31,7 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "list.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "udev_version.h" -#include "logging.h" #include "udev_rules.h" @@ -221,26 +215,29 @@ static int import_program_into_env(struct udevice *udev, const char *program) char result[1024]; size_t reslen; - if (run_program(program, udev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_INFO)) != 0) + if (run_program(program, udev->dev->subsystem, result, sizeof(result), &reslen, (udev_log_priority >= LOG_INFO)) != 0) return -1; return import_keys_into_env(udev, result, reslen); } -static int import_parent_into_env(struct udevice *udev, struct sysfs_class_device *class_dev, const char *filter) +static int import_parent_into_env(struct udevice *udev, const char *filter) { - struct sysfs_class_device *parent = sysfs_get_classdev_parent(class_dev); + struct sysfs_device *dev_parent; int rc = -1; - if (parent != NULL) { - struct udevice udev_parent; + 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", parent->path); - udev_init_device(&udev_parent, NULL, NULL, NULL); + dbg("found parent '%s', get the node name", dev_parent->devpath); + udev_parent = udev_device_init(); + if (udev_parent == NULL) + return -1; /* import the udev_db of the parent */ - if (udev_db_get_device(&udev_parent, &parent->path[strlen(sysfs_path)]) == 0) { - dbg("import stored parent env '%s'", udev_parent.name); - list_for_each_entry(name_loop, &udev_parent.env_list, node) { + 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; @@ -260,7 +257,7 @@ static int import_parent_into_env(struct udevice *udev, struct sysfs_class_devic rc = 0; } else dbg("parent not found in database"); - udev_cleanup_device(&udev_parent); + udev_device_cleanup(udev_parent); } return rc; @@ -291,22 +288,24 @@ static int find_free_number(const char *base, const char *devpath) { char db_devpath[PATH_SIZE]; char filename[PATH_SIZE]; - struct udevice udev_db; + struct udevice *udev_db; int num = 0; /* check if the device already owns a matching name */ - udev_init_device(&udev_db, NULL, NULL, NULL); - if (udev_db_get_device(&udev_db, devpath) == 0) { + udev_db = udev_device_init(); + if (udev_db == NULL) + return -1; + if (udev_db_get_device(udev_db, devpath) == 0) { struct name_entry *name_loop; int devnum; - devnum = match_name_and_get_number(base, udev_db.name); + devnum = match_name_and_get_number(base, udev_db->name); if (devnum >= 0) { num = devnum; dbg("device '%s', already has the node '%s' with num %u, use it", devpath, base, num); goto out; } - list_for_each_entry(name_loop, &udev_db.symlink_list, node) { + list_for_each_entry(name_loop, &udev_db->symlink_list, node) { devnum = match_name_and_get_number(base, name_loop->name); if (devnum >= 0) { num = devnum; @@ -336,45 +335,10 @@ static int find_free_number(const char *base, const char *devpath) } out: - udev_cleanup_device(&udev_db); + udev_device_cleanup(udev_db); return num; } -static int find_sysfs_attribute(struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device, - const char *name, char *value, size_t len) -{ - struct sysfs_class_device *class_dev_parent; - struct sysfs_attribute *tmpattr; - - dbg("look for device attribute '%s'", name); - if (class_dev) { - dbg("look for class attribute '%s/%s'", class_dev->path, name); - tmpattr = sysfs_get_classdev_attr(class_dev, name); - if (tmpattr) - goto attr_found; - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent) { - tmpattr = sysfs_get_classdev_attr(class_dev_parent, name); - if (tmpattr) - goto attr_found; - } - } - if (sysfs_device) { - dbg("look for devices attribute '%s/%s'", sysfs_device->path, name); - tmpattr = sysfs_get_device_attr(sysfs_device, name); - if (tmpattr) - goto attr_found; - } - return -1; - -attr_found: - strlcpy(value, tmpattr->value, len); - remove_trailing_chars(value, '\n'); - - dbg("found attribute '%s'", tmpattr->path); - return 0; -} - #define WAIT_LOOP_PER_SECOND 50 static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) { @@ -382,7 +346,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) struct stat stats; int loop = timeout * WAIT_LOOP_PER_SECOND; - snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->devpath, file); + snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->dev->devpath, file); filename[sizeof(filename)-1] = '\0'; dbg("wait %i sec for '%s'", timeout, filename); @@ -398,8 +362,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) return -1; } -static void apply_format(struct udevice *udev, char *string, size_t maxsize, - struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) +static void apply_format(struct udevice *udev, char *string, size_t maxsize) { char temp[PATH_SIZE]; char temp2[PATH_SIZE]; @@ -408,11 +371,9 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, int i; int count; unsigned int next_free_number; - struct sysfs_class_device *class_dev_parent; enum subst_type { SUBST_UNKNOWN, SUBST_DEVPATH, - SUBST_ID, SUBST_KERNEL_NUMBER, SUBST_KERNEL_NAME, SUBST_MAJOR, @@ -432,7 +393,6 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, enum subst_type type; } map[] = { { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH }, - { .name = "id", .fmt = 'b', .type = SUBST_ID }, { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER }, { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL_NAME }, { .name = "major", .fmt = 'M', .type = SUBST_MAJOR }, @@ -502,25 +462,20 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, found: attr = get_format_attribute(&tail); strlcpy(temp, tail, sizeof(temp)); - dbg("format=%i, string='%s', tail='%s', class_dev=%p, sysfs_dev=%p", - type ,string, tail, class_dev, sysfs_device); + dbg("format=%i, string='%s', tail='%s'", type ,string, tail); switch (type) { case SUBST_DEVPATH: - strlcat(string, udev->devpath, maxsize); - dbg("substitute devpath '%s'", udev->devpath); - break; - case SUBST_ID: - strlcat(string, udev->bus_id, maxsize); - dbg("substitute bus_id '%s'", udev->bus_id); + strlcat(string, udev->dev->devpath, maxsize); + dbg("substitute devpath '%s'", udev->dev->devpath); break; case SUBST_KERNEL_NAME: - strlcat(string, udev->kernel_name, maxsize); - dbg("substitute kernel name '%s'", udev->kernel_name); + strlcat(string, udev->dev->kernel_name, maxsize); + dbg("substitute kernel name '%s'", udev->dev->kernel_name); break; case SUBST_KERNEL_NUMBER: - strlcat(string, udev->kernel_number, maxsize); - dbg("substitute kernel number '%s'", udev->kernel_number); + strlcat(string, udev->dev->kernel_number, maxsize); + dbg("substitute kernel number '%s'", udev->dev->kernel_number); break; case SUBST_MAJOR: sprintf(temp2, "%d", major(udev->devt)); @@ -570,54 +525,59 @@ found: if (attr == NULL) { dbg("missing attribute"); break; - } - if (find_sysfs_attribute(class_dev, sysfs_device, attr, temp2, sizeof(temp2)) != 0) { - struct sysfs_device *parent_device; + } else { + struct sysfs_device *dev_parent; + const char *value; - dbg("sysfs attribute '%s' not found, walk up the physical devices", attr); - parent_device = sysfs_get_device_parent(sysfs_device); - while (parent_device) { - dbg("looking at '%s'", parent_device->path); - if (find_sysfs_attribute(NULL, parent_device, attr, temp2, sizeof(temp2)) == 0) + 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; - parent_device = sysfs_get_device_parent(parent_device); - } - if (!parent_device) - break; + } + dev_parent = sysfs_device_get_parent(dev_parent); + } while (dev_parent != NULL); + + /* strip trailing whitespace of sysfs value */ + i = strlen(temp2); + while (i > 0 && isspace(temp2[i-1])) + temp2[--i] = '\0'; + count = replace_untrusted_chars(temp2); + if (count) + info("%i untrusted character(s) replaced" , count); + strlcat(string, temp2, maxsize); + dbg("substitute sysfs value '%s'", temp2); } - /* strip trailing whitespace of sysfs value */ - i = strlen(temp2); - while (i > 0 && isspace(temp2[i-1])) - temp2[--i] = '\0'; - count = replace_untrusted_chars(temp2); - if (count) - info("%i untrusted character(s) replaced" , count); - strlcat(string, temp2, maxsize); - dbg("substitute sysfs value '%s'", temp2); break; case SUBST_ENUM: - next_free_number = find_free_number(string, udev->devpath); + next_free_number = find_free_number(string, udev->dev->devpath); if (next_free_number > 0) { sprintf(temp2, "%d", next_free_number); strlcat(string, temp2, maxsize); } break; case SUBST_PARENT: - if (!class_dev) - break; - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) { - struct udevice udev_parent; + { + struct sysfs_device *dev_parent; - dbg("found parent '%s', get the node name", class_dev_parent->path); - udev_init_device(&udev_parent, NULL, NULL, NULL); - /* lookup the name in the udev_db with the DEVPATH of the parent */ - if (udev_db_get_device(&udev_parent, &class_dev_parent->path[strlen(sysfs_path)]) == 0) { - strlcat(string, udev_parent.name, maxsize); - dbg("substitute parent node name'%s'", udev_parent.name); - } else - dbg("parent not found in database"); - udev_cleanup_device(&udev_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(); + 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: @@ -636,10 +596,15 @@ found: dbg("substitute udev_root '%s'", udev_root); break; case SUBST_MODALIAS: - if (find_sysfs_attribute(NULL, sysfs_device, "modalias", temp2, sizeof(temp2)) != 0) - break; - strlcat(string, temp2, maxsize); - dbg("substitute MODALIAS '%s'", temp2); + { + const char *value; + + value = sysfs_attr_get_value(udev->dev->devpath, "modalias"); + if (value != NULL) { + strlcat(string, value, maxsize); + dbg("substitute MODALIAS '%s'", temp2); + } + } break; case SUBST_ENV: if (attr == NULL) { @@ -714,28 +679,28 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k } /* match a single rule against a given device and possibly its parent devices */ -static int match_rule(struct udevice *udev, struct udev_rule *rule, - struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device) +static int match_rule(struct udevice *udev, struct udev_rule *rule) { - struct sysfs_device *parent_device = sysfs_device; + struct sysfs_device *dev_parent; int i; if (match_key("ACTION", rule, &rule->action, udev->action)) goto exit; - if (match_key("KERNEL", rule, &rule->kernel_name, udev->kernel_name)) + if (match_key("KERNEL", rule, &rule->kernel_name, udev->dev->kernel_name)) goto exit; - if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->subsystem)) + if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->dev->subsystem)) goto exit; - if (match_key("DEVPATH", rule, &rule->devpath, udev->devpath)) + if (match_key("DEVPATH", rule, &rule->devpath, udev->dev->devpath)) goto exit; if (rule->modalias.operation != KEY_OP_UNSET) { - char value[NAME_SIZE]; + const char *value; - if (find_sysfs_attribute(NULL, sysfs_device, "modalias", value, sizeof(value)) != 0) { + value = sysfs_attr_get_value(udev->dev->devpath, "modalias"); + if (value == NULL) { dbg("MODALIAS value not found"); goto exit; } @@ -777,34 +742,23 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, } /* walk up the chain of physical devices and find a match */ + dev_parent = udev->dev; while (1) { /* check for matching driver */ if (rule->driver.operation != KEY_OP_UNSET) { - if (parent_device == NULL) { - dbg("device has no sysfs_device"); - goto exit; - } - if (match_key("DRIVER", rule, &rule->driver, parent_device->driver_name)) + if (match_key("DRIVER", rule, &rule->driver, dev_parent->driver)) goto try_parent; } /* check for matching bus value */ if (rule->bus.operation != KEY_OP_UNSET) { - if (parent_device == NULL) { - dbg("device has no sysfs_device"); - goto exit; - } - if (match_key("BUS", rule, &rule->bus, parent_device->bus)) + if (match_key("BUS", rule, &rule->bus, dev_parent->subsystem)) goto try_parent; } /* check for matching bus id */ if (rule->id.operation != KEY_OP_UNSET) { - if (parent_device == NULL) { - dbg("device has no sysfs_device"); - goto exit; - } - if (match_key("ID", rule, &rule->id, parent_device->bus_id)) + if (match_key("ID", rule, &rule->id, dev_parent->kernel_name)) goto try_parent; } @@ -815,36 +769,39 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule, struct key_pair *pair = &rule->sysfs.keys[i]; const char *key_name = key_pair_name(rule, pair); const char *key_value = key_val(rule, &pair->key); - char value[VALUE_SIZE]; + const char *value; + char val[VALUE_SIZE]; size_t len; - if (find_sysfs_attribute(class_dev, parent_device, key_name, value, sizeof(value)) != 0) + value = sysfs_attr_get_value(dev_parent->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 && !isspace(key_value[len-1])) { - len = strlen(value); - while (len > 0 && isspace(value[len-1])) - value[--len] = '\0'; - dbg("removed %zi trailing whitespace chars from '%s'", strlen(value)-len, 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("SYSFS", rule, &pair->key, value)) + if (match_key("SYSFS", rule, &pair->key, val)) goto try_parent; } dbg("all %i SYSFS keys matched", rule->sysfs.count); } - /* found matching physical device */ + /* found matching device */ break; try_parent: dbg("try parent sysfs device"); - parent_device = sysfs_get_device_parent(parent_device); - if (parent_device == NULL) + dev_parent = sysfs_device_get_parent(dev_parent); + if (dev_parent == NULL) goto exit; - dbg("look at sysfs_device->path='%s'", parent_device->path); - dbg("look at sysfs_device->bus_id='%s'", parent_device->bus_id); + dbg("looking at dev_parent->devpath='%s'", dev_parent->devpath); + dbg("looking at dev_parent->bus_kernel_name='%s'", dev_parent->kernel_name); } /* execute external program */ @@ -853,8 +810,8 @@ try_parent: char result[PATH_SIZE]; strlcpy(program, key_val(rule, &rule->program), sizeof(program)); - apply_format(udev, program, sizeof(program), class_dev, sysfs_device); - if (run_program(program, udev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) { + apply_format(udev, program, sizeof(program)); + if (run_program(program, udev->dev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) { dbg("PROGRAM is false"); udev->program_result[0] = '\0'; if (rule->program.operation != KEY_OP_NOMATCH) @@ -886,18 +843,18 @@ try_parent: int rc = -1; strlcpy(import, key_val(rule, &rule->import), sizeof(import)); - apply_format(udev, import, sizeof(import), class_dev, sysfs_device); + 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 && class_dev) { + } else if (rule->import_type == IMPORT_PARENT) { dbg("import parent import='%s'", import); - rc = import_parent_into_env(udev, class_dev, import); + rc = import_parent_into_env(udev, import); } - if (rc) { + if (rc != 0) { dbg("IMPORT failed"); if (rule->import.operation != KEY_OP_NOMATCH) goto exit; @@ -926,35 +883,13 @@ exit: return -1; } -int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct sysfs_class_device *class_dev) +int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) { - struct sysfs_class_device *class_dev_parent; - struct sysfs_device *sysfs_device = NULL; struct udev_rule *rule; int name_set = 0; - dbg("class_dev->name='%s'", class_dev->name); - - /* Figure out where the "device"-symlink is at. For char devices this will - * always be in the class_dev->path. On block devices, only the main block - * device will have the device symlink in it's path. All partition devices - * need to look at the symlink in its parent directory. - */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) { - dbg("given class device has a parent, use this instead"); - sysfs_device = sysfs_get_classdev_device(class_dev_parent); - } else { - sysfs_device = sysfs_get_classdev_device(class_dev); - } - - if (sysfs_device) { - dbg("found devices device: path='%s', bus_id='%s', bus='%s'", - sysfs_device->path, sysfs_device->bus_id, sysfs_device->bus); - strlcpy(udev->bus_id, sysfs_device->bus_id, sizeof(udev->bus_id)); - } - - dbg("udev->kernel_name='%s'", udev->kernel_name); + dbg("udev->dev->devpath='%s'", udev->dev->devpath); + dbg("udev->dev->kernel_name='%s'", udev->dev->kernel_name); /* look for a matching rule to apply */ udev_rules_iter_init(rules); @@ -969,10 +904,10 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s } dbg("process rule"); - if (match_rule(udev, rule, class_dev, sysfs_device) == 0) { + if (match_rule(udev, rule) == 0) { /* apply options */ if (rule->ignore_device) { - info("rule applied, '%s' is ignored", udev->kernel_name); + info("rule applied, '%s' is ignored", udev->dev->kernel_name); udev->ignore_device = 1; return 0; } @@ -981,7 +916,8 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s dbg("remove event should be ignored"); } /* apply all_partitions option only at a main block device */ - if (rule->partitions && udev->type == DEV_BLOCK && udev->kernel_number[0] == '\0') { + 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"); } @@ -991,21 +927,21 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s 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->kernel_name); + dbg("applied mode=%#o to '%s'", rule->mode, udev->dev->kernel_name); } 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)); - apply_format(udev, udev->owner, sizeof(udev->owner), class_dev, sysfs_device); - dbg("applied owner='%s' to '%s'", udev->owner, udev->kernel_name); + apply_format(udev, udev->owner, sizeof(udev->owner)); + dbg("applied owner='%s' to '%s'", udev->owner, udev->dev->kernel_name); } 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)); - apply_format(udev, udev->group, sizeof(udev->group), class_dev, sysfs_device); - dbg("applied group='%s' to '%s'", udev->group, udev->kernel_name); + apply_format(udev, udev->group, sizeof(udev->group)); + dbg("applied group='%s' to '%s'", udev->group, udev->dev->kernel_name); } /* collect symlinks */ @@ -1021,7 +957,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s name_list_cleanup(&udev->symlink_list); } strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); - apply_format(udev, temp, sizeof(temp), class_dev, sysfs_device); + apply_format(udev, temp, sizeof(temp)); count = replace_untrusted_chars(temp); if (count) info("%i untrusted character(s) replaced" , count); @@ -1052,13 +988,13 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s int count; name_set = 1; strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name)); - apply_format(udev, udev->name, sizeof(udev->name), class_dev, sysfs_device); + apply_format(udev, udev->name, sizeof(udev->name)); count = replace_untrusted_chars(udev->name); if (count) info("%i untrusted character(s) replaced", count); - info("rule applied, '%s' becomes '%s'", udev->kernel_name, udev->name); - if (udev->type != DEV_NET) + info("rule applied, '%s' becomes '%s'", udev->dev->kernel_name, 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); } @@ -1073,7 +1009,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s name_list_cleanup(&udev->run_list); } strlcpy(program, key_val(rule, &rule->run), sizeof(program)); - apply_format(udev, program, sizeof(program), class_dev, sysfs_device); + apply_format(udev, program, sizeof(program)); dbg("add run '%s'", program); name_list_add(&udev->run_list, program, 0); } @@ -1091,7 +1027,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s } if (!name_set) { - strlcpy(udev->name, udev->kernel_name, sizeof(udev->name)); + strlcpy(udev->name, udev->dev->kernel_name, sizeof(udev->name)); info("no node name set, will use kernel name '%s'", udev->name); } @@ -1104,20 +1040,11 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev, struct s return 0; } -int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, - struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev) +int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev) { struct udev_rule *rule; - if (class_dev && !sysfs_dev) - sysfs_dev = sysfs_get_classdev_device(class_dev); - if (sysfs_dev) { - dbg("found devices device: path='%s', bus_id='%s', bus='%s'", - sysfs_dev->path, sysfs_dev->bus_id, sysfs_dev->bus); - strlcpy(udev->bus_id, sysfs_dev->bus_id, sizeof(udev->bus_id)); - } - - dbg("udev->kernel_name='%s'", udev->kernel_name); + dbg("udev->kernel_name='%s'", udev->dev->kernel_name); /* look for a matching rule to apply */ udev_rules_iter_init(rules); @@ -1133,9 +1060,9 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, continue; } - if (match_rule(udev, rule, class_dev, sysfs_dev) == 0) { + if (match_rule(udev, rule) == 0) { if (rule->ignore_device) { - info("rule applied, '%s' is ignored", udev->kernel_name); + info("rule applied, '%s' is ignored", udev->dev->kernel_name); udev->ignore_device = 1; return 0; } @@ -1148,7 +1075,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, name_list_cleanup(&udev->run_list); } strlcpy(program, key_val(rule, &rule->run), sizeof(program)); - apply_format(udev, program, sizeof(program), class_dev, sysfs_dev); + apply_format(udev, program, sizeof(program)); dbg("add run '%s'", program); name_list_add(&udev->run_list, program, 0); if (rule->run.operation == KEY_OP_ASSIGN_FINAL) diff --git a/udev_rules.h b/udev_rules.h index 6d9d306ded..125babf1c5 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -22,7 +22,6 @@ #ifndef UDEV_RULES_H #define UDEV_RULES_H -#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" #include "list.h" @@ -104,18 +103,15 @@ struct udev_rules { }; extern int udev_rules_init(struct udev_rules *rules, int resolve_names); -extern void udev_rules_close(struct udev_rules *rules); +extern void udev_rules_cleanup(struct udev_rules *rules); -extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize, - struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_device); +extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize); 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, - struct sysfs_class_device *class_dev); -extern int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev, - struct sysfs_class_device *class_dev, struct sysfs_device *sysfs_dev); +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); #endif diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 7fa21afa8c..4fcd6db08e 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -28,10 +28,7 @@ #include #include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "logging.h" #include "udev_rules.h" @@ -626,7 +623,7 @@ int udev_rules_init(struct udev_rules *rules, int resolve_names) return retval; } -void udev_rules_close(struct udev_rules *rules) +void udev_rules_cleanup(struct udev_rules *rules) { if (rules->buf) { free(rules->buf); diff --git a/udev_selinux.c b/udev_selinux.c index 298c75566c..94c213d297 100644 --- a/udev_selinux.c +++ b/udev_selinux.c @@ -32,7 +32,6 @@ #include "udev.h" #include "udev_selinux.h" -#include "logging.h" static security_context_t prev_scontext = NULL; diff --git a/udev_sysfs.c b/udev_sysfs.c new file mode 100644 index 0000000000..19fd614e63 --- /dev/null +++ b/udev_sysfs.c @@ -0,0 +1,345 @@ +/* + * udev_sysfs.c - sysfs access + * + * 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. + * + * 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. + * + */ + + +#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[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) +{ + char *pos; + + strlcpy(dev->devpath, devpath, sizeof(dev->devpath)); + if (subsystem != NULL) + strlcpy(dev->subsystem, subsystem, sizeof(dev->subsystem)); + + /* set kernel name */ + pos = strrchr(dev->devpath, '/'); + if (pos == NULL) + return; + + strlcpy(dev->kernel_name, &pos[1], sizeof(dev->kernel_name)); + dbg("kernel_name='%s'", dev->kernel_name); + + /* some devices have '!' in their name, change that to '/' */ + pos = dev->kernel_name; + while (pos[0] != '\0') { + if (pos[0] == '!') + pos[0] = '/'; + pos++; + } + + /* get kernel number */ + pos = &dev->kernel_name[strlen(dev->kernel_name)]; + while (isdigit(pos[-1])) + pos--; + strlcpy(dev->kernel_number, pos, sizeof(dev->kernel_number)); + dbg("kernel_number='%s'", dev->kernel_number); +} + +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; + + dbg("open '%s'", devpath); + strlcpy(devpath_real, devpath, sizeof(devpath_real)); + remove_trailing_chars(devpath_real, '/'); + + strlcpy(path, sysfs_path, sizeof(path)); + strlcat(path, devpath_real, sizeof(path)); + if (lstat(path, &statbuf) != 0) { + dbg("stat '%s' failed: %s", devpath, strerror(errno)); + return NULL; + } + + /* if we got a link, resolve it to the real device */ + if (S_ISLNK(statbuf.st_mode)) { + int i; + int back; + + len = readlink(path, link_target, sizeof(link_target)); + if (len <= 0) + return NULL; + link_target[len] = '\0'; + dbg("devpath link '%s' points to '%s'", path, link_target); + + for (back = 0; strncmp(&link_target[back * 3], "../", 3) == 0; back++) + ; + dbg("base '%s', tail '%s', back %i", devpath_real, &link_target[back * 3], back); + for (i = 0; i <= back; i++) { + pos = strrchr(devpath_real, '/'); + if (pos == NULL) + return NULL; + pos[0] = '\0'; + } + dbg("after moving back '%s'", devpath_real); + strlcat(devpath_real, "/", sizeof(devpath_real)); + strlcat(devpath_real, &link_target[back * 3], sizeof(devpath_real)); + } + + /* look for device in 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; + } + } + + /* new device */ + dbg("'%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); + + /* get subsystem */ + if (strncmp(dev->devpath, "/class/", 7) == 0) { + strlcpy(dev->subsystem, &dev->devpath[7], sizeof(dev->subsystem)); + pos = strchr(dev->subsystem, '/'); + if (pos != NULL) + pos[0] = '\0'; + else + dev->subsystem[0] = '\0'; + } else if (strncmp(devpath, "/block/", 7) == 0) { + strlcpy(dev->subsystem, "block", sizeof(dev->subsystem)); + } else if (strncmp(devpath, "/devices/", 9) == 0) { + /* get subsystem from bus name */ + 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)); + } + + /* 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)); + } + } else if (strncmp(devpath, "/bus/", 5) == 0 && strstr(devpath, "/drivers/")) { + strlcpy(dev->subsystem, "drivers", sizeof(dev->subsystem)); + } else if (strncmp(devpath, "/module/", 8) == 0) { + strlcpy(dev->subsystem, "module", sizeof(dev->subsystem)); + } + + 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 device_link[PATH_SIZE]; + char device_link_target[PATH_SIZE]; + char *pos; + int i; + int len; + int back; + + /* requesting a parent is only valid for devices */ + if ((strncmp(dev->devpath, "/devices/", 9) != 0) && + (strncmp(dev->devpath, "/class/", 7) != 0) && + (strncmp(dev->devpath, "/block/", 7) != 0)) + return NULL; + + 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'; + + /* are we at the top level */ + if (strcmp(parent_devpath, "/devices") == 0) { + dbg("/devices top level"); + return NULL; + } + + /* at the top level we may follow the "device" link */ + if (strcmp(parent_devpath, "/block") == 0) { + dbg("/block top level, look for device link"); + goto device_link; + } + + 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; + } + } + return sysfs_device_get(parent_devpath); + +device_link: + strlcpy(device_link, sysfs_path, sizeof(device_link)); + strlcat(device_link, dev->devpath, sizeof(device_link)); + strlcat(device_link, "/device", sizeof(device_link)); + len = readlink(device_link, device_link_target, sizeof(device_link_target)); + if (len < 0) + return NULL; + device_link_target[len] = '\0'; + dbg("device link '%s' points to '%s'", device_link, device_link_target); + + for (back = 0; strncmp(&device_link_target[back * 3], "../", 3) == 0; back++) + ; + strlcpy(parent_devpath, dev->devpath, sizeof(parent_devpath)); + dbg("base='%s', tail='%s', back=%i", parent_devpath, &device_link_target[back * 3], back); + for (i = 0; i < back; i++) { + pos = strrchr(parent_devpath, '/'); + if (pos == NULL) + return NULL; + pos[0] = '\0'; + } + dbg("after moving back '%s'", parent_devpath); + strlcat(parent_devpath, "/", sizeof(parent_devpath)); + strlcat(parent_devpath, &device_link_target[back * 3], sizeof(parent_devpath)); + return sysfs_device_get(parent_devpath); +} + +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; + int fd; + ssize_t size; + size_t sysfs_len; + + 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; + } + } + + /* read attribute value */ + fd = open(path_full, O_RDONLY); + if (fd < 0) + return NULL; + size = read(fd, value, sizeof(value)); + close(fd); + if (size < 0) + return NULL; + if (size == sizeof(value)) + return NULL; + value[size] = '\0'; + remove_trailing_chars(value, '\n'); + + /* store attribute in cache */ + attr = malloc(sizeof(struct sysfs_attr)); + if (attr == NULL) + return NULL; + strlcpy(attr->path, path, sizeof(attr->path)); + strlcpy(attr->value, value, sizeof(attr->value)); + dbg("add to cache '%s' '%s'", attr->path, attr->value); + list_add(&attr->node, &attr_list); + + return attr->value; +} diff --git a/udev_utils.c b/udev_utils.c index 581ba9e80a..a37c4dfe74 100644 --- a/udev_utils.c +++ b/udev_utils.c @@ -30,11 +30,7 @@ #include #include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "logging.h" -#include "udev_utils.h" -#include "list.h" int log_priority(const char *priority) diff --git a/udev_utils.h b/udev_utils.h deleted file mode 100644 index a28ba005ca..0000000000 --- a/udev_utils.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * udev_utils.c - generic stuff used by udev - * - * 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., - * 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifndef _UDEV_COMMON_H_ -#define _UDEV_COMMON_H_ - -#include "udev.h" -#include "list.h" - -#define UDEV_MAX(a,b) ((a) > (b) ? (a) : (b)) - -/* pipes */ -#define READ_END 0 -#define WRITE_END 1 - -struct name_entry { - struct list_head node; - char name[PATH_SIZE]; -}; - -/* udev_utils.c */ -extern int log_priority(const char *priority); -extern int name_list_add(struct list_head *name_list, const char *name, int sort); -extern int name_list_key_add(struct list_head *name_list, const char *key, const char *value); -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); - -/* udev_utils_string.c */ -extern int strcmp_pattern(const char *p, const char *s); -extern int string_is_true(const char *str); -extern void remove_trailing_chars(char *path, char c); -extern int utf8_encoded_valid_unichar(const char *str); -extern int replace_untrusted_chars(char *str); - -/* 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); - -/* udev_utils_run.c */ -extern int pass_env_to_socket(const char *name, const char *devpath, const char *action); -extern int run_program(const char *command, const char *subsystem, - char *result, size_t ressize, size_t *reslen, int log); - -#endif diff --git a/udev_utils_file.c b/udev_utils_file.c index cd9c244f0f..acaffdc918 100644 --- a/udev_utils_file.c +++ b/udev_utils_file.c @@ -30,11 +30,7 @@ #include #include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "logging.h" -#include "udev_utils.h" -#include "list.h" int create_path(const char *path) { diff --git a/udev_utils_run.c b/udev_utils_run.c index e1e775ebe6..b6020b0ab6 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -31,11 +31,7 @@ #include #include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "logging.h" -#include "udev_utils.h" -#include "list.h" int pass_env_to_socket(const char *sockname, const char *devpath, const char *action) diff --git a/udev_utils_string.c b/udev_utils_string.c index 37db8dbc85..36ef8bef7e 100644 --- a/udev_utils_string.c +++ b/udev_utils_string.c @@ -30,11 +30,7 @@ #include #include -#include "udev_libc_wrapper.h" #include "udev.h" -#include "logging.h" -#include "udev_utils.h" -#include "list.h" /* compare string with pattern (like fnmatch(), supports * ? [0-9] [!A-Z]) */ int strcmp_pattern(const char *p, const char *s) diff --git a/udevcontrol.c b/udevcontrol.c index bd6563531d..6d91adc1c4 100644 --- a/udevcontrol.c +++ b/udevcontrol.c @@ -32,10 +32,7 @@ #include #include "udev.h" -#include "udev_version.h" #include "udevd.h" -#include "udev_utils.h" -#include "logging.h" /* global variables */ static int sock = -1; diff --git a/udevd.c b/udevd.c index ff61c656c8..f64a4252bb 100644 --- a/udevd.c +++ b/udevd.c @@ -42,16 +42,11 @@ #include #include -#include "list.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_version.h" #include "udev_rules.h" -#include "udev_utils.h" #include "udevd.h" -#include "logging.h" -struct udev_rules rules; +static struct udev_rules rules; static int udevd_sock; static int uevent_netlink_sock; static int inotify_fd; @@ -94,8 +89,7 @@ static void asmlinkage udev_event_sig_handler(int signum) static int udev_event_process(struct uevent_msg *msg) { struct sigaction act; - struct udevice udev; - struct name_entry *name_loop; + struct udevice *udev; int i; int retval; @@ -109,27 +103,34 @@ static int udev_event_process(struct uevent_msg *msg) /* trigger timeout to prevent hanging processes */ alarm(UDEV_ALARM_TIMEOUT); - /* reconstruct env from message */ + /* reconstruct event environment from message */ for (i = 0; msg->envp[i]; i++) putenv(msg->envp[i]); - udev_init_device(&udev, msg->devpath, msg->subsystem, msg->action); - retval = udev_process_event(&rules, &udev); + udev = udev_device_init(); + if (udev == NULL) + return -1; + strlcpy(udev->action, msg->action, sizeof(udev->action)); + sysfs_device_set_values(udev->dev, msg->devpath, msg->subsystem); + udev->devt = msg->devt; + + retval = udev_device_event(&rules, udev); /* run programs collected by RUN-key*/ - if (!retval) { - list_for_each_entry(name_loop, &udev.run_list, node) { + if (retval == 0) { + struct name_entry *name_loop; + + 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:")], msg->devpath, msg->action); else - if (run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, + if (run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO))) retval = -1; } } - udev_cleanup_device(&udev); - + udev_device_cleanup(udev); return retval; } @@ -819,7 +820,7 @@ int main(int argc, char *argv[], char *envp[]) if (fd < 0) err("fatal, could not open /dev/null: %s", strerror(errno)); - udev_init_config(); + udev_config_init(); dbg("version %s", UDEV_VERSION); if (getuid() != 0) { @@ -859,6 +860,7 @@ int main(int argc, char *argv[], char *envp[]) } /* parse the rules and keep it in memory */ + sysfs_init(); udev_rules_init(&rules, 1); if (daemonize) { @@ -1020,7 +1022,7 @@ int main(int argc, char *argv[], char *envp[]) /* rules changed, set by inotify or a signal*/ if (reload_config) { reload_config = 0; - udev_rules_close(&rules); + udev_rules_cleanup(&rules); udev_rules_init(&rules, 1); } @@ -1038,7 +1040,8 @@ int main(int argc, char *argv[], char *envp[]) } exit: - udev_rules_close(&rules); + udev_rules_cleanup(&rules); + sysfs_cleanup(); if (signal_pipe[READ_END] > 0) close(signal_pipe[READ_END]); diff --git a/udevd.h b/udevd.h index afbc3a31b1..c0a32e97ed 100644 --- a/udevd.h +++ b/udevd.h @@ -32,7 +32,7 @@ #define EVENT_QUEUE_DIR ".udev/queue" #define EVENT_FAILED_DIR ".udev/failed" -/* maximum limit of runnig childs */ +/* maximum limit of forked childs */ #define UDEVD_MAX_CHILDS 64 /* start to throttle forking if maximum number of running childs in our session is reached */ #define UDEVD_MAX_CHILDS_RUNNING 16 diff --git a/udevinfo.c b/udevinfo.c index 8ff09da3d1..f8d0b6125a 100644 --- a/udevinfo.c +++ b/udevinfo.c @@ -21,17 +21,14 @@ #include #include #include +#include #include #include #include +#include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_utils.h" -#include "udev_version.h" -#include "logging.h" #ifdef USE_LOG @@ -48,42 +45,89 @@ void log_message (int priority, const char *format, ...) } #endif -static void print_all_attributes(struct dlist *attr_list) +static void print_all_attributes(const char *devpath) { - struct sysfs_attribute *attr; - char value[VALUE_SIZE]; - size_t len; + char path[PATH_SIZE]; + DIR *dir; + struct dirent *dent; - dlist_for_each_data(attr_list, attr, struct sysfs_attribute) { - if (attr->value == NULL) - continue; - len = strlcpy(value, attr->value, sizeof(value)); - if (len >= sizeof(value)) { - dbg("attribute value of '%s' too long, skip", attr->name); - continue; - } + strlcpy(path, sysfs_path, sizeof(path)); + strlcat(path, devpath, sizeof(path)); - /* 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", attr->name); - continue; + dir = opendir(path); + if (dir != NULL) { + for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) { + char *attr_value; + char value[NAME_SIZE]; + size_t len; + + 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_untrusted_chars(value); + printf(" SYSFS{%s}==\"%s\"\n", dent->d_name, value); } - replace_untrusted_chars(value); - printf(" SYSFS{%s}==\"%s\"\n", attr->name, value); } printf("\n"); } +static int print_device_chain(const char *devpath) +{ + struct sysfs_device *dev; + + printf("\n" + "udevinfo starts with the device the node belongs to and then walks up the\n" + "device chain, to print for every device found, all possibly useful attributes\n" + "in the udev key format.\n" + "Only attributes within one device section may be used together in one rule,\n" + "to match the device for which the node will be created.\n" + "\n"); + + dev = sysfs_device_get(devpath); + if (dev == NULL) + return -1; + + printf(" looking at device '%s':\n", dev->devpath); + printf(" KERNEL==\"%s\"\n", dev->kernel_name); + printf(" SUBSYSTEM==\"%s\"\n", dev->subsystem); + print_all_attributes(dev->devpath); + + /* walk up the chain of devices */ + while (1) { + dev = sysfs_device_get_parent(dev); + if (dev == NULL) + break; + printf(" looking at device '%s':\n", dev->devpath); + printf(" ID==\"%s\"\n", dev->kernel_name); + printf(" BUS==\"%s\"\n", dev->subsystem); + printf(" DRIVER==\"%s\"\n", dev->driver); + + print_all_attributes(dev->devpath); + } + + return 0; +} + static void print_record(struct udevice *udev) { struct name_entry *name_loop; - printf("P: %s\n", udev->devpath); + 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); @@ -91,82 +135,8 @@ static void print_record(struct udevice *udev) printf("E: %s\n", name_loop->name); } -static int print_device_chain(const char *path) -{ - struct sysfs_class_device *class_dev; - struct sysfs_class_device *class_dev_parent; - struct sysfs_attribute *attr; - struct sysfs_device *sysfs_dev; - struct dlist *attr_list; - int retval = 0; - - /* get the class dev */ - class_dev = sysfs_open_class_device_path(path); - if (class_dev == NULL) { - fprintf(stderr, "couldn't get the class device\n"); - return -1; - } - - printf("\nudevinfo starts with the device the node belongs to and then walks up the\n" - "device chain, to print for every device found, all possibly useful attributes\n" - "in the udev key format.\n" - "Only attributes within one device section may be used together in one rule,\n" - "to match the device for which the node will be created.\n" - "\n"); - - /* look for the 'dev' file */ - attr = sysfs_get_classdev_attr(class_dev, "dev"); - if (attr != NULL) - printf("device '%s' has major:minor %s", class_dev->path, attr->value); - - /* open sysfs class device directory and print all attributes */ - printf(" looking at class device '%s':\n", class_dev->path); - printf(" KERNEL==\"%s\"\n", class_dev->name); - printf(" SUBSYSTEM==\"%s\"\n", class_dev->classname); - - attr_list = sysfs_get_classdev_attributes(class_dev); - if (attr_list == NULL) { - fprintf(stderr, "couldn't open class device directory\n"); - retval = -1; - goto exit; - } - print_all_attributes(attr_list); - - /* get the device link (if parent exists look here) */ - class_dev_parent = sysfs_get_classdev_parent(class_dev); - if (class_dev_parent != NULL) - sysfs_dev = sysfs_get_classdev_device(class_dev_parent); - else - sysfs_dev = sysfs_get_classdev_device(class_dev); - - if (sysfs_dev != NULL) - printf("follow the \"device\"-link to the physical device:\n"); - - /* look the device chain upwards */ - while (sysfs_dev != NULL) { - printf(" looking at the device chain at '%s':\n", sysfs_dev->path); - printf(" BUS==\"%s\"\n", sysfs_dev->bus); - printf(" ID==\"%s\"\n", sysfs_dev->bus_id); - printf(" DRIVER==\"%s\"\n", sysfs_dev->driver_name); - - attr_list = sysfs_get_device_attributes(sysfs_dev); - if (attr_list != NULL) - print_all_attributes(attr_list); - else - printf("\n"); - - sysfs_dev = sysfs_get_device_parent(sysfs_dev); - if (sysfs_dev == NULL) - break; - } - -exit: - sysfs_close_class_device(class_dev); - return retval; -} - static void export_name_devpath(struct udevice *udev) { - printf("%s=%s/%s\n", udev->devpath, udev_root, udev->name); + printf("%s=%s/%s\n", udev->dev->devpath, udev_root, udev->name); } static void export_record(struct udevice *udev) { @@ -180,12 +150,14 @@ static void export_db(void fnct(struct udevice *udev)) { udev_db_get_all_entries(&name_list); list_for_each_entry(name_loop, &name_list, node) { - struct udevice udev_db; + struct udevice *udev_db; - udev_init_device(&udev_db, NULL, NULL, NULL); - if (udev_db_get_device(&udev_db, name_loop->name) == 0) - fnct(&udev_db); - udev_cleanup_device(&udev_db); + udev_db = udev_device_init(); + if (udev_db == NULL) + continue; + if (udev_db_get_device(udev_db, name_loop->name) == 0) + fnct(udev_db); + udev_device_cleanup(udev_db); } name_list_cleanup(&name_list); } @@ -215,7 +187,7 @@ int main(int argc, char *argv[], char *envp[]) { static const char short_options[] = "aden:p:q:rVh"; int option; - struct udevice udev; + struct udevice *udev; int root = 0; enum action_type { @@ -239,12 +211,18 @@ int main(int argc, char *argv[], char *envp[]) char temp[PATH_SIZE]; struct name_entry *name_loop; char *pos; - int retval = 0; + int rc = 0; logging_init("udevinfo"); - udev_init_config(); - udev_init_device(&udev, NULL, NULL, NULL); + udev_config_init(); + sysfs_init(); + + udev = udev_device_init(); + if (udev == NULL) { + rc = 1; + goto exit; + } /* get command line options */ while (1) { @@ -260,7 +238,11 @@ int main(int argc, char *argv[], char *envp[]) break; case 'p': dbg("udev path: %s\n", optarg); - strlcpy(path, optarg, sizeof(path)); + /* remove sysfs mountpoint if not given */ + if (strncmp(optarg, sysfs_path, strlen(sysfs_path)) == 0) + strlcpy(path, &optarg[strlen(sysfs_path)], sizeof(path)); + else + strlcpy(path, optarg, sizeof(path)); break; case 'q': dbg("udev query: %s\n", optarg); @@ -286,7 +268,7 @@ int main(int argc, char *argv[], char *envp[]) break; } fprintf(stderr, "unknown query type\n"); - retval = 2; + rc = 2; goto exit; case 'r': if (action == ACTION_NONE) @@ -331,10 +313,9 @@ int main(int argc, char *argv[], char *envp[]) pos = path; } } - retval = udev_db_get_device(&udev, pos); - if (retval != 0) { + if (udev_db_get_device(udev, pos) != 0) { fprintf(stderr, "no record for '%s' in database\n", pos); - retval = 3; + rc = 3; goto exit; } } else if (name[0] != '\0') { @@ -348,46 +329,45 @@ int main(int argc, char *argv[], char *envp[]) } else pos = name; - retval = udev_db_lookup_name(pos, devpath, sizeof(devpath)); - if (retval != 0) { + if (udev_db_lookup_name(pos, devpath, sizeof(devpath)) != 0) { fprintf(stderr, "no record for '%s' in database\n", pos); - retval = 3; + rc = 3; goto exit; } - udev_db_get_device(&udev, devpath); + udev_db_get_device(udev, devpath); } else { fprintf(stderr, "query needs device path(-p) or node name(-n) specified\n"); - retval = 4; + rc = 4; goto exit; } switch(query) { case QUERY_NAME: if (root) - printf("%s/%s\n", udev_root, udev.name); + printf("%s/%s\n", udev_root, udev->name); else - printf("%s\n", udev.name); + printf("%s\n", udev->name); break; case QUERY_SYMLINK: - if (list_empty(&udev.symlink_list)) + if (list_empty(&udev->symlink_list)) goto exit; if (root) - list_for_each_entry(name_loop, &udev.symlink_list, node) + 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) + 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.devpath); + printf("%s\n", udev->dev->devpath); goto exit; case QUERY_ENV: - list_for_each_entry(name_loop, &udev.env_list, node) + list_for_each_entry(name_loop, &udev->env_list, node) printf("%s\n", name_loop->name); break; case QUERY_ALL: - print_record(&udev); + print_record(udev); break; default: print_help(); @@ -397,29 +377,23 @@ int main(int argc, char *argv[], char *envp[]) case ACTION_ATTRIBUTE_WALK: if (path[0] == '\0') { fprintf(stderr, "attribute walk on device chain needs path(-p) specified\n"); - retval = 4; + rc = 4; goto exit; - } else { - if (strncmp(path, sysfs_path, strlen(sysfs_path)) != 0) { - /* prepend sysfs mountpoint if not given */ - snprintf(temp, sizeof(temp), "%s%s", sysfs_path, path); - temp[sizeof(temp)-1] = '\0'; - strlcpy(path, temp, sizeof(temp)); - } + } else print_device_chain(path); - } break; case ACTION_ROOT: printf("%s\n", udev_root); break; default: print_help(); - retval = 1; + rc = 1; break; } exit: - udev_cleanup_device(&udev); + udev_device_cleanup(udev); + sysfs_cleanup(); logging_close(); - return retval; + return rc; } diff --git a/udevmonitor.c b/udevmonitor.c index 7d3f0aa538..80c49753f5 100644 --- a/udevmonitor.c +++ b/udevmonitor.c @@ -34,8 +34,6 @@ #include "udev.h" #include "udevd.h" -#include "udev_utils.h" -#include "udev_libc_wrapper.h" static int uevent_netlink_sock; static int udev_monitor_sock; diff --git a/udevsend.c b/udevsend.c index b67df9720b..1b9860baca 100644 --- a/udevsend.c +++ b/udevsend.c @@ -33,9 +33,7 @@ #include #include "udev.h" -#include "udev_version.h" #include "udevd.h" -#include "logging.h" /* global variables */ static int sock = -1; @@ -67,7 +65,7 @@ int main(int argc, char *argv[], char *envp[]) logging_init("udevsend"); #ifdef USE_LOG - udev_init_config(); + udev_config_init(); #endif dbg("version %s", UDEV_VERSION); diff --git a/udevstart.c b/udevstart.c index a9959c5d6b..8c414f1acb 100644 --- a/udevstart.c +++ b/udevstart.c @@ -38,14 +38,8 @@ #include #include -#include "libsysfs/sysfs/libsysfs.h" -#include "udev_libc_wrapper.h" #include "udev.h" -#include "udev_version.h" -#include "logging.h" -#include "udev_utils.h" #include "udev_rules.h" -#include "list.h" static const char *udev_run_str; static const char *udev_log_str; @@ -68,11 +62,10 @@ void log_message(int priority, const char *format, ...) struct device { struct list_head node; char path[PATH_SIZE]; - char subsys[NAME_SIZE]; }; /* sort files in lexical order */ -static int device_list_insert(const char *path, char *subsystem, struct list_head *device_list) +static int device_list_insert(const char *path, struct list_head *device_list) { struct device *loop_device; struct device *new_device; @@ -93,9 +86,8 @@ static int device_list_insert(const char *path, char *subsystem, struct list_hea } strlcpy(new_device->path, devpath, sizeof(new_device->path)); - strlcpy(new_device->subsys, subsystem, sizeof(new_device->subsys)); list_add_tail(&new_device->node, &loop_device->node); - dbg("add '%s' from subsys '%s'", new_device->path, new_device->subsys); + dbg("add '%s'" , new_device->path); return 0; } @@ -112,64 +104,68 @@ static char *first_list[] = { NULL, }; -static int add_device(const char *devpath, const char *subsystem) +static int add_device(const char *devpath) { - struct udevice udev; - struct sysfs_class_device *class_dev; - char path[PATH_SIZE]; + struct sysfs_device *dev; + struct udevice *udev; /* clear and set environment for next event */ clearenv(); setenv("ACTION", "add", 1); - setenv("DEVPATH", devpath, 1); - setenv("SUBSYSTEM", subsystem, 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); - dbg("add '%s'", devpath); - snprintf(path, sizeof(path), "%s%s", sysfs_path, devpath); - path[sizeof(path)-1] = '\0'; - class_dev = sysfs_open_class_device_path(path); - if (class_dev == NULL) { - dbg("sysfs_open_class_device_path failed"); + dev = sysfs_device_get(devpath); + if (dev == NULL) return -1; + + udev = udev_device_init(); + if (udev == NULL) + return -1; + + /* override built-in sysfs device */ + udev->dev = dev; + strcpy(udev->action, "add"); + udev->devt = udev_device_get_devt(udev); + + if (strcmp(udev->dev->subsystem, "net") != 0) { + udev->devt = udev_device_get_devt(udev); + if (major(udev->devt) == 0) + return -1; } - udev_init_device(&udev, &class_dev->path[strlen(sysfs_path)], subsystem, "add"); - udev.devt = get_devt(class_dev); - if (!udev.devt && udev.type != DEV_NET) { - dbg("sysfs_open_class_device_path failed"); - return -1; - } - udev_rules_get_name(&rules, &udev, class_dev); - if (udev.ignore_device) { + 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') { + if (udev->name[0] == '\0') { dbg("device node creation supressed"); goto run; } - udev_add_device(&udev, class_dev); + udev_add_device(udev); run: - if (udev_run && !list_empty(&udev.run_list)) { + if (udev_run && !list_empty(&udev->run_list)) { struct name_entry *name_loop; dbg("executing run list"); - list_for_each_entry(name_loop, &udev.run_list, node) { + 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:")], devpath, "add"); + pass_env_to_socket(&name_loop->name[strlen("socket:")], udev->dev->devpath, "add"); else - run_program(name_loop->name, udev.subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); } } exit: - sysfs_close_class_device(class_dev); - udev_cleanup_device(&udev); + udev_device_cleanup(udev); return 0; } @@ -184,7 +180,7 @@ static void exec_list(struct list_head *device_list) 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, loop_device->subsys); + add_device(loop_device->path); list_del(&loop_device->node); free(loop_device); break; @@ -204,14 +200,14 @@ static void exec_list(struct list_head *device_list) if (found) continue; - add_device(loop_device->path, loop_device->subsys); + 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, loop_device->subsys); + add_device(loop_device->path); list_del(&loop_device->node); free(loop_device); } @@ -253,7 +249,7 @@ static void udev_scan_block(struct list_head *device_list) snprintf(dirname, sizeof(dirname), "%s/%s", base, dent->d_name); dirname[sizeof(dirname)-1] = '\0'; if (has_devt(dirname)) - device_list_insert(dirname, "block", device_list); + device_list_insert(dirname, device_list); else continue; @@ -270,7 +266,7 @@ static void udev_scan_block(struct list_head *device_list) dirname2[sizeof(dirname2)-1] = '\0'; if (has_devt(dirname2)) - device_list_insert(dirname2, "block", device_list); + device_list_insert(dirname2, device_list); } closedir(dir2); } @@ -313,7 +309,7 @@ static void udev_scan_class(struct list_head *device_list) dirname2[sizeof(dirname2)-1] = '\0'; if (has_devt(dirname2) || strcmp(dent->d_name, "net") == 0) - device_list_insert(dirname2, dent->d_name, device_list); + device_list_insert(dirname2, device_list); } closedir(dir2); } @@ -339,7 +335,7 @@ int main(int argc, char *argv[], char *envp[]) struct sigaction act; logging_init("udevstart"); - udev_init_config(); + udev_config_init(); dbg("version %s", UDEV_VERSION); udev_run_str = getenv("UDEV_RUN"); @@ -361,13 +357,15 @@ int main(int argc, char *argv[], char *envp[]) /* 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_close(&rules); + udev_rules_cleanup(&rules); + sysfs_cleanup(); logging_close(); return 0; } diff --git a/udevtest.8 b/udevtest.8 index e547811a8b..ea0ea59238 100644 --- a/udevtest.8 +++ b/udevtest.8 @@ -10,8 +10,8 @@ .SH "NAME" udevtest \- simulate a udev run and print the action to the console .SH "SYNOPSIS" -.HP 31 -\fBudevtest \fR\fB\fIdevice\-path\fR\fR\fB \fR\fB\fIsubsystem\fR\fR +.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 renamend. diff --git a/udevtest.c b/udevtest.c index 1be3fa9515..22fd3735c2 100644 --- a/udevtest.c +++ b/udevtest.c @@ -21,17 +21,15 @@ #include #include #include +#include +#include #include #include #include #include -#include "libsysfs/sysfs/libsysfs.h" #include "udev.h" -#include "udev_utils.h" -#include "udev_version.h" #include "udev_rules.h" -#include "logging.h" #ifdef USE_LOG @@ -53,28 +51,28 @@ void log_message (int priority, const char *format, ...) int main(int argc, char *argv[], char *envp[]) { struct udev_rules rules; - struct sysfs_class_device *class_dev; char *devpath; - char path[PATH_SIZE]; char temp[PATH_SIZE]; - struct udevice udev; - char *subsystem = NULL; + struct udevice *udev; + struct sysfs_device *dev; + int retval; + int rc = 0; info("version %s", UDEV_VERSION); /* initialize our configuration */ - udev_init_config(); + udev_config_init(); if (udev_log_priority < LOG_INFO) udev_log_priority = LOG_INFO; - if (argc != 3) { - info("Usage: udevtest "); + if (argc != 2) { + info("Usage: udevtest "); return 1; } /* remove sysfs_path if given */ if (strncmp(argv[1], sysfs_path, strlen(sysfs_path)) == 0) - devpath = &argv[1][strlen(sysfs_path)] ; + devpath = &argv[1][strlen(sysfs_path)]; else if (argv[1][0] != '/') { /* prepend '/' if missing */ @@ -84,39 +82,46 @@ int main(int argc, char *argv[], char *envp[]) } else devpath = argv[1]; - subsystem = argv[2]; - setenv("DEVPATH", devpath, 1); - setenv("SUBSYSTEM", subsystem, 1); - setenv("ACTION", "add", 1); - info("looking at device '%s' from subsystem '%s'", devpath, subsystem); - - /* initialize the naming deamon */ + sysfs_init(); udev_rules_init(&rules, 0); - /* fill in values and test_run flag*/ - udev_init_device(&udev, devpath, subsystem, "add"); - - /* open the device */ - snprintf(path, sizeof(path), "%s%s", sysfs_path, udev.devpath); - path[sizeof(path)-1] = '\0'; - class_dev = sysfs_open_class_device_path(path); - if (class_dev == NULL) { - info("sysfs_open_class_device_path failed"); - return 1; + dev = sysfs_device_get(devpath); + if (dev == NULL) { + info("unable to open '%s'", devpath); + rc = 2; + goto exit; } - info("opened class_dev->name='%s'", class_dev->name); - if (udev.type == DEV_BLOCK || udev.type == DEV_CLASS) - udev.devt = get_devt(class_dev); + udev = udev_device_init(); + if (udev == NULL) { + info("can't open device"); + rc = 3; + goto exit; + } + + /* override built-in sysfs device */ + udev->dev = dev; + strcpy(udev->action, "add"); + udev->devt = udev_device_get_devt(udev); /* simulate node creation with test flag */ - udev.test_run = 1; - if (udev.type == DEV_NET || udev.devt) { - udev_rules_get_name(&rules, &udev, class_dev); - udev_add_device(&udev, class_dev); - } else - info("only char and block devices with a dev-file are supported by this test program"); - sysfs_close_class_device(class_dev); + udev->test_run = 1; - return 0; + setenv("DEVPATH", udev->dev->devpath, 1); + setenv("SUBSYSTEM", udev->dev->subsystem, 1); + setenv("ACTION", "add", 1); + + info("looking at device '%s' from subsystem '%s'", udev->dev->devpath, udev->dev->subsystem); + retval = udev_device_event(&rules, udev); + if (retval == 0) { + struct name_entry *name_loop; + + list_for_each_entry(name_loop, &udev->run_list, node) + info("run: '%s'", name_loop->name); + } + +exit: + udev_rules_cleanup(&rules); + sysfs_cleanup(); + return rc; } From 8531b0b9649b504c660d6fecc78d1be919153f2d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 9 Jan 2006 21:30:04 +0100 Subject: [PATCH 1673/4284] 080 release --- ChangeLog | 22 ++++++++++++++++++++++ Makefile | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index cba96f91a6..25e23de593 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +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 ============================================ @@ -8,6 +29,7 @@ Kay Sievers: update SUSE rules remove %e from man page + Summary of changes from v077 to v078 ============================================ diff --git a/Makefile b/Makefile index 461f5ac012..5c44571aab 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 079 +VERSION = 080 # set this to make use of syslog USE_LOG = true From afe9f2fb5fe97281e2e84c12e1451a8e9bab6edb Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 10 Jan 2006 13:19:53 +0100 Subject: [PATCH 1674/4284] add DEVLINKS to "remove" event Signed-off-by: Kay Sievers --- udev_remove.c | 46 +++++++++++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 19 deletions(-) diff --git a/udev_remove.c b/udev_remove.c index 945618ce5a..6de6cf5962 100644 --- a/udev_remove.c +++ b/udev_remove.c @@ -33,7 +33,6 @@ static int delete_node(struct udevice *udev) { char filename[PATH_SIZE]; - char devname[PATH_SIZE]; char partitionname[PATH_SIZE]; struct name_entry *name_loop; struct stat stats; @@ -41,24 +40,35 @@ static int delete_node(struct udevice *udev) int i; int num; - list_for_each_entry(name_loop, &udev->symlink_list, node) { - snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); - filename[sizeof(filename)-1] = '\0'; + if (!list_empty(&udev->symlink_list)) { + char symlinks[512] = ""; - if (stat(filename, &stats) != 0) { - dbg("symlink '%s' not found", filename); - continue; - } - if (udev->devt && stats.st_rdev != udev->devt) { - info("symlink '%s' points to a different device, skip removal", filename); - continue;; + list_for_each_entry(name_loop, &udev->symlink_list, node) { + snprintf(filename, sizeof(filename), "%s/%s", udev_root, name_loop->name); + filename[sizeof(filename)-1] = '\0'; + + if (stat(filename, &stats) != 0) { + dbg("symlink '%s' not found", filename); + continue; + } + if (udev->devt && stats.st_rdev != udev->devt) { + info("symlink '%s' points to a different device, skip removal", filename); + continue; + } + + info("removing symlink '%s'", filename); + unlink(filename); + + if (strchr(filename, '/')) + delete_path(filename); + + strlcat(symlinks, filename, sizeof(symlinks)); + strlcat(symlinks, " ", sizeof(symlinks)); } - info("removing symlink '%s'", filename); - unlink(filename); - - if (strchr(filename, '/')) - delete_path(filename); + remove_trailing_chars(symlinks, ' '); + if (symlinks[0] != '\0') + setenv("DEVLINKS", symlinks, 1); } snprintf(filename, sizeof(filename), "%s/%s", udev_root, udev->name); @@ -78,9 +88,7 @@ static int delete_node(struct udevice *udev) if (retval) return retval; - snprintf(devname, sizeof(devname), "%s/%s", udev_root, udev->name); - devname[sizeof(devname)-1] = '\0'; - setenv("DEVNAME", devname, 1); + setenv("DEVNAME", filename, 1); num = udev->partitions; if (num > 0) { From d548032795b3c02aad606537a35ff63d954f1613 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 13 Jan 2006 13:17:10 +0100 Subject: [PATCH 1675/4284] better log test and comments Signed-off-by: Kay Sievers --- udev.h | 10 ++++++---- udev_config.c | 2 +- udev_rules.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/udev.h b/udev.h index c060b8d6ff..6dc0c9e354 100644 --- a/udev.h +++ b/udev.h @@ -55,7 +55,7 @@ struct udev_rules; struct sysfs_device { struct list_head node; /* for device cache */ char devpath[PATH_SIZE]; - char subsystem[NAME_SIZE]; /* $class/$bus/"drivers */ + char subsystem[NAME_SIZE]; /* $class/$bus/"drivers" */ char kernel_name[NAME_SIZE]; /* device instance name */ char kernel_number[NAME_SIZE]; char driver[NAME_SIZE]; /* device driver name */ @@ -63,7 +63,7 @@ struct sysfs_device { struct udevice { /* device event */ - struct sysfs_device *dev; + struct sysfs_device *dev; /* points to dev_local by default */ struct sysfs_device dev_local; char action[NAME_SIZE]; @@ -114,9 +114,11 @@ extern struct sysfs_device *sysfs_device_get(const char *devpath); extern struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev); extern char *sysfs_attr_get_value(const char *devpath, const char *attr_name); -/* udev_add.c / udev_remove.c */ -extern int udev_add_device(struct udevice *udev); +/* udev_add.c */ extern int udev_make_node(struct udevice *udev, const char *file, dev_t devt, mode_t mode, uid_t uid, gid_t gid); +extern int udev_add_device(struct udevice *udev); + +/* udev_remove.c */ extern int udev_remove_device(struct udevice *udev); /* udev_db.c */ diff --git a/udev_config.c b/udev_config.c index a7e19fe864..204827407d 100644 --- a/udev_config.c +++ b/udev_config.c @@ -136,7 +136,7 @@ static int parse_config_file(void) 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)); + err("error parsing %s, line %d:%d", udev_config_filename, lineno, (int)(linepos-line)); continue; } diff --git a/udev_rules.c b/udev_rules.c index 8693b71c08..fc1f3c9c3d 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -352,7 +352,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) while (--loop) { if (stat(filename, &stats) == 0) { - info("file appeared after %i loops", (timeout * WAIT_LOOP_PER_SECOND) - loop-1); + info("file '%s' appeared after %i loops", filename, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); return 0; } info("wait for %i mseconds", 1000 / WAIT_LOOP_PER_SECOND); From e3440f37f026b1e45d48f27ef1be903542b385f0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 13 Jan 2006 13:18:41 +0100 Subject: [PATCH 1676/4284] vol_id: probe volume as user nobody Signed-off-by: Kay Sievers --- extras/volume_id/libvolume_id/mac.c | 7 ++++--- extras/volume_id/libvolume_id/volume_id.h | 2 +- extras/volume_id/vol_id.c | 17 ++++++++++++++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/extras/volume_id/libvolume_id/mac.c b/extras/volume_id/libvolume_id/mac.c index 99bcbde6be..53f0761c8a 100644 --- a/extras/volume_id/libvolume_id/mac.c +++ b/extras/volume_id/libvolume_id/mac.c @@ -84,14 +84,15 @@ int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off) part_count = be32_to_cpu(part->map_count); dbg("expecting %d partition entries", part_count); + if (part_count < 1 || part_count > 256) + return -1; if (id->partitions != NULL) free(id->partitions); - id->partitions = - malloc(part_count * sizeof(struct volume_id_partition)); + id->partitions = malloc(part_count * sizeof(struct volume_id_partition)); if (id->partitions == NULL) return -1; - memset(id->partitions, 0x00, sizeof(struct volume_id_partition)); + memset(id->partitions, 0x00, part_count * sizeof(struct volume_id_partition)); id->partition_count = part_count; diff --git a/extras/volume_id/libvolume_id/volume_id.h b/extras/volume_id/libvolume_id/volume_id.h index ad65fe5438..edeb225faf 100644 --- a/extras/volume_id/libvolume_id/volume_id.h +++ b/extras/volume_id/libvolume_id/volume_id.h @@ -14,7 +14,7 @@ #include #include -#define VOLUME_ID_VERSION 55 +#define VOLUME_ID_VERSION 56 #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 diff --git a/extras/volume_id/vol_id.c b/extras/volume_id/vol_id.c index a291eda51d..6961969c13 100644 --- a/extras/volume_id/vol_id.c +++ b/extras/volume_id/vol_id.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include "../../udev.h" @@ -110,6 +111,8 @@ int main(int argc, char *argv[]) int i; uint64_t size; const char *node = NULL; + uid_t nobody_uid; + gid_t nobody_gid; int rc = 0; logging_init("vol_id"); @@ -146,12 +149,24 @@ int main(int argc, char *argv[]) size = 0; dbg("BLKGETSIZE64=%llu", size); + /* drop all privileges */ + nobody_uid = lookup_user("nobody"); + nobody_gid = lookup_group("nogroup"); + if (nobody_uid > 0 && nobody_gid > 0) { + if (setgroups(0, NULL) != 0 || + setgid(nobody_gid) != 0 || + setuid(nobody_uid) != 0) { + rc = 3; + goto exit; + } + } + if (volume_id_probe_all(vid, 0, size) == 0) goto print; if (print != PRINT_EXPORT) fprintf(stderr, "%s: unknown volume type\n", node); - rc = 3; + rc = 4; goto exit; print: From 03b24b71e05d116c592b08281f8a5f0dadf6d3c7 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 16 Jan 2006 06:12:49 +0100 Subject: [PATCH 1677/4284] fix BUS, ID, $id usage Signed-off-by: Kay Sievers --- TODO | 6 ---- docs/udev.xml | 81 +++++++++++++++++++++++++++-------------------- test/udev-test.pl | 71 ++++++++++++++++------------------------- udev.8 | 66 +++++++++++++++++++++----------------- udev.h | 37 +++++++++++----------- udev_rules.c | 60 ++++++++++++++++++++--------------- 6 files changed, 163 insertions(+), 158 deletions(-) diff --git a/TODO b/TODO index 19aae9edf0..bdd2e1e1f6 100644 --- a/TODO +++ b/TODO @@ -4,12 +4,6 @@ These things need to be done, or would be nice to have: to syslog, so any error logged from the kernel can be associated with any of the links at that time. - o Fix inconsistency with KERNEL and ID. ID will walk up the device chain - but it matches on "KERNEL names" too. And ID and SYSFS can only match - on the same device in the chain. That's pretty hard to explain and to - understand. Same for SUBSYSTEM and BUS. - - These things are deprecated and scheduled for removal in a future udev version: diff --git a/docs/udev.xml b/docs/udev.xml index 7f6a30df52..ab8174e6a9 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -148,66 +148,68 @@ - Match the kernel action name. + Match the name of the event action. - Match the kernel device name + Match the name of the device. - Match the kernel devpath. + Match the devpath of the device. - Match the kernel subsystem name + Match the subsystem of the device. - Match the type of bus the device is connected to. + Search the devpath upwards for a matching device subsystem name. - Match the kernel driver name. + Search the devpath upwards for a matching device driver name. - Match the device number on the bus. - - - - - - - Match against the value of an environment key. Depending on - the specified operation, this key is also used as an assignment. + Search the devpath upwards for a matching device name. - Match the sysfs attribute value. Up to five values can be specified. - Trailing whitespace is ignored, if the specified match value does not contain - trailing whitespace itself. + Search the devpath upwards for a device with matching sysfs attribute values. + Up to five keys can be specified per rule. All attributes + 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. This key can also be used to export a variable to + the environment. @@ -290,8 +292,8 @@ - Export the key to the environment. Depending on the specified - operation, this key is also used as a match. + Export a variable to the environment. This key can also be used to match + against an environment variable. @@ -320,7 +322,7 @@ - Import the printed result or the content of a file in environment key + Import the printed result or the value of a file in environment key format into the event environment. will execute an external program and read its output. will inport a text file. If no option is given, udev will determine it from the executable @@ -331,8 +333,8 @@ - Wait for the specified sysfs file of the device to be created. May be used - to fight agains timing issues wth the kernel. + Wait for the specified sysfs file of the device to be created. Can be used + to fight against kernel sysfs timing issues. @@ -355,14 +357,14 @@ printf-like string substitutions: - , + , The kernel name for this device. - , + , The kernel number for this device. For example, 'sda3' has kernel number of '3' @@ -370,42 +372,51 @@ - , + , The devpath of the device. - , + , - The content of a sysfs attribute. + The name of the device matched while searching the devpath upwards for + , and . + - , + , + + The value of a sysfs attribute found at the current or a parent device. + + + + + , 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 @@ -416,21 +427,21 @@ - , + , The node name of the parent device. - , + , The udev_root value. - , + , The name of a created temporary device node to provide access to the device from a external program before the real node is created. diff --git a/test/udev-test.pl b/test/udev-test.pl index 7ce920092f..555d36e7f2 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -231,7 +231,7 @@ KERNEL=="ttyUSB0", NAME="sub/direct/ory/visor" EOF }, { - desc => "place on bus of scsi partition", + desc => "parent device name match of scsi partition", subsys => "block", devpath => "/block/sda/sda3", exp_name => "first_disk3" , @@ -243,18 +243,18 @@ EOF desc => "test substitution chars", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "Major:8:minor:3:kernelnumber:3" , + 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-bsd-sIBM" , + exp_name => "M8-m3-n3-b0:0-sIBM" , rules => < "program result substitution", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "test-3" , + exp_name => "test-0:0:0:0" , rules => < "test substitution by variable name", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "Major:8-minor:3-kernelnumber:3" , + 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-name: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 => "83sda33" , + exp_name => "830:0:0:03" , rules => < "test substitution by variable name 5", subsys => "block", devpath => "/block/sda/sda3", - exp_name => "833sda3" , + exp_name => "8330:0:0:0" , rules => < "invalid program for device with no bus", + desc => "non matching BUS for device with no parent", subsys => "tty", devpath => "/class/tty/console", - exp_name => "TTY" , + exp_name => "TTY", rules => < "valid program for device with no bus", - subsys => "tty", - devpath => "/class/tty/console", - exp_name => "foo" , - rules => < "invalid label for device with no bus", + desc => "non matching BUS", subsys => "tty", devpath => "/class/tty/console", exp_name => "TTY" , @@ -457,7 +447,7 @@ KERNEL=="console", NAME="TTY" EOF }, { - desc => "valid label for device with no bus", + desc => "SYSFS match", subsys => "tty", devpath => "/class/tty/console", exp_name => "foo" , @@ -470,11 +460,11 @@ EOF desc => "program and bus type match", subsys => "block", devpath => "/block/sda", - exp_name => "scsi-sda" , + exp_name => "scsi-0:0:0:0" , rules => < "symlink2-ttyUSB0", exp_target => "ttyUSB0", rules => < "symlink %k substitution", + desc => "symlink %b substitution", subsys => "block", devpath => "/block/sda", - exp_name => "symlink-sda", + exp_name => "symlink-0:0:0:0", exp_target => "node", rules => <; - close $fd; - $dev =~ m/^(.+):(.+)$/; - $ENV{MAJOR} = $1; - $ENV{MINOR} = $2; - # create temporary rules open CONF, ">$udev_rules" || die "unable to create rules file: $udev_rules"; print CONF $$rules; diff --git a/udev.8 b/udev.8 index 6d2f5e679e..8eb63c2015 100644 --- a/udev.8 +++ b/udev.8 @@ -70,31 +70,35 @@ Assign a value to a key finally; disallow any later changes, which may be used t The following key names can be used to match against device properties: .TP \fBACTION\fR -Match the kernel action name. +Match the name of the event action. .TP \fBKERNEL\fR -Match the kernel device name +Match the name of the device. .TP \fBDEVPATH\fR -Match the kernel devpath. +Match the devpath of the device. .TP \fBSUBSYSTEM\fR -Match the kernel subsystem name +Match the subsystem of the device. .TP \fBBUS\fR -Match the type of bus the device is connected to. +Search the devpath upwards for a matching device subsystem name. .TP \fBDRIVER\fR -Match the kernel driver name. +Search the devpath upwards for a matching device driver name. .TP \fBID\fR -Match the device number on the bus. -.TP -\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR -Match against the value of an environment key. Depending on the specified operation, this key is also used as an assignment. +Search the devpath upwards for a matching device name. .TP \fBSYSFS{\fR\fB\fIfilename\fR\fR\fB}\fR -Match the sysfs attribute value. Up to five values can be specified. Trailing whitespace is ignored, if the specified match value does not contain trailing whitespace itself. +Search the devpath upwards for a device with matching sysfs attribute values. Up to five +\fBSYSFS\fR +keys can be specified per rule. All attributes 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. +.TP +\fBENV{\fR\fB\fIkey\fR\fR\fB}\fR +Match against the value of an environment variable. Up to five +\fBENV\fR +keys can be specified per rule. This key can also be used to export a variable to the environment. .TP \fBPROGRAM\fR Execute external program. The key is true, if the program returns without exit code zero. The whole event environment is available to the executed program. The program's output printed to stdout is available for the RESULT key. @@ -125,7 +129,7 @@ The name of a symlink targeting the node. Every matching rule can add this value The permissions for the device node. Every specified value overwrites the compiled\-in default value. .TP \fBENV{\fR\fB\fIkey\fR\fR\fB}\fR -Export the key to the environment. Depending on the specified operation, this key is also used as a match. +Export a variable to the environment. This key can also be used to match against an environment variable. .TP \fBRUN\fR Add a program to the list of programs to be executed for a specific device. @@ -137,14 +141,14 @@ Named label where a GOTO can jump to. Jumps to the next LABEL with a matching gname .TP \fBIMPORT{\fR\fB\fItype\fR\fR\fB}\fR -Import the printed result or the content of a file in environment key format into the event environment. +Import the printed result or the value of a file in environment key format into the event environment. \fBprogram\fR will execute an external program and read its output. \fBfile\fR will inport a text file. If no option is given, udev will determine it from the executable bit of of the file permissions. .TP \fBWAIT_FOR_SYSFS\fR -Wait for the specified sysfs file of the device to be created. May be used to fight agains timing issues wth the kernel. +Wait for the specified sysfs file of the device to be created. Can be used to fight against kernel sysfs timing issues. .TP \fBOPTIONS\fR \fBlast_rule\fR @@ -165,42 +169,46 @@ and \fBGROUP\fR fields support simple printf\-like string substitutions: .TP -\fB%k\fR, \fB$kernel\fR +\fB$kernel\fR, \fB%k\fR The kernel name for this device. .TP -\fB%b\fR, \fB$id\fR -The kernel bus id for this device. -.TP -\fB%n\fR, \fB$number\fR +\fB$number\fR, \fB%n\fR The kernel number for this device. For example, 'sda3' has kernel number of '3' .TP -\fB%p\fR, \fB$devpath\fR +\fB$devpath\fR, \fB%p\fR The devpath of the device. .TP -\fB%s{\fR\fB\fIfile\fR\fR\fB}\fR, \fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR -The content of a sysfs attribute. +\fB$id\fR, \fB%b\fR +The name of the device matched while searching the devpath upwards for +\fBBUS\fR, +\fBID\fR \fBDRIVER\fR +and +\fBSYSFS\fR. .TP -\fB%E{\fR\fB\fIkey\fR\fR\fB}\fR, \fB$env{\fR\fB\fIkey\fR\fR\fB}\fR +\fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR, \fB%s{\fR\fB\fIfile\fR\fR\fB}\fR +The value of a sysfs attribute found at the current or a parent device. +.TP +\fB$env{\fR\fB\fIkey\fR\fR\fB}\fR, \fB%E{\fR\fB\fIkey\fR\fR\fB}\fR The value of an environment variable. .TP -\fB%m\fR, \fB$major\fR +\fB$major\fR, \fB%M\fR The kernel major number for the device. .TP -\fB%M\fR \fB$minor\fR +\fB$minor\fR \fB%m\fR The kernel minor number for the device. .TP -\fB%c\fR, \fB$result\fR +\fB$result\fR, \fB%c\fR 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 .TP -\fB%P\fR, \fB$parent\fR +\fB$parent\fR, \fB%P\fR The node name of the parent device. .TP -\fB%r\fR, \fB$root\fR +\fB$root\fR, \fB%r\fR The udev_root value. .TP -\fB%N\fR, \fB$tempnode\fR +\fB$tempnode\fR, \fB%N\fR The name of a created temporary device node to provide access to the device from a external program before the real node is created. .TP \fB%%\fR diff --git a/udev.h b/udev.h index 6dc0c9e354..5d54b54432 100644 --- a/udev.h +++ b/udev.h @@ -30,41 +30,42 @@ #include "udev_libc_wrapper.h" #include "udev_version.h" -#define COMMENT_CHARACTER '#' -#define PATH_TO_NAME_CHAR '@' -#define LINE_SIZE 512 -#define NAME_SIZE 128 -#define PATH_SIZE 256 -#define USER_SIZE 32 -#define SEQNUM_SIZE 32 -#define VALUE_SIZE 128 +#define COMMENT_CHARACTER '#' +#define PATH_TO_NAME_CHAR '@' +#define LINE_SIZE 512 +#define NAME_SIZE 128 +#define PATH_SIZE 256 +#define USER_SIZE 32 +#define SEQNUM_SIZE 32 +#define VALUE_SIZE 128 -#define DEFAULT_PARTITIONS_COUNT 15 -#define UDEV_ALARM_TIMEOUT 180 +#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 READ_END 0 +#define WRITE_END 1 -#define DB_DIR ".udev/db" +#define DB_DIR ".udev/db" struct udev_rules; struct sysfs_device { - struct list_head node; /* for device cache */ + struct list_head node; /* for device cache */ char devpath[PATH_SIZE]; - char subsystem[NAME_SIZE]; /* $class/$bus/"drivers" */ - char kernel_name[NAME_SIZE]; /* device instance name */ + char subsystem[NAME_SIZE]; /* $class/$bus/"drivers" */ + char kernel_name[NAME_SIZE]; /* device instance name */ char kernel_number[NAME_SIZE]; - char driver[NAME_SIZE]; /* device driver name */ + 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; /* 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 */ diff --git a/udev_rules.c b/udev_rules.c index fc1f3c9c3d..e9d8d7560e 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -376,6 +376,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize) SUBST_DEVPATH, SUBST_KERNEL_NUMBER, SUBST_KERNEL_NAME, + SUBST_ID, SUBST_MAJOR, SUBST_MINOR, SUBST_RESULT, @@ -395,6 +396,7 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize) { .name = "devpath", .fmt = 'p', .type = SUBST_DEVPATH }, { .name = "number", .fmt = 'n', .type = SUBST_KERNEL_NUMBER }, { .name = "kernel", .fmt = 'k', .type = SUBST_KERNEL_NAME }, + { .name = "id", .fmt = 'b', .type = SUBST_ID }, { .name = "major", .fmt = 'M', .type = SUBST_MAJOR }, { .name = "minor", .fmt = 'm', .type = SUBST_MINOR }, { .name = "result", .fmt = 'c', .type = SUBST_RESULT }, @@ -477,6 +479,12 @@ found: 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_name, maxsize); + dbg("substitute id '%s'", udev->dev_parent->kernel_name); + } + break; case SUBST_MAJOR: sprintf(temp2, "%d", major(udev->devt)); strlcat(string, temp2, maxsize); @@ -681,20 +689,19 @@ static int match_key(const char *key_name, struct udev_rule *rule, struct key *k /* match a single rule against a given device and possibly its parent devices */ static int match_rule(struct udevice *udev, struct udev_rule *rule) { - struct sysfs_device *dev_parent; int i; if (match_key("ACTION", rule, &rule->action, udev->action)) - goto exit; + goto nomatch; if (match_key("KERNEL", rule, &rule->kernel_name, udev->dev->kernel_name)) - goto exit; + goto nomatch; if (match_key("SUBSYSTEM", rule, &rule->subsystem, udev->dev->subsystem)) - goto exit; + goto nomatch; if (match_key("DEVPATH", rule, &rule->devpath, udev->dev->devpath)) - goto exit; + goto nomatch; if (rule->modalias.operation != KEY_OP_UNSET) { const char *value; @@ -702,10 +709,10 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule) value = sysfs_attr_get_value(udev->dev->devpath, "modalias"); if (value == NULL) { dbg("MODALIAS value not found"); - goto exit; + goto nomatch; } if (match_key("MODALIAS", rule, &rule->modalias, value)) - goto exit; + goto nomatch; } for (i = 0; i < rule->env.count; i++) { @@ -721,7 +728,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule) value = ""; } if (match_key("ENV", rule, &pair->key, value)) - goto exit; + goto nomatch; } } @@ -741,24 +748,24 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule) return -1; } - /* walk up the chain of physical devices and find a match */ - dev_parent = udev->dev; + /* walk up the chain of parent devices and find a match */ + udev->dev_parent = udev->dev; while (1) { /* check for matching driver */ if (rule->driver.operation != KEY_OP_UNSET) { - if (match_key("DRIVER", rule, &rule->driver, dev_parent->driver)) + if (match_key("DRIVER", rule, &rule->driver, udev->dev_parent->driver)) goto try_parent; } - /* check for matching bus value */ + /* check for matching subsystem/bus value */ if (rule->bus.operation != KEY_OP_UNSET) { - if (match_key("BUS", rule, &rule->bus, dev_parent->subsystem)) + if (match_key("BUS", rule, &rule->bus, udev->dev_parent->subsystem)) goto try_parent; } - /* check for matching bus id */ + /* check for matching bus id (device name) */ if (rule->id.operation != KEY_OP_UNSET) { - if (match_key("ID", rule, &rule->id, dev_parent->kernel_name)) + if (match_key("ID", rule, &rule->id, udev->dev_parent->kernel_name)) goto try_parent; } @@ -773,7 +780,7 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule) char val[VALUE_SIZE]; size_t len; - value = sysfs_attr_get_value(dev_parent->devpath, key_name); + value = sysfs_attr_get_value(udev->dev_parent->devpath, key_name); if (value == NULL) goto try_parent; strlcpy(val, value, sizeof(val)); @@ -796,12 +803,13 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule) /* found matching device */ break; try_parent: + /* move to parent device */ dbg("try parent sysfs device"); - dev_parent = sysfs_device_get_parent(dev_parent); - if (dev_parent == NULL) - goto exit; - dbg("looking at dev_parent->devpath='%s'", dev_parent->devpath); - dbg("looking at dev_parent->bus_kernel_name='%s'", dev_parent->kernel_name); + 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->bus_kernel_name='%s'", udev->dev_parent->kernel_name); } /* execute external program */ @@ -815,7 +823,7 @@ try_parent: dbg("PROGRAM is false"); udev->program_result[0] = '\0'; if (rule->program.operation != KEY_OP_NOMATCH) - goto exit; + goto nomatch; } else { int count; @@ -828,14 +836,14 @@ try_parent: strlcpy(udev->program_result, result, sizeof(udev->program_result)); dbg("PROGRAM returned successful"); if (rule->program.operation == KEY_OP_NOMATCH) - goto exit; + 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 exit; + goto nomatch; /* import variables returned from program or or file into environment */ if (rule->import.operation != KEY_OP_UNSET) { @@ -857,7 +865,7 @@ try_parent: if (rc != 0) { dbg("IMPORT failed"); if (rule->import.operation != KEY_OP_NOMATCH) - goto exit; + goto nomatch; } else dbg("IMPORT '%s' imported", key_val(rule, &rule->import)); dbg("IMPORT key is true"); @@ -879,7 +887,7 @@ try_parent: return 0; -exit: +nomatch: return -1; } From ea48d4d7fb856184b5caadf5436a48afe5ad113c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 16 Jan 2006 06:14:26 +0100 Subject: [PATCH 1678/4284] prepare moving of /sys/class devices to /sys/devices Signed-off-by: Kay Sievers --- udev_sysfs.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index 19fd614e63..9838379803 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -128,7 +128,7 @@ struct sysfs_device *sysfs_device_get(const char *devpath) strlcpy(path, sysfs_path, sizeof(path)); strlcat(path, devpath_real, sizeof(path)); if (lstat(path, &statbuf) != 0) { - dbg("stat '%s' failed: %s", devpath, strerror(errno)); + dbg("stat '%s' failed: %s", path, strerror(errno)); return NULL; } @@ -182,10 +182,10 @@ struct sysfs_device *sysfs_device_get(const char *devpath) pos[0] = '\0'; else dev->subsystem[0] = '\0'; - } else if (strncmp(devpath, "/block/", 7) == 0) { + } else if (strncmp(dev->devpath, "/block/", 7) == 0) { strlcpy(dev->subsystem, "block", sizeof(dev->subsystem)); - } else if (strncmp(devpath, "/devices/", 9) == 0) { - /* get subsystem from bus name */ + } 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)); @@ -196,8 +196,20 @@ struct sysfs_device *sysfs_device_get(const char *devpath) pos = strrchr(link_target, '/'); if (pos != NULL) strlcpy(dev->subsystem, &pos[1], sizeof(dev->subsystem)); + } else { + /* get subsystem from "subsystem" link */ + 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) { + 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)); + } } - /* get driver name */ strlcpy(link_path, sysfs_path, sizeof(link_path)); strlcat(link_path, dev->devpath, sizeof(link_path)); @@ -210,9 +222,9 @@ struct sysfs_device *sysfs_device_get(const char *devpath) if (pos != NULL) strlcpy(dev->driver, &pos[1], sizeof(dev->driver)); } - } else if (strncmp(devpath, "/bus/", 5) == 0 && strstr(devpath, "/drivers/")) { + } else if (strncmp(dev->devpath, "/bus/", 5) == 0 && strstr(dev->devpath, "/drivers/")) { strlcpy(dev->subsystem, "drivers", sizeof(dev->subsystem)); - } else if (strncmp(devpath, "/module/", 8) == 0) { + } else if (strncmp(dev->devpath, "/module/", 8) == 0) { strlcpy(dev->subsystem, "module", sizeof(dev->subsystem)); } From 7155bfb7fa7d72bc4e7341ad1481ffd4c6e39f97 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 16 Jan 2006 06:16:57 +0100 Subject: [PATCH 1679/4284] 081 release --- ChangeLog | 11 +++++++++++ Makefile | 2 +- RELEASE-NOTES | 11 +++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 25e23de593..68db4db036 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 5c44571aab..bb4f6d4239 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 080 +VERSION = 081 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 623ea0ed60..68f7b88067 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,14 @@ +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 From 6ecd4d1e364ea8104c83e36b82d1c23835fb104b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 18 Jan 2006 04:24:48 +0100 Subject: [PATCH 1680/4284] scsi_id, usb_id: request device parent by subsystem Request specific parents identified by subsystem and don't rely on a predefined sequence. Also let the devpath be longer than 72 chars, tsss ... Signed-off-by: Kay Sievers --- extras/scsi_id/scsi_id.c | 28 ++++++++++++---------------- extras/scsi_id/scsi_id.h | 2 +- extras/usb_id/usb_id.c | 27 ++++++++++----------------- udev.h | 1 + udev_sysfs.c | 13 +++++++++++++ 5 files changed, 37 insertions(+), 34 deletions(-) diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 3a4a374d3e..6458f2b7ac 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -48,7 +48,7 @@ static int all_good; static int always_info; static int dev_specified; static int sys_specified; -static char config_file[MAX_NAME_LEN] = SCSI_ID_CONFIG_FILE; +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; @@ -174,7 +174,7 @@ static int create_tmp_dev(const char *devpath, char *tmpdev, int dev_type) return -1; } - snprintf(tmpdev, MAX_NAME_LEN, "%s/%s-maj%d-min%d-%u", + snprintf(tmpdev, MAX_PATH_LEN, "%s/%s-maj%d-min%d-%u", TMP_DIR, TMP_PREFIX, maj, min, getpid()); dbg("tmpdev '%s'", tmpdev); @@ -433,7 +433,8 @@ static int set_options(int argc, char **argv, const char *short_opts, case 'd': dev_specified = 1; - strncpy(maj_min_dev, optarg, MAX_NAME_LEN); + strncpy(maj_min_dev, optarg, MAX_PATH_LEN); + maj_min_dev[MAX_PATH_LEN-1] = '\0'; break; case 'e': @@ -441,7 +442,8 @@ static int set_options(int argc, char **argv, const char *short_opts, break; case 'f': - strncpy(config_file, optarg, MAX_NAME_LEN); + strncpy(config_file, optarg, MAX_PATH_LEN); + config_file[MAX_PATH_LEN-1] = '\0'; break; case 'g': @@ -467,8 +469,8 @@ static int set_options(int argc, char **argv, const char *short_opts, case 's': sys_specified = 1; - strncpy(target, optarg, MAX_NAME_LEN); - target[MAX_NAME_LEN-1] = '\0'; + strncpy(target, optarg, MAX_PATH_LEN); + target[MAX_PATH_LEN-1] = '\0'; break; case 'u': @@ -640,18 +642,12 @@ static int scsi_id(const char *devpath, char *maj_min_dev) dev_type = S_IFCHR; /* get scsi parent device */ - dev_scsi = sysfs_device_get_parent(dev); + 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; } - /* allow only scsi devices */ - if (strcmp(dev_scsi->subsystem, "scsi") != 0) { - info("%s is not a scsi device", devpath); - return 1; - } - /* 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"); @@ -707,8 +703,8 @@ static int scsi_id(const char *devpath, char *maj_min_dev) int main(int argc, char **argv) { int retval = 0; - char devpath[MAX_NAME_LEN]; - char maj_min_dev[MAX_NAME_LEN]; + char devpath[MAX_PATH_LEN]; + char maj_min_dev[MAX_PATH_LEN]; int newargc; const char *env; char **newargv; @@ -729,7 +725,7 @@ int main(int argc, char **argv) if (env) { hotplug_mode = 1; sys_specified = 1; - strncpy(devpath, env, MAX_NAME_LEN); + strncpy(devpath, env, MAX_PATH_LEN); devpath[sizeof(devpath)-1] = '\0'; } diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index b5312b8988..758706ba25 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -21,7 +21,7 @@ * USA */ -#define MAX_NAME_LEN 72 +#define MAX_PATH_LEN 512 /* * MAX_ATTR_LEN: maximum length of the result of reading a sysfs diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index 0bcd267f67..62aa1506d7 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -23,7 +23,7 @@ #include "../../udev.h" -#define MAX_NAME_LEN 72 +#define MAX_PATH_LEN 512 #define MAX_SERIAL_LEN 256 #define BLKGETSIZE64 _IOR(0x12,114,size_t) @@ -247,7 +247,9 @@ static int usb_id(const char *devpath) struct sysfs_device *dev; struct sysfs_device *dev_scsi; struct sysfs_device *dev_target; - struct sysfs_device *dev_host, *dev_interface, *dev_usb; + struct sysfs_device *dev_host; + 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; @@ -263,14 +265,9 @@ static int usb_id(const char *devpath) } /* get scsi parent device */ - dev_scsi = sysfs_device_get_parent(dev); + 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; - } - /* allow only scsi devices */ - if (strcmp(dev_scsi->subsystem, "scsi") != 0) { - info("%s is not a scsi device", devpath); + err("unable to find parent 'scsi' device of '%s'", devpath); return 1; } @@ -289,20 +286,16 @@ static int usb_id(const char *devpath) } /* usb interface directory */ - dev_interface = sysfs_device_get_parent(dev_host); + dev_interface = sysfs_device_get_parent_with_subsystem(dev_host, "usb"); if (dev_interface == NULL) { err("unable to access parent device of '%s'", devpath); return 1; } /* usb device directory */ - dev_usb = sysfs_device_get_parent(dev_interface); + dev_usb = sysfs_device_get_parent_with_subsystem(dev_interface, "usb"); if (dev_usb == NULL) { - err("unable to access parent device of '%s'", devpath); - return 1; - } - if (strcmp(dev_interface->subsystem, "usb") != 0) { - info("%s is not an usb device", devpath); + err("unable to find parent 'usb' device of '%s'", devpath); return 1; } @@ -397,7 +390,7 @@ int main(int argc, char **argv) { int retval = 0; const char *env; - char devpath[MAX_NAME_LEN]; + char devpath[MAX_PATH_LEN]; int option; logging_init("usb_id"); diff --git a/udev.h b/udev.h index 5d54b54432..0c7ca12f10 100644 --- a/udev.h +++ b/udev.h @@ -113,6 +113,7 @@ extern void sysfs_cleanup(void); extern void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath, const char *subsystem); 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); /* udev_add.c */ diff --git a/udev_sysfs.c b/udev_sysfs.c index 9838379803..172f0ce1fd 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -306,6 +306,19 @@ device_link: return sysfs_device_get(parent_devpath); } +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]; From fbc5a2b921477cf490198e2781f096668f4ffba8 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 19 Jan 2006 04:54:34 +0100 Subject: [PATCH 1681/4284] path_id: work with "all devices in /sys/devices" Signed-off-by: Kay Sievers --- extras/path_id | 129 ++++++++++++++++++++++--------------------------- 1 file changed, 58 insertions(+), 71 deletions(-) diff --git a/extras/path_id b/extras/path_id index 44fc4820b5..af1837a77d 100755 --- a/extras/path_id +++ b/extras/path_id @@ -15,33 +15,37 @@ # DEVPATH=/block/sda/sda3 path_id # path_id -# example for all block devices on a system: -# for i in `find /sys/block -name dev` ;do DEVPATH="`echo $i | sed -e 's@^/sys\|/dev@@g'`" path_id ; done +# examples for all block devices on a system: +# for i in `find /sys/class/block`; do DEVPATH="`echo $i | sed -e 's@^/sys\|/dev@@g'`"; path_id; done -# examples: # SCSI cdrom -# /block/sr0 -> /devices/pci0002:30/0002:30:0c.0/host0/0:0:1:0 -# result: pci-0002:30:0c.0-scsi-0:0:1:0 +# /class/block/sr0 -> /devices/pci0002:30/0002:30:0c.0/host0/target0:0:0/0:0:1:0 +# pci-0002:30:0c.0-scsi-0:0:1:0 +# # SCSI disk -# /block/sda -> /devices/pci0002:30/0002:30:0c.0/host0/0:0:4:0 -# result: pci-0002:30:0c.0-scsi-0:0:4:0 +# /class/block/sda -> /devices/pci0002:30/0002:30:0c.0/host0/target0:0:0/0:0:4:0 +# pci-0002:30:0c.0-scsi-0:0:4:0 +# # SATA disk, 4 channels per controller -# /block/sda -> /devices/pci0001:00/0001:00:07.0/0001:05:0c.0/host0/0:0:0:0 -# result: pci-0001:05:0c.0-scsi-0:0:0:0 +# /class/block/sda -> /devices/pci0001:00/0001:00:07.0/0001:05:0c.0/host0/target0:0:0/0:0:0:0 +# pci-0001:05:0c.0-scsi-0:0:0:0 +# # IDE disk -# /block/hda -> /devices/pci0002:02/0002:02:0d.0/ide0/0.0 -# result: pci-0002:02:0d.0-ide-0.0 +# /class/block/hda -> /devices/pci0002:02/0002:02:0d.0/ide0/0.0 +# pci-0002:02:0d.0-ide-0.0 +# # IDE cdrom on a Mac ASIC: -# /block/hdc -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.00020000:ata-3/ide1/1.0 -# result: mac-io_ata-3_master +# /class/block/hdc -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.00020000:ata-3/ide1/1.0 +# mac-io_ata-3_master +# # IDE cdrom on a Mac ASIC, with ide-scsi: -# /block/sr0 -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.0001f000:ata-4/ide0/0.1/host2/2:0:0:0 -# result: mac-io_ata-4_slave +# /class/block/sr0 -> /devices/pci0001:01/0001:01:17.0/0.80000000:mac-io/0.0001f000:ata-4/ide0/0.1/host2/target2:0:0/2:0:0:0 +# mac-io_ata-4_slave # USB CDrom drive without 'serial' number: # reusing 'product' and 'manufacturer' string, if available -# /block/sr0 -> /devices/pci0001:00/0001:00:04.0/0001:02:0b.0/usb4/4-2/4-2:1.0/host4/4:0:0:0 -# result: usb-storage-odd-Freecom-USIDERev930:0:0:0 +# /class/block/sr0 -> /devices/pci0001:00/0001:00:04.0/0001:02:0b.0/usb4/4-2/4-2:1.0/host4/4:0:0:0 +# usb-storage-odd-Freecom-USIDERev930:0:0:0 # devices may have several interfaces on one PCI device, like IDE: # pci-0001:00:04.0_ide1-master @@ -52,24 +56,14 @@ # interface # # match order is important. -# first IDE to find ide-scsi devices. -# then SCSI -# first usb-storage -# then firewire sbp2 -# then the rest +# first IDE to find ide-scsi devices, then SCSI +# first usb-storage, then firewire sbp2, then the rest SYSFS=/sys RESULT=1 -CDROM= TYPE= OPWD="`pwd`" -# Check for 'pwd -P' -if $(pwd -P > /dev/null 2>&1); then - pwd_cmd="pwd -P" -else - pwd_cmd="pwd" -fi -full_sysfs_class_path= +full_sysfs_path= full_sysfs_device_path= if [ -z "$DEVPATH" -a -z "$1" ] ; then @@ -87,29 +81,28 @@ if [ -z "$DEVPATH" ] ; then esac fi -if [ ! -d $SYSFS$DEVPATH ] ; then - exit 1 -fi -if [ ! -f $SYSFS$DEVPATH/dev ] ; then +if [ ! -e $SYSFS$DEVPATH/dev ] ; then exit 1 fi case "$DEVPATH" in - /block/*) - TYPE=block + /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 () { local type offset port @@ -183,7 +176,7 @@ handle_block_ide () { ;; /sys/devices) # PCMCIA devices - ifname=${full_sysfs_class_path##*/} + ifname=${full_sysfs_path##*/} set -- `sed -n "/$ifname/p" /var/lib/pcmcia/stab` d="pcmcia-$1" ;; @@ -202,7 +195,6 @@ handle_block_ide () { else d="${d}-ide-${port}:$channel" fi - RESULT=0 } @@ -301,25 +293,35 @@ handle_block_usb_storage () { fi d="$d:$cil" RESULT=0 - - } handle_block () { - full_sysfs_class_path="$SYSFS$DEVPATH" - if [ ! -f $full_sysfs_class_path/dev ] ; then return ; fi - # the main device has (hopefully) a symlink to the real device - # a partition is a subdir of the main (raw) device - if [ ! -L $full_sysfs_class_path/device ] ; then - if [ -f $full_sysfs_class_path/range ] ; then return ; fi - full_sysfs_class_path="${full_sysfs_class_path%/*}" - : full_sysfs_class_path "$full_sysfs_class_path" - if [ ! -L $full_sysfs_class_path/device -o ! -f $full_sysfs_class_path/dev ] ; then - return + full_sysfs_path="$SYSFS$DEVPATH" + if [ -L $full_sysfs_path/subsystem ]; then + # new sysfs block layout + full_sysfs_path="${full_sysfs_path%/*}" + cd "$full_sysfs_path/subsystem"; + subsys="`pwd -P`" + cd "$OPWD" + subsys="${subsys##*/}" + if [ "$subsys" == "block" ]; then + # parent is "block", it's a partition, move one up + full_sysfs_path="${full_sysfs_path%/*}" fi + cd $full_sysfs_path + else + # old sysfs block layout + if [ ! -L $full_sysfs_path/device ] ; then + if [ -f $full_sysfs_path/range ] ; then return ; fi + 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 fi - cd $full_sysfs_class_path/device - full_sysfs_device_path="`$pwd_cmd`" + full_sysfs_device_path="`pwd -P`" cd "$OPWD" D=$full_sysfs_device_path case "$D" in @@ -361,27 +363,12 @@ handle_block () { handle_block_scsi "$D" fi ;; - *) : not handled RESULT=1 return - ;; esac - # look for a partition - if [ "$full_sysfs_class_path" != "$SYSFS$DEVPATH" ] ; then - dp="`echo $SYSFS$DEVPATH | sed -e 's@^/.*/@@;s@^[^0-9]\{1,\}@@;s@.*_@@'`" - case "$d" in - *[0-9]) - d="${d}p${dp}" - ;; - *) - d="${d}${dp}" - ;; - esac - fi - # done echo "ID_PATH=$d" } From 0ec819d92bd53a2f64e738c40bde39e4d2dd66be Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 20 Jan 2006 02:54:31 +0100 Subject: [PATCH 1682/4284] ignore all messages with missing devpath or action Signed-off-by: Kay Sievers --- udevd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/udevd.c b/udevd.c index f64a4252bb..c45d3a4cd0 100644 --- a/udevd.c +++ b/udevd.c @@ -516,8 +516,8 @@ static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) msg->envp[i++] = "UDEVD_EVENT=1"; msg->envp[i] = NULL; - if (!msg->devpath) { - info("DEVPATH missing, ignore message"); + if (msg->devpath == NULL || msg->action == NULL) { + info("DEVPATH or ACTION missing, ignore message"); free(msg); return NULL; } From aaa14841de57fc0d8c92514da9453c58d9ba59fe Mon Sep 17 00:00:00 2001 From: Olivier Blin Date: Fri, 20 Jan 2006 23:18:23 +0100 Subject: [PATCH 1683/4284] fixes udev build with -fpie Add missing includes and environ declaration. --- udev_sysfs.c | 1 + udev_utils_run.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/udev_sysfs.c b/udev_sysfs.c index 172f0ce1fd..d1e43a60ee 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "udev.h" diff --git a/udev_utils_run.c b/udev_utils_run.c index b6020b0ab6..c6af90658d 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -30,9 +30,11 @@ #include #include #include +#include #include "udev.h" +extern char **environ; int pass_env_to_socket(const char *sockname, const char *devpath, const char *action) { From d8a57e7c2624bf19ad2f4f91a6d9149d5228402f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 23 Jan 2006 03:24:16 +0100 Subject: [PATCH 1684/4284] Makefile: remove dynamic config file generation Signed-off-by: Kay Sievers --- Makefile | 34 +++++++++------------------- etc/udev/{udev.conf.in => udev.conf} | 0 udev_sysfs.c | 2 +- udev_utils_run.c | 3 +-- 4 files changed, 13 insertions(+), 26 deletions(-) rename etc/udev/{udev.conf.in => udev.conf} (100%) diff --git a/Makefile b/Makefile index bb4f6d4239..cb097dde58 100644 --- a/Makefile +++ b/Makefile @@ -43,7 +43,7 @@ USE_STATIC = false # make EXTRAS="extras/ extras/" EXTRAS = -# make the build silent. Set this to something else to make it noisy again. +# make the build silent. V = false PROGRAMS = \ @@ -89,10 +89,6 @@ MAN_PAGES = \ udevinfo.8 \ udevstart.8 -# config files automatically generated -GEN_CONFIGS = \ - $(LOCAL_CFG_DIR)/udev.conf - GEN_HEADERS = \ udev_version.h @@ -105,12 +101,11 @@ libudevdir = ${prefix}/lib/udev mandir = ${prefix}/usr/share/man configdir = ${etcdir}/udev udevdir = /dev -LOCAL_CFG_DIR = etc/udev DESTDIR = INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} -INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} PWD = $(shell pwd) @@ -149,7 +144,6 @@ ifeq ($(strip $(USE_GCOV)),true) LDFLAGS += -fprofile-arcs endif -# if our own version of klibc is used, we need to build it ifeq ($(strip $(USE_KLIBC)),true) KLCC = /usr/bin/$(CROSS)klcc CC = $(KLCC) @@ -211,14 +205,9 @@ $(LIBUDEV): $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS) $(QUIET) $(AR) cq $@ $(UDEV_OBJS) $(QUIET) $(RANLIB) $@ -# generate config files -$(GEN_CONFIGS): - sed -e "s:@udevdir@:$(udevdir):" -e "s:@configdir@:$(configdir):" < $@.in > $@ - -# generate config header file udev_version.h: - @echo "Creating udev_version.h" - @echo \#define UDEV_VERSION \"$(VERSION)\" > $@ + @echo "/* Generated by make. */" > $@ + @echo \#define UDEV_VERSION \"$(VERSION)\" >> $@ @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ @@ -239,8 +228,9 @@ clean: - find -name "*.gcda" -print0 | xargs -0rt rm -f - find -name "*.gcov" -print0 | xargs -0rt rm -f - rm -f udev_gcov.txt - - rm -f core $(PROGRAMS) $(GEN_HEADERS) $(GEN_CONFIGS) + - rm -f core $(PROGRAMS) $(GEN_HEADERS) - rm -f udev-$(VERSION).tar.gz + - rm -f udev-$(VERSION).tar.bz2 @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ $(MAKE) -C $$target $@ || exit 1; \ @@ -249,14 +239,13 @@ clean: release: git-tar-tree HEAD udev-$(VERSION) | gzip -9v > udev-$(VERSION).tar.gz - @echo "udev-$(VERSION).tar.gz created" + git-tar-tree HEAD udev-$(VERSION) | bzip2 -9v > udev-$(VERSION).tar.bz2 .PHONY: release -install-config: $(GEN_CONFIGS) +install-config: $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d @if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \ - echo $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ - $(INSTALL_DATA) $(LOCAL_CFG_DIR)/udev.conf $(DESTDIR)$(configdir); \ + $(INSTALL_DATA) etc/udev/udev.conf $(DESTDIR)$(configdir); \ fi @if [ ! -r $(DESTDIR)$(configdir)/rules.d/50-udev.rules ]; then \ echo; \ @@ -327,8 +316,8 @@ uninstall-bin: - rm -f $(DESTDIR)$(sbindir)/udevcontrol - rm -f $(DESTDIR)$(sbindir)/udevstart - rm -f $(DESTDIR)$(usrsbindir)/udevmonitor - - rm -f $(usrbindir)/udevinfo - - rm -f $(DESTDIR)$(DESTDIR)$(usrbindir)/udevtest + - rm -f $(DESTDIR)$(usrbindir)/udevinfo + - rm -f $(DESTDIR)$(usrbindir)/udevtest ifndef DESTDIR - killall udevd - rm -rf /dev/.udev @@ -387,4 +376,3 @@ udev_gcov.txt: $(wildcard *.gcda) $(wildcard *.gcno) echo >> $@; \ done; \ echo "view $@ for the result" - diff --git a/etc/udev/udev.conf.in b/etc/udev/udev.conf similarity index 100% rename from etc/udev/udev.conf.in rename to etc/udev/udev.conf diff --git a/udev_sysfs.c b/udev_sysfs.c index d1e43a60ee..8de523dadf 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -275,7 +275,7 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) 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"); + dbg("/class top level, look for device link"); goto device_link; } } diff --git a/udev_utils_run.c b/udev_utils_run.c index c6af90658d..31363588c8 100644 --- a/udev_utils_run.c +++ b/udev_utils_run.c @@ -30,7 +30,6 @@ #include #include #include -#include #include "udev.h" @@ -51,7 +50,7 @@ int pass_env_to_socket(const char *sockname, const char *devpath, const char *ac sock = socket(AF_LOCAL, SOCK_DGRAM, 0); memset(&saddr, 0x00, sizeof(struct sockaddr_un)); saddr.sun_family = AF_LOCAL; - /* only abstract namespace is supported */ + /* abstract namespace only */ strcpy(&saddr.sun_path[1], sockname); addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(saddr.sun_path+1) + 1; From aabc6a7294936030fa646ee6f6eae6ffe004774c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 23 Jan 2006 19:08:06 +0100 Subject: [PATCH 1685/4284] path_id: handle fiber channel Patch from: Hannes Reinecke Signed-off-by: Kay Sievers --- extras/path_id | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/extras/path_id b/extras/path_id index af1837a77d..b58e1eda6a 100755 --- a/extras/path_id +++ b/extras/path_id @@ -248,6 +248,46 @@ handle_block_scsi () { RESULT=0 } +handle_block_fc () { +: handle_block_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 + 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]*}" + adapter="${controller_dev##*/}" + bus="pci" + d="$bus-$adapter" + if [ -z "$controller_port" ] ; then + controller_port=0 + fi + d="${d}-fc-${wwpn}:${lun}" + RESULT=0 +} + handle_block_usb_storage () { : handle_block_usb_storage $* local DEV=$1 @@ -353,6 +393,9 @@ handle_block () { RESULT=0 fi ;; + */rport-[0-9]*:[0-9]*-[0-9]*/*) + handle_block_fc "$D" + ;; */host[0-9]*/[0-9]*:[0-9]*:[0-9]*:[0-9]*) # check for ieee1394 sbp2 if test -f $D/ieee1394_id ; then From f83cccb9798d6ce70c6cc39d2100794813b3615b Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 23 Jan 2006 19:09:17 +0100 Subject: [PATCH 1686/4284] usb_id: don't fail on other subsytems than "scsi" Signed-off-by: Kay Sievers --- extras/usb_id/usb_id.c | 151 +++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 89 deletions(-) diff --git a/extras/usb_id/usb_id.c b/extras/usb_id/usb_id.c index 62aa1506d7..783d546b26 100644 --- a/extras/usb_id/usb_id.c +++ b/extras/usb_id/usb_id.c @@ -101,59 +101,44 @@ static void set_str(char *to, const char *from, size_t count) to[j] = '\0'; } -/* - * set_usb_iftype - * - * Set the type based on the USB interface class - */ -static void set_usb_iftype(char *to, const char *from, size_t len) +static void set_usb_iftype(char *to, int if_class_num, size_t len) { - int type_num; - char *eptr; char *type = "generic"; - type_num = strtoul(from, &eptr, 0); - if (eptr != from) { - switch (type_num) { - case 1: - type = "audio"; - break; - case 3: - type = "hid"; - break; - case 7: - type = "printer"; - break; - case 8: - type = "disk"; - 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 */ - default: - break; - } + switch (if_class_num) { + case 1: + type = "audio"; + break; + case 3: + type = "hid"; + break; + case 7: + type = "printer"; + break; + case 8: + type = "disk"; + 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'; } -/* - * set_usb_ifsybtype - * - * Set the type base on the interfaceSubClass. - * Valid for Mass-Storage devices (type 8) only. - */ -static int set_usb_ifsubtype(char *to, const char *from, size_t len) +static int set_usb_mass_storage_ifsubtype(char *to, const char *from, size_t len) { int type_num = 0; char *eptr; @@ -245,9 +230,6 @@ static void set_scsi_type(char *to, const char *from, int count) static int usb_id(const char *devpath) { struct sysfs_device *dev; - struct sysfs_device *dev_scsi; - struct sysfs_device *dev_target; - struct sysfs_device *dev_host; struct sysfs_device *dev_interface; struct sysfs_device *dev_usb; const char *scsi_model, *scsi_vendor, *scsi_type, *scsi_rev; @@ -258,44 +240,17 @@ static int usb_id(const char *devpath) 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; } - /* get scsi parent device */ - dev_scsi = sysfs_device_get_parent_with_subsystem(dev, "scsi"); - if (dev_scsi == NULL) { - err("unable to find parent 'scsi' device of '%s'", devpath); - return 1; - } - - /* target directory */ - dev_target = sysfs_device_get_parent(dev_scsi); - if (dev_target == NULL) { - err("unable to access parent device of '%s'", devpath); - return 1; - } - - /* host directory */ - dev_host = sysfs_device_get_parent(dev_target); - if (dev_host == NULL) { - err("unable to access parent device of '%s'", devpath); - return 1; - } - /* usb interface directory */ - dev_interface = sysfs_device_get_parent_with_subsystem(dev_host, "usb"); + dev_interface = sysfs_device_get_parent_with_subsystem(dev, "usb"); if (dev_interface == NULL) { - err("unable to access parent device of '%s'", devpath); - return 1; - } - - /* usb device directory */ - dev_usb = sysfs_device_get_parent_with_subsystem(dev_interface, "usb"); - if (dev_usb == NULL) { - err("unable to find parent 'usb' device of '%s'", devpath); + info("unable to access usb_interface device of '%s'", devpath); return 1; } @@ -305,46 +260,64 @@ static int usb_id(const char *devpath) return 1; } if_class_num = strtoul(if_class, NULL, 16); - if (if_class_num != 8) { - set_usb_iftype(type_str, if_class, sizeof(type_str)-1); - protocol = 0; - } else { + if (if_class_num == 8) { if_subclass = sysfs_attr_get_value(dev_interface->devpath, "bInterfaceSubClass"); - protocol = set_usb_ifsubtype(type_str, if_subclass, sizeof(type_str)-1); + 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; } - if (!use_usb_info && protocol == 6) { + /* mass storage */ + if (protocol == 6 && !use_usb_info) { + struct sysfs_device *dev_scsi; + + /* 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; + } + /* 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_name); - return 1; + 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_name); - return 1; + 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_name); - return 1; + 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_name); - return 1; + goto fallback; } set_str(revision_str, scsi_rev, sizeof(revision_str)-1); - } +fallback: /* Fallback to USB vendor & device */ if (vendor_str[0] == '\0') { if (!use_num_info) From f61f78a76e424e4ec8197bc52e08d19b2ce07236 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Jan 2006 03:03:42 +0100 Subject: [PATCH 1687/4284] don't do RUN if "ignore_device" is given Signed-off-by: Kay Sievers --- udev_device.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/udev_device.c b/udev_device.c index 0325001428..781787ef4a 100644 --- a/udev_device.c +++ b/udev_device.c @@ -88,7 +88,7 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) udev_rules_get_name(rules, udev); if (udev->ignore_device) { info("device event will be ignored"); - return 0; + return -1; } /* create node, store in db */ if (udev->name[0] != '\0') @@ -104,7 +104,7 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) udev_rules_get_run(rules, udev); if (udev->ignore_device) { info("device event will be ignored"); - return 0; + return -1; } /* get data from db, remove db-entry, delete node */ retval = udev_remove_device(udev); @@ -117,8 +117,10 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) /* default devices */ udev_rules_get_run(rules, udev); - if (udev->ignore_device) + if (udev->ignore_device) { info("device event will be ignored"); + return -1; + } return retval; } From 7d1e179f86aabeb5c206bf9b5bcac52235a9afbf Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Jan 2006 12:12:07 +0100 Subject: [PATCH 1688/4284] increase kernel uevent buffer size Signed-off-by: Kay Sievers --- udevd.c | 2 +- udevd.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/udevd.c b/udevd.c index c45d3a4cd0..ffa81bbb75 100644 --- a/udevd.c +++ b/udevd.c @@ -621,7 +621,7 @@ static struct uevent_msg *get_netlink_msg(void) struct uevent_msg *msg; int bufpos; ssize_t size; - static char buffer[UEVENT_BUFFER_SIZE + 512]; + static char buffer[UEVENT_BUFFER_SIZE+512]; char *pos; size = recv(uevent_netlink_sock, &buffer, sizeof(buffer), 0); diff --git a/udevd.h b/udevd.h index c0a32e97ed..242c0b6907 100644 --- a/udevd.h +++ b/udevd.h @@ -38,8 +38,8 @@ #define UDEVD_MAX_CHILDS_RUNNING 16 /* environment buffer, should match the kernel's size in lib/kobject_uevent.h */ -#define UEVENT_BUFFER_SIZE 1024 -#define UEVENT_NUM_ENVP 32 +#define UEVENT_BUFFER_SIZE 2048 +#define UEVENT_NUM_ENVP 64 enum udevd_msg_type { UDEVD_UNKNOWN, From f5f0c34f6dc32769fd788560ce0d0cac843872b2 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Tue, 24 Jan 2006 20:10:48 +0100 Subject: [PATCH 1689/4284] substitute format chars in RUN after rule matching Apply substitutions before running a program, not while the rule is parsed. It allows to use environment variables set during rule processing as command arguments. --- udev.c | 9 +++++++-- udev_rules.c | 3 +-- udev_rules.h | 2 +- udevd.c | 9 +++++++-- udevstart.c | 9 +++++++-- 5 files changed, 23 insertions(+), 9 deletions(-) diff --git a/udev.c b/udev.c index 4762ab1cef..f808abf427 100644 --- a/udev.c +++ b/udev.c @@ -161,8 +161,13 @@ int main(int argc, char *argv[], char *envp[]) 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:")], devpath, action); - else - run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + else { + char program[PATH_SIZE]; + + strlcpy(program, name_loop->name, sizeof(program)); + apply_format(udev, program, sizeof(program)); + run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + } } } diff --git a/udev_rules.c b/udev_rules.c index e9d8d7560e..fbcbbe0083 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -362,7 +362,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) return -1; } -static void apply_format(struct udevice *udev, char *string, size_t maxsize) +void apply_format(struct udevice *udev, char *string, size_t maxsize) { char temp[PATH_SIZE]; char temp2[PATH_SIZE]; @@ -1017,7 +1017,6 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) name_list_cleanup(&udev->run_list); } strlcpy(program, key_val(rule, &rule->run), sizeof(program)); - apply_format(udev, program, sizeof(program)); dbg("add run '%s'", program); name_list_add(&udev->run_list, program, 0); } diff --git a/udev_rules.h b/udev_rules.h index 125babf1c5..b183d9b531 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -105,7 +105,7 @@ struct udev_rules { extern int udev_rules_init(struct udev_rules *rules, int resolve_names); extern void udev_rules_cleanup(struct udev_rules *rules); -extern void udev_apply_format(struct udevice *udev, char *string, size_t maxsize); +extern void apply_format(struct udevice *udev, char *string, size_t maxsize); extern void udev_rules_iter_init(struct udev_rules *rules); extern struct udev_rule *udev_rules_iter_next(struct udev_rules *rules); diff --git a/udevd.c b/udevd.c index ffa81bbb75..8a352e1eb9 100644 --- a/udevd.c +++ b/udevd.c @@ -123,10 +123,15 @@ static int udev_event_process(struct uevent_msg *msg) 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:")], msg->devpath, msg->action); - else - if (run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, + else { + char program[PATH_SIZE]; + + strlcpy(program, name_loop->name, sizeof(program)); + apply_format(udev, program, sizeof(program)); + if (run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO))) retval = -1; + } } } diff --git a/udevstart.c b/udevstart.c index 8c414f1acb..11bdf79183 100644 --- a/udevstart.c +++ b/udevstart.c @@ -160,8 +160,13 @@ run: 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, "add"); - else - run_program(name_loop->name, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + else { + char program[PATH_SIZE]; + + strlcpy(program, name_loop->name, sizeof(program)); + apply_format(udev, program, sizeof(program)); + run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); + } } } exit: From 2c769419a18281ab095809cf3c37a36f0f615c01 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Jan 2006 20:21:42 +0100 Subject: [PATCH 1690/4284] move udev(8) manpage to udev(7) Signed-off-by: Kay Sievers --- Makefile | 8 ++-- docs/udev.xml | 7 +-- udev.8 => udev.7 | 111 +++++++++++++++++++++++------------------------ 3 files changed, 61 insertions(+), 65 deletions(-) rename udev.8 => udev.7 (86%) diff --git a/Makefile b/Makefile index cb097dde58..500c8db6d2 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ UDEV_OBJS = \ LIBUDEV = libudev.a MAN_PAGES = \ - udev.8 \ + udev.7 \ udevmonitor.8 \ udevd.8 \ udevsend.8 \ @@ -213,7 +213,7 @@ udev_version.h: @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ # man pages -%.8: docs/%.xml +%.8 %.7: docs/%.xml xmlto man $? .PRECIOUS: %.8 @@ -259,7 +259,7 @@ install-config: .PHONY: install-config install-man: - $(INSTALL_DATA) -D udev.8 $(DESTDIR)$(mandir)/man8/udev.8 + $(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 udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 @@ -274,7 +274,7 @@ install-man: .PHONY: install-man uninstall-man: - - rm -f $(DESTDIR)$(mandir)/man8/udev.8 + - 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/udevstart.8 diff --git a/docs/udev.xml b/docs/udev.xml index ab8174e6a9..7e29077977 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -27,7 +27,7 @@ udev - 8 + 7 @@ -510,14 +510,11 @@ SEE ALSO - udev8 + udevd8 , udevinfo8 , - - udevd8 - , udevmonitor8 diff --git a/udev.8 b/udev.7 similarity index 86% rename from udev.8 rename to udev.7 index 8eb63c2015..a7e2f5a4e7 100644 --- a/udev.8 +++ b/udev.7 @@ -1,8 +1,8 @@ .\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. -.TH "UDEV" "8" "August 2005" "udev" "udev" +.TH "UDEV" "7" "August 2005" "udev" "udev" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -11,43 +11,43 @@ 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 +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) +Usually udev runs as +\fBudevd\fR(8) and receives uevents directly from the kernel if a device is added or removed form 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 +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 +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: .TP \fBudev_root\fR -Specifies where to place the device nodes in the filesystem. The default value is +Specifies where to place the device nodes in the filesystem. The default value is \fI/dev\fR. .TP \fBudev_rules\fR -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 +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. .TP \fBudev_log\fR -The logging priority. Valid values are the numerical syslog priorities or their textual representations: -\fBerr\fR, -\fBinfo\fR -and +The logging priority. Valid values are the numerical syslog priorities or their textual representations: +\fBerr\fR, +\fBinfo\fR +and \fBdebug\fR. .SS "Rules files" .PP -The udev rules are read from the files located in the -\fI/etc/udev/rules.d\fR +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 configuraton file. Every line in the rules file contains at least one key value pair. There are two kind of keys, match and assignement 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. .PP A rule may consists 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: @@ -91,13 +91,13 @@ Search the devpath upwards for a matching device driver name. Search the devpath upwards for a matching device name. .TP \fBSYSFS{\fR\fB\fIfilename\fR\fR\fB}\fR -Search the devpath upwards for a device with matching sysfs attribute values. Up to five -\fBSYSFS\fR +Search the devpath upwards for a device with matching sysfs attribute values. Up to five +\fBSYSFS\fR keys can be specified per rule. All attributes 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. .TP \fBENV{\fR\fB\fIkey\fR\fR\fB}\fR -Match against the value of an environment variable. Up to five -\fBENV\fR +Match against the value of an environment variable. Up to five +\fBENV\fR keys can be specified per rule. This key can also be used to export a variable to the environment. .TP \fBPROGRAM\fR @@ -141,32 +141,32 @@ Named label where a GOTO can jump to. Jumps to the next LABEL with a matching gname .TP \fBIMPORT{\fR\fB\fItype\fR\fR\fB}\fR -Import the printed result or the value of a file in environment key format into the event environment. -\fBprogram\fR -will execute an external program and read its output. -\fBfile\fR +Import the printed result or the value of a file in environment key format into the event environment. +\fBprogram\fR +will execute an external program and read its output. +\fBfile\fR will inport a text file. If no option is given, udev will determine it from the executable bit of of the file permissions. .TP \fBWAIT_FOR_SYSFS\fR Wait for the specified sysfs file of the device to be created. Can be used to fight against kernel sysfs timing issues. .TP \fBOPTIONS\fR -\fBlast_rule\fR -stops further rules application. No later rules will have any effect. -\fBignore_device\fR -will ignore this event completely. -\fBignore_remove\fR -will ignore any later remove event for this device. This may be useful as a workaround for broken device drivers. -\fBall_partitions\fR +\fBlast_rule\fR +stops further rules application. No later rules will have any effect. +\fBignore_device\fR +will ignore this event completely. +\fBignore_remove\fR +will ignore any later remove event for this device. This may be useful as a workaround for broken device drivers. +\fBall_partitions\fR will create device nodes for all available partitions of a block device. This may be useful for removable media. .PP -The -\fBNAME\fR, -\fBSYMLINK\fR, -\fBPROGRAM\fR, -\fBOWNER\fR -and -\fBGROUP\fR +The +\fBNAME\fR, +\fBSYMLINK\fR, +\fBPROGRAM\fR, +\fBOWNER\fR +and +\fBGROUP\fR fields support simple printf\-like string substitutions: .TP \fB$kernel\fR, \fB%k\fR @@ -179,10 +179,10 @@ The kernel number for this device. For example, 'sda3' has kernel number of '3' The devpath of the device. .TP \fB$id\fR, \fB%b\fR -The name of the device matched while searching the devpath upwards for -\fBBUS\fR, -\fBID\fR \fBDRIVER\fR -and +The name of the device matched while searching the devpath upwards for +\fBBUS\fR, +\fBID\fR\fBDRIVER\fR +and \fBSYSFS\fR. .TP \fB$sysfs{\fR\fB\fIfile\fR\fR\fB}\fR, \fB%s{\fR\fB\fIfile\fR\fR\fB}\fR @@ -198,8 +198,8 @@ The kernel major number for the device. The kernel minor number for the device. .TP \fB$result\fR, \fB%c\fR -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: +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 .TP \fB$parent\fR, \fB%P\fR @@ -221,9 +221,9 @@ The count of characters to be substituted may be limited by specifying the forma .SH "ENVIRONMENT" .TP \fBACTION\fR -\fIadd\fR -or -\fIremove\fR +\fIadd\fR +or +\fIremove\fR signifies the addition or the removal of a device. .TP \fBDEVPATH\fR @@ -236,15 +236,14 @@ The kernel subsystem the device belongs to. Overrides the syslog priority specified in the config file. .SH "AUTHOR" .PP -Written by Greg Kroah\-Hartman - -and Kay Sievers -. With much help from Dan Stekloff - +Written by Greg Kroah\-Hartman + +and Kay Sievers +. With much help from Dan Stekloff + and many others. .SH "SEE ALSO" .PP -\fBudev\fR(8), -\fBudevinfo\fR(8), -\fBudevd\fR(8), +\fBudevd\fR(8), +\fBudevinfo\fR(8), \fBudevmonitor\fR(8) From 0d210b3ad9ebca9fb60c79b2ebbd3d1482485bd3 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Jan 2006 20:24:26 +0100 Subject: [PATCH 1691/4284] recreate man pages from xml source Signed-off-by: Kay Sievers --- udevd.8 | 12 ++++++------ udevinfo.8 | 32 ++++++++++++++++---------------- udevmonitor.8 | 4 ++-- udevsend.8 | 12 ++++++------ udevstart.8 | 4 ++-- udevtest.8 | 4 ++-- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/udevd.8 b/udevd.8 index c6efe9a03a..bf7e3c7f2f 100644 --- a/udevd.8 +++ b/udevd.8 @@ -1,5 +1,5 @@ .\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. .TH "UDEVD" "8" "August 2005" "udev" "udevd, udevcontrol" @@ -23,10 +23,10 @@ udevd listens to kernel uevents and passes the incoming events to udev. It ensur Detach and run in the background. .TP \fBlog_priority=\fR\fB\fIvalue\fR\fR -udevcontrol can dynamically set the log level of udevd. Valid values are the numerical syslog priorities or their textual representations: -\fBerr\fR, -\fBinfo\fR -and +udevcontrol can dynamically set the log level of udevd. Valid values are the numerical syslog priorities or their textual representations: +\fBerr\fR, +\fBinfo\fR +and \fBdebug\fR. .TP \fBstop_exec_queue\fR @@ -40,7 +40,7 @@ udevcontrol starts the execution of events from udevd. Overrides the syslog priority specified in the config file. .SH "AUTHOR" .PP -Written by Kay Sievers +Written by Kay Sievers . .SH "SEE ALSO" .PP diff --git a/udevinfo.8 b/udevinfo.8 index fc7001dc21..b74a690584 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -1,5 +1,5 @@ .\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. .TH "UDEVINFO" "8" "August 2005" "udev" "udevinfo" @@ -18,15 +18,15 @@ udevinfo queries the udev database for device information stored in the udev dat .SH "OPTIONS" .TP \fB\-q\fR -Query the database for specified type of device data. It needs the -\fB\-p\fR -or -\fB\-n\fR -to identify the specified device. Valid queries are: -\fBname\fR, -\fBsymlink\fR, -\fBpath\fR, -\fBenv\fR, +Query the database for specified type of device data. It needs the +\fB\-p\fR +or +\fB\-n\fR +to identify the specified device. Valid queries are: +\fBname\fR, +\fBsymlink\fR, +\fBpath\fR, +\fBenv\fR, \fBall\fR. .TP \fB\-a\fR @@ -39,11 +39,11 @@ The sysfs path of the device to query. The name of the device node or a symlink to query .TP \fB\-r\fR -The udev root directory: -\fI/dev\fR. If used in conjunction with a -\fBname\fR -or -\fBsymlink\fR +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. .TP \fB\-e\fR @@ -53,7 +53,7 @@ Export the content of the udev database. Print help text. .SH "AUTHOR" .PP -Written by Kay Sievers +Written by Kay Sievers . .SH "SEE ALSO" .PP diff --git a/udevmonitor.8 b/udevmonitor.8 index 6f60130cc7..e302ba1ab2 100644 --- a/udevmonitor.8 +++ b/udevmonitor.8 @@ -1,5 +1,5 @@ .\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. .TH "UDEVMONITOR" "8" "August 2005" "udev" "udevmonitor" @@ -21,7 +21,7 @@ udevmonitor listens to the kernel uevents and events send out by a udev rule and Print the complete environment for all events. Can be used to compare the kernel supplied and the udev added environment values. .SH "AUTHOR" .PP -Written by Kay Sievers +Written by Kay Sievers . .SH "SEE ALSO" .PP diff --git a/udevsend.8 b/udevsend.8 index d483f22133..97d09d3110 100644 --- a/udevsend.8 +++ b/udevsend.8 @@ -1,5 +1,5 @@ .\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. .TH "UDEVSEND" "8" "August 2005" "udev" "udevsend" @@ -18,9 +18,9 @@ Usually the udev daemon listens directly to the kernel uevents. udevsend may be .SH "ENVIRONMENT" .TP \fBACTION\fR -\fIadd\fR -or -\fIremove\fR +\fIadd\fR +or +\fIremove\fR signifies the addition or the removal of a device. .TP \fBDEVPATH\fR @@ -30,9 +30,9 @@ The sysfs devpath without the mountpoint but a leading slash. The kernel subsystem the device belongs to. .SH "AUTHOR" .PP -Written by Kay Sievers +Written by Kay Sievers . .SH "SEE ALSO" .PP -\fBudev\fR(8), +\fBudev\fR(8), \fBudevd\fR(8) diff --git a/udevstart.8 b/udevstart.8 index ea7a59ea8b..bbc022c2c2 100644 --- a/udevstart.8 +++ b/udevstart.8 @@ -1,5 +1,5 @@ .\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. .TH "UDEVSTART" "8" "August 2005" "udev" "udevstart" @@ -17,7 +17,7 @@ udevstart \- populate initial device directory 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 +Written by Harald Hoyer . .SH "SEE ALSO" .PP diff --git a/udevtest.8 b/udevtest.8 index ea0ea59238..f59c2e921c 100644 --- a/udevtest.8 +++ b/udevtest.8 @@ -1,5 +1,5 @@ .\" ** You probably do not want to edit this file directly ** -.\" It was generated using the DocBook XSL Stylesheets (version 1.69.0). +.\" It was generated using the DocBook XSL Stylesheets (version 1.69.1). .\" Instead of manually editing it, you probably should edit the DocBook XML .\" source for it and then use the DocBook XSL Stylesheets to regenerate it. .TH "UDEVTEST" "8" "August 2005" "udev" "udevtest" @@ -17,7 +17,7 @@ udevtest \- simulate a udev run and print the action to the console 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 renamend. .SH "AUTHOR" .PP -Written by Greg Kroah\-Hartman +Written by Greg Kroah\-Hartman . .SH "SEE ALSO" .PP From c233b59baaabe55a8f99dc37c4ee9011b85f8917 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Jan 2006 20:29:37 +0100 Subject: [PATCH 1692/4284] remove udev, udevstart, udevsend from the default installation They still get compiled and are used for the test program, but everything should just work with the daemon and the kernel "uevent" triggers these days. Signed-off-by: Kay Sievers --- Makefile | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Makefile b/Makefile index 500c8db6d2..94ec41a0a6 100644 --- a/Makefile +++ b/Makefile @@ -262,9 +262,7 @@ 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 udevstart.8 $(DESTDIR)$(mandir)/man8/udevstart.8 $(INSTALL_DATA) -D udevd.8 $(DESTDIR)$(mandir)/man8/udevd.8 - $(INSTALL_DATA) -D udevsend.8 $(DESTDIR)$(mandir)/man8/udevsend.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 \ @@ -277,10 +275,8 @@ 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/udevstart.8 - rm -f $(DESTDIR)$(mandir)/man8/udevd.8 - rm -f $(DESTDIR)$(mandir)/man8/udevmonitor.8 - - rm -f $(DESTDIR)$(mandir)/man8/udevsend.8 - rm -f $(DESTDIR)$(mandir)/man8/udevcontrol.8 @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ @@ -290,14 +286,11 @@ uninstall-man: install-bin: $(INSTALL) -d $(DESTDIR)$(udevdir) - $(INSTALL_PROGRAM) -D udev $(DESTDIR)$(sbindir)/udev $(INSTALL_PROGRAM) -D udevd $(DESTDIR)$(sbindir)/udevd - $(INSTALL_PROGRAM) -D udevsend $(DESTDIR)$(sbindir)/udevsend $(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 - $(INSTALL_PROGRAM) -D udevstart $(DESTDIR)$(sbindir)/udevstart @extras="$(EXTRAS)"; for target in $$extras; do \ echo $$target; \ $(MAKE) -C $$target $@ || exit 1; \ @@ -310,11 +303,8 @@ endif .PHONY: install-bin uninstall-bin: - - rm -f $(DESTDIR)$(sbindir)/udev - rm -f $(DESTDIR)$(sbindir)/udevd - - rm -f $(DESTDIR)$(sbindir)/udevsend - rm -f $(DESTDIR)$(sbindir)/udevcontrol - - rm -f $(DESTDIR)$(sbindir)/udevstart - rm -f $(DESTDIR)$(usrsbindir)/udevmonitor - rm -f $(DESTDIR)$(usrbindir)/udevinfo - rm -f $(DESTDIR)$(usrbindir)/udevtest From 4a2c3aad07a97845ac61701d750cbf6487b36c77 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 24 Jan 2006 21:02:30 +0100 Subject: [PATCH 1693/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/50-udev-default.rules | 4 ---- etc/udev/suse/80-sysconfig.rules | 4 ++-- etc/udev/suse/90-hal.rules | 1 - 3 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 etc/udev/suse/90-hal.rules diff --git a/etc/udev/suse/50-udev-default.rules b/etc/udev/suse/50-udev-default.rules index 667b0ae9b1..4f69c666ac 100644 --- a/etc/udev/suse/50-udev-default.rules +++ b/etc/udev/suse/50-udev-default.rules @@ -43,7 +43,6 @@ KERNEL=="js*", NAME="input/%k", MODE="0644" KERNEL=="ts*", NAME="input/%k", MODE="0600" KERNEL=="uinput", NAME="input/%k", MODE="0600" KERNEL=="lirc0", NAME="%k", SYMLINK+="lirc" -KERNEL=="input[0-9]*", ACTION=="add", RUN+="input.sh" # printer SUBSYSTEM=="usb", KERNEL=="lp*", NAME="usb/%k", SYMLINK+="usb%k", GROUP="lp" @@ -121,9 +120,6 @@ SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="1", RUN+="/sbin/mo SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{device/type}=="[45]", RUN+="/sbin/modprobe sr_mod" SUBSYSTEM=="scsi_device", ACTION=="add", RUN+="/sbin/modprobe sg" -# load IDE modules -SUBSYSTEM=="ide", ACTION=="add", RUN+="ide.sh" - # device mapper KERNEL=="device-mapper", NAME="%k", SYMLINK+="mapper/control" diff --git a/etc/udev/suse/80-sysconfig.rules b/etc/udev/suse/80-sysconfig.rules index d6778647ba..137754e166 100644 --- a/etc/udev/suse/80-sysconfig.rules +++ b/etc/udev/suse/80-sysconfig.rules @@ -15,7 +15,7 @@ SUBSYSTEM=="macio", ACTION=="add", RUN+="/sbin/hwup bus-macio-%k -o hotplug" SUBSYSTEM=="ccw", ACTION=="add", RUN+="/sbin/hwup ccw-devpath-%p -o hotplug" SUBSYSTEM=="ccwgroup", ACTION=="add", RUN+="/sbin/hwup ccwgroup-devpath-%p -o hotplug" SUBSYSTEM=="pnp", ACTION=="add", RUN+="/sbin/hwup pnp-devpath-%p -o hotplug" -#SUBSYSTEM=="ide", ACTION=="add", RUN+="/sbin/hwup ide-devpath-%p -o hotplug" -#SUBSYSTEM=="input", KERNEL=="input[0-9]*", ACTION=="add", RUN+="/sbin/hwup input-devpath-%p -o hotplug" +SUBSYSTEM=="ide", ACTION=="add", RUN+="/sbin/hwup ide-devpath-%p -o hotplug" +SUBSYSTEM=="input", KERNEL=="input[0-9]*", ACTION=="add", RUN+="/sbin/hwup input-devpath-%p -o hotplug" LABEL="sysconfig_end" diff --git a/etc/udev/suse/90-hal.rules b/etc/udev/suse/90-hal.rules deleted file mode 100644 index b0b36330df..0000000000 --- a/etc/udev/suse/90-hal.rules +++ /dev/null @@ -1 +0,0 @@ -RUN+="socket:/org/freedesktop/hal/udev_event" From a9bd2ed84a7b0871c281adc8226f12ae46da4de0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 25 Jan 2006 01:28:31 +0100 Subject: [PATCH 1694/4284] rename apply_format() cause it is public now Signed-off-by: Kay Sievers --- udev.c | 2 +- udev_rules.c | 16 ++++++++-------- udev_rules.h | 4 ++-- udevd.c | 2 +- udevstart.c | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/udev.c b/udev.c index f808abf427..6387d0b14e 100644 --- a/udev.c +++ b/udev.c @@ -165,7 +165,7 @@ int main(int argc, char *argv[], char *envp[]) char program[PATH_SIZE]; strlcpy(program, name_loop->name, sizeof(program)); - apply_format(udev, program, sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); } } diff --git a/udev_rules.c b/udev_rules.c index fbcbbe0083..90dc0243fe 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -362,7 +362,7 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) return -1; } -void apply_format(struct udevice *udev, char *string, size_t maxsize) +void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize) { char temp[PATH_SIZE]; char temp2[PATH_SIZE]; @@ -818,7 +818,7 @@ try_parent: char result[PATH_SIZE]; strlcpy(program, key_val(rule, &rule->program), sizeof(program)); - apply_format(udev, program, sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); if (run_program(program, udev->dev->subsystem, result, sizeof(result), NULL, (udev_log_priority >= LOG_INFO)) != 0) { dbg("PROGRAM is false"); udev->program_result[0] = '\0'; @@ -851,7 +851,7 @@ try_parent: int rc = -1; strlcpy(import, key_val(rule, &rule->import), sizeof(import)); - apply_format(udev, 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); @@ -941,14 +941,14 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) if (rule->owner.operation == KEY_OP_ASSIGN_FINAL) udev->owner_final = 1; strlcpy(udev->owner, key_val(rule, &rule->owner), sizeof(udev->owner)); - apply_format(udev, udev->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_name); } 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)); - apply_format(udev, udev->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_name); } @@ -965,7 +965,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) name_list_cleanup(&udev->symlink_list); } strlcpy(temp, key_val(rule, &rule->symlink), sizeof(temp)); - apply_format(udev, temp, sizeof(temp)); + udev_rules_apply_format(udev, temp, sizeof(temp)); count = replace_untrusted_chars(temp); if (count) info("%i untrusted character(s) replaced" , count); @@ -996,7 +996,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) int count; name_set = 1; strlcpy(udev->name, key_val(rule, &rule->name), sizeof(udev->name)); - apply_format(udev, udev->name, sizeof(udev->name)); + udev_rules_apply_format(udev, udev->name, sizeof(udev->name)); count = replace_untrusted_chars(udev->name); if (count) info("%i untrusted character(s) replaced", count); @@ -1082,7 +1082,7 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev) name_list_cleanup(&udev->run_list); } strlcpy(program, key_val(rule, &rule->run), sizeof(program)); - apply_format(udev, program, sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); dbg("add run '%s'", program); name_list_add(&udev->run_list, program, 0); if (rule->run.operation == KEY_OP_ASSIGN_FINAL) diff --git a/udev_rules.h b/udev_rules.h index b183d9b531..e4d5ebd765 100644 --- a/udev_rules.h +++ b/udev_rules.h @@ -105,8 +105,6 @@ struct udev_rules { extern int udev_rules_init(struct udev_rules *rules, int resolve_names); extern void udev_rules_cleanup(struct udev_rules *rules); -extern void apply_format(struct udevice *udev, char *string, size_t maxsize); - 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); @@ -114,4 +112,6 @@ extern struct udev_rule *udev_rules_iter_label(struct udev_rules *rules, const c 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 void udev_rules_apply_format(struct udevice *udev, char *string, size_t maxsize); + #endif diff --git a/udevd.c b/udevd.c index 8a352e1eb9..4ed2f94bfc 100644 --- a/udevd.c +++ b/udevd.c @@ -127,7 +127,7 @@ static int udev_event_process(struct uevent_msg *msg) char program[PATH_SIZE]; strlcpy(program, name_loop->name, sizeof(program)); - apply_format(udev, program, sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); if (run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO))) retval = -1; diff --git a/udevstart.c b/udevstart.c index 11bdf79183..fdb2ae3808 100644 --- a/udevstart.c +++ b/udevstart.c @@ -164,7 +164,7 @@ run: char program[PATH_SIZE]; strlcpy(program, name_loop->name, sizeof(program)); - apply_format(udev, program, sizeof(program)); + udev_rules_apply_format(udev, program, sizeof(program)); run_program(program, udev->dev->subsystem, NULL, 0, NULL, (udev_log_priority >= LOG_INFO)); } } From ad27f5b3962d4cb1e4fcc25d3d0c7d0c81abc82a Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 25 Jan 2006 02:18:13 +0100 Subject: [PATCH 1695/4284] udevtest: add udev_rules_apply_format() to RUN keys Signed-off-by: Kay Sievers --- udev_add.c | 14 ++++++-------- udevtest.c | 11 ++++++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/udev_add.c b/udev_add.c index 2c66a0ba8d..6de2858313 100644 --- a/udev_add.c +++ b/udev_add.c @@ -135,16 +135,14 @@ static int create_node(struct udevice *udev) gid = lookup_group(udev->group); } - if (!udev->test_run) { - info("creating device node '%s'", filename); + 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_make_node(udev, filename, udev->devt, udev->mode, uid, gid) != 0) goto error; - setenv("DEVNAME", filename, 1); - } else { - 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); - } + + setenv("DEVNAME", filename, 1); /* create all_partitions if requested */ if (udev->partitions) { diff --git a/udevtest.c b/udevtest.c index 22fd3735c2..d736711a3f 100644 --- a/udevtest.c +++ b/udevtest.c @@ -113,11 +113,16 @@ int main(int argc, char *argv[], char *envp[]) info("looking at device '%s' from subsystem '%s'", udev->dev->devpath, udev->dev->subsystem); retval = udev_device_event(&rules, udev); - if (retval == 0) { + if (retval == 0 && !udev->ignore_device && udev_run) { struct name_entry *name_loop; - list_for_each_entry(name_loop, &udev->run_list, node) - info("run: '%s'", name_loop->name); + 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); + } } exit: From 37854ffc9ae60da66d5525225c93eb1754a780bb Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 25 Jan 2006 02:21:07 +0100 Subject: [PATCH 1696/4284] let "ignore_device" always return the event successfully Signed-off-by: Kay Sievers --- udev.c | 6 ++++-- udev_device.c | 14 ++++++-------- udevd.c | 3 ++- udevstart.c | 15 ++++++++------- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/udev.c b/udev.c index 6387d0b14e..17ab635f1e 100644 --- a/udev.c +++ b/udev.c @@ -154,7 +154,7 @@ int main(int argc, char *argv[], char *envp[]) retval = udev_device_event(&rules, udev); - if (!retval && udev_run && !list_empty(&udev->run_list)) { + if (retval == 0 && !udev->ignore_device && udev_run) { struct name_entry *name_loop; dbg("executing run list"); @@ -178,5 +178,7 @@ fail: exit: logging_close(); - return retval; + if (retval != 0) + return 1; + return 0; } diff --git a/udev_device.c b/udev_device.c index 781787ef4a..5db27093d4 100644 --- a/udev_device.c +++ b/udev_device.c @@ -88,14 +88,14 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) udev_rules_get_name(rules, udev); if (udev->ignore_device) { info("device event will be ignored"); - return -1; + return 0; } /* create node, store in db */ if (udev->name[0] != '\0') retval = udev_add_device(udev); else info("device node creation supressed"); - return 0; + return retval; } if (major(udev->devt) != 0 && strcmp(udev->action, "remove") == 0) { @@ -104,7 +104,7 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) udev_rules_get_run(rules, udev); if (udev->ignore_device) { info("device event will be ignored"); - return -1; + return 0; } /* get data from db, remove db-entry, delete node */ retval = udev_remove_device(udev); @@ -112,15 +112,13 @@ int udev_device_event(struct udev_rules *rules, struct udevice *udev) /* restore stored persistent data */ list_for_each_entry(name_loop, &udev->env_list, node) putenv(name_loop->name); - return 0; + return retval; } - /* default devices */ + /* default devices without a node */ udev_rules_get_run(rules, udev); - if (udev->ignore_device) { + if (udev->ignore_device) info("device event will be ignored"); - return -1; - } return retval; } diff --git a/udevd.c b/udevd.c index 4ed2f94bfc..c94fdc74d8 100644 --- a/udevd.c +++ b/udevd.c @@ -117,9 +117,10 @@ static int udev_event_process(struct uevent_msg *msg) retval = udev_device_event(&rules, udev); /* run programs collected by RUN-key*/ - if (retval == 0) { + if (retval == 0 && !udev->ignore_device && udev_run) { struct name_entry *name_loop; + 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:")], msg->devpath, msg->action); diff --git a/udevstart.c b/udevstart.c index fdb2ae3808..8f8342ff48 100644 --- a/udevstart.c +++ b/udevstart.c @@ -108,6 +108,7 @@ static int add_device(const char *devpath) { struct sysfs_device *dev; struct udevice *udev; + int retval; /* clear and set environment for next event */ clearenv(); @@ -146,14 +147,14 @@ static int add_device(const char *devpath) dbg("device event will be ignored"); goto exit; } - if (udev->name[0] == '\0') { - dbg("device node creation supressed"); - goto run; + if (udev->name[0] != '\0') + retval = udev_add_device(udev); + else { + info("device node creation supressed"); + goto exit; } - udev_add_device(udev); -run: - if (udev_run && !list_empty(&udev->run_list)) { + if (retval == 0 && !udev->ignore_device && udev_run) { struct name_entry *name_loop; dbg("executing run list"); @@ -169,9 +170,9 @@ run: } } } + exit: udev_device_cleanup(udev); - return 0; } From 1a72d06f7be696cf6f6753fdc01c0ff8171240ea Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 25 Jan 2006 02:45:48 +0100 Subject: [PATCH 1697/4284] 082 release --- ChangeLog | 27 +++++++++++++++++++++++++++ Makefile | 2 +- RELEASE-NOTES | 35 +++++++++++++++++++++++++++++++++++ TODO | 2 +- 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 68db4db036..9ca3e9354f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 94ec41a0a6..09511c4693 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 081 +VERSION = 082 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 68f7b88067..d04dcd83be 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,38 @@ +udev 082 +======== +The udev man page has moced to udev(7) as it doesnot 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 diff --git a/TODO b/TODO index bdd2e1e1f6..5047f06da9 100644 --- a/TODO +++ b/TODO @@ -15,7 +15,7 @@ udev version: o remove MODALIAS + $modalias (ENV{MODALIAS}, $env{MODALIAS}, $sysfs{modalias} will do it) - o remove udevstart, udevsend + o remove udevsend, udevstart and their man pages (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) From 4cfdeaf3bf82b50fb6af123511d2f94078fe7df2 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 26 Jan 2006 02:16:58 +0100 Subject: [PATCH 1698/4284] udevstart: fix NAME="" which prevents RUN from being executed Thanks to Olivier Blin for finding this. Signed-off-by: Kay Sievers --- udevstart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/udevstart.c b/udevstart.c index 8f8342ff48..d9d6a7b521 100644 --- a/udevstart.c +++ b/udevstart.c @@ -108,7 +108,7 @@ static int add_device(const char *devpath) { struct sysfs_device *dev; struct udevice *udev; - int retval; + int retval = 0; /* clear and set environment for next event */ clearenv(); From 864412e02df16555c02da9ccb0a67fddb6628acd Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 26 Jan 2006 02:18:01 +0100 Subject: [PATCH 1699/4284] man page: document when substitutions are applied for RUN and other keys --- docs/udev.xml | 8 ++++++-- udev.7 | 9 ++++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/udev.xml b/docs/udev.xml index 7e29077977..e0542a6be1 100644 --- a/docs/udev.xml +++ b/docs/udev.xml @@ -353,8 +353,12 @@ The , , , - and fields support simple - printf-like string substitutions: + , 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: , diff --git a/udev.7 b/udev.7 index a7e2f5a4e7..711bd0861b 100644 --- a/udev.7 +++ b/udev.7 @@ -164,10 +164,13 @@ The \fBNAME\fR, \fBSYMLINK\fR, \fBPROGRAM\fR, -\fBOWNER\fR -and +\fBOWNER\fR, \fBGROUP\fR -fields support simple printf\-like string substitutions: +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: .TP \fB$kernel\fR, \fB%k\fR The kernel name for this device. From f7ed0d113a964aae8da4ca752d1330704adb1c65 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 26 Jan 2006 02:24:13 +0100 Subject: [PATCH 1700/4284] check for ignore_device in loop looks redundant --- udevstart.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/udevstart.c b/udevstart.c index d9d6a7b521..e5ce7af030 100644 --- a/udevstart.c +++ b/udevstart.c @@ -149,12 +149,10 @@ static int add_device(const char *devpath) } if (udev->name[0] != '\0') retval = udev_add_device(udev); - else { + else info("device node creation supressed"); - goto exit; - } - if (retval == 0 && !udev->ignore_device && udev_run) { + if (retval == 0 && udev_run) { struct name_entry *name_loop; dbg("executing run list"); From d2f605c8d61e4c5ef129f93510ab8b38e32cee97 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 26 Jan 2006 03:59:13 +0100 Subject: [PATCH 1701/4284] find programs in /lib/udev for IMPORT if {program} is not given Signed-off-by: Kay Sievers --- udev_rules_parse.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/udev_rules_parse.c b/udev_rules_parse.c index 4fcd6db08e..376006c7c4 100644 --- a/udev_rules_parse.c +++ b/udev_rules_parse.c @@ -366,6 +366,16 @@ static int add_to_rules(struct udev_rules *rules, char *line) 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, &stats) && (stats.st_mode & S_IXUSR)) { dbg("IMPORT is executable, will be executed (autotype)"); From 36af2ddcb92c51acad0f909bb5dfb090cea9c5ed Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 26 Jan 2006 04:38:33 +0100 Subject: [PATCH 1702/4284] don't add $SUBSYSTEM automatically as $1 to programs Signed-off-by: Kay Sievers --- RELEASE-NOTES | 12 ++++++++++++ test/udev-test.pl | 9 --------- udev_utils_run.c | 12 ++++++------ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index d04dcd83be..42048cce53 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,15 @@ +udev 083 +======== +Fix a bug where NAME="" would prevent RUN from beeing executed. + +RUN="/bin/program" does no 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 space at the +end of the program name to prevent this. If you use rules that +depend on this, like the old "udev_run_hotlugd" and "udev_run_devd", +switch them to: RUN+="/bin/program $env{SUBSYSTEM}", otherwise +they will no longer work as expected. + udev 082 ======== The udev man page has moced to udev(7) as it doesnot describe a command diff --git a/test/udev-test.pl b/test/udev-test.pl index 555d36e7f2..b44bd18af5 100755 --- a/test/udev-test.pl +++ b/test/udev-test.pl @@ -298,15 +298,6 @@ BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special--*", NAME= BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-device-", NAME="%c-3-%n" BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-devic", NAME="%c-4-%n" BUS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-*", NAME="%c-%n" -EOF - }, - { - desc => "program result substitution (no argument should be subsystem)", - subsys => "block", - devpath => "/block/sda/sda3", - exp_name => "subsys_block" , - rules => < Date: Fri, 27 Jan 2006 01:40:26 +0100 Subject: [PATCH 1703/4284] remove redundant substitution of RUN key Thanks to Andrey Borzenkov for the initial patch. Signed-off-by: Kay Sievers --- udev_rules.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 90dc0243fe..f1bbfd854c 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -994,6 +994,7 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) /* set name, later rules with name set will be ignored */ if (rule->name.operation != KEY_OP_UNSET) { 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)); @@ -1008,17 +1009,14 @@ int udev_rules_get_name(struct udev_rules *rules, struct udevice *udev) } if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { - char program[PATH_SIZE]; - 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); } - strlcpy(program, key_val(rule, &rule->run), sizeof(program)); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); + dbg("add run '%s'", key_val(rule, &rule->run)); + name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); } if (rule->last_rule) { @@ -1075,16 +1073,12 @@ int udev_rules_get_run(struct udev_rules *rules, struct udevice *udev) } if (!udev->run_final && rule->run.operation != KEY_OP_UNSET) { - char program[PATH_SIZE]; - if (rule->run.operation == KEY_OP_ASSIGN || rule->run.operation == KEY_OP_ASSIGN_FINAL) { info("reset run list"); name_list_cleanup(&udev->run_list); } - strlcpy(program, key_val(rule, &rule->run), sizeof(program)); - udev_rules_apply_format(udev, program, sizeof(program)); - dbg("add run '%s'", program); - name_list_add(&udev->run_list, program, 0); + dbg("add run '%s'", key_val(rule, &rule->run)); + name_list_add(&udev->run_list, key_val(rule, &rule->run), 0); if (rule->run.operation == KEY_OP_ASSIGN_FINAL) break; } From cef28db9db6e40271ce72ee42c1bb1a3eecbe25c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 27 Jan 2006 01:41:07 +0100 Subject: [PATCH 1704/4284] 083 release --- ChangeLog | 14 ++++++++++++++ Makefile | 2 +- RELEASE-NOTES | 12 ++++++------ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9ca3e9354f..a2137019cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 09511c4693..9da2964ddf 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 082 +VERSION = 083 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 42048cce53..cce8dc03ce 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -2,13 +2,13 @@ udev 083 ======== Fix a bug where NAME="" would prevent RUN from beeing executed. -RUN="/bin/program" does no longer automatically add the subsystem +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 space at the -end of the program name to prevent this. If you use rules that -depend on this, like the old "udev_run_hotlugd" and "udev_run_devd", -switch them to: RUN+="/bin/program $env{SUBSYSTEM}", otherwise -they will no longer work as expected. +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 ======== From a6aa9d70a470e02ccaf68bdb1929a2b7a3c5d030 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 27 Jan 2006 02:17:59 +0100 Subject: [PATCH 1705/4284] update SUSE rules Signed-off-by: Kay Sievers --- etc/udev/suse/05-udev-early.rules | 9 +++++---- etc/udev/suse/50-udev-default.rules | 14 +++++++------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/etc/udev/suse/05-udev-early.rules b/etc/udev/suse/05-udev-early.rules index dfdbdff0c9..5818d43335 100644 --- a/etc/udev/suse/05-udev-early.rules +++ b/etc/udev/suse/05-udev-early.rules @@ -1,8 +1,9 @@ -# 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" - # 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", SUBSYSTEM=="scsi", WAIT_FOR_SYSFS="ioerr_cnt" +ACTION=="add", SUBSYSTEM=="net", WAIT_FOR_SYSFS="address" + diff --git a/etc/udev/suse/50-udev-default.rules b/etc/udev/suse/50-udev-default.rules index 4f69c666ac..838d5b91a7 100644 --- a/etc/udev/suse/50-udev-default.rules +++ b/etc/udev/suse/50-udev-default.rules @@ -103,7 +103,7 @@ KERNEL=="pktcdvd[0-9]*", NAME="pktcdvd/%k" # fix floppy devices KERNEL=="nvram", ACTION=="add", RUN+="load_floppy_module.sh" -KERNEL=="fd[0-9]*", ACTION=="add", SYSFS{device/cmos}=="*", RUN+="create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" +KERNEL=="fd[0-9]*", ACTION=="add", SYSFS{cmos}=="*", RUN+="create_floppy_devices -c -t $sysfs{cmos} -m %M /dev/%k" KERNEL=="fd[0-9]*", ACTION=="remove", RUN+="/bin/rm -f $root/%k*" # block devices @@ -112,12 +112,12 @@ SUBSYSTEM=="block", GROUP="disk", MODE="0640" # sd: 0 TYPE_DISK, 7 TYPE_MOD, 14 TYPE_RBC # sr: 4 TYPE_WORM, 5 TYPE_ROM # st/osst: 1 TYPE_TAPE -ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="0|7|14", RUN+="/bin/sh -c 'echo 60 > /sys/$DEVPATH/timeout'" -ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="1", RUN+="/bin/sh -c 'echo 900 > /sys/$DEVPATH/timeout'" -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" +ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="0|7|14", RUN+="/bin/sh -c 'echo 60 > /sys$$DEVPATH/timeout'" +ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="1", RUN+="/bin/sh -c 'echo 900 > /sys$$DEVPATH/timeout'" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{type}=="0|7|14", RUN+="/sbin/modprobe sd_mod" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{type}=="1", SYSFS{vendor}=="On[sS]tream", RUN+="/sbin/modprobe osst" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{type}=="1", RUN+="/sbin/modprobe st" +SUBSYSTEM=="scsi_device", ACTION=="add", SYSFS{type}=="[45]", RUN+="/sbin/modprobe sr_mod" SUBSYSTEM=="scsi_device", ACTION=="add", RUN+="/sbin/modprobe sg" # device mapper From 4942c78cb01ef4100a3cbce577fc3262b82d9be4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 27 Jan 2006 21:36:29 +0100 Subject: [PATCH 1706/4284] switch CROSS to CROSS_COMPILE This matches what the kernel uses and was a suggestion from: KRONSTORFER Horst Signed-off-by: Kay Sievers --- Makefile | 14 +++++++------- RELEASE-NOTES | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index 9da2964ddf..db8ecdacc6 100644 --- a/Makefile +++ b/Makefile @@ -109,13 +109,13 @@ INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} PWD = $(shell pwd) -CROSS = -CC = $(CROSS)gcc -LD = $(CROSS)gcc -AR = $(CROSS)ar -RANLIB = $(CROSS)ranlib +CROSS_COMPILE = +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)gcc +AR = $(CROSS_COMPILE)ar +RANLIB = $(CROSS_COMPILE)ranlib HOSTCC = gcc -STRIP = $(CROSS)strip +STRIP = $(CROSS_COMPILE)strip STRIPCMD = $(STRIP) -s CFLAGS = -g -Wall -pipe -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 @@ -145,7 +145,7 @@ ifeq ($(strip $(USE_GCOV)),true) endif ifeq ($(strip $(USE_KLIBC)),true) - KLCC = /usr/bin/$(CROSS)klcc + KLCC = /usr/bin/$(CROSS_COMPILE)klcc CC = $(KLCC) LD = $(KLCC) V = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index cce8dc03ce..27545893c9 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,7 @@ +udev 084 +======== +CROSS changed to CROSS_COMPILE to match the kernel build. + udev 083 ======== Fix a bug where NAME="" would prevent RUN from beeing executed. From 1ef985452b0247ec32799b64ecabb85cb8ffe473 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 28 Jan 2006 04:44:51 +0100 Subject: [PATCH 1707/4284] replace fancy silent build program by simple kernel build like logic Signed-off-by: Kay Sievers --- Makefile | 102 ++++--- ccdv.c | 387 ------------------------- extras/ata_id/Makefile | 17 +- extras/cdrom_id/Makefile | 15 +- extras/dasd_id/Makefile | 15 +- extras/edd_id/Makefile | 15 +- extras/firmware/Makefile | 15 +- extras/floppy/Makefile | 15 +- extras/run_directory/Makefile | 15 +- extras/scsi_id/Makefile | 36 +-- extras/usb_id/Makefile | 15 +- extras/volume_id/Makefile | 19 +- extras/volume_id/libvolume_id/Makefile | 14 +- 13 files changed, 168 insertions(+), 512 deletions(-) delete mode 100644 ccdv.c diff --git a/Makefile b/Makefile index db8ecdacc6..f650233cee 100644 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ USE_STATIC = false EXTRAS = # make the build silent. -V = false +V = PROGRAMS = \ udev \ @@ -148,7 +148,6 @@ ifeq ($(strip $(USE_KLIBC)),true) KLCC = /usr/bin/$(CROSS_COMPILE)klcc CC = $(KLCC) LD = $(KLCC) - V = true endif ifeq ($(strip $(USE_SELINUX)),true) @@ -162,17 +161,17 @@ ifeq ($(strip $(USE_STATIC)),true) LDFLAGS += -static endif -ifeq ($(strip $(V)),false) - QUIET=@$(PWD)/ccdv - HOST_PROGS=ccdv +ifeq ($(strip $(V)),) + E = @echo + Q = @ else - QUIET= - HOST_PROGS= + E = @\# + Q = endif +export E Q all: $(PROGRAMS) $(MAN_PAGES) - @extras="$(EXTRAS)"; for target in $$extras; do \ - echo $$target; \ + $(Q) extras="$(EXTRAS)"; for target in $$extras; do \ $(MAKE) CC="$(CC)" \ CFLAGS="$(CFLAGS)" \ LD="$(LD)" \ @@ -180,7 +179,6 @@ all: $(PROGRAMS) $(MAN_PAGES) STRIPCMD="$(STRIPCMD)" \ LIB_OBJS="$(LIB_OBJS)" \ LIBUDEV="$(PWD)/$(LIBUDEV)" \ - QUIET="$(QUIET)" \ -C $$target $@ || exit 1; \ done; .PHONY: all @@ -190,49 +188,54 @@ all: $(PROGRAMS) $(MAN_PAGES) .SUFFIXES: # build the objects -%.o: %.c $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ +%.o: %.c $(HEADERS) $(GEN_HEADERS) + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ # "Static Pattern Rule" to build all programs -$(PROGRAMS): %: $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(LIBUDEV) %.o - $(QUIET) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIB_OBJS) +$(PROGRAMS): %: $(HEADERS) $(GEN_HEADERS) $(LIBUDEV) %.o + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(STRIPCMD),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif -$(LIBUDEV): $(HOST_PROGS) $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS) - @rm -f $@ - $(QUIET) $(AR) cq $@ $(UDEV_OBJS) - $(QUIET) $(RANLIB) $@ +$(LIBUDEV): $(HEADERS) $(GEN_HEADERS) $(UDEV_OBJS) + $(Q) rm -f $@ + $(E) " AR " $@ + $(Q) $(AR) cq $@ $(UDEV_OBJS) + $(E) " RANLIB " $@ + $(Q) $(RANLIB) $@ udev_version.h: - @echo "/* Generated by make. */" > $@ - @echo \#define UDEV_VERSION \"$(VERSION)\" >> $@ - @echo \#define UDEV_ROOT \"$(udevdir)\" >> $@ - @echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ - @echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ + $(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_FILE \"$(configdir)/rules.d\" >> $@ # man pages %.8 %.7: docs/%.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 -ccdv: ccdv.c - @$(HOSTCC) -O1 ccdv.c -o ccdv -.SILENT: ccdv - clean: - - rm -f $(HOST_PROGS) - - find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print0 | xargs -0rt rm -f - - find -name "*.gcno" -print0 | xargs -0rt rm -f - - find -name "*.gcda" -print0 | xargs -0rt rm -f - - find -name "*.gcov" -print0 | xargs -0rt rm -f - - rm -f udev_gcov.txt - - rm -f core $(PROGRAMS) $(GEN_HEADERS) - - rm -f udev-$(VERSION).tar.gz - - rm -f udev-$(VERSION).tar.bz2 - @extras="$(EXTRAS)"; for target in $$extras; do \ - echo $$target; \ + $(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 + @ extras="$(EXTRAS)"; for target in $$extras; do \ $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: clean @@ -244,16 +247,15 @@ release: install-config: $(INSTALL) -d $(DESTDIR)$(configdir)/rules.d - @if [ ! -r $(DESTDIR)$(configdir)/udev.conf ]; then \ + @ 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 \ + @ 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 \ - echo $$target; \ + @ extras="$(EXTRAS)"; for target in $$extras; do \ $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: install-config @@ -266,7 +268,6 @@ install-man: $(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 \ - echo $$target; \ $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: install-man @@ -278,8 +279,7 @@ uninstall-man: - rm -f $(DESTDIR)$(mandir)/man8/udevd.8 - rm -f $(DESTDIR)$(mandir)/man8/udevmonitor.8 - rm -f $(DESTDIR)$(mandir)/man8/udevcontrol.8 - @extras="$(EXTRAS)"; for target in $$extras; do \ - echo $$target; \ + @ extras="$(EXTRAS)"; for target in $$extras; do \ $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: uninstall-man @@ -292,7 +292,6 @@ install-bin: $(INSTALL_PROGRAM) -D udevinfo $(DESTDIR)$(usrbindir)/udevinfo $(INSTALL_PROGRAM) -D udevtest $(DESTDIR)$(usrbindir)/udevtest @extras="$(EXTRAS)"; for target in $$extras; do \ - echo $$target; \ $(MAKE) -C $$target $@ || exit 1; \ done; ifndef DESTDIR @@ -313,7 +312,6 @@ ifndef DESTDIR - rm -rf /dev/.udev endif @extras="$(EXTRAS)"; for target in $$extras; do \ - echo $$target; \ $(MAKE) -C $$target $@ || exit 1; \ done; .PHONY: uninstall-bin @@ -346,9 +344,9 @@ ChangeLog: Makefile gcov-all: $(MAKE) clean all STRIPCMD= USE_GCOV=true - @echo - @echo "binaries built with gcov support." - @echo "run the tests and analyze with 'make udev_gcov.txt'" + @ 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 diff --git a/ccdv.c b/ccdv.c deleted file mode 100644 index e3ae9da91a..0000000000 --- a/ccdv.c +++ /dev/null @@ -1,387 +0,0 @@ -/* ccdv.c - * - * Copyright (C) 2002-2003, by Mike Gleason, NcFTP Software. - * All Rights Reserved. - * - * Licensed under the GNU Public License. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SETCOLOR_SUCCESS (gANSIEscapes ? "\033\1331;32m" : "") -#define SETCOLOR_FAILURE (gANSIEscapes ? "\033\1331;31m" : "") -#define SETCOLOR_WARNING (gANSIEscapes ? "\033\1331;33m" : "") -#define SETCOLOR_NORMAL (gANSIEscapes ? "\033\1330;39m" : "") - -#define TEXT_BLOCK_SIZE 8192 -#define INDENT 2 - -#define TERMS "vt100:vt102:vt220:vt320:xterm:xterm-color:ansi:linux:scoterm:scoansi:dtterm:cons25:cygwin" - -size_t gNBufUsed = 0, gNBufAllocated = 0; -char *gBuf = NULL; -int gCCPID; -char gAction[200] = ""; -char gTarget[200] = ""; -char gAr[32] = ""; -char gArLibraryTarget[64] = ""; -int gDumpCmdArgs = 0; -char gArgsStr[1000]; -int gColumns = 80; -int gANSIEscapes = 0; -int gExitStatus = 95; - -static void DumpFormattedOutput(void) -{ - char *cp; - char spaces[8 + 1] = " "; - char *saved; - int curcol; - int i; - - curcol = 0; - saved = NULL; - for (cp = gBuf + ((gDumpCmdArgs == 0) ? strlen(gArgsStr) : 0); ; cp++) { - if (*cp == '\0') { - if (saved != NULL) { - cp = saved; - saved = NULL; - } else break; - } - if (*cp == '\r') - continue; - if (*cp == '\t') { - saved = cp + 1; - cp = spaces + 8 - (8 - ((curcol - INDENT - 1) % 8)); - } - if (curcol == 0) { - for (i = INDENT; --i >= 0; ) - putchar(' '); - curcol = INDENT; - } - putchar(*cp); - if (++curcol == (gColumns - 1)) { - putchar('\n'); - curcol = 0; - } else if (*cp == '\n') - curcol = 0; - } - free(gBuf); -} /* DumpFormattedOutput */ - - - -/* Difftime(), only for timeval structures. */ -static void TimeValSubtract(struct timeval *tdiff, struct timeval *t1, struct timeval *t0) -{ - tdiff->tv_sec = t1->tv_sec - t0->tv_sec; - tdiff->tv_usec = t1->tv_usec - t0->tv_usec; - if (tdiff->tv_usec < 0) { - tdiff->tv_sec--; - tdiff->tv_usec += 1000000; - } -} /* TimeValSubtract */ - - - -static void Wait(void) -{ - int pid2, status; - - do { - status = 0; - pid2 = (int) waitpid(gCCPID, &status, 0); - } while (((pid2 >= 0) && (! WIFEXITED(status))) || ((pid2 < 0) && (errno == EINTR))); - if (WIFEXITED(status)) - gExitStatus = WEXITSTATUS(status); -} /* Wait */ - - - -static int SlurpProgress(int fd) -{ - char s1[71]; - char *newbuf; - int nready; - size_t ntoread; - ssize_t nread; - struct timeval now, tnext, tleft; - fd_set ss; - fd_set ss2; - const char *trail = "/-\\|", *trailcp; - - trailcp = trail; - snprintf(s1, sizeof(s1), "%s%s%s... ", gAction, gTarget[0] ? " " : "", gTarget); - printf("\r%-70s%-9s", s1, ""); - fflush(stdout); - - gettimeofday(&now, NULL); - tnext = now; - tnext.tv_sec++; - tleft.tv_sec = 1; - tleft.tv_usec = 0; - FD_ZERO(&ss2); - FD_SET(fd, &ss2); - for(;;) { - if (gNBufUsed == (gNBufAllocated - 1)) { - if ((newbuf = (char *) realloc(gBuf, gNBufAllocated + TEXT_BLOCK_SIZE)) == NULL) { - perror("ccdv: realloc"); - return (-1); - } - gNBufAllocated += TEXT_BLOCK_SIZE; - gBuf = newbuf; - } - for (;;) { - ss = ss2; - nready = select(fd + 1, &ss, NULL, NULL, &tleft); - if (nready == 1) - break; - if (nready < 0) { - if (errno != EINTR) { - perror("ccdv: select"); - return (-1); - } - continue; - } - gettimeofday(&now, NULL); - if ((now.tv_sec > tnext.tv_sec) || ((now.tv_sec == tnext.tv_sec) && (now.tv_usec >= tnext.tv_usec))) { - tnext = now; - tnext.tv_sec++; - tleft.tv_sec = 1; - tleft.tv_usec = 0; - printf("\r%-71s%c%-7s", s1, *trailcp, ""); - fflush(stdout); - if (*++trailcp == '\0') - trailcp = trail; - } else { - TimeValSubtract(&tleft, &tnext, &now); - } - } - ntoread = (gNBufAllocated - gNBufUsed - 1); - nread = read(fd, gBuf + gNBufUsed, ntoread); - if (nread < 0) { - if (errno == EINTR) - continue; - perror("ccdv: read"); - return (-1); - } else if (nread == 0) { - break; - } - gNBufUsed += nread; - gBuf[gNBufUsed] = '\0'; - } - snprintf(s1, sizeof(s1), "%s%s%s: ", gAction, gTarget[0] ? " " : "", gTarget); - Wait(); - if (gExitStatus == 0) { - printf("\r%-70s", s1); - printf("[%s%s%s]", ((gNBufUsed - strlen(gArgsStr)) < 4) ? SETCOLOR_SUCCESS : SETCOLOR_WARNING, "OK", SETCOLOR_NORMAL); - printf("%-5s\n", " "); - } else { - printf("\r%-70s", s1); - printf("[%s%s%s]", SETCOLOR_FAILURE, "ERROR", SETCOLOR_NORMAL); - printf("%-2s\n", " "); - gDumpCmdArgs = 1; /* print cmd when there are errors */ - } - fflush(stdout); - return (0); -} /* SlurpProgress */ - - - -static int SlurpAll(int fd) -{ - char *newbuf; - size_t ntoread; - ssize_t nread; - - printf("%s%s%s.\n", gAction, gTarget[0] ? " " : "", gTarget); - fflush(stdout); - - for(;;) { - if (gNBufUsed == (gNBufAllocated - 1)) { - if ((newbuf = (char *) realloc(gBuf, gNBufAllocated + TEXT_BLOCK_SIZE)) == NULL) { - perror("ccdv: realloc"); - return (-1); - } - gNBufAllocated += TEXT_BLOCK_SIZE; - gBuf = newbuf; - } - ntoread = (gNBufAllocated - gNBufUsed - 1); - nread = read(fd, gBuf + gNBufUsed, ntoread); - if (nread < 0) { - if (errno == EINTR) - continue; - perror("ccdv: read"); - return (-1); - } else if (nread == 0) { - break; - } - gNBufUsed += nread; - gBuf[gNBufUsed] = '\0'; - } - Wait(); - gDumpCmdArgs = (gExitStatus != 0); /* print cmd when there are errors */ - return (0); -} /* SlurpAll */ - - - -static const char *Basename(const char *path) -{ - const char *cp; - cp = strrchr(path, '/'); - if (cp == NULL) - return (path); - return (cp + 1); -} /* Basename */ - - - -static const char * Extension(const char *path) -{ - const char *cp = path; - cp = strrchr(path, '.'); - if (cp == NULL) - return (""); - // printf("Extension='%s'\n", cp); - return (cp); -} /* Extension */ - - - -static void Usage(void) -{ - fprintf(stderr, "Usage: ccdv /path/to/cc CFLAGS...\n\n"); - fprintf(stderr, "I wrote this to reduce the deluge Make output to make finding actual problems\n"); - fprintf(stderr, "easier. It is intended to be invoked from Makefiles, like this. Instead of:\n\n"); - fprintf(stderr, "\t.c.o:\n"); - fprintf(stderr, "\t\t$(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n"); - fprintf(stderr, "\nRewrite your rule so it looks like:\n\n"); - fprintf(stderr, "\t.c.o:\n"); - fprintf(stderr, "\t\t@ccdv $(CC) $(CFLAGS) $(DEFS) $(CPPFLAGS) $< -c\n\n"); - fprintf(stderr, "ccdv 1.1.0 is Free under the GNU Public License. Enjoy!\n"); - fprintf(stderr, " -- Mike Gleason, NcFTP Software \n"); - exit(96); -} /* Usage */ - - - -int main(int argc, char **argv) -{ - int pipe1[2]; - int devnull; - char emerg[256]; - int fd; - int nread; - int i; - int cc = 0, pch = 0; - const char *quote; - - if (argc < 2) - Usage(); - - snprintf(gAction, sizeof(gAction), "Running %s", Basename(argv[1])); - memset(gArgsStr, 0, sizeof(gArgsStr)); - for (i = 1; i < argc; i++) { - // printf("argv[%d]='%s'\n", i, argv[i]); - quote = (strchr(argv[i], ' ') != NULL) ? "\"" : ""; - snprintf(gArgsStr + strlen(gArgsStr), sizeof(gArgsStr) - strlen(gArgsStr), "%s%s%s%s%s", (i == 1) ? "" : " ", quote, argv[i], quote, (i == (argc - 1)) ? "\n" : ""); - if ((strcmp(argv[i], "-o") == 0) && ((i + 1) < argc)) { - if (strcasecmp(Extension(argv[i + 1]), ".o") != 0) { - strcpy(gAction, "Linking"); - snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i + 1])); - } - } else if (strchr("-+", (int) argv[i][0]) != NULL) { - continue; - } else if (strncasecmp(Extension(argv[i]), ".c", 2) == 0) { - cc++; - snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); - // printf("gTarget='%s'\n", gTarget); - } else if ((strncasecmp(Extension(argv[i]), ".h", 2) == 0) && (cc == 0)) { - pch++; - snprintf(gTarget, sizeof(gTarget), "%s", Basename(argv[i])); - } else if ((i == 1) && (strcmp(Basename(argv[i]), "ar") == 0)) { - snprintf(gAr, sizeof(gAr), "%s", Basename(argv[i])); - } else if ((gArLibraryTarget[0] == '\0') && (strcasecmp(Extension(argv[i]), ".a") == 0)) { - snprintf(gArLibraryTarget, sizeof(gArLibraryTarget), "%s", Basename(argv[i])); - } - } - if ((gAr[0] != '\0') && (gArLibraryTarget[0] != '\0')) { - strcpy(gAction, "Creating library"); - snprintf(gTarget, sizeof(gTarget), "%s", gArLibraryTarget); - } else if (pch > 0) { - strcpy(gAction, "Precompiling"); - } else if (cc > 0) { - strcpy(gAction, "Compiling"); - } - - if (pipe(pipe1) < 0) { - perror("ccdv: pipe"); - exit(97); - } - - (void) close(0); - devnull = open("/dev/null", O_RDWR, 00666); - if ((devnull != 0) && (dup2(devnull, 0) == 0)) - close(devnull); - - gCCPID = (int) fork(); - if (gCCPID < 0) { - (void) close(pipe1[0]); - (void) close(pipe1[1]); - perror("ccdv: fork"); - exit(98); - } else if (gCCPID == 0) { - /* Child */ - (void) close(pipe1[0]); /* close read end */ - if (pipe1[1] != 1) { /* use write end on stdout */ - (void) dup2(pipe1[1], 1); - (void) close(pipe1[1]); - } - (void) dup2(1, 2); /* use write end on stderr */ - execvp(argv[1], argv + 1); - perror(argv[1]); - exit(99); - } - - /* parent */ - (void) close(pipe1[1]); /* close write end */ - fd = pipe1[0]; /* use read end */ - - gColumns = (getenv("COLUMNS") != NULL) ? atoi(getenv("COLUMNS")) : 80; - gANSIEscapes = (getenv("TERM") != NULL) && (strstr(TERMS, getenv("TERM")) != NULL); - gBuf = (char *) malloc(TEXT_BLOCK_SIZE); - if (gBuf == NULL) - goto panic; - gNBufUsed = 0; - gNBufAllocated = TEXT_BLOCK_SIZE; - if (strlen(gArgsStr) < (gNBufAllocated - 1)) { - strcpy(gBuf, gArgsStr); - gNBufUsed = strlen(gArgsStr); - } - - if (isatty(1)) { - if (SlurpProgress(fd) < 0) - goto panic; - } else { - if (SlurpAll(fd) < 0) - goto panic; - } - DumpFormattedOutput(); - exit(gExitStatus); - -panic: - gDumpCmdArgs = 1; /* print cmd when there are errors */ - DumpFormattedOutput(); - while ((nread = read(fd, emerg, (size_t) sizeof(emerg))) > 0) - (void) write(2, emerg, (size_t) nread); - Wait(); - exit(gExitStatus); -} /* main */ diff --git a/extras/ata_id/Makefile b/extras/ata_id/Makefile index 0a881fb194..9049a35787 100644 --- a/extras/ata_id/Makefile +++ b/extras/ata_id/Makefile @@ -30,21 +30,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) -ifneq ($(STRIPCMD),) - $(QUIET) $(STRIPCMD) $@ + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) +ifneq ($(strip $(STRIPCMD)),) + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/cdrom_id/Makefile b/extras/cdrom_id/Makefile index 9a722d52f9..59c2532d41 100644 --- a/extras/cdrom_id/Makefile +++ b/extras/cdrom_id/Makefile @@ -30,21 +30,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/dasd_id/Makefile b/extras/dasd_id/Makefile index 79f14a49ba..6831a9d507 100644 --- a/extras/dasd_id/Makefile +++ b/extras/dasd_id/Makefile @@ -30,21 +30,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/edd_id/Makefile b/extras/edd_id/Makefile index db6afae18c..8afd8cc2fd 100644 --- a/extras/edd_id/Makefile +++ b/extras/edd_id/Makefile @@ -30,21 +30,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/firmware/Makefile b/extras/firmware/Makefile index da7fe9d1a8..d6b13b20db 100644 --- a/extras/firmware/Makefile +++ b/extras/firmware/Makefile @@ -30,21 +30,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/floppy/Makefile b/extras/floppy/Makefile index e23191a533..7b46a5f00c 100644 --- a/extras/floppy/Makefile +++ b/extras/floppy/Makefile @@ -30,21 +30,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/run_directory/Makefile b/extras/run_directory/Makefile index 37a59597b9..0b52326a9a 100644 --- a/extras/run_directory/Makefile +++ b/extras/run_directory/Makefile @@ -29,21 +29,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/scsi_id/Makefile b/extras/scsi_id/Makefile index 057594d5bf..b185998b19 100644 --- a/extras/scsi_id/Makefile +++ b/extras/scsi_id/Makefile @@ -28,41 +28,37 @@ INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 INSTALL_SCRIPT = ${INSTALL_PROGRAM} -# be able to run without udev -CROSS = -QUIET = -CC = $(CROSS)gcc -LD = $(CROSS)gcc -AR = $(CROSS)ar -STRIPCMD = $(CROSS)strip -CFLAGS += -Wall -pipe -fno-builtin -Wstrict-prototypes -Wsign-compare -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -LDFLAGS += -Wl - all: $(PROG) $(MAN_PAGES) .PHONY: all .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) -ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) +ifneq ($(STRIPCMD),) + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif scsi_id_version.h: - @echo "/* This file is auto-generated by the Makefile */" > $@ - @echo \#define SCSI_ID_VERSION \"$(SCSI_ID_VERSION)\" >> $@ - @echo \#define SCSI_ID_CONFIG_FILE \"$(etcdir)/scsi_id.config\" >> $@ + $(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 - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all @@ -82,7 +78,7 @@ uninstall-man: .PHONY: uninstall-man install-config: - @if [ ! -r $(DESTDIR)$(etcdir)/scsi_id.config ]; then \ + @ 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 diff --git a/extras/usb_id/Makefile b/extras/usb_id/Makefile index 91b4d57d76..b3c417276a 100644 --- a/extras/usb_id/Makefile +++ b/extras/usb_id/Makefile @@ -30,21 +30,26 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(PROG): %: $(HEADERS) %.o $(OBJS) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(OBJS) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) .PHONY: clean install-bin: all diff --git a/extras/volume_id/Makefile b/extras/volume_id/Makefile index edb5d3ac68..b72d5b11d9 100644 --- a/extras/volume_id/Makefile +++ b/extras/volume_id/Makefile @@ -29,25 +29,30 @@ all: $(PROG) $(MAN_PAGES) .DEFAULT: all %.o: %.c $(GEN_HEADERS) - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(LIBVOLUME_ID): - $(MAKE) -C libvolume_id + $(Q) $(MAKE) -C libvolume_id $(PROG): %: $(HEADERS) %.o $(LIBVOLUME_ID) - $(QUIET) $(LD) $(LDFLAGS) $@.o $(LIBVOLUME_ID) -o $@ $(LIBUDEV) $(LIB_OBJS) + $(E) " LD " $@ + $(Q) $(LD) $(LDFLAGS) $@.o $(LIBVOLUME_ID) -o $@ $(LIBUDEV) $(LIB_OBJS) ifneq ($(strip $(STRIPCMD)),) - $(QUIET) $(STRIPCMD) $@ + $(E) " STRIP " $@ + $(Q) $(STRIPCMD) $@ endif # man pages %.8: %.xml - xmlto man $? + $(E) " XMLTO " $@ + $(Q) xmlto man $? .PRECIOUS: %.8 clean: - rm -f $(PROG) $(OBJS) $(GEN_HEADERS) - $(MAKE) -C libvolume_id clean + $(E) " CLEAN " + $(Q) rm -f $(PROG) $(OBJS) $(GEN_HEADERS) + $(Q) $(MAKE) -C libvolume_id clean .PHONY: clean install-bin: all diff --git a/extras/volume_id/libvolume_id/Makefile b/extras/volume_id/libvolume_id/Makefile index 02c24eae05..07f6662f25 100644 --- a/extras/volume_id/libvolume_id/Makefile +++ b/extras/volume_id/libvolume_id/Makefile @@ -53,14 +53,18 @@ all: $(LIBVOLUME_ID) .DEFAULT: all %.o: %.c - $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + $(E) " CC " $@ + $(Q) $(CC) -c $(CFLAGS) $< -o $@ $(LIBVOLUME_ID): $(HEADERS) $(OBJS) - @rm -f $@ - $(QUIET) $(AR) cq $@ $(OBJS) - $(QUIET) $(RANLIB) $@ + $(Q) rm -f $@ + $(E) " AR " $@ + $(Q) $(AR) cq $@ $(OBJS) + $(E) " RANLIB " $@ + $(Q) $(RANLIB) $@ clean: - rm -f $(LIBVOLUME_ID) $(OBJS) + $(E) " CLEAN " + $(Q) rm -f $(LIBVOLUME_ID) $(OBJS) .PHONY: clean From 9de98988130c5565e6d75f444f591141ad33e95e Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 28 Jan 2006 04:56:24 +0100 Subject: [PATCH 1708/4284] move manpages to top level Signed-off-by: Kay Sievers --- Makefile | 2 +- docs/udev.xml => udev.xml | 0 docs/udevd.xml => udevd.xml | 0 docs/udevinfo.xml => udevinfo.xml | 0 docs/udevmonitor.xml => udevmonitor.xml | 0 docs/udevsend.xml => udevsend.xml | 0 docs/udevstart.xml => udevstart.xml | 0 docs/udevtest.xml => udevtest.xml | 0 8 files changed, 1 insertion(+), 1 deletion(-) rename docs/udev.xml => udev.xml (100%) rename docs/udevd.xml => udevd.xml (100%) rename docs/udevinfo.xml => udevinfo.xml (100%) rename docs/udevmonitor.xml => udevmonitor.xml (100%) rename docs/udevsend.xml => udevsend.xml (100%) rename docs/udevstart.xml => udevstart.xml (100%) rename docs/udevtest.xml => udevtest.xml (100%) diff --git a/Makefile b/Makefile index f650233cee..460ccf9ee7 100644 --- a/Makefile +++ b/Makefile @@ -217,7 +217,7 @@ udev_version.h: $(Q) echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ # man pages -%.8 %.7: docs/%.xml +%.8 %.7: %.xml $(E) " XMLTO " $@ $(Q) xmlto man $? .PRECIOUS: %.8 diff --git a/docs/udev.xml b/udev.xml similarity index 100% rename from docs/udev.xml rename to udev.xml diff --git a/docs/udevd.xml b/udevd.xml similarity index 100% rename from docs/udevd.xml rename to udevd.xml diff --git a/docs/udevinfo.xml b/udevinfo.xml similarity index 100% rename from docs/udevinfo.xml rename to udevinfo.xml diff --git a/docs/udevmonitor.xml b/udevmonitor.xml similarity index 100% rename from docs/udevmonitor.xml rename to udevmonitor.xml diff --git a/docs/udevsend.xml b/udevsend.xml similarity index 100% rename from docs/udevsend.xml rename to udevsend.xml diff --git a/docs/udevstart.xml b/udevstart.xml similarity index 100% rename from docs/udevstart.xml rename to udevstart.xml diff --git a/docs/udevtest.xml b/udevtest.xml similarity index 100% rename from docs/udevtest.xml rename to udevtest.xml From 4179809b22af94a2c8c3937a9baa45870910ea0d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 28 Jan 2006 05:04:38 +0100 Subject: [PATCH 1709/4284] remove UDEVD_UEVENT_INITSEND Signed-off-by: Kay Sievers --- udevd.c | 2 -- udevd.h | 1 - 2 files changed, 3 deletions(-) diff --git a/udevd.c b/udevd.c index c94fdc74d8..3f4605ed11 100644 --- a/udevd.c +++ b/udevd.c @@ -527,7 +527,6 @@ static struct uevent_msg *get_msg_from_envbuf(const char *buf, int buf_size) free(msg); return NULL; } - return msg; } @@ -581,7 +580,6 @@ static struct uevent_msg *get_udevd_msg(void) switch (usend_msg.type) { case UDEVD_UEVENT_UDEVSEND: - case UDEVD_UEVENT_INITSEND: info("udevd event message received"); envbuf_size = size - offsetof(struct udevd_msg, envbuf); dbg("envbuf_size=%i", envbuf_size); diff --git a/udevd.h b/udevd.h index 242c0b6907..9ab6a445b9 100644 --- a/udevd.h +++ b/udevd.h @@ -44,7 +44,6 @@ enum udevd_msg_type { UDEVD_UNKNOWN, UDEVD_UEVENT_UDEVSEND, - UDEVD_UEVENT_INITSEND, UDEVD_UEVENT_NETLINK, UDEVD_STOP_EXEC_QUEUE, UDEVD_START_EXEC_QUEUE, From c1979c82e18c5ee0993479043f44f5dcc76d8d2d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 28 Jan 2006 16:39:46 +0100 Subject: [PATCH 1710/4284] whitespace fixes Signed-off-by: Kay Sievers --- Makefile | 8 ++++---- extras/eventrecorder.sh | 2 +- logging.h | 4 ++-- udev.xml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 460ccf9ee7..1234160d63 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Makefile for udev # # Copyright (C) 2003,2004 Greg Kroah-Hartman -# Copyright (C) 2004-2005 Kay Sievers +# 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 @@ -43,7 +43,7 @@ USE_STATIC = false # make EXTRAS="extras/ extras/" EXTRAS = -# make the build silent. +# make the build silent V = PROGRAMS = \ @@ -213,8 +213,8 @@ udev_version.h: $(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_FILE \"$(configdir)/rules.d\" >> $@ + $(Q) echo \#define UDEV_CONFIG_FILE \"$(configdir)/udev.conf\" >> $@ + $(Q) echo \#define UDEV_RULES_FILE \"$(configdir)/rules.d\" >> $@ # man pages %.8 %.7: %.xml diff --git a/extras/eventrecorder.sh b/extras/eventrecorder.sh index 95ec95a24e..d3e4a70c95 100755 --- a/extras/eventrecorder.sh +++ b/extras/eventrecorder.sh @@ -1,4 +1,4 @@ #!/bin/sh [ -d /events ] || exit 0 -set > /events/debug.$SEQNUM.$1.$ACTION.$$ +set > /events/debug.$SEQNUM.$SUBSYSTEM.$ACTION.$$ diff --git a/logging.h b/logging.h index dd520dd874..00b5f23b25 100644 --- a/logging.h +++ b/logging.h @@ -38,13 +38,13 @@ #undef err #define err(format, arg...) \ do { \ - log_message(LOG_ERR ,"%s: " format ,__FUNCTION__ ,## arg); \ + 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); \ + log_message(LOG_INFO ,"%s: " format ,__FUNCTION__ ,## arg); \ } while (0) #ifdef DEBUG diff --git a/udev.xml b/udev.xml index e0542a6be1..bf5676bee6 100644 --- a/udev.xml +++ b/udev.xml @@ -11,7 +11,7 @@ kay.sievers@vrfy.org - 2005 + 2006 Kay Sievers From 3d94fb8742847afe8396f6dd38b16ff4e836611d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 28 Jan 2006 16:42:49 +0100 Subject: [PATCH 1711/4284] scsi_id: remove dead files Signed-off-by: Kay Sievers --- extras/scsi_id/ChangeLog | 208 ----------------------------------- extras/scsi_id/README | 14 +-- extras/scsi_id/TODO | 8 -- extras/scsi_id/release-notes | 23 ---- extras/scsi_id/scsi.h | 17 +-- extras/scsi_id/scsi_id.c | 19 +--- extras/scsi_id/scsi_id.h | 17 +-- extras/scsi_id/scsi_serial.c | 18 +-- 8 files changed, 19 insertions(+), 305 deletions(-) delete mode 100644 extras/scsi_id/ChangeLog delete mode 100644 extras/scsi_id/TODO delete mode 100644 extras/scsi_id/release-notes diff --git a/extras/scsi_id/ChangeLog b/extras/scsi_id/ChangeLog deleted file mode 100644 index d2a8be5b18..0000000000 --- a/extras/scsi_id/ChangeLog +++ /dev/null @@ -1,208 +0,0 @@ -2004-oct-15: - * Makefile: Add $(QUIET) to sync with the udev version. - -2004-oct-06: - * scsi_id.c: fix alignment for use with 64 bit pointers - -2004-jul-30: - * scsi_id.c, scsi_serial.c: Align the buffer passed to scsi_serial, - don't bother aligning and memcpy-ing the result in scsi_inquiry. - Aligning to 512 probably does not help, since the IO length of - 254 is not a multiple of 512. - -2004-jul-30: - * scsi.h, scsi_serial.c: Use a define for the SCSI INQUIRY buffer - length. - -2004-jul-30: - * scsi_id.c: Patch from add a -u flag - to substitute white space with underscores so it is easier to use - the output as a device name. - -2004-jul-30: - * scsi_serial.c: Patch from Hannes Reinecke use 254 - bytes for SCSI INQUIRY commands. - -2004-jul-28: - * scsi_id.h, scsi_serial.c: get rid of dumb/dead code, and use a - 512 byte aligned buffer. - -2004-jun-23: - * scsi_id.h: increase MAX_SERIAL_LEN from 128 to 256, as some - devices (maybe broken ones) are giving really long id's. - -2004-jun-17: - * Makefile: Olaf Hering add spotless target (already in udev). - -2004-jun-17: - * scsi_serial.c: Include linux/compiler.h so we can build with - klibc using kernel headers. - -2004-may-24: - * scsi_id.c: Rename major and minor to maj min to avoid compiler - warnings when compiled with -D_GNU_SOURCE. - -2004-mar-30: - * scsi_id.config: Minor wording changes - -2004-mar-30: - * scsi_id.h: Don't supply a makedev() when built under klibc. - -2004-mar-30: - * scsi_id.c: Ken Brush Have the command line - options override generic options. - -2004-mar-05: - * scsi_serial.c: Log INQUIRY failure, including the - failing page code and vpd values. And add a dprintf() to - the scsi_inquiry function. - -2004-mar-02: - * gen_scsi_id_udev_rules.sh: Per bug report from Atul Sabharwal - change to not require that sysfs be - in the mount tab (and default to "/sys"), and fix so scsi_id - results containing spaces work correctly. - -2004-mar-02: - * scsi_id.8: Escape '-' with '\-'. - -2004-feb-25: - * scsi_id.8: Add verbage about usage with udev, and running via - hotplug. - -2004-feb-25: - * scsi_id.c, scsi_id.8: Disable support for -e (all output to - stderr) as it cannot be used in any useful way, and the -c - (device specific callout) as the code is incomplete and has no - users. - -2004-feb-25: - * scsi_id.c: Don't print errno for NULL return from - sysfs_get_classdev_device. - -2004-feb-23: - * scsi_id.c: Get rid of dead/leftover code that checked - if we are on a scsi bus. - -2004-feb-23: - * scsi_serial.c, scsi_id.c: Use ":" consistently in output messages. - -2004-feb-23: - * scsi_serial.c: Add missing new lines for some error messages. - -2004-feb-23: - * scsi_serial.c: open O_NONBLOCK so we handle tape drives without - tapes loaded. - -2004-feb-20: - * scsi_id.h, scsi_id.c: Remove hacks based on KLIBC define to get - around problems when building with udev (udev libsysfs files - were rearranged). - -2004-feb-19: - * scsi_id.h, scsi_id.c, scsi_serial.c: As done in udev code, support - partitions via looking for a parent of the target path. Uses - libsysfs functions to do most of the work, and includes changing - a lot of variables to be struct sysfs_device instead of - sysfs_class_device. - -2004-feb-19: - * Makefile: Version 0.4 - -2004-jan-15: - * Makefile: Version 0.3 - -2004-jan-13: - * scsi_id.c, Makefile: Fix prefix usage with scsi_id.config. - -2004-jan-13: - * scsi_id.config: Clean up some comment entries. - -2004-jan-13: - * Makefile: Install the sample scsi_id.config file. - -2004-jan-13: - * Makefile: Use DESTDIR in all install/uninstall rules, per - problem reported by Svetoslav Slavtchev. - -2004-jan-12: - * scsi_id.h, scsi_id.c, scsi_serial.c: Fix to work with current - sysfs 0.4, based on patch from Dan Stekloff, but uses - sysfs_read_attribute_value instead of - sysfs_get_value_from_attributes. - -2004-jan-08: - * scsi_id.c: SYSFS_BUS_DIR was replaced with SYSFS_BUS_NAME. - -2004-jan-08: - * scsi_id.c: Must now use sysfs_open_class_device_path instead of the - previous sysfs_open_class_device. - -2003-dec-07: - * Makefile: patch from Olaf Hering remove DEBUG and - add --fno-builtin - -2003-dec-05: - * Makefile, scsi_id.8: Add a man page. - -2003-dec-04: - * Makefile: Set and use variables that might be passed down when - built under udev (with or without klibc), don't set LDFLAGS or - STRIP. - -2003-dec-04: - * scsi_id.c, scsi_id.h: Fix a bad bug - when parsing file options, - no space was allocated for the creation of the new argv[] - strings. - -2003-dec-04: - * scsi_id.c: Catch too long a line in the config file. - -2003-dec-02: - * scsi_id.h: Add u8 typedef to avoid ummm scsi.h kernel header - problem when built with klibc. - -2003-dec-02: - * scsi_id.h: Add define of makedev() if built with klibc. - -2003-dec-02: - * scsi_id.c: reset optind to 1 since klibc does not work if it is - reset to zero. - -2003-dec-02: - * scsi_id.c: remove fflush() as it is not needed, and is not - supported by klibc. - -2003-dec-02: - * scsi_serial.c: Make the functions do_scsi_page0_inquiry and - do_scsi_page80_inquiry static. - -2003-dec-01: - * scsi_id.c: Don't use syslog LOG_PID, as it is not supported by - klibc. - -2003-dec-01: - * scsi_id.c, scsi_serial.c: Hack - change include path to libsysfs - if built under klibc. - -2003-dec-01: - * Makefile: Use "override" for CFLAGS so we can pass CFLAGS values - down when built with udev - -2003-dec-01: - * scsi_id.c, Makefile: Use SCSI_ID_VERSION instead of VERSION. - -2003-nov-25: - * scsi_id.c: Remove getopt_long (long option names), as there - is no support for that in klibc. - -2003-nov-17: - * scsi_id.c: Patch from Brian King : check - result of setting model, not vendor in per_dev_options. - -2003-nov-03: - * scsi_id.c, scsi_serial.c: Use new and correct path to libsysfs.h. - -2003-nov-03: - * scsi_id.h: Fix scsi_id.h so var args in macros works ok with - older gcc. diff --git a/extras/scsi_id/README b/extras/scsi_id/README index 97af517304..9cfe73991c 100644 --- a/extras/scsi_id/README +++ b/extras/scsi_id/README @@ -1,14 +1,4 @@ scsi_id - generate a SCSI unique identifier for a given SCSI device -Primarily for use with udev callout config entries. This could also be -used by a multi-path configuration tool that requires SCSI id's. - -Requires: - - - Linux kernel 2.6 - - - sysfsutils 0.4 - -Build via make and make install. - -Please send questions, comments or patches to patmans@us.ibm.com. +Please send questions, comments or patches to or +. diff --git a/extras/scsi_id/TODO b/extras/scsi_id/TODO deleted file mode 100644 index 857c22b87a..0000000000 --- a/extras/scsi_id/TODO +++ /dev/null @@ -1,8 +0,0 @@ -- Add a bus white/black list option. So for example, all scsi devices - under USB could easily be blacklisted. This should allow multiple busses - to be listed. - -- Add code to check that SCSI commands get back enough data for their - intended usage, mainly callers of scsi_inquiry(). - -- Document the config file in the man page diff --git a/extras/scsi_id/release-notes b/extras/scsi_id/release-notes deleted file mode 100644 index c7ea51679c..0000000000 --- a/extras/scsi_id/release-notes +++ /dev/null @@ -1,23 +0,0 @@ -Version 0.7 of scsi_id is available at: - -http://www-124.ibm.com/storageio/scsi_id/scsi_id-0.7.tar.gz - -scsi_id is a program to generate a unique identifier for a given SCSI -device. - -It is primarily for use with the udev program key, or hotplug scripts that -want persistent naming of scsi devices. It could also be used for -automatic multi-path configuration or device mapper configuration. - -Requires: - -- Linux kernel 2.6 -- libsysfs 0.4.0 - -Changes since the last release: - - - Fix a bug introduced in version 0.6 so that buffer alignement - works on 64 bit systems. Without this fix, it crashes on 64 bit - systems. - - - Add $(QUIET) to sync up with the udev Makefile diff --git a/extras/scsi_id/scsi.h b/extras/scsi_id/scsi.h index 212765a17d..f5aa686f71 100644 --- a/extras/scsi_id/scsi.h +++ b/extras/scsi_id/scsi.h @@ -5,20 +5,9 @@ * * Copyright (C) IBM Corp. 2003 * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * 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 diff --git a/extras/scsi_id/scsi_id.c b/extras/scsi_id/scsi_id.c index 6458f2b7ac..2ffc95fbfe 100644 --- a/extras/scsi_id/scsi_id.c +++ b/extras/scsi_id/scsi_id.c @@ -4,21 +4,14 @@ * Main section of the scsi_id program * * Copyright (C) IBM Corp. 2003 + * Copyright (C) SUSE Linux Products GmbH, 2006 * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. + * Author: + * Patrick Mansfield * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * 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 diff --git a/extras/scsi_id/scsi_id.h b/extras/scsi_id/scsi_id.h index 758706ba25..64ea349064 100644 --- a/extras/scsi_id/scsi_id.h +++ b/extras/scsi_id/scsi_id.h @@ -5,20 +5,9 @@ * * Copyright (C) IBM Corp. 2003 * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * 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 diff --git a/extras/scsi_id/scsi_serial.c b/extras/scsi_id/scsi_serial.c index bdebe94eb3..0ecfebe1b6 100644 --- a/extras/scsi_id/scsi_serial.c +++ b/extras/scsi_id/scsi_serial.c @@ -5,20 +5,12 @@ * * Copyright (C) IBM Corp. 2003 * - * This library is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of the - * License, or (at your option) any later version. + * Author: + * Patrick Mansfield * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA + * 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 From 34f55103c5d451d247fc3b57579a6b3c1de0d58d Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 29 Jan 2006 02:09:35 +0100 Subject: [PATCH 1712/4284] optimize sysfs device and attribute cache Add negative cache for attributes and look for device in cache before doing any sysfs access. (Three times speed up for a stupid 1000 rules SYSFS file). Signed-off-by: Kay Sievers --- udev.h | 1 + udev_sysfs.c | 76 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/udev.h b/udev.h index 0c7ca12f10..2652d46ada 100644 --- a/udev.h +++ b/udev.h @@ -54,6 +54,7 @@ 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" */ char kernel_name[NAME_SIZE]; /* device instance name */ diff --git a/udev_sysfs.c b/udev_sysfs.c index 8de523dadf..b579c17caa 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -40,7 +40,8 @@ static LIST_HEAD(attr_list); struct sysfs_attr { struct list_head node; char path[PATH_SIZE]; - char value[NAME_SIZE]; + char *value; /* points to value_local if value is cached */ + char value_local[NAME_SIZE]; }; int sysfs_init(void) @@ -126,14 +127,21 @@ struct sysfs_device *sysfs_device_get(const char *devpath) strlcpy(devpath_real, devpath, sizeof(devpath_real)); remove_trailing_chars(devpath_real, '/'); + /* 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 we got a link, resolve it to the real device */ if (S_ISLNK(statbuf.st_mode)) { int i; int back; @@ -156,17 +164,17 @@ struct sysfs_device *sysfs_device_get(const char *devpath) dbg("after moving back '%s'", devpath_real); strlcat(devpath_real, "/", sizeof(devpath_real)); strlcat(devpath_real, &link_target[back * 3], sizeof(devpath_real)); - } - /* look for device in 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; + /* 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; + } } } - /* new device */ + /* it is a new device */ dbg("'%s'", devpath_real); dev = malloc(sizeof(struct sysfs_device)); if (dev == NULL) @@ -245,6 +253,9 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) int len; int back; + if (dev->parent != NULL) + return dev->parent; + /* requesting a parent is only valid for devices */ if ((strncmp(dev->devpath, "/devices/", 9) != 0) && (strncmp(dev->devpath, "/class/", 7) != 0) && @@ -266,12 +277,11 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) return NULL; } - /* at the top level we may follow the "device" link */ + /* at the top level of class/block we want to follow the "device" link */ if (strcmp(parent_devpath, "/block") == 0) { dbg("/block top level, look for device link"); goto device_link; } - if (strncmp(parent_devpath, "/class", 6) == 0) { pos = strrchr(parent_devpath, '/'); if (pos == &parent_devpath[6] || pos == parent_devpath) { @@ -279,7 +289,8 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) goto device_link; } } - return sysfs_device_get(parent_devpath); + dev->parent = sysfs_device_get(parent_devpath); + return dev->parent; device_link: strlcpy(device_link, sysfs_path, sizeof(device_link)); @@ -304,7 +315,9 @@ device_link: dbg("after moving back '%s'", parent_devpath); strlcat(parent_devpath, "/", sizeof(parent_devpath)); strlcat(parent_devpath, &device_link_target[back * 3], sizeof(parent_devpath)); - return sysfs_device_get(parent_devpath); + + 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) @@ -345,27 +358,32 @@ char *sysfs_attr_get_value(const char *devpath, const char *attr_name) } } - /* read attribute value */ - fd = open(path_full, O_RDONLY); - if (fd < 0) - return NULL; - size = read(fd, value, sizeof(value)); - close(fd); - if (size < 0) - return NULL; - if (size == sizeof(value)) - return NULL; - value[size] = '\0'; - remove_trailing_chars(value, '\n'); - - /* store attribute in cache */ + /* store attribute in cache (also negatives are kept in cache) */ 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)); - strlcpy(attr->value, value, sizeof(attr->value)); dbg("add to cache '%s' '%s'", attr->path, attr->value); list_add(&attr->node, &attr_list); + /* read attribute value */ + fd = open(path_full, O_RDONLY); + if (fd < 0) + 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'); + strlcpy(attr->value_local, value, sizeof(attr->value_local)); + attr->value = attr->value_local; + +out: return attr->value; } From 9538b16d8b6086691dd01d76dea91ba73d13a630 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sun, 29 Jan 2006 17:08:44 +0100 Subject: [PATCH 1713/4284] let SYSFS{} look at the device, not only the parent device The stricter parent logic broke: BUS=="ide", SYSFS{removable}=="1", ... cause removable is on the block device, which isn't a ide device. Just look for matching attributes at the device and the selected parent device at the same time now. Signed-off-by: Kay Sievers --- udev_rules.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index f1bbfd854c..8e9c1605bf 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -348,14 +348,14 @@ static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->dev->devpath, file); filename[sizeof(filename)-1] = '\0'; - dbg("wait %i sec for '%s'", timeout, filename); + dbg("will wait %i sec for '%s'", timeout, filename); while (--loop) { if (stat(filename, &stats) == 0) { info("file '%s' appeared after %i loops", filename, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); return 0; } - info("wait for %i mseconds", 1000 / WAIT_LOOP_PER_SECOND); + info("wait for '%s' for %i mseconds", filename, 1000 / WAIT_LOOP_PER_SECOND); usleep(1000 * 1000 / WAIT_LOOP_PER_SECOND); } err("waiting for '%s' failed", filename); @@ -781,6 +781,8 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule) 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)); From 7e75cfa6fe0818ffb76c2a5a88c8572f04bda879 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 30 Jan 2006 08:39:55 +0100 Subject: [PATCH 1714/4284] add debug output to sysfs operations Signed-off-by: Kay Sievers --- udev_sysfs.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/udev_sysfs.c b/udev_sysfs.c index b579c17caa..ddc0b46790 100644 --- a/udev_sysfs.c +++ b/udev_sysfs.c @@ -175,7 +175,7 @@ struct sysfs_device *sysfs_device_get(const char *devpath) } /* it is a new device */ - dbg("'%s'", devpath_real); + dbg("new uncached device '%s'", devpath_real); dev = malloc(sizeof(struct sysfs_device)); if (dev == NULL) return NULL; @@ -253,6 +253,9 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) int len; int back; + dbg("open '%s'", dev->devpath); + + /* look if we already know the parent */ if (dev->parent != NULL) return dev->parent; @@ -271,7 +274,7 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) return NULL; pos[0] = '\0'; - /* are we at the top level */ + /* are we at the top level of /devices */ if (strcmp(parent_devpath, "/devices") == 0) { dbg("/devices top level"); return NULL; @@ -289,6 +292,7 @@ struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev) goto device_link; } } + /* get parent and remember it */ dev->parent = sysfs_device_get(parent_devpath); return dev->parent; @@ -316,6 +320,7 @@ device_link: strlcat(parent_devpath, "/", sizeof(parent_devpath)); strlcat(parent_devpath, &device_link_target[back * 3], sizeof(parent_devpath)); + /* get parent and remember it */ dev->parent = sysfs_device_get(parent_devpath); return dev->parent; } @@ -344,6 +349,7 @@ char *sysfs_attr_get_value(const char *devpath, const char *attr_name) 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)); @@ -359,18 +365,21 @@ char *sysfs_attr_get_value(const char *devpath, const char *attr_name) } /* 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' '%s'", attr->path, attr->value); + dbg("add to cache '%s'", path_full); list_add(&attr->node, &attr_list); /* read attribute value */ fd = open(path_full, O_RDONLY); - if (fd < 0) + if (fd < 0) { + dbg("attribute '%s' does not exist", path_full); goto out; + } size = read(fd, value, sizeof(value)); close(fd); if (size < 0) @@ -381,6 +390,7 @@ char *sysfs_attr_get_value(const char *devpath, const char *attr_name) /* got a valid value, store and return it */ value[size] = '\0'; remove_trailing_chars(value, '\n'); + dbg("cache '%s' with value '%s'", path_full, value); strlcpy(attr->value_local, value, sizeof(attr->value_local)); attr->value = attr->value_local; From 66c2bc212087d02faf77520b52ef6177d5c351fa Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 30 Jan 2006 08:51:38 +0100 Subject: [PATCH 1715/4284] 084 release --- ChangeLog | 16 ++++++++++++++++ Makefile | 2 +- RELEASE-NOTES | 8 +++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index a2137019cf..8f0e9b157b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 1234160d63..55cecd3755 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 083 +VERSION = 084 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 27545893c9..50831aceba 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,6 +1,12 @@ udev 084 ======== -CROSS changed to CROSS_COMPILE to match the kernel build. +If BUS== and SYSFS{}== have been used in the same rule, the sysfs +attributes are only checked at the parent device that matched the +by BUS requested subsystem. Fix t 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 ======== From f8db897faaaf3417ed0a31a39c7f47cc8cf40bd6 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 31 Jan 2006 16:24:22 +0100 Subject: [PATCH 1716/4284] make WAIT_FOR_SYSFS usable in non "wait-only" rules Thanks to Andrey Borzenkov for noticing this and the initial patch to fix it. Signed-off-by: Kay Sievers --- udev_rules.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index 8e9c1605bf..e9b32df1c6 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -733,19 +733,13 @@ static int match_rule(struct udevice *udev, struct udev_rule *rule) } if (rule->wait_for_sysfs.operation != KEY_OP_UNSET) { - int match; + int found; - match = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0); - if (match && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) { - dbg("WAIT_FOR_SYSFS is true (matching value)"); - return 0; + found = (wait_for_sysfs(udev, key_val(rule, &rule->wait_for_sysfs), 3) == 0); + if (!found && (rule->wait_for_sysfs.operation != KEY_OP_NOMATCH)) { + dbg("WAIT_FOR_SYSFS failed"); + goto nomatch; } - if (!match && (rule->wait_for_sysfs.operation == KEY_OP_NOMATCH)) { - dbg("WAIT_FOR_SYSFS is true, (non matching value)"); - return 0; - } - dbg("WAIT_FOR_SYSFS is false"); - return -1; } /* walk up the chain of parent devices and find a match */ From b3e8c12b2d18897d6d9220607fc32ee18e5db4ac Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Wed, 1 Feb 2006 02:01:12 +0100 Subject: [PATCH 1717/4284] Fix trivial spelling errors in RELEASE-NOTES Signed-off-by: Andrey Borzenkov --- RELEASE-NOTES | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 50831aceba..c8e7baa4db 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,8 +1,8 @@ udev 084 ======== If BUS== and SYSFS{}== have been used in the same rule, the sysfs -attributes are only checked at the parent device that matched the -by BUS requested subsystem. Fix t to also look at the device we +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 @@ -22,7 +22,7 @@ to the key like RUN+="/bin/program $env{SUBSYSTEM}". udev 082 ======== -The udev man page has moced to udev(7) as it doesnot describe a command +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. From a2a7f7d7af3c44bf9390c9fe168993f4d0916807 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 1 Feb 2006 02:08:11 +0100 Subject: [PATCH 1718/4284] fix typo in man page Thanks to Joachim Breitner . --- udev.7 | 2 +- udev.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/udev.7 b/udev.7 index 711bd0861b..75db2b72a5 100644 --- a/udev.7 +++ b/udev.7 @@ -138,7 +138,7 @@ Add a program to the list of programs to be executed for a specific device. Named label where a GOTO can jump to. .TP \fBGOTO\fR -Jumps to the next LABEL with a matching gname +Jumps to the next LABEL with a matching name .TP \fBIMPORT{\fR\fB\fItype\fR\fR\fB}\fR Import the printed result or the value of a file in environment key format into the event environment. diff --git a/udev.xml b/udev.xml index bf5676bee6..51288c0089 100644 --- a/udev.xml +++ b/udev.xml @@ -315,7 +315,7 @@ - Jumps to the next LABEL with a matching gname + Jumps to the next LABEL with a matching name From 67f69ae17c2ba2cf54ca40ece1dc42418fb72aaa Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Fri, 3 Feb 2006 13:52:37 +0100 Subject: [PATCH 1719/4284] include sys/socket.h for klibc build Requested by Aaron Griffin --- udev_add.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/udev_add.c b/udev_add.c index 6de2858313..398dcb58fa 100644 --- a/udev_add.c +++ b/udev_add.c @@ -26,11 +26,12 @@ #include #include #include +#include #include #include -#include -#include +#include #include +#include #include #include "udev.h" From 42878445d73b19096e068e50a0ab86c9fa047c63 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 13 Feb 2006 06:29:30 +0100 Subject: [PATCH 1720/4284] cramfs detection for bigendian Patch from Olaf Hering . --- extras/volume_id/libvolume_id/cramfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/volume_id/libvolume_id/cramfs.c b/extras/volume_id/libvolume_id/cramfs.c index 0ad5886b32..bf79407d9d 100644 --- a/extras/volume_id/libvolume_id/cramfs.c +++ b/extras/volume_id/libvolume_id/cramfs.c @@ -52,7 +52,7 @@ int volume_id_probe_cramfs(struct volume_id *id, uint64_t off) if (cs == NULL) return -1; - if (memcmp(cs->magic, "\x45\x3d\xcd\x28", 4) == 0) { + 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); From 656ba91ee111308b53938b0f518ccbfadada9aa0 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 15 Feb 2006 20:43:28 +0100 Subject: [PATCH 1721/4284] exit WAIT_FOR_SYSFS if the whole device goes away Signed-off-by: Kay Sievers --- udev_rules.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/udev_rules.c b/udev_rules.c index e9b32df1c6..9fa2253e96 100644 --- a/udev_rules.c +++ b/udev_rules.c @@ -342,23 +342,33 @@ out: #define WAIT_LOOP_PER_SECOND 50 static int wait_for_sysfs(struct udevice *udev, const char *file, int timeout) { - char filename[PATH_SIZE]; + char devicepath[PATH_SIZE]; + char filepath[PATH_SIZE]; struct stat stats; int loop = timeout * WAIT_LOOP_PER_SECOND; - snprintf(filename, sizeof(filename), "%s%s/%s", sysfs_path, udev->dev->devpath, file); - filename[sizeof(filename)-1] = '\0'; - dbg("will wait %i sec for '%s'", timeout, filename); + 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) { - if (stat(filename, &stats) == 0) { - info("file '%s' appeared after %i loops", filename, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); + /* lookup file */ + if (stat(filepath, &stats) == 0) { + info("file '%s' appeared after %i loops", filepath, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); return 0; } - info("wait for '%s' for %i mseconds", filename, 1000 / WAIT_LOOP_PER_SECOND); + /* make sure the device does not have disappeared 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); } - err("waiting for '%s' failed", filename); + err("waiting for '%s' failed", filepath); return -1; } From 348f9dfa0461a9e3d93c360de59f4959b0c97fd4 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 15 Feb 2006 20:54:53 +0100 Subject: [PATCH 1722/4284] update SUSE rules --- etc/udev/suse/60-persistent-disk.rules | 14 +++++++------- etc/udev/suse/60-persistent-input.rules | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 etc/udev/suse/60-persistent-input.rules diff --git a/etc/udev/suse/60-persistent-disk.rules b/etc/udev/suse/60-persistent-disk.rules index 3515bb189d..bcbd7721ab 100644 --- a/etc/udev/suse/60-persistent-disk.rules +++ b/etc/udev/suse/60-persistent-disk.rules @@ -1,14 +1,14 @@ # persistent disk links: /dev/disk/{by-id,by-uuid,by-label,by-path} # scheme based on "Linux persistent device names", 2004, Hannes Reinecke -ACTION!="add", GOTO="persistent_end" -SUBSYSTEM!="block", GOTO="persistent_end" +ACTION!="add", GOTO="persistent_disk_end" +SUBSYSTEM!="block", GOTO="persistent_disk_end" # skip rules for inappropriate block devices -KERNEL=="ram*|loop*|fd*|nbd*", GOTO="persistent_end" +KERNEL=="ram*|loop*|fd*|nbd*", GOTO="persistent_disk_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" +BUS=="ide", DRIVER!="ide-cdrom", SYSFS{removable}="1", GOTO="persistent_disk_end" # by-id (hardware serial number) KERNEL=="hd*[!0-9]", IMPORT{program}="/sbin/ata_id --export $tempnode" @@ -28,12 +28,12 @@ KERNEL=="sd*[0-9]|dasd*[0-9]", ENV{ID_SERIAL}=="?*", SYMLINK+="disk/by-id/$env{I # by-path (shortest physical path) KERNEL=="*[!0-9]|sr*", ENV{ID_TYPE}=="?*", IMPORT{program}="/sbin/path_id %p", SYMLINK+="disk/by-path/$env{ID_PATH}" -KERNEL=="sr*", GOTO="persistent_end" +KERNEL=="sr*", GOTO="persistent_disk_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" +KERNEL=="*[!0-9]", SYSFS{removable}=="1", GOTO="persistent_disk_end" IMPORT{program}="/sbin/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}" @@ -45,4 +45,4 @@ KERNEL=="*[0-9]", ENV{ID_EDD}=="?*", SYMLINK+="disk/by-id/edd-$env{ID_EDD}-part% 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" +LABEL="persistent_disk_end" diff --git a/etc/udev/suse/60-persistent-input.rules b/etc/udev/suse/60-persistent-input.rules new file mode 100644 index 0000000000..2a74d15482 --- /dev/null +++ b/etc/udev/suse/60-persistent-input.rules @@ -0,0 +1,20 @@ +ACTION!="add", GOTO="persistent_input_end" +SUBSYSTEM!="input", GOTO="persistent_input_end" +KERNEL=="input[0-9]*", GOTO="persistent_input_end" + +# usb devices +BUS=="usb", IMPORT{program}="/sbin/usb_id -x" +BUS=="usb", SYSFS{bInterfaceClass}="03", SYSFS{bInterfaceProtocol}="01", ENV{ID_CLASS}="kbd" +BUS=="usb", SYSFS{bInterfaceClass}="03", SYSFS{bInterfaceProtocol}="02", ENV{ID_CLASS}="mouse" + +# by-id links +KERNEL=="mouse*", ENV{ID_BUS}=="?*", ENV{ID_SERIAL}=="?*", ENV{ID_CLASS}=="?*", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-$env{ID_CLASS}" +KERNEL=="event*", ENV{ID_BUS}=="?*", ENV{ID_SERIAL}=="?*", ENV{ID_CLASS}=="?*", SYMLINK+="input/by-id/$env{ID_BUS}-$env{ID_SERIAL}-event-$env{ID_CLASS}" + +# by-path +IMPORT{program}="/sbin/path_id %p" +ENV{ID_PATH}=="?*", KERNEL=="mouse*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{ID_CLASS}" +ENV{ID_PATH}=="?*", KERNEL=="event*", SYMLINK+="input/by-path/$env{ID_PATH}-$env{ID_CLASS}" + +LABEL="persistent_input_end" + From bee6e24fa94fced3a23115ca020f041ed9ed9143 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 15 Feb 2006 20:57:29 +0100 Subject: [PATCH 1723/4284] update Red Hat rules --- etc/udev/redhat/05-udev-early.rules | 9 ++ etc/udev/redhat/95-pam-console.rules | 1 + etc/udev/redhat/hotplug.rules | 13 ++- etc/udev/redhat/udev.rules | 118 ++++++++++++++------------- 4 files changed, 82 insertions(+), 59 deletions(-) create mode 100644 etc/udev/redhat/05-udev-early.rules create mode 100644 etc/udev/redhat/95-pam-console.rules diff --git a/etc/udev/redhat/05-udev-early.rules b/etc/udev/redhat/05-udev-early.rules new file mode 100644 index 0000000000..9a96b6a198 --- /dev/null +++ b/etc/udev/redhat/05-udev-early.rules @@ -0,0 +1,9 @@ +# 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" + +# ignore these events until someone needs them +SUBSYSTEM=="drivers", OPTIONS="ignore_device" +SUBSYSTEM=="module", OPTIONS="ignore_device" + +ACTION=="add", SUBSYSTEM=="firmware", ENV{FIRMWARE}=="*", RUN="/sbin/firmware_helper", OPTIONS="last_rule" diff --git a/etc/udev/redhat/95-pam-console.rules b/etc/udev/redhat/95-pam-console.rules new file mode 100644 index 0000000000..8de9249c28 --- /dev/null +++ b/etc/udev/redhat/95-pam-console.rules @@ -0,0 +1 @@ +ACTION=="add", SYSFS{dev}="?*", KERNEL=="?*", RUN+="/sbin/pam_console_apply $env{DEVNAME} $env{DEVLINKS}" diff --git a/etc/udev/redhat/hotplug.rules b/etc/udev/redhat/hotplug.rules index 1f4369c36b..4c47976ee5 100644 --- a/etc/udev/redhat/hotplug.rules +++ b/etc/udev/redhat/hotplug.rules @@ -1,8 +1,15 @@ # do not call hotplug.d and dev.d for "drivers" and "module" events -SUBSYSTEM=="drivers", OPTIONS="last_rule" -SUBSYSTEM=="module", OPTIONS="last_rule" +SUBSYSTEM=="drivers", GOTO="hotplug_end" +SUBSYSTEM=="module", GOTO="hotplug_end" +ACTION="add", GOTO="hotplug_comp" +ACTION="remove", GOTO="hotplug_comp" +GOTO="hotplug_end" + +LABEL="hotplug_comp" # compatibility support for the obsolete hotplug.d and dev.d directories -ENV{UDEVD_EVENT}=="1", RUN+="/lib/udev/udev_run_hotplugd" +ENV{UDEVD_EVENT}=="1", RUN+="/lib/udev/udev_run_hotplugd" RUN+="/lib/udev/udev_run_devd" + +LABEL="hotplug_end" diff --git a/etc/udev/redhat/udev.rules b/etc/udev/redhat/udev.rules index ba10fd5501..dbd62c397b 100644 --- a/etc/udev/redhat/udev.rules +++ b/etc/udev/redhat/udev.rules @@ -3,6 +3,7 @@ # # default is OWNER="root" GROUP="root", MODE="0600" # + KERNEL="*", OWNER="root" GROUP="root", MODE="0600" # all block devices @@ -10,40 +11,44 @@ SUBSYSTEM=="block", GROUP="disk", MODE="0640" KERNEL=="root", GROUP="disk", MODE="0640" # console devices -KERNEL=="tty", MODE="0666", OPTIONS="last_rule" -KERNEL=="console", MODE="0600", OPTIONS="last_rule" -KERNEL=="tty[0-9]", GROUP="tty", MODE="0660", OPTIONS="last_rule" -KERNEL=="tty[0-9][0-9]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" -KERNEL=="vc/[0-9]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="tty", NAME="%k", GROUP="tty", MODE="0666", OPTIONS="last_rule" +KERNEL=="console", NAME="%k", MODE="0600", OPTIONS="last_rule" +KERNEL=="tty[0-9]*", NAME="%k", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="vc/[0-9]*", NAME="%k", GROUP="tty", MODE="0660", OPTIONS="last_rule" # pty devices # Set this to 0660 if you only want users belonging to tty group # to be able to allocate PTYs -KERNEL=="ptmx", GROUP="tty", MODE="0666", OPTIONS="last_rule" -KERNEL=="pty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" -KERNEL=="tty[p-za-e][0-9a-f]*", GROUP="tty", MODE="0660", OPTIONS="last_rule" -KERNEL=="pty/m*", GROUP="tty", MODE="0660", OPTIONS="last_rule" -KERNEL=="vc/s*", GROUP="tty", MODE="0660", OPTIONS="last_rule" +KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="666", OPTIONS="last_rule" +KERNEL=="pty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="660", OPTIONS="last_rule" +KERNEL=="tty[pqrstuvwxyzabcdef][0123456789abcdef]", NAME="%k", GROUP="tty", MODE="660", OPTIONS="last_rule" +KERNEL=="pty/m*", NAME="%k", GROUP="tty", MODE="0660", OPTIONS="last_rule" # serial+dialup devices -KERNEL=="ttyS*", GROUP="uucp", MODE="0660", OPTIONS="last_rule" -KERNEL=="ttyACM*", GROUP="uucp", MODE="0660", OPTIONS="last_rule" -KERNEL=="ttyUSB*", GROUP="uucp", MODE="0660", OPTIONS="last_rule" -KERNEL=="ippp*", MODE="0660" -KERNEL=="isdn*", MODE="0660" -KERNEL=="isdnctrl*", MODE="0660" -KERNEL=="capi*", MODE="0660" -KERNEL=="dcbri*", MODE="0660" -KERNEL=="ircomm*", GROUP="uucp", MODE="0660" -KERNEL=="tts/[0-9]*", GROUP="uucp", MODE="0660" -KERNEL=="tts/USB[0-9]*", GROUP="uucp", MODE="0660" +KERNEL=="ippp*", NAME="%k", MODE="0660" +KERNEL=="isdn*", NAME="%k", MODE="0660" +KERNEL=="isdnctrl*", NAME="%k", MODE="0660" +KERNEL=="capi*", NAME="%k", 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" +KERNEL=="ttyUSB*", SYSFS{product}=="Palm Handheld*", SYMLINK+="pilot" +KERNEL=="ttyUSB*", SYSFS{product}=="palmOne Handheld*", SYMLINK+="pilot" # vc devices -KERNEL=="vcs", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" -KERNEL=="vcs[0-9]*", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" -KERNEL=="vcsa", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" -KERNEL=="vcsa[0-9]*", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" -KERNEL=="vcc/*", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcs", NAME="%k", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcs[0-9]*", NAME="%k", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcsa", NAME="%k", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcsa[0-9]*", NAME="%k", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" +KERNEL=="vcc/*", NAME="%k", OWNER="vcsa", GROUP="tty", OPTIONS="last_rule" # memory devices KERNEL=="random", MODE="0666", OPTIONS="last_rule" @@ -54,6 +59,8 @@ KERNEL=="port", GROUP="kmem", MODE="0640", OPTIONS="last_rule" KERNEL=="full", MODE="0666", OPTIONS="last_rule" KERNEL=="null", MODE="0666", OPTIONS="last_rule" KERNEL=="zero", MODE="0666", OPTIONS="last_rule" +# 183 = /dev/hwrng Generic random number generator +KERNEL=="hw_random", NAME="hwrng", SYMLINK+="%k" # misc devices KERNEL=="nvram", MODE="0660" @@ -61,6 +68,10 @@ 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", SYSFS{device/cmos}=="*", RUN+="create_floppy_devices -c -t $sysfs{device/cmos} -m %M /dev/%k" +KERNEL=="fd[0-9]*", ACTION=="remove", RUN+="/bin/sh -c 'rm -f /dev/%k*'" # audio devices KERNEL=="dsp*", MODE="0660" @@ -209,7 +220,7 @@ KERNEL=="pcd[0-9]*", SYMLINK+="cdrom%e" KERNEL=="fd[0-9]*", SYMLINK+="floppy%e" KERNEL=="nst[0-9]", BUS=="scsi", SYMLINK+="tape%e", MODE="0660" KERNEL=="nosst[0-9]", BUS=="scsi", SYMLINK+="tape%e", MODE="0660" -KERNEL=="sg[0-9]*", BUS="scsi", SYSFS{type}=="6", SYMLINK+="scanner%e", MODE="0660" +KERNEL=="sg[0-9]*", BUS="scsi", SYSFS{type}=="[36]", SYMLINK+="scanner%e", MODE="0660" KERNEL=="umad*", NAME="infiniband/%k" KERNEL=="issm*", NAME="infiniband/%k" @@ -224,24 +235,25 @@ KERNEL=="zap[0-9]*", NAME="zap/%n" BUS=="scsi", KERNEL=="sg[0-9]*", SYSFS{type}=="6", NAME="%k", SYMLINK="scanner%e", MODE="0660" # do not seperate the next 2 lines!! -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/lib/udev/ide-media.sh %k", RESULT=="floppy", SYMLINK+="floppy%e", NAME{ignore_remove, all_partitions}="%k" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="ide-media.sh %k", RESULT=="floppy", SYMLINK+="floppy%e", NAME{ignore_remove, all_partitions}="%k" KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", RESULT=="cdrom", SYMLINK+="cdrom%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/lib/udev/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/lib/udev/check-cdrom.sh %k DVD", SYMLINK+="dvd%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="check-cdrom.sh %k DVD", SYMLINK+="dvd%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="check-cdrom.sh %k DVD", SYMLINK+="dvd%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="/lib/udev/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/lib/udev/check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM=="check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="check-cdrom.sh %k CD-R", SYMLINK+="cdwriter%e" -KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="/lib/udev/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" -KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="/lib/udev/check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" +KERNEL=="hd[a-z]", BUS=="ide", SYSFS{removable}=="1", PROGRAM="check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" +KERNEL=="sr[0-9]*", BUS=="scsi", PROGRAM=="check-cdrom.sh %k DVD-R", SYMLINK+="dvdwriter%e" # rename sr* to scd* KERNEL=="sr[0-9]*", BUS=="scsi", NAME="scd%n" KERNEL=="hd[a-z]*", BUS=="ide", SYSFS{removable}=="1", NAME{ignore_remove}="%k" -KERNEL=="dvb*", PROGRAM=="/lib/udev/dvb.sh %k", NAME="%c" +# dvb +SUBSYSTEM=="dvb", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter%%i/%%s $${K%%%%.*} $${K#*.}'", NAME="%c" ####################################### # Persistent block device stuff - begin @@ -297,37 +309,31 @@ LABEL="persistent_end" # Persistent block device stuff - end ##################################### -ACTION=="add", SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'X=%k X=$${X#usbdev} B=$${X%%%%.*} D=$${X#*.}; echo bus/usb/$$B/$$D'", SYMLINK+="%c" - +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" # Perhaps this should just be for all subsystems? +ACTION=="add", SUBSYSTEM=="?*", MODALIAS=="?*", RUN+="/sbin/modprobe $modalias" -ACTION=="add", SUBSYSTEM=="pci", MODALIAS=="*", \ - RUN+="/sbin/modprobe $modalias" -ACTION=="add", SUBSYSTEM=="usb", MODALIAS=="*", \ - RUN+="/sbin/modprobe $modalias" -ACTION=="add", SUBSYSTEM=="pcmcia", MODALIAS=="*", \ - RUN+="/sbin/modprobe $modalias" ACTION=="add", SUBSYSTEM=="pcmcia", MODALIAS=="*", \ RUN+="/bin/sh -c 'echo 1 > /sys/$DEVPATH/allow_func_id_match'" -ACTION=="add", SUBSYSTEM=="ieee1394", MODALIAS=="*", \ - RUN+="/sbin/modprobe $modalias" +# sd: 0 TYPE_DISK, 7 TYPE_MOD, 14 TYPE_RBC +# sr: 4 TYPE_WORM, 5 TYPE_ROM +# st/osst: 1 TYPE_TAPE +ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="0|7|14", RUN+="/bin/sh -c 'echo 60 > /sys$$DEVPATH/timeout'" +ACTION=="add", SUBSYSTEM="scsi" , SYSFS{type}=="1", RUN+="/bin/sh -c 'echo 900 > /sys$$DEVPATH/timeout'" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[07]", \ +ACTION=="add", SUBSYSTEM=="scsi_device", SYSFS{type}=="0|7|14", \ RUN+="/sbin/modprobe sd_mod" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="14", \ - RUN+="/sbin/modprobe sd_mod" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[45]", \ +ACTION=="add", SUBSYSTEM=="scsi_device", SYSFS{type}=="[45]", \ RUN+="/sbin/modprobe sr_mod" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="On[sS]tream", \ +ACTION=="add", SUBSYSTEM=="scsi_device", SYSFS{type}=="1", SYSFS{device/vendor}=="On[sS]tream", \ SYSFS{model}!="ADR*", RUN+="/sbin/modprobe osst" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}=="On[sS]tream", \ +ACTION=="add", SUBSYSTEM=="scsi_device", SYSFS{type}=="1", SYSFS{device/vendor}=="On[sS]tream", \ SYSFS{model}=="ADR*", RUN+="/sbin/modprobe st" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="1", SYSFS{vendor}!="On[sS]tream", \ +ACTION=="add", SUBSYSTEM=="scsi_device", SYSFS{type}=="1", SYSFS{device/vendor}!="On[sS]tream", \ RUN+="/sbin/modprobe st" -ACTION=="add", SUBSYSTEM=="scsi", SYSFS{type}=="[23689]", \ - RUN+="/sbin/modprobe sg" +ACTION=="add", SUBSYSTEM=="scsi_device" RUN+="/sbin/modprobe sg" + +RUN+="socket:/org/kernel/udev/monitor" -ACTION=="add", SUBSYSTEM=="firmware", ENV{FIRMWARE}=="*", \ - RUN+="/sbin/firmware_helper" From 515e50555cb9776e425d498197eb382a22a51a04 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 15 Feb 2006 21:03:25 +0100 Subject: [PATCH 1724/4284] update Gentoo rules --- etc/udev/gentoo/udev.rules | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/etc/udev/gentoo/udev.rules b/etc/udev/gentoo/udev.rules index 6614c76394..24f67be85a 100644 --- a/etc/udev/gentoo/udev.rules +++ b/etc/udev/gentoo/udev.rules @@ -22,8 +22,8 @@ KERNEL=="console", NAME="%k", GROUP="tty", MODE="0600" KERNEL=="ptmx", NAME="%k", GROUP="tty", MODE="0666" # tty devices -KERNEL=="ttyS[0-9]*", NAME="tts/%n", SYMLINK+="%k", GROUP="tty" -KERNEL=="ttyUSB[0-9]*", NAME="tts/USB%n", GROUP="tty", MODE="0660" +KERNEL=="ttyS[0-9]*", NAME="%k", SYMLINK="tts/%n", GROUP="tty" +KERNEL=="ttyUSB[0-9]*", NAME="%k", SYMLINK="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" @@ -133,7 +133,7 @@ KERNEL=="dnrtmsg", NAME="netlink/%k" KERNEL=="tap*", NAME="netlink/%k" # network devices -KERNEL=="tun", NAME="net/%k" +KERNEL=="tun", NAME="net/%k", MODE="0600" # ramdisk devices KERNEL=="ram[0-9]*", NAME="rd/%n", SYMLINK+="%k" @@ -183,7 +183,7 @@ 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/%%i $${K%%%%.*} $${K#*.}'", NAME="%c" +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" @@ -210,6 +210,7 @@ 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" @@ -299,10 +300,10 @@ SUBSYSTEM=="usb_device", PROGRAM="/bin/sh -c 'K=%k; K=$${K#usbdev}; printf bus/u # be backward compatible for a while with the /etc/dev.d and /etc/hotplug.d/ systems # run /etc/hotplug.d/ stuff only if we came from a hotplug event, not for udevstart -ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd" +ENV{UDEVD_EVENT}=="1", RUN+="/sbin/udev_run_hotplugd $env{SUBSYSTEM}" # always run /etc/dev.d/ stuff for now. -RUN+="/sbin/udev_run_devd" +RUN+="/sbin/udev_run_devd $env{SUBSYSTEM}" # debugging monitor RUN+="socket:/org/kernel/udev/monitor" From c779c930f157a3e8984110f813d03289092eb60b Mon Sep 17 00:00:00 2001 From: Jeroen Roovers Date: Wed, 15 Feb 2006 21:06:19 +0100 Subject: [PATCH 1725/4284] fix typo in parisc support to path_id As reported at http://bugs.gentoo.org/show_bug.cgi?id=113379 path_id is still broken for parisc boxes. This patch from Jeroen Roovers fixes that. Signed-off-by: Greg Kroah-Hartman --- extras/path_id | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/path_id b/extras/path_id index b58e1eda6a..73d5c834dd 100755 --- a/extras/path_id +++ b/extras/path_id @@ -229,7 +229,7 @@ handle_block_scsi () { ;; # PARISC devices *parisc*) - adapter="${controler_dev##*/}" + adapter="${controller_dev##*/}" bus=parisc; ;; *) From 4c2d04bd997b1585625926aa10397616097f7b0f Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 15 Feb 2006 21:12:49 +0100 Subject: [PATCH 1726/4284] include errno.h in udev_libc_wrapper.c --- udev_libc_wrapper.c | 1 + 1 file changed, 1 insertion(+) diff --git a/udev_libc_wrapper.c b/udev_libc_wrapper.c index 02a1f8d016..1711811e83 100644 --- a/udev_libc_wrapper.c +++ b/udev_libc_wrapper.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "udev.h" From 4cb665e431cfd03f000e7f025b47b24727458131 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Wed, 15 Feb 2006 23:15:27 +0100 Subject: [PATCH 1727/4284] 085 release --- ChangeLog | 21 +++++++++++++++++++++ Makefile | 2 +- RELEASE-NOTES | 7 +++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 8f0e9b157b..2b959f04a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +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 ============================================ diff --git a/Makefile b/Makefile index 55cecd3755..5d82d44c64 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -VERSION = 084 +VERSION = 085 # set this to make use of syslog USE_LOG = true diff --git a/RELEASE-NOTES b/RELEASE-NOTES index c8e7baa4db..6826b8fd8a 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,3 +1,10 @@ +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 From 559776036744f6dc4e475851ae646ee1c0c51631 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Tue, 21 Feb 2006 17:01:54 +0100 Subject: [PATCH 1728/4284] workaround missing kernel headers for some architectures Signed-off-by: Kyle McMartin --- udev_libc_wrapper.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/udev_libc_wrapper.h b/udev_libc_wrapper.h index a4d320fef2..fc66670a3c 100644 --- a/udev_libc_wrapper.h +++ b/udev_libc_wrapper.h @@ -135,8 +135,12 @@ static inline int inotify_add_watch(int fd, const char *name, uint32_t mask) #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 uid_t lookup_user(const char *user); extern gid_t lookup_group(const char *group); From 467546b586e9ae29ac168967f5cdaac696cadcfb Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 21 Feb 2006 18:44:18 +0100 Subject: [PATCH 1729/4284] volume_id: replace __packed__ by PACKED macro --- extras/volume_id/libvolume_id/cramfs.c | 4 ++-- extras/volume_id/libvolume_id/ext.c | 2 +- extras/volume_id/libvolume_id/fat.c | 10 +++++----- extras/volume_id/libvolume_id/hfs.c | 16 ++++++++-------- extras/volume_id/libvolume_id/highpoint.c | 4 ++-- extras/volume_id/libvolume_id/hpfs.c | 2 +- extras/volume_id/libvolume_id/iso9660.c | 4 ++-- extras/volume_id/libvolume_id/isw_raid.c | 2 +- extras/volume_id/libvolume_id/jfs.c | 2 +- extras/volume_id/libvolume_id/linux_raid.c | 2 +- extras/volume_id/libvolume_id/linux_swap.c | 2 +- extras/volume_id/libvolume_id/lsi_raid.c | 2 +- extras/volume_id/libvolume_id/lvm.c | 4 ++-- extras/volume_id/libvolume_id/mac.c | 4 ++-- extras/volume_id/libvolume_id/minix.c | 2 +- extras/volume_id/libvolume_id/msdos.c | 2 +- extras/volume_id/libvolume_id/ntfs.c | 8 ++++---- extras/volume_id/libvolume_id/nvidia_raid.c | 2 +- extras/volume_id/libvolume_id/ocfs.c | 8 ++++---- extras/volume_id/libvolume_id/promise_raid.c | 2 +- extras/volume_id/libvolume_id/reiserfs.c | 4 ++-- extras/volume_id/libvolume_id/romfs.c | 2 +- extras/volume_id/libvolume_id/silicon_raid.c | 2 +- extras/volume_id/libvolume_id/sysv.c | 4 ++-- extras/volume_id/libvolume_id/udf.c | 14 +++++++------- extras/volume_id/libvolume_id/ufs.c | 18 +++++++++--------- extras/volume_id/libvolume_id/via_raid.c | 4 ++-- extras/volume_id/libvolume_id/volume_id.h | 4 ++++ extras/volume_id/libvolume_id/vxfs.c | 2 +- extras/volume_id/libvolume_id/xfs.c | 2 +- 30 files changed, 72 insertions(+), 68 deletions(-) diff --git a/extras/volume_id/libvolume_id/cramfs.c b/extras/volume_id/libvolume_id/cramfs.c index bf79407d9d..e099c214c8 100644 --- a/extras/volume_id/libvolume_id/cramfs.c +++ b/extras/volume_id/libvolume_id/cramfs.c @@ -38,9 +38,9 @@ struct cramfs_super { uint32_t edition; uint32_t blocks; uint32_t files; - } __attribute__((__packed__)) info; + } PACKED info; uint8_t name[16]; -} __attribute__((__packed__)); +} PACKED; int volume_id_probe_cramfs(struct volume_id *id, uint64_t off) { diff --git a/extras/volume_id/libvolume_id/ext.c b/extras/volume_id/libvolume_id/ext.c index d1f62dfb6f..26ac98bc37 100644 --- a/extras/volume_id/libvolume_id/ext.c +++ b/extras/volume_id/libvolume_id/ext.c @@ -61,7 +61,7 @@ struct ext2_super_block { uint32_t s_feature_ro_compat; uint8_t s_uuid[16]; uint8_t s_volume_name[16]; -} __attribute__((__packed__)); +} PACKED; #define EXT_SUPER_MAGIC 0xEF53 #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x00000004 diff --git a/extras/volume_id/libvolume_id/fat.c b/extras/volume_id/libvolume_id/fat.c index cea5b8cff2..a72ec19f59 100644 --- a/extras/volume_id/libvolume_id/fat.c +++ b/extras/volume_id/libvolume_id/fat.c @@ -58,7 +58,7 @@ struct vfat_super_block { uint8_t magic[8]; uint8_t dummy2[192]; uint8_t pmagic[2]; - } __attribute__((__packed__)) fat; + } PACKED fat; struct fat32_super_block { uint32_t fat32_length; uint16_t flags; @@ -73,9 +73,9 @@ struct vfat_super_block { uint8_t magic[8]; uint8_t dummy2[164]; uint8_t pmagic[2]; - } __attribute__((__packed__)) fat32; - } __attribute__((__packed__)) type; -} __attribute__((__packed__)); + } PACKED fat32; + } PACKED type; +} PACKED; struct vfat_dir_entry { uint8_t name[11]; @@ -89,7 +89,7 @@ struct vfat_dir_entry { uint16_t date_write; uint16_t cluster_low; uint32_t size; -} __attribute__((__packed__)); +} PACKED; static uint8_t *get_attr_volume_id(struct vfat_dir_entry *dir, unsigned int count) { diff --git a/extras/volume_id/libvolume_id/hfs.c b/extras/volume_id/libvolume_id/hfs.c index 27a8ac9999..09194d5be1 100644 --- a/extras/volume_id/libvolume_id/hfs.c +++ b/extras/volume_id/libvolume_id/hfs.c @@ -35,7 +35,7 @@ struct hfs_finder_info{ uint32_t reserved; uint32_t osx_folder; uint8_t id[8]; -} __attribute__((__packed__)); +} PACKED; struct hfs_mdb { uint8_t signature[2]; @@ -65,7 +65,7 @@ struct hfs_mdb { uint8_t embed_sig[2]; uint16_t embed_startblock; uint16_t embed_blockcount; -} __attribute__((__packed__)) *hfs; +} PACKED *hfs; struct hfsplus_bnode_descriptor { uint32_t next; @@ -74,7 +74,7 @@ struct hfsplus_bnode_descriptor { uint8_t height; uint16_t num_recs; uint16_t reserved; -} __attribute__((__packed__)); +} PACKED; struct hfsplus_bheader_record { uint16_t depth; @@ -83,19 +83,19 @@ struct hfsplus_bheader_record { uint32_t leaf_head; uint32_t leaf_tail; uint16_t node_size; -} __attribute__((__packed__)); +} PACKED; struct hfsplus_catalog_key { uint16_t key_len; uint32_t parent_id; uint16_t unicode_len; uint8_t unicode[255 * 2]; -} __attribute__((__packed__)); +} PACKED; struct hfsplus_extent { uint32_t start_block; uint32_t block_count; -} __attribute__((__packed__)); +} PACKED; #define HFSPLUS_EXTENT_COUNT 8 struct hfsplus_fork { @@ -103,7 +103,7 @@ struct hfsplus_fork { uint32_t clump_size; uint32_t total_blocks; struct hfsplus_extent extents[HFSPLUS_EXTENT_COUNT]; -} __attribute__((__packed__)); +} PACKED; struct hfsplus_vol_header { uint8_t signature[2]; @@ -132,7 +132,7 @@ struct hfsplus_vol_header { struct hfsplus_fork cat_file; struct hfsplus_fork attr_file; struct hfsplus_fork start_file; -} __attribute__((__packed__)) *hfsplus; +} PACKED *hfsplus; #define HFS_SUPERBLOCK_OFFSET 0x400 #define HFS_NODE_LEAF 0xff diff --git a/extras/volume_id/libvolume_id/highpoint.c b/extras/volume_id/libvolume_id/highpoint.c index 721b7ab26f..78a4ad82b4 100644 --- a/extras/volume_id/libvolume_id/highpoint.c +++ b/extras/volume_id/libvolume_id/highpoint.c @@ -30,11 +30,11 @@ struct hpt37x_meta { uint8_t filler1[32]; uint32_t magic; -} __attribute__((packed)); +} PACKED; struct hpt45x_meta { uint32_t magic; -} __attribute__((packed)); +} PACKED; #define HPT37X_CONFIG_OFF 0x1200 #define HPT37X_MAGIC_OK 0x5a7816f0 diff --git a/extras/volume_id/libvolume_id/hpfs.c b/extras/volume_id/libvolume_id/hpfs.c index 52cb47be39..452df0124d 100644 --- a/extras/volume_id/libvolume_id/hpfs.c +++ b/extras/volume_id/libvolume_id/hpfs.c @@ -31,7 +31,7 @@ struct hpfs_super { uint8_t magic[4]; uint8_t version; -} __attribute__((__packed__)); +} PACKED; #define HPFS_SUPERBLOCK_OFFSET 0x2000 diff --git a/extras/volume_id/libvolume_id/iso9660.c b/extras/volume_id/libvolume_id/iso9660.c index b6654cecf2..2e28af8d70 100644 --- a/extras/volume_id/libvolume_id/iso9660.c +++ b/extras/volume_id/libvolume_id/iso9660.c @@ -45,14 +45,14 @@ struct iso_volume_descriptor { uint8_t unused[8]; uint8_t space_size[8]; uint8_t escape_sequences[8]; -} __attribute__((__packed__)); +} PACKED; struct high_sierra_volume_descriptor { uint8_t foo[8]; uint8_t type; uint8_t id[4]; uint8_t version; -} __attribute__((__packed__)); +} PACKED; int volume_id_probe_iso9660(struct volume_id *id, uint64_t off) { diff --git a/extras/volume_id/libvolume_id/isw_raid.c b/extras/volume_id/libvolume_id/isw_raid.c index 1f49959ff9..72b2b85b12 100644 --- a/extras/volume_id/libvolume_id/isw_raid.c +++ b/extras/volume_id/libvolume_id/isw_raid.c @@ -33,7 +33,7 @@ struct isw_meta { uint32_t mpb_size; uint32_t family_num; uint32_t generation_num; -} __attribute__((packed)); +} PACKED; #define ISW_SIGNATURE "Intel Raid ISM Cfg Sig. " diff --git a/extras/volume_id/libvolume_id/jfs.c b/extras/volume_id/libvolume_id/jfs.c index b6ae9624d6..78b61fb30d 100644 --- a/extras/volume_id/libvolume_id/jfs.c +++ b/extras/volume_id/libvolume_id/jfs.c @@ -38,7 +38,7 @@ struct jfs_super_block { uint8_t uuid[16]; uint8_t label[16]; uint8_t loguuid[16]; -} __attribute__((__packed__)); +} PACKED; #define JFS_SUPERBLOCK_OFFSET 0x8000 diff --git a/extras/volume_id/libvolume_id/linux_raid.c b/extras/volume_id/libvolume_id/linux_raid.c index d90510a817..2285e87b97 100644 --- a/extras/volume_id/libvolume_id/linux_raid.c +++ b/extras/volume_id/libvolume_id/linux_raid.c @@ -44,7 +44,7 @@ struct mdp_super_block { uint32_t set_uuid1; uint32_t set_uuid2; uint32_t set_uuid3; -} __attribute__((packed)) *mdp; +} PACKED *mdp; #define MD_RESERVED_BYTES 0x10000 #define MD_MAGIC 0xa92b4efc diff --git a/extras/volume_id/libvolume_id/linux_swap.c b/extras/volume_id/libvolume_id/linux_swap.c index 18928b8351..b4828347f7 100644 --- a/extras/volume_id/libvolume_id/linux_swap.c +++ b/extras/volume_id/libvolume_id/linux_swap.c @@ -34,7 +34,7 @@ struct swap_header_v1_2 { uint32_t nr_badpages; uint8_t uuid[16]; uint8_t volume_name[16]; -} __attribute__((__packed__)) *sw; +} PACKED *sw; #define LARGEST_PAGESIZE 0x4000 diff --git a/extras/volume_id/libvolume_id/lsi_raid.c b/extras/volume_id/libvolume_id/lsi_raid.c index 2720de763d..efa792575f 100644 --- a/extras/volume_id/libvolume_id/lsi_raid.c +++ b/extras/volume_id/libvolume_id/lsi_raid.c @@ -29,7 +29,7 @@ struct lsi_meta { uint8_t sig[6]; -} __attribute__((packed)); +} PACKED; #define LSI_SIGNATURE "$XIDE$" diff --git a/extras/volume_id/libvolume_id/lvm.c b/extras/volume_id/libvolume_id/lvm.c index 650986256d..074660b1e4 100644 --- a/extras/volume_id/libvolume_id/lvm.c +++ b/extras/volume_id/libvolume_id/lvm.c @@ -29,7 +29,7 @@ struct lvm1_super_block { uint8_t id[2]; -} __attribute__((packed)); +} PACKED; struct lvm2_super_block { uint8_t id[8]; @@ -37,7 +37,7 @@ struct lvm2_super_block { uint32_t crc_xl; uint32_t offset_xl; uint8_t type[8]; -} __attribute__((packed)); +} PACKED; #define LVM1_SB_OFF 0x400 #define LVM1_MAGIC "HM" diff --git a/extras/volume_id/libvolume_id/mac.c b/extras/volume_id/libvolume_id/mac.c index 53f0761c8a..78ef9fc803 100644 --- a/extras/volume_id/libvolume_id/mac.c +++ b/extras/volume_id/libvolume_id/mac.c @@ -31,7 +31,7 @@ struct mac_driver_desc { uint8_t signature[2]; uint16_t block_size; uint32_t block_count; -} __attribute__((__packed__)); +} PACKED; struct mac_partition { uint8_t signature[2]; @@ -41,7 +41,7 @@ struct mac_partition { uint32_t block_count; uint8_t name[32]; uint8_t type[32]; -} __attribute__((__packed__)); +} PACKED; int volume_id_probe_mac_partition_map(struct volume_id *id, uint64_t off) { diff --git a/extras/volume_id/libvolume_id/minix.c b/extras/volume_id/libvolume_id/minix.c index ca57745f78..fefba8e729 100644 --- a/extras/volume_id/libvolume_id/minix.c +++ b/extras/volume_id/libvolume_id/minix.c @@ -39,7 +39,7 @@ struct minix_super_block uint16_t s_magic; uint16_t s_state; uint32_t s_zones; -} __attribute__((__packed__)); +} PACKED; #define MINIX_SUPERBLOCK_OFFSET 0x400 diff --git a/extras/volume_id/libvolume_id/msdos.c b/extras/volume_id/libvolume_id/msdos.c index a66046052a..ca3801a8db 100644 --- a/extras/volume_id/libvolume_id/msdos.c +++ b/extras/volume_id/libvolume_id/msdos.c @@ -38,7 +38,7 @@ struct msdos_partition_entry { uint8_t end_cyl; uint32_t start_sect; uint32_t nr_sects; -} __attribute__((packed)); +} PACKED; #define MSDOS_MAGIC "\x55\xaa" #define MSDOS_PARTTABLE_OFFSET 0x1be diff --git a/extras/volume_id/libvolume_id/ntfs.c b/extras/volume_id/libvolume_id/ntfs.c index de9ad6d654..fe9ff8d5d6 100644 --- a/extras/volume_id/libvolume_id/ntfs.c +++ b/extras/volume_id/libvolume_id/ntfs.c @@ -52,7 +52,7 @@ struct ntfs_super_block { uint8_t reserved2[3]; uint8_t volume_serial[8]; uint16_t checksum; -} __attribute__((__packed__)) *ns; +} PACKED *ns; struct master_file_table_record { uint8_t magic[4]; @@ -65,7 +65,7 @@ struct master_file_table_record { uint16_t flags; uint32_t bytes_in_use; uint32_t bytes_allocated; -} __attribute__((__packed__)) *mftr; +} PACKED *mftr; struct file_attribute { uint32_t type; @@ -77,13 +77,13 @@ struct file_attribute { uint16_t instance; uint32_t value_len; uint16_t value_offset; -} __attribute__((__packed__)) *attr; +} PACKED *attr; struct volume_info { uint64_t reserved; uint8_t major_ver; uint8_t minor_ver; -} __attribute__((__packed__)) *info; +} PACKED *info; #define MFT_RECORD_VOLUME 3 #define MFT_RECORD_ATTR_VOLUME_NAME 0x60 diff --git a/extras/volume_id/libvolume_id/nvidia_raid.c b/extras/volume_id/libvolume_id/nvidia_raid.c index 3b967e6979..24717aaaec 100644 --- a/extras/volume_id/libvolume_id/nvidia_raid.c +++ b/extras/volume_id/libvolume_id/nvidia_raid.c @@ -32,7 +32,7 @@ struct nvidia_meta { uint32_t size; uint32_t chksum; uint16_t version; -} __attribute__((packed)); +} PACKED; #define NVIDIA_SIGNATURE "NVIDIA" diff --git a/extras/volume_id/libvolume_id/ocfs.c b/extras/volume_id/libvolume_id/ocfs.c index faf89bd3e0..c2f8360cae 100644 --- a/extras/volume_id/libvolume_id/ocfs.c +++ b/extras/volume_id/libvolume_id/ocfs.c @@ -56,7 +56,7 @@ struct ocfs1_super_block_header { uint64_t new_cfg_off; uint32_t prot_bits; int32_t excl_mount; -} __attribute__((__packed__)); +} PACKED; struct ocfs1_super_block_label { struct ocfs1_disk_lock { @@ -69,14 +69,14 @@ struct ocfs1_super_block_label { uint32_t reader_node_num; uint64_t oin_node_map; uint64_t dlock_seq_num; - } disk_lock __attribute__((__packed__)); + } 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; -} __attribute__((__packed__)); +} PACKED; struct ocfs2_super_block { uint8_t i_signature[8]; @@ -125,7 +125,7 @@ struct ocfs2_super_block { uint64_t s_first_cluster_group; uint8_t s_label[64]; uint8_t s_uuid[16]; -} __attribute__((__packed__)); +} PACKED; int volume_id_probe_ocfs1(struct volume_id *id, uint64_t off) { diff --git a/extras/volume_id/libvolume_id/promise_raid.c b/extras/volume_id/libvolume_id/promise_raid.c index 6611aeab32..bdf0c7b601 100644 --- a/extras/volume_id/libvolume_id/promise_raid.c +++ b/extras/volume_id/libvolume_id/promise_raid.c @@ -29,7 +29,7 @@ struct promise_meta { uint8_t sig[24]; -} __attribute__((packed)); +} PACKED; #define PDC_CONFIG_OFF 0x1200 #define PDC_SIGNATURE "Promise Technology, Inc." diff --git a/extras/volume_id/libvolume_id/reiserfs.c b/extras/volume_id/libvolume_id/reiserfs.c index 0eecbda5cb..91a5bcb9b0 100644 --- a/extras/volume_id/libvolume_id/reiserfs.c +++ b/extras/volume_id/libvolume_id/reiserfs.c @@ -42,7 +42,7 @@ struct reiserfs_super_block { uint32_t dummy4[5]; uint8_t uuid[16]; uint8_t label[16]; -} __attribute__((__packed__)); +} PACKED; struct reiser4_super_block { uint8_t magic[16]; @@ -50,7 +50,7 @@ struct reiser4_super_block { uint8_t uuid[16]; uint8_t label[16]; uint64_t dummy2; -} __attribute__((__packed__)); +} PACKED; #define REISERFS1_SUPERBLOCK_OFFSET 0x2000 #define REISERFS_SUPERBLOCK_OFFSET 0x10000 diff --git a/extras/volume_id/libvolume_id/romfs.c b/extras/volume_id/libvolume_id/romfs.c index 51ef3739b3..456077d1e1 100644 --- a/extras/volume_id/libvolume_id/romfs.c +++ b/extras/volume_id/libvolume_id/romfs.c @@ -32,7 +32,7 @@ struct romfs_super { uint32_t size; uint32_t checksum; uint8_t name[0]; -} __attribute__((__packed__)); +} PACKED; int volume_id_probe_romfs(struct volume_id *id, uint64_t off) { diff --git a/extras/volume_id/libvolume_id/silicon_raid.c b/extras/volume_id/libvolume_id/silicon_raid.c index a307764730..27ac9591a7 100644 --- a/extras/volume_id/libvolume_id/silicon_raid.c +++ b/extras/volume_id/libvolume_id/silicon_raid.c @@ -44,7 +44,7 @@ struct silicon_meta { uint16_t vendor_id; uint16_t minor_ver; uint16_t major_ver; -} __attribute__((packed)); +} PACKED; #define SILICON_MAGIC 0x2F000000 diff --git a/extras/volume_id/libvolume_id/sysv.c b/extras/volume_id/libvolume_id/sysv.c index fc874d5bea..4aa281e9fa 100644 --- a/extras/volume_id/libvolume_id/sysv.c +++ b/extras/volume_id/libvolume_id/sysv.c @@ -56,7 +56,7 @@ struct sysv_super uint32_t s_state; uint32_t s_magic; uint32_t s_type; -} __attribute__((__packed__)); +} PACKED; #define XENIX_NICINOD 100 #define XENIX_NICFREE 100 @@ -82,7 +82,7 @@ struct xenix_super { uint8_t s_fill[371]; uint32_t s_magic; uint32_t s_type; -} __attribute__((__packed__)); +} PACKED; #define SYSV_SUPERBLOCK_BLOCK 0x01 #define SYSV_MAGIC 0xfd187e20 diff --git a/extras/volume_id/libvolume_id/udf.c b/extras/volume_id/libvolume_id/udf.c index fede1ce68a..f0e0d41957 100644 --- a/extras/volume_id/libvolume_id/udf.c +++ b/extras/volume_id/libvolume_id/udf.c @@ -37,28 +37,28 @@ struct volume_descriptor { uint16_t crc; uint16_t crc_len; uint32_t location; - } __attribute__((__packed__)) tag; + } PACKED tag; union { struct anchor_descriptor { uint32_t length; uint32_t location; - } __attribute__((__packed__)) anchor; + } PACKED anchor; struct primary_descriptor { uint32_t seq_num; uint32_t desc_num; struct dstring { uint8_t clen; uint8_t c[31]; - } __attribute__((__packed__)) ident; - } __attribute__((__packed__)) primary; - } __attribute__((__packed__)) type; -} __attribute__((__packed__)); + } PACKED ident; + } PACKED primary; + } PACKED type; +} PACKED; struct volume_structure_descriptor { uint8_t type; uint8_t id[5]; uint8_t version; -} __attribute__((__packed__)); +} PACKED; #define UDF_VSD_OFFSET 0x8000 diff --git a/extras/volume_id/libvolume_id/ufs.c b/extras/volume_id/libvolume_id/ufs.c index ace61db657..2351d1f926 100644 --- a/extras/volume_id/libvolume_id/ufs.c +++ b/extras/volume_id/libvolume_id/ufs.c @@ -80,7 +80,7 @@ struct ufs_super_block { uint32_t cs_nbfree; uint32_t cs_nifree; uint32_t cs_nffree; - } __attribute__((__packed__)) fs_cstotal; + } PACKED fs_cstotal; int8_t fs_fmod; int8_t fs_clean; int8_t fs_ronly; @@ -93,7 +93,7 @@ struct ufs_super_block { uint32_t fs_maxcluster; uint32_t fs_cpc; uint16_t fs_opostbl[16][8]; - } __attribute__((__packed__)) fs_u1; + } PACKED fs_u1; struct { int8_t fs_fsmnt[468]; uint8_t fs_volname[32]; @@ -116,17 +116,17 @@ struct ufs_super_block { uint64_t cs_nffree; uint64_t cs_numclusters; uint64_t cs_spare[3]; - } __attribute__((__packed__)) fs_cstotal; + } PACKED fs_cstotal; struct ufs_timeval { int32_t tv_sec; int32_t tv_usec; - } __attribute__((__packed__)) fs_time; + } PACKED fs_time; int64_t fs_size; int64_t fs_dsize; uint64_t fs_csaddr; int64_t fs_pendingblocks; int32_t fs_pendinginodes; - } __attribute__((__packed__)) fs_u2; + } PACKED fs_u2; } fs_u11; union { struct { @@ -136,7 +136,7 @@ struct ufs_super_block { int32_t fs_state; uint32_t fs_qbmask[2]; uint32_t fs_qfmask[2]; - } __attribute__((__packed__)) fs_sun; + } PACKED fs_sun; struct { int32_t fs_sparecon[53]; int32_t fs_reclaim; @@ -144,7 +144,7 @@ struct ufs_super_block { uint32_t fs_npsect; uint32_t fs_qbmask[2]; uint32_t fs_qfmask[2]; - } __attribute__((__packed__)) fs_sunx86; + } PACKED fs_sunx86; struct { int32_t fs_sparecon[50]; int32_t fs_contigsumsize; @@ -154,7 +154,7 @@ struct ufs_super_block { uint32_t fs_qbmask[2]; uint32_t fs_qfmask[2]; int32_t fs_state; - } __attribute__((__packed__)) fs_44; + } PACKED fs_44; } fs_u2; int32_t fs_postblformat; int32_t fs_nrpos; @@ -162,7 +162,7 @@ struct ufs_super_block { int32_t fs_rotbloff; uint32_t fs_magic; uint8_t fs_space[1]; -} __attribute__((__packed__)); +} PACKED; #define UFS_MAGIC 0x00011954 #define UFS2_MAGIC 0x19540119 diff --git a/extras/volume_id/libvolume_id/via_raid.c b/extras/volume_id/libvolume_id/via_raid.c index 66962cd7f0..375a20979d 100644 --- a/extras/volume_id/libvolume_id/via_raid.c +++ b/extras/volume_id/libvolume_id/via_raid.c @@ -36,10 +36,10 @@ struct via_meta { uint32_t capacity_low; uint32_t capacity_high; uint32_t serial_checksum; - } __attribute((packed)) array; + } PACKED array; uint32_t serial_checksum[8]; uint8_t checksum; -} __attribute__((packed)); +} PACKED; #define VIA_SIGNATURE 0xAA55 diff --git a/extras/volume_id/libvolume_id/volume_id.h b/extras/volume_id/libvolume_id/volume_id.h index edeb225faf..0f265a584d 100644 --- a/extras/volume_id/libvolume_id/volume_id.h +++ b/extras/volume_id/libvolume_id/volume_id.h @@ -16,6 +16,10 @@ #define VOLUME_ID_VERSION 56 +#ifndef PACKED +#define PACKED __attribute__((packed)) +#endif + #define VOLUME_ID_LABEL_SIZE 64 #define VOLUME_ID_UUID_SIZE 36 #define VOLUME_ID_FORMAT_SIZE 32 diff --git a/extras/volume_id/libvolume_id/vxfs.c b/extras/volume_id/libvolume_id/vxfs.c index 0aef369899..883c1266a4 100644 --- a/extras/volume_id/libvolume_id/vxfs.c +++ b/extras/volume_id/libvolume_id/vxfs.c @@ -32,7 +32,7 @@ struct vxfs_super { uint32_t vs_magic; int32_t vs_version; -} __attribute__((__packed__)); +} PACKED; int volume_id_probe_vxfs(struct volume_id *id, uint64_t off) { diff --git a/extras/volume_id/libvolume_id/xfs.c b/extras/volume_id/libvolume_id/xfs.c index a5f5d8432c..934ed2d877 100644 --- a/extras/volume_id/libvolume_id/xfs.c +++ b/extras/volume_id/libvolume_id/xfs.c @@ -40,7 +40,7 @@ struct xfs_super_block { uint64_t icount; uint64_t ifree; uint64_t fdblocks; -} __attribute__((__packed__)); +} PACKED; int volume_id_probe_xfs(struct volume_id *id, uint64_t off) { From ab925d69d5d38e851ae3b71523fb70a75f7b16de Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 21 Feb 2006 18:48:28 +0100 Subject: [PATCH 1730/4284] volume_id: split raid and filesystem detection --- extras/volume_id/libvolume_id/volume_id.c | 31 ++++++++++++++++++++--- extras/volume_id/libvolume_id/volume_id.h | 4 ++- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/extras/volume_id/libvolume_id/volume_id.c b/extras/volume_id/libvolume_id/volume_id.c index 09d1e31725..1daf1cbd74 100644 --- a/extras/volume_id/libvolume_id/volume_id.c +++ b/extras/volume_id/libvolume_id/volume_id.c @@ -31,7 +31,7 @@ #include "util.h" -int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) +int volume_id_probe_raid(struct volume_id *id, uint64_t off, uint64_t size) { if (id == NULL) return -EINVAL; @@ -72,6 +72,17 @@ int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) if (volume_id_probe_highpoint_37x_raid(id, off) == 0) goto exit; +exit: + /* If recognized, we free the allocated buffers */ + volume_id_free_buffer(id); + return 0; +} + +int volume_id_probe_filesystem(struct volume_id *id, uint64_t off, uint64_t size) +{ + if (id == NULL) + return -EINVAL; + if (volume_id_probe_luks(id, off) == 0) goto exit; @@ -139,13 +150,25 @@ int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) return -1; exit: - /* If the filestystem in recognized, we free the allocated buffers, - otherwise they will stay in place for the possible next probe call */ + /* If recognized, we free the allocated buffers */ volume_id_free_buffer(id); - return 0; } +int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size) +{ + if (id == NULL) + return -EINVAL; + + if (volume_id_probe_raid(id, off, size) == 0) + return 0; + + if (volume_id_probe_filesystem(id, off, size) == 0) + return 0; + + return -1; +} + /* open volume by already open file descriptor */ struct volume_id *volume_id_open_fd(int fd) { diff --git a/extras/volume_id/libvolume_id/volume_id.h b/extras/volume_id/libvolume_id/volume_id.h index 0f265a584d..2caf75f532 100644 --- a/extras/volume_id/libvolume_id/volume_id.h +++ b/extras/volume_id/libvolume_id/volume_id.h @@ -14,7 +14,7 @@ #include #include -#define VOLUME_ID_VERSION 56 +#define VOLUME_ID_VERSION 57 #ifndef PACKED #define PACKED __attribute__((packed)) @@ -73,6 +73,8 @@ struct volume_id { extern struct volume_id *volume_id_open_fd(int fd); extern struct volume_id *volume_id_open_node(const char *path); extern int volume_id_probe_all(struct volume_id *id, uint64_t off, uint64_t size); +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 void volume_id_close(struct volume_id *id); /* filesystems */ From 731f0aec41e3f46f5b630e70166ab384976d52c6 Mon Sep 17 00:00:00 2001 From: Nix Date: Tue, 21 Feb 2006 18:53:25 +0100 Subject: [PATCH 1731/4284] update to udev-084/doc/writing_udev_rules --- docs/writing_udev_rules/index.html | 118 ++++++++++++++--------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/docs/writing_udev_rules/index.html b/docs/writing_udev_rules/index.html index c2ccdc3663..1c5c89b3c9 100644 --- a/docs/writing_udev_rules/index.html +++ b/docs/writing_udev_rules/index.html @@ -113,7 +113,7 @@ As your own rules will effectively mask out the udev defaults which create the b In rule files, lines starting with a "#" are treated as comments. Every uncommented line in the file corresponds to a rule.

    -Rules are composed of keys. Keys are seperated by commas. Some keys are used for reading and matching information, others are used for assigning information and performing actions. +Rules are composed of keys. Keys are seperated by commas. Some keys are used for reading and matching information, others are used for assigning information and performing actions. Matches and assignments are carried out with the expected operators (= and ==).

    1. At least one identification key should be provided, which will match the rule to any number of devices in the system. These are listed in the later section: Identifying devices through basic keys.
    2. @@ -123,7 +123,7 @@ Rules are composed of keys. Keys are seperated by commas. Some keys are used for Common rules will use basic identification keys to determine the device to name, and then have a NAME assignement key to define the device node name. udev will only create one node for one device, so if you want it to be accessible through multiple nodes, then you have to specify the other nodes in the SYMLINK assignment key.

      I'll take a slightly modified udev example rule to illustrate this: -
      BUS="usb", SYSFS{serial}="HXOLL0012202323480", NAME="lp_epson", SYMLINK="printers/epson_stylus"
      +
      BUS=="usb", SYSFS{serial}=="HXOLL0012202323480", NAME="lp_epson", SYMLINK="printers/epson_stylus"
      The identification keys here are BUS and SYSFS{serial}. The assignment keys here are NAME and SYMLINK. udev will match this rule against a device that is connected through the USB bus and with a serial number of HXOLL0012202323480. Note that all (as opposed to any) specified keys must be matched for udev to use the rule to name a device.
      @@ -140,7 +140,7 @@ In the NAME and SYMLINK parameters of your rules, you are able to use basic oper There are a number of operators which can compose some or all of your NAME/SYMLINK parameters. These operators refer to kernel-data relating to the device. Take this example: -
      BUS="usb", SYSFS{vendor}="FUJIFILM", SYSFS{model}="M100", NAME="camera%n"
      +
      BUS=="usb", SYSFS{vendor}=="FUJIFILM", SYSFS{model}=="M100", NAME="camera%n"
      The %n operator will be replaced with the "kernel number" for the camera device, to produce a NAME such as camera0, camera1, etc.

      @@ -153,7 +153,7 @@ Another common operator is %k. This represents what the kernel would name You can use shell style pattern matching to provide even more flexibility when writing keys. Taking a default udev rule: -
      KERNEL="ts*", NAME="input/%k"
      +
      KERNEL=="ts*", NAME="input/%k"
      The * operator is used here, which matches literally anything - zero, one, or more characters of any kind. The rule literally says:
      @@ -166,7 +166,7 @@ You can also use square brackets [ ] to match any single character. Direct quote You can also specify ranges that can be matched, e.g. [0-9] would match any single digit. Using an example rule from a default udev installation: -
      KERNEL="fd[0-9]*", NAME="floppy/%n"
      +
      KERNEL=="fd[0-9]*", NAME="floppy/%n"
      This rule says:
      @@ -208,7 +208,7 @@ The ID and PLACE keys do have their uses, but they are not commonly used in rule Background information: SYSFS stores many small files under a tree of directories which provide information about your hardware. One file typically contains just one "data item" - e.g. device name, manufacturer, or product ID.

      Note that SYSFS{...} keys can be combined with the basic keys described in the previous section.


      -You can use keys in the format SYSFS{filename} to match specific info from SYSFS, where filename corresponds to a file in your SYSFS tree. For example, when my camera is connected, there is a file located at /sys/block/sda/device/model which contains "USB 2.0M DSC". To match this, I could use the following key: SYSFS{model} = "USB 2.0M DSC"

      +You can use keys in the format SYSFS{filename} to match specific info from SYSFS, where filename corresponds to a file in your SYSFS tree. For example, when my camera is connected, there is a file located at /sys/block/sda/device/model which contains "USB 2.0M DSC". To match this, I could use the following key: SYSFS{model} == "USB 2.0M DSC"

      Note that any file in sysfs can be matched in this manner, but if you match more than one file (through multiple keys), then you must only match files that exist in the same directory. Typically, there will be several directories giving information about one device. You cannot mix and match (as shown by example below).

      @@ -237,42 +237,42 @@ Moving on to rule-writing, some snipped output of the results of my "udevinfo -a
      
       follow the class device's "device"
         looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3/3-3:1.0/host0/0:0:0:0':
      -    BUS="scsi"
      -    ID="0:0:0:0"
      -    SYSFS{detach_state}="0"
      -    SYSFS{type}="0"
      -    SYSFS{max_sectors}="240"
      -    SYSFS{device_blocked}="0"
      -    SYSFS{queue_depth}="1"
      -    SYSFS{scsi_level}="3"
      -    SYSFS{vendor}="        "
      -    SYSFS{model}="USB 2.0M DSC    "
      -    SYSFS{rev}="1.00"
      -    SYSFS{online}="1"
      +    BUS=="scsi"
      +    ID=="0:0:0:0"
      +    SYSFS{detach_state}=="0"
      +    SYSFS{type}=="0"
      +    SYSFS{max_sectors}=="240"
      +    SYSFS{device_blocked}=="0"
      +    SYSFS{queue_depth}=="1"
      +    SYSFS{scsi_level}=="3"
      +    SYSFS{vendor}=="        "
      +    SYSFS{model}=="USB 2.0M DSC    "
      +    SYSFS{rev}=="1.00"
      +    SYSFS{online}=="1"
       
         looking at the device chain at '/sys/devices/pci0000:00/0000:00:02.1/usb3/3-3':
      -    BUS="usb"
      -    ID="3-3"
      -    SYSFS{detach_state}="0"
      -    SYSFS{bNumInterfaces}=" 1"
      -    SYSFS{bConfigurationValue}="1"
      -    SYSFS{bmAttributes}="c0"
      -    SYSFS{bMaxPower}="  0mA"
      -    SYSFS{idVendor}="052b"
      -    SYSFS{idProduct}="1514"
      -    SYSFS{bcdDevice}="0100"
      -    SYSFS{bDeviceClass}="00"
      -    SYSFS{bDeviceSubClass}="00"
      -    SYSFS{bDeviceProtocol}="00"
      -    SYSFS{bNumConfigurations}="1"
      -    SYSFS{speed}="12"
      -    SYSFS{manufacturer}="Tekom Technologies, Inc"
      -    SYSFS{product}="USB 2.0M DSC"
      +    BUS=="usb"
      +    ID=="3-3"
      +    SYSFS{detach_state}=="0"
      +    SYSFS{bNumInterfaces}==" 1"
      +    SYSFS{bConfigurationValue}=="1"
      +    SYSFS{bmAttributes}=="c0"
      +    SYSFS{bMaxPower}=="  0mA"
      +    SYSFS{idVendor}=="052b"
      +    SYSFS{idProduct}=="1514"
      +    SYSFS{bcdDevice}=="0100"
      +    SYSFS{bDeviceClass}=="00"
      +    SYSFS{bDeviceSubClass}=="00"
      +    SYSFS{bDeviceProtocol}=="00"
      +    SYSFS{bNumConfigurations}=="1"
      +    SYSFS{speed}=="12"
      +    SYSFS{manufacturer}=="Tekom Technologies, Inc"
      +    SYSFS{product}=="USB 2.0M DSC"
       
      The udevinfo tool provides a lot of information which you can simply copy-paste as udev rules. The reason that I have colour coded the above output is to point out that you generally cannot mix and match information from different parts of the udevinfo output. In the above output, I could not combine information from the different coloured sections - this is because each section of output refers to a different directory in SYSFS. For example, the following rule would not work: -
      BUS="scsi", SYSFS{manufacturer}="Tekom Technologies, Inc", NAME="%k"
      -This rule would not work because I am combining information found in the section beginning with BUS="scsi" (green) with information only found in the blue section. The rule would work if I used BUS="usb", sticking only to information found in the blue section above.

      +
      BUS=="scsi", SYSFS{manufacturer}=="Tekom Technologies, Inc", NAME="%k"
      +This rule would not work because I am combining information found in the section beginning with BUS=="scsi" (green) with information only found in the blue section. The rule would work if I used BUS=="usb", sticking only to information found in the blue section above.

      You will notice that a lot of information is not relevant for writing basic rules (there is so much of it!), you should generally be looking for information that you recognise and know will not change (e.g. model name).

      @@ -293,7 +293,7 @@ The behaviour of your own rules masking the defaults can be overcome if you writ Another recent feature is the ability to write rules that do not specify a NAME, but instead they simply specify SYMLINK keys. This allows you to avoid the issue where your own rules effectively mask the udev defaults.

      Take the rule:
      -
      KERNEL="hdc", SYMLINK="dvd"
      +
      KERNEL=="hdc", SYMLINK="dvd"
      When udev finds this rule, it will take a mental note of it. Upon finding another rule matching the same device which also includes a NAME parameter, udev will create the node as specified by the NAME parameter, plus symbolic links as specified by the SYMLINK parameters of both rules.
      To put it into practical terms, when udev is naming nodes for my hdc device, it will use the default rules for block devices as usual, with the addition of my personal symlink "dvd".

      @@ -307,23 +307,23 @@ As well as controlling the naming of the device nodes which are created, udev ru The GROUP key allows you to define which unix group should own the device node. Here's an example from the udev defaults, which defines that the video group will own framebuffer (fb) devices: -
      KERNEL="fb[0-9]*", NAME="fb/%n", SYMLINK="%k", GROUP="video"
      +
      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 own 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"
      +
      KERNEL=="fd[0-9]*", OWNER="john"
      You'll notice in the above rule that we didn't specify any NAME or SYMLINK keys. This is similar to the multiple symlink style where udev will take a mental note that we want john to own floppy nodes, and will apply that ownership once it finds a rule which defines a NAME for the floppy device nodes.

      Building on the style mentioned above, you can do even more flashy things. The udev defaults use the following rule to define that all the sound device nodes shall be owned by the "audio" group: -
      SUBSYSTEM="sound", GROUP="audio"
      +
      SUBSYSTEM=="sound", GROUP="audio"
      -This prevents the need to excessively provide a GROUP="audio" key on every following rule which names sound devices.

      +This prevents the need to excessively provide a GROUP=="audio" key on every following rule which names sound devices.

      udev defaults to creating nodes with unix permissions of 0660 (read/write to owner and group). There may be some situations where you do not want to use the default permissions on your device node. Fortunately, you can easily override the permissions in your rules using the MODE assignment key. 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"
      +
      KERNEL=="inotify", NAME="misc/%k", SYMLINK="%k", MODE="0666"

      Example: Writing a rule for my USB printer

      @@ -337,14 +337,14 @@ After plugging in my printer, I started looking around some /sys directories for Running "udevinfo -a -p /sys/class/usb/lp0" provided me with a heap of info, as usual. I picked out the relevant bits for unique device identification:
       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"
      +BUS=="usb"
      +SYSFS{manufacturer}=="EPSON"
      +SYSFS{product}=="USB Printer"
      +SYSFS{serial}=="L72010011070626380"
       
      My udev rule becomes: -
      BUS="usb", SYSFS{serial}="L72010011070626380", NAME="%k", SYMLINK="epson_680"
      +
      BUS=="usb", SYSFS{serial}=="L72010011070626380", NAME="%k", SYMLINK="epson_680"
      And my printer nodes exist at /dev/lp0 (or /dev/lp1 if another printer was plugged in beforehand) and /dev/epson_680 always points at the device node for that particular printer.

      @@ -357,7 +357,7 @@ This one is a bit tricky. Several nodes are created by default when my camera is sda1 is the node that I would like as my /dev/camera, as that is what gets mounted. udevinfo did not point out any useful differences between sda, sda1, and sg1. I decided that a reliable way to differentiate between these 3 nodes would be to look at the KERNEL name.

      -A key such as KERNEL="sd?1" would match KERNEL names such as "sda1", "sdb1", "sdc1", and equally importantly, it will not match KERNEL names such as sda, sdb, or sg1. The purpose of this key is to ignore the /dev/sda and /dev/sg1 nodes. The device is a digital camera - I would not dream of fdisking it or anything like that, so these 2 nodes are pretty useless to me. The key attempts to capture the /dev/sda1 node, which is mountable and therefore useful!

      +A key such as KERNEL=="sd?1" would match KERNEL names such as "sda1", "sdb1", "sdc1", and equally importantly, it will not match KERNEL names such as sda, sdb, or sg1. The purpose of this key is to ignore the /dev/sda and /dev/sg1 nodes. The device is a digital camera - I would not dream of fdisking it or anything like that, so these 2 nodes are pretty useless to me. The key attempts to capture the /dev/sda1 node, which is mountable and therefore useful!

      As this node (sda1) is treated as a block device, looking in /sys/block would be a good place to start.

      @@ -366,10 +366,10 @@ In my /sys/block, I have a directory named sda. In my /sys/bloc
      # udevinfo -a -p /sys/block/sda/sda1
      In the udevinfo output, I also noticed this bit of useful and understandable information: -
      SYSFS{product}="USB 2.0M DSC"
      +
      SYSFS{product}=="USB 2.0M DSC"
      So that gives me my rule. For completeness, I also include a BUS key (this was also found in the udevinfo output). -
      BUS="usb", SYSFS{product}="USB 2.0M DSC", KERNEL="sd?1", NAME="%k", SYMLINK="camera"
      +
      BUS=="usb", SYSFS{product}=="USB 2.0M DSC", KERNEL=="sd?1", NAME="%k", SYMLINK="camera"
      Now, when my camera is plugged in, it will be named /dev/sda1 (or, if sda1 isnt available, it might be called /dev/sdb1) and will always be correctly linked to from /dev/camera. The /dev/sda (or sdb) node still appears as normal, but the important thing is that my custom persistent "camera" symlink points to the mountable partition.

      @@ -379,7 +379,7 @@ Now, when my camera is plugged in, it will be named /dev/sda1 (or, if sda Carl Streeter, the owner of a large USB hard disk, wrote to me and explained that unlike in my digital camera example, the /dev/sda node is useful to him. He pointed out that he does occasionally need to use tools such as fdisk and hdparm on that node.

      Carl's rule is: -
      BUS="usb", KERNEL="sd*", SYSFS{product}="USB 2.0 Storage Device", NAME="%k", SYMLINK="usbhd%n"
      +
      BUS=="usb", KERNEL=="sd*", SYSFS{product}=="USB 2.0 Storage Device", NAME="%k", SYMLINK="usbhd%n"
      This rule creates symlinks such as: